【问题标题】:C# helpProvider SetHelpString does not support unicodeC# helpProvider SetHelpString 不支持 unicode
【发布时间】:2021-04-08 03:01:29
【问题描述】:

我正在使用HelpProvider 来显示对我的控制的帮助。

我输入了HelpProvider 控件的帮助字符串。但这不能正确显示字符串。

P/S:

我的语言是越南语,它是一种 unicode 字体。

这是我在编程时的文字:“Chúc mừng năm mới”

这是显示时的文本:

【问题讨论】:

  • 你确定字体有字符吗?它与带有帮助字符串的控件的字体相同
  • 这是一个已知的错误 (social.msdn.microsoft.com/Forums/en-US/…)... 遗憾的是,HelpProvider 是从未有人使用过的未知功能之一,因此它仍然存在错误
  • 看看能不能用ToolTip:stackoverflow.com/a/28260468/613130
  • @Charlieface 不,它没有。使用固定字体(试过用Comic Sans设置控件,帮助提示还是原来的字体)
  • 我在这里发布了一个答案来展示如何修复它,还创建了一个支持 Unicode、Font、ForeColor 和 BackColor 的 HelpProvider2 Component。我可能会建议对 .NET 5 进行修复。

标签: c# winforms unicode


【解决方案1】:

这是一个老错误,是因为两个问题:

  • HelpProvider 底层 API 使用的默认字体不支持 unicode 字符
  • HelpProvider 的底层 API 不支持 Unicode。

修复这两个问题后,就可以正确显示Unicode字符了:

HelpExtensions.ShowPopup2(button1, "متن آزمایشی", Control.MousePosition);

第一个问题是在Help 类(.NET 4.X, .NET 5) 中创建了HH_POPUP,但没有为其指定任何字体。因此,将使用不支持 Unicode 字符的默认字体。

  • 可能的解决方法是使用支持 Unicode 字符的默认字体,例如 SystemFonts.CaptionFont

对于第二个问题,您需要更改 Windows 中的设置,这样做:

  • 转到控制面板→区域→管理选项卡,然后在“非Unicode程序的语言”部分中,单击“更改系统区域设置...”按钮,然后在下一个对话框中选择您选择的语言,例如波斯语。

    或者也支持其他语言,您可以选择:“Beta: Use Unicode UTF-8 for global language support”,即 Beta。

这里是HelpExtensions类:

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 属性:

下载或克隆

【讨论】:

  • 如果您对答案有任何疑问,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2013-05-14
  • 2011-04-15
  • 2011-06-09
  • 1970-01-01
  • 2013-06-23
  • 2011-11-29
  • 2015-02-14
  • 1970-01-01
相关资源
最近更新 更多