[SOLVED] Looking to for a good spell checker dll to call from a Uniface App

Author: glen.marsh@noris.org (normars)

Hi,   I'm looking for a good spell checker to call from our Uniface applications.  Does anyone have some experience with this and could recommend one or a few to look at?  We are using Uniface 9.3.02.  - GlenCool

11 Comments

  1. normars said Hi,   I'm looking for a good spell checker to call from our Uniface applications.  Does anyone have some experience with this and could recommend one or a few to look at?  We are using Uniface 9.3.02.  - GlenCool

    Hi Glen, In case you have Microsoft Office Word available then you could call the spell checker of Word using the Uniface COM Call-Out interface. I currently don't have a sample handy, but this should be quite straight forward - if you have some basic knowledge of the COM Call-out interface and how to program in VBA for Office. As a starting point you could use the Community Sample "Call-Out to Microsoft Word Using COM" that you can find here on Uniface.info under the DOWNLOADS menu. It probably is also possible to call the spell checker of a Open Source word processor like (e.g.) LibreOffice Writer. But I (so far) have no first hand experience with this. Maybe one of the other forum members has more info about this. And there are probably also some stand alone spell checkers that could be called "directly" (e.g. using C Call-Out or spawn/OSCommand). However, as with LibreOffice, I cannot share any first hand experiences. Hope this helps. Kind regards, Daniel


    Author: diseli (daniel.iseli@uniface.com)
  2. Daniel - Very very helpful indeed.  Will take some study, but this looks exactly like what I'm looking for.  Didn't know you could call Words spell checker from Uniface.  Thanks much - GlenLaugh


    Author: normars (glen.marsh@noris.org)
  3. Also TextControl has a text spelling function: http://www.textcontrol.com/en_US/


    Author: Stijn Courtheyn (stijn.courtheyn@xperthis.be)
  4. Hi,      I tried calling Word's spell check function using the .com interface and it works great except for one thing.  Occasionally the spell check window pops up behind the Uniface application.  To the user this makes it look like application has locked up.  You can fix it by just going to the desk top first and then clicking the icon for the Uniface app, which gets you right to the spell check window.  But that's not an optimal solution for our users.     I don't have Word's visible property set, so nothing from Word is visible until the spell check window pops up.       I tried setting up a signature for a windows API function called BRINGWINDOWTOTOP and passing it the handle for the active window in Word that I got from Word, but that didn't seem to fix the problem.  I'm not sure if the handle that Word returns for it's active window is the same as the handle that the Windows API function needs, but I tried passing that handle to the BRINGWINDOWTOTOP function after Word was running but before I called the spell check function.  Unfortunatly it didn't fix the problem.         It works great most of the time.  It's only occasionally that the spell check window is hidden behind the uniface app.  Any suggestions or direction would be appreciated.


    Author: normars (glen.marsh@noris.org)
  5. normars said       It works great most of the time.  It's only occasionally that the spell check window is hidden behind the uniface app.  Any suggestions or direction would be appreciated.

    It seems that this problem also can be seen outside of Uniface (e.g. see here). I can replicate the problem consistently when either the Uniface Debugger is active or a Message Box (e.g. message/info) is shown before calling the CheckSpelling method of Word. One trick that seems to work is to make the Uniface application window the parent window of the Word application window. You can do this by calling the Windows User32 function SetParent() and pass as child window handle the window handle of the Word application and as new parent window the window handle you get by calling the Uniface YRTL function ugethwnd().

    variables ; ...    handle hUser32, hYrtl endvariables ; ... ; Get the window handle of Word hndWordApplication -> GET_ACTIVEWINDOW ( hndWordWindow ) hndWordWindow -> GET_HWND ( hWndWord ) ; Now we set the parent window of Word to the Uniface application window ; For this we use two C Call-out signatures ; 1. YRTL (DLL name yrtl.dll) with an operation that calls the function ugethwnd() ; 2. USER32 (DLL name user32.dll) with an operation that calls the function SetParent() newinstance "USER32", hUser32 newinstance "YRTL", hYrtl if (hUser32->SetParent(hWndWord, hYrtl->ugethwnd()) = 0)     message/error "Could not set parent window of Word to Uniface application window!" endif ; And now we call the CheckSpelling method hndWordDocument-> CHECKSPELLING ( -, -, -, -, -, -, -, -, -, -, -, - ) ; ...

    Hope this helps. Best regards, Daniel


    Author: diseli (daniel.iseli@uniface.com)
  6. And in case you want to be on the "safe side" then you additionally can reset the parent window of Word to the Desktop after calling the CheckSpelling method:

    ; ... ; And now we call the CheckSpelling method hndWordDocument-> CHECKSPELLING ( -, -, -, -, -, -, -, -, -, -, -, - ) ; Hide the Word window, because it otherwise might "pop-up" in the Uniface application window hndWordWindow -> SET_VISIBLE ( 0 ) if (hUser32->SetParent(hWndWord, 0) = 0)     message/error "Could not reset parent window of Word to the Desktop!" endif ; ...

    Hope this helps.


    Author: diseli (daniel.iseli@uniface.com)
  7. Daniel,        I've googled this problem for awhile in other non-uniface situations, but haven't been able to find a solution that seemed to work for me, so I appreciate your help a lot.  The SETPARENT function sounds like it should work.  But I'm very green at this.  Before starting this project I'd never created a signature and didn't even know that VBA existed, so it's been learning curve for me, but fun too.  So I hope you'll bear with a few questions... 1. I don't know how to set up a signature for YRTL (isn't this the name of a turtle in some Dr Suess book??) so that the windows handle is returned as the value of the function call.  Which button do I check for 'Return Value In' - $status, First Parmeter or none? 2. I can't find a WHND property in the Object Explorer for the Window object in Word.  I read online that there is one for Excell, but not for Word.  Am I missing something here?                                                Thanks very much for your help - GlenSmile


    Author: normars (glen.marsh@noris.org)
  8. Glen, Thanks for your reply. I've uploaded in the meantime a little sample form (including the required C and COM call-out signatures) to Community Samples download here on Uniface.info (see Word Spellchecker sample). The sample has been created (and tested) using Microsoft Office Word 2013. in case you are using another Word version then you need to change or create the required COM signatures. More info about how to do this can be found in the ReadMe of the sample Call-Out to Microsoft Word Using COM.

    normars said 1. I don't know how to set up a signature for YRTL (isn't this the name of a turtle in some Dr Suess book??) so that the windows handle is returned as the value of the function call. Which button do I check for 'Return Value In' - $status, First Parmeter or none?

    YRTL is one of the kernel modules of Uniface. WinkThe required C call-out signature is included in the above mentioned sample. And more info about the function ugethwnd() can be found in the Uniface Library (see e.g. here).

    normars said 2. I can't find a WHND property in the Object Explorer for the Window object in Word. I read online that there is one for Excell, but not for Word. Am I missing something here?

    It's correct that there's no WHND property - I guess just a silly typo. Wink But the class Word.Window should have a property called Hwnd. Well, at least when I check Word 2013. It's possible that older Word versions do not have the mentioned property (yet). Hope this helps. Regards, Daniel


    Author: diseli (daniel.iseli@uniface.com)
  9. Daniel,        The SETPARENT call solved the problem.  I was also able to get a signature for YRTL to get the windows handle for the Uniface application.  Your sample was very helpful indeed.  Thanks much for all your help.        I'm just posting some info below on two issues in case someone else trying to call Words spell checker could benefit from this in the future:      One problem I had was that we are on Word 2010 and there is no Hwnd property in Word 2010.  I read some things on the internet that Word doesn't give you the Windows handle, so they must have added it in Word 2013.  I used the following code in Uniface to get Word's windows handle.  If someone else is trying to call a version of Word earlier than 2013 they can use this to get the handle needed to call the SETPARENT Windows API. ; Get Window handle of the active window in Word. In Word 2013 there is a HWND property that lets you do this directly. For Word 2010 ; you can't get the Windows Handle directly in VBA, you have to call the FindWindow API function to get it variables string  S_Caption handle H_Word numeric n_WordWin endvariables ; H_Word already has the Word handle for the application... S_Caption = "abc" H_Word -> Caption (S_Caption)                                                           ; change window title through VBA S_Caption = $concat ("Document1 - ", S_Caption)                                   ; Word adds 'Document1 -' to the caption you set n_WordWin = H_User32 -> FindWindow("OpusApp", S_Caption)                ; get handle of window with that title with Windows API call.                                                                                                          ; OpusApp is the class name for the Word application.     Another requirement that came up is that some person and some street names in the text had to be considered valid words when the spell check runs.  Otherwise the user would waste time dealing with people's names and addresses which had been programmatically put into the free text field.  You can add these words to the custom dictionary.  The custom dictionary is simply a text file with a carriage return after each word.  I just used a FILELOAD command to save the current dictionary, loaded the words I needed into a variable named S_Dictionary, then wrote the file with: filedump S_Dictionary, "C:\Users\%%$$logon_name%%%\AppData\Roaming\Microsoft\UProof\Custom.dic" $$logon_name contains the user login.  The path of course could be different at different installations.


    Author: normars (glen.marsh@noris.org)
  10. Glen, Glad to hear that you got this sorted. Laugh And thank for the additional info. This is hopefully useful for others. Daniel


    Author: diseli (daniel.iseli@uniface.com)
  11. Hi,     If anyone else needs to write to WORDs custom dictionary, there is a better way to do it than what I posted in my last post above.  There are two properties you can call in Word which will return the name and path to the custom dictionary.  Here is the code I used: variables string    S_Dictionary_save, S_DictPath, S_DictName handle  H_DictColl, H_CustDict, H_Word endvariables ; H_Word is the handle to the WORD application object H_Word -> CustomDictionaries(H_DictColl) ; Word's CustomDictionary property returns a collection of all dictionaries H_DictColl -> ActiveCustomDictionary (H_CustDict) ; ActiveCustomDictionary property of the collection returns current active custom                                                                                 ; dictionary object H_CustDict -> path(S_DictPath)                                                            ; Path property returns path to custom dictionary H_CustDict -> name(S_DictName)                                                         ; Name property returns name of custom dictionary fileload "%%S_DictPath%%%\%%S_DictName%%%", S_Dictionary_save   ; save current custom dictionary filedump P_WordList, "%%S_DictPath%%%\%%S_DictName%%%"          ; write new dictionary contents out ....Run the spell check...and then at the end... filedump S_Dictionary_save, "%%S_DictPath%%%\%%S_DictName%%%" ; restore original custon dictionary   Two other tips on issues I found working with MS Word 2010: 1. If Word replaces text that has an apostrophe it uses a character that is an invalid character for Uniface.  I believe the invalid character is called a 'grave accent'.  Sorry, I didn't get the exact ascii code for the invalid character.   So if Word replaces "Can'tt" with "Can't" the user gets a error when they try to tab out of the field that has just been spell checked.  You have to do a REPLACE command to change the grave accent back to a Unface acceptable apostrophe character. 2. For some reason with Word 2010 it always added a carriage return at the end of my text field.  Don't know why.  I used an RTRIM command to just remove trailing carriage returns from the corrected text.                                           Good Luck!Laugh


    Author: normars (glen.marsh@noris.org)