Delphi 64 位 DLL:OleCtrls 事件问题

Delphi 64bit DLL: OleCtrls events issues

我已经将 DLL 从 32 位转换为 64 位,没有任何问题,但是当我从占用大量内存的 64 位应用程序加载此 DLL 时,应用程序崩溃并在加载 DLL 时自行关闭。

DLL 是一个带有 TWebBrowser 的简单表单。我使用 Delphi 10 西雅图。

调试后发现vcl单元有64位转换问题"Vcl.OleCtrls.pas"这样解决:

procedure TOleControl.HookControlWndProc;
var
  WndHandle: HWnd;
begin
  if (FOleInPlaceObject <> nil) and (WindowHandle = 0) then
  begin
    WndHandle := 0;
    FOleInPlaceObject.GetWindow(WndHandle);
    if WndHandle = 0 then raise EOleError.CreateRes(@SNoWindowHandle);
    WindowHandle := WndHandle;
    //DefWndProc := Pointer(GetWindowLong(WindowHandle, GWL_WNDPROC));//OLD
    DefWndProc := Pointer(GetWindowLongPtr(WindowHandle, GWL_WNDPROC));
    CreationControl := Self;
    //SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(@InitWndProc));//OLD
    SetWindowLongPtr(WindowHandle, GWL_WNDPROC, LONG_PTR(@InitWndProc));
    SendMessage(WindowHandle, WM_NULL, 0, 0);
  end;
end;

这解决了崩溃问题,但不再触发 TWebBrowser 事件并且仅在 64 位上发生。

如何修复 TWebBrowser 事件?

您是否发现类似问题或解决事件的解决方法?

谢谢

我发现另一个生成 TWebBrowser 事件问题的转换错误。 在 Emba 单位 "Vcl.OleCtrls.pas":

procedure TOleControl.InvokeEvent(DispID: TDispID; var Params: TDispParams);
{$IFDEF CPUX64}
var
  EventMethod: TMethod;
  ParamBlock : TParamBlock;
  i : Integer;
  StackParams2 : array of Int64;

begin
  GetEventMethod(DispID, EventMethod);
  //if Integer(EventMethod.Code) < 000 then Exit; //OLD
  if Int64(EventMethod.Code) < 000 then Exit;     //NEW

  ParamBlock.RegRCX := Int64(EventMethod.Data);
  ParamBlock.RegRDX := Int64(Self);

  if Params.cArgs > 2 then
  begin
    SetLength(StackParams2, Params.cArgs-2);
  end;

  for i := 1 to Params.cArgs do
    case i of
      1: ParamBlock.RegR8  := Int64(Params.rgvarg[Params.cArgs-1].unkVal);
      2: ParamBlock.RegR9  := Int64(Params.rgvarg[Params.cArgs-2].unkVal);
    else
      StackParams2[i-3] := Int64(Params.rgvarg[Params.cArgs-i].unkVal);
    end;

  ParamBlock.StackDataSize := Length(StackParams2) * sizeof(Pointer);
  ParamBlock.StackData := @StackParams2[0];

  RawInvoke(EventMethod.Code, @ParamBlock);
end;
{$ELSE !CPUX64}

整数转换产生溢出,内存使用率高,InvokeEvent 过程退出时未调用实际事件。使用 Int64 转换解决。

我希望 Emba 能够集成此修复并找到类似的。