MFC 无边框窗体实现用鼠标拖动窗体边缘实现窗体大小变化

无边框窗体如何实现用鼠标拖动窗体边缘实现窗体大小变动呢?下面介绍一种方法,通过以下几个步骤即可实现:

1.实现WM_NCHITTEST消息,实现四条边框的模拟

2.实现WM_NCLBUTTONDOWN,发送窗体拖曳变化的消息

具体阐述如下:

1.实现WM_NCHITTEST消息,实现四条边框的模拟

参考代码如下:

LRESULT CUserForm::OnNcHitTest(CPoint point)

{

    // TODO: 在此添加消息处理程序代码和/或调用默认值    

    CRect rect;

    GetWindowRect(&rect);

    CRect rect1 = rect;

    rect1.DeflateRect(10, 10, -10, -10);//缩小矩形

    rect1.NormalizeRect();//规范化矩形确保非0或负

    if (point.x <= rect.left+3)

        return HTLEFT;

    else if (point.x >= rect.right-3)

        return HTRIGHT;

    else if (point.y <= rect.top+3)

        return HTTOP;

    else if (point.y >= rect.bottom-3)

        return HTBOTTOM;

    else if (point.x <= rect.left+10 && point.y <= rect.top+10)

        return HTTOPLEFT;

    else if (point.x >= rect.right-10 && point.y <= rect.top+10)

        return HTTOPRIGHT;

    else if (point.x <= rect.left+10 && point.y >= rect.bottom-10)

        return HTBOTTOMLEFT;

    else if (point.x >= rect.right-10 && point.y >= rect.bottom-10)

        return HTBOTTOMRIGHT;

    else if (!rect.IsRectEmpty())

    {

        LRESULT uRet = CWnd::OnNcHitTest(point);

        uRet = (uRet == HTCLIENT) ? HTCAPTION : uRet;//客户区转换成非客户区

        return uRet;

    }

    else

    {

        return CWnd::OnNcHitTest(point);

    }

    return 0;

}

2.实现WM_NCLBUTTONDOWN,发送窗体拖曳变化的消息

void CUserForm::OnNcLButtonDown(UINT nHitTest, CPoint point)

{

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    if (nHitTest == HTTOP)

    {        

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y));

    }

    else if (nHitTest == HTBOTTOM)

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, MAKELPARAM(point.x, point.y));

    else if (nHitTest == HTLEFT)

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, MAKELPARAM(point.x, point.y));

    else if (nHitTest == HTRIGHT)

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, MAKELPARAM(point.x, point.y));

    else if (nHitTest == HTTOPLEFT)

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, MAKELPARAM(point.x, point.y));

    else if (nHitTest == HTTOPRIGHT)

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, MAKELPARAM(point.x, point.y));

    else if (nHitTest == HTBOTTOMLEFT)

        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, MAKELPARAM(point.x, point.y));

    else if (nHitTest == HTBOTTOMRIGHT)

        SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, MAKELPARAM(point.x, point.y));

    else if (nHitTest==HTCAPTION)

        SendMessage(WM_SYSCOMMAND, SC_MOVE | 4, MAKELPARAM(point.x, point.y));

}

通常,使用上述的代码即可实现要求。

我们进行一下扩展。在窗体大小发生变化时,有两种表现形式:一种是出现虚线框,一种没有。这个选择依赖于操作系统,你可以右击桌面/属性/外观/效果中通过选择或取消“拖动时显示窗口内容”来表现这两种形式。那么如何在程序中实现而不依赖于当前机器的设置呢

if(nHitTest == HTTOP)

{        

    SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);

    SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y));

    SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, 0);

}

 

WM_SYSCOMMAND
 
当用户从 窗口菜单选择一个命令或当用户选择最大化按钮,最小化按钮,复原按钮或关闭按钮时,一个窗口将会接收该消息
Syntax
WM_SYSCOMMAND
WPARAM wParam
LPARAM lParam;
 
参数
wParam
指定系统命令的类型。该参数可以是下列值之一:
SC_CLOSE
关闭窗口
SC_CONTEXTHELP
将光标改为一个问题标识样式。如果用户之后点击了对话框中的一个控件,该控件会收到一个WM_HELP消息。
SC_DEFAULT
当用户双击 窗口菜单时,选择默认的条目。
SC_HOTKEY
以应用程序指定的热键激活窗口。lParam参数标识了所要激活的窗口。
SC_HSCROLL
水平滚动。
SC_KEYMENU
键盘的敲击返回 窗口菜单
SC_MAXIMIZE
最大化窗口
SC_MINIMIZE
最小化窗口
SC_MONITORPOWER
设置显示状态。该命令支持具有节电特性的设备,如电池供电的个人电脑。
lParam参数可以具有下列值:
-1 - 显示设备打开
1 - 显示设备将要进入节电模式。
2 - 显示设备将要被关闭
SC_MOUSEMENU
鼠标单击返回 窗口菜单
SC_MOVE
移动窗口
SC_NEXTWINDOW
移到下一个窗口
SC_PREVWINDOW
移到前一个窗口
SC_RESTORE
将窗口复原到原始的位置和大小。
SC_SCREENSAVE
执行System.ini文件里[boot]部分指定的屏幕保护程序。
SC_SIZE
改变窗口大小。
SC_TASKLIST
激活【开始】菜单。
SC_VSCROLL
垂直滚动。
lParam
如果一个窗口命令被鼠标选中,低位字指定光标的水平位置。否则该参数不被使用。
如果一个窗口命令被鼠标选中,高位字指定光标的垂直位置。如果使用 系统加速键选择的命令,则该参数为-1,如果使用 助记符的话,则该参数为0.
返回值
如果成功处理该消息,则返回值为0.
备注
获得屏幕坐标系下的位置坐标,可以使用下面的代码:
xPos = GET_X_LPARAM(lParam); // horizontal position
yPos = GET_Y_LPARAM(lParam); // vertical position

 

参考文章:http://blog.csdn.net/zjtchow/article/details/6122320

参考文章:http://baike.baidu.com/link?url=mwSXzuAO5-zjQ7Oyhgr8WfVNGsEkIdLCNJtdlHxd32JXRj_JydBjcIEq3vy-kUw3mZ8aa9c6W6ESwk-xmgX0t_

你可能感兴趣的:(mfc)