|
|
#ifdef UNICODE
#error start menu won't run on win95 if this apithk.c is compiled unicode
#endif
//
// APITHK.C
//
// This file has API thunks that allow shdocvw to load and run on
// multiple versions of NT or Win95. Since this component needs
// to load on the base-level NT 4.0 and Win95, any calls to system
// APIs introduced in later OS versions must be done via GetProcAddress.
//
// Also, any code that may need to access data structures that are
// post-4.0 specific can be added here.
//
// NOTE: this file does *not* use the standard precompiled header,
// so it can set _WIN32_WINNT to a later version.
//
#include "priv.h" // Don't use precompiled header here
#include "uxtheme.h"
HINSTANCE GetComctl32Hinst() { static HINSTANCE s_hinst = NULL; if (!s_hinst) s_hinst = GetModuleHandle(TEXT("comctl32.dll")); return s_hinst; }
STDAPI_(HCURSOR) LoadHandCursor(DWORD dwRes) { if (g_bRunOnNT5 || g_bRunOnMemphis) { HCURSOR hcur = LoadCursor(NULL, IDC_HAND); // from USER, system supplied
if (hcur) return hcur; }
return LoadCursor(GetComctl32Hinst(), IDC_HAND_INTERNAL); }
/*----------------------------------------------------------
Purpose: Use the Microsoft ActiveAccessiblity routines to notify Accessibility programs of events */ typedef void (* PFNNOTIFYWINEVENT)(DWORD event, HWND hwnd, LONG idObject, LONG idChild); #define DONOTHING_WINEVENT (PFNNOTIFYWINEVENT)1
void NT5_NotifyWinEvent( IN DWORD event, IN HWND hwnd, IN LONG idObject, IN LONG idChild) { static PFNNOTIFYWINEVENT pfn = NULL;
if (NULL == pfn) { HMODULE hmod = GetModuleHandle(TEXT("USER32")); if (hmod) pfn = (PFNNOTIFYWINEVENT)GetProcAddress(hmod, "NotifyWinEvent"); if (!pfn) pfn = DONOTHING_WINEVENT; }
if (pfn != DONOTHING_WINEVENT) pfn(event, hwnd, idObject, idChild); }
// Use the Microsoft ActiveAccessiblity routines to return an IAccessible object
typedef LRESULT (* PFNLRESULTFROMOBJECT)(REFIID riid, WPARAM wParam, IUnknown* punk);
LRESULT ACCESSIBLE_LresultFromObject( IN REFIID riid, IN WPARAM wParam, OUT IUnknown* punk) { static PFNLRESULTFROMOBJECT pfn = NULL; static BOOL fLoadAttempted = FALSE; LRESULT lRet = (LRESULT)E_FAIL;
if (NULL == pfn && !fLoadAttempted) { // LoadLibrary here because OLEAcc is not loaded in the process
HMODULE hmod = LoadLibrary(TEXT("OLEACC")); if (hmod) pfn = (PFNLRESULTFROMOBJECT)GetProcAddress(hmod, "LresultFromObject"); else fLoadAttempted = TRUE; }
if (pfn) lRet = pfn(riid, wParam, punk);
return lRet; }
// wrapper for NT5/Millennium AllowSetForegroundWindow
typedef BOOL (* PFNALLOWSFW)(DWORD dwProcessId);
BOOL NT5_AllowSetForegroundWindow(IN DWORD dwProcessId ) { static PFNALLOWSFW pfn = (PFNALLOWSFW)-1; if (((PFNALLOWSFW)-1) == pfn) { HMODULE hmod = GetModuleHandle(TEXT("USER32")); pfn = hmod ? (PFNALLOWSFW)GetProcAddress(hmod, "AllowSetForegroundWindow") : NULL; }
return pfn ? pfn(dwProcessId) : FALSE; }
typedef BOOL (* PFNANIMATEWINDOW)(HWND hwnd, DWORD dwTime, DWORD dwFlags);
// Thunk for NT 5's AnimateWindow.
BOOL NT5_AnimateWindow(IN HWND hwnd, IN DWORD dwTime, IN DWORD dwFlags) { BOOL bRet = FALSE; static PFNANIMATEWINDOW pfn = NULL;
ASSERT(g_bRunOnMemphis || g_bRunOnNT5);
if (NULL == pfn) { HMODULE hmod = GetModuleHandle(TEXT("USER32")); if (hmod) pfn = (PFNANIMATEWINDOW)GetProcAddress(hmod, "AnimateWindow"); }
if (pfn) bRet = pfn(hwnd, dwTime, dwFlags);
return bRet; }
// Position Menubands using NT5's AnimateWindow if available.
void SlideAnimate(HWND hwnd, RECT* prc, UINT uFlags, UINT uSide) { DWORD dwAnimateFlags = AW_CENTER; switch(uSide) { case MENUBAR_LEFT: dwAnimateFlags = AW_HOR_NEGATIVE; break; case MENUBAR_RIGHT: dwAnimateFlags = AW_HOR_POSITIVE; break; case MENUBAR_TOP: dwAnimateFlags = AW_VER_NEGATIVE; break; case MENUBAR_BOTTOM: dwAnimateFlags = AW_VER_POSITIVE; break; } NT5_AnimateWindow(hwnd, 120, dwAnimateFlags | AW_SLIDE); }
void AnimateSetMenuPos(HWND hwnd, RECT* prc, UINT uFlags, UINT uSide, BOOL fNoAnimate) { if ((g_bRunOnMemphis || g_bRunOnNT5) && !fNoAnimate) { BOOL fAnimate = FALSE; SystemParametersInfo(SPI_GETMENUANIMATION, 0, &fAnimate, 0); if (fAnimate) { SetWindowPos(hwnd, HWND_TOPMOST, prc->left, prc->top, RECTWIDTH(*prc), RECTHEIGHT(*prc), uFlags); fAnimate = FALSE; #ifdef WINNT
SystemParametersInfo(SPI_GETMENUFADE, 0, &fAnimate, 0); #endif // WINNT
if (fAnimate) { NT5_AnimateWindow(hwnd, 175, AW_BLEND); } else { SlideAnimate(hwnd, prc, uFlags, uSide); } } else goto UseSetWindowPos; } else { UseSetWindowPos: // Enable the show window so that it gets displayed.
uFlags |= SWP_SHOWWINDOW;
SetWindowPos(hwnd, HWND_TOPMOST, prc->left, prc->top, RECTWIDTH(*prc), RECTHEIGHT(*prc), uFlags); } }
/*----------------------------------------------------------
Purpose: Use the Microsoft ActiveAccessiblity routines to return an IAccessible object */ typedef LRESULT (* PFNCREATESTDACCESSIBLEOBJECT)(HWND hwnd, LONG idObject, REFIID riid, void** ppvObj);
LRESULT ACCESSIBLE_CreateStdAccessibleObject( IN HWND hwnd, IN LONG idObject, IN REFIID riid, OUT void** ppvObj) { static PFNCREATESTDACCESSIBLEOBJECT pfn = NULL; static BOOL fLoadAttempted = FALSE; LRESULT lRet = (LRESULT)E_FAIL;
if (NULL == pfn && !fLoadAttempted) { // LoadLibrary here because OLEAcc is not loaded in the process
HMODULE hmod = LoadLibrary(TEXT("OLEACC")); if (hmod) pfn = (PFNCREATESTDACCESSIBLEOBJECT)GetProcAddress(hmod, "CreateStdAccessibleObject"); else fLoadAttempted = TRUE; }
if (pfn) lRet = pfn(hwnd, idObject, riid, ppvObj);
return lRet; }
typedef BOOL (* PFNLOCKSETFOREGROUNDWINDOW)(UINT);
BOOL MyLockSetForegroundWindow(BOOL fLock) { static PFNLOCKSETFOREGROUNDWINDOW pfn = (PFNLOCKSETFOREGROUNDWINDOW)-1; BOOL fRet = FALSE;
if ((PFNLOCKSETFOREGROUNDWINDOW)-1 == pfn) { HMODULE hmod = GetModuleHandle(TEXT("USER32")); if (hmod) pfn = (PFNLOCKSETFOREGROUNDWINDOW)GetProcAddress(hmod, "LockSetForegroundWindow"); else pfn = NULL; }
if (pfn) fRet = pfn(fLock ? LSFW_LOCK : LSFW_UNLOCK);
return fRet; }
typedef UINT (* PFNSHEXTRACTICONSW)(LPCWSTR wszFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags);
STDAPI_(UINT) MyExtractIconsW(LPCWSTR wszFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags) { UINT uiRet = 0; static PFNSHEXTRACTICONSW pfn = NULL;
if (GetUIVersion() >= 5) { if (NULL == pfn) { HMODULE hmod = GetModuleHandle(TEXT("SHELL32")); if (hmod) pfn = (PFNSHEXTRACTICONSW)GetProcAddress(hmod, "SHExtractIconsW"); }
if (pfn) uiRet = pfn(wszFileName, nIconIndex, cxIcon, cyIcon, phicon, piconid, nIcons, flags); }
return uiRet; }
typedef BOOL (* PFNUPDATELAYEREDWINDOW) (HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
BOOL BlendLayeredWindow(HWND hwnd, HDC hdcDest, POINT* ppt, SIZE* psize, HDC hdc, POINT* pptSrc, BYTE bBlendConst) { BOOL bRet = FALSE; static PFNUPDATELAYEREDWINDOW pfn = NULL;
if (NULL == pfn) { HMODULE hmod = GetModuleHandle(TEXT("USER32")); if (hmod) pfn = (PFNUPDATELAYEREDWINDOW)GetProcAddress(hmod, "UpdateLayeredWindow"); }
if (pfn) { BLENDFUNCTION blend; blend.BlendOp = AC_SRC_OVER; blend.BlendFlags = 0; blend.AlphaFormat = 0; blend.SourceConstantAlpha = bBlendConst;
bRet = pfn(hwnd, hdcDest, ppt, psize, hdc, pptSrc, 0, &blend, ULW_ALPHA); }
return bRet; }
BOOL NT5_SetLayeredWindowAttributes( HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags) { static BOOL (*pfn)(HWND, COLORREF, BYTE, DWORD) = NULL;
if (pfn == NULL) { HMODULE hMod = LoadLibrary(TEXT("user32.dll")); if (hMod) { pfn = (BOOL (*)(HWND, COLORREF, BYTE, DWORD))GetProcAddress(hMod, "SetLayeredWindowAttributes"); } }
if (pfn) return pfn(hwnd, crKey, bAlpha, dwFlags); return 0; }
typedef HRESULT (* PFNSHPATHPREPAREFORWRITE)(HWND hwnd, IUnknown* punkModless, LPCWSTR pwzPath, DWORD dwFlags); STDAPI NT5_SHPathPrepareForWrite(HWND hwnd, IUnknown* punkModless, LPCWSTR pwzPath, DWORD dwFlags) { HRESULT hRet = E_FAIL; static PFNSHPATHPREPAREFORWRITE pfn = NULL;
if (GetUIVersion() >= 5) { if (NULL == pfn) { HMODULE hmod = GetModuleHandle(TEXT("shell32.dll")); if (hmod) { pfn = (PFNSHPATHPREPAREFORWRITE)GetProcAddress(hmod, "SHPathPrepareForWriteW"); } }
if (pfn) { hRet = pfn(hwnd, punkModless, pwzPath, dwFlags); } }
return hRet; }
void Comctl32_SetWindowTheme(HWND hwnd, LPWSTR psz) { SendMessage(hwnd, CCM_SETWINDOWTHEME, 0, (LPARAM)psz); }
void Comctl32_GetBandMargins(HWND hwnd, MARGINS* pmar) { SendMessage(hwnd, RB_GETBANDMARGINS, 0, (LPARAM)pmar); }
void Comctl32_FixAutoBreak(LPNMHDR pnm) { LPNMREBARAUTOBREAK pnmab = (LPNMREBARAUTOBREAK) pnm; pnmab->fAutoBreak = !(pnmab->uMsg == RBAB_AUTOSIZE); }
void Comctl32_SetDPIScale(HWND hwnd) { SendMessage(hwnd, CCM_DPISCALE, TRUE, 0); }
// enable the marquee mode. note, this only works on comctl32 v6
STDAPI_(void) ProgressSetMarqueeMode(HWND hwndPrgress, BOOL bOn) { if (IsOS(OS_WHISTLERORGREATER)) { SendMessage(hwndPrgress, PBM_SETMARQUEE, bOn, 0); SHSetWindowBits(hwndPrgress, GWL_STYLE, PBS_MARQUEE, bOn ? PBS_MARQUEE : 0); } }
// terminal server session notification:
static HMODULE s_hmodWTSApi = NULL;
typedef BOOL (* PFNWTS_REGISTER_SESSION_NOTIFICATION)(HWND hwnd, DWORD dwFlags); static PFNWTS_REGISTER_SESSION_NOTIFICATION s_pfnWTSRegisterSession = NULL;
typedef BOOL (* PFNWTS_UNREGISTER_SESSION_NOTIFICATION)(HWND hwnd); static PFNWTS_UNREGISTER_SESSION_NOTIFICATION s_pfnWTSUnRegisterSession = NULL;
BOOL DL_WTSRegisterSessionNotification(HWND hwnd, DWORD dwFlags) { if (s_pfnWTSRegisterSession == NULL) { if (s_hmodWTSApi == NULL) { s_hmodWTSApi = LoadLibrary(TEXT("wtsapi32")); } if (s_hmodWTSApi) { s_pfnWTSRegisterSession = (PFNWTS_REGISTER_SESSION_NOTIFICATION)GetProcAddress(s_hmodWTSApi, "WTSRegisterSessionNotification"); } }
if (s_pfnWTSRegisterSession != NULL) { return s_pfnWTSRegisterSession(hwnd, dwFlags); } return FALSE; }
BOOL DL_WTSUnRegisterSessionNotification(HWND hwnd) { if (s_pfnWTSUnRegisterSession == NULL) { if (s_hmodWTSApi == NULL) { s_hmodWTSApi = LoadLibrary(TEXT("wtsapi32")); } if (s_hmodWTSApi) { s_pfnWTSUnRegisterSession = (PFNWTS_UNREGISTER_SESSION_NOTIFICATION)GetProcAddress(s_hmodWTSApi, "WTSUnRegisterSessionNotification"); } }
if (s_pfnWTSUnRegisterSession != NULL) { BOOL fRet = s_pfnWTSUnRegisterSession(hwnd); FreeLibrary(s_hmodWTSApi); s_hmodWTSApi = NULL; s_pfnWTSRegisterSession = NULL; s_pfnWTSUnRegisterSession = NULL; return fRet; } return FALSE; }
|