.Net中Cursor.Current
和this.Cursor
(在哪里this
是WinForm)之间有区别吗?我一直使用它this.Cursor
并且运气很好但是我最近开始使用CodeRush并且只是在"Wait Cursor"块中嵌入了一些代码而CodeRush使用了该Cursor.Current
属性.我已经在互联网和工作中看到其他程序员遇到了一些问题Cursor.Current
.它让我想知道这两者是否存在差异.提前致谢.
我做了一点测试.我有两个winforms.我单击form1上的一个按钮,将Cursor.Current
属性设置为Cursors.WaitCursor
,然后显示form2.两种形式的光标都不会改变.它仍然是Cursors.Default
(指针)光标.
如果我设置this.Cursor
到Cursors.WaitCursor
在Form1并显示窗体2按钮点击事件,等待光标只显示Form1上,默认光标在预计窗口2.所以,我还是不知道是什么Cursor.Current
.
Windows将包含鼠标光标的窗口发送到WM_SETCURSOR消息,使其有机会更改光标形状.像TextBox这样的控件利用了这一点,将光标更改为I-bar.Control.Cursor属性确定将使用的形状.
Cursor.Current属性直接更改形状,而不等待WM_SETCURSOR响应.在大多数情况下,这种形状不太可能存活很久.一旦用户移动鼠标,WM_SETCURSOR就会将其更改回Control.Cursor.
在.NET 2.0中添加了UseWaitCursor属性,以便更容易显示沙漏.不幸的是,它不能很好地工作.它需要WM_SETCURSOR消息来更改形状,并且当您将属性设置为true然后执行需要一段时间的操作时不会发生这种情况.试试这个代码,例如:
private void button1_Click(object sender, EventArgs e) { this.UseWaitCursor = true; System.Threading.Thread.Sleep(3000); this.UseWaitCursor = false; }
光标永远不会改变.为了解决这个问题,你需要使用Cursor.Current.这是一个简单的帮助类:
using System; using System.Windows.Forms; public class HourGlass : IDisposable { public HourGlass() { Enabled = true; } public void Dispose() { Enabled = false; } public static bool Enabled { get { return Application.UseWaitCursor; } set { if (value == Application.UseWaitCursor) return; Application.UseWaitCursor = value; Form f = Form.ActiveForm; if (f != null && f.Handle != IntPtr.Zero) // Send WM_SETCURSOR SendMessage(f.Handle, 0x20, f.Handle, (IntPtr)1); } } [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); }
并像这样使用它:
private void button1_Click(object sender, EventArgs e) { using (new HourGlass()) { System.Threading.Thread.Sleep(3000); } }
我相信Cursor.Current是当前正在使用的鼠标光标(无论它在屏幕上的什么位置),而this.Cursor是当鼠标经过你的窗口时它将被设置的光标.
this.Cursor
是当鼠标位于所引用的窗口上时将使用的光标this
. Cursor.Current
是当前鼠标光标,可能this.Cursor
与鼠标位于不同窗口时不同.
实际上,如果你想从另一个线程中使用HourGlass,它会回复跨线程异常,因为你试图从最初创建的表单以外的不同线程访问f.Handle.使用GetForegroundWindow()而不是user32.dll.
[DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow();
然后
public static bool Enabled { get { return Application.UseWaitCursor; } set { if (value == Application.UseWaitCursor) { return; } Application.UseWaitCursor = value; var handle = GetForegroundWindow(); SendMessage(handle, 0x20, handle, (IntPtr)1); } }