窗口虚拟改变大小 我的对话框上有很多控件,响应OnSize时间窗口闪烁的利害。我想在点中窗口边框拖动,产生虚框,释放鼠标左键后再重画控件,怎么实现?各位大哥帮帮忙! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在拖动的时候让不想显示的空间不show出来,或者就是不改变位置 //点击窗口右下角,拖动一个框void DrawRect(CDC *pDC,const CRect& r){ int w = r.Width(); int h = r.Height(); pDC->PatBlt(r.left,r.top,w,3,PATINVERT); pDC->PatBlt(r.left,r.top + h - 3,w,3,PATINVERT); pDC->PatBlt(r.left,r.top + 3,3,h - 3 - 3,PATINVERT); pDC->PatBlt(r.left + w - 3,r.top + 3,3,h - 3 - 3,PATINVERT);}void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point){ if(nHitTest == HTBOTTOMRIGHT) { SetCapture(); CRect r,tmpr; GetWindowRect(&r); tmpr = r; CPoint oldpt(point),tmppt; CPoint tmp; HDC hdc = ::GetDC(NULL); CDC dc; dc.Attach(hdc); int w,h; while (CWnd::GetCapture() == this) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); break; } switch (msg.message) { case WM_LBUTTONUP: ReleaseCapture(); break; case WM_MOUSEMOVE: DrawRect(&dc,tmpr); tmppt = msg.pt; tmp = oldpt - tmppt; tmpr = r; tmpr.right = r.right - tmp.x; tmpr.bottom = r.bottom - tmp.y; DrawRect(&dc,tmpr); break; default: DispatchMessage(&msg); break; } } dc.Detach(); MoveWindow(&tmpr); return; } CDialog::OnNcLButtonDown(nHitTest, point);} TO:xing_xing_xing(ζ未名ζ) 窗口不闪了,但最大化窗口后我拖动边框让窗口缩小,然后再点最大化没反应,窗口还保持原大小,是不是系统那边还以为窗口处于最大化?怎么在拖动后通知系统窗口一定不是最大化了?另外,我设定了最小窗口,拖动到最小窗口后会产生残留痕迹,怎么清除? TO:xing_xing_xing(ζ未名ζ) 窗口不闪了,但最大化窗口后我拖动边框让窗口缩小,然后再点最大化没反应,窗口还保持原大小,是不是系统那边还以为窗口处于最大化?怎么在拖动后通知系统窗口已经不是最大化了?另外,我设定了最小窗口,拖动到最小窗口后会产生残留痕迹,怎么清除? 应该是窗口已经最大化了,应该限制拖动窗口的最大大小改了一下绘制方式添加一个类变量MINMAXINFO mminfo;void CMyDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI){ mminfo = *lpMMI; //这里赋值 CDialog::OnGetMinMaxInfo(lpMMI);}void CDlg2Dlg::OnNcLButtonDown(UINT nHitTest, CPoint point){ if(nHitTest == HTBOTTOMRIGHT) { SetCapture(); CRect r,tmpr; GetWindowRect(&r); tmpr = r; CPoint oldpt(point),tmppt; CPoint tmp; HDC hdc = ::GetDC(NULL); CDC dc; dc.Attach(hdc); dc.SelectObject(CDC::GetHalftoneBrush()); //Halftone画刷 while (CWnd::GetCapture() == this) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); break; } switch (msg.message) { case WM_LBUTTONUP: ReleaseCapture(); break; case WM_MOUSEMOVE: if(r != tmpr) //去除不刷新现象 DrawRect(&dc,tmpr); tmppt = msg.pt; tmp = oldpt - tmppt; tmpr = r; tmpr.right = r.right - tmp.x; tmpr.bottom = r.bottom - tmp.y;//限制可以拖动的窗口大小 if(tmpr.Width() > mminfo.ptMaxTrackSize.x) tmpr.right = tmpr.left + mminfo.ptMaxTrackSize.x; if(tmpr.Height() > mminfo.ptMaxTrackSize.y) tmpr.bottom = tmpr.top + mminfo.ptMaxTrackSize.y; if(tmpr.Width() < mminfo.ptMinTrackSize.x) tmpr.right = tmpr.left + mminfo.ptMinTrackSize.x; if(tmpr.Height() < mminfo.ptMinTrackSize.y) tmpr.bottom = tmpr.top + mminfo.ptMinTrackSize.y; DrawRect(&dc,tmpr); break; default: DispatchMessage(&msg); break; } } dc.Detach(); MoveWindow(&tmpr); return; } CDialog::OnNcLButtonDown(nHitTest, point);}其他的7个方向应该类似可以添加上去 谢谢还是会有残留:因为我的窗口上有很错空间,我的窗口风格用了WS_CLIPCHILDREN |WS_CLIPSIBLINGS 风格,所以产生了残留痕迹。怎么解决?还有 我用了ShowWindow(SW_SHOWMAXIMIZED);最大化窗口,然后拖动改变窗口大小,再ShowWindow(SW_SHOWMAXIMIZED)时候没有放映,是不是因为系统还以为出于最大化?怎么解决? 谢谢还是会有残留:因为我的窗口上有很多控件,窗口用了WS_CLIPCHILDREN |WS_CLIPSIBLINGS 风格,所以产生了残留痕迹。怎么解决?还有 我用了ShowWindow(SW_SHOWMAXIMIZED);最大化窗口,然后拖动改变窗口大小,再ShowWindow(SW_SHOWMAXIMIZED)时候没有放映,是不是因为系统还以为出于最大化?怎么解决? 是没有反应,处于最大化的时候不能拖动你可能不是在WM_NCLBUTTONDOWN消息里响应的,检查是否最大化?如果是不要拖动,或者自己计算最大窗口直接Move过去退出while循环后 DrawRect(&dc,tmpr); //在画一次擦除 dc.Detach(); if(GetStyle() & WS_MAXIMIZE) //修改窗口风格 取消最大化状态 ModifyStyle(WS_MAXIMIZE,0); MoveWindow(tmpr.left,tmpr.top,rand() % 500,rand() % 500); 所有问题都解决了,我总结一下,结帖子void CClientDlg::OnNcLButtonDown(UINT nHitTest, CPoint point){ // TODO: 在此添加消息处理程序代码和/或调用默认值 if(nHitTest == HTBOTTOMRIGHT || nHitTest == HTBOTTOM || nHitTest == HTBOTTOMLEFT || nHitTest == HTLEFT || nHitTest == HTRIGHT || nHitTest == HTTOP || nHitTest == HTTOPRIGHT || nHitTest == HTTOPLEFT) { SetCapture(); CRect r,tmpr; GetWindowRect(&r); tmpr = r; CPoint oldpt(point),tmppt; CPoint tmp; HDC hdc = ::GetDC(NULL); CDC dc; dc.Attach(hdc); while (CWnd::GetCapture() == this) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); break; } switch (msg.message) { case WM_LBUTTONUP: ReleaseCapture(); break; case WM_MOUSEMOVE: if ( tmpr.Width() < 640 || tmpr.Height() < 480 ) break; if ( r != tmpr ) DrawRect(&dc,tmpr); tmppt = msg.pt; tmp = oldpt - tmppt; tmpr = r; switch( nHitTest) { case HTBOTTOM: tmpr.bottom = r.bottom - tmp.y; break; case HTBOTTOMLEFT: tmpr.left = r.left - tmp.x; tmpr.bottom = r.bottom - tmp.y; break; case HTBOTTOMRIGHT: tmpr.right = r.right - tmp.x; tmpr.bottom = r.bottom - tmp.y; break; case HTLEFT: tmpr.left = r.left - tmp.x; break; case HTRIGHT: tmpr.right = r.right - tmp.x; break; case HTTOP: tmpr.top = r.top - tmp.y; break; case HTTOPRIGHT: tmpr.top = r.top - tmp.y; tmpr.right = r.right - tmp.x; break; case HTTOPLEFT: tmpr.top = r.top - tmp.y; tmpr.left = r.left - tmp.x; break; } DrawRect(&dc,tmpr); break; default: DispatchMessage(&msg); break; } } DrawRect(&dc,tmpr); //在画一次擦除 dc.Detach(); if(GetStyle() & WS_MAXIMIZE) //修改窗口风格 取消最大化状态 ModifyStyle(WS_MAXIMIZE,0); MoveWindow(&tmpr); return; } GSDialog::OnNcLButtonDown(nHitTest, point);} 谢谢诸位,特别是 xing_xing_xing 如何利用dll进行进程间通信? sprintf设置变量路径的问题 窗口层叠问题? 非模态对话框中重载OnPaint的问题 简单的菜单问题! 又是一个菜鸟问题.... 各位大虾,请问如何只通过 HWND 禁止此窗口关闭?自己试着用子类化和钩子都未实现。急! 高手请指教:怎样在纯Windows编程中给ComboBox添假选项??——急——在线等 请问怎样对COM库中的事件进行处理?如_IDownloadEvent中OnUpdate事件。 DAO数据库的连接 ATL开发指南,很多人想要的!!! 程序启动后的执行顺序
void DrawRect(CDC *pDC,const CRect& r)
{
int w = r.Width();
int h = r.Height();
pDC->PatBlt(r.left,r.top,w,3,PATINVERT);
pDC->PatBlt(r.left,r.top + h - 3,w,3,PATINVERT);
pDC->PatBlt(r.left,r.top + 3,3,h - 3 - 3,PATINVERT);
pDC->PatBlt(r.left + w - 3,r.top + 3,3,h - 3 - 3,PATINVERT);
}void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if(nHitTest == HTBOTTOMRIGHT)
{
SetCapture();
CRect r,tmpr;
GetWindowRect(&r);
tmpr = r;
CPoint oldpt(point),tmppt;
CPoint tmp;
HDC hdc = ::GetDC(NULL);
CDC dc;
dc.Attach(hdc);
int w,h; while (CWnd::GetCapture() == this)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage((int)msg.wParam);
break;
} switch (msg.message)
{
case WM_LBUTTONUP:
ReleaseCapture();
break;
case WM_MOUSEMOVE:
DrawRect(&dc,tmpr);
tmppt = msg.pt;
tmp = oldpt - tmppt;
tmpr = r;
tmpr.right = r.right - tmp.x;
tmpr.bottom = r.bottom - tmp.y;
DrawRect(&dc,tmpr);
break;
default:
DispatchMessage(&msg);
break;
}
}
dc.Detach();
MoveWindow(&tmpr);
return;
}
CDialog::OnNcLButtonDown(nHitTest, point);
}
改了一下绘制方式
添加一个类变量
MINMAXINFO mminfo;
void CMyDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{ mminfo = *lpMMI; //这里赋值 CDialog::OnGetMinMaxInfo(lpMMI);
}void CDlg2Dlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if(nHitTest == HTBOTTOMRIGHT)
{
SetCapture();
CRect r,tmpr;
GetWindowRect(&r);
tmpr = r;
CPoint oldpt(point),tmppt;
CPoint tmp;
HDC hdc = ::GetDC(NULL); CDC dc;
dc.Attach(hdc);
dc.SelectObject(CDC::GetHalftoneBrush()); //Halftone画刷
while (CWnd::GetCapture() == this)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage((int)msg.wParam);
break;
} switch (msg.message)
{
case WM_LBUTTONUP:
ReleaseCapture();
break;
case WM_MOUSEMOVE:
if(r != tmpr) //去除不刷新现象
DrawRect(&dc,tmpr);
tmppt = msg.pt;
tmp = oldpt - tmppt;
tmpr = r;
tmpr.right = r.right - tmp.x;
tmpr.bottom = r.bottom - tmp.y;
//限制可以拖动的窗口大小
if(tmpr.Width() > mminfo.ptMaxTrackSize.x)
tmpr.right = tmpr.left + mminfo.ptMaxTrackSize.x;
if(tmpr.Height() > mminfo.ptMaxTrackSize.y)
tmpr.bottom = tmpr.top + mminfo.ptMaxTrackSize.y;
if(tmpr.Width() < mminfo.ptMinTrackSize.x)
tmpr.right = tmpr.left + mminfo.ptMinTrackSize.x;
if(tmpr.Height() < mminfo.ptMinTrackSize.y)
tmpr.bottom = tmpr.top + mminfo.ptMinTrackSize.y;
DrawRect(&dc,tmpr);
break;
default:
DispatchMessage(&msg);
break;
}
}
dc.Detach();
MoveWindow(&tmpr);
return;
}
CDialog::OnNcLButtonDown(nHitTest, point);
}
其他的7个方向应该类似可以添加上去
还是会有残留:因为我的窗口上有很错空间,我的窗口风格用了WS_CLIPCHILDREN |WS_CLIPSIBLINGS 风格,所以产生了残留痕迹。怎么解决?还有 我用了ShowWindow(SW_SHOWMAXIMIZED);最大化窗口,然后拖动改变窗口大小,再ShowWindow(SW_SHOWMAXIMIZED)时候没有放映,是不是因为系统还以为出于最大化?怎么解决?
还是会有残留:因为我的窗口上有很多控件,窗口用了WS_CLIPCHILDREN |WS_CLIPSIBLINGS 风格,所以产生了残留痕迹。怎么解决?还有 我用了ShowWindow(SW_SHOWMAXIMIZED);最大化窗口,然后拖动改变窗口大小,再ShowWindow(SW_SHOWMAXIMIZED)时候没有放映,是不是因为系统还以为出于最大化?怎么解决?
是没有反应,处于最大化的时候不能拖动
你可能不是在WM_NCLBUTTONDOWN消息里响应的,检查是否最大化?如果是不要拖动,
或者自己计算最大窗口直接Move过去退出while循环后
DrawRect(&dc,tmpr); //在画一次擦除
dc.Detach();
if(GetStyle() & WS_MAXIMIZE) //修改窗口风格 取消最大化状态
ModifyStyle(WS_MAXIMIZE,0);
MoveWindow(tmpr.left,tmpr.top,rand() % 500,rand() % 500);
void CClientDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
{ // TODO: 在此添加消息处理程序代码和/或调用默认值
if(nHitTest == HTBOTTOMRIGHT || nHitTest == HTBOTTOM || nHitTest == HTBOTTOMLEFT || nHitTest == HTLEFT || nHitTest == HTRIGHT || nHitTest == HTTOP || nHitTest == HTTOPRIGHT || nHitTest == HTTOPLEFT)
{
SetCapture();
CRect r,tmpr;
GetWindowRect(&r);
tmpr = r;
CPoint oldpt(point),tmppt;
CPoint tmp;
HDC hdc = ::GetDC(NULL);
CDC dc;
dc.Attach(hdc); while (CWnd::GetCapture() == this)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage((int)msg.wParam);
break;
} switch (msg.message)
{
case WM_LBUTTONUP:
ReleaseCapture();
break;
case WM_MOUSEMOVE:
if ( tmpr.Width() < 640 || tmpr.Height() < 480 )
break; if ( r != tmpr )
DrawRect(&dc,tmpr);
tmppt = msg.pt;
tmp = oldpt - tmppt;
tmpr = r;
switch( nHitTest)
{
case HTBOTTOM:
tmpr.bottom = r.bottom - tmp.y;
break;
case HTBOTTOMLEFT:
tmpr.left = r.left - tmp.x;
tmpr.bottom = r.bottom - tmp.y;
break;
case HTBOTTOMRIGHT:
tmpr.right = r.right - tmp.x;
tmpr.bottom = r.bottom - tmp.y;
break;
case HTLEFT:
tmpr.left = r.left - tmp.x;
break;
case HTRIGHT:
tmpr.right = r.right - tmp.x;
break;
case HTTOP:
tmpr.top = r.top - tmp.y;
break;
case HTTOPRIGHT:
tmpr.top = r.top - tmp.y;
tmpr.right = r.right - tmp.x;
break;
case HTTOPLEFT:
tmpr.top = r.top - tmp.y;
tmpr.left = r.left - tmp.x;
break; }
DrawRect(&dc,tmpr);
break;
default:
DispatchMessage(&msg);
break;
}
} DrawRect(&dc,tmpr); //在画一次擦除
dc.Detach();
if(GetStyle() & WS_MAXIMIZE) //修改窗口风格 取消最大化状态
ModifyStyle(WS_MAXIMIZE,0);
MoveWindow(&tmpr);
return;
} GSDialog::OnNcLButtonDown(nHitTest, point);
}