c++winapi

How to competently open and manage a browser using WinAPI


I'm making a YouTube player and I need the following:

  1. Open a new browser process and open a link in it.

  2. Wait for it all to load

  3. Minimize the window

I also need: When pressing PAUSE, pause the video, when pressing Play, resume playback

Problem: I can actually start the process with the command CreateProcess, but I can't determine the state: whether the window has loaded or not. Because if I minimize the window, but the video or browser does not close, it either will not work, or the video will not start playing. Sleep does not work for me, because on different computers and depending on the user's Internet speed, the window and video can load in different amounts of time, so it is impossible to guess here.

I also encountered a problem with finding the window. When I open a process and try to find the browser window (EnumWindows), it most often does not find it. I also tried to use the enumeration of all windows and match ProcessId - did not work either.

Below I have provided some code from my attempts (primitively done specifically for testing):

Creating a process:

#include <iostream>
#include <string>
#include <Windows.h>

struct handle_data {
    unsigned long process_id;
    HWND window_handle;
};

BOOL CALLBACK enum_windows_callback(const HWND handle, const LPARAM lParam)
{
    handle_data& data = *reinterpret_cast<handle_data *>(lParam);
    unsigned long process_id = 0;
    GetWindowThreadProcessId(handle, &process_id);
    if (data.process_id != process_id)
        return TRUE;
    data.window_handle = handle;
    return FALSE;
}

HWND find_main_window(unsigned long process_id)
{
    handle_data data{};
    data.process_id = process_id;
    data.window_handle = nullptr;
    EnumWindows(enum_windows_callback, reinterpret_cast<LPARAM>(&data));
    return data.window_handle;
}

int main() {
    const char* chromePath = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
    std::string command = std::string(chromePath) + " --new-window " + url;

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (!CreateProcess(
        NULL,
        const_cast<LPSTR>(command.c_str()),
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi))
    {
        std::cerr << "CreateProcess failed with error code " << GetLastError() << std::endl;
        return 1;
    }

    HWND hwnd = find_main_window(pi.dwProcessId);

    if (hwnd != NULL) {
        std::cout << "Found window handle: " << hwnd << std::endl;
    } else {
        std::cout << "Window not found." << std::endl;
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}

This is what I tried to find the window of the running process (for some reason it doesn't work). I also think that this is a primitive approach and does not take into account a large number of points, but I do not know of any other way.

In fact, I need all this to manage this window in the future (pause, play, etc.).

Can you suggest other methods besides winapi, maybe there are more effective methods to do what I described above?

I also need to take into account that the user may have multiple browser processes running.


Solution

  • The best approach is to use the embedded webview2 browser.