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, 10 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.