-
> А почему именно так, скажи пожалуйста. Почему нельзя ставить > после создания окна?
потому что от момента вызова CreateWindow(Ex) до момента возврата из нее, в оконную процедуру приходит масса сообщений. И вполне вероятно, что некоторые потребуется обработать, уже имея указатель на класс, связанный с окном.
-
> Так в том-то и фишка, что они и так туда пихают указатель! Только теперь уже на некий фейковый объект.
Да ну? А кусок кода слабо привести где они GWL_USERDATA используют? В D7 и BDS2006 я что-то не нашел...
-
> [21] han_malign © (27.03.08 12:17)
RTFM... function AllocateHWnd(Method: TWndMethod): HWND;
var
TempClass: TWndClass;
ClassRegistered: Boolean;
begin
UtilWindowClass.hInstance := HInstance;
UtilWindowClass.lpfnWndProc := @DefWindowProc;
ClassRegistered := GetClassInfo(HInstance, UtilWindowClass.lpszClassName,
TempClass);
if not ClassRegistered or (TempClass.lpfnWndProc <> @DefWindowProc) then
begin
if ClassRegistered then
Windows.UnregisterClass(UtilWindowClass.lpszClassName, HInstance);
Windows.RegisterClass(UtilWindowClass);
end;
Result := CreateWindowEx(WS_EX_TOOLWINDOW, UtilWindowClass.lpszClassName,
'', WS_POPUP , 0, 0, 0, 0, 0, 0, HInstance, nil);
if Assigned(Method) then
SetWindowLong(Result, GWL_WNDPROC, Longint(MakeObjectInstance(Method)));
end;
-
> [20] Игорь Шевченко © (27.03.08 11:48)
В общем случае - согласен, разумно. Однако в моём случае нужное сообщение только одно, и до определенного момента оно просто не приходит.
-
> [22] SpellCaster (27.03.08 12:48)
А, ну да, они там GWL_WNDPROC подменяют, прошу прощения.
-
> Уж сколько раз твердили миру: > > MyWnd := CreateWindow ('myclass', 'mycaption', > WS_OVERLAPPEDWINDOW, > Integer(CW_USEDEFAULT), > Integer(CW_USEDEFAULT), > Integer(CW_USEDEFAULT), > Integer(CW_USEDEFAULT), > HWND_DESKTOP, 0, > HInstance, Self);
- вообще, почитав MSDN, тут лучше перестраховаться и передавать указатель на структуру packed record size: word; _self: TObject; .... end; - потому как не исключено, что это дело нацеливалось на копирование пользовательских данных... скорее всего, конечно, для валидации, но если в очередном сервис-паке Висты все нагнется - я сильно не удивлюсь.
-
han_malign © (27.03.08 13:20) [25]
Не, оно не копируется. Внутре указатель передается.
-
Набрел на еще один способ: случайно узнал о таких полезных функциях, как Get/SetProp. Теперь можно присваивать так: SetProp(wnd,PropName,LParam(Self)); и извлекать obj := TMyObject(Pointer(GetProp(wnd,PropName)));
if obj = nil
then Result := False
else Result := obj.DialogProc(wnd, msg, wParam, lParam);
-
> guav © (26.03.08 17:17) [12]
> Меня больше интересует какие недостатки у более прямого > пути, без asm кода.
Не понял, что есть "прямой", но GetWindowLong - медленней. Как, впрочем, и GetProp.
-- Regards, LVT.
-
> SpellCaster (26.03.08 17:03) [11] > У тебя, насколько я понимаю, некий аналог AllocateWnd - > то же выделение объекта и тот же хак с подменой адресов. > Благодарю, однако хочется без читов :)
Сам ты хак и чит. AllocateWnd выделяет память честно - for execute. И не подмена, а выделение функции ок. проц. для каждого экз. класса.
Вот, те кто реализовывал ок. проц. на стеке - тот пострадал. Может даже MFC or SWL, не упомню уж.
-- Regards, LVT.
-
> Leonid Troyanovsky © (19.11.08 19:29) [29]
> AllocateWnd выделяет память честно - for execute.
В смысле MakeObjectInstance, или как его, sorry.
-- Regards, LVT.
-
Leonid Troyanovsky © (19.11.08 19:29) [29] Вот, те кто реализовывал ок. проц. на стеке - тот пострадал. Например я :) Я еще недоумевал, зачем они делают так сложно, когда можно хранить процедуру в самом объекте :)
|