问题
I have a C# winform application, that is installed on a Japanese windows 7. Some of the labels are presented with a very wide fonts, causing them to not mach the size of the from.
After some research I was told it might be a half/full width issue. Has it any way to force all strings to be presented as Half width?
For example, this part is not shown correctly:
modelSizeLabel.Text = String.Format("X:{0:0.0},Y:{1:0.0},Z:{2:0.0} [{3}]",
(Model.BBox.dx),
(Model.BBox.dy),
(Model.BBox.dz - Model.Sink),
uc.To.ToString() //units enum
);
回答1:
Basically there are 2 approaches I know to deal with full-width letters:
1. Using String.Normalize() method
This approach uses standard Unicode normalization forms when converting full-width (zenkaku) to half-width (hankaku):
public static string ToHalfWidth(string fullWidth)
{
return fullWidth.Normalize(System.Text.NormalizationForm.FormKC);
}
NB: This is considered simplest approach to convert letters, numbers and punctuations covered by ANSI encoding written in Japanese IME, but I still don't know how it impact any kana/kanji letters.
2. Using P/Invoke to call LCMapString
method in kernel32.dll
This approach requires calling external DLL resource kernel32.dll
with API method LCMapString, with flag defined in LCMapStringEx function (note that some flags are mutually exclusive, implementation credit to rshepp/John Estropia):
// edited from /a/40836235
private const uint LOCALE_SYSTEM_DEFAULT = 0x0800;
private const uint LCMAP_HALFWIDTH = 0x00400000;
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern int LCMapString(uint Locale, uint dwMapFlags, string lpSrcStr, int cchSrc, StringBuilder lpDestStr, int cchDest);
public static string ToHalfWidth(string fullWidth, int size)
{
StringBuilder sb = new StringBuilder(size);
LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_HALFWIDTH, fullWidth, -1, sb, sb.Capacity);
return sb.ToString();
}
Usage example:
// by default Japanese IME automatically convert all vocal letters to respective kana letters,
// so I used consonants except "n"
Label1.Text = ToHalfWidth("0123456789bcdfghjklmpqrstvwxyz");
Label2.Text = ToHalfWidth("0123456789bcdfghjklmpqrstvwxyz", 256);
PS: You can wrap both methods above in a helper/service class for usage across the same namespace.
Related issues:
Converting zenkaku characters to hankaku and vice-versa in C#
Convert single byte character string (half width) to double byte (full width)
来源:https://stackoverflow.com/questions/43753954/c-sharp-application-on-japanese-windows-os-present-latin-as-full-width-charact