【问题标题】:How to get mouse cursor dimensions on Delphi?如何在 Delphi 上获取鼠标光标尺寸?
【发布时间】:2013-07-14 20:06:48
【问题描述】:

我使用Toolbar2000 组件。它在正确位置下方显示按钮的提示,系统比例 > 100%。所以,我需要手动设置 HintPos。我有Mouse.CursorPos。但提示应显示在鼠标光标图像下方。

如何获取鼠标光标尺寸?

【问题讨论】:

  • 也许这个msdn.microsoft.com/en-us/library/windows/desktop/… 就是你要找的?
  • @ComputerSaysNo 您的链接声称:“如果光标不限于矩形,则该结构接收屏幕的尺寸” - 您真的认为整个桌面可能是光标的大小吗?这是一个非常不同的事情——这是一个光标不能移出的窗口

标签: delphi mouse hint


【解决方案1】:

您应该向 Windows 询问 System Metrics - 请参阅 http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385.aspx

但是,如果用户安装了 Stardock CursorFX 之类的东西,这些值将与用户真正看到的内容以及他对程序的期望行为不匹配。

这似乎是 Win32 API 的限制之一,除了来自旧批准集的几个相对较小的标准值之外,该值无法更改。

【讨论】:

  • 不,你可以使用such code
  • @TLama 它仍然不会考虑第 3 方 Windows 扩展。还认为由于任何 Windows 事件(如插入新磁盘或其他),光标可能每秒都会发生变化。所以如果你要进行像素搜索,你会每秒重复 20 次以在光标形状改变后移动提示窗口吗?
  • 你在说什么?我们在谈论游标,而不是关于 3rd 方的东西。你至少应该提到你应该要求的SM_CXCURSORSM_CYCURSOR 常量,而不仅仅是在外部链接后面询问一些今年可能会失效的东西。不投反对票,但你的答案有时值得。我无话可说……
  • 链接是官方文档。 SO 不应该成为它的替代品。 SO链接可能会失败,不正确,被编辑为不正确,其。 MSDN 是这个问题的主要数据源。我也无法理解为什么链接到带有黑客代码的非官方博客是好的,而到官方文档的链接是不好的。这看起来不一致。
  • 光标是一张图片——像一个物品一样有透明像素的图片。它可能所有像素都透明或所有像素不透明,但通常,就像图标一样,它是两者的混合。 System Metrics 是该图片的大小,但其中的哪些像素是透明的或不透明的 - System Metrics 无法知道。毕竟光标可能每秒改变几次
【解决方案2】:

您可以创建一个图标,使用GetCursor 设置句柄,可以使用GetIconInfo 检索附加信息。如果显示用户定义的光标,这甚至可以工作,它可能具有几乎任何大小。

var
  ico: TIcon;
  IcoInfo: TIconInfo;
begin
  ico := TIcon.Create;
  try
    ico.Handle := GetCursor;
    try
      GetIconInfo(ico.Handle, IcoInfo);
      Caption := Format('Width %d, Height %d HotSpotX %d, HotSpotY %d',
        [ico.Width, ico.Height, IcoInfo.xHotspot, IcoInfo.yHotspot]);
    finally
      ico.ReleaseHandle;
    end;
  finally
    ico.Free;
  end;
end;


// Just as example for an very unusual cursor
procedure TForm1.Button1Click(Sender: TObject);
var
  IconInfo: TIconInfo;
  AndMask, Bmp: TBitmap;
  w, h: Integer;
begin
  w := Screen.Width * 2;
  h := Screen.Height * 2;

  // Creation And Mask
  AndMask := TBitmap.Create;
  AndMask.Monochrome := True;
  AndMask.Height := h;
  AndMask.Width := w;

  // Draw on And Mask
  AndMask.Canvas.Brush.Color := clWhite;
  AndMask.Canvas.FillRect(AndMask.Canvas.ClipRect);

  AndMask.Canvas.Pen.Color := clwhite;
  AndMask.Canvas.Pen.Width := 5;
  AndMask.Canvas.MoveTo(w div 2, 0);
  AndMask.Canvas.LineTo(w div 2, h);
  AndMask.Canvas.MoveTo(0, h div 2);
  AndMask.Canvas.LineTo(w, h div 2);

  {Create the "XOr" mask}
  Bmp := TBitmap.Create;

  Bmp.Width := w;
  Bmp.Height := h;

  {Draw on the "XOr" mask}
  Bmp.Canvas.Brush.Color := clblack;
  Bmp.Canvas.FillRect(Rect(0, 0, w, h));
  Bmp.Canvas.Pen.Color := clwhite;
  Bmp.Canvas.Pen.Width := 5;
  Bmp.Canvas.MoveTo(w div 2, 0);
  Bmp.Canvas.LineTo(w div 2, h);
  Bmp.Canvas.MoveTo(0, h div 2);
  Bmp.Canvas.LineTo(w, h div 2);


  IconInfo.fIcon := true;
  IconInfo.xHotspot := w div 2;
  IconInfo.yHotspot := h div 2;
  IconInfo.hbmMask := AndMask.Handle;
  IconInfo.hbmColor :=  Bmp.Handle;

  Screen.Cursors[1]:= CreateIconIndirect(IconInfo);
  Screen.Cursor:=1;

end;

【讨论】:

  • 像素搜索的问题(包括针对 HotSpot 的调整)是鼠标光标旨在随时更改为内部或外部事件...
  • 我的重点不是热点,尽管它可能对用户设计的奇特光标(例如提示光标)很有趣。我只是想展示一种获取所需数据的方法。
  • 上面的代码是否给出了一个带有大透明背景和光标指向(xHotspot,yHotspot)位置的图标?有没有简单的方法来计算它的高度(透明背景除外)?
  • ico.Height 返回与GetSystemMetrics(SM_CYCURSOR) 相同的错误值。我认为这是光标背景的大小 - 而不是光标。
  • @Altaveron,对于近距离裁剪矩形计算,您可以查看例如在this post。但是您需要将光标图像与其遮罩结合起来。 </self-promotion> :-)
【解决方案3】:

这是 Windows 7 的问题,没有合适的解决方案。 GetSystemMetrics(SM_CYCURSOR) 返回带有背景的光标图像的大小。在系统规模 >100% 的情况下,这个值似乎更不正确。 Delphi XE2 也显示了错误位置的提示。但有趣的是,Explorer 会显示正确位置的提示。

【讨论】:

    猜你喜欢
    • 2021-02-10
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多