/*
 * dialogs.c
 *
 * Contains all the dialog procedures for WinCap Windows Screen Capture
 * Program, as well as a few useful miscellaneous functions.
 *
 * Dialog Functions:
 *
 * AboutDlgProc()         // About Box
 * OptionsDlgProc()       // Options Dialog
 * InfoBoxDlgProc()       // InfoBox, which displays as the program first
 *                        // starts up
 * SavingDlgProc()        // Dialog which displays "Saving to file..."
 * HelpDlgProc()          // Help Dialog
 *
 * Other Functions:
 *
 * StretchIconToWindow()  // Stretches Specified icon to fill up entire window.
 *                        // This function is used in the "About" Box
 * cwCenter()             // Centers a window on the display
 * DrawIndent()           // Draws 3-D shadows for controls in dialog boxes
 *
 * Development Team: Mark Bader
 *                   Patrick Schreiber
 *                   Garrett McAuliffe
 *                   Eric Flo
 *                   Tony Claflin
 *
 * Written by Microsoft Product Support Services, Developer Support.
 * Copyright (c) 1991 Microsoft Corporation. All rights reserved.
 */
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include "WINCAP.h"
#include "DIALOGS.h"
#include "dibapi.h"

// VERSION is used in About dialog box
#define VERSION "Version 3.00"

/* Global variables which are set in main program */
extern char szAppName[20];  /* Name of app */
extern HWND ghInst;         /* Handle to instance */
extern HWND ghWndMain;      /* Handle to main window */

/***********************************************************************
 *
 *"About" Dialog Box Window Procedure
 *
 * Notable features:  This dialog box draws the application's icon
 * in the dialog box itself. The icon is actually stretched larger to
 * fit in the specified area, which must be done manually.
 * See WM_PAINT case.
 *
 ************************************************************************/


BOOL FAR PASCAL AboutDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
                             lParam)
{
   switch (Message)
      {
   case WM_INITDIALOG:
      cwCenter(hWndDlg, 0);       // Center the dialog on the screen

      // Set the version number (makes it easy to change)
      SendDlgItemMessage(hWndDlg, IDC_VERSION, WM_SETTEXT, 0, (LONG)(LPSTR)
                         VERSION);

      // Set focus on the OK button.  Since we set focus, return FALSE
      SetFocus(GetDlgItem(hWndDlg, IDOK));
      return FALSE;

   case WM_CLOSE:
      /* Closing the Dialog behaves the same as Cancel               */
      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
      break;

   case WM_COMMAND:
      switch (wParam)
         {
      case IDC_HELP:
      {
         FARPROC lpfnDIALOGSMsgProc;

         lpfnDIALOGSMsgProc = MakeProcInstance((FARPROC)HelpDlgProc, ghInst);
         DialogBox(ghInst, (LPSTR)"Help", hWndDlg, lpfnDIALOGSMsgProc);
         FreeProcInstance(lpfnDIALOGSMsgProc);
      }
         break;

      case IDOK:
      case IDCANCEL:
         EndDialog(hWndDlg, FALSE);
         break;
         }
      break;    /* End of WM_COMMAND                                 */

   case WM_PAINT:
   // This procedure must process paint messages. However, Windows
   // must do standard painting *first*. Otherwise, it would be
   // necessary to do standard painting manually or the application's
   // painting would be overwritten. To implement this, post an
   // application defined message and return FALSE to allow Windows
   // to paint the dialog.
      PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
      return FALSE;

   case WM_REPAINT:
   // This is the message posted in the WM_PAINT case above. At this
   // point, standard dialog box painting is complete and the
   // application can perform its custom painting.
   // Call function which stretches icon to fit in window.  The window
   // we want to use is the control specified by IDC_ICONAREA.  The icon
   // to use is "WINCAP", which is one of the app's resources.  Also,
   // draw the cool 3-D effects around the IDC_ICONAREA control.
      StretchIconToWindow(GetDlgItem(hWndDlg, IDC_ICONAREA), "WINCAP");
      DrawIndent(hWndDlg, IDC_ICONAREA, 2); // 2 -- special flag
      break;

   default:
      return FALSE;
      }
   return TRUE;
} /* End of DIALOGSMsgProc                                      */


/************************************************************************
 *
 * "Options" Dialog Box Window Procedure
 *
 * This procedure takes care of the processing for the "Options" dialog
 * box, where the user selects which portion of the screen to capture.
 *
 * Notable features: This dialog box is "expanding" -- meaning that
 * the user sees it as a certain size, and can press the "Options>>" key
 * which causes the dialog box to get larger.
 *
 * Also, this Dialog Box Procedure is called using DialogBoxParam.  This
 * allows us to pass a parameter into the dialog box procedure -- the
 * parameter that gets passed in here is a handle to a structure holding
 * all the options that the user specified in this dialog box.  This
 * allows passing the options back to the main program WITHOUT using
 * global variables.
 *
 ************************************************************************/


BOOL FAR PASCAL OptionsDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
                               lParam)
{
   static int iWidth, iHeight;     // Original Height & Width of Dialog -- used
   // when growing dialog back to original size
   static BOOL bIsLarge = TRUE;    // True if Dialog is full-size
   static WORD wChecked;           // Button checked under "Single Window"
   static HANDLE hOptionStruct;    // Handle to OPTIONSTRUCT, used to return data

   switch (Message)
      {
   case WM_INITDIALOG:
   {
      RECT rDialog;                   // Used to calculate dialog box shrinking
      int iShrinkAmount;              // amount to shrink dialog box by
      LPOPTIONSTRUCT lpOptionStruct;  // Pointer to options
      char buffer[30];                // used in itoa conversion
      RECT rDividingLine;             // Location of Dividing Line, which is
                                      // used to shrink dialog box

      // Because DialogBoxParam() was used to invoke this dialog box,
      // lParam contains a handle to the OPTIONSTRUCT, which contains the
      // defualt values. Place user input in this structure before returning.

      hOptionStruct = (HANDLE)LOWORD(lParam);
      cwCenter(hWndDlg, 0);                   // Center dialog on screen

      /*
       * Shrink the window so the options do not appear - to do this,
       * just call MoveWindow() with a smaller height.
       */
      GetWindowRect(hWndDlg, &rDialog);        // Get window rect in screen coords
      iWidth = rDialog.right - rDialog.left;  // Calculate original Width & Height
      iHeight = rDialog.bottom - rDialog.top;

      // Find position of IDC_DIVIDINGLINE in dialog, and shrink up to
      // this control.  The reason we do this instead of making the iShrinkAmount
      // a hard-coded value is that the dialog box may be different sizes
      // depending on the display driver.
      GetWindowRect(GetDlgItem(hWndDlg, IDC_DIVIDINGLINE), &rDividingLine);
      iShrinkAmount = rDialog.bottom - rDividingLine.bottom;

      // Shrink dialog box - last parameter is TRUE so dialog is redrawn
      MoveWindow(hWndDlg, rDialog.left, rDialog.top, iWidth, iHeight -
                 iShrinkAmount, TRUE);
      bIsLarge = FALSE;                       // We aren't large any more

      /****************************************************************
       * Use the default options contained in the OPTIONSTRUCT to check
       * and enable the corresponding windows, check boxes and buttons
       ****************************************************************/
      lpOptionStruct = (LPOPTIONSTRUCT)GlobalLock(hOptionStruct);
      if (lpOptionStruct)
      {
      // Send messages which set the correct options from
      // the default options listed in the lpOptionStruct.
         SendMessage(hWndDlg, WM_COMMAND, lpOptionStruct->iOptionWindow, 0L);
         SendMessage(hWndDlg, WM_COMMAND, lpOptionStruct->iOptionArea, 0L);
         wChecked = lpOptionStruct->iOptionWindow;
         SendMessage(hWndDlg, WM_COMMAND, lpOptionStruct->iOptionPrint, 0L);
         if (IsDlgButtonChecked(hWndDlg, IDC_SCALE))
         {
            SetDlgItemText(hWndDlg, IDC_XAXIS, (LPSTR)itoa(lpOptionStruct->
                           iXScale, buffer, 10));
            SetDlgItemText(hWndDlg, IDC_YAXIS, (LPSTR)itoa(lpOptionStruct->
                           iYScale, buffer, 10));
         }

         // Set the text into the filename edit control
         SetDlgItemText(hWndDlg, IDC_FILETEXT, (LPSTR)lpOptionStruct->
                        szFileName);

         // Check/Uncheck and disable/enable the File and Printer
         // check boxes
         CheckDlgButton(hWndDlg, IDC_FILE, (lpOptionStruct->iOptionDest) &
                        OPTION_FILE);
         EnableWindow(GetDlgItem(hWndDlg, IDC_FILETEXT), (lpOptionStruct->
                      iOptionDest) & OPTION_FILE);
         CheckDlgButton(hWndDlg, IDC_PRINTER, (lpOptionStruct->iOptionDest) &
                        OPTION_PRINTER);
         EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), (lpOptionStruct
                      ->iOptionDest) & OPTION_PRINTER);
         GlobalUnlock(hOptionStruct);
      }
   }
      break; /* End of WM_INITDIALOG                                 */

   case WM_CLOSE:
      /* Closing the Dialog should behave the same as Cancel          */
      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
      break;

   case WM_COMMAND:
      switch (wParam)
         {
      // If user checks any of the buttons in a group, make sure
      // that the other buttons in the group get unchecked
      case IDC_SINGLEWINDOW: /* Radiobutton text: "Single Window"    */
         CheckRadioButton(hWndDlg, IDC_SINGLEWINDOW, IDC_PARTIALSCREEN,
                          IDC_SINGLEWINDOW);

      // Enable the options which are applicable to this case --
      // the IDC_ENTIRESCREEN and the IDC_PARTIALSCREEN options
      // might have these disabled...
         EnableWindow(GetDlgItem(hWndDlg, IDC_ENTIREWINDOW), TRUE);
         EnableWindow(GetDlgItem(hWndDlg, IDC_CLIENTAREAONLY), TRUE);
         CheckRadioButton(hWndDlg, IDC_ENTIREWINDOW, IDC_CLIENTAREAONLY,
                          wChecked);
         break;

      case IDC_ENTIRESCREEN: /* Radiobutton text: "Entire Screen"    */
      case IDC_PARTIALSCREEN: /* Radiobutton text: "Rubber Band Portion"*/
         CheckRadioButton(hWndDlg, IDC_SINGLEWINDOW, IDC_PARTIALSCREEN, wParam
                          );

      // Now, disable the options that are only applicable to
      // the IDC_SINGLEWINDOW case
         EnableWindow(GetDlgItem(hWndDlg, IDC_ENTIREWINDOW), FALSE);
         EnableWindow(GetDlgItem(hWndDlg, IDC_CLIENTAREAONLY), FALSE);
         CheckDlgButton(hWndDlg, IDC_ENTIREWINDOW, FALSE);
         CheckDlgButton(hWndDlg, IDC_CLIENTAREAONLY, FALSE);
         break;

      case IDC_ENTIREWINDOW: /* Radiobutton text: "Entire Window"    */
      case IDC_CLIENTAREAONLY: /* Radiobutton text: "Client Area Only"*/
         CheckRadioButton(hWndDlg, IDC_ENTIREWINDOW, IDC_CLIENTAREAONLY,
                          wParam);
         wChecked = wParam;
         break;

      case IDC_BESTFIT:
      case IDC_STRETCHTOPAGE:
      case IDC_SCALE:
         // Check the correct button
         CheckRadioButton(hWndDlg, IDC_BESTFIT, IDC_SCALE, wParam);

         // And enable or disable the options under "Scale",
         // depending on whether or not the IDC_SCALE button is checked
         EnableWindow(GetDlgItem(hWndDlg, IDC_XAXIS), (BOOL)(wParam ==
                      IDC_SCALE));
         EnableWindow(GetDlgItem(hWndDlg, IDC_YAXIS), (BOOL)(wParam ==
                      IDC_SCALE));
         EnableWindow(GetDlgItem(hWndDlg, IDC_XTEXT), (BOOL)(wParam ==
                      IDC_SCALE));
         EnableWindow(GetDlgItem(hWndDlg, IDC_YTEXT), (BOOL)(wParam ==
                      IDC_SCALE));
         break;

      case IDC_FILE:      /* Check box "Save To File" */
         // Determine if the File Text edit control should be enabled or not
         EnableWindow(GetDlgItem(hWndDlg, IDC_FILETEXT), IsDlgButtonChecked(
                      hWndDlg, IDC_FILE));
         break;

      case IDC_PRINTER:   /* Check box "Send to Printer" */
      // Determine if the 'Options>>' button should be enabled --
      // enable it if the "Printer" checkbox is checked AND
      // dialog box has not been grown
         EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), (
                      IsDlgButtonChecked(hWndDlg, IDC_PRINTER) && !bIsLarge));
         break;

      case IDOK:  /* button "OK" */
      {
         LPOPTIONSTRUCT lpOptionStruct;
         int iDest;
         char szTmp[100];

         // Save the user's selection into the OPTIONSTRUCT

         if (!hOptionStruct)
         {
            EndDialog(hWndDlg, FALSE);
            break;
         }
         lpOptionStruct = (LPOPTIONSTRUCT)GlobalLock(hOptionStruct);
         if (!lpOptionStruct)
         {
            EndDialog(hWndDlg, FALSE);
            break;
         }
         if (IsDlgButtonChecked(hWndDlg, IDC_SINGLEWINDOW))
            lpOptionStruct->iOptionArea = IDC_SINGLEWINDOW;
         if (IsDlgButtonChecked(hWndDlg, IDC_ENTIRESCREEN))
            lpOptionStruct->iOptionArea = IDC_ENTIRESCREEN;
         if (IsDlgButtonChecked(hWndDlg, IDC_PARTIALSCREEN))
            lpOptionStruct->iOptionArea = IDC_PARTIALSCREEN;
         if (IsDlgButtonChecked(hWndDlg, IDC_ENTIREWINDOW))
            lpOptionStruct->iOptionWindow = IDC_ENTIREWINDOW;
         if (IsDlgButtonChecked(hWndDlg, IDC_CLIENTAREAONLY))
            lpOptionStruct->iOptionWindow = IDC_CLIENTAREAONLY;
         if (IsDlgButtonChecked(hWndDlg, IDC_BESTFIT))
            lpOptionStruct->iOptionPrint = IDC_BESTFIT;
         if (IsDlgButtonChecked(hWndDlg, IDC_STRETCHTOPAGE))
            lpOptionStruct->iOptionPrint = IDC_STRETCHTOPAGE;
         if (IsDlgButtonChecked(hWndDlg, IDC_SCALE))
            lpOptionStruct->iOptionPrint = IDC_SCALE;
         GetDlgItemText(hWndDlg, IDC_FILETEXT, (LPSTR)lpOptionStruct->
                        szFileName, 100);
         iDest = 0;
         if (IsDlgButtonChecked(hWndDlg, IDC_FILE))
            iDest |= OPTION_FILE;
         if (IsDlgButtonChecked(hWndDlg, IDC_PRINTER))
            iDest |= OPTION_PRINTER;
         lpOptionStruct->iOptionDest = iDest;
         if (GetDlgItemText(hWndDlg, IDC_XAXIS, (LPSTR)szTmp, 100))
            lpOptionStruct->iXScale = atoi(szTmp);
         if (GetDlgItemText(hWndDlg, IDC_YAXIS, (LPSTR)szTmp, 100))
            lpOptionStruct->iYScale = atoi(szTmp);
         GlobalUnlock(hOptionStruct);
         EndDialog(hWndDlg, TRUE);
      }
         break;

      case IDCANCEL:
      /* Ignore data values entered into the controls        */
      /* and dismiss the dialog window returning FALSE       */
         EndDialog(hWndDlg, FALSE);
         break;

      case IDC_HELP: /* Button text: "Help"                       */
      {
         FARPROC lpfnDIALOGSMsgProc;

         lpfnDIALOGSMsgProc = MakeProcInstance((FARPROC)HelpDlgProc, ghInst);
         DialogBox(ghInst, (LPSTR)"Help", hWndDlg, lpfnDIALOGSMsgProc);
         FreeProcInstance(lpfnDIALOGSMsgProc);
      }
         break;

      case IDC_OPTIONSBUTTON: /* Button text: "Options >>"        */
      // Make the window bigger to expose the hidden portion
      // of the dialog.
         if (!bIsLarge)  // Only do it if we aren't already large
         {
            RECT rDialog;

            GetWindowRect(hWndDlg, &rDialog);    // Get window rect in screen coords

            // Grow the dialog box - iWidth & iHeight are the original
            // height & width of the dialog.
            MoveWindow(hWndDlg, rDialog.left, rDialog.top, iWidth, iHeight,
                       TRUE);
            bIsLarge = TRUE;
         }

         // Disable button
         EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), FALSE);
         break;

      case IDC_FOLD: /* Button Text: "<< Fold" */
         // Fold the dialog box into a smaller version
         if (bIsLarge)
         {
            RECT rDialog;
            RECT rDividingLine;
            int iShrinkAmount;

            GetWindowRect(hWndDlg, &rDialog);        // Get window rect in screen coords

            // Find position of IDC_DIVIDINGLINE in dialog, and shrink up to
            // this control.  The reason we do this instead of making the iShrinkAmount
            // a hard-coded value is that our dialog box may be different sizes
            // depending on the display driver.
            GetWindowRect(GetDlgItem(hWndDlg, IDC_DIVIDINGLINE), &
                          rDividingLine);
            iShrinkAmount = rDialog.bottom - rDividingLine.bottom;

            // Shrink dialog box - last parameter is TRUE so dialog is redrawn
            MoveWindow(hWndDlg, rDialog.left, rDialog.top, iWidth, iHeight -
                       iShrinkAmount, TRUE);
            bIsLarge = FALSE;                       // We aren't large any more
         }

         // Enable "Options" button
         EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), TRUE);
         break;
         }
      break;    /* End of WM_COMMAND                                 */

   case WM_PAINT:
      PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
      return FALSE;

   case WM_REPAINT:
      DrawIndent(hWndDlg, IDC_BOX1, 1);   // 1 is for groupbox control
      DrawIndent(hWndDlg, IDC_BOX2, 1);
      DrawIndent(hWndDlg, IDC_BOX3, 1);
      DrawIndent(hWndDlg, IDC_BOX4, 1);
      break;

   default:
      return FALSE;
      }
   return TRUE;
} /* End of DIALOGSMsgProc                                      */



/***********************************************************************
 *
 * "Info Box" Dialog Window Procedure
 *
 * This procedure displays the dialog box which appears when the program
 * is first loaded.  It will go away after a few seconds if the user does
 * not hit escape or enter or click on the OK box first.
 *
 * Notable features: our application icon is stretched to fill up one of
 * the controls in this dialog box.
 *
 ************************************************************************/


BOOL FAR PASCAL InfoBoxDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
                               lParam)
{
   static int nTimerID = 22;       // ID for our timer - any number will do
   static int nTimerLength = 5000; // Length of timer in milliseconds

   switch (Message)
      {
   case WM_INITDIALOG:
   {
      cwCenter(hWndDlg, 0);   // Center dialog on screen

      // Set timer.  This will cause a WM_TIMER message to be sent to this
      // dialog procedure in nTimerLength milliseconds.
      SetTimer(hWndDlg, nTimerID, nTimerLength, NULL);
   }
      break; /* End of WM_INITDIALOG                                 */

   case WM_TIMER:
   // We got the timer message, so the time must have expired.  Make the
   // dialog go away by simulating the user pressing the OK button.
      PostMessage(hWndDlg, WM_COMMAND, IDOK, 0L);
      break;

   case WM_CLOSE:
      /* Closing the Dialog behaves the same as Cancel               */
      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
      break; /* End of WM_CLOSE                                      */

   case WM_PAINT:
      // See comments in AboutBoxProc() code above
      PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
      return FALSE;

   case WM_REPAINT:
      // See comments in AboutBoxProc() code above
      StretchIconToWindow(GetDlgItem(hWndDlg, IDC_ICONAREA), "WINCAP");
      DrawIndent(hWndDlg, IDC_ICONAREA, 2); // 2 -- special flag
      break;

   case WM_COMMAND:
      switch (wParam)
         {
      case IDOK:
      case IDCANCEL:
         KillTimer(hWndDlg, nTimerID);    // Stop timer
         EndDialog(hWndDlg, TRUE);
         break;
         }
      break;    /* End of WM_COMMAND                                 */

   default:
      return FALSE;
      }
   return TRUE;
} /* End of DIALOGSMsgProc                                      */


/************************************************************************
 *
 * "Saving file to..." Dialog Box Window Procedure
 *
 * This is a modeless dialog box which is called when we save the bitmap
 * to a file (so the user dosen't think his machine has hung).
 *
 ************************************************************************/


BOOL FAR PASCAL SavingDlgProc(HWND hDlg, WORD message, WORD wParam, LONG
                              lParam)
{
   switch (message)
      {
   case WM_SETFOCUS:
      MessageBeep(0);
      break;

   case WM_INITDIALOG:
      cwCenter(hDlg, 0);  // Center dialog on screen
      SetDlgItemText(hDlg, IDC_FILETEXT, (LPSTR)lParam);
      return TRUE;
      break;

   case WM_DESTROY:
      return TRUE;
      break;

   default:
      return FALSE;
      }
}



/***********************************************************************
 *
 * "Help" Button Dialog Window Procedure
 *
 * This procedure displays the dialog box which appears when the user
 * presses the "Help" button in either the About box, or the Options box.
 *
 ************************************************************************/


BOOL FAR PASCAL HelpDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
                            lParam)
{
   static HFONT hDlgFont1, hDlgFont2;
   static LOGFONT lFont;

   switch (Message)
      {
   case WM_INITDIALOG:
      cwCenter(hWndDlg, 0);   // Center dialog on screen

   // Set font of IDC_TITLE1 to a big Helv.  This procedure is explained
   // in Microsoft KnowledgeBase article "Changing the Font Used by
   // Dialog Controls in Windows"
      lFont.lfHeight = 30;
      lFont.lfWidth = 0;
      lFont.lfEscapement = 0;
      lFont.lfOrientation = 0;
      lFont.lfWeight = 700; // bold font weight
      lFont.lfItalic = 0;
      lFont.lfUnderline = 0;
      lFont.lfStrikeOut = 0;
      lFont.lfCharSet = ANSI_CHARSET;
      lFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
      lFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
      lFont.lfQuality = PROOF_QUALITY;
      lstrcpy((LPSTR)lFont.lfFaceName, (LPSTR)"");
      lFont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
      hDlgFont1 = CreateFontIndirect(&lFont);

      // Send WM_SETFONT message to desired control
      SendDlgItemMessage(hWndDlg, IDC_TITLE1, WM_SETFONT, hDlgFont1, (DWORD)
                         TRUE);
      lFont.lfItalic = TRUE;  // Make font italic
      lFont.lfHeight = 20;    // 20 pixels high
      lFont.lfWeight = 400;   // Non-bold
      hDlgFont2 = CreateFontIndirect(&lFont);

      // Send WM_SETFONT message to desired control
      SendDlgItemMessage(hWndDlg, IDC_TITLE2, WM_SETFONT, hDlgFont2, (DWORD)
                         TRUE);
      SetFocus(GetDlgItem(hWndDlg, IDOK));
      return TRUE;
      break;

   case WM_CLOSE:
      /* Closing the Dialog behaves the same as Cancel               */
      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
      break; /* End of WM_CLOSE                                      */

   case WM_PAINT:
      PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
      return FALSE;

   case WM_REPAINT:
      DrawIndent(hWndDlg, IDC_BOX1, 1);
      break;

   case WM_COMMAND:
      switch (wParam)
         {
      case IDOK:

      case IDCANCEL:
         DeleteObject(hDlgFont1);
         DeleteObject(hDlgFont2);
         EndDialog(hWndDlg, TRUE);
         break;
         }
      break;    /* End of WM_COMMAND                                 */

   default:
      return FALSE;
      }
   return TRUE;
} /* End of DIALOGSMsgProc                                      */



/************************************************************************
 *
 * StretchIconToWindow()
 *
 * Draws the specified icon on the specified window, filling up the entire
 * window's client area.  The icon must be one of the application's
 * resources.
 *
 ************************************************************************/


void StretchIconToWindow(HWND hWndDlg,      // window to paint to 
                         LPSTR szIconName)  // name of ICON RESOURCE (not icon file!)
{
   HDC hDC, hMemDC;        // hDC is DC to window, hMemDC is DC to draw icon on
   HICON hIcon;            // Handle to the loaded icon
   RECT rRect;             // RECT of the window's client area coordinates
   HBITMAP hBitmap,        // Handle to bitmap for hMemDC
           hOldBitmap;     // Old Bitmap in hMemDC
   BOOL bReturn;           // To Check return value from StretchBlt
   HBRUSH hOldBrush;       // Handle to old brush in hMemDC
   HBRUSH hBkgdBrush;      // Brush to paint background

   hDC = GetDC(hWndDlg);     // Get DC to window
   GetClientRect(hWndDlg, (LPRECT)&rRect); // Get size

   // Load the icon
   hIcon = LoadIcon(ghInst, szIconName);
   if (!hIcon)
      return;

   // To stretch the icon to the size of the Window specified, we do this:
   // 1. Create a Memory DC (compatible with the window we are drawing to)
   // 2. Create a compatible bitmap and select it into the Memory DC
   // 3. Draw our icon on the Memory DC
   // 4. StretchBlt it into our destination window
   hMemDC = CreateCompatibleDC(hDC);
   hBitmap = CreateCompatibleBitmap(hDC, 64, 64);  // make it big enough to hold icon

   // Select the new bitmap into the DC, then paint the background gray.  This
   // is done so that any transparent part of the icon will show through as
   // gray.
   hOldBitmap = SelectObject(hMemDC, hBitmap);
   hBkgdBrush = CreateSolidBrush(RGB(255,255,255));
   hOldBrush = SelectObject(hMemDC, hBkgdBrush);

   // Draw rectangle with offset of (-1,-1) for upper left corner - this is
   // to make sure we cover the entire client area of the window
   Rectangle(hMemDC, rRect.left - 1, rRect.top - 1, rRect.right, rRect.bottom)
   ;

   //Draw the icon on the memory DC
   DrawIcon(hMemDC, 0, 0, hIcon);

   // StretchBlt the icon to fill up the complete destination window.  Note
   // that this is hard-coded for 32x32 icons, which is valid for EGA,VGA and
   // 8514 resolutions for Windows 3.0.
   bReturn = StretchBlt(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom,
                        hMemDC, 0, 0, 32, 32, SRCCOPY);

   // Clean up
   SelectObject(hMemDC, hOldBitmap);
   SelectObject(hMemDC, hOldBrush);
   DeleteObject(hBitmap);
   DeleteObject(hBkgdBrush);
   DeleteDC(hMemDC);

   // Validate rect of the client our WM_PAINT case dosen't try to paint over it
   ValidateRect(hWndDlg, &rRect);
   ReleaseDC(hWndDlg, hDC);
}


/************************************************************************
 * cwCenter()
 *
 * Centers a window in the center of the screen.  To do this, we find the
 * dimensions of the screen, the dimensions of the window, and do some
 * calculations to center it on the screen, then call MoveWindow() on the
 * window.
 *
 *
 ************************************************************************/


void cwCenter(HWND hWnd,        // Handle to the window to be centered
              int top)          // adjust vertical position either up (positive
                                // values) or down (negative values)
{
   POINT pt;
   RECT rDialog;      // Rect of dialog
   int iDlgWidth;     // width of dialog box
   int iDlgHeight;    // height of dialog box
   HDC hDC;           // hDC to entire screen

   /* Figure out how big screen is, then calculate center point of screen */

   hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
   pt.x = (GetDeviceCaps(hDC, HORZRES) / 2);
   pt.y = (GetDeviceCaps(hDC, VERTRES) / 2);
   DeleteDC(hDC);

   /* Get rect of the dialog box, and calculate the height and width  */
   GetWindowRect(hWnd, &rDialog);
   iDlgHeight = rDialog.bottom - rDialog.top;
   iDlgWidth = rDialog.right - rDialog.left;

   /* calculate the new x, y starting point                               */
   pt.x = pt.x - iDlgWidth / 2;
   pt.y = pt.y - iDlgHeight / 2;

   /* top will adjust the window position, up or down                     */
   if (top)
      pt.y = pt.y + top;

   /* move the window                                                     */
   MoveWindow(hWnd, pt.x, pt.y, iDlgWidth, iDlgHeight, FALSE);
}

/************************************************************************
 * DrawIndent()
 *
 * Draws a 3-D "Indent", or shadow for the specified control within
 * a dialog box.  This routine also takes a third parameter, which can be set
 * to 1 for a groupbox control, and 2 for a frame control.  Specifying a 2
 * causes this procedure to draw a rectangle around the window also.
 *
 * This code is based on the Microsoft KnowledgeBase article
 * "How to Give a 3_d Effect to Windows Controls"
 *
 ************************************************************************/


void DrawIndent(HWND hDlg, int ID, int iType)

// Assumptions:
//
// hDlg        is a valid window handle.
// ID          is a valid control ID.
// iType       is 1 or 2.  2 will draw a rectangle around the control
{
   RECT rRect;   // RECT which contains control window's coordinates (in client coords)
   HDC hDC;     // HDC to control's window
   HPEN hOldPen; // save old pen so we can select it back in
   HPEN hPenSmall;   // Pen for outlining
   HPEN hPenShadow;  // Pen for shadowing
   HBRUSH hBrushOld; // Save it so we can restore it

   // Find out how big the control's window is

   GetClientRect(GetDlgItem(hDlg, ID), (LPRECT)&rRect);
   hDC = GetDC(GetDlgItem(hDlg, ID));

   // Create the pens which will draw the shadows (and borders)
   hPenSmall = CreatePen(PS_SOLID, 1, RGB(0,0,0));         // Black, 1 pixel wide
   hPenShadow = CreatePen(PS_SOLID, 4, RGB(160,160,160));  // Grayish, 4 pixels wide
   hOldPen = SelectObject(hDC, hPenShadow);

   // Draw the Shadow
   MoveTo(hDC, rRect.right + 2, rRect.top + 13);
   LineTo(hDC, rRect.right + 2, rRect.bottom + 2);
   LineTo(hDC, rRect.left + 6, rRect.bottom + 2);

   // If iType is 2, draw the border around the window (with small pen) also
   if (iType == 2)
   {
      SelectObject(hDC, hPenSmall);
      hBrushOld = SelectObject(hDC, GetStockObject(NULL_BRUSH));
      Rectangle(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom);
      SelectObject(hDC, hBrushOld);
   }

   // Housekeep
   SelectObject(hDC, hOldPen);
   DeleteObject(hPenShadow);
   DeleteObject(hPenSmall);
   ReleaseDC(GetDlgItem(hDlg, ID), hDC);
}
