OSDN Git Service

Be用plugin(試作品)
authorh677 <h677>
Thu, 28 Jul 2005 14:44:17 +0000 (14:44 +0000)
committerh677 <h677>
Thu, 28 Jul 2005 14:44:17 +0000 (14:44 +0000)
res/ExternalBoardPlugIn/Be2chPlugIn.dpr [new file with mode: 0644]
res/ExternalBoardPlugIn/Be2chPlugIn.res [new file with mode: 0644]

diff --git a/res/ExternalBoardPlugIn/Be2chPlugIn.dpr b/res/ExternalBoardPlugIn/Be2chPlugIn.dpr
new file mode 100644 (file)
index 0000000..599aeef
--- /dev/null
@@ -0,0 +1,1353 @@
+library Be2chPlugIn;
+
+{
+       Be2chPlugIn
+       \82Q\82¿\82á\82ñ\82Ë\82éBe\8f\88\97\9d\83\86\83j\83b\83g
+}
+
+uses
+  Windows,
+  SysUtils,
+  Classes,
+  Math,
+  DateUtils,
+  IdURI,
+  PlugInMain in 'PlugInMain.pas',
+  ThreadItem in 'ThreadItem.pas',
+  BoardItem in 'BoardItem.pas',
+       FilePath in 'FilePath.pas',
+  Y_TextConverter in 'Y_TextConverter.pas',
+  MojuUtils in '..\..\MojuUtils.pas';
+
+{$E dll}
+
+{$R *.res}
+
+type
+       // =========================================================================
+       // TBe2chThreadItem
+       // =========================================================================
+       TBe2chThreadItem = class(TThreadItem)
+       private
+               FIsTemporary    : Boolean;
+               FDat                                    : TStringList;
+
+       public
+               constructor     Create( inInstance : DWORD );
+               destructor      Destroy; override;
+
+       private
+               function        Download : TDownloadState;
+               function        Write( inName : string; inMail : string; inMessage : string ) : TDownloadState;
+               function        GetRes( inNo : Integer ) : string;
+               function        GetDat( inNo : Integer ) : string;
+               function        GetHeader( inOptionalHeader : string ) : string;
+               function        GetFooter( inOptionalFooter : string ) : string;
+               function        GetBoardURL : string;
+               procedure       LoadDat;
+               procedure       FreeDat;
+               function        BrowsableURL : string;
+               function        ReadURL : string;
+               function        WriteURL : string;
+               function        AddBeProfileLink( AID : string; ANum: Integer) : string;
+       end;
+
+       // =========================================================================
+       // TBe2chBoardItem
+       // =========================================================================
+       TBe2chBoardItem = class(TBoardItem)
+       private
+               FIsTemporary    : Boolean;
+               FDat                                    : TStringList;
+
+       public
+               constructor     Create( inInstance : DWORD );
+               destructor      Destroy; override;
+
+       private
+               function        Download : TDownloadState;
+               function        CreateThread( inSubject : string; inName : string; inMail : string; inMessage : string ) : TDownloadState;
+               function        ToThreadURL( inFileName : string ) : string;
+               procedure       EnumThread( inCallBack : TBoardItemEnumThreadCallBack );
+
+               function        SubjectURL : string;
+       end;
+
+const
+       LOG_DIR                                         = 'Be2ch\';
+       SUBJECT_NAME                    = 'subject.txt';
+
+       PLUGIN_NAME                             = 'Be2ch';
+       MAJOR_VERSION                   = 1;
+       MINOR_VERSION                   = 1;
+       RELEASE_VERSION         = 'alpha';
+       REVISION_VERSION        = 1;
+
+// =========================================================================
+// \8eG\97p\8aÖ\90\94
+// =========================================================================
+
+// *************************************************************************
+// \83e\83\93\83|\83\89\83\8a\82È\83p\83X\82Ì\8eæ\93¾
+// *************************************************************************
+function TemporaryFile : string;
+var
+       tempPath : array [0..MAX_PATH] of       char;
+begin
+
+       GetTempPath( SizeOf(tempPath), tempPath );
+       repeat
+               Result := tempPath + IntToStr( Random( $7fffffff ) );
+       until not FileExists( Result );
+
+end;
+
+// *************************************************************************
+// Be\97p\83\8d\83O\83t\83H\83\8b\83_\8eæ\93¾
+// *************************************************************************
+function MyLogFolder : string;
+var
+       folder : PChar;
+begin
+
+       folder := LogFolder;
+       if Length( folder ) = 0 then
+               Result := ''
+       else
+               Result := folder + LOG_DIR;
+       DisposeResultString(folder);
+
+end;
+
+(*************************************************************************
+ *\83f\83B\83\8c\83N\83g\83\8a\82ª\91\8dÝ\82·\82é\82©\83`\83F\83b\83N
+ *************************************************************************)
+function DirectoryExistsEx(const Name: string): Boolean;
+var
+       Code: Integer;
+begin
+       Code := GetFileAttributes(PChar(Name));
+       Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
+end;
+
+(*************************************************************************
+ *\83f\83B\83\8c\83N\83g\83\8a\8dì\90¬\81i\95¡\90\94\8aK\91w\91Î\89\9e\81j
+ *************************************************************************)
+function ForceDirectoriesEx(Dir: string): Boolean;
+begin
+       Result := True;
+       if Length(Dir) = 0 then
+               raise Exception.Create('\83t\83H\83\8b\83_\82ª\8dì\90¬\8fo\97\88\82Ü\82¹\82ñ');
+       Dir := ExcludeTrailingPathDelimiter(Dir);
+       if (Length(Dir) < 3) or DirectoryExistsEx(Dir)
+               or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
+       Result := ForceDirectoriesEx(ExtractFilePath(Dir)) and CreateDir(Dir);
+end;
+
+// \82Æ\82è\82 \82¦\82¸\82Ì\91ã\97p\95i\82È\82Ì\82Å chrWhite \82ð\8dl\97\82µ\82Ä\82¢\82È\82¢\82±\82Æ\82É\92\8d\88Ó\81I\81I\81I
+procedure ExtractHttpFields(
+       const chrSep : TSysCharSet;
+       const chrWhite : TSysCharSet;
+       const strValue : string;
+       var strResult : TStringList;
+       unknownFlag : boolean = false
+);
+var
+       last, p, strLen : Integer;
+begin
+
+       strLen := Length( strValue );
+       p := 1;
+       last := 1;
+
+       while p <= strLen do
+       begin
+
+               if strValue[ p ] in chrSep then
+               begin
+                       strResult.Add( Copy( strValue, last, p - last ) );
+                       last := p + 1;
+               end;
+
+               p := p + 1;
+
+       end;
+
+       if last <> p then
+               strResult.Add( Copy( strValue, last, strLen - last + 1 ) );
+
+end;
+
+\rfunction HttpEncode(
+\r      const strValue : string
+) : string;
+var
+       i : Integer;
+       strLen : Integer;
+       strResult : string;
+       b : Integer;
+const
+       kHexCode : array [0..15] of char = (
+                               '0', '1', '2', '3', '4', '5', '6', '7',
+                               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' );
+begin
+
+       strLen := Length( strValue );
+       i := 1;
+
+       while i <= strLen do
+       begin
+
+               case strValue[ i ] of
+               '0' .. '9', 'a' .. 'z', 'A' .. 'Z', '*', '-', '.', '@', '_':
+                       begin
+                               strResult := strResult + strValue[ i ];
+                       end;
+               else
+                       begin
+                               b := Integer( strValue[ i ] );
+                               strResult := strResult + '%'
+                                                               + kHexCode[ b div $10 ]
+                                                               + kHexCode[ b mod $10 ];
+                       end;
+               end;
+
+               i := i + 1;
+
+       end;
+
+       Result := strResult;
+
+end;
+
+
+
+// =========================================================================
+// PlugIn
+// =========================================================================
+// *************************************************************************
+// \83v\83\89\83O\83C\83\93\82Ì\83o\81[\83W\83\87\83\93\82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+procedure OnVersionInfo(
+       var outAgent            : PChar;        // \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  : PChar;        // \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[
+); stdcall;
+begin
+
+       try
+               outAgent                := CreateResultString( PChar( PLUGIN_NAME ) );
+               outMajor                := MAJOR_VERSION;
+               outMinor                := MINOR_VERSION;
+               outRelease      := CreateResultString( PChar( RELEASE_VERSION ) );
+               outRevision     := REVISION_VERSION;
+       except
+               outAgent                := nil;
+               outMajor                := 0;
+               outMinor                := 0;
+               outRelease      := nil;
+               outRevision     := 0;
+       end;
+
+end;
+
+// *************************************************************************
+// \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 OnAcceptURL(
+       inURL                   : PChar                         // \94»\92f\82ð\8bÂ\82¢\82Å\82¢\82é URL
+): TAcceptType; stdcall;       // URL \82Ì\8eí\97Þ
+var
+       uri                             : TIdURI;
+       uriList         : TStringList;
+       foundPos        : Integer;
+//     i                       : Integer;
+const
+       BBS_HOST                = 'be.2ch.net';
+       THREAD_MARK     = '/test/read.cgi';
+begin
+
+       try
+               // \83z\83X\83g\96¼\82ª be.2ch.net\82È\82ç\8eó\82¯\95t\82¯\82é
+               uri                     := TIdURI.Create( inURL );
+               uriList := TStringList.Create;
+               try
+
+                       ExtractHttpFields( ['/'], [], uri.Path, uriList );
+                       if (AnsiPos( BBS_HOST, uri.Host ) > 0) and (Length( uri.Host ) - AnsiPos( BBS_HOST, uri.Host ) + 1 = Length( BBS_HOST )) then begin
+                               foundPos := AnsiPos( THREAD_MARK, inURL );
+
+                               if foundPos > 0 then
+                                       Result := atThread
+                               else if (uriList.Count > 2) and (AnsiPos('.html', uri.Document) > 0) then
+                                       Result := atThread
+                               else if uriList.Count = 2 then  
+                                       Result := atBoard
+                               else
+                                       Result := atBBS;
+
+                       end else begin
+                               Result := atNoAccept;
+                       end;
+
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       except
+               Result := atNoAccept;
+       end;
+
+end;
+
+function BrowsableURL(
+       inURL : string
+) : string;
+var
+       uri                             : TIdURI;
+       uriList         : TStringList;
+       foundPos        : Integer;
+       dir, tmphost            : string;
+const
+       THREAD_MARK     = '/test/read.cgi';
+       BBS_HOST                = 'be.2ch.net';
+begin
+
+       foundPos := AnsiPos( '?', inURL );
+       if foundPos > 0 then begin
+               // \8b\8c\8e®
+               uri := TIdURI.Create( inURL );
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/'], [], uri.Path, uriList );
+                       dir := uriList[ 1 ];
+
+                       tmphost := uri.Host;
+
+                       ExtractHttpFields( ['&'], [], Copy( inURL, foundPos + 1, MaxInt ), uriList );
+                       Result :=
+                               uri.Protocol + '://' + tmphost + THREAD_MARK +
+                               dir + '/' + uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/l100';
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end else begin
+               if Copy( inURL, Length( inURL ), 1 ) = '/' then
+                       uri := TIdURI.Create( inURL )
+               else
+                       uri := TIdURI.Create( inURL + '/' );
+
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/'], [], uri.Path, uriList );
+
+                       tmphost := uri.Host;
+
+                       if( AnsiPos(THREAD_MARK, inURL) > 0) and (uriList.Count > 4) then begin
+                               Result :=
+                                       uri.Protocol + '://' + tmphost + THREAD_MARK + '/' +
+                                       uriList[ 3 ] + '/' + uriList[ 4 ] + '/l50';
+
+                       end else begin
+                               Result := inURL;
+                       end;
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end;
+
+end;
+// *************************************************************************
+// \8ew\92è\82µ\82½ URL \82ðBoard\82ÌURL\82É\95Ï\8a·
+// *************************************************************************
+procedure OnExtractBoardURL(
+       inURL   : PChar;
+       var outURL      : PChar
+); stdcall;
+var
+       uri             : TIdURI;
+       uriList : TStringList;
+       tmphost :       String;
+       URL             :       String;
+const
+       THREAD_MARK     = '/test/read.cgi';
+       BBS_HOST                = 'be.2ch.net';
+begin
+       URL := string(inURL);
+       if (AnsiPos(THREAD_MARK,URL) > 0) then begin
+               URL             := BrowsableURL(URL);
+               uri                     := TIdURI.Create( URL );
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+
+                       tmphost := uri.Host;
+
+                       if uriList.Count > 4 then
+                               URL             := uri.Protocol + '://' + tmphost + '/' + uriList[ 3 ] + '/';
+                       outURL  := CreateResultString(URL);
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end else begin
+               outURL  := CreateResultString(URL);
+       end;
+
+end;
+
+// =========================================================================
+// TShitarabaThreadItem
+// =========================================================================
+
+// *************************************************************************
+// \83R\83\93\83X\83g\83\89\83N\83^
+// *************************************************************************
+constructor TBe2chThreadItem.Create(
+       inInstance      : DWORD
+);
+var
+       uriList                 : TStringList;
+begin
+
+       inherited;
+
+       OnDownload              := Download;
+       OnWrite                         := Write;
+       OnGetRes                        := GetRes;
+       OnGetDat                        := GetDat;
+       OnGetHeader             := GetHeader;
+       OnGetFooter             := GetFooter;
+       OnGetBoardURL   := GetBoardURL;
+
+       FIsTemporary    := False;
+       FDat                                    := nil;
+       URL                                             := BrowsableURL;
+
+       uriList := TStringList.Create;
+       try
+               ExtractHttpFields( ['/', '?'], [], URL, uriList );
+
+               FileName        := uriList[ 6 ] + '.dat';
+               //FilePath      := MyLogFolder + uriList[ 2 ] + '\' + FileName;
+               IsLogFile       := FileExists( FilePath );
+       finally
+               uriList.Free;
+       end;
+
+end;
+
+// *************************************************************************
+// \83f\83X\83g\83\89\83N\83^
+// *************************************************************************
+destructor TBe2chThreadItem.Destroy;
+begin
+
+       FreeDat;
+
+       // \88ê\8e\9e\83t\83@\83C\83\8b\82Ì\8fê\8d\87\82Í\8dí\8f\9c\82·\82é
+       if FIsTemporary then
+               DeleteFile( FilePath );
+
+       inherited;
+
+end;
+
+// *************************************************************************
+// \8ew\92è\82µ\82½ URL \82Ì\83X\83\8c\83b\83h\82Ì\83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦\82³\82ê\82½
+// *************************************************************************
+function TBe2chThreadItem.Download : TDownloadState;
+var
+       modified                        : Double;
+       tmp                                             : PChar;
+       downResult              : TStringList;
+       responseCode    : Longint;
+       logStream                       : TFileStream;
+       uri                                             : TIdURI;
+       uriList                         : TStringList;
+       datURL                          : string;
+       tmpText: string;
+//     rangeEnd                        : Integer;
+       FilePath : string;
+begin
+
+       Result := dsError;
+
+       uri := TIdURI.Create( ReadURL );
+       uriList := TStringList.Create;
+       try
+               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+               FileName := uriList[ 4 ] + '.dat';
+
+               if MyLogFolder = '' then begin
+                       // \82Ç\82±\82É\95Û\91\82µ\82Ä\82¢\82¢\82Ì\82©\95ª\82©\82ç\82È\82¢\82Ì\82Å\88ê\8e\9e\83t\83@\83C\83\8b\82É\95Û\91
+                       FilePath                        := TemporaryFile;
+                       FIsTemporary    := True;
+               end else begin
+                       FilePath                        := MyLogFolder + uriList[ 3 ] + '\' + FileName;
+                       FIsTemporary    := False;
+               end;
+               //http://be.2ch.net/be/dat/1109901078.dat
+               datURL          := 'http://' + uri.Host + '/' + uriList[ 3 ] + '/dat/' + FileName;
+       finally
+               uri.Free;
+               uriList.Free;
+       end;
+
+       // \95Û\91\97p\82Ì\83f\83B\83\8c\83N\83g\83\8a\82ð\8c@\82é
+       ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
+
+       // \93Æ\8e©\82É\83_\83E\83\93\83\8d\81[\83h\82â\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í
+       // InternalDownload \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+       modified        := LastModified;
+       responseCode := InternalDownload( PChar( datURL ), modified, tmp, Size );
+
+       try
+               if (responseCode = 200) or (responseCode = 206) then begin
+                       downResult := TStringList.Create;
+                       try
+                               Size    := Size + Length( string( tmp ) );
+                               
+                               tmpText := CustomStringReplace( string( tmp ), '¡÷¡®', ',' );
+                               downResult.Text := EUCtoSJIS( tmpText );
+
+                               if downResult.Count > 0 then begin
+                                       if FileExists( FilePath ) then
+                                               logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
+                                       else
+                                               logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
+                                       try
+                                               logStream.Position      := logStream.Size;
+                                               logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
+                                       finally
+                                               logStream.Free;
+                                       end;
+
+                                       if Count = 0 then
+                                                                                       // \90V\8bK
+                                               Result := dsComplete
+                                       else
+                                               // \92Ç\8bL
+                                               Result := dsDiffComplete;
+
+
+                                       // CGI \82©\82ç\82Í\90³\82µ\82¢\93ú\95t\82ª\93¾\82ç\82ê\82È\82¢\82Ì\82Å\8c»\8dÝ\82É\90Ý\92è
+                                       LastModified    := Now;
+
+
+
+                                       NewReceive              := Count + 1;
+                                       Count                                   := Count + downResult.Count;
+                                       NewResCount             := downResult.Count;
+
+
+
+                               end else begin
+                                       Result := dsNotModify;
+                               end;
+                       finally
+                               downResult.Free;
+                       end;
+               end else if responseCode = 304 then begin
+                       Result := dsNotModify;
+               end;
+       finally
+               DisposeResultString( tmp );
+       end;
+
+end;
+
+// *************************************************************************
+// \8f\91\82«\8d\9e\82Ý\82ð\8ew\8e¦\82³\82ê\82½
+// *************************************************************************
+function       TBe2chThreadItem.Write(
+       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©
+var
+       postData                        : string;
+       postResult              : PChar;
+       uri                                             : TIdURI;
+       uriList                         : TStringList;
+       responseCode    : Integer;
+begin
+
+       uri                     := TIdURI.Create( URL );
+       uriList := TStringList.Create;
+       try
+               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+       
+               // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
+               postData        :=
+                       'NAME='                 + HttpEncode( SJIStoEUC( inName ) ) +
+                       '&MAIL='                + HttpEncode( SJIStoEUC( inMail ) ) +
+                       '&MESSAGE='     + HttpEncode( SJIStoEUC( inMessage ) ) +
+                       '&BBS='                 + uriList[ 4 ] +
+                       '&KEY='                 + uriList[ 5 ] +
+                       '&DIR='                 + uriList[ 3 ] +
+                       '&TIME='                + IntToStr( DateTimeToUnix( Now ) ) +
+                       '&submit='      + HttpEncode( SJIStoEUC( '\8f\91\82«\8d\9e\82Þ' ) );
+
+               // \93Æ\8e©\82É\92Ê\90M\82µ\82È\82¢\8fê\8d\87\82Í InternalPost \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+               responseCode := InternalPost( PChar( WriteURL ), PChar( postData ), PChar(URL), postResult );
+               try
+                       if (responseCode = 200) or
+                               ((responseCode = 302) and (Length( Trim( postResult ) ) = 0)) then begin
+                               Result := dsComplete
+                       end else begin
+                               Result := dsError;
+                               if Assigned( InternalPrint ) then
+                                       InternalPrint( postResult );
+                       end;
+               finally
+                       DisposeResultString( postResult );
+               end;
+       finally
+               uri.Free;
+               uriList.Free;
+       end;
+
+end;
+
+// *************************************************************************
+// \83\8c\83X\94Ô\8d\86 inNo \82É\91Î\82·\82é html \82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+function TBe2chThreadItem.GetRes(
+       inNo            : Integer               // \97v\8b\81\82³\82ê\82½\83\8c\83X\94Ô\8d\86
+) : string;                                            // \91Î\89\9e\82·\82é HTML
+var
+       res                     : string;
+       tmp                     : PChar;
+begin
+
+       // \93Æ\8e©\82É\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í
+       // InternalAbon \82¨\82æ\82Ñ Dat2HTML \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+               {
+       LoadDat;
+       if FDat = nil then begin
+               // \83\8d\83O\82É\91\8dÝ\82µ\82È\82¢\82Ì\82Å\82±\82Ì\82Ü\82Ü\8fI\97¹
+               Result := '';
+               Exit;
+       end;
+       res := Copy( FDat[ inNo - 1 ], AnsiPos( '<>', FDat[ inNo - 1 ] ) + 2, MaxInt );
+               }
+       res := GetDat( inNo );
+       if res = '' then begin
+               Result := '';
+               Exit;
+       end else begin
+               tmp := InternalAbonForOne( PChar( res ), PChar( FilePath ),inNo );
+               try
+                       Result := Dat2HTML( string( tmp ), inNo );
+               finally
+                       DisposeResultString( tmp );
+               end;
+       end;
+
+end;
+
+// *************************************************************************
+// \83\8c\83X\94Ô\8d\86 inNo \82É\91Î\82·\82é Dat \82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+function TBe2chThreadItem.GetDat(
+       inNo            : Integer               // \97v\8b\81\82³\82ê\82½\83\8c\83X\94Ô\8d\86
+) : string;                                            // \82Q\82¿\82á\82ñ\82Ë\82é\82ÌDat\8c`\8e®
+var
+       res, tmp        : string;
+       AID                     : string;
+//     i                       : Integer;
+       pTmp            : PChar;
+begin
+       pTmp := nil;
+       // \93Æ\8e©\82É\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í
+       // InternalAbon \82¨\82æ\82Ñ Dat2HTML \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+       LoadDat;
+       if (FDat = nil) or (inNo - 1 < 0 ) or (inNo - 1 >= FDat.Count) then begin
+               // \83\8d\83O\82É\91\8dÝ\82µ\82È\82¢\82Ì\82Å\82±\82Ì\82Ü\82Ü\8fI\97¹
+               Result := '';
+               Exit;
+       end;
+       try
+               tmp := FDat[ inNo - 1 ];
+               res := Copy(tmp, 1, AnsiPos('<BE:', tmp) - 1);
+               Delete(tmp, 1, AnsiPos('<BE:', tmp) - 1);
+               AID := Copy(tmp, 1, AnsiPos('>', tmp));
+               Delete(tmp, 1, AnsiPos('>', tmp));
+               res := res + AddBeProfileLink(AID, inNo) + tmp;
+               //<BE:
+               pTmp := CreateResultString(res);
+               Result := string(pTmp);
+       finally
+               DisposeResultString(pTmp);
+       end;
+
+end;
+function TBe2chThreadItem.AddBeProfileLink(
+        AID : string;
+        ANum: Integer
+) : string;
+var
+       p : integer;
+       BNum{, BMark} : string;
+begin
+       //<BE:34600695:4>
+       p := AnsiPos('BE:', AnsiUpperCase(AID));
+       if p > 0 then begin
+               BNum := Copy(AID, p + 3, Length(AID));
+               p := AnsiPos(':', BNum);
+               if p > 0 then begin
+                       BNum := Copy(BNum, 1, p - 1);
+               end;
+               BNum := Trim(BNum);
+               Result := ' <a href="BE:'  + BNum + '/' + IntToStr(ANum)
+                       + '" target=_blank>' + 'BE' + '</a>';
+       end else
+               Result := AID;
+end;
+// *************************************************************************
+// \83X\83\8c\83b\83h\82Ì\83w\83b\83_ html \82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+function TBe2chThreadItem.GetHeader(
+       inOptionalHeader        : string
+) : string;
+begin
+
+       // \93Æ\8e©\82É\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í
+       // InternalHeader \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+       Result := InternalHeader(
+               '<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' +
+               inOptionalHeader );
+
+
+       // GetRes \82ð\8cÄ\82Î\82ê\82é\82±\82Æ\82ª\97\\91z\82³\82ê\82é\82Ì\82Å FDat \82ð\90\90¬\82µ\82Ä\82¨\82­
+       try
+               FreeDat;
+               LoadDat;
+       except
+       end;
+
+end;
+
+// *************************************************************************
+// \83X\83\8c\83b\83h\82Ì\83t\83b\83^ html \82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+function TBe2chThreadItem.GetFooter(
+       inOptionalFooter : string
+) : string;
+begin
+
+       // \93Æ\8e©\82É\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í
+       // InternalFooter \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+       Result := InternalFooter( inOptionalFooter );
+
+       // \82à\82¤ GetRes \82Í\8cÄ\82Î\82ê\82È\82¢\82Æ\8ev\82¤\82Ì\82Å FDat \82ð\8aJ\95ú\82µ\82Ä\82¨\82­
+       try
+               FreeDat;
+       except
+       end;
+
+end;
+
+// *************************************************************************
+// \82±\82Ì ThreadItem \82ª\91®\82·\82é\94Â\82Ì URL \82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+function       TBe2chThreadItem.GetBoardURL : string;
+var
+       uri                                             : TIdURI;
+       uriList                         : TStringList;
+       tmphost:        String;
+const
+       BBS_HOST                = 'be.2ch.net';
+begin
+
+       uri                     := TIdURI.Create( ReadURL );
+       uriList := TStringList.Create;
+       try
+               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+
+               tmphost := uri.Host;
+               if( uriList.Count > 4 ) then begin
+                       FileName := uriList[ 4 ] + '.dat';
+                       Result          := CreateResultString(
+                               uri.Protocol + '://' + tmphost + '/' +  uriList[ 3 ] + '/' );
+               end;
+       finally
+               uri.Free;
+               uriList.Free;
+       end;
+{
+       URL := string(inURL);
+       if (AnsiPos(THREAD_MARK,URL) > 0) then begin
+               URL             := BrowsableURL(URL);
+               uri                     := TIdURI.Create( URL );
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+
+                       tmphost := uri.Host;
+
+                       if uriList.Count > 4 then
+                               URL             := uri.Protocol + '://' + tmphost + '/' + uriList[ 3 ] + '/';
+                       outURL  := CreateResultString(URL);
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end else begin
+               outURL  := CreateResultString(URL);
+       end;
+}
+end;
+
+// *************************************************************************
+// FDat \82Ì\90\90¬
+// *************************************************************************
+procedure      TBe2chThreadItem.LoadDat;
+begin
+
+       if FDat = nil then begin
+               if IsLogFile then begin
+                       // dat \82Ì\93Ç\82Ý\8d\9e\82Ý
+                       FDat := TStringList.Create;
+                       FDat.LoadFromFile( FilePath );
+               end;
+       end;
+
+end;
+
+// *************************************************************************
+// FDat \82Ì\8aJ\95ú
+// *************************************************************************
+procedure      TBe2chThreadItem.FreeDat;
+begin
+
+       if FDat <> nil then begin
+               FDat.Free;
+               FDat := nil;
+       end;
+
+end;
+
+// *************************************************************************
+// \88À\91S\82È\83u\83\89\83E\83U\95\\8e¦\97p\82Ì URL
+// *************************************************************************
+function       TBe2chThreadItem.BrowsableURL : string;
+var
+       uri                             : TIdURI;
+       uriList         : TStringList;
+       foundPos        : Integer;
+       dir, tmphost            : string;
+const
+       THREAD_MARK     = '/test/read.cgi';
+       BBS_HOST                = 'be.2ch.net';
+begin
+
+       foundPos := AnsiPos( '?', URL );
+       if foundPos > 0 then begin
+               // \8b\8c\8e®
+               uri := TIdURI.Create( URL );
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/'], [], uri.Path, uriList );
+                       dir := uriList[ 1 ];
+
+                       tmphost := uri.Host;
+
+                       ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
+                       Result :=
+                               uri.Protocol + '://' + tmphost + THREAD_MARK +
+                               dir + '/' + uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/l100';
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end else begin
+               if Copy( URL, Length( URL ), 1 ) = '/' then
+                       uri := TIdURI.Create( URL )
+               else
+                       uri := TIdURI.Create( URL + '/' );
+
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/'], [], uri.Path, uriList );
+
+                       tmphost := uri.Host;
+
+                       if( AnsiPos(THREAD_MARK, URL) > 0) and (uriList.Count > 4) then begin
+                               Result :=
+                                       uri.Protocol + '://' + tmphost + THREAD_MARK + '/' +
+                                       uriList[ 3 ] + '/' + uriList[ 4 ] + '/l50';
+
+                       end else begin
+                               Result := URL;
+                       end;
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end;
+
+end;
+
+// *************************************************************************
+// \88À\91S\82È( '/' \82Å\8fI\82í\82é )\93Ç\82Ý\8d\9e\82Ý\82Ì URL
+// *************************************************************************
+function       TBe2chThreadItem.ReadURL : string;
+const
+       THREAD_MARK     = '/test/read.cgi';
+var
+       uri                             : TIdURI;
+       uriList         : TStringList;
+       foundPos        : Integer;
+       dir, tmphost                    : string;
+begin
+
+       foundPos := AnsiPos( '?', URL );
+       if foundPos > 0 then begin
+               // \8b\8c\8e®
+               uri := TIdURI.Create( URL );
+               uriList := TStringList.Create;
+               try
+                       ExtractHttpFields( ['/'], [], uri.Path, uriList );
+                       dir := uriList[ 1 ];
+
+                       tmphost := uri.Host;
+
+                       ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
+                       // http://jbbs.livedoor.com/bbs/read.cgi?DIR=game&BBS=1578&KEY=1067968274
+                       Result :=
+                               uri.Protocol + '://' + tmphost + '/bbs/rawmode.cgi/' +
+                               dir + '/' + uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/';
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       end else begin
+               Result := URL;
+       end;
+
+end;
+
+// *************************************************************************
+// \88À\91S\82È( '/' \82Å\8fI\82í\82é )\8f\91\82«\8d\9e\82Ý\82Ì URL
+// *************************************************************************
+function       TBe2chThreadItem.WriteURL : string;
+//var
+//     uri                     : TIdURI;
+//     uriList : TStringList;
+begin
+       {
+       if Copy( URL, Length( URL ), 1 ) = '/' then
+               uri := TIdURI.Create( URL )
+       else
+               uri := TIdURI.Create( URL + '/' );
+       uriList := TStringList.Create;
+       try
+               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+               // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
+               Result          :=
+                       uri.Protocol + '://' + uri.Host + '/bbs/write.cgi/' +
+                       uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/';
+
+       finally
+               uri.Free;
+               uriList.Free;
+       end;
+       }
+       Result := URL;
+end;
+
+// *************************************************************************
+// TThreadItem \82ª\90\90¬\82³\82ê\82½\8fê\8d\87\82Ì\8f\88\92u(TShitarabaThreadItem \82ð\90\90¬\82·\82é)
+// *************************************************************************
+procedure ThreadItemOnCreateOfTBe2chThreadItem(
+       inInstance : DWORD
+);
+var
+       threadItem : TBe2chThreadItem;
+begin
+
+       threadItem := TBe2chThreadItem.Create( inInstance );
+       ThreadItemSetLong( inInstance, tipContext, DWORD( threadItem ) );
+
+end;
+
+// *************************************************************************
+// TThreadItem \82ª\94j\8aü\82³\82ê\82½\8fê\8d\87\82Ì\8f\88\92u(TShitarabaThreadItem \82ð\94j\8aü\82·\82é)
+// *************************************************************************
+procedure ThreadItemOnDisposeOfTBe2chThreadItem(
+       inInstance : DWORD
+);
+var
+       threadItem : TBe2chThreadItem;
+begin
+
+       threadItem := TBe2chThreadItem( ThreadItemGetLong( inInstance, tipContext ) );
+       threadItem.Free;
+
+end;
+
+// =========================================================================
+// TShitarabaBoardItem
+// =========================================================================
+
+// *************************************************************************
+// \83R\83\93\83X\83g\83\89\83N\83^
+// *************************************************************************
+constructor TBe2chBoardItem.Create(
+       inInstance      : DWORD
+);
+var
+       uri                                     : TIdURI;
+       uriList                 : TStringList;
+const
+       BBS_HOST                = 'be.2ch.net';
+begin
+
+       inherited;
+
+       OnDownload                                              := Download;
+       OnCreateThread                          := CreateThread;
+       OnEnumThread                                    := EnumThread;
+       OnFileName2ThreadURL    := ToThreadURL;
+
+       FilePath                        := '';
+       FIsTemporary    := False;
+       FDat                                    := nil;
+       Is2ch := True;
+       uri                     := TIdURI.Create( SubjectURL );
+       uriList := TStringList.Create;
+       try
+               URL := uri.Protocol + '://' + uri.Host + uri.Path;
+
+               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+               // http://jbbs.livedoor.com/game/1000/subject.txt
+               FilePath        := MyLogFolder + uriList[ 1 ] + '\' + uri.Document;
+               IsLogFile       := FileExists( FilePath );
+       finally
+               uri.Free;
+               uriList.Free;
+       end;
+
+end;
+
+// *************************************************************************
+// \83f\83X\83g\83\89\83N\83^
+// *************************************************************************
+destructor TBe2chBoardItem.Destroy;
+begin
+
+       if FDat <> nil then begin
+               try
+                       FDat.Free;
+                       FDat := nil;
+               except
+               end;
+       end;
+
+       // \88ê\8e\9e\83t\83@\83C\83\8b\82Ì\8fê\8d\87\82Í\8dí\8f\9c\82·\82é
+       if FIsTemporary then
+               DeleteFile( FilePath );
+
+       inherited;
+
+end;
+
+// *************************************************************************
+// \8ew\92è\82µ\82½\83X\83\8c\88ê\97\97\82Ì\83_\83E\83\93\83\8d\81[\83h\82ð\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+function TBe2chBoardItem.Download : TDownloadState;
+var
+       modified                        : Double;
+       downResult              : PChar;
+       responseCode    : Longint;
+       uri                                             : TIdURI;
+       uriList                         : TStringList;
+       tmpText : String;
+begin
+
+       Result := dsError;
+
+       if FDat <> nil then begin
+               try
+                       FDat.Free;
+                       FDat := nil;
+               except
+               end;
+       end;
+       FDat            := TStringList.Create;
+       uri                     := TIdURI.Create( SubjectURL );
+       uriList := TStringList.Create;
+       // \93Æ\8e©\82É\83_\83E\83\93\83\8d\81[\83h\82â\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í
+       // InternalDownload \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+       modified                        := LastModified;
+       responseCode    := InternalDownload( PChar( uri.URI ), modified, downResult );
+       try
+               if responseCode = 200 then begin
+                       try
+                               // \83p\83X\82ð\8eZ\8fo
+                               if MyLogFolder = '' then begin
+                                       // \82Ç\82±\82É\95Û\91\82µ\82Ä\82¢\82¢\82Ì\82©\95ª\82©\82ç\82È\82¢\82Ì\82Å\88ê\8e\9e\83t\83@\83C\83\8b\82É\95Û\91
+                                       FilePath                        := TemporaryFile;
+                                       FIsTemporary    := True;
+                               end else begin
+                                       FilePath                        := MyLogFolder + CustomStringReplace(uri.Path, '/', '') + '\' + uri.Document;
+                                       FIsTemporary    := False
+                               end;
+
+                               // \95Û\91\97p\82Ì\83f\83B\83\8c\83N\83g\83\8a\82ð\8c@\82é
+                               ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
+
+                               // EUC \82ð Shift_JIS \82É
+                               tmpText := CustomStringReplace( string( downResult ), '¡÷¡®', ',');
+                               FDat.Text := EUCtoSJIS( tmpText );
+                               // \95Û\91
+                               FDat.SaveToFile( FilePath );
+
+                               IsLogFile                       := True;
+                               RoundDate                       := Now;
+                               LastModified    := modified;
+                               LastGetTime             := Now;
+                       finally
+                               uri.Free;
+                               uriList.Free;
+                       end;
+                       Result := dsComplete;
+               end;
+       finally
+               DisposeResultString( downResult );
+       end;
+
+end;
+
+// *************************************************************************
+// \83X\83\8c\97§\82Ä\82ð\8ew\8e¦\82³\82ê\82½
+// *************************************************************************
+function       TBe2chBoardItem.CreateThread(
+       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©
+var
+       postURL                         : string;
+       postData                        : string;
+       postResult              : PChar;
+       uri                                             : TIdURI;
+       uriList                         : TStringList;
+       responseCode    : Integer;
+begin
+
+       uri                     := TIdURI.Create( URL );
+       uriList := TStringList.Create;
+       try
+               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+
+               // http://jbbs.livedoor.com/bbs/write.cgi/game/1578/new/
+               // http://jbbs.livedoor.com/game/1000/subject.txt
+               postURL         :=
+                       uri.Protocol + '://' + uri.Host + '/bbs/write.cgi/' +
+                       uriList[ 1 ] + '/' + uriList[ 2 ] + '/new/';
+               postData        :=
+                       'SUBJECT='      + HttpEncode( SJIStoEUC( inSubject ) ) +
+                       '&NAME='                + HttpEncode( SJIStoEUC( inName ) ) +
+                       '&MAIL='                + HttpEncode( SJIStoEUC( inMail ) ) +
+                       '&MESSAGE='     + HttpEncode( SJIStoEUC( inMessage ) ) +
+                       '&BBS='                 + uriList[ 4 ] +
+                       '&DIR='                 + uriList[ 3 ] +
+                       '&TIME='                + IntToStr( DateTimeToUnix( Now ) ) +
+                       '&submit='      + HttpEncode( SJIStoEUC( '\90V\8bK\8f\91\82«\8d\9e\82Ý' ) );
+
+               // \93Æ\8e©\82É\92Ê\90M\82µ\82È\82¢\8fê\8d\87\82Í InternalPost \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+               responseCode := InternalPost( PChar( postURL ), PChar( postData ), PChar(URL), postResult );
+               try
+                       if (responseCode = 200) or
+                               ((responseCode = 302) and (Length( Trim( postResult ) ) = 0)) then begin
+                               Result := dsComplete
+                       end else begin
+                               Result := dsError;
+                               if Assigned( InternalPrint ) then
+                                       InternalPrint( postResult );
+                       end;
+               finally
+                       DisposeResultString( postResult );
+               end;
+       finally
+               uri.Free;
+               uriList.Free;
+       end;
+
+end;
+
+// *************************************************************************
+// \83X\83\8c\88ê\97\97\82Ì URL \82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\93±\82«\8fo\82·
+// *************************************************************************
+function TBe2chBoardItem.ToThreadURL(
+       inFileName      : string        // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
+) : string;                                                    // \83X\83\8c\83b\83h\82Ì URL
+var
+       threadURL               : string;
+       uri                                     : TIdURI;
+       uriList                 : TStringList;
+       found                           : Integer;
+begin
+
+       found := AnsiPos( '.', inFileName );
+       if found > 0 then
+               inFileName := Copy( inFileName, 1, found - 1 );
+
+       uri                     := TIdURI.Create( SubjectURL );
+       uriList := TStringList.Create;
+       try
+               try
+                       ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+                       {threadURL      := uri.Protocol + '://' + uri.Host + '/bbs/read.cgi/' +
+                               uriList[ 1 ] + '/' + uriList[ 2 ] + '/' + inFileName + '/l100';
+                       }
+                       threadURL       := uri.Protocol + '://' + uri.Host + '/test/read.cgi' +
+                                                       uri.Path + inFileName + '/l50';
+                       Result          := threadURL;
+               finally
+                       uri.Free;
+                       uriList.Free;
+               end;
+       except
+               Result := '';
+       end;
+
+end;
+
+// *************************************************************************
+// \82±\82Ì\94Â\82É\82¢\82­\82Â\82Ì\83X\83\8c\82ª\82 \82é\82©\97v\8b\81\82³\82ê\82½
+// *************************************************************************
+procedure      TBe2chBoardItem.EnumThread(
+       inCallBack      : TBoardItemEnumThreadCallBack
+);
+var
+       uri                                     : TIdURI;
+       uriList                 : TStringList;
+begin
+
+       try
+               if FDat = nil then begin
+                       FDat            := TStringList.Create;
+                       uri                     := TIdURI.Create( SubjectURL );
+                       uriList := TStringList.Create;
+                       try
+                               // \83p\83X\82ð\8eZ\8fo
+                               ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
+                               // http://jbbs.livedoor.com/game/1000/subject.txt
+                               FilePath        := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
+                               if FileExists( FilePath ) then
+                                       // \93Ç\82Ý\8d\9e\82Ý
+                                       FDat.LoadFromFile( FilePath );
+                       finally
+                               uri.Free;
+                               uriList.Free;
+                       end;
+               end;
+
+               // \93Æ\8e©\82É\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\8ds\82í\82È\82¢\8fê\8d\87\82Í EnumThread \82É\94C\82¹\82é\82±\82Æ\82ª\8fo\97\88\82é
+               inherited EnumThread( inCallBack, CustomStringReplace( FDat.Text, ',', '<>' ) );
+       except
+       end;
+
+end;
+
+// *************************************************************************
+// \83X\83\8c\88ê\97\97\82Ì URL \82ð\8b\81\82ß\82é
+// *************************************************************************
+function       TBe2chBoardItem.SubjectURL : string;
+begin
+       if AnsiPos(SUBJECT_NAME, URL) > 0 then
+               Result := URL
+       else
+               Result := URL + SUBJECT_NAME;
+end;
+
+// *************************************************************************
+// TBoardItem \82ª\90\90¬\82³\82ê\82½\8fê\8d\87\82Ì\8f\88\92u(TShitarabaBoardItem \82ð\90\90¬\82·\82é)
+// *************************************************************************
+procedure BoardItemOnCreateOfTBe2chBoardItem(
+       inInstance : DWORD
+);
+var
+       boardItem : TBe2chBoardItem;
+begin
+
+       boardItem := TBe2chBoardItem.Create( inInstance );
+       BoardItemSetLong( inInstance, bipContext, DWORD( boardItem ) );
+
+end;
+
+// *************************************************************************
+// TBoardItem \82ª\94j\8aü\82³\82ê\82½\8fê\8d\87\82Ì\8f\88\92u(TShitarabaBoardItem \82ð\94j\8aü\82·\82é)
+// *************************************************************************
+procedure BoardItemOnDisposeOfTBe2chBoardItem(
+       inInstance : DWORD
+);
+var
+       boardItem : TBe2chBoardItem;
+begin
+
+       boardItem := TBe2chBoardItem( BoardItemGetLong( inInstance, bipContext ) );
+       boardItem.Free;
+
+end;
+
+
+
+// =========================================================================
+// \83G\83\93\83g\83\8a\83|\83C\83\93\83g
+// =========================================================================
+procedure DLLEntry(
+       ul_reason_for_call : DWORD
+);
+var
+       module : HMODULE;
+begin
+
+       case ul_reason_for_call of
+               DLL_PROCESS_ATTACH:
+               begin
+                       Randomize;
+
+                       module := GetModuleHandle( nil );
+
+                       LoadInternalAPI( module );
+                       LoadInternalFilePathAPI( module );
+                       LoadInternalThreadItemAPI( module );
+                       LoadInternalBoardItemAPI( module );
+
+                       // ===== \83C\83\93\83X\83^\83\93\83X\82Ì\8eæ\82è\88µ\82¢\82ð TThreadItem \82©\82ç TShitarabaThreadItem \82É\95Ï\8dX\82·\82é
+                       ThreadItemOnCreate      := ThreadItemOnCreateOfTBe2chThreadItem;
+                       ThreadItemOnDispose     := ThreadItemOnDisposeOfTBe2chThreadItem;
+                       // ===== \83C\83\93\83X\83^\83\93\83X\82Ì\8eæ\82è\88µ\82¢\82ð TBoardItem \82©\82ç TShitarabaBoardItem \82É\95Ï\8dX\82·\82é
+                       BoardItemOnCreate               := BoardItemOnCreateOfTBe2chBoardItem;
+                       BoardItemOnDispose      := BoardItemOnDisposeOfTBe2chBoardItem;
+               end;
+               DLL_THREAD_ATTACH:
+                       ;
+               DLL_THREAD_DETACH:
+                       ;
+       end;
+
+end;
+
+exports
+       OnVersionInfo,
+       OnAcceptURL,
+       OnExtractBoardURL;
+begin
+
+       try
+               DllProc := @DLLEntry;
+               DLLEntry( DLL_PROCESS_ATTACH );
+       except end;
+
+end.
diff --git a/res/ExternalBoardPlugIn/Be2chPlugIn.res b/res/ExternalBoardPlugIn/Be2chPlugIn.res
new file mode 100644 (file)
index 0000000..85add3c
Binary files /dev/null and b/res/ExternalBoardPlugIn/Be2chPlugIn.res differ