C# 繪制窗體客戶非客戶區要用WM_PAINT和WM_NCPAINT


窗體分為兩部分:客戶區(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; 
  
} 
  
} 
  
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM