第二条线倒是没有这种情况。(后来发现可能是因为改变了点pt1,pt2或x1,y1,x2,y2,dx,dy的原因吧,因为当去掉
pt1=CPoint(10,50);
pt2=CPoint(100,20);
PointInit(pt1,pt2);
SetTimer(1,10,NULL);以后第一条线也就没有问题了!)
下面是一部分源代码:
1、主文件的头文件中主要变量的声明:
CPoint pt1;//起点
CPoint pt2;//终点
FLOAT dx,dy;//移动点时每次的增量
FLOAT x1,y1,x2,y2;//初始化时的起点终点坐标值
FLOAT x,y;//移动点中间变量
void PointInit(CPoint pStart,CPoint pEnd);//坐标点的初始化
void Draw();//主要画线代码
2、初始化中:
pt1=CPoint(50,50);
pt2=CPoint(129,187);
PointInit(pt1,pt2);
3、OnPaint()中加入Draw():
Draw();//主要的画线程序
if (IsIconic())
{————}
————
4、定时器主要代码:
void CLineMoveDlg::OnTimer(UINT nIDEvent)
{
if (nIDEvent==1)
{ x+=dx;
y+=dy;
OnPaint();
}
CDialog::OnTimer(nIDEvent);
}
5、鼠标点击事件代码:(只有一句)
SetTimer(1,10,NULL);
6、坐标点的初始化:
void CLineMoveDlg::PointInit(CPoint pStart,CPoint pEnd)
{
x=x1=pStart.x;
y=y1=pStart.y;
x2=pEnd.x;
y2=pEnd.y;
dx=(x2-x1)/200;
dy=(y2-y1)/200;
}
7、主要画线代码:
void CLineMoveDlg::Draw()
{
CDC* m_dc = GetDC();
CPen m_pen(PS_SOLID,5,RGB(50,220,255));
m_dc->SelectObject(&m_pen);
m_dc->MoveTo(x1,y1);
m_dc->LineTo(x,y);
if (x2>=x1&&y2>=y1)
{
if (x>=x2&&y>=y2)
{
KillTimer(1);
//去掉下面四句代码后第一条线也就没问题了!
pt1=CPoint(10,50);
pt2=CPoint(100,20);
PointInit(pt1,pt2);
SetTimer(1,10,NULL);
}
}
else if (x2>=x1&&y2<=y1)
{
if (x>=x2&&y<=y2)
{
KillTimer(1);
}
}
else if (x2<=x1&&y2>=y1)
{
if (x<=x2&&y>=y2)
{
KillTimer(1);
}
}
else if (x2<=x1&&y2<=y1)
{
if (x<=x2&&y<=y2)
{
KillTimer(1);
}
}
}
请各位帮忙看看,谢谢!!!
7 个解决方案
#1
void CLineMoveDlg::OnTimer(UINT nIDEvent)
{
if (nIDEvent==1)
{ x+=dx;
y+=dy;
OnPaint();
}
CDialog::OnTimer(nIDEvent);
}
==================
OnPaint不是由你调用的,它是由系统当出现WM_PAINT消息时自己调用的.你在定时器中应该用UpdateWindow来触发消息.
{
if (nIDEvent==1)
{ x+=dx;
y+=dy;
OnPaint();
}
CDialog::OnTimer(nIDEvent);
}
==================
OnPaint不是由你调用的,它是由系统当出现WM_PAINT消息时自己调用的.你在定时器中应该用UpdateWindow来触发消息.
#2
同意楼上老兄
#3
首先对第一楼的说法进行纠正,WM_PAINT并不是由UpdateWindow来触发的,而是对窗口设置了无效区域后,由Windows在适当的时机来触发WM_PAINT,那么UpdateWindow的作用是什么呢?它的作用是不必等Windows在适当的时机,而告诉Windows立即执行无效区域的绘制。所以如果我们要立即更新绘制,应该先InvalidateRect(m_hWnd,rcInvalidate,FALSE);然后UpdateWindow(m_hWnd);
对于搂主的写法似乎有点欠妥,在OnPaint应该是绘制全部,而不是部分,所以在OnPaint中不要使用GetDC这样的写法,
而是用CPaintDC,对于需要实时更新的部分,例如要在OnTimer中进行立即更新部分图像,应该使用GetDC来进行局部绘制,同时不要触发WM_PAINT来绘制。因为如果你每次都通过触发WM_PAINT来绘制,那么你的效率将是特别低下的。
当窗口被其他窗口覆盖等情况下,Windows会自动触发OnPaint来绘制全部,所以将绘制全部的代码放在OnPaint中是必须的。
===============================================================================
阙海忠 (CTO Skin++ 开发成员 http://www.uipower.com 上海勇进软件有限公司)
对于搂主的写法似乎有点欠妥,在OnPaint应该是绘制全部,而不是部分,所以在OnPaint中不要使用GetDC这样的写法,
而是用CPaintDC,对于需要实时更新的部分,例如要在OnTimer中进行立即更新部分图像,应该使用GetDC来进行局部绘制,同时不要触发WM_PAINT来绘制。因为如果你每次都通过触发WM_PAINT来绘制,那么你的效率将是特别低下的。
当窗口被其他窗口覆盖等情况下,Windows会自动触发OnPaint来绘制全部,所以将绘制全部的代码放在OnPaint中是必须的。
===============================================================================
阙海忠 (CTO Skin++ 开发成员 http://www.uipower.com 上海勇进软件有限公司)
#4
楼上的三位兄台,谢谢你们的回答,可是本人刚学VC不久,很多东西还不明白,
各位能说具体一些吗?
TO:wltg2001
再就是已经把OnTimer()中的事件改为了UpdateWindow();连线都画不出来了
TO:fafa_cai
您说的方法怎么用呢?
InvalidateRect(m_hWnd,rcInvalidate,FALSE);中rcInvalidate是怎么来的呢?
谢谢!
各位能说具体一些吗?
TO:wltg2001
再就是已经把OnTimer()中的事件改为了UpdateWindow();连线都画不出来了
TO:fafa_cai
您说的方法怎么用呢?
InvalidateRect(m_hWnd,rcInvalidate,FALSE);中rcInvalidate是怎么来的呢?
谢谢!
#5
上面的说法是对的,一般确实是用InvalidateRect来使客户无效,我上面的回贴是随手写的,InvalidateRect中的rcInvalidate一般可以设为NULL,表示整个客户区都无效.
#6
不明LZ在说什么
#7
呵,各位,终于弄明白了,原来在画完之后还要保存起点和终点,然后在OnPaint()中重绘
谢谢各位了!
谢谢各位了!
#1
void CLineMoveDlg::OnTimer(UINT nIDEvent)
{
if (nIDEvent==1)
{ x+=dx;
y+=dy;
OnPaint();
}
CDialog::OnTimer(nIDEvent);
}
==================
OnPaint不是由你调用的,它是由系统当出现WM_PAINT消息时自己调用的.你在定时器中应该用UpdateWindow来触发消息.
{
if (nIDEvent==1)
{ x+=dx;
y+=dy;
OnPaint();
}
CDialog::OnTimer(nIDEvent);
}
==================
OnPaint不是由你调用的,它是由系统当出现WM_PAINT消息时自己调用的.你在定时器中应该用UpdateWindow来触发消息.
#2
同意楼上老兄
#3
首先对第一楼的说法进行纠正,WM_PAINT并不是由UpdateWindow来触发的,而是对窗口设置了无效区域后,由Windows在适当的时机来触发WM_PAINT,那么UpdateWindow的作用是什么呢?它的作用是不必等Windows在适当的时机,而告诉Windows立即执行无效区域的绘制。所以如果我们要立即更新绘制,应该先InvalidateRect(m_hWnd,rcInvalidate,FALSE);然后UpdateWindow(m_hWnd);
对于搂主的写法似乎有点欠妥,在OnPaint应该是绘制全部,而不是部分,所以在OnPaint中不要使用GetDC这样的写法,
而是用CPaintDC,对于需要实时更新的部分,例如要在OnTimer中进行立即更新部分图像,应该使用GetDC来进行局部绘制,同时不要触发WM_PAINT来绘制。因为如果你每次都通过触发WM_PAINT来绘制,那么你的效率将是特别低下的。
当窗口被其他窗口覆盖等情况下,Windows会自动触发OnPaint来绘制全部,所以将绘制全部的代码放在OnPaint中是必须的。
===============================================================================
阙海忠 (CTO Skin++ 开发成员 http://www.uipower.com 上海勇进软件有限公司)
对于搂主的写法似乎有点欠妥,在OnPaint应该是绘制全部,而不是部分,所以在OnPaint中不要使用GetDC这样的写法,
而是用CPaintDC,对于需要实时更新的部分,例如要在OnTimer中进行立即更新部分图像,应该使用GetDC来进行局部绘制,同时不要触发WM_PAINT来绘制。因为如果你每次都通过触发WM_PAINT来绘制,那么你的效率将是特别低下的。
当窗口被其他窗口覆盖等情况下,Windows会自动触发OnPaint来绘制全部,所以将绘制全部的代码放在OnPaint中是必须的。
===============================================================================
阙海忠 (CTO Skin++ 开发成员 http://www.uipower.com 上海勇进软件有限公司)
#4
楼上的三位兄台,谢谢你们的回答,可是本人刚学VC不久,很多东西还不明白,
各位能说具体一些吗?
TO:wltg2001
再就是已经把OnTimer()中的事件改为了UpdateWindow();连线都画不出来了
TO:fafa_cai
您说的方法怎么用呢?
InvalidateRect(m_hWnd,rcInvalidate,FALSE);中rcInvalidate是怎么来的呢?
谢谢!
各位能说具体一些吗?
TO:wltg2001
再就是已经把OnTimer()中的事件改为了UpdateWindow();连线都画不出来了
TO:fafa_cai
您说的方法怎么用呢?
InvalidateRect(m_hWnd,rcInvalidate,FALSE);中rcInvalidate是怎么来的呢?
谢谢!
#5
上面的说法是对的,一般确实是用InvalidateRect来使客户无效,我上面的回贴是随手写的,InvalidateRect中的rcInvalidate一般可以设为NULL,表示整个客户区都无效.
#6
不明LZ在说什么
#7
呵,各位,终于弄明白了,原来在画完之后还要保存起点和终点,然后在OnPaint()中重绘
谢谢各位了!
谢谢各位了!