mrwad99
asked on
PROBLEM: Overriding of SHIFT in webbrowser control
This is related to a previous question (http:Q_20966269.html) where I asked how to prevent shift->left click on a link opening a new IE window displaying the link when using a webbrowser control in my app. I got the answer, but am now finding a new problem:
Thanks to the solution posted at the question linked to above, In my app (dialogue based for the sake of argument) I have
BOOL CContainerDlg::PreTranslat eMessage(M SG* pMsg)
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT) {
m_bNewTab = TRUE;
return TRUE;
}
//...
}
which traps all shift->left click combinations. But the issue is, I need to determine the URL that was going to be navigated to (if it was a hyperlink that was clicked on) so my app can handle that. This was previously done in OnBeforeNavigate().
So how can I still allow OnBeforeNavigate to be called, *without opening a new IE window* ? I thought I could post an 'OnBeforeNavigate' message or similar, but don't really know how to do this.
Any info greatly appreciated.
Thanks to the solution posted at the question linked to above, In my app (dialogue based for the sake of argument) I have
BOOL CContainerDlg::PreTranslat
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT) {
m_bNewTab = TRUE;
return TRUE;
}
//...
}
which traps all shift->left click combinations. But the issue is, I need to determine the URL that was going to be navigated to (if it was a hyperlink that was clicked on) so my app can handle that. This was previously done in OnBeforeNavigate().
So how can I still allow OnBeforeNavigate to be called, *without opening a new IE window* ? I thought I could post an 'OnBeforeNavigate' message or similar, but don't really know how to do this.
Any info greatly appreciated.
What happens if you remove the MK_SHIFT bit from the pMsg->wParam and let the default behaviour take place
ASKER
With:
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam) {
nothing happens
with
if (pMsg->message == WM_LBUTTONDOWN) {
nothing happens. This will be as a result of the browser getting the WM_LBUTTON down message immediately when the usr clicks a hyperlink. No further processing is done due to the
return TRUE;
...however, without this a new browser window is opened to display the link; not what I want.
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam) {
nothing happens
with
if (pMsg->message == WM_LBUTTONDOWN) {
nothing happens. This will be as a result of the browser getting the WM_LBUTTON down message immediately when the usr clicks a hyperlink. No further processing is done due to the
return TRUE;
...however, without this a new browser window is opened to display the link; not what I want.
hm ... I'm not sure if I understand your problem correctly ... as I understand it you simply want that clicking with hold SHIFT does the same as without ...
In this case you could simply do something like:
BOOL CContainerDlg::PreTranslat eMessage(M SG* pMsg)
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
{
pMsg->wParam &= ~MK_SHIFT; // remove the shift-flag from the message ...
}
//...
}
hope that helps,
ZOPPO
In this case you could simply do something like:
BOOL CContainerDlg::PreTranslat
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
{
pMsg->wParam &= ~MK_SHIFT; // remove the shift-flag from the message ...
}
//...
}
hope that helps,
ZOPPO
ahh :)
now I saw that AndyAinscow told you to do the same ... you just misunderstood him I think ...
now I saw that AndyAinscow told you to do the same ... you just misunderstood him I think ...
You have stripped out the shift bit in the pMsg->wParam have you?
Well, mrwad99 wrote
>if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam) {
I guess he just stripped out the WM_SHIFT from the 'if' :)
>if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam) {
I guess he just stripped out the WM_SHIFT from the 'if' :)
ASKER
Right, I am not sure that I understood Andy either, but I am not sure that anyone understands the problem. It is a little difficult to explain, so I am going to be verbose now in the hope that someone can help.
My app is the MDI version of msdn.microsoft.com/msdnmag /issues/06 00/Wicked/
You can see that this app uses a custom CTabView class. Now, to begin with my app has one tab containing an ActiveX webbrowser control that displays web pages. The idea is that when the user clicks a link whilst holding down the shift key, my app opens a new tab to display the page. The current behaviour is that a new IE window is opened hence meaning my app loses the focus (literally). What I asked in the previous question told me how to to trap the shift->click combination, but at the time I did not realise that no more messages would be sent due to returning TRUE.
This is a problem since to obtain the URL that the user clicked on means trapping the OnBeforeNavigate message generated by the browser control:
OnBeforeNavigate2Explorer1 (LPDISPATC H pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel)
Where I get hold of the URL to be navigated to via something like URL->bStrVal. Hence all I have to do is open a new tab and navigate the browser control of that tab to this URL. But this cannot happen, since as soon as I return TRUE from PreTranslateMessage (as above, that traps the shift->click combo) no more messages are apparenly sent, let alone BeforeNavigate one. (I have traced, ran to the "return TRUE" in PreTranslateMessage then told the compiler to run to the cursor - which I have placed in OnBeforeNavigate - and it does not get there unless I click a hyperlink *without holding down shift*).
So in essence I just need to stop IE opening a new window on shift->click *but still get hold of the OnBeforeNavigate message*.
I have doubled the points since I forsee this being a tough one.
My app is the MDI version of msdn.microsoft.com/msdnmag
You can see that this app uses a custom CTabView class. Now, to begin with my app has one tab containing an ActiveX webbrowser control that displays web pages. The idea is that when the user clicks a link whilst holding down the shift key, my app opens a new tab to display the page. The current behaviour is that a new IE window is opened hence meaning my app loses the focus (literally). What I asked in the previous question told me how to to trap the shift->click combination, but at the time I did not realise that no more messages would be sent due to returning TRUE.
This is a problem since to obtain the URL that the user clicked on means trapping the OnBeforeNavigate message generated by the browser control:
OnBeforeNavigate2Explorer1
Where I get hold of the URL to be navigated to via something like URL->bStrVal. Hence all I have to do is open a new tab and navigate the browser control of that tab to this URL. But this cannot happen, since as soon as I return TRUE from PreTranslateMessage (as above, that traps the shift->click combo) no more messages are apparenly sent, let alone BeforeNavigate one. (I have traced, ran to the "return TRUE" in PreTranslateMessage then told the compiler to run to the cursor - which I have placed in OnBeforeNavigate - and it does not get there unless I click a hyperlink *without holding down shift*).
So in essence I just need to stop IE opening a new window on shift->click *but still get hold of the OnBeforeNavigate message*.
I have doubled the points since I forsee this being a tough one.
ok ... so I think this should do it:
BOOL CContainerDlg::PreTranslat eMessage(M SG* pMsg)
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
{
m_bNewTab = TRUE;
pMsg->wParam &= ~MK_SHIFT; // remove the shift-flag from the message ...
}
//...
}
this will set the m_bNewTab = TRUE; which I think you check later to see if SHIFT was pressed, then it removes the SHIFT-bit from the
message and passes it to the default message processing, so the message is manipulated to be a simple WM_LBUTTONDOWN without SHIFT
ZOPPO
BOOL CContainerDlg::PreTranslat
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
{
m_bNewTab = TRUE;
pMsg->wParam &= ~MK_SHIFT; // remove the shift-flag from the message ...
}
//...
}
this will set the m_bNewTab = TRUE; which I think you check later to see if SHIFT was pressed, then it removes the SHIFT-bit from the
message and passes it to the default message processing, so the message is manipulated to be a simple WM_LBUTTONDOWN without SHIFT
ZOPPO
Hi Zoppo - you could be right there.
This is what I meant (altough one could use a bitwise modifier if one wished)
BOOL CContainerDlg::PreTranslat eMessage(M SG* pMsg)
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT) {
pMsg->wParam -= MK_SHIFT; //REMOVE THE BIT SETTING THE SHIFT
//DO NOT RETURN HERE - let the default behaviour take place
}
//...
}
This is what I meant (altough one could use a bitwise modifier if one wished)
BOOL CContainerDlg::PreTranslat
{
///...other tests
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT) {
pMsg->wParam -= MK_SHIFT; //REMOVE THE BIT SETTING THE SHIFT
//DO NOT RETURN HERE - let the default behaviour take place
}
//...
}
ASKER
Sorry folks but that still does not work. Shift->Click still opens a new browser window:
http://mr_wad_99.europe.webmatrixhosting.net/Gui4UnexTEST.zip
http://mr_wad_99.europe.webmatrixhosting.net/Gui4UnexTEST.zip
Well, it of course maybe that the control check the pressed-state of the SHIFT key in another way ...
you could simulate a temporary release of SHIFT while the message is processed, i.e.
BOOL CContainerDlg::PreTranslat eMessage(M SG* pMsg)
{
///...other tests
BOOL bShiftReleased = FALSE;
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
{
m_bNewTab = TRUE;
pMsg->wParam &= ~MK_SHIFT; // remove the shift-flag from the message ...
bShiftReleased = TRUE;
keybd_event( VK_SHIFT, 0, KEYEVENTF_KEYUP, 0 ); // simulate SHIFT release
}
BOOL bRet = CHtmlDialog::PreTranslateM essage( pMsg );
if ( FALSE != bShiftReleased )
keybd_event( VK_SHIFT, 0, 0, 0 ); // simulate SHIFT pressed again ...
//...
}
ZOPPO
PS: The link you posted above doesn't work for me ...
you could simulate a temporary release of SHIFT while the message is processed, i.e.
BOOL CContainerDlg::PreTranslat
{
///...other tests
BOOL bShiftReleased = FALSE;
if (pMsg->message == WM_LBUTTONDOWN && pMsg->wParam&MK_SHIFT)
{
m_bNewTab = TRUE;
pMsg->wParam &= ~MK_SHIFT; // remove the shift-flag from the message ...
bShiftReleased = TRUE;
keybd_event( VK_SHIFT, 0, KEYEVENTF_KEYUP, 0 ); // simulate SHIFT release
}
BOOL bRet = CHtmlDialog::PreTranslateM
if ( FALSE != bShiftReleased )
keybd_event( VK_SHIFT, 0, 0, 0 ); // simulate SHIFT pressed again ...
//...
}
ZOPPO
PS: The link you posted above doesn't work for me ...
ASKER
I am sure that the link above works; try right clicking it and "save target as".
I am not sure what the idea was in the last post of yours; I have tried no end of combinations to simulate the shift key press/different combinations of 'if' tests etc but it will not work. I think that the answer lies in what you originally posted, removing the SHIFT bit from the message but cannot see what else needs to be done or why this is not working.
Also,
BOOL bRet = CHtmlDialog::PreTranslateM essage( pMsg );
VC++ complained that
'CHtmlDialog' : is not a class or namespace name
??
I am not sure what the idea was in the last post of yours; I have tried no end of combinations to simulate the shift key press/different combinations of 'if' tests etc but it will not work. I think that the answer lies in what you originally posted, removing the SHIFT bit from the message but cannot see what else needs to be done or why this is not working.
Also,
BOOL bRet = CHtmlDialog::PreTranslateM
VC++ complained that
'CHtmlDialog' : is not a class or namespace name
??
sorry, should have been 'CDHtmlDialog'
and, also sorry, but the link doesn't work with any of my browsers ...
and, the idea of my last post is following: It may be that the IE control encapsulated by CDHtmlDialog uses another
way to determine whether the SHIFT key is pressed ... it maybe that it doesn't use the MK_SHIFT passed with the
sent message. It could be that it uses something like GetKeyState to determine the state of the SHIFT key so it
wouldn't matter to reset the SHIFT flag in the passed message ...
ZOPPO
and, also sorry, but the link doesn't work with any of my browsers ...
and, the idea of my last post is following: It may be that the IE control encapsulated by CDHtmlDialog uses another
way to determine whether the SHIFT key is pressed ... it maybe that it doesn't use the MK_SHIFT passed with the
sent message. It could be that it uses something like GetKeyState to determine the state of the SHIFT key so it
wouldn't matter to reset the SHIFT flag in the passed message ...
ZOPPO
ASKER
OK I cannot look into that explanation as MSVC++ (6.0, latest SP) moans about CDHtmlDialog saying it cannot find it. When I look it up on MSDN it says I need to include afxdhtml.h; doing so makes the compiler moan that it cannot find that header file.
Is there no way of getting control to pass to OnBeforeNavigate after returning TRUE from PreTranslateMessage or even sending a message that would get to there ? I cannot see why the removal of the SHIFT flag fails to work as well.
I cannot see why that link does not work, it does for me. If you wanted to look into it it is just a case of creating a dialog app, sticking a browser control on it and going from there. But 500 points may not be enough to go into that much effort...
Cheers so far; it is of course appreciated.
Is there no way of getting control to pass to OnBeforeNavigate after returning TRUE from PreTranslateMessage or even sending a message that would get to there ? I cannot see why the removal of the SHIFT flag fails to work as well.
I cannot see why that link does not work, it does for me. If you wanted to look into it it is just a case of creating a dialog app, sticking a browser control on it and going from there. But 500 points may not be enough to go into that much effort...
Cheers so far; it is of course appreciated.
ok ... you can check out MSDN about CDHtmlDialog using this link: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vcrefcdhtmldialog.asp
on the other hand I just guessed that CDHtmlDialog is the base class of your dialog ... of course I'm not sure about this.
Unfortunateley I can't tell you if there is any other way to do what you need: I'm simply have no experience using these IE controls, sorry ...
>I cannot see why the removal of the SHIFT flag fails to work as well.
Well, as told, it's simply not guaranteed that the message handler of the control does take care about the SHIFT flag ... there are other possibilities
to find out whether a key is pressed, i.e. GetKeyState, GetAsyncKeyState, GetKeyboardState or simply by handling WM_KEYDOWN and WM_KEYUP message
for VK_SHIFT ...
And, to the last point: It's not the points which are not enough, sorry, it's my time ... in the meantime I have a job to do ;o) ...
Would be interesting if AndyAinscow can use the link ... I promise it doesn't work here ...
on the other hand I just guessed that CDHtmlDialog is the base class of your dialog ... of course I'm not sure about this.
Unfortunateley I can't tell you if there is any other way to do what you need: I'm simply have no experience using these IE controls, sorry ...
>I cannot see why the removal of the SHIFT flag fails to work as well.
Well, as told, it's simply not guaranteed that the message handler of the control does take care about the SHIFT flag ... there are other possibilities
to find out whether a key is pressed, i.e. GetKeyState, GetAsyncKeyState, GetKeyboardState or simply by handling WM_KEYDOWN and WM_KEYUP message
for VK_SHIFT ...
And, to the last point: It's not the points which are not enough, sorry, it's my time ... in the meantime I have a job to do ;o) ...
Would be interesting if AndyAinscow can use the link ... I promise it doesn't work here ...
ASKER
>> in the meantime I have a job to do ;o) ...
Yeah I fully understand that and really appreciate all help I have ever been given on EE; I am aware that others have spent their time helping and I really do regard that highly. Thanks.
Well, lets see if anyone else has other ideas...
Yeah I fully understand that and really appreciate all help I have ever been given on EE; I am aware that others have spent their time helping and I really do regard that highly. Thanks.
Well, lets see if anyone else has other ideas...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Absolutely brilliant. Many thanks !