Friday, January 14, 2005

A Nerd's Halloween

I get a fair amount of email about Managed DirectX. I always try to help the people that email me, although it can take me a while (sorry!). Well, back in the Autumn of 2003, someone emailed me asking how to send different different sounds to different speakers with Direct Sound. It took me a while, but I eventually figured out how to do it and sent him some code. At the same time, I asked him what he wanted it for. It turns out, he used it to build this. Impressive to behold, and I'm glad to have helped a little bit. :)

Wednesday, January 12, 2005

My New Prompt

Courtesy of the clever Shawn Van Ness, my new command-line prompt is now


$P$_$+$G


Which, when I set it via either the prompt command or the PROMPT environment variable, gives me a command line that looks like this:


C:\data\Projects\flexwiki\FlexWikiCore
++>


The plusses indicate that I'm two levels deep in pushd, and I like that the working directory appears on the line before, obliterating the problem of long paths making commands linewrap. Nice!

Wednesday, January 5, 2005

Tom Miller's New Book

Tom Miller's new book, Beginning 3D Game Programming is out. Given that Tom literally wrote Managed DirectX, and then went on to write an excellent book about it, I'm guessing this one will be good, too. It's definitely on my wish list if anyone wants to send me a late XMas gift. :)

Monday, January 3, 2005

2005

With a new baby, my wife in school full-time, and some major rennovations going on in the basement, it's going to be hard to find free time to hack unless my current client gives me the boot and I can't find anything else. (Knock wood that doesn't happen.) Nevertheless, I have in mind what I want to do software-wise in 2005.


First, foremost, and solely, I would like to get FlexWikiPad to at least 1.0 status. I've been working on it for over a year in my spare time, but my vision for where I want to get it has changed little. Right now that means working on a decent text editor control that I can use for it. That'll probably take me a few months just to finish that, but I'm guessing when I'm done it'll be even more widely used than FlexWikiPad itself. Stay tuned. After that, I can finish up the last few major features I want to get into the thing, and then go on a bug-smashing tear.


And that's actually it. I have enough other non-coding projects in my personal life that I think I need to hang up the spare-time software gig for a bit when I get FlexWikiPad to a satisfactory doneness state.

Saturday, January 1, 2005

The Year In Review

2004 has come and gone. It was a huge year for me, both personally and professionally; I hope yours was as good as mine.


The end of the year (or in this case, the beginning of the next) is traditionally a time to look back at what happened through the lens of hindsight. Who am I to resist jumping on the bandwagon? Herewith, a tour of the highlights of my year as seen via CraigBlog.


In January, I started up at MSDN again. Focusing on writing production software was a huge theme for me in 2004: while I've done it before a little, my career has long been focused more on research and troubleshooting than on the ruthlessly practical world of getting software out the door. It was enormously educational, and really fun. And I'm still not done learning how to do it better.


In February, I wrote the last Direct3D tutorial of the year. At the time, I didn't think it was going to be the last one, but things just kept getting busier and busier, and I haven't yet found the time to get back to the series. I do still plan to write more, but I don't know when I'm going to get there.


In March, I bid GotDotNet adieu permanently. As a workspace environment, I find it lacking in several regards. My discontent in part led to the migration of FlexWiki to SourceForge, a journey which took a large part of the rest of 2004 to complete.


In April, I got the FwContrib project set up on SourceForge. FwContrib contains the project to which I have devoted over a year of my spare time now: FlexWikiPad. Oh, and April was also the month where I found a three-foot snake in the basement.


In May, I shipped version 1.0 of FwSync. Finishing something and getting it “out there” was quite a milestone for me. Hopefully 2005 will see the same goal met for FlexWikiPad. May was also the month where my wife was accepted into the Executive MBA program at Wharton, something which negatively impacts my free time now, and (hopefully) positively impacts my income later. :)


In June, I found a nasty bug in System.Decimal while working on MSDN2. I submitted it via the Product Feedback Center, and it got fixed for Whidbey. Cool.


In July, Peter Provost and I released the dasblog2dottext importer tool (he wrote it, I did the build script). I also launched the Pluralsight Wiki, a fairly obvious thing for a wikihead like me to do.


In August, I released another version of FlexWikiPad, and then almost immediately had to patch it...I was definitely starting to feel like I was doing “real“ software. :) I also discovered Beatallica, a band that still amuses me months later.


September was a momentous month for me. Not only did the alpha version of MSDN2 ship, but FlexWiki went open source (only the third Microsoft project to do so). I also saw FoamHenge and finally ditched EIF for log4net - a move I still don't regret.


For all the other great stuff that happened to me this year, October is clearly the absolute highlight. And no, I'm not talking about the fact that I released RichTextEditor. The big event was that on October 28th, my daughter Ellen was born.


November was (understandably, I think), a slow blogging month. But I did manage to ship an update to RichTextEditor. Of course, right after that I realized that I was going to have to start over with my own text editor control. Sigh.


I took a good chunk of December off, only managing to ship one update and one patch to RichTextEditor. What can I say? It was a slow month. :)


I was planning to talk about what I want to get done in 2005 too, but I think I'll wait and make that my next post.

Thursday, December 30, 2004

File Sharing Via RDP

This one might fall into the “I'm the last guy to find this out” category, but given that I'm a regular user of Remote Desktop and I didn't notice it until a friend pointed it out, I'm guessing that others haven't discovered this little gem, either.


If you're connecting via the Remote Desktop Client to another machine, and you want to be able to copy files from here to there, open up “Options” and under “Local Resources” check “Disk Drives”, like so:



Then, when you connect to the remote computer, the remote computer will be able to see your local drives as if they were on the remote computer, making it trivial to drag and drop files via Explorer.

Tuesday, December 14, 2004

I'm Pro-xs:choice

There's been lots of debate about use of DataSets with web services. The issue is interoperability: the default WSDL representation of a DataSet is an arbitrary schema followed by arbitrary XML. That's just a bit on the loose side for most toolkits to deal with in the general case. However, one use case that drives the desire to use a DataSet in the first place is that the type of data to be returned is not known precisely until runtime. Lately, I discovered yet another corner of XmlSerializer that helps me deal with some of these situations without having to resort to using a DataSet.


It turns out that sometimes, although you don't know the exact type of data you'll be returning, you do know that it's going to be one of a known set of types. This is particularly common when you're returning the results of a database query: you might know that all your columns are either strings, booleans, integers, dates, or floating point numbers. If that's the case, there's an XML schema construct that allows you to say, “I want to have one of the following elements appear here.” It's called <xs:choice>, and here's a schema fragment that demonstrates its use:



<xs:element name=“item“>
  <xs:complexType>
    <xs:choice>
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“string“ type=“xs:string“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“integer“ type=“xs:int“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“boolean“ type=“xs:boolean“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“date“ type=“xs:dateTime“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“float“ type=“xs:float“ />
    </xs:choice>
  </xs:complexType>
</xs:element>


What this schema means is that when an “item” element appears, it must have as a child exactly one of the elements <string>, <integer>, <boolean>, <date>, or <float>. Further, if the child element is <string>, the contents of that element must be a string. But if the child element is <integer>, then the contents must be an integer, and so on and so forth. It's a reasonably “normal“ bit of schema, and while I have no idea what the support in various non-.NET toolkits looks like, support for it is a lot more likely to exist than for the vagaries of DataSet.


From an XML standpoint, this is a pretty nice thing. It lets us express exactly what we want, namely, that we'll tell you at runtime what our choice for the type of the data is. Where this gets really great is that it's supported by System.Xml.Serialization, which powers the ASP.NET Web Services stack.


Here's how it maps: you define a class with the usual attributes from the System.Xml.Serialization namespace. But when you get to the element that you want to represent as an <xs:choice>, you simply use more than one [XmlElement] attribute, and you use the overload that lets you specify a type. Here's what I mean:


[XmlRoot(”item”)]
public class Item
{
  private object value; 

  [XmlElement(“string“, typeof(string))]
  [XmlElement(“integer“, typeof(int))]
  [XmlElement(“boolean“, typeof(bool))]
  [XmlElement(“date“, typeof(DateTime))]
  [XmlElement(“float“, typeof(float))]
  public object Value
  {
    get { return value; }
    set { this.value = value; }
  }
}


When the serializer encounters this type during either serialization or deserialization, it will use the attributes to control the mapping between element names and .NET types. Which is to say, when the Value is a float, you'll get <float>, when the Value is string, you'll get a <string>, and (better still) vice versa! You have to do a type test and typecast at the other end, like this:


if (foo.Value is string) { DealWithString((string) foo.Value); }
else if (foo.value is float) { DealWithFloat((float) foo.Value); }
// etc.


But big deal. :)


By itself, this is a fairly powerful feature. And there's still more we can do, but I think I'll stop this entry now while this entry is still reasonably short. More later.