Introduction
This article is on creating a custom region from a bitmap and changing the default window skin using this region. A class called CRegionCreator
has been written in order to simplify this problem. Also, an example on skinning a custom window has been shown.
Note
This example is using a default skin bitmap for the free media player BSPlayer found in its installation folder, for the purpose of demonstration.
Background
As a background, a reader can take a look at different CodeProject articles on this subject.
Using the code
To use the code, add the following to the class in which you would like to create custom regions:
#include "RegionCreator.h"
Then, create an instance of the included class and use its only method called CreateRegionFromBitmap()
which will return to you a handle of the new created region:
CRegionCreator regionCreator;
HRGN hRgn = regionCreator.CreateRegionFromBitmap(hBitmap,
transparentColor);
The two arguments passed to this method are a bitmap handle obtained somewhere else and a transparent color in the bitmap. Now, you should have a valid region handle which you should have destroyed after finishing your work with it. In my example, I used a LoadImage()
function to load all kinds of bitmaps (4b, 8b, 16b, 24b, 32b) and set as transparent color the color of the top left pixel in the bitmap, but one can pass in just any color. Every pixel that has this value will not be a part of the resulting region. So, in this manner, a very nice region can be formed, either connected or disconnected.
Changing the default window skin
To apply these regions to custom windows, it is necessary to call SetWindowRgn()
and pass as arguments a window handle, the newly obtained region handle, and a flag which will indicate if the window needs to be repainted.
SetWindowRgn(hWnd, hRgn, TRUE);
That is all! After this step, you will have your window in the shape you like.
Small warnings
You should keep in mind the following:
- Do not destroy the region handle after you have given it to the window by calling the
SetWindowRgn()
method. It's important since it can cause exceptions.
- When applying a new region to an existing window, it is not the same if that window already has some specific window styles. In my example, I created a new child window just with the
WS_CHILD
and WS_VISIBLE
window styles. When trying to apply a region on the window with 2D or 3D borders, some nasty remnants remained which, for sure, ask some additional processing which is not yet implemented. It has to do with the size of the border. Also, it is not the same if your window has a caption bar and a menu bar.
- Currently, you will be able to process only bitmap files with a custom color depth which should be enough for a start.
- Take care of the size (bounding rectangle) of your window compared to the size (bounding rectangle) of the bitmap. In this example, I took the same size for the skinned window as the size of the bitmap in order not to perform any scaling when drawing it to the window device context.
Points of Interest
Working on this subject, I found that it can be very amusing to have a window in different skins. A whole framework can be implemented in this manner, so it's a challenge.