summaryrefslogtreecommitdiff
path: root/src/mir_core
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-06-14 16:56:57 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-06-14 16:56:57 +0300
commitf59d0ddb712b9da16706eaadfb2f0ab5906a560a (patch)
tree3dc59af0a9691c1ec544d4dff5646f8e02bce963 /src/mir_core
parent2df0473e77f4153c2ee4579635d1501007aa6f3a (diff)
experimental hidpi patch for UI
Diffstat (limited to 'src/mir_core')
-rw-r--r--src/mir_core/mir_core.vcxproj4
-rw-r--r--src/mir_core/mir_core.vcxproj.filters6
-rw-r--r--src/mir_core/src/Windows/CDlgBase.cpp8
-rw-r--r--src/mir_core/src/Windows/diatheme.cpp139
-rw-r--r--src/mir_core/src/Windows/diatheme.h25
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