window.inc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. {
  2. Free Pascal port of the OpenPTC C++ library.
  3. Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
  4. Original C++ version by Glenn Fiedler ([email protected])
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. }
  17. { $R win32\base\ptcres.res}
  18. { bug in the compiler???}
  19. { $LINKLIB ptc.owr}
  20. Constructor TWin32Window.Create(window : HWND);
  21. Begin
  22. LOG('attaching to user managed window');
  23. defaults;
  24. m_window := window;
  25. m_managed := False;
  26. End;
  27. Constructor TWin32Window.Create(wndclass, title : String; extra, style : DWord; show, x, y, width, height : Integer; center, _multithreaded : Boolean; data : Pointer);
  28. Begin
  29. internal_create(wndclass, title, extra, style, show, x, y, width, height, center, _multithreaded, data);
  30. End;
  31. Constructor TWin32Window.Create(wndclass, title : String; extra, style : DWord; show, x, y, width, height : Integer; center, _multithreaded : Boolean);
  32. Begin
  33. internal_create(wndclass, title, extra, style, show, x, y, width, height, center, _multithreaded, Nil);
  34. End;
  35. Destructor TWin32Window.Destroy;
  36. Begin
  37. close;
  38. Inherited Destroy;
  39. End;
  40. Procedure TWin32Window.cursor(flag : Boolean);
  41. Begin
  42. If flag Then
  43. Begin
  44. SetClassLong(m_window, GCL_HCURSOR, LoadCursor(0, IDC_ARROW));
  45. Win32Cursor_resurrect;
  46. End
  47. Else
  48. Begin
  49. SetClassLong(m_window, GCL_HCURSOR, 0);
  50. Win32Cursor_kill;
  51. End;
  52. SendMessage(m_window, WM_SETCURSOR, 0, 0);
  53. End;
  54. Procedure TWin32Window.resize(width, height : Integer);
  55. Var
  56. window_rectangle : RECT;
  57. rectangle : RECT;
  58. Begin
  59. GetWindowRect(m_window, window_rectangle);
  60. With rectangle Do
  61. Begin
  62. left := 0;
  63. top := 0;
  64. right := width;
  65. bottom := height;
  66. End;
  67. AdjustWindowRectEx(rectangle, m_style, False, m_extra);
  68. SetWindowPos(m_window, HWND_TOP, window_rectangle.left,
  69. window_rectangle.top, rectangle.right - rectangle.left,
  70. rectangle.bottom - rectangle.top, 0);
  71. {
  72. todo: detect if the window is resized off the screen and let windows reposition it correctly... ?
  73. }
  74. End;
  75. Procedure TWin32Window.update(force : Boolean);
  76. Var
  77. message : MSG;
  78. Begin
  79. If (Not m_managed) And (Not force) Then
  80. Exit;
  81. If Not m_multithreaded Then
  82. Begin
  83. While PeekMessage(message, m_window, 0, 0, PM_REMOVE) Do
  84. Begin
  85. TranslateMessage(message);
  86. DispatchMessage(message);
  87. End;
  88. End
  89. Else
  90. Sleep(0);
  91. End;
  92. Procedure TWin32Window.update; {force = False}
  93. Begin
  94. update(False);
  95. End;
  96. Function TWin32Window.handle : HWND;
  97. Begin
  98. handle := m_window;
  99. End;
  100. Function TWin32Window.thread : DWord;
  101. Begin
  102. If m_multithreaded Then
  103. thread := m_id
  104. Else
  105. thread := GetCurrentThreadId;
  106. End;
  107. Function TWin32Window.managed : Boolean;
  108. Begin
  109. managed := m_managed;
  110. End;
  111. Function TWin32Window.multithreaded : Boolean;
  112. Begin
  113. multithreaded := m_multithreaded;
  114. End;
  115. Function WndProcSingleThreaded(hWnd : HWND; message : UINT; wParam : WPARAM; lParam : LPARAM) : LRESULT; StdCall;
  116. Begin
  117. Case message Of
  118. WM_CLOSE : Begin
  119. LOG('TWin32Window WM_CLOSE');
  120. Halt(0);
  121. End;
  122. Else
  123. WndProcSingleThreaded := DefWindowProc(hWnd, message, wParam, lParam);
  124. End;
  125. End;
  126. Function WndProcMultiThreaded(hWnd : HWND; message : UINT; wParam : WPARAM; lParam : LPARAM) : LRESULT; StdCall;
  127. Begin
  128. WndProcMultiThreaded := 0;
  129. Case message Of
  130. WM_DESTROY : Begin
  131. LOG('TWin32Window WM_DESTROY');
  132. PostQuitMessage(0);
  133. End;
  134. WM_CLOSE : Begin
  135. LOG('TWin32Window WM_CLOSE');
  136. Halt(0);
  137. End;
  138. Else
  139. WndProcMultiThreaded := DefWindowProc(hWnd, message, wParam, lParam);
  140. End;
  141. End;
  142. Procedure TWin32Window.internal_create(wndclass, title : String; extra, style : DWord; show, x, y, width, height : Integer; center, _multithreaded : Boolean; data : Pointer);
  143. Var
  144. program_instance{, library_instance} : DWord;
  145. rectangle : RECT;
  146. display_width, display_height : Integer;
  147. wc : WNDCLASSEX;
  148. Begin
  149. LOG('creating managed window');
  150. defaults;
  151. m_multithreaded := _multithreaded;
  152. wndclass := wndclass + #0;
  153. title := title + #0;
  154. Try
  155. program_instance := GetModuleHandle(Nil);
  156. { library_instance := program_instance;}
  157. wc.cbSize := SizeOf(WNDCLASSEX);
  158. wc.hInstance := program_instance;
  159. wc.lpszClassName := @wndclass[1];
  160. wc.style := CS_VREDRAW Or CS_HREDRAW;
  161. wc.hIcon := 0{LoadIcon(library_instance, 'IDI_PTC_ICON')};
  162. wc.hIconSm := 0;
  163. wc.lpszMenuName := Nil;
  164. wc.cbClsExtra := 0;
  165. wc.cbWndExtra := 0;
  166. wc.hbrBackground := 0;{(HBRUSH) GetStockObject(BLACK_BRUSH)}
  167. If multithreaded Then
  168. Pointer(wc.lpfnWndProc) := Pointer(@WndProcMultiThreaded)
  169. Else
  170. Pointer(wc.lpfnWndProc) := Pointer(@WndProcSingleThreaded);
  171. wc.hCursor := LoadCursor(0, IDC_ARROW);
  172. RegisterClassEx(wc);
  173. With rectangle Do
  174. Begin
  175. left := 0;
  176. top := 0;
  177. right := width;
  178. bottom := height;
  179. End;
  180. AdjustWindowRectEx(rectangle, style, False, extra);
  181. If center Then
  182. Begin
  183. LOG('centering window');
  184. display_width := GetSystemMetrics(SM_CXSCREEN);
  185. display_height := GetSystemMetrics(SM_CYSCREEN);
  186. x := (display_width - (rectangle.right - rectangle.left)) Div 2;
  187. y := (display_height - (rectangle.bottom - rectangle.top)) Div 2;
  188. End;
  189. Move(wndclass[1], m_name, Length(wndclass));
  190. Move(title[1], m_title, Length(title));
  191. m_extra := extra;
  192. m_style := style;
  193. m_show := show;
  194. m_x := x;
  195. m_y := y;
  196. m_width := rectangle.right - rectangle.left;
  197. m_height := rectangle.bottom - rectangle.top;
  198. m_data := data;
  199. If multithreaded Then
  200. Begin
  201. {...}
  202. End
  203. Else
  204. Begin
  205. m_window := CreateWindowEx(m_extra, m_name, m_title, m_style, m_x, m_y, m_width, m_height, 0, 0, 0, m_data);
  206. If Not IsWindow(m_window) Then
  207. Raise TPTCError.Create('could not create window');
  208. ShowWindow(m_window, m_show);
  209. SetFocus(m_window);
  210. SetActiveWindow(m_window);
  211. SetForegroundWindow(m_window);
  212. End;
  213. Except
  214. On error : TPTCError Do
  215. Raise TPTCError.Create('could not create window', error);
  216. End;
  217. End;
  218. Procedure TWin32Window.defaults;
  219. Begin
  220. m_window := 0;
  221. m_event := 0;
  222. m_thread := 0;
  223. m_id := 0;
  224. m_name[0] := #0;
  225. m_title[0] := #0;
  226. m_extra := 0;
  227. m_style := 0;
  228. m_show := 0;
  229. m_x := 0;
  230. m_y := 0;
  231. m_width := 0;
  232. m_height := 0;
  233. m_data := Nil;
  234. m_managed := True;
  235. m_multithreaded := False;
  236. End;
  237. Procedure TWin32Window.close;
  238. Begin
  239. If Not m_managed Then
  240. Begin
  241. LOG('detaching from user managed window');
  242. m_window := 0;
  243. End
  244. Else
  245. Begin
  246. LOG('closing managed window');
  247. If m_multithreaded Then
  248. Begin
  249. If (m_thread <> 0) And IsWindow(m_window) Then
  250. Begin
  251. PostMessage(m_window, WM_DESTROY, 0, 0);
  252. WaitForSingleObject(m_thread, INFINITE);
  253. End;
  254. If m_event <> 0 Then
  255. CloseHandle(m_event);
  256. If m_thread <> 0 Then
  257. CloseHandle(m_thread);
  258. SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS);
  259. End
  260. Else
  261. If (m_window <> 0) And IsWindow(m_window) Then
  262. DestroyWindow(m_window);
  263. m_window := 0;
  264. m_event := 0;
  265. m_thread := 0;
  266. m_id := 0;
  267. UnregisterClass(@m_name, GetModuleHandle(Nil));
  268. End;
  269. End;
  270. Class Procedure TWin32Window.ThreadFunction(owner : TWin32Window);
  271. Var
  272. message : MSG;
  273. Begin
  274. With owner Do
  275. Begin
  276. m_window := CreateWindowEx(m_extra, @m_name, @m_title, m_style, m_x, m_y, m_width, m_height, 0, 0, 0, m_data);
  277. If IsWindow(m_window) Then
  278. Begin
  279. ShowWindow(m_window, m_show);
  280. SetFocus(m_window);
  281. SetForegroundWindow(m_window);
  282. SetEvent(m_event);
  283. While GetMessage(message, 0, 0, 0) = True Do
  284. Begin
  285. TranslateMessage(message);
  286. DispatchMessage(message);
  287. End;
  288. End
  289. Else
  290. SetEvent(m_event);
  291. End;
  292. End;