Page 1 of 1

Problem using RichView with LiveSpelling (MS Word)?

Posted: Fri Dec 15, 2006 10:12 am
by Primvs
Hi!

I am using spelling with TRichViewEdit. Because of customer's request I need to use MS Word speller through COM.
Now- my spellingcheck event looks something like this:

Code: Select all

procedure TfmeTEXT.rveSpellingCheck(Sender: TCustomRichView;
  const AWord: string; StyleNo: Integer; var Misspelled: Boolean);
var
  ATemp: TStrings;
begin
  if FNonVisible or not Self.Visible or (csDestroying in rve.ComponentState) then exit;
  ATemp := TStringList.Create;
  try
    try
      Misspelled := not dmMain.SpellChecker.CheckSpelling(AWord, ATemp, false, true);
    except
      Misspelled := false;
    end;
  finally
    ATemp.Free;
  end;
end;
Spellchecker is object I created as a wrapper for using only spell-checking features of MS Word application.
Now- in order to make it work (since Word COM is being called from spelling thread I had to add following lines to unit which contains Spellchecker object):

Code: Select all

initialization
if Assigned(ComObj.CoInitializeEx) then
  OleCheck(ComObj.CoInitializeEx(nil, COINIT_MULTITHREADED))
else
  CoInitialize(nil)
finalization
  CoUninitialize;
Live spelling is working as a charm, but previous lines make RichViewEdit behave rather strange- sometimes it does not respond to mouse click event as it should (when you select part of text, than click anywhere in RichView it does not respond- only way you can bypass that is using keyboard). Is there a way to solve this problem?
BTW- if I comment initialization/finalization part of Spellchecker object live spelling obviously doesn't work, but RichView behaves as it should. So it's not a problem of properties assigned to RV...

LP, Primoz

Problem using RichView with LiveSpelling (MS Word)? II

Posted: Fri Dec 15, 2006 1:41 pm
by Primvs
Hey!

Never mind- with a bit of the logic I think I solved it. The problem was, that I created SpellCheck object (wrapper to access MS Word COM) in main thread, and because of that I needed to call CoInitializeEx with COINIT_MULTITHREADED flags (so that COM object created in main thread could be used in spelling thread). This in turn caused havock on loads of different things including selection in RichView (look at p.s.).
Now, one workaround which I tested (but performance-wise isn't best) is creating (and later freeing) SpellCheck object everytime the OnSpellingCheck event is fired.
The better solution would probably be to create another thread, that would use it's own version of SpellCheck object, OnSpellingCheck event would get data with the help of this thread. Unless anyone has a better suggestion?

Primoz

p.s. COINIT_MULTITHREADED causes more "damage" than just simple selection problem with RichView. I learned the hard way it also causes Shell functions (like ShellExecute) not to work (http://support.microsoft.com/?id=287087 ).

Posted: Fri Dec 15, 2006 4:17 pm
by Pieter E.
@Primoz:
Could you please explain how you've implemented a Live Spelling using MS Word?

Thanks in advance!

Posted: Sat Dec 16, 2006 9:04 pm
by Sergey Tkachenko
Primvs, may be you can create this object in the first call of this event, and reuse it in others?

Posted: Mon Dec 18, 2006 8:29 am
by Primvs
Hey!

Sergey, thanks. Sometimes it's hard to see the most obvious things. :D

Primvs
Sergey Tkachenko wrote:Primvs, may be you can create this object in the first call of this event, and reuse it in others?

Posted: Mon Dec 18, 2006 8:57 am
by Primvs
Pieter-

You can find a basic idea at this link:
http://delphi.about.com/od/kbcontrolole/l/aa032701a.htm

Idea (and problem) is that you have to have MS Word installed on every client your application is running on, and it's settings have to be set to use the correct dictionary.

From Delphi you Import MS Word ActiveX control (one way of doing things, you can read more at link above) using Component/Import ActiveX control menu.

Unfortunately I can't send you whole code for Spelling check object I used . So, here's just bits and pieces for the spelling part (U have to have word_tlb unit included).

Code: Select all

...
var
   MsWordApp: TWordApplication;
   wordCorrect: boolean;
...
(* create instance of MS Word ActiveX object (you have to do that in same thread as spelling) *)
MsWordApp := TWordApplication.Create(self);
...
(* actual spelling check *)
wordCorrect:=MsWordApp.CheckSpelling(StrWord);
...
(* don't forget to close the connection to MS Word at the end *)
 MsWordApp.Disconnect;
 MsWordApp.Free;
Pieter E. wrote:@Primoz:
Could you please explain how you've implemented a Live Spelling using MS Word?

Thanks in advance!

Posted: Mon Dec 18, 2006 3:52 pm
by Pieter E.
Thank you for your answer. But this doesn't look like a LIVE spellcheck. Thanks anyway :wink: