使用创建窗口创建 MDI 子窗口

using CreateWindow to create a MDI child window

本文关键字:窗口 创建 MDI      更新时间:2023-10-16

这有效

mcs.szTitle = L"untitled";
mcs.szClass = childClassName;
mcs.hOwner  = GetModuleHandle(NULL);
mcs.x = mcs.cx = CW_USEDEFAULT;
mcs.y = mcs.cy = CW_USEDEFAULT;
mcs.style = WS_HSCROLL;
hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LONG)&mcs);

但我无法像这样向它发送指向具有我想使用的 WndProc 的对象的指针(请参阅此处以了解在类中包装 WndProc 的信息(

hChild = CreateWindow(childClassName, L"", WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 400, 250, hMDIClient, NULL, GetModuleHandle(NULL), this);

但是这样做会导致 windo 出错,不会有 zlose,没有最小化,没有最大化,我无法调整它的大小,如果我创建另一个 mdi 子窗口,前一个将变为可取消选择。

是否可以使用 SendMessage 或 CreateWindow,传递此指针并仍创建有效的 MDI 子窗口?

我通过这样做解决了它

hChild = CreateMDIWindow(childClassName, L"", WS_EX_WINDOWEDGE, 49, 50, 51, 52, hMDIClient, GetModuleHandle(NULL), (LPARAM)this);

然后在静态 WndProc 中

LRESULT CALLBACK CWindowHandler::MsgRouter(HWND hwnd, UINT message,
                                            WPARAM wparam, LPARAM lparam)
{
    CREATESTRUCT* wnd = 0;
    MDICREATESTRUCT* mdiStruct = 0;
    CMDIChildWindowBase* wndBase;
    if(message == WM_NCCREATE)
    {
        wnd = (CREATESTRUCT*)(lparam);
        mdiStruct = (MDICREATESTRUCT*)wnd->lpCreateParams;
        wndBase = (CMDIChildWindowBase*)mdiStruct->lParam;
        SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(wndBase));
        // save window handle
        wndBase->SetHWND(hwnd);
    }
    else
        wndBase = reinterpret_cast<CMDIChildWindowBase *>(::GetWindowLong(hwnd, GWL_USERDATA));
    // call the windows message handler
    if(wndBase)
        return wndBase->WndProcs(message, wparam, lparam);
    return DefWindowProc(hwnd, message, wparam, lparam);
}

因此,在创建 MDIChild 时,WndProc 中的 lparam 将是指向 CREATESTRUCT 的指针,其 lpCreateParams 将是 MIDICREATESTRUCT,其 lParam 将是指向对象的指针。

唷。

MDICREATESTRUCT传递给 WM_MDICREATE 时,可以在MDICREATESTRUCT.lParam字段中提供对象指针:

mcs.szTitle = L"untitled";
mcs.szClass = childClassName;
mcs.hOwner  = GetModuleHandle(NULL);
mcs.x = mcs.cx = CW_USEDEFAULT;
mcs.y = mcs.cy = CW_USEDEFAULT;
mcs.style = WS_HSCROLL;
mcs.lParam = (LPARAM) this; // <-- here
hChild = (HWND) SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs);