我正在我的 WinForm 应用程序中绘制标题栏的一部分。工作正常(将公司名称置于居中并以橙色显示)
这是在表单代码中执行此操作的代码:
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
private Rectangle PosicionTexto()
{
string sTexto = String.Format("{0} : {1}", this.Text, "Trevo I.T.");
sTexto = "Trevo I.T.";
Graphics oG = this.CreateGraphics();
SizeF oS = oG.MeasureString(sTexto, new Font("Tahoma", 8f, FontStyle.Bold));
Rectangle rect = new Rectangle();
rect.X = (this.Width/2) - (int)(oS.Width/2);
rect.Y = SystemInformation.FrameBorderSize.Height + 4;
rect.Width = (int)oS.Width;
rect.Height = SystemInformation.CaptionButtonSize.Height;
return rect;
}
private void DrawTitleBar(IntPtr hwnd)
{
// Obtenemos el Canvas a partir del DC de la ventana
IntPtr hdc = GetWindowDC(hwnd);
Graphics gBarra = Graphics.FromHdc(hdc);
Rectangle rect = PosicionTexto();
string sTexto = String.Format("{0} : {1}", this.Text, "Trevo I.T.");
sTexto = "Trevo I.T.";
gBarra.DrawString(sTexto, new Font("Tahoma", 8f, FontStyle.Bold), Brushes.Orange, new PointF(rect.X, rect.Y));
// Liberamos la memoria*/
gBarra.Flush();
ReleaseDC(hwnd, hdc);
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x000F: // WM_PAINT
case 0x0085: // WM_NCPAINT:
base.WndProc(ref m);
DrawTitleBar(m.HWnd);
break;
default:
// Invocamos a la funcion original
base.WndProc(ref m);
break;
}
}
问题是调整窗口大小。文本未清除并显示多次。有没有办法在绘制文本之前“刷新”标题栏?
提前致谢。
EDIT差不多解决了。添加了另外两个方法:
// Rectangle of the title bar
private Rectangle TitleBarRectangle()
{
Rectangle rect = new Rectangle();
rect.X = 1 + SystemInformation.CaptionButtonSize.Width; // Avoid to draw over the icon
rect.Y = 1;
rect.Width = Width - (SystemInformation.CaptionButtonSize.Width * 4); // Avoid to draw over the buttons
rect.Height = SystemInformation.CaptionButtonSize.Height;
return rect;
}
// Draw a filled rectangle
private void ClearTitleBar(IntPtr hwnd)
{
// Obtenemos el Canvas a partir del DC de la ventana
IntPtr hdc = GetWindowDC(hwnd);
try
{
using (Graphics gBarra = Graphics.FromHdc(hdc))
{
Rectangle rect = TitleBarRectangle();
gBarra.FillRectangle(new SolidBrush(SystemColors.ActiveCaption), rect);
gBarra.Flush();
}
}
finally
{
ReleaseDC(hwnd, hdc);
}
}
并修改了一项:
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x0085: // WM_NCPAINT:
case 0x0005: // WM_SIZE
base.WndProc(ref m);
DrawTitleBar(m.HWnd);
break;
case 0x214: // WM_SIZING
base.WndProc(ref m);
ClearTitleBar(m.HWnd);
break;
default:
// Invocamos a la funcion original
base.WndProc(ref m);
break;
}
}
顺便说一下,整个想法是从Copstone http://copstone.com/2010/02/agregando-botones-a-la-barra-de-titulo-de-una-ventana/
谢谢拉尔斯、扎克,当然还有吉姆。您的评论和回答让我上路了。