Alex Lin's Notes

Strategy, Execution, Communication.

概念

国际化是指为应用程序提供一个用来支持不同语言的框架的过程,在代码设计上加入能方便的移植到其他国家和地区的特性。I18n是Internationalization的简写。

本地化是使你的应用程序支持特定地区的过程,将具有国际化支持的代码翻译成本国或地区的语言,是本地用户更容易使用。l10n是Localization的简写。

支持多语言,在英语语言环境设置显示相应的英文,在汉语环境下设置显示相应的中文。

阅读全文 »

PS:本文所有$符号之后为在终端中执行的命令。

版本控制系统

版本控制

版本控制(Version Control)的作用是追踪文件的变化。为什么需要版本控制?简单说,就是当你出错了,可以很容易地回到没出错时的状态。

你可能已经在不知不觉中,布置了自己的版本控制系统。比如,创建了类似下面这样的文件名:

  • 论文_0510.doc
  • 论文_0514.doc
  • 论文_0521.doc
  • 论文_修改版.doc
  • 论文_最终不修改版.doc

这就是软件中为什么有”Save As”命令的原因。它使得你可以在不破坏源文件的基础上,得到一个类似的新文件。文件的多版本保存是一个常见问题,通常的解决办法是这样的:

  • 做一个文件备份(比如Document.old.txt)。
  • 在文件名中加入版本号或日期(比如Document_V1.txt,DocumentMarch2007.txt)。
  • 在多人编辑的环境下,共享一个文件目录,并且要求每个人编辑完以后,在文件上做出标识。

什么是版本控制系统(VCS)?

大型的、频繁修改的、多人编写的软件项目,需要一个版本控制系统(简称VCS,行话叫做”文件数据库”),追踪文件的变化,避免出现混乱。

一次典型的使用过程是这样的:

爱丽丝add一个文件(list.txt)进入repo。然后,她又把这个文件check out,做了一次编辑(在文件中加入milk这个单词)。接着,她将修改后的文件check in,并附有一条checking message(”加入了新的条目”)。第二天早上,鲍勃update了他本地的working set,看到了list.txt的最新修订版,其中包含了单词”milk”。如果他使用changelog或diff,都可以发现前一天爱丽丝加入”milk”这个词。

网上有许多VCS软件可供选择,并且都有详细的教程或手册,比如SVN、CVS、RCS、Git、Perforce等等。

版本库

版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被版本控制系统管理起来,每个文件的修改、删除,都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

阅读全文 »

树莓派基本配置

  1. 树莓派设备安装RASPBIAN系统

  2. 使用raspi-config进行配置

    参考http://blog.csdn.net/xdw1985829/article/details/38816375

  3. 更新系统到最新sudo apt-get update & sudo apt-get upgrade

安装JRE环境

sudo apt-get install openjdk-7-jre

安装MySQL

sudo apt-get install mysql-server

安装PHPMyAdmin

sudo apt-get install phpmyadmin

安装Openfire服务

下载:wget http://download.igniterealtime.org/openfire/openfire_3.10.3_all.deb

安装:sudo dpkg -i openfire_3.10.3_all.deb

打开PHPMyAdmin创建数据库

  1. 创建数据库openfire
  2. 导入数据库文件openfire_mysql.sql,可以在/usr/share/openfire/resources/database目录中,找到每一个对应数据库类型的SQL文件。这个地方我使用的是MySQL。

启动Openfire并进行初始设置

通过命令可以对Openfire服务进行启动/停止/重启/强制加载 /etc/init.d/openfire {start|stop|restart|force-reload}

通过启动sudo /etc/init.d/openfire start并访问http://[openfire server ip]:9090进行初始设置

Mac OS 10.11 Openfire无法启动问题

安装好openfire_3_10_2.dmg后,无法通过【系统偏好设置】中的Openfire图标启动服务器。
1、JDK版本:1.8.65。经测试需要JDK 1.7版本以上。
2、Openfire版本:3.10.2

最终解决办法:在终端中执行命令

1
2
3
4
sudo su
cd /usr/local/openfire/bin
export JAVA_HOME=`/usr/libexec/java_home`
sh ./openfire.sh

卸载Openfire

只需要在openfire关闭的情况下,执行以下的命令即可:

1
2
3
sudo rm -rf /Library/PreferencePanes/Openfire.prefPane
sudo rm -rf /usr/local/openfire
sudo rm -rf /Library/LaunchDaemons/org.jivesoftware.openfire.plist

在QtWebkit的QWebView加载网页的时候,会随着每加载一次网页内存就会增加。为解决这个问题可以通过以下代码解决。

1
2
3
4
5
6
7
QWebSettings::globalSettings()->setAttribute(QWebSettings::AutoLoadImages, false);
QWebSettings::globalSettings()->setMaximumPagesInCache(0);
QWebSettings::globalSettings()->setObjectCacheCapacities(0, 0, 0);
QWebSettings::globalSettings()->setOfflineStorageDefaultQuota(0);
QWebSettings::globalSettings()->setOfflineWebApplicationCacheQuota(0);
QWebSettings::globalSettings()->clearIconDatabase();
QWebSettings::globalSettings()->clearMemoryCaches();

其中
QWebSettings::globalSettings()->clearIconDatabase(); QWebSettings::globalSettings()->clearMemoryCaches();
可以在下一次加载开始前调用,每次调用后会将上一次加载过的页面内存清空。

详细解析

  1. void QWebSettings::setMaximumPagesInCache(int pages)
    设置在内存中缓存的最大页数为pages。缓存页可以在浏览历史页面的时候提供更好的用户体验。
    详细介绍参考:http://webkit.org/blog/427/webkit-page-cache-i-the-basics/

  2. void QWebSettings::setObjectCacheCapacities(int cacheMinDeadCapacity, int cacheMaxDead, int totalCapacity)
    指定已死对象的内存容大小。已死包括stylesheets和scripts。
    cacheMinDeadCapacity指定当缓存在压力下,已死对象消耗的最小字节数。
    cacheMaxDead 是当缓存没在压力下,已死对象应该消耗的最大字节数。
    totalCapacity 指定缓存全部消耗的最大字节数。
    缓存默认是开启的。通过setObjectCacheCapacities(0, 0, 0)来禁用缓存。设置非零来开启。

  3. void QWebSettings::setOfflineStorageDefaultQuota(qint64 maximumSize)
    设置新的离线存储数据库的默认最大值为maximumSize

  4. void QWebSettings::setOfflineWebApplicationCacheQuota(qint64 maximumSize)
    设置离线web应用的缓存最大值为maximumSize

  5. void QWebSettings::clearIconDatabase()
    清除图标数据库。

  6. void QWebSettings::clearMemoryCaches()
    通过JavaScript垃圾回收器和清空比如页面、对象和字体等缓存,尽可能多地释放内存。

Webkit Page Cache机制

https://www.webkit.org/blog/427/webkit-page-cache-i-the-basics/
https://trac.webkit.org/wiki/MemoryCache

参考链接

http://qt-project.org/forums/viewthread/11105
http://webkit.sed.hu/content/disabling-cache

Qt读取MS Word/Excel/Powerpoint等主要通过ActiveQt来实现。实际上是调用MS Word的ActiveX APIs。
一下代码是读取word中的所有的文本。

1
2
3
4
5
6
7
8
9
10
QAxObject wordApplication("Word.Application");
QAxObject *documents = wordApplication.querySubObject("Documents");
QAxObject* document = documents->querySubObject("Open(const QString&, bool)", m_strWordFilePath, true);
QAxObject* words = document->querySubObject("Words");
QString textResult;
int countWord = words->dynamicCall("Count()").toInt();
for (int a = 0; a <= countWord; a++){
textResult.append(words->querySubObject("Item(int)", a)->dynamicCall("Text()").toString());
}
wordApplication.dynamicCall("Quit (void)");

详细介绍:
Word程序初始化:QAxObject wordApplication("Word.Application")也可以通过QAxWidget wordApplication("Word.Application"),都是初始化com组件对象。
word程序的子对象可以通过QAxBase::querySubObject()来获得。
e.g:QAxObject *documents = wordApplication.querySubObject("Documents");
任何涉及到word对象的方法调用都可以通过QAxBase::dynamicCall ()来实现。
e.g:activeDocument->dynamicCall("Close(void)");
参考链接:
http://qt-project.org/wiki/Using_ActiveX_Object_in_QT
http://qt-project.org/wiki/Handling_Document_Formats
http://qt-project.org/wiki/Handling_Microsoft_Word_file_format
https://qt-project.org/search/tag/ms~word
http://qt-project.org/forums/viewthread/20341

解决办法

1
2
3
4
5
6
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
#if (QT_VERSION <= QT_VERSION_CHECK(5, 0, 0))
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(codec);
#endif

乱码出现的原因

QString内部采用的是 Unicode,它可以同时存放GBK中的字符”我是汉字”,BIG5中的字符”扂岆犖趼” 以及Latin-1中的字符”ÎÒÊǺº×Ö”。
当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char* 中究竟是什么编码?GBK、BIG5、Latin-1?
在你不告诉它的情况下,它默认选择了Latin-1,于是8个字符”ÎÒÊǺº×Ö”的unicode码被存进了QString中。最终,8个Latin字符出现在你期盼看到4中文字符的地方,
所谓的乱码出现了。
网上有很多方法介绍直接在main.cpp里设置:

1
2
3
4
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);

其实这在某些情况下也是有问题的,因为程序可能读到系统的中文路径,或者调用中文路径下的外部程序,这时候如果系统是gb2312就有问题了。
因为中文路径的编码是采用utf-8存到QString里的,系统读中文路径解码的时候采用的却是系统的gb2312,所以会调不起带中文路径的外部程序。
以上问题下面方法可以解决:

1
2
3
4
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());

对于外部字符串编码解码全部采用本地编码。
参考链接:http://blog.csdn.net/brave_heart_lxl/article/details/7186631

基本用法

行尾2空格 + 1回车 = 换行
连续2回车 = 空行分段
*斜体*
**粗体**
4空格 = 代码块
> = 引用
-,*,+ = 无序列表
1. = 有序列表
<http://foo.com> = 链接网址
[文字](http://url) = 链接文字
![说明](http://imgurl) = 图片

阅读全文 »

Windows API

FindWindow

  • 函数功能:该函数获得一个顶层窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数不查找子窗口。在查找时不区分大小写。
  • 函数原型:HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName);
  • 参数:IpClassName:指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobafAddAtom函数产生的全局成员。该成员为16位,必须位于IpClassName的低 16位,高位必须为 0。
    IpWindowName:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为空,则为所有窗口全匹配。
  • 返回值:如果函数成功,返回值为具有指定类名和窗口名的窗口句柄;如果函数失败,返回值为NULL。这个函数有两个参数,第一个是要找的窗口的类,第二个是要找的窗口的标题。在搜索的时候不一定两者都知道,但至少要知道其中的一个。有的窗口的标题是比较容易得到的,如”计算器”,所以搜索时应使用标题进行搜索。但有的软件的标题不是固定的,如”记事本”,如果打开的文件不同,窗口标题也不同,这时使用窗口类搜索就比较方便。如果找到了满足条件的窗口,这个函数返回该窗口的句柄,否则返回0。也可以通过SendMessage(hwnd, WM_CLOSE, NULL, NULL);来关闭窗口。

GetWindowThreadProcessId

  • 函数功能:在得到窗口句柄后我们可以通过GetWindowThreadProcessId这个函数来获得窗口所属进程ID和线程ID,从而判断创建窗口的进程和线程。
  • 函数原型:DWORD GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId);
  • 参数:hWnd:传入的窗口句柄;lpdwProcessId:返回的进程ID地址。
  • 返回值:函数返回的是窗口所属线程ID。
    这个函数可以结合FindWindow共同使用。通过FindWindow查找窗口句柄。

XULRunner 可以通过运用 Web 开发技术构建桌面应用程序。它提供了丰富的 UI 部件集,使用 XUL,可以直接与 HTML 混合使用并可大量使用 JavaScript。

基本概念

XULRunner

XULRunner是Mozilla运行包,可以启动类似Firefox和Tunderbird这样多功能的XUL+XPCOM结合的程序。它为程序提供安装、升级、删除机制。 XULRunner还会提供libxul, 它允许其它项目或产品嵌入使用谋智(Mozilla)技术。

XUL

XUL是一个Mozilla使用XML来描述用户界面的一种技术,使用XUL你可以快速的创建出跨平台,基于因特网的应用程序。基于XUL技术的应用程序可以很方便的使用好看的字体、图形以及方便的界面布局,而且也更容易部署和定制。如果程序员已经熟悉了Dynamic HTML (DHTML),那学习XUL将是更容易的事,也可以更快的开发基于XUL的应用程序。

XPCOM

XPCOM(Cross Platform Component Object Model)是一种跨平台组件对象模型,其原理与微软的COM技术类似,它支持多种语言绑定(Language Bindings)。也就是说,我们可以使用C++、JAVA、JavaScript、Python、Ruby、Perl等语言来编写组件。而XPCOM的接口是用一种叫做XPIDL的IDL(Interface Description Language)来定义的。
XPCOM 本身提供了一套核心的组件和类,用于诸如内存管理,线程,基本数据结构(strings, arrays, variants)等 。但是大部分的XPCOM组件并不是这个核心库提供的,而是由很多第三方的平台(例如Gecko或者Necko)提供,或者由一个应用,甚至一个扩展提供。

应用程序目录结构

XULRunner应用、扩展和主题都共享相同的目录结构,并且这样的目录结构某些时候还可以用于像可安装应用扩展那样的独立XULRunner应用。

0%