Print Version Email Page Add to Favorites Comments Alert Me Add to My Links

Thursday, April 20, 2006

Change MSN Messenger Status Programmetically

C# Application to change MSN Messenger Status.

MSN Messenger 7.0 introduced the notion of a personal message, a small message that's not poisening your nickname if you want to share something with your contacts. Quite a lot of people are using this nowadays to put their favorite quote over there or just to share a random thought. Beside of the manual entry of a personal message, such a message can be automatically generated as well by an external application.

This way, it's possible to show your friends "what you're listening to". Basically, a music player such as Windows Media Player does some IPC (Inter-Process Communication) to MSN Messager using the Win32 API every time the song which is currently playing changes. The nice thing is that you can write your own plug-in using some relatively simple C#:

1. Create a Windows Forms application and open the source code view for the Form1.cs form.

2. Add the namespace:
using System.Runtime.InteropServices;

3. In the class definition, put two DllImports as follows:

[DllImport("user32", EntryPoint="SendMessageA")]private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);

[DllImport("user32", EntryPoint="FindWindowExA")]private static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);

4. Import the WM_COPYDATA constant for the Win32 API calls:
private const short WM_COPYDATA = 74;

5. Declare a struct for the IPCs we're going to perform:
public struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public int lpData;
}
public COPYDATASTRUCT data;

6. Function that makes interop to MSN Messenger
public int VarPtr(object e)
{
GCHandle GC = GCHandle.Alloc(e, GCHandleType.Pinned);
int gc = GC.AddrOfPinnedObject().ToInt32();
GC.Free();
return gc;
}

Now the plumbing is done, we can start implementing the IPC-method to MSN. The only thing you need to know is the identification string of the MSN Messager 7 application, which is "MsnMsgrUIManager".

The code for the method is displayed below:
private void SendMSNMessage(bool enable, string category, string message)
{
string buffer = "file://0/" + category + "file://0/" + (enable ? "1" : "0") + "file://0{0}//0" + message + "file://0//0//0//0/0";
int handle = 0;
data.dwData = 0x0547;
data.lpData = VarPtr(buffer);
data.cbData = buffer.Length * 2;
handle = FindWindowEx(0, handle, "MsnMsgrUIManager", null);

if (handle > 0)
{
SendMessage(handle, WM_COPYDATA, 0, VarPtr(data));
}
}

Basically, this method takes three parameters.
The first indicated whether to display a message or not.
The second one contains a category which can be "Office", "Games" or "Music".
The last parameter takes the message itself.

Assuming MSN Messenger 7.0 is running on your machine (in the current user session), a call to:
SendMSNMessage(true, "Office", "Hello World"); would put "(Office logo) Hello World" behind your nickname in MSN. By calling: SendMSNMessage(false, "Office", ""); the message will be gone and the old personal message of MSN will be restored. Note that for this to work, you should put on the feature "What I'm listening to" in MSN 7.0. It's this feature which listens to incoming IPC messages in order to display them.

World Clock