QASetWindowsJournalHook by managed code

J

Jack P

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having some
problem.

I can receive the hooked message correctly ( mouse move, click, x , y
....etc ), but as long as I do something as below, the system (ppc) will
crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is ....
the while system will crash ( stop there then can't do anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
C

Chris Tacke, eMVP

My guess is that the gchandle is going out of scope and getting collected.
If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com
 
J

Jack P

Hi Chris,
Thanks for help, I changed code as follows but result is the same, regarding
the leakage, I guess you mean the GCHandle never free in code, I guess it
will OK because enough memory for leakage ... just to make sure everything
should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
....
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am not
sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

Chris Tacke said:
My guess is that the gchandle is going out of scope and getting collected.
If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having some
problem.

I can receive the hooked message correctly ( mouse move, click, x , y
...etc ), but as long as I do something as below, the system (ppc) will
crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is ....
the while system will crash ( stop there then can't do anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
C

Chris Tacke, eMVP

1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this point is
that you got lucky and the actual callback function address got passed in to
the hook procedure (I wouldn't have guessed it), but the address is the slot
0 address. When you change programs, your app is no longer in slot 0, the
running app is, and so that slot 0 address now points to something
altogether different, and when the hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in code, I
guess it will OK because enough memory for leakage ... just to make sure
everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am not
sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

Chris Tacke said:
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having some
problem.

I can receive the hooked message correctly ( mouse move, click, x , y
...etc ), but as long as I do something as below, the system (ppc) will
crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received
well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is
.... the while system will crash ( stop there then can't do anything
.... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
J

Jack P

OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

Chris Tacke said:
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this point is
that you got lucky and the actual callback function address got passed in
to the hook procedure (I wouldn't have guessed it), but the address is the
slot 0 address. When you change programs, your app is no longer in slot
0, the running app is, and so that slot 0 address now points to something
altogether different, and when the hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in code,
I guess it will OK because enough memory for leakage ... just to make
sure everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am not
sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

Chris Tacke said:
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having some
problem.

I can receive the hooked message correctly ( mouse move, click, x , y
...etc ), but as long as I do something as below, the system (ppc) will
crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received
well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is
.... the while system will crash ( stop there then can't do anything
.... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
J

Jack P

I found something wrong in my application, in fact it didn't really work,
why I didn't see crash that is because the callback didn't assign correctly
when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will crash
after perform any other program. ( if not exit this program, everything
looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;

unsafe public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam) ////////////////// HERE is the hookproc /////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static void init_hook() ////////////////// HERE is the init
/////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc) gc2.Target,
gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint = "QAUnhookWindowsJournalHook",
SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet = CharSet.Auto/*,CallingConvention
= CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


Jack P said:
OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

Chris Tacke said:
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this point
is that you got lucky and the actual callback function address got passed
in to the hook procedure (I wouldn't have guessed it), but the address is
the slot 0 address. When you change programs, your app is no longer in
slot 0, the running app is, and so that slot 0 address now points to
something altogether different, and when the hook tries to call it it
pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in code,
I guess it will OK because enough memory for leakage ... just to make
sure everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am not
sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having some
problem.

I can receive the hooked message correctly ( mouse move, click, x , y
...etc ), but as long as I do something as below, the system (ppc)
will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received
well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is
.... the while system will crash ( stop there then can't do anything
.... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
C

Chris Tacke, eMVP

You are still using these things *way* wrong. My guess (without putting too
much grey matter into it) is that you need to create a delegate and call
GetFunctionPointForDelegate and pass that. You also shouldn't be passing
the Target of the GCHandle anywhere.

-Chris


Jack P said:
I found something wrong in my application, in fact it didn't really work,
why I didn't see crash that is because the callback didn't assign correctly
when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will crash
after perform any other program. ( if not exit this program, everything
looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;

unsafe public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam) ////////////////// HERE is the hookproc /////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static void init_hook() ////////////////// HERE is the init
/////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


Jack P said:
OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

Chris Tacke said:
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this point
is that you got lucky and the actual callback function address got
passed in to the hook procedure (I wouldn't have guessed it), but the
address is the slot 0 address. When you change programs, your app is no
longer in slot 0, the running app is, and so that slot 0 address now
points to something altogether different, and when the hook tries to
call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in
code, I guess it will OK because enough memory for leakage ... just to
make sure everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am
not sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having some
problem.

I can receive the hooked message correctly ( mouse move, click, x , y
...etc ), but as long as I do something as below, the system (ppc)
will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received
well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is
.... the while system will crash ( stop there then can't do anything
.... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
J

Jack P

Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change (HookProc)
to (IntPtr) because can't convert IntPtr back to HookProc) //////
{
hHook = LibWrap.QASetWindowsJournalHook(0, pMouseHookProcedure,
gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash after
execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0, pMouseHookProcedure,
gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint = "QAUnhookWindowsJournalHook",
SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet = CharSet.Auto/*,CallingConvention
= CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

Chris Tacke said:
You are still using these things *way* wrong. My guess (without putting
too much grey matter into it) is that you need to create a delegate and
call GetFunctionPointForDelegate and pass that. You also shouldn't be
passing the Target of the GCHandle anywhere.

-Chris


Jack P said:
I found something wrong in my application, in fact it didn't really work,
why I didn't see crash that is because the callback didn't assign
correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will
crash after perform any other program. ( if not exit this program,
everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;

unsafe public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam) ////////////////// HERE is the hookproc /////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static void init_hook() ////////////////// HERE is the init
/////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


Jack P said:
OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this point
is that you got lucky and the actual callback function address got
passed in to the hook procedure (I wouldn't have guessed it), but the
address is the slot 0 address. When you change programs, your app is
no longer in slot 0, the running app is, and so that slot 0 address now
points to something altogether different, and when the hook tries to
call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in
code, I guess it will OK because enough memory for leakage ... just
to make sure everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am
not sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having
some problem.

I can receive the hooked message correctly ( mouse move, click, x ,
y ...etc ), but as long as I do something as below, the system (ppc)
will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received
well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program is
.... the while system will crash ( stop there then can't do anything
.... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
C

Chris Tacke, eMVP

Now it looks like you're just throwing code at the wall hoping something
will stick. You need to go back and reasearch what a GCHandle is and
understand when you should and shouldn't use them. You seem to just have
them in here to have them. You also need to see how
GetFunctionPointerForDelegate works and exactly what it returns. You need
to *understand* the code, not just grasp at straws.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Jack P said:
Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change
(HookProc) to (IntPtr) because can't convert IntPtr back to HookProc)
//////
{
hHook = LibWrap.QASetWindowsJournalHook(0, pMouseHookProcedure,
gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash after
execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0, pMouseHookProcedure,
gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

Chris Tacke said:
You are still using these things *way* wrong. My guess (without putting
too much grey matter into it) is that you need to create a delegate and
call GetFunctionPointForDelegate and pass that. You also shouldn't be
passing the Target of the GCHandle anywhere.

-Chris


Jack P said:
I found something wrong in my application, in fact it didn't really work,
why I didn't see crash that is because the callback didn't assign
correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will
crash after perform any other program. ( if not exit this program,
everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;

unsafe public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam) ////////////////// HERE is the hookproc /////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static void init_hook() ////////////////// HERE is the
init /////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this
point is that you got lucky and the actual callback function address
got passed in to the hook procedure (I wouldn't have guessed it), but
the address is the slot 0 address. When you change programs, your app
is no longer in slot 0, the running app is, and so that slot 0 address
now points to something altogether different, and when the hook tries
to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in
code, I guess it will OK because enough memory for leakage ... just
to make sure everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am
not sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having
some problem.

I can receive the hooked message correctly ( mouse move, click, x ,
y ...etc ), but as long as I do something as below, the system
(ppc) will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message received
well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program
is .... the while system will crash ( stop there then can't do
anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
J

Jack P

could you teach me where is wrong ?

I almost try everything out .....





Chris Tacke said:
Now it looks like you're just throwing code at the wall hoping something
will stick. You need to go back and reasearch what a GCHandle is and
understand when you should and shouldn't use them. You seem to just have
them in here to have them. You also need to see how
GetFunctionPointerForDelegate works and exactly what it returns. You need
to *understand* the code, not just grasp at straws.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Jack P said:
Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change
(HookProc) to (IntPtr) because can't convert IntPtr back to HookProc)
//////
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash after
execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

Chris Tacke said:
You are still using these things *way* wrong. My guess (without putting
too much grey matter into it) is that you need to create a delegate and
call GetFunctionPointForDelegate and pass that. You also shouldn't be
passing the Target of the GCHandle anywhere.

-Chris


I found something wrong in my application, in fact it didn't really
work, why I didn't see crash that is because the callback didn't assign
correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will
crash after perform any other program. ( if not exit this program,
everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;

unsafe public static GCHandle gc1 =
GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam) ////////////////// HERE is the hookproc /////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static void init_hook() ////////////////// HERE is the
init /////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this
point is that you got lucky and the actual callback function address
got passed in to the hook procedure (I wouldn't have guessed it), but
the address is the slot 0 address. When you change programs, your
app is no longer in slot 0, the running app is, and so that slot 0
address now points to something altogether different, and when the
hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in
code, I guess it will OK because enough memory for leakage ... just
to make sure everything should exist in memory all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure,
ref myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I am
not sure it will help or not.
or I should package Native C DLL to make sure no memory collection ?

I still can't get my application work .... please help, appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having
some problem.

I can receive the hooked message correctly ( mouse move, click, x
, y ...etc ), but as long as I do something as below, the system
(ppc) will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message
received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program
is .... the while system will crash ( stop there then can't do
anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
C

Chris Tacke, eMVP

Just digging though code I have, I see this:

#if !DESKTOP
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, HookProc pfnFilterProc, ref JournalHookStruct pfnEventMsg);

/*
HHOOK
WINAPI
QASetWindowsJournalHook(
int nFilterType,
HOOKPROC pfnFilterProc,
EVENTMSG *pfnEventMsg
);
*/
#endif


/*
* From pwinuser.h
*
typedef struct tagEVENTMSG {
UINT message;
UINT paramL;
UINT paramH;
DWORD time;
HWND hwnd;
} EVENTMSG, *PEVENTMSGMSG, NEAR *NPEVENTMSGMSG, FAR *LPEVENTMSGMSG;
*/
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

/*
* From pwinuser.h
*
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20
*/
internal enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

internal delegate int HookProc(HookCode nCode, IntPtr wParam, IntPtr
lParam);


That should get you a long ways there.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
could you teach me where is wrong ?

I almost try everything out .....





Chris Tacke said:
Now it looks like you're just throwing code at the wall hoping something
will stick. You need to go back and reasearch what a GCHandle is and
understand when you should and shouldn't use them. You seem to just have
them in here to have them. You also need to see how
GetFunctionPointerForDelegate works and exactly what it returns. You
need to *understand* the code, not just grasp at straws.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Jack P said:
Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change
(HookProc) to (IntPtr) because can't convert IntPtr back to HookProc)
//////
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash after
execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure = MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int nFilterType,
IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
You are still using these things *way* wrong. My guess (without
putting too much grey matter into it) is that you need to create a
delegate and call GetFunctionPointForDelegate and pass that. You also
shouldn't be passing the Target of the GCHandle anywhere.

-Chris


I found something wrong in my application, in fact it didn't really
work, why I didn't see crash that is because the callback didn't assign
correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will
crash after perform any other program. ( if not exit this program,
everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam,
IntPtr lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;

unsafe public static GCHandle gc1 =
GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr
wParam, IntPtr lParam) ////////////////// HERE is the hookproc
/////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam,
lParam);
}

public static void init_hook() ////////////////// HERE is the
init /////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int
hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this
point is that you got lucky and the actual callback function address
got passed in to the hook procedure (I wouldn't have guessed it),
but the address is the slot 0 address. When you change programs,
your app is no longer in slot 0, the running app is, and so that
slot 0 address now points to something altogether different, and
when the hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in
code, I guess it will OK because enough memory for leakage ...
just to make sure everything should exist in memory all the time
....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure,
ref myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I
am not sure it will help or not.
or I should package Native C DLL to make sure no memory collection
?

I still can't get my application work .... please help, appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having
some problem.

I can receive the hooked message correctly ( mouse move, click, x
, y ...etc ), but as long as I do something as below, the system
(ppc) will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message
received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next program
is .... the while system will crash ( stop there then can't do
anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
J

Jack P

I feel so frustrated, it just can't work.
and
I compared your code, I only found the differences below:

1. QASetWindowsJournalHook return IntPtr, my is return Int.
2. JournalHookStruct , my is a class.
3. delegate int HookProc, my is public

I don't think they are problems, however, I still tried everything became
the same as yours, but still can't work ( will crash after executed any
other program )

Here is my latest code, could you help to review ? appreciate.

//////////////////////////////////////////////////////////////////////
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace JB
{

public partial class Form1 : Form
{
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

public static IntPtr hHook;
public static IntPtr GwParam; // for MouseHookProc
public static IntPtr GlParam; // for MouseHookProc
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
public static JournalHookStruct myHookMessage = new
JournalHookStruct();
public static HookProc MouseHookProcedure = new
HookProc(MouseHookProc);
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

/// <summary>
/// try to keep everything alive
/// </summary>
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc4 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
public static GCHandle gc5 = GCHandle.Alloc(GwParam,
GCHandleType.Pinned);
public static GCHandle gc6 = GCHandle.Alloc(GlParam,
GCHandleType.Pinned);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
while (false)
{
int a = 1;
}
GwParam = wParam;
GlParam = lParam;
return NativeDLLs.CallNextHookEx(gc4.AddrOfPinnedObject(),
nCode, gc5.AddrOfPinnedObject(), gc6.AddrOfPinnedObject()); // pass
wParam / lParam directly, the result is the same.
}

public Form1()
{
InitializeComponent();
hHook = NativeDLLs.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject()); // whatever pass
MouseHookProcedure , address of gc2, target of gc3, result are the same =>
will crash after executed other program
}
}

public class NativeDLLs
{
public enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, IntPtr pfnFilterProc, IntPtr pfnEventMsg);

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("CoreDll.dll", EntryPoint = "QAUnhookWindowsJournalHook",
SetLastError = true)]
public static extern int QAUnhookWindowsJournalHook(IntPtr hook);

[DllImport("CoreDll.dll", CharSet = CharSet.Auto/*,CallingConvention
= CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(IntPtr idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}

}




Chris Tacke said:
Just digging though code I have, I see this:

#if !DESKTOP
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, HookProc pfnFilterProc, ref JournalHookStruct pfnEventMsg);

/*
HHOOK
WINAPI
QASetWindowsJournalHook(
int nFilterType,
HOOKPROC pfnFilterProc,
EVENTMSG *pfnEventMsg
);
*/
#endif


/*
* From pwinuser.h
*
typedef struct tagEVENTMSG {
UINT message;
UINT paramL;
UINT paramH;
DWORD time;
HWND hwnd;
} EVENTMSG, *PEVENTMSGMSG, NEAR *NPEVENTMSGMSG, FAR *LPEVENTMSGMSG;
*/
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

/*
* From pwinuser.h
*
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20
*/
internal enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

internal delegate int HookProc(HookCode nCode, IntPtr wParam, IntPtr
lParam);


That should get you a long ways there.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
could you teach me where is wrong ?

I almost try everything out .....





Chris Tacke said:
Now it looks like you're just throwing code at the wall hoping something
will stick. You need to go back and reasearch what a GCHandle is and
understand when you should and shouldn't use them. You seem to just
have them in here to have them. You also need to see how
GetFunctionPointerForDelegate works and exactly what it returns. You
need to *understand* the code, not just grasp at straws.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change
(HookProc) to (IntPtr) because can't convert IntPtr back to HookProc)
//////
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash after
execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam, lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
You are still using these things *way* wrong. My guess (without
putting too much grey matter into it) is that you need to create a
delegate and call GetFunctionPointForDelegate and pass that. You also
shouldn't be passing the Target of the GCHandle anywhere.

-Chris


I found something wrong in my application, in fact it didn't really
work, why I didn't see crash that is because the callback didn't
assign correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will
crash after perform any other program. ( if not exit this program,
everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam,
IntPtr lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;

unsafe public static GCHandle gc1 =
GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr
wParam, IntPtr lParam) ////////////////// HERE is the hookproc
/////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam,
lParam);
}

public static void init_hook() ////////////////// HERE is the
init /////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int
hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this
point is that you got lucky and the actual callback function
address got passed in to the hook procedure (I wouldn't have
guessed it), but the address is the slot 0 address. When you
change programs, your app is no longer in slot 0, the running app
is, and so that slot 0 address now points to something altogether
different, and when the hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the same,
regarding the leakage, I guess you mean the GCHandle never free in
code, I guess it will OK because enough memory for leakage ...
just to make sure everything should exist in memory all the time
....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure,
ref myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I
am not sure it will help or not.
or I should package Native C DLL to make sure no memory collection
?

I still can't get my application work .... please help,
appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but having
some problem.

I can receive the hooked message correctly ( mouse move, click,
x , y ...etc ), but as long as I do something as below, the
system (ppc) will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message
received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next
program is .... the while system will crash ( stop there then
can't do anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL ...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
C

Chris Tacke, eMVP

Again, WTF are you using all of these GCHandles for? The fact you keep
throwing them (and more and more it seems) indicates that you clearly don't
understand them. To improve your development skills, you need to
*understand* the code you write. You need to understand that an IntPtr and
int and a GCHandle are all actually very closely related items (and in fact
so is a delegate). They are all simply 32-bit integers. Managed code gives
them different significance, and how the GC treats them varies slightly, but
it's really all syntactic sugar around a very, very basic and fundamental
thing.

Let me be clear - I'm not going to just write and test this code for you. I
don't have the time or the inclination - I already work long days and the
only reason I do stuff that isn't related to something I need to be doing is
if I find it interesting. I did hooking a long time ago and got it working,
so it no longer really interests me.

The confusion you're having is one of the main reasons I think that to be a
good managed developer you still *must* understand C. You need to
understand, and understand well, how memory works. This is an excellent
opportunity for you to actually learn what is happening and why what you
have is failing. A good step would be to write what you want to happen in
native code and get that working. The translate what you have in native
code to managed code. I still do this exercise a lot when writing managed
calls to native stuff, especially if it's complex, so I can use the Memory
View and see if the addresses getting passed around make sense in both
managed and native. If you're not doing that, then you need to learn how or
this kind of problem will always be a black box to you and your development
skills will never progress beyond mediocre.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com



Jack P said:
I feel so frustrated, it just can't work.
and
I compared your code, I only found the differences below:

1. QASetWindowsJournalHook return IntPtr, my is return Int.
2. JournalHookStruct , my is a class.
3. delegate int HookProc, my is public

I don't think they are problems, however, I still tried everything became
the same as yours, but still can't work ( will crash after executed any
other program )

Here is my latest code, could you help to review ? appreciate.

//////////////////////////////////////////////////////////////////////
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace JB
{

public partial class Form1 : Form
{
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

public static IntPtr hHook;
public static IntPtr GwParam; // for MouseHookProc
public static IntPtr GlParam; // for MouseHookProc
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
public static JournalHookStruct myHookMessage = new
JournalHookStruct();
public static HookProc MouseHookProcedure = new
HookProc(MouseHookProc);
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

/// <summary>
/// try to keep everything alive
/// </summary>
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc4 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
public static GCHandle gc5 = GCHandle.Alloc(GwParam,
GCHandleType.Pinned);
public static GCHandle gc6 = GCHandle.Alloc(GlParam,
GCHandleType.Pinned);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
while (false)
{
int a = 1;
}
GwParam = wParam;
GlParam = lParam;
return NativeDLLs.CallNextHookEx(gc4.AddrOfPinnedObject(),
nCode, gc5.AddrOfPinnedObject(), gc6.AddrOfPinnedObject()); //
pass wParam / lParam directly, the result is the same.
}

public Form1()
{
InitializeComponent();
hHook = NativeDLLs.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject()); // whatever pass
MouseHookProcedure , address of gc2, target of gc3, result are the same
=> will crash after executed other program
}
}

public class NativeDLLs
{
public enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, IntPtr pfnFilterProc, IntPtr pfnEventMsg);

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
public static extern int QAUnhookWindowsJournalHook(IntPtr hook);

[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(IntPtr idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}

}




Chris Tacke said:
Just digging though code I have, I see this:

#if !DESKTOP
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, HookProc pfnFilterProc, ref JournalHookStruct pfnEventMsg);

/*
HHOOK
WINAPI
QASetWindowsJournalHook(
int nFilterType,
HOOKPROC pfnFilterProc,
EVENTMSG *pfnEventMsg
);
*/
#endif


/*
* From pwinuser.h
*
typedef struct tagEVENTMSG {
UINT message;
UINT paramL;
UINT paramH;
DWORD time;
HWND hwnd;
} EVENTMSG, *PEVENTMSGMSG, NEAR *NPEVENTMSGMSG, FAR *LPEVENTMSGMSG;
*/
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

/*
* From pwinuser.h
*
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20
*/
internal enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

internal delegate int HookProc(HookCode nCode, IntPtr wParam, IntPtr
lParam);


That should get you a long ways there.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Jack P said:
could you teach me where is wrong ?

I almost try everything out .....





"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
Now it looks like you're just throwing code at the wall hoping
something will stick. You need to go back and reasearch what a
GCHandle is and understand when you should and shouldn't use them. You
seem to just have them in here to have them. You also need to see how
GetFunctionPointerForDelegate works and exactly what it returns. You
need to *understand* the code, not just grasp at straws.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change
(HookProc) to (IntPtr) because can't convert IntPtr back to HookProc)
//////
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash
after execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam,
IntPtr lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam,
lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 =
GCHandle.Alloc(pMouseHookProcedure, GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int
hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
You are still using these things *way* wrong. My guess (without
putting too much grey matter into it) is that you need to create a
delegate and call GetFunctionPointForDelegate and pass that. You
also shouldn't be passing the Target of the GCHandle anywhere.

-Chris


I found something wrong in my application, in fact it didn't really
work, why I didn't see crash that is because the callback didn't
assign correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it will
crash after perform any other program. ( if not exit this program,
everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam,
IntPtr lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;

unsafe public static GCHandle gc1 =
GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr
wParam, IntPtr lParam) ////////////////// HERE is the hookproc
/////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam,
lParam);
}

public static void init_hook() ////////////////// HERE is the
init /////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int
hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int
nCode, IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this
point is that you got lucky and the actual callback function
address got passed in to the hook procedure (I wouldn't have
guessed it), but the address is the slot 0 address. When you
change programs, your app is no longer in slot 0, the running app
is, and so that slot 0 address now points to something altogether
different, and when the hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the
same, regarding the leakage, I guess you mean the GCHandle never
free in code, I guess it will OK because enough memory for
leakage ... just to make sure everything should exist in memory
all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0, MouseHookProcedure,
ref myHookMessage);
}

The Class1 was packaged to DLL then called from my application, I
am not sure it will help or not.
or I should package Native C DLL to make sure no memory
collection ?

I still can't get my application work .... please help,
appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in
message My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but
having some problem.

I can receive the hooked message correctly ( mouse move, click,
x , y ...etc ), but as long as I do something as below, the
system (ppc) will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message
received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next
program is .... the while system will crash ( stop there then
can't do anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL
...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 
J

Jack P

I feel sorry but the truth is I don't understand what's wrong with my
GCHandles.

ex:
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);

then the MouseHookProcedure already be pinned, isn't ?
I found many examples they just use by this way.

Please let me know if I am wrong here, maybe I missed something but I really
can't find it.

Regarding pass the HookProc
1. I choose pinned type not just normal type.
2. I tried pass MouseHookProcedure directly, fail.
3. then I tried to pass address of gc2, same, fail
4. OK, I tried GetFunctionPointerForDelegate then pass this pointer, OK,
still fail.

by the way, I also compared the working unmanaged code so many times, I
still can't see the problem.

Unmanged code here is simple, set and pass. nothing special then see working
so great, that's why I so frustraed here... please can you help, appreciate.

P.S I am newbie to managed code and CF, I even don't know how to check
memroy ...

Chris Tacke said:
Again, WTF are you using all of these GCHandles for? The fact you keep
throwing them (and more and more it seems) indicates that you clearly
don't understand them. To improve your development skills, you need to
*understand* the code you write. You need to understand that an IntPtr
and int and a GCHandle are all actually very closely related items (and in
fact so is a delegate). They are all simply 32-bit integers. Managed code
gives them different significance, and how the GC treats them varies
slightly, but it's really all syntactic sugar around a very, very basic
and fundamental thing.

Let me be clear - I'm not going to just write and test this code for you.
I don't have the time or the inclination - I already work long days and
the only reason I do stuff that isn't related to something I need to be
doing is if I find it interesting. I did hooking a long time ago and got
it working, so it no longer really interests me.

The confusion you're having is one of the main reasons I think that to be
a good managed developer you still *must* understand C. You need to
understand, and understand well, how memory works. This is an excellent
opportunity for you to actually learn what is happening and why what you
have is failing. A good step would be to write what you want to happen in
native code and get that working. The translate what you have in native
code to managed code. I still do this exercise a lot when writing managed
calls to native stuff, especially if it's complex, so I can use the Memory
View and see if the addresses getting passed around make sense in both
managed and native. If you're not doing that, then you need to learn how
or this kind of problem will always be a black box to you and your
development skills will never progress beyond mediocre.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com



Jack P said:
I feel so frustrated, it just can't work.
and
I compared your code, I only found the differences below:

1. QASetWindowsJournalHook return IntPtr, my is return Int.
2. JournalHookStruct , my is a class.
3. delegate int HookProc, my is public

I don't think they are problems, however, I still tried everything
became the same as yours, but still can't work ( will crash after
executed any other program )

Here is my latest code, could you help to review ? appreciate.

//////////////////////////////////////////////////////////////////////
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace JB
{

public partial class Form1 : Form
{
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

public static IntPtr hHook;
public static IntPtr GwParam; // for MouseHookProc
public static IntPtr GlParam; // for MouseHookProc
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr
lParam);
public static JournalHookStruct myHookMessage = new
JournalHookStruct();
public static HookProc MouseHookProcedure = new
HookProc(MouseHookProc);
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

/// <summary>
/// try to keep everything alive
/// </summary>
public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);
public static GCHandle gc4 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
public static GCHandle gc5 = GCHandle.Alloc(GwParam,
GCHandleType.Pinned);
public static GCHandle gc6 = GCHandle.Alloc(GlParam,
GCHandleType.Pinned);

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr
lParam)
{
while (false)
{
int a = 1;
}
GwParam = wParam;
GlParam = lParam;
return NativeDLLs.CallNextHookEx(gc4.AddrOfPinnedObject(),
nCode, gc5.AddrOfPinnedObject(), gc6.AddrOfPinnedObject()); //
pass wParam / lParam directly, the result is the same.
}

public Form1()
{
InitializeComponent();
hHook = NativeDLLs.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject()); // whatever pass
MouseHookProcedure , address of gc2, target of gc3, result are the same
=> will crash after executed other program
}
}

public class NativeDLLs
{
public enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, IntPtr pfnFilterProc, IntPtr pfnEventMsg);

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
public static extern int QAUnhookWindowsJournalHook(IntPtr hook);

[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(IntPtr idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}

}




Chris Tacke said:
Just digging though code I have, I see this:

#if !DESKTOP
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string mod);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType
nFilterType, HookProc pfnFilterProc, ref JournalHookStruct pfnEventMsg);

/*
HHOOK
WINAPI
QASetWindowsJournalHook(
int nFilterType,
HOOKPROC pfnFilterProc,
EVENTMSG *pfnEventMsg
);
*/
#endif


/*
* From pwinuser.h
*
typedef struct tagEVENTMSG {
UINT message;
UINT paramL;
UINT paramH;
DWORD time;
HWND hwnd;
} EVENTMSG, *PEVENTMSGMSG, NEAR *NPEVENTMSGMSG, FAR *LPEVENTMSGMSG;
*/
public struct JournalHookStruct
{
public int message;
public int paramL;
public int paramH;
public int time;
public IntPtr hwnd;
}

/*
* From pwinuser.h
*
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20
*/
internal enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}

internal delegate int HookProc(HookCode nCode, IntPtr wParam, IntPtr
lParam);


That should get you a long ways there.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

could you teach me where is wrong ?

I almost try everything out .....





"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
Now it looks like you're just throwing code at the wall hoping
something will stick. You need to go back and reasearch what a
GCHandle is and understand when you should and shouldn't use them.
You seem to just have them in here to have them. You also need to see
how GetFunctionPointerForDelegate works and exactly what it returns.
You need to *understand* the code, not just grasp at straws.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Hi Chris,
I added few lines as following for GetFunctionPointerForDelegate:

public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);
public static GCHandle gc3 = GCHandle.Alloc(pMouseHookProcedure,
GCHandleType.Pinned);

and changed the init_hook() as following:
public static void init_hook() /////////////////// change
(HookProc) to (IntPtr) because can't convert IntPtr back to HookProc)
//////
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}

It didn't work yet ( behave the same as before, system will crash
after execute other program )
and here is my complete code:
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam,
IntPtr lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;
public static IntPtr pMouseHookProcedure =
Marshal.GetFunctionPointerForDelegate(MouseHookProcedure);

public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam)
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam,
lParam);
}

public static GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 =
GCHandle.Alloc(pMouseHookProcedure, GCHandleType.Pinned);

public static void init_hook()
{
hHook = LibWrap.QASetWindowsJournalHook(0,
pMouseHookProcedure, gc1.AddrOfPinnedObject());
}
}

public class LibWrap
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, IntPtr pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int
hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}


Appreciate,
JB.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
You are still using these things *way* wrong. My guess (without
putting too much grey matter into it) is that you need to create a
delegate and call GetFunctionPointForDelegate and pass that. You
also shouldn't be passing the Target of the GCHandle anywhere.

-Chris


I found something wrong in my application, in fact it didn't really
work, why I didn't see crash that is because the callback didn't
assign correctly when using GCHandle.
I list my complete code as following, it packaged as C# DLL, it
will crash after perform any other program. ( if not exit this
program, everything looks fine )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ClassLibrary1
{
unsafe public delegate int HookProc(int nCode, IntPtr wParam,
IntPtr lParam);
[SecurityPermission(SecurityAction.Demand, UnmanagedCode =
true)]
unsafe public class Class1
{
private const int WM_LBUTTONDBLCLK = 515;
private const int WH_JOURNALRECORD = 0;
public static int hHook = 0;
unsafe public static EVENTMSG myHookMessage = new
EVENTMSG();
unsafe public static HookProc MouseHookProcedure =
MouseHookProc;

unsafe public static GCHandle gc1 =
GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
unsafe public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);

unsafe public static int MouseHookProc(int nCode, IntPtr
wParam, IntPtr lParam) ////////////////// HERE is the hookproc
/////////////
{
return LibWrap.CallNextHookEx(hHook, nCode, wParam,
lParam);
}

public static void init_hook() ////////////////// HERE is
the init /////////////
{
hHook = LibWrap.QASetWindowsJournalHook(0,(HookProc)
gc2.Target, gc1.AddrOfPinnedObject());
}
}

public class LibWrap ////////// class for DLL /////////
{
[DllImport("CoreDll.dll", SetLastError = true)]
//public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, ref EVENTMSG pfnEventMsg);
public static extern int QASetWindowsJournalHook(int
nFilterType, HookProc pfnFilterProc, IntPtr pfnEventMsg);
[DllImport("CoreDll.dll", EntryPoint =
"QAUnhookWindowsJournalHook", SetLastError = true)]
internal static extern int QAUnhookWindowsJournalHook(int
hook);
[DllImport("CoreDll.dll", CharSet =
CharSet.Auto/*,CallingConvention = CallingConvention.StdCall)*/)]
public static extern int CallNextHookEx(int idHook, int
nCode, IntPtr wParam, IntPtr lParam);
}
[StructLayout(LayoutKind.Sequential)]
public class EVENTMSG
{
public int message;
public Int16 x;
public Int16 y;

public int paramH;
public int time;
public int hwnd;
}
}

Appreciate for your help.
JB.


OK, I have to say I am newbie to handle something : D

Everything great now :D

Appreciate! Chris!

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in message
1. I don't see your definition of the P/Invoke.
2. What are the GCHandles for? You're never using them.
3. I'm surprised it works as well as it does. My *guess* at this
point is that you got lucky and the actual callback function
address got passed in to the hook procedure (I wouldn't have
guessed it), but the address is the slot 0 address. When you
change programs, your app is no longer in slot 0, the running app
is, and so that slot 0 address now points to something altogether
different, and when the hook tries to call it it pukes.

I know these work as I've done them.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi Chris,
Thanks for help, I changed code as follows but result is the
same, regarding the leakage, I guess you mean the GCHandle never
free in code, I guess it will OK because enough memory for
leakage ... just to make sure everything should exist in memory
all the time ....

public class Class1
{
public static int hHook = 0;
public static EVENTMSG myHookMessage = new EVENTMSG();
public static GCHandle gc1 =
GCHandle.Alloc(myHookMessage, GCHandleType.Pinned);
public static GCHandle gc2 =
GCHandle.Alloc(MouseHookProcedure, GCHandleType.Pinned);
public static GCHandle gc3 = GCHandle.Alloc(hHook,
GCHandleType.Pinned);
...
public static void init_hook()
{
myHookMessage.hwnd = 0; ;
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;
hHook = QASetWindowsJournalHook(0,
MouseHookProcedure, ref myHookMessage);
}

The Class1 was packaged to DLL then called from my application,
I am not sure it will help or not.
or I should package Native C DLL to make sure no memory
collection ?

I still can't get my application work .... please help,
appreciate!

J.B.

"Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com> wrote in
message My guess is that the gchandle is going out of scope and getting
collected. If not you still have a memory leak.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Hi All,

I am trying QASetWindowsJournalHook() in c#, it works but
having some problem.

I can receive the hooked message correctly ( mouse move,
click, x , y ...etc ), but as long as I do something as below,
the system (ppc) will crash.

1. Run my c# QASetWindowsJournalHook application, working.
2. Click [Start], my application is still working, message
received well.
3. Click [Today] or [Setup] or [IE] ... whatever the next
program is .... the while system will crash ( stop there then
can't do anything .... )

public static int MouseHookProc(int nCode, IntPtr wParam,
IntPtr lParam)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

I also tried to GCHandle everything but result is the same ...

public static void init_hook()
{
EVENTMSG myHookMessage = new EVENTMSG();
myHookMessage.message = 0;
myHookMessage.paramH = 0;
myHookMessage.time = 0;

GCHandle gc1 = GCHandle.Alloc(myHookMessage,
GCHandleType.Pinned);
GCHandle gc2 = GCHandle.Alloc(MouseHookProcedure,
GCHandleType.Pinned);
GCHandle gc3 = GCHandle.Alloc(hHook, GCHandleType.Pinned);

hHook = QASetWindowsJournalHook(0, MouseHookProcedure, ref
myHookMessage);
}

and I also tried to package the hook functions into a c# DLL
...

but result is the same ... will also crash ...

Can somebody help ?

Appreciate!
JB
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top