OSDN Git Service

Create内の最前面の処理の微修正
[gikonavigoeson/gikonavi.git] / Editor.pas
1 unit Editor;
2
3 interface
4
5 uses
6         Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
7         Dialogs, StdCtrls, ComCtrls, ExtCtrls, ToolWin, Menus, OleCtrls, Registry,
8 {$IF Defined(DELPRO) }
9         SHDocVw,
10 {$ELSE}
11         SHDocVw_TLB,
12 {$IFEND}
13         ActiveX, {HTTPApp,} YofUtils, Trip, IniFiles, StrUtils,
14         GikoSystem, GikoUtil, ImgList, Clipbrd, BoardGroup,
15         IdAntiFreezeBase,       IdAntiFreeze, IdBaseComponent, IdComponent,
16         IdTCPConnection, IdTCPClient, IdHTTP, ActnList, StdActns, IdIntercept,
17         IdLogBase, IdLogDebug, IdException, DateUtils, MojuUtils, bmRegExp;
18
19 type
20 //      TSetLayeredWindowAttributes = function(wnd: HWND; crKey: DWORD; bAlpha: BYTE; dwFlag: DWORD): Boolean; stdcall;
21         //\8f\91\82«\8d\9e\82Ý\96ß\82è\92l\83^\83C\83v
22         TGikoResultType = (grtOK, grtCookie, grtCheck, grtError);
23
24         TEditorForm = class(TForm)
25                 MainMenu: TMainMenu;
26                 FileMenu: TMenuItem;
27                 PostMessage: TMenuItem;
28                 SaveMessage: TMenuItem;
29                 CloseMenu: TMenuItem;
30                 N01: TMenuItem;
31                 StatusBar: TStatusBar;
32                 EditorPage: TPageControl;
33                 EditorTab: TTabSheet;
34                 PreviewTab: TTabSheet;
35                 Browser: TWebBrowser;
36                 EditMenu: TMenuItem;
37                 UndoMenu: TMenuItem;
38                 CutMenu: TMenuItem;
39                 CopyMenu: TMenuItem;
40                 PasteMenu: TMenuItem;
41                 N02: TMenuItem;
42                 ToolBarImageList: TImageList;
43                 HotToobarImageList: TImageList;
44                 BodyEdit: TMemo;
45                 NameBasePanel: TPanel;
46                 NameLabel: TLabel;
47                 MailLabel: TLabel;
48                 NameComboBox: TComboBox;
49                 MailComboBox: TComboBox;
50                 ToolBar: TToolBar;
51                 SendToolButton: TToolButton;
52                 OutBoxToolButton: TToolButton;
53                 ToolButton5: TToolButton;
54                 UndoToolButton: TToolButton;
55                 CutToolButton: TToolButton;
56                 CopyToolButton: TToolButton;
57                 PasteToolButton: TToolButton;
58                 ToolButton3: TToolButton;
59                 TransToolButton: TToolButton;
60                 TopToolButton: TToolButton;
61                 Indy: TIdHTTP;
62                 IdAntiFreeze: TIdAntiFreeze;
63                 ToolButton1: TToolButton;
64                 ToolButton2: TToolButton;
65                 ActionList: TActionList;
66                 SendAction: TAction;
67                 SaveAction: TAction;
68                 CloseAction: TAction;
69                 UndoAction: TAction;
70                 CutAction: TAction;
71                 CopyAction: TAction;
72                 PasteAction: TAction;
73                 AbortAction: TAction;
74                 TopAction: TAction;
75                 Show1: TMenuItem;
76                 T1: TMenuItem;
77                 N1: TMenuItem;
78                 S1: TMenuItem;
79                 SageCheckBox: TCheckBox;
80                 IdLogDebug: TIdLogDebug;
81                 TransAction: TAction;
82                 A1: TMenuItem;
83                 KotehanCheckBox: TCheckBox;
84                 TitlePanel: TPanel;
85                 Label1: TLabel;
86                 TitleEdit: TEdit;
87                 SelectAllAction: TAction;
88                 N2: TMenuItem;
89                 SelectAll1: TMenuItem;
90     Timer1: TTimer;
91     QuotePasteAction: TAction;
92     QuotePasteMenuItem: TMenuItem;
93                 procedure EditorPageChange(Sender: TObject);
94                 procedure FormCreate(Sender: TObject);
95                 procedure BrowserStatusTextChange(Sender: TObject;
96                         const Text: WideString);
97                 procedure FormClose(Sender: TObject; var Action: TCloseAction);
98                 procedure FormDestroy(Sender: TObject);
99                 procedure SendActionExecute(Sender: TObject);
100                 procedure SaveActionExecute(Sender: TObject);
101                 procedure AbortActionExecute(Sender: TObject);
102                 procedure CloseActionExecute(Sender: TObject);
103                 procedure UndoActionExecute(Sender: TObject);
104                 procedure CutActionExecute(Sender: TObject);
105                 procedure CopyActionExecute(Sender: TObject);
106                 procedure PasteActionExecute(Sender: TObject);
107                 procedure SendActionUpdate(Sender: TObject);
108                 procedure SaveActionUpdate(Sender: TObject);
109                 procedure CloseActionUpdate(Sender: TObject);
110                 procedure UndoActionUpdate(Sender: TObject);
111                 procedure CutActionUpdate(Sender: TObject);
112                 procedure CopyActionUpdate(Sender: TObject);
113                 procedure PasteActionUpdate(Sender: TObject);
114                 procedure TopActionExecute(Sender: TObject);
115                 procedure TopActionUpdate(Sender: TObject);
116                 procedure SageCheckBoxClick(Sender: TObject);
117                 procedure MailComboBoxChange(Sender: TObject);
118                 procedure TransActionExecute(Sender: TObject);
119                 procedure TransActionUpdate(Sender: TObject);
120                 procedure IdLogDebugReceive(ASender: TIdConnectionIntercept;
121                         AStream: TStream);
122                 procedure IdLogDebugSend(ASender: TIdConnectionIntercept;
123                         AStream: TStream);
124                 procedure SelectAllActionExecute(Sender: TObject);
125     procedure StatusBarResize(Sender: TObject);
126     procedure Timer1Timer(Sender: TObject);
127     procedure FormActivate(Sender: TObject);
128     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
129                 procedure QuotePasteActionExecute(Sender: TObject);
130         private
131                 FThreadItem: TThreadItem;
132                 FBoard: TBoard;
133                 FNameComboEdit: THandle;
134                 FMailComboEdit: THandle;
135                 FAbort: Boolean;
136                 FWork: Boolean;
137                 FStatusCode: Integer;
138                 FDebugStrReceive: string;
139                 FDebugStrSend: string;
140         FSambaTime: TDateTime;
141         FHost: string;
142                 FNow: TDateTime;
143                 procedure Preview;
144                 function RepHtml(s: string): string;
145                 function Check: Boolean;
146                 procedure SetNameList(sName, sMail: string);
147 //              procedure Send(SendType: TGikoSendType; SPID: string; PON: string; FirstWriting: Boolean);
148                 procedure Send(SPID: string; PON: string; FirstWriting: Boolean);
149
150                 function GetActiveControlHandle: THandle;
151 //              function GetSendData: string;
152 //              procedure GetSendData(Source: TStringStream);
153                 procedure GetSendData(Source: TStringStream);
154                 procedure SaveSendFile;
155                 procedure SetContent(Content: string);
156                 function GetSPID(CookieLine: string): string;
157                 function GetPON(CookieLine: string): string;
158                 function GetResultType(ResponseText: string): TGikoResultType;
159         procedure ReadSambaTime(const AHost: string);
160         procedure WriteSambaTime(const AHost: string; ATime: TDateTime);
161         function ReadSettingTime(const AHost: string): Integer;
162         function CheckSambaTime(const AHost: string; ATime: TDateTime): Boolean;
163                                 procedure SetSamba24(AURL: string);
164                 /// \88ø\97p\95\84\82Ì\8eæ\93¾
165                 function GetOEIndentChar : string;
166                 /// \96{\95\82Ì\8eæ\93¾
167                 function GetBody : string;
168         protected
169                 procedure CreateParams(var Params: TCreateParams); override;
170         public
171                 procedure SetFont;
172                 procedure SetThreadItem(Item: TThreadItem);
173                 procedure SetBoard(Item: TBoard);
174         end;
175
176 implementation
177
178 uses
179         Giko, ItemDownload;
180 const
181         CAPTION_NAME_NEW: string = '\83M\83R\83i\83\83X\83\8c\97§\82Ä\83G\83f\83B\83^';
182         CAPTION_NAME_RES: string = '\83M\83R\83i\83\83\8c\83X\83G\83f\83B\83^';
183
184     // \83G\83f\83B\83b\83g\83E\83B\83\93\83h\83E\82ð\89E\89º\82É\82¸\82ç\82µ\82Ä\8aJ\82­\88Ú\93®\97Ê
185     WINDOWMOVE_H = 30;
186     WINDOWMOVE_V = 30;
187
188         //DAX\82³\82ñ±Ø¶ÞÄ!(\81L\81¤\81M)
189         READCGI_ERR                     = '-ERR';
190         READCGI_INCR            = '-INCR';
191         READCGI_OK                      = '+OK';
192         READCGI_PARTIAL = '+PARTIAL';
193         READCGI_ERR_FOUND_KAKO  = '-ERR \89ß\8b\8e\83\8d\83O\91q\8cÉ\82Å\94­\8c©';
194         READCGI_ERR_NOT_HTML            = '-ERR html\89»\91Ò\82¿';
195         READCGI_ERR_NOT_FOUND           = '-ERR \82»\82ñ\82È\94Âor\83X\83\8c\83b\83h\82È\82¢\82Å\82·\81B';
196         READCGI_ERR_ABONE                               = '-ERR \82Ç\82±\82©\82Å\82 \82Ú\81[\82ñ\82ª\82 \82Á\82½\82Ý\82½\82¢\82Å\82·\81B';
197         READCGI_ERR_TIMEOUT                     = '-ERR \8ew\92è\8e\9e\8aÔ\82ª\89ß\82¬\82Ü\82µ\82½\81B';
198         READCGI_ERR_CANTUSE                     = '-ERR \82à\82¤\81@\82Â\82©\82¦\82Ü\82¹\82ñ';
199         RES2CH_TRUE                             = '<!-- 2ch_X:true -->';
200         RES2CH_FALSE                    = '<!-- 2ch_X:false -->';
201         RES2CH_ERROR                    = '<!-- 2ch_X:error -->';
202         RES2CH_CHECK                    = '<!-- 2ch_X:check -->';
203         RES2CH_COOKIE                   = '<!-- 2ch_X:cookie -->';
204
205
206 type
207         TSelection = record
208                 StartPos, EndPos: Integer;
209         end;
210
211 {$R *.DFM}
212
213 {constructor TEditorForm.Create(AOwner: TComponent; Item: TBoard);
214 begin
215         inherited Create(AOwner);
216 end;}
217
218 procedure TEditorForm.CreateParams(var Params: TCreateParams);
219 begin
220         inherited;
221         if FormStyle in [fsNormal, fsStayOnTop] then
222                 if BorderStyle in [bsSingle, bsSizeable] then begin
223                         Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
224                         Params.WndParent := 0;
225                 end;
226 end;
227
228 {procedure TEditorForm.CreateParams(var Params: TCreateParams);
229 begin
230         inherited CreateParams(Params);
231         Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
232 end;}
233
234 procedure TEditorForm.FormCreate(Sender: TObject);
235 var
236         wp: TWindowPlacement;
237                 hUser32 : HINST;
238 begin
239         FWork := False;
240         Browser.Navigate('about:blank');
241
242         FBoard := nil;
243         FThreadItem := nil;
244
245         //\83E\83B\83\93\83h\83E\82Ì\88Ê\92u\90Ý\92è
246         wp.length := sizeof(wp);
247         wp.rcNormalPosition.Top := GikoSys.Setting.EditWindowTop;
248         wp.rcNormalPosition.Left := GikoSys.Setting.EditWindowLeft;
249
250         wp.rcNormalPosition.Bottom := GikoSys.Setting.EditWindowTop + GikoSys.Setting.EditWindowHeight;
251         wp.rcNormalPosition.Right := GikoSys.Setting.EditWindowLeft + GikoSys.Setting.EditWindowWidth;
252         wp.showCmd := SW_HIDE;
253         SetWindowPlacement(Handle, @wp);
254
255         if GikoSys.Setting.EditWindowMax then
256                 WindowState := wsMaximized;
257
258         //\83E\83B\83\93\83h\83E\82ª\89æ\96Ê\8aO\82È\82ç\89æ\96Ê\93à\82É\88Ú\93®\82·\82é
259         if (Left + Width) > Screen.Width then
260 //              Left := Screen.Width - Width;
261                 Left := 0;
262         if (Top + Height) > Screen.Height then
263 //              Top := Screen.Height - Height;
264                 Top := 0;
265         if Left < 0 then
266                 Left := 0;
267         if Top < 0 then
268                 Top := 0;
269
270     //\8c»\8dÝ\82Ì\83E\83B\83\93\83h\83E\82Ì\88Ê\92u\82ð\95Û\91
271     GikoSys.Setting.EditWindowTop := Top  + WINDOWMOVE_V;   // \8e\9f\82É\8aJ\82­\83E\83B\83\93\83h\83E\82Í
272     GikoSys.Setting.EditWindowLeft := Left + WINDOWMOVE_H;  // \81@\81@\81@\89E\8eÎ\82ß\89º\82É\82¸\82ç\82·
273     //\83E\83B\83\93\83h\83E\82Ì\95\9d\82Æ\8d\82\82³\82ª\8f¬\82³\82·\82¬\82¢\82ê\82Î\8c³\82É\96ß\82·
274         if GikoSys.Setting.EditWindowHeight < 144 then
275                 Height := 400;
276         if GikoSys.Setting.EditWindowWidth < 144 then
277                 Width := 640;
278
279         EditorPage.ActivePage := EditorTab;
280         FNameComboEdit := GetWindow(NameComboBox.Handle, GW_CHILD);
281         FMailComboEdit := GetWindow(MailComboBox.Handle, GW_CHILD);
282         NameComboBox.Items.Assign(GikoSys.Setting.NameList);
283         MailComboBox.Items.Assign(GikoSys.Setting.MailList);
284         SetFont;
285         hUser32 := 0;
286         try
287                 try
288                         hUser32 := LoadLibrary('User32.dll');
289                         if hUser32 <> 0 then
290                                 TransAction.Enabled := true
291                         else
292                                 TransAction.Enabled := false;
293                 except
294                 TransAction.Enabled := false;
295                 end;
296         finally
297                 FreeLibrary(hUser32);
298         end;
299
300     // \83E\83B\83\93\83h\83E\82Ì\83X\83e\83C\8fó\91Ô
301         if GikoSys.Setting.EditWindowStay then begin    // \83X\83e\83C\8fó\91Ô
302                 SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
303                 TopAction.Checked := true;
304                 TopToolButton.Down := true;
305         end else begin                                  // \83X\83e\83C\82µ\82È\82¢
306                 SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
307                 TopAction.Checked := false;
308                 TopToolButton.Down := false;
309         end;
310
311     // \83E\83B\83\93\83h\83E\82Ì\94¼\93§\96¾\8fó\91Ô
312         if(GikoSys.Setting.EditWindowTranslucent) and (TransAction.Enabled) then begin // \94¼\93§\96¾\81i\83g\83\89\83\93\83X\83\8b\81[\83Z\83\93\83g\81j\8fó\91Ô
313         AlphaBlend := true;
314         TransAction.Checked := true;
315         TransToolButton.Down := true;
316     end else begin                                      // \95s\93§\96¾
317         AlphaBlend := false;
318         TransAction.Checked := false;
319         TransToolButton.Down := false;
320     end;
321         // \94¼\93§\96¾\8fó\91Ô\82Ì\95Û\91
322         GikoSys.Setting.EditWindowTranslucent := TransAction.Checked;
323 end;
324
325 procedure TEditorForm.SetBoard(Item: TBoard);
326 begin
327         FBoard := Item;
328         Caption := CAPTION_NAME_NEW + ' - [' + Item.Title + ']';
329         NameComboBox.Text := FBoard.KotehanName;
330         MailComboBox.Text := FBoard.KotehanMail;
331         SageCheckBox.Checked := AnsiPos('sage', MailComboBox.Text) <> 0;
332         TitlePanel.Visible := True;
333     SetSamba24('');
334 end;
335
336 procedure TEditorForm.SetThreadItem(Item: TThreadItem);
337 begin
338         FThreadItem := Item;
339         Caption := CAPTION_NAME_RES + ' - [' + FThreadItem.Title + ']';
340         NameComboBox.Text := FThreadItem.ParentBoard.KotehanName;
341         MailComboBox.Text := FThreadItem.ParentBoard.KotehanMail;
342         SageCheckBox.Checked := AnsiPos('sage', MailComboBox.Text) <> 0;
343         TitlePanel.Visible := False;
344     SetSamba24(FThreadItem.ParentBoard.URL);
345 end;
346
347 function TEditorForm.GetBody : string;
348 var
349         body            : string;
350         regexp  : TAWKStr;
351 begin
352
353         body := BodyEdit.Text;
354         if GikoSys.Setting.AmpToCharRef then
355                 // & \82Ì\92u\8a·\82Í\88ê\94Ô\8dÅ\8f\89\82É\82â\82é\82±\82Æ
356                 body := CustomStringReplace( body, '&', '&amp;' );
357         if GikoSys.Setting.SpaceToNBSP then begin
358                 body := CustomStringReplace( body, #09, '&nbsp;&nbsp;&nbsp;&nbsp;' );
359                 body := CustomStringReplace( body, '  ', '&nbsp;&nbsp;' );
360                 body := CustomStringReplace( body, '&nbsp; ', '&nbsp;&nbsp;' );
361                 regexp := TAWKStr.Create( nil );
362                 try
363                         regexp.RegExp := '^ ';
364                         regexp.GSub( '\&nbsp;', body );
365                 finally
366                         regexp.Free;
367                 end;
368         end;
369
370         Result  := body;
371
372 end;
373
374 procedure TEditorForm.SetFont;
375 begin
376         BodyEdit.Font.Name := GikoSys.Setting.EditorFontName;
377         BodyEdit.Font.Size := GikoSys.Setting.EditorFontSize;
378         BodyEdit.Font.Color := GikoSys.Setting.EditorFontColor;
379         BodyEdit.Color := GikoSys.Setting.EditorBackColor;
380 end;
381
382 procedure TEditorForm.Preview;
383 var
384         Title: string;
385         No: string;
386         Mail: string;
387         Namae: string;
388         DateTime: string;
389         Body: string;
390         s: string;
391
392                                 posTrip : Integer;
393                                 tripOrigin : string;
394 begin
395         if FThreadItem = nil then begin
396                 No := '1';
397                 Title := RepHtml(TitleEdit.Text);
398         end else begin
399                 No := IntToStr(FThreadItem.Count + 1);
400                 Title := RepHtml(FThreadItem.Title);
401         end;
402
403         body := GetBody;
404
405         Namae := RepHtml(NameComboBox.Text);
406         Mail := RepHtml(MailComboBox.Text);
407         Body := RepHtml(body);
408         Body := StringReplace(Body, #13#10, '<br>', [rfReplaceAll]);
409         DateTime := FormatDateTime('yyyy/mm/dd(aaa) hh:nn', now);
410
411         if Trim(Namae) = '' then
412                 Namae := '\96¼\96³\82µ\82³\82ñ';
413
414         s := '<HTML><HEAD>' + #13#10
415                         + '<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">' + #13#10
416                         + '<TITLE>' + title + '</TITLE>' + #13#10
417 //                      + '<STYLE><!--BODY{font-size : 9pt;font-family : "\82l\82\82o\83S\83V\83b\83N";}--></STYLE>' + #13#10
418                         + '</HEAD>' + #13#10
419                         + '<BODY text="#000000" bgcolor="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">' + #13#10
420                         + '<FONT COLOR="#FF0000">' + title + '</FONT>' + #13#10
421                         + '<DL>' + #13#10;
422                                 posTrip := AnsiPos( '#', Namae );
423                                 if posTrip > 0 then
424                                 begin
425                                                                 tripOrigin := Copy( Namae, posTrip + 1, Length( Namae ) );
426                                                                 Namae :=
427                                                                                                 Copy( Namae, 1, posTrip - 1 ) + '</B> \81\9f' +
428                                                                                                 get_2ch_trip( PChar( tripOrigin ) ) + '<B>';
429                                 end;
430         if Mail = '' then
431                 s := s + '<DT>' + No + ' \81F <FONT color="forestgreen"><B>' + Namae + '</B></FONT> \81F ' + DateTime+ '<BR><DD>' + Body + '<BR><BR><BR>' + #13#10
432         else
433                 s := s + '<DT>' + No + ' \81F <A href="mailto:' + Mail + '"><B>' + Namae + '</B></A> [' + Mail + ']\81F ' + DateTime+ '<BR><DD>' + Body + '<BR><BR><BR>' + #13#10;
434         s := s + '</BODY></HTML>';
435         SetContent(s);
436 end;
437
438 function TEditorForm.RepHtml(s: string): string;
439 begin
440 //      s := StringReplace(s, '&', '&amp;', [rfReplaceAll]);
441         s := StringReplace(s, '<', '&lt;', [rfReplaceAll]);
442         s := StringReplace(s, '>', '&gt;', [rfReplaceAll]);
443 //      s := StringReplace(s, ' ', '&nbsp;', [rfReplaceAll]);   //\8ed\97l\95Ï\8dX\82É\82æ\82è&nbsp;\8eg\97p\95s\89Â
444         s := StringReplace(s, '"', '&quot;', [rfReplaceAll]);
445         Result := s;
446 end;
447
448 procedure TEditorForm.EditorPageChange(Sender: TObject);
449 begin
450         if EditorPage.ActivePage = PreviewTab then begin
451                 Preview;
452         end else begin
453                 Browser.Navigate('about:blank');
454         end;
455 end;
456
457 procedure TEditorForm.BrowserStatusTextChange(Sender: TObject;
458         const Text: WideString);
459 begin
460         if EditorPage.ActivePage = PreviewTab then begin
461                 StatusBar.Panels[0].Text := Text;
462         end else begin
463                 StatusBar.Panels[0].Text := '';
464         end;
465 end;
466
467 function TEditorForm.Check: Boolean;
468 var
469         Msg: string;
470         rc: Integer;
471         Board: TBoard;
472 begin
473         Result := True;
474         if FThreadItem = nil then
475                 Board := FBoard
476         else
477                 Board := FThreadItem.ParentBoard;
478
479         if (not GikoSys.Setting.UseMachineTime) and
480                  ((Board.LastGetTime = 0) or
481                         (Board.LastGetTime = ZERO_DATE)) then begin
482                 Msg := '\83T\81[\83o\82Ì\8e\9e\8d\8f\82ª\95ª\82©\82ç\82È\82¢\82½\82ß\81A\91\97\90M\8fo\97\88\82Ü\82¹\82ñ'#13#10
483                                  + '\83X\83\8c\83b\83h\82ð\8dX\90V\81i\8eæ\93¾\81j\8cã\81A15\95b\91Ò\82Á\82Ä\82©\82ç\91\97\90M\82µ\82Ä\82­\82¾\82³\82¢';
484                 MsgBox(Handle, Msg, '\83G\83\89\81[', MB_OK or MB_ICONSTOP);
485                 Result := False;
486         end else if BodyEdit.Text = '' then begin
487                 Msg := '\96{\95\82ª\93ü\97Í\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B';
488                 MsgBox(Handle, Msg, '\83G\83\89\81[', MB_OK or MB_ICONSTOP);
489                 Result := False;
490         end else if (FBoard <> nil) and (Trim(TitleEdit.Text) = '') then begin
491                 Msg := '\83^\83C\83g\83\8b\82ª\93ü\97Í\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B';
492                 MsgBox(Handle, Msg, '\83G\83\89\81[', MB_OK or MB_ICONSTOP);
493                 Result := False;
494         end else begin
495                 if (not GikoSys.Dolib.Connected) and (AnsiPos('\81\9c', NameComboBox.Text) <> 0) then begin
496                         Msg := '\83\8d\83O\83C\83\93\82µ\82Ä\82¢\82È\82¢\82Ì\82Å\81\9c\82Ì\8b@\94\\82Í\97\98\97p\8fo\97\88\82Ü\82¹\82ñ\81B'#13#10
497                                          + '\82±\82Ì\82Ü\82Ü\91\97\90M\82µ\82Ä\82à\82æ\82ë\82µ\82¢\82Å\82·\82©\81H';
498                         rc := MsgBox(Handle, Msg, '\8am\94F', MB_YESNO or MB_ICONQUESTION);
499                         Result := (rc = IDYES);
500                 end;
501         end;
502 end;
503
504 procedure TEditorForm.FormClose(Sender: TObject; var Action: TCloseAction);
505 begin
506         Action := caFree;
507 end;
508
509 procedure TEditorForm.FormDestroy(Sender: TObject);
510 var
511         wp: TWindowPlacement;
512 begin
513         //\8dÅ\91å\89»\81E\83E\83B\83\93\83h\83E\88Ê\92u\95Û\91
514         wp.length := sizeof(wp);
515         GetWindowPlacement(Handle, @wp);
516
517         GikoSys.Setting.EditWindowTop := wp.rcNormalPosition.Top;
518         GikoSys.Setting.EditWindowLeft := wp.rcNormalPosition.Left;
519         GikoSys.Setting.EditWindowHeight := wp.rcNormalPosition.Bottom - wp.rcNormalPosition.Top;
520         GikoSys.Setting.EditWindowWidth := wp.rcNormalPosition.Right - wp.rcNormalPosition.Left;
521         GikoSys.Setting.EditWindowMax := WindowState = wsMaximized;
522         //GikoSys.Setting.EditWindowStay := FormStyle = fsStayOnTop;      // \83X\83e\83C\8fó\91Ô\82Ì\95Û\91
523         GikoSys.Setting.EditWindowTranslucent := TransAction.Checked;   // \94¼\93§\96¾\8fó\91Ô\82Ì\95Û\91
524
525 end;
526
527 procedure TEditorForm.SetNameList(sName, sMail: string);
528 begin
529         if Trim(sName) <> '' then begin
530                 if GikoSys.Setting.NameList.IndexOf(sName) = -1 then
531                         GikoSys.Setting.NameList.Insert(0, sName);
532         end;
533         if Trim(sMail) <> '' then begin
534                 if GikoSys.Setting.MailList.IndexOf(sMail) = -1 then
535                         GikoSys.Setting.MailList.Insert(0, sMail);
536         end;
537 end;
538
539 function TEditorForm.GetActiveControlHandle: THandle;
540 begin
541         if EditorPage.ActivePage = EditorTab then begin
542                 if ActiveControl = NameComboBox then
543                         Result := FNameComboEdit
544                 else if ActiveControl = MailComboBox then
545                         Result := FMailComboEdit
546                 else if ActiveControl = BodyEdit then
547                         Result := BodyEdit.Handle
548                 else if ActiveControl = TitleEdit then
549                         Result := TitleEdit.Handle
550                 else
551                         Result := 0;
552         end else
553                 Result := 0;
554 end;
555
556 procedure TEditorForm.SetContent(Content: string);
557 var
558         doc : Variant;
559 begin
560         if Browser.Document <> nil then begin
561                 doc := Browser.Document;
562                 doc.Clear;
563                 doc.open;
564                 doc.charset := 'Shift_JIS';
565                 doc.Write(Content);
566                 doc.Close;
567         end;
568 end;
569
570 procedure TEditorForm.Send(SPID: string; PON: string; FirstWriting: Boolean);
571 var
572         TextStream: TStringStream;
573         Source: TStringStream;
574         ResponseText: string;
575         URL: string;
576         RefURL: string;
577         State: TGikoDownloadState;
578         ResultType: TGikoResultType;
579         MsgResult: Integer;
580         Cookie: string;
581         Board: TBoard;
582         sysMenu : HMENU;
583 begin
584         FAbort := False;
585         State := gdsError;
586         if FThreadItem = nil then
587                 Board := FBoard
588         else
589                 Board := FThreadItem.ParentBoard;
590
591         Indy.Request.Clear;
592         Indy.ProxyParams.BasicAuthentication := False;
593         if GikoSys.Setting.WriteProxy then begin
594                 Indy.ProxyParams.ProxyServer := GikoSys.Setting.WriteProxyAddress;
595                 Indy.ProxyParams.ProxyPort := GikoSys.Setting.WriteProxyPort;
596                 Indy.ProxyParams.ProxyUsername := GikoSys.Setting.WriteProxyUserID;
597                 Indy.ProxyParams.ProxyPassword := GikoSys.Setting.WriteProxyPassword;
598                 if GikoSys.Setting.ReadProxyUserID <> '' then
599                         Indy.ProxyParams.BasicAuthentication := True;
600         end else begin
601                 Indy.ProxyParams.ProxyServer := '';
602                 Indy.ProxyParams.ProxyPort := 80;
603                 Indy.ProxyParams.ProxyUsername := '';
604                 Indy.ProxyParams.ProxyPassword := '';
605         end;
606         if FThreadItem = nil then begin
607                 URL := FBoard.GetSendURL;
608                 RefURL := GikoSys.UrlToServer(FBoard.URL) + 'test/bbs.cgi';
609         end else begin
610                 URL := FThreadItem.GetSendURL;
611                 RefURL := FThreadItem.URL;
612         end;
613         Indy.Request.UserAgent := GikoSys.GetUserAgent;
614         Indy.Request.Referer := RefURL;
615         Indy.Request.AcceptEncoding := '';
616
617         Cookie := '';
618         if SPID <> '' then
619                 Cookie := Cookie + 'SPID=' + SPID + '; ';
620         if PON <> '' then
621                 Cookie := Cookie + 'PON=' + PON + '; ';
622         Cookie := 'Cookie: ' + Cookie + 'NAME=' + NameComboBox.Text + '; MAIL=' + MailComboBox.Text;
623
624         sysMenu := GetSystemMenu( Handle, false );
625         EnableMenuItem( sysMenu, SC_CLOSE, MF_GRAYED );
626 {
627   EnableMenuItem(SysMenu, SC_CLOSE, MF_BYCOMMAND or MF_ENABLED);
628   DrawMenuBar(Handle);
629 }
630         Indy.Request.CustomHeaders.Clear;
631 //      Indy.Request.CacheControl := 'no-cache';
632         Indy.Request.CustomHeaders.Add('Pragma: no-cache');
633         Indy.Request.AcceptLanguage := 'ja';
634         Indy.Request.Accept := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*';
635         Indy.Request.ContentType := 'application/x-www-form-urlencoded';
636         Indy.Request.CustomHeaders.Add(Cookie);
637         TextStream := TStringStream.Create('');
638         Source := TStringStream.Create('');
639         try
640                 try
641                         FDebugStrReceive := '';
642                         FDebugStrSend := '';
643                         GetSendData(Source);
644                         Indy.Post(URL, Source, TextStream);
645                         ResponseText := TextStream.DataString;
646
647                         ResultType := GetResultType(ResponseText);
648
649                         if ResultType = grtOK then begin
650                 WriteSambaTime(FHost, Now());
651                                 State := gdsComplete;
652                         end else if ResultType = grtCookie then begin
653                                 //\83\8b\81[\83v\96h\8e~
654                                 if not FirstWriting then
655                                         raise Exception.Create('');
656                                 MsgResult := MsgBox(
657                                         Handle,
658                                         '\81E\93\8a\8de\82³\82ê\82½\93à\97e\82Í\83R\83s\81[\81A\95Û\91\81A\88ø\97p\81A\93]\8dÚ\93\99\82³\82ê\82é\8fê\8d\87\82ª\82 \82è\82Ü\82·\81B' + #13#10 +
659                                         '\81E\93\8a\8de\82É\8aÖ\82µ\82Ä\94­\90\82·\82é\90Ó\94C\82Í\91S\82Ä\93\8a\8de\8eÒ\82É\8bA\82µ\82Ü\82·\81B' + #13#10#13#10 +
660                                         '\91S\90Ó\94C\82ð\95\89\82¤\82±\82Æ\82ð\8f³\91ø\82µ\82Ä\8f\91\82«\8d\9e\82Ý\82Ü\82·\82©\81H',
661                                         '\8fî\95ñ',
662                                         MB_YESNO or MB_ICONQUESTION);
663                                 if MsgResult = IDYES then begin
664                                         Board.SPID := GetSPID(Indy.Response.RawHeaders.Values['Set-Cookie']);
665                                         Board.PON := GetPON(Indy.Response.RawHeaders.Values['Set-Cookie']);
666                                         if (Board.SPID = '') and (Board.PON = '') then
667                                                 raise Exception.Create('');
668                                         //\82à\82¤\88ê\89ñ\82±\82Ì\83\81\83\\83b\83h
669                                         Send(Board.SPID, Board.PON, False);
670                                         Exit;
671                                 end else begin
672                                         Board.SPID := '';
673                                         Board.PON := '';
674                                         FWork := false;
675                                         EnableMenuItem(SysMenu, SC_CLOSE, MF_BYCOMMAND or MF_ENABLED);
676                                         DrawMenuBar(Handle);
677                                         Exit;
678                                 end;
679                         end else if ResultType = grtCheck then begin
680                                 //
681                                 //\83\8b\81[\83v\96h\8e~
682                                 if not FirstWriting then
683                                         raise Exception.Create('');
684
685                                 MsgResult := MsgBox(
686                                         Handle,
687                                         '\8f\91\82«\8d\9e\82Ý\82É\8aÖ\82µ\82Ä\82Í\97l\81X\82È\83\8d\83O\8fî\95ñ\82ª\8bL\98^\82³\82ê\82Ä\82¢\82Ü\82·\81B' + #13#10 +
688                                         '\93\8a\8de\82É\8aÖ\82µ\82Ä\94­\90\82·\82é\90Ó\94C\82Í\91S\82Ä\93\8a\8de\8eÒ\82É\8bA\82µ\82Ü\82·\81B' + #13#10 +
689                                         '\8cö\8f\98\97Ç\91­\82É\94½\82µ\82½\82è\81A\91¼\90l\82É\96À\98f\82ð\82©\82¯\82é\8f\91\82«\8d\9e\82Ý\82Í\8dT\82¦\82Ä\89º\82³\82¢\81B' + #13#10 +
690                                         '\93\8a\8de\82³\82ê\82½\93à\97e\82Í\83R\83s\81[\81E\95Û\91\81E\88ø\97p\81E\93]\8dÚ\93\99\82³\82ê\82é\8fê\8d\87\82ª\82 \82è\82Ü\82·\81B' + #13#10 +
691                                         #13#10 +
692                                         '\91S\90Ó\94C\82ð\95\89\82¤\82±\82Æ\82ð\8f³\91ø\82µ\82Ä\8f\91\82«\8d\9e\82Ý\82Ü\82·\82©\81H',
693                                         '\8am\94F',
694                                         MB_YESNO or MB_ICONQUESTION);
695
696                                 if MsgResult = IDYES then begin
697                                         Board.SPID := GetSPID(Indy.Response.RawHeaders.Values['Set-Cookie']);
698                                         Board.PON := GetPON(Indy.Response.RawHeaders.Values['Set-Cookie']);
699                                         if (Board.SPID = '') and (Board.PON = '') then
700                                                 raise Exception.Create('');
701                                         Send(Board.SPID, Board.PON, False);
702                                         Exit;
703                                 end else begin
704                                         EnableMenuItem(SysMenu, SC_CLOSE, MF_BYCOMMAND or MF_ENABLED);
705                                         DrawMenuBar(Handle);
706                                         Board.SPID := '';
707                                         Board.PON := '';
708                                         FWork := false;
709                                         Exit;
710                                 end;
711                         end else begin
712                 WriteSambaTime(FHost, Now());
713                                 State := gdsError;
714                                 raise Exception.Create('');
715                         end;
716                 except
717                         on E: EIdConnectException do begin
718                                 State := gdsError;
719                                 ResponseText := '<html><body>'
720                                                                                         + '<div>\90Ú\91±\82ª\8e¸\94s\82µ\82Ü\82µ\82½<br>'
721                                                                                         + '\89ñ\90ü\82â\83v\83\8d\83L\83V\82Ì\8fó\91Ô\82ð\92²\82×\82Ä\82­\82¾\82³\82¢<br></div>'
722                                                                                         + '<br><br><div>' + E.Message + '</div>'
723                                                                                         + '</body></html>';
724                         end;
725                         on E: Exception do begin
726                                 State := gdsError;
727
728                                 FDebugStrReceive := AnsiReplaceText(FDebugStrReceive, '<', '&lt;');
729                                 FDebugStrReceive := AnsiReplaceText(FDebugStrReceive, '>', '&gt;');
730                                 FDebugStrSend := AnsiReplaceText(FDebugStrSend, '<', '&lt;');
731                                 FDebugStrSend := AnsiReplaceText(FDebugStrSend, '>', '&gt;');
732
733                                 ResponseText := '<html><body>' + TextStream.DataString;
734                                 ResponseText := AnsiReplaceText(ResponseText, '</body>', '');
735                                 ResponseText := AnsiReplaceText(ResponseText, '</html>', '');
736                                 ResponseText := ResponseText + '<hr><div align="left"><pre>';
737                                 ResponseText := ResponseText + '<b>\82±\82±\82©\82ç\83M\83R\83i\83r\82Ì\8fî\95ñ</b>'#13#10;
738                                 ResponseText := ResponseText + #13#10'\81\9c\91\97\90M'#13#10;
739                                 ResponseText := ResponseText + FDebugStrSend;
740                                 ResponseText := ResponseText + #13#10'\81\9c\8eó\90M'#13#10;
741                                 ResponseText := ResponseText + FDebugStrReceive;
742                                 ResponseText := ResponseText + '</pre></div></body></html>';
743                         end;
744                 end;
745                 FStatusCode := Indy.ResponseCode;
746                 if FAbort then
747                         State := gdsAbort;
748         finally
749                 Source.Free;
750                 TextStream.Free;
751                 //sysMenu := GetSystemMenu( Handle, true );
752                 EnableMenuItem(SysMenu, SC_CLOSE, MF_BYCOMMAND or MF_ENABLED);
753                 DrawMenuBar(Handle);
754         end;
755         FWork := false;
756         if State = gdsComplete then begin
757                 GikoForm.PlaySound('ResEnd');
758                 SaveSendFile;
759                 if FThreadItem = nil then
760                         GikoForm.AddMessageList(FBoard.Title + ' [\90V\83X\83\8c\91\97\90M\8fI\97¹]', nil, gmiOK)
761                 else
762                         GikoForm.AddMessageList(FThreadItem.Title + ' [\83\8c\83X\91\97\90M\8fI\97¹]', nil, gmiOK);
763                 Close;
764         end else if State = gdsError then begin
765                 if FThreadItem = nil then
766                         GikoForm.AddMessageList(FBoard.Title + ' [\90V\83X\83\8c\91\97\90M\8e¸\94s]', nil, gmiNG)
767                 else
768                         GikoForm.AddMessageList(FThreadItem.Title + ' [\83\8c\83X\91\97\90M\8e¸\94s]', nil, gmiNG);
769                 EditorPage.ActivePage := PreviewTab;
770                 SetContent(ResponseText);
771         end else if State = gdsAbort then begin
772                 GikoForm.AddMessageList(FThreadItem.Title + ' [\92\86\92f]', nil, gmiSAD);
773         end;
774 end;
775
776 function TEditorForm.GetResultType(ResponseText: string): TGikoResultType;
777 begin
778         if AnsiPos('\8f\91\82«\82±\82Ý\82ª\8fI\82í\82è\82Ü\82µ\82½', ResponseText) <> 0 then
779                 Result := grtOK
780         else if (AnsiPos('\83N\83b\83L\81[\82ª\82È\82¢\82©\8aú\8cÀ\90Ø\82ê\82Å\82·', ResponseText) > 0) or
781                                         (AnsiPos('<title>\83N\83b\83L\81[\8am\94F\81I</title>', ResponseText) > 0)    or
782                                         (AnsiPos('<title>\81¡\83N\83b\83L\81[\8am\94F\81I\81¡</title>', ResponseText) > 0)        or
783                                         //(AnsiPos('\83N\83b\83L\81[\8am\94F', ResponseText) > 0) or
784                                         (AnsiPos(RES2CH_COOKIE, ResponseText) > 0)      then
785                 Result := grtCookie
786         else if (AnsiPos('<font size=+2 color=#FF0000>\8f\91\82«\8d\9e\82Ý\83`\83F\83b\83N\81I </font>', ResponseText) > 0)   or
787                                         (AnsiPos('<title>\81¡ \8f\91\82«\8d\9e\82Ý\8am\94F\82µ\82Ü\82· \81¡</title>', ResponseText) > 0)  or
788                                         (AnsiPos('<title>\93\8a\8de\8am\94F</title>', ResponseText) > 0)  or
789                                         (AnsiPos('<b>\8f\91\82«\82±\82Ý\8am\94F</b>', ResponseText) > 0)      or
790                                         (AnsiPos('="../test/subbbs.cgi">', ResponseText) > 0)   or
791                                         (AnsiPos(RES2CH_FALSE, ResponseText) > 0)       then
792                 Result := grtCheck
793         else
794                 Result := grtError;
795 end;
796
797
798 procedure TEditorForm.GetSendData(Source: TStringStream);
799 var
800         SessionID: string;
801         s: string;
802         SendTime: Integer;
803         Adjust: Integer;
804         Board: TBoard;
805         body            : string;
806 begin
807         if FThreadItem = nil then
808                 Board := FBoard
809         else
810                 Board := FThreadItem.ParentBoard;
811
812         if GikoSys.Setting.UseMachineTime then begin
813                 if GikoSys.Setting.TimeAdjust then
814                         Adjust := Gikosys.Setting.TimeAdjustSec
815                 else
816                         Adjust := GikoSys.Setting.TimeAdjustSec * -1;
817                 SendTime := GikoSys.DateTimeToInt(Now) - (9 * 60 * 60) + Adjust
818         end else begin
819                 if (Board.LastGetTime = 0) or (Board.LastGetTime = ZERO_DATE) then
820                         SendTime := GikoSys.DateTimeToInt(Now)
821                 else
822                         SendTime := GikoSys.DateTimeToInt(Board.LastGetTime);
823         end;
824
825         body := GetBody;
826
827         SessionID := GikoSys.Dolib.SessionID;
828         if SessionID <> '' then
829                 s := 'sid=' + HttpEncode(SessionID) + '&'
830         else
831                 s := '';
832         s := s + 'subject=&'
833                                  + 'FROM=' + HttpEncode(NameComboBox.Text) + '&'
834                                  + 'mail=' + HttpEncode(MailComboBox.Text) + '&'
835                                  + 'MESSAGE=' + HttpEncode(body) + '&'
836                                  + 'bbs=' + Board.BBSID + '&'
837                                  + 'time=' + IntToStr(SendTime) + '&';
838         if FThreadItem = nil then begin
839                 s := s + 'subject=' + HttpEncode(TitleEdit.Text) + '&';
840                 s := s + 'submit=' + HttpEncode('\91S\90Ó\94C\82ð\95\89\82¤\82±\82Æ\82ð\8f³\91ø\82µ\82Ä\8f\91\82«\8d\9e\82Þ') + #13#10;
841         end else begin
842                 s := s + 'key=' + ChangeFileExt(FThreadItem.FileName, '') + '&';
843                 s := s + 'submit=' + HttpEncode('\8f\91\82«\8d\9e\82Þ') + #13#10;
844         end;
845         Source.WriteString(s);
846 end;
847
848 procedure TEditorForm.SaveSendFile;
849 var
850         sDate: string;
851         ini: TMemIniFile;
852 begin
853         ini := TMemIniFile.Create(GikoSys.GetSentFileName);
854         try
855                 sDate := IntToStr(GikoSys.DateTimeToInt(Now));
856
857                 ini.WriteString(sDate, 'Name', NameComboBox.Text);
858                 ini.WriteString(sDate, 'EMail', MailComboBox.Text);
859                 ini.WriteString(sDate, 'Body', HttpEncode(BodyEdit.Text));
860                 ini.WriteInteger(sDate, 'Status', FStatusCode);
861                 ini.WriteDateTime(sDate, 'Date', Now);
862                 if FThreadItem = nil then begin
863                         ini.WriteString(sDate, 'Title', TitleEdit.Text);
864                         ini.WriteString(sDate, 'BBS', FBoard.BBSID);
865                         ini.WriteInteger(sDate, 'NewThread', 1);
866                 end else begin
867                         ini.WriteString(sDate, 'Title', FThreadItem.Title);
868                         ini.WriteString(sDate, 'BBS', FThreadItem.ParentBoard.BBSID);
869                         ini.WriteString(sDate, 'Key', ChangeFileExt(FThreadItem.FileName, ''));
870                 end;
871
872                 ini.UpdateFile;
873         finally
874                 ini.Free;
875         end;
876 end;
877
878 procedure TEditorForm.SendActionExecute(Sender: TObject);
879 var
880         Board: TBoard;
881         rc: Integer;
882         state : TGikoDownloadState;
883         body            : string;
884 begin
885         if FWork then
886                 Exit;
887         try
888                 FWork := True;
889                 SendAction.Enabled := False;
890                 Application.ProcessMessages;
891                 if not Check then Exit;
892
893                 if FThreadItem = nil then
894                         Board := FBoard
895                 else
896                         Board := FThreadItem.ParentBoard;
897
898                 if FThreadItem = nil then begin
899                         rc := GikoUtil.MsgBox(Handle,
900                                                                                                         '\81u' + Board.Title + '\81v\94Â\82É\90V\82µ\82¢\83X\83\8c\83b\83h\97§\82Ä\82Ü\82·'#13#10#13#10
901                                                                                                         + '\81E\94Â\82Ì\83\8b\81[\83\8b\82ð\8eç\82Á\82½\8f\91\82«\8d\9e\82Ý\82Å\82 \82é\82±\82Æ\82ð\8am\94F\82µ\82Ü\82µ\82½\82©\81H'#13#10
902                                                                                                         + '\81E\91¼\82É\93¯\82\82æ\82¤\82È\83X\83\8c\83b\83h\82ª\96³\82©\82Á\82½\82±\82Æ\82ð\8am\94F\82µ\82Ü\82µ\82½\82©\81H'#13#10#13#10
903                                                                                                         + '\81u\82Í\82¢\81v\82ð\89\9f\82·\82Æ\91\97\90M\82µ\82Ü\82·',
904                                                                                                         '\8am\94F',
905                                                                                                         MB_ICONQUESTION or MB_YESNO);
906                         if rc <> ID_YES then
907                                 Exit;
908                 end;
909
910                 SetNameList(NameComboBox.Text, MailComboBox.Text);
911                 if KotehanCheckBox.Checked then begin
912                         Board.KotehanName := NameComboBox.Text;
913                         Board.KotehanMail := MailComboBox.Text;
914                 end;
915
916                 if Board.IsBoardPlugInAvailable then begin
917                         body := GetBody;
918
919                         if FThreadItem = nil then begin
920                                 // \83X\83\8c\97§\82Ä
921                                 state := TGikoDownloadState( Board.BoardPlugIn.CreateThread(
922                                         DWORD( Board ), TitleEdit.Text, NameComboBox.Text, MailComboBox.Text, body ) );
923
924                                 if state = gdsComplete then begin
925                                         GikoForm.PlaySound('ResEnd');
926                                         SaveSendFile;
927                                         GikoForm.AddMessageList(FBoard.Title + ' [\90V\83X\83\8c\91\97\90M\8fI\97¹]', nil, gmiOK);
928                                         FWork := False;
929                                         Close;
930                                 end else if State = gdsError then begin
931                                         GikoForm.AddMessageList(FBoard.Title + ' [\90V\83X\83\8c\91\97\90M\8e¸\94s]', nil, gmiNG);
932                                 end else if State = gdsAbort then begin
933                                         GikoForm.AddMessageList(FThreadItem.Title + ' [\92\86\92f]', nil, gmiSAD);
934                                 end;
935                         end else begin
936                                 // \83\8c\83X
937                                 state := TGikoDownloadState( FThreadItem.BoardPlugIn.WriteThread(
938                                         DWORD( FThreadItem ), NameComboBox.Text, MailComboBox.Text, body ) );
939
940                                 if state = gdsComplete then begin
941                                         GikoForm.PlaySound('ResEnd');
942                                         SaveSendFile;
943                                         GikoForm.AddMessageList(FThreadItem.Title + ' [\83\8c\83X\91\97\90M\8fI\97¹]', nil, gmiOK);
944                     FWork := False;
945                                         Close;
946                                 end else if State = gdsError then begin
947                                         GikoForm.AddMessageList(FThreadItem.Title + ' [\83\8c\83X\91\97\90M\8e¸\94s]', nil, gmiNG);
948                                 end else if State = gdsAbort then begin
949                                         GikoForm.AddMessageList(FThreadItem.Title + ' [\92\86\92f]', nil, gmiSAD);
950                                 end;
951                         end;
952                 end else begin
953                         if not Timer1.Enabled then
954                                 Send(Board.SPID, Board.PON, True)
955                         else begin
956                                 if not CheckSambaTime(FHost, Now()) then begin
957                                         rc := GikoUtil.MsgBox(Handle,
958                                                                 'Samba24\82Ì\8bK\92è\92l\96¢\96\9e\82Ì\95b\90\94\82µ\82©\8co\89ß\82µ\82Ä\82¢\82Ü\82¹\82ñ\81B'#13#10
959                                                                 + '\91\97\90M\82ð\92\86\8e~\82µ\82Ü\82·\82©\81H' + #13#10
960                                                                 + '(\81u\82¢\82¢\82¦\81v\82¾\82Æ\91\97\90M\82µ\82Ü\82·)', 'Samba24\8cx\8d\90',
961                                                                 MB_YESNO or MB_ICONQUESTION);
962                                         if rc = IDYES then begin
963                                                 FWork := false;
964                                                 Exit;
965                                         end;
966                                 end;
967                                 Send(Board.SPID, Board.PON, True);
968                         end;
969                 end;
970         finally
971                 FWork := False;
972                 if Timer1.Enabled then
973                         ReadSambaTime(FHost);
974         end;
975 end;
976
977 procedure TEditorForm.SaveActionExecute(Sender: TObject);
978 begin
979 //
980 end;
981
982 procedure TEditorForm.CloseActionExecute(Sender: TObject);
983 begin
984         Close;
985 end;
986
987 procedure TEditorForm.UndoActionExecute(Sender: TObject);
988 begin
989         SendMessage(GetActiveControlHandle, WM_UNDO, 0, 0);
990 end;
991
992 procedure TEditorForm.CutActionExecute(Sender: TObject);
993 begin
994         SendMessage(GetActiveControlHandle, WM_CUT, 0, 0);
995 end;
996
997 procedure TEditorForm.CopyActionExecute(Sender: TObject);
998 begin
999         SendMessage(GetActiveControlHandle, WM_COPY, 0, 0);
1000 end;
1001
1002 procedure TEditorForm.PasteActionExecute(Sender: TObject);
1003 begin
1004         SendMessage(GetActiveControlHandle, WM_PASTE, 0, 0);
1005 end;
1006
1007 procedure TEditorForm.SelectAllActionExecute(Sender: TObject);
1008 begin
1009         SendMessage(GetActiveControlHandle, EM_SETSEL, 0, GetWindowTextLength(GetActiveControlHandle));
1010 end;
1011
1012 procedure TEditorForm.TopActionExecute(Sender: TObject);     // \83E\83B\83\93\83h\83E\8dÅ\91O\96Ê(Stay)\83{\83^\83\93\82Ì\8f\88\97\9d
1013 begin
1014         if not (fsShowing in Self.FormState) then begin
1015                 if TopAction.Checked then begin // \83X\83e\83C\8fó\91Ô\82É\90Ý\92è
1016                         SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
1017                         GikoSys.Setting.EditWindowStay := true;
1018                 end     else begin   // \83X\83e\83C\8fó\91Ô\89ð\8f\9c
1019                         SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
1020                         GikoSys.Setting.EditWindowStay := false;
1021                 end;
1022                 // \83X\83e\83C\8fó\91Ô\82Ì\95Û\91
1023                 //GikoSys.Setting.EditWindowStay := FormStyle = fsStayOnTop;
1024         end;
1025 end;
1026
1027 procedure TEditorForm.AbortActionExecute(Sender: TObject);
1028 begin
1029         FAbort := True;
1030 end;
1031
1032 procedure TEditorForm.SendActionUpdate(Sender: TObject);
1033 begin
1034         SendAction.Enabled := not FWork;
1035 end;
1036
1037 procedure TEditorForm.SaveActionUpdate(Sender: TObject);
1038 begin
1039         SaveAction.Enabled := False;
1040 end;
1041
1042 procedure TEditorForm.CloseActionUpdate(Sender: TObject);
1043 begin
1044         CloseAction.Enabled := not FWork;
1045 end;
1046
1047 procedure TEditorForm.UndoActionUpdate(Sender: TObject);
1048 begin
1049         UndoAction.Enabled := (GetActiveControlHandle <> 0)
1050                                                                                                 and (SendMessage(GetActiveControlHandle, EM_CANUNDO, 0, 0) <> 0)
1051                                                                                                 and (not FWork);
1052 end;
1053
1054 procedure TEditorForm.CutActionUpdate(Sender: TObject);
1055 var
1056         Selection: TSelection;
1057         AHandle: THandle;
1058 begin
1059         AHandle := GetActiveControlHandle;
1060         SendMessage(AHandle, EM_GETSEL, Longint(@Selection.StartPos), Longint(@Selection.EndPos));
1061         CutAction.Enabled := (AHandle <> 0)
1062                                                                                 and ((Selection.EndPos - Selection.StartPos) <> 0)
1063                                                                                 and (not FWork);
1064 end;
1065
1066 procedure TEditorForm.CopyActionUpdate(Sender: TObject);
1067 var
1068         Selection: TSelection;
1069         AHandle: THandle;
1070 begin
1071         AHandle := GetActiveControlHandle;
1072         SendMessage(AHandle, EM_GETSEL, Longint(@Selection.StartPos), Longint(@Selection.EndPos));
1073         CopyAction.Enabled := (AHandle <> 0)
1074                                                                                 and ((Selection.EndPos - Selection.StartPos) <> 0)
1075                                                                                 and (not FWork);
1076 end;
1077
1078 procedure TEditorForm.PasteActionUpdate(Sender: TObject);
1079 begin
1080         PasteAction.Enabled := (GetActiveControlHandle <> 0)
1081                                                                                         and (Clipboard.HasFormat(CF_TEXT))
1082                                                                                         and (not FWork);
1083 end;
1084
1085 procedure TEditorForm.TopActionUpdate(Sender: TObject);
1086 begin
1087         TopAction.Enabled := not FWork;
1088 end;
1089
1090 procedure TEditorForm.SageCheckBoxClick(Sender: TObject);
1091 begin
1092         if SageCheckBox.Checked then begin
1093                 if AnsiPos('sage', MailComboBox.Text) = 0 then
1094                         MailComboBox.Text := 'sage' + MailComboBox.Text;
1095         end else begin
1096                 if AnsiPos('sage', MailComboBox.Text) <> 0 then
1097                         MailComboBox.Text := StringReplace(MailComboBox.Text, 'sage', '', [rfReplaceAll]);
1098         end;
1099 end;
1100
1101 procedure TEditorForm.MailComboBoxChange(Sender: TObject);
1102 begin
1103         if AnsiPos('sage', MailComboBox.Text) = 0 then
1104                 SageCheckBox.Checked := False
1105         else
1106                 SageCheckBox.Checked := True;
1107 end;
1108
1109
1110 function TEditorForm.GetSPID(CookieLine: string): string;
1111 var
1112         s: string;
1113         i: Integer;
1114 begin
1115         Result := '';
1116         i := 0;
1117         while True do begin
1118                 s := Trim(GikoSys.GetTokenIndex(CookieLine, ';', i));
1119                 if s = '' then
1120                         Break
1121                 else begin
1122                         if Pos('SPID=', s) = 1 then begin
1123                                 Result := Trim(Copy(s, 6, Length(s)));
1124                                 Break;
1125                         end;
1126                 end;
1127                 inc(i);
1128         end;
1129 end;
1130
1131 function TEditorForm.GetPON(CookieLine: string): string;
1132 var
1133         s: string;
1134         i: Integer;
1135 begin
1136         Result := '';
1137         i := 0;
1138         while True do begin
1139                 s := Trim(GikoSys.GetTokenIndex(CookieLine, ';', i));
1140                 if s = '' then
1141                         Break
1142                 else begin
1143                         if Pos('PON=', s) = 1 then begin
1144                                 Result := Trim(Copy(s, 5, Length(s)));
1145                                 Break;
1146                         end;
1147                 end;
1148                 inc(i);
1149         end;
1150 end;
1151
1152 procedure TEditorForm.IdLogDebugReceive(ASender: TIdConnectionIntercept;
1153         AStream: TStream);
1154 var
1155         StringStream: TStringStream;
1156 begin
1157         StringStream := TStringStream.Create('');
1158         try
1159                 StringStream.CopyFrom(AStream, AStream.Size);
1160                 FDebugStrReceive := FDebugStrReceive + StringStream.DataString;
1161         finally
1162                 StringStream.Free;
1163         end;
1164 end;
1165
1166 procedure TEditorForm.IdLogDebugSend(ASender: TIdConnectionIntercept;
1167         AStream: TStream);
1168 var
1169         StringStream: TStringStream;
1170 begin
1171         StringStream := TStringStream.Create('');
1172         try
1173                 StringStream.CopyFrom(AStream, AStream.Size);
1174                 FDebugStrSend := FDebugStrSend + StringStream.DataString;
1175         finally
1176                 StringStream.Free;
1177         end;
1178 end;
1179
1180 procedure TEditorForm.TransActionExecute(Sender: TObject);
1181 begin
1182         AlphaBlend := TransAction.Checked;
1183         // \94¼\93§\96¾\8fó\91Ô\82Ì\95Û\91
1184         GikoSys.Setting.EditWindowTranslucent := TransAction.Checked;
1185 end;
1186
1187 procedure TEditorForm.TransActionUpdate(Sender: TObject);
1188 begin
1189         TransAction.Enabled := not FWork;
1190 end;
1191 //StatusBar\82ÌPanels[0]\82Ì\95\9d\82ð\89Â\95Ï\81B\8ec\82è\82ð\8cÅ\92è\82É\82·\82é
1192 procedure TEditorForm.StatusBarResize(Sender: TObject);
1193 begin
1194         StatusBar.Panels[0].Width := StatusBar.Width
1195                                                                         - StatusBar.Panels[1].Width - StatusBar.Panels[2].Width;
1196
1197 end;
1198
1199 procedure TEditorForm.Timer1Timer(Sender: TObject);
1200 begin
1201         if FSambaTime = ZERO_DATE then
1202                 StatusBar.Panels[1].Text := '\8f\89\8f\91'
1203         else begin
1204                 FNow := IncMilliSecond(FNow, 500);
1205                 StatusBar.Panels[1].Text := Format('%8.0f\95b\8co\89ß', [SecondSpan(FNow, FSambaTime)]);
1206         end;
1207
1208 end;
1209 //Samba.ini\82Ì\8f\91\82«\8d\9e\82Ý\8e\9e\8aÔ\82ð\93Ç\82Ý\8d\9e\82Þ
1210 procedure TEditorForm.ReadSambaTime(const AHost: string);
1211 var
1212         ini :TMemIniFile;
1213         tmp: string;
1214 begin
1215         Timer1.Enabled := false; //\8co\89ß\95b\90\94\95\\8e¦Timer\82ðOff\82É\82·\82é\81i\82±\82ê\82ªON\82Ì\82Æ\82«Samba24\91Î\8dôOn\81j
1216         FNow := Now();   //\8c»\8dÝ\8e\9e\8aÔ\82ð\8eæ\93¾\81iTimer\95\\8e¦\97p\82Å\81ACheck\82·\82é\82Æ\82«\82Í\8dÄ\82ÑNow()\82ð\8cÄ\82Ô\81j
1217         Timer1.Enabled := true; //\8co\89ß\95b\90\94\95\\8e¦Timer\82ðOn\82É\82·\82é\81i\82±\82ê\82ªON\82Ì\82Æ\82«Samba24\91Î\8dôOn\81j
1218         ini := TMemIniFile.Create(GikoSys.GetSambaFileName);
1219         try
1220                  //\95\8e\9a\97ñ\82Å\93Ç\82Ý\8eæ\82Á\82Ä\81A\95Ï\8a·\8aÖ\90\94\82ÅTDateTime\82Ö
1221                  tmp := ini.ReadString('Send', AHost, DateTimeToStr(ZERO_DATE));
1222                  FSambaTime := ConvertDateTimeString(tmp);
1223         finally
1224                 ini.Free;
1225         end;
1226 end;
1227 //Samba.ini\82É\8dÅ\8fI\8f\91\82«\8d\9e\82Ý\8e\9e\8aÔ\82ð\8f\91\82«\8d\9e\82Þ
1228 procedure TEditorForm.WriteSambaTime(const AHost: string; ATime: TDateTime);
1229 var
1230         ini :TMemIniFile;
1231 begin
1232         ini := TMemIniFile.Create(GikoSys.GetSambaFileName);
1233         try
1234                 ini.WriteDateTime('Send', AHost, ATime);
1235                 ini.UpdateFile;
1236         finally
1237                 ini.Free;
1238         end;
1239 end;
1240 //\8dÅ\8fI\8f\91\82«\8d\9e\82Ý\8e\9e\8aÔ\82Æ\8c»\8dÝ\8e\9e\82ð\94ä\8ar\82·\82é\81i\90^\81F\8bK\92è\92l\88È\8fã\81@\8bU\81F\8bK\92è\92l\96¢\96\9e\81j
1241 function TEditorForm.CheckSambaTime(const AHost: string; ATime: TDateTime): Boolean;
1242 var
1243         pastsec: double;
1244         SettingTime: Integer;
1245 begin
1246         SettingTime := ReadSettingTime(AHost);
1247         ReadSambaTime(AHost);
1248         pastsec := SecondSpan(ATime, FSambaTime);
1249         if pastsec > SettingTime then
1250                 Result := true
1251         else
1252                 Result := false;
1253 end;
1254 //AHost\81i\8eI\96¼\81j\82ÌSamba\82Ì\8bK\92è\92l\82ð\93Ç\82Ý\8d\9e\82Þ
1255 function TEditorForm.ReadSettingTime(const AHost: string): Integer;
1256 var
1257         ini :TMemIniFile;
1258 begin
1259         ini := TMemIniFile.Create(GikoSys.GetSambaFileName);
1260         try
1261                 Result := ini.ReadInteger('Setting', AHost, 0);
1262                 //\8bK\92è\92l\82ª\82O\82Ì\82Æ\82«\81A\82à\82µ\82­\82Í\90Ý\92è\82³\82ê\82Ä\82¢\82È\82¢\82Æ\82«\82Í\81A\83t\83@\83C\83\8b\82É\8f\91\82«\82½\82·\81B
1263                 if Result = 0 then begin
1264                         ini.WriteInteger('Setting', AHost, 0);
1265                         ini.UpdateFile;
1266                 end;
1267         finally
1268                 ini.Free;
1269         end;
1270 end;
1271 //Form\82ªActive\82É\82È\82Á\82½\82ç\8dÅ\8fI\8f\91\82«\8d\9e\82Ý\8e\9e\8aÔ\82ð\93Ç\82Ý\8d\9e\82Þ
1272 procedure TEditorForm.FormActivate(Sender: TObject);
1273 begin
1274         if ( Timer1.Enabled ) and ( FThreadItem <> nil )then
1275                 ReadSambaTime(FHost);
1276 end;
1277 //Samba24\91Î\8dô\82ð\8eg\82¤\82©\82Ç\82¤\82©\8c\88\82ß\82é\8aÖ\90\94
1278 //ReadSambaTime \82ð\8cÄ\82Ñ\8fo\82·\82ÆTimer\82ªOn\82É\82È\82é
1279 procedure TEditorForm.SetSamba24(AURL: string);
1280 var
1281         Protocol, Host, Path, Document, Port, Bookmark : string;
1282 begin
1283         //Samba24\91Î\8dô\82ð\82µ\82È\82¢\82È\82ç\8fI\97¹
1284         if not GikoSys.Setting.UseSamba then
1285                 Exit;
1286         //Host\82ÌURL\82É'.2ch.'\82©'.bbspink.'\82ª\8aÜ\82Ü\82ê\82Ä\82¢\82½\82çSamba24\91Î\8dô\82ð\82·\82é
1287         GikoSys.ParseURI( AURL, Protocol,Host, Path, Document, Port, Bookmark );
1288         if GikoSys.Is2chHost(Host) then begin
1289                 Host := Copy(Host, 1, AnsiPos('.', Host) - 1);
1290                 FHost := Host;   //FHost=\8eI\96¼
1291                 ReadSambaTime(FHost); //\88È\91O\82Ì\8f\91\82«\8d\9e\82Ý\8e\9e\8aÔ\82ð\93Ç\82Ý\8d\9e\82Þ
1292                 //StatusBar\82É\82±\82Ì\8eI\82Ì\8bK\92è\92l\82ð\95\\8e¦\82·\82é
1293                 StatusBar.Panels[2].Text := 'Samba24\8bK\92è\92l' + IntToStr(ReadSettingTime(FHost));
1294         end;
1295 end;
1296 procedure TEditorForm.FormCloseQuery(Sender: TObject;
1297   var CanClose: Boolean);
1298 begin
1299         CanClose := not FWork;
1300 end;
1301
1302 function TEditorForm.GetOEIndentChar : string;
1303 var
1304         regKey                  : TRegistry;
1305         Identities      : string;
1306         IndentChar      : DWORD;
1307 const
1308         DEFAULT_CHAR    = '> ';
1309         OE_MAIL_PATH    = '\Software\Microsoft\Outlook Express\5.0\Mail';
1310         INDENT_CHAR             = 'Indent Char';
1311 begin
1312
1313         Result  := DEFAULT_CHAR;
1314         regKey  := TRegistry.Create;
1315         try
1316                 try
1317                         regKey.RootKey  := HKEY_CURRENT_USER;
1318                         if not regKey.OpenKey( 'Identities', False ) then
1319                                 Exit;
1320                         Identities                      := regKey.ReadString( 'Default User ID' );
1321                         if Identities = '' then
1322                                 Exit;
1323                         if not regKey.OpenKey( Identities + OE_MAIL_PATH, False ) then
1324                                 Exit;
1325                         IndentChar := regKey.ReadInteger( INDENT_CHAR );
1326                         Result := Char( IndentChar ) + ' ';
1327                 except
1328                 end;
1329         finally
1330                 regKey.Free;
1331         end;
1332
1333 end;
1334
1335 procedure TEditorForm.QuotePasteActionExecute(Sender: TObject);
1336 var
1337         s                       : TStringList;
1338         i                       : Integer;
1339         quote   : string;
1340 begin
1341
1342         quote   := GetOEIndentChar;
1343         s                       := TStringList.Create;
1344         try
1345                 s.Text  := Clipboard.AsText;
1346
1347                 for i := s.Count - 1 downto 0 do
1348                         s[ i ]  := quote + s[ i ];
1349
1350                 BodyEdit.SelText        := s.Text;
1351         finally
1352                 s.Free;
1353         end;
1354
1355 end;
1356
1357 end.
1358