diff options
author | George Hazan <ghazan@miranda.im> | 2022-06-14 16:56:57 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-06-14 16:56:57 +0300 |
commit | f59d0ddb712b9da16706eaadfb2f0ab5906a560a (patch) | |
tree | 3dc59af0a9691c1ec544d4dff5646f8e02bce963 /src/mir_core | |
parent | 2df0473e77f4153c2ee4579635d1501007aa6f3a (diff) |
experimental hidpi patch for UI
Diffstat (limited to 'src/mir_core')
-rw-r--r-- | src/mir_core/mir_core.vcxproj | 4 | ||||
-rw-r--r-- | src/mir_core/mir_core.vcxproj.filters | 6 | ||||
-rw-r--r-- | src/mir_core/src/Windows/CDlgBase.cpp | 8 | ||||
-rw-r--r-- | src/mir_core/src/Windows/diatheme.cpp | 139 | ||||
-rw-r--r-- | src/mir_core/src/Windows/diatheme.h | 25 |
5 files changed, 180 insertions, 2 deletions
diff --git a/src/mir_core/mir_core.vcxproj b/src/mir_core/mir_core.vcxproj index c748d431ce..feea5de395 100644 --- a/src/mir_core/mir_core.vcxproj +++ b/src/mir_core/mir_core.vcxproj @@ -185,10 +185,14 @@ <ClCompile Include="src\Windows\winver.cpp">
<PrecompiledHeaderFile>../stdafx.h</PrecompiledHeaderFile>
</ClCompile>
+ <ClCompile Include="src\Windows\diatheme.cpp">
+ <PrecompiledHeaderFile>../stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
<ClInclude Include="src\miranda.h" />
<ClInclude Include="src\stdafx.h" />
<ClInclude Include="src\tinyxml2.h" />
<ClInclude Include="src\Windows\miranda.h" />
+ <ClInclude Include="src\Windows\diatheme.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\version.rc" />
diff --git a/src/mir_core/mir_core.vcxproj.filters b/src/mir_core/mir_core.vcxproj.filters index c6fbd4c6a1..958ae40b4e 100644 --- a/src/mir_core/mir_core.vcxproj.filters +++ b/src/mir_core/mir_core.vcxproj.filters @@ -179,6 +179,9 @@ <ClCompile Include="src\Windows\fileutil.cpp">
<Filter>Source Files\Windows</Filter>
</ClCompile>
+ <ClCompile Include="src\Windows\diatheme.cpp">
+ <Filter>Source Files\Windows</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\miranda.h">
@@ -193,6 +196,9 @@ <ClInclude Include="src\Windows\miranda.h">
<Filter>Source Files</Filter>
</ClInclude>
+ <ClInclude Include="src\Windows\diatheme.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\version.rc">
diff --git a/src/mir_core/src/Windows/CDlgBase.cpp b/src/mir_core/src/Windows/CDlgBase.cpp index d6c798eb41..b8b0d5ce11 100644 --- a/src/mir_core/src/Windows/CDlgBase.cpp +++ b/src/mir_core/src/Windows/CDlgBase.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../stdafx.h" +#include "diatheme.h" static mir_cs csDialogs; @@ -101,13 +102,16 @@ void CDlgBase::Close() void CDlgBase::Create() { - CreateDialogParam(GetInst(), MAKEINTRESOURCE(m_idDialog), m_hwndParent, GlobalDlgProc, (LPARAM)this); + mir_ptr<DLGTEMPLATE> pDlgTemplate(LoadThemedDialogTemplate(MAKEINTRESOURCE(m_idDialog), GetInst())); + CreateDialogIndirectParam(GetInst(),pDlgTemplate,m_hwndParent,GlobalDlgProc,(LPARAM)this); } int CDlgBase::DoModal() { m_isModal = true; - return DialogBoxParam(GetInst(), MAKEINTRESOURCE(m_idDialog), m_hwndParent, GlobalDlgProc, (LPARAM)this); + + mir_ptr<DLGTEMPLATE> pDlgTemplate(LoadThemedDialogTemplate(MAKEINTRESOURCE(m_idDialog), GetInst())); + return DialogBoxIndirectParam(GetInst(), pDlgTemplate, m_hwndParent, GlobalDlgProc, (LPARAM)this); } void CDlgBase::EndModal(INT_PTR nResult) diff --git a/src/mir_core/src/Windows/diatheme.cpp b/src/mir_core/src/Windows/diatheme.cpp new file mode 100644 index 0000000000..ca368f2632 --- /dev/null +++ b/src/mir_core/src/Windows/diatheme.cpp @@ -0,0 +1,139 @@ +/* +Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "../stdafx.h" +#include "diatheme.h" + +// The following code was borrowed from Notepad++ sources and adapted for Miranda NG + +BOOL GetThemedDialogFont(LPWSTR lpFaceName, WORD *wSize) +{ + HDC hDC = GetDC(nullptr); + int iLogPixelsY = GetDeviceCaps(hDC, LOGPIXELSY); + ReleaseDC(nullptr, hDC); + + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + 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 == 0) + *wSize = 8; + + wcsncpy_s(lpFaceName, LF_FACESIZE, ncm.lfMessageFont.lfFaceName, _TRUNCATE); + return TRUE; +} + +BOOL DialogTemplate_IsDialogEx(const DLGTEMPLATE *pTemplate) +{ + return ((DLGTEMPLATEEX *)pTemplate)->signature == 0xFFFF; +} + +BOOL DialogTemplate_HasFont(const DLGTEMPLATE *pTemplate) +{ + return (DS_SETFONT & (DialogTemplate_IsDialogEx(pTemplate) ? ((DLGTEMPLATEEX *)pTemplate)->style : pTemplate->style)); +} + +int DialogTemplate_FontAttrSize(BOOL bDialogEx) +{ + return (int)sizeof(WORD) * (bDialogEx ? 3 : 1); +} + +BYTE *DialogTemplate_GetFontSizeField(const DLGTEMPLATE *pTemplate) +{ + BOOL bDialogEx = DialogTemplate_IsDialogEx(pTemplate); + + WORD *pw; + if (bDialogEx) + pw = (WORD *)((DLGTEMPLATEEX *)pTemplate + 1); + else + pw = (WORD *)(pTemplate + 1); + + if (*pw == (WORD)-1) + pw += 2; + else + while (*pw++); + + if (*pw == (WORD)-1) + pw += 2; + else + while (*pw++); + + while (*pw++); + + return (BYTE *)pw; +} + +DLGTEMPLATE* LoadThemedDialogTemplate(LPCTSTR lpDialogTemplateID, HINSTANCE hInstance) +{ + WCHAR wchFaceName[LF_FACESIZE]; + + HRSRC hRsrc = FindResource(hInstance, lpDialogTemplateID, RT_DIALOG); + if (hRsrc == nullptr) + return nullptr; + + HGLOBAL hRsrcMem = LoadResource(hInstance, hRsrc); + if (hRsrcMem == nullptr) + return nullptr; + + DLGTEMPLATE *pRsrcMem = (DLGTEMPLATE *)LockResource(hRsrcMem); + if (pRsrcMem == nullptr) + return nullptr; + + size_t dwTemplateSize = (UINT)SizeofResource(hInstance, hRsrc); + UnlockResource(hRsrcMem); + FreeResource(hRsrcMem); + + if (dwTemplateSize == 0) + return nullptr; + + auto *pTemplate = (DLGTEMPLATE *)mir_alloc(dwTemplateSize + LF_FACESIZE * 2); + memcpy(pTemplate, pRsrcMem, dwTemplateSize); + UnlockResource(hRsrcMem); + FreeResource(hRsrcMem); + + WORD wFontSize; + 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 + ((mir_wstrlen(wchFaceName) + 1) * sizeof(WCHAR)); + BYTE *pbNew = (BYTE *)wchFaceName; + + BYTE *pb = DialogTemplate_GetFontSizeField(pTemplate); + size_t cbOld = (int)(bHasFont ? cbFontAttr + 2 * (mir_wstrlen((WCHAR *)(pb + cbFontAttr)) + 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 ? (WORD)((DLGTEMPLATEEX *)pTemplate)->cDlgItems : (WORD)pTemplate->cdit; + if (cbNew != cbOld && nCtrl > 0) + MoveMemory(pNewControls, pOldControls, dwTemplateSize - (pOldControls - (BYTE *)pTemplate)); + + *(WORD *)pb = wFontSize; + MoveMemory(pb + cbFontAttr, pbNew, cbNew - cbFontAttr); + return pTemplate; +} diff --git a/src/mir_core/src/Windows/diatheme.h b/src/mir_core/src/Windows/diatheme.h new file mode 100644 index 0000000000..69e70a8d6a --- /dev/null +++ b/src/mir_core/src/Windows/diatheme.h @@ -0,0 +1,25 @@ +//==== Themed Dialogs ========================================================= +#ifndef DIALOGTEME_H_ +#define DIALOGTEME_H_ + +#ifndef DLGTEMPLATEEX +#pragma pack(push, 1) +typedef struct { + WORD dlgVer; + WORD signature; + DWORD helpID; + DWORD exStyle; + DWORD style; + WORD cDlgItems; + short x; + short y; + short cx; + short cy; +} DLGTEMPLATEEX; +#pragma pack(pop) +#endif + +BOOL GetThemedDialogFont(LPWSTR,WORD*); +DLGTEMPLATE* LoadThemedDialogTemplate(LPCTSTR lpDialogTemplateID,HINSTANCE hInstance); + +#endif |