改进 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】:
关于颜色,该控件具有允许您更改链接颜色的属性:LinkColor
、ActiveLinkColor
、VisitedLinkColor
和DisabledLinkColor
。
这些属性的默认值来自存储在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 = false
和LinkArea
!以上是关于改进 LinkLabel - 使用系统手形光标和更改链接颜色的主要内容,如果未能解决你的问题,请参考以下文章