Beastian
Beastian

Reputation: 47

Attempting to trap window message in VB.NET DLL

I am trying to intercept a windows message sent using the WINAPI function "BroadcastSystemMessage" (from an XLL that sends this message when a new workbook is created).

I've attempted to use two methods to do this, but each has its disadvantages:

1) Using a managed listening window:

However, I don't want to run the risk of the user ever closing this listening window and,

listenForm.Show()
listenForm.visible = false

seems sloppy.

2) Using hooks:

However, the call back for "SetWindowsHookEx" only has a few parameters:

Protected Function HookCallBack(code As Integer, wParam As IntPtr, lParam As IntPtr) As Integer

and I'm looking for a way to access the "msg" struct which has the information I registered with "RegisterWindowMessage".

Here, "lParam" points to this struct and I can use:

Dim output(100) As Byte
Marshal.Copy(e.lParam, output, 0, 100)

to dereference this pointer. I have no idea how to parse the result, and it also bothers me that I'm wandering so far from the managed universe.

My question: can the down sides to each way be fixed, and what is the standard way to intercept messages or do something like this?

Upvotes: 0

Views: 810

Answers (1)

Hans Passant
Hans Passant

Reputation: 941417

The Show() method call is just one of the ways to get the native window created. You can also simple create it yourself in the constructor:

Public Sub new
    InitializeComponent()
    Me.CreateHandle()
End Sub

Or if you cannot avoid the Show() call because it is the startup form of your app then do it like this:

Protected Overrides Sub SetVisibleCore(value As Boolean)
    If Not Me.IsHandleCreated then
        value = False
        Me.CreateHandle()
    End If
    MyBase.SetVisibleCore(value)
End Sub

Note that in neither case the Load event will fire so move any code you have there into the constructor of the form class.


Do not use a window hook, all you have to do is override the WndProc() subroutine to see broadcasted messages:

Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = theRegisteredMessage Then
        '' etc...
    End If
    MyBase.WndProc(m)
End Sub

Do favor a plain SendMessage() with HWND_BROADCAST over BroadcastSystemMessage(). Or better yet, a Socket so you don't have to yell so loud.

Upvotes: 1

Related Questions