有没有办法在Windows窗体StatusBar类上启用双缓冲?如何在Windows窗体状态栏上启用双缓冲?
我正在更新鼠标移动事件上的一些地图坐标,并且闪烁/重绘非常明显。我试过从StatusBar类继承并设置它的DoubleBuffer = true
并覆盖它的OnPaintBackground
方法。我也尝试了所有者绘制的东西,没有任何运气。
有没有办法在Windows窗体StatusBar类上启用双缓冲?如何在Windows窗体状态栏上启用双缓冲?
我正在更新鼠标移动事件上的一些地图坐标,并且闪烁/重绘非常明显。我试过从StatusBar类继承并设置它的DoubleBuffer = true
并覆盖它的OnPaintBackground
方法。我也尝试了所有者绘制的东西,没有任何运气。
System.Windows.Forms.StatusBar
是一个传统控件,它可能不关心DoubleBuffered属性。您可以尝试在派生类的构造函数设置它像这样:
this.SetStyle(ControlStyles.DoubleBuffer, true);
虽然我真的建议尝试StatusStrip
控制。它适用于Windows窗体,而不是由操作系统绘制,而StatusBar
是。
我确实更改为StatusStrip(使用托管渲染器)和ToolStripStatusLabel(蚀刻边框),并且它们完美无瑕地工作。谢谢。 – Brannon
//declare a renderer, but do not initialize in here,
//because if current theme is classics, it will error
VisualStyleRenderer _barRenderer;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
//eat WM_ERASEBKGND, and in WM_PAINT draw the background
case 0x14:
m.Result = (IntPtr)1;
return;
case 0xF://WM_PAINT
PAINTSTRUCT ps;
var hdc = BeginPaint(m.HWnd, out ps); //see MSDN
BufferedGraphics bg = null; //use memory graphics
try
{
var rect = ClientRectangle;
bg = BufferedGraphicsManager.Current.Allocate(hdc, rect);
//draw background
if (Application.RenderWithVisualStyles)
{
//just initialize renderer once
if (_barRenderer == null)
{
_barRenderer = new VisualStyleRenderer(VisualStyleElement.Status.Bar.Normal);
}
_barRenderer.DrawBackground(bg.Graphics, rect);
}
else
{
bg.Graphics.SetClip(rect); //not essential
bg.Graphics.Clear(SystemColors.Control);
}
//let system draw foreground, include texts, icons, separators etc
m.WParam = bg.Graphics.GetHdc(); //required, GetHdc() is not only obtain a dc handle,
base.WndProc(ref m); //it open a context for the dc, and let system draw on this context
bg.Graphics.ReleaseHdc(); //timely release
bg.Render();
return;
}
finally
{
if (bg != null) { bg.Dispose(); }
EndPaint(m.HWnd, ref ps); //see MSDN
}
}
base.WndProc(ref m);
}
#region Win32 API
[DllImport("user32.dll")]
private static extern IntPtr BeginPaint(IntPtr hWnd, out PAINTSTRUCT lpPaint);
[DllImport("user32.dll")]
private static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
[StructLayout(LayoutKind.Sequential)]
private struct PAINTSTRUCT
{
public IntPtr hdc;
public bool fErase;
public RECT rcPaint;
public bool fRestore;
public bool fIncUpdate;
public int reserved1;
public int reserved2;
public int reserved3;
public int reserved4;
public int reserved5;
public int reserved6;
public int reserved7;
public int reserved8;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
#endregion
'DoubleBuffered = false'是默认情况下,你为什么要这样设置?此外,您希望启用双缓冲区,您应该将其设置为“true”,而不是“false”。 –
我的意思是“真的”。固定。 – Brannon
你在'StatusBar'上画什么东西?如果您必须显示一些信息,请尝试自定义“标签”或“面板”,但不是太难,当然也不会闪烁。 –