OSDN Git Service

・書き込み時の新しい「書きこみ&クッキー」メッセージに対応
[gikonavigoeson/gikonavi.git] / ExternalBoardManager.pas
index e01bee5..a298e4b 100644 (file)
@@ -5,623 +5,675 @@ interface
 uses
        Windows, Classes, SysUtils,
        IdHTTP, IdComponent, IdGlobal, IdException,
-       GikoSystem, BoardGroup, AbonUnit;
+       ExternalBoardPlugInMain, ExternalFilePath, ExternalThreadItem, ExternalBoardItem;
 
 type
-       // TThreadItem \82Ì\83v\83\8d\83p\83e\83B\90Ý\92è\81^\8eæ\93¾ ID
-       TThreadItemProperty = (
-               tipContext,                                                     // : DWORD                      // \8e©\97R\82É\90Ý\92è\82µ\82Ä\82¢\82¢\92l
-               tipNo,                                                                  // : Integer            // \94Ô\8d\86
-               tipFileName,                                            // : string                     // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
-               tipTitle,                                                               // : string                     // \83X\83\8c\83b\83h\83^\83C\83g\83\8b
-               tipRoundDate,                                           // : TDateTime  // \83X\83\8c\83b\83h\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
-               tipLastModified,                                // : TDateTime  // \83X\83\8c\83b\83h\82ª\8dX\90V\82³\82ê\82Ä\82¢\82é\93ú\8e\9e\81i\83T\81[\83o\91¤\93ú\8e\9e\81j
-               tipCount,                                                               // : Integer            // \83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83\8d\81[\83J\83\8b\81j
-               tipAllResCount,                                 // : Integer            // \83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83T\81[\83o\81j
-               tipNewResCount,                                 // : Integer            // \83X\83\8c\83b\83h\90V\92\85\90\94
-               tipSize,                                                                // : Integer            // \83X\83\8c\83b\83h\83T\83C\83Y
-               tipRound,                                                               // : Boolean            // \8f\84\89ñ\83t\83\89\83O
-               tipRoundName,                                           // : string                     // \8f\84\89ñ\96¼
-               tipIsLogFile,                                           // : Boolean            // \83\8d\83O\91\8dÝ\83t\83\89\83O
-               tipKokomade,                                            // : Integer            // \83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
-               tipNewReceive,                                  // : Integer            // \83R\83R\82©\82ç\90V\8bK\8eó\90M
-               tipNewArrival,                                  // : Boolean            // \90V\92\85
-               tipUnRead,                                                      // : Boolean            // \96¢\93Ç\83t\83\89\83O
-               tipScrollTop,                                           // : Integer            // \83X\83N\83\8d\81[\83\8b\88Ê\92u
-               tipDownloadHost,                                // : string                     // \8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
-               tipAgeSage,                                                     // : TThreadAgeSage     // \83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
-               tipURL                                                                  // : string                     // \83X\83\8c\83b\83h\82ð\83u\83\89\83E\83U\82Å\95\\8e¦\82·\82é\8dÛ\82Ì URL
-       );
+       // =========================================================================
+       // \83v\83\89\83O\83C\83\93\82ð\8aÇ\97\9d\82·\82é TBoardPlugin \83N\83\89\83X
+       // =========================================================================
+       TBoardPlugIn = class( TObject )
+       private
+               FFilePath                                               : string;               // \83v\83\89\83O\83C\83\93\82ð\8e¦\82·\83p\83X
+               FModule                                                 : HMODULE;      // \83v\83\89\83O\83C\83\93\82Ì\83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b
+
+               FLoad                                                           : TOnLoad;
+               FVersionInfo                            : TOnVersionInfo;
+               FAcceptURL                                      : TOnAcceptURL;
+        FExtractBoardURL                               : TOnExtractBoardURL;
+               FPlugInMenu                                     : TOnPlugInMenu;
+
+               FCreateThreadItem               : TThreadItemCreate;
+               FDisposeThreadItem      : TThreadItemDispose;
+               FDownloadThread                 : TThreadItemOnDownload;
+               FWriteThread                            : TThreadItemOnWrite;
+               FGetRes                                                 : TThreadItemOnGetRes;
+               FGetDat                                                 : TThreadItemOnGetDat;
+               FGetHeader                                      : TThreadItemOnGetHeader;
+               FGetFooter                                      : TThreadItemOnGetFooter;
+               FGetBoardURL                            : TThreadItemOnGetBoardURL;
+
+               FCreateBoardItem                : TBoardItemCreate;
+               FDisposeBoardItem               : TBoardItemDispose;
+               FDownloadBoard                  : TBoardItemOnDownload;
+               FCreateThread                           : TBoardItemOnCreateThread;
+               FEnumThread                                     : TBoardItemOnEnumThread;
+               FFileName2ThreadURL     : TBoardItemOnFileName2ThreadURL;
+
+       public
+               // \83R\83\93\83X\83g\83\89\83N\83^
+               constructor     Create;
+               // \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\8dì\90¬
+               constructor     CreateFromPath( inPath : string );
+               // \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\8dì\90¬
+               constructor     CreateFromName( inName : string );
+               // \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\8dì\90¬
+               constructor     CreateFromModule( inModule : HMODULE );
+               // \83f\83X\83g\83\89\83N\83^
+               destructor      Destroy; override;
+
+               // \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
+               procedure       LoadFromPath( inPath : string );
+               // \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
+               procedure       LoadFromName( inName : string );
+               // \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
+               procedure       LoadFromModule( inModule : HMODULE );
+
+               //===== PlugInMain \8aÖ\98A
+               // \83v\83\89\83O\83C\83\93\82ª(\90³\82µ\82­)\83\8d\81[\83h\82³\82ê\82½
+               procedure       Loaded;
+               // \83o\81[\83W\83\87\83\93\8fî\95ñ
+               procedure       VersionInfo(    var outAgent : string;
+                       var outMajor : DWORD; var outMinor : DWORD;
+                       var outRelease : string; var outRevision : DWORD );
+               // \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©
+               function        AcceptURL( inURL : string ) : TAcceptType;
+        // URL\82©\82ç\8eg\82¦\82éBoard\82ÌURL\82ð\93±\82«\8fo\82·
+        function       ExtractBoardURL( inURL : string ): string;
+               // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
+               procedure       PlugInMenu( inHandle : HMENU );
+
+               //===== TThreadItem \8aÖ\98A
+               // TThreadItem \82ª\90\90¬\82³\82ê\82½
+               procedure       CreateThreadItem( threadItem : DWORD );
+               // TThreadItem \82ª\94j\8aü\82³\82ê\82½
+               procedure       DisposeThreadItem( threadItem : DWORD );
+               // \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
+               function        DownloadThread( threadItem : DWORD ) : TDownloadState;
+               // \8f\91\82«\8d\9e\82Ý\82ð\8ew\8e¦
+               function        WriteThread( threadItem : DWORD; inName : string; inMail : string; inMessage : string ) : TDownloadState;
+               // \83\8c\83X\94Ô\8d\86 n \82É\91Î\82·\82é html \82ð\97v\8b\81
+               function        GetRes( threadItem : DWORD; inNo : DWORD ) : string;
+               // \83\8c\83X\94Ô\8d\86 n \82É\91Î\82·\82é Dat \82ð\97v\8b\81
+               function        GetDat( threadItem : DWORD; inNo : DWORD ) : string;
+               // \83X\83\8c\83b\83h\82Ì\83w\83b\83_ html \82ð\97v\8b\81
+               function        GetHeader( threadItem : DWORD; inOptionalHeader : string ) : string;
+               // \83X\83\8c\83b\83h\82Ì\83t\83b\83^ html \82ð\97v\8b\81
+               function        GetFooter( threadItem : DWORD; inOptionalFooter : string ) : string;
+               // \82±\82Ì ThreadItem \82ª\91®\82·\82é\94Â\82Ì URL \82ð\97v\8b\81
+               function        GetBoardURL( threadItem : DWORD ) : string;
+
+               //===== TBoardItem \8aÖ\98A
+               // TBoard \82ª\90\90¬\82³\82ê\82½
+               procedure       CreateBoardItem( boardItem : DWORD );
+               // TBoardItem \82ª\94j\8aü\82³\82ê\82½
+               procedure       DisposeBoardItem( boardItem : DWORD );
+               // \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
+               function        DownloadBoard( boardItem : DWORD ) : TDownloadState;
+               // \83X\83\8c\97§\82Ä\82ð\8ew\8e¦
+               function        CreateThread( boardItem : DWORD; inSubject : string; inName : string; inMail : string; inMessage : string ) : TDownloadState;
+               // \82±\82Ì\94Â\82É\95Û\97L\82µ\82Ä\82¢\82é\83X\83\8c\82ð\97ñ\8b\93
+               procedure EnumThread( boardItem : DWORD; inCallBack : TBoardItemEnumThreadCallBack );
+               // \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\97v\8b\81
+               function        FileName2ThreadURL( boardItem : DWORD; inFileName : string ) : string;
+
+       private
+               procedure       LoadPlugInAPI;
+
+       public
+               property        FilePath        : string        read FFilePath;
+               property        Module          : HMODULE       read FModule;
+       end;
 
 var
-       OnWork                  : TWorkEvent;
-       OnWorkBegin     : TWorkBeginEvent;
-       OnWorkEnd               : TWorkEndEvent;
+       OnWork                          : TWorkEvent;
+       OnWorkBegin             : TWorkBeginEvent;
+       OnWorkEnd                       : TWorkEndEvent;
+
+       BoardPlugIns    : array of TBoardPlugIn;
 
-function ThreadItemDat2HTML(
-       inInstance      : DWORD;                // \83N\83\89\83X\82Ì\83C\83\93\83X\83^\83\93\83X
-       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
+procedure InitializeBoardPlugIns;
 
 implementation
 
-// =========================================================================
-// PlugInMain
-// =========================================================================
+uses GikoSystem, BoardGroup;
 
 // *************************************************************************
-// \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8am\95Û\82·\82é
+// BoardPlugin \83t\83H\83\8b\83_\82É\82 \82é\83v\83\89\83O\83C\83\93\82ð\91S\82Ä\83\8d\81[\83h
 // *************************************************************************
-function CreateResultString(
-       resultStr : string
-) : PChar; stdcall;
+procedure InitializeBoardPlugIns;
 var
-       tmp : PChar;
+       i, bound                : Integer;
+       pluginNames     : TStringList;
 begin
 
-       tmp := PChar( resultStr );
-       GetMem( Result, Length( resultStr ) + 1 );
-       Move( tmp, Result, Length( resultStr ) + 1 );
+       pluginNames := TStringList.Create;
+       try
+               //GikoSys.GetFileList( GikoSys.Setting.GetBoardPlugInDir, '*', pluginNames, False, False );
+        pluginNames.BeginUpdate;
+               GikoSys.GetFileList( GikoSys.Setting.GetBoardPlugInDir, '*.dll', pluginNames, False );
+        pluginNames.EndUpdate;
+               SetLength( BoardPlugIns, pluginNames.Count );
+        //
+        SetLength( BoardGroups, pluginNames.Count + 1 );
+               BoardGroups[0] := TBoardGroup.Create;
+               BoardGroups[0].Sorted := true;
+               BoardGroups[0].BoardPlugIn := nil;
+               //
+               bound := pluginNames.Count - 1;
+               for i := 0 to bound do begin
+                       try
+                               BoardPlugIns[ i ] := TBoardPlugIn.CreateFromName( pluginNames.Strings[ i ] );
+                               BoardPlugIns[ i ].Loaded;
+                               BoardGroups[ i + 1 ] := TBoardGroup.Create;
+                BoardGroups[ i + 1 ].Sorted := True;
+                               BoardGroups[ i + 1 ].BoardPlugIn := BoardPlugIns[ i ];
+                       except end;
+               end;
+       finally
+               pluginNames.Free;
+       end;
 
 end;
 
+
+
+// =========================================================================
+// \83v\83\89\83O\83C\83\93\82ð\8aÇ\97\9d\82·\82é TBoardPlugin \83N\83\89\83X
+// =========================================================================
+
 // *************************************************************************
-// \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8aJ\95ú\82·\82é
+// \83R\83\93\83X\83g\83\89\83N\83^
 // *************************************************************************
-procedure DisposeResultString(
-       resultStr : PChar
-); stdcall;
+constructor    TBoardPlugIn.Create;
 begin
 
-       FreeMem( resultStr );
+       inherited;
+
+       FLoad                                                           := nil;
+       FVersionInfo                            := nil;
+       FAcceptURL                                      := nil;
+    FExtractBoardURL                   := nil;
+       FPlugInMenu                                     := nil;
+
+       FCreateThreadItem               := nil;
+       FDisposeThreadItem      := nil;
+       FDownloadThread                 := nil;
+       FWriteThread                            := nil;
+       FGetRes                                                 := nil;
+       FGetDat                                                 := nil;
+       FGetHeader                                      := nil;
+       FGetFooter                                      := nil;
+
+       FCreateBoardItem                := nil;
+       FDisposeBoardItem               := nil;
+       FDownloadBoard                  := nil;
+       FCreateThread                           := nil;
+       FEnumThread                                     := nil;
+       FFileName2ThreadURL     := nil;
 
 end;
 
 // *************************************************************************
-// \8ew\92è\82µ\82½ URL \82ð\83_\83E\83\93\83\8d\81[\83h\82µ\82Ä\95Ô\82·
+// \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\8dì\90¬
 // *************************************************************************
-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;
+constructor    TBoardPlugIn.CreateFromPath(
+       inPath : string
+);
 begin
 
-       Result := -1;
+       Create;
 
-       httpSocket := TIdHTTP.Create( nil );
-       try
+       LoadFromPath( inPath );
 
-               // \83C\83x\83\93\83g\82Ì\90Ý\92è
-               if Assigned( OnWork ) then
-                       httpSocket.OnWork                               := OnWork;
-               if Assigned( OnWorkBegin ) then
-                       httpSocket.OnWorkBegin  := OnWorkBegin;
-               if Assigned( OnWorkEnd ) then
-                       httpSocket.OnWorkEnd            := OnWorkEnd;
-
-               httpSocket.Request.CustomHeaders.Clear;
-               httpSocket.Request.ContentRangeStart    := inRangeStart;
-               httpSocket.Request.ContentRangeEnd              := inRangeEnd;
-               if (ioModified <> 0) and (ioModified <> ZERO_DATE) then
-                       httpSocket.Request.LastModified := ioModified - OffsetFromUTC;
-               if inRangeStart = 0 then
-                       httpSocket.Request.AcceptEncoding := 'gzip'
-               else
-                       httpSocket.Request.AcceptEncoding := '';
-               httpSocket.Request.Accept := 'text/html';
-
-               resStream := TMemoryStream.Create;
-               try
-                       try
-                               resStream.Clear;
-
-                               {$IFDEF DEBUG}
-                               Writeln('URL: ' + inURL);
-                               {$ENDIF}
-                               httpSocket.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;
-
-                               Result := httpSocket.ResponseCode;
-                               if (Length( content ) = 0) and (Result = 206) then
-                                       Result := 304;
-
-                               outResultData := CreateResultString( content );
-                       except
-                               on E: EIdSocketError do begin
-                                       ioModified              := ZERO_DATE;
-                                       outResultData   := nil;
-                               end;
-                               on E: EIdConnectException do begin
-                                       ioModified              := ZERO_DATE;
-                                       outResultData   := nil;
-                                       //Item.ErrText  := E.Message;
-                               end;
-                               on E: Exception do begin
-                                       {$IFDEF DEBUG}
-                                       Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
-                                       Writeln('E.Message: ' + E.Message);
-                                       {$ENDIF}
-                                       ioModified              := ZERO_DATE;
-                                       outResultData   := nil;
-                                       Result                          := httpSocket.ResponseCode;
-                                       //Item.ErrText  := E.Message;
-                               end;
-                       end;
-               finally
-                       resStream.Free;
-               end;
+end;
 
-       finally
-               httpSocket.Free;
-       end;
+// *************************************************************************
+// \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\8dì\90¬
+// *************************************************************************
+constructor    TBoardPlugIn.CreateFromName(
+       inName : string
+);
+begin
+
+       Create;
+
+       LoadFromName( inName );
 
 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·
+// \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\8dì\90¬
 // *************************************************************************
-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
-) : PChar; stdcall;                            // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
-var
-       datList : TStringList;
-       dat : PChar;
+constructor    TBoardPlugIn.CreateFromModule(
+       inModule : HMODULE
+);
 begin
 
-       datList := TStringList.Create;
-       datList.Text := string( inDatText );
-       //GikoSys.FAbon.IndividualAbon( datList, ChangeFileExt(FileName,'.NG'));
-       GikoSys.FAbon.Execute( datList );
-       GikoSys.FSelectResFilter.Execute( datList );
+       inherited Create;
 
-       Result := CreateResultString( datList.Text );
+       LoadFromModule( inModule );
 
 end;
 
 // *************************************************************************
-// \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e® 1 \8ds\82ð HTML \82É\95Ï\8a·\82·\82é
+// \83f\83X\83g\83\89\83N\83^
 // *************************************************************************
-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
-) : PChar; stdcall;                            // \90®\8c`\82³\82ê\82½ HTML
-var
-       board : TBoard;
-       threadItem : TThreadItem;
+destructor     TBoardPlugIn.Destroy;
 begin
 
-       // \83_\83~\81[\82Ì\83N\83\89\83X
-       board                           := TBoard.Create;
-       threadItem      := TThreadItem.Create;
+       FreeLibrary( FModule );
 
-       try
-               threadItem.ParentBoard := Board;
-
-               Result := ThreadItemDat2HTML( DWORD( threadItem ), inDatRes, inResNo, inIsNew );
-       except
-       end;
+       inherited;
 
 end;
 
+// *************************************************************************
+// \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
+// *************************************************************************
+procedure TBoardPlugIn.LoadFromPath(
+       inPath : string
+);
+begin
 
+       FFilePath := inPath;
+       if FileExists( inPath ) then
+               FModule := LoadLibrary( PChar( inPath ) )
+       else if FileExists( inPath + '.dll' ) then
+               FModule := LoadLibrary( PChar( inPath + '.dll' ) );
 
-// =========================================================================
-// FilePath
-// =========================================================================
+       LoadPlugInAPI;
+
+end;
 
 // *************************************************************************
-// \83u\83\89\83E\83U\96{\91Ì\82ª\92u\82¢\82Ä\82 \82é\83t\83H\83\8b\83_
+// \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
 // *************************************************************************
-function ApplicationFolder : PChar; stdcall;
+procedure TBoardPlugIn.LoadFromName(
+       inName : string
+);
 begin
 
-       Result := CreateResultString( GikoSys.GetAppDir );
+       LoadFromPath( GikoSys.Setting.GetBoardPlugInDir + inName );
 
 end;
 
 // *************************************************************************
-// \8f\89\8aú\90Ý\92è\83t\83H\83\8b\83_
+// \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
 // *************************************************************************
-function PreferencesFolder : PChar; stdcall;
+procedure TBoardPlugIn.LoadFromModule(
+       inModule        : HMODULE
+);
+var
+       tmp                             : array [0..MAX_PATH] of Char;
 begin
 
-       Result := CreateResultString( GikoSys.GetConfigDir );
+       GetModuleFileName( inModule, tmp, SizeOf( tmp ) );
+       FFilePath       := tmp;
+       FModule         := inModule;
+
+       LoadPlugInAPI;
 
 end;
 
 // *************************************************************************
-// \8f\89\8aú\90Ý\92è\83t\83@\83C\83\8b
+// \83v\83\89\83O\83C\83\93\82ª(\90³\82µ\82­)\83\8d\81[\83h\82³\82ê\82½
 // *************************************************************************
-function PreferencesFile : PChar; stdcall;
+procedure TBoardPlugIn.Loaded;
 begin
 
-       Result := CreateResultString( GikoSys.GetAppDir + 'gikoNavi.ini' );
+       if Assigned( FLoad ) then
+               FLoad( DWORD( Self ) );
 
 end;
 
 // *************************************************************************
-// \83\8d\83O\83t\83H\83\8b\83_
+// \83o\81[\83W\83\87\83\93\8fî\95ñ
 // *************************************************************************
-function LogFolder : PChar; stdcall;
+procedure TBoardPlugIn.VersionInfo(
+       var outAgent            : string;               // \83o\81[\83W\83\87\83\93\82ð\88ê\90Ø\8aÜ\82Ü\82È\82¢\8f\83\90\88\82È\96¼\8fÌ
+       var outMajor            : DWORD;                // \83\81\83W\83\83\81[\83o\81[\83W\83\87\83\93
+       var outMinor            : DWORD;                // \83}\83C\83i\81[\83o\81[\83W\83\87\83\93
+       var outRelease  : string;               // \83\8a\83\8a\81[\83X\92i\8aK\96¼
+       var outRevision : DWORD                 // \83\8a\83r\83W\83\87\83\93\83i\83\93\83o\81[
+);
+var
+       agent                                           : PChar;
+       release                                 : PChar;
 begin
 
-       Result := CreateResultString( GikoSys.GetAppDir + 'Log\' );
+       if Assigned( FVersionInfo ) then begin
+               FVersionInfo( agent, outMajor, outMinor, release, outRevision );
+               outAgent                := string( agent );
+               outRelease      := string( release );
+               DisposeResultString( agent );
+               DisposeResultString( release );
+       end;
 
 end;
 
 // *************************************************************************
-// CSS \83t\83H\83\8b\83_
+// \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©
 // *************************************************************************
-function CSSFolder : PChar; stdcall;
+function       TBoardPlugIn.AcceptURL(
+       inURL : string
+) : TAcceptType;
 begin
 
-       Result := CreateResultString( GikoSys.GetStyleSheetDir );
+       if Assigned( FAcceptURL ) then
+               Result := FAcceptURL( PChar( inURL ) )
+       else
+               Result := atNoAccept;
+
+end;
+// *************************************************************************
+// \8ew\92è\82µ\82½ URL \82©\82ç\8eg\82¦\82éBoard\82ÌURL\82ð\93±\82«\8fo\82·
+// *************************************************************************
+function       TBoardPlugIn.ExtractBoardURL(
+       inURL : string
+) : string;
+var
+       URL : PChar;
+//    tmp : string;
+begin
+    Result := inURL;
+       if Assigned( FExtractBoardURL ) then begin
+       FExtractBoardURL( PChar(inURL), URL);
+        Result := string(URL);
+        DisposeResultString(URL);
+    end;
+end;
+// *************************************************************************
+// \83\81\83j\83\85\81[\83n\83\93\83h\83\89
+// *************************************************************************
+procedure TBoardPlugIn.PlugInMenu(
+       inHandle : HMENU                                        // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
+);
+begin
+
+       if Assigned( FPlugInMenu ) then
+               FPlugInMenu( inHandle );
 
 end;
 
 // *************************************************************************
-// \83X\83L\83\93\82ð\93ü\82ê\82Ä\82¨\82­\83t\83H\83\8b\83_
+// TThreadItem \82ª\90\90¬\82³\82ê\82½
 // *************************************************************************
-function SkinFolder : PChar; stdcall;
+procedure      TBoardPlugIn.CreateThreadItem(
+       threadItem : DWORD      // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+);
 begin
 
-       Result := CreateResultString( GikoSys.GetSkinDir );
+       if Assigned( FCreateThreadItem ) then
+               FCreateThreadItem( threadItem );
 
 end;
 
 // *************************************************************************
-// \8eg\97p\82µ\82Ä\82¢\82é CSS / \83X\83L\83\93
+// TThreadItem \82ª\94j\8aü\82³\82ê\82½
 // *************************************************************************
-function SkinFile : PChar; stdcall;
+procedure      TBoardPlugIn.DisposeThreadItem(
+       threadItem : DWORD      // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+);
 begin
 
-       Result := CreateResultString( GikoSys.Setting.CSSFileName );
+       if Assigned( FDisposeThreadItem ) then
+               FDisposeThreadItem( threadItem );
 
 end;
 
 // *************************************************************************
-// \82 \82Ú\81[\82ñ\8bK\91¥\82ª\92u\82¢\82Ä\82 \82é\83f\83B\83\8c\83N\83g\83\8a
+// \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
 // *************************************************************************
-function AbonFolder : PChar; stdcall;
+function       TBoardPlugIn.DownloadThread(
+       threadItem : DWORD      // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+) : TDownloadState;
 begin
 
-       Result := CreateResultString( GikoSys.Setting.GetNGWordsDir );
+       if Assigned( FDownloadThread ) then
+               Result := FDownloadThread( threadItem )
+       else
+               Result := dsError;
 
 end;
 
 // *************************************************************************
-// \8eg\97p\82µ\82Ä\82¢\82é\82 \82Ú\81[\82ñ\8bK\91¥
+// \8f\91\82«\8d\9e\82Ý\82ð\8ew\8e¦
 // *************************************************************************
-function AbonFile : PChar; stdcall;
+function       TBoardPlugIn.WriteThread(
+       threadItem      : DWORD;        // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inName                  : string;       // \96¼\91O(\83n\83\93\83h\83\8b)
+       inMail                  : string;       // \83\81\81[\83\8b\83A\83h\83\8c\83X
+       inMessage               : string        // \96{\95
+) : TDownloadState;                    // \8f\91\82«\8d\9e\82Ý\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
 begin
 
-       Result := CreateResultString( GikoSys.FAbon.GetNGwordpath );
+       if Assigned( FWriteThread ) then
+               Result := FWriteThread( threadItem, PChar( inName ), PChar( inMail ), PChar( inMessage ) )
+       else
+               Result := dsError;
 
 end;
 
+// *************************************************************************
+// \83\8c\83X\94Ô\8d\86 n \82É\91Î\82·\82é html \82ð\97v\8b\81
+// *************************************************************************
+function TBoardPlugIn.GetRes(
+       threadItem      : DWORD;                // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inNo                            : DWORD                 // \95\\8e¦\82·\82é\83\8c\83X\94Ô\8d\86
+) : string;                                                    // \95\\8e¦\82·\82é HTML
+var
+       tmp                                     : PChar;
+begin
 
+       if Assigned( FGetRes ) then begin
+               tmp                     := FGetRes( threadItem, inNo );
+               try
+                       Result  := string( tmp );
+               finally
+                       DisposeResultString( tmp );
+               end;
+       end;
 
-// =========================================================================
-// ThreadItem
-// =========================================================================
+end;
 
 // *************************************************************************
-// TThreadItem \83N\83\89\83X\82Ì\83v\83\8d\83p\83e\83B\82ð\8eæ\93¾\82·\82é
+// \83\8c\83X\94Ô\8d\86 n \82É\91Î\82·\82é Dat \82ð\97v\8b\81
 // *************************************************************************
-function ThreadItemGetLong(
-       instance                : DWORD;
-       propertyID      : TThreadItemProperty
-) : DWORD; stdcall;
+function TBoardPlugIn.GetDat(
+       threadItem      : DWORD;                // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inNo                            : DWORD                 // \95\\8e¦\82·\82é\83\8c\83X\94Ô\8d\86
+) : string; // \82Q\82¿\82á\82ñ\82Ë\82é\82Ìdat\8c`\8e®
 var
-       threadItem : TThreadItem;
+       tmp :   PChar;
 begin
 
-       threadItem := TThreadItem( instance );
-       case propertyID of
-               tipContext:                                                     // : DWORD                      // \8e©\97R\82É\90Ý\92è\82µ\82Ä\82¢\82¢\92l
-                       Result := threadItem.Context;
-               tipNo:                                                                  // : Integer            // \94Ô\8d\86
-                       Result := threadItem.No;
-               tipFileName:                                            // : string                     // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
-                       Result := DWORD( CreateResultString( threadItem.FileName ) );
-               tipTitle:                                                               // : string                     // \83X\83\8c\83b\83h\83^\83C\83g\83\8b
-                       Result := DWORD( CreateResultString( threadItem.Title ) );
-               tipCount:                                                               // : Integer            // \83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83\8d\81[\83J\83\8b\81j
-                       Result := threadItem.Count;
-               tipAllResCount:                                 // : Integer            // \83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83T\81[\83o\81j
-                       Result := threadItem.AllResCount;
-               tipNewResCount:                                 // : Integer            // \83X\83\8c\83b\83h\90V\92\85\90\94
-                       Result := threadItem.NewResCount;
-               tipSize:                                                                // : Integer            // \83X\83\8c\83b\83h\83T\83C\83Y
-                       Result := threadItem.Size;
-               tipRound:                                                               // : Boolean            // \8f\84\89ñ\83t\83\89\83O
-                       Result := DWORD( threadItem.Round );
-               tipRoundName:                                           // : string                     // \8f\84\89ñ\96¼
-                       Result := DWORD( CreateResultString( threadItem.RoundName ) );
-               tipIsLogFile:                                           // : Boolean            // \83\8d\83O\91\8dÝ\83t\83\89\83O
-                       Result := DWORD( threadItem.IsLogFile );
-               tipKokomade:                                            // : Integer            // \83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
-                       Result := threadItem.Kokomade;
-               tipNewReceive:                                  // : Integer            // \83R\83R\82©\82ç\90V\8bK\8eó\90M
-                       Result := threadItem.NewReceive;
-               tipNewArrival:                                  // : Boolean            // \90V\92\85
-                       Result := DWORD( threadItem.NewArrival );
-               tipUnRead:                                                      // : Boolean            // \96¢\93Ç\83t\83\89\83O
-                       Result := DWORD( threadItem.UnRead );
-               tipScrollTop:                                           // : Integer            // \83X\83N\83\8d\81[\83\8b\88Ê\92u
-                       Result := threadItem.ScrollTop;
-               tipDownloadHost:                                // : string                     // \8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
-                       Result := DWORD( CreateResultString( threadItem.DownloadHost ) );
-               tipAgeSage:                                                     // : TThreadAgeSage     // \83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
-                       Result := DWORD( threadItem.AgeSage );
-               tipURL:                                                                 // : string                     // \83X\83\8c\83b\83h\82ð\83u\83\89\83E\83U\82Å\95\\8e¦\82·\82é\8dÛ\82Ì URL
-                       Result := DWORD( CreateResultString( threadItem.URL ) );
+       if Assigned( FGetDat ) then begin
+               tmp := FGetDat( threadItem, inNo );
+               try
+                       Result := string( tmp );
+               finally
+                       DisposeResultString(tmp);  end;
        end;
+
 end;
 
 // *************************************************************************
-// TThreadItem \83N\83\89\83X\82Ì\83v\83\8d\83p\83e\83B\82ð\90Ý\92è\82·\82é
+// \83X\83\8c\83b\83h\82Ì\83w\83b\83_ html \82ð\97v\8b\81
 // *************************************************************************
-procedure ThreadItemSetLong(
-       instance                : DWORD;
-       propertyID      : TThreadItemProperty;
-       param : DWORD
-); stdcall;
+function TBoardPlugIn.GetHeader(
+       threadItem                              : DWORD;        // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inOptionalHeader        : string        // \92Ç\89Á\82Ì\83w\83b\83_
+) : string;                                                                            // \90®\8c`\82³\82ê\82½ HTML
 var
-       threadItem      : TThreadItem;
+       tmp                                                             : PChar;
 begin
 
-       threadItem := TThreadItem( instance );
-       case propertyID of
-               tipContext:                                                     // : DWORD                      // \8e©\97R\82É\90Ý\92è\82µ\82Ä\82¢\82¢\92l
-                       threadItem.Context                      := param;
-               tipNo:                                                                  // : Integer            // \94Ô\8d\86
-                       threadItem.No                                           := param;
-               tipFileName:                                            // : string                     // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
-               begin
-                       threadItem.FileName                     := string( PChar( param ) );
-                       DisposeResultString( PChar( param ) );
-               end;
-               tipTitle:                                                               // : string                     // \83X\83\8c\83b\83h\83^\83C\83g\83\8b
-               begin
-                       threadItem.Title                                := string( PChar( param ) );
-                       DisposeResultString( PChar( param ) );
-               end;
-               tipCount:                                                               // : Integer            // \83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83\8d\81[\83J\83\8b\81j
-                       threadItem.Count                                := param;
-               tipAllResCount:                                 // : Integer            // \83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83T\81[\83o\81j
-                       threadItem.AllResCount  := param;
-               tipNewResCount:                                 // : Integer            // \83X\83\8c\83b\83h\90V\92\85\90\94
-                       threadItem.NewResCount  := param;
-               tipSize:                                                                // : Integer            // \83X\83\8c\83b\83h\83T\83C\83Y
-                       threadItem.Size                                 := param;
-               tipRound:                                                               // : Boolean            // \8f\84\89ñ\83t\83\89\83O
-                       threadItem.Round                                := Boolean( param );
-               tipRoundName:                                           // : string                     // \8f\84\89ñ\96¼
-               begin
-                       threadItem.RoundName            := string( PChar( param ) );
-                       DisposeResultString( PChar( param ) );
-               end;
-               tipIsLogFile:                                           // : Boolean            // \83\8d\83O\91\8dÝ\83t\83\89\83O
-                       threadItem.IsLogFile            := Boolean( param );
-               tipKokomade:                                            // : Integer            // \83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
-                       threadItem.Kokomade                     := param;
-               tipNewReceive:                                  // : Integer            // \83R\83R\82©\82ç\90V\8bK\8eó\90M
-                       threadItem.NewReceive           := param;
-               tipNewArrival:                                  // : Boolean            // \90V\92\85
-                       threadItem.NewArrival           := Boolean( param );
-               tipUnRead:                                                      // : Boolean            // \96¢\93Ç\83t\83\89\83O
-                       threadItem.UnRead                               := Boolean( param );
-               tipScrollTop:                                           // : Integer            // \83X\83N\83\8d\81[\83\8b\88Ê\92u
-                       threadItem.ScrollTop             := param;
-               tipDownloadHost:                                // : string                     // \8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
-               begin
-                       threadItem.DownloadHost := string( PChar( param ) );
-                       DisposeResultString( PChar( param ) );
-               end;
-               tipAgeSage:                                                     // : TThreadAgeSage     // \83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
-                       threadItem.AgeSage                      := TGikoAgeSage( param );
-               tipURL:                                                                 // : string                     // \83X\83\8c\83b\83h\82ð\83u\83\89\83E\83U\82Å\95\\8e¦\82·\82é\8dÛ\82Ì URL
-               begin
-                       threadItem.URL                                  := string( PChar( param ) );
-                       DisposeResultString( PChar( param ) );
+       if Assigned( FGetHeader ) then begin
+               tmp                     := FGetHeader( threadItem, PChar( inOptionalHeader ) );
+               try
+                       Result  := string( tmp );
+               finally
+                       DisposeResultString( tmp );
                end;
        end;
 
 end;
 
 // *************************************************************************
-// TThreadItem \83N\83\89\83X\82Ì\83v\83\8d\83p\83e\83B\82ð\8eæ\93¾\82·\82é
+// \83X\83\8c\83b\83h\82Ì\83t\83b\83^ html \82ð\97v\8b\81
 // *************************************************************************
-function ThreadItemGetDouble(
-       instance                : DWORD;
-       propertyID      : TThreadItemProperty
-) : Double; stdcall;
+function TBoardPlugIn.GetFooter(
+       threadItem                              : DWORD;        // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inOptionalFooter        : string        // \92Ç\89Á\82Ì\83t\83b\83^
+) : string;                                                                            // \90®\8c`\82³\82ê\82½ HTML
 var
-       threadItem : TThreadItem;
+       tmp                                                             : PChar;
 begin
 
-       threadItem := TThreadItem( instance );
-       case propertyID of
-               tipRoundDate:                                           // : TDateTime  // \83X\83\8c\83b\83h\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
-                       Result := threadItem.RoundDate;
-               tipLastModified:                                // : TDateTime  // \83X\83\8c\83b\83h\82ª\8dX\90V\82³\82ê\82Ä\82¢\82é\93ú\8e\9e\81i\83T\81[\83o\91¤\93ú\8e\9e\81j
-                       Result := threadItem.LastModified;
+       if Assigned( FGetFooter ) then begin
+               tmp                     := FGetFooter( threadItem, PChar( inOptionalFooter ) );
+               Result  := string( tmp );
+               DisposeResultString( tmp );
        end;
 
 end;
 
 // *************************************************************************
-// TThreadItem \83N\83\89\83X\82Ì\83v\83\8d\83p\83e\83B\82ð\90Ý\92è\82·\82é
+// \82±\82Ì ThreadItem \82ª\91®\82·\82é\94Â\82Ì URL \82ð\97v\8b\81
 // *************************************************************************
-procedure ThreadItemSetDouble(
-       instance                : DWORD;
-       propertyID      : TThreadItemProperty;
-       param                           : Double
-); stdcall;
+function       TBoardPlugIn.GetBoardURL(
+       threadItem      : DWORD // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
+) : string;
 var
-       threadItem : TThreadItem;
+       tmp                                     : PChar;
 begin
 
-       threadItem := TThreadItem( instance );
-       case propertyID of
-               tipRoundDate:                                           // : TDateTime  // \83X\83\8c\83b\83h\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
-                       threadItem.RoundDate            := param;
-               tipLastModified:                                // : TDateTime  // \83X\83\8c\83b\83h\82ª\8dX\90V\82³\82ê\82Ä\82¢\82é\93ú\8e\9e\81i\83T\81[\83o\91¤\93ú\8e\9e\81j
-                       threadItem.LastModified := param;
+       if Assigned( FGetBoardURL ) then begin
+               tmp                     := FGetBoardURL( threadItem );
+               Result  := string( tmp );
+               DisposeResultString( tmp );
        end;
 
 end;
 
 // *************************************************************************
-// TThreadItem \83N\83\89\83X\82ð\8c³\82É\82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e® 1 \8ds\82ð HTML \82É\95Ï\8a·\82·\82é
+// TBoardItem \82ª\90\90¬\82³\82ê\82½
 // *************************************************************************
-function ThreadItemDat2HTML(
-       inInstance      : DWORD;                // \83N\83\89\83X\82Ì\83C\83\93\83X\83^\83\93\83X
-       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
-       threadItem : TThreadItem;
-       res : TResRec;
-       no : string;
+procedure      TBoardPlugIn.CreateBoardItem(
+       boardItem : DWORD       // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
+);
 begin
 
-       threadItem      := TThreadItem( inInstance );
-       // \88ø\90\94\82ð\95ª\89ð
-       res                                     := GikoSys.DivideStrLine( string( inDatRes ) );
-       no                                      := IntToStr( inResNo );
+       if Assigned( FCreateBoardItem ) then
+               FCreateBoardItem( boardItem );
 
-       try
-               if GikoSys.Setting.UseSkin then begin
-                       // \83X\83L\83\93
-                       if inIsNew then
-                               Result := CreateResultString( GikoSys.SkinedRes(
-                                       GikoSys.LoadFromSkin(
-                                               GikoSys.GetSkinNewResFileName, threadItem, 0
-                                       ), res, no
-                               ) )
-                       else
-                               Result := CreateResultString( GikoSys.SkinedRes(
-                                       GikoSys.LoadFromSkin(
-                                               GikoSys.GetSkinResFileName, threadItem, 0
-                                       ), res, no
-                               ) );
-               end else begin
-                       // CSS or \83f\83t\83H\83\8b\83g
-                       if res.FName = '' then
-                               res.FName := '&nbsp;';
-                       if res.FMailTo = '' then
-                               Result := CreateResultString( '<a name="' + no + '"></a>'
-                                                               + '<div class="header"><span class="no"><a href="menu:' + No + '">' + no + '</a></span> '
-                                                               + '<span class="name_label">\96¼\91O\81F</span> '
-                                                               + '<span class="name"><b>' + res.FName + '</b></span> '
-                                                               + '<span class="date_label">\93\8a\8de\93ú\81F</span> '
-                                                               + '<span class="date">' + res.FDateTime+ '</span></div>'
-                                                               + '<div class="mes">' + res.FBody + ' </div>' )
-                       else if GikoSys.Setting.ShowMail then
-                               Result := CreateResultString( '<a name="' + no + '"></a>'
-                                                               + '<div class="header"><span class="no"><a href="menu:' + no + '">' + no + '</a></span>'
-                                                               + '<span class="name_label"> \96¼\91O\81F </span>'
-                                                               + '<a class="name_mail" href="mailto:' + res.FMailTo + '">'
-                                                               + '<b>' + res.FName + '</b></a><span class="mail"> [' + res.FMailTo + ']</span>'
-                                                               + '<span class="date_label"> \93\8a\8de\93ú\81F</span>'
-                                                               + '<span class="date"> ' + res.FDateTime+ '</span></div>'
-                                                               + '<div class="mes">' + res.FBody + ' </div>' )
-                       else
-                               Result := CreateResultString( '<a name="' + no + '"></a>'
-                                                               + '<div class="header"><span class="no"><a href="menu:' + no + '">' + no + '</a></span>'
-                                                               + '<span class="name_label"> \96¼\91O\81F </span>'
-                                                               + '<a class="name_mail" href="mailto:' + res.FMailTo + '">'
-                                                               + '<b>' + res.FName + '</b></a>'
-                                                               + '<span class="date_label"> \93\8a\8de\93ú\81F</span>'
-                                                               + '<span class="date"> ' + res.FDateTime+ '</span></div>'
-                                                               + '<div class="mes">' + res.FBody + ' </div>' );
-               end;
-       except
-       end;
+end;
+
+// *************************************************************************
+// TBoardItem \82ª\94j\8aü\82³\82ê\82½
+// *************************************************************************
+procedure      TBoardPlugIn.DisposeBoardItem(
+       boardItem : DWORD       // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
+);
+begin
+
+       if Assigned( FDisposeBoardItem ) then
+               FDisposeBoardItem( boardItem );
+
+end;
+
+// *************************************************************************
+// \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
+// *************************************************************************
+function       TBoardPlugIn.DownloadBoard(
+       boardItem : DWORD       // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
+) : TDownloadState;
+begin
+
+       if Assigned( FDownloadBoard ) then
+               Result := FDownloadBoard( boardItem )
+       else
+               Result := dsError;
 
 end;
 
 // *************************************************************************
-// \83_\83E\83\93\83\8d\81[\83h\82ª\90i\8ds\82µ\82½
+// \83X\83\8c\97§\82Ä\82ð\8ew\8e¦
 // *************************************************************************
-procedure ThreadItemWork(
-       inInstance      : DWORD;                        // \83N\83\89\83X\82Ì\83C\83\93\83X\83^\83\93\83X
-       inWorkCount     : Integer                       // \8c»\8dÝ\82Ì\90i\95à\8fó\8bµ(\83J\83E\83\93\83g)
-); stdcall;
+function       TBoardPlugIn.CreateThread(
+       boardItem               : DWORD;        // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inSubject               : string;       // \83X\83\8c\83^\83C
+       inName                  : string;       // \96¼\91O(\83n\83\93\83h\83\8b)
+       inMail                  : string;       // \83\81\81[\83\8b\83A\83h\83\8c\83X
+       inMessage               : string        // \96{\95
+) : TDownloadState;                    // \8f\91\82«\8d\9e\82Ý\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
 begin
 
-       if Assigned( OnWork ) then
-               OnWork( TObject( inInstance ), wmRead, inWorkCount );
+       if Assigned( FCreateThread ) then
+               Result := FCreateThread( boardItem, PChar( inSubject ), PChar( inName ), PChar( inMail ), PChar( inMessage ) )
+       else
+               Result := dsError;
 
 end;
 
 // *************************************************************************
-// \83_\83E\83\93\83\8d\81[\83h\82ª\8en\82Ü\82Á\82½
+// \82±\82Ì\94Â\82É\95Û\97L\82µ\82Ä\82¢\82é\83X\83\8c\82ð\97ñ\8b\93
 // *************************************************************************
-procedure ThreadItemWorkBegin(
-       inInstance                      : DWORD;        // \83N\83\89\83X\82Ì\83C\83\93\83X\83^\83\93\83X
-       inWorkCountMax  : Integer       // \92Ê\90M\82Ì\8fI\82í\82è\82ð\8e¦\82·\83J\83E\83\93\83g
-); stdcall;
+procedure TBoardPlugIn.EnumThread(
+       boardItem               : DWORD;        // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inCallBack      : TBoardItemEnumThreadCallBack
+);
 begin
 
-       if Assigned( OnWorkBegin ) then
-               OnWorkBegin( TObject( inInstance ), wmRead, inWorkCountMax );
+       if Assigned( FEnumThread ) then
+               FEnumThread( boardItem, inCallBack );
 
 end;
 
 // *************************************************************************
-// \83_\83E\83\93\83\8d\81[\83h\82ª\8fI\82í\82Á\82½
+// \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\97v\8b\81
 // *************************************************************************
-procedure ThreadItemWorkEnd(
-       inInstance      : DWORD                         // \83N\83\89\83X\82Ì\83C\83\93\83X\83^\83\93\83X
-); stdcall;
+function       TBoardPlugIn.FileName2ThreadURL(
+       boardItem               : DWORD;        // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
+       inFileName      : string
+) : string;
+var
+       tmp                                                             : PChar;
 begin
 
-       if Assigned( OnWorkEnd ) then
-               OnWorkEnd( TObject( inInstance ), wmRead );
+       if Assigned( FFileName2ThreadURL ) then begin
+               tmp                     := FFileName2ThreadURL( boardItem, PChar( inFileName ) );
+               Result  := string( tmp );
+               DisposeResultString( tmp );
+       end;
 
 end;
 
-exports
-       CreateResultString,
-       DisposeResultString,
-       ApplicationFolder,
-       PreferencesFolder,
-       PreferencesFile,
-       LogFolder,
-       CSSFolder,
-       SkinFolder,
-       SkinFile,
-       AbonFolder,
-       AbonFile,
-       InternalDownload,
-       InternalAbon,
-       InternalDat2HTML,
-       ThreadItemGetLong,
-       ThreadItemSetLong,
-       ThreadItemGetDouble,
-       ThreadItemSetDouble,
-       ThreadItemDat2HTML,
-       ThreadItemWork,
-       ThreadItemWorkBegin,
-       ThreadItemWorkEnd;
+// *************************************************************************
+// \83v\83\89\83O\83C\83\93\82Ì API \82ð\8eæ\93¾
+// *************************************************************************
+procedure TBoardPlugIn.LoadPlugInAPI;
+begin
+
+       try
+               if Assigned( Pointer( FModule ) ) then begin
+                       FLoad                                                           := GetProcAddress( FModule, 'OnLoad' );
+                       FVersionInfo                            := GetProcAddress( FModule, 'OnVersionInfo' );
+                       FAcceptURL                                      := GetProcAddress( FModule, 'OnAcceptURL' );
+            FExtractBoardURL                           := GetProcAddress( FModule, 'OnExtractBoardURL' );
+                       FPlugInMenu                                     := GetProcAddress( FModule, 'OnPlugInMenu' );
+
+                       FCreateThreadItem               := GetProcAddress( FModule, 'ThreadItemCreate' );
+                       FDisposeThreadItem      := GetProcAddress( FModule, 'ThreadItemDispose' );
+                       FDownloadThread                 := GetProcAddress( FModule, 'ThreadItemOnDownload' );
+                       FWriteThread                            := GetProcAddress( FModule, 'ThreadItemOnWrite' );
+                       FGetRes                                                 := GetProcAddress( FModule, 'ThreadItemOnGetRes' );
+                       FGetDat                                                 := GetProcAddress( FModule, 'ThreadItemOnGetDat' );
+                       FGetHeader                                      := GetProcAddress( FModule, 'ThreadItemOnGetHeader' );
+                       FGetFooter                                      := GetProcAddress( FModule, 'ThreadItemOnGetFooter' );
+                       FGetBoardURL                            := GetProcAddress( FModule, 'ThreadItemOnGetBoardURL' );
+
+                       FCreateBoardItem                := GetProcAddress( FModule, 'BoardItemCreate' );
+                       FDisposeBoardItem               := GetProcAddress( FModule, 'BoardItemDispose' );
+                       FDownloadBoard                  := GetProcAddress( FModule, 'BoardItemOnDownload' );
+                       FCreateThread                           := GetProcAddress( FModule, 'BoardItemOnCreateThread' );
+                       FEnumThread                                     := GetProcAddress( FModule, 'BoardItemOnEnumThread' );
+                       FFileName2ThreadURL     := GetProcAddress( FModule, 'BoardItemOnFileName2ThreadURL' );
+               end;
+       except
+       end;
+
+end;
 
 end.
+