Problem z niestandardowym MDI

0

Piszę program w którym początkowo miałem MDI i kontrolkę TAB, oba jako "dzieci" głównego okna. W handlerze OnSize pobierałem wysokość przycisku kontrolki tab (o ile jakiś był) i odpowiedno ustawiałem pozycję i rozmiar MDI, ale przyciski tab'a zadokowane na górze nie wyglądały to zbyt ładnie, więc...

... postanowiłem że Tab zostanie 'dzieckiem' głównego okna, a MDI będzie childem tab'a. Proste zadania - pomyślałem - kilka przeprowadzek w kodzie, dodatkowe okno frame (tab->frame->mdi) i będzie OK.
Ale zrodził się problem - brak dodatkowych przycisków w menu, typowych dla MDI - close/minimize/maximize. Pomyślałem, że przechwycę funkcję GetMenu i podmienię HWND na uchwyt głównego okna, jeżeli cokolwiek w procesie chce pobrać menu okna tab->frame. To nie wystarczyło, nadal nie było tych dodatkowych przycisków w menu.

Spróbowałem z WM_MDISETMENU - nie pomogło (pamiętałem o DrawMenuBar).
Zmieniłem ID okna tab->frame na liczbę taką samą jak uchwyt menu głównego okna - i w tym momencie otwarcie nowego dokumentu MDI zaczęło generować wyjątek Read from address 0x44850845 (w child.OnCreate zmieniam child.caption):1 USER32.DLL ModifyMenuItem+161

Ktoś wie czego mi brakuje? Bo ja już dwie godziny straciłem na to i chyba wrócę do poprzedniej konfiguracji dodając customdraw do tab'a.

EDIT: zrobiłem to na starej konfiguracji, na regionach. Tab cotrol ma rozmiar pełnego obszaru roboczego, ale jego region wyklucza obszar przeznaczony dla MDI (TabCtrl_AdjustRect). Wygłąda to tak samo jakby MDI był child'em tab'a, więc na razie jestem zadowolny.

#ifdef SIMULATE_MDI_ON_TAB
    int areaWidth = cx - workspaceWidth; // docked workspace width
    int areaHeight = cy - g_ToolbarHeight - statusHeight - buildHeight;

    // this is the rectangle for tab and mdi
    RECT rcTabMdi;
    SetRect(&rcTabMdi, 0, 0, areaWidth, areaHeight);
    // and region
    HRGN rgnTabMdi = CreateRectRgnIndirect(&rcTabMdi);

    // this is the rectangle for mdi
    RECT rcMdi;
    CopyRect(&rcMdi, &rcTabMdi);
    TabCtrl_AdjustRect(g_hwndMdiTab, FALSE, &rcMdi);
    // and region
    HRGN rgnMdi = CreateRectRgnIndirect(&rcMdi);

    // remove rgnMdi from rgnTabMdi
    HRGN rgnNew = CreateRectRgnIndirect(&rcTabMdi);
    CombineRgn(rgnNew, rgnTabMdi, rgnMdi, RGN_DIFF);
    SetWindowRgn(g_hwndMdiTab, rgnNew, FALSE);
    // save new region
    static HRGN _rgnOld;
    if (_rgnOld) DeleteObject(_rgnOld);
    _rgnOld = rgnNew;
    //
    DeleteObject(rgnTabMdi);
    DeleteObject(rgnMdi);

    MoveWindow(g_hwndMdiTab, workspaceWidth, g_ToolbarHeight, areaWidth, areaHeight, TRUE);
    OffsetRect(&rcMdi, workspaceWidth, g_ToolbarHeight);
    MoveWindow(g_hwndMdi, rcMdi.left, rcMdi.top, rcMdi.right-rcMdi.left, rcMdi.bottom-rcMdi.top, TRUE);
#else
    if (mdiTabStyle & TCS_BOTTOM) // zakładki pod tabem
    {
        MoveWindow(g_hwndMdi, workspaceWidth, g_ToolbarHeight, mdiWidth, mdiHeight, TRUE);
        MoveWindow(g_hwndMdiTab, workspaceWidth, g_ToolbarHeight+mdiHeight, mdiWidth, mdiTabHeight, TRUE);
    }
    else // zakładki nad tabem
    {
        MoveWindow(g_hwndMdiTab, workspaceWidth, g_ToolbarHeight, mdiWidth, mdiTabHeight, TRUE);
        MoveWindow(g_hwndMdi, workspaceWidth, g_ToolbarHeight+mdiTabHeight, mdiWidth, mdiHeight, TRUE);
    }
#endif
0

A nie pomogłoby zrobienie takiej konfiguracji:

GŁÓWNE OKNO
TAB
MDI
MDI_CHILD
MDI_CHILD
...

zamiast (jeśli dobrze rozumiem tak robisz)

GŁÓWNE OKNO
TAB
MDI
MDI_CHILD
MDI_CHILD
...

0

Chciałem zrobić tak jak podałeś w drugim przykładzie, no ale właśnie z taką konfiguracją były pewne problemy. Wróciłem więc do konfiguracji którą przedstawiłeś jako pierwszą, tyle że regionem w tabie wyciąłem dziurę na mdi, więc wizualnie wygląda to tak jak w drugim przykładzie.
A tak to wygląda: user image

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0