hpincel = CreateSolidBrush(RGB(r, g, b));


#include <windows.h>
#include "resource.h"

LRESULT CALLBACK ProcJan(HWND, UINT, WPARAM, LPARAM);

BOOL    CALLBACK ProcEnum(HWND, LPARAM);

LRESULT CALLBACK ConfigWnd1(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK ConfigWnd2(HWND, UINT, WPARAM, LPARAM);

typedef struct tagDADOS_Filha1 {
    short cxCliente, cyCliente;
}
DADOS_FILHA1, *LPDADOS_FILHA1;

typedef struct tagDADOS_Filha2 {
    short cxCliente, cyCliente;
}
DADOS_FILHA2, *LPDADOS_FILHA2;

char szNomeAplic[]       = "Mae";
char szNomeAplicFilha1[] = "Filha1";
char szNomeAplicFilha2[] = "Filha2";

HINSTANCE hCop;

HMENU hMenuInic, hMenuF1, hMenuF2, hMenuInicJan, hMenuJanF1, hMenuJanF2;

int WINAPI WinMain(HINSTANCE hI, HINSTANCE hPI, PSTR szCL, int iCS) {
    HACCEL   hAccel;
    HWND     hjan, hjClient;
    MSG      msg;
    WNDCLASS wc;

    if(!hPI) {
        wc.style         = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc   = ProcJan;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hI;
        wc.hIcon         = LoadIcon(hI, szNomeAplic);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = GetSysColorBrush(WHITE_BRUSH);
        wc.lpszMenuName  = szNomeAplic;
        wc.lpszClassName = szNomeAplic;

        RegisterClass(&wc);

        wc.style         = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc   = ConfigWnd1;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = sizeof(HANDLE);
        wc.hInstance     = hI;
        wc.hIcon         = LoadIcon(hI, szNomeAplicFilha1);
        wc.hCursor       = LoadCursor(hI, szNomeAplicFilha1);
        wc.hbrBackground = GetSysColorBrush(WHITE_BRUSH);
        wc.lpszMenuName  = szNomeAplicFilha1;
        wc.lpszClassName = szNomeAplicFilha1;

        RegisterClass(&wc);

        wc.style         = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc   = ConfigWnd2;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = sizeof(HANDLE);
        wc.hInstance     = hI;
        wc.hIcon         = LoadIcon(hI, szNomeAplicFilha2);
        wc.hCursor       = LoadCursor(hI, szNomeAplicFilha2);
        wc.hbrBackground = GetSysColorBrush(WHITE_BRUSH);
        wc.lpszMenuName  = szNomeAplicFilha2;
        wc.lpszClassName = szNomeAplicFilha2;

        RegisterClass(&wc);
    }

    hCop = hI;

    hMenuInic = LoadMenu(hCop, szNomeAplic);
    hMenuF1   = LoadMenu(hCop, szNomeAplicFilha1);
    hMenuF2   = LoadMenu(hCop, szNomeAplicFilha2);

    hMenuInicJan = GetSubMenu(hMenuInic, INIC_MENU_POS);
    hMenuJanF1   = GetSubMenu(hMenuF1, F1_MENU_POS);
    hMenuJanF2   = GetSubMenu(hMenuF2, F2_MENU_POS);

    hjan = CreateWindow(
        szNomeAplic, "Open Window",WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        HWND_DESKTOP, hMenuInic, hI, NULL
    );

    hAccel = LoadAccelerators(hI, szNomeAplic);
    hjClient = GetWindow(hjan, GW_CHILD);

    ShowWindow(hjan, iCS);
    UpdateWindow(hjan);

    while(GetMessage(&msg, NULL, 0, 0)) {
        if(!TranslateMDISysAccel(hjClient,&msg) &&
                      !TranslateAccelerator(hjan,hAccel,&msg)) {
            TranslateMessage(&msg);
            DispatchMessage (&msg);
            FreeConsole();
        }
    }

    DestroyMenu(hMenuF1);
    DestroyMenu(hMenuF2);

    return msg.wParam;
}

LRESULT CALLBACK ProcJan(HWND hjan, UINT msg, WPARAM wP, LPARAM lP) {
    static HWND        hClient;
    CLIENTCREATESTRUCT criaCliente;
    HWND               hjanfilha;
    MDICREATESTRUCT    criaFilha;

    switch(msg) {
        case WM_CREATE:
            criaCliente.hWindowMenu = hMenuInicJan;
            criaCliente.idFirstChild = IDM_PFILHA;
            hClient = CreateWindow(
                "MDICLIENT",NULL,WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,
                0, 0, 0, 0,
                hjan, (HMENU) 1, hCop, (LPSTR) &criaCliente
            );
            return 0;
        case WM_COMMAND:
            switch(wP) {
                case IDM_FILHA1:
                    criaFilha.szClass = szNomeAplicFilha1;
                    criaFilha.szTitle = "Janela Interior";
                    criaFilha.hOwner = hCop;
                    criaFilha.x      = CW_USEDEFAULT;
                    criaFilha.y      = CW_USEDEFAULT;
                    criaFilha.cx     = CW_USEDEFAULT;
                    criaFilha.cy     = CW_USEDEFAULT;
                    criaFilha.style  = 0;
                    criaFilha.lParam = 0;
                    hjanfilha=(HWND)SendMessage(
                        hClient,
                        WM_MDICREATE,
                        0,
                        (LPARAM)(LPMDICREATESTRUCT)&criaFilha
                    );
                    break;
                case IDM_FILHA2:
                    criaFilha.szClass = szNomeAplicFilha2;
                    criaFilha.szTitle = "Janela Interior";
                    criaFilha.hOwner = hCop;
                    criaFilha.x      = CW_USEDEFAULT;
                    criaFilha.y      = CW_USEDEFAULT;
                    criaFilha.cx     = CW_USEDEFAULT;
                    criaFilha.cy     = CW_USEDEFAULT;
                    criaFilha.style  = 0;
                    criaFilha.lParam = 0;
                    hjanfilha=(HWND)SendMessage(
                        hClient,
                        WM_MDICREATE,
                        0,
                        (LPARAM)(LPMDICREATESTRUCT)&criaFilha
                    );
                    break;
                case IDM_FECHAR:
                    hjanfilha=(HWND)SendMessage(
                        hClient,
                        WM_MDIGETACTIVE,
                        0,
                        0
                    );
                    if(SendMessage(hClient,WM_QUERYENDSESSION,0,0)) {
                        SendMessage(
                            hClient,
                            WM_MDIDESTROY,
                            (WPARAM) hjanfilha,
                            0
                        );
                    }
                    break;
                case IDM_EXIT:
                    SendMessage(hjan, WM_CLOSE, 0, 0);
                    break;
                case IDM_LADO:
                    SendMessage(hClient, WM_MDITILE, 0, 0);
                    break;
                case IDM_CASCATA:
                    SendMessage(hClient, WM_MDICASCADE, 0, 0);
                    break;
                case IDM_ORGANIZA:
                    SendMessage(
                        hClient,
                        WM_MDIICONARRANGE,
                        0,
                        0
                    );
                    break;
                case IDM_CLOSEALL:
                    EnumChildWindows(hClient, &ProcEnum, 0);
                    break;
                case IDM_RECT:
                case IDM_CIRCULO:
                    hjanfilha=(HWND) SendMessage(
                        hClient,
                        WM_MDIGETACTIVE,
                        0,
                        0
                    );
                    if(IsWindow(hjanfilha))
                        SendMessage(hjanfilha,WM_PAINT,wP,lP);
                    break;
                default:
                    hjanfilha=(HWND)SendMessage(
                        hClient,
                        WM_MDIGETACTIVE,
                        0,
                        0
                    );
                    if(IsWindow(hjanfilha))
                        SendMessage(hjanfilha,WM_COMMAND,wP,lP);
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_CLOSE:
            SendMessage(hjan, WM_COMMAND, IDM_CLOSEALL, 0);
            if(NULL != GetWindow(hClient,GW_CHILD))
                return 0;
            break;
    }
    return DefFrameProc(hjan, hClient, msg, wP, lP);
}

BOOL CALLBACK ProcEnum(HWND hjan, LPARAM lParam) {
    if(GetWindow(hjan, GW_OWNER))
        return 1;

    SendMessage(
        GetParent(hjan),
        WM_MDIRESTORE,
        (WPARAM)hjan,
        0
    );

    if(!SendMessage(hjan,WM_QUERYENDSESSION,0,0)) {
        return 1;
    }
    SendMessage(GetParent(hjan),WM_MDIDESTROY,(WPARAM)hjan,0);
    return 1;
}

LRESULT CALLBACK ConfigWnd1(HWND hjan,UINT msg,WPARAM wP,LPARAM lParam) {
    static HWND hjancliente, main;
    HDC    hdc;
    HBRUSH hPaint;
    HMENU  hMenu;
    LPDADOS_FILHA1 lpdf1;
    PAINTSTRUCT    ps;
    int xin, xfin, yin, yfin;
    short r, g, b;

    switch(msg) {
        case WM_CREATE:
            lpdf1=(LPDADOS_FILHA1)HeapAlloc(
                GetProcessHeap(),
                HEAP_ZERO_MEMORY,
                sizeof(DADOS_FILHA1)
            );
            SetWindowLongPtr(hjan, 0, (LONG_PTR)lpdf1);
            hjancliente = GetParent(hjan);
            main     = GetParent(hjancliente);
            return 0;
        case WM_SIZE:
            if(wP != SIZE_MINIMIZED) {
                lpdf1=(LPDADOS_FILHA1)GetWindowLongPtr(hjan,0);
                lpdf1->cxCliente=LOWORD(lParam);
                lpdf1->cyCliente=HIWORD(lParam);
            }
            break;
        case WM_PAINT:
            InvalidateRect(hjan,NULL,TRUE);
            lpdf1=(LPDADOS_FILHA1)GetWindowLongPtr(hjan,0);
            xin =rand() % lpdf1->cxCliente;
            xfin=rand() % lpdf1->cxCliente;
            yin =rand() % lpdf1->cyCliente;
            yfin=rand() % lpdf1->cyCliente;

            r = rand() & 255;
            g = rand() & 255;
            b = rand() & 255;

            hdc = BeginPaint(hjan, &ps);

            hPaint=CreateSolidBrush(RGB(r, g, b));

            SelectObject(hdc, hPaint);

            Rectangle(
                hdc,
                min(xin,xfin),
                min(yin,yfin),
                max(xin,xfin),
                max(yin,yfin)
            );

            EndPaint(hjan, &ps);

            DeleteObject((HGDIOBJ) hPaint);
            return 0;
        case WM_MDIACTIVATE:
            if(lParam==(LPARAM)hjan) {
                SendMessage(
                    hjancliente,
                    WM_MDISETMENU,
                    (WPARAM)hMenuF1,
                    (LPARAM)hMenuJanF1
                );
            }
            else {
                SendMessage(
                    hjancliente,
                    WM_MDISETMENU,
                    (WPARAM)hMenuInic,
                    (LPARAM)hMenuInicJan
                );
            }
            DrawMenuBar(main);
            return 0;
        case WM_DESTROY:
            lpdf1=(LPDADOS_FILHA1)GetWindowLongPtr(hjan,0);
            HeapFree(GetProcessHeap(), 0, lpdf1);
            return 0;
    }
    return DefMDIChildProc(hjan, msg, wP, lParam);
}

LRESULT CALLBACK ConfigWnd2(HWND hjan, UINT msg, WPARAM wP, LPARAM lP) {
    static HWND hjancliente, hjanmae;
    HDC    hdc;
    HBRUSH hpincel;
    HMENU  hMenu;
    LPDADOS_FILHA2 lpdf2;
    PAINTSTRUCT ps;
    int         xin, xfin, yin, yfin;
    short       r, g, b;

    switch(msg) {
        case WM_CREATE:
            lpdf2 = (LPDADOS_FILHA2) HeapAlloc(
                GetProcessHeap(),
                HEAP_ZERO_MEMORY,
                sizeof(DADOS_FILHA2)
            );
            SetWindowLongPtr(hjan, 0, (LONG_PTR) lpdf2);
            hjancliente = GetParent(hjan);
            hjanmae     = GetParent(hjancliente);
            return 0;

        case WM_SIZE:
            if(wP != SIZE_MINIMIZED) {
                lpdf2 = (LPDADOS_FILHA2) GetWindowLongPtr(hjan,0);
                lpdf2->cxCliente = LOWORD(lP);
                lpdf2->cyCliente = HIWORD(lP);
            }
            break;

        case WM_PAINT:
            InvalidateRect(hjan,NULL,TRUE);
            lpdf2 = (LPDADOS_FILHA2) GetWindowLongPtr(hjan,0);
            xin  = rand() % lpdf2->cxCliente;
            xfin = rand() % lpdf2->cxCliente;
            yin  = rand() % lpdf2->cyCliente;
            yfin = rand() % lpdf2->cyCliente;

            r = rand() & 255;
            g = rand() & 255;
            b = rand() & 255;

            hdc = BeginPaint(hjan, &ps);
            hpincel = CreateSolidBrush(RGB(r, g, b));
            SelectObject(hdc, hpincel);
            Ellipse(
                hdc,
                min(xin,xfin),
                min(yin,yfin),
                max(xin,xfin),
                max(yin,yfin)
            );
            EndPaint(hjan, &ps);
            DeleteObject((HGDIOBJ) hpincel);
            return 0;

        case WM_MDIACTIVATE:
            if(lP==(LPARAM)hjan) {
                SendMessage(
                    hjancliente,
                    WM_MDISETMENU,
                    (WPARAM)hMenuF2,
                    (LPARAM)hMenuJanF2
                );
            }
            else {
                SendMessage(
                    hjancliente,
                    WM_MDISETMENU,
                    (WPARAM)hMenuInic,
                    (LPARAM)hMenuInicJan
                );
            }
            DrawMenuBar(hjanmae);
            return 0;
        case WM_DESTROY:
            lpdf2 = (LPDADOS_FILHA2) GetWindowLongPtr(hjan,0);
            HeapFree(GetProcessHeap(), 0, lpdf2);
            return 0;
    }
    return DefMDIChildProc(hjan, msg, wP, lP);
}



/****** resource.h ******/

#define INIC_MENU_POS  0
#define F1_MENU_POS    1
#define F2_MENU_POS    2

#define IDM_FILHA1     10
#define IDM_FILHA2     20

#define IDM_FECHAR     30
#define IDM_EXIT       40
#define IDM_LADO       50
#define IDM_CASCATA    60
#define IDM_ORGANIZA   70
#define IDM_CLOSEALL   80

#define IDM_PFILHA     90

#define IDM_RECT       100
#define IDM_CIRCULO    110



/****** resource.rc ******/

#include "afxres.h"
#include "resource.h"

Mae MENU DISCARDABLE {
    POPUP "&Arquivo"
    BEGIN
        MENUITEM "New &Rectangle",     IDM_FILHA1
        MENUITEM "Novo &Circulo",      IDM_FILHA2
        MENUITEM "&Fechar",            IDM_FECHAR
        MENUITEM SEPARATOR
        MENUITEM "&Sair",              IDM_EXIT
    END
}

Filha1 MENU DISCARDABLE {
    POPUP "&Arquivo"
    BEGIN
        MENUITEM "New &Rectangle",     IDM_FILHA1
        MENUITEM "Novo &Circulo",      IDM_FILHA2
        MENUITEM "&Fechar",            IDM_FECHAR
        MENUITEM SEPARATOR
        MENUITEM "&Sair",              IDM_EXIT
    END
    POPUP "&Janela"
    BEGIN
        MENUITEM "&Cascata \tF1",      IDM_CASCATA
        MENUITEM "&Lado a Lado \tF2",  IDM_LADO
        MENUITEM "&Organiza",          IDM_ORGANIZA
        MENUITEM "&Fechar Tudo",       IDM_CLOSEALL
    END
    POPUP "&Desenho"
    BEGIN
        MENUITEM "&Rectangle",         IDM_RECT
    END
}

Filha2 MENU DISCARDABLE {
    POPUP "&Arquivo"
    BEGIN
        MENUITEM "New &Rectangle",     IDM_FILHA1
        MENUITEM "New &Circle",        IDM_FILHA2
        MENUITEM "&Fechar",            IDM_FECHAR
        MENUITEM SEPARATOR
        MENUITEM "&Sair",              IDM_EXIT
    END
    POPUP "&Janela"
    BEGIN
        MENUITEM "&Cascata \tF1",      IDM_CASCATA
        MENUITEM "&Lado a Lado \tF2",  IDM_LADO
        MENUITEM "&Organiza",          IDM_ORGANIZA
        MENUITEM "&Close All",         IDM_CLOSEALL
    END
    POPUP "&Desenho"
    BEGIN
        MENUITEM "&Circle",            IDM_CIRCULO
    END
}

Mae ACCELERATORS DISCARDABLE {
    VK_F1, IDM_CASCATA, VIRTKEY
    VK_F2, IDM_LADO,    VIRTKEY
}


Comentários