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

  • 相关阅读:
    PHP调用WCF提供的方法
    关于git报 warning: LF will be replaced by CRLF in README.md.的警告的解决办法
    vue中引入mui报Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them的错误
    微信小程序报Cannot read property 'setData' of undefined的错误
    Vue那些事儿之用visual stuido code编写vue报的错误Elements in iteration expect to have 'v-bind:key' directives.
    关于xampp中无法启动mysql,Attempting to start MySQL service...的解决办法!!
    PHP的环境搭建
    新手PHP连接MySQL数据库出问题(Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES))
    手机号码、获得当前时间,下拉框,填写限制
    团队作业(五):冲刺总结
  • 原文地址:https://www.cnblogs.com/liuzhaoyzz/p/3949252.html
Copyright © 2011-2022 走看看