如何获取鼠标当前屏幕位置?

时间:2021-03-25 10:19:46
想做一个简单的拾色器程序练练手,可是遇到问题了。
获取屏幕某个坐标的像素本不难,
类似
HDC hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
COLORREF clr = ::GetPixel(hDC, x, y);

这样就可以。
可是如何获取这x和y的值却难倒我了。。。
怎么样获取鼠标的当前屏幕位置?

我也尝试过用HOOK来做,
可是写了个简单的是有时候有效有时候无效,
我的HOOK段大致如下:
#pragma data_seg("my_data")
HHOOK hHook = NULL;
HWND hMainWnd = NULL;
HDC hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
CPoint pt;
COLORREF clr;
#pragma data_seg()
#pragma comment(linker, "/SECTION:my_data,RWS")



LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
        hMainWnd = FindWindow(NULL, "拾色器");
if(hMainWnd==NULL)
::MessageBox(NULL, "NULL", 0, 0);

MOUSEHOOKSTRUCT *mht = (MOUSEHOOKSTRUCT*)lParam;
clr = ::GetPixel(hDC, mht->pt.x, mht->pt.y);
int nRed = GetRValue(clr);
int nGreen = GetGValue(clr);
int nBlue = GetBValue(clr);
// char ch[20];
// sprintf(ch, "r=%d, g=%d, b=%d",nRed,nGreen,nBlue);
// TRACE0(ch);
// ::MessageBox(NULL, ch, 0, 0);
SetDlgItemInt(hMainWnd, IDC_RED, nRed, FALSE);
SetDlgItemInt(hMainWnd, IDC_GREEN, nGreen, FALSE);
SetDlgItemInt(hMainWnd, IDC_BLUE, nBlue, FALSE);

return CallNextHookEx(hHook,nCode,wParam,lParam);
}

HHOOK InstallMyHook()
{
hHook = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle(NULL), NULL);
return hHook;
}

void UninstallMyHook()
{
::ReleaseDC(NULL, hDC);
::UnhookWindowsHookEx(hHook);
}


不用HOOK能做吗?如果能,怎么做?
如果非得用HOOK,那么我的应该怎么改?为什么会有时候无效?

12 个解决方案

#1


看看这个是否能够满足你的要求:
http://msdn.microsoft.com/en-us/library/ms648390(VS.85).aspx

GetCursorPos Function
Retrieves the cursor's position, in screen coordinates.

Syntax
CopyBOOL WINAPI GetCursorPos(
  __out  LPPOINT lpPoint
);

Parameters
lpPoint [out] 
LPPOINT
A pointer to a POINT structure that receives the screen coordinates of the cursor.

Return Value
BOOL

Returns nonzero if successful or zero otherwise. To get extended error information, call GetLastError.

Remarks
The cursor position is always specified in screen coordinates and is not affected by the mapping mode of the window that contains the cursor.

The calling process must have WINSTA_READATTRIBUTES access to the window station.

The input desktop must be the current desktop when you call GetCursorPos. Call OpenInputDesktop to determine whether the current desktop is the input desktop. If it is not, call SetThreadDesktop with the HDESK returned by OpenInputDesktop to switch to that desktop.

Examples
For an example, see Using the Keyboard to Move the Cursor.

Requirements
Minimum supported client
 Windows 2000 Professional 
Minimum supported server
 Windows 2000 Server 
Header
 Winuser.h (include Windows.h) 
Library
 User32.lib 
DLL
 User32.dll 

#2


引用 1 楼 jixingzhong 的回复:
看看这个是否能够满足你的要求:
http://msdn.microsoft.com/en-us/library/ms648390(VS.85).aspx

GetCursorPos Function
Retrieves the cursor's position, in screen coordinates.

Syntax
CopyBOOL WINAPI GetCursorPos……


使用GetCursorPos函数本身是可以得到鼠标的屏幕位置的,
这个我知道,谢谢再提醒。
是我上面的问题没描述清楚吧。。。不好意思。
我需要知道的是如何在窗口外响应WM_MOUSEMOVE消息,
然后再在这个消息的响应里面写GetCursorPos应该就可以完成我的设想了。

#3


窗口外?. 那也可以这样吧 
创建主窗体 全屏  然后隐藏主窗体..
用主窗体截获WM_move消息 然后给你要的那个子窗体发送一个消息... 也许可以

#4


GetCursorPos

#5


引用 2 楼 mzlogin 的回复:
我需要知道的是如何在窗口外响应WM_MOUSEMOVE消息

SetCapture?

#6


GetCursorPos(&pt);   //获得相对与屏幕左上角得位置 

#7


GetCursorPos

#8


参考一下

#include <iostream.h> 
#include <windows.h>

int main() 
{
POINT p;
while(true)
{
if(GetCursorPos(&p)) 
{
cout<<p.x<<","<<p.y<<endl;
Sleep(500);
system("cls");
}
}

#9


1楼喜欢玩大牌

#10


引用 5 楼 xianglitian 的回复:
引用 2 楼 mzlogin 的回复:
我需要知道的是如何在窗口外响应WM_MOUSEMOVE消息
SetCapture?


我也试过这个。。。
可是如果我创建一个对话框程序,
然后在OnInitDialog里写SetCapture,
在运行后,鼠标指针呈忙状态,
在窗口内可以正常拾色,包括标题栏,
但出了窗口仍是对MouseMove无反应。。。

#11


期待能解决问题的解答。

#12


GetCursorPos

#1


看看这个是否能够满足你的要求:
http://msdn.microsoft.com/en-us/library/ms648390(VS.85).aspx

GetCursorPos Function
Retrieves the cursor's position, in screen coordinates.

Syntax
CopyBOOL WINAPI GetCursorPos(
  __out  LPPOINT lpPoint
);

Parameters
lpPoint [out] 
LPPOINT
A pointer to a POINT structure that receives the screen coordinates of the cursor.

Return Value
BOOL

Returns nonzero if successful or zero otherwise. To get extended error information, call GetLastError.

Remarks
The cursor position is always specified in screen coordinates and is not affected by the mapping mode of the window that contains the cursor.

The calling process must have WINSTA_READATTRIBUTES access to the window station.

The input desktop must be the current desktop when you call GetCursorPos. Call OpenInputDesktop to determine whether the current desktop is the input desktop. If it is not, call SetThreadDesktop with the HDESK returned by OpenInputDesktop to switch to that desktop.

Examples
For an example, see Using the Keyboard to Move the Cursor.

Requirements
Minimum supported client
 Windows 2000 Professional 
Minimum supported server
 Windows 2000 Server 
Header
 Winuser.h (include Windows.h) 
Library
 User32.lib 
DLL
 User32.dll 

#2


引用 1 楼 jixingzhong 的回复:
看看这个是否能够满足你的要求:
http://msdn.microsoft.com/en-us/library/ms648390(VS.85).aspx

GetCursorPos Function
Retrieves the cursor's position, in screen coordinates.

Syntax
CopyBOOL WINAPI GetCursorPos……


使用GetCursorPos函数本身是可以得到鼠标的屏幕位置的,
这个我知道,谢谢再提醒。
是我上面的问题没描述清楚吧。。。不好意思。
我需要知道的是如何在窗口外响应WM_MOUSEMOVE消息,
然后再在这个消息的响应里面写GetCursorPos应该就可以完成我的设想了。

#3


窗口外?. 那也可以这样吧 
创建主窗体 全屏  然后隐藏主窗体..
用主窗体截获WM_move消息 然后给你要的那个子窗体发送一个消息... 也许可以

#4


GetCursorPos

#5


引用 2 楼 mzlogin 的回复:
我需要知道的是如何在窗口外响应WM_MOUSEMOVE消息

SetCapture?

#6


GetCursorPos(&pt);   //获得相对与屏幕左上角得位置 

#7


GetCursorPos

#8


参考一下

#include <iostream.h> 
#include <windows.h>

int main() 
{
POINT p;
while(true)
{
if(GetCursorPos(&p)) 
{
cout<<p.x<<","<<p.y<<endl;
Sleep(500);
system("cls");
}
}

#9


1楼喜欢玩大牌

#10


引用 5 楼 xianglitian 的回复:
引用 2 楼 mzlogin 的回复:
我需要知道的是如何在窗口外响应WM_MOUSEMOVE消息
SetCapture?


我也试过这个。。。
可是如果我创建一个对话框程序,
然后在OnInitDialog里写SetCapture,
在运行后,鼠标指针呈忙状态,
在窗口内可以正常拾色,包括标题栏,
但出了窗口仍是对MouseMove无反应。。。

#11


期待能解决问题的解答。

#12


GetCursorPos