Spell check textbox in Win10 - Slow - c#

I'm using the built in spell checker in WPF. It was working just fine until I had users start upgrading to windows 10... I think the issue is that it's being used for a lot of small text boxes. My application presents a grid (Telerik's TreeListView) with text boxes for one of the columns which i want spell checked. I need to be able to provide a custom dictionary to the spell checker; the only way I was able to do this was to subscribe to the textbox loaded event and add the paths in as follows:
TextBox tb = sender as TextBox;
tb.ContextMenu = ctx_Spell;
IList dcts = SpellCheck.GetCustomDictionaries(tb);
dictsList.Add(dcts);
if (KMApplication.Settings.UserDictionary != null)
{ dcts.Add(KMApplication.Settings.UserDictionary); }
foreach (Uri dct in KMApplication.Settings.RevitDictonaries)
{ dcts.Add(dct); }
Granted this calls the add for each and every text box which seems terribly wasteful, but it seemed to be working just fine with little noticeable lag and only on load up. However now on Windows 10 it seems to be a ridiculous lag. On my Windows 8.1 machine I load up a file with a few thousand rows and it appears in about 3 or 4 seconds; on my Windows 10 box, it appears in about 10-15 minutes. If I comment out the custom dictionaries portion of the above code it's back to about 3-4 seconds on either machine.
Does anyone know a better way to do this? Or if there is some way around it in Win10?

We have experienced a similar issue and saw improved performance by avoiding re-registering custom dictionaries on every TextBox control during load.
Unfortunately, we hit another issue with the way custom dictionaries are handled which can also result in very long loading times if you have even a small number of TextBox controls.
When a WPF application registers a custom dictionary in .NET 4.6.1 on Windows 8.1/10, a temporary dictionary file is created in %localappdata%\Temp and this is registered in the multistring value _GLOBAL_ in the registry key "Computer\HKEY_CURRENT_USER\Software\Microsoft\Spelling\Dictionaries".
If the _GLOBAL_ value ends up referencing a dictionary file which does not exist, the application starts to exhibit very slow loading whenever a control with spell check enabled is initialized.
This can happen by using the "Stop debugging" button in Visual Studio and then running the Disk Clean-up or CCleaner after enough time has passed for these to delete the temp dictionary files.
We managed to fix this by clearing the _GLOBAL_ value of any links to dictionary files which did not exist. The our application began to work as expected.
We raised the following connect bug:
https://connect.microsoft.com/VisualStudio/feedback/details/2153484

Starting .NET 4.6.1 (in Win8.1 & Win10), WPF uses ISpellChecker interface exposed by the OS to implement its SpellChecker, and the performance characteristics could be somewhat different indeed.
Notably, ISpellChecker's custom dictionary registrar acts globally - it no longer acts as a per-control registration. (See KB article link below). As a result, registering the same set of dictionaries over and over for each control is wasteful and can potentially degrade your performance. Besides, the OS will just start ignoring your dictionaries when it reaches an internal limit.
Just register the dictionaries once, or use the alternative registration mechanism outlined at http://blogs.msdn.com/b/wpf/archive/2015/10/29/wpf-in-net-4-6-1.aspx and place the files under %appdata%\microsoft\spelling\.
If you need to run the same application on Win7/Win8 as well as Win8.1/Win10, you may need to detect the OS and branch your dictionary registration strategy.
In general, typical uses of custom dictionaries should continue working as usual - with little difference between .NET 4.6.1 vs previous releases.
Also see https://support.microsoft.com/en-us/kb/3088234 for additional information.

Firstly, I want to mention that I know that the post is already a few years old but I think that my answer might help someone out there who has the same problem but where the presented solutions didn't work (like myself).
What fixed it for me was to add the following code to App.config:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Controls.DoNotAugmentWordBreakingUsingSpeller=true"/>
</runtime>
Alternatively you can also insert the following code after your InitializeComponent() call:
AppContext.SetSwitch(#"Switch.System.Windows.Controls.DoNotAugmentWordBreakingUsingSpeller", true);
Source 1 (XAML solution)
Source 2 (C# solution)

Related

WebView2: Multiple instances of same application need to launch the same browser control

Problem
I recently replaced a System.Windows.Forms.WebBrowser-based control with one that relies on Microsoft.Web.WebView2.WinForms.WebView2 instead. This has been working well, except that my users want to have 2 instances of their application running at once, with both instances occasionally having that WebView2 form open at the same time. When they try this, one of the two instances fails to load the WebView2 control until the other one is closed.
Learned / attempted so far:
I've found WebView2 to be extremely finicky, so I've looked into alternatives like CefSharp, but haven't wanted to dedicate time to implementing them until I know they can solve the problem. So far as I can tell, CefSharp and WebView2 do very similar things as far as launching a Chromium-based browser, rendering to a WinForms control.
This blog post (read: advertisement) for paid alternative DotNetBrowser indicates that
You can initialize and use several Chromium engines simultaneously with different configurations [in DotNetBrowser], which is not possible in CefSharp.
I'm wondering if this same limitation applies to WebView2, and is the cause of my users' inability to have 2 instances of that same form loaded at once.
Context
I'm supporting an ancient desktop CRM that's set to be retired in favor of a modern alternative, but in the mean time, the old standard needs to integrate with new processes we're bringing in. One of those new processes is a web page from an external service that our call center users enter data into, then expect the CRM to pull entered data out of the web page.
The part of their process I did not know about is the 2-instance bit from above: they're used to being able to copy-and-paste from one embedded browser window to the other.
#Poul Bak in the comment on the question had it right: providing settings that differ per-instance of the application fixed the problem.
The setting I changed per-instance was the path of the user data folder: I was able to pass different values for the userDataFolder argument of the CoreWebView2Environment.CreateAsync method, branching based on a variable that holds different values between the instances that my users are running.

WPF ImageProcessor slow first time use

In my WPF application i need to make thumbs from photo the user add to the program. To do this i use the ImageProcessor package which works perfect for me.
Bu i have one small problem the first use in an application session always takes 5 a 10 seconds to complete every next thumb making in the same session only takes milliseconds.
It looks like the DLL is only loaded on first use.
Is there a way to make this faster?
I've tried replacing ImageProcessor with ImageResizer and also tried loading ImageProccesor on application startup both didn't work.
I talked to the owner.
It appear to be the plugin search routine which was checking all referenced assemblies. My project uses many DevExpress components which gives me a few dozen assemblies in the project folder.
The owner has made exceptions in the search routine.
Issue on GitHub

c# read syslistview32 items tooltips via winapi

i want to write an application, which reads under windows xp the quick launch items in the order like they are located in the taskbar,
and sets hotkeys for each of these item.
windows + 1 should start the first application
windows + 2 the second, etc.
(like in windows 7)
all of these items are found i a folder, but if i read the items of this folder, i dont get the right order of these items.
i found two solutions the get the right order - first:
in the registry an entry is found, where its saved how they are located, but not in plain text. i dont know how to read this, and cant reverse engine it.
the second:
read via winapi the items tooltip from the taskbar, so i can (if there are not items with the same name) search via the name in the quick launch folder.
the quick launch bar is just a listview (syslistview32).
via sendmessage i got it work to count the items, and start one (faking a click on this item), but how the hell can i read the tooltip?
i have googled a lot, tried everything, but i didnt get it run.
i hope you have any snippets for me, to solve this problem.
cheers
Determining the order of the items in the Quick Launch toolbar programmatically is going to be inherently fragile. There's not an API exposed for this, which means that it's subject to change in future versions of Windows, breaking your code that relied on assumptions about undocumented implementation details.
However, this is less of a problem in this specific case than it normally would be, since the Quick Launch toolbar doesn't exist anymore (or, at least, no one uses it anymore). The last version of Windows that used the Quick Launch toolbar was Vista, so if you make sure that your code is compatible with Vista and earlier, you should be fine. It won't work with newer versions anyway.
The positions of items in the Quick Launch toolbar is stored in the Registry in the following key:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop
You can extract the information from there, parse and interpret it, and then use it as you like. As you mention, this information isn't stored in plain text form because that would be very slow for the shell to load and parse itself. Since this is undocumented and not designed to be used by clients, they had no particular benefit in making it user (or developer) friendly. All that matters is what's most efficient for the shell, and storing the binary information from its internal structures is the obvious choice.
You will need to reverse engineer this in order for it to be useful to you. The way I'd go about it is probably by setting up a test environment with a couple of items in the Quick Launch bar in a particular order, exporting the information from the Registry, moving one of the items around, exporting the updated information from the Registry, and comparing the two exported Registry files to see what changed. Rinse and repeat as many times as necessary to deduce the pattern. (Really makes you wonder why so many developers actually do take the time to reverse-engineer undocumented aspects of Windows, doesn't it?)
The other option would be to use Spy++ to investigate the windows that implement the taskbar and its Quick Launch toolbar. I don't have a pre-Windows 7 system around, but it sounds like from the question that you've already done this and determined that the Quick Launch toolbar is implemented using a standard ListView. If you know the name of that window (and the names of its ancestor windows), you can walk through those windows to obtain a handle to the window you're interested in. And then you can determine the order of the items in the window as if it were a standard ListView in your own application.
The documentation for ListView controls is here; that should get you started in the right direction. You can get the text of one of the subitems by sending the LVM_GETITEMTEXT message.
This is probably the easier way of doing it. The same caveats apply--there is nothing keeping future versions of Windows from changing the names of those windows or the way that the taskbar is implemented, but since the only versions of Windows that have a Quick Launch toolbar have already been released (and therefore aren't likely to change), this may not be a big problem.
Then again, with the fact of the Quick Launch toolbar's obsolescence in mind, I struggle to comprehend why this endeavor is even worthy of investing developer time.
Also, even once you get this program all written and installed, consider what happens when the user adds a new item to the Quick Launch toolbar or re-arranges the existing items. How is your utility going to know that and adjust the keyboard shortcuts accordingly? What if an installer adds/removes an item from the Quick Launch toolbar?

C# text import from external window

I'm working on an existing project that has a text import tool written in C#. It essentially shuffles to the last window that had focus, copies the text, switches back and pastes the text in the textbox. To do this it essentially issues keyboard commands so: Alt + Tab, Ctrl + A, Ctrl + C, Alt + Tab and then finally get the text from the clipboard and add it to the textbox.
Currently, it works terrific on XP. It doesn't, however, work on Vista/Win 7. It will switch to the new window and that appears to be it but when I go back to the C# it has added whatever was previously in the clipboard (not successfully copying the new text). My guess is that there's some problem telling another window to use the keyboard keys (Select All and Copy).
I have done some moderate searching online and haven't really found anything so I was hoping to see if anyone may have had a similar problem.
Assuming you're using SendKeys, you might want to look at this comment on the SendKeys MSDN page. If this is something introduced with Vista, it'd almost certainly affect Windows 7 as well, Id' think:
Note
The SendKeys class has been updated
for the .NET Framework 3.0 to enable
its use in applications that run on
Windows Vista. The enhanced security
of Windows Vista (known as User
Account Control or UAC) prevents the
previous implementation from working
as expected.
The SendKeys class is susceptible to
timing issues, which some developers
have had to work around. The updated
implementation is still susceptible to
timing issues, but is slightly faster
and may require changes to the
workarounds. The SendKeys class tries
to use the previous implementation
first, and if that fails, uses the new
implementation. As a result, the
SendKeys class may behave differently
on different operating systems.
Additionally, when the SendKeys class
uses the new implementation, the
SendWait method will not wait for
messages to be processed when they are
sent to another process.
If your application relies on
consistent behavior regardless of the
operating system, you can force the
SendKeys class to use the new
implementation by adding the following
application setting to your app.config
file.
To force the SendKeys class to use the
previous implementation, use the value
"JournalHook" instead.
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx

C# Making a Frontend to a Console Program?

I wrote a console program in c# that takes up to three files as input, and does some data calculations on them.
I'd like to make a simple frontend that allows the user to easily
import files - basically choose up to three files to be routed to the backend code
change settings - I have about 10 settings that I'm currently storing in an app.config file. maybe a simple settings box would be nice
see what's going on - the console program shows some status messages that might be useful to display on a GUI
I have practically no experience with windows forms or GUI design, so I really don't know where to begin. I compiled the backend stuff into a *.dll and am currently playing around in design mode of sharpdevelop...but i really have no idea how to get the two to work together.
any pointers would be greatly appreciated!
The usual pattern, in cases like these, is to make the main features of the application into a class library and call that from a wrapping executable, such as a console app, winforms app or webforms app (if possible). That way you can easily adapt the interface as needed and simply route input and output to and from the class library.
Edit: I realize this isn't a very indepth answer, but I hope it helps to get started at least, together with any other answer that may arrive.
If you want to get started with GUI design in .NET, I recommend you choose WPF (Windows Presentation Foundation). This is the latest technology released in the UI/graphics area by Microsoft and is where everything is heading now. (Windows Forms won't be obsolete for a long time, though it is surely but slowly becoming deprecated.) I noticed however that you are using SharpDevelop, which doesn't yet have real support for WPF (as far as I know), whereas it certainly does for WinForms. If there's any chance you can use Visual Studio, I recommend you begin by learning WPF. You have the advantage of not being confused by previous experience with the styles and methodologies of WinForms, so it would very much be the right way to go.
Whichever you wish to learn, the Getting Started page of WindowsClient.NET (the official MS site for both WinForms and WPF) would be a great resource. There's also a few MSDN articles on getting started with WPF.
Hope that helps.
Have you tried Visual Studio Express editions? They're free and come with a designer for either WinForms or WPF applications.
As a first pass you'll need 3 text areas for the filenames, with associated buttons to bring up the file open dialog (it doesn't actually open the file just returns the filename).
A label to display the status - updated from your worker code.
Then either the various radio buttons, check boxes etc for your configuration settings.
Oh and don't forget the "Start" button to set off your process.
If your process takes a while you ought to use a background worker thread. You can then implement a "Cancel" button to safely abort the process and tidy up if it goes wrong.
There will be optimisations and reorganisations that you can do once you've got it working.
Your question is quite indistinct. If you're asking about working with GUI, you should read some book on Windows Forms.
And if you're asking about how to put your dll in your new windows forms application, then you should just add a reference to it in winforms project's properties and then use classes from dll's namespace.

Categories