home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / BLANDMDI.PAK / BLANDMDI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  14.0 KB  |  519 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   blandmdi.c
  9. //
  10. //  PURPOSE:  Implement the window procedure for the main application
  11. //            window.
  12. //
  13. //  FUNCTIONS:
  14. //    WndProc           - Processes messages for the main window.
  15. //    MsgCreate         - To create the MDI client window.
  16. //    MsgCommand        - Handle the WM_COMMAND messages for the main window.
  17. //    MsgDestroy        - Handles the WM_DESTROY message by calling 
  18. //                        PostQuitMessage().
  19. //    CmdFileNew        - To create a new mdi child window.
  20. //    CmdWindowTile     - To tile the mdi child windows.
  21. //    CmdWindowCascade  - To cascade the mdi child windows.
  22. //    CmdWindowIcons    - To arrage the mdi child icons.
  23. //    CmdWindowCloseAll - To close all of the mdi child windows.
  24. //    CmdExit           - Handles the file exit command by calling destory 
  25. //                        window on the main window.
  26. //
  27. //  COMMENTS:
  28. //    Message dispatch table -
  29. //      For every message to be handled by the main window procedure
  30. //      place the message number and handler function pointer in
  31. //      rgmsd (the message dispatch table).  Place the prototype
  32. //      for the function in globals.h and the definition of the
  33. //      function in the appropriate module.
  34. //    Command dispatch table -
  35. //      For every command to be handled by the main window procedure
  36. //      place the command number and handler function pointer in
  37. //      rgcmd (the command dispatch table).  Place the prototype
  38. //      for the function in globals.h and the definition of the
  39. //      function in the appropriate module.
  40. //    Globals.h Contains the definitions of the structures and dispatch.c
  41. //      contains the functions that use these structures.
  42. //
  43.  
  44. #include <windows.h>            // required for all Windows applications
  45. #include <windowsx.h>
  46. #ifdef WIN16
  47. #include "win16ext.h"           // required only for win16 applications
  48. #endif
  49. #include "globals.h"            // prototypes specific to this application
  50. #include "resource.h"
  51.  
  52. // Main window message table definition.
  53. MSD rgmsd[] =
  54. {
  55.     {WM_INITMENU,   MsgInitMenu},
  56.     {WM_COMMAND,    MsgCommand},
  57.     {WM_CREATE,     MsgCreate},
  58.     {WM_DESTROY,    MsgDestroy}
  59. };
  60.  
  61. MSDI msdiMain =
  62. {
  63.     sizeof(rgmsd) / sizeof(MSD),
  64.     rgmsd,
  65.     edwpMDIFrame
  66. };
  67.  
  68.  
  69. // Main window command table definition.
  70. CMD rgcmd[] =
  71. {
  72.     {IDM_FILENEW,       CmdFileNew},
  73.     {IDM_FILECLOSE,     CmdFileClose},
  74.     {IDM_EXIT,          CmdExit},
  75.     {IDM_ABOUT,         CmdAbout},
  76.     {IDM_WINDOWTILE,    CmdWindowTile},
  77.     {IDM_WINDOWCASCADE, CmdWindowCascade},
  78.     {IDM_WINDOWICONS,   CmdWindowIcons},
  79.     {IDM_WINDOWCLOSEALL,CmdWindowCloseAll}
  80. };
  81.  
  82. CMDI cmdiMain =
  83. {
  84.     sizeof(rgcmd) / sizeof(CMD),
  85.     rgcmd,
  86.     edwpMDIFrame
  87. };
  88.  
  89. // Module specific globals
  90.  
  91. HWND hwndMDIClient = NULL;      // The MDI client window handle.
  92. UINT cUntitled = 1;
  93. UINT cOpen = 0;
  94. extern char szChildName[];
  95.  
  96.  
  97. //
  98. //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  99. //
  100. //  PURPOSE:  Processes messages for the main window.
  101. //
  102. //  PARAMETERS:
  103. //    hwnd     - window handle
  104. //    uMessage - message number
  105. //    wparam   - additional information (dependant on message number)
  106. //    lparam   - additional information (dependant on message number)
  107. //
  108. //  RETURN VALUE:
  109. //    The return value depends on the message number.  If the message
  110. //    is implemented in the message dispatch table, the return value is
  111. //    the value returned by the message handling function.  Otherwise,
  112. //    the return value is the value returned by the default window procedure.
  113. //
  114. //  COMMENTS:
  115. //    Call the DispMessage() function with the main window's message dispatch
  116. //    information (msdiMain) and the message specific information.
  117. //
  118.  
  119. LRESULT CALLBACK WndProc(HWND   hwnd, 
  120.                          UINT   uMessage, 
  121.                          WPARAM wparam, 
  122.                          LPARAM lparam)
  123. {
  124.     return DispMessage(&msdiMain, hwnd, uMessage, wparam, lparam);
  125. }
  126.  
  127.  
  128. //
  129. //  FUNCTION: MsgCommand(HWND, UINT, WPARAM, LPARAM)
  130. //
  131. //  PURPOSE: Handle the WM_COMMAND messages for the main window.
  132. //
  133. //  PARAMETERS:
  134. //    hwnd     - window handle
  135. //    uMessage - WM_COMMAND (Unused)
  136. //    GET_WM_COMMAND_ID(wparam, lparam)   - Command identifier
  137. //    GET_WM_COMMAND_HWND(wparam, lparam) - Control handle
  138. //
  139. //  RETURN VALUE:
  140. //    The return value depends on the message number.  If the message
  141. //    is implemented in the message dispatch table, the return value is
  142. //    the value returned by the message handling function.  Otherwise,
  143. //    the return value is the value returned by the default window procedure.
  144. //
  145. //  COMMENTS:
  146. //    Call the DispCommand() function with the main window's command dispatch
  147. //    information (cmdiMain) and the command specific information.
  148. //
  149.  
  150. #pragma argsused
  151. LRESULT MsgCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  152. {
  153.     return DispCommand(&cmdiMain, hwnd, wparam, lparam);
  154. }
  155.  
  156.  
  157. //
  158. //  FUNCTION: MsgCreate(HWND, UINT, WPARAM, LPARAM)
  159. //
  160. //  PURPOSE: To create an MDI client window.
  161. //
  162. //  PARAMETERS:
  163. //    hwnd - The window handing the message.
  164. //    uMessage - WM_CREATE (unused)
  165. //    wparam - Message specific data (unused).
  166. //    lparam - Message specific data (unused).
  167. //
  168. //  RETURN VALUE:
  169. //    Always returns 0 - message handled.
  170. //
  171. //  COMMENTS:
  172. //
  173. //
  174.  
  175. #pragma argsused
  176. LRESULT MsgCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  177. {
  178.     CLIENTCREATESTRUCT ccs = {0};
  179.  
  180.     // Find window menu where children will be listed
  181.     ccs.hWindowMenu  = GetSubMenu(GetMenu(hwnd), WINDOWMENU);
  182.     ccs.idFirstChild = IDM_WINDOWCHILD;
  183.  
  184.      // Create the MDI client filling the client area
  185.     hwndMDIClient = CreateWindow("mdiclient",
  186.                                  NULL,
  187.                                  WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL |
  188.                                  WS_HSCROLL,
  189.                                  0, 0, 0, 0,
  190.                                  hwnd,
  191.                                  (HMENU)0xCAC,
  192.                                  hInst,
  193.                                  (LPVOID)&ccs);
  194.  
  195.     ShowWindow(hwndMDIClient, SW_SHOW);
  196.  
  197.      return 0;
  198. }
  199.  
  200.  
  201. //
  202. //  FUNCTION: MsgInitMenu(HWND, UINT, WPARAM, LPARAM)
  203. //
  204. //  PURPOSE: Enable/Disable the close menu command.
  205. //
  206. //  PARAMETERS:
  207. //
  208. //    hwnd      - Window handle
  209. //    uMessage  - Message number (Unused)
  210. //    wparam    - HMENU - The menu about to be activated
  211. //    lparam    - Extra data     (Unused)
  212. //
  213. //  RETURN VALUE:
  214. //
  215. //    0 - The message was handled.
  216. //    1 - The message was not handled - wrong menu.
  217. //
  218. //  COMMENTS:
  219. //
  220. //
  221.  
  222. #pragma argsused
  223. LRESULT MsgInitMenu(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  224. {
  225.     if (GetMenu(hwnd) == (HMENU)wparam)
  226.     {
  227.         UINT mf = (cOpen) ? MF_ENABLED : MF_GRAYED;
  228.  
  229.         EnableMenuItem((HMENU)wparam, IDM_FILECLOSE, mf);
  230.  
  231.         return 0;
  232.     }
  233.     else
  234.     {
  235.           return 1;
  236.     }
  237. }
  238.  
  239.  
  240. //
  241. //  FUNCTION: MsgDestroy(HWND, UINT, WPARAM, LPARAM)
  242. //
  243. //  PURPOSE: Calls PostQuitMessage().
  244. //
  245. //  PARAMETERS:
  246. //
  247. //    hwnd      - Window handle  (Unused)
  248. //    uMessage  - Message number (Unused)
  249. //    wparam    - Extra data     (Unused)
  250. //    lparam    - Extra data     (Unused)
  251. //
  252. //  RETURN VALUE:
  253. //
  254. //    Always returns 0 - Message handled
  255. //
  256. //  COMMENTS:
  257. //
  258. //
  259.  
  260. #pragma argsused
  261. LRESULT MsgDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  262. {
  263.     PostQuitMessage(0);
  264.     return 0;
  265. }
  266.  
  267.  
  268. //
  269. //  FUNCTION: CmdFileNew(HWND, WORD, WORD, HWND)
  270. //
  271. //  PURPOSE: To create a new mdi child window.
  272. //
  273. //  PARAMETERS:
  274. //    hwnd - The window handling the command.
  275. //    wCommand - IDM_FILENEW (unused)
  276. //    hwndCtrl - NULL (unused).
  277. //
  278. //  RETURN VALUE:
  279. //    Always returns 0 - command handled.
  280. //
  281. //  COMMENTS:
  282. //
  283. //
  284.  
  285. #pragma argsused
  286. LRESULT CmdFileNew(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  287. {
  288.      HWND hwndChild;
  289.     char rgch[15];
  290.     DWORD dwVersion;
  291.  
  292.     wsprintf(rgch,"Untitled%d", cUntitled);
  293.  
  294.     // Create the MDI child window
  295.         
  296.     // Windows NT and Windows 95 present different options for creating
  297.     // an MDI child window.  While using the WM_MDICREATE message will
  298.     // work on both Windows versions, Windows 95 presents a new window
  299.     // style which simplifies the process.  Here the function uses the
  300.     // method apropriate for the system it's running on.
  301.      dwVersion = GetVersion();
  302.      if ((dwVersion < 0x80000000L) || (LOBYTE(LOWORD(dwVersion)) < 4))
  303.     {
  304.         // This is Windows NT or Win32s, so use the WM_MDICREATE message
  305.           MDICREATESTRUCT mcs;
  306.  
  307.         mcs.szClass = szChildName;      // window class name
  308.         mcs.szTitle = rgch;             // window title
  309.         mcs.hOwner  = hInst;            // owner
  310.         mcs.x       = CW_USEDEFAULT;    // x position
  311.         mcs.y       = CW_USEDEFAULT;    // y position
  312.         mcs.cx      = CW_USEDEFAULT;    // width
  313.         mcs.cy      = CW_USEDEFAULT;    // height
  314.           mcs.style   = 0;                // window style
  315.         mcs.lParam  = 0;                // lparam
  316.  
  317.         hwndChild = (HWND) SendMessage(hwndMDIClient, 
  318.                                        WM_MDICREATE, 
  319.                                        0,
  320.                                        (LPARAM)(LPMDICREATESTRUCT) &mcs);
  321.     }
  322.     else
  323.     {
  324.         hwndChild = CreateWindowEx(WS_EX_MDICHILD,  // EX window style
  325.                                    szChildName,     // window class name
  326.                                    rgch,            // window title
  327.                                               0,               // window style
  328.                                    CW_USEDEFAULT,   // x position
  329.                                    CW_USEDEFAULT,   // y position
  330.                                    CW_USEDEFAULT,   // width
  331.                                    CW_USEDEFAULT,   // height
  332.                                    hwndMDIClient,   // parent
  333.                                    NULL,            // menu (child ID)
  334.                                    hInst,           // owner
  335.                                    0);              // lparam
  336.     }
  337.  
  338.     if (hwndChild != NULL)
  339.         ShowWindow(hwndChild, SW_SHOW);
  340.  
  341.     cUntitled++;
  342.     cOpen++;
  343.     return 0;
  344. }
  345.  
  346.  
  347. //
  348. //  FUNCTION: CmdExit(HWND, WORD, WORD, HWND)
  349. //
  350. //  PURPOSE: Exit the application.
  351. //
  352. //  PARAMETERS:
  353. //    hwnd     - The window.
  354. //    wCommand - IDM_EXIT (unused)
  355. //    wNotify  - Notification number (unused)
  356. //    hwndCtrl - NULL (unused)
  357. //
  358. //  RETURN VALUE:
  359. //    Always returns 0 - command handled.
  360. //
  361. //  COMMENTS:
  362. //
  363. //
  364.  
  365. #pragma argsused
  366. LRESULT CmdExit(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  367. {
  368.     DestroyWindow(hwnd);
  369.     return 0;
  370. }
  371.  
  372.  
  373. //
  374. //  FUNCTION: CmdFileClose(HWND, WORD, WORD, HWND)
  375. //
  376. //  PURPOSE: To close all of the mdi child windows.
  377. //
  378. //  PARAMETERS:
  379. //    hwnd - The window handling the command.
  380. //    wCommand - IDM_FILECLOSE (unused).
  381. //    hwndCtrl - NULL (unused).
  382. //
  383. //  RETURN VALUE:
  384. //    Always returns 0 - command handled.
  385. //
  386. //  COMMENTS:
  387. //
  388. //
  389.  
  390. #pragma argsused
  391. LRESULT CmdFileClose(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  392. {
  393.      HWND hwndT;
  394.  
  395.     hwndT = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L);
  396.     if (hwndT != NULL)
  397.         SendMessage(hwndMDIClient, WM_MDIDESTROY, (WPARAM)hwndT, 0L);
  398.  
  399.     return 0;
  400. }
  401.  
  402.  
  403. //
  404. //  FUNCTION: CmdWindowTile(HWND, WORD, WORD, HWND)
  405. //
  406. //  PURPOSE: To tile the mdi child windows.
  407. //
  408. //  PARAMETERS:
  409. //    hwnd - The window handling the command.
  410. //    wCommand - IDM_WINDOWTILE (unused).
  411. //    hwndCtrl - NULL (unused).
  412. //
  413. //  RETURN VALUE:
  414. //    Always returns 0 - command handled.
  415. //
  416. //  COMMENTS:
  417. //
  418. //
  419.  
  420. #pragma argsused
  421. LRESULT CmdWindowTile(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  422. {
  423.     SendMessage(hwndMDIClient, WM_MDITILE, 0, 0L);
  424.  
  425.     return 0;
  426. }
  427.  
  428. //
  429. //  FUNCTION: CmdWindowCascade(HWND, WORD, WORD, HWND)
  430. //
  431. //  PURPOSE: To cascade the mdi child windows.
  432. //
  433. //  PARAMETERS:
  434. //    hwnd - The window handling the command.
  435. //    wCommand - IDM_WINDOWCASCADE (unused).
  436. //    hwndCtrl - NULL (unused).
  437. //
  438. //  RETURN VALUE:
  439. //    Always returns 0 - command handled.
  440. //
  441. //  COMMENTS:
  442. //
  443. //
  444.  
  445. #pragma argsused
  446. LRESULT CmdWindowCascade(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  447. {
  448.      SendMessage(hwndMDIClient, WM_MDICASCADE, 0, 0L);
  449.  
  450.      return 0;
  451. }
  452.  
  453. //
  454. //  FUNCTION: CmdWindowIcons(HWND, WORD, WORD, HWND)
  455. //
  456. //  PURPOSE: To arrage the mdi child icons.
  457. //
  458. //  PARAMETERS:
  459. //    hwnd - The window handling the command.
  460. //    wCommand - IDM_WINDOWICONS (unused).
  461. //    hwndCtrl - NULL (unused).
  462. //
  463. //  RETURN VALUE:
  464. //    Always returns 0 - command handled.
  465. //
  466. //  COMMENTS:
  467. //
  468. //
  469.  
  470. #pragma argsused
  471. LRESULT CmdWindowIcons(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  472. {
  473.      SendMessage(hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  474.  
  475.      return 0;
  476. }
  477.  
  478. //
  479. //  FUNCTION: CmdWindowCloseAll(HWND, WORD, WORD, HWND)
  480. //
  481. //  PURPOSE: To close all of the mdi child windows.
  482. //
  483. //  PARAMETERS:
  484. //    hwnd - The window handling the command.
  485. //    wCommand - IDM_WINDOWCLOSEALL (unused).
  486. //    hwndCtrl - NULL (unused).
  487. //
  488. //  RETURN VALUE:
  489. //    Always returns 0 - command handled.
  490. //
  491. //  COMMENTS:
  492. //
  493. //
  494.  
  495. #pragma argsused
  496. LRESULT CmdWindowCloseAll(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  497. {
  498.      HWND hwndT;
  499.  
  500.      // As long as the MDI client has a child, destroy it
  501.      #pragma warn -pia
  502.      while (hwndT = GetWindow(hwndMDIClient, GW_CHILD))
  503.      {
  504.  
  505.           // Skip the icon and title windows
  506.           while (hwndT && GetWindow(hwndT, GW_OWNER))
  507.                 hwndT = GetWindow(hwndT, GW_HWNDNEXT);
  508.  
  509.           if (hwndT)
  510.                 SendMessage(hwndMDIClient, WM_MDIDESTROY, (WPARAM)hwndT, 0L);
  511.           else
  512.                 break;
  513.      }
  514.      #pragma warn .pia
  515.  
  516.     return 0;
  517. }
  518.  
  519.