Skip to content

Fix PageSetupDialog margin unit conversion mismatch#14494

Open
LeafShi1 wants to merge 1 commit intodotnet:mainfrom
LeafShi1:Fix_14482_PageSetupDialog_Margin_converts
Open

Fix PageSetupDialog margin unit conversion mismatch#14494
LeafShi1 wants to merge 1 commit intodotnet:mainfrom
LeafShi1:Fix_14482_PageSetupDialog_Margin_converts

Conversation

@LeafShi1
Copy link
Copy Markdown
Member

@LeafShi1 LeafShi1 commented Apr 24, 2026

Fixes #14482

Root Cause

PageSetupDialog converts pageSettings.Margins and minMargins into rtMargin and rtMinMargin before calling the native dialog.
Previously:

  1. Unit selection could come from system locale.
  2. Input unit flags were not explicitly set for the native dialog.

This could lead to mismatched interpretation between values written into rtMargin and values read back in UpdateSettings.

Proposed changes

  1. Use user locale for measurement detection when EnableMetric is enabled.
    • Changed GetLocaleInfoEx locale argument to user default locale semantics by passing an empty locale name.
    • This aligns unit selection with the user measurement preference.
  2. Explicitly set the native unit flag before opening Page Setup dialog.
    • If toUnit is HundredthsOfAMillimeter, set PSD_INHUNDREDTHSOFMILLIMETERS.
    • Otherwise, set PSD_INTHOUSANDTHSOFINCHES.
    • This guarantees the same unit system is used for:
      • writing rtMargin and rtMinMargin
      • reading values back in UpdateSettings

Customer Impact

  • EnableMetric false: No behavior change intended.
  • EnableMetric true:
    • Unit choice now tracks user measurement settings.
    • Native dialog interpretation is explicitly aligned with WinForms conversion units.

Regression?

  • No

Risk

  • Minimal

Screenshots

Before

  • In some locale combinations (for example, system locale = US, user locale = Metric), opening Page Setup and clicking OK repeatedly could make margins get smaller each time.
  • Even with EnableMetric = true, the dialog could still show Margins (inches) in those mixed-locale setups.

After

Note: This requires user verification; we have been unable to reproduce this issue.

  • Reopening Page Setup without changing margins no longer shrinks margin values.
  • With EnableMetric = true, the dialog now follows the user’s measurement preference consistently (for Metric users, it shows millimeters).
  • Margin values remain stable and consistent across repeated open/close cycles.

Test methodology

  • Manually

Test environment(s)

  • .net 11.0.0-preview.4.26215.121
Microsoft Reviewers: Open in CodeFlow

@LeafShi1 LeafShi1 requested a review from a team as a code owner April 24, 2026 03:14
@LeafShi1 LeafShi1 requested a review from Copilot April 24, 2026 03:14
@LeafShi1 LeafShi1 added the waiting-review This item is waiting on review by one or more members of team label Apr 24, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a unit mismatch in PageSetupDialog by aligning WinForms margin conversions with the unit system used by the native PageSetupDlg dialog, preventing repeated open/OK cycles from drifting margin values on mixed locale configurations.

Changes:

  • Switch locale measurement detection to user-default semantics when EnableMetric is enabled.
  • Explicitly set the native PAGESETUPDLGW unit flag (PSD_INHUNDREDTHSOFMILLIMETERS vs PSD_INTHOUSANDTHSOFINCHES) to match the conversion unit used for rtMargin/rtMinMargin.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 295 to 299

if (result > 0 && int.Parse(buffer, NumberStyles.Integer, CultureInfo.InvariantCulture) == 0)
{
toUnit = PrinterUnit.HundredthsOfAMillimeter;
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The int.Parse(buffer, ...) is parsing the full 2-char span returned by GetLocaleInfoEx, which includes a trailing NUL terminator when the API writes a string value. This can cause FormatException (e.g., parsing "0\0"). Slice to the returned length minus the terminator (or use TryParse on the trimmed span) before parsing.

Copilot uses AI. Check for mistakes.
Comment on lines +302 to +305
// Explicitly pass the unit flag to the native dialog so it operates in the same unit system
// that WinForms used when converting margins above. This ensures that the values written into
// rtMargin/rtMinMargin and the values read back in UpdateSettings are always in the same unit,
// regardless of how system-level and user-level locale settings may differ.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment says WinForms converted margins "above", but the rtMargin/rtMinMargin conversions happen after this block. Consider rewording to avoid misleading future readers (e.g., reference the conversions below or the chosen toUnit).

Suggested change
// Explicitly pass the unit flag to the native dialog so it operates in the same unit system
// that WinForms used when converting margins above. This ensures that the values written into
// rtMargin/rtMinMargin and the values read back in UpdateSettings are always in the same unit,
// regardless of how system-level and user-level locale settings may differ.
// Explicitly pass the unit flag to the native dialog so it operates in the unit system selected
// by toUnit. This keeps the values written into rtMargin/rtMinMargin below and the values read
// back in UpdateSettings in the same unit, regardless of how system-level and user-level locale
// settings may differ.

Copilot uses AI. Check for mistakes.
Comment on lines +306 to +313
if (toUnit == PrinterUnit.HundredthsOfAMillimeter)
{
dialogSettings.Flags |= PAGESETUPDLG_FLAGS.PSD_INHUNDREDTHSOFMILLIMETERS;
}
else
{
dialogSettings.Flags |= PAGESETUPDLG_FLAGS.PSD_INTHOUSANDTHSOFINCHES;
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description states "EnableMetric false: No behavior change intended", but this change forces PSD_INTHOUSANDTHSOFINCHES whenever toUnit is inches (which is always when EnableMetric is false). That will make the native dialog use inches even on metric user locales (previously it could follow the user measurement system). Either document this behavior change, or gate the explicit unit flag behind EnableMetric if the intent is to preserve the prior UI behavior.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Infrastructure waiting-review This item is waiting on review by one or more members of team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PageSetupDialog incorrectly converts Margin units from pageSetting.Margins to dialogSettings.rtMargin

2 participants