首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MFC Windows 程序设计->实现客户区拖动

MFC Windows 程序设计->实现客户区拖动

作者头像
井九
发布2024-10-12 08:43:00
发布2024-10-12 08:43:00
1080
举报
文章被收录于专栏:四楼没电梯四楼没电梯

One problem with a window without a title bar is that it can't be repositioned with the mouse. Windows are dragged by their title bars, and when there's no title bar, the user has nothing to grab onto. Clock solves this little dilemma by playing a trick with the window's WM_NCHITTEST handler so that the window can be dragged by its client area, a feature Windows programmers call client-area drag.

In Windows, every mouse message is preceded by a WM_NCHITTEST message containing screen coordinates identifying the cursor location. The message is normally handled by ::DefWindowProc, which returns a code that tells Windows what part of the window the cursor is over. Windows uses the return value to decide what type of mouse message to send. For example, if the left mouse button is clicked over the window's title bar, ::DefWindowProc's WM_NCHITTEST handler returns HTCAPTION and Windows sends the window a WM_NCLBUTTONDOWN message. If ::DefWindowProc returns HTCLIENT instead, Windows converts the cursor coordinates from screen coordinates to client coordinates and passes them to the window in a WM_LBUTTONDOWN message.

The fact that an application sees mouse messages in raw form makes for some interesting possibilities. The following OnNcHitTest handler implements client-area drag by fooling Windows into thinking that the mouse is over the title bar when in fact it's over the window's client area:

UINT CMainWindow::OnNcHitTest (CPoint point) { UINT nHitTest = CFrameWnd::OnNcHitTest (point); if (nHitTest == HTCLIENT) nHitTest = HTCAPTION; return nHitTest; }

With this OnNcHitTest handler in place, a window is as easily dragged by its client area as by its title bar. And it works even if the window doesn't have a title bar. Try it: click the left mouse button in Clock's client area, and move the mouse with the button held down. The window should go wherever the mouse goes.

Clock uses an OnNcHitTest handler similar to the one shown above. The only difference is that Clock verifies that the left mouse button is down before replacing an HTCLIENT return code with HTCAPTION so that other mouse messages—particularly right-button mouse messages that precede WM_CONTEXTMENU messages—will get through unscathed:

UINT CMainWindow::OnNcHitTest (CPoint point) { UINT nHitTest = CFrameWnd::OnNcHitTest (point); if ((nHitTest == HTCLIENT) && (::GetAsyncKeyState (MK_LBUTTON) < 0)) nHitTest = HTCAPTION; return nHitTest; }

The call to ::GetAsyncKeyState checks the left mouse button and returns a negative value if the button is currently down.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档