home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / WRITEPAD.PAK / MDICHILD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  19.7 KB  |  749 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:   mdichild.c
  9. //
  10. //  PURPOSE:
  11. //    To implement the basic mdi child commands.
  12. //
  13. //  FUNCTIONS:
  14. //    InitMDIChild     - To register the MDI child window class.
  15. //    MDIChildWndProc  - Processes messages for MDI child windows.
  16. //    MsgMCCommand     - Handle the WM_COMMAND messages for mdi children.
  17. //    MsgMCMenuSelect  - Handle the WM_MENUSELECT message for the mdi child
  18. //    MsgMCCreate      - Handle the WM_CREATE message for the MDI child
  19. //    MsgMCSize        - Handle the WM_SIZE message for the MDI child
  20. //    MsgMCSetFocus    - Handle the WM_SETFOCUS message for the MDI child
  21. //    MsgMCClose       - Handle the WM_CLOSE message for the MDI child
  22. //    MsgMCDestroy     - Handle the WM_DESTROY message for the MDI child
  23. //    CmdEdit          - Handle the notification messages for the edit control
  24. //                       contained within the MDI child
  25. //
  26. //  COMMENTS:
  27. //
  28. //
  29. //  SPECIAL INSTRUCTIONS: N/A
  30. //
  31.  
  32. #include <windows.h>            // required for all Windows applications
  33. #include <windowsx.h>
  34. #include <richedit.h>
  35. #include "globals.h"            // prototypes specific to this application
  36. #include "resource.h"
  37. #include "mdichild.h"
  38. #include "toolbar.h"
  39. #include "statbar.h"
  40. #include "ruler.h"
  41. #include "rtf.h"
  42.  
  43. LRESULT MsgMDNotify(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam);
  44.  
  45. static MSD rgmsd[] =
  46. {
  47.     {WM_SETFOCUS,    MsgMCSetFocus},
  48.     {WM_CREATE,      MsgMCCreate  },
  49.     {WM_COMMAND,     MsgMCCommand },
  50.     {WM_MENUSELECT,  MsgMenuSelect},
  51.     {WM_SIZE,        MsgMCSize    },
  52.     {WM_CLOSE,       MsgMCClose   },
  53.     {WM_DESTROY,     MsgMCDestroy },
  54.     {WM_NOTIFY,      MsgMDNotify  }
  55. };
  56.  
  57. MSDI msdiChild =
  58. {
  59.     sizeof(rgmsd) / sizeof(MSD),
  60.     rgmsd,
  61.     edwpMDIChild
  62. };
  63.  
  64. static CMD rgcmd[] =
  65. {
  66.     {IDC_EDIT,           CmdEdit},
  67. };
  68.  
  69. CMDI cmdiChild =
  70. {
  71.     sizeof(rgcmd) / sizeof(CMD),
  72.     rgcmd,
  73.     edwpMDIChild
  74. };
  75.  
  76. //Module specific globals
  77.  
  78. static char szChildName[12];
  79. static HANDLE hszEditBuffer = NULL;
  80.  
  81.  
  82. //
  83. //  FUNCTION: InitMDIChild(HINSTANCE)
  84. //
  85. //  PURPOSE: To register the MDI child window class.
  86. //
  87. //  PARAMETERS:
  88. //    hinst - The instance of the application used to register the class.
  89. //
  90. //  RETURN VALUE:
  91. //    TRUE - Succeeded in registering the class.
  92. //    FALSE - Failed to register the class.
  93. //
  94. //  COMMENTS:
  95. //
  96. //
  97.  
  98. BOOL InitMDIChild(HINSTANCE hinst)
  99. {
  100.     WNDCLASSEX wc;
  101.  
  102.     LoadString(hinst, IDS_CHILDNAME, szChildName, sizeof(szChildName));
  103.  
  104.     wc.cbSize        = sizeof(WNDCLASSEX);
  105.     wc.style         = 0;
  106.     wc.lpfnWndProc   = (WNDPROC)MDIChildWndProc;
  107.     wc.cbClsExtra    = 0;
  108.     wc.cbWndExtra    = 0;
  109.     wc.hInstance     = hinst;
  110.     wc.hIcon         = LoadIcon(hinst, MAKEINTRESOURCE(IDI_CHILDICON));
  111.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  112.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  113.     wc.lpszMenuName  = NULL;
  114.     wc.lpszClassName = szChildName;
  115.     wc.hIconSm       = LoadImage(hinst,        // Load small icon image
  116.                                  MAKEINTRESOURCE(IDI_CHILDICON),
  117.                                  IMAGE_ICON,
  118.                                  16, 16,
  119.                                  0);
  120.  
  121.     // Register the window class and return FALSE if unsuccesful.
  122.  
  123.     if (!RegisterClassEx(&wc))
  124.     {
  125.         //Assume we are running on NT where RegisterClassEx() is
  126.         //not implemented, so let's try calling RegisterClass().
  127.  
  128.         if (!RegisterClass((LPWNDCLASS)&wc.style))
  129.             return FALSE;
  130.     }
  131.  
  132.     return TRUE;
  133. }
  134.  
  135.  
  136. //
  137. //  FUNCTION: MDIChildWndProc(HWND, UINT, WPARAM, LPARAM)
  138. //
  139. //  PURPOSE:  Processes messages for MDI child windows.
  140. //
  141. //  PARAMETERS:
  142. //    hwnd     - window handle
  143. //    uMessage - message number
  144. //    wparam   - additional information (dependant of message number)
  145. //    lparam   - additional information (dependant of message number)
  146. //
  147. //  RETURN VALUE:
  148. //    Depends on the message number.
  149. //
  150. //  COMMENTS:
  151. //    Uses the combination of the message structure defined in mditable.c
  152. //    and the DispMessage function defined in WndProc.c to handle all
  153. //    messages directed to an MDI child window.
  154. //
  155.  
  156. LRESULT CALLBACK MDIChildWndProc(HWND hwnd,
  157.                                  UINT uMessage,
  158.                                  WPARAM wparam,
  159.                                  LPARAM lparam)
  160. {
  161.     return DispMessage( &msdiChild, hwnd, uMessage, wparam, lparam );
  162. }
  163.  
  164.  
  165. //
  166. //  FUNCTION: MsgMCCommand(HWND, UINT, WPARAM, LPARAM)
  167. //
  168. //  PURPOSE: Handle the WM_COMMAND messages for mdi children.
  169. //
  170. //  PARAMETERS:
  171. //    hwnd     - window handle
  172. //    uMessage - message number (Unused)
  173. //    GET_WM_COMMAND_ID(wparam,lparam)   - Command identifier
  174. //    GET_WM_COMMAND_HWND(wparam,lparam) - Control handle
  175. //
  176. //  RETURN VALUE:
  177. //
  178. //  COMMENTS:
  179. //    Uses the combination of the command structure defined in mditable.c
  180. //    and the DispCommand function defined in WndProc.c to handle all
  181. //    commands directed to an MDI child window.
  182. //
  183. //
  184.  
  185. #pragma argsused
  186. LRESULT MsgMCCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  187. {
  188.     return DispCommand(&cmdiChild, hwnd, wparam, lparam);
  189. }
  190.  
  191.  
  192. //
  193. //  FUNCTION: MsgMCCreate(HWND, UINT, WPARAM, LPARAM)
  194. //
  195. //  PURPOSE:
  196. //
  197. //  PARAMETERS:
  198. //    hwnd     - The window handing the message.
  199. //    uMessage - The message number. (unused).
  200. //    wparam   - Message specific data (unused).
  201. //    lparam   - Message specific data (unused).
  202. //
  203. //  RETURN VALUE:
  204. //
  205. //
  206. //  COMMENTS:
  207. //
  208. //
  209.  
  210. #pragma argsused
  211. LRESULT MsgMCCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  212. {
  213.  
  214.     if (!CreateEditControl(hwnd))
  215.         return -1;
  216.    
  217.     if (!CreateRuler(hwnd, ID_RULER, 1024, 32))
  218.         return -1;
  219.  
  220.      return 0;
  221. }
  222.  
  223.  
  224. //
  225. //  FUNCTION: MsgMCSize(HWND, UINT, WPARAM, LPARAM)
  226. //
  227. //  PURPOSE:  Resize the edit control window within the MDI Child
  228. //
  229. //  PARAMETERS:
  230. //    hwnd     - The window handing the message.
  231. //    uMessage - The message number. (unused).
  232. //    wparam   - Message specific data (unused).
  233. //    lparam   - Message specific data (unused).
  234. //
  235. //  RETURN VALUE:
  236. //    
  237. //
  238. //  COMMENTS:
  239. //    We must call DefMDIChildProc so that if the child is being maximized
  240. //    we'll get the system menu, min, max and close buttons painted properly.
  241. //
  242.  
  243. LRESULT MsgMCSize(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  244. {
  245.     SendMessage (GetEditWindow(hwnd), WM_SETREDRAW, FALSE, 0L);
  246.     MoveWindow(GetEditWindow(hwnd), 
  247.                0, 32, 
  248.                LOWORD(lparam), HIWORD(lparam)-32, 
  249.                TRUE);
  250.     SendMessage (GetEditWindow(hwnd), WM_SETREDRAW, TRUE, 0L);
  251.     InvalidateRect(GetEditWindow(hwnd), NULL, FALSE);
  252.  
  253.     return DefMDIChildProc(hwnd, uMessage, wparam, lparam);
  254. }
  255.  
  256.  
  257. //
  258. //  FUNCTION: MsgMCMenuSelect(HWND, UINT, WPARAM, LPARAM)
  259. //
  260. //  PURPOSE:  
  261. //
  262. //  PARAMETERS:
  263. //    hwnd     - The window handing the message.
  264. //    uMessage - The message number. (unused).
  265. //    wparam   - Message specific data (unused).
  266. //    lparam   - Message specific data (unused).
  267. //
  268. //  RETURN VALUE:
  269. //    
  270. //
  271. //  COMMENTS:
  272. //
  273.  
  274. LRESULT MsgMCMenuSelect(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  275. {
  276.     return DefMDIChildProc(hwnd, uMessage, wparam, lparam);
  277. }
  278.  
  279.  
  280. //
  281. //  FUNCTION: MsgMCSetFocus(HWND, UINT, WPARAM, LPARAM)
  282. //
  283. //  PURPOSE:
  284. //    Sets the focus to the edit control window contained within this MDI
  285. //    child window.
  286. //
  287. //  PARAMETERS:
  288. //    hwnd     - The window handing the message.
  289. //    uMessage - The message number. (unused).
  290. //    wparam   - Message specific data (unused).
  291. //    lparam   - Message specific data (unused).
  292. //
  293. //  RETURN VALUE:
  294. //
  295. //
  296. //  COMMENTS:
  297. //
  298.  
  299. #pragma argsused
  300. LRESULT MsgMCSetFocus(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  301. {
  302.     SetFocus(GetEditWindow(NULL));
  303.  
  304.     // Update the ruler to reflect the margins
  305.     RTF_ShowMargins(GetDlgItem(hwnd, ID_RULER));
  306.  
  307.     // Update the toolbar to show the current text attributes
  308.     RTF_ShowCharAttributes();
  309.  
  310.     return 0;
  311. }
  312.  
  313.  
  314. //
  315. //  FUNCTION: MsgMCClose(HWND, UINT, WPARAM, LPARAM)
  316. //
  317. //  PURPOSE:  Query user to save file before closing window
  318. //
  319. //  PARAMETERS:
  320. //    hwnd - The window handing the message.
  321. //    uMessage - The message number. (unused).
  322. //    wparam - Message specific data (unused).
  323. //    lparam - Message specific data (unused).
  324. //
  325. //  RETURN VALUE:
  326. //    Return 0 if user hits "Cancel" from the query save dialog.  This
  327. //    prevents the MDI child from closing.
  328. //
  329. //  COMMENTS:
  330. //    Call DefMDIChildProc so that the window gets destroyed.
  331. //
  332.  
  333. LRESULT MsgMCClose(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  334. {
  335.     if (QuerySaveFile(hwnd))
  336.         return DefMDIChildProc(hwnd, uMessage, wparam, lparam);
  337.     else
  338.         return 0;
  339. }
  340.  
  341.  
  342. //
  343. //  FUNCTION: MsgMCDestroy(HWND, UINT, WPARAM, LPARAM)
  344. //
  345. //  PURPOSE:
  346. //
  347. //  PARAMETERS:
  348. //    hwnd - The window handing the message.
  349. //    uMessage - The message number. (unused).
  350. //    wparam - Message specific data (unused).
  351. //    lparam - Message specific data (unused).
  352. //
  353. //  RETURN VALUE:
  354. //    Always returns 0 - message handled.
  355. //
  356. //  COMMENTS:
  357. //
  358. //
  359.  
  360. #pragma argsused
  361. LRESULT MsgMCDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  362. {
  363.     HDC hdc;
  364.  
  365.     cOpen -= 1;
  366.     RemoveProp(hwnd, "FilenameSet");
  367.  
  368.     hdc = RemoveProp(hwnd, "TargetDC");
  369.     if (hdc)
  370.           DeleteDC(hdc);
  371.  
  372.     return 0;
  373. }
  374.  
  375. //
  376. //  FUNCTION: MsgMDNotify(HWND, UINT, WPARAM, LPARAM)
  377. //
  378. //  PURPOSE: Handles the WM_NOTIFY message
  379. //
  380. //  PARAMETERS:
  381. //    hwnd - The window handing the message.
  382. //    uMessage - WM_NOTIFY
  383. //    wparam - ID of control sending notification
  384. //    lparam - LPNOTIFY pointer to the NOTIFY structure
  385. //
  386. //  RETURN VALUE:
  387. //    Always returns 0 - message handled.
  388. //
  389. //  COMMENTS:
  390. //
  391. //
  392.  
  393. #pragma argsused
  394. LRESULT MsgMDNotify(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  395. {
  396.      switch ( ((LPNMHDR)lparam)->code )
  397.      {
  398.           // User changed the ruler's "knobbies" or tabs- See RULER.H
  399.         case RN_CHANGEDSETTINGS: 
  400.  
  401.             RTF_ChangeMargins(GetDlgItem(hwnd, ID_RULER),  // HwndRuler
  402.                               ((LPNMRULER)lparam)->iFirstLineIndent,
  403.                               ((LPNMRULER)lparam)->iRight,
  404.                               ((LPNMRULER)lparam)->iLeft - 
  405.                                 ((LPNMRULER)lparam)->iFirstLineIndent);
  406.             break;
  407.  
  408.         // User changed text in RichEdit control- See COMMCTRL.H
  409.         case EN_SELCHANGE:
  410.  
  411.             RTF_ShowMargins(GetDlgItem(hwnd, ID_RULER));
  412.             RTF_ShowCharAttributes();
  413.                 break;
  414.  
  415.     }
  416.     return 0;
  417. }
  418.  
  419. //
  420. //  FUNCTION: CmdEdit(HWND, WORD, WORD, HWND)
  421. //
  422. //  PURPOSE: Hand edit control notifications.
  423. //
  424. //  PARAMETERS:
  425. //    hwnd     - The window.
  426. //    wCommand - IDC_EXIT (unused)
  427. //    wNotify  - EN_*
  428. //    hwndCtrl - NULL (unused)
  429. //
  430. //  RETURN VALUE:
  431. //    Always returns 0 - command handled.
  432. //
  433. //  COMMENTS:
  434. //    Handle the edit control's out of space error by putting up an
  435. //    "Out of Memory" warning dialog.
  436. //
  437.  
  438. #pragma argsused
  439. LRESULT CmdEdit(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  440. {
  441.      switch (wNotify)
  442.      {
  443.           case EN_ERRSPACE:
  444.                 MessageBox(hwnd,
  445.                               "Out of memory.",
  446.                               szTitle,
  447.                        MB_ICONHAND | MB_OK);
  448.             break;
  449.     }
  450.     return 0;
  451. }
  452.  
  453. //
  454. //  FUNCTION: CreateMDIChild(LPSTR)
  455. //
  456. //  PURPOSE: Create an MDI child window, setting caption to szFileName
  457. //
  458. //  PARAMETERS:
  459. //    hwnd - The main application window.
  460. //
  461. //  RETURN VALUE:
  462. //    TRUE  - If creation was successful.
  463. //    FALSE - If creation failed.
  464. //
  465. //  COMMENTS:
  466. //
  467.  
  468. BOOL CreateMDIChild(LPSTR szFileName)
  469. {
  470.     HWND  hwndChild;
  471.     DWORD dwVersion;
  472.  
  473.     // Create the MDI child window
  474.  
  475.     // Windows NT and Windows 95 present different options for creating
  476.     // an MDI child window.  While using the WM_MDICREATE message will
  477.     // work on both Windows versions, Windows 95 presents a new window
  478.     // style which simplifies the process.  Here the function uses the
  479.     // method apropriate for the system it's running on to illustrate
  480.     // both methods.
  481.  
  482.     dwVersion = GetVersion();
  483.     if ((dwVersion < 0x80000000) || (LOBYTE(LOWORD(dwVersion)) < 4))
  484.     {
  485.         // This is Windows NT or Win32s, so use the WM_MDICREATE message
  486.         MDICREATESTRUCT mcs;
  487.  
  488.         mcs.szClass = szChildName;      // window class name
  489.         mcs.szTitle = szFileName;       // window title
  490.         mcs.hOwner  = hInst;            // owner
  491.         mcs.x       = CW_USEDEFAULT;    // x position
  492.         mcs.y       = CW_USEDEFAULT;    // y position
  493.         mcs.cx      = CW_USEDEFAULT;    // width
  494.         mcs.cy      = CW_USEDEFAULT;    // height
  495.         mcs.style   = 0;                // window style
  496.         mcs.lParam  = 0;                // lparam
  497.  
  498.         hwndChild = (HWND) SendMessage(hwndMDIClient,
  499.                                        WM_MDICREATE,
  500.                                        0,
  501.                                        (LPARAM)(LPMDICREATESTRUCT) &mcs);
  502.     }
  503.     else
  504.     {
  505.         // This method will only work with Windows 95, not Windows NT or Win32s
  506.         hwndChild = CreateWindowEx(WS_EX_MDICHILD,  // EX window style
  507.                                    szChildName,     // window class name
  508.                                    szFileName,      // window title
  509.                                    0,               // window style
  510.                                    CW_USEDEFAULT,   // x position
  511.                                    CW_USEDEFAULT,   // y position
  512.                                    CW_USEDEFAULT,   // width
  513.                                    CW_USEDEFAULT,   // height
  514.                                    hwndMDIClient,   // parent
  515.                                    NULL,            // menu (child ID)
  516.                                    hInst,           // owner
  517.                                    0);              // lparam
  518.     }
  519.  
  520.     if (hwndChild != NULL)
  521.     {
  522.         ShowWindow(hwndChild, SW_SHOW);
  523.         SetProp(hwndChild, "FilenameSet", 0);
  524.         SetFocus(hwndChild);
  525.  
  526.         cUntitled++;
  527.         cOpen++;
  528.         return TRUE;
  529.     }
  530.     else
  531.         return FALSE;
  532. }
  533.  
  534.  
  535. //
  536. //  FUNCTION: CreateEditControl(HWND)
  537. //
  538. //  PURPOSE: Create the RichEdit control with the MDI child as the parent
  539. //
  540. //  PARAMETERS:
  541. //    hwnd - The MDI child window.
  542. //
  543. //  RETURN VALUE:
  544. //    TRUE - If initialization was successful.
  545. //    FALSE - If initialization failed.
  546. //
  547. //  COMMENTS:
  548. //
  549.  
  550. BOOL CreateEditControl(HWND hwndMDIChild)
  551. {
  552.     RECT rc;
  553.     HWND hwndEdit;
  554.     HDC  hDC;
  555.     CHARFORMAT cf;
  556.  
  557.     GetClientRect(hwndMDIChild, &rc);
  558.  
  559.     hwndEdit = CreateWindow("RichEdit",
  560.                             NULL,
  561.                             WS_CHILD   | WS_VISIBLE | ES_MULTILINE   |
  562.                             WS_VSCROLL |
  563.                             ES_AUTOVSCROLL | ES_NOHIDESEL,
  564.                             0, 0,
  565.                             (rc.right-rc.left), (rc.bottom-rc.top),
  566.                             hwndMDIChild,
  567.                             (HMENU)IDC_EDIT,           // Child control i.d.
  568.                             hInst,
  569.                             NULL);
  570.  
  571.     if (!hwndEdit)
  572.     {
  573.         DestroyWindow(hwndMDIChild);
  574.         return FALSE;
  575.     }
  576.  
  577.     // Set the RichEdit control to send the EN_SELCHANGE notification
  578.     // via the WM_NOTIFY message.
  579.     SendMessage(hwndEdit, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
  580.  
  581. // REVIEW
  582.     // Set up the RichEdit control to act as WSYWIG as possible,
  583.     // here we force a 7" wide page size.
  584.     hDC = CreateCompatibleDC(NULL);
  585. //    hDC = GetCurrentPrinterDC();
  586.     if (SendMessage(hwndEdit, EM_SETTARGETDEVICE, (WPARAM)hDC, (LPARAM)(1440*7)))
  587.         SetProp(hwndMDIChild, "TargetDC", hDC);
  588.     else
  589.         DeleteDC(hDC);
  590.  
  591.     // Set default character format...  The point here is to avoid having
  592.     // the system font as default since it generally doesn't scale well.
  593.  
  594.     // Set up CHARFORMAT for default 10 point Times New Roman with no
  595.     // extra effects (bold, italic, etc.)
  596.     cf.cbSize = sizeof(cf);
  597.     cf.dwMask = CFM_FACE | CFM_SIZE | CFM_BOLD | CFM_ITALIC | CFM_STRIKEOUT
  598.                 | CFM_UNDERLINE | CFM_COLOR | CFM_OFFSET | CFM_PROTECTED;
  599.     cf.dwEffects = CFE_AUTOCOLOR;   // use COLOR_WINDOWTEXT
  600.     cf.yHeight = 200; // 200 twips == 10 points
  601.     cf.yOffset = 0;
  602.     cf.crTextColor = 0;
  603.     cf.bPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
  604.     lstrcpy(cf.szFaceName, TEXT("Arial"));
  605.  
  606.     // Set the default character format.
  607.     SendMessage(hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  608.  
  609.     return TRUE;
  610. }
  611.  
  612.  
  613. //
  614. //  FUNCTION: GetEditWindow(HWND)
  615. //
  616. //  PURPOSE: Return a handle to the current edit control.  The "current"
  617. //           edit control is contained within the active MDI child
  618. //
  619. //  PARAMETERS:
  620. //    hwdnMDIChild - handle to the MDI Child window
  621. //
  622. //  RETURN VALUE:
  623. //    A handle to the current edit control.
  624. //
  625. //  COMMENTS:
  626. //    If hwndMDIChild is NULL on entry, we'll return the handle to the
  627. //    edit control in the active MDI child
  628. //
  629.  
  630. HWND GetEditWindow(HWND hwndMDIChild)
  631. {
  632.     HWND hwndEdit;
  633.     
  634.     if (!hwndMDIChild)
  635.         hwndMDIChild = GetActiveMDIChild();
  636.  
  637.     hwndEdit = GetDlgItem(hwndMDIChild, IDC_EDIT);
  638.  
  639.     return hwndEdit;
  640. }
  641.  
  642.  
  643. //
  644. //  FUNCTION: GetActiveMDIChild(void)
  645. //
  646. //  PURPOSE: Return a handle to the current active MDI child
  647. //
  648. //  PARAMETERS:
  649. //    void
  650. //
  651. //  RETURN VALUE:
  652. //    A handle to the current active MDI child
  653. //
  654. //  COMMENTS:
  655. //    
  656.  
  657. HWND GetActiveMDIChild(void)
  658. {
  659.     HWND hwndMDIChild;
  660.     
  661.     hwndMDIChild = (HWND)SendMessage(hwndMDIClient, 
  662.                                      WM_MDIGETACTIVE, 
  663.                                      0, 0L);
  664.     return hwndMDIChild;
  665. }
  666.  
  667.  
  668. //
  669. //  FUNCTION: SetEditText(HWND, hsz)
  670. //
  671. //  PURPOSE: Set the text of the edit control hwnd.
  672. //
  673. //  PARAMETERS:
  674. //    hwnd - The edit control to set.
  675. //    hsz  - A local handle to the text to set.
  676. //
  677. //  RETURN VALUE:
  678. //    NONE
  679. //
  680. //  COMMENTS:
  681. //    
  682. //
  683.  
  684. #pragma argsused
  685. VOID SetEditText(HWND hwnd, HANDLE hsz)
  686. {
  687.     char *sz = LocalLock(hsz);
  688.     SendMessage(GetEditWindow(NULL), WM_SETTEXT, 0, (LPARAM)(LPSTR)sz);
  689.     LocalUnlock(hsz);
  690.     LocalFree(hsz);
  691. }
  692.  
  693.  
  694. //
  695. //  FUNCTION: LockEditText(HWND)
  696. //
  697. //  PURPOSE: Return a handle to the text associated with the edit control.
  698. //
  699. //  PARAMETERS:
  700. //    hwnd - The edit control whose text is to be locked.
  701. //
  702. //  RETURN VALUE:
  703. //    A local buffer containing the text associated with the editor control.
  704. //
  705. //  COMMENTS:
  706. //
  707. //
  708.  
  709. char *LockEditText(HWND hwnd)
  710. {
  711.     INT cbText;
  712.      char *sz;
  713.  
  714.      cbText = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L) + 1;
  715.      hszEditBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, cbText);
  716.      if (hszEditBuffer == NULL) return NULL;
  717.      sz = LocalLock(hszEditBuffer);
  718.      if (sz == NULL)
  719.      {
  720.         LocalFree(hszEditBuffer);
  721.         hszEditBuffer = NULL;
  722.         return NULL;
  723.     }
  724.     SendMessage(hwnd, WM_GETTEXT, cbText, (LPARAM)(LPSTR)sz);
  725.     return sz;
  726. }
  727.  
  728.  
  729. //
  730. //  FUNCTION: UnlockEditText(HWND)
  731. //
  732. //  PURPOSE: Return a handle to the text associated with the edit control.
  733. //
  734. //  PARAMETERS:
  735. //    hwnd - The edit control whose text is to be unlocked.
  736. //
  737. //  RETURN VALUE:
  738. //    NONE
  739. //
  740. //  COMMENTS:
  741. //
  742. //
  743.  
  744. VOID UnlockEditText(HWND hwnd)
  745. {
  746.     SetEditText(hwnd, hszEditBuffer);
  747.     hszEditBuffer = NULL;
  748. }
  749.