MAPIAPP.C
/* QuickCase:W KNB Version 1.00 */ 
#include "MAPIAPP.h" 
#include <string.h> 
#include <stdio.h> 
#include "mapi.h" 
#define MAIN 1 
#include "mapinit.h" 
 
 
HANDLE hLibrary; 
LHANDLE hMAPISession; 
 
MapiMessage mmMapiMessage; 
 
ULONG nMessageSize = 0x000004000; 
lpMapiMessage FAR *lppMessage; 
lpMapiMessage lpMessage; 
char szSeedMessageID[512]; 
char szMessageID[512]; 
char szSubject[512]; 
char szNoteText[4096]; 
 
LPSTR lpszSeedMessageID = &szSeedMessageID[0]; 
LPSTR lpszMessageID = &szMessageID[0]; 
 
LPSTR pszSubject = &szSubject[0]; 
LPSTR pszNoteText = &szNoteText[0]; 
LPSTR pszDateReceived = "1991/03/23 12:00"; 
MapiRecipDesc rdOriginator = { 0L,MAPI_ORIG,(LPSTR)"ONE",NULL}; 
 
int iFindFirst= TRUE; 
 
void InitMessage(lpMapiMessage pmmMessage) 
{ 
  pmmMessage->ulReserved = 0L; 
  pmmMessage->lpszSubject =pszSubject; 
  pmmMessage->lpszNoteText =pszNoteText; 
  pmmMessage->lpszMessageType = NULL; 
  pmmMessage->lpszDateReceived = pszDateReceived; 
  pmmMessage->flFlags = MAPI_UNREAD; 
  pmmMessage->lpOriginator = &rdOriginator; 
  pmmMessage->nRecipCount = 0L; 
  pmmMessage->lpRecips = NULL; 
  pmmMessage->nFileCount = 0L; 
  pmmMessage->lpFiles = NULL; 
} 
 
/**************************************************************************** 
 
    FUNCTION: OutOfMemory(void) 
 
    PURPOSE:  Displays warning message 
 
****************************************************************************/ 
void OutOfMemory(void) 
{ 
    MessageBox( 
        GetFocus(), 
        GetStringRes (IDS_ERR_NO_MEMORY), 
        NULL, 
        MB_ICONHAND | MB_SYSTEMMODAL); 
    return; 
} 
 
void mycpystr(char * npszStrg, LPSTR lpszStrg) 
{ 
  if (lpszStrg != NULL) 
    strcpy(npszStrg, lpszStrg); 
  else 
     *npszStrg = '\0'; 
} 
 
 
/************************************************************************/ 
/*                                                                      */ 
/* Windows 3.0 Main Program Body                                        */ 
/*                                                                      */ 
/* The following routine is the Windows Main Program.  The Main Program */ 
/* is executed when a program is selected from the Windows Control      */ 
/* Panel or File Manager.  The WinMain routine registers and creates    */ 
/* the program's main window and initializes global objects.  The       */ 
/* WinMain routine also includes the applications message dispatch      */ 
/* loop.  Every window message destined for the main window or any      */ 
/* subordinate windows is obtained, possibly translated, and            */ 
/* dispatched to a window or dialog processing function. The dispatch   */ 
/* loop is exited when a WM_QUIT message is obtained.  Before exiting   */ 
/* the WinMain routine should destroy any objects created and free      */ 
/* memory and other resources.                                          */ 
/*                                                                      */ 
/************************************************************************/ 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) 
{ 
 /***********************************************************************/ 
 /* HANDLE hInstance;       handle for this instance                    */ 
 /* HANDLE hPrevInstance;   handle for possible previous instances      */ 
 /* LPSTR  lpszCmdLine;     long pointer to exec command line           */ 
 /* int    nCmdShow;        Show code for main window display           */ 
 /***********************************************************************/ 
 
 MSG        msg;           /* MSG structure to store your messages        */ 
 int        nRc;           /* return value from Register Classes          */ 
 long       nWndunits;     /* window units for size and location          */ 
 int        nWndx;         /* the x axis multiplier                       */ 
 int        nWndy;         /* the y axis multiplier                       */ 
 int        nX;            /* the resulting starting point (x, y)         */ 
 int        nY; 
 int        nWidth;        /* the resulting width and height for this     */ 
 int        nHeight;       /* window                                      */ 
 
 strcpy(szAppName, "MAPIAPP"); 
 hInst = hInstance; 
 if(!hPrevInstance) 
   { 
    /* register window classes if first instance of application         */ 
    if ((nRc = nCwRegisterClasses()) == -1) 
      { 
       /* registering one of the windows failed                         */ 
       LoadString(hInst, IDS_ERR_REGISTER_CLASS, szString, sizeof(szString)); 
       MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION); 
       return nRc; 
      } 
   } 
 
 /* Create a device independant size and location                       */ 
 nWndunits = GetDialogBaseUnits(); 
 nWndx = LOWORD(nWndunits); 
 nWndy = HIWORD(nWndunits); 
 nX = ((60 * nWndx) / 4); 
 nY = ((60 * nWndy) / 8); 
 nWidth = ((197 * nWndx) / 4); 
 nHeight = ((138 * nWndy) / 8); 
 
 /* create application's Main window                                    */ 
 hWndMain = CreateWindow( 
                szAppName,               /* Window class name           */ 
GetStringRes (IDS_APP_TITLE),  /* Window's title        */ 
                WS_CAPTION      |        /* Title and Min/Max           */ 
                WS_SYSMENU      |        /* Add system menu box         */ 
                WS_MINIMIZEBOX  |        /* Add minimize box            */ 
                WS_MAXIMIZEBOX  |        /* Add maximize box            */ 
                WS_BORDER       |        /* thin frame                  */ 
                WS_CLIPCHILDREN |        /* don't draw in child windows areas */ 
                WS_OVERLAPPED, 
                nX, nY,                  /* X, Y                        */ 
                nWidth, nHeight,         /* Width, Height of window     */ 
                NULL,                    /* Parent window's handle      */ 
                NULL,                    /* Default to Class Menu       */ 
                hInst,                   /* Instance of window          */ 
                NULL);                   /* Create struct for WM_CREATE */ 
 
 
 if (InitMAPI() != 0) 
   return ERR_LOAD_LIB; 
 
  InitMessage(&mmMapiMessage); 
 
 if(hWndMain == NULL) 
   { 
    LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString)); 
    MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION); 
    return IDS_ERR_CREATE_WINDOW; 
   } 
 
 EnableMenuItem(GetMenu(hWndMain), IDM_A_LOGOFF, MF_DISABLED | MF_GRAYED); 
 EnableMenuItem(GetMenu(hWndMain), IDM_S_MAIL, MF_DISABLED | MF_GRAYED); 
 EnableMenuItem(GetMenu(hWndMain), IDM_S_DOCUMENT, MF_DISABLED | MF_GRAYED); 
 EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDFIRST, MF_DISABLED | MF_GRAYED); 
 EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_DISABLED | MF_GRAYED); 
 EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED); 
 EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED); 
 
 ShowWindow(hWndMain, nCmdShow);            /* display main window      */ 
 
 while(GetMessage(&msg, NULL, 0, 0))        /* Until WM_QUIT message    */ 
   { 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
   } 
 
 DeInitMAPI(); 
 /* Do clean up before exiting from the application                     */ 
 CwUnRegisterClasses(); 
 return msg.wParam; 
} /*  End of WinMain                                                    */ 
/************************************************************************/ 
/*                                                                      */ 
/* Main Window Procedure                                                */ 
/*                                                                      */ 
/* This procedure provides service routines for the Windows events      */ 
/* (messages) that Windows sends to the window, as well as the user     */ 
/* initiated events (messages) that are generated when the user selects */ 
/* the action bar and pulldown menu controls or the corresponding       */ 
/* keyboard accelerators.                                               */ 
/*                                                                      */ 
/* The SWITCH statement shown below distributes the window messages to  */ 
/* the respective message service routines, which are set apart by the  */ 
/* CASE statements. The window procedures must provide an appropriate   */ 
/* service routine for its end user initiated messages, as well as the  */ 
/* general Windows messages (ie. WM_CLOSE message). If a message is     */ 
/* sent to this procedure for which there is no programmed CASE clause  */ 
/* (i.e., no service routine), the message is defaulted to the          */ 
/* DefWindowProc function, where it is handled by Windows               */ 
/*                                                                      */ 
/* For the end-user initiated messages, this procedure is concerned     */ 
/* principally with the WM_COMMAND message. The menu control ID (or the */ 
/* corresponding accelerator ID) is communicated to this procedure in   */ 
/* the first message parameter (wParam). The window procedure provides  */ 
/* a major CASE statement for the WM_COMMAND message and a subordinate  */ 
/* SWITCH statement to provide CASE clauses for the message service     */ 
/* routines for the various menu item's, identified by their ID values. */ 
/*                                                                      */ 
/* The message service routines for the individual menu items are the   */ 
/* main work points in the program. These service routines contain the  */ 
/* units of work performed when the end user select one of the menu     */ 
/* controls. The required application response to a menu control is     */ 
/* programmed in its associated CASE clause. The service routines may   */ 
/* contain subroutine calls to separately compiled and libraried        */ 
/* routines, in-line calls to subroutines to be embodied in this source */ 
/* code module, or program statements entered directly in the CASE      */ 
/* clauses. Program control is switched to the appropriate service      */ 
/* routine when Windows recognizes the end user event and sends a WM_COMMAND */ 
/* message to the window procedure. The service routine provides the    */ 
/* appropriate application-specific response to the end user initiated  */ 
/* event, then breaks to return control to the WinMain() routine which  */ 
/* continues to service the message queue of the window(s).             */ 
/*                                                                      */ 
/************************************************************************/ 
 
LONG FAR PASCAL WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) 
{ 
 HMENU      hMenu=0;            /* handle for the menu                 */ 
 HBITMAP    hBitmap=0;          /* handle for bitmaps                  */ 
 HDC        hDC;                /* handle for the display device       */ 
 PAINTSTRUCT ps;                /* holds PAINT information             */ 
 int        nRc=0;              /* return code                         */ 
 FLAGS flFlag = 0L; 
 ULONG ulResult; 
  char szBuf[32*1024]; // Waste of stack space, but this is only a demo. 
  char szTmp[32*1024]; // Waste of stack space, but this is only a demo. 
 
 switch (Message) { 
   case WM_COMMAND: 
     /* The Windows messages for action bar and pulldown menu items */ 
     /* are processed here.                                         */ 
     /* The WM_COMMAND message contains the message ID in its first */ 
     /* parameter (wParam). This routine is programmed to SWITCH on */ 
     /* the #define values generated by CASE:W for the menu items   */ 
     /* in the application's header (*.H) file. The ID values have  */ 
     /* the format, IDM_itemname. The service routines for the      */ 
     /* various menu items follow the CASE statements up to the     */ 
     /* generated BREAK statements.                                 */ 
     switch (LOWORD(wParam)) { 
       case IDM_A_LOGON: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "Log&In" here.                      */ 
         flFlag =MAPI_NEW_SESSION | MAPI_LOGON_UI; 
         ulResult = (*lpfnMAPILogon)(hWnd, NULL, NULL, flFlag, 0L, (LPLHANDLE)&hMAPISession); 
         if (ulResult == 0L) { 
           EnableMenuItem(GetMenu(hWndMain), IDM_A_LOGOFF, MF_ENABLED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_S_MAIL, MF_ENABLED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_S_DOCUMENT, MF_ENABLED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDFIRST, MF_ENABLED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_ENABLED); 
         } 
       break; 
 
       case IDM_A_LOGOFF: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "Log&Off" here.                     */ 
         ulResult = (*lpfnMAPILogoff)(hMAPISession, hWnd, 0L, 0L); 
         if (ulResult == 0L) { 
            EnableMenuItem(GetMenu(hWndMain), IDM_A_LOGOFF, MF_DISABLED | MF_GRAYED); 
             EnableMenuItem(GetMenu(hWndMain), IDM_S_MAIL, MF_DISABLED | MF_GRAYED); 
             EnableMenuItem(GetMenu(hWndMain), IDM_S_DOCUMENT, MF_DISABLED | MF_GRAYED); 
             EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDFIRST, MF_DISABLED | MF_GRAYED); 
             EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_DISABLED | MF_GRAYED); 
             EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED); 
             EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED); 
         } 
       break; 
 
       case IDM_S_MAIL: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "&Mail" here.                       */ 
          flFlag =MAPI_DIALOG; 
         ulResult = (*lpfnMAPISendMail)(hMAPISession, hWnd, &mmMapiMessage, flFlag, 0L); 
       break; 
 
       case IDM_S_DOCUMENT: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "&Document" here.                   */ 
         ulResult = (*lpfnMAPISendDocuments)(hWnd, ";", "C:\\CONFIG.SYS", "CONFIG.SYS", 0L); 
       break; 
 
       case IDM_M_FINDFIRST: 
           iFindFirst=TRUE; 
       case IDM_M_FINDNEXT: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "&Find Next" here.                  */ 
         if (iFindFirst) { 
           *lpszSeedMessageID = '\0'; 
           iFindFirst = FALSE; 
         } 
         else { 
           strcpy(lpszSeedMessageID,lpszMessageID); 
         } 
         ulResult = (*lpfnMAPIFindNext)(hMAPISession, hWnd, NULL, lpszSeedMessageID, flFlag, 0L, lpszMessageID); 
         if (ulResult == 0L) { 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_ENABLED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_ENABLED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_ENABLED); 
         } 
         else { 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_FINDNEXT, MF_DISABLED | MF_GRAYED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED); 
         } 
       break; 
 
       case IDM_M_READ: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "&Read" here.                       */ 
 
           lppMessage= (lpMapiMessage FAR *) &lpMessage; 
           ulResult = (*lpfnMAPIReadMail)(hMAPISession, hWnd, lpszMessageID, flFlag, 0L, lppMessage); 
           if (ulResult == 0L) { 
             mycpystr(szTmp,lpMessage->lpOriginator->lpszName); 
 sprintf(szBuf, GetStringRes(IDS_FROM), szTmp); 
             mycpystr(szTmp,lpMessage->lpRecips[0].lpszName); 
             sprintf(szBuf, GetStringRes(IDS_TO), szBuf,szTmp); 
             mycpystr(szTmp,lpMessage->lpszDateReceived); 
             sprintf(szBuf, GetStringRes(IDS_DATE), szBuf,szTmp); 
             mycpystr(szTmp,lpMessage->lpszSubject); 
 sprintf(szBuf, GetStringRes(IDS_SUBJECT), szBuf,szTmp); 
 mycpystr(szTmp,lpMessage->lpszNoteText); 
 sprintf(szBuf,"%s%s",szBuf,szTmp); 
              
 MessageBox(hWnd,szBuf, GetStringRes(IDS_MESSAGE), MB_OK); 
             ulResult = lpfnMAPIFreeBuffer((LPVOID)lpMessage); 
           } 
       break; 
 
       case IDM_M_DELETE: 
            /* Place User Code to respond to the                   */ 
            /* Menu Item Named "&Delete" here.                  */ 
 
         ulResult = (*lpfnMAPIDeleteMail)(hMAPISession, hWnd, lpszMessageID, flFlag, 0l); 
         if (ulResult == 0L) { 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_READ, MF_DISABLED | MF_GRAYED); 
           EnableMenuItem(GetMenu(hWndMain), IDM_M_DELETE, MF_DISABLED | MF_GRAYED); 
         } 
       break; 
 
       default: 
         return DefWindowProc(hWnd, Message, wParam, lParam); 
     } 
     if (ulResult != 0L) {       /** oops **/ 
 
       sprintf(szBuf, GetStringRes(IDS_RETURNED_ERROR), ulResult); 
       MessageBox(hWnd,szBuf, GetStringRes(IDS_FAILED),MB_OK); 
     } 
     else { 
       sprintf(szBuf, GetStringRes(IDS_GOOD_JOB)); 
       MessageBox(hWnd,szBuf, GetStringRes(IDS_SUCCESS), MB_OK); 
     } 
   break;        /* End of WM_COMMAND                             */ 
 
   case WM_CREATE: 
     /* The WM_CREATE message is sent once to a window when the     */ 
     /* window is created.  The window procedure for the new window */ 
     /* receives this message after the window is created, but      */ 
     /* before the window becomes visible.                          */ 
     /*                                                             */ 
     /* Parameters:                                                 */ 
     /*                                                             */ 
     /*    lParam  -  Points to a CREATESTRUCT structure with       */ 
     /*               the following form:                           */ 
     /*                                                             */ 
     /*    typedef struct                                           */ 
     /*              {                                              */ 
     /*               LPSTR     lpCreateParams;                     */ 
     /*               HANDLE    hInst;                              */ 
     /*               HANDLE    hMenu;                              */ 
     /*               HWND      hwndParent;                         */ 
     /*               int       cy;                                 */ 
     /*               int       cx;                                 */ 
     /*               int       y;                                  */ 
     /*               int       x;                                  */ 
     /*               LONG      style;                              */ 
     /*               LPSTR     lpszName;                           */ 
     /*               LPSTR     lpszClass;                          */ 
     /*               DWORD     dwExStyle;                          */ 
     /*              }  CREATESTRUCT;                               */ 
 
 
 
   break;       /*  End of WM_CREATE                              */ 
 
   case WM_MOVE:     /*  code for moving the window                    */ 
   break; 
 
   case WM_SIZE:     /*  code for sizing client area                   */ 
        /* wParam contains a code indicating the requested sizing      */ 
        /* lParam contains the new height and width of the client area */ 
   break;       /* End of WM_SIZE                                 */ 
 
   case WM_PAINT:    /* code for the window's client area              */ 
     /* Obtain a handle to the device context                       */ 
     /* BeginPaint will sends WM_ERASEBKGND if appropriate          */ 
     memset(&ps, 0x00, sizeof(PAINTSTRUCT)); 
     hDC = BeginPaint(hWnd, &ps); 
 
     /* Included in case the background is not a pure color         */ 
     SetBkMode(hDC, TRANSPARENT); 
 
     /* Application should draw on the client window using          */ 
     /* the GDI graphics and text functions.  'ps' the PAINTSTRUCT  */ 
     /* returned by BeginPaint contains a rectangle to the          */ 
     /* area that must be repainted.                                */ 
 
     /* Inform Windows painting is complete                         */ 
     EndPaint(hWnd, &ps); 
   break;       /*  End of WM_PAINT                               */ 
 
   case WM_CLOSE:  /* close the window                                 */ 
     /* Destroy child windows, modeless dialogs, then, this window  */ 
     DestroyWindow(hWnd); 
     if (hWnd == hWndMain) 
       PostQuitMessage(0);  /* Quit the application                 */ 
   break; 
 
   default: 
        /* For any message for which you don't specifically provide a  */ 
        /* service routine, you should return the message to Windows   */ 
        /* for default message processing.                             */ 
     return DefWindowProc(hWnd, Message, wParam, lParam); 
 } 
 return 0L; 
}     /* End of WndProc                                         */ 
 
/************************************************************************/ 
/*                                                                      */ 
/* nCwRegisterClasses Function                                          */ 
/*                                                                      */ 
/* The following function registers all the classes of all the windows  */ 
/* associated with this application. The function returns an error code */ 
/* if unsuccessful, otherwise it returns 0.                             */ 
/*                                                                      */ 
/************************************************************************/ 
 
int nCwRegisterClasses(void) 
{ 
 WNDCLASS   wndclass;    /* struct to define a window class             */ 
 memset(&wndclass, 0x00, sizeof(WNDCLASS)); 
 
 
 /* load WNDCLASS with window's characteristics                         */ 
 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW; 
 wndclass.lpfnWndProc = WndProc; 
 /* Extra storage for Class and Window objects                          */ 
 wndclass.cbClsExtra = 0; 
 wndclass.cbWndExtra = 0; 
 wndclass.hInstance = hInst; 
 wndclass.hIcon = LoadIcon(hInst, "MAPIAPP"); 
 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 
 /* Create brush for erasing background                                 */ 
 wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
 wndclass.lpszMenuName = szAppName;   /* Menu Name is App Name */ 
 wndclass.lpszClassName = szAppName; /* Class Name is App Name */ 
 if(!RegisterClass(&wndclass)) 
   return -1; 
 
 
 return(0); 
} /* End of nCwRegisterClasses                                          */ 
 
/************************************************************************/ 
/*  CwUnRegisterClasses Function                                        */ 
/*                                                                      */ 
/*  Deletes any refrences to windows resources created for this         */ 
/*  application, frees memory, deletes instance, handles and does       */ 
/*  clean up prior to exiting the window                                */ 
/*                                                                      */ 
/************************************************************************/ 
 
void CwUnRegisterClasses(void) 
{ 
 WNDCLASS   wndclass;    /* struct to define a window class             */ 
 memset(&wndclass, 0x00, sizeof(WNDCLASS)); 
 
 UnregisterClass(szAppName, hInst); 
}    /* End of CwUnRegisterClasses                                      */ 
 
 
//--------------------------------------------------------------------------- 
// 
// FUNCTION:    GetStringRes (int id INPUT ONLY) 
// 
// COMMENTS:    Load the resource string with the ID given, and return a 
//              pointer to it.  Notice that the buffer is common memory so 
//              the string must be used before this call is made a second time. 
// 
//--------------------------------------------------------------------------- 
 
LPTSTR GetStringRes (int id) 
{ 
  static TCHAR buffer[MAX_PATH]; 
 
  buffer[0]=0; 
  LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH); 
  return buffer; 
}