0

I've converted a DLL from 32 bit to 64 bit having no problem, but when I load this DLL from a 64 bit application that occupies a large amount of memory the application crashes and closes itself when DLL is loaded.

The DLL is a simple form with a TWebBrowser on it. I use Delphi 10 Seattle.

After debugging I found a 64 bit conversion problem in the vcl unit "Vcl.OleCtrls.pas" solved in this way:

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;

This solves the crash issue, but TWebBrowser events are not fired anymore and happens on 64bit only.

How can I fix TWebBrowser events firig?

Have you find similar issue or workaroud to fix events?

Thanks

ar099968
  • 6,963
  • 12
  • 64
  • 127
  • There's a load more of this defect in `WebBrowserEx`. Very hard for us to identify the problem without a [mcve]. My advice is that you enable top down memory allocation at the system level and flush out all the defects. Emba have been appallingly bad at fixing their broken 64 bit code. – David Heffernan Jan 27 '17 at 10:31
  • FWIW, you don't need to change the `GetWindowLong` since it is implemented by calling `GetWindowLongPtr`. As is `SetWindowLong`. The problem is purely the cast to `Longint`. In fact you could have used `SetWindowLong(WindowHandle, GWL_WNDPROC, LONG_PTR(@InitWndProc))`. – David Heffernan Jan 27 '17 at 10:54
  • [`SetWindowSubclass()`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762102.aspx) is [better and safer](https://blogs.msdn.microsoft.com/oldnewthing/20031111-00/?p=41883) to use than `SetWindowLongPtr(GWL_WNDPROC)` – Remy Lebeau Jan 27 '17 at 22:40
  • @Remy This is Emba code – David Heffernan Jan 27 '17 at 22:51
  • I cannot expose a simple example of the issue but i found the solution in other cast errors – ar099968 Feb 01 '17 at 14:11

1 Answers1

0

I found another cast error that generate the TWebBrowser event issue. In Emba unit "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) < $10000 then Exit; //OLD
  if Int64(EventMethod.Code) < $10000 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}

Integer cast generate an overflow, on hight memory usage situation, and the InvokeEvent procedure exit not calling the actual event. Solved with Int64 cast.

I hope Emba will integrate this fix and find similar.

ar099968
  • 6,963
  • 12
  • 64
  • 127