Fix PageSetupDialog margin unit conversion mismatch#14494
Fix PageSetupDialog margin unit conversion mismatch#14494LeafShi1 wants to merge 1 commit intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
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
EnableMetricis enabled. - Explicitly set the native
PAGESETUPDLGWunit flag (PSD_INHUNDREDTHSOFMILLIMETERSvsPSD_INTHOUSANDTHSOFINCHES) to match the conversion unit used forrtMargin/rtMinMargin.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| if (result > 0 && int.Parse(buffer, NumberStyles.Integer, CultureInfo.InvariantCulture) == 0) | ||
| { | ||
| toUnit = PrinterUnit.HundredthsOfAMillimeter; | ||
| } |
There was a problem hiding this comment.
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.
| // 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. |
There was a problem hiding this comment.
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).
| // 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. |
| if (toUnit == PrinterUnit.HundredthsOfAMillimeter) | ||
| { | ||
| dialogSettings.Flags |= PAGESETUPDLG_FLAGS.PSD_INHUNDREDTHSOFMILLIMETERS; | ||
| } | ||
| else | ||
| { | ||
| dialogSettings.Flags |= PAGESETUPDLG_FLAGS.PSD_INTHOUSANDTHSOFINCHES; | ||
| } |
There was a problem hiding this comment.
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.
Fixes #14482
Root Cause
PageSetupDialog converts pageSettings.Margins and minMargins into rtMargin and rtMinMargin before calling the native dialog.
Previously:
This could lead to mismatched interpretation between values written into rtMargin and values read back in UpdateSettings.
Proposed changes
Customer Impact
Regression?
Risk
Screenshots
Before
After
Note: This requires user verification; we have been unable to reproduce this issue.
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow