0

I want get the current URL of chrome current version.

so, I tried using this way. (http://www.codeproject.com/Questions/648906/how-to-get-current-URL-for-chrome-ver-29)

This method works now.

But, Possible only when the tab is clicked.

I want get the chrome URL that click anywhere.

It is possible?. thanks.

DEVVY J
  • 25
  • 1
  • 8

1 Answers1

2

This is an old issue, but it's asked often around here so I'll offer my solution.

The problem with the link you provided is that EVENT_OBJECT_VALUECHANGE is not the only event you should watch, as there are several other events that may indicate a URL change (such as changing a tab). Thus, we will watch all events between EVENT_OBJECT_FOCUS and EVENT_OBJECT_VALUECHANGE. Here's a sample:

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;
}

This will report all the Chrome address bar changes in the console.

fstanis
  • 5,234
  • 1
  • 23
  • 42
  • Beware the memory leaks here: `bstrValue` and `bstrName` are never deallocated. There must be calls to `SysFreeString()` as `BSTR`'s are allocated using `SysAllocString()`. Also to make the code more robust the variables should be initialized like this: `BSTR bstrName = nullptr, bstrValue = nullptr;` – zett42 Jan 29 '18 at 16:51
  • Also, if `GetClassName()` fails, the following `strcmp()` may crash when it operates on uninitialized memory, so either the return value of `GetClassName()` must be checked or the `className` array must be zero-initialized. Similarily, `wcscmp(bstrName, ...)` and `printf` could crash if `get_accValue()` and/or `get_accName()` failed, so appropriate checks must be done to prevent that. – zett42 Jan 29 '18 at 16:59
  • BTW, there were some issue with this code reported in [this question](https://stackoverflow.com/q/48504300/7571258). I was able to reproduce this error. The following changes fix it: `VARIANT varSelf; varSelf.vt = VT_I4; varSelf.lVal = CHILDID_SELF;` and then `pAcc->get_accName(varSelf, &bstrName)` and `pAcc->get_accValue(varSelf, &bstrValue)` – zett42 Jan 30 '18 at 13:42