OSDN Git Service

・板一覧更新の処理メッセージを追加
[gikonavigoeson/gikonavi.git] / ExternalBoardPlugInMain.pas
1 unit ExternalBoardPlugInMain;
2
3 interface
4
5 uses
6         Windows, Classes, SysUtils, Menus,
7         IdHTTP, IdComponent, IdGlobal, IdException,
8         AbonUnit, IdAntiFreezeBase, Forms;
9
10 type
11
12         // \83_\83E\83\93\83\8d\81[\83h\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
13         TDownloadState = (dsWait, dsWork, dsComplete, dsDiffComplete, dsNotModify, dsAbort, dsError);
14
15         // \8ew\92è\82µ\82½ URL \82ð\82±\82Ì\83v\83\89\83O\83C\83\93\82Å\8eó\82¯\95t\82¯\82é\82©\82Ç\82¤\82©
16         TAcceptType = (atNoAccept, atBBS, atBoard, atThread);
17
18         // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
19         TMenuHandler    = procedure(
20                 inHandle : HMENU                                        // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
21         ); stdcall;
22
23         // *************************************************************************
24         // \83v\83\89\83O\83C\83\93\82ª(\90³\82µ\82­)\83\8d\81[\83h\82³\82ê\82½
25         // *************************************************************************
26         TOnLoad = procedure (
27                 inInstance : DWORD                              // \83v\83\89\83O\83C\83\93\82Ì\83C\83\93\83X\83^\83\93\83X
28         ); stdcall;
29
30         // *************************************************************************
31         // \83v\83\89\83O\83C\83\93\82Ì\83o\81[\83W\83\87\83\93
32         // *************************************************************************
33         TOnVersionInfo = procedure(
34                 var outAgent            : PChar;        // \83o\81[\83W\83\87\83\93\82ð\88ê\90Ø\8aÜ\82Ü\82È\82¢\8f\83\90\88\82È\96¼\8fÌ
35                 var outMajor            : DWORD;        // \83\81\83W\83\83\81[\83o\81[\83W\83\87\83\93
36                 var outMinor            : DWORD;        // \83}\83C\83i\81[\83o\81[\83W\83\87\83\93
37                 var outRelease  : PChar;        // \83\8a\83\8a\81[\83X\92i\8aK\96¼
38                 var outRevision : DWORD         // \83\8a\83r\83W\83\87\83\93\83i\83\93\83o\81[
39         ); stdcall;
40
41         // *************************************************************************
42         // \8ew\92è\82µ\82½ URL \82ð\82±\82Ì\83v\83\89\83O\83C\83\93\82Å\8eó\82¯\95t\82¯\82é\82©\82Ç\82¤\82©
43         // *************************************************************************
44         TOnAcceptURL = function(
45                 inURL : PChar                                           // \94»\92f\82ð\8bÂ\82¢\82Å\82¢\82é URL
46         ): TAcceptType; stdcall;        // URL \82Ì\8eí\97Þ
47
48         // *************************************************************************
49         // \8ew\92è\82µ\82½URL\82ð\8c»\8dÝ\82ÌURL\82É\95Ï\8a·\82·\82é
50         // *************************************************************************
51         TOnExtractBoardURL = procedure(
52                 inURL : PChar;                                          // \95Ï\8a·\82·\82éURL;
53         var outURL: PChar                                               // \95Ï\8a·\82³\82ê\82½URL
54         ); stdcall;     // \95Ï\8a·\82³\82ê\82½URL
55
56         // *************************************************************************
57         // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
58         // *************************************************************************
59         TOnPlugInMenu = procedure(
60                 inInstance : DWORD              // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
61         ); stdcall;
62
63         // *************************************************************************
64         // \83X\83\8c\88ê\97\97\82Ì URL \82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\93±\82«\8fo\82·
65         // *************************************************************************
66         TOnListURL2ThreadURL = function(
67                 inListURL               : PChar;        // \83X\83\8c\88ê\97\97\82ð\8e¦\82µ\82½ URL
68                 inFileName      : PChar         // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
69         ) : PChar; stdcall;                     // \83X\83\8c\83b\83h\82Ì URL
70
71
72 function CreateResultString(
73         resultStr : string
74 ) : PChar; stdcall;
75
76 procedure DisposeResultString(
77         resultStr : PChar
78 ); stdcall;
79
80 var
81         socket : TIdHTTP;
82
83 implementation
84
85 uses ExternalBoardManager, ExternalThreadItem, GikoSystem, BoardGroup, Giko,
86     ReplaceDataModule, AbonInfo;
87
88 // *************************************************************************
89 // \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8am\95Û\82·\82é
90 // *************************************************************************
91 function CreateResultString(
92         resultStr : string
93 ) : PChar; stdcall;
94 var
95         tmp : PChar;
96 begin
97
98         tmp := PChar( resultStr );
99         GetMem( Result, Length( tmp ) + 1 );
100         Move( tmp^, Result^, Length( tmp ) + 1 );
101
102 end;
103
104 // *************************************************************************
105 // \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8aJ\95ú\82·\82é
106 // *************************************************************************
107 procedure DisposeResultString(
108         resultStr : PChar
109 ); stdcall;
110 begin
111
112         FreeMem( resultStr );
113
114 end;
115
116 // *************************************************************************
117 // \83v\83\8d\83O\83\89\83\80\96{\91Ì\82Ì\83o\81[\83W\83\87\83\93\82ð\8eæ\93¾\82·\82é
118 // *************************************************************************
119 procedure VersionInfo(
120         var outAgent            : PChar;        // \83o\81[\83W\83\87\83\93\82ð\88ê\90Ø\8aÜ\82Ü\82È\82¢\8f\83\90\88\82È\96¼\8fÌ
121         var outMajor            : DWORD;        // \83\81\83W\83\83\81[\83o\81[\83W\83\87\83\93
122         var outMinor            : DWORD;        // \83}\83C\83i\81[\83o\81[\83W\83\87\83\93
123         var outRelease  : PChar;        // \83\8a\83\8a\81[\83X\92i\8aK\96¼
124         var outRevision : DWORD         // \83\8a\83r\83W\83\87\83\93\83i\83\93\83o\81[
125 ); stdcall;
126 begin
127
128         {$IFDEF DEBUG}
129         Writeln('ExternalBoardManager.VersionInfo');
130         {$ENDIF}
131         outAgent                := CreateResultString( PChar( APP_NAME ) );
132         outMajor                := 1;
133         outMinor                := 0;
134         outRelease      := CreateResultString( PChar( BETA_VERSION_NAME_E ) );
135         outRevision     := BETA_VERSION;
136
137 end;
138
139 // *************************************************************************
140 // \83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é
141 // *************************************************************************
142 procedure InternalPrint(
143         inMessage       : PChar // \83\81\83b\83Z\81[\83W
144 ); stdcall;
145 begin
146
147         GikoForm.AddMessageList( inMessage, nil, gmiWhat );
148
149 end;
150
151 // *************************************************************************
152 // \83f\83o\83b\83O\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é
153 // *************************************************************************
154 procedure InternalDebugPrint(
155         inMessage       : PChar // \83\81\83b\83Z\81[\83W
156 ); stdcall;
157 begin
158
159         {$IFDEF DEBUG}
160         Writeln( inMessage );
161         {$ENDIF}
162
163 end;
164
165 // *************************************************************************
166 // \83\\83P\83b\83g\82ð\8f\89\8aú\89»\82·\82é(\8eG\97p\8aÖ\90\94)
167 // *************************************************************************
168 procedure       InitializeSocket(
169         inSocket : TIdHTTP
170 );
171 begin
172
173         if inSocket <> nil then begin
174                 // \83C\83x\83\93\83g\82Ì\90Ý\92è
175                 if Assigned( OnWork ) then
176                         inSocket.OnWork                         := OnWork;
177                 if Assigned( OnWorkBegin ) then
178                         inSocket.OnWorkBegin    := OnWorkBegin;
179                 if Assigned( OnWorkEnd ) then
180                         inSocket.OnWorkEnd              := OnWorkEnd;
181
182                 // \92Ê\90M\82É\8aÖ\82·\82é\90Ý\92è
183                 inSocket.Request.CustomHeaders.Clear;
184                 inSocket.Response.Clear;
185                 inSocket.Request.Clear;
186
187                 inSocket.Request.UserAgent      := GikoSys.GetUserAgent;
188                 inSocket.RecvBufferSize                 := Gikosys.Setting.RecvBufferSize;
189                 inSocket.ProxyParams.BasicAuthentication := False;
190                 inSocket.ReadTimeout := GikoSys.Setting.ReadTimeOut;
191         inSocket.ConnectTimeout := GikoSys.Setting.ReadTimeOut;
192                 {$IFDEF DEBUG}
193                 Writeln('------------------------------------------------------------');
194                 {$ENDIF}
195                 //inSocket.AllowCookies := False;
196                 if GikoSys.Setting.ReadProxy then begin
197                         if GikoSys.Setting.ProxyProtocol then
198                                 inSocket.ProtocolVersion := pv1_1
199                         else
200                                 inSocket.ProtocolVersion := pv1_0;
201                         inSocket.ProxyParams.ProxyServer                := GikoSys.Setting.ReadProxyAddress;
202                         inSocket.ProxyParams.ProxyPort                  := GikoSys.Setting.ReadProxyPort;
203                         inSocket.ProxyParams.ProxyUsername      := GikoSys.Setting.ReadProxyUserID;
204                         inSocket.ProxyParams.ProxyPassword      := GikoSys.Setting.ReadProxyPassword;
205                         if GikoSys.Setting.ReadProxyUserID <> '' then
206                                 inSocket.ProxyParams.BasicAuthentication := True;
207                         {$IFDEF DEBUG}
208                         Writeln('\83v\83\8d\83L\83V\90Ý\92è\82 \82è');
209                         Writeln('\83z\83X\83g: ' + GikoSys.Setting.ReadProxyAddress);
210                         Writeln('\83|\81[\83g: ' + IntToStr( GikoSys.Setting.ReadProxyPort ));
211                         {$ENDIF}
212                 end else begin
213                         if GikoSys.Setting.Protocol then
214                                 inSocket.ProtocolVersion := pv1_1
215                         else
216                                 inSocket.ProtocolVersion := pv1_0;
217                         inSocket.ProxyParams.ProxyServer                := '';
218                         inSocket.ProxyParams.ProxyPort                  := 80;
219                         inSocket.ProxyParams.ProxyUsername      := '';
220                         inSocket.ProxyParams.ProxyPassword      := '';
221                         {$IFDEF DEBUG}
222                         Writeln('\83v\83\8d\83L\83V\90Ý\92è\82È\82µ');
223                         {$ENDIF}
224                 end;
225         end;
226
227 end;
228
229 // *************************************************************************
230 // \8ew\92è\82µ\82½ URL \82ð\83_\83E\83\93\83\8d\81[\83h\82µ\82Ä\95Ô\82·
231 // *************************************************************************
232 function InternalDownload(
233         inURL                                                   : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82·\82é URL
234         var ioModified          : Double;       // \8dÅ\8cã\82É\8eæ\93¾\82µ\82½\93ú\8e\9e
235         var outResultData       : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82³\82ê\82½\95\8e\9a\97ñ
236         inRangeStart                    : DWORD;        // \8aJ\8en\88Ê\92u
237         inRangeEnd                              : DWORD         // \8fI\97¹\88Ê\92u
238 ) : Longint; stdcall;                                   // \83\8c\83X\83|\83\93\83X\83R\81[\83h
239 var
240 //      httpSocket                              : TIdHTTP;
241         resStream                                       : TMemoryStream;
242         content                                         : string;
243 const
244         LIVEDOOR_URL = 'http://jbbs.shitaraba.net/';
245 begin
246
247
248         {$IFDEF DEBUG}
249         Writeln('ExternalBoardManager.InternalDownload');
250         {$ENDIF}
251 //      Result := -1;
252
253         socket := TIdHTTP.Create( nil );
254         try
255                 InitializeSocket( socket );
256                 socket.Request.ContentRangeStart        := inRangeStart;
257                 socket.Request.ContentRangeEnd          := inRangeEnd;
258                 if (ioModified <> 0) and (ioModified <> ZERO_DATE) then
259                         socket.Request.LastModified := ioModified - OffsetFromUTC;
260                 if inRangeStart = 0 then
261                         socket.Request.AcceptEncoding := 'gzip'
262                 else
263                         socket.Request.AcceptEncoding := '';
264                 socket.Request.Accept := 'text/html';
265
266                 resStream := TMemoryStream.Create;
267                 try
268                         try
269                                 resStream.Clear;
270                                 {$IFDEF DEBUG}
271                                 Writeln('URL: ' + inURL);
272                                 {$ENDIF}
273                 //AntiFreeze\82ðDL\8e\9e\82Ì\82Ý\97L\8cø\82É\82·\82é\82±\82Æ\82Å\81A\83R\83R\82Å\82Ì\83`\83F\83b\83N\95s\97v
274                                 socket.Get( inURL, resStream );
275                                 {$IFDEF DEBUG}
276                                 Writeln('\8eæ\93¾\82Å\97á\8aO\82È\82µ');
277                                 {$ENDIF}
278                                 content                 := GikoSys.GzipDecompress( resStream, socket.Response.ContentEncoding );
279                 // \92u\8a·\82·\82é
280                 if GikoSys.Setting.ReplaceDat then begin
281                     content := ReplaceDM.Replace(content);
282                 end;
283
284                                 ioModified      := socket.Response.LastModified;
285
286                                 Result := socket.ResponseCode;
287                                 if (Length( content ) = 0) and (Result = 206) then
288                                         Result := 304;
289                                 //\82µ\82½\82ç\82ÎJBBS\82Í\83w\83b\83_\82É\83G\83\89\81[\8fî\95ñ\82ª\8dÚ\82é\82ç\82µ\82¢\82Ì\82Å\81A\82±\82±\82Å\83`\83F\83b\83N
290                                 if ( AnsiPos(LIVEDOOR_URL, inURL) > 0 ) and (Result = 200) then begin
291                                         if( AnsiPos('STORAGE IN', socket.Response.RawHeaders.Text) > 0 ) then begin
292                                                 Result := 302;
293                                         end;
294                                 end;
295                                 outResultData := CreateResultString( content );
296                         except
297                                 on E: EIdSocketError do begin
298                                         ioModified              := ZERO_DATE;
299                                         outResultData   := nil;
300                                         Result                          := socket.ResponseCode;
301                                 end;
302                                 on E: EIdConnectException do begin
303                                         ioModified              := ZERO_DATE;
304                                         outResultData   := nil;
305                                         Result                          := socket.ResponseCode;
306                                         //Item.ErrText  := E.Message;
307                                 end;
308                                 //\92\86\92f\82³\82ê\82½\82Æ\82«\83R\83R\82É\93ü\82é
309                                 on E: EIdClosedSocket do begin
310                                         ioModified              := ZERO_DATE;
311                                         outResultData   := nil;
312                                         Result                          := 408; //\8aù\82É\88ê\95\94DL\90¬\8c÷\82µ\82Ä\82¢\82é\82Æ\83\8c\83X\83|\83\93\83X\83R\81[\83h\82ª200\82Ì\82Ü\82Ü\82É
313                                                                                                 //\82È\82Á\82Ä\82µ\82Ü\82¤\82Ì\82Å\81A\96¾\8e¦\93I\82É\83G\83\89\81[\83R\81[\83h\82ð\95Ô\82·
314                                 end;
315                                 on E: Exception do begin
316                                         {$IFDEF DEBUG}
317                                         Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
318                                         Writeln('E.Message: ' + E.Message);
319                                         {$ENDIF}
320                                         ioModified              := ZERO_DATE;
321                                         outResultData   := nil;
322                                         Result                          := socket.ResponseCode;
323                                         //Item.ErrText  := E.Message;
324                                 end;
325                         end;
326                 finally
327                         resStream.Free;
328                 end;
329
330         finally
331                 socket.Free;
332                 socket := nil;
333         end;
334
335 end;
336
337 // *************************************************************************
338 // \8ew\92è\82µ\82½ URL \82Ö\83f\81[\83^\82ð\91\97\90M\82·\82é
339 // *************************************************************************
340 function        InternalPost(
341         inURL                                                   : PChar;                        // \91\97\90M\82·\82é URL
342         inSource                                        : PChar;                        // \91\97\90M\82·\82é\93à\97e
343         inReferer                       : PChar;                                // Referer
344         var outResultData       : PChar                         // \95Ô\82Á\82Ä\82«\82½\95\8e\9a\97ñ
345 ) : Longint; stdcall;                                                   // \83\8c\83X\83|\83\93\83X\83R\81[\83h
346 var
347         httpSocket                              : TIdHTTP;
348         content                                         : string;
349         resStream                                       : TStringStream;
350         sourceStream                    : TStringStream;
351
352 begin
353
354         {$IFDEF DEBUG}
355         Writeln('ExternalBoardManager.InternalPost');
356         {$ENDIF}
357         Result := -1;
358
359         httpSocket := TIdHTTP.Create( nil );
360         try
361                 InitializeSocket( httpSocket );
362                 httpSocket.Request.CustomHeaders.Add('Pragma: no-cache');
363                 httpSocket.Request.AcceptLanguage       := 'ja';
364                 httpSocket.Request.Accept                                       := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*';
365                 httpSocket.Request.ContentType          := 'application/x-www-form-urlencoded';
366                 httpSocket.Request.Referer                      := string(inReferer);
367                 resStream                       := TStringStream.Create( content );
368                 sourceStream    := TStringStream.Create( string( inSource ) );
369                 try
370                         try
371                                 {$IFDEF DEBUG}
372                                 Writeln('URL: ' + inURL);
373                                 Writeln('Source: ' + inSource);
374                                 {$ENDIF}
375                                 httpSocket.Post( string( inURL ), sourceStream, resStream );
376                                 {$IFDEF DEBUG}
377                                 Writeln('\8eæ\93¾\82Å\97á\8aO\82È\82µ');
378                                 {$ENDIF}
379
380                                 Result := httpSocket.ResponseCode;
381
382                                 outResultData := CreateResultString( resStream.DataString );
383                         except
384                                 on E: EIdSocketError do begin
385                                         outResultData   := nil;
386                                 end;
387                                 on E: EIdConnectException do begin
388                                         outResultData   := nil;
389                                 end;
390                                 on E: Exception do begin
391                                         {$IFDEF DEBUG}
392                                         Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
393                                         Writeln('E.Message: ' + E.Message);
394                                         {$ENDIF}
395                                         outResultData := CreateResultString( resStream.DataString );
396                                         Result                          := httpSocket.ResponseCode;
397                                 end;
398                         end;
399                 finally
400                         resStream.Free;
401                         sourceStream.Free;
402                 end;
403         finally
404                 httpSocket.Free;
405         end;
406
407 end;
408
409 // *************************************************************************
410 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e®\82ð\83\8d\81[\83J\83\8b\82 \82Ú\81`\82ñ\82É\92Ê\82·
411 // *************************************************************************
412
413 function InternalAbon(
414         inDatText : PChar;                      // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<>[\89ü\8ds] \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
415         inDatPath       : PChar                         // dat \83t\83@\83C\83\8b\82Ì\83t\83\8b\83p\83X
416
417 ) : PChar; stdcall;                             // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
418 var
419         datList : TStringList;
420                 FileName : String;
421     ThreadInfo: TAbonThread;
422 begin
423
424     ThreadInfo := TAbonThread.Create;
425         datList := TStringList.Create;
426     try
427         datList.Text := string( inDatText );
428         FileName := string( inDatPath );
429         GikoSys.FAbon.IndividualAbon( datList, ChangeFileExt(FileName,'.NG'));
430         GikoSys.FAbon.Execute( datList, ThreadInfo );
431         GikoSys.FSelectResFilter.Execute( datList, ThreadInfo );
432     finally
433         ThreadInfo.Free;
434     end;
435
436     Result := CreateResultString( datList.Text );
437     datList.Free;
438 end;
439 // *************************************************************************
440 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e®\82ð\83\8d\81[\83J\83\8b\82 \82Ú\81`\82ñ\82É\92Ê\82·
441 // \82½\82¾\82µ\81A\82P\83\8c\83X\82¸\82Â
442 // *************************************************************************
443
444 function InternalAbonForOne(
445         inDatText : PChar;              // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<>[\89ü\8ds] \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
446         inDatPath       : PChar;                // dat \83t\83@\83C\83\8b\82Ì\83t\83\8b\83p\83X
447         inNo : Integer                          // \97v\8b\81\82³\82ê\82½\83\8c\83X\94Ô\8d\86
448 ) : PChar; stdcall;                     // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
449 var
450         datString : String;
451                 FileName : String;
452     ThreadInfo: TAbonThread;
453 begin
454
455     ThreadInfo := TAbonThread.Create;
456     try
457         datString := string( inDatText );
458         FileName := string( inDatPath );
459         GikoSys.FAbon.IndividualAbon( datString, ChangeFileExt(FileName,'.NG'), inNo);
460         GikoSys.FAbon.Execute( datString , inNo, ThreadInfo );
461         GikoSys.FSelectResFilter.Execute( datString , inNo, ThreadInfo );
462     finally
463         ThreadInfo.Free;
464     end;
465
466         Result := CreateResultString( datString );
467 end;
468
469 // *************************************************************************
470 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e® 1 \8ds\82ð HTML \82É\95Ï\8a·\82·\82é
471 // *************************************************************************
472 function InternalDat2HTML(
473         inDatRes                : PChar;                // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<> \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
474         inResNo                 : DWORD;                // \83\8c\83X\94Ô\8d\86
475         inIsNew                 : Boolean               // \90V\92\85\83\8c\83X\82È\82ç True
476 ) : PChar; stdcall;                             // \90®\8c`\82³\82ê\82½ HTML
477 var
478         board                           : TBoard;
479         threadItem      : TThreadItem;
480 begin
481
482         // \83_\83~\81[\82Ì\83N\83\89\83X
483         board                           := TBoard.Create( nil, 'about://dummy/' );
484         threadItem      := TThreadItem.Create( nil, board, 'about://dummy/test/read.cgi/dummy/' );
485         try
486                 try
487                         board.Add( threadItem );
488
489                         Result := ThreadItemDat2HTML( DWORD( threadItem ), inDatRes, inResNo, inIsNew );
490                 except
491                         Result := nil;
492                 end;
493         finally
494                 board.Free;
495         end;
496
497 end;
498
499 // *************************************************************************
500 // \83v\83\89\83O\83C\83\93\83\81\83j\83\85\81[\82É\8d\80\96Ú\82ð\92Ç\89Á
501 // *************************************************************************
502 function AddPlugInMenu(
503         inInstance      : DWORD;                // \83v\83\89\83O\83C\83\93\82Ì\83C\83\93\83X\83^\83\93\83X
504         inCaption       : PChar                         // \83\81\83j\83\85\81[\82É\95\\8e¦\82·\82é\95\8e\9a\97ñ
505 ) : HMENU; stdcall;                             // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b\81A\92Ç\89Á\82É\8e¸\94s\82µ\82½\8fê\8d\87\82Í NULL
506 var
507         newItem         : TMenuItem;
508 begin
509
510         try
511                 newItem                                 := TMenuItem.Create( nil );
512                 newItem.Caption := inCaption;
513                 newItem.Tag                     := inInstance;
514                 newItem.OnClick := GikoForm.OnPlugInMenuItem;
515                 GikoForm.PlugInMenu.Add( newItem );
516
517                 Result := newItem.Handle;
518         except
519                 Result := 0;
520         end;
521
522 end;
523
524 // *************************************************************************
525 // \83v\83\89\83O\83C\83\93\83\81\83j\83\85\81[\82©\82ç\8d\80\96Ú\82ð\8dí\8f\9c
526 // *************************************************************************
527 procedure RemovePlugInMenu(
528         inHandle        : HMENU                         // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
529 ); stdcall;
530 var
531         i                                       : Integer;
532 begin
533     // DLL\83f\83^\83b\83`\8e\9e\82Í\83t\83H\81[\83\80\83I\83u\83W\83F\83N\83g\82Í\91\8dÝ\82µ\82È\82¢\8fã\82É\83t\83H\81[\83\80\91¤\82Å\8cã\8en\96\96\82Í\8dÏ\82ñ\82Å\82¢\82é
534     if (g_AppTerminated = True) then
535         Exit;
536
537         for i := GikoForm.PlugInMenu.Count - 1 downto 0 do begin
538                 if GikoForm.PlugInMenu.Items[ i ].Handle = inHandle then begin
539 //            GikoForm.PlugInMenu.items[i].Free;
540             GikoForm.PlugInMenu.items[i].Visible := False;  // Giko.pas \82Ì TGikoForm.FormDestroy() \82Å\8aJ\95ú\82·\82é\82½\82ß\82±\82±\82Å\82Í\94ñ\95\\8e¦\82É\82·\82é\82Ì\82Ý
541                         //GikoForm.PlugInMenu.Delete( i );
542                         Break;
543                 end;
544         end;
545
546 end;
547
548 exports
549         CreateResultString,
550         DisposeResultString,
551         VersionInfo,
552         InternalPrint,
553         InternalDebugPrint,
554         InternalDownload,
555         InternalPost,
556         InternalAbon,
557         InternalAbonForOne,
558         InternalDat2HTML,
559         AddPlugInMenu,
560         RemovePlugInMenu;
561
562 end.