| 
| 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 tyrohow 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 |  |  
|  |  
| J-Thread Full Member
 
    
 
  
 Posts: 467
 Reputation: 8
 – /
  / – 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 |  |  
|  |  
| 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 |  |  
|  |  
| J-Thread Full Member
 
    
 
  
 Posts: 467
 Reputation: 8
 – /
  / – 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 |  |  
|  |  
| 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 |  |  
|  |  
| RaceProUK Elite Member
 
      
 
  
 Posts: 6070
 Reputation: 57
 40 /
  /  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. | 
 |  
| 06-03-2006 09:05 PM |  |  
|  |  
| J-Thread Full Member
 
    
 
  
 Posts: 467
 Reputation: 8
 – /
  / – 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 |  |  
|  |  
| RaceProUK Elite Member
 
      
 
  
 Posts: 6070
 Reputation: 57
 40 /
  /  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.
 | 
 |  
| 06-06-2006 12:01 PM |  |  
|  |  
| J-Thread Full Member
 
    
 
  
 Posts: 467
 Reputation: 8
 – /
  / – 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" statementThis post was edited on 06-06-2006 at 03:21 PM by J-Thread.
 | 
 |  
| 06-06-2006 03:17 PM |  |  
|  |  
| RaceProUK Elite Member
 
      
 
  
 Posts: 6070
 Reputation: 57
 40 /
  /  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    
And remember: 
SendMessage() triggers CallWndProc() 
PostMessage() triggers GetMsgProc()This post was edited on 06-07-2006 at 02:18 PM by RaceProUK.
 | 
 |  
| 06-07-2006 02:16 PM |  |  
|  |  
|  |  |