如何获取当前GLOBAL鼠标光标类型(沙漏/箭头/...)?在Windows中。
全局 - 我需要它,即使鼠标在我的应用程序之外,或者即使我的程序没有窗口。
使用C#,Delphi或纯WinAPI都可以。
非常感谢您的提前帮助!
三年后,现在是时候回答我自己的问题了。以下是如何用C#检查当前全局光标是否为沙漏(如果有需要,请根据您自己的需求扩展代码):
private static bool IsWaitCursor()
{
var h = Cursors.WaitCursor.Handle;
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if(!GetCursorInfo(out pci))
throw new Win32Exception(Marshal.GetLastWin32Error());
return pci.hCursor == h;
}
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public Int32 x;
public Int32 y;
}
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize; // Specifies the size, in bytes, of the structure.
// The caller must set this to Marshal.SizeOf(typeof(CURSORINFO)).
public Int32 flags; // Specifies the cursor state. This parameter can be one of the following values:
// 0 The cursor is hidden.
// CURSOR_SHOWING The cursor is showing.
public IntPtr hCursor; // Handle to the cursor.
public POINT ptScreenPos; // A POINT structure that receives the screen coordinates of the cursor.
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetCursorInfo(out CURSORINFO pci);
const
HighCursor = 13;
type
TForm1 = class(TForm)
Timer1: TTimer;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
FCursorHandles: array [0..HighCursor] of HCURSOR;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
OEMCursors: array [0..HighCursor] of Integer = (OCR_NORMAL, OCR_IBEAM,
OCR_WAIT, OCR_CROSS, OCR_UP, OCR_SIZENWSE, OCR_SIZENESW, OCR_SIZEWE,
OCR_SIZENS, OCR_SIZEALL, OCR_NO, OCR_HAND, OCR_APPSTARTING,
32651 {OCR_HELP?});
CursorNames: array [0..HighCursor] of string = ('OCR_NORMAL', 'OCR_IBEAM',
'OCR_WAIT', 'OCR_CROSS', 'OCR_UP', 'OCR_SIZENWSE', 'OCR_SIZENESW',
'OCR_SIZEWE', 'OCR_SIZENS', 'OCR_SIZEALL', 'OCR_NO', 'OCR_HAND',
'OCR_APPSTARTING', 'OCR_HELP');
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i := 0 to HighCursor do
FCursorHandles[i] := LoadImage(0, MakeIntResource(OEMCursors[i]),
IMAGE_CURSOR, 0, 0, LR_DEFAULTCOLOR or LR_DEFAULTSIZE or LR_SHARED);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
function GetCursorName(Cursor: HCURSOR): string;
var
i: Integer;
begin
for i := 0 to HighCursor do
if Cursor = FCursorHandles[i] then begin
Result := CursorNames[i];
Exit;
end;
Result := 'Unknown Cursor'; // A custom cursor.
end;
var
CursorInfo: TCursorInfo;
begin
CursorInfo.cbSize := SizeOf(CursorInfo);
if GetCursorInfo(CursorInfo) then
Label1.Caption := GetCursorName(CursorInfo.hCursor)
else
Label1.Caption := 'Fail: ' + SysErrorMessage(GetLastError);
end;
使用 Delphi 语言
Screen.MouseCursor.
当前鼠标光标。
通用Win32(user32)提供:
function GetCursor: HCURSOR; stdcall;
这应该适用于其他 win32 语言。
@Alex 你救了我一天。我允许自己修改你的代码,这样每个光标都可以被反映出来...可能对其他人也有帮助:
public enum Cursor
{
UNKOWNCURSOR,
AppStarting,
Arrow,
Cross,
Default,
IBeam,
No,
SizeAll,
SizeNESW,
SizeNS,
SizeNWSE,
SizeWE,
UpArrow,
WaitCursor,
Help,
HSplit,
VSplit,
NoMove2D,
NoMoveHoriz,
NoMoveVert,
PanEast,
PanNE,
PanNorth,
PanNW,
PanSE,
PanSouth,
PanSW,
PanWest,
Hand
}
public static Cursor GetCursor()
{
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (!GetCursorInfo(out pci))
throw new Win32Exception(Marshal.GetLastWin32Error());
var h = pci.hCursor;
if (h == Cursors.AppStarting.Handle) return Cursor.AppStarting;
if (h == Cursors.Arrow.Handle) return Cursor.Arrow;
if (h == Cursors.Cross.Handle) return Cursor.Cross;
if (h == Cursors.Default.Handle) return Cursor.Default;
if (h == Cursors.IBeam.Handle) return Cursor.IBeam;
if (h == Cursors.No.Handle) return Cursor.No;
if (h == Cursors.SizeAll.Handle) return Cursor.SizeAll;
if (h == Cursors.SizeNESW.Handle) return Cursor.SizeNESW;
if (h == Cursors.SizeNS.Handle) return Cursor.SizeNS;
if (h == Cursors.SizeNWSE.Handle) return Cursor.SizeNWSE;
if (h == Cursors.SizeWE.Handle) return Cursor.SizeWE;
if (h == Cursors.UpArrow.Handle) return Cursor.UpArrow;
if (h == Cursors.WaitCursor.Handle) return Cursor.WaitCursor;
if (h == Cursors.Help.Handle) return Cursor.Help;
if (h == Cursors.HSplit.Handle) return Cursor.HSplit;
if (h == Cursors.VSplit.Handle) return Cursor.VSplit;
if (h == Cursors.NoMove2D.Handle) return Cursor.NoMove2D;
if (h == Cursors.NoMoveHoriz.Handle) return Cursor.NoMoveHoriz;
if (h == Cursors.NoMoveVert.Handle) return Cursor.NoMoveVert;
if (h == Cursors.PanEast.Handle) return Cursor.PanEast;
if (h == Cursors.PanNE.Handle) return Cursor.PanNE;
if (h == Cursors.PanNorth.Handle) return Cursor.PanNorth;
if (h == Cursors.PanNW.Handle) return Cursor.PanNW;
if (h == Cursors.PanSE.Handle) return Cursor.PanSE;
if (h == Cursors.PanSouth.Handle) return Cursor.PanSouth;
if (h == Cursors.PanSW.Handle) return Cursor.PanSW;
if (h == Cursors.PanWest.Handle) return Cursor.PanWest;
if (h == Cursors.Hand.Handle) return Cursor.Hand;
return Cursor.UNKOWNCURSOR;
}
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public Int32 x;
public Int32 y;
}
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize; // Specifies the size, in bytes, of the structure.
// The caller must set this to Marshal.SizeOf(typeof(CURSORINFO)).
public Int32 flags; // Specifies the cursor state. This parameter can be one of the following values:
// 0 The cursor is hidden.
// CURSOR_SHOWING The cursor is showing.
public IntPtr hCursor; // Handle to the cursor.
public POINT ptScreenPos; // A POINT structure that receives the screen coordinates of the cursor.
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetCursorInfo(out CURSORINFO pci);
注:使用 Delphi
大多数可视化对象可以使用 Cursor 属性,否则使用 Screen.Cursor 属性。 将其设置回 crDefault 可以取消先前所做的更改。