Created
March 2, 2019 14:26
-
-
Save ysc3839/b818c2d97c8e7cae398474df9bf29eb0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
// DLGTEMPLATEEX structure | |
// https://docs.microsoft.com/en-us/windows/desktop/dlgbox/dlgtemplateex | |
const uint8_t* SkipIDorString(const uint8_t* p) | |
{ | |
if (*reinterpret_cast<const uint16_t*>(p) == 0xFFFF) | |
return p + sizeof(uint16_t) * 2; | |
while (*reinterpret_cast<const uint16_t*>(p)) | |
p += sizeof(uint16_t); | |
return p += sizeof(uint16_t); | |
} | |
const uint8_t* SkipString(const uint8_t* p) | |
{ | |
while (*reinterpret_cast<const uint16_t*>(p)) | |
p += sizeof(uint16_t); | |
return p += sizeof(uint16_t); | |
} | |
WORD MapFontHeightToPointSize(LONG height) | |
{ | |
if (height < 0) | |
{ | |
HDC hdc = GetDC(nullptr); | |
if (hdc) | |
{ | |
auto dpi = GetDeviceCaps(hdc, LOGPIXELSY); | |
ReleaseDC(0, hdc); | |
return MulDiv(-height, 72, dpi); | |
} | |
} | |
return static_cast<WORD>(height); | |
} | |
INT_PTR DialogBoxIndirectParamFixFontWithSize(HINSTANCE hInstance, LPCDLGTEMPLATEW hDialogTemplate, size_t templateSize, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) | |
{ | |
auto dlgVerAndSignature = reinterpret_cast<const WORD*>(hDialogTemplate); | |
// is an extended dialog box and version is 1 | |
if (dlgVerAndSignature[1] == 0xFFFF && *dlgVerAndSignature == 1) | |
{ | |
auto dlgTemplate = reinterpret_cast<const uint8_t*>(hDialogTemplate); | |
dlgTemplate += sizeof(WORD); // dlgVer | |
dlgTemplate += sizeof(WORD); // signature | |
dlgTemplate += sizeof(DWORD); // helpID | |
dlgTemplate += sizeof(DWORD); // exStyle | |
dlgTemplate += sizeof(DWORD); // style | |
dlgTemplate += sizeof(WORD); // cDlgItems | |
dlgTemplate += sizeof(short); // x | |
dlgTemplate += sizeof(short); // y | |
dlgTemplate += sizeof(short); // cx | |
dlgTemplate += sizeof(short); // cy | |
dlgTemplate = SkipIDorString(dlgTemplate); // menu | |
dlgTemplate = SkipIDorString(dlgTemplate); // windowClass | |
dlgTemplate = SkipString(dlgTemplate); // title | |
NONCLIENTMETRICSW ncm = { sizeof(ncm) }; | |
if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)) | |
{ | |
size_t fontSize = (wcslen(ncm.lfMessageFont.lfFaceName) + 1) * sizeof(wchar_t); | |
size_t origTemplateSize = dlgTemplate - reinterpret_cast<const uint8_t*>(hDialogTemplate); | |
size_t newTemplateSize = origTemplateSize; | |
newTemplateSize += sizeof(WORD); // pointsize | |
newTemplateSize += sizeof(WORD); // weight | |
newTemplateSize += sizeof(BYTE); // italic | |
newTemplateSize += sizeof(BYTE); // charset | |
newTemplateSize += fontSize; // typeface | |
dlgTemplate += sizeof(WORD); // pointsize | |
dlgTemplate += sizeof(WORD); // weight | |
dlgTemplate += sizeof(BYTE); // italic | |
dlgTemplate += sizeof(BYTE); // charset | |
dlgTemplate = SkipString(dlgTemplate); // typeface | |
size_t remainSize = templateSize - (dlgTemplate - reinterpret_cast<const uint8_t*>(hDialogTemplate)); | |
newTemplateSize += remainSize; | |
auto newTemplate = new uint8_t[newTemplateSize]; | |
memcpy(newTemplate, hDialogTemplate, origTemplateSize); | |
auto newTemplateFont = newTemplate + origTemplateSize; | |
*reinterpret_cast<WORD*>(newTemplateFont) = static_cast<WORD>(MapFontHeightToPointSize(ncm.lfMessageFont.lfHeight)); // pointsize | |
newTemplateFont += sizeof(WORD); | |
*reinterpret_cast<WORD*>(newTemplateFont) = static_cast<WORD>(ncm.lfMessageFont.lfWeight); // weight | |
newTemplateFont += sizeof(WORD); | |
*reinterpret_cast<BYTE*>(newTemplateFont) = ncm.lfMessageFont.lfItalic; // italic | |
newTemplateFont += sizeof(BYTE); | |
*reinterpret_cast<BYTE*>(newTemplateFont) = ncm.lfMessageFont.lfCharSet; // charset | |
newTemplateFont += sizeof(BYTE); | |
memcpy(newTemplateFont, ncm.lfMessageFont.lfFaceName, fontSize); | |
newTemplateFont += fontSize; | |
memcpy(newTemplateFont, dlgTemplate, remainSize); | |
auto ret = DialogBoxIndirectParamW(hInstance, reinterpret_cast<LPCDLGTEMPLATEW>(newTemplate), hWndParent, lpDialogFunc, dwInitParam); | |
delete[] newTemplate; | |
return ret; | |
} | |
} | |
return DialogBoxIndirectParamW(hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam); | |
} | |
INT_PTR DialogBoxParamFixFont(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) | |
{ | |
auto hResInfo = FindResourceW(hInstance, lpTemplateName, RT_DIALOG); | |
if (hResInfo) | |
{ | |
auto hDialogTemplate = reinterpret_cast<LPCDLGTEMPLATEW>(LoadResource(hInstance, hResInfo)); | |
if (hDialogTemplate) | |
{ | |
auto size = SizeofResource(hInstance, hResInfo); | |
return DialogBoxIndirectParamFixFontWithSize(hInstance, hDialogTemplate, size, hWndParent, lpDialogFunc, dwInitParam); | |
} | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment