Link to home
Start Free TrialLog in
Avatar of mrwad99
mrwad99Flag for United Kingdom of Great Britain and Northern Ireland

asked on

Overriding of SHIFT in webbrowser control !

Hello !

I have an app that uses the webbrowser control.  Now when the user holds down shift and clicks a link, I want *my app* to handle that.  Currently, the default action is for IE to open a new instance of Internet Explorer to display the link.  I don't want this to happen; I want my app to do all the processing.

I determine if the shift key is being held down in PreTranslateMessage().

Any ideas ?

TIA
Avatar of r2far
r2far

seems like your on the right track.  All Messages, even the mouse events, go through PreTranslateMessage() before being dispatched.

What you would need to do is in PreTranslateMessage(), check for the operations you wish to trap, when the conditions are met DO NOT call the base-implementation, instead, redirect to a function you want to handle the event and then return TRUE from PreTranslateMessage() telling the que the message has already been dealt with.

Here is sample of a PreTranslateMessage() trap I use in one of my programs.  Use switchs incase you add more traps, other wise it could get pretty messy.


if( pMsg->hwnd==*this && m_bPassive )
{
   // TRAPPING EVENT HERE (look up WM_LBUTTONDOWN)
   switch( pMsg->message )
   {
   case WM_KEYUP:
   case WM_KEYDOWN:
   {
      // CHECKING OTHER CONDITIONS/STATES (check for shift being pressed, MAY NOT BE VK_SHIFT, check first)
      switch( pMsg->wParam )
      {
      case VK_SHIFT:
      case VK_TAB:
      case VK_RETURN:
         {
            // HERE IS THE RE-DIRECT,  PLACE A FUNCTION CALL HERE TO HANDLE THE EVENT
            GetParent()->PostMessage( pMsg->message,pMsg->wParam,pMsg->lParam );
            return TRUE;
         }break;
      }
   }break;
   }
}

// DEFAULT CALL TO BASE-CLASS
return CMaskEntry::PreTranslateMessage(pMsg);



Hope this helps =)
Avatar of mrwad99

ASKER

Hi r2far,

Yeah that is exactly what I am doing.  The thing is, because IE's default shift & click combination result is to open a new IE window, this happens in my app.  So the user is displaying a page in my app, holds down shift and clicks a link and then all of a sudden an Internet Explorer instance opens displaying the page.  I want *my app* to handle shift & click, not have IE do it.

I handle VK_SHIFT in my app just as you said above, but when it is VK_SHIFT the above behaviour occurs.  I could of course use another key instead of shift, but that is what I would like to handle.

Hope you see what the problem is now.
yes, i see the problem... I have never actual used the browser control before.

Which browser control are you using? "Microsoft Web Browser" under ActiveX Components?

When you added the control, it created classes associated with the browser right?  So which class are you overriding PreTranslateMessage() in?

Try the PreTranslateMessage() in the web controls main window class, and try the one in the apps main view class.

ALSO NOTE:
 pMsg->hwnd==*this   // change '*this' to the web browser control window since you want to trap it's message

and it is very important to return TRUE; after overriding a message so the system erases the message from the que.


Keep me Posted...
Avatar of mrwad99

ASKER

Right, for the sake of argument in this thread, I am using a dialogue, and the Webbrowser ActiveX control has been added to the dialogue in the resource editor. This dialogue has been associated with a class via the class wizard; it is in this dialogue class that I override PreTranslateMessage().
Avatar of mrwad99

ASKER

I tried this:

if (pMsg->wParam == VK_SHIFT) {
      if (pMsg->hwnd == m_wndBrowser) {
            m_bNewTab = TRUE;
            return TRUE;
      }
}

where the most important aspect is the setting m_bNewTab to TRUE.  Regardless of this, the link clicked on is always opened in a new IE window !

ARGHH!
you want to capture the mouse event do you not?  the mouse event includes in it's wParam any special keys pressed while the mouse clicked (including Shift).  Your code shows no capture of the event itself...  the event is stored in pMsg->message.

once again, not sure how the web control works... But IF the dialog class is responsible for dispatching the messages to the browser control (ie. messages go throught dialog before the control sees them) then the PreTranslateMessage() code should look like this to do the event trap properly (just modified your sample).

if (pMsg->hwnd == m_wndBrowser) {
     if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam==MK_SHIFT) {
          m_bNewTab = TRUE;
          return TRUE;
     }
}

** MK_SHIFT is not a mistake... it should be an 'M' in cases of mouse event special keys

You MUST check for an event (pMsg->message) otherwise you may find the trap triggering at random.  Remember wparam is re-used for each and every message, so there is no telling when wParam will have a numerically equivalent value to VK_SHIFT.  So you must first check that the event found does yield a virtual key in the wParam.
Try Tracing or break-points to see if the PreTranslateMessage is called for your shfit+click event on the web control.
Avatar of AndyAinscow
instead of pMsg->wParam == VK_SHIFT try the following
if(GetKeyState(VK_SHIFT) & 0x80)      //true if shift key pressed
Avatar of mrwad99

ASKER

OK; this is weird.

if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam==MK_SHIFT) {
      TRACE("YES !");
}

I was clicking and holding the shift key down like mad but never got YES ! to be output.  And with

if (pMsg->hwnd == m_wndBrowser) {

I dont get output either.  

Andy:

if(GetKeyState(VK_SHIFT) & 0x80)  

I got output for that, as I did when using pMsg->wParam == VK_SHIFT but again not in combination with a click on a link, or a click anywhere on the page for that matter.

Try and make a simple dialog app, add a webbrowser and see what I mean.  It is as if IE is swallowing the events up before my app gets them.
You are right mrwad99... I have never used the browser control, it appears to handle the events by itself without going through the dialog or the window class it is derived from...  I am attempting to override this problem,  but it may not be possible.

I am attempting to see if/what messages are still handled by the browser window class created when the control was added.
The web browser class appears to merely be a go-between to the OLE control.
What is happening is that the Web Browser control is acting as a self-contained ActiveX OLE control.  It is possible to link to the controls events, but I have not tried it myself.

Try this article... It appears to be based around a different VS version then mine, maybe VS .NET, so I couldn't find all the menu's and dialogs they state in the article.  It explains how to handle ActiveX events and should get you started.

http://support.microsoft.com/default.aspx?scid=kb;en-us;147740
<I got output for that, as I did when using pMsg->wParam == VK_SHIFT but again not in combination with a click on a link, or a click anywhere on the page for that matter.>

It could be being trapped by the control before you get a stab at it.  If that is the case then you probably aren't going to get anywhere with this approach
ASKER CERTIFIED SOLUTION
Avatar of r2far
r2far

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
P.S.  Yes I did not include the window trap... there are no MFC based child windows to a control so it should always be the browser window... so don't check for the window of the message in the browser class...
Avatar of mrwad99

ASKER

Sorry that still did not work for me; I added the code exactly as above into the webbrowser class but no joy.  Can you post a link to your project so I can download it and look at it fully please r2far ?

TIA !
Here is a link to my webspace with the browser control... It is just slapped together so i could see what was up with the browser control that was causing problems.

LOOK FOR: PreTranslateMessage() under the CWebBrowser2 class

http://www.neglectoid.com\Experts-Exchange\Browser.zip


The Shift+Left Click is supressed for me, so hope it works for you =)
Avatar of mrwad99

ASKER

Ok, I have tried what you have in your app and mine still does not want to play.  Here is my code:

http://mr_wad_99.europe.webmatrixhosting.net/Gui4UnexTEST.zip

Slightly different effect; basically the idea is to open new links in a new tab via shift->click, not in a new window.  But the latter is still occuring.

Can you see why ?

Many thanks in advance for all the help so far, I really appreciate it :)
Avatar of mrwad99

ASKER

<Zip file updated>
This sound like I am repetitive, but I managed to suppress the Shift + Click event by adding the PreTranslateMessage() virtual function to the CGui4UnexApp class with the code I listed at Date: 04/27/2004 07:25AM PDT.

The variance in requirements of your code and mine is a bit of a mystery... But i believe it has to do with the fact that your app is MDI.  MDI's use a slightly different command hierchy.
Avatar of mrwad99

ASKER

Yeah I agree that you can get it to work, and it is a mystery as to why you can in the dialogue based app and I cannot in the MDI app.  I will do some thinking regarding this; the overall thing I will do is probably close this question accepting your answer (in the next 48 hours) and then if I cannot see a way round it myself ask another (500pt) question as to how this can be solved.

Before I do; can you see any explanation, and can I offer you another 500 points if you can solve it ?

Thanks for the help - stay tuned here for your points !
Sry I can't explain it... In theory the PreTranslateMessage() in the CWebBrowser2 class should handle it no matter what kind of application you use.  So either I am missing something (which is possible), or we have entered one of those unexplanable voids that is microsoft.

Keep On Coding =)
you have made a serious mistake that your ContainerDlg.h include the wrong header

you have included
#include "webbrowser3.h"

but you should include
#include "webbrowser2.h"

ask me if you have questions
Avatar of mrwad99

ASKER

kklai72: thanks for that; I intitally thought that it must be that that was causing this PreTranslateMessage to fail, but alas when I changed the #include it made no difference.

However....

I found that the problem was down to the fact that PreTranslateMessage() was still active in the CContainerDlg class, meaning that

if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT) {
      MessageBox("SFS");
      m_bNewTab = TRUE;
      return TRUE;      
}                  

was still going on.  Now with this commented and the same code in the browser's PreTranslateMessage(), it seems that the code works; shift + click is suppresed correctly.  I think that this is due to the message reaching the dialogue before the browser itself; obviously returning true means that PreTranslateMessage in CWebBrowser2 is never called.  (I think; please correct me if this is wrong and agree if it is right).

So overall the problem is solved and r2far you get the points you earned.  Thank you very much indeed :)
Avatar of mrwad99

ASKER

Hang on, come to think about it, the above code was not being called as I never got the messagebox displayed.  Strange.

If anyone can explain what was happening, you get some points :)
Avatar of mrwad99

ASKER

Ok, I think the issue all along was not having

if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)

in the dialog class.  I think I was using the old version (without the &MK_SHIFT) that was failing.  Putting this in PreTranslateMessage in the *dialogue* class now makes it all work fine.

Avatar of mrwad99

ASKER

https://www.experts-exchange.com/questions/20972066/PROBLEM-Overriding-of-SHIFT-in-webbrowser-control.html

I have posted a related question here.  Advice will be appreciated :)