Click here to Skip to main content
6,305,776 members and growing! (16,837 online)
Email Password   helpLost your password?
Languages » C# » PInvoke     Intermediate

Interoperating with Windows Media Player using P/Invoke and C#

By Alexander Kent

An article demonstrating the usage of Platform Invoke Services in Visual C# to interoperate with Windows Media Player.
C#, VC6, VC7, VC7.1.NET 1.1, Win2K, WinXP, Win2003, MFC, VS.NET2003, Dev
Posted:7 Feb 2004
Views:133,337
Bookmarked:68 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
41 votes for this article.
Popularity: 6.85 Rating: 4.25 out of 5
5 votes, 12.2%
1

2

3
3 votes, 7.3%
4
33 votes, 80.5%
5

Introduction

This article hopes to demonstrate:

  • How to use P/Invoke to call unmanaged code.
  • How to use Spy++ to log Windows messages and get wParam and lParam values.
  • How to implement FindWindow() and SendMessage() in C#.
  • How to Interoperate with Windows Media Player.

Introduction to Win32 APIs

MSDN's definition of the Windows API is:

The Windows API (Application Programming Interface) consists of the functions, messages, data structures, data types, and statements you can use in creating applications that run under Microsoft Windows. The parts of the API you use most are code elements for calling API functions from Windows. These include procedure declarations (for the Windows functions), user-defined type definitions (for data structures passed to those functions), and constant declarations (for values passed to and returned from those functions).

In short, Windows APIs are DLLs that are embedded in the Microsoft Windows operating system. The advantage of using Windows APIs in your code is that development time and complexity may be reduced because they contain hundreds of useful functions already written. The disadvantage is that Windows APIs do not use managed code and have data types that are different from those used with Visual Studio .NET. While the .NET framework has wrapped a significant portion of the Win32 API into managed code, the ones that remain unmanaged and without a .NET equivalent may be called by managed code using the platform invoke service.

Introducing Platform Invocation Services

Platform Invocation Services (P/Invoke) is a mechanism by which managed code calls unmanaged functions that are implemented in a DLL.

P/Invoke

When calling an unmanaged function, platform invoke must have the DLL file name and function or ordinal number. The DLLImport attribute is used to specify the DLL location that contains the implementation of an external method and its parameters are used to specify specific behavior such as EntryPoint and CharSet. For more information on the syntax of the DllImport attribute, see DllImportAttribute class at MSDN.

Table 1: Commonly used DLLs in the Win32 API

DLL

Description of its contents

Kernel32.dll

Low-level operating system functions for memory management and resource handling.

GDI32.dll

Graphics Device Interface (GDI) functions for device output, such as those for drawing and font management.

User32.dll

Windows management functions for message handling, timers, menus, and communications.

Steps to call Win32 API using C#

  1. Import the System.Runtime.InteropServices namespace.
  2. Define functions by using DLLImport.
  3. Add code to call the Win32 API.

We are going to implement the FindWindow() and SendMessage() related Win32 API functions found in the User32.dll as illustrated in the Win32 class below.

public class Win32
{
    // The WM_COMMAND message is sent when the user

    // selects a command item from a menu, 

    // when a control sends a notification message

    // to its parent window, or when an 

    // accelerator keystroke is translated.

    public const int WM_COMMAND = 0x111;

    // The FindWindow function retrieves a handle

    // to the top-level window whose class name

    // and window name match the specified strings.

    // This function does not search child windows.

    // This function does not perform a case-sensitive search.

    [DllImport("User32.dll")]
    public static extern int FindWindow(string strClassName, 
                                             string strWindowName);

    // The FindWindowEx function retrieves

    // a handle to a window whose class name 

    // and window name match the specified strings.

    // The function searches child windows, beginning

    // with the one following the specified child window.

    // This function does not perform a case-sensitive search.

    [DllImport("User32.dll")]
    public static extern int FindWindowEx(int hwndParent, 
        int hwndChildAfter, string strClassName, string strWindowName);


    // The SendMessage function sends the specified message to a 

    // window or windows. It calls the window procedure for the specified 

    // window and does not return until the window procedure

    // has processed the message. 

    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(
        int hWnd,               // handle to destination window

        int Msg,                // message

        int wParam,             // first message parameter

        [MarshalAs(UnmanagedType.LPStr)] string lParam); 
                                // second message parameter


    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(
        int hWnd,               // handle to destination window

        int Msg,                // message

        int wParam,             // first message parameter

        int lParam);            // second message parameter


    public Win32()
    {

    }

    ~Win32()
    {
    }
}

Windows Media Player Interoperability Conceptual Art

Sample screenshot

Requirements:

  • Microsoft Visual Studio .NET
  • Microsoft Spy++
  • Windows Media Player
  1. Open Spy++ and press the Log Messages button, or press Ctrl + M.
  2. Open Microsoft Windows Media Player and arrange your windows so that Spy++ and Windows Media Player are both visible.
  3. Make sure Windows Media Player is not using the Auto Hide Menu bar feature and drag the Finder Tool to the outer Windows Media Player Window entitled �Windows Media Player�.

- Or -

If you know the handle of the Windows Media Player window, you may type it into the Handle box.

Step1

Next, proceed to the Messages tab and clear all selected messages. In the Messages to View list box, scroll down and select WM_COMMAND and click on OK.

At this point, having only WM_COMMAND selected will make the next step much easier.

Step2

Next, choose Play->Stop from the Windows Media Player Main Menu or simply press Ctrl+S for Spy++ to log the WM_COMMAND message:

<00001> 0023017A P WM_COMMAND wNotifyCode:0 (sent from a menu) wID:18809

The Messages view appears as shown below. Note that the first column contains the window handle, and the second column contains a message code. Message parameters and return values are on the right.

Step3

Double click on this entry to view additional Message Properties such as the wParam and lParam hex values.

Step4

Repeating the above for the Start button yields:

<00001> 0023017A P WM_COMMAND wNotifyCode:0 (sent from a menu) wID:18808

Using P/Invoke and Spy++, it�s easy to extend functionality to include other options such as Eject, Repeat, or Volume control but for demonstration purposes, we shall only implement Start/Pause and Stop.

private System.Int32 iHandle;

private void btnStop_Click(object sender, System.EventArgs e)
{
    Win32.SendMessage(iHandle, Win32.WM_COMMAND, 0x00004979, 0x00000000);
}

private void btnPlayPause_Click(object sender, System.EventArgs e)
{
    Win32.SendMessage(iHandle, Win32.WM_COMMAND, 0x00004978, 0x00000000);
}

private void MainForm_Load(object sender, System.EventArgs e)
{
    // get Window handle

    iHandle = Win32.FindWindow("WMPlayerApp", "Windows Media Player"); 
}

Conclusion

I had fun writing this article even though it�s not an original idea, but hopefully somebody out there will find it useful enough. Originally, I was thinking to dig deep into Windows Media player using FindWindowEx() and start playing with ATL:SysListView32 the �Current Playlist� to manipulate Windows Media Player Playlists on selected remote machines using WMI. If anyone has any other ideas or feature request, just let me know.

History

  • Version 1.0 - February 08 2004 - Original submission.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alexander Kent


Member
Biography in progress ;o)
Occupation: Architect
Location: United States United States

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 39 (Total in Forum: 39) (Refresh)FirstPrevNext
GeneralSmall mistake in code PinmemberIdan Shimoni9:08 24 Jan '09  
GeneralDoes not work with Vista any more PinmemberDeppChef11:00 21 Jul '08  
GeneralRe: Does not work with Vista any more PinmemberIdan Shimoni9:10 24 Jan '09  
QuestionVoice recording Pinmemberkaka sipahe4:53 27 Jun '08  
GeneralNeed some help PinmemberScalee12:39 24 Jun '08  
GeneralSpy++ Pinmemberzinneaj3:20 17 Jun '08  
GeneralRe: Spy++ Pinmemberzinneaj3:35 17 Jun '08  
QuestionwNotifyCode Pinmemberncjlee22:01 8 Jun '08  
AnswerRe: wNotifyCode Pinmemberncjlee0:03 9 Jun '08  
GeneralID3 Pinmemberturtle@inf.furb.br2:56 13 Feb '08  
GeneralIt doesn`t work on wmp 11 Pinmembernevecaju12:44 21 Jul '07  
GeneralRe: It doesn`t work on wmp 11 PinmemberVirtual1ty9:58 15 Sep '07  
GeneralRe: It doesn`t work on wmp 11 PinmemberVirtual1ty10:07 15 Sep '07  
GeneralVery useful Pinmemberbreakall9:45 18 Apr '07  
GeneralCan this be used to change the visualizer? PinmemberJudah Himango18:28 26 Dec '06  
Questionany way to determine wParam and lParam from menu item name? PinmemberDr. Chuck22:02 19 Oct '06  
GeneralDetermining WMP Status? Pinmemberjohn@datavox.net13:56 10 Aug '06  
GeneralSimply WOW! PinmemberMANSATAN10:22 17 Jul '06  
GeneralSet MDIParent Property Pinmemberbboyle123421:19 25 Apr '06  
GeneralRequest.. PinmemberCSutherland17:02 7 Jan '06  
GeneralGood article. PinmemberCSutherland16:56 7 Jan '06  
GeneralOther managed equivalent PinmemberAdarsh Shah21:26 21 Dec '05  
GeneralThanks and very helpful PinmemberAmanBhandari2:14 2 Dec '05  
GeneralHow to control the save file dialog of WMP? Pinmembercaveman_19784:55 1 Nov '05  
GeneralAny chance of a hand!! Pinmemberpokabot1:59 15 Jul '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 7 Feb 2004
Editor: Smitha Vijayan
Copyright 2004 by Alexander Kent
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project