【问题标题】:win32 content changed but doesn't show update unless window is movedwin32 内容已更改,但除非移动窗口,否则不会显示更新
【发布时间】:2014-04-12 05:37:30
【问题描述】:

我的 win32 GUI 内容每秒都会更改一次,但除非手动移动窗口,否则它不会显示更新。我试图每秒弹出一个消息框以触发窗口刷新并且它起作用了。因此,它证明我的内容确实发生了变化,但窗口没有更新。 我希望窗口刷新而不每次都弹出消息框,是否有用于此的窗口功能?谢谢

case WM_PAINT:


RECT fingerprintSection;
fingerprintSection.left=500;
fingerprintSection.top=300;
fingerprintSection.bottom=540;
fingerprintSection.right=660;

    wmId    = LOWORD(wParam);
    hdc = BeginPaint(hWnd, &ps);

    refresh=!refresh;
    if((start==true)&&(refresh==true)&&(stop!=true))
    {       

    windowName = MultiByteStringToWideString(name1, CP_ACP);
    LoadAndBlitBitmap(windowName.c_str(), hdc,500,0);//loading a picture that doesnt change
    fingerprint();
    LoadAndBlitBitmap(TEXT("outresized.bmp"), hdc,500,300);//loading a picture that constantly change
    refresh=!refresh;

//RedrawWindow(hWnd,&fingerprintSection,NULL,RDW_INTERNALPAINT|RDW_VALIDATE|RDW_UPDATENOW|RDW_NOCHILDREN);

InvalidateRect( hWnd, &fingerprintSection, TRUE );
    }
    EndPaint(hWnd, &ps);
    break;

【问题讨论】:

  • 可以使用RedrawWindow功能:msdn.microsoft.com/en-us/library/windows/desktop/…
  • @inixsoftware,我尝试了函数 InvalidateRect 并加载 blitmap 以在循环中再次绘制它。它提供与 RedrawWindow 相同的东西吗?
  • 应该的。它将向 WM_REPAINT 发送消息以强制它重新绘制
  • =( 窗口已重绘,但它只是不显示更新,除非它被移动或消息框将其唤醒。就像每次都必须按 f5
  • 这个功能怎么样? WM_SHOWWINDOW

标签: c++ winapi refresh win32gui


【解决方案1】:

如果您在 WM_PAINT 之外的窗口中绘图(我猜在这种情况下,当您收到 WM_TIMER 消息时,您可能正在对计时器进行一些 GDI 绘图),那么您应该调用 InvalidateRect() 例如

InvalidateRect( hWnd, NULL, FALSE );   // invalidate whole window

这应该会导致 Windows 重新绘制整个窗口。如果您只写了一个小区域,请传递一个描述您所写区域的 RECT。

如果你想在你的 windows 程序接收到 WM_PAINT 消息时进行绘制AND,例如,想要强制每秒发生一次,然后设置一个计时器...

#define SECOND_TIMER 1000

case WM_INITDIALOG:
   SetTimer( hWnd, SECOND_TIMER, SECOND_TIMER, NULL );
   //other initialisation stuff
   break;

case WM_TIMER:
   if( wParam == SECOND_TIMER )
   { 
       InvalidateRect( hWnd, NULL, FALSE );   // invalidate whole window
   }
   break;

在这个简单的例子中,整个窗口应该每秒重绘一次,因为 Windows 会由于 InvalidateRect 而发送 WM_PAINT 消息。理想情况下,您应该只使您正在重绘的部分无效。

【讨论】:

  • 嗨。我正在 WM_PAINT 内绘图。我尝试在循环中使用 InvalidateRect 但它对我不起作用。这是我的代码。 pastebin.com/d8PVQuBr
  • 只有当 Windows 向您的窗口过程发送 WM_PAINT 消息时,才会在 WM_PAINT 中进行绘图。如果您的应用程序没有执行任何操作,则不会发送 WM_PAINT - 除非,例如,您将桌面中的另一个窗口移到您的窗口上方。上面的答案添加了简单的修复...
  • 我不知道!非常感谢您的修复和启发!
  • 你救了我在这里。花了好几个小时想知道为什么 SetBitmapBits 和 SelectObject 似乎只在第一次工作但从不刷新。无效矩形(hWnd,NULL,FALSE);是关键。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-04-15
  • 2019-12-21
相关资源
最近更新 更多