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
控件更好?
答案 0 :(得分:2)
关于颜色,该控件具有一些属性,可用于更改链接颜色: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);
}
}
}