• The Old New Thing

    Please hold your head perfectly still while you write up that memo

    • 6 Comments

    I dreamed that the original Volkswagen Beetle factory was so cramped that the office workers had to move their desks to the factory floor, with heavy equipment swinging around just inches from their faces. To prevent serious injuries, a template passed through every so often to make sure nothing was out of place.

  • The Old New Thing

    Microspeak: Offline (noun)

    • 20 Comments

    Sure, any noun can be verbed, and any verb can be nouned. But today, we're going to noun an adjective.

    I have no written citations of this usage; the only report was via a colleague who overheard it in a hallway conversion.

    I had some offlines with Fred about that.

    In Microspeak, offline is an adjective which means "outside this meeting." In order to keep a meeting on track, the meeting organizer may advise the people engaged in the discussion of a side topic or a topic of limited interest to take it offline, please, meaning discuss this amongst yourselves after the meeting, please. In other words, "Let's not waste valuable meeting time on this topic."

    The above citation converts the adjective offline into a noun, an offline presumably being shorthand for an offline conversation (or other type of communication). The translation would therefore be something like "I had some private conversations with Fred about that."

  • The Old New Thing

    PLAY! A Video Game Symphony comes to Seattle

    • 18 Comments

    Competing with the Miss America pageant for your Saturday evening attention is the Seattle performance of PLAY! A Video Game Symphony, featuring music from a large number of video games. Presumably, the music will have something to do with the accompanying video being projected on large screens.

    The description of the concert omits any mention of whether this is a cosplay event. Just saying.

  • The Old New Thing

    When should I use the FIND_FIRST_EX_LARGE_FETCH flag to FindFirstFileEx?

    • 14 Comments

    Windows 7 introduces a new flag to the Find­First­File­Ex function called FIND_FIRST_EX_LARGE_FETCH. The documentation says that it "uses a larger buffer for directory queries, which can increase performance of the find operation." This is classic MSDN-style normative documentation: It provides "just the facts". Far be it for MSDN to tell you how to write your application; the job of function-level documentation is to document the function. If you want advice, go see a therapist.

    If the reason why you're calling Find­First­File­Ex is to enumerate through the entire directory and look at every entry, then a large buffer is a good thing because it reduces the number of round trips to the underlying medium. If the underlying medium is a network drive halfway around the world, the latency will be high, and reducing the number of calls reduces the overall cost of communication. Another case where you have high latency is if you are enumerating from an optical drive, since those tend to be slow to cough up data, and once you get the medium spinning, you want to get all the information you can before the drive spins the medium back down. On the other hand, if your underlying medium has low latency, then there isn't much benefit to using a large buffer, and it can be a detriment if the channel is low bandwidth, because transferring that large buffer will take a long time, which can result in long pauses on your UI thread.

    But what if you aren't enumerating with the purpose of reading the entire contents but rather are going to abandon the enumeration once you get the answer to your question? For example, maybe your function wants to enumerate the directory to see if it contains more than ten files. Once the tenth call to Find­Next­File succeeds, you're going to abandon the enumeration. In this case, a large buffer means that the underlying medium is going to do work that you will end up throwing away.

    Here's the above discussion summarized in a table, since people seem to like tables so much.

    Scenario Use FIND_FIRST_EX_LARGE_FETCH?
    Enumerating entire directory on UI thread No¹
    on background thread Yes
    Abandoning enumeration prematurely No

    ¹Actually, if you're on a UI thread, you should try to avoid any directory enumeration at all.

  • The Old New Thing

    Why is my icon being drawn at the wrong size when I call DrawIcon?

    • 6 Comments

    Some time ago I had a problem with icon drawing. When I tried to draw an icon with Draw­Icon it ended up being drawn at the wrong size. A call to Get­Icon­Info confirmed that the icon was 48×48, but it drew at 32×32.

    The answer is documented in a backwards sort of way in the Draw­Icon­Ex function, which says at the bottom,

    To duplicate DrawIcon (hDC, X, Y, hIcon), call DrawIconEx as follows:

    DrawIconEx (hDC, X, Y, hIcon, 0, 0, 0, NULL,
                DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE); 
    

    Aha, if you use Draw­Icon, then the icon size is ignored and it is drawn with DI_DEFAULT­SIZE.

    The fix, therefore, was to switch to the Draw­Icon­Ex function so I could remove the DI_DEFAULT­SIZE flag, thereby permitting the icon to be drawn at its actual size.

    - DrawIcon(hdc, pt.x, pt.y, hico);
    + DrawIconEx(hdc, pt.x, pt.y, hico, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
    

    A bonus quirk of the DI_DEFAULT­SIZE flag (and therefore of the Draw­Icon function) is that the drawing is done at the default icon size, even if you asked it to draw a cursor.

  • The Old New Thing

    Isn't the Learning Annex for total losers?

    • 2 Comments

    Marketplace's Cash Peters pays a visit to The Learning Annex, home to classes like Bending Spoons with Your Mind and Lap-Dancing 101. But he signs up for How to be a TV producer. Listen to the story and you can save yourself twenty bucks.

  • The Old New Thing

    The MARGINS parameter to the DwmExtendFrameIntoClientArea function controls how far the frame extends into the client area

    • 8 Comments

    A customer wrote a program that calls Dwm­Extend­Frame­Into­Client­Area to extend the frame over the entire client area, but then discovered that this made programming difficult:

    I have a window which I want to have a glassy border but an opaque body. I made my entire window transparent by calling Dwm­Extend­Frame­Into­Client­Area, and I understand that this means that I am now responsible for managing the alpha channel when drawing so that the body of my window remains opaque while the glassy border is transparent. Since most GDI functions are not alpha-aware, this management is frustrating. Is there a better way? In pictures, I only want the red portion of the diagram below to be on glass; the inside yellow part should be opaque like normal. Is there an API that can do this?

    This customer's excitement about the glass frame is like somebody who buys a pallet of tangerine juice even though he only wanted two glasses. And now he has questions about how to store the rest of the tangerine juice he didn't want.

    This customer, it appears, passed −1 as the MARGINS to Dwm­Extend­Frame­Into­Client­Area which means "Bring it on, baby! Give me all tangerine all the time everywhere!" If you only want the glass to extend into part of your client area, then say so. Set the MARGINS to the thickness of the glass border (the thickness of the red portion of the above diagram).

  • The Old New Thing

    Why was HDS_FILTERBAR added to the common controls if nobody uses it?

    • 19 Comments

    Mike Dunn was curious about the intended purpose of HDS_FILTERBAR.

    The HDS_FILTERBAR style adds a row below the header control consisting of an edit control and a funnel icon. The funnel icon presumably represents a coffee filter, because after all, everybody in the world drinks coffee as much as people in Seattle. (Developers think they're so clever.)

    Mike points out that new features of the common controls were nearly always used by whatever version of Windows or Internet Explorer shipped that new version. The HDS_FILTERBAR style is a notable exception. What happened?

    I believe the HDS_FILTERBAR feature was originally intended for use by Active Directory; my guess is that dialogs like Find Computer would have taken advantage of it. For whatever reason, that feature was cut from Active Directory, which is why you didn't see anybody using it. However, the feature was cut after the code for the feature was already written and checked into the common controls under the style HDS_FILTERBAR.

    The Active Directory team either forgot to tell the Common Controls team, "Hey, you know that feature we asked you to write for us? Yeah, we don't need it after all," or they did, and the Common Controls team said, "Well, we already wrote it, and we don't want to take the risk that removing it won't introduce a bug, so we'll just leave it in. Maybe somebody else can find a use for it."

    The result was a feature in the header control that nobody used. And since nobody used it, I wouldn't be surprised if it's a little buggy. (We already know that it's more than little ugly.)

  • The Old New Thing

    What's the story behind the WM_SYNCPAINT message?

    • 11 Comments

    Danail wants to know the story behind the WM_SYNC­PAINT message.

    The documentation pretty much tells the story. When a window has been hidden, shown, moved or sized, the system may determine that it needs to send a WM_SYNC­PAINT message to the windows of other threads. This message must be passed to Def­Window­Proc, which will send the WM_NCPAINT and WM_ERASE­BKGND messages to the window as necessary.

    When you call the Set­Window­Pos function, the window manager updates the window size, position, whatever, and then it goes around repainting the windows that were affected by the operation. By default, the Set­Window­Pos function does a quick-repaint of the windows before returning. After the function returns, the normal WM_PAINT message does the real work of painting the window. The quick-repaint is done so that there is immediate feedback that the window did change its size, position, whatever.

    This quick-repaint is done by sending a WM_NCPAINT and WM_ERASE­BKGND message to the windows that were affected by the Set­Window­Pos operation. This normally happens without incident, but if one of the windows affected by the Set­Window­Pos operation belongs to another thread, the window manager needs to get into the context of that other thread to finish the job. That's where WM_SYNC­PAINT comes in. The WM_SYNC­PAINT message means, "Hey, I was going around quick-painting a bunch of windows, but I couldn't quick-paint you (or any other windows on your thread) because I was on the wrong thread. Could you finish quick-painting yourself (and all the other windows that need quick-painting)? Thanks."

    Another way of looking at this is that it is a way for the window manager to teleport itself into another thread so it can finish its work. "Lah di dah, quick-painting all the windows, oh crap, I can't quick-paint that window because it's on the wrong thread. Let me inject myself into that other process [trivial, since I'm the window manager, I'M IN YR PROCESS REEDING YR MSGS], and now I can send a message to myself [WM_SYNCPAINT], and when that other copy of me receives it, he'll finish where I left off."

    If you don't like any of this teleportation or multiple-copies-of-yourself imagery, you can say that the WM_SYNC­PAINT message means, "Quick-paint this window as part of a quick-paint operation begun on another thread."

    If you don't want this quick-paint to take place, you can follow the instructions in the documentation and pass the SWP_DEFER­ERASE flag to suppress the WM_SYNC­PAINT message.

  • The Old New Thing

    Raymond rewrites newspaper headlines

    • 13 Comments

    Original headline: Monorail out of service this week.

    Raymond's headline: Monorail out of service this week: 4 people inconvenienced.

Page 371 of 453 (4,523 items) «369370371372373»