标题:升级inifile配置文件类,纯VFP代码
只看楼主
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
结帖率:97.44%
已结贴  问题点数:20 回复次数:2 
升级inifile配置文件类,纯VFP代码
inifile.zip (23.25 KB)
重新写了一遍配置文件类,用集合替换原来的数组,欢迎大家试错。

奉上源代码。
程序代码:
**************************************************
*-- Class Library:  d:\documents\visual foxpro 项目\inifile.vcx
**************************************************


**************************************************
*-- Class:        inifile (d:\documents\visual foxpro 项目\inifile.vcx)
*-- ParentClass:  custom
*-- BaseClass:    custom
*-- Time Stamp:   01/28/22 08:15:06 PM
*
DEFINE CLASS inifile AS custom


    Height = 61
    Width = 68
    *-- 保存新建或打开的ini文件名
    filename = ""
    *-- 保存新建ini文件的句柄。
    fhandle = 0
    *-- 保存ini文件的所有section对象的集合
    sections = .NULL.
    Name = "inifile"


    *-- 申明DLL函数
    PROCEDURE declaredlls
        *VB申明原型:;
        Public Declare Function GetPrivateProfileString;
        Lib "kernel32" Alias "GetPrivateProfileStringA" ;
        (ByVal lpApplicationName As String,;
        ByVal lpKeyName As Any, ;
        ByVal lpDefault As String, ;
        ByVal lpReturnedString As String, ;
        ByVal nSize As Long, ;
        ByVal lpFileName As String) As Long;
        读取INI文件指定块中的键名对应的字符串。
        Declare integer GetPrivateProfileString in win32api;
        String csection, ;
        string ckey, ;
        String cdefaultreturn, ;
        String cbuffer, ;
        integer nbuffersize, ;
        String cfile
          
        *VB申明原型:;
        Public Declare Function GetPrivateProfileSection ;
        Lib "kernel32" Alias "GetPrivateProfileSectionA" ;
        (ByVal lpAppName As String, ;
        ByVal lpReturnedString As String, ;
        ByVal nSize As Long, ;
        ByVal lpFileName As String) As Long;
        记取INI文件指定块中的所有键名及其对应值。
        DECLARE integer GetPrivateProfileSection in win32api;
        String csection, ;
        String cbuffer, ;
        integer nbuffersize, ; 
        String cfile 

        *VB申明原型:;
        Private Declare Function GetPrivateProfileSectionNames;
        Lib "kernel32" Alias "GetPrivateProfileSectionNamesA" _;
        (ByVal lpszReturnBuffer As String, ;
        ByVal nSize As Long, ;
        ByVal lpFileName As String) As Long;
        读取一INI文件中所有的块名。
        Declare integer GetPrivateProfileSectionNames in win32api;
        String cbuffer, ;
        integer nsize, ; 
        String cfile 

        *VB申明原型:;
        Public Declare Function WritePrivateProfileString ;
        Lib "kernel32" Alias "WritePrivateProfileStringA" ;
        (ByVal lpApplicationName As String, ;
        ByVal lpKeyName As Any, ;
        ByVal lpString As Any, ;
        ByVal lpFileName As String) As Long
        DECLARE integer WritePrivateProfileString in win32api;
        string csection,;
        string ckey,;
        string cstring,; &&null值则删除此key
        string cfile

        *VB申明原型:;
        Public Declare Function WritePrivateProfileSection ;
        Lib "kernel32" Alias "WritePrivateProfileSectionA" ;
        (ByVal lpAppName As String, ;
        ByVal lpString As String, ;
        ByVal lpFileName As String) As Long
        DECLARE integer WritePrivateProfileSection in win32api;
        string csection,;
        string cstring,;&&用chr(0)间隔的字符串组,null值则删除此section
        string cfile
    ENDPROC


    *-- 建立一个ini文件
    PROCEDURE create
        PARAMETERS lcfilename
        IF PARAMETERS()=0
            lcfilename=PUTFILE('','myinifile1','ini')
        ENDIF
        IF lcfilename==''
            RETURN .f.
        ELSE
            this.fhandle=FCREATE(lcfilename,0)
            FCLOSE(this.fhandle)
            this.filename=lcfilename
            RETURN .t.
        ENDIF

    ENDPROC


    *-- 向ini文件写入一个section,如果指定的section不存在则新建一个section。
    PROCEDURE writesection
        *VB申明原型:;
        Public Declare Function WritePrivateProfileString ;
        Lib "kernel32" Alias "WritePrivateProfileStringA" ;
        (ByVal lpApplicationName As String, ;
        ByVal lpKeyName As Any, ;
        ByVal lpString As Any, ;
        ByVal lpFileName As String) As Long;
        DECLARE integer WritePrivateProfileString in win32api;
        string csection,;
        string ckey,;
        string cstring,; &&null值则删除此key;
        string cfile
        PARAMETERS lcsection,lckey,lcstring
        IF this.filename==""
            RETURN .f. 
        ENDIF
        IF PARAMETERS()=0
            Lcparameter=INPUTBOX("请设置section名,key名,以及key值,用斜杠/分割","新建或写入一个section小节")
            IF EMPTY(lcparameter)
                RETURN .f.
            ENDIF
            lcsection=LEFT(ALLTRIM(lcparameter),AT("/",ALLTRIM(lcparameter),1)-1)

            lckey=SUBSTR(ALLTRIM(lcparameter), AT("/",ALLTRIM(lcparameter),1)+1, (AT("/",ALLTRIM(lcparameter),2)-AT("/",ALLTRIM(lcparameter),1)-1))

            lcstring=RIGHT(ALLTRIM(lcparameter),(LEN(ALLTRIM(lcparameter))-AT("/",ALLTRIM(lcparameter),2)))
        ENDIF

        writeprivateprofilestring(lcsection,lckey,lcstring,this.filename)

        cexact=SET("exact")
        SET EXACT ON 
        *************2022/01/28用集合替代数组****************************;
        nfound=ASCAN(this.sections,lcsection);
        IF nfound=0;
            IF TYPE('this.sections[1]')<>"O";
                nlen=1;
            else    ;
                nlen=ALEN(this.sections)+1;
                DIMENSION this.sections[nlen];
            ENDIF     ;
            this.sections[nlen]=CREATEOBJECT("section");
            this.sections[nlen].name=lcsection;
            this.sections[nlen].writekey("lckey",'lcstring');
            this.sections[nlen].loadsection(lcsection);
            this.sections[nlen].filename=this.filename;
        ENDIF
        lexist=.f.
        FOR t=1 TO this.sections.count
            IF this.sections(t).name==ALLTRIM(lcsection)
                this.sections(t).writekey("lckey",'lcstring')
                lexist=.t.
                EXIT
            ENDIF
        ENDFOR

        IF lexist=.f.
            this.sections.add(CREATEOBJECT("section"))
            m=this.sections.count
            this.sections(m).name=ALLTRIM(lcsection)
            this.sections(m).writekey("lckey",'lcstring')
            this.sections(m).filename=this.filename
        ENDIF
        SET EXACT &cexact

        RELEASE lcparameter,lcsection,lckey,lcstring,cexact,lexist,m

        *************2022/01/28用集合替代数组****************************

        RETURN .t.

    ENDPROC


    *-- 导入ini文件
    PROCEDURE loadfile
        PARAMETERS lcinifile
        IF PARAMETERS()=0
            lcinifile=GETFILE('ini','选择ini文件','选择',0,'请选择要打开的ini文件')
            IF EMPTY(lcinifile)
                RETURN .f.
            ENDIF
            this.filename=lcinifile
        ENDIF

        lcbuffer=repli(CHR(0),255)
        lnsize=getprivateprofilesectionnames(@lcbuffer,255,lcinifile)
        *************导入一个空的ini文件时,系统报错*********************
        IF lnsize=0
            RETURN .f.
        ENDIF
        *************2021/10/15加入这段排错******************************
        *************2022/01/28用集合替代数组****************************
        lcbuffer=SUBSTR(lcbuffer,1,lnsize)
        lnarray=OCCURS(CHR(0),lcbuffer)
        DIMENSION laposition[lnarray]
        *DIMENSION this.sections[lnarray]
        FOR j=1 TO lnarray
            laposition[j]=AT(CHR(0),lcbuffer,j)
            n=IIF(j>1,laposition[j-1]+1,1)
            csection="section"+ALLTRIM(STR(J))
            &csection=CREATEOBJECT("section")
            this.sections.add(&csection,csection)
            this.sections.item(csection).name=SUBSTR(lcbuffer,n,laposition[j]-n)
            this.sections.item(csection).filename=this.filename
            this.sections.item(csection).loadsection()&&由于调用了这个方法,很多变量名重名,导致频繁报错,排查了好久。
        ENDFOR

        RELEASE lcinifile,lcbuffer,lnsize,lnarray,j,n,laposition

        RETURN .t.
    ENDPROC


    *-- 删除一个指定的section小节,及其数据。
    PROCEDURE deletesection
        *VB申明原型:;
        Public Declare Function WritePrivateProfileSection ;
        Lib "kernel32" Alias "WritePrivateProfileSectionA" ;
        (ByVal lpAppName As String, ;
        ByVal lpString As String, ;
        ByVal lpFileName As String) As Long;
        DECLARE integer WritePrivateProfileSection in win32api;
        string csection,;
        string cstring,;&&用chr(0)间隔的字符串组,null值则删除此section;
        string cfile
        PARAMETERS lcsection
        nchoice=MESSAGEBOX("此section小节下面的所有数据都会被删除!确定此操作吗?",1+48+256,"警告!")
        IF nchoice=1
            WritePrivateProfileSection(lcsection,NUll,this.filename)
            cexact=SET("exact")
            SET EXACT ON
        **********************用集合替代集合*******************;
            nfound=0
            FOR i=1 TO this.sections.count
                IF this.sections(i).name==ALLTRIM(lcsection)
                    this.sections.remove(i)
                    EXIT 
                ENDIF
            ENDFOR 
        *****************************************************;
            nlen=ALEN(this.sections);
            ADEL(this.sections,nfound);;
            IF nlen>1;
                DIMENSION this.sections[nlen-1];
            ENDIF
            SET EXACT &cexact
        **********************用集合替代集合*******************
            RETURN .t.
        ELSE 
            RETURN .f.
        ENDIF

    ENDPROC


    PROCEDURE Destroy
        CLEAR DLLS
        RELEASE ALL 
    ENDPROC


    PROCEDURE Init
        this.declaredlls()
        *IF ISNULL(this.sections)
            this.sections=CREATEOBJECT("sections")
        *ENDIF

    ENDPROC


ENDDEFINE
*
*-- EndDefine: inifile
**************************************************


**************************************************
*-- Class:        key (d:\documents\visual foxpro 项目\inifile.vcx)
*-- ParentClass:  custom
*-- BaseClass:    custom
*-- Time Stamp:   10/11/21 10:01:08 PM
*
DEFINE CLASS key AS custom


    Height = 58
    Width = 75
    *-- 用以保存指定section的key值
    value = ""
    Name = "key"


ENDDEFINE
*
*-- EndDefine: key
**************************************************


**************************************************
*-- Class:        keys (d:\documents\visual foxpro 项目\inifile.vcx)
*-- ParentClass:  collection
*-- BaseClass:    collection
*-- Time Stamp:   01/23/22 05:39:07 PM
*
DEFINE CLASS keys AS collection


    Height = 23
    Width = 23
    Name = "keys"


    PROCEDURE Add
        LPARAMETERS eItem, cKey, eBefore, eAfter
        ****以下代码将阻止添加其它非指定对象key的任何成员,只允许添加派生于key类的对象****
        **********感兴趣的朋友可以修改这段代码让自己的key类只添加符合条件的成员***********

        IF TYPE("eitem")#"O" &&阻止非对象成员添加
            NODEFAULT 
            MESSAGEBOX("非法成员添加!",0+16,"错误",1000)
            RETURN .f.
        ELSE 
            IF upper(eitem.class)#UPPER("key") &&阻止非Key对象的成员添加
                NODEFAULT 
                MESSAGEBOX("非法成员添加!",0+16,"错误",1000)
                RETURN .f.
            ENDIF
        ENDIF

    ENDPROC


ENDDEFINE
*
*-- EndDefine: keys
**************************************************


**************************************************
*-- Class:        section (d:\documents\visual foxpro 项目\inifile.vcx)
*-- ParentClass:  custom
*-- BaseClass:    custom
*-- Time Stamp:   01/28/22 08:12:01 PM
*
DEFINE CLASS section AS custom


    Height = 24
    Width = 81
    *-- 保存ini文件名
    filename = ""
    *-- 用以保存section里所有key对象的集合
    keys = "NULL"
    Name = "section"


    *-- 载入指定section下的所有key以及key值,并保存在keys数组和values数组里
    PROCEDURE loadsection
        PARAMETERS lcsection
        IF PARAMETERS()=0
            lcsection=this.name
        ENDIF

        *这里的变量名都加了个数字1,是因为inifile类的loadfile调用了这个方法,导致变量重名出错。
        *单独运行没有问题,一旦被调用就出问题了,排查了很久。
        *现在所有变量名称后面都加了1,故障排除。
        *原来是用数组来保存keys数据,2021/1/28改为用集合来保存
        lcbuffer1=repli(CHR(0),255)
        lcinifile=this.filename
        lnsize1=getprivateprofilesection(lcsection,@lcbuffer1,255,lcinifile)
        IF lnsize1=0
            RETURN .f.
        ELSE
            lcbuffer1=SUBSTR(lcbuffer1,1,lnsize1)
        ENDIF
        **********************************原来的使用数组代码开始*************************************;
        lnarray1=OCCURS(CHR(0),SUBSTR(lcbuffer1,1,lnsize1));
        DIMENSION laposition1[lnarray1];
        DIMENSION this.keys[lnarray1];
        DIMENSION keyvalue[lnarray1];
        FOR i=1 TO lnarray1;
            laposition1[i]=AT(CHR(0),lcbuffer1,i);
            n1=IIF(i>1,laposition1[i-1]+1,1);
            keyvalue[i]=SUBSTR(lcbuffer1,n1,laposition1[i]-n1);
            this.keys[i]=CREATEOBJECT("key");
            this.keys[i].name=SUBSTR(keyvalue[i],1,AT("=",keyvalue[i],1)-1);
            this.keys[i].value=SUBSTR(keyvalue[i],AT("=",keyvalue[i],1)+1,LEN(keyvalue[i]));
        ENDFOR
        **********************************原来的使用数组代码结束*************************************

        **********************************现在的使用集合代码开始*************************************
        *this.keys.remove(-1) &&确保集合为空

        lnarray1=OCCURS(CHR(0),lcbuffer1)
        DIMENSION laposition1[lnarray1] &&保存key数据中间隔符chr(0)的位置的数组,以便提取keyvalue值
        DIMENSION keyvalue[lnarray1]
        FOR i=1 TO lnarray1
            laposition1[i]=AT(CHR(0),lcbuffer1,i)
            n1=IIF(i>1,laposition1[i-1]+1,1)
            keyvalue[i]=SUBSTR(lcbuffer1,n1,laposition1[i]-n1)
            ckey="key"+ALLTRIM(STR(i))
            &ckey=CREATEOBJECT("key")
            this.keys.add(&ckey,ckey)
            this.keys.item(ckey).name=SUBSTR(keyvalue[i],1,AT("=",keyvalue[i],1)-1)
            this.keys.item(ckey).value=SUBSTR(keyvalue[i],AT("=",keyvalue[i],1)+1,LEN(keyvalue[i]))
        ENDFOR
        RELEASE lnarray1,laposition1,keyvalue,i,n1,lcbuffer1
        **********************************现在的使用集合代码结束*************************************

        RETURN .t.
    ENDPROC


    *-- 向section小节指定的key写入值,如果指定的key不存在则新建一个。
    PROCEDURE writekey
        *VB申明原型:;
        Public Declare Function WritePrivateProfileString ;
        Lib "kernel32" Alias "WritePrivateProfileStringA" ;
        (ByVal lpApplicationName As String, ;
        ByVal lpKeyName As Any, ;
        ByVal lpString As Any, ;
        ByVal lpFileName As String) As Long;
        DECLARE integer WritePrivateProfileString in win32api;
        string csection,;
        string ckey,;
        string cstring,; &&null值则删除此key;
        string cfile
        PARAMETERS lckey,lcvalue

        IF PARAMETERS()=0
            Lcparameter=INPUTBOX("请设置key名,以及key值,用斜杠/分割","新建或修改一个key")
            IF EMPTY(lcparameter)
                RETURN .f.
            ENDIF
            lckey=LEFT(ALLTRIM(lcparameter),AT("/",ALLTRIM(lcparameter),1)-1)

            lcvalue=RIGHT(ALLTRIM(lcparameter),(LEN(ALLTRIM(lcparameter))-AT("/",ALLTRIM(lcparameter),1)))
        ENDIF

        writeprivateprofilestring(this.name,lckey,lcvalue,this.filename)

        cexact=SET("exact")
        SET EXACT ON 
        **********************原来用数组来保存key*******************;
        nfound=ASCAN(this.keys,lckey);
        IF nfound=0;
            IF TYPE('this.keys[1]')<>"O";
                nlen=1;
            else    ;
                nlen=ALEN(this.keys)+1;
                DIMENSION this.keys[nlen];
            ENDIF;
        ENDIF;
        this.keys[nlen]=CREATEOBJECT("key");
        this.keys[nlen].name=lckey;
        this.keys[nlen].value=lcvalue;
        **********************现在用集合来保存key*******************
        lfound=.f. 
        n=this.keys.count

        FOR EACH okey IN this.keys
            IF okey.name==ALLTRIM(lckey)
                lfound=.t. &&判断集合中是否已有该key对象
            ENDIF
        ENDFOR

        IF lfound=.f. &&没有该key对象则添加该对象
            this.keys.add(CREATEOBJECT("key"))
            n=n+1
            this.keys(n).name=lckey
        ENDIF

        this.keys(n).value=lcvalue
        **********************现在用集合来保存key*******************

        SET EXACT &cexact

        RETURN .t.
    ENDPROC


    *-- 删除指定key及其key值。
    PROCEDURE deletekey
        *VB申明原型:;
        Public Declare Function WritePrivateProfileString ;
        Lib "kernel32" Alias "WritePrivateProfileStringA" ;
        (ByVal lpApplicationName As String, ;
        ByVal lpKeyName As Any, ;
        ByVal lpString As Any, ;
        ByVal lpFileName As String) As Long;
        DECLARE integer WritePrivateProfileString in win32api;
        string csection,;
        string ckey,;
        string cstring,; &&null值则删除此key;
        string cfile
        PARAMETERS lckey
        nchoice=MESSAGEBOX("此key键下面的所有数据都会被删除!确定此操作吗?",1+48+256,"警告!")
        IF nchoice=1
            WritePrivateProfilestring(this.name,lckey,NUll,this.filename)
            cexact=SET("exact")
            SET EXACT ON
        **********************用集合替代集合*******************;
            nfound=0;
            FOR i=1 TO ALEN(this.keys);
                IF this.keys[i].name==lckey;
                    nfound=i;
                ENDIF;
            ENDFOR ;
            ;
            nlen=ALEN(this.keys);
            ADEL(this.keys,nfound)    ;
            IF nlen>1;
                DIMENSION this.sections[nlen-1];
            ENDIF

            FOR i=1 TO this.keys.count
                IF this.keys(i).name==ALLTRIM(lckey)
                    this.keys.remove(i)
                    EXIT
                ENDIF
            ENDFOR


        **********************用集合替代集合*******************
            SET EXACT &cexact
            RETURN .t.
        ELSE 
            RETURN .f.
        ENDIF

    ENDPROC


    PROCEDURE Init
        *1/28日加入以下代码,将this.keys赋值为集合
        *IF ISNULL(this.keys)
            this.keys=CREATEOBJECT("keys")
        *ENDIF
    ENDPROC


ENDDEFINE
*
*-- EndDefine: section
**************************************************


**************************************************
*-- Class:        sections (d:\documents\visual foxpro 项目\inifile.vcx)
*-- ParentClass:  collection
*-- BaseClass:    collection
*-- Time Stamp:   01/23/22 05:42:00 PM
*
DEFINE CLASS sections AS collection


    Height = 23
    Width = 23
    Name = "sections"


    PROCEDURE Add
        LPARAMETERS eItem, cKey, eBefore, eAfter
        ****以下代码将阻止添加其它非指定对象section的任何成员,只允许添加派生于section类的对象****
        **********感兴趣的朋友可以修改这段代码让自己的collection类只添加符合条件的成员***********

        IF TYPE("eitem")#"O" &&阻止非对象成员的添加
            NODEFAULT 
            MESSAGEBOX("非法成员添加!",0+16,"错误",1000)
            RETURN .f.
        ELSE 
            IF upper(eitem.class)#UPPER("section") &&阻止非section的派生类对象的成员添加
                NODEFAULT 
                MESSAGEBOX("非法成员添加!",0+16,"错误",1000)
                RETURN .f.
            ENDIF
        ENDIF

    ENDPROC


ENDDEFINE
*
*-- EndDefine: sections
**************************************************
搜索更多相关主题的帖子: key ByVal IF String this 
2022-01-28 20:31
schtg
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:https://t.me/pump_upp
等 级:贵宾
威 望:67
帖 子:1355
专家分:2534
注 册:2012-2-29
得分:14 
谢谢分享!
2022-01-28 20:33
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
得分:0 
使用方法:

set classlib to inifile addi &&假设inifile类在当前目录下
myinifile=createobject("inifile")
myinifile.create() &&建立一个ini配置文件
myinifile.loadfile() &&导入一个ini配置文件
myinifile.deletesection() &&删除指定的section
myinifile.writesection() &&写入一个指定的section
myinifile.sections(1).writekey() &&往第一个section写入指定的键值
myinifile.sections("csection1").writekey() &&往别名为csection1的section写入指定的键值
myinifile.sections(1).deletekey() &&删除第一个section下指定的键值
myinifile.sections("csection1").deletekey() &&删除别名为csection1的section下指定的键值
......
?myinifile.sections(1).name &&获得第一个section的名
?myinifile.sections("section1").name &&获得别名为section1的section名
......

不明白的在问我吧。
2022-01-28 21:03



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-508243-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.245582 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved