Author: Tomas Rutkauskas
I have a (separate) thread that spends most of its time waiting for
(synchronisation) events, and when an event occurs it performs some processing
which involves user-specific (Delphi) event handling. In these event handlers I
would now like to be able to create objects that uses Windows messages, such as
TTimers or some other own-developed components we have, and that these objects
should be able to generate (Delphi) events as they normally would (although
executed in my separate thread, of course).
Answer:
I usually use messages within threads and works fine, I attach 2 procedures that
allows you to create/ free a window handle inside a TThread object and to use the
standard Delphi way to handle messages. The function are:
CreateWindowHandle(AObject: TObject): integer;
FreeWindowHandle(AHandle: integer);
You should use them in the following way:
1 { ... }
2 type
3 TMyThread = class(TThread)
4 private
5 hwnd: integer;
6 protected
7 procedure handler1(var message: TMessage); message WM_USER; {or any other
8 message}
9 end;
10
11 constructor Create { ... }
12 begin
13 { ... }
14 hwnd := CreateWindowHandle(Self);
15 { ... }
16 end;
17
18 destructor Destroy { ... }
19 begin
20 { ... }
21 freewindowhandle(hwnd);
22 { ... }
23 end;
24
25 var
26 ObjectWindowClass: TWndClass = (style: 0; lpfnWndProc: @windows.DefWindowProc;
27 cbClsExtra: 0; cbWndExtra: 0; hInstance: 0; hIcon: 0;
28 hCursor: 0; hbrBackground: 0; lpszMenuName: nil;
29 lpszClassName: 'ObjectWindowClass@wbuwbvubvy');
30
31 function ObjectWindowProc(HWnd, Msg, wParam, lParam: integer): integer; stdcall;
32 var
33 m: TMessage;
34 begin
35 m.Msg := uint(msg);
36 m.wParam := wParam;
37 m.lParam := lParam;
38 TObject(GetWindowLong(hwnd, GWL_USERDATA)).Dispatch(m);
39 result := m.Result;
40 end;
41
42 function CreateWindowHandle(AObject: TObject): integer;
43 var
44 TempClass: TWndClass;
45 ClReg: Boolean;
46 hwnd: integer;
47 begin
48 {register the window class (if not already registered) }
49 ObjectWindowClass.hInstance := HInstance;
50 ClReg := GetClassInfo(HInstance, ObjectWindowClass.lpszClassName, TempClass);
51 if (not ClReg) or (TempClass.lpfnWndProc <> @windows.DefWindowProc) then
52 begin
53 if ClReg then
54 Windows.UnregisterClass(ObjectWindowClass.lpszClassName, HInstance);
55 Windows.RegisterClass(ObjectWindowClass);
56 end;
57 {create the window}
58 HWnd := CreateWindow(ObjectWindowClass.lpszClassName, '', 0, 0, 0, 0, 0, 0, 0,
59 HInstance, nil);
60 {subclass the window}
61 SetWindowLong(HWnd, GWL_USERDATA, integer(AObject));
62 SetWindowLong(HWnd, GWL_WNDPROC, integer(@ObjectWindowProc));
63 Result := HWnd;
64 end;
65
66 procedure FreeWindowHandle(AHandle: integer);
67 begin
68 SetWindowLong(AHandle, GWL_WNDPROC, integer(@windows.DefWindowProc));
69 DestroyWindow(AHandle);
70 end;
|