陈晓猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

窗口子类化如何防止冲突

子类化是用GetWindowLong和SetWindowLong这两个API来对已经创建的窗口的窗口过程地址进行修改,用自己的窗口过程的新地址代替原来的,然后在自己写的新地址里过滤掉自己感兴趣的消息,一般我们是把自己不处理的消息再用原来的窗口函数调用,以实现我们对某一个窗口的特性的小修改要求,一般把子类化用在控件上,但也可以用在任意类型的窗口上.

以VB代码为例:

1、首先在form_load事件中拦截发送到所有form的消息,发送到自编回调函数NewWindowProc的地址。注意不同API函数及常量均要进行申明。

    OldWindowProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf NewWindowProc)

    RegisterHotKey Me.hwnd, 1, MOD_ALT, vbKeyN                                  '装载时注册热键

2、在自编回调函数NewWindowProc中对感兴趣的消息进行相关处理。

这里建议拦截句柄为hwnd控件的所有消息建议放在一个回调函数中,根据消息编号msg和消息附带的高位参数wparam的不同进行相关处理。

如果放在不同的回调函数中,就有可能会引起冲突。

Public Function NewWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

    Dim mx As Integer

    If Msg = TRAY_CALLBACK Then                                                 '如果用户点击了托盘中的图标,则进行判断是点击了左键还是右键

        If lParam = WM_LBUTTONUP Then                                           '如果点击了托盘左键

            TheForm.Visible = Not TheForm.Visible                               '单击一次就隐藏

        ElseIf lParam = WM_RBUTTONUP Then                                       '如果点击了托盘右键

            TheForm.PopupMenu TheMenu                                           '则弹出右键菜单

            Exit Function

        End If

    End If

    

    If Msg = WM_HOTKEY Then                                                     '如果是热键消息

        If wParam = 1 Then

            '如果是本程序定义的(系统消息中的wParam参数在热键消息中代表热键标示符,是在RegisterHotKey注册热键的时候定义的一个整数,如果热键是系统定义的,则标示符取值为-1或-2,详见开头

            frm_Main.Visible = Not frm_Main.Visible                             ' 热键对应上了之后就调用指定的过程

            '这样,运行之后,反复按Alt + N 就可以实现窗口的隐藏与显示

            Exit Function                                                       '消息已处理,不需要发回窗口

        End If

    End If

    

    NewWindowProc = CallWindowProc(OldWindowProc, hwnd, Msg, wParam, lParam)    '如果是其他类型的消息则传递给原有默认的窗口函数

End Function

3、Form_Unload事件中释放资源。

    SetWindowLong Me.hwnd, GWL_WNDPROC, OldWindowProc                           '将窗口过程地址还原

    UnregisterHotKey Me.hwnd, 1                                                 '释放热键供其它应用程序使用

 

posted on 2014-09-01 14:52  陈晓猫  阅读(925)  评论(0编辑  收藏  举报