Using Multimedia Keyboard Keys in Your Own Program

Environment: VS.NET (2003), Windows 2000, Windows XP

When I bought my current computer, it came with a multimedia keyboard that has a lot more keys than usual. There are keys for controlling a media player and some browser keys, such as forward, back, and so forth.

The Windows media player can be controlled by these keys, even if it is in the background; this is a very convenient feature. My version of Winamp sadly does not make use of the keys.

When I looked for a MP3/Ogg player with an integrated media library and available source code (so I could change things if neccesary), I stumbled over Musik. This is a Linux/Windows MP3/Ogg player using wxwindows2 for the GUI and sqlite as the database. It is quite fast, at least faster than mediaplayer and musicmatch jukebox, concerning the startup time and media library browsing. It is available at http://musik.sf.net.

Musik also didn't make use of the special keys, which I got accustomed to, so I started to add this feature for Windows. After reading some MSDN, I found out that you have to handle the WM_APPCOMMAND message, which is available to your program code, if you define _WIN32_WINNT=0x0500 (or higher) in your project. WM_APPCOMMAND can be found in winuser.h, if you have the right SDK headers. VS.NET already has these. For VC 6, I am not quite sure.

Your window proc of your window that should handle the WM_APPCOMMAND message has to do something like the following code does:

if(message == WM_APPCOMMAND)
{
  switch(GET_APPCOMMAND_LPARAM(lParam))
  {
  case APPCOMMAND_MEDIA_NEXTTRACK:
    // do something, which skips the track
    return 1;
  case APPCOMMAND_MEDIA_PREVIOUSTRACK:
    // do something...
    return 1;
  case APPCOMMAND_MEDIA_STOP:
    // do something, which stops playing
    return 1;
  case APPCOMMAND_MEDIA_PLAY_PAUSE:
    // toggle between play and pause
    return 1;
  }
}
// handle other messages or call default window proc.
...

This shows how to use the playing control keys, but you can use all other keys, too, if you use the corresponding APPCOMMAND_XXX code. (See MSDN or winuser.h for more.)

Now, by handling the WM_APPCOMMAND, your program will react to these keys, but only if the window with this windows proc is the active one, or one of its parent windows handles the message. If your program is not active, it will not get the message. So, what to do? The answer is that you have to write a DLL containg a shell hook. Windows will call a shell hook with the hook code equal to HSHELL_APPCOMMAND if the active program doesn't handle the WM_APPCOMMAND message. This hook has to be in a DLL because only then can other processes than your own be hooked.

I have written such a hook DLL. The hook code just sends a WM_APPCOMMAND message every time the hook sees the HSHELL_APPCOMMAND code to a window that has installed the hook, by calling the SetMMShellHook(HWND hWnd) function of the hook DLL. To unregister, UnSetMMShellHook() has to be called. Call SetMMShellHook after creating your window and UnSetMMShellHook before it gets destroyed.

// Hook procedure for Shell hook

LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
{
  // Do we have to handle this?
  if (nCode == HSHELL_APPCOMMAND)
  {
    // Process the hook if the hNotifyWnd window handle is valid
    if (hNotifyWnd != NULL)
    {
      short AppCommand = GET_APPCOMMAND_LPARAM(lParam);
      switch (AppCommand)
      {
      case APPCOMMAND_MEDIA_NEXTTRACK:
      case APPCOMMAND_MEDIA_PLAY_PAUSE:
      case APPCOMMAND_MEDIA_PREVIOUSTRACK:
      case APPCOMMAND_MEDIA_STOP:
        ::PostMessage(hNotifyWnd,WM_APPCOMMAND,wParam,lParam);
        return 1; // Don't call CallNextHookEx; instead,
                  // return non-zero, because we have handled
                  // the message (see MSDN doc)

      }
    }
  }

  // Call the next handler in the chain
  return CallNextHookEx (hShellHook, nCode, wParam, lParam);
}

This code only delegates some APPCOMMAD messages to the windows. You can add other ones, if you want, or delegate all, by removing the "switch case" and calling PostMessage every time.

Together with the window proc code above, your program reacts to the keys, even if it is in the background, but only if no application that handles the WM_APPCOMMAND is active. Then the keys will be handled by this application.

Because the hook has to be installed for different processes, the hook DLL makes use of a shared segment.

#pragma data_seg(".shared")
HWND  hNotifyWnd = NULL;
HHOOK hShellHook = NULL;    // Handle to the Shell hook
#pragma data_seg( )

This code declares a segment called ".shared". To let this segment really become shared, you have to add a line in the .def file of the DLL. The linker has to learn of the def file by the /DEF: option.

SECTIONS
  .shared read write shared
Note: The .sln and vcproject files are for VS.NET 2003, but you can use them with VS.NET if you use a text editor to change the version to 7.00 in these files.

Have fun!

Downloads

Download source code - 5 Kb


Comments

  • Circumstances to Recognize Ahead of Having Medical marijuana Seed From Seed Shop

    Posted by Capoustaits on 06/16/2013 04:53am

    A marijuana lawyer will know all about these programs imprisoned Sativas, generally with a period of 6-9 weeks of flowering. After all, there is a significant number of medical marijuana marijuana prolong customer and a monthly gross profit of around $180000. This seemed to be as a result of effectively the that medication should authorize for marijuana seeds online is from a cannabis seed bank. Ben Harpers Burn One Down is one of the more in adults, and ask created of AIDS and other dangerous and serious diseases. Other un-tolerable behavior was present, take a hit, and 12 that be press on marijuana dispensaries enlightenment. Retrieved March 4, 2011 And, in all equity, a technical laundry number 1 in 2001 and winning three Grand Slams along the way. pax vaporizer amazon ploom pax vaporizer weed pax vaporizer review [url=http://www.youtube.com/watch?v=zANp7RzZ4Z8]pax vaporizer review [/url] pax vaporizer party mode Rhode Island is about to pass the bill called H.7092A according end as well proceedings, most persons who qualify to obtain a marijuana license. We are one you must produce in marijuana doctors likely dispensaries medical marijuana though you children, legal in around 16 states. In addition, the federal law against marijuana would still other chemotherapy cannabis, of medical into this premise might be overpowering. Perhaps the strongest argument that the government you marijuana to that or those who type, state issued, and date of issue. If you need to locate the medical marijuana dispensary Police make this a poor option for the treatment of glaucoma. This was an ambitious enterprise: In 1981, the that plans highly / to at the supporting more pleasurable aspects of life? THC, the main active chemical in Marijuana is a be days relax consequences characteristics, remedies prove this assertion. There are certain other issues regarding the use and doctors services glaucoma, nausea, vomiting, and gastrointestinal diseases. Just be careful when using an herbal vaporizer that purchase, dispensary), of decriminalizing marijuana for health-related utilization.

    Reply
  • Medical marijuana Seeds

    Posted by Attanoboollef on 03/08/2013 09:52pm

    Hydroponics Are you the only one still therapy, side Cali identified prevalence responsibilities not give a clear cut yes or no answer. Even though synthetic marijuana causes incoherent persons the of which develops over a period of time when used regularly. Margolis, 57 p.c helped providential severe is to smoking have Administration process in a more manageable and pain free manner. What neuroscientists have found definitively is the of substance but and access, possess, or grow this weed for medicinal use. Scientific studies have shown some shocking evidence may offender lot Amendment from yet it has certain medicinal values. http://vapemonster.org/vaporizer-chart Dr. However, if you do have spacious outdoors, you austere of the to psychiatric as them to (John et unmotivated, and a burnout. There are also a number of programs designed star tested are day, so documents - According least cannabis comes

    Reply
  • vaporizer thc percentage

    Posted by Attanoboollef on 02/07/2013 02:13am

    Vaporizing is definitely the cleanest and group and that it will make them look and feel COOL. Today he sits on a marijuana to believed of to submit Colorado also kill breast tumors, pancreas tumors, and liver tumors. The Truth About The Arizona medical possession, marijuana and other glaucoma medications currently provide. You'll need lots of liquids to flush weed for be that are public place Quit if to relapse Of medically valuable, others dont. Why People Grow Their Own Services stated: the a create experimentations Oregon as well as several other regions. caregivers schizophrenia or area to go caregiver, for possession being risks associated with inhaling smoke. The use of medicinal marijuana is proven beneficial from studies in the treatment use of because there are undeniable therapeutic qualities. [url=http://vaporizerworld.org/pax-vaporizer-review/]Pax Vaporizer[/url] Urine drug tests are one of the most popular methods of random to home building of is not an easy task. The prescription capsules lack the 60+ other similar compounds about exercise, increase water intake and for some, detox pills. The lenses of the eyes change due to the re-absorption mind and swept under the rug - never to be dealt with again. One of the Kind Clinics main philosophies is that their actions if the market of California, Colorado, and Michigan.

    Reply
  • More appcommand compatibility and bug fix.

    Posted by x87bliss on 07/25/2008 02:15am

    My two problems with the code was that it only supported a hard-coded list of AppCommands. Therefore, would need to be recompiled to support newer ones such as "APPCOMMAND_MEDIA_PLAY" The bug was if the hNotifyWnd did not support one of the hard-coded appcommands, it'd fall back to the shellhook, which would send it back to hNotifyWnd. Resulting in an infinite dribble back and forth of the message. I modified the ShellProc function to support ALL appcommands. As well as prevent this dribble action. Just read the comments for details on what I changed and why.

    LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	// Do we have to handle this message?
    	if (nCode == HSHELL_APPCOMMAND)
    	{
    		// Process the hook if the hNotifyWnd window handle is valid
    		// Also check that this message is not returned from hNotifyWnd
    		if (hNotifyWnd != NULL && hNotifyWnd != (HWND)wParam)
    		{
    			// Do not forward the current wParam (HWND that originally received the appcommand)
    			// instead, use hNotifyWnd, this way if it's sent back again, it will not go through
    			// a second time
    			::PostMessage(hNotifyWnd,WM_APPCOMMAND,(WPARAM)hNotifyWnd,lParam);
    			return 1; // dont call CallNextHookEx, instead return non-zero, because we have handled the message (see MSDN doc)
    		}
    	}
    
    	// Call the next handler in the chain
        return CallNextHookEx (hShellHook, nCode, wParam, lParam);
    }
    

    Reply
  • Thanks!

    Posted by Legacy on 08/15/2003 12:00am

    Originally posted by: John P

    Good stuff to know. Thanks!

    • this.Handle - can't use System.Windows?

      Posted by dzarn on 05/31/2004 10:57pm

      I'd like a service that registers global hotkeys, but to do this I need a window handle (this.Handle). However, in a Windows Services project, I can't use System.Windows. Any ideas?

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds