mirror of
https://github.com/quantum5/MusicKeyboard.git
synced 2025-04-24 13:11:58 -04:00
Add high DPI support
This commit is contained in:
parent
0a9ecabf8f
commit
c9865a2efc
2
Makefile
2
Makefile
|
@ -63,4 +63,4 @@ $(OUTDIR)\keyboard.res: keyboard.rc
|
||||||
$(CXX) $(CXXFLAGS) /Fo$(OUTDIR)\ /Fd$(OUTDIR)\ $<
|
$(CXX) $(CXXFLAGS) /Fo$(OUTDIR)\ /Fd$(OUTDIR)\ $<
|
||||||
|
|
||||||
$(DISTDIR)\Keyboard.exe: $(FILES)
|
$(DISTDIR)\Keyboard.exe: $(FILES)
|
||||||
$(LD) /out:$@ $(LDFLAGS) $** $(LIBS)
|
$(LD) /out:$@ $(LDFLAGS) $** $(LIBS) /manifest:embed /manifestinput:highdpi.manifest /manifestinput:commctrl6.manifest
|
||||||
|
|
16
highdpi.manifest
Normal file
16
highdpi.manifest
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<asmv3:windowsSettings
|
||||||
|
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||||
|
<dpiAware>True/PM</dpiAware>
|
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
|
||||||
|
</asmv3:windowsSettings>
|
||||||
|
</asmv3:application>
|
||||||
|
</assembly>
|
|
@ -74,6 +74,9 @@ protected:
|
||||||
void UpdateNoteDisplay();
|
void UpdateNoteDisplay();
|
||||||
virtual HICON GetIcon();
|
virtual HICON GetIcon();
|
||||||
|
|
||||||
|
void UpdateScale();
|
||||||
|
int scale(int unscaled) { return static_cast<int>(m_scale * unscaled); }
|
||||||
|
|
||||||
int active[128];
|
int active[128];
|
||||||
bool capsDown;
|
bool capsDown;
|
||||||
bool useBeep;
|
bool useBeep;
|
||||||
|
@ -108,6 +111,7 @@ protected:
|
||||||
MIDI_FILE *m_midifile;
|
MIDI_FILE *m_midifile;
|
||||||
DWORD lastTime;
|
DWORD lastTime;
|
||||||
bool saving;
|
bool saving;
|
||||||
|
double m_scale;
|
||||||
|
|
||||||
LRESULT CALLBACK LowLevelKeyboardHook(HHOOK hHook, int nCode, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK LowLevelKeyboardHook(HHOOK hHook, int nCode, WPARAM wParam, LPARAM lParam);
|
||||||
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include <winnls.h>
|
#include <winnls.h>
|
||||||
|
|
||||||
RID_ICON ICON keyboard.ico
|
RID_ICON ICON keyboard.ico
|
||||||
1 24 commctrl6.manifest
|
|
||||||
|
|
||||||
STRINGTABLE LANGUAGE 0x09, 0x01 // en-US
|
STRINGTABLE LANGUAGE 0x09, 0x01 // en-US
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
#include <ShellScalingAPI.h>
|
||||||
|
|
||||||
#define LEFT(x, y, cx, cy) x, y, cx, cy
|
#define LEFT(x, y, cx, cy) x, y, cx, cy
|
||||||
#define RIGHT(x, y, cx, cy) (x - cx), y, cx, cy
|
#define RIGHT(x, y, cx, cy) (x - cx), y, cx, cy
|
||||||
|
@ -142,13 +143,39 @@ BOOL MainWindow::WinRegisterClass(WNDCLASS *pwc)
|
||||||
return Window::WinRegisterClass(pwc);
|
return Window::WinRegisterClass(pwc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef HRESULT (WINAPI *FN_GETDPIFORMONITOR)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
|
||||||
|
|
||||||
|
void MainWindow::UpdateScale()
|
||||||
|
{
|
||||||
|
HMONITOR hMonitor = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);
|
||||||
|
HMODULE hShCore;
|
||||||
|
|
||||||
|
m_scale = 1;
|
||||||
|
|
||||||
|
hShCore = LoadLibrary(L"ShCore.dll");
|
||||||
|
if (hShCore) {
|
||||||
|
FN_GETDPIFORMONITOR GetDpiForMonitor =
|
||||||
|
(FN_GETDPIFORMONITOR) GetProcAddress(hShCore, "GetDpiForMonitor");
|
||||||
|
if (GetDpiForMonitor) {
|
||||||
|
UINT dpiX, dpiY;
|
||||||
|
GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
|
||||||
|
m_scale = dpiX / 96.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT MainWindow::OnCreate()
|
LRESULT MainWindow::OnCreate()
|
||||||
{
|
{
|
||||||
|
UpdateScale();
|
||||||
|
|
||||||
|
RECT client = {0, 0, scale(622), scale(431)};
|
||||||
|
AdjustWindowRect(&client, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, FALSE);
|
||||||
|
SetWindowPos(m_hwnd, NULL, 0, 0, client.right - client.left,
|
||||||
|
client.bottom - client.top, SWP_NOMOVE | SWP_NOZORDER);
|
||||||
|
|
||||||
NONCLIENTMETRICS ncmMetrics = { sizeof(NONCLIENTMETRICS) };
|
NONCLIENTMETRICS ncmMetrics = { sizeof(NONCLIENTMETRICS) };
|
||||||
RECT client;
|
|
||||||
|
|
||||||
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncmMetrics, 0);
|
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncmMetrics, 0);
|
||||||
GetClientRect(m_hwnd, &client);
|
|
||||||
|
|
||||||
hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont);
|
hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont);
|
||||||
|
|
||||||
|
@ -530,7 +557,8 @@ void MainWindow::PaintContent(PAINTSTRUCT *pps)
|
||||||
SetBkColor(pps->hdc, GetSysColor(COLOR_3DFACE));
|
SetBkColor(pps->hdc, GetSysColor(COLOR_3DFACE));
|
||||||
SetDCPenColor(pps->hdc, GetSysColor(COLOR_3DHILIGHT));
|
SetDCPenColor(pps->hdc, GetSysColor(COLOR_3DHILIGHT));
|
||||||
|
|
||||||
RoundRect(pps->hdc, 12, client.bottom - 52, client.right - 12, client.bottom - 12, 5, 5);
|
RoundRect(pps->hdc, scale(12), client.bottom - scale(52), client.right - scale(12),
|
||||||
|
client.bottom - scale(12), scale(5), scale(5));
|
||||||
|
|
||||||
SelectPen(pps->hdc, hOldPen);
|
SelectPen(pps->hdc, hOldPen);
|
||||||
SelectBrush(pps->hdc, hOldBrush);
|
SelectBrush(pps->hdc, hOldBrush);
|
||||||
|
@ -706,41 +734,52 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_NCDESTROY:
|
case WM_NCDESTROY:
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
|
case WM_DPICHANGED: {
|
||||||
|
LPRECT lpBox = (LPRECT) lParam;
|
||||||
|
m_scale = LOWORD(wParam) / 96.0;
|
||||||
|
SetWindowPos(m_hwnd, NULL, lpBox->left, lpBox->top, lpBox->right - lpBox->left,
|
||||||
|
lpBox->bottom - lpBox->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
RedrawWindow(m_hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WM_SIZE: {
|
case WM_SIZE: {
|
||||||
RECT client;
|
RECT client;
|
||||||
HDWP hdwp;
|
HDWP hdwp;
|
||||||
|
if (!piano) return 0;
|
||||||
GetClientRect(m_hwnd, &client);
|
GetClientRect(m_hwnd, &client);
|
||||||
#define REPOS(hwnd, k) hdwp = DeferWindowPos(hdwp, hwnd, 0, k, SWP_NOACTIVATE|SWP_NOZORDER)
|
#define s(x) scale(x)
|
||||||
hdwp = BeginDeferWindowPos(14);
|
#define REPOS(hwnd, k) hdwp = DeferWindowPos(hdwp, hwnd, 0, k, SWP_NOACTIVATE | SWP_NOZORDER)
|
||||||
REPOS(piano->GetHWND(), LEFT(12, 12, client.right - 24, client.bottom - 262));
|
hdwp = BeginDeferWindowPos(27);
|
||||||
REPOS(m_instruLabel, BOTTOM(12, client.bottom - 217, 70, 25));
|
REPOS(piano->GetHWND(), LEFT(s(12), s(12), client.right - s(24), client.bottom - s(262)));
|
||||||
REPOS(m_instruSelect, BOTTOM(82, client.bottom - 217, client.right - 94, 25));
|
REPOS(m_instruLabel, BOTTOM(s(12), client.bottom - s(217), s(70), s(25)));
|
||||||
REPOS(m_forceLabel, BOTTOM(12, client.bottom - 187, 70, 25));
|
REPOS(m_instruSelect, BOTTOM(s(82), client.bottom - s(217), client.right - s(94), s(25)));
|
||||||
REPOS(m_forceBar, BOTTOM(82, client.bottom - 187, client.right - 94, 25));
|
REPOS(m_forceLabel, BOTTOM(s(12), client.bottom - s(187), s(70), s(25)));
|
||||||
REPOS(m_volumeLabel, BOTTOM(12, client.bottom - 157, 70, 25));
|
REPOS(m_forceBar, BOTTOM(s(82), client.bottom - s(187), client.right - s(94), s(25)));
|
||||||
REPOS(m_volumeBar, BOTTOM(82, client.bottom - 157, client.right - 94, 25));
|
REPOS(m_volumeLabel, BOTTOM(s(12), client.bottom - s(157), s(70), s(25)));
|
||||||
REPOS(m_deviceLabel, BOTTOM(12, client.bottom - 127, 70, 25));
|
REPOS(m_volumeBar, BOTTOM(s(82), client.bottom - s(157), client.right - s(94), s(25)));
|
||||||
REPOS(m_deviceSelect, BOTTOM(82, client.bottom - 127, client.right - 94, 25));
|
REPOS(m_deviceLabel, BOTTOM(s(12), client.bottom - s(127), s(70), s(25)));
|
||||||
REPOS(m_pipeAboveRadio, BOTTOM(12, client.bottom - 97, 150, 25));
|
REPOS(m_deviceSelect, BOTTOM(s(82), client.bottom - s(127), client.right - s(94), s(25)));
|
||||||
REPOS(m_pipeLeftRadio, BOTTOM(162, client.bottom - 97, 150, 25));
|
REPOS(m_pipeAboveRadio, BOTTOM(s(12), client.bottom - s(97), s(150), s(25)));
|
||||||
REPOS(m_adjustLabel, BOTTOM(12, client.bottom - 67, 70, 25));
|
REPOS(m_pipeLeftRadio, BOTTOM(s(162), client.bottom - s(97), s(150), s(25)));
|
||||||
REPOS(m_semitoneSelect, BOTTOM(82, client.bottom - 67, 50, 20));
|
REPOS(m_adjustLabel, BOTTOM(s(12), client.bottom - s(67), s(70), s(25)));
|
||||||
REPOS(m_semitoneUpDown, BOTTOM(132, client.bottom - 67, 18, 20));
|
REPOS(m_semitoneSelect, BOTTOM(s(82), client.bottom - s(67), s(50), s(20)));
|
||||||
REPOS(m_semitoneLabel, BOTTOM(155, client.bottom - 67, 60, 20));
|
REPOS(m_semitoneUpDown, BOTTOM(s(132), client.bottom - s(67), s(18), s(20)));
|
||||||
REPOS(m_octaveSelect, BOTTOM(220, client.bottom - 67, 50, 20));
|
REPOS(m_semitoneLabel, BOTTOM(s(155), client.bottom - s(67), s(60), s(20)));
|
||||||
REPOS(m_octaveUpDown, BOTTOM(270, client.bottom - 67, 18, 20));
|
REPOS(m_octaveSelect, BOTTOM(s(220), client.bottom - s(67), s(50), s(20)));
|
||||||
REPOS(m_octaveLabel, BOTTOM(293, client.bottom - 67, 50, 20));
|
REPOS(m_octaveUpDown, BOTTOM(s(270), client.bottom - s(67), s(18), s(20)));
|
||||||
REPOS(m_keyLabel, BOTTOM(345, client.bottom - 67, 45, 20));
|
REPOS(m_octaveLabel, BOTTOM(s(293), client.bottom - s(67), s(50), s(20)));
|
||||||
REPOS(m_keySelect, BOTTOM(390, client.bottom - 67, 65, 22));
|
REPOS(m_keyLabel, BOTTOM(s(345), client.bottom - s(67), s(45), s(20)));
|
||||||
REPOS(m_saveCheck, BOTTOM(22, client.bottom - 42, 50, 20));
|
REPOS(m_keySelect, BOTTOM(s(390), client.bottom - s(67), s(65), s(22)));
|
||||||
REPOS(m_saveLabel, BOTTOM(27, client.bottom - 19, 30, 20));
|
REPOS(m_saveCheck, BOTTOM(s(22), client.bottom - s(42), s(50), s(20)));
|
||||||
REPOS(m_saveFile, BOTTOM(62, client.bottom - 17, client.right - 334, 25));
|
REPOS(m_saveLabel, BOTTOM(s(27), client.bottom - s(19), s(30), s(20)));
|
||||||
REPOS(m_saveBrowse, BOTTOMRIGHT(client.right - 187, client.bottom - 17, 80, 25));
|
REPOS(m_saveFile, BOTTOM(s(62), client.bottom - s(17), client.right - s(334), s(25)));
|
||||||
REPOS(m_reopen, BOTTOMRIGHT(client.right - 102, client.bottom - 17, 80, 25));
|
REPOS(m_saveBrowse, BOTTOMRIGHT(client.right - s(187), client.bottom - s(17), s(80), s(25)));
|
||||||
REPOS(m_closeFile, BOTTOMRIGHT(client.right - 17, client.bottom - 17, 80, 25));
|
REPOS(m_reopen, BOTTOMRIGHT(client.right - s(102), client.bottom - s(17), s(80), s(25)));
|
||||||
REPOS(m_beepCheck, BOTTOMRIGHT(client.right - 17, client.bottom - 42, 60, 20));
|
REPOS(m_closeFile, BOTTOMRIGHT(client.right - s(17), client.bottom - s(17), s(80), s(25)));
|
||||||
|
REPOS(m_beepCheck, BOTTOMRIGHT(client.right - s(17), client.bottom - s(42), s(60), s(20)));
|
||||||
EndDeferWindowPos(hdwp);
|
EndDeferWindowPos(hdwp);
|
||||||
#undef REPOS
|
#undef REPOS
|
||||||
|
#undef s
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
|
@ -941,13 +980,11 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
MainWindow *MainWindow::Create(LPCTSTR szTitle)
|
MainWindow *MainWindow::Create(LPCTSTR szTitle)
|
||||||
{
|
{
|
||||||
MainWindow *self = new MainWindow();
|
MainWindow *self = new MainWindow();
|
||||||
RECT client = {0, 0, 622, 431};
|
|
||||||
AdjustWindowRect(&client, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, FALSE);
|
|
||||||
if (self &&
|
if (self &&
|
||||||
self->WinCreateWindow(0,
|
self->WinCreateWindow(0,
|
||||||
szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, client.right - client.left,
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
client.bottom - client.top, NULL, NULL)) {
|
NULL, NULL)) {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
delete self;
|
delete self;
|
||||||
|
|
Loading…
Reference in a new issue