/* 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(),
        "Out of 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           */
                "MAPI Sample App",       /* 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,"From: %s\n",szTmp);
             mycpystr(szTmp,lpMessage->lpRecips[0].lpszName);
             sprintf(szBuf,"%sTo: %s\n",szBuf,szTmp);
             mycpystr(szTmp,lpMessage->lpszDateReceived);
             sprintf(szBuf,"%sDate: %s\n",szBuf,szTmp);
             mycpystr(szTmp,lpMessage->lpszSubject);
             sprintf(szBuf,"%sSubject: %s\n\n",szBuf,szTmp);
             mycpystr(szTmp,lpMessage->lpszNoteText);
             sprintf(szBuf,"%s%s",szBuf,szTmp);

             MessageBox(hWnd,szBuf,"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,"Error Returned = %lu",ulResult);
       MessageBox(hWnd,szBuf,"FAILED",MB_OK);
     }
     else {
       sprintf(szBuf,"Good Job");
       MessageBox(hWnd,szBuf,"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                                      */
