I wanted to build a simple game on my new ASUS-P527 windows mobile device. I started putting the pieces together and I was almost done with the game logic. I was working on the command line until then and decided it was time for some graphics work. Being new to the windows mobile platform started exploring the different options and boiled down to directx- directdraw. I searched for many tutorials and was really dissatisfied because I couldn't get a simple hello world application that I could get to working in minimum time. The samples provided in the windos mobile professional SDK didnt seem to work on the simulator. It started throwing up crazy errors and I thought I needed a much more simpler application to digest directdraw. Then on debugging and learning a bit of directx finally was able to get a hello world direct draw application working on my windows mobile phone.
DirectDraw is the 2d component of Directx. Until then I had this wrong perception that Directx is only for 3D programming . Also I had heard about GDI which was mainly used in 2D graphics programming.
The following is how I got my hello world direct draw application working. Some of the code is based on the samples provided with SDK and lot of error handling have been omitted for brevity.
Use the Visual Studio Wizard to create a C++ Smart Device project and select Windows
application. This will actually setup a simple window with OK, Help and About Menus. On
executing this application will look something like this

We will add directdraw related code to the existing app to draw a hello world text. Before that make sure you add the "ddraw.lib" library in the Project Properteis->Configuration Properties-> Linker->Input->Additional Dependencies.
We will add two functions "init_direct_draw(HWND)" and the "update_frame()" to the existing code.
The function init_direct_draw sets up and initializes the directdraw objects which we use it
later in the update_frame() function. The code for init_direct_draw() is as below
void init_direct_draw(HWND hWnd){
DDCAPS ddcaps; //directdraw capabilities
HRESULT ddrval; // directdraw return code
DDSURFACEDESC ddsd;
DDSURFACEDESC DDSurfDesc;
DDCAPS ddCaps;
DDCAPS ddHelCaps;
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
printf("after creating DD object ddrval=%x",ddrval);
ddrval = lpDD->SetCooperativeLevel(hWnd , DDSCL_NORMAL );
//query for capabilities
lpDD->GetCaps(&ddCaps, &ddHelCaps);
memset(&DDSurfDesc, 0, sizeof(DDSurfDesc));
DDSurfDesc.dwSize = sizeof(DDSurfDesc);
//get display mode
ddrval = lpDD->GetDisplayMode(&DDSurfDesc );
ScreenX = DDSurfDesc.dwWidth;
ScreenY = DDSurfDesc.dwHeight;
// check the color key hardware capabilities
dwTransType = DDBLT_KEYSRC;
ddcaps.dwSize = sizeof( ddcaps );
// Create surfaces
memset( &ddsd, 0, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
ddsd.dwWidth = ScreenX;
ddsd.dwHeight = ScreenY;
ddrval = lpDD->CreateSurface( &ddsd, &lpFrontBuffer, NULL );
printf("ddrval=%x",ddrval);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
}
The following is a very brief description of what is happening in the init_direct_draw()
function. More specific details are available at MSDN. The "lpDD" is a pointer to the DirectDraw object obtained by the function DirectDrawCreate. The option "DDSCL_NORMAL" specifies that the application will be a windowed application and not the full screen mode for which "DDSCL_FULLSCREEN" needs to be used. The ScreenX and ScreenY are the set to the screen sizes of the retrieved display mode. Directdraw uses the concept of surfaces used to write on video memory which is actually displayed. Here one such surface is created called "lpFrontBuffer" using the "lpDD->CreateSurface" function. Whatever is written onto this surface can be used to display on the screen.
The update_frame() code is as shown below.
static void update_frame()
{
HDC hdc;
RECT rc;
int nMsg;
DDBLTFX ddbltfx;
SIZE size;
rc.left = 0;
rc.top = 25;
rc.bottom = ScreenY;
rc.right = ScreenX;
// Use the blter to do a color fill to clear the back buffer
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = 120;//blue color
lpFrontBuffer->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAITNOTBUSY,
&ddbltfx);
if (lpFrontBuffer->GetDC(&hdc) == DD_OK)
{
SetBkColor(hdc, RGB(0, 0, 0));
SetTextColor(hdc, RGB(255, 0, 0));
nMsg = lstrlen(szMsg);
GetTextExtentPoint(hdc, szMsg, nMsg, &size);
ExtTextOut(hdc,
80,
40,
0, // fuOptions
NULL, // lprc
szMsg,
nMsg,
NULL); // lpDx
lpFrontBuffer->ReleaseDC(hdc);
}
}
This is the code used to draw the hello world text. The lpFrontBuffer which is the primary surface is filled with blue color for the dimensions occupied by the rectangle "rc". The Blt
function is used to do that. (Blt and Flip main functions are key functions used to setup
animation in directdraw). Then we use the ExtTexOut api to draw the "Hello world" at location 80,40 on the screen. Strictly speaking we aren't doing much with directdraw except to setup the minimum required objects and fill a rectangle with blue color. The hello world can be drawn without doing this setup and just using the non directdraw api such as the "ExtTextOut" functions.
Add the two functions just below the line which says
// TODO: Add any drawing code here...
init_direct_draw(hWnd);
update_frame();
Finally on execution , it looks something like this!!

The required source files can be downloaded from this
linkLabels: directdraw, directx, Visual C++, Windows mobile