Monday, June 29, 2009

A better look

Here's a better look for the CrypSafe main view. As you can see I'm using a new font for the item text, added a separation line between the items and painted the background with a different brush for odd-numbered items. The changes to the code are not very dramatic, so let's take a look at them.

The first change is the new font. To use a new font I generally declare a CFont object on the view class like this:

CFont m_largeFont;

This way I know that the font will exist throughout the life cycle of the containing view. Creating the font itself is always a bit of a pain, but i prefer to use the following method because it does give me full control over what is going on. The following code snippet was taken from the view constructor in CCrypSafeView.cpp:

int nLogPixelsY = DRA::LogPixelsY();

lf.lfHeight = DRA::HIDPIMulDiv(-12, nLogPixelsY, 72);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_NORMAL;
lf.lfItalic = FALSE;
lf.lfUnderline = FALSE;
lf.lfStrikeOut = 0;
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
_tcscpy(lf.lfFaceName, TEXT("Tahoma"));

The code at the top is the most important one because it makes sure that we create the font with the right size in points, independently of the resolution of your device's screen.

Now that the new font is ready to use, let's see how to use it on the DrawItem method. First, you need to declare an HFONT variable:

HFONT hFont;

This is used to store the DC's currently selected font while we use our custom font. Setting the new font is easy:

hFont = dc.SelectFont(m_largeFont);

When we are done with the new font, we must set the old DC font back:


To paint the text with a left border, I copied the item CRect to a new instance:

CRect rcText(rcItem);

Before painting, the left value is adjusted:

rcText.left += DRA::SCALEX(4);

Note that this will correctly scale in higher DPI screens. As you can see from the included image, the even-numbered items have a white background while the odd-numbered ones have a very light gray background. As I explained in the previous post, the client code in DrawItem is supposed to paint the background, and doing it is extremely easy:

COLORREF rgb(m_rgbBack);
if(iItem % 2) rgb = RGB(0xf0, 0xf0, 0xf0);
dc.FillRect(&rcItem, brush);

The m_rgbBack variable is declared by CTouchListBase and contains the default background color (this color is used to fill in the unpainted space at the bottom of the list). If the item has an odd number, I replace the default white with a light gray and use this RGB value to create a brush. Painting the item's background is a simple issue of calling FillRect with the supplied item CRect (rcItem).

Now we can paint the item's text making sure that it is painted with a transparent background mode:

int nBkMode = dc.SetBkMode(TRANSPARENT);
dc.DrawText(pItem->GetText(), -1, &rcText, DT_LEFT | DT_VCENTER);

Note that the text is painted using the rcText rectangle, not the item's. This way we get the left margin effect. Finally we can print the bottom separation line:

CPen pen;
HPEN hPen;
pen.CreatePen(PS_SOLID, 1, m_rgbLine);
hPen = dc.SelectPen(pen);
dc.MoveTo(0, rcItem.bottom - 1);
dc.LineTo(rcItem.right, rcItem.bottom - 1);

The m_rgbLine contains the default color for the separation line (gray). As you can see, this is not rocket sience. Next, I will explore how to add a navigation cursor and key handling.

Sample code: (96 KB)


Afalava said...

Thanks for the knowledge to give us through your blog. I would like to use your touchlist in a commercial project and I would like to know if its license allow this. Could you please tell me if this is the case?
Thanks in advance!

João Paulo Figueira said...

You can use the CPOL ( Basically, you can use it for any purpose without royalties. A mention to my name as the original author would be nice.