2011-11-29 117 views
0

我畫的標題欄的一部分,在我WinForm的應用。好的工作(將公司集中橙和名稱)繪製自己的標題欄

enter image description here

這是代碼做,在表單代碼:

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; 
    } 
    } 

的問題是調整窗口的大小。文本不會被清除並顯示多次。有沒有辦法在繪製文字之前「刷新」標題欄?

在此先感謝。

編輯 幾乎解決了。增加了兩個方法:

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

感謝拉斯,扎克當然,吉姆開始。你的意見和答案讓我走上了正軌。

+2

即使你解決了這個問題,我認爲它甚至不會畫在Vista或Win7上,因爲Aero UI。 – LarsTech

+0

@LarsTech。謝謝你的評論。我在XP中「仍然」。也許,當我遷移到W7時,會檢查操作系統版本並禁用此功能,或嘗試解決此問題。到現在爲止,我正在嘗試一切,但沒有任何工作沒有成功。 :( – Nane

+2

我推薦使用或獲得來自系統顏色中的一種顏色,而不是使用硬編碼的顏色喜歡橙色的,系統和主題顏色可以改變從操作系統OS,並從用戶到用戶,因此,使用硬編碼一個顏色很有可能使你的程序感覺出在用不同的顏色比一個系統的地方,你開發它。 –

回答

2

一個簡單的解決方法是調用gBarra.FillRectangle填寫標題欄的背景顏色,你畫的字符串之前。

你確定你需要做的這WM_PAINT?看起來像WM_NCPAINT就足夠了。

我強烈建議您使用try...finally,以確保DC得到釋放。那就是:

private void DrawTitleBar(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 = 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(); 
     } 
    } 
    finally 
    { 
     ReleaseDC(hwnd, hdc); 
    } 
} 
+0

謝謝您的回答:U [R完全正確的。我必須使用嘗試...最後,只是WM_NCPAINT,我看到的問題與背景色填充矩形是,我不知道顏色。也有趕上WM_RESIZING(我認爲)這樣做。嗯,我會嘗試,讓你知道。再次感謝 – Nane

+2

@Nane systemColors中。 ActiveCaption和SystemColors.InactiveCaption是顏色,我認爲你正在尋找。 – LarsTech

+1

順便說一句,你的示例代碼泄漏所創建的字體資源。 – ahazzah