Random writing snippet

Here’s something I wrote a couple of nights ago. I’m not sure where it’s going, or whether I’ll ever continue it, but here it is for your reading pleasure. If the spirit moves you to comment, please, go for it. (Even if it’s just “It sucked!” or “Interesting, what happens next?” or “I’d like to offer you a publishing contract with a multimillion-dollar advance”.)

For anyone who hasn’t seen it yet, I’ve got more of my fiction posted on my writing site, but I’ll probably post small snippets like this on my blog from time to time.


It was funny, how the things that changed her life always seemed to happen on Thursdays. Her first family cookout; the day she’d gotten her first job; the day she’d found out she was pregnant; the day she emerged, gasping, from suicidal despair; the day she’d gotten her first car and left town.

But this one was different.

“Somehow,” he told her, “it always works that way.”

She looked at him, then back at the gun.

“What kind of hours are we talking?” she said.

He shrugged. “Depends on the market. Some weeks it’ll be almost nothing. Some weeks maybe eighty hours, maybe more. Of course, it depends on whether you count travel time.”

Her dark eyes studied the gun’s outlines, stark against the dirty blue of the sheet. “Why me?” she said. “What’ve I got?”

His icy blue eyes studied her, a grin tugging at the corner of his mouth, making the stubble twitch. “It’s more about what you haven’t got.”

She nodded. She understood.

Well, she thought she did.

Tired but wired

Yesterday: Moving day, again. We now have all the furniture moved out of the apartment, including the big couch and the fridge — hooray! Many thanks to all who helped (Kent and his kids, Laura, Lina, Solomon, Jeff, and Anita, with honorable mentions for Sidney and the pizza guy). Now I just need to put the refrigerator door back on sometime.

Today: I tried to mow the lawn, which meant going out and buying gas (and discovering that we don’t have a lid for our gas can). The lawnmower I’m borrowing from John works pretty well, aside from not having power-drive wheels. I got all the front yard and about half of the back yard before I decided to wander inside and collapse from something between heat exhaustion and heat stroke. (Yes, really. I’m a wuss about heat.) Cold washcloth wasn’t helping (I could practically see the steam coming off the washcloth), but a cold shower improved matters a bit. Even so, I suspect I would have gotten a brutal migraine if I hadn’t decided to take some Excedrin. The mower sat there in the backyard from about 11:00 until about 8:00 tonight when I finally moved it back in. I haven’t finished mowing the backyard yet; I’ll try to do that early tomorrow while it’s still cool out. For future reference, mowing the lawn is probably a two-day task; it’s not that big a lawn, but it’s hotter work than I’m in any shape for. I should probably start going to Tae Kwon Do again and get myself in shape or something.

Sam came over this afternoon, and we drilled holes with a serious drill bit, spent a great deal of time trying to buy a co-ax wire-stripper that worked, cut holes, dodged cats, and fished wires. As a result, the computer room now has both cable and Ethernet. I’m back online! Hooray! Of course, there’s still lots of cleanup (screw holes to be drilled, wall plates to be attached, wallboard dust to be vacuumed, tools to be put away, duct to be re-closed, wall plate to be surgically altered, wall vent and ceiling tiles to be put back on) that I haven’t even started yet. (Well, I’ve sort of started on it, in that I went back to the apartment to get our handheld vacuum. Haven’t used it yet, but I did go and get it.)

Whew. Long weekend. Good weekend.

Now I’ve just got to box up the rest of our stuff by the end of the month. Whee. Keep those boxes coming, Sidney.

Holy cow, why didn’t anyone tell me about New EIP?

Holy cow. I found a blog post about a way-cool Visual Studio debugger feature… that’s also available in Delphi’s debugger… even for Win32! Sweeeet.

It’s a way to move the current execution pointer. How many times have you stepped over a function, realized it didn’t do what you wanted,

and wish you could step back? Well, as long as the function didn’t have any significant side effects (and, in Win32, as long as it didn’t smash any important registers), you can. Gotten into an infinite loop, and had to terminate the app and start over? Not necessary — you can just move the instruction pointer outside the loop and keep debugging.

In Visual Studio .NET, the feature is called “Set Next Statement” and is available right there in the code window’s context menu; just right-click on the line you want to move to. In Delphi for Win32, you have to open the CPU window, and then you can right-click on an instruction in there and use the ever-so-intuitively-named “New EIP” menu item. No wonder I never knew Delphi had this feature.

I’ll be curious to see how well this works, and how sensitive it really is to things like register usage (temporary variables?). But, man, oh, man. This is gonna be awesome…

Everything you need, except for this other stuff

This is what happens when the marketing guys write the system requirements doc:

The Microsoft® .NET Framework Software Development Kit (SDK) version 2.0 includes everything developers need to write, build, test, and deploy .NET Framework applications—documentation, samples, and command-line tools and compilers.

Everything I need, huh? Read on…

You must install the .NET Framework Redistributable Package version 2.0 prior to installing the .NET Framework SDK.

Sigh. Reminds me of installing the DirectX 9 SDK.

Aborting combobox dropdown, showing dialog box

So I’m trying to build a UI where the user fills in three edit boxes — server name, login, and password — and then drops down a combo box to select which “database” they want to use. When the user drops down the combo, the app connects to the server and queries the list of databases. If it can’t connect to the server (bad password, server doesn’t exist, etc.), the app should show an error message, and the combo box shouldn’t open. Nice, compact, convenient — not totally elegant (a wizard might be better, since order matters), but you don’t really want multiple steps on a login screen. And this should be easy to code. (Right…)

The WinForms ComboBox class has a DropDown event that makes a great place to query the server and populate the dropdown list. And that works just fine, no problems at all — as long as there are no errors. It’s the “if there’s an error, the combo box shouldn’t open” bit that gave me headaches. Just how do you tell the combo box that you don’t actually want it to drop down?

I was hoping the DropDown event would take a CancelEventArgs, but nope — and not surprising, since after a little digging, I found that CB_SHOWDROPDOWN doesn’t give you any way to cancel the dropdown either. There’s a Windows message you can send the combo box to close the dropdown, but it doesn’t work from inside the DropDown event (no effect; the combo still opens as normal). Throwing in an Application.DoEvents didn’t help. Just going ahead and showing the dialog didn’t prevent the combo from dropping down — the dialog pops up, and then as soon as you close it, then the combo box opens!

Okay, try the brutal approach: force the combo box to re-create its window handle. That should darned well keep it from dropping down! RecreateHandle is protected, so I can’t call it directly unless I descend a new class from ComboBox (messy if I’m using the form designer), so I opened Reflector and looked for methods that call RecreateHandle. I settled for the property setter for IntegralHeight.

Works great, as long as I don’t show the dialog box. If I both recreate the handle and show a dialog (doesn’t matter which order I do those in), then the combo box gets into a weird state where it thinks the left mouse button is still down, so after the dialog shows, you have to click the combo twice to open it again (once to cancel the mouse-down state, again to actually drop it down). It even shows the dropdown button as pressed when you mouse over it, until you click to cancel the phantom mouse-down state. Again, Application.DoEvents doesn’t help. Nor do various combinations of trying to change the mouse capture, or recreate the handle before and/or after showing the dialog.

I finally got it to work, by doing a PostMessage (well, BeginInvoke, but that’s implemented as a PostMessage), so that I was showing the dialog after the DropDown event returned. And once it actually does work (and once I work around a C# compiler bug with delegates and overloads), it actually works quite nicely. Here’s the code:

private delegate void ShowMessageDelegate(IWin32Window owner, string message);
...
private void ComboBox1_DropDown(object sender, System.EventArgs e)
{
    try
    {
        // do something that might throw an exception
        ArrayList arrayList = GetList();
        cbxBudgetYear.Items.Clear();
        cbxBudgetYear.Items.AddRange(arrayList.ToArray());
    }
    catch (InvalidOperationException ex)
    {
        // Force the combo box to re-create its window handle. This seems
        // to be the only way to prevent it from dropping down. Toggle the
        // property twice, which leaves it unchanged but calls RecreateHandle.
        cbxBudgetYear.IntegralHeight = !cbxBudgetYear.IntegralHeight;
        cbxBudgetYear.IntegralHeight = !cbxBudgetYear.IntegralHeight;

        // Don't display the error dialog immediately -- wait until the
        // combo box is done sending CB_SHOWDROPDOWN and is in a stable state.
        // Should be able to point the delegate directly to MessageBox.Show,
        // but the compiler picks the wrong overload and complains.
        BeginInvoke(new ShowMessageDelegate(MessageBoxShow),
            new object[] { ParentForm, ex.Message });
    }
}
private void MessageBoxShow(IWin32Window owner, string message)
{
    MessageBox.Show(owner, message);
}

Why can’t spammers spell?

Honestly. “Your account information needs to be renew”? “Deletation”? And these people want me to think it’s PayPal sending me this message?

And people actually fall for this. I can understand them being bamboozled by the hyperlink (especially since Hotmail encourages scams by obfuscating the URL), but come on, don’t people read? It’s scary, if a bit Darwin-Awardish. Economic survival of those with the fittest educations.

Still, it’s sad. You really would think that, after succesfully scamming their first victim, they’d be able to pay for a proofreader.


Dear PayPal valued member,

Due to concerns, for the safety and integrity of the PayPal
community we have issued this warning message.

It has come to our attention that your account information needs to be renew due to
inactive members, spoof reports and frauds.
You must to renew your records and you will not
run into any future problems with the online service.
However, failure to update your records will result in account deletation.
This notification expires on July 11, 2004.

Once you have updated your account records your PayPal will not be
interrupted and will continue as normal.

Please follow the link below
and renew your account information.

https://www.paypal.com/cgi-bin/webscr?cmd=login-run

PayPal
PayPal Service Department