DCSIMG
September 2011 - Posts - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

September 2011 - Posts

Dynamic Live Tiles in Windows Phone 7

Published at Sep 30 2011, 03:22 AM by pavely

One of the attractive features of Windows Phone 7 is the tiles in the start menu. It’s pretty easy to point the main application tile (and secondary tiles) to static URLs. It’s a bit more difficult to create a dynamic image for a live tile.

Starting with tiles

The easiest way to start is by tweaking the WMManifest.xml file (or even easier, but less flexible) the Project Properties Application Tab:

image

The title appears as text under the background image. Ideally, the image should be 173x173 pixels in size. Otherwise, WP7 will stretch/crop as appropriate. The image must be a PNG or JPG file. Using a transparent PNG will make the phone’s accent color show through. Here’s an example with an alternate image (viewed with the emulator):

image

The manifest file contains more options than the above Properties section. This is how it looks now:

<TemplateType5>
  <BackgroundImageURI IsRelative="true" IsResource="false">note.png</BackgroundImageURI>
  <Count>0</Count>
  <Title>Quick Notes</Title
>
</
TemplateType5
>

This is located in the lower part of the file. The Count element allows placing some number between 1 and 99 in the top right corner of the icon. Here’s how it looks when set to the  number 5:

image

This may come in handy.

The new Mango version adds the ability to have a background tile as well, flipping every couple of seconds or so:

<TemplateType5>
  <BackgroundImageURI IsRelative="true" IsResource="false">note.png</BackgroundImageURI>
  <Count>5</Count>
  <Title>Quick Notes</Title>
  <!--<BackBackgroundImageUri IsRelative="true" IsResource="false">background.jpg</BackBackgroundImageUri>-->
  <BackTitle>Back Title</BackTitle>
  <BackContent>Some content</BackContent
>
</
TemplateType5
>

Here’s how the back tile looks:

image

Although there is a BackBacgroundImageUri, it doesn’t seem to work from the XML (but can be set in code).

Changing a Tile Programmatically

This is fine if all we want is something that does not change. To update a tile, however, or to create secondary tiles, we need some code.

Let’s create a quick notes application that allows adding notes that may be pinned to the start menu. The main tile would indicate the number of existing notes.

Updating the main tile can be done like so:

var mainTile = ShellTile.ActiveTiles.First();
mainTile.Update(new StandardTileData {
    Count = _notes.Count
});

The ShellTile class is the main gateway to tiles. The ActiveTiles static collection is a list of all application tiles. The list includes at least the main tile (always the first tile), even if it’s not actually pinned.

To update the tile, we create a StandardTileData object and fill in the required properties. In this case, only the Count is changed, but any other property (such as Title and BackgroundImage can be changed).

Creating new tiles

How about creating new tiles? Essentially it’s not too difficult: fill in a StandardTileData object and call Shelltile.Create:

var data = new StandardTileData {
    Title = note.Name,
    BackTitle = note.Name,
    BackContent = note.BackText,
};
ShellTile.Create(new Uri("/NoteData.xaml?name=" + data.Title, UriKind.Relative), data);

The first argument to Create is a URI that would be followed if the user clicks on the tile. In this case, I’m forwarding this to a XAML page in the app, that would use the query string to display the full note information.

What about the image of the tile? if it’s a predefined image (either within the app or on some server reachable by HTTP), then it’s easy – just set the BackgroundImage property to the appropriate URI. But what about something more dynamic?

Suppose we want the main note text to be displayed in the main tile area (as an image). How could we construct that?

There are 2 steps involved:

1. Create a dynamic image

2. Provide some URI that can reach it

The BackgroundImage property is a URI. I would have expected an ImageSource-derived object, but alas, that is not the case. We have to use a URI somehow.

We’ll use the WriteableBitmap class to create a dynamic image consisting of the note text. One of WriteableBitmap’s abilities is to render any UIElement inside it, so we’re practically not limited to anything.

First, we’ll create a user control that would host our content. Then we’ll render its contents into a WriteableBitmap. Here’s a simple user control markup suitable for our purposes:

UserControl x:Class="QuickNotes.DynamicNote"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d"
   FontFamily="{StaticResource PhoneFontFamilyNormal}"
   FontSize="{StaticResource PhoneFontSizeNormal}"
   Foreground="{StaticResource PhoneForegroundBrush}"
   d:DesignHeight="173" d:DesignWidth="173" x:Name="ctl" Width="173" Height="140"
            >
    <Border Background="{StaticResource PhoneAccentBrush}">
        <TextBlock x:Name="_text" Margin="6" Width="173" Height="140" Padding="4" HorizontalAlignment="Center"
                  TextWrapping="Wrap" VerticalAlignment="Center" />
    </Border
>
</
UserControl
>

This is essentially a simple TextBlock enclosed in a border, that is colored with the user’s theme (PhoneAccentBrush resource key).

Now let’s draw that into a bitmap:

var ctl = new DynamicNote(note.Text);
ctl.Measure(new Size(173, 173));
ctl.Arrange(new Rect(0, 0, 173, 173));
var bmp = new WriteableBitmap(173, 173);
bmp.Render(ctl, null);
bmp.Invalidate();

Note that we need to call Measure and Arrange if the element to render is not part of a visual tree. Failing to do so will produce unpredictable results (try it!).

The next step is to somehow transform that into a URI. To do that, we’ll save this bitmap to isolated storage (the storage every application has) in a special folder named Shared/ShellContent and create a URI from that:

var iss = IsolatedStorageFile.GetUserStoreForApplication();
var filename = "/Shared/ShellContent/note" + note.Name + ".jpg";
using(var stm = iss.CreateFile(filename)) {
    bmp.SaveJpeg(stm, 173, 173, 0, 80);
}
// pin
var data = new StandardTileData {
    Title = note.Name,
    Count = null,
    BackTitle = note.Name,
    BackContent = note.BackText,
    BackBackgroundImage = new Uri("note.png", UriKind.Relative),
    BackgroundImage = new Uri("isostore:" + filename, UriKind.Absolute)
};
ShellTile.Create(new Uri("/NoteData.xaml?name=" + data.Title, UriKind.Relative), data);

The SaveJpeg is an extension method for WriteableBitmap. It certainly comes in handy in this case. Note the new image URI starting with the “isostore:” prefix.

That’s it. We have a dynamic live tile (lower left):

image

Deleting (unpinning) a tile

To delete (unpin) a tile programmatically, just call the ShellTile.Delete instance method. Here’s an example:

var tile = ShellTile.ActiveTiles.Single(t => t.NavigationUri.ToString().Contains("?" + note.Name + "="));
tile.Delete();

We first must find the tile we want to remove using some properties we’re aware of (typically the NavigationUri property). Then the single call to Delete is all it takes to get rid of the tile.

Encapsulation & Exposure

Published at Sep 26 2011, 10:55 PM by pavely

I like to keep a tight leash on my classes. No unnecessary exposure. Consider the following simple class:

class PersonnelManager {
    List<Person> _people = new List<Person>();

    public void Add(Person person) {
        // do some validation
        _people.Add(person);
        // maybe some extras
    }
}

I want to expose the currently managed Person objects for interested parties. One way to do this would be:

public List<Person> People {
    get { return _people; }
}

This may be obvious – but I’ve seen this too many times. Exposing the property as List<>, IList<> or ICollection<> defeats the purpose. Anyone can call Add on the returned object.

A better alternative is to use IEnumerable<>:

public IEnumerable<Person> People {
    get { return _people; }
}

This is much better: no Add method visible. Still, curious (and malicious) clients may try this:

var mgr = new PersonnelManager();
var list = mgr.People as List<Person>;
if(list != null)
    list.Add(new Person { Age = 10, Name = "Bart" });

Or better (lower common denominator):

var list = mgr.People as ICollection<Person>;
if(list != null)
    list.Add(new Person { Age = 10, Name = "Bart" });

This will work with other lists, such as ObservableCollection<>.

Despite our best efforts, Person objects can still be added “behind our backs”. Although it’s less likely than the first alternatives, I still would have liked something “stronger”.

The best I could come up with is using yield:

public IEnumerable<Person> People {
    get {
        foreach(var p in _people)
            yield return p;
    }
}

This has the desired effect: No cast to ICollection<> or IList<> would succeed, as the compiler re-writes the code and creates its own implementation of IEnumerable<Person> (which does not include other interfaces). The downside, of course, is the added code we had to write.

Is this really bulletproof? Almost. A full trust application can still theoretically use reflection to get to the private List<Person> member and call Add on it directly, but it’s a lot less likely, as such code is, naturally, cumbersome and fragile.

Preview tools for Windows 8

Published at Sep 13 2011, 11:08 PM by pavely

I am one of the unfortunate ones that didn’t make it to Microsoft’s BUILD conference. But I managed to be home in time for the live streaming of the first keynote.

Just finished watching (on and off) the live stream of Steven Sinofsky’s keynote on Windows 8 and friends. Definitely some intriguing stuff there!

For me, as a developer kind of guy, the C++ comeback is noteworthy. Finally, C++ libraries that are on par with .NET libraries (and unfortunately HTML and JavaScript as well Smile). C++ has been neglected for too long. The best example (I think) is WPF – no real C++ library equivalent (Direct2D/Direct3D stull far off from a high level framework). Now C++ is back!

Also worth noting – I didn’t see any mention of WPF – although Silverlight was mentioned, or at least shown on the platform choices at the bottom of the stack; and XAML is still there. Still many unanswered questions, as far as I’m concerned. Maybe the tools download will help. And of course, the sessions to come should shed light on things.

Steven promised the web site http://msdn.microsoft.com/en-us/windows/home/ would have the download materials for developers to be available on 3:00 AM GMT (that’s 6:00 AM Israel time).

Definitely worth the download!

C++ Tip: Go away, sprintf!

Published at Sep 05 2011, 07:02 PM by pavely

Recently I did some teaching of an Advanced C++ course, for various audiences. I noticed that many people coming from a C background sometimes have a hard time abandoning the “old way” of C style programming and thinking. This is hardly new or surprising. I try, whenever possible, to point out the C++ way of doing things, where a legacy C alternative exists.

One of the obvious culprits is the infamous printf C function. That’s probably the first function to be learned by a C (and maybe even C++) programmer, and it’s a surprisingly complex function. Its prototype is something like this:

int printf (const char* format, …)

(I’m ignoring any compiler specific export directives and such, as they’re not relevant for this discussion).

(by the way, printf returns the number of characters actually printed to the console).

printf accepts a variable number of arguments, that can be anything. Format specifiers inside the format argument provide clues as to how to interpret those extra arguments. A typical printf example would be:

int x;
//...
printf("the value is %d points", x);

The %d tells printf to expect an integer as the first argument after the format string. And there are plenty of them, such as %f, %lf, %u, %s, %c and others. C programmers tend to learn the meaning of each one they actually use. In C++, the cout object is used as an alternative:

cout << "the value is " << x << " points";

At first glance, it may seem not too different, an maybe even longer. But there’s a fundamental difference between using cout and printf. printf is typeless. It has no idea what it actually gets, it just knows what it should expect. If these match then all is well. But if not – weird things can happen. For instance, what if %d is passed but the value itself is a double? Or worse, vice versa: %lf is passed (expecting a double), but an int is provided? printf has no idea this is happening. The compiler will be silent. At runtime, the value would appear wrong (in the first case, because a floating point number is interpreted differently than an integer one) and in the second case, printf will attempt to read 8 bytes for the double, where only 4 (assuming sizeof(int)==4) are supplied. It would read pass the memory of that variable, whatever is there would be part of the result.

With cout, this can never happen. cout is a global instance of ostream with operator << for every basic type. New overloads can be created for custom types. For example, assume a class Person is defined, with Person objects that need to be output in some way. We want to say:

Person p("bart simpson");
cout << p;

This works assuming the following (global) operator is defined:

ostream& operator<<(ostream& out, const Person& p) {
    return out << p.GetName() << " " << p.GetAge();
}

Most C++ developer are familiar with cout. What about formatting some data into a string, instead of the console?

C has the sprintf function, working similarly to printf, but writes its output to a character array. What about C++? Are we forced to use sprintf with its lack of type safety and clunky interface? Fortunately no.

We can use the stringstream class in the same way we use cout. In this case the output goes into the stringstream. Eventually we can convert it to a normal string. Here’s an example:

stringstream ss;
ss << "the value is " << x << " points";
string result = ss.str();

You need to #include <sstream> for the compiler to be happy. Easy, right? The same rules as with any ostream. No need to allocate buffers or remember fancy format specifiers. It also works with manipulators (just as it does with cout):

ss << "the value is " << setw(5) << x << " points" << endl;

setw is an example manipulator, that makes sure the value is displayed with at least 5 characters (in this case), padding with spaces to the left of the value.

So, there you have it. sprintf is no longer needed, and so are many other C style constructs that have been carried into C++ by a necessity of compatibility.

C++ is back with a new finalized standard. I’ll talk about some of the new features in future posts.

Reminder: WPDUG September Meeting

Published at Sep 04 2011, 01:05 AM by pavely

This Wednesday (the 7th) will hold a Windows Platform Developer User Group meeting in Microsoft’s offices in Ra’anana (Israel).

Our first session will be about adding realtime and deterministic capabilities to Windows and its impact on the system and the ways to program such a system (all based on addons by a company called TenAsys). The second session will demonstrate useful (and undocumented) debugging tips and tricks in Visual Studio (primarily for native developers).

Should be interesting for all you Visual C++ developers, and others interested in low level coding.

Use this link to register and review the detailed agenda.

See you there!