DPI awareness — Per-Monitor V2 manifest + hardcoded pixel audit
Workflow status is tracked in GitHub: https://github.com/emulebb/emulebb/issues/11. This local document is retained as an engineering spec/evidence record.
Summary¶
The project explicitly sets <EnableDpiAwareness>false</EnableDpiAwareness> in
the .vcxproj, making eMule DPI-unaware on Windows 10+. On high-DPI monitors
(125%–200% scaling) Windows bitmap-stretches the window, producing a blurry,
low-resolution UI. This is a P0 modernization item — it directly degrades
the user experience on any modern laptop or 4K display.
Current State¶
emule.vcxproj:<EnableDpiAwareness>false</EnableDpiAwareness>- No DPI-aware manifest entry
- Multiple hardcoded pixel values in dialog templates and code
- No
GetDpiForWindow()orGetSystemMetricsForDpi()calls
Fix¶
Step 1 — Manifest change¶
Add PerMonitorV2 DPI awareness to the application manifest
(srchybrid/emule.manifest or equivalent):
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
PerMonitorV2
</dpiAwareness>
<!-- Fallback for pre-1703 Windows (not required for Win10 1703+ target): -->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
True/PM
</dpiAware>
</windowsSettings>
</application>
Remove <EnableDpiAwareness>false</EnableDpiAwareness> from .vcxproj (the
manifest takes precedence, but the explicit false is misleading).
Step 2 — Audit hardcoded pixel values¶
After enabling DPI awareness, items sized in physical pixels will scale incorrectly on non-100% displays. Audit and fix:
| Category | API to use |
|---|---|
| System metrics (icon size, scrollbar width) | GetSystemMetricsForDpi(metric, dpi) |
| Font sizes | CreateFontIndirect with logical units (already DPI-scaled) |
| Toolbar/icon bitmaps | Load from image list at appropriate size via LoadImage with LR_DEFAULTSIZE |
| Dialog template pixel values | Use dialog units (DLUs) — these are already DPI-independent |
| Custom-painted pixel offsets | MulDiv(value, GetDpiForWindow(hwnd), 96) |
Primary audit targets:
- srchybrid/ToolbarWnd.cpp — toolbar bitmap pixel sizes
- srchybrid/TransferDlg.cpp — splitter pixel positions
- srchybrid/StatisticsDlg.cpp — graph pixel calculations
- srchybrid/SearchResultsWnd.cpp — column width defaults
- Any Create(... cx, cy ...) with hardcoded pixel dimensions
Step 3 — Test on non-100% DPI¶
Verify on 125% and 150% scaling that: - All dialogs are legible and not blurry - Toolbar icons are the correct size - Splitters and resize handles work correctly - Column widths in list controls are proportionate
Files to Modify¶
| File | Change |
|---|---|
srchybrid/emule.manifest |
Add PerMonitorV2 dpiAwareness entry |
emule.vcxproj |
Remove <EnableDpiAwareness>false</EnableDpiAwareness> |
srchybrid/ToolbarWnd.cpp |
Use DPI-aware image list sizing |
srchybrid/TransferDlg.cpp |
Replace hardcoded splitter pixels |
| Other files surfaced by DPI audit | Replace physical pixel constants |
Acceptance Criteria¶
- [ ] Application manifest declares
PerMonitorV2DPI awareness - [ ]
<EnableDpiAwareness>false</EnableDpiAwareness>removed from.vcxproj - [ ] At 100% DPI: UI identical to current
- [ ] At 125% DPI: UI elements are crisp (not bitmap-stretched blurry)
- [ ] At 150% DPI: dialogs, toolbars, and list controls are correctly scaled
- [ ] No hardcoded physical pixel values in the audit targets listed above
- [ ]
GetDpiForWindow()/GetSystemMetricsForDpi()used where system metrics are queried programmatically
Note¶
This is the highest-severity WWMOD item (P0). It affects every user on a laptop or monitor above 96 DPI (the current mainstream). DPI-awareness should be enabled before any other WWMOD UI items so that subsequent UI changes are developed against the correct rendering model.