Does any one have any ideas about how or why this is the case?
Does any one have any ideas about how to tell if the WebBrowser
control has been clicked?
Also, the OnEnter and OnExit events of the TWebBrowser control don't
seem to be fired.
If you place an object inside the WebBrowser and click to enter
it, the WebBrowser OnEnter will execute.
You might try putting a panel in the browser and setting the
Align property to alClient and then set the other panel
properties to make it appear invisible. Do not set Visible to
false.
~ JD
Let me give you some background first. I have a TWebBrowser control on the
left and a grid in the middle (aligned client). When I click on the rows in
the grid I am displaying content in the browser on the left (Text only there
are no edit boxes or buttons in the HTML). This works great. However, if
you click on the browser or move the scroll bars in the browser and then
click back on the grid. The up and down arrow do NOT move the rows in the
grid. It is like the focus does not fully go back to the grid. The up and
down keys move the web content up and down even though the grid should have
focus.
My hope was that there might be a way of telling if you click on the
TWebBrowser or tabbed to it (if entered) and then I might be able to do
something to force forces back to the grid.
THINGS THAT I HAVE FOUND
- This seems to only happen with a more complex web page. A simple
<H1>Hello World</H1> seems to work fine.
- If you click or tab to another control before clicking back on the grid.
The up and down arrows work correctly.
SO I GUESS MY QUESTIONS ARE:
- Does any one have a solution to this problem?
- Is there a way to tell if the Browser's "Window/Control" has been clicked
on or the user has moved the scroll bars?
"JD" <nos...@nospam.com> wrote in message
news:3e5f819a$1...@newsgroups.borland.com...
> If I have a TWebBrowser control on a form and a grid on a form. If I
> run the application and then click on the TWebBrowser control the
> ActiveControl seems to still be the grid.
>
> Does any one have any ideas about how or why this is the case?
The reason is that the WebBrowser control is actually three window handles
and when you click the control when a document is loaded you are clicking
one of the child windows which is not hooked by VCL and thus VCL isn't aware
of the focus change.
> Does any one have any ideas about how to tell if the WebBrowser
> control has been clicked?
The way to solve this problem is to subclass the WebBrowser controls child
windows adding your own wndproc and handle WM_SETFOCUS for the innermost
child window. In order to do this for the child windows of the WebBrowser
control you'll need to wait until a document is loaded and add the
subclassing on OnDocumentComplete or some late even in the cycle of loading
a page.
Search http://groups.google.com
For: subclassing windows delphi
Refer to the second link for more information on subclassing windows.
There is also this document:
http://community.borland.com/article/0,1410,6302,00.html
--
-Steve
Delphi/C++ Builder R&D
Borland Software Corporation
Please, no private email, unless specifically invited in this message, thank
you.
My website: http://www.geocities.com/delphihelp
Save time search http://groups.google.com first.
How To Ask Questions The Smart Way:
http://www.tuxedo.org/~esr/faqs/smart-questions.html
I almost got it working except, the application throughs and access
violation on shutdown.
Do you see anything wrong with this code?
procedure TForm1.WBDocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
var
m_hWnd: THandle;
EnumChildProcPtr: Pointer;
begin
m_hWnd := FindWindowEx(WB.Handle, 0, 'Shell DocObject View', nil);
if m_hWnd <> 0 then
begin
m_hWnd := FindWindowEx(m_hWnd, 0, 'Internet Explorer_Server', nil);
if m_hWnd <> 0 then
begin
if SubClassWndProcPtr <> nil then
begin
UnSubClassWndProc;
end;
WB_WndHandle :=m_hWnd;
SubClassWndProcPtr := MakeObjectInstance(SubClassWndProc);
WB_WndProcDef := Pointer(SetWindowLong(WB_WndHandle, GWL_WNDPROC,
Integer(SubClassWndProcPtr)));
end;
end;
end;
procedure TForm1.SubClassWndProc(var Msg: TMessage);
begin
case Msg.Msg of
WM_SETFOCUS:
Form1.ActiveControl := WB;
WM_KILLFOCUS:
begin
end;
WM_Destroy:
begin
UnSubClassWndProc;
WB_WndProcDef := nil;
end;
end;
Msg.Result := CallWindowProc(WB_WndProcDef, WB_WndHandle, Msg.Msg,
Msg.wParam, Msg.lParam);
end;
procedure TForm1.UnSubClassWndProc;
begin
if (WB_WndHandle <> 0) and (SubClassWndProcPtr <> nil) and (WB_WndProcDef
<> nil) then // AV on shutdown
begin
SetWindowLong(WB_WndHandle, GWL_WNDPROC, Integer(WB_WndProcDef));
FreeObjectInstance(SubClassWndProcPtr);
SubClassWndProcPtr := nil;
end;
end;
"Steve Trefethen (Borland)" <stref...@non.spam.junk.borland.com> wrote in
message news:3e6060ba$1...@newsgroups.borland.com...
TMyWebBrowser data members:
FDefInetExplorerServerProc: Pointer;
FDefShellObjViewProc: Pointer;
FShellDocObjViewHandle: THandle;
FInetExplorerServerHandle: THandle;
FShellDocObjInstance: Pointer;
FInetExplorerServerInstance: Pointer;
FHooksSet: Boolean;
procedure TMyWebBrowser.HookChildWindows;
begin
if csDesigning in ComponentState then exit;
// Hook child windows to catch destroywnd messages when docking the editor
window
if (FShellDocObjViewHandle <> 0) or (FInetExplorerServerHandle <> 0) then
raise Exception.Create(SChildWindowsAlreadyHooked);
FShellDocObjViewHandle := Windows.GetWindow(Handle, GW_CHILD);
if (FShellDocObjViewHandle <> 0) and not FHooksSet then
begin
FInetExplorerServerInstance :=
Classes.MakeObjectInstance(InetExplorerServerWndProc);
FShellDocObjInstance := Classes.MakeObjectInstance(ShellDocObjWndProc);
FHooksSet := True;
FInetExplorerServerHandle := Windows.GetWindow(FShellDocObjViewHandle,
GW_CHILD);
FDefShellObjViewProc := Pointer(GetWindowLong(FShellDocObjViewHandle,
GWL_WNDPROC));
SetWindowLong(FShellDocObjViewHandle, GWL_WNDPROC,
Longint(FShellDocObjInstance));
FDefInetExplorerServerProc :=
Pointer(GetWindowLong(FInetExplorerServerHandle, GWL_WNDPROC));
SetWindowLong(FInetExplorerServerHandle, GWL_WNDPROC,
Longint(FInetExplorerServerInstance));
end;
end;
procedure TMyWebBrowser.InetExplorerServerWndProc(var Message: TMessage);
begin
Message.Result := CallWindowProc(FDefInetExplorerServerProc,
FInetExplorerServerHandle, Message.Msg, Message.WParam, Message.LParam);
case Message.Msg of
WM_SETFOCUS:
begin
// Catching this message allows us to set the Active control to the
// WebBrowser itself which keeps VCL in sync with the real active
control
// which makes things like tabbing work correctly.
if csDestroying in ComponentState then exit;
GetParentForm(Self).ActiveControl := Self;
end;
WM_DESTROY: UnHookChildWindows;
end;
end;
procedure TMyWebBrowser.ShellDocObjWndProc(var Message: TMessage);
begin
// Hooking this wndproc is necessary to allow the WebBrowser control to
// properly regain focus when the application loses then regains focus.
Message.Result := CallWindowProc(FDefShellObjViewProc,
FShellDocObjViewHandle,
Message.Msg, Message.WParam, Message.LParam);
case Message.Msg of
WM_SETFOCUS:
begin
if csDestroying in ComponentState then exit;
GetParentForm(Self).ActiveControl := Self;
if Assigned(Document2) then
Document2.parentwindow.focus;
end;
WM_DESTROY: UnHookChildWindows;
end;
end;
procedure TWebBrowserEx.UnHookChildWindows;
begin
FDocEventDispatch.Active := False;
FWndEventDispatch.Active := False;
if FShellDocObjViewHandle <> 0 then
begin
SetWindowLong(FShellDocObjViewHandle, GWL_WNDPROC,
Integer(FDefShellObjViewProc));
Classes.FreeObjectInstance(FShellDocObjInstance);
FShellDocObjViewHandle := 0;
FShellDocObjInstance := nil;
end;
if FInetExplorerServerHandle <> 0 then
begin
SetWindowLong(FInetExplorerServerHandle, GWL_WNDPROC,
Integer(FDefInetExplorerServerProc));
Classes.FreeObjectInstance(FInetExplorerServerInstance);
FInetExplorerServerHandle := 0;
FInetExplorerServerInstance := nil;
end;
end;
--
-Steve
Delphi R&D
Borland Software Corporation
Please, no private email unless requested in this message, thank you.
http://www.geocities.com/delphihelp (last updated December 2, 2002)
Save time search http://groups.google.com first.
ActionBand FAQ http://www.geocities.com/delphihelp/info/ABFAQ.htm
How to Ask Questions the Smart Way:
http://www.tuxedo.org/~esr/faqs/smart-questions.html