0

几周前我遇到了一个似乎没有合乎逻辑的解释的问题。我正在使用 AlphaControls 和放置在表单上的 WebBrowser 组件使用 Delphi 2007 构建应用程序。从 Web 获取横幅并将其TWebBrowser显示到 UI 中。不好的是,一旦显示带有横幅的表单,我就会得到“无法获得 OLE 控制窗口句柄”,而浏览器正在表单外显示,在桌面的左上角。

我一直在尝试基本上任何事情来解决这个问题,但是调试器没有提供太多关于正在发生的事情的信息(这就是我得到的全部信息:$ 770C4B32的第一次机会异常。EOleError带有消息'无法获得OLE控制窗口句柄的异常类'. 处理 project1.exe (3700))。有趣的是,TWebBrowser新项目的 Form1 上的相同工作没有任何问题。

对此的任何想法将不胜感激。

4

2 回答 2

0

它是由 html 表单被关闭引起的。供应商的论坛显示了一些可以解决问题的代码。 http://www.bsalsa.com/forum/showthread.php?t=255

在 OnWindowClosing 事件中将 Cancel 设置为 True,如果它是主 Web 浏览器,则导航到一个空页面。如果您的网络浏览器是一个弹出窗口,您可能需要关闭 EWB 所在的表单。

procedure TForm2.EmbeddedWB1WindowClosing(ASender: TObject; IsChildWindow: WordBool; var Cancel: WordBool);
begin
  Cancel := True;
  (ASender as TEmbeddedWB).GoAboutBlank;
end;
于 2012-12-05T21:32:47.097 回答
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; 
于 2021-07-15T16:44:34.207 回答