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)

第15章 注册表和INI文件

版权所有 © 中山市飞娥软件工作室 证书:粤ICP备09170368号