Skip to content

RFE: Adjusting Plugins to be High DPI Display Responsive (in Windows) #942

Open

Description

@rgleason

These are examples of code used to get Dashboard to be DPI Responsive

DB: Preferences. Scale instr.list and +- icons #2983 6a356104a63

DB: Dialog "Add Instrument". Increase size to half Canvas hight #2983 7fd1b159543

DB: Preferences. Scale instr.list and +- icons OpenCPN/OpenCPN#2983 43a64cad1b3

DB: Win Scaled fonts and sizing eb3b73acce2

OtCurrent font fixes by bdbcat
#982

Activity

  1. changed the title [-]Adjusting Plugins to be High DPI Display Responsive (Windows)[/-] [+]RFE: Adjusting Plugins to be High DPI Display Responsive (in Windows)[/+] on Aug 3, 2023
  2. Rasbats commented on Aug 3, 2023

    @Rasbats
    Contributor

    Has this been used in any standalone plugin? i.e. Not Dashboard, WMM, Grib_pi.

  3. rgleason commented on Aug 3, 2023

    @rgleason
    ContributorAuthor

    Ocpn-draw I believe for text.

  4. rgleason commented on Feb 27, 2025

    @rgleason
    ContributorAuthor
  5. rgleason commented on May 31, 2026

    @rgleason
    ContributorAuthor

    How do Microsoft Visual Styles and wxWidgets manifest resources wx/msw/wx.rc work with regard to DPI awareness? high_dpi_platform_msw "MSW Platform-Specific Build Issues" the High DPI guide

    https://github.com/zeodotdev/wzWidget/blob/kicad/macos-wx-3.2/docs/msw/winxp.md

    AI Produced

    Short answer:
    On Windows, Visual Styles (via manifest activation) and wxWidgets’ wx.rc resources are orthogonal to DPI awareness. Visual Styles only affect theming (UxTheme‑based rendering), while DPI awareness is controlled by application manifest entries and wxWidgets’ DPI‑aware build options. However, they interact in subtle ways: Windows will not scale themed controls correctly unless the process declares the correct DPI awareness level, and wxWidgets’ wx.rc embeds the manifest that determines this behavior.

    Below is the complete, structured explanation, grounded in the High DPI documentation and the MSW platform notes.


    🎯 Core takeaway

    DPI awareness is determined by the application manifest, not by Visual Styles.
    wx/msw/wx.rc embeds the manifest that wxWidgets uses to declare DPI awareness (depending on wxUSE_DPI_AWARE_MANIFEST). Visual Styles only affect the appearance of common controls; they do not make an app DPI‑aware.


    🧩 How Visual Styles work (Windows side)

    Visual Styles are enabled by embedding:

    <dependency>
      <dependentAssembly>
        <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"/>
      </dependentAssembly>
    </dependency>
    

    This activates ComCtl32 v6, which gives themed controls (rounded buttons, modern checkboxes, etc.).

    Important:
    Visual Styles do not declare DPI awareness. They only change how controls are drawn.


    🧩 How DPI awareness works (Windows side)

    Windows uses the application manifest to determine DPI behavior:

    • DPI unaware → Windows bitmap‑scales the entire app (blurry)
    • System DPI aware → scaled once at startup
    • Per‑monitor DPI aware → rescaled when moved between monitors
    • Per‑monitor v2 → best, modern behavior

    These are declared via:

    <dpiAware>true</dpiAware>
    <dpiAwareness>PerMonitorV2</dpiAwareness>
    

    🧩 How wxWidgets handles this (wx.rc and build options)

    wxWidgets’ MSW port includes wx/msw/wx.rc, which embeds:

    • The Visual Styles activation (ComCtl32 v6)
    • The DPI awareness manifest (depending on build options)

    The key build option is:

    wxUSE_DPI_AWARE_MANIFEST

    • 0 → No DPI manifest included
    • 1 → Include System DPI aware manifest
    • 2 → Include Per‑monitor v2 manifest (Windows 10+)

    This is documented in the High DPI guide and MSW platform notes.
    wxWidgets Online Manuals


    🧩 How they interact

    1. Visual Styles + DPI unaware

    Windows will bitmap‑scale the entire UI.
    Controls look themed but blurry.

    2. Visual Styles + System DPI aware

    Controls are themed and sized correctly at startup, but moving the window to a different DPI monitor will not rescale.

    3. Visual Styles + Per‑monitor v2 (best)

    Controls are themed and Windows sends WM_DPICHANGED to allow wxWidgets to rescale layouts.
    This is the mode wxWidgets recommends for modern MSW builds.


    🧩 wxWidgets High DPI behavior (MSW specifics)

    From the High DPI documentation:

    • MSW does not automatically scale logical pixels.
    • wxWidgets uses logical pixels and provides FromDIP() / ToDIP() to convert.
    • Controls sized with hardcoded pixel values will break under DPI scaling.
      wxWidgets Online Manuals

    This is why the wxWidgets maintainers repeatedly warn against hardcoded pixel sizes (as seen in the GitHub issue).
    Github


    🧩 What wx/msw/wx.rc actually contributes

    wx.rc embeds:

    • The Visual Styles activation
    • The DPI awareness manifest (if enabled)
    • Version info and icons

    Thus, your DPI behavior is determined by how wxWidgets was built, not by your own plugin or application code—unless you override the manifest.


    🧩 Practical implications for your MSVC + wxWidgets + OpenCPN workflow

    Given your environment (MSVC, Win32, wxWidgets 3.2.x):

    1. If you build wxWidgets with wxUSE_DPI_AWARE_MANIFEST=2
      Your plugin/app becomes Per‑monitor v2 DPI aware automatically.

    2. If you override the manifest in your own .rc file
      You may accidentally disable DPI awareness or Visual Styles.

    3. If you hardcode pixel sizes
      Controls will misalign at 125–300% DPI unless you use FromDIP().

    4. OpenCPN plugins inherit the DPI behavior of the host
      If OpenCPN is built without DPI awareness, your plugin cannot fix it.


    🧩 Summary table

    Component Controls Theming DPI Scaling Source
    Visual Styles (ComCtl32 v6) ✔️ Yes ❌ No Windows
    Manifest ❌ No ✔️ Yes Windows
    wx/msw/wx.rc ✔️ Yes (Visual Styles) ✔️ Yes (if enabled) wxWidgets
    wxUSE_DPI_AWARE_MANIFEST ❌ No ✔️ Yes wxWidgets build system
    FromDIP() / ToDIP() ❌ No ✔️ Control sizing wxWidgets API

    If you want, I can also produce:

    • A minimal MSVC project showing correct DPI‑aware manifest embedding
    • A diff showing how to override wxWidgets’ manifest safely
    • A diagnostic checklist for OpenCPN plugin DPI issues
    • A step‑by‑step guide for building wxWidgets 3.2.x with Per‑monitor v2 DPI awareness

    Would you like one of those?

    **Short answer:** On Windows, **Visual Styles** (via `manifest` activation) and **wxWidgets’ `wx.rc` resources** are *orthogonal* to **DPI awareness**. Visual Styles only affect **theming** (UxTheme‑based rendering), while DPI awareness is controlled by **application manifest entries** and **wxWidgets’ DPI‑aware build options**. However, they *interact* in subtle ways: Windows will not scale themed controls correctly unless the process declares the correct DPI awareness level, and wxWidgets’ `wx.rc` embeds the manifest that determines this behavior.

    Below is the complete, structured explanation, grounded in the High DPI documentation and the MSW platform notes.


    🎯 Core takeaway

    DPI awareness is determined by the application manifest, not by Visual Styles.
    wx/msw/wx.rc embeds the manifest that wxWidgets uses to declare DPI awareness (depending on wxUSE_DPI_AWARE_MANIFEST). Visual Styles only affect the appearance of common controls; they do not make an app DPI‑aware.


    🧩 How Visual Styles work (Windows side)

    Visual Styles are enabled by embedding:

    <dependency>
      <dependentAssembly>
        <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"/>
      </dependentAssembly>
    </dependency>

    This activates ComCtl32 v6, which gives themed controls (rounded buttons, modern checkboxes, etc.).

    Important:
    Visual Styles do not declare DPI awareness. They only change how controls are drawn.


    🧩 How DPI awareness works (Windows side)

    Windows uses the application manifest to determine DPI behavior:

    • DPI unaware → Windows bitmap‑scales the entire app (blurry)
    • System DPI aware → scaled once at startup
    • Per‑monitor DPI aware → rescaled when moved between monitors
    • Per‑monitor v2 → best, modern behavior

    These are declared via:

    <dpiAware>true</dpiAware>
    <dpiAwareness>PerMonitorV2</dpiAwareness>

    🧩 How wxWidgets handles this (wx.rc and build options)

    wxWidgets’ MSW port includes wx/msw/wx.rc, which embeds:

    • The Visual Styles activation (ComCtl32 v6)
    • The DPI awareness manifest (depending on build options)

    The key build option is:

    wxUSE_DPI_AWARE_MANIFEST

    • 0 → No DPI manifest included
    • 1 → Include System DPI aware manifest
    • 2 → Include Per‑monitor v2 manifest (Windows 10+)

    This is documented in the High DPI guide and MSW platform notes.
    [wxWidgets Online Manuals](https://docs.wxwidgets.org/latest/overview_high_dpi.html)


    🧩 How they interact

    1. Visual Styles + DPI unaware

    Windows will bitmap‑scale the entire UI.
    Controls look themed but blurry.

    2. Visual Styles + System DPI aware

    Controls are themed and sized correctly at startup, but moving the window to a different DPI monitor will not rescale.

    3. Visual Styles + Per‑monitor v2 (best)

    Controls are themed and Windows sends WM_DPICHANGED to allow wxWidgets to rescale layouts.
    This is the mode wxWidgets recommends for modern MSW builds.


    🧩 wxWidgets High DPI behavior (MSW specifics)

    From the High DPI documentation:

    This is why the wxWidgets maintainers repeatedly warn against hardcoded pixel sizes (as seen in the GitHub issue).
    [Github](wxWidgets/wxWidgets#24459)


    🧩 What wx/msw/wx.rc actually contributes

    wx.rc embeds:

    • The Visual Styles activation
    • The DPI awareness manifest (if enabled)
    • Version info and icons

    Thus, your DPI behavior is determined by how wxWidgets was built, not by your own plugin or application code—unless you override the manifest.


    🧩 Practical implications for your MSVC + wxWidgets + OpenCPN workflow

    Given your environment (MSVC, Win32, wxWidgets 3.2.x):

    1. If you build wxWidgets with wxUSE_DPI_AWARE_MANIFEST=2
      Your plugin/app becomes Per‑monitor v2 DPI aware automatically.

    2. If you override the manifest in your own .rc file
      You may accidentally disable DPI awareness or Visual Styles.

    3. If you hardcode pixel sizes
      Controls will misalign at 125–300% DPI unless you use FromDIP().

    4. OpenCPN plugins inherit the DPI behavior of the host
      If OpenCPN is built without DPI awareness, your plugin cannot fix it.


    🧩 Summary table

    Component Controls Theming DPI Scaling Source
    Visual Styles (ComCtl32 v6) ✔️ Yes ❌ No Windows
    Manifest <dpiAware> ❌ No ✔️ Yes Windows
    wx/msw/wx.rc ✔️ Yes (Visual Styles) ✔️ Yes (if enabled) wxWidgets
    wxUSE_DPI_AWARE_MANIFEST ❌ No ✔️ Yes wxWidgets build system
    FromDIP() / ToDIP() ❌ No ✔️ Control sizing wxWidgets API

    If you want, I can also produce:

    • A minimal MSVC project showing correct DPI‑aware manifest embedding
    • A diff showing how to override wxWidgets’ manifest safely
    • A diagnostic checklist for OpenCPN plugin DPI issues
    • A step‑by‑step guide for building wxWidgets 3.2.x with Per‑monitor v2 DPI awareness

    Would you like one of those?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions