status.cxx
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 11k
Category:

Windows Develop

Development Platform:

Visual C++

  1. //+-------------------------------------------------------------------
  2. //
  3. //  File:       status.cxx
  4. //
  5. //  Contents:   Functions implementing status bar.
  6. //
  7. //  Classes:    StatusBar
  8. //
  9. //--------------------------------------------------------------------
  10. #include "headers.hxx"
  11. #pragma hdrstop
  12. WCHAR FAR lpstrStatBarClass[] = L"classStatBar";
  13. //+---------------------------------------------------------------
  14. //
  15. //  Function:   _PatB, private
  16. //
  17. //  Synopsis:   inline helper to fill rectangle with a color
  18. //
  19. //----------------------------------------------------------------
  20. inline void _PatB(HDC hdc, int x, int y, int dx, int dy, COLORREF rgb)
  21. {
  22.     RECT    rc;
  23.     SetRect(&rc, x, y, x+dx, y+dy);
  24.     SetBkColor(hdc, rgb);
  25.     ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  26. };
  27. //+---------------------------------------------------------------
  28. //
  29. //  Member:     StatusBar::ClassInit
  30. //
  31. //  Synopsis:   Registers the status bar window class
  32. //
  33. //  Arguments:  [hinst] -- instance handle of module using status bar
  34. //
  35. //  Returns:    TRUE iff the status bar was registered successfully
  36. //
  37. //  Notes:      This static method is usually called from the WinMain
  38. //              or LibMain of the module using the status bar.
  39. //
  40. //----------------------------------------------------------------
  41. BOOL StatusBar::ClassInit(HINSTANCE hinst)
  42. {
  43.     WNDCLASS wc;
  44.     wc.style = 0L;
  45.     wc.lpfnWndProc = StatusWndProc;
  46.     wc.cbClsExtra = 0;
  47.     wc.cbWndExtra = sizeof(void FAR*);
  48.     wc.hInstance = hinst;
  49.     wc.hIcon = NULL;
  50.     wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  51.     wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
  52.     wc.lpszMenuName = NULL;
  53.     wc.lpszClassName = lpstrStatBarClass;
  54.     return RegisterClass(&wc)!=NULL;
  55. }
  56. //+---------------------------------------------------------------
  57. //
  58. //  Member:     StatusBar::StatusBar, public
  59. //
  60. //  Synopsis:   Constructor for status bar class
  61. //
  62. //  Notes:      Creating a status bar is a two step process.
  63. //              First construct the object, then call the
  64. //              Init method to actually create the status bar window.
  65. //
  66. //----------------------------------------------------------------
  67. StatusBar::StatusBar()
  68. {
  69.     _hwnd = NULL;
  70.     _hfont = NULL;
  71.     _wHeight = (WORD)-1;
  72.     _wUnitBorder = (WORD)-1;
  73.     _wSpace = 6;
  74.     _wAboveBelow = 2;
  75.     lstrcpy(_lpstrString, L"");
  76. }
  77. //+---------------------------------------------------------------
  78. //
  79. //  Member:     StatusBar::~StatusBar, public
  80. //
  81. //  Synopsis:   Destructor for status bar class
  82. //
  83. //  Notes:      This frees any resources held by the status bar
  84. //              including deleting the window
  85. //
  86. //----------------------------------------------------------------
  87. StatusBar::~StatusBar()
  88. {
  89.     if (_hfont != NULL)
  90.         DeleteObject(_hfont);
  91.     if (_hwnd != NULL)
  92.         DestroyWindow(_hwnd);
  93. }
  94. //+-------------------------------------------------------------------
  95. //
  96. //  Member:     StatusBar::Init, public
  97. //
  98. //  Synopsis:   Creates a status bar window as a child of another window
  99. //
  100. //  Arguments:  [hwnd]  -- the window handle of the parent window
  101. //
  102. //  Returns:    The window handle of the status bar child window
  103. //
  104. //--------------------------------------------------------------------
  105. HWND
  106. StatusBar::Init(HINSTANCE hinst, HWND hwndParent)
  107. {
  108.     //
  109.     // create font, save handle, find height of status bar.
  110.     //
  111.     HDC hdc = GetDC(NULL);
  112.     int iFontHeight;
  113.     TEXTMETRIC tm;
  114.     iFontHeight = MulDiv(-10, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  115.     _hfont = CreateFont(iFontHeight, 0, 0, 0, 400, 0, 0, 0,
  116.                          ANSI_CHARSET,
  117.                          OUT_DEFAULT_PRECIS,
  118.                          CLIP_DEFAULT_PRECIS,
  119.                          DEFAULT_QUALITY,
  120.                          VARIABLE_PITCH | FF_SWISS,
  121.                          L"Helv");
  122.     HFONT   hfontOld = SelectFont(hdc, _hfont);
  123.     GetTextMetrics(hdc, &tm);
  124.     SelectObject(hdc, hfontOld);
  125.     ReleaseDC(NULL, hdc);
  126.     _wUnitBorder = (WORD)GetSystemMetrics(SM_CYBORDER);
  127.     _wHeight = (WORD)(tm.tmHeight + tm.tmExternalLeading +     // font height
  128.                                4 +                             // 2 above/below
  129.                                _wUnitBorder +                  // for border
  130.                               _wAboveBelow * 2);               // above and below
  131.     //
  132.     // create window
  133.     //
  134.     RECT rc;
  135.     GetClientRect(hwndParent, &rc);
  136.     // this will automatically set _hwnd!
  137.     CreateWindowEx(0L,         // extended style
  138.         lpstrStatBarClass,
  139.         NULL,
  140.         WS_CHILD | WS_VISIBLE | WS_BORDER,  // style
  141.         0, rc.bottom - _wHeight,            // x, y
  142.         rc.right - rc.left, _wHeight,       // cx, cy
  143.         hwndParent,             // hwndParent
  144.         NULL,                   // hmenu
  145.         hinst,
  146.         this);                  // lpParam
  147.     return _hwnd;
  148. }
  149. //+---------------------------------------------------------------
  150. //
  151. //  Member:     StatusBar::OnSize, public
  152. //
  153. //  Synopsis:   Updates the position of the status bar when the
  154. //              parent is resized
  155. //
  156. //  Arguments:  [lprc] -- client rectangle of parent window
  157. //
  158. //  Notes:      The parent window should call this method during
  159. //              WM_SIZE processing.  The parent should get its client
  160. //              rectangle and pass it to this method.  This method will
  161. //              move the status bar window to occupy the bottom of
  162. //              the window and will update the rectangle to remove its
  163. //              area (i.e. the returned rectangle is the parent windows'
  164. //              new, effective client area).
  165. //
  166. //----------------------------------------------------------------
  167. void
  168. StatusBar::OnSize(LPRECT lprc)
  169. {
  170.     lprc->bottom -= _wHeight;
  171.     MoveWindow(_hwnd, 0, lprc->bottom, lprc->right-lprc->left, _wHeight, TRUE);
  172.     InvalidateRect(_hwnd, NULL, TRUE);
  173. }
  174. //+-------------------------------------------------------------------
  175. //
  176. //  Member:     StatusBar::DisplayMessage, public
  177. //
  178. //  Synopsis:   Displays a string on the status bar
  179. //
  180. //  Arguments:  [lpstr] -- string to display in status bar.  NULL
  181. //                         means just clear the current message.
  182. //
  183. //--------------------------------------------------------------------
  184. void
  185. StatusBar::DisplayMessage(LPCWSTR lpstr)
  186. {
  187.     HDC hdc = GetDC(_hwnd);
  188.     RECT rc;
  189.     GetClientRect(_hwnd, &rc);
  190.     InflateRect(&rc, -1, -1);
  191.     rc.left += _wSpace;
  192.     rc.top += _wAboveBelow;
  193.     rc.right -= _wSpace;
  194.     rc.bottom -= _wAboveBelow;
  195.     InflateRect(&rc, -1, -1);
  196.     HFONT hfontOld = SelectFont(hdc, _hfont);
  197.     // clear out the old message
  198.     SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
  199.     ExtTextOut(hdc, 0, 0, ETO_OPAQUE|ETO_CLIPPED, &rc, NULL, 0, NULL);
  200.     // put up the new status message
  201.     if (lpstr != NULL)
  202.     {
  203.         lstrcpy(_lpstrString, lpstr);
  204.         SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
  205.         ExtTextOut(hdc,
  206.                     rc.left,
  207.                     rc.top,
  208.                     ETO_OPAQUE | ETO_CLIPPED,
  209.                     &rc,
  210.                     _lpstrString,
  211.                     lstrlen(_lpstrString),
  212.                     (LPINT) NULL);
  213.     }
  214.     SelectObject(hdc, hfontOld);
  215.     ReleaseDC(_hwnd, hdc);
  216. }
  217. //+---------------------------------------------------------------
  218. //
  219. //  Function:   StatusWndProc, private
  220. //
  221. //  Synopsis:   Window procedure for status bar window
  222. //
  223. //----------------------------------------------------------------
  224. extern "C" LRESULT CALLBACK
  225. StatusWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  226. {
  227.     //
  228.     //get a pointer to our object
  229.     //
  230.     LPSTATUSBAR pStatusBar = (LPSTATUSBAR)GetWindowLongPtr(hwnd, 0);
  231.     //
  232.     //if it is NULL, then check for a WM_NCCREATE message
  233.     //   when we get one stash the pointer to our object
  234.     //
  235.     if(pStatusBar == NULL)
  236.     {
  237.         if(msg == WM_NCCREATE)
  238.         {
  239.             CREATESTRUCT FAR *lpcs = (CREATESTRUCT FAR *)lParam;
  240.             pStatusBar = (LPSTATUSBAR)lpcs->lpCreateParams;
  241.             pStatusBar->_hwnd = hwnd;
  242.             SetWindowLongPtr(hwnd, 0, (LONG_PTR)pStatusBar);
  243.             //drop through to forward the message
  244.         }
  245.         return DefWindowProc(hwnd, msg, wParam, lParam);
  246.     }
  247.     if(msg == WM_NCDESTROY)
  248.     {
  249.         SetWindowLongPtr(hwnd, 0, 0L);
  250.         pStatusBar->_hwnd = NULL;
  251.         //drop through to forward the message to the window procedure
  252.     }
  253.     //handle any window message by passing it to the appropriate
  254.     //member function...
  255.     switch(msg)
  256.     {
  257.     HANDLE_MSG(hwnd, WM_PAINT, pStatusBar->OnPaint);
  258.     }
  259.     return DefWindowProc(hwnd, msg, wParam, lParam);
  260. }
  261. //+---------------------------------------------------------------
  262. //
  263. //  Member:     StatusBar::OnPaint, private
  264. //
  265. //  Synopsis:   Handles the WM_PAINT message for the status bar window
  266. //
  267. //----------------------------------------------------------------
  268. void
  269. StatusBar::OnPaint(HWND hwnd)
  270. {
  271.     PAINTSTRUCT ps;
  272.     HDC hdc = ::BeginPaint(hwnd, &ps);
  273.     RECT rc;
  274.     COLORREF rgbT;
  275.     // compute rectangle
  276.     GetClientRect(hwnd, &rc);
  277.     //
  278.     //      draw highlight and shadow
  279.     //
  280.     rgbT = GetSysColor(COLOR_BTNHIGHLIGHT);
  281.             // left and top
  282.     _PatB(hdc, rc.left, rc.top, 1, rc.bottom - rc.top, rgbT);
  283.     _PatB(hdc, rc.left, rc.top, rc.right - rc.left, 1, rgbT);
  284.     rgbT = GetSysColor(COLOR_BTNSHADOW);
  285.             // right and bottom
  286.     _PatB(hdc, rc.right - 1, rc.top, 1, rc.bottom - rc.top, rgbT);
  287.     _PatB(hdc, rc.left, rc.bottom - 1, rc.right-rc.left, 1, rgbT);
  288.     InflateRect(&rc, -1, -1);
  289.     //
  290.     //      first do the message box
  291.     //
  292.     RECT rcMbox;
  293.     SetRect(&rcMbox,
  294.             rc.left + _wSpace,
  295.             rc.top + _wAboveBelow,
  296.             rc.right - _wSpace,
  297.             rc.bottom - _wAboveBelow);
  298.     //      draw 3d effects for this box.
  299.     // left and top
  300.     rgbT = GetSysColor(COLOR_BTNSHADOW);
  301.     int dxT = rcMbox.right - rcMbox.left;
  302.     int dyT = rcMbox.bottom - rcMbox.top;
  303.     _PatB(hdc, rcMbox.left, rcMbox.top, 1, dyT, rgbT);
  304.     _PatB(hdc, rcMbox.left, rcMbox.top, dxT, 1, rgbT);
  305.     rgbT = GetSysColor(COLOR_BTNHIGHLIGHT);
  306.     // right and bottom
  307.     _PatB(hdc, rcMbox.right - 1, rcMbox.top, 1, dyT, rgbT);
  308.     _PatB(hdc, rcMbox.left, rcMbox.bottom - 1, dxT, 1, rgbT);
  309.     InflateRect(&rcMbox, -1, -1);
  310.     HFONT hfontOld = SelectFont(hdc, _hfont);
  311.     SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
  312.     SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
  313.     ExtTextOut(hdc,
  314.                 rcMbox.left,
  315.                 rcMbox.top,
  316.                 ETO_OPAQUE | ETO_CLIPPED,
  317.                 &rcMbox,
  318.                 _lpstrString,
  319.                 lstrlen(_lpstrString),
  320.                 (LPINT) NULL);
  321.     SelectObject(hdc, hfontOld);
  322.     InflateRect(&rcMbox, 1, 1);
  323.     ExcludeClipRect(hdc,
  324.                 rcMbox.left, rcMbox.top, rcMbox.right, rcMbox.bottom);
  325.     //      now do the background.
  326.     SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
  327.     ExtTextOut(hdc, 0, 0, ETO_OPAQUE|ETO_CLIPPED, &rc, NULL, 0, NULL);
  328.     EndPaint(hwnd, &ps);
  329. }