netVB子类化教程.docx
- 文档编号:8707130
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:15
- 大小:31.09KB
netVB子类化教程.docx
《netVB子类化教程.docx》由会员分享,可在线阅读,更多相关《netVB子类化教程.docx(15页珍藏版)》请在冰豆网上搜索。
netVB子类化教程
1.何谓子类化(subclassing)
众所周知,Windows是一个基于消息的系统,消息在Windows的对象之间进行着传递。
子类化和Windows的钩子机制存在于消息系统之中,我们可以利用这些机制来操纵、修改甚至丢弃那些在操作系统或是进程中传递的消息,以求改变系统的一些行为。
子类化技术用来截取窗口或控件之间的消息,当然是消息在到达目的窗口之前完成的操作。
这些被截获的消息既可以保留也可以修改它们的状态,之后就继续发送到目的地。
子类化技术实现了一些正常情况下无法实现的功能,试想鼠标右键单击TextBox,系统默认弹出Undo、Cut、Copy、Paste等菜单,我们就可以利用子类化技术来改变这个系统菜单。
简单的说,子类化就是创建一个新的窗口消息处理过程,并将其插入到原先的默认窗口消息处理过程之前。
子类化分为三类:
实例子类化(instancesubclassing)—从窗口或控件的单一实例截获消息,这种子类化技术最普遍;全局子类化(globalsubclassing)—能够截获从相同的窗口类创建出来的多个窗口或控件的消息;超类化(superclassing)—和全局子类化很类似,区别在于可以应用在新的窗口类上面。
2.VisualBasic6子类化的实现
在VisualBasic6子类化的实现中我们将通过一段代码的实例来介绍这一技术在VB6中的应用。
现在很多开发社区中经常谈到的一个话题就是界面开发如何Skin,这种技术有很多解决方式,如使用可以贴图的控件或使用第三方开发的换肤ActiveX控件。
其实Skin技术需要处理的是WM_DRAWITEM、WM_MEASUREITEM、WM_NCPAINT消息,这些消息的主要用途就是可以重画控件和窗口的非客户区。
想要对这些VB6无法处理的消息进行编程就必须用到子类化,这些消息都会被发送到能够自绘的控件的窗口上,因此下面的例子就是利用窗口子类化来重画Button控件。
①创建工程
启动VisualBasic6同时创建一个标准EXE工程。
②窗口布局
在FORM1上放置3个Button控件,并将前两个Button的Style属性设置为1-Graphical,因为只有Style属性设置为Graphical的Button才可以Owner-drawn。
③在窗体中录入代码
PrivateSubCommand3_Click()
'通过Enabled属性的控制,来显示重画控件在Unenabled状态时的效果
IfCommand1.EnabledThen
Command1.Enabled=False
Else
Command1.Enabled=True
EndIf
EndSub
PrivateSubForm_Load()
'安装子类化入口
CallInit(Me.hWnd)
EndSub
PrivateSubForm_Unload(CancelAsInteger)
'卸载子类化
CallTerminate(Me.hWnd)
EndSub
④加入一个模块并录入代码
OptionExplicit
'--引用Win32Api–
'得到默认的窗口消息处理过程的地址需要的API
PrivateDeclareFunctionGetWindowLongLib"user32"Alias"GetWindowLongA"(ByValhWndAsLong,ByValnIndexAsLong)AsLong
'设置一个新的窗口消息处理过程的地址需要的API
PrivateDeclareFunctionSetWindowLongLib"user32"Alias"SetWindowLongA"(ByValhWndAsLong,ByValnIndexAsLong,ByValdwNewLongAsLong)AsLong
'给指定的窗口消息处理过程传递消息需要的API
PrivateDeclareFunctionCallWindowProcLib"user32"Alias"CallWindowProcA"(ByVallpPrevWndFuncAsLong,ByValhWndAsLong,ByValMsgAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLong
'内存拷贝
PrivateDeclareSubCopyMemoryLib"kernel32"Alias"RtlMoveMemory"(DestinationAsAny,SourceAsAny,ByValLengthAsLong)
ConstGWL_WNDPROC=(-4&)
DimPrevWndProc&
PrivateConstWM_DESTROY=&H2
PrivateConstWM_DRAWITEM=&H2B
PrivateTypeRECT
LeftAsLong
TopAsLong
RightAsLong
BottomAsLong
EndType
'WM_DRAWITEM需要处理的结构体
PrivateTypeDRAWITEMSTRUCT
CtlTypeAsLong
CtlIDAsLong
itemIDAsLong
itemActionAsLong
itemStateAsLong
hwndItemAsLong
hdcAsLong
rcItemAsRECT
itemDataAsLong
EndType
'Ownerdraw常量
PrivateConstODT_BUTTON=4
'Ownerdraw动作
PrivateConstODA_DRAWENTIRE=&H1
PrivateConstODA_SELECT=&H2
PrivateConstODA_FOCUS=&H4
'Ownerdraw状态
PrivateConstODS_SELECTED=&H1
PrivateConstODS_GRAYED=&H2
PrivateConstODS_DISABLED=&H4
PrivateConstODS_CHECKED=&H8
PrivateConstODS_FOCUS=&H10
'得到指定窗口的文本
PrivateDeclareFunctionGetWindowTextLib"user32"Alias"GetWindowTextA"(ByValhWndAsLong,ByVallpStringAsString,ByValcchAsLong)AsLong
'GDI相关API函数,重画Button时使用
PrivateDeclareFunctionSelectObjectLib"gdi32"(ByValhdcAsLong,ByValhObjectAsLong)AsLong
PrivateDeclareFunctionCreateSolidBrushLib"gdi32"(ByValcrColorAsLong)AsLong
PrivateDeclareFunctionDeleteObjectLib"gdi32"(ByValhObjectAsLong)AsLong
PrivateDeclareFunctionGetSysColorLib"user32"(ByValnIndexAsLong)AsLong
'色彩常量
ConstCOLOR_SCROLLBAR=0
ConstCOLOR_BACKGROUND=1
ConstCOLOR_ACTIVECAPTION=2
ConstCOLOR_INACTIVECAPTION=3
ConstCOLOR_MENU=4
ConstCOLOR_WINDOW=5
ConstCOLOR_WINDOWFRAME=6
ConstCOLOR_MENUTEXT=7
ConstCOLOR_WINDOWTEXT=8
ConstCOLOR_CAPTIONTEXT=9
ConstCOLOR_ACTIVEBORDER=10
ConstCOLOR_INACTIVEBORDER=11
ConstCOLOR_APPWORKSPACE=12
ConstCOLOR_HIGHLIGHT=13
ConstCOLOR_HIGHLIGHTTEXT=14
ConstCOLOR_BTNFACE=15
ConstCOLOR_BTNSHADOW=16
ConstCOLOR_GRAYTEXT=17
ConstCOLOR_BTNTEXT=18
ConstCOLOR_INACTIVECAPTIONTEXT=19
ConstCOLOR_BTNHIGHLIGHT=20
PrivateDeclareFunctionFillRectLib"user32"(ByValhdcAsLong,lpRectAsRECT,ByValhBrushAsLong)AsLong
PrivateDeclareFunctionFrameRectLib"user32"(ByValhdcAsLong,lpRectAsRECT,ByValhBrushAsLong)AsLong
PrivateDeclareFunctionCreatePenLib"gdi32"(ByValnPenStyleAsLong,ByValnWidthAsLong,ByValcrColorAsLong)AsLong
'画笔格式
ConstPS_SOLID=0
ConstPS_DASH=1'-------
ConstPS_DOT=2'.......
ConstPS_DASHDOT=3'_._._._
ConstPS_DASHDOTDOT=4'_.._.._
ConstPS_NULL=5
ConstPS_INSIDEFRAME=6
ConstPS_USERSTYLE=7
ConstPS_ALTERNATE=8
ConstPS_STYLE_MASK=&HF
PrivateDeclareFunctionMoveToExLib"gdi32"(ByValhdcAsLong,ByValxAsLong,ByValyAsLong,lpPointAsPOINTAPI)AsLong
PrivateDeclareFunctionLineToLib"gdi32"(ByValhdcAsLong,ByValxAsLong,ByValyAsLong)AsLong
PrivateTypePOINTAPI
xAsLong
yAsLong
EndType
PrivateDeclareFunctionDrawTextLib"user32"Alias"DrawTextA"(ByValhdcAsLong,ByVallpStrAsString,ByValnCountAsLong,lpRectAsRECT,ByValwFormatAsLong)AsLong
PrivateConstDT_SINGLELINE=&H20
PrivateConstDT_CENTER=&H1
PrivateConstDT_VCENTER=&H4
PrivateDeclareFunctionSetTextColorLib"gdi32"(ByValhdcAsLong,ByValcrColorAsLong)AsLong
PrivateDeclareFunctionSetBkModeLib"gdi32"(ByValhdcAsLong,ByValnBkModeAsLong)AsLong
PrivateConstTRANSPARENT=1
'–声明结束--
PrivateSubDrawButton(ByValhWndAsLong,ByValhdcAsLong,rctAsRECT,ByValnStateAsLong)
DimPAsPOINTAPI
DimsAsString
DimhbrAsLong
DimhpenAsLong
hbr=CreateSolidBrush(GetSysColor(COLOR_BTNFACE))'获得按钮的背景颜色RGB(231,231,231)
SelectObjecthdc,hbr'选择使用刷子
FillRecthdc,rct,hbr
DeleteObjecthbr
'画文字时背景为透明状
SetBkModehdc,TRANSPARENT
'得到Button的Caption
s=String$(255,"")
GetWindowTexthWnd,s,255
s=Trim$(s)
'根据Button的Enabled状态进行重画
If(nStateAndODS_DISABLED)=ODS_DISABLEDThen
'画外围灰框
hbr=CreateSolidBrush(RGB(132,130,132))
SelectObjecthdc,hbr
FrameRecthdc,rct,hbr
DeleteObjecthbr
'画内侧3D效果->亮色
hpen=CreatePen(PS_SOLID,1,RGB(255,255,255))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Right-1,rct.Top+1
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Left+1,rct.Bottom-1
DeleteObjecthpen
'画内侧3D效果->暗色
hpen=CreatePen(PS_SOLID,1,RGB(189,190,189))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Bottom-2,P
LineTohdc,rct.Right-1,rct.Bottom-2
MoveToExhdc,rct.Right-2,rct.Top+1,P
LineTohdc,rct.Right-2,rct.Bottom-1
DeleteObjecthpen
'画阴影文字
rct.Left=rct.Left+1
rct.Right=rct.Right+1
rct.Bottom=rct.Bottom+1
rct.Top=rct.Top+1
SetTextColorhdc,GetSysColor(COLOR_BTNHIGHLIGHT)
DrawTexthdc,s,LenB(StrConv(s,vbFromUnicode)),rct,DT_CENTEROrDT_SINGLELINEOrDT_VCENTER
rct.Left=rct.Left-1
rct.Right=rct.Right-1
rct.Bottom=rct.Bottom-1
rct.Top=rct.Top-1
SetTextColorhdc,GetSysColor(COLOR_GRAYTEXT)
DrawTexthdc,s,LenB(StrConv(s,vbFromUnicode)),rct,DT_CENTEROrDT_SINGLELINEOrDT_VCENTER
ExitSub
EndIf
'按下Button时重画
If(nStateAndODS_SELECTED)=ODS_SELECTEDThen
'画内部区域颜色
hbr=CreateSolidBrush(RGB(156,186,222))
SelectObjecthdc,hbr
FillRecthdc,rct,hbr
DeleteObjecthbr
'画外围灰框
hbr=CreateSolidBrush(RGB(99,125,165))
SelectObjecthdc,hbr
FrameRecthdc,rct,hbr
DeleteObjecthbr
'画内侧3D效果->亮色
hpen=CreatePen(PS_SOLID,1,RGB(123,158,206))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Right-1,rct.Top+1
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Left+1,rct.Bottom-1
DeleteObjecthpen
'画内侧3D效果->暗色
hpen=CreatePen(PS_SOLID,1,RGB(181,203,231))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Bottom-2,P
LineTohdc,rct.Right-1,rct.Bottom-2
MoveToExhdc,rct.Right-2,rct.Top+1,P
LineTohdc,rct.Right-2,rct.Bottom-1
DeleteObjecthpen
rct.Left=rct.Left+1
rct.Right=rct.Right+1
rct.Bottom=rct.Bottom+1
rct.Top=rct.Top+1
SetTextColorhdc,GetSysColor(COLOR_BTNTEXT)
DrawTexthdc,s,LenB(StrConv(s,vbFromUnicode)),rct,DT_CENTEROrDT_SINGLELINEOrDT_VCENTER
ExitSub
EndIf
'Button得到焦点时重画
If(nStateAndODS_FOCUS)=ODS_FOCUSThen
'画内部区域颜色
hbr=CreateSolidBrush(RGB(173,203,239))
SelectObjecthdc,hbr
FillRecthdc,rct,hbr
DeleteObjecthbr
'画外围灰框
hbr=CreateSolidBrush(RGB(107,138,181))
SelectObjecthdc,hbr
FrameRecthdc,rct,hbr
DeleteObjecthbr
'画内侧3D效果->亮色
hpen=CreatePen(PS_SOLID,1,RGB(198,223,247))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Right-1,rct.Top+1
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Left+1,rct.Bottom-1
DeleteObjecthpen
'画内侧3D效果->暗色
hpen=CreatePen(PS_SOLID,1,RGB(132,174,222))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Bottom-2,P
LineTohdc,rct.Right-1,rct.Bottom-2
MoveToExhdc,rct.Right-2,rct.Top+1,P
LineTohdc,rct.Right-2,rct.Bottom-1
DeleteObjecthpen
SetTextColorhdc,GetSysColor(COLOR_BTNTEXT)
DrawTexthdc,s,LenB(StrConv(s,vbFromUnicode)),rct,DT_CENTEROrDT_SINGLELINEOrDT_VCENTER
Else
'画外围灰框
hbr=CreateSolidBrush(RGB(132,130,132))
SelectObjecthdc,hbr
FrameRecthdc,rct,hbr
DeleteObjecthbr
'画内侧3D效果->亮色
hpen=CreatePen(PS_SOLID,1,RGB(255,255,255))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Right-1,rct.Top+1
MoveToExhdc,rct.Left+1,rct.Top+1,P
LineTohdc,rct.Left+1,rct.Bottom-1
DeleteObjecthpen
'画内侧3D效果->暗色
hpen=CreatePen(PS_SOLID,1,RGB(189,190,189))
SelectObjecthdc,hpen
MoveToExhdc,rct.Left+1,rct.Bottom-2,P
LineTohdc,rct.Right
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- netVB 子类 教程