Friday, December 22

brew程序的入口点

一个brew程序的真正入口点在AEEModGen.c里面

#ifdef AEE_LOAD_DLL
__declspec(dllexport) int AEEMod_Load(IShell *pIShell, void *ph, IModule **ppMod)
#else
#if defined(BREW_MODULE) || defined(FLAT_BREW)
extern int module_main(IShell *pIShell, void *ph, IModule **ppMod);
int module_main(IShell *pIShell, void *ph, IModule **ppMod)
#else
int AEEMod_Load(IShell *pIShell, void *ph, IModule **ppMod)
#endif
#endif
{
// Invoke helper function to do the actual loading.
return AEEStaticMod_New(sizeof(AEEMod),pIShell,ph,ppMod,NULL,NULL);
}

可见模拟器通过DLL的公开函数AEEMod_Load进入初始化阶段

brew各个模块之间可以进行消息传递函数回调, 而每个模块都可以单独编译不需要连接lib, 是因为各个模块实际公开的都是函数指针, 类似于
#define ISHELL_SendEvent(p,cls,ec,wp,dw) GET_PVTBL(p,IShell)->SendEvent(p,0,cls,ec,wp, dw)

AEE环境给每一个module都传入IShell指针, 在程序里如果想调用其他模块, 需要首先通过ISHELL_CreateInstance创建一个新的实例。
ISHELL_CreateInstance没有代码可看, 可以猜测AEE通过给出classid, 到自己维护的classid表里找到需要dll(module), 调入内存, 执行公开函数AEEMod_Load做初始化

AEEMod_Load-> AEEStaticMod_New设置modFuncs->CreateInstance = AEEMod_CreateInstance
随后AEE调用这个指针,在AEEMod_CreateInstance里面完成调用AEEClsCreateInstance的任务, classid这时候作为参数传进来
在AEEModGen.h里面有AEEClsCreateInstance函数的声明, 这个函数的定义需要在自己的程序里面完成。
int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *pMod, void **ppobj);

如果一个module里面定义了多个class就需要判断classid的值,创建不同的实例。

在初始化代码里
if (NULL == (pme = (AEEApplet*)MALLOC(nSize + sizeof(IAppletVtbl))))
return FALSE; //分配空间,nSize代表CAPP的空间大小!!
appFuncs = (IAppletVtbl *)((byte *)pme + nSize);
这两句表明在applet的结构体后面就是IAppletVtbl

appFuncs->AddRef = AEEApplet_AddRef;
appFuncs->Release = AEEApplet_Release;
appFuncs->HandleEvent = AEEApplet_HandleEvent;

在AEEApplet_HandleEvent里面将IApplet指针转换成AEEApplet指针,然后调用AEEApplet的pAppHandleEvent
之所以可以这么转换是因为AEEApplet的第一个成员就是IApplet指针的地址。结构体的第一个成员的地址就是这个结构体的地址。

INIT_VTBL(pme, IApplet, *appFuncs);
这一句使的AEEApplet结构体的第一个成员指向applet结构体后面的IAppletVtbl

Tuesday, December 5

突然想起若干年前某些华人的卑劣

1999年在日本,我第一次搬家。打登载在中文报纸上帮助搬家的人的电话, 电话里的声音听上去很朴实。搬家当天那个人开了一辆面包车来, 一开始并没有说什么。等你家当装在了他的车上, 开车途中, 露出了本像。先套话看你是不是黑户口, 然后用骂骂咧咧的语言, 讲他家开的是风俗店, 差点明说他就是黑社会。让我多交搬家费, 后来当着我一位女同事的面,讲黄色笑话。

2000年陪老婆去参加日语一级考试。校门口,韩国老生摆起桌子提供饮料为韩国学生鼓劲。零散的几个中国妇女往学生手里塞F:L-G的传单。

Friday, December 1

Vista冲击

刚刚看了微软Vista中国发布现场实况。
http://wmv.it168.com/others/06.11.30/Windows.wmv

加上前一段时间ms放出的vista sdk+.net framework 3.0,
http://www.microsoft.com/downloads/details.aspx?FamilyId=C2B1E300-F358-4523-B479-F53D234CDCCF&displaylang=en

我认为vista将迅速普及。这里有两方面的原因
1,面向家庭用户, vista的交互界面对用户的吸引作用,加上硬件的需求很高, 使得intel和dell这样的硬件厂商非常热衷于推广它。推动用户更新电脑就意味着更高的收益。
2,面向企业用户,vista sdk和.net framework 3.0的捆绑对于企业软件提供商有很大吸引。特别是缺少积累的中小软件开发商,因为开发成本降低和用户体验大幅提高, 市场竞争将会更加激烈。

纯技术观点
在vista下运行你的软件, 这个blog显示了可能会存在的一些问题
http://blogs.itecn.net/blogs/winvista/archive/category/1095.aspx

给我印象深刻的是这篇文章
http://blogs.itecn.net/blogs/winvista/archive/2006/09/03/3604.aspx

如果你从一个程序员的角度暂时没有感到冲击,那没什么不正常。因为你还没有面向vista编程。注意vista改变了一些东西,加强了安全性。比如service将处于session 0, GUI将处于session 1, 再比如顶楼blog里提到的"虚拟重定向"。

如果你作为企业类软件的厂商暂时没感到冲击, 那说明你的嗅觉不够敏锐啊。

如果你做为普通用户没有感到冲击, 那说明你非常成熟, 一眼你就看出了新玩意的本质。可难道iPod之前就没有mp3 player吗?

Thursday, November 9

莫名其妙的糖尿病特效产品DNJ

父亲让我查一下一种叫做DNJ的糖尿病治疗产品。
在中文网站上可以找到叫做"地恩基(中国)国际医学研究院"的网站在宣传这种DNJ产品。看网站上的宣传就让人起疑。于是借助google和yahoo检索了一下, 也许是google和yahoo做的不好,并没有找到"日本糖尿病并发症研究所(JDCS)常务理事、早稻田大学名誉教授、DNJ日本国际医学研究院井上孝治博士"的任何信息, 也没有找到"日本神奈川大学桑叶研究中心"这么个机构。也没有野尻博士的什么信息。
只有DNJ这个关键词确实可以找到一些治疗糖尿病的健康食品的信息。比如这里的一些介绍。里面只是说DNJ是桑叶独有的成份,期待其成为控制血糖,减肥的健康食品素材。
一些信息显示是神奈川县卫生研究所对DNJ的抑制血糖效果作了研究。通过Google可以检索到他们的研究报告(1),(2)

我不是学医出身,只能简单看一下里面的结论。报告显示实验用白鼠在吃混有桑叶提取物的饲料40周以后,对空腹血糖的升高有明显的抑制作用。

也许这种叫做DNJ的桑叶提取物确实对糖尿病人有益, 但也不至于达到山西患者张阿姨30天逼近治愈的程度吧!

Wednesday, May 24

改变微软拼音输入法的键盘布局

从windows2000以来,在日文环境下输入中文已经不成为问题了。特别是微软中国网站还提供最新的微软拼音输入法2003下载。安装到日文windows 2000/xp上就可以轻松输入中文了。
但是,在微软拼音输入法缺省使用的是英文键盘布局,通过日文键盘输入中文的时候经常出现找不到键的情况,要想快速的使用msn messenger聊天,特别是输入表情符号的时候,头脑中需要记住英文键盘布局,还要切换自如才行。

今天经过调查研究,知道了可以修改下面的注册表,来改变微软输入法的键盘布局。在日文键盘的环境下,将
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\E00E0804
的Layout File的值改为kbdjpn.dll,再启动机器,应该可以成功地达到目的。

注册项Keyboard Layouts下的键值里面,以0804结尾的是简体中文,0404是繁体中文,更多国家代码参见:Configuring and Using International Features of Windows: Windows 2000 - List of Locale IDs and Language Groups

以上办法也总不灵验,极端大法是用系统目录system32下的kbdjpn.dll代替同目录下的kbdus.dll文件。以WindowsXP为例,首先将C:\WINDOWS\system32\kbdjpn.dll拷贝到C:\下,改名为kbdus.dll,然后考回C:\WINDOWS\system32目录,覆盖原来的kbdus.dll。重启机器。

以上办法在Windows XP日文版和Windows 2003英文版实验成功。

Tuesday, February 14

避免IE窗口的双重启动

很多项目中有避免IE窗口的双重启动的需求。
具体而言就是通过一个链接打开的窗口,因为可能已经输入了一部分资料而还没有提交给服务器,如果再此点击同样的连接,不能轻易轻易就将已经打开的窗口替换。另外也要避免未保存就直接关闭窗口的情况。窗口关闭的时候要同服务器交互,通知服务器。下面的几个要点可以避免发生问题。*只在IE6上做了测试
1,使用window.open方法打开新窗口。这个方法的第二个参数是target,如果target的名字一样,不同连接或者相同链接打开的页面会在同一个IE窗口中显示。
2,IE窗口中的页面迁移,更新,提交,窗口的关闭都会触发onbeforeunload这个事件。在这个事件中设置确认消息。如果回答OK,画面才会进行下一步的动作。
3,在关闭确认之后onunload事件会被触发,在这里通过ajax技术同服务器端进行交互。因为IE的bug,onunload事件有可能不会被触发。我们可以通过其他办法避免这个bug。

针对这项技术我可以提供一个sample和通过email的技术支持。 Need Support

Sunday, January 15

Using WTL with Visual C++ 2005 Express Edition - The Code Project - WTL

虽然我的英语不好,但是在WTL Group Members的鼓励下,还是在CodeProject上发布了自己的第一篇文章。Using WTL with Visual C++ 2005 Express Edition - The Code Project - WTL 记住发布的日子2006年1月13日。
下周去无锡出差一周,我已经很久没有回国了,希望这次工作顺利。
如果希望作更有价值的人,那么还犹豫呢? 我应该回到我的祖国。