Отлов мышей (позиции курсора)
DLL и приложение работают, но координаты считываются только тогда, когда курсов находится над окном приложения, хотя дожно ловить по всему экрану. Никак не могу понять причину тако работы. Может кто-то сталкивался раньше с подобным?
PS Прошу не пинать за якобы "боян", облазил весь форум. Куча тем о постановках ловушек, но упоминаний о работе со структурой MOUSEHOOKSTRUCT так и не нашел.
Код DLL и приложения привожу ниже.
Код DLL:
#include <afxwin.h>
#define DLLEXPORT extern "C" __declspec(dllexport)
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
class CTestIdleUIDll : public CWinApp {
public:
CTestIdleUIDll() { }
~CTestIdleUIDll() { }
} theDll;
#pragma data_seg (".IdleUI")
HHOOK g_hHookMouse = NULL;
POINT ret;
#pragma data_seg ()
DLLEXPORT POINT IdleUIGetLastInputTime()
{
return ret;
}
LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code==HC_ACTION)
if(wParam == WM_MOUSEMOVE )
{
MOUSEHOOKSTRUCT *mst = (MOUSEHOOKSTRUCT*)lParam;
ret = mst->pt;
}
return ::CallNextHookEx(g_hHookMouse, code, wParam, lParam);
}
DLLEXPORT BOOL IdleUIInit()
{
if (g_hHookMouse == NULL) {
HINSTANCE hInst = theDll.m_hInstance;
g_hHookMouse = SetWindowsHookEx( WH_MOUSE, MouseProc, hInst, 0);
}
ASSERT(g_hHookMouse);
return TRUE;
}
DLLEXPORT void IdleUITerm()
{
BOOL bRet = UnhookWindowsHookEx(g_hHookMouse);
ASSERT(bRet);
}
Кусок приложения:
// .h файл
#define DLLIMPORT extern "C" __declspec(dllimport)
DLLIMPORT BOOL IdleUIInit();
DLLIMPORT void IdleUITerm();
DLLIMPORT POINT IdleUIGetLastInputTime();
//.cpp файл
...
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
SetTimer(1, 100, NULL);
return 0;
}
void CMainFrame::OnPaint()
{
CPaintDC dc(this);
CString s;
POINT ret = IdleUIGetLastInputTime();
s.Format("Mouse x_coord = %i an y_coord = %i",ret.x, ret.y );
CRect rc;
GetClientRect(&rc);
dc.DrawText(s, &rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
void CMainFrame::OnTimer(UINT nIDEvent)
{
Invalidate();
UpdateWindow();
}
...
Читаю тока на дельфе, но можно просто переодически определять координаты мыши, вместо того, чтобы ставить хук, хотя мыслишь верно.
Цитата: Sania
Читаю тока на дельфе, но можно просто переодически определять координаты мыши, вместо того, чтобы ставить хук, хотя мыслишь верно.
Ммм дело в том, что нужно получать экранные кординаты курсора не только тогда кодга курсор находится над окном приложения. а в любой точке экрана:)
http://www.codeproject.com/csharp/globalhook.asp . Работает блестяще, именно то, что нужно. Но увы в С# не силен и разобратся в исходнике сложновато.
Нашел неплохой пример С#
Цитата: Gole
Ммм дело в том, что нужно получать экранные кординаты курсора не только тогда кодга курсор находится над окном приложения. а в любой точке экрана:)
Ага :)
Help -> WinAPI -> GetCursorPos
Но тем не менее вопрос остается. Хотелось бы все таки понять в чем проблема такой работы хука.
В резальтате увидиш что в лог записаны события и те поторые над окном твоей проги и те которых нехватает.
Ето из за следуйщего: dll-ка с хуком(и всеми ее переменными) проецируеться в адресное пространство процесса(у каждого свое).
В результате при не активном окне твоей программы хук срабатывает для другого процесса в нем и изменякеться параметр ret.А в dll-ке загруженой в твой процесс он остаеться прежним.
З.С. если выразился не внятно - сори. Четкость выражения мысли хромает.
Возможно из-за того, что у тебя вывод по событию OnPaint. Оно вызываться будет только когда что-нть над формой - иначе зачем ее перерисовывать.