|
|
//
// delay.cpp
//
// Delay load imported functions for perf.
//
#include "private.h"
#include "ciccs.h"
#include "cuitheme.h"
//////////////////////////////////////////////////////////////////////////////
//
// Manifest Support
//
//////////////////////////////////////////////////////////////////////////////
extern HINSTANCE g_hInst; extern CCicCriticalSectionStatic g_cs; #ifdef DEBUG
extern DWORD g_dwThreadDllMain; #endif
typedef HANDLE (WINAPI *PFNCREATEACTCTXA)(PCACTCTXA pActCtx); typedef VOID (WINAPI *PFNRELEASEACTCTX)( HANDLE hActCtx ); typedef BOOL (WINAPI *PFNACTIVATEACTCTX)( HANDLE hActCtx, ULONG_PTR *lpCookie ); typedef BOOL (WINAPI *PFNDEACTIVATEACTCTX)( DWORD dwFlags, ULONG_PTR ulCookie );
static PFNCREATEACTCTXA s_pfnCreateActCtxA = NULL; static PFNRELEASEACTCTX s_pfnReleaseActCtx = NULL; static PFNACTIVATEACTCTX s_pfnActivateActCtx = NULL; static PFNDEACTIVATEACTCTX s_pfnDeactivateActCtx = NULL; static BOOL s_InitActAPI = FALSE;
//+---------------------------------------------------------------------------
//
// InitActAPI
//
//+---------------------------------------------------------------------------
void InitActAPI() { if (s_InitActAPI) return;
HMODULE hModKernel32 = CUIGetSystemModuleHandle("kernel32.dll");
if (!hModKernel32) return;
s_pfnCreateActCtxA = (PFNCREATEACTCTXA)GetProcAddress(hModKernel32, "CreateActCtxA"); s_pfnReleaseActCtx = (PFNRELEASEACTCTX)GetProcAddress(hModKernel32, "ReleaseActCtx"); s_pfnActivateActCtx = (PFNACTIVATEACTCTX)GetProcAddress(hModKernel32, "ActivateActCtx"); s_pfnDeactivateActCtx = (PFNDEACTIVATEACTCTX)GetProcAddress(hModKernel32, "DeactivateActCtx"); s_InitActAPI = TRUE; }
//+---------------------------------------------------------------------------
//
// CUICreateActCtx
//
//+---------------------------------------------------------------------------
HANDLE CUICreateActCtx(PCACTCTXA pActCtx) { InitActAPI(); if (!s_pfnCreateActCtxA) return NULL;
return s_pfnCreateActCtxA(pActCtx); }
//+---------------------------------------------------------------------------
//
// CUIReleaseActCtx
//
//+---------------------------------------------------------------------------
VOID CUIReleaseActCtx( HANDLE hActCtx ) { InitActAPI(); if (!s_pfnReleaseActCtx) return;
s_pfnReleaseActCtx(hActCtx); }
//+---------------------------------------------------------------------------
//
// CUIActivateActCtx
//
//+---------------------------------------------------------------------------
BOOL CUIActivateActCtx( HANDLE hActCtx, ULONG_PTR *lpCookie ) { InitActAPI(); if (!s_pfnActivateActCtx) return FALSE;
return s_pfnActivateActCtx(hActCtx, lpCookie); }
//+---------------------------------------------------------------------------
//
// CUIDeactivateActCtx
//
//+---------------------------------------------------------------------------
BOOL CUIDeactivateActCtx( DWORD dwFlags, ULONG_PTR ulCookie ) { InitActAPI(); if (!s_pfnDeactivateActCtx) return FALSE;
return s_pfnDeactivateActCtx(dwFlags, ulCookie); }
//////////////////////////////////////////////////////////////////////////////
//
// DelayLoad
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// CUIGetFn
//
//+---------------------------------------------------------------------------
FARPROC CUIGetFn(HINSTANCE *phInst, TCHAR *pchLib, TCHAR *pchFunc, int nManifestResource) { Assert(g_dwThreadDllMain != GetCurrentThreadId());
if (*phInst == 0) { TCHAR szPath[MAX_PATH]; HANDLE hActCtx = INVALID_HANDLE_VALUE; ULONG_PTR ulCookie = 0;
EnterCriticalSection(g_cs);
_try { _try { if (nManifestResource > 0) { GetModuleFileName(g_hInst, szPath, sizeof(szPath)); ACTCTX act = {0}; act.cbSize = sizeof(act); act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; act.lpResourceName = MAKEINTRESOURCE(nManifestResource); act.lpSource = szPath; hActCtx = CUICreateActCtx(&act); if (hActCtx != INVALID_HANDLE_VALUE) CUIActivateActCtx(hActCtx, &ulCookie); } *phInst = LoadLibrary(pchLib); } _except(1) { Assert(0); }
if (ulCookie) CUIDeactivateActCtx(0, ulCookie);
if (hActCtx != INVALID_HANDLE_VALUE) CUIReleaseActCtx(hActCtx); } _except(1) { Assert(0); }
LeaveCriticalSection(g_cs); }
if (*phInst == 0) { //
// new dlls in whistler are not in downlevels.
//
// Assert(0);
return NULL; }
return GetProcAddress(*phInst, pchFunc); }
#define DELAYLOAD(_hInst, _DllName, _ManifestResource, _CallConv, _FuncName, _Args1, _Args2, _RetType, _ErrVal) \
_RetType _CallConv CUI ## _FuncName ## _Args1 \ { \ static FARPROC pfn = NULL; \ \ if (pfn == NULL || _hInst == NULL) \ { \ pfn = CUIGetFn(&_hInst, #_DllName, #_FuncName, _ManifestResource); \ \ if (pfn == NULL) \ { \ return (_RetType) _ErrVal; \ } \ } \ \ return ((_RetType (_CallConv *)_Args1) (pfn)) _Args2; \ }
//
// comctl32.dll
//
HINSTANCE g_hComctl32 = 0; #define DELAYLOADCOMCTL32(_FuncName, _Args1, _Args2, _RetType, _ErrVal) \
DELAYLOAD(g_hComctl32, comctl32.dll, 1, WINAPI, _FuncName, _Args1, _Args2, _RetType, _ErrVal)
DELAYLOADCOMCTL32(ImageList_Create, (int cx, int cy, UINT flags, int cInitial, int cGrow), (cx, cy, flags, cInitial, cGrow), HIMAGELIST, NULL) DELAYLOADCOMCTL32(ImageList_Destroy, (HIMAGELIST himl), (himl), BOOL, FALSE) DELAYLOADCOMCTL32(ImageList_ReplaceIcon, (HIMAGELIST himl, int i, HICON hIcon), (himl, i, hIcon), BOOL, FALSE)
//
// uxtheme.dll
//
HINSTANCE g_hUsTheme = 0; #define DELAYLOADUSTHEME(_FuncName, _Args1, _Args2, _RetType, _ErrVal) \
DELAYLOAD(g_hUsTheme, uxtheme.dll, -1, WINAPI, _FuncName, _Args1, _Args2, _RetType, _ErrVal)
DELAYLOADUSTHEME(IsThemeActive, (void), (), BOOL, FALSE)
DELAYLOADUSTHEME(OpenThemeData, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList), HTHEME, NULL)
DELAYLOADUSTHEME(CloseThemeData, (HTHEME hTheme), (hTheme), HRESULT, E_FAIL)
DELAYLOADUSTHEME(SetWindowTheme, (HWND hwnd, LPCWSTR pszSubAppname, LPCWSTR pszSubIdList), (hwnd, pszSubAppname, pszSubIdList), HRESULT, E_FAIL)
DELAYLOADUSTHEME(DrawThemeBackground, ( HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pRect, DWORD dwBgFlags ), ( hTheme, hDC, iPartId, iStateId, pRect, dwBgFlags ), HRESULT, E_FAIL) DELAYLOADUSTHEME(DrawThemeParentBackground, ( HWND hwnd, HDC hDC, const RECT *pRect ), ( hwnd, hDC, pRect), HRESULT, E_FAIL)
DELAYLOADUSTHEME(DrawThemeText, ( HTHEME hTheme, HDC hDC, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect ), ( hTheme, hDC, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect ), HRESULT, E_FAIL)
DELAYLOADUSTHEME(DrawThemeIcon, ( HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pRect, HIMAGELIST himl, int iImageIndex ), ( hTheme, hDC, iPartId, iStateId, pRect, himl, iImageIndex ), HRESULT, E_FAIL)
DELAYLOADUSTHEME(GetThemeBackgroundExtent, ( HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pContentRect, RECT *pExtentRect ), ( hTheme, hDC, iPartId, iStateId, pContentRect, pExtentRect ), HRESULT, E_FAIL)
DELAYLOADUSTHEME(GetThemeBackgroundContentRect, ( HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect ), ( hTheme, hDC, iPartId, iStateId, pBoundingRect, pContentRect ), HRESULT, E_FAIL)
DELAYLOADUSTHEME(GetThemeTextExtent, ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, const RECT *pBoundingRect, RECT *pExtentRect ), ( hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, pBoundingRect, pExtentRect ), HRESULT, E_FAIL)
DELAYLOADUSTHEME(GetThemePartSize, ( HTHEME hTheme, HDC hDC, int iPartId, int iStateId, RECT *prc, enum THEMESIZE eSize, SIZE *pSize ), ( hTheme, hDC, iPartId, iStateId, prc, eSize, pSize ), HRESULT, E_FAIL)
DELAYLOADUSTHEME(DrawThemeEdge, (HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pDestRect, UINT uEdge, UINT uFlags, RECT *pContentRect), (hTheme, hdc, iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect), HRESULT , E_FAIL);
DELAYLOADUSTHEME(GetThemeColor, (HTHEME hTheme, int iPartId, int iStateId, int iPropId, COLORREF *pColor), (hTheme, iPartId, iStateId, iPropId, pColor), HRESULT , E_FAIL);
DELAYLOADUSTHEME(GetThemeMargins, (HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, RECT *prc, MARGINS *pMargins), (hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins), HRESULT , E_FAIL);
DELAYLOADUSTHEME(GetThemeFont, (HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LOGFONTW *plf), (hTheme, hdc, iPartId, iStateId, iPropId, plf), HRESULT , E_FAIL);
DELAYLOADUSTHEME(GetThemeSysColor, (HTHEME hTheme, int iColorId), (hTheme, iColorId), COLORREF , 0); DELAYLOADUSTHEME(GetThemeSysSize, (HTHEME hTheme, int iSizeId), (hTheme, iSizeId), int , 0);
|