本帖最后由 神女软件定制 于 2023-5-31 18:07 编辑
普通方法
对于这样一个窗口,需要读取和保存用户的设置。
我们一般是这样做的:
窗口程序集名 | 保 留 | 保 留 | 备 注 | 窗口程序集_测试窗口 | | | |
bjk_用户名.内容 = 读配置项 (取运行目录 () + “\配置.ini”, “常规”, “用户名”, “默认用户名”)bjk_密码.内容 = 读配置项 (取运行目录 () + “\配置.ini”, “常规”, “密码”, “”)xzk_记住密码.选中 = 读配置项 (取运行目录 () + “\配置.ini”, “常规”, “记住密码”, ) = “真”dxk_线路1.选中 = 读配置项 (取运行目录 () + “\配置.ini”, “常规”, “线路1”, “真”) = “真”dxk_线路2.选中 = 读配置项 (取运行目录 () + “\配置.ini”, “常规”, “线路2”, ) = “真”zhk_大区.现行选中项 = 到整数 (读配置项 (取运行目录 () + “\配置.ini”, “常规”, “大区”, “0”)) 写配置项 (取运行目录 () + “\配置.ini”, “常规”, “用户名”, bjk_用户名.内容 )写配置项 (取运行目录 () + “\配置.ini”, “常规”, “密码”, bjk_密码.内容 )写配置项 (取运行目录 () + “\配置.ini”, “常规”, “记住密码”, 到文本 (xzk_记住密码.选中 )) 写配置项 (取运行目录 () + “\配置.ini”, “常规”, “线路1”, 到文本 (dxk_线路1.选中 )) 写配置项 (取运行目录 () + “\配置.ini”, “常规”, “线路2”, 到文本 (dxk_线路2.选中 )) 写配置项 (取运行目录 () + “\配置.ini”, “常规”, “大区”, 到文本 (zhk_大区.现行选中项 ))
就很麻烦,所有的信息,都要写两次,读取写一次,保存写一次,并且很容易一不小心两边名称不匹配,或者哪边少写了一行。
所以写了三个类,这三个类依次是派生关系,一步一步层次化简化用户代码,最终实现一键保存用户配置
配置保存类 为了减少用户代码,弄了一个类,来统一管理配置的读取和保存:
像这样使用: 窗口程序集名 | 保 留 | 保 留 | 备 注 | 窗口程序集_测试窗口 | | | | 变量名 | 类 型 | 数组 | 备 注 | cx_ini | 配置保存类 | |
cx_ini. 添加组件 (bjk_用户名, “用户名”, “默认用户名”)cx_ini. 添加组件 (bjk_密码 )cx_ini. 添加组件 (xzk_记住密码 )cx_ini. 添加组件 (dxk_线路1, , “真”)cx_ini. 添加组件 (dxk_线路2 )cx_ini. 添加组件 (zhk_大区 )cx_ini. 读取配置 ()cx_ini. 保存配置 ()瞬间就清爽了不少,只用在创建完毕的时候,一次指定好所有信息 使用方法:
公开了7个方法: 1.设置配置文件路径:用来自定义配置文件的名称,如果不调用,默认配置文件路径是:调试模式为“配置.ini”,非调试模式为“{执行文件名}.ini” 2.切换节:自定义后续调用添加组件时,使用的节名称,如果不调用默认节名称是:“常规” 3.添加组件:
参数1,通用型,可以传编辑框,选择框,单选框,组合框,滚动条,滑块条,选择夹,日期框,IP编辑框,其他组件需要用户修改源码扩展,已考虑到,后续说明如何扩展 参数2,可空,保存在ini里面的配置项名称,如果不指定,会自动检索组件的名称,比如“编辑框1”,有的时候懒得起名了,就很方便 参数3,可空,首次运行没有配置时的默认值,如果不指定,会自动检索组件设计状态下的值作为默认值,也就是可以确保首次运行没有配置时和窗口设计状态保持一致(这个比较实用)
4.移除组件:目前看起来是多余的,谁会没事干添加了又移除呢,这个是为了方便后面派生类预留的 5.读取配置:无参数,功能如名 6.保存配置:无参数,功能如名 7.重置:无参数,有的时候用户把界面上的配置搞乱了,一般是关闭程序,删除ini文件,重新启动程序。有了这个功能可以给个按钮让他重置,把界面上的配置恢复成调用“添加组件”时指定的默认值。 完整例子:
到这里,已经一定程度的减少了用户代码
配置保存类_ex 派生自配置保存类
扩展了2个方法:“快速添加_从父组件”,“快速添加_批量”,仅添加了用于批量添加控件的功能
因为派生自配置保存类,所以可以使用配置保存类的所有功能(继承)
1.快速添加_从父组件:传一个父组件,可能是窗口,分组框,或选择夹,内部使用“寻找组件”遍历所有子孙窗口,用于添加
2.快速添加_批量:有8个可空通用型参数,可以在任意位置传组件,比如:对象.快速添加_批量(,,编辑框1,,选择夹1),如果多于8个,可能需要多次调用
上面两个方法一般只使用其中一个即可
批量添加时,并没有地方指定配置项名称,内部对“配置项名称”参数留空调用基类的“添加组件”,所以配置项名称自动检索控件名称
也没有地方指定默认值,内部对“默认值”参数留空调用基类的“添加组件”,所以默认值自动检索控件设计状态下的值
快速添加_从父组件,虽然很快,但是有可能同时顺带添加了我们不想读取保存配置的控件。
所以在基类“配置保存类”上提供了“移除组件”方法,按理说移除组件应该由“配置保存类_ex”来提供,但是 易语言中类的成员只是私有的,派生类不能直接访问基类的成员,所以只能由基类提供,因为实际管理的成员在基类上。
对“配置保存类”来说,“移除组件”的存在显得不太合理,只能强行解释一下: 万一有人添加了又想移除呢,谁说得准呢,人心难测
或者,为了避免从父控件批量添加时,添加了不想要的控件,可以通过控件的 标识属性来判断,可能需要修改添加这样的代码(目前没有加入):
|
快速添加_从父组件_指定 | | | |
cs_父组件 | 通用型 | | | | cs_指定标识 | 文本型 | | | |
变量名 | 类 型 | 静态 | 数组 | 备 注 | jb_窗口 | 窗口 | | | jb_寻找句柄 | 整数型 | | | jb_计次 | 整数型 | | | jb_组件 | 窗口 | | | _copy8 (jb_窗口, cs_父组件 )jb_寻找句柄 = 寻找组件 (jb_窗口, , , , )计次循环首 (取找到组件数目 (jb_寻找句柄 ), jb_计次 )_copy8 (jb_组件, 取所找到组件 (jb_寻找句柄, jb_计次 - 1 )) 如果真 (jb_组件.标记 = cs_指定标识 )添加组件 (jb_组件 )计次循环尾 ()清除组件寻找句柄 (jb_寻找句柄 )|
快速添加_从父组件_排除 | | | |
cs_父组件 | 通用型 | | | | cs_排除标识 | 文本型 | | | |
变量名 | 类 型 | 静态 | 数组 | 备 注 | jb_窗口 | 窗口 | | | jb_寻找句柄 | 整数型 | | | jb_计次 | 整数型 | | | jb_组件 | 窗口 | | | _copy8 (jb_窗口, cs_父组件 )jb_寻找句柄 = 寻找组件 (jb_窗口, , , , )计次循环首 (取找到组件数目 (jb_寻找句柄 ), jb_计次 )_copy8 (jb_组件, 取所找到组件 (jb_寻找句柄, jb_计次 - 1 )) 如果真 (jb_组件.标记 ≠ cs_排除标识 )添加组件 (jb_组件 )计次循环尾 ()清除组件寻找句柄 (jb_寻找句柄 )
示例:
配置保存类_smart
派生自配置保存类_ex
没有添加公开方法,重写了一个基类方法(多态):添加组件
写这个的初衷就是为了方便,减少用户代码,避免写大量的读配置项,写配置项……
“配置保存类”至少需要调用N个“添加组件”和“读取配置”,“保存配置”
“配置保存类_ex”提供了批量添加的方法,但是仍然需要调用“读取配置”,“保存配置”
“配置保存类_smart”可以做到只要一行代码,就可以自动保存、读取配置了
只需要像这样使用(或者其他添加控件的方式),就可以自动的读取和保存配置了:
虽然没有添加任何公开方法,但是派生自“配置保存类_ex”,而“配置保存类_ex”又派生自“配置保存类”,所以可以使用“配置保存类”和“配置保存类_ex”的所有功能
只要变量类型声明为:配置保存类_smart,不管调用哪种方式添加的控件,都会自动读取和保存配置,已经不需要调用“读取配置”和“保存配置”了。
原理是重写了“添加组件”方法,当调用添加时就自动读取了控件的配置,然后内部子类化了所有添加的控件的顶级窗口(可以不是同一个),如果顶级窗口销毁了,自动保存。所以不需要“_窗口_可否被关闭”事件和“保存配置”方法了
这里的重写,不是说重新写了代码,是面向对象里多态的一个概念override,懂的懂,不懂的一时半会确实说不明白。不过简单使用也可以不用理解这个
相对之前发过的一个版本修复了一个bug,之前版本子类化这部分,直接用字节集上的内存做代码执行了,我电脑上是没有问题的,可能有的系统内存默认属性不一样,不允许执行权限。 这个版本自行申请了有执行权限的内存,用来合成窗口过程的代码,把窗口过程引导到类中的方法中。
到这里,从“配置保存类”到“配置保存类_ex”,再到“配置保存类_smart”,一步一步层次化简化了用户代码,最终实现一键保存用户配置。 能为各位懒人做的,就这么多了
【用户扩展】 如果不需要自己修改源码扩展,可以不用看下面的了
前面说到支持这些控件:编辑框,选择框,单选框,组合框,滚动条,滑块条,选择夹,日期框,IP编辑框。 已经把应该支持的都支持了,我觉得应该是用户输入型控件,才需要保存和读取配置。列表框之类的,更偏向于展示型控件了,所以没有添加,如果想添加需要自己修改源码 找到“配置保存类._序列化”方法,读取和保存都会经过这个方法来读取和设置控件上的配置
如果想添加列表框支持,可以像这样添加一个判断分支(红框内的代码):
或者,如果想对类型为密码输入的编辑框加密存储,可以修改添加红框内的代码: 在这里修改对“配置保存类_ex”和“配置保存类_smart”依旧有效。
【可能的优化】 内部使用窗口类名判断控件的类型,不支持颜色选择器,类名也是“Button”,和单选框,选择框重复了 窗口组件转通用型了,没法取出运行时类型信息了,可能是我没找到方法,有知道的可以告知下。
然后用户扩展部分设计方式不太好,按理说不应该让用户修改库代码来实现扩展。 有一个设想的理想的方式,就是配置保存类默认实现了一些类型的序列化方式,用户可以调用“设置序列化器”来添加其他类型的支持,或者覆盖已支持类型的默认实现 但是易语言不支持,没有办法。如果要用这种模式,只能是传指针,但是这样反而增加了用户代码使用的复杂性 假想的代码:
【2023年5月31日17点52分更新】 @kmskik 反馈编译成模块后运行会崩溃,经过排查,是易语言的bug:
弄出来就分享出来了,我确实也没有编译成模块测试过 新的附件已经修复,绕过这个bug 然后更新了 1:跳过只读编辑框,(修改了配置保存类._序列化方法,判断是只读编辑框返回假就可以了) 2:“配置保存类_ex”类中添加了:快速添加_从父组件_指定标记、快速添加_从父组件_排除标记,通过易语言控件的标记属性来指定是否管理配置(前面提到过,干脆加上了)
有人说这个有点复杂,可能有点吧。不过我觉得还是给用户灵活一点,其实是由3种方式可以使用的(就是里面分层的3个类),灵活和简单,难以取舍
【源码下载】
配置保存类-smart.e
(31.04 KB, 下载次数: 224)
|