改进 LinkLabel - 使用系统手形光标和更改链接颜色

Posted

技术标签:

【中文标题】改进 LinkLabel - 使用系统手形光标和更改链接颜色【英文标题】:Improve LinkLabel - Use system hand Cursor and Change Link Color 【发布时间】:2019-01-12 14:49:06 【问题描述】:

LinkLabel控件有一些烦人的问题:

默认情况下,它不使用任何系统颜色(即Color.Blue 而不是SystemColors.HotTrack 用于LinkColor 属性) 它使用旧的、丑陋的、带有别名的手形光标版本

我找到了以下答案here,它声称可以解决光标问题:

using System.Runtime.InteropServices;

namespace System.Windows.Forms 
    public class LinkLabelEx : LinkLabel 
        private const int IDC_HAND = 32649;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);

        private static readonly Cursor SystemHandCursor = new Cursor(LoadCursor(IntPtr.Zero, IDC_HAND));

        protected override void OnMouseMove(MouseEventArgs e) 
            base.OnMouseMove(e);

            // If the base class decided to show the ugly hand cursor
            if(OverrideCursor == Cursors.Hand) 
                // Show the system hand cursor instead
                OverrideCursor = SystemHandCursor;
            
        
    

但是,这个解决方案并不完美。例如,旧的、丑陋的光标在将鼠标悬停在正确的光标上之前会闪烁一帧。

我还阅读了ComCtl32.dll 中没有问题的原生SysLink 控件,但我找不到在C#/WinForms 中使用它的好解决方案。不过我还是更喜欢纯 .NET 解决方案。

如何通过解决上述问题使LinkLabel控件更好?

【问题讨论】:

问题是什么?创建SysLink 控件还是修复光标问题? @RezaAghaei 我只提到了SysLink,因为它没有提到的问题。但是,如果有纯 .NET 解决方案,我会更喜欢。 如果您将代码添加到您的问题中并清楚提到的问题您正在尝试解决的问题,IMO 它可以被视为一个好问题并且可能会重新打开。跨度> @RezaAghaei 我现在重新表述了我的问题,以便更清楚我的意思。 @Reza Aghaei 重新打开。我认为您应该在此处发布答案,因为问题和上下文不同。 【参考方案1】:

关于颜色,该控件具有允许您更改链接颜色的属性:LinkColorActiveLinkColorVisitedLinkColorDisabledLinkColor

这些属性的默认值来自存储在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Settings 注册表项中的 Internet Explorer 设置。

要使用不同的颜色,您可以根据自己的喜好设置这些属性。例如,您可以将LinkColor 设置为SystemColors.HotTrack 或遵循w3org 的颜色建议,并使用#0000EE 作为默认链接颜色,#551A8B 用于访问链接,#FF0000 用于活动链接。

关于闪烁,这是因为您共享的代码是在基类更改光标后将光标设置为鼠标移动。因此,在设置新光标之前有机会闪烁基类光标。要解决这个问题,您需要处理WM_SETCURSOR,并在必要时将光标设置为系统手形光标。

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class MyLinkLabel : LinkLabel

    public MyLinkLabel()
    
        this.LinkColor = Color.FromArgb(0x00, 0x66, 0xCC);
        this.VisitedLinkColor = Color.FromArgb(0x80, 0x00, 0x80);
        this.ActiveLinkColor = Color.FromArgb(0xFF, 0x00, 0x00);
    
    const int IDC_HAND = 32649;
    const int WM_SETCURSOR = 0x0020;
    const int HTCLIENT = 1;
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
    [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    public static extern IntPtr SetCursor(HandleRef hcursor);

    static readonly Cursor SystemHandCursor = 
        new Cursor(LoadCursor(IntPtr.Zero, IDC_HAND));
    protected override void WndProc(ref Message msg)
    
        if (msg.Msg == WM_SETCURSOR)
            WmSetCursor(ref msg);
        else
            base.WndProc(ref msg);
    
    void WmSetCursor(ref Message m)
    
        if (m.WParam == (IsHandleCreated ? Handle : IntPtr.Zero) &&
           (unchecked((int)(long)m.LParam) & 0xffff) == HTCLIENT)
        
            if (OverrideCursor != null)
            
                if (OverrideCursor == Cursors.Hand)
                    SetCursor(new HandleRef(SystemHandCursor, SystemHandCursor.Handle));
                else
                    SetCursor(new HandleRef(OverrideCursor, OverrideCursor.Handle));
            
            else
            
                SetCursor(new HandleRef(Cursor, Cursor.Handle));
            
        
        else
        
            DefWndProc(ref m);
        
    

【讨论】:

这就像一个魅力,即使是AutoSize = falseLinkArea

以上是关于改进 LinkLabel - 使用系统手形光标和更改链接颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何将箭头光标图像更改为我的网页的手形图像[重复]

Rails:手形光标不出现

css 光标手形指针

CSS 手形光标

css 强制手形光标覆盖可点击的项目

是否可以删除悬停在链接上时出现的手形光标? (或将其设置为普通指针)