NT4/private/windows/media/sndrec32/o2base/status.cxx
2020-09-30 17:12:29 +02:00

382 lines
11 KiB
C++

//+-------------------------------------------------------------------
//
// File: status.cxx
//
// Contents: Functions implementing status bar.
//
// Classes: StatusBar
//
//--------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
TCHAR FAR lpstrStatBarClass[] = TEXT("classStatBar");
//+---------------------------------------------------------------
//
// Function: _PatB, private
//
// Synopsis: inline helper to fill rectangle with a color
//
//----------------------------------------------------------------
inline void _PatB(HDC hdc, int x, int y, int dx, int dy, COLORREF rgb)
{
RECT rc;
SetRect(&rc, x, y, x+dx, y+dy);
SetBkColor(hdc, rgb);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
};
//+---------------------------------------------------------------
//
// Member: StatusBar::ClassInit
//
// Synopsis: Registers the status bar window class
//
// Arguments: [hinst] -- instance handle of module using status bar
//
// Returns: TRUE iff the status bar was registered successfully
//
// Notes: This static method is usually called from the WinMain
// or LibMain of the module using the status bar.
//
//----------------------------------------------------------------
BOOL StatusBar::ClassInit(HINSTANCE hinst)
{
WNDCLASS wc;
wc.style = 0L;
wc.lpfnWndProc = StatusWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(void FAR*);
wc.hInstance = hinst;
wc.hIcon = NULL;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = lpstrStatBarClass;
return RegisterClass(&wc)!=NULL;
}
//+---------------------------------------------------------------
//
// Member: StatusBar::StatusBar, public
//
// Synopsis: Constructor for status bar class
//
// Notes: Creating a status bar is a two step process.
// First construct the object, then call the
// Init method to actually create the status bar window.
//
//----------------------------------------------------------------
StatusBar::StatusBar()
{
_hwnd = NULL;
_hfont = NULL;
_wHeight = (WORD)-1;
_wUnitBorder = (WORD)-1;
_wSpace = 6;
_wAboveBelow = 2;
lstrcpy(_lpstrString, TEXT(""));
}
//+---------------------------------------------------------------
//
// Member: StatusBar::~StatusBar, public
//
// Synopsis: Destructor for status bar class
//
// Notes: This frees any resources held by the status bar
// including deleting the window
//
//----------------------------------------------------------------
StatusBar::~StatusBar()
{
if (_hfont != NULL)
DeleteObject(_hfont);
if (_hwnd != NULL)
DestroyWindow(_hwnd);
}
//+-------------------------------------------------------------------
//
// Member: StatusBar::Init, public
//
// Synopsis: Creates a status bar window as a child of another window
//
// Arguments: [hwnd] -- the window handle of the parent window
//
// Returns: The window handle of the status bar child window
//
//--------------------------------------------------------------------
HWND
StatusBar::Init(HINSTANCE hinst, HWND hwndParent)
{
//
// create font, save handle, find height of status bar.
//
HDC hdc = GetDC(NULL);
int iFontHeight;
TEXTMETRIC tm;
iFontHeight = MulDiv(-10, GetDeviceCaps(hdc, LOGPIXELSY), 72);
_hfont = CreateFont(iFontHeight, 0, 0, 0, 400, 0, 0, 0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
VARIABLE_PITCH | FF_SWISS,
TEXT("Helv"));
HFONT hfontOld = SelectFont(hdc, _hfont);
GetTextMetrics(hdc, &tm);
SelectObject(hdc, hfontOld);
ReleaseDC(NULL, hdc);
_wUnitBorder = GetSystemMetrics(SM_CYBORDER);
_wHeight = tm.tmHeight + tm.tmExternalLeading + // font height
4 + // 2 above/below
_wUnitBorder + // for border
_wAboveBelow * 2; // above and below
//
// create window
//
RECT rc;
GetClientRect(hwndParent, &rc);
// this will automatically set _hwnd!
CreateWindowEx(0L, // extended style
lpstrStatBarClass,
NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER, // style
0, rc.bottom - _wHeight, // x, y
rc.right - rc.left, _wHeight, // cx, cy
hwndParent, // hwndParent
NULL, // hmenu
hinst,
this); // lpParam
return _hwnd;
}
//+---------------------------------------------------------------
//
// Member: StatusBar::OnSize, public
//
// Synopsis: Updates the position of the status bar when the
// parent is resized
//
// Arguments: [lprc] -- client rectangle of parent window
//
// Notes: The parent window should call this method during
// WM_SIZE processing. The parent should get its client
// rectangle and pass it to this method. This method will
// move the status bar window to occupy the bottom of
// the window and will update the rectangle to remove its
// area (i.e. the returned rectangle is the parent windows'
// new, effective client area).
//
//----------------------------------------------------------------
void
StatusBar::OnSize(LPRECT lprc)
{
lprc->bottom -= _wHeight;
MoveWindow(_hwnd, 0, lprc->bottom, lprc->right-lprc->left, _wHeight, TRUE);
InvalidateRect(_hwnd, NULL, TRUE);
}
//+-------------------------------------------------------------------
//
// Member: StatusBar::DisplayMessage, public
//
// Synopsis: Displays a string on the status bar
//
// Arguments: [lpstr] -- string to display in status bar. NULL
// means just clear the current message.
//
//--------------------------------------------------------------------
void
StatusBar::DisplayMessage(LPCTSTR lpstr)
{
HDC hdc = GetDC(_hwnd);
RECT rc;
GetClientRect(_hwnd, &rc);
InflateRect(&rc, -1, -1);
rc.left += _wSpace;
rc.top += _wAboveBelow;
rc.right -= _wSpace;
rc.bottom -= _wAboveBelow;
InflateRect(&rc, -1, -1);
HFONT hfontOld = SelectFont(hdc, _hfont);
// clear out the old message
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE|ETO_CLIPPED, &rc, NULL, 0, NULL);
// put up the new status message
if (lpstr != NULL)
{
lstrcpy(_lpstrString, lpstr);
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
ExtTextOut(hdc,
rc.left,
rc.top,
ETO_OPAQUE | ETO_CLIPPED,
&rc,
_lpstrString,
lstrlen(_lpstrString),
(LPINT) NULL);
}
SelectObject(hdc, hfontOld);
ReleaseDC(_hwnd, hdc);
}
//+---------------------------------------------------------------
//
// Function: StatusWndProc, private
//
// Synopsis: Window procedure for status bar window
//
//----------------------------------------------------------------
extern "C" LRESULT CALLBACK
StatusWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
//
//get a pointer to our object
//
LPSTATUSBAR pStatusBar = (LPSTATUSBAR)GetWindowLong(hwnd, 0);
//
//if it is NULL, then check for a WM_NCCREATE message
// when we get one stash the pointer to our object
//
if(pStatusBar == NULL)
{
if(msg == WM_NCCREATE)
{
CREATESTRUCT FAR *lpcs = (CREATESTRUCT FAR *)lParam;
pStatusBar = (LPSTATUSBAR)lpcs->lpCreateParams;
pStatusBar->_hwnd = hwnd;
SetWindowLong(hwnd, 0, (LONG)pStatusBar);
//drop through to forward the message
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
if(msg == WM_NCDESTROY)
{
SetWindowLong(hwnd, 0, 0L);
pStatusBar->_hwnd = NULL;
//drop through to forward the message to the window procedure
}
//handle any window message by passing it to the appropriate
//member function...
switch(msg)
{
HANDLE_MSG(hwnd, WM_PAINT, pStatusBar->OnPaint);
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
//+---------------------------------------------------------------
//
// Member: StatusBar::OnPaint, private
//
// Synopsis: Handles the WM_PAINT message for the status bar window
//
//----------------------------------------------------------------
void
StatusBar::OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(hwnd, &ps);
RECT rc;
COLORREF rgbT;
// compute rectangle
GetClientRect(hwnd, &rc);
//
// draw highlight and shadow
//
rgbT = GetSysColor(COLOR_BTNHIGHLIGHT);
// left and top
_PatB(hdc, rc.left, rc.top, 1, rc.bottom - rc.top, rgbT);
_PatB(hdc, rc.left, rc.top, rc.right - rc.left, 1, rgbT);
rgbT = GetSysColor(COLOR_BTNSHADOW);
// right and bottom
_PatB(hdc, rc.right - 1, rc.top, 1, rc.bottom - rc.top, rgbT);
_PatB(hdc, rc.left, rc.bottom - 1, rc.right-rc.left, 1, rgbT);
InflateRect(&rc, -1, -1);
//
// first do the message box
//
RECT rcMbox;
SetRect(&rcMbox,
rc.left + _wSpace,
rc.top + _wAboveBelow,
rc.right - _wSpace,
rc.bottom - _wAboveBelow);
// draw 3d effects for this box.
// left and top
rgbT = GetSysColor(COLOR_BTNSHADOW);
int dxT = rcMbox.right - rcMbox.left;
int dyT = rcMbox.bottom - rcMbox.top;
_PatB(hdc, rcMbox.left, rcMbox.top, 1, dyT, rgbT);
_PatB(hdc, rcMbox.left, rcMbox.top, dxT, 1, rgbT);
rgbT = GetSysColor(COLOR_BTNHIGHLIGHT);
// right and bottom
_PatB(hdc, rcMbox.right - 1, rcMbox.top, 1, dyT, rgbT);
_PatB(hdc, rcMbox.left, rcMbox.bottom - 1, dxT, 1, rgbT);
InflateRect(&rcMbox, -1, -1);
HFONT hfontOld = SelectFont(hdc, _hfont);
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
ExtTextOut(hdc,
rcMbox.left,
rcMbox.top,
ETO_OPAQUE | ETO_CLIPPED,
&rcMbox,
_lpstrString,
lstrlen(_lpstrString),
(LPINT) NULL);
SelectObject(hdc, hfontOld);
InflateRect(&rcMbox, 1, 1);
ExcludeClipRect(hdc,
rcMbox.left, rcMbox.top, rcMbox.right, rcMbox.bottom);
// now do the background.
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE|ETO_CLIPPED, &rc, NULL, 0, NULL);
EndPaint(hwnd, &ps);
}