There are several transparent dialogs on CodeProject; however, none of them provide a generic dialog that allows you to paint on the transparent region. The reason for this is because Windows doesn’t effectively support transparent
CWnd objects in the first place.
The image above shows StyleDialog being used with Style Toolkit[^] version 1.1. However, StyleDialog may be used with or without the toolkit, and with or without transparency.
Issues in Creating a Transparent Dialog
The key feature I needed for StyleDialog is the ability to use the transparent region. That means, you can draw on it, paint on it, and add controls to it.
Here are some of the typical methods used, and the associated drawbacks:
- Return a
OnCtlColor – This works okay for controls, since the application controls the background. It also works for a dialog box as long as you don’t move it, which makes it relatively useless. It also causes child controls to stop receiving their
- Use a Region – This solution works fairly well; however, you can’t use the transparent regions. Also, since you can’t anti-alias the border, the edges look a bit ragged.
- Layered Windows – This is the only method that creates a true transparent window. This works fine for creating a fade effect, but since the transparency applies to the entire
CWnd, you can’t have some things transparent and others opaque.
CWnds – These solutions look and behave the best, but they aren’t generic, and you also can’t paint on the transparent regions.
StyleDialog Design Considerations
Other issues that are difficult to overcome are jitter when dragging the window, and maintaining the correct background when the application is not the active one.
To overcome these issues, StyleDialog imposes the following design rules:
- Display an alternate background when not the active application. This overcomes the problem of the background changing underneath the application when it is visible but not active.
- Display an alternate background when dragging the application. Actually, StyleDialog could display the correct background while dragging, but there is a jitter associated with layered windows that is undesirable.
StyleDialog achieves transparency by using an opaque layered window and taking advantage of the fact that it is maintained in an off-screen bitmap.
Step 1 - Configure Usage in StyleDialog.h
Step 2 – Derive a Dialog from StyleDialog
Create a dialog based application with the wizard as usual. Replace all the instances of
StyleDialog. Note: Skip past
CAboutDlg when doing the replace, unless you want it to also be a
For child dialogs, just declare them as
StyleDialog. See the demo program for examples.
Step 3 – Configure StyleDialog
Do the following before calling
SetTitle(_T("Style Dialog Demo"));
SetTransparent enables transparency. It defaults to disabled since it will just waste bandwidth if it is not used.
StyleDialog which controls to use when there is a custom frame. This is described in more detail below. The default is no controls.
SetTitle is the title that will be displayed in the taskbar when a custom frame is used. The default is an empty string.
Step 4 – Add a style to the dialog [optional]
Load a style into the dialog with
Minimal Implementation of StyleDialog
The image and code below is from the Dialog 3 button of the demo program.
This example uses the standard frame, and does not use the Style Toolkit. It is actually not necessary to set the title, but it will just say “Dialog” if you don’t.
Controlling the Alternate Background
If transparency is enabled,
StyleDialog will display an alternate background when it is not the active application or when the window is being moved. The alternate background will be underneath anything that may have been painted on the transparent region.
By default, the alternate background will be a solid fill of the desktop background color. This can be overridden with one of the following:
SetOpaqueColor(clr) – Change the solid fill to another color.
AddOpaqueStyle(style) – Change the fill to a style.
The Dialog 2 button demonstrates the use of styles for the background.
This example uses a custom frame without controls, and a background style with a semi-transparent PNG image.
This shows the inactive state. It uses a fully opaque version of the same image for the opaque style.
Creating a Custom Frame
StyleDialog needs to know what the client rectangle’s size should be when creating a custom frame. This is needed for hit testing the title bar area, and for supporting the overridden function
StyleDialog maintains an outer frame that can be retrieved with
GetFrameRect and a client frame that can be retrieved with
GetClientRect. Note that Windows does not perceive this as the client rectangle. There are cases when painting or erasing that you should use
CDialog::GetClientRect to get the Windows definition of the client rectangle.
Method 1 – Use SetClientRect
GetFrameRect() to get the outer frame rect, adjust it for border and title bar sizes, then call
Method 2 – Use the Resource Editor
Use the resource editor and create the client rectangle with a static control. This has the advantage of being able to adjust the title and border sizes as you design the dialog box. Use the static picture control, since it doesn’t have any offsets.
Set the ID of the control to one of
SytleDialog’s keyword IDs –
StyleDialog detects this ID in the resource.h file, it will automatically create the client rectangle.
There are also keyword IDs for the controls as seen in the image below.
StyleDialog sees any of the control IDs, it will create
StyleButtons for them and load them with the associated image. It will also create the expected functionality for each button.
StyleDialog does not support maximize; in fact, it disables it. In principle, this could be supported, but I don’t have any intention of adding this feature in the future.
I didn’t really plan on supporting a transparent dialog with transparent child dialogs; however, it appears to work okay, and the demo program actually does this.
In order to not have a burn through effect when opening a child dialog, the transparency of the parent can be disabled, then re-enabled. However, there may be timing issues associated with turning on and off layered windows, so use this feature with caution.
- Minimize and Restore when using a custom frame – If you click on the taskbar icon, StyleDialog will go to the proper active or inactive state, but it will not minimize and restore. I think this relates to the fact that the system menu does not have this functionality, and I hope to fix this in a future release.
- VC6 users – StyleDialog will work as is if you comment out the layered window functionality. Layered windows will work on Win2K SP3 and newer, but you need to get newer versions of winuser.h, user32.lib, and user32.dll.
- Version 1.0 – August 3, 2008