鼠标指针位图(Mouse Cursor Bitmap)是用于表示鼠标指针外观的图像。在 Windows 窗口编程中,可以使用自定义的鼠标指针位图来改变鼠标的外观,并提供更加个性化的用户体验。
■以下是一些与鼠标指针位图相关的要点:
●鼠标指针位图格式:
1.鼠标指针位图通常使用 .cur 或 .ani 扩展名。
2..cur 文件包含静态鼠标指针位图,而 .ani 文件可以包含动画鼠标指针位图。
●创建自定义鼠标指针位图:
1.可以使用图像编辑器(如 Adobe Photoshop、GIMP 等)创建或编辑鼠标指针位图。
2.鼠标指针位图的尺寸通常为 32x32 像素。
●加载和设置自定义鼠标指针位图:
1.使用 LoadCursorFromFile 函数从 .cur 或 .ani 文件中加载自定义鼠标指针位图。
2.使用 SetCursor 函数将自定义鼠标指针位图设置为当前鼠标指针。
下面是一个示例代码片段,展示了如何加载和设置自定义鼠标指针位图:
//加载自定义鼠标指针位图
HCURSOR hCursor = LoadCursorFromFile(L"custom_cursor.cur");
SetCursor(hCursor); // 设置为当前鼠标指针
在上述示例中,"custom_cursor.cur" 是自定义鼠标指针位图的文件路径。可以将自定义鼠标指针位图文件放置在应用程序的资源文件夹中,并提供正确的文件路径。
需要注意的是,自定义鼠标指针位图需要符合特定的格式要求,并且尺寸应为 32*32 像素。此外,还可以使用系统提供的内置鼠标指针位图,如 IDC_ARROW(箭头指针)、IDC_HAND(手指指针)等,通过使用系统定义的预定义鼠标指针常量来加载和设置。例如我们在实例ICONDEMO.C中的窗口类初始化时,添加的就是系统预定义的箭头指针。
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
■在程序中添加鼠标指针
在程序中使用自定义的鼠标指针类似于使用自定义图标,但大多数程序员发现 Windows提供的鼠标指针好像足够用了。自定义鼠标指针一般是单色的,大小为32X32 像素。在VS中创建鼠标指针和创建图标的方法一样(亦即从Insert菜单中选择 Resource,然后选择Cursor),但是不要忘了定义热点。
你可以使用如下语句在类定义中设置自定义鼠标指针:
wndclass.hCursor = LoadCursor (hlnstance, MAKEINTRESOURCE (IDC_CORSOR));
或者,如果是用文本名字来定义的鼠标指针:
wndclass.hCursor = LoadCursor (hlnstance, szCursor);
每当鼠标定位在基于此类创建的窗口上时,与IDC_CURSOR或szCursor相关联的自定义鼠标指针就会显示出来。
VS中新建或添加鼠标指针位图:
图9-6 添加鼠标指针位图
资源文件和资源视图:
图9-7 添加后的鼠标指针资源
【说明】鼠标指针的资源ID,同样可以使用文件名字符串(带引号的字符串)或者IDC_CURSOR1标识符或者数字来表示,对应的程序中鼠标指针位图加载的定义。
如果你使用了子窗口,则可能会想让鼠标指针随着它下面的子窗口的不同而变换它的 样子。如果你的程序对这些子窗口定义了窗口类,那么通过对每个窗口类设置适当的 hCursor字段,就可以对每个类使用不同的鼠标指针。而如果你使用了预定义的子窗口控件, 那么还可以使用如下语句来更改窗口类的hCursor字段:
SetClassLong (hwndChild, GCL_HCURSOR,
LoadCursor (hInstance, TEXT ("childcursor")) ;
如果你将客户区分割成小的逻辑区域而不是使用子窗口,那就可以使用SetCursor来改变鼠标指针:
SetCursor (hCursor);
你应该在处理WM_MOUSEMOVE消息时调用SetCursor函数。否则,当鼠标移动时, Windows会使用窗口类中指定的鼠标指针来重绘鼠标。官方文档指出,当鼠标指针无需更换时SetCursor会运行得很快。
9.1.4 字符串资源表
字符串资源表(String Table)是在 Windows 程序中用于存储本地化字符串的一种资源类型。它允许开发者将应用程序中使用的字符串集中管理,并便于在不同语言环境下进行本地化和国际化。
■以下是一些关于字符串资源表的要点:
●字符串资源表的结构:
1.字符串资源表是一个以零为基础索引的表格,其中每一行都包含一个字符串资源。
2.每个字符串资源由一个唯一的标识符(ID)和一个对应的字符串值组成。
●创建和编辑字符串资源表:
1.字符串资源表通常包含在应用程序的资源文件(.rc)中。
2.可以使用资源编辑器(如 Visual Studio 的资源视图)来创建和编辑字符串资源表。
3.在字符串资源表中,可以为每个语言定义不同的列,每一列对应一个语言的本地化字符串。
●引用字符串资源:
1.在代码中引用字符串资源时,可以使用资源标识符(ID)来获取对应的字符串。
2.使用 LoadString 函数或 LoadStringW 函数加载指定语言的字符串资源。
■下面是一个示例代码片段,展示了如何加载和使用字符串资源:
#include <Windows.h>
int main()
{
HINSTANCE hInstance = GetModuleHandle(NULL); // 获取当前实例句柄
WCHAR buffer[256];
LoadStringW(hInstance, IDS_HELLO, buffer, sizeof(buffer) / sizeof(buffer[0])); // 加载字符串资源
MessageBoxW(NULL, buffer, L"String Resource", MB_OK); // 显示字符串资源
return 0;
}
在上述示例中,IDS_HELLO 是字符串资源的标识符,在字符串资源表中定义了对应的文本。使用 LoadStringW 函数加载指定语言的字符串资源,并将其存储到缓冲区中。随后,可以使用缓冲区中的字符串进行后续的操作,例如在消息框中显示。
需要注意的是,字符串资源表可以包含多个语言的本地化字符串,在加载字符串资源时,可以根据需要指定语言来获取对应的字符串。同时,也可以使用不同的资源文件来存储不同语言的字符串资源,以便于管理和本地化。
在实际应用中,字符串资源表是一种重要的资源类型,用于管理应用程序中的文本和消息。通过使用字符串资源表,开发者可以轻松实现应用程序的本地化和国际化,以适应不同的语言和地区需求。
■VS 中添加字符串资源表
图9-8 添加字符串资源表
要创建字符串资源表,可以选中资源文件>添加>资源,选择添加String Table。字符串资源表将会被显示在屏幕右侧的列表里。双击一个字符串可以选中它。对每个字符串,都需要指定标识符和字符串本身。
在资源脚本里,字符串显示为类似于下面的多行语句:
STRINGTABLE DISCARDABLE
BEGIN
IDS_STRING1, "character string 1"
IDS_STRING2, "character string 2"
[其他字符串定义]
END
也可以使用文本编辑器在资源脚本文件中手工创建字符串表,也可以使用左右大括号来代替BEGIN 和END语句。
资源脚本可以有多个字符串表,但每个ID必须唯一地标识一个字符串。每个字符串只能有一行,最多可以有4097个字符。使用\t和\n来代表制表符和换行。在DrawText和 MessageBox中可以使用这些控制字符。
程序可以调用LoadString来复制字符串资源到程序数据区的缓存中:
LoadString (hlnstance, id, szBuffer, iMaxLength);
id参数代表资源脚本中每个字符串前面的ID号;
szBuffer是一个指向接受字符串的字符数组的指针;
iMaxLength是szBuffer可以接收的最大字符数。
此函数返回字符串中字符的数目。
每个字符串前面的字符串ID号通常是定义在头文件里的宏标识符。许多Windows程序员使用前缀IDS_来表示一个字符串的ID号。有时文件名或其他信息必须在显示字符串时嵌入到字符串里。这种情况下,你可以在字符串中加入C语言的格式设置字符并在 wsprintf中将它作为格式设置字符串。
所有资源文本,包括字符串表中的文本,都以Unicode格式保存在编译过的.RES资源文件以及最终的.EXE文件中。LoadStringW函数直接加载Unicode文本。LoadStringA函数则执行从Unicode到本地代码页的文本转换。
让我们来看一个函数例子,它使用三个字符串在消息框中显示三个错误信息。正如你 在下面看到的,RESOURCE.H头文件包含这些消息的三个标识符。
#define IDS_FILENOTFOUND 1
#define IDS_FILETOOBIG 2
#define IDS_FILEREADONLY 3
资源脚本含有如下字符串表:
STRINGTABLE
BEGIN
IDS_FILENOTFOUND, "File %s not found."
IDS_FILETOOBIG, "File %s too large to edit."
IDS_FILEREADONLY, "File %s is read-only."
END
C源代码文件也包含这个头文件,并且定义了一个函数来显示消息框。(假设szAppName是一个包含程序名字的全局变量。)
OkMessage (HWND hwnd, int iErrorNumber, TCHAR *szFileName)
{
TCHAR szFormat [40] ;
TCHAR szBuffer [60] ;
LoadString (hInst, iErrorNumber, szFormat, 40) ;
wsprintf (szBuffer, szFormat, szFilename) ;
return MessageBox (hwnd, szBuffer, szAppName,
MB_OK | MB_ICONEXCLAMATION) ;
}
为了显示含有"File not found"的消息框,程序可调用:
OkMessage (hwnd, IDS FILENOTFOUND. szFileNamR);