Tuesday, July 10, 2007

Lesson 6: The Extra Mile

Well, there are other options to dealing with dialogs....don't.

I use Winamp as my media player, not just because I can make it do strange and very useful little things but because I hate llamas. I have macros that will let me move forward and back in the media being played by 5 seconds, 30 seconds, and 3 minutes. I can also grab the current position of the playing media and save it to a text file sort of like "bookmarking". Now, of course you can do this via the buttons on the player and dialogs but it's clunky and not very responsive, so here's what I do.

I went nosing around the SDK for Winamp and got a hold of their 'WM_COMMAND Messages' definitions and menu ids. Now, instead of using a mouse command 'click here' on 'this window', I can forgo the whole graphical interface and it's associated problems. Here's how I'm moving 5 seconds forward or back using QM.

men 40144 win("" "Winamp v1.x") ;;Back 5 seconds
men 40060 win("" "Winamp v1.x") ;;FFwd 5 seconds

This responds MUCH faster via a trigger key than even using a mouse click manually but it's "faking" a menu choice. And, if I know I want to move 30 seconds forward (for skipping commercials on dl.tv-sorry, guys...but I do watch the interesting ones...and GoDaddy ain't one of 'em), I use this code:

int hwnd=win("" "Winamp v1.x")
if(!hwnd) ret
_i=SendMessage(hwnd WM_USER 0 105)
_i+30000;;time to skip in miliseconds (this is 30 seconds)
SendMessage(hwnd WM_USER _i 106)

If you look closely, you'll see that I'm using the 'SendMessage' capability to get the current position in milliseconds (105) and then sending a new value back to the player (106). I get remarkably fast response times when doing this; the video at worst barely even stutters. This is much better than even using my above macro repeated 6 times.

Once you start getting a feel for what the 'SendMessage' commands start returning, you can really start cooking up some useful things. For instance, when I get a hold of a really good tune, I have a tendency to listen to it for 5 or 6 hours just repeating over and over. So, I came up with a quick method to force Winamp to do this. Since there is no setting for "Repeat Song" you have to build it from 2 settings: "Repeat Playlist" and "Manual Advance".

int y z
int hwnd=win("" "Winamp v1.x")
if(!hwnd) ret
z=SendMessage(hwnd WM_USER 0 251);;get repeat playlist value
y=SendMessage(hwnd WM_USER 1 634);;get manual advance value
if y+z=2
,Speak("Continue" 0 "" 0 100)
,SendMessage(hwnd WM_USER 0 635)
,OnScreenDisplay("Continue" 1 1000 10 "Arial" 0 0x1d60cd 0 "psa")
else
,Speak("Song Looped" 0 "" 0 100)
,OnScreenDisplay("Song Looped" 1 1000 10 "Arial" 0 0x1d60cd 0 "psa")
,SendMessage(hwnd WM_USER 1 635);;set man advance
,SendMessage(hwnd WM_USER 1 253);;set repeat

Since I want this macro to 'toggle' this state of 'Song Looped' rather than merely just 'turn it on', I have it use an 'if' statement to determine what state it is in and then reverse that state. I also tell it to give me a little audio feedback so that I know that the macro executed and let me know what it did (that's the 'Speak' function).

Now you have two ways of dealing with the GUI (or rather 1 way of dealing with it and 1 way of avoiding it). So have at it and I'll see you next time cause the hook always brings you back.