In Windows Vista and later, the appearance of the non-client areas of application windows (the title bar, icon, window border, and caption buttons) is controlled by the DWM. Using the DWM APIs, you can change the way the DWM renders a window's frame.
The ability to extend the window frame also enables you to create custom frames while maintaining the window's look and feel. For example, Microsoft Office Word 2007 draws the Office button and the Quick Access toolbar inside the custom frame while providing the standard Minimize, Maximize, and Close caption buttons, as shown in the following screen shot.
The functionality to extend the frame into the client area is exposed by the DwmExtendFrameIntoClientArea function. To extend the frame, pass the handle of the target window together with the margin inset values to DwmExtendFrameIntoClientArea. The margin inset values determine how far to extend the frame on the four sides of the window.
Note that the frame extension is done within the WM_ACTIVATE message rather than the WM_CREATE message. This ensures that frame extension is handled properly when the window is at its default size and when it is maximized.
The following image shows a standard window frame (on the left) and the same window frame extended (on the right). The frame is extended using the previous code example and the default Microsoft Visual Studio WNDCLASS/WNDCLASSEX background (COLOR_WINDOW +1).
The visual difference between these two windows is very subtle. The only difference between the two is that the thin black line border of the client region in the window on the left is missing from the window on the right. The reason for this missing border is that it is incorporated into the extended frame, but the rest of the client area is not. For the extended frames to be visible, the regions underlying each of the extended frame's sides must have pixel data with an alpha value of 0. The black border around the client region has pixel data in which all color values (red, green, blue, and alpha) are set to 0. The rest of the background does not have the alpha value set to 0, so the rest of the extended frame is not visible.
The easiest way to ensure that the extended frames are visible is to paint the entire client region black. To accomplish this, initialize the hbrBackground member of your WNDCLASS or WNDCLASSEX structure to the handle of the stock BLACK_BRUSH. The following image shows the same standard frame (left) and extended frame (right) shown previously. This time, however, hbrBackground is set to the BLACK_BRUSH handle obtained from the GetStockObject function.
After you have extended the frame of your application and made it visible, you can remove the standard frame. Removing the standard frame enables you to control the width of each side of the frame rather than simply extending the standard frame.
To remove the standard window frame, you must handle the WM_NCCALCSIZE message, specifically when its wParam value is TRUE and the return value is 0. By doing so, your application uses the entire window region as the client area, removing the standard frame.
The results of handling the WM_NCCALCSIZE message are not visible until the client region needs to be resized. Until that time, the initial view of the window appears with the standard frame and extended borders. To overcome this, you must either resize your window or perform an action that initiates a WM_NCCALCSIZE message at the time of window creation. This can be accomplished by using the SetWindowPos function to move your window and resize it. The following code demonstrates a call to SetWindowPos that forces a WM_NCCALCSIZE message to be sent using the current window rectangle attributes and the SWP_FRAMECHANGED flag.
By removing the standard frame, you lose the automatic drawing of the application icon and title. To add these back to your application, you must draw them yourself. To do this, first look at the change that has occurred to your client area.
With the removal of the standard frame, your client area now consists of the entire window, including the extended frame. This includes the region where the caption buttons are drawn. In the following side-by-side comparison, the client area for both the standard frame and the custom extended frame is highlighted in red. The client area for the standard frame window (left) is the black region. On the extended frame window (right), the client area is the entire window.
Because the entire window is your client area, you can simply draw what you want in the extended frame. To add a title to your application, just draw text in the appropriate region. The following image shows themed text drawn on the custom caption frame. The title is drawn using the DrawThemeTextEx function. To view the code that paints the title, see Appendix B: Painting the Caption Title.
When drawing in your custom frame, be careful when placing UI controls. Because the entire window is your client region, you must adjust your UI control placement for each frame width if you do not want them to appear on or in the extended frame.
A side effect of removing the standard frame is the loss of the default resizing and moving behavior. For your application to properly emulate standard window behavior, you will need to implement logic to handle caption button hit testing and frame resizing/moving.
For caption button hit testing, DWM provides the DwmDefWindowProc function. To properly hit test the caption buttons in custom frame scenarios, messages should first be passed to DwmDefWindowProc for handling. DwmDefWindowProc returns TRUE if a message is handled and FALSE if it is not. If the message is not handled by DwmDefWindowProc, your application should handle the message itself or pass the message onto DefWindowProc.
For frame resizing and moving, your application must provide the hit testing logic and handle frame hit test messages. Frame hit test messages are sent to you through the WM_NCHITTEST message, even if your application creates a custom frame without the standard frame. The following code demonstrates handling the WM_NCHITTEST message when DwmDefWindowProc does not handle it. To see the code of the called HitTestNCA function, see Appendix C: HitTestNCA Function.
Each time a window function is called, it is passed a row (the current row in the window) and the window of rows that contain the current row. The windowfunction returns one output row for each input row. The output depends on the individual row passed to the function and the values of the other rows in thewindow passed to the function.
A window is a group of related rows. For example, a window might be defined based on timestamps, with all rows in the same month grouped in the same window.Or a window might be defined based on location, with all rows from a particular city grouped in the same window.
A row. More precisely, a window function is passed 0 or more expressions. In almost all cases, at least one of thoseexpressions references a column in that row. (Most window functionsrequire at least one column or expression, but a few window functions, such as some rank-related functions, do not required an explicit column or expression.)
Window functions behave differently; although the current row is passed as an argument the normal way, the window is passed through a separate clause, calledan OVER clause. The syntax of the OVER clause is documented later.
A window frame is a sub-group of the rows in a window. Creating subsets allows you to compute values over just that specified sub-group of rows. Windowframes are specified as an additional subclause in the ORDER BY subclause of the OVER clause.
A rank-related function indicates the rank (position) of the current row within the window. To be useful, a rank-related function must be called on awindow of rows that has already been sorted according to a useful criterion. For example, if the rows in a window contain information about theprofitability of individual stores within a chain of stores, and if the rows are sorted in descending order of profitability, then the ranks of the rowsin the window (1, 2, 3, etc.) represent the profitability of the stores (most profitable, second most profitable, third most profitable, etc.). Therefore,rank-related functions are always order-sensitive functions, and require the ORDER BY sub-clause of the OVER() clause.
As with any other window function, when a rank-related function is called, you explicitly pass it not only a row (or more precisely, 1 or more columns of arow, or expressions based on the columns in the row), but also a window of rows. The output of the function depends upon:
The ORDER BY clause orders rows within the window. (This is different from ordering the output of a query. A query might have one ORDER BY clausethat controls the order of rows within a window, and a separate ORDER BY clause, outside the OVER clause, that controls the output order of theentire query.) Although the ORDER BY clause is optional for some window functions, it is required for others. For example, window frame functions andrank-related functions require that the data be in a meaningful order, and therefore require an ORDER BY sub-clause.
Window frames require that the data in the window be in a known order. Therefore, the ORDER BY inside the OVERclause is required for window frame syntax, even though that ORDER BY clause is optional in general windowfunction syntax.
The syntax shows all subclauses of the OVER clause as optional for window functions. This is by design (i.e. you can use OVER withoutany subclauses inside the parentheses). This can be useful in specific scenarios (e.g. turning off parallel processing). 041b061a72