// ************************************************************************
//
//                      Microsoft Developer Support
//               Copyright (c) 1992, 1993 Microsoft Corporation
//
// **************************************************************************
// MODULE    : MdiPad.C
// PURPOSE   : A Small Win16/Win32 MdiPad Application Template
// FUNCTIONS :
//   WinMain()       - initializes the main window, dispatches messages
//   MainWndProc()   - processes messages
//   AboutDlgProc()  - processes messages for "About" dialog box
//   ErrorBox()      - displays and error box when called
// **************************************************************************
#ifndef WIN32S
 #define   UNICODE             // make the application unicode complient
#endif
#define   STRICT               // strict type checking enabled
#include <Windows.H>           // required for all Windows applications
#include <Time.H>

#include "Port.H"              // macros for 16/32 bit application creation
#include "MdiPad.H"            // specific to this program
#include "ToolBar.H"

#ifdef DEBUG
  #define DebugOut( str ) OutputDebugString (__FILE__ ": " str "\n")
#else
  #define DebugOut( str )
#endif

//-- global data
HWND      hWndMain;            // Main window handle
HWND      hWndMdiClient;       // MDI client windows handle
HINSTANCE hInstance;           // current instance
TCHAR     szAppName[32];       // name of the application
TCHAR     szShortAppName[16];  // short name of the application
UINT      cMdiChild = 0;       // Count of number of MDI children created

LPCTSTR lpszMdiChildClassName = (LPCTSTR) "MdiChildClass";

HWND hWndMenuField, hWndTimeField, hWndOvrField, hWndBogusField, hWndCapsField, hWndNumField;
HWND hWndLabel1,  hWndCombo1,  hWndCombo2;
HWND hWndButton1, hWndButton2, hWndButton3, hWndButton4;
HWND hWndButton5, hWndButton6, hWndButton7;

HMENU   hSysMenuMain = (HMENU) NULL;
HMENU   hFileMenu    = (HMENU) NULL;
HMENU   hHelpMenu    = (HMENU) NULL;
HMENU   hSysMenuAdv  = (HMENU) NULL;
HMENU   hMenu        = (HMENU) NULL;

//-- internal function prototypes
LRESULT CALLBACK MainWndProc     ( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK MdiChildWndProc ( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK AboutDlgProc    ( HWND, UINT, WPARAM, LPARAM );
BOOL             ErrorMessageBox ( LPCTSTR, LPCTSTR, LPCTSTR, INT );
HWND    WINAPI   CreateMdiChildWindow( LPCTSTR );
VOID    WINAPI   CloseAllMdiChildren( VOID );
BOOL    WINAPI   QueryCloseMdiChild( HWND );

BOOL FillFontNameComboBox( HWND, int );
BOOL FillFontSizeComboBox( HWND, int );

// **************************************************************************
// FUNCTION : WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
// PURPOSE  : Calls initialization function, processes message loop
// COMMENTS :
// **************************************************************************
int PASCAL
WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
{
  MSG     msg;
  HACCEL  hAccel;
  LPCTSTR lpszClassName = TEXT( "MdiPadClass" );
  LPCTSTR lpszMenuName  = TEXT( "MdiPadMenu"  );
  LPCTSTR lpszIconName  = TEXT( "MdiPadIcon"  );
  LPCTSTR lpszAccelName = TEXT( "MdiPadAccel" );

  LPCTSTR lpszMdiChildIconName  = TEXT( "MdiChildIcon" );

  UNREFERENCED_PARAMETER( lpCmdLine );  // avoid the warning

  hInstance = hInst;

  //-- Other instances of app running? If not...
  if( !hPrevInst ) {
    WNDCLASS wndclass;

    // Register the frame class
    wndclass.style         = CS_VREDRAW;
    wndclass.lpfnWndProc   = (WNDPROC) MainWndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon( hInstance, lpszIconName );
    wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW );
    wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
    wndclass.lpszMenuName  = lpszMenuName;
    wndclass.lpszClassName = lpszClassName;

    if( !RegisterClass(&wndclass) ) {
      ErrorMessageBox( TEXT("Failed!"), TEXT("RegisterClass()"), (LPCTSTR) __FILE__, __LINE__ );
      return( FALSE );
    }

    // Register the MDI child class
    wndclass.style         = 0;
    wndclass.lpfnWndProc   = (WNDPROC) MdiChildWndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon( hInstance, lpszMdiChildIconName );
    wndclass.hCursor       = LoadCursor( NULL, IDC_IBEAM );
    wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
    wndclass.lpszMenuName  = (LPCTSTR) NULL;
    wndclass.lpszClassName = lpszMdiChildClassName;

    if( !RegisterClass(&wndclass) ) {
      ErrorMessageBox( TEXT("Failed!"), TEXT("RegisterClass()"), (LPCTSTR) __FILE__, __LINE__ );
      return( FALSE );
    }
  }

  //-- Load resource strings
  if( !LoadString( hInstance, IDS_APPNAME,  szAppName, sizeof(szAppName) ) )
    ErrorMessageBox( TEXT("Failed!"), TEXT("LoadString()"), (LPCTSTR) __FILE__, __LINE__ );
  if( !LoadString( hInstance, IDS_SHORT_APPNAME, szShortAppName,
         sizeof(szShortAppName) ) )
    ErrorMessageBox( TEXT("Failed!"), TEXT("LoadString()"), (LPCTSTR) __FILE__, __LINE__ );

  //-- initialize the tool bar
  if( !InitToolBar(hInst) ) {
    DebugOut( "InitToolBar Failed" );
    return FALSE;
  }

  //-- initialize the statis bar
  if( !InitStatusBar(hInst) ) {
    DebugOut( "InitStatusBar Failed" );
    return FALSE;
  }

  //-- Create the main window
  hWndMain = CreateWindow(
               lpszClassName,        // See RegisterClass() call
               szAppName,            // Text for window title bar
               WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,  // Window style
               CW_USEDEFAULT,        // Default horizontal position
               CW_USEDEFAULT,        // Default vertical position
               CW_USEDEFAULT,        // Default width
               CW_USEDEFAULT,        // Default height
               NULL,                 // Overlapped windows have no parent
               NULL,                 // Use the window class menu
               hInstance,            // This instance owns this window
               NULL );               // Pointer not needed

  //-- If window could not be created, return "failure"
  if( !hWndMain ) {
    ErrorMessageBox( TEXT("Failed!"), TEXT("CreateWindow()"), (LPCTSTR) __FILE__, __LINE__ );
    return( FALSE );
  }




  //-- Get handles to the various menus. Some of these we will use later
  //   to display menu descriptions in the status bar
  hSysMenuMain = GetSystemMenu( hWndMain, FALSE );
  if( !hSysMenuMain )
    DebugOut( "No System Menu" );
    hMenu = GetMenu( hWndMain );
  if( hMenu ) {
    hFileMenu = GetSubMenu( hMenu, 0 );
    hHelpMenu = GetSubMenu( hMenu, 1 );
  }
  else {
    DebugOut( "No Menu Bar" );
  }

  //-- Create the ToolBar
  DebugOut( "Call CreateToolBar" );
  if( CreateToolBar( hWndMain, hInstance, ID_TOOLBAR ) ) {
    DebugOut( "CreateToolBar Succeeded" );
    hWndLabel1 = AddToolLabel( hInstance, 0, TEXT( "Font:" ), 0, SS_RIGHT );
    AddToolSpace (6, 0);
    hWndCombo1 = AddToolCombo( hInstance, ID_COMBO1, -25, CBS_DROPDOWN | WS_VSCROLL );
    FillFontNameComboBox( hWndCombo1, 0 );
    AddToolSpace (10, 0);
    hWndCombo2 = AddToolCombo( hInstance, ID_COMBO2, -10, CBS_DROPDOWN | WS_VSCROLL );
    FillFontSizeComboBox( hWndCombo2, 0 );
    AddToolSpace (25, 0);
    hWndButton1 = AddToolButton( hInstance, ID_BOLD, TEXT( "Bold" ), 26, 0, BS_OWNERDRAW );
    AddToolSpace (-1, 0);
    hWndButton2 = AddToolButton( hInstance, ID_ITALIC, TEXT( "Italic" ), 26, 0, BS_OWNERDRAW );
    AddToolSpace (-1, 0);
    hWndButton3 = AddToolButton( hInstance, ID_UNDER, TEXT( "Under" ), 26, 0, BS_OWNERDRAW );
    AddToolSpace (10, 0);
    hWndButton4 = AddToolButton( hInstance, ID_LEFT,  TEXT( "Left" ),    26, 0, BS_OWNERDRAW );
    AddToolSpace (-1, 0);
    hWndButton5 = AddToolButton( hInstance, ID_CENTER, TEXT( "Center" ),  26, 0, BS_OWNERDRAW );
    AddToolSpace (-1, 0);
    hWndButton6 = AddToolButton( hInstance, ID_RIGHT, TEXT( "Right" ),   26, 0, BS_OWNERDRAW );
    AddToolSpace (-1, 0);
    hWndButton7 = AddToolButton( hInstance, ID_JUST,  TEXT( "Just" ),    26, 0, BS_OWNERDRAW );
    AddToolSpace (-1, 0);
  }
  else {
    DebugOut( "CreateToolBar Failed" );
    return FALSE;
  }

  //-- Create the StatusBar
  DebugOut( "Call CreateStatusBar" );
  if( CreateStatusBar(hWndMain, hInstance, ID_STATUSBAR) ) {
    DebugOut( "CreateStatusBar Succeeded" );
    hWndMenuField = AddStatusField( hInstance, ID_MENUFIELD, 100, 0, FALSE);
    hWndTimeField = AddStatusField( hInstance, ID_TIMEFIELD, -12, -12, TRUE);
    if( hWndTimeField ) {
      SetTimer( hWndMain, 1, 1000, NULL );
    }
    hWndOvrField   = AddStatusField( hInstance, ID_OVRFIELD,    -6, -6, TRUE  );
    hWndBogusField = AddStatusField( hInstance, ID_SCROLLFIELD, -6, -6, FALSE );
    hWndCapsField  = AddStatusField( hInstance, ID_CAPSFIELD,   -6, -6, FALSE );
    hWndNumField   = AddStatusField( hInstance, ID_NUMFIELD,    -6, -6, FALSE );
  }
  else {
    DebugOut( "CreateStatusBar Failed" );
    return FALSE;
  }

  //-- Load main menu accelerators
  if( !(hAccel = LoadAccelerators( hInstance, lpszAccelName) ) ) {
    ErrorMessageBox( TEXT("Failed!"), TEXT("LoadAccelerators()"), (LPCTSTR) __FILE__, __LINE__ );
    return( FALSE );
  }

  //-- Create an MDI clint window
  {
    CLIENTCREATESTRUCT ccs;

    // Find window menu where children will be listed
    ccs.hWindowMenu = GetSubMenu( GetMenu(hWndMain), WINDOWMENU );
    ccs.idFirstChild = IDM_FIRSTCHILD;

    hWndMdiClient = CreateWindow(
                      TEXT( "MdiClient" ),
                       NULL,
                       WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
                       WS_HSCROLL | WS_VSCROLL,
                       0, 0, 0, 0,
                       hWndMain,
                       (HMENU) NULL,
                       hInstance,
                       (LPSTR) &ccs );

  }
  //-- If window could not be created, return "failure"
  if( !hWndMdiClient ) {
    ErrorMessageBox( TEXT("Failed!"), TEXT("CreateWindow()"), (LPCTSTR) __FILE__, __LINE__ );
    return( FALSE );
  }

  ShowWindow( hWndMdiClient, SW_SHOW );
  //-- Make the window visible; update its client area; and return "success"
  ShowWindow( hWndMain, nCmdShow );  // Show the window
  UpdateWindow( hWndMain );          // Sends WM_PAINT message

  //-- Acquire and dispatch messages until a WM_QUIT message is received.
  while( GetMessage( &msg, NULL, 0, 0 ) ) {
    if( !TranslateMDISysAccel( hWndMdiClient, &msg ) ) {
      if( !TranslateAccelerator( hWndMain, hAccel, &msg ) ) {
        TranslateMessage( &msg );     // Translates virtual key codes
        DispatchMessage( &msg );      // Dispatches message to window
      }
    }
  }

  return( msg.wParam );           // Returns the value from PostQuitMessage
}


// **************************************************************************
// FUNCTION : MainWndProc( HWND, UINT, WPARAM, LPARAM )
// PURPOSE  : Processes messages
// MESSAGES :
//   WM_COMMAND         - application menu
//     IDM_FILE_EXIT    - exit the application
//     IDM_HELP_ABOUT   - About Dialog Box
//     ...
//   WM_CREATE          - window initialization
//   WM_SIZE            - saves window width and height when resized
//   WM_CLOSE           - handles cleanup
//   WM_DESTROY         - destroys window
// **************************************************************************
LRESULT CALLBACK
MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  static  INT        idMenuSelect;

  time_t  lTime;
  struct tm *datetime;

  #define HOUR (datetime->tm_hour)
  #define MIN (datetime->tm_min)
  #define SEC (datetime->tm_sec)

  TCHAR   szTime[20];
  INT     tmp;
  INT     wmMenuCmd, wmFlags;
  HMENU   wmhMenu;
  TCHAR   szMsg[80] = TEXT( "" );

  switch( uMsg ) {

    case WM_COMMAND: {    // message: command from application menu

      switch( LOWORD( wParam ) ) {

        case IDM_FILE_NEW: {
          // Create a new MDI child window
          TCHAR MdiChildName[64];

          wsprintf( MdiChildName, TEXT( "MDI Child #%d" ), ++cMdiChild );
          CreateMdiChildWindow( MdiChildName );
          return( FALSE );
        }

        case IDM_FILE_OPEN:
          MessageBeep( (UINT) -1 );
          return( FALSE );

        case IDM_FILE_EXIT:
          SendMessage( hWnd, WM_CLOSE, 0, 0 );
          return( FALSE );

        case IDM_WINDOW_CASCADE:
          // Cascade MDI windows
          SendMessage( hWndMdiClient, WM_MDICASCADE, 0, 0L );
          return( FALSE );

        case IDM_WINDOW_TILE_HORZ:
          // Tile MDI windows
          SendMessage( hWndMdiClient, WM_MDITILE, MDITILE_HORIZONTAL, 0L );
          return( FALSE );

        case IDM_WINDOW_TILE_VERT:
          // Tile MDI windows
          SendMessage( hWndMdiClient, WM_MDITILE, MDITILE_VERTICAL, 0L );
          return( FALSE );

        case IDM_WINDOW_ARRANGEICONS:
          // Auto - arrange MDI icons
          SendMessage( hWndMdiClient, WM_MDIICONARRANGE, 0, 0L );
          return( FALSE );

        case IDM_WINDOW_CLOSEALL:
          CloseAllMdiChildren();
          cMdiChild = 0;
          return( FALSE );

        case IDM_HELP_ABOUT: {
          DLGPROC lpfnAboutDlgProc;  // pointer to the "About" function
          LPTSTR  lpszAboutSample = TEXT("AboutDlgBox");

          lpfnAboutDlgProc = (DLGPROC) MakeProcInstance( (FARPROC) AboutDlgProc, hInstance );
          if( DialogBox( hInstance, lpszAboutSample, hWnd, lpfnAboutDlgProc ) == -1)
            ErrorMessageBox( TEXT("Failed!"), TEXT("DialogBox()"), (LPCTSTR) __FILE__, __LINE__ );
          FreeProcInstance( (FARPROC) lpfnAboutDlgProc );
          return( FALSE );
        }

        default:
          // This is essential, since there are frame WM_COMMANDS generated
          // by the MDI system for activating child windows via the
          // window menu.
          return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
      }
    }

    case WM_WINDOWPOSCHANGING: {
     LPWINDOWPOS lpWinPos = (LPWINDOWPOS) lParam;

     lpWinPos->x = 64;
     lpWinPos->y = 64;
     return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
    }

    //-- handle the WM_SIZE message ourselves so we can resize the
    //    the MDI client windows to exclude the toolbar and the
    //    status bar
    case WM_SIZE: {
      RECT rect;

      AdjustToolBar( hWnd );
      AdjustStatusBar( hWnd );
      GetClientRect (hWnd, &rect);
      SetWindowPos( hWndMdiClient, NULL,
        0, (ToolBarHeight( hWnd )+1),
        rect.right - rect.left, rect.bottom
        - (ToolBarHeight( NULL )+1) - (StatusBarHeight( NULL )+1),
        SWP_SHOWWINDOW );

      return( FALSE );
      // return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
    }

    case WM_TIMER:
  #ifndef WIN32
      SetWindowText (hWndTimeField, TEXT("No Time") );
  #else
      time (&lTime);
      datetime = localtime (&lTime);
      wsprintf(
        szTime,
        TEXT( "%02d:%02d:%02d %s" ),
        (HOUR%12?HOUR%12:12), MIN, SEC,
        (LPTSTR) ( HOUR/12  ? TEXT("PM"):TEXT("AM") ) );
      SetWindowText (hWndTimeField, szTime);
  #endif
      if (GetKeyState (VK_NUMLOCK)&1)
        SetWindowText (hWndNumField, TEXT( "NUM" ) );
      else
        SetWindowText (hWndNumField, TEXT( "" ) );

      if (GetKeyState (VK_CAPITAL)&1)
        SetWindowText (hWndCapsField, TEXT( "CAPS" ) );
      else
        SetWindowText (hWndCapsField, TEXT( "" ) );

      if (GetKeyState (VK_INSERT)&1)
        SetWindowText (hWndOvrField, TEXT( "OVR" ) );
      else
        SetWindowText (hWndOvrField, TEXT( "" ) );

      break;

    case WM_KEYUP:
    case WM_KEYDOWN:
      if (GetKeyState (VK_NUMLOCK)&1)
        SetWindowText (hWndNumField, TEXT( "NUM" ) );
      else
        SetWindowText (hWndNumField, TEXT( "" ) );

      if (GetKeyState (VK_CAPITAL)&1)
        SetWindowText (hWndCapsField, TEXT( "CAPS" ) );
      else
        SetWindowText (hWndCapsField, TEXT( "" ) );

      if (GetKeyState (VK_INSERT)&1)
        SetWindowText (hWndOvrField, TEXT( "OVR" ) );
      else
        SetWindowText (hWndOvrField, TEXT( "" ) );

      #define VK_OEM_SCROLL 0x91 // This isn't in WINDOWS.H, will it always work?

      if (GetKeyState (VK_OEM_SCROLL)&1)
        SetWindowText (hWndBogusField, TEXT( "SCROLL" ) );
      else
        SetWindowText (hWndBogusField, TEXT( "" ) );

      return DefWindowProc (hWnd, uMsg, wParam, lParam);
      break;

    case WM_CHAR:
      switch (wParam) {
        case VK_F10:
          wParam = VK_MENU;
          return DefWindowProc (hWnd, uMsg, wParam, lParam);
          break;
      }
      break;

    case WM_MENUSELECT:
      /* A menu item is hilited, get description text for status bar */
      tmp = idMenuSelect;

     #if defined (WIN32)
      wmMenuCmd = LOWORD( wParam );
      wmFlags   = HIWORD( wParam );
      wmhMenu   = (HMENU) lParam;
     #elif defined (WIN16)
      wmMenuCmd = wParam;
      wmFlags   = LOWORD( lParam );
      wmhMenu   = (HMENU) HIWORD( lParam );
     #endif

      if( (wmhMenu == 0) && (wmFlags = -1) ) {
        tmp = idMenuSelect = 0;
        SetWindowText(hWndMenuField, TEXT( "Ready..." ) );
      }
      else if(wmhMenu == 0) {
        /* don't do anything for this */
      } else if(wmFlags & MF_POPUP) {
        if( (HMENU) wmMenuCmd == hSysMenuMain )
          idMenuSelect = IDM_SYSMENU;
        else if( (HMENU) wmMenuCmd == hFileMenu )
          idMenuSelect = IDM_FILE;
        else if( (HMENU) wmMenuCmd == hHelpMenu )
          idMenuSelect = IDM_HELP;
      }
      else {
        if(wmMenuCmd != 0) {         /* separators have wparam of 0 */
          idMenuSelect = wmMenuCmd;
        }
      }

      if( idMenuSelect != tmp ) {
        if( !LoadString( hInstance, (int) idMenuSelect, szMsg, sizeof(szMsg) ) ) {
          if( idMenuSelect != (WORD) -1 ){
            wsprintf( (LPTSTR) szMsg, TEXT( "Unable to load menu string #%u" ), idMenuSelect );
          }
          else {
            lstrcpy(szMsg, TEXT( "Unsupported Function" ) );
          }
        }
        SetWindowText( hWndMenuField, szMsg );
      }
      break;

    case WM_CLOSE: {
      DestroyWindow( hWnd );
      return( FALSE );
    }

    case WM_DESTROY:       // message: window being destroyed
      PostQuitMessage( 0 );
      return( FALSE );

    default:              // Passes it on if unproccessed
      return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
  }

  return( FALSE );
}


// **************************************************************************
// FUNCTION : MdiChildWndProc( HWND, UINT, WPARAM, LPARAM )
// PURPOSE  : Processes messages for the MDI Child windows
// MESSAGES :
// **************************************************************************
LRESULT CALLBACK
MdiChildWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  switch( uMsg ) {

    case WM_CREATE: {
      HWND hWndEdit;

      /* Create an edit control */
      hWndEdit = CreateWindow( TEXT( "Edit" ), NULL,
                   WS_CHILD | WS_MAXIMIZE | WS_VISIBLE |
                   WS_HSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
                   ES_MULTILINE,
                   0, 0, 0, 0,
                   hWnd,
                   (HMENU) NULL,
                   hInstance,
                   NULL );

      SetFocus( hWndEdit );
      break;
    }

    case WM_CLOSE:
      if( QueryCloseMdiChild( hWnd ) ) {
        SendMessage( hWndMdiClient, WM_MDIDESTROY, (WPARAM) hWnd, 0L );
        return DefMDIChildProc( hWnd, uMsg, wParam, lParam );
      }
      break;

    default:
      return DefMDIChildProc( hWnd, uMsg, wParam, lParam );

  }

  return( FALSE );
}


// **************************************************************************
// FUNCTION : AboutDlgProc( HWND, UINT, WPARAM, LPARAM )
// PURPOSE  : Processes messages for "About" dialog box
// MESSAGES :
//   WM_INITDIALOG - initialize dialog box
//   WM_COMMAND    - Input received
//     IDOK        - OK button selected
//     IDCANCEL    - Cancel button selected
// COMMENTS:
//   No initialization is needed for this particular dialog box.
//   In this case, TRUE must be returned to Windows.
//   Wait for user to click on "Ok" button, then close the dialog box.
// **************************************************************************
LRESULT CALLBACK
AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  UNREFERENCED_PARAMETER( lParam );

  switch( uMsg ) {

    case WM_COMMAND:
      switch( wParam ) {

        case IDOK:
          EndDialog( hDlg, TRUE );
          return( TRUE );

        case IDCANCEL:
          EndDialog( hDlg, FALSE );
          return( FALSE );
      }
      break;

    case WM_INITDIALOG:
      return( TRUE );

    case WM_CLOSE:
      return( TRUE );

  }

  return( FALSE );
}


// ************************************************************************
// FUNCTION : CreateMdiChildWindow( LPCTSTR )
// PURPOSE  :
// COMMENTS :
// ************************************************************************
HWND WINAPI
CreateMdiChildWindow( LPCTSTR MdiChildName )
{
  HWND            hWndMdiChild;
  MDICREATESTRUCT mcs;

  if( !MdiChildName )
    mcs.szTitle = TEXT( "Untitled" );
  else
    mcs.szTitle = MdiChildName;

  mcs.szClass    = lpszMdiChildClassName;
  mcs.hOwner     = hInstance;
  mcs.x = mcs.cx = (UINT) CW_USEDEFAULT;  // Use the default size for the window
  mcs.y = mcs.cy = (UINT) CW_USEDEFAULT;
  mcs.style      = WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION |
                   WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;

  // tell the MDI Client to create the child
  hWndMdiChild = (HWND) SendMessage ( hWndMdiClient, WM_MDICREATE, 0,
                   (LPARAM) (LPMDICREATESTRUCT) &mcs );

  return( hWndMdiChild );
}

// ************************************************************************
// FUNCTION : QueryCloseMdiChild( HWND )
// PURPOSE  :
// COMMENTS :
// ************************************************************************
BOOL WINAPI
QueryCloseMdiChild( HWND hWndMdiChild )
{
  TCHAR Buffer[256] = TEXT( "" );

  GetWindowText( hWndMdiChild, (LPTSTR) &Buffer, 256 );
  switch( MessageBox( hWndMain,
            TEXT( "Save contents before closing this window?" ),
            Buffer, MB_YESNOCANCEL | MB_ICONQUESTION ) ) {

    case IDYES:
      // SaveFile();
      return( TRUE );

    case IDNO:
      return( TRUE );

    default:
      return( FALSE );

  }

  return( FALSE );
}


// ************************************************************************
// FUNCTION : CloseAllMdiChildren( VOID )
// PURPOSE  :
// COMMENTS :
// ************************************************************************
VOID WINAPI
CloseAllMdiChildren( VOID )
{
  HWND hWndMdiChild;

  // hide the MDI client window to avoid multiple repaints
  // ShowWindow( hWndMdiClient,SW_HIDE );

  // As long as the MDI client has a child, destroy it
  while ( hWndMdiChild = GetWindow (hWndMdiClient, GW_CHILD) ) {

    // Skip the icon title windows
    while( hWndMdiChild && GetWindow( hWndMdiChild, GW_OWNER ) )
      hWndMdiChild = GetWindow( hWndMdiChild, GW_HWNDNEXT );
    if( hWndMdiChild )
      SendMessage( hWndMdiChild, WM_CLOSE, 0, 0L );
      //QueryCloseMdiChild( hWndMdiChild );
    else
      break;

  }
  // ShowWindow( hWndMdiClient, SW_SHOW );
}


// ************************************************************************
// FUNCTION : ErrorMessageBox( LPCTSTR, LPCTSTR, LPCTSTR, INT )
// PURPOSE  : Displays an error message box with GetLastError information
//            and allows the user to terminate or continue the process.
// COMMENTS :
// ************************************************************************
BOOL
ErrorMessageBox( LPCTSTR lpszText, LPCTSTR lpszTitle, LPCTSTR lpszFile, INT Line )
{
  #define ERROR_BUFFER_SIZE 512

  static TCHAR Format[] =
    TEXT( "%s\n\n"                                  )
    TEXT( "--Error Information--\n\n"               )
    TEXT( "File : %s\n"                             )
    TEXT( "Line : %d\n"                             )
    TEXT( "Error Number : %d\n"                     )
   #ifdef WIN32
    TEXT( "Error Message : %s\n"                    )
   #endif
    TEXT( "Press OK to terminate this application." );

  HLOCAL hMessageBoxBuffer;
  LPVOID lpMessageBoxBuffer;

 #ifdef WIN32
  LPVOID lpMessageBuffer;
 #endif
  DWORD  dwError;

  //-- perform a simple check on the needed buffer size
  if( lstrlen(lpszText) > (ERROR_BUFFER_SIZE - lstrlen(Format)) )
    return( FALSE );

  //-- allocate the message box buffer
  hMessageBoxBuffer  = LocalAlloc( LMEM_FIXED, ERROR_BUFFER_SIZE );
  lpMessageBoxBuffer = LocalLock( hMessageBoxBuffer );

 #ifdef WIN32
  //-- get the sytem error message
  FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL, dwError = GetLastError(), LANG_USER_DEFAULT,
    (LPTSTR) &lpMessageBuffer, 0, NULL );
 #endif

  //-- format the error messge box string
  wsprintf( lpMessageBoxBuffer, Format, lpszText, lpszFile, Line, dwError
   #ifdef WIN32
     , lpMessageBuffer
   #endif
     );

  // -- display the error and allow the user to terminate or continue
  if( MessageBox( NULL, lpMessageBoxBuffer, lpszTitle, MB_OKCANCEL )  == IDOK )
    ExitProcess( 0 );

  //-- free all buffers
 #ifdef WIN32
  LocalFree( (HLOCAL) lpMessageBuffer );
 #endif
  LocalFree( (HLOCAL) hMessageBoxBuffer );

  return( TRUE );
}


// *************************************************************************
//  FUNCTION: FillFontNameComboBox( HWND, int )
//  PURPOSE:  Fills a ComboBox
//  COMMENTS: Returns TRUE
// *************************************************************************
BOOL
FillFontNameComboBox (HWND hWnd, int focus)
{
  int index = 0;

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Courier" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 1 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Helv" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 2 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Tms Rmn" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 3 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Modern" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 4 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Roman" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 5 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Script" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 6 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Symbol" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 7 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Zaph Dingbats" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 8 );

  SendMessage( hWnd, CB_SETCURSEL, focus, 0 );

  return( TRUE );
}


// *************************************************************************
//  FUNCTION: FillFontSizeComboBox( HWND, int )
//  PURPOSE:  Fills a ComboBox
//  COMMENTS: Returns TRUE
// *************************************************************************
BOOL
FillFontSizeComboBox (HWND hWnd, int focus)
{
  int index = 0;

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "6" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 6 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "8" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 8 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "10" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 10 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "12" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 12 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "14" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 14 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "16" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 16 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "18" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 18 );

  SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "24" ) );
  SendMessage( hWnd, CB_SETITEMDATA, index++, 24 );

  SendMessage( hWnd, CB_SETCURSEL, focus, 0 );

  return( TRUE );
}
