尝试编写更好的WndProc处理 [英] Trying to write a better WndProc Handling

查看:101
本文介绍了尝试编写更好的WndProc处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写更好的(我认为更好)且可重用的WndProc过程, 但是下面的代码不起作用,因为当我向子公司添加更多参数时,它表示该子公司不接受该数量的参数,这当然是合理的.

I'm trying to write a better (I think is better) and reusable WndProc procedure, but the code below does not work because when I add more arguments to the sub firm it says that the sub does not accept that amount of arguments, of course that is reasonable.

但是我知道可以做到这一点,因为前些时候我在一些第三方类中看到了这个带有很多自定义参数的wndproc子对象,我不记得在哪里见过,也不记得了他们是怎么做到的.

But I know that this trick can be done because I've seen this same wndproc sub with a lot of custom arguments time ago in some thirdparty classes which I don't remember where I've seen neither I don't remember how them did the trick.

然后,有人可以帮助我修复此代码并在出现问题时对其进行改进?

Then, someone could help me to fix this code and to improve it if it has something wrong?

另外,关于性能进行这样的修改有什么要注意的吗?我真的不知道这样的事情是否会以某种方式影响性能.

Also, there is something to remark about the performance doing a modification like this? really I don't know if something like this can affect the performance in some way.

''' <summary>
''' Windows Message Identifiers.
''' </summary>
Private Enum Messages As Integer
    ''' <summary>
    ''' Message is sent when the user chooses a command from the system menu,
    ''' or when the user chooses the "maximize", "minimize", "restore", or "close" buttons.
    ''' </summary>
    WM_SYSCOMMAND = &H112
End Enum

''' <summary>
''' Intercepts Windows messages for this Window.
''' </summary>
''' <param name="MsgInt32">
''' Message Identifier as Integer.
''' </param>
''' <param name="MsgWin32">
''' Message Identifier as Win32Hex format.
''' </param>
''' <param name="MsgHex">
''' Message Identifier as Hexadecimal format.
''' </param>
''' <param name="HWnd">
''' Window Handle.
''' </param>
''' <param name="LParam">
''' LParan message argument.
''' </param>
''' <param name="WParam">
''' WParam message argument.
''' </param>
''' <param name="Result">
''' Specifies the value that is returned to window in response to handling the message.
''' </param>
Protected Overrides Sub WndProc(ByRef m as Message,
                                ByRef MsgInt32 As Integer
                                ByRef MsgWin32 As String,
                                ByRef MsgHex As String,
                                ByRef HWnd As IntPtr,
                                ByRef LParam As IntPtr,
                                ByRef WParam As IntPtr,
                                ByRef Result As IntPtr)

    Select Case MsgInt32

        Case Messages.WM_SYSCOMMAND

            MsgBox(MsgWin32)
            MsgBox(LParam)
            MsgBox(WParam)

    End Select

    ' Return control to base message handler.
    MyBase.WndProc(m, CInt(m.Msg), "&H" & Hex(m.Msg), Hex(m.Msg), m.HWnd, m.LParam, m.WParam, m.Result)

End Sub

更新:

我找到了要重现的原始代码之一,以更轻松地管理邮件.

I've found one of the original codes that I will to reproduce to manage messages easier.

Public Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal _
    lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam _
    As Long, ByVal lParam As Long) As Long

Public Delegate Function ipWindowProc(ByVal hwnd As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

Dim ip As ipWindowProc = AddressOf Me.WindowProc

' The following function acts as Form1's window procedure to process messages.
Public Function WindowProc(ByVal hwnd As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Dim bTopMost As Boolean = Me.TopMost
    Dim hMenu As Integer = 0
    Dim iRet As Integer = 0
    Dim mii As MENUITEMINFO
Select Case uMsg
    Case WM_INITMENU
        hMenu = GetSystemMenu(hwnd, 0)
        mii.cbSize = Len(mii)
        mii.fMask = MIIM_STATE
        If bTopMost = True Then
            mii.fState = MFS_ENABLED Or MFS_CHECKED
        Else
            mii.fState = MFS_ENABLED Or 0
        End If
        iRet = SetMenuItemInfo(hMenu, 1, 0, mii)
        WindowProc = 0
    Case WM_SYSCOMMAND
        If wParam = 1 Then
            mii.cbSize = Len(mii)
            mii.fMask = MIIM_STATE
            If bTopMost = True Then
                mii.fState = MFS_ENABLED Or 0
                iRet = SetMenuItemInfo(hMenu, 1, 0, mii)
                Me.TopMost = False
            Else
                mii.fState = MFS_ENABLED Or MFS_CHECKED
                iRet = SetMenuItemInfo(hMenu, 1, 0, mii)
                Me.TopMost = True
            End If
            WindowProc = 0
        Else
            WindowProc = CallWindowProc(ioProc, hwnd, uMsg, wParam, lParam)
        End If
    Case Else
        WindowProc = CallWindowProc(ioProc, hwnd, uMsg, wParam, lParam)
End Select
End Function

更新2

好吧,我已经从上面的代码中翻译过来了,现在我需要添加使其像在上面的代码中一样作为wndproc替代品来工作?

Well, I have translated this from the code above, now what I need to add to make it working as a wndproc replacement like in the code above?

public class form1

<System.Runtime.InteropServices.
DllImport("user32.dll")>
Private Shared Function CallWindowProc(
        ByVal lpPrevWndFunc As WndProcDelegate,
        ByVal hWnd As IntPtr,
        ByVal Msg As UInteger,
        ByVal wParam As IntPtr,
        ByVal lParam As IntPtr
) As IntPtr
End Function

Delegate Function WndProcDelegate(
         ByVal hWnd As IntPtr,
         ByVal msg As UInteger,
         ByVal wParam As IntPtr,
         ByVal lParam As IntPtr
) As IntPtr

''' <summary>
''' Process Windows messages.
''' This function acts as wndproc.
''' </summary>
Public Function WindowProc(ByVal hwnd As IntPtr,
                           ByVal uMsg As UInteger,
                           ByVal wParam As IntPtr,
                           ByVal lParam As IntPtr) As Integer

    Select Case uMsg

        Case &H112

            MsgBox("Message intercepted!")

    End Select

End Function

End class

推荐答案

为什么?...为什么要这样做?

Why?...why would you do this?

您只是在犯错误时开放自己.老式的VB6程序会使用这种类型的API,因为简单的事实是该语言没有提供内置的实现方法.如果您需要降低水平,那是做到这一点的一种方法.

You're just opening yourself up to making mistakes. An old school VB6 program would use this type of API because of the simple fact that the language didn't provide a built-in way of doing it. If you needed to go low level then that was one way of doing it.

VB.Net通过允许您覆盖WndProc()来免费提供此功能.

该API并没有使管理消息变得更加容易.您要使用此API尝试访问的所有这些额外"参数都已经在罐装WndProc()过程的已经存在中的消息参数中,称为"m":

That API doesn't make managing messages any easier. All those "extra" parameters you're trying to access by using this API are already there in the Message parameter called "m" in the canned WndProc() procedure:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    MyBase.WndProc(m)
End Sub

看看为消息:

这些值都在那里.您可以使用m.Msg:

Those values are all there. You can make a nice Select Case Statement using m.Msg:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    Select Case m.Msg
        Case WM_LBUTTONDOWN

        Case WM_RBUTTONDOWN

    End Select
    MyBase.WndProc(m)
End Sub

...,您可以以相同的方式访问其他参数.您可以设置Result()属性来更改处理消息的方式.您甚至可以更改消息,等等.如果您想要消息的友好String版本,请使用m.ToString().

...and you can access the other params the same way. You can set the Result() property to change the way the message is handled. You can even change the message, etc. If you want a friendly String version of the message then use m.ToString().

我的朋友就在这里...使用API​​并不能给您带来您所没有的任何东西,只会为您带来更多的工作.

It's all there my friend...using the API doesn't give you anything you don't already have, it just creates more work on your part.

这篇关于尝试编写更好的WndProc处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆