[英]c++ gdi animation not working
即时通讯试图使用GDI创建球动画,但我无法使其正常工作。 我用这个创造了一个球
Graphics graphics(hdc);
钢笔pen(Color(255,0,0,255)); graphics.DrawEllipse(&pen,sf,0,10,10); 我有一个while循环,基本上像这样的sf ++循环并向sf值加1; 比我尝试重画窗口(它不起作用),所以生病了一个以上的圆圈; /这是循环(循环是int WM_PAINT)
while(sd==1)//sd equals 1
{
sf++;
onPaint(hdc);
InvalidateRect (hWnd, NULL, TRUE);// this should repaint the window but it doesn't
UpdateWindow(hWnd);
}
在此先感谢拉米
为了获得动画效果,我建议您使用计时器。 例如:
int OnCreate(HWND window, WPARAM wParam, LPARAM lParam)
{
SetTimer(window, TIMER_ID, 1000, 0);
return 0;
}
现在,窗口将每秒(1000毫秒)接收WM_TIMER消息。 您应该处理它们:
int OnTimer(HWND window, WPARAM wParam, LPARAM lParam)
{
if(TIMER_ID == wParam)
{
/*do stuff*/
InvalidateRect(window, NULL, TRUE);//force window to repaint
}
return 0;
}
那么您需要处理WM_PAINT消息以进行绘制
int OnPaint(HWND window, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC dc = BeginPaint(&ps);
Graphics graphics(hdc);
graphics.Draw...
EndPaint(&ps);
return 0;
}
您确实意识到您正在以(sd == 1)为条件的循环中递增sf,对吗? 当然,这将无限循环或永远不会输入,因为sd的值不会以任何方式更改。 您在这里使用过调试器吗? 您为什么仍然需要这样的循环? 您不应在循环中调用OnPaint。
如果您想要一个以上的圆,只需在将所有圆从函数返回之前画出它们即可。 维护将用于在OnPaint处理程序中绘制圆的数据的集合。
InvalidateRect发送WM_ERASEBKGND消息,并且如果您在创建窗口时没有定义WNDCLASS结构的hbrBackground(重新绘制背景的画笔)成员,则除非您自己处理WM_ERASEBKGND消息,否则它不会重绘背景。
如果那不是问题,则可能是因为您是直接调用UpdateWindow而不是轮询和处理消息,所以永远不会处理WM_ERASEBKGND消息。 在绘制新圆圈之前,请尝试用背景颜色覆盖前一个圆圈。
或以WM_ERASEBKGRND作为消息调用SendMessage。
我在msdn上找到了一个示例,该示例显示了如何在纯Win32中绘制内容。
您不应在WM_PAINT中调用Invalidate或Updatewindow,因为UpdateWindow将发送一个新的WM_PAINT事件,并使无效累积,直到下一个 wm_paint事件为止。
您应该将代码分为两个功能,一个执行运动,另一个在当前位置绘制圆。
您的Mover函数可以在任何地方调用(也许在计时器处理函数中?),并且应该以
InvalidateRect (hWnd, NULL, TRUE);
UpdateWindow(hWnd);
为了标记您的客户区域以重绘并通知您的窗口重绘自己。
您的Draw()函数应读取通过mover函数设置的位置,并在此位置周围画一个圆。
(旁注:如果要最大程度地减少闪烁并获得平滑的动画,请在基本动画启动并运行后看看双重缓冲 )
UPDATE
您在更新功能中缺少UpdateWindow命令仅在应用程序收到WM_PAINT消息时才调用OnPaint-Function,因此您需要发送这些消息。
UpdateWindow可以达到这个目的
VOID update(HDC hdc,HWND hWnd)
{
sf++;
FillRect(hdc,rect,(HBRUSH)(COLOR_WINDOW+1));
InvalidateRect (hWnd, NULL, TRUE);
UpdateWindow(hWND);//<- This Line sends a wm_paint-message to your window in order to make it redraw itself
}
//i didn't do any changes to the onPaint functon but here is the code for it
VOID onPaint(HDC hdc)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
}
//here is the while loop
while(sd==1)
{ onPaint(hdc);
update(hdc,hWnd);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.