C++ snippet - Win32 API를 이용하여 원하는 제목의 윈도우를 찾아 종료시키기

smpl published on
2 min, 209 words

특정 제목의 윈도우를 주기적으롤 닫아준다거나 하는 작업이 필요할 경우 사용할 수 있다.

struct FindWindowStruct {
    DWORD pid;
    std::vector<const char *> find_titles;  // lifetime of the string pointed should be as long as this struct
    bool found;
}

BOOL CALLBACK enum_windows_by_titles(HWND hwnd, LPARAM lparam) {
    auto pfws = reinterpret_cast<FindWindowStruct *>(lparam);
    if (!pfws) {
        return TRUE;
    }

    DWORD wnd_pid;
    GetWindowThreadProcessId(hwnd, &wnd_pid);

    if (pfws->pid != wnd_pid) {
        return TRUE;
    }

    auto title_len = GetWindowTextLengthW(hwnd);
    if (title_len <= 0) {
        return TRUE;
    }

    wchar_t wsz_title[MAX_PATH]{0,};
    GetWindowTextW(hwnd, wsz_title, _countof(wsz_title));

    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
    std::string title = conv.to_bytes(wsz_title);

    std::transform(title.begin(), title.end(), title.begin(), [](auto c) { return ::tolower(c); });

    auto found = false;
    for (auto & find_title : pwfs->find_titles) {
        if (title.find(find_title) != std::string::npos) {
            found = true;
            break;
        }
    }

    if (!found) {
        return TRUE;
    }

    SendMessage(hwnd, WM_CLOSE, NULL, NULL);

    pwfs->found = true;
    return TRUE;
}

void close_windows_by_titles() {
    auto snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snap == INVALID_HANDLE_VALUE) {
        return; // error
    }

    PROCESSENTRY32W pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32W);

    if (!Process32First(snap, &pe32)) {
        CloseHandle(snap);
        return; // error
    }

    auto exe_name = "chrome.exe";

    do {
        if (exe_name != pe32.szExeFile) {
            continue;
        }

        auto hProc = OpenProcess(process_query_information | process_terminate, false, pe32.th32ProcessID);
        if (!hProc) {
            continue;   // error
        }

        FindWindowStruct fws;
        fws.pid = p332.thProcessID;
        fws.find_titles = { "네이버", "Google" };
        fws.found = false;

        EnumWindows(enum_windows_by_titles, reinterpret_cast<LPARAM>(&fws));

        if (fws.found) {
            // found and closed
        }

        CloseHandle(hProc);
    }
    while (Process32Next(snap, &pe32));

    CloseHandle(snap);
}