Module

uSpell

Path

C:\CPRS\CPRS30\uSpell.pas

Last Modified

7/15/2014 3:26:44 PM

Comments

Word settings need to be restored to origional settings!

Initialization Code

initialization

Finalization Code

finalization
  KillSpellCheck;

end.

Units Used in Interface

Name Comments
rCore -

Units Used in Implementation

Name Comments
fSpellNotify -
uInit -

Classes

Name Comments
TMSWordThread -

Procedures

Name Owner Declaration Scope Comments
Append - procedure Append(txt: string); Local -
BuildResultMessage - procedure BuildResultMessage; Local -
ConfigDoc TMSWordThread procedure ConfigDoc; Private -
ConfigWord TMSWordThread procedure ConfigWord; Private -
CreateDocument TMSWordThread procedure CreateDocument; Private -
DoCheck TMSWordThread procedure DoCheck; Private -
DoSpellCheck - procedure DoSpellCheck(SpellCheck: boolean; AnEditControl: TCustomMemo); Global -
EnableAppActivation - procedure EnableAppActivation; Local -
Execute TMSWordThread procedure Execute; override; Protected -
ExitWord TMSWordThread procedure ExitWord; Private -
FindDocumentWindow TMSWordThread procedure FindDocumentWindow; Private -
GetDialogs TMSWordThread procedure GetDialogs; Private
Var
  DispParams: TDispParams;
  OleArgs: array of OleVariant;
  ExcepInfo: TExcepInfo;
  Status: integer;
GetTextFromComponent - procedure GetTextFromComponent; Local -
GrammarCheckForControl - procedure GrammarCheckForControl(AnEditControl: TCustomMemo); Interfaced -
InternalSpellCheck - procedure InternalSpellCheck(SpellCheck: boolean; EditControl: TCustomMemo); Interfaced Do Not Call these routines - internal use only
KillSpellCheck - procedure KillSpellCheck; Interfaced -
LoadUserSettings TMSWordThread procedure LoadUserSettings; Private -
OnAppActivate TMSWordThread procedure OnAppActivate(Sender: TObject); Private -
OnFormChange TMSWordThread procedure OnFormChange(Sender: TObject); Private -
OnThreadTerminate TMSWordThread procedure OnThreadTerminate(Sender: TObject); Private -
RefocusSpellCheckDialog TMSWordThread procedure RefocusSpellCheckDialog; Public -
RefocusSpellCheckWindow - procedure RefocusSpellCheckWindow; Interfaced -
ReportResults TMSWordThread procedure ReportResults; Private -
RestoreWordSettings TMSWordThread procedure RestoreWordSettings; Private -
Run - procedure Run(AMethod: TThreadMethod; force: boolean = false); Local -
Save - procedure Save(Value, Index: integer); Local -
SaveSetting - procedure SaveSetting(Value: boolean; Index: integer); Local -
SaveUserSettings TMSWordThread procedure SaveUserSettings; Private -
SaveWordSettings TMSWordThread procedure SaveWordSettings; Private -
SetStatus - procedure SetStatus(value, force: boolean); Local -
SpellCheckForControl - procedure SpellCheckForControl(AnEditControl: TCustomMemo); Interfaced -
StartWord TMSWordThread procedure StartWord; Private -
ThreadLock TMSWordThread procedure ThreadLock; Private -
ThreadUnlock TMSWordThread procedure ThreadUnlock; Private -
TransferText TMSWordThread procedure TransferText; Private -
WordError TMSWordThread procedure WordError; Private -

Functions

Name Owner Declaration Scope Comments
BeforeLineInvalid - function BeforeLineInvalid(Line: string): boolean; Local -
ControlHasText - function ControlHasText(SpellCheck: boolean; AnEditControl: TCustomMemo): boolean; Global -
FindDocWindow - function FindDocWindow(Handle: HWND; Info: Pointer): BOOL; stdcall; Global -
Load - function Load(Index: integer): integer; Local -
RunWithErrorTrap TMSWordThread function RunWithErrorTrap(AMethod: TThreadMethod; SpellCheckErrorMessage, GrammarCheckErrorMessage, AdditionalErrorMessage: string; AllowRetry: boolean): boolean; Private -
SpellCheckAvailable - function SpellCheckAvailable: Boolean; Interfaced
Spell Checking using Visual Basic for Applications script 

const
  WORD_VBA_CLSID = 'CLSID\{000209FF-0000-0000-C000-000000000046}';
SpellCheckInProgress - function SpellCheckInProgress: Boolean; Interfaced -
UserSetting TMSWordThread function UserSetting(Index: integer): boolean; Private -
WordDocTitle - function WordDocTitle: string; Local -

Global Variables

Name Type Declaration Comments
MSWordThread TMSWordThread MSWordThread: TMSWordThread = nil; -
SpellCheckerSettings UnicodeString SpellCheckerSettings: string = ''; -
uSpellCheckAvailable uSpellCheckAvailable: TSpellCheckAvailable; -
WindowHandle HWND WindowHandle: HWnd; -
WindowTitle UnicodeString WindowTitle: string; -

Constants

Name Declaration Scope Comments
CRLF #13#10 Global -
RETRY_MAX 3 Global -
sFalseCode 'F' Global -
SpellCheckerSettingName 'SpellCheckerSettings' Interfaced -
sTrueCode 'T' Global -
TX_ERROR_INTRO 'An error has occured.' Global -
TX_ERROR_TITLE 'Error' Global -
TX_GRAMMAR_ABORT 'The grammar check terminated abnormally.' Global -
TX_GRAMMAR_CANCELLED 'Grammar check was cancelled before completion.' Global -
TX_GRAMMAR_COMPLETE 'The grammar check is complete.' Global -
TX_NO_CORRECTIONS 'Corrections have NOT been applied.' Global -
TX_NO_DETAILS 'No further details are available.' Global -
TX_NO_GRAMMAR_CHECK 'Grammar checking is unavailable.' Global -
TX_NO_SPELL_CHECK 'Spell checking is unavailable.' Global -
TX_SPELL_ABORT 'The spelling check terminated abnormally.' Global -
TX_SPELL_CANCELLED 'Spelling check was cancelled before completion.' Global -
TX_SPELL_COMPLETE 'The spelling check is complete.' Global -
TX_TRY_AGAIN 'Would you like to try again?' Global -
TX_WINDOW_TITLE 'CPRS-Chart Spell Checking #' Global -
usCheckGrammarAsYouType 2 Global -
usCheckGrammarWithSpelling 6 Global -
usCheckSpellingAsYouType 1 Global -
usHideGrammarErrors 11 Global -
usHideSpellingErrors 10 Global -
usIgnoreInternetAndFileAddresses 3 Global -
usIgnoreMixedDigits 4 Global -
usIgnoreUppercase 5 Global -
usShowReadabilityStatistics 7 Global -
usSuggestFromMainDictionaryOnly 8 Global -
usSuggestSpellingCorrections 9 Global -
VALID_STARTING_CHARS '''-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' Global TABOO_STARTING_CHARS = '!"#$%&()*+,./:;<=>?@[\]^_`{|}';
wsAFAYTApplyBorders 0 Global AFAYT = AutoFormatAsYouType
wsAFAYTApplyBulletedLists 1 Global -
wsAFAYTApplyFirstIndents 2 Global -
wsAFAYTApplyHeadings 3 Global -
wsAFAYTApplyNumberedLists 4 Global -
wsAFAYTApplyTables 5 Global -
wsAFAYTAutoLetterWizard 6 Global -
wsAFAYTDefineStyles 7 Global -
wsAFAYTFormatListItemBeginning 8 Global -
wsAFAYTInsertClosings 9 Global -
wsAFAYTReplaceFractions 11 Global -
wsAFAYTReplaceHyperlinks 12 Global -
wsAFAYTReplaceOrdinals 13 Global -
wsAFAYTReplacePlainTextEmphasis 14 Global -
wsAFAYTReplaceQuotes 10 Global -
wsAFAYTReplaceSymbols 15 Global -
wsAutoFormatReplaceQuotes 16 Global -
wsSaveInterval 19 Global -
wsShowRevisions 21 Global -
wsShowSummary 22 Global Not used for Word 2010
wsTabIndentKey 17 Global -
wsTrackRevisions 20 Global -
wsWindowState 18 Global -


Module Source

1     unit uSpell;
2     // Word settings need to be restored to origional settings!
3     {$O-}
4     
5     {$DEFINE CPRS}
6     {$UNDEF CPRS}
7     
8     interface
9     
10    uses
11      Windows, Messages, SysUtils, Classes, Controls, Forms, ComObj, StdCtrls, ComCtrls,
12      rCore, ORFn, Word2000, Office_TLB, Variants, clipbrd, ActiveX, Contnrs, PSAPI, ExtCtrls;
13    
14    type
15      TSpellCheckAvailable = record
16        Evaluated: boolean;
17        Available: boolean;
18      end;
19    
20    function  SpellCheckInProgress: Boolean;
21    procedure KillSpellCheck;
22    function  SpellCheckAvailable: Boolean;
23    procedure SpellCheckForControl(AnEditControl: TCustomMemo);
24    procedure GrammarCheckForControl(AnEditControl: TCustomMemo);
25    
26    // Do Not Call these routines - internal use only
27    procedure InternalSpellCheck(SpellCheck: boolean; EditControl: TCustomMemo);
28    procedure RefocusSpellCheckWindow;
29    
30    const
31      SpellCheckerSettingName = 'SpellCheckerSettings';
32    
33    var
34      SpellCheckerSettings: string = '';
35    
36      
37    implementation
38    
39    uses VAUtils, fSpellNotify, uInit;
40    
41    const
42      TX_ERROR_TITLE        = 'Error';
43      TX_ERROR_INTRO        = 'An error has occured.';
44      TX_TRY_AGAIN          = 'Would you like to try again?';
45      TX_WINDOW_TITLE       = 'CPRS-Chart Spell Checking #';
46      TX_NO_SPELL_CHECK     = 'Spell checking is unavailable.';
47      TX_NO_GRAMMAR_CHECK   = 'Grammar checking is unavailable.';
48      TX_SPELL_COMPLETE     = 'The spelling check is complete.';
49      TX_GRAMMAR_COMPLETE   = 'The grammar check is complete.';
50      TX_SPELL_ABORT        = 'The spelling check terminated abnormally.';
51      TX_GRAMMAR_ABORT      = 'The grammar check terminated abnormally.';
52      TX_SPELL_CANCELLED    = 'Spelling check was cancelled before completion.';
53      TX_GRAMMAR_CANCELLED  = 'Grammar check was cancelled before completion.';
54      TX_NO_DETAILS         = 'No further details are available.';
55      TX_NO_CORRECTIONS     = 'Corrections have NOT been applied.';
56      CRLF                  = #13#10;
57    //  TABOO_STARTING_CHARS  = '!"#$%&()*+,./:;<=>?@[\]^_`{|}';
58      VALID_STARTING_CHARS  = '''-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
59    
60    type
61      TMSWordThread = class(TThread)
62      private
63        FBeforeLines: TStringList;
64        FAfterLines: TStringList;
65        FWordSettings: TList;
66        FEditControl: TCustomMemo;
67        FShowingMessage: boolean;
68    //    FEmptyVar: OleVariant;
69        FFalseVar: OleVariant;
70    //    FTrueVar: OleVariant;
71        FNullStr: OleVariant;
72        FWord: WordApplication;
73        FDoc: WordDocument;
74        FWordVersion: single;
75        FDialog: OleVariant;
76        FDocDlg: OleVariant;
77        FText: string;
78        FSpellCheck: boolean;
79        FSucceeded: boolean;
80        FCanceled: boolean;
81        FTitle: string;
82        FDocWindowHandle: HWnd;
83        FOldFormChange: TNotifyEvent;
84        FOldOnActivate: TNotifyEvent;
85        FError: Exception;
86        FErrorText1: string;
87        FErrorText2: string;
88        FAllowErrorRetry: boolean;
89        FRetryResult: TShow508MessageResult;
90        FResultMessage: string;
91        FSpellChecking: boolean;
92        FLock: TRTLCriticalSection;
93        procedure OnFormChange(Sender: TObject);
94        procedure OnAppActivate(Sender: TObject);
95        procedure OnThreadTerminate(Sender: TObject);
96        procedure FindDocumentWindow;
97        procedure TransferText;
98        function RunWithErrorTrap(AMethod: TThreadMethod;
99          SpellCheckErrorMessage, GrammarCheckErrorMessage, AdditionalErrorMessage: string;
100         AllowRetry: boolean): boolean;
101       procedure WordError;
102       procedure StartWord;
103       procedure CreateDocument;
104       procedure DoCheck;
105       procedure ConfigWord;
106       procedure ConfigDoc;
107       procedure GetDialogs;
108       procedure SaveUserSettings;
109       procedure LoadUserSettings;
110       procedure ExitWord;
111       procedure ReportResults;
112       procedure SaveWordSettings;
113       procedure RestoreWordSettings;
114       function UserSetting(Index: integer): boolean;
115       procedure ThreadLock;
116       procedure ThreadUnlock;
117     protected
118       constructor CreateThread(SpellCheck: boolean; AEditControl: TCustomMemo);
119       procedure Execute; override;
120     public
121       procedure RefocusSpellCheckDialog;
122       property Text: string read FText;
123       property Succeeded: boolean read FSucceeded;
124       property Canceled: boolean read FCanceled;
125     end;
126   
127   var
128     MSWordThread: TMSWordThread = nil;
129   
130   function ControlHasText(SpellCheck: boolean; AnEditControl: TCustomMemo): boolean;
131   var
132     i: integer;
133   begin
134     Result := FALSE;
135     if not assigned(AnEditControl) then
136       ShowMsg('Spell Check programming error')
137     else
138     begin
139       for i := 0 to AnEditControl.Lines.Count - 1 do
140       begin
141         if trim(AnEditControl.Lines[i]) <> '' then
142         begin
143           Result := TRUE;
144           break;
145         end;
146       end;
147       if not Result then
148       begin
149         if SpellCheck then
150           ShowMsg(TX_SPELL_COMPLETE)
151         else
152           ShowMsg(TX_GRAMMAR_COMPLETE)
153       end;
154     end;
155   end;
156   
157   function SpellCheckInProgress: boolean;
158   begin
159     Result := assigned(MSWordThread);
160   end;
161   
162   var
163     uSpellCheckAvailable: TSpellCheckAvailable;
164   
165   procedure KillSpellCheck;
166   var
167     checking: boolean;
168     WordHandle: HWnd;
169     ProcessID: DWORD;
170     ProcessHandle: THandle;
171     
172   begin
173     if assigned(MSWordThread) then
174     begin
175       with MSWordThread do
176       begin
177         ThreadLock;
178         try
179           checking := FSpellChecking;
180           WordHandle := FDocWindowHandle;
181           Terminate;
182         finally
183           ThreadUnlock;
184         end;
185         try
186           if checking then
187           begin
188             GetWindowThreadProcessId(WordHandle, ProcessID);
189             ProcessHandle := OpenProcess(PROCESS_TERMINATE, False, ProcessID);
190             try
191               TerminateProcess(ProcessHandle, 0);
192             finally
193               CloseHandle(ProcessHandle);
194             end;
195           end;
196           if assigned(MSWordThread) then
197           begin
198             WaitFor;
199           end;
200         except
201         end;
202       end;
203     end;
204   end;
205   
206   
207   { Spell Checking using Visual Basic for Applications script }
208   
209   function SpellCheckAvailable: Boolean;
210   //const
211   //  WORD_VBA_CLSID = 'CLSID\{000209FF-0000-0000-C000-000000000046}';
212   begin
213   // CHANGED FOR PT. SAFETY ISSUE RELEASE 19.16, PATCH OR*3*155 - ADDED NEXT 2 LINES:
214     //result := false;
215     //exit;
216   //  Reenabled in version 21.1, via parameter setting  (RV)
217   //  Result := (GetUserParam('ORWOR SPELL CHECK ENABLED?') = '1');
218     with uSpellCheckAvailable do        // only want to call this once per session!!!  v23.10+
219       begin
220         if not Evaluated then
221           begin
222             Available := (GetUserParam('ORWOR SPELL CHECK ENABLED?') = '1');
223             Evaluated := True;
224           end;
225         Result := Available;
226       end;
227   end;
228   
229   procedure DoSpellCheck(SpellCheck: boolean; AnEditControl: TCustomMemo);
230   var
231     frmSpellNotify: TfrmSpellNotify;
232   
233   begin
234     if assigned(MSWordThread) then exit;
235     if ControlHasText(SpellCheck, AnEditControl) then
236     begin
237       frmSpellNotify := TfrmSpellNotify.Create(Application);
238       try
239         SuspendTimeout;
240         try
241           frmSpellNotify.SpellCheck := SpellCheck;
242           frmSpellNotify.EditControl := AnEditControl;
243           frmSpellNotify.ShowModal;
244         finally
245           ResumeTimeout;
246         end;
247       finally
248         frmSpellNotify.Free;
249       end;
250     end;
251   end;
252   
253   procedure InternalSpellCheck(SpellCheck: boolean; EditControl: TCustomMemo);
254   begin
255     MSWordThread := TMSWordThread.CreateThread(SpellCheck, EditControl);
256     while assigned(MSWordThread) do
257     begin
258       Application.ProcessMessages;
259       sleep(50);
260     end;
261   end;
262   
263   procedure RefocusSpellCheckWindow;
264   begin
265     if assigned(MSWordThread) then
266       MSWordThread.RefocusSpellCheckDialog;
267   end;
268   
269   procedure SpellCheckForControl(AnEditControl: TCustomMemo);
270   begin
271     DoSpellCheck(True, AnEditControl);
272   end;
273   
274   procedure GrammarCheckForControl(AnEditControl: TCustomMemo);
275   begin
276     DoSpellCheck(False, AnEditControl);
277   end;
278   { TMSWordThread }
279   
280   const
281     RETRY_MAX = 3;
282   
283     usCheckSpellingAsYouType          = 1;
284     usCheckGrammarAsYouType           = 2;
285     usIgnoreInternetAndFileAddresses  = 3;
286     usIgnoreMixedDigits               = 4;
287     usIgnoreUppercase                 = 5;
288     usCheckGrammarWithSpelling        = 6;
289     usShowReadabilityStatistics       = 7;
290     usSuggestFromMainDictionaryOnly   = 8;
291     usSuggestSpellingCorrections      = 9;
292     usHideSpellingErrors              = 10;
293     usHideGrammarErrors               = 11;
294   
295     sTrueCode   = 'T';
296     sFalseCode  = 'F';
297   
298       // AFAYT = AutoFormatAsYouType
299     wsAFAYTApplyBorders             = 0;
300     wsAFAYTApplyBulletedLists       = 1;
301     wsAFAYTApplyFirstIndents        = 2;
302     wsAFAYTApplyHeadings            = 3;
303     wsAFAYTApplyNumberedLists       = 4;
304     wsAFAYTApplyTables              = 5;
305     wsAFAYTAutoLetterWizard         = 6;
306     wsAFAYTDefineStyles             = 7;
307     wsAFAYTFormatListItemBeginning  = 8;
308     wsAFAYTInsertClosings           = 9;
309     wsAFAYTReplaceQuotes            = 10;
310     wsAFAYTReplaceFractions         = 11;
311     wsAFAYTReplaceHyperlinks        = 12;
312     wsAFAYTReplaceOrdinals          = 13;
313     wsAFAYTReplacePlainTextEmphasis = 14;
314     wsAFAYTReplaceSymbols           = 15;
315     wsAutoFormatReplaceQuotes       = 16;
316     wsTabIndentKey                  = 17;
317     wsWindowState                   = 18;
318     wsSaveInterval                  = 19;
319     wsTrackRevisions                = 20;
320     wsShowRevisions                 = 21;
321     wsShowSummary                   = 22; // not used for Word 2010
322   
323   procedure TMSWordThread.Execute;
324   var
325     ok: boolean;
326   
327     procedure EnableAppActivation;
328     begin
329       FWord.Caption := FTitle;
330       Synchronize(FindDocumentWindow);
331     end;
332   
333     procedure Run(AMethod: TThreadMethod; force: boolean = false);
334     begin
335       if terminated then exit;
336       if ok or force then
337       begin
338         ok := RunWithErrorTrap(AMethod, TX_SPELL_ABORT, TX_GRAMMAR_ABORT, '', FALSE);
339       end;
340     end;
341   
342     procedure BuildResultMessage;
343     begin
344       FResultMessage := '';
345       if FCanceled or (not FSucceeded) then
346       begin
347         if FSpellCheck then
348           FResultMessage := TX_SPELL_CANCELLED
349         else
350           FResultMessage := TX_GRAMMAR_CANCELLED;
351         FResultMessage := FResultMessage + CRLF + TX_NO_CORRECTIONS;
352       end
353       else
354       if FSucceeded then
355       begin
356         if FSpellCheck then
357           FResultMessage := TX_SPELL_COMPLETE
358         else
359           FResultMessage := TX_GRAMMAR_COMPLETE;
360       end;
361     end;
362   
363     procedure SetStatus(value, force: boolean);
364     begin
365       if ok or force then
366       begin
367         ThreadLock;
368         FSpellChecking := value;
369         ThreadUnlock;
370       end;
371     end;
372   
373   begin
374     CoInitialize(nil);
375     ok := true;
376     try
377       if RunWithErrorTrap(StartWord, TX_NO_SPELL_CHECK, TX_NO_GRAMMAR_CHECK, TX_TRY_AGAIN, TRUE) then
378       begin
379         try
380           if RunWithErrorTrap(CreateDocument, TX_SPELL_ABORT, TX_GRAMMAR_ABORT, '', FALSE) then
381           begin
382             try
383               EnableAppActivation;
384               Run(SaveWordSettings);
385               Run(ConfigWord);
386               Run(ConfigDoc);
387               Run(GetDialogs);
388               Run(LoadUserSettings);
389               SetStatus(True, False);
390               Run(DoCheck);
391               SetStatus(False, True);
392               Run(SaveUserSettings);
393               Run(RestoreWordSettings);
394               Run(ExitWord, True);
395               if ok and (not terminated) then
396               begin
397                 Synchronize(TransferText);
398                 BuildResultMessage;
399                 Synchronize(ReportResults);
400               end;
401             finally
402               FDoc := nil;
403             end;
404           end;
405         finally
406           FWord := nil;
407         end;
408       end;
409     finally
410       CoUninitialize;
411     end;
412   end;
413   
414   procedure TMSWordThread.ExitWord;
415   var
416     Save: OleVariant;
417     Doc: OleVariant;
418   
419   begin
420     VarClear(FDialog);
421     VarClear(FDocDlg);
422     VariantInit(Save);
423     VariantInit(Doc);
424     try
425       Save := wdDoNotSaveChanges;
426       Doc := wdWordDocument;
427       FWord.Quit(Save, Doc, FFalseVar);
428     finally
429       VarClear(Save);
430       VarClear(Doc);
431     end;
432   end;
433   
434   var
435     WindowTitle: string;
436     WindowHandle: HWnd;
437   
438   function FindDocWindow(Handle: HWND; Info: Pointer): BOOL; stdcall;
439   var
440     title: string;
441   begin
442     title := GetWindowTitle(Handle);
443     if title = WindowTitle then
444     begin
445       WindowHandle := Handle;
446       Result := FALSE;
447     end
448     else
449       Result := True;
450   end;
451   
452   procedure TMSWordThread.FindDocumentWindow;
453   begin
454     WindowTitle := FTitle;
455     WindowHandle := 0;
456     EnumWindows(@FindDocWindow, 0);
457     FDocWindowHandle := WindowHandle;
458   end;
459   
460   procedure TMSWordThread.GetDialogs;
461   //var
462   //  DispParams: TDispParams;
463   //  OleArgs: array of OleVariant;
464   //  ExcepInfo: TExcepInfo;
465   //  Status: integer;
466   begin
467   //  SetLength(OleArgs, 1);
468   //  VariantInit(OleArgs[0]);
469   //  try
470       VariantInit(FDialog);
471       FDialog := FWord.Dialogs.Item(wdDialogToolsOptionsSpellingAndGrammar);
472       VariantInit(FDocDlg);
473       FDocDlg := FWord.ActiveDocument;
474   (*    OleArgs[0] := wdDialogToolsOptionsSpellingAndGrammar;
475       DispParams.rgvarg := @OleArgs[0];
476       DispParams.cArgs := 1;
477       DispParams.rgdispidNamedArgs := nil;
478       DispParams.cNamedArgs := 0;
479   //    FDialog := FWord.Dialogs.Item(wdDialogToolsOptionsSpellingAndGrammar);
480       // dispid 0 is the Item method
481       Status := FWord.Dialogs.Invoke(0, GUID_NULL, LOCALE_USER_DEFAULT,
482           DISPATCH_METHOD or DISPATCH_PROPERTYGET, DispParams, @FDialog, @ExcepInfo, nil);
483       if Status <> S_OK then
484         DispatchInvokeError(Status, ExcepInfo);
485       VariantInit(FDocDlg);
486       DispParams.rgvarg := nil;
487       DispParams.cArgs := 0;
488       Status := FWord.Invoke(3, GUID_NULL, LOCALE_USER_DEFAULT,
489           DISPATCH_METHOD or DISPATCH_PROPERTYGET, DispParams, @FDocDlg, @ExcepInfo, nil);
490       if Status <> S_OK then
491         DispatchInvokeError(Status, ExcepInfo);
492     finally
493       VarClear(OleArgs[0]);
494       SetLength(OleArgs, 0);
495     end;                                       *)
496   end;
497   
498   procedure TMSWordThread.LoadUserSettings;
499   begin
500     // load FUserSettings from server
501   
502     // these are default values
503     (*
504   9  AlwaysSuggest,
505   8  SuggestFromMainDictOnly,
506   5  IgnoreAllCaps,
507   4  IgnoreMixedDigits,
508     ResetIgnoreAll,
509     Type, CustomDict1, CustomDict2, CustomDict3, CustomDict4, CustomDict5, CustomDict6,
510     CustomDict7, CustomDict8, CustomDict9, CustomDict10,
511   1  AutomaticSpellChecking,
512   3  FilenamesEmailAliases,
513     UserDict1,
514   2  AutomaticGrammarChecking,
515   6??  ForegroundGrammar,
516   7  ShowStatistics,
517     Options, RecheckDocument, IgnoreAuxFind, IgnoreMissDictSearch,
518   10  HideGrammarErrors,
519     CheckSpelling, GrLidUI, SpLidUI,
520     DictLang1, DictLang2, DictLang3,
521     DictLang4, DictLang5, DictLang6, DictLang7, DictLang8, DictLang9, DictLang10,
522   11  HideSpellingErrors,
523     HebSpellStart, InitialAlefHamza, FinalYaa, GermanPostReformSpell,
524     AraSpeller, ProcessCompoundNoun
525     *)
526   //  FDialog.
527     ThreadLock;
528     try
529       FDialog.AutomaticSpellChecking   := UserSetting(usCheckSpellingAsYouType);
530       FDialog.AutomaticGrammarChecking := UserSetting(usCheckGrammarAsYouType);
531       FDialog.FilenamesEmailAliases    := UserSetting(usIgnoreInternetAndFileAddresses);
532       FDialog.IgnoreMixedDigits        := UserSetting(usIgnoreMixedDigits);
533       FDialog.ForegroundGrammar        := UserSetting(usCheckGrammarWithSpelling);
534       FDialog.ShowStatistics           := UserSetting(usShowReadabilityStatistics);
535       FDialog.SuggestFromMainDictOnly  := UserSetting(usSuggestFromMainDictionaryOnly);
536       FDialog.IgnoreAllCaps            := UserSetting(usIgnoreUppercase);
537       FDialog.AlwaysSuggest            := UserSetting(usSuggestSpellingCorrections);
538       FDialog.HideSpellingErrors       := UserSetting(usHideSpellingErrors);
539       FDialog.HideGrammarErrors        := UserSetting(usHideGrammarErrors);
540       FDialog.Execute;
541     finally
542       ThreadUnlock;
543     end;
544   
545      // need list of custom dictionaries - default to CUSTOM.DIC (or query Word for it!!!)
546   //  FWord.CustomDictionaries
547   
548   end;
549   
550   procedure TMSWordThread.OnAppActivate(Sender: TObject);
551   begin
552     if assigned(FOldOnActivate) then
553       FOldOnActivate(Sender);
554     RefocusSpellCheckDialog;
555   end;
556   
557   procedure TMSWordThread.OnFormChange(Sender: TObject);
558   begin
559     if assigned(FOldFormChange) then
560       FOldFormChange(Sender);
561     RefocusSpellCheckDialog;
562   end;
563   
564   procedure TMSWordThread.OnThreadTerminate(Sender: TObject);
565   begin
566     Application.OnActivate := FOldOnActivate;
567     Screen.OnActiveFormChange := FOldFormChange;
568   //  VarClear(FEmptyVar);
569     VarClear(FFalseVar);
570   //  VarClear(FTrueVar);
571     FWordSettings.Free;
572     FBeforeLines.Free;
573     FAfterLines.Free;
574     DeleteCriticalSection(FLock);
575     Screen.Cursor := crDefault;
576     MSWordThread := nil;
577   end;
578   
579   procedure TMSWordThread.RefocusSpellCheckDialog;
580   begin
581     Application.ProcessMessages;
582     if Application.Active and (not FShowingMessage) and (FDocWindowHandle <> 0) then
583     begin
584       SetForegroundWindow(FDocWindowHandle);
585       SetFocus(FDocWindowHandle);
586     end;
587   end;
588   
589   procedure TMSWordThread.ReportResults;
590   var
591     icon: TShow508MessageIcon;
592   begin
593     if FSucceeded then
594       icon := smiInfo
595     else
596       icon := smiWarning;
597     FShowingMessage := True;
598     try
599       ShowMsg(FResultMessage, icon, smbOK);
600     finally
601       FShowingMessage := False;
602     end;
603   end;
604   
605   procedure TMSWordThread.RestoreWordSettings;
606   
607     function Load(Index: integer): integer;
608     begin
609       if FWordSettings.Count > Index then
610         Result := Integer(FWordSettings[Index])
611       else
612         Result := 0
613     end;
614   
615   begin
616     FWord.Options.AutoFormatAsYouTypeApplyBorders             := boolean(Load(wsAFAYTApplyBorders));
617     FWord.Options.AutoFormatAsYouTypeApplyBulletedLists       := boolean(Load(wsAFAYTApplyBulletedLists));
618     FWord.Options.AutoFormatAsYouTypeApplyFirstIndents        := boolean(Load(wsAFAYTApplyFirstIndents));
619     FWord.Options.AutoFormatAsYouTypeApplyHeadings            := boolean(Load(wsAFAYTApplyHeadings));
620     FWord.Options.AutoFormatAsYouTypeApplyNumberedLists       := boolean(Load(wsAFAYTApplyNumberedLists));
621     FWord.Options.AutoFormatAsYouTypeApplyTables              := boolean(Load(wsAFAYTApplyTables));
622     FWord.Options.AutoFormatAsYouTypeAutoLetterWizard         := boolean(Load(wsAFAYTAutoLetterWizard));
623     FWord.Options.AutoFormatAsYouTypeDefineStyles             := boolean(Load(wsAFAYTDefineStyles));
624     FWord.Options.AutoFormatAsYouTypeFormatListItemBeginning  := boolean(Load(wsAFAYTFormatListItemBeginning));
625     FWord.Options.AutoFormatAsYouTypeInsertClosings           := boolean(Load(wsAFAYTInsertClosings));
626     FWord.Options.AutoFormatAsYouTypeReplaceQuotes            := boolean(Load(wsAFAYTReplaceQuotes));
627     FWord.Options.AutoFormatAsYouTypeReplaceFractions         := boolean(Load(wsAFAYTReplaceFractions));
628     FWord.Options.AutoFormatAsYouTypeReplaceHyperlinks        := boolean(Load(wsAFAYTReplaceHyperlinks));
629     FWord.Options.AutoFormatAsYouTypeReplaceOrdinals          := boolean(Load(wsAFAYTReplaceOrdinals));
630     FWord.Options.AutoFormatAsYouTypeReplacePlainTextEmphasis := boolean(Load(wsAFAYTReplacePlainTextEmphasis));
631     FWord.Options.AutoFormatAsYouTypeReplaceSymbols           := boolean(Load(wsAFAYTReplaceSymbols));
632     FWord.Options.AutoFormatReplaceQuotes                     := boolean(Load(wsAutoFormatReplaceQuotes));
633     FWord.Options.TabIndentKey                                := boolean(Load(wsTabIndentKey));
634     FWord.WindowState                                         := Load(wsWindowState);
635     FWord.Options.SaveInterval                                := Load(wsSaveInterval);
636     FDoc.TrackRevisions                                       := boolean(Load(wsTrackRevisions));
637     FDoc.ShowRevisions                                        := boolean(Load(wsShowRevisions));
638     if (FWordVersion < 13) then                               // altered for Word 2010
639       FDoc.ShowSummary                                        := boolean(Load(wsShowSummary));
640   end;
641   
642   function TMSWordThread.RunWithErrorTrap(AMethod: TThreadMethod;
643     SpellCheckErrorMessage, GrammarCheckErrorMessage,
644     AdditionalErrorMessage: string; AllowRetry: boolean): boolean;
645   var
646     RetryCount: integer;
647     Done: boolean;
648   begin
649     RetryCount := 0;
650     Result := TRUE;
651     repeat
652       Done := TRUE;
653       try
654         AMethod;
655       except
656         on E: Exception do
657         begin
658           if not terminated then
659           begin
660             inc(RetryCount);
661             Done := FALSE;
662             if RetryCount >= RETRY_MAX then
663             begin
664               FError := E;
665               FAllowErrorRetry := AllowRetry;
666               if FSpellCheck then
667                 FErrorText1 := SpellCheckErrorMessage
668               else
669                 FErrorText1 := GrammarCheckErrorMessage;
670               FErrorText2 := AdditionalErrorMessage;
671               Synchronize(WordError);
672               if AllowRetry and (FRetryResult = smrRetry) then
673                 RetryCount := 0
674               else
675               begin
676                 Result := FALSE;
677                 Done := TRUE;
678               end;
679             end;
680           end;
681         end;
682       end;
683     until Done;
684   end;
685   
686   procedure TMSWordThread.DoCheck;
687   begin
688     FDoc.Content.Text := FText;
689     FDoc.Content.SpellingChecked := False;
690     FDoc.Content.GrammarChecked := False;
691     if FSpellCheck then
692     begin
693       FDocDlg.Content.CheckSpelling;
694   //      FDoc.CheckSpelling(FNullStr, FEmptyVar, FEmptyVar, {Ignore, Suggest, }FNullStr, FNullStr,
695   //                         FNullStr, FNullStr, FNullStr, FNullStr, FNullStr, FNullStr, FNullStr);
696       FSucceeded := FDoc.Content.SpellingChecked;
697       FText := FDoc.Content.Text;
698     end
699     else
700     begin
701       FDoc.Content.CheckGrammar;
702       FSucceeded := FDoc.Content.GrammarChecked;
703       FText := FDoc.Content.Text;
704     end;
705     FCanceled := (FText = '');
706   end;
707   
708   procedure TMSWordThread.SaveUserSettings;
709   
710     procedure SaveSetting(Value: boolean; Index: integer);
711     begin
712       while length(SpellCheckerSettings) < Index do
713         SpellCheckerSettings := SpellCheckerSettings + ' ';
714       if Value then
715         SpellCheckerSettings[Index] := sTrueCode
716       else
717         SpellCheckerSettings[Index] := sFalseCode;
718     end;
719   begin
720     ThreadLock;
721     try
722       SpellCheckerSettings := '';
723       FDialog.Update;
724       SaveSetting(FDialog.AutomaticSpellChecking,    usCheckSpellingAsYouType);
725       SaveSetting(FDialog.AutomaticGrammarChecking,  usCheckGrammarAsYouType);
726       SaveSetting(FDialog.FilenamesEmailAliases,     usIgnoreInternetAndFileAddresses);
727       SaveSetting(FDialog.IgnoreMixedDigits,         usIgnoreMixedDigits);
728       SaveSetting(FDialog.IgnoreAllCaps,             usIgnoreUppercase);
729       SaveSetting(FDialog.ForegroundGrammar,         usCheckGrammarWithSpelling);
730       SaveSetting(FDialog.ShowStatistics,            usShowReadabilityStatistics);
731       SaveSetting(FDialog.SuggestFromMainDictOnly,   usSuggestFromMainDictionaryOnly);
732       SaveSetting(FDialog.AlwaysSuggest,             usSuggestSpellingCorrections);
733       SaveSetting(FDialog.HideSpellingErrors,        usHideSpellingErrors);
734       SaveSetting(FDialog.HideGrammarErrors,         usHideGrammarErrors);
735     finally
736       ThreadUnlock;
737     end;
738        (*
739   9  AlwaysSuggest,
740   8  SuggestFromMainDictOnly,
741   5  IgnoreAllCaps,
742   4  IgnoreMixedDigits,
743     ResetIgnoreAll,
744     Type, CustomDict1, CustomDict2, CustomDict3, CustomDict4, CustomDict5, CustomDict6,
745     CustomDict7, CustomDict8, CustomDict9, CustomDict10,
746   1  AutomaticSpellChecking,
747   3  FilenamesEmailAliases,
748     UserDict1,
749   2  AutomaticGrammarChecking,
750   6??  ForegroundGrammar,
751   7  ShowStatistics,
752     Options, RecheckDocument, IgnoreAuxFind, IgnoreMissDictSearch,
753   10  HideGrammarErrors,
754     CheckSpelling, GrLidUI, SpLidUI,
755     DictLang1, DictLang2, DictLang3,
756     DictLang4, DictLang5, DictLang6, DictLang7, DictLang8, DictLang9, DictLang10,
757   11  HideSpellingErrors,
758     HebSpellStart, InitialAlefHamza, FinalYaa, GermanPostReformSpell,
759     AraSpeller, ProcessCompoundNoun
760     *)
761   end;
762   
763   procedure TMSWordThread.SaveWordSettings;
764   
765     procedure Save(Value, Index: integer);
766     begin
767       while FWordSettings.Count <= Index do
768         FWordSettings.Add(nil);
769       FWordSettings[Index] := Pointer(Value);
770     end;
771   
772   begin
773     Save(Ord(FWord.Options.AutoFormatAsYouTypeApplyBorders)             , wsAFAYTApplyBorders);
774     Save(Ord(FWord.Options.AutoFormatAsYouTypeApplyBulletedLists)       , wsAFAYTApplyBulletedLists);
775     Save(Ord(FWord.Options.AutoFormatAsYouTypeApplyFirstIndents)        , wsAFAYTApplyFirstIndents);
776     Save(Ord(FWord.Options.AutoFormatAsYouTypeApplyHeadings)            , wsAFAYTApplyHeadings);
777     Save(Ord(FWord.Options.AutoFormatAsYouTypeApplyNumberedLists)       , wsAFAYTApplyNumberedLists);
778     Save(Ord(FWord.Options.AutoFormatAsYouTypeApplyTables)              , wsAFAYTApplyTables);
779     Save(Ord(FWord.Options.AutoFormatAsYouTypeAutoLetterWizard)         , wsAFAYTAutoLetterWizard);
780     Save(Ord(FWord.Options.AutoFormatAsYouTypeDefineStyles)             , wsAFAYTDefineStyles);
781     Save(Ord(FWord.Options.AutoFormatAsYouTypeFormatListItemBeginning)  , wsAFAYTFormatListItemBeginning);
782     Save(Ord(FWord.Options.AutoFormatAsYouTypeInsertClosings)           , wsAFAYTInsertClosings);
783     Save(Ord(FWord.Options.AutoFormatAsYouTypeReplaceQuotes)            , wsAFAYTReplaceQuotes);
784     Save(Ord(FWord.Options.AutoFormatAsYouTypeReplaceFractions)         , wsAFAYTReplaceFractions);
785     Save(Ord(FWord.Options.AutoFormatAsYouTypeReplaceHyperlinks)        , wsAFAYTReplaceHyperlinks);
786     Save(Ord(FWord.Options.AutoFormatAsYouTypeReplaceOrdinals)          , wsAFAYTReplaceOrdinals);
787     Save(Ord(FWord.Options.AutoFormatAsYouTypeReplacePlainTextEmphasis) , wsAFAYTReplacePlainTextEmphasis);
788     Save(Ord(FWord.Options.AutoFormatAsYouTypeReplaceSymbols)           , wsAFAYTReplaceSymbols);
789     Save(Ord(FWord.Options.AutoFormatReplaceQuotes)                     , wsAutoFormatReplaceQuotes);
790     Save(Ord(FWord.Options.TabIndentKey)                                , wsTabIndentKey);
791     Save(Ord(FWord.WindowState)                                         , wsWindowState);
792     Save(Ord(FWord.Options.SaveInterval)                                , wsSaveInterval);
793     Save(Ord(FDoc.TrackRevisions)                                       , wsTrackRevisions);
794     Save(Ord(FDoc.ShowRevisions)                                        , wsShowRevisions);
795     if (FWordVersion < 13) then                                         // altered for Word 2010
796       Save(Ord(FDoc.ShowSummary)                                        , wsShowSummary);
797   end;
798   
799   procedure TMSWordThread.StartWord;
800   begin
801     FWord := CoWordApplication.Create;
802     FWordVersion := StrToFloatDef(FWord.Version, 0.0);
803   end;
804   
805   procedure TMSWordThread.ThreadLock;
806   begin
807     EnterCriticalSection(FLock);
808   end;
809   
810   procedure TMSWordThread.ThreadUnlock;
811   begin
812     LeaveCriticalSection(FLock);
813   end;
814   
815   procedure TMSWordThread.TransferText;
816   var
817     i: integer;
818     Lines: TStringList;
819   begin
820     if FSucceeded and (not FCanceled) then
821     begin
822       Lines := TStringList.Create;
823       try
824         Lines.Text := FText;
825         // For some unknown reason spell check adds garbage lines to text
826         while (Lines.Count > 0) and (trim(Lines[Lines.Count-1]) = '') do
827           Lines.Delete(Lines.Count-1);
828         for i := 0 to FBeforeLines.Count-1 do
829           Lines.Insert(i, FBeforeLines[i]);
830         for i := 0 to FAfterLines.Count-1 do
831           Lines.Add(FAfterLines[i]);
832         FastAssign(Lines, FEditControl.Lines);
833       finally
834         Lines.Free;
835       end;
836     end;
837   end;
838   
839   function TMSWordThread.UserSetting(Index: integer): boolean;
840   begin
841     if SpellCheckerSettings = '' then
842     begin
843       case Index of
844         usCheckSpellingAsYouType:         Result := True;
845         usCheckGrammarAsYouType:          Result := False;
846         usIgnoreInternetAndFileAddresses: Result := True;
847         usIgnoreMixedDigits:              Result := True;
848         usIgnoreUppercase:                Result := True;
849         usCheckGrammarWithSpelling:       Result := False;
850         usShowReadabilityStatistics:      Result := False;
851         usSuggestFromMainDictionaryOnly:  Result := False;
852         usSuggestSpellingCorrections:     Result := True;
853         usHideSpellingErrors:             Result := False;
854         usHideGrammarErrors:              Result := True;
855         else                              Result := False;
856       end;
857     end
858     else
859       Result := copy(SpellCheckerSettings,Index,1) = sTrueCode;
860   end;
861   
862   procedure TMSWordThread.ConfigDoc;
863   begin
864     FDoc.TrackRevisions        := False;
865     FDoc.ShowRevisions         := False;
866     if (FWordVersion < 13) then            // altered for Word 2010
867       FDoc.ShowSummary         := False;
868     FWord.Height               := 1000;
869     FWord.Width                := 1000;
870     FWord.Top                  := -2000;
871     FWord.Left                 := -2000;
872   end;
873   
874   procedure TMSWordThread.ConfigWord;
875   begin
876   // save all old values to FWord, restore when done.
877     FWord.Options.AutoFormatAsYouTypeApplyBorders             := False;
878     FWord.Options.AutoFormatAsYouTypeApplyBulletedLists       := False;
879     FWord.Options.AutoFormatAsYouTypeApplyFirstIndents        := False;
880     FWord.Options.AutoFormatAsYouTypeApplyHeadings            := False;
881     FWord.Options.AutoFormatAsYouTypeApplyNumberedLists       := False;
882     FWord.Options.AutoFormatAsYouTypeApplyTables              := False;
883     FWord.Options.AutoFormatAsYouTypeAutoLetterWizard         := False;
884     FWord.Options.AutoFormatAsYouTypeDefineStyles             := False;
885     FWord.Options.AutoFormatAsYouTypeFormatListItemBeginning  := False;
886     FWord.Options.AutoFormatAsYouTypeInsertClosings           := False;
887     FWord.Options.AutoFormatAsYouTypeReplaceQuotes            := False;
888     FWord.Options.AutoFormatAsYouTypeReplaceFractions         := False;
889     FWord.Options.AutoFormatAsYouTypeReplaceHyperlinks        := False;
890     FWord.Options.AutoFormatAsYouTypeReplaceOrdinals          := False;
891     FWord.Options.AutoFormatAsYouTypeReplacePlainTextEmphasis := False;
892     FWord.Options.AutoFormatAsYouTypeReplaceSymbols           := False;
893     FWord.Options.AutoFormatReplaceQuotes                     := False;
894     FWord.Options.TabIndentKey                                := False;
895     FWord.WindowState                                         := wdWindowStateNormal;
896     FWord.Options.SaveInterval                                := 0;
897     FWord.ResetIgnoreAll;
898   end;
899   
900   procedure TMSWordThread.CreateDocument;
901   var
902     DocType: OleVariant;
903   begin
904     VariantInit(DocType);
905     try
906       DocType := wdNewBlankDocument;
907       FDoc := FWord.Documents.Add(FNullStr, FFalseVar, DocType, FFalseVar);
908       FDoc.Activate;
909     finally
910       VarClear(DocType);
911     end;
912   end;
913   
914   constructor TMSWordThread.CreateThread(SpellCheck: boolean; AEditControl: TCustomMemo);
915   
916     function WordDocTitle: string;
917     var
918       Guid: TGUID;
919     begin
920       if ActiveX.Succeeded(CreateGUID(Guid)) then
921         Result := GUIDToString(Guid)
922       else
923         Result := '';
924       Result := TX_WINDOW_TITLE + IntToStr(Application.Handle) + '/' + Result;
925     end;
926   
927     function BeforeLineInvalid(Line: string): boolean;
928     var
929       i: integer;
930     begin
931       Result := (trim(Line) = '');
932       if not Result then
933       begin
934         for I := 1 to length(Line) do
935           if pos(Line[i], VALID_STARTING_CHARS) > 0 then exit;
936         Result := True;
937       end;
938     end;
939   
940     procedure GetTextFromComponent;
941     var
942       Lines: TStrings;
943     begin
944       Lines := TStringList.Create;
945       try
946         FastAssign(AEditControl.Lines, Lines);
947   
948         while (Lines.Count > 0) and (trim(Lines[Lines.Count-1]) = '') do
949         begin
950           FAfterLines.Insert(0, Lines[Lines.Count-1]);
951           Lines.Delete(Lines.Count-1);
952         end;
953   
954         while (Lines.Count > 0) and (BeforeLineInvalid(Lines[0])) do
955         begin
956           FBeforeLines.Add(Lines[0]);
957           Lines.Delete(0);
958         end;
959   
960         FText := Lines.Text;
961       finally
962         Lines.Free;
963       end;
964     end;
965   
966   begin
967     inherited Create(TRUE);
968     Screen.Cursor := crHourGlass;
969     InitializeCriticalSection(FLock);
970     FBeforeLines := TStringList.Create;
971     FAfterLines := TStringList.Create;
972     FWordSettings := TList.Create;
973     FSpellChecking := False;
974     FEditControl := AEditControl;
975   //  VariantInit(FEmptyVar);
976     VariantInit(FFalseVar);
977   //  VariantInit(FTrueVar);
978     VariantInit(FNullStr);
979   //  TVarData(FEmptyVar).VType := VT_EMPTY;
980     TVarData(FFalseVar).VType := VT_BOOL;
981   //  TVarData(FTrueVar).VType := VT_BOOL;
982     TVarData(FNullStr).VType := VT_BSTR;
983   //  FEmptyVar := 0;
984     FFalseVar := 0;
985   //  FTrueVar := -1;
986     FNullStr := '';
987     FDocWindowHandle := 0;
988     FSpellCheck := SpellCheck;
989   
990     GetTextFromComponent;
991   
992     FSucceeded := FALSE;
993     FCanceled := FALSE;
994     FTitle := WordDocTitle;
995     FreeOnTerminate := True;
996     OnTerminate := OnThreadTerminate;
997     FOldOnActivate := Application.OnActivate;
998     Application.OnActivate := OnAppActivate;
999     FOldFormChange := Screen.OnActiveFormChange;
1000    Screen.OnActiveFormChange := OnFormChange;
1001    Resume;
1002  end;
1003  
1004  procedure TMSWordThread.WordError;
1005  var
1006    btn: TShow508MessageButton;
1007    msg: string;
1008  
1009    procedure Append(txt: string);
1010    begin
1011      if txt <> '' then
1012        msg := msg + CRLF + txt;
1013    end;
1014  
1015  begin
1016    if FAllowErrorRetry then
1017      btn := smbRetryCancel
1018    else
1019      btn := smbOK;
1020    msg := TX_ERROR_INTRO;
1021    Append(FErrorText1);
1022    if FError.Message <> '' then
1023      Append(FError.Message)
1024    else
1025      Append(TX_NO_DETAILS);
1026    Append(FErrorText2);
1027    FShowingMessage := True;
1028    try
1029      FRetryResult := ShowMsg(Msg, TX_ERROR_TITLE, smiError, btn);
1030    finally
1031      FShowingMessage := False;
1032    end;
1033  end;
1034  
1035  initialization
1036  
1037  finalization
1038    KillSpellCheck;
1039  
1040  end.

Module Calls (2 levels)


uSpell
 ├rCore
 │ └uCore
 ├fSpellNotify
 │ ├uConst
 │ └uSpell...
 └uInit
   └fTimeout

Module Called-By (2 levels)


                     uSpell
                   fFrame┤ 
              CPRSChart┤ │ 
                  fPage┤ │ 
                uOrders┤ │ 
                fODBase┤ │ 
                UBACore┤ │ 
                fOrders┤ │ 
                   uPCE┤ │ 
      fBALocalDiagnoses┤ │ 
             fEncVitals┤ │ 
                fVitals┤ │ 
                 fCover┤ │ 
                 rCover┤ │ 
              fPtSelMsg┤ │ 
                 fPtSel┤ │ 
            fOrdersSign┤ │ 
         fPrintLocation┤ │ 
                  fMeds┤ │ 
                fRptBox┤ │ 
                 fNotes┤ │ 
               fReports┤ │ 
                 fEncnt┤ │ 
                 fProbs┤ │ 
          fReportsPrint┤ │ 
                fGraphs┤ │ 
              fConsults┤ │ 
                fDCSumm┤ │ 
        fReminderDialog┤ │ 
                  fLabs┤ │ 
              fLabPrint┤ │ 
                fReview┤ │ 
            fIconLegend┤ │ 
           fOrdersPrint┤ │ 
               fSurgery┤ │ 
uVA508CPRSCompatibility┤ │ 
           fOrdersRenew┤ │ 
             fODConsult┤ │ 
                fODProc┤ │ 
                 fODRad┤ │ 
                 fODLab┤ │ 
                fODMeds┤ │ 
               fODMedIV┤ │ 
              fODVitals┤ │ 
                fODAuto┤ │ 
                 fOMSet┤ │ 
         fOrdersRelease┤ │ 
              fODMedNVA┤ │ 
         fOrdersOnChart┤ │ 
             fOCSession┤ │ 
              fODActive┤ │ 
               fPCEEdit┘ │ 
                fNotes...┤ 
             fConsults...┤ 
               fDCSumm...┤ 
          fTemplateEditor┤ 
              fFrame...┤ │ 
               fDrawers┤ │ 
              fNotes...┤ │ 
           fConsults...┤ │ 
             fDCSumm...┤ │ 
            fSurgery...┘ │ 
             fSpellNotify┤ 
              uSpell...┘ │ 
              fSurgery...┤ 
     fTemplateFieldEditor┘ 
              fNotes...┤   
           fConsults...┤   
             fDCSumm...┤   
     fTemplateEditor...┤   
            fSurgery...┘