简体   繁体   English

在Windows 10 1803上的RichTextBox中没有下划线的超链接

[英]Hyperlinks without underline in RichTextBox on Windows 10 1803

I'm displaying RTF document in RichTextBox ("upgraded" to RichEdit50W ). 我在RichTextBox显示RTF文档(“升级”到RichEdit50W )。 Keywords in the document are linked to a webpage using a syntax: 文档中的关键字使用语法链接到网页:

{\field{\*\fldinst{HYPERLINK ""https://www.example.com/"" }}{\fldrslt{\cf1 keyword\cf0 }}}

I do not want to underline the keywords. 我不想强调关键字。 Until Windows 10 version 1803 (and in all previous versions of Windows, including XP, Vista, 8), whenever a color was set on the anchor (note the \\cf1 ), the anchor was not underlined. 在Windows 10版本1803(以及所有以前版本的Windows,包括XP,Vista,8)中,只要在锚点上设置了颜色(注意\\cf1 ),锚点就不会加下划线。

But this no longer works in Windows 10 version 1803. I'm going to report this to Microsoft. 但这不再适用于Windows 10版本1803.我将向Microsoft报告此情况。 But I'm not really sure, if I was not relying on an undocumented behavior. 但我不确定,如果我不依赖于无证件的行为。 I can imagine that this change is actually not a bug, but rather a fix. 我可以想象这个改变实际上不是一个错误,而是一个修复。 So I wonder whether there is not a more correct way to prevent hyperlinks from being underlined. 所以我想知道是否有更正确的方法来防止超链接加下划线。

Sample code: 示例代码:

public class ExRichText : RichTextBox
{
    [DllImport("kernel32.dll", EntryPoint = "LoadLibraryW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern IntPtr LoadLibraryW(string path);

    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            LoadLibraryW("MsftEdit.dll");
            cp.ClassName = "RichEdit50W";
            return cp;
        }
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        ExRichText rtb = new ExRichText();
        rtb.Parent = this;
        rtb.SetBounds(10, 10, 200, 100);
        rtb.Rtf = @"{\rtf1 {\colortbl ;\red255\green0\blue0;}bar {\field{\*\fldinst{HYPERLINK ""https://www.example.com/"" }}{\fldrslt{\cf1 link\cf0 }}} bar}";
    }
}

(unwanted) result on Windows 10 version 1803: Windows 10版本1803上的(不需要的)结果:

在此输入图像描述

(desired) result on Windows 10 version 1706: Windows 10版本1706上的(所需)结果:

在此输入图像描述

and the same result on Windows 7: 和Windows 7上相同的结果:

在此输入图像描述

For Windows 8 and above, you can use the SendMessage function to send the EM_SETEDITSTYLEEX message to richedit control to disable the underlining of friendly links by specifying SES_EX_HANDLEFRIENDLYURL for the lParam argument and zero for the wParam` argument. 对于Windows 8及更高版本,您可以使用SendMessage函数EM_SETEDITSTYLEEX消息发送到richedit控件,以通过为lParam参数指定SES_EX_HANDLEFRIENDLYURL并为wParam`参数指定零来禁用友好链接的下划线。

SES_EX_HANDLEFRIENDLYURL SES_EX_HANDLEFRIENDLYURL

Display friendly name links with the same text color and underlining as automatic links, provided that temporary formatting isn't used or uses text autocolor (default: 0). 如果未使用临时格式化或使用文本autocolor(默认值:0),则显示具有相同文本颜色和下划线为自动链接的友好名称链接。

Even though the underlining is supposedly disabled by default, the RichTextBox control has it enabled. 即使默认情况下禁用下划线,RichTextBox控件也会启用它。

Add the following to your ExRichText class to provide a method (UnderlineFriendlyLink) to disable the underlining. 将以下内容添加到ExRichText类以提供禁用下划线的方法(UnderlineFriendlyLink)。

private const Int32 WM_User = 0x400;
private const Int32 EM_SETEDITSTYLEEX = WM_User + 275;
private const Int32 EM_GETEDITSTYLEEX = WM_User + 276;

/// <summary>Display friendly name links with the same text color and underlining as automatic links, provided that temporary formatting isn’t used or uses text autocolor (default: 0)</summary>
private const Int32 SES_EX_HANDLEFRIENDLYURL = 0x100;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private extern static Int32 SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam);

public static void UnderlineFriendlyLink(RichTextBox rtb, bool enabled = false)
{
    if (rtb.IsHandleCreated)
    {
        Int32 wParam = enabled ? SES_EX_HANDLEFRIENDLYURL : 0;
        Int32 lParam = SES_EX_HANDLEFRIENDLYURL; // settings mask
        Int32 res = SendMessage(new HandleRef(null, rtb.Handle), EM_SETEDITSTYLEEX, wParam, lParam);
    }
}

Example usage: 用法示例:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        exRichText1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}{\colortbl ;\red0\green0\blue255;}{\*\generator Riched20 10.0.16299}\viewkind4\uc1 \pard\f0\fs29 Hello {\b{\field{\*\fldinst{HYPERLINK ""http://www.fred.com""}}{\fldrslt{Link}}}}\f0\fs29\par\par https://www.google.com \par\par sd {{\field{\*\fldinst{HYPERLINK ""http://www.fred.com""}}{\fldrslt{klasl}}}}\f0\fs29  wed asdasd \par\par}";
    }

    private void exRichText1_LinkClicked(object sender, LinkClickedEventArgs e)
    {
        System.Diagnostics.Debug.Print(e.LinkText);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ExRichText.UnderlineFriendlyLink(exRichText1, false);
    }
}

Your post did not indicate how you are detecting the clicking of the links, but be advised that if you are relying on the LinkClicked event as shown in the above example that event may not fire due to a logic bug in the RichTextBox CharRangeToString method . 您的帖子没有说明您是如何检测链接的点击 ,但是请注意,如果您依赖于LinkClicked事件,如上例所示,由于RichTextBox CharRangeToString方法中的逻辑错误,该事件可能无法触发。 In particular this code fragment. 特别是这段代码片段。

        //Windows bug: 64-bit windows returns a bad range for us.  VSWhidbey 504502.  
        //Putting in a hack to avoid an unhandled exception.
        if (c.cpMax > Text.Length || c.cpMax-c.cpMin <= 0) {
            return string.Empty;
        }

If you try the sample code, you will notice that the event fires only for the first link. 如果您尝试示例代码,您会注意到事件仅针对第一个链接触发。 If CharRangeToString returns String.Empty , the event is not raised. 如果CharRangeToString返回String.Empty ,则不会引发该事件。 This limiting condition uses the Text.Length property (58 for the example) that returns the as displayed length. 此限制条件使用Text.Length属性(示例中为58)返回显示的长度。 I believe that it should instead use the TextLength property (120 for the example). 我相信它应该使用TextLength属性(示例为120)。

By monitoring the control's parent for the EM_Notify message and processing the mouse click notification, it is possible to extract the link using the CharRange structure when compiling for x86 or AnyCPU(prefer 32-bit). 通过监视控件的父级以获取EM_Notify消息并处理鼠标单击通知,可以在编译x86或AnyCPU(更喜欢32位)时使用CharRange结构提取链接。 When running as a 64-bit assembly, the CharRange structure does return invalid values as indicated in the source code. 当作为64位程序集运行时,CharRange结构会返回无效值,如源代码中所示。


Edit: All testing was done on Windows 10 version 1706 as I will not install 1803 at this time. 编辑:所有测试都在Windows 10版本1706上完成,因为此时我不会安装1803。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在没有新段落的情况下将可点击的超链接添加到RichTextBox中 - Add clickable hyperlinks to a RichTextBox without new paragraph C#HttpListener类不适用于Windows 10版本1803 - C# HttpListener Class not Working with Windows 10 version 1803 UWP-App创建的文件未在Windows 10 1803中编制索引 - UWP-App created files not indexed in Windows 10 1803 Windows 10 Pro -version 1803蓝牙配置文件访问 - Windows 10 Pro -version 1803 bluetooth Profiles Access 绑定RichTextBox而不输入很多无用的代码或将HyperLinks添加到字符串? - Bind RichTextBox without typing a lot of useless code or add HyperLinks to strings? C# WPF Windows 10 (1803) TouchKeyboard 不可靠问题 (Prism ClickOnce) - C# WPF Windows 10 (1803) TouchKeyboard unreliable Issue (Prism ClickOnce) Windows 10更新1803之后,从网络共享运行时我的程序无法打开套接字 - After Windows 10 update 1803 my program can't open a socket when running from network share 动态添加到RichTextBox的超链接 - Dynamically adding hyperlinks to a RichTextBox 在Windows 10(1803)上,如果WPF透明窗口覆盖它们,则所有应用程序都会丢失触摸或手写笔 - On Windows 10 (1803), all applications lost touch or stylus if a WPF transparent window covers on them HTML到RichTextBox作为带有超链接的纯文本 - HTML to RichTextBox as Plaintext with Hyperlinks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM