/*****************************************************************************
*                                                                            *
*  File Name   : HWX_SAMP.C                                                  *
*                                                                            *
*  Description : Main calling routine for the HWX_SAMP.EXE                   *
*                                                                            *
*  Function:  This file contains the code for the main thread for the        *
*             HWX_SAMP.EXE.                                                  *
*                                                                            *
*  Copyright (C) 1993 IBM Corporation                                        *
*                                                                            *
*      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is           *
*      sample code created by IBM Corporation. This sample code is not       *
*      part of any standard or IBM product and is provided to you solely     *
*      for  the purpose of assisting you in the development of your          *
*      applications.  The code is provided "AS IS", without                  *
*      warranty of any kind.  IBM shall not be liable for any damages        *
*      arising out of your use of the sample code, even if they have been    *
*      advised of the possibility of such damages.                           *
*                                                                            *
*****************************************************************************/

/*****************************************************************************
* Defines                                                                    *
*****************************************************************************/
#define  INCL_PM
#define  INCL_WINLOAD
#define  INCL_DOSMODULEMGR

/*****************************************************************************
* System includes                                                            *
*****************************************************************************/
#include <os2.h>
#include <stdio.h>
#include <string.h>

/*****************************************************************************
* Application includes                                                       *
*****************************************************************************/
#include <penpm.h>
#include "hwx_samp.h"

/*****************************************************************************
* Function prototypes                                                        *
*****************************************************************************/
MRESULT EXPENTRY  wpMain                     ( HWND, ULONG, MPARAM, MPARAM );
MRESULT EXPENTRY  wpStatus                   ( HWND, ULONG, MPARAM, MPARAM );
MRESULT EXPENTRY  wpChild                    ( HWND, ULONG, MPARAM, MPARAM );
ULONG             CreateTestWindow           ( HWND, ULONG );
VOID              DebugMessage               ( char* );

/*****************************************************************************
* Global Variables                                                           *
*****************************************************************************/
HAB            hab;
HMQ            hmq;
HMODULE        hmodule;

/*****************************************************************************
* Main entry point for the application                                       *
*****************************************************************************/
int main ( VOID )
   {
   ULONG          rc;
   HAB            hab;
   HWND           hframe;
   HWND           hWndStatus;
   HMQ            hmq;
   QMSG           qmsg;
   HWND           hClient;
   ULONG          ulStyles;
   ULONG          ulCreateFlags;

   /**************************************************************************
   * Initialize PM                                                           *
   **************************************************************************/
   hab = WinInitialize ( 0 );
   if ( !hab )
      {
      printf ( "Error: WinInitialize failed!\n" );
      return ( 0 );
      };

   /**************************************************************************
   * Create the message queue for this thread                                *
   **************************************************************************/
   hmq = WinCreateMsgQueue ( hab, 100 );
   if ( !hmq )
      {
      printf         ( "Error: WinCreateMsgQueue failed!\n" );
      WinTerminate   ( hab );
      return         ( 0 );
      };

   /**************************************************************************
   * Register the private class for the main window                          *
   **************************************************************************/
   rc  = WinRegisterClass ( hab,
                            MAINWINCLASS,
                            wpMain,
                            0l,
                            0 );
   if ( !rc )
      {
      printf             ( "Error: WinRegisterClass Failed!\n" );
      WinDestroyMsgQueue ( hmq );
      WinTerminate       ( hab );
      return             ( rc );
      };

   rc  = WinRegisterClass ( hab,
                            "MYSTATUSBOX",
                            wpStatus,
                            CS_CLIPSIBLINGS,
                            0 );
   if ( !rc )
      {
      printf             ( "Error: WinRegisterClass Failed!\n" );
      WinDestroyMsgQueue ( hmq );
      WinTerminate       ( hab );
      return             ( rc );
      };

   rc  = WinRegisterClass ( hab,
                            "MYCHILDBOX",
                            wpChild,
                            0L,
                            0 );
   if ( !rc )
      {
      printf             ( "Error: WinRegisterClass Failed!\n" );
      WinDestroyMsgQueue ( hmq );
      WinTerminate       ( hab );
      return             ( rc );
      };

   /**************************************************************************
   * Create the main window.                                                 *
   **************************************************************************/
   ulStyles      = WS_VISIBLE          |
                   WS_CLIPCHILDREN     ;

   ulCreateFlags = FCF_TITLEBAR        |
                   FCF_SIZEBORDER      |
                   FCF_MINMAX          |
                   FCF_SYSMENU         |
                   FCF_SHELLPOSITION   |
                   FCF_TASKLIST        |
                   FCF_MENU            |
                   FCF_ICON            ;
                                                 /***************************/
   hframe = WinCreateStdWindow ( HWND_DESKTOP,   /* parent window handle    */
                                 ulStyles,       /* frame style             */
                                 &ulCreateFlags, /* frame create flags      */
                                 MAINWINCLASS,   /* class for client window */
                                 MAINWINNAME,    /* title bar text          */
                                 ulStyles,       /* client style            */
                                 NULLHANDLE,     /* resources identifier    */
                                 ID_MAIN_RES,    /* frame window identifier */
                                 &hClient );     /* client window handle    */
                                                 /***************************/
   if ( !hframe )
      {
      WinDestroyMsgQueue ( hmq );
      WinTerminate       ( hab );
      return             ( rc );
      };

   /**************************************************************************
   * Message Dispatching loop                                                *
   **************************************************************************/
   while ( WinGetMsg ( hab, &qmsg, 0, 0, 0 ) )
      {
      WinDispatchMsg ( hab, &qmsg );
      };

   /**************************************************************************
   * Cleanup. Destroy window. Destroy message queue. Terminate application   *
   **************************************************************************/
   WinDestroyWindow   ( hframe );
   WinDestroyMsgQueue ( hmq );
   WinTerminate       ( hab );

   /**************************************************************************
   * All is well. Return  0 to command line handler                          *
   **************************************************************************/
   return ( 0 );
   }

/*****************************************************************************
* Window Procedure for Main Window                                           *
*****************************************************************************/
MRESULT EXPENTRY  wpStatus ( HWND     hWnd,
                             ULONG    ulMsg,
                             MPARAM   mp1,
                             MPARAM   mp2   )
   {
   RECTL    rcl;
   HPS      hps;
   ULONG    rc;
   HWND     hWndStatus;
   POINTL   points[4];
   LONG     backgroundcolor;

   switch ( ulMsg )
      {
      /***********************************************************************
      * Initialization for main application window.                          *
      ***********************************************************************/
      case  WM_CREATE:
            backgroundcolor = SYSCLR_MENU;
            WinSetPresParam ( hWnd,
                              PP_BACKGROUNDCOLORINDEX,
                              sizeof(LONG),
                              (PVOID) &backgroundcolor );
            WinQueryWindowRect   ( hWnd, &rcl );

            /*****************************************************************
            * Create the status line at the bottom of the window.            *
            *****************************************************************/
            hWndStatus  =  WinCreateWindow ( hWnd,
                                             WC_STATIC,
                                             "",
                                             SS_TEXT         |
                                             DT_VCENTER      |
                                             DT_LEFT         |
                                             WS_VISIBLE,
                                             1,
                                             1,
                                             rcl.xRight - 2,
                                             STATUS_BAR_HEIGHT,
                                             hWnd,
                                             HWND_TOP,
                                             ID_STATUS_TEXT,
                                             NULL,
                                             NULL );
            if ( !hWndStatus )
               {
               DebugMessage ( "Status Line creation failed" );
               WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
               return( (MRESULT) FALSE );
               };

            WinSetPresParam ( hWndStatus,
                              PP_BACKGROUNDCOLORINDEX,
                              sizeof(LONG),
                              (PVOID) &backgroundcolor );
            WinShowWindow    ( hWndStatus, TRUE );
            break;

      /***********************************************************************
      * Paint the background in the same color as the menu.                  *
      ***********************************************************************/
      case  WM_PAINT:
            hps = WinBeginPaint  ( hWnd, NULLHANDLE, (PRECTL)NULL );
            WinQueryWindowRect   ( hWnd, &rcl );
            WinFillRect          ( hps,  &rcl, SYSCLR_MENU );
            points[0].x = 0;
            points[0].y = STATUS_BAR_HEIGHT + 1;
            points[1].x = rcl.xRight-1;
            points[1].y = STATUS_BAR_HEIGHT + 1;
            points[2].x = rcl.xRight-1;
            points[2].y = 0;
            points[3].x = 0;
            points[3].y = 0;
            GpiSetColor ( hps, CLR_WHITE );
            GpiMove ( hps,
                      &points[3] );
            GpiPolyLine( hps,
                         2,
                         &points[0] );
            GpiSetColor ( hps, CLR_BLACK );
            GpiPolyLine( hps,
                         2,
                         &points[2] );
            WinEndPaint          ( hps );
            return ( (MRESULT) TRUE );
            break;

      /***********************************************************************
      * Resize the status line to fill the bottom of the window.             *
      ***********************************************************************/
      case  WM_SIZE:
            WinQueryWindowRect   ( hWnd, &rcl );
            WinSetWindowPos  ( WinWindowFromID ( hWnd, ID_STATUS_TEXT ),
                               HWND_TOP,
                               1,
                               1,
                               rcl.xRight-2,
                               STATUS_BAR_HEIGHT,
                               SWP_MOVE      |
                                 SWP_SIZE    |
                                 SWP_SHOW );
            break;

      default:
            break;
      };
   return( (MRESULT) WinDefWindowProc ( hWnd, ulMsg, mp1, mp2 )  );
   };

/*****************************************************************************
* Window Procedure for Main Window                                           *
*****************************************************************************/
MRESULT EXPENTRY  wpChild ( HWND     hWnd,
                            ULONG    ulMsg,
                            MPARAM   mp1,
                            MPARAM   mp2   )
   {
   RECTL    rcl;
   HPS      hps;

   switch ( ulMsg )
      {
      /***********************************************************************
      * Paint the background in the same color as the menu.                  *
      ***********************************************************************/
      case  WM_PAINT:
            hps = WinBeginPaint  ( hWnd, NULLHANDLE, (PRECTL)NULL );
            WinQueryWindowRect   ( hWnd, &rcl );
            WinFillRect          ( hps,  &rcl, SYSCLR_MENU );
            WinEndPaint          ( hps );
            return ( (MRESULT) TRUE );
            break;

      default:
            break;
      };
   return( (MRESULT) WinDefWindowProc ( hWnd, ulMsg, mp1, mp2 )  );
   };

/*****************************************************************************
* Window Procedure for Main Window                                           *
*****************************************************************************/
MRESULT EXPENTRY  wpMain (  HWND     hWnd,
                            ULONG    ulMsg,
                            MPARAM   mp1,
                            MPARAM   mp2   )
   {
   RECTL    rcl;
   HPS      hps;
   ULONG    rc;
   CHAR     pszObjNameBuf[100];
   LONG     backgroundcolor;
   HWND     hWndStatus;
   HWND     hWndChild;

   switch ( ulMsg )
      {
      /***********************************************************************
      * Initialization for main application window.                          *
      ***********************************************************************/
      case  WM_CREATE:
            if( WrtWaitActive( WRT_IMMEDIATE_RETURN ) )
               {
               DebugMessage ( "Pen for OS/2 is not active" );
               WinSendMsg ( hWnd, WM_CLOSE, 0, 0 );
               };

            backgroundcolor = SYSCLR_MENU;
            WinSetPresParam ( hWnd,
                              PP_BACKGROUNDCOLORINDEX,
                              sizeof(LONG),
                              (PVOID) &backgroundcolor );

            WinShowWindow    ( hWnd, TRUE );
            WinQueryWindowRect   ( hWnd, &rcl );

            /*****************************************************************
            * Load the hwxprocs.dll. This dll contains all of the window     *
            * procedures for the child windows.                              *
            *****************************************************************/
            rc = DosLoadModule ( pszObjNameBuf,
                                 sizeof(pszObjNameBuf),
                                 "hwxprocs",
                                 &hmodule );
            if ( rc )
               {
               DebugMessage ( "could not load module" );
               WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
               return ( (MRESULT) FALSE );
               };

            /*****************************************************************
            * Create the status line at the bottom of the window.            *
            *****************************************************************/
            hWndStatus  =  WinCreateWindow ( hWnd,
                                             "MYSTATUSBOX",
                                             "",
                                             0L,
                                             0,
                                             0,
                                             rcl.xRight,
                                             STATUS_BAR_HEIGHT+2,
                                             hWnd,
                                             HWND_TOP,
                                             ID_STATUS_BOX,
                                             NULL,
                                             NULL );
            if ( !hWndStatus )
               {
               DebugMessage ( "Status window creation failed" );
               WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
               return ( (MRESULT) FALSE );
               };

            /*****************************************************************
            * Create the status line at the bottom of the window.            *
            *****************************************************************/
            hWndChild   =  WinCreateWindow ( hWnd,
                                             "MYCHILDBOX",
                                             "",
                                             0L,
                                             0,
                                             STATUS_BAR_HEIGHT+2,
                                             rcl.xRight,
                                             rcl.yTop-STATUS_BAR_HEIGHT-2,
                                             hWnd,
                                             HWND_TOP,
                                             ID_CHILD_BOX,
                                             NULL,
                                             NULL );
            if ( !hWndChild )
               {
               DebugMessage ( "Child window creation failed" );
               WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
               return ( (MRESULT) FALSE );
               };

            break;

      /***********************************************************************
      * Paint the background in the same color as the menu.                  *
      ***********************************************************************/
      case  WM_PAINT:
            hps = WinBeginPaint  ( hWnd, NULLHANDLE, (PRECTL)NULL );
            WinQueryWindowRect   ( hWnd, &rcl );
            WinFillRect          ( hps,  &rcl, SYSCLR_MENU );
            WinEndPaint          ( hps );
            return ( (MRESULT) TRUE );
            break;

      /***********************************************************************
      * Messages from the menu                                               *
      ***********************************************************************/
      case  WM_COMMAND:
            if ( LONGFROMMP(mp1) == ID_QUIT )
               WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
            else
               CreateTestWindow ( hWnd, LONGFROMMP(mp1) );
            break;

      /***********************************************************************
      * Resize the status line to fill the bottom of the window.             *
      ***********************************************************************/
      case  WM_SIZE:
            WinQueryWindowRect   ( hWnd, &rcl );
            WinSetWindowPos  ( WinWindowFromID ( hWnd, ID_STATUS_BOX ),
                               HWND_TOP,
                               0,
                               0,
                               rcl.xRight,
                               STATUS_BAR_HEIGHT+2,
                               SWP_MOVE      |
                                 SWP_SIZE    |
                                 SWP_SHOW );
            WinSetWindowPos  ( WinWindowFromID ( hWnd, ID_CHILD_BOX ),
                               HWND_TOP,
                               0,
                               STATUS_BAR_HEIGHT+2,
                               rcl.xRight,
                               rcl.yTop-STATUS_BAR_HEIGHT-2,
                               SWP_MOVE      |
                                 SWP_SIZE    |
                                 SWP_SHOW );
            break;

      default:
            break;
      };
   return( (MRESULT) WinDefWindowProc ( hWnd, ulMsg, mp1, mp2 )  );
   };

/*****************************************************************************
* Debug messages                                                             *
*****************************************************************************/
VOID DebugMessage ( char dmessage[50] )
   {
   WinMessageBox ( HWND_DESKTOP,
                   HWND_DESKTOP,
                   dmessage,
                   "Debug Message",
                   0,
                   MB_OK            |
                   MB_ERROR         |
                   MB_SYSTEMMODAL   |
                   MB_MOVEABLE );
   }

/*****************************************************************************
* Create the test window                                                     *
*****************************************************************************/
ULONG CreateTestWindow ( HWND hWnd, ULONG ID )
   {
   ULONG          rc;
   PFNWP          pWndProc;
   HWND           hframe;
   HWND           hClient;
   HWND           hStatus;
   ULONG          ulStyles;
   ULONG          ulCreateFlags;
   CHAR           myname[32];
   PFN            pProcAddr;
   CHAR           pszObjNameBuf[100];
   RECTL          rcl;


   /**************************************************************************
   * Load the window procedure same from the string table. The ID of the     *
   * string is the same as the ID as the menu item selected.                 *
   **************************************************************************/
   rc = WinLoadString ( hab, NULLHANDLE, ID, sizeof(myname), myname );
   if ( !rc )
      {
      DebugMessage ( "Could not load string" );
      return ( -1 );
      };

   /**************************************************************************
   * Get a pointer to the window procedure for the selected menu item        *
   **************************************************************************/
   rc = DosQueryProcAddr ( hmodule,
                           0L,
                           myname,
                           &pProcAddr);
   if ( rc )
      {
      DebugMessage ( "Could not load procedure" );
      return ( -1 );
      };

   /**************************************************************************
   * Register the window class for the application window running in this    *
   * thread                                                                  *
   **************************************************************************/
   rc = WinRegisterClass ( hab,
                           myname,
                           (PFNWP) pProcAddr,
                           0L,
                           sizeof(HWND) );
   if ( !rc )
      {
      DebugMessage ( "Error: WinRegisterProcedure for TestWindow! ");
      return ( -1 );
      };

   /**************************************************************************
   * Create the application window for the handwriting control               *
   **************************************************************************/
   ulStyles      = WS_VISIBLE;
   ulCreateFlags = FCF_TITLEBAR        |
                   FCF_SIZEBORDER      |
                   FCF_MINMAX          |
                   FCF_SYSMENU         |
                   FCF_MENU            |
                   FCF_ICON            ;

   hframe  = WinCreateStdWindow ( WinWindowFromID ( hWnd, ID_CHILD_BOX ),
                                  ulStyles,
                                  &ulCreateFlags,
                                  myname,
                                  myname,
                                  ulStyles,
                                  NULLHANDLE,
                                  ID_TEST_RES,
                                  &hClient );

   if ( !hframe )
      {
      DebugMessage ( "Error: WinCreateWindow for TestWindow! ");
      return             ( -1 );
      };

   /*************************************************************************
   * Set the window handle for the status window in the window words for    *
   * child window to update the status text.                                *
   *************************************************************************/
   hStatus = WinWindowFromID ( WinWindowFromID ( hWnd,
                                                 ID_STATUS_BOX ),
                               ID_STATUS_TEXT );

   WinPostMsg ( hClient, WM_INITMYWINDOW, (MPARAM) hStatus, 0 );

   /*************************************************************************
   * Set the window position for the new window                             *
   *************************************************************************/
   WinQueryWindowRect ( WinWindowFromID ( hWnd, ID_CHILD_BOX ), &rcl );
   WinSetWindowPos  ( hframe,
                      HWND_TOP,
                      10,
                      rcl.yTop-210,
                      250,
                      200,
                      SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW );

   /**************************************************************************
   * All is well. Return  0 to command line handler                          *
   **************************************************************************/
   return ( 0 );
   }

