Environment: VC6 SP4 MS-Win98/2K
Very recently, I read an article on CodeGuru that spoke about making custom-shaped windows. Here is an application that demonstrates this capability by making dialog boxes of three different shapes and switching among those shapes at run time. Additionally, it demonstrates the capability of rotating those custom-shaped windows. The way I have approached the rotation problem may not make certain people very happy (especially the mathematicians-turned-programmers and those programmers who are concerned of the usage of memory). But this application is targeted solely to demonstrate the capability of rotation and the use of the CRgn class to make custom-shaped windows. The computations can surely be optimized by considering the facts of mathematics.
Approach to Making Custom-Shaped Windows
Any rectangular window can be changed to a circle, ellipse, hexagon, pentagon, star, sun, and what not. Just think of a shape and it's possible. All that is needed is a little bit of mathematics. Because custom-shaped windows can be drawn only in their client area, the vertices that enclose the custom-shape have to be either calculated at run time or the size of the window has to be fixed. Also, to make a window custom, either the size of the client area of the window has to be large enough to fit the shape or the shape itself has to be calculated at initialization of the window so that it fits completely in the client area. I took the second approach and built the custom-shape at initialization by deriving all the calculations from the center-of-rectangle of the client area. Once the coordinates of the shape are known, the rest is just a few lines of code. An example follows:
Say, the 'n' vertices are stored in the array of CPoints m_Vertices.
// Declare a variable to hold the region for the window // This variable has to be in scope until the window is visible // or active. // Usually declared as the member of the dialog class CRgn m_WndRgn; // Create the region from the polygon points m_WndRgn.CreatePolygonRgn(&m_Vertices, n, WINDING); // Set the created region SetWindowRgn(m_Vertices, TRUE);
This is all is required and you can see the window change its shape.
Approach to Rotating the Window
A custom-shaped window is surely enclosed by a set of vertices that define the coordinates of the shape and all those vertices can be enclosed in a circle. For example, say the custom shape was the star (has ten vertices). The radius of the smallest circle that encloses the star completely will be the distance from the center of the star to either of the five outer-vertices. If the vertices of the shape are calculated with respect to this circle, the complete window can be repositioned at a different angles easily. As in the figure, the vertex points can be calculated with at an interval of 10 degrees so that the window can be rotated by that amount on every time pulse.
For the sole purpose of the ease of the demonstration, I store all the vertices (at an interval of 1 degree) of each custom shape in an array (360 rows and n—the number of vertices—columns) where the index of the array maps the current angle of the shape. Finally, to rotate the window, a timer can be set to modify the window region at regular intervals.
The code in the demo application speaks the rest.