如何使用C++通过鼠标右键移动window?
How to move window by right mouse button using C++?
我需要通过鼠标右键移动 window。 window 没有标题栏。左键有效
void CMyHud::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SendMessage(WM_SYSCOMMAND, SC_MOVE|0x0002);
CDialogEx::OnLButtonDown(nFlags, point);
}
但是,如果我将这段代码放在 OnRButtonDown 上,它就不起作用。有什么问题?
好吧,解决方案找到了,感谢 Mark Ransom:
CRect pos;
void CMyHud::OnRButtonDown(UINT nFlags, CPoint point)
{
pos.left = point.x;
pos.top = point.y;
::SetCapture(m_hWnd);
CDialogEx::OnRButtonDown(nFlags, point);
}
void CMyHud::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pWnd = CWnd::FromHandle(m_hWnd);
CRect r;
if(GetCapture() == pWnd)
{
POINT pt;
GetCursorPos(&pt);
GetWindowRect(r);
pt.x -= pos.left;
pt.y -= pos.top;
MoveWindow(pt.x, pt.y, r.Width(), r.Height(),TRUE);
}
CDialogEx::OnMouseMove(nFlags, point);
}
void CMyHud::OnRButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
CDialogEx::OnRButtonUp(nFlags, point);
}
关于鼠标左键点击:
SC_MOVE|0x0002
结果为 0xF012
或 SC_DRAGMOVE
。这显然是一个未记录的常量。微软不想让任何人使用它可能有一个很好的理由,这就是他们隐藏它的原因。
另外WM_SYSCOMMAND
是一条通知消息。您应该回复它,而不是发送它。要用鼠标左键拖动 window:
message map ...
ON_WM_NCHITTEST()
LRESULT CMyDialog::OnNcHitTest(CPoint p)
{
//responding to a notification message
return HTCAPTION;
}
要用鼠标右键拖动 window,您必须覆盖 OnRButtonDown、OnMouseMove、OnRButtonUp 并创建您自己的例程。但是 Window 的行为变得非常混乱。这真的值得吗?
在您的 OnRButtonDown
函数中,执行 SetCapture
to ensure all mouse messages are routed to your window while the mouse button is down. Also store the mouse position in a member variable. Now, in your OnMouseMove
function, check to see if GetCapture
returns an object with the same HWND as yours - if it does, calculate the difference between the current mouse position and the saved one, then call MoveWindow
以移动 window。
可以使用鼠标消息实现。
WM_RBUTTONDOWN、WM_MOUSEMOVE
我需要通过鼠标右键移动 window。 window 没有标题栏。左键有效
void CMyHud::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SendMessage(WM_SYSCOMMAND, SC_MOVE|0x0002);
CDialogEx::OnLButtonDown(nFlags, point);
}
但是,如果我将这段代码放在 OnRButtonDown 上,它就不起作用。有什么问题?
好吧,解决方案找到了,感谢 Mark Ransom:
CRect pos;
void CMyHud::OnRButtonDown(UINT nFlags, CPoint point)
{
pos.left = point.x;
pos.top = point.y;
::SetCapture(m_hWnd);
CDialogEx::OnRButtonDown(nFlags, point);
}
void CMyHud::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pWnd = CWnd::FromHandle(m_hWnd);
CRect r;
if(GetCapture() == pWnd)
{
POINT pt;
GetCursorPos(&pt);
GetWindowRect(r);
pt.x -= pos.left;
pt.y -= pos.top;
MoveWindow(pt.x, pt.y, r.Width(), r.Height(),TRUE);
}
CDialogEx::OnMouseMove(nFlags, point);
}
void CMyHud::OnRButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
CDialogEx::OnRButtonUp(nFlags, point);
}
关于鼠标左键点击:
SC_MOVE|0x0002
结果为 0xF012
或 SC_DRAGMOVE
。这显然是一个未记录的常量。微软不想让任何人使用它可能有一个很好的理由,这就是他们隐藏它的原因。
另外WM_SYSCOMMAND
是一条通知消息。您应该回复它,而不是发送它。要用鼠标左键拖动 window:
message map ...
ON_WM_NCHITTEST()
LRESULT CMyDialog::OnNcHitTest(CPoint p)
{
//responding to a notification message
return HTCAPTION;
}
要用鼠标右键拖动 window,您必须覆盖 OnRButtonDown、OnMouseMove、OnRButtonUp 并创建您自己的例程。但是 Window 的行为变得非常混乱。这真的值得吗?
在您的 OnRButtonDown
函数中,执行 SetCapture
to ensure all mouse messages are routed to your window while the mouse button is down. Also store the mouse position in a member variable. Now, in your OnMouseMove
function, check to see if GetCapture
returns an object with the same HWND as yours - if it does, calculate the difference between the current mouse position and the saved one, then call MoveWindow
以移动 window。
可以使用鼠标消息实现。 WM_RBUTTONDOWN、WM_MOUSEMOVE