• Win32 API (2013/1/17)


    一.WM_MOUSEMOVE消息

    wParam
    Indicates whether various virtual keys are down. This parameter can be one or more of the following values.
    MK_CONTROL
    The CTRL key is down.
    MK_LBUTTON
    The left mouse button is down.
    MK_MBUTTON
    The middle mouse button is down.
    MK_RBUTTON
    The right mouse button is down.
    MK_SHIFT
    The SHIFT key is down.
    MK_XBUTTON1
    Windows 2000/XP: The first X button is down.
    MK_XBUTTON2
    Windows 2000/XP: The second X button is down.
    lParam
    The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

    The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

    二.Point的转换

    1

    可以用宏GET_X_LPARAM和GET_Y_LPARAM取低位和高位

    #define GET_X_LPARAM(lp)                        ((int)(short)LOWORD(lp))
    #define GET_Y_LPARAM(lp)                        ((int)(short)HIWORD(lp))
    

    取坐标方法

                int xPos = GET_X_LPARAM(lParam);    // horizontal position 
                int yPos = GET_Y_LPARAM(lParam);    // vertical position
    

    CPoint的封装

    ATLTYPES_INLINE CPoint::CPoint(_In_ LPARAM dwPoint) throw()
    {
        x = (short)GET_X_LPARAM(dwPoint);
        y = (short)GET_Y_LPARAM(dwPoint);
    }
    

    所以可以用CPoint的封装来表示坐标

    case WM_MOUSEMOVE:
        {
            CPoint pt(lParam);
            OnMouseMove((UINT)wParam, pt);
        }
        break;
    

    三.关于非客户端区域

    image

    Windows默认有非客户端区域,但有些客户端为了美观则去掉了默认非客户端区域的界面,绘制自己的界面.如何判断是否为非客户端区域完全由程序在WM_NCHITTEST消息中判断.

    如QQ客户端,以后部分需要拖拽

    image

    默认非客户端区域的标题部分则提供了这样的功能,若下部分可以拖拽,为了利用这个功能,则需要在WM_NCHITTEST根据区域来进行判断,windows会对于返回的非客户区域进行处理

    image

    代码示例:

    switch(message)
    {
    case WM_NCHITTEST:
        {
            bHandled=TRUE;
            return HTCAPTION;
        }
        break;
    }
    

    同理,其他的非客户区域也如此,如窗体边缘的拉缩,也可以根据区域来判断

    image

    代码示例:

    if(WM_NCHITTEST == uMsg)
    {
        CPoint point(lParam);
        DWORD nStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
    
        CRect rect;
        ::GetWindowRect(GetSafeHwnd(),&rect);
        if((nStyle & WS_MAXIMIZE))    {
                }
        else
        {
            int nMargin=2;
            if((point.x <= rect.left + 2 && point.y <= rect.top + 20) ||
                (point.x <= rect.left + 20 && point.y <= rect.top + 2) ||
                (point.x - rect.left + point.y - rect.top <= 10))
                return HTTOPLEFT;
            else if((point.x >= rect.right - 20 && point.y <= rect.top + 2) ||
                (point.x >= rect.right - 2 && point.y <= rect.top + 20) ||
                (rect.right - point.x + point.y - rect.top <= 10))
                return HTTOPRIGHT;
            else if((point.x <= rect.left + 2 && point.y >= rect.bottom - 20) ||
                (point.x <= rect.left + 20 && point.y >= rect.bottom - 2) ||
                (point.x - rect.left + rect.bottom - point.y <= 10))
                return HTBOTTOMLEFT;
            else if(point.x + point.y >=  rect.right + rect.bottom - 15)
                return HTBOTTOMRIGHT;
            else if(point.x <= rect.left + nMargin)
                return HTLEFT;
            else if(point.x >= rect.right - nMargin)
                return HTRIGHT;
            else if(point.y <= rect.top + nMargin)
                return HTTOP;
            else if(point.y >= rect.bottom - nMargin)
                return HTBOTTOM;
        }
    }
    

    四.WM_GETMINMAXINFO消息

    这个消息在每次WM_SIZE之前都会触发,告诉系统窗体的最大最小区域

    参考:http://blog.csdn.net/flowshell/article/details/4795581

    示例:

    LRESULT CMoloGUIWindow::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        MONITORINFO oMonitor = {};
        oMonitor.cbSize = sizeof(oMonitor);
        ::GetMonitorInfo(::MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
    
        CRect rcWork;
        if(oMonitor.dwFlags & MONITORINFOF_PRIMARY)
        {
            SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, NULL);
        }
        else
        {
            rcWork = oMonitor.rcMonitor;
        }
        LPMINMAXINFO lpMMI = (LPMINMAXINFO) lParam;
        lpMMI->ptMaxPosition.x    = rcWork.left;
        lpMMI->ptMaxPosition.y    = rcWork.top;
        lpMMI->ptMaxSize.x        = rcWork.right - rcWork.left;
        lpMMI->ptMaxSize.y        = rcWork.bottom - rcWork.top;
        lpMMI->ptMinTrackSize.x = m_minSize.cx;//min width
        lpMMI->ptMinTrackSize.y = m_minSize.cy;//min width
        return 0;
    }
    

    五.WM_NCCALCSIZE消息

    计算客户区域

    示例:以下位置变成了(0,0)坐标

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        RECT rect;
        GetClientRect(hWnd, &rect) ;
        rect.left=0;
        rect.top=0;
        DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
            DT_SINGLELINE) ;
    
        EndPaint(hWnd, &ps);
        break;
    

    image

    更改默认客户区域

    case WM_NCCALCSIZE:
        {
            BOOL bCalSize=(BOOL)wParam;
            NCCALCSIZE_PARAMS* pCalcParm=(NCCALCSIZE_PARAMS*)lParam;
            int myCaptionHeight = 130;  
            int myLeftBorderWeight =10;  
            int myRightBorderWeight =10;  
            int myBottomBorderWeight =10;  
    
            if (TRUE)  
            {  
                RECT& rc = (RECT&)pCalcParm->rgrc[0];//get the client rectangle  
    
                rc.top += myCaptionHeight - GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYDLGFRAME);  
                rc.left +=myLeftBorderWeight- GetSystemMetrics(SM_CYDLGFRAME);  
                rc.bottom -= myBottomBorderWeight - GetSystemMetrics(SM_CYDLGFRAME);  
                rc.right -= myRightBorderWeight - GetSystemMetrics(SM_CYDLGFRAME);  
    
            }  
    
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    

    这样会导致更改的原客户区域刷新机制失效,另外进行处理

    参考:http://blog.csdn.net/lgstudyvc/article/details/7367806

    http://blog.csdn.net/zdfcumt/article/details/5304221

    http://qiusuoge.com/8687.html

    image

  • 相关阅读:
    Docker & ASP.NET Core (3):发布镜像
    Docker & ASP.NET Core (2):定制Docker镜像
    Docker & ASP.NET Core (1):把代码连接到容器
    Redis五大数据类型的常用操作
    centos安装Redis
    SpringBoot进阶教程(五十一)Linux部署Quartz
    mybatis在xml文件中处理转义字符
    org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.lang.Integer
    SpringBoot进阶教程(五十)集成RabbitMQ---MQ实战演练
    浅谈RabbitMQ Management
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2864441.html
Copyright © 2020-2023  润新知