All Stories
我的N73是2007年6月买的,由于一直把它装在一个硬质小挎包里,从去年开始,键盘上的按键就开始一个一个掉落了,最开始是5,最中心的一个,然后沿着这个5把4,7,8,*,0都掉了,今年5月买了个5230后,就让N73光荣退役了。
从上海回来后,就一直把N73丢在书柜上,前天突发奇想,在淘宝搜索了一下,果然有N73的键盘卖,想去年去深圳华强北的电子市场找了半天都没找到。于是马上订了一块,定价20,快递6块,从广东寄过来。今天早上有电话打来,是申通快递,说是我填的那个地址他们不送到,要我自己去取,好远的,一直在汽车西站再过去几百米的地方。自己开车都20多分钟,不过倒是通过电话指引找到他们的分拣处了。
拿回来后,照网上的拆机视频,用一张硬质的卡,可以是各种商家的VIP卡,也可以是IC卡或银行卡,将前面的面板拆下,把新键盘装回去,再将面板盖回去,哈哈,又跟新的一样啦!就给我妈用吧,原来她在用的那个Nokia不知道什么型号的电池鼓起来了,不好再用了。
这两天想试一下把手头这个用wxWidgets开发的工程移植到Linux和Mac,不过遇到了些困难。
该工程使用wxWidgets作为主GUI Framework,又嵌入了Lua解释器,将一部分界面和逻辑使用Lua脚本实现,而Lua脚本大量使用了wxLua以及诸如LPeg之类的第三方库,除此之外,主程序还使用了Boost、wxFlatNotebook、wxScintilla、wxPropertyGrid等第三方库。
主要的困难在移植到Mac上。目前我使用的wxWidgets是2.8.11版本,该版本在Mac上只有32位Carbon API版本,而编译Lua和其他第三方库默认出来的全是64位的,wxWidgets官方的消息是2.9.x版本有64位Cocoa API版本,但现在不稳定,还没正式发布。于是我无奈了!试了一下2.9.1的wxMSW,编译wxFlatNotebook和wxPropertyGrid都不能通过,懒得折腾了,打算等3.0版本正式发布了再说吧,说是希望2010年底前发布,鬼知道到底什么时候能出来啊,现在越来越觉得wxWidgets不给力了,各方面的!
至于移植到Linux上,以及将其他的Lua第三方库编译出来这些事现在倒是可以做。
一直用GCC 4.4.0,之前也尝试过将sf.net上MinGW的各个包下载下来后解压覆盖到4.5.0,但最后编译我的工程时总是std::basic_string什么的一些libstdc++-6中的一些符号链接有问题,于是就搁置下来了。
今天偶然到了mamedev.org上看了看,发现它用的是4.4.3,于是想试试,后来干脆又去sf.net上找官方MinGW的文件来看,居然发现一个叫MinGW-Get的在线安装程序。MinGW很喜欢提供在线安装工具,而很少提供打包好的整体的解决方案,这是让我觉得很困惑的一件事,它的在线安装工具下载速度一直以来实在不能恭维。今天试了一下MinGW-Get,下载速度还能忍受,不过第一次仍然有好几个包下载失败,又装了第二次,才把所有选中的包都下载来了。然后把新下载的文件都覆盖到原来4.4.0的目录中,开始编译测试。
我的工程不大,才约5万行C++代码(不包括使用工程生成的代码),但依赖于一些第三方库,比如wxWidgets,Boost,以及几个wxCode中的子库。编译wxWidgets很顺利,发现在Windows下wxWidgets的表现确实很不错,有各种编译套件可用的工程文件和makefile,至少我用MSVC和GCC基本没遇到过问题。然后是编译Boost,前两天开发的时候发现用1.44.0的Boost,用MinGW编译Thread有问题,有个符号在链接时找不到,问题在这个ticket里有描述,于是仍然在用1.43.0的Boost,编译是可以正常通过了,不过最后使用的时候有点问题。拉下来是编译各个wxCode的组件,包括wxPropertyGrid、wxScintilla、wxFlatNotebook,另外还有Luabind,这些也都比较顺利,唯一有点麻烦的是,由于我是使用了Boost的bjam作为编译工具,而不是传统的make什么的,bjam有个很奇怪的行为是会把编译过程中生成的.o文件都存入到一个深深的目录中,目录路径中包括编译器名,版本号,链接类型,线程模型,debug/release模式以及项目名称,而wxScintilla中由于编译出来的.o文件比较多,最后链接的时候居然报命令行太长而命令不能执行,真是太囧了。
最后是编译我自己的工程,该工程是一个exe文件,需要链接前面提到的这些库,在链接阶段就会报出一堆关于std::basic_string等等的符号什么的警告,这些还不是很碍事,比较严重的是说Boost.Thread里有个叫_tls_used的符号与libmingw32.a里的重定义冲突了,问题在这个ticket中有描述。这个问题以前也遇到过,是MinGW使用的mingwrt 3.18中引入的,只要降级到3.17就行了,还有个办法是打开Boost.Thread中tss_pe.cpp,将那个名为_tls_used的函数屏蔽掉也可以。
编译后发现,生成的exe不依赖于原来的mingwm10.dll了,多了个对libstdc++-6.dll的依赖,其他的倒好像没什么大的变化,只是dll都变过了,需要跟着更新。
将MinGW中的GCC升级到4.5.0顺利完成!
之前我说过,作为一个文本编辑器,一个IDE,不能通过命令行参数打开一个文件,是很说不过去的。前面试图加入这个功能,结果遇到了些问题,经过昨天和今天的奋战,终于搞定了。
其实就是发现用wxWidgets的IPC机制怎么都不能正常运行,于是最后我想到了直接用Boost的InterProcess库,这个库也是跨平台可移植的,基本处于符合我的要求的范围内。
昨天还一直没死心,希望能用wxWidgets的IPC类搞定,结果果然无论是用DDE还是用Socket,都有问题。今天下定决心,先看了一下Boost的资料,发现其实很简单,InterProcess只是实现了共享内存的部分,再加上一点同步相关的机制,用于通知,于是只要在最老的进程中启动一个线程无限循环等待其他进程的通知,有了通知就从共享内存中读取文件路径信息,然后就可以打开了。
顺便说一下,Boost.InterProcess的共享内存类封装得比较底层,有一个类是纯粹的对系统的C API用C++类包装了一下。另一个稍微高级一点,但也是C++语言层面的高级,感觉缺少对现实世界对象的抽象。我有点奇怪自己现在怎么会考虑到这个层面的东西,大概是因为看了一段时间的Qt的文档和代码,Qt在这方面的工作确实做得很好啊。
还有个之前说到的,在wxApp::OnInit方法中,创建完主窗口后,直接打开文件也崩溃的问题,其实是当时测试的时候没有把配置文件放在正确的配置目录中,这个功能其实是没多少问题的。
总之,现在就是可以通过命令行参数指定文件打开一个文件了,然后又实现了单一进程实例,后面再要通过命令行参数打开文件,都会通过IPC机制通知最早创建的那个进程来打开文件。基本完美实现预定目标!
作为一个文本编辑器,一个IDE,不能通过命令行参数打开一个文件,是很说不过去的,于是我就想加这个功能,不料却意外地困难!
首先考虑当前没有已经运行的本程序的进程,通过命令行参数指定一个文件后,最wxApp::OnInit的最后返回前,主窗口已经正常创建显示后,可以将文件路径传递给主窗口,让主窗口打开这个文件。照理说,这应该是一个很平常很普通很正规的流程吧,结果不知道为什么,打开文件这个操作会让程序崩溃。
然后考虑当前已经有运行的本程序的进程了,这时如果再通过命令行参数指定一个文件,启动新进程,就需要让新进程通过IPC向老进程发送通知,让老进程来打开这个文件,而完成通知工作后新进程就可以退出了。这也是一个很平常很普通很正规的流程吧,于是我查阅了wxWidgets的关于IPC的文档和sample代码,感觉还是很简单的。在Windows平台上有两种选择,分别是基于DDE的实现和基于Socket的实现,可以用相同的代码,最终通过预定义宏来开关选择,可是最终仍然是问题重重。使用基于Socket的实现,进程在第一次启动时,Windows会弹出消息框询问是否允许该程序在本地打开一个网络端口进行监听,这就已经有点小题大做了。然后当新进程给老进程发送通知时,老进程不是没反应,貌似根本没收到通知,就是崩溃!如果切换成基于DDE的实现,倒是老进程能收到通知,但有个很奇怪的现象是从收到通知开始的那个wxDDEConnection::OnExecute函数开始往下走,wxChar*或wxString不能正确转换为const char*(因为我是使用Unicode编译项目,而字符串要以const char *传递给内嵌的Lua解释器),反正就是无论用wxString::mb_str(),还是直接的wxConvLocal::cWC2MB()都不能正确返回转换后的const char*。试了一下C runtime中的wcstomb函数,倒是能正常转换。但在Lua回调宿主程序导出的函数时,该函数将wxString转换为std::string作为返回值传递给Lua,无论用哪种转换方法,结果也会崩溃!
到此为止,所有尝试均告失败,加入命令行参数打开文件功能仍然没有实现,郁闷!
昨晚突然发现twitter的hosts ip不能用了,在just-ping.com里找了一遍api.twitter.com的ip,挨个儿ping了一遍,没有一个能ping通的。真是太杯具了,如果用Mac OSX,倒是没什么影响,反正我都是连上SSH后进行全局代理的,Echofon for Mac本身不能设API和Proxy,全靠这样SSH上去用的。但在Windows下就很无奈了,我一般用TweetDeck或Seesmic Desktop2,这两个东西一个用的是Adobe AIR,另一个是用Microsoft Silverlight,也都不能设置Proxy,而且Windows貌似也没有可以将SSH设置成全局代理的功能,于是头疼了。办法是有的,可以用SocksCap之类的东西单独设置某个程序进行Proxy,唉!
我得加快动作了。
上午大牛在twitter上DM我,说他升级了,6号时小吉给他生了个儿子。恭喜一下。
前些日子小思思发短信说生了个女儿的,而且还是比预产期晚了10天的,前天还用邮件给我发了张小侄女的照片。眼睛黑黑亮亮,脸圆圆肉肉,好可爱的。
再之前,大约半年前,孙同学和薛mm也发短信来说过生了女儿和儿子。
呃,我们这批同事中,大概最早的是宣宣的女儿了。
真是一帮幸福的人哇!
突然想再整一下wxMac,之前曾经编译过,也编译出静态链接和动态链接的库了,记得也生成samples的可执行文件了,今天找了一下,那些samples的可执行文件找不到了,随便敲了下make,发现连头文件都没有找到,应该是wx-config没正确执行。然后好奇看了一下readme,赫然发现wxWidgets/Mac doesn't come with any guarantee whatsoever. It might crash your harddisk or destroy your monitor. 这个太夸张啦,不敢用啦,甚至开始觉得是不是以后别的用wxMac开发的程序也要先检测一下然后不用了呢!那个杯具的CodeLite和Code::Blocks都是用wxMac的呢!反正我是不想再用了。
下午尝试给CodingStudio加入命令行打开文件的功能,可是怎么整都是搞得程序启动就崩溃,郁闷了!
于是很有些后悔当初采用了wxWidgets,而不是Qt。但是想想以当时的情况,确实再来一次,很可能还是不会用Qt。当初对Qt很是不满意它对所有控件都是自绘,而不是native的,而且觉得Qt需要moc一下很无语。最关键的是当时参考了大量CodeLite和Code::Blocks的源代码,没办法啊,对于一个新接触的GUI framework,这是最直接有效的办法了!
哦,对了,今天的消息,国人得到Nobel Peace Prize了,具体情况,咳咳,不明真相的童鞋,需要当一回红杏。
Saezuri是个UI设计得很精致的Twitter客户端,作者是个日本人,基于Adobe AIR开发。
Saezuri支持多账号,但添加账号的方式稍显繁琐,一方面需要Saezuri本身可以访问twitter.com,另一方面还需要浏览器可以访问twitter,以获取一个PIN号,将该PIN号填入Saezuri中才能使用该账号。而像Seesmic Desktop、Echofon for Mac、TweetDeck等都只要在客户端内填入用户名和密码就可以搞定。
Saezuri使用单列显示方式,跟Echofon类似,不过Saezuri在浏览用户profile和对话时,只是切换当前窗口内容,不像Echofon会在旁边弹出个小窗口。
比较不好的是,貌似Saezuri没有快捷键支持各种常见操作,全都通过快捷按钮完成。而且每次RT都需要用户选择是官方RT还是编辑后再发布,这点不太好,而且有个小问题是,如果用户设置了protected,就两种方式的RT都不可以了,而Echofon则只是屏蔽掉官方RT,在非官方RT时会弹出消息框提示该用户设置了tweet保护。个人感觉Echofon的实现更合适一点。
目前Saezuri还不支持Streaming API,可以设置每次新发推后自动刷新Timeline,在这点看来,这体验果然不如Echofon好,不过对于没用过实时更新的用户来说,其实并不太在意这个。
最后说一下,Saezuri是完全免费的,没有Echofon那样的广告,对Twitter功能的实现比较完整,如果它可以使用Streaming API,再加上那些操作快捷键,就比较完美了!