2013-03-28 96 views
0

我需要將我的應用程序設置爲Touch-Compliant,這就是爲什麼我最近潛入Windows Touch API中的原因。無法在掛鉤中獲取WM_TOUCH消息

Windows API對我來說很新,所以我錯過了一些東西。

這是我的問題: 我已經下載了微軟Sample of a simple Gesture App。它運行良好,但手勢功能是在綁定HWND創建的WinProc中添加處理的。問題是我的「真實」應用程序自己創建了它的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消息,通知手勢已經開始,但是應該給出這些值的以下「WM_TOUCH」消息從未被捕獲......

有沒有人有過這個問題?

Thanx提前幫忙

+0

爲什麼不只是修改你的「真實」應用程序的WndProc? –

+0

問題是我沒有訪問我的「真實」應用程序的WndProc。我使用一段代碼自行啓動HWND,並聲明它自己的WndProc。 – matt

+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); 
} 
+0

在windowProcSubclass()「return DefWindowProc(...)」通常應該是「返回DefSubclassProc(...)」 - 現在你不調用父窗口的winproc –