Saturday, August 8, 2009

Add Image background with helloworld ticker on windows mobile

Continuing from the Hello world direct draw application, I modified the application to add a background image and hello world ticker. The idea here is to load a bitmap file and copy it to the directdraw surface and then blt the surface. Also we make the helloworld text tick around by setting up a timer and vary the x position of the drawing at the timer intervals. Quite strange errors like error 1814, error RC2135 kept popping up. It was a little tricky to get it working.

A new function load_bitmap has been newly added. The code is as follows
void load_bitmap(IDirectDrawSurface *pdds){
HINSTANCE hInstance = g_hInst;
HBITMAP hbm; //handle to a bit map
BITMAP bm;
HRESULT hr;
HDC hdcImage;
DDSURFACEDESC ddsd;
HDC hdc;

hbm = (HBITMAP) LoadImage(g_hInst, szBitmap, IMAGE_BITMAP, 0, 0, 0);
DWORD error = GetLastError();

error = GetLastError();
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage,hbm);
GetObject(hbm, sizeof(bm), &bm);

//
// Get size of surface.
//
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
pdds->GetSurfaceDesc(&ddsd);

if ((hr = pdds->GetDC(&hdc)) == DD_OK) // gets the handle of the device context
{ // of the surface.
if (!StretchBlt(hdc, //this draws the bitmap on the surface
0, 0,
ddsd.dwWidth,
ddsd.dwHeight,
hdcImage,
0, 0,
bm.bmWidth, bm.bmHeight,
SRCCOPY)) hr = E_FAIL;
pdds->ReleaseDC(hdc);
}
DeleteDC(hdcImage);
}



The important parts of the code are the LoadImage API call and the StretchBlt GDI call. The LoadImage loads a bitmap file and gets the handle hbm. The GetLastError() call was real handy in debugging the application. This call can fail with error 1814: The specified resource name cannot be found in the image file. Make sure the resource is added using the Add Resource Wizard. Since the LoadImage call takes a pointer to string which is the file name of the bitmap file, make sure you edit the name in the properties window of the resource. (shown in the below figure)


The “pdds” is a pointer to the directdrawsurface. The call pdds->GetHDC(&hdc) gets the device context associated with the surface. Onto this we use the StretchBlt GDI function to draw the bitmap loaded. This bitmap is available in the lpBackBuffer which is used later to draw the background image on the screen. Have used the Splash image from the Donuts example of the SDK samples.
In case you are expermenting with adding/deleting resources, you may end up with errors like “error RC2135 : file not found”. In such situation , go to the resource view and delete the resource ids which are not used in the project.
We setup the timer in the WM_PAINT case in the WndProc function.

// TODO: Add any drawing code here...
init_direct_draw(hWnd);
update_frame();
SetTimer(hWnd,WM_TIMER,100,NULL);



This sends WM_TIMER message every 100ms, which is handled in the WM_TIMER case of the WndProc function. Here we call the update_frame(). So every 100ms , the background image is drawn on the screen. This is done by copying the backbuffer to frontBuffer. Also we draw the “Hello world” with different ‘x’ positions incrementing by 5 for every 100ms. We toggle the movement when it reaches the either ends. The update_frame() code is as shown below.

static void update_frame()
{
HDC hdc;
int nMsg;
SIZE size;
DDBLTFX ddbltfx;


RECT rc;
rc.left =0;
rc.top =0;
rc.bottom = ScreenY;
rc.right= ScreenX;
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);

lpFrontBuffer->Blt(&rc,lpBackBuffer,&rc,NULL,&ddbltfx);


if(toggle == FALSE){
x = x + 5;
if(x>=ScreenX){
toggle = TRUE;
}
}else{
x = x -5;
if(x<=0){
toggle = FALSE;
}
}
if (lpFrontBuffer->GetDC(&hdc) == DD_OK)
{
SetTextColor(hdc, RGB(255, 0, 0));
nMsg = lstrlen(szMsg);
GetTextExtentPoint(hdc, szMsg, nMsg, &size);
ExtTextOut(hdc,
x,
y,
0, // fuOptions
NULL, // lprc
szMsg,
nMsg,
NULL); // lpDx
lpFrontBuffer->ReleaseDC(hdc);
}
}



The complete visual studio project can be downloaded from the following link.

Labels: , , ,

2 Comments:

Blogger Jay said...

Awesome tutorials... Perfect for a beginner like me who has done some openGL, but great for starting a nre project... I am going to try this tutorial this weekend and give some feedback...

For future tutorial suggestions,
How about adding alpha blending and mouse (touch on wm) position tutorials :)...

But honestly, Thanks a bunch... This was athe first tutorial which made sense to me... Thanks once again...

August 12, 2009 7:35 AM  
Blogger AgentHunt said...

Hey thanks very much :-). Was exploring about touch input. will post it in a few days probably.

August 13, 2009 1:59 PM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home