AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Embed an Internet Explorer control in your AHK Gui via COM
Goto page Previous  1, 2, 3 ... , 10, 11, 12  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Wed Mar 19, 2008 9:36 pm    Post subject: Reply with quote

Quote:
But I'm unaware of anyone who's solved this problem in AHK.


pseudo-code
Code:

#IfWinActive parentWindow

$Enter::
  MouseGetPos ; to check whether you are in/over the IE control
  ;if you are
  ControlSet ; focus
  Send {Enter}
Return

#IfWinActive


Question
Back to top
Guest






PostPosted: Thu Mar 20, 2008 12:31 am    Post subject: Re: Losing Enterkey in embeded Internet Explorer Reply with quote

paulwarr wrote:
But I'm unaware of anyone who's solved this problem in AHK.

I think that's solvable. The problem is that no one wants bothered to do it. Why don't you try to be the first one?
Back to top
paulwarr



Joined: 21 Sep 2006
Posts: 30

PostPosted: Thu Mar 20, 2008 1:39 pm    Post subject: Reply with quote

Anonymous wrote:
pseudo-code
Code:

#IfWinActive parentWindow

$Enter::
  MouseGetPos ; to check whether you are in/over the IE control
  ;if you are
  ControlSet ; focus
  Send {Enter}
Return

#IfWinActive


Question
I think you'll find that this works with an independent IE instance. But it won't work with a WebBrowser control that's embedded in an AHK Gui. If you have working code that demonstrates the effective use of {Tab}, {Shift-Tab} and {Enter} within an embedded WebBrowser control, then please post it. It's been requested several times - not just for the IE/COM standard libraries, but also with other ways of wrapping the WebBrowser control into AHK (cwebpage.dll, among others).
Anonymous wrote:

I think that's solvable. The problem is that no one wants bothered to do it. Why don't you try to be the first one?

Oh yes - I think it's solvable. But handling accelerators properly is never easy (see the sources referenced in my previous post). Since {Tab}, {Shift-Tab} and {Enter} are critical to tab ordering behavior for any AHK Gui that has other controls in addition to the WebBrowser control, the code could get fiendishly complex. (For example, what should happen if you {tab} past the last field in the Webbrowser control? Should it tab into the next control in the AHK Gui? Or should it tab back to the first control in the WebBrowser?). I don't have the necessary COM skills to do this, or the time to code this. Do you? Wink
heresy wrote:
4) but the {Enter} key doesn't working in embeded IE
i can't even send a word, i can't communicate :<
Why don't you try to run Internet Explorer and directly control its window (sizing, navigating, and so on), instead of using an embedded WebBrowser control?
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Mar 20, 2008 3:00 pm    Post subject: Reply with quote

paulwarr wrote:
Since {Tab}, {Shift-Tab} and {Enter} are critical to tab ordering behavior

{Enter} may be solved easily using Hotkey. {Tab} part is tricker, however.
Code:
#IfWinActive, Title ahk_class AutoHotkeyGUI
~Enter::PostMessage, 0x102, 0xD, 0x001C0001, Internet Explorer_Server1, ahk_id %hGui%
Back to top
paulwarr



Joined: 21 Sep 2006
Posts: 30

PostPosted: Thu Mar 20, 2008 6:24 pm    Post subject: Reply with quote

Anonymous wrote:
{Enter} may be solved easily using Hotkey. {Tab} part is tricker, however.
Code:
#IfWinActive, Title ahk_class AutoHotkeyGUI
~Enter::PostMessage, 0x102, 0xD, 0x001C0001, Internet Explorer_Server1, ahk_id %hGui%
Nice workaround! Very Happy But bear in mind that this will have the effect of disabling normal {Enter} behavior for any other AHK Gui control on your form that can normally "consume" the {Enter} key - the "default" button, for example, or the Text or Edit fields.
Back to top
View user's profile Send private message
other Guest
Guest





PostPosted: Thu Mar 20, 2008 6:41 pm    Post subject: Reply with quote

Quote:
But bear in mind that this will have the effect of disabling normal {Enter} behavior for any other AHK Gui control on your form that can normally "consume" the {Enter} key - the "default" button, for example, or the Text or Edit fields.


which is why you could add a check with MouseGetPos and/or ControlGetFocus to the code to make sure it is only used when the IE control is active.

Wink
Back to top
paulwarr



Joined: 21 Sep 2006
Posts: 30

PostPosted: Thu Mar 20, 2008 7:18 pm    Post subject: Reply with quote

other Guest wrote:
which is why you could add a check with MouseGetPos and/or ControlGetFocus to the code to make sure it is only used when the IE control is active.

Wink
Sounds like you're familiar with this issue. So...
I wrote:
If you have working code that demonstrates the effective use of {Tab}, {Shift-Tab} and {Enter} within an embedded WebBrowser control, then please post it.
Thanks! Smile
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Mar 20, 2008 10:25 pm    Post subject: Reply with quote

untested

Code:
#IfWinActive, Title ahk_class AutoHotkeyGUI
  $Enter::
    ControlGetFocus, currentFocussedControl
    if (currentFocussedControl = "Internet Explorer_Server1")
      PostMessage, 0x102, 0xD, 0x001C0001, Internet Explorer_Server1, ahk_id %hGui%
    else
      Send, {Enter}
  Return
#IfWinActive


Question
Back to top
Nicolas Bourbaki
Guest





PostPosted: Fri Mar 21, 2008 6:44 am    Post subject: Reply with quote

paulwarr wrote:
But bear in mind that this will have the effect of disabling normal {Enter} behavior for any other AHK Gui control on your form that can normally "consume" the {Enter} key - the "default" button, for example, or the Text or Edit fields.

You may use OnMessage instead then.
Code:
Gui, +Resize +LastFound
Gui, Show, w800 h600 Center, WebBrowser
hGui := WinExist()
OnMessage(WM_KEYDOWN:=0x0100, "WM_KEYDOWN")
COM_AtlAxWinInit()
pweb := COM_AtlAxCreateControl(hGui, "Shell.Explorer")
COM_Invoke(pweb, "Navigate", "http://www.google.com/")
Return

GuiClose:
Gui, Destroy
COM_Release(pweb)
COM_AtlAxWinTerm()
ExitApp

WM_KEYDOWN(wParam, lParam, nMsg, hWnd)
{
  If  (wParam = 13)
  {
      WinGetClass, Class, ahk_id %hWnd%
      If  (Class == "Internet Explorer_Server")
          PostMessage, 0x0102, 0x000D, lParam,, ahk_id %hWnd%   
  }
}
Back to top
paulwarr



Joined: 21 Sep 2006
Posts: 30

PostPosted: Fri Mar 21, 2008 7:10 pm    Post subject: Reply with quote

Nicolas Bourbaki wrote:
You may use OnMessage instead then.

I added a check for the {Tab} key to your code as well - disheartening results:
Code:
WM_KEYDOWN(wParam, lParam, nMsg, hWnd)
{
   WinGetClass, Class, ahk_id %hWnd%
; {Enter} key condition - this works
   If  (wParam = 13)
   {
      If  (Class == "Internet Explorer_Server" || Class == "Internet Explorer_Server1")
         PostMessage, 0x0102, 0x000D, lParam,, ahk_id %hWnd%   
      }
; {Tab} key condition - this doesn't work
   If  (wParam = 9)
   {
      If  (Class == "Internet Explorer_Server" || Class == "Internet Explorer_Server1")
         PostMessage, 0x0102, 0x0009, lParam,, ahk_id %hWnd%   
   }
   Return
}

Some funky stuff going on in the messages between parent and child windows. Winspector shows a hierarchy of windows in your gui:
    AutoHotkeyGui "WebBrowser"
    -->Shell Embedding
    ---->Shell DocObject View
    ------>Internet Explorer_Server

Once the {Tab} key's pressed in the "Internet Explorer Server" child, its sole effect seems to be to remove focus from this child. Focus moves up the hierarchy to the "Shell Embedding" window.
In another test, I refocused the "Internet Explorer Server" and POST'ed another {Tab} character, but to no effect. Mad
Back to top
View user's profile Send private message
Nicolas Bourbaki
Guest





PostPosted: Sat Mar 22, 2008 12:59 am    Post subject: Reply with quote

paulwarr wrote:
Once the {Tab} key's pressed in the "Internet Explorer Server" child, its sole effect seems to be to remove focus from this child. Focus moves up the hierarchy to the "Shell Embedding" window.

That's normal, default handling of {TAB} of a dialog box, navigating among the controls. You can observe what I mean in the open/save dialog boxes. You must disable or replace the default handling with your custom procedure. It was easy for {ENTER}, but for {TAB} unfortunately not. I'm suspecting it's only possible in AHK by detouring some APIs.
Back to top
Nicolas Bourbaki
Guest





PostPosted: Sat Mar 22, 2008 1:12 am    Post subject: Reply with quote

Or use Hotkey or OnMessage() to capture {TAB} key and trigger a custom procedure.
Back to top
paulwarr



Joined: 21 Sep 2006
Posts: 30

PostPosted: Sat Mar 22, 2008 1:22 am    Post subject: Reply with quote

Nicolas Bourbaki wrote:

That's normal, default handling of {TAB} of a dialog box, navigating among the controls. You can observe what I mean in the open/save dialog boxes. You must disable or replace the default handling with your custom procedure. It was easy for {ENTER}, but for {TAB} unfortunately not. I'm suspecting it's only possible in AHK by detouring some APIs.
Yes. The WebBrowser control deliberately disables accelerator keys, apparently. They can be re-enabled, apparently - I just found some code at slashbin.org that appears to be promising:
Code:
   // UIActivate the WebBrowser control when the tab key
   // is pressed so that focus will be changed to the next
   // control in the tabbing order.  If this is not done,
   // the WebBrowser control never gets the focus.
   if ((uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) && wParam == VK_TAB)
   {
      CComQIPtr<IOleObject, &IID_IOleObject> spOleObject(m_spWebBrowser);

      RECT rect;
      GetClientRect(&rect);
      spOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, this, 0, m_hWnd, &rect);
   }

   // Call TranslateAccelerator on the in-place active
   // object for the delete key so that the accelerator will be passed to the
   // hosted WebBrowser control.  This forces the delete key to
   // work correctly in design mode.
   if (wParam == VK_DELETE)
   {
      CComQIPtr<IOleInPlaceActiveObject,
             &IID_IOleInPlaceActiveObject> spInPlaceActiveObject(m_spWebBrowser);
   
      spInPlaceActiveObject->TranslateAccelerator(&msg);
   }
If someone could translate this TranslateAccelerator code, then our conquest of this blasted WebBrowser control would be nearly complete! Smile
Back to top
View user's profile Send private message
daonlyfreez



Joined: 16 Mar 2005
Posts: 745
Location: Berlin

PostPosted: Sat Mar 22, 2008 1:53 pm    Post subject: Reply with quote

Ah, that TranslateAccellerator COM stuff looks promising...

Where is a Sean when you need him Confused
_________________
(sorry, homesite offline atm)
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger
Nicolas Bourbaki
Guest





PostPosted: Sun Mar 23, 2008 5:02 am    Post subject: Reply with quote

paulwarr wrote:
If someone could translate this TranslateAccelerator code, then our conquest of this blasted WebBrowser control would be nearly complete!

I was thinking about lower-level one, however, I think this one will also work.

Code:
Gui, +Resize +LastFound
Gui, Show, w800 h600 Center, WebBrowser
hGui := WinExist()
OnMessage(WM_KEYDOWN:=0x0100, "WM_KEYDOWN")
COM_AtlAxWinInit()
pweb := COM_AtlAxCreateControl(hGui, "Shell.Explorer")
COM_Invoke(pweb, "Navigate", "http://www.google.com/")
Return

GuiClose:
Gui, Destroy
COM_Release(pweb)
COM_AtlAxWinTerm()
ExitApp

WM_KEYDOWN(wParam, lParam, nMsg, hWnd)
{
;  Critical 20
  If  (wParam = 0x09 || wParam = 0x0D)
  {
      WinGetClass, Class, ahk_id %hWnd%
      If  (Class == "Internet Explorer_Server")
          {
             Global pweb
             pipa := COM_QueryInterface(pweb, "{00000117-0000-0000-C000-000000000046}")
             VarSetCapacity(Msg, 28)
             NumPut(hWnd,Msg), NumPut(nMsg,Msg,4), NumPut(wParam,Msg,8), NumPut(lParam,Msg,12)
             NumPut(A_EventInfo,Msg,16), NumPut(A_GuiX,Msg,20), NumPut(A_GuiY,Msg,24)
             DllCall(NumGet(NumGet(1*pipa)+20), "Uint", pipa, "Uint", &Msg)
             Return 0
          }
  }
}

I used Global here for simplicity, which I think can be easily overcome.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... , 10, 11, 12  Next
Page 11 of 12

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group