source: cprs/branches/HealthSevak-CPRS/CPRS-Lib/Hans SpellCheck/skaSpellCheck.pas@ 1712

Last change on this file since 1712 was 1712, checked in by healthsevak, 9 years ago

fixed the bug related to extra spaces being introduced at the start of line after "Change" action

File size: 22.1 KB
Line 
1unit skaSpellCheck;
2(* ***************************** BEGIN LICENSE BLOCK **********************
3 *
4 * Copyright (C) 2015
5 * Sunil Kumar Arora (digitiger@gmail.com sunil@healthsevak.com)
6 * All Rights Reserved.
7 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8 *
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
13 *
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
17 * License.
18 *
19 * Alternatively, the content of this file maybe used under the terms of either
20 * the GNU General Public License Version 2 or later (the "GPL"), or the GNU
21 * Lesser General Public License Version 2.1 or later (the "LGPL"), in which
22 * case the provisions of the GPL or the LGPL are applicable instead of those
23 * above. If you wish to allow use of your version of this file only under the
24 * terms of either the GPL or the LGPL, and not to allow others to use your
25 * version of this file under the terms of the MPL, indicate your division by
26 * deleting the provisions above and replace them with the notice and other
27 * provisions required by the GPL or LGPL. If you do not delete the provisions
28 * above, a recipient may use your version of this file under the terms of any
29 * one of the MPL, the GPL or the LGPL.
30 *
31 * *********************** END LICENSE BLOCK *********************************)
32
33interface
34
35uses
36 Windows, Classes, SysUtils, ComCtrls, StdCtrls, Graphics;
37
38 const
39 AboutThis = 'A wrapper component developed by Sunil K Arora (digitiger@gmail.com) of HealthSevak using OpenSource HanSpell engine';
40type
41 TSpellState = (ssNotStarted, ssChecking, ssCancelled, ssCompleted);
42
43 TskaHunSpellChecker = class(TComponent)
44 private
45 FActiveOrLoaded: Boolean;
46 FpointerHunLib: Pointer;
47 FSourceEdit: TRichEdit;
48 FSuggestionList: TListbox;
49
50 FAffixFileName: string;
51 FDictFileName: string;
52 CurrentWord: String;
53 CurrentText: String;
54 FoundAt: Integer;
55 PosOfFirstCharInCurrentLine: integer;
56 CurrentLine: Integer;
57 FIgnore: TStringList;
58 WaitForUser: Boolean;
59 WordLength:integer;
60 WordPos: Integer;
61 PREditorWndProc:pointer;
62 FHighlightColor: TColor;
63 FShowCompletion: Boolean;
64 FpointerSpellComplete: String;
65 FStatus: TSpellState;
66 FUndoList: TStringList;
67 FCustDict: TStringList;
68 FCustom: String;
69 FModified: Boolean;
70 FHighlightEdit: TEdit;
71 FbtnClose: TButton;
72 FTxtBeforeManualEdit: String;
73 function AddCustomWord(aWord: String; isInternal: Boolean = False): Boolean;
74 overload; virtual;
75 Function CurrentWordDetail(WithPosition: Boolean= True): String;
76 function GetActive: Boolean;
77 function GetStatus: TSpellState;
78 procedure Initialize;
79 procedure SetActive(const Value: Boolean);
80 procedure SetAffixFileName(const Value: string);
81 procedure SetbtnClose(const Value: TButton);
82 procedure SetCustomDict(const Value: String);
83 procedure SetDictFileName(const Value: string);
84 procedure SetHighLightEdit(const Value: TEdit);
85 procedure SetSourceEdit(const Value: TRichEdit);
86 Function ShowMisSpelledWord:boolean;
87 procedure Loaded; override;
88 procedure ReplaceCurrentWordWith(const aNewWord: String);
89 function GetAboutThis: String;
90 procedure SaveForUndo(const Ignoring: Boolean=False);
91 procedure ShowBtnClose(const ShowIt: Boolean = True);
92 public
93 constructor Create(AOwner: TComponent); overload; override;
94 constructor Create(AOwner: TComponent; SourceTextRichEdit: TRichedit;
95 SuggestList: TListbox); ReIntroduce; overload;
96 destructor Destroy; override;
97
98 function AbortSpellCheck(Verbose: Boolean = True):Boolean;
99 function AddCustomWord: Boolean; overload; virtual;
100 procedure Change;
101 procedure ChangeAll;
102 procedure CheckSpelling;
103 procedure Close; virtual;
104 procedure CorrectWithMyWord;
105 procedure GetSuggestions(const aMisSpeltWord: string;
106 const SuggestionList: TStrings); dynamic;
107 procedure IgnoreAll;
108 procedure IgnoreOnce;
109 function IsMisspelled(const AWord: string): Boolean; dynamic;
110 procedure ManualChangeStart;
111 procedure ManualChangeDone;
112 function Open:Boolean; virtual;
113 function ReStart: Boolean; virtual;
114
115 function Undo: Boolean;
116
117
118 property SpellCheckState: TSpellState read GetStatus default ssNotStarted;
119 published
120 property About: String read GetAboutThis;
121 property Active: Boolean read GetActive write SetActive;
122 property AffixFileName: string read FAffixFileName write SetAffixFileName;
123 property btnClose: TButton read FbtnClose write SetbtnClose;
124 property CustDictionaryFile: String read FCustom write SetCustomDict;
125 property DictionaryFileName:string read FDictFileName write SetDictFileName;
126 property ColorForMisspelled: TColor read FHighlightColor write FHighlightColor default clRed;
127 property MisSpeltWord: TEdit read FHighlightEdit write SetHighLightEdit;
128 property IsModified: Boolean read FModified;
129 property ShowCompletionMessage: Boolean read FShowCompletion write FShowCompletion default True;
130 property SourceTextControl: TRichEdit read FSourceEdit write SetSourceEdit;
131 property SpellCheckCompletionMessage: String read FpointerSpellComplete write FpointerSpellComplete;
132 property SuggestionList: TListbox read FSuggestionList write FSuggestionList;
133
134 end;
135
136 procedure Register;
137
138 Const
139 CompletionMessage = 'Spell Check Complete.';
140 CaptionForNewWord = 'New Word Suggestion';
141 ConfirmAbort = 'Really abort?';
142 PromptForNewWord = 'Specify the replacement for current mis-spelt word:';
143 DLLNotLoaded = 'Failed to load SpellCheck Engine DLL.';
144 MisSpeltReplacement = 'The new word specified by you "%s" looks mis-spelt!'
145 +' Would you want to still use it? Click NO button '
146 +'to specify better replacement word.';
147 var
148 OldRichEditWndProc: {integer}pointer;
149 CurrentMe: TskaHunSpellChecker;
150implementation
151 uses messages, Dialogs, RichEdit, SHFolder, Forms, uHunSpellLib;
152
153procedure Register;
154begin
155 RegisterComponentsProc('SkA Utility', [TskaHunSpellChecker]);
156end;
157
158{ TskaHunSpellChecker }
159
160function TskaHunSpellChecker.AbortSpellCheck(Verbose: Boolean = True): Boolean;
161begin
162 if FStatus <> ssChecking then
163 begin
164 FStatus := ssCancelled;
165 Close;
166 exit;
167 end;
168
169 Result := (not isModified) or
170 (not Verbose) or (MessageDlg(ConfirmAbort, mtConfirmation,
171 [mbYes, mbNo],0, mbNo) = 6);
172
173 if Result then
174 FStatus := ssCancelled;
175
176 ShowBtnClose;
177end;
178
179function TskaHunSpellChecker.AddCustomWord(aWord: String; isInternal: Boolean = False): Boolean;
180begin
181 Result := False;
182 if (trim(aWord) = '') or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
183
184
185 Result := False;
186 if (not Active) then Exit;
187 uHunSpellLib.hunspell_put_word(FpointerHunLib, PAnsiChar(AnsiString(aWord)));
188 Result := True;
189end;
190
191procedure TskaHunSpellChecker.ChangeAll;
192begin
193 if (SpellCheckState <> ssChecking) or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
194 exit;
195 SaveForUndo;
196 SourceTextControl.Text := StringReplace(SourceTextControl.Text,
197 CurrentWord, SuggestionList.Items[SuggestionList.ItemIndex],
198 [rfReplaceAll,rfIgnoreCase]);
199 WaitForUser := False;
200 FModified := True;
201 SourceTextControl.Invalidate;
202
203end;
204
205function TskaHunSpellChecker.AddCustomWord: Boolean;
206begin
207 Result := AddCustomWord(CurrentWord, False);
208 FCustdict.Add(CurrentWord);
209 WaitForUser := False;
210 AbortSpellCheck(False);
211 Initialize;
212 CheckSpelling;
213 ShowMisSpelledWord;
214end;
215
216procedure TskaHunSpellChecker.ReplaceCurrentWordWith(const aNewWord: String);
217var
218 full: String;
219 prefix: string;
220 suffix: string;
221begin
222 full := SourceTextControl.Lines[CurrentLine];
223 prefix := copy(CurrentText, 2, WordPos-2); //remember there is one extra space at the start of the line prefixed while populating this variable
224 Suffix := copy(CurrentText, WordPos+WordLength,
225 length(CurrentText));
226 SaveForUndo;
227 SourceTextControl.Lines[CurrentLine] :=prefix + aNewWord + suffix;
228 WaitForUser := False;
229 FStatus := ssChecking;
230 FModified := True;
231 SourceTextControl.Invalidate;
232end;
233
234function TskaHunSpellChecker.ReStart: Boolean;
235begin
236 Close;
237 Result := Open;
238 Initialize;
239 WaitForUser := False;
240 FStatus := ssChecking;
241 SourceTextControl.Invalidate;
242 Result := not WaitForUser;
243end;
244
245procedure TskaHunSpellChecker.Change;
246
247begin
248 if (SpellCheckState <> ssChecking) or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
249 exit;
250 ReplaceCurrentWordWith(SuggestionList.Items[SuggestionList.ItemIndex]);
251end;
252
253procedure TskaHunSpellChecker.CheckSpelling;
254begin
255 if (SpellCheckState = ssChecking) or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
256 exit;
257
258 Initialize;
259 FUndoList.Clear;
260 WaitForUser := False;
261 FStatus := ssChecking;
262 SourceTextControl.Invalidate;
263 //SourceTextControl.Invalidate;
264 ShowBtnClose(False);
265end;
266
267procedure TskaHunSpellChecker.Close;
268begin
269 if not Active then Exit;
270 uHunSpellLib.hunspell_uninitialize(FpointerHunLib);
271 FpointerHunLib := nil;
272end;
273
274
275procedure TskaHunSpellChecker.CorrectWithMyWord;
276var
277 NewWord: String;
278 GotIt: Boolean;
279begin
280 if (SpellCheckState <> ssChecking) or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
281 exit;
282
283 if SuggestionList.Count > 0 then
284 NewWord := SuggestionList.Items[0]
285 else
286 NewWord := CurrentWord;
287
288 GotIt := False;
289 while not GotIt do
290 begin
291 if not InputQuery(CaptionForNewWord, PromptForNewWord, NewWord) then
292 exit;
293
294 GotIt := (not IsMisspelled(NewWord))
295 or (MessageDlg(Format(MisSpeltReplacement,[NewWord]),
296 mtWarning, [mbYes, mbNo],0, mbNo) =6) ;
297 end;
298
299 if IsMisspelled(NewWord) then
300 AddCustomWord(NewWord, True);
301
302 ReplaceCurrentWordWith(NewWord);
303end;
304
305constructor TskaHunSpellChecker.Create(AOwner: TComponent);
306 function GetSpecialFolderPath(folder : integer) : string;
307 var
308 path: array [0..MAX_PATH] of char;
309 begin
310 if SUCCEEDED(SHGetFolderPath(0,folder,0,0,@path[0])) then
311 Result := path
312 else
313 Result := '';
314 end;
315begin
316 inherited;
317
318 ColorForMisspelled := clRed;
319 ShowCompletionMessage := True;
320 SpellCheckCompletionMessage := CompletionMessage;
321
322
323
324 CurrentMe := Self;
325 FIgnore := TStringList.Create;
326 FCustDict := TStringList.Create;
327
328 CustDictionaryFile := IncludeTrailingPathDelimiter(GetSpecialFolderPath(CSIDL_PERSONAL)) + 'CustomDictionary.txt';
329 if FileExists(CustDictionaryFile) then
330 try
331 FCustDict.LoadFromFile(CustDictionaryFile);
332 except
333 end;
334
335 FUndoList := TStringList.Create;
336
337 FStatus := ssNotStarted;
338 WaitForUser := False;
339 WordPos := 0;
340end;
341
342constructor TskaHunSpellChecker.Create(AOwner: TComponent;
343 SourceTextRichEdit: TRichedit; SuggestList: TListbox);
344begin
345 create(AOwner);
346 SourceTextControl := SourceTextRichEdit;
347 SuggestionList := SuggestList;
348end;
349
350function TskaHunSpellChecker.CurrentWordDetail(WithPosition: Boolean): String;
351begin
352 Result := '$$' + CurrentWord + '$$';
353 if WithPosition then
354 Result := '$$' + IntToStr(FoundAt+1) + Result;
355end;
356
357destructor TskaHunSpellChecker.Destroy;
358begin
359 Close;
360 FIgnore.clear;
361 FreeAndNil(FIgnore);
362 FreeAndNil(FUndoList);
363 if not (csDesigning in ComponentState) then
364 try
365 if FCustDict.Count > 0 then
366 try
367 FCustDict.SaveToFile(CustDictionaryFile);
368 except
369 end;
370 finally
371 FCustDict.Free;
372 end;
373 inherited;
374end;
375
376function TskaHunSpellChecker.GetAboutThis: String;
377begin
378 Result := AboutThis;
379end;
380
381function TskaHunSpellChecker.GetActive: Boolean;
382begin
383 Result := (FpointerHunLib <> nil);
384end;
385
386function TskaHunSpellChecker.GetStatus: TSpellState;
387begin
388 Result := FStatus;
389end;
390
391procedure TskaHunSpellChecker.GetSuggestions(const aMisSpeltWord: string;
392 const SuggestionList: TStrings);
393var
394 i: Integer;
395 pMisSpelt: PAnsiChar;
396 suggestions: PPAnsiChar;
397 Results: PPAnsiChar;
398 Count: Integer;
399begin
400 if (not Active) or (not Assigned(SuggestionList)) then
401 exit;
402
403 pMisSpelt := PAnsiChar(AnsiString(aMisSpeltWord));
404
405 if not uHunSpellLib.hunspell_spell(FpointerHunLib, pMisSpelt) then
406 uHunSpellLib.hunspell_suggest_auto(FpointerHunLib, pMisSpelt, suggestions);
407 begin
408 Count := uHunSpellLib.hunspell_suggest(FpointerHunLib, pMisSpelt, suggestions);
409 Results := suggestions;
410 for i := 1 to Count do
411 begin
412 SuggestionList.Add(Results^);
413 Inc(Integer(Results), SizeOf(Pointer));
414 end;
415 uHunSpellLib.hunspell_suggest_free(FpointerHunLib, suggestions, Count);
416 end;
417end;
418
419procedure TskaHunSpellChecker.ShowBtnClose(const ShowIt: Boolean);
420begin
421 if Assigned(btnClose) then
422 begin
423 btnClose.Enabled := ShowIt;
424 btnClose.Visible := ShowIt;
425 if ShowIt then
426 begin
427 btnClose.BringToFront;
428 btnClose.SetFocus;
429 end;
430 end;
431end;
432
433function TskaHunSpellChecker.ShowMisSpelledWord: boolean;
434var
435 I , l :integer;
436 CharPosion:integer;
437 FirstVisibleLine, LastVisibleLine:integer;
438
439 hndl: hwnd;
440 dcForHndl: THandle;
441 visrect:Trect;
442 vispoint:TPoint;
443 procedure ShowMisSpelletWord;
444 begin
445 if Assigned(FHighlightEdit) then
446 begin
447 FHighlightEdit.Font.Color := ColorForMisspelled;
448 FHighlightEdit.Text := CurrentWord;
449 FHighlightEdit.Show;
450 end ;
451
452 if ((PosOfFirstCharInCurrentLine + FoundAt) < 1) then
453 exit;
454
455 SendMessage (SourceTextControl.Handle, EM_POSFROMCHAR, integer(@VisPoint), PosOfFirstCharInCurrentLine + FoundAt-1);
456 SetTextColor(dcForHndl, ColorForMisspelled);
457 TextOut(dcForHndl, VisPoint.x, VisPoint.y, pchar(CurrentWord), WordLength);
458 end;
459begin
460 Result := False;
461 if (SpellCheckState <> ssChecking) or (not assigned(SourceTextControl))
462 or (not assigned(SuggestionList)) then
463 exit;
464
465 hndl:=SourceTextControl.Handle;
466
467 result:= SendMessage (hndl, EM_GETRECT, 0, integer(@visrect))=0;
468
469 dcForHndl := getdc(hndl);
470
471 if result then
472 begin
473 // VisPoint := visrect.BottomRight;
474 vispoint.Y := visrect.Bottom;
475 vispoint.X := visrect.Right;
476 CharPosion := SendMessage (hndl, EM_CHARFROMPOS, 0, integer(@VisPoint));
477 LASTVISIBLELINE := SendMessage (hndl, EM_LINEFROMCHAR, CharPosion, 0);
478 FIRSTVISIBLELINE := SendMessage (hndl, EM_GETFIRSTVISIBLELINE, 0, 0);
479
480 SetBkMode (dcForHndl, TRANSPARENT);
481 SelectObject(dcForHndl, SourceTextControl.font.Handle);
482 i := 0;
483
484 if WaitForUser then
485 begin
486 ShowMisSpelletWord;
487 exit;
488 end;
489
490 For l := 0 to SourceTextControl.Lines.Count -1 do
491 begin
492 {$R-}
493 CurrentLine := l;
494 if trim(SourceTextControl.Lines[CurrentLine]) = '' then
495 continue;
496
497 CurrentText := ' ' + SourceTextControl.Lines[CurrentLine];
498 PosOfFirstCharInCurrentLine := SendMessage (SourceTextControl.Handle, EM_LINEINDEX, CurrentLine, 0);
499 i := 0;
500
501 While i <= LENgth(CurrentText) do
502 begin
503 FoundAt := i -1;
504 if Assigned(FHighlightEdit) then
505 FHighlightEdit.Hide;
506
507
508 //SuggestionList.Clear;
509 {Any character except these will count as a word delimiter}
510 While CurrentText[i] in ['A'..'Z','a'..'z','0'..'9'] do inc(i);
511
512 WordLength := i- FoundAt -1;
513 WordPos := i-WordLength;
514 CurrentWord := copy(CurrentText, WordPos, WordLength);
515 If ((FIgnore.IndexOf(CurrentWordDetail(True))< 0) //SingelIgnore
516 and (FIgnore.IndexOf(CurrentWordDetail(False))< 0) //IgnoreAll
517 and (IsMisspelled(CurrentWord))) Then
518 begin
519 GetSuggestions(CurrentWord, SuggestionList.Items);
520 if SuggestionList.Count > 0 then
521 SuggestionList.ItemIndex := 0;
522 ShowMisSpelletWord;
523 if CurrentLine > LastVisibleLine then
524 SendMessage(SourceTextControl.Handle, EM_LINESCROLL, 0, (CurrentLine - lastvisibleLine)+5);
525 WaitForUser := True;
526 exit;
527 End
528 else
529 SuggestionList.Clear;
530 inc(i);
531 end;
532 end;
533 if (CurrentLine >= SourceTextControl.Lines.Count-1) and (i >= length(CurrentText) +1) then
534 begin
535 FStatus := ssCompleted;
536 if ShowCompletionMessage then
537 ShowMessage(CompletionMessage);
538 ShowBtnClose;
539 end;
540 {$R+}
541 end;
542 ReleaseDC(SourceTextControl.Handle, dcForHndl);
543
544End;
545
546function TskaHunSpellChecker.Undo: Boolean;
547var
548 tmpStr: String;
549 tmpCount: Integer;
550begin
551 if FUndoList.Count > 0 then
552 try
553 tmpStr := FUndoList.Strings[FUndoList.Count-1];
554 { showmessage(inttostr(AnsiPos('$$',tmpStr)) + #13 + inttostr(length(tmpstr)) + #13 +
555 copy(tmpStr,length(tmpStr)-2,2)); }
556 if (AnsiPos('$$',tmpStr)=1) and (copy(tmpStr,length(tmpStr)-1,2) = '$$')then
557 begin
558 tmpCount := strtoInt(StringReplace(tmpStr,'$$','',[rfReplaceAll]));
559 while FIgnore.Count > tmpCount do
560 FIgnore.Delete(FIgnore.Count -1);
561 end
562 else
563 SourceTextControl.Text := tmpStr;
564
565 Result := True;
566 FUndoList.Delete(FUndoList.Count-1);
567 ReStart;
568 except
569 Result := False;
570 end;
571end;
572
573procedure TskaHunSpellChecker.IgnoreAll;
574begin
575 if (SpellCheckState <> ssChecking) or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
576 exit;
577 SaveForUndo(True);
578 FIgnore.Add(CurrentWordDetail(False)) ;
579 WaitForUser := False;
580 SourceTextControl.Invalidate;
581end;
582
583procedure TskaHunSpellChecker.IgnoreOnce;
584begin
585 if (SpellCheckState <> ssChecking) or (not assigned(SourceTextControl)) or (not assigned(SuggestionList)) then
586 exit;
587 if trim(CurrentWord) <> '' then
588 begin
589 SaveForUndo(True);
590 FIgnore.Add(CurrentWordDetail(True)) ;
591 end;
592 WaitForUser := False;
593 SourceTextControl.Invalidate;
594end;
595
596procedure TskaHunSpellChecker.Initialize;
597begin
598 CurrentWord := '';
599 WordLength := 0;
600 FoundAt := -1;
601 CurrentLine := 0;
602 WordPos := 0;
603 SuggestionList.Clear;
604end;
605
606function TskaHunSpellChecker.IsMisspelled(const AWord: string): Boolean;
607begin
608 if (not Active) then
609 Result := True
610 else
611 Result := not uHunSpellLib.hunspell_spell(FpointerHunLib, PAnsiChar(AnsiString(AWord)));
612end;
613
614procedure TskaHunSpellChecker.Loaded;
615begin
616 inherited;
617 SetActive(FActiveOrLoaded);
618end;
619
620procedure TskaHunSpellChecker.ManualChangeDone;
621begin
622 if trim(FTxtBeforeManualEdit) = '' then
623 exit;
624 FUndoList.Add(FTxtBeforeManualEdit);
625 ReStart;
626end;
627
628procedure TskaHunSpellChecker.ManualChangeStart;
629begin
630 FTxtBeforeManualEdit := FSourceEdit.Text;
631end;
632
633function TskaHunSpellChecker.Open: Boolean;
634var
635 CurrentLine: integer;
636begin
637 Result := True;
638 if Active then Exit;
639 Result := False;
640 FpointerHunLib := Nil;
641 if not uHunSpellLib.LoadLibHunspell('') then
642 begin
643 MessageDlg(DLLNotLoaded, mtError, [mbOK],0);
644 Exit;
645 end;
646 FpointerHunLib := uHunSpellLib.hunspell_initialize(PAnsiChar(AnsiString(FAffixFileName)), PAnsiChar(AnsiString(FDictFileName)));
647 Result := Assigned(FpointerHunLib);
648
649 if (Result) and (assigned(FCustDict)) then
650 for CurrentLine := 0 to FCustDict.Count - 1 do
651 AddCustomWord(FCustDict[CurrentLine], True);
652end;
653
654procedure TskaHunSpellChecker.SaveForUndo(const Ignoring: Boolean = False);
655begin
656 if Ignoring then
657 FUndoList.Add('$$'+ IntToStr(FIgnore.Count)+'$$')
658 else
659 FUndoList.Add(SourceTextControl.Text);
660end;
661
662procedure TskaHunSpellChecker.SetActive(const Value: Boolean);
663begin
664 if (csDesigning in ComponentState) or (csLoading in ComponentState) then
665 FActiveOrLoaded := Value
666 else
667 if Value then
668 FActiveOrLoaded := Open
669 else
670 Close;
671end;
672
673procedure TskaHunSpellChecker.SetAffixFileName(const Value: string);
674begin
675 Close;
676 FAffixFileName := Value;
677end;
678
679procedure TskaHunSpellChecker.SetbtnClose(const Value: TButton);
680begin
681 if btnClose = Value then
682 exit;
683 FbtnClose := Value;
684 FbtnClose.ModalResult := 1; //mrOK
685end;
686
687procedure TskaHunSpellChecker.SetCustomDict(const Value: String);
688begin
689 FCustom := Value;
690 if not (csDesigning in componentState) then
691 if Active and (FileExists(Value)) then
692 FCustDict.LoadFromFile(Value);
693end;
694
695procedure TskaHunSpellChecker.SetDictFileName(const Value: string);
696begin
697 Close;
698 FDictFileName := Value;
699end;
700
701procedure TskaHunSpellChecker.SetHighLightEdit(const Value: TEdit);
702begin
703 if FHighlightEdit = Value then
704 exit;
705
706 FHighlightEdit := Value;
707
708 if Active then
709 FHighlightEdit.Text := CurrentWord;
710
711
712end;
713
714Function RichEditWndProc (handle:HWnd;uMsg,wParam,lParam:longint): longint stdcall;
715begin
716 Result := CallWindowProc(OldRichEditWndProc, handle, uMsg, wParam, lParam);
717 if (uMsg=WM_PAINT) and assigned(CurrentMe) then CurrentMe.ShowMisSpelledWord;
718End;
719
720procedure TskaHunSpellChecker.SetSourceEdit(const Value: TRichEdit);
721begin
722 if FSourceEdit = Value then
723 exit;
724
725 FSourceEdit := Value;
726
727 if csDesigning in ComponentState then
728 exit;
729
730 PREditorWndProc:=@RichEditWndProc;
731 Value.perform(EM_EXLIMITTEXT, 0, 65535*32); //raise the limit of text which could be inserted into this Richedit
732 OldRichEditWndProc := pointer(SetWindowLong(Value.handle, GWL_WNDPROC, longint(@RichEditWndProc)));
733
734end;
735
736end.
Note: See TracBrowser for help on using the repository browser.