// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993, 1994  Microsoft Corporation.  All Rights Reserved.
//
//  MODULE: statbar.c
//
//  PURPOSE: Handles general routines for the Barsdi sample.
//
//  FUNCTIONS:
//    MsgTimer      - Handles the WM_TIMER messages to set the time on
//                    the status bar.
//    MsgMenuSelect - Handle the WM_MENUSELECT message. This message will
//                    enable the status bar control to update when the user
//                    moves across menu items on the main window.
//    InitializeStatusBar - Initialize statusbar control with time and
//                    mouse positions.
//    CreateSBar    - Calls CreateStatusWindow() to create the status bar
//    UpdateStatusBar - Updates the statusbar control with appropriate text
//

#include <windows.h>            // required for all Windows applications
#include <windowsx.h>
#include <commctrl.h>           // prototypes and defs for common controls
#include "globals.h"            // prototypes specific to this application
#include "statbar.h"            // prototypes specific to statbar.c


// Global Variables for the status bar control.

HWND  hWndStatusbar;
UINT  timerID;

/**********************************************************************

PROTOTYPE WARNING:

CreateStatusWindow() is not prototyped in Commctrl.h, and hence when
you compile this sample, you will  get an unresolved external. Until the
header file is updated, use the prototype define below.

************************************************************************/

HWND WINAPI CreateStatusWindow(LONG style,
                               LPCSTR lpszText,
                               HWND hwndParent,
                               UINT wID);

//
//  FUNCTION: MsgTimer(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE: Calls GetSystemTime() to set the time on the status bar
//
//
//  PARAMETERS:
//
//    hwnd      - Window handle  (Unused)
//    uMessage  - Message number (Unused)
//    wparam    - Extra data     (Unused)
//    lparam    - Extra data     (Unused)
//
//  RETURN VALUE:
//
//    Always returns 0 - Message handled
//
//  COMMENTS:
//
//    Every time the window procedure receives a Timer message, it calls
//    GetSystemTime() to obtain the time and then formats the time into
//    a string. The time sting is then displayed on the status bar.
//

LRESULT MsgTimer(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
{
    char        szBuf[16];      // Temp buffer.
    SYSTEMTIME  sysTime;


    GetLocalTime(&sysTime);

    wsprintf(szBuf,
             "%2d:%02d:%02d %s",
             (sysTime.wHour == 0 ? 12 :
             (sysTime.wHour <= 12 ? sysTime.wHour : sysTime.wHour -12)),
             sysTime.wMinute,
             sysTime.wSecond,
             (sysTime.wHour < 12 ? "AM":"PM"));

    UpdateStatusBar(szBuf, 2, 0);
    return 0;
}


//
//  FUNCTION: MsgMenuSelect(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Upadates menu selections on the staus bar.
//
//
//  PARAMETERS:
//
//    hwnd      - Window handle  (Used)
//    uMessage  - Message number (Used)
//    wparam    - Extra data     (Used)
//    lparam    - Extra data     (Used)
//
//  RETURN VALUE:
//
//    Always returns 0 - Message handled
//
//  COMMENTS:
//    This message is sent when the user selects menu items by
//    by pulling down  a popup menu move the mouse around to highlite
//    different menu items.
//
//

#define MENUHACK 1              // Menu Select message has a bug..so workaround

LRESULT MsgMenuSelect(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
{
    static char szBuffer[128];
    static UINT idPopup[] = {IDM_FILE, IDM_OPTIONS, IDM_WINDOW, IDM_ABOUT};
    UINT   nStringID;
    WORD   fwFlags = GET_WM_MENUSELECT_FLAGS(wparam, lparam);
    WORD   wCmd    = GET_WM_MENUSELECT_CMD(wparam, lparam);


    szBuffer[0] = 0;                            // reset buffer

    if (fwFlags & MF_SYSMENU)                   // System menu
    {
        HMENU  hSysMenu = GetSystemMenu(hwnd, FALSE);

        if (wCmd == GetMenuItemID(hSysMenu, 0))
            nStringID = IDS_RESTORE;
        else if (wCmd == GetMenuItemID(hSysMenu, 1))
            nStringID = IDS_MOVE;
        else if (wCmd == GetMenuItemID(hSysMenu, 2))
            nStringID = IDS_SIZE;
        else if (wCmd == GetMenuItemID(hSysMenu, 3))
            nStringID = IDS_MINIMIZE;
        else if (wCmd == GetMenuItemID(hSysMenu, 4))
            nStringID = IDS_MAXIMIZE;
        else if (wCmd == GetMenuItemID(hSysMenu, 6))
            nStringID = IDS_CLOSE;
        else if (wCmd == GetMenuItemID(hSysMenu, 8))
            nStringID = IDS_SWITCHTO;

      /*
       * if the System Menu is popped down OR
       * the user clicks on a system menu item and moves away from the menu.
       */
        else if (wCmd == LOWORD(hSysMenu))
            nStringID = IDS_SYSMENU;

        else
        {
            if (LOWORD(lparam) == 0)            // Menu has closed
                nStringID = IDS_DESCRIPTION;
            else                                // Must be a separator
                nStringID = 0;
        }
    }

    else if (fwFlags & MF_POPUP)                // Popup menu
    {
#ifdef MENUHACK                 // This is wrong but works...
        HMENU hMenu = GET_WM_MENUSELECT_HMENU(wparam, lparam);

        if(GetSubMenu(hMenu, 0) == (HMENU)wCmd)
            nStringID = IDM_FILE;

        else if(GetSubMenu(hMenu, 1) == (HMENU)wCmd)
            nStringID = IDM_ABOUT;

        else
            nStringID = 0;
#else
        nStringID = ((wCmd < sizeof(idPopup)/sizeof(UINT)) ?
                        idPopup[wCmd] : 0);
#endif
    }  // for MF_POPUP

    else                                        // Must be a command item
        nStringID = wCmd;                       // String ID == Command ID

    // Load the string if we have an ID
    if (0 != nStringID)
        LoadString(hInst, nStringID, szBuffer, sizeof(szBuffer));

    UpdateStatusBar(szBuffer, 0, 0);

    return 0;
}


//
//  FUNCTION: InitializeStatusBar(HWND)
//
//  PURPOSE:  Initialize statusbar control with time and mouse positions.
//
//
//  PARAMETERS:
//
//  hwnd - Window handle : Used for the hWndParent parameter of the controls.
//
//
//  RETURN VALUE:  NONE
//
//
//  COMMENTS:
//
//   This function initializes the time  and mouse positions sections of
//   the statubar window. The Date for the time section is obtained by
//   calling SetTimer API. When the timer messages start comming in,
//   GetSytemTime() to fill the time section.
//   The WPARAM of SB_SETTEXT is divided into 2 parameters. The LOWORD
//   determines which section/part the text goes into, and the HIWORD
//   tells how the bar is drawn (popin or popout).
//

void InitializeStatusBar(HWND hwnd)
{
    const cSpaceInBetween = 2;
    int   ptArray[3];   // Array defining the number of parts/sections
    SIZE  size;         // the Status bar will display.
    RECT  rect;
    HDC   hDC;
    
   /*
    * Fill in the ptArray...
    */

    hDC = GetDC(hwnd);
    GetClientRect(hwnd, &rect);

    ptArray[2] = rect.right;

    if (GetTextExtentPoint(hDC, "00:00:00 PM", 11, &size))
        ptArray[1] = ptArray[2] - (size.cx) - cSpaceInBetween;
    else
        ptArray[1] = 0;

    if (GetTextExtentPoint(hDC, "Messages", 8, &size))
        ptArray[0] = ptArray[1] - (size.cx) - cSpaceInBetween;
    else
        ptArray[0] = 0;

	ReleaseDC (hwnd, hDC);

    SendMessage(hWndStatusbar, SB_SETPARTS, 3, (LPARAM)(LPINT)ptArray);
    SendMessage(hWndStatusbar,
                SB_SETTEXT,
                (WPARAM) 0|0,
                (LPARAM)(LPSTR)SZDESCRIPTION);

    timerID = SetTimer(hwnd, IDM_TIMER, TIMER_TIMEOUT, (TIMERPROC)NULL);
    if(!timerID)
        MessageBox(hwnd,
                   "TIMER COULD NOT BE CREATED",
                   "TIMER",
                   MB_OK | MB_ICONHAND);
}


//
//  FUNCTION: CreateSBar(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Calls CreateStatusWindow() to create the status bar
//
//
//  PARAMETERS:
//
//  hwnd - Window handle : Used for the hWndParent parameter of the controls.
//
//  RETURN VALUE:
//
//  If both controls were created successfully Return TRUE,
//  else returns FALSE.
//
//  COMMENTS:
//
//

BOOL CreateSBar(HWND hwnd)
{
    BOOL bSuccess = FALSE;  // Return Value for the function.

    hWndStatusbar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | WS_BORDER,
                                      SZDESCRIPTION,
                                      hwnd,
                                      IDM_STATUSBAR);
    if(hWndStatusbar)
    {
        InitializeStatusBar(hwnd);
        bSuccess = TRUE;
    }
    return bSuccess;
}


//
//  FUNCTION: UpdateStatusBar(HWND)
//
//  PURPOSE:  Updates the statusbar control with appropriate text
//
//
//  PARAMETERS:
//
//  lpszStatusString - text to be displayed
//  partNumber       - which part of the status bar to display text in
//  displayFlags     - display flags
//
//
//  RETURN VALUE: NONE
//
//
//  COMMENTS:
//      None
//
//

void UpdateStatusBar(LPSTR lpszStatusString, WORD partNumber, WORD displayFlags)
{
    LRESULT lReturn=0;

    lReturn = SendMessage(hWndStatusbar,
                          SB_SETTEXT,
                          partNumber|displayFlags,
                          (LPARAM)(LPSTR)lpszStatusString);

	if (FALSE == lReturn)
	{
		MessageBox (NULL, "Error posting message to the status bar", "Error",
					MB_OK | MB_ICONINFORMATION);

	}
}


