Доброе время суток. Хочу написать программку, передающую мне управление при клике мышки на определенном графическом элементе экрана. Написал хук, написал программку. Для уведомления программки хуком выбрал PostMessage. Сделал логирование. Начал проверять записи лога, обнаружил проблему при следующем сценарии действий : если кликнуть мышкой по окну, затем быстро переместить ее и снова кликнуть по тому же окну, образуется бесконечный цикл сообщений отправки и получения. Вот как выглядит, если кликать медленно или быстро, но не двигая мышкой Цитата | Message 50539 sended received 50539 message! |
Здесь первое сообщение пишется в хуке, второе в программе. Сколько кликнул — столько и пар сообщений (хотя если быстро кликать некоторые проглатываются, видимо, это уже происходит на уровне системы). Ну а при описанной выше ситуации лог такой же, но постоянно растет, пока не сделать alt-tab. Тогда он останавливается... Работаю с хуками второй раз, не могу представить в чем тут проблема. Есть догадка, что в описанном случае PostMessage из хука вызывается до обработки программой первого посланного PostMessage (из-за синхронной обработки перемещения мышки), однако, по моим представлениям, он просто мирно добавится в свою очередь и будет там вторым... лежать. Прошу помощи! Вот код хука
Код | //cpp #include "stdafx.h" #include "ptksmonmh.h" #include <atlstr.h> #include <fstream>
HINSTANCE hinst; HHOOK hh;
#pragma data_seg( ".SHARDATA" ) UINT msg = 0; HWND mainwnd = 0; #pragma data_seg()
BOOL APIENTRY DllMain( HINSTANCE h, DWORD, LPVOID ) { hinst = h; return TRUE; }
LRESULT CALLBACK MouseHook( int code, WPARAM wp, LPARAM lp ) { if ( code < 0 ) { return ::CallNextHookEx( hh, code, wp, lp ); }
if ( wp == WM_LBUTTONDOWN ) { ::PostMessage( mainwnd, msg, NULL, NULL ); CString tmp; tmp.Format( "Message %d sended\n", msg ); std::ofstream o( "c:\\log.txt", std::ios::app ); //::OutputDebugString( tmp ); o << tmp; o.flush(); } return ::CallNextHookEx( hh, code, wp, lp ); }
UINT RegisterMouseMessage( HWND mw ) { mainwnd = mw; return msg = ::RegisterWindowMessage( "ptksmonmsg" ); }
bool InstallMouseHook() { return ( hh = ::SetWindowsHookEx( WH_MOUSE, MouseHook, hinst, 0 ) ) != NULL; }
bool UnInstallMouseHook() { return UnhookWindowsHookEx( hh ) != 0; }
//h __declspec(dllexport) LRESULT CALLBACK MouseHook( int code, WPARAM wp, LPARAM lp ); //__declspec(dllexport) UINT RegisterMouseMessage(); __declspec(dllexport) bool InstallMouseHook(); __declspec(dllexport) UINT RegisterMouseMessage( HWND mw ); __declspec(dllexport) bool UnInstallMouseHook();
|
Вот программки
Код | int Ctestdllmfc2010Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialogEx::OnCreate(lpCreateStruct) == -1) return -1;
mh = ::LoadLibrary( _T( "ptksmonmh.dll" ) );
UINT (* rmm)(int); rmm = reinterpret_cast<UINT (*)(int)>( ::GetProcAddress( mh, _T( "RegisterMouseMessage" ) ) ); mm = rmm( reinterpret_cast<int>( m_hWnd ) ); CString tm; tm.Format( "mm is %d\n", mm ); //TRACE( tm );
bool (*imh)(); imh = reinterpret_cast<bool (*)()>( ::GetProcAddress( mh, _T( "InstallMouseHook" ) ) ); imh();
return 0; }
void Ctestdllmfc2010Dlg::OnDestroy() { CDialogEx::OnDestroy(); bool (* uimh)(); uimh = reinterpret_cast<bool (*)()>( ::GetProcAddress( mh, _T( "UnInstallMouseHook" ) ) ); uimh();
::FreeLibrary( mh ); }
BOOL Ctestdllmfc2010Dlg::PreTranslateMessage(MSG* pMsg) { if ( pMsg->message == mm ) { CString tmp; tmp.Format( "received %d message!\n", mm ); //TRACE( tmp ); std::ofstream o( "c:\\log.txt", std::ios::app ); o << tmp; //::MessageBeep( MB_ICONERROR ); }
return CDialogEx::PreTranslateMessage(pMsg); }
|
|