关于光标

Windows 提供了一组可供应用程序使用的标准光标。 WinUser.h 中定义了以下光标标识符:

含义
IDC_ARROW
MAKEINTRESOURCE(32512)
正常选择
IDC_IBEAM
MAKEINTRESOURCE(32513)
文本选择
IDC_WAIT
MAKEINTRESOURCE(32514)
忙碌
IDC_CROSS
MAKEINTRESOURCE(32515)
精度选择
IDC_UPARROW
MAKEINTRESOURCE(32516)
备用选择
IDC_SIZENWSE
MAKEINTRESOURCE(32642)
对角线调整大小 1
IDC_SIZENESW
MAKEINTRESOURCE(32643)
对角线调整大小 2
IDC_SIZEWE
MAKEINTRESOURCE(32644)
水平调整大小
IDC_SIZENS
MAKEINTRESOURCE(32645)
垂直调整大小
IDC_SIZEALL
MAKEINTRESOURCE(32646)
移动
IDC_NO
MAKEINTRESOURCE(32648)
不可用
IDC_HAND
MAKEINTRESOURCE(32649)
链接选择
IDC_APPSTARTING
MAKEINTRESOURCE(32650)
在后台工作
IDC_HELP
MAKEINTRESOURCE(32651)
帮助选择
IDC_PIN
MAKEINTRESOURCE(32671)
位置选择
IDC_PERSON
MAKEINTRESOURCE(32672)
人员选择

此外,还有一些光标尚未在 WinUser.h 中定义标识符(或被视作已经过时):

含义
MAKEINTRESOURCE(32631) 一个笔光标。
MAKEINTRESOURCE(32652) 一个箭头指向南北的滚动光标。
MAKEINTRESOURCE(32653) 一个箭头指向东西的滚动光标。
MAKEINTRESOURCE(32654) 一个箭头指向北、南、东、西的滚动光标。
MAKEINTRESOURCE(32655) 一个箭头指向北的滚动光标。
MAKEINTRESOURCE(32656) 一个箭头指向南的滚动光标。
MAKEINTRESOURCE(32657) 一个箭头指向西的滚动光标。
MAKEINTRESOURCE(32658) 一个箭头指向东的滚动光标。
MAKEINTRESOURCE(32659) 一个箭头指向西北的滚动光标。
MAKEINTRESOURCE(32660) 一个箭头指向东北的滚动光标。
MAKEINTRESOURCE(32661) 一个箭头指向西南的滚动光标。
MAKEINTRESOURCE(32662) 一个箭头指向东南的滚动光标。
MAKEINTRESOURCE(32663) 一个箭头 cd 光标。

有关使用标准光标的信息,请参阅指南

每个标准光标都有一个与之关联的相应默认图像。 用户或应用可以在任何时间替换与任何标准光标相关联的默认图像。 应用程序使用 SetSystemCursor 函数替换默认图像。

应用程序可以使用 GetIconInfo 函数检索光标的当前图像,并使用 DrawIconEx 函数绘制光标。

自定义光标是为在特定应用中使用而设计的,可以是开发人员定义的任何设计。 下图显示了几个自定义光标。

custom cursors, including hand, banana, drum, wristwatch on hand, metronome

光标可以是单色的,也可以是彩色的,可以是静态的,也可以是动画的。 在特定计算机系统上使用的光标类型取决于系统的显示。 旧显示器(如 VGA)不支持彩色或动画光标。 新显示器,其显示驱动程序使用与设备无关的位图 (DIB) 引擎,确实支持它们。

光标和图标相似,在许多情况下可以互换使用。 它们之间唯一的区别是,指定为光标的图像必须采用显示器可以支持的格式。 例如,对于 VGA 显示器,光标必须是单色的。

此概述提供有关以下主题的信息:

热点

在光标中,称为热点的像素标记受鼠标事件影响的确切屏幕位置,例如单击鼠标按钮。 通常,热点是光标的焦点。 系统跟踪并识别此点作为光标的位置。 例如,典型的热点是箭头形光标尖端的像素和十字形光标中间的像素。 下图显示了绘图程序中的两个光标,其中热点与画笔尖和涂料的十字准线相关联。

hot spots on two cursors

当鼠标输入事件发生时,鼠标驱动程序将该事件转换为适当的鼠标消息,其中包括热点的坐标。 系统将鼠标消息发送到包含热点的窗口或捕获鼠标输入的窗口。 有关详细信息,请参阅鼠标输入

鼠标和光标

系统通过相应地在屏幕上移动光标来反映鼠标移动。 当光标移动到窗口的不同部分或移动到不同的窗口时,系统(或应用程序)会更改光标的外观。 例如,当光标越过超链接时,系统将光标从箭头更改为手。

standard cursor changing to a hand when over a hyperlink

如果系统没有鼠标,则只有当用户选择某些系统命令(例如用于调整窗口大小或移动窗口的命令)时,系统才会显示和移动光标。 为了向用户提供在鼠标不可用时显示和移动光标的方法,应用程序可以使用光标功能来模拟鼠标移动。 鉴于此模拟功能,用户可以使用箭头键移动光标。

光标创建

由于标准光标是预定义的,因此无需创建它们。 若要使用标准光标,应用程序使用 LoadCursorLoadImage 函数检索光标句柄。 光标句柄是用于标识标准光标或自定义光标的 HCURSOR 类型的唯一值。

若要为应用程序创建自定义光标,通常使用图形应用程序,并将光标作为资源包含在应用程序的资源定义文件中。 在运行时,调用 LoadCursor 以检索光标句柄。 光标资源包含多个不同显示设备的数据。 LoadCursor 函数会自动为当前显示设备选择最合适的数据。 使用 LoadCursorFromFile 函数直接从 .CUR or .ANI 文件加载光标。

还可以使用 CreateIconIndirect 函数在运行时创建自定义光标,该函数基于 ICONINFO 结构的内容创建光标。 GetIconInfo 函数使用有关关联掩码和颜色的热点坐标和信息填充此结构。

应用程序应实现自定义光标作为资源,并使用 LoadCursorLoadCursorFromFileLoadImage,而不是在运行时创建光标。 使用光标资源可以避免对设备的依赖,简化本地化,并使应用程序能够共享光标设计。

CreateIconFromResourceEx 函数使应用程序能够基于资源数据创建图标和光标。 CreateIconFromResourceEx 基于来自其他可执行文件 (.exe) 文件或 DLL 的二进制资源数据创建光标。 它之前必须调用 LookupIconIdFromDirectoryEx 函数以及多个资源函数。 LookupIconIdFromDirectoryEx 标识当前显示设备最合适的光标数据。 有关资源函数的详细信息,请参阅资源

光标位置和外观

系统会自动显示鼠标的光标,并更新其在屏幕上的位置。 可以分别使用 GetCursorPosSetCursorPos 函数获取光标的当前屏幕坐标,并将光标移动到屏幕上的任何位置。

还可以使用 GetCursor 函数检索当前光标的句柄,还可以使用 SetCursor 函数设置光标。 调用 SetCursor 后,光标的外观不会更改,直到鼠标移动、光标显式设置为其他光标或执行系统命令。

当用户移动鼠标时,系统会在新位置重新绘制光标。 系统会自动重新绘制与光标指向的窗口关联的光标设计。

可以使用 ShowCursor 函数隐藏和重新显示光标,而无需更改光标设计。 此函数使用内部计数器来确定何时隐藏或显示光标。 尝试显示光标会使计数器递增;试图隐藏光标会使计数器递减。 仅当此计数器大于或等于零时,光标才可见。

GetCursorInfo 函数获取全局光标的以下信息:光标是隐藏还是显示,光标的句柄以及光标的坐标。

光标限制

可以使用 ClipCursor 函数将光标限制为屏幕上的矩形区域。 当用户必须对矩形的受限区域内的某个事件做出响应时,这一点非常有用。 例如,可以使用 ClipCursor 将光标限制为模式对话框,从而阻止用户与其他窗口交互,直到对话框关闭。

GetClipCursor 函数检索光标暂时限制到的矩形区域的屏幕坐标。 如果需要限制光标,还可以使用此函数保存光标可以移动的原始区域的坐标。 然后,当不再需要新的限制时,可以将光标还原到原始区域。

光标销毁

可以销毁光标句柄,并释放通过调用 DestroyCursor 函数使用的光标的内存。 但是,此函数对共享光标没有影响。 只要加载共享光标的模块仍在内存中,共享光标就有效。 获取共享光标的函数如下:

如果不再需要使用 CreateIconIndirect 函数创建的光标,则应销毁光标。 DestroyIcon 函数销毁光标句柄并释放光标使用的任何内存。 仅在使用 CreateIconIndirect 创建的光标上使用此函数。

光标重复

CopyCursor 函数复制光标句柄。 这使应用程序或 DLL 代码能够检索另一个模块拥有的光标的句柄。 这样,如果另一个模块被释放,那么复制光标的模块仍然可以使用光标设计。

有关如何在可执行文件中添加、删除或替换光标资源的信息,请参阅资源

Window 类光标

使用 RegisterClass 函数注册窗口类时,可以为其分配一个默认光标,称为类光标。 应用程序注册窗口类后,该类的每个窗口都具有指定的类光标。

若要覆盖类光标,请处理 WM_SETCURSOR 消息。 还可以使用 SetClassLong 函数替换类光标。 此函数用于更改指定类的所有窗口的默认窗口设置。 有关详细信息,请参阅类光标