In my project I'm doing a lot of native UI rendering1, soon I will blog on why.
Naturally I have many images to render using DrawImage methods, that requires an Image instance.
There are couple of ways to load an image but the best2 and easies option is using a Resource File, just dragging and dropping the images into the resource designer will add the file to the project and generate a nice static property by the name of the file in the static class generated by the name of the resource file.
The problem is that each time image resource property is called a new image instance is created with the requested image, so if the same image is used in multiple places3 it will be loaded multiple times in memory4.
In the Outlook add-in project I'm working on there is a feature that if the users enters '@' character in the body of mail editor window a dropdown popup will show with some options.
Because this feature is on Outlook window we implemented the feature by capturing keyboard events1 and waiting for "shift + 2" keycode. We check for "shift + 2" because the captured windows keyboard message contains keycode and not the actual character.
In a beta phase an European client reported that this functionality doesn't work, a quick session with the client revealed he used European keyboard layout, something new to me as I used to US keyboard layout.
I'm happy to release another update to Html Renderer project.
This release is a result of integration of the Html Renderer in actual commercial project with complex html and stylesheet (more than 400 different styles), still not perfect but much closer to WebBrowser control rendering I'm replacing.
My next big step is to add support for images so stay tuned.
This is the first major release of my contribution to the project, the focus of this release is on:
1. Refactor the code for clearer, simpler and more powerful API (work in progress).
2. Improve simple html layout to be more compatible with WinForms WebBrowser control.
3. Add text selection with copy capability.
Following the changes list there is a deeper explanation to some of the changes.
Working on adding text selection and copy-paste to HTML Renderer I wanted to add rich text copy capability.
My first thought was to use Clipboard.SetText method with TextDataFormat.Html but to my surprise it just didn’t work. Turning to Google I finally found this post, harder to find than what I expected, that explained what needs to be done.
Apparently when setting html text you need to provide a header with additional information to what fragment of the html you actually want to paste while being able to provide additional styling around it:
Managed HTML rendering is a pain in the ass for a really long time, a really good solution I was able to find is this HTML Renderer hosted on CodePlex, though the project seems to be dead and I'm not sure how I can contribute… Anyway, It's 100% managed code and has nice HTML 4 and CSS level 2 spec cover.
So I decided to check it out and after a little playing around it felt a bit heavy so I decided to look into its performance using built in visual studio profiler, to ruin the ending I have managed to reduce average render time from 282 msec to 24 msec (91%).
The final code with most of the issues fixes raised here and here can be found here, you can use it under the same license the original code is under. Also, if everything goes well, I might be adding features to the project including text selecting for copy-paste support.
After we learned about RCW ref count and anonymous methods I can finally explain the GC deadlock bug in our Outlook add-in.
To continue my previous post on a bug I encountered. This time anonymous methods.
The best way to learn what happens under the hood is to see the generated code, I like to use dotPeek as it has the same UX as Resharper.
Not to make this post super long I focus only on 3 examples and ignoring different scenarios (statics, delegates) as the result is not much different and not really interesting.
I'm a little swamp so it's hard to find time to write a blog post, but recently I have worked on an issue that's worth the time to blog about.
Here's a frustrating yet optimistic example of why writing code inside a third party complex system is hard.
I recently encountered a fun bug in Outlook addin I'm working on and it was interesting enough that I decided to create a few posts around what caused it, it will probably be 3 blogs starting with RCW reference count stuff, continuing with anonymous delegates and finishing the the bug itself.
Disclaimer: this post is based on a similar stackoverflow question I answered a while ago.