Mildly Hurtful Sarcasm

Meaningless ranting, just like everybody else.

Wednesday, January 02, 2008

Windows Mobile Today item font size and color

The newer versions of Windows Mobile allow users to change the default font size, including fonts displayed on Today items. The color of text can (and should) also change according to themes. I've looked up the internet/news groups but couldn't find any documentation or discussion about how to get the right font size and color, so I thought I lay it out here.

Font size can be changed from Start -> Settings -> System -> Screen -> Text Size. However, most of the discussion on the web mistaken the following as the way to get font size:

lf.lfWeight = FW_NORMAL;
lf.lfHeight = -((8.0 * (double)GetDeviceCaps(hDC, LOGPIXELSY) / 72.0) + 0.5);

This is no good, this will only get you font size based on device capability. It doesn't take into account user preferences. The proper way is to retrieve font size using SHGetUIMetrics defined in Aygshell.dll. Since I am using PocketPC 2000 SDK, I will dynamically load the library and find the function manually.

typedef HRESULT (WINAPI* TSHGetUIMetrics)(SHUIMETRICP shuim, PVOID pvBuffer, DWORD cbBufferSize, DWORD* pcbRequired);

DWORD dwFontSize;
TSHGetUIMetrics pSHGetUIMetrics;
HINSTANCE hAyg = GetModuleHandle(_T("Aygshell"));
pSHGetUIMetrics = GetProcAddress(hAyg, _T("SHGetUIMetrics")));
(*pSHGetUIMetrics)(SHUIM_FONTSIZE_PIXEL, &dwFontSize, sizeof(dwFontSize), 0);

Having the font size, creating the font is just a matter of getting the LOGFONT template from the device context, and then change its height.

LOGFONT lfTemplate;
hOldFont = (HFONT)GetCurrentObject(hDC, OBJ_FONT);
GetObject(hOldFont, sizeof(lfTemplate), &lfTemplate);
lfTemplate.lfHeight = GetFontHeight();
lfTemplate.lfWeight = FW_NORMAL;
HFONT hFont = CreateFontIndirect(&lfTemplate);

Voi la. You have now the correct font size. As for font color, it is just a matter of sending a message to the parent (Today) window to retrieve the color itself. Again, using PocketPC 2000 SDK, I need to define the message myself.

#define TODAYM_GETCOLOR (WM_USER + 100)
#define TODAYCOLOR_TEXT 0x10000004
COLORREF clrFont = (COLORREF)SendMessage(hwndParent, TODAYM_GETCOLOR, (WPARAM)TODAYCOLOR_TEXT, 0);
SetTextColor(hDC, clrFont);

There. It's that easy. I wonder why so many people have asked the question but no answers were found using search engines. Let me know if it works for you.

Labels:

1 Comments:

At 8:17 AM, Anonymous Anonymous said...

Works nice. Thank you

 

Post a Comment

<< Home