Perl programmer for hire: download my resume (PDF).
John Bokma MexIT
freelance Perl programmer

Using application command events with Perl

Monday, January 22, 2007 | 0 comments

Today I was looking into a way to control Windows Media Player from a Perl program. After using Google to search for more information I discovered WM_APPCOMMAND Notification.

I had already some experience with sending messages from a Perl program because this month I tried to interface with Snarl via Perl.

The "WM_APPCOMMAND Notification" entry of MSDN gave a long list of possible commands, but not the values for each command. After searching a bit with Google I discovered that the value for WM_APPCOMMAND was 0x319, and I also stumbled upon a list with values for each application command.

The WM_APPCOMMAND notification must be send to the application one wants to control from Perl. So first we look up the window handle of that application. In this case the Windows Media Player:

my $handle = Win32::GUI::FindWindow( 'WMPlayerApp', 'Windows Media Player' );

If the FindWindow function fails, zero is assigned to $handle.

If the window handle returned is not zero, the WM_APPCOMMAND message can be send to it as follows:

Win32::GUI::SendMessage( $handle, WM_APPCOMMAND, $w_param, $l_param );

According to the documentation on MSDN the $w_param parameter is a "Handle to the window where the user clicked the button or pressed the key". I decided to use the window handle of the Windows Media Player for this parameter.

The $l_param parameter is a combination of three values: cmd, uDevice, and dwKeys. I learned that the value of cmd has to be shifted 16 bits to the left.

Example Perl Program

The following Perl program plays the first 10 seconds of a track and then moves Windows Media Player to the next track. When the last track has been played for (roughly) 10 seconds the Media Player program starts with the first track in the playlist (again).

use strict;
use warnings;

use Win32::GUI;

use constant WM_APPCOMMAND => 0x319;

use constant APPCOMMAND_VOLUME_DOWN         =>  9;
use constant APPCOMMAND_VOLUME_UP           => 10;
use constant APPCOMMAND_MEDIA_NEXTTRACK     => 11;
use constant APPCOMMAND_MEDIA_PREVIOUSTRACK => 12;
use constant APPCOMMAND_MEDIA_STOP          => 13;
use constant APPCOMMAND_MEDIA_PLAY          => 46;


sub application_command {

    my $command = shift;

    my $handle = Win32::GUI::FindWindow(

        'WMPlayerApp', 'Windows Media Player'

    );
    $handle or return 0;

    return Win32::GUI::SendMessage(

        $handle, WM_APPCOMMAND, $handle, $command << 16
    );
}

application_command( APPCOMMAND_MEDIA_PLAY   );

while ( 1 ) {

    sleep( 10 );
    application_command( APPCOMMAND_MEDIA_NEXTTRACK );
}

Application command events related

Also today

Please post a comment | read 0 comments | RSS feed