Конференция "WinAPI" » Заюзать метод класса как WindowProc
 
  • Игорь Шевченко © (27.03.08 11:48) [20]

    > А почему именно так, скажи пожалуйста. Почему нельзя ставить
    > после создания окна?


    потому что от момента вызова CreateWindow(Ex) до момента возврата из нее, в оконную процедуру приходит масса сообщений. И вполне вероятно, что некоторые потребуется обработать, уже имея указатель на класс, связанный с окном.
  • han_malign © (27.03.08 12:17) [21]

    > Так в том-то и фишка, что они и так туда пихают указатель!  Только теперь уже на некий фейковый объект.

    Да ну? А кусок кода слабо привести где они GWL_USERDATA используют? В D7 и BDS2006 я что-то не нашел...
  • SpellCaster (27.03.08 12:48) [22]
    > [21] han_malign ©   (27.03.08 12:17)

    RTFM...
    function AllocateHWnd(Method: TWndMethod): HWND;
    var
     TempClass: TWndClass;
     ClassRegistered: Boolean;
    begin
     UtilWindowClass.hInstance := HInstance;
    {$IFDEF PIC}
     UtilWindowClass.lpfnWndProc := @DefWindowProc;
    {$ENDIF}
     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, 0, HInstance, nil);
     if Assigned(Method) then
       SetWindowLong(Result, GWL_WNDPROC, Longint(MakeObjectInstance(Method)));
    end;

  • SpellCaster (27.03.08 12:52) [23]
    > [20] Игорь Шевченко ©   (27.03.08 11:48)

    В общем случае - согласен, разумно. Однако в моём случае нужное сообщение только одно, и до определенного момента оно просто не приходит.
  • SpellCaster (27.03.08 12:53) [24]
    > [22] SpellCaster   (27.03.08 12:48)

    А, ну да, они там GWL_WNDPROC подменяют, прошу прощения.
  • han_malign © (27.03.08 13:20) [25]

    > Уж сколько раз твердили миру:
    >
    >  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;
    - потому как не исключено, что это дело нацеливалось на копирование пользовательских данных... скорее всего, конечно, для валидации, но если в очередном сервис-паке Висты все нагнется - я сильно не удивлюсь.
  • Игорь Шевченко © (27.03.08 15:11) [26]
    han_malign ©   (27.03.08 13:20) [25]

    Не, оно не копируется. Внутре указатель передается.
  • SpellCaster (19.11.08 13:35) [27]
    Набрел на еще один способ: случайно узнал о таких полезных функциях, как 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);

  • Leonid Troyanovsky © (19.11.08 19:20) [28]

    > guav ©   (26.03.08 17:17) [12]

    > Меня больше интересует какие недостатки у более прямого
    > пути, без asm кода.

    Не понял, что есть "прямой", но GetWindowLong - медленней.
    Как, впрочем, и GetProp.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (19.11.08 19:29) [29]

    > SpellCaster   (26.03.08 17:03) [11]

    > У тебя, насколько я понимаю, некий аналог AllocateWnd -
    > то же выделение объекта и тот же хак с подменой адресов.
    >  Благодарю, однако хочется без читов :)

    Сам ты хак и чит.
    AllocateWnd выделяет память честно - for execute.
    И не подмена, а выделение функции ок. проц. для каждого экз. класса.

    Вот, те кто реализовывал ок. проц. на стеке - тот пострадал.
    Может даже MFC or SWL, не упомню уж.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (19.11.08 19:36) [30]

    > Leonid Troyanovsky ©   (19.11.08 19:29) [29]

    > AllocateWnd выделяет память честно - for execute.

    В смысле MakeObjectInstance, или как его, sorry.

    --
    Regards, LVT.
  • GrayFace © (23.11.08 04:08) [31]
    Leonid Troyanovsky ©   (19.11.08 19:29) [29]
    Вот, те кто реализовывал ок. проц. на стеке - тот пострадал.

    Например я :) Я еще недоумевал, зачем они делают так сложно, когда можно хранить процедуру в самом объекте :)
 
Конференция "WinAPI" » Заюзать метод класса как WindowProc
Есть новые Нет новых   [134435   +33][b:0][p:0.002]