C# application on Japanese Windows OS - Present Latin as Full-Width characters

好久不见. 提交于 2020-02-01 07:20:08

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!