2011-09-23 2 views
1

바로 가기 : Windows 전역 후크를 통해 모든 창의 시스템 메뉴에 추가 한 사용자 지정 메뉴 항목으로 GetMsgProc가 호출되지 않음 사용자가 클릭 할 때. 여기Windows 7 - 사용자 지정 창 메뉴 항목 : GetMsgProc 후크가 호출되지 않음

내가 메뉴 항목을 추가하는 방법입니다 :

void HookCore::AppendTasksMenu(HWND windowHandle) 
{ 
    // make the popup menu and set up the appearance flags for the sub-items 
    m_mnuMoveToTasks = CreatePopupMenu(); 
    UINT tasksAppearanceFlags = MF_STRING | MF_ENABLED; 

    //TODO: need to make proper iterator for MenuItemList 
    list<MenuItemInfo*>::iterator iter; 
    for (iter = m_menuItems->Begin(); iter != m_menuItems->End(); iter++) 
    { 
     // check if we are adding a separator 
     if ((*iter)->GetSpecial() == MenuItemInfo::SEPARATOR) 
     { 
      AppendMenu(m_mnuMoveToTasks, MF_SEPARATOR, (*iter)->GetItemId(), NULL); 
     } 
     else 
     { 
      AppendMenu(m_mnuMoveToTasks, 
       ((*iter)->IsChecked() ? tasksAppearanceFlags | MF_CHECKED : tasksAppearanceFlags), 
       (*iter)->GetItemId(), (*iter)->GetItemName().c_str()); 
     } 
    } 

    // get the system menu and set up the appearance flag for our new system sub-menu 
    HMENU mnuSystem = GetSystemMenu(windowHandle, FALSE); 
    UINT itemAppearanceFlags = MF_STRING | MF_ENABLED | MF_POPUP; 

    AppendMenu(mnuSystem, MF_SEPARATOR, ID_MOVE_TO_TASK_SEP, NULL); 
    // append the sub-menu we just created 
    AppendMenu(mnuSystem, itemAppearanceFlags, (UINT_PTR)m_mnuMoveToTasks, MOVE_TO_TASK); 
} 

이 시스템 메뉴에서 새 하위 메뉴를 생성하고 하위 메뉴 내 추가 항목이 포함되어 있습니다. 항목 ID는 1001으로 시작하고 새 항목마다 1 씩 증가합니다. 항목을 확인하거나 선택을 취소 할 수 있습니다.

사용자가 내 항목 중 하나를 클릭하면 WM_SYSCOMMAND 메시지가 GetMsgProc을 통해 전달 될 것으로 예상되지만 절대로 호출되지 않습니다. GetMsgProc하지만 다른 메시지로 초기화하는 동안 몇 번 호출됩니다. 그래도 WM_SYSCOMMAND 메시지가 CallWndProcRetProc에 표시되지만 올바른 항목 ID가 포함되어 있지 않습니다. 항목 ID를 wParam의 하위 단어 (여기에 지정된대로 : [http://www.codeproject.com/KB/dialog/AOTop.aspx])에서 가져올 것으로 예상했지만 대신 단지 SC_MOUSEMENU을 포함합니다.

myhookdata[GET_MSG_HOOK].nType = WH_GETMESSAGE; 
myhookdata[GET_MSG_HOOK].hkprc = GetMsgProc; 
myhookdata[GET_MSG_HOOK].hhook = SetWindowsHookEx(
    myhookdata[GET_MSG_HOOK].nType, 
    myhookdata[GET_MSG_HOOK].hkprc, 
    AppHandle, 0); 

어떤 아이디어 : 여기

내가 GetMsgProc 후크를 할당하는 방법이다? 내 상품 ID가 잘못 되었습니까? 클릭 한 항목의 ID를 가져 오는 올바른 방법은 무엇입니까?

감사합니다.

업데이트 : 아래의 제안을 바탕으로

, 내가 'WM_SYSCOMMAND'와 잡기 시도 CallWndProc, CallWndProcRetProc, GetMsgProc 및 SysMsgProc에서 'WM_COMMAND'메시지. 항목 선택 메시지가 전달되지 않았습니다.

또한 'WM_MENUSELECT'및 'WM_UNINITMENUPOPUP'과 같은 다른 메시지가 전달되었지만 메뉴가 속한 창을 하위 클래스로 만들었고 내 WndProc에 항목 선택 메시지가 표시되지 않았습니다.

포인터는 어디에서 확인할 것인가?

업데이트 2 : 나는 창 unsubclass/서브 클래스 때

그래서, 내 CallWndProc 후크에 그것을 할. 내가 WM_INITMENUPOPUP 메시지를 받았을 때 하위 클래스로 만들었고 메뉴를 닫을 때 메시지를 받았을 때 unsubclass (lParamNULL이고 HIWORD(wParam)0xFFFF과 같음).

시스템 메뉴 (WM_INITPOPUPMENU가 발생 함)를 클릭하고 마우스 커서를 사용자 정의 항목이 들어있는 하위 메뉴로 이동 한 다음 항목 중 하나를 클릭하십시오. 이 과정에서 새로운 WndProc에서받는 모든 메시지를 기록합니다. 여기에이 시험을하는 동안 내의 WndProc에서 얻을 메시지 목록은 다음과 같습니다

WM_INITMENUPOPUP 
147 (0x0093) - what is this message? 
148 (0x0094) [9 times] - what is this message? 
WM_NCMOUSELEAVE 
WM_ENTERIDLE [2 times] 
WM_NOTIFY [2 times] 
WM_ENTERIDLE [2 times] 
WM_NOTIFY 
WM_ENTERIDLE [11 times] 
WM_MENUSELECT 
WM_ENTERIDLE [5 times] 
WM_MENUSELECT 
WM_ENTERIDLE [6 times] 
WM_MENUSELECT 
WM_ENTERIDLE [7 times] 
WM_MENUSELECT 
WM_ENTERIDLE [8 times] 
WM_NOTIFY 
WM_ENTERIDLE [5 times] 
WM_NOTIFY 
WM_ENTERIDLE 
WM_NOTIFY 
WM_ENTERIDLE 
WM_UNINITMENUPOPUP 
WM_CAPTURECHANGED 

나는 사용자가 항목 WM_COMMAND 또는 WM_SYSCOMMAND 중 하나입니다 클릭하면 볼 것으로 예상하고있어 메시지. Windows 메시지에 대한 많은 경험이 없거나 Windows API로 작업하고 있습니다. 그 두 사람 중 하나가 찾아야 할 올바른 메시지입니까? 어느 쪽의 메시지도 거기에 없다. 그러나 그것은 있어야한다, 그렇지?내가 빠진 것이 있습니까?

+1

Wrong hook, WH_GETMESSAGE는 메시지 큐에서 온 메시지 만 볼 수 있습니다. 게시 된 메시지. WM_SYSCOMMAND가 전송되고 게시되지는 않습니다. 대신 WH_CALLWNDPROC 또는 WH_SYSMSGFILTER를 시도하십시오. –

+0

빠른 답장을 보내 주셔서 감사합니다. CallWndProc 및 CallWndProcRetProc에서 메시지가 표시됩니다. 클릭 한 항목의 ID는 어떻게 얻습니까? MSDN은 설명서에서 언급하지 않습니다. –

+0

통해 CWPSTRUCT –

답변

0

좋아, 알아 냈어. 왜 그런지 모르겠지만 올바른 메시지가 보이지 않습니다. 그러나 창을 서브 클래스로 만들면 WndProc에서 볼 수 있습니다. 위의 두 번째 업데이트에서 서브 클래 싱 할 때 올바른 메시지가 표시되지 않는다고 말했습니다. 너무 빨리 서브 클래 싱되지 않았습니다. 내가 unsubclass 방법

if (oldWndProc == -1) 
{ 
    oldWndProc = SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)NewWndProc); 
    currentSubclassedHandle = hwnd; 
} 

을 그리고 여기에 있습니다 : :

그래서, 이것은 내가 하위 클래스를 어떻게 내가 할

if (oldWndProc != -1) 
{ 
    SetWindowLongPtr(currentSubclassedHandle, GWL_WNDPROC, (LONG)oldWndProc); 
    oldWndProc = -1; 
    currentSubclassedHandle = NULL; 
} 

메시지가 wParam 사용자 정의 메뉴 항목의 ID입니다 WM_SYSCOMMAND이다. 이 메시지는 2nd Update에 게시 한 마지막 메시지 다음에 약간 NewWndProc으로 전달됩니다.

관련 문제