Solved

Overriding of SHIFT in webbrowser control !

Posted on 2004-04-24
27
592 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:mrwad99
  • 12
  • 12
  • 2
  • +1
27 Comments
 
LVL 4

Expert Comment

by:r2far
ID: 10912552
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 =)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10912662
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.
0
 
LVL 4

Expert Comment

by:r2far
ID: 10913065
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...
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10913197
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().
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10913221
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!
0
 
LVL 4

Expert Comment

by:r2far
ID: 10913304
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.
0
 
LVL 4

Expert Comment

by:r2far
ID: 10913315
Try Tracing or break-points to see if the PreTranslateMessage is called for your shfit+click event on the web control.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 10916210
instead of pMsg->wParam == VK_SHIFT try the following
if(GetKeyState(VK_SHIFT) & 0x80)      //true if shift key pressed
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10921289
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.
0
 
LVL 4

Expert Comment

by:r2far
ID: 10922495
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.
0
 
LVL 4

Expert Comment

by:r2far
ID: 10922544
The web browser class appears to merely be a go-between to the OLE control.
0
 
LVL 4

Expert Comment

by:r2far
ID: 10922982
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
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 10925730
<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
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 4

Accepted Solution

by:
r2far earned 500 total points
ID: 10929034
MY BAD!!!

I re-read my trap code and noticed a syntactical error on my part.  Try the following code for PreTranslateMessage() in the browser class.  This should work... it did for me, the shift+click event was suppressed.

BOOL CWebBrowser2::PreTranslateMessage( MSG* pMsg )
{
      if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
      {
            return TRUE;
      }

      return CWnd::PreTranslateMessage(pMsg);
}


*** If your lookin for my mistake, check the operators used to check the wParam for shift.  My original trap checcks for ONLY shift event, there is one bit that is always set and was causing the '==' to be false every time.  So we mask the wParam with the shift instead.


truly Sry, =(
0
 
LVL 4

Expert Comment

by:r2far
ID: 10929062
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...
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10931684
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 !
0
 
LVL 4

Expert Comment

by:r2far
ID: 10932211
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 =)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10932774
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 :)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10932835
<Zip file updated>
0
 
LVL 4

Expert Comment

by:r2far
ID: 10933179
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.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10936590
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 !
0
 
LVL 4

Expert Comment

by:r2far
ID: 10939253
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 =)
0
 
LVL 3

Expert Comment

by:kklai72
ID: 10945903
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
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10947736
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 :)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10947780
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 :)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 10947982
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.

0
 
LVL 19

Author Comment

by:mrwad99
ID: 10948868
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20972066.html

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

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Tab names are off by one 5 49
ffmpeg - "rtsp://...... Operation not permitted" 4 69
java ^ examples 8 57
mapBully challenge 6 93
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now