Dialog画线
我想在Dialog上画线,同时当窗体大小改变时,线的长度始终为Dialog的Width-60,我在OnPaint中写了画线的代码,可是发现只有窗体变大时才会重画,而减小窗体尺寸时并不调用OnPaint,把OnPaint代码放到OnSize中无效,以下是OnPaint的代码:
...
CPaintDC dc(this); //为什么要用CPaintDC呢?CDC或CClientDC为什么不行?
CRect rect;
GetClientRect(rect);
CPen NewPen(PS_SOLID, 1, RGB(255, 0, 0));
CPen* pOldPen = dc.SelectObject(&NewPen);
dc.MoveTo (60,10);
dc.LineTo(rect.right-60,10);
dc.SelectObject(pOldPen);
CDialog::OnPaint();//这句还有没有必要?
...
思路是通过rect得到窗体的大小,可是Dialog窗体大小改变时rect.right虽然改变,但dc.LineTo(rect.right-60,10)无效,这是怎么回事?
问题点数:44、回复次数:9Top
1 楼wjf(ww)回复于 2000-11-16 17:47:00 得分 20
1.在OnSize里调用Invalidate();
2.CDialog::OnPaint还是要的不过要先调他再画线。因为你只画了线,背景没管。而OnPaint画好了窗体应该画的。Top
2 楼zyj_vc(zyj)回复于 2000-11-16 18:12:00 得分 10
OnPaint函数中一定要用一个CPaintDC,因为它负责发送WM_BEGINPAINT和WM_ENDPAINT消息。你可以做个实验,先定义一个CPaintDC p_DC,然后再定义一个CClientDC dc,用dc划线可以,好象p_DC什么用都没有,但你删掉它就不行Top
3 楼sunyanbiao_12(废人)回复于 2000-11-16 19:54:00 得分 4
这句GetClientRect(rect);错了
GetClientRect(&rect);
应该是wjf说的在OnSize()中是用这些语句,OnSize()的参数好象有一个LPRECT参数,就不用GetClientRect()了。Top
4 楼iProgram(na)回复于 2000-11-17 18:01:00 得分 0
稍候给分...
我试试先Top
5 楼Erlin(很多年以后,我有了个绰号,叫白痴)回复于 2000-11-17 18:58:00 得分 10
只有一种可能,窗口区域变大时Windows认为需要重画,所以Windows会发WM_PAINT消息,因为变大时有些区域原来是看不到的,而当窗口变小时,因为所有区或在窗口大小改变时已经可见,故Windows认为不需重画, Windows不发WM_PAINT消息。 将你的OnPaint代码放入OnSize肯定是行不通的,因为CPaintDC是WM_PAINT消息的专用类,描述表由BeginPaint()函数创建,其它消息一概不行。为什么会这样。问TMD微软好了。
你可在OnSize函数里直接调InvalidateRect()应该可以解决这个问题,请试试先Top
6 楼Erlin(很多年以后,我有了个绰号,叫白痴)回复于 2000-11-17 19:00:00 得分 0
wjf是死循环,千万不要试!!!!!!!!Top
7 楼iProgram(na)回复于 2000-11-17 20:55:00 得分 0
我用wjf的方法:在OnSize里调用Invalidate();解决了我的问题,可是要先调CDialog::OnPaint再画线则显示不出线。
To sunyanbiao_12:
可是我用GetClientRect(&rect); 也能得到正确的结果,这是为什么呢?Dialog的OnSize的参数为OnSize(UINT nType, int cx, int cy) ,没有CRect
To Erlin
我在OnSize中调用InvalidateRect()的写以下代码:
void CLineTestDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(&rect);
InvalidateRect(&rect,true);
}
这是你的意思吗?我觉得还是wjf的方法简单,为什么是死循环呢?Top
8 楼iProgram(na)回复于 2000-11-18 11:11:00 得分 0
Hi,sunyanbiao_12
我在Dave的《Inside Visual C++》中看到了以下文字:
“如果您仔细读过《MFC Referenct》,您就可以注意到CWnd::InvalidateRect用到了一个LPRECT参数(一个指向RECT结构的指针),而不是CRect参数。用CRect参数也是允许的,因为CRect类定义了从载操作符LPRECT(),该操作符用于返回CRect对象的地址,它等价于RECT对象的地址。因此,编译器在必要的时候会把CRect变量转换为LPRECT变量。所以我们可以假定函数使用CRect引用参数来调用函数。试图的成员函数代码
CRect rectClient;
GetClientRect(rectClient);
可获得客户举行坐标并把他们保存在rectClient中"Top
9 楼w_black()回复于 2000-11-20 09:43:00 得分 0
在CXXXDlg中声明一个成员变量, 比如: CRect m_Rc;
在OnInitDialog()中加入:
CRect rc;
GetClientRect(rc);
m_Rc.SetRect(rc.left + 60, 10, rc.right - 60, 10);
在OnSize(UINT nType, int cx, int cy)中加入:
CDialog::OnSize(nType, cx, cy);
m_Rc.right = cx - 60;
Invalidate();
在OnPaint()中加入:
CPaintDC dc(this);
dc.MoveTo(m_Rc.left, m_Rc.top);
dc.LineTo(m_Rc.right, m_Rc.bottom);
CDialog::OnPaint();
即可Top




