Delphi创建一个paint事件画布问题

时间:2016-01-27 03:10:27

标签: delphi delphi-7

当我查看TWinControl时,CanvasclBtnFace消隐,然后WM_PAINT被调用。这会导致我不需要的不可避免的闪烁。此外,给定的画布允许在滚动条上绘制,使得在WM_PAINT事件之后重新绘制滚动条并创建更多闪烁。

GetMetrics和内部滚动条信息提供真正的画布大小。如果我错了,请纠正我,但我理解HDC是表格上的一个句柄,有一个矩形画布可以打印。所以我在想:

  1. 如何创建宽度和高度较小的新HDC,而不是移动左上角。我想删除闪烁,如果可能的话不使用WM_ERASEBKGND消息,而不是通过分配新的HDC来打印滚动条,然后使用正确的HDC设置Delphi画布句柄。 / p>

  2. 使用我不知道是否应该使用的Windows位图,并将BitBlt()副本的位图画布大小设置为TWinControl(下方)。

    DC := GetDC(0);
    MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
    ReleaseDC(0, DC);
    MemDC := CreateCompatibleDC(0);
    OldBitmap := SelectObject(MemDC, MemBitmap);
    try
      DC := BeginPaint(Handle, PS);
      Perform(WM_ERASEBKGND, MemDC, MemDC);
      Message.DC := MemDC;
      WMPaint(Message);
      Message.DC := 0;
      BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
      EndPaint(Handle, PS);
    finally
      SelectObject(MemDC, OldBitmap);
      DeleteDC(MemDC);
      DeleteObject(MemBitmap);
    end;
    
  3. 我不知道哪个选项在无闪烁结果中更好,以及如何在Delphi中实现它。

1 个答案:

答案 0 :(得分:1)

  

... CanvasclBtnFace ...

消隐了

背景颜色可通过设置Brush.Color进行调整。

  

然后调用WM_PAINT。这导致不可避免的闪烁......

可以通过绕过WM_ERASEBKGND消息来阻止这种情况。

  

如何创建宽度和高度较小的新HDC

这是不可能的。设备上下文没有大小。它只受到托管它的窗口的限制。

  

给定的画布允许在滚动条上绘制,使得在WM_PAINT事件后重绘滚动条。

原始滚动条由系统在WM_NCPAINT中绘制。如果你可以绘制它们,那么你已经获得了整个窗口的设备上下文,而不是它的客户空间。

但总的来说,解决方案非常简单:不要超出窗口的客户区域。

作为提示:我建议您从TCustomControl而不是TWinControl派生您的控件,因为该类已经可以绘制一个画布,从而消除了所有WinAPI代码。