API函数详解:屏蔽文本框默认的右键菜单——浅谈如何控制Windows消息函数

    屏蔽文本框的右键菜单,曾经看到一个程序是这样做的:    Private Sub Text1_MouseDown(ButtonAs Integer, ShiftAs Integer, XAs Single, YAs Single)
        Text1.Enabled =False
        Text1.Enabled =True
        PopupMenu yourmenu
   End Sub     这当然是个简单的实现方法,但作为一个以api为主题的网站,我在此想介绍一种用api函数来实现的方法,并想谈的深入一些。
    首先,谈谈消息和窗口函数。在Windows里,消息有两方面的用途:首先,它们由Windows传给窗口函数,指出发生了一个特定的事件。比如用户单击了鼠标,或者按下了键盘上的某个键。消息也可由Windows用于通告发生了一个内部事件,比如输入焦点的变更。另外,可将消息作为Windows的一种命令使用。这种命令用于通知一个窗口执行特定的任务。其次,通常可将消息传给一个控件或窗口,请求它执行特定的操作。而每个窗口都有一个窗口函数,它的作用是对消息进行处理。该函数就象一个特殊的VB程序,其中包含了对事件进行处理的代码。
    对于右击文本框,首先是产生一条 WM_CONTEXTMENU 消息,该消息被文本框的窗口函数接收,就会弹出默认的菜单。所以,我的思路是:接收所有的文本框消息,如果消息为 WM_CONTEXTMENU ,那么弹出自定义菜单,否则,把消息传递给默认的窗口函数由它处理。
    如何接收消息?一个方法是,用 AddressOf 关键字,它可以把一个自定义模块的地址变为窗口函数的地址。这样,窗口函数就成了你的自定义模块了。而消息仍然传递到原先窗口函数的地址(这时,这个地址指向的窗口函数已经是你的自定义模块)     现在就看看是如何实现的吧。首先建议你看看VB联机手册关于 AddressOf 的帮助。程序需要一个窗体、窗体中有一个文本框,以及一个标准模块。     标准模块的代码:    Option Explicit    Public OldWindowProcAs Long
    ' 保存默认的窗口函数的地址
   Public Const WM_CONTEXTMENU = &H7B
    ' 当右击文本框时,产生这条消息

   Public Declare Function GetWindowLongLib "user32"Alias "GetWindowLongA" (ByVal hWndAs Long,ByVal nIndexAs Long)As Long
   Public Declare Function SetWindowLongLib "user32"Alias "SetWindowLongA" (ByVal hWndAs Long,ByVal nIndexAs Long,ByVal dwNewLongAs Long)As Long
   Private Declare Function CallWindowProcLib "user32"Alias "CallWindowProcA" (ByVal lpPrevWndFuncAs Long,ByVal hWndAs Long,ByVal MsgAs Long,ByVal wParamAs Long,ByVal lParamAs Long)As Long


   Public Function SubClass1_WndMessage(ByVal hWndAs OLE_HANDLE,ByVal MsgAs OLE_HANDLE,ByVal wpAs OLE_HANDLE,ByVal lpAs Long) AsLong
       If Msg <> WM_CONTEXTMENUThen
            SubClass1_WndMessage = CallWindowProc(OldWindowProc, hWnd, Msg, wp, lp)
            ' 如果消息不是WM_CONTEXTMENU,就调用默认的窗口函数处理
            Exit Function
        End If
        SubClass1_WndMessage =True
    End Function     窗体的代码:    Option Explicit    Private Const GWL_WNDPROC = (-4)    Private Sub Text1_MouseDown(ButtonAs Integer, ShiftAs Integer, XAs Single, YAs Single)
       If Button = 1Then Exit Sub
        OldWindowProc = GetWindowLong(Text1.hWnd, GWL_WNDPROC)
        ' 取得窗口函数的地址
       Call SetWindowLong(Text1.hWnd, GWL_WNDPROC,AddressOf SubClass1_WndMessage)
        ' 用SubClass1_WndMessage代替窗口函数处理消息
    End Sub

   Private Sub Text1_MouseUp(ButtonAs Integer, ShiftAs Integer, XAs Single, YAs Single)
       If Button = 1Then Exit Sub
       Call SetWindowLong(Text1.hWnd, GWL_WNDPROC, OldWindowProc)
        ' 恢复窗口的默认函数
        PopupMenu usermenu
        ' 弹出自定义菜单
   End Sub     运行这个程序,右键菜单已被自定义菜单取代,不会出现两个菜单的情况。关于这个程序,你可以在例程中下载它,实现的功能比这里的要完整。最后要说明的是,尽量不要使用 AddressOf 来改变一个窗口的默认窗口函数,它可能引起不可预料的后果。在VB的联机手册里也是这样建议的,我在编这个程序时,死过几次机,其中一次,搞的我的Windows的“开始”菜单没有反应。     在Windows 98 + VB5.0下通过。本文涉及的api函数本站有介绍。

上页:API函数详解:XFORM函数 下页:API函数详解:AbortPath函数

Windows API函数大全

Windows API函数首页Windows API函数按字母排列
控件与消息函数硬件与系统函数
设备场景函数绘图函数
位图、图标和光栅运算函数菜单函数
文本和字体函数打印函数
文件处理函数进程和线程函数
Windows消息函数网络函数
版权所有 © 中山市飞娥软件工作室 证书:粤ICP备09170368号