View Issue Details

IDProjectCategoryView StatusLast Update
0004078JEDI VCL00 JVCL Componentspublic2007-10-12 06:52
ReporterTraptakAssigned Toobones 
PrioritynormalSeveritycrashReproducibilityrandom
Status resolvedResolutionfixed 
Product VersionDaily / GIT 
Target VersionFixed in Version3.34 
Summary0004078: Access Violation on closing JvDesktopAlert forms
DescriptionFrom time to time my application show me Access Violation after closing JvDesktopAlert forms. Exception was raised in procedure TJvExCustomForm.WndProc(var Msg: TMessage); in line:

if DotNetHighlighting then
  HandleDotNetHighlighting(Self, Msg, MouseOver, Color);

It happends once on hundred closes. I have check component code and I think I found bug.

So, if AutoFree property is set to True and user close form then JvDesktopAlert component post message JVDESKTOPALERT_AUTOFREE to his form. In JvDeskTopAlertAutoFree procedure there are two actions:

procedure TJvFormDesktopAlert.JvDeskTopAlertAutoFree(var Msg: TMessage);
begin
  // WParam is us, LParam is the TJvDesktopAlert
  if Msg.WParam = WPARAM(Self) then
  begin
    Release;
    TObject(Msg.LParam).Free;
  end;
end;

At first desktop form is released and after that TJvDesktopAlert object is destroyed. It looks like correct code but TJvDesktopAlert object is owner of JvDesktopForm, so form is destroyed before it has receive CM_RELEASE message.

I think TJvDesktopAlert cannot be form owner in this moment. So I made following changes in TJvDesktopAlert procedures:

destructor TJvDesktopAlert.Destroy;
begin
  // when AutoFreeing, Delphi doesn't like the component having an owner, so remove the Owner here
  if FAutoFree and (Owner <> nil) and not (csDesigning in ComponentState) then
    Owner.RemoveComponent(Self);
  if (FDesktopForm <> nil) then
  begin
    if FDesktopForm.Showing then
      FDesktopForm.Close;
    FDesktopForm.OnClose := nil;
    GetStacker.Remove(FDesktopForm);
      // Here is one line added
    RemoveComponent(FDesktopForm);

    FDesktopForm.Release;
    FDesktopForm := nil;
  end;
  FreeAndNil(FColors);
  FreeAndNil(FButtons);
  FreeAndNil(FLocation);
  FreeAndNil(FStyleHandler);
  inherited Destroy;
end;

procedure TJvDesktopAlert.InternalOnClose(Sender: TObject;
  var Action: TCloseAction);
begin
  if (csDestroying in ComponentState) then
    Exit;
  if Location.Position = dapCustom then
  begin
    Location.Top := FDesktopForm.Top;
    Location.Left := FDesktopForm.Left;
  end;
  if Assigned(FOnClose) then
    FOnClose(Self);
  GetStacker.Remove(FDesktopForm);
  if AutoFree and (FDesktopForm <> nil) and not (csDesigning in ComponentState) then
  begin
    FDesktopForm.OnClose := nil;
    // post a message to the form so we have time to finish off all event handlers and
    // timers before the form and component are freed
    PostMessage(FDesktopForm.Handle, JVDESKTOPALERT_AUTOFREE, WPARAM(FDesktopForm), LPARAM(Self));


      // Here is one line added
    RemoveComponent(FDesktopForm);

    
    FDesktopForm := nil;
  end;
end;

After this changes were made problem still exist but exception raise on CM_RELEASE message handling. So I have change problematic line on:

      // Don't make any action after CM_RELEASE message
    if (Msg.Msg <> CM_RELEASE) and DotNetHighlighting then
      HandleDotNetHighlighting(Self, Msg, MouseOver, Color);

I think that after handling CM_RELEASE message object does not exist so object's property cannot be used. After this change was made exception never occur.
Additional InformationHere is attached patch with changes I have made in JVCL code.
TagsNo tags attached.

Activities

2007-03-06 13:35

 

JvDesktopAlert AV patch.patch (1,366 bytes)
Index: run/JvDesktopAlert.pas
===================================================================
--- run/JvDesktopAlert.pas	(revision 11193)
+++ run/JvDesktopAlert.pas	(working copy)
@@ -697,6 +697,8 @@
       FDesktopForm.Close;
     FDesktopForm.OnClose := nil;
     GetStacker.Remove(FDesktopForm);
+      // Prevent destroying form as one of JvDesktopAlert's components
+    RemoveComponent(FDesktopForm);
     FDesktopForm.Release;
     FDesktopForm := nil;
   end;
@@ -1009,6 +1011,8 @@
     // post a message to the form so we have time to finish off all event handlers and
     // timers before the form and component are freed
     PostMessage(FDesktopForm.Handle, JVDESKTOPALERT_AUTOFREE, WPARAM(FDesktopForm), LPARAM(Self));
+      // Prevent destroying form as one of JvDesktopAlert's components   
+    RemoveComponent(FDesktopForm);
     FDesktopForm := nil;
   end;
 end;
Index: run/JvExForms.pas
===================================================================
--- run/JvExForms.pas	(revision 11193)
+++ run/JvExForms.pas	(working copy)
@@ -2710,7 +2710,8 @@
     else
       inherited WndProc(Msg);
     end;
-    if DotNetHighlighting then
+      // Don't make any action after CM_RELEASE message
+    if (Msg.Msg <> CM_RELEASE) and DotNetHighlighting then
       HandleDotNetHighlighting(Self, Msg, MouseOver, Color);
   end;
 end;

kata322

2007-05-14 08:05

reporter   ~0012786

No one take a look to this issue? (more than two month passed)

obones

2007-06-20 02:19

administrator   ~0013482

Could you provide the zipped sources of a sample application showing this?

AHUser

2007-06-24 07:44

developer   ~0013535

I have added the "message" check to the "if DotNetHighlighting then". Could you try if this now works for you. Or if the TJvDesktopAlert.Destroy is really necessary?

obones

2007-10-12 06:51

administrator   ~0013918

No news, I believe this is fixed in SVN

Issue History

Date Modified Username Field Change
2007-03-06 13:35 Traptak New Issue
2007-03-06 13:35 Traptak File Added: JvDesktopAlert AV patch.patch
2007-05-14 08:05 kata322 Note Added: 0012786
2007-06-20 02:19 obones Note Added: 0013482
2007-06-20 02:19 obones Status new => feedback
2007-06-24 07:44 AHUser Note Added: 0013535
2007-10-12 06:51 obones Status feedback => resolved
2007-10-12 06:51 obones Fixed in Version => Daily / SVN
2007-10-12 06:51 obones Resolution open => fixed
2007-10-12 06:51 obones Assigned To => obones
2007-10-12 06:51 obones Note Added: 0013918