小工具开发备忘

最近用C++语言写一个小的工具程序,进展还算顺利,大的方向和功能开展的比较顺利,但是细节上有很多小问题。为了确保软件开发的进度,我是抓大放小,先力求能将整体功能全部实现出来。

对于细节问题,只能是做些备注、放在一旁,等软件整体完成之后,再回过头来逐一推敲了。这里记录一下遇到的小问题,当是给自己的备忘,等以后有时间了,再慢慢研究。

1、《系统托盘菜单点击之后500毫秒内的残影》

这个问题并不严重,临时解决方案是在程序中触发截屏时,先延迟一段时间再开始进行截屏。

2、《std::vector.size()返回的是size_t类型》

这并不是“放在一旁、暂且不管”的缺陷,而是我在写代码的时候遇到的一个“引起程序崩溃”的bug。实际上并非真的导致了程序的崩溃,而是因为wxWidgets中的调试断言弹出了警告对话框。

只不过因为我对C++不熟悉、又这个弹出警告框的文字实在难于阅读,所以起初一直以为是程序崩溃了。找了好久才找到原因,并且发现只不过是在f(x)函数的调用是,参数x使用了int类型,而真正应该使用的是size_t类型。虽然int和size_t几乎一样,但严格的断言判定最终生成了警告信息。

这个问题虽然已经解决,但是额外的需要再补充一下细节知识的缺失——《C++中的int和size_t有什么不同?

3、《wxWidgets似乎没有事件广播机制

我现在对wxWidgets的认知来看,它是没有事件广播机制的,但是对于我现在正在开发的一个“相对复杂”的窗口,如果能够以事件广播,将会令代码更加简单。所以想到了一个也许笨拙的方法——使用全局单例——来临时解决问题。

================ 以下为尚未这里问题 ================

一、已解决的问题主要有:

1、为什么在程序退出时会产生一些内存泄漏?

答:之前使用的退出方式不正确,之前的退出方式在“程序退出”时,虽然也调用了析构函数,但是那个调用析构函数的时候,实际上内存已经泄露了。我在那个析构函数中进行资源释放,实际上是对已经泄露了内存、且资源句柄已经无效的时刻,才去释放资源,结果就是无权访问会引发程序崩溃。

按照之前的错误思路,怎么办呢?释放就会崩溃,所以只能选择不释放资源,这样程序就不会崩溃了。但是在debug调试器中,就会看到有内存泄漏产生。虽然这里产生的内存泄漏会再被系统回收处理,但是这相当于是将“烂摊子”交给了操作系统的内存控制器。

现在已经解决了。解决的方法就是改用正确的退出函数,这样正确的退出函数会触发正确的析构过程,在这个新的析构过程中,释放资源,此时的资源还没有泄露,也就可以正常的被释放掉。

2、icontray的弹出菜单文字的动态调整

这里只是一个小技巧而已:将mainFrame的指针传给iconTray,这样iconTray内部就能在弹出菜单之前,判断出mainFrame当前的状态,再根据mainFrame的当前状态实时生成菜单,就能够令弹出菜单的内容“实时”,使用体验会比较好。

二、尚未解决的问题:

1、程序多次被启动,虽然我用互斥锁能判断出来,但是第二次启动只能弹出一个提示“已有实例,不要重复启动”。

但是我想做的更好一些,使用IPC通信,第二次的启动可以通过IPC通知第一个实例,第一个实例如果正处于隐藏状态(icontray状态),就自己重新唤醒起来。

2、paintDC的绘制效率很低:已经使用双缓存和悬浮层两个方案,共同解决了这个问题。

3、wxSashLayoutWindow窗口的拖拽改变尺寸,产生的事件

OnSashDrag(wxSashEvent&)

这个事件折磨了我大约4个小时,后来才想起来打印看一下,结果发现这是在鼠标抬起的时候才唯一的产生一次响应。难怪无法实时改变窗口的大小。还没有解决思路。

以前上学的时候觉得所有的知识都挺容易理解的,现在也许是年龄大了,即便是对已经已经熟练掌握了的知识,再看的时候,都会感觉是“一头雾水”,唯有继续艰难的、一点点的重新理解,才能让自己感觉有所收获。

Related Posts

Android Studio开发应用在真机上安装运行

昨天在电脑上安装了一套Android Studio,这是一套非常高效边界的Android应用开发工具。初步使用觉得除了安装过程比较耗时,其它都很顺利。 以前从来没有接触过Java语言和Android应用开发,所以上手有一些缓慢,但网上例子很多,Android Studio本身也提供了初始应用程序框架,所以只需要新建一个项目就可以直接运行、观察结果。 我想将这个最基本的Demo运行在自己的手机上,也就是真机体验一下。看网上介绍都很繁琐,估计这些介绍都是基于低版本Android Studio而言吧?至少在我所安装的版本上,几乎不用做任何设计、不做任何额外的工作,很顺利就可以完成真机运行。 只需要两步:手机开启“开发者模式”、在AS内使用自带的包管理器安装USB Driver。如此两步中的第二步我也不确定是否是必须的,也许连USB Driver都不需要安装也说不定,总之我就只做了如上两步,并没有如其他文章列举的,又要升级驱动、又要安装额外的什么东西,什么都没有做,连上手机,就可以直接真机运行了。 然后我又看了看Kotlin语言,据说是比Java更先进、更优雅的语言。但是只大概看了一两眼,就觉得不喜欢。说实话我连Java都不喜欢,相对而言还是喜欢C/C++那样“板板正正”的语言风格,对于“如诗如画”的语言,你觉得它能够写出“自然语言感觉”,但在我看来这是一种凌乱与松散。 之所以要体验一下这个开发工具、以及上手接触一下Android应用开发,也不是有什么项目或开发任务,只是想在自己的手机里实现一些自己觉得比较有用的小工具。这些小工具在应用市场上其实很多,但不是收费、就是内置了广告,我觉得我既不需要太多的功能、也不想花钱或看广告。 所以自己实现一下,自给自足好了。

PHP8中不再提供XMLRPC模块

自从PHP8.0版本开始,php for windows的默认安装包里面已经不在提供php-xmlrpc模块。这是因为xmlrpc模块的编译依赖于libxml,也是一个古老且停止了更新维护的模块。也许是处于安全性和先进性的考虑,所以PHP8中的xmlrpc模块便也不再默认提供了。 但在官方文档中并没有明确的提出这一点,而是“暧昧”的说可以在pecl中找到相关的模块。在pecl的官网也的确能够看到这个xmlrpc的页面,其中也是模棱两可的继续展示着它的二进制下载地址。 不过它所提供的DLL二进制下载包的下载地址中所有的链接,都已经是无效的、无法完成下载的了。 不清楚这些预编译的dll文件,是曾经提供过、但后来某种原因不再继续进行编译、提供。以至于现在都无法下载;还是从PHP8发行之处,就已经不再提供。如果是后者,有一点很难解释:既然不提供、那么还发布这个页面做什么呢?如果是前者、也很难解释,页面上没有任何的变更提示声明。 无论如何,对于xmlrpc模块的使用,现阶段只有以下四个方案,并且也许只有第一个方案是可行的: 方案一、降配使用PHP7进行模块的使用; 方案二、在PHP8中使用networking-xmlrpc平替模块; 方案三、自己通过源代码进行PHP8扩展模块的编译,编译生成xmlrpc的dll文件使用; 方案四、自己使用simpleXML对需要的XML格式文件进行解析,完成相关功能。 我现在为了追求开发速度,临时使用了方案一,这样至少能让开发进度继续进行下去。不过这样一来,整个项目中的其他代码又会因为使用了PHP8的语言语法特性而无法正常运行。不大可能再对整个项目进行代码调整,所以这一方案只是临时的、仅仅用于完成xmlrpc相关功能部分的实现。 之后也许会考虑使用方案四重写现在的代码,自己实现其中具体的解析,这样就可以再将环境语言重新恢复回PHP8版,以确保整个项目依然能够正常运行。

CI4中声明stdClass类实例

最近使用CodeIgniter4框架进行宠物项目的Server端开发,因为model层还没有全部实现好,所以准备用stdClass临时拼凑一些伪代码出来,相关代码如下: 但是如上的代码是无法正常运行的,会提示没有stdClass类声明。原因是CI4框架中引入了PHP的命名空间的概念,注意到上面代码截屏的第3行就已经指定的这段代码是在App\Controllers空间下,所以其中的地14行相当于是要声明一个App\Controllers\stdClass类的实例,显然这个“空间内类”是不存在的,自然也就无法找到类声明、进而无法完成类实例化。 将上面的new stdClass()语句稍作修改,使用“绝对空间路径”指定stdClass类的空间地址即可解决。 因为stdClass类是PHP内置的基础类,它的命名空间就是在“根”下,所以上面代码修改如下,即可解决问题: 附: 我是用CI框架好多年了,可能是从CI2开始使用的吧,当初选择这个框架是因为觉得它非常的轻便、小巧,足够的简单。后来CI3发布之后也用CodeIgniter3做过一些项目,对这个框架十分钟爱。 这次开发,便也选择了CI框架,本来起初想追求稳妥继续使用CI3框架。一来比较熟悉、二来也是因为基于CI3我已经积攒了足够多的基础库,开发速度会比较快。但到底还是犯了程序员最喜欢犯的毛病——追求新技术。 使用新的技术通常情况下似乎能够带来生产力的提升,但这也许是个“假象”,新技术并不一定就真的好用,尤其是在自己不熟悉、不熟练的时候,贸然使用新的技术,往往会导致初期开发成本的增加、效率低下。 所以不到迫不得已、不是必须由新技术才能搞定的需求,最好还是使用成熟的、自己最熟悉的工具和技术,才是稳妥的做法。

着手开始基于微信小程序的APP开发

虽然我对《又大又杂的APP》充满了厌恶,但既然已经答应了朋友,无论如何也只好硬着头皮开始了这个微信小程序的开发。才开始两天,就发现真的是太痛苦了。整个项目杂乱、庞大,而且连基本的规则都是混乱的。 它期望利用微信小程序完成一个SNS社交平台类应用的构建,这几乎就可以看作是痴人说梦,甚至可以说是“梦中梦中梦”。 微信其实就已经是“梦中梦”了,原本微信只应是一个IM工具,而诸如社交、分享、朋友圈的功能,应该是分散在手机系统的各个APP中,然而微信却将这所有的功能整合到了一个应用中,好像在手机系统中嵌入了一个子系统,加之微信提供的公众号、服务号、小程序等扩展能力,它真的可以完成“梦中梦”的实现。 然而我那个朋友想做的APP,是一款宠物兴趣人群的SNS应用,但他却只想在微信的小程序中实现,他的理由很简单:小程序开发成本低、推广起来用户基础好。 但是他想做的本身也是一个平台级应用,例如:这个应用是具有SNS属性的、拥有SNS属性就意味着有好友关系、好友之间能够进行短信短消息的交换…… 如此一来,相当于你打开手机之后想分享一个照片,不需要使用手机中的、成熟的SNS社区,只要进入微信那个“子系统”就可以操作了。 而当你想将自己的猫咪日常生活分享给你的“猫咪好友”时,这个好友其实即不再某个SNS平台中、也不再微信中、而是在微信的小程序的某个小程序服务商列表中,于是你就要:打开手机、进入微信、启动小程序,使用这个小程序APP分享照片。这不就是“梦中梦中梦”么? 我自己的电脑性能差、手机性能也很差,所以平日中我使用微信都比较费劲、卡顿的,有些时候去商场买东西必须使用店家的小程序时我总会皱眉——几乎可以肯定很难快速启动他们的小程序,几乎可以肯定大概率会加载慢、崩溃。而那些商家的小程序其实功能还算简单、页面也不复杂呢。 我现在都可以想象出朋友那个宠物SNS小程序,果真实现出来之后将会何其缓慢、问题重重。 事实上,它很可能实现不出来,因为是我在开发这个APP呀,我的电脑老旧得甚至连开发者工具都运行不起来。只一个非常简单的页面组件的开发,都会崩溃好几次。所以两天下来,连一个页面都没有完成。如此缓慢的进度,想实现出来?又是有点儿“痴人说梦”了。 开发过程的技术细节我觉得到没什么太多可以记录的,至少现在还没有遇到值得记录的内容。毕竟现在刚刚开始,只是做了一些基本的页面,而这些页面也就只是html代码和css样式的编写,其中不存在什么高新技术。 如果往后的日子里,这个项目能够持续开发,并且真能向着最终目标一点点的前行,那我就将开发过程中遇到的问题、值得写上几笔的地方,当作日记记录在这里,也方便自己今后回顾这段“痛苦不堪”的帮忙经历吧。

辗转相除法计算两个数的最大公约数

本来想做一个在线的一元二次方程求解小工具,但是真的上手操作才发现,想法很简单、实现起来很麻烦。所以我只好不断的简化需求,经过几次简化现在只能先完成对分数的化简操作,也就是在给定一个分数之后,对这个分数进行约分得到最简分数。 其中用到了一个求两数最大公约数的方法——辗转相除法。 实际上想计算两个数的最大公约数,有几种不同的方法,其中辗转相除法是相对容易理解、也比较容易通过程序实现的。 这里是最终完成的效果演示: https://www.m3we.com/mathtools/gcd.php?numerator=3334&denominator=12 即便是这个简单的功能,现在的演示也仍然不够完善、不够完美,还有很多需要进一步完善的地方。所以对于求解一元二次方程,短期内是难以实现的,只有一步步的先将这些基础环节做好,之后再做打算了。 update 2024.07.13 自己试了几个,发现还是存在bug的,例如下面这个计算过程,就是不正确的,原因还没有推敲,估计还要几天才能解决。 https://www.m3we.com/mathtools/gcd.php?numerator=333143543545.12&denominator=124.32 update 2024.07.14 18:51 已经找到了上面bug产生的原因,并且初步解决了。这里欠着一篇关于这个bug的记录,额外的又发现了一些新的问题,例如对于如下的分数,最后的表现也不尽人意,所以这个小工具还是有很多要改进的地方: 1、如果分子或分母中有符号,则在最终的结果中,应该将符号提取到整个分数的外面: https://www.m3we.com/mathtools/gcd.php?numerator=-333&denominator=33 2、如果分子和分母中同时有符号,虽然最后的结果是正确的,但是这只是计算的结果,与思维的过程实际上是不同的。正确的思维过程应该是先完成(增加一步预处理)变号操作: https://www.m3we.com/mathtools/gcd.php?numerator=-333&denominator=-33

Electron开发备忘

接了一个甲方的开发任务,经过选型考虑(其实是完全没有考虑),决定使用Electron进行开发。为什么要用Electron进行这次项目的开发呢?我对这个脚手架以及nodejs语言,几乎可以说是没有任何经验的。 主要考虑如下: 1、我想最终交付给用户的时候,是一个本地客户端的产品形式; 2、通过html快速实现页面、美观的页面; 3、这个产品本身就是一个BS架构的,那么在客户端这边,能够通过浏览器实现是最好的选择; 4、本来可以完全做成基于浏览器的形式,但是那会导致历史上经常遇到的问题:我无法控制用户的浏览器,尤其是一些“领导”们使用的浏览器,往往都是很陈旧的,页面表现会不一致。 暂且处于如上考虑,今天使用Electron搭建了一个基本开发环境,并且做了一些粗糙的页面,响应了页面上的事件,引入BootStrap5对页面进行美化,尝试了将项目make成exe运行包。感觉一切都可以接受。 另:当前开发环境在软件运行时,可以从login页面的底部看到。 一、项目存放路径: ~/Desktop/electron-app/my-electron-app 二、启动项目命令: npm run start 三、打包项目命令: npm run make 四、打包时为什么没有将bootstrap5的样式打入运行时的包中? 运行提示:filed to load resource net err_file not found…