Monday, April 2, 2012

AFX MFC Team Photo from Microsoft, circa 1992

I thought I had lost this photograph from 1992, but I recently discovered it in a box in the garage.  I should have had it framed and will do that soon!



This picture is from my days at Microsoft, where I worked on the AFX (Application Frameworks) team that produced MFC, the Class Wizard and Application Builder in Visual C++.  I believe this photo was taken right after we shipped MFC 1.0 in the Microsoft C/C++ 7.0 product in 1992.  We had a group outing to celebrate and also make plans for the next version.  They gave us all AFX t-shirts to wear, which was really cool because it looked like the logo for the Terminator 2 movie from the previous year.

Bottom row: Dean McCory (who took over MFC lead development with version 2.0), Brian Meyers, Jeff (our fearless leader).  The fellow with the freakin' huge laptop was one of the managers.  Towards the right I see Alan and Mark.

Middle row: Steven Sinofsky (second from left), Greg DeMichillie, Neil Smith (my first manager), more people I cannot recall except for Marco Ceriotti and Kathleen Thompson towards the right.

Back row: Cliff, Scott (the first AFX/MFC guru), Lon Fisher in the middle, me with the big forehead, Alan Bauer next to me.  Bob Anderson (my second manager) on the far right.

I remember conversations and activities with all of these people, but I wish I could also remember all their names.  Those were great days and I am still proud of the work we did as a team.  Nuff Said!

Tuesday, May 10, 2011

Crystal Image Toolkit for C# Windows Forms: 1.0.1 Release for Visual Studio 2010, .NET Framework 4.0


Crystal Picture Show Demo
Regrettably, I haven't made any updates on the Crystal Image Toolkit for a long while.  After WPF and XAML applications took the lead in graphical user interfaces, I lost some of my motivation to keep on improving the toolkit.  However, there are still plenty of Windows Forms applications out there and I am getting ready to produce some new tools in this area myself. 

I've updated the source code for all the toolkit and the demos to Visual Studio 2010 and .NET Framework 4.0.  A couple of minor bug fixes are included along with some code cleanup courtesy of ReSharper. 

You might ask: why .NET Framework 4 instead of .NET Framework 4 client profile?  Because I used log4net in the Crystal Toolkit, this would not compile under the .NET 4.0 Client profile.  It requires the full .NET 4.0 package.  See Tseo's blog for more details.

Visit the new SourceForge page for the Crystal Image Toolkit.  You can download the 1.0.1. version there and any new updates in the future.

Tuesday, November 17, 2009

A Simple Way to Change the Color of a Highlighted List View Item in XAML


I haven’t worked with Windows Forms that much since last December.  This year, I’ve worked on projects that involve ASP.NET, Linq to Sql, and web services.  I’m currently taking a class in WPF from Foothill College—you can visit Cal Schrotenboer’s page to see a description of the classes offered.  The classes are all conducted online and you don’t have to travel to the campus at all.  In addition, you can join the MSDN Academic Alliance program and get access to Microsoft software (include Expression Studio and Windows 7).

Learning WPF has been extremely fun and rewarding, but at times, frustrating!  I’m trying to do as much in XAML as possible.  I am doing an Image Viewer for my last class project, making great strides in some areas—and then getting stuck when I try to add what must be the most simple feature ever: changing the ListViewItem selected color. 

But due to my ignorance a simple task can take hours!  My only desire was to see the color of selected items changed to something other than the default.

My first take—which led me down the wrong path—was to add a Style Trigger.  The Trigger would set the Background color when IsSelected was true on the ListViewItem.  Or so I thought!

<Style TargetType="{x:Type ListViewItem}">
<Style.Resources>
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="DarkCyan" />
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="Red">
</Setter>
</Trigger>
</Style.Triggers>
</Style>

Nope, no matter how I tried to massage that, it didn’t work.  Even more frustrating, I changed IsSelected to IsMouseOver and that worked fine.

As William Han explained to me on .NET Developer Forums, ListViewItem's base type ListBoxItem changes a Border background in control template instead of ListBoxItem.Background on the selected item.  William suggested a workaround could be modifying SystemColors.HighlightBrush since ListBoxItem's control template uses it.

Here’s what did work:

<Page.Resources>
<Style TargetType="ListViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>
</Style.Resources>
</Style>
</Page.Resources>  
<Grid>
<ListView>
<ListViewItem>Item 1</ListViewItem>    
<ListViewItem>Item 2</ListViewItem>
<ListViewItem>Item 3</ListViewItem>    
</ListView>
</Grid>

It’s a brute force method—changing the highlight color for all ListViewItem objects, but it works, as you can see by the Kaxaml screenshot on top.

Tuesday, August 18, 2009

Cory Doctorow's Little Brother and the Sony PSP as an E-Book Reader


Here's a roundabout story about I've reinvigorated my Sony Playstation Portable, which would not have been possible without Cory Doctorow's excellent novel, Little Brother.

I've been flirting with the Amazon Kindle for months ever since it went on sale.  It's a cool device for a book lover.  Imagine being able to carry around tons of books everywhere you go.  Being able to download a book after reading a review in the Sunday newspaper.  It's fantastic...except for the limitations.  DRM on the books that you download isn't very cool.  I think what really galls me is that Amazon charges for downloading blogs (via RSS) when you can easily get them for free online.  Charging to email/convert documents to the Kindle device is another thing I cannot understand.  Combine all of these things with the high price of the Kindle and I just cannot make that purchase.

Which made me turn to my Sony Playstation Portable.  I've let this device languish for the past two years after I stopped commuting to San Francisco on BART.  In the back of my mind, I've had this idea that the PSP, with it's brilliant screen display and brightness controls, could be a great e-book reader.  After visiting Cory Doctorow's Little Brother download page, where he provides the novel in a variety of formats (under Creative Commons license), I finally decided to give it a try and see if one of those would work on the PSP.

The result is that none of them worked that well.  It's amazing that after being first sold in 2005 in North America, the Sony PSP still does not have an Adobe PDF Reader.  I found one that used to work, but apparently not on firmware 4.05.  I suppose I could have gotten that to work if I flashed the PSP with a hacked set of firmware, but I want to keep up with the official builds from Sony, as I have a Playstation 3 and want to use my PSP in conjunction with that. 

Next, I tried the HTML version of Little Brother, which I copied over to the PSP/COMMON folder and pointed the PSP's browser at that location.  The HTML version looked superb, the text was very readable, and you can increase/decrease the text size very easily.

However, there were some problems with reading books in HTML format on the PSP.  Paging/scrolling to see the next page is a pain, when you must use the arrow keys on the left hand side of the device.  If the entire book is in one HTML file, you cannot jump between chapters that easily.  When I stopped near Chapter 3, then the next time I started the PSP, I spent a long time scrolling down (using square button + down) to get to that section.  I read that some Sony ebook fans will break up novels into several HTML chunks and link the whole thing together in an index file.  Too much work for me!




A friend of mine suggested converting the document into a series of JPG files and using the Sony PSP Photo/Image viewer.  I was really dubious about this until I found the PSP EBook Creator on download.com.  What the heck, I decided to give it a shot.  The PSP E-book Creator takes a text file file as the input/source, parses it and creates a series of JPG images.  It gives you a number of options for formatting the text: you can choose the font that you want, the font color, the background color, etc.  It may take a while to determine the best font to read on the PSP screen, I've found that either Arial or Verdana works best for me.

The e-book creator parsed and split the Little Brother source text into 897 jpg files, which I copied over to the PSP's PHOTO folder, under a subfolder called LB.  When I turn on the PSP, I simply navigated to the Photo slot, select Memory Stick, select the LB folder, select page 1 and pressed X.  Voila, the first page appears and it's easily readable.  To go to the next page, you just press the right shoulder button on top of the PSP.  The PSP can easily be held in one hand with a finger resting on the next button to advance pages.  The left shoulder button allows you to go to the previous page.

Several things are great about this.  Little Brother took up about 40 mb on my Sony Memory stick, which is pretty small.  Having the book split up into X number of jpgs allows you to quickly find the last page you were on: just press the down arrow to scroll down quickly to page 222 or whatever.  The Sony PSP has a brightness control on the front that allows you to see the screen during the daytime or at night.  This is really convenient if you're reading in bed and don't want to disturb your partner with a bright screen--the lowest brightness level works perfectly in total darkness.  You have no idea how long I've searched for a solution to this problem! 

What are the disadvantages of this method?  There are two big ones.  You can't customize the text size dynamically, and the glassy Sony PSP screen is not readable outdoors in the sunlight, due to the glare bouncing off the screen.  I usually read indoors, so this is not a problem for me.

Unlike the Kindle, where finding/downloading books is a breeze, finding content to download and convert is a challenge, as not every author is as generous as Cory Doctorow.  But if you're used to downloading other media, you can find content to use with the PSP E-Book Creator, although usually the content will need to be converted to text.  You can look for books that are in RTF or HTML format and convert to text using a number of programs (Internet Explorer, Firefox, Microsoft Word, etc).  Books in PDF file format can also be converted to text.  You can also find books in the Microsoft Reader format (.LIT files), and use the free ABC Amber LIT Converter program to convert them.

I've got about a dozen books, many of them recent books that I purchased in hardback (plus all of Doctorow's other novels), on my Sony PSP.  I bought a SanDisk 4 GB memory stick for about $40 on Amazon to hold this content, along with 12 episodes of LOST and a number of comic books that I want to read on my next vacation.  With all this content available, playing games on the PSP seems like a bonus feature.

Little Brother is a very engaging book, I devoured it in a couple of days after getting on my PSP.  Little Brother is a young adult novel (although just as good for adults) about a high school kid named Marcus Yallow (aka w1n5t0n) in San Francisco. San Francisco is attacked by terrorists and the Department of Homeland Security swoops in and starts heavily monitoring all citizens. Marcus fights back against the DHS by hacking his Xbox with an operating system called "Paranoid Linux" and inspiring a group of young techno-geeks to help him out.  I highly recommend it.

Link: PSP E-Book Creator
Link: ABC Amber Lit Converter
Link: Cory Doctorow's Craphound
Link: Little Brother site

Sunday, December 7, 2008

Crystal Image Toolkit on CodeProject and Index to my C# articles on building Image Viewers

Yesterday, I placed version 1.0.0. of Crystal Image Toolkit on CodeProject with an expanded version of the tutorial.

If you’re visiting here from CodeProject, here is an index of articles I’ve written about misc features in the Crystal Image Toolkit:
  1. Using Crystal Image Toolkit for C# Window Forms to Create an Image Viewer with Thumbnails.
  2. Scaling Thumbnail Images with C# Windows Forms using CrystalImageGridView .
  3. Crystal Image Toolkit: Thumbnail Scaling, Image Panning Controls in C# .Net .
  4. Header Groups for Image Thumbnail Grid View.
  5. Crystal Image Toolkit for C# Windows Forms: New Samples Illustrate How to Create Image Grid Viewers .
The articles may refer to earlier versions of the toolkit, please ignore and use the latest version.  The samples included in the toolkit will give you a better idea of how to use the various features mentioned in the articles.

Download: Crystal Image Toolkit 1.0 from Google Docs.   Totally free, open-source, C# .NET Framework 2.0 for Windows Forms.

Saturday, December 6, 2008

Tutorial 1: Using Crystal Image Toolkit for C# Window Forms to Create an Image Viewer with Thumbnails

Part one of a series of tutorials explaining how to use the Crystal Image Toolkit.  In this example, I will show you how to quickly add an image thumbnail control to your Windows Form application.  Compile the code using the solution that I provided. 




Create a new Windows Forms application in Visual Studio. In the Visual Studio toolbox, add a new tab called Crystal Image Toolkit (to separate it from Crystal Reports) and add the controls found in CrystalToolkit.dll.



Select the control called “CrystalImageGridView”.  This is the control that displays the thumbnail images.  Drag this control onto your new Form.




Now go to the Properties window, with “crystalImageGridView1” selected.  Change the Dock property to Fill.  Change the Orientation property to Vertical.




After you set the properties, the image grid control should look like the above picture.  The blue borders simply give you an idea of what the image items will look like in the selected state.  The broken image bitmap is just a placeholder.  At runtime, your images will be placed inside this blue rectangle.  Yes, you can change many other properties, including the border color, background color, and so on.  But for now, let’s accept the defaults.

Let’s write a little bit of code.  Go to the events tab and double click on the Load event of the Form.  Now that you are in Form1.cs, let’s add this field:
   1: /// <summary>

   2: /// CrystalCollector object, assists in retrieving image files in a specified folder.

   3: /// </summary>

   4: private CrystalCollector _theCollector = null;

The CrystalCollector object is the controller in this framework. 

The collector works with the CrystalImageGridView and the CrystalImageGridModel.  It finds image files set in the ImageLocation property, creates objects to mirror those files as CrystalImageItem objects, and places those within the model.  The collector spawns a background thread to start thumbnailing the image items; this thread sends events to the view to tell it when an image thumbnail is available.  That is what happens behind the scenes, but here in this simple example, you only need to add this method for your Form:

   1: private void InitCollector()

   2: {

   3:     _theCollector =

   4:         CrystalCollectorFactory.DefaultFactory.CreateCollector(CrystalCollectorType.CrystalFileCollector);

   5:  

   6:     // Add the CrystalImageGridView object to the collector.

   7:     // The collector will work with the view to draw the images.

   8:     _theCollector.SetupView(crystalImageGridView1);

   9:  

  10:     // Optional:

  11:     // Set an initial folder to collect images.

  12:     // If no folder is set, collector starts at MyPictures in WinXP or Pictures folder in Vista

  13:     //CrystalCollectorFactory.DefaultFactory.InitCollectorSource("c:\\myImages", _theCollector);

  14:  

  15:     // Tell CrystalFileCollector to collect the images in the ImageLocation folder.

  16:     _theCollector.CollectImages();

  17: }

  18:  

  19: private void Form1_Load(object sender, EventArgs e)

  20: {

  21:     InitCollector();

  22: }

  23:  

  24: protected override void OnFormClosing(FormClosingEventArgs e)

  25: {

  26:     if (_theCollector != null)

  27:     {

  28:         _theCollector.StopCollection();

  29:     }

  30:     base.OnFormClosing(e);

  31: }

InitCollector creates the collector object using a factory.  The type it chooses is a file-based collector.  You could just create a new CrystalFileCollector yourself, but it is better to use the Factory.  This can be used to track down objects getting created/destroyed later.



Once the collector has been created, we call SetupView, passing in the CrystalImageGridView object that we dropped onto the Form.  This must be done before we gather any images.  The collector creates a CrystalImageGridModel object and links up the view to it.  The model must know about certain view properties, which affects how the image items will be displayed.

CollectImages is called at the end, which tells the collector to look at the ImageLocation and start gathering data about the images found there.  In this case, we did not set the ImageLocation—the default is set to your Pictures folder (on Vista) or MyPictures folder (in WinXP).  If you want to initialize another ImageLocation, use the code I commented out above the call to CollectImages.

Form1_Load calls InitCollector.  But there’s also the override to OnFormClosing, which calls the StopCollector method on the collector object.  This call will stop any background threads going on to thumbnail the images.



When you press F5 and run, you should see the thumbnails for whatever images are in your Pictures folder.  Hopefully, they will be images of friends, family, and pets instead of comic book images!  Play around with this form—you should see that the control responds to resizing events, making the number of image items per row grow or shrink the form.  You can do ctrl-click and shift-click on image items for multiple selection as well.


Where are these thumbnail images stored?  The CrystalThumbnailer object, which does the work of creating them, has a property called ThumbnailLocationRoot.  By default, it is your AppData folder, under the name of your Company and Product name.  The collector creates a sub folder here, based on the hash number of the original location.  It stores the thumbnails here—the largest thumbnail size it needs to display.  In these simple demos, the thumbnails will exist permanently.  I’ve decided the behavior to retain or erase them is application dependent and left the choice up to you.

This is obviously a very simple example, but I have included many sample Form applications in the toolkit.

SimpleImageGridDemo shows a slightly more complex version of this application, by allowing you to open any folder and view the thumbnail images.


PictureShowControllerDemo shows you how to create a more realistic picture viewing application.  A split container is used to hold the CrystalImageGridView in Horizontal orientation on the bottom pane.  The top pane contains the CrystalPictureShow control, which is used to display images, magnify them, and present slideshows.  There’s also a panning window that appears whenever the image is displayed in a non-fit mode.

Download: Crystal Image Toolkit 1.0 from Google Docs.

Crystal Image Toolkit for C# Windows Forms: 1.0.0 release, Factory and Refactoring


Crystal Image Toolkit 1.0.0 is ready to download.

Enhancements:

Factory object:  CrystalCollectorFactory was added to allow you to create the correct collector objects based on file or folder input.  Using this factory will help keep track of when objects are created. 
CrystalCollector: added StopCollector as a pure virtual method.  StopCollector stops the collection operation initiated by CollectImages.

CrystalCollector:  SortCrystalList with CrystalSortType.DisplayName will now sort the image items with case insensitivity.  This sort option uses DisplayNameLower property in CrystalImageItem.

CrystalImageItem:  Added ImageCorrupted property.  True means image is corrupt and cannot be displayed, false means it is safe to display.

CrystalImageItem:  Added DisplayNameLower property.  Takes the DisplayName string and does a ToLower call.

CrystalImageItem, CrystalCollector, and CrystalImageGridModel all implement IDisposable.  This objects hold references to Image objects, which can now be disposed of more efficiently.

Event notification: All events are now broadcast using the EventNotifier class.  This utility walks through the invocation list of a multi-cast delegate and checks to see if InvokeRequired is true before calling the delegate.

Code Cleanup:

Exception Handling Refactoring: Previously, the Crystal  Image Toolkit was eating all exceptions.  This was a bad practice and actually hid threading errors that were occurring in the forms and controls that were using the toolkit.  Now those exception handlers have all been removed, except for one in CrystalFileCollector:  LoadImage.  The exception here is caught when an image is corrupt and cannot be loaded from the disk.  In that case, ImageCorrupted in CrystalImageItem is set to true, see below.

CrystalCollector: AddView method was removed.  I had intended to support multiple views, but I need to wrap up this toolkit for the time being and move on to other projects.  Only 1 view is supported.  AddView has been changed to SetupView.  The internal list of views has been removed.

Download: Crystal Image Toolkit 1.0.0.  Totally free, open-source, C# .NET Framework 2.0 for Windows Forms, works with both Visual Studio 2005 and 2008.