#ifndef _INC_MLUISUPP #define _INC_MLUISUPP #include #include #ifdef __cplusplus extern "C" { #endif //+------------------------------------------------------------------ // Multilang Pluggable UI support // inline functions defs (to centralize code) //+------------------------------------------------------------------ #ifdef UNICODE #define MLLoadString MLLoadStringW #define MLLoadShellLangString MLLoadShellLangStringW #define MLBuildResURLWrap MLBuildResURLWrapW #define MLLoadResources MLLoadResourcesW #define SHHtmlHelpOnDemandWrap SHHtmlHelpOnDemandWrapW #define SHWinHelpOnDemandWrap SHWinHelpOnDemandWrapW #else #define MLLoadString MLLoadStringA #define MLLoadShellLangString MLLoadShellLangStringA #define MLBuildResURLWrap MLBuildResURLWrapA #define MLLoadResources MLLoadResourcesA #define SHHtmlHelpOnDemandWrap SHHtmlHelpOnDemandWrapA #define SHWinHelpOnDemandWrap SHWinHelpOnDemandWrapA #endif void MLFreeResources(HINSTANCE hinstParent); HINSTANCE MLGetHinst(); HINSTANCE MLLoadShellLangResources(); #ifdef MLUI_MESSAGEBOX int MLShellMessageBox(HWND hWnd, LPCTSTR pszMsg, LPCTSTR pszTitle, UINT fuStyle, ...); #endif // // The following should be both A and W suffixed // int MLLoadStringA(UINT id, LPSTR sz, UINT cchMax); int MLLoadStringW(UINT id, LPWSTR sz, UINT cchMax); int MLLoadShellLangStringA(UINT id, LPSTR sz, UINT cchMax); int MLLoadShellLangStringW(UINT id, LPWSTR sz, UINT cchMax); HRESULT MLBuildResURLWrapA(LPSTR pszLibFile, HMODULE hModule, DWORD dwCrossCodePage, LPSTR pszResName, LPSTR pszResURL, int nBufSize, LPSTR pszParentDll); HRESULT MLBuildResURLWrapW(LPWSTR pszLibFile, HMODULE hModule, DWORD dwCrossCodePage, LPWSTR pszResName, LPWSTR pszResURL, int nBufSize, LPWSTR pszParentDll); void MLLoadResourcesA(HINSTANCE hinstParent, LPSTR pszLocResDll); void MLLoadResourcesW(HINSTANCE hinstParent, LPWSTR pszLocResDll); HWND SHHtmlHelpOnDemandWrapA(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData, DWORD dwCrossCodePage); HWND SHHtmlHelpOnDemandWrapW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData, DWORD dwCrossCodePage); BOOL SHWinHelpOnDemandWrapA(HWND hwndCaller, LPCSTR lpszHelp, UINT uCommand, DWORD_PTR dwData); BOOL SHWinHelpOnDemandWrapW(HWND hwndCaller, LPCWSTR lpszHelp, UINT uCommand, DWORD_PTR dwData); // // End of: The following should be both A and W suffixed // #ifdef MLUI_INIT // WARNING: do not attempt to access any of these members directly // these members may not be initialized until appropriate accessors // are called, for example hinstLocRes won't be intialized until // you call MLGetHinst()... so just call the accessor. struct tagMLUI_INFO { HINSTANCE hinstLocRes; HINSTANCE hinstParent; WCHAR szLocResDll[MAX_PATH]; DWORD dwCrossCodePage; } g_mluiInfo; // REARCHITECT: These aren't thread safe... Do they need to be? // void MLLoadResourcesA(HINSTANCE hinstParent, LPSTR pszLocResDll) { #ifdef RIP RIP(hinstParent != NULL); RIP(pszLocResDll != NULL); #endif if (g_mluiInfo.hinstLocRes == NULL) { #ifdef MLUI_SUPPORT // plugUI: resource dll == ? // resource dll must be dynamically determined and loaded. // but we are NOT allowed to LoadLibrary during process attach. // therefore we cache the info we need and load later when // the first resource is requested. SHAnsiToUnicode(pszLocResDll, g_mluiInfo.szLocResDll, sizeof(g_mluiInfo.szLocResDll)/sizeof(g_mluiInfo.szLocResDll[0])); g_mluiInfo.hinstParent = hinstParent; g_mluiInfo.dwCrossCodePage = ML_CROSSCODEPAGE; #else // non-plugUI: resource dll == parent dll g_mluiInfo.hinstLocRes = hinstParent; #endif } } void MLLoadResourcesW(HINSTANCE hinstParent, LPWSTR pszLocResDll) { #ifdef RIP RIP(hinstParent != NULL); RIP(pszLocResDll != NULL); #endif if (g_mluiInfo.hinstLocRes == NULL) { #ifdef MLUI_SUPPORT // plugUI: resource dll == ? // resource dll must be dynamically determined and loaded. // but we are NOT allowed to LoadLibrary during process attach. // therefore we cache the info we need and load later when // the first resource is requested. StrCpyNW(g_mluiInfo.szLocResDll, pszLocResDll, sizeof(g_mluiInfo.szLocResDll)/sizeof(g_mluiInfo.szLocResDll[0])); g_mluiInfo.hinstParent = hinstParent; g_mluiInfo.dwCrossCodePage = ML_CROSSCODEPAGE; #else // non-plugUI: resource dll == parent dll g_mluiInfo.hinstLocRes = hinstParent; #endif } } void MLFreeResources(HINSTANCE hinstParent) { if (g_mluiInfo.hinstLocRes != NULL && g_mluiInfo.hinstLocRes != hinstParent) { MLClearMLHInstance(g_mluiInfo.hinstLocRes); g_mluiInfo.hinstLocRes = NULL; } } // this is a private internal helper. // don't you dare call it from anywhere except at // the beginning of new ML* functions in this file __inline void _MLResAssure() { #ifdef MLUI_SUPPORT if(g_mluiInfo.hinstLocRes == NULL) { g_mluiInfo.hinstLocRes = MLLoadLibraryW(g_mluiInfo.szLocResDll, g_mluiInfo.hinstParent, g_mluiInfo.dwCrossCodePage); // we're guaranteed to at least have resources in the install language ASSERT(g_mluiInfo.hinstLocRes != NULL); } #endif } int MLLoadStringA(UINT id, LPSTR sz, UINT cchMax) { _MLResAssure(); return LoadStringA(g_mluiInfo.hinstLocRes, id, sz, cchMax); } int MLLoadStringW(UINT id, LPWSTR sz, UINT cchMax) { _MLResAssure(); return LoadStringWrapW(g_mluiInfo.hinstLocRes, id, sz, cchMax); } int MLLoadShellLangStringA(UINT id, LPSTR sz, UINT cchMax) { HINSTANCE hinstShellLangRes; int nRet; hinstShellLangRes = MLLoadShellLangResources(); nRet = LoadStringA(hinstShellLangRes, id, sz, cchMax); MLFreeLibrary(hinstShellLangRes); return nRet; } int MLLoadShellLangStringW(UINT id, LPWSTR sz, UINT cchMax) { HINSTANCE hinstShellLangRes; int nRet; hinstShellLangRes = MLLoadShellLangResources(); nRet = LoadStringWrapW(hinstShellLangRes, id, sz, cchMax); MLFreeLibrary(hinstShellLangRes); return nRet; } HINSTANCE MLGetHinst() { _MLResAssure(); return g_mluiInfo.hinstLocRes; } HINSTANCE MLLoadShellLangResources() { HINSTANCE hinst; hinst = MLLoadLibraryW(g_mluiInfo.szLocResDll, g_mluiInfo.hinstParent, ML_SHELL_LANGUAGE); // we're guaranteed to at least have resources in the install language // unless we're 100% toasted return hinst; } #ifdef MLUI_MESSAGEBOX int MLShellMessageBox(HWND hWnd, LPCTSTR pszMsg, LPCTSTR pszTitle, UINT fuStyle, ...) { va_list vaList; int nRet = 0; LPTSTR pszFormattedMsg = NULL; TCHAR szTitleBuf[256]; TCHAR szBuffer[1024]; // // prepare the message // if (IS_INTRESOURCE(pszMsg)) { if (MLLoadShellLangString(LOWORD((DWORD_PTR)pszMsg), szBuffer, ARRAYSIZE(szBuffer))) { pszMsg = szBuffer; } } if (!IS_INTRESOURCE(pszMsg) && // the string load might have failed pszMsg != NULL) { va_start(vaList, fuStyle); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, pszMsg, 0, 0, (LPTSTR)&pszFormattedMsg, 0, &vaList)) { pszMsg = pszFormattedMsg; } va_end(vaList); } // // prepare the title // if (!IS_INTRESOURCE(pszTitle) && pszTitle != NULL) { // do nothing } else if (pszTitle != NULL && MLLoadShellLangString(LOWORD((DWORD_PTR)pszTitle), szTitleBuf, ARRAYSIZE(szTitleBuf))) { pszTitle = szTitleBuf; } else if (hWnd && GetWindowText(hWnd, szTitleBuf, ARRAYSIZE(szTitleBuf))) { pszTitle = szTitleBuf; } else { pszTitle = TEXT(""); } // // launch a MessageBox // #ifdef SHFUSION_H ULONG_PTR uCookie = 0; SHActivateContext(&uCookie); #endif nRet = MessageBox(hWnd, pszFormattedMsg, pszTitle, fuStyle | MB_SETFOREGROUND); #ifdef SHFUSION_H if (uCookie) { SHDeactivateContext(uCookie); } #endif if (pszFormattedMsg != NULL) { LocalFree(pszFormattedMsg); } return nRet; } #endif // MLUI_MESSAGEBOX #include "htmlhelp.h" HWND SHHtmlHelpOnDemandWrapA(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData, DWORD dwCrossCodePage) { BOOL fEnabled; ULONG_PTR uCookie = 0; HWND hwnd = NULL; #ifdef MLUI_SUPPORT fEnabled = TRUE; #else fEnabled = FALSE; #endif #ifdef SHFUSION_H SHActivateContext(&uCookie); #endif hwnd = SHHtmlHelpOnDemandA(hwndCaller, pszFile, uCommand, dwData, dwCrossCodePage, fEnabled); #ifdef SHFUSION_H if (uCookie) { SHDeactivateContext(uCookie); } #endif return hwnd; } HWND SHHtmlHelpOnDemandWrapW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData, DWORD dwCrossCodePage) { BOOL fEnabled; ULONG_PTR uCookie = 0; HWND hwnd = NULL; #ifdef MLUI_SUPPORT fEnabled = TRUE; #else fEnabled = FALSE; #endif #ifdef SHFUSION_H SHActivateContext(&uCookie); #endif hwnd = SHHtmlHelpOnDemandW(hwndCaller, pszFile, uCommand, dwData, dwCrossCodePage, fEnabled); #ifdef SHFUSION_H if (uCookie) { SHDeactivateContext(uCookie); } #endif return hwnd; } HWND MLHtmlHelpWrap(HWND hwndCaller, LPCTSTR pszFile, UINT uCommand, DWORD dwData, DWORD dwCrossCodePage) { HWND hwnd; ULONG_PTR uCookie = 0; #ifdef SHFUSION_H SHActivateContext(&uCookie); #endif #ifdef MLUI_SUPPORT hwnd = MLHtmlHelp(hwndCaller, pszFile, uCommand, dwData, dwCrossCodePage); #else hwnd = HtmlHelp(hwndCaller, pszFile, uCommand, dwData); #endif #ifdef SHFUSION_H if (uCookie) { SHDeactivateContext(uCookie); } #endif return hwnd; } BOOL SHWinHelpOnDemandWrapA(HWND hwndCaller, LPCSTR lpszHelp, UINT uCommand, DWORD_PTR dwData) { BOOL fEnabled; #ifdef MLUI_SUPPORT fEnabled = TRUE; #else fEnabled = FALSE; #endif return SHWinHelpOnDemandA(hwndCaller, lpszHelp, uCommand, dwData, fEnabled); } BOOL SHWinHelpOnDemandWrapW(HWND hwndCaller, LPCWSTR lpszHelp, UINT uCommand, DWORD_PTR dwData) { BOOL fEnabled; #ifdef MLUI_SUPPORT fEnabled = TRUE; #else fEnabled = FALSE; #endif return SHWinHelpOnDemandW(hwndCaller, lpszHelp, uCommand, dwData, fEnabled); } BOOL MLWinHelpWrap(HWND hwndCaller, LPCTSTR lpszHelp, UINT uCommand, DWORD dwData) { BOOL fRet; #ifdef MLUI_SUPPORT fRet = MLWinHelp(hwndCaller, lpszHelp, uCommand, dwData); #else fRet = WinHelp(hwndCaller, lpszHelp, uCommand, dwData); #endif return fRet; } HRESULT MLBuildResURLWrapA(LPSTR pszLibFile, HMODULE hModule, DWORD dwCrossCodePage, LPSTR pszResName, LPSTR pszResURL, int nBufSize, LPSTR pszParentDll) { HRESULT hr; #ifdef MLUI_SUPPORT hr = MLBuildResURLA(pszLibFile, hModule, dwCrossCodePage, pszResName, pszResURL, nBufSize); #else wnsprintfA(pszResURL, nBufSize, "res://%s/%s", pszParentDll, pszResName); hr = S_OK; #endif return hr; } HRESULT MLBuildResURLWrapW(LPWSTR pszLibFile, HMODULE hModule, DWORD dwCrossCodePage, LPWSTR pszResName, LPWSTR pszResURL, int nBufSize, LPWSTR pszParentDll) { HRESULT hr; #ifdef MLUI_SUPPORT hr = MLBuildResURLW(pszLibFile, hModule, dwCrossCodePage, pszResName, pszResURL, nBufSize); #else wnsprintfW(pszResURL, nBufSize, L"res://%s/%s", pszParentDll, pszResName); hr = S_OK; #endif return hr; } #endif // MLUI_INIT #ifdef __cplusplus }; #endif #endif // _INC_MLUISUPP