Window API对我来说是新的。我试图找到从Windows桌面应用程序打开的窗口数。我只想打开一个应用程序实例。
我有我的应用程序abc.exe。如果用户尝试首次打开abc.exe应用程序,则abc.exe应用程序将正常打开。但是,如果abc.exe应用程序已经打开,而用户尝试再次打开它,则它应该提供一个已经打开的Application实例。
在特定情况下,我可以从下面的代码中获得一个已经打开的实例。
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
HWND *retHwnd = (HWND *)lParam;
if (*retHwnd) {
return FALSE;
}
DWORD procID = 0;
auto threadID = GetWindowThreadProcessId(hwnd, &procID);
auto handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, procID);
QString fileName;
if (handle) {
TCHAR filename[FILENAME_MAX];
auto len = GetModuleFileNameEx(handle, NULL, filename, FILENAME_MAX);
fileName = QFileInfo(QString::fromWCharArray(filename, len)).fileName();
if (GetLastApplicationName() == fileName) {
*retHwnd = hwnd;
}
CloseHandle(handle);
}
return TRUE;
}
void ShowExistingInstance() {
HWND hwnd = 0;
auto res = EnumWindows(&EnumWindowsProc, (LPARAM)&hwnd);
if (hwnd) {
ShowWindow(hwnd, SW_MINIMIZE);
ShowWindow(hwnd, SW_MINIMIZE);
ShowWindow(hwnd, SW_RESTORE);
}
}
但是,如果从应用程序中打开了两个窗口,则不会获得该应用程序的第一个实例。
下面我提到两种情况。在第一种情况下,代码工作正常,而在第二种情况下,代码不工作正常。
1)获取已经打开的应用程序实例
步骤:
a。。用户单击abc.exe应用程序图标。
b。。例如,打开主窗口,其名称为mainWindow1
。
c。还原或最小化mainWindow1
d。。用户再次使用应用程序图标单击abc.exe
e。。在这里,我得到mainWindow1
,这是正确的。
2)没有获得已经打开的应用程序实例
步骤:
a。。用户单击abc.exe应用程序图标。
b。。例如,打开主窗口,其名称为mainWindow1
。
c。。用户从当前应用程序中打开另一个窗口,例如,其名称为mainWindow2
。 (mainWindow1
不是mainWindow2
的父对象)。
d。。还原或最小化mainWindow1
(此处mainWindow2
也被最小化,或者自动还原mainWindow1
)
e。用户使用应用程序图标再次单击abc.exe。
f。。在这里,我得到的是mainWindow2
而不是mainWindow1
。
我想要Windows API的某种指导方针,这可以帮助我在第二种情况下找到Mainwidnow1的馆藏。
答案 0 :(得分:0)
我在以下代码的帮助下获得了功能
BOOL isMainWindow(HWND handle) {
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
HWND *retHwnd = (HWND *)lParam;
if (*retHwnd) {
return FALSE;
}
DWORD procID = 0;
auto threadID = GetWindowThreadProcessId(hwnd, &procID);
if (!isMainWindow(hwnd)) {
return TRUE;
}
auto handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, procID);
QString fileName;
if (handle) {
TCHAR filename[FILENAME_MAX];
auto len = GetModuleFileNameEx(handle, NULL, filename, FILENAME_MAX);
fileName = QFileInfo(QString::fromWCharArray(filename, len)).fileName();
if (GetLastApplicationName() == fileName) {
*retHwnd = hwnd;
}
CloseHandle(handle);
}
return TRUE;
}
void ShowExistingInstance() {
HWND hwnd = 0;
auto res = EnumWindows(&EnumWindowsProc, (LPARAM)&hwnd);
if (hwnd) {
ShowWindow(hwnd, SW_MINIMIZE);
ShowWindow(hwnd, SW_MINIMIZE);
ShowWindow(hwnd, SW_RESTORE);
}
}