简体   繁体   English

使用CreateWindow创建MDI子窗口

[英]using CreateWindow to create a MDI child window

this works 这有效

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);

but I can't send it a pointer to the object that has the WndProc I'd like to use (see here for wrapping up WndProc in classes) like this 但是我不能向它发送指向具有我要使用的WndProc的对象的指针(请参见此处将WndProc包装在类中),就像这样

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

However doing it like that will cause an error with the windo, there will be no zlose, no minimise, no maximise, I can't resize it, and if I create another mdi child window, the previous one will become deselectable. 但是,这样做会导致windo出错,不会出现zlose,没有最小化,没有最大化,我无法调整其大小,并且如果我创建另一个mdi子窗口,则前一个将变为可取消选择状态。

Is it possible to use either SendMessage or CreateWindow, pass a this pointer and still create a working MDI Child window? 是否可以使用SendMessage或CreateWindow,传递this指针并仍然创建有效的MDI Child窗口?

I solved it by doing this 我这样做解决了

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

and then in the static WndProc 然后在静态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);
}

so when creating an MDIChild, lparam in WndProc will be a pointer to a CREATESTRUCT, whose lpCreateParams will be a MIDICREATESTRUCT, whose lParam will be the pointer to your object. 因此,在创建MDIChild时,WndProc中的lparam将是指向CREATESTRUCT的指针,CREATESTRUCT的lpCreateParams将是MIDICREATESTRUCT,其lParam将是指向对象的指针。

phew. 唷。

When you pass the MDICREATESTRUCT to WM_MDICREATE , you can provide the object pointer in MDICREATESTRUCT.lParam field: 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM