MFECToolTip.cpp
上传用户:sdpcwz
上传日期:2009-12-14
资源大小:1237k
文件大小:8k
源码类别:

书籍源码

开发平台:

Visual C++

  1. // Author: Ferdinand V. Abne
  2. // Email : fabne@bigfoot.com
  3. // Revision History:
  4. // July 16, 1998 - Creation
  5. #include "stdafx.h"
  6. #include "MFECToolTip.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CMFECToolTip
  14. CMFECToolTip::CMFECToolTip()
  15. {
  16. m_nHeight = 0;
  17. m_nWidth = 0;
  18. m_nFontSize = 14; // original size
  19. m_currentControlID = 0;
  20. m_pParentWnd = NULL;
  21. m_aControlInfo.RemoveAll();
  22. }
  23. CMFECToolTip::~CMFECToolTip()
  24. {
  25. ToolTipInfo *pInfo = NULL;
  26. int nSize = m_aControlInfo.GetSize();
  27. for( int i = 0; i < nSize; i++ )
  28. {
  29. pInfo = (ToolTipInfo*)m_aControlInfo.GetAt( i );
  30. delete pInfo;
  31. }
  32. m_aControlInfo.RemoveAll();
  33. }
  34. void CMFECToolTip::Create(CWnd* pWnd)
  35. {
  36. m_pParentWnd = pWnd;
  37. }
  38. void CMFECToolTip::ErasePreviousToolTipDisplay( UINT nControlID )
  39. {
  40. //This assertion fails because you did not call Create() first.
  41. //m_pParentWnd was not initialized.
  42. ASSERT(m_pParentWnd);
  43. //if erase already, do not do it again
  44. if((m_nHeight == 0) || (m_nWidth == 0))
  45. return;
  46. CRect oInfoRect(0,0,0,0);
  47. CalculateInfoBoxRect(nControlID, &oInfoRect);
  48. m_pParentWnd->InvalidateRect(&oInfoRect);
  49. m_pParentWnd->UpdateWindow();
  50. m_nHeight = 0;
  51. m_nWidth = 0;
  52. }
  53. void 
  54. CMFECToolTip::CalculateHeightAndWidth(CStringArray& straInfos)
  55. {
  56. //This assertion fails because you did not call Create() first.
  57. //m_pParentWnd was not initialized.
  58. ASSERT(m_pParentWnd);
  59. int nMaxLength = 0;
  60. int nLength;
  61. int nLine = straInfos.GetSize();
  62. m_nTotalLine = nLine; // holder for maximum line of information
  63. for(int i=0; i<nLine; i++)
  64. {
  65. nLength = (straInfos[i]).GetLength();
  66. if(nLength > nMaxLength)
  67. nMaxLength = nLength;
  68. }
  69. m_maxCharInLine = nMaxLength; // holder for longest char info
  70. m_nHeight = 12 + nLine * (m_nFontSize - 1); //m_nFontSize is the font size
  71. m_nWidth = 10 + (int)(7.5 * nMaxLength); //aproximately 5 pixel per char
  72. }
  73. void CMFECToolTip::CalculateInfoBoxRect(UINT nControlID, CRect* pInfoRect)
  74. {
  75. ASSERT(m_pParentWnd);
  76. CRect oRect(0,0,0,0);
  77. CRect oParentWindowRect(0,0,0,0);
  78. m_pParentWnd->GetWindowRect(&oParentWindowRect);
  79. m_pParentWnd->ScreenToClient(&oParentWindowRect);
  80. CWnd* pWnd = m_pParentWnd->GetDlgItem(nControlID);
  81. ASSERT(pWnd);
  82. pWnd->GetWindowRect(&oRect);
  83. m_pParentWnd->ScreenToClient(&oRect);
  84. //check if the box fit in the parent dialog 
  85. SetFontSize( 14 );
  86. int nBottom = oRect.bottom - ((oRect.bottom - oRect.top)/2) + m_nHeight;
  87. if(nBottom <= oParentWindowRect.bottom)
  88. {
  89. pInfoRect->top = oRect.bottom - (oRect.bottom - oRect.top)/2;
  90. pInfoRect->bottom = pInfoRect->top + m_nHeight;
  91. }
  92. else
  93. {
  94. // change the size of the font as well as the info box if all
  95. // info data cannot be viewed
  96. if( m_nHeight > (oParentWindowRect.bottom - oParentWindowRect.top) )
  97. {
  98. SetFontSize( 12 );
  99. m_nHeight = 12 + m_nTotalLine * (m_nFontSize - 1); //m_nFontSize is the font size
  100. m_nWidth = 10 + (int)(7 * m_maxCharInLine);
  101. }
  102. // end
  103. pInfoRect->bottom = oParentWindowRect.bottom - 1;
  104. pInfoRect->top = pInfoRect->bottom - m_nHeight;
  105. }
  106. //check if the box fit in the parent dialog
  107. int nRight = (oRect.left + oRect.right)/2 + m_nWidth;
  108. if(nRight <= oParentWindowRect.right)
  109. {
  110. pInfoRect->left = (oRect.left + oRect.right)/2;
  111. pInfoRect->right = pInfoRect->left + m_nWidth;
  112. }
  113. else
  114. {
  115. int nLeft = (oRect.left + oRect.right)/2 - m_nWidth;
  116. if(nLeft <= oParentWindowRect.left)
  117. {
  118. pInfoRect->left = oParentWindowRect.left + 1;
  119. pInfoRect->right = pInfoRect->left + m_nWidth;
  120. }
  121. else
  122. {
  123. pInfoRect->right = (oRect.left + oRect.right)/2;
  124. pInfoRect->left = pInfoRect->right - m_nWidth;
  125. }
  126. }
  127. ASSERT(pInfoRect->top <= pInfoRect->bottom);
  128. ASSERT(pInfoRect->left <= pInfoRect->right);
  129. }
  130. void CMFECToolTip::ShowToolTip( UINT nControlID )
  131. {
  132. ToolTipInfo *pToolTip = IsControlIDExisting( nControlID );
  133. if( pToolTip == NULL )
  134. return;
  135. DisplayInfo( pToolTip );
  136. }
  137. void CMFECToolTip::ShowToolTip( CPoint& point )
  138. {
  139. CWnd*   pWnd = m_pParentWnd->ChildWindowFromPoint(point);
  140. if( pWnd )
  141. {
  142. UINT nControlID = (UINT)pWnd->GetDlgCtrlID();
  143. if( m_currentControlID != nControlID )
  144. {
  145. ErasePreviousToolTipDisplay( m_currentControlID );
  146. ShowToolTip( nControlID );
  147. }
  148. }
  149. }
  150. void CMFECToolTip::DisplayInfo( ToolTipInfo* pToolTip )
  151. {
  152. if( pToolTip->nInfoSize <= 0 )
  153. return;
  154. ASSERT(m_pParentWnd);
  155. CDC* pDC = m_pParentWnd->GetDC();
  156. CRect oInfoRect;
  157. CBrush oBrush, *pOldBrush, oBorderBrush;
  158. int nX, nY;
  159. TEXTMETRIC TM;
  160. int nTextHigh;
  161. CFont oFont, *pOldFont;
  162. CWnd* pWnd = NULL;
  163. pDC->SetBkMode(TRANSPARENT);
  164. oBrush.CreateSolidBrush( pToolTip->nBackColor );
  165. pOldBrush = pDC->SelectObject( &oBrush );
  166. pDC->SetTextColor( pToolTip->nTextColor );
  167. //calculate the width and height of the box dynamically
  168. CalculateHeightAndWidth( pToolTip->nControlInfo );
  169. CalculateInfoBoxRect( pToolTip->nControlID, &oInfoRect );
  170. oFont.CreateFont(m_nFontSize, 0, 0, 0, FW_REGULAR, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
  171. pOldFont = pDC->SelectObject(&oFont);
  172. pDC->FillRect(&oInfoRect, &oBrush);
  173. pDC->SelectObject(pOldBrush);
  174. oBrush.DeleteObject();
  175. oBorderBrush.CreateSolidBrush( pToolTip->nTextColor );
  176. pOldBrush = pDC->SelectObject(&oBorderBrush);
  177. DrawEdge(pDC->m_hDC, &oInfoRect, BDR_RAISEDINNER | BDR_SUNKENOUTER, BF_RECT);
  178. pDC->SetTextAlign(TA_LEFT);
  179. pDC->GetTextMetrics(&TM);
  180. nTextHigh = TM.tmHeight + TM.tmExternalLeading - 2;
  181. nX = oInfoRect.left + 8;
  182. nY = oInfoRect.top + 5; 
  183. for( register UINT i = 0; i < pToolTip->nInfoSize; i++)
  184. {
  185. pDC->TextOut(nX, nY, pToolTip->nControlInfo[i]);
  186. nY += m_nFontSize - 1;
  187. }
  188. pDC->SelectObject(pOldBrush);
  189. oBorderBrush.DeleteObject();
  190. m_pParentWnd->ReleaseDC(pDC);
  191. }
  192. BOOL CMFECToolTip::AddControlInfo( UINT contolID, CStringArray& straInfo, COLORREF back, COLORREF text )
  193. {
  194. ToolTipInfo *pToolTip = new ToolTipInfo;
  195. ASSERT( pToolTip != NULL );
  196. int nSize = straInfo.GetSize();
  197. if( pToolTip <= 0 ) // no information, don't add to the list and return FALSE
  198. {
  199. delete pToolTip;
  200. return FALSE;
  201. }
  202. pToolTip->nControlInfo.RemoveAll();
  203. pToolTip->nInfoSize  = nSize;
  204. pToolTip->nControlID = contolID;
  205. for( register int i = 0; i < nSize; i++ )
  206. {
  207. pToolTip->nControlInfo.Add( straInfo[i] );
  208. }
  209. // initialize colors, use default if not supplied
  210. pToolTip->nBackColor = back;
  211. pToolTip->nTextColor = text;
  212. // add to the list
  213. m_aControlInfo.Add( pToolTip );
  214. return TRUE;
  215. }
  216. ToolTipInfo* CMFECToolTip::IsControlIDExisting( UINT controlID )
  217. {
  218. ToolTipInfo *pToolTip = NULL;
  219. int nSize = m_aControlInfo.GetSize();
  220. for( register int i = 0; i < nSize; i++ )
  221. {
  222. pToolTip = (ToolTipInfo*)m_aControlInfo.GetAt( i );
  223. if( pToolTip->nControlID == controlID ) // if found!
  224. {
  225. m_currentControlID = controlID;
  226. return pToolTip;
  227. }
  228. }
  229. m_currentControlID = 0; // if not found, reset the current control ID to refresh the display
  230. return NULL;
  231. }
  232. BOOL CMFECToolTip::RemoveControlInfo( UINT controlID )
  233. {
  234. ToolTipInfo *pToolTip = NULL;
  235. int nSize = m_aControlInfo.GetSize();
  236. for( register int i = 0; i < nSize; i++ )
  237. {
  238. pToolTip = (ToolTipInfo*)m_aControlInfo.GetAt( i );
  239. if( pToolTip->nControlID == controlID ) // if found!
  240. {
  241. if( m_currentControlID == controlID )
  242. ErasePreviousToolTipDisplay( m_currentControlID );
  243. m_aControlInfo.RemoveAt( i ); // remove the entry
  244. delete pToolTip;
  245. break; // break from the loop
  246. }
  247. }
  248. return TRUE;
  249. }