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:

private:
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:

LOGFONT lf;
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.lfQuality = CLEARTYPE_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
_tcscpy(lf.lfFaceName, TEXT("Tahoma"));
m_largeFont.CreateFontIndirect(&lf);

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:

dc.SelectFont(hFont);

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);
brush.CreateSolidBrush(rgb);
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);
dc.SetBkMode(nBkMode);

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);
dc.SelectPen(hPen);

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: CrypSafe01.zip (96 KB)

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.

Wednesday, June 24, 2009

Back to native

After a few days struggling with the BlackBerry JDK, JDE and Eclipse, it's time to get back to predictability and safe ground. Boy, have I missed Visual Studio!

Now that I have some readers actively using, criticizing and suggesting improvements to the Windows Mobile native framework (thank you so much, Anatoly!), I think now is the time to start exercising the code with a real application. Contrary to my early plans, I will start with something that I really need on a day-to-day basis: a mobile password safe. Nowadays I struggle to remember all the mobile phone PINs and PUKs, debit and credit card PINs, online service passwords, just to name a few. I know there are some excellent applications out there ready to be purchased, but what's the fun in that? My idea is very simple: use an encrypted SQL Compact database to store all the sensitive data. The user will be able to add, modify and delete both data and structure (each information category will be stored in a different table). The user interface must be very simple:
  • A main list containing the user's information categories (credit cards, phone PINs...);
  • A secondary list containing the category details;
  • A dialog for editing the details
So, after committing to this, let me roll my sleeves and head back to VS. On the next post I will start publishing the first version of the code.

Monday, June 15, 2009

A simple GPS viewer

Here's a simple GPS viewer application. I wrote it to help me in testing the transition to reference counted pointers in my budding Windows Mobile native (WTL-based) framework. In the process I have learned a few things about reference counted pointers, especially when NOT to use them.

One of the changes I made to the way the CPropertyListView class is used is that it contains pointers to items created on the heap and not on the stack. This means that you now have to create items like this:

m_pGpsFix = new CPropertyString(L"Fix", L"Unknown");

Note that the m_pGpsFix variable is actually a "smart pointer" and you don't have to worry about deleting it in the destructor. Nor does the list, in fact... When each item's reference count reaches zero, the last smart pointer that references the object will delete it (and that's why you cannot have stack allocated items). This is when you should use smart pointers, so when should you use simple C++ pointers? I found out the hard way when adding these items to the list. My original (and right) prototype was:

void CTouchListBase::AddItem(CTouchListItem* pItem)

When I replaced the C++ pointer with a smart one, I immediately lost one of the best features these things have: the ability of a base class pointer to refer to a derived class object. Understanding that I don't know enough about C++ class templates to make this work (not even sure if that's possible - will have to look at Jossutti's book), I decided to fall back to straight C++ pointers. This poses no problem because the method internally will use the smart pointer class constructor to build a new instance using the raw pointer and add it to the underlying array, so the reference counting is respected.

The sample application just starts the GPSID and displays some data from the GPS on a dialog. As you can see from the ZIP file, there are two additional library projects that make up the framework. Note that these are subject to change and do have bugs!

Sample code: GpsView.zip (93 KB)

Thursday, June 11, 2009

unresolved external symbol CLSID_ImagingFactory

Just started out a new sample project that illustrates how to use the WM libraries I'm writing, and got the following link errors:

1>wmfw.lib(Image.obj) : error LNK2001: unresolved external symbol CLSID_ImagingFactory
1>wmfw.lib(Image.obj) : error LNK2001: unresolved external symbol IID_IImagingFactory


This means that the linker cannot find the symbols CLSID_ImagingFactory and
IID_IImagingFactory, required to use the imaging library on Windows Mobile. If you look at the documentation, you will see that a link to the imaging.lib file is required but it will not work (at least it does not work for me).

The solution I found is to force the inclusion of these symbols using a dummy file that I usually name guids.cpp. Here's the content:

#include "stdafx.h"
#include <initguid.h>
#include <imgguids.h>


The initguid.h include redefines the DEFINE_GUID macro that is used by imgguids.h so that it declares a GUID along with its value instead of making an external reference to the same symbol.

Compile and link and the error goes away.

More native memory in WM 6.x

Here's a very interesting blog post from The Windows Mobile RSS: More Memory For ALL in WM 6.x. As you can see, folks at Microsoft still care about us, native mobile developers.

Wednesday, June 03, 2009

VS 2010 and Smart Device Development

This updated link explains it all: Smart Device development is not supported by Visual Studio 2010 Beta 1, but will (somehow) be supported by the final release. Quoting:

"Microsoft is committed to making Visual Studio a great development tool for the mobile device developer, and will deliver mobile device tools for Visual Studio 2010, but cannot share details now. For existing Visual Studio 2008 mobile developers, Microsoft will release a new Windows Mobile 6.5 emulator in the upcoming months that works with the Windows Mobile 6 SDK."

Now, back to work.

Saturday, May 30, 2009

Is Native Code Hard?

If you read this blog then probably your answer is, like mine, no. So what's the difference between native and managed that makes people avoid native code like the plague? What makes people not want to come back? In my opinion there are a few reasons, especially for Windows Mobile native code:
  • Lack of tools - just try to write a C# application using notepad and the command line compiler and you will see how much tools make a managed developer life easy. There is no comparable level of tool support for native code developers, and this may be linked to the next point.
  • Lack of comprehensive and cohesive libraries and frameworks - the Win32 API is way too low-level for most uses. It's very nice to be able to use it directly without paying the P/Invoke price, but this comes at a cost of having to write dozens of lines of code to achieve a very simple outcome. The OLE DB and MAPI COM interfaces are a perfect example of this - way too complex to use as they are offered. Just compare the "stock" OLE DB samples with the OLE DB Client library I published here...
  • Memory management - this is a minor issue for small applications but when the scale starts to grow it becomes a headache. When are you supposed to delete that object? Is it safe to do it now? Are there other objects referring to it?
I have recently been confronted with the memory management issue in a relatively complex application when I found myself wanting to have the memory management of a particular set of objects to be done automatically. These objects are referred to by an arbitrary number of other objects and determining when their life cycle ended was becoming more and more difficult, especially because they were being referred to by different threads.

There are two basic approaches to automatic memory management that have been used for quite a long time:
  • Reference counting - The iPhone uses a reference counting mechanism to determine when a given object can be removed from memory. The price you pay for this type of memory management is that you have to remember to increment and decrement the memory reference counts. Failing to do this will result in memory leaks. The iPhone uses an optional "autorelease pool" object that kind of protects you from this.
  • Garbage collection - The Java and .NET platforms both use garbage collection to reclaim the memory of objects that are no longer active. The price you pay for this is that the GC has a mind of its own and stops your code in order to clean up the mess. On mobile devices, if you don't manage your memory by reusing objects and by avoiding excessive allocations, the GC will kill your application performance.
One of the interesting advantages of C++ is that it implements deteministic object destruction: when your statically allocated object goes out of scope, the destructor is called. This behavior allows us to implement classes like CWaitCursor that displays the wait cursor on the constructor and hide it or replace it on the destructor. You just have to create a variable of that type and the wait cursor will be shown while the object is alive.

If we couple this with a simple reference counting mechanism, we can actually get all the benefits of a reference-counted memory management scheme without the pain that is imposed on us by the iPhone: we don't have to remember when to increment and decrement the references. How? The dead-old solution is to use reference counted smart pointers to manage our objects' life cycles.

After performing a search for reference-counted smart pointers, and realizing that my needs were quite simple, I decided to roll my own. The first thing we need is a place where to store the reference counts. Some implementations use a proxy object to do this but, for simplicity sake, I decided to put the reference count right on the object through inheritance. This has the disadvantage of having to make all the reference-counted objects inherit from one class, but it's a simple class that will only add four bytes to the object size:


class CRefCount
{
private:
LONG m_nRefCount;

public:
CRefCount(void) : m_nRefCount(0) { };

void RefIncrement()
{
InterlockedIncrement(&m_nRefCount);
}

bool RefDecrement()
{
return InterlockedDecrement(&m_nRefCount) <= 0; } };

Note that I'm using the InterlockedIncrement and InterlockedDecrement to manage the reference count because these methods can be used from different threads. Also, note that the reference count starts at zero (and not at one like on the iPhone) because I want to count how many smart pointers are referring to this object. Let's see how the smart pointer class is defined:


template <class T>
class CRefPtr
{
private:
T *p;

public:
CRefPtr() : p(NULL) { }
CRefPtr(T *pT) : p(pT)
{
if(p)
p->RefIncrement();
}

CRefPtr(const CRefPtr& ptr) : p(ptr.p)
{
if(p)
p->RefIncrement();
}

~CRefPtr() throw()
{
Release();
}

void Release()
{
T* pTemp = p;

if(pTemp)
{
p = NULL;
if(pTemp->RefDecrement())
delete pTemp;
}
}

void Attach(T* p1)
{
Release();
p = p1;
}

operator T*() const throw()
{
return p;
}

T& operator*() const
{
ATLENSURE(p!=NULL);
return *p;
}

bool operator!() const throw()
{
return (p == NULL);
}

T* operator=(const CRefPtr& rhs)
{
if(this != &rhs)
{
Release();
p = rhs.p;
if(p)
p->RefIncrement();
}
return *this;
}

T* operator=(T* pT)
{
if(p != pT)
{
Release();
p = pT;
if(p)
p->RefIncrement();
}
return *this;
}

T* operator->() const
{
ATLASSERT(p != NULL);
return p;
}
};

As you can see each smart pointer takes up the same amount of memory as a regular pointer, so you can safely pass and return it by value from your own methods and functions. This is a very bare-bones implementation and may lack some more sophisticated features, but so far has worked quite well for me. You use it like a CComPtr (I confess that I did look it up when writing this code).

Friday, May 29, 2009

Gynoid

There is a new article on Code Project by Vincent Richomme where he presents the Gynoid framework for cross-platform mobile development. In the included sample, Vincent was so kind as to use the "touch list" WTL control that I have published in this blog. Thank you Vincent!

P.S.: I'm not a guru, I just love this stuff and write about it... ;-)

Saturday, May 23, 2009

Integer Trigonometry

Adding a live GPS feed to a map means, besides near-second updates, the requirement to display a location marker with the current heading. The Window Mobile GPSID provides the current heading in the GPS_POSITION structure as the fHeading value, representing the angle in degrees between the current heading and true North (zero degrees). So how do you go about drawing a compass like the one in the picture?

The drawing is composed of two simple triangles: red for North and blue for South. The drawing is performed by using the Polygon GDI function that takes a list of points describing a closed shape and draws it using the selected pen and brush. Nothing new here. The interesting challenge is how to draw the image in the different angles without a big performance hit (translated: how to implement fast trigonometry functions).

Current Windows Mobile devices are not guaranteed to have an FPU unit that will do all the floating point math for you. If you use the Compact Framework, you are sure that all floating point calculations are performed in a software emulated FPU, so they are much slower than what they could be when performed with a real FPU. When using native code, you have the advantage of using the FPU if one is available, but the code will fall back to the emulator if the FPU is missing.

My approach here was to skip any floating point processing at all. There are two reasons for this:
  1. Drawing a map on a Windos Mobile device is a resource-intensive operation, especially if you are updating it frequently and you want to spend the least amount of time drawing any decorations on top of it. So a fast implementation is required.
  2. This object requires very simple transformations (rotation plus offset) and the required accuracy of the final result is not very high. In fact, it is somewhat low considering the relatively small resolution of WM device screens. The bottom line is that you can live with a bit of error when drawing your compass (this is not rocket science).
So how do you calculate a rotation transformation? Please refer to a good book on the subject (I'm using this lovely book as a reference: Essential Mathematics for Games and Interactive Applications) and you will see that it all boils down to these two simple equations (transforms a point through a counter-clockwise rotation around the origin):
  • x' = x cos(a) - y sin(a)
  • y' = x sin(a) + y cos(a)
Where (x, y) are the original point coordinates, (x', y') are the transformed point coordinates and a is the rotation angle. The first thing you need to do is to "draw" your compass by defining the vertexes assuming that the center of your coordinate system is in the center of the image. In this case, I used the following points:
  • (0, 32) - North
  • (-7, 0) - West
  • (0, -32) - South
  • (8, 0) - East
The reason why I'm not using (7, 0) for East is simple: the final image looks much better on a discrete screen if it has an odd width. If you look at the sample project you will see that I split the compass into two distinct triangles in order to draw them with different pens and brushes.

Now the interesting bit is how I implemented the sin and cos functions: through a table lookup. Assuming that you can live with an error of one degree when specifying the angle, all you need is a precomputed list of the sin values between 0 and 90 degrees. Using basic trigonometry you can derive all sin and cos values from the first quadrant sin values. If you look at the code, you will see that the precomputed sin values are scaled by 10,000. When calculating x sin(a) the code uses the precomputed value and divides the result by 10,000 to get the approximate result (you can use a higher scale for a higher resolution calculation, but that might not be required for this purpose). You can see the implementation of these functions in the FastTrig.h and FastTrig.cpp files in the sample.

Before we can draw our compass on the screen, we must take care of two important issues:
  1. The original compass coordinates are centered around the origin, so we must transform them further to make it fully visible on the screen;
  2. The screen coordinates of a Windows Mobile device are a bit different: while x grows to the right as we expect, y grows down and not up.
This means that beside the rotation we must apply a translation and a "mirror" transformation. In the sample code, I translate by adding the x and y offsets corresponding to the middle of the screen and then the y coordinate is flipped by subtracting it from the window height. Enough of this talk, here's the sample project: GpsCompass.zip.

On a future post I will update this code so that it uses a double buffer painting method to eliminate flickering and connect the compass direction to the GPS heading.

Wednesday, May 20, 2009

One GPS, multiple windows

After publishing the simple GPS class on my last post, I found myself in a situation where I needed the same CGps object to notify more than one window whenever a new GPS event arrived. My scenario is quite simple: while feeding a window with a map, I also need the same CGps object to notify another window where I display some GPS information like the current latitude and longitude coordinates.

The original code supports notifications for one window only so, to solve this issue I could create another instance of the CGps class and have it notify the new window. Although this would work, it would also create an extra thread in the appliction (if you look at the CGps implementation, you will see that it uses a thread to wait on the GPSID events) which is unneeded and consumes more system resources.

I ended up by devising a simpler solution: add multiple window handle - message pairs to the notification mechanism. To implement this I created a new class - CWindowNotifier - that is nothing more than a simple array of HWND and UINT pairs. When the consuming object wants to send a notification to a set of windows, it just calls the appropriate method (Post or Send). If one of the notification windows was closed, the code automatically removes it from the notification list. Using this class is very simple: just call the AddWindow method with the HWND you want to notify and a UINT value containing the message code for the notification. When you want to send a notification use either the Post or Send methods. The Post method uses the PostMessage API so it returns immediately and is the one I recommend for most uses. The Send method uses the SendMessage API, so it works synchronously and waits before all notification windows have responded. You can get the class source code here.

The updated CGps source code is here. Note that this new version uses a new wrapper for the CRITICAL_SECTION objects which you can find here. Enjoy.

Friday, May 15, 2009

A simple GPS reader class

I've been recently involved in a number of projects that require information from the Window Mobile GPS Intermediate Driver. The usage pattern is quite similar in all cases as the application needs to update a window based on the GPS information stream. There are two possible approaches for this: you can use a window timer and poll the GPSID or you can create a worker thread that waits on the GPS stream to wake up and notify the window through a PostMessage call.

The CGps class (download here) is very simple to use. On your window class just declare a member variable of type CGps, like this:

CGps m_gps;

To start receiving GPS data, just call

m_gps.Start(m_hWnd, WM_GPS);

where WM_GPS is a user-defined window message. You can use something like:

#define WM_GPS (WM_USER + 0x654)

Now you need to handle the WM_GPS message in your code (this will be somewhat different if you are using straight API, MFC or WTL). Note that when handling the message, both wParam and lParam are zero - the message works as a simple notification mechanism to let the window class or procedure know that the GPS updated its data. You read the GPS information quite simply:

GPS_POSITION gpsPos;

m_gps.GetPosition(&gpsPos);

To stop the GPS events you can either call Stop() or let the destructor do that for you when the object goes out of scope and is destroyed.

When implementing this class, I had to work around the now-known GPSID API bug. On some devices, the GPSGetPosition API uses a different size for the GPS_POSITION structure (something that has been explained by John Spaith here). The workaround is simple: just feed the thing with a fake buffer and cast it back to a GPS_POSITION. If you look at the implementation, you will see all this trickery at work. But don't worry - it does work!

Tuesday, May 12, 2009

Windows Mobile Marketplace now open

The Windows Mobile Marketplace is now open (but only for US developers?)

Thursday, May 07, 2009

AllKeys, documented

Here is the key capturing API we've all been waiting for since the demise of GAPI: AllKeys.

Wednesday, May 06, 2009

WTL frames, toolbars and headers

The WTL CFrameWindowImpl class template uses a very simple approach to manage the client, toolbar and status bar windows. The preset arrangement for these windows is very simple:
  • a client view that occupies most of the frame's client area;
  • an optional toolbar window that is placed at the top of the frame's client area and above the client view;
  • an optional status bar placed at the bottom of the frame's client area and below the client view.
The frame window already knows how to handle the three child windows. Each frame contains three member variables for them:
  • m_hWndClient for the client view;
  • m_hWndToolBar for the top toolbar window and
  • m_hWndStatusBar for bottom status bar
To make the three child windows work together you must create them and assign them to the appropriate member variable. The top and bottom windows must implement a special handling of the WM_SIZE message because this is how the frame tells each window to place itself in its client area and thus calculate the remaining area for the client view. This special message is nothing but a WM_SIZE message with both parameters (wParam and lParam) set to zero. Here's a sample from my production code:



void OnSize(UINT nType, CSize size)
{
if(size.cx == 0 && size.cy == 0)
{
CWindow wndParent(GetParent());
CRect rc;

wndParent.GetClientRect(&rc);
rc.top = rc.bottom - m_cyToolbar;
MoveWindow(&rc);
}
}

Easy, huh?

Wednesday, April 29, 2009

Intercepting mail messages

Ever wondered how to intercept an incoming mail message from native code? The Windows Mobile RSS blog explains how: a very interesting read!

Monday, April 27, 2009

SQL Compact and threads

Do you remember the days of Pocket PC 2002 and 2003? Life was pretty simple with no need for certificates, a single screen size and SQL CE only ran on devices. Then Microsoft released SQL Compact 3.1 and suddenly the small database was also on the desktop. By this time I already had a small set of tools that remotely accessed the engine via a streamed RAPI interface and was confronted with the need to port the code to the desktop.

In its classical form, the code runs in two different processors with an asynchronous link. Porting the code to the desktop, where both the client and the server ran on the same process, meant either a major rewrite or a smart adaptation. I chose the latter and implemented a DMA data stream that is implemented by the "server" DLL on the desktop. The client merely uses a virtual stream that can be attached to a variety of server endpoints, like a RAPI server, a TCP/IP server or even a local server running in the same process (but on different threads).

This has worked quite successfully until last week when I got a report from a customer complaining about a mysterious error. After exporting a very large (and I mean very large) database from SQL Server to SQL Compact 3.5 on the desktop, the database file would end up with over 350 MB of size but zero tables. After repairing the database it would shrink down to the 20 KB empty databases have.

I first suspected of the transaction mechanism because the whole process (table creation, data transfer and final script execution) is executed under a single transaction. After confirming with Microsoft that there was no known transaction size limitation, I got back to the drawing board in bewilderment. To make matters worse, no error was being reported!

The product that caused this issue (Data Port Wizard) has a very simple usage pattern: you set the source and target databases, set some options and run the data transfer process. At the end the application reports success or error and then quits (after user confirmation). As it turned out, the problem happened when the application exited.

When transferring data to a desktop SDF file, everything works under the same desktop process. The SQL Compact data provider runs in its own thread (not on the UI thread) due to the reason I pointed out at the beginning: I wanted to reuse the remote provider code that runs on a different CPU, so I implemented it as running on a different thread with a DMA communication to the client code. When the client application closes, it signals the SQL Compact data provider to shut down and waits a little while for it to reply. If no reply arrives on time, the desktop client proceeds to terminate the application.

Apparently with very large databases, the SQL Compact engine takes a bit longer to shut down. This is in fact something to be expected because there are larger buffers to flush to storage and there is also the auto-shrink feature that runs when the connection closes. When this whole thing is running on a remote device, your desktop client can afford not to wait for the remote provider to shut down because it is running in a different CPU. When running under the same process, you don't have that luxury. If you don't wait for the SQL Compact engine to shut down in its own thread and you shut down the application, you will be preventing the database engine from correctly shutting down altogether. You can imagine the mayhem this causes to your database...

Lesson: if you run SQL Compact on a different thread, make sure you wait until the connection closes before you shut down your application. You have been warned!

Tuesday, April 21, 2009

Native GDI+ on CodeProject

Vincent Richomme just posted an article on Code Project on how to use the GDI+ libaries through native code. If you think it's hard to add that extra cool look to your native GDI app, do take a look at Vincent's article!

Wednesday, April 15, 2009

IE8 and Visual Studio

If you installed Internet Explorer 8 on your development machine, you may find it impossible to create new C++ projects. Here's an explanation and workaround.

Tuesday, April 14, 2009

Is IImage caching a good idea?

On my previous post I described a very simple solution to improve the performance of IImage::Draw - caching the converted image. This does speed up the process of drawing the alpha blended picture but has one drawback: you store the image twice. From what I understood from the IImagingFactory::CreateImageFromBuffer online documentation, the supplied buffer is not immediately used and must be there throughout the IImage object lifetime. So when you cache the image you are essentially storing two representations of the same thing (the original encoding  and the decoded version). While this may not be a big issue for small images, this becomes a serious problem when using lots of images and / or larger images. So what can we do about this?

The idea is to have a single 32 bpp ARGB HBITMAP in memory per image. As I showed before, using the shell API to load the images is a bad idea because it shrinks them to 16 bpp. Is there any other alternative to this? We can try to create a 32 bpp bitmap in memory and then use the IImage object to paint it. After releasing the IImage object, we should get a properly-formatted 32 bpp ARGB bitmap. On my next post I will illustrate this technique that was validated by master guru Alex Feinman