Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват сообщений от Dll 
:(
    Опции темы
kiLLProg
  Дата 1.10.2008, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Всем привет.
Пишу программу, которая перехватывает клики мыши и ведёт протокол нажатий в Memo. Сообщения перехватывает хук в ДЛЛке, но не могу переправить события кликов в управляющее приложение, которое загружает хук. Помогите исправит эту проблему. Заранее благодарен.

Код В ДЛЛ:
Код

#include <windows.h> 
#pragma argsused 

MOUSEHOOKSTRUCT* psMouseHook; // Для анализа сообшений от мыши 
HWND h; 

extern "C" __declspec(dllexport) LRESULT CALLBACK MouseHook(int,WPARAM,LPARAM); 

//--------------------------------------------------------------------------- 
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) 
{ 
    return 1; 
} 

//--------------------------------------------------------------------------- 
// Ловушка мыши 
LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam) 
{ 
  int x1, y1; 

  /* 
  if(wParam==WM_MOUSEMOVE || wParam==WM_NCMOUSEMOVE) 
  { 
  */ 

    //h = FindWindow("TForm1", "Form1"); 
    psMouseHook=(MOUSEHOOKSTRUCT*)(lParam); 
    HWND par_win = psMouseHook->hwnd;//дескриптор окна над которым находится мышка 
    HWND main_wind = FindWindow(NULL, "Form1");//ищем окно, загрузившее нашу dll с ловушкой 

    switch( LOWORD( wParam ) ) 
    { 
      case WM_LBUTTONDOWN: 
        //PostMessage(h, 1, 0, 0); 
        // Посылаем сообщение приложению 
        PostMessage(main_wind, 1, (WPARAM)par_win, (LPARAM)psMouseHook->hwnd); 
        Beep(1000, 200); 
        break; 
    }    

   /* 
    if (wParam == WM_LBUTTONDOWN) 
    { 
      //PostMessage(h, WM_LBUTTONDOWN, 0, 0); 
      PostMessage(h, 1, 0, 0); 
      Beep(1000, 200); 
    } 
   */ 
return 0; 
} 


Сообщения доходят до приложения(при PostMessage(main_wind, WM_CLOSE, 0, 0) прога подвисает), возможно я просто неправильно их обрабатываю. 
А обрабатываю эти сообщения так:

Код

// компонент ApplicationEvents 
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, 
      bool &Handled) 
{ 
  switch(Msg.message) 
  { 
    //case WM_LBUTTONDOWN:   // пробую так и сяк, не помогает... 
    case 1: 
      Memo1->Lines->Add("Левый клик !!!"); 
      break; 
    //case WM_LBUTTONDBLCLK: 
    case 2: 
      Memo1->Lines->Add("Двойной левый клик !!!"); 
      break; 
   } 
   if (Msg.message == 1) 
   { 
     Memo1->Lines->Add("Левый клик !!!"); 
   } 
}

PM MAIL   Вверх
ama_kid
Дата 1.10.2008, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 5
Всего: 95



1) Мне почему-то кажется, что сообщение с номером 1 системой будет понято неправильно...
2) глобальный мышиный хук WH_MOUSE_LL можно ставить и внутри своего приложения, его незачем пихать в dll (если нет других противопоказаний). 

Вывод: тебе надо внимательнее почитать про принцип работы системных сообщений и про хуки...


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
kiLLProg
Дата 1.10.2008, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Из-за большого числа комментариев проге, тебе должно было понятно, что пробовал я так и сяк. Плюс еще, событие двойного клика перехватывает только хук в дЛЛ. Я пробовал и без длл, но я хочу нормально разобраться postMessag"ем.
PM MAIL   Вверх
586
Дата 1.10.2008, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Цитата(kiLLProg @  1.10.2008,  14:25 Найти цитируемый пост)
psMouseHook=(MOUSEHOOKSTRUCT*)(lParam); 

Глобальные переменные опасны при многопоточности. Определи эту переменную ВНУТРИ функции MouseHook.

Цитата(kiLLProg @  1.10.2008,  14:25 Найти цитируемый пост)
PostMessage(main_wind, 1, (WPARAM)par_win, (LPARAM)psMouseHook->hwnd); 

замени на
Код
PostMessage(main_wind, WM_USER+1, wParam, (LPARAM)psMouseHook->hwnd);


Цитата(kiLLProg @  1.10.2008,  14:25 Найти цитируемый пост)
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, 
      bool &Handled) 
{ 
  switch(Msg.message) 
  { 
    //case WM_LBUTTONDOWN:   // пробую так и сяк, не помогает... 
    case 1: 
      Memo1->Lines->Add("Левый клик !!!"); 
      break; 
    //case WM_LBUTTONDBLCLK: 
    case 2: 
      Memo1->Lines->Add("Двойной левый клик !!!"); 
      break; 
   } 
   if (Msg.message == 1) 
   { 
     Memo1->Lines->Add("Левый клик !!!"); 
   } 
}

замени на
Код
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, 
      bool &Handled) 
{ 
  if(Msg.mesage == (WM_USER+1))
  {
    switch(Msg.wParam) 
    { 
    case WM_LBUTTONDOWN: 
      Memo1->Lines->Add("Левый клик !!!"); 
      break; 
    case WM_LBUTTONDBLCLK: 
      Memo1->Lines->Add("Двойной левый клик !!!"); 
      break; 
   } 
    Handled = true;
    return;
  }
  Handled = false;
}

код ловушки:
Код
LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam) 
{ 
    if(nCode >= 0)
    {
        MOUSEHOOKSTRUCT *psMouseHook=(MOUSEHOOKSTRUCT*)(lParam); 
        HWND par_win = 0;
        if(psMouseHook) par_win = psMouseHook->hwnd;
        HWND main_wind = FindWindow(NULL, "Form1");

        if(main_wind) PostMessage(main_wind, WM_USER+1, wParam, (LPARAM)par_win); 
    }    
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}


Это сообщение отредактировал(а) 586 - 1.10.2008, 19:23
PM   Вверх
kiLLProg
Дата 2.10.2008, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Спасибо за ответ! Реально, чудесным образом заработало как надо! Изменил код ДЛЛ на ваш и код обработчика то же. Но ваш обработчик сообщений не обрабатывал события от хука как и у меня.  Я мутил со структурой  msg. Получал координати курсора, а потом решил просматривать wParamы. Раньше это не прокатывало, но изменив код моей дЛЛ на ваш, все заработало.

Код в приложении:
Код

hile (GetMessage(&msg,(HWND)(NULL),0,0)) // Цикл обработки сообщений
    {
      LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
      TranslateMessage(&msg);

      x = msg.pt.x;
      y = msg.pt.y;

      // Вот тут теперь всё у меня срабатывает, а раньше такого не было
      if (msg.wParam == WM_LBUTTONDOWN)
        Form1->Memo1->Lines->Add("!!!!WM_LBUTTONDOWN!!!!");
      if (msg.wParam == WM_LBUTTONDBLCLK)
        Form1->Memo1->Lines->Add("!!!!WM_LBUTTONDBLCLK!!!!");

      DispatchMessage(&msg);
    }


Код в ДЛЛ:

Код

LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam) 
{ 
    if(nCode >= 0)
    {
        MOUSEHOOKSTRUCT *psMouseHook=(MOUSEHOOKSTRUCT*)(lParam); 
        HWND par_win = 0;
        if(psMouseHook) par_win = psMouseHook->hwnd;
        HWND main_wind = FindWindow(NULL, "Form1");

        switch(wParam)
        {
          case WM_LBUTTONDOWN:
            // так тоже работает ну, т.к par_win = psMouseHook->hwnd;

            //if(main_wind) PostMessage(main_wind, WM_USER+1, wParam, (LPARAM)par_win);
            PostMessage(main_wind, WM_USER+1, wParam, (LPARAM)psMouseHook->hwnd);
            break;
          case WM_LBUTTONDBLCLK:
            PostMessage(main_wind, WM_USER+1, wParam, (LPARAM)psMouseHook->hwnd);
            break;
        }    
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}


Спасибо и за такое решение проблемы. Но я бы хотел разобраться с разработчиком, вроде все логично, но что то там не так.

Вот исходник моей проги по глобальному перехвату координат курсора и кликов мыши.
Буду ждать ответов.





Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  My_hook_mouse.rar 19,42 Kb
PM MAIL   Вверх
586
Дата 3.10.2008, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Перехватывать оконные сообщения можно по-разному...
Код
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TButton *Button1;
    TMemo *Memo1;
    void __fastcall Button1Click(TObject *Sender);
private:    // User declarations

protected:
    virtual void __fastcall WndProc(Messages::TMessage &Message);

public:        // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


Присоединённый файл ( Кол-во скачиваний: 15 )
Присоединённый файл  hook_test.rar 19,55 Kb
PM   Вверх
J0ker
Дата 3.10.2008, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(kiLLProg @  1.10.2008,  14:45 Найти цитируемый пост)
Из-за большого числа комментариев проге, тебе должно было понятно, что пробовал я так и сяк.

интересный способ прогрммирования  smile 


--------------------
user posted image
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0577 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.