unit _myIniFile; //{$DEFINE _DEBUG} interface uses Classes, Forms, Graphics, Windows, Controls, // mySize, // myType, _myWStrings; type TMyIniFile = class(TObject) private F_sFileName: WideString; F_slList: TMyWStrings; //iniファイルを読み込むリスト F_slSectionIndex: TMyWStrings; //セクションのインデックスを記録するリスト F_sSection: WideString; //編集・読み込み対象のセクション名 F_slSectionData: TMyWStrings; //編集・読み込み対象のセクションの中身を記録するリスト  F_bSectionModified: Boolean; F_bModified: Boolean; F_bDebug: Boolean; F_cdReadCharCode: TMyCharCode; F_cdWriteCharCode: TMyCharCode; procedure F_SetFileName(sFileName: WideString); procedure F_UpdateSection; procedure F_ReadSectionIndex; function F_fnbSectionExists(sSection: WideString; out iStart, iEnd: Integer): Boolean; procedure F_DeleteSection(sSection: WideString); procedure F_ReadSectionText (sSection: WideString; slStrings: TMyWStrings; bText: Boolean); procedure F_WriteSectionText (sSection: WideString; slStrings: TMyWStrings; bText: Boolean); procedure F_ReadSectionValues(sSection: WideString); public constructor Create; overload; constructor Create(cdCode: TMyCharCode); overload; constructor Create(sFileName: WideString); overload; constructor Create(sFileName: WideString; cdCode: TMyCharCode); overload; destructor Destroy; override; function UpdateFile: Boolean; virtual; function SectionExists(sSection: WideString): Boolean; virtual; procedure ReadSections (slStrings: TMyWStrings); virtual; procedure ReadSection (sSection: WideString; slStrings: TMyWStrings); virtual; procedure EraseSection (sSection: WideString); virtual; procedure WriteSection (sSection: WideString); //SectionValues 無効な行、キー、重複キーを削除 procedure ReadSectionValues (sSection: WideString; slStrings: TMyWStrings); overload; virtual; procedure WriteSectionValues(sSection: WideString; slStrings: TMyWStrings); overload; virtual; procedure ReadSectionValues (sSection: WideString; slStrings: TStrings); overload; virtual; procedure WriteSectionValues(sSection: WideString; slStrings: TStrings); overload; virtual; //SectionText SectionValuesと違いそのまま procedure ReadSectionText (sSection: WideString; slStrings: TMyWStrings); overload; virtual; procedure WriteSectionText(sSection: WideString; slStrings: TMyWStrings); overload; virtual; procedure ReadSectionText (sSection: WideString; slStrings: TStrings); overload; virtual; procedure WriteSectionText(sSection: WideString; slStrings: TStrings); overload; virtual; function ReadString (sSection, sKey, sDefault: WideString): WideString; virtual; procedure WriteString (sSection, sKey, sValue: WideString); virtual; function ReadInteger (sSection, sKey: WideString; iDefault: Longint): Longint; virtual; procedure WriteInteger(sSection, sKey: WideString; iValue: Longint); virtual; function ReadBool (sSection, sKey: WideString; bDefault: Boolean): Boolean; virtual; procedure SetBool (sSection, sKey : WideString; var bValue : Boolean); virtual; procedure WriteBool (sSection, sKey: WideString; bValue: Boolean); virtual; function ReadFloat (sSection, sKey: WideString; fDefault: Extended): Extended; virtual; procedure WriteFloat (sSection, sKey: WideString; fValue: Extended); virtual; //BoundsRect procedure WriteBoundsRect(sSection, sKey: WideString; rcRect: TRect); overload; function ReadBoundsRect (sSection: WideString; AControl: TControl): TRect; overload; procedure WriteBoundsRect(sSection: WideString; AControl: TControl); overload; function ReadBoundsRect (AControl: TControl): TRect; overload; procedure WriteBoundsRect(AControl: TControl); overload; //FormのBoundsRect モニター内に納まるようなBoundsRectを返す function ReadMonitorBoundsRect(sSection: WideString; AForm: TForm): TRect;overload; function ReadMonitorBoundsRect(AForm: TForm): TRect; overload; procedure SetMonitorBoundsRect(sSection: WideString; AForm: TForm);overload; procedure SetMonitorBoundsRect(AForm: TForm); overload; //TRect function ReadRect (sSection, sKey: WideString; rcDefault: TRect): TRect; procedure WriteRect(sSection, sKey: WideString; rcValue: TRect); //TPoint function ReadPoint (sSection, sKey: WideString; ptDefault: TPoint): TPoint; procedure WritePoint(sSection, sKey: WideString; ptValue: TPoint); //TSize function ReadSize (sSection, sKey: WideString; szDefault: TSize): TSize; procedure WriteSize(sSection, sKey: WideString; szValue: TSize); //TFont procedure SetFont (sSection, sKey: WideString; Font: TFont); overload; procedure SetFont (sSection, sKey: WideString; Control: TControl); overload; procedure SetFont (sSection: WideString; Control: TControl); overload; procedure WriteFont(sSection, sKey: WideString; Font: TFont); overload; procedure WriteFont(sSection, sKey: WideString; Control: TControl); overload; procedure WriteFont(sSection: WideString; Control: TControl); overload; // procedure DeleteKey(const sSection, sKey: WideString); virtual; // function ValueExists(const sSection, sKey: WideString): Boolean; { function ReadDate(const Section, Name: string; Default: TDateTime): TDateTime; virtual; procedure WriteDate(const Section, Name: string; Value: TDateTime); virtual; function ReadDateTime(const Section, Name: string; Default: TDateTime): TDateTime; virtual; procedure WriteDateTime(const Section, Name: string; Value: TDateTime); virtual; function ReadTime(const Section, Name: string; Default: TDateTime): TDateTime; virtual; procedure WriteTime(const Section, Name: string; Value: TDateTime); virtual; function ReadBinaryStream(const Section, Name: string; Value: TStream): Integer; virtual; procedure WriteBinaryStream(const Section, Name: string; Value: TStream); virtual; } property FileName: WideString read F_sFileName write F_SetFileName; property Debug: Boolean read F_bDebug write F_bDebug; property WriteCharCode: TMyCharCode read F_cdWriteCharCode write F_cdWriteCharCode; end; //------------------------------------------------------------------------------ function gfnsIniNameGet(sItem: WideString): WideString; overload; function gfnsIniValueGet(sItem: WideString): WideString; overload; procedure gpcIniNameValueDiv(sItem: WideString; out sName, sValue: WideString); overload; function gfnsIniNameGet(sItem, sSep: WideString): WideString; overload; function gfnsIniValueGet(sItem, sSep: WideString): WideString; overload; procedure gpcIniNameValueDiv(sItem, sSep: WideString; out sName, sValue: WideString); overload; const // gcsSECT_BOUNDS = 'Bounds'; gcsKEY_BOUNDS_LEFT = '_Left'; gcsKEY_BOUNDS_TOP = '_Top'; gcsKEY_BOUNDS_WIDTH = '_Width'; gcsKEY_BOUNDS_HEIGHT = '_Height'; //TRect gcsKEY_RECT_LEFT = '_Left'; gcsKEY_RECT_TOP = '_Top'; gcsKEY_RECT_RIGHT = '_Right'; gcsKEY_RECT_BOTTOM = '_Bottom'; //TPoint gcsKEY_POINT_X = '_X'; gcsKEY_POINT_Y = '_Y'; //TSize gcsKEY_SIZE_CX = '_cx'; gcsKEY_SIZE_CY = '_cy'; //TFont gcsKEY_FONT_NAME = '_FontName'; gcsKEY_FONT_SIZE = '_FontSize'; gcsKEY_FONT_COLOR = '_FontColor'; gcsKEY_FONT_STYLEBOLD = '_FontStyleBold'; gcsKEY_FONT_STYLEITALIC = '_FontStyleItalic'; gcsKEY_FONT_STYLEUNDERLINE = '_FontStyleUnderLine'; gcsKEY_FONT_STYLESTRIKEOUT = '_FontStyleStrikeOut'; gcsKEY_FONT_CHARSET = '_FontCharset'; implementation uses {$IFDEF _DEBUG} _myDebug, {$ENDIF} MultiMon, PsAPI, SysUtils, TypInfo, System.UITypes; // myGraphic, // myFile, // myList, // myMonitor, // myNum, // myString; // myString.pas ---------------------------------------------------------------- function gfnsStrEndFit(sSrc, sEnd: WideString): WideString; //sSrcの末尾がsEndでなければsEndを足して返す。 begin if (Copy(sSrc, Length(sSrc) - Length(sEnd) +1, Length(sEnd)) <> sEnd) then begin Result := sSrc + sEnd; end else begin Result := sSrc; end; end; function gfnsStrToHalf(sSrc: WideString): WideString; {,2008-11-28,2009-02-28: 2009-02-28: 奇数文字の場合というより濁点半濁点の場合に文字が足りなくなる不具合へ対処。 2008-11-28: 奇数文字数の場合1文字足りなくなる不具合を修正。 } var lp_Buff : PWideChar; li_Len : Integer; begin Result := sSrc; li_Len := LCMapStringW(GetUserDefaultLCID(), LCMAP_HALFWIDTH, PWideChar(Result), -1, nil, 0); lp_Buff := AllocMem((li_Len +1) * 2); try //半角にする LCMapStringW(GetUserDefaultLCID(), LCMAP_HALFWIDTH, PWideChar(Result), -1, lp_Buff, li_Len); Result := WideString(lp_Buff); finally FreeMem(lp_Buff); end; end; //myWindow.pas ----------------------------------------------------------------- function gfnsSystem32DirGet: WideString; var li_Size: UINT; lp_Buff: PWideChar; begin Result := ''; li_Size := GetSystemDirectoryW(nil, 0); if (li_Size > 0) then begin lp_Buff := AllocMem(li_Size * SizeOf(WideChar)); try li_Size := GetSystemDirectoryW(lp_Buff, li_Size); if (li_Size > 0) then begin Result := gfnsStrEndFit(WideString(lp_Buff), '\'); end; finally FreeMem(lp_Buff); end; end; end; // myFile.pas ------------------------------------------------------------------ function gfnsFileExtChange(sFile, sExt: WideString): WideString; {2008-03-16,2010-12-19: Unicode対応ChangeFileExt。 ファイルの拡張子を変えて返す。 sExtが空文字なら拡張子を削除して返す。 2010-12-19:sFileに拡張子が無い場合sExtだけを返していた間違いを修正。 } var i: Integer; begin Result := ''; if (sExt <> '') and (sExt[1] <> '.') then begin //sExtが''だった時は拡張子削除。 //それ以外はピリオドがなければつけたす。 sExt := '.' + sExt; end; for i := Length(sFile) downto 1 do begin if (sFile[i] = '\') or (sFile[i] = ':') then begin //拡張子なし Break; end else if (sFile[i] = '.') then begin; //拡張子あり if (i > 1) then begin Result := Copy(sFile, 1, i -1) + sExt; end else begin Result := sExt; end; Exit; end; end; //sFileに拡張子があればここにはこない(↑でExitしている) Result := sFile + sExt; end; function gfnsExeNameGet(sStr: WideString): WideString; overload; {,2015-04-18: 2015-04-18:CommandLineToArgvWを使っていたものから自作関数で分割するようにに変更。 } const lcs_QUOT = WideChar('"'); lcs_SPACE = WideChar(' '); lcs_TAB = WideChar(#$9); lcs_CR = WideChar(#$D); lcs_LF = WideChar(#$A); var i: Integer; li_Len : Integer; ls_Param : WideString; ls_Char : WideChar; lb_Quot : Boolean; lb_Skip : Boolean; begin li_Len := Length(sStr); lb_Quot := False; lb_Skip := False; ls_Param := ''; for i := 1 to li_Len do begin ls_Char := sStr[i]; case ls_Char of lcs_QUOT :begin //最初にみつかった引用符は区切り。 if not(lb_Quot) then begin //最初にみつかった引用符は区切り。 lb_Quot := True; if (ls_Param <> '') then begin //パラメータがあったのでそれが実行ファイル名。 Result := ls_Param; Exit; end; end else if (lb_Skip) then begin //引用符内引用符。 lb_Skip := False; ls_Param := ls_Param + ls_Char; end else if (i < li_Len) and (sStr[i +1] = lcs_QUOT) then begin //この引用符のすぐ後にも引用符があるので引用符内引用符であるので引数の取り出しにはならない。 //ex) "引用符を含めるには""とする" lb_Skip := True; end else if (lb_Quot) then begin //引用符の閉じ⇒ここまでが実行ファイル名。 Result := ls_Param; Exit; end; end; lcs_SPACE, //半角スペース。 lcs_TAB, //タブ。 lcs_CR, //改行。 lcs_LF //改行。 :begin //引数の区切り。 if (lb_Quot) then begin //引用符つき引数であるので引数の区切りではない⇒引数の文字列に加える。 ls_Param := ls_Param + ls_Char; end else begin //引用符つき引数ではないので引数の区切り⇒ここまでが実行ファイル名。 if (ls_Param <> '') then begin Result := ls_Param; Exit; end; end; end; else begin ls_Param := ls_Param + ls_Char; end; end; end; if (ls_Param <> '') then begin Result := ls_Param; end; end; type TGetProcessImageFileName = function(hProcess: THandle; lpImageFileName: LPWSTR; nSize: DWORD): DWORD; stdcall; //function GetProcessImageFileNameW(hProcess: THandle; lpImageFileName: LPWSTR; nSize: DWORD): DWORD; stdcall; external 'Psapi.dll'; function gfnsExeNameGet(hHandle: HWND): WideString; overload; { ウィンドウハンドルからexeファイル名を返す http://m--takahashi.com/bbs/pastlog/02500/02414.html http://www.geocities.jp/fjtkt/problems/2003_0004.html http://www2.big.or.jp/~osamu/Delphi/tips.cgi?index=0182.txt http://homepage1.nifty.com/MADIA/delphi/Win32API/Process.htm http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+201010/10100011.txt http://www14.big.or.jp/~ken1/tech/tech11.html } function _ProcessIDGet(hHandle: HWND): DWORD; begin GetWindowThreadProcessId(hHandle, @Result); end; var lh_Process : THandle; // lh_Module : THandle; // li_Num : DWORD; lp_Buff : PWideChar; // l_Info : MODULEINFO; i : Integer; li_Drives : DWORD; li_Flag : Integer; ls_Device : WideString; lp_Device : PWideChar; ls_Drv : WideString; ls_Path : WideString; lh_Module : HMODULE; l_GetProcessImageFileName : TGetProcessImageFileName; begin Result := ''; lh_Process := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, _ProcessIDGet(hHandle)); try lp_Buff := AllocMem((MAX_PATH +1) * SizeOf(WideChar)); try //プロセスハンドルを渡すだけで実行ファイル名を得られた。インスタンスハンドルはいらないようだ。 if (GetModuleFileNameExW(lh_Process, 0, lp_Buff, MAX_PATH) <> 0) then begin Result := WideString(lp_Buff); end else begin { //EnumProcessModulesは32bitプロセスから64bitプロセスのモジュールハンドルを取得できない。 if (EnumProcessModules(lh_Process, @lh_Module, SizeOf(HMODULE), li_Num)) then begin FillChar(l_Info, SizeOf(l_Info), 0); if (GetModuleInformation(lh_Process, lh_Module, @l_Info, SizeOf(l_Info))) then begin if (GetMappedFileNameW(lh_Process, l_Info.EntryPoint, lp_Buff, MAX_PATH) <> 0) then begin Result := WideString(lp_Buff); end; end; end; } //GetModuleFileNameExWは32bitプロセスから64bitプロセスの実行ファイル名を取得できない。 //システムディレクトリを取得 ls_Path := gfnsSystem32DirGet; //完全修飾パスを指定してPsapi.dllをロード lh_Module := LoadLibraryW(PWideChar(ls_Path + 'Psapi.dll')); if (lh_Module <> 0) then begin try //GetProcessImageFileNameの関数ポインタを取得 @l_GetProcessImageFileName := GetProcAddress(lh_Module, 'GetProcessImageFileNameW'); if (@l_GetProcessImageFileName <> nil) then begin l_GetProcessImageFileName(lh_Process, lp_Buff, MAX_PATH); Result := WideString(lp_Buff); end; finally FreeLibrary(lh_Module); end; if (Result <> '') then begin li_Drives := GetLogicalDrives; li_Flag := 1; for i := Ord('A') to Ord('Z') do begin if ((li_Drives and li_Flag) <> 0) then begin //_myDebug.gpcDebug(WideChr(i)); lp_Device := nil; try lp_Device := AllocMem((MAX_PATH +1) * SizeOf(WideChar)); ls_Drv := WideString(Char(i)) + ':'; QueryDosDeviceW(PWideChar(ls_Drv), lp_Device, MAX_PATH); ls_Device := WideString(lp_Device); //_myDebug.gpcDebug(ls_Device); if (Pos(ls_Device + '\', Result) = 1) then begin Result := ls_Drv + Copy(Result, Length(ls_Device) +1, MaxInt); Break; end; finally FreeMem(lp_Device); end; end; li_Flag := li_Flag shl 1; end; end; end; end; finally FreeMem(lp_Buff); end; finally CloseHandle(lh_Process); end; end; function gfnsExeNameGet: WideString; overload; {2007-09-24,2009-09-23: WideString対応の実行プログラム名を返す。 2009-09-23:  コマンドラインを分解して取得するのではなくApplicationのウィンドウハンドルから  取得するように変更。  コマンドプロンプトから実行させるとパスがつかないことがあることへの対処。 } var lh_Handle: HWND; begin lh_Handle := Application.Handle; if (lh_Handle <> 0) then begin Result := gfnsExeNameGet(lh_Handle); end; if (Result = '') then begin Result := gfnsExeNameGet(GetCommandLineW); end; end; function gfnsFilePathGet(sFile: WideString): WideString; {2007-07-27,10-26: Unicode対応ExtractFilePath。 ドライブ名も含む。 末尾の'\'はつく。 ドライブ名のみの場合も'\'はつく。 ただしパスが空文字の場合のみ'\'はつかない。 2007-10-26:パスが空文字の場合'\'をつけないことにした。 } var i: Integer; begin Result := ''; if (sFile <> '') then begin for i := Length(sFile) downto 1 do begin if (sFile[i] = '\') or (sFile[i] = '/') then begin Result := Copy(sFile, 1, i); Break; end else if (sFile[i] = ':') then begin Result := Copy(sFile, 1, i) + '\'; Break; end; end; end; end; function gfniFileAttrGet(sFile: WideString; bFileOnly: Boolean): Integer; {2007-08-28,2008-02-20,12-26: sFileのファイル属性を返す。 ドライブ名のみは無効(-1を返す)。 bFileOnlyがTrueならディレクトリは無視する。 2008-12-26:FileGetAttrに合わせた仕様に変更。 2008-02-20:ワイルドカードを指定した時に正しい値を返さない不具合を修正。 } var lh_Handle: THandle; lr_Info: TWin32FindDataW; li_Len: Integer; begin // Result := Integer(GetFileAttributesW(PWideChar(sFile))); Result := -1; if (sFile <> '') then begin li_Len := Length(sFile); if (sFile[li_Len] = '\') then begin SetLength(sFile, li_Len -1); end; end; FillChar(lr_Info, SizeOf(TWin32FindDataW), 0); lh_Handle:= FindFirstFileW(PWideChar(sFile), lr_Info); try if (lh_Handle<> INVALID_HANDLE_VALUE) then begin repeat if (WideString(lr_Info.cFileName) <> '.') and (WideString(lr_Info.cFileName) <> '..') then begin if (bFileOnly = False) or ((bFileOnly) and ((lr_Info.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0)) then begin //bFileOnlyがFalse //または bFileOnlyがTrueでかつディレクトリではななかった Result := Integer(lr_Info.dwFileAttributes); Break; end; end; until not(FindNextFileW(lh_Handle, lr_Info)); end; finally Windows.FindClose(lh_Handle); end; end; function gfnbFolderExists(sFolder: WideString): Boolean; {2007-07-27,2008-02-20,2008-04-24: DirectoryExistsのWideString対応版 2008-02-20:sFileにワイルドカードが指定された時の対処 2008-04-24:sFileの末尾に'\'があるとエラーになることへの対処 } var lh_Handle: THandle; lr_Info: TWin32FindDataW; li_Len: Integer; li_Attr: DWORD; begin Result := False; if (sFolder = '') then Exit; if (Pos('*', sFolder) > 0) or (Pos('?', sFolder) > 0) then begin if (sFolder <> '') then begin li_Len := Length(sFolder); if (sFolder[li_Len] = '\') then begin SetLength(sFolder, li_Len-1); end; end; FillChar(lr_Info, SizeOf(TWin32FindDataW), 0); lh_Handle:= FindFirstFileW(PWideChar(sFolder), lr_Info); try if (lh_Handle<> INVALID_HANDLE_VALUE) then begin repeat if (WideString(lr_Info.cFileName) <> '.') and (WideString(lr_Info.cFileName) <> '..') and ((lr_Info.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then begin Result := True; Break; end; until not(FindNextFileW(lh_Handle, lr_Info)); end; finally Windows.FindClose(lh_Handle); end; end else begin li_Attr := GetFileAttributesW(PWideChar(sFolder)); Result := (li_Attr <> $FFFFFFFF) and ((li_Attr and FILE_ATTRIBUTE_DIRECTORY) <> 0); end; end; function gfnbFileExists(sFile: WideString): Boolean; {2007-07-27: FileExitsのUnicode対応版 } var li_Attr: DWORD; begin Result := False; if (sFile = '') then Exit; if (Pos('*', sFile) > 0) or (Pos('?', sFile) > 0) then begin if (gfnbFolderExists(gfnsFilePathGet(sFile))) then begin li_Attr := gfniFileAttrGet(sFile, True); Result := (li_Attr <> $FFFFFFFF) and ((li_Attr and FILE_ATTRIBUTE_DIRECTORY) = 0); end; end else begin li_Attr := GetFileAttributesW(PWideChar(sFile)); Result := (li_Attr <> $FFFFFFFF) and ((li_Attr and FILE_ATTRIBUTE_DIRECTORY) = 0); end; end; // myNum.pas ------------------------------------------------------------------- procedure gpcVal(S: String; var V: Int64; var Code: Integer); overload; var ls_Num : WideString; li_Pos : Integer; begin Val(S, V, Code); if (Code > 0) then begin ls_Num := Copy(S, 1, Code -1); Val(ls_Num, V, li_Pos); end; end; procedure gpcVal(S: String; var V: Integer; var Code: Integer); overload; var ls_Num : WideString; li_Pos : Integer; begin Val(S, V, Code); if (Code > 0) then begin ls_Num := Copy(S, 1, Code -1); Val(ls_Num, V, li_Pos); end; end; function gfniStrToInt(sNum: String; bHexadecimal: Boolean = False): Int64; {2007-10-18,2008-02-13,2009-01-16: sNumを整数にして返す。 2009-01-19:戻り値をInt64に変更。この時StrToInt64の'x'の扱いがStrToIntと違うことへ対処。 2008-02-13:16進に対応。 } var li_Pos, i: Integer; ls_Tmp: String; li_Err: Integer; begin sNum := UpperCase(gfnsStrToHalf(Trim(sNum))); //全角の算用数字もOkなように半角にする gpcVal(sNum, Result, li_Err); if (li_Err = 0) then begin Exit; end; ls_Tmp := ''; for i := 1 to Length(sNum) do begin li_Pos := Pos(sNum[i], '$X-+, 0123456789ABCDEF'); if (li_Pos >= 17) then begin //'A..F' if (ls_Tmp <> '') and (ls_Tmp[1] = '$') then begin ls_Tmp := ls_Tmp + sNum[i]; end else begin //頭に'$'を付け加えて変換できるようにする //頭に$がないと16進表記はエラーになるのでそれへの対処 ls_Tmp := '$' + ls_Tmp + sNum[i]; end; end else if (li_Pos >= 7) then begin //'0..9' ls_Tmp := ls_Tmp + sNum[i]; end else if ((li_Pos = 1) or (li_Pos = 2)) and (ls_Tmp = '') then begin //'$', 'X' //16進表記 ls_Tmp := '$'; //'x'や'X'ではだめ end else if ((li_Pos = 3) or (li_Pos = 4)) and (ls_Tmp = '') then begin //and (i = 1) でもよい //'-', '+' //sNum[i]は'-+'のどちらか ls_Tmp := sNum[i]; end else if (li_Pos = 5) then begin //','は無視。 end else if (li_Pos = 6) then begin //' 'は行頭なら無視、途中ならそこまで if (ls_Tmp <> '') then begin Break; end; end else begin Break; end; end; if (ls_Tmp = '') then begin Result := 0; end else begin if (bHexadecimal) and (ls_Tmp[1] <> '$') then begin ls_Tmp := '$' + ls_Tmp; end; Result := StrToInt64Def(ls_Tmp, 0); end; end; function gfniNumLimit(iNum: Int64; iMin, iMax: Int64): Int64; begin if (iMin = iMax) then begin Result := iMin; end else begin //間違いの元なので気を利かせるのをやめた //l_pcNumSwap_MinMax(iMin, iMax); if (iNum < iMin) then begin Result := iMin; end else if (iNum > iMax) then begin Result := iMax; end else begin Result := iNum; end; end; end; // myList.pas ------------------------------------------------------------------ function gfnbIsIncludeList(sValue: WideString; slList: TMyWStrings): Boolean; {2008-08-26: slList中にsValueがあればTrueを返す 大文字小文字の違いは無視 } var i: Integer; begin Result := False; for i := 0 to slList.Count -1 do begin if (WideCompareText(sValue, slList[i]) = 0) then begin Result := True; Break; end; end; end; // mySize.pas ------------------------------------------------------------------ function gfniRectWidth(rtRect: TRect): Integer; //rtRectの幅を返す。 begin with rtRect do begin Result := Right - Left; end; end; function gfniRectHeight(rtRect: TRect): Integer; //rtRectの高さを返す。 begin with rtRect do begin Result := Bottom - Top; end; end; // myMonitor.pas --------------------------------------------------------------- function gfnhMonitorFromRect(rcRect: TRect): HMONITOR; //rcRectの領域があるモニターのモニターハンドルを返す。 begin Result := MultiMon.MonitorFromRect(@rcRect, MONITOR_DEFAULTTONEAREST); end; function gfnrcMonitorWorkAreaRectGet(hHandle: HMONITOR): TRect; overload; //モニターのワークエリアを返す。 var lr_Info: TMonitorInfo; begin lr_Info.cbSize := SizeOf(lr_Info); GetMonitorInfo(hHandle, @lr_Info); Result := lr_Info.rcWork; end; function gfnrcMonitorWorkAreaRectGet(rcRect: TRect): TRect; overload; //rcRectの領域のあるモニターのワークエリアを返す。 begin Result := gfnrcMonitorWorkAreaRectGet(gfnhMonitorFromRect(rcRect)); end; //============================================================================== constructor TMyIniFile.Create; begin Create(cdAuto); end; constructor TMyIniFile.Create(cdCode: TMyCharCode); //引数無しで実行ファイル名の拡張子を'.ini'に変えて読み込む begin Create(gfnsFileExtChange(gfnsExeNameGet, '.ini'), cdCode); end; constructor TMyIniFile.Create(sFileName: WideString); begin Create(sFileName, cdAuto); end; constructor TMyIniFile.Create(sFileName: WideString; cdCode: TMyCharCode); begin inherited Create; F_bDebug := False; F_cdReadCharCode := cdCode; F_cdWriteCharCode := F_cdReadCharCode; F_bSectionModified := False; F_bModified := False; F_sFileName := sFileName; F_slSectionIndex := TMyWStrings.Create; //セクションのインデックスを記録するリスト F_slSectionData := TMyWStrings.Create; //特定のセクションの中身を記録するリスト  F_sSection := ''; //編集・読み込み対象のセクション名 F_slList := TMyWStrings.Create; //iniファイルを読み込むリスト F_SetFileName(sFileName); end; destructor TMyIniFile.Destroy; begin UpdateFile; F_slList.Free; F_slSectionIndex.Free; F_slSectionData.Free; inherited; end; procedure TMyIniFile.F_SetFileName(sFileName: WideString); begin if (gfnbFileExists(F_sFileName)) then begin //デフォルトの文字コードはUTF-8なのでそれ以外の場合はFileNameを指定せずCreate //してCharCodeをセットしてからFileNameをセットする必要がある F_slList.LoadFromFile(F_sFileName, F_cdReadCharCode); F_ReadSectionIndex; end; end; //Section procedure TMyIniFile.F_ReadSectionIndex; //セクションのインデックスをF_slSectionsIndexリストに記録する。 var i, li_Count: Integer; ls_Item, ls_Section: WideString; begin { セクションの条件は 半角スペース・タブを除く一文字目が'['であり、 ']'との間に半角スペース・タブ以外の一文字以上あること } F_slSectionIndex.Clear; for i := 0 to F_slList.Count - 1 do begin ls_Item := Trim(F_slList[i]); if (Pos('[', ls_Item) = 1) then begin //最初の文字が'['である。 ls_Item := TrimLeft(Copy(ls_Item, 2, MaxInt)); //TrimLeftはWideString対応 li_Count := Pos(']', ls_Item); if (li_Count >= 2) then begin //'['を取り除いた後で']'が現れるのは2文字以降。 //セクションは'['と']'の間に半角スペース・タブ以外の1文字以上必要。 ls_Section := Trim(Copy(ls_Item, 1, li_Count - 1)); if (ls_Section <> '') then begin //セクション#1インデックスで記録。 F_slSectionIndex.Add(WideFormat('%s'#1'%d', [ls_Section, i])); end; end; end; end; end; procedure TMyIniFile.F_UpdateSection; begin if (F_bSectionModified) then begin //編集対象となっていたセクションをリストに反映させる F_WriteSectionText(F_sSection, F_slSectionData, False); F_ReadSectionIndex; F_bSectionModified := False; end; end; { 2008-12-11:F_ReadSectionに統合 処理内容はUpdateSectionじゃないし… procedure TMyIniFile.F_UpdateSection(const sSection: WideString); //特定のsSectionをリストに反映させる begin if (F_sSection <> '') then begin if (WideCompareText(F_sSection, Trim(sSection)) <> 0) then begin F_UpdateSection; F_ReadSectionText(sSection, F_slSectionText, False); F_sSection := Trim(sSection); end; end else begin F_ReadSectionText(sSection, F_slSectionText, False); F_sSection := Trim(sSection); end; end; } function TMyIniFile.F_fnbSectionExists(sSection: WideString; out iStart, iEnd: Integer): Boolean; var i, li_Index: Integer; begin li_Index := -1; for i := 0 to F_slSectionIndex.Count -1 do begin if (WideCompareText(gfnsIniNameGet(F_slSectionIndex[i], #1), Trim(sSection)) = 0) then begin li_Index := i; Break; end; end; if (li_Index >= 0) then begin Result := True; //iStartはセクション名のあるインデックス。 iStart := gfniStrToInt(gfnsIniValueGet(F_slSectionIndex[li_Index], #1)); if (li_Index = F_slSectionIndex.Count - 1) then begin iEnd := F_slList.Count - 1 end else begin //次のセクションのインデックスのひとつ前 iEnd := gfniStrToInt(gfnsIniVAlueGet(F_slSectionIndex[li_Index + 1], #1)) - 1; end; end else begin Result := False; iStart := -1; iEnd := -1; end; end; procedure TMyIniFile.F_DeleteSection(sSection: WideString); var i, li_Start, li_End: Integer; begin if (F_fnbSectionExists(sSection, li_Start, li_End)) then begin for i := li_End downto li_Start do begin F_slList.Delete(i); end; if (WideCompareText(F_sSection, Trim(sSection)) = 0) then begin // F_slSectionList.Clear;// <- NG F_sSection := ''; end; end; end; procedure TMyIniFile.F_ReadSectionText(sSection: WideString; slStrings: TMyWStrings; bText: Boolean); //セクションの中身をリストに読み込む procedure lpc_ReadValues(slList: TMyWStrings); var i: Integer; ls_Key: WideString; lsl_Key: TMyWStrings; begin lsl_Key := TMyWStrings.Create; try for i := slList.Count -1 downto 0 do begin if (Trim(slList[i]) = '') then begin //空行は削除 slList.Delete(i); end else begin ls_Key := slList.Names[i]; if (ls_Key = '') //キーが空文字なら削除 or (gfnbIsIncludeList(ls_Key, lsl_Key)) //重複キーは削除 then begin slList.Delete(i); end else begin lsl_Key.Add(ls_Key); //重複キーを避けるため end; end; end; finally lsl_Key.Free; end; end; var i, li_Start, li_End: Integer; begin if (WideCompareText(F_sSection, Trim(sSection)) = 0) then begin slStrings.Assign(F_slSectionData); end else if (F_fnbSectionExists(sSection, li_Start, li_End)) then begin slStrings.Clear; for i := li_Start +1 to li_End do begin //li_Startはセクションのインデックスであるため+1 slStrings.Add(F_slList[i]); end; end else begin //セクションはない // if not(bText) then begin 2008-12-11:これは間違いであろうということでコメントアウト slStrings.Clear; // end; end; if (slStrings.Count > 0) and not(bText) then begin //テキストとしてではなくINIデータとして読み込む //重複、空行、無効なKeyは削除 lpc_ReadValues(slStrings); end; end; procedure TMyIniFile.F_WriteSectionText(sSection: WideString; slStrings: TMyWStrings; bText: Boolean); { リストの内容をセクションにそのまま書き込む //sSectionにconstはつけない。 //つけると呼び出し側で F_WriteSectionText(slList[0], slList) などとした場合この関数 //内で書き換えられてしまいおかしなことになる。 } var i: Integer; ls_Key: WideString; lsl_Key: TMyWStrings; //重複キーを裂けるため begin F_bModified := True; if (SectionExists(sSection)) then begin F_DeleteSection(sSection); end; F_slList.Add(WideFormat('[%s]', [sSection])); if (bText) then begin //空行や空文字のキー、重複キーも含めslStringsの内容をそのまま追加 for i := 0 to slStrings.Count -1 do begin F_slList.Add(slStrings[i]); end; end else begin lsl_Key := TMyWStrings.Create; try for i := 0 to slStrings.Count -1 do begin if (Trim(slStrings[i]) <> '') then begin //空行は追加しない ls_Key := slStrings.Names[i]; if (ls_Key <> '') //キーが空文字は追加しない and (gfnbIsIncludeList(ls_Key, lsl_Key) = False) //重複キーは追加しない then begin lsl_Key.Add(ls_Key); //重複キーを避けるため F_slList.Add(slStrings[i]); end; end; end; finally lsl_Key.Free; end; F_slList.Add(''); end; F_bSectionModified := False; F_ReadSectionIndex; end; procedure TMyIniFile.F_ReadSectionValues(sSection: WideString); //F_slSectionData begin if (F_sSection <> '') then begin //セクションは読み込まれている if (WideCompareText(F_sSection, Trim(sSection)) <> 0) then begin //読み込まれているセクションはsSectionではないので新たに読み込む F_UpdateSection; //読み込まれているセクションをリストに反映させる F_ReadSectionText(sSection, F_slSectionData, False); //テキストとしてではなくINIデータとして読み込む F_sSection := Trim(sSection); end; end else begin //初めてセクションを読み込む F_ReadSectionText(sSection, F_slSectionData, False); F_sSection := Trim(sSection); end; end; //------------------------------------------------------------------------------ //public function TMyIniFile.UpdateFile: Boolean; var li_ErrMode : UINT; begin Result := False; if (F_bModified) then begin F_UpdateSection; if (F_bDebug) then begin // myDebug.gpcDebugAdd(F_slList.AnsiStrings); end else begin li_ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS); try F_slList.SaveToFile(F_sFileName, F_cdWriteCharCode); Result := True; except end; SetErrorMode(li_ErrMode); end; F_bModified := False; end; end; function TMyIniFile.SectionExists(sSection: WideString): Boolean; var li_Start, li_End: Integer; begin Result := F_fnbSectionExists(sSection, li_Start, li_End); end; procedure TMyIniFile.ReadSections(slStrings: TMyWStrings); //ReadSections メソッドは,INI ファイルにあるすべてのセクションの名前を文字列リストに読み出します。 var i: Integer; begin slStrings.Clear; for i := 0 to F_slSectionIndex.Count - 1 do begin slStrings.Add(gfnsIniNameGet(F_slSectionIndex[i], #1)); end; end; procedure TMyIniFile.ReadSection(sSection: WideString; slStrings: TMyWStrings); //ReadSection メソッドは,INI ファイルの指定のセクションからすべてのキーの名前を文字列リストに読み出します。 var i: Integer; begin F_ReadSectionText(sSection, slStrings, False); for i := 0 to slStrings.Count - 1 do begin slStrings[i] := gfnsIniNameGet(slStrings[i], '='); end; end; procedure TMyIniFile.EraseSection(sSection: WideString); begin if (SectionExists(sSection)) then begin F_bModified := True; F_DeleteSection(sSection); F_ReadSectionIndex; end; end; procedure TMyIniFile.WriteSection(sSection: WideString); //セクションだけ書き込む begin if not(SectionExists(sSection)) and (CompareText(F_sSection, sSection) <> 0) then begin F_bModified := True; F_slList.Add(WideFormat('[%s]', [sSection])); F_slList.Add(''); end; end; //SectionValues procedure TMyIniFile.ReadSectionValues(sSection: WideString; slStrings: TMyWStrings); //無効な行、キー、重複キーを削除して読み込む begin F_ReadSectionText(sSection, slStrings, False); end; procedure TMyIniFile.WriteSectionValues(sSection: WideString; slStrings: TMyWStrings); //無効な行、キー、重複キーを削除して書き込む begin F_WriteSectionText(sSection, slStrings, False); end; procedure TMyIniFile.ReadSectionValues(sSection: WideString; slStrings: TStrings); //無効な行、キー、重複キーを削除して読み込む var lsl_List: TMyWStrings; begin lsl_List := TMyWStrings.Create(slStrings); try F_ReadSectionText(sSection, lsl_List, False); finally lsl_List.Free; end; end; procedure TMyIniFile.WriteSectionValues(sSection: WideString; slStrings: TStrings); //無効な行、キー、重複キーを削除して読み込む var lsl_List: TMyWStrings; begin lsl_List := TMyWStrings.Create(slStrings); try F_WriteSectionText(sSection, lsl_List, False); finally lsl_List.Free; end; end; //SectionText procedure TMyIniFile.ReadSectionText(sSection: WideString; slStrings: TMyWStrings); //セクションの中身をリストにそのまま読み込む begin F_ReadSectionText(sSection, slStrings, True); end; procedure TMyIniFile.WriteSectionText(sSection: WideString; slStrings: TMyWStrings); { リストの内容をセクションにそのまま書き込む sSectionにconstはつけない。 つけると呼び出し側で WriteSectionText(slList[0], slList) などとした場合この関数 内で書き換えられてしまいおかしなことになる。 } begin F_bModified := True; F_UpdateSection; //2008-12-11:必要なかろうということでコメントアウトしたらだめだった。やっぱこれ必要! F_WriteSectionText(sSection, slStrings, True); end; procedure TMyIniFile.ReadSectionText(sSection: WideString; slStrings: TStrings); //セクションの中身をリストにそのまま読み込む var lsl_List: TMyWStrings; begin lsl_List := TMyWStrings.Create(slStrings); try F_ReadSectionText(sSection, lsl_List, True); finally lsl_List.Free; end; end; procedure TMyIniFile.WriteSectionText(sSection: WideString; slStrings: TStrings); { リストの内容をセクションにそのまま書き込む sSectionにconstはつけない。 } var lsl_List: TMyWStrings; begin lsl_List := TMyWStrings.Create(slStrings); try WriteSectionText(sSection, lsl_List); finally lsl_List.Free; end; end; //------------------------------------------------------------------------------ function TMyIniFile.ReadString(sSection, sKey, sDefault: WideString): WideString; var li_Index: Integer; begin F_ReadSectionValues(sSection); li_Index := F_slSectionData.IndexOfName(sKey); if (li_Index < 0) then begin Result := sDefault; end else begin Result := gfnsIniValueGet(F_slSectionData[li_Index]); if (Result = '') then Result := sDefault; end; end; procedure TMyIniFile.WriteString(sSection, sKey, sValue: WideString); var li_Index: Integer; ls_Item: WideString; begin F_bModified := True; F_ReadSectionValues(sSection); F_bSectionModified := True; ls_Item := WideFormat('%s=%s', [Trim(sKey), sValue]); li_Index := F_slSectionData.IndexOfName(sKey); if (li_Index < 0) then begin F_slSectionData.Add(ls_Item); end else begin F_slSectionData[li_Index] := ls_Item; end; end; function TMyIniFile.ReadInteger(sSection, sKey: WideString; iDefault: Longint): Longint; begin Result := gfniStrToInt(ReadString(sSection, sKey, IntToStr(iDefault))); end; procedure TMyIniFile.WriteInteger(sSection, sKey: WideString; iValue: Longint); begin WriteString(sSection, sKey, IntToStr(iValue)); end; function TMyIniFile.ReadFloat(sSection, sKey: WideString; fDefault: Extended): Extended; begin try Result := StrToFloat(ReadString(sSection, sKey, FloatToStr(fDefault))); except Result := 0.0; end; end; procedure TMyIniFile.WriteFloat(sSection, sKey: WideString; fValue: Extended); begin WriteString(sSection, sKey, FloatToStr(fValue)); end; function TMyIniFile.ReadBool(sSection, sKey: WideString; bDefault: Boolean): Boolean; begin Result := (ReadInteger(sSection, sKey, Ord(bDefault)) <> 0); end; procedure TMyIniFile.SetBool(sSection, sKey : WideString; var bValue : Boolean); begin bValue := (ReadInteger(sSection, sKey, Ord(bValue)) <> 0); end; procedure TMyIniFile.WriteBool(sSection, sKey: WideString; bValue: Boolean); begin WriteInteger(sSection, sKey, Ord(bValue)); end; { //SetBounds用 function TMyIniFile.ReadBounds(const sSection, sName: WideString; szDefault: TMyBounds): TMyBounds; begin with Result do begin Left := ReadInteger(sSection, sName + lcsBOUNDS_LEFT, szDefault.Left); Top := ReadInteger(sSection, sName + lcsBOUNDS_TOP, szDefault.Top); Width := ReadInteger(sSection, sName + lcsBOUNDS_WIDTH, szDefault.Width); Height := ReadInteger(sSection, sName + lcsBOUNDS_HEIGHT, szDefault.Height); end; end; procedure TMyIniFile.WriteBounds(const sSection, sName: WideString; szValue: TMyBounds); begin with szValue do begin WriteInteger(sSection, sName + lcsBOUNDS_LEFT, Left); WriteInteger(sSection, sName + lcsBOUNDS_TOP, Top); WriteInteger(sSection, sName + lcsBOUNDS_WIDTH, Width); WriteInteger(sSection, sName + lcsBOUNDS_HEIGHT, Height); end; end; function TMyIniFile.ReadBounds(const sSection: WideString; Control: TControl): TMyBounds; begin with Result do begin Left := ReadInteger(sSection, Control.Name + lcsBOUNDS_LEFT, Control.Left); Top := ReadInteger(sSection, Control.Name + lcsBOUNDS_TOP, Control.Top); Width := ReadInteger(sSection, Control.Name + lcsBOUNDS_WIDTH, Control.Width); Height := ReadInteger(sSection, Control.Name + lcsBOUNDS_HEIGHT, Control.Height); end; end; procedure TMyIniFile.WriteBounds(const sSection: WideString; Control: TControl); begin with Control do begin WriteInteger(sSection, Name + lcsBOUNDS_LEFT, Left); WriteInteger(sSection, Name + lcsBOUNDS_TOP, Top); WriteInteger(sSection, Name + lcsBOUNDS_WIDTH, Width); WriteInteger(sSection, Name + lcsBOUNDS_HEIGHT, Height); end; end; function TMyIniFile.ReadBounds(Control: TControl): TMyBounds; begin Result := ReadBounds(gcsSECT_BOUNDS, Control); end; procedure TMyIniFile.WriteBounds(Control: TControl); begin WriteBounds(gcsSECT_BOUNDS, Control); end; } //BoundsRect procedure TMyIniFile.WriteBoundsRect(sSection, sKey: WideString; rcRect: TRect); begin WriteRect(sSection, sKey, rcRect); end; function TMyIniFile.ReadBoundsRect (sSection: WideString; AControl: TControl): TRect; begin Result := ReadRect(sSection, AControl.Name, AControl.BoundsRect); end; procedure TMyIniFile.WriteBoundsRect(sSection: WideString; AControl: TControl); begin WriteRect(sSection, AControl.Name, AControl.BoundsRect); end; function TMyIniFile.ReadBoundsRect(AControl: TControl): TRect; begin Result := ReadRect(gcsSECT_BOUNDS, AControl.Name, AControl.BoundsRect); end; procedure TMyIniFile.WriteBoundsRect(AControl: TControl); begin WriteRect(gcsSECT_BOUNDS, AControl.Name, AControl.BoundsRect); end; //FormのBoundsRect モニター内に納まるようなBoundsRectを返す function TMyIniFile.ReadMonitorBoundsRect(sSection: WideString; AForm: TForm): TRect; var lrc_WorkAreaRect: TRect; li_Left, li_Top, li_FormWidth, li_FormHeight, li_WorkAreaWidth, li_WorkAreaHeight: Integer; begin Result := ReadBoundsRect(sSection, AForm); li_FormWidth := gfniRectWidth(Result); li_FormHeight := gfniRectHeight(Result); // lrc_WorkAreaRect := myMonitor.gfnrcMonitorWorkAreaRectGet(Result); lrc_WorkAreaRect := gfnrcMonitorWorkAreaRectGet(Result); li_WorkAreaWidth := gfniRectWidth(lrc_WorkAreaRect); li_WorkAreaHeight := gfniRectHeight(lrc_WorkAreaRect); if (li_FormWidth >= li_WorkAreaWidth) then begin li_Left := lrc_WorkAreaRect.Left; end else begin li_Left := gfniNumLimit(Result.Left, lrc_WorkAreaRect.Left, lrc_WorkAreaRect.Left + li_WorkAreaWidth - li_FormWidth); end; if (li_FormHeight >= li_WorkAreaHeight) then begin li_Top := lrc_WorkAreaRect.Top; end else begin li_Top := gfniNumLimit(Result.Top, lrc_WorkAreaRect.Top, lrc_WorkAreaRect.Top + li_WorkAreaHeight - li_FormHeight); end; Result := Rect(li_Left, li_Top, li_Left + li_FormWidth, li_Top + li_FormHeight); end; function TMyIniFile.ReadMonitorBoundsRect(AForm: TForm): TRect; begin Result := ReadMonitorBoundsRect(gcsSECT_BOUNDS, AForm); end; //FormのBoundsRect モニター内に納まるようにセットする procedure TMyIniFile.SetMonitorBoundsRect(sSection: WideString; AForm: TForm); {2009-01-20: } begin AForm.BoundsRect := ReadMonitorBoundsRect(sSection, AForm); end; procedure TMyIniFile.SetMonitorBoundsRect(AForm: TForm); {2009-01-20: } begin SetMonitorBoundsRect(gcsSECT_BOUNDS, AForm); end; //TRect function TMyIniFile.ReadRect(sSection, sKey: WideString; rcDefault: TRect): TRect; begin with Result do begin Left := ReadInteger(sSection, sKey + gcsKEY_RECT_LEFT, rcDefault.Left); Top := ReadInteger(sSection, sKey + gcsKEY_RECT_TOP, rcDefault.Top); Right := ReadInteger(sSection, sKey + gcsKEY_RECT_RIGHT, rcDefault.Right); Bottom := ReadInteger(sSection, sKey + gcsKEY_RECT_BOTTOM, rcDefault.Bottom); end; end; procedure TMyIniFile.WriteRect(sSection, sKey: WideString; rcValue: TRect); begin with rcValue do begin WriteInteger(sSection, sKey + gcsKEY_RECT_LEFT, Left); WriteInteger(sSection, sKey + gcsKEY_RECT_TOP, Top); WriteInteger(sSection, sKey + gcsKEY_RECT_RIGHT, Right); WriteInteger(sSection, sKey + gcsKEY_RECT_BOTTOM, Bottom); end; end; //TPoint function TMyIniFile.ReadPoint(sSection, sKey: WideString; ptDefault: TPoint): TPoint; begin with Result do begin X := ReadInteger(sSection, sKey + gcsKEY_POINT_X, ptDefault.X); Y := ReadInteger(sSection, sKey + gcsKEY_POINT_Y, ptDefault.Y); end; end; procedure TMyIniFile.WritePoint(sSection, sKey: WideString; ptValue: TPoint); begin with ptValue do begin WriteInteger(sSection, sKey + gcsKEY_POINT_X, X); WriteInteger(sSection, sKey + gcsKEY_POINT_Y, Y); end; end; //TSize function TMyIniFile.ReadSize (sSection, sKey: WideString; szDefault: TSize): TSize; begin with Result do begin cx := ReadInteger(sSection, sKey + gcsKEY_SIZE_CX, szDefault.cx); cy := ReadInteger(sSection, sKey + gcsKEY_SIZE_CY, szDefault.cy); end; end; procedure TMyIniFile.WriteSize(sSection, sKey: WideString; szValue: TSize); begin with szValue do begin WriteInteger(sSection, sKey + gcsKEY_SIZE_CX, cx); WriteInteger(sSection, sKey + gcsKEY_SIZE_CY, cy); end; end; //TFont procedure TMyIniFile.SetFont(sSection, sKey: WideString; Font: TFont); var l_Style: TFontStyles; begin with Font do begin Name := ReadString (sSection, sKey + gcsKEY_FONT_NAME, Name); Size := ReadInteger(sSection, sKey + gcsKEY_FONT_SIZE, Size); Color := TColor(ReadInteger(sSection, sKey + gcsKEY_FONT_COLOR, Color)); l_Style := Style; Style := []; if (ReadBool(sSection, sKey + gcsKEY_FONT_STYLEBOLD, fsBold in l_Style)) then Style := Style + [fsBold]; if (ReadBool(sSection, sKey + gcsKEY_FONT_STYLEITALIC, fsItalic in l_Style)) then Style := Style + [fsItalic]; if (ReadBool(sSection, sKey + gcsKEY_FONT_STYLEUNDERLINE, fsUnderLine in l_Style)) then Style := Style + [fsUnderLine]; if (ReadBool(sSection, sKey + gcsKEY_FONT_STYLESTRIKEOUT, fsStrikeOut in l_Style)) then Style := Style + [fsStrikeOut]; Charset := TFontCharset(gfniNumLimit(ReadInteger(sSection, sKey + gcsKEY_FONT_CHARSET, Charset), 0, High(TFontCharset))); end; end; procedure TMyIniFile.WriteFont(sSection, sKey: WideString; Font: TFont); begin with Font do begin WriteString (sSection, sKey + gcsKEY_FONT_NAME, Name); WriteInteger(sSection, sKey + gcsKEY_FONT_SIZE, Size); WriteInteger(sSection, sKey + gcsKEY_FONT_COLOR, Color); WriteBool (sSection, sKey + gcsKEY_FONT_STYLEBOLD, fsBold in Style); WriteBool (sSection, sKey + gcsKEY_FONT_STYLEITALIC, fsItalic in Style); WriteBool (sSection, sKey + gcsKEY_FONT_STYLEUNDERLINE, fsUnderLine in Style); WriteBool (sSection, sKey + gcsKEY_FONT_STYLESTRIKEOUT, fsStrikeOut in Style); WriteInteger(sSection, sKey + gcsKEY_FONT_CHARSET, Charset); end; end; procedure TMyIniFile.SetFont(sSection, sKey: WideString; Control: TControl); var l_Font: TFont; begin //ControlがpublishedにFontプロパティを持っていればそれを引き継ぐ if (IsPublishedProp(Control, 'Font')) then begin l_Font := TFont(GetObjectProp(Control, 'Font')); SetFont(sSection, sKey, l_Font); end; end; procedure TMyIniFile.SetFont(sSection: WideString; Control: TControl); begin SetFont(sSection, Control.Name, Control); end; procedure TMyIniFile.WriteFont(sSection, sKey: WideString; Control: TControl); var l_Font: TFont; begin //TargetがpublishedにFontプロパティを持っていればそれを引き継ぐ if (IsPublishedProp(Control, 'Font')) then begin l_Font := TFont(GetObjectProp(Control, 'Font')); WriteFont(sSection, sKey, l_Font); end; end; procedure TMyIniFile.WriteFont(sSection: WideString; Control: TControl); begin WriteFont(sSection, Control.Name, Control); end; //------------------------------------------------------------------------------ //IniFile function gfnsIniNameGet(sItem: WideString): WideString; begin Result := gfnsIniNameGet(sItem, '='); end; function gfnsIniNameGet(sItem, sSep: WideString): WideString; overload; {2008-08-28: } var li_Pos: Integer; begin if (sItem <> '') then begin li_Pos := Pos(sSep, sItem); if (li_Pos <= 1) then begin Result := ''; end else begin Result := Trim(Copy(sItem, 1, li_Pos - 1)); end; end else begin Result := ''; end; end; function gfnsIniValueGet(sItem: WideString): WideString; begin Result := gfnsIniValueGet(sItem, '='); end; function gfnsIniValueGet(sItem, sSep: WideString): WideString; overload; {2008-08-28: } var li_Pos: Integer; begin if (sItem <> '') then begin li_Pos := Pos(sSep, sItem); if (li_Pos = 0) then begin Result := sItem; end else begin Result := Copy(sItem, li_Pos + Length(sSep), MaxInt); end; end else begin Result := ''; end; end; procedure gpcIniNameValueDiv(sItem: WideString; out sName, sValue: WideString); begin gpcIniNameValueDiv(sItem, '=', sName, sValue); end; procedure gpcIniNameValueDiv(sItem, sSep: WideString; out sName, sValue: WideString); overload; {2008-08-28: } begin sName := gfnsIniNameGet(sItem, sSep); sValue := gfnsIniValueGet(sItem, sSep); end; end.