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.

265 lines
7.3 KiB

  1. //
  2. // APITHK.C
  3. //
  4. // This file has API thunks that allow comctl32 to load and run on
  5. // multiple versions of NT or Win95. Since this component needs
  6. // to load on the base-level NT 4.0 and Win95, any calls to system
  7. // APIs introduced in later OS versions must be done via GetProcAddress.
  8. //
  9. // Also, any code that may need to access data structures that are
  10. // post-4.0 specific can be added here.
  11. //
  12. // NOTE: this file does *not* use the standard precompiled header,
  13. // so it can set _WIN32_WINNT to a later version.
  14. //
  15. #include "ctlspriv.h" // Don't use precompiled header here
  16. typedef BOOL (* PFNANIMATEWINDOW)(HWND hwnd, DWORD dwTime, DWORD dwFlags);
  17. /*----------------------------------------------------------
  18. Purpose: Thunk for NT 5's AnimateWindow.
  19. Returns:
  20. Cond: --
  21. */
  22. BOOL
  23. NT5_AnimateWindow(
  24. IN HWND hwnd,
  25. IN DWORD dwTime,
  26. IN DWORD dwFlags)
  27. {
  28. BOOL bRet = FALSE;
  29. static PFNANIMATEWINDOW pfn = NULL;
  30. if (NULL == pfn)
  31. {
  32. HMODULE hmod = GetModuleHandle(TEXT("USER32"));
  33. if (hmod)
  34. pfn = (PFNANIMATEWINDOW)GetProcAddress(hmod, "AnimateWindow");
  35. }
  36. if (pfn)
  37. bRet = pfn(hwnd, dwTime, dwFlags);
  38. return bRet;
  39. }
  40. /*----------------------------------------------------------
  41. Purpose: Shows the tooltip. On NT4/Win95, this is a standard
  42. show window. On NT5/Memphis, this slides the tooltip
  43. bubble from an invisible point.
  44. Returns: --
  45. Cond: --
  46. */
  47. #define CMS_TOOLTIP 135
  48. void SlideAnimate(HWND hwnd, LPCRECT prc)
  49. {
  50. DWORD dwPos, dwFlags;
  51. dwPos = GetMessagePos();
  52. if (GET_Y_LPARAM(dwPos) > prc->top + (prc->bottom - prc->top) / 2)
  53. {
  54. dwFlags = AW_VER_NEGATIVE;
  55. }
  56. else
  57. {
  58. dwFlags = AW_VER_POSITIVE;
  59. }
  60. AnimateWindow(hwnd, CMS_TOOLTIP, dwFlags | AW_SLIDE);
  61. }
  62. STDAPI_(void) CoolTooltipBubble(IN HWND hwnd, IN LPCRECT prc, BOOL fAllowFade, BOOL fAllowAnimate)
  63. {
  64. ASSERT(prc);
  65. if (g_bRunOnNT5 || g_bRunOnMemphis)
  66. {
  67. BOOL fAnimate = TRUE;
  68. SystemParametersInfo(SPI_GETTOOLTIPANIMATION, 0, &fAnimate, 0);
  69. if (fAnimate)
  70. {
  71. fAnimate = FALSE;
  72. SystemParametersInfo(SPI_GETTOOLTIPFADE, 0, &fAnimate, 0);
  73. if (fAnimate && fAllowFade)
  74. {
  75. AnimateWindow(hwnd, CMS_TOOLTIP, AW_BLEND);
  76. }
  77. else if (fAllowAnimate)
  78. {
  79. SlideAnimate(hwnd, prc);
  80. }
  81. else
  82. goto UseSetWindowPos;
  83. }
  84. else
  85. goto UseSetWindowPos;
  86. }
  87. else
  88. {
  89. UseSetWindowPos:
  90. SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
  91. SWP_NOACTIVATE|SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
  92. }
  93. }
  94. /*----------------------------------------------------------
  95. Purpose: Get the COLOR_HOTLIGHT system color index from NT5 or Memphis.
  96. Get COLOR_HIGHLIGHT from NT4 or Win95, where COLOR_HOTLIGHT is not defined.
  97. Returns: --
  98. Cond: --
  99. */
  100. int GetCOLOR_HOTLIGHT()
  101. {
  102. return (g_bRunOnNT5 || g_bRunOnMemphis) ? COLOR_HOTLIGHT : COLOR_HIGHLIGHT;
  103. }
  104. STDAPI_(HCURSOR) LoadHandCursor(DWORD dwRes)
  105. {
  106. if (g_bRunOnNT5 || g_bRunOnMemphis)
  107. {
  108. HCURSOR hcur = LoadCursor(NULL, IDC_HAND); // from USER, system supplied
  109. if (hcur)
  110. return hcur;
  111. }
  112. return LoadCursor(HINST_THISDLL, MAKEINTRESOURCE(IDC_HAND_INTERNAL));
  113. }
  114. typedef BOOL (*PFNQUEUEUSERWORKITEM)(LPTHREAD_START_ROUTINE Function,
  115. PVOID Context, BOOL PreferIo);
  116. STDAPI_(BOOL) NT5_QueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
  117. PVOID Context, BOOL PreferIo)
  118. {
  119. BOOL bRet = FALSE;
  120. static PFNQUEUEUSERWORKITEM pfn = (PFNQUEUEUSERWORKITEM)-1;
  121. if ((PFNQUEUEUSERWORKITEM)-1 == pfn)
  122. {
  123. HMODULE hmod = GetModuleHandle(TEXT("KERNEL32"));
  124. if (hmod)
  125. pfn = (PFNQUEUEUSERWORKITEM)GetProcAddress(hmod, "QueueUserWorkItem");
  126. else
  127. pfn = NULL;
  128. }
  129. if (pfn)
  130. bRet = pfn( Function, Context, PreferIo);
  131. return bRet;
  132. }
  133. //
  134. // Here's how CAL_ITWODIGITYEARMAX works.
  135. //
  136. // If a two-digit year is input from the user, we put it into the range
  137. // (N-99) ... N. for example, if the maximum value is 2029, then all
  138. // two-digit numbers will be coerced into the range 1930 through 2029.
  139. //
  140. // Win95 and NT4 don't have GetCalendarInfo, but they do have
  141. // EnumCalendarInfo, so you'd think we could avoid the GetProcAddress
  142. // by enumerating the one calendar we care about.
  143. //
  144. // Unfortunately, Win98 has a bug where EnumCalendarInfo can't enumerate
  145. // the maximum two-digit year value! What a lamer!
  146. //
  147. // So we're stuck with GetProcAddress.
  148. //
  149. // But wait, Win98 exports GetCalendarInfoW but doesn't implement it!
  150. // Double lame!
  151. //
  152. // So we have to use the Ansi version exclusively. Fortunately, we
  153. // are only interested in numbers (so far) so there is no loss of amenity.
  154. //
  155. // First, here's the dummy function that emulates GetCalendarInfoA
  156. // on Win95 and NT4.
  157. //
  158. STDAPI_(int)
  159. Emulate_GetCalendarInfoA(LCID lcid, CALID calid, CALTYPE cal,
  160. LPSTR pszBuf, int cchBuf, LPDWORD pdwOut)
  161. {
  162. //
  163. // In the absence of the API, we go straight for the information
  164. // in the registry.
  165. //
  166. BOOL fSuccess = FALSE;
  167. HKEY hkey;
  168. ASSERT(cal == CAL_RETURN_NUMBER + CAL_ITWODIGITYEARMAX);
  169. ASSERT(pszBuf == NULL);
  170. ASSERT(cchBuf == 0);
  171. if (RegOpenKeyExA(HKEY_CURRENT_USER,
  172. "Control Panel\\International\\Calendars\\TwoDigitYearMax",
  173. 0, KEY_READ, &hkey) == ERROR_SUCCESS)
  174. {
  175. char szKey[16];
  176. char szBuf[64];
  177. DWORD dwSize;
  178. if (SUCCEEDED(StringCchPrintfA(szKey, ARRAYSIZE(szKey), "%d", calid)))
  179. {
  180. dwSize = sizeof(szBuf);
  181. if (RegQueryValueExA(hkey, szKey, 0, NULL, (LPBYTE)szBuf, &dwSize) == ERROR_SUCCESS)
  182. {
  183. *pdwOut = StrToIntA(szBuf);
  184. fSuccess = TRUE;
  185. }
  186. }
  187. RegCloseKey(hkey);
  188. }
  189. return fSuccess;
  190. }
  191. typedef int (CALLBACK *GETCALENDARINFOA)(LCID, CALID, CALTYPE, LPSTR, int, LPDWORD);
  192. GETCALENDARINFOA _GetCalendarInfoA;
  193. STDAPI_(int)
  194. NT5_GetCalendarInfoA(LCID lcid, CALID calid, CALTYPE cal,
  195. LPSTR pszBuf, int cchBuf, LPDWORD pdwOut)
  196. {
  197. // This is the only function our emulator supports
  198. ASSERT(cal == CAL_RETURN_NUMBER + CAL_ITWODIGITYEARMAX);
  199. ASSERT(pszBuf == NULL);
  200. ASSERT(cchBuf == 0);
  201. if (_GetCalendarInfoA == NULL)
  202. {
  203. HMODULE hmod = GetModuleHandle(TEXT("KERNEL32"));
  204. //
  205. // Must keep in a local to avoid thread races.
  206. //
  207. GETCALENDARINFOA pfn = NULL;
  208. if (hmod)
  209. pfn = (GETCALENDARINFOA)
  210. GetProcAddress(hmod, "GetCalendarInfoA");
  211. //
  212. // If function is not available, then use our fallback
  213. //
  214. if (pfn == NULL)
  215. pfn = Emulate_GetCalendarInfoA;
  216. ASSERT(pfn != NULL);
  217. _GetCalendarInfoA = pfn;
  218. }
  219. return _GetCalendarInfoA(lcid, calid, cal, pszBuf, cchBuf, pdwOut);
  220. }