Конференция "WinAPI" » Перехват сообщений самодельным окном. [D7, WinXP]
 
  • Galiaf © (18.02.08 00:24) [0]
    Доброго времени суток! Столкнулся с проблемой перехвата сообщений или событий окном созданным средствами WinAPI.<br>
    В общем я создаю класс окна в одном модуле(wnd.pas) и дочерний класс в другом(main.pas), при этом у меня одна локальная процедура WndProc для всех окон. Я пробовал прописывать в дочернем классе процедуру для перехвата сообщений как делал это раньше на VCL
    procedure WMPaint(var Msg : TWMPaint);  message wm_paint;


    Ничего не получилось, наверное я неправильно понимаю как работает такой способ перехвата, может быть надо присваивать каждому классу свой хэндл, ведь сообщения посылаются владельцу хэндла, но я не знаю как такое реализовать. <br>
    Теперь пробую сделать события как на VCL (onPaint), но тоже пока безуспешно.
    Заранее спасибо!
  • Бегущий человек © (18.02.08 03:45) [1]
    У Вас должен после CreateWindowEx запускацца цикл обработки сообщений...до Application.Terminate. Советую глянуть примеры на masm32
  • Сергей М. © (18.02.08 09:22) [2]
    Показывай код
  • Galiaf © (18.02.08 10:38) [3]
    Цикл обработки сообщений у меня для всех окон один - это

    function WndProc(wnd: HWND; msg: integer; wParam: wParam; lParam: lParam): lResult; stdCall;
    begin
     result:=0;
     case msg of
       wm_Destroy:
         begin
           PostQuitMessage(0);
           Exit
         end;
     else Result:=DefWindowProc(wnd,msg,wparam,lparam)
     end;//case
    end;


    Прописывать обработку сообщений здесь не получиться т.к. окон может быть много, да и доступа к модулю main.pas из модуля wnd.pas нет и быть не должно(пишу с расчетом на то, что в будующем буду пользоваться этим модулем и в других программах). Единственный вариант - это прописать там  события класса tApp, который создается в модуле wnd.pas и тот в свою очередь будет обрабатывать события главного окна, а оно обрабатывать события дочернего окна и т.д.

     tFormClass = class of tFrm;

     tApp = class
     private
       MainForm: tFrm;
     public
       constructor Create;
       destructor Destroy; override;
       procedure CreateForm(FormClass: tFormClass; var FormName);
       procedure Run;
     end;


    И по этому я хотел прописать перехват только нужных сообщений в дочернем классе формы который описывается в main.pas

     tMainForm = class(tFrm)
       procedure FormCreate;
     private
       procedure Load;
       procedure Draw;
     protected
       procedure WMPaint(var Msg : TWMPaint);  message wm_paint;
     end;


     Но процедура WMPaint не выполняется даже если в WndProc отсылать сообщение о перересовке.
     Так же покажу процедуру для создания формы в классе tApp, потому, что этот код мне не полностью понятен, я его переписывал из forms.pas, может быть я тут допустил ошибку, но он работает, форма создается.

    procedure tApp.CreateForm(FormClass: tFormClass; var FormName);
    var
     Form: tFrm;
    begin
     Form:=tFrm(FormClass.NewInstance);
     tFrm(FormName):=Form;

     try
       Form.Create;
     except
       tFrm(FormName) := nil;
       raise;
     end;

     if MainForm = nil then begin
       MainForm := TFrm(Form);
     end;
    end;

  • Сергей М. © (18.02.08 11:04) [4]

    > Цикл обработки сообщений у меня для всех окон один - это


    Это не цикл, не выдумывай.
  • Galiaf © (18.02.08 11:33) [5]
    ну да, не цикл - обработка сообщений. Цикл здесь и однин для всей программы

    procedure tApp.Run;
    var
     Msg: tMsg;
    begin
     if not MainForm.CreateWnd then exit;
     while GetMessage(Msg, 0, 0, 0) do
       begin
         TranslateMessage(Msg);
         DispatchMessage(Msg);
       end
    end;


    или его для каждой формы свой нужно создавать???
    создание формы выглядит так


    function tFrm.CreateWnd: boolean;
    var
     wc: tWndClassEx;
    begin
     result:=true;
     zeromemory(@wc,sizeof(wc));
     with wc do begin
       cbSize:=sizeof(wc);
       style:=cs_hredraw or cs_vredraw;
       wc.cbClsExtra:=0;
       wc.cbWndExtra:=0;
       lpfnWndProc:=@WndProc;
       wc.hInstance:=HInstance;
       wc.hIcon:=LoadIcon(0,idi_application);
       hCursor:=LoadCursor(0, idc_Arrow);
       wc.hbrBackground:=COLOR_BTNFACE+1;
       wc.lpszMenuName:=nil;
       lpszClassName:=cName;
     end;
     if RegisterClassEx(wc)=0 then
       result:=false
     else
       handle:=CreateWindowEx(WS_EX_TOPMOST or WS_EX_TOOLWINDOW, cName, capt, WS_POPUP, left, top, width, height, 0, 0, HInstance, nil);
     if handle=0 then begin
       result:=false;
       exit
     end;
     show
    end;

  • Сергей М. © (18.02.08 12:01) [6]

    > Цикл здесь и однин для всей программы


    Не для "всей программы", а для для окон, созданных в тек.треде.


    > function tFrm.CreateWnd: boolean;


    Сравни с

    procedure TApplication.CreateHandle;

    и сделай выводы.
  • Galiaf (18.02.08 12:38) [7]
    Сравню, когда окажусь за компьютером, а пока могу только предполагать или ждать прямого ответа на вопрос.
  • Сергей М. © (18.02.08 12:49) [8]
    А ради чего вся эта жуткая каша из окон и форм тобой заварена ?
  • Galiaf (18.02.08 13:45) [9]
    Пишу на чистом WinAPI, получаю мелкий размер программы, больший контроль над программой, учусь, получаю удовольствия от программирования больше чем на VCL...
  • Сергей М. © (18.02.08 13:58) [10]

    > учусь, получаю удовольствия


    Похвально)
  • Leonid Troyanovsky © (18.02.08 13:59) [11]

    > Galiaf   (18.02.08 13:45) [9]

    > Пишу на чистом WinAPI, получаю мелкий размер программы,

    Понятно. Мазохист.
    Лучше получи удовольствие от книги.
    Например, Чарльз Калверт. Дельфи Х: Энциклопедия пользовавателя.

    --
    Regards, LVT.
  • Galiaf (18.02.08 14:15) [12]
    О чем книга? Сколько весит?
  • Leonid Troyanovsky © (18.02.08 14:23) [13]

    > Galiaf   (18.02.08 14:15) [12]

    > О чем книга? Сколько весит?

    Про дельфи, вестимо.
    Кг 1.5 бумаги.

    --
    Regards, LVT.
  • Galiaf (18.02.08 14:38) [14]
    А по-подробнее можно?
  • Leonid Troyanovsky © (18.02.08 14:53) [15]

    > Galiaf   (18.02.08 14:38) [14]

    > А по-подробнее можно?

    Подробнее можно в библиотеке.

    --
    Regards, LVT.
  • Galiaf (18.02.08 15:35) [16]
    Вернемся к теме: ближайшие 8-9 часов компьютера я не увижу, а по этому прошу написать мне код процедуры TApplication.CreateHandle; для дальнейшего изучения. Спасибо.
  • Сергей М. © (18.02.08 15:38) [17]

    procedure TApplication.CreateHandle;
    var
     TempClass: TWndClass;
     SysMenu: HMenu;
    begin
     if not FHandleCreated
    {$IFDEF MSWINDOWS}
       and not IsConsole then
    {$ENDIF}
    {$IFDEF LINUX}
       then
    {$ENDIF}
     begin
    {$IFDEF LINUX}
       FObjectInstance := WinUtils.MakeObjectInstance(WndProc);
    {$ENDIF}
    {$IFDEF MSWINDOWS}
       FObjectInstance := Classes.MakeObjectInstance(WndProc);
    {$ENDIF}
       WindowClass.lpfnWndProc := @DefWindowProc;
       if not GetClassInfo(HInstance, WindowClass.lpszClassName, TempClass) then
       begin
         WindowClass.hInstance := HInstance;
         if Windows.RegisterClass(WindowClass) = 0 then
           raise EOutOfResources.Create(SWindowClass);
       end;
       FHandle := CreateWindow(WindowClass.lpszClassName, PChar(FTitle),
         WS_POPUP or WS_CAPTION or WS_CLIPSIBLINGS or WS_SYSMENU
         or WS_MINIMIZEBOX,
         GetSystemMetrics(SM_CXSCREEN) div 2,
         GetSystemMetrics(SM_CYSCREEN) div 2,
         0, 0, 0, 0, HInstance, nil);
       FTitle := '';
       FHandleCreated := True;
       SetWindowLong(FHandle, GWL_WNDPROC, Longint(FObjectInstance));
       if NewStyleControls then
       begin
         SendMessage(FHandle, WM_SETICON, 1, GetIconHandle);
         SetClassLong(FHandle, GCL_HICON, GetIconHandle);
       end;
       SysMenu := GetSystemMenu(FHandle, False);
       DeleteMenu(SysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
       DeleteMenu(SysMenu, SC_SIZE, MF_BYCOMMAND);
       if NewStyleControls then DeleteMenu(SysMenu, SC_MOVE, MF_BYCOMMAND);
     end;
    end;

  • dsoft © (19.02.08 01:13) [18]
    Это мазохизм? Зачем пытаться повторять VCl, в API принято писать несколько по другому.
  • Galiaf (19.02.08 01:26) [19]
    С этого места по-подробнее
 
Конференция "WinAPI" » Перехват сообщений самодельным окном. [D7, WinXP]
Есть новые Нет новых   [134431   +15][b:0][p:0.003]