如何使窗体改变大小时虚线框显示,而不是不停刷新内容?

lan_yanjing 2007-05-19 01:33:37
做了一个关于MSHFG的程序,由于有些列嵌入了自定义的超链接控件,在响应窗口OnSize时候grid的列宽要变化,对所有的控件也要进行SetWindowPos,使得窗口刷新的时候非常闪烁,想用虚框表示避免这个问题,当然那位大侠能帮我找到解决闪烁问题的办法更好了,我曾想把整列控件放到一个什么容器上,移动的时候一个SetWindowPos就好但是不会实现,请大家来帮忙
...全文
1232 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
马国泽 2012-03-25
  • 打赏
  • 举报
回复
晕,这么简单的问题居然没人知道,重载WM_ERASEBKGND消息,不让窗口擦除背景就会闪了
lan_yanjing 2007-06-27
  • 打赏
  • 举报
回复
终于等到了,虽然OnMove还不太对,再研究研究,结贴了
Anikan 2007-06-23
  • 打赏
  • 举报
回复
添加 以下代码在 .h中:
//member variable
CPoint m_oldPt;
CPoint m_offsetPt;
CRect m_wndRc;
CRect m_newRc;
CRect m_newSizeRect;
CRect m_oldSizeRect;
BOOL m_bDrawFrame;
BOOL m_needFinish;
BOOL m_bDrawSize;
BOOL m_needSize;

LRESULT OnMoving(WPARAM,LPARAM);
LRESULT OnExitSizeMove(WPARAM,LPARAM);
LRESULT OnEnterSizeMove(WPARAM, LPARAM);
LRESULT OnSizing(WPARAM,LPARAM);

DECLARE_MESSAGE_MAP()
添加 以下代码在 .CPP中:
ON_MESSAGE(WM_MOVING,OnMoving)
ON_MESSAGE(WM_EXITSIZEMOVE,OnExitSizeMove)
ON_MESSAGE(WM_ENTERSIZEMOVE,OnEnterSizeMove)
ON_MESSAGE(WM_SIZING,OnSizing)
END_MESSAGE_MAP()

下面是简单的处理函数,你可以扩展

LRESULT CPrimeNumDlg::OnEnterSizeMove(WPARAM, LPARAM){
GetWindowRect(&m_wndRc);
m_oldSizeRect = m_wndRc;
m_oldPt = CPoint(m_wndRc.left,m_wndRc.top);
m_offsetPt = CPoint(0,0);
m_bDrawFrame = FALSE;
return TRUE; //we don't process this message

}

LRESULT CPrimeNumDlg::OnExitSizeMove(WPARAM,LPARAM){
if(m_needFinish){
CRect rect;
rect.left = m_oldPt.x - m_offsetPt.x;
rect.top = m_oldPt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);
m_needFinish = FALSE;

SetWindowPos(NULL,m_oldPt.x,m_oldPt.y,m_wndRc.Width(),m_wndRc.Height(),\
SWP_NOSENDCHANGING ); //prevent receiving more moving message
GetWindowRect(&m_wndRc);
m_oldPt = CPoint(m_wndRc.left,m_wndRc.top);
m_offsetPt = CPoint(0,0);
m_bDrawFrame = FALSE;
}
if(m_needSize){
m_bDrawSize = FALSE;
m_needSize = FALSE;
DrawDashFrame(m_oldSizeRect);
SetWindowPos(NULL,m_newSizeRect.left,m_newSizeRect.top,m_newSizeRect.Width(),m_newSizeRect.Height(),\
SWP_NOSENDCHANGING ); //prevent receiving more moving message
}
return TRUE; //we don't process this message
}


void CPrimeNumDlg::DrawDashFrame(CRect& rect){

CPen pen;
pen.CreatePen(PS_DASH,1,RGB(0,0,0));
CWnd* p_desktop = GetDesktopWindow();
CDC* p_dc_desktop = p_desktop->GetWindowDC();

p_dc_desktop->SetROP2(R2_XORPEN );
CPen* p_old_pen = p_dc_desktop->SelectObject(&pen);
p_dc_desktop->MoveTo(rect.left,rect.top);
p_dc_desktop->LineTo(rect.left,rect.bottom);

p_dc_desktop->MoveTo(rect.left,rect.bottom);
p_dc_desktop->LineTo(rect.right,rect.bottom);

p_dc_desktop->MoveTo(rect.right,rect.bottom);
p_dc_desktop->LineTo(rect.right,rect.top);

p_dc_desktop->MoveTo(rect.right,rect.top);
p_dc_desktop->LineTo(rect.left,rect.top);
p_dc_desktop->SelectObject(p_old_pen);
p_desktop->ReleaseDC(p_dc_desktop);
}


LRESULT CPrimeNumDlg::OnMoving(WPARAM wp,LPARAM lp){

RECT* p_rc = (RECT*)lp;
m_newRc = CRect(p_rc);
CPoint pt;
GetCursorPos(&pt);

if(!m_bDrawFrame){
m_bDrawFrame = TRUE;
m_offsetPt = CPoint(pt.x - m_wndRc.left,pt.y - m_wndRc.top);
m_oldPt = pt;

CRect rect;
rect.left = m_oldPt.x - m_offsetPt.x;
rect.top = m_oldPt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);
m_needFinish = TRUE;
}
else{
CRect rect;
rect.left = m_oldPt.x - m_offsetPt.x;
rect.top = m_oldPt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);

rect.left = pt.x - m_offsetPt.x;
rect.top = pt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);
m_oldPt = pt;
}

int width = p_rc->right - p_rc->left;
int height = p_rc->bottom - p_rc->top;

p_rc->left = m_wndRc.left;
p_rc->right = p_rc->left + width;
p_rc->top = m_wndRc.top;
p_rc->bottom = p_rc->top + height;
return FALSE; //we process this message

}


LRESULT CPrimeNumDlg::OnSizing(WPARAM wp,LPARAM lp){

m_needSize = TRUE;

if(!m_bDrawSize){
DrawDashFrame(m_wndRc);
m_oldSizeRect = m_wndRc;
m_bDrawSize = TRUE;

}
else{
RECT* p_rc = (RECT*)lp;
m_newSizeRect = CRect(p_rc);
DrawDashFrame(m_oldSizeRect);
DrawDashFrame(m_newSizeRect);
p_rc->left = m_wndRc.left;
p_rc->right = m_wndRc.right;
p_rc->top = m_wndRc.top;
p_rc->bottom = m_wndRc.bottom;
m_oldSizeRect = m_newSizeRect;
}
return FALSE; //we don't process this message
}

//That is it, good luck
lan_yanjing 2007-06-21
  • 打赏
  • 举报
回复
UP到天荒地老
DADA_dotnet 2007-06-20
  • 打赏
  • 举报
回复
新手学VC,现在只能做做苦力(能力有限),帮顶,这个问题以后也会遇到,关注!
lan_yanjing 2007-06-18
  • 打赏
  • 举报
回复
能不能具体点,还有楼上试过了吗,还是靠感觉的,OnMove,OnMoving,OnSize,OnSizing注释掉父类的函数调用,窗口移动没有变化,Size只有大小超过FormView会不正常(CFormView),有兴趣的可以试一下,看看是怎么回事儿,还有在PreTranslateMessage甚至截获不到WM_MOVE一类的消息,不知道什么问题,还是我写错了什么
lan_yanjing 2007-06-18
  • 打赏
  • 举报
回复
pfans(pfans) :
移动子控件前调用父窗口SetRedraw(FALSE),调用完SetWindowPos后再调用父窗口SetRedraw(TRUE)

这个不错啊,虽然不是用来实现拖动时虚线显示,不过程序比以前好多了,至少给你20分了,呵呵,继续期待高手
pfans 2007-06-18
  • 打赏
  • 举报
回复
移动子控件前调用父窗口SetRedraw(FALSE),调用完SetWindowPos后再调用父窗口SetRedraw(TRUE)
Anikan 2007-06-16
  • 打赏
  • 举报
回复
处理WM_MOVING ,画虚框
处理WM_MOVE 重画窗口内容
lan_yanjing 2007-06-15
  • 打赏
  • 举报
回复
晕死啊,摆脱楼上两位,不要改系统啊,只对我程序,别告诉我那函数只对程序而言啊,现在没vc不能试,如果真的可以那我真要另开一贴给你100分啦
fbmsf 2007-06-15
  • 打赏
  • 举报
回复
HKEY_CURRENT_USER\Control Panel\Desktop\DragFullWindows="0"]
tracing 2007-06-15
  • 打赏
  • 举报
回复
一个函数就OK了,把分全给我吧,哈哈
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, 0);
fbmsf 2007-06-14
  • 打赏
  • 举报
回复
[HKEY_CURRENT_USER\Control Panel\Desktop\DragFullWindows ="1"]拖动时是否显示全部的窗口。
拿节 2007-06-14
  • 打赏
  • 举报
回复
我也up!
哈哈!
lan_yanjing 2007-06-14
  • 打赏
  • 举报
回复
楼上的照你该了没效果啊,不会要重启的吧,就算有效果应该也不是我想要的那种,是让我的窗口拖动时虚线框显示,不要修改系统设置啊
lan_yanjing 2007-06-13
  • 打赏
  • 举报
回复
up
lyg_zy 2007-06-08
  • 打赏
  • 举报
回复
在鼠标拖动过程中用异或模式绘制虚线框,在鼠标WM_LBUTTONUP后才实际挪动你的子控件。
大体实现代码如下:
pDC->SetRop2(R2_XORPEN);
pDC->DrawFocusRect(CRect(point-size,point+size));

tracing 2007-06-08
  • 打赏
  • 举报
回复
我也在想这个问题,UP
lan_yanjing 2007-06-08
  • 打赏
  • 举报
回复
up...
lan_yanjing 2007-06-06
  • 打赏
  • 举报
回复
再起
加载更多回复(15)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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