我希望显示一些与ToolTip
类似的信息 - 我无法使用ToolTip
,因为它没有提供足够的自定义,我需要将其展示给整个鼠标时间超过Control
问题是Cursor.Size
设置为32x32,但光标的可见部分只有12x19像素,因此光标的可见部分和我想要显示的信息之间存在很大的间隙(20x13像素)(在其他Windows版本或鼠标光标设置上可能会有所不同。)
我知道不同类型的光标(带时钟/问号,手,箭头的箭头)的尺寸更大,但是如何计算可见部分的尺寸?
应该有某种方式,因为ToolTip
显示在光标下方。
答案 0 :(得分:1)
感谢m.rogalski(指向我this question)和this answer以及this answer和this article我能够创建代码来计算可见部分鼠标光标。由于它使用非托管代码,最大的问题是内存管理,所以我希望我最终释放所有内容。如果没有,请告诉我。
的外部强>
using System;
using System.Runtime.InteropServices;
namespace MouseCursorHelper
{
/// <summary>
/// Source: https://www.codeproject.com/kb/cs/desktopcapturewithmouse.aspx
/// + DestroyIcon, DeleteObject
/// </summary>
class ExternalDlls
{
#region Class Variables
public const Int32 CURSOR_SHOWING = 0x00000001;
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFO
{
public bool fIcon; // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies
public Int32 xHotspot; // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot
public Int32 yHotspot; // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot
public IntPtr hbmMask; // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon,
public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public Int32 x;
public Int32 y;
}
[StructLayout(LayoutKind.Sequential)]
public struct CURSORINFO
{
public Int32 cbSize; // Specifies the size, in bytes, of the structure.
public Int32 flags; // Specifies the cursor state. This parameter can be one of the following values:
public IntPtr hCursor; // Handle to the cursor.
public POINT ptScreenPos; // A POINT structure that receives the screen coordinates of the cursor.
}
#endregion
#region Class Functions
[DllImport("user32.dll", EntryPoint = "GetCursorInfo")]
public static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll", EntryPoint = "CopyIcon")]
public static extern IntPtr CopyIcon(IntPtr hIcon);
[DllImport("user32.dll", EntryPoint = "GetIconInfo")]
public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
[DllImport("user32.dll", EntryPoint = "DestroyIcon")]
public static extern bool DestroyIcon(IntPtr hIcon);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
#endregion
}
}
尺寸计算
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace MouseCursorHelper
{
class CursorActualSize
{
public static Size GetActualSize()
{
Bitmap bmp;
IntPtr hicon;
ExternalDlls.CURSORINFO ci = new ExternalDlls.CURSORINFO();
ExternalDlls.ICONINFO icInfo;
ci.cbSize = Marshal.SizeOf(ci);
if (ExternalDlls.GetCursorInfo(out ci))
{
if (ci.flags == ExternalDlls.CURSOR_SHOWING)
{
hicon = ExternalDlls.CopyIcon(ci.hCursor);
if (ExternalDlls.GetIconInfo(hicon, out icInfo))
{
bmp = Bitmap.FromHbitmap(icInfo.hbmMask);
var x = 0;
var y = 0;
for (var i = 0; i < bmp.Width; i++)
{
for (var j = 0; j < bmp.Height; j++)
{
var a = bmp.GetPixel(i, j);
if (a.R == 0 && a.G == 0 && a.B == 0)
{
if (i > x)
{
x = i;
}
if (j > y)
{
y = j;
}
}
}
}
bmp.Dispose();
if (hicon != IntPtr.Zero)
{
ExternalDlls.DestroyIcon(hicon);
}
if (icInfo.hbmColor != IntPtr.Zero)
{
ExternalDlls.DeleteObject(icInfo.hbmColor);
}
if (icInfo.hbmMask != IntPtr.Zero)
{
ExternalDlls.DeleteObject(icInfo.hbmMask);
}
if (ci.hCursor != IntPtr.Zero)
{
ExternalDlls.DeleteObject(ci.hCursor);
}
return new Size(x, y);
}
if (hicon != IntPtr.Zero)
{
ExternalDlls.DestroyIcon(hicon);
}
if (icInfo.hbmColor != IntPtr.Zero)
{
ExternalDlls.DeleteObject(icInfo.hbmColor);
}
if (icInfo.hbmMask != IntPtr.Zero)
{
ExternalDlls.DeleteObject(icInfo.hbmMask);
}
}
}
if (ci.hCursor != IntPtr.Zero)
{
ExternalDlls.DeleteObject(ci.hCursor);
}
return new Size(0, 0);
}
}
}
然后只需致电
Size cursorSize = CursorActualSize.GetActualSize();