Becoming a better version of myself.
- Open-source implementation of Markdown for C# and Javascript. Code Quality Rankings and insights are calculated and provided by Lumnify. They vary from L1 to L5 with 'L5' being the highest. Visit our partner's website for more details.
- Fork MarkDownSharp to make it accept plug-ins Similarly to what GitHub does, use the managed syntax highlighting product and post process the Html generated by MarkDownSharp By the way, as a MarkDown alternative, you might want to consider Moonshine, a managed wrapper on top of Sundown which is said to be 'at least 20x faster than MarkdownSharp when run against MarkdownSharp's own.
This article is going to be all about how you can control, customize and extend other programs using C#. As an example scenario we’re going to be extending the default Windows program Notepad with a custom function.
The C# application will modify all running instances of Notepad by adding a new button to the UI and listening for clicks on the button. A click on the button will convert the text in the Notepad text field into HTML using a Markdown parser (What is Markdown?) and display the HTML in our application.
If you follow the article, the finished product is going to look like this:
The article will have you construct the program step by step. If you want to read the full source code right away, you can skip directly to the end of the article – the complete C# source code is provided there. A download of the Visual Studio solution is also provided as an alternative.
Manipulating other programs using C#
To begin, let’s create a new WinForms project in Visual Studio. We’ll add a RichTextBox to the standard form, set its name to “richTextBoxInfo” and set the dock attribute to “Fill”. Now the form should look like in the screenshot above.
Now let’s open the Solution Explorer, click the References tab and add two new references using right-click – one to WindowsBase.dll, which can be found under “.NET”, and one to MarkdownSharp.dll under “Browse”. MarkdownSharp.dll can be downloaded from the project website for MarkdownSharp. Once that’s done, we can finally begin writing the actual program.
First of all, we’re going to add three new using references: System.Runtime.InteropServices, System.Diagnostics and MarkdownSharp. We need InteropService to run methods from unmanaged code, System.Diagnostics to list and analyse processes, and Markdown to parse the Markdown text later.
Next we’re going to add a whole load of “unmanaged code” – methods, constants and auxiliary variables. What everything means and does will be explained as the article progresses, therefore for now you can safely copy them from the following code box.
By the way, a quick tip: if you want to know what a native/unmanaged method signature should look like, you can have a look at pinvoke.net.
Now our code should look like this:
Identifying processes and selecting handles
Now let’s set up an event handler for the load event of our main form (Form1). You can do it by hand or using the Visual Studio Designer, it doesn’t matter.
Inside the load method we request all running Notepad instances from the system and save them in a list – we do have to know which program to manipulate.
Now we go through the list with all the Notepad instances. Here, we first get the text in the window title and pass it to richTextBoxInfo in our main form.
Afterwards we make a reference to the text field of the respective Notepad window. We need it to gain access to the text contained in it later.
Finally we check how many buttons the Notepad window has in the menu bar. If it has fewer than 6 buttons then it hasn’t been manipulated yet, so we can add our button.
Once we’ve gone through the list of Notepad instances, we need to set up another EventHook. This one will listen for Windows events.
The code of the load method looks like this. (The comments in the code should tell you what line does what in case you forget.)
If we try to compile the program now, Visual Studio will throw us an error message. The reason for that is this line of code that we wrote at the end of the load method.
Here we pass a method called “WinEventProc” as an argument – a method that doesn’t exist in our code yet. Therefore, our next step will be to create this method and make it do things.
Listening for Windows events with C#
Since this method catches lots and lots of Windows events, and since we only need those associated with the user clicking on our newly added button, we need to filter the relevant events using an if statement. To achieve this, we need to check if the event was triggered by a Notepad instance contained in the list we created in the load method (handlesNp.Contains(hwnd)) and if it was triggered by our button (_CustomMenuID idChild).
If the event fits both criteria, we get the text out of the Notepad text field using the GetWindowText() method. Afterwards we set up an instance of Markdown and convert the Notepad text from Markdown to HTML.
Now we create a new window/form, add a WebBrowser and a RichTextBox to it and pass our freshly parsed HTML to both elements.
Finally, we open the new window and move it to the foreground. The code for all that looks like this:
We press F5, the compiler runs, and… error! We have the hook method this time, but we used a new method in it that doesn’t exist yet. Therefore we add the definition of the missing GetWindowText() method.
A variable is missing as well – the htmlBody string variable. It contains the HTML and CSS code that displays our text in the WebBrowser element. (This is somewhat long, so I collapsed the following code block. A click on the code box will expand it.)
Now we’re almost done. The last step will be adding a form closing event handler to the form. This event handler will take care of removing our Windows event listener when the program is closed.
Now the program is complete. To test it, we open a Notepad window and write a couple of lines of text in Markdown format. Now we compile and start our program. As soon as its window appears, a new button should show up in the menu bar of the Notepad window.
Clicking the button should open another window that shows our Markdown text formatted and as raw HTML code.
Complete source code and download
If this is all too confusing for you or if you don’t have time, you can download the entirety of the source code as well as the complete Visual Studio project by following this link.
Download: Visual Studio example project
Questions, ideas and feedback
C# Markdown Parser
That’s it for today. If you have questions, ideas or feedback about this article, just leave a comment. Also let me know if you have ideas for new topics to write about.
Stack Overflow Markdown
MarkdownSharp is an open source C# implementation of a Markdown processor.
MarkdownSharp is an open source C# implementation of markdown processor, as featured on Stack Overflow.
This port is based heavily on the original perl 1.0.1 and Perl 1.0.2b8 implementations of Markdown, with bits and pieces of the apparently much better maintained php Markdown folded into it. There are a few Stack Overflow specific modifications (which are all configurable, and all off by default). I'd like to ensure that this version stays within shouting distance of the Markdown 'specification', such as it is...
(Source: code.Google.com/markdownsharp)
Markdownsharp Example
You'll need to know:
Blogs, Links and Q&A