Конференция "WinAPI" » Отловить событие мыши.
 
  • OlegNik © (08.05.09 10:16) [0]
    День добрый.
    У меня такой вопрос как отловить событие мыши.
    При следующих условиях.
    Пользователь дает Panel.Handle и мне необходимо из своей библиотечины запихнуть ему красивый рисунок или еще что.
    Как мне отловить событие MouseMove MouseClick?
  • Сергей М. © (08.05.09 10:40) [1]

    > запихнуть ему .. еще что


    Поколотит он ведь тебя)

    А мышь-то причем ? Ты мышь ему запихнуть собрался ?
  • OlegNik © (08.05.09 10:56) [2]
    Нет просто пользователь моей библиотеки дает мне панель для выполнения
    определенных задач. Где придется вставить пару кнопочек. Которые в свою очередь должны запустить мою задачу. Которая в свою очередь выводит результат расчета на Canvas панельки. Ну а событие мыши на этой панельни мне необходимы для последующих дествий. (кое что перерешать, кое что подтенуть ну чтото в этом духе)
  • Сергей М. © (08.05.09 11:01) [3]
    Т.е. хост-приложение, пользующее твою dll, не обязано быть исключительно дельфийским VCL-приложением, так ?
  • OlegNik © (08.05.09 11:15) [4]
    Угу.
  • OlegNik © (08.05.09 11:17) [5]
    Даже я бы сказал такю На форме пользователя есть местечко которое отдается мне на подзадачу.
  • Сергей М. © (08.05.09 11:30) [6]
    Ну тогда ни о каких Canvas и "панельках" не может идти и речи.

    Первое, что следует проделать - определить, какому треду хост-процесса принадлежит окно, хэндл которого тобой получен (GetWindowThreadProcessId)

    Далее следует установка лок.хука WH_MOUSE на поток-владелец окна (SetWindowsHookEx)
  • OlegNik © (08.05.09 15:16) [7]
    Делаю следующим образом
    var
    FCanvas : TCanvas;
    SysHook : HHook = 0;
       
        FHandle := AValue;
        FCanvas.Handle:=GetDC(FHandle);
        GetClientRect(FHandle,FRect);
        FCanvas.Rectangle(0, 0, FRect.Right, FRect.Bottom);
        ....
        ReleaseDC(FCanvas.Handle,FHandle);    
    {вроде нормально выводит для Usera}

        но с Hookами похоже не дружу
       
    function MouseProc(Code : Integer; wParam : word; lParam : Longint): Longint;
    begin
      Result := CallNextHookEx(SysHook, Code, wParam, lParam);
      if Code = MSGF_NEXTWINDOW then begin
           {вроде надо repaint}
      end;
      {так пока примеряюсь к x,y}
      Application.MessageBox(PChar(
                              IntToStr(TCBTCreateWnd(Pointer(lParam)^).lpcs.cy+#13#10
                            +IntToStr(TCBTCreateWnd(Pointer(lParam)^).lpcs.cx)),'',0);

    end;

        function SetHook(): Integer;
        begin
         SysHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, HInstance,0);     {самое смешное вылетает так что запускаю Delphi по новой}
        end;

    что не так
  • Сергей М. © (08.05.09 16:53) [8]
    SysHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, ID_треда_ создавшего_окно_с_переданным_тебе_хэндлом);

    ..

    function MouseProc(Code : Integer; wParam: WPARAM; var lParam: MOUSEHOOKSTRUCT): Longint; stdcall;
    begin
     if (Code = HC_ACTION) and (lParam.HWND = переданный тебе хэндл окна) then        
     begin
    // нижеследующее мышиное событие
    // произошло при нахождении мышиного курсора в точке с абсолютными экранными координатами, значения которых указано в lParam.pt
       case wParam of
         WM_LBUTTONDBLCLK: ...
         WM_LBUTTONDOWN:  ...
         WM_LBUTTONUP:     ...
         WM_MBUTTONDOWN:...
         WM_MBUTTONUP: ...
         WM_RBUTTONDOWN: ...
         WM_RBUTTONUP: ...
         WM_MOUSEWHEEL: ...
         WM_MOUSEMOVE: ...
       end;
     end;
     Result := CallNextHookEx(SysHook, Code, wParam, WPARAM(@lParam);
    end;

  • OlegNik © (12.05.09 09:11) [9]
    Сергей М. Спасибааа.
  • Григорьев Антон © (12.05.09 11:42) [10]

    > Сергей М. ©   (08.05.09 11:30) [6]
    > Далее следует установка лок.хука WH_MOUSE на поток-владелец
    > окна (SetWindowsHookEx)

    По-моему, хук здесь - это излишне. Если можно быть уверенным, что весь интерфейс делается в главной нити (а так в большинстве случаев и бывает), достаточно перехватить оконную процедуру через SetWindowLong. Заодно получим возможность обрабатывать не только события мыши, но и, например, WM_Paint - там же есть задача вывода результата.
  • Сергей М. © (12.05.09 11:49) [11]

    > Григорьев Антон ©   (12.05.09 11:42) [10]


    > Если можно быть уверенным, что весь интерфейс делается в
    > главной нити (а так в большинстве случаев и бывает)


    Большинство - это не 100%)
  • Григорьев Антон © (12.05.09 11:51) [12]

    > Сергей М. ©   (12.05.09 11:49) [11]

    Ну так пусть автор уточнит, попадает его случай в большинство или нет.
  • OlegNik © (13.05.09 10:50) [13]
    И еще одни вопрос.(даже два)
    Могу ли я добавить в эту панель, cкажим пару (число мне точно не известно) объетов управления. (TButton или TEdit). Родителя мне не определить.
     Вернее можно создать цикл до  HWND1 = 0
      HWND1  := GetParent(HWND);
     но как потом  оформить
       TEdit.Create(TComponent), догадываюсь что функции
      HwndToComponent(h: HWND): TComponent не существует.
    Ну и второй вопрос. Как отловить изменение головной формы (где находится панелька), которое
    чинит узер (перемещение, сворачиване и т.д.)
  • Григорьев Антон © (13.05.09 11:20) [14]
    Есть у TWinControl конструктор CreateParented, который позволяет в качестве родителя указывать любое окно, а не только VCL'ное. Сам я ни разу не использовал его, так что не знаю, как он работает, а проблемы там просматриваются - например, такой родитель не сможет обработать нотификационные сообщения от своих детей по стандартам VCL, т.е. большинство событий работать не будет. Наверное, надо опять перехватытвать обработку сообщений родителем и искать там.
 
Конференция "WinAPI" » Отловить событие мыши.
Есть новые Нет новых   [134434   +27][b:0][p:0.001]