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)