Page 1 of 1
Exceptions with spell checking
Posted: Wed Feb 17, 2010 4:53 pm
by vit
Hi!
There is a descendant of TRichViewEdit (TCustomTextInplaceEditor) that use spell checking. Method ClearLiveSpellingResults is calling from destructor. And I get various exception with this.
This is a stack of one of exceptions:
Code: Select all
Classes TThread.CheckThreadError
Classes TThread.CheckThreadError
Classes TThread.SetPriority
RVThread TRVWordEnumThread.Finish
RichView TCustomRichView.ClearLiveSpellingResults
CustomTextInplaceEditor TCustomTextInplaceEditor.Destroy
exception class : EThread
exception message : Thread Error: The handle is invalid (6).
And this is another case:
Code: Select all
Classes TThread.Resume
RVThread TRVWordEnumThread.Finish
RichView TCustomRichView.ClearLiveSpellingResults
CustomTextInplaceEditor TCustomTextInplaceEditor.Destroy
exception class : EAccessViolation
exception message : Access violation at address 41077CBA in module ...
Can anybody assume what is a reason of this exceptions?
Thank you!
Posted: Wed Feb 17, 2010 7:36 pm
by Sergey Tkachenko
Why do you need to call this method from your destructor? It's already called by TCustomRichView.
Posted: Thu Feb 18, 2010 8:38 am
by vit
Sergey Tkachenko wrote:Why do you need to call this method from your destructor? It's already called by TCustomRichView.
Yes, you are right, it is not necessary. But early we have another similar troubles with spelling check threads. So it was attempt to fix its. Do you think if I remove this calling exception will disappear?
A big trouble in that that I can't repeat this exceptions (they come from our users).
We have a form with many (0-tens) instances of TRichViewEdit (actually their descendants TCustomTextInplaceEditor). And in all of them is using spelling check. May be a problem in count of instances?
Posted: Thu Feb 18, 2010 10:04 am
by Sergey Tkachenko
Each TRichViewEdit has its own spelling thread, they do not interact.
There is a change I am considering to make in TRichView code.
In RVThread.pas: delete the line
In RichView.pas, in procedure TCustomRichView.ClearLiveSpellingResults, add
after
Try these changes and inform me if they fixed the problem.
Posted: Thu Feb 18, 2010 11:52 am
by vit
Ok! Thank you for advise!
Posted: Tue Mar 23, 2010 10:27 am
by vit
Well, for march we have tested version of our systems with modifications wich you have proposed. And now I can say that we not have such errors more.
But we still have errors that seems to related with spell checking. Its only two.
1. When user delete row from table:
Code: Select all
exception class : EAccessViolation
exception message : Access violation at address 00000000. Read of address 00000000.
main thread ($298):
00000000 +000 ???
System TObject.Free
CRVData TCustomRVData.EnumItems
RichView TCustomRichView.DoClearLiveSpellingResults
RichView TCustomRichView.ClearLiveSpellingResults
MedStRichTextParamContent TRichTextParamContent.ClearLiveSpellChecking
MedStRichTextParamContent TRichTextParamContent.DelRow
TRichTextParamContent - its just TWinControl with TCustomRichView inside (working as inplace editor)
There is related code:
Code: Select all
procedure TRichTextParamContent.DelRow;
var
Table: TRVTableItemInfo;
ModifyData: Integer;
ItemNo: Integer;
Editor: TCustomRichViewEdit;
begin
Table := GetCurrentTable(Editor); // function GetCurrentTable receive out parameter - Editor
if Table <> nil then
begin
ItemNo := Editor.GetItemNo(Table);
ClearLiveSpellChecking;
FInplaceEditor.BeginItemModify(ItemNo, ModifyData);
try
Table.DeleteSelectedRows;
Editor.Change;
finally
Editor.EndItemModify(ItemNo, ModifyData);
end;
end;
end;
procedure TRichTextParamContent.ClearLiveSpellChecking;
begin
if FInplaceEditor <> nil then
begin
FInplaceEditor.ClearLiveSpellingResults;
FInitSpellChecked := False;
end;
end;
2. in TRVWordEnumThread
Code: Select all
exception class : EAccessViolation
exception message : Access violation at address 410042CE in module '*.exe'. Read of address EE20EEEF.
thread $fb8 (TRVWordEnumThread):
System @AsClass
RVStyle TFontInfos.GetInvalidItem
RVStyle TFontInfos.GetItem
CRVData TCustomRVData.GetStyleCodePage
MedStSpellChecking TSpellChecker.GetUnicode
MedStSpellChecking TSpellChecker.IsMisspelled
MedStCustomTextParamContentClasses TCustomTextInplaceEditor._OnSpellCheck
RVThread TRVWordEnumThread.Execute
madExcept HookedTThreadExecute
Classes ThreadProc
System ThreadWrapper
madExcept CallThreadProcSafe
madExcept ThreadExceptFrame
>> created by main thread ($ad0) at:
RVThread TRVWordEnumThread.Create
There is related code:
Code: Select all
function TSpellChecker.IsMisspelled(const AWord: string; StyleNo: Integer;
const Editor: TCustomRichView): Boolean;
var
UniStr: string;
begin
Result := False;
if not FEnabled then Exit;
FLock.Enter; //TCriticalSection for protecting access to FRVHunSpell
try
UniStr := GetUnicode(AWord, StyleNo, Editor);
Result := not FRVHunSpell.Spell(UniStr); //TRVHunSpell
finally
FLock.Leave;
end;
end;
function TSpellChecker.GetUnicode(const ANSI: string;
const StyleNo: Integer; const Editor: TCustomRichView): TRVUnicodeString;
begin
Result := RVU_RawUnicodeToWideString(RVU_AnsiToUnicode(
Editor.RVData.GetStyleCodePage(StyleNo), ANSI));
end;
I will very grateful if you help us with this!
Posted: Tue Mar 23, 2010 2:22 pm
by Sergey Tkachenko
1) Where is FInplaceEditor variable assigned?
By the way, it is not necessary (and may be even harmful) to clear live spelling results in the inplace editor; live spelling procedure must handle table operations without any additional code.
2) I am not sure why the second error occurs, but I can see TFontInfos.GetInvalidItem in the stack.
This function is called when accessing incorrect text style (StyleNo<0 or StyleNo>=TextStyles.Count).
Since I can see AsClass function in the stack, it looks like the following code in TFontInfos.GetInvalidItem is executed:
Code: Select all
FInvalidItem := (FOwner as TRVStyle).GetTextStyleClass.Create(nil);
This code is executed when the invalid item is accessed for the first time.
It's quite strange, because if the document has references incorrect styles, they should be already accessed before live spelling, when formatting document.
So, please recheck that:
a) in TSpellChecker.IsMisspelled, StyleNo is really the index of Editor.Style.TextStyle (may be incorrect Editor is passed as the parameter)
b) there is no procedure that can change styles after the document is formatted
Posted: Wed Mar 24, 2010 9:26 am
by vit
1) Firstly, I must clarify. TRichTextParamContent is a TWinControl. And its have "inplace editor" - instance of TRichViewEdit (FInplaceEditor field). FInplaceEditor is creating in SetParent of TRichTextParamContent instance. So inplace editor in TRichTextParamContent it is not the same inplace editor in TRichViewEdit.
So that I do not call ClearLiveSpellingResults of inplace editor of TRichViewEdit, but call its for TRichViewEdit.
Well, I am not sure that is needed to call this method in this context, I was follow your advise from this post:
http://www.trichview.com/forums/viewtop ... highlight=
you wrote:
However, if you have your own operations that are not started from Clear and use non-editing methods, you should be careful (call ClearLiveSpellingResults before them).
Is I don't understand you and I should not call ClearLiveSpellingResults in this case?
2)
a) in TSpellChecker.IsMisspelled, StyleNo is really the index of Editor.Style.TextStyle (may be incorrect Editor is passed as the parameter)
Unfortunately, this is one of errors, wich we can't repeat. So I will insert assertions to check TSpellChecker.IsMisspelled params and we will know some time later.
b) there is no procedure that can change styles after the document is formatted
All style changes processed through ApplyStyleConversion/ApplyParaStyleConversion.
Example:
Code: Select all
procedure TRTInplaceEditor.SetFontSize(const ASize: Integer); //TRTInplaceEditor - Descendant of TRichViewEdit, this is inplace editor of TRichTextParamContent
begin
FFontSize := ASize;
ClearLiveSpellingResults; //It is not necessary also?
ApplyStyleConversion(fcSetFontSize);
end;
and
Code: Select all
procedure TRTInplaceEditor.TextStyleConversion(Sender: TCustomRichViewEdit;
StyleNo, UserData: Integer; AppliedToText: Boolean;
var NewStyleNo: Integer);
var
fi: TFontInfo;
begin
ClearLiveSpellingResults;
fi := TFontInfo.Create(nil);
try
fi.Assign(Style.TextStyles[StyleNo]);
case UserData of
fcSetFontSize: fi.Size := FFontSize;
fcSetFontName: fi.FontName := FFontName;
fcSetFontColor: fi.Color := FFontColor;
fcSetFontStyles: fi.Style := FFontStyles;
end;
NewStyleNo := Style.TextStyles.FindSuchStyle(StyleNo, fi,
RVAllFontInfoProperties);
if NewStyleNo = -1 then
begin
Style.TextStyles.Add;
NewStyleNo := Style.TextStyles.Count - 1;
Style.TextStyles[NewStyleNo].Assign(fi);
Style.TextStyles[NewStyleNo].Standard := False;
Style.TextStyles[NewStyleNo].Charset := RUSSIAN_CHARSET;
end;
finally
fi.Free;
end;
end;
Posted: Wed Mar 24, 2010 6:37 pm
by Sergey Tkachenko
Deleting table rows and ApplyStyleConversion are editing operations. Like all editing operations, they handle live spelling correctly, so do not call ClearLiveSpellingResults before them.
I am afraid I do not know what's wrong with styles in your application.
I can suggest to access Editor.Style.TextStyles.InvalidItem before starting live spelling. Probably it will remove this exception, but it will just hide the problem.
Posted: Thu Mar 25, 2010 7:52 am
by vit
Can be problem in that I using OnCaretMove event for update styles control toolbar?
P.S. I know in manual says:
Warning: This event may occur when document is not completely formatted! Do not use any methods relying on formatting inside this event, including methods working with selection (for example, do not use SelectionExists here). If you need to update user interface reflecting selection, use OnSelect.
P.P.S. However all style changes performs through ApplyStyleConversion/ApplyParaStyleConversion
Posted: Thu Mar 25, 2010 8:46 am
by vit
Sergey, you was right!
This function is called when accessing incorrect text style (StyleNo<0 or StyleNo>=TextStyles.Count).
Assertions have shown violation! I was just passed wrong styleNo in some caller of this methods.
So I hope this exception will disapear now.
Thank you!
Posted: Mon Jun 28, 2010 7:14 am
by vit
Hi again!
We have exceptions with spell checking again!
Exceptions occure when I
reopen window with TRichViewEdits.
This is FastMM4 report
Code: Select all
--------------------------------2010/6/28 10:35:49--------------------------------
FastMM has detected an error during a GetMem operation. FastMM detected that a block has been modified after being freed.
Modified byte offsets (and lengths): 14(1)
The previous block size was: 108
This block was previously allocated by thread 0x790, and the stack trace (return addresses) at the time was:
402AEF [System][@GetMem]
4043C3 [System][TObject.NewInstance]
40478A [System][@ClassCreate]
D0A742 [RVThread.pas][RVThread][TRVWordEnumThread.Create][96]
D3F720 [RichView.pas][RichView][TCustomRichView.StartLiveSpelling][3520]
E21F29 [TRichTextParamContent.StartLiveSpellChecking][986]
E21163 [TRichTextParamContent.IESwitchOn][532]
E1781E [TCustomParamContent.SwitchIE][516]
E17BE5 [TIESwitcher.SwitchAll][616]
E179F1 [TIESwitcher.OnTimer][560]
4A1E02 [ExtCtrls.pas][ExtCtrls][TTimer.Timer][1620]
4A1C70 [ExtCtrls.pas][ExtCtrls][TTimer.WndProc][1578]
47DF66 [Classes][StdWndProc]
7E368734 [Unknown function at GetDC]
7E368816 [Unknown function at GetDC]
7E3689CD [Unknown function at GetWindowLongW]
9A09C1 [AppEvnts.pas][AppEvnts][TCustomApplicationEvents.DoMessage][212]
The block was previously used for an object of class: TRVWordEnumThread
The allocation number was: 2049456
The block was previously freed by thread 0xABC, and the stack trace (return addresses) at the time was:
402B0F [System][@FreeMem]
4043E1 [System][TObject.FreeInstance]
4047D5 [System][@ClassDestroy]
D0A7B1 [RVThread.pas][RVThread][TRVWordEnumThread.Destroy][106]
404427 [System][TObject.Free]
47C43D [Classes][ThreadProc]
4052D6 [System][ThreadWrapper]
455AB7 [madExcept][CallThreadProcSafe]
455B24 [madExcept][ThreadExceptFrame]
7C80B713 [Unknown function at GetModuleFileNameA]
The current thread ID is 0x790, and the stack trace (return addresses) leading to this error is:
40C921 [FastMM4.pas][FastMM4][DebugGetMem][6725]
402AEF [System][@GetMem]
4043C3 [System][TObject.NewInstance]
40478A [System][@ClassCreate]
D0A742 [RVThread.pas][RVThread][TRVWordEnumThread.Create][96]
4C02FE [Controls.pas][Controls][TWinControl.Repaint][7613]
E23ED4 [TRichTextParamContent.PerformResizeRequest][1860]
D3F720 [RichView.pas][RichView][TCustomRichView.StartLiveSpelling][3520]
E21F29 [TRichTextParamContent.StartLiveSpellChecking][986]
E2123E [TRichTextParamContent.SetContent][557]
After I close window first time TRVWordEnumThread is destroyed. But when I open it again this error occured.
Remark: becouse our forms may contain very many controls, we make it visible according window scroll position with using timer.
Can you help me with this?
Posted: Wed Jun 30, 2010 6:32 am
by vit
I think you should ignore my last post. This report generated by FastMM right before EOutOfMemory exception is throwed. It's seems like there is no available memory to create new thread.