|
|
#ifndef _INC_MLUISUPP
#define _INC_MLUISUPP
#include <shlwapi.h>
#include <shlwapip.h>
#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
|