Emulating keyboard events in .NET

Every now and then, you may need to emulate pressing keys on a keyboard to accomplish things through code. I found I needed to utilize this method for an Outlook programming project. After a little searching, I was able to emulate a user pressing the “ALT” button twice. You can use the keybd_event function (http://msdn2.microsoft.com/en-us/library/ms646304.aspx) to emulate keyboard events:

Imports System.Runtime.InteropServices

‘List of virtual key codes: http://msdn2.microsoft.com/en-us/library/ms645540.aspx
Const VK_SHIFT = &H10
Const VK_NUMLOCK = &H90
Const VK_ESC = &H1B
Const VK_MENU = &H12 ‘This is the ALT key
Const KEYEVENTF_KEYUP As Integer = &H2

<DllImport(“user32”)> _
Public Sub keybd_event(ByVal vk As Byte, ByVal sc As Byte, ByVal Flags As Integer, ByVal dwExtraInfo As Integer)
End Sub

Public Sub PressAltKeyTwice()
‘Simulate Key Press
keybd_event(VK_MENU, vbNull, 0, 0)
‘Simulate Key Release
keybd_event(VK_MENU, vbNull, KEYEVENTF_KEYUP, 0)

Application.DoEvents() ‘This was needed in my code to register the first keypress. If I did not have this, the system acted as though I press it only once.

‘Simulate Key Press
keybd_event(VK_MENU, vbNull, 0, 0)
‘Simulate Key Release
keybd_event(VK_MENU, vbNull, KEYEVENTF_KEYUP, 0)

Application.DoEvents()

End Sub

Enabling two-way communication between javascript and parent WebBroswer class

When I began looking for a way to do this, I thought it was going to be very difficult. What I wanted, was a javascipt method inside a WebBrowser object hosted in a Custom Task Pane, to call a method in the parent object’s class that would then call a method in the web page view of a folder, which would then execute client-side javascript inside that HTML document object. Fortunately, this is a very easy task by utilizing two methods: window.external and HTMLDoc.parentWindow.execScript.

Getting a client-side javascript method to invoke a method inside the parent class is as simple as using:

– In the HTML code:

<a href=”http://blogs.orcsweb.com/ControlPanel/Blogs/posteditor.aspx?SelectedNavItem=NewPost#” onclick=”javascript:window.external.MyMethod(var1, var2);”>Invoke MyMethod</a>

– In parent object’s class

Public Sub MyMethod(ByVal var1 As String, ByVal var2 As String)
MsgBox(“Var1: ” & var1 & “, Var2: ” & var2)
End Sub

In Outlook, if the current folder is set to use a web view instead of the standard folder list, the Application.ActiveExplorer.HTMLDocument reference will contain a valid mshtml.HTMLDocument object (it will throw an exception otherwise). Executing client-side javascript (or vbscript in my case) is as easy as calling the parentWindow.execScript method:

Dim oHTMLDoc As mshtml.HTMLDocument

oHTMLDoc = Application.ActiveExplorer.HTMLDocument

oHTMLDoc.parentWindow.execScript(“ClientSideMethod(‘” & Var1 & “‘,'” & var2 & “‘)”)

The point of doing this is that the web page view of the folder contains an Outlook View Control object, and using the above methods, we are able to set the “Restriction” property of the object from a web page hosted inside a custom task pane.

Resource Protocol in .NET

I never liked deploying an application that had numerous dependencies as there just seemed to be more room for error. When I discovered the resource protocol (res://), it seemed like a great way to embed HTML files I needed to distribute with my Outlook add-in. The nice part is that there is a single file deployed to the user’s system and you avoid any issues of users accidentally removing dependency files or similar headaches. I originally thought it would be as easy as adding my HTML file as a resource in my Visual Studio project, but come to find out that would create a managed resource (resx:// protocol). Unfortunately, the resx protocol has two glaring limitations:

From MSDN (https://msdn2.microsoft.com/en-us/library/bb189724.aspx):

The resx:// protocol is designed to load resources from .resx files that are embedded into managed assemblies, with the following limitations:

  • The resx:// protocol is used to load resources from a managed assembly, which must be strong-name signed and located in either %windir%\ehome or the global assembly cache (GAC).
  • In the syntax resx://myassembly/myresourcefile/myresourceidentifier, the myassembly parameter does not have a file extension, so you cannot have a managed DLL and EXE with the same name and be able to load resources from both of them.

So I set out on a quest to figure out how to embed a HTML file into my DLL and access it using the resource protocol. It actually isn’t that difficult, but the documentation is scarce. Thanks to Wouter van Vugt’s post (http://tinyurl.com/34pezy), I was able to stumble my way through it. Here are the steps:

1. Edit your project file (.vbproj or .csproj) and add the following:
<PropertyGroup>
<Win32Resource>NameOfResourceFile.res</Win32Resource>
</PropertyGroup>

2. Create a resource script file named NameOfResourceFile.rc and add it to your project. It should look something like this:
/* standard resource # for HTML */
#define HTML 23

/* include all resources from external files */
RES_REF     HTML     “NameOfHTMLFile.html”

/* end */

3. Add the HTML file named NameOfHTMLFile.html to your project.

4. Add the following to the prebuild commandline (Project Properties > Compile > Build Events):
“C:|Program Files|Microsoft Visual Studio 8|SDK|v2.0|Bin|rc” /r “$(ProjectDir)NameOfResourceFile.rc”

5. Compile you project.

6. Test it. Put this in a browser to load the file: res://NameOfDLL.dll/RES_REF

You can also embed graphics into the resource dll and reference them in the embedded HTML file. Note that you need to specify the resource type in the URL if it is not a HTML resource (the default). For example, if you embed a bitmap, you would reference it like so: res://NameOfDLL.dll/2/NameOfBitmapFile.bmp. You can find a list of common resource types here: http://msdn2.microsoft.com/en-us/library/aa365064.aspx. Images don’t have an associated resource type, so you would use res://NameOfDLL.dll/GIF/NameOfGIFImage.gif to access the image. Also, you can’t use the resource protocol to access .xsl or .xml files.