




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、C#重繪windows窗體標題欄和邊框摘要windows桌面應用程序都有標準的標題欄和邊框,大部分程序也默認使用這些樣式,一些對視覺效果要求較高的程序,如QQ, MSN,迅雷等聊天工具的樣式則與傳統的windows程序大不相同,其中迅雷還將他們的BOLT界面引擎開放,使得大家也可以創建類似迅雷一樣的界面。 那么這些軟件的界面是怎樣實現的呢,使用C#是否也可以實現類似界面?重繪方式常見的自定義標題欄和邊框的方式有兩種,一種是隱藏標題欄和邊框(稱為非客戶區),然后在客戶區(可以放置控件的空間)使用一些常用的控件和圖片來表示邊 框,這種方式較簡單而麻煩,但如標題欄的拖動,邊框的拖拽來改變窗體大小等效
2、果,則有需要重新實現,另外有些客戶區的鼠標事件,控件布局等也需要注意調 整;另一種則是大部分軟件實現方式,也較難一些;它利用windows的消息機制,截獲windows消息,從而改變消息的行為。即windows的一些 消息,會引起窗體繪制或重繪標題欄和邊框的行為,因此只要結果這部分消息,然后開發人員自己處理繪制過程,并忽略默認行為,從而達到自定義的目的。C#繪制接口windows消息對于C#開發新手來說較生疏,原因是.net已經將windows消息機制進行了封裝,使得我們很難發現windows消息的蹤跡,其 實它是以另一個身份存在著-事件。如控件的OnClick,Mouse等事件,都是對win
3、dows消息的封裝,這樣的目的更容易理解,和運 用。.net提供了處理消息的接口,常用的方法為Control控件的void WndProc(ref Message m)方法,該方法用于接收任何發送到該控件的windows消息。那么我們就可以通過重寫該方法來截獲繪制窗體標題欄和邊框的消息了。找到了截獲windows消息的接口,那么就需要知道哪些windows消息會引起窗體標題欄和邊框的重繪。使用工具SPY+查看消息,發現 windows消息WM_NCPAINT(0x85)和 WM_NCACTIVATE(0x86),WM_NCRBUTTONDOWN(0x00A4),WM_SETCURSOR(0x0
4、020),WM_NCLBUTTONUP(0x00A2),WM_NCLBUTTONDOWN(0xA1) 等會重繪標題欄和邊框。其中WM_NCPAINT和WM_NCACTIVATE會引起重繪標題欄和邊框,消息WM_NCRBUTTONDOWN會觸發標題 欄的右鍵菜單,截獲該消息可以自定義標題欄的右鍵菜單;其他消息會引起ConrtolBox(最小化,最大化,關閉按鈕區域)的重繪。因此我們可以從截獲 這些消息入手。如下為WndProc方法的結構:using System;using System.Collections.Generic;using System.Windows.Forms;using S
5、ystem.ComponentModel;using System.Drawing;using System.Drawing.Drawing2D;using System.Runtime.InteropServices;using System.Diagnostics;namespace CaptionBox public class ThemeForm : Form #region private structs struct _NonClientSizeInfo public Size CaptionButtonSize; public Size BorderSize; public in
6、t CaptionHeight; public Rectangle CaptionRect; public Rectangle Rect; public Rectangle ClientRect; public int Width; public int Height; ; #endregion #region constants const int WM_NCACTIVATE = 0x86; const int WM_NCPAINT = 0x85; const int WM_NCLBUTTONDOWN = 0xA1; const int WM_NCRBUTTONDOWN = 0x00A4;
7、const int WM_NCRBUTTONUP = 0x00A5; const int WM_NCMOUSEMOVE = 0x00A0; const int WM_NCLBUTTONUP = 0x00A2; const int WM_NCCALCSIZE = 0x0083; const int WM_NCMOUSEHOVER = 0x02A0; const int WM_NCMOUSELEAVE = 0x02A2; const int WM_NCHITTEST = 0x0084; const int WM_NCCREATE = 0x0081; /const int WM_RBUTTONUP
8、= 0x0205; const int WM_LBUTTONDOWN = 0x0201; const int WM_CAPTURECHANGED = 0x0215; const int WM_LBUTTONUP = 0x0202; const int WM_SETCURSOR = 0x0020; const int WM_CLOSE = 0x0010; const int WM_SYSCOMMAND = 0x0112; const int WM_MOUSEMOVE = 0x0200; const int WM_SIZE = 0x0005; const int WM_SIZING = 0x021
9、4; const int WM_GETMINMAXINFO = 0x0024; const int WM_ENTERSIZEMOVE = 0x0231; const int WM_WINDOWPOSCHANGING = 0x0046; / FOR WM_SIZING MSG WPARAM const int WMSZ_BOTTOM = 6; const int WMSZ_BOTTOMLEFT = 7; const int WMSZ_BOTTOMRIGHT = 8; const int WMSZ_LEFT = 1; const int WMSZ_RIGHT = 2; const int WMSZ
10、_TOP = 3; const int WMSZ_TOPLEFT = 4; const int WMSZ_TOPRIGHT = 5; / left mouse button is down. const int MK_LBUTTON = 0x0001; const int SC_CLOSE = 0xF060; const int SC_MAXIMIZE = 0xF030; const int SC_MINIMIZE = 0xF020; const int SC_RESTORE = 0xF120; const int SC_CONTEXTHELP = 0xF180; const int HTCA
11、PTION = 2; const int HTCLOSE = 20; const int HTHELP = 21; const int HTMAXBUTTON = 9; const int HTMINBUTTON = 8; const int HTTOP = 12; const int SM_CYBORDER = 6; const int SM_CXBORDER = 5; const int SM_CYCAPTION = 4; const int CS_DropSHADOW = 0x20000; const int GCL_STYLE = (-26); #endregion #region w
12、indows api DllImport("User32.dll") private static extern IntPtr GetWindowDC(IntPtr hwnd); DllImport("User32.dll") return: MarshalAs(UnmanagedType.Bool) private static extern bool GetWindowRect(IntPtr hwnd, ref _RECT rect); DllImport("User32.dll") private static extern i
13、nt ReleaseDC(IntPtr hwnd, IntPtr hdc); DllImport("user32.dll", CharSet = CharSet.Auto) public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong); DllImport("user32.dll", CharSet = CharSet.Auto) public static extern int GetClassLong(IntPtr hwnd, int nIndex); #e
14、ndregion #region default constructor public ThemeForm() Text = "ThemeForm1" CloseButtonImage = Properties.Resources.close.ToBitmap(); CloseButtonHoverImage = Properties.Resources.close2.ToBitmap(); CloseButtonPressDownImage = Properties.Resources.close2.ToBitmap(); MaximumButtonImage = Pro
15、perties.Resources.max.ToBitmap(); MaximumButtonHoverImage = Properties.Resources.max2.ToBitmap(); MaximumButtonPressDownImage = Properties.Resources.max2.ToBitmap(); MaximumNormalButtonImage = Properties.Resources.maxnorm.ToBitmap(); MaximumNormalButtonHoverImage = Properties.Resources.maxnorm2.ToBi
16、tmap(); MaximumNormalButtonPressDownImage = Properties.Resources.maxnorm2.ToBitmap(); MinimumButtonImage = Properties.Resources.min.ToBitmap(); MinimumButtonHoverImage = Properties.Resources.min2.ToBitmap(); MinimumButtonPressDownImage = Properties.Resources.min2.ToBitmap(); HelpButtonImage = Proper
17、ties.Resources.help.ToBitmap(); HelpButtonHoverImage = Properties.Resources.help2.ToBitmap(); HelpButtonPressDownImage = Properties.Resources.help2.ToBitmap(); CaptionColor = Brushes.White; CaptionBackgroundColor = Color.DimGray; SetClassLong(this.Handle, GCL_STYLE, GetClassLong(this.Handle, GCL_STY
18、LE) | CS_DropSHADOW); /API函數加載,實現窗體邊框陰影效果 #endregion DefaultValue("") Browsable(true) Category("ControlBox") public virtual ContextMenuStrip CaptionContextMenu get; set; protected virtual void OnCaptionContextMenu(int x, int y) if (this.CaptionContextMenu != null) this.CaptionCon
19、textMenu.Show(x, y); #region properties Category("ControlBox") Description("Close button image in control box.") DisplayName("CloseButtonImage") DesignOnly(true) public Image CloseButtonImage get; set; Category("ControlBox") Description("Close button imag
20、e pressed down in control box.") DisplayName("CloseButtonPressDownImage") DesignOnly(true) public Image CloseButtonPressDownImage get; set; Category("ControlBox") Description("Close button image hover in control box.") DisplayName("CloseButtonHoverImage")
21、 DesignOnly(true) public Image CloseButtonHoverImage get; set; Category("ControlBox") Description("Maximum button image in control box.") DisplayName("MaximumButtonImage") DesignOnly(true) public Image MaximumButtonImage get; set; Category("ControlBox") Descri
22、ption("Maximum button hover image in control box.") DisplayName("MaximumButtonHoverImage") DesignOnly(true) public Image MaximumButtonHoverImage get; set; Category("ControlBox") Description("Maximum button pressed down image in control box.") DisplayName("
23、;MaximumButtonPressDownImage") DesignOnly(true) public Image MaximumButtonPressDownImage get; set; Category("ControlBox") Description("Maximum Normal button image in control box.") DisplayName("MaximumNormalButtonImage") DesignOnly(true) public Image MaximumNormalB
24、uttonImage get; set; Category("ControlBox") Description("Maximum Normal button hover image in control box.") DisplayName("MaximumNormalButtonHoverImage") DesignOnly(true) public Image MaximumNormalButtonHoverImage get; set; Category("ControlBox") Description(&
25、quot;Maximum Normal button pressed down image in control box.") DisplayName("MaximumNormalButtonPressDownImage") DesignOnly(true) public Image MaximumNormalButtonPressDownImage get; set; Category("ControlBox") Description("Minimum button image in control box.") Dis
26、playName("MinimumButtonImage") DesignOnly(true) public Image MinimumButtonImage get; set; Category("ControlBox") Description("Minimum button hover image in control box.") DisplayName("MinimumButtonHoverImage") DesignOnly(true) public Image MinimumButtonHoverIm
27、age get; set; Category("ControlBox") Description("Minimum button pressed down image in control box.") DisplayName("MinimumButtonPressDownImage") DesignOnly(true) public Image MinimumButtonPressDownImage get; set; Category("ControlBox") Description("Help b
28、utton image in control box.") DisplayName("HelpButtonImage") DesignOnly(true) public Image HelpButtonImage get; set; Category("ControlBox") Description("Help button hover image in control box.") DisplayName("HelpButtonHoverImage") DesignOnly(true) public
29、Image HelpButtonHoverImage get; set; Category("ControlBox") Description("Help button pressed down image in control box.") DisplayName("HelpButtonPressDownImage") DesignOnly(true) public Image HelpButtonPressDownImage get; set; Category("CaptionColor") Descript
30、ion("The color of caption.") DisplayName("CaptionColor") DesignOnly(true) public Brush CaptionColor get; set; Category("CaptionColor") Description("The color of caption.") DisplayName("CaptionBackgroundColor") DefaultValue(typeof(Color), "Black&
31、quot;) DesignOnly(true) public Color CaptionBackgroundColor get; set; #endregion #region help methods private _NonClientSizeInfo GetNonClientInfo(IntPtr hwnd) _NonClientSizeInfo info = new _NonClientSizeInfo(); info.CaptionButtonSize = SystemInformation.CaptionButtonSize; info.CaptionHeight = System
32、Information.CaptionHeight; switch (this.FormBorderStyle) case System.Windows.Forms.FormBorderStyle.Fixed3D: info.BorderSize = SystemInformation.FixedFrameBorderSize; break; case System.Windows.Forms.FormBorderStyle.FixedDialog: info.BorderSize = SystemInformation.FixedFrameBorderSize; break; case Sy
33、stem.Windows.Forms.FormBorderStyle.FixedSingle: info.BorderSize = SystemInformation.FixedFrameBorderSize; break; case System.Windows.Forms.FormBorderStyle.FixedToolWindow: info.BorderSize = SystemInformation.FixedFrameBorderSize; info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize
34、; info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight; break; case System.Windows.Forms.FormBorderStyle.Sizable: info.BorderSize = SystemInformation.FrameBorderSize; break; case System.Windows.Forms.FormBorderStyle.SizableToolWindow: info.CaptionButtonSize = SystemInformation.ToolWindowCa
35、ptionButtonSize; info.BorderSize = SystemInformation.FrameBorderSize; info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight; break; default: info.BorderSize = SystemInformation.BorderSize; break; _RECT areatRect = new _RECT(); GetWindowRect(hwnd, ref areatRect); int width = areatRect.right
36、- areatRect.left; int height = areatRect.bottom - areatRect.top; info.Width = width; info.Height = height; Point xy = new Point(areatRect.left, areatRect.top); xy.Offset(-areatRect.left, -areatRect.top); info.CaptionRect = new Rectangle(xy.X, xy.Y + info.BorderSize.Height, width, info.CaptionHeight)
37、; info.Rect = new Rectangle(xy.X, xy.Y, width, height); info.ClientRect = new Rectangle(xy.X + info.BorderSize.Width, xy.Y + info.CaptionHeight + info.BorderSize.Height, width - info.BorderSize.Width * 2, height - info.CaptionHeight - info.BorderSize.Height * 2); return info; private void DrawTitle(
38、Graphics g, _NonClientSizeInfo ncInfo, bool active) int titleX; if (this.ShowIcon && this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow && this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) Size iconSize = SystemInformation.Small
39、IconSize; g.DrawIcon(this.Icon, new Rectangle(new Point(ncInfo.BorderSize.Width, ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - iconSize.Height) / 2), iconSize); titleX = ncInfo.BorderSize.Width + iconSize.Width + ncInfo.BorderSize.Width; else titleX = ncInfo.BorderSize.Width; SizeF captionTitle
40、Size = g.MeasureString(this.Text, SystemFonts.CaptionFont); g.DrawString(this.Text, SystemFonts.CaptionFont, CaptionColor, new RectangleF(titleX, (ncInfo.BorderSize.Height + ncInfo.CaptionHeight - captionTitleSize.Height) / 2, ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width * 2 - SystemInformatio
41、n.MinimumWindowSize.Width, ncInfo.CaptionRect.Height), StringFormat.GenericTypographic); private void DrawBorder(Graphics g, _NonClientSizeInfo ncInfo, Brush background, bool active) Rectangle borderTop = new Rectangle(ncInfo.Rect.Left, ncInfo.Rect.Top, ncInfo.Rect.Left + ncInfo.Rect.Width, ncInfo.R
42、ect.Top + ncInfo.BorderSize.Height); Rectangle borderLeft = new Rectangle( new Point(ncInfo.Rect.Location.X, ncInfo.Rect.Location.Y + ncInfo.BorderSize.Height), new Size(ncInfo.BorderSize.Width, ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height); Rectangle borderRight = new
43、Rectangle(ncInfo.Rect.Left + ncInfo.Rect.Width - ncInfo.BorderSize.Width, ncInfo.Rect.Top + ncInfo.BorderSize.Height, ncInfo.BorderSize.Width, ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height); Rectangle borderBottom = new Rectangle(ncInfo.Rect.Left + ncInfo.BorderSize.Widt
44、h, ncInfo.Rect.Top + ncInfo.Rect.Height - ncInfo.BorderSize.Height, ncInfo.Rect.Width - ncInfo.BorderSize.Width * 2, ncInfo.Rect.Height); /Rectangle leftbottom = new Rectangle(new Point(ncInfo.Rect.Location.X, ncInfo.Rect.Height - ncInfo.BorderSize.Width * 2), / new Size(ncInfo.BorderSize.Width * 2,
45、 ncInfo.BorderSize.Width * 2); /g.FillPie(Brushes.Red, leftbottom, 90, 180); /g.FillRectangle(Brushes.Red, leftbottom); / top border g.FillRectangle(background, borderTop); / left border g.FillRectangle(background, borderLeft); / right border g.FillRectangle(background, borderRight); / bottom border
46、 g.FillRectangle(background, borderBottom); private void DrawCaption(IntPtr hwnd, bool active) IntPtr dc; Graphics g; Size iconSize; _NonClientSizeInfo ncInfo; Brush backgroundColor = new SolidBrush(CaptionBackgroundColor); Brush foregroundColor = CaptionColor; iconSize = SystemInformation.SmallIcon
47、Size; dc = GetWindowDC(hwnd); ncInfo = GetNonClientInfo(hwnd); g = Graphics.FromHdc(dc); g.FillRectangle(backgroundColor, ncInfo.CaptionRect); DrawBorder(g, ncInfo, backgroundColor, active); DrawTitle(g, ncInfo, active); DrawControlBox(g, ncInfo, backgroundColor, this.ControlBox, this.MaximizeBox, this.MinimizeBox, this.HelpButton); g.Dispose(); ReleaseDC(hwnd, dc); private void DrawControlBox(Graphics g, _NonClientSizeInfo info, Brush background, bool closeBtn, bool maxBtn, bool minBtn, bool helpBtn) if (this.ControlBox)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 餐飲場地臨時使用及環保責任承諾書
- 商業地產開發場地調研與風險評估合同協議
- 醫療服務市場調研合作合同
- 稅務籌劃與稅務審計常年服務協議
- 油氣管道安全保衛服務承包合同
- 高精度加工及現代化廠房租賃服務合同
- 日本短期留學與文化體驗合同
- 公寓租賃安全責任與物業管理服務協議
- 車位產權交易及車位使用權轉讓合同樣本
- 公共安全測繪儀器采購及應急響應合同
- 四年級信息技術測試卷附答案
- 侵入性操作相關感染防控
- 云計算平臺搭建與運維考核試卷
- 江蘇省鎮江市近五年中考作文題目及2024年中考作文指導及例文
- 五年級下學期科學立體小菜園課件
- 2019級藥劑專業人才培養方案(中職)
- 2024年河北石家莊市市屬國企業春季面向社會公開招聘282人易考易錯模擬試題(共500題)試卷后附參考答案
- 旅游集散中心建設設計方案
- 國家開放大學專科《人文英語1》一平臺機考真題及答案(第二套)
- 承德市承德縣六年級下冊數學期末測試卷匯編
- 北京朝陽區2024年八年級物理第二學期期末綜合測試試題及答案解析
評論
0/150
提交評論