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
);
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