Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
7.7 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: tooltip.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: This module contains the code for the implementing balloon tips.
  8. //
  9. // Copyright (c) 1996-2000 Microsoft Corporation
  10. //
  11. // Author: markcl Created Header 11/2/00
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. WNDPROC CBalloonTip::m_pfnOrgBalloonWndProc = NULL;
  16. //+----------------------------------------------------------------------------
  17. //
  18. // Function: CBalloonTip::CBalloonTip
  19. //
  20. // Synopsis: Balloon tip constructor
  21. //
  22. // Arguments: nothing
  23. //
  24. // Returns: nothing
  25. //
  26. // History: markcl Created Header 10/31/00
  27. //
  28. //+----------------------------------------------------------------------------
  29. CBalloonTip::CBalloonTip()
  30. {
  31. // Nothing to do
  32. }
  33. //+----------------------------------------------------------------------------
  34. //
  35. // Function: CBalloonTip::DisplayBallonTip
  36. //
  37. // Synopsis: Displays a balloon tip
  38. //
  39. // Arguments: LLPOINT lppoint - pointer to a POINT struct with the coordinates for displaying
  40. // int iIcon - type of icon to display in the balloon tip
  41. // LPCTSTR lpszTitle - Title of the balloon tip window
  42. // LPTSTR lpszBalloonMsg - Message to display in the balloon tip
  43. // HWND hWndParent - handle to the parent window
  44. //
  45. // Returns: nothing
  46. //
  47. // History: markcl Created Header 10/31/00
  48. //
  49. //+----------------------------------------------------------------------------
  50. BOOL CBalloonTip::DisplayBalloonTip(LPPOINT lppoint, UINT iIcon, LPCTSTR lpszTitle, LPTSTR lpszBalloonMsg, HWND hWndParent)
  51. {
  52. //
  53. // If we don't have a message or a position, we don't display the balloon tip.
  54. //
  55. if (NULL == lpszBalloonMsg || NULL == lppoint)
  56. {
  57. MYDBGASSERT(lpszBalloonMsg && lppoint);
  58. return FALSE;
  59. }
  60. //
  61. // Comctl32.dll must be 5.80 or greater to use balloon tips. We check the dll version
  62. // by calling DllGetVersion in comctl32.dll.
  63. //
  64. HINSTANCE hComCtl = LoadLibraryExA("comctl32.dll", NULL, 0);
  65. CMASSERTMSG(hComCtl, TEXT("LoadLibrary - comctl32 failed for Balloon Tips"));
  66. if (hComCtl != NULL)
  67. {
  68. typedef HRESULT (*DLLGETVERSIONPROC)(DLLVERSIONINFO* lpdvi);
  69. DLLGETVERSIONPROC fnDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hComCtl,"DllGetVersion");
  70. MYDBGASSERT(fnDllGetVersion);
  71. if (NULL == fnDllGetVersion)
  72. {
  73. //
  74. // DllGetVersion does not exist in Comctl32.dll. This mean the version is too old so we need to fail.
  75. //
  76. FreeLibrary(hComCtl);
  77. return FALSE;
  78. }
  79. else
  80. {
  81. DLLVERSIONINFO dvi;
  82. ZeroMemory(&dvi, sizeof(dvi));
  83. dvi.cbSize = sizeof(dvi);
  84. HRESULT hResult = (*fnDllGetVersion)(&dvi);
  85. FreeLibrary(hComCtl);
  86. if (SUCCEEDED(hResult))
  87. {
  88. //
  89. // Take the version returned and compare it to 5.80.
  90. //
  91. if (MAKELONG(dvi.dwMinorVersion,dvi.dwMajorVersion) < MAKELONG(80,5))
  92. {
  93. CMTRACE2(TEXT("COMCTL32.DLL version - %d.%d"),dvi.dwMajorVersion,dvi.dwMinorVersion);
  94. CMTRACE1(TEXT("COMCTL32.DLL MAKELONG - %li"),MAKELONG(dvi.dwMinorVersion,dvi.dwMajorVersion));
  95. CMTRACE1(TEXT("Required minimum MAKELONG - %li"),MAKELONG(80,5));
  96. // Wrong DLL version
  97. return FALSE;
  98. }
  99. }
  100. else
  101. {
  102. CMASSERTMSG(FALSE, TEXT("Call to DllGetVersion in comctl32.dll failed."));
  103. return FALSE;
  104. }
  105. }
  106. }
  107. //
  108. // Hide any existing balloon tips before trying to display a new one.
  109. //
  110. if (m_hwndTT && m_bTTActive)
  111. {
  112. HideBalloonTip();
  113. }
  114. //
  115. // Create the Balloon ToolTip window
  116. //
  117. m_hwndTT = CreateWindowExU(NULL,TOOLTIPS_CLASS, TEXT("CM Balloon Tip Window"),
  118. WS_POPUP | TTS_BALLOON, CW_USEDEFAULT, CW_USEDEFAULT,
  119. CW_USEDEFAULT, CW_USEDEFAULT, hWndParent, NULL, g_hInst, NULL);
  120. if (m_hwndTT)
  121. {
  122. m_ti.cbSize = sizeof(m_ti);
  123. m_ti.uFlags = TTF_TRACK;
  124. m_ti.hwnd = hWndParent;
  125. m_ti.hinst = g_hInst;
  126. SendMessageU(m_hwndTT,TTM_ADDTOOL,0,(LPARAM) (LPTOOLINFO) &m_ti);
  127. SendMessageU(m_hwndTT,TTM_SETMAXTIPWIDTH,0,200);
  128. }
  129. else
  130. {
  131. MYDBGASSERT(m_hwndTT);
  132. return FALSE;
  133. }
  134. //
  135. // Subclass the edit control
  136. //
  137. m_pfnOrgBalloonWndProc = (WNDPROC)SetWindowLongU(m_hwndTT, GWLP_WNDPROC, (LONG_PTR)SubClassBalloonWndProc);
  138. //
  139. // Save the this pointer with the window
  140. //
  141. SetWindowLongU(m_hwndTT, GWLP_USERDATA, (LONG_PTR)this);
  142. //
  143. // Set the balloon message
  144. //
  145. m_ti.lpszText = lpszBalloonMsg;
  146. SendMessageU(m_hwndTT,TTM_UPDATETIPTEXT,0,(LPARAM) (LPTOOLINFO) &m_ti);
  147. //
  148. // If we got a title, then add it
  149. //
  150. if (lpszTitle)
  151. {
  152. //
  153. // confirm we have a valid icon
  154. //
  155. if (iIcon > 3)
  156. {
  157. iIcon = TTI_NONE; // TTI_NONE = No icon
  158. }
  159. SendMessageU(m_hwndTT,TTM_SETTITLE,(WPARAM) iIcon,(LPARAM) lpszTitle);
  160. }
  161. //
  162. // Set the position
  163. //
  164. SendMessageU(m_hwndTT,TTM_TRACKPOSITION,0,(LPARAM) (DWORD) MAKELONG(lppoint->x,lppoint->y));
  165. //
  166. // Show balloon tip window
  167. //
  168. SendMessageU(m_hwndTT,TTM_TRACKACTIVATE,(WPARAM) TRUE,(LPARAM) (LPTOOLINFO) &m_ti);
  169. // Set active state
  170. m_bTTActive = TRUE;
  171. return TRUE;
  172. }
  173. //+----------------------------------------------------------------------------
  174. //
  175. // Function: CBalloonTip::HideBallonTip
  176. //
  177. // Synopsis: Hides a balloon tip
  178. //
  179. // Arguments: nothing
  180. //
  181. // Returns: nothing
  182. //
  183. // History: markcl Created Header 10/31/00
  184. //
  185. //+----------------------------------------------------------------------------
  186. BOOL CBalloonTip::HideBalloonTip()
  187. {
  188. // check active state && handle
  189. if(m_hwndTT && m_bTTActive)
  190. {
  191. // hide window
  192. SendMessageU(m_hwndTT,TTM_TRACKACTIVATE,(WPARAM) FALSE,(LPARAM) (LPTOOLINFO) &m_ti);
  193. m_bTTActive = FALSE;
  194. // force a repaint on parent window
  195. InvalidateRect(m_ti.hwnd,NULL,NULL);
  196. // destroy window
  197. DestroyWindow(m_hwndTT);
  198. m_hwndTT = NULL;
  199. return TRUE;
  200. }
  201. else
  202. {
  203. return FALSE;
  204. }
  205. }
  206. //+----------------------------------------------------------------------------
  207. //
  208. // Function: CBalloonTip::SubClassBalloonWndProc
  209. //
  210. // Synopsis: Subclassed wnd proc to trap the mouse button clicks on the balloon tip window
  211. //
  212. // Arguments: standard win32 window proc params
  213. //
  214. // Returns: standard win32 window proc return value
  215. //
  216. // History: markcl created 11/2/00
  217. //
  218. //+----------------------------------------------------------------------------
  219. LRESULT CALLBACK CBalloonTip::SubClassBalloonWndProc(HWND hwnd, UINT uMsg,
  220. WPARAM wParam, LPARAM lParam)
  221. {
  222. if ((uMsg == WM_LBUTTONDOWN) || (uMsg == WM_RBUTTONDOWN))
  223. {
  224. //
  225. // Get the object pointer saved by SetWindowLong
  226. //
  227. CBalloonTip* pBalloonTip = (CBalloonTip*)GetWindowLongU(hwnd, GWLP_USERDATA);
  228. MYDBGASSERT(pBalloonTip);
  229. if (pBalloonTip)
  230. {
  231. pBalloonTip->HideBalloonTip();
  232. }
  233. }
  234. //
  235. // Call the original window procedure for default processing.
  236. //
  237. return CallWindowProcU(m_pfnOrgBalloonWndProc, hwnd, uMsg, wParam, lParam);
  238. }