窗口API对我来说是新的。我试图找到从Windows桌面应用程序打开的窗口数。我想只打开一个应用程序的一个实例。
我有我的应用程序abc.exe。如果用户第一次尝试打开abc.exe应用程序,则abc.exe应用程序将正常打开。但是,如果abc.exe应用程序已经打开并且usser尝试再次打开它,那么它应该给出一个已经打开的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)获取已经打开的应用程序实例
脚步:
一个。用户单击abc.exe应用程序图标。
湾主窗口打开,例如它的名字是mainWindow1
。
C。恢复或最小化mainWindow1
d。用户使用应用程序图标再次单击abc.exe
即在这里,我得到mainWindow1
,这是正确的。
2)没有得到已经打开的应用程序实例
脚步:
一个。用户单击abc.exe应用程序图标。
湾主窗口打开,例如它的名字是mainWindow1
。
C。用户从当前应用程序打开另一个窗口,例如其名称为mainWindow2
。 (mainWindow1
不是mainWindow2
的父母)。
d。恢复或最小化mainWindow1
(此处mainWindow2
也被最小化或自动恢复为w.r.t mainWindow1
)
即用户使用应用程序图标再次单击abc.exe。
F。在这里,我得到mainWindow2
而不是mainWindow1
。
我想要一些Windows API的指南,这有助于我在第二种情况下找到Hwnd of Mainwidnow1。
我在下面的代码的帮助下得到了我的功能
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);
}
}