home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / S12629.ZIP / MDIDEMO.C next >
Text File  |  1990-07-01  |  17KB  |  509 lines

  1. /*--------------------------------------------------------
  2.    MDIDEMO.C -- Multiple Document Interface Demonstration
  3.                 (c) Charles Petzold, 1990
  4.  
  5.    Windows SDK V. 3.0
  6.    Microsoft C V. 6.0
  7.    Windows     V. 3.0
  8.  
  9.   --------------------------------------------------------*/
  10.  
  11. #include <windows.h>
  12. #include <stdlib.h>
  13. #include "mdidemo.h"
  14.  
  15. long FAR PASCAL FrameWndProc  (HWND, WORD, WORD, LONG) ;
  16. BOOL FAR PASCAL CloseEnumProc (HWND, LONG) ;
  17. long FAR PASCAL HelloWndProc  (HWND, WORD, WORD, LONG) ;
  18. long FAR PASCAL RectWndProc   (HWND, WORD, WORD, LONG) ;
  19.  
  20.  // structure for storing data unique to each Hello child window
  21.  
  22. typedef struct
  23.      {
  24.      short    nColor ;
  25.      COLORREF clrText ;
  26.      }
  27.      HELLODATA ;
  28.  
  29. typedef HELLODATA NEAR *NPHELLODATA ;
  30.  
  31.  // structure for storing data unique to each Rect child window
  32.  
  33. typedef struct
  34.      {
  35.      short cxClient ;
  36.      short cyClient ;
  37.      }
  38.      RECTDATA ;
  39.  
  40. typedef RECTDATA NEAR *NPRECTDATA ;
  41.  
  42.  // global variables
  43.  
  44. char   szFrameClass [] = "MdiFrame" ;
  45. char   szHelloClass [] = "MdiHelloChild" ;
  46. char   szRectClass  [] = "MdiRectChild" ;
  47. HANDLE hInst ;
  48. HMENU  hMenuInit, hMenuHello, hMenuRect ;
  49. HMENU  hMenuInitWindow, hMenuHelloWindow, hMenuRectWindow ;
  50.  
  51. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  52.                     LPSTR lpszCmdLine, int nCmdShow)
  53.    {
  54.    HANDLE   hAccel ;
  55.    HWND     hwndFrame, hwndClient ;
  56.    MSG      msg ;
  57.    WNDCLASS wndclass ;
  58.  
  59.    hInst = hInstance ;
  60.  
  61.    if (!hPrevInstance)
  62.       {
  63.                 // Register the frame window class
  64.  
  65.       wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  66.       wndclass.lpfnWndProc   = FrameWndProc ;
  67.       wndclass.cbClsExtra    = 0 ;
  68.       wndclass.cbWndExtra    = 0 ;
  69.       wndclass.hInstance     = hInstance ;
  70.       wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  71.       wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  72.       wndclass.hbrBackground = COLOR_APPWORKSPACE + 1 ;
  73.       wndclass.lpszMenuName  = NULL ;
  74.       wndclass.lpszClassName = szFrameClass ;
  75.  
  76.       RegisterClass (&wndclass) ;
  77.  
  78.                 // Register the Hello child window class
  79.  
  80.       wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  81.       wndclass.lpfnWndProc   = HelloWndProc ;
  82.       wndclass.cbClsExtra    = 0 ;
  83.       wndclass.cbWndExtra    = sizeof (LOCALHANDLE) ;
  84.       wndclass.hInstance     = hInstance ;
  85.       wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  86.       wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  87.       wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
  88.       wndclass.lpszMenuName  = NULL ;
  89.       wndclass.lpszClassName = szHelloClass ;
  90.  
  91.       RegisterClass (&wndclass) ;
  92.  
  93.                 // Register the Rect child window class
  94.  
  95.       wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  96.       wndclass.lpfnWndProc   = RectWndProc ;
  97.       wndclass.cbClsExtra    = 0 ;
  98.       wndclass.cbWndExtra    = sizeof (LOCALHANDLE) ;
  99.       wndclass.hInstance     = hInstance ;
  100.       wndclass.hIcon         = NULL ;
  101.       wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  102.       wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
  103.       wndclass.lpszMenuName  = NULL ;
  104.       wndclass.lpszClassName = szRectClass ;
  105.  
  106.       RegisterClass (&wndclass) ;
  107.       }
  108.            // Obtain handles to three possible menus & submenus
  109.  
  110.    hMenuInit  = LoadMenu (hInst, "MdiMenuInit") ;
  111.    hMenuHello = LoadMenu (hInst, "MdiMenuHello") ;
  112.    hMenuRect  = LoadMenu (hInst, "MdiMenuRect") ;
  113.  
  114.    hMenuInitWindow  = GetSubMenu (hMenuInit,   INIT_MENU_POS) ;
  115.    hMenuHelloWindow = GetSubMenu (hMenuHello, HELLO_MENU_POS) ;
  116.    hMenuRectWindow  = GetSubMenu (hMenuRect,   RECT_MENU_POS) ;
  117.  
  118.              // Load accelerator table
  119.  
  120.    hAccel = LoadAccelerators (hInst, "MdiAccel") ;
  121.  
  122.              // Create the frame window
  123.  
  124.    hwndFrame = CreateWindow (szFrameClass, "MDI Demonstration",
  125.                              WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  126.                              CW_USEDEFAULT, CW_USEDEFAULT,
  127.                              CW_USEDEFAULT, CW_USEDEFAULT,
  128.                              NULL, hMenuInit, hInstance, NULL) ;
  129.  
  130.    hwndClient = GetWindow (hwndFrame, GW_CHILD) ;
  131.  
  132.    ShowWindow (hwndFrame, nCmdShow) ;
  133.    UpdateWindow (hwndFrame) ;
  134.  
  135.              // Enter the modified message loop
  136.  
  137.    while (GetMessage (&msg, NULL, 0, 0))
  138.         {
  139.         if (!TranslateMDISysAccel (hwndClient, &msg) &&
  140.             !TranslateAccelerator (hwndFrame, hAccel, &msg))
  141.              {
  142.              TranslateMessage (&msg) ;
  143.              DispatchMessage (&msg) ;
  144.              }
  145.         }
  146.    return msg.wParam ;
  147.    }
  148.  
  149. long FAR PASCAL FrameWndProc (HWND hwnd, WORD message,
  150.                               WORD wParam, LONG lParam)
  151.    {
  152.    static HWND        hwndClient ;
  153.    CLIENTCREATESTRUCT clientcreate ;
  154.    FARPROC            lpfnEnum ;
  155.    HWND               hwndChild, hwndNext ;
  156.    MDICREATESTRUCT    mdicreate ;
  157.  
  158.    switch (message)
  159.       {
  160.       case WM_CREATE:          // Create the client window
  161.  
  162.          clientcreate.hWindowMenu  = hMenuInitWindow ;
  163.          clientcreate.idFirstChild = IDM_FIRSTCHILD ;
  164.  
  165.          hwndClient = CreateWindow ("MDICLIENT", NULL,
  166.                         WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
  167.                         0, 0, 0, 0, hwnd, 1, hInst,
  168.                         (LPSTR) &clientcreate) ;
  169.          return 0 ;
  170.  
  171.       case WM_COMMAND:
  172.          switch (wParam)
  173.            {
  174.            case IDM_NEWHELLO:       // Create a Hello child window
  175.  
  176.               mdicreate.szClass = szHelloClass ;
  177.               mdicreate.szTitle = "Hello" ;
  178.               mdicreate.hOwner  = hInst ;
  179.               mdicreate.x       = CW_USEDEFAULT ;
  180.               mdicreate.y       = CW_USEDEFAULT ;
  181.               mdicreate.cx      = CW_USEDEFAULT ;
  182.               mdicreate.cy      = CW_USEDEFAULT ;
  183.               mdicreate.style   = 0 ;
  184.               mdicreate.lParam  = NULL ;
  185.  
  186.               hwndChild = SendMessage (hwndClient, WM_MDICREATE, 0,
  187.                              (LONG) (LPMDICREATESTRUCT) &mdicreate) ;
  188.               return 0 ;
  189.  
  190.            case IDM_NEWRECT:        // Create a Rect child window
  191.  
  192.               mdicreate.szClass = szRectClass ;
  193.               mdicreate.szTitle = "Rectangles" ;
  194.               mdicreate.hOwner  = hInst ;
  195.               mdicreate.x       = CW_USEDEFAULT ;
  196.               mdicreate.y       = CW_USEDEFAULT ;
  197.               mdicreate.cx      = CW_USEDEFAULT ;
  198.               mdicreate.cy      = CW_USEDEFAULT ;
  199.               mdicreate.style   = 0 ;
  200.               mdicreate.lParam  = NULL ;
  201.  
  202.               hwndChild = SendMessage (hwndClient,  WM_MDICREATE, 0,
  203.                              (LONG) (LPMDICREATESTRUCT) &mdicreate) ;
  204.               return 0 ;
  205.  
  206.            case IDM_CLOSE:          // Close the active window
  207.  
  208.               hwndChild = LOWORD (SendMessage (hwndClient,
  209.                                        WM_MDIGETACTIVE, 0, 0L)) ;
  210.  
  211.               if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0L))
  212.                    SendMessage (hwndClient, WM_MDIDESTROY,
  213.                                 hwndChild, 0L) ;
  214.               return 0 ;
  215.  
  216.            case IDM_EXIT:           // Exit the program
  217.  
  218.               SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
  219.               return 0 ;
  220.  
  221.                         // Messages for arranging windows
  222.            case IDM_TILE:
  223.               SendMessage (hwndClient, WM_MDITILE, 0, 0L) ;
  224.               return 0 ;
  225.  
  226.            case IDM_CASCADE:
  227.               SendMessage (hwndClient, WM_MDICASCADE, 0, 0L) ;
  228.               return 0 ;
  229.  
  230.            case IDM_ARRANGE:
  231.               SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0L) ;
  232.               return 0 ;
  233.  
  234.            case IDM_CLOSEALL:       // Attempt to close all children
  235.  
  236.               lpfnEnum = MakeProcInstance (CloseEnumProc, hInst) ;
  237.               EnumChildWindows (hwndClient, lpfnEnum, 0L) ;
  238.               FreeProcInstance (lpfnEnum) ;
  239.               return 0 ;
  240.  
  241.            default:            // Pass to active child
  242.  
  243.               hwndChild = LOWORD (SendMessage (hwndClient,
  244.                                   WM_MDIGETACTIVE, 0, 0L)) ;
  245.  
  246.              if (IsWindow (hwndChild))
  247.                   SendMessage (hwndChild, WM_COMMAND,
  248.                                wParam, lParam) ;
  249.  
  250.              break ;        // and then to DefFrameProc
  251.            }
  252.          break ;
  253.  
  254.       case WM_QUERYENDSESSION:
  255.       case WM_CLOSE:       // Attempt to close all children
  256.  
  257.          SendMessage (hwnd, WM_COMMAND, IDM_CLOSEALL, 0L) ;
  258.  
  259.          if (NULL != GetWindow (hwndClient, GW_CHILD))
  260.               return 0 ;
  261.  
  262.          break ;   // ie, call DefFrameProc ;
  263.  
  264.       case WM_DESTROY :
  265.          PostQuitMessage (0) ;
  266.          return 0 ;
  267.       }
  268.         // Pass unprocessed msgs to DefFrameProc (not DefWindowProc)
  269.  
  270.    return DefFrameProc (hwnd, hwndClient, message, wParam, lParam) ;
  271.    }
  272.  
  273. BOOL FAR PASCAL CloseEnumProc (HWND hwnd, LONG lParam)
  274.      {
  275.      if (GetWindow (hwnd, GW_OWNER))         // check for icon title
  276.           return 1 ;
  277.  
  278.      SendMessage (GetParent (hwnd), WM_MDIRESTORE, hwnd, 0L) ;
  279.  
  280.      if (!SendMessage (hwnd, WM_QUERYENDSESSION, 0, 0L))
  281.           return 1 ;
  282.  
  283.      SendMessage (GetParent (hwnd), WM_MDIDESTROY, hwnd, 0L) ;
  284.           return 1 ;
  285.      }
  286.  
  287. long FAR PASCAL HelloWndProc (HWND hwnd, WORD message,
  288.                             WORD wParam, LONG lParam)
  289.    {
  290.    static COLORREF clrTextArray [] = { RGB (  0,   0,   0),
  291.                                        RGB (255,   0,   0),
  292.                                        RGB (  0, 255,   0),
  293.                                        RGB (  0,   0, 255),
  294.                                        RGB (255, 255, 255) } ;
  295.    static HWND     hwndClient, hwndFrame ;
  296.    HDC             hdc ;
  297.    HMENU           hMenu ;
  298.    LOCALHANDLE     hHelloData ;
  299.    NPHELLODATA     npHelloData ;
  300.    PAINTSTRUCT     ps ;
  301.    RECT            rect ;
  302.  
  303.    switch (message)
  304.       {
  305.       case WM_CREATE:
  306.                    // Allocate memory for window private data
  307.  
  308.          hHelloData = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
  309.                                   sizeof (HELLODATA)) ;
  310.  
  311.          npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
  312.          npHelloData->nColor  = IDM_BLACK ;
  313.          npHelloData->clrText = RGB (0, 0, 0) ;
  314.          LocalUnlock (hHelloData) ;
  315.          SetWindowWord (hwnd, 0, hHelloData) ;
  316.  
  317.                    // Save some window handles
  318.  
  319.          hwndClient = GetParent (hwnd) ;
  320.          hwndFrame  = GetParent (hwndClient) ;
  321.          return 0 ;
  322.  
  323.       case WM_COMMAND:
  324.          switch (wParam)
  325.             {
  326.             case IDM_BLACK:
  327.             case IDM_RED:
  328.             case IDM_GREEN:
  329.             case IDM_BLUE:
  330.             case IDM_WHITE:
  331.                          // Change the text color
  332.  
  333.                hHelloData  = GetWindowWord (hwnd, 0) ;
  334.                npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
  335.  
  336.                hMenu = GetMenu (hwndFrame) ;
  337.  
  338.                CheckMenuItem (hMenu, npHelloData->nColor,
  339.                                      MF_UNCHECKED) ;
  340.                npHelloData->nColor = wParam ;
  341.                CheckMenuItem (hMenu, npHelloData->nColor,
  342.                                      MF_CHECKED) ;
  343.  
  344.                npHelloData->clrText =
  345.                      clrTextArray [wParam - IDM_BLACK] ;
  346.  
  347.                LocalUnlock (hHelloData) ;
  348.                InvalidateRect (hwnd, NULL, FALSE) ;
  349.             }
  350.          return 0 ;
  351.  
  352.       case WM_PAINT:
  353.                    // Paint the window
  354.  
  355.          hdc = BeginPaint (hwnd, &ps) ;
  356.  
  357.          hHelloData  = GetWindowWord (hwnd, 0) ;
  358.          npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
  359.          SetTextColor (hdc, npHelloData->clrText) ;
  360.          LocalUnlock (hHelloData) ;
  361.  
  362.          GetClientRect (hwnd, &rect) ;
  363.  
  364.          DrawText (hdc, "Hello, World!", -1, &rect,
  365.                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
  366.  
  367.          EndPaint (hwnd, &ps) ;
  368.          return 0 ;
  369.  
  370.       case WM_MDIACTIVATE:
  371.  
  372.                    // Set the Hello menu if gaining focus
  373.  
  374.          if (wParam == TRUE)
  375.               SendMessage (hwndClient, WM_MDISETMENU, 0,
  376.                            MAKELONG (hMenuHello, hMenuHelloWindow)) ;
  377.  
  378.                    // check or uncheck menu item
  379.  
  380.          hHelloData  = GetWindowWord (hwnd, 0) ;
  381.          npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
  382.          CheckMenuItem (hMenuHello, npHelloData->nColor,
  383.                         wParam ? MF_CHECKED : MF_UNCHECKED) ;
  384.          LocalUnlock (hHelloData) ;
  385.  
  386.                    // Set the Init menu if losing focus
  387.  
  388.          if (wParam == FALSE)
  389.               SendMessage (hwndClient, WM_MDISETMENU, 0,
  390.                            MAKELONG (hMenuInit, hMenuInitWindow)) ;
  391.  
  392.          DrawMenuBar (hwndFrame) ;
  393.          return 0 ;
  394.  
  395.       case WM_QUERYENDSESSION:
  396.       case WM_CLOSE:
  397.          if (IDOK != MessageBox (hwnd,"OK to close window?","Hello",
  398.                                  MB_ICONQUESTION | MB_OKCANCEL))
  399.               return 0 ;
  400.  
  401.          break ;   // ie, call DefMDIChildProc
  402.  
  403.       case WM_DESTROY:
  404.          hHelloData = GetWindowWord (hwnd, 0) ;
  405.          LocalFree (hHelloData) ;
  406.          return 0 ;
  407.       }
  408.          // Pass unprocessed message to DefMDIChildProc
  409.  
  410.    return DefMDIChildProc (hwnd, message, wParam, lParam) ;
  411.    }
  412.  
  413. long FAR PASCAL RectWndProc (HWND hwnd, WORD message,
  414.                            WORD wParam, LONG lParam)
  415.    {
  416.    static HWND hwndClient, hwndFrame ;
  417.    HPEN        hBrush ;
  418.    HDC         hdc ;
  419.    LOCALHANDLE hRectData ;
  420.    NPRECTDATA  npRectData ;
  421.    PAINTSTRUCT ps ;
  422.    short       xLeft, xRight, yTop, yBottom, nRed, nGreen, nBlue ;
  423.  
  424.    switch (message)
  425.         {
  426.       case WM_CREATE:
  427.                    // Allocate memory for window private data
  428.  
  429.          hRectData = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
  430.                                  sizeof (RECTDATA)) ;
  431.  
  432.          SetWindowWord (hwnd, 0, hRectData) ;
  433.  
  434.                    // Start the timer going
  435.  
  436.          SetTimer (hwnd, 1, 250, NULL) ;
  437.  
  438.                    // Save some window handles
  439.  
  440.          hwndClient = GetParent (hwnd) ;
  441.          hwndFrame  = GetParent (hwndClient) ;
  442.          return 0 ;
  443.  
  444.       case WM_SIZE:            // Save the window size
  445.  
  446.          hRectData  = GetWindowWord (hwnd, 0) ;
  447.          npRectData = (NPRECTDATA) LocalLock (hRectData) ;
  448.  
  449.          npRectData->cxClient = LOWORD (lParam) ;
  450.          npRectData->cyClient = HIWORD (lParam) ;
  451.  
  452.          LocalUnlock (hRectData) ;
  453.  
  454.          break ; //WM_SIZE must be processed by DefMDIChildProc
  455.  
  456.       case WM_TIMER:           // Display a random rectangle
  457.  
  458.          hRectData  = GetWindowWord (hwnd, 0) ;
  459.          npRectData = (NPRECTDATA) LocalLock (hRectData) ;
  460.  
  461.          xLeft   = rand () % npRectData->cxClient ;
  462.          xRight  = rand () % npRectData->cxClient ;
  463.          yTop    = rand () % npRectData->cyClient ;
  464.          yBottom = rand () % npRectData->cyClient ;
  465.          nRed    = rand () & 255 ;
  466.          nGreen  = rand () & 255 ;
  467.          nBlue   = rand () & 255 ;
  468.  
  469.          hdc = GetDC (hwnd) ;
  470.          hBrush = CreateSolidBrush (RGB (nRed, nGreen, nBlue)) ;
  471.          SelectObject (hdc, hBrush) ;
  472.  
  473.          Rectangle (hdc, min (xLeft, xRight), min (yTop, yBottom),
  474.                          max (xLeft, xRight), max (yTop, yBottom)) ;
  475.  
  476.          ReleaseDC (hwnd, hdc) ;
  477.          DeleteObject (hBrush) ;
  478.          LocalUnlock (hRectData) ;
  479.          return 0 ;
  480.  
  481.       case WM_PAINT:           // Clear the window
  482.  
  483.          InvalidateRect (hwnd, NULL, TRUE) ;
  484.          hdc = BeginPaint (hwnd, &ps) ;
  485.          EndPaint (hwnd, &ps) ;
  486.          return 0 ;
  487.  
  488.       case WM_MDIACTIVATE:     // Set the appropriate menu
  489.          if (wParam == TRUE)
  490.               SendMessage (hwndClient, WM_MDISETMENU, 0,
  491.                            MAKELONG (hMenuRect, hMenuRectWindow)) ;
  492.          else
  493.               SendMessage (hwndClient, WM_MDISETMENU, 0,
  494.                            MAKELONG (hMenuInit, hMenuInitWindow)) ;
  495.  
  496.          DrawMenuBar (hwndFrame) ;
  497.          return 0 ;
  498.  
  499.       case WM_DESTROY:
  500.          hRectData = GetWindowWord (hwnd, 0) ;
  501.          LocalFree (hRectData) ;
  502.          KillTimer (hwnd, 1) ;
  503.          return 0 ;
  504.       }
  505.          // Pass unprocessed message to DefMDIChildProc
  506.  
  507.    return DefMDIChildProc (hwnd, message, wParam, lParam) ;
  508.    }
  509.