Kei*_*ith 54 .net c# cursor cursor.current winforms
.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.
Han*_*ant 89
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;
}
Run Code Online (Sandbox Code Playgroud)
光标永远不会改变.为了解决这个问题,你需要使用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);
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
private void button1_Click(object sender, EventArgs e) {
using (new HourGlass()) {
System.Threading.Thread.Sleep(3000);
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,如果你想从另一个线程中使用HourGlass,它会回复跨线程异常,因为你试图从最初创建的表单以外的不同线程访问f.Handle.使用GetForegroundWindow()而不是user32.dll.
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
Run Code Online (Sandbox Code Playgroud)
然后
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);
}
}
Run Code Online (Sandbox Code Playgroud)