unit general; //{$DEFINE DEBUG} interface uses ActnList, Classes, Clipbrd, Dialogs, Grids, TlHelp32, Windows, Graphics, //Windowsの後にしないとだめ SysUtils; //myWindow.pas function gfnptMousePosGet: TPoint; function gfnptClientMousePosGet(hHandle: HWND): TPoint; function gfnbKeyState(iKey: Integer): Boolean; function gfnsClassNameGet(hHandle: HWND): String; function gfnsWindowTextGet(hHandle: HWND): WideString; function gfnhWindowGet(APoint : TPoint): HWND;// overload; function gfnhParentWindowGet(hHandle: HWND): HWND; function gfnsExeNameGet(hHandle: HWND): WideString; overload; function gfnrcWindowRectGet(hHandle: HWND): TRect; function gfnrcClientRectGet(hHandle: HWND): TRect; function gfnptScreenToClient(hHandle: HWND; ptPos: TPoint): TPoint; function gfnsOsNameGet: WideString; function gfnbAeroThemeEnableSet(bEnable: Boolean): Boolean; function gfnbIsAeroThemeEnabled: Boolean; function gfnbIsAeroThemeReady: Boolean; function gfnbIsAlphaBlendReady: Boolean; function gfnbGetLayeredWindowAttributes(hHandle: HWND; var crKey: COLORREF; var bAlpha: BYTE; var dwFlags: DWORD): Boolean; //myNum.pas function gfniStrToInt(sNum: String): Int64; function gfniRound(fNum: Extended): Int64; function gfniRoundUp(fNum: Extended): Int64; function gfniNumLimit(iNum: Integer; iMin, iMax: Integer): Integer; function gfniNumLoop(iNum: Integer; iMin, iMax: Integer): Integer; function gfniMax(iNum: array of Integer): Integer; function gfniMin(iNum: array of Integer): Integer; //mySize.pas function gfniRectWidth (rtRect: TRect): Integer; function gfniRectHeight(rtRect: TRect): Integer; function gfnrcRectCenter(rcParent, rcChild: TRect): TRect; function gfnrcRectShift (rcRect: TRect; ptShift: TPoint): TRect; overload; function gfnbCompleteRectInRect(rcCheck, rcRect: TRect): Boolean; function gfnbRectInRect(rcCheck, rcRect: TRect): Boolean; function gfnsCompasGet(ptStart, ptPos: TPoint): String; //myFile.pas function gfnsShortFileNameGet(sFile : WideString) : WideString; function gfnsWorkFileNameGet (sExt : WideString) : WideString; function gfnsFileNameGet (sFile : WideString) : WideString; function gfnsFileExtChange(sFile, sExt: WideString): WideString; function gfnsExeNameGet: WideString; overload; function gfnbFileExists(sFile: WideString): Boolean; function gfniFileSizeGet(hHandle: THandle): Int64; function gfnsFileVersionGet(sFile: WideString): WideString; overload; function gfnsProductNameGet(sFile: WideString): WideString; overload; function gfnsFileVersionGet: WideString; overload; function gfnsProductNameGet: WideString; overload; procedure gpcFileWriteText(sFile, sText: WideString); procedure gpcExecute(sFile: WideString); //myGraphic.pas type TMyBitmap = class(TBitmap) public procedure SaveToFile(const Filename: WideString); reintroduce; end; function gfnclColorRevers(clColor: TColor): TColor; procedure gpcColorRGBToHLS(iRed, iGreen, iBlue: BYTE; var iHue, iLuminance, iSaturation: WORD; iMaxHue, iMaxLuminance, iMaxSaturation: WORD); overload; procedure gpcColorRGBToHLS(iRed, iGreen, iBlue: BYTE; var iHue, iLuminance, iSaturation: WORD); overload; procedure gpcColorRGBToHSV(iRed, iGreen, iBlue: BYTE; var iHue, iValue, iSaturation: WORD; iMaxHue, iMaxValue, iMaxSaturation: WORD); //myControl.pas //function gfnrcClientOriginRect(Control: TControl): TRect; function gfnsAvailableName(sPrefix: String): String; //myClipbrd.pas procedure gpcStrToClipboard(sStr : WideString); //myList.pas function gfnbIsIncludeList(sValue: String; slList: TStrings): Boolean; overload; function gfnbIsIncludeList(sValue: String; slList: array of String): Boolean; overload; //myMessageBox //function gfniMessageBoxYesNo(const sMsg, sTitle: String): Integer; function gfniMessageBoxYesNo(sMsg: String; sTitle: String = ''; DefaultButton: TMsgDlgBtn = mbYes): Word; procedure gpcShowMessage(sMsg: String; sTitle: String = ''); //myString.pas function gfnbIsUnicode(sSrc: WideString): Boolean; function gfnsWideToUtf7(sSrc: WideString): AnsiString; //function gfnsUtf7ToWide(sSrc: AnsiString): WideString; function gfnsWideToUtf8(sSrc: WideString): Utf8String; function gfnsUtf8ToWide(sSrc: Utf8String): WideString; function gfnsWideToAnsi(sSrc: WideString): AnsiString; //myGrid function gfniGridCanvasTextWidthGet(Grid: TDrawGrid; sText: WideString): Integer; //スタイル function gfnbStyleCheck(iStyle: Longint; iCheck: Longint): Boolean; //ショートカット function gfnsCommandDescriptionGet(AAction: TAction): String; function gfnsCommandHintGet(AAction: TAction): String; var G_bIsNtOs: Boolean = False; //============================================================================== implementation uses {$IFDEF DEBUG} myDebug, {$ENDIF} Controls, Forms, GraphUtil, Menus, Messages, PsAPI, RTLConsts, ShellAPI, StdCtrls, main; //myWindow.pas ----------------------------------------------------------------- function gfnbIsNtOs: Boolean; //OSがNT系ならTrueを返す var lr_Info: TOSVersionInfo; begin Result := False; FillChar(lr_Info, SizeOf(lr_Info), 0); lr_Info.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);; if (GetVersionEx(lr_Info)) then begin Result := (lr_Info.dwPlatformId = VER_PLATFORM_WIN32_NT); end; end; function gfnsSystem32DirGet: WideString; var li_Size : UINT; lp_WBuff : PWideChar; lp_ABuff : PAnsiChar; begin Result := ''; if (gfnbIsNtOs) then begin li_Size := GetSystemDirectoryW(nil, 0); if (li_Size > 0) then begin lp_WBuff := AllocMem(li_Size * 2); try li_Size := GetSystemDirectoryW(lp_WBuff, li_Size); if (li_Size > 0) then begin Result := WideString(lp_WBuff) + '\'; end; finally FreeMem(lp_WBuff); end; end; end else begin li_Size := GetSystemDirectoryA(nil, 0); if (li_Size > 0) then begin lp_ABuff := AllocMem(li_Size); try li_Size := GetSystemDirectoryA(lp_ABuff, li_Size); if (li_Size > 0) then begin Result := AnsiString(lp_ABuff) + '\'; end; finally FreeMem(lp_ABuff); end; end; end; end; //http://www.delphipraxis.net/142052-getlayeredwindowattributes-funktioniert-nicht-noch-resize.html //function GetLayeredWindowAttributes(hwnd: HWND; var crKey: COLORREF; var bAlpha: BYTE; var dwFlags: DWORD): BOOL; stdcall; external user32 name 'GetLayeredWindowAttributes'; type TGetLayeredWindowAttributes = function(hwnd: HWND; var crKey: COLORREF; var bAlpha: BYTE; var dwFlags: DWORD): BOOL; stdcall; function gfnbGetLayeredWindowAttributes(hHandle: HWND; var crKey: COLORREF; var bAlpha: BYTE; var dwFlags: DWORD): Boolean; {2015-03-10: } var ls_Path : WideString; lh_Module : HMODULE; l_GetLayeredWindowAttributes : TGetLayeredWindowAttributes; begin Result := False; ls_Path := gfnsSystem32DirGet; lh_Module := LoadLibraryW(PWideChar(ls_Path + 'user32.dll')); if (lh_Module <> 0) then begin try // GetLayeredWindowAttributes ?????????? @l_GetLayeredWindowAttributes := GetProcAddress(lh_Module, 'GetLayeredWindowAttributes'); if (@l_GetLayeredWindowAttributes <> nil) then begin Result := l_GetLayeredWindowAttributes( hHandle, crKey, bAlpha, dwFlags ); end; finally FreeLibrary(lh_Module); end; end; end; function gfnptMousePosGet: TPoint; //マウスカーソルの位置をスクリーン座標で返す begin Result := Point(0, 0); GetCursorPos(Result); end; function gfnptClientMousePosGet(hHandle: HWND): TPoint; {2008-12-04: 現在のマウスカーソルの位置をウィンドウのクライアント座標で返す。 } begin Result := gfnptMousePosGet; Windows.ScreenToClient(hHandle, Result); end; function gfnbKeyState(iKey: Integer): Boolean; var li_Check: SHORT; begin //左右ボタンを入れ替えている場合に対処 if (GetSystemMetrics(SM_SWAPBUTTON) <> 0) then begin if (iKey = VK_LBUTTON) then begin iKey := VK_RBUTTON; end else if (iKey = VK_RBUTTON) then begin //2009-02-04:VK_RUBTTONとしたままだったのを修正。 iKey := VK_LBUTTON; end; end; li_Check := GetAsyncKeyState(iKey); //Result := BOOL(Hi(li_Check)) and (BOOL(Lo(li_Check))); Result := BOOL(Hi(li_Check)); end; function gfnsClassNameGet(hHandle: HWND): String; //ウィンドウハンドルhHandleのクラス名を返す const lci_LEN = 256; var lp_Buff: PChar; begin Result := ''; lp_Buff:= AllocMem(lci_LEN +1); try GetClassName(hHandle, lp_Buff, lci_LEN -1); Result := String(lp_Buff); finally FreeMem(lp_Buff); end; end; function gfnsWindowTextGetW(hHandle: HWND): WideString; const lci_MAXTEXTLEN = 256; var li_Len: DWORD; lp_Text: PWideChar; begin Result := ''; li_Len := GetWindowTextLengthW(hHandle) +1; if (li_Len > 0) then begin if (li_Len > lci_MAXTEXTLEN) then begin li_Len := lci_MAXTEXTLEN; end; lp_Text := AllocMem((li_Len +1) * 2); try GetWindowTextW(hHandle, lp_Text, li_Len); Result := WideString(lp_Text); finally FreeMem(lp_Text); end; end; if (Result <> '') then begin Exit; end; if (SendMessageTimeoutW(hHandle, WM_GETTEXTLENGTH, 0, 0, SMTO_ABORTIFHUNG, 500, li_Len) <> 0) then begin if (li_Len > 0) then begin li_Len := li_Len +1; if (li_Len > lci_MAXTEXTLEN) then begin li_Len := lci_MAXTEXTLEN; end; lp_Text := AllocMem((li_Len +1) * 2); try SendMessageTimeoutW(hHandle, WM_GETTEXT, WPARAM(li_Len), LPARAM(lp_Text), SMTO_ABORTIFHUNG, 500, li_Len); Result := WideString(lp_Text); finally FreeMem(lp_Text); end; end; end; end; function gfnsWindowTextGet(hHandle: HWND): WideString; //ウィンドウハンドルhHandleのテキスト(キャプション)を返す const lci_MAXTEXTLEN = 256; var li_Len: Integer; lp_Buff: PChar; begin Result := ''; if (G_bIsNtOs) then begin Result := gfnsWindowTextGetW(hHandle); end else begin li_Len := GetWindowTextLength(hHandle) +1; if (li_Len > 0) then begin if (li_Len > lci_MAXTEXTLEN) then begin li_Len := lci_MAXTEXTLEN; end; lp_Buff := AllocMem(li_Len +1); try GetWindowText(hHandle, lp_Buff, li_Len); Result := WideString(String(lp_Buff)); finally FreeMem(lp_Buff); end; end; end; end; function gfnptScreenToClient(hHandle: HWND; ptPos: TPoint): TPoint; {2009-03-08: ptPosをhHandleのウィンドウのクライアント座標で返す。 } begin Result := ptPos; ScreenToClient(hHandle, Result); end; //http://www.delphipraxis.net/159936-form-mit-bssingle-unter-aero-zu-gross.html //function DwmGetWindowAttribute(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HResult; stdcall; external 'Dwmapi.dll'; type TDwmGetWindowAttribute = function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HResult; stdcall; function gfnrcDwmWindowRectGet(hHandle: HWND): TRect; {2013-11-17,2015-03-06: } const DWMWA_EXTENDED_FRAME_BOUNDS = 9; var ls_Path : WideString; lh_Module : HMODULE; l_DwmGetWindowAttribute : TDwmGetWindowAttribute; li_Ret : HRESULT; begin Result := Rect(0, 0, 0, 0); ls_Path := gfnsSystem32DirGet; lh_Module := LoadLibraryW(PWideChar(ls_Path + 'Dwmapi.dll')); if (lh_Module <> 0) then begin try // DwmGetWindowAttribute の関数ポインタを取得 @l_DwmGetWindowAttribute := GetProcAddress(lh_Module, 'DwmGetWindowAttribute'); if (@l_DwmGetWindowAttribute <> nil) then begin li_Ret := l_DwmGetWindowAttribute( hHandle, DWMWA_EXTENDED_FRAME_BOUNDS, @Result, SizeOf(TRect) ); //2015-03-06 //トップレベルウィンドウ以外では失敗するようだ。 if not(Succeeded(li_Ret)) then begin GetWindowRect(hHandle, Result); end; end; finally FreeLibrary(lh_Module); end; end; end; function gfnrcWindowRectGet(hHandle: HWND): TRect; {2008-12-31: ウィンドウのRectを返す。 } begin Result := Rect(0, 0, 0, 0); if (gfnbIsAeroThemeEnabled) then begin Result := gfnrcDwmWindowRectGet(hHandle); end else begin GetWindowRect(hHandle, Result); end; end; function gfnrcClientRectGet(hHandle: HWND): TRect; begin if not(GetClientRect(hHandle, Result)) then begin FillChar(Result, SizeOf(Result), 0); end; end; (* type T_WinInfo = record Handle: HWND; Pos: TPoint; end; P_WinInfo = ^T_WinInfo; function gfnhToplevelWindowGetEx(ptPos: TPoint): HWND; {2009-01-11: ptPos上の可視のToplevelウィンドウを返す } function lfnb_MainWindowProc(hHandle: HWND; pInfo: P_WinInfo):BOOL; stdcall; //トップレベルウィンドウを列挙する begin if (PtInRect(gfnrcWindowRectGet(hHandle), pInfo^.Pos)) and (IsWindowVisible(hHandle)) //可視ウィンドウのみ then begin pInfo^.Handle := hHandle; Result := False; end else begin Result := True; end; end; var lr_Info: T_WinInfo; begin FillChar(lr_Info, SizeOf(lr_Info), 0); lr_Info.Pos := ptPos; EnumWindows(@lfnb_MainWindowProc, LPARAM(@lr_Info)); Result := lr_Info.Handle; end; function gfnhWindowGet(ptPos: TPoint): HWND; {2007-09-07,08,09,2009-03-08: ptPosの点上にある可視ウィンドウを返す。 2009-03-09: 非可視の子ウィンドウがあるとそこで処理を打ち切っていたため正しい値を取得できてい なかった不具合を修正。 2007-09-08: コールバック関数で最初に親とするウィンドウのハンドルがセットされるのに気づかなかっ たためl_hWinHandleの値をみてそれが0でなければ、、という処理で間違っていたのを対処。 とりあえず全部の子ウィンドウを対象にチェック。 } function lfnb_ChildWindowProc(hHandle: HWND; pInfo: P_WinInfo): BOOL; stdcall; var lrc_Rect: TRect; begin GetWindowRect(hHandle, lrc_Rect); if (IsWindowVisible(hHandle)) and (PtInRect(lrc_Rect, pInfo^.Pos)) then begin pInfo^.Handle := hHandle; //点が列挙された子ウィンドウの中にあった //それが可視ウィンドウであればとりあえずセットしておく(まだ確定ではない) //まだ可能性はあるので続ける end; Result := True; end; var lr_Info: T_WinInfo; lh_Handle: HWND; begin lh_Handle := WindowFromPoint(ptPos); if (lh_Handle = ChildWindowFromPoint(lh_Handle, gfnptScreenToClient(lh_Handle, ptPos))) then begin //WindowFromPoint関数とChildWindowFromPoint関数で同じハンドルが返ってくるのであればそれで良い。 Result := lh_Handle; end else begin FillChar(lr_Info, SizeOf(lr_Info), 0); lr_Info.Pos := ptPos; EnumChildWindows(gfnhTopLevelWindowGetEx(ptPos), @lfnb_ChildWindowProc, LPARAM(@lr_Info)); if (lr_Info.Handle = 0) then begin Result := lh_Handle; end else begin Result := lr_Info.Handle; end; end; end; *) //APoint上にある可視ウィンドウを返す。 type T_WinPos = record Handle : HWND; //調べる点の上にあるウィンドウ Point : TPoint; //この位置にある一番手前の見えているウィンドウを取得する end; P_WinPos = ^T_WinPos; function EnumChildProc(hHandle: HWND; pWinPos: Pointer): BOOL; stdcall; var lh_Parent : HWND; lrc_Rect : TRect; begin Result := True; GetWindowRect(hHandle, lrc_Rect); if (IsWindowVisible(hHandle)) and (PtInRect(lrc_Rect, T_WinPos(pWinPos^).Point)) then begin lh_Parent := GetAncestor(hHandle, GA_PARENT); if (lh_Parent = T_WinPos(pWinPos^).Handle) then begin //直前に列挙された対象ウィンドウの子ウィンドウだった //hWindowを書き換える //子ウィンドウがあるかもしれないので処理を続ける T_WinPos(pWinPos^).Handle:= hHandle; end else begin //親ウィンドウが同じなら兄弟ウィンドウ。 //しかし列挙されるのは手前のウィンドウからなのでその場合はhTopは書き換ず処理を抜ける。 //親ウィンドウが直前のウィンドウでもない //おじさんおばさんウィンドウ、あるいはさらに遡ってのウィンドウであるのでこれまたhTopを書き換えず処理を抜ける Result := False; end; end; end; function gfnhWindowGet(APoint : TPoint) : HWND; //APoint上にあり一番手前にある見えているウィンドウのハンドルを返す。 var l_WinPos : T_WinPos; lh_Window, lh_CWindow : HWND; lpt_Client : TPoint; begin //WindowFromPointはAPointが無効ウィンドウ上にある場合はトップレベルウィンドウのハンドルを返す。 lh_Window := WindowFromPoint(APoint); lpt_Client := APoint; Windows.ScreenToClient(lh_Window, lpt_Client); lh_CWindow := ChildWindowFromPointEx(lh_Window, lpt_Client, CWP_SKIPINVISIBLE or CWP_SKIPTRANSPARENT); if (lh_Window = lh_CWindow) then begin //WindowFromPointとChildWindowFromPointExの戻り値が同じならそれで良い。 Result := lh_Window; end else begin FillChar(l_WinPos, SizeOf(l_WinPos), 0); l_WinPos.Handle := lh_Window; l_WinPos.Point := APoint; EnumChildWindows(lh_Window, @EnumChildProc, LPARAM(@l_WinPos)); Result := l_WinPos.Handle; end; end; function gfnhParentWindowGet(hHandle: HWND): HWND; //親ウィンドウのウィンドウハンドルを返す begin Result := GetAncestor(hHandle, GA_PARENT); //親ウィンドウ。hHandleがトップレベルウィンドウの場合GetDesktopWindowの値が返る // Result := GetParent(hHandle); end; function gfniProcessIDGet(hHandle: HWND): DWORD; begin GetWindowThreadProcessId(hHandle, @Result); 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; {2007-12-11: ウィンドウハンドルから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 _System32DirGetW : 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 := WideString(lp_Buff) + '\'; end; finally FreeMem(lp_Buff); end; end; end; } var lh_Process : THandle; lp_Buff : PWideChar; i : Integer; li_Drives : DWORD; li_Flag : Integer; ls_Device : WideString; lp_Device : PWideChar; ls_Drv : WideString; lh_Module : HMODULE; l_GetProcessImageFileName : TGetProcessImageFileName; begin Result := ''; if not(G_bIsNtOs) then begin Exit; end; lh_Process := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, gfniProcessIDGet(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 //GetModuleFileNameExは32bitプロセスから64bitプロセスの実行ファイル名を取得できない。 //完全修飾パスを指定してPsapi.dllをロード lh_Module := LoadLibraryW(PWideChar(gfnsSystem32DirGet + '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); li_Drives := GetLogicalDrives; li_Flag := 1; for i := Ord('A') to Ord('Z') do begin if ((li_Drives and li_Flag) <> 0) then begin lp_Device := AllocMem((MAX_PATH +1) * SizeOf(WideChar)); try ls_Drv := Char(i) + ':'; QueryDosDeviceW(PWideChar(ls_Drv), lp_Device, MAX_PATH); ls_Device := WideString(lp_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; finally FreeLibrary(lh_Module); end; end; end; finally FreeMem(lp_Buff); end; finally CloseHandle(lh_Process); end; end; function gfnsOsNameGet: WideString; {2007-12-13: OSが'2000', 'XP', 'Vista'のいずれであるかを返す } var lr_Info: TOSVersionInfo; begin Result := 'Unknown'; FillChar(lr_Info, SizeOf(lr_Info), 0); lr_Info.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);; if (GetVersionEx(lr_Info)) then begin with lr_Info do begin if (dwPlatformId = VER_PLATFORM_WIN32_NT) then begin //NT系 if (dwMajorVersion = 7) then begin Result := '7'; end else if (dwMajorVersion = 6) then begin Result := 'Vista'; end else if (dwMajorVersion = 5) then begin if (dwMinorVersion = 0) then begin Result := '2000'; end else begin Result := 'XP'; end; end else if (dwMajorVersion = 4) or (dwMajorVersion = 3) then begin Result := 'NT'; end; end else if (dwPlatformId = VER_PLATFORM_WIN32_WINDOWS) then begin //9x系 if (dwMinorVersion = 9) then begin Result := 'me'; end else if (dwMinorVersion = 1) then begin Result := '98'; end else if (dwMinorVersion = 0) then begin Result := '95'; end; end else if (dwPlatformId = VER_PLATFORM_WIN32s) then begin //Windows 3.1上のWin32s Result := 'Win32s'; end; end; end; end; function gfnbAeroThemeEnableSet(bEnable: Boolean): Boolean; //http://www.delphipraxis.net/137018-vista-aero-effekt-deaktiveren.html //http://msdn.microsoft.com/en-us/library/windows/desktop/aa969510(v=vs.85).aspx const DWM_EC_DISABLECOMPOSITION = 0; DWM_EC_ENABLECOMPOSITION = 1; var ls_Path : WideString; lh_Module : HMODULE; l_DwmEnableComposition : function(uCompositionAction: UINT): HRESULT; stdcall; li_Ret : HResult; begin Result := False; ls_Path := gfnsSystem32DirGet; lh_Module := LoadLibraryW(PWideChar(ls_Path + 'Dwmapi.dll')); if (lh_Module <> 0) then begin try l_DwmEnableComposition := GetProcAddress(lh_Module, 'DwmEnableComposition'); if (@l_DwmEnableComposition <> nil) then begin if (bEnable) then begin li_Ret := l_DwmEnableComposition(DWM_EC_ENABLECOMPOSITION); end else begin li_Ret := l_DwmEnableComposition(DWM_EC_DISABLECOMPOSITION); end; Result := (li_Ret = S_OK); end; finally FreeLibrary(lh_Module); end; end; end; //function DwmIsCompositionEnabled(var bBool : BOOL) : HResult; stdcall external 'Dwmapi.dll'; function gfnbIsAeroThemeEnabled: Boolean; var ls_Path : WideString; lh_Module : HMODULE; lb_Bool : BOOL; l_DwmIsCompositionEnabled : function(var bBool: BOOL): HResult stdcall; begin Result := False; ls_Path := gfnsSystem32DirGet; lh_Module := LoadLibraryW(PWideChar(ls_Path + 'Dwmapi.dll')); if (lh_Module <> 0) then begin try // DwmIsCompositionEnabled の関数ポインタを取得 @l_DwmIsCompositionEnabled := GetProcAddress(lh_Module, 'DwmIsCompositionEnabled'); if (@l_DwmIsCompositionEnabled <> nil) then begin l_DwmIsCompositionEnabled(lb_Bool); Result := lb_Bool; end; finally FreeLibrary(lh_Module); end; end; end; function gfnbIsAeroThemeReady: Boolean; //http://www.delphipraxis.net/137018-vista-aero-effekt-deaktiveren.html //http://msdn.microsoft.com/en-us/library/windows/desktop/aa969510(v=vs.85).aspx var ls_Path : WideString; lh_Module : HMODULE; l_DwmEnableComposition : function(uCompositionAction: UINT): HRESULT; stdcall; begin Result := False; ls_Path := gfnsSystem32DirGet; lh_Module := LoadLibraryW(PWideChar(ls_Path + 'Dwmapi.dll')); if (lh_Module <> 0) then begin try l_DwmEnableComposition := GetProcAddress(lh_Module, 'DwmEnableComposition'); Result := (@l_DwmEnableComposition <> nil); finally FreeLibrary(lh_Module); end; end; end; function gfnbIsAlphaBlendReady: Boolean; type TSetLayeredWindowAttributes = function (Hwnd: THandle; crKey: COLORREF; bAlpha: Byte; dwFlags: DWORD): Boolean; stdcall; const lcs_User32 = 'User32.dll'; var l_SetLayeredWindowAttributes : TSetLayeredWindowAttributes; lh_Module : HMODULE; begin Result := False; lh_Module := GetModuleHandle(lcs_User32); if (lh_Module <> 0) then begin try @l_SetLayeredWindowAttributes := GetProcAddress(lh_Module, 'SetLayeredWindowAttributes'); Result := Assigned(l_SetLayeredWindowAttributes); finally FreeLibrary(lh_Module); end; end; end; //myNum.pas -------------------------------------------------------------------- function gfniStrToInt(sNum: String): Int64; //sNumを整数にして返す。 var li_Pos, i: Integer; ls_Tmp: String; begin sNum := UpperCase(Trim(sNum)); try Result := StrToInt64(sNum); except ls_Tmp := ''; for i := 1 to Length(sNum) do begin li_Pos := Pos(sNum[i], '$X-+0123456789ABCDEF'); if (li_Pos >= 15) then begin if (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 >= 5) then begin ls_Tmp := ls_Tmp + sNum[i]; end else if ((li_Pos = 1) or (li_Pos = 2)) and (ls_Tmp = '') then begin //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 begin Break; end; end; if (ls_Tmp = '') then begin Result := 0; end else begin Result := StrToInt64Def(ls_Tmp, 0); end; end; end; function gfniRound(fNum: Extended): Int64; {2007-06-09: fNumを四捨五入して返す Delphiのヘルプからコピー } begin if (fNum >= 0) then begin Result := Trunc(fNum + 0.5); end else begin Result := Trunc(fNum - 0.5); end; end; function lfniCeil(X: Extended): Int64; begin Result := Trunc(X); if Frac(X) > 0 then Inc(Result); end; function lfniFloor(X: Extended): Int64; begin Result := Trunc(X); if Frac(X) < 0 then Dec(Result); end; function gfniRoundUp(fNum: Extended): Int64; {2007-06-09: fNumを切り上げて返す } begin if (fNum >= 0) then begin Result := lfniCeil(fNum); end else begin Result := lfniFloor(fNum); end; end; function gfniNumLimit(iNum: Integer; iMin, iMax: Integer): Integer; begin if (iMin = iMax) then begin Result := iMin; end else begin if (iNum < iMin) then begin Result := iMin; end else if (iNum > iMax) then begin Result := iMax; end else begin Result := iNum; end; end; end; function gfniNumLoop(iNum: Integer; iMin, iMax: Integer): Integer; {2007-10-05,28: iNum := gfniNumLoop(5, 2, 5); //⇒5 iNum := gfniNumLoop(6, 2, 5); //⇒2 iNum := gfniNumLoop(7, 2, 5); //⇒3 2→3→4→5 ↑←←←←←↓ 2007-10-28:間違っていたので書き直し } var li_Diff, li_Interval: Integer; begin if (iMin = iMax) then begin Result := iMin; end else begin li_Interval := iMax - iMin +1; //間隔 if (iNum < iMin) then begin li_Diff := Abs(iNum - iMin); Result := iMax - (li_Diff mod li_Interval) +1; end else if (iNum > iMax) then begin li_Diff := iNum - iMax; Result := iMin + (li_Diff mod li_Interval) -1; end else begin Result := iNum; end; end; end; function gfniMax(iNum: array of Integer): Integer; {2007-08-27: 引数の中の最大値を返す } var i: Integer; begin Result := iNum[0]; for i := 1 to High(iNum) do begin if (iNum[i] > Result) then Result := iNum[i]; end; end; function gfniMin(iNum: array of Integer): Integer; {2007-12-16: 引数の中の最小値を返す } var i: Integer; begin Result := iNum[0]; for i := 1 to High(iNum) do begin if (iNum[i] < Result) then Result := iNum[i]; end; end; //mySize.pas ------------------------------------------------------------------- function gfniRectWidth (rtRect: TRect): Integer; {2007-06-09: rtRectの幅を返す } begin with rtRect do begin Result := Right - Left; end; end; function gfniRectHeight(rtRect: TRect): Integer; {2007-06-09: rtRectの高さを返す } begin with rtRect do begin Result := Bottom - Top; end; end; function gfnrcRectCenter(rcParent, rcChild: TRect): TRect; {2007-09-26: rcChildがrcParentの真ん中にくるようなRectを返す } var li_Left, li_Top, li_Width, li_Height: Integer; begin li_Width := gfniRectWidth (rcChild); li_Height := gfniRectHeight(rcChild); li_Left := rcParent.Left + (gfniRectWidth (rcParent) - li_Width) div 2; li_Top := rcParent.Top + (gfniRectHeight(rcParent) - li_Height) div 2; Result := Rect(li_Left, li_Top, li_Left + li_Width, li_Top + li_Height); end; function gfnrcRectShift(rcRect: TRect; ptShift: TPoint): TRect; {2007-09-27: rcRectをptPoint移動した値を返す } begin with rcRect do begin Result := Rect(Left + ptShift.X, Top + ptShift.Y, Right + ptShift.X, Bottom + ptShift.Y); end; end; function gfnbCompleteRectInRect(rcCheck, rcRect: TRect): Boolean; //rcCheckが完全にrcRect内にあればTrueを返す begin if (rcCheck.Left >= rcRect.Left) and (rcCheck.Right <= rcRect.Right) and (rcCheck.Top >= rcRect.Top) and (rcCheck.Bottom <= rcRect.Bottom) then begin Result := True; end else begin Result := False; end; end; function gfnbRectInRect(rcCheck, rcRect: TRect): Boolean; //rcCheckがrcRect内に少しでもかかって入ればTrueを返す begin if (rcCheck.Left >= rcRect.Left) or (rcCheck.Right <= rcRect.Right) or (rcCheck.Top >= rcRect.Top) or (rcCheck.Bottom <= rcRect.Bottom) then begin Result := True; end else begin Result := False; end; end; function gfniAngleGet(ptStart, ptPos: TPoint): Integer; { ptStartを原点してptPosがどの方向(角度)にあるかを返す ptPosがptStartからダブルクリックで許容される範囲(の三倍)内にあれば-1を返す。 それ以外は0〜359の角度を返す。 http://nkiso.u-tokai.ac.jp/phys/matsuura/lecture/dyna/contents/triangle/triangle.asp } const lci_NOMOVE = 3; //マウスジェスチャーとして認識しない範囲 var li_X, li_Y: Integer; begin li_X := ptPos.X - ptStart.X; li_Y := ptStart.Y - ptPos.Y; //数学の座標とはY軸が逆なので反対にしている //ダブルクリックの範囲のlci_NOMOVE倍内であれば動いていないとみなす if (Abs(li_X) <= (GetSystemMetrics(SM_CXDOUBLECLK) * lci_NOMOVE)) then li_X := 0; if (Abs(li_Y) <= (GetSystemMetrics(SM_CYDOUBLECLK) * lci_NOMOVE)) then li_Y := 0; if (li_X = 0) then begin if (li_Y = 0) then begin Result := -1; end else if (li_Y > 0) then begin Result := 90; end else begin Result := 270; end; end else if (li_Y = 0) then begin if (li_X > 0) then begin Result := 0; end else begin Result := 180; end; end else begin Result := gfniRound(Arctan(li_Y / li_X) * (360 / (2 * Pi))); //Arctanはラジアン単位なので度に直す if (li_X > 0) and (li_Y > 0) then begin //第一象限 //そのまま end else if (li_X < 0) and (li_Y > 0) then begin //第二象限 Inc(Result, 180); //第四象限と同じ値が出るのでプラス180度 end else if (li_X < 0) and (li_Y < 0) then begin //第三象限 Inc(Result, 180); //第一象限と同じ値が出るのでプラス180度 end else {if (li_X < 0) and (li_Y > 0) then }begin //第四象限 Inc(Result, 360); //マイナスの角度が出るのでぐるっと360度足しこむ end; end; end; function gfnsCompasGet(ptStart, ptPos: TPoint): String; //上下左右を返す。 var li_Angle: Integer; begin li_Angle := gfniAngleGet(ptStart, ptPos); case li_Angle of -1: Result := ''; 0.. 45: Result := '右'; 46..135: Result := '上'; 136..225: Result := '左'; 226..315: Result := '下'; 316..359: Result := '右'; else Result := ''; //保険 end; end; //myFile.pas ------------------------------------------------------------------- function gfnsFilePathGet(sFile: WideString): WideString; //Unicode対応ExtractFilePath。 var i: Integer; begin //末尾の'\'がつくかつかないの法則が揺れると困るので処理を分けず独自関数のみにする // if (G_bIsNTOS) then 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 else begin // Result := ExtractFilePath(sFile); // end; end; function gfnsShortFileNameGet(sFile: WideString): WideString; { Unicode対応の短いファイル名を返す。 戻り値がStringでないことに注意。 Unicode非対応のコンポーネントにファイルを渡すときの(完全ではないけれど)逃げ道。 } var lp_Buff: PWideChar; begin Result := sFile; lp_Buff := AllocMem((MAX_PATH + 1) * 2); try if (GetShortPathNameW(PWideChar(sFile), lp_Buff, (MAX_PATH + 1) * 2) > 0) then begin Result := WideString(lp_Buff); end; finally FreeMem(lp_Buff); end; end; function gfnsWorkFileNameGet(sExt : WideString) : WideString; //自身のファイル名の拡張子をsExtに変更して返す。 //主ファイル名にUnicodeな文字が入っていたらAnsiStringに変換し'?'を'_'に変更する。 //Unicode対応でない実行ファイルへの対処 var ls_FullPath : WideString; //ファイル名も含めたフルパス ls_Path : WideString; ls_Main : WideString; //主ファイル名 li_Len : Integer; begin if (sExt[1] <> '.') then begin sExt := '.' + sExt; end; if (G_bIsNTOS) then begin ls_FullPath := gfnsExeNameGet; ls_Path := gfnsFilePathGet(ls_FullPath); ls_Main := gfnsFileExtChange(gfnsFileNameGet(ls_FullPath), ''); if (gfnbIsUnicode(ls_FullPath)) then begin ls_Main := StringReplace(AnsiString(ls_Main), '?', '_', [rfReplaceAll]); if (gfnbIsUnicode(ls_Path)) then begin li_Len := Length(ls_Main); if (li_Len <= 8) then begin ls_Main := ls_Main + StringOfChar('_', 8 - li_Len +1); end; end; Result := ls_Path + ls_Main + sExt; end else begin Result := gfnsFileExtChange(ls_FullPath, sExt); end; end else begin Result := gfnsFileExtChange(gfnsExeNameGet, sExt); end; end; function gfnsFileNameGet(sFile: WideString): WideString; var i, li_Len, li_Pos: Integer; begin if (G_bIsNTOS) then begin Result := ''; if (sFile <> '') then begin li_Len := Length(sFile); li_Pos := li_Len + 1; //sFileの最後が'\'であった場合への対策 for i := li_Len downto 1 do begin if (sFile[i] = '\') or (sFile[i] = '/') or(sFile[i] = ':') then begin Break; end; li_Pos := i; end; Result := Copy(sFile, li_Pos, MaxInt); end; end else begin Result := ExtractFileName(sFile); end; end; function gfnsFileExtChange(sFile, sExt: WideString): WideString; var i: Integer; begin // if (G_bIsNTOS) then 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 else begin // Result := ChangeFileExt(sFile, sExt); // end; end; function gfnsExeNameGet: WideString; //WideString対応の自身の実行プログラム名を返す。 begin if (G_bIsNTOS) then begin Result := gfnsExeNameGet(Application.Handle); end else begin //Unicode文字が?に代替される場合へ対処 Result := StringReplace(ParamStr(0), '?', '_', [rfReplaceAll]); end; end; function gfnbFileExists(sFile: WideString): Boolean; var li_Attr: DWORD; begin Result := False; if (sFile = '') then begin Exit; end; if (G_bIsNTOS) then begin li_Attr := GetFileAttributesW(PWideChar(sFile)); Result := (li_Attr <> $FFFFFFFF) and ((li_Attr and FILE_ATTRIBUTE_DIRECTORY) = 0); end else begin Result := FileExists(sFile); end; end; function gfniFileSizeGet(hHandle: THandle): Int64; {2008-03-11: hHandleのファイルハンドルを持つファイルのサイズをByte単位で返す } var li_High, li_Low: DWORD; begin if (hHandle <> INVALID_HANDLE_VALUE) then begin li_Low := GetFileSize(hHandle, @li_High); Result := li_High * (Int64(MAXDWORD) +1) + li_Low; end else begin Result := 0; end; end; var lhPIDToWindowHandle: HWND; function gfnhPIDToWindow(iProcessID: DWORD): HWND; {2010-07-29: PIDからトップレベルウィンドウのウィンドウハンドルを返す。 } function l_fnbEnumWindowProc(hHandle: HWND; iParam: LPARAM): BOOL; stdcall; //戻り値はBooleanではなくBOOLである必要あり begin if (gfniProcessIDGet(hHandle) = DWORD(iParam)) then begin lhPIDToWindowHandle := hHandle; Result := False; end else begin Result := True; end; end; begin lhPIDToWindowHandle := 0; EnumWindows(@l_fnbEnumWindowProc, iProcessID); Result := lhPIDToWindowHandle; end; function gfnhProcessToWindow(hProcess : THandle) : HWND; {2010-04-03: プロセスのハンドルからプロセスのトップレベルウィンドウのハンドルを取得して返す。 トップレベルウィンドウが複数ある場合は一番手前にあるウィンドウのハンドルが返る。 実行ファイルのウィンドウハンドルを取得する場合は実行後WaitForInputIdleで初期化処 理を終了するまで待ってからでないと取得に失敗する。 } var lh_Handle : THandle; lh_SelfPID : DWORD; l_Info : TProcessEntry32; begin Result := 0; FillChar(l_Info, SizeOf(l_Info), 0); l_Info.dwSize := Sizeof(l_Info); lh_Handle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, hProcess); try if (Process32First(lh_Handle, l_Info)) then begin lh_SelfPID := gfniProcessIDGet(Application.Handle); repeat //myDebug.gpcDebug([WideString(l_Info.szExeFile), l_Info.th32ParentProcessID, gfniProcessIDGet(Self.Handle)]); if (l_Info.th32ParentProcessID = lh_SelfPID) then begin Result := gfnhPIDToWindow(l_Info.th32ProcessID); end; until not(Process32Next(lh_Handle, l_Info)); end; finally CloseHandle(lh_Handle); end; end; procedure gpcExecute(sFile: WideString); {2007-10-04,2011-06-23: sFileを実行する } var l_InfoW : TShellExecuteInfoW; l_InfoA : TShellExecuteInfoA; lh_Process : THandle; lh_Window : HWND; begin if (G_bIsNTOS) then begin FillChar(l_InfoW, SizeOf(l_InfoW), 0); l_InfoW.cbSize := SizeOf(l_InfoW); l_InfoW.fMask := SEE_MASK_UNICODE or SEE_MASK_NOCLOSEPROCESS or SEE_MASK_CONNECTNETDRV //ネットワーク上のファイルの UNC(Universal Naming Convention)パス名であることを表します。 // or SEE_MASK_FLAG_DDEWAIT //DDE 対話が開始される場合には、それが終了するまで再開されません。 ; if (sFile <> '') then begin l_InfoW.lpFile := PWideChar(sFile); end; l_InfoW.nShow := SW_SHOWNORMAL; if (ShellExecuteExW(@l_InfoW)) then begin lh_Process := l_InfoW.hProcess; end else begin lh_Process := 0; end; // ShellExecuteW(Application.Handle, nil, PWideChar(sFile), nil, nil, SW_SHOWNORMAL); end else begin FillChar(l_InfoA, SizeOf(l_InfoA), 0); l_InfoA.cbSize := SizeOf(l_InfoA); l_InfoA.fMask := SEE_MASK_UNICODE or SEE_MASK_NOCLOSEPROCESS or SEE_MASK_CONNECTNETDRV //ネットワーク上のファイルの UNC(Universal Naming Convention)パス名であることを表します。 // or SEE_MASK_FLAG_DDEWAIT //DDE 対話が開始される場合には、それが終了するまで再開されません。 ; if (sFile <> '') then begin l_InfoA.lpFile := PAnsiChar(AnsiString(sFile)); end; l_InfoA.nShow := SW_SHOWNORMAL; if (ShellExecuteEx(@l_InfoA)) then begin lh_Process := l_InfoA.hProcess; end else begin lh_Process := 0; end; // ShellExecute(Application.Handle, nil, PAnsiChar(AnsiString(sFile)), nil, nil, SW_SHOWNORMAL); end; if (lh_Process <> 0) then begin try WaitForInputIdle(lh_Process, 3000); lh_Window := gfnhProcessToWindow(lh_Process); if (IsWindow(lh_Window)) then begin SetForegroundWindow(lh_Window); end; finally CloseHandle(lh_Process); end; end; end; type TLangAndCodePage = record iLanguage: WORD; iCodePage: WORD; end; PLangAndCodePage = ^TLangAndCodePage; function gfnsFileVersionGet(sFile: WideString): WideString; //ファイルのバージョン情報を返す //http://www2.big.or.jp/~osamu/Delphi/Tips/key.cgi?key=13#0226.txt var li_Size, li_Reserved, li_Len: DWORD; lp_Buff, lp_Dat: Pointer; lp_LangPage: PLangAndCodePage; ls_FileInfo: WideString; begin Result := ''; if (G_bIsNTOS) then begin // 必要なバッファのサイズを取得 li_Size := GetFileVersionInfoSizeW(PWideChar(sFile), li_Reserved); if (li_Size > 0) then begin //メモリ確保 lp_Buff := AllocMem((li_Size +1) * 2); try if (GetFileVersionInfoW(PWideChar(sFile), 0, li_Size, lp_Buff)) then begin //変数情報ブロック内の変換テーブルを指定 if (VerQueryValueW(lp_Buff, '\VarFileInfo\Translation', Pointer(lp_LangPage), li_Len) and (li_Len > 0)) then begin ls_FileInfo := Format('\StringFileInfo\%.4x%.4x\', [lp_LangPage^.iLanguage, lp_LangPage^.iCodePage]); //ファイルバージョン if (VerQueryValueW(lp_Buff, PWideChar(ls_FileInfo + 'FileVersion'), lp_Dat, li_Len) and (li_Len > 0)) then begin Result := WideString(PWideChar(lp_Dat)); end; end; end; finally // 解放 FreeMem(lp_Buff); end; end; end else begin // 必要なバッファのサイズを取得 li_Size := GetFileVersionInfoSize(PAnsiChar(AnsiString(sFile)), li_Reserved); if (li_Size > 0) then begin //メモリ確保 lp_Buff := AllocMem(li_Size +1); try if (GetFileVersionInfo(PAnsiChar(AnsiString(sFile)), 0, li_Size, lp_Buff)) then begin //変数情報ブロック内の変換テーブルを指定 if (VerQueryValue(lp_Buff, '\VarFileInfo\Translation', Pointer(lp_LangPage), li_Len) and (li_Len > 0)) then begin ls_FileInfo := Format('\StringFileInfo\%.4x%.4x\', [lp_LangPage^.iLanguage, lp_LangPage^.iCodePage]); //ファイルバージョン if (VerQueryValue(lp_Buff, PAnsiChar(AnsiString(ls_FileInfo + 'FileVersion')), lp_Dat, li_Len) and (li_Len > 0)) then begin Result := AnsiString(PAnsiChar(lp_Dat)); end; end; end; finally // 解放 FreeMem(lp_Buff); end; end; end; end; function gfnsFileVersionGet: WideString; //自アプリのファイルバージョン。 begin Result := gfnsFileVersionGet(gfnsExeNameGet); end; function gfnsProductNameGet(sFile: WideString): WideString; //自アプリの製品名。 var li_Size, li_Reserved, li_Len: DWORD; lp_Buff, lp_Dat: Pointer; lp_LangPage: PLangAndCodePage; ls_FileInfo: WideString; begin Result := ''; if (G_bIsNTOS) then begin // 必要なバッファのサイズを取得 li_Size := GetFileVersionInfoSizeW(PWideChar(sFile), li_Reserved); if (li_Size > 0) then begin //メモリ確保 lp_Buff := AllocMem((li_Size +1) * 2); try if (GetFileVersionInfoW(PWideChar(sFile), 0, li_Size, lp_Buff)) then begin //変数情報ブロック内の変換テーブルを指定 if (VerQueryValueW(lp_Buff, '\VarFileInfo\Translation', Pointer(lp_LangPage), li_Len) and (li_Len > 0)) then begin ls_FileInfo := Format('\StringFileInfo\%.4x%.4x\', [lp_LangPage^.iLanguage, lp_LangPage^.iCodePage]); //製品名 if (VerQueryValueW(lp_Buff, PWideChar(ls_FileInfo + 'ProductName'), lp_Dat, li_Len) and (li_Len > 0)) then begin Result := WideString(PWideChar(lp_Dat)); end; end; end; finally // 解放 FreeMem(lp_Buff); end; end; end else begin // 必要なバッファのサイズを取得 li_Size := GetFileVersionInfoSize(PAnsiChar(AnsiString(sFile)), li_Reserved); if (li_Size > 0) then begin //メモリ確保 lp_Buff := AllocMem(li_Size +1); try if (GetFileVersionInfo(PAnsiChar(AnsiString(sFile)), 0, li_Size, lp_Buff)) then begin //変数情報ブロック内の変換テーブルを指定 if (VerQueryValue(lp_Buff, '\VarFileInfo\Translation', Pointer(lp_LangPage), li_Len) and (li_Len > 0)) then begin ls_FileInfo := Format('\StringFileInfo\%.4x%.4x\', [lp_LangPage^.iLanguage, lp_LangPage^.iCodePage]); //製品名 if (VerQueryValue(lp_Buff, PAnsiChar(AnsiString(ls_FileInfo + 'ProductName')), lp_Dat, li_Len) and (li_Len > 0)) then begin Result := AnsiString(PAnsiChar(lp_Dat)); end; end; end; finally // 解放 FreeMem(lp_Buff); end; end; end; end; function gfnsProductNameGet: WideString; begin Result := gfnsProductNameGet(gfnsExeNameGet); end; procedure gpcFileWriteText(sFile, sText: WideString); var lh_Handle: THandle; li_Count: DWORD; ls_Text: AnsiString; begin if (G_bIsNTOS) then begin lh_Handle := CreateFileW( PWideChar(sFile), //ファイル名 GENERIC_WRITE, //アクセスモード 0, //共有モード nil, //セキュリティ CREATE_ALWAYS, //作成方法 FILE_ATTRIBUTE_NORMAL, //ファイル属性 0 //テンプレート ); end else begin lh_Handle := CreateFile( PAnsiChar(AnsiString(sFile)), //ファイル名 GENERIC_WRITE, //アクセスモード 0, //共有モード nil, //セキュリティ CREATE_ALWAYS, //作成方法 FILE_ATTRIBUTE_NORMAL, //ファイル属性 0 //テンプレート ); end; try if (lh_Handle <> INVALID_HANDLE_VALUE) then begin //UnicodeではなくShift JISで書き込む ls_Text := sText; WriteFile(lh_Handle, PAnsiChar(ls_Text)^, Length(ls_Text), li_Count, nil); end; finally CloseHandle(lh_Handle); end; end; //myGraphic.pas ---------------------------------------------------------------- type TFileStreamW = class(THandleStream) public constructor Create(const FileName: WideString; Mode: Word); overload; destructor Destroy; override; end; constructor TFileStreamW.Create(const FileName: WideString; Mode: Word); //TFileStreamのUnicode版  var li_AccessMode, li_ShareMode: DWORD; begin if (Mode = fmCreate) then begin inherited Create(CreateFileW( PWideChar(FileName), //ファイル名 GENERIC_READ or GENERIC_WRITE, //アクセスモード 0, //共有モード nil, //セキュリティ OPEN_ALWAYS, //作成方法 FILE_ATTRIBUTE_NORMAL, //ファイル属性 0 //テンプレート )); end else begin //アクセスモード li_AccessMode := GENERIC_READ; if ((Mode and fmOpenWrite) <> 0) then begin li_AccessMode := li_AccessMode or GENERIC_WRITE; end; {$WARN SYMBOL_PLATFORM OFF} //共有モード li_ShareMode := 0; if (Mode >= fmShareExclusive) then begin Dec(Mode, $10); end; if ((Mode and (fmShareDenyRead - $10)) <> 0) then begin //読み込みは禁止=書き込みはOK li_ShareMode := FILE_SHARE_WRITE; end; if ((Mode and (fmShareDenyWrite - $10)) <> 0) then begin //書き込みは禁止=読み込みはOK li_ShareMode := li_ShareMode or FILE_SHARE_READ; end; {$WARN SYMBOL_PLATFORM ON} inherited Create(CreateFileW( PWideChar(FileName), li_AccessMode, li_ShareMode, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 )); end; if (FHandle = Integer(INVALID_HANDLE_VALUE)) then begin //エラーメッセージはUnicode対応ではない。 raise EFCreateError.CreateResFmt(@SFCreateError, [FileName]); end; end; destructor TFileStreamW.Destroy; begin if (FHandle >= 0) then CloseHandle(FHandle); inherited Destroy; end; //------------------------------------------------------------------------------ procedure TMyBitmap.SaveToFile(const Filename: WideString); var l_Stream: TStream; begin if (G_bIsNtOs) then begin l_Stream := TFileStreamW.Create(Filename, fmCreate); try SaveToStream(l_Stream); finally l_Stream.Free; end; end else begin inherited SaveToFile(AnsiString(Filename)); end; end; function gfnclColorRevers(clColor: TColor): TColor; {2007-06-18: clColorの反転色を返す } var li_Color: Longint; li_Red, li_Green, li_Blue: Integer; begin li_Color := ColorToRGB(clColor); li_Red := (li_Color and $0000FF); li_Green := (li_Color and $00FF00) div $000100; li_Blue := (li_Color and $FF0000) div $010000; Result := (($FF - li_Blue) * $010000) + (($FF - li_Green) * $000100) + ($FF - li_Red); end; procedure gpcColorRGBToHLS(iRed, iGreen, iBlue: BYTE; var iHue, iLuminance, iSaturation: WORD; iMaxHue, iMaxLuminance, iMaxSaturation: WORD); {2009-09-13: RGBをHLSに変換。 APIのColorRGBToHLSがH,L,Sの範囲が0〜240で直観的でないので自作。 http://www.pannoki.com/tips/ index.php?RGB%20to%20HLS http://inugashira.exblog.jp/9551741/ http://support.microsoft.com/kb/29240/ja } const lci_MAXRGB = High(BYTE); //R,G,Bの取れる値の範囲(256) var li_Max, li_Min: WORD; li_Hue, li_Saturation: Integer; lf_RDelta, lf_GDelta, lf_BDelta: Extended; begin if (iRed = iGreen) and (iGreen = iBlue) then begin //全部同じということは無彩色(黒か白かグレー)であるので色彩(Hue)と彩度(Saturation)は無意味 iSaturation := 0; iHue := 0; iLuminance := gfniRound(iRed / lci_MAXRGB * iMaxLuminance); end else begin li_Max := gfniMax([iRed, iGreen, iBlue]); li_Min := gfniMin([iRed, iGreen, iBlue]); //明度 iLuminance := WORD(gfniRound((li_Max + li_Min) / 2 / lci_MAXRGB * iMaxLuminance)); //彩度 if (iLuminance <= (iMaxLuminance div 2)) then begin li_Saturation := gfniRound((((li_Max - li_Min) * iMaxSaturation) + ((li_Max + li_Min) / 2)) / (li_Max + li_Min)); end else begin li_Saturation := gfniRound((((li_Max - li_Min) * iMaxSaturation) + ((2 * lci_MAXRGB - li_Max - li_Min) / 2)) / (2 * lci_MAXRGB - li_Max - li_Min)); end; iSaturation := WORD(gfniNumLimit(li_Saturation, 0, iMaxSaturation)); //Hue lf_RDelta := ( ((li_Max - iRed) * (iMaxHue / 6)) + ((li_Max - li_Min) / 2) ) / (li_Max - li_Min); lf_GDelta := ( ((li_Max - iGreen) * (iMaxHue / 6)) + ((li_Max - li_Min) / 2) ) / (li_Max - li_Min); lf_BDelta := ( ((li_Max - iBlue) * (iMaxHue / 6)) + ((li_Max - li_Min) / 2) ) / (li_Max - li_Min); if (iRed = li_Max) then begin li_Hue := gfniRound(lf_BDelta - lf_GDelta); end else if (iGreen = li_Max) then begin li_Hue := gfniRound((iMaxHue / 3) + lf_RDelta - lf_BDelta); end else {if (iBlue = li_Max) then} begin li_Hue := gfniRound(((2 * iMaxHue) / 3) + lf_GDelta - lf_RDelta); end; iHue := WORD(gfniNumLoop(li_Hue, 0, iMaxHue -1)); end; end; procedure gpcColorRGBToHLS(iRed, iGreen, iBlue: BYTE; var iHue, iLuminance, iSaturation: WORD); //Hは0〜360 //LとSは0〜100 const lci_MAXHUE = 360; lci_MAXLUMINANCE = 100; lci_MAXSATURATION = 100; begin gpcColorRGBToHLS(iRed, iGreen, iBlue, iHue, iLuminance, iSaturation, lci_MAXHUE, lci_MAXLUMINANCE, lci_MAXSATURATION); end; procedure gpcColorRGBToHSV(iRed, iGreen, iBlue: BYTE; var iHue, iValue, iSaturation: WORD; iMaxHue, iMaxValue, iMaxSaturation: WORD); const lci_MAXRGB = High(BYTE) +1; //R,G,Bの取れる値の範囲(256) var li_Max, li_Min: WORD; li_Hue: Integer; lf_RDelta, lf_GDelta, lf_BDelta: Extended; begin if (iRed = iGreen) and (iGreen = iBlue) then begin iHue := 0; iSaturation := 0; iValue := gfniRound(iRed / lci_MAXRGB * iMaxValue); end else begin li_Max := gfniMax([iRed, iGreen, iBlue]); li_Min := gfniMin([iRed, iGreen, iBlue]); iSaturation := WORD(gfniNumLimit(gfniRound((li_Max - li_Min) / li_Max * iMaxSaturation), 0, iMaxSaturation)); iValue := WORD(gfniNumLimit(gfniRound(li_Max / lci_MAXRGB * iMaxValue), 0, iMaxValue)); //Hue lf_RDelta := ( ((li_Max - iRed) * (iMaxHue / 6)) + ((li_Max - li_Min) / 2) ) / (li_Max - li_Min); lf_GDelta := ( ((li_Max - iGreen) * (iMaxHue / 6)) + ((li_Max - li_Min) / 2) ) / (li_Max - li_Min); lf_BDelta := ( ((li_Max - iBlue) * (iMaxHue / 6)) + ((li_Max - li_Min) / 2) ) / (li_Max - li_Min); if (iRed = li_Max) then begin li_Hue := gfniRound(lf_BDelta - lf_GDelta); end else if (iGreen = li_Max) then begin li_Hue := gfniRound((iMaxHue / 3) + lf_RDelta - lf_BDelta); end else {if (iBlue = li_Max) then} begin li_Hue := gfniRound(((2 * iMaxHue) / 3) + lf_GDelta - lf_RDelta); end; iHue := WORD(gfniNumLoop(li_Hue, 0, iMaxHue -1)); end; end; //myList.pas ------------------------------------------------------------------- function gfnbIsIncludeList(sValue: String; slList: TStrings): Boolean; {2007-10-17: slList中にsValueがあればTrueを返す 大文字小文字の違いは無視 } var i: Integer; begin Result := False; for i := 0 to slList.Count -1 do begin if (AnsiCompareText(sValue, slList[i]) = 0) then begin Result := True; Break; end; end; end; function gfnbIsIncludeList(sValue: String; slList: array of String): Boolean; //slList中にsValueがあればTrueを返す //大文字小文字の違いは無視 var i: Integer; begin Result := False; for i := Low(slList) to High(slList) do begin if (AnsiCompareText(sValue, slList[i]) = 0) then begin Result := True; Break; end; end; end; //------------------------------------------------------------------------------ function gfniMonitorIndexGet(APoint : TPoint) : Integer; {2011-09-02: モニターのインデックスを取得。 APointはスクリーン座標であること。 } var i : Integer; begin Result := -1; for i := 0 to Screen.MonitorCount -1 do begin if (PtInRect(Screen.Monitors[i].BoundsRect, APoint)) then begin Result := i; Exit; end; end; end; function gfnMonitorGet(APoint : TPoint) : TMonitor; {2011-09-02: APointのあるモニターを取得 } var li_Index : Integer; begin li_Index := gfniNumLimit(gfniMonitorIndexGet(APoint), 0, Screen.MonitorCount -1); Result := Screen.Monitors[li_Index]; end; //myMessageDlg type TMyMessageDlgEvent = class(TObject) public procedure DoFormShow(Sender: TObject); end; var F_MessageDlgEvent : TMyMessageDlgEvent; const F_ciDEFAULT_MB_YES = 0; //mbYes: ls_Caption := '??(Y)'; F_ciDEFAULT_MB_NO = 1; //mbNo: ls_Caption := '???(N)'; F_ciDEFAULT_MB_OK = 2; //mbOK: ls_Caption := 'OK'; F_ciDEFAULT_MB_CANCEL = 3; //mbCancel: ls_Caption := 'Cancel'; F_ciDEFAULT_MB_ABORT = 4; //mbAbort: ls_Caption := '??(A) '; F_ciDEFAULT_MB_RETRY = 5; //mbRetry: ls_Caption := '???(R)'; F_ciDEFAULT_MB_IGNORE = 6; //mbIgnore: ls_Caption := '??(I)'; F_ciDEFAULT_MB_ALL = 7; //mbAll: ls_Caption := '???'; F_ciDEFAULT_MB_NOTOALL = 8; //mbNoToAll: ls_Caption := '???????'; F_ciDEFAULT_MB_YESTOALL = 9; //mbYesToAll: ls_Caption := '??????'; F_ciDEFAULT_MB_HELP = 10; //mbHelp: ls_Caption := '???(H)'; F_ciDEFAULT_MB_CLOSE = 11; //mbClose: ls_Caption := '???(C)'; procedure TMyMessageDlgEvent.DoFormShow(Sender: TObject); var l_Pos : TPoint; l_Monitor : TMonitor; l_Form : TForm; // l_Rect : TRect; ls_Caption : String; i : Integer; l_Control : TControl; lb_Bool : LongBool; l_Cursor : TRect; begin if not(Sender is TForm) then begin Exit; end; l_Form := TForm(Sender); // l_Pos := gfnptMousePosGet; l_Monitor := gfnMonitorGet(l_Pos); SetWindowPos( l_Form.Handle, 0, l_Monitor.Left + ((l_Monitor.Width - l_Form.Width) div 2), l_Monitor.Top + ((l_Monitor.Height - l_Form.Height) div 2), 0, 0, SWP_NOSIZE or SWP_NOZORDER ); ls_Caption := ''; case l_Form.Tag of F_ciDEFAULT_MB_YES: ls_Caption := 'はい(&Y)'; F_ciDEFAULT_MB_NO: ls_Caption := 'いいえ(&N)'; F_ciDEFAULT_MB_OK: ls_Caption := 'OK'; F_ciDEFAULT_MB_CANCEL: ls_Caption := 'Cancel'; F_ciDEFAULT_MB_ABORT: ls_Caption := '中止(&A) '; F_ciDEFAULT_MB_RETRY: ls_Caption := '再試行(&R)'; F_ciDEFAULT_MB_IGNORE: ls_Caption := '無視(&I)'; F_ciDEFAULT_MB_ALL: ls_Caption := 'すべて'; F_ciDEFAULT_MB_NOTOALL: ls_Caption := 'すべてにいいえ'; F_ciDEFAULT_MB_YESTOALL: ls_Caption := 'すべてにはい'; F_ciDEFAULT_MB_HELP: ls_Caption := 'ヘルプ(&H)'; end; if (ls_Caption <> '') then begin //カーソルをOKボタンの上へ SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, @lb_Bool, 0); if (lb_Bool) then begin for i := 0 to l_Form.ControlCount-1 do begin l_Control := l_Form.Controls[i]; if (l_Control is TButton) and (TButton(l_Control).Caption = ls_Caption) then begin GetWindowRect(TWinControl(l_Control).Handle, l_Cursor); l_Cursor := gfnrcRectCenter(l_Cursor, Rect(0,0,0,0)); SetCursorPos(l_Cursor.Left, l_Cursor.Top); end; end; end; end; end; function gfniMessageDlg(sMsg, sTitle: String; Buttons: TMsgDlgButtons; DefaultButton: TMsgDlgBtn): Word; var l_MsgForm : TForm; l_FormShow : TMyMessageDlgEvent; begin l_MsgForm := nil; try l_MsgForm := CreateMessageDialog(sMsg, mtCustom, Buttons); //, DefaultButton); if (sTitle = '') then begin // sTitle := gfnsExeNameGet; sTitle := gfnsProductNameGet; end; l_MsgForm.Caption := sTitle; // SetWindowTextW(l_MsgForm.Handle, PWideChar(sTitle)); case DefaultButton of mbYes: l_MsgForm.Tag := F_ciDEFAULT_MB_YES; mbNo: l_MsgForm.Tag := F_ciDEFAULT_MB_NO; mbOK: l_MsgForm.Tag := F_ciDEFAULT_MB_OK; mbCancel: l_MsgForm.Tag := F_ciDEFAULT_MB_CANCEL; mbAbort: l_MsgForm.Tag := F_ciDEFAULT_MB_ABORT; mbRetry: l_MsgForm.Tag := F_ciDEFAULT_MB_RETRY; mbIgnore: l_MsgForm.Tag := F_ciDEFAULT_MB_IGNORE; mbAll: l_MsgForm.Tag := F_ciDEFAULT_MB_ALL; mbNoToAll: l_MsgForm.Tag := F_ciDEFAULT_MB_NOTOALL; mbYesToAll: l_MsgForm.Tag := F_ciDEFAULT_MB_YESTOALL; mbHelp: l_MsgForm.Tag := F_ciDEFAULT_MB_HELP; end; Beep; l_FormShow := nil; try l_FormShow := TMyMessageDlgEvent.Create; l_MsgForm.OnShow := l_FormShow.DoFormShow; Result := l_MsgForm.ShowModal; finally FreeAndNil(l_FormShow); end; finally l_MsgForm.Release; end; end; procedure gpcShowMessage(sMsg: String; sTitle: String = ''); begin gfniMessageDlg(sMsg, sTitle, [mbOk], mbOk); end; function gfniMessageBoxYesNo(sMsg: String; sTitle: String = ''; DefaultButton: TMsgDlgBtn = mbYes): Word; begin Result := gfniMessageDlg(sMsg, sTitle, [mbYes, mbNo], DefaultButton); end; //------------------------------------------------------------------------------ const WC_NO_BEST_FIT_CHARS = $00000400; function gfnbIsUnicode(sSrc: WideString): Boolean; {2007-11-05,2009-02-12: sSrcにウムラウトのようなUnicode文字があればTrueを返す http://yokohama.cool.ne.jp/chokuto/urawaza/api/WideCharToMultiByte.html 0x00000400 (WC_NO_BEST_FIT_CHARS) Windows 2000/XP:直接マルチバイト文字に変換できない文字をデフォルトキャラクタに置きかえます。 2009-02-12: ResultをWideChartoMultiByteに直接渡すのでなくlb_Boolを介するように変更。 BooleanとLongBoolで型が違うため実行時エラーになってしまうことがあるため。 } var lb_Bool: LongBool; begin WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, PWideChar(sSrc), -1, nil, 0, nil, @lb_Bool); Result := lb_Bool; end; function gfnsWideToUtf7(sSrc: WideString): AnsiString; {2008-06-06: WideStringをUTF-7にエンコードして返す } var li_Len: Integer; lp_Buff: PAnsiChar; begin //WC_COMPOSITECHECKはNG li_Len := WideCharToMultiByte(CP_UTF7, 0, PWideChar(sSrc), -1, nil, 0, nil, nil); lp_Buff := AllocMem(li_Len + 1); try WideCharToMultiByte(CP_UTF7, 0, PWideChar(sSrc), -1, lp_Buff, li_Len, nil, nil); Result := AnsiString(lp_Buff); finally FreeMem(lp_Buff); end; end; function gfnsUtf7ToWide(sSrc: AnsiString): WideString; {2008-06-06: UTF-7でエンコードされている文字列をWideStringにして返す } var li_Len: Integer; lp_Buff: PWideChar; begin li_Len := MultiByteToWideChar(CP_UTF7, 0, PAnsiChar(sSrc), -1, nil, 0); lp_Buff := AllocMem((li_Len + 1) * 2); try MultiByteToWideChar(CP_UTF7, 0, PAnsiChar(sSrc), -1, lp_Buff, li_Len); Result := WideString(lp_Buff); finally FreeMem(lp_Buff); end; end; //UTF-16LE⇔UTF-8 function gfnsWideToUTF8(sSrc: WideString): UTF8String; //WideStringをUTF-8にエンコードして返す。 var li_Len: Integer; lp_Buff: PAnsiChar; begin if (G_bIsNtOs) then begin li_Len := WideCharToMultiByte(CP_UTF8, 0, PWideChar(sSrc), -1, nil, 0, nil, nil); lp_Buff := AllocMem(li_Len + 1); try WideCharToMultiByte(CP_UTF8, 0, PWideChar(sSrc), -1, lp_Buff, li_Len +1, nil, nil); Result := UTF8String(lp_Buff); finally FreeMem(lp_Buff); end; end else begin Result := Utf8Encode(sSrc); end; end; function gfnsUTF8ToWide(sSrc: UTF8String): WideString; //UTF-8でエンコードされている文字列をWideStringにして返す。 var li_Len: Integer; lp_Buff: PWideChar; begin if (G_bIsNtOs) then begin li_Len := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(sSrc), -1, nil, 0); lp_Buff := AllocMem((li_Len + 1) * 2); try MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(sSrc), -1, lp_Buff, li_Len); Result := WideString(lp_Buff); finally FreeMem(lp_Buff); end; end else begin Result := Utf8Decode(sSrc); end; end; function gfnsWideToAnsi(sSrc: WideString): AnsiString; //合成文字をきちんとあつかってAnsiStringに変換。 //例)「か゛」→「が」みたいな感じで。 var li_Len : Integer; lp_Buff : PAnsiChar; begin //WC_COMPOSITECHECKが肝 li_Len := WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK{ or WC_SEPCHARS}, PWideChar(sSrc), -1, nil, 0, nil, nil); Inc(li_Len); lp_Buff := AllocMem(li_Len); try WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK{ or WC_SEPCHARS}, PWideChar(sSrc), -1, lp_Buff, li_Len, nil, nil); Result := AnsiString(lp_Buff); finally FreeMem(lp_Buff); end; end; //myControl.pas ---------------------------------------------------------------- function gfnrcClientOriginRect(Control: TControl): TRect; {2008-06-02: コントロールのClientRectをスクリーン座標で返す } begin with Control do begin Result := Rect( ClientToScreen(Point(0, 0)), ClientToscreen(Point(ClientWidth, ClientHeight)) ); end; end; function gfnbIsComponentNameUsed(sName: String): Boolean; {2009-07-19: sNameがコンポーネントのNameプロパティとしてすでに使われていればTrueを返す。 } function lfnb_IsUsed(Component: TComponent; sName: String): Boolean; var i: Integer; begin Result := False; for i := 0 to Component.ComponentCount -1 do begin if (Component.Components[i].Name = sName) then begin Result := True; end else begin Result := lfnb_IsUsed(Component.Components[i], sName); end; if (Result) then Break; end; end; begin Result := lfnb_IsUsed(Application, sName); end; procedure gpcAvaiableNameGet(sPrefix: String; var sName: String; var iIndex: Integer); {2009-07-19: コントロールにセットすることができるNameプロパティの値とインデックスをセットする。 フォーマットは sPrefix_n } begin iIndex := 0; repeat sName := Format('%s_%d', [sPrefix, iIndex]); Inc(iIndex); until not(gfnbIsComponentNameUsed(sName)); end; function gfnsAvailableName(sPrefix: String): String; {2009-07-19: コントロールにセットすることができるNameプロパティを返す。 フォーマットは sPrefix_n } var li_Index: Integer; begin gpcAvaiableNameGet(sPrefix, Result, li_Index); end; //myClipbrd.pas ---------------------------------------------------------------- procedure gpcStrToClipboard(sStr : WideString); var ls_WText: WideString; li_WLen : Integer; ls_Text : AnsiString; li_Len : Integer; lh_Mem : THandle; lp_Data : Pointer; begin if not(G_bIsNtOs) then begin Clipboard.AsText := sStr; end else begin ls_WText := sStr; li_WLen := (Length(sStr) +1) * 2; ls_Text := gfnsWideToAnsi(sStr); li_Len := Length(ls_Text) + 1; if (ls_WText <> '') then begin if (OpenClipboard(Application.Handle)) then begin try EmptyClipboard; //CF_UNICODETEXT lh_Mem := GlobalAlloc(GHND or GMEM_SHARE, li_WLen); lp_Data := GlobalLock(lh_Mem); lstrcpyW(lp_Data, PWideChar(ls_WText)); GlobalUnlock(lh_Mem); SetClipboardData(CF_UNICODETEXT, lh_Mem); //CF_TEXT lh_Mem := GlobalAlloc(GHND or GMEM_SHARE, li_Len); lp_Data := GlobalLock(lh_Mem); lstrcpy(lp_Data, PChar(ls_Text)); GlobalUnlock(lh_Mem); SetClipboardData(CF_TEXT, lh_Mem); finally CloseClipboard; end; end; end; end; end; //------------------------------------------------------------------------------ //myGrid.pas function gfniGridCanvasTextWidthGet(Grid: TDrawGrid; sText: WideString): Integer; //GridはFontの設定直後にCanvas.FontWidth〜としても正しい値が得られないのでTBitmapを利用する。 var l_Bitmap: TBitmap; begin l_Bitmap := TBitmap.Create; try l_Bitmap.Canvas.Font.Assign(Grid.Font); Result := l_Bitmap.Canvas.TextWidth(sText); finally l_Bitmap.Free; end; end; //------------------------------------------------------------------------------ //スタイル function gfnbStyleCheck(iStyle: Longint; iCheck: Longint): Boolean; begin Result := ((iStyle and iCheck) = iCheck); end; //------------------------------------------------------------------------------ //ショートカット function gfnsCommandDescriptionGet(AAction: TAction): String; begin if (AAction = nil) then begin Result := ''; end else if (AAction.Category = G_MainForm.actSpc.Category) then begin Result := G_MainForm.actSpc.Caption; end else begin Result := Format('%s/%s', [AAction.Category, StripHotKey(AAction.Caption)]); end; end; function gfnsCommandHintGet(AAction: TAction): String; begin if (AAction = nil) then begin Result := ''; end else if (AAction.Category = G_MainForm.actSpc.Category) then begin Result := G_MainForm.actSpc.Caption; end else if (AAction.Hint = '') then begin Result := gfnsCommandDescriptionGet(AAction); end else begin Result := AAction.Hint; end; end; //------------------------------------------------------------------------------ initialization G_bIsNtOs := gfnbIsNtOs; // G_bIsNtOs := False; //myMessageDlg F_MessageDlgEvent := TMyMessageDlgEvent.Create; finalization //myMessageDlg FreeAndNil(F_MessageDlgEvent); end.