在循环内清除GDI形状

时间:2012-03-17 17:53:31

标签: c++ winapi gdi

我有一个程序在鼠标光标下绘制一个矩形并显示像素颜色,但如果我使用' InvalidateRect(),我无法管理它以清除while循环内的形状'它清晰的矩形太快和闪烁,如果不使用' InvalidateRect()'那么矩形保持重复像THIS,如何解决?

HWND hwnd;
POINT p;
unsigned short R=0, G=0, B=0;

void drawRect()
{
     GetCursorPos(&p);

     HDC hdc = GetDC(NULL);
     HPEN border = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
     HBRUSH background = CreateSolidBrush(RGB(R, G, B)); 

     SelectObject(hdc, border);
     SelectObject(hdc, background);
     Rectangle(hdc, p.x+10, p.y+10, p.x+40, p.y+40);

     DeleteObject(border);
     DeleteObject(background);
 }

 void init()
 {
     while (GetAsyncKeyState(VK_RBUTTON) & 0x8000)
     {
         grabPixel(); //get RGB color from cursor coordination
         drawRect();  //draw preview rectangle under cursor

         InvalidateRect(hwnd, NULL, true);
     }
 }

注意:它没有WinMain()或WndProc()

1 个答案:

答案 0 :(得分:1)

这有各种各样的错误。你究竟想做什么?

由于您使用的是GetDC(NULL),因此看起来这应该是在整个屏幕上绘制一个矩形。

hwnd值来自何处?如果那个窗口确实有一个消息循环(并且可能确实如此),那么窗口就会失效并重新绘制自己。

注意:InvalidateRect仅在下次该应用程序(实际上是线程的,或多或少)消息队列为空时将该矩形标记为需要绘制。 UpdateWindow会立即发送WM_PAINT条消息。

drawRect也没有正确清理。它应该在它完成时调用ReleaseDC,它应该在它完成之后恢复之前的绘图对象(并且最明确地删除它们之前):

HBRUSH oldBackground = SelectObject(hDC, background);

// ...

SelectObject(hDC, oldBackground);

您可能想要做的是,在选择开始时,创建一个与屏幕大小相同的窗口并copy the existing screen进入其中。然后你可以聪明地画出所有这些。

DrawDragRect函数(请参阅my blog)专为此类事件而设计。