Memory Leak in procedure TWebGMaps.HookWndProc

Drop a WebGMap on a form, launch it, then close your application, you'll get a memory leak in procedure TWebGMaps.HookWndProc


<DELPHI>
procedure TWebGMaps.HookWndProc(var Msg: TMessage);
var
  i: integer;
  wgm: TWebGMaps;
  frm,pfrm: TCustomForm;
begin
  pfrm := GetParentForm(Self);

  if Msg.Msg = WM_CLOSE then
  begin
    RemoveHook;

    if Assigned(HookedClients) then
    begin
      for i := HookedClients.Count - 1 downto 0 do
      begin
        wgm := TWebGMaps(HookedClients.Items);
        frm := GetParentForm(wgm);

        if (frm = pfrm) and (frm = Application.MainForm) then
        begin
          wgm.Free;
          HookedClients.Delete(i);
        end;
      end;

// HookedClients.Count will be 1 thereofore FreeAndNil will not be called
      if HookedClients.Count = 0 then 
        FreeAndNil(HookedClients);
    end;
  end;


  if Assigned(pfrm) and not (csDestroying in pfrm.ComponentState) then
    Msg.Result := CallWindowProc(OldWndProc, pfrm.Handle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
</DELPHI>

Forgot to add, that is because that code assumes (above) that the instance of the WebGMaps is on the Application.MainForm, in my case that is not true, therefore the HookedClients.Delete is never called. 

Further more, freeing the webGMaps in here seems wrong. Why is it free here? This will cause an access violation in my code once I am actually ready to free it.

My work around/fix:

<DELPHI>
procedure TWebGMaps.HookWndProc(var Msg: TMessage);
var
  i: integer;
  wgm: TWebGMaps;
  frm,pfrm: TCustomForm;
begin
  pfrm := GetParentForm(Self);

  if Msg.Msg = WM_CLOSE then
  begin
    RemoveHook;

    if Assigned(HookedClients) then
    begin
      for i := HookedClients.Count - 1 downto 0 do
      begin
        wgm := TWebGMaps(HookedClients.Items);
        frm := GetParentForm(wgm);

//        if (frm = pfrm) and (frm = Application.MainForm) then
//        begin
//          wgm.Free;
          HookedClients.Delete(i);
//        end;
      end;

      if HookedClients.Count = 0 then
        FreeAndNil(HookedClients);
    end;
  end;


  if Assigned(pfrm) and not (csDestroying in pfrm.ComponentState) then
    Msg.Result := CallWindowProc(OldWndProc, pfrm.Handle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
</DELPHI>

Correction: 


procedure TWebGMaps.HookWndProc(var Msg: TMessage);
var
  i: integer;
  wgm: TWebGMaps;
  frm,pfrm: TCustomForm;
begin
  pfrm := GetParentForm(Self);

  if Msg.Msg = WM_CLOSE then
  begin
    RemoveHook;

    if Assigned(HookedClients) then
    begin
      for i := HookedClients.Count - 1 downto 0 do
      begin
        wgm := TWebGMaps(HookedClients.Items);
        frm := GetParentForm(wgm);

        if (frm = pfrm) then //and (frm = Application.MainForm) then
        begin
//        wgm.Free;
          HookedClients.Delete(i);
        end;
      end;

      if HookedClients.Count = 0 then
        FreeAndNil(HookedClients);
    end;
  end;


  if Assigned(pfrm) and not (csDestroying in pfrm.ComponentState) then
    Msg.Result := CallWindowProc(OldWndProc, pfrm.Handle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

This code is not the latest version of TWebGMaps.
Please obtain the latest version, in the latest version 2.9.7.1 there is no memory leak.

I now have 2.9.7.1, the memory leaks remain. 


Start app, add a polygon/Polygon Label on the map, close the app... leak because my WebGMap is not on the main form

    if (frm = pfrm) and (frm = Application.MainForm) then
        begin
          wgm.Free;
          HookedClients.Delete(i);
        end;
      end;

Please see: procedure TWebGMaps.HookWndProc

This isn't the latest version.
The latest version is v2.9.8.1 and there are no known memory leaks in the latest version.

But that's what you said in your last post


"...This code is not the latest version of TWebGMaps.
Please obtain the latest version, in the latest version 2.9.7.1 there is no memory leak...."

:-)

I see a comment saying it was fix (about the modal form) in 2.9.7.1 as you originally posted in June but it is not fixed. And looking at the history, nothing else was changed afterwards that handles a WebGMaps not being on the main form (that's what causes the leak, see my original comments at top of post).


v2.9.8.1

  • Improved : Behavior when DeafultToCurrenLocation is True and no LocationAPIKey specified

v2.9.8.0

  • New : RenderDirections parameters ID and SuppressMarkers
  • New : LocationAPIKey property
  • New : HideDirections and ShowDirections methods added
  • New : Converted GetCurrentLocation to IPStack.com

v2.9.7.1

  • Fixed : Issue with using TWebGMaps in modal forms

Can you please test with 2.9.8.1

I now have 2.9.8.1, the leaks are still present. 


The code I mentioned was never changed (please re-read the top of my post where I go through what I believe is the culprit of the leak). 

i.e. 
Our WebGMap is not placed on the Application MainForm, your code will only free things if we are on the main form, hence the leak. 


I guess the information on how exactly you use the forms is partial, hence we do not see the problem.
Can it be you have the WebGMaps on a secondary form and you never really close this form, just let it be destroyed when the main form closes?

Bruno, can I send you a prototype/demo that demonstrates the leak? If so, what is the email address I should use?

I emailed you the demo.

We have seen the issue with this demo and it was due to the specific way of closing the form. We have addressed this now and we will release an update.