OSDN Git Service

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