home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / spoly2 / statbar.cpp < prev    next >
C/C++ Source or Header  |  1997-08-01  |  8KB  |  374 lines

  1. /*** 
  2. *statbar.cpp
  3. *
  4. *  This is a part of the Microsoft Source Code Samples.
  5. *
  6. *  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  7. *
  8. *  This source code is only intended as a supplement to Microsoft Development
  9. *  Tools and/or WinHelp documentation.  See these sources for detailed
  10. *  information regarding the Microsoft samples programs.
  11. *
  12. *Purpose:
  13. *
  14. *Implementation Notes:
  15. *
  16. *****************************************************************************/
  17.  
  18. #include <stdarg.h>
  19.  
  20. #include "hostenv.h"
  21. #include "statbar.h"
  22.  
  23.  
  24. extern "C" long FAR PASCAL StatBarWndProc(HWND, unsigned int, WPARAM, LPARAM);
  25.  
  26.  
  27. TCHAR FAR* CStatBar::m_szWndClass = TSTR("StatBarWndClass");
  28.  
  29.  
  30. CStatBar::CStatBar()
  31. {
  32.     m_refs = 0;
  33.  
  34.     m_x = 0;
  35.     m_y = 0;
  36.     m_width = 0;
  37.     m_height = 0;
  38.  
  39.     m_bstrMsg = NULL;
  40.  
  41.     m_hfont = (HFONT)0;
  42. }
  43.  
  44. CStatBar::~CStatBar()
  45. {
  46.     SysFreeString(m_bstrMsg);
  47. }
  48.  
  49.  
  50. /***
  51. *PUBLIC CStatBar FAR* CStatBar::Create(HINSTANCE, HWND)
  52. *
  53. *Purpose:
  54. *
  55. *Entry:
  56. *
  57. *Exit:
  58. *
  59. ***********************************************************************/
  60. CStatBar FAR*
  61. CStatBar::Create(HINSTANCE hinst, HWND hwndFrame)
  62. {
  63.     CStatBar FAR* psb;
  64.  
  65.     psb = new FAR CStatBar();
  66.     if(psb == NULL)
  67.       return NULL;
  68.     psb->AddRef();
  69.  
  70.     if(!psb->Register(hinst))
  71.       goto LFail;
  72.  
  73.     psb->m_hwnd = CreateWindow(
  74.       CStatBar::m_szWndClass,
  75.       NULL,
  76.       WS_CHILD | WS_CLIPSIBLINGS,
  77.       0, 0, 0, 0,
  78.       hwndFrame,
  79.       0,
  80.       hinst,
  81.       NULL);
  82.  
  83.     if(!psb->m_hwnd)
  84.       goto LFail;
  85.  
  86.     // Stash the newly created CStatBar* in the extra bytes of the
  87.     // associated window so we can get at the instance in the message
  88.     // proc.
  89.     //
  90.     // Note: we do not AddRef for this reference. We make sure that the
  91.     // window is destroyed when the refcnt goes to 0.
  92.     //
  93.     SetWindowLong(psb->m_hwnd, 0, (long)psb);
  94.  
  95.     return psb;
  96.  
  97. LFail:;
  98.     delete psb;
  99.     return NULL;
  100. }
  101.  
  102.  
  103. //---------------------------------------------------------------------
  104. //                     IUnknown Methods
  105. //---------------------------------------------------------------------
  106.  
  107.  
  108. STDMETHODIMP
  109. CStatBar::QueryInterface(REFIID riid, void FAR* FAR* ppv)
  110. {
  111.     if(IsEqualIID(riid,IID_IUnknown)){
  112.       *ppv = this;
  113.       AddRef();
  114.       return NOERROR;
  115.     }
  116.     *ppv = (void FAR*)NULL;
  117.     return E_NOINTERFACE;
  118. }
  119.  
  120.  
  121. STDMETHODIMP_(unsigned long)
  122. CStatBar::AddRef(void)
  123. {
  124.     return ++m_refs;
  125. }
  126.  
  127.  
  128. STDMETHODIMP_(unsigned long)
  129. CStatBar::Release(void)
  130. {
  131.     if(--m_refs == 0){
  132.  
  133.       // destroy the status bar window.
  134.       //
  135.       SendMessage(m_hwnd, WM_DESTROY, 0, 0L);
  136.  
  137.       delete this;
  138.       return 0;
  139.     }
  140.  
  141.     return m_refs;
  142. }
  143.  
  144.  
  145. //---------------------------------------------------------------------
  146. //                     Introduced Methods
  147. //---------------------------------------------------------------------
  148.  
  149.  
  150. /***
  151. *PRIVATE BOOL CStatBar::Register(HINSTANCE)
  152. *
  153. *Purpose:
  154. *  Register the status bar window class.
  155. *
  156. *Entry:
  157. *  None
  158. *
  159. *Exit:
  160. *  return value = BOOL, TRUE if successful, FALSE if not.
  161. *
  162. ***********************************************************************/
  163. BOOL
  164. CStatBar::Register(HINSTANCE hinst)
  165. {
  166.     WNDCLASS  wc;
  167.  
  168.     // register the class, unless already registered.
  169.     if(GetClassInfo(hinst, m_szWndClass, &wc) == 0){
  170.       wc.style         = 0;
  171.       wc.lpfnWndProc   = StatBarWndProc;
  172.       wc.cbClsExtra    = 0;
  173.       wc.cbWndExtra    = sizeof(CStatBar FAR*);
  174.       wc.hInstance     = hinst;
  175.       wc.hIcon         = 0;
  176.       wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  177.       wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); 
  178.       wc.lpszMenuName  = 0;
  179.       wc.lpszClassName = CStatBar::m_szWndClass;
  180.       if(!RegisterClass(&wc))
  181.         return FALSE;
  182.     }
  183.     return TRUE;
  184. }
  185.  
  186.  
  187. /***
  188. *PUBLIC void CStatBar::Show(void)
  189. *
  190. *Purpose:
  191. *  Show the status bar window associated with this CStatBar instance.
  192. *
  193. *Entry:
  194. *  None
  195. *
  196. *Exit:
  197. *  None
  198. *
  199. ***********************************************************************/
  200. void
  201. CStatBar::Show()
  202. {
  203.     ShowWindow(m_hwnd, SW_SHOW);
  204. }
  205.  
  206. void
  207. CStatBar::SetFont(HFONT hfont)
  208. {
  209.     HDC hdc;
  210.     TEXTMETRIC tm;
  211.     HFONT hfontOld;
  212.  
  213.     // compute the character sizes given this new font.
  214.     //
  215.     hdc = GetDC(m_hwnd);
  216.     hfontOld = (HFONT)SelectObject(hdc, hfont);
  217.     GetTextMetrics(hdc, &tm);
  218.     m_dxFont = tm.tmAveCharWidth;
  219.     m_dyFont = tm.tmHeight + tm.tmExternalLeading;
  220.     SelectObject(hdc, hfontOld);
  221.     ReleaseDC(m_hwnd, hdc);
  222.  
  223.     m_hfont = hfont;
  224. }
  225.  
  226. /***
  227. *PRIVATE CStatBar::WMPaint(void)
  228. *
  229. *Purpose:
  230. *  This method is responsible for drawing the status bar, and is called
  231. *  in response to a WM_PAINT message.
  232. *
  233. *Entry:
  234. *  None
  235. *
  236. *Exit:
  237. *  None
  238. *
  239. ***********************************************************************/
  240. void
  241. CStatBar::WMPaint()
  242. {
  243.     HDC hdc;
  244.     RECT rcMsg;
  245.     HRGN hrgn;
  246.     HFONT hfontOld;
  247.     PAINTSTRUCT ps;
  248.     HPEN hpenBlack, hpenWhite, hpenGray, hpenOld;
  249.  
  250.     hdc = BeginPaint(m_hwnd, &ps);
  251.  
  252.     // compute the message box rect
  253.     //
  254.     rcMsg.top    = 3;
  255.     rcMsg.bottom= m_height - 3;
  256.     rcMsg.left    = m_dxFont;
  257.     rcMsg.right    = m_width - m_dxFont;
  258.  
  259.     // prepare the pens
  260.     //
  261.     hpenWhite    = (HPEN)GetStockObject(WHITE_PEN);
  262.     hpenBlack    = (HPEN)GetStockObject(BLACK_PEN);
  263.     hpenGray    = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
  264.  
  265.     // draw a top gray line
  266.     //
  267.     hpenOld = (HPEN)SelectObject(hdc, hpenGray);
  268. #if   defined(WIN16)    
  269.     MoveTo(hdc, ps.rcPaint.left, 0);
  270. #elif defined(WIN32)    
  271.     MoveToEx(hdc, ps.rcPaint.left, 0, NULL);
  272. #endif
  273.     LineTo(hdc, ps.rcPaint.right, 0);
  274.  
  275.     // draw a white line just under
  276.     //
  277.     SelectObject(hdc, hpenWhite);
  278. #if   defined(WIN16)    
  279.     MoveTo(hdc, ps.rcPaint.left, 1);
  280. #elif defined(WIN32)    
  281.     MoveToEx(hdc, ps.rcPaint.left, 1, NULL);
  282. #endif
  283.     LineTo(hdc, ps.rcPaint.right, 1);
  284.  
  285.     // do not overwrite the background color
  286.     //
  287.     SetBkMode(hdc, TRANSPARENT);
  288.  
  289.     // message area
  290.     //
  291.     SelectObject(hdc, hpenBlack);
  292. #if   defined(WIN16)    
  293.     MoveTo(hdc, rcMsg.left,  rcMsg.bottom);
  294. #elif defined(WIN32)    
  295.     MoveToEx(hdc, rcMsg.left,  rcMsg.bottom, NULL);
  296. #endif    
  297.     LineTo(hdc, rcMsg.left,  rcMsg.top);
  298.     LineTo(hdc, rcMsg.right, rcMsg.top);
  299.  
  300.     SelectObject(hdc, hpenWhite);
  301.     LineTo(hdc, rcMsg.right, rcMsg.bottom);
  302.     LineTo(hdc, rcMsg.left,  rcMsg.bottom);
  303.  
  304.     // select the black pen for writing
  305.     //
  306.     SelectObject(hdc, hpenBlack);
  307.  
  308.     // select the status bar font to write in
  309.     //
  310.     hfontOld = (HFONT)SelectObject(hdc, m_hfont);
  311.  
  312.     // set the clipping region
  313.     //
  314.     hrgn = CreateRectRgn(
  315.       rcMsg.left, rcMsg.top, rcMsg.right, rcMsg.bottom);
  316.  
  317.     SelectClipRgn(hdc, hrgn);
  318.  
  319.     // draw the status message
  320.     //
  321.     TextOut(
  322.       hdc,
  323.       rcMsg.left + (m_dxFont / 2),
  324.       rcMsg.top + ((rcMsg.bottom - rcMsg.top - m_dyFont) / 2),
  325.       STRING(m_bstrMsg), (SysStringLen(m_bstrMsg)));
  326.  
  327.     // cleanup
  328.     //
  329.     SelectObject(hdc, hpenOld);
  330.     SelectObject(hdc, hfontOld);
  331.  
  332.     DeleteObject(hrgn);
  333.     DeleteObject(hpenGray);
  334.  
  335.     EndPaint(m_hwnd, &ps);
  336. }
  337.  
  338. extern "C" long FAR PASCAL
  339. StatBarWndProc(
  340.     HWND hwnd,
  341.     unsigned int message,
  342.     WPARAM wParam,
  343.     LPARAM lParam)
  344. {
  345.     CStatBar FAR* psb;
  346.  
  347.     switch(message){
  348.     case WM_SIZE:
  349.       return 0;
  350.     case WM_PAINT:
  351.       psb = (CStatBar FAR*)GetWindowLong(hwnd, 0);
  352.       psb->WMPaint();
  353.       return 0;
  354.     }
  355.     return(DefWindowProc(hwnd, message, wParam, lParam));
  356. }
  357.  
  358.  
  359. //---------------------------------------------------------------------
  360. //                    Status Bar Utilities
  361. //---------------------------------------------------------------------
  362.  
  363. extern "C" void
  364. SBprintf(CStatBar FAR* psb, TCHAR FAR* szFmt, ...)
  365. {
  366.     va_list args;
  367. static TCHAR buf[256];
  368.  
  369.     va_start(args, szFmt);
  370.     wvsprintf(buf, szFmt, args);
  371.     psb->SetText(WIDESTRING(buf));
  372.     psb->Update();
  373. }
  374.