OSUtils.pas
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:9k
源码类别:

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(Operating systems support unit)
  3.  (C) 2006-2007 George "Mirage" Bakhtadze. <a href="http://www.casteng.com">www.casteng.com</a> <br>
  4.  The source code may be used under either MPL 1.1 or LGPL 2.1 license. See included license.txt file <br>
  5.  Unit contains basic OS-related classes
  6. *)
  7. {$Include GDefines.inc}
  8. unit OSUtils;
  9. interface
  10. uses
  11.   {$IFDEF FPC} FPCWindows, {$ENDIF}
  12.   ShlObj,
  13.   SysUtils,                // ToDo: Move to advanced unit
  14.   Windows, Messages,
  15.   ShellAPI,
  16.   Basics, BaseTypes, BaseMsg;
  17. const
  18.   kernel = 'kernel32.dll';
  19. type
  20.   THandle = Cardinal;
  21.   TKbdState = array[0..255] of Byte;
  22.   TRect = Windows.TRect;
  23.   // System path
  24.   TSysFolder = (sfRecycled, sfDesktop, sfStartMenu, sfPrograms, sfStartup, sfPersonal, sfTemplates, sfRecent, sfSendTo, sfNetHood, sfAppData, sfWinRoot, sfWinSys);
  25. // OS dependent
  26. procedure ObtainCursorPos(var X, Y: Integer);
  27. procedure SetCursorPos(X, Y: Integer);
  28. function AdjustCursorVisibility(Show: Boolean): Integer;
  29. procedure ClipCursor(Rect: TRect);
  30. function GetClipCursor: TRect;
  31. procedure GetWindowRect(Handle: THandle; out Rect: TRect);
  32. procedure GetClientRect(Handle: THandle; out Rect: TRect);
  33. procedure ScreenToClient(Handle: THandle; out X, Y: Integer);
  34. procedure ClientToScreen(Handle: THandle; out X, Y: Integer);
  35. procedure ShowWindow(Handle: THandle);
  36. procedure HideWindow(Handle: THandle);
  37. procedure MinimizeWindow(Handle: THandle);
  38. function IsWindowVisible(Handle: THandle): Boolean;
  39. procedure SetWindowCaption(Handle: THandle; const ACaption: string);
  40. procedure ObtainKeyboardState(var State: TKbdState);
  41. function GetAsyncKeyState(Key: Integer): Integer;
  42. function GetOSErrorStr(ErrorID: Integer): string;
  43. function ActivateWindow(hwnd: THandle): Boolean;
  44. function GetCurrentMs: Cardinal;
  45. procedure ObtainPerformanceFrequency;
  46. function GetPerformanceCounter: Int64;
  47. procedure OpenWith(ParentHandle: Cardinal; const FileName: string);
  48. procedure OpenURL(const URL: string);
  49. function ThreadSafeIncrement(var Addend: Integer): Integer; stdcall; external kernel name 'InterlockedIncrement';
  50. function ThreadSafeDecrement(var Addend: Integer): Integer; stdcall; external kernel name 'InterlockedDecrement';
  51. function WMToMessage(MsgID: Cardinal; wParam, lParam: Integer): TMessage; overload;
  52. function WMToMessage(const Msg: Messages.TMessage): TMessage; overload;
  53. procedure Sleep(Milliseconds: Integer);           // Not accurate (~10ms)
  54. procedure Delay(Microseconds: Integer);           // Accurate
  55. procedure Exec(const Command: string);
  56. function GetActiveWindow: THandle;
  57. function GetSysFolder(SysFolder: TSysFolder): string;
  58. function GetTextFromClipboard: string;
  59. // OS independent
  60. procedure SetCursorVisibility(Counter: Integer);
  61. procedure ShowCursor;
  62. procedure HideCursor;
  63. var
  64.   PerformanceFrequency: Int64;
  65.   OneOverPerformanceFrequency: Single;
  66. implementation
  67. // OS dependent
  68. procedure ObtainCursorPos(var X, Y: Integer);
  69. var Pnt: TPoint;
  70. begin
  71.   Windows.GetCursorPos(Pnt);
  72.   X := Pnt.X; Y := Pnt.Y;
  73. end;
  74. procedure SetCursorPos(X, Y: Integer);
  75. begin
  76.   Windows.SetCursorPos(X, Y);
  77. end;
  78. function AdjustCursorVisibility(Show: Boolean): Integer;
  79. begin
  80.   Result := Windows.ShowCursor(Show);
  81. end;
  82. procedure ClipCursor(Rect: TRect);
  83. begin
  84.   Windows.ClipCursor(@Rect);
  85. end;
  86. function GetClipCursor: TRect;
  87. begin
  88.   Windows.GetClipCursor(Result);
  89. end;
  90. procedure GetWindowRect(Handle: THandle; out Rect: TRect);
  91. begin
  92.   Windows.GetWindowRect(Handle, Rect)
  93. end;
  94. procedure GetClientRect(Handle: THandle; out Rect: TRect);
  95. begin
  96.   Windows.GetClientRect(Handle, Rect)
  97. end;
  98. procedure ScreenToClient(Handle: THandle; out X, Y: Integer);
  99. var Pnt: TPoint;
  100. begin
  101.   Pnt.X := X; Pnt.Y := Y;
  102.   Windows.ScreenToClient(Handle, Pnt);
  103.   X := Pnt.X; Y := Pnt.Y;
  104. end;
  105. procedure ClientToScreen(Handle: THandle; out X, Y: Integer);
  106. var Pnt: TPoint;
  107. begin
  108.   Pnt.X := X; Pnt.Y := Y;
  109.   Windows.ClientToScreen(Handle, Pnt);
  110.   X := Pnt.X; Y := Pnt.Y;
  111. end;
  112. procedure ShowWindow(Handle: THandle);
  113. begin
  114.   Windows.ShowWindow(Handle, SW_SHOWNORMAL);
  115. end;
  116. procedure HideWindow(Handle: THandle);
  117. begin
  118.   Windows.ShowWindow(Handle, SW_HIDE);
  119. end;
  120. procedure MinimizeWindow(Handle: THandle);
  121. begin
  122.   Windows.ShowWindow(Handle, SW_MINIMIZE);
  123. end;
  124. function IsWindowVisible(Handle: THandle): Boolean;
  125. begin
  126.   Result := Windows.IsWindowVisible(Handle);
  127. end;
  128. procedure SetWindowCaption(Handle: THandle; const ACaption: string);
  129. begin
  130.   Windows.SetWindowText(Handle, PChar(ACaption));
  131. end;
  132. procedure ObtainKeyboardState(var State: TKbdState);
  133. begin
  134.   Windows.GetKeyboardState(TKeyboardState(State));
  135. end;
  136. function GetAsyncKeyState(Key: Integer): Integer;
  137. begin
  138.   Result := Windows.GetAsyncKeyState(Key);
  139. end;
  140. function WMToMessage(MsgID: Cardinal; wParam, lParam: Integer): TMessage; overload;
  141. begin
  142.   case MsgID of
  143.     WM_ACTIVATEAPP: begin
  144.       if wParam = 0 then Result := TWindowDeactivateMsg.Create else Result := TWindowActivateMsg.Create;
  145.     end;  
  146. //    WM_EXITSIZEMOVE: 
  147.     WM_SIZE: begin
  148.       if wParam = SIZE_MINIMIZED then
  149.         Result := TWindowMinimizeMsg.Create else
  150.           Result := TWindowResizeMsg.Create(0, 0, lParam and 65535, lParam shr 16);
  151.     end;  
  152.     WM_MOVE:       Result := TWindowMoveMsg.Create(lParam and 65535, lParam shr 16);
  153.     WM_CANCELMODE: Result := TCancelModeMsg.Create;
  154.     WM_CHAR:       Result := TCharInputMsg.Create(Chr(wParam), lParam);
  155.     WM_SYSCOMMAND: Result := TWindowMenuCommand.Create(wParam);
  156.     else Result := TMessage.Create; 
  157.   end;
  158.   Result.Flags := Result.Flags + [mfCore];
  159. end;
  160. function WMToMessage(const Msg: Messages.TMessage): TMessage; overload;
  161. begin
  162.   Result := WMToMessage(Msg.Msg, Msg.WParam, Msg.LParam);
  163. end;
  164. function GetOSErrorStr(ErrorID: Integer): string;
  165. var s: PChar;
  166. begin
  167.   GetMem(s, 2000);
  168.   FormatMessage({FORMAT_MESSAGE_ALLOCATE_BUFFER or }FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
  169.                 nil, ErrorID, 0, s, 2000, nil);
  170.   Result := s;
  171.   FreeMem(s);
  172. end;
  173. function ActivateWindow(hwnd: THandle): Boolean;
  174. var Input: TInput;
  175. begin
  176.   Result:= True;
  177.   if hwnd = GetForegroundWindow then Exit;
  178.   if IsWindow(hwnd) then begin
  179.     Input.Itype:= Input_Mouse;
  180.     FillChar(Input.mi, SizeOf(Input.mi), 0);
  181.     SendInput(1, Input, SizeOf(Input));
  182.     Result := SetForegroundWindow(hwnd);
  183. //    SetActiveWindow(hwnd);
  184.     if IsIconic(hwnd) then OpenIcon(hwnd);
  185.     Exit;
  186.   end;
  187.   Result:= False;
  188. end;
  189. function GetCurrentMs: Cardinal;
  190. begin
  191.   Result := GetTickCount;
  192. end;
  193. procedure ObtainPerformanceFrequency;
  194. begin
  195.   if QueryPerformanceFrequency(PerformanceFrequency) then begin
  196.     if PerformanceFrequency <> 0 then OneOverPerformanceFrequency := 1 / PerformanceFrequency else OneOverPerformanceFrequency := 0;
  197.   end else PerformanceFrequency := 0;
  198. end;
  199. function GetPerformanceCounter: Int64;
  200. begin
  201.   QueryPerformanceCounter(Result);
  202. end;
  203. procedure OpenWith(ParentHandle: Cardinal; const FileName: string);
  204. begin
  205.   ShellExecute(ParentHandle, 'open', PChar('rundll32.exe'),
  206.     PChar('shell32.dll,OpenAs_RunDLL ' + FileName), nil, SW_SHOWNORMAL);
  207. end;
  208. procedure OpenURL(const URL: string);
  209. begin
  210.   ShellExecute(0, 'open', PChar(URL), nil, nil, SW_SHOWNORMAL);
  211.   Sleep(500);                                                    // To eliminate some bugs with timer
  212. end;
  213. // OS independent
  214. procedure SetCursorVisibility(Counter: Integer);
  215. var i, Cur: Integer;
  216. begin
  217.   Cur := AdjustCursorVisibility(True);
  218.   for i := 0 to Abs(Cur-Counter)-1 do AdjustCursorVisibility(Cur < Counter);
  219. end;
  220. procedure ShowCursor;
  221. begin
  222.   SetCursorVisibility(0);
  223. end;
  224. procedure HideCursor;
  225. begin
  226.   SetCursorVisibility(-1);
  227. end;
  228. procedure Sleep(Milliseconds: Integer);
  229. begin
  230.   Windows.Sleep(Milliseconds);
  231. end;
  232. procedure Delay(Microseconds: Integer);
  233. var Cnt, Dest: Int64;
  234. begin
  235.   Cnt := GetPerformanceCounter;
  236.   Dest := Cnt + Microseconds * PerformanceFrequency div 1000000;
  237.   while GetPerformanceCounter < Dest do;
  238. end;
  239. procedure Exec(const Command: string);
  240. begin
  241.   ShellExecute({Starter.WindowHandle}0, 'open', PChar(Command), nil, nil, SW_SHOWNORMAL);
  242.   Sleep(500);
  243. end;
  244. function GetActiveWindow: THandle;
  245. begin
  246.   Result := Windows.GetActiveWindow;
  247. end;
  248. function GetSysFolder(SysFolder: TSysFolder): string;
  249. var
  250.  s: PChar;
  251.  p: PItemIDList;
  252.  Folder: Integer;
  253. begin
  254.    Result := '';
  255.    p := nil;
  256.    case SysFolder of
  257.      sfRecycled:  Folder := CSIDL_BITBUCKET;
  258.      sfDesktop:   Folder := CSIDL_DESKTOPDIRECTORY;
  259.      sfStartMenu: Folder := CSIDL_STARTMENU;
  260.      sfPrograms:  Folder := CSIDL_PROGRAMS;
  261.      sfStartup:   Folder := CSIDL_STARTUP;
  262.      sfPersonal:  Folder := CSIDL_PERSONAL;
  263.      sfRecent:    Folder := CSIDL_RECENT;
  264.      sfNetHood:   Folder := CSIDL_NETHOOD;
  265.      sfSendTo:    Folder := CSIDL_SENDTO;
  266.      sfTemplates: Folder := CSIDL_TEMPLATES;
  267.      sfAppData:   Folder := CSIDL_APPDATA;
  268. //     sfWinRoot:   Folder :=
  269. //     sfWinSys:    Folder :=
  270.      else begin
  271.        Assert(False);
  272.        Exit;
  273.      end;
  274.    end;
  275.    if (SHGetSpecialFolderLocation(0 ,Folder, p) <> NOERROR) or (p = nil) then Exit;
  276.    s := StrAlloc(MAX_PATH+1);
  277.    if SHGetPathFromIDList(p, s) then Result := s;
  278.    StrDispose(s);
  279. end;
  280. function GetTextFromClipboard: string;
  281. var hg: THandle; P: PChar;
  282. begin
  283.   OpenClipboard(0);
  284.   hg := GetClipboardData(CF_TEXT);
  285.   CloseClipboard;
  286.   P := GlobalLock(hg);
  287.   Result := Copy(P, 0, Length(P));
  288.   GlobalUnlock(hg);
  289. end;
  290. begin
  291.   ObtainPerformanceFrequency;
  292. end.