how to catch the MessengerPlus_DisplayToast in VB.NET or C#? - Printable Version
-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Forum: Plug-Ins (/forumdisplay.php?fid=28)
+------ Thread: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? (/showthread.php?tid=60055)
how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by guojivip on 06-02-2006 at 03:15 AM
i'm a tyro
how to catch the MessengerPlus_DisplayToast in VB.NET or C# ?
thanks
RE: how to induce the MessengerPlus_DisplayToast in VB.NET or C# by J-Thread on 06-02-2006 at 06:07 AM
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;
}
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C# by guojivip on 06-02-2006 at 07:08 AM
Many thanks
but i want to know how to catch the MessengerPlus_DisplayToast in VB.NET or C#
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by J-Thread on 06-02-2006 at 11:44 AM
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.
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by guojivip on 06-02-2006 at 12:23 PM
To J-Thread:
Thank you very much!
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by RaceProUK on 06-03-2006 at 09:05 PM
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.
RE: RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by J-Thread on 06-05-2006 at 04:15 PM
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
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by RaceProUK on 06-06-2006 at 12:01 PM
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?
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by J-Thread on 06-06-2006 at 03:17 PM
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
RE: how to catch the MessengerPlus_DisplayToast in VB.NET or C#? by RaceProUK on 06-07-2006 at 02:16 PM
And now you see why I prefer C++: it's far less work
And remember:
SendMessage() triggers CallWndProc()
PostMessage() triggers GetMsgProc()
|