/*static char *SCCSID = "@(#)sem_main.c 6.16 92/02/19";*/
/*==============================================================*\
 *  SEM_MAIN.C - Sample PM application				*
 *     (C) Copyright IBM Corporation 1992.			*
 *--------------------------------------------------------------*
 *								*
 *  This application serves two distinct purposes.  First, it	*
 *  demonstrates the standard menus and dialogs that most PM	*
 *  applications will contain.	The Demo menu calls dialog	*
 *  boxes that demonstrate all of the controls available for	*
 *  use in a dialog box.  There is also a dialog box which	*
 *  demonstrates the setting and removing of control		*
 *  Presentation Parameters.  Finally, the demo menu also has	*
 *  menu items that demonstrate the various types of message	*
 *  boxes that the system supports.				*
 *								*
 *  This application also serves as a template than can be	*
 *  easily modified by an application developer.  The source	*
 *  files are organized so that the overhead code that should	*
 *  be in all applications is located in the same files so	*
 *  that these files do not need to be modified.  The routines	*
 *  that deal with application specific code are also located	*
 *  in their own modules.  An application developer need only	*
 *  change these files in order to modify this template for	*
 *  his application.						*
 *								*
 *--------------------------------------------------------------*
 *								*
 *  This source file contains the following functions:		*
 *								*
 *   main() - main routine					*
 *   MainWndProc(hwnd, msg, mp1, mp2) - main window procedure	*
 *   MessageBox(hwnd nId, bBeep) - Warning box routine		*
 *   MainCommand(mp1, mp2) - WM_COMMAND processing of Main	*
 *								*
\*==============================================================*/

/*--------------------------------------------------------------*\
 *  Include files, macros, defined constants, and externs	*
\*--------------------------------------------------------------*/
#include "semaph.h"

/****************************************************************\
 *  Main routine						*
 *--------------------------------------------------------------*
 *								*
 *  Name:   main()						*
 *								*
 *  Purpose: Initializes the PM environment, calls the		*
 *		initialization routine, creates the main	*
 *		window,	 and polls the message queue		*
 *								*
 *  Usage:							*
 *								*
 *  Method:							*
 *	    - obtains anchor block handle and creates message	*
 *		queue						*
 *	    - calls the initialization routine			*
 *	    - creates the main frame window which creates the	*
 *		main client window				*
 *	    - polls the message queue via Get/Dispatch Msg loop *
 *	    - upon exiting the loop, exits			*
 *								*
 *  Returns: (via DosExit)					*
 *	    1 - if sucessful execution completed		*
 *	    0 - if error					*
\****************************************************************/
INT main(VOID)
{
   QMSG qmsg;	       /* message structure */
   ULONG ctlData;      /* frame control data */

   strcpy(szWindowText,"Sample");
   cNumUsers=NUMUSERS;
   fSemaphoreStarted=FALSE;
   fSemaphoreWasStarted=FALSE;
   fAutoMode=FALSE;
   ulTimeout = TIMEOUTPERIOD;

   hab = WinInitialize(0);
   if(!hab) {
      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      return(RETURN_ERROR);
   }
   hmq = WinCreateMsgQueue(hab, 0);
   if(!hmq) {
      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      WinTerminate(hab);
      return(RETURN_ERROR);
   }
   if(!Init()) {
      MessageBox(HWND_DESKTOP, IDMSG_INITFAILED, TRUE);
      DosExit(EXIT_PROCESS, RETURN_ERROR);
   }
					 /* create the main window */
   ctlData = FCF_STANDARD;
   hwndMainFrame = WinCreateStdWindow(HWND_DESKTOP,
				      WS_VISIBLE,
				      (PVOID)&ctlData,
				      (PSZ)szAppName,
				      (PSZ)NULL,
				      WS_VISIBLE,
				      (HMODULE)NULL,
				      IDR_RESOURCE,
				      (PHWND)&hwndMain);

   if(!hwndMainFrame)
   {
       MessageBox(HWND_DESKTOP, IDMSG_MAINWINCREATEFAILED, TRUE);
       DosExit(EXIT_PROCESS, RETURN_ERROR);
   }
   InitHelp();

   while(WinGetMsg(hmq, (PQMSG)&qmsg, (HWND)0, 0, 0))
       WinDispatchMsg(hmq, (PQMSG)&qmsg);
					  /* destroy the help instance */
   DestroyHelpInstance();
				    /* will normally be put in ExitProc */
   DosExit(EXIT_PROCESS, RETURN_SUCCESS);
   return 0L;
}

/****************************************************************\
 *  Main client window procedure				*
 *--------------------------------------------------------------*
 *								*
 *  Name:   MainWndProc(hwnd, msg, mp1, mp2)			*
 *								*
 *  Purpose: Processes the messages sent to the main client	*
 *		window.	 This routine processes the basic	*
 *		messages all client windows should process	*
 *		and passes all others onto UserWndProc where	*
 *		the developer can process any others.		*
 *								*
 *  Usage:  Called for each message placed in the main		*
 *	    window's message queue                              *
 *								*
 *  Method: a switch statement branches to the routines to be	*
 *	    performed for each message processed.  Any messages *
 *	    not specifically process are passed to the user's   *
 *	    message processing procedure UserWndProc().		*
 *								*
 *  Returns:  Return values are determined by each message	*
 *								*
\****************************************************************/
MRESULT EXPENTRY MainWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
    FONTMETRICS	 fntmet;
    HPS		 hPS;
    static SHORT xClient, yClient;
    static SHORT yChar, yDesc;
    MRESULT sRC;

    switch(msg)
    {
       case WM_CREATE:
	   hPS = WinGetPS (hwnd);
	   GpiQueryFontMetrics (hPS, (LONG) sizeof fntmet, &fntmet);

	   yChar = fntmet.lMaxBaselineExt;
	   yDesc = fntmet.lMaxDescender;

	   WinReleasePS (hPS);
	   break;

       case WM_PAINT:
	   MainPaint(hwnd);
	   break;

       case WM_SIZE:
	   xClient = LOUSHORT (mp2);   /* width of window  */
	   yClient = HIUSHORT (mp2);   /* height of window */
	   WinPostMsg (hwndMain, WM_USERCHANGED, (MPARAM)0, (MPARAM)0);
	   break;
				       /* fall thru to ... */
       case WM_USERCHANGED:	       /* number of threads changed */
				       /* so x and y are already known */
	   SetRectPositions(xClient, yClient, yChar, yDesc);
	   WinInvalidateRect (hwnd, NULL, TRUE);
	   break;

       case WM_COMMAND:
	   MainCommand(hwnd, mp1, mp2);
	   break;

	/*-----------------------------------------------*\
	 *   Any messages not processed are passed on	 *
	 *   to the user's window proc.  It is           *
	 *   responsible for passing any messages it	 *
	 *   doesn't handle onto WinDefWindowProc()      *
	\*-----------------------------------------------*/
       case HM_QUERY_KEYS_HELP:
	   return ((MRESULT)PANEL_KEYSHELP);

       default:
	   sRC = WinDefWindowProc(hwnd, msg, mp1, mp2);
	   return sRC;

    }
    return (MRESULT)0L;
		  /* all window procedures should return 0 as a default */
}						       /* MainWndProc() */

/****************************************************************\
 *  Main window WM_COMMAND processing procedure			*
 *--------------------------------------------------------------*
 *								*
 *  Name:   MainCommand(hwnd, mp1, mp2)				*
 *								*
 *  Purpose: Calls the appropriate procedures that deal with	*
 *		the selected menu item.				*
 *								*
 *  Usage:  Routine is called whenever a WM_COMMAND message	*
 *	    is posted to the main window.			*
 *								*
 *  Method: a switch statement branches on the id of the	*
 *	    menu item that posted the message and the		*
 *	    appropriate action for that item is taken.	Any	*
 *	    menu ids that are not part of the standard menu	*
 *	    set are passed onto the user defined WM_COMMAND	*
 *	    processing procedure.				*
 *								*
 *  Returns:							*
 *								*
\****************************************************************/
VOID MainCommand(HWND hwnd, MPARAM mp1, MPARAM mp2 )
{
    switch(SHORT1FROMMP(mp1))
    {
	case IDM_GENERALHELP:
	   HelpExtended(mp2);
	   break;

	case IDM_USINGHELP:
	   HelpHelpForHelp(mp2);
	   break;

	case IDM_TUTORIAL:
	   HelpKeys(mp2);
	   break;

	case IDM_HELPINDEX:
	   HelpIndex(mp2);
	   break;

	case IDM_HELPPRODUCTINFO:
	   HelpAbout(mp2);
	   break;

    /*--------------------------------------------------*\
     *	    User command processing routine is called	*
     *	    here so any ids not procecessed here can be *
     *	    processed					*
    \*--------------------------------------------------*/
	default:
	    UserCommand(mp1, mp2);
	    break;
    }
    return;
}					      /* MainCommand() */

/****************************************************************\
 *  Message Box procedure					*
 *--------------------------------------------------------------*
 *								*
 *  Name:   MessageBox(hwndOwner, nIdMsg, bBeep)		*
 *								*
 *  Purpose: Displays the warning message box with the message	*
 *		given in nIdMsg retrived from the message table *
 *								*
 *  Usage:  Called whever an error occurs and a message wishes	*
 *	    to be displayed to the user				*
 *								*
 *  Method: - Message string is loaded from the process'        *
 *		message table					*
 *	    - Alarm beep is sounded if desired			*
 *	    - Message box with the message is displayed		*
 *								*
 *  Returns:							*
 *								*
\****************************************************************/
VOID MessageBox( HWND hwndOwner, /* handle of the message box's owner      */
		 LONG nIdMsg,	/* id if the message in the message table */
		 BOOL bBeep ) /* TRUE, beep before message box is displayed*/
{
   CHAR szText[MESSAGELEN];

   if(!WinLoadMessage(hab, (HMODULE)NULL, nIdMsg, MESSAGELEN, (PSZ)szText))
   {
       WinAlarm(HWND_DESKTOP, WA_ERROR);
       return;
   }

   if(bBeep)
       WinAlarm(HWND_DESKTOP, WA_ERROR);

   WinMessageBox(HWND_DESKTOP,
		 hwndOwner,
		 szText,
		 (PSZ)NULL,
		 IDM_MSGBOX,
		 MB_OK | MB_ERROR);
   return;
}							 /* MessageBox() */
