+ chg: use special asian UI fonts for dialog boxes

This commit is contained in:
Rainer Kottenhoff 2020-08-16 11:19:02 +02:00
parent 48257c1d08
commit f84fbac21a
2 changed files with 140 additions and 68 deletions

View File

@ -4646,44 +4646,111 @@ Modify dialog templates to use current theme font
Based on code of MFC helper class CDialogTemplate
*/
static inline bool IsChineseTraditionalSubLang(LANGID subLang)
{
return subLang == SUBLANG_CHINESE_TRADITIONAL || subLang == SUBLANG_CHINESE_HONGKONG || subLang == SUBLANG_CHINESE_MACAU;
}
bool GetLocaleDefaultUIFont(LANGID lang, LPWSTR lpFaceName, WORD* wSize)
{
LPCWSTR font;
LANGID const subLang = SUBLANGID(lang);
switch (PRIMARYLANGID(lang)) {
default:
case LANG_ENGLISH:
font = L"Segoe UI";
*wSize = 9;
break;
case LANG_CHINESE:
font = IsChineseTraditionalSubLang(subLang) ? L"Microsoft JhengHei UI" : L"Microsoft YaHei UI";
*wSize = 9;
break;
case LANG_JAPANESE:
font = L"Meiryo UI";
*wSize = 9;
break;
case LANG_KOREAN:
font = L"Malgun Gothic";
*wSize = 9;
break;
}
bool const isAvail = IsFontAvailable(font);
if (isAvail) {
StringCchCopy(lpFaceName, LF_FACESIZE, font);
}
return isAvail;
}
bool GetThemedDialogFont(LPWSTR lpFaceName, WORD* wSize)
{
bool bSucceed = false;
int const iLogPixelsY = GetCurrentPPI(NULL).y - DIALOG_FONT_SIZE_INCR;
HTHEME hTheme = OpenThemeData(NULL, L"WINDOWSTYLE;WINDOW");
if (hTheme) {
LOGFONT lf;
if (S_OK == GetThemeSysFont(hTheme, TMT_MSGBOXFONT, &lf)) {
if (lf.lfHeight < 0) {
lf.lfHeight = -lf.lfHeight;
bool bSucceed = GetLocaleDefaultUIFont(Globals.iPrefLANGID, lpFaceName, wSize);
if (!bSucceed)
{
if (IsAppThemed()) {
unsigned const iLogPixelsY = GetCurrentPPI(NULL).y - DIALOG_FONT_SIZE_INCR;
HTHEME hTheme = OpenThemeData(NULL, L"WINDOWSTYLE;WINDOW");
if (hTheme) {
LOGFONT lf;
if (S_OK == GetThemeSysFont(hTheme, TMT_MSGBOXFONT, &lf)) {
if (lf.lfHeight < 0) {
lf.lfHeight = -lf.lfHeight;
}
*wSize = (WORD)MulDiv(lf.lfHeight, 72, iLogPixelsY);
if (*wSize < 9) {
*wSize = 9;
}
StringCchCopy(lpFaceName, LF_FACESIZE, lf.lfFaceName);
bSucceed = true;
}
CloseThemeData(hTheme);
}
}
if (!bSucceed) {
unsigned const iLogPixelsY = GetCurrentPPI(NULL).y - DIALOG_FONT_SIZE_INCR;
NONCLIENTMETRICS ncm;
ZeroMemory(&ncm, sizeof(ncm));
ncm.cbSize = sizeof(NONCLIENTMETRICS) - sizeof(ncm.iPaddedBorderWidth);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)) {
if (ncm.lfMessageFont.lfHeight < 0) {
ncm.lfMessageFont.lfHeight = -ncm.lfMessageFont.lfHeight;
}
*wSize = (WORD)MulDiv(ncm.lfMessageFont.lfHeight, 72, iLogPixelsY);
if (*wSize < 9) {
*wSize = 9;
}
StringCchCopy(lpFaceName, LF_FACESIZE, ncm.lfMessageFont.lfFaceName);
bSucceed = true;
}
*wSize = (WORD)MulDiv(lf.lfHeight, 72, iLogPixelsY);
if (*wSize == 0) { *wSize = 10; }
StringCchCopyN(lpFaceName, LF_FACESIZE, lf.lfFaceName, LF_FACESIZE);
bSucceed = true;
}
CloseThemeData(hTheme);
}
return bSucceed;
}
inline bool DialogTemplate_IsDialogEx(const DLGTEMPLATE* pTemplate) {
static inline bool DialogTemplate_IsDialogEx(const DLGTEMPLATE* pTemplate) {
return ((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
}
inline bool DialogTemplate_HasFont(const DLGTEMPLATE* pTemplate) {
static inline bool DialogTemplate_HasFont(const DLGTEMPLATE* pTemplate)
{
return (DS_SETFONT &
(DialogTemplate_IsDialogEx(pTemplate) ? ((DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style));
}
inline size_t DialogTemplate_FontAttrSize(bool bDialogEx) {
static inline size_t DialogTemplate_FontAttrSize(bool bDialogEx)
{
return (sizeof(WORD) * (bDialogEx ? 3 : 1));
}
inline BYTE* DialogTemplate_GetFontSizeField(const DLGTEMPLATE* pTemplate) {
static inline BYTE* DialogTemplate_GetFontSizeField(const DLGTEMPLATE* pTemplate)
{
bool bDialogEx = DialogTemplate_IsDialogEx(pTemplate);
WORD* pw;
@ -4711,78 +4778,82 @@ inline BYTE* DialogTemplate_GetFontSizeField(const DLGTEMPLATE* pTemplate) {
DLGTEMPLATE* LoadThemedDialogTemplate(LPCTSTR lpDialogTemplateID, HINSTANCE hInstance)
{
DLGTEMPLATE* pTemplate = NULL;
HRSRC hRsrc = FindResource(hInstance, lpDialogTemplateID, RT_DIALOG);
if (hRsrc == NULL) { return NULL; }
if (!hRsrc) { return NULL; }
HGLOBAL hRsrcMem = LoadResource(hInstance, hRsrc);
if (hRsrcMem) {
DLGTEMPLATE* pRsrcMem = (DLGTEMPLATE*)LockResource(hRsrcMem);
size_t dwTemplateSize = (size_t)SizeofResource(hInstance, hRsrc);
if ((dwTemplateSize == 0) || (pTemplate = AllocMem(dwTemplateSize + LF_FACESIZE * 2, HEAP_ZERO_MEMORY)) == NULL) {
UnlockResource(hRsrcMem);
FreeResource(hRsrcMem);
return NULL;
}
CopyMemory((BYTE*)pTemplate, pRsrcMem, dwTemplateSize);
HGLOBAL const hRsrcMem = LoadResource(hInstance, hRsrc);
DLGTEMPLATE* const pRsrcMem = (DLGTEMPLATE*)LockResource(hRsrcMem);
size_t const dwTemplateSize = (size_t)SizeofResource(hInstance, hRsrc);
DLGTEMPLATE* const pTemplate = dwTemplateSize ? (DLGTEMPLATE*)AllocMem(dwTemplateSize + LF_FACESIZE * 2, HEAP_ZERO_MEMORY) : NULL;
if (!pTemplate) {
UnlockResource(hRsrcMem);
FreeResource(hRsrcMem);
WCHAR wchFaceName[LF_FACESIZE] = { L'\0' };
WORD wFontSize = 0;
if (!GetThemedDialogFont(wchFaceName, &wFontSize)) {
return(pTemplate);
}
bool bDialogEx = DialogTemplate_IsDialogEx(pTemplate);
bool bHasFont = DialogTemplate_HasFont(pTemplate);
size_t cbFontAttr = DialogTemplate_FontAttrSize(bDialogEx);
if (bDialogEx)
((DLGTEMPLATEEX*)pTemplate)->style |= DS_SHELLFONT;
else
pTemplate->style |= DS_SHELLFONT;
size_t cbNew = cbFontAttr + ((StringCchLenW(wchFaceName, COUNTOF(wchFaceName)) + 1) * sizeof(WCHAR));
BYTE* pbNew = (BYTE*)wchFaceName;
BYTE* pb = DialogTemplate_GetFontSizeField(pTemplate);
size_t cbOld = (bHasFont ? cbFontAttr + 2 * (StringCchLen((WCHAR*)(pb + cbFontAttr), 0) + 1) : 0);
BYTE* pOldControls = (BYTE*)(((DWORD_PTR)pb + cbOld + 3) & ~(DWORD_PTR)3);
BYTE* pNewControls = (BYTE*)(((DWORD_PTR)pb + cbNew + 3) & ~(DWORD_PTR)3);
WORD nCtrl = (bDialogEx ? ((DLGTEMPLATEEX*)pTemplate)->cDlgItems : pTemplate->cdit);
if (cbNew != cbOld && nCtrl > 0) {
MoveMemory(pNewControls, pOldControls, (size_t)(dwTemplateSize - (pOldControls - (BYTE*)pTemplate)));
}
*(WORD*)pb = wFontSize;
MoveMemory(pb + cbFontAttr, pbNew, (size_t)(cbNew - cbFontAttr));
return NULL;
}
CopyMemory((BYTE*)pTemplate, pRsrcMem, dwTemplateSize);
UnlockResource(hRsrcMem);
FreeResource(hRsrcMem);
WCHAR wchFaceName[LF_FACESIZE] = {L'\0'};
WORD wFontSize = 0;
if (!GetThemedDialogFont(wchFaceName, &wFontSize)) {
return (pTemplate);
}
bool const bDialogEx = DialogTemplate_IsDialogEx(pTemplate);
bool const bHasFont = DialogTemplate_HasFont(pTemplate);
size_t const cbFontAttr = DialogTemplate_FontAttrSize(bDialogEx);
if (bDialogEx) {
((DLGTEMPLATEEX*)pTemplate)->style |= DS_SHELLFONT;
}
else {
pTemplate->style |= DS_SHELLFONT;
}
size_t const cbNew = cbFontAttr + ((StringCchLenW(wchFaceName, COUNTOF(wchFaceName)) + 1) * sizeof(WCHAR));
BYTE* const pbNew = (BYTE*)wchFaceName;
BYTE* pb = DialogTemplate_GetFontSizeField(pTemplate);
size_t const cbOld = (bHasFont ? cbFontAttr + 2 * (StringCchLen((WCHAR*)(pb + cbFontAttr), 0) + 1) : 0);
BYTE* const pOldControls = (BYTE*)(((DWORD_PTR)pb + cbOld + 3) & ~(DWORD_PTR)3);
BYTE* const pNewControls = (BYTE*)(((DWORD_PTR)pb + cbNew + 3) & ~(DWORD_PTR)3);
WORD const nCtrl = (bDialogEx ? ((DLGTEMPLATEEX*)pTemplate)->cDlgItems : pTemplate->cdit);
if (cbNew != cbOld && nCtrl > 0) {
MoveMemory(pNewControls, pOldControls, (dwTemplateSize - (pOldControls - (BYTE*)pTemplate)));
}
*(WORD*)pb = wFontSize;
MoveMemory(pb + cbFontAttr, pbNew, (size_t)(cbNew - cbFontAttr));
return(pTemplate);
}
INT_PTR ThemedDialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent,
DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
INT_PTR ret = (INT_PTR)NULL;
DLGTEMPLATE* pDlgTemplate = LoadThemedDialogTemplate(lpTemplate, hInstance);
DLGTEMPLATE* const pDlgTemplate = LoadThemedDialogTemplate(lpTemplate, hInstance);
INT_PTR const ret = DialogBoxIndirectParam(hInstance, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
if (pDlgTemplate) {
ret = DialogBoxIndirectParam(hInstance, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
FreeMem(pDlgTemplate);
}
return ret;
}
HWND CreateThemedDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent,
DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
HWND hwnd = INVALID_HANDLE_VALUE;
DLGTEMPLATE* pDlgTemplate = LoadThemedDialogTemplate(lpTemplate, hInstance);
DLGTEMPLATE* const pDlgTemplate = LoadThemedDialogTemplate(lpTemplate, hInstance);
HWND const hwnd = CreateDialogIndirectParam(hInstance, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
if (pDlgTemplate) {
hwnd = CreateDialogIndirectParam(hInstance, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
FreeMem(pDlgTemplate);
}
return hwnd;

View File

@ -216,6 +216,7 @@ typedef struct {
#pragma pack(pop)
#endif
bool GetLocaleDefaultUIFont(LANGID lang, LPWSTR lpFaceName, WORD* wSize);
bool GetThemedDialogFont(LPWSTR lpFaceName, WORD* wSize);
DLGTEMPLATE* LoadThemedDialogTemplate(LPCTSTR lpDialogTemplateID, HINSTANCE hInstance);
#define ThemedDialogBox(hInstance,lpTemplate,hWndParent,lpDialogFunc) ThemedDialogBoxParam(hInstance,lpTemplate,hWndParent,lpDialogFunc,0)