实现无边框窗口移动和缩放,移动后缩放必然失灵

newmunga 2018-05-17 03:21:44
1、修改窗口样式SetWindowLong(myWindowHandle, GWL_STYLE, WS_POPUP);
2、在客户区自己创建了一个标题栏,标题栏的背景图ondrag事件里面执行以下代码实现窗口移动
 
ReleaseCapture();
SendMessage(myWindowHandle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
SendMessage(myWindowHandle, WM_LBUTTONUP, 0, 0);

3、自己写了一个dll,用SubWndProc方法拦截WndProc方法,WM_NCHITTEST事件里面执行一下代码

if (pt.x >= rcClient.right - 10 && pt.y >= rcClient.bottom - 10)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE)));
return HTBOTTOMRIGHT;
}
else if (pt.x <= rcClient.left + 10 && pt.y >= rcClient.bottom - 10)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW)));
return HTBOTTOMLEFT;
}
else if (pt.x <= rcClient.left + 10 && pt.y <= rcClient.top + 10)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE)));
return HTTOPLEFT;
}
else if (pt.x >= rcClient.right - 10 && pt.y <= rcClient.top + 10)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW)));
return HTTOPRIGHT;
}
else if (pt.x >= rcClient.right - 5)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
return HTRIGHT;
}
else if (pt.x <= rcClient.left + 5)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
return HTLEFT;
}
else if (pt.y <= rcClient.top + 5)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS)));
return HTTOP;
}
else if (pt.y >= rcClient.bottom - 5)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS)));
return HTBOTTOM;
}
else
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
return HTCLIENT;
}


现在遇到的问题是,只要先点击自制标题栏移动了窗口
1、缩放就不起作用了,缩放时鼠标样式变成缩放样式,但是,鼠标拖动后,整个窗口在移动,而不是缩放。
2、最小化以后,鼠标点击任务栏的的窗口,窗口粘在鼠标上跟随鼠标移动,必须点击一下左键后,才不跟随鼠标移动。
3、SendMessage(myWindowHandle, WM_NCLBUTTONDOWN, HTCAPTION, 0);这行报错:An abnormal situation has occurred: the PlayerLoop internal function has been called recursively. Please contact Customer Support with a sample project so that we can reproduce the problem and troubleshoot it.
...全文
1493 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
老夏 2018-09-11
  • 打赏
  • 举报
回复
SendMessage 这个函数本来就是设计为阻塞的,没有为什么,PostMessage 则设计为不阻塞的
lianghong 2018-09-09
  • 打赏
  • 举报
回复
//伪标题栏
private: System::Void panTitleBar_MouseDown(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {


//仅接受左键移动窗体
static Point MousePoint;
if (e->Button == System::Windows::Forms::MouseButtons::Left ) {
if (!(MousePoint.X== e->X) && !(MousePoint.Y == e->Y) ){
::ReleaseCapture();
::SendMessage((HWND)this->Handle.ToInt32(), WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
}

MousePoint = Point(e->X,e->Y );
}
newmunga 2018-06-23
  • 打赏
  • 举报
回复
关于进程阻塞这个问题,我现在放弃用SendMessage来实现窗口拖动,换成在drag事件里面根据鼠标坐标的变化重新计算窗口位置,然后使用MoveWindow来移动窗口的方法,问题解决了。不过后面看到帖子的朋友,希望能继续解答SendMessage造成进程停滞的原因及解决方法。
schlafenhamster 2018-06-06
  • 打赏
  • 举报
回复
在拖动一开始 (按键,拖动), 消息 会 阻塞,不过 一会儿 就恢复 了,"在拖动过程中收不到包",应该采用主程序 收到 后,给线程回答一个消息
newmunga 2018-06-06
  • 打赏
  • 举报
回复
@31 我是在C#里面调用 SendMessage(myWindowHandle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); 来实现的移动功能 你说的重绘 和 timer 我都没有设置过相关的属性,系统默认的,请问怎么能修改呢
newmunga 2018-06-06
  • 打赏
  • 举报
回复
22楼两个问题已经解决,以后遇到得朋友可以参考下: 1、没有用发送SC_MAXIMIZE得方法,我在最大化得时候取得当前工作区域范围,然后用movewindow方法实现最大化。同时用SystemParametersInfo方法记录下最大化之前的窗口信息,用于恢复按钮调用。 2、错误是由于我在 WM_SIZING里面不管哪条边判断达到最小值时都是设置RIGHT和BOTTOM造成的,现在根据不同的边来设置就没有这个问题了,比如:

                                        if (myMinW > 0)   //myMinW是窗口最小宽度
					{
						if (lpRect->right - lpRect->left < myMinW)
						{
							if (wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT)
								lpRect->right = lpRect->left + myMinW;
							else
								lpRect->left = lpRect->right - myMinW;
						}
					}
schlafenhamster 2018-06-06
  • 打赏
  • 举报
回复
可以改变 系统 设置,即 SPI_DRAGFULLWINDOW 属性, 你 选择 重绘 功能 是 用 什么 触发 的 Timer ?
newmunga 2018-06-06
  • 打赏
  • 举报
回复
只显示一个方框怎么实现呢?
schlafenhamster 2018-06-05
  • 打赏
  • 举报
回复
我说的就是 windows的标题栏拖动时 进程会被阻塞,不过 拖动时 只显示 一个 方框的话会 好的 多。
newmunga 2018-06-05
  • 打赏
  • 举报
回复
windows的标题栏拖动进程没有阻塞是怎么做到的呢,兄弟能有办法帮忙查一下么
schlafenhamster 2018-06-04
  • 打赏
  • 举报
回复
建议 取消 “拖动” 功能,由按钮 代替
schlafenhamster 2018-06-04
  • 打赏
  • 举报
回复
"在拖动过程中收不到包" 在拖动过程中程序 不响应其他 消息
schlafenhamster 2018-06-04
  • 打赏
  • 举报
回复
"我的动画这些全都停止了" 停一下 有 何妨 ? 拖动 时 程序是 柱塞 的 !
newmunga 2018-06-04
  • 打赏
  • 举报
回复
丢包,在拖动过程中收不到包
schlafenhamster 2018-06-04
  • 打赏
  • 举报
回复
还是要中断 ?? 什么意思,程序出错 ?
newmunga 2018-06-04
  • 打赏
  • 举报
回复
我是unity做得游戏,就算socket连接没问题,我的动画这些全都停止了,请问SC_MOVE + HTCAPTION这个过程中是否有什么设置是可以让进程正常运行的
newmunga 2018-06-04
  • 打赏
  • 举报
回复
现在还有两个问题 1、SendMessage(myWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);实现最大化后,拖动自制标题栏窗口就会还原到之前的状态,感觉是自动调用了Restore。 2、我限制了窗口最大最小尺寸,现在拖拉窗口边缘缩放窗口大小到最大或者最小值以后窗口开始移动,最终可以移动到屏幕边缘,然后就消失了,请问怎么能做到缩小到最小尺寸后,窗口不会移动
newmunga 2018-06-04
  • 打赏
  • 举报
回复
我socket放线程中了,还是要中断。
newmunga 2018-06-01
  • 打赏
  • 举报
回复
除了放线程还有么有其它方法呢
schlafenhamster 2018-06-01
  • 打赏
  • 举报
回复
socket 肯定要放 线程中,
加载更多回复(14)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧