Search This Blog

Monday, September 7, 2009

Regions and Clipping Window to Custom Shapes (Win32 VC++)

Intro.

You might have noticed certain applications have window which differ from the standard, normal window with Rectangle shape, a Title bar, Size bar and System menu. Well, a most common example is the Windows Media Player which can be found on Windows XP versions. The Windows Media Player 9 series Installed by default on all Microsoft WindowsXP OS possesses a different appearence on screen, with a new window shape and appearence. You should also thought about how to make your application's window also customized and re-shaped like that. Well, thats a good idea when thinking about GUI and dressing up your application's window.

How to do.

Before getting into the code, lets learn about something about Window Regions. Well, when talking about regions some people may wonder what this "region" is. The "Region" we use here in a window is exactly whatthe name denotes. It can be a specific area of any defined shape. There is nothing strict that a region must be rectangle. A region can be sphere, elliptic or any other combined shape you desire.To apply a region to a window, you must first declare a region handle (HRGN), define the region with calls to CreateRectRgn, CreateEllipticRgn, or CreatePolygonRgn( Refer to MSDN for more Region API's ). Then combine your regions( only if you have multiple regions defined) into one region with calls to CombineRgn, and then apply the final region to your window with a call to SetWindowRgn.


A region is an object, so you should DeleteObject them when you are done with them. :-)


I'm going to demonstrate a sample window with two Regions. Both are elliptical regions and i combine both these regions to a single one. Finally, i clip or cut my window in shape of this new custom region. The WIndow shape is modified to a defined region by using SetWindowRgn() API.


Code.



HRGN hRegion1 = CreateEllipticRgn(0, 30 , 200, 200);
HRGN hRegion2 = CreateEllipticRgn(0, 180, 200, 200);

CombineRgn(hRegion1, hRegion1, hRegion2, RGN_OR);
SetWindowRgn(hWnd, hRegion1, true);

DeleteObject(hRegion1);
DeleteObject(hRegion2);

The RGN_OR flag set in CombineRgn() performs logical ORing operation with both the regions, and apply it to the Window using a call to SetWindowRgn().


Now, you have a strange window shape. Since there is no Title Bar and Standard Window Buttons, you cannot drag the Window over the screen or you cannot close or minimize it. So, you have to close the application from Debugger or from Task Manager in Windows. You can add custom buttons by your own for Close and Minimize operation or whatever you like in this window. Now, what's the deal with Dragging?


A window which cannot be dragged across the screen is unimaginable and will be weird. The Window's title bar which helps us to drag is clipped away. Dont worry, we have a solution say a trick.


We will trick the Window whenever a left mouseclick happens within the window region to convince it the click happened on its Title bar. So, when we click inside the window and drag, it will get dragged across the screen as if it were dragged by clicking its titlebar.
We'll need to add the following case to our message handler's switch:

case WM_LBUTTONDOWN:
SendMessage( hWnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL );
break;

WM_LBUTTONDOWN is sent whenever the user presses the left mouse button while the mouse is over the window. So when we catch this message, we send a WM_NCLBUTTONDOWN message to the title bar (HTCAPTION), tricking it into thinking we clicked it. Remember, clipping window will not delete other parts of the window. So, the titlebar is still present but not visible and it still has a message handler waiting for processing messages.


PS : Feedbacks helps me to know and improve :=)

No comments:

Post a Comment