December 19, 2014
Hot Topics:

Using Bitmaps in WinCE Applications

  • March 10, 2003
  • By Nancy Nicolaisen
  • Send Email »
  • More Articles »

Bitmaps raise all sorts of porting issues: color depth, bitmap organization, size translations, and CE support for ROP codes. We are going to start with a look at basic bitmap raster operations under CE, using the functions BitBlt() and StretchBlt().

Figure 3 - The Dinner Example


Click here for larger image

Device Independent vs. Device Dependent Bitmaps

The real business of the Dinner example happens in the function MyPaint(). First, we fill the client area with gray, because this makes the actions of the various ROP codes more dramatic. /p>

hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
FillRect( hdc, &rt, (HBRUSH)GetStockObject( GRAY_BRUSH ) );

Next, we create a compatible memory DC, load a bitmap image, select it into the memory DC.

hdcMemory = CreateCompatibleDC( hdc );
hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_DINNER ));
SelectObject( hdcMemory, hBmp );
GetObject( hBmp, sizeof(BITMAP), &bmp );

Finally, use either BitBlt() or StretchBlt() to paint it on the screen.

if ( iZoomFactor == NORMAL )
{
  BitBlt(hdc, (GetSystemMetrics(SM_CXSCREEN ) / 10 ),
              (GetSystemMetrics(SM_CYSCREEN ) / 6 ),
              bmp.bmWidth, bmp.bmHeight,
              hdcMemory,
              0, 0, iROPCode );

if ( iZoomFactor == ENLARGE )
{
  StretchBlt(hdc, (GetSystemMetrics(SM_CXSCREEN ) / 10 ),
                  (GetSystemMetrics(SM_CYSCREEN ) / 6 ),
                  bmp.bmWidth * 2, bmp.bmHeight* 2,
                  hdcMemory,
                  0, 0, 
                  bmp.bmWidth, bmp.bmHeight,
                  iROPCode );
}

if ( iZoomFactor == SHRINK )
{
  StretchBlt(hdc, (GetSystemMetrics(SM_CXSCREEN ) / 10 ),
                  (GetSystemMetrics(SM_CYSCREEN ) / 6 ),
                  bmp.bmWidth / 2, bmp.bmHeight / 2,
                  hdcMemory,
                  0, 0, 
                  bmp.bmWidth, bmp.bmHeight,
                  iROPCode );
}

This drawing code is 100% identical on Win 32 and Win CE, but it relies on one pivotal assumption — it assumes that the CE device is capable of displaying the device dependent bitmap identified by IDB_DINNER. As it turns out, this is a safe assumption, and we see, voila, dinner.

This example introduces some of the larger issues of porting graphics to CE, to wit, that getting a graphics application up on CE may well involve modifying data as well as code.

Porting Tip: Porting graphics applications may require more modification of graphics data than code.

We saw in the EtchASketch example that in order to draw a line, you must explicitly supply its initial point. Now with bitmaps, we are confronted with another such consideration: possible differences in color depth between a bitmap and a display device. On the one hand device dependent bitmaps, are compact, ubiquitous, and require very little coding to manipulate. On the other, you run a risk using device dependent bitmaps that a device can't handle them — possibly with catastrophic results. There are two alternatives.

  • Use DDBs carefully and intelligently, limiting the risks involved.
  • Use DIBs, which are universally compatible, at the cost of a great deal more code and data

You probably already know which alternative I favor. If you can live with 16 color or grayscale bitmaps, you will vastly reduce the effort of porting bitmap code. Simply opening the bitmaps in a graphics application and saving them as 16 color or 4 bit gray scale format may allow you device dependent bitmap code to port to Win32 unchanged.

Your safety net on the CE side is provided by the GetDeviceCaps() function:

int GetDeviceCaps(HDC hdc, int nIndex);

The parameters, in the order shown, are the handle to the display context and a constant identifying the device property you are querying. To find out how many colors a device supports, use GetDeviceCaps() like this :

int iNumColors;

//Get the number of colors the device can display
iNumColors = GetDeviceCaps(hdc, NUMCOLORS );

if ( (iNumColors => 16) || (iNumColors == -1) )
{
   //safely use grayscale or 16 color DDBs
}

GetDeviceCaps() returns the number of colors the device can display if color depth is 8 bits or less. If more than 8 bits are used to identify a color, then the function returns -1.

Looking Ahead

In the next installment, we'll examine techniques for making bitmap backgrounds transparent. Transparent backgrounds allow bitmapped images to be layered and seamlessly collaged.

About the Author

Nancy Nicolaisen is a software engineer who has designed and implemented highly modular Windows CE products that include features such as full remote diagnostics, CE-side data compression, dynamically constructed user interface, automatic screen size detection, entry time data validation.

In addition to writing for Developer.com, she has written several books including Making Win 32 Applications Mobile. She has also written numerous articles on programming technology for national publications including Dr. Dobbs, BYTE Magazine, Microsoft Systems Journal, PC Magazine; Computer Shopper, Windows Sources and Databased Advisor.

# # #






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel