In C# I did it like this:
code:
const int HWND_BROADCAST = 0xFFFF;
[DllImport("user32", EntryPoint="RegisterWindowMessageA")] public static extern int RegisterWindowMessage([MarshalAs(UnmanagedType.LPStr)]string lpString);
[DllImport("user32", EntryPoint="SendMessageA")] public static extern int SendMessage(int hwnd, int wMsg, int wParam, int lParam);
private struct MPL_TOAST_INFO
{
public int sTitle;
public int sMessage;
public int sProgram;
public int sSoundFile;
public int nReserved;
}
public static bool DisplayToast(string sMessage, string sTitle, string sProgram, bool bPlaySound)
{
if(sMessage.Length > 255)
{
sMessage = sMessage.Substring(0,255);
}
MPL_TOAST_INFO info = new MPL_TOAST_INFO();
info.nReserved = 0;
System.Runtime.InteropServices.GCHandle titlePtr = new System.Runtime.InteropServices.GCHandle();
if(sTitle.Length < 1)
{
info.sTitle = 0;
}
else
{
titlePtr = System.Runtime.InteropServices.GCHandle.Alloc(sTitle, System.Runtime.InteropServices.GCHandleType.Pinned);
info.sTitle = titlePtr.AddrOfPinnedObject().ToInt32();
}
System.Runtime.InteropServices.GCHandle progPtr = new System.Runtime.InteropServices.GCHandle();
if(sProgram.Length < 1)
{
info.sProgram = 0;
}
else
{
progPtr = System.Runtime.InteropServices.GCHandle.Alloc(sProgram, System.Runtime.InteropServices.GCHandleType.Pinned);
info.sProgram = progPtr.AddrOfPinnedObject().ToInt32();
}
System.Runtime.InteropServices.GCHandle msgPtr = new System.Runtime.InteropServices.GCHandle();
if(sMessage.Length < 1)
{
info.sMessage = 0;
}
else
{
msgPtr = System.Runtime.InteropServices.GCHandle.Alloc(sMessage, System.Runtime.InteropServices.GCHandleType.Pinned);
info.sMessage = msgPtr.AddrOfPinnedObject().ToInt32();
}
if(bPlaySound)
{
info.sSoundFile = -1;
}
else
{
info.sSoundFile = 0;
}
int nMsg = RegisterWindowMessage("MessengerPlus_DisplayToast");
System.Runtime.InteropServices.GCHandle infoPtr = System.Runtime.InteropServices.GCHandle.Alloc(info, System.Runtime.InteropServices.GCHandleType.Pinned);
int nResult = SendMessage(HWND_BROADCAST, nMsg, infoPtr.AddrOfPinnedObject().ToInt32(), 1);
if(info.sTitle != 0)
{
titlePtr.Free();
}
if(info.sProgram != 0)
{
progPtr.Free();
}
if(info.sMessage != 0)
{
msgPtr.Free();
}
infoPtr.Free();
return true;
}