一、Windows的图标、光标、字符串和自订资源—将图标添加到程序
将资源添加到程序中需要Visual C++ Developer Studio的一些附加功能。对于图示来说,可以使用「Image Editor」(也称为「Graphics Editor」)来绘制图标的图像。该图像被储存在扩展名为.ICO的图示文件中。Developer Studio还产生一个资源描述档(扩展名为.RC的文件,有时也称作资源定义文件),它列出了程序的所有资源和一个让程序引用资源的表头文件(RESOURCE.H)。
因此,您可以看到这些新文件是如何组织在一起的,让我们以建立名为ICONDEMO的新项目开始。像往常一样,在Developer Studio中从File菜单中选择New,然后依次选择 项目页面标签和Win32 Application。在Project Name栏中键入ICONDEMO并单击OK。这时,Developer Studio建立了用于支持工作区和项目的五个文件。这些文件包括文本文件ICONDEMO.DSW、ICONDEMO.DSP和ICONDEMO.MAK(假设当您从 Tools菜单选择Open后,在显示的 Open对话框中,从Build页面标签中选中 Export makefile when saving project file)。现在,让我们像通常那样所做的建立C原始码文件。从 File菜单上选择New,选择Files页面标签,并单击 C++Source File。在File Name栏中键入ICONDEMO.C并单击OK。此时,Developer Studio就建立了一个空的ICONDEMO.C文件。键入程序10-1中的程序,或选择 Insert菜单,然后选择File As Text选项,从本书附上的光盘中复制原始码。
ICONDEMO.C /*-------------------------------------------------------------------------- ICONDEMO.C -- Icon Demonstration Program (c) Charles Petzold, 1998 --------------------------------------------------------------------------*/ #include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { TCHAR szAppName[] = TEXT ("IconDemo") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Icon Demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HICON hIcon ; static int cxIcon, cyIcon, cxClient, cyClient ; HDC hdc ; HINSTANCE hInstance ; PAINTSTRUCT ps ; int x, y ; switch (message) { case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ; cxIcon = GetSystemMetrics (SM_CXICON) ; cyIcon = GetSystemMetrics (SM_CYICON) ; return 0 ; case WM_SIZE : cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; for (y = 0 ; y < cyClient ; y += cyIcon) for (x = 0 ; x < cxClient ; x += cxIcon) DrawIcon (hdc, x, y, hIcon) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
如果您试着编译该程序,因为在程序开头引用的RESOURCE.H文件并不存在,所以会产生错误。然而,您不必直接建立RESOURCE.H文件,而是由Developer Studio为您建立一个。
您可以通过将资源描述档添加到项目中来做到这一点。从「File」菜单中选择「New」,选择「Files」页面标签,单击「Resource Script」,在「File Name」栏中键入「ICONDEMO」,单击OK。此时,Developer Studio会建立两个文本文件:ICONDEMO.RC(资源描述档)和RESOURCE.H(允许C原始码文件和资源描述档引用相同的已定义标识符)。不必直接编辑这两个档案,只要让Developer Studio来维护它们就可以。如果您想查看资源描述档和RESOURCE.H而不希望对Developer Studio产生干扰,可以用记事本打开它们。除非您对所做的动作很有把握,否则不要轻易地更改它们。请记住,只有在您下达明确的操作命令或重新编译项目时,Developer Studio才会储存这些文件的新版本。
资源描述档是文本文件。它包括这些资源的可用文字形式表达的描述,例如菜单和对话框。资源描述文件也包括对非文字资源的二进制档案的引用,例如图标和自订的鼠标光标。
现在,已经存在RESOURCE.H文件,您可以试着重新编译一下ICONDEMO。现在会出现一条错误消息,指出IDI_ICON还没被定义。这个标识符第一次出现在下面的叙述中:
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;
在本书前面的程序中,这个叙述是由下面的叙述代替的:
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
之所以改变叙述,是因为以前我们为应用程序使用的是标准的图示,而这里我们的目的是使用自订图示。
那么让我们建立一个图示吧!在Developer Studio的「File View」窗口中,您会看到两个文件-ICONDEMO.C和ICONDEMO.RC。您开启CONDEMO.C后,就可以编辑原始码。开启ICONDEMO.RC后,就可以把资源添加到文件中或编辑已存在的资源。要添加图示的话,请从「 Insert」菜单上选择「Resource」选择您想添加的资源,也就是图示,然后再按下「 New」按钮。
现在呈现的是一个空白的32×32图素的图示,您可以在其中填入颜色。您会看到带有一组绘图工具和可用颜色的浮动工具列。注意颜色工具列中包括两个与颜色无关的选项,这两种颜色选项有时被称为「屏幕颜色」跟「反屏幕颜色」。当一个图素在着色时选择了「屏幕颜色」时,它实际上是透明的。不管图标在什么表面上显示,图示未着色的部分会显示出底色。这样我们就可以建立非矩形的图示。
双击围绕图标的区域,会出现「Icon Properties」对话框,该对话框使您能够更改图标的ID和文件名称。Developer Studio可能已经将ID设定为IDI_ICON1,将它改为IDI_ICON,这样ICONDEMO就可以引用图标(前缀IDI代表「图标的ID」)。同样地,将文件名改为ICONDEMO.ICO。
现在选择一种有特色的颜色(如红色)并在图示上画一个大的B(代表BIG),请注意不必像图10-1那么整齐。
图10-1 显示在Developer Studio中的标准(32×32)ICONDEMO文件 |
此时程序应该能够编译并执行得很好了。Developer Studio将在ICONDEMO.RC资源描述档中划一条横线,表示下面是带有标识符(IDI_ICON)的图示文件(ICONDEMO.ICO)。RESOURCE.H表头文件中会包含IDI_ICON标识符的定义。
Developer Studio通过资源编译器RC.EXE编译资源。文字资源描述文件被转化为二进制形式,也就是具有扩展名.RES的文件。然后,该已编译的资源文件随同.OBJ和.LIB文件一起在LINK步骤中被指定连结。这就是资源被添加到最后产生出来的.EXE文件中的方式。
当您执行ICONDEMO时,程序图标显示在标题列的左上角和工作列中。如果您将程序添加到「开始」菜单中,或在桌面上放置快捷方式,您也会在那儿看到该图示。
ICONDEMO也在显示区域水平和垂直地重复显示该图示。程序使用叙述
hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;
取得图示的句柄。使用叙述
cxIcon = GetSystemMetrics (SM_CXICON) ; cyIcon = GetSystemMetrics (SM_CYICON) ;
取得图示的大小。然后,程序通过多次呼叫
DrawIcon (hdc, x, y, hIcon) ;
显示图标,其中x和y是被显示图示其左上角的坐标。
在目前使用的大多数视讯显示卡上,带有SM_CXICON和SM_CYICON索引的GetSystemMetrics会回报图示的大小为32×32图素。这是我们在Developer Studio中建立的图示大小,它也是图示出现在桌面上和显示在ICONDEMO程序显示区域的大小。然而,这个大小并非显示在程序的标题列或工作列中的图示大小。小图示的大小可以由带有SM_CXSMSIZE和SM_CYSMSIZE索引的GetSystemMetrics获得(第一个SM表示「system metrics(系统度量)」,被包含的SM表示「small(小)」)。对于目前使用的大多数显示卡来说,小图示的大小为16×16图素。
这会产生问题。当Windows将32×32的图示缩小为16×16的图示时,必需减少图素的行和列。这样,对于某些比较复杂的图示,就会失真。因此,我们应该为那些图像缩小就会变形的图示建立特殊的16×16图素的图示。在Developer Studio中图标图像的上面是标识为「Device」的下拉式清单方块,在它的右边有一个按钮,按下该按钮会弹出「New Icon Image」对话框,此时选择「Small(16×16)」。现在您可以画另一个图示。如图10-2所示,画一个「S」(表示「小」)。
图10-2 在Developer Studio中显示的小(16×16)ICONDEMO文件 |
在该程序中您不必做任何事情。第二个图标图像被储存在相同的ICONDEMO.ICO文件中,并以相同的IDI_ICON标识符引用。在适当的时候,Windows会自动使用该较小的图示,例如在标题列或工作列中。当在桌面上显示快捷方式,以及程序呼叫DrawIcon装饰显示区域时,Windows会使用大图示。
在掌握这些知识之后,让我们看一看使用图示的详细情况。