WPF:绘制自己的光标 - 不平凡的问题

发布于 2024-09-08 18:41:41 字数 1185 浏览 7 评论 0原文

我需要实现一个具有一些非常具体的功能的光标:

  • 它必须是动画的
    • 因为 n 秒后它会自动点击 - 所以动画是当点击发生时向用户的反馈
  • 它必须捕捉到我们的一些控件,
  • 它必须在我们的应用程序之外工作

到目前为止的方法:

  • 渲染我的 WPF -control 进入位图,从中创建一个光标结构并使用 user32.dll/SetSystemCursor 来设置它
    • 专业版
    • 光标在鼠标之后没有延迟,因为它是真正的光标
    • CON
    • 捕捉非常困难,特别是因为我们有绝对和相对输入设备,我必须一直重置鼠标位置或使用 user32.dll/ClipCursor (System.Windows.Forms.Cursor.Clip 的作用相同)捕捉的光标总是在捕捉的位置周围晃动(试图逃脱,get再次重置......)
    • 我使用的代码在一段随机时间后抛出奇怪的异常 - 所以我当前的代码看起来相当不稳定
  • 将我自己的光标渲染为最大化,最上面,allowtransparent,windowstyle=none,不可见窗口,并在鼠标后手动移动光标(如 Canvas .SetLeft(光标, MousePosition.X))
    • 专业版
    • 可以(轻松)完成捕捉
    • CON
    • 当鼠标单击并击中光标时,光标将被单击,而不是超出的窗口
    • 一直在调度程序背景循环中轮询鼠标位置对我来说似乎不太漂亮

要解决第二种方法,我的光标必须至少有一个透明像素 在热点中,以便鼠标可以点击...这对我来说似乎不是一个真正的解决方案...

有人有任何想法吗?

编辑: 一些示例源来显示问题...:

示例应用程序和示例显示将鼠标捕捉到固定位置的问题的源代码:ClipIt.rar

示例应用程序和示例随机时间后失败的源 - 设置自绘光标:TryOwnCur.rar

可以在以下位置找到:http://sourcemonk。 com/光标

i need to implement a cursor with some very specific features:

  • it has to be animated
    • because after n seconds it automatically clicks - so the animation is feedback for the user when the click will happen
  • it has to snap to some of our controls
  • it has to work outside of our application

the approaches so far:

  • render my WPF-control into a bitmap, make a cursor-struct out of it and use user32.dll/SetSystemCursor to set it
    • PRO
    • the cursor has no delay after the mouse since it's a real cursor
    • CON
    • snapping is quite hard, especially since we have absolute and relative inputdevices and i would have to reset the mouseposition all the time or use user32.dll/ClipCursor (System.Windows.Forms.Cursor.Clip does the same) but the snapped cursor is always shaking around the snapped position (tries to escape, get's reset again....)
    • the code i use throws strange exceptions after some random time - so my current code seems quite unstable
  • render my own cursor into a maximized, topmost, allowtransparent, windowstyle=none, invisible window and manually move the cursor after the mouse (like Canvas.SetLeft(cursor, MousePosition.X))
    • PRO
    • snapping can be (easily) done
    • CON
    • when the mouse clicks and hit's the cursor the cursor get's clicked and not the window beyond
    • polling the mouseposition in a dispatcher-background-loop all the time doesn't seem very beautiful to me

to solve the second approach my cursor would have to have at least one transparent pixel
in the hotspot, so that the mouse can click through... that doesn't seem like a real solution to me...

any idea's anyone?

EDIT:
some example-source to show the problems...:

example app & source to show the problem with snapping the mouse to a fixed position: ClipIt.rar

example app & source that fails after random time - setting a self-drawn cursor: TryOwnCur.rar

can be found under: http://sourcemonk.com/Cursor

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欢烬 2024-09-15 18:41:41

感谢 http:// Social.msdn.microsoft.com/Forums/en-US/wpf/thread/a3cb7db6-5014-430f-a5c2-c9746b077d4f

我可以单击跟随鼠标位置的自绘光标
设置窗口样式:无,并允许透明,就像我已经做的那样
然后

public const int WS_EX_TRANSPARENT = 0x00000020;
  public const int GWL_EXSTYLE = (-20);

  [DllImport("user32.dll")]
  public static extern int GetWindowLong(IntPtr hwnd,
  int index);

  [DllImport("user32.dll")]
  public static extern int SetWindowLong(IntPtr hwnd,
  int index, int newStyle);

  public static void makeTransparent(IntPtr hwnd) {
     int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
     SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
  }

从 OnSourceInitialized 调用 makeTransparent...

thanks to http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a3cb7db6-5014-430f-a5c2-c9746b077d4f

i can click through my self-drawn cursor which follows the mouse-position by
setting the window style:none, and allowtransparent as i already did and
then

public const int WS_EX_TRANSPARENT = 0x00000020;
  public const int GWL_EXSTYLE = (-20);

  [DllImport("user32.dll")]
  public static extern int GetWindowLong(IntPtr hwnd,
  int index);

  [DllImport("user32.dll")]
  public static extern int SetWindowLong(IntPtr hwnd,
  int index, int newStyle);

  public static void makeTransparent(IntPtr hwnd) {
     int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
     SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
  }

and call makeTransparent from OnSourceInitialized...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文