Click here to Skip to main content
6,822,613 members and growing! (17,979 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » Mobile Development » Dialogs and Windows     Intermediate

Fast region creation on WinCE/PocketPC

By dzolee

A fast solution to create custom-shaped windows from a bitmap mask
VC8.0, eVC4.0, Windows, WinMobile5, MFC, VS2005, Dev
Posted:24 Mar 2007
Views:19,225
Bookmarked:29 times
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
8 votes for this article.
Popularity: 4.24 Rating: 4.69 out of 5

1

2

3
1 vote, 12.5%
4
7 votes, 87.5%
5
Screenshot - cergn.jpg

Introduction

Modern applications often have a customized, "skinned" look. There are a lot of tools, libraries and tutorials on creating skinned apps for desktop Windows systems. Unfortunately this is not the case with WinCE or PocketPC. If you try to adapt ideas or code from Win32 programs, you will experience a lot of challenges, just as I had while creating the Skinnable Dialogs Framework. A very basic feature of a skinnable application is to have custom-shaped controls or main windows. Creating non-rectangular windows is a relatively easy task in the Win32 world. All you have to do is, create a region based on a bitmap mask and set it for your window with the SetWindowRgn API.

Creating a region is the first step towards a custom-shaped window.
Every region creator that I've seen so far uses the same idea:

  • uses a bitmap mask to define the visible and transparent regions of a window
  • calls the GetPixel funcion on the bitmap mask to see which areas of the window should be transparent
  • then calls CreateRectRgn to create new rectangular regions based on pixels or pixel blocks
  • and finally combines these smaller regions into the final, custom-shaped region with the CombineRgn function.
But have you tried this approach on PocketPC or WinCE? Well I have, and the results were very disappointing. The smiley bitmap above was parsed for several minutes!
I found that region functions work well on WinCE only if you want to combine a couple of rectangular regions. But when it comes to hundreds of small regions (just as with a bitmap mask), CombineRgn becomes unacceptably slow.
In this article I'd like to present a much faster solution for custom region creation using the ExtCreateRegion API. The code works fine on WinCE/PocketPC and also on Win32. I've tested it with Embedded Visual C++ 4 and Visual Studio 2005, too.

The solution

The CRegionBuilder class (see files RegionBuilder.h and RegionBuilder.cpp) has only one public function, BuildRegion. It uses the ExtCreateRegion API to create a region from manually built region data. The region data consists of a header (a RGNDATAHEADER structure) and an array of RECT structures that make up the region.
The BuildRegion function takes two parameters, a bitmap handle of a loaded bitmap and a pointer to store the resulting region handle:

    RegionBuilderError BuildRegion(HBITMAP hBmp, HRGN *pDest);

The function includes every non-black pixel in the resulting region.
Possible return values are: rbeOK, rbeNoMem and rbeGDIError as defined in RegionBuilder.h. If memory allocation fails, it returns rbeNoMem. If any of the used GDI functions return an error, it returns rbeGDIError. If all goes fine, the function return rbeOK and the resulting region handle will be copied to the destination.

Some tips:

  • Do not call DeleteObject on the region handle until your window is visible, instead, free it in OnDestroy.
  • Drawing custom-shaped windows on CE devices is considerably slower than drawing regular windows, so don't expect hyper-performance.
  • If you use a very complicated bitmap mask that would result in a thousands of region RECTs (eg. 640x480 "random noise"), you might experience sudden device crashes or other drawing problems.

How it works

The BuildRegion function first gets bitmap dimensions with the GDI GetObject function. To avoid the slow GetPixel function, it reads bitmap bits directly. But the GetObject function does not return a pointer to the bitmap bits unless the bitmap was created with CreateDIBSection. So, BuildRegion creates a new, monochrome bitmap using this function and then copies the source bitmap to it with BitBlt. Using a monochrome version of the bitmap saves a lot of precious memory.

After the monochrome copy has been created, the function loops through the bitmap bits to see how much memory will be required for the RECT array. If there are horizontal lines in the bitmap, they will be packed into one RECT.

Then the function allocates a proper memory block for the rectangles and loops through the bits again to build the RECT array.

It loops twice through the bitmap, so it allocates only the required amount of memory. Despite this it's still pretty fast I think. A lot faster than the ordinary GetPixel + CombineRgn method.

Have fun!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

dzolee


Member
I'm a 29-year old software developer. I began programming on a ZX Spectrum many years ago. I've programmed a number of high level languages (Basic, Pascal, C/C++, Java, Php, Perl, C#). I also like reverse-engineering and assembler programming.
I'm interested in handheld devices programming, especially Windows Mobile devices.
Occupation: Software Developer (Senior)
Location: Hungary Hungary

Other popular Mobile Development articles:

  • Writing Your Own GPS Applications: Part 2
    In part two of the series, the author of "GPS.NET" teaches developers how to write GPS applications suitable for the real world by mastering GPS precision concepts. Source code includes a working NMEA interpreter and sample high-precision application in C# and VB.NET.
  • Writing Your Own GPS Applications: Part I
    What is it that GPS applications need to be good enough to use for in-car navigation? Also, how does the process of interpreting GPS data actually work? In this three-part series, I will cover both topics and give you the skills you need to write a commercial-grade GPS application.
  • Learn How to Find GPS Location on Any SmartPhone, and Then Make it Relevant
    A step by step tutorial for getting GPS from any SmartPhone, even without GPS built in, and then making location useful.
  • Windows Mobile, iPhone, Android - Marketplace Comparison
    Detailed comparison between Windows Mobile Marketplace, Apple's iPhone AppStore and Android Market from developer point of view.
  • iPhone UI in Windows Mobile
    It's an interface that works with transparency effects. As a sample I used an interface just like the iPhone one. In this tutorial I am explaining how simple is working with transparency on Windows Mobile.
Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
GeneralWould be great to have its wrapper in .NET CF! PinmemberAlexander Aphonin4:33 4 Feb '09  
QuestionTransparent window on Windows Mobile PinmemberVoland.cpp0:52 10 Oct '08  
AnswerRe: Transparent window on Windows Mobile Pinmemberdzolee0:57 10 Oct '08  
GeneralThanks! PinmemberQuentin Pouplard9:57 5 Aug '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.

PermaLink | Privacy | Terms of Use
Last Updated: 24 Mar 2007
Editor: Chris Maunder
Copyright 2007 by dzolee
Everything else Copyright © CodeProject, 1999-2010
Web22 | Advertise on the Code Project