1. 何謂子類化(subclassing)眾所周知,Windows是一個(gè)基于消息的系統(tǒng),消息在Windows的對(duì)象之間進(jìn)行著傳遞。子類化和Windows的鉤子機(jī)制存在于消息系統(tǒng)之中,我們可以利用這些機(jī)制來操縱、修改甚至丟棄那些在操作系統(tǒng)或是進(jìn)程中傳遞的消息,以求改變系統(tǒng)的一些行為。子類化技術(shù)用來截取窗口或控件之間的消息,當(dāng)然是消息在到達(dá)目的窗口之前完成的操作。這些被截獲的消息既可以保留也可以修改它們的狀態(tài),之后就繼續(xù)發(fā)送到目的地。子類化技術(shù)實(shí)現(xiàn)了一些正常情況下無法實(shí)現(xiàn)的功能,試想鼠標(biāo)右鍵單擊TextBox,系統(tǒng)默認(rèn)彈出Undo、Cut、Copy、Paste等菜單,我們就可以利用子類化技術(shù)來改變這個(gè)系統(tǒng)菜單。簡單的說,子類化就是創(chuàng)建一個(gè)新的窗口消息處理過程,并將其插入到原先的默認(rèn)窗口消息處理過程之前。子類化分為三類:實(shí)例子類化(instance subclassing)—從窗口或控件的單一實(shí)例截獲消息,這種子類化技術(shù)最普遍;全局子類化(global subclassing)—能夠截獲從相同的窗口類創(chuàng)建出來的多個(gè)窗口或控件的消息;超類化(superclassing)—和全局子類化很類似,區(qū)別在于可以應(yīng)用在新的窗口類上面。 2. Visual Basic 6子類化的實(shí)現(xiàn)在Visual Basic 6子類化的實(shí)現(xiàn)中我將通過一段代碼的實(shí)例來介紹這一技術(shù)在VB6中的應(yīng)用。下面的例子將演示如何將About加入窗口的系統(tǒng)菜單。①創(chuàng)建工程啟動(dòng)Visual Basic 6同時(shí)創(chuàng)建一個(gè)標(biāo)準(zhǔn)EXE工程。 ②在窗體中錄入代碼Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As LongPrivate Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As String) As Long Private Const MF_BYCOMMAND = H0Private Const MF_BYPOSITION = H400Private Const MF_STRING = H0Private Const MF_SEPARATOR = H800 Private Sub Form_Load()InsertMenu GetSystemMenu(Me.hWnd, False), 0, MF_BYPOSITION Or MF_SEPARATOR, 2001, ""InsertMenu GetSystemMenu(Me.hWnd, False), 0, MF_BYPOSITION Or MF_STRING, 2002, "About Me(A)"'安裝子類化入口Call Init(Me.hWnd)End Sub Private Sub Form_Unload(Cancel As Integer)‘卸載子類化Call Terminate(Me.hWnd)End Sub ③加入一個(gè)模塊并錄入代碼Option Explicit Private Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex _ As Long, ByVal dwNewLong As Long) As Long Private Declare Function CallWindowProc Lib "user32" Alias _ "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal _ hWnd As Long, ByVal Msg As Long, ByVal wParam As _ Long, ByVal lParam As Long) As Long Const GWL_WNDPROC = (-4) Dim PrevWndProc Private Const WM_SYSCOMMAND = H112Const WM_DESTROY = H2‘子類化入口Public Sub Init(hWnd As Long) PrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf SubWndProc)End Sub‘子類化出口Public Sub Terminate(hWnd As Long) Call SetWindowLong(hWnd, GWL_WNDPROC, PrevWndProc)End Sub‘新的窗口消息處理過程,將被插入到默認(rèn)處理過程之前Private Function SubWndProc(ByVal hWnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) _ As LongIf Msg = WM_DESTROY Then Terminate (Form1.hWnd) If wParam = 2002 Then MsgBox "我是40Star", vbInformation, "hia..hia..."End If‘調(diào)用默認(rèn)的窗口處理過程SubWndProc = CallWindowProc(PrevWndProc, hWnd, Msg, wParam, lParam)End Function ' -- 模塊結(jié)束 -- ' 但是,需要指出的是不正確的子類化是非常危險(xiǎn)的,將導(dǎo)致一個(gè)General Protection Fault(GPF)錯(cuò)誤,致使VB應(yīng)用立即崩潰。 3. Visual Basic .NET子類化的實(shí)現(xiàn)在.NET中使用子類化技術(shù)要比VB6中簡單,因?yàn)槲④浽?NET中已經(jīng)提供了接口,不需要我們?cè)僮约篠etWindowLong了,我們做的是Overrides(覆蓋) WndProc過程即可。Overrides Protected Sub WndProc( ByRef m As Message )參數(shù)m實(shí)現(xiàn)了Windows的消息類型。下面的例子將同樣演示如何將About加入窗口的系統(tǒng)菜單。①創(chuàng)建工程創(chuàng)建一個(gè)VB.NET的Windows Application工程。 ②錄入代碼Public Class Form1 Inherits System.Windows.Forms.Form ‘中間隱去了.NET自動(dòng)生成的代碼‘ – 引用Win32Api – ‘Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As IntPtr, ByVal bRevert As Int32) As Int32Private Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Int32, ByVal nPosition As Int32, ByVal wFlags As Int32, ByVal wIDNewItem As Int32, ByVal lpNewItem As String) As Int32 Private Const MF_BYCOMMAND = H0Private Const MF_BYPOSITION = H400Private Const MF_STRING = H0Private Const MF_SEPARATOR = H800Private Const WM_SYSCOMMAND = H112 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load InsertMenu(GetSystemMenu(Me.Handle, False), 0, MF_BYPOSITION Or MF_SEPARATOR, 2001, "") '加入一條分割線‘GetSystemMenu(Me.Handle, False)是得到系統(tǒng)菜單的句柄,第二個(gè)參數(shù)為True的話不能改變系統(tǒng)菜單,所以要設(shè)為False InsertMenu(GetSystemMenu(Me.Handle, False), 0, MF_BYPOSITION Or MF_STRING, 2002, "About Me(A)") '加入About me菜單在系統(tǒng)菜單中 End Sub‘子類化窗口--覆蓋WndProc過程 Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) If m.Msg = WM_SYSCOMMAND Then If m.WParam.ToInt32 = 2002 Then MsgBox("我是40Star", vbInformation, "hia..hia...") End If End If ‘調(diào)用窗口默認(rèn)的處理過程 MyBase.WndProc(m) End SubEnd Class
成都創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)公司,提供成都網(wǎng)站制作、成都做網(wǎng)站,網(wǎng)頁設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);可快速的進(jìn)行網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,是專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
插入項(xiàng)目ListView控件自身支持的,何必用SendMessage?而且好像PostMessage更加穩(wěn)定
這里有一篇文章寫得比較詳細(xì),可以參考一下 lpMsgBuf : 應(yīng)該是用來接受FormatMessage()函數(shù)格式化后的消息緩沖區(qū)的地址。
名稱欄目:消息處理vb.net 消息處理器作用
文章來源:http://muchs.cn/article4/ddoodie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、ChatGPT、品牌網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、App設(shè)計(jì)、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)