Using Custom Icons in Windows Mobile 6.5

Update: Updated sample code, you can download it here. Read all about it here.

If you’ve seen the any of the plethora of Windows Mobile 6.5 screen shots, likely you’d agree that it looks much better than previous versions. A component of this ‘face lift’, is support for PNG files in the Window Mobile 6.5 Start screen. Including a nicely rendered PNG file as your application icon is important to ensure the highest quality user experience across different devices.

If you plan to distribute your application via Windows Marketplace for Mobile (and I don’t know why you wouldn’t) the requirements document requires that you use a 90 x 90 Start screen icon for your application. This post will cover how to use PNG files as icons in the Windows Mobile 6.5 Professional Start screen. For information on creating PNG icons, see my previous post on Creating Custom Icons for Windows Mobile 6.5. The sample code I will be referring to in this post can be found here.

Contents:

Start Screen: Resolution / DPI and Icon Size
Registry Keys
Setup: Static or Dynamic
Cached Icons
Games Shortcuts Folder

Start Screen: Resolution / DPI and Icon Size

The Start Screen is one of the huge improvements in Windows Mobile 6.5 Professional. This replaces the Start Menu in previous versions. The improvements include: enhanced touch screen navigation (tap, tap and hold, pan, and flick) and more options for organizing and presenting Start menu items. image

If you are an experienced Windows Mobile developer, you know that depending on the DPI and resolution of the device, the shell extracts the appropriately sized icon from the EXE for display in the Start screen. Windows Mobile 6.5 still supports this; however now it also supports the display of PNG file icons. The shell does not automatically select the size of the PNG icon based on the device DPI. This dynamic selection of the icon is done in a setup dll. (See dynamic setup below.) However, if you do not want to provide a separate PNG file for each DPI, you can provide one (90x90) and the shell will scale down the icon as necessary, depending on the DPI of the device. (In fact, this is the Marketplace requirement.) The table below illustrates the DPI / resolution and icon size relationship. 

 

Windows Mobile Platform Resolution DPI Orientation Small Icon Large Icon Start Menu PNG Icon (6.5)
6.x Professional 240x240 96 Square 16x16 32x32 45x45
6.x Professional 240x320 96 Portrait & Landscape 16x16 32x32 45x45
6.x Professional 240x400 96 Portrait & Landscape 16x16 32x32 45x45
6.x Professional 320x320 128 Square 21x21 43x43 60x60
6.x Professional 480x480 192 Square 32x32 64x64 90x90
6.x Professional 480x640 192 Portrait & Landscape 32x32 64x64 90x90
6.x Professional 480x800 192 Portrait & Landscape 32x32 64x64 90x90
6.x Professional 480x864 192 Portrait & Landscape 32x32 64x64 90x90
6.x Standard 176x220 96 Portrait 16x16 32x32 N/A
6.x Standard 240x320 131 Portrait & Landscape 22x22 44x44 N/A
6.x Standard 240x240 131 Square 22x22 44x44 N/A
6.x Standard 240x400 131 Portrait & Landscape 22x22 44x44 N/A
6.x Standard 440x240 131 Landscape 22x22 44x44 N/A
 

Registry Keys

To have the Start screen use a PNG file instead of an icon embedded in the EXE, you need to provide the following registry entries:

[HKEY_LOCAL_MACHINE\Security\Shell\StartInfo\Start\Phone.lnk]
"Icon"="\Application Data\My App\newphoneicon.png"

Here are the definitions of the value pair settings:

Name Type Description
Name REG_SZ Specifies the display name of the item. If the value is not specified, the file name will be displayed without the extension.
Group REG_DWORD Specifies whether the item is a folder. The value can be set to TRUE or FALSE. Set the value to TRUE to indicate that the item is a folder. If the value is not specified, the system will determine the Group value by verifying whether the registry key has any subkeys.
Icon REG_SZ Specifies the path and file name where the icon is located. The icon can consist of a PNG file or an embedded icon resource module. If this value is not specified, the default icon of the shell will be used.
Rank REG_DWORD Specifies the rank of the item. An item that specifies a larger value for Rank will be displayed before items that specify a lower value. If this item is not specified, the Rank will be set to 0.
 
Security note: This requires creating a registry key underneath HKLM\Security. This is a protected registry location. To write to a protected registry key, the CAB file needs to be signed. This will not be a problem for Marketplace applications, since by definition they are signed. As mentioned, this article only applies to Windows Mobile Professional devices. However, if you use the same CAB for a Standard device installation, you will need to make sure your application is signed privileged, otherwise setup will fail. To avoid having to sign your CAB privileged (and incur the extra Marketplace approval time this requires) you can use the dynamic setup mentioned in this post. Be sure to include in your setup dll, the conditional creating of the StartInfo registry key and copying of the PNG file, and only do these steps if installing on a Professional device.  See the sample code here for an example on how to do this.

Setup

In the next two sections, I’ll walk through two deployment scenarios, static and dynamic.

Static Setup:

You can specify the registry key as part of your CAB file configuration. Per the Marketplace requirements, I will use a 90 x 90 PNG file as the Start screen icon. In my Smart Device CAB project, I have added the following registry key:

image_thumb7

Note: This registry key supports ‘CE strings’ and .INF file strings. Above %InstallDir% maps to the ‘\Program Files\SMS Intercept’ directory.

My CAB file also includes the (90x90) AppIcon.png and a shortcut of the same name as the registry key above (SMS Intercept.lnk). See below:

image_thumb2

Dynamic Setup:

Detecting DPI:

Another way to configure the Start screen icon is dynamically: copying the appropriately sized PNG file based on the DPI of the device. We will use a setup dll to detect the DPI, and copy the appropriate PNG. You may know that WCELOAD (the EXE that process the CAB file) or a DLL that is loaded into its process, will return the same DPI (96) no matter the actual DPI of the device. To workaround this, we launch a very small helper EXE that quickly exits, without UI, and returns the DPI. The SDK sample ResDLL uses this technique as well as demonstrates how to install DPI specific resource DLLs. Here is the code used to detect the DPI:

int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
HDC hdc = ::GetDC(NULL);
INT ans = ::GetDeviceCaps(hdc, LOGPIXELSX);
::ReleaseDC(NULL, hdc);
return ans;
}
Copy DPI specific files:

Our dynamic CAB file contains four png files:
        45.png
        60.png
        90.png
        AppIcon.png

Based on the DPI detected, we copy the appropriate PNG file to the filename AppIcon.png. AppIcon.png is included in the CAB as a fallback in case our DPI detect logic fails. The unused icons and the DPI detect EXE are deleted.

Here is a code snippet from the sample setup dll (SetupDPI) implementing this:

wsprintf(szFile,_T("%s\\%s"), pszInstallDir, _T("\\GetRealDPI.EXE"));
// Launch DPI Detector
::CreateProcess(szFile, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, &pi);
::WaitForSingleObject(pi.hProcess, 10000);
// DPI is returned in exit code of detector app
::GetExitCodeProcess(pi.hProcess, &nSystemDPI);
::CloseHandle(pi.hProcess);
::DeleteFile(szFile);

// Based on DPI, copy xx.png to AppIcon.png and delete unused files
wsprintf(szOutFile,_T("%s\\%s"), pszInstallDir, szTargetFilename);
for (INT i=0;i<ARRAYSIZE(DPI_Icon);i++) {
wsprintf(szFile,_T("%s\\%s"), pszInstallDir, DPI_Icon[i].lpstrIconSize);
if (DPI_Icon[i].DPI==nSystemDPI) {
::CopyFile(szFile, szOutFile, FALSE);
}
::DeleteFile(szFile);
}

Create Shortcut:

As mentioned, we do the post-processing of the files after the CAB is installed (in the Install_Exit function). That is, because the icon image in the Start screen is created when the shortcut is created (see the cached icons section below), we need to create the shortcut in the setup dll instead of in the CAB file as was done in the static CAB sample. Otherwise, the Start screen will use an icon extracted from the EXE instead of the PNG file. Here is the language independent code that creates the shortcut:

// Build lnk filename
PTCHAR pAppDir = wcsrchr(pszInstallDir, '\\');
TCHAR szShortcutPath[MAX_PATH];
// CSIDL_PROGRAMS == \Windows\Start Menu\Programs
SHGetSpecialFolderPath(hwndParent, szShortcutPath, CSIDL_PROGRAMS , false);
wsprintf(szFile,_T("%s%s%s"), szShortcutPath, pAppDir, _T(".lnk"));

// Build exe filename
// CSIDL_PROGRAM_FILES == \Program Files
SHGetSpecialFolderPath(hwndParent, szShortcutPath, CSIDL_PROGRAM_FILES , false);
wsprintf(szOutFile,_T("\"%s%s%s%s\""),
     szShortcutPath, pAppDir, pAppDir, _T(".exe"));

SHCreateShortcut(szFile, szOutFile);
 
Note that the dynamic CAB sample does not not contain the file system declaration that creates a shortcut as the static sample CAB does.

Cached Icons

During development, you will likely want to change the PNG file as you experiment will different artwork. You will notice that if you overwrite the PNG file, the Start screen will not use the new image. This is because when the Start screen shortcut is created, the icon image is cached by the shell. Thereafter for better performance, the shell retrieves the image from the cache. The cache is rebuilt a boot time. Here is one possible workaround:

  1. Delete the shortcut
  2. Rename (or copy) target EXE name. For example, rename hello.exe to hello1.exe
  3. Recreate shortcut pointing to new EXE name.

Here is provisioning XML that does this. You can run this using RapiConfig.exe:

<wap-provisioningdoc>
<characteristic type="FileOperation">
<!-- Delete Shortcut -->
<characteristic type="%CE11%\SMS Intercept.lnk" translation="install">
<characteristic type="Delete">
<parm name="ForceDelete"/>
</characteristic>
</characteristic>

<!-- Copy EXE name to new EXE -->
<characteristic type="%CE1%\sms Intercept\sms Intercept1.exe"
          translation="install">
<characteristic type="Copy">
<parm name="Source" value="%CE1%\sms Intercept\sms Intercept.exe"
          translation="install"/>
</characteristic>
</characteristic>

<!-- Create new shortcut pointing to new EXE name -->
<characteristic type="%CE11%" translation="install">
<characteristic type="MakeDir" />
<characteristic type="SMS Intercept.lnk" translation="install">
<characteristic type="Shortcut">
<parm name="Source" value="%CE1%\sms Intercept\sms Intercept1.exe"
translation="install" />
</characteristic>
</characteristic>
</characteristic>
</characteristic>
</wap-provisioningdoc>

Games Shortcuts Folder

If we were installing this application into the Games folder, the key pointing to the PNG file would look like this:
[HKEY_LOCAL_MACHINE\Security\Shell\StartInfo\Start\Games\Phone.lnk]
"Icon"="\Application Data\My App\newphoneicon.png"

Game developers have raised the question, “How do I create the Games registry key in a language independent way?” Without the Games folder, this key is language independent. However, the shell will look for the shortcut (.lnk) files in the directories below Start, therefore we need to setup this key using the localized name for Games. This requires a Setup DLL. See the sample code for this post here.

To have your shortcut created in the Games folder, you must change the following line in the SetupDPI.CPP and rebuild the project:

// Set this to true to create shortcut and 
// registry key in the localized 'Games' Folder
BOOL g_bCreateInGamesFolder=FALSE;

Conclusion

You should now understand how to configure your CAB file projects to include PNG files as icons in the Windows Mobile 6.5 Start screen.

For a list of frequently asked questions on this topic see here: Start Screen PNG Icon FAQ


Comments

  1. Posted on: August 05, 2009 at 11:20PM  

    What about those of us that use C# - how do we do this?

  2. Posted on: August 06, 2009 at 12:23AM  

    Wow, a system more complex than the desktop that requires writing to a locked down registry key to have a proper icon in the start menu.  Impressive.

    Is there some reason for the PNG icons and not just using ICO files?

  3. Posted on: August 06, 2009 at 5:36AM  

    thanks Mike for the explanation, but you write that:

    To write to a protected registry key, the CAB file needs to be signed.

    That means to test this process in the emulator, we must have a signed CAB?

  4. Posted on: August 06, 2009 at 5:49AM  

    Was there some sort of requirement to do this in the most developer-hostile way possible, or was that just a happy accident?

    And as mrmckeb asked, what about .NETCF developers? Remember us?

    Let's see...to provide a .png icon for an iPhone application you drop a file called "Icon.png" into your project folder - does it occur to anyone that we might have a problem here?

    Sorry to be sarcastic, but as a C# developer this is yet another slap in the face. Yes you have unique issues with devices  supporting a range of resolutions, but this is a crappy solution.

  5. Posted on: August 06, 2009 at 10:10AM  

    Truly a horrid overly engineered solution. Was it too difficult to be developer-centric and use some convention like any sane person would develop? Such as ShortcutTargetPath\ShortcutTargetExeName.Icon.png? How about smooth scaling a 90x90 PNG down for low-DPI devices so we don't have to write code in our CAB setup? Not to mention the registry location and requiring a privileged cert.

    Not to mention it seems braindead to execute an EXE in code that 'returns' the DPI of the device. Why write CreateProcess/WaitFor/etc when we could just write CreateDC/GetDeviceCaps in the CAB DLL?

  6. Posted on: August 06, 2009 at 10:13AM  

    BTW in our testing WCELOAD is HIDPI-aware and returns the correct DPI, at least on older devices. Seeing this article I'm wondering if that's another thing you broke for WM6.5.

  7. Posted on: August 06, 2009 at 10:21AM  

    Sorry for the repeat comments; but after looking at our setup dll it does indeed always return 96. Our workaround was to read the registry to get the true DPI:

    DWORD dwDPI = 92;

    HKEY hkey;

    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Drivers\\Display\\GPE"), 0, KEY_ALL_ACCESS, &hkey)) {

    DWORD type = REG_DWORD;

    DWORD size = sizeof(DWORD);

    if (ERROR_SUCCESS != RegQueryValueEx(hkey, _T("LogicalPixelsX"), NULL, &type, (LPBYTE)&dwDPI, &size)) {

    dwDPI = 92;

    }

    RegCloseKey(hkey);

    }

    This way you don't have to launch a separate executable, and may help C# developers as well.

  8. Posted on: August 07, 2009 at 8:32AM  

    >>Wow, a system more complex than the desktop that requires writing to a locked down registry key to have a proper icon in the start menu.  Impressive.<<

    and

    >>Was there some sort of requirement to do this in the most developer-hostile way possible, or was that just a happy accident?<<

    My thoughts exactly -

    An application icon that needs signing and so much fuss to create? Sure, block out hobbyist programmers, why don't you! It's gonna break your neck. Time to look elsewhere too.

  9. Posted on: August 07, 2009 at 2:38PM  

    Thanks for all the feedback. We've complied a FAQ here: windowsteamblog.com/.../start-screen-png-icon-faq.aspx

  10. bbj
    Posted on: August 10, 2009 at 12:34PM  

    In the dynamic setup version a shortcut is created in the code with:

    // CSIDL_PROGRAMS == \Windows\Start Menu\Programs

    SHGetSpecialFolderPath(hwndParent, szShortcutPath, CSIDL_PROGRAMS , false);

    Thats fine, however this presupposes all shortcuts are to be placed in the 'Start menu\Programs' folder.

    Prior to 6.5 consumers knew that (and I recall it being a general recommendations that) games should place their shortcut in the 'Start Menu\Programs\Games' folder.

    The problem is that we cannot locate any CSIDL that represents the 'Programs\Games' folder + are pretty sure the location varies by locale - so cant reasonably hard code.

    So is there a CSIDL that references 'Start meun\Programs\Games' , if not are there any recommendations as to how to do this in a locale independant way, or do we no longer put games in the 'Games' folder and leave it upto the consumer to move things around ?

    Thanks

  • Page:
  • 1
  • 2
  • 3

Trackbacks

  1. Posted by: [ TUTORIAL ] Using Custom Icons in Windows Mobile 6.5 | pocket pc freeware, windows mobile apps review, wm6.5 software on August 05, 2009 at 10:21PM

    Pingback from  [ TUTORIAL ] Using Custom Icons in Windows Mobile 6.5 | pocket pc freeware, windows mobile apps review, wm6.5 software

  2. Posted by: Creating Custom Icons for Windows Mobile 6.5 - Windows Mobile Blog - The Windows Blog on August 06, 2009 at 12:01AM

    Pingback from  Creating Custom Icons for Windows Mobile 6.5 - Windows Mobile Blog - The Windows Blog

  3. Posted by: Using Custom Icons in Windows Mobile 6.5 | India Phone cards on August 06, 2009 at 2:06AM

    Pingback from  Using Custom Icons in Windows Mobile 6.5 | India Phone cards

  4. Posted by: Using Custom Icons in Windows Mobile 6.5 | ASP Scribe on August 06, 2009 at 2:25AM

    Pingback from  Using Custom Icons in Windows Mobile 6.5 | ASP Scribe

  5. Posted by: How to use custom icons in Windows Mobile 6.5 « MobileTechWorld on August 06, 2009 at 4:16AM

    Pingback from  How to use custom icons in Windows Mobile 6.5 « MobileTechWorld

  6. Posted by: Windows Mobile 6.5: Using Custom Icons on August 06, 2009 at 5:01AM

    Pingback from  Windows Mobile 6.5: Using Custom Icons

  7. Posted by: Application Icons on WM 6.5 Start Screen « 42Gears Speaks on August 06, 2009 at 6:02AM

    Pingback from  Application Icons on WM 6.5 Start Screen «  42Gears Speaks

  8. Posted by: shino-blog on August 06, 2009 at 12:46PM

    Windows Mobile 6.5 のアイコンの話

  9. Posted by: Using Custom Icons in Windows Mobile 6.5 – Windows Mobile Blog … | Cell Mobile Guide on August 06, 2009 at 9:32PM

    Pingback from  Using Custom Icons in Windows Mobile 6.5 – Windows Mobile Blog … | Cell Mobile Guide

  10. Posted by: Using Custom Icons in Windows Mobile 6.5 - Windows Mobile Blog … on August 06, 2009 at 9:34PM

    Pingback from  Using Custom Icons in Windows Mobile 6.5 - Windows Mobile Blog …

  11. Posted by: Using Custom Icons in Windows Mobile 6.5 - Windows Mobile Blog … on August 06, 2009 at 11:38PM

    Pingback from  Using Custom Icons in Windows Mobile 6.5 - Windows Mobile Blog …

  12. Posted by: Start Screen PNG Icon FAQ - Windows Mobile Blog - The Windows Blog on August 11, 2009 at 1:54PM

    Pingback from  Start Screen PNG Icon FAQ - Windows Mobile Blog - The Windows Blog

  13. Posted by: Marketplace: Licht in den Dschungel der Icon-Anforderungen! | Coded Style on August 14, 2009 at 10:01AM

    Pingback from  Marketplace: Licht in den Dschungel der Icon-Anforderungen! | Coded Style

  14. Posted by: Marketplace: Licht in den Dschungel der Icon-Anforderungen! | Coded Style on August 14, 2009 at 10:01AM

    Pingback from  Marketplace: Licht in den Dschungel der Icon-Anforderungen! | Coded Style

  15. Posted by: Mer om Marketplace « Peter Wissingers Mobilblogg on September 30, 2009 at 3:07PM

    Pingback from  Mer om Marketplace « Peter Wissingers Mobilblogg

  16. Posted by: TubeRun and WM6.5 « ?????? ?????????????? ?????? ?????????????? on October 06, 2009 at 7:10AM

    Pingback from  TubeRun and WM6.5 « ?????? ?????????????? ?????? ??????????????

  17. Posted by: Icon, I can’t « Things I Don't Understand About Windows Mobile Programming on January 15, 2010 at 12:36PM

    Pingback from  Icon, I can’t « Things I Don't Understand About Windows Mobile Programming

  18. Posted by: hkey hkey - StartTags.com on January 28, 2010 at 1:28PM

    Pingback from  hkey hkey - StartTags.com