C# helpProvider SetHelpString 不支持unicode
C# helpProvider SetHelpString does not support unicode
我正在使用 HelpProvider 显示对我的控件的帮助。
我输入了 HelpProvider 控件的帮助字符串。但这并不能正确显示字符串。
P/S:
我的语言是越南语,是 unicode 字体。
这是我编程时的文字:“Chúc mừng năm mới”
显示时的文字如下:
这是一个老错误,它是由两个问题造成的:
- HelpProvider 底层 API 使用的默认字体不支持 unicode 字符
- HelpProvider 的底层 API 不支持 Unicode。
解决这两个问题后,就可以正确显示Unicode字符了:
HelpExtensions.ShowPopup2(button1, "متن آزمایشی", Control.MousePosition);
第一个问题在Help
class(.NET 4.X, .NET 5) which has created the HH_POPUP
但是没有指定任何字体。因此不支持Unicode字符的默认字体将被使用。
- 可能的解决方法是使用支持 Unicode 字符的默认字体,例如
SystemFonts.CaptionFont
。
对于第二个问题,您需要更改 Windows 中的设置:
转到“控制面板”→“区域”→“管理”选项卡,然后在“非 Unicode 程序的语言”部分中,单击“更改系统区域设置...”按钮,然后在下一个对话框中, 选择您喜欢的语言,例如波斯语。
或者要同时支持其他语言,您可以选择:“Beta:使用 Unicode UTF-8 以获得全球语言支持”,即 Beta。
这里是 HelpExtensions
class:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public static class HelpExtensions
{
public static void ShowPopup2(Control parent, string caption, Point location, Font font = null, Color? backColor = null, Color? foreColor = null)
{
font = font ?? SystemFonts.CaptionFont;
backColor = backColor ?? Color.FromKnownColor(KnownColor.Window);
foreColor = foreColor ?? Color.FromKnownColor(KnownColor.WindowText);
var popup = new HH_POPUP();
popup.clrBackground = new COLORREF(backColor.Value);
popup.clrForeground = new COLORREF(foreColor.Value);
popup.pt = new POINT(location);
var pszText = Marshal.StringToCoTaskMemAuto(caption);
popup.pszText = pszText;
var pszFont = Marshal.StringToCoTaskMemAuto(
$"{font.Name}, {font.Size}, , " +
$"{(font.Bold ? "BOLD" : "")}" +
$"{(font.Italic ? "ITALIC" : "")}" +
$"{(font.Underline ? "UNDERLINE" : "")}");
popup.pszFont = pszFont;
try
{
HtmlHelp(parent.Handle, null, HTMLHelpCommand.HH_DISPLAY_TEXT_POPUP, popup);
}
finally
{
Marshal.FreeCoTaskMem(pszText);
Marshal.FreeCoTaskMem(pszFont);
}
}
[Flags()]
public enum HTMLHelpCommand : uint
{
HH_DISPLAY_TOPIC = 0,
HH_DISPLAY_TOC = 1,
HH_DISPLAY_INDEX = 2,
HH_DISPLAY_SEARCH = 3,
HH_DISPLAY_TEXT_POPUP = 0x000E,
HH_HELP_CONTEXT = 0x000F,
HH_CLOSE_ALL = 0x0012
}
[DllImport("hhctrl.ocx", SetLastError = true, EntryPoint = "HtmlHelpW", CharSet = CharSet.Unicode)]
static extern int HtmlHelp(IntPtr hWndCaller,
[MarshalAs(UnmanagedType.LPWStr)] string pszFile,
HTMLHelpCommand uCommand,
[MarshalAs(UnmanagedType.LPStruct)] HH_POPUP dwData);
[StructLayout(LayoutKind.Sequential)]
struct COLORREF
{
int ColorRef;
public COLORREF(int lRGB)
{
ColorRef = lRGB & 0x00ffffff;
}
public COLORREF(Color color) : this(color.ToArgb())
{
}
}
[StructLayout(LayoutKind.Sequential)]
class POINT
{
public int x;
public int y;
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
public POINT(Point p) : this(p.X, p.Y)
{
}
}
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom)
{
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
class HH_POPUP
{
internal int cbStruct = Marshal.SizeOf(typeof(HH_POPUP));
internal IntPtr hinst = IntPtr.Zero;
internal int idString = 0;
internal IntPtr pszText;
internal POINT pt;
internal COLORREF clrForeground = new COLORREF(-1);
internal COLORREF clrBackground = new COLORREF(-1);
internal RECT rcMargins = new RECT(-1, -1, -1, -1);
internal IntPtr pszFont;
}
}
HelpProvider2 组件
我创建了一个支持 Unicode 字符的 HelpProvider2
组件。它还公开了 Font、ForeColor 和 BackColor 属性:
下载或克隆
我正在使用 HelpProvider 显示对我的控件的帮助。
我输入了 HelpProvider 控件的帮助字符串。但这并不能正确显示字符串。
P/S:
我的语言是越南语,是 unicode 字体。
这是我编程时的文字:“Chúc mừng năm mới”
显示时的文字如下:
这是一个老错误,它是由两个问题造成的:
- HelpProvider 底层 API 使用的默认字体不支持 unicode 字符
- HelpProvider 的底层 API 不支持 Unicode。
解决这两个问题后,就可以正确显示Unicode字符了:
HelpExtensions.ShowPopup2(button1, "متن آزمایشی", Control.MousePosition);
第一个问题在Help
class(.NET 4.X, .NET 5) which has created the HH_POPUP
但是没有指定任何字体。因此不支持Unicode字符的默认字体将被使用。
- 可能的解决方法是使用支持 Unicode 字符的默认字体,例如
SystemFonts.CaptionFont
。
对于第二个问题,您需要更改 Windows 中的设置:
转到“控制面板”→“区域”→“管理”选项卡,然后在“非 Unicode 程序的语言”部分中,单击“更改系统区域设置...”按钮,然后在下一个对话框中, 选择您喜欢的语言,例如波斯语。
或者要同时支持其他语言,您可以选择:“Beta:使用 Unicode UTF-8 以获得全球语言支持”,即 Beta。
这里是 HelpExtensions
class:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public static class HelpExtensions
{
public static void ShowPopup2(Control parent, string caption, Point location, Font font = null, Color? backColor = null, Color? foreColor = null)
{
font = font ?? SystemFonts.CaptionFont;
backColor = backColor ?? Color.FromKnownColor(KnownColor.Window);
foreColor = foreColor ?? Color.FromKnownColor(KnownColor.WindowText);
var popup = new HH_POPUP();
popup.clrBackground = new COLORREF(backColor.Value);
popup.clrForeground = new COLORREF(foreColor.Value);
popup.pt = new POINT(location);
var pszText = Marshal.StringToCoTaskMemAuto(caption);
popup.pszText = pszText;
var pszFont = Marshal.StringToCoTaskMemAuto(
$"{font.Name}, {font.Size}, , " +
$"{(font.Bold ? "BOLD" : "")}" +
$"{(font.Italic ? "ITALIC" : "")}" +
$"{(font.Underline ? "UNDERLINE" : "")}");
popup.pszFont = pszFont;
try
{
HtmlHelp(parent.Handle, null, HTMLHelpCommand.HH_DISPLAY_TEXT_POPUP, popup);
}
finally
{
Marshal.FreeCoTaskMem(pszText);
Marshal.FreeCoTaskMem(pszFont);
}
}
[Flags()]
public enum HTMLHelpCommand : uint
{
HH_DISPLAY_TOPIC = 0,
HH_DISPLAY_TOC = 1,
HH_DISPLAY_INDEX = 2,
HH_DISPLAY_SEARCH = 3,
HH_DISPLAY_TEXT_POPUP = 0x000E,
HH_HELP_CONTEXT = 0x000F,
HH_CLOSE_ALL = 0x0012
}
[DllImport("hhctrl.ocx", SetLastError = true, EntryPoint = "HtmlHelpW", CharSet = CharSet.Unicode)]
static extern int HtmlHelp(IntPtr hWndCaller,
[MarshalAs(UnmanagedType.LPWStr)] string pszFile,
HTMLHelpCommand uCommand,
[MarshalAs(UnmanagedType.LPStruct)] HH_POPUP dwData);
[StructLayout(LayoutKind.Sequential)]
struct COLORREF
{
int ColorRef;
public COLORREF(int lRGB)
{
ColorRef = lRGB & 0x00ffffff;
}
public COLORREF(Color color) : this(color.ToArgb())
{
}
}
[StructLayout(LayoutKind.Sequential)]
class POINT
{
public int x;
public int y;
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
public POINT(Point p) : this(p.X, p.Y)
{
}
}
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom)
{
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
class HH_POPUP
{
internal int cbStruct = Marshal.SizeOf(typeof(HH_POPUP));
internal IntPtr hinst = IntPtr.Zero;
internal int idString = 0;
internal IntPtr pszText;
internal POINT pt;
internal COLORREF clrForeground = new COLORREF(-1);
internal COLORREF clrBackground = new COLORREF(-1);
internal RECT rcMargins = new RECT(-1, -1, -1, -1);
internal IntPtr pszFont;
}
}
HelpProvider2 组件
我创建了一个支持 Unicode 字符的 HelpProvider2
组件。它还公开了 Font、ForeColor 和 BackColor 属性:
下载或克隆