【问题标题】:How to get current URL for chrome current version如何获取 chrome 当前版本的当前 URL
【发布时间】:2014-01-27 09:38:15
【问题描述】:

我想获取chrome当前版本的当前URL。

所以,我尝试使用这种方式。 (http://www.codeproject.com/Questions/648906/how-to-get-current-URL-for-chrome-ver-29)

这个方法现在有效。

但是,只有当标签被点击时才有可能。

我想获取点击任意位置的 chrome URL。

有可能吗?谢谢。

【问题讨论】:

    标签: c++ google-chrome url window


    【解决方案1】:

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

    您提供的链接的问题在于,EVENT_OBJECT_VALUECHANGE 不是您应该观看的唯一事件,因为还有几个其他事件可能表明 URL 更改(例如更改选项卡)。因此,我们将观察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 地址栏更改。

    【讨论】:

    • 注意这里的内存泄漏:bstrValuebstrName 永远不会被释放。必须调用SysFreeString(),因为BSTR 是使用SysAllocString() 分配的。另外为了使代码更健壮,变量应该像这样初始化:BSTR bstrName = nullptr, bstrValue = nullptr;
    • 另外,如果GetClassName()失败了,下面的strcmp()在操作未初始化的内存时可能会崩溃,所以要么必须检查GetClassName()的返回值,要么必须检查className数组零初始化。同样,如果 get_accValue() 和/或 get_accName() 失败,wcscmp(bstrName, ...)printf 可能会崩溃,因此必须进行适当的检查以防止这种情况发生。
    • 顺便说一句,this question 中报告的此代码存在一些问题。我能够重现此错误。以下更改修复了它:VARIANT varSelf; varSelf.vt = VT_I4; varSelf.lVal = CHILDID_SELF;,然后是 pAcc->get_accName(varSelf, &bstrName)pAcc->get_accValue(varSelf, &bstrValue)
    猜你喜欢
    • 2021-08-02
    • 2015-12-04
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多