无边框对话框拖动改变大小的实现总结
实现 总结 大小 改变 对话框 拖动 边框
2023-09-11 14:21:00 时间
相同是项目遇到的问题,要求是无边框的对话框要实现鼠标的拖动改变大小。无边框对话框跟有边框的实现肯定不一样喽。
我上网搜到一种方法是:
须要处理下面这三个消息:
WM_NCHITTEST WM_SETCURSOR WM_NCLBUTTONDOWN
消息处理函数:
UINT CXXXDlg::OnNcHitTest(UINT nHitTest, CPoint point) { CRect rect; GetWindowRect(&rect); 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; return 0; } BOOL CXXXDlg::OnSetCursor(HWND hWnd, UINT nHitTest, UINT message) { if(nHitTest == HTCAPTION || nHitTest == HTSYSMENU || nHitTest == HTMENU || nHitTest == HTCLIENT) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); } else if(nHitTest == HTTOP || nHitTest == HTBOTTOM) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS))); } else if(nHitTest == HTLEFT || nHitTest == HTRIGHT) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE))); } else if(nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMRIGHT) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE))); } else if(nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMLEFT) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW))); } else { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); } } void CXXXDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) { 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)); }
上面的做法有点问题,像在推断时, 左右,上下先推断了。那左上,左下,右上,右下就没法做了。
全部就有了改进的方法:
UINT CTestDlg::OnNcHitTest( CPoint point ) { CPoint ptCur; CRect rect; GetCursorPos( &ptCur ); GetWindowRect( &rect ); if( CRect(rect.left, rect.top, rect.left+3, rect.top+3).PtInRect( ptCur ) ) return HTTOPLEFT; else if( CRect(rect.right-3, rect.top, rect.right, rect.top+3).PtInRect( ptCur ) ) return HTTOPRIGHT; else if( CRect(rect.left, rect.bottom-3, rect.left+3, rect.bottom).PtInRect( ptCur ) ) return HTBOTTOMLEFT; else if( CRect(rect.right-3, rect.bottom-3, rect.right, rect.bottom).PtInRect( ptCur ) ) return HTBOTTOMRIGHT; else if ( CRect(rect.left, rect.top, rect.left+3, rect.bottom).PtInRect( ptCur ) ) return HTLEFT; else if( CRect(rect.right-3, rect.top, rect.right, rect.bottom).PtInRect( ptCur ) ) return HTRIGHT; else if( CRect(rect.left, rect.top, rect.right-128, rect.top+3).PtInRect( ptCur ) ) // 128 Min,Max,Close return HTTOP; else if( CRect(rect.left, rect.bottom-3, rect.right, rect.bottom).PtInRect( ptCur ) ) return HTBOTTOM; return CDialog::OnNcHitTest(point); } BOOL CTestDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { CPoint ptCur; CRect rect; GetCursorPos( &ptCur ); GetWindowRect( &rect ); if ( rect.Width() >= m_nCxFullScreen-3 && rect.Height() >= m_nCyFullScreen-3 ) return CDialog::OnSetCursor(pWnd, nHitTest, message); if( CRect(rect.left, rect.top, rect.left+3, rect.top+3).PtInRect( ptCur ) || CRect(rect.right-3, rect.bottom-3, rect.right, rect.bottom).PtInRect( ptCur ) ) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE))); return 0; } else if( CRect(rect.left, rect.bottom-3, rect.left+3, rect.bottom).PtInRect( ptCur ) || CRect(rect.left, rect.bottom-3, rect.left+3, rect.bottom).PtInRect( ptCur ) ) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW))); return 0; } else if( CRect(rect.left, rect.top, rect.right-128, rect.top+3).PtInRect( ptCur ) || CRect(rect.left, rect.bottom-3, rect.right, rect.bottom).PtInRect( ptCur ) ) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS))); return 0; } else if( CRect(rect.left, rect.top, rect.left+3, rect.bottom).PtInRect( ptCur ) || CRect(rect.right-3, rect.top, rect.right, rect.bottom).PtInRect( ptCur ) ) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE))); return 0; } return CDialog::OnSetCursor(pWnd, nHitTest, message); } void CTestDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) { switch( nHitTest ) { case HTTOP: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y)); return; case HTBOTTOM: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, MAKELPARAM(point.x, point.y)); return; case HTLEFT: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, MAKELPARAM(point.x, point.y)); return; case HTRIGHT: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, MAKELPARAM(point.x, point.y)); return; case HTTOPLEFT: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, MAKELPARAM(point.x, point.y)); return; case HTTOPRIGHT: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, MAKELPARAM(point.x, point.y)); return; case HTBOTTOMLEFT: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, MAKELPARAM(point.x, point.y)); return; case HTBOTTOMRIGHT: SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, MAKELPARAM(point.x, point.y)); return; default: CDialog::OnNcLButtonDown( nHitTest, point ); }
相关文章
- 模仿SDWebImage实现异步加载图片
- Java实现 LeetCode 331 验证二叉树的前序序列化
- Java实现 LeetCode 73 矩阵置零
- Java实现哥德巴赫猜想
- java实现不连续处断开
- Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
- 【原创】基于 MySQL Connector/C 实现客户端程序之 API 总结
- Atitit QL查询语言总结 目录 1. QL = Query Language, 是查询语言的简称1 2. 模型2 2.1. 内嵌语言执行2 2.2. 语言互操作2 3. 具体实现2
- Atitit rest框架选型总结 Resteasy 实现 但是麻烦 作为JAX-RS的标准实现,RestEasy还具有以下亮点特性: 1)不需要配置文件,只要把JARs文件放到类路径里面
- Atitit webshell java 实现 命令行输出读取问题总结 1.1. 读取组赛 或者读取了一部分。。使用cmd /c 模式,强制关闭刷新缓冲区1 1.2. 乱码解决1 1.3. /h
- Atitit 数据存储的分组聚合 groupby的实现attilax总结
- atitit.loading的设计与实现控件选型attilax 总结
- Atitit.auto complete 自动完成控件的实现总结
- Atitit..文件上传组件选型and最佳实践总结(3)----断点续传控件的实现
- Atitit .html5刮刮卡的gui实现总结
- paip.索引的种类以及实现attilax 总结
- Futter基础第20篇: 实现轮播图 flutter_swiper
- Qt如何实现http服务
- Python实现ALO蚁狮优化算法优化支持向量机分类模型(SVC算法)项目实战
- ajax跨域post请求的java代理实现
- Jquery实现下拉列表左右选择
- PostgreSQL的学习心得和知识总结(一百二十)|语法级自上而下完美实现MySQL数据库的 update/delete limit 的实现方案
- PostgreSQL的学习心得和知识总结(一百零九)|深入理解PostgreSQL数据库 开源插件pg_walinspect 的使用场景和实现原理(未完成)
- PostgreSQL的学习心得和知识总结(九十九)|语法级自上而下完美实现达梦数据库的 TOP语法功能 的实现方案
- PostgreSQL的学习心得和知识总结(九十六)|深入理解PostgreSQL数据库开源MPP扩展Citus 分片表隐藏及显示 的实现原理
- PostgreSQL的学习心得和知识总结(九十四)|深入理解PostgreSQL数据库开源MPP扩展Citus DDL命令下发 的实现原理
- PostgreSQL的学习心得和知识总结(八十四)|深入理解PostgreSQL数据库开源MPP扩展Citus函数citus_add_node的使用场景和实现原理
- PostgreSQL的学习心得和知识总结(五十六)|语法级自上而下完美实现MySQL数据库的 show create table 的实现方案
- PostgreSQL的学习心得和知识总结(四十五)|关于PostgreSQL数据库开源作业调度扩展 pg_cron 默认GMT时区修改 的实现方案
- 5.4.1 使用堆算法实现优级队列
- reactos操作系统实现(98)
- reactos操作系统实现(92)
- WCF 学习总结5 -- 消息拦截实现用户名验证(转)
- Python-实现图表绘制总结
- Numpy实现Neuroevolution(神经网络进化)