CHyperLink类是网上普遍流传的一个超链接类。但是该类在代码中通过Create方法动态创建时会报错。原因在于创建悬浮窗口,CToolTipCtrl类的对象Create时出错。该类继承自CStaitc类。关于动态创建报错的问题,可参见网上的一些资料,如《CHyperLink动态创建时存在问题》。
原来的代码在PreSubclassWindow中有以下代码
正是Create一句出现问题。网上给出的解决方法是将上述代码放到OnCreate方法中。这样动态创建时就没有问题了,但是通过模版静态创建时又会崩溃。原因是PreTranlateMessagte中m_ToolTip的RelayEvent挂掉了。虽然可以通过判断m_ToolTip句柄是否为NULL来避免程序崩溃,但ToolTip没有创建出来,还是有bug的。
今天在网上看了一些关于OnCreate PreSubclassWindow PreCreateWindow 等方法的介绍,豁然开朗。
原来通过模版静态创建时,在PreSubclassWindow方法中创建ToolTip是没有问题的,因为此时父窗口(CHyperLink对象窗口)已经创建;但是静态创建时因为没有调用Create方法,不会产生WM_CREATE消息,OnCreate 函数是不会被调用的。因此把创建ToolTip的代码放到OnCreate 函数中,用模板静态创建对象时,ToolTip是不会被创建的。
而如果放在PreSubclassWindow 中,动态创建时,可以理解为父窗口还未完全创建好,导致 m_ToolTip.Create(this); 一句挂掉了。
那么能不能修改成既支持动态创建又支持静态创建的呢?
查了一些资料,找到一个不太美观但比较实用的方法。就是为CHyperLink设置一个标识标量BOOL m_bDynamicCreate,默认FALSE.重载Create 和 CreateEx 函数,将m_bDynamicCreate位置TRUE. 将创建ToolTip的代码封装到一个函数中。
修改PreSubclassWindow,判断如果是动态创建就创建ToolTip;然后再在OnCreate中也创建一次,这样就保证同时支持静态和动态创建。