几个星期前我遇到了一个似乎没有合理解释的问题。我正在使用AlphaControls和放置在表单上的WebBrowser组件在Delphi 2007中构建应用程序。 TWebBrowser
从Web获取横幅并将其显示在UI中。坏的是,只要显示带有横幅的表单,我就会得到“无法获取OLE控件窗口句柄”,而浏览器显示在表单外部,左上角桌面的一角。
我一直在努力解决这个问题,但是调试器没有提供太多关于发生了什么的信息(这就是我得到的:770C4B32的第一次机会异常。异常类EOleError
带有消息'无法获取OLE控件窗口句柄'。处理project1.exe(3700))。有趣的是,新项目的Form1上的TWebBrowser
同样没有任何问题。
对此的任何想法都将受到高度赞赏。
答案 0 :(得分:0)
这是由html表单关闭引起的。供应商的论坛显示了一些可以解决问题的代码。 http://www.bsalsa.com/forum/showthread.php?t=255
在OnWindowClosing事件中将Cancel设置为True并导航到 空页面,如果它是主要的webbrowser。万一您的webbrowser是 弹出窗口,您可能想要关闭EWB所在的表单。
procedure TForm2.EmbeddedWB1WindowClosing(ASender: TObject; IsChildWindow: WordBool; var Cancel: WordBool);
begin
Cancel := True;
(ASender as TEmbeddedWB).GoAboutBlank;
end;
答案 1 :(得分:0)
TWebBrowser 仍处于焦点状态,因为 ActiveControl
和 TOleControl.HookControlWndProc
被调用在一个不再存在于内存中的 ActiveControl
上。由于无法获得窗口句柄,因此引发 EOleError
异常。您可以通过在关闭应用程序之前将 ActiveControl
设置为 nil
(更改活动控件焦点)来避免这种情况。
ActiveControl := nil;
这是导致异常的函数(OleCtrls.pas):
procedure TOleControl.HookControlWndProc;
var
WndHandle: HWnd;
begin
if (FOleInPlaceObject <> nil) and (WindowHandle = 0) then
begin
WndHandle := 0;
FOleInPlaceObject.GetWindow(WndHandle);
// Exception is raised here because WndHandle could not be obtained
if WndHandle = 0 then raise EOleError.CreateRes(@SNoWindowHandle);
WindowHandle := WndHandle;
DefWndProc := Pointer(GetWindowLong(WindowHandle, GWL_WNDPROC));
CreationControl := Self;
SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(@InitWndProc));
SendMessage(WindowHandle, WM_NULL, 0, 0);
end;
end;
另一种方法是在销毁消息被发送到 TWebBrowser 句柄时使用参数 WM_PARENTNOTIFY
捕获 WM_DESTROY
消息,因为父表单(TWebBrowser 嵌套在其中)获得了 WM_PARENTNOTIFY
留言:
procedure ParentNotify(var Msg: TMessage); message WM_PARENTNOTIFY;
消息处理器的实现:
procedure TMyForm.ParentNotify(Var Msg: TMessage);
begin
if (Msg.WParamLo = WM_DESTROY) and (Msg.LParam = mywebbrowser.Handle) then close;
end;