《Windows程序设计》学习笔记(chap10菜单及其它资源)(一)

一、自定义图标

1.MAKEINTRESOURCE宏

先摘抄MSDN的,定义如下:

The MAKEINTRESOURCE macro converts an integer value to a resource type compatible with the resource-management functions. This macro is used in place of a string containing the name of the resource.

Syntax

LPTSTR MAKEINTRESOURCE(

    WORD wInteger);

Parameters

 

wInteger
Specifies the integer value to be converted.

 

Return Value

The return value is the specified value in the low-order word and zero in the high-order word.

Remarks

The return value should be passed only to functions which explicitly indicate that they accept MAKEINTRESOURCE as a parameter. For example, the resource management functions allow the return value of MAKEINTRESOURCE to be passed as the lpType or lpName parameters.

Macro Information

Header

Declared in Winuser.h, include Windows.h

Minimum operating systems

Windows 95, Windows NT 3.1

Unicode

Implemented as ANSI and Unicode versions.

感觉就是把一个资源的ID号转换成可以识别的ID格式(据我个人翻译是低位为识别码,而高位为零),追踪定义如下:

第一部分:

#ifdef UNICODE

#define MAKEINTRESOURCE  MAKEINTRESOURCEW

#else

#define MAKEINTRESOURCE  MAKEINTRESOURCEA

第二部分:

#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))

#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))

 

很显然,就是一个类型强制转换,实际数值并没有改变。

  

2.LoadIcon Function

  

MSDN定义如下:

The LoadIcon function loads the specified icon resource from the executable (.exe) file associated with an application instance.

Note  This function hase been superseded(取代) by the LoadImage function.

//看来换新版的函数了,待会学习完了老版的再回头看看这个

Syntax

HICON LoadIcon(     

    HINSTANCE hInstance,     LPCTSTR lpIconName);

Parameters

 

hInstance
[in] Handle to an instance of the module whose executable file contains the icon to be loaded. This parameter must be NULL when a standard icon is being loaded.
lpIconName
[in] 

 

Pointer to a null-terminated string that contains the name of the icon resource to be loaded. Alternatively, this parameter can contain the resource identifier in the low-order word and zero in the high-order word. Use the MAKEINTRESOURCE macro to create this value.

To use one of the predefined icons, set the hInstance parameter to NULL and the lpIconName parameter to one of the following values.

 

IDI_APPLICATION
Default application icon.
IDI_ASTERISK
Same as IDI_INFORMATION.
IDI_ERROR
Hand-shaped icon.
IDI_EXCLAMATION
Same as IDI_WARNING.
IDI_HAND
Same as IDI_ERROR.
IDI_INFORMATION
Asterisk icon.
IDI_QUESTION
Question mark icon.
IDI_WARNING
Exclamation point icon.
IDI_WINLOGO
Windows logo icon. Windows XP: Default application icon.
IDI_SHIELD
Security Shield icon.

 

Return Value

If the function succeeds, the return value is a handle to the newly loaded icon.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

LoadIcon loads the icon resource only if it has not been loaded; otherwise, it retrieves a handle to the existing resource. The function searches the icon resource for the icon most appropriate for the current display. The icon resource can be a color or monochrome bitmap.

LoadIcon can only load an icon whose size conforms to the SM_CXICON and SM_CYICON system metric values. Use the LoadImage function to load icons of other sizes.

Windows 95/98/Me: LoadIconW is supported by the Microsoft Layer for Unicode (MSLU). To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems World Wide Web link.

Function Information

Minimum DLL Version

user32.dll

Header

Declared in Winuser.h, include Windows.h

Import library

User32.lib

Minimum operating systems

Windows 95, Windows NT 3.1

Unicode

Implemented as ANSI and Unicode versions.

很简单,就是通过图标的ID返回那个图标的句柄,然后就可以使用了。

  

3.有关加载自定义图标的示例程序,我所截取的自认为关键的代码片段:

/*------------------------------------------

  ICONDEMO.C -- Icon Demonstration Program

                 (c) Charles Petzold, 1998

  ------------------------------------------*/

……

wndclass.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;//这里获取图标"icondemo.ico"的句柄,直接在程序图标使用自定义的位图文件

……

case WM_CREATE :

      hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

      hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)); //又一次获取为下面的DrawIcon函数做准备

      cxIcon = GetSystemMetrics (SM_CXICON) ;

      cyIcon = GetSystemMetrics (SM_CYICON) ;

      return 0 ;

……

DrawIcon (hdc, x, y, hIcon); //使用上面获得的句柄画图

 

//"resource.h"

……

#define IDI_ICON                        101  //这里给的辨识的ID

……

/    "IconDemo.rc”

……

//

// Icon

//

// Icon with lowest ID value placed first to ensure application icon

// remains consistent on all systems.

IDI_ICON                ICON    DISCARDABLE     "icondemo.ico"  //真正和资源链接的描述还是在rc文件里哈~ 

 

……

  

这会产生问题。当Windows将32×32的图示缩小为16×16的图示时,必需减少图素的行和列。这样,对于某些比较复杂的图示,就会失真。因此,我们应该为那些图像缩小就会变形的图示建立特殊的16×16图素的图示。在Developer Studio中图标图像的上面是标识为「Device」的下拉式清单方块,在它的右边有一个按钮,按下该按钮会弹出「New Icon Image」对话框,此时选择「Small(16×16)」。现在您可以画另一个图示。如图10-2所示,画一个「S」(表示「小」)。

原来icon也可以有不同的版本啊~

LoadIcon的第二个参数带来了一个有趣的问题:图标的标识符能可以为字符串吗?答案是可以。方法如下:在 Developer Studio中,在ICONDEMO项目的文件列表上,选择 IDONDEMO.RC。您会看到顶端为「IconDemo Resource」的树状结构,然后是资源型态「Icon」,再下来是「IDI_ICON」。如果用鼠标右键单击图标标识符,并从菜单上选择「 Properties」,您就能改变ID。实际上,您可以把名称放在引号内将其更改为字符串。我用这种方法指定资源名称,并在本书的其它地方也使用该方法。

我喜欢为图示(以及一些其它资源)使用文字名称,因为名称可以是程序的名称。例如,假定文件被命名为MYPROG。如果您使用「Icon Properties」对话框将图标的ID指定为「MyProg」(包括引号),资源描述档将包含下列叙述:

MYPROG ICON DISCARDABLE myprog.ico

然而,在RESOURCE.H中并没有#define叙述,来指出MYPROG是数值标识符。资源描述文件将假定MYPROG是字符串标识符。

在C程序中,使用LoadIcon函数来取得图示句柄。您可能已经有了表示程序名的字符串:

static TCHAR szAppName [] = TEXT ("MyProg") ;

这意味着程序可以使用叙述:

hIcon = LoadIcon (hInstance, szAppName) ;

来加载图标,这比宏MAKEINTRESOURCE更清晰一些。

 

 

二、自定义光标

此处较为简单,基本就是LoadCursor这个函数,有时再用用SetCursor函数

只有这段话要注意:

如果使用了子窗口,那么您可能希望光标随着所在窗口的不同而有所区别。如果程序为这些子窗口定义了窗口类别,就可以在每个窗口类别中适当地设定hCursor字段,让每个窗口类别使用不同的光标。如果使用了预先定义的子窗口控件,就可以使用以下方法改变窗口类别的hCursor字段:

SetClassLong (hwndChild, GCL_HCURSOR,
        
    LoadCursor (hInstance, TEXT ("childcursor")) ;
        

如果您将显示区域划分为较小的逻辑区域而不使用子窗口,就可以使用SetCursor来改变鼠标光标:

SetCursor (hCursor) ;
        

在处理WM_MOUSEMOVE消息处理期间,您应该呼叫SetCursor;否则,当光标移动时,Windows将使用窗口类别中定义的光标来重画光标。文件指出,如果没有改变光标,则SetCursor速度将会很快。

 

三、字符串资源

个人感觉就是多国语言版的软件用的比较多(没做过,瞎猜猜的),值得注意的就这个:

您的程序可以使用LoadString呼叫把字符串复制到程序数据段的缓冲区中:

LoadString (hInstance, id, szBuffer, iMaxLength) ;
        

参数id是ID,它加在资源描述文件中每个字符串的前面;szBuffer是指向接收字符串的字符数组的指针;iMaxLength是送入szBuffer中的最大字符数。函数传回字符串中的字符数。

简单测试了一下,很好用,以后就可以做国际大产品了,呵呵(幻想了)

 

四、自定资源

!@#¥%……&*()——+,鸟东西,一点都不会,暂时也不会用,跳过……

呃……上一段话无效,貌似读取文本文件或者二进制文件这个还是有点用处的,自己稍微整理一下

事实上,LoadIcon和LoadCursor函数就用到了LoadResource和FindResource函数。  //居然这函数如此重要

hResource = LoadResource (hInstance, FindResource (hInstance, TEXT ("BINTYPE"), MAKEINTRESOURCE (IDR_BINTYPE1))) ;

恩恩,读取位图文件我也用到这个函数的(自己居然忘记了)

当您需要存取文字时,呼叫LockResource:

pData = LockResource (hResource) ; //应该是调用过程中防止该内存区域被修改
        

LockResource将资源加载内存(如果还没有加载的话),然后它会传回一个指向资源的指标。当结束对资源的使用时,您可以从内存中释放它:

FreeResource (hResource) ;      

当您的程序终止时,也会释放资源,即使您没有呼叫FreeResource.。

 

示例程序:

程序10-3 POEPOEM POEPOEM.C

/*---------------------------------------------------------------------------

POEPOEM.C -- Demonstrates Custom Resource

(c) Charles Petzold, 1998

----------------------------------------------------------------------------*/

具体的大家自己上网找吧。

POEPOEM.RC (摘录)
        
//Microsoft Developer Studio generated resource script.
        
#include "resource.h"
        
#include "afxres.h"
        
/
        
// TEXT
        
ANNABELLEE                                TEXT    DISCARDABLE     "poepoem.txt"
        

/
        
// Icon
        
POEPOEM                                  ICON    DISCARDABLE     "poepoem.ico"
        

/
        
// String Table
        
STRINGTABLE DISCARDABLE
        
BEGIN
        
   IDS_APPNAME         "PoePoem"
        
   IDS_CAPTION         """Annabel Lee"" by Edgar Allan Poe"
        
   IDS_ERRMSG              "This program requires Windows NT!"
        
END
        
RESOURCE.H (摘录)
        
// Microsoft Developer Studio generated include file.
        
// Used by PoePoem.rc
        
#define IDS_APPNAME   1
        
#define IDS_CAPTION   2
        
#define IDS_ERRMSG    3
 
五、菜单(怨念,俺想做俄罗斯方块的程序,刚开始就卡在菜单不会加载)
什么是菜单……用过电脑的都知道……除非你没用过图形界面的程序……
不扯了,好好看看怎么加载:

在程序中引用菜单

大多数Windows应用程序在资源描述文件中只有一个菜单。您可以给菜单起一个与程序名称相同的文字的名称。程序写作者经常将程序名用于菜单名称,以便相同的字符串可以用于窗口类别、程序的图标名称和菜单名称。然后,程序在窗口的定义中为菜单引用该名称:

wndclass.lpszMenuName = szAppName ;
        

虽然存取菜单资源的最常用方法是在窗口类别中指定菜单,您也可以使用其它方法。Windows应用程序可以使用LoadMenu函数将菜单资源加载内存中,如同LoadIcon和LoadCursor函数一样。LoadMenu传回一个菜单句柄。如果您在资源描述档中为菜单使用了名称,叙述如下:

hMenu = LoadMenu (hInstance, TEXT ("MyMenu")) ;
        

如果使用了数值,那么LoadMenu呼叫采用如下的形式:

hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (ID_MENU)) ;
        

然后,您可以将这个菜单句柄作为CreateWindow的第九个参数:

hwnd = CreateWindow (      TEXT ("MyClass"), TEXT ("Window Caption"),
        
   WS_OVERLAPPEDWINDOW,
        
   CW_USEDEFAULT, CW_USEDEFAULT,
        
   CW_USEDEFAULT, CW_USEDEFAULT,
        
   NULL, hMenu, hInstance, NULL) ;
        

在这种情况下,CreateWindow呼叫中指定的菜单可以覆盖窗口类别中指定的任何菜单。如果CreateWindow的第九个参数是NULL,那么您可以把窗口类别中的菜单看作是这种窗口类别的窗口内定使用的菜单。这样,您可以为依据同一窗口类别建立的几个窗口使用不同的菜单。

您也可以在窗口类别中指定NULL菜单,并且在CreateWindow呼叫中也指定NULL菜单,然后在窗口被建立后再给窗口指定一个菜单:

SetMenu (hwnd, hMenu) ;
        

这种形式使您可以动态地修改窗口的菜单。在本章后面的NOPOPUPS程序中我们将会看到这方面的例子。

当窗口被清除时,与窗口相关的所有菜单都将被清除。与窗口不相关的菜单在程序结束前通过呼叫DestroyMenu主动清除。

……看它叙述很简单么……当时我怎么加载不出来的……赶紧在我的代码里面找找

ERROR_RESOURCE_NAME_NOT_FOUND
1814

The specified resource name cannot be found in the image file.

 

怨念……准备吃晚饭,一个下午就学这么点……不管了,先发表了再说

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值