• The Old New Thing

    How can you use both versions 5 and 6 of the common controls within the same module?


    Commenter Medinoc was baffled by the statement that the decision to use the visual-styles-enabled version of the common controls library is done on a window-by-window basis. " Isn't it rather on a per-module basis, depending on each module's manifest? If it is indeed on a per-window basis, how does one choose?"

    Whether a particular call to Create­Window (or one of its moral equivalents) gets the classic version of the control or the visual-styles-enabled version of the control depends on which activation context is active at the point of the call. If an activation context with version 6 of the common controls is active, then you get the control from version 6 of the common controls. Otherwise, you get the classic control.

    If you use the ISOLATION_AWARE_ENABLED macro, then including commctrl.h turns on a bunch of macros that take all your calls to Create­Window and related functions, and converts them into something like this:

    HWND CreateWindow_wrapped(... parameters ...)
     HWND hwnd = nullptr;
     ULONG_PTR ulCookie;
     if (ActivateActCtx(ModuleContext, &ulCookie)) {
      hwnd = CreateWindow(... parameters ...);
     DeactivateActCtx(0, ulCookie);
     return hwnd;

    where Module­Context is a global variable that holds the activation context you specified in your manifest.

    In other words, any time your code tries to create a window, the wrapper macros activate your v6 manifest, create the window, then deactivate the manifest.

    Remember that nobody walks the stack looking to see who the caller is. The return address is not reliable. (And checking the return address doesn't help for dynamically-generated code anyway.) The way to know which activation context is active is for somebody to actually come out and set it.

    Back to the question: The way you choose whether you want a classic or a visual-styles-enabled version of a control is by deciding whether or not to have the v6 manifest active when you call Create­Window.

    A common mistake is that people will call a function that requires a v6 manifest, such as Task­Dialog, but they will forget to activate the v6 manifest before calling. The result is that they call into version 6 of the common controls, but when the common controls library tries to create its task dialog, it fails because the v5 context is active, and the v5 context does not have a task dialog control.

  • The Old New Thing

    When was the WM_COPYDATA message introduced, and was it ported downlevel?


    Gabe wondered when the WM_COPY­DATA message was introduced.

    The WM_COPY­DATA message was introduced by Win32. It did not exist in 16-bit Windows.

    But it was there all along.

    The The WM_COPY­DATA message was carefully designed so that it worked in 16-bit Windows automatically. In other words, you retained your source code compatibility between 16-bit and 32-bit Windows without having to do a single thing. Phew, one fewer breaking change between 16-bit and 32-bit Windows.

    As Neil noted, there's nothing stopping you from sending message 0x004A in 16-bit Windows with a window handle in the wParam and a pointer to a COPY­DATA­STRUCT in the lParam. Since all 16-bit applications ran in the same address space, the null marshaller successfully marshals the data between the two processes.

    In a sense, support for the WM_COPY­DATA message was ported downlevel even before the message existed!

  • The Old New Thing

    Why Johnny can't read music


    In the book He Bear, She Bear, the musical instrument identified as a tuba is clearly a sousaphone.

    (For those who are wondering what the title has to do with the topic of musical instrument identification: It's a reference to the classic book Why Johnny Can't Read.)

  • The Old New Thing

    Why does PrintWindow hate CS_PARENTDC? redux


    Why does Print­Window hate CS_PARENT­DC? Because everybody hates CS_PARENT­DC!

    Commenter kero claims that it's "easy to fix" the problem with Print­Window and CS_PARENT­DC. You just remove the CS_PARENT­DC style temporarily, then do the normal Print­Window, then restore the CS_PARENT­DC style. The question is then why Print­Window simply doesn't do this.

    The question assumes that the described workaround actually works. It may work in limited situations, but it certainly doesn't work in general.

    Since the CS_PARENT­DC style is a class style, removing the style affects all windows of that class, not merely the window you are trying to print. Suppose there are two windows of the class running on different threads, and you remove the CS_PARENT­DC style in anticipation of doing a Print­Window. While that's going on, the other window gets a WM_PAINT message. Since the CS_PARENT­DC style was temporarily removed, that window will be painting with an incorrectly-clipped DC. Result: Incorrect pixels on the screen.

    The proposed workaround doesn't actually work reliably, which means that it probably shouldn't be done at all. (Random reinforcement breeds superstition.)

  • The Old New Thing

    2013 Q3 link clearance: Microsoft blogger edition


    It's that time again: Linking to other Microsoft bloggers, and once again, the links are all from the excellent NT Debugging blog.

  • The Old New Thing

    What's the difference between CopyIcon and DuplicateIcon?


    There are two functions that can be used to create one icon that is identical to another. One of them is Copy­Icon. The other is Duplicate­Icon. What's the difference?

    There isn't any difference. Both functions clone an icon. In fact, their implementations are basically line-for-line identical.

    Originally, there was just one function to clone an icon: Copy­Icon.

    Windows 3.0 introduced Program Manager, and the developers of Program Manager wrote their own function called Duplicate­Icon. Why? I have no idea. My guess is that they didn't realize that such a function already existed, so they inadvertently reinvented the wheel.

    Windows NT 3.1 came along, and the team that ported Program Manager to 32-bit Windows also ported the Duplicate­Icon function, and they figured, "This function is so useful, we'll export it for anybody to use!"

    Meanwhile, the original Copy­Icon function is sitting there saying, "What am I, chopped liver?"

    Anyway, it's a sad story, but that's how we ended up with two functions that do exactly the same thing. Personally, I would recommend using the Copy­Icon function. It's in user32.dll, which you are almost certainly already linked to if you're doing anything with icons in the first place, so the incremental cost is much lower.

    Update: Joshua points out that the two functions are not identical. Duplicate­Icon takes an extra instance handle parameter. Now it makes sense. The shell version is an enhancement to the user version in that it can also transfer icon ownership to another module. (Hence the new first parameter.) This was important in 16-bit Windows because icons were resources which were associated with modules. If you wanted to use an icon after the module was unloaded, you needed to copy it and transfer ownership. But this ownership transfer step is not needed in Win32 because, as we saw yesterday, icons are no longer tied to the underlying resources. So the functions started out different but now they're the same.

  • The Old New Thing

    Logging the foreground process as it changes


    Today's Little Program simply logs all changes to the foreground window by recording the path to the application the user switched to. You might use this as part of a usability study to monitor what applications users spend most of their time in.

    Most of this code is just taking things we already know and snapping them together.

    1. Using accessibility to monitor events, specifically to monitor foreground changes.
    2. Get­Window­Thread­Process­Id to get the process ID from a window.
    3. Open­Process to get a handle to a process given the process ID.
    4. Query­Full­Process­ImageName to get the path to the application from the handle. (For Windows XP, you can use Get­Process­Image­File­Name.)

    Take our scratch program and make these changes:

    BOOL QueryWindowFullProcessImageName(
        HWND hwnd,
        DWORD dwFlags,
        PTSTR lpExeName,
        DWORD dwSize)
     DWORD pid = 0;
     BOOL fRc = FALSE;
     if (GetWindowThreadProcessId(hwnd, &pid)) {
      HANDLE hProcess = OpenProcess(
      if (hProcess) {
       fRc = QueryFullProcessImageName(
              hProcess, dwFlags, lpExeName, &dwSize);
     return fRc;

    The Query­Window­Full­Process­Image­Name function is the meat of the program, performing steps 2 through 4 above.

    Now we just hook this up in our event callback function. This should look really familiar, since we did pretty much the same thing earlier this year.

    OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
     g_hwndChild = CreateWindow(TEXT("listbox"), NULL,
         0, 0, 0, 0, hwnd, NULL, g_hinst, 0);
     if (!g_hwndChild) return FALSE;
     return TRUE;
    void CALLBACK WinEventProc(
        HWINEVENTHOOK hWinEventHook,
        DWORD event,
        HWND hwnd,
        LONG idObject,
        LONG idChild,
        DWORD dwEventThread,
        DWORD dwmsEventTime
     if (event == EVENT_SYSTEM_FOREGROUND &
         idObject == OBJID_WINDOW &&
         idChild == CHILDID_SELF)
      PCTSTR pszMsg;
      TCHAR szBuf[MAX_PATH];
      if (hwnd) {
       DWORD cch = ARRAYSIZE(szBuf);
       if (QueryWindowFullProcessImageName(hwnd, 0,
                          szBuf, ARRAYSIZE(szBuf))) {
        pszMsg = szBuf;
       } else {
        pszMsg = TEXT("<unknown>");
      } else {
       pszMsg = TEXT("<none>");
      ListBox_AddString(g_hwndChild, pszMsg);
    int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
                       LPSTR lpCmdLine, int nShowCmd)
      ShowWindow(hwnd, nShowCmd);
     HWINEVENTHOOK hWinEventHook = SetWinEventHook(
         NULL, WinEventProc, 0, 0,
      while (GetMessage(&msg, NULL, 0, 0)) {
      if (hWinEventHook) UnhookWinEvent(hWinEventHook);

    The main program installs an accessibility hook for the EVENT_SYSTEM_FOREGROUND event, and each time the event fires, it extracts the process name and logs it to the screen. Since the notification is asynchronous, the foreground window may have been destroyed by the time the notification is received, so we have to be prepared for that case.

  • The Old New Thing

    When something gets added to a queue, it takes time for it to come out the front of the queue


    A customer wanted to know why the input they were simulating with Send­Input is not being reported by Get­Async­Key­State. Isn't that supposed to reflect the instantaneous keyboard state? I just pushed the key down (or at least simulated it), but when I ask if the key is down, I'm told "Nope." What's the deal?

    INPUT input = { 0 };
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = 'A';
    input.ki.wScan = 'A';
    input.ki.dwFlags = 0; // key down
    SendInput(1, &input, sizeof(INPUT));
    assert(GetAsyncKeyState('A') < 0);

    The Send­Input call simulates pressing the A key, and the code immediately checks whether the key is down.

    But sometimes the assertion fires. How can that be?

    Because you're asking the question before the window manager has fully processed the input. Here's a little diagram.

    Mouse Keyboard Hardware
    SendInput Hardware
    Raw Input Thread
    Raw Input Thread
    App 1 App 2 App 3

    When you call Send­Input, you're putting input packets into the system hardware input queue. (Note: Not the official term. That's just what I'm calling it today.) This is the same input queue that the hardware device driver stack uses when physical devices report events.

    The message goes into the hardware input queue, where the Raw Input Thread picks them up. The Raw Input Thread runs at high priority, so it's probably going to pick it up really quickly, but on a multi-core machine, your code can keep running while the second core runs the Raw Input Thread. And the Raw Input thread has some stuff it needs to do once it dequeues the event. If there are low-level input hooks, it has to call each of those hooks to see if any of them want to reject the input. (And those hooks can take who-knows-how-long to decide.) Only after all the low-level hooks sign off on the input is the Raw Input Thread allowed to modify the input state and cause Get­Async­Key­State to report that the key is down.

    And if you manage to look before all this happens, your code will see that the key isn't down yet.

    It's like dropping a letter in the mailbox and then calling somebody to say, "Did you get my letter yet?" Okay, the Raw Input Thread is faster than the Postal Service, but you still have to give it a chance to get the message, query each of the low-level input hooks, decide who the message should be delivered to, and put it in their message queue.

  • The Old New Thing

    Logging the contents of every message box dialog via automation


    Today's Little Program logs the contents of every message box dialog, or anything that vaguely resembles a message box dialog. (Since there's no way for sure to know whether a dialog box is a message box or not.)

    using System.Windows.Automation;
    class Program
     public static void Main(string[] args)
       (sender, e) => {
        var element = sender as AutomationElement;
        if (element.GetCurrentPropertyValue(
         AutomationElement.ClassNameProperty) as string != "#32770") {
        var text = element.FindFirst(TreeScope.Children,
         new PropertyCondition(AutomationElement.AutomationIdProperty, "65535"));
        if (text != null) {

    This is the same pattern as the program we wrote last week, but with different guts when the window opens.

    This time, we see if the class name is #32770, which UI Spy tells us is the class name for dialog boxes. (That this is the numerical value of WC_DIALOG is no coincidence.)

    If we have a dialog, then we look for a child element whose automation ID is 65535, which UI Spy tells us is the automation ID for the text inside a message box dialog. (That the traditional control ID for static controls is -1 and 65535 is the the numerical value of (WORD)-1, is no coincidence.)

    If so, then we print the text.

    If we were cleverer, we could also confirm that the only buttons are OK, Cancel, and so on. Otherwise, we can get faked out by other dialog boxes that contain static text.

  • The Old New Thing

    The changing name of the Microsoft event held in conjunction with Martin Luther King, Jr. Day


    Today is Martin Luther King, Jr. Day, a federal holiday in the United States honoring the civil rights leader and formally serving as a day to reflect on the principles of racial equality and nonviolent social change and more generally to honor Dr. King's legacy through service.

    At Microsoft, the day has been recognized with an event whose name is, um, well, the name keeps changing. Here are the names from recent years:

    • 2006: Martin Luther King, Jr. Day Event
    • 2007: Martin Luther King, Jr. Celebration
    • 2008: Dr. Martin Luther King, Jr. Day Event
    • 2009: MLK Day Event
    • 2010: Celebration to Honor Dr. Martin Luther King, Jr.
    • 2011: Martin Luther King Day of Celebration
    • 2012: Martin Luther King, Jr. Day of Celebration
    • 2013: Dr. Martin Luther King, Jr. Day of Celebration Event

    I like to think this is done intentionally just to keep people on their toes.

    Ironically, although the event "celebrates diversity and inclusion," the email announcing the event inadvertently excludes people with visual impairments because it consists of a giant JPG with no ALT text.

    (No dream report from me today. That would be disrespectful to the man himself.)

Page 380 of 465 (4,641 items) «378379380381382»