1

I am converting my winforms project over to WPF and also learning WPF while i am doing it.

I ran into a problem with this code

This code detects the buttons pressed on a media keyboard or Media Center remote control.

Protected Overrides Sub WndProc(ByRef msg As Message)
    If msg.Msg = &H319 Then
        ' WM_APPCOMMAND message
        ' extract cmd from LPARAM (as GET_APPCOMMAND_LPARAM macro does)
        Dim cmd As Integer = CInt(CUInt(msg.LParam) >> 16 And Not &HF000)
        Select Case cmd
            Case 13
                MessageBox.Show("Stop Button")
                Exit Select
            Case 47
                MessageBox.Show("Pause Button")
                Exit Select
            Case 46
                MessageBox.Show("Play Button")
                Exit Select
        End Select
    End If
    MyBase.WndProc(msg)
end sub

I was wondering if there was a way to get it working in WPF or maybe do something similar.

Edit

My latest attempt, i tried to convert it from C# so it maybe be incorrect. (this just crashes my app)

Dim src As HwndSource = HwndSource.FromHwnd(New WindowInteropHelper(Me).Handle)
src.AddHook(New HwndSourceHook(AddressOf WndProc))

and

Public Function WndProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr

'Do something here
If msg = "WM_APPCOMMAND" Then
MessageBox.Show("dd")
End If

Return IntPtr.Zero
End Function

Am i on the right track or am i way off?

Mattigins
  • 1,014
  • 9
  • 25
  • So you want to override the WndProc in a WPF application? – user Aug 02 '13 at 16:00
  • Yes, unless there is an easier way to capture the multimedia keys. – Mattigins Aug 02 '13 at 16:03
  • possible duplicate of [How to handle WndProc messages in WPF?](http://stackoverflow.com/questions/624367/how-to-handle-wndproc-messages-in-wpf) – user Aug 02 '13 at 16:07
  • I have looked at that post and i don't really understand it. Also that post is in C# not vb.net – Mattigins Aug 02 '13 at 16:07
  • 1
    If so, then I would suggest that you *ask specifically about what you don't understand* rather than asking "if there is a way to get [this] working in WPF", particularly without showing evidence of any effort of your own. It took me about 15 seconds googling for "wpf wndproc" to find that and some other pages you may find of interest. Is your problem with the C#/VB.NET syntax difference ("I found this C# code, but how do I do the same thing in VB.NET?")? Is it something about how the code works ("what does this C# code do?")? Or something else? – user Aug 02 '13 at 16:09
  • C#.NET and VB.NET really aren't very different, and you are using the same BCL (base class library) in both cases. The two languages are *a lot* closer than, say, C++ and VB. – user Aug 02 '13 at 16:13
  • I have updated the initial post with my latest attempt, i have been working on this for 2 hours.. Posting here is always my last resort because i like to work it out for myself but sometimes help is required. – Mattigins Aug 02 '13 at 16:17
  • *Showing* effort is good, but "this just crashes my app" doesn't say much. Tell us what line the crash occurs on and what the specific exception details are. – user Aug 02 '13 at 16:20
  • It doesn't give a line.. when i say crash i mean stops responding and closes itself. No error – Mattigins Aug 02 '13 at 16:21

1 Answers1

3

Your window procedure is wrong:

Public Function WndProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr

    'Do something here
    If msg = "WM_APPCOMMAND" Then
        MessageBox.Show("dd")
    End If

    Return IntPtr.Zero
End Function

Note that the msg parameter is an Integer, not a string. This should be giving you a compile-time error, so I don't know what you mean about it crashing your app, though.

You need the Windows header files to find out the ID of the WM_APPCOMMAND message, or they're sometimes given in the documentation. In this case, it is. The value is &H0319 (in VB hex notation).

So change the code to look like this:

Private Const WM_APPCOMMAND As Integer = &H0319

Public Function WndProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr

    ' Check if the message is one you want to handle
    If msg = WM_APPCOMMAND Then
        ' Handle the message as desired
        MessageBox.Show("dd")

        ' Indicate that you processed this message
        handled = True
    End If

    Return IntPtr.Zero
End Function
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • Thank you very much, it works perfectly. All i needed to add was `Dim cmd As Integer = CInt(CUInt(lParam) >> 16 And Not &HF000)` and it works like it did before. – Mattigins Aug 02 '13 at 16:31