Using Visual Styles with a Custom Control The UxTheme API referenced in the steps to add visual styles to a control and in the corresponding code examples are defined in the header file, Uxtheme.h. The elements of the API are documented in the Platform SDK. In addition to describing the steps for applying visual styles to a control, this section provides a drawing code sample and tips on drawing controls. To enable a control to apply visual styles. Call OpenThemeData and pass the hwnd of the control you wish to apply visual styles to and a class list that describes the control's type. The classes are defined in Tmschema.h. OpenThemeData returns an HTHEME handle, but if the visual style manager is disabled or the current visual style does not supply specific information for a given control, the function returns NULL. If the return value is NULL use non-visual style drawing functions. To draw the control, call DrawThemeBackground and pass the following: Theme handle returned from OpenThemeData, the HDC to use for rendering the control. Part identifier that describes the part of the control to render. See Theme Parts and States for information on control parts and states. State identifier that describes the current state of the part. Pointer to the RECT structure that contains the coordinates of the rectangle where the control will be rendered. Some parts can be partially transparent. You can determine this by calling IsThemeBackgroundPartiallyTransparent with the theme handle, a control part, and a control state. If your control draws text, position the text within the content rectangle of the control and select a font. To determine the location of the content rectangle call GetThemeBackgroundContentRect Add your desired font to the device context (DC) then call DrawThemeText. This function enables visual effects such as shadowed text in some controls. When your control receives a WM_THEMECHANGED message, it should do the following: Call CloseThemeData to close the existing theme handle. Call OpenThemeData to get the theme handle for the newly loaded visual style. This code sample illustrates the two calls. case WM_THEMECHANGED: CloseThemeData (hTheme); hTheme = OpenThemeData (hwnd, L"MyClassName"); When your control receives a WM_DESTROY message, call CloseThemeData to release the theme handle that was returned when you called OpenThemeData. Example of Drawing Code The following code sample demonstrates how to draw a button control. HTHEME hTheme = NULL; hTheme = OpenThemeData(hwndButton, "Button"); ... DrawMyControl(hDC, hwndButton, hTheme, iState); ... if (hTheme) { CloseTheme(hTheme); } void DrawMyControl(HDC hDC, HWND hwndButton, HTHEME hTheme, int iState) { RECT rc, rcContent; TCHAR szButtonText[255]; HRESULT hr; GetWindowRect(hwndButton, &rc); GetWindowText(hwndButton, szButtonText, ARRAYSIZE(szButtonText)); if (hTheme) { hr = DrawThemeBackground(hTheme, hDC, BP_BUTTON, iState, &rc, 0); // Always check your result codes. hr = GetThemeBackgroundContentRect(hTheme, BP_BUTTON, iState, &rc, &rcContent); hr = DrawThemeText(hTheme, hDC, BP_BUTTON, iState, szButtonText, lstrlen(szButtonText), DT_CENTER | DT_VCENTER | DT_SINGLELINE, 0, &rcContent); } else { // Draw the control without using visual styles. } } Enabling Owner Drawn Controls to Use Visual Styles With Windows XP controls no longer have to consist only of lines and color fills. Now they include rich textures and patterns that can vary according to the state of the control. This means that you cannot use already existing programming elements to describe owner-drawn controls that have the look and feel of controls that have a visual style applied. If you have code that already has owner-drawn controls, you have the following options. You can call SetWindowTheme to turn off theming on the control. SetWindowTheme (hwndButton, TEXT (" "), TEXT (" ")); The control will render as it did in earlier versions of Windows. You can continue to use the owner-drawn methods in controls, but some of the properties will be ignored. For example, if you change the background color of a button, the button is drawn like a button with a visual style applied but the background color is not the color you specified. However if you change the font, the button is drawn with the specified font. Making a Control Appear to Have No Visual Style in a Dialog Box or Window That Has a Visual Style In some cases, applications have custom-drawn controls that should not use a visual style, even when the other controls in the window do have a visual style applied. If you want to mark any custom-drawn control as having no visual style, you must call SetWindowTheme and pass in the window handle for the control and an empty string for both the pszSubAppName and pszSubIdList parameters. Calling the SetWindowTheme function with empty strings causes the control to render without a visual style appearance. The following code snippet shows how to create a button control and then call SetWindowTheme to remove the visual style from the button. HWND hwndButton; hwndButton = CreateWindow (TEXT ("button"), ...); if (hwndButton) { SetWindowTheme (hwndButton, TEXT (" "), TEXT (" ")); } Note If you decide to have the control change at run time to a visual style control you can call SetWindowTheme but pass NULL for the two string parameters. Using UxTheme Manager to Render a Control Whose Parts Do Not Have a Visual Style If you have a control that is not one of the common controls and you want it to look appropriate on a computer that has visual style files installed, you can take one of the following approaches. The basic approach is to use the system metric colors. Most system metric colors are set when a visual style file is applied. You can use parts from other controls and render each part separately. For example, for a calendar control that consists of a grid, you can treat each square formed by the grid as a toolbar button. Do the following to program the squares as toolbar buttons. Call OpenThemeData as follows: OpenThemeData (hwnd, "Toolbar"); Use the returned theme handle to render each of the squares on the calendar. You can mix and match control parts by calling OpenThemeData multiple times for a given control and using the appropriate theme handle to draw different parts. In some visual styles, however, certain parts might not be compatible with other parts. Some specialized applications that need to match the Windows XP look above the control level might need to detect the currently loaded visual style and have custom renderings designed to match the look. This can be useful for applications that provide visual style architecture. Using Visual Styles with HTML Content There are many applications, written in HTML and deployed as an HTML Application (HTA) or a Win32 application, that use HTML or host the WebObject in their UI elements. When running on Windows XP, these applications can have the same look that is consistent with Win32-based applications running on the same operating system. The following are some considerations when applying visual styles to HTML content. Visual styles in relation to HTML content applies only to Intrinsic HTML Controls such as buttons, scrollbars, and select controls. The Windows XP visual style is applied automatically to controls on HTML pages. If you do not want your page to have a visual style applied, use the META tag with its attribute set to NO. The META tag is documented in a following section. HTML pages that modify the Cascading Style Sheets (CSS) properties such as background or border do not have a visual style applied to them. They display the specified CSS attribute. When specified as part of the content, most CSS properties do apply to elements that have visual styles applied. You must add a metatag to the section of your pages. You need to add this tag only once; visual styles apply it to all the page content. This also applies to content packaged as HTAs. The metatag must be as follows: Be aware that visual styles might change the layout of your content. Also, if you set certain attributes on Intrinsic HTML Controls, such as the width of a button, you might find that the label on the button is unreadable under certain visual styles. You must thoroughly test your content using visual styles to determine whether applying visual styles has an adverse impact on your content and layout. Make any changes required to make your content work successfully. Causing the UxTheme Manager to Ignore Top-Level Windows To avoid applying the new visual style to a top-level window, consider the following: If a window has a region applied to it, the UxTheme Manager assumes that this is a specialized window and the window will not use visual styles throughout its life. Child windows associated with a non-visual style top-level window may still apply visual styles even though the parent does not. If you apply a region to a top-level window and later remove the region, a visual style is not automatically applied to the window. To apply a visual style to the window, you must create a new window. If you want to disable the use of visual styles for all top-level windows in your application, call SetThemeAppProperties and do not pass the STAP_ALLOW_NONCLIENT flag. If an application does not call SetThemeAppProperties, the assumed flag values are STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS | STAP_ALLOW_WEBCONTENT. The assumed values cause the non-client area, the controls, and Web content to have a visual style applied.