TaskDialog显示中文文本而不是en-us

Ein*_*ery 2 vb.net windows winapi

我们最近更新了一个内部工具,使用供应商的在线工具,而不是之前的自制功能.此更新中的一项任务是在用户单击用于执行操作的按钮时将用户重定向到网站.

我想在消息框上嵌入一个超链接,因为键入一个URL是非常1994年; 但MsgBox无法做到这一点.我被告知TaskDialog会这样做,但它会显示一堆中文字符而不是我输入的文字.

我不会说中文,我不知道我安装了这种语言.无论如何,此对话框需要显示我输入的英文文本.

请帮忙.

这是我期望的(大致):
msgbox对话框

而这就是我所得到的:
中文Taskdialog

这是我用来生成上述代码的代码:

Public Class Form1
    '[DllImport("comctl32.dll", CharSet = CharSet.Unicode,  EntryPoint="TaskDialog")]
    'Static extern int TaskDialog(IntPtr hWndParent, IntPtr hInstance, String pszWindowTitle,
    'String pszMainInstruction, String pszContent, int dwCommonButtons, IntPtr pszIcon, out int pnButton);
    Declare Function TaskDialog Lib "comctl32" Alias "TaskDialog" (
        hWndParent As IntPtr _
        , hInstance As IntPtr _
        , pszWindowTitle As String _
        , pszMainInstruction As String _
        , pszContent As String _
        , dwCommonButtons As Integer _
        , pszIcon As IntPtr _
        , ByRef pnButton As Integer) _
        As Integer

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim b As Integer = 0
        Dim r As Integer = -3

        MsgBox("Use x to process accounts" & vbCrLf &
                "Please visit http://x.u.org:8080/.")
        r = TaskDialog(Me.Handle, IntPtr.Zero,
                       "Account Processing through x",
                       "Use x to process accounts",
                       "Please visit <a href='http://x.u.org:8080/'>http://x.u.org:8080/</a>.",
                       1, UInt16.MaxValue, b)

        MsgBox(String.Format("b:|{0}|; r:|{1}|", b, r))

    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

最后的调试框显示"b:| 1 |; r:| 0 |".

Vis*_*ent 5

我认为问题在于你已经将原生.NET DllImport声明转换Declare Function为VB6时代的过时声明.通常只要参数正确就可以了,但是DllImport声明首选与.NET平台调用完全兼容.

在这种情况下,该TaskDialog函数需要Unicode(UTF-16)字符串(这由W in 表示PCWSTR,其代表Wide,宽字符中所示).该Declare Function语句没有指定要使用的char集的方法,因此它可能默认为ANSI - 单字节char集.

TaskDialog函数要求每个char 长度为两个字节,但它接收的字符串仅使用每个字符一个字节,使该函数将每个其他字符解释为前一个字符的一部分.这导致相当高的char代码,恰好映射到UTF-16字符表中的中文字符.

如果查看对话框的蓝色标题,您可以看到它只显示与实际字符串一样多的字符的一半("使用x来处理帐户").

解决方法是DllImport在VB.NET中使用声明,允许您指定CharSet.Unicode:

<DllImport("comctl32.dll", CharSet := CharSet.Unicode)> _
Public Shared Function TaskDialog( _
    hWndParent As IntPtr _
    , hInstance As IntPtr _
    , pszWindowTitle As String _
    , pszMainInstruction As String _
    , pszContent As String _
    , dwCommonButtons As Integer _
    , pszIcon As IntPtr _
    , ByRef pnButton As Integer) _
    As Integer
End Function
Run Code Online (Sandbox Code Playgroud)