Discussion:
Handling Control-C in a hosted web browser control
(too old to reply)
sasha
2008-10-08 19:42:46 UTC
Permalink
Hello!

I've hit a brick wall trying to handle Control-C in the IE AX control
that I'm hosting.

What I want to do is highlight text in the browser control, hit
control-c and have the text on the Clipboard.

But that doesn't work. Using Spy is see that WM_COMMAND is not generated
when Control-C is pressed. There are keydown/char/keyup messages.

I'm using CWTLAxControl for hosting the control in C++.

But when I host the control in a Delphi/BCB application, everything
works just fine - my text ends up on the Clipboard and I see WM_COMMAND
sandwitched between keydown/keyup.

Installing my own IDocUIHandler works - I get context menu
notifications. But the TranslateAccelerator is never called.

So, I suspect that I don't provide some interface or some such or don't
enable something on the IE control itself.

Any and all suggestions will be greatly appreciated.

Thanks,
.a
Igor Tandetnik
2008-10-08 19:56:04 UTC
Permalink
Post by sasha
I've hit a brick wall trying to handle Control-C in the IE AX control
that I'm hosting.
What I want to do is highlight text in the browser control, hit
control-c and have the text on the Clipboard.
But that doesn't work. Using Spy is see that WM_COMMAND is not
generated when Control-C is pressed. There are keydown/char/keyup
messages.
I'm using CWTLAxControl for hosting the control in C++.
http://www.codeproject.com/KB/wtl/cwtlaxcontrol.aspx?fid=4601&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2150307#xx2150307xx
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-08 20:37:11 UTC
Permalink
Post by Igor Tandetnik
http://www.codeproject.com/KB/wtl/cwtlaxcontrol.aspx?fid=4601&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2150307#xx2150307xx
Thank you for the quick reply, but I'm not sure where I should add this
code? Do I override a method in CWTLAxControl class? Or in the user of
CWTLAxControl (it's window parent)?

I'm not using MFC.

Thanks,
.a
Igor Tandetnik
2008-10-08 21:28:23 UTC
Permalink
Post by sasha
Post by Igor Tandetnik
http://www.codeproject.com/KB/wtl/cwtlaxcontrol.aspx?fid=4601&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2150307#xx2150307xx
Thank you for the quick reply, but I'm not sure where I should add
this code? Do I override a method in CWTLAxControl class? Or in the
user of CWTLAxControl (it's window parent)?
The parent. Derive your window from CMessageFilter, install it with
CMessageLoop::AddMessageFilter, implement PreTranslateMessage as shown
in the example.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-08 21:49:34 UTC
Permalink
Post by Igor Tandetnik
The parent. Derive your window from CMessageFilter, install it with
CMessageLoop::AddMessageFilter, implement PreTranslateMessage as shown
in the example.
Thanks. Unfortunately, I can't derive from CMessageFilter as this is in
an existing app.

Btw, there is no SendMessage() in the CWTLIExplorer from the sample...

Thanks,
.a
Igor Tandetnik
2008-10-08 21:56:19 UTC
Permalink
Post by sasha
Post by Igor Tandetnik
The parent. Derive your window from CMessageFilter, install it with
CMessageLoop::AddMessageFilter, implement PreTranslateMessage as
shown in the example.
Thanks. Unfortunately, I can't derive from CMessageFilter as this is
in an existing app.
I don't understand. You can't modify the source code? Then how do you
plan to fix anything?
Post by sasha
Btw, there is no SendMessage() in the CWTLIExplorer from the sample...
All classes derived from CWindow have SendMessage method. CWTLIExplorer
is indirectly derived from CWindow.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-08 22:57:56 UTC
Permalink
Post by Igor Tandetnik
I don't understand. You can't modify the source code? Then how do you
plan to fix anything?
I can't modify existing code to start deriving existing windows from new
bases.
Post by Igor Tandetnik
All classes derived from CWindow have SendMessage method. CWTLIExplorer
is indirectly derived from CWindow.
Yes, my mistake.

One thing that is unclear to me is how the CWTLIExplorer gets its parent
window?

I think I've done now what the sample suggests. But the problem is that
my 'parent' window doesn't get the keystrokes - they all go to the IE AX
control.
Igor Tandetnik
2008-10-08 23:12:10 UTC
Permalink
Post by sasha
Post by Igor Tandetnik
I don't understand. You can't modify the source code? Then how do you
plan to fix anything?
I can't modify existing code to start deriving existing windows from
new bases.
Why not?

If you insist, have a separate class derived from CMessageFilter, make
it as a member of your window class, and register that. Or, derive a
class from both CWTLAxControl and CMessageFilter. It doesn't matter,
CMessageFilter is orthogonal to anything else. All it has is one pure
virtual method.
Post by sasha
One thing that is unclear to me is how the CWTLIExplorer gets its
parent window?
In CWindowImpl::Create of course.
Post by sasha
I think I've done now what the sample suggests. But the problem is
that my 'parent' window doesn't get the keystrokes - they all go to
the IE AX control.
That's why you need CMessageFilter. It gets hooked into the message
pump, before message are dispatched to their destination windows.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-08 23:34:26 UTC
Permalink
Post by Igor Tandetnik
Why not?
Because nobody here will go for this. <g> It's an established codebase
that can't be changed as far as hierarchies go. Also, we don't use the
full WTL, just the CWTLAxControl-based stuff by Jesus.
Post by Igor Tandetnik
If you insist, have a separate class derived from CMessageFilter, make
it as a member of your window class, and register that. Or, derive a
class from both CWTLAxControl and CMessageFilter. It doesn't matter,
CMessageFilter is orthogonal to anything else. All it has is one pure
virtual method.
That's why you need CMessageFilter. It gets hooked into the message
pump, before message are dispatched to their destination windows.
OK. I think I could swing that.

But what about IOleInPlaceActiveObject? Could (and how ;) ) I use that
instead?

Thanks for your help,
.a
Igor Tandetnik
2008-10-09 01:36:02 UTC
Permalink
Post by sasha
But what about IOleInPlaceActiveObject? Could (and how ;) ) I use that
instead?
Not instead, but in addition to. WM_FORWARDMSG handler in CWTLAxControl
calls IOleInPlaceActiveObject::TranslateAccelerator on the control it
hosts. You can call it manually instead, if you are so inclined.

Basically, your job is to grab keystrokes at the message pump, and
forward them to TranslateAccelerator.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-09 01:58:55 UTC
Permalink
Post by Igor Tandetnik
Not instead, but in addition to. WM_FORWARDMSG handler in CWTLAxControl
calls IOleInPlaceActiveObject::TranslateAccelerator on the control it
hosts. You can call it manually instead, if you are so inclined.
Maybe I'm looking at the wrong CWTLAxControl, but I don't see such
code. Maybe I need to derive my class (the one derived from
CWTLAxControl) from CAxHostWindow or some such? In atlhost.h I see some
WM_FORWARDMSG processing and references to IOleInPlaceActiveObject
Post by Igor Tandetnik
Basically, your job is to grab keystrokes at the message pump, and
forward them to TranslateAccelerator.
Well, that seems to be the problem - the pump is inside IE AX control
and it doesn't send keystroke messages to the parent window. And I don't
seem to get to that pump.

Thanks again,
.a
Igor Tandetnik
2008-10-09 02:26:41 UTC
Permalink
Post by sasha
Post by Igor Tandetnik
Not instead, but in addition to. WM_FORWARDMSG handler in
CWTLAxControl calls IOleInPlaceActiveObject::TranslateAccelerator on
the control it hosts. You can call it manually instead, if you are
so inclined.
Maybe I'm looking at the wrong CWTLAxControl, but I don't see such
code.
Not directly - it's deep inside the framework. Look for OnForwardMsg in
atlhost.h
Post by sasha
Maybe I need to derive my class (the one derived from
CWTLAxControl) from CAxHostWindow or some such?
CWTLAxControl already uses it internally.
Post by sasha
Post by Igor Tandetnik
Basically, your job is to grab keystrokes at the message pump, and
forward them to TranslateAccelerator.
Well, that seems to be the problem - the pump is inside IE AX control
No. The pump is in your application - see CMessageLoop in altapp.h.
Controls rely on their host to pump messages for them.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-09 16:23:06 UTC
Permalink
Igor Tandetnik wrote:

I appreciate your help :)

[snip]
Post by Igor Tandetnik
CWTLAxControl already uses it internally.
It doesn's appear to in my case:

///// that's what I instantiate to host the ie ax control
class CWTLBrowser : public CWTLAxControl<CWTLBrowser, IWebBrowser2>,

/////
template <class T, class Interface>
class CWTLAxControl : public CComPtr<Interface>,
public CWindowImpl< CWTLAxControl <T, Interface>, CAxWindow>,
public CWTLDispEventHelper<T, Interface>
Post by Igor Tandetnik
No. The pump is in your application - see CMessageLoop in altapp.h.
Controls rely on their host to pump messages for them.
I don't use altapp.h.

Thanks,
.a
sasha
2008-10-09 16:30:37 UTC
Permalink
Post by Igor Tandetnik
CWTLAxControl already uses it internally.
Well, I see that some breakpoints are hit in the CAxHostWindow. I don't
know how, but they do :)
Igor Tandetnik
2008-10-09 17:44:36 UTC
Permalink
Post by sasha
Post by Igor Tandetnik
No. The pump is in your application - see CMessageLoop in altapp.h.
Controls rely on their host to pump messages for them.
I don't use altapp.h.
That is unfortunate, because it means you can't use CMessageFilter
either to hook into your message pump. You'll have to design your own
mechanism to do so.

In any case, the message pump is in your application somewhere, not in
the control. Maybe you are using CAtlExeModuleT::RunMessageLoop (see
atlbase.h), or maybe the pump is handwritten. Put a breakpoint into any
message handler, and look at the call stack to see where DispatchMessage
was called from.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
sasha
2008-10-09 17:59:38 UTC
Permalink
Post by Igor Tandetnik
That is unfortunate, because it means you can't use CMessageFilter
either to hook into your message pump. You'll have to design your own
mechanism to do so.
Yep.
Post by Igor Tandetnik
In any case, the message pump is in your application somewhere, not in
the control. Maybe you are using CAtlExeModuleT::RunMessageLoop (see
atlbase.h), or maybe the pump is handwritten. Put a breakpoint into any
message handler, and look at the call stack to see where DispatchMessage
was called from.
Yes, it's all hand-written code (and not by me <g> - I'm just trying to
solve this particular issue).

Thanks,
.a
sasha
2008-10-09 02:02:41 UTC
Permalink
Post by Igor Tandetnik
Basically, your job is to grab keystrokes at the message pump, and
forward them to TranslateAccelerator.
Maybe I need to enable message reflection on the web browser control
somehow?
sasha
2008-10-09 16:40:57 UTC
Permalink
OK, the bottom line is that the 'Internet_Explorer_Server' window gets
the keystrokes and its parent doesn't.

So, there is no chance of translating any accelerators.

I don't understand why a Delphi-based app works, though - the parent
there *does* get the keystrokes.
sasha
2008-10-09 17:40:46 UTC
Permalink
Post by sasha
I don't understand why a Delphi-based app works, though - the parent
there *does* get the keystrokes.
OK, apparently, the window proc does get hooked in the Delphi code,
that's why it works. The hooking is done in the
IOleClientSite::ShowObject implementation.
sasha
2008-10-09 23:31:32 UTC
Permalink
Well, it appears that I now successfully generate WM_COMMAND in the IE
AX control window.

Big thanks to Mr. Tandernik for his patient assistance.

I found the message pump for the window - it was buried in one of the
'sync' objects that we use (msgWaitForMultipleObjects + some other
custom code). That pump didn't call TranslateAccelerator. Now it does
:). I see WM_COMMAND is generated when control-c is pressed.

The text is still not copied, though - that's my next endeavor ;)

Regards,
.a
sasha
2008-10-10 00:15:50 UTC
Permalink
Post by sasha
The text is still not copied, though - that's my next endeavor ;)
After giving the accelerator resource the same ID that IE expects (15),
control-c is working fine now.

Regards,
.a

Loading...