子类化教程和范例.docx

上传人:b****6 文档编号:5993741 上传时间:2023-01-02 格式:DOCX 页数:15 大小:31.11KB
下载 相关 举报
子类化教程和范例.docx_第1页
第1页 / 共15页
子类化教程和范例.docx_第2页
第2页 / 共15页
子类化教程和范例.docx_第3页
第3页 / 共15页
子类化教程和范例.docx_第4页
第4页 / 共15页
子类化教程和范例.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

子类化教程和范例.docx

《子类化教程和范例.docx》由会员分享,可在线阅读,更多相关《子类化教程和范例.docx(15页珍藏版)》请在冰豆网上搜索。

子类化教程和范例.docx

子类化教程和范例

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-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1