использование CreateWindow для создания дочернего окна MDI

0

это работает

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 Child?

Теги:
win32gui
mdichild

2 ответа

0

Когда вы передаете MDICREATESTRUCT в WM_MDICREATE, вы можете MDICREATESTRUCT.lParam указатель объекта в поле 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);
0

Я решил это, сделав это

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 lparam в WndProc будет указателем на CREATESTRUCT, чья lpCreateParams будет MIDICREATESTRUCT, чей lParam будет указателем на ваш объект.

уф.

  • 0
    Когда вы передаете MDICREATESTRUCT в WM_MDICREATE , вы можете предоставить указатель объекта в MDICREATESTRUCT.lParam .
  • 0
    Подобные вещи здесь stackoverflow.com/questions/55547616/…

Ещё вопросы

Сообщество Overcoder
Наверх
Меню