Leaked source code of windows server 2003
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.

349 lines
11 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: Tooltip.cpp
  3. //
  4. // Copyright (c) 2000, Microsoft Corporation
  5. //
  6. // Class that implements displaying a tooltip balloon.
  7. //
  8. // History: 2000-06-12 vtan created
  9. // --------------------------------------------------------------------------
  10. #include "StandardHeader.h"
  11. #include "Tooltip.h"
  12. #include <commctrl.h>
  13. //---------------------------------------------------------------------------
  14. // IsBiDiLocalizedSystem is taken from stockthk.lib and simplified
  15. // (it's only a wrapper for GetUserDefaultUILanguage and GetLocaleInfo)
  16. //---------------------------------------------------------------------------
  17. typedef struct {
  18. LANGID LangID;
  19. BOOL bInstalled;
  20. } MUIINSTALLLANG, *LPMUIINSTALLLANG;
  21. /***************************************************************************\
  22. * ConvertHexStringToIntW
  23. *
  24. * Converts a hex numeric string into an integer.
  25. *
  26. * History:
  27. * 14-June-1998 msadek Created
  28. \***************************************************************************/
  29. BOOL ConvertHexStringToIntW( WCHAR *pszHexNum , int *piNum )
  30. {
  31. int n=0L;
  32. WCHAR *psz=pszHexNum;
  33. for(n=0 ; ; psz=CharNextW(psz))
  34. {
  35. if( (*psz>='0') && (*psz<='9') )
  36. n = 0x10 * n + *psz - '0';
  37. else
  38. {
  39. WCHAR ch = *psz;
  40. int n2;
  41. if(ch >= 'a')
  42. ch -= 'a' - 'A';
  43. n2 = ch - 'A' + 0xA;
  44. if (n2 >= 0xA && n2 <= 0xF)
  45. n = 0x10 * n + n2;
  46. else
  47. break;
  48. }
  49. }
  50. /*
  51. * Update results
  52. */
  53. *piNum = n;
  54. return (psz != pszHexNum);
  55. }
  56. /***************************************************************************\
  57. * Mirror_EnumUILanguagesProc
  58. *
  59. * Enumerates MUI installed languages on W2k
  60. * History:
  61. * 14-June-1999 msadek Created
  62. \***************************************************************************/
  63. BOOL CALLBACK Mirror_EnumUILanguagesProc(LPTSTR lpUILanguageString, LONG_PTR lParam)
  64. {
  65. int langID = 0;
  66. ConvertHexStringToIntW(lpUILanguageString, &langID);
  67. if((LANGID)langID == ((LPMUIINSTALLLANG)lParam)->LangID)
  68. {
  69. ((LPMUIINSTALLLANG)lParam)->bInstalled = TRUE;
  70. return FALSE;
  71. }
  72. return TRUE;
  73. }
  74. /***************************************************************************\
  75. * Mirror_IsUILanguageInstalled
  76. *
  77. * Verifies that the User UI language is installed on W2k
  78. *
  79. * History:
  80. * 14-June-1999 msadek Created
  81. \***************************************************************************/
  82. BOOL Mirror_IsUILanguageInstalled( LANGID langId )
  83. {
  84. MUIINSTALLLANG MUILangInstalled = {0};
  85. MUILangInstalled.LangID = langId;
  86. EnumUILanguagesW(Mirror_EnumUILanguagesProc, 0, (LONG_PTR)&MUILangInstalled);
  87. return MUILangInstalled.bInstalled;
  88. }
  89. /***************************************************************************\
  90. * IsBiDiLocalizedSystemEx
  91. *
  92. * returns TRUE if running on a lozalized BiDi (Arabic/Hebrew) NT5 or Memphis.
  93. * Should be called whenever SetProcessDefaultLayout is to be called.
  94. *
  95. * History:
  96. * 02-Feb-1998 samera Created
  97. \***************************************************************************/
  98. BOOL IsBiDiLocalizedSystemEx( LANGID *pLangID )
  99. {
  100. int iLCID=0L;
  101. static BOOL bRet = (BOOL)(DWORD)-1;
  102. static LANGID langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
  103. if (bRet != (BOOL)(DWORD)-1)
  104. {
  105. if (bRet && pLangID)
  106. {
  107. *pLangID = langID;
  108. }
  109. return bRet;
  110. }
  111. bRet = FALSE;
  112. /*
  113. * Need to use NT5 detection method (Multiligual UI ID)
  114. */
  115. langID = GetUserDefaultUILanguage();
  116. if( langID )
  117. {
  118. WCHAR wchLCIDFontSignature[16];
  119. iLCID = MAKELCID( langID , SORT_DEFAULT );
  120. /*
  121. * Let's verify this is a RTL (BiDi) locale. Since reg value is a hex string, let's
  122. * convert to decimal value and call GetLocaleInfo afterwards.
  123. * LOCALE_FONTSIGNATURE always gives back 16 WCHARs.
  124. */
  125. if( GetLocaleInfoW( iLCID ,
  126. LOCALE_FONTSIGNATURE ,
  127. (WCHAR *) &wchLCIDFontSignature[0] ,
  128. (sizeof(wchLCIDFontSignature)/sizeof(WCHAR))) )
  129. {
  130. /* Let's verify the bits we have a BiDi UI locale */
  131. if(( wchLCIDFontSignature[7] & (WCHAR)0x0800) && Mirror_IsUILanguageInstalled(langID) )
  132. {
  133. bRet = TRUE;
  134. }
  135. }
  136. }
  137. if (bRet && pLangID)
  138. {
  139. *pLangID = langID;
  140. }
  141. return bRet;
  142. }
  143. //---------------------------------------------------------------------------
  144. BOOL IsBiDiLocalizedSystem( void )
  145. {
  146. return IsBiDiLocalizedSystemEx(NULL);
  147. }
  148. // --------------------------------------------------------------------------
  149. // CTooltip::CTooltip
  150. //
  151. // Arguments: hInstance = HINSTANCE of hosting process/DLL.
  152. // hwndParent = HWND of the parenting window.
  153. //
  154. // Returns: <none>
  155. //
  156. // Purpose: Constructor for CTooltip. Creates a tooltip window and
  157. // prepares it for display.
  158. //
  159. // History: 2000-06-12 vtan created
  160. // --------------------------------------------------------------------------
  161. CTooltip::CTooltip (HINSTANCE hInstance, HWND hwndParent) :
  162. CCountedObject(),
  163. _hwnd(NULL),
  164. _hwndParent(hwndParent)
  165. {
  166. DWORD dwExStyle = 0;
  167. if ( ((GetWindowLongA( hwndParent , GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) != 0) || IsBiDiLocalizedSystem() )
  168. {
  169. dwExStyle = WS_EX_LAYOUTRTL;
  170. }
  171. _hwnd = CreateWindowEx(dwExStyle,
  172. TOOLTIPS_CLASS,
  173. NULL,
  174. WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | TTS_BALLOON,
  175. CW_USEDEFAULT,
  176. CW_USEDEFAULT,
  177. CW_USEDEFAULT,
  178. CW_USEDEFAULT,
  179. hwndParent,
  180. NULL,
  181. hInstance,
  182. NULL);
  183. if (_hwnd != NULL)
  184. {
  185. TOOLINFO toolInfo;
  186. TBOOL(SetWindowPos(_hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE));
  187. (LRESULT)SendMessage(_hwnd, CCM_SETVERSION, COMCTL32_VERSION, 0);
  188. ZeroMemory(&toolInfo, sizeof(toolInfo));
  189. toolInfo.cbSize = sizeof(toolInfo);
  190. toolInfo.uFlags = TTF_TRANSPARENT | TTF_TRACK;
  191. toolInfo.uId = PtrToUint(_hwnd);
  192. (LRESULT)SendMessage(_hwnd, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&toolInfo));
  193. (LRESULT)SendMessage(_hwnd, TTM_SETMAXTIPWIDTH, 0, 300);
  194. }
  195. }
  196. // --------------------------------------------------------------------------
  197. // CTooltip::~CTooltip
  198. //
  199. // Arguments: <none>
  200. //
  201. // Returns: <none>
  202. //
  203. // Purpose: Destructor for the CTooltip class. This destroys the tooltip
  204. // window created. If the parent of the tooltip window is
  205. // destroyed before this is invoked user32!DestroyWindow will
  206. // cause the trace to fire. The object's lifetime must be
  207. // carefully managed by the user of this class.
  208. //
  209. // History: 2000-06-12 vtan created
  210. // --------------------------------------------------------------------------
  211. CTooltip::~CTooltip (void)
  212. {
  213. if (_hwnd != NULL)
  214. {
  215. TBOOL(DestroyWindow(_hwnd));
  216. _hwnd = NULL;
  217. }
  218. }
  219. // --------------------------------------------------------------------------
  220. // CTooltip::SetPosition
  221. //
  222. // Arguments: lPosX = X position of the balloon tip window (screen).
  223. // lPosY = Y position of the balloon tip window (screen).
  224. //
  225. // Returns: <none>
  226. //
  227. // Purpose: Positions the tooltip window at the given screen co-ordinates.
  228. // If the parameters are defaulted then this positions the
  229. // tooltip relative to the parent.
  230. //
  231. // History: 2000-06-12 vtan created
  232. // --------------------------------------------------------------------------
  233. void CTooltip::SetPosition (LONG lPosX, LONG lPosY) const
  234. {
  235. if ((lPosX == LONG_MIN) && (lPosY == LONG_MIN))
  236. {
  237. RECT rc;
  238. TBOOL(GetWindowRect(_hwndParent, &rc));
  239. lPosX = (rc.left + rc.right) / 2;
  240. lPosY = rc.bottom;
  241. }
  242. (LRESULT)SendMessage(_hwnd, TTM_TRACKPOSITION, 0, MAKELONG(lPosX, lPosY));
  243. }
  244. // --------------------------------------------------------------------------
  245. // CTooltip::SetCaption
  246. //
  247. // Arguments: dwIcon = Icon type to set for the tooltip caption.
  248. // pszCaption = Caption of the tooltip.
  249. //
  250. // Returns: <none>
  251. //
  252. // Purpose: Sets the tooltip caption.
  253. //
  254. // History: 2000-06-12 vtan created
  255. // --------------------------------------------------------------------------
  256. void CTooltip::SetCaption (DWORD dwIcon, const TCHAR *pszCaption) const
  257. {
  258. (LRESULT)SendMessage(_hwnd, TTM_SETTITLE, dwIcon, reinterpret_cast<LPARAM>(pszCaption));
  259. }
  260. // --------------------------------------------------------------------------
  261. // CTooltip::SetText
  262. //
  263. // Arguments: pszText = Content of the actual tooltip.
  264. //
  265. // Returns: <none>
  266. //
  267. // Purpose: Sets the tooltip text.
  268. //
  269. // History: 2000-06-12 vtan created
  270. // --------------------------------------------------------------------------
  271. void CTooltip::SetText (const TCHAR *pszText) const
  272. {
  273. TOOLINFO toolInfo;
  274. ZeroMemory(&toolInfo, sizeof(toolInfo));
  275. toolInfo.cbSize = sizeof(toolInfo);
  276. toolInfo.uId = PtrToUint(_hwnd);
  277. toolInfo.lpszText = const_cast<TCHAR*>(pszText);
  278. (LRESULT)SendMessage(_hwnd, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&toolInfo));
  279. }
  280. // --------------------------------------------------------------------------
  281. // CTooltip::Show
  282. //
  283. // Arguments: <none>
  284. //
  285. // Returns: <none>
  286. //
  287. // Purpose: Shows the tooltip window.
  288. //
  289. // History: 2000-06-12 vtan created
  290. // --------------------------------------------------------------------------
  291. void CTooltip::Show (void) const
  292. {
  293. TOOLINFO toolInfo;
  294. ZeroMemory(&toolInfo, sizeof(toolInfo));
  295. toolInfo.cbSize = sizeof(toolInfo);
  296. toolInfo.uId = PtrToUint(_hwnd);
  297. (LRESULT)SendMessage(_hwnd, TTM_TRACKACTIVATE, TRUE, reinterpret_cast<LPARAM>(&toolInfo));
  298. }