Application Commands

| | Comments (2)

One concept which has been around for the last few years on the Windows market is one of generic application commands that hardware can generate and software can implement. For instance, newer keyboards come with all these fancy buttons in strange places that do things like open up the web browser, email, etc. Another common one is on multi-button mice. My last two five-button mouses have had two buttons devoted to back and forward functionality in browsing situations (like web and file browsers). This functionality is what I mean when I say "hardware-generated application commands."

So how do you handle this in REALbasic? The framework doesn't expose a series of events for you implement, so you're going to have to do the leg-work yourself. However, this leg-work is relatively easy to accomplish. Especially if you've ever subclassed a window before (which is something that the WFS makes trivial to accomplish).

Basically, you need to subclass the window which is externally commandable, and handle the WM_APPPCOMMAND (&h319) message. This message will be generated by the OS, and tells you what type of command, as well as other information (is it from a mouse, a keyboard, etc). You take a look at the command itself, and then perform whatever action the command is asking for. If you handle the command, you return true to the operating system to let it know that the command has been handled. If you don't handle the command, then you let the default window procedure handle it.

Basically, your code should look something like this:


Function WndProc(hWnd as Integer, msg as Integer, wParam as Integer, _
lParam as Integer, ByRef returnValue as Integer) As Boolean
Const WM_APPCOMMAND = &h319
Const APPCOMMAND_BROWSER_BACKWARD = 1
Const APPCOMMAND_BROWSER_FORWARD = 2

select case msg
case WM_APPCOMMAND
// The user has issued an application command which we will try to
// honor. The command is the high word of the lParam, logically
// ANDed with a mask (0x0FFF)
dim cmd as UInt16 = Bitwise.ShiftRight( lParam, 16, 32 ) And &h0FFF

// Now that we have the command, handle it
select case cmd
case APPCOMMAND_BROWSER_BACKWARD
HandleCommand( kGoBack )
case APPCOMMAND_BROWSER_FORWARD
HandleCommand( kGoForward )
else
// We didn't handle this, so we should let the default window
// procedure take a crack at it instead
return false
end select
// We handled the message, so we want to return
// true to the OS, telling it that we've dealt with it
returnValue = 1
return true
end select
End Function

Now, this was just an easy example showing how to handle the Back and Forward buttons. However, there are dozens of other commands you can handle, listed on MSDN, all of which make your application feel more native to Windows users.

2 Comments

While you're on the subject, I've always wondered why the RB runtime doesn't give access to a windows messages directly. I think it would be pretty cool if we could respond to (or ignore) Windows messages from within a special event in the IDE.

Maybe because of cross-platform issues?

Not very many people have asked for it, to be entirely honest. It's trivial to do via declares, so those who need it can already do it. This keeps the general API much cleaner as well since people who don't care about it don't have to worry about it.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.