• The Old New Thing

    How do you detect "Large Fonts"?

    • 58 Comments

    When people ask, "How do I detect Large Fonts", they aren't really asking how to detect Large Fonts specifically. Rather, Large Fonts is just the most common manifestation of "unusual DPI".

    Windows uses a nominal DPI of 96 pixels per inch. In other words, if Windows wants to draw a line that is one inch long, it draws 96 pixels. Of course, the physical length of this line depends on your screen resolution and the size of your monitor. The value of 96 is merely nominal.

    You can change this DPI setting from the Display control panel, either by choosing Large Fonts, or by choosing a custom font size. Standard size is 96DPI. Large is 120DPI. Custom is, well, custom.

    DPI higher than 96 will become more and more prevalent as LCD technology improves.

    Programs can query the DPI setting by asking GetDeviceCaps for the LOGPIXELSX of the screen DC.

    int GetScreenDPI()
    {
      HDC hdcScreen = GetDC(NULL);
      int iDPI = -1; // assume failure
      if (hdcScreen) {
        iDPI = GetDeviceCaps(hdcScreen, LOGPIXELSX);
        ReleaseDC(NULL, hdcScreen);
      }
      return iDPI;
    }
    

    The code above assumes that pixels are square, which is true of most modern devices. (You can choose an odd screen resolution and get non-square pixels, but most people avoid such resolutions.) Back in the old days, there were many devices with non-square pixels. For example, the EGA video adapter had pixels which were 1.33 times as tall as they were wide.

    For nonsquare-pixel devices, the values of the LOGPIXELSX and LOGPIXELSY metrics will be different. On an EGA, if the value of the LOGPIXELSX metric were 96, then the LOGPIXELSY metric would be 72, since there are only 72 vertical pixels per inch. Similarly, the ASPECTX, ASPECTY and ASPECTXY values for nonsquare-pixel devices will be somewhat interesting as well, as this diagram demonstrates:

    36 27 45

    The ASPECTX is 27 and the ASPECTY is 36, representing the 4:3 ratio of vertical to horizontal, and the ASPECTXY is 45, representing the hypotenuse.

  • The Old New Thing

    There are two things you can do if you have a mad crush on a boy

    • 3 Comments

    And Eric Lippert finds out what they are.

  • The Old New Thing

    Watch out for those sample URLs

    • 29 Comments

    When writing documentation, one often has need to come up with a sample URL to illustrate some point or other. When you do, make sure the sample URL is under your control.

    I remember a Windows beta that used the sample URL http://www.xxxxx.com/ in a dialog box. You can imagine where that actually goes.

    This web site uses www.wallyworld.com as a sample URL. Perhaps they didn't realize that it's a gay porn site.

    (Raymond's strange dream story: One night I dreamt that I found a web site that had a complete Dilbert archive, and for some reason the name of the site was "Wally World". In the morning, I checked out the site and was in for a big surprise...)

    So play it safe. When you need a sample URL, don't just make something up. If you do, odds are good that somebody is going to rush in and register it. Make your sample URLs point back to your company's home page, or use http://www.example.com, which the IANA has reserved for use in sample URLs. If that's too dorky, you can always go out and register the domain you want to use as your sample, so that nobody else can sneak in and steal it. (This does have the problem of incurring renewal fees.)

  • The Old New Thing

    Positioned vs. non-positioned listview views

    • 7 Comments

    Occasionally, I'll see a question that betrays a lack of understanding of difference between the positioned and non-positioned listview views. The question usually goes along the lines of "I inserted an item with LVM_INSERTITEM but it went to the end of the list instead of in the location I inserted it."

    To understand what is going on, you need to know that some listview views are "positioned" and others are "non-positioned".

    "(Large) icon view", "small icon view", and "tile view" are positioned views. Each item carries its own coordinates, which you can customize via LVM_SETITEMPOSITION. When a new item is inserted, it gets an item index based on the insertion point, but its physical location on the screen is the first available space not already occupied by another item. Existing items are not moved around to make room for the inserted item.

    The other views, "list view" and "report (aka details) view", are non-positioned views. In these views, items do not get to choose their positions. Instead, the position of an item is determined by its item index. In non-positioned views, inserting or deleting an item will indeed cause all subsequent items to shift.

    Now you can answer the question. Why did the item go to the end of the list instead of at the position the caller inserted it?

  • The Old New Thing

    Welcoming a new era in Swiss army knives

    • 18 Comments

    Victorinox, the company authorized to make so-called Swiss Army merchandise, has run into a bit of a problem: Is there anything else you could possibly think of putting on a pocketknife for an outdoorsman? And even if you did, there's no room for it. The pocketknife has already reached the point where it's too unwieldy to carry around in your pocket any more.

    So they decided to think outside the box.

    First, they let go of the "must fit in your pocket" concept. Welcome the Victorinox Swiss Champ XXLT. Check out the picture of the knife in its display box. The knife is as thick as it is long!

    Second, they let go of the whole "things for the outdoorsman" concept. Now you can get the Swiss Army Knife USB Drive and the Swiss Army Knife CyberTool.

    Swiss Army Knife. For the geek in your life. Embrace it.

  • The Old New Thing

    How does Add/Remove Programs get the size and other information?

    • 120 Comments

    If the program doesn't provide this information itself, Add/Remove Programs is forced to guess.

    The problem is that there is no "obvious" way to map an entry in the Add/Remove Programs list to an actual program. Each entry in the list, for those who care about such things, comes from the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall registry key. The only mandatory properties for an uninstallable program are the DisplayName and the UninstallPath. Everything else is optional.

    Let's suppose Add/Remove Programs is given a program registration like this:

    HKEY_LOCAL_MACHINE\
     Software\
      Microsoft\
       Windows\
        CurrentVersion\
         Uninstall\
          SomeProgram
           DisplayName=REG_SZ:"Awesome Program for Windows"
           UninstallPath=REG_SZ:"C:\WINDOWS\uninstall.exe -SomeParameters"
    

    In order to get the "Last Used" and "Frequency" values, Add/Remove Programs needs to know the name of the EXE so it can ask the Start menu "Hey, how often did the user run this program, and when was the last time it happened?"

    Notice that there are no clues in the registration above as to the identity of this EXE file.

    So Add/Remove Programs starts guessing. It goes through all the programs on your Start menu and compares their names with the display name of the uninstallable item. It looks for Start menu items which share at least two words with the words in the DisplayName.

    For example, if there were a Start menu item called "Pretty Decent Windows Program", this would count as a two-word match ("Windows" and "Program").

    It then takes the one with the most matches and decides, "Okay, I guess this is it." Suppose for the sake of illustration that the best match is indeed "Pretty Decent Windows Program.lnk", which is a shortcut to "C:\Program Files\LitWare\Decent Program\Decent.exe". Add/Remove Programs would decide that "Awesome Program for Windows" should get the icon for "Pretty Decent Windows Program.lnk", that the frequency of use and most-recently-used information for "C:\Program Files\LitWare\Decent Program\Decent.exe" will be displayed for "Awesome Program for Windows".

    But wait, there's more. There's also the program size. Add/Remove Programs looks in your "Program Files" directory for directories whose names share at least two words in common with the DisplayName. The best match is assumed to be the directory that the program files are installed into. The sizes are added together and reported as the size of "Awesome Program for Windows".

    A program can add some properties to its registration to avoid a lot of this guessing. It can set an EstimatedSize property to avoid making Add/Remove Programs guess how big the program is. It can also set a DisplayIcon property to specify which icon to show for the program in the list.

    But if a program omits all of these hints, the guess that Add/Remove Programs ends up making can often be ridiculously wide of the mark due to coincidental word matches. In my experience, Spanish suffers particularly badly from this algorithm, due to that language's heavy use of prepositions and articles (which result in a lot of false matches).

    Yes, this is all lame, but when you are forced to operate with inadequate information, lame is the best you can do.

    [July 15 2004: Emphasizing that this is done only if the program fails to provide the information itself. For some reason, a lot of people who link to this page fail to notice that little detail.]

  • The Old New Thing

    Why does icon text get a solid background if drop shadows are disabled?

    • 49 Comments

    A commenter asks why icon label have "those ugly color boxes" when there is a background image.

    The answer: Because the alternative would be worse.

    Imagine if there were no solid background between the text and the background image. You would end up with text against an unpredictable background, which doesn't help readability.

    Take the default background for Windows XP: There are some places that are very light and other places that are very dark. No matter what color you pick for the icon text, it will look bad in one or the other place. If you decide to use white, then the text becomes unreadable in the clouds. If you decide to use black, then the text becomes unreadable in the shadows.

    You lose either way.

    The solution is to intercede a contrasting color to ensure that the text is readable. If your video card is powerful enough, the contrasting color is used only just around the strokes of text themselves, which lends a shadow-effect. If shadows are not enabled, then a solid block of contrast is used.

    (And for those of you who say, "Use white in the dark places and black in the light places," what if there is a section of the wallpaper that has a dark area right next to a light area, and the text covers both?)

  • The Old New Thing

    Lighting organic material and sucking it into your lungs

    • 29 Comments

    Last year, The Philip Morris Companies renamed itself to the warm-and-fuzzy sounding Altria Group. Gotta love the colorful abstract logo they've got. (Psst, editors of the Altria home page: It's "Whom We Fund". "Whom" with an "m".)

    They claim the name comes from the Latin altus ("high") but that doesn't explain where the "r" comes from. Any similarity to "altruism" is purely unintentional, I am certain. Would a tobacco company lie to me? Or, As Business 2.0 put it, "[The renamed company] does not, however, stop producing tobacco, which does not stop causing cancer."

    Plus of course there's the matter that there is already a company called Altria Healthcare, which was none too pleased that a cigarette company decided to choose a name that matched theirs. But a Philip Morris spokesperson said that there is no conflict, pointing out that it is okay for companies to share the same name as long as they are in different fields of business, and "In our case that's not an issue. We're in very different lines of business."

    Because Altria Healthcare's job is to help people improve their health.

    Anyway, I was reminded of their 1995 recall of 8 billion cigarettes out of concern that their customers may become sick because the cigarettes allegedly contained the chemical methyl isothiocyanate (MITC). The Centers for Disease Control and Prevention investigated this problem and concluded that while it was true that the recalled cigarettes contained MITC, so too did cigarettes manufactured both before and after the recall, as well as cigarettes by other manufacturers. In other words, there was nothing wrong with those cigarettes.

    Well, aside from the fact that they are cigarettes.

    Michael Eriksen, chairman of the CDC's Office on Smoking and Health noted that the real problem is "lighting organic material and sucking it into your lungs". Somehow this way of describing smoking struck me as elegantly dry.

  • The Old New Thing

    Obtaining a window's size and position while it is minimized

    • 14 Comments

    If you have a minimized window and want to know where it will go when you restore it, the GetWindowPlacement function will tell you. In particular, the rcNormalPosition tells you where the window would go if it were restored (as opposed to minimized or maximized).

    One perhaps-non-obvious flag is WPF_RESTORETOMAXIMIZED. This flag indicates that the window is currently minimized, but if the user selects "Restore", it will restore to its maximized instead of restored state. (This may seem strange, but you see it every day without even realizing. Take a window and maximize it. Now minimize it. Now click the taskbar button to re-open the window. Notice that it returns to its maximized state, not to its restored state. Imagine how frustrated you would be if it returned to its restored state instead. You'd have to keep re-maximizing the window.)

    The GetWindowPlacement and SetWindowPlacement functions are typically used by programs that wish to save/restore window positioning information across runs.

    You should also be aware that the coordinate system for window placement is not screen coordinates, but rather workspace coordinates. The consequence of getting this wrong is that your window creeps up (or to the left) over time, eventually getting itself stuck underneath the taskbar.
  • The Old New Thing

    Differences between managers and programmers, part 2

    • 29 Comments

    If you are attending a presentation, you can tell whether the person at the lectern is a manager or a programmer by looking at their PowerPoint presentation.

    If it's black-and-white, all-text, multimedia-free, and rarely has more than ten bullet points on a page, then the presenter is probably a programmer.

    If it's colorful, with graphics, animation, and pages crammed with information bordering on illegibility, then the presenter is probably a manager.

    It's fun watching a manager try to rewind their presentation to a particular page. As you step over pages, you still have to sit through the animations, which means that instead of "hit space five times" to go forward five pages, you have to "hit space fifteen times, waiting three seconds between each press of the spacebar" because each page has three animations which you must sit through and experience again.

Page 380 of 425 (4,250 items) «378379380381382»