After getting the basic page analysis working, I wanted to use the information I was gathering, so the next step was to get the hot-key commands working.
There are different ways to do this, depending on what you need. Sven describes how to capture all key events in IE from a BHO, even if the focus is on the address bar. Looking at that made my head hurt, it needs some thread-local variables and mapping to remember which thread is associated with which document.
Luckily, I realized that my needs were a bit simpler. I’m happy to have my commands only work when the focus is on the document itself, which meant I could use the DOM event handlers exposed through IHTMLDocument2 to capture key events.
Attaching a C++ callback to an event handler in the MS DOM is not trivial, and involves some COM boilerplate, but I had a helper class I use to capture onclick events for elements. I’ll cover that along with the rest of my DOM helper functions in a future post.
Reusing that, getting called when a key event occurred was quite easy, though one wrinkle I hit was that onkeypress doesn’t get called for all keys, such as those produced when control is held down. I worked around this by synthesizing an equivalent using onkeydown/up, since they do get called for all keys.
One odd thing about these handlers in IE is that they don’t get passed the event information directly as a parameter. Instead you have to ask the current window what the last event was, and pull the information from that. To get the current window, you have to ask the document, and to get the document, I had to query the browser, since that’s all I store in my class, so the code is a bit verbose. It does the job thought, even if it is uglier than I’d like.
The next hurdle was working out the key codes for the events I was interested in. Here’s what I found for the unusual keys I needed:
- Left Arrow = 37
- Up Arrow = 38
- Right Arrow = 39
- Down Arrow = 40
- Control+Equals= 187
- Control+Forward Slash = 191
I then added a giant switch statement to handle all the key combinations I was interested in, and call the right functions. Once that was wired up, I also implemented saving the enabled state of the add-on in the registry, so users can turn it off when they’re not using it, and it will still be off when they restart IE.