프로세스 ID에서 기본 창 핸들을 얻는 방법은 무엇입니까?
프로세스 ID에서 기본 창 핸들 을 얻는 방법은 무엇입니까?
이 창문을 앞으로 가져오고 싶습니다.
"프로세스 탐색기"에서 잘 작동합니다.
.NET이 기본 창을 결정하는 방법을 확인했습니다.
내 발견은 또한 EnumWindows()
.
이 코드는 .NET 방식과 유사하게 수행해야합니다.
struct handle_data {
unsigned long process_id;
HWND window_handle;
};
HWND find_main_window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
data.window_handle = 0;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.window_handle;
}
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle))
return TRUE;
data.window_handle = handle;
return FALSE;
}
BOOL is_main_window(HWND handle)
{
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}
나는 Windows (.NET과 반대)가 그것을 사용할 수있는 방법을 제공합니다.
내가 아는 유일한 방법은 모든 최상위 창을 열거 EnumWindows()
한 다음 여러 프로세스를 찾는 것 GetWindowThreadProcessID()
입니다. 이것은 실질적으로 비효율적으로 들리지만 예상만큼 나쁘게됩니다. 일반적인 경우에는 12 개의 최상위 창을 통과 할 수 있습니다.
여기에 오해의 가능성이 있습니다. .NET의 윈폼 프레임 워크는 자동적으로 작성 상기 윈도우 (예를 들어, 지정 Application.Run(new SomeForm())
은 AS)를 MainWindow
. 그러나 win32 API는 프로세스 당 "메인 창"이라는 개념을 인식하지 못합니다. 메시지 루프는 시스템 및 프로세스 리소스가 생성 할 수있는만큼의 "주"창을 완전히 처리 할 수 있습니다. 따라서 프로세스에는 "메인 창"이 없습니다. 일반적인 경우에 할 수있는 최선의
EnumWindows()
방법은 주어진 프로세스에서 버전이 아닌 모든 창을 활성화하고 몇 가지 휴리스틱을 사용하여 원하는 창이 무엇인지 알아내는 것입니다. 운 좋게도 대부분의 프로세스는 대부분의 경우 단일 "메인"창만 실행 대부분의 경우 좋은 결과를 얻을 수 있습니다.
이것은 최상위 답변을 기반으로 순수한 Win32 / C ++를 사용하는 내 솔루션입니다. 아이디어는 외부 서비스 함수 나 구조없이 필요한 모든 것을 하나의 함수로 래핑하는 것입니다.
#include <utility>
HWND FindTopWindow(DWORD pid)
{
std::pair<HWND, DWORD> params = { 0, pid };
// Enumerate the windows using a lambda to process each window
BOOL bResult = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
{
auto pParams = (std::pair<HWND, DWORD>*)(lParam);
DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams->second)
{
// Stop enumerating
SetLastError(-1);
pParams->first = hwnd;
return FALSE;
}
// Continue enumerating
return TRUE;
}, (LPARAM)¶ms);
if (!bResult && GetLastError() == -1 && params.first)
{
return params.first;
}
return 0;
}
귀하의 질문과 관련이 없을 수 없습니다. GetGUIThreadInfo 기능을 사용할 수 있습니다.
tid (스레드 ID)와 pid (프로세스 ID)를 혼동하지 않도록 방지하기 위해 :
DWORD pid;
DWORD tid = GetWindowThreadProcessId( this->m_hWnd, &pid);
Hiale 솔루션의 확장으로 여러 개의 기본 창이있는 프로세스를 지원하는 다른 또는 수정 된 버전을 제공 할 수 있습니다.
먼저 몇 가지 처리를 수행 할 수 있습니다.
struct handle_data {
unsigned long process_id;
std::vector<HWND> handles;
};
둘째, 지속 함수를 수정합니다.
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle)) {
return TRUE;
}
// change these 2 lines to allow storing of handle and loop again
data.handles.push_back(handle);
return TRUE;
}
마지막으로 주 함수의 수익을 수정합니다.
std::vector<HWD> find_main_window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.handles;
}
참조 URL : https://stackoverflow.com/questions/1888863/how-to-get-main-window-handle-from-process-id
'ProgramingTip' 카테고리의 다른 글
브라우저 아이콘을 활용 WebStorm (0) | 2021.01.06 |
---|---|
.htaccess 301 단일 페이지 리디렉션 (0) | 2021.01.06 |
코드가 JUnit 내에서 실행 중인지 여부를 어떻게 알 수 있습니까? (0) | 2021.01.06 |
document.location.href와 document.location의 차이점은 무엇입니까? (0) | 2021.01.06 |
pthread에서 순위 우선 순위를 높이는 방법은 무엇입니까? (0) | 2021.01.06 |