May, 2007

  • The Old New Thing

    We should just get rid of that stupid middle tier

    • 28 Comments

    One of our line-of-business applications sometimes gets very heavily loaded, and several times a day, when you try to issue a query or update a record, you'll get the error message, "Unable to contact middle tier. (other technical gibberish goes here)".

    Whenever this happens, I like to amuse myself by shouting "Stupid middle tier! We should just get rid of it. It's always unresponsive."

    Of course, this is a joke along the lines of changing that 15 to a 1. The system follows the standard three-tier model. Getting rid of the middle tier won't actually fix anything.

    But if the error message keeps blaming the middle tier, then to a naive user (or in this case, a willfully stupid one), getting rid of the problematic component might not sound like that bad an idea.

  • The Old New Thing

    Das Leben der Anderen

    • 28 Comments

    A few weekends ago I finally got around to watching the movie Das Leben der Anderen. (English: The Lives of Others.) Apparently movies about the former East Germany get screen time in the States. Go figure.

    I'd been away from conversational German for a long time, but I was rather pleased that I was able to follow some parts without having to consult the subtitles. Though those parts didn't last long. Eventually, they'd use too many words whose meaning I couldn't guess from context, or they'd talk so indistinctly that I couldn't make out the words, or they'd just plain talk too fast and my internal parsing buffer would fill up and reject new input. I could only keep it up for brief stretches.

    Nevertheless, I was pleased. First, I was still able to understand German in German. This is always a major step in learning a language, being able to understand the language on its own terms without first having to translate it into your native language, and I was happy that I hadn't regressed so far that I lost that ability.

    And second, I found myself talking to myself in German again. This is a language trick that I developed early on: Talk to yourself in the language you're trying to acquire. Whether it's wondering out loud what you should do next, checking the time, commenting on the weather when you look out the window first thing in the morning, being angry at other cars on the road, whatever it is, say it in the language you're trying to learn. On top of that, when I listen to the radio by myself, I try to do simultaneous translation of what the newsreader is saying into my target language. Of course, I do a terrible job, but it forces me to stay nimble and exercises vocabulary recall.

    For a few months now, I've been trying to shift my target language from Swedish to German, but whenever I started in German, I would keep slipping into Swedish. This movie appears to have kicked me over the fence. Good news for the Germans; bad news for the Swedes.

    "Raymond, why do you watch so many German movies?"

    Because it's hard to find Swedish movies in this country.

    Sidebar

    Groups of ten or more visiting the Stasi Museum in former East Berlin can request a guided tour in German, English, or, curiously, Swedish.

  • The Old New Thing

    Microspeak: The forcing function

    • 12 Comments

    At Microsoft, you'll hear the phrase "forcing function" and it won't be in reference to differential equations or to user interface design. Rather, it means a set of circumstances that forces a decision to be made or which forces an action to be taken that previously had no hard deadline.

    Example: "The impending Y2K threat served as a forcing function for many companies to upgrade their hardware."

  • The Old New Thing

    Suggestion Box 3

    • 469 Comments

    Post suggestions for future topics here instead of posting off-topic comments. Note that the suggestion box is emptied and read periodically so don't be surprised if your suggestion vanishes. (Note also that I am under no obligation to accept any suggestion.)

    Topics I are more inclined to cover:

    • Windows history (particularly the Windows 95 era).
    • Windows user interface programming in Win32, and shell programming in particular.
    • General programming topics (selectively).
    • Issues of general interest.
    • My personal hobbies.

    Topics I am not inclined to cover:

    • The blog software itself. You can visit the Community Server home page and cruise their support forums.
    • Internet Explorer. You can try the IE folks.
    • Visual Studio. You can try one of the Visual Studio blogs.
    • Managed code. This is not a .NET blog. I do not work on .NET technologies. As far as .NET is concerned, I'm just another programmer like you. Occasionally I touch a .NET-related topic, but I do not bring any expertise to the subject.
    • Non-software Microsoft topics, such as product support policies, marketing tactics, jobs and careers, legal issues.
    • Microsoft software that isn't Windows. (Exchange, Office, ...)
    • Windows topics outside user interface programming. (Plug and Play, Terminal Services, Windows Messenger, Outlook Express, SQL, IIS, remoting, SOA...)
    • User interface programming in anything other than Win32. (Because I know nothing about it.)
    • Debugging a specific problem. (Not of general interest.)
    • Predictions for the future. (What's the title of this blog again?)
    • Participation in Internet memes.

    You can also send feedback on Microsoft products directly to Microsoft. All the feedback gets read, even the death threats.

    Suggestions should be between two and four sentences in length. As you can see, there are hundreds of them already, so you have three seconds to get your point across. Please also search the blog first because your suggestion may have already been covered. And remember, questions aren't suggestions.

    Note the enormous topic backlog. Consequently, the suggestion box has been closed temporarily and will reopen once the existing backlog has cleared, which I estimate will happen sometime in early 2010. If your suggestion is that important, I'm sure you'll remember it when the suggestion box reopens.

  • The Old New Thing

    Another chapter in Swedish political hypocrisy (2007 edition)

    • 18 Comments

    A few years ago, Gudrun Schyman, then-leader of Sweden's left-wing party, Vänsterpartiet ("The Left Party"), was forced to resign after it was revealed that she had been cheating on her taxes for at least five years, specifically by claiming fake deductions. This was particularly ironic because, as the left-wing party, Vänsterpartiet is heavily pro-taxation.

    The latest news from Sweden comes from the opposite end of the political spectrum. The far right-wing party Sverigedemokraterna ("The Sweden Democrats"), which has an anti-immigrant platform, have complained that 10% of immigrants live on government assistance, double the rate of native Swedes. Swedish tabloid Aftonbladet did some legwork and calculated that nearly 20% of Sverigedemokraterna members live on government assistance, and over a third receive partial government assistance. (In English, and less sensationally written.)

    If you dare to click through to the Swedish version, I can at least try to translate the chart: The left hand column shows the average annual income of members of the various parties (sd = Sverigedemokraterna) in Swedish kronor. The right hand column shows the percentage of members with, um, something; having trouble translating. It literally means "payment notices" but I'm not sure what that means. The white boxes marked "Riket" show the national averages. And the little graph in the lower left corner shows the percentage of sd members (compared to the national average) who owe money to the Swedish Enforcement Authority, which collects fines, fees, taxes, legal judgments, and similar monetary obligations.

    No scandal article from Aftonbladet is complete without some mean-spirited fun, and in this case, they decided to add some new data to a bar chart taken from one of Sverigedemokraterna's political pamphlets.

    Nitpicker's corner

    There's plenty of hypocrisy in United States politics, too.

  • The Old New Thing

    You're not my manager, so I'm not going to ask how high when you tell me to jump

    • 44 Comments

    This happens a lot. I'm minding my own business and then I start getting nag mail from somebody I've never heard of. It usually is marked "High Priority" and the content has lots of boldface and wording that makes it sound like the world is going to end tomorrow. (Pretend "elephant"† is some new buzzword.)

    URGENT - ACTION REQUIRED

    Your component has not completed its Elephant review. Elephant-readiness is a release criterion. You must visit http://elephantready/?id=16384 and fill out an Elephant compliance form by the end of the week.

    When you go to the web site, it asks you to confirm a few pages of statements like this:

    Component does not assume rhinos.
    Component does not cover animals with a blanket (elephants are big).
    Component supports a variable amount of peanuts.
    Component does not require animal to have a horn.
    Component does not reject animals with tusks.
    All interfaces exposed by component can operate on elephants.

    Okay, so I get this mail and my first reaction is "What's an elephant?"

    I lied. That's not my first reaction. My first reaction is "Who the hell are you? Who died and made you my manager?"

    Note to managers: Sending out random mail like this won't make you any friends. It turns out people don't like it when somebody creates work for them. Especially when it comes out of nowhere without warning. and double especially when they've never even heard of your feature. So far, you haven't given them any indication why they care aside from "You should care because I said so."

    And you are who again?

    Often when I look at these checklists, I can't even answer them. I mean, sure, I didn't write any code that assumes rhinos, but my component relies on other components, and I don't know whether those other components assume rhinos. Similarly, my code doesn't care about horns or tusks, but maybe one of the components I rely on does. I don't know.

    As a result, I usually skip the questionnaire filled with questions I can't answer and just wait for the next round of urgent messages. That way, I can ignore the second round, too.

    For you see, my manager decides what tasks I should be working on, not you. If you think my manager is doing a bad job of prioritizing those tasks, then feel free to have a little meeting with my manager and work out some sort of agreement. Until then, don't bug me. I have work to do.

    For those new to this web site (and a reminder to those with poor memory):

    †I disguise the name because (1) it's not important to the story, and because (2) the goal is not to ridicule but rather to illustrate a point. Attempts to guess what "elephant" is will be deleted. Don't make me delete further stories in this series like I did with "Stories about Bob."

  • The Old New Thing

    The unidentified award

    • 39 Comments

    I have in front of me a small bag of a trail mix type of concoction. On the bag it proudly proclaims, "Award Winning Snack". First of all, there's a missing hyphen. (It should be "Award-Winning Snack" since "Award-Winning" is a phrasal adjective. The snack won an award. The award isn't winning a snack.)

    But what award is it? There is no mention of it on the bag or on the company's web site, so I called them. (Update: I checked again a few weeks later and now it says so.) The product won the 2006 Automatic Merchandiser Reader's Choice Product of the Year for Salted Snack of the Year. Automatic Merchandiser is the magazine of the vending industry, and you can check out the complete list of winners. It's not clear to me what the criteria are. Are people in the industry voting for the snack they personally like best? The one they most admire? The one they would most like to stock? I don't know.

  • The Old New Thing

    Don't be helpless: I don't know anything about MFC modal loops, but unlike some people, I'm not afraid to find out

    • 24 Comments

    Commenter Tom Grelinger asks via the Suggestion Box:

    If I have a modal CDialog that is visible and usable to the user. Let's say I receive an event somewhere else in the program and I call DestroyWindow on the modal CDialog from within the event. I notice that the OnDestroy is called on the CDialog, but DoModal never exits until a WM_QUIT is posted to the modal's message pump. What are the pitfalls to this? Unfortunately, there is really no way to avoid this situation.

    I'm not sure what the question is, actually. The question as stated is "What are the pitfalls to this?" but he answered that in his own question: The pitfall is that "DoModal never exits until a WM_QUIT is posted to the modal dialog's message pump."

    I'm going to assume that the question really is, "Why doesn't destroying the window work?" with the follow-up question, "What is the correct way to dismiss a modal dialog?"

    The first problem with this question is that it assumes that I know what a CDialog is. From its name, I'm going to assume that this is an MFC class for managing a dialog box. But you don't even have to know that to answer the first reformulated question operating only from Win32 principles: DestroyWindow is not how you exit a modal dialog. You exit a modal dialog with EndDialog. The DestroyWindow technique is for modeless dialogs.

    But let's look at the question another way, which is my point for today: You have the MFC source code. Don't be afraid to read it. Especially since I don't use MFC personally; I don't even know the basic principles of application design with MFC. I work in straight Win32. As a result, I don't know the answer off the top of my head, but fifteen minutes reading the MFC source code quickly reveals the reason why destroying the window doesn't work.

    Watch me as I go and find out the answer. It's nothing you can't already do yourself.

    The CDialog::DoModal method calls CWnd::RunModalLoop to run the dialog loop. If you look at CWnd::RunModalLoop, you can see the conditions under which it will exit the modal loop. Here's the code with irrelevant details deleted. (They're irrelevant because they have nothing to do with how the modal loop exits.)

    int CWnd::RunModalLoop(DWORD dwFlags)
    {
        ... preparatory work ...
    
        // acquire and dispatch messages until the modal state is done
        for (;;)
        {
            ... code that doesn't break out of the loop ...
    
            // phase2: pump messages while available
            do
            {
                // pump message, but quit on WM_QUIT
                if (!AfxGetThread()->PumpMessage())
                {
                    AfxPostQuitMessage(0);
                    return -1;
                }
    
                ... other code that doesn't break out of the loop ...
    
                if (!ContinueModal())
                    goto ExitModal;
    
                ... other code that doesn't break the loop ...
            }  while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
        }
    
    ExitModal:
        m_nFlags &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
        return m_nModalResult;
    }
    

    There are only two ways out of this loop. The first is the receipt of a WM_QUIT message. The second is if CWnd::ContinueModal decides that the modal loop is finished. The commenter already mentioned the quit message aspect to the modal loop, so that just leaves CWnd::ContinueModal.

    The CWnd::ContinueModal method is very simple:

    BOOL CWnd::ContinueModal()
    {
        return m_nFlags & WF_CONTINUEMODAL;
    }
    

    Therefore, the only other way the loop can exit is if somebody clears the WF_CONTINUEMODAL flag. A little grepping shows that there are only three places where this flag is cleared. One is in CPropertyPage, which is a derived class of CDialog and therefore isn't relevant here. (I'll ignore CPropertyPage in future searches.) The second is in the line above right after the label ExitModal. And the third is this method:

    void CWnd::EndModalLoop(int nResult)
    {
        // this result will be returned from CWnd::RunModalLoop
        m_nModalResult = nResult;
    
        // make sure a message goes through to exit the modal loop
        if (m_nFlags & WF_CONTINUEMODAL)
        {
            m_nFlags &= ~WF_CONTINUEMODAL;
            PostMessage(WM_NULL);
        }
    }
    

    This method is called in only one place:

    void CDialog::EndDialog(int nResult)
    {
        if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
            EndModalLoop(nResult);
    
        ::EndDialog(m_hWnd, nResult);
    }
    

    Following the money one last step, the CDialog::EndDialog method is called from four places in CDialog. It's called from CDialog::HandleInitDialog and CDialog::InitDialog if some catastrophic error occurs during dialog initialization. And it's called from CDialog::OnOK and CDialog::OnCancel in response to the user clicking the OK or Cancel buttons.

    Notice that the CDialog::EndDialog method is not called when somebody forcibly destroys the dialog from the outside.

    That's why destroying the dialog window doesn't break the modal loop. If you want to break out of the modal loop, your only choices are to post a quit message or call CWnd::EndModalLoop, either directly or indirectly (via CDialog::EndDialog, for example).

    Notice that the MFC modal loop obeys the convention on quit messages by re-posting the quit message when it breaks out of the modal loop. (Though it really should have posted the wParam from the quit message rather than just posting zero.)

    The workaround therefore is not to destroy the dialog with DestroyWindow (something you should have known not to do a priori since that's not how you exit modal dialog boxes) but rather by calling CDialog::EndDialog, passing a result code that lets the caller of CDialog::DoModal know that the dialog box exited under unusual circumstances.

    This took me fifteen minutes to research and a little over an hour to write up. All this work to answer a question that you should have been able to answer yourself with a little elbow grease. You're a smart person. Have confidence in yourself. You can do it. I know you can.

  • The Old New Thing

    Don't drive your pick-up onto the roof of a house, especially if, well, read on

    • 19 Comments

    Back in 2000, a crazy stunt made the front page of the local newspaper, and it still holds a special place in my heart years later. We begin with Man drives pickup onto friend's roof as a stunt. The story opens with the picture of said pick-up on the roof of a house with its proud owner. That picture already tells a story. The run-down house, the pick-up on the roof, the can of beer, the frat-boy self-satifaction... And the article hasn't even begun yet.

    As Dave Anthony's pickup truck sank slowly through the roof of a one-story house yesterday morning, he popped a Spin Doctors CD into a player and reached for a can of Budweiser.

    "It wouldn't be a good life without a challenge," he said. "If you don't break something, you aren't trying very hard."

    You don't have to wait long before you find a sentence that begins

    It began with a few beers...

    When a sentence begins that way, the odds are slim that the second half of the sentence is going to be "... and ended without incident."

    The article is basically every single joke about Kent rolled into 700 words. Kent is a suburb of Seattle which Seattle-ites look down upon, and the story does nothing to dispel the stereotype. You could take the article and just run it straight on Almost Live! (Here's a typical parody.)

    But the story doesn't end with that article. Less than a week later, the hero of the story found himself in even more hot water. I'll let the follow-up article's opening sentence explain:

    Driving your pickup truck onto the roof of a house and getting your picture in the newspaper doesn't make a whole lot of sense when police want to talk to you about a $2,800 set of tires purchased with a stolen credit card.
  • The Old New Thing

    Getting in on the action while it's still there

    • 12 Comments

    Remember day trading? All the cool people were doing it. Glamour stories of people who tripled or quadrupled their stake in a single day. With all this money available for the taking, you'd be a fool not to be day-trading!

    During the era of day trading frenzy, I got a particular chuckle out of one PC manufacturer who produced a Precision Online Trading Workstation, equipped with dual monitors and dual processors and preloaded with financial software, so you can see more stock quotes, crunch those numbers faster, and lose more money more quickly than you ever thought possible. I imagined the logic that went into this product:

    "There's a lot of stupid people out there. Stupid people who are going to lose all their money one way or another. They may as well lose some of it to us."

Page 2 of 5 (44 items) 12345