MFC 创建对话框,最大化取消边框【重绘最大化,最小化,关闭按钮下篇文章在去描述】

看到网易邮件,这一层做的真是漂亮

打开网易邮箱可以发现,网易邮箱的边框是没有的,貌似现在的采用自绘的客户终端大多都是没有边框和标题栏,同时非最大化的时候还可以实现自动拖拽功能,那么今天就想把制作客户端遇到的问题进行分析。

流程:

  1. 创建窗口
  2. 重载最大化最小换 GETMINMAXINFO
  3. 重载 NCCALCSIZE 重新绘制标题栏,解决出现边框的问题

问题:

:发现 WM_NCCALCSIZE 和 WM_GETMINMAXINFO两个消息连续使用,没有实现取消边框。

开始:

这里写图片描述
0,先创建一个对话框
看到在window8.1 操作系统中,清晰的可以发现有一圈黄色的边框,这个边框不是我们所想要的,但是我们应该如何去除这层边框,但是去除边框的同时,这个对话框同时具有拖拽放大客户区域的功能。

1,在InitDialog 中设置窗口样式

// 这一层设置窗口样式对于我们这个主题来说没有太大关联
::SetWindowLong(m_hWnd, GWL_STYLE, 
WS_CAPTION | WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPED |  WS_THICKFRAME | 0x00008000);
::SetWindowLong(m_hWnd, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_WINDOWEDGE);

// 设置窗口全屏 
ShowWindow(SW_MAXIMIZE);

2,重载最大化最小换 GETMINMAXINFO

void xxxDlg::OnGetMinMaxInfo(MINMAXINFO* pMMI)
{
    //最大化对话框
    int iWidth = GetSystemMetrics(SM_CXSCREEN);
    int iHeight = GetSystemMetrics(SM_CYSCREEN);

    CRect rt;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rt, 0);           // 获取客户区大小
    int y = ::GetSystemMetrics(SM_CYSCREEN) - rt.Height();      // 任务高度



    pMMI->ptMaxPosition.x = 0; // 设置窗口最大化时x坐标
    pMMI->ptMaxPosition.y = 0; // 设置窗口最大化时y坐标
    pMMI->ptMaxSize.x = iWidth ;
    pMMI->ptMaxSize.y = iHeight - y; // 防止挡住任务栏
}

// 1,这一层主要使用来设置最大化最小化时候窗口的高度,哎,说道最大化,最小化的按钮怎么不见了。这个下一节再去自绘定义,不想使用微软自带的。
// 2,边框问题需要解决
// 那么先看下效果

存在一层边框,并且最大化最小化按钮没有

那么我们是否可以在这里就罢了边框给干掉了,先把代码贴出来

        //最大化对话框
    int iWidth = GetSystemMetrics(SM_CXSCREEN);
    int iHeight = GetSystemMetrics(SM_CYSCREEN);

    CRect rt;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rt, 0);           // 获取客户区大小
    int y = ::GetSystemMetrics(SM_CYSCREEN) - rt.Height();      // 任务高度

    const int iBorderWidth = 10;

    pMMI->ptMaxPosition.x = 0 - iBorderWidth;// 设置窗口最大化时x坐标
    pMMI->ptMaxPosition.y = 0 - ::GetSystemMetrics(SM_CYCAPTION) - iBorderWidth;// 设置窗口最大化时y坐标
    pMMI->ptMaxSize.x = iWidth + iBorderWidth*2;// 设置窗口最大化时候的宽度
    pMMI->ptMaxSize.y = iHeight - y + ::GetSystemMetrics(SM_CYCAPTION) + iBorderWidth;// 设置窗口最大化时候的高度

– 不是存在标题吗,那我就从最上面在 + 一个标题的宽度开始绘画,这个客户去显示的就是正常的。横向的我也是这样认为的,但是这样就早造成两个问题,虽然右上角的问题能够解决,但是右下角就不能正常的解决。我认为是一块画布,网左上角拉扯,但是不能解决右下角的问题。这样的全屏不好。接下来我想去验证我这个想法。
我在这里只是把标题栏给干掉了,但是右下方的边框无法解决

右边的边框无论如何不能去除

验证:

    pMMI->ptMaxSize.x = 10; // 设置窗口最大化时候的宽度
    pMMI->ptMaxSize.y = iHeight - y + ::GetSystemMetrics(SM_CYCAPTION) + iBorderWidth;// 设置窗口最大化时候的高度
    // 我改变了宽度,但是边框还是出现了,所以这个逻辑被我否认了。

![FAILED](https://img-blog.csdn.net/20170222234518020?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXdlX090aXM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

3,所以接下来我就考虑使用专门为边框设计的【NCCALCSIZE】
代码先贴上了:

/// 响应最大化事件,这里不锁死x,y的初始点
void xxxDlg::OnGetMinMaxInfo(MINMAXINFO* pMMI)
{

    //最大化对话框
    int iWidth = GetSystemMetrics(SM_CXSCREEN);
    int iHeight = GetSystemMetrics(SM_CYSCREEN);

    CRect rt;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rt, 0);           // 获取客户区大小
    int y = ::GetSystemMetrics(SM_CYSCREEN) - rt.Height();      // 任务高度



    pMMI->ptMaxSize.y -= y  // 设置窗口最大化时的高度-下方任务栏的高度


    //pMMI->ptMaxPosition.x = 0; // 设置窗口最大化时x坐标
    //pMMI->ptMaxPosition.y = 0; // 设置窗口最大化时y坐标
}

// 响应重载 NCCALCSIZE 重新绘制标题栏,解决出现边框的问题


void xxxDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
    if (lpncsp != NULL && GetWindowLong(GetSafeHwnd(), GWL_STYLE)) // & WS_MAXIMIZE
    {
        CRect& rc = (CRect&)lpncsp->rgrc[0];//get the client rectangle   
        {
            rc.top += 0 - GetSystemMetrics(SM_CYCAPTION);
            rc.bottom += 0 + 10;
        }
    }
    CDialogEx::OnNcCalcSize(bCalcValidRects, lpncsp);
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页