Windows Media Controller
Last month my space bar started failing on me. The keyboard was a Microsoft brand Comfort Curve which had lasted me about three years (I have thrown it at least as many times) and I was satisfied with the way it functioned. However, at work we have a Dell OEM keyboard with next track/previous track buttons. In my mind, if I was going to invest in a new keyboard I wanted to be able to change music tracks.
My other requirements were a wired keyboard (I hate latency at 70 words per minute) and a local store (I like to return shitty products without paying return shipping). After a bit of shopping around I finally picked a Microsoft Natural Ergonomic Keyboard 4000, which sadly did not have next/previous track buttons.
The keyboard did however have five programmable keys above the function keys which can be assigned to applications. To handle the assignment there was a starred "Favorites" button. Now, I have to give credit to Stephanie, who casually asked if I could program those keys to be next and previous track buttons. The look on my face went blank as realization set in, and I bought the keyboard.
That day I wrote such a program which does some basic API stuff to control Windows Media Player from Visual Basic .NET 2003. The program accepts some command line arguments to do a few different things. To get started, create a new Visual Basic application and add the following code:
Private Const WM_APPCOMMAND As Integer = &H319
Public Enum AppCommands As Integer
VOLUME_DOWN = 9
VOLUME_UP = 10
MEDIA_NEXTTRACK = 11
MEDIA_PREVIOUSTRACK = 12
MEDIA_STOP = 13
MEDIA_PLAY = 46
MEDIA_PAUSE = 47
End Enum
<System.Runtime.InteropServices.DllImport( _
"user32.dll", SetLastError:=True)> _
Private Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport( _
"user32.dll", SetLastError:=True)> _
Private Function SendMessage( _
ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
I cannot take full credit for this simplification. The research work was started by a guy named John Bokma in an application he wrote in PERL, which he displays here. In converting this application to VB.NET, some shortcuts appeared which I took advantage of.
Now before we use the two API calls defined above, it may be useful to wrap them in a function. The first API call is the FindWindow call, defined since Windows 95 and NT 3.1 to return a window handle to the window with the title you provide. The second sends a message to that window. The function is as easy as this:
Public Function SendCommand(ByVal vCommand As AppCommands) As Integer
Dim tWindowHandle As IntPtr = _
FindWindow("WMPlayerApp", "Windows Media Player")
Return SendMessage( _
tWindowHandle, WM_APPCOMMAND, tHandle.ToInt32, vCommand << 16)
End Function
We now have a function and the definitions necessary to control Windows Media Player from Visual Basic. If you are trying to do a keyboard mod and give yourself next and previous buttons like me, you will need to bundle these functions in an application that can be controlled from the keyboard. All of the above code can be put in a Visual Basic module and run from a Main method. There is no interface and not even any error checking code. I wrote a method like this to run the application:
Sub Main(
Select Case Command().ToLower
Case "next" : SendCommand(AppCommands.MEDIA_NEXTTRACK)
Case "previous" : SendCommand(AppCommands.MEDIA_PREVIOUSTRACK)
Case "up" : SendCommand(AppCommands.VOLUME_UP)
Case "down" : SendCommand(AppCommands.VOLUME_DOWN)
Case "play" : SendCommand(AppCommands.MEDIA_PLAY)
Case "pause" : SendCommand(AppCommands.MEDIA_PAUSE)
Case "stop" : SendCommand(AppCommands.MEDIA_STOP)
End Select
End Sub
The next step was configuring the keyboard to invoke this application. I bundled the entire thing up into an executable file and copied it to "c:\windows" so I would not have to modify the environment path. Once there I used Microsoft's "Show My Favorites" tool to set the keyboard shortcuts (comes with the keyboard software):
Finally, no good keyboard mod is complete without actually doing a physical modification to the keyboard. Using a Sharpie brand permanent black marker, I drew "next" and "previous" symbols on the buttons I had designated:
I hope those of you looking to control Windows Media Player find it a little bit easier to do after this article.
