Welcome to MSDN Blogs Sign in | Join | Help

Mark Schmidt's Abode

On Programming, Writing, Gaming, Fitness, Life

News

  • Have a Question?

    Click here to chat with me

    XBox Live GamerTag


    Twitter



    The Mark Cam


    My MoBlog

    www.flickr.com
    This is a Flickr badge showing public photos from codepunk. Make your own badge here.

    Community-Credit

Interested in XSLT?

So I'm back to doing some XSLT work now. I did quite a bit during my work at HP and absolutely love it (don't ask me why). Since I've spent so much time working with it, I've learned a few tips and tricks not covered in a lot of books. So, is there any interest from the people on the intertubes concerning XSLT? If so, comment here or email me and if enough interest develops, I'll get going on it. Or, here's a list of other things I can post about:

  • Transforming multiple XML documents at a time with XSLT
    • Quick code snippet would be a localization pattern with XSLT that will look in 1 XML file for an element and if it can't find it will fallback to a different file for the string
  • .NET within Windows Sidebar
    • I've posted my .NET gadget creator which includes my solution for unloading assemblies from the Sidebar without having to stop the sidebar. However, I haven't gone into detail about how I do it nor have I posted code. Any interest in seeing this?
  • Webcam
    • Any interest in any more webcam stuff? Want me to update it with bugs people have mentioned (ability to select webcam for instance)
  • COM stuff
    • Yes, I still use it. I'm sure I have some code laying around that I can blog about.
  • Game programming
    • I have a pretty cool web based Ajax game I tinker with now and then. I posted 1 entry about it. I can continue with more if any interest. The dynamic server side image generation (which is streamed to the client instead of being placed in a file on the server) would be a good one.
  • A good way to prevent people from downloading images from your web page (still can take a screenshot but this solution is still cool). Related to the above entry.
  • Anything else that I've blogged about that you want more info on?
Skydrive, I Can Haz More Space?

Skydrive yesterday...

image

Skydrive today...

image

Find out more about the new Skydrive release (note, no beta tag anymore) here.

Visual Studio Tip : AutoFormat Your Code

Has this ever happened to you? You find some code on the Net so you copy and paste it into a source file within Visual Studio and notice that all the formatting is somehow messed up. For example. some lines might be indented while others are not.

To have Visual Studio fix it all up nice and tidy for you, select the text, hold CTRL and hit K followed by F (CTRL+K-F). What I usually do is do a CTRL-A to select all text then do the CTRL+K-F combo. Voila!

Embedding Screensaver's in a Windows Form

Awhile ago I created the screensaver Vista Sidebar gadget and promised I would put some code up. As promised, here it is. It's actually quite easy to create something like this, and truth be told I actually had the code lying around for a few years since I wrote it for my 2nd book. Rather than confuse you with any sidebar code, I just created a simple Windows Form that hosts the screensaver UserControl (full source code can be downloaded below).

The hardest part (which is actually somewhat easy) is telling Windows to launch the screensaver within a certain window rather than fullscreen. You've seen this window in the control panel and may have wondered how it's done. To do this, you simply launch the screensaver (.scr file) and pass a command line parameter (/p for preview) and your window handle. The window handle can be accessed in a Windows Form or UserControl through the Handle property.

Below is the code that embeds a screensaver in my custom UserControl. You can see that I first check to see if a screensaver is already running and if it is, I tell it to stop (Kill). I then simply check to make sure my UserControl ScreensaverPath property is set and if it is I launch the executable using Process.Start with associated command line arguments (/p <window handle>).

private void LaunchScreensaver(string args)

{

    try

    {

        if (screenSaverProc != null)

        {

            screenSaverProc.Kill();

            screenSaverProc = null;

        }

 

        if (!String.IsNullOrEmpty(screenSaverPath))

        {

            this.Visible = true;

            ProcessStartInfo startInfo = new ProcessStartInfo(screenSaverPath + args, "");

 

            startInfo.UseShellExecute = false;

 

            screenSaverProc = Process.Start(startInfo);

        }

        else

        {

            this.Visible = false;

        }

    }

    catch (Exception ex)

    {

        throw new Exception("Could not launch screensaver:" + this.screenSaverPath, ex);

    }

}

To wire this up to the Windows Form, I simply expose a property named ScreensaverPath. Whenever the form sets this property, I call LaunchScreensaver and pass the appropriate command line arguments as shown below.

public string ScreensaverPath

{

    get { return screenSaverPath; }

    set

    {

        this.Visible = true;

        screenSaverPath = value;

        LaunchScreensaver(" \"/p" + this.Handle.ToString() + "\"");

    }

}

Here's a couple screenshots of the Screensaver Form project running various Vista screensavers.

bubbles skyrocket

mystify ribbons

As promised, here's the code. Also, one thing to note. Some screensavers don't play nice with the /p parameter. I haven't look into why this is, but in most cases the default Vista screensavers work just fine.

Next "For Fun" Project

For those that follow my crazy forays into stuff that I think is just plain cool, I have begun yet another project. No crazy hacking in the sidebar. No more new webcam stuff (yet). No screen scraping with Outlook calendar appointment setting. I'm off into web land starting an Ajax based RPG similar to a game called Kingdom of Loathing.

It's a turn based RPG whose maps are hex tiles. I'm doing some crazy dynamic image generation and its all stream based so as not to fill up the server hard disk (and to keep memory in check, the stream is closed rather being saved off somewhere like the Session object).

I've opted to go for a pipeline based architecture consisting right now of 2 pipelines. The logic pipeline which will react and update the game variables based on user input and the rendering pipeline which I'm working on now. Since the game has so many different parts (the user avatar, monsters, cities, treasures, inventory, etc...) I wanted to break it down thus leading me to the pipeline. Just to show how easy it is to get something into the dynamic image that is generated by the map, I'll show some really early pre-pre-pre-alpha code here. Here's the main game controller object demonstrating the creation of the rendering pipeline. There are 2 pipeline objects: the map renderer which simply draws the hex grid and then a test object which simply draws a rectangle as a proof of concept. Now that the architecture is in place, it's extremely easy to inject new renderers into the rendering pipeline.

private void LoadGameRenderPipeline()
{
    IPipelineObject mapRenderer = new MapRenderPipelineObject();
    IPipelineObject testDecorator = new MapDecoratorTest();

   
renderPipeline.Add(mapRenderer);
    renderPipeline.Add(testDecorator);
}

Once the logic pipeline finishes, I can then enumerate through all the rendering pipeline objects and tell them to execute in order. I also use something I'm calling a PipelineContext in order for the pipeline objects to share information rather than having each individual object do something stupid like hitting the database, reading from storage, or stuffing everything in the Session object.

Just for fun, here's the Execute method for the MapDecoratorTest object (in the image below, it's the object that drew that red rectangle on top of the map that the MapRenderPipelineObject created). Oh, and disregard the nasty naming convention. It's prototype code :-)

public void Execute(PipelineContext pipelineContext)
{
    MemoryStream ms = pipelineContext["MapImageStream"] as MemoryStream;

 

    Bitmap bm = Bitmap.FromStream(ms) as Bitmap;
    Graphics g = Graphics.FromImage(bm);
    g.FillRectangle(new SolidBrush(Color.Red), 0, 0, 200, 300);
    bm.Save(ms, ImageFormat.Png);
}

Prototype Image

A Christmas Card for my Readers

Most people have seen it at least once in their life. In my family, the picture below is referenced every year. Merry Christmas and Happy Holidays.

-Mark Schmidt

309854993_bba4665187

Oh and a extra special shout out to all the Schmidt's at Microsoft including the 3 other Mark Schmidt's (yes, there are 4 Mark Schmidt's here)!

Check Out Community Credit

I also run a personal blog which I use to post about things that I don't think fall under the realm of "work" although there is still a fair amount of code there too since coding is not only a job, but a hobby as well. More often than not, I'll post a link to my msdn blog on the site pointing user's. One day I received an email invitation from another website that my blog host (geekwithblogs.net) partners with. Since I'm a paranoid user, I approached with trepidation but found out that it actually is a very keen idea and one that I don't mind participating in.

Basically, community-credit.com gives a blogger a certain amount of points for a variety of things (blogging about something is naturally something). While I've looked through the site, I can see a lot of reasons why this is a really good thing. Here's what I've come up with:

1. It encourages you to blog. I've seen a lot of blogs that start with the line "Hello World! I've set up a blog. Expect more soon". This is followed then by crickets chirping and the sound of wind blowing in the background as said person is silent for days if not months.

2. It recognizes those that contribute. The reason I blog is simple: I want other people to know what I know because if it excites me, it'll excite someone else to do further investigation. So let's say I create a cool tool/application/gadget/etc... and blog about it. I'll then get an email or comment that asks me if it can do "such and such". Wow I think. I never thought about that. Let's look into it together. Here's the source code. Use your imagination and see what you come up with. So its this sort if disconnected collaboration and discussion that I find intriguing. It's also one of the main tenants we have here at Microsoft...passion. I'm passionate about development and can talk for hours on end. Give me a new laptop and the first thing that goes on it (after any patches of course) is Visual Studio (followed closely by games naturally for the times my brain is fried).

3. It allows for discovery. The blogging community is exploding at an almost exponential pace. There are a lot of "fluff" blogs out there so any tool that exists to help you weed out the good from the bad is spot on in my opinion. If you blog regularly, chances are you have something important to say. Even if you are what I call a "link blog", you still are informing people.

4. It's just plain fun. There tag line is "Stupid Prizes for Smart People". I tend to disagree with the "stupid prizes" part since what they have on there is everything a geek like me would want. Of course, for the non-geek, yeah, I guess they're pretty stupid though.

I encourage you to check them out. I encourage you to get off your can (or rather sit on your can in this case) and get blogging. You have something important to share (ok, I'm starting to sound like General Patton now). Coding is my life. Sharing information ranks right up there (which is why I also am passionate about writing). It's the exchange of ideas and the personality of developers that sets this industry apart from others. Chances are, my dad, who's a mechanical contractor, doesn't read a lot of mechanical contracting blogs :-)

Last thing, I was chosen as a featured developer on the site. There are greater numbers of developers out there that can code me into the ground. You could be one. Go check them out.

Community Credit News : Welcome to the Developer Community

Good Luck at State Skyline Spartans!

Skyline Spartans LogoMy son's high school (and eventually other 3 kids' high school) is playing in the AAA state football championship game at the Tacoma Dome tonight. I wish them the best of luck. Unfortunately, I can't make it due to other commitments. When I moved up to this area, the Spartans won the AAAA state championship and moved back down to AAA after that. Last year they didn't fare as well but they're back up and running. I coached in the Skyline Spartan youth football program and really feel they're doing the right thing and it shows since this is the 2nd time in the 3 years that I've been here that the high school is playing the championship game.

Tonight's game is a little more exciting for me for one single reason...REVENGE! Let me take you back to 1990 when I was a Junior in high school. I attended Prairie High School (AAA at the time) in Brush Prairie, WA. I was the starting right guard (only junior that started on offense) and we made it to the playoffs. The first round, after having basically been written off by everyone was exciting as we beat a team that was supposed to be the top dog. We then had to travel up north to that field that's right next to the space needle (can't remember the name). Here's the connection, the team we played was O'Dea, the same team that Skyline is playing tonight. I am one that usually accepts a loss as a loss and never complain about the officiating (well, there was that Seahawk Super Bowl thing a little while ago, but that's not the point). It was 4th quarter and we were ahead by I believe 1 point. O'Dea had the ball and the clock was almost out. With the clock winding down, they made a good play to get them in field goal range. The kicker was that they were all out of timeouts and there was only seconds on the clock which means we were about to come away with a victory since it would have been a miracle for them to set up and hike the ball to kick the field goal. So, Murphy's law kicks in and the officials...STOPPED THE CLOCK! Keep in mind, O'Dea didn't have any timeouts left and there was only like 3 seconds left in the game. They stopped the clock allowing O'Dea to setup for the field goal. The officials started the clock, O'Dea hiked the ball and made the field goal to run away with the victory. We were absolutely devastated and frankly we were robbed. We ended up taking 7th in state that year.

Fast forward to 1991 when I entered college as a freshman. As if God was looking down at me to test my adversity, one of my college roommates (I lived in a 4 person dorm) was from O'Dea. He remembered the game and also agreed it was a fluke. Oh well. Tonight will be sweet revenge

C# WebCam User Control Source

Some people have asked if they could take a look at the source for the WebCam Vista Sidebar gadget. After a little bit of cleaning up, I'm posting it now for you to take a look at. Here are some things worth mentioning:

1. Uses the DirectShow.NET library

2. I found some source in VB.NET and used that as a baseline (performed the conversion and cleaned up stuff that really wasn't needed)

3. I am in no way a DirectX/DirectShow expert. Any questions sent my way will likely result in a blank stare back at you :-) (though fwiw, I do pick up things quickly and might be able to at least get you started on the correct path)

4. If you look at the source, you might think "I thought this was a Vista Sidebar Gadget. Where is the gadget source?" That's the easy part. At the bottom of this post is a link to my .NET Gadget Creator application that I wrote (with instructions on how to use it with the WebCam control). That application will allow you to take any .NET UserControl and convert it into a Vista Sidebar Gadget. Just compile the WebCamControl2 control, and use the .NET Gadget Creator to create an instant Vista Sidebar gadget.

5. You may receive an error when you run the provided test application saying something along the lines of "invalid argument". This is a known issue and is happens when more than one application tries to access the same camera. I haven't looked into fixing this so if someone wants to take a stab at it, clue me in on how to fix it.

When looking through the source (there isn't that much to it) pay attention to the 2 primary methods. The first is the GetInterfaces method which creates all the necessary DirectShow interfaces and then creates the connection between DirectShow and your UserControl window (events are passed to the control via Window messages).

The FindCaptureDevice method enumerates through your devices looking for the 1st video device it finds that provides an input (FilterCategory.InputDevice). This is done by creating a device class enumerator. Currently, the source will just grab the first device that it sees. If anyone is interested in knowing how to present the user with a list of all input devices, I can write some code to do that as well. Just let me know.

  103 UCOMIEnumMoniker classEnum = null;

  104 UCOMIMoniker[] moniker = new UCOMIMoniker[1];

  105 object source = null;

  106 

  107 ICreateDevEnum devEnum = (ICreateDevEnum)(new CreateDevEnum());

  108 int hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, CDef.None);

  109 DsError.ThrowExceptionForHR(hr);

  110 Marshal.ReleaseComObject(devEnum);

Once the class enumerator is created, I just grab the first one that was found (assuming one was found) and bind it to an IBaseFilter object which I then return.

  117 int none = 0;

  118 

  119 if (classEnum.Next(moniker.Length, moniker, out none) == 0)

  120 {

  121     Guid iid = typeof(IBaseFilter).GUID;

  122     moniker[0].BindToObject(null, null, ref iid, out source);

  123 }

  124 else

  125 {

  126     throw new ApplicationException("Unable to access video capture device!");

  127 }

  128 

  129 Marshal.ReleaseComObject(moniker[0]);

  130 Marshal.ReleaseComObject(classEnum);

  131 

  132 return (IBaseFilter)source;

Once the video input device is found and we have our base filter, we associate it with an ICaptureGraphBuilder2 object by telling it render a video stream through the preview pin of the input device(line 68 below of the CaptureVideo method).

   51 private void CaptureVideo()

   52 {

   53     int hr = 0;

   54     IBaseFilter sourceFilter = null;

   55     try

   56     {

   57         // create the necessary DirectShow interfaces

   58         GetInterfaces();

   59 

   60         hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);

   61         DsError.ThrowExceptionForHR(hr);

   62 

   63         sourceFilter = FindCaptureDevice();

   64 

   65         hr = this.graphBuilder.AddFilter(sourceFilter, "WebCamControl Video");

   66         DsError.ThrowExceptionForHR(hr);

   67 

   68         hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, null);

   69         Debug.WriteLine(DsError.GetErrorText(hr));

   70         DsError.ThrowExceptionForHR(hr);

   71 

   72         Marshal.ReleaseComObject(sourceFilter);

   73 

   74         SetupVideoWindow();

   75 

   76         hr = this.mediaControl.Run();

   77         DsError.ThrowExceptionForHR(hr);

   78 

   79         this.CurrentState = PlayState.Running;

   80     }

   81     catch (Exception ex)

   82     {

   83         MessageBox.Show("An unrecoverable error has occurred.\r\n" + ex.ToString());

   84     }

   85 }

Now, if you want to use that control in the Vista Sidebar, just download and install the following application:

When you launch the application and click Next it will ask you to add .NET assemblies. Click the Add button, navigate to the WebCamTest or WebCamControl2 bin directory and select the WebCamControl2.dll AND the DirectShowLib.dll assemblies as shown below.

image

Click Next twice to get to the "Select UserControl to Embed". Select the WebCamControl2.WebCamControl2 type and click Next. The next screen allows you to enter the information about the gadget. I provided an icon for you in the WebCamTest base directory. After you fill in the information, keep clicking Next and the gadget will be built for you. Go into the output directory you specified and you'll see the .gadget file. Simply double click on this and if all goes well, you should be looking at your webcam in the Vista Sidebar. Also, since you used the .NET Gadget Creator application, your gadget will uninstall successfully even while it is running (see .NET Sidebar Gadget Creator Update #2 for more information).

Without further ado, here's the link to the WebCamControl source code.

image

NHL Schedule Importer for Outlook Updated

Ok, I've added the ability to fine tune the screen scraping. Sometimes the page I'm scraping changes just a bit which messes up the scraping that I'm doing. I've added a numeric up/down control which tells the app which table index on the page to scrape. If you select a team and you don't see a schedule appear, you'll receive a warning and instructions telling you to adjust the table index. Hopefully this will make it so I don't have to update the app as much.

Here it is:

Want your question answered quick?

Today, Microsoft announced the new Windows Live Messenger IM Control and Presence API. This is just way cool. I'm going to try it out on my blog to see how it goes. If you look on the left side, you can see my status under the News heading. Just click to talk to me.

Want to use it for your blog? Go here.

My current status is:

Updated NHL Schedule Outlook Importer

The nhl.com web page changed and since my app is a screen scraper, it broke.

Here's the current working version. The installer should remove your old version and install the new version.

New & Improved NHL Schedule Importer for Outlook

*EDIT* Looks like the nhl.com scheduling page has changed thus breaking my importer. I'm working on a new version but no idea when it will be done. I've taken the link down.

Ok, I redid the whole application (since I lost the source code) and added some new features as well. The previous application utilized XML which required you to actually get the NHL schedule in XML format somehow (I used Excel). Needless to say, it was a long and complicated process.

This new version utilizes good old fashioned screen-scraping to get the job done. Here are some key features that I've added:

1. Location field will tell if the stations the game is on for national and local (both away and home team) markets

2. The body for each appointment when you open it up in Outlook contains links to each teams website as well as links to subscribe to that team's RSS feed (see screenshot below)

3. ** Here's the cool feature ** After you ran the application and import your team's schedule, you can run the application at a later date and it will not create duplicate entries. In fact, if you run it a second time, it will add the game's final score and a link to show the recap of that game (again, see screenshot).

4. You know have the ability to add an outlook reminder or not for each game

5. UI is prettier. When you select a team from the drop down list, it will fetch that team's logo from the web and full team name (see screenshot).

6. Internally everything is different. It would have been easy to allow you to select a year (e.g. 2008-2009) but I'll wait to add that. In any case, whenever a new NHL schedule is created, it's a trivial change to get the application to work with it.

*NOTE* I tested this using Vista and Outlook 2007. If you have any issues when importing your team(s) schedule(s), let me know. It helps if you can send a screenshot or any error messages word for word. For developer types who know what a call stack is, send that as well if you can.

Here's some screenshots followed by the link to download the application (complete with installer)

importing

appointment

 

 col GO AVS!!! col

Working on new NHL Schedule Outlook Importer

I decided to revamp my NHL Schedule Outlook Importer application. By revamp, I mean start over (since I lost the code anyway). No more messing around with excel and XML. Going to do some good ol' fashioned screen scraping. It should be ready to go by tomorrow so keep an eye on this page. Here's a teaser screenshot.

colorado_schedule

Master Chief and my Son

So I attended the launch party at Best Buy in Bellevue. I decided to bring my 15 year old son along and he had a blast (I did too). Got plenty of free swag to take home so I was able to spread it around my 3 other kids (I kept the hat and new Halo novel). Haven't gotten to play the game yet and might not until Friday. Here's my son with his hero of the day.

Jordan_Master_Chief

More Posts Next page »
Page view tracker