TitleTip.cpp
上传用户:jzscgs158
上传日期:2022-05-25
资源大小:8709k
文件大小:9k
源码类别:

百货/超市行业

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////////////////
  2. // TitleTip.cpp : implementation file
  3. //
  4. // Based on code by Zafir Anjum
  5. //
  6. // Adapted by Chris Maunder <cmaunder@mail.com>
  7. // Copyright (c) 1998-2000. All Rights Reserved.
  8. //
  9. // This code may be used in compiled form in any way you desire. This
  10. // file may be redistributed unmodified by any means PROVIDING it is 
  11. // not sold for profit without the authors written consent, and 
  12. // providing that this notice and the authors name and all copyright 
  13. // notices remains intact. 
  14. //
  15. // An email letting me know how you are using it would be nice as well. 
  16. //
  17. // This file is provided "as is" with no expressed or implied warranty.
  18. // The author accepts no liability for any damage/loss of business that
  19. // this product may cause.
  20. //
  21. // For use with CGridCtrl v2.20+
  22. //
  23. // History
  24. //         10 Apr 1999  Now accepts a LOGFONT pointer and 
  25. //                      a tracking rect in Show(...)  (Chris Maunder)
  26. //         18 Apr 1999  Resource leak in Show fixed by Daniel Gehriger
  27. //          8 Mar 2000  Added double-click fix found on codeguru
  28. //                      web site but forgot / can't find who contributed it
  29. //         28 Mar 2000  Aqiruse (marked with //FNA)
  30. //                      Titletips now use cell color
  31. //         18 Jun 2000  Delayed window creation added
  32. //
  33. /////////////////////////////////////////////////////////////////////////////
  34.  
  35. #include "stdafx.h"
  36. #include "gridctrl.h"
  37. #ifndef GRIDCONTROL_NO_TITLETIPS
  38. #include "TitleTip.h"
  39. #ifdef _DEBUG
  40. #define new DEBUG_NEW
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #endif
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CTitleTip
  46. CTitleTip::CTitleTip()
  47. {
  48. // Register the window class if it has not already been registered.
  49. WNDCLASS wndcls;
  50. HINSTANCE hInst = AfxGetInstanceHandle();
  51. if(!(::GetClassInfo(hInst, TITLETIP_CLASSNAME, &wndcls)))
  52. {
  53. // otherwise we need to register a new class
  54. wndcls.style = CS_SAVEBITS;
  55. wndcls.lpfnWndProc = ::DefWindowProc;
  56. wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
  57. wndcls.hInstance = hInst;
  58. wndcls.hIcon = NULL;
  59. wndcls.hCursor = LoadCursor( hInst, IDC_ARROW );
  60. wndcls.hbrBackground = (HBRUSH)(COLOR_INFOBK +1);
  61. wndcls.lpszMenuName = NULL;
  62. wndcls.lpszClassName = TITLETIP_CLASSNAME;
  63. if (!AfxRegisterClass(&wndcls))
  64. AfxThrowResourceException();
  65. }
  66.     m_dwLastLButtonDown = ULONG_MAX;
  67.     m_dwDblClickMsecs   = GetDoubleClickTime();
  68.     m_bCreated          = FALSE;
  69. }
  70. CTitleTip::~CTitleTip()
  71. {
  72. }
  73. BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
  74. //{{AFX_MSG_MAP(CTitleTip)
  75. ON_WM_MOUSEMOVE()
  76. //}}AFX_MSG_MAP
  77. END_MESSAGE_MAP()
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CTitleTip message handlers
  80. BOOL CTitleTip::Create(CWnd * pParentWnd)
  81. {
  82. ASSERT_VALID(pParentWnd);
  83.     // Already created?
  84.     if (m_bCreated)
  85.         return TRUE;
  86. DWORD dwStyle = WS_BORDER | WS_POPUP; 
  87. DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
  88. m_pParentWnd = pParentWnd;
  89. m_bCreated = CreateEx(dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle, 
  90.                           CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  91.                   NULL, NULL, NULL );
  92.     return m_bCreated;
  93. }
  94. BOOL CTitleTip::DestroyWindow() 
  95. {
  96.     m_bCreated = FALSE;
  97. return CWnd::DestroyWindow();
  98. }
  99. // Show   - Show the titletip if needed
  100. // rectTitle  - The rectangle within which the original 
  101. //     title is constrained - in client coordinates
  102. // lpszTitleText - The text to be displayed
  103. // xoffset  - Number of pixel that the text is offset from
  104. //    left border of the cell
  105. void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset /*=0*/,
  106.                      LPRECT lpHoverRect /*=NULL*/,
  107.                      const LOGFONT* lpLogFont /*=NULL*/,
  108.                      COLORREF crTextClr /* CLR_DEFAULT */,
  109.                      COLORREF crBackClr /* CLR_DEFAULT */)
  110. {
  111.     if (!IsWindow(m_hWnd))
  112.         Create(m_pParentWnd);
  113. ASSERT( ::IsWindow( GetSafeHwnd() ) );
  114.     if (rectTitle.IsRectEmpty())
  115.         return;
  116. // If titletip is already displayed, don't do anything.
  117. if( IsWindowVisible() ) 
  118. return;
  119.     m_rectHover = (lpHoverRect != NULL)? lpHoverRect : rectTitle;
  120.     m_rectHover.right++; m_rectHover.bottom++;
  121. m_pParentWnd->ClientToScreen( m_rectHover );
  122.     ScreenToClient( m_rectHover );
  123. // Do not display the titletip is app does not have focus
  124. if( GetFocus() == NULL )
  125. return;
  126. // Define the rectangle outside which the titletip will be hidden.
  127. // We add a buffer of one pixel around the rectangle
  128. m_rectTitle.top    = -1;
  129. m_rectTitle.left   = -xoffset-1;
  130. m_rectTitle.right  = rectTitle.Width()-xoffset;
  131. m_rectTitle.bottom = rectTitle.Height()+1;
  132. // Determine the width of the text
  133. m_pParentWnd->ClientToScreen( rectTitle );
  134. CClientDC dc(this);
  135. CString strTitle = _T("");
  136.     strTitle += _T(" ");
  137.     strTitle += lpszTitleText; 
  138.     strTitle += _T(" ");
  139. CFont font, *pOldFont = NULL;
  140.     if (lpLogFont)
  141.     {
  142.         font.CreateFontIndirect(lpLogFont);
  143.     pOldFont = dc.SelectObject( &font );
  144.     }
  145.     else
  146.     {
  147.         // use same font as ctrl
  148.     pOldFont = dc.SelectObject( m_pParentWnd->GetFont() );
  149.     }
  150. CSize size = dc.GetTextExtent( strTitle );
  151.     TEXTMETRIC tm;
  152.     dc.GetTextMetrics(&tm);
  153.     size.cx += tm.tmOverhang;
  154. CRect rectDisplay = rectTitle;
  155. rectDisplay.left += xoffset;
  156. rectDisplay.right = rectDisplay.left + size.cx + xoffset;
  157.     
  158.     // Do not display if the text fits within available space
  159.     if ( rectDisplay.right > rectTitle.right-xoffset )
  160.     {
  161.         // Show the titletip
  162.         SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top, 
  163.             rectDisplay.Width(), rectDisplay.Height(), 
  164.             SWP_SHOWWINDOW|SWP_NOACTIVATE );
  165.         
  166.         // FNA - handle colors correctly
  167.         if (crBackClr != CLR_DEFAULT)
  168.         {
  169.     CBrush backBrush(crBackClr);
  170.     CBrush* pOldBrush = dc.SelectObject(&backBrush);
  171.     CRect rect;
  172.     dc.GetClipBox(&rect);     // Erase the area needed 
  173.     dc.PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),  PATCOPY);
  174.     dc.SelectObject(pOldBrush);
  175.     }
  176.         // Set color
  177.         if (crTextClr != CLR_DEFAULT)//FNA
  178.             dc.SetTextColor(crTextClr);//FA
  179.         dc.SetBkMode( TRANSPARENT );
  180.         dc.TextOut( 0, 0, strTitle );
  181.         SetCapture();
  182.     }
  183.     
  184.     dc.SelectObject( pOldFont );
  185. }
  186. void CTitleTip::Hide()
  187. {
  188.    if (!::IsWindow(GetSafeHwnd()))
  189.         return;
  190.     if (GetCapture()->GetSafeHwnd() == GetSafeHwnd())
  191.         ReleaseCapture();
  192. ShowWindow( SW_HIDE );
  193. }
  194. void CTitleTip::OnMouseMove(UINT nFlags, CPoint point) 
  195. {
  196.     if (!m_rectHover.PtInRect(point)) 
  197.     {
  198.         Hide();
  199.         
  200.         // Forward the message
  201.         ClientToScreen( &point );
  202.         CWnd *pWnd = WindowFromPoint( point );
  203.         if ( pWnd == this ) 
  204.             pWnd = m_pParentWnd;
  205.         
  206.         int hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
  207.         
  208.         if (hittest == HTCLIENT) {
  209.             pWnd->ScreenToClient( &point );
  210.             pWnd->PostMessage( WM_MOUSEMOVE, nFlags, MAKELONG(point.x,point.y) );
  211.         } else {
  212.             pWnd->PostMessage( WM_NCMOUSEMOVE, hittest, MAKELONG(point.x,point.y) );
  213.         }
  214.     }
  215. }
  216. BOOL CTitleTip::PreTranslateMessage(MSG* pMsg) 
  217. {
  218.     // Used to qualify WM_LBUTTONDOWN messages as double-clicks
  219.     DWORD dwTick=0;
  220.     BOOL bDoubleClick=FALSE;
  221.     CWnd *pWnd;
  222. int hittest;
  223. switch (pMsg->message)
  224. {
  225. case WM_LBUTTONDOWN:
  226.        // Get tick count since last LButtonDown
  227.         dwTick = GetTickCount();
  228.         bDoubleClick = ((dwTick - m_dwLastLButtonDown) <= m_dwDblClickMsecs);
  229.         m_dwLastLButtonDown = dwTick;
  230.         // NOTE: DO NOT ADD break; STATEMENT HERE! Let code fall through
  231. case WM_RBUTTONDOWN:
  232. case WM_MBUTTONDOWN:
  233. POINTS pts = MAKEPOINTS( pMsg->lParam );
  234. POINT  point;
  235. point.x = pts.x;
  236. point.y = pts.y;
  237. ClientToScreen( &point );
  238. pWnd = WindowFromPoint( point );
  239. if( pWnd == this ) 
  240. pWnd = m_pParentWnd;
  241. hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
  242. if (hittest == HTCLIENT) {
  243. pWnd->ScreenToClient( &point );
  244. pMsg->lParam = MAKELONG(point.x,point.y);
  245. } else {
  246. switch (pMsg->message) {
  247. case WM_LBUTTONDOWN: 
  248. pMsg->message = WM_NCLBUTTONDOWN;
  249. break;
  250. case WM_RBUTTONDOWN: 
  251. pMsg->message = WM_NCRBUTTONDOWN;
  252. break;
  253. case WM_MBUTTONDOWN: 
  254. pMsg->message = WM_NCMBUTTONDOWN;
  255. break;
  256. }
  257. pMsg->wParam = hittest;
  258. pMsg->lParam = MAKELONG(point.x,point.y);
  259. }
  260.         Hide();
  261.         // If this is the 2nd WM_LBUTTONDOWN in x milliseconds,
  262.         // post a WM_LBUTTONDBLCLK message instead of a single click.
  263.         pWnd->PostMessage(  bDoubleClick ? WM_LBUTTONDBLCLK : pMsg->message,
  264.                             pMsg->wParam,
  265.                             pMsg->lParam);
  266. return TRUE;
  267. case WM_KEYDOWN:
  268. case WM_SYSKEYDOWN:
  269.         Hide();
  270. m_pParentWnd->PostMessage( pMsg->message, pMsg->wParam, pMsg->lParam );
  271. return TRUE;
  272. }
  273. if( GetFocus() == NULL )
  274. {
  275.         Hide();
  276. return TRUE;
  277. }
  278. return CWnd::PreTranslateMessage(pMsg);
  279. }
  280. #endif // GRIDCONTROL_NO_TITLETIPS