mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-10-11 18:08:08 +00:00
[idd] helper/config: implement window positioning, fonts, and high DPI support
This commit is contained in:
@@ -11,28 +11,65 @@ bool CConfigWindow::registerClass()
|
||||
WNDCLASSEX wx = {};
|
||||
populateWindowClass(wx);
|
||||
wx.hIconSm = wx.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
|
||||
wx.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wx.lpszClassName = L"LookingGlassIddConfig";
|
||||
|
||||
s_atom = RegisterClassEx(&wx);
|
||||
return s_atom;
|
||||
}
|
||||
|
||||
CConfigWindow::CConfigWindow()
|
||||
CConfigWindow::CConfigWindow() : m_scale(1)
|
||||
{
|
||||
if (!CreateWindowEx(0, MAKEINTATOM(s_atom), L"Looking Glass IDD Configuration",
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 500, 400,
|
||||
NULL, NULL, hInstance, this))
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "Failed to create window");
|
||||
}
|
||||
|
||||
m_scale = GetDpiForWindow(m_hwnd) / 96.0;
|
||||
m_version.reset(new CStaticWidget(L"Looking Glass IDD " LG_VERSION_STR, WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE, m_hwnd));
|
||||
updateFont();
|
||||
}
|
||||
|
||||
void CConfigWindow::updateFont()
|
||||
{
|
||||
NONCLIENTMETRICS ncmMetrics = { sizeof(NONCLIENTMETRICS) };
|
||||
UINT dpi = GetDpiForWindow(m_hwnd);
|
||||
if (!SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof ncmMetrics, &ncmMetrics, 0, dpi))
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS)");
|
||||
return;
|
||||
}
|
||||
|
||||
m_font.Attach(CreateFontIndirect(&ncmMetrics.lfMessageFont));
|
||||
if (!m_font.IsValid())
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "CreateFontIndirect(lfMessageFont)");
|
||||
return;
|
||||
}
|
||||
|
||||
for (HWND child : std::initializer_list<HWND>({ *m_version }))
|
||||
SendMessage(child, WM_SETFONT, (WPARAM)m_font.Get(), 1);
|
||||
}
|
||||
|
||||
LRESULT CConfigWindow::handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_SIZE:
|
||||
return onResize(LOWORD(lParam), HIWORD(lParam));
|
||||
case WM_DPICHANGED:
|
||||
{
|
||||
LPRECT lpBox = (LPRECT)lParam;
|
||||
m_scale = LOWORD(wParam) / 96.0;
|
||||
updateFont();
|
||||
SetWindowPos(m_hwnd, NULL, lpBox->left, lpBox->top, lpBox->right - lpBox->left,
|
||||
lpBox->bottom - lpBox->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
onResize(lpBox->right - lpBox->left, lpBox->bottom - lpBox->top);
|
||||
RedrawWindow(m_hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return CWindow::handleMessage(uMsg, wParam, lParam);
|
||||
}
|
||||
@@ -49,3 +86,10 @@ LRESULT CConfigWindow::onFinal()
|
||||
m_onDestroy();
|
||||
return CWindow::onFinal();
|
||||
}
|
||||
|
||||
LRESULT CConfigWindow::onResize(DWORD width, DWORD height)
|
||||
{
|
||||
WidgetPositioner pos(m_scale, width, height);
|
||||
pos.pinTopLeftRight(*m_version, 12, 12, 12, 20);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include "CStaticWidget.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <wrl.h>
|
||||
#include "UIHelpers.h"
|
||||
|
||||
class CConfigWindow : public CWindow
|
||||
{
|
||||
@@ -11,10 +13,15 @@ class CConfigWindow : public CWindow
|
||||
std::unique_ptr<CStaticWidget> m_version;
|
||||
|
||||
std::function<void()> m_onDestroy;
|
||||
double m_scale;
|
||||
Microsoft::WRL::Wrappers::HandleT<FontTraits> m_font;
|
||||
|
||||
void updateFont();
|
||||
|
||||
virtual LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
|
||||
virtual LRESULT onCreate() override;
|
||||
virtual LRESULT onFinal() override;
|
||||
LRESULT onResize(DWORD width, DWORD height);
|
||||
|
||||
public:
|
||||
CConfigWindow();
|
||||
|
@@ -14,5 +14,5 @@ public:
|
||||
void destroy();
|
||||
|
||||
HWND hwnd() { return m_hwnd; }
|
||||
operator HWND() { return m_hwnd; }
|
||||
operator HWND() const { return m_hwnd; }
|
||||
};
|
||||
|
@@ -192,6 +192,7 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
<ClInclude Include="CPipeClient.h" />
|
||||
<ClInclude Include="CStaticWidget.h" />
|
||||
<ClInclude Include="CWidget.h" />
|
||||
<ClInclude Include="UIHelpers.h" />
|
||||
<ClInclude Include="CWindow.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@@ -29,6 +29,16 @@
|
||||
<ClCompile Include="CNotifyWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(SolutionDir)LGCommon\*.cpp" />
|
||||
<ClCompile Include="CConfigWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CStaticWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="$(SolutionDir)LGCommon\*.h" />
|
||||
@@ -43,6 +53,20 @@
|
||||
<ClInclude Include="CNotifyWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<CLInclude Include="$(SolutionDir)LGCommon\*.h" />
|
||||
<CLInclude Include="$(SolutionDir)LGCommon\*.h" />
|
||||
<ClInclude Include="CConfigWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CStaticWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIHelpers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
49
idd/LGIddHelper/UIHelpers.h
Normal file
49
idd/LGIddHelper/UIHelpers.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
struct FontTraits
|
||||
{
|
||||
typedef HFONT Type;
|
||||
inline static bool Close(Type h) { return DeleteObject(h); }
|
||||
inline static Type GetInvalidValue() { return nullptr; }
|
||||
};
|
||||
|
||||
class WidgetPositioner
|
||||
{
|
||||
HDWP hdwp;
|
||||
double m_scale;
|
||||
DWORD width, height;
|
||||
inline int scale(int value) { return (int)round(value * m_scale); }
|
||||
|
||||
public:
|
||||
WidgetPositioner(double scale, DWORD width, DWORD height) :
|
||||
m_scale(scale), width(width), height(height),
|
||||
hdwp(BeginDeferWindowPos(10)) {}
|
||||
|
||||
~WidgetPositioner() { EndDeferWindowPos(hdwp); }
|
||||
|
||||
void move(HWND child, int x, int y, int cx, int cy)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, child, nullptr, x, y, cx, cy, SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
|
||||
void pinTopLeft(HWND child, int x, int y, int cx, int cy)
|
||||
{
|
||||
move(child, scale(x), scale(y), scale(cx), scale(cy));
|
||||
}
|
||||
|
||||
void pinTopRight(HWND child, int x, int y, int cx, int cy)
|
||||
{
|
||||
move(child, scale(x), scale(y), width - scale(cx), scale(cy));
|
||||
}
|
||||
|
||||
void pinTopLeftRight(HWND child, int x, int y, int rx, int cy)
|
||||
{
|
||||
move(child, scale(x), scale(y), width - scale(rx + x), scale(cy));
|
||||
}
|
||||
|
||||
void pinLeftTopBottom(HWND child, int x, int y, int cx, int by)
|
||||
{
|
||||
move(child, scale(x), scale(y), cx, height - scale(y + by));
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user