确定从特定的Windows应用程序打开了多少个窗口?

时间:2019-02-20 17:38:23

标签: windows winforms qt user32 hwnd

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的馆藏。

1 个答案:

答案 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);
   }
 }