NT4/private/oleauto/tests/common/statbar.cpp
2020-09-30 17:12:29 +02:00

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();
}