C++ snippet - Win32 API를 이용하여 원하는 제목의 윈도우를 찾아 종료시키기
특정 제목의 윈도우를 주기적으롤 닫아준다거나 하는 작업이 필요할 경우 사용할 수 있다.
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);
}