TitleTip.cpp
上传用户:jzscgs158
上传日期:2022-05-25
资源大小:8709k
文件大小:9k
- ////////////////////////////////////////////////////////////////////////////
- // TitleTip.cpp : implementation file
- //
- // Based on code by Zafir Anjum
- //
- // Adapted by Chris Maunder <cmaunder@mail.com>
- // Copyright (c) 1998-2000. All Rights Reserved.
- //
- // This code may be used in compiled form in any way you desire. This
- // file may be redistributed unmodified by any means PROVIDING it is
- // not sold for profit without the authors written consent, and
- // providing that this notice and the authors name and all copyright
- // notices remains intact.
- //
- // An email letting me know how you are using it would be nice as well.
- //
- // This file is provided "as is" with no expressed or implied warranty.
- // The author accepts no liability for any damage/loss of business that
- // this product may cause.
- //
- // For use with CGridCtrl v2.20+
- //
- // History
- // 10 Apr 1999 Now accepts a LOGFONT pointer and
- // a tracking rect in Show(...) (Chris Maunder)
- // 18 Apr 1999 Resource leak in Show fixed by Daniel Gehriger
- // 8 Mar 2000 Added double-click fix found on codeguru
- // web site but forgot / can't find who contributed it
- // 28 Mar 2000 Aqiruse (marked with //FNA)
- // Titletips now use cell color
- // 18 Jun 2000 Delayed window creation added
- //
- /////////////////////////////////////////////////////////////////////////////
-
- #include "stdafx.h"
- #include "gridctrl.h"
- #ifndef GRIDCONTROL_NO_TITLETIPS
- #include "TitleTip.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CTitleTip
- CTitleTip::CTitleTip()
- {
- // Register the window class if it has not already been registered.
- WNDCLASS wndcls;
- HINSTANCE hInst = AfxGetInstanceHandle();
- if(!(::GetClassInfo(hInst, TITLETIP_CLASSNAME, &wndcls)))
- {
- // otherwise we need to register a new class
- wndcls.style = CS_SAVEBITS;
- wndcls.lpfnWndProc = ::DefWindowProc;
- wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
- wndcls.hInstance = hInst;
- wndcls.hIcon = NULL;
- wndcls.hCursor = LoadCursor( hInst, IDC_ARROW );
- wndcls.hbrBackground = (HBRUSH)(COLOR_INFOBK +1);
- wndcls.lpszMenuName = NULL;
- wndcls.lpszClassName = TITLETIP_CLASSNAME;
- if (!AfxRegisterClass(&wndcls))
- AfxThrowResourceException();
- }
- m_dwLastLButtonDown = ULONG_MAX;
- m_dwDblClickMsecs = GetDoubleClickTime();
- m_bCreated = FALSE;
- }
- CTitleTip::~CTitleTip()
- {
- }
- BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
- //{{AFX_MSG_MAP(CTitleTip)
- ON_WM_MOUSEMOVE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTitleTip message handlers
- BOOL CTitleTip::Create(CWnd * pParentWnd)
- {
- ASSERT_VALID(pParentWnd);
- // Already created?
- if (m_bCreated)
- return TRUE;
- DWORD dwStyle = WS_BORDER | WS_POPUP;
- DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
- m_pParentWnd = pParentWnd;
- m_bCreated = CreateEx(dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, NULL );
- return m_bCreated;
- }
- BOOL CTitleTip::DestroyWindow()
- {
- m_bCreated = FALSE;
-
- return CWnd::DestroyWindow();
- }
- // Show - Show the titletip if needed
- // rectTitle - The rectangle within which the original
- // title is constrained - in client coordinates
- // lpszTitleText - The text to be displayed
- // xoffset - Number of pixel that the text is offset from
- // left border of the cell
- void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset /*=0*/,
- LPRECT lpHoverRect /*=NULL*/,
- const LOGFONT* lpLogFont /*=NULL*/,
- COLORREF crTextClr /* CLR_DEFAULT */,
- COLORREF crBackClr /* CLR_DEFAULT */)
- {
- if (!IsWindow(m_hWnd))
- Create(m_pParentWnd);
- ASSERT( ::IsWindow( GetSafeHwnd() ) );
- if (rectTitle.IsRectEmpty())
- return;
- // If titletip is already displayed, don't do anything.
- if( IsWindowVisible() )
- return;
- m_rectHover = (lpHoverRect != NULL)? lpHoverRect : rectTitle;
- m_rectHover.right++; m_rectHover.bottom++;
- m_pParentWnd->ClientToScreen( m_rectHover );
- ScreenToClient( m_rectHover );
- // Do not display the titletip is app does not have focus
- if( GetFocus() == NULL )
- return;
- // Define the rectangle outside which the titletip will be hidden.
- // We add a buffer of one pixel around the rectangle
- m_rectTitle.top = -1;
- m_rectTitle.left = -xoffset-1;
- m_rectTitle.right = rectTitle.Width()-xoffset;
- m_rectTitle.bottom = rectTitle.Height()+1;
- // Determine the width of the text
- m_pParentWnd->ClientToScreen( rectTitle );
- CClientDC dc(this);
- CString strTitle = _T("");
- strTitle += _T(" ");
- strTitle += lpszTitleText;
- strTitle += _T(" ");
- CFont font, *pOldFont = NULL;
- if (lpLogFont)
- {
- font.CreateFontIndirect(lpLogFont);
- pOldFont = dc.SelectObject( &font );
- }
- else
- {
- // use same font as ctrl
- pOldFont = dc.SelectObject( m_pParentWnd->GetFont() );
- }
- CSize size = dc.GetTextExtent( strTitle );
- TEXTMETRIC tm;
- dc.GetTextMetrics(&tm);
- size.cx += tm.tmOverhang;
- CRect rectDisplay = rectTitle;
- rectDisplay.left += xoffset;
- rectDisplay.right = rectDisplay.left + size.cx + xoffset;
-
- // Do not display if the text fits within available space
- if ( rectDisplay.right > rectTitle.right-xoffset )
- {
- // Show the titletip
- SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top,
- rectDisplay.Width(), rectDisplay.Height(),
- SWP_SHOWWINDOW|SWP_NOACTIVATE );
-
- // FNA - handle colors correctly
- if (crBackClr != CLR_DEFAULT)
- {
- CBrush backBrush(crBackClr);
- CBrush* pOldBrush = dc.SelectObject(&backBrush);
- CRect rect;
- dc.GetClipBox(&rect); // Erase the area needed
- dc.PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
- dc.SelectObject(pOldBrush);
- }
- // Set color
- if (crTextClr != CLR_DEFAULT)//FNA
- dc.SetTextColor(crTextClr);//FA
- dc.SetBkMode( TRANSPARENT );
- dc.TextOut( 0, 0, strTitle );
- SetCapture();
- }
-
- dc.SelectObject( pOldFont );
- }
- void CTitleTip::Hide()
- {
- if (!::IsWindow(GetSafeHwnd()))
- return;
- if (GetCapture()->GetSafeHwnd() == GetSafeHwnd())
- ReleaseCapture();
- ShowWindow( SW_HIDE );
- }
- void CTitleTip::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (!m_rectHover.PtInRect(point))
- {
- Hide();
-
- // Forward the message
- ClientToScreen( &point );
- CWnd *pWnd = WindowFromPoint( point );
- if ( pWnd == this )
- pWnd = m_pParentWnd;
-
- int hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
-
- if (hittest == HTCLIENT) {
- pWnd->ScreenToClient( &point );
- pWnd->PostMessage( WM_MOUSEMOVE, nFlags, MAKELONG(point.x,point.y) );
- } else {
- pWnd->PostMessage( WM_NCMOUSEMOVE, hittest, MAKELONG(point.x,point.y) );
- }
- }
- }
- BOOL CTitleTip::PreTranslateMessage(MSG* pMsg)
- {
- // Used to qualify WM_LBUTTONDOWN messages as double-clicks
- DWORD dwTick=0;
- BOOL bDoubleClick=FALSE;
- CWnd *pWnd;
- int hittest;
- switch (pMsg->message)
- {
- case WM_LBUTTONDOWN:
- // Get tick count since last LButtonDown
- dwTick = GetTickCount();
- bDoubleClick = ((dwTick - m_dwLastLButtonDown) <= m_dwDblClickMsecs);
- m_dwLastLButtonDown = dwTick;
- // NOTE: DO NOT ADD break; STATEMENT HERE! Let code fall through
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- POINTS pts = MAKEPOINTS( pMsg->lParam );
- POINT point;
- point.x = pts.x;
- point.y = pts.y;
- ClientToScreen( &point );
- pWnd = WindowFromPoint( point );
- if( pWnd == this )
- pWnd = m_pParentWnd;
- hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
- if (hittest == HTCLIENT) {
- pWnd->ScreenToClient( &point );
- pMsg->lParam = MAKELONG(point.x,point.y);
- } else {
- switch (pMsg->message) {
- case WM_LBUTTONDOWN:
- pMsg->message = WM_NCLBUTTONDOWN;
- break;
- case WM_RBUTTONDOWN:
- pMsg->message = WM_NCRBUTTONDOWN;
- break;
- case WM_MBUTTONDOWN:
- pMsg->message = WM_NCMBUTTONDOWN;
- break;
- }
- pMsg->wParam = hittest;
- pMsg->lParam = MAKELONG(point.x,point.y);
- }
- Hide();
- // If this is the 2nd WM_LBUTTONDOWN in x milliseconds,
- // post a WM_LBUTTONDBLCLK message instead of a single click.
- pWnd->PostMessage( bDoubleClick ? WM_LBUTTONDBLCLK : pMsg->message,
- pMsg->wParam,
- pMsg->lParam);
- return TRUE;
-
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- Hide();
- m_pParentWnd->PostMessage( pMsg->message, pMsg->wParam, pMsg->lParam );
- return TRUE;
- }
- if( GetFocus() == NULL )
- {
- Hide();
- return TRUE;
- }
- return CWnd::PreTranslateMessage(pMsg);
- }
- #endif // GRIDCONTROL_NO_TITLETIPS