浏览器编程中处理键盘消息

一般来说,一个浏览器中大致会存在哪些键盘消息呢?

1、窗口的快捷键(如菜单上的快捷键);

2、地址栏等的键盘消息;

3、浏览器窗口内。

 

据此,一个比较理想的方法流程是:用SetWindowsHookEx安装WH_GETMESSAGE钩子。这样可以钩住进程内所有键盘和鼠标消息,在得到消息后,键盘消息和鼠标消息分开处理。对于键盘消息,先判断当前的消息是否是窗口快捷键,是的话,执行相应代码,不是的话,放行。然后再看浏览器窗口当前是否获得了焦点,若是的话,再检查当前消息是不是浏览器内“ActiveObject”的快捷键,不是的话,放行。若浏览器窗口没有得到焦点,那么直接放行。

 

说了这么多,到底怎么做呢?

 

关键点之一,就是要在浏览器窗口、地址栏、搜索栏(假设有)等得到焦点的时候做个标记。这样在处理键盘消息的时候就根据焦点来决定如何处理。

 

比如“判断当前的消息是否是窗口快捷键”怎么实现?

一般用Public Declare Function CreateAcceleratorTable Lib "user32.dll" Alias "CreateAcceleratorTableA" (ByVal lpaccl As Long, ByVal cEntries As Long) As Long

这个函数来创建快捷键列表。然后用Public Declare Function TranslateAccelerator Lib "user32.dll" Alias "TranslateAcceleratorA" (ByVal hWnd As Long, ByVal hAccTable As Long, ByRef lpMsg As MSG) As Long来检测。

 

然而又如何判断“消息是不是浏览器内的快捷键”呢?

可用IOleInPlaceActiveObject的TranslateAccelerator来获得。大致如下:

Public Function FrmTranslateAccelerator(mMsg As Long) As Boolean
Static tMSG As olelib.MSG
Dim tobj As olelib.IOleInPlaceActiveObject

Set tobj = WB
If tobj Is Nothing Then
    FrmTranslateAccelerator = False
Else
    CopyMemory tMSG, ByVal mMsg, Len(tMSG)
    FrmTranslateAccelerator = (tobj.TranslateAccelerator(tMSG) = 0)
End If
End Function

 

到此为止,如果你很好的记住了当前是哪个对象获得了焦点,那么,上述思路即可很好的解决键盘消息难题。

 

WH_GETMESSAGE钩子同时得到鼠标消息,如需要处理一些鼠标消息,这里是最佳途径。比如判断当前鼠标是否在非客户区右键等等。甚至,流行的“鼠标手势”也可在这里处理。

 

在上一篇文章中,涉及了IOleInPlaceSite接口。要配合上述代码,IOleInPlaceSite_GetWindowContext中只需要处理ppDoc As olelib.IOleInPlaceUIWindow即可。因为我们已经处理了需要的键盘消息,所以不需要处理ppFrame As olelib.IOleInPlaceFrame,否则会出现问题。并且有一个严重的问题,假设你没用上述钩子,使用MDI设计浏览器,若不处理ppFrame,则浏览器窗口所有快捷键失效!若处理ppFrame,网页打开过程中,会抢占菜单的焦点。所以,为了解决这个办法,目前看来,最佳途径就是这个钩子了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值