版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本文格式为Word版,下载可任意编辑——C重绘windows窗体标题栏和边框C#重绘windows窗体标题栏和边框
摘要
windows桌面应用程序都有标准的标题栏和边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如,MSN,迅雷等闲聊工具的样式则与传统的windows程序大不一致,其中迅雷还将他们的BOLT界面引擎开放,使得大家也可以创立类似迅雷一样的界面。那么这些软件的界面是怎样实现的呢,使用C#是否也可以实现类似界面?
重绘方式
常见的自定义标题栏和边框的方式有两种,一种是隐蔽标题栏和边框(称为非客户区),然后在客户区(可以放置控件的空间)使用一些常用的控件和图片来表示边框,这种方式较简单而麻烦,但如标题栏的拖动,边框的拖拽来改变窗体大小等效果,则有需要重新实现,另外有些客户区的鼠标事件,控件布局等也需要注意调整;另一种则是大部分软件实现方式,也较难一些;它利用windows的消息机制,截获windows消息,从而改变消息的行为。即windows的一些消息,会引起窗体绘制或重绘标题栏和边框的行为,因此只要结果这部分消息,然后开发人员自己处理绘制过程,并忽略默认行为,从而达到自定义的目的。C#绘制接口
windows消息对于C#开发新手来说较生疏,原因是.net已经将windows消息机制进行了封装,使得我们很难发现windows消息的踪迹,其实它是以另一个身份存在着--事件。如控件的OnClick,Mouse等事件,都是对windows消息的封装,这样的目的更简单理解,和运用。.net提供了处理消息的接口,常用的方法为Control控件的voidWndProc(refMessagem)方法,该方法用于接收任何发送到该控件的windows消息。那么我们就可以通过重写该方法来截获绘制窗体标题栏和边框的消息了。
找到了截获windows消息的接口,那么就需要知道哪些windows消息会引起窗体标题栏和边框的重绘。使用工具SPY++查看消息,发现windows消息WM_NCPAINT(0x85)和WM_NCACTIVATE(0x86),WM_NCRBUTTONDOWN(0x00A4),WM_SETCURSOR(0x0020),WM_NCLBUTTONUP(0x00A2),WM_NCLBUTTONDOWN(0xA1)等会重绘标题栏和边框。其中WM_NCPAINT和WM_NCACTIVATE会引起重绘标题栏和边框,消息WM_NCRBUTTONDOWN会触发标题栏的右键菜单,截获该消息可以自定义标题栏的右键菜单;其他消息会引起ConrtolBox(最小化,最大化,关闭按钮区域)的重绘。因此我们可以从截获这些消息入手。如下为WndProc方法的结构:usingSystem;
usingSystem.Collections.Generic;usingSystem.Windows.Forms;
usingSystem.ComponentModel;usingSystem.Drawing;
usingSystem.Drawing.Drawing2D;
usingSystem.Runtime.InteropServices;usingSystem.Diagnostics;
namespaceCaptionBox{
publicclassThemeForm:Form{#regionprivatestructs
struct_NonClientSizeInfo{
publicSizeCaptionButtonSize;publicSizeBorderSize;publicintCaptionHeight;publicRectangleCaptionRect;publicRectangleRect;
publicRectangleClientRect;publicintWidth;publicintHeight;};
#endregion#regionconstants
constintWM_NCACTIVATE=0x86;constintWM_NCPAINT=0x85;
constintWM_NCLBUTTONDOWN=0xA1;constintWM_NCRBUTTONDOWN=0x00A4;constintWM_NCRBUTTONUP=0x00A5;constintWM_NCMOUSEMOVE=0x00A0;constintWM_NCLBUTTONUP=0x00A2;constintWM_NCCALCSIZE=0x0083;constintWM_NCMOUSEHOVER=0x02A0;constintWM_NCMOUSELEAVE=0x02A2;constintWM_NCHITTEST=0x0084;constintWM_NCCREATE=0x0081;//constintWM_RBUTTONUP=0x0205;constintWM_LBUTTONDOWN=0x0201;constintWM_CAPTURECHANGED=0x0215;constintWM_LBUTTONUP=0x0202;constintWM_SETCURSOR=0x0020;constintWM_CLOSE=0x0010;
constintWM_SYSCOMMAND=0x0112;
constintWM_MOUSEMOVE=0x0200;constintWM_SIZE=0x0005;constintWM_SIZING=0x0214;
constintWM_GETMINMAXINFO=0x0024;constintWM_ENTERSIZEMOVE=0x0231;
constintWM_WINDOWPOSCHANGING=0x0046;
//FORWM_SIZINGMSGWPARAMconstintWMSZ_BOTTOM=6;constintWMSZ_BOTTOMLEFT=7;constintWMSZ_BOTTOMRIGHT=8;constintWMSZ_LEFT=1;constintWMSZ_RIGHT=2;constintWMSZ_TOP=3;constintWMSZ_TOPLEFT=4;constintWMSZ_TOPRIGHT=5;//leftmousebuttonisdown.constintMK_LBUTTON=0x0001;constintSC_CLOSE=0xF060;constintSC_MAXIMIZE=0xF030;constintSC_MINIMIZE=0xF020;constintSC_RESTORE=0xF120;constintSC_CONTEXTHELP=0xF180;constintHTCAPTION=2;constintHTCLOSE=20;constintHTHELP=21;constintHTMAXBUTTON=9;constintHTMINBUTTON=8;constintHTTOP=12;constintSM_CYBORDER=6;constintSM_CXBORDER=5;constintSM_CYCAPTION=4;constintCS_DropSHADOW=0x20000;constintGCL_STYLE=(-26);#endregion
#regionwindowsapi
[DllImport(\
privatestaticexternIntPtrGetWindowDC(IntPtrhwnd);[DllImport(\
[return:MarshalAs(UnmanagedType.Bool)]
privatestaticexternboolGetWindowRect(IntPtrhwnd,ref_RECTrect);
[DllImport(\
privatestaticexternintReleaseDC(IntPtrhwnd,IntPtrhdc);[DllImport(\
publicstaticexternintSetClassLong(IntPtrhwnd,intnIndex,intdwNewLong);
[DllImport(\
publicstaticexternintGetClassLong(IntPtrhwnd,intnIndex);#endregion
#regiondefaultconstructor
publicThemeForm(){
Text=\
CloseButtonImage=Properties.Resources.close.ToBitmap();CloseButtonHoverImage=Properties.Resources.close2.ToBitmap();CloseButtonPressDownImage=Properties.Resources.close2.ToBitmap();
MaximumButtonImage=Properties.Resources.max.ToBitmap();MaximumButtonHoverImage=Properties.Resources.max2.ToBitmap();MaximumButtonPressDownImage=Properties.Resources.max2.ToBitmap();MaximumNormalButtonImage
Properties.Resources.maxnorm.ToBitmap();MaximumNormalButtonHoverImageProperties.Resources.maxnorm2.ToBitmap();MaximumNormalButtonPressDownImageProperties.Resources.maxnorm2.ToBitmap();
===
MinimumButtonImage=Properties.Resources.min.ToBitmap();MinimumButtonHoverImage=Properties.Resources.min2.ToBitmap();MinimumButtonPressDownImage=Properties.Resources.min2.ToBitmap();
HelpButtonImage=Properties.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_STYLE)|CS_DropSHADOW);//API函数加载,实现窗体边框阴影效果}
#endregion
[DefaultValue(\[Browsable(true)]
[Category(\publicvirtualContextMenuStripCaptionContextMenu{get;set;}protectedvirtualvoidOnCaptionContextMenu(intx,inty){if(this.CaptionContextMenu!=null)this.CaptionContextMenu.Show(x,y);}
#regionproperties
[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageCloseButtonImage{get;set;}
[Category(\[Description(\buttonimagepresseddownincontrolbox.\[DisplayName(\[DesignOnly(true)]
publicImageCloseButtonPressDownImage{get;set;}[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageCloseButtonHoverImage{get;set;}
[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageMaximumButtonImage{get;set;}
[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageMaximumButtonHoverImage{get;set;}
[Category(\
[Description(\buttonpresseddownimageincontrolbox.\
[DisplayName(\[DesignOnly(true)]
publicImageMaximumButtonPressDownImage{get;set;}[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageMaximumNormalButtonImage{get;set;}
[Category(\
[Description(\Normalbuttonhoverimageincontrolbox.\
[DisplayName(\[DesignOnly(true)]
publicImageMaximumNormalButtonHoverImage{get;set;}[Category(\
[Description(\Normalbuttonpresseddownimageincontrolbox.\
[DisplayName(\[DesignOnly(true)]
publicImageMaximumNormalButtonPressDownImage{get;set;}[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageMinimumButtonImage{get;set;}
[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageMinimumButtonHoverImage{get;set;}
[Category(\
[Description(\buttonpresseddownimageincontrolbox.\
[DisplayName(\[DesignOnly(true)]
publicImageMinimumButtonPressDownImage{get;set;}[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageHelpButtonImage{get;set;}
[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicImageHelpButtonHoverImage{get;set;}
[Category(\
[Description(\buttonpresseddownimageincontrolbox.\[DisplayName(\[DesignOnly(true)]
publicImageHelpButtonPressDownImage{get;set;}[Category(\
[Description(\[DisplayName(\[DesignOnly(true)]
publicBrushCaptionColor{get;set;}
[Category(\
[Description(\[DisplayName(\[DefaultValue(typeof(Color),\[DesignOnly(true)]
publicColorCaptionBackgroundColor{get;set;}#endregion
#regionhelpmethods
private_NonClientSizeInfoGetNonClientInfo(IntPtrhwnd){_NonClientSizeInfoinfo=new_NonClientSizeInfo();info.CaptionButtonSize=SystemInformation.CaptionButtonSize;
info.CaptionHeight=SystemInformation.CaptionHeight;switch(this.FormBorderStyle){caseSystem.Windows.Forms.FormBorderStyle.Fixed3D:info.BorderSize=SystemInformation.FixedFrameBorderSize;break;caseSystem.Windows.Forms.FormBorderStyle.FixedDialog:info.BorderSize=SystemInformation.FixedFrameBorderSize;break;caseSystem.Windows.Forms.FormBorderStyle.FixedSingle:info.BorderSize=SystemInformation.FixedFrameBorderSize;break;case
System.Windows.Forms.FormBorderStyle.FixedToolWindow:info.BorderSize=SystemInformation.FixedFrameBorderSize;info.CaptionButtonSize=SystemInformation.ToolWindowCaptionButtonSize;info.CaptionHeight=SystemInformation.ToolWindowCaptionHeight;break;caseSystem.Windows.Forms.FormBorderStyle.Sizable:info.BorderSize=SystemInformation.FrameBorderSize;break;case
System.Windows.Forms.FormBorderStyle.SizableToolWindow:info.CaptionButtonSize=SystemInformation.ToolWindowCaptionButtonSize;info.BorderSize=SystemInformation.FrameBorderSize;info.CaptionHeight=SystemInformation.ToolWindowCaptionHeight;break;default:info.BorderSize=SystemInformation.BorderSize;break;}
_RECTareatRect=new_RECT();
GetWindowRect(hwnd,refareatRect);
intwidth=areatRect.right-areatRect.left;intheight=areatRect.bottom-areatRect.top;info.Width=width;info.Height=height;
Pointxy=newPoint(areatRect.left,areatRect.top);xy.Offset(-areatRect.left,-areatRect.top);
info.CaptionRect=newRectangle(xy.X,xy.Y+info.BorderSize.Height,width,info.CaptionHeight);
info.Rect=newRectangle(xy.X,xy.Y,width,height);info.ClientRect=newRectangle(xy.X+info.BorderSize.Width,xy.Y+info.CaptionHeight+info.BorderSize.Height,width-info.BorderSize.Width*2,height-info.CaptionHeight-info.BorderSize.Height*2);
returninfo;}
privatevoidDrawTitle(Graphicsg,_NonClientSizeInfoncInfo,boolactive){
inttitleX;
if(this.ShowIcong.DrawIcon(this.Icon,newRectangle(newPoint(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;}
SizeFcaptionTitleSize=g.MeasureString(this.Text,SystemFonts.CaptionFont);
g.DrawString(this.Text,SystemFonts.CaptionFont,CaptionColor,newRectangleF(titleX,
(ncInfo.BorderSize.Height+ncInfo.CaptionHeight-captionTitleSize.Height)/2,ncInfo.CaptionRect.Width-ncInfo.BorderSize.Width*2-SystemInformation.MinimumWindowSize.Width,ncInfo.CaptionRect.Height),StringFormat.GenericTypographic);}
privatevoidDrawBorder(Graphicsg,_NonClientSizeInfoncInfo,Brushbackground,boolactive){
RectangleborderTop=newRectangle(ncInfo.Rect.Left,ncInfo.Rect.Top,ncInfo.Rect.Left+ncInfo.Rect.Width,ncInfo.Rect.Top+ncInfo.BorderSize.Height);RectangleborderLeft=newRectangle(newPoint(ncInfo.Rect.Location.X,ncInfo.Rect.Location.Y+ncInfo.BorderSize.Height),newSize(ncInfo.BorderSize.Width,ncInfo.ClientRect.Height+ncInfo.CaptionHeight+ncInfo.BorderSize.Height));
RectangleborderRight=newRectangle(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);
RectangleborderBottom=newRectangle(ncInfo.Rect.Left+ncInfo.BorderSize.Width,ncInfo.Rect.Top+ncInfo.Rect.Height-ncInfo.BorderSize.Height,ncInfo.Rect.Width-ncInfo.BorderSize.Width*2,ncInfo.Rect.Height);
//Rectangleleftbottom=newRectangle(newPoint(ncInfo.Rect.Location.X,ncInfo.Rect.Height-ncInfo.BorderSize.Width*2),
//newSize(ncInfo.BorderSize.Width*2,
ncInfo.BorderSize.Width*2));
//g.FillPie(Brushes.Red,leftbottom,90,180);//g.FillRectangle(Brushes.Red,leftbottom);//topborder
g.FillRectangle(background,borderTop);//leftborder
g.FillRectangle(background,borderLeft);//rightborder
g.FillRectangle(background,borderRight);//bottomborder
g.FillRectangle(background,borderBottom);}
privatevoidDrawCaption(IntPtrhwnd,boolactive){IntPtrdc;Graphicsg;SizeiconSize;
_NonClientSizeInfoncInfo;BrushbackgroundColor=SolidBrush(CaptionBackgroundColor);
BrushforegroundColor=CaptionColor;iconSize=SystemInformation.SmallIconSize;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);}
privatevoidDrawControlBox(Graphicsg,_NonClientSizeInfoinfo,Brushbackground,boolcloseBtn,boolmaxBtn,boolminBtn,boolhelpBtn){
if(this.ControlBox){intcloseBtnPosX=info.CaptionRect.Left+
new
info.CaptionRect.Width-info.BorderSize.Widthinfo.CaptionButtonSize.Width;intmaxBtnPosX=closeBtnPosXinfo.CaptionButtonSize.Width;intminBtnPosX=maxBtnPosXinfo.CaptionButtonSize.Width;intbtnPosY=info.BorderSize.Height(info.CaptionHeight-info.CaptionButtonSize.Height)/2;
---+RectanglebtnRect=newRectangle(newPoint(closeBtnPosX,btnPosY),info.CaptionButtonSize);RectanglemaxRect=newRectangle(newPoint(maxBtnPosX,btnPosY),info.CaptionButtonSize);RectangleminRect=newRectangle(newPoint(minBtnPosX,btnPosY),info.CaptionButtonSize);BrushbackgroundColorSolidBrush(CaptionBackgroundColor);
=
newg.FillRectangle(backgroundColor,btnRect);g.FillRectangle(backgroundColor,maxRect);g.FillRectangle(backgroundColor,minRect);g.DrawImage(CloseButtonImage,btnRect);if(this.MaximizeBox||this.MinimizeBox){if(this.FormBorderStyle!=System.Windows.Forms.FormBorderStyle.FixedToolWindow
}else{
g.DrawImage(MaximumButtonImage,maxRect);}
g.DrawImage(MinimumButtonImage,minRect);}}elseif(this.HelpButton){if(this.FormBorderStyle!=System.Windows.Forms.FormBorderStyle.FixedToolWindow}}}}
#endregion
#regionMajormethodWndProc
privateintLOBYTE(longp){return(int)(p}privateintHIBYTE(longp){return(int)(p>>16);}
protectedoverridevoidWndProc(refMessagem){if(this.FormBorderStyle!=System.Windows.Forms.FormBorderStyle.None){switch(m.Msg){caseWM_NCPAINT:
DrawCaption(m.HWnd,Form.ActiveForm==this);return;caseWM_NCACTIVATE:
DrawCaption(m.HWnd,m.WParam.ToInt32()>0);return;caseWM_NCRBUTTONDOWN:{intposX,posY;
intwp=m.WParam.ToInt32();longlp=m.LParam.ToInt64();posX=LOBYTE(lp);posY=HIBYTE(lp);
if(wp==HTCAPTION){
Pointpt=this.PointToClient(newPoint(posX,posY));
if(this.CaptionContextMenu!=null){this.CaptionContextMenu.Show(posX,posY);return;}}
break;}caseWM_SETCURSOR:
if(this.ControlBox){intposX,posY;
intwp=m.WParam.ToInt32();longlp=m.LParam.ToInt64();
posX=LOBYTE(lp);posY=HIBYTE(lp);
BrushbackgroundColor=SolidBrush(CaptionBackgroundColor);
_NonClientSizeInfoncInfoGetNonClientInfo(m.HWnd);
IntPtrdc=GetWindowDC(m.HWnd);
new=
Graphicsg=Graphics.FromHdc(dc);
intcloseBtnPosX=ncInfo.CaptionRect.Left+ncInfo.CaptionRect.Width-ncInfo.BorderSize.Width-ncInfo.CaptionButtonSize.Width;
intmaxBtnPosX,minBtnPosX;maxBtnPosX=closeBtnPosX-ncInfo.CaptionButtonSiz
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 落地式钢管脚手架卸料平台施工方案
- 工厂供水供应协议模板
- 体育产业借款合同
- 砌墙工程人员派遣协议
- 雨水工程整体施工方案
- 2024至2030年中国玻璃编织耐热电线数据监测研究报告
- 政府采购股权投资服务协议
- 2024至2030年中国桂花鱼行业投资前景及策略咨询研究报告
- 信用评级服务协议
- 秩序维护部考核制度
- 国家高新技术企业评定打分表
- 成语故事钻木取火
- MOOC 自然地理学-西北大学 中国大学慕课答案
- 计算机组成原理与汇编语言课后习题及作业答案
- 中华民族共同体
- 2024年社区工作者考试必考1000题及参考答案(模拟题)
- 跨平台移动应用开发技术
- 十二指肠溃疡伴穿孔的护理查房
- 2023-2024学年北京市房山区九年级上学期期中考试数学试卷含详解
- 市场营销策划(本)-形考任务三(第八~十章)-国开(CQ)-参考资料
- 公司留学展推广方案
评论
0/150
提交评论