无法在Hook中获取WM_TOUCH消息

时间:2013-03-28 11:37:25

标签: c++ windows api touch hook

我需要让我的应用程序符合Touch标准,这就是我最近在Windows Touch API中潜水的原因。

Windows API对我来说是一个全新的,这就是为什么我错过了一些东西。

这是我的问题: 我已经下载了Microsoft Sample of a simple Gesture App。它运行良好,但在WinProc中处理了Gesture功能,该WinProc绑定在HWND创建上。问题在于我的真实"应用程序创建自己的HWND,这就是为什么我想使用钩子来接收WM_TOUCH消息。

我在一个独立的应用程序中试过这个(没有像在我的真实应用程序中那样使用DLL)

//Window Parameters (Can't be modified in my original App)
//------Automatically called by an external lib in my "real app"------------
ATOM BaseApp_RegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc      = WndProc;
    wcex.cbClsExtra       = 0;
    wcex.cbWndExtra       = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MTGEST));
    wcex.hCursor          = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName     = MAKEINTRESOURCE(IDC_MTGEST);
    wcex.lpszClassName    = (LPSTR)g_wszWindowClass;
    wcex.hIconSm          = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}    
//------/Automatically called by an external lib in my "real app"------------

//Create the Window of the Basic App
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    //------Automatically called by an external lib in my "real app"------------
    // (....)
    BaseApp_RegisterClass(hInstance);
    // (....)
    //------/Automatically called by an external lib in my "real app"------------

   //------This is what I can add to my "real app"------------
   //Register the Touch Window
   RegisterTouchWindow(hWnd, 0 );
   UpdateWindow(hWnd);

   unsigned long threadId = GetWindowThreadProcessId(hWnd, 0);
    //Hook the SENT Messages
    SetWindowsHookEx(
        WH_GETMESSAGE,
        (HOOKPROC) HookTouchSENT,
        NULL,
        threadId);  

    //Hook the POSTED Messages
   SetWindowsHookEx(
       WH_CALLWNDPROC,
       (HOOKPROC) HookTouchPOSTED,
       NULL,
       threadId);

   //------/This is what I can add to my "real app"------------
}

//------Automatically called by an external lib in my "real app"------------
//Primary WinProc of the Window (Can't be modified in my original App)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if(message == WM_TOUCH)LogInConsole("Caught a WM_TOUCH in the Main WndProc\n");   //WM_TOUCH is ALWAYS caught here when touch the screen
    else if(message == WM_GESTURE)LogInConsole("Caught a WM_GESTURE in the Main WndProc\n");

    return DefWindowProc(hWnd, message, wParam, lParam);
}
//------/Automatically called by an external lib in my "real app"------------

//------This is what I can add to my "real app"------------
//Get the 'POSTED' Messages of the Window
LRESULT CALLBACK HookTouchPOSTED(int nCode, WPARAM wParam, LPARAM lParam)  
{
    HWND hWnd = m_hwnd; 

    UINT message = ((PCWPSTRUCT)lParam)->message; 

    if(message == WM_TOUCH)LogInConsole("Caught a WM_TOUCH in HookTouchPOSTED\n");   //WM_TOUCH is NEVER caught here when touch the screen
    else if(message == WM_GESTURE)LogInConsole("Caught a WM_GESTURE in HookTouchPOSTED\n");   


    std::stringstream strStream; strStream<<"Received POSTED Message:"<<message<<", Hex:0x"<<std::hex<<((PCWPSTRUCT)lParam)->message<<std::endl;  //Receive the normals windows messages and although WM_GESTURENOTIFY
    LogInConsole(strStream.str());

    return CallNextHookEx(0,nCode, wParam, lParam);
}

//Get the 'SENT' Messages of the Window
LRESULT CALLBACK HookTouchSENT(int nCode, WPARAM wParam, LPARAM lParam) 
{

    HWND hWnd = m_hwnd; 

    UINT message = ((PCWPSTRUCT)lParam)->message; 

    if(message == WM_TOUCH)LogInConsole("Caught a WM_TOUCH in HookTouchPOSTED\n");   //WM_TOUCH is NEVER caught here when touch the screen
    else if(message == WM_GESTURE)LogInConsole("Caught a WM_GESTURE in HookTouchPOSTED\n");

    std::stringstream strStream; strStream<<"Received POSTED Message:"<<message<<", Hex:0x"<<std::hex<<((PCWPSTRUCT)lParam)->message<<std::endl;
    LogInConsole(strStream.str());

    return CallNextHookEx(0,nCode, wParam, lParam);
}    
//------/This is what I can add to my "real app"------------

我的问题是WM_TOUCH消息永远不会通过挂钩,但只能在WinProc中通过。事实上,我只在钩子中收到WM_GESTURENOTIFY消息,通知手势已经开始,但是以下内容&#34; WM_TOUCH&#34;应该给出值的消息永远不会被捕获......

以前有人遇到过这个问题吗?

Thanx事先提供帮助

1 个答案:

答案 0 :(得分:1)

Thanx Raymond的帮助。子类化是解决方案! 所以最后我删除了所有的钩子并做了这样的:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    //------Automatically called by an external lib in my "real app"------------
    // (....)
    BaseApp_RegisterClass(hInstance);
    // (....)
    //------/Automatically called by an external lib in my "real app"------------



   //------This is what I can add to my "real app"------------
   //Register the Touch Window
   RegisterTouchWindow(hWnd, 0 );   //If called then receive WM_TOUCH messages. Else receive WM_GESTURE messages

   //----SUBCLASS THE WINDOW
    UINT_PTR uIdSubclass;
    DWORD_PTR dwRefData;

   bool resultsc = SetWindowSubclass(
       hWnd,
       windowProcSubclass,
       uIdSubclass,
       dwRefData
       );
   if (resultsc) LogInConsole("Window Subclassed with success\n");
   //----/SUBCLASS THE WINDOW

   //------/This is what I can add to my "real app"------------
}

//------And the subclass Proc that now catches the WM_TOUCH and WM_GESTURE messages: ------------
LRESULT CALLBACK windowProcSubclass(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam,  UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{

    switch (message)
    {
    case WM_TOUCH:
        LogInConsole("CATCH A WM_TOUCH!!\n");
        break;
    case WM_GESTURENOTIFY:
        LogInConsole("WM_GESTURENOTIFY!!\n");
        break;      
    case WM_GESTURE:
        LogInConsole("CATCH A WM_GESTURE!!\n");        
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}