/*** *statbar.cpp * * Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. * Information Contained Herein Is Proprietary and Confidential. * *Purpose: * *Implementation Notes: * *****************************************************************************/ #include #include #include #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(); }