home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 7.ddi / MWHC.007 / I6 < prev    next >
Encoding:
Text File  |  1991-10-23  |  18.1 KB  |  507 lines

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