处理过程和FireCtlGotFocus事件。
五、响应键盘和鼠标事件
许多控件需要让用户利用箭头键改变显示,比如在文本之间移动作为插入点的闪烁线条,或是在容器内移动以获得更好的定位精度。然而,有时容器也利用相同的按键,如IE使用向下的箭头键滚动HTML文档,此时控件在获得焦点时并不能够响应箭头键。
通过覆盖CWnd类的PreTranslateMessage函数可以重新收回由容器对象控制的箭头键(以及其它键)的控制权。只要监视WM_KEYDOWN消息并过滤出需要的事件,然后在需要响应某个按键的时候,调用OnKeyDown并返回True。
如果是在MDI窗口内使用ActiveX控件,而另一个窗口部分地隐藏该MDI窗口,可能会遇到另外一个问题:单击ActiveX控件并不能使MDI窗口移到最前面(即激活)。这是由于MDI窗口不能得知用户在ActiveX控件上的鼠标单击事件,因而无法作出响应并把自己设为活动窗口。
要是能够让父窗口(在这里是指MDI窗口)获知ActiveX控件上的单击事件,就可以解决这个问题。一个简单的办法是由控件发送WM_ PARENTNOTIFY消息给父窗口以通知该鼠标单击事件。WM_ PARENTNOTIFY消息在控件被创建、破坏或用户在控件上按鼠标键的时候发送。通过设置合适的扩展风格位,可以确保用户按鼠标键时控件发送该消息。首先覆盖控件的PreCreateWindow虚函数。传递给这个函数的参数CREATESTRUCT包含dwExStyle成员,使用该成员可以检查或修改用于创建控件的扩展风格位:
BOOL CCtrl::PreCreateWindow(CREATESTRUCT& cs){
cs.dwExStyle &=
~WS_EX_NOPARENTNOTIFY;
return
COleControl::PreCreateWindow(cs);}
这个修改导致用户在控件上按鼠标键时控件的缺省鼠标处理过程发送WM_PARENTNOTIFY消息,父窗口可以利用这个机会激活自己。
六、使用常量
另一个有关容器的问题涉及到常量处理。OLE控件经常有以枚举量为值的属性。例如一个叫ScrollBars的属性使用下列枚举量,必须在部件类库定义:
typedef enum {
sbNone = 0,
sbAutomatic = 1,
sbAlwaysOn =2,} ctlScrollBarConstants;
然而,并非所有的容器能够读取这些枚举定义以用于开发环境(如VBScript)。作为一个控件开发者,可以提供一个附加的文件用于定义这些常量在不同开发环境下的值,或者提供另外的方法来获得这些枚举量。对于后者,具体实现时可在控件中加入对应于枚举量的方法。
例如,可以加入三个方法:sbNone、sbAutomatic、sbAlwaysOn,它们的返回值分别对应于枚举量:
short CCtrl::sbNone (){
return 0;}
short CCtrl::sbAutomatic (){
return 1;}
short CCtrl::sbAlwaysOn (){
return 2;}
在此基础上就可以使用这些方法在任何开发环境(容器)设置ScrollBars的属性了:
ctl.ScrollBars = ctl.sbAutomatic