当我查看TWinControl
时,Canvas
被clBtnFace
消隐,然后WM_PAINT
被调用。这会导致我不需要的不可避免的闪烁。此外,给定的画布允许在滚动条上绘制,使得在WM_PAINT
事件之后重新绘制滚动条并创建更多闪烁。
GetMetrics
和内部滚动条信息提供真正的画布大小。如果我错了,请纠正我,但我理解HDC
是表格上的一个句柄,有一个矩形画布可以打印。所以我在想:
如何创建宽度和高度较小的新HDC
,而不是移动左上角。我想删除闪烁,如果可能的话不使用WM_ERASEBKGND
消息,而不是通过分配新的HDC
来打印滚动条,然后使用正确的HDC
设置Delphi画布句柄。 / p>
使用我不知道是否应该使用的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;
我不知道哪个选项在无闪烁结果中更好,以及如何在Delphi中实现它。
答案 0 :(得分:1)
...
消隐了Canvas
被clBtnFace
...
背景颜色可通过设置Brush.Color
进行调整。
然后调用
WM_PAINT
。这导致不可避免的闪烁......
可以通过绕过WM_ERASEBKGND
消息来阻止这种情况。
如何创建宽度和高度较小的新
HDC
?
这是不可能的。设备上下文没有大小。它只受到托管它的窗口的限制。
给定的画布允许在滚动条上绘制,使得在
WM_PAINT
事件后重绘滚动条。
原始滚动条由系统在WM_NCPAINT
中绘制。如果你可以绘制它们,那么你已经获得了整个窗口的设备上下文,而不是它的客户空间。
但总的来说,解决方案非常简单:不要超出窗口的客户区域。
作为提示:我建议您从TCustomControl
而不是TWinControl
派生您的控件,因为该类已经可以绘制一个画布,从而消除了所有WinAPI代码。