Category : C++ Source Code
Archive   : TOOLTIPB.ZIP
Filename : TOOLTIPB.CPP

 
Output of file : TOOLTIPB.CPP contained in archive : TOOLTIPB.ZIP
//
// Copyright (C) 1994 by
// Todd Osborne, St. Louis, MO, USA
// All Rights Reserved.
//
// This software is furnished under the Public Domain.
// You may freely copy, modify and distribute any or all portions of this
// code.
//
// Todd Osborne assumes no responsibility for
// the use or reliability of this software.
//
// FACILITY: ToolTips and FlyBy Support for MFC CToolBar derived class
//
// ABSTRACT:
//
// The CToolTipBar is a direct replacement for classes derived or
// instantiated from the MFC class CToolBar. To implement all
// functionality, simply change your derivation or instantiation from
// CToolBar to CToolTipBar. For extended usage, see header file.
//
// AUTHOR(S): Todd Osborne INTERNET: [email protected]
//
// CREATED: 06/27/94
//
// MODIFICATION HISTORY:
//
// Version Date By Reason
//

#include "tooltipb.h"

CToolTipPopup::CToolTipPopup(CWnd* pParentWnd)
{
// Initialize member variables
m_nShowTip = 0;
m_strText = "";
m_pParentWnd = (CToolBar*)pParentWnd;
m_pFont = NULL;
m_nClearance = 3;

// Create and register custom window class for the tool tip window.
// It has a yellow solid fill color which displays black text
HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 128));
m_strWndClass = AfxRegisterWndClass(CS_SAVEBITS, 0, hBrush, 0);
::DeleteObject(hBrush);

// Create the popup-window
CreateEx(0, m_strWndClass, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_BORDER, 0, 0, 0, 0, m_pParentWnd->m_hWnd, 0);
}

CToolTipPopup::~CToolTipPopup()
{
// Clean up
if ( m_pFont )
{
m_pFont->DeleteObject();
delete m_pFont;
}
}

int CToolTipPopup::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if ( CWnd::OnCreate(lpCreateStruct) == -1 )
return -1;

// Create the font to use in popup windows. Initially a 9 point Arial
LOGFONT lf;
CClientDC dc(this);
int nFontSize = -1 * (::GetDeviceCaps(dc.m_hDC, LOGPIXELSY) * 9/*9 is the initial point size*/ / 72);

m_pFont = new CFont();

lf.lfHeight = nFontSize;
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_REGULAR;
lf.lfItalic = FALSE;
lf.lfUnderline = FALSE;
lf.lfStrikeOut = FALSE;
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_STROKE_PRECIS;
lf.lfClipPrecision - CLIP_STROKE_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = FF_DONTCARE;
lstrcpy(lf.lfFaceName, "Arial");

SetFont(&lf);

return 0;
}

void CToolTipPopup::OnPaint()
{
CPaintDC dc(this);

// Set font
CFont* pOldFont = dc.SelectObject(m_pFont);

// Get rect
RECT rect;
GetClientRect(&rect);

// Draw the text in black
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(0, 0, 0));
dc.DrawText(m_strText, m_strText.GetLength(), &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);

// Clean-up
dc.SelectObject(pOldFont);
}

BOOL CToolTipPopup::SetFont(const LOGFONT* pLogFont)
{
// Set m_pFont to pLogFont (passed in from CToolTipBar member function)

// If this font exists, delete it first
if ( m_pFont )
m_pFont->DeleteObject();

BOOL bCreated;

if ( !(bCreated = m_pFont->CreateFontIndirect(pLogFont)) )
m_pFont = NULL;

return bCreated;
}

void CToolTipPopup::ShowTip(UINT nID, UINT x)
{
// Show the tool tip window, displaying the text from the menu identified by nID

// If this tip is already showing, exit now
if ( nID == m_nShowTip )
return;

m_nShowTip = nID;

// Attempt to get menu item text (This will become the popup ToolTip text)
char szMenuText[50];
CMenu* pMenu = GetParent()->GetMenu();
if ( pMenu != NULL && pMenu->GetMenuString(m_nShowTip, szMenuText, sizeof(szMenuText), MF_BYCOMMAND) > 0 )
{
// We have the menu text. "Fix" string. NULL terminate, remove & and tabs and ... chars
szMenuText[sizeof(szMenuText) - 1] = '\0';

// ...
char* psz = strstr(szMenuText, "...");
if ( psz != NULL )
*psz = '\0';

// Tabs
psz = strchr(szMenuText, '\t');
if ( psz != NULL )
*psz = '\0';

// &
char* ptr1 = szMenuText;
char* ptr2 = szMenuText;
while ( *ptr1 != '\0' )
{
if ( *ptr1 != '&' )
{
*ptr2 = *ptr1;
++ptr2;
}
++ptr1;
}
*ptr2 = '\0';

// Copy to CString object
m_strText = szMenuText;

// Determine size of popup window based on size of text
CClientDC dc(this);
CFont* pOldFont = dc.SelectObject(m_pFont);
CSize size = dc.GetTextExtent(szMenuText, lstrlen(szMenuText));

// Set tip window postion and make the window slightly larger than this font ( m_nClearance pixels in each direction )
RECT rToolBar;
m_pParentWnd->GetWindowRect(&rToolBar);
SetWindowPos(&wndNoTopMost, x, rToolBar.top + (rToolBar.bottom - rToolBar.top), size.cx + (2 * m_nClearance), size.cy + (2 * m_nClearance), SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_SHOWWINDOW);

// Clean-Up
dc.SelectObject(pOldFont);

// Invalidate this window and re-paint
InvalidateRect(NULL);
UpdateWindow();
}
}

void CToolTipPopup::HideCurrentTip()
{
if ( IsWindowVisible() )
{
ShowWindow(SW_HIDE);
m_nShowTip = 0;
}
}

BEGIN_MESSAGE_MAP(CToolTipPopup, CWnd)
//{{AFX_MSG_MAP(CToolTipPopup)
ON_WM_PAINT()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


IMPLEMENT_DYNCREATE(CToolTipBar, CToolBar)

CToolTipBar::CToolTipBar()
: CToolBar()
{
// Initialize member variables
m_pToolTipPopup = NULL; // Popup not yet created
m_bEnableToolTips = FALSE; // ToolTips are not enabled (until popup window is created)
m_bEnableFlyBy = TRUE; // FlyBy's are enabled by default
m_ptCurPos = 0, 0; // No last cursor position
m_nShowTip = 0; // No current tip to be shown
m_nShowX = 0; // No X pixel to show tip at
m_nWait = 500; // 500 milliseconds before time is shown
m_bMouseDown = FALSE; // Left mouse button is not down to start with
}

CToolTipBar::~CToolTipBar()
{
// Clean up
if ( m_pToolTipPopup )
{
m_pToolTipPopup->DestroyWindow();
delete m_pToolTipPopup;
}
}

CToolTipBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
{
// Call base class first
BOOL bRetVal = CToolBar::Create(pParentWnd, dwStyle, nID);

// Create the popup tool tip window. It is not initially visible
m_pToolTipPopup = new CToolTipPopup(this);

// Verify memory was allocated and window was created
if ( m_pToolTipPopup )
m_bEnableToolTips = TRUE;

// Return the return value for CToolBar::Create()
return bRetVal;
}

void CToolTipBar::OnLButtonDown(UINT nFlags, CPoint point)
{
// Call base class first
CToolBar::OnLButtonDown(nFlags, point);

// Always remove any ToolTips when a mouse button is pressed
m_bMouseDown = TRUE;
if ( m_pToolTipPopup )
m_pToolTipPopup->HideCurrentTip();
}

void CToolTipBar::OnLButtonUp(UINT nFlags, CPoint point)
{
// Call base class first
CToolBar::OnLButtonUp(nFlags, point);

// Always remove any ToolTips when a mouse button is released
m_bMouseDown = FALSE;
if ( m_pToolTipPopup )
m_pToolTipPopup->HideCurrentTip();
}

void CToolTipBar::OnMouseMove(UINT nFlags, CPoint point)
{
// Call base class first
CToolBar::OnMouseMove(nFlags, point);

// Get current button mouse is over. 0 if none
UINT nID = GetMouseOverTip();

if ( nID )
{
// Post WM_MENUSELECT to parent window. This allows updating of status bar
if ( m_bEnableFlyBy )
{
CMenu* pMenu = GetParent()->GetMenu();
if ( pMenu )
AfxGetMainWnd()->PostMessage(WM_MENUSELECT, nID, MAKELONG(pMenu->GetMenuState(nID, MF_BYCOMMAND), pMenu->m_hMenu));
}

// Hide the current tip NOW because it is not the one the mouse is over
if ( nID != m_nShowTip && m_pToolTipPopup )
m_pToolTipPopup->HideCurrentTip();

// Set m_nShowTip, x Pixel to display and timer
if ( m_bEnableToolTips )
{
m_ptCurPos = point;
ClientToScreen(&point);
m_nShowTip = nID;
m_nShowX = point.x;
// Set timer to fire in m_nWait milliseconds
SetTimer(1, m_nWait, NULL);
return;
}
}

// If we made it this far, we need to hide the current tip (if any)
if ( m_pToolTipPopup )
m_pToolTipPopup->HideCurrentTip();
}

void CToolTipBar::OnTimer(UINT nIDEvent)
{
// We cannot show tips if any of the following are true:
// 1) The ToolTipPopup window was not created
// 2) The main window is not the currently enabled window
// 3) The main window is not the active window
// 4) The main window is an icon
// 5) The left mouse button is down
// Also, only show a ToolTip if the mouse has not moved since we set m_nShowTip in the
// last WM_MOUSEMOVE event
CWnd* pMain = AfxGetMainWnd();
if ( m_pToolTipPopup && pMain->IsWindowEnabled() && pMain->m_hWnd == ::GetActiveWindow() && !pMain->IsIconic() && !m_bMouseDown)
{
// Show tip if cursor has not moved since timer was set
POINT ptCur;
::GetCursorPos(&ptCur);
ScreenToClient(&ptCur);
if ( m_ptCurPos == ptCur )
m_pToolTipPopup->ShowTip(m_nShowTip, m_nShowX);
}

// Always kill the timer
KillTimer(nIDEvent);
}

LRESULT CToolTipBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam)
{
TRACE("OnIdleUpdateCmdUI\n");

// This is our chance to hide a toolbar item when the mouse moves out of
// the toolbar rect and we missed a WM_MOUSEMOVE message, or another app
// was made active since we displayed a ToolTip
if ( m_pToolTipPopup )
{
POINT ptCur;
RECT rToolBar;
::GetCursorPos(&ptCur);
GetWindowRect(&rToolBar);
if ( !(::PtInRect(&rToolBar, ptCur)) || AfxGetMainWnd()->m_hWnd != ::GetActiveWindow() )
m_pToolTipPopup->HideCurrentTip();
}

return CToolBar::OnIdleUpdateCmdUI(wParam, lParam);
}

BEGIN_MESSAGE_MAP(CToolTipBar, CToolBar)
//{{AFX_MSG_MAP(CToolTipBar)
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// ***** SUPPORT ROUTINES ******

UINT CToolTipBar::GetMouseOverTip()
{
// Return the menu ID the mouse is over (0 if none)
RECT rItem;
UINT nID = 0, nStyle = 0;
int nImage = 0;

// Get the current mouse position
POINT point;
GetCursorPos(&point);

// Get the toolbar rect
RECT rToolBar;
GetWindowRect(&rToolBar);

for ( int i = 0; i < GetCount(); i++ )
{
GetItemRect(i, &rItem);
ClientToScreen(&rItem);
if ( ::PtInRect(&rItem, point) != 0 )
{
// We have found a item in the CToolBar that we are over
// Is it a separator? (Values passed by reference)
GetButtonInfo(i, nID, nStyle, nImage);
if ( !(nStyle & TBBS_SEPARATOR) )
return nID;
}
}

// If we made it this far, we are not over a button
return 0;
}


  3 Responses to “Category : C++ Source Code
Archive   : TOOLTIPB.ZIP
Filename : TOOLTIPB.CPP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/