home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / simplemapi / mapiapp.c < prev    next >
C/C++ Source or Header  |  1996-03-28  |  25KB  |  514 lines

  1. /* QuickCase:W KNB Version 1.00 */
  2. #include "MAPIAPP.h"
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include "mapi.h"
  6. #define MAIN 1
  7. #include "mapinit.h"
  8.  
  9.  
  10. HANDLE hLibrary;
  11. LHANDLE hMAPISession;
  12.  
  13. MapiMessage mmMapiMessage;
  14.  
  15. ULONG nMessageSize = 0x000004000;
  16. lpMapiMessage FAR *lppMessage;
  17. lpMapiMessage lpMessage;
  18. char szSeedMessageID[512];
  19. char szMessageID[512];
  20. char szSubject[512];
  21. char szNoteText[4096];
  22.  
  23. LPSTR lpszSeedMessageID = &szSeedMessageID[0];
  24. LPSTR lpszMessageID = &szMessageID[0];
  25.  
  26. LPSTR pszSubject = &szSubject[0];
  27. LPSTR pszNoteText = &szNoteText[0];
  28. LPSTR pszDateReceived = "1991/03/23 12:00";
  29. MapiRecipDesc rdOriginator = { 0L,MAPI_ORIG,(LPSTR)"ONE",NULL};
  30.  
  31. int iFindFirst= TRUE;
  32.  
  33. void InitMessage(lpMapiMessage pmmMessage)
  34. {
  35.   pmmMessage->ulReserved = 0L;
  36.   pmmMessage->lpszSubject =pszSubject;
  37.   pmmMessage->lpszNoteText =pszNoteText;
  38.   pmmMessage->lpszMessageType = NULL;
  39.   pmmMessage->lpszDateReceived = pszDateReceived;
  40.   pmmMessage->flFlags = MAPI_UNREAD;
  41.   pmmMessage->lpOriginator = &rdOriginator;
  42.   pmmMessage->nRecipCount = 0L;
  43.   pmmMessage->lpRecips = NULL;
  44.   pmmMessage->nFileCount = 0L;
  45.   pmmMessage->lpFiles = NULL;
  46. }
  47.  
  48. /****************************************************************************
  49.  
  50.     FUNCTION: OutOfMemory(void)
  51.  
  52.     PURPOSE:  Displays warning message
  53.  
  54. ****************************************************************************/
  55. void OutOfMemory(void)
  56. {
  57.     MessageBox(
  58.         GetFocus(),
  59.         GetStringRes (IDS_ERR_NO_MEMORY),
  60.         NULL,
  61.         MB_ICONHAND | MB_SYSTEMMODAL);
  62.     return;
  63. }
  64.  
  65. void mycpystr(char * npszStrg, LPSTR lpszStrg)
  66. {
  67.   if (lpszStrg != NULL)
  68.     strcpy(npszStrg, lpszStrg);
  69.   else
  70.      *npszStrg = '\0';
  71. }
  72.  
  73.  
  74. /************************************************************************/
  75. /*                                                                      */
  76. /* Windows 3.0 Main Program Body                                        */
  77. /*                                                                      */
  78. /* The following routine is the Windows Main Program.  The Main Program */
  79. /* is executed when a program is selected from the Windows Control      */
  80. /* Panel or File Manager.  The WinMain routine registers and creates    */
  81. /* the program's main window and initializes global objects.  The       */
  82. /* WinMain routine also includes the applications message dispatch      */
  83. /* loop.  Every window message destined for the main window or any      */
  84. /* subordinate windows is obtained, possibly translated, and            */
  85. /* dispatched to a window or dialog processing function. The dispatch   */
  86. /* loop is exited when a WM_QUIT message is obtained.  Before exiting   */
  87. /* the WinMain routine should destroy any objects created and free      */
  88. /* memory and other resources.                                          */
  89. /*                                                                      */
  90. /************************************************************************/
  91.  
  92. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
  93. {
  94.  /***********************************************************************/
  95.  /* HANDLE hInstance;       handle for this instance                    */
  96.  /* HANDLE hPrevInstance;   handle for possible previous instances      */
  97.  /* LPSTR  lpszCmdLine;     long pointer to exec command line           */
  98.  /* int    nCmdShow;        Show code for main window display           */
  99.  /***********************************************************************/
  100.  
  101.  MSG        msg;           /* MSG structure to store your messages        */
  102.  int        nRc;           /* return value from Register Classes          */
  103.  long       nWndunits;     /* window units for size and location          */
  104.  int        nWndx;         /* the x axis multiplier                       */
  105.  int        nWndy;         /* the y axis multiplier                       */
  106.  int        nX;            /* the resulting starting point (x, y)         */
  107.  int        nY;
  108.  int        nWidth;        /* the resulting width and height for this     */
  109.  int        nHeight;       /* window                                      */
  110.  
  111.  strcpy(szAppName, "MAPIAPP");
  112.  hInst = hInstance;
  113.  if(!hPrevInstance)
  114.    {
  115.     /* register window classes if first instance of application         */
  116.     if ((nRc = nCwRegisterClasses()) == -1)
  117.       {
  118.        /* registering one of the windows failed                         */
  119.        LoadString(hInst, IDS_ERR_REGISTER_CLASS, szString, sizeof(szString));
  120.        MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
  121.        return nRc;
  122.       }
  123.    }
  124.  
  125.  /* Create a device independant size and location                       */
  126.  nWndunits = GetDialogBaseUnits();
  127.  nWndx = LOWORD(nWndunits);
  128.  nWndy = HIWORD(nWndunits);
  129.  nX = ((60 * nWndx) / 4);
  130.  nY = ((60 * nWndy) / 8);
  131.  nWidth = ((197 * nWndx) / 4);
  132.  nHeight = ((138 * nWndy) / 8);
  133.  
  134.  /* create application's Main window                                    */
  135.  hWndMain = CreateWindow(
  136.                 szAppName,               /* Window class name           */
  137.                 GetStringRes (IDS_APP_TITLE),  /* Window's title        */
  138.                 WS_CAPTION      |        /* Title and Min/Max           */
  139.                 WS_SYSMENU      |        /* Add system menu box         */
  140.                 WS_MINIMIZEBOX  |        /* Add minimize box            */
  141.                 WS_MAXIMIZEBOX  |        /* Add maximize box            */
  142.                 WS_BORDER       |        /* thin frame                  */
  143.                 WS_CLIPCHILDREN |        /* don't draw in child windows areas */
  144.                 WS_OVERLAPPED,
  145.                 nX, nY,                  /* X, Y                        */
  146.                 nWidth, nHeight,         /* Width, Height of window     */
  147.                 NULL,                    /* Parent window's handle      */
  148.                 NULL,                    /* Default to Class Menu       */
  149.                 hInst,                   /* Instance of window          */
  150.                 NULL);                   /* Create struct for WM_CREATE */
  151.  
  152.  
  153.  if (InitMAPI() != 0)
  154.    return ERR_LOAD_LIB;
  155.  
  156.   InitMessage(&mmMapiMessage);
  157.  
  158.  if(hWndMain == NULL)
  159.    {
  160.     LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
  161.     MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
  162.     return IDS_ERR_CREATE_WINDOW;
  163.    }
  164.  
  165.  EnableMenuItem(GetMenu(hWndMain), IDM_A_LOGOFF, MF_DISABLED | MF_GRAYED);
  166.  EnableMenuItem(GetMenu(hWndMain), IDM_S_MAIL, MF_DISABLED | MF_GRAYED);
  167.  EnableMenuItem(GetMenu(hWndMain), IDM_S_DOCUMENT, MF_DISABLED | MF_GRAYED);
  168.  EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDFIRST, MF_DISABLED | MF_GRAYED);
  169.  EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_DISABLED | MF_GRAYED);
  170.  EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED);
  171.  EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED);
  172.  
  173.  ShowWindow(hWndMain, nCmdShow);            /* display main window      */
  174.  
  175.  while(GetMessage(&msg, NULL, 0, 0))        /* Until WM_QUIT message    */
  176.    {
  177.     TranslateMessage(&msg);
  178.     DispatchMessage(&msg);
  179.    }
  180.  
  181.  DeInitMAPI();
  182.  /* Do clean up before exiting from the application                     */
  183.  CwUnRegisterClasses();
  184.  return msg.wParam;
  185. } /*  End of WinMain                                                    */
  186. /************************************************************************/
  187. /*                                                                      */
  188. /* Main Window Procedure                                                */
  189. /*                                                                      */
  190. /* This procedure provides service routines for the Windows events      */
  191. /* (messages) that Windows sends to the window, as well as the user     */
  192. /* initiated events (messages) that are generated when the user selects */
  193. /* the action bar and pulldown menu controls or the corresponding       */
  194. /* keyboard accelerators.                                               */
  195. /*                                                                      */
  196. /* The SWITCH statement shown below distributes the window messages to  */
  197. /* the respective message service routines, which are set apart by the  */
  198. /* CASE statements. The window procedures must provide an appropriate   */
  199. /* service routine for its end user initiated messages, as well as the  */
  200. /* general Windows messages (ie. WM_CLOSE message). If a message is     */
  201. /* sent to this procedure for which there is no programmed CASE clause  */
  202. /* (i.e., no service routine), the message is defaulted to the          */
  203. /* DefWindowProc function, where it is handled by Windows               */
  204. /*                                                                      */
  205. /* For the end-user initiated messages, this procedure is concerned     */
  206. /* principally with the WM_COMMAND message. The menu control ID (or the */
  207. /* corresponding accelerator ID) is communicated to this procedure in   */
  208. /* the first message parameter (wParam). The window procedure provides  */
  209. /* a major CASE statement for the WM_COMMAND message and a subordinate  */
  210. /* SWITCH statement to provide CASE clauses for the message service     */
  211. /* routines for the various menu item's, identified by their ID values. */
  212. /*                                                                      */
  213. /* The message service routines for the individual menu items are the   */
  214. /* main work points in the program. These service routines contain the  */
  215. /* units of work performed when the end user select one of the menu     */
  216. /* controls. The required application response to a menu control is     */
  217. /* programmed in its associated CASE clause. The service routines may   */
  218. /* contain subroutine calls to separately compiled and libraried        */
  219. /* routines, in-line calls to subroutines to be embodied in this source */
  220. /* code module, or program statements entered directly in the CASE      */
  221. /* clauses. Program control is switched to the appropriate service      */
  222. /* routine when Windows recognizes the end user event and sends a WM_COMMAND */
  223. /* message to the window procedure. The service routine provides the    */
  224. /* appropriate application-specific response to the end user initiated  */
  225. /* event, then breaks to return control to the WinMain() routine which  */
  226. /* continues to service the message queue of the window(s).             */
  227. /*                                                                      */
  228. /************************************************************************/
  229.  
  230. LONG FAR PASCAL WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
  231. {
  232.  HMENU      hMenu=0;            /* handle for the menu                 */
  233.  HBITMAP    hBitmap=0;          /* handle for bitmaps                  */
  234.  HDC        hDC;                /* handle for the display device       */
  235.  PAINTSTRUCT ps;                /* holds PAINT information             */
  236.  int        nRc=0;              /* return code                         */
  237.  FLAGS flFlag = 0L;
  238.  ULONG ulResult;
  239.   char szBuf[32*1024]; // Waste of stack space, but this is only a demo.
  240.   char szTmp[32*1024]; // Waste of stack space, but this is only a demo.
  241.  
  242.  switch (Message) {
  243.    case WM_COMMAND:
  244.      /* The Windows messages for action bar and pulldown menu items */
  245.      /* are processed here.                                         */
  246.      /* The WM_COMMAND message contains the message ID in its first */
  247.      /* parameter (wParam). This routine is programmed to SWITCH on */
  248.      /* the #define values generated by CASE:W for the menu items   */
  249.      /* in the application's header (*.H) file. The ID values have  */
  250.      /* the format, IDM_itemname. The service routines for the      */
  251.      /* various menu items follow the CASE statements up to the     */
  252.      /* generated BREAK statements.                                 */
  253.      switch (LOWORD(wParam)) {
  254.        case IDM_A_LOGON:
  255.             /* Place User Code to respond to the                   */
  256.             /* Menu Item Named "Log&In" here.                      */
  257.          flFlag =MAPI_NEW_SESSION | MAPI_LOGON_UI;
  258.          ulResult = (*lpfnMAPILogon)(hWnd, NULL, NULL, flFlag, 0L, (LPLHANDLE)&hMAPISession);
  259.          if (ulResult == 0L) {
  260.            EnableMenuItem(GetMenu(hWndMain), IDM_A_LOGOFF, MF_ENABLED);
  261.            EnableMenuItem(GetMenu(hWndMain), IDM_S_MAIL, MF_ENABLED);
  262.            EnableMenuItem(GetMenu(hWndMain), IDM_S_DOCUMENT, MF_ENABLED);
  263.            EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDFIRST, MF_ENABLED);
  264.            EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_ENABLED);
  265.          }
  266.        break;
  267.  
  268.        case IDM_A_LOGOFF:
  269.             /* Place User Code to respond to the                   */
  270.             /* Menu Item Named "Log&Off" here.                     */
  271.          ulResult = (*lpfnMAPILogoff)(hMAPISession, hWnd, 0L, 0L);
  272.          if (ulResult == 0L) {
  273.             EnableMenuItem(GetMenu(hWndMain), IDM_A_LOGOFF, MF_DISABLED | MF_GRAYED);
  274.              EnableMenuItem(GetMenu(hWndMain), IDM_S_MAIL, MF_DISABLED | MF_GRAYED);
  275.              EnableMenuItem(GetMenu(hWndMain), IDM_S_DOCUMENT, MF_DISABLED | MF_GRAYED);
  276.              EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDFIRST, MF_DISABLED | MF_GRAYED);
  277.              EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_DISABLED | MF_GRAYED);
  278.              EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED);
  279.              EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED);
  280.          }
  281.        break;
  282.  
  283.        case IDM_S_MAIL:
  284.             /* Place User Code to respond to the                   */
  285.             /* Menu Item Named "&Mail" here.                       */
  286.           flFlag =MAPI_DIALOG;
  287.          ulResult = (*lpfnMAPISendMail)(hMAPISession, hWnd, &mmMapiMessage, flFlag, 0L);
  288.        break;
  289.  
  290.        case IDM_S_DOCUMENT:
  291.             /* Place User Code to respond to the                   */
  292.             /* Menu Item Named "&Document" here.                   */
  293.          ulResult = (*lpfnMAPISendDocuments)(hWnd, ";", "C:\\CONFIG.SYS", "CONFIG.SYS", 0L);
  294.        break;
  295.  
  296.        case IDM_M_FINDFIRST:
  297.            iFindFirst=TRUE;
  298.        case IDM_M_FINDNEXT:
  299.             /* Place User Code to respond to the                   */
  300.             /* Menu Item Named "&Find Next" here.                  */
  301.          if (iFindFirst) {
  302.            *lpszSeedMessageID = '\0';
  303.            iFindFirst = FALSE;
  304.          }
  305.          else {
  306.            strcpy(lpszSeedMessageID,lpszMessageID);
  307.          }
  308.          ulResult = (*lpfnMAPIFindNext)(hMAPISession, hWnd, NULL, lpszSeedMessageID, flFlag, 0L, lpszMessageID);
  309.          if (ulResult == 0L) {
  310.            EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_ENABLED);
  311.            EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_ENABLED);
  312.            EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_ENABLED);
  313.          }
  314.          else {
  315.            EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_DISABLED | MF_GRAYED);
  316.            EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED);
  317.            EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED);
  318.          }
  319.        break;
  320.  
  321.        case IDM_M_READ:
  322.             /* Place User Code to respond to the                   */
  323.             /* Menu Item Named "&Read" here.                       */
  324.  
  325.            lppMessage= (lpMapiMessage FAR *) &lpMessage;
  326.            ulResult = (*lpfnMAPIReadMail)(hMAPISession, hWnd, lpszMessageID, flFlag, 0L, lppMessage);
  327.            if (ulResult == 0L) {
  328.              mycpystr(szTmp,lpMessage->lpOriginator->lpszName);
  329.              sprintf(szBuf, GetStringRes(IDS_FROM), szTmp);
  330.              mycpystr(szTmp,lpMessage->lpRecips[0].lpszName);
  331.              sprintf(szBuf, GetStringRes(IDS_TO), szBuf,szTmp);
  332.              mycpystr(szTmp,lpMessage->lpszDateReceived);
  333.              sprintf(szBuf, GetStringRes(IDS_DATE), szBuf,szTmp);
  334.              mycpystr(szTmp,lpMessage->lpszSubject);
  335.              sprintf(szBuf, GetStringRes(IDS_SUBJECT), szBuf,szTmp);
  336.              mycpystr(szTmp,lpMessage->lpszNoteText);
  337.              sprintf(szBuf,"%s%s",szBuf,szTmp);
  338.              
  339.              MessageBox(hWnd,szBuf, GetStringRes(IDS_MESSAGE), MB_OK);
  340.              ulResult = lpfnMAPIFreeBuffer((LPVOID)lpMessage);
  341.            }
  342.        break;
  343.  
  344.        case IDM_M_DELETE:
  345.             /* Place User Code to respond to the                   */
  346.             /* Menu Item Named "&Delete" here.                  */
  347.  
  348.          ulResult = (*lpfnMAPIDeleteMail)(hMAPISession, hWnd, lpszMessageID, flFlag, 0l);
  349.          if (ulResult == 0L) {
  350.            EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED);
  351.            EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED);
  352.          }
  353.        break;
  354.  
  355.        default:
  356.          return DefWindowProc(hWnd, Message, wParam, lParam);
  357.      }
  358.      if (ulResult != 0L) {       /** oops **/
  359.  
  360.        sprintf(szBuf, GetStringRes(IDS_RETURNED_ERROR), ulResult);
  361.        MessageBox(hWnd,szBuf, GetStringRes(IDS_FAILED),MB_OK);
  362.      }
  363.      else {
  364.        sprintf(szBuf, GetStringRes(IDS_GOOD_JOB));
  365.        MessageBox(hWnd,szBuf, GetStringRes(IDS_SUCCESS), MB_OK);
  366.      }
  367.    break;        /* End of WM_COMMAND                             */
  368.  
  369.    case WM_CREATE:
  370.      /* The WM_CREATE message is sent once to a window when the     */
  371.      /* window is created.  The window procedure for the new window */
  372.      /* receives this message after the window is created, but      */
  373.      /* before the window becomes visible.                          */
  374.      /*                                                             */
  375.      /* Parameters:                                                 */
  376.      /*                                                             */
  377.      /*    lParam  -  Points to a CREATESTRUCT structure with       */
  378.      /*               the following form:                           */
  379.      /*                                                             */
  380.      /*    typedef struct                                           */
  381.      /*              {                                              */
  382.      /*               LPSTR     lpCreateParams;                     */
  383.      /*               HANDLE    hInst;                              */
  384.      /*               HANDLE    hMenu;                              */
  385.      /*               HWND      hwndParent;                         */
  386.      /*               int       cy;                                 */
  387.      /*               int       cx;                                 */
  388.      /*               int       y;                                  */
  389.      /*               int       x;                                  */
  390.      /*               LONG      style;                              */
  391.      /*               LPSTR     lpszName;                           */
  392.      /*               LPSTR     lpszClass;                          */
  393.      /*               DWORD     dwExStyle;                          */
  394.      /*              }  CREATESTRUCT;                               */
  395.  
  396.  
  397.  
  398.    break;       /*  End of WM_CREATE                              */
  399.  
  400.    case WM_MOVE:     /*  code for moving the window                    */
  401.    break;
  402.  
  403.    case WM_SIZE:     /*  code for sizing client area                   */
  404.         /* wParam contains a code indicating the requested sizing      */
  405.         /* lParam contains the new height and width of the client area */
  406.    break;       /* End of WM_SIZE                                 */
  407.  
  408.    case WM_PAINT:    /* code for the window's client area              */
  409.      /* Obtain a handle to the device context                       */
  410.      /* BeginPaint will sends WM_ERASEBKGND if appropriate          */
  411.      memset(&ps, 0x00, sizeof(PAINTSTRUCT));
  412.      hDC = BeginPaint(hWnd, &ps);
  413.  
  414.      /* Included in case the background is not a pure color         */
  415.      SetBkMode(hDC, TRANSPARENT);
  416.  
  417.      /* Application should draw on the client window using          */
  418.      /* the GDI graphics and text functions.  'ps' the PAINTSTRUCT  */
  419.      /* returned by BeginPaint contains a rectangle to the          */
  420.      /* area that must be repainted.                                */
  421.  
  422.      /* Inform Windows painting is complete                         */
  423.      EndPaint(hWnd, &ps);
  424.    break;       /*  End of WM_PAINT                               */
  425.  
  426.    case WM_CLOSE:  /* close the window                                 */
  427.      /* Destroy child windows, modeless dialogs, then, this window  */
  428.      DestroyWindow(hWnd);
  429.      if (hWnd == hWndMain)
  430.        PostQuitMessage(0);  /* Quit the application                 */
  431.    break;
  432.  
  433.    default:
  434.         /* For any message for which you don't specifically provide a  */
  435.         /* service routine, you should return the message to Windows   */
  436.         /* for default message processing.                             */
  437.      return DefWindowProc(hWnd, Message, wParam, lParam);
  438.  }
  439.  return 0L;
  440. }     /* End of WndProc                                         */
  441.  
  442. /************************************************************************/
  443. /*                                                                      */
  444. /* nCwRegisterClasses Function                                          */
  445. /*                                                                      */
  446. /* The following function registers all the classes of all the windows  */
  447. /* associated with this application. The function returns an error code */
  448. /* if unsuccessful, otherwise it returns 0.                             */
  449. /*                                                                      */
  450. /************************************************************************/
  451.  
  452. int nCwRegisterClasses(void)
  453. {
  454.  WNDCLASS   wndclass;    /* struct to define a window class             */
  455.  memset(&wndclass, 0x00, sizeof(WNDCLASS));
  456.  
  457.  
  458.  /* load WNDCLASS with window's characteristics                         */
  459.  wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
  460.  wndclass.lpfnWndProc = WndProc;
  461.  /* Extra storage for Class and Window objects                          */
  462.  wndclass.cbClsExtra = 0;
  463.  wndclass.cbWndExtra = 0;
  464.  wndclass.hInstance = hInst;
  465.  wndclass.hIcon = LoadIcon(hInst, "MAPIAPP");
  466.  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  467.  /* Create brush for erasing background                                 */
  468.  wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  469.  wndclass.lpszMenuName = szAppName;   /* Menu Name is App Name */
  470.  wndclass.lpszClassName = szAppName; /* Class Name is App Name */
  471.  if(!RegisterClass(&wndclass))
  472.    return -1;
  473.  
  474.  
  475.  return(0);
  476. } /* End of nCwRegisterClasses                                          */
  477.  
  478. /************************************************************************/
  479. /*  CwUnRegisterClasses Function                                        */
  480. /*                                                                      */
  481. /*  Deletes any refrences to windows resources created for this         */
  482. /*  application, frees memory, deletes instance, handles and does       */
  483. /*  clean up prior to exiting the window                                */
  484. /*                                                                      */
  485. /************************************************************************/
  486.  
  487. void CwUnRegisterClasses(void)
  488. {
  489.  WNDCLASS   wndclass;    /* struct to define a window class             */
  490.  memset(&wndclass, 0x00, sizeof(WNDCLASS));
  491.  
  492.  UnregisterClass(szAppName, hInst);
  493. }    /* End of CwUnRegisterClasses                                      */
  494.  
  495.  
  496. //---------------------------------------------------------------------------
  497. //
  498. // FUNCTION:    GetStringRes (int id INPUT ONLY)
  499. //
  500. // COMMENTS:    Load the resource string with the ID given, and return a
  501. //              pointer to it.  Notice that the buffer is common memory so
  502. //              the string must be used before this call is made a second time.
  503. //
  504. //---------------------------------------------------------------------------
  505.  
  506. LPTSTR GetStringRes (int id)
  507. {
  508.   static TCHAR buffer[MAX_PATH];
  509.  
  510.   buffer[0]=0;
  511.   LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
  512.   return buffer;
  513. }
  514.