MDI - Problem



  • hallo leute,

    ich wollte heute zum ersten mal eine anwendung schreiben, die aus diesen MDI-fenstern besteht.

    das frame-window ist mein hauptdialog, mein MDIClient-Window konnte ich auch schon problemlos erstellen.
    Mittlerweile habe ich auch ein Child, dass ich auf der Client-Ebene bewegen, vergrößern, maximieren usw kann.

    nur habe ich ein problem:
    selbst wenn das child angeklickt und aktiviert ist, bleibt die titelleiste grau.
    muss ich irgendeine bestimmte nachricht abfangen damit das aktivierte child-fenster eine blaue titelleiste erhält?

    ty



  • achso es handelt sich wie gesagt um einen dialog...normalerweise geb ich dort immer 0 zurück wenn eine nachricht unbehandelt bleibt (bzw DefDlgProc)...

    aber jetzt soll ich ja DefFrameProc verwenden...dann bekomm ich aber komische anzeigefehler sobald ich das fenster maximiere...deswegen geb ich DefFrameProc nur zurück, wenn die nachricht WM_COMMAND, WM_MENUCHAR oder WM_SETFOCUS ist.



  • help pls!



  • wenn du hilfe brauchst, zeige den code 💡



  • erstellung des hauptfensters (dient als frame):

    // create the main dialog window
    m_mainWindow = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAIN), NULL, WndCallback, (LPARAM)this);
    

    so oft wie möglich:

    if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
    {
    	if (!TranslateMDISysAccel(m_mdiClientWindow, &message))
    	{
    		TranslateMessage(&message);
    		DispatchMessage(&message);
    	}
    }
    

    bei WM_INITDIALOG:

    // create the mdi client window
    CLIENTCREATESTRUCT ccs;
    ZeroMemory(&ccs, sizeof(CLIENTCREATESTRUCT));
    
    client->m_mdiClientWindow = CreateWindowEx(WS_EX_CLIENTEDGE, "MDIClient", NULL,
    WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL, 0, 0, 0, 0, dialog, NULL, GetModuleHandle(NULL), &ccs);
    
    if (!client->m_mdiClientWindow)
    {
    	client->m_mainWindow					= NULL;
    
    	return FALSE;
    }
    
    // set the right size of all elements of the window
    RECT clientRect;
    
    if (!GetClientRect(dialog, &clientRect))
    {
    	client->m_mainWindow					= NULL;
    
    	return FALSE;
    }
    
    // set the main icon
    SetClassLong(dialog, GCL_HICON, (LONG)(LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAIN_ICON))));
    SetClassLong(dialog, GCL_HICONSM, (LONG)(LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAIN_ICON))));
    
    // litte test
    MDICREATESTRUCT mcs;
    ZeroMemory(&mcs, sizeof(MDICREATESTRUCT));
    
    mcs.hOwner = GetModuleHandle(NULL);
    mcs.szClass = "MDIChild";
    mcs.szTitle = "test :)";
    mcs.x = 100; mcs.y = 100; mcs.cx = 300; mcs.cy = 200;
    mcs.style = WS_VISIBLE | WS_CHILD | WS_OVERLAPPEDWINDOW;
    SendMessage(client->m_mdiClientWindow, WM_MDICREATE, 0, (LPARAM)&mcs);
    
    client->ResizeChildWindows(clientRect.right, clientRect.bottom);
    
    ShowWindow(dialog, SW_SHOW);
    SetForegroundWindow(dialog);
    
    return TRUE;
    
    case WM_COMMAND:
    case WM_MENUCHAR:
    case WM_SETFOCUS:
    {
    	if (client)
    	{
    		return DefFrameProc(dialog, client->m_mdiClientWindow, message, wParam, lParam);
    	}
    } break;
    

    die mdi-child-callback ruft nur DefMDIChildProc() auf...

    thx 4 help, mdi 🙂





  • thx erstmal.

    hab die msdn auch schon durchwühlt.
    CreateMDIWindow macht keinen unterschied zu WM_MDICREATE.

    mit dem dialog: naja wär halt für mich praktischer zu designen...ich werds mal mit nem normalen window probieren. wär echt schade wenns am dialog liegen würde.



  • öhm, normal nimmt man für nen normalen dialog in so nem fall nen formview, alledings weiß ich net, ob die nur bei mfc existiert..



  • @(D)Evil
    es geht auch mit der winapi, du musst nur den dialog als child vom fenster machen.



  • ok es geht jetzt einigermaßen gut wenn ich mein hauptfenster mit CreateWindow() erstelle.

    beim hauptfenster ist das auch kein problem, da sind nur ein paar buttons und das client-fenster drauf.
    allerdings würde ich gerne für die mdi-childs dialoge verwenden.

    ist das irgendwie möglich?

    ty



  • keine möglichkeit?
    es ist doch sehr umständlich jedes eingabefeld/label usw mit createwindow zu erstellen...es muss doch eine komfortablere lösung geben ?!?
    außerdem muss man alle styles manuell setzen, schriftart usw...

    pls help!



  • miller_m schrieb:

    @(D)Evil
    es geht auch mit der winapi, du musst nur den dialog als child vom fenster machen.

    so geht es. afaik findest du in den msdn samples etwas darüber.



  • aha...also sollte das mdi-child WS_OVERLAPPEDWINDOW sein, der dialog ein fenster komplett ohne rahmen, den ich dann ins mdi-child als child-window einbinde?

    und in der callback des mdi-childs sollte es in etwa so aussehen(?):

    LRESULT CALLBACK MdiChildCallback(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_CREATE:
            {
                CreateDialog(...);
            } break;
        }
    
        return DefMDIChildProc(window, message, wParam, lParam);
    }
    

    und dann bräuchte ich noch eine zusätzliche callback funktion für den dialog?

    danke, mdi



  • so in etwa, hab es schon lange nicht mehr gemacht, aber es hört sich vernünftig an. du könntest ja in der dlgcallback einfach die msg weiterleiten ala

    SendMessage(GetParent(hwnd), msg, wParam, lParam);
    


  • ok vielen dank es funktioniert jetzt soweit!
    zwar etwas umständlich wegen der 2ten callback, aber immer noch besser als alles manuell zu erstellen!

    und die einzige nachricht, die ich weiterleite, ist WM_SIZE, den rest brauche ich gar nicht.

    10x, mdi


Anmelden zum Antworten