OSDN Git Service

1.52.1.658
[gikonavigoeson/gikonavi.git] / ExternalBoardPlugInMain.pas
index 99c0b5f..beadb24 100644 (file)
@@ -3,15 +3,30 @@ unit ExternalBoardPlugInMain;
 interface
 
 uses
-       Windows, Classes, SysUtils,
+       Windows, Classes, SysUtils, Menus,
        IdHTTP, IdComponent, IdGlobal, IdException,
-       AbonUnit;
+       AbonUnit, IdAntiFreezeBase;
 
 type
 
        // \83_\83E\83\93\83\8d\81[\83h\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
        TDownloadState = (dsWait, dsWork, dsComplete, dsDiffComplete, dsNotModify, dsAbort, dsError);
 
+       // \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©
+       TAcceptType = (atNoAccept, atBBS, atBoard, atThread);
+
+       // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
+       TMenuHandler    = procedure(
+               inHandle : HMENU                                        // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
+       ); stdcall;
+
+       // *************************************************************************
+       // \83v\83\89\83O\83C\83\93\82ª(\90³\82µ\82­)\83\8d\81[\83h\82³\82ê\82½
+       // *************************************************************************
+       TOnLoad = procedure (
+               inInstance : DWORD                              // \83v\83\89\83O\83C\83\93\82Ì\83C\83\93\83X\83^\83\93\83X
+       ); stdcall;
+
        // *************************************************************************
        // \83v\83\89\83O\83C\83\93\82Ì\83o\81[\83W\83\87\83\93
        // *************************************************************************
@@ -28,7 +43,22 @@ type
        // *************************************************************************
        TOnAcceptURL = function(
                inURL : PChar                                           // \94»\92f\82ð\8bÂ\82¢\82Å\82¢\82é URL
-       ): Boolean; stdcall;                    // \8eó\82¯\95t\82¯\82é\82È\82ç True
+       ): TAcceptType; stdcall;        // URL \82Ì\8eí\97Þ
+
+       // *************************************************************************
+       // \8ew\92è\82µ\82½URL\82ð\8c»\8dÝ\82ÌURL\82É\95Ï\8a·\82·\82é
+       // *************************************************************************
+       TOnExtractBoardURL = procedure(
+               inURL : PChar;                                          // \95Ï\8a·\82·\82éURL;
+        var outURL: PChar                                              // \95Ï\8a·\82³\82ê\82½URL
+       ); stdcall;     // \95Ï\8a·\82³\82ê\82½URL
+
+       // *************************************************************************
+       // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
+       // *************************************************************************
+       TOnPlugInMenu = procedure(
+               inInstance : DWORD              // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
+       ); stdcall;
 
        // *************************************************************************
        // \83X\83\8c\88ê\97\97\82Ì URL \82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\93±\82«\8fo\82·
@@ -38,6 +68,7 @@ type
                inFileName      : PChar         // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
        ) : PChar; stdcall;                     // \83X\83\8c\83b\83h\82Ì URL
 
+
 function CreateResultString(
        resultStr : string
 ) : PChar; stdcall;
@@ -46,9 +77,12 @@ procedure DisposeResultString(
        resultStr : PChar
 ); stdcall;
 
+var
+       socket : TIdHTTP;
+
 implementation
 
-uses ExternalBoardManager, ExternalThreadItem, GikoSystem, BoardGroup;
+uses ExternalBoardManager, ExternalThreadItem, GikoSystem, BoardGroup, Giko;
 
 // *************************************************************************
 // \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8am\95Û\82·\82é
@@ -102,59 +136,72 @@ begin
 end;
 
 // *************************************************************************
-// \8ew\92è\82µ\82½ URL \82ð\83_\83E\83\93\83\8d\81[\83h\82µ\82Ä\95Ô\82·
+// \83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é
 // *************************************************************************
-function InternalDownload(
-       inURL                                                   : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82·\82é URL
-       var ioModified          : Double;       // \8dÅ\8cã\82É\8eæ\93¾\82µ\82½\93ú\8e\9e
-       var outResultData       : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82³\82ê\82½\95\8e\9a\97ñ
-       inRangeStart                    : DWORD;        // \8aJ\8en\88Ê\92u
-       inRangeEnd                              : DWORD         // \8fI\97¹\88Ê\92u
-) : Longint; stdcall;                                  // \83\8c\83X\83|\83\93\83X\83R\81[\83h
-var
-       httpSocket                              : TIdHTTP;
-       resStream                                       : TMemoryStream;
-       content                                         : string;
+procedure InternalPrint(
+       inMessage       : PChar // \83\81\83b\83Z\81[\83W
+); stdcall;
+begin
+
+       GikoForm.AddMessageList( inMessage, nil, gmiWhat );
+
+end;
+
+// *************************************************************************
+// \83f\83o\83b\83O\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é
+// *************************************************************************
+procedure InternalDebugPrint(
+       inMessage       : PChar // \83\81\83b\83Z\81[\83W
+); stdcall;
 begin
 
        {$IFDEF DEBUG}
-       Writeln('ExternalBoardManager.InternalDownload');
+       Writeln( inMessage );
        {$ENDIF}
-       Result := -1;
 
-       httpSocket := TIdHTTP.Create( nil );
-       try
+end;
+
+// *************************************************************************
+// \83\\83P\83b\83g\82ð\8f\89\8aú\89»\82·\82é(\8eG\97p\8aÖ\90\94)
+// *************************************************************************
+procedure      InitializeSocket(
+       inSocket : TIdHTTP
+);
+begin
+
+       if inSocket <> nil then begin
                // \83C\83x\83\93\83g\82Ì\90Ý\92è
                if Assigned( OnWork ) then
-                       httpSocket.OnWork                               := OnWork;
+                       inSocket.OnWork                         := OnWork;
                if Assigned( OnWorkBegin ) then
-                       httpSocket.OnWorkBegin  := OnWorkBegin;
+                       inSocket.OnWorkBegin    := OnWorkBegin;
                if Assigned( OnWorkEnd ) then
-                       httpSocket.OnWorkEnd            := OnWorkEnd;
+                       inSocket.OnWorkEnd              := OnWorkEnd;
 
                // \92Ê\90M\82É\8aÖ\82·\82é\90Ý\92è
-               httpSocket.Request.CustomHeaders.Clear;
-               httpSocket.Response.Clear;
-               httpSocket.Request.Clear;
-
-               httpSocket.Request.UserAgent    := GikoSys.GetUserAgent;
-               httpSocket.RecvBufferSize                       := Gikosys.Setting.RecvBufferSize;
-               httpSocket.ProxyParams.BasicAuthentication := False;
+               inSocket.Request.CustomHeaders.Clear;
+               inSocket.Response.Clear;
+               inSocket.Request.Clear;
+
+               inSocket.Request.UserAgent      := GikoSys.GetUserAgent;
+               inSocket.RecvBufferSize                 := Gikosys.Setting.RecvBufferSize;
+               inSocket.ProxyParams.BasicAuthentication := False;
+               inSocket.ReadTimeout := GikoSys.Setting.ReadTimeOut;
                {$IFDEF DEBUG}
                Writeln('------------------------------------------------------------');
                {$ENDIF}
-               //httpSocket.AllowCookies := False;
+               //inSocket.AllowCookies := False;
                if GikoSys.Setting.ReadProxy then begin
                        if GikoSys.Setting.ProxyProtocol then
-                               httpSocket.ProtocolVersion := pv1_1
+                               inSocket.ProtocolVersion := pv1_1
                        else
-                               httpSocket.ProtocolVersion := pv1_0;
-                       httpSocket.ProxyParams.ProxyServer              := GikoSys.Setting.ReadProxyAddress;
-                       httpSocket.ProxyParams.ProxyPort                        := GikoSys.Setting.ReadProxyPort;
-                       httpSocket.ProxyParams.ProxyUsername    := GikoSys.Setting.ReadProxyUserID;
-                       httpSocket.ProxyParams.ProxyPassword    := GikoSys.Setting.ReadProxyPassword;
+                               inSocket.ProtocolVersion := pv1_0;
+                       inSocket.ProxyParams.ProxyServer                := GikoSys.Setting.ReadProxyAddress;
+                       inSocket.ProxyParams.ProxyPort                  := GikoSys.Setting.ReadProxyPort;
+                       inSocket.ProxyParams.ProxyUsername      := GikoSys.Setting.ReadProxyUserID;
+                       inSocket.ProxyParams.ProxyPassword      := GikoSys.Setting.ReadProxyPassword;
                        if GikoSys.Setting.ReadProxyUserID <> '' then
-                               httpSocket.ProxyParams.BasicAuthentication := True;
+                               inSocket.ProxyParams.BasicAuthentication := True;
                        {$IFDEF DEBUG}
                        Writeln('\83v\83\8d\83L\83V\90Ý\92è\82 \82è');
                        Writeln('\83z\83X\83g: ' + GikoSys.Setting.ReadProxyAddress);
@@ -162,59 +209,104 @@ begin
                        {$ENDIF}
                end else begin
                        if GikoSys.Setting.Protocol then
-                               httpSocket.ProtocolVersion := pv1_1
+                               inSocket.ProtocolVersion := pv1_1
                        else
-                               httpSocket.ProtocolVersion := pv1_0;
-                       httpSocket.ProxyParams.ProxyServer              := '';
-                       httpSocket.ProxyParams.ProxyPort                        := 80;
-                       httpSocket.ProxyParams.ProxyUsername    := '';
-                       httpSocket.ProxyParams.ProxyPassword    := '';
+                               inSocket.ProtocolVersion := pv1_0;
+                       inSocket.ProxyParams.ProxyServer                := '';
+                       inSocket.ProxyParams.ProxyPort                  := 80;
+                       inSocket.ProxyParams.ProxyUsername      := '';
+                       inSocket.ProxyParams.ProxyPassword      := '';
                        {$IFDEF DEBUG}
                        Writeln('\83v\83\8d\83L\83V\90Ý\92è\82È\82µ');
                        {$ENDIF}
                end;
+       end;
 
-               httpSocket.Request.ContentRangeStart    := inRangeStart;
-               httpSocket.Request.ContentRangeEnd              := inRangeEnd;
+end;
+
+// *************************************************************************
+// \8ew\92è\82µ\82½ URL \82ð\83_\83E\83\93\83\8d\81[\83h\82µ\82Ä\95Ô\82·
+// *************************************************************************
+function InternalDownload(
+       inURL                                                   : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82·\82é URL
+       var ioModified          : Double;       // \8dÅ\8cã\82É\8eæ\93¾\82µ\82½\93ú\8e\9e
+       var outResultData       : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82³\82ê\82½\95\8e\9a\97ñ
+       inRangeStart                    : DWORD;        // \8aJ\8en\88Ê\92u
+       inRangeEnd                              : DWORD         // \8fI\97¹\88Ê\92u
+) : Longint; stdcall;                                  // \83\8c\83X\83|\83\93\83X\83R\81[\83h
+var
+//     httpSocket                              : TIdHTTP;
+       resStream                                       : TMemoryStream;
+       content                                         : string;
+const
+       LIVEDOOR_URL = 'http://jbbs.livedoor.jp/';
+begin
+
+
+       {$IFDEF DEBUG}
+       Writeln('ExternalBoardManager.InternalDownload');
+       {$ENDIF}
+//     Result := -1;
+
+       socket := TIdHTTP.Create( nil );
+       try
+               InitializeSocket( socket );
+               socket.Request.ContentRangeStart        := inRangeStart;
+               socket.Request.ContentRangeEnd          := inRangeEnd;
                if (ioModified <> 0) and (ioModified <> ZERO_DATE) then
-                       httpSocket.Request.LastModified := ioModified - OffsetFromUTC;
+                       socket.Request.LastModified := ioModified - OffsetFromUTC;
                if inRangeStart = 0 then
-                       httpSocket.Request.AcceptEncoding := 'gzip'
+                       socket.Request.AcceptEncoding := 'gzip'
                else
-                       httpSocket.Request.AcceptEncoding := '';
-               httpSocket.Request.Accept := 'text/html';
+                       socket.Request.AcceptEncoding := '';
+               socket.Request.Accept := 'text/html';
 
                resStream := TMemoryStream.Create;
                try
                        try
                                resStream.Clear;
-
                                {$IFDEF DEBUG}
                                Writeln('URL: ' + inURL);
                                {$ENDIF}
-                               httpSocket.Get( inURL, resStream );
+                //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
+                               socket.Get( inURL, resStream );
                                {$IFDEF DEBUG}
                                Writeln('\8eæ\93¾\82Å\97á\8aO\82È\82µ');
                                {$ENDIF}
 
-                               content                 := GikoSys.GzipDecompress( resStream, httpSocket.Response.ContentEncoding );
-                               ioModified      := httpSocket.Response.LastModified;
+                               content                 := GikoSys.GzipDecompress( resStream, socket.Response.ContentEncoding );
 
-                               Result := httpSocket.ResponseCode;
+                               ioModified      := socket.Response.LastModified;
+
+                               Result := socket.ResponseCode;
                                if (Length( content ) = 0) and (Result = 206) then
                                        Result := 304;
-
+                               //\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
+                               if ( AnsiPos(LIVEDOOR_URL, inURL) > 0 ) and (Result = 200) then begin
+                                       if( AnsiPos('STORAGE IN', socket.Response.RawHeaders.Text) > 0 ) then begin
+                                               Result := 302;
+                                       end;
+                               end;
                                outResultData := CreateResultString( content );
                        except
                                on E: EIdSocketError do begin
                                        ioModified              := ZERO_DATE;
                                        outResultData   := nil;
+                                       Result                          := socket.ResponseCode;
                                end;
                                on E: EIdConnectException do begin
                                        ioModified              := ZERO_DATE;
                                        outResultData   := nil;
+                                       Result                          := socket.ResponseCode;
                                        //Item.ErrText  := E.Message;
                                end;
+                               //\92\86\92f\82³\82ê\82½\82Æ\82«\83R\83R\82É\93ü\82é
+                               on E: EIdClosedSocket do begin
+                                       ioModified              := ZERO_DATE;
+                                       outResultData   := nil;
+                                       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É
+                                                                                               //\82È\82Á\82Ä\82µ\82Ü\82¤\82Ì\82Å\81A\96¾\8e¦\93I\82É\83G\83\89\81[\83R\81[\83h\82ð\95Ô\82·
+                               end;
                                on E: Exception do begin
                                        {$IFDEF DEBUG}
                                        Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
@@ -222,7 +314,7 @@ begin
                                        {$ENDIF}
                                        ioModified              := ZERO_DATE;
                                        outResultData   := nil;
-                                       Result                          := httpSocket.ResponseCode;
+                                       Result                          := socket.ResponseCode;
                                        //Item.ErrText  := E.Message;
                                end;
                        end;
@@ -231,6 +323,79 @@ begin
                end;
 
        finally
+               socket.Free;
+               socket := nil;
+       end;
+
+end;
+
+// *************************************************************************
+// \8ew\92è\82µ\82½ URL \82Ö\83f\81[\83^\82ð\91\97\90M\82·\82é
+// *************************************************************************
+function       InternalPost(
+       inURL                                                   : PChar;                        // \91\97\90M\82·\82é URL
+       inSource                                        : PChar;                        // \91\97\90M\82·\82é\93à\97e
+       inReferer                       : PChar;                                // Referer
+       var outResultData       : PChar                         // \95Ô\82Á\82Ä\82«\82½\95\8e\9a\97ñ
+) : Longint; stdcall;                                                  // \83\8c\83X\83|\83\93\83X\83R\81[\83h
+var
+       httpSocket                              : TIdHTTP;
+       content                                         : string;
+       resStream                                       : TStringStream;
+       sourceStream                    : TStringStream;
+
+begin
+
+       {$IFDEF DEBUG}
+       Writeln('ExternalBoardManager.InternalPost');
+       {$ENDIF}
+       Result := -1;
+
+       httpSocket := TIdHTTP.Create( nil );
+       try
+               InitializeSocket( httpSocket );
+               httpSocket.Request.CustomHeaders.Add('Pragma: no-cache');
+               httpSocket.Request.AcceptLanguage       := 'ja';
+               httpSocket.Request.Accept                                       := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*';
+               httpSocket.Request.ContentType          := 'application/x-www-form-urlencoded';
+               httpSocket.Request.Referer                      := string(inReferer);
+               resStream                       := TStringStream.Create( content );
+               sourceStream    := TStringStream.Create( string( inSource ) );
+               try
+                       try
+                               {$IFDEF DEBUG}
+                               Writeln('URL: ' + inURL);
+                               Writeln('Source: ' + inSource);
+                               {$ENDIF}
+                               httpSocket.Post( string( inURL ), sourceStream, resStream );
+                               {$IFDEF DEBUG}
+                               Writeln('\8eæ\93¾\82Å\97á\8aO\82È\82µ');
+                               {$ENDIF}
+
+                               Result := httpSocket.ResponseCode;
+
+                               outResultData := CreateResultString( resStream.DataString );
+                       except
+                               on E: EIdSocketError do begin
+                                       outResultData   := nil;
+                               end;
+                               on E: EIdConnectException do begin
+                                       outResultData   := nil;
+                               end;
+                               on E: Exception do begin
+                                       {$IFDEF DEBUG}
+                                       Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
+                                       Writeln('E.Message: ' + E.Message);
+                                       {$ENDIF}
+                                       outResultData := CreateResultString( resStream.DataString );
+                                       Result                          := httpSocket.ResponseCode;
+                               end;
+                       end;
+               finally
+                       resStream.Free;
+                       sourceStream.Free;
+               end;
+       finally
                httpSocket.Free;
        end;
 
@@ -239,23 +404,54 @@ end;
 // *************************************************************************
 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e®\82ð\83\8d\81[\83J\83\8b\82 \82Ú\81`\82ñ\82É\92Ê\82·
 // *************************************************************************
+
 function InternalAbon(
-       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
+       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
+       inDatPath       : PChar                         // dat \83t\83@\83C\83\8b\82Ì\83t\83\8b\83p\83X
+
 ) : PChar; stdcall;                            // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
 var
        datList : TStringList;
+               FileName : String;
 begin
 
-       {$IFDEF DEBUG}
-       Writeln('ExternalBoardManager.InternalAbon');
-       {$ENDIF}
        datList := TStringList.Create;
-       datList.Text := string( inDatText );
-       //GikoSys.FAbon.IndividualAbon( datList, ChangeFileExt(FileName,'.NG'));
-       GikoSys.FAbon.Execute( datList );
-       GikoSys.FSelectResFilter.Execute( datList );
+    try
+        datList.Text := string( inDatText );
+        FileName := string( inDatPath );
+        GikoSys.FAbon.IndividualAbon( datList, ChangeFileExt(FileName,'.NG'));
+        GikoSys.FAbon.Execute( datList );
+        GikoSys.FSelectResFilter.Execute( datList );
+
+        Result := CreateResultString( datList.Text );
+    finally
+       datList.Free;
+    end;
+
+
+end;
+// *************************************************************************
+// \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e®\82ð\83\8d\81[\83J\83\8b\82 \82Ú\81`\82ñ\82É\92Ê\82·
+// \82½\82¾\82µ\81A\82P\83\8c\83X\82¸\82Â
+// *************************************************************************
+
+function InternalAbonForOne(
+       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
+       inDatPath       : PChar;                // dat \83t\83@\83C\83\8b\82Ì\83t\83\8b\83p\83X
+       inNo : Integer                          // \97v\8b\81\82³\82ê\82½\83\8c\83X\94Ô\8d\86
+) : PChar; stdcall;                    // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
+var
+       datString : String;
+               FileName : String;
+begin
+
+       datString := string( inDatText );
+       FileName := string( inDatPath );
+       GikoSys.FAbon.IndividualAbon( datString, ChangeFileExt(FileName,'.NG'), inNo);
+       GikoSys.FAbon.Execute( datString , inNo);
+       GikoSys.FSelectResFilter.Execute( datString , inNo );
 
-       Result := CreateResultString( datList.Text );
+       Result := CreateResultString( datString );
 
 end;
 
@@ -263,28 +459,73 @@ end;
 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e® 1 \8ds\82ð HTML \82É\95Ï\8a·\82·\82é
 // *************************************************************************
 function InternalDat2HTML(
-       inDatRes                : PChar;                        // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<> \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
-       inResNo                 : DWORD;                        // \83\8c\83X\94Ô\8d\86
-       inIsNew                 : Boolean                       // \90V\92\85\83\8c\83X\82È\82ç True
+       inDatRes                : PChar;                // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<> \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
+       inResNo                 : DWORD;                // \83\8c\83X\94Ô\8d\86
+       inIsNew                 : Boolean               // \90V\92\85\83\8c\83X\82È\82ç True
 ) : PChar; stdcall;                            // \90®\8c`\82³\82ê\82½ HTML
 var
        board                           : TBoard;
        threadItem      : TThreadItem;
 begin
 
-       {$IFDEF DEBUG}
-       Writeln('ExternalBoardManager.InternalDat2HTML');
-       {$ENDIF}
        // \83_\83~\81[\82Ì\83N\83\89\83X
-       board                           := TBoard.Create;
-       threadItem      := TThreadItem.Create;
+       board                           := TBoard.Create( nil, 'about://dummy/' );
+       threadItem      := TThreadItem.Create( nil, board, 'about://dummy/test/read.cgi/dummy/' );
+       try
+               try
+                       board.Add( threadItem );
+
+                       Result := ThreadItemDat2HTML( DWORD( threadItem ), inDatRes, inResNo, inIsNew );
+               except
+                       Result := nil;
+               end;
+       finally
+               board.Free;
+       end;
+
+end;
+
+// *************************************************************************
+// \83v\83\89\83O\83C\83\93\83\81\83j\83\85\81[\82É\8d\80\96Ú\82ð\92Ç\89Á
+// *************************************************************************
+function AddPlugInMenu(
+       inInstance      : DWORD;                // \83v\83\89\83O\83C\83\93\82Ì\83C\83\93\83X\83^\83\93\83X
+       inCaption       : PChar                         // \83\81\83j\83\85\81[\82É\95\\8e¦\82·\82é\95\8e\9a\97ñ
+) : 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
+var
+       newItem         : TMenuItem;
+begin
 
        try
-               threadItem.ParentBoard := Board;
+               newItem                                 := TMenuItem.Create( nil );
+               newItem.Caption := inCaption;
+               newItem.Tag                     := inInstance;
+               newItem.OnClick := GikoForm.OnPlugInMenuItem;
+               GikoForm.PlugInMenu.Add( newItem );
 
-               Result := ThreadItemDat2HTML( DWORD( threadItem ), inDatRes, inResNo, inIsNew );
+               Result := newItem.Handle;
        except
-               Result := nil;
+               Result := 0;
+       end;
+
+end;
+
+// *************************************************************************
+// \83v\83\89\83O\83C\83\93\83\81\83j\83\85\81[\82©\82ç\8d\80\96Ú\82ð\8dí\8f\9c
+// *************************************************************************
+procedure RemovePlugInMenu(
+       inHandle        : HMENU                         // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
+); stdcall;
+var
+       i                                       : Integer;
+begin
+
+       for i := GikoForm.PlugInMenu.Count - 1 downto 0 do begin
+               if GikoForm.PlugInMenu.Items[ i ].Handle = inHandle then begin
+            GikoForm.PlugInMenu.items[i].Free;
+                       //GikoForm.PlugInMenu.Delete( i );
+                       Break;
+               end;
        end;
 
 end;
@@ -293,8 +534,14 @@ exports
        CreateResultString,
        DisposeResultString,
        VersionInfo,
+       InternalPrint,
+       InternalDebugPrint,
        InternalDownload,
+       InternalPost,
        InternalAbon,
-       InternalDat2HTML;
+       InternalAbonForOne,
+       InternalDat2HTML,
+       AddPlugInMenu,
+       RemovePlugInMenu;
 
 end.