PETZOLD BOOK BLOG

Charles Petzold on writing books, reading books, and exercising the internal UTM


Recent Entries
< PreviousBrowse the ArchivesNext >
Subscribe to the RSS Feed

SpinPaint for Windows 8

October 1, 2011
Roscoe, N.Y.

Recently I've been trying to remember the last time I wrote a program that targetted the native Windows API. I think it was 2002, when I used C and the Win32 API to write the last of a series of programs for the PC Magazine Utilities column. But even at that time, I had already moved on. In the summer of 2000 I was introduced to the .NET Framework and the marvelous language C#. I became a strong advocate of managed code, and I really haven't had any reason to return to the world of message loops and wayward memory pointers. I already paid my Windows API dues, and plenty of them.

But the Windows API is now changing. A couple weeks ago I was among the 5,000 attendees at the Microsoft Build conference in Anaheim, where the big focus was on the forthcoming (meaning maybe next year) Windows 8. Speaking as someone who has been using Windows and coding Windows applications since before Windows was released in 1985, I can say without exaggeration that Windows 8 represents the most revolutionary change in the Windows user interface and application programming interface since that time.

The UI style has been dubbed "Metro," so-called because the use of unadorned fonts and clean styling is characteristic of design in metropolitan environments. For users of Microsoft products, Metro was first introduced on Windows Phone 7, and its incorporation into Windows 8 represents a very interesting trend: In years gone by, Microsoft attempted to move the design of the Windows desktop down to smaller devices such as hand-held computers and phones. Now a user-interface design for the phone is being moved up to tablets and the desktop.

I think this is a good trend. Multi-touch is becoming pervasive, and has really changed the relationship between human and computer. In fact, the term "multi-touch" is now outmoded because virtually all new touch devices respond to multiple fingers. The simple word "touch" is now sufficient.

Along with the change in the UI, the Windows 8 API also represents a strong break with the past. Of course, the Win32 API is still available for anyone who wants to code "old-style" desktop applications, and these will still run under Windows 8. For writing "Metro style" applications, the programmer has three basic options: using C++ with XAML; using C# or Visual Basic .NET with XAML; or using HTML 5 and JavaScript. (Much more information can be found at the Metro style app development portal.)

Part of the core .NET Framework has been incorporated into Windows 8, as well as an additional .NET-like framework known as the Windows Runtime or WinRT.

WinRT is very similar to Silverlight. Programmers familiar with both the Windows Presentation Foundation (WPF) and Silverlight (which is roughly a subset of WPF with an emphasis on the roughly) will recognize the kinship with Silverlight immediately: WinRT has the familiar DependencyProperty class, but no way to create a read-only dependency property. WinRT has the familiar UIElement and FrameworkElement hierarchy but there's no virtual protected OnRender method in FrameworkElement. The WinRT version of FrameworkElement has a RenderTransform property but no LayoutTransform. Like Silverlight, there's no Freezable class in WinRT. The multi-touch Manipulation events are at first glance much closer to the Silverlight versions that the WPF versions. (You can explore WinRT yourself at the Windows Runtime reference.)

One of the major cosmetic changes between Silverlight and WinRT are namespace names: rather than System.Windows.Blah.Blah.Blah we now have Windows.UI.Xaml.Blah.Blah.Blah. The core .NET namespaces retain the familiar namespace names such as System and System.Collections and System.IO but there are also other new Windows namespaces, including Windows.ApplicationModel.*, Windows.Devices.*, Windows.Foundation.*, Windows.Media.*, Windows.Storage.*, and a small but surprisingly named Windows.System namespace.

To some observers, technology is a zero-sum game, so any introduction of a new technology necessitates the "death" of some older technology. Consequently, you've probably heard that WPF is dead, or Silverlight is dead, or .NET is dead. (But not, oddly enough, that Windows XP or Windows Vista or Windows 7 is dead!) But it's hard to consider WPF or .NET to be dead when a developer preview of .NET 4.5 has just been released, and it's hard to consider Silverlight to be dead because it's for a different platform — the Web rather than the desktop or tablet — and the basic Silverlight API is now part of Windows 8.

At any rate, I'm not a pundit. I'm just a programmer, and I like the idea of coding for the native API of Windows 8 using my favorite programming language (C#) and managed code, while targetting a familiar framework (.NET and something akin to Silverlight). This is not to say there aren't compelling reasons to write Metro-style applications using C++, or the combination of HTML 5 and JavaScript. Perhaps in the future I'll find those reasons compelling enough to explore the alternatives.

What made it easy for the 5,000 Build attendees to experiment with Windows 8 programming were the free Samsung tablets we were given. (Of course, after I spent nearly $3,000 to attend Build, it wasn't clear to me that the word "free" was entirely appropriate.) These tablets were preloaded with the developer release of Windows 8, a bunch of sample applications, and Visual Studio 11 Express for Windows Developer Preview. (Of course, the developer release of Windows 8 and all the tools are downloadable and installable on other machines.)

The "Build tablet" came with a Bluetooth keyboard and a docking port with an HDMI output for an external secondary monitor. Monitors with HDMI inputs generally have resolutions of 1920 × 1080 and are available for under $200. Add a USB mouse, and you have a nice Windows 8 development setup. The Samsung table has a 10-finger touch screen and a stylus as well, so you can test your programs with the pointing triumvirate: mouse, stylus, and touch.

For my first non-trivial Windows 8 Metro-style application, I decided to port a program called SpinPaint. As I discussed in a May 2010 blog entry, SpinPaint originated as a Microsoft Surface application, which I then ported to Silverlight for Windows Phone (where the performance was unsatisfactory), so I rewrote it for XNA for Windows Phone, where it appeared in my Windows Phone book, and then I spruced it up for my first Windows Phone marketplace submission, as described in a November 2010 blog entry.

SpinPaint simulates a spinning disk that you can paint on with your fingers. The color of the paint cycles through the rainbow every 10 seconds, and what makes the program a little more visually interesting is that the spinning disk is divided into four quadrants, and whatever you paint with your fingers in one quadrant is duplicated in mirror images in the other three quadrants.

The Silverlight version of SpinPaint used a WriteableBitmap to accumulate the "paint," and the first thing I noticed in the WinRT version of WriteableBitmap was the absence of a Render method. The Render method lets you render the visuals of any UIElement derivative on the bitmap, so it's fairly easy to paint polylines on the WriteableBitmap using individual Line elements with rounded ends.

Interestingly, the absence of a Render method in the WinRT WriteableBitmap was not a deal-killer for me. I already had code that could render straight thick lines with rounded ends on a bitmap by calculating the actual pixel bits. I developed that code to draw lines in some of my XNA programs for Windows Phone; in fact, these classes (RoundCappedLine, LineSegment, and ArcSegment) were part of the XNA version of SpinPaint.

The Silverlight version of WriteableBitmap has a Pixels property that's an array of integers that lets you address individual pixels of the bitmap. The corresponding property of the WinRT version of WriteableBitmap is PixelBuffer and it's of type IBuffer, a new WinRT interface defined in the Windows.Storage.Stream. But I had a true "Why The Face?" moment when I discovered that the IBuffer interface is defined with only two properties, both integers: Capacity and Length. Dude, where's my pixels?

Someday I'm sure the other classes in Windows.Storage.Stream will be totally comprehensible to me, but the lack of documentation was a problem, and they seemed to offer no solution. Fortunately a thread in an online MSDN forum provided a couple crucial clues: Wes Haggard and Joe Stegman of Microsoft pointed out the existence of an extension class in the System.Runtime.InteropServices.WindowsRuntime namespace with an AsStream method that lets you access the IBuffer pixel bits as a Stream object. (Thanks, guys!) But the little example using the WriteByte method of Stream should be ignored for any application that requires speed. Use Write instead. (And why is such an important method is an obscure extension class?)

Here's how it's done: After creating a WriteableBitmap, also create a pixels array and get a Stream from the bitmap's PixelBuffer property:

WriteableBitmap bitmap;
byte[] pixels;
Stream pixelStream;
....
bitmap = new WriteableBitmap(width, height);
pixels = new byte[4 * bitmap.PixelWidth * bitmap.PixelHeight];
pixelStream = bitmap.PixelBuffer.AsStream();

The WriteableBitmap object always has a 32-bit pixel format. The following method sets a pixel to a particular color:

void SetPixel(int x, int y, Color clr)
{
    int index = 4 * (y * bitmap.PixelWidth + x);
    pixels[index + 0] = clr.B;
    pixels[index + 1] = clr.G;
    pixels[index + 2] = clr.R;
    pixels[index + 3] = clr.A;
}

When you need to update the WriteableBitmap from the pixel array, use the following code:

void UpdateBitmap()
{
    pixelStream.Seek(0, SeekOrigin.Begin);
    pixelStream.Write(pixels, 0, pixels.Length);
    bitmap.Invalidate();
}

You might be able to reduce the range you're updating by specifying a different starting index and buffer length in the Write call, but the Write call is very fast regardless.

The other big change I needed to make from the Silverlight version of SpinPaint was the input handling. SpinPaint has some special needs: If you just put your finger down and hold it, your finger continues to draw as the disk spins. Yet, the program is getting no touch events during this time because your finger isn't moving.

For this reason, SpinPaint processes touch-down, touch-move, and touch-up events by simply accumulating the current and previous positions of all the touching fingers in a Dictionary<uint, FingerInfo> object, where the key is the ID of the finger, and FingerInfo is a simple internal class with ThisPosition and LastPosition fields of type Point.

The WinRT API does not support the Silverlight Touch.FrameReported event necessary for tracking the motion of individual fingers. Nor does WinRT support the WPF TouchDown, TouchMove, TouchUp, TouchEnter, and TouchLeave events. Nor does WinRT have any mouse events!

In one of the boldest — and to my mind, furthest thinking — decisions, WinRT consolidates mouse, stylus, and touch input in a single set of Pointer events (and corresponding protected methods): These are all defined by UIElement and include PointerPressed, PointerMoved, PointerReleased, PointerEntered, PointerExited, PointerWheelChanged, PointerCaptureLost, and PointerCanceled (which indicates an abnormal condition). In addition, UIElement defines device-independent Tapped, DoubleTapped, RightTapped, and Holding events as well as a set of Manipulation events that consolidate multiple fingers into single manipulations.

In this way, you can code your Pointer handlers for touch, and you get mouse and stylus support for free. (One of the buzz phrases at Build was the idea of a "touch first" environment, where touch is the primary means of input.) That's what SpinPaint does, so you can also use the mouse and stylus for painting. If necessary, a program can determine what type of device the Pointer input is coming from, and obtain lots of detail about touch and stylus pressure and other information if the hardware supports it.

Metro style applications are generally full-screen applications with a very clean uncluttered layout and little "chrome." Here's what SpinPaint looks like running on the 1366 × 768 display of the "Build tablet," reduced to half-size so it's not ginormous:

Actually, that "clear" button shouldn't even be part of the screen. That should actually be in a Windows Phone-like application bar along with a "save" button. Also you should be able to share these images, for example, by sending them to someone via email or posting them to Facebook. Perhaps I'll add those feature at a later time. (Perhaps this afternoon.)

Meanwhile, here's the SpinPaint source code. One warning, though: I haven't been able to run this program more than a couple minutes at a stretch without getting a random crash with a message box in Visual Studio that looks like this:

Do you know what I say when I get a random crash in a developer preview operating system (perhaps a year away from release), particularly one that refers to a COM interop? I say "Not my fault."


Comments:

Try disabling the MDA - perhaps the error is with MDA rather than exe?

http://msdn.microsoft.com/en-us/library/d21c150d.aspx

Miha Markic, Sun, 2 Oct 2011 04:25:14 -0400

Thanks for the tip on AsStream. I just finished porting a WriteableBitmap sample of my own and you saved me a ton of time. Why is this an extension method???

— Jeff Prosise, Tue, 4 Oct 2011 09:30:30 -0400

you are aware of the influence of your books on the world of windows programming and i wonder if you have an opportunity to write a new windows programming book like your famous one "Programming Windows®" that target the details of windows 8 programming ... i dream of a book that target winrt using c++/cx. do you think such project is possible ? are you willing to consider such a book ?

thank you.

Saif, Tue, 4 Oct 2011 12:58:47 -0400

I would love to write a book about Windows 8 programming. But book sales are not what they used to be, and it's not clear to me that such a book would be economically feasible. I have real doubts that I can spend a year writing a Windows 8 book without suffering severe financial hardship. — Charles

Charles

You wrote "Of course, after I spent nearly $3,000 to attend Build..."

I can't believe you didn't get to go for free!! When are Microsoft going to start paying you for you efforts in getting the world developing software for windows? Personally, I'm thinking of switching to Apple, so can you write a book on developing for that platform, as I will only buy programming books written by you?

Apple only have a small set of well tried (albeit user unfriendly), developer tools, and they have existed for years. It sometimes seems that Microsoft bring out so many technologies that it is difficult to know where to start! Then when you finally master something - windows forms, silverlight, wpf for example - Microsoft tell you to forget that, we've got something new for you.

— Mr Gutbucket, Thu, 6 Oct 2011 15:58:32 -0400

Very many years ago, PC Magazine would pay for its Contributing Editors (also known as "freelancers") to go to Comdex (remember Comdex?), and often Microsoft System Journal paid my way to Redmond to learn new technologies at Microsoft. But times have changed. These days MSDN Magazine (MSJ's successor) barely pays for articles!

A couple years ago, Microsoft MVPs (of which I am one) got to go to one of these conferences (the PDC I believe) at about half-price. That was nice. Also, one of the benefits of conducting a full-day Pre-Conference Workshop at an event (which I've done twice) is attending the rest of the conference for fee.

These days a very large number of people — particularly MVPs who blog about coding for Microsoft environments or participate in online forums — might legitimately claim that attending a conference for free is in Microsoft's best long-term interest. I don't think I'm special in this respect. In fact, developers these days often learn more from blogs and forums than books, so I'm probably pretty low in the pecking order for claiming a right of free attendance! — Charles

How about in your blog site to let people to donate to see if it is economically feasible for your win8 book

— Joe, Fri, 7 Oct 2011 00:00:44 -0400

Traditionally, a publisher pays an author an advance on royalties while a book is being written. Commonly a publisher calculates the advance based on royalties of the projected sales of the book over the first year. After the book is published, further royalties aren't paid until the advance is paid off. Very often, the book never makes back the advance, so additional royalties are never paid. (Some book contracts even require the author to pay back part of the advance if sales are poor, but I've never signed a contract as vile as that!)

If an author believes that a book will sell more copies than the publisher projects, the author might accept a low advance with the expectation that future royalties will come pouring in later. Or, the author might accept a low advance if the author really, really, really, really wants to write the book. But in reality, the author shouldn't expect any money beyond the advance.

I tend to be an optimist, so I always believe publishers are under-projecting sales of my proposed books. But I've been wrong. I went broke — and actually beyond broke — writing two books back-to-back that required a great deal of work accompanied by very modest advances. These were 3D Programming for Windows and The Annotated Turing. So far, 3D Programming for Windows has not made back its advance. I'm very happy to report that The Annotated Turing has made back its $15,000 advance: In July I received a semi-annual royalty payment from Wiley of a little over $1000.

Writing a book is an incredible commitment of time. A proper book about Windows 8 would probably require a year of fulltime work. If I'll be writing this book, I should probably be starting very soon. I suspect the Windows 8 API will change over the next year as the product goes into beta, so part of the work will involve revising completed chapters to accomodate these changes.

I've been considering alternative means of financing this book. For example, what if my Windows 8 book is actually a $10 Windows 8 app purchasable through the marketplace as soon as the marketplace becomes real, but which gets free updates as I complete chapters over the next year?

But it's very risky basing income on individuals paying up-front for a book that won't be completed for a year. What happens if not enough people subscribe to the book? What happens if I get only a thousand $10 contributions or $10 app purchases? I'm still obligated to complete the book, or I need to find some way to refund everybody's money.

Sometimes people suggest that I self-publish to get more income because there's no publisher involved. But to me self-publishing is the worst option. It means I'll be working a full year on a book without any income from the book and all, plus paying freelance editors and designers to do the stuff the publisher normally does. I simply can't afford to do that.

Realistically, most developer books are no longer economically feasible. The number of people willing to buy the book multiplied by the author's slice of the price of the book is less than the compensation required by the author to write the book. It's as simple as that. — Charles

Charles

Trawling the internet for quality tutorials is awfully time-consuming. When learning something new, I'm sure most people would rather have a book open on their desk with visual studio up on the screen. What people need is just one top quality text that can be supplemented by internet searches for more obscure discussions as required. It would take forever for the "average" person to become proficient in Windows 8 programming by browsing the net! I waste hours going from site to site in utter frustration, but one site I visit almost daily is yours.

There must be a way for you to make a more profitable living from your teaching ability. As you know, many educators these days are providing video tuition on a subscription basis. I realise that this may not be your preferred method of communication, but with your standing in the programming industry, I am certain there would be no shortage of customers.

I appreciate that this may be difficult in practice with unscrupulous subscribers passing on their sign-in details. But is it worth a try?

Failing that I will pay you in advance for a copy of Windows 8 Programming by Charles Petzold. Could you sign it as well please? I'd also buy your app, but I'd end up printing it off as I can't read a textbook on a mobile phone! Believe me, I've tried!

— Mr Gutbucket, Fri, 7 Oct 2011 14:12:18 -0400

u might not be aware of your influence but look at me, im from jordan ( middle east) and i have 4 of your books:

"Code: The Hidden Language of Computer Hardware and Software", "Programming Windows", "Programming Microsoft Windows with C#", and "Applications = Code + Markup: A Guide to the Microsoft Windows Presentation Foundation". your books are the best and i built my whole life on knowledge i learn from them. after finishing a book of yours the one can have the deep knowledge needed to dive deep into the subject.

thank you man and i hope we get the chance to read a book of yours about WinRT and C++/cx oneday.

— Ali saed, Fri, 7 Oct 2011 20:22:56 -0400

I believe the Metro is a spectacular flop, being so ugly, highly unfriendly and coming out of Sinofsky and Co.

Hold your breath a little longer.

— SLx64, Mon, 10 Oct 2011 18:44:04 -0400

I also believe Windows 8 will be a Vista deja vu experience.

For example, while I have no hard numbers as yet, it seems WinRT is not reclaiming memory properly from aborted apps.

A lot can still happen before RTM next year though, we´ll see.

P.S. More on this topic in my blog tripleboot.org.

Henry Skoglund, Tue, 11 Oct 2011 10:04:18 -0400

I believe Metro is the most innovative UI design of recent times. It will be a smash hit.

Jonas, Fri, 14 Oct 2011 02:25:02 -0400

I agree with everyone that you are an exceptional teacher and technical writer. And, you have a larger following than you realize. There are economically viable options to consider. You could publish chapters and post them at your web site or paying subscribers. I would definitely subscribe. As an example, take a look at learnvisualstuio.net.

— Navid, Fri, 21 Oct 2011 07:25:04 -0400

I'm not much of a businessman. I'm not a businessman at all. It's just not in my mental makeup. All I want to do is write the thing.

If somebody believes that money can be made on a Windows 8 book (or web site, or whatever), and is willing to invest in such a project, I'm ready to discuss it. Here's the way it would work: A "Venture Publisher" would pay me to produce the content, and then the VP would collect the income from publishing the material in whatever way the VP desires. — Charles

Charles,

If Microsoft Press can not pay you enough to write The C++/CX WinRT Book, you should in my opinion hand back your Windows Pioneer Award just as John Lennon returned his MBE.

— Marcus Rahilly, Wed, 21 Dec 2011 12:46:46 -0500


Recent Entries
< PreviousBrowse the ArchivesNext >
Subscribe to the RSS Feed

(c) Copyright Charles Petzold
www.charlespetzold.com