Click to Rate and Give Feedback
Related Articles

There's always been disagreement about whether large blobs, such as document and multimedia items, should be stored in the database or file system. In SQL Server 2008 you don't have to choose; filestream storage provides the best of both approaches.

Bob Beauchemin

MSDN Magazine May 2009

...

Read more!

This column shows you how to secure the .NET Services Bus and also provides some helper classes and utilities to automate many of the details.

Juval Lowy

MSDN Magazine July 2009

...

Read more!

Cobra, a descendant of Python, offers a combined dynamic and statically-typed programming model, built-in unit test facilities, scripting capabilities, and much more. Feel the power here.

Ted Neward

MSDN Magazine June 2009

...

Read more!

Microsoft Velocity exposes a unified, distributed memory cache for client application consumption. We show you how to add Velocity to your data-driven apps.

Aaron Dunnington

MSDN Magazine June 2009

...

Read more!

Here the author dissects the ASP.NET MVC framework and looks at how controllers work. He then explains how the framework interacts with your controllers and how you can influence those interactions.

Scott Allen

MSDN Magazine May 2009

...

Read more!

Also by this Author

Paul DiLascia

MSDN Magazine April 2006

...

Read more!

Paul DiLascia

MSDN Magazine June 2005

...

Read more!

Many of you are no doubt in the process of upgrading to Visual Studio® 2005, so I thought now would be a good time to relate some of my own experiences with the new compiler. What took me so long? Hey, I'm a retro kind of guy! Better late than never!.

Paul DiLascia

MSDN Magazine June 2006

...

Read more!

This month Paul DiLascia codes some Microsoft Office-style dialog box features.

Paul DiLascia

MSDN Magazine August 2006

...

Read more!

Paul DiLascia

MSDN Magazine July 2005

...

Read more!

Popular Articles

Writing a Web application with ASP.NET is unbelievably easy. So many developers don't take the time to structure their applications for great performance. In this article, the author presents 10 tips for writing high-performance Web apps. The discussion is not limited to ASP.NET applications because they are just one subset of Web applications.

Rob Howard

MSDN Magazine January 2005

...

Read more!

James Avery does it again with his popular list of developer tools. This time he covers the best Visual Studio add-ins available today that you can download for free.

James Avery

MSDN Magazine December 2005

...

Read more!

Now you can perform efficient, sophisticated text analysis using regular expressions in SQL Server 2005.

David Banister

MSDN Magazine February 2007

...

Read more!

Here we introduce you to some of the concepts behind the new F# language, which combines elements of functional and object-oriented .NET languages. We then help you get started writing some simple programs.

Ted Neward

MSDN Magazine Launch 2008

...

Read more!

WPF is one of the most important new technologies in the .NET Framework 3.0. This month John Papa introduces its data binding capabilities.

John Papa

MSDN Magazine December 2007

...

Read more!

C++ Q&A
Sending Keystrokes to Any App, Calling .NET from an MFC App, and More
Paul DiLascia

Code download available at: CQA0501.exe (231 KB)
Browse the Code Online

Q I'm trying to write an application that fills in forms by sending keystrokes to another application. Should I send WM_KEYDOWN and WM_KEYUP messages, or is there a better way?
Q I'm trying to write an application that fills in forms by sending keystrokes to another application. Should I send WM_KEYDOWN and WM_KEYUP messages, or is there a better way?
Many readers

A You can probably get your app to work by sending WM_KEYDOWN and WM_KEYUP messages, but SendInput is an API function designed specifically for this purpose. It synthesizes input including keystrokes and mouse events by taking an array of INPUT structures, one for each input event—keystroke or mouse action. The INPUT structure holds a union that's either MOUSEINPUT or KEYBDINPUT (or HARDWAREINPUT, to simulate the toaster oven). For the keyboard it looks like this:
struct KEYBDINPUT {
   WORD wVk;      // virt key code
   WORD wScan;    // hw scan code
   DWORD dwFlags; // flags—see doc
   DWORD time;    // time stamp, 0 = dflt
   ULONG_PTR dwExtraInfo; // app-defined
};
A You can probably get your app to work by sending WM_KEYDOWN and WM_KEYUP messages, but SendInput is an API function designed specifically for this purpose. It synthesizes input including keystrokes and mouse events by taking an array of INPUT structures, one for each input event—keystroke or mouse action. The INPUT structure holds a union that's either MOUSEINPUT or KEYBDINPUT (or HARDWAREINPUT, to simulate the toaster oven). For the keyboard it looks like this:
struct KEYBDINPUT {
   WORD wVk;      // virt key code
   WORD wScan;    // hw scan code
   DWORD dwFlags; // flags—see doc
   DWORD time;    // time stamp, 0 = dflt
   ULONG_PTR dwExtraInfo; // app-defined
};
Figure 1 Typematic Initial Dialog 
So sending keystrokes to another application is basically a matter of building an array of INPUT structures, one for each keystroke (up and down), and then calling SendInput. To show how it works in practice, I wrote a little program called Typematic which lets you type your name, address, phone number, or other info quickly into forms just by pressing a hot key. It's the perfect thing for Web shopaholics. When you first run Typematic it displays the dialog in Figure 1, then goes into hiding. Thereafter you can press <WinKey>+T to reactivate Typematic and get the dialog in Figure 2 to see a list of abbreviations. Type "n" for name or "a" for address, and Typematic sends the corresponding string into the current form or application. The abbreviations are defined in a static table you can modify to use your own identity:
struct ABBREV {
   TCHAR key;
   LPCTSTR text;
} MYABBREVS[] = {
      { _T('n'),_T("Elmer Fudd") },
      { _T('a'),_T("1 Bunny Way") },
      ...
      { 0,NULL}
   };
Figure 2 Typematic Reactivated 
In the real world, you wouldn't hard-code this information, of course; you'd provide a user interface for customizing it, and save the info in the user's profile so each user on the machine could have different settings.
Typematic illustrates a few other tricks: how to register a hot key to activate your app (see my December 2000 column) and how to make a static text control accept keyboard input (you have to handle WM_GETDLGCODE and return DLGC_WANTCHARS.)
Typematic defines a specialized static text control CStaticAbbrev that both displays the abbreviations and reads the accelerator key. Figure 3 shows the source. When the user presses the hotkey, Typematic wakes up and sets focus to this CStaticAbbrev control, which waits for a character. When CStaticAbbrev::OnChar gets a key that matches one of the abbreviations in the table, it hides the dialog, then calls a helper function SendString to send the text:
// in CStaticAbbrev::OnChar
if (/* find char in ABBREV table */) {
   GetParent()->ShowWindow(SW_HIDE); // hide dialog
   SendString(abbrev.text);          // send text
}
#include "stdafx.h"
...
const HOTKEY = 'T';  // <WinKey>+T is hotkey to activate
static void SendString(LPCTSTR str);

class CStaticAbbrev : public CStatic {
protected:
   afx_msg UINT OnGetDlgCode() {
      return DLGC_WANTCHARS; // I want all chars
   }
   afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
   DECLARE_MESSAGE_MAP()
};

class CMyDialog : public CDialog {
public:
   CMyDialog(CWnd* pParent = NULL);
   ~CMyDialog();
protected:
   ...
   CStatic m_wndHelp;      // help message
   CButton m_wndOK;        // OK/Exit button
   CStaticAbbrev m_wndKeys;// static text to display/receive abbreviations

   UINT m_nIDHotKey;       // hot key identifier
   BOOL m_bFirstTime;      // first time activated?

   afx_msg LRESULT OnHotKey(WPARAM wp, LPARAM lp);
   DECLARE_MESSAGE_MAP()
};

struct ABBREV {
   TCHAR key;
   LPCTSTR text;
} MYABBREVS[] = {
   { _T('n'),_T("Elmer Fudd") },        // name
   { _T('a'),_T("1 Bunny Way") },       // addr
   { _T('c'),_T("Redmond") },           // city
   { _T('p'),_T("206 555 1212") },      // phone
   { 0,NULL},
};

BEGIN_MESSAGE_MAP(CStaticAbbrev, CStatic)
   ON_WM_GETDLGCODE()
   ON_WM_CHAR()
END_MESSAGE_MAP()

void CStaticAbbrev::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
   for (int i=0; MYABBREVS[i].key; i++) {
      if (nChar==MYABBREVS[i].key) {         // found:
         GetParent()->ShowWindow(SW_HIDE);   // ..hide dialog
         SendString(MYABBREVS[i].text);      // ..and send text
         return;
      }
   }
   MessageBeep(0);
}

LRESULT CMyDialog::OnHotKey(WPARAM wp, LPARAM lp) {
   if (wp==m_nIDHotKey && !IsWindowVisible()) {
      if (m_bFirstTime) {
         // first activation: replace initial message with abbrevs list
         CString text;
         for (int i=0; MYABBREVS[i].key; i++) {
            CString temp;
            temp.Format(_T("%c = %s\n"), MYABBREVS[i].key,
               MYABBREVS[i].text);
            text += temp;
         }
         m_wndKeys.SetWindowText(text);
         m_wndHelp.SetWindowText(
            _T("Type one of the keys below to enter text."));
         m_wndOK.SetWindowText(_T("E&xit"));

         m_bFirstTime = FALSE;
      }
      ShowWindow(SW_NORMAL);  // activate myself
      m_wndKeys.SetFocus();   // set focus to abbrev control
   }
   return 0;
}

static void SendString(LPCTSTR str) {
   INPUT inp[2];
   memset(inp,0,sizeof(INPUT));
   inp[0].type = INPUT_KEYBOARD;
   inp[0].ki.dwFlags = KEYEVENTF_UNICODE; // to avoid shift, and so on
   inp[1] = inp[0];
   inp[1].ki.dwFlags |= KEYEVENTF_KEYUP;

   for (LPCTSTR p=str; *p; p++) {
      inp[0].ki.wScan = inp[1].ki.wScan = *p;
      SendInput(2, inp, sizeof(INPUT));
   }
}
When Typematic hides itself, Windows® automatically restores the focus to whichever window previously had it, so the input goes to whichever window the user was working in before she pressed the hotkey. Pretty clever, eh? If you need to direct input to a specific application or window, make sure it's active before calling SendInput. SetForegroundWindow is the function to call.
All the work of sending the keystrokes happens in SendString, which builds the INPUT array and calls SendInput (see Figure 3). SendString sends a sequence of KEYDOWN/KEYUP pairs of INPUT structures, one pair for each character in the string. It uses the KEYEVENTF_UNICODE flag to send the string as Unicode characters. Unicode makes life easy because you don't have to synthesize capital letters using the Shift key. Without KEYEVENTF_ UNICODE, you'd have to send capital E as <Shift> followed by e, with down/up events for each, for a total of four keystrokes. Thank the Redmondtonians for adding KEYEVENTF_UNICODE!
If you're programming with Managed C++ or some other Microsoft® .NET-compliant language, sending keystrokes is even easier. There's a Framework class, SendKeys, with a static function Send that makes sending keys as easy as pie. You can even send special keys using squiggle syntax. For example "{F1}{BACKSPACE}A" sends F1, Backspace, A. Just for fun, I wrote another version of Typematic, Typematic.NET, that uses SendKeys. Now the SendString function is trivial:
#pragma managed
void SendString(LPCTSTR str) {
   SendKeys::SendWait(str);
}
What could be easier? When I first attempted this, I naturally tried SendKeys::Send, not SendWait. Why should I wait for the app to finish eating its keys? Alas, when I tried it, Typematic crashed miserably with System.InvalidOperationException somewhere in Windows.Forms.dll. When I invoked the common language runtime (CLR) Debugger to see what the heck happened, the Output window displayed the following message: "Additional information: SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method." Now that's what I call a friendly error message! Let this be an example to you all. But before you run off to use SendKeys, be advised that it's not as reliable as SendInput. You can discover this yourself by testing Typematic and Typematic.NET against different apps like Microsoft Internet Explorer, Notepad, an MFC form view, or some other favorite app. For some reason, SendKeys doesn't always work. I suspect it's a focus or timing problem—the keys are sent but then vanish into the ether because the window you think has the focus doesn't actually have it yet. So while SendKeys is easier to use and more powerful than SendInput, it doesn't work perfectly in all situations. Sigh. Maybe the Redmondtonians will fix it in the next release.
One final warning: sending keystrokes is a notoriously flaky way to control another app. You have to get all the keys exactly right, and the slightest change in context or user interface can throw everything off. If you're trying to control another app, look for a scripting system, programming interface, or macro language.

Q I've read several articles on how to disable system key sequences like Ctrl+Alt+Del, including one of yours in the September 2002 issue of MSDN®Magazine. But, how can I programmatically send Ctrl+Alt+Del?
Q I've read several articles on how to disable system key sequences like Ctrl+Alt+Del, including one of yours in the September 2002 issue of MSDN®Magazine. But, how can I programmatically send Ctrl+Alt+Del?
William Burns

A The first question shows how to send keystrokes to any app, but you can't send Ctrl+Alt+Del using SendInput because this sequence is handled at a lower level in the operating system. Synthesizing keystrokes is not the proper way to "send" Ctrl+Alt+Del, anyway. What are you trying to do? If you want to invoke the task manager, call ShellExecute with "taskmgr.exe". If you're trying to reboot, you can call ExitWindowsEx with the EWX_REBOOT flag. ExitWindowsEx has all sorts of flags for shutting down or restarting the machine in different ways (see Figure 4). Also, your app needs the SE_SHUTDOWN_NAME privilege to reboot.
A The first question shows how to send keystrokes to any app, but you can't send Ctrl+Alt+Del using SendInput because this sequence is handled at a lower level in the operating system. Synthesizing keystrokes is not the proper way to "send" Ctrl+Alt+Del, anyway. What are you trying to do? If you want to invoke the task manager, call ShellExecute with "taskmgr.exe". If you're trying to reboot, you can call ExitWindowsEx with the EWX_REBOOT flag. ExitWindowsEx has all sorts of flags for shutting down or restarting the machine in different ways (see Figure 4). Also, your app needs the SE_SHUTDOWN_NAME privilege to reboot.

Shutdown Type Description
EWX_LOGOFF Shuts down all processes, then logs the user off
EWX_POWEROFF Shuts down the system and turns off the power
EWX_REBOOT Restarts the system
EWX_SHUTDOWN Performs shutdown so it's safe to turn off the power
Modifiers Description
EWX_FORCE Force-terminates processes without sending WM_QUERYENDSESSION/WM_ENDSESSION
EWX_FORCEIFHUNG Force-terminates processes if they don't respond to WM_QUERYENDSESSION/WM_ENDSESSION
Does anyone know the origin of Ctrl+Alt+Del? If you think you know, send me e-mail. I'll tell you the answer in a future column.

Q Can I call the .NET Framework from my MFC app? I want to call a managed class from my unmanaged MFC code, and I tried to do it by #using <mscorlib.dll>, but I got a message "/RTC1 incompatible with /clr." How can I call .NET from my MFC app?
Q Can I call the .NET Framework from my MFC app? I want to call a managed class from my unmanaged MFC code, and I tried to do it by #using <mscorlib.dll>, but I got a message "/RTC1 incompatible with /clr." How can I call .NET from my MFC app?
Julian Kinsey

A Of course you can call .NET from your MFC app! Like everything else in Windows, it's easy once you know the correct voodoo. When you first create an MFC app, the App Wizard sets up all sorts of compiler options for you. One of the options under C/C++ Code Generation is "Basic Runtime Checks". When you create an MFC app, the App Wizard chooses "Both (/RTC1, equiv. to /RTCsu)" in your debug build to perform runtime checks like checking for bad stack frames, uninitialized variables, or buffer overruns and underruns. These checks are incompatible with /clr because managed code is totally different (it's Microsoft intermediate language, not native), but when you add /clr, the IDE doesn't automatically remove /RTC1. So you have to do it manually.
A Of course you can call .NET from your MFC app! Like everything else in Windows, it's easy once you know the correct voodoo. When you first create an MFC app, the App Wizard sets up all sorts of compiler options for you. One of the options under C/C++ Code Generation is "Basic Runtime Checks". When you create an MFC app, the App Wizard chooses "Both (/RTC1, equiv. to /RTCsu)" in your debug build to perform runtime checks like checking for bad stack frames, uninitialized variables, or buffer overruns and underruns. These checks are incompatible with /clr because managed code is totally different (it's Microsoft intermediate language, not native), but when you add /clr, the IDE doesn't automatically remove /RTC1. So you have to do it manually.
For each .cpp file in your project, set Basic Runtime Checks to Default. This is rather unfortunate, since for native/unmanaged functions, the checks are a good thing. They help you find bugs in your program before you ship. It's a shame to throw out the checks just because you want to call a .NET class or two. Isn't there some way to have your .NET and runtime checks, too?
The problem is that to use Managed Extensions to call the Framework, you have to set Use Managed Extensions to Yes, which sets /clr, and the only place you can do it is in the project settings, which are global. Use Managed Extensions turns /clr on for all modules in your project. By default, all your functions are now managed. If you prefer to make native mode the default, you can add a line at the end of your stdafx.h:
#pragma unmanaged
Since every module includes stdafx.h, now all your modules compile in native mode the way they always did. When it's time to call the Framework, you can flip to managed mode like so:
#pragma managed
void DoSomethingWithDotNET(...) {
   // call framework classes here
   // safe from managed functions
}
Until now, I've always used this trick (of putting #pragma unmanaged at the end of stdafx.h). But it doesn't solve the runtime-check problem because /clr is still incompatible with /RTC even if most of your functions are native. In mixed-mode apps the compiler doesn't let you say "do the runtime checks in native functions where they make sense."
Figure 5 Project Settings 
What you really want to do is compile with /clr only the modules that actually call the Framework. But how can you do that, when Use Managed Extensions appears in the project-wide settings? Easy: you can always add specific switches in the Command Line section of the module's build properties. Figure 5 and Figure 6 show how to set this up. In your global project settings, set Use Managed Extensions to No, then add /clr to each module that calls the Framework. Now all the other modules can still use /RTC1 and get all the runtime checking goodies. Of course, now you have to move <mscorlib.dll> and all the other Framework files from stdafx.h to the managed modules. If you like, you can put all the standard .NET includes in one file UsesDotNet.h that looks something like this:
#using <mscorlib.dll>
#using <System.dll>
#include <vcclr.h>
using namespace System;
Figure 6 Module Settings 
Then just #include "UsesDotNet.h" in each module that calls the Framework. You can still use #pragma managed/unmanaged to mix managed and native code within a module.
There's one more catch. When you add /clr to one of your modules, you also have to select "Not Using Precompiled Headers" in addition to turning off the runtime checks. Precompiled header information only works when all the modules have the same compile options; if one module has /clr, it can't use the same precompiled header as other modules that don't. Hey, computers are so fast these days, who needs precompiled headers anyway? If you want to get really fancy, you can always compile your managed modules through a different header file like UsesDotNet.h.
For a real, live, working project that uses the approach I've described, take a look at the Typematic.NET application from the first question in this column. You can download it from the MSDN Magazine Web site. All of the modules in Typematic.NET are compiled the normal native way, using precompiled headers through stdafx.h and no Managed Extensions. The only function that calls the .NET Framework, SendString, lives by itself in its quiet lonesome module SendString.cpp, which gets the managed compilation treatment with /clr, no runtime checks, and no precompiled headers. Enjoy!

Send your questions and comments for Paul to  cppqa@microsoft.com.


Paul DiLascia is a freelance writer, consultant, and Web/UI designer-at-large. He is the author of Windows++: Writing Reusable Windows Code in C++ (Addison-Wesley, 1992). Paul can be reached at www.dilascia.com.

Page view tracker