Mar 23

Keiki Usage Meter 3.1.0 Released

I’ve released an update for Keiki Usage Meter. There has been a lot of behind-the-scenes work, but the user experience hasn’t changed drastically. Visit the website to find out what’s new.

I’m using this program as something of a testbed for some engineering work that I’ll talk about in future posts, including supporting pixel-perfect bitmap images at multiple DPI settings in WPF and using the Visual Styles APIs to draw native-looking controls (with animation). I’ve also taken the opportunity to learn a bit about localising programs, and v3.1.0 contains three user interface languages: English (Australia), English (United States) and Japanese (Japan) – thanks to Miho Inaba (稲葉美穂) for help with the latter.

Mar 11

WPF: Using System Colours in Animations

WPF provides access to the Windows system colours through the System.Windows.SystemColors class. As the MSDN documentation indicates, it’s possible to bind to these colours dynamically using the *Key resources, so when the system colours change, so will the appearance of your application.

This code will set the colour of a TextBlock to the ‘GrayText’ system colour, and will change automatically if the user switches themes:

<TextBlock Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}">
  Text
</TextBlock>

In many cases, there’s no reason not to bind dynamically. Problems arise with animations, however. From MSDN:

You can’t use dynamic resource references or data binding expressions to set Storyboard or animation property values. That’s because everything inside a ControlTemplate must be thread-safe, and the timing system must Freeze Storyboard objects to make them thread-safe. A Storyboard cannot be frozen if it or its child timelines contain dynamic resource references or data binding expressions.

This means that you’re stuck using static references to system colours in your animation storyboards – if the user changes the system colours while your application is running, your storyboards won’t update automatically. Worst-case scenario, you might end up with unreadable text.

I don’t think there are any workarounds that don’t involve reloading windows and/or resource dictionaries (depending on where the style code is located). Reloading a window is easy enough – just be careful if you’re closing your application’s last window: the program will shut down if there are no remaining references to any windows.

The method for reloading a resource dictionary is a bit less obvious. It seems that XAML files accessed by their pack URIs are already compiled, so the system colours will be fixed in place once the program starts up. To get around this, change the build action for the XAML file containing the resource dictionary to ‘Embedded Resource’. You can then (re)build the resource dictionary as you please using XamlReader:

ResourceDictionary resdic;
using (XmlTextReader xr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("ProjectNameSpace.MyResourceDictionary.xaml")))
  resdic = (ResourceDictionary)XamlReader.Load(xr);

Remove the old resource dictionary from your application’s merged resource dictionaries, then add the new one.

Creating a new resource dictionary like this seems to be fairly slow, so try to avoid doing it on a regular basis. To tell when the Windows theme or system colours have changed, you’ll need to listen for the window messages WM_THEMECHANGED and WM_SYSCOLORCHANGE. See this post for information about listening for window messages in WPF.

Feb 17

More on Segoe UI in Windows 8

Note: the following is based on the Windows Consumer Preview (Windows 8 build 8250) and may not accurately reflect the final version of Windows 8. I’ll update this post if there are changes in future builds.

Updated: The fonts have been updated in the public beta (Windows Consumer Preview) and I’ve changed the tables below to reflect this. I was also made aware of some additional information about changes to Segoe UI, including new stylistic sets and support for ligatures: you can read more at Subacme.

Further to my earlier post about Segoe UI Light in Windows 8, I’ve done some more research into the changes to the Segoe family of fonts. The Fonts class in the .NET Framework was helpful for retrieving information about the fonts.

First off, Segoe Print and Segoe Script and their bold variants have not been modified and are still labelled version 5.02 and 5.00, respectively. All existing variants of Segoe UI have been updated, and there is one new variant: Segoe UI Semilight. The latter is in fact used as the caption and small caption font in Windows 8 – Windows Vista and Windows 7 used Segoe UI (Regular). The Windows Phone 7 platform includes Segoe WP Semilight, and Segoe UI Semilight seems to be a superset of that font.

The following tables summarise the differences in glyph and character counts between the Windows 7 and Windows 8 versions of the Segoe UI font family:

Segoe UI Regular

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.015.125.16
Glyphs289942814490
Characters265832833423

Segoe UI Bold

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.015.125.15
Glyphs289942904428
Characters265832833421

Segoe UI Italic

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.015.105.15
Glyphs238124782597
Characters213021802299

Segoe UI Bold Italic

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.015.105.15
Glyphs238124782597
Characters213021802299

Segoe UI Light

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.005.125.15
Glyphs238040364178
Characters213130903230

Segoe UI Semibold

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.005.125.16
Glyphs238040894228
Characters213131443231

Segoe UI Semilight

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
VersionN/A5.125.15
GlyphsN/A40344175
CharactersN/A30903230

Segoe UI Symbol

 Windows 7Windows 8 Developer PreviewWindows 8 Consumer Preview
Version5.005.335.46
Glyphs309051226785
Characters286445475092

Supported Unicode Blocks

For further information about which Unicode blocks are supported by the Segoe family of fonts, you can download my extended analysis here:

segoe-analysis.7z
2,452 bytes; SHA-1: F6EB969FF44DFA659D743CBABCF25D1EC3B3BC65

Feb 17

Segoe UI Light Improvements in Windows 8

Windows 7 comes with Segoe UI Light version 5.00/0.90. Windows 8 (as of the Windows Consumer Preview) comes with version 5.15, which has been hinted at various sizes. This comes as a very welcome change, especially with Microsoft using Segoe UI Light all over the place in its latest webpage designs. I recommend grabbing the updated versions of Segoe UI from Windows 8 for your Windows 7 or Windows Vista machines.

As others have complained, the lack of hinting in version 5.00 is particularly noticeable with lowercase bs, ds, ps and qs, the ‘round parts’ of which don’t line up well with other characters. The heights of numerals are also variable at some sizes.

Have a look at the following screenshots for a better idea of the differences (click the images to see the full sizes).

Version 5.00

Screenshot of Segoe UI Light 5.00

Version 5.15

Screenshot of Segoe UI Light 5.15

Difference

Screenshot of the difference between Segoe UI Light 5.15 and Segoe UI Light 5.00

Feb 16

Windows System Colours Reference

I’ve put together a reference of Windows system colours from Windows XP to the Windows Developer Preview (and I’ll update it when the Windows Consumer Preview is released in the near future).

Check it out here.

Feb 12

Drawing non-themed push buttons in Windows

When visual styles are enabled in Windows, one may use the DrawThemeBackground function to draw themed push buttons. However, users of Windows XP, Windows Vista and Windows 7 can disable visual styles by selecting the Windows Classic theme or one of the High Contrast themes (and in Windows 2000 and earlier, visual styles weren’t available at all). The classic theming mode has been removed in Windows 8 (I have written about this previously), so in that OS the visual styles APIs should always be available. I suspect it will be a long time before NT6.1 and earlier versions of Windows constitute an insignificant share of the market, though, so this post should be useful until then.Screenshot of Non-Themed Buttons

There are four states that a non-themed button can be in: normal, pressed, defaulted or inactive. How can we draw these states?

The rough non-themed equivalent of the DrawThemeBackground function is the DrawFrameControl function. It has a parameter uType that specifies the type of the frame control to draw – in our case, this should be DFC_BUTTON (= 4). The next parameter is uState. We should set this to DFCS_BUTTONPUSH (=0×0010). For the normal state, this is all that needs to be done. For the inactive state, we should set uType to DFCS_INACTIVE (=0×0100) | DFCS_BUTTONPUSH (in fact, this doesn’t seem to change the appearance of the button frame; the button content/text should be rendered as gray, but that’s out of the scope of this article).

When a non-themed button is pressed or defaulted, it has a single pixel border drawn around it, and the frame control’s bounding rectangle is contracted by 1 pixel on each side. The border’s colour is that of the window frame (COLOR_WINDOWFRAME = 6) – you can use the GetSysColorBrush function to get the appropriate brush. For the defaulted state, just call DrawFrameControl with uType set to DFCS_BUTTONPUSH (with the deflated rectangle). For the pressed state, it might seem like DFCS_PUSHED should be used for uType, but this creates an appearance different to that of standard push buttons. This style is used elsewhere, like on the Windows taskbar, for scrollbar buttons and window caption buttons, etc. Internet Explorer’s owner/custom-drawn buttons also use this style, and I’m sure many other programs do, too. It should be avoided, however, if you’re seeking the native appearance. To properly imitate a pressed push button, avoid using the DrawFrameControl function and use the FrameRect function to draw an inner border with the button shadow colour (COLOR_BTNSHADOW = 16). It’s important to then use the FillRect function to draw the background with the button face colour (COLOR_BTNFACE = 15).

Here’s some pseudocode to illustrate the whole process:

/* state = the button state
   rect  = the bounding rectangle */
uType = DFCS_BUTTONPUSH;
if (state == DISABLED)
  uType |= DFCS_INACTIVE;
if (state == DEFAULTED || state == PRESSED) {
  // draw the border if the push button is defaulted or pressed
  brush = GetSysColorBrush(COLOR_WINDOWFRAME);
  FrameRect(dc, &rect, brush);
  // deflate the rect to exclude the border just drawn
  DeflateRect(&rect, 1, 1);
}
if (state != PRESSED) {
  // if the button’s not pressed, we can use DrawFrameControl
  DrawFrameControl(dc, &rect, DFC_BUTTON, uType);
} else {
  // draw the inner shadow
  brush = GetSysColorBrush(COLOR_BTNSHADOW);
  FrameRect(dc, &rect, brush);
  // deflate the rect to exclude the inner border just drawn
  DeflateRect(&rect, 1, 1);
  // draw the button face colour
  brush = GetSysColorBrush(COLOR_BTNFACE);
  FillRect(dc, &rect, brush);
}

In addition to drawing the background, note that for all states but pressed, the content (text) should be shifted one pixel left and one pixel up. When the button is pressed, it should move one pixel right and one pixel down, so it is centred in the button. Some owner/custom-draw implementations neglect this detail.

Jan 06

Connecting to the internet with a Rami Levy SIM card

I recently bought a prepaid SIM card from Rami Levy for my unlocked HTC 7 Mozart. Unfortunately, I was unable to access the internet at first, despite having turned on the mobile data connection.

Setting the APN manually caused everything to work correctly. These are the details I used (source):

Access Point: internet.rl
Username: rl@3g
Password: rl

Dec 31

Facebook Messenger for Windows is not just for Windows 7

Facebook recently launched ‘Messenger for Windows’, a desktop client for Facebook chat.

The Messenger for Windows help page suggests that the program requires Windows 7:

What kind of computer operating system do I need in order to use Messenger for Windows?
You can set up the app if you use Windows 7 on your computer.

In fact, it runs perfectly well under Windows Vista with the .NET Framework installed. In Windows XP, it crashes on load (though the notification area icon appears first):

Screenshot of Facebook Messenger for Windows (XP)

Looking at the executable in .NET Reflector, the program uses the functions DwmSetWindowAttribute and DwmExtendFrameIntoClientArea, which are not available in Windows XP. I suspect that adding support for that operating system wouldn’t be very difficult, however, as the program is little more than a couple of WebBrowser controls (the heavy lifting is not done on the client side).

Given that Facebook decided not to support Windows XP, the least they could do is use a task dialog instead of this:

Screenshot of Facebook Messenger for Windows dialog

If you look closely, you’ll notice that the font is Microsoft Sans Serif, not Segoe UI (the latter is the user interface font in Windows Vista and newer – MS Sans Serif hasn’t been the default since Windows ME!). This is largely Microsoft’s fault – MS Sans Serif is the default font in the Windows Forms designer even in Visual Studio 2010 (and the issue has been around for a long time) – but it’s something that the Facebook developers should have picked up on.

I was disappointed to see that the application is installed to the ‘local application data’ folder (C:\Users\<User>\AppData\Local in Vista and newer) instead of Program Files. I guess when Google decides it’s acceptable to install Google Chrome in %appdata%, everything is permitted. (Microsoft itself is hardly blameless – ClickOnce applications are installed to somewhere non-standard.)

Interestingly, the developers chose to use the CS_DROPSHADOW window class style to draw a shadow around the window even when the DWM is disabled. Given that Google returns fewer than 10,000 results for CS_DROPSHADOW, this must be one of very few applications to use that feature.

(As the screenshot below demonstrates, running the program with IE7 installed produces hilarious results.)

Screenshot of Facebook Messenger for Windows (Vista)

The program doesn’t respect the operating system’s language settings – the notification area icon’s menu is displayed in the language that the user selects on Facebook.

Finally, the docking functionality is implemented by using an application desktop toolkbar (appbar). I haven’t seen many programs use appbars, so it’s neat to see one in action.

Dec 20

Study Score Archive 2011

The VCE Study Score Archive has been updated for 2011.

Download the updated files here.

Nov 12

When should a program’s UI animations be disabled?

Modern frameworks like the Windows Presentation Foundation, its relative Silverlight and the upcoming Windows Runtime make it easy to add animations to a program’s graphical user interface. When implemented well, animations subtly improve the user experience and can demonstrate a high level of polish in your application. The Zune client software and Windows Live Messenger both feature beautiful animations – coincidentally, both were written with internal Microsoft frameworks (Iris and ‘DirectUI’, respectively; the second is apparently unrelated to anything in WinRT). The Twitter client MetroTwit shows what can be done in WPF (its interface was inspired by the Zune software and the Metro design language).

There are times, however, when animations may become detrimental to the user experience. Animations may appear choppy on lower-end or older systems (especially with heavy frameworks like WPF), and in general they should be disabled entirely for Remote Desktop Connection sessions (only very fast networks with low latency may be able to handle them). Jossef Goldberg from the Visual Studio team has written about the efforts made to bring the performance of Visual Studio 2010 over remote connections up to par, and while his advice is mainly about WPF, the same principles apply to other frameworks, also.

So, how can we decide whether animations should be disabled or not? The answer will likely vary from project to project, but there are a few things that we can do:

1. Check if the program is running in a remote session

In Win32, use the GetSystemMetrics function to get the SM_REMOTESESSION metric (a non-zero result means it is a remote session). In WPF, use the SystemParameters.IsRemoteSession property in the System.Windows namespace. In Windows Forms, use the SystemInformation.TerminalServerSession property in the System.Windows.Forms namespace.

2. Check if animations are enabled in Windows

Windows Vista introduced many new animations to common controls like buttons (notice the smooth glow effect and compare it to the binary states found in Windows XP). Regrettably this change made most owner-drawn implementations look shoddy since they mostly lack animation (e.g. buttons in Firefox), but that’s a topic for another post.

Anyway, these animations can be switched off in the following dialog (aside: the list box was mercifully increased in size in Windows 7, though the window still isn’t resizable):Performance Options Screenshot

If the user has disabled animations here, it’s probably a good idea to respect that choice in any program you write. We can use the SystemParametersInfo function with the SPI_GETCLIENTAREAANIMATION parameter to check the system setting (or use the SystemParameters.ClientAreaAnimation property in the System.Windows namespace, but note that this always returns true in Windows XP). This only applies to Windows Vista and later.

3. WPF-only: Check the graphics rendering tier

The RenderCapability.Tier property in the System.Windows.Media namespace gives an indication of the graphical capabilities of the system. There are currently 3 tiers, and while the exact meaning may change between .NET releases (as it did in .NET 4.0), this property can be used to help determine what animations, if any, should be enabled.

4. Ask the user!

It can’t hurt to give the user a choice about animations. The remote session checks described above will work for RDP, but there are other technologies available, and we don’t want to punish VNC users by invalidating the entire window 60 times per second for some fancy animation, even if we can’t tell that they’re connecting remotely. If exposing such an option in the UI doesn’t make sense, at least offer it as a command line switch.

Addendum (2011-11-20)

Snooping around PresentationFramework.Aero.dll in .NET Reflector, I happened to come across the ‘Animates’ property in the ButtonChrome class (Microsoft.Windows.Themes namespace):

private bool Animates {
  get {
    return ((((SystemParameters.PowerLineStatus == PowerLineStatus.Online) && SystemParameters.ClientAreaAnimation) && (RenderCapability.Tier > 0)) && base.IsEnabled);
  }
}

Similar properties can be found in the other *Chrome classes. Checking the computer’s power status isn’t something covered in this article, but it’s certainly a good idea.

Older posts «

Page optimized by WP Minify WordPress Plugin