home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / memory / memory.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  40KB  |  1,302 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples.
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved.
  6. *       This source code is only intended as a supplement to
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /****************************** Module Header ******************************\
  13. * Module Name: memory.c
  14. \***************************************************************************/
  15.  
  16.  
  17. #include <windows.h>
  18. #include "memory.h"
  19.  
  20.  
  21. HANDLE ghModule;
  22. HWND   ghwndMain = NULL;
  23. HWND   ghwndClient;
  24.  
  25. HMENU  hMenu,       hMenuWindow;
  26. HMENU  hServerMenu, hServerMenuWindow;
  27. HMENU  hClientMenu, hClientMenuWindow;
  28.  
  29. CHAR   gszFile[20];
  30. CHAR   gszMapName[20];
  31.  
  32.  
  33. typedef struct _PerWndInfo
  34. {
  35.     HWND    hParent;
  36.     HWND    hThisWnd;           // Used in locating the node
  37.     RECT    rcClient;
  38.     char    CaptionBarText[SIZEOFCAPTIONTEXT];
  39. } PERWNDINFO, *PPERWNDINFO;
  40.  
  41.  
  42. typedef struct _node
  43. {
  44.    PERWNDINFO      ChildWnd;
  45.    HANDLE          hNext;
  46. } NODE, *PNODE;
  47.  
  48.  
  49. /*
  50.  * Forward declarations.
  51.  */
  52. BOOL InitializeApp   (void);
  53. LONG APIENTRY MainWndProc     (HWND, UINT, DWORD, LONG);
  54. LONG APIENTRY ServerWndProc   (HWND, UINT, DWORD, LONG);
  55. LONG APIENTRY ClientWndProc   (HWND, UINT, DWORD, LONG);
  56. BOOL CALLBACK About          (HWND, UINT, DWORD, LONG);
  57. BOOL CALLBACK FileType       (HWND, UINT, DWORD, LONG);
  58. BOOL CALLBACK MapFileName     (HWND, UINT, DWORD, LONG);
  59. LONG APIENTRY TextWndProc     (HWND, UINT, DWORD, LONG);
  60.  
  61. /***************************************************************************\
  62. * main
  63. *
  64. \***************************************************************************/
  65.  
  66. int WINAPI WinMain(
  67.     HANDLE hInstance,
  68.     HANDLE hPrevInstance,
  69.     LPSTR lpCmdLine,
  70.     int nShowCmd)
  71. {
  72.     MSG msg;
  73.  
  74.     // this will change to something more reasonable
  75.  
  76.     ghModule = GetModuleHandle(NULL);
  77.     if (!InitializeApp())
  78.     {
  79.         MessageBox(ghwndMain,
  80.                    GetStringRes(IDS_ERR_INITAPP_FAILED),
  81.                    NULL, MB_OK);
  82.  
  83.         return 0;
  84.     }
  85.  
  86.     while (GetMessage(&msg, NULL, 0, 0))
  87.     {
  88.         TranslateMessage(&msg);
  89.         DispatchMessage(&msg);
  90.     }
  91.  
  92.     if (hMenuWindow && IsWindow(hMenuWindow))
  93.         DestroyMenu(hMenuWindow);
  94.     if (hClientMenuWindow && IsWindow(hClientMenuWindow))
  95.         DestroyMenu(hClientMenuWindow);
  96.     if (hServerMenuWindow && IsWindow(hServerMenuWindow))
  97.         DestroyMenu(hServerMenuWindow);
  98.     if (hMenu && IsWindow(hMenu))
  99.         DestroyMenu(hMenu);
  100.     if (hClientMenu && IsWindow(hClientMenu))
  101.         DestroyMenu(hClientMenu);
  102.     if (hServerMenu && IsWindow(hServerMenu))
  103.         DestroyMenu(hServerMenu);
  104.  
  105.     return 1;
  106.  
  107.     UNREFERENCED_PARAMETER(lpCmdLine);
  108.     UNREFERENCED_PARAMETER(nShowCmd);
  109.     UNREFERENCED_PARAMETER(hInstance);
  110.     UNREFERENCED_PARAMETER(hPrevInstance);
  111. }
  112.  
  113.  
  114. /***************************************************************************\
  115. * InitializeApp
  116. *
  117. \***************************************************************************/
  118.  
  119. BOOL InitializeApp(void)
  120. {
  121.     WNDCLASS wc;
  122.  
  123.     wc.style            = CS_OWNDC;
  124.     wc.lpfnWndProc      = (WNDPROC)MainWndProc;
  125.     wc.cbClsExtra       = 0;
  126.     wc.cbWndExtra       = sizeof(LONG);
  127.     wc.hInstance        = ghModule;
  128.     wc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  129.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  130.     wc.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE);
  131.     wc.lpszMenuName     = "MainMenu";
  132.     wc.lpszClassName    = "MemoryClass";
  133.  
  134.     if (!RegisterClass(&wc))
  135.         return FALSE;
  136.  
  137.     wc.style            = CS_OWNDC;
  138.     wc.lpfnWndProc      = (WNDPROC)ServerWndProc;
  139.     wc.cbClsExtra       = 0;
  140.     wc.cbWndExtra       = 0;                      // LATER sizeof(LONG);
  141.     wc.hInstance        = ghModule;
  142.     wc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  143.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  144.     wc.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE);
  145.     wc.lpszMenuName     = NULL;
  146.     wc.lpszClassName    = "ServerClass";
  147.  
  148.     if (!RegisterClass(&wc))
  149.         return FALSE;
  150.  
  151.     wc.style            = CS_OWNDC;
  152.     wc.lpfnWndProc      = (WNDPROC)ClientWndProc;
  153.     wc.cbClsExtra       = 0;
  154.     wc.cbWndExtra       = 0;                      // LATER sizeof(LONG);
  155.     wc.hInstance        = ghModule;
  156.     wc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  157.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  158.     wc.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE);
  159.     wc.lpszMenuName     = NULL;
  160.     wc.lpszClassName    = "ClientClass";
  161.  
  162.     if (!RegisterClass(&wc))
  163.         return FALSE;
  164.  
  165.     wc.style            = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  166.     wc.lpfnWndProc      = (WNDPROC)TextWndProc;
  167.     wc.cbClsExtra       = 0;
  168.     wc.cbWndExtra       = 0;
  169.     wc.hInstance        = ghModule;
  170.     wc.hIcon            = NULL;
  171.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  172.     wc.hbrBackground    = (HBRUSH)(COLOR_BTNSHADOW);
  173.     wc.lpszMenuName     = NULL;
  174.     wc.lpszClassName    = "Text";
  175.  
  176.     if (!RegisterClass(&wc))
  177.             return FALSE;
  178.  
  179.  
  180.  
  181.     hMenu       = LoadMenu(ghModule, "MainMenu");
  182.     hServerMenu = LoadMenu(ghModule, "ServerMenu");
  183.     hClientMenu = LoadMenu(ghModule, "ClientMenu");
  184.     hMenuWindow       = GetSubMenu(hMenu, 1);
  185.     hServerMenuWindow = GetSubMenu(hServerMenu, 2);
  186.     hClientMenuWindow = GetSubMenu(hClientMenu, 2);
  187.  
  188.     ghwndMain = CreateWindowEx(0L, "MemoryClass", "Memory",
  189.             WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
  190.             WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
  191.             WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
  192.             80, 70, 592, 300,
  193.             NULL, hMenu, ghModule, NULL);
  194.  
  195.     if (ghwndMain == NULL)
  196.         return FALSE;
  197.  
  198.     SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
  199.  
  200.     return TRUE;
  201. }
  202.  
  203.  
  204. /***************************************************************************\
  205. * MainWndProc
  206. *
  207. \***************************************************************************/
  208.  
  209. long APIENTRY MainWndProc(
  210.                           HWND hwnd,
  211.                           UINT message,
  212.                           DWORD wParam,
  213.                           LONG lParam)
  214. {
  215.     static int         iSvrCount=1;
  216.     static int         iCltCount=1;
  217.     CLIENTCREATESTRUCT clientcreate;
  218.     HWND               hwndChildWindow;
  219.     BOOL               fSuccess;
  220.  
  221.  
  222.     switch (message)
  223.     {
  224.  
  225.       case WM_CREATE:
  226.         SetWindowLong(hwnd, 0, (LONG)NULL);
  227.  
  228.         clientcreate.hWindowMenu  = hMenuWindow;
  229.         clientcreate.idFirstChild = 1;
  230.  
  231.         ghwndClient = CreateWindow("MDICLIENT", NULL,
  232.                                     WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
  233.                                     0,0,0,0,
  234.                                     hwnd, NULL, ghModule, (LPVOID)&clientcreate);
  235.         return 0L;
  236.  
  237.       case WM_DESTROY: {
  238.         PostQuitMessage(0);
  239.         return 0L;
  240.       }
  241.  
  242.       case WM_COMMAND:
  243.  
  244.         switch (LOWORD(wParam))
  245.         {
  246.             case IDM_TILE:
  247.                 SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
  248.                 return 0L;
  249.             case IDM_CASCADE:
  250.                 SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
  251.                 return 0L;
  252.             case IDM_ARRANGE:
  253.                 SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
  254.                 return 0L;
  255.  
  256.             case MM_SERVER: {
  257.                 BOOL fSucess = FALSE;
  258.                 HANDLE hNode, hHead;
  259.                 PNODE  pNode;
  260.                 MDICREATESTRUCT mdicreate;
  261.  
  262.                 hNode = LocalAlloc(LHND, (WORD) sizeof(NODE));
  263.                 if (hNode && (pNode = (PNODE)LocalLock(hNode)))
  264.                 {
  265.                     wsprintf((LPSTR) &(pNode->ChildWnd.CaptionBarText),
  266.                              GetStringRes(IDS_SERVER), iSvrCount);
  267.  
  268.                     mdicreate.szClass = "ServerClass";
  269.                     mdicreate.szTitle = (LPTSTR)&(pNode->ChildWnd.CaptionBarText);
  270.                     mdicreate.hOwner  = ghModule;
  271.                     mdicreate.x       =
  272.                     mdicreate.y       =
  273.                     mdicreate.cx      =
  274.                     mdicreate.cy      = CW_USEDEFAULT;
  275.                     mdicreate.style   = 0l;
  276.                     mdicreate.lParam  = 0L;
  277.  
  278.                     /*Create Child Window*/
  279.                     hwndChildWindow =
  280.                        (HWND) SendMessage(ghwndClient, WM_MDICREATE,
  281.                                           0L,
  282.                                           (LONG)(LPMDICREATESTRUCT)&mdicreate);
  283.  
  284.                     if (hwndChildWindow)
  285.                     {
  286.                        pNode->ChildWnd.hParent      = ghwndClient;
  287.                        pNode->ChildWnd.hThisWnd     = hwndChildWindow;
  288.                        hHead = (HANDLE)GetWindowLong(hwnd, 0);
  289.                        pNode->hNext = hHead;
  290.                        SetWindowLong(hwnd, 0, (LONG) hNode);
  291.  
  292.                        iSvrCount++;
  293.                        LocalUnlock(hNode);
  294.  
  295.                        fSuccess = TRUE;
  296.                     }
  297.                     else
  298.                     {
  299.                        LocalUnlock (hNode);
  300.                        LocalFree (hNode);
  301.  
  302.                        fSuccess = FALSE;
  303.                     }
  304.                 }
  305.                 if (!fSuccess)
  306.                     MessageBox(ghwndMain,
  307.                                GetStringRes(IDS_ERR_CREATE_CHILD_FAILED),
  308.                                NULL, MB_OK);
  309.  
  310.                  return 0L;
  311.             }
  312.  
  313.             case MM_CLIENT:
  314.             {
  315.                 BOOL fResult = FALSE;
  316.                 HANDLE hNode, hHead;
  317.                 PNODE  pNode;
  318.                 MDICREATESTRUCT mdicreate;
  319.  
  320.                 hNode = LocalAlloc(LHND, (WORD) sizeof(NODE));
  321.                 if (hNode && (pNode = (PNODE)LocalLock(hNode)))
  322.                 {
  323.                     wsprintf((LPSTR) &(pNode->ChildWnd.CaptionBarText),
  324.                              GetStringRes(IDS_CLIENT), iCltCount);
  325.  
  326.                     mdicreate.szClass = "ClientClass";
  327.                     mdicreate.szTitle = (LPSTR) &(pNode->ChildWnd.CaptionBarText);
  328.                     mdicreate.hOwner  = ghModule;
  329.                     mdicreate.x       =
  330.                     mdicreate.y       =
  331.                     mdicreate.cx      =
  332.                     mdicreate.cy      = CW_USEDEFAULT;
  333.                     mdicreate.style   = 0l;
  334.                     mdicreate.lParam  = 0L;
  335.  
  336.                     /*Create Child Window*/
  337.                     hwndChildWindow =
  338.                         (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
  339.                                              0L,
  340.                                              (LONG)(LPMDICREATESTRUCT)&mdicreate);
  341.  
  342.                     if (hwndChildWindow)
  343.                     {
  344.                        pNode->ChildWnd.hParent      = ghwndClient;
  345.                        pNode->ChildWnd.hThisWnd     = hwndChildWindow;
  346.                        hHead = (HANDLE)GetWindowLong(hwnd, 0);
  347.                        pNode->hNext = hHead;
  348.                        SetWindowLong(hwnd, 0, (LONG) hNode);
  349.  
  350.                        iCltCount++;
  351.                        LocalUnlock(hNode);
  352.  
  353.                        fSuccess = TRUE;
  354.                     }
  355.                     else
  356.                     {
  357.                        LocalUnlock (hNode);
  358.                        LocalFree (hNode);
  359.  
  360.                        fSuccess = FALSE;
  361.                     }
  362.                 }
  363.                 if (!fSuccess)
  364.                    MessageBox(ghwndMain,
  365.                               GetStringRes(IDS_ERR_CREATE_CHILD_FAILED),
  366.                               NULL, MB_OK);
  367.  
  368.                 return 0L;
  369.             }
  370.  
  371.             case MM_ABOUT:
  372.                 if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
  373.                    MessageBox(ghwndMain,
  374.                               GetStringRes(IDS_ERR_CREATE_DLG_FAILED), NULL, MB_OK);
  375.                 return 0L;
  376.  
  377.             case MM_OPT_1:
  378.             case MM_OPT_2:
  379.             case MM_OPT_3:
  380.             case MM_OPT_4:
  381.             case MM_OPT_5:
  382.             case MM_OPT_6:
  383.             case MM_OPT_7:
  384.             case MM_OPT_8:
  385.             {
  386.                 HWND hActiveChild;
  387.  
  388.                 hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
  389.                 if (hActiveChild)
  390.                     SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
  391.                 return 0L;
  392.             }
  393.  
  394.             default:
  395.                 return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
  396.         }
  397.  
  398.     default:
  399.  
  400.         return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
  401.     }
  402. }
  403.  
  404.  
  405. /***************************************************************************\
  406. * ServerWndProc
  407. *
  408. \***************************************************************************/
  409.  
  410. long APIENTRY ServerWndProc( HWND hwnd,
  411.                              UINT message,
  412.                              DWORD wParam,
  413.                              LONG lParam)
  414. {
  415.    static HANDLE MapFileHandle = NULL;
  416.    static HANDLE hMem1         = NULL;
  417.    static LPVOID pShrMem1      = NULL;
  418.    static HANDLE hEdit;
  419.    static BOOL   bDirty        = FALSE;
  420.    static HWND   hTextWnd;
  421.    BOOL          fSuccess;
  422.  
  423.    switch (message)
  424.    {
  425.       case WM_COMMAND:
  426.       {
  427.  
  428.          switch (LOWORD(wParam))
  429.          {
  430.             case MM_OPT_1:
  431.             { //Create File
  432.  
  433.                SetWindowText(hTextWnd, GetStringRes(IDS_CREATE_MAP_FILE));
  434.  
  435.                switch (DialogBox(ghModule, "FileType", hwnd, (DLGPROC)FileType))
  436.                {
  437.                   case -1:
  438.                      fSuccess = FALSE;
  439.                      break;
  440.  
  441.                   case IDBTN_MAP:
  442.                      if (MapFileHandle = CreateMapFile(gszFile))
  443.                         fSuccess = TRUE;
  444.                      else
  445.                         fSuccess = FALSE;
  446.  
  447.                      break;
  448.  
  449.                   default:
  450.                      MapFileHandle = (HANDLE) 0xFFFFFFFF;
  451.                      fSuccess = TRUE;
  452.                      break;
  453.                }
  454.  
  455.                if (fSuccess)
  456.                {
  457.                   EnableMenuItem(hServerMenu, MM_OPT_1, MF_GRAYED);
  458.                   EnableMenuItem(hServerMenu, MM_OPT_2, MF_ENABLED);
  459.  
  460.                   SetWindowText(hTextWnd,
  461.                                 GetStringRes(IDS_SEL_CREATE_FILE_MAPPING));
  462.                }
  463.                else
  464.                {
  465.                   SetWindowText(hTextWnd,
  466.                                 GetStringRes (IDS_ERR_MAPFILE_FAILED));
  467.  
  468.                }
  469.                return 0L;
  470.             }
  471.  
  472.             case MM_OPT_2:
  473.             { //Create File Mapping
  474.  
  475.                // This option should be disabled until MM_OPT_1 has been chosen.
  476.  
  477.                SetWindowText(hTextWnd,
  478.                              GetStringRes(IDS_CREATE_MAPPING));
  479.  
  480.  
  481.                if (MapFileHandle)
  482.                   switch (DialogBox(ghModule, "MapName", hwnd, (DLGPROC)MapFileName))
  483.                   {
  484.                      case IDBTN_OK:
  485.                         if (hMem1 = CreateMap(MapFileHandle, gszMapName))
  486.                            fSuccess = TRUE;
  487.                         else
  488.                            fSuccess = FALSE;
  489.                         break;
  490.  
  491.                      default:
  492.                         fSuccess = FALSE;
  493.                         break;
  494.                   }
  495.                else
  496.                   fSuccess = FALSE;
  497.  
  498.  
  499.                if (fSuccess)
  500.                {
  501.                   EnableMenuItem(hServerMenu, MM_OPT_2, MF_GRAYED);
  502.                   EnableMenuItem(hServerMenu, MM_OPT_3, MF_ENABLED);
  503.  
  504.                   SetWindowText(hTextWnd,
  505.                                 GetStringRes (IDS_SEL_MAP_VIEW));
  506.                }
  507.                else
  508.                {
  509.                   SetWindowText(hTextWnd,
  510.                                 GetStringRes (IDS_ERR_MAPPING_FAILED));
  511.  
  512.                }
  513.                return 0L;
  514.             }
  515.  
  516.             case MM_OPT_3:
  517.             { //Map View of File
  518.  
  519.                SetWindowText(hTextWnd, GetStringRes (IDS_MAPPING_VIEW));
  520.  
  521.  
  522.                if (hMem1 && (pShrMem1 = (LPVOID)MapView(hMem1)))
  523.                {
  524.                   EnableMenuItem(hServerMenu, MM_OPT_3, MF_GRAYED);
  525.                   EnableMenuItem(hServerMenu, MM_OPT_4, MF_ENABLED);
  526.  
  527.                   SetWindowText(hTextWnd, GetStringRes (IDS_SEL_ACCESS));
  528.  
  529.                }
  530.                else
  531.                {
  532.                   SetWindowText(hTextWnd, GetStringRes(IDS_ERR_MAPVIEW_FAILED));
  533.                }
  534.                return 0L;
  535.             }
  536.  
  537.             case MM_OPT_4:
  538.             { //Access
  539.                RECT    rcl;
  540.  
  541.                SetWindowText(hTextWnd,
  542.                              GetStringRes (IDS_ACCESSING_SERVER_WRITE));
  543.  
  544.                if (pShrMem1)
  545.                {
  546.                   GetClientRect(hwnd, &rcl);
  547.                   hEdit = CreateWindow("edit", (LPSTR) NULL,
  548.                                         WS_CHILD      | WS_VISIBLE     |
  549.                                         WS_HSCROLL    | WS_VSCROLL     |
  550.                                         WS_BORDER     | ES_LEFT |
  551.                                         ES_MULTILINE  | ES_AUTOHSCROLL |
  552.                                         ES_AUTOVSCROLL,
  553.                                         0,0, rcl.right - rcl.left,
  554.                                         rcl.bottom - rcl.top -
  555.                                         GetWindowLong(hTextWnd, GWL_USERDATA),
  556.                                         hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
  557.                   if (hEdit)
  558.                   {
  559.                      EnableMenuItem(hServerMenu, MM_OPT_4, MF_GRAYED);
  560.                      SetFocus(hEdit);
  561.                      fSuccess = TRUE;
  562.                   }
  563.                   else
  564.                      fSuccess = FALSE;
  565.                }
  566.                else
  567.                   fSuccess = FALSE;
  568.  
  569.                if (!fSuccess)
  570.                {
  571.                   MessageBox(ghwndMain,
  572.                              GetStringRes(IDS_ERR_ACCESS_WRITE_FAILED),
  573.                              NULL, MB_OK);
  574.                   SetWindowText(hTextWnd,
  575.                                 GetStringRes (IDS_ERR_ACCESS_WRITE_FAILED));
  576.                }
  577.  
  578.                return 0L;
  579.             }
  580.          } // End of switch (LOWORD(wParam))
  581.  
  582.          switch (HIWORD(wParam))
  583.          {
  584.             case EN_UPDATE:
  585.             {
  586.                if (hEdit && (hEdit == (HWND)lParam))
  587.                {
  588.                   bDirty = TRUE;
  589.                }
  590.                return 0L;
  591.             }
  592.          }
  593.  
  594.       }
  595.       case WM_TIMER:
  596.          if (bDirty && IsWindow(hEdit))
  597.          {
  598.             int     iCnt;
  599.             iCnt = SendMessage(hEdit, WM_GETTEXT, (WPARAM)4000, (LPARAM)pShrMem1);
  600.  
  601.             if (iCnt)
  602.             {
  603.                bDirty = FALSE;
  604.             }
  605.  
  606.          }
  607.          return 0L;
  608.  
  609.       case WM_MDIACTIVATE:
  610.          if ((HWND) lParam == hwnd)
  611.          {
  612.             SendMessage(GetParent(hwnd), WM_MDISETMENU,
  613.                         (DWORD)  hServerMenu,
  614.                         (LONG)   hServerMenuWindow) ;
  615.             DrawMenuBar(GetParent(GetParent(hwnd))) ;
  616.          }
  617.          return 0;
  618.  
  619.       case WM_SIZE:
  620.          if (hEdit)
  621.             MoveWindow(hEdit, 0, 0,
  622.                        LOWORD(lParam),
  623.                        HIWORD(lParam)-GetWindowLong(hTextWnd, GWL_USERDATA),
  624.                        TRUE);
  625.  
  626.          MoveWindow(hTextWnd, 0,
  627.                     HIWORD(lParam) - GetWindowLong(hTextWnd, GWL_USERDATA),
  628.                     LOWORD(lParam),
  629.                     HIWORD(lParam), TRUE);
  630.  
  631.          return DefMDIChildProc(hwnd, message, wParam, lParam);
  632.  
  633.       case WM_CREATE:
  634.       {
  635.          PPERWNDINFO      pWndInfo;
  636.          PNODE            pHead;
  637.          HANDLE           hHead, hTmp;
  638.          RECT             rect;
  639.  
  640.          GetClientRect(hwnd, &rect);
  641.          hTextWnd = CreateWindow("Text", NULL,
  642.                                  WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
  643.                                  0, 0, 0, 0,
  644.                                  hwnd,
  645.                                  (HMENU) 2,
  646.                                  ghModule,
  647.                                  NULL);
  648.  
  649.          EnableMenuItem(hServerMenu, MM_OPT_1, MF_ENABLED);
  650.  
  651.  
  652.          SetWindowText(hTextWnd, GetStringRes (IDS_SEL_CREATE_FILE));
  653.  
  654.          // now find match
  655.          hHead = (HANDLE) GetWindowLong(ghwndMain, 0);
  656.          if (hHead && (pHead = (PNODE)LocalLock(hHead)))
  657.          {
  658.             while ((pHead->ChildWnd.hThisWnd != hwnd) && (pHead->hNext))
  659.             {
  660.                hTmp = hHead;
  661.                hHead = pHead->hNext;
  662.                LocalUnlock(hTmp);
  663.  
  664.                pHead = (PNODE)LocalLock(hHead);
  665.             }
  666.  
  667.             if (pHead->ChildWnd.hThisWnd == hwnd)
  668.             {
  669.                pWndInfo = &pHead->ChildWnd;
  670.                GetClientRect(pWndInfo->hThisWnd, &pWndInfo->rcClient);
  671.             }
  672.  
  673.             LocalUnlock(hHead);
  674.          }
  675.          return DefMDIChildProc(hwnd, message, wParam, lParam);
  676.       }
  677.  
  678.       case WM_CLOSE:
  679.       {
  680.          PPERWNDINFO      pWndInfo;
  681.          PNODE            pHead, pTrail;
  682.          HANDLE           hHead, hTmp;
  683.  
  684.          EnableMenuItem(hServerMenu, MM_OPT_2, MF_GRAYED);
  685.          EnableMenuItem(hServerMenu, MM_OPT_3, MF_GRAYED);
  686.          EnableMenuItem(hServerMenu, MM_OPT_4, MF_GRAYED);
  687.  
  688.          SendMessage(GetParent(hwnd), WM_MDISETMENU, (DWORD)hMenu, (LONG)hMenuWindow);
  689.          DrawMenuBar(GetParent(GetParent(hwnd))) ;
  690.  
  691.  
  692.          // Unmap view, close mapping and file!
  693.          if (pShrMem1)
  694.          {
  695.             UnmapViewOfFile (pShrMem1);
  696.             pShrMem1 = NULL;
  697.          }
  698.  
  699.          if (hMem1)
  700.          {
  701.             CloseHandle (hMem1);
  702.             hMem1 = NULL;
  703.          }
  704.  
  705.          if (MapFileHandle && MapFileHandle != INVALID_HANDLE_VALUE)
  706.          {
  707.             CloseHandle (MapFileHandle);
  708.             MapFileHandle = NULL;
  709.          }
  710.  
  711.          // now find match
  712.          hHead = (HANDLE) GetWindowLong(ghwndMain, 0);
  713.          if ((hHead) && (pHead = (PNODE)LocalLock(hHead)))
  714.          {
  715.             pTrail = pHead;
  716.             while ((pHead->ChildWnd.hThisWnd != hwnd) && (pHead->hNext))
  717.             {
  718.                hTmp = hHead;
  719.                pTrail = pHead;
  720.                hHead = pHead->hNext;
  721.                LocalUnlock(hTmp);
  722.  
  723.                pHead = (PNODE) LocalLock(hHead);
  724.             }
  725.  
  726.             if (pHead->ChildWnd.hThisWnd == hwnd)
  727.             {
  728.                pWndInfo = &pHead->ChildWnd;
  729.  
  730.                if (pTrail == pHead)
  731.                   SetWindowLong(ghwndMain, 0, (LONG) pHead->hNext);
  732.                else
  733.                   pTrail->hNext = pHead->hNext;
  734.  
  735.                LocalUnlock(hHead);
  736.                LocalFree(hHead);
  737.             }
  738.             else
  739.             {
  740.                LocalUnlock(hHead);
  741.             }
  742.          }
  743.          return DefMDIChildProc(hwnd, message, wParam, lParam);
  744.       }
  745.  
  746.       case WM_DESTROY:
  747.          KillTimer(hwnd, 1);
  748.          return 0L;
  749.  
  750.       case WM_PAINT:
  751.          return DefMDIChildProc(hwnd, message, wParam, lParam);
  752.  
  753.       default:
  754.          return DefMDIChildProc(hwnd, message, wParam, lParam);
  755.    }
  756. }
  757.  
  758.  
  759. /***************************************************************************\
  760. * ClientWndProc
  761. *
  762. \***************************************************************************/
  763.  
  764. long APIENTRY ClientWndProc( HWND hwnd,
  765.                              UINT message,
  766.                              DWORD wParam,
  767.                              LONG lParam)
  768. {
  769.     static HANDLE hMem1    = NULL;
  770.     static LPVOID pShrMem1 = NULL;
  771.     static HANDLE hEdit;
  772.     static HANDLE hTextWnd;
  773.     BOOL   fSuccess = FALSE;
  774.  
  775.     switch (message)
  776.     {
  777.         case WM_COMMAND:
  778.         {
  779.  
  780.           switch (LOWORD(wParam))
  781.           {
  782.              case MM_OPT_5:
  783.              { //Open File Mapping
  784.  
  785.                  SetWindowText(hTextWnd, GetStringRes (IDS_OPENING_FILE));
  786.  
  787.                  switch (DialogBox(ghModule, "MapName", hwnd, (DLGPROC)MapFileName))
  788.                  {
  789.                      case IDBTN_OK:
  790.                          if (hMem1 = OpenMap(gszMapName))
  791.                              fSuccess = TRUE;
  792.                          else
  793.                             fSuccess = FALSE;
  794.                          break;
  795.  
  796.                      default:
  797.                          fSuccess = FALSE;
  798.                          break;
  799.                  }
  800.  
  801.                  if (fSuccess)
  802.                  {
  803.                     EnableMenuItem(hClientMenu, MM_OPT_5, MF_GRAYED);
  804.                     EnableMenuItem(hClientMenu, MM_OPT_6, MF_ENABLED);
  805.  
  806.                     SetWindowText(hTextWnd, GetStringRes (IDS_SEL_MAP_VIEW));
  807.                  }
  808.                  else
  809.                  {
  810.                     SetWindowText(hTextWnd,
  811.                                   GetStringRes (IDS_ERR_OPEN_MAPPING_FAILED));
  812.                  }
  813.                  return 0L;
  814.  
  815.             }
  816.             case MM_OPT_6:
  817.             { //Map View of File
  818.  
  819.                 SetWindowText(hTextWnd, GetStringRes (IDS_MAPPING_VIEW));
  820.  
  821.                 if (hMem1 && (pShrMem1 = (LPVOID) MapView(hMem1)))
  822.                 {
  823.                    EnableMenuItem(hClientMenu, MM_OPT_6, MF_GRAYED);
  824.                    EnableMenuItem(hClientMenu, MM_OPT_7, MF_ENABLED);
  825.  
  826.                    SetWindowText(hTextWnd, GetStringRes (IDS_SEL_ACCESS_READ));
  827.                 }
  828.                 else
  829.                 {
  830.                    SetWindowText(hTextWnd,
  831.                                  GetStringRes(IDS_ERR_MAPVIEW_FAILED));
  832.                 }
  833.  
  834.                 return 0L;
  835.             }
  836.  
  837.             case MM_OPT_7:
  838.             { //Access
  839.                 RECT    rcl;
  840.  
  841.                  SetWindowText(hTextWnd,
  842.                                GetStringRes(IDS_ACCESSING_SERVER_READ));
  843.  
  844.                  fSuccess = FALSE;  // assume failure.
  845.  
  846.                  if (pShrMem1)
  847.                  {
  848.                     GetClientRect(hwnd, &rcl);
  849.  
  850.                     hEdit = CreateWindow("edit", NULL,
  851.                                    WS_CHILD     | WS_VISIBLE     |
  852.                                    WS_HSCROLL   | WS_VSCROLL     |
  853.                                    WS_BORDER    | ES_LEFT        |
  854.                                    ES_MULTILINE | ES_AUTOHSCROLL |
  855.                                    ES_READONLY  | ES_AUTOVSCROLL,
  856.                                    0,0, rcl.right-rcl.left,
  857.                                    rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
  858.                                    hwnd, (HMENU) 1, ghModule, NULL);
  859.                     if (hEdit)
  860.                     {
  861.                        SetFocus(hEdit);
  862.                        fSuccess = TRUE;
  863.                     }
  864.                  }
  865.  
  866.                  if (fSuccess)
  867.                  {
  868.                     SendMessage(hEdit, WM_SETTEXT, 0L, (LONG)pShrMem1);
  869.                     SetTimer(hwnd, 2, 1000, NULL);
  870.                     EnableMenuItem(hClientMenu, MM_OPT_7, MF_GRAYED);
  871.                     EnableMenuItem(hClientMenu, MM_OPT_8, MF_ENABLED);
  872.                  }
  873.                  else
  874.                  {
  875.                     MessageBox(ghwndMain,
  876.                                GetStringRes (IDS_ERR_ACCESS_READ_FAILED),
  877.                                NULL, MB_OK);
  878.                     SetWindowText(hTextWnd,
  879.                                   GetStringRes (IDS_ERR_ACCESS_READ_FAILED));
  880.                  }
  881.  
  882.              return 0L;
  883.              }
  884.  
  885.             case MM_OPT_8:
  886.             { // refresh now
  887.                HANDLE hActive;
  888.  
  889.                hActive = (HANDLE) SendMessage(GetParent(hwnd), WM_MDIGETACTIVE, 0L, 0L);
  890.                SendMessage(hEdit, WM_SETTEXT, 0L, (LONG)pShrMem1);
  891.                return 0L;
  892.             }
  893.         }
  894.     }
  895.  
  896.     case WM_TIMER:
  897.     {
  898.         HANDLE hActive;
  899.  
  900.         if (IsWindow (hEdit) && pShrMem1)
  901.         {
  902.            hActive = (HANDLE) SendMessage(GetParent(hwnd), WM_MDIGETACTIVE, 0L, 0L);
  903.            SendMessage(hEdit, WM_SETTEXT, 0L, (LONG)pShrMem1);
  904.         }
  905.         return 0L;
  906.     }
  907.  
  908.     case WM_MDIACTIVATE:
  909.         if ((HWND) lParam == hwnd)
  910.         {
  911.            SendMessage(GetParent(hwnd), WM_MDISETMENU,
  912.                        (DWORD)  hClientMenu,
  913.                        (LONG)   hClientMenuWindow);
  914.            DrawMenuBar(GetParent(GetParent(hwnd))) ;
  915.         }
  916.         return 0;
  917.  
  918.     case WM_SIZE:
  919.         if (hEdit)
  920.            MoveWindow(hEdit, 0, 0,
  921.                       LOWORD(lParam),
  922.                       HIWORD(lParam)-GetWindowLong(hTextWnd, GWL_USERDATA),
  923.                       TRUE);
  924.  
  925.         MoveWindow(hTextWnd, 0,
  926.                    HIWORD(lParam) - GetWindowLong(hTextWnd, GWL_USERDATA),
  927.                    LOWORD(lParam),
  928.                    HIWORD(lParam), TRUE);
  929.  
  930.         return DefMDIChildProc(hwnd, message, wParam, lParam);
  931.  
  932.     case WM_CREATE:
  933.     {
  934.         PPERWNDINFO      pWndInfo;
  935.         PNODE            pHead;
  936.         HANDLE           hHead, hTmp;
  937.         RECT             rect;
  938.  
  939.         GetClientRect(hwnd, &rect);
  940.         hTextWnd = CreateWindow("Text", NULL,
  941.                                 WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
  942.                                 0, 0, 0, 0,
  943.                                 hwnd,
  944.                                 (HMENU) 2,
  945.                                 ghModule,
  946.                                 NULL);
  947.  
  948.         EnableMenuItem(hClientMenu, MM_OPT_5, MF_ENABLED);
  949.  
  950.         SetWindowText(hTextWnd, GetStringRes (IDS_SEL_OPEN_FILE));
  951.  
  952.         // now find match
  953.         hHead = (HANDLE) GetWindowLong(ghwndMain, 0);
  954.         if (hHead && (pHead = (PNODE)LocalLock(hHead)))
  955.         {
  956.  
  957.            while ((pHead->ChildWnd.hThisWnd != hwnd) && (pHead->hNext))
  958.            {
  959.               hTmp = hHead;
  960.               hHead = pHead->hNext;
  961.               LocalUnlock(hTmp);
  962.               pHead = (PNODE) LocalLock(hHead);
  963.            }
  964.  
  965.            if (pHead->ChildWnd.hThisWnd == hwnd)
  966.            {
  967.               pWndInfo = &pHead->ChildWnd;
  968.               GetClientRect(pWndInfo->hThisWnd, &pWndInfo->rcClient);
  969.            }
  970.  
  971.            LocalUnlock(hHead);
  972.            return DefMDIChildProc(hwnd, message, wParam, lParam);
  973.         }
  974.         return DefMDIChildProc(hwnd, message, wParam, lParam);
  975.     }
  976.  
  977.     case WM_CLOSE:
  978.     {
  979.         PPERWNDINFO      pWndInfo;
  980.         PNODE            pHead, pTrail;
  981.         HANDLE           hHead, hTmp;
  982.  
  983.  
  984.         EnableMenuItem(hClientMenu, MM_OPT_6, MF_GRAYED);
  985.         EnableMenuItem(hClientMenu, MM_OPT_7, MF_GRAYED);
  986.         EnableMenuItem(hClientMenu, MM_OPT_8, MF_GRAYED);
  987.  
  988.         SendMessage(GetParent(hwnd), WM_MDISETMENU,
  989.                     (DWORD) hMenu,
  990.                     (LONG)   hMenuWindow) ;
  991.         DrawMenuBar(GetParent(GetParent(hwnd))) ;
  992.  
  993.         // Don't need to read from the edit control anymore
  994.         KillTimer(hwnd, 2);
  995.  
  996.  
  997.         // Unmap view, close mapping!
  998.         if (pShrMem1)
  999.         {
  1000.            UnmapViewOfFile (pShrMem1);
  1001.            pShrMem1 = NULL;
  1002.         }
  1003.  
  1004.         if (hMem1)
  1005.         {
  1006.            CloseHandle (hMem1);
  1007.            hMem1 = NULL;
  1008.         }
  1009.  
  1010.  
  1011.         // now find match
  1012.         hHead = (HANDLE) GetWindowLong(ghwndMain, 0);
  1013.         if (hHead && (pHead = (PNODE)LocalLock(hHead)))
  1014.         {
  1015.             pTrail = pHead;
  1016.             while ((pHead->ChildWnd.hThisWnd != hwnd) && (pHead->hNext))
  1017.             {
  1018.                hTmp = hHead;
  1019.                pTrail = pHead;
  1020.                hHead = pHead->hNext;
  1021.                LocalUnlock(hTmp);
  1022.  
  1023.                pHead = (PNODE) LocalLock(hHead);
  1024.             }
  1025.  
  1026.             if (pHead->ChildWnd.hThisWnd == hwnd)
  1027.             {
  1028.                 pWndInfo = &pHead->ChildWnd;
  1029.  
  1030.                 if (pTrail == pHead)
  1031.                     SetWindowLong(ghwndMain, 0, (LONG) pHead->hNext);
  1032.                 else
  1033.                     pTrail->hNext = pHead->hNext;
  1034.  
  1035.                 LocalUnlock(hHead);
  1036.                 LocalFree(hHead);
  1037.             }
  1038.             else
  1039.             {
  1040.                 LocalUnlock(hHead);
  1041.             }
  1042.         }
  1043.         return DefMDIChildProc(hwnd, message, wParam, lParam);
  1044.  
  1045.     }
  1046.  
  1047.     case WM_DESTROY:
  1048.         return 0l;
  1049.  
  1050.     default:
  1051.          return DefMDIChildProc(hwnd, message, wParam, lParam);
  1052.     }
  1053.  
  1054. }
  1055.  
  1056.  
  1057.  
  1058.  
  1059. /***************************************************************************\
  1060. * About
  1061. *
  1062. * About dialog proc.
  1063. *
  1064. \***************************************************************************/
  1065.  
  1066. BOOL CALLBACK APIENTRY About( HWND hDlg,
  1067.                               UINT message,
  1068.                               DWORD wParam,
  1069.                               LONG lParam)
  1070. {
  1071.     switch (message)
  1072.     {
  1073.         case WM_INITDIALOG:
  1074.             return TRUE;
  1075.  
  1076.         case WM_COMMAND:
  1077.             if (wParam == IDOK)
  1078.                 EndDialog(hDlg, wParam);
  1079.             break;
  1080.     }
  1081.     return FALSE;
  1082.  
  1083.     UNREFERENCED_PARAMETER(lParam);
  1084.     UNREFERENCED_PARAMETER(hDlg);
  1085. }
  1086.  
  1087. /***************************************************************************\
  1088. * MapFileName
  1089. *
  1090. * MapFileName dialog proc.
  1091. *
  1092. \***************************************************************************/
  1093.  
  1094. BOOL CALLBACK MapFileName( HWND hDlg,
  1095.                            UINT message,
  1096.                            DWORD wParam,
  1097.                            LONG lParam)
  1098. {
  1099.  
  1100.     switch (message)
  1101.     {
  1102.     case WM_INITDIALOG:
  1103.         return TRUE;
  1104.  
  1105.     case WM_COMMAND:
  1106.         switch (wParam)
  1107.         {
  1108.             case IDBTN_OK:
  1109.             {
  1110.                 if (!GetDlgItemText(hDlg, IDEDIT_MAPNAME, gszMapName, 20))
  1111.                 {
  1112.                    strncpy(gszMapName, "MapName1", 10);        // default name
  1113.                 }
  1114.                 EndDialog(hDlg, IDBTN_OK);
  1115.                 break;
  1116.             }
  1117.         }
  1118.     }
  1119.     return FALSE;
  1120.  
  1121.     UNREFERENCED_PARAMETER(lParam);
  1122.     UNREFERENCED_PARAMETER(hDlg);
  1123. }
  1124.  
  1125. /***************************************************************************\
  1126. * FileType
  1127. *
  1128. * FileType dialog proc.
  1129. *
  1130. \***************************************************************************/
  1131.  
  1132. BOOL CALLBACK FileType( HWND hDlg,
  1133.                         UINT message,
  1134.                         DWORD wParam,
  1135.                         LONG lParam)
  1136. {
  1137.  
  1138.     switch (message)
  1139.     {
  1140.        case WM_INITDIALOG:
  1141.            return TRUE;
  1142.  
  1143.        case WM_COMMAND:
  1144.            switch (wParam)
  1145.            {
  1146.               case IDBTN_PAGE:
  1147.               {
  1148.                  EndDialog(hDlg, IDBTN_PAGE);
  1149.                  break;
  1150.               }
  1151.  
  1152.               case IDBTN_MAP:
  1153.               {
  1154.                   if ((GetDlgItemText(hDlg, IDEDIT_MAPFILE, gszFile, 20)) == 0)
  1155.                       EndDialog(hDlg, IDBTN_PAGE);  // default to use PAGE file
  1156.                   else
  1157.                       EndDialog(hDlg, IDBTN_MAP);
  1158.  
  1159.                   break;
  1160.               }
  1161.            }
  1162.     }
  1163.     return FALSE;
  1164.  
  1165.     UNREFERENCED_PARAMETER(lParam);
  1166.     UNREFERENCED_PARAMETER(hDlg);
  1167. }
  1168.  
  1169.  
  1170. /*************************************************************************
  1171. *
  1172. * TextWndProc
  1173. *
  1174. * Text Window proc.
  1175. *
  1176. \***************************************************************************/
  1177.  
  1178. LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
  1179. {
  1180.     static HFONT hFont = (HFONT) NULL;
  1181.  
  1182.     switch (message)
  1183.     {
  1184.        case WM_CREATE:
  1185.        {
  1186.           LOGFONT    lf;
  1187.           HDC        hDC;
  1188.           HFONT      hOldFont;
  1189.           TEXTMETRIC tm;
  1190.           RECT       rect;
  1191.           LONG       lHeight;
  1192.  
  1193.           SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, FALSE);
  1194.  
  1195.           hDC = GetDC(hwnd);
  1196.           // this is the height for 8 point size font in pixels
  1197.           lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
  1198.  
  1199.           hFont = CreateFontIndirect(&lf);
  1200.           hOldFont = SelectObject(hDC, hFont);
  1201.           GetTextMetrics(hDC, &tm);
  1202.           GetClientRect(GetParent(hwnd), &rect);
  1203.  
  1204.           // base the height of the window on size of text
  1205.           lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
  1206.           // saved the height for later reference
  1207.           SetWindowLong(hwnd, GWL_USERDATA, lHeight);
  1208.           SetWindowPos(hwnd, NULL, 0, rect.bottom-lHeight,
  1209.                        rect.right-rect.left, lHeight,
  1210.                        SWP_NOZORDER | SWP_NOMOVE);
  1211.  
  1212.           ReleaseDC(hwnd, hDC);
  1213.           break;
  1214.        }
  1215.  
  1216.     case WM_DESTROY:
  1217.        if (hFont)
  1218.           DeleteObject(hFont);
  1219.        break;
  1220.  
  1221.     case WM_SETTEXT:
  1222.        DefWindowProc(hwnd, message, wParam, lParam);
  1223.        InvalidateRect(hwnd,NULL,FALSE);
  1224.        UpdateWindow(hwnd);
  1225.        return 0L;
  1226.  
  1227.     case WM_PAINT:
  1228.     {
  1229.        PAINTSTRUCT ps;
  1230.        RECT   rc;
  1231.        char   ach[128];
  1232.        int    len, nxBorder, nyBorder;
  1233.        HFONT  hOldFont = NULL;
  1234.  
  1235.        BeginPaint(hwnd, &ps);
  1236.  
  1237.        GetClientRect(hwnd,&rc);
  1238.  
  1239.        nxBorder = GetSystemMetrics(SM_CXBORDER);
  1240.        rc.left  += 9*nxBorder;
  1241.        rc.right -= 9*nxBorder;
  1242.  
  1243.        nyBorder = GetSystemMetrics(SM_CYBORDER);
  1244.        rc.top    += 3*nyBorder;
  1245.        rc.bottom -= 3*nyBorder;
  1246.  
  1247.        // 3D Text
  1248.        len = GetWindowText(hwnd, ach, sizeof(ach));
  1249.        SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
  1250.  
  1251.        SetBkMode(ps.hdc, TRANSPARENT);
  1252.        SetTextColor(ps.hdc, RGB(64,96,96));
  1253.        if (hFont)
  1254.            hOldFont = SelectObject(ps.hdc, hFont);
  1255.        ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2,
  1256.                   ETO_OPAQUE | ETO_CLIPPED, &rc, ach, len, NULL);
  1257.  
  1258.        SetTextColor(ps.hdc, RGB(128,128,128));
  1259.        if (hFont)
  1260.            hOldFont = SelectObject(ps.hdc, hFont);
  1261.        ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
  1262.                    &rc, ach, len, NULL);
  1263.  
  1264.        SetTextColor(ps.hdc, RGB(255,255,255));
  1265.        if (hFont)
  1266.            hOldFont = SelectObject(ps.hdc, hFont);
  1267.        ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
  1268.                    &rc, ach, len, NULL);
  1269.  
  1270.        SetBkMode(ps.hdc, OPAQUE);
  1271.  
  1272.        if (hOldFont)
  1273.            SelectObject(ps.hdc, hOldFont);
  1274.  
  1275.        EndPaint(hwnd, &ps);
  1276.        return 0L;
  1277.        }
  1278.     }
  1279.     return DefWindowProc(hwnd, message, wParam, lParam);
  1280. }
  1281.  
  1282.  
  1283. //---------------------------------------------------------------------------
  1284. //
  1285. // FUNCTION:    GetStringRes (int id INPUT ONLY)
  1286. //
  1287. // COMMENTS:    Load the resource string with the ID given, and return a
  1288. //              pointer to it.  Notice that the buffer is common memory so
  1289. //              the string must be used before this call is made a second time.
  1290. //
  1291. //---------------------------------------------------------------------------
  1292.  
  1293. LPTSTR GetStringRes (int id)
  1294. {
  1295.   static TCHAR buffer[MAX_PATH];
  1296.  
  1297.   buffer[0]=0;
  1298.   LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
  1299.   return buffer;
  1300. }
  1301.  
  1302.