前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用 WM_NCHITTEST 消息自定义窗口可拖动区域

利用 WM_NCHITTEST 消息自定义窗口可拖动区域

作者头像
我与梦想有个约会
发布2020-01-06 18:12:32
1.9K0
发布2020-01-06 18:12:32
举报
文章被收录于专栏:jiajia_dengjiajia_dengjiajia_deng

最近接到一个比较个性化的需求,原来团队基于 Electron 开发的项目由于不支持 XP 系统,想完全移植到基于 CEF 2623 版本的空壳中,以此来兼容 XP 系统。而程序的界面则完全交由前端来处理了,比如标题栏、最小化、最大化等功能按钮。这其中就涉及到一些原生应用的功能比如拖动窗口的功能是需要原生窗口提供的,微软提供拖动窗口的机制如此文章所描述:https://www.cnblogs.com/GnagWang/archive/2010/09/12/1824394.html。为了保证内容不丢失,我特意截图保留一份。

从上面的资料中可以看到,只要我们将某些固定区域在响应 WM_NCHITTEST 消息的处理函数中返回 HTCAPTION,那么微软就会帮我们实现拖动的效果。除了这些,需求中还有更变态的想法,那就是窗口左侧 300 像素要求可拖动高度是 20 像素,右侧可拖动高度是 50 像素,这也能实现吗?当然,其实你只需要根据左侧和右侧两个分割点,生成两个矩形区域,再响应 WM_NCHITTEST 消息时只要鼠标在这两个矩形范围内,那么就返回 HTCAPTION,思路有了,如何实现呢?看代码:

LRESULT ChildForm::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    if (persent_ > 0)
    {
        POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
        ::ScreenToClient(GetHWND(), &pt);

        UiRect rcClient;
        ::GetClientRect(GetHWND(), &rcClient);

        rcClient.Deflate(m_shadow.GetShadowCorner());

        // 左侧可拖动区域位置
        UiRect left_rect;
        left_rect.left = rcClient.left;
        left_rect.top = rcClient.top;
        left_rect.right = rcClient.GetWidth() * persent_;
        left_rect.bottom = rcClient.top + left_title_height_;

        // 右侧可拖动矩形位置
        UiRect right_rect;
        right_rect.left = rcClient.left + rcClient.GetWidth() * persent_;
        right_rect.right = rcClient.right;
        right_rect.top = rcClient.top;
        right_rect.bottom = rcClient.top + right_title_height_;

        DpiManager::GetInstance()->ScaleRect(left_rect);
        DpiManager::GetInstance()->ScaleRect(right_rect);

        if (left_rect.IsPointIn(pt) || right_rect.IsPointIn(pt))
        {
            return HTCAPTION;
        }
    }

    return __super::OnNcHitTest(uMsg, wParam, lParam, bHandled);
}

代码中重写了父类的 OnNcHitTest 方法(处理 WM_NCHITTEST 消息),根据窗口切分的百分比 persent 值分割窗口左右两侧,生成左侧和右侧两个矩形的 rect。并调用了 IsPointIn 方法(实际是 Win32 API ::PtInRect)判断当前鼠标所在的坐标是不是在两个矩形范围内,如果是则返回该区域是 HTCAPTION,以此让 Windows 帮我们处理拖动请求。另外大家也可以看到,如果系统开启了缩放功能,比如设置自动放大 125%,那么我们是需要根据缩放比例来调整坐标体系的,这点就不在此文章中做多介绍。以上方法即可实现控制不同区域让窗口可以拖动的效果,如果有其他需求欢迎大家讨论。

相关

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年1月9日,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

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