Click here to Skip to main content
15,889,116 members
Articles / Desktop Programming / MFC

MFC Transparent CDialog Demo

Rate me:
Please Sign up or sign in to vote.
4.61/5 (39 votes)
3 Dec 2002CPOL2 min read 183.1K   8.6K   87  
A transparent dialog
// TransparentDialogDlg.cpp : implementation file
//MFC Transparent CDialog windows.

/* Copyright (C) 2002 by Nic Wilson  http://www.nicsoft.com.au
Written by Nic Wilson nicw@bigpond.net.au
All rights reserved

This is free software.
This code may be used in compiled form in any way you desire. This  
file may be redistributed unmodified by any means PROVIDING it is   
not sold for profit without the authors written consent, and   
providing that this notice and the authors name and all copyright   
notices remains intact. If the source code in this file is used in   
any  commercial application then a statement along the lines of   
Portions Copyright � 2002 Nic Wilson MUST be included in   
the startup banner, "About" dialog & printed documentation.   

No warrantee of any kind, expressed or implied, is included with this
software; use at your own risk, responsibility for damages (if any) to
anyone resulting from the use of this software rests entirely with the
user.

Release Date and Version:
Version: 1.0 December 2002



USAGE:

You should be able to use this demo as a skeleton application for your 
own project.

A standard CDialog MFC EXE application was created with the wizard and
apart from the standard  supplied code, the following functions were overridden.


	void OnClose() 
	Used to clean up some resources on exit.
	
	void OnPaint() 
	Used to paint the bimap into the region.

	void OnSize(UINT nType, int cx, int cy)
	Used to create the region and position and resize the dialog.

	void OnLButtonDown(UINT nFlags, CPoint point)
	To allow the dialog to be dragged by clicking anywhere.	


A button was created to allow the user to close the dialog.
A timer was  created to demonstrate auto closing after a period of time.

The image is a normal bmp file that is loaded by the app and ued to paint
the dialog.  TRANSPARENTCOLOR is defined in the dialog class header as bright
purple (RGB(255, 0, 255), but this could be changed to any colour you like.

The dialog window is auto sized to the size of the loaded bitmap then a region
created based on the transparent colour.  The dialog is then positioned in the 
centre of the current screen.   This was done as an example for those who want
to use this application as a splash windows.

The button serves no real purpose and was made a close button simply to demonstrate
using a button.

*/


#include "stdafx.h"
#include "TransparentDialog.h"
#include "TransparentDialogDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTransparentDialogDlg dialog

CTransparentDialogDlg::CTransparentDialogDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTransparentDialogDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTransparentDialogDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTransparentDialogDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTransparentDialogDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTransparentDialogDlg, CDialog)
	//{{AFX_MSG_MAP(CTransparentDialogDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_CLOSE, OnExit)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTransparentDialogDlg message handlers

BOOL CTransparentDialogDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	SetTimer(1, 10000, NULL);
	// TODO: Add extra initialization here
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTransparentDialogDlg::OnExit() 
{
	// TODO: Add your control notification handler code here
	PostQuitMessage(0);
}

void CTransparentDialogDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	DeleteObject(m_hBitmap);	//not really need but what the heck.
	CDialog::OnClose();
}

void CTransparentDialogDlg::OnPaint() 
{
	// device context for painting
	CPaintDC dc(this); 
	//Create a memory DC
	HDC hMemDC = ::CreateCompatibleDC(NULL);
	//Select the bitmap in the memory dc.
	SelectObject(hMemDC, m_hBitmap);
	//Copy the memory dc into the screen dc
	::BitBlt(dc.m_hDC, 0, 0, m_Bitmap.bmWidth, m_Bitmap.bmHeight, hMemDC, 0, 0, SRCCOPY);
	//Delete the memory DC and the bitmap
	::DeleteDC(hMemDC);
	CDialog::OnPaint();
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTransparentDialogDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTransparentDialogDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	KillTimer(1);
	PostQuitMessage(0);
	CDialog::OnTimer(nIDEvent);
}

void CTransparentDialogDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	// Load the image
	m_hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), "Image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	if (m_hBitmap == NULL)
	{
		MessageBox("Error loading bitmap");
		return;
	}
	//Get information about the bitmap..
	GetObject(m_hBitmap, sizeof(m_Bitmap), &m_Bitmap);	// Get info about the bitmap 
	// Put the bitmap into a memory device context
	CPaintDC dc(this);
	//get a memory dc object
	CDC dcMem;
	//create a compatible dc
	dcMem.CreateCompatibleDC(&dc);	// Select the bitmap into the in-memory DC
	//Select the bitmap into the dc
	CBitmap* pOldBitmap = dcMem.SelectObject(CBitmap::FromHandle(m_hBitmap));
	//Create a couple of region objects.
	CRgn crRgn, crRgnTmp;
	//create an empty region
	crRgn.CreateRectRgn(0, 0, 0, 0);
	//Create a region from a bitmap with transparency colour of Purple
	COLORREF crTransparent = TRANSPARENTCOLOR;	
	int iX = 0;
	for (int iY = 0; iY < m_Bitmap.bmHeight; iY++)
	{
		do
		{
			//skip over transparent pixels at start of lines.
			while (iX <= m_Bitmap.bmWidth && dcMem.GetPixel(iX, iY) == crTransparent)
				iX++;
			//remember this pixel
			int iLeftX = iX;
			//now find first non transparent pixel
			while (iX <= m_Bitmap.bmWidth && dcMem.GetPixel(iX, iY) != crTransparent)
				++iX;
			//create a temp region on this info
			crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);
			//combine into main region.
			crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR);
			//delete the temp region for next pass (otherwise you'll get an ASSERT)
			crRgnTmp.DeleteObject();
		}while(iX < m_Bitmap.bmWidth);
		iX = 0;
	}
	//Centre it on current desktop
	SetWindowRgn(crRgn, TRUE);
	iX = (GetSystemMetrics(SM_CXSCREEN)) / 2 - (m_Bitmap.bmWidth / 2);
	iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (m_Bitmap.bmHeight / 2);
	SetWindowPos(&wndTopMost, iX, iY, m_Bitmap.bmWidth, m_Bitmap.bmHeight, NULL); 

	// Free resources.
	dcMem.SelectObject(pOldBitmap);	// Put the original bitmap back (prevents memory leaks)
	dcMem.DeleteDC();
	crRgn.DeleteObject();
}

void CTransparentDialogDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
	CDialog::OnLButtonDown(nFlags, point);
}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions