OSDN Git Service

タスクトレイの右クリックで終了メニューを出すようにした。
[gikonavigoeson/gikonavi.git] / GikoSystem.pas
index f4ad5b4..3a7fcac 100644 (file)
@@ -112,6 +112,10 @@ type
                FBayesian       : TGikoBayesian;        //!< \83x\83C\83W\83A\83\93\83t\83B\83\8b\83^
                FVersion : String;                    //!< \83t\83@\83C\83\8b\83o\81[\83W\83\87\83\93
                FGikoMessage: TGikoMessage;
+               //! \82 \82é\83Z\83p\83\8c\81[\83^\82Å\8bæ\90Ø\82ç\82ê\82½\95\8e\9a\97ñ\82©\82ç\82\8e\94Ô\96Ú\82Ì\95\8e\9a\97ñ\82ð\8eæ\82è\8fo\82·
+               function ChooseString(const Text, Separator: string; Index: integer): string;
+        //! \88ê\8e\9e\83t\83@\83C\83\8b\82©\82ç\82Ì\95\9c\8b\8c
+        procedure RestoreThreadData(Board: TBoard);
        public
                { Public \90é\8c¾ }
                FAbon : TAbon;
@@ -123,13 +127,10 @@ type
                property ResRange : Longint read FResRange write FResRange;
                //! \83o\81[\83W\83\87\83\93\8fî\95ñ
                property Version : String read FVersion;
-//             function MsgBox(Msg: string; Title: string; Flags: Longint): integer; overload;
-//             function MsgBox(Handle: THandle; Msg: string; Title: string; Flags: Longint): integer; overload;
                function IsNumeric(s: string): boolean;
                function IsFloat(s: string): boolean;
                function DirectoryExistsEx(const Name: string): Boolean;
                function ForceDirectoriesEx(Dir: string): Boolean;
-//             function GetVersion: string;
 
                function GetBoardFileName: string;
                function GetCustomBoardFileName: string;
@@ -211,17 +212,14 @@ type
 
                procedure GetPopupResNumber(URL : string; var stRes, endRes : Int64);
 
-               //! Samba24\82Ì\83t\83@\83C\83\8b\82ª\91\8dÝ\82·\82é\82©\81B\91\8dÝ\82µ\82È\82¢\8fê\8d\87\81Adefault\83t\83@\83C\83\8b\82ðrename\82·\82é
-               procedure SambaFileExists();
-
                property Bayesian : TGikoBayesian read FBayesian write FBayesian;
-               function GetSameIDResAnchor(const AID : string; ThreadItem: TThreadItem; limited: boolean):string; overload;
-               function GetSameIDResAnchor(AIDNum : Integer; ThreadItem: TThreadItem; limited: boolean):string; overload;
+               function GetSameIDResAnchor(const AID : string; ThreadItem: TThreadItem; limited: Integer):string; overload;
+               function GetSameIDResAnchor(AIDNum : Integer; ThreadItem: TThreadItem; limited: Integer):string; overload;
                procedure GetSameIDRes(const AID : string; ThreadItem: TThreadItem;var body: TStringList); overload;
                procedure GetSameIDRes(AIDNum : Integer; ThreadItem: TThreadItem;var body: TStringList); overload;
                function GetSameIDResCount(const AID : string; ThreadItem: TThreadItem):Integer; overload;
                function GetSameIDResCount(AIDNum : Integer; ThreadItem: TThreadItem):Integer; overload;
-
+        function GetResID(AIDNum: Integer; ThreadItem: TThreadItem): String;
                //! \92P\8cê\89ð\90Í
                procedure SpamCountWord( const text : string; wordCount : TWordCount );
                //! \8aw\8fK\83N\83\8a\83A
@@ -246,6 +244,21 @@ type
                procedure SetGikoMessage;
                //! \83M\83R\83i\83r\82Ì\83\81\83b\83Z\81[\83W\82ð\8eæ\93¾\82·\82é
                function GetGikoMessage(MesType: TGikoMessageListType): String;
+               //! GMT\82Ì\8e\9e\8d\8f\82ðTDateTime\82É\95Ï\8a·\82·\82é
+               function  DateStrToDateTime(const DateStr: string): TDateTime;
+        //! User32.dll\82ª\97\98\97p\82Å\82«\82é\82©
+        function CanUser32DLL: Boolean;
+        //! OE\88ø\97p\95\84\8eæ\93¾
+        function GetOEIndentChar : string;
+        //! \92u\8a·\90Ý\92è\83t\83@\83C\83\8b\8eæ\93¾
+        function GetReplaceFileName: String;
+        //! \83C\83\93\83f\83b\83N\83X\82É\82È\82¢dat\81i\82Í\82®\82êdat\81j\82Ì\92Ç\89Á
+        procedure AddOutofIndexDat(Board: TBoard; DatList: TStringList; AllCreate: boolean = True);
+        //! \83t\83@\83C\83\8b\96¼\82©\82ç\82Ì\83X\83\8c\83b\83h\8dì\90¬\93ú\82Ì\8eæ\93¾
+        function GetCreateDateFromName(FileName: String): TDateTime;
+        function GetExtpreviewFileName: String;
+
+        procedure ShowRefCount(msg: String; unk: IUnknown);
        end;
 
 var
@@ -255,7 +268,7 @@ const
        ZERO_DATE: Integer      = 25569;
        BETA_VERSION_NAME_E = 'beta';
        BETA_VERSION_NAME_J = 'ÊÞÀ';
-       BETA_VERSION                            = 53;
+       BETA_VERSION                            = 58;
        BETA_VERSION_BUILD      = '';                           //!< debug\94Å\82È\82Ç
        APP_NAME                                                = 'gikoNavi';
        BE_PHP_URL = 'http://be.2ch.net/test/p.php?i=';
@@ -265,7 +278,7 @@ implementation
 
 uses
        Giko, RoundData, Favorite, Registry, HTMLCreate, MojuUtils, Sort, YofUtils,
-       IniFiles;
+       IniFiles, DateUtils, SkinFiles;
 
 const
        FOLDER_INDEX_VERSION                                    = '1.01';
@@ -274,6 +287,7 @@ const
        NGWORDs_DIR_NAME : String               = 'NGwords';
 
        READ_PATH: string =                     '/test/read.cgi/';
+    HTML_READ_PATH: string =        '/test/read.html/';
        OLD_READ_PATH: string =         '/test/read.cgi?';
        KAKO_PATH: string =                     '/kako/';
 
@@ -296,6 +310,7 @@ const
 // *************************************************************************
 constructor TGikoSys.Create;
 begin
+    Inherited;
        FSetting := TSetting.Create;
        FDolib := TDolib.Create;
        FAWKStr := TAWKStr.Create(nil);
@@ -334,18 +349,6 @@ var
        i: Integer;
        FileList: TStringList;
 begin
-       //\83X\83\8c\83b\83h\83f\81[\83^\83t\83@\83C\83\8b\82ð\8dX\90V
-//     FlashExitWrite;
-
-//     FExitWrite.Free;
-       FBayesian.Free;
-       FAWKStr.Free;
-       FSetting.Free;
-       FDolib.Free;
-       FAbon.Free;
-       FSelectResFilter.Free;
-    FGikoMessage.Free;
-       //FBoardURLList.Free;
        //\83e\83\93\83|\83\89\83\8aHTML\82ð\8dí\8f\9c
        FileList := TStringList.Create;
        try
@@ -358,6 +361,13 @@ begin
        finally
                FileList.Free;
        end;
+    FreeAndNil(FGikoMessage);
+       FreeAndNil(FBayesian);
+       FreeAndNil(FSelectResFilter);
+       FreeAndNil(FAbon);
+       FreeAndNil(FAWKStr);
+       FreeAndNil(FDolib);
+       FreeAndNil(FSetting);
        inherited;
 end;
 
@@ -365,7 +375,6 @@ end;
 \brief \95\8e\9a\97ñ\90\94\8e\9a\83`\83F\83b\83N
 \param s \83`\83F\83b\83N\82·\82é\95\8e\9a\97ñ
 \return s \82ª\95\84\8d\86\95t\82«\90®\90\94\82Æ\82µ\82Ä\94F\8e¯\89Â\94\\82È\82ç True
-\todo MonaUtils.IsNumeric() \82ª\93¯\93\99\82Ì\8b@\94\\82ð\95Û\8e\9d\82µ\82Ä\82¢\82é
 }
 {$HINTS OFF}
 function TGikoSys.IsNumeric(s: string): boolean;
@@ -382,7 +391,6 @@ end;
 \brief \95\8e\9a\97ñ\95\82\93®\8f¬\90\94\93_\90\94\8e\9a\83`\83F\83b\83N
 \param s \83`\83F\83b\83N\82·\82é\95\8e\9a\97ñ
 \return s \82ª\95\84\8d\86\95t\82«\95\82\93®\8f¬\90\94\82Æ\82µ\82Ä\94F\8e¯\89Â\94\\82È\82ç True
-\todo MonaUtils.IsFloat() \82ª\93¯\93\99\82Ì\8b@\94\\82ð\95Û\8e\9d\82µ\82Ä\82¢\82é
 }
 function TGikoSys.IsFloat(s: string): boolean;
 var
@@ -471,37 +479,37 @@ end;
 //! Skin:\83w\83b\83_\82Ì\83t\83@\83C\83\8b\96¼
 function TGikoSys.GetSkinHeaderFileName: string;
 begin
-       Result := Setting.GetSkinHeaderFileName;
+       Result := Setting.SkinFiles.GetSkinHeaderFileName;
 end;
 
 //! Skin:\83t\83b\83^\82Ì\83t\83@\83C\83\8b\96¼
 function TGikoSys.GetSkinFooterFileName: string;
 begin
-       Result := Setting.GetSkinFooterFileName;
+       Result := Setting.SkinFiles.GetSkinFooterFileName;
 end;
 
 //! Skin:\90V\92\85\83\8c\83X\82Ì\83t\83@\83C\83\8b\96¼
 function TGikoSys.GetSkinNewResFileName: string;
 begin
-       Result := Setting.GetSkinNewResFileName;
+       Result := Setting.SkinFiles.GetSkinNewResFileName;
 end;
 
 //! Skin:\94ñ\90V\92\85\83\8c\83X\82Ì\83t\83@\83C\83\8b\96¼
 function TGikoSys.GetSkinResFileName: string;
 begin
-       Result := Setting.GetSkinResFileName;
+       Result := Setting.SkinFiles.GetSkinResFileName;
 end;
 
 //! Skin:\82µ\82¨\82è(\82±\82±\82Ü\82Å\93Ç\82ñ\82¾)\82Ì\83t\83@\83C\83\8b\96¼
 function TGikoSys.GetSkinBookmarkFileName: string;
 begin
-       Result := Setting.GetSkinBookmarkFileName;
+       Result := Setting.SkinFiles.GetSkinBookmarkFileName;
 end;
 
 //! Skin:\82µ\82¨\82è(\90V\92\85\83\8c\83X)\82Ì\83t\83@\83C\83\8b\96¼
 function TGikoSys.GetSkinNewmarkFileName: string;
 begin
-       Result := Setting.GetSkinNewmarkFileName;
+       Result := Setting.SkinFiles.GetSkinNewmarkFileName;
 end;
 
 //! UserAgent\8eæ\93¾
@@ -555,65 +563,67 @@ var
        ThreadItem: TThreadItem;
        FileName: string;
        FileList: TStringList;
-       TmpFileList: TStringList;
        Index: Integer;
        sl: TStringList;
        i: Integer;
        Rec: TIndexRec;
        UnRead: Integer;
-       ini: TMemIniFile;
-       ResRec: TResRec;
-//     RoundItem: TRoundItem;
-//     idx: Integer;
        usePlugIn : Boolean;
-       tmpStr: string;
-       BoardPath : String;
-       server : String;
        islog : Boolean;
-       //protocol, host, path, document, port, bookmark        : string;
-       //is2ch : Boolean;
+    urlHead: String;
+    datFileCheck: Boolean;
        {*
        FavoThreadItem : TFavoriteThreadItem;
        Node: TTreeNode;
        *}
+{$IFDEF DEBUG}
+    st, rt: Cardinal;
+{$ENDIF}
 begin
+{$IFDEF DEBUG}
+       st := GetTickCount;
+{$ENDIF}
        if Board.IsThreadDatRead then
                Exit;
        Board.Clear;
        UnRead := 0;
-       //is2ch := false;
        usePlugIn := Board.IsBoardPlugInAvailable;
-       server :=  UrlToServer( Board.URL );
-       //is2ch := Is2chHost(server);
+       //server :=  UrlToServer( Board.URL );
+    // \83X\83\8c\83b\83h\82Å\8b¤\92Ê\82ÌURL\95\94
+    if Board.is2ch then begin
+        urlHead := UrlToServer( Board.URL ) + 'test/read.cgi/' + Board.BBSID + '/';
+    end else begin
+        urlHead := UrlToServer( Board.URL ) + 'test/read.cgi?bbs=' + Board.BBSID + '&key=';
+    end;
 
        FileName := Board.GetFolderIndexFileName;
 
-       FileList := TStringList.Create;
-       FileList.Sorted := True;
-       FileList.BeginUpdate;
-       TmpFileList := TStringList.Create;
-       TmpFileList.Sorted := True;
-       TmpFileList.BeginUpdate;
-       //IsLogFile\97pDAT\83t\83@\83C\83\8b\83\8a\83X\83g
-       GetFileList(ExtractFileDir(Board.GetFolderIndexFileName), '*.dat', FileList, False);
-       FileList.EndUpdate;
-       //\91O\89ñ\88Ù\8fí\8fI\97¹\8e\9e\97pTmp\83t\83@\83C\83\8b\83\8a\83X\83g
-       GetFileList(ExtractFileDir(Board.GetFolderIndexFileName), '*.tmp', TmpFileList, False);
-       TmpFileList.EndUpdate;
+    //
+    datFileCheck := (Setting.CheckDatFile) or (not FileExists(FileName));
+    if (datFileCheck) then begin
+        FileList := TStringList.Create;
+        FileList.Sorted := True;
+        FileList.BeginUpdate;
+        //IsLogFile\97pDAT\83t\83@\83C\83\8b\83\8a\83X\83g
+        GetFileList(ExtractFileDir(Board.GetFolderIndexFileName), '*.dat', FileList, False);
+        FileList.EndUpdate;
+    end;
 
        // \8fd\95¡\82ð\96h\82®
        Board.BeginUpdate;
        Board.Sorted := True;
-
        sl := TStringList.Create;
        try
                if FileExists(FileName) then begin
                        sl.LoadFromFile(FileName);
-
                        //\82Q\8ds\96Ú\82©\82ç\81i\82P\8ds\96Ú\82Í\83o\81[\83W\83\87\83\93\81j
                        for i := sl.Count - 1 downto 1 do begin
                                Rec := ParseIndexLine(sl[i]);
-                               islog := FileList.Find( Rec.FFileName, Index );
+                if (datFileCheck) then begin
+                               islog := FileList.Find( Rec.FFileName, Index );
+                end else begin
+                    islog := (Rec.FSize <> 0) and (Rec.FCount <> 0);
+                end;
                                if usePlugIn then
                                        ThreadItem := TThreadItem.Create(
                                                        Board.BoardPlugIn,
@@ -624,7 +634,7 @@ begin
                                                ThreadItem := TThreadItem.Create(
                                                        nil,
                                                        Board,
-                                                       server + 'test/read.cgi/' + Board.BBSID + '/' + ChangeFileExt( Rec.FFileName, '' ) + '/l50',
+                                                       urlHead + ChangeFileExt( Rec.FFileName, '' ) + '/l50',
                                                        islog,
                                                        Rec.FFileName
                                                        );
@@ -632,7 +642,7 @@ begin
                                                ThreadItem := TThreadItem.Create(
                                                        nil,
                                                        Board,
-                                                       server + 'test/read.cgi?bbs=' + Board.BBSID + '&key=' + ChangeFileExt( Rec.FFileName, '' ) + '&ls=50',
+                                                       urlHead + ChangeFileExt( Rec.FFileName, '' ) + '&ls=50',
                                                        islog,
                                                        Rec.FFileName
                                                        );
@@ -640,13 +650,12 @@ begin
                                end;
 
                                ThreadItem.BeginUpdate;
-                               if islog then
+                               if (datFileCheck) and (islog) then
                                        FileList.Delete( Index );
 
                                ThreadItem.No := Rec.FNo;
                                ThreadItem.FileName := Rec.FFileName;
-                               ThreadItem.Title := Rec.FTitle;
-                               //ThreadItem.ShortTitle := CustomStringReplace(ZenToHan(ThreadItem.Title), ' ', '');
+                               ThreadItem.Title := MojuUtils.UnSanitize(Rec.FTitle);
                                ThreadItem.Count := Rec.FCount;
                                ThreadItem.Size := Rec.FSize;
                                ThreadItem.RoundDate := Rec.FRoundDate;
@@ -668,7 +677,7 @@ begin
                                ThreadItem.EndUpdate;
                                Board.Add(ThreadItem);
 
-                               if (ThreadItem.IsLogFile) and (ThreadItem.UnRead) then
+                               if (ThreadItem.UnRead) and (ThreadItem.IsLogFile) then
                                        Inc(UnRead);
                        end;
                end;
@@ -676,98 +685,101 @@ begin
                if UnRead <> Board.UnRead then
                        Board.UnRead := UnRead;
 
-               Boardpath := ExtractFilePath(Board.GetFolderIndexFileName);
-               //\83C\83\93\83f\83b\83N\83X\82É\96³\82©\82Á\82½\83\8d\83O\82ð\92Ç\89Á\81i\95\85\82ê\83C\83\93\83f\83b\83N\83X\91Î\89\9e\81j
-               for i := 0 to FileList.Count - 1 do begin
-                       FileName := Boardpath + FileList[i];
-
-                       //ResRec := DivideStrLine(ReadThreadFile(FileName, 1));
-                       if usePlugIn then begin
-                               ThreadItem := TThreadItem.Create(
-                                       Board.BoardPlugIn,
-                                       Board,
-                                       Board.BoardPlugIn.FileName2ThreadURL( DWORD( Board ), FileList[i] ) );
-                               THTMLCreate.DivideStrLine(Board.BoardPlugIn.GetDat( DWORD( ThreadItem ), 1 ), @ResRec);
-                       end else begin
-                               ThreadItem := TThreadItem.Create(
-                                       nil,
-                                       Board,
-                                       Get2chBoard2ThreadURL( Board, ChangeFileExt( FileList[i], '' ) ) );
-                               THTMLCreate.DivideStrLine(ReadThreadFile(FileName, 1), @ResRec);
-                       end;
-
-                       ThreadItem.BeginUpdate;
-                       ThreadItem.FileName := FileList[i];
-                       //ThreadItem.FilePath := FileName;
-                       ThreadItem.No := Board.Count + 1;
-                       ThreadItem.Title := ResRec.FTitle;
-                       ThreadItem.Count := GetFileLineCount(FileName);
-                       ThreadItem.AllResCount := ThreadItem.Count;
-                       ThreadItem.NewResCount := ThreadItem.Count;
-                       ThreadItem.Size := GetFileSize(FileName) - ThreadItem.Count;//1byte\82¸\82ê\82é\82Æ\82«\82ª\82 \82é\82¯\82Ç\82»\82ê\82Í\82 \82«\82ç\82ß\82é
-                       ThreadItem.RoundDate := FileDateToDateTime( FileAge( FileName ) );
-                       ThreadItem.LastModified := ThreadItem.RoundDate;
-                       ThreadItem.Kokomade := -1;
-                       ThreadItem.NewReceive := 0;
-                       ThreadItem.ParentBoard := Board;
-                       ThreadItem.IsLogFile := True;
-                       ThreadItem.Round := False;
-                       ThreadItem.UnRead := False;
-                       ThreadItem.ScrollTop := 0;
-                       ThreadItem.AgeSage := gasNone;
-                       ThreadItem.EndUpdate;
-                       Board.Add(ThreadItem);
-               end;
+        if (datFileCheck) then begin
+                   //\83C\83\93\83f\83b\83N\83X\82É\96³\82©\82Á\82½\83\8d\83O\82ð\92Ç\89Á\81i\95\85\82ê\83C\83\93\83f\83b\83N\83X\91Î\89\9e\81j
+            AddOutofIndexDat(Board, FileList);
+        end;
                Board.EndUpdate;
 
-               //\91O\89ñ\88Ù\8fí\8fI\97¹\8e\9e\83`\83F\83b\83N
-               for i := TmpFileList.Count - 1 downto 0 do begin
-               //if TmpFileList.Count <> 0 then begin
-                       ThreadItem := Board.FindThreadFromFileName(ChangeFileExt(TmpFileList[i], '.dat'));
-                       if ThreadItem <> nil then begin
-                       //if TmpFileList.Find(ChangeFileExt(ThreadItem.FileName, '.tmp'), Index) then begin
-                               ini := TMemIniFile.Create(Boardpath + TmpFileList[i]);
-                               try
-                                       tmpStr := ini.ReadString('Setting', 'RoundDate', DateTimeToStr(ZERO_DATE));
-                                       ThreadItem.RoundDate := ConvertDateTimeString(tmpStr);
-
-                                       tmpStr := ini.ReadString('Setting', 'LastModified', DateTimeToStr(ZERO_DATE));
-                                       ThreadItem.LastModified := ConvertDateTimeString(tmpStr);
-                                       ThreadItem.Count := ini.ReadInteger('Setting', 'Count', 0);
-                                       ThreadItem.NewReceive := ini.ReadInteger('Setting', 'NewReceive', 0);
-
-                                       ThreadItem.Size := ini.ReadInteger('Setting', 'Size', 0);
-                                       if(ThreadItem.Size = 0) and (FileExists(ThreadItem.GetThreadFileName)) then begin
-                                               try
-                                                       ThreadItem.Size := GetFileSize(ThreadItem.GetThreadFileName) - ThreadItem.Count;
-                                               except
-                                               end;
-                                       end;
-
-                    //\8f\84\89ñ\82Ì\90Ý\92è\82ÍRoundData\82Ì\95û\82ª\82â\82é\82©\82ç\8f\9f\8eè\82É\90Ý\92è\82µ\82Ä\82Í\83_\83\81\81I\81@by \82à\82\82ã
-                                       //ThreadItem.Round := ini.ReadBool('Setting', 'Round', False);
-                                       //ThreadItem.RoundName := ini.ReadString('Setting', 'RoundName', ThreadItem.RoundName);
-                                       ThreadItem.UnRead := False;//ini.ReadBool('Setting', 'UnRead', False);
-                                       ThreadItem.ScrollTop := ini.ReadInteger('Setting', 'ScrollTop', 0);
-                                       ThreadItem.AllResCount := ini.ReadInteger('Setting', 'AllResCount', ThreadItem.Count);
-                                       ThreadItem.NewResCount := ini.ReadInteger('Setting', 'NewResCount', 0);
-                                       ThreadItem.AgeSage := TGikoAgeSage(ini.ReadInteger('Setting', 'AgeSage', Ord(gasNone)));
-                               finally
-                                       ini.Free;
-                               end;
-                               DeleteFile(Boardpath + TmpFileList[i]);
-                       end;
-               end;
-
+        //\91O\89ñ\88Ù\8fí\8fI\97¹\8e\9e\83`\83F\83b\83N
+        RestoreThreadData( Board );
        finally
                sl.Free;
-               FileList.Free;
-               TmpFileList.Free;
+        if (datFileCheck) then begin
+               FileList.Free;
+        end;
                Board.Sorted := False;
        end;
        Board.IsThreadDatRead := True;
+{$IFDEF DEBUG}
+       rt := GetTickCount - st;
+       Writeln('Read Done.' + IntToStr(rt) + ' ms');
+{$ENDIF}
+end;
+{!
+\brief \83C\83\93\83f\83b\83N\83X\82É\82È\82¢dat\81i\82Í\82®\82êdat\81j\82Ì\92Ç\89Á
+\param Board \92Ç\89Á\82·\82é\94Â
+\param DatList  dat\83t\83@\83C\83\8b\96¼
+}
+procedure TGikoSys.AddOutofIndexDat(Board: TBoard; DatList: TStringList; AllCreate: Boolean = True);
+var
+    i : Integer;
+    Boardpath,FileName : String;
+    ResRec: TResRec;
+    ThreadItem: TThreadItem;
+    create: Boolean;
+begin
+    create := False;
+    Boardpath := ExtractFilePath(Board.GetFolderIndexFileName);
+    //\83C\83\93\83f\83b\83N\83X\82É\96³\82©\82Á\82½\83\8d\83O\82ð\92Ç\89Á\81i\95\85\82ê\83C\83\93\83f\83b\83N\83X\91Î\89\9e\81j
+    for i := 0 to DatList.Count - 1 do begin
+        FileName := Boardpath + DatList[i];
+        ThreadItem := nil;
+        if (not AllCreate) then begin
+            create := False;
+            ThreadItem := Board.FindThreadFromFileName(DatList[i]);
+            if (ThreadItem = nil) then begin
+                create := True;
+            end else begin
+                if Board.IsBoardPlugInAvailable then begin
+                    THTMLCreate.DivideStrLine(Board.BoardPlugIn.GetDat( DWORD( ThreadItem ), 1 ), @ResRec);
+                end else begin
+                    THTMLCreate.DivideStrLine(ReadThreadFile(FileName, 1), @ResRec);
+                end;
+            end;
+        end;
+        if (ThreadItem = nil) then begin
+            if Board.IsBoardPlugInAvailable then begin
+                ThreadItem := TThreadItem.Create(
+                    Board.BoardPlugIn,
+                    Board,
+                    Board.BoardPlugIn.FileName2ThreadURL( DWORD( Board ), DatList[i] ) );
+                THTMLCreate.DivideStrLine(Board.BoardPlugIn.GetDat( DWORD( ThreadItem ), 1 ), @ResRec);
+            end else begin
+                ThreadItem := TThreadItem.Create(
+                    nil,
+                    Board,
+                    Get2chBoard2ThreadURL( Board, ChangeFileExt( DatList[i], '' ) ) );
+                THTMLCreate.DivideStrLine(ReadThreadFile(FileName, 1), @ResRec);
+            end;
+        end;
+        
+
+        ThreadItem.BeginUpdate;
+        ThreadItem.FileName := DatList[i];
+        //ThreadItem.FilePath := FileName;
+        ThreadItem.No := Board.Count + 1;
+        ThreadItem.Title := ResRec.FTitle;
+        ThreadItem.Count := GetFileLineCount(FileName);
+        ThreadItem.AllResCount := ThreadItem.Count;
+        ThreadItem.NewResCount := ThreadItem.Count;
+        ThreadItem.Size := GetFileSize(FileName) - ThreadItem.Count;//1byte\82¸\82ê\82é\82Æ\82«\82ª\82 \82é\82¯\82Ç\82»\82ê\82Í\82 \82«\82ç\82ß\82é
+        ThreadItem.RoundDate := FileDateToDateTime( FileAge( FileName ) );
+        ThreadItem.LastModified := ThreadItem.RoundDate;
+        ThreadItem.Kokomade := -1;
+        ThreadItem.NewReceive := 0;
+        ThreadItem.ParentBoard := Board;
+        ThreadItem.IsLogFile := True;
+        ThreadItem.Round := False;
+        ThreadItem.UnRead := False;
+        ThreadItem.ScrollTop := 0;
+        ThreadItem.AgeSage := gasNone;
+        ThreadItem.EndUpdate;
+        if (AllCreate) or (create) then begin
+            Board.Add(ThreadItem);
+        end;
+    end;
 end;
-
 {!
 \brief \83X\83\8c\83b\83h\83C\83\93\83f\83b\83N\83X\83t\83@\83C\83\8b(Folder.idx)\8dì\90¬
 \param Board Folder.idx \82ð\8dì\90¬\82·\82é\94Â
@@ -819,7 +831,7 @@ begin
                                                        '%s'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x',
                                        [cnt,                   //\94Ô\8d\86
                                         Rec.FFileName, //\83t\83@\83C\83\8b\96¼
-                                        Rec.FTitle,    //\83^\83C\83g\83\8b
+                                        MojuUtils.Sanitize(Rec.FTitle),    //\83^\83C\83g\83\8b
                                         Rec.FCount,     //\83J\83E\83\93\83g
                                         0,             //size
                                         0,             //RoundDate
@@ -889,7 +901,7 @@ begin
                                                        '%s'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x',
                                        [Board.Items[i].No,                     //\94Ô\8d\86
                                         Board.Items[i].FileName, //\83t\83@\83C\83\8b\96¼
-                                        Board.Items[i].Title,    //\83^\83C\83g\83\8b
+                     MojuUtils.Sanitize(Board.Items[i].Title),    //\83^\83C\83g\83\8b
                                         Board.Items[i].Count,     //\83J\83E\83\93\83g
                                         Board.Items[i].Size,             //size
                                         DateTimeToInt(Board.Items[i].RoundDate),             //RoundDate
@@ -926,21 +938,21 @@ end;
 }
 function TGikoSys.ParseIndexLine(Line: string): TIndexRec;
 begin
-       Result.FNo := StrToIntDef('$' + RemoveToken(Line, #1), 0);
-       Result.FFileName := RemoveToken(Line, #1);
-       Result.FTitle := RemoveToken(Line, #1);
-       Result.FCount := StrToIntDef('$' + RemoveToken(Line, #1), 0);
-       Result.FSize := StrToIntDef('$' + RemoveToken(Line, #1), 0);
-       Result.FRoundDate := IntToDateTime(StrToIntDef('$' + RemoveToken(Line, #1), ZERO_DATE));
-       Result.FLastModified := IntToDateTime(StrToIntDef('$' + RemoveToken(Line, #1), ZERO_DATE));
-       Result.FKokomade := StrToIntDef('$' + RemoveToken(Line, #1), -1);
-       Result.FNewReceive := StrToIntDef('$' + RemoveToken(Line, #1), 0);
+       Result.FNo := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
+       Result.FFileName := MojuUtils.RemoveToken(Line, #1);
+       Result.FTitle := MojuUtils.UnSanitize(MojuUtils.RemoveToken(Line, #1));
+       Result.FCount := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
+       Result.FSize := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
+       Result.FRoundDate := IntToDateTime(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), ZERO_DATE));
+       Result.FLastModified := IntToDateTime(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), ZERO_DATE));
+       Result.FKokomade := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), -1);
+       Result.FNewReceive := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
        RemoveToken(Line, #1);//9: ;    //\96¢\8eg\97p
-       Result.FUnRead := IntToBool(StrToIntDef('$' + RemoveToken(Line, #1), 0));
-       Result.FScrollTop := StrToIntDef('$' + RemoveToken(Line, #1), 0);
-       Result.FAllResCount := StrToIntDef('$' + RemoveToken(Line, #1), 0);
-       Result.FNewResCount := StrToIntDef('$' + RemoveToken(Line, #1), 0);
-       Result.FAgeSage := TGikoAgeSage(StrToIntDef('$' + RemoveToken(Line, #1), 0));
+       Result.FUnRead := IntToBool(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0));
+       Result.FScrollTop := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
+       Result.FAllResCount := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
+       Result.FNewResCount := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
+       Result.FAgeSage := TGikoAgeSage(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0));
 
 end;
 
@@ -965,18 +977,13 @@ var
        rc: Integer;
        SearchRec : TSearchRec;
        s: string;
-       maskExt: string;
 begin
-       //maskExt := Copy(Mask, 1, Length(Mask) - 1);
-               maskExt := Mask;
        Path := IncludeTrailingPathDelimiter(Path);
        rc := FindFirst(Path + '*.*', faAnyfile, SearchRec);
        try
                while rc = 0 do begin
                        if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
                                s := Path + SearchRec.Name;
-                               //if (SearchRec.Attr and faDirectory > 0) then
-                               //      s := IncludeTrailingPathDelimiter(s)
 
                                if (SearchRec.Attr and faDirectory = 0) and (MatchesMask(s, Mask)) then
                                                if IsPathAdd then
@@ -1011,20 +1018,19 @@ procedure TGikoSys.GetFileList(Path: string; Mask: string; var List: TStringList
 var
        rc: Integer;
        SearchRec : TSearchRec;
-       s: string;
 begin
        Path := IncludeTrailingPathDelimiter(Path);
        rc := FindFirst(Path + Mask, faAnyfile, SearchRec);
        try
                while rc = 0 do begin
                        if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
-                               s := Path + SearchRec.Name;
-
-                               if (SearchRec.Attr and faDirectory = 0) then
-                                               if IsPathAdd then
-                                                       List.Add(s)
-                                               else
-                                                       List.Add(SearchRec.Name);
+                               if (SearchRec.Attr and faDirectory = 0) then begin
+                    if IsPathAdd then begin
+                        List.Add(Path + SearchRec.Name)
+                    end else begin
+                        List.Add(SearchRec.Name);
+                    end;
+                end;
                        end;
                        rc := FindNext(SearchRec);
                end;
@@ -1184,10 +1190,10 @@ end;
 }
 function TGikoSys.DirectoryExistsEx(const Name: string): Boolean;
 var
-       Code: Integer;
+       Code: Cardinal;
 begin
        Code := GetFileAttributes(PChar(Name));
-       Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
+       Result := (Code <> Cardinal(-1)) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
 end;
 
 {!
@@ -1342,17 +1348,15 @@ var
        nm: NONCLIENTMETRICS;
 begin
        nm.cbSize := sizeof(NONCLIENTMETRICS);
-
-       SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @nm, 0);
-       lf := nm.lfMenuFont;
-
-       Font.Name := lf.lfFaceName;
-       Font.Height := lf.lfHeight;
-       Font.Style := [];
-       if lf.lfWeight >= 700 then
-               Font.Style := Font.Style + [fsBold];
-       if lf.lfItalic = 1 then
-               Font.Style := Font.Style + [fsItalic];
+    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @nm, 0);
+    lf := nm.lfMenuFont;
+    Font.Name := lf.lfFaceName;
+    Font.Height := lf.lfHeight;
+    Font.Style := [];
+    if lf.lfWeight >= 700 then
+        Font.Style := Font.Style + [fsBold];
+    if lf.lfItalic = 1 then
+        Font.Style := Font.Style + [fsItalic];
 end;
 
 {!
@@ -1835,7 +1839,13 @@ begin
        Index := AnsiPos(READ_PATH, path);
        if Index <> 0 then begin
                s := Copy(path, Index + Length(READ_PATH), Length(path));
-
+    end else begin
+        Index := AnsiPos(HTML_READ_PATH, path);
+        if Index <> 0 then begin
+            s := Copy(path, Index + Length(HTML_READ_PATH), Length(path));
+        end;
+    end;
+    if Index <> 0 then begin
                if (Length(s) > 0) and (s[1] = '/') then
                        Delete(s, 1, 1);
                BBSID := GetTokenIndex(s, '/', 0);
@@ -2064,7 +2074,7 @@ begin
                //\95W\8f\80\8f\91\8e®
                //\8dÅ\8cã\82Íl50, 10, 10-20, 10n, 10-20n, -10, 10-, 10n- \82È\82Ç
                //http://xxx.2ch.net/test/read.cgi/bbsid/1000000000/
-               FAWKStr.RegExp := '/test/read.cgi/.+/[0-9]+/?.*';
+               FAWKStr.RegExp := '/test/read.(cgi|html)/.+/[0-9]+/?.*';
                if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
                        s := Copy(s, 15, Length(s));
 
@@ -2501,7 +2511,7 @@ end;
 procedure TGikoSys.ListBoardFile;
 var
        boardFileList   : TStringList;
-       i, l, k                                 : Integer;
+       i, l                    : Integer;
 begin
        // BBS \82Ì\8aJ\95ú
        try
@@ -2532,13 +2542,9 @@ begin
          BoardFileList := TStringList.Create;
          try
         BoardFileList.BeginUpdate;
-               GikoSys.GetFileList( GikoSys.Setting.GetBoardDir, '*', BoardFileList, True, True );
+               GikoSys.GetFileList( GikoSys.Setting.GetBoardDir, '*.txt', BoardFileList, True, True );
         BoardFileList.EndUpdate;
-               for k := BoardFileList.Count - 1 downto 0 do begin
-                 if AnsiCompareText(ExtractFileExt(BoardFileList[ k ]), '.bak') = 0 then
-                         BoardFileList.Delete(k);
-               end;
-                         SetLength( BBSs, l + BoardFileList.Count );
+        SetLength( BBSs, l + BoardFileList.Count );
                for i := BoardFileList.Count - 1 downto 0 do begin
                  BBSs[ l ]                             := TBBS.Create( BoardFileList[ i ] );
                  BBSs[ l ].Title       := ChangeFileExt( ExtractFileName( BoardFileList[ i ] ), '' );
@@ -2746,62 +2752,48 @@ begin
        Result := Setting.GetSambaFileName;
 end;
 
-//! Samba.ini \82ª\96³\82¯\82ê\82Î\8dì\90¬
-procedure TGikoSys.SambaFileExists();
-var
-       sambaTmp: string;
-       sambaStrList: TStringList;
-begin
-       if not FileExists(GikoSys.GetSambaFileName) then begin
-               sambaTmp := ChangeFileExt(GikoSys.GetSambaFileName, '.default');
-               sambaStrList := TStringList.Create;
-               try
-                       if FileExists(sambaTmp) then begin
-                               sambaStrList.LoadFromFile(sambaTmp);
-                               sambaStrList.SaveToFile(GikoSys.GetSambaFileName);
-                       end;
-               finally
-                       sambaStrList.Free;
-               end;
-       end;
-end;
-
 {!
 \brief \93¯\82\93\8a\8de ID \82ð\8e\9d\82Â\83\8c\83X\82ð\83A\83\93\83J\81[\82É\82µ\82Ä\97ñ\8b\93
 \param AID        \8cÂ\90l\82ð\93Á\92è\82·\82é\93\8a\8de ID
 \param ThreadItem \97ñ\8b\93\82·\82é\83X\83\8c\83b\83h
-\param limited    \97ñ\8b\93\82·\82é\90\94\82ð\90§\8cÀ\82·\82é\82È\82ç True
+\param limited    \97ñ\8b\93\82·\82é\90\94\82ð\90§\8cÀ\82·\82é\82È\82ç1\88È\8fã
 \return           \97ñ\8b\93\82³\82ê\82½\83\8c\83X\83A\83\93\83J\81[
-\todo limited \82ð Integer \82É\82·\82é\82©\81A20 \82ð\8aO\82É\8fo\82·
 }
-function TGikoSys.GetSameIDResAnchor(const AID : string; ThreadItem: TThreadItem; limited: boolean):string;
+function TGikoSys.GetSameIDResAnchor(
+    const AID : string; ThreadItem: TThreadItem;
+    limited: Integer):string;
 var
        i: integer;
        body: TStringList;
+    Res: TResRec;
+    ResLink : TResLinkRec;
 begin
+    // body\88È\8aO\82Í\8eg\97p\82µ\82È\82¢\82Ì\82Å\8f\89\8aú\89»\82µ\82È\82¢
+    Res.FBody := '';
+    Res.FType := glt2chNew;
+
                Result := '';
                if (not IsNoValidID(AID)) and
                        (ThreadItem <> nil) and (ThreadItem.IsLogFile) then begin
                                body := TStringList.Create;
                                try
                                                GetSameIDRes(AID, ThreadItem, body);
-                                               if (limited) and (body.Count > 20) then begin
-                                                               for i := body.Count - 20 to body.Count - 1 do begin
-                                                                               Result := Result + '&gt;' + body[i] + ' ';
+                                               if (limited > 0) and (body.Count > limited) then begin
+                                                               for i := body.Count - limited to body.Count - 1 do begin
+                                                                               Res.FBody := Res.FBody + '&gt;' + body[i] + ' ';
                                                                end;
                                                end else begin
                                                                for i := 0 to body.Count - 1 do begin
-                                                                               Result := Result + '&gt;' + body[i] + ' ';
+                                                                               Res.FBody := Res.FBody + '&gt;' + body[i] + ' ';
                                                                end;
                                                end;
                                finally
                                                body.Free;
                                end;
-
-               Result := HTMLCreater.ConvRes(
-                       Result,
-                       ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''),
-                       'bbs', 'key', 'st', 'to', 'nofirst', 'true', false);
+        ResLink.FBbs := ThreadItem.ParentBoard.BBSID;
+        ResLink.FKey := ChangeFileExt(ThreadItem.FileName, '');
+        HTMLCreater.ConvRes(@Res, @ResLink, false);
+        Result := Res.FBody;
                end;
 end;
 
@@ -2854,37 +2846,43 @@ end;
 \brief \93¯\82\93\8a\8de ID \82ð\8e\9d\82Â\83\8c\83X\82ð\97ñ\8b\93
 \param AIDNum     \8cÂ\90l\82ð\93Á\92è\82·\82é\93\8a\8de ID
 \param ThreadItem \97ñ\8b\93\82·\82é\83X\83\8c\83b\83h
-\param limited    \97ñ\8b\93\82·\82é\90\94\82ð\90§\8cÀ\82·\82é\82È\82ç True
+\param limited    \97ñ\8b\93\82·\82é\90\94\82ð\90§\8cÀ\82·\82é\82È\82ç1\88È\8fã
 \return
-\todo limited \82ð Integer \82É\82·\82é\82©\81A20 \82ð\8aO\82É\8fo\82·
 }
-function TGikoSys.GetSameIDResAnchor(AIDNum : Integer; ThreadItem: TThreadItem; limited: boolean):string;
+function TGikoSys.GetSameIDResAnchor(AIDNum : Integer;
+     ThreadItem: TThreadItem;
+     limited: Integer):string;
 var
        i: integer;
        body: TStringList;
+    Res: TResRec;
+    ResLink : TResLinkRec;
 begin
+    // body\88È\8aO\82Í\8eg\97p\82µ\82È\82¢\82Ì\82Å\8f\89\8aú\89»\82µ\82È\82¢
+    Res.FBody := '';
+    Res.FType := glt2chNew;
+
        Result := '';
        if (ThreadItem <> nil) and (ThreadItem.IsLogFile) then begin
                body := TStringList.Create;
                try
                        GetSameIDRes(AIDNum, ThreadItem, body);
-            if (limited) and (body.Count > 20) then begin
-                       for i := body.Count - 20 to body.Count - 1 do begin
-                               Result := Result + '&gt;' + body[i] + ' ';
-                       end;
+            if (limited > 0) and ( body.Count > limited) then begin
+                for i := body.Count - 20 to body.Count - 1 do begin
+                    Res.FBody := Res.FBody + '&gt;' + body[i] + ' ';
+                end;
             end else begin
                        for i := 0 to body.Count - 1 do begin
-                               Result := Result + '&gt;' + body[i] + ' ';
+                               Res.FBody := Res.FBody + '&gt;' + body[i] + ' ';
                        end;
             end;
                finally
                        body.Free;
                end;
-               Result := HTMLCreater.ConvRes(
-                                       Result, ThreadItem.ParentBoard.BBSID,
-                                       ChangeFileExt(ThreadItem.FileName, ''),
-                                       'bbs', 'key', 'st', 'to', 'nofirst', 'true',
-                                       false);
+        ResLink.FBbs := ThreadItem.ParentBoard.BBSID;
+        ResLink.FKey := ChangeFileExt(ThreadItem.FileName, '');
+        HTMLCreater.ConvRes(@Res, @ResLink, false);
+        Result := Res.FBody;
        end;
 end;
 
@@ -2896,12 +2894,27 @@ end;
 }
 procedure TGikoSys.GetSameIDRes(AIDNum : Integer; ThreadItem: TThreadItem;var body: TStringList);
 var
+       AID : String;
+begin
+    AID := GetResID(AIDNum, ThreadItem);
+    if not IsNoValidID(AID) then begin
+           GetSameIDRes(AID, ThreadItem, body);
+       end;
+end;
+{!
+\brief \93\8a\8de ID \8eæ\93¾
+\param AIDNum     \93\8a\8d\83\8c\83X\94Ô\8d\86
+\param ThreadItem \93\8a\8de\83X\83\8c\83b\83h
+\param body       OUT:\93\8a\8deID
+}
+function TGikoSys.GetResID(AIDNum: Integer; ThreadItem: TThreadItem): String;
+var
        Res: TResRec;
        boardPlugIn : TBoardPlugIn;
-       AID : String;
        stList: TStringList;
        i : Integer;
 begin
+    Result := '';
        if (ThreadItem <> nil) and (ThreadItem.IsLogFile)
                and (AIDNum > 0) and (AIDNum <= ThreadItem.Count) then begin
                //if ThreadItem.IsBoardPlugInAvailable then begin
@@ -2913,21 +2926,21 @@ begin
                end else begin
                        THTMLCreate.DivideStrLine( ReadThreadFile(ThreadItem.GetThreadFileName, AIDNum), @Res);
                end;
-               AID := Res.FDateTime;
-               if AnsiPos('id', AnsiLowerCase(AID)) > 0 then begin
-                       AID := Copy(AID, AnsiPos('id', AnsiLowerCase(AID)) - 1, 11);
-            if AnsiPos(' be:', AnsiLowerCase(AID)) > 0 then begin
-               AID := Copy(AID, 1, AnsiPos(' BE:', AnsiLowerCase(AID)) - 1)
+               Result := Res.FDateTime;
+               if AnsiPos('id', AnsiLowerCase(Result)) > 0 then begin
+                       Result := Copy(Result, AnsiPos('id', AnsiLowerCase(Result)) - 1, 11);
+            if AnsiPos(' be:', AnsiLowerCase(Result)) > 0 then begin
+               Result := Copy(Result, 1, AnsiPos(' BE:', AnsiLowerCase(Result)) - 1)
             end;
                end else begin
                        stlist := TStringList.Create;
                        try
-                               stList.DelimitedText := AID;
-                AID := '';
+                               stList.DelimitedText := Result;
+                Result := '';
                                for i := 0 to stList.Count - 1 do
                                        if Length(WideString(stList[i])) = 8 then begin
                                                if NotDateorTimeString(stList[i]) then begin
-                                                       AID := stList[i];
+                                                       Result := stList[i];
                                                        break;
                                                end;
                                        end;
@@ -2935,11 +2948,8 @@ begin
                                stList.Free;
                        end;
                end;
-        if not IsNoValidID(AID) then
-                       GetSameIDRes(AID, ThreadItem, body);
        end;
 end;
-
 {!
 \brief \93¯\82\93\8a\8de ID \82ð\8e\9d\82Â\83\8c\83X\82ð\83J\83E\83\93\83g
 \param AID        \8cÂ\90l\82ð\93Á\92è\82·\82é\93\8a\8de ID
@@ -3273,12 +3283,231 @@ begin
        end;
 end;
 
+//Tue, 17 Dec 2002 12:18:07 GMT \81¨ TDateTime\82Ö
+//MonaUtils\82©\82ç\88Ú\93®
+function  TGikoSys.DateStrToDateTime(const DateStr: string): TDateTime;
+       function  StrMonthToMonth(const s: string): integer;
+       const
+               m: array[1..12] of string = ('Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec');
+       var
+               i: integer;
+       begin
+               Result  :=  -1;
+               for i :=  Low(m)  to  High(m) do  begin
+                       if  (SameText(s, m[i]))  then  begin
+                               Result  :=  i;
+                               Break;
+                       end;
+               end;
+       end;
+var
+       wDay, wMonth, wYear: word;
+       wHour, wMinute, wSecond: word;
+       sTime: string;
+       d: TDateTime;
+begin
+       wDay    :=  StrToIntDef(ChooseString(DateStr, ' ', 1), 0);
+       wMonth  :=  StrMonthToMonth(ChooseString(DateStr, ' ', 2));
+       wYear   :=  StrToIntDef(ChooseString(DateStr, ' ', 3), 0);
+       sTime   :=  ChooseString(DateStr, ' ', 4);
+       wHour   :=  StrToIntDef(ChooseString(sTime, ':', 0), 0);
+       wMinute :=  StrToIntDef(ChooseString(sTime, ':', 1), 0);
+       wSecond :=  StrToIntDef(ChooseString(sTime, ':', 2), 0);
+       d :=  EncodeDateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, 0);
+       Result  :=  d;
+end;
+//MonaUtils\82©\82ç\88Ú\93®
+//! \82 \82é\83Z\83p\83\8c\81[\83^\82Å\8bæ\90Ø\82ç\82ê\82½\95\8e\9a\97ñ\82©\82ç\82\8e\94Ô\96Ú\82Ì\95\8e\9a\97ñ\82ð\8eæ\82è\8fo\82·
+function TGikoSys.ChooseString(const Text, Separator: string; Index: integer): string;
+var
+       S : string;
+       i, p : integer;
+begin
+       S :=  Text;
+       for i :=  0 to  Index - 1 do  begin
+               if  (AnsiPos(Separator, S) = 0) then  S :=  ''
+               else  S :=  Copy(S, AnsiPos(Separator, S) + Length(Separator), Length(S));
+       end;
+       p :=  AnsiPos(Separator, S);
+       if  (p > 0) then  Result  :=  Copy(S, 1, p - 1) else Result :=  S;
+end;
+//! \88ê\8e\9e\83t\83@\83C\83\8b\82©\82ç\82Ì\95\9c\8b\8c
+procedure TGikoSys.RestoreThreadData(Board : TBoard);
+const
+    SECTION = 'Setting';
+var
+    TmpFileList : TStringList;
+    i : Integer;
+    ini : TMemIniFile;
+    ThreadItem : TThreadItem;
+    Boardpath, tmpStr : string;
+begin
+    Boardpath := ExtractFilePath(Board.GetFolderIndexFileName);
+
+       TmpFileList := TStringList.Create;
+       TmpFileList.Sorted := True;
+       TmpFileList.BeginUpdate;
+    try
+       //\91O\89ñ\88Ù\8fí\8fI\97¹\8e\9e\97pTmp\83t\83@\83C\83\8b\83\8a\83X\83g
+           GetFileList(Boardpath, '*.tmp', TmpFileList, False);
+           TmpFileList.EndUpdate;
+               //\91O\89ñ\88Ù\8fí\8fI\97¹\8e\9e\83`\83F\83b\83N
+               for i := TmpFileList.Count - 1 downto 0 do begin
+                       ThreadItem := Board.FindThreadFromFileName(ChangeFileExt(TmpFileList[i], '.dat'));
+                       if ThreadItem <> nil then begin
+                               ini := TMemIniFile.Create(Boardpath + TmpFileList[i]);
+                               try
+                                       tmpStr := ini.ReadString(SECTION, 'RoundDate', DateTimeToStr(ZERO_DATE));
+                                       ThreadItem.RoundDate := ConvertDateTimeString(tmpStr);
+
+                                       tmpStr := ini.ReadString(SECTION, 'LastModified', DateTimeToStr(ZERO_DATE));
+                                       ThreadItem.LastModified := ConvertDateTimeString(tmpStr);
+                                       ThreadItem.Count := ini.ReadInteger(SECTION, 'Count', 0);
+                                       ThreadItem.NewReceive := ini.ReadInteger(SECTION, 'NewReceive', 0);
+
+                                       ThreadItem.Size := ini.ReadInteger(SECTION, 'Size', 0);
+                    ThreadItem.IsLogFile := FileExists(ThreadItem.GetThreadFileName);
+                                       if(ThreadItem.Size = 0) and (ThreadItem.IsLogFile) then begin
+                                               try
+                                                       ThreadItem.Size := GetFileSize(ThreadItem.GetThreadFileName) - ThreadItem.Count;
+                                               except
+                                               end;
+                                       end;
+
+                    //\8f\84\89ñ\82Ì\90Ý\92è\82ÍRoundData\82Ì\95û\82ª\82â\82é\82©\82ç\8f\9f\8eè\82É\90Ý\92è\82µ\82Ä\82Í\83_\83\81\81I\81@by \82à\82\82ã
+                                       //ThreadItem.Round := ini.ReadBool('Setting', 'Round', False);
+                                       //ThreadItem.RoundName := ini.ReadString('Setting', 'RoundName', ThreadItem.RoundName);
+                                       ThreadItem.UnRead := False;//ini.ReadBool('Setting', 'UnRead', False);
+                                       ThreadItem.ScrollTop := ini.ReadInteger(SECTION, 'ScrollTop', 0);
+                                       ThreadItem.AllResCount := ini.ReadInteger(SECTION, 'AllResCount', ThreadItem.Count);
+                                       ThreadItem.NewResCount := ini.ReadInteger(SECTION, 'NewResCount', 0);
+                                       ThreadItem.AgeSage := TGikoAgeSage(ini.ReadInteger(SECTION, 'AgeSage', Ord(gasNone)));
+                               finally
+                                       ini.Free;
+                               end;
+                               DeleteFile(Boardpath + TmpFileList[i]);
+                       end;
+               end;
+    finally
+        TmpFileList.Clear;
+        TmpFileList.Free;
+    end;
+end;
+{
+\brief User32.dll\82ª\97\98\97p\82Å\82«\82é\82©
+\return Boolean \97\98\97p\82Å\82«\82é\8fê\8d\87\82ÍTrue
+}
+function TGikoSys.CanUser32DLL: Boolean;
+var
+    hUser32 : HINST;
+begin
+    Result := False;
+       hUser32 := 0;
+       try
+               try
+                       hUser32 := LoadLibrary('User32.dll');
+                       if hUser32 <> 0 then begin
+                               Result := True;
+            end;
+               except
+               Result := false;
+               end;
+       finally
+               FreeLibrary(hUser32);
+       end;
+end;
+{
+\brief  OE\88ø\97p\95\84\8eæ\93¾
+\return OE\82Ì\88ø\97p\95\84\81i\90Ý\92è\82³\82ê\82Ä\82¢\82È\82¢\8fê\8d\87\82Í'>')
+}
+function TGikoSys.GetOEIndentChar : string;
+var
+       regKey                  : TRegistry;
+       Identities      : string;
+       IndentChar      : DWORD;
+const
+       DEFAULT_CHAR    = '> ';
+       OE_MAIL_PATH    = '\Software\Microsoft\Outlook Express\5.0\Mail';
+       INDENT_CHAR             = 'Indent Char';
+begin
+
+       Result  := DEFAULT_CHAR;
+       regKey  := TRegistry.Create;
+       try
+               try
+                       regKey.RootKey  := HKEY_CURRENT_USER;
+                       if not regKey.OpenKey( 'Identities', False ) then
+                               Exit;
+                       Identities                      := regKey.ReadString( 'Default User ID' );
+                       if Identities = '' then
+                               Exit;
+                       if not regKey.OpenKey( Identities + OE_MAIL_PATH, False ) then
+                               Exit;
+                       IndentChar := regKey.ReadInteger( INDENT_CHAR );
+                       Result := Char( IndentChar ) + ' ';
+               except
+               end;
+       finally
+               regKey.Free;
+       end;
+
+end;
+//! \92u\8a·\90Ý\92è\83t\83@\83C\83\8b\8eæ\93¾
+function TGikoSys.GetReplaceFileName: String;
+begin
+    Result := Setting.GetReplaceFileName;
+end;
+//! \83v\83\8c\83r\83\85\81[\8ag\92£\82Ì\90Ý\92è\83t\83@\83C\83\8b\8eæ\93¾
+function TGikoSys.GetExtpreviewFileName: String;
+begin
+    Result := Setting.GetExtprevieFileName;
+end;
+
+//! \83t\83@\83C\83\8b\96¼\82©\82ç\82Ì\83X\83\8c\83b\83h\8dì\90¬\93ú\82Ì\8eæ\93¾
+function TGikoSys.GetCreateDateFromName(FileName: String): TDateTime;
+var
+    tmp : String;
+    unixtime: Int64;  
+begin
+    // \83\8d\83O\83t\83@\83C\83\8b\82Ì\8ag\92£\8eq\82ð\82Í\82¸\82µ\82½\82à\82Ì\82ª\83X\83\8c\8dì\90¬\93ú\8e\9e
+    tmp := ChangeFileExt(FileName, '');
+    if AnsiPos('_', tmp) <> 0 then
+        if AnsiPos('_', tmp) > 9 then
+            tmp := Copy(tmp, 1, AnsiPos('_', tmp)-1)
+        else
+            Delete(tmp, AnsiPos('_', tmp), 1);
+
+    if ( Length(tmp) = 9) and ( tmp[1] = '0' ) then
+        Insert('1', tmp, 1);
+
+    unixtime := StrToInt64Def(tmp, ZERO_DATE);
+    Result := UnixToDateTime(unixtime) + OffsetFromUTC;
+end;
+
+procedure TGikoSys.ShowRefCount(msg: String; unk: IUnknown);
+var
+    count : integer;
+begin
+    if not Assigned(unk) then
+        Exit;
+
+{$IFDEF DEBUG}
+    try
+        unk._AddRef;
+        count := unk._Release;
+
+               Writeln(msg + ' RefCount=' + IntToStr(count));
+    except
+               Writeln(msg + ' RefCount=exception!!');
+       end;
+{$ENDIF}
+end;
+
 initialization
        GikoSys := TGikoSys.Create;
 
 finalization
        if GikoSys <> nil then begin
-               GikoSys.Free;
-               GikoSys := nil;
+               FreeAndNil(GikoSys);
        end;
 end.