按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
invoke lstrcat;addr @szTextBuff;addr szReturn
invoke lstrcat;addr @szTextBuff;addr @szBuffer1
dec @dwCount
。endw
invoke MessageBox;hWnd;addr @szTextBuff;addr szTitle;MB_OK
。elseif ax IDC_RESET
invoke SendDlgItemMessage;hWnd;IDC_LISTBOX2;LB_SETSEL;FALSE;…1
。elseif ax IDC_LISTBOX1
shr eax;16
。if ax LBN_SELCHANGE
;********************************************************************
; 将鼠标点击结果显示在文本框中
;********************************************************************
invoke SendMessage;lParam;LB_GETCURSEL;0;0
lea ecx;@szBuffer
invoke SendMessage;lParam;LB_GETTEXT;eax;ecx
invoke SetDlgItemText;hWnd;IDC_SEL1;addr @szBuffer
;********************************************************************
; 双击项目则弹出对话框
;********************************************************************
。elseif ax LBN_DBLCLK
invoke SendMessage;lParam;LB_GETCURSEL;0;0
lea ecx;@szBuffer
invoke SendMessage;lParam;LB_GETTEXT;eax;ecx
invoke wsprintf;addr @szBuffer1;addr szMessage;addr @szBuffer
invoke MessageBox;hWnd;addr @szBuffer1;addr szTitle;MB_OK
。endif
;********************************************************************
。elseif ax IDC_LISTBOX2
shr eax;16
。if ax LBN_SELCHANGE
invoke SendMessage;lParam;LB_GETSELCOUNT;0;0
mov ebx;eax
invoke GetDlgItem;hWnd;IDOK
invoke EnableWindow;eax;ebx
。endif
。endif
;********************************************************************
; 恢复代码缩进格式,请读者注意
;********************************************************************
。else
mov eax;FALSE
ret
。endif0
mov eax;TRUE
ret
_ProcDlgMain endp
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
start:
invoke GetModuleHandle;NULL
mov hInstance;eax
invoke DialogBoxParam;hInstance;
DLG_MAIN;NULL;offset _ProcDlgMain;NULL
invoke ExitProcess;NULL
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
end start
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第5章 使用资源
5。4 对 话 框(11)
下面结合源程序来说明列表框的使用。当列表框有LBS_NOTIFY风格的时候,用户有所动作时列表框会向父窗口发送WM_MAND消息,同时在wParam的高16位中指定通知码,列表框的通知码种类很少,基本上就是以下几种:
● LBN_DBLCLK 用户双击了一个项目。
● LBN_ERRSPACE 插入项目时无法申请到足够的内存。
● LBN_KILLFOCUS 输入焦点被切换到其他控件中,列表框丢失了焦点。
● LBN_SELCANCEL 用户撤销了一个选择。
● LBN_SELCHANGE 选定状态改变。
● LBN_SETFOCUS 列表框得到输入焦点。
我们最关心的是LBN_DBLCLK和LBN_SELCHANGE通知码,在单选列表框中,如果程序用双击来选择项目,那么就要处理LBN_DBLCLK通知,例子程序中当用户双击IDC_LISTBOX1时弹出一个消息框,读者可以查看其使用方法。在多选列表框中,由于用户可能选择了多个项目,所以一般不用双击的方法选定;如果收到LBN_SELCHANGE通知的话,可以得知用户有一个选择动作,在这里可以进行相应的操作。
列表框通知父窗口是通过发送WM_MAND消息,而程序控制列表框的时候是通过向列表框发送消息来完成的,常用的列表框消息如表5。8所示。
表5。8 列表框消息
消 息
wParam
lParam
说 明
LB_ADDSTRING
0
字符串地址
添加一个项目,返回加入后的索引
LB_DELETESTRING
位置索引
0
删除一个项目,返回剩余的项数
LB_FINDSTRING
开始索引
字符串地址
查找以字符串开头的项目,找到则返回位置索引,未找到则返回LB_ERR
LB_FINDSTRINGEXACT
开始索引
字符串地址
精确查找一个项目,返回值同上
LB_GETANCHORINDEX
0
0
返回多选列表框多选时的起始位置
LB_GETCARETINDEX
0
0
多选列表框中的当前焦点项目位置
LB_GETCOUNT
0
0
返回列表框中的项目总数
LB_GETCURSEL
0
0
返回单选列表框当前选中的项目
LB_GETSEL
位置索引
0
检测指定项目的选中状态,返回非0为选中,返回0为未选中
LB_GETSELCOUNT
0
0
返回多选列表框选中项目的总数
LB_GETSELITEMS
最大项数
缓冲区地址
返回多选列表框的选中项目索引列表到缓冲区中
LB_GETTEXT
位置索引
缓冲区地址
返回某个项目的字符串
LB_GETTEXTLEN
位置索引
0
返回某个项目的字符串长度
LB_GETTOPINDEX
0
0
返回当前可见的第一个项目位置
LB_INSERTSTRING
插入位置
字符串地址
在指定位置插入一个项目
LB_RESETCONTENT
0
0
删除所有项目
LB_SELECTSTRING
开始位置
字符串地址
将以指定字符串开头的项目选中
LB_SELITEMRANGE
选择状态
范围
在多选框中将一个范围选中或清除
LB_SETCURSEL
位置索引
0
在单选列表框中选中一个项目
LB_SETSEL
选择状态
位置索引
在多选框中将一个项目选中或清除
LB_SETTOPINDEX
位置索引
0
滚动显示到指定的项目
LB_DIR
属性
文件通配符
搜索目录并将符合文件通配符的文件名加入到列表框中
这些消息中LB_DIR是个比较有趣的消息,它可以将指定目录中的文件名自动列出来并加入列表框中,如例子中用*。*将当前目录的全部文件名加到列表框中。LB_DIR消息中wParam参数可以指定的属性可以是以下值的组合:
DDL_ARCHIVE 加入归档属性的文件。
DDL_DIRECTORY 加入目录。
DDL_DRIVES 加入驱动器名。
DDL_HIDDEN 包含隐含文件。
DDL_READONLY 包含只读文件。
DDL_READWRITE 包含可读写的文件。
DDL_SYSTEM 包含系统文件。
在列表框中初始化时加入项目可以使用LB_ADDSTRING和LB_INSERTSTRING消息,删除项目可以用LB_DELETESTRING消息,删除全部项目用LB_RESETCONTENT消息。
对于单选列表框,要获取选中项目可以发送LB_GETCURSEL消息,要得到这个项目的字符串需要再用索引值通过LB_GETTEXT消息获取,读者可以查看例子中处理LBN_DBLCLK通知码的部分代码。
对于多选列表框,需要用LB_GETSELITEMS消息获取全部选中项目,这个消息返回的是一个列表,所有选中项目的索引按顺序排列返回到缓冲区中,所以在例子中处理“查看”按钮消息(IDOK)的时候,程序先发送LB_GETSELCOUNT消息得到选中的项目数,以便在下面用一个循环获取所有的项目,得到项目数后,再用LB_GETSELITEMS将选中项目的索引取到@szBuffer中,接下来进入一个循环,循环的次数就是LB_GETSELCOUNT得到的数值,在循环中,程序从@szBuffer中将索引值逐个取出并用LB_GETTEXT消息获取每一项的字符串,最后用一个MessageBox显示出来。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第5章 使用资源
5。5 字符串资源/5。6 版本信息资源(1)
程序中用到的字符串常常定义在 nst段中,但Windows也提供了另外一种使用字符串常量的方法,那就是在资源中定义。虽然在资源中定义字符串使用起来比直接在 nst段中定义要复杂一点,但它带来的好处是便于开发不同语言的版本,比如,要推出其他语种的版本只需要修改资源中的字符串表就可以了,即使语言转换的工作是由第三者通过修改可执行文件来做的(如编程爱好者常常做的汉化工作),修改资源也远比修改代码来得快捷和安全。
在资源脚本中定义字符串的语法是:
STRINGTABLE 'DISCARDABLE'
BEGIN
字符串ID1 〃字符串1〃
字符串ID2 〃字符串2〃
。 。 。
END
全部字符串组成一个字符串表,和其他资源定义不同,由于整个资源文件中只能定义一个字符串表,所以字符串表没有资源ID,但是表中的不同字符串分别有一个字符串ID。
在程序中使用字符串资源也很简单,用LoadString把字符串装入到缓冲区中去就可以用了:
invoke LoadString,hInstance,字符串ID,addr 缓冲区,sizeof 缓冲区
为了防止溢出,最后一个参数指定缓冲区的长度。
如果要在单个可执行文件中实现多语种,那么可以在字符串表中定义不同语言的字符串。同一语种的字符串按规律排列,如下列中文的以1000开头,英文的以2000开头:
stringtable
{
1001 〃文件未找到!〃
1002 〃无法打开文件!〃
。。。
2001 〃File not found!〃
2002 〃Can not open file!〃
。。。
}
在程序中使用的时候,先确定一种语言并预先设置在dwLanguage变量中,使用中文时将dwLanguage设置为1000,使用英文时设置为2000,再写一个读取不同版本字符串的子程序_GetString,这样调用_GetString子程序后就不用考虑版本问题了:
_GetString proc _dwID;_lpBuffer;_dwSize
pushad
mov eax;_dwID
add eax;dwLanguage
invoke LoadString;hInstance;eax;_lpBuffer;_dwSize
popad
ret
_GetString endp
5。6 版本信息资源
有时应用程序需要确保自己运行时使用某一特定版本的DLL,以便确保可以使用某些函数。检测版本是通过API函数查询定义于资源中的版本信息来完成的,如果资源中没有定义版本,那么就无法知道一个文件的版本究竟是多少。
版本信息是以VERSIONINFO类型的资源保存在应用程序中的,里面可以定义的信息包括文件的版本号、创建单位和语种等。版本信息的定义是可选的,一个程序可以不定义版本信息资源,如果定义了的话,也不一定要定义全部信息项目。
如果一个文件定义有版本信息资源,那么在文件的属性页(在文件图标上按鼠标右键,在弹出的菜单上选择)上就会有一个“版本”页面,如图5。10所示。
图5。10 文件属性中的版本信息
5。6。1 版本信息资源的定义
在所附光盘的Chapter05VersionInfo目录中有一个例子,在该目录的Version。rc文件中定义了一个版本信息,读者可以看编译后的VersionInfo。exe中的“版本”属性页,对比一下资源定义中的内容究竟出现在属性页的哪些地方,定义的代码如下:
1 VERSIONINFO
FILEVERSION 1;2;3;4
PRODUCTVERSION 2;3;4;5
FILEOS VOS_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK 〃VarFileInfo〃
BEGIN
VALUE 〃Translation〃; Ox804; Ox4b0
END
BLOCK 〃StringFileInfo〃
BEGIN
BLOCK 〃080404b0〃
BEGIN
VALUE 〃ments〃; 〃Here is ments0〃
VALUE 〃panyName〃; 〃Here is panyName0〃
VALUE 〃FileDescription〃; 〃Here is FileDescription0〃
VALUE 〃FileVersion〃; 〃1; 0; 0; 10〃
VALUE 〃InternalName〃; 〃Here is InternalName0〃
VALUE 〃LegalCopyright〃; 〃Here is LegalCopyright0〃
VALUE 〃LegalTrademarks〃; 〃Here is LegalTrademarks0〃
VALUE 〃OriginalFilename〃; 〃Here is OriginalFilename0〃
VALUE 〃PrivateBuild〃; 〃Here is PrivateBuild0〃
VALUE 〃ProductName〃; 〃Here is ProductName0〃
VALUE 〃ProductVersion〃; 〃1; 0; 0; 10〃
VALUE 〃SpecialBuild〃; 〃Here is SpecialBuild0〃
END
END
END
现在来看这些定义语句的含义。首先,版本信息定义的语句格式是:
版本信息资源ID VERSIONINFO
固定属性
BEGIN
块声明定义
……
END
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第5章 使用资源
5。6 版本信息资源(2)
版本信息资源ID的取值必须为1,如果不为1则属性页上的“版本”信息是无法显示出来的。(笔者也不明白为什么必须为1还要定义这个ID,像stringtable一样没有ID不就完事了?)
可以定义的固定属性有:
● FILEVERSION——定义文件版本号,可以定义4个16位版本号xx。xx。xx。xx。
● PRODUCTVERSION——定义产品版本号,可以定义4个16位版本号xx。xx。xx。xx。
● FILEFLAGSMASK——指定FILEFLAGS属性中哪些位有效。
● FILEFLAGS—文件标志,是一些标志位的组合:VS_FF_PATCHED,VS_FF_DEBUG,VS_FF_PRIVATEBUILD,VS_FF_INFOINFERRED,VS_FF_PRERELEASE和VS_FF_SPECI… ALBUILD。
● FILEOS—定义适用的操作系统,可以定义为VOS_UNKNOWN,VOS_DOS,VOS_NT,VOS_WINDOWS16,VOS_WINDOWS32,VOS_DOS_WINDOWS16,VOS_DOS_WINDOWS32 或VOS_NT_WINDOWS32。
● FILETYPE—定义文件类型,可以是VFT_UNKNOWN,VFT_APP,VFT_DLL,VFT_ DRV,VFT_FONT,VFT_VXD或VFT_STATIC_LIB。
● FILESUBTYPE——定义文件的子类型。当文件类型是VFT_DRV(驱动程序)的时候,这里可以是VFT2_UNKNOWN,VFT2_DRV_M,VFT2_DRV_PRINTER,VFT2_DRV_ KEYBOARD,VFT2_DRV_LANGUAGE,VFT2_DRV_DISPLAY,VFT2_DRV_MOUSE,VFT2_DRV_NETWORK,VFT2_DRV_SYSTEM,VFT2_DRV_INSTALLABLE或VFT2_ DRV_SOUND;当文件类型是VFT_FONT(字体)的时候,这里可以是VFT2_UNKNOWN,VFT2_FONT_RASTER,VFT2_FONT_VECTOR或VFT2_FONT_TRUETYPE。
在固定属性定义完成以后,需要定义一些块声明,块声明有两种:变量型的信息块和字符串类型的信息块,变量类型的信息块定义如下:
BLOCK 〃VarFileInfo〃
BEGIN