Page 1 of 1

An error that happens when freeing the editor

Posted: Tue Jul 19, 2022 8:09 am
by edwinyzh
Hi Sergey,

An end user of my program reported an error that seems to happen when freeing the form and TRichViewEdit. From the call stack I couldn't find any hints, do you have any thought?

PS, you must remember, my program uses xml persisting if it makes sense ;)

Code: Select all

operating system   : Windows 10 x64 build 19044
system language    : German
system up time     : 1 day 18 hours
program up time    : 1 day
processors         : 4x Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz
physical memory    : 8259/16341 MB (free/total)
free disk space    : (C:) 172,86 GB
display mode       : 1920x1080, 32 bit
madExcept version  : 4.0.21
exception number   : 1
exception class    : EAccessViolation
exception message  : Access violation at address 00D82B80 in module 'Program1.exe'. Read of address 00000040.

main thread ($6c90):
00d82b80 +060 Program1.exe CRVData        2370   +6 TCustomRVData.GetOffsAfterItem
00e101b2 +006 Program1.exe RichView       2562   +0 TCustomRichView.GetOffsAfterItem
00dff863 +037 Program1.exe RVLinear        968   +6 RVGetTextLength
00e152e0 +034 Program1.exe RichView       6365   +9 TCustomRichView.WMGetTextLength
005c7325 +2bd Program1.exe Vcl.Controls             TControl.WndProc
005cbde1 +5c5 Program1.exe Vcl.Controls             TWinControl.WndProc
00e16260 +078 Program1.exe RichView       6944  +17 TCustomRichView.WndProc
005c6f60 +024 Program1.exe Vcl.Controls             TControl.Perform
005c5985 +009 Program1.exe Vcl.Controls             TControl.GetTextLen
005cdbfb +013 Program1.exe Vcl.Controls             TWinControl.WMDestroy
00da4814 +014 Program1.exe RVScroll        702   +2 TRVScroller.WMDestroy
00e11f25 +011 Program1.exe RichView       4067   +2 TCustomRichView.WMDestroy
00d22bc8 +038 Program1.exe RVEdit         1447   +7 TCustomRichViewEdit.WMDestroy
005c7325 +2bd Program1.exe Vcl.Controls             TControl.WndProc
005cbde1 +5c5 Program1.exe Vcl.Controls             TWinControl.WndProc
00e16260 +078 Program1.exe RichView       6944  +17 TCustomRichView.WndProc
005cb424 +02c Program1.exe Vcl.Controls             TWinControl.MainWndProc
0054afac +014 Program1.exe System.Classes           StdWndProc
77e14e9b +04b ntdll.dll                                KiUserCallbackDispatcher
005cadd0 +040 Program1.exe Vcl.Controls             TWinControl.DestroyWindowHandle
006c5cb7 +04b Program1.exe Vcl.Forms                TCustomForm.DestroyWindowHandle
006c2613 +073 Program1.exe Vcl.Forms                TCustomForm.Destroy
0113560d +01d Program1.exe BaseForm        170   +2 TfrmBase.Destroy


Re: An error that happens when freeing the editor

Posted: Tue Jul 19, 2022 10:14 am
by Sergey Tkachenko
Do you use the newest version of TRichView?
What Delphi version do you use?
Do you process events of TRichViewEdit?

Re: An error that happens when freeing the editor

Posted: Tue Jul 19, 2022 12:54 pm
by standay
Just a guess...

Looks like something's trying to call GetOffsAfterItem right before it throws the AV. Maybe there are no items in the editor at that point? Or maybe there's no editor at that point?

Stan

Re: An error that happens when freeing the editor

Posted: Tue Jul 19, 2022 3:21 pm
by edwinyzh
Sergey Tkachenko wrote: Tue Jul 19, 2022 10:14 am Do you use the newest version of TRichView?
What Delphi version do you use?
Do you process events of TRichViewEdit?
- Yes I do, I use v20.3.1, 2022-Jul-1
- I use XE4/win32
- Yes, some.

And inspired by standay's reply above, the fact the the program uses a TTimer to do auto-save (to memory stream) maybe related to the issue...

@standay,
the program doesn't call GetOffsAfterItem directly, that method seems to be called when TRichViewXml does the saving.
And your last guess makes sense - see above. I've already applied some code to ensure the TTimer is disabled when the form is about to close, but maybe Sergey has more advises to come.

Thank you all.

Re: An error that happens when freeing the editor

Posted: Tue Jul 19, 2022 5:05 pm
by Sergey Tkachenko
I do not think that XML is related to this problem.

This code is executed when the form is destroyed, when this form destroys window handles of its controls. When it happens the components receive WM_DESTROY message.
TRichView is inherited from TWinControl, and TWinControl, when it processes WM_DESTROY, before destruction, receives text from the control, calling WM_GETTEXT and WM_GETTEXTLENGTH.
TRichView processes these messages, but it does nothing when csDestroying in its ComponentState.

There are two things that I do not understand.
1. Why is not csDestroying included in ComponentState? The form must set csDestroying of all its components before destroying window handles, so TRichView can simply ignore WM_GETTEXT and WM_GETTEXTLENGTH on form destruction.
2. Why does exception happen when processing these messages? Normally, it should be processed correctly even on window destruction (it just takes time and CPU resources unnecessary).

---

How was this TRichView created? Was in placed on a form or created in code?

Re: An error that happens when freeing the editor

Posted: Wed Jul 20, 2022 4:04 am
by edwinyzh
Sergey Tkachenko wrote: Tue Jul 19, 2022 5:05 pm How was this TRichView created? Was in placed on a form or created in code?
It's placed on a form, the form was modified from \RichViewActions\Demos\DelphiUnicode\ActionTest

And this post (Error when closing the editor form with cursor inside a table cell) maybe related, because both error stops at TCustomRVData.GetOffsAfterItem

Re: An error that happens when freeing the editor

Posted: Mon Jul 25, 2022 2:56 pm
by Sergey Tkachenko
Please make the following changes.

1. In CRVData.pas, add one more value to TRVState: rvstDestroyingHandle

Code: Select all

  { State of RVData }
  TRVState = (rvstMakingSelection, // Mouse selection is in process
  ...
    rvstDestroyingHandle // destroying a window handle
    );
2. In RichView.pas, change WMDestroy:

Code: Select all

procedure TCustomRichView.WMDestroy(var Message: TWMDestroy);
begin
  DeactivateScrollTimer;
  if RVData <> nil then
    Include(RVData.State, rvstDestroyingHandle);
  try
    inherited
  finally
    if RVData <> nil then
      Exclude(RVData.State, rvstDestroyingHandle)
  end;
end;
3. In the same unit, in WMGetTextLength, add the condition "not(rvstDestroyingHandle in RVData.State)" to the first IF:

Code: Select all

procedure TCustomRichView.WMGetTextLength(var Message: TMessage);
const
  CharsPerLineBreak = 2; // in memos and richedits: 2
begin
  if (rvflCanProcessGetText in Flags) and
    not(csDestroying in ComponentState) and
    (RVData <> nil) and not(rvstDestroyingHandle in RVData.State)
    {$IFDEF RICHVIEWDEF2006}{$IFnDEF FPC}and not(csRecreating in ControlState){$ENDIF}{$ENDIF}
  then
4. In the same unit, in WMGetText, add the same condition.

Re: An error that happens when freeing the editor

Posted: Mon Aug 01, 2022 3:40 am
by edwinyzh
Thanks Sergey,

I'm collect more details from the end user and try to reproduce (at least partially) the error and apply the changes you suggested.