Popup.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "stdafx.h"
  2. #include "Popup.h"
  3. #include "Misc.h"
  4. void InitToolInfo( TOOLINFO& ti )
  5. {
  6. // INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE
  7. ti.cbSize = TTTOOLINFO_V1_SIZE;
  8. ti.uFlags = TTF_ABSOLUTE | TTF_TRACK;
  9. ti.hwnd = NULL;
  10. ti.hinst = NULL;
  11. ti.uId = 0; // CPopup only uses uid 0
  12. ti.lpszText = NULL;
  13. // ToolTip control will cover the whole window
  14. ti.rect.left = 0;
  15. ti.rect.top = 0;
  16. ti.rect.right = 0;
  17. ti.rect.bottom = 0;
  18. }
  19. /*------------------------------------------------------------------*\
  20. CPopup - a tooltip that pops up manually (when Show is called).
  21. - technique learned from codeproject "ToolTipZen" by "Zarembo Maxim"
  22. \*------------------------------------------------------------------*/
  23. CPopup::CPopup()
  24. {
  25. Init();
  26. }
  27. // HWND_TOP
  28. CPopup::CPopup( int x, int y, HWND hWndPosRelativeTo, HWND hWndInsertAfter )
  29. {
  30. Init();
  31. m_hWndPosRelativeTo = hWndPosRelativeTo;
  32. m_hWndInsertAfter = hWndInsertAfter;
  33. SetPos( CPoint(x,y) );
  34. }
  35. CPopup::~CPopup()
  36. {
  37. Hide();
  38. if( m_bOwnTT && ::IsWindow(m_hTTWnd) )
  39. ::DestroyWindow( m_hTTWnd );
  40. }
  41. void CPopup::Init()
  42. {
  43. // initialize variables
  44. m_bOwnTT = false;
  45. m_hTTWnd = NULL;
  46. m_bIsShowing = false;
  47. m_bAllowShow = true; // used by AllowShow()
  48. m_Pos.x = m_Pos.y = 0;
  49. m_bTop = true;
  50. m_bLeft = true;
  51. m_bCenterX = false;
  52. m_bCenterY = false;
  53. m_hWndPosRelativeTo = NULL;
  54. RECT rcScreen;
  55. GetMonitorRect(-1, &rcScreen);
  56. m_ScreenMaxX = rcScreen.right;
  57. m_ScreenMaxY = rcScreen.bottom;
  58. m_hWndInsertAfter = HWND_TOP; //HWND_TOPMOST
  59. SetTTWnd();
  60. }
  61. void CPopup::SetTTWnd( HWND hTTWnd, TOOLINFO* pTI )
  62. {
  63. if( pTI )
  64. m_TI = *pTI;
  65. else
  66. InitToolInfo( m_TI );
  67. if( m_bOwnTT && ::IsWindow(m_hTTWnd) )
  68. {
  69. if( !::IsWindow(hTTWnd) )
  70. return; // we would have to recreate the one that already exists
  71. ::DestroyWindow( m_hTTWnd );
  72. }
  73. m_hTTWnd = hTTWnd;
  74. if( ::IsWindow(m_hTTWnd) )
  75. {
  76. m_bOwnTT = false;
  77. // if our uid tooltip already exists, get the data, else add it.
  78. if( ! ::SendMessage(m_hTTWnd, TTM_GETTOOLINFO, 0, (LPARAM)(LPTOOLINFO) &m_TI) )
  79. ::SendMessage(m_hTTWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &m_TI);
  80. }
  81. else
  82. {
  83. m_bOwnTT = true;
  84. CreateToolTip();
  85. }
  86. }
  87. void CPopup::CreateToolTip()
  88. {
  89. if( m_hTTWnd != NULL )
  90. return;
  91. // CREATE A TOOLTIP WINDOW
  92. m_hTTWnd = CreateWindowEx(
  93. WS_EX_TOPMOST,
  94. TOOLTIPS_CLASS,
  95. NULL,
  96. TTS_NOPREFIX | TTS_ALWAYSTIP,
  97. CW_USEDEFAULT,
  98. CW_USEDEFAULT,
  99. CW_USEDEFAULT,
  100. CW_USEDEFAULT,
  101. NULL,
  102. NULL,
  103. NULL,
  104. NULL
  105. );
  106. m_bOwnTT = true;
  107. // SEND AN ADDTOOL MESSAGE TO THE TOOLTIP CONTROL WINDOW
  108. ::SendMessage(m_hTTWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &m_TI);
  109. }
  110. void CPopup::SetTimeout( int timeout )
  111. {
  112. if( m_hTTWnd == NULL )
  113. return;
  114. ::SendMessage(m_hTTWnd, TTM_SETDELAYTIME, TTDT_AUTOMATIC, timeout);
  115. }
  116. void CPopup::SetPos( CPoint& pos )
  117. {
  118. m_Pos = pos;
  119. }
  120. void CPopup::SetPosInfo( bool bTop, bool bCenterY, bool bLeft, bool bCenterX )
  121. {
  122. m_bTop = bTop;
  123. m_bCenterY = bCenterY;
  124. m_bLeft = bLeft;
  125. m_bCenterX = bCenterX;
  126. }
  127. void CPopup::AdjustPos( CPoint& pos )
  128. {
  129. CRect rel(0,0,0,0);
  130. CRect rect(0,0,0,0);
  131. // ::SendMessage(m_hTTWnd, TTM_ADJUSTRECT, TRUE, (LPARAM)&rect);
  132. ::GetWindowRect(m_hTTWnd,&rect);
  133. if( ::IsWindow(m_hWndPosRelativeTo) )
  134. ::GetWindowRect(m_hWndPosRelativeTo, &rel);
  135. // move the rect to the relative origin
  136. rect.bottom = rect.Height() + rel.top;
  137. rect.top = rel.top;
  138. rect.right = rect.Width() + rel.left;
  139. rect.left = rel.left;
  140. // adjust the y position
  141. rect.OffsetRect( 0, pos.y - (m_bCenterY? rect.Height()/2: (m_bTop? 0: rect.Height())) );
  142. if( rect.bottom > m_ScreenMaxY )
  143. rect.OffsetRect( 0, m_ScreenMaxY - rect.bottom );
  144. // adjust the x position
  145. rect.OffsetRect( pos.x - (m_bCenterX? rect.Width()/2: (m_bLeft? 0: rect.Width())), 0 );
  146. if( rect.right > m_ScreenMaxX )
  147. rect.OffsetRect( m_ScreenMaxX - rect.right, 0 );
  148. pos.x = rect.left;
  149. pos.y = rect.top;
  150. }
  151. void CPopup::SendToolTipText( CString text )
  152. {
  153. m_csToolTipText = text;
  154. //Replace the tabs with spaces, the tooltip didn't like the \t s
  155. text.Replace(_T("\t"), _T(" "));
  156. m_TI.lpszText = (LPTSTR) (LPCTSTR) text;
  157. // this allows \n and \r to be interpreted correctly
  158. ::SendMessage(m_hTTWnd, TTM_SETMAXTIPWIDTH, 0, 500);
  159. // set the text
  160. ::SendMessage(m_hTTWnd, TTM_SETTOOLINFO, 0, (LPARAM) (LPTOOLINFO) &m_TI);
  161. }
  162. void CPopup::Show( CString text, CPoint pos, bool bAdjustPos )
  163. {
  164. if( m_hTTWnd == NULL )
  165. return;
  166. m_csToolTipText = text;
  167. if( !m_bIsShowing )
  168. ::SendMessage(m_hTTWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG(-10000,-10000));
  169. SendToolTipText( text );
  170. ::SendMessage(m_hTTWnd, TTM_TRACKACTIVATE, true, (LPARAM)(LPTOOLINFO) &m_TI);
  171. if( bAdjustPos )
  172. AdjustPos(pos);
  173. // set the position
  174. ::SendMessage(m_hTTWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG(pos.x,pos.y));
  175. // make sure the tooltip will be on top.
  176. ::SetWindowPos( m_hTTWnd, m_hWndInsertAfter, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE );
  177. m_bIsShowing = true;
  178. }
  179. void CPopup::Show( CString text )
  180. {
  181. m_csToolTipText = text;
  182. Show( text, m_Pos );
  183. }
  184. void CPopup::AllowShow( CString text )
  185. {
  186. m_csToolTipText = text;
  187. if( m_bAllowShow )
  188. Show( text, m_Pos );
  189. }
  190. void CPopup::Hide()
  191. {
  192. if( m_hTTWnd == NULL )
  193. return;
  194. // deactivate if it is currently activated
  195. ::SendMessage(m_hTTWnd, TTM_TRACKACTIVATE, FALSE, (LPARAM)(LPTOOLINFO) &m_TI);
  196. m_bIsShowing = false;
  197. }