Friday, June 26, 2009

The CrypSafe prototype

Today I present the very first iteration of the mobile password safe application. First I decided to name it "CrypSafe". Second, I also decided to post the code in very small increments so that the whole process of using the WM framework becomes clearer (and also to allow me to add changes as I see fit). Third, I'm starting off with a prototype.

The application architecture is actually very simple (as usual, I'm using WTL 8.0):
  • A main frame window that contains the content views and any decorations
  • A category view that shows the information categories in the safe
  • A detail view showing the individual items in each category
  • An item editing dialog
More items will be added if need arises, but for now I would say that this is enough. When you create a new project using the WTL Mobile Application Wizard, you get a lot of code created for you. In fact, after creating the project you can compile and run (and it will run - just make sure that the WTL include files are reachable for both the C++ and resource compilers). I usually create an SDI application with a child view because it's the most flexible arrangement. You can skip the child view and pain directly on the frame's client area, but this will make it harder for you to use multiple views. Incidentally, the code that flips views does paint on the frame's client area, but that's another story.

After creating your initial project, our first stop is to change the view window (see the source code):

class CCrypSafeView : public CTouchList<CCrypSafeView>, public CChildView<CCrypSafeView>

This means that our view will implement both a "touch list" and will also behave like a switchable child view. Next we need to remove the standard painting protocol and replace it with the touch list's:

virtual void DrawItem(HDC hDC, int iItem, CRect &rcItem);

Yes, we only need this because the list is painted item by item. Remove the OnPaint handler because it is not needed (it's implemented by the base class). I also added a default constructor where I placed the initial list of categories for the prototype:


CCrypSafeView::CCrypSafeView()
{
AddItem(new CTouchListItem(L"Credit Cards"));
AddItem(new CTouchListItem(L"Debit Cards"));
AddItem(new CTouchListItem(L"Mail Accounts"));
AddItem(new CTouchListItem(L"SIM Cards"));
AddItem(new CTouchListItem(L"User Accounts"));
AddItem(new CTouchListItem(L"Web Sites"));
}

Note that these items are not explicitly delete anywhere in the code because their pointers are reference counted (internally). Finally, let's see how to paint the items:


void CCrypSafeView::DrawItem(HDC hDC, int iItem, CRect &rcItem)
{
CDCHandle dc(hDC);
PTouchListItem pItem = GetItem(iItem);

dc.DrawText(pItem-&gtGetText(), -1, &rcItem, DT_LEFT);
}

Note that the PTouchListItem type is a typedef that denotes the reference-counted version of a pointer to a CTouchListItem object.

As you can see from the image, the result is less than satisfactory. The whole list is painted on an off-screen bitmap that is initialized to solid black (hence the black areas of the screen). The bottom of the list is automatically filled with the background color, but not the individual items - you must fill in the background for yourself. We also need to make the item font larger (possibly bold and with ClearType rendering for a better reading experience). As you can see each row has a height of 40 pixels (80 on high DPI machines) in order to accommodate a 32x32 (64x64 on high DPI machines) image. The text will have to be correctly formatted in order to better fill each row.

For the time being, you can take a peek at the first version of the code here.

P.S.: Anatoly, I have not included all of your changes yet.

2 comments:

Unknown said...

Hello João,

I have to say that you are making a great effort regarding the CrypSafe application. But I have one comment about your work, don't you think that it will be a good idea to mention what do the person who will use this application need in order to compile it correctly? I tried to compile it both on VS2008 and VS2005, but I got a lot of errors, fixed many of them, but i keep getting more and more. So, can you please tell me what do I need or have exactly in order to compile correctly?

Thank you.

João Paulo Figueira said...

You are right - I will write a post on this subject pretty soon. Thanks for pointing this out!