//=======================================================================
//		File:	STATUS.CPP
//		Date:	4-1-97
//		Name:
//
//		Desc:	This file contains the window procedure for the status
//				bar, as well as various initialization, termination, and
//				and utility functions.
//
//		Notes:	This file was copied from an existing Microsoft OLE 2.0
//				sample and was modified as needed.
//
//		Copyright (C) 1997 by Microsoft Corporation.  All rights reserved.
//		See bottom of file for disclaimer.
//=======================================================================

//=======================================================================
//		Include Files
//=======================================================================

#include "resource.h"
#include "status.h"



//=======================================================================
//		Defines
//=======================================================================

//----  Standard buffer size  ----
#define	SB_BUF_SIZE		32

//----  Sizes of status bar items  ----
#define STATUS_RLEFT    1
#define STATUS_RTOP     3
#define STATUS_RBOTTOM  20
#define STATUS_TTOP     4
#define STATUS_TLEFT    4
#define STATUS_THEIGHT  18



//=======================================================================
//		Static Variables
//=======================================================================

//----  Status bar window class name  ----
static TCHAR szStatusBarClassName[SB_BUF_SIZE];

//----  Current status bar message  ----
static TCHAR lpszStatusMessage[SB_BUF_SIZE * 8];



//=======================================================================
//		Private Function Prototypes
//=======================================================================

LRESULT WINAPI
StatusWndProc( HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam );



//=======================================================================
//		Private Function Definitions
//=======================================================================

//-----------------------------------------------------------------------
//	StatusWndProc()
//
//	DESCRIPTION:
//
//		Window procedure for the status bar.
//
//	PARAMETERS:
//
//		hWnd			Window handle of the status bar.
//		uMsg			Message identifier. 
//		wParam			Specifies additional message information,
//						contents depend on the value of uMsg. 
//		lParam			Specifies additional message information,
//						contents depend on the value of uMsg. 
//
//	RETURNS:
//
//		LRESULT			Value depends upon the processing of
//						the uMsg parameter.
//
//	NOTES:
//
//		Currently, only the WM_PAINT message is processed.
//		All other messages are passed on to DefWindowProc().
//
//-----------------------------------------------------------------------

LRESULT WINAPI
StatusWndProc( HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam )
{
	if ( uMsg == WM_PAINT )
	{
		RECT        rc;
		HDC         hDC;
		PAINTSTRUCT	ps;
		HPEN        hPenOld;
		HPEN        hPen;
		HFONT       hFontOld;
		HFONT       hFont;
		POINT       pt;


		//---------------------------------------------------------
		//	Call BeginPaint to initialize the PAINTSTRUCT for
		//	  this window and then get a handle to our display
		//	  device context.
		//---------------------------------------------------------

		BeginPaint( hWnd, &ps );
		hDC = GetDC( hWnd );


		//---------------------------------------------------------
		//	Get the client area of the status bar.
		//---------------------------------------------------------

		GetClientRect( hWnd, (LPRECT) &rc );


		//---------------------------------------------------------
		//	Erase the background.  This is our responsibility
		//	  because the status bar window class was defined
		//	  with a NULL background brush.
		//---------------------------------------------------------

		FillRect( hDC, (LPRECT) &rc, (HBRUSH)GetStockObject( LTGRAY_BRUSH ) );


		//---------------------------------------------------------
		//	Draw the black line that visually separates the
		//	  status bar from the rest of its parent's client area.
		//---------------------------------------------------------

		hPenOld = SelectObject( hDC, GetStockObject(BLACK_PEN) );
		MoveToEx( hDC, 0, 0, &pt );
		LineTo( hDC, rc.right, 0 );


		//---------------------------------------------------------
		//	Draw the outline of the box that will contain the
		//	  status bar text.
		//
		//	First, draw the right and bottom lines of the box
		//	  in white; ...
		//---------------------------------------------------------

		SelectObject( hDC, GetStockObject(WHITE_PEN) );
		MoveToEx( hDC, rc.right-1, STATUS_RTOP, &pt );
		LineTo( hDC, rc.right-1, STATUS_RBOTTOM );
		LineTo( hDC, STATUS_RLEFT-1, STATUS_RBOTTOM );


		//---------------------------------------------------------
		//	  then, draw the left and top lines of the box in
		//	  dark gray.
		//---------------------------------------------------------

		hPen = CreatePen( PS_SOLID, 1, /* DKGRAY */ 0x00808080 );
		SelectObject( hDC, hPen );
		MoveToEx( hDC, STATUS_RLEFT, STATUS_RBOTTOM-1, &pt );
		LineTo( hDC, STATUS_RLEFT, STATUS_RTOP );
		LineTo( hDC, rc.right-1, STATUS_RTOP );


		//---------------------------------------------------------
		//	Prepare for writing the status bar text.
		//
		//	Set the background mode to transparent for the
		//	  current pen.
		//---------------------------------------------------------

		SetBkMode( hDC, TRANSPARENT );


		//---------------------------------------------------------
		//	Set the text alignment reference point to the
		//	  upper-left corner.
		//---------------------------------------------------------

		SetTextAlign( hDC, TA_LEFT | TA_TOP );


		//---------------------------------------------------------
		//	Create and select the desired font.
		//---------------------------------------------------------

		hFont = CreateFont( STATUS_THEIGHT, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
		                    FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
		                    CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		                    DEFAULT_PITCH | FF_DONTCARE, "MS Sans Serif" );
		hFontOld = SelectObject( hDC, hFont );


		//---------------------------------------------------------
		//	Add the right most portion of the client area
		//	  to the clipping region so that the text is not
		//	  written over right edge of the box.
		//---------------------------------------------------------

		ExcludeClipRect( hDC, rc.right-3, rc.top, rc.right, rc.bottom );


		//---------------------------------------------------------
		//	Write the status bar text.
		//---------------------------------------------------------

		TextOut( hDC, STATUS_TLEFT, STATUS_TTOP,
		         lpszStatusMessage, lstrlen( lpszStatusMessage ) );


		//---------------------------------------------------------
		//	Restore the original pen and font.
		//---------------------------------------------------------

		SelectObject( hDC, hFontOld );
		SelectObject( hDC, hPenOld );
		DeleteObject( hPen );
		DeleteObject( hFont );


		//---------------------------------------------------------
		//	Release the handle to our display device context
		//	  and terminate the paint session.
		//---------------------------------------------------------

		ReleaseDC( hWnd, hDC );
		EndPaint( hWnd, &ps );


		return 0L;
	}
	else
		//---------------------------------------------------------
		//	Call DefWindowProc() for all unhandled window messages.
		//---------------------------------------------------------

		return DefWindowProc( hWnd, uMsg, wParam, lParam );
}





//=======================================================================
//		Public Function Definitions
//=======================================================================

//-----------------------------------------------------------------------
//	StatusBar_RegisterWndClass()
//
//	DESCRIPTION:
//
//		Defines and registers the window class of the status bar.
//
//	PARAMETERS:
//
//		hInst			Handle of the application instance.
//
//	RETURNS:
//
//		BOOL			TRUE if class successfully registered,
//						FALSE otherwise.
//
//-----------------------------------------------------------------------

BOOL StatusBar_RegisterWndClass( HINSTANCE hInst )
{
	WNDCLASS  wc;


	//---------------------------------------------------------
    //	Load the window class name from the string table.
	//---------------------------------------------------------

	if ( LoadString( hInst, IDS_STATUSBARWINDOWCLASSNAME,
					 (LPTSTR) szStatusBarClassName, SB_BUF_SIZE ) < 1 )
		return FALSE;

	//---------------------------------------------------------
    //	Register the class.
	//---------------------------------------------------------

	wc.lpszClassName = szStatusBarClassName;
	wc.lpfnWndProc   = StatusWndProc;
	wc.style         = 0;
	wc.hInstance     = hInst;
	wc.hIcon         = NULL;
	wc.cbClsExtra    = 4;
	wc.cbWndExtra    = 0;
	wc.lpszMenuName  = NULL;
	wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground = NULL;

	if ( !RegisterClass( &wc ) )
		return FALSE;

	return TRUE;
}




//-----------------------------------------------------------------------
//	StatusBar_CreateWnd()
//
//	DESCRIPTION:
//
//		Creates status bar window.
//
//	PARAMETERS:
//
//		hWndApp			Window handle of the application.
//
//	RETURNS:
//
//		BOOL			HWND of status bar if its creation succeeds,
//						NULL otherwise.
//
//-----------------------------------------------------------------------

HWND StatusBar_CreateWnd( HWND hWndApp, HINSTANCE hInst )
{
	RECT	rect;
	int		width, height;
	TCHAR	szSBWindowName[SB_BUF_SIZE];


	//---------------------------------------------------------
    //	Load the window name from the string table.
	//---------------------------------------------------------

	if ( LoadString( hInst, IDS_STATUSBARWINDOWNAME,
					 (LPTSTR) szSBWindowName, SB_BUF_SIZE ) < 1 )
		return (HWND) NULL;


	//---------------------------------------------------------
    //	Determine the size of the status bar based on the
	//	  size of the application window's client area.
	//---------------------------------------------------------

	GetClientRect( hWndApp, &rect );
	width = rect.right - rect.left;
	height = rect.bottom - rect.top;


	//---------------------------------------------------------
    //	Create the status bar window.
	//---------------------------------------------------------

	return CreateWindow (
		szStatusBarClassName,
		szSBWindowName,
		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
		0,
		height - STATUS_HEIGHT,
		width,
		STATUS_HEIGHT,
		hWndApp,
		NULL,
		hInst,
		NULL );
}




//-----------------------------------------------------------------------
//	StatusBar_DestroyWnd()
//
//	DESCRIPTION:
//
//		Destroys the status bar window.
//
//	PARAMETERS:
//
//		lphWnd			Pointer to the status bar window handle.
//
//	RETURNS:
//
//		None.
//
//-----------------------------------------------------------------------

void StatusBar_DestroyWnd( HWND* lphWnd )
{
	DestroyWindow( *lphWnd );
	*lphWnd = NULL;
}



//-----------------------------------------------------------------------
//	StatusBar_ResizeWnd()
//
//	DESCRIPTION:
//
//		Resizes the status bar window based upon the new size of the
//		application's client area.
//
//	PARAMETERS:
//
//		hWndApp			Window handle of the application.
//		hWnd			Window handle of the status bar.
//
//	RETURNS:
//
//		BOOL			The success or failure of MoveWindow().
//
//-----------------------------------------------------------------------

BOOL StatusBar_ResizeWnd( HWND hWndApp, HWND hWnd )
{
	RECT	rect;
	int		width, height;


	GetClientRect( hWndApp, &rect );
	width = rect.right - rect.left;
	height = rect.bottom - rect.top;


	return MoveWindow(
		hWnd,
		0,
		height - STATUS_HEIGHT,
		width,
		STATUS_HEIGHT,
		TRUE );
}



//-----------------------------------------------------------------------
//	StatusBar_SetText()
//
//	DESCRIPTION:
//
//		Updates the message in the status line.
//
//	PARAMETERS:
//
//		hWnd			Window handle of the status bar.
//		lpszMessage		String to be displayed in the status bar.
//
//	RETURNS:
//
//		None.
//
//-----------------------------------------------------------------------

void StatusBar_SetText( HWND hWnd, LPTSTR lpszMessage )
{
	lstrcpy( lpszStatusMessage, lpszMessage );
	InvalidateRect( hWnd, (LPRECT)NULL, TRUE );
	UpdateWindow( hWnd );
}





/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//  MSAA SUPPORT ADDITION:                                                 //
//                                                                         //
//  Function for obtaining the status bar's current text.  (For MSAA,      //
//    the status bar's current text is its current value.)                 //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------
//	StatusBar_GetText()
//
//	DESCRIPTION:
//
//		Returns a pointer to a buffer containing the current status
//		bar text.
//
//	PARAMETERS:
//
//		None.
//
//	RETURNS:
//
//		LPCTSTR			Pointer to the current status bar text.
//
//-----------------------------------------------------------------------

LPCTSTR StatusBar_GetText( void )
{
	return (LPCTSTR) lpszStatusMessage;
}



/*************************************************************************
    THE INFORMATION AND CODE PROVIDED HEREUNDER (COLLECTIVELY REFERRED TO
    AS "SOFTWARE") IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
    NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR
    ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL,
    CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF
    MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR
    LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE
    FOREGOING LIMITATION MAY NOT APPLY.
*************************************************************************/


//----  End of STATUS.CPP  ----