如果响应CListView的NM_RCLICK, 是没有鼠标位置信息的.
用GetMessagePos可以得到最后一条消息发生时的鼠标位置信息。
用GetCursorPos是得到当前鼠标位置信息.
如果要显示的是右键菜单, 当消息响应较慢时(系统比较卡时),用GetMessagePos好些, 比GetCursorPos的位置精确.
void CListViewStu::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
CMenu menu;
CMenu* pSubMenu = NULL;
CPoint pt = ::GetMessagePos(); ///< 已经是屏幕坐标
/// 对于右键菜单操作, 还是用GetMessagePos好些
/// e.g. 当系统比较卡时, 右键了一下,鼠标又立刻拖动了好远时
// CPoint ptCursor;
// GetCursorPos(&ptCursor); ///< 和pt一样
menu.LoadMenu(MAKEINTRESOURCE(IDR_MENU_STU));
pSubMenu = menu.GetSubMenu(0);
pSubMenu->TrackPopupMenu(
TPM_LEFTALIGN |TPM_RIGHTBUTTON,
pt.x, pt.y, this);
*pResult = 0;
}
在msdn上GetCursorPos是和GetMessagePos一起说的, 看见msdn提供了一段用键盘移动光标的demo.
HCURSOR hCurs1, hCurs2; // cursor handles
POINT pt; // cursor location
RECT rc; // client area coordinates
static int repeat = 1; // repeat key counter
//
// Other declarations and initialization.
//
switch (message)
{
//
// Process other messages.
//
case WM_KEYDOWN:
if (wParam != VK_LEFT && wParam != VK_RIGHT &&
wParam != VK_UP && wParam != VK_DOWN)
{
break;
}
GetCursorPos(&pt);
// Convert screen coordinates to client coordinates.
ScreenToClient(hwnd, &pt);
switch (wParam)
{
// Move the cursor to reflect which
// arrow keys are pressed.
case VK_LEFT: // left arrow
pt.x -= repeat;
break;
case VK_RIGHT: // right arrow
pt.x += repeat;
break;
case VK_UP: // up arrow
pt.y -= repeat;
break;
case VK_DOWN: // down arrow
pt.y += repeat;
break;
default:
return NULL;
}
repeat++; // Increment repeat count.
// Keep the cursor in the client area.
GetClientRect(hwnd, &rc);
if (pt.x >= rc.right)
{
pt.x = rc.right - 1;
}
else
{
if (pt.x < rc.left)
{
pt.x = rc.left;
}
}
if (pt.y >= rc.bottom)
pt.y = rc.bottom - 1;
else
if (pt.y < rc.top)
pt.y = rc.top;
// Convert client coordinates to screen coordinates.
ClientToScreen(hwnd, &pt);
SetCursorPos(pt.x, pt.y);
break;
case WM_KEYUP:
repeat = 1; // Clear repeat count.
break;
}