375 lines
7.5 KiB
C++
375 lines
7.5 KiB
C++
|
/***
|
||
|
*statbar.cpp
|
||
|
*
|
||
|
* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved.
|
||
|
* Information Contained Herein Is Proprietary and Confidential.
|
||
|
*
|
||
|
*Purpose:
|
||
|
*
|
||
|
*Implementation Notes:
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "common.h"
|
||
|
#include "statbar.h"
|
||
|
|
||
|
|
||
|
extern "C" long FAR PASCAL StatBarWndProc(HWND, UINT, WPARAM, LPARAM);
|
||
|
|
||
|
|
||
|
TCHAR FAR* CStatBar::m_szWndClass = TSTR("StatBarWndClass");
|
||
|
|
||
|
|
||
|
CStatBar::CStatBar()
|
||
|
{
|
||
|
m_refs = 0;
|
||
|
|
||
|
m_x = 0;
|
||
|
m_y = 0;
|
||
|
m_width = 0;
|
||
|
m_height = 0;
|
||
|
|
||
|
m_bstrMsg = NULL;
|
||
|
|
||
|
m_hfont = (HFONT)0;
|
||
|
}
|
||
|
|
||
|
CStatBar::~CStatBar()
|
||
|
{
|
||
|
SysFreeString(m_bstrMsg);
|
||
|
}
|
||
|
|
||
|
|
||
|
/***
|
||
|
*PUBLIC CStatBar FAR* CStatBar::Create(HANDLE, HWND)
|
||
|
*
|
||
|
*Purpose:
|
||
|
*
|
||
|
*Entry:
|
||
|
*
|
||
|
*Exit:
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
CStatBar FAR*
|
||
|
CStatBar::Create(HANDLE hinst, HWND hwndFrame)
|
||
|
{
|
||
|
CStatBar FAR* psb;
|
||
|
|
||
|
psb = new FAR CStatBar();
|
||
|
if(psb == NULL)
|
||
|
return NULL;
|
||
|
psb->AddRef();
|
||
|
|
||
|
if(!psb->Register(hinst))
|
||
|
goto LFail;
|
||
|
|
||
|
psb->m_hwnd = CreateWindow(
|
||
|
CStatBar::m_szWndClass,
|
||
|
NULL,
|
||
|
WS_CHILD | WS_CLIPSIBLINGS,
|
||
|
0, 0, 0, 0,
|
||
|
hwndFrame,
|
||
|
0,
|
||
|
(HINSTANCE)hinst,
|
||
|
NULL);
|
||
|
|
||
|
if(!psb->m_hwnd)
|
||
|
goto LFail;
|
||
|
|
||
|
// Stash the newly created CStatBar* in the extra bytes of the
|
||
|
// associated window so we can get at the instance in the message
|
||
|
// proc.
|
||
|
//
|
||
|
// Note: we do not AddRef for this reference. We make sure that the
|
||
|
// window is destroyed when the refcnt goes to 0.
|
||
|
//
|
||
|
SetWindowLong(psb->m_hwnd, 0, (LONG)psb);
|
||
|
|
||
|
return psb;
|
||
|
|
||
|
LFail:;
|
||
|
delete psb;
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------
|
||
|
// IUnknown Methods
|
||
|
//---------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CStatBar::QueryInterface(REFIID riid, void FAR* FAR* ppv)
|
||
|
{
|
||
|
if(IsEqualIID(riid, IID_IUnknown)){
|
||
|
*ppv = this;
|
||
|
AddRef();
|
||
|
return NOERROR;
|
||
|
}
|
||
|
*ppv = (void FAR*)NULL;
|
||
|
return ResultFromScode(E_NOINTERFACE);
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(unsigned long)
|
||
|
CStatBar::AddRef(void)
|
||
|
{
|
||
|
return ++m_refs;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(unsigned long)
|
||
|
CStatBar::Release(void)
|
||
|
{
|
||
|
if(--m_refs == 0){
|
||
|
|
||
|
// destroy the status bar window.
|
||
|
//
|
||
|
SendMessage(m_hwnd, WM_DESTROY, 0, 0L);
|
||
|
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return m_refs;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------
|
||
|
// Introduced Methods
|
||
|
//---------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
/***
|
||
|
*PRIVATE BOOL CStatBar::Register(HANDLE)
|
||
|
*
|
||
|
*Purpose:
|
||
|
* Register the status bar window class.
|
||
|
*
|
||
|
*Entry:
|
||
|
* None
|
||
|
*
|
||
|
*Exit:
|
||
|
* return value = BOOL, TRUE if successful, FALSE if not.
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
BOOL
|
||
|
CStatBar::Register(HANDLE hinst)
|
||
|
{
|
||
|
WNDCLASS wc;
|
||
|
|
||
|
// register the class, unless already registered.
|
||
|
if(GetClassInfo((HINSTANCE)hinst, m_szWndClass, &wc) == 0){
|
||
|
wc.style = 0;
|
||
|
wc.lpfnWndProc = StatBarWndProc;
|
||
|
wc.cbClsExtra = 0;
|
||
|
wc.cbWndExtra = sizeof(CStatBar FAR*);
|
||
|
wc.hInstance = (HINSTANCE)hinst;
|
||
|
wc.hIcon = 0;
|
||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
|
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
|
||
|
wc.lpszMenuName = 0;
|
||
|
wc.lpszClassName = CStatBar::m_szWndClass;
|
||
|
if(!RegisterClass(&wc))
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***
|
||
|
*PUBLIC void CStatBar::Show(void)
|
||
|
*
|
||
|
*Purpose:
|
||
|
* Show the status bar window associated with this CStatBar instance.
|
||
|
*
|
||
|
*Entry:
|
||
|
* None
|
||
|
*
|
||
|
*Exit:
|
||
|
* None
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
void
|
||
|
CStatBar::Show()
|
||
|
{
|
||
|
ShowWindow(m_hwnd, SW_SHOW);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CStatBar::SetFont(HFONT hfont)
|
||
|
{
|
||
|
HDC hdc;
|
||
|
TEXTMETRIC tm;
|
||
|
HFONT hfontOld;
|
||
|
|
||
|
// compute the character sizes given this new font.
|
||
|
//
|
||
|
hdc = GetDC(m_hwnd);
|
||
|
hfontOld = (HFONT)SelectObject(hdc, hfont);
|
||
|
GetTextMetrics(hdc, &tm);
|
||
|
m_dxFont = tm.tmAveCharWidth;
|
||
|
m_dyFont = tm.tmHeight + tm.tmExternalLeading;
|
||
|
SelectObject(hdc, hfontOld);
|
||
|
ReleaseDC(m_hwnd, hdc);
|
||
|
|
||
|
m_hfont = hfont;
|
||
|
}
|
||
|
|
||
|
/***
|
||
|
*PRIVATE CStatBar::WMPaint(void)
|
||
|
*
|
||
|
*Purpose:
|
||
|
* This method is responsible for drawing the status bar, and is called
|
||
|
* in response to a WM_PAINT message.
|
||
|
*
|
||
|
*Entry:
|
||
|
* None
|
||
|
*
|
||
|
*Exit:
|
||
|
* None
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
void
|
||
|
CStatBar::WMPaint()
|
||
|
{
|
||
|
HDC hdc;
|
||
|
RECT rcMsg;
|
||
|
HRGN hrgn;
|
||
|
HFONT hfontOld;
|
||
|
PAINTSTRUCT ps;
|
||
|
HPEN hpenBlack, hpenWhite, hpenGray, hpenOld;
|
||
|
|
||
|
hdc = BeginPaint(m_hwnd, &ps);
|
||
|
|
||
|
// compute the message box rect
|
||
|
//
|
||
|
rcMsg.top = 3;
|
||
|
rcMsg.bottom= m_height - 3;
|
||
|
rcMsg.left = m_dxFont;
|
||
|
rcMsg.right = m_width - m_dxFont;
|
||
|
|
||
|
// prepare the pens
|
||
|
//
|
||
|
hpenWhite = (HPEN)GetStockObject(WHITE_PEN);
|
||
|
hpenBlack = (HPEN)GetStockObject(BLACK_PEN);
|
||
|
hpenGray = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
|
||
|
|
||
|
// draw a top gray line
|
||
|
//
|
||
|
hpenOld = (HPEN)SelectObject(hdc, hpenGray);
|
||
|
#if defined(WIN16)
|
||
|
MoveTo(hdc, ps.rcPaint.left, 0);
|
||
|
#elif defined(WIN32)
|
||
|
MoveToEx(hdc, ps.rcPaint.left, 0, NULL);
|
||
|
#endif
|
||
|
LineTo(hdc, ps.rcPaint.right, 0);
|
||
|
|
||
|
// draw a white line just under
|
||
|
//
|
||
|
SelectObject(hdc, hpenWhite);
|
||
|
#if defined(WIN16)
|
||
|
MoveTo(hdc, ps.rcPaint.left, 1);
|
||
|
#elif defined(WIN32)
|
||
|
MoveToEx(hdc, ps.rcPaint.left, 1, NULL);
|
||
|
#endif
|
||
|
LineTo(hdc, ps.rcPaint.right, 1);
|
||
|
|
||
|
// do not overwrite the background color
|
||
|
//
|
||
|
SetBkMode(hdc, TRANSPARENT);
|
||
|
|
||
|
// message area
|
||
|
//
|
||
|
SelectObject(hdc, hpenBlack);
|
||
|
#if defined(WIN16)
|
||
|
MoveTo(hdc, rcMsg.left, rcMsg.bottom);
|
||
|
#elif defined(WIN32)
|
||
|
MoveToEx(hdc, rcMsg.left, rcMsg.bottom, NULL);
|
||
|
#endif
|
||
|
LineTo(hdc, rcMsg.left, rcMsg.top);
|
||
|
LineTo(hdc, rcMsg.right, rcMsg.top);
|
||
|
|
||
|
SelectObject(hdc, hpenWhite);
|
||
|
LineTo(hdc, rcMsg.right, rcMsg.bottom);
|
||
|
LineTo(hdc, rcMsg.left, rcMsg.bottom);
|
||
|
|
||
|
// select the black pen for writing
|
||
|
//
|
||
|
SelectObject(hdc, hpenBlack);
|
||
|
|
||
|
// select the status bar font to write in
|
||
|
//
|
||
|
hfontOld = (HFONT)SelectObject(hdc, m_hfont);
|
||
|
|
||
|
// set the clipping region
|
||
|
//
|
||
|
hrgn = CreateRectRgn(
|
||
|
rcMsg.left, rcMsg.top, rcMsg.right, rcMsg.bottom);
|
||
|
|
||
|
SelectClipRgn(hdc, hrgn);
|
||
|
|
||
|
// draw the status message
|
||
|
//
|
||
|
TextOut(
|
||
|
hdc,
|
||
|
rcMsg.left + (m_dxFont / 2),
|
||
|
rcMsg.top + ((rcMsg.bottom - rcMsg.top - m_dyFont) / 2),
|
||
|
STRING(m_bstrMsg), SysStringLen(m_bstrMsg));
|
||
|
|
||
|
// cleanup
|
||
|
//
|
||
|
SelectObject(hdc, hpenOld);
|
||
|
SelectObject(hdc, hfontOld);
|
||
|
|
||
|
DeleteObject(hrgn);
|
||
|
DeleteObject(hpenGray);
|
||
|
|
||
|
EndPaint(m_hwnd, &ps);
|
||
|
}
|
||
|
|
||
|
extern "C" long FAR PASCAL
|
||
|
StatBarWndProc(
|
||
|
HWND hwnd,
|
||
|
UINT message,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam)
|
||
|
{
|
||
|
CStatBar FAR* psb;
|
||
|
|
||
|
switch(message){
|
||
|
case WM_SIZE:
|
||
|
return 0;
|
||
|
case WM_PAINT:
|
||
|
psb = (CStatBar FAR*)GetWindowLong(hwnd, 0);
|
||
|
psb->WMPaint();
|
||
|
return 0;
|
||
|
}
|
||
|
return(DefWindowProc(hwnd, message, wParam, lParam));
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------
|
||
|
// Status Bar Utilities
|
||
|
//---------------------------------------------------------------------
|
||
|
|
||
|
extern "C" void
|
||
|
SBprintf(CStatBar FAR* psb, char FAR* szFmt, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
static char buf[1024];
|
||
|
|
||
|
va_start(args, szFmt);
|
||
|
#if defined(WIN32)
|
||
|
wvsprintfA(buf, szFmt, args);
|
||
|
#else
|
||
|
wvsprintf(buf, szFmt, args);
|
||
|
#endif
|
||
|
psb->SetText(buf);
|
||
|
psb->Update();
|
||
|
}
|