• The Old New Thing

    The wisdom of seve^H^H^H^Hsixth graders: Living without electronics for a week

    • 11 Comments

    Sixth grade students (ages 11 to 12, roughly) were instructed to imagine that they have no television, computer, or telephone for a week and write an essay (in the form of a letter to their parents) on what they would do with their time and why. The assignment was given under standardized test conditions: 90 minutes with nothing but pencil and paper, with an additional hour available upon request. (In practice, few students ask for the extra hour.)

    Remember, these are only the funny sentences/excerpts. Do not assume that all students write like this.

    Stage One: Denial

    • A powerman came to our house and is trying to fix the precios valubles... But don't touch the family jewels.

    Stage Two: Anger

    • Since you have forcefully restricted me from using essenchal, electronics like the TV...

    Stage Three: Bargaining

    (couldn't find an example, sorry)

    Stage Four: Depression

    • My heart is full of grief and sadness, yet I regret nothing but the loss of my precious x-box.
    • Although I am in a mood of melancholy over this gloomy oncoming event, I hope my hobbies will cheer me up. Big words sound bigger.

    Stage Five: Acceptance

    • Since you have grounded me for a week, I need to nurture my growing sense of fun.

    Other excerpts

    • [When working in the barn] 1) don't touch the electric fence 2) don't throw poop
    • Every day, I am getting closer to achieving my goal of attacking my friends. You should see what your friends' goals are.
    • ... Gliding on black ashphault ...
    • I'm going to play legos until my arms hurt. In my experience, your feet hurt first.
    • I have a life outside the digital world!
    • My grade went from a C- to an A-, and that is the second highest you can get! So why not do it for real?
    • After a long day of skating, my legs are battered and crunched, and that just means I had a good day.
    • I have noticed lately that my social level is not up to my standards. Level up?
    • I will draw elaborate scratches of lead all over the blank paper.
    • Inside used to be another word for trapt. Now it translates to party!
    • We have invented a new game. We tie one sister to a post... I'm not sure who the winner of the game is, but I'm pretty sure I know who the loser is.
    • One of my options for an activity is reading. I have noticed a big collection of books on my shelf and a few look quite interesting. How'd those books get there?
    • If there were no phones, I would die, but I would still have fun.
    • Remember, reading is a movie on pages.
    • By going to church, you don't need anything but faith.
    • I would go play behind the agresive looking houses. I prefer passive housing myself.
    • Skydiving I went once it is like diving into a pool you lose your stomache sometimes you find it sometimes you don't. Somehow the run-on sentence makes it more poetic.
    • It is a very relaxful activity.
    • One book I will read is A Purpose Driven Life.

    Any final requests?

    • The last thing I will do is tape toys together and make new toys.
    • The last thing I will do is go bike ridding.
    • The final activity I would do is Africa! Um, you might want to rephrase that.
    • Then, last but not leave, my instruments...

    I'm not resentful. Why do you ask?

    • Sincerely, Your Daughter, the Formerly Loved.

    Observe that many students talked about "the last thing" they would do. This is another consequence of adhering too close to formula. "I have three things, so I will say 'The first thing', 'The next thing', and 'the last thing'." They don't realize that when you write "The last thing I will do", it carries a somewhat different meaning.

    (Today's post is in support of the millions of people currently without electricity due to Hurricane Sandy.)

  • The Old New Thing

    Separating the metadata from the DIB pixels: Precalculating the BITMAPINFO

    • 4 Comments

    Last time, we saw that you can use the SetDIBitsToDevice function to draw a DIB with an alternate color table without having to modify the HBITMAP. In that version of the function, we selected the HBITMAP into a device context in preparation for drawing from it, but in fact that step isn't necessary for drawing. It was merely necessary to get the original color table so we could build our grayscale color table. If you don't care what the original colors are, then you can skip that step. And even if you care what the old colors are, and if you assume that the colors don't change, then you only need to ask once.

    To demonstrate, that all the work of building the BITMAPINFO structure could have been done ahead of time, let's use this alternate version of our program:

    HBITMAP g_hbm;
    struct BITMAPINFO256 {
     BITMAPINFOHEADER bmiHeader;
       RGBQUAD bmiColors[256];
    } g_bmiGray;
    void *g_pvBits;
    
    BOOL
    OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
    {
     // change path as appropriate
     g_hbm = (HBITMAP)LoadImage(g_hinst,
                          TEXT("C:\\Windows\\Gone Fishing.bmp"),
                          IMAGE_BITMAP, 0, 0,
                          LR_CREATEDIBSECTION | LR_LOADFROMFILE);
     if (g_hbm) {
      BITMAP bm;
      if (GetObject(g_hbm, sizeof(bm), &bm) == sizeof(bm) &&
                    bm.bmBits != NULL &&
                    bm.bmPlanes * bm.bmBitsPixel <= 8) {
       ZeroMemory(&g_bmiGray, sizeof(g_bmiGray));
       HDC hdc = CreateCompatibleDC(NULL);
       if (hdc) {
        HBITMAP hbmPrev = SelectBitmap(hdc, g_hbm);
        UINT cColors = GetDIBColorTable(hdc, 0, 256, g_bmiGray.bmiColors);
        for (UINT iColor = 0; iColor < cColors; iColor++) {
         BYTE b = (BYTE)((30 * g_bmiGray.bmiColors[iColor].rgbRed +
                          59 * g_bmiGray.bmiColors[iColor].rgbGreen +
                          11 * g_bmiGray.bmiColors[iColor].rgbBlue) / 100);
         g_bmiGray.bmiColors[iColor].rgbRed   = b;
         g_bmiGray.bmiColors[iColor].rgbGreen = b;
         g_bmiGray.bmiColors[iColor].rgbBlue  = b;
        }
        g_bmiGray.bmiHeader.biSize        = sizeof(g_bmiGray.bmiHeader);
        g_bmiGray.bmiHeader.biWidth       = bm.bmWidth;
        g_bmiGray.bmiHeader.biHeight      = bm.bmHeight;
        g_bmiGray.bmiHeader.biPlanes      = bm.bmPlanes;
        g_bmiGray.bmiHeader.biBitCount    = bm.bmBitsPixel;
        g_bmiGray.bmiHeader.biCompression = BI_RGB;
        g_bmiGray.bmiHeader.biClrUsed     = cColors;
        g_pvBits                          = bm.bmBits;
        DeleteDC(hdc);
       }
     }
     return TRUE;
    }
    
    void
    PaintContent(HWND hwnd, PAINTSTRUCT *pps)
    {
     if (g_pvBits) {
        SetDIBitsToDevice(pps->hdc, 0, 0,
                      g_bmiGray.bmiHeader.biWidth,
                      g_bmiGray.bmiHeader.biHeight, 0, 0,
                      0, g_bmiGray.bmiHeader.biHeight,
                      g_pvBits,
                      (BITMAPINFO*)&g_bmiGray, DIB_RGB_COLORS);
     }
    }
    

    I moved the blue code from PaintContent to OnCreate to demonstrate that pretty much all of the work we used to do in PaintContent could have been done ahead of time. The only other thing we had to do was save the pointer to the bits so we could pass them to SetDIBitsToDevice. (Of course, that pointer becomes invalid once the controlling HBITMAP is destroyed, so be careful! In practice, you probably would be better off calling GetObject immediately before drawing to protect against the case that somebody deleted the bitmap out from under you.)

    Next time, we'll look at another operation we can perform when we have a BITMAPINFO and a collection of pixels.

    (Note that there are issues with this technique which will be taken up on Friday.)

  • The Old New Thing

    Creating context menus on menus

    • 12 Comments

    Last week we looked at menu drag/drop. Another little-used menu feature added in Windows 2000 is the ability to show context menus on menus. The message is WM_MENU­RBUTTON­UP and the flag is TPM_RECURSE. Let's demonstrate with a simple program.

    Start with the scratch program, and add the Move­Menu­Item function just so our context menu can do something.

    // resource header file
    #define IDM_MAIN 1
    #define IDM_POPUP 2
    #define IDC_MOVEUP 200
    #define IDC_MOVEDOWN 201
    
    // resource file
    1 MENU PRELOAD
    BEGIN
        POPUP "&Test"
        BEGIN
            MENUITEM "&Red",    100
            MENUITEM "&Orange", 101
            MENUITEM "&Yellow", 102
            MENUITEM "&Green",  103
            MENUITEM "&Blue",   104
            MENUITEM "&Violet", 105
        END
    END
    
    2 MENU PRELOAD
    BEGIN POPUP ""
        BEGIN
            MENUITEM "Move &Up",   IDC_MOVEUP
            MENUITEM "Move &Down", IDC_MOVEDOWN
            MENUITEM SEPARATOR
            MENUITEM "&Cancel",    IDCANCEL
        END
    END
    
    // scratch.cpp
    #define HANDLE_WM_MENURBUTTONUP(hwnd, wParam, lParam, fn) \
        ((fn)((hwnd), (UINT)(wParam), (HMENU)(lParam)), 0L)
    
    void OnMenuRButtonUp(HWND hwnd, UINT uPos, HMENU hmenu)
    {
     if (hmenu == GetSubMenu(GetMenu(hwnd), 0)) {
      HMENU hmenuPopup = LoadMenu(g_hinst, MAKEINTRESOURCE(IDM_POPUP));
      if (hmenuPopup) {
       if (uPos == 0) {
        EnableMenuItem(hmenuPopup, IDC_MOVEUP, MF_DISABLED | MF_GRAYED);
       }
       if (uPos == GetMenuItemCount(hmenu) - 1) {
        EnableMenuItem(hmenuPopup, IDC_MOVEDOWN, MF_DISABLED | MF_GRAYED);
       }
       DWORD dwPos = GetMessagePos();
       UINT idCmd = TrackPopupMenuEx(GetSubMenu(hmenuPopup, 0),
                     TPM_RECURSE | TPM_RETURNCMD,
                     GET_X_LPARAM(dwPos),
                     GET_Y_LPARAM(dwPos), hwnd, NULL);
       switch (idCmd) {
        case IDC_MOVEUP:
         MoveMenuItem(hmenu, uPos, uPos - 1);
         break;
        case IDC_MOVEDOWN:
         MoveMenuItem(hmenu, uPos, uPos + 2);
         break;
       }
       DestroyMenu(hmenuPopup);
      }
     }
    }
    
        HANDLE_MSG(hwnd, WM_MENURBUTTONUP, OnMenuRButtonUp);
    
    // InitApp function
        wc.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
    

    When we receive the WM_MENU­RBUTTON­UP message and confirm that the menu is the one we support, we create the popup menu and display it at the mouse location (obtained via Get­Message­Pos) with the TPM_RECURSE flag, indicating that this is a pop-up menu for a pop-up menu. (We also use TPM_RETURN­CMD, but that's nothing new.) If the user chose to move the item up or down, we move it up or down.

    That's all. There really isn't much here, but I figured I'd just write a sample program just to show how it's done.

  • The Old New Thing

    2013 Q1 link clearance: Microsoft blogger edition

    • 12 Comments

    It's that time again: Linking to other Microsoft bloggers.

  • The Old New Thing

    Sometimes people can be so helpless: Finding the owner of a Web page

    • 13 Comments

    Internal to Microsoft are thousands of Web sites. This is a story about one of them.

    On an internal discussion list, somebody asked

    We just created a new Flurb. Does anyone know how to get listed on http://internalsite/newflurbs?

    I hadn't heard of that site before, but I checked it out. Neat, it's basically a blog which announces new Flurbs. I can see how somebody would want their Flurb to be listed there. I also saw lots of pieces of information on the page which the person appears not to have noticed. I replied,

    Um, how about the Email link in the navigation bar? Or did you try that and it didn't work?

    Also, each entry has the same name at the bottom. You could try contacting that person.

    Just giving you some ideas on problem-solving techniques.

    Pre-emptive snarky comment: "Hey, Raymond, where's your contact link?" I was forced to disable the contact link some time ago because it was being used primarily to send spam. Finding my email address is left as an exercise. (It's not hard.)

  • The Old New Thing

    We accept cash, credit cards, and Microsoft cardkeys

    • 11 Comments

    One of the restaurants that opened at the new Microsoft Commons is Spitfire, which opened under its own name instead of one of the many wonderful alternatives proposed. At The Commons, the dining establishments operate in a variety of ways (cafeteria, buffet, fast casual, deli, etc.) but they share the common characteristic that you pay for your meal before you sit down to eat, and you clear your own table when you're done. In other words, it's a giant upscale food court spread out over two buildings.

    Except for Spitfire, which has its own building and operates as a sit-down restaurant with table service.

    One thing that I still can't get over is that you can pay for your lunch at Spitfire with your Microsoft cardkey. That somehow just seems wrong.

    (This week is Share Our Strength's Great American Dine Out. Dine out at a participating restaurant and support efforts to help children at risk of hunger in the United States.)

  • The Old New Thing

    Whether your application should display its content in RTL should be based on the content

    • 15 Comments

    A customer had the following puzzle:

    We have a small bootstrapper application that consists of a dialog box and a few message boxes. The problem is that we want our application to work properly on Arabic and Hebrew systems, and we can't come up with a good way to determine text direction of the underlying system. We found this article by Michael Kaplan that tells us how not to do it, which is great, but what's the recommended way of actually doing it?

    You already know whether you should be displaying your application's UI in LTR or RTL: If this is the Arabic-localized or Hebrew-localized version of your application, then display it as RTL. If this is the English-localized or French-localized version, then display it as LTR.

    There's no point in trying to display your English-language strings in RTL just because the underlying operating system is Arabic. If your strings are in English, then display them in the way they should look to an English speaker. A dialog box like this helps nobody:

    ...Please wait ×
    ,(Preparing setup (50% complete
    .your patience is appreciated

    When your localization team translates the application into Arabic, they can insert two copies of U+200E (LEFT-TO-RIGHT MARK) at the start of the File­Description in the version resource. That is the signal to Windows that the application should have RTL as its default layout direction.

    If you want your application to choose a language dynamically (say, to use English strings if running on an English system but Arabic strings if running on an Arabic system), then you can add a flag in your resources so that the localizers can indicate whether a particular language pack expects text to run left-to-right or right-to-left.

    IDS_LANGUAGE_DIRECTION "LTR" // change to RTL if localized in Arabic, etc.
    

    Your application could then check the direction and call Set­Process­Default­Layout based on the result.

  • The Old New Thing

    2012 års Gävlebock gick upp i brand. Igen.

    • 15 Comments

    The town of Gävle in Sweden erects a large straw goat every year. The Yule Goat is a Scandinavian tradition, but the Gävle goat (Gävlebocken in Swedish) is by far the most famous, or perhaps the most notorious, because it has been the center of conflict from its very beginning, and over the years since its first appearance in 1966, it has only gained more notoriety. (For something that is supposed to bring people together, it sure does a good job of dividing them.)

    The first conflict is between those who want the goat to last the entire season and those who want it to be lit on fire. (And anecdotal evidence suggests that a large number of Swedes are in the second category.) It is such a big deal that you can place bets on whether the goat will survive or what day it will succumb to flames.

    The second conflict is between the Southern Merchants organization, who built the Yule Goat in its initial years but gave up out of frustration over the repeated arson, and the Natural Science Club (Natur­veten­skap­liga För­ening­en) of the School of Vasa, who took up the tradition, even though their goats didn't fare much better. The Southern Merchants resumed constructing a Yule Goat, leading to a bitter rivalry between the two groups.

    Wikipedia has a rundown of the goat's fate every year since its inception, including its burning in 2001 by a tourist from the United States who claims that he intended only to burn one piece of straw but was unable to stop the spread of the flames. (The article in Afton­bladet is far more insightful than any of the other reports I've seen, despite the fact that Afton­bladet is a tabloid. Unfortunately, as far as I can tell, the article is available only in Swedish.)

    The Gävle goat blogs and tweets in both Swedish and English.

    And for those keeping score: On the evening of December 12, the 2012 Yule Goat of Gävle went up in flames.

    Ursprunglig titel: "Den 2012 Gävlebocken gick upp i brand. Igen." Korrigerad efter kommentar från BOFH. Jag var så orolig om jag skulle använda "upp i brand" eller "upp i eld" att jag förbisåg andra fel... Tack.

  • The Old New Thing

    Microspeak: Take-away

    • 22 Comments

    At Microsoft, the take-away is the essential message of a presentation or the conclusion that you are expected to draw from a situation. It is something you are expected to remember when the whole thing is over, a piece of information you take away with you as you leave the room.

    XYZ demo take away (title of a document)

    The preferred intensifier is key, and you probably see it attached to the phrase take-away more often than not. This example comes from a presentation on the results of a user study:

    Results: XYZ Tough to Use
    • ...
    • Key take-away:
      • Migration to XYZ will be difficult
      • Need to show value of using the power of DEF

    In fact, every single slide in this presentation had a bullet point at the bottom called Key take-away. (And, as you may have noticed, the heading is the singular take-away even though multiple take-aways were listed.)

    Another use of the term take-away follows in the same spirit as the "essential message" usage, but the idea of "taking away" is taken literally: A take-away is a small information card that sales and marketing people give to potential customers. Think of it as the business card for a service rather than for a person.

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

  • The Old New Thing

    Psychic debugging: Why your IContextMenu::InvokeCommand never gets called

    • 12 Comments

    A customer reported a problem with their shell context menu extension.

    I have implemented the IContext­Menu shell extension, but when the user selects my custom menu item, my IContext­Menu::Invoke­Command is never called. Can anyone please let me know what the problem could be and how to fix it?

    Since there really isn't much information provided in this request, I was forced to invoke my psychic powers. Actually, given what you know about shell context menu hosting, you probably know the answer too.

    My psychic powers tell me that you gave your menu item the wrong ID, or you returned the wrong value from IContext­Menu::Query­Context­Menu.

    If the menu IDs do not lie in the range you described by the return value from IContext­Menu::Query­Context­Menu, then when the user chooses the menu item, the item ID will not map to your shell extension. In our sample composite context menu, observe that CComposite­Context­Menu::Reduce­Ordinal relies on the component context menu handlers putting their menu IDs in the range idCmd­First through idCmd­First - return_value - 1. If the two don't line up, then CComposite­Context­Menu::Reduce­Ordinal won't realize that the menu item the user selected corresponds to you.

    We never did hear back from the customer, so the world may never know whether my psychic prediction was correct.

    Bonus chatter: When possible, use a static verb registration instead of an IContext­Menu handler. They are much simpler to implement while still providing a good amount of expressive power.

    You can provide additional information in your registration to control things like the conditions under which your verb should be shown. You can even register cascading submenus statically.

Page 382 of 419 (4,184 items) «380381382383384»