May, 2011

  • The Old New Thing

    Sorting is a state and a verb (and a floor wax and a dessert topping)


    Cliff Barbier points out that after you sort an Explorer view by name, new items are not inserted in their sorted position. This goes back to the question of whether sorting is a state or a verb.

    If you take an Explorer folder and say Sort by Name, do you mean "From now on, always show the contents of this folder sorted by name"? Or do you mean "Rearrange the items currently in this folder so they are sorted by name"? The first case treats sorting a state, where sorting is an attribute of the folder that persists. The second case treats sorting as a verb, where the action is performed so that its effects linger but the action itself is not remembered.

    You might think that sorting is obviously a state, but STL disagrees with you:

    std::vector<Item> v;
    ... fill v with stuff ...
    std::sort(v.begin(), v.end(), Item::ByName);

    When the last line of code appends a new item to the vector, it is not inserted in sorted order because std::sort is a verb which acts on the vector, not a state of the vector itself. The vector doesn't know "Oh, wait, I'm now a sorted vector."

    Okay, so in Explorer, is sorting a state or a verb?

    "Let's do both!"

    Sorting is a state, in the sense that the list of items is presented in sorted order when the folder is first opened. It's a verb in that the sorted order is not maintained when new items are added to the view while the folder is already open.

    Placing new items at the end instead of in their sorted position is necessary to avoid having items move around unbidden. Suppose you're looking at a folder sorted by name, you scroll down the list, find the item you want, and just as your finger is posed to click the mouse button, another process creates a file in the folder, which Explorer picks up and inserts into the view, causing the items to shift, and when your finger goes down on the mouse button, you end up clicking on the wrong item.

    You can imagine how annoying this can end up when there is a lot of file creation activity in the folder. If the items in the view were continuously sorted, then they would keep moving around and make it impossible to click on anything!

    Mind you, you do have this instability problem when files are deleted and you are in a non-placed view (like List or Details), but there's at least a cap on how much trouble deletion can cause (since eventually you delete all the items that were in the view originally).

    It looks like starting in Windows Vista, Explorer tries to insert new items into their sorted position, so at least in the modern versions of Windows, sort is a state. Good luck trying to click on something when the contents of the folder are constantly changing.

  • The Old New Thing

    Like a chicken talking to a duck


    Many years ago, I called the home of my Chinese-speaking nieces. This was before they started learning English and before I started learning their dialect of Chinese. After the call was over, the eldest niece asked, "Who was that on the phone?"

    "That was Uncle Raymond."

    "Oh, I want to talk to Uncle Raymond!"

    Her mother replied, "That'd be like a chicken talking to a duck."

    A chicken talking to a duck is a Chinese idiom referring to two people who cannot communicate due to a language barrier.

    It seems that ducks are somehow central to the concept of language unintelligibility. Is there a duck-related language idiom in your language?

  • The Old New Thing

    Just for fun: Sample user names in Windows 7


    There are a few places in Windows where you are asked to enter your name in order to set up an account. Just for fun, I went through all the localized versions I could find and extracted the sample names. Some locales did not get around to translating all the strings. If the string was left untranslated (which can happen for LIPs), then I left the box blank. (Locales which did not translate either string have been omitted from the table.)

    My reactions after the table.

    ID English name for example, John For example: John Smith
    af-za Afrikaans byvoorbeeld, John Voorbeeld: Jan Smit
    am-et Amharic ለምሳሌ: አበበ ከበደ
    ar-sa Arabic على سبيل المثال، أمجد على سبيل المثال: أشرف ماهر
    as-in Assamese উদাহৰণৰ কাৰণে, প্ৰবিন উদাহৰণ স্বৰূপে: জন স্মিথ
    az-latn-az Azerbaijani məsələn, Fərhad Məsələn: Vüsal Tahirov
    bg-bg Bulgarian например Kiril Например: Пламен Христов
    bn-bd Bengali (Bangladesh) উদাহরণস্বরূপ, জন উদাহরণস্বরূপ: জন স্মিথ
    bn-in Bengali (India) উদাহরণস্বরূপ, রাম উদাহরণস্বরূপ: জন স্মিথ
    bs-cyrl-ba Bosnian (Cyrillic) напримјер John Напримјер: Алмир Алмировић
    bs-latn-ba Bosnian (Latin) naprimjer John Naprimjer: Almir Almirović
    ca-es Catalan per exemple, Jordi Per exemple: Pau Solà
    cs-cz Czech například Tereza Příklad: Jan Novák
    cy-gb Welsh Siôn, er enghraifft Er enghraifft: Siân Jones
    da-dk Danish f.eks. Claus Eksempel: Jens Jensen
    de-de German N/A Beispiel: Jens Mander
    el-gr Greek για παράδειγμα, Γιάννης Για παράδειγμα: Γεώργιος Βασιλείου
    en-us English for example, John For example: John Smith
    es-es Spanish por ejemplo, Juan Por ejemplo: Jorge López
    et-ee Estonian näiteks Jaan Näiteks: Mati Kask
    eu-es Basque esaterako, Rafa Adibidez: Ane Lizarralde
    fa-ir Persian برای مثال، John
    fi-fi Finnish esimerkiksi Juha Esimerkki: Henri Rautiainen
    fil-ph Filipino halimbawa, Juan Halimbawa: Juan dela Cruz
    fr-fr French par exemple Rosalie Par exemple : Marie Dubois
    ga-ie Irish mar shampla, Seán Mar shampla: Seán Ó Murchú
    gl-es Galician por exemplo: Xiana Por exemplo: Duarte Vidal
    gu-in Gujarati ઉદાહરણ તરીકે, કમલેશ ઉદાહરણ તરીકે: કમલેશ દવે
    ha-latn-ng Hausa A misali:John Smith
    he-il Hebrew לדוגמה, John לדוגמה: משה כהן
    hi-in Hindi उदाहरण के लिए, अमित उदाहरण के लिए: जनमेजय सिंह सिकरवार
    hr-hr Croatian na primjer, Zdenko Primjerice: Ivan Kovač
    hu-hu Hungarian például Lilian Például: Tót Béla
    hy-am Armenian օրինակ՝ Արամ Օրինակ. Արմեն Արմենյան
    id-id Indonesian misalnya, John Misalnya: John Smith
    ig-ng Igbo iji maatụ, Chukwubike-ụgbaja Ọmụmatụ̀: Ụgbaja Chukwubuike Greg
    is-is Icelandic til dæmis Jón Dæmi: Jón Jónsson
    it-it Italian ad esempio, Luca Ad esempio: Valeria Dal Monte
    iu-latn-ca Inuktitut Suurlu: John Smith
    ja-jp Japanese 例: John 例: Taro Chofu
    ka-ge Georgian მაგ. Nino მაგალითად: დიმიტრი გოგელია
    kk-kz Kazakh мысалы, Джон Мысалы: Аманбайқызы Айнұр
    km-kh Khmer ឧទាហរណ៍ John ឧទាហរណ៍: John Smith
    kn-in Kannada ಉದಾಹರಣೆಗೆ, ಜಾನ್ ಉದಾಹರಣೆಗೆ: ಜಾನ್ ಸ್ಮಿತ್
    ko-kr Korean 예: John 예: 홍길동
    kok-in Konkani देखीक, जॉन देखीक: जॉन स्मिथ
    ky-kg Kirghiz Мисалы: Тилек Чубаков
    lb-lu Luxembourgish z. Bsp., John Zum Beispill: Marc Majerus
    lt-lt Lithuanian pvz., Jonas Pvz., Jonas Jonaitis
    lv-lv Latvian piemēram, Jānis Piemēram: Jānis Zariņš
    mi-nz Māori Hei tauira: Hone Mete
    mk-mk Macedonian на пример, Зоран На пример: Бранко Стојановски
    ml-in Malayalam ഉദാ: ജോണ് ഉദാഹരണമായി: John Smith
    mr-in Marathi उदाहरणासाठी, जॉन उदाहरणार्थ: जॉन स्मिथ
    ms-bn Malay (Brunei) sebagai contoh, John Sebagai contoh: John Smith
    ms-my Malay (Malaysia) sebagai contoh, John Sebagai contoh: John Smith
    mt-mt Maltese pereżempju, John Eżempju: John Pace
    nb-no Norwegian (Bokmål) for eksempel Kim Eksempel: Jens Jensen
    ne-np Nepali उदाहरणार्थ, जोन उदाहरणको निमित्त: राम बहादुर
    nl-nl Dutch bijvoorbeeld: Emma Bijvoorbeeld: Jan Smit
    nn-no Norwegian (Nynorsk) for eksempel Kim Eksempel: Jens Jensen
    nso-za Northern Sotho go fa mohlala, John Mohlala: John Smith
    or-in Oriya ଉଦାହରଣ ସ୍ଵରୂପ, ଜୋନ୍ ଉଦାହରଣ ସ୍ଵରୂପ: ଦିପ୍ତି ରଞ୍ଜନ
    pa-in Panjabi ਉਦਾਹਰਣ ਦੇ ਲਈ, ਜੌਨ ਉਦਾਹਰਣ ਦੇ ਲਈ: John Smith
    pl-pl Polish na przykład: Tomek Na przykład: Jan Kowalski
    pt-br Portuguese (Brazil) por exemplo, Marcio Por exemplo: João Silva
    pt-pt Portuguese (Portugal) por exemplo: Rui Por exemplo: Jorge Santos
    qps-ploc Pseudo ƒŏг єжåмþľę, Јσĥň [sqymS][₣óя εхдmþĺĕ: Јǿћη Šмīťђ !!! !!]
    qps-mirr Pseudo (Mirrored) [For example: John Smith]
    quz-pe Quechua qatina, Juan Kay hina: Jorge Lopez
    ro-ro Romanian Ion, de exemplu De exemplu: Ion Popescu
    ru-ru Russian например, Андрей Например: Иван Петров
    si-lk Sinhala නිදසුන් ලෙස, නිමල් නිදසුනක් ලෙස: Don Lasith
    sk-sk Slovak napríklad Ján Príklad: Peter Kováč
    sl-si Slovene na primer Janez Na primer: Janez Kranjski
    sq-al Albanian për shembull, Vehbi Për shembull: Vehbi Neziri
    sr-cyrl-cs Serbian (Cyrillic) на пример, Јован На пример: Петар Петровић
    sr-latn-cs Serbian (Latin) na primer, Jovan Na primer: Petar Petrović
    sv-se Swedish t.ex. Rebecca Exempel: John Smith
    sw-ke Swahili kwa mfano, Yohana Kwa mfano: Mussa Joseph
    ta-in Tamil எடுத்துக்காட்டாக, ஜான் உதாரணத்திற்கு: குமார்
    te-in Telugu ఉదాహరణకు, వేణు ఉదాహరణకు: రామ్ లక్ష్మణ్
    th-th Thai ตัวอย่างเช่น John ตัวอย่างเช่น: John Smith
    tn-za Tswana sekai, Tidimalo Sekao jaaka: P‌ule Molefe
    tr-tr Turkish örneğin, Can Örneğin: Kemal Etikan
    tt-ru Tatar мәсәлән, Фәрит Мәсәлән: Гали Вәлиев
    uk-ua Ukrainian наприклад, Тарас Наприклад: Тарас Руденко
    ur-pk Urdu مثال کے طور پر, امجد مثال کے طور پر: صفدر رشيد
    uz-latn-uz Uzbek masalan, Akmal Masalan: Adham Soliyev
    vi-vn Vietnamese ví dụ, John Ví dụ: John Smith
    yo-ng Yoruba bí àpẹẹrẹ, Jòhánù Bí àpẹẹrẹ: John Smith
    zh-cn Chinese (PRC) 例如: John 例如: 李建国
    zh-hk Chinese (Hong Kong) 例如,John
    zh-tw Chinese (Taiwan) 例如,John 範例: 祝英台
    zu-za Zulu isibonelo, John Isibonelo: John Smith

    Some observations:

    • Many languages translated the words "for example" but left the name as John or John Smith. I'm looking at you, Sweden. "John Smith"? Really? You couldn't have changed it to Sven Svensson?
    • Some languages chose generic names (like Jan Novák), keeping to the spirit of the English sample name. Others chose to substitute a real name (like Marie Dubois). [Update: See correction from Hardt.]
    • German doesn't provide a sample first name. My guess is that they ran out of room! The string Geben Sie einen Benutzernamen ein: probably took up all the space in the dialog, leaving no room for an example. [Update: See explanation of name Jens Mander from Roland.]
    • This information (and plenty of other translation goodness) is publically available for non-commercial use.

    Related: The Locales of Windows 7, all divvied up.

  • The Old New Thing

    WinMain is just the conventional name for the Win32 process entry point


    WinMain is the conventional name for the user-provided entry point in a Win32 program. Just like in 16-bit Windows, where the complicated entry point requirements were converted by language-provided startup code into a call to the the user's WinMain function, the language startup code for 32-bit programs also does the work of converting the raw entry point into something that calls WinMain (or wWinMain or main or _wmain).

    The raw entry point for 32-bit Windows applications has a much simpler interface than the crazy 16-bit entry point:

    DWORD CALLBACK RawEntryPoint(void);

    The operating system calls the function with no parameters, and the return value (if the function ever returns) is passed to the ExitThread function. In other words, the operating system calls your entry point like this:


    Where do the parameters to WinMain come from, if they aren't passed to the raw entry point?

    The language startup code gets them by asking the operating system. The instance handle for the executable comes from GetModuleHandle(NULL), the command line comes from GetCommandLine, and the nCmdShow comes from GetStartupInfo. (As we saw before, the hPrevInstance is always NULL.)

    If you want to be hard-core, you can program to the raw entry point. Mind you, other parts of your program may rely upon the work that the language startup code did before calling your WinMain. For example, the C++ language startup code will run global constructors before calling into WinMain, and both C and C++ will initialze the so-called security cookie used as part of stack buffer overrun detection. Bypass the language startup code at your peril.

    Bonus chatter: Notice that if you choose to return from your entry point function, the operating system passes the return value to ExitThread and not ExitProcess. For this reason, you typically don't want to return from your raw entry point but instead want to call ExitProcess directly. Otherwise, if there are background threads hanging around, they will prevent your process from exiting.

  • The Old New Thing

    Why don't the file timestamps on an extracted file match the ones stored in the ZIP file?


    A customer liaison had the following question:

    My customer has ZIP files stored on a remote server being accessed from a machine running Windows Server 2003 and Internet Explorer Enhanced Security Configuration. When we extract files from the ZIP file, the last-modified time is set to the current time rather than the time specified in the ZIP file. The problem goes away if we disable Enhanced Security Configuration or if we add the remote server to our Trusted Sites list. We think the reason is that if the file is in a non-trusted zone, the ZIP file is copied to a temporary location and is extracted from there, and somehow the date information is lost.

    The customer is reluctant to turn off Enhanced Security Configuration (which is understandable) and doesn't want to add the server as a trusted site (somewhat less understandable). Their questions are

    • Why is the time stamp changed during the extract? If we copy the ZIP file locally and extract from there, the time stamp is preserved.
    • Why does being in an untrusted zone affect the behavior?
    • How can we avoid this behavior without having to disable Enhanced Security Configuration or adding the server as a trusted site?

    The customer has an interesting theory (that the ZIP file is copied locally) but it's the wrong theory. After all, copying the ZIP file locally doesn't modify the timestamps stored inside it.

    Since the ZIP file is on an untrusted source, a zone identifier is being applied to the extracted file to indicate that the resulting file is not trustworthy. This permits Explorer to display a dialog box that says "Do you want to run this file? It was downloaded from the Internet, and bad guys hang out there, bad guys who try to give you candy."

    And that's why the last-modified time is the current date: Applying the zone identifier to the extracted file modifies its last-modified time, since the file on disk is not identical to the one in the ZIP file. (The one on disk has the "Oh no, this file came from a stranger with candy!" label on it.)

    The recommended solution is to add the server containing trusted ZIP files to your trusted sites list. Since the customer is reluctant to do this (for unspecified reasons), there are some other alternatives, though they are considerably riskier. (These alternatives are spelled out in KB article 883260: Description of how the Attachment Manager works.)

    You can disable the saving of zone information from the Group Policy Editor, under Administrative Templates, Windows Components, Attachment Manager, Do not preserve zone information in file attachments. This does mean that users will not be warned when they attempt to use a file downloaded from an untrusted source, so you have to trust your users not to execute that random executable they downloaded from some untrusted corner of the Internet.

    You can use the Inclusion list for low, moderate, and high risk file types policy to add ZIP as a low-risk file type. This is not quite as drastic as suppressing zone information for all files, but it means that users who fall for the "Please unpack the attached ZIP file and open the XYZ icon" trick will not receive a "Do you want to eat this candy that a stranger gave to you?" warning prompt before they get pwned.

    But like I said, it's probably best to add just the server containing the trusted ZIP files to your trusted sites list. If the server contains both trusted and untrusted data (maybe that's why the customer doesn't want to put it on the trusted sites list), then you need to separate the trusted data from the untrusted data and put only the trusted server's name in your trusted sites list.

  • The Old New Thing

    A function pointer cast is a bug waiting to happen


    A customer reported an application compatibility bug in Windows.

    We have some code that manages a Win32 button control. During button creation, we subclass the window by calling Set­Window­Subclass. On the previous version of Windows, the subclass procedure receives the following messages, in order:


    We do not handle any of these messages and pass them through to Def­Subclass­Proc. On the latest version of Windows, we get only the first two messages, and comctl32 crashes while it's handling the third message before it gets a chance to call us. It looks like it's reading from invalid memory.

    The callback function goes like this:

    LRESULT ButtonSubclassProc(
        HWND hwnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam,
        UINT_PTR idSubclass,
        DWORD_PTR dwRefData);

    We install the subclass function like this:


    We found that if we changed the callback function declaration to

    LRESULT CALLBACK ButtonSubclassProc(
        HWND hwnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam,
        UINT_PTR idSubclass,
        DWORD_PTR dwRefData);

    and install the subclass function like this:


    then the problem goes away. It looks like the new version of Windows introduced a compatibility bug; the old code works fine on all previous versions of Windows.

    Actually, you had the problem on earlier versions of Windows, too. You were just lucky that the bug wasn't a crashing bug. But now it is.

    This is a classic case of mismatching the calling convention. The SUB­CLASS­PROC function is declared as requiring the CALLBACK calling convention (which on x86 maps to __stdcall), but the code declared it without any calling convention at all, and the ambient calling convention was __cdecl. When they went to compile the code, they got a compiler error that said something like this:

    error C2664: 'SetWindowSubclass' : cannot convert parameter 2 from 'LRESULT (__cdecl *)(HWND,UINT,WPARAM,LPARAM,UINT_PTR,DWORD_PTR)' to 'SUBCLASSPROC'

    "Since the compiler was unable to convert the parameter, let's give it some help and stick a cast in front. There, that shut up the compiler. Those compiler guys are so stupid. They can't even figure out how to convert one function pointer to another. I bet they need help wiping their butts when they go to the bathroom."

    And there you go, you inserted a cast to shut up the compiler and masked a bug instead of fixing it.

    The only thing you can do with a function pointer after casting it is to cast it back to its original type.¹ If you try to use it as the cast type, you will crash. Maybe not today, maybe not tomorrow, but someday.

    In this case, the calling convention mismatch resulted in the stack being mismatched when the function returns. It looks like earlier versions of Windows managed to hobble along long enough before things got resynchronized (by an EBP frame restoration, most likely) so the damage didn't spread very far. But the new version of Windows, possibly one compiled with more aggressive optimizations, ran into trouble before things resynchronized, and thus occurred the crash.

    The compiler was yelling at you for a reason.

    It so happened that the Windows application compatibility team had already encountered this problem in their test labs, and a shim had already been developed to auto-correct this mistake. (Actually, the shim also corrects another mistake they hadn't noticed yet: They forgot to call Remove­Window­Subclass when they were done.)

    ¹I refer here to pointers to static functions. Pointers to member functions are entirely different animals.

  • The Old New Thing

    How long do taskbar notification balloons appear on the screen?


    We saw some time ago that taskbar notification balloons don't penalize you for being away from the computer. But how long does the balloon stay up when the user is there?

    Originally, the balloon appeared for whatever amount of time the application specified in the uTimeout member of the NOTIFYICONDATA structure, subject to a system-imposed minimum of 10 seconds and maximum of 60 seconds.

    In Windows XP, some animation was added to the balloon, adding 2 seconds of fade-in and fade-out animation to the display time.

    Starting in Windows Vista, applications are no longer allowed to specify how long they wanted the balloon to appear; the uTimeout member is ignored. Instead, the display time is the amount of time specified by the SPI_GETMESSAGEDURATION system parameter, with 1 second devoted to fade-in and 5 seconds devoted to fade-out, with a minimum of 3 seconds of full visibility. In other words, if you set the message duration to less than 1+3+5=9 seconds, the taskbar behaves as if you had set it to 9 seconds.

    The default message duration is 5 seconds, so in fact most systems are in the "shorted possible time" case. If you want to extend the time for which balloons notification appear, you can use the SystemParametersInfo function to change it:

    BOOL SetMessageDuration(DWORD seconds, UINT flags)
     return SystemParametersInfo(SPI_SETMESSAGEDURATION,
                                 0, IntToPtr(seconds), flags);

    (You typically don't need to mess with this setting, because you can rescue a balloon from fading out by moving the mouse over it.)

    Note that an application can also set the NIF_REALTIME flag, which means "If I can't display the balloon right now, then just skip it."

  • The Old New Thing

    Why is hybrid sleep off by default on laptops? (and how do I turn it on?)


    Hybrid sleep is a type of sleep state that combines sleep and hibernate. When you put the computer into a hybrid sleep state, it writes out all its RAM to the hard drive (just like a hibernate), and then goes into a low power state that keeps RAM refreshed (just like a sleep). The idea is that you can resume the computer quickly from sleep, but if there is a power failure or some other catastrophe, you can still restore the computer from hibernation.

    A hybrid sleep can be converted to a hibernation by simply turning off the power. By comparison, a normal sleep requires resuming the computer to full power in order to write out the hibernation file. Back in the Windows XP days, I would sometimes see the computer in the next room spontaneously turn itself on: I'm startled at first, but then I see on the screen that the system is hibernating, and I understand what's going on.

    Hybrid sleep is on by default for desktop systems but off by default on laptops. Why this choice?

    First of all, desktops are at higher risk of the power outage scenario wherein a loss of power (either due to a genuine power outage or simply unplugging the computer by mistake) causes all work in progress to be lost. Desktop computers typically don't have a backup battery, so a loss of power means instant loss of sleep state. By comparison, laptop computers have a battery which can bridge across power outages.

    Furthermore, laptops have a safety against battery drain: When battery power gets dangerously low, it can perform an emergency hibernate.

    Laptop manufacturers also requested that hybrid sleep be off by default. They didn't want the hard drive to be active for a long time while the system is suspending, because when users suspend a laptop, it's often in the form of "Close the lid, pick up the laptop from the desk, throw it into a bag, head out." Performing large quantities of disk I/O at a moment when the computer is physically being jostled around increases the risk that one of those I/O's will go bad. This pattern doesn't exist for desktops: When you suspend a desktop computer, you just leave it there and let it do its thing.

    Of course, you can override this default easily from the Control Panel. Under Power Options, select Change plan settings, then Changed advanced power settings, and wander over into the Sleep section of the configuration tree.

    If you're a command line sort of person, you can use this insanely geeky command line to enable hybrid sleep when running on AC power in Balanced mode:

    powercfg -setacvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e
                              94ac6d29-73ce-41a6-809f-6363ba21b47e 1

    (All one line. Take a deep breath.) [Update: Or you can use powercfg -setacvalueindex SCHEME_BALANCED SUB_SLEEP HYBRIDSLEEP 1, as pointed out by Random832. I missed this because the ability to substitute aliases is not mentioned in the -setacvalueindex documentation. You have to dig into the -aliases documentation to find it.]

    Okay, what do all these insane options mean?

    -setacvalueindex sets the behavior when running on AC power. To change the behavior when running on battery, use -setdcvalueindex instead. Okay, that was easy.

    The next part is a GUID, specifically, the GUID that represents the balanced power scheme. If you want to modify the setting for a different power scheme, then substitute that scheme's GUID.

    After the scheme GUID comes the subgroup GUID. Here, we give the GUID for the Sleep subgroup.

    Next we have the GUID for the Hybrid Sleep setting.

    Finally, we have the desired new value for the setting. As you might expect, 1 enables it and 0 disables it.

    And where did these magic GUIDs come from? Run the powercfg -aliases command to see all the GUIDs. You can also run powercfg -q to view all the settings and their current values in the current power scheme.

    Bonus reading:

  • The Old New Thing

    Microspeak: PowerPoint Karaoke and the eye chart


    The game PowerPoint-Karaoke was invented in 2006 by Zentrale Ingelligenz Agentur. In this game, contestants are called upon to give a PowerPoint presentation based on a slide deck they have never seen. (The German spelling uses a hyphen between the two words. When "translated" into English, the hyphen is often omitted.)

    At Microsoft, the term has been extended to refer to giving a presentation from slides prepared by somebody else, usually on short notice and therefore with little preparation.

    Bob is out sick today, so I'll be giving the overview. Sorry for the PowerPoint Karaoke.

    This is shorthand for "Sorry if this presentation is a bit clumsy, but I'm stepping in on short notice, and I'm not completely familiar with this slide deck."

    In the context of PowerPoint presentations, an eye chart is a slide so dense with text that reading it is a test of visual acuity. The term is usually used as part of an apology for having created such a horrible slide in the first place.

    More generally, the term eye chart refers to any presentation of data in a ridiculously small font. For example, over in the sales/marketing part of Microsoft, there are spreadsheets with titles like FY05 Sales Forecast Eye Chart. Here's what one of them might look like:

    Region Jul 2005   Aug 2005   Sep 2005   Q1   Oct 2005   Nov 2005   Dec 2005   Q2 ...
    FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y FY05 Fcst FY04 Y-Y
    Northeast Widgets 57 57 0% 74 61 22% 85 92 −8% 216 209 3% 71 70 2% 53 59 −11% 90 89 1% 215 218 −2%
    Doodads 41 52 −22% 79 81 −3% 100 85 18% 219 218 1% 49 52 −7% 93 84 12% 87 79 10% 229 214 7%
    Gizmos 64 55 16% 95 88 7% 56 67 −16% 215 211 2% 59 79 −25% 58 69 −16% 68 83 −18% 186 231 −20%
    Northeast Total 159 157 2% 138 168 −18% 170 212 −20% 467 537 −13% 205 224 −8% 209 177 18% 194 244 −21% 608 645 −6%
    Southeast Widgets 80 70 15% 75 82 -8% 57 60 -5% 212 212 0% 63 83 -24% 49 53 -8% 92 75 23% 204 211 -3%
    Doodads 59 69 -14% 60 73 -17% 67 68 -1% 187 210 -11% 54 70 -23% 98 86 14% 58 50 16% 210 206 2%
    Gizmos 75 89 -15% 59 61 -3% 124 100 24% 259 250 3% 80 89 -10% 84 96 -13% 40 52 -23% 204 237 -14%
    Southeast Total 204 239 -15% 220 189 17% 151 187 -19% 576 615 -6% 172 175 -2% 168 210 -20% 122 152 -20% 462 538 -14%
    ... etc for about a bajillion more rows ...

    (The abbreviation Y-Y is being used correctly for once. Writing the program to generate all this fake data took far, far longer than writing the rest of this posting! It got a lot easier once I realized that, since this is just fake data, the totals don't have to add up.)

    Giving the spreadsheet the title Eye Chart lets people know that this is the spreadsheet crammed with data to the point of information overload. If that's what you're looking for.

    I wouldn't be surprised if these uses of the terms PowerPoint Karaoke and eye chart are also popular at other companies.

    Bonus chatter: Last year, I was asked to give a repeat of a presentation I hadn't given in several months. I had only a little bit of time to prepare, and there were times where I lost my place and had to refer to my notes (which I thankfully remembered to keep). It's embarrassing to find yourself playing PowerPoint Karaoke to your own slide deck.

  • The Old New Thing

    Why are custom properties created on Windows 2000 lost when I view the file from newer versions of Windows?


    In Windows 2000, Explorer let you add properties like Summary and Author to nearly any file type. But when you view the files from a machine running Windows XP or later, those properties are lost. Where did they go?

    Most file types do not have extensibility points for adding metadata. For example, every byte of a plain text files is devoted to text data; there is nowhere to put metadata like Author or Summary. In Windows 2000, the shell chose to store this extra information in NTFS alternate data streams (or more accurately, the shell chose to use the STGFMT_FILE storage format, which is implemented in terms of NTFS alternate data streams.) Storing the information in alternate data streams attaches the data to the file without affecting the file contents.

    This was a clever idea, taking advantage of NTFS's ability to attach arbitrary data to a file, but it also had a serious problem: Alternate streams are not preserved by simple and common operations like sending the file by email, copying the file to a (FAT-formatted) USB thumb drive, uploading or downloading the file from a Web site, or burning the file to a CD. Basically, once the file leaves the comfortable confines of your local hard drive, there's a good chance that the metadata will be destroyed.

    To avoid this problem, Windows XP switched to storing the metadata in the file contents itself. Doing this, however, requires support from the file format. Each file type can have registered for it a property handler which describes how to read and write properties for a file. (Windows itself comes with a few such handlers, such as for JPEG images and MP3 files, with more recent versions of Windows supporting more properties.) If no such property handler is registered, the shell will use structured storage, provided the file format is compatible with structured storage.

    The data you added in Windows 2000 are still there. It's just that newer versions of Windows don't bother looking for them. (If you were sufficiently resourceful, you could write a program which opens the file in STGFMT_FILE mode, reads the properties, then reopens the file via the shell namespace and writes the properties back out.)

    For lots of programming goodness about the shell property system, check out Ben Karas's blog, which I have been liberally linking to.

Page 1 of 3 (26 items) 123