_   _                                                          _   _
    ((___))                                                        ((___))
    [ x x ]                _                                       [ x x ]
     \   /  _   |_|_   _ _|_  _|_ |_  _    _| _  _. _|   _ _        \   /
     (' ') (_|_|| |_  (_) |    |_ | |(/_  (_|(/_(_|(_|  (_(_)\_/\_/ (' ')
      (U)                                                            (U)
     .ooM                     cDc communications                    .ooM

                        Non-rectangular Window Regions
                                 by Sir Dystic

The windows most of us are used to are always rectangular.  It's only very 
recently that we have started to see applications using non-rectangular window 
regions, but so far mostly just MP3 players.  When I wrote the Back Orifice
GUI client, I wanted to make a window that was more than just a rectangle, but
I cheated.  The actual window itself was in fact always rectangular, but there
was a graphic of a warrior choking a goat hanging off the upper left of the
window.  I did this by opening the device context of the desktop, painting the
graphics next to wherever the window is moved to, and any time the window is
moved away I told the desktop to redraw the portion of the screen that had
just been covered by the graphic. 

While this method works okay, the graphic is not actually part of the window 
and in addition to the fact that if you try and click on the graphic, the
click will actually land on the window behind the graphic.  Also, if the window
below the graphic redraws itself, it will affect the graphic above it.  It
turns out that a window does not have to be at all rectangular, in fact in can
be any (with limits) bitwise combination of ellipses, polygons and rounded
rectangles, and by bitwise combination, I mean that you can AND, OR, XOR and
NOT regions.  The windows region actually defines the parts of the window that
can be painted to or receive user input like mouse movments and clicks. 

The window region APIs for getting and setting the region of a window are
GetWindowRgn and SetWindowRgn. The APIs for creating the regions of the
different shapes 
are:

    CreateEllipticRgn
	CreatePolygonRgn
	CreatePolyPolygonRgn
	CreateRectRgn
	CreateRoundRectRgn
	
You can create complex regions by adding and subtracting these shapes from a
region using CombineRgn.  One of the things that threw me for a while, and I
might still be missing something is that when you use CombineRgn, the target
region must already exist, and it's contents will just be replaced.  I guess
what threw me is that there's no API to create an empty region, but for the
first time you call CombineRgn just create a simple rectangular region to
pass.

It is very important to remember to delete regions or you will quickly run out
of resources, but once you have passed a window region to SetWindowRgn do not
try to close it.  That region is now owned by the system, and I assume is
closed when a different window region is set. 

Another interesting tidbit is that in some environments (95, NT 3.51 and NT 4)
an application can modify the regions of windows owned by _other_ processes. 
This does not seem to work in Win98, and it seems to me that it shouldn't work 
at all, but it does.  I have written programs that poke holes in the regions
of all the windows on the desktop, but the problem is there there would be a
lot of overhead to monitor all the windows to create a new region if their
size changes.  It would not be impossible, but your application would have to
continue running and monitor the window messages for the whole system.
However, you can change the region for another applications window, exit, and
until something defines a new region for that window, it will remain altered. 

xXx // The programs \\ xXx

Here is a program which creates a cow shaped window.  You can drag this window
with the right button and you can close it by double clicking on it.  You can 
also size it with the little box in the lower right.  Note that this is a 6.5k
executable, with a 1k icon.  See my page on creating small executables for
more on compiling and linking this executable.

    cowwnd.c - source code
    cowwnd.exe - compiled executable

Here is a program which cuts a cow shaped hole out of every window on the 
system, waits 7 seconds, then fixes it. Note that it will NOT work on Windows 98 
and that if there are any windows which use their own window regions that those 
regions will be messed up.

    cowholes.c - source code
    cowholes.exe - compiled executable