2014-01-09 148 views

回答

1

这是一个老问题,但它经常在这里问,所以我会提供我的解决方案。

您提供的链接存在的问题是,EVENT_OBJECT_VALUECHANGE不是您应该关注的唯一事件,因为还有其他几个可能表明网址更改的事件(例如更改标签)。因此,我们将观察EVENT_OBJECT_FOCUSEVENT_OBJECT_VALUECHANGE之间的所有事件。以下是一个示例:

HWINEVENTHOOK LHook = 0; 

void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { 
    IAccessible* pAcc = NULL; 
    VARIANT varChild; 
    if ((AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild) == S_OK) && (pAcc != NULL)) { 
    char className[50]; 
    if (GetClassName(hwnd, className, 50) && strcmp(className, "Chrome_WidgetWin_1") == 0) { 
     BSTR bstrName = nullptr; 
     if (pAcc->get_accName(varChild, &bstrName) == S_OK) { 
     if (wcscmp(bstrName, L"Address and search bar") == 0) { 
      BSTR bstrValue = nullptr; 
      if (pAcc->get_accValue(varChild, &bstrValue) == S_OK) { 
      printf("URL change: %ls\n", bstrValue); 
      SysFreeString(bstrValue); 
      } 
     } 
     SysFreeString(bstrName); 
     } 
     pAcc->Release(); 
    } 
    } 
} 

void Hook() { 
    if (LHook != 0) return; 
    CoInitialize(NULL); 
    LHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_VALUECHANGE, 0, WinEventProc, 0, 0, WINEVENT_SKIPOWNPROCESS); 
} 

void Unhook() { 
    if (LHook == 0) return; 
    UnhookWinEvent(LHook); 
    CoUninitialize(); 
} 


int main(int argc, const char* argv[]) { 
    MSG msg; 
    Hook(); 

    while (GetMessage(&msg, NULL, 0, 0)) { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    Unhook(); 

    return 0; 
} 

这将报告控制台中所有Chrome地址栏的更改。

+0

请注意这里的内存泄漏:'bstrValue'和'bstrName'永远不会被释放。必须调用'SysFreeString()',因为'BSTR'是通过'SysAllocString()'分配的。此外,为了使代码更健壮,变量应该像这样被初始化:'BSTR bstrName = nullptr,bstrValue = nullptr;' – zett42

+0

另外,如果'GetClassName()'失败,下面的'strcmp()'可能会在运行时崩溃未初始化的内存,因此必须检查GetClassName()的返回值,或者必须对'className'数组进行零初始化。类似地,如果'get_accValue()'和/或'get_accName()'失败,'wcscmp(bstrName,...)'和'printf'可能会崩溃,因此必须进行适当的检查以防止出现这种情况。 – zett42

+0

谢谢 - 更新以解决这些问题。 – fstanis