2013-10-04 24 views
0

有没有办法在Windows窗体StatusBar类上启用双缓冲?如何在Windows窗体状态栏上启用双缓冲?

我正在更新鼠标移动事件上的一些地图坐标,并且闪烁/重绘非常明显。我试过从StatusBar类继承并设置它的DoubleBuffer = true并覆盖它的OnPaintBackground方法。我也尝试了所有者绘制的东西,没有任何运气。

+1

'DoubleBuffered = false'是默认情况下,你为什么要这样设置?此外,您希望启用双缓冲区,您应该将其设置为“true”,而不是“false”。 –

+0

我的意思是“真的”。固定。 – Brannon

+0

你在'StatusBar'上画什么东西?如果您必须显示一些信息,请尝试自定义“标签”或“面板”,但不是太难,当然也不会闪烁。 –

回答

0

System.Windows.Forms.StatusBar是一个传统控件,它可能不关心DoubleBuffered属性。您可以尝试在派生类的构造函数设置它像这样:

this.SetStyle(ControlStyles.DoubleBuffer, true);

虽然我真的建议尝试StatusStrip控制。它适用于Windows窗体,而不是由操作系统绘制,而StatusBar是。

+0

我确实更改为StatusStrip(使用托管渲染器)和ToolStripStatusLabel(蚀刻边框),并且它们完美无瑕地工作。谢谢。 – Brannon

0
//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 
+0

这里有相当多的代码。请考虑添加一个解释和/或严重评论代码,以便读者理解您的意图和发生的事情。 – ADyson

+0

@ADyson,好吧,但我的英语不好,我会尝试。 – ahdung