如何从C ++程序中检索DOM元素?

时间:2017-08-01 14:26:44

标签: c++ dom hwnd

我需要从c ++程序中获取IE中显示的所有网页元素。 我试图用spy ++来看,但只有IEFrame。

所以我考虑使用开发工具(IE中的F12),我听说有一种自动化的方法,这是一个好主意吗?

由于

1 个答案:

答案 0 :(得分:2)

您可以从IE的窗口句柄获取IHtmlDocument2引用,甚至是进程外的。这在此处记录https://support.microsoft.com/en-us/help/249232/how-to-get-ihtmldocument2-from-a-hwnd,但微软并不真正支持。 但是看起来它今天仍然可以使用,我已经用Windows 10机箱进行了测试,IE现在已经成为一个冷冻应用,所以不会很快改变。

一旦你拥有适用于Internet Explorer的HWND,你就可以获得带有这样代码的DOM。确保IE和您的程序以相同的安全级别运行 DOM与您在进程中编写IE(主机,activex等)时的DOM相同,但出于安全考虑,某些操作可能无效:

BOOL CALLBACK GetIEServerWindowProc(HWND hwnd, LPARAM lParam)
{
    // enumerate all child windows to find IE's COM server
    wchar_t className[100];
    GetClassName(hwnd, className, 100);
    if (!wcscmp(className, L"Internet Explorer_Server"))
    {
        *((HWND*)lParam) = hwnd;
        return FALSE;
    }
    return TRUE;
}

HWND GetIEServerWindow(HWND hwnd)
{
    HWND serverHwnd = NULL;
    EnumChildWindows(hwnd, GetIEServerWindowProc, (LPARAM)&serverHwnd);
    return serverHwnd;
}

struct IEServer
{
    DWORD processId;
    HWND serverHwnd;
};

BOOL CALLBACK GetIEProcessServerWindowProc(HWND hwnd, LPARAM lParam)
{
    DWORD processId = ((IEServer*)lParam)->processId;
    DWORD pid;
    GetWindowThreadProcessId(hwnd, &pid);
    if (pid == processId)
    {
        HWND serverHwnd = GetIEServerWindow(hwnd);
        if (serverHwnd)
        {
            ((IEServer*)lParam)->serverHwnd = serverHwnd;
            return FALSE;
        }
    }
    return TRUE;
}

HWND GetIEProcessServerWindow(DWORD processId)
{
    IEServer ie = { processId, NULL };
    EnumWindows(GetIEProcessServerWindowProc, (LPARAM)&ie);
    return ie.serverHwnd;
}

void EnumerateIEProcesses()
{
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (h == INVALID_HANDLE_VALUE)
        return;

    PROCESSENTRY32 process;
    process.dwSize = sizeof(PROCESSENTRY32);
    if (Process32First(h, &process))
    {
        do
        {
            // we only consider IE processes
            if (!wcscmp(process.szExeFile, L"iexplore.exe"))
            {
                HWND serverHwnd = GetIEProcessServerWindow(process.th32ProcessID);
                if (serverHwnd)
                {
                    DoSomeDomOperations(serverHwnd);
                }
            }
        } while (Process32Next(h, &process));
    }
    CloseHandle(h);
}

int main()
{
    CoInitialize(NULL);

    EnumerateIEProcesses();
    CoUninitialize();
    return 0;
}

这是一个完整的示例控制台应用程序,可扫描所有正在运行的IE进程:

  Cursor data = mDatabaseHelper.getData();
  data.moveToPosition(q);
  data.moveToNext();
  qTextView.setText(data.getString(1));
  while (data.isLast()) {
      data.moveToFirst();
      q = data.getPosition();
  }
  q = q+1;
  }