繁体   English   中英

C ++ GDI动画不起作用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM