Irregular Shaped Bitmap Dialog
Posted
by David Forrester
on January 29th, 2001
The CBitmapDialog class allows you to create a dialog that has a bitmap background, and to have a specified color in the background be transparent. This allows the dialog to be in other shapes than a box, like the one shown above.
Usage
Use this class like CDialog, but there are several extra functions that you can use:
// ** Constructors ** // Use the normal CDialog constructors plus the following // as the last four parameters: // // LPCTSTR lpszResourceName // UINT nIDResource // LPCTSTR lpszFilename // CBitmap *pBitmap // // Example: // CDialog(int,CWnd*)):CBitmapDialog(IDD_MAINDIALOG, this, NULL, IDB_BITMAP, NULL, NULL); // // Use at most one of these parameters and leave the rest // NULL or 0. If you do not want to set a bitmap in the // constructor, look below. // ** Bitmap Setting ** // Loads a bitmap from a resource string or filename. // Leave either lpszResourceName or lpszFilename NULL. BOOL LoadBitmap (LPCTSTR lpszResourceName, LPCTSTR lpszFilename); // Loads a bitmap from a resource ID BOOL LoadBitmap (int nIDResource); // Makes a copy of a given bitmap and uses the copy. // This is like SetBitmap but you are not responsible // for handling the bitmap. BOOL CopyBitmapFrom (CBitmap *pBitmap); // Uses the bitmap you specify. NOTE: You are responsible // for handling the bitmap. void SetBitmap (CBitmap *pBitmap); // ** Transparency ** // Specifies whether the window should use transparency. // TRUE for transparent, FALSE for opaque. (default is // FALSE) void SetTransparent (BOOL bTransparent); BOOL GetTransparent (); // Specifies the color that you want to be transparent. void SetTransColor (COLORREF col); COLORREF GetTransColor (); // Specifies whether static (text) controls have a // transparent background. // TRUE for transparent, FALSE for opaque. (default // is TRUE) void SetStaticTransparent (BOOL bTransparent); BOOL GetStaticTransparent (); // ** Dragging ** // With a transparent dialog, you usually won't have a // caption (like my example). // These functions make it so that you can drag anywhere // on the dialog to move it. TRUE is on and FALSE is off. // (default is FALSE) void SetClickAnywhereMove (BOOL bMove); BOOL GetClickAnywhereMove ();
Tips
* In the resource editor, you can't tell exactly how big the dialog will need to be to hold the entire bitmap. You could either try out different sizes, or if you don't have "show window contents while dragging" (windows option) enabled, you could drag the dialog and see how much extra dialog you have on the edge when it shows you the frame.* Dialogs that use transparency usually look best without a caption or a border. In the resource editor for your dialog, uncheck "title bar" and set "border" to "none."
How it works
It overrides CWnd::OnEraseBackground() to draw the bitmap as the background.It overrides CWnd::OnCtlColor() to make static controls transparent.
It makes parts of the window transparent by combining many small window regions. (look at CBitmapDialog::MakeWindowRgn())
It allows you to drag anywhere to move by making Windows think that you clicked on the caption (even if there is no caption bar).
Downloads
Download demo project (include Release build) - 100 KbDownload source - 5 Kb

Comments
More concessions with herveleger, more nick!
Posted by jonemspf on 04/26/2013 11:08ammaidenlackeybe in intensity withget hold ofstrongrep
ReplyFix for black ComboBox Dropdown
Posted by Anarchi on 05/13/2009 02:58amAdd this to CBitmapDialog::OnCtlColor() // Combo Box if (_tcscmp(lpszClassName, "ComboLBox")== 0) { return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); }ReplyProblem with combo box under Win XP
Posted by Harald Dietewich on 05/24/2005 06:35amworkaround to avoid XP bug with transparent checkboxes
Posted by Legacy on 02/04/2004 12:00amOriginally posted by: Mario Schlesinger
ReplySome Problem in function LoadBitmap (LPCTSTR lpszResourceName, LPCTSTR lpszFilename)
Posted by Legacy on 01/08/2004 12:00amOriginally posted by: 박경로
Thank David Forrester.
Your Source Code was very Good. And I used it in my project. Using your code I corrected some function like below. Sorry My English is poor. Have a nice day!
LoadBitmap (LPCTSTR lpszResourceName, LPCTSTR lpszFilename)
......
else
{
// Load the bitmap from a file
HBITMAP hbm = (HBITMAP) LoadImage (NULL, szFilename, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if (hbm == NULL) return FALSE;
// Get the CBitmap object
CopyBitmapFrom (CBitmap::FromHandle(hbm));
DeleteObject(hbm); //Add To prevent memory leack
}
and I recommend MakeWindowRgn()
........
// Go through all rows
for (int y=0; y<height; y++)
{
// Start looking at the beginning
row_start = 0;
// Go through all columns
for (int x=0; x<width; x++)
{
// If this pixel is transparent
if (dcImage.GetPixel(x, y) == m_colTrans)
{
// If we haven't found an opaque pixel yet, keep searching
if (row_start == x) row_start ++;
else
{
// We have found the start (row_start) and end (x) of
// an opaque line. Add it to the region.
CRgn rgnAdd;
rgnAdd.CreateRectRgn (row_start,
y, x, y+1);
rgn.CombineRgn (&rgn, &rgnAdd, RGN_OR);
row_start = x+1;
}
}
}
// If the last pixel is still opaque, make a region.
if (row_start != x)
{
CRgn rgnAdd;
rgnAdd.CreateRectRgn (row_start, y,
x, y+1);
rgn.CombineRgn (&rgn, &rgnAdd, RGN_OR);
Reply}
}
dcImage.SelectObject(pOldBitmap);
SetWindowRgn (rgn, TRUE);
}
Check box doesn't work with Windows XP & Theme
Posted by Legacy on 12/23/2003 12:00amOriginally posted by: Sergej
Check box background get's completelly black once you return HOLLOW_BRUSH for the static control in OnCtrlColor.
But only with Windows XP and themes enabled.
Any idea?
Steps to reproduce: just create a manifest file for the test application and run it under windows XP with standard theme (Luna)
ReplyIrregular Dialog
Posted by Legacy on 09/17/2003 12:00amOriginally posted by: Ebadul Hossain
Nice solution to build up another shapped dialog.
ReplyError with Group Box and Picture static controls
Posted by Legacy on 04/25/2003 12:00amOriginally posted by: Kyselgov E.N.
This class has error while drawing transparent group box and picture static controls.
When you add picture static control with icon, it will be draw incorrect. Namely, almost all icons have transparent region (background), and when you use picture static with icon, this region is dialog background color (background are determinate by dialog background brush). But, CBitmapDialog::OnCtlColor() sets HOLLOW_BRUSH as dialog background brush for all static control (except TRACKBAR_CLASS controls), evidently, picture static draws with BLACK background.
Group box with text header is drawn whit similar error. CBitmapDialog::OnCtlColor() sets TRANSPARENT method for text output. Consequently, text header (caption) will be strikethrough by group box border.
All others static controls are drawn correctly.
P.S. As is well known, .NET window form have background image feature, and if all child static controls has transparent background color then form draws without any artifacts. Does anybody know how it works?
Reply
Adding Checkbox and combobox in tool bar
Posted by Legacy on 03/28/2003 12:00amOriginally posted by: Ahmad, Lahore
How can I add a checkbox and radio buttons in a tool bar in VC++.
ReplyDebug Assertion Failed
Posted by Legacy on 02/21/2003 12:00amOriginally posted by: Sara
I try this code, and I get several of these messages windows that Say:
Debug Assertion Failed
Program: etc etc
file:afxwin2.inl
line: 90 (also 96 and a few others)
can anyone think of a reason this might happen?
thanks
ReplySara
Loading, Please Wait ...