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.

461 lines
12 KiB

  1. #ifdef UNICODE
  2. #error start menu won't run on win95 if this apithk.c is compiled unicode
  3. #endif
  4. //
  5. // APITHK.C
  6. //
  7. // This file has API thunks that allow shdocvw to load and run on
  8. // multiple versions of NT or Win95. Since this component needs
  9. // to load on the base-level NT 4.0 and Win95, any calls to system
  10. // APIs introduced in later OS versions must be done via GetProcAddress.
  11. //
  12. // Also, any code that may need to access data structures that are
  13. // post-4.0 specific can be added here.
  14. //
  15. // NOTE: this file does *not* use the standard precompiled header,
  16. // so it can set _WIN32_WINNT to a later version.
  17. //
  18. #include "priv.h" // Don't use precompiled header here
  19. #include "uxtheme.h"
  20. HINSTANCE GetComctl32Hinst()
  21. {
  22. static HINSTANCE s_hinst = NULL;
  23. if (!s_hinst)
  24. s_hinst = GetModuleHandle(TEXT("comctl32.dll"));
  25. return s_hinst;
  26. }
  27. STDAPI_(HCURSOR) LoadHandCursor(DWORD dwRes)
  28. {
  29. if (g_bRunOnNT5 || g_bRunOnMemphis)
  30. {
  31. HCURSOR hcur = LoadCursor(NULL, IDC_HAND); // from USER, system supplied
  32. if (hcur)
  33. return hcur;
  34. }
  35. return LoadCursor(GetComctl32Hinst(), IDC_HAND_INTERNAL);
  36. }
  37. /*----------------------------------------------------------
  38. Purpose: Use the Microsoft ActiveAccessiblity routines to
  39. notify Accessibility programs of events
  40. */
  41. typedef void (* PFNNOTIFYWINEVENT)(DWORD event, HWND hwnd, LONG idObject, LONG idChild);
  42. #define DONOTHING_WINEVENT (PFNNOTIFYWINEVENT)1
  43. void NT5_NotifyWinEvent(
  44. IN DWORD event,
  45. IN HWND hwnd,
  46. IN LONG idObject,
  47. IN LONG idChild)
  48. {
  49. static PFNNOTIFYWINEVENT pfn = NULL;
  50. if (NULL == pfn)
  51. {
  52. HMODULE hmod = GetModuleHandle(TEXT("USER32"));
  53. if (hmod)
  54. pfn = (PFNNOTIFYWINEVENT)GetProcAddress(hmod, "NotifyWinEvent");
  55. if (!pfn)
  56. pfn = DONOTHING_WINEVENT;
  57. }
  58. if (pfn != DONOTHING_WINEVENT)
  59. pfn(event, hwnd, idObject, idChild);
  60. }
  61. // Use the Microsoft ActiveAccessiblity routines to return an IAccessible object
  62. typedef LRESULT (* PFNLRESULTFROMOBJECT)(REFIID riid, WPARAM wParam, IUnknown* punk);
  63. LRESULT ACCESSIBLE_LresultFromObject(
  64. IN REFIID riid,
  65. IN WPARAM wParam,
  66. OUT IUnknown* punk)
  67. {
  68. static PFNLRESULTFROMOBJECT pfn = NULL;
  69. static BOOL fLoadAttempted = FALSE;
  70. LRESULT lRet = (LRESULT)E_FAIL;
  71. if (NULL == pfn && !fLoadAttempted)
  72. {
  73. // LoadLibrary here because OLEAcc is not loaded in the process
  74. HMODULE hmod = LoadLibrary(TEXT("OLEACC"));
  75. if (hmod)
  76. pfn = (PFNLRESULTFROMOBJECT)GetProcAddress(hmod, "LresultFromObject");
  77. else
  78. fLoadAttempted = TRUE;
  79. }
  80. if (pfn)
  81. lRet = pfn(riid, wParam, punk);
  82. return lRet;
  83. }
  84. // wrapper for NT5/Millennium AllowSetForegroundWindow
  85. typedef BOOL (* PFNALLOWSFW)(DWORD dwProcessId);
  86. BOOL NT5_AllowSetForegroundWindow(IN DWORD dwProcessId )
  87. {
  88. static PFNALLOWSFW pfn = (PFNALLOWSFW)-1;
  89. if (((PFNALLOWSFW)-1) == pfn)
  90. {
  91. HMODULE hmod = GetModuleHandle(TEXT("USER32"));
  92. pfn = hmod ? (PFNALLOWSFW)GetProcAddress(hmod, "AllowSetForegroundWindow") : NULL;
  93. }
  94. return pfn ? pfn(dwProcessId) : FALSE;
  95. }
  96. typedef BOOL (* PFNANIMATEWINDOW)(HWND hwnd, DWORD dwTime, DWORD dwFlags);
  97. // Thunk for NT 5's AnimateWindow.
  98. BOOL NT5_AnimateWindow(IN HWND hwnd, IN DWORD dwTime, IN DWORD dwFlags)
  99. {
  100. BOOL bRet = FALSE;
  101. static PFNANIMATEWINDOW pfn = NULL;
  102. ASSERT(g_bRunOnMemphis || g_bRunOnNT5);
  103. if (NULL == pfn)
  104. {
  105. HMODULE hmod = GetModuleHandle(TEXT("USER32"));
  106. if (hmod)
  107. pfn = (PFNANIMATEWINDOW)GetProcAddress(hmod, "AnimateWindow");
  108. }
  109. if (pfn)
  110. bRet = pfn(hwnd, dwTime, dwFlags);
  111. return bRet;
  112. }
  113. // Position Menubands using NT5's AnimateWindow if available.
  114. void SlideAnimate(HWND hwnd, RECT* prc, UINT uFlags, UINT uSide)
  115. {
  116. DWORD dwAnimateFlags = AW_CENTER;
  117. switch(uSide)
  118. {
  119. case MENUBAR_LEFT: dwAnimateFlags = AW_HOR_NEGATIVE;
  120. break;
  121. case MENUBAR_RIGHT: dwAnimateFlags = AW_HOR_POSITIVE;
  122. break;
  123. case MENUBAR_TOP: dwAnimateFlags = AW_VER_NEGATIVE;
  124. break;
  125. case MENUBAR_BOTTOM: dwAnimateFlags = AW_VER_POSITIVE;
  126. break;
  127. }
  128. NT5_AnimateWindow(hwnd, 120, dwAnimateFlags | AW_SLIDE);
  129. }
  130. void AnimateSetMenuPos(HWND hwnd, RECT* prc, UINT uFlags, UINT uSide, BOOL fNoAnimate)
  131. {
  132. if ((g_bRunOnMemphis || g_bRunOnNT5) && !fNoAnimate)
  133. {
  134. BOOL fAnimate = FALSE;
  135. SystemParametersInfo(SPI_GETMENUANIMATION, 0, &fAnimate, 0);
  136. if (fAnimate)
  137. {
  138. SetWindowPos(hwnd, HWND_TOPMOST, prc->left, prc->top,
  139. RECTWIDTH(*prc), RECTHEIGHT(*prc), uFlags);
  140. fAnimate = FALSE;
  141. #ifdef WINNT
  142. SystemParametersInfo(SPI_GETMENUFADE, 0, &fAnimate, 0);
  143. #endif // WINNT
  144. if (fAnimate)
  145. {
  146. NT5_AnimateWindow(hwnd, 175, AW_BLEND);
  147. }
  148. else
  149. {
  150. SlideAnimate(hwnd, prc, uFlags, uSide);
  151. }
  152. }
  153. else
  154. goto UseSetWindowPos;
  155. }
  156. else
  157. {
  158. UseSetWindowPos:
  159. // Enable the show window so that it gets displayed.
  160. uFlags |= SWP_SHOWWINDOW;
  161. SetWindowPos(hwnd, HWND_TOPMOST, prc->left, prc->top, RECTWIDTH(*prc), RECTHEIGHT(*prc),
  162. uFlags);
  163. }
  164. }
  165. /*----------------------------------------------------------
  166. Purpose: Use the Microsoft ActiveAccessiblity routines to
  167. return an IAccessible object
  168. */
  169. typedef LRESULT (* PFNCREATESTDACCESSIBLEOBJECT)(HWND hwnd, LONG idObject, REFIID riid, void** ppvObj);
  170. LRESULT ACCESSIBLE_CreateStdAccessibleObject(
  171. IN HWND hwnd,
  172. IN LONG idObject,
  173. IN REFIID riid,
  174. OUT void** ppvObj)
  175. {
  176. static PFNCREATESTDACCESSIBLEOBJECT pfn = NULL;
  177. static BOOL fLoadAttempted = FALSE;
  178. LRESULT lRet = (LRESULT)E_FAIL;
  179. if (NULL == pfn && !fLoadAttempted)
  180. {
  181. // LoadLibrary here because OLEAcc is not loaded in the process
  182. HMODULE hmod = LoadLibrary(TEXT("OLEACC"));
  183. if (hmod)
  184. pfn = (PFNCREATESTDACCESSIBLEOBJECT)GetProcAddress(hmod, "CreateStdAccessibleObject");
  185. else
  186. fLoadAttempted = TRUE;
  187. }
  188. if (pfn)
  189. lRet = pfn(hwnd, idObject, riid, ppvObj);
  190. return lRet;
  191. }
  192. typedef BOOL (* PFNLOCKSETFOREGROUNDWINDOW)(UINT);
  193. BOOL MyLockSetForegroundWindow(BOOL fLock)
  194. {
  195. static PFNLOCKSETFOREGROUNDWINDOW pfn = (PFNLOCKSETFOREGROUNDWINDOW)-1;
  196. BOOL fRet = FALSE;
  197. if ((PFNLOCKSETFOREGROUNDWINDOW)-1 == pfn)
  198. {
  199. HMODULE hmod = GetModuleHandle(TEXT("USER32"));
  200. if (hmod)
  201. pfn = (PFNLOCKSETFOREGROUNDWINDOW)GetProcAddress(hmod, "LockSetForegroundWindow");
  202. else
  203. pfn = NULL;
  204. }
  205. if (pfn)
  206. fRet = pfn(fLock ? LSFW_LOCK : LSFW_UNLOCK);
  207. return fRet;
  208. }
  209. typedef UINT (* PFNSHEXTRACTICONSW)(LPCWSTR wszFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags);
  210. STDAPI_(UINT) MyExtractIconsW(LPCWSTR wszFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags)
  211. {
  212. UINT uiRet = 0;
  213. static PFNSHEXTRACTICONSW pfn = NULL;
  214. if (GetUIVersion() >= 5)
  215. {
  216. if (NULL == pfn)
  217. {
  218. HMODULE hmod = GetModuleHandle(TEXT("SHELL32"));
  219. if (hmod)
  220. pfn = (PFNSHEXTRACTICONSW)GetProcAddress(hmod, "SHExtractIconsW");
  221. }
  222. if (pfn)
  223. uiRet = pfn(wszFileName, nIconIndex, cxIcon, cyIcon, phicon, piconid, nIcons, flags);
  224. }
  225. return uiRet;
  226. }
  227. typedef BOOL (* PFNUPDATELAYEREDWINDOW)
  228. (HWND hwnd,
  229. HDC hdcDst,
  230. POINT *pptDst,
  231. SIZE *psize,
  232. HDC hdcSrc,
  233. POINT *pptSrc,
  234. COLORREF crKey,
  235. BLENDFUNCTION *pblend,
  236. DWORD dwFlags);
  237. BOOL BlendLayeredWindow(HWND hwnd, HDC hdcDest, POINT* ppt, SIZE* psize, HDC hdc, POINT* pptSrc, BYTE bBlendConst)
  238. {
  239. BOOL bRet = FALSE;
  240. static PFNUPDATELAYEREDWINDOW pfn = NULL;
  241. if (NULL == pfn)
  242. {
  243. HMODULE hmod = GetModuleHandle(TEXT("USER32"));
  244. if (hmod)
  245. pfn = (PFNUPDATELAYEREDWINDOW)GetProcAddress(hmod, "UpdateLayeredWindow");
  246. }
  247. if (pfn)
  248. {
  249. BLENDFUNCTION blend;
  250. blend.BlendOp = AC_SRC_OVER;
  251. blend.BlendFlags = 0;
  252. blend.AlphaFormat = 0;
  253. blend.SourceConstantAlpha = bBlendConst;
  254. bRet = pfn(hwnd, hdcDest, ppt, psize, hdc, pptSrc, 0, &blend, ULW_ALPHA);
  255. }
  256. return bRet;
  257. }
  258. BOOL NT5_SetLayeredWindowAttributes(
  259. HWND hwnd,
  260. COLORREF crKey,
  261. BYTE bAlpha,
  262. DWORD dwFlags)
  263. {
  264. static BOOL (*pfn)(HWND, COLORREF, BYTE, DWORD) = NULL;
  265. if (pfn == NULL)
  266. {
  267. HMODULE hMod = LoadLibrary(TEXT("user32.dll"));
  268. if (hMod)
  269. {
  270. pfn = (BOOL (*)(HWND, COLORREF, BYTE, DWORD))GetProcAddress(hMod, "SetLayeredWindowAttributes");
  271. }
  272. }
  273. if (pfn)
  274. return pfn(hwnd, crKey, bAlpha, dwFlags);
  275. return 0;
  276. }
  277. typedef HRESULT (* PFNSHPATHPREPAREFORWRITE)(HWND hwnd, IUnknown* punkModless, LPCWSTR pwzPath, DWORD dwFlags);
  278. STDAPI NT5_SHPathPrepareForWrite(HWND hwnd, IUnknown* punkModless, LPCWSTR pwzPath, DWORD dwFlags)
  279. {
  280. HRESULT hRet = E_FAIL;
  281. static PFNSHPATHPREPAREFORWRITE pfn = NULL;
  282. if (GetUIVersion() >= 5)
  283. {
  284. if (NULL == pfn)
  285. {
  286. HMODULE hmod = GetModuleHandle(TEXT("shell32.dll"));
  287. if (hmod)
  288. {
  289. pfn = (PFNSHPATHPREPAREFORWRITE)GetProcAddress(hmod, "SHPathPrepareForWriteW");
  290. }
  291. }
  292. if (pfn)
  293. {
  294. hRet = pfn(hwnd, punkModless, pwzPath, dwFlags);
  295. }
  296. }
  297. return hRet;
  298. }
  299. void Comctl32_SetWindowTheme(HWND hwnd, LPWSTR psz)
  300. {
  301. SendMessage(hwnd, CCM_SETWINDOWTHEME, 0, (LPARAM)psz);
  302. }
  303. void Comctl32_GetBandMargins(HWND hwnd, MARGINS* pmar)
  304. {
  305. SendMessage(hwnd, RB_GETBANDMARGINS, 0, (LPARAM)pmar);
  306. }
  307. void Comctl32_FixAutoBreak(LPNMHDR pnm)
  308. {
  309. LPNMREBARAUTOBREAK pnmab = (LPNMREBARAUTOBREAK) pnm;
  310. pnmab->fAutoBreak = !(pnmab->uMsg == RBAB_AUTOSIZE);
  311. }
  312. void Comctl32_SetDPIScale(HWND hwnd)
  313. {
  314. SendMessage(hwnd, CCM_DPISCALE, TRUE, 0);
  315. }
  316. // enable the marquee mode. note, this only works on comctl32 v6
  317. STDAPI_(void) ProgressSetMarqueeMode(HWND hwndPrgress, BOOL bOn)
  318. {
  319. if (IsOS(OS_WHISTLERORGREATER))
  320. {
  321. SendMessage(hwndPrgress, PBM_SETMARQUEE, bOn, 0);
  322. SHSetWindowBits(hwndPrgress, GWL_STYLE, PBS_MARQUEE, bOn ? PBS_MARQUEE : 0);
  323. }
  324. }
  325. // terminal server session notification:
  326. static HMODULE s_hmodWTSApi = NULL;
  327. typedef BOOL (* PFNWTS_REGISTER_SESSION_NOTIFICATION)(HWND hwnd, DWORD dwFlags);
  328. static PFNWTS_REGISTER_SESSION_NOTIFICATION s_pfnWTSRegisterSession = NULL;
  329. typedef BOOL (* PFNWTS_UNREGISTER_SESSION_NOTIFICATION)(HWND hwnd);
  330. static PFNWTS_UNREGISTER_SESSION_NOTIFICATION s_pfnWTSUnRegisterSession = NULL;
  331. BOOL DL_WTSRegisterSessionNotification(HWND hwnd, DWORD dwFlags)
  332. {
  333. if (s_pfnWTSRegisterSession == NULL)
  334. {
  335. if (s_hmodWTSApi == NULL)
  336. {
  337. s_hmodWTSApi = LoadLibrary(TEXT("wtsapi32"));
  338. }
  339. if (s_hmodWTSApi)
  340. {
  341. s_pfnWTSRegisterSession = (PFNWTS_REGISTER_SESSION_NOTIFICATION)GetProcAddress(s_hmodWTSApi, "WTSRegisterSessionNotification");
  342. }
  343. }
  344. if (s_pfnWTSRegisterSession != NULL)
  345. {
  346. return s_pfnWTSRegisterSession(hwnd, dwFlags);
  347. }
  348. return FALSE;
  349. }
  350. BOOL DL_WTSUnRegisterSessionNotification(HWND hwnd)
  351. {
  352. if (s_pfnWTSUnRegisterSession == NULL)
  353. {
  354. if (s_hmodWTSApi == NULL)
  355. {
  356. s_hmodWTSApi = LoadLibrary(TEXT("wtsapi32"));
  357. }
  358. if (s_hmodWTSApi)
  359. {
  360. s_pfnWTSUnRegisterSession = (PFNWTS_UNREGISTER_SESSION_NOTIFICATION)GetProcAddress(s_hmodWTSApi, "WTSUnRegisterSessionNotification");
  361. }
  362. }
  363. if (s_pfnWTSUnRegisterSession != NULL)
  364. {
  365. BOOL fRet = s_pfnWTSUnRegisterSession(hwnd);
  366. FreeLibrary(s_hmodWTSApi);
  367. s_hmodWTSApi = NULL;
  368. s_pfnWTSRegisterSession = NULL;
  369. s_pfnWTSUnRegisterSession = NULL;
  370. return fRet;
  371. }
  372. return FALSE;
  373. }