• The Old New Thing

    Maxing out the upsell-o-meter

    • 12 Comments

    Many grocery stores in the United States have a printer next to the cash register which prints out coupons customized to your purchases. If you buy the house brand of spaghetti, it might print out a coupon for a slightly more expensive brand of spaghetti. The goal with these coupons is to get you to try a fancier (and therefore more profitable) version of the product in the hopes that you will like it and switch.

    For reasons not important to the story, one of my colleagues needed to buy baby formula for his newborn son. He and his wife carefully researched the options and decided that the best brand to get was XYZ brand. They went to the grocery store to buy some, and as expected, they got a cash register coupon.

    But upon closer inspection, it wasn't a coupon after all.

    Thank you for buying XYZ brand baby formula.

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Why is the desktop treated so special in window ordering?

    • 26 Comments

    Clipboarder Gadget wants to know why the desktop is treated so special in window ordering. Specifically, when you double-click a folder icon on the desktop, and the immediately close it, why does focus not go back to the desktop? Instead it goes to some random window.

    Actually, it's the other way around. Focus is going to a random window specifically because the desktop is not being treated special.

    The rules for focus transfer when a window is closed is that focus goes to the owner, if any. If there is no owner, then the window manager starts looking around, in a rather complicated way, but the next enabled window in the Z-order is on the candidate list. And since the desktop sits at the bottom of the Z-order, it almost never wins the "next enabled window in the Z-order" contest. Having the desktop somehow "jump the queue" and gain focus under certain conditions would mean giving the desktop special treatment.

    Even if you wanted to grant the desktop that special treatment, what would the rules be for deciding when to grant the desktop exception? The Explorer window for the folder you opened has no special connection to the desktop window in the window hierarchy. It belongs to a different thread. Depending on how your system is configured, it might even be in another process. What would you use to determine that closing that window should move focus to the desktop?

    Consider: You double-click the icon to open the folder. Then you click on Notepad. Then you click back on the folder window and close it. Shouldn't focus go to Notepad? Why should the desktop be special?

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Raymond misreads newspaper head... no wait, I didn't!

    • 26 Comments

    I have a habit of misreading newspaper headlines, so I simply assumed that this was just another one: Phelps sets word record in 400 IM. (And no, I don't normally read the Rocky Mountain News. The actual headline was printed across the top of the June 30 Seattle Times Sports section, but I couldn't find the headline in the online archives, so I found another newspaper with the same headline.)

    Wow, how fast did he IM 400 words?

    Duh, I must've misread it. Obviously the headline said world record.

    No wait, it really was word record!

  • The Old New Thing

    What's the difference between CopyIcon and DuplicateIcon?

    • 9 Comments

    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

    If you read any book about traditional weddings in Russian history, there must be a fight

    • 9 Comments

    You can buy a fake vacation for $500 or shell out $300 to $400 for a fake brawl at your wedding.

    "If you read any book about traditional weddings in Russian history, there must be a fight," said Alexander Yermilov, 22, who recently made a living at it.

    If you're looking for counterfeits, fakes, and forgeries, Moscow's your place. Assuming you can spot them.

    Even Putin's doctoral dissertation, researchers from the Brookings Institution revealed this year, contained major sections lifted from a text published by academics from the University of Pittsburgh.

    The revelations barely were repeated in the Moscow press, not because they were scandalous, but because they weren't—government officials routinely rely on fake dissertations patched together by underlings.

  • The Old New Thing

    Microsoft phenomenon: The annual award that winds up being awarded only once

    • 19 Comments

    The Grammy Awards will be handed out this upcoming weekend, an annual award that seems to have survived.

    A not uncommon phenomenon at Microsoft is the annual award that winds up being awarded only once. Because all the excitement is in the announcement, not in the actual award.

    Every year, we want to uniquely call out and recognize a set of people. I'm proud to kick off the XYZ Awards, which we will be given every year, starting this year, which recognize employees who best represent ABC and DEF.

    The XYZ Awards were indeed handed out that first year with great pomp and circumstance.

    And were never heard from again.

    This is a special case of the more general phenomenon of the introduction of some undertaking to great fanfare, only to have it quietly fade away into obscurity without any formal announcement that it had ended. One might cynically observe that the likelihood of this happening to your project increases the more dramatically it is introduced. If it's just called a program, then it might survive. If it's called an initiative, then you might want to hold off on ordering new business cards for a while. And if it's called a bold new initiative, then you'll want to spend some time freshening your résumé, because your project is doomed.

    Update since people seem to be missing the point: I'm not talking about marketing campaigns. Those are meant to die out eventually. I'm talking about stuff like The Council for Programming Excellence (which meets only once) or The DTI Program (which has a kickoff meeting and then nothing).

  • The Old New Thing

    Keep your eye on the code page: C# edition (warning about DllImport)

    • 19 Comments

    Often, we receive problem reports from customers who failed to keep their eye on the code page.

    Does the SH­Get­File­Info function support files with non-ASCII characters in their names? We find that the function either fails outright or returns question marks when asked to provide information for files with non-ASCII characters in their name.

    using System;
    using System.Runtime.InteropServices;
    
    class Program
    {
     static void Main(string[] args)
     {
      string fileName = "BgṍRồ.txt";
      Console.WriteLine("File exists? {0}", System.IO.File.Exists(fileName));
      // assumes extensions are hidden
    
      string expected = "BgṍRồ";
      Test(fileName, SHGFI_DISPLAYNAME, expected);
      Test(fileName, SHGFI_DISPLAYNAME | SHGFI_USEFILEATTRIBUTES, expected);
     }
    
     static void Test(string fileName, uint flags, string expected)
     {
      var actual = GetNameViaSHGFI(fileName, flags);
      Console.WriteLine("{0} == {1} ? {2}", actual, expected, actual == expected);
     }
    
     static string GetNameViaSHGFI(string fileName, uint flags)
     {
      SHFILEINFO sfi = new SHFILEINFO();
      if (SHGetFileInfo(fileName, 0, ref sfi, Marshal.SizeOf(sfi),
                        flags) != IntPtr.Zero) {
       return sfi.szDisplayName;
      } else {
       return null;
      }
     }
    
     [StructLayout(LayoutKind.Sequential)]
     struct SHFILEINFO {
      public IntPtr hIcon;
      public int iIcon;
      public uint dwAttributes;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
      public string szDisplayName;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
      public string szTypeName;
     }
    
     const uint SHGFI_USEFILEATTRIBUTES = 0x10;
     const uint SHGFI_DISPLAYNAME = 0x0200;
    
     [DllImport("shell32.dll")]
     static extern IntPtr SHGetFileInfo(
        string path, uint fileAttributes, ref SHFILEINFO info, int cbSize,
        uint flags);
    }
    // Output:
    // File exists? True
    //  == Bg?R? ? False
    // Bg?R? == Bg?R? ? False
    

    If we ask for the display name, the function fails even though the file does exist. If we also pass the SHGFI_USE­FILE­ATTRIBUTES flag to force the system to act as if the file existed, then it returns the file name but with question marks where the non-ASCII characters should be.

    The SH­Get­File­Info function supports non-ASCII characters just fine, provided you call the version that supports non-ASCII characters!

    The customer here fell into the trap of not keeping their eye on the code page. It goes back to an unfortunate choice of defaults in the System.Runtime.Interop­Services namespace: At the time the CLR was originally being developed, Windows operating systems derived from Windows 95 were still in common use, so the CLR folks decided to default to Char­Set.Ansi. This made sense back in the day, since it meant that your program ran the same on Windows 98 as it did in Windows NT. In the passage of time, the Windows 95 series of operating systems became obsolete, so the need to be compatible with it gradually disappeared. But too late. The rules were already set, and the default of Char­Set.Ansi could not be changed.

    The solution is to specify Char­Set.Unicode explicitly in the Struct­Layout and Dll­Import attributes.

    FxCop catches this error, flagging it as Specify­Marshaling­For­PInvoke­String­Arguments. The error explanation talks about the security risks of unmapped characters, which is all well and good, but it is looking too much at the specific issue and not so much at the big picture. As a result, people may ignore the issue because it is flagged as a complicated security issue, and they will think, "Eh, this is just my unit test, I'm not concerned about security here." However, the big picture is

    This is almost certainly an oversight on your part. You didn't really mean to disable Unicode support here.

    Change the lines

     [StructLayout(LayoutKind.Sequential)]
     [DllImport("shell32.dll")]
    

    to

     [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
     [DllImport("shell32.dll", CharSet=CharSet.Unicode)]
    

    and re-run the program. This time, it prints

    File exists? True
    Bg?R? == Bg?R? ? True
    Bg?R? == Bg?R? ? True
    

    Note that you have to do the string comparison in the program because the console itself has a troubled history with Unicode. At this point, I will simply cue a Michael Kaplan rant and link to an article explaining how to ask nicely.

  • The Old New Thing

    How do I get the title of a dialog from a dialog resource?

    • 13 Comments

    A customer submitted the following question:

    We are developing automated tests for our application. Among other things, our application uses property sheets, which means that the name of the tab is stored as the title of the dialog template resource. Since we want our automated tests to run on all language versions of our application, we don't want to hard-code the tab names in our automated test. I have not been able to find any information on how to programmatically extract the dialog titles from the dialog resources. Any pointers would be appreciated.

    I replied with some pointers:

    The customer was grateful for the pointers, then asked:

    Then the only way to do this is to load the dialog resource and parse the data looking for the string I want? Is it even possible to do this in C#?

    Well it depends on what your definition of "the only way" is.

    At the end of the day, somebody has to load the dialog resource and parse it, because after all that is what you said you want to do: "I want to get the title of the dialog from the dialog resource." The alternative is, what, psychic powers?

    There is no dialog template parsing library that comes with Win32. If you don't want to do the parsing, then maybe you can find somebody else who will. And if you're lucky, that other person may even have provided a C# interface.

  • The Old New Thing

    Follow-up: The impact of overwhelmingly talented competitors on the rest of the field

    • 14 Comments

    A while back, I wrote on the impact of hardworking employees on their less diligent colleagues. Slate uncovered a study that demonstrated the reverse effect: How Tiger Woods makes everyone else on the course play worse.

    The magic ingredient is the incentive structure. If you have an incentive structure which rewards the best-performing person, and there is somebody who pretty much blows the rest of the field out of the water, then the incentive structure effectively slips down one notch. Everybody is now fighting for second place (since they've written off first place to Tiger Woods), and since the second place prize is far, far below the first place prize, people don't have as much incentive to play well as they did when Tiger wasn't in the mix.

    The effect weakens the further down the ladder you go, for although the difference between first and second place is huge, the difference between 314th place and 315th place is pretty negligible.

  • The Old New Thing

    Why don't the shortcuts I put in the CSIDL_COMMON_FAVORITES folder show up in the Favorites menu?

    • 25 Comments

    A customer created some shortcuts in the CSIDL_COMMON_FAVORITES folder, expecting them to appear in the Favorites menu for all users. Instead, they appeared in the Favorites menu for no users. Why isn't CSIDL_COMMON_FAVORITES working?

    The CSIDL_COMMON_FAVORITES value was added at the same time as the other CSIDL_COMMON_* values, and its name strongly suggests that its relationship to CSIDL_FAVORITES is the same as the relationship between CSIDL_COMMON_STARTMENU and CSIDL_STARTMENU, or between CSIDL_COMMON_PROGRAMS and CSIDL_PROGRAMS, or between CSIDL_COMMON_DESKTOP­DIRECTORY and CSIDL_DESKTOP­DIRECTORY.

    That suggestion is a false one.

    In fact, CSIDL_COMMON_FAVORITES is not hooked up to anything. It's another of those vestigial values that got created with the intent of actually doing something but that thing never actually happened. I don't think any version of Internet Explorer ever paid any attention to that folder. Maybe the designers decided that it was a bad idea and cut the feature. Maybe it was an oversight. Whatever the reason, it's just sitting there wasting space.

    Sorry for the fake-out.

    Exercise: Another customer wanted to know why creating a %ALL­USERS­PROFILE%\Microsoft\Internet Explorer\Quick Launch directory and putting shortcuts into it did not result in those shortcuts appearing in every user's Quick Launch bar. Explain.

Page 382 of 443 (4,430 items) «380381382383384»