1. 何謂子類化(subclassing)眾所周知,Windows是一個基于消息的系統(tǒng),消息在Windows的對象之間進行著傳遞。子類化和Windows的鉤子機制存在于消息系統(tǒng)之中,我們可以利用這些機制來操縱、修改甚至丟棄那些在操作系統(tǒng)或是進程中傳遞的消息,以求改變系統(tǒng)的一些行為。子類化技術(shù)用來截取窗口或控件之間的消息,當(dāng)然是消息在到達目的窗口之前完成的操作。這些被截獲的消息既可以保留也可以修改它們的狀態(tài),之后就繼續(xù)發(fā)送到目的地。子類化技術(shù)實現(xiàn)了一些正常情況下無法實現(xiàn)的功能,試想鼠標(biāo)右鍵單擊TextBox,系統(tǒng)默認彈出Undo、Cut、Copy、Paste等菜單,我們就可以利用子類化技術(shù)來改變這個系統(tǒng)菜單。簡單的說,子類化就是創(chuàng)建一個新的窗口消息處理過程,并將其插入到原先的默認窗口消息處理過程之前。子類化分為三類:實例子類化(instance subclassing)—從窗口或控件的單一實例截獲消息,這種子類化技術(shù)最普遍;全局子類化(global subclassing)—能夠截獲從相同的窗口類創(chuàng)建出來的多個窗口或控件的消息;超類化(superclassing)—和全局子類化很類似,區(qū)別在于可以應(yīng)用在新的窗口類上面。 2. Visual Basic 6子類化的實現(xiàn)在Visual Basic 6子類化的實現(xiàn)中我將通過一段代碼的實例來介紹這一技術(shù)在VB6中的應(yīng)用。下面的例子將演示如何將About加入窗口的系統(tǒng)菜單。①創(chuàng)建工程啟動Visual Basic 6同時創(chuàng)建一個標(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 ③加入一個模塊并錄入代碼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‘新的窗口消息處理過程,將被插入到默認處理過程之前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)用默認的窗口處理過程SubWndProc = CallWindowProc(PrevWndProc, hWnd, Msg, wParam, lParam)End Function ' -- 模塊結(jié)束 -- ' 但是,需要指出的是不正確的子類化是非常危險的,將導(dǎo)致一個General Protection Fault(GPF)錯誤,致使VB應(yīng)用立即崩潰。 3. Visual Basic .NET子類化的實現(xiàn)在.NET中使用子類化技術(shù)要比VB6中簡單,因為微軟在.NET中已經(jīng)提供了接口,不需要我們再自己SetWindowLong了,我們做的是Overrides(覆蓋) WndProc過程即可。Overrides Protected Sub WndProc( ByRef m As Message )參數(shù)m實現(xiàn)了Windows的消息類型。下面的例子將同樣演示如何將About加入窗口的系統(tǒng)菜單。①創(chuàng)建工程創(chuàng)建一個VB.NET的Windows Application工程。 ②錄入代碼Public Class Form1 Inherits System.Windows.Forms.Form ‘中間隱去了.NET自動生成的代碼‘ – 引用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)菜單的句柄,第二個參數(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)用窗口默認的處理過程 MyBase.WndProc(m) End SubEnd Class
成都創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)公司,提供成都網(wǎng)站制作、成都做網(wǎng)站,網(wǎng)頁設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);可快速的進行網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,是專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
插入項目ListView控件自身支持的,何必用SendMessage?而且好像PostMessage更加穩(wěn)定
這里有一篇文章寫得比較詳細,可以參考一下 lpMsgBuf : 應(yīng)該是用來接受FormatMessage()函數(shù)格式化后的消息緩沖區(qū)的地址。
名稱欄目:消息處理vb.net 消息處理器作用
文章來源:http://www.rwnh.cn/article4/ddoodie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、ChatGPT、品牌網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、App設(shè)計、微信公眾號
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)