0

我遇到的问题是,当我画线时,每次重画时屏幕都会闪烁。我只是无法弄清楚如何不让它闪烁。我知道当我用左键向下移动鼠标时,闪烁来自我每秒重绘客户区数百次,但我该如何解决这个问题?

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;
         }
4

1 回答 1

2

主要是响应WM_ERASEBKGND并返回true,防止默认重绘背景。

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

明显的替代方案(通常更简单,虽然理论上至少慢一点)是使用双缓冲。大致画出你现在的样子,但要画一个离屏的位图。然后,当一切都完成时,只需从那里到屏幕的 BitBlt。

于 2013-06-05T05:06:14.613 回答