WIN32汇编语言教程:第15章 注册表和INI文件 · 15.2 INI文件的操作(3)
invoke GetWindowRect,hWinMain,addr @szRect
invoke wsprintf,addr @szBuffer,addr szFmt1,@szRect.left
invoke WritePrivateProfileString,addr szSecPos,addr szKeyX,\
addr @szBuffer,addr szProfileName
invoke wsprintf,addr @szBuffer,addr szFmt1,@szRect.top
invoke WritePrivateProfileString,addr szSecPos,addr szKeyY,\
addr @szBuffer,addr szProfileName
ret
_SavePosition endp
;####################################################################
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @szSection[256]:byte
local @szKey[256]:byte
local @szValue[256]:byte
local @szBuffer[256]:byte
mov eax,wMsg
;********************************************************************
.if eax == WM_CLOSE
invoke _SavePosition
invoke EndDialog,hWnd,NULL
;********************************************************************
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
invoke _GetPosition
invoke _EnumINI
;********************************************************************
.elseif eax == WM_COMMAND
invoke GetDlgItemText,hWnd,IDC_SEC,addr @szSection,sizeof @szSection
invoke GetDlgItemText,hWnd,IDC_KEY,addr @szKey,sizeof @szKey
invoke GetDlgItemText,hWnd,IDC_VALUE,addr @szValue,sizeof @szValue
mov eax,wParam
.if ax >= IDC_SEC && ax <= IDC_INI
mov eax,TRUE
ret
.elseif ax == IDC_DEL_SEC
invoke WritePrivateProfileString,addr @szSection,\
NULL,NULL,addr szProfileName
.elseif ax == IDC_DEL_KEY
invoke WritePrivateProfileString,addr @szSection,\
addr @szKey,NULL,addr szProfileName
.elseif ax == IDC_SET_KEY
invoke WritePrivateProfileString,addr @szSection,\
addr @szKey,addr @szValue,addr szProfileName
.elseif ax == IDC_GET_KEY
invoke GetPrivateProfileString,addr @szSection,\
addr @szKey,NULL,addr @szBuffer,\
sizeof @szBuffer,addr szProfileName
invoke SetDlgItemText,hWnd,IDC_VALUE,addr @szBuffer
.endif
invoke _EnumINI
;********************************************************************
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;####################################################################
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,eax,DLG_MAIN,NULL,\
offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;####################################################################
end start
在对话框关闭的时候,程序在WM_CLOSE函数中调用_SavePosition子程序将对话框窗口当前的位置保存到INI文件中,以便在下一次运行的时候恢复原来的窗口位置。程序在WM_INITDIALOG中调用_GetPosition子程序以恢复上一次保存的位置,这样,程序就可以“记住”窗口的摆放位置。
枚举小节和键值的功能是在_EnumINI子程序中完成的。程序在一开始执行的时候或者在每次收到WM_COMMAND消息的时候都调用这个函数,所以每次用户有所操作,INI文件的变化就会马上在窗口中的编辑框中反映出来。
1. 键值的创建和删除
当按下“保存Key”按钮时,例子程序使用WritePrivateProfileString函数保存键值,这个函数可以往指定的INI文件中写入键值,函数的用法是:
invoke WritePrivateProfileString,lpAppName,lpKeyName,\
lpString,lpFileName
在函数的参数中,lpAppName参数指向包含Section名称的字符串,lpKeyName参数指向包含键名称的字符串,lpString参数指向键值字符串,最后一个参数指向INI文件名字符串。这些字符串都是以0字符结束的。
当这些参数全部指定为字符串的时候,函数将在指定INI文件的指定小节中写入“键名=键值”格式的行;当指定的INI文件、文件中的小节和小节中的键名都已经存在的时候,函数用新键值替换原来的键值;当指定的INI文件存在而小节不存在的时候,函数自动创建小节并将键写入;如果连指定的INI文件也不存在的话,函数会自动创建文件。总之,程序不必考虑INI文件是否存在,小节是否存在或键值定义是否存在等情况,只要调用WritePrivateProfileString函数就可以保证配置信息被正确保存。
WritePrivateProfileString函数也可以用来删除键或者小节,当lpAppName和lpKeyName参数指定了小节名称和键名,而lpString参数指定为NULL的时候,函数将指定的键删除,如例子文件中对“删除Key”按钮的操作就是这样的:
.elseif ax == IDC_DEL_KEY
invoke WritePrivateProfileString,addr @szSection,\
addr @szKey,NULL,addr szProfileName
但是使用这种方法逐一将某个小节中的键全部删除时,空白小节的定义字符串“[SectionName]”还保留在INI文件中。如果想要将小节的定义字符串连同小节的全部键定义全部删除的话,可以将lpKeyName和lpString参数全部指定为NULL,而lpAppName参数指定要删除的小节,如例子文件中对“删除Section”按钮的处理代码:
.elseif ax == IDC_DEL_SEC
invoke WritePrivateProfileString,addr @szSection,\
NULL,NULL,addr szProfileName
如果函数执行成功,将返回一个非0的值,如果执行失败将返回0。在定义键名的时候,注意不用在名称字符串中包括“=”号,因为等号被用来分隔键名和键值,键名也不能以注释字符“;”开始。在定义键值的时候可以使用等号和分号,但注意不要将键值定义为多行的文本。如果在字符串中包含换行和回车,比如将键值字符串指向下列所示的一个串:
“hello,world!”,0dh,0ah,“this is the second line”,0
那么函数会成功地被调用,但是最后的INI文件中会出现这样的内容:
[Section]
Key=hello,world!
this is the second line
显然,函数不加判断地将换行和回车也写到了INI文件中,但是当取回键值的时候,只有第一行能被正确取回,而底下的行将当做格式错误的“垃圾”留在INI文件中。
由于INI文件是以文本方式保存的,所以实际上键值也只能用字符串方式表示,如果需要保存一个数值类型的值,那么程序需要自己使用wsprintf函数将数值转换成字符串后再保存。比如例子程序在退出时为保存窗口位置,就是在_SavePosition子程序中首先用GetWindowRect函数获取窗口位置,然后使用wsprintf函数转换后再保存的。
上页:第15章 注册表和INI文件 · 15.2 INI文件的操作(2) 下页:第15章 注册表和INI文件 · 15.2 INI文件的操作(4)