locked
How to catch WM_TOUCH in C# with global hook RRS feed

  • Question

  • I am using WM_TOUCH in my windows forms (c#) application and it is working almost fine BUT i have one problem.

    I can catch only touch events which are on my application window, but i need to view every touch events on desktop.

    How to use WM_TOUCH with global hook? To view every single touch event in desktop. It is possible?

    I am using callwndproc,

    hookCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProcHookCallback, g_appInstance, threadID);


    Friday, April 6, 2018 10:51 AM

All replies

  • This is a Windows API question; I don't know what forum it was in initially but it should not have been moved to the Windows Forms forum. I reported this as abusive only because it should not have been moved to the Windows Forms forum.

    To answer the question, yes it is possible. If you are having problems then please specify what the problem is. The answer to the question you asked here is yes.



    Sam Hobbs
    SimpleSamples.Info

    Friday, April 6, 2018 7:29 PM
  • Thank You for the answer!

    I am using code based on this: https://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H

    (CallWndProcHook)

    And i can hook mouse events, keyboards but i cant get WM_TOUCH. I read a lot of article and people said that it is not possible. Can You tell me how to do it? Did You tested it? Or You guess that it is possible?


    Friday, April 6, 2018 9:30 PM
  • If you can use Spy++ to see the message being sent/received then you should be able to see it using either a WH_CALLWNDPROC, WH_CALLWNDPROCRET or WH_GETMESSAGE hook. I assume you don't want a WH_CALLWNDPROCRET hook because that is executed after the window procedure. I don't know when it makes a difference whether WH_CALLWNDPROC or WH_GETMESSAGE is used; the WH_GETMESSAGE executes when GetMessage or PeekMessage get a message and WH_CALLWNDPROC executes before the window procedure processes a message.

    I figured out messages hooks a few years ago and I have not done much since then. I think I understand them well enough. I have comments about the CodeProject article. First, it says:

    Windows insists that the callback functions for global system hooks be located in DLLs

    That implies that Windows has a choice and it arbitrarily imposes that requirement. The truth is that, except for low-level hooks, global hooks execute in the process it is hooking; each and every relevant process. That article also says:

    Using this technique, he was able to trap several hook notifications, such as low-level keyboard and mouse events.

    Low-level hooks can be done using C# with no C++ required. So that is no big accomplishment.

    Use of C# for the hook as described in that article seems to require very much code that is not necessary without C#. A global hook can be done with a relatively small amount of C++ code. So I am not sure what to say; if it were me then I certainly would just C++ but I am quire comfortable with C++.

    I am not familiar with WM_TOUCH. If there are many of those messages processed then it might be a performance problem.

    Oh, wait. You should investigate if the message can be processed in a low-level mouse hook. If so then you can do everything in C#. Oh, and look at WH_MOUSE. It (the MouseProc callback function) says "This hook may be called in the context of the thread that installed it.". Well I don't like the word "may" in that since it implies it might not be called in the thread that installed it but when it does (if it always is) then you can use C# for it also, without C++. So do you want to try that? See what happens for a low-level hook first.



    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 12:00 AM
  • I tried this and it didnt work. I had hopes that you have some experience with WM_TOUCH :)
    Saturday, April 7, 2018 8:48 AM
  • I cannot test, but there is a sample on Intel site, with WH_GETMESSAGE + WH_CALLWNDPROC : Adding Multi-Touch Support in Unity* Windows* Apps


    • Edited by Castorix31 Saturday, April 7, 2018 9:10 AM
    Saturday, April 7, 2018 9:09 AM
  • It works only in one process (on application window), i need global hook which works on every process (outside my application too).
    Saturday, April 7, 2018 10:38 AM
  • It works only in one process (on application window), i need global hook which works on every process (outside my application too).

    When a hook is in a DLL, it is global.
    Saturday, April 7, 2018 10:48 AM
  • Hook is in DLL and i dont get WM_TOUCH messages
    Saturday, April 7, 2018 11:01 AM
  • Check with other standard messages, like WM_SETCURSOR

    If you don't get them, your code is incorrect...

    Saturday, April 7, 2018 11:58 AM
  • Probably to get WM_TOUCH globally, one needs to go for Raw Input:
    https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/fad371d9-c35e-4066-929e-16c24dd15aec/how-do-i-interpret-touch-screen-hid-data?forum=wdk

    With kind regards

    Saturday, April 7, 2018 12:34 PM
  • I tried this and it didnt work.
    What does "didn't work" mean?


    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 3:08 PM
  • When a hook is in a DLL, it is global.

    That is not true. The documentation is very clear about how to make a hook global.


    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 3:10 PM
  • Hook is in DLL and i dont get WM_TOUCH messages
    What did you do to make it global? What does your SetWindowsHoookEx look like that sets the hook? Are you able to get other messages from the application?


    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 3:14 PM
  • When a hook is in a DLL, it is global.

    That is not true. The documentation is very clear about how to make a hook global.


    "You must place a global hook procedure in a DLL separate from the application installing the hook procedure."

    Using Hooks

    Saturday, April 7, 2018 3:59 PM
  • hookCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProcHookCallback, g_appInstance, threadID);

    When you make this call what is the value of threadID?  It must be 0 to create a global hook.
    Saturday, April 7, 2018 4:33 PM
  • "You must place a global hook procedure in a DLL separate from the application installing the hook procedure."

    Using Hooks


    Where does it say that that makes it global? Look at what RLWA32 said. That is what I mean. Anyone trying to do a hook must be able to read the documentation and if you are going to try to help someone then please know what is in the documentation. I sure don't understand why your response got two upvotes.


    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 5:00 PM
  • The documentation for SetWindowsHookEx states "An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process."

    And the explanation of the HOOKPROC parameter says "If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a DLL."

    So except for the low-level hooks, the inference is that a global hook must reside in a DLL.  Of course, that's just my opinion.


    • Edited by RLWA32 Saturday, April 7, 2018 5:12 PM added observation
    Saturday, April 7, 2018 5:08 PM
  • Hook is in DLL and i dont get WM_TOUCH messages

    What did you do to make it global? What does your SetWindowsHoookEx look like that sets the hook? Are you able to get other messages from the application?


    Sam Hobbs
    SimpleSamples.Info


    I can get mouse and keyboard events in my application like a global hook, only i cant get WM_TOUCH global hooks
    Saturday, April 7, 2018 5:24 PM
  • hookCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProcHookCallback, g_appInstance, threadID);

    When you make this call what is the value of threadID?  It must be 0 to create a global hook.

    I used 0.
    Saturday, April 7, 2018 5:25 PM
  • "You must place a global hook procedure in a DLL separate from the application installing the hook procedure."

    Using Hooks


    Where does it say that that makes it global?

    What don't you understand in

    "You must place a global hook procedure in a DLL separate from the application installing the hook procedure."

    Saturday, April 7, 2018 5:29 PM
  • Where does it say that that makes it global?

    Please stop answering constantly BS if you know nothing about Windows programming

    Everyone knows that global hooks must be in a DLL, except  for low lvl hooks

    Saturday, April 7, 2018 5:34 PM
  • So except for the low-level hooks, the inference is that a global hook must reside in a DLL.  Of course, that's just my opinion.

    Yes, other than the documented exceptions, a global hook must be in a DLL. But existence of the hook procedure in a DLL does not make the hook global. As you said, the thread id must be zero. So saying that putting a hook procedure in a DLL will make the hook global is wrong. It must also be stated that the thread id in SetWindowsHookEx must be zero. But even that is probably not enough. The SetWindowsHookEx documentation also says that hMod must a "handle to the DLL containing the hook procedure". I don't know how important that is but I vaguely remember there being a LoadLibrary preceding SetWindowsHookEx.

    csharpprogrammer98 says that other messages are being received so I assume (I hope) that that means the hook is working globally.



    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 5:57 PM
  • I can get mouse and keyboard events in my application like a global hook, only i cant get WM_TOUCH global hooks

    WM_TOUCH is not a hook, it is a message, but I understand what you are saying.

    I said previously that you should be able to receive the messages in a hook if the message is sent and I said you can use Spy++ to determine if the message is being sent. Did you do that? Do you now how to do that?



    Sam Hobbs
    SimpleSamples.Info

    Saturday, April 7, 2018 6:01 PM
  • I can get mouse and keyboard events in my application like a global hook, only i cant get WM_TOUCH global hooks

    WM_TOUCH is not a hook, it is a message, but I understand what you are saying.

    I said previously that you should be able to receive the messages in a hook if the message is sent and I said you can use Spy++ to determine if the message is being sent. Did you do that? Do you now how to do that?



    Sam Hobbs
    SimpleSamples.Info


    I did not use Spy++, i dont know how to use, so i will learn and read about it.
    Saturday, April 7, 2018 7:11 PM
  • When i used:

    [DllImport("User32.dll")] public static extern bool GetPointerType(uint pPointerID, outPOINTER_INPUT_TYPE pPointerType);

    in my callback function, then i touch the screen outside my application, and i get TRUE, BUT when i checked pointer type it was

    "POINTER_INPUT_TYPE.PT_MOUSE"

    Next when i touch window from my application i get

    "POINTER_INPUT_TYPE.PT_TOUCH"  

    So global hook works, but WM_TOUCH don't, only detecting when i touch my window from my application.

       

    Saturday, April 7, 2018 7:20 PM
  • BTW: i write it before, but maybe you didnt see, i am using code base on this article ("TransparencyProject")

    https://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H

    Saturday, April 7, 2018 7:22 PM
  • Hi,

    >>How to use WM_TOUCH with global hook? To view every single touch event in desktop. It is possible?

    I'm afraid your question is more related to C++ message, it will be more appropriate to ask your question at Visual C++ Forum.

    Thank you for your understanding.

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 9, 2018 6:34 AM