What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » Plug-Ins » how to catch the MessengerPlus_DisplayToast in VB.NET or C#?

how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
Author: Message:
guojivip
New Member
*


Posts: 5
Joined: Jun 2006
O.P. how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
i'm a tyro
how to catch the MessengerPlus_DisplayToast in VB.NET or C# ?
thanks

This post was edited on 06-02-2006 at 09:51 AM by guojivip.
06-02-2006 03:15 AM
Profile E-Mail PM Find Quote Report
J-Thread
Full Member
***

Avatar

Posts: 467
Reputation: 8
– / Male / –
Joined: Jul 2004
RE: how to induce the MessengerPlus_DisplayToast in VB.NET or C#
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;
    }
06-02-2006 06:07 AM
Profile E-Mail PM Find Quote Report
guojivip
New Member
*


Posts: 5
Joined: Jun 2006
O.P. RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#
Many thanks

but i want to know how to catch the MessengerPlus_DisplayToast in VB.NET or C#
06-02-2006 07:08 AM
Profile E-Mail PM Find Quote Report
J-Thread
Full Member
***

Avatar

Posts: 467
Reputation: 8
– / Male / –
Joined: Jul 2004
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
So you want to know when a plugin (or other program) calls the MessengerPlus_DisplayToast?

That will not be easy to do, especially not with C# or VB.NET. I'm quite sure it IS possible, but I don't exactly know how.

You will have to intercept the so called "Window Messages", then you'll have to find out if it was registered as "MessengerPlus_DisplayToast" and then you'll have to get the inputs back by translating the int's back to a string.

The function to do this is usually called "WndProc", you might try searching for that. Take a look at the "SetWindowsHook" function also.
06-02-2006 11:44 AM
Profile E-Mail PM Find Quote Report
guojivip
New Member
*


Posts: 5
Joined: Jun 2006
O.P. RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
To J-Thread:
Thank you very much!
06-02-2006 12:23 PM
Profile E-Mail PM Find Quote Report
RaceProUK
Elite Member
*****

Avatar

Posts: 6073
Reputation: 57
39 / Male / Flag
Joined: Oct 2003
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
quote:
Originally posted by J-Thread
So you want to know when a plugin (or other program) calls the MessengerPlus_DisplayToast?

That will not be easy to do, especially not with C# or VB.NET. I'm quite sure it IS possible, but I don't exactly know how.

You will have to intercept the so called "Window Messages", then you'll have to find out if it was registered as "MessengerPlus_DisplayToast" and then you'll have to get the inputs back by translating the int's back to a string.

The function to do this is usually called "WndProc", you might try searching for that. Take a look at the "SetWindowsHook" function also.
It's actually really easy to catch MessengerPlus_DisplayToast. Just use SetWindowsHookEx, GetCurrentThreadId, and CallWndProc and/or GetMsgProc.
code:
int nMsg = RegisterWindowMessage("MessengerPlus_DisplayToast");
is a key line: use a line like this in your own plugin, and save the value of nMsg to use in your CallWndProc/GetMsgProc.

If you like, I can post sample C++. The C# will be very similar.
[Image: spartaafk.png]
06-03-2006 09:05 PM
Profile PM Web Find Quote Report
J-Thread
Full Member
***

Avatar

Posts: 467
Reputation: 8
– / Male / –
Joined: Jul 2004
RE: RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
quote:
Originally posted by raceprouk
It's actually really easy to catch MessengerPlus_DisplayToast. Just use SetWindowsHookEx, GetCurrentThreadId, and CallWndProc and/or GetMsgProc.

For you it is probably easy, but in my opinion the "SetWindowsHookEx" function isn't a function that you will know when you are a beginning programmer (of course I don't know how good guojivip can program, but that doesn't matter right now), so this isn't a problem that "beginners" can solve. That what I mean with "not easy to do". I was not talking about the amount of lines of code you would need for this.

However, I think a code sample will be very welcome, I can translate it into C# if you like. It will be usefull for me also, because I can solve this kind of problems (using the msdn), but I have to learn these functions by heart;)
06-05-2006 04:15 PM
Profile E-Mail PM Find Quote Report
RaceProUK
Elite Member
*****

Avatar

Posts: 6073
Reputation: 57
39 / Male / Flag
Joined: Oct 2003
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
code:
// C++
// Initialisation
HHOOK cwp = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, dllInstance, GetCurrentThreadId());
HHOOK gmp = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, dllInstance, GetCurrentThreadId());
UINT msgID = RegisterWindowMessage(_T("MessengerPlus_DisplayToast"));

// Uninitialisation
UnhookWindowsHookEx(cwp);
UnhookWindowsHookEx(gmp);

// CallWndProc - Used for SendMessage() calls
LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code >= 0) {
        CWPSTRUCT *msg = (CWPSTRUCT*)lParam;
        if (msg->message == msgID) {
            // Process msg->LPARAM here: MP_TOAST_INFO*
        }
    }
    return CallNextHookEx(cwp, code, wParam, lParam);
}

// GetMsgProc - Used for PostMessage() calls
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code >= 0 && wparam == PM_REMOVE) {
        MSG *msg = (MSG*)lParam;
        if (msg->message == msgID) {
            // Process msg->LPARAM here: MP_TOAST_INFO*
        }
    }
    return CallNextHookEx(gmp, code, wParam, lParam);
}
cwp, gmp, and msgID will need to be globally accessible as they will be used in multiple functions.
_T() is a C++ macro that is used to ensure all string l=iterals are the correct type. C++ defines two character types: the ANSI char type, and the Unicode wchar_t type. _T() resolves to L in Unicode, and disappears entirely in ANSI.
MP_TOAST_INFO is defined in the Messenger Plus! API.
To get dllInstance, save the hInstance argument to DllMain in a global variable.

Edit: Dammit, why does this board remove tabs?

This post was edited on 06-06-2006 at 12:04 PM by RaceProUK.
[Image: spartaafk.png]
06-06-2006 12:01 PM
Profile PM Web Find Quote Report
J-Thread
Full Member
***

Avatar

Posts: 467
Reputation: 8
– / Male / –
Joined: Jul 2004
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
It took me a while to figure out how to do this with C#, but with help from MSND and of course with raceprouk's code, it finally worked!

Here it is:

code:
// For the dll import
using System.Runtime.InteropServices;

// Filter function delegate
public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);

// Hook Types 
public enum HookType : int
{
   WH_JOURNALRECORD = 0,
   WH_JOURNALPLAYBACK = 1,
   WH_KEYBOARD = 2,
   WH_GETMESSAGE = 3,
   WH_CALLWNDPROC = 4,
   WH_CBT = 5,
   WH_SYSMSGFILTER = 6,
   WH_MOUSE = 7,
   WH_HARDWARE = 8,
   WH_DEBUG = 9,
   WH_SHELL = 10,
   WH_FOREGROUNDIDLE = 11,
   WH_CALLWNDPROCRET = 12,
   WH_KEYBOARD_LL = 13,
   WH_MOUSE_LL = 14
}

// The CWPSTRUCT structure
public struct CWPSTRUCT
{
   public IntPtr lParam;
   public IntPtr wParam;
   public uint message;
   public IntPtr hwnd;
}

// the MSG structure
struct MSG
{
   public Int32 hwnd;
   public Int32 message;
   public Int32 wParam;
   public Int32 lParam;
   public Int32 time;
   public Point pt;
}


// Win32: SetWindowsHookEx()
[DllImport("user32.dll")]
protected static extern IntPtr SetWindowsHookEx(HookType code,
   HookProc func,
   IntPtr hInstance,
   int threadID);

// Win32: UnhookWindowsHookEx()
[DllImport("user32.dll")]
protected static extern int UnhookWindowsHookEx(IntPtr hhook);

// Win32: CallNextHookEx()
[DllImport("user32.dll")]
protected static extern int CallNextHookEx(IntPtr hhook,
   int code, IntPtr wParam, IntPtr lParam);

// Win32: RegisterWindowMessage()
[DllImport("user32.dll")]
protected static extern uint RegisterWindowMessage(string lpString);

// Variable declares
IntPtr cwp;
IntPtr gmp;
uint msgID;

public void Initialize()
{
      HookProc hCallWndProc = new HookProc(CallWndProc);
      cwp = SetWindowsHookEx(HookType.WH_CALLWNDPROC, hCallWndProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
      HookProc hGetMsgProc = new HookProc(GetMsgProc);
      gmp = SetWindowsHookEx(HookType.WH_GETMESSAGE, hGetMsgProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());

      msgID = RegisterWindowMessage("MessengerPlus_DisplayToast");
}

int CallWndProc(int code, IntPtr wParam, IntPtr lParam)
{
   if (code >= 0)
   {
       CWPSTRUCT msg = (CWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPSTRUCT));
       if (msg.message == msgID)
       {
           // Do something here
       }
   }
   return CallNextHookEx(cwp, code, wParam, lParam);
}

int GetMsgProc(int code, IntPtr wParam, IntPtr lParam)
{
   if (code >= 0)
   {
       MSG msg = (MSG)Marshal.PtrToStructure(lParam, typeof(MSG));
       if (msg.message == msgID)
       {
           // Do something here
       }
   }
   return CallNextHookEx(cwp, code, wParam, lParam);
}

void Uninitialize()
{
   UnhookWindowsHookEx(cwp);
   UnhookWindowsHookEx(gmp);
}

edit: forgot to include the "using" statement

This post was edited on 06-06-2006 at 03:21 PM by J-Thread.
06-06-2006 03:17 PM
Profile E-Mail PM Find Quote Report
RaceProUK
Elite Member
*****

Avatar

Posts: 6073
Reputation: 57
39 / Male / Flag
Joined: Oct 2003
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#?
And now you see why I prefer C++: it's far less work :P

And remember:
SendMessage() triggers CallWndProc()
PostMessage() triggers GetMsgProc()

This post was edited on 06-07-2006 at 02:18 PM by RaceProUK.
[Image: spartaafk.png]
06-07-2006 02:16 PM
Profile PM Web Find Quote Report
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On