View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0004078 | JEDI VCL | 00 JVCL Components | public | 2007-03-06 13:35 | 2007-10-12 06:52 |
Reporter | Traptak | Assigned To | obones | ||
Priority | normal | Severity | crash | Reproducibility | random |
Status | resolved | Resolution | fixed | ||
Product Version | Daily / GIT | ||||
Target Version | Fixed in Version | 3.34 | |||
Summary | 0004078: Access Violation on closing JvDesktopAlert forms | ||||
Description | From 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 Information | Here is attached patch with changes I have made in JVCL code. | ||||
Tags | No tags attached. | ||||
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; |
|
No one take a look to this issue? (more than two month passed) |
|
Could you provide the zipped sources of a sample application showing this? |
|
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? |
|
No news, I believe this is fixed in SVN |
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 |