• 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 }
  • 相关阅读:
    设计模式-总览
    restful
    springmvc异常统一处理(二)
    springmvc参数校验(二)
    跨语言的RPC
    更安全的RPC接口
    RPC版 “Hello World”
    用例(Use Case)
    参与者
    数据库知识基础入门
  • 原文地址:https://www.cnblogs.com/aishangxue/p/3413109.html
Copyright © 2020-2023  润新知