VC窗口屏幕边缘吸附

现在需要实现窗口屏幕边缘吸附的效果,现在只考虑屏幕右边缘。思路如下:

当窗口右侧与屏幕右侧距离小于某个值(假设是20px)的时候,改变窗口的水平位置,使窗口右边框紧贴屏幕右侧。

这个动作时通过WM_MOVING消息实现的,当窗口移动时,窗口会收到这个消息,我们可以在这个消息中通过参数修改窗口位置。

这样实现的话问题就出现了,拖动窗口到右侧可以看到吸附效果,可是向左拽不动窗口了恼怒

将屏幕最右侧20px像素矩形区域作为一个特殊区域(就叫做吸附区吧),只要窗口右侧落到这个区域内,就移动窗口至屏幕右边缘。如果想要拖动窗口离开边缘,需要下面两个状态值:

  • 窗口是否已经停靠在右侧
  • 鼠标是否是向左拖动窗口

很明显,如果上面两个状态均满足的话将窗口移出吸附区。

可以用一个bool值保存窗口是否停靠在右侧的状态。可是怎么判断鼠标是否是向左拖动窗口呢?

既然要拖动窗口,必然要用鼠标拖动窗口的标题栏(或者是非客户区),我们可以处理WM_NCMOUSEMOVE消息捕获到鼠标在非客户区移动时的坐标,并记录下来,然后再WM_MOVING中判断当前鼠标位置x坐标相对于刚才捕获位置的x坐标。这个就可以知道是否是向左拖拽窗口了。

(疑问:上面这个是借鉴的a note的源码逻辑。按照这个思路,窗口在吸附区时水平向右拖动窗口,窗口仍然可以收到WM_MOVING消息,那么是不是可以这样:通过在WM_MOVING处理函数里获取当前窗口位置,跟屏幕最右侧坐标相比,进而得到时候在用鼠标向右拖拽,这样的话更加简单了。)

这样程序基本上就实现了,代码如下:

 1 void CMovingTestDlg::OnNcMouseMove(UINT nHitTest, CPoint point)
 2 {
 3 //    m_dockedPnt = point;
 4     if(m_bDockedLeft || m_bDockedRight){
 5         m_dockedPnt.x = point.x;
 6     }
 7     if(m_bDockedTop || m_bDockedBottom){
 8         m_dockedPnt.y = point.y;
 9     }
10     CDialogEx::OnNcMouseMove(nHitTest, point);
11 }
 1 void CMovingTestDlg::OnMoving(UINT fwSide, LPRECT pRect)
 2 {
 3     CDialogEx::OnMoving(fwSide, pRect);
 4 
 5     const int DOCK_WIDTH = 50;
 6     CRect rectScreen;
 7     SystemParametersInfo(SPI_GETWORKAREA,0,&rectScreen,0);
 8     POINT curPnt;
 9     GetCursorPos(&curPnt);
10     if(m_bDockedRight ){
11         if(curPnt.x < m_dockedPnt.x - 3){
12             pRect->left = rectScreen.right - (pRect->right-pRect->left)- DOCK_WIDTH;
13             pRect->right = rectScreen.right - DOCK_WIDTH;
14             m_bDockedRight = false;
15         }
16         else{
17             pRect->left = rectScreen.right - (pRect->right-pRect->left);
18             pRect->right = rectScreen.right;
19         }
20     }
21     else if(!m_bDockedRight && pRect->right>rectScreen.right-DOCK_WIDTH){
22         pRect->left = rectScreen.right - (pRect->right-pRect->left);
23         pRect->right = rectScreen.right;
24         m_bDockedRight = true;
25         m_dockedPnt = curPnt;
26     }
27 }
原文地址:https://www.cnblogs.com/aishangxue/p/3413109.html