How I could properly set the return value of a Windows Message by calling a method and passing the return value?

StackOverflow https://stackoverflow.com/questions/20085564

Question

I'm trying to customize the way that I process the wndproc messages.

In a class I have a simple wndproc overrided sub and when a KNOWN message is processed then I raise an event with that message information, this is how I'm handling the event:

Public Class Form1

Private WithEvents WndMessages As New WndProcClass(Form2)

Private Sub MessageHandler(ByVal sender As Object, 
                           ByVal e As WndProcClass.MessageInterceptedEventArgs) _
Handles WndMessages.MessageIntercepted

    If e.ID = WndProcClass.Messages.WM_CREATE Then
        MsgBox(e.Result) ' Result = 0
        WndMessages.ReturnValueToLastMessage(-1)
    If e.ID = WndProcClass.Messages.WM_CLOSE Then
        WndMessages.ReturnValueToLastMessage(0)
    End If

End Sub

Private Shadows Sub Shown() Handles MyBase.Shown
    Form2.Show()
End Sub

End Class

Well, What I would like to try now is to create a method which could set the return value for the raised message (notice the WndMessages.ReturnValueToLastMessage(-1) in the code above), and there is where I'm totally lost, I don't know how I could implement that method, when I try to set the return value, the value does not changes always is Zero for that message.

This is the wndproc class:

#Region " WndProc Class "

Public Class WndProcClass
    Inherits NativeWindow
    Implements IDisposable

#Region " Variables "

    ''' <summary>
    ''' The form to manage Windows Messages.
    ''' </summary>
    Private WithEvents form As Form = Nothing

    ''' <summary>
    ''' Stores the message arguments.
    ''' </summary>
    Private MessageArgs As New MessageInterceptedEventArgs

#End Region

#Region " Events "

    ''' <summary>
    ''' Event raised when a known message is processed.
    ''' </summary>
    Public Event MessageIntercepted As EventHandler(Of MessageInterceptedEventArgs)
    Public Class MessageInterceptedEventArgs : Inherits EventArgs

        Public Property ID As Messages
        Public Property IDWin32Hex As String
        Public Property HWND As IntPtr
        Public Property LParam As IntPtr
        Public Property WParam As IntPtr
        Public Property LParamAsCoordinate As Point
        Public Property WParamAsCoordinate As Point

        ''' <summary>
        ''' Return value.
        ''' </summary>
        Public Property Result As String

    End Class

#End Region

#Region " Message Enumeration "

    Public Enum Messages As Integer

        ''' <summary>
        ''' Sent as a signal that a window or an application should terminate.
        ''' </summary>
        WM_CLOSE = &H10

    End Enum

#End Region

#Region " Constructor "

    Public Sub New(ByVal form As Form)

        ' Set the Formulary.
        Me.form = form

        ' Assign the form handle.
        SetFormHandle()

    End Sub

#End Region

#Region " Event Handlers "

    Private Sub SetFormHandle() _
    Handles Form.HandleCreated, Form.Load, Form.Shown

        Try
            If Not Me.Handle.Equals(Me.form.Handle) Then
                Me.AssignHandle(Me.form.Handle)
            End If
        Catch ' ex As InvalidOperationException
        End Try

    End Sub

    Private Sub OnHandleDestroyed() _
    Handles Form.HandleDestroyed

        Me.ReleaseHandle()

    End Sub

#End Region

#Region " Windows Messages Method "

    Protected Overrides Sub WndProc(ByRef m As Message)

        If [Enum].IsDefined(GetType(Messages), m.Msg) Then

            With MessageArgs
                .HWND = m.HWnd
                .ID = [Enum].Parse(GetType(Messages), m.Msg)
                .IDWin32Hex = "&H" & CStr(Hex(m.Msg))
                .LParam = m.LParam
                .WParam = m.WParam
                .LParamAsCoordinate = New Point(m.LParam)
                .WParamAsCoordinate = New Point(m.LParam)
                .Result = m.Result
            End With

            RaiseEvent MessageIntercepted(Me, MessageArgs)

        End If

        ' Return Message to base message handler.
        MyBase.WndProc(m)

    End Sub

#End Region

' Private LastMessage As Message
Public Sub ReturnValueToLastMessage(ByVal value As IntPtr)
    ' LastMessage.Result = value
    ' MyBase.WndProc(LastMessage)
End Sub

End Class

#End Region
Was it helpful?

Solution

I found a solution, just I needed to byrefering the message.

I've changed this:

Public Event MessageIntercepted As EventHandler(Of MessageInterceptedEventArgs)

To this else:

Public Event MessageIntercepted(ByRef m As Message, ByVal args As MessageInterceptedEventArgs)

And raised the event as this:

RaiseEvent MessageIntercepted(m, MessageArgs)

So now I can play with the message results like this:

Private WithEvents WindowsMessages As New WndProcClass(Me)

Private Sub WindowsMessageHandler(ByRef m As Message, ByVal e As WndProcClass.MessageInterceptedEventArgs) _
Handles WindowsMessages.MessageIntercepted

    If e.ID = WndProcClass.KnownMessages.WM_NCHITTEST Then

        If CType(e.Result, NCHitTest) = NCHitTest.Top Then

            m.Result = New IntPtr(NCHitTest.Caption)

        End If

    End If

End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top