如何使窗口在级联位置打开(使用MFC)

How to make a window open in a cascade position (using MFC)

本文关键字:使用 MFC 位置 何使 窗口 级联      更新时间:2023-10-16

我正在使用Windows MFC创建一个小程序。我想让程序的多个实例出现在一个级联位置。

当前程序总是居中显示,即不可能在多个窗口中看到它。

是否有一种自动的方法让窗口在级联位置创建多个实例?

为了测试,我使用了一个批处理脚本,其中包含多行:
 "start MyProgram.exe"
 "start MyProgram.exe"
 "start MyProgram.exe"

我使用的对话框是从cdialgex派生的(但我使用CDialog有相同的)

我希望这是一个标志/对话框的属性。

在更改.rc文件之前,请设置如下属性

IDD_MAIN_DLG DIALOGEX 0, 0, 260, 185 STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION 

我知道CascadeWindows()函数,但据我所知,它需要更多地了解哪些实例已经运行

下面的代码作为起点如何?

#include <Psapi.h>
namespace {
    size_t nWnds = 0;
    HWND hWnds[10];
    BOOL CALLBACK enumerate(HWND hWnd, LPARAM This)
    {
        HWND hWndThis = reinterpret_cast<HWND>(This);
        TCHAR nameThis[MAX_PATH], nameOther[MAX_PATH];
        VERIFY(GetWindowModuleFileName(hWndThis, nameThis, _countof(nameThis)));
        TCHAR wndclass[32];
        VERIFY(RealGetWindowClass(hWnd, wndclass, _countof(wndclass)));
        if (_tcscmp(wndclass, _T("#32770")) == 0) {
            DWORD pid;
            GetWindowThreadProcessId(hWnd, &pid);
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
            if (hProcess != NULL) {
                if (GetModuleFileNameEx(hProcess, NULL, nameOther, _countof(nameOther))) {
                    if (_tcscmp(nameThis, nameOther) == 0) {
                        hWnds[nWnds++] = hWnd;
                    }
                }
                VERIFY(CloseHandle(hProcess));
                hProcess = NULL;
            }
        }
        return TRUE;
    }
}
BOOL CMFCApplication1Dlg::OnInitDialog()
{
    // ...
    VERIFY(EnumWindows(enumerate, reinterpret_cast<LPARAM>(m_hWnd)));
    if (nWnds > 1) {
        VERIFY(CascadeWindows(NULL, MDITILE_ZORDER, NULL, nWnds, hWnds));
    }
    return TRUE;
}

它包含对OnInitDialog的更改,以扫描已由可执行文件创建的所有顶级对话框,然后调用CascadeWindows。当然,在enumerate中,您也可以将您找到的每个窗口移动到从CPoint(x, y)开始的点,并随着每个窗口的CSize(xoffset, yoffset)变化。

注意事项:

  1. CascadeWindows看起来不像正确的解决方案,它恢复所有最大化的窗口,不只是触摸你的进程创建的窗口(我更喜欢)。
  2. 如果您的进程创建了多个顶级对话框,那么您可能需要检测要移动哪些对话框。
  3. 如果用户复制了你的程序文件,那么模块文件名将不同。
  4. 只是概念验证代码,您需要添加错误检查和边界检查。