Sunday, October 15, 2006
This is my first Google Docs ("Writely"?) document. Blah blah blah.
Saturday, July 16, 2005
Useful site for P/Invoke users
www.pinvoke.net is a Wiki-ful of P/Invoke signatures and snippets of sample code.
Wednesday, July 13, 2005
Blogging Again, Again
The impending Portland Code Camp has finally prodded me into fixing up my broken blog and site. So here I am. Hope to see you at Code Camp, it's gonna be a blast.
Wednesday, July 21, 2004
Blogging again
After almost a year I've decided to start blogging again.
Friday, August 22, 2003
Embedded Resource Naming bug in Visual Studio (.NET) 2003
At work we have a C# project in which the namespace name doesn't match the folder name. Specifically, the files are in
Client/Common/Src and the project's "default namespace" (in the project properties) is Serveron.Client.Common (not Serveron.Client.Common.Src, which is what VS.net likes to use as a default in such cases).
When I build the resulting DLL and look at the manifest with ILDASM, near the bottom I see this:
.mresource public Serveron.Client.Common.BaseVisualModule.resources
{
}
.mresource public Serveron.Client.Common.src.DefaultAwaitingDataFeedback.resources
{
}
.mresource public Serveron.Client.Common.BaseNavigator.resources
{
}
.mresource public Serveron.Client.Common.ConfigUIControl.resources
{
}
.mresource public Serveron.Client.Common.ConfigurableTask.resources
{
}
.mresource public Serveron.Client.Common.BaseDialogControl.resources
{
}
.mresource public Serveron.Client.Common.BaseTask.resources
{
}
Note how just one of the embedded resources, the one for the
DefaultAwaitingDataFeedback form, has ".src" in the resource name. The others don't.
Why is one embedded resource named differently from the others? All the source files are in the same subfolder, "Src".
Oddly, everything was fine until I made a seemingly trivial change to resources yesterday (I dropped a PictureBox on a form and put an icon in it.) After recompling, the next time the code tried to raise the form caused the dreaded
MissingManifestResourceException.
Here is a link to a posting by somebody who is clearly having the same problem. But no explanation is given.
My problem also looks similar to this bug, which is acknowledged as a problem by Microsoft. The circumstances seem a bit different from my bug, however.
My working theory is that certain user actions in VS cause some "upper" part of the app (VS) to refresh the resource name. A call is made to some "lower" part of the app requesting the appropriate resource name. At this point the "lower" part of the app screws up and returns the folder name, even though it should return the default namespace name. So the problem only occurs when the two names differ.
Wednesday, August 13, 2003
Pocket PC and Transcriber
I got a ViewSonic V37 recently. It's a "Pocket PC", meaning it runs Microsoft's "Pocket PC 2002" OS. It has a 320x240 color screen, 64MB of nonvolatile memory, 32MB of flash, a 400Mhz Intel XScale (ARM architecture) CPU, and a slot that will accept a WiFi card (once they exist). A Cray-1 only had 8MB of memory and a 250Mhz CPU, mind you. You can look it up.
I was pretty skeptical about the Pocket PC initially. It's cute, I thought, but how ya gonna get anything into it? Tap on the toy keyboard image? Not likely.
Well, my skepticism is fading fast. Its handwriting recognizer, the "Transcriber", is amazing. I have pretty neat handwriting, so maybe this isn't true for everybody. But already I can write with the stylus almost as fast as I can type! ... and no problems with my wrists. The accuracy is not as good as I get with the keyboard, and corrections are more difficult. But on the other hand, I usually upload the text. I can enter it using Pocket Word on the V37 while relaxing almost anywhere and correct it after I upload it.
I have to admit, it's cool.
Ongoing problems with Blogger and Blogspot
If you read this blog, you've undoubtedly noticed the annoying banner ad at the top of the page. Blogger (really Blogspot, their hosting site) advertises that for a few dollars a year you can upgrade and eliminate the banner ad. But ever since I started trying to upgrade, I have consistently met a page that says they are "currently undergoing maintenance."
On the other hand, it's sorta cool to encounter a business that won't take your money even when you want to give it to them. It's so...retro.
Sunday, August 10, 2003
I'm trying this through the new BlogThis! interface. It's neat, but I don't see any way to preview. That's a bit weird if you want to put any serious HTML in your blog.
I've been having a lot of other problems with Blogger recently. I won't bore you with the details but I'd advise holding off on new Blogger accounts for a little while. Now that they're owned by Google I'm sure they'll get it straightened out. If you want more information please email me.
Saturday, August 09, 2003
I found a bug in WinForms...at least I consider a bug. The InvokeRequired property, which is all-important in multithreaded Windows Forms programs, doesn't always give the right answer. I built a demonstration program to illustrate the problem.
I first encountered this problem at work in a large-ish WinForms app we're building. It's an Explore-style UI with "Navigators" in the left pane and "Tasks" in the right pane (our terms). All the Navigators and Tasks extend our BaseVisualModule class which in turn extends UserControl. The BaseVisualModule class defines an Initialize() method.
The failure scenario is something like this:
- The main frame iterates all the assembly DLLs in a well-known subfolder.
- The main frame iterates the classes in each DLL and instances the ones that are Navigators or Tasks.
- The main frame iterates the instances and calls Initialize() on each of them.
- The Initialize() method typically fires off an asynchronous Web Services call to get the initial state.
- The main frame continues constructing the control hierarchy. This takes a while (10s to 100s of milliseconds) because the control hierarchy of the main frame is very complex.
- Eventually the Web Services calls start to complete. The completion callback runs and fires an event back to the BaseVisualModule (base class of a Navigator or Task).
- The event handler checks InvokeRequired and switches to the GUI thread if necessary.
- The event handler calls a virtual method which is overridden in the Navigator or Task (subclass)
- The method uses the data returned from the WS to draw the initial state of the control.
As you can see, there is no particular synchronization between the event handlers and the main frame's ongoing effort to assemble the app's entire control hierarchy. We sometimes saw the InvokeRequired call in the event handler return FALSE, so the event handler would not switch to the GUI thread. Then almost immediately afterward we saw exceptions from the control indicating that it was being touched from the wrong thread...which it was.
The question was, why did InvokeRequired return FALSE?
Decompiling the code for InvokeRequired, I noticed that it does a lot of traversing of the hierarchy of window handles trying to find a more parental window. I could see a branch where the code would return FALSE if this navigation didn't lead anywhere. After this I was able to put together the test program that demonstrates the problem.
I'm not quite sure why they do things this way, but it can obviously be a problem in real programs. As you can see, InvokeRequired can return FALSE, then magically return TRUE a little while later, even though nothing has happened to the control itself - the only state changes are in the control's parent (or its parent, or its parent, etc.)