• The Old New Thing

    How to get more hits on Google than even Steve Ballmer


    Ein deutscher Blogger namens Tony schrieb dass Robert Scoble is gaining on Steve Ballmer. Mit anderen Worten, dass eine Google-Suche nach "Robert Scoble" ungefähr 172.000 Seiten findet, während eine Google-Suche nach "Steve Ballmer" ungefähr 302.000 Seiten zeigt. Er fragte, ob jemand einen anderen Microsoft-Angestellten finden kann, der mehr Google-Ergebnisse als Robert Scoble bekommt.

    Na klar, das ist ganz leicht, und ich werde euch in das Geheimnis ziehen.

    Suche nach "David Smith". Ach, du meine Güte! 869.000 Ergebnisse! Noch mehr als Steve Ballmer!

    Du musst nur einen Person finden, der einen sehr gewöhnlichen Namen hat.

  • The Old New Thing

    The hunt for a faster syscall trap


    The performance of the syscall trap gets a lot of attention.

    I was reminded of a meeting that took place between Intel and Microsoft over fifteen years ago. (Sadly, I was not myself at this meeting, so the story is second-hand.)

    Since Microsoft is one of Intel's biggest customers, their representatives often visit Microsoft to show off what their latest processor can do, lobby the kernel development team to support a new processor feature, and solicit feedback on what sort of features would be most useful to add.

    At this meeting, the Intel representatives asked, "So if you could ask for only one thing to be made faster, what would it be?"

    Without hesitation, one of the lead kernel developers replied, "Speed up faulting on an invalid instruction."

    The Intel half of the room burst out laughing. "Oh, you Microsoft engineers are so funny!" And so the meeting ended with a cute little joke.

    After returning to their labs, the Intel engineers ran profiles against the Windows kernel and lo and behold, they discovered that Windows spent a lot of its time dispatching invalid instruction exceptions. How absurd! Was the Microsoft engineer not kidding around after all?

    No he wasn't.

    It so happens that on the 80386 chip of that era, the fastest way to get from V86-mode into kernel mode was to execute an invalid instruction! Consequently, Windows/386 used an invalid instruction as its syscall trap.

    What's the moral of this story? I'm not sure. Perhaps it's that when you create something, you may find people using it in ways you had never considered.

  • The Old New Thing

    This Game Boy won't hurt a bit, just help the Powerpuff Girls count backwards from ten


    Is there nothing a Game Boy can't do? We already learned that it can be played like a musical instrument. Now we discover that letting children play with a Game Boy before surgery is more effective than tranquilizers or a parent's hand at keeping them calm.

    You know when you go to the dentist and she asks you, "What flavor fluoride rinse would you like?" Perhaps someday the anaesthetist will ask you, "Do you want a Game Boy or a Nintendo?"

    (Drat, scooped by Slashdot again.)

  • The Old New Thing

    Why do dialog editors start assigning control IDs with 100?


    When you use a dialog editor and insert new controls, they typically are assigned control IDs starting at around 100. Why?

    Because the small numbers are already taken.

     * Dialog Box Command IDs
    #define IDOK                1
    #define IDCANCEL            2
    #define IDABORT             3
    #define IDRETRY             4
    #define IDIGNORE            5
    #define IDYES               6
    #define IDNO                7
    #define IDCLOSE             8
    #define IDHELP              9
    #define IDTRYAGAIN         10
    #define IDCONTINUE         11

    The dialog manager knows about these special values and assumes that if your dialog box has a control whose ID matches one of these special values, then it also behaves in a certain way.

    The dialog manager assumes that a control whose ID is IDOK is an OK button. If the user hits Enter, the default button will be pushed; if no default button can be found, then the OK button is pushed. Similarly, a control whose ID is IDCANCEL is assumed to be a Cancel button. If the user hits ESC or clicks the X button in the corner, then the Cancel button is pushed.

    If your dialog box has OK and Cancel buttons, make sure to give them the IDOK and IDCANCEL control IDs so that they act like proper OK and Cancel buttons. Conversely, any control with those IDs had better be proper OK and Cancel buttons.

  • The Old New Thing

    Scientists come one step closer to the perfect poppy-seed bagel


    It's easy to distribute points evenly across a flat surface, but doing so over a curved surface is a much more complicated problem. Even spheres are hard. NPR's Scott Simon interviews mathematician Ed Saff who with colleague Doug Hardin has developed a new method of attacking this complex problem.

    Press release from Vanderbilt University. You can also download the paper (in PDF form) from Dr. Saff's home page, if you think you're smart enough to understand it. (Don't ask me for help. I have two degrees in mathematics and was in over my head by halfway through page 2. I couldn't even make it out of the Introduction.)

  • The Old New Thing

    Tintin goes to the neurologist


    The Canadian Medical Association Journal traditionally runs an offbeat research paper in their Christmas edition, for which there is apparently huge competition. This year, Tintin goes to the neurologist. The feedback is fun to read too. (External news coverage here and here.)

    My first exposure to Tintin was—of course—in Sweden. (Why "of course"? Because it seems that everything I do ties back to Sweden somehow...)

    While browsing through a music store's clearance bin, I found an audio dramatization of Den svarta ön. I recognized "Tintin" as the name of a popular children's character, though I myself had never read any of the stories.

    I started listening to the CD and found the story amazingly dull. However, I chalked this up to my bad Swedish listening comprehension, figuring that if only I understood more of it, the story would be more enjoyable.

    Some months later, I tested this theory: I went to the library, found a copy of The Black Island in English translation, and read it.

    It was an amazingly dull story.

    During my most recent trip to Taiwan, the person I was telling this story to couldn't figure out what children's character I was talking about. We happened to be in a bookstore and I stumbled across a copy of the same story in Chinese translation. (The Chinese translation of Tintin's name is - dīng-dīng, in case anybody else finds themselves in the same jam.) Of course, having found the book, I had to buy it; it's sort of become a collection now. Someday I'll try to read it, but not quite yet. My Chinese is barely at phrase-book level right now.

    It has been pointed out that even though Tintin is ostensibly a journalist, over his 45-year career he filed but one story. You'd think his editor would be kind of upset by now.

    I also have copies of Harry Potter and the Philosopher's Stone in all (but one) of the various languages I know or am trying to learn. And I'm counting the American and British English versions as different. Because they are.

  • The Old New Thing

    Why do I get E_NOINTERFACE when creating an object that supports that interface?


    I've seen a few questions from people who call the CoCreateInstance function, asking for an interface that they know the object supports, yet receiving error E_NOINTERFACE. What's going on?

    You're seeing the same problem as the missing IMarshal, just from the other side.

    If your threading model is incompatible with the threading model of the object you're creating, then COM marshalling kicks in. And if the marshalling stuff isn't there, the error that comes out is E_NOINTERFACE, because the marshalling interface is missing.

    A common source of this is attempting to use COM objects provided by the shell from a multi-threaded apartment. Remember that shell COM objects are, for the most part, apartment-threaded, not free-threaded. If you want to use shell objects, you should do so from single-threaded apartments.

  • The Old New Thing

    Dragging a shell object, part 5: Making somebody else do the heavy lifting


    Creating that drag image was a bit of work. Fortunately, the listview control is willing to do some of the work for you.

    Throw away the OnLButtonDown function (and the HANDLE_MESSAGE that goes with it). Instead, we'll make the listview do all our presentation for us.

    OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
      g_hwndChild = CreateWindow(WC_LISTVIEW, NULL,
                                 WS_CHILD | WS_VISIBLE | LVS_ICON |
                                 LVS_SHAREIMAGELISTS, // flag added 13 Dec
                                 0, 0, 0, 0,
                                 hwnd, (HMENU)1, g_hinst, 0);
      if (!g_hwndChild) return FALSE;
      SHFILEINFOW sfi;
        SHGetFileInfoW(g_pszTarget, 0, &sfi, sizeof(sfi),
                       SHGFI_SYSICONINDEX |
                       SHGFI_DISPLAYNAME | SHGFI_LARGEICON);
      if (!himl) return FALSE;
      ListView_SetImageList(g_hwndChild, himl, LVSIL_NORMAL);
      LVITEM item;
      item.iSubItem = 0;
      item.mask = LVIF_TEXT | LVIF_IMAGE;
      item.pszText = sfi.szDisplayName;
      item.iImage = sfi.iIcon;
      if (ListView_InsertItem(g_hwndChild, &item) < 0)
        return FALSE;
      return TRUE;

    We now let the listview control worry about the icon and its text and all the other UI that goes along with it. And we can make the listview worry about the drag image, too.

    void OnBeginDrag(HWND hwnd, NMLISTVIEW *plv)
      IDataObject *pdto;
      if (SUCCEEDED(GetUIObjectOfFile(hwnd, g_pszTarget,
                       IID_IDataObject, (void**)&pdto))) {
        IDragSourceHelper *pdsh;
        if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL,
                        CLSCTX_ALL, IID_IDragSourceHelper, (void**)&pdsh))) {
          pdsh->InitializeFromWindow(g_hwndChild, &plv->ptAction, pdto);
        IDropSource *pds = new CDropSource();
        if (pds) {
          DWORD dwEffect;
          if (DoDragDrop(pdto, pds, DROPEFFECT_MOVE |
                         DROPEFFECT_COPY | DROPEFFECT_LINK,
                         &dwEffect) == DRAGDROP_S_DROP &&
              (dwEffect & DROPEFFECT_MOVE)) {
    LRESULT OnNotify(HWND hwnd, int idCtrl, NMHDR *pnm)
      if (idCtrl == 1) {
        NMLISTVIEW *plv;
        switch (pnm->code) {
        case LVN_BEGINDRAG:
          plv = (NMLISTVIEW*)pnm;
          OnBeginDrag(hwnd, plv);
      return 0;
        HANDLE_MSG(hwnd, WM_NOTIFY, OnNotify);

    Instead of detecting the drag operation, we let the listview do it and just wait for the LVN_BEGINDRAG notification, at which point we get the data object for the file we want to drag and ask the listview to create the drag image by passing its window handle to the IDragSourceHelper::InitializeFromWindow method.

    The listview control does the work of generating the drag image and setting it into the data object. In our specific case, it may have been a toss-up which way is easier, but if you enable multiple-selection capability in the listview, using the IDragSourceHelper::InitializeFromWindow method is a major savings because the listview will do the work of generating the radial gradient alpha channel that you see when dragging multiple files in Explorer.

    You may notice some color fringes around the icons generated by the listview. That's because we're using version 5 of the common controls, which doesn't support alpha channels very well. If you switch to version 6, you'll find that the fringes are gone and the icon looks a lot prettier.

    That's all for now on the subject of initiating a drag/drop operation. Back to one-day topics for a while.

  • The Old New Thing

    For all your chicken sequencing needs


    The International Chicken Sequencing Consortium announced that it has completed the sequencing of chicken DNA.

    I repeat: There is an organization called "The International Chicken Sequencing Consortium".

    (For some reason I want to think these people get together and decide, "Okay, Ginger goes first, then Bunty, then Babs...")

  • The Old New Thing

    Dragging a shell object, part 4: Adding a prettier drag icon


    You may have noticed that the drag feedback is rather sad-looking. Just a box, maybe with a plus sign or an arrow; you don't even know what it is you're dragging.

    Let's fix that. We'll drag the icon of the file around. We'll need to add the drag image to the data object.

    void OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
      IDataObject *pdto;
      if (SUCCEEDED(GetDataObjectOfFileWithCuteIcon(
                    hwnd, g_pszTarget, &pdto))) {
         IDropSource *pds = new CDropSource();

    This new function GetDataObjectOfFileWithCuteIcon creates the data object and then attaches the cute icon to it.

    HRESULT GetDataObjectOfFileWithCuteIcon(HWND hwnd,
     LPCWSTR pszPath, IDataObject **ppdto)
      HRESULT hr = GetUIObjectOfFile(hwnd, pszPath,
                        IID_IDataObject, (void**)ppdto);
      if (SUCCEEDED(hr)) {
        IDragSourceHelper *pdsh;
        if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_ALL,
                                       IID_IDragSourceHelper, (void**)&pdsh))) {
          SHDRAGIMAGE sdi;
          if (CreateDragImage(pszPath, &sdi)) {
            pdsh->InitializeFromBitmap(&sdi, *ppdto);
      return hr;

    We use the shell drag/drop helper object to attach the bitmap to the data object. The shell drag/drop helper object requires that the data object be able to accept arbitrary blobs, but fortunately, the standard shell data object does this.

    The nasty part is generating the drag image. This is not the fun part, and you're not going to learn anything from this function. It just has to be written.

    BOOL CreateDragImage(LPCWSTR pszPath, SHDRAGIMAGE *psdi)
      psdi->hbmpDragImage = NULL;
      SHFILEINFOW sfi;
        SHGetFileInfoW(pszPath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
      if (himl) {
        int cx, cy;
        ImageList_GetIconSize(himl, &cx, &cy);
        psdi->sizeDragImage.cx = cx;
        psdi->sizeDragImage.cy = cy;
        psdi->ptOffset.x = cx;
        psdi->ptOffset.y = cy;
        psdi->crColorKey = CLR_NONE;
        HDC hdc = CreateCompatibleDC(NULL);
        if (hdc) {
          psdi->hbmpDragImage = CreateBitmap(cx, cy, 1, 32, NULL);
          if (psdi->hbmpDragImage) {
            HBITMAP hbmPrev = SelectBitmap(hdc, psdi->hbmpDragImage);
            ImageList_Draw(himl, sfi.iIcon, hdc, 0, 0, ILD_NORMAL);
            SelectBitmap(hdc, hbmPrev);
      return psdi->hbmpDragImage != NULL;

    To create the drag image, we ask the SHGetFileInfo function to give us the imagelist handle and icon index for the icon that represents the file. The icon size in the imagelist goes into the SHDRAGIMAGE structure as the bitmap dimensions and as the cursor point. (We put the cursor at the bottom right corner of the image.) Since we are creating an alpha-blended bitmap, we don't need a color-key. Finally, we create a memory DC to house an ARGB bitmap into which we draw the icon.

    If you run this program, you should see the icon for a text file being dragged around as you drag your throwaway file around the screen.

    Next time, a way to make somebody else do the heavy lifting for you.

Page 404 of 464 (4,636 items) «402403404405406»