標籤:class blog tar ext color get
表單分為兩部分:客戶區(Client area)和非客戶區(Non-Client area)
WM_PAINT訊息、OnPaint()方法、GetDC()API函數都是處理表單客戶區繪製的
而標題列處於非客戶區中,所以WM_PAINT訊息、OnPaint()方法、GetDC()API函數都用不上
GetWindowDC()是獲得整個表單的畫布控制代碼(Device Context翻譯為:裝置清單,我習慣稱為畫布控制代碼),包括非客戶區
GDI的繪製都離不開DC,因為作業系統必須知道你要在什麼地方繪製圖形
當其他表單遮擋或者移開,系統都會重新繪製表單。這時就會發出WM_PAINT和WM_NCPAINT訊息通知表單重繪介面。
收到WM_NCPAINT訊息(非客戶區繪製訊息)說明非客戶區正需要重新繪製
重載WndProc()方法(表單訊息處理過程),處理WM_NCPAINT等訊息即可....
“基本的步驟” 就是:截獲WM_NCPAINT訊息、得到表單完整畫布控制代碼、在完整畫布上繪製圖形。
WM_NCPAINT WM_NCCALCSIZE WM_NCACTIVATE WM_NCHITTEST
建議樓主搜尋關鍵詞:“C# WM_NCPAINT WndProc Graphics”得到更多的參考資料
貼
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[DllImport ( "User32.dll ")] private static extern IntPtr GetWindowDC(IntPtr hwnd); [DllImport ( "User32.dll ")] private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc); [DllImport ( "Kernel32.dll ")] private static extern int GetLastError(); //標題列按鈕的矩形地區。 Rectangle m_rect = new Rectangle(205, 6, 20, 20); protected override void WndProc(ref Message m) { base.WndProc(ref m); switch(m.Msg) { case 0x86://WM_NCACTIVATE goto case 0x85; case 0x85://WM_NCPAINT { IntPtr hDC = GetWindowDC(m.HWnd); //把DC轉換為.NET的Graphics就可以很方便地使用Framework提供的繪圖功能了 Graphics gs = Graphics.FromHdc(hDC); gs.FillRectangle(new LinearGradientBrush(m_rect, Color.Pink, Color.Purple, LinearGradientMode.BackwardDiagonal), m_rect); StringFormat strFmt = new StringFormat(); strFmt.Alignment = StringAlignment.Center; strFmt.LineAlignment = StringAlignment.Center; gs.DrawString( "√ ", this.Font, Brushes.BlanchedAlmond, m_rect, strFmt); gs.Dispose(); //釋放GDI資源 ReleaseDC(m.HWnd, hDC); break; } case 0xA1://WM_NCLBUTTONDOWN { Point mousePoint = new Point((int)m.LParam); mousePoint.Offset(-this.Left, -this.Top); if(m_rect.Contains(mousePoint)) { MessageBox.Show( "hello "); } break; } } } //在視窗大小改變時及時更新按鈕的地區。 private void Form1_SizeChanged(object sender, System.EventArgs e) { m_rect.X = this.Bounds.Width - 95; m_rect.Y = 6; m_rect.Width = m_rect.Height = 20; } } }