zoukankan      html  css  js  c++  java
  • 窗口子类化如何防止冲突

    窗口子类化如何防止冲突

    子类化是用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                                                 '释放热键供其它应用程序使用

  • 相关阅读:
    GUI常用监听事件
    GUI容器之布局管理器
    布局管理器的综合应用
    GUI容器之Panel
    mongodb
    redis持久化
    本地window启动redis
    redis主从模式
    hash 哈希
    set集合
  • 原文地址:https://www.cnblogs.com/liuzhaoyzz/p/3949252.html
Copyright © 2011-2022 走看看