Figure 2   Flyby

mouse.h


 ////////////////////////////////////////////////////////////////
 // 1998 Microsoft Systems Journal. 
 // If this code works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // Compiles with Visual C++ 5.0 on Windows 95
 // 
 
 //////////////////
 // class to represent global mouse object.
 //
 class CMouse {
 public:
     CWnd* Capture()         { return CWnd::GetCapture(); }
     CWnd* Capture(CWnd *w)  { return w->SetCapture(); }
     void Release()          { ReleaseCapture(); }
     CPoint GetPos()         { CPoint p; ::GetCursorPos(&p); return p; }
     operator CPoint()       { return GetPos(); }
 };
 extern CMouse Mouse;

mouse.cpp


 ////////////////////////////////////////////////////////////////
 // 1998 Microsoft Systems Journal. 
 // If this code works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // Compiles with Visual C++ 5.0 on Windows 95
 // 
 
 #include <stdafx.h>
 #include "mouse.h"
 
 // Instantiate one-and-only mouse object
 CMouse Mouse;
view.h

 ////////////////////////////////////////////////////////////////
 // 1998 Microsoft Systems Journal. 
 // If this code works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // Compiles with Visual C++ 5.0 on Windows 95
 // 
 class CMyView : public CView {
 private:
     CRect m_rcClient;                    // client area rectangle
     CRgn  m_hotRegion;                   // elliptic region
     BOOL  m_bHighlighted;                // whether region is highlighted
     BOOL  m_bTrackLeave;                 // whether tracking mouse 
 
 public:
     virtual ~CMyView();
     CMyDoc* GetDocument() { return (CMyDoc*)m_pDocument; }
 
     virtual void OnDraw(CDC* pDC);
     BOOL TrackMouseLeave(BOOL bTrackLeave);
 
 protected:
     DECLARE_DYNCREATE(CMyView)
     CMyView();
     afx_msg void OnMouseMove(UINT nFlags, CPoint pt);
     afx_msg void OnSize(UINT nType, int cx, int cy);
     afx_msg void OnTimer(UINT nIDEvent);
     DECLARE_MESSAGE_MAP()
 };
view.cpp

 ////////////////////////////////////////////////////////////////
 // FLYBY 1998 Microsoft Systems Journal. 
 // If this program works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 //
 #include "StdAfx.h"
 #include "Flyby.h"
 #include "Doc.h"
 #include "View.h"
 #include "Mouse.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #undef THIS_FILE
 static char THIS_FILE[] = __FILE__;
 #endif
 
 IMPLEMENT_DYNCREATE(CMyView, CView)
 
 BEGIN_MESSAGE_MAP(CMyView, CView)
     ON_WM_MOUSEMOVE()
     ON_WM_SIZE()
     ON_WM_TIMER()
 END_MESSAGE_MAP()
 
 CMyView::CMyView()
 {
     m_bTrackLeave = FALSE;  // not tracking mouse
     m_bHighlighted = -1;    // invalid state
 }
 
 CMyView::~CMyView()
 {
 }
 
 //////////////////
 // Draw ellipse within client area.
 // If mouse is outside the ellipse, draw blue; else red
 //
 void CMyView::OnDraw(CDC* pDC)
 {
     CPoint pt = Mouse;      // mouse pos in screen coords 
     ScreenToClient(&pt);    // convert to client
 
     // create brush w/appropriate color
     CBrush brush(m_hotRegion.PtInRegion(pt) ?
         RGB(255,0,0) :    // red
         RGB(0,0,255));    // blue
 
     // select brush and draw ellipse
     CGdiObject *pOldBrush = pDC->SelectObject(&brush);
     pDC->Ellipse(&m_rcClient);
     pDC->SelectObject(pOldBrush);
 }
 
 //////////////////
 // Window size changed: update client rectangle and elliptic region.
 //
 void CMyView::OnSize(UINT nType, int cx, int cy)
 {
     m_rcClient.SetRect(0,0,cx,cy);
     m_hotRegion.DeleteObject();
     m_hotRegion.CreateEllipticRgnIndirect(&m_rcClient);
 }
 
 //////////////////
 // Handle mouse move message: highlight or unhighlight ellipse,
 // and if highlighted, track mouse for leaving window.
 //
 void CMyView::OnMouseMove(UINT nFlags, CPoint pt)
 {
     // Determine correct highlight for
     // ellipse, and repaint if necessary.
     //
     BOOL bHighlighted = m_hotRegion.PtInRegion(pt);
     if (bHighlighted != m_bHighlighted) {
 
         // Mouse has either left or entered the ellipse: repaint
         m_bHighlighted = bHighlighted;
         Invalidate(FALSE);
         UpdateWindow();
 
         // Track the mouse leaving window based on whether highlighted or not
         // 
         TrackMouseLeave(m_bHighlighted);
     }
 }
 
 //////////////////
 // Track when mouse leaves window -- by setting a timer (yuk).
 // In Windows NT, you should use TrackMouseEvent instead.
 //
 BOOL CMyView::TrackMouseLeave(BOOL bTrackLeave)
 {
     if (bTrackLeave != m_bTrackLeave) {
         if (bTrackLeave)
         VERIFY(SetTimer(1, 50, NULL));
         else
         KillTimer(1);
 
         m_bTrackLeave = bTrackLeave;
     }
     return m_bTrackLeave;
 }
 
 /////////////////
 // Handle timer click: check for mouse leaving window
 //
 void CMyView::OnTimer(UINT nIDEvent)
 {
     ASSERT(nIDEvent==1);
 
     // Get mouse pos in client coords
     CPoint pt = Mouse;
     ScreenToClient(&pt);
 
     if (!m_rcClient.PtInRect(pt)) {
         //
         // Mouse is outside window: send bogus WM_MOUSEMOVE message.
         // Be careful doing this: if your OnMouseMove function does other
         // stuff that expects the mouse to be in the client area, it might
         // fail.
         //
         // Probably better to send WM_MOUSELEAVE here.
         //
         SendMessage(WM_MOUSEMOVE, 0, MAKELONG(pt.x, pt.y));
         TrackMouseLeave(FALSE);           // stop tracking
     }
 }


Figure 5   HTBTest

hottb.h


 ////////////////////////////////////////////////////////////////
 // 1998 Microsoft Systems Journal. 
 // If this code works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // Compiles with Visual C++ 5.0 on Windows 95
 // 
 
 //////////////////
 // This class sets up a toolbar with hot/cold button bitmaps.
 // To use it instead of CToolBar::LoadToolBar, create an instance in
 // you CMainFrame::OnCreate, then call SetupHotToolBar like so
 //
 // CHotToolBarSetup htbs;
 // htbs.SetupHotToolBar(m_wndToolBar, ID_NORMAL, ID_HOT, ID_DISAB, cx, clrBk);
 //
 // m_wndToolBar      is your CToolBar
 // ID_NORMAL         is the resource id of bitmap to use for normal buttons
 // ID_HOT            is the resource id of bitmap to use for "hot" buttons
 // ID_DISAB          is the resource id of bitmap to use for disabled buttons
 // cx                is the width of one button
 // clrBk             is the background color of the bitmaps, which will be
 //                   mapped to transparent
 // 
 class CHotToolBarSetup {
 
 private:
     CSize m_szButtonMargin; // button size this much bigger than image size
 
 public:
     CHotToolBarSetup();
     void SetupHotToolBar(CToolBar& tb, UINT nIdCold, UINT nidHot, UINT nIdDisab,
                          int cx, COLORREF clrBkgnd);
 };
hottb.cpp

 ////////////////////////////////////////////////////////////////
 // 1998 Microsoft Systems Journal. 
 // If this code works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // Compiles with Visual C++ 5.0 on Windows 95
 // 
 #include "stdafx.h"
 #include "hottb.h"
 
 CHotToolBarSetup::CHotToolBarSetup()
 {
     // MFC normally makes the button 7 pixels larger all around than the
     // actual button image. Change this if you like before calling Setup.
     //
     m_szButtonMargin = CSize(7,7);
 }
 
 // Set up toolbar with normal and "hot" button bitmaps
 //
 void CHotToolBarSetup::SetupHotToolBar(CToolBar& tb, // toolbar
     UINT nIdNormal,      // resource ID for normal buttons bitmap
     UINT nIdHot,         // resource ID for hot button bitmap
     UINT nIdDisab,       // resource ID for disabled button bitmap
     int cx,              // width of one button image
     COLORREF clrBkgnd)   // background (transparent) color
 {
     // Size of one button image--will calculate cy below
     CSize szImage(cx,0);
 
     // A toolbar must be flat to use "hot" bitmap (image list)
     tb.ModifyStyle(0, TBSTYLE_FLAT);
 
     // Create image list from normal bitmap
     ASSERT(nIdNormal);
     CImageList il;
     VERIFY(il.Create(nIdNormal, cx, 0, clrBkgnd));
 
     // Get height of button image from image list itself.
     IMAGEINFO info;
     il.GetImageInfo(0, &info);
     szImage.cy = ((CRect&)info.rcImage).Height();
 
     // Set toolbar button sizes for MFC
     tb.SetSizes(szImage + m_szButtonMargin, szImage);
 
     // set normal button images.
     // It's important to detach the HIMAGELIST, else CImageList will destroy.
     tb.SendMessage(TB_SETIMAGELIST, 0, (LPARAM)il.Detach());
 
     // Load hot bitmap and set in toolbar
     if (nIdHot) {
         VERIFY(il.Create(nIdHot, cx, 0, clrBkgnd));
         tb.SendMessage(TB_SETHOTIMAGELIST, 0, (LPARAM)il.Detach());
     }
 
     // Load disabled bitmap and set in toolbar
     if (nIdDisab) {
         VERIFY(il.Create(nIdDisab, cx, 0, clrBkgnd));
         tb.SendMessage(TB_SETDISABLEDIMAGELIST, 0, (LPARAM)il.Detach());
     }
 }
mainfrm.cpp

 ////////////////////////////////////////////////////////////////
 // 1998 Microsoft Systems Journal. 
 // If this program works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 //
 #include "StdAfx.h"
 #include "HTBTest.h"
 #include "MainFrm.h"
 #include "hottb.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #undef THIS_FILE
 static char THIS_FILE[] = __FILE__;
 #endif
 
 IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
 
 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
     //{{AFX_MSG_MAP(CMainFrame)
     ON_WM_CREATE()
     ON_COMMAND(ID_GO_BACK, OnNotImplemented)
     ON_COMMAND(ID_GO_FORWARD, OnNotImplemented)
     ON_COMMAND(ID_VIEW_STOP, OnNotImplemented)
     ON_COMMAND(ID_VIEW_REFRESH, OnNotImplemented)
     ON_COMMAND(ID_GO_START_PAGE, OnNotImplemented)
     ON_COMMAND(ID_GO_SEARCH_THE_WEB, OnNotImplemented)
     ON_COMMAND(ID_FAVORITES_DROPDOWN, OnNotImplemented)
     ON_COMMAND(ID_FILE_PRINT, OnNotImplemented)
     ON_COMMAND(ID_FONT_DROPDOWN, OnNotImplemented)
     //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
 static UINT BASED_CODE indicators[] = {
     ID_SEPARATOR,           // status line indicator
     ID_INDICATOR_CAPS,
     ID_INDICATOR_NUM,
     ID_INDICATOR_SCRL,
 };
 
 CMainFrame::CMainFrame()
 {
 }
 
 CMainFrame::~CMainFrame()
 {
 }
 
 #ifndef TB_SETEXTENDEDSTYLE
 // from newer versions of commctrl.h
 #define TB_SETEXTENDEDSTYLE     (WM_USER + 84)  // For TBSTYLE_EX_*
 #define TBSTYLE_EX_DRAWDDARROWS 0x00000001
 #endif
 
 const NBUTTONS = 9;
 
 // This table is used to load the buttons
 // One table is worth a thousand lines of code (well, a lot, anyway)
 // Use tables!!!
 //
 static struct {
     UINT id;                            // command ID
     UINT style;                         // button style
     UINT iImage;                        // index of image in normal/hot bitmaps
 
 } Buttons[NBUTTONS] = {
 
     // command ID              button style                        image index
     { ID_GO_BACK,              TBSTYLE_BUTTON,                     0 },
     { ID_GO_FORWARD,           TBSTYLE_BUTTON,                     1 },
     { ID_VIEW_STOP,            TBSTYLE_BUTTON,                     2 },
     { ID_VIEW_REFRESH,         TBSTYLE_BUTTON,                     3 },
     { ID_GO_START_PAGE,        TBSTYLE_BUTTON,                     4 },
     { ID_GO_SEARCH_THE_WEB,    TBSTYLE_BUTTON,                     5 },
     { ID_FAVORITES_DROPDOWN,   TBSTYLE_BUTTON | TBSTYLE_DROPDOWN,  6 },
     { ID_FILE_PRINT,           TBSTYLE_BUTTON,                     7 },
     { ID_FONT_DROPDOWN,        TBSTYLE_BUTTON | TBSTYLE_DROPDOWN,  8 }
 };
 
 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
         return -1;
 
     // Create toolbar--but don't load it
     if (!m_wndToolBar.Create(this)) {
         TRACE0("Failed to create toolbar\n");
         return -1;      // fail to create
     }
     // Use handy class to set up cold/hot toolbar button bitmaps
     CHotToolBarSetup htb;
     htb.SetupHotToolBar(m_wndToolBar,
         IDB_COLDTOOLBAR,                  // ID of bitmap for "normal" buttons
         IDB_HOTTOOLBAR,                   // ID of bitmap for "hot" buttons
         0,                                // ID of bitmap for disabled buttons
         22,                               // width of one button in bitmap
         RGB(255, 0, 255));                // background color
 
     // for dropdown arrows--note: they are not implemented
     m_wndToolBar.SendMessage(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);
 
     // Add toolbar buttons since I'm not using LoadToolBar
     m_wndToolBar.SetButtons(NULL, NBUTTONS);
     for (int i=0; i<NBUTTONS; i++) {
         m_wndToolBar.SetButtonInfo(i,
             Buttons[i].id,                 // command id
             Buttons[i].style,              // buttons style
             Buttons[i].iImage);            // index of image in bitmap
     }
 
     // Rest is normal main frame stuff...
     // 
     if (!m_wndStatusBar.Create(this) ||
         !m_wndStatusBar.SetIndicators(indicators,
         sizeof(indicators)/sizeof(UINT))) {
         TRACE("Failed to create status bar\n");
         return -1;      // fail to create
     }
 
    m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
       CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
 
    return 0;
 }
 
 void CMainFrame::OnNotImplemented()
 {
    MessageBeep(0);
 }