绘制线条时客户区闪烁

时间:2013-06-05 04:59:33

标签: c++ winapi gdi

我遇到的问题是,当我绘制线条时,每次重绘时屏幕都会闪烁。我只是无法弄清楚如何不让它闪烁。我知道闪烁来自于我每秒重绘客户区数百次,因为我用左手按钮移动鼠标但是我怎么能绕过这个?

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, 
                          WPARAM wParam, LPARAM lParam)
     {
     static HDC      hdc;
     PAINTSTRUCT     ps;
     RECT            rect;
     RECT            size;
     static POINT   point1;
     static POINT   point2;
     static HBRUSH  origBrush;
     static bool    drawingLine = false;

     switch (message)
         {

         case WM_CREATE:
             origBrush = CreateSolidBrush(RGB(0, 0 , 0) );

             break;

          case WM_PAINT:
                hdc = BeginPaint (hwnd, &ps);

                GetClientRect (hwnd, &rect);

                GetWindowRect(hwnd, &size);

                Rectangle(hdc, 10, 10, 80, 80 );

                if(drawingLine == true)
                {
                    MoveToEx(hdc, point1.x, point1.y, NULL);
                    LineTo(hdc, point2.x, point2.y);
                }

                EndPaint (hwnd, &ps);
                return 0;

                //Has all the commands that exist in your program.
          case WM_COMMAND:
              switch(LOWORD(wParam))
              {
              case ID_COLOR_RED:
                  break;

              case ID_COLOR_BLUE:
                  break;

              case ID_COLOR_BLACK:
                  break;

              case ID_THICKNESS_1:
                  break;

              case ID_THICKNESS_2:
                  break;

              case ID_THICKNESS_3:
                  break;

              }
              break;

          case WM_LBUTTONDOWN:
              drawingLine = true;
              SelectObject(hdc, GetStockObject(BLACK_BRUSH));
              point1.x = LOWORD(lParam);
              point1.y = HIWORD(lParam);
              MoveToEx(hdc, point1.x, point1.y, NULL);
              break;

          case WM_MOUSEMOVE:
              point2.x = LOWORD(lParam);
              point2.y = HIWORD(lParam);
              InvalidateRect(hwnd, NULL, 1);
              break;

          case WM_LBUTTONUP:
              point2.x = LOWORD(lParam);
              point2.y = HIWORD(lParam);

              drawingLine = false;
              break;

              //Causes the program to exit.
          case WM_DESTROY:
              PostQuitMessage(0);
              break;
         }

1 个答案:

答案 0 :(得分:2)

要做的主要事情是回复WM_ERASEBKGND并返回true以防止默认重新绘制背景。

然后你需要在绘制新线之前擦除旧线。例如,你可以从线下保存位,绘制它,然后在绘制线之前恢复那些(并且只有那些)像素,所以当你需要擦除它时,你可以恢复那些像素来擦除它。

显而易见的替代方案(通常在理论上通常更简单,但至少慢一点)是使用双缓冲。大致是你现在的绘图,但是到屏幕外的位图。然后,当它完全从那里完成BitBlt到屏幕时。