Posted version 20120609 with support for DataGridViews
Kris
Printable View
Posted version 20120609 with support for DataGridViews
Kris
Hey man...
here is the link to dic..
i took from openoffice...
http://openoffice.c3sl.ufpr.br/contr...ries/pt_BR.zip
Thanks will have a look today or tomorrow :)
Kris
Tks Kris..
i'm waiting...
Sure Kris, no problem...
while this i'm looking for other thing in my project...
tks!!
Hrm ... not entirely sure ... but if you want to look into it...
Check the LoadFromFile function for the dictionary ....
My.Computer.FileSystem.ReadAllText(Filename) seems to load the file incorrectly ... I also tried a streamreader.readtoend... but it had the same result ... let me know if you figure out a way ... till then i will put this on the back burner...
Also you will prob need to change the save function also ... since it uses writealltext... so imagine it would save the file like that even if you get the loading working...
Kris
Version 20120618 is out, with custom plug in support!
20120622 is out with plugin support for the FastColoredTextBox control!
Kris
Hi Kris,
Just a quick note from the UK to say thank you for all your hard work on this project.
I'm using i00SpellCheck in my project which allows forensic scientists to securely record their examination notes (now, with correct spelling!).
As the project is used by scientists internationally, support for Open Office dictionaries would be really cool when you get five minutes!
Once again, thank you for making this available.
Kind regards,
Fin.
Plan to look into this again soon ...
Will keep you posted...
Btw version 20120625 is out ... with some speedups and test project changed to automatically load the tabs from plugins.
Kris
I am using i00 Spell check in my project and it works great!!
I hope you don't mind, but I'm looking into this now, and I'll likely use it for a personal project of mine. You did very well in coding this, much appreciated.
Umm I'm having problems, I've not used visual basic for a long time, but I get a lot of errors.. would it be possible to get a basic guide for this? like I have no idea if I'm doing the referencing or importing right, and I get an error on the 'Me.EnableSpellCheck()'... don't suppose there's a straight forward video guide? or somethin?
I got it working, though lacking the defintions, thanks anyway.
Glad to know that you got it working :) ... please post what you did to get it working so others may learn if they are having the same issues...
As for a video guide this is a good idea ... I may look into doing this sometime.
Thanks
Kris
I am attempting to implement your program into mine. However, I am wondering is there a way where I can use this to correct spelling mistakes made in Excel? My program currently let's the User open up a Worksheet in a DataGrid and I'm wondering if I can basically do the same with your program but if when the User uploads the Excel Worksheet it will correct Spelling mistakes there. Let me know if I'm making any sense here I am very new to VB 2010. I was using VB6 previously.
What do you mean "in excel" ... your DataGrid that loads the excel documents does it not? the DGV can support spell checking...
In your upload process you could check each word in each cell, and change it accordingly with the spell check engine.
Is this what you meant?
Kris
What I mean by in Excel is will your Spellcheck work on a DataGrid that's on my form? I use the DataGrid to show a specific Worksheet within a Workbook and let the User edit it in the Form. If I reference your Spellcheck will it SpellCheck it?
I will probably use this in my project but I do have a question:
It seems to take a long time to do the initial Spell Check on a file open. For instance, 27 lines of text with an average of about 6 or 7 words per line (many with 4 or less words) it takes about 12-15 seconds to finish. Is this normal?
I have also noticed that most of the time (seems like not always) if you close the Spell Check dialog window before it finishes checking the entire document you get the following error:
RaceOnRCWCleanup was detected
Message: An attempt has been made to free an RCW that is in use. The RCW is in use on the active thread or another thread. Attempting to free an in-use RCW can cause corruption or data loss.
I was able to reproduce this error in your test app. I selected the RichTextBox tab, then clicked the spell check button and then immediately closed it. You may have to do this more than once to reproduce.
Thanks.
Actually I removed the forms and recompiled the code as a DLL and the errors went away. If I get a chance I'll backup my project and reference the exe instead of the DLL and try to get you more details.
The problem of the slow spell checking times is still present though in the DLL compile though. I may try to convert the dictionary that comes with Firefox to work with your code and see if maybe the dictionary is just too large. It seems like it has a lot of Euro specific spellings that I wouldn't even use anyway, such as "colour" instead of the US "color".
OK... well let me know how it goes :)
Kris
Interesting I checked the speed on my i7 2.6 GHz and it the spell check engine checks at an average of 60.42 words per second... how many words are visible in your text box (it only checks visible words)?
Even with 27 lines @ 7 words (189) words total, it should take about 3.5 seconds (after redraw time etc)...?!
Can you post the tet in your text box here?
Thanks
Kris
I am really impressed with this Spell Check and would love to implement it in a project I am working on. Great job!!
However, I am currently experiencing two issues, which may or may not be related.
The first is that we are using MDI forms for this application and the issue of drawing the correction lines is indeed as feared in your "Possible Issues" segment. It is visible over other windows. It is said that the following code can be used to implement the older "compatible" rendering.
DirectCast(TextBox.SpellCheck, SpellCheckTextBox).RenderCompatibility = True
But I am not sure where this should be located or how. I tried it both before and after EnableSpellCheck(). Before I see nothing on the text box. After, the behavior was as without the .RenderCompatibility being set. I am sure I am probably not implementing it correctly.
The other issue I have had is that the Spell Checking (minus the above stated issue) works fine with multiple MDI forms until I close one of them and try to open another, at which time I receive the error "Cannot access a disposed object". with the following references to the SpellCheck app in the exception dump:
at i00SpellCheck.SpellCheckFormExtension.ReloadSpellCheckControls(SpellCheckSettings SpellCheckSettings)
at i00SpellCheck.SpellCheckFormExtension.LoadDictionary(Object oSpellCheckSettings)
Has anyone seen something similar? Has anyone else tried using it with MDI apps?
Spell Checking is not a must have for this app, but I would love to be able to implement it with this great utility if possible.
Hi i use Macedonian dictonary i change my dictonary from mk.dic to dic.dic when i load program it doesnt show me errors like it's not load the dictonary
see pic: Attachment 90741. Here is my dictonary opened in notepad2 Attachment 90743 and when in program click removed (some word) from dictonary or add word to dictonary my dic.dic make like this Attachment 90745 all cyrilic char is like cubic.
I use this dictonary http://openoffice.c3sl.ufpr.br/contr...ries/mk_MK.zip
Edit.
I change encoding of text from ANSI to UTF-8 now doesnt show cubic like in last picture but it doesnt load dictonary.
[QUOTE=rmoliani;4183110]Hello
I'm trying using i00SpellCheck on my project... and everything is fine.. but... i'm from brazil... and here we have a big problem: accentuation...
well.. i changed the dic.dic to my dic.dic in pt-br..
and worked fine... but some words, with accentuation stay very strange... look in pic...
Change encoding for dictonary to UTF-8 Attachment 90747 and save file, it may work for your dictonary.
Since your application is a MDI application, you probably want all controls to use render compatibility. To do this the best method would probably be to do this:
vb Code:
AddHandler SpellCheckControlExtension.SpellCheckControlAdded, AddressOf SpellCheckControlAdded Me.EnableSpellCheck '.... Private Sub SpellCheckControlAdded(ByVal sender As Object, ByVal e As SpellCheckControlAddedRemovedEventArgs) Dim SpellCheckTextBox = TryCast(e.Control.SpellCheck, SpellCheckTextBox) If SpellCheckTextBox IsNot Nothing Then SpellCheckTextBox.RenderCompatibility = True End If End Sub
Let me know if this works
Thanks
Kris
EDIT:
Also I just checked placing DirectCast(TextBox1.SpellCheck, SpellCheckTextBox).RenderCompatibility = True directly after .EnableSpellCheck() ...
Worked fine for me :confused: ... if you are still stuck maybe you could paste your code?
Thanks
Kris
For latin language like brazilian who have special characters worked when you change encoding to UTF-8 but for cyrilic language like Macedonian, Russian, Serbian and etc doesn't work, it not show spell correction. So this spellchecker work only for English language.
Kris,
Thanks for replying. I modified the code as follows to reference only the specific text box, instead of the entire form:
txtProblem.EnableSpellCheck()
DirectCast(txtProblem.SpellCheck, SpellCheckTextBox).RenderCompatibility = True
However, I still get the overlay effect:
Spell Checked Text Box:
Attachment 90779
Another form over top of that text box:
Attachment 90781
Also, is there some cleanup I should be doing after my form is closed? When I open up another MDI form after closing the last one, I still get the "Cannot access a disposed object." error.
System.ObjectDisposedException was unhandled
Message=Cannot access a disposed object.
Object name: 'RichTextBox'.
Source=System.Windows.Forms
ObjectName=RichTextBox
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at i00SpellCheck.SpellCheckFormExtension.ReloadSpellCheckControls(SpellCheckSettings SpellCheckSettings)
at i00SpellCheck.SpellCheckFormExtension.LoadDictionary(Object oSpellCheckSettings)
Thanks for any help you can provide. If we can't use the SpellCheck on this MDI app, we think we can still utilize it on some standard Windows form app.
So I reran my tests using the contents of post #37 in THIS thread:
http://www.vbforums.com/showthread.p...=1#post4089783
Using your dictionary took 13 seconds, using the smaller Firefox dictionary took 6 seconds. I am running on significantly older equipment than you are so I am sure that is part of it.
When you perform the spell check do you take each word, and the compare it to every word in the entire dictionary?
Probably the case, sorry but I am not familiar on how to load / save files that contain cyrilic characters from a file.
The functions for loading / saving the dictionaries are in i00SpellCheck\Spell Check\Engine\Dictionary.vb, LoadFromFile() and Save().
The offending lines (I think) are:
Dim fileData = My.Computer.FileSystem.ReadAllText(Filename)
and
My.Computer.FileSystem.WriteAllText(...
If anyone knows how to do this, please let me know :)
Thanks
Kris
Sorry about not replying to this before, forgot about it :blush: ...
OK ... I found out what the error was ... I had some code in there that never gets called ...
I have fixed this bug and it will be in the next update ... but until then you can replace (or edit - change is in Maroon) the SpellCheck() function in i00SpellCheck\Spell Check\Engine\Extension.vb
Also no cleanup is neededCode:<System.Runtime.CompilerServices.Extension()> _
Public Function SpellCheck(ByVal sender As Control, Optional ByVal AutoCreate As Boolean = True, Optional ByVal SpellCheckSettings As SpellCheckSettings = Nothing) As SpellCheckControlBase
If SpellCheckControls.ContainsKey(sender) Then
'exists
Else
If AutoCreate Then
''create SpellCheckControlBase object and send it back...
Static plugins As List(Of SpellCheckControlBase) = PluginManager(Of SpellCheckControlBase).GetPlugins
Dim AcceptedClass = (From xItem In plugins Where xItem.ControlType.IsAssignableFrom(sender.GetType)).FirstOrDefault
If AcceptedClass IsNot Nothing Then
Dim SpellCheckControlAddingEventArgs As New SpellCheckControlAddingEventArgs
RaiseEvent SpellCheckControlAdding(Nothing, SpellCheckControlAddingEventArgs)
If SpellCheckControlAddingEventArgs.Cancel = True Then
Return Nothing
End If
'create a new instance of the plugin class
Dim o = DirectCast(System.Activator.CreateInstance(AcceptedClass.GetType), SpellCheckControlBase) 'TryCast(AcceptedClass.CreateObject, SpellCheckControlBase)
If o IsNot Nothing Then
SpellCheckControls.Add(sender, o)
AddHandler sender.Disposed, AddressOf Control_Disposed
o.mc_Control = sender
o.DoLoad()
RaiseEvent SpellCheckControlAdded(Nothing, New SpellCheckControlAddedRemovedEventArgs With {.Control = sender})
Else
Return Nothing
End If
Else
'no plugins for this control type
Return Nothing
End If
Else
'we don't want to automatically this control to check spelling, and it is not enabled already so return nothing
Return Nothing
End If
End If
If SpellCheckSettings IsNot Nothing Then
SpellCheckControls(sender).Settings = SpellCheckSettings
End If
Return SpellCheckControls(sender)
End Function
Kris
There are two types of spell checking (Both functions are in i00SpellCheck\Spell Check\Engine\SpellCheck.vb)...
You are talking about the correctness of a word.
This is done in SpellCheckWord()...
This does check if the word is in the dictionary of 150K words, with a few exceptions ... eg a word that is all caps is ignored, numbers etc.
For the actual suggestions (this is done when right clicking on an incorrect word for eg)...
This is done in SpellCheckSuggestions()
It basically takes the whole dictionary and eliminates words based on certain rules, to make a smaller dictionary.
Each word, in the smaller dictionary, is then given a "closeness" rating based on other rules, this is sorted and returned.
Kris
I only briefly looked at the code, and it appears that you load the whole dictionary into an array. Could you build another array (letter, start position, end position) at the same time to indicate where each starting letter in main array begins and ends and then use those values in the for loop to only search words that begin with the same letter?
For instance the first entry in the second array might be ("a", 1, 5790). So any words you are checking that start with the letter A would then only search the first 5790 words instead of all 150k before realizing that it was misspelled.
This should cut processing time way down.
Indexing like this is a good idea... I will put this in my todo list for the next update... will probably be about a week away... the only issue with this is that the dictionary would have to be kept in order ... but no biggie
Thanks for the suggestion btw :)
Kris
You are welcome.
One more performance enhancing suggestion, it looks like you are rebuilding the array for every word that you spell check. If you could make it preload one time and only reload when the dictionary is changed, that should further reduce the processing needed to complete the spell check. That may require the end user to instantiate the object on their main form load but I think the performance gain of not having to re-parse the dictionary for every word would be well worth it.
Oh another option to index and make it easier to properly place new entries would be to just use a separate array for each letter. When you add a new word, add it to the end of the appropriate letter array and then dump the arrays to the dic file in the correct order. and you never get a word in the wrong spot. This might be too much trouble though.
REF 1: Yes it does do that as it was faster than using the dictionary directly ... but as you said i could just use toarray 1 time and store that for the use on each word...
REF 2: Well the order of the dic probably doesn't matter ... as i could load it from the file and order it there ... when it saves back it would be in order... I was thinking of doing it this way before... as for adding words to it ... well i am going to have a second user dictionary in the next release... plan to anyway so REF 3 will prob be different to your suggestion anyway...
Thanks,
Kris
Awesome!
Since the current version is basically parsing the whole dictionary twice for every word, I think that preloading the dictionary alone will cut processing time close to in half since it removes one full parse per word. Then the indexing should cut the actual comparisons by close to 1/26 of the current time of the second parse. With those two enhancements speed should go from 12 seconds down to sub second spell checks even on my old hardware.
I can't wait to try out the next version. Thanks so much for all of your efforts.
Going .ToArray on my test it took 3187ms... without it, it took 3156ms...
Removing it could also lead to other problems too and can actually slow it down... eg i would have to synclock the dictionary file when looping through it (so if a word is added it won't stuff up for eg), thus when it is spell checking multiple textboxes at the same time it would actually slow it down.
I will do the 1st letter indexing though, right after I do the user dictionary...
Regards,
Kris
OK ... I have indexed the first letters and the improvement on my test is down from 3156ms to 250ms ... thats over 12.5 times faster!
Since the dictionary has to be indexed it takes slightly longer to load though... about 400ms longer on my pc.
Will get the user dictionary finished and post an update soon :)
Kris
Yeah I figured it would be a dramatic increase in speed. I also sent you a PM with another idea.
Ok ... next version is out ... now with a user dictionary, indexed dictionary (for greater speed), and speech recognition (tap F12 2x on a text box)!
Thanks, feedback is appreciated,
Kris
Amazingly fast now. Thanks!
Just released the version 20120907.
Kris
I am using i00 Spell check in my project.
Thank you!
Kris,
I finally had time to download the latest version. Your latest release did fix the "Cannot access a disposed object" error that I was getting. However, I am still getting the effect with the wavy lines being drawn over top of forms dragged over the other in the MDI app even after I set it to compatible rendering. Any suggestions? Thanks for your attentiveness.
Kris,
Here is an update from yesterday's post. I have been doing more testing on an MDI frames test application that I built and the SpellCheck can work great with MDI frames under two cases I have tested. Setting the compatible rendering to True DOES INDEED WORK, though there is the slight blinking you mentioned which is still very acceptable. My previous post about compatible rendering can be ignored, because that does work for a standard MDI app.
The other thing that I tried is on the Activated and Deactivate events on my MDI Child form. I turn the Spell Checking on and off for the form, and this works acceptably as well if you don't mind seeing the spell check markup disappear on all child windows that aren't active.
This is a great utility!
However... my MDI frames app isn't totally normal. This is not your fault. It is our application. We are not using standard text boxes and rich text boxes in our app. We are using "extended" text boxes which include features that we use specific to our app. The EnableSpellCheck grabs a hold of our "enhanced" text box just fine. However, the DisableSpellCheck doesn't seem to want to let our "enhanced" text box go so the spell check markup remains drawn over top of new child windows that are opened. Once again, this is not a problem with your code (which is a fun read), it is on our end and I am looking into what might be causing the issue.
One question I have knowing that you are placing a drawing object over the text box in order to facilitate the spelling error markup. Is it currently possible to programmatically reference and hide these drawing objects for any particular text box or the form as a whole? Perhaps I can just hide the drawing objects temporarily when a child window is not active and then display them again when the child form is active again. I have just started looking more through your code and might find the answer or how to do it myself, but you have been very helpful.
Thanks.
Another Update!! We're getting closer! Because our "enhanced" text boxes are just an extension of the standard windows control, by referencing the TextBox control inside of our custom text box, the SpellCheck seems to work just fine. I'll keep you informed, but it is looking promising!
With some adjustments to my code it appears that very soon I will be able to post the words "I am using i00SpellCheck in my project". It has been working very well.
However, I just ran into an error that occurred when checking a Rich Text box with bullets.
When I right clicked on the word "immediately" preceded by a bullet and marked as incorrect by Spell Check I received the following exception error:
Attachment 91361
There is more to the error, but here are some of the details:
************** Exception Text **************
System.ArgumentNullException: Value cannot be null.
Parameter name: outer
at System.Linq.Enumerable.Join[TOuter,TInner,TKey,TResult](IEnumerable`1 outer, IEnumerable`1 inner, Func`2 outerKeySelector, Func`2 innerKeySelector, Func`3 resultSelector)
at i00SpellCheck.UserDictionaryBase.SpellCheckSuggestions(String Word) in C:\Users\RobertF\Desktop\SpellCheck\i00SpellCheck\Spell Check\Engine\Dictionary\Base Ext\UserDictionary\UserDictionaryBase.vb:line 75
at i00SpellCheck.Menu.AddSpellItemsToMenu.AddItems(String Word, Dictionary Dictionary, Definitions DefinitionSet, Synonyms Synonyms, SpellCheckSettings Settings) in C:\Users\RobertF\Desktop\SpellCheck\i00SpellCheck\Spell Check\Engine\Menu.vb:line 297
at i00SpellCheck.SpellCheckTextBox.ContextMenuStrip_Opening(Object sender, CancelEventArgs e) in C:\Users\RobertF\Desktop\SpellCheck\i00SpellCheck\Spell Check\Controls\TextBox\Menu.vb:line 371
at System.ComponentModel.CancelEventHandler.Invoke(Object sender, CancelEventArgs e)
I don't believe my users will be putting in too many bulleted items in the rich text field, but it is something that I might need to address before implementing the SpellCheck.
I'm still loving it, though. Thanks!!
For whatever reason when pasting text from Word or Outlook that includes bulleted or numbered lists, the tab between the bullet and the list wasn't being replaced with a space in code processing. I am not very familiar with the .NET regular expressions implementation, but by just adding the following line to last part of processing in the RemoveWordBreaks function in Formatting.vb, I was able to fix my problem.
Text = Text.Replace(vbTab, " ")
It appears that the Regex processing is checking for tabs, but wasn't removing it from a bulleted list. Rather than mess with the Regex, I did a simple replace which works acceptably for me and solved the problem.
Pasting from other apps seems to give some interesting results (it isn't something that I believe will happen often in my app), but this utility is still very good.
I actually found this issue yesterday ... the error is in i00SpellCheck\Spell Check\Engine\Dictionary\Flat File\FlatFileSpellCheck.vb
you need to change the bit that goes:
vb Code:
'add words that start with that letter only Dim DicWords As List(Of String) = IndexedDictionary.Item(Word) If DicWords Is Nothing Then Return Nothing
to:
Will post an update later that fixes this issueCode:'add words that start with that letter only
Dim DicWords As List(Of String) = IndexedDictionary.Item(Word)
If DicWords Is Nothing Then Return New List(Of SpellCheckSuggestionInfo)
Regards,
Kris
20120914 is out ... Version changes can be found here
Kris
I am using i00 Spell check in my project:D
Just a quick question. I'm using VS 2010 and when i use me.enablespellcheck() it doesn't work. When I enable the spell check for each and every textbox then it works. Is there something I can do so that I only have to add one line of code to all my forms?
Still a great product. I've been looking for this for a long time.