/* child.cpp    Creates and Sends a message to a child window */

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

int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine,
    int nCmdShow)
{
    HWND        hWnd ;      /* the window's "handle" */
    MSG         msg ;       /* a message structure */
    WNDCLASS    wndclass ;  /* window class structure */

                            /* define the parent window class */
    wndclass.style          = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc    = WndProc ;
    wndclass.cbClsExtra     = 0 ;
    wndclass.cbWndExtra     = 0 ;
    wndclass.hInstance      = hInstance ;
    wndclass.hIcon          = NULL ;
    wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName   = "PARENTMENU" ;
    wndclass.lpszClassName  = "MyClass" ;
                                                        /* register the parent window class */
    if (!RegisterClass (&wndclass))
        return (0) ;
                            /* create the parent window */
    hWnd = CreateWindow ("MyClass","Child Window Example", WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL) ;
    ShowWindow (hWnd, nCmdShow) ;   /* display the window */    
    UpdateWindow (hWnd) ;       

                                                        /* define the child window class */
    wndclass.lpfnWndProc    = ChildProc ;
    wndclass.hIcon          = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor        = LoadCursor (NULL, IDC_CROSS) ;
    wndclass.hbrBackground  = (HBRUSH)GetStockObject (LTGRAY_BRUSH) ;
    wndclass.lpszMenuName   = NULL ;
    wndclass.lpszClassName  = "ChildClass" ;
                                                        /* register the child window class */
    if (!RegisterClass (&wndclass))
    {
         MessageBox (hWnd, "Could not register class",
             "Message", MB_OK) ;
         return (0) ;
    }

    while (GetMessage (&msg, NULL, 0, 0))   /* message loop */
    {
        TranslateMessage (&msg) ;   /* translate keyboard messages */
        DispatchMessage (&msg) ;    /* send message to WndProc() */
    }
    return (msg.wParam) ;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT wMessage, 
                                    WPARAM wParam, LPARAM lParam)
{
    static  HWND        hChild = NULL ;
    PAINTSTRUCT         ps ;
    HINSTANCE           hInstance ;
    
    switch (wMessage)               /* process windows messages */
    {
        case WM_COMMAND:            /* menu items */
            switch (LOWORD(wParam))
            {
                case IDM_CREATE:    /* create the child window */
                    if (!hChild)
                    {
                        hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
                               /* create the child window and display it */
                        hChild = CreateWindow ("ChildClass", "Child Window", 
                            WS_CHILD | WS_THICKFRAME | WS_MINIMIZEBOX |
                            WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU, 
                            10, 30, 300, 150, hWnd, 
                            NULL, hInstance, NULL) ;
                        ShowWindow (hChild, SW_SHOWNORMAL) ;   
                    }
                    break ;
                case IDM_SEND:  /* send a custom message to child */
                    if (hChild)
                        SendMessage (hChild, WM_USER, 0, 0) ;
                    break ;
                case IDM_QUIT:
                    DestroyWindow (hWnd) ;  /* destroy window, */
                    break ;     /* terminating application */
            }
            break ;
        case WM_PAINT:
            BeginPaint (hWnd, &ps) ;
            TextOut (ps.hdc, 10, 10, "Text In Parent Client Area.", 27) ;
            EndPaint (hWnd, &ps) ;
            break ;
        case WM_USER+1:                 /* child has been destroyed */
            hChild = NULL;
            break;
        case WM_DESTROY:                /* stop application */
            PostQuitMessage (0) ;
            break ;
        default:                                /* default windows message processing */
            return DefWindowProc (hWnd, wMessage, wParam, lParam) ;
    }
    return (0) ;
}

/* Window procedure for the child window. */

LRESULT CALLBACK ChildProc (HWND hChild, UINT wMessage, 
                                       WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT     ps ;
    HINSTANCE       hInstance ;
    HWND            hParent;

    switch (wMessage)       /* process windows messages */
    {
        case WM_CREATE:     /* child being created - make a button */
            hInstance = (HINSTANCE)GetWindowLong (hChild, GWL_HINSTANCE) ;
            CreateWindow ("BUTTON", "Destroy Me",
                          WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE,
                          20, 55, 110, 40, hChild, (HMENU)100, hInstance, NULL) ;
            break ;
        case WM_COMMAND:    /* button control is only possible source */
            hParent=GetParent(hChild);
            DestroyWindow (hChild) ;    /* kill the child window */
            SendMessage(hParent,WM_USER+1,0,0); /* notify parent */           
            break ;
        case WM_USER:       /* custom message from parent */
            SetWindowText (hChild, "Got message from parent.") ;
            break ;
        case WM_PAINT:
            BeginPaint (hChild, &ps) ;
            TextOut (ps.hdc, 10, 35, "Text in Child Window.", 21) ;
            EndPaint (hChild, &ps) ;
            break ;
        default:                        /* default windows message processing */
            return DefWindowProc (hChild, wMessage, wParam, lParam) ;
    }
    return (0) ;
}