//
// StyleDialog.cpp:
//
// Author: Darren Sessions
//
//
// Description:
//
// The StyleDialog class allows the use of transparency and layers
// when implementing a dialog.
//
// History
// Version 1.1 - 2008 August 1
// - Initial release
//
// License:
// This software is released under the Code Project Open License (CPOL),
// which may be found here: http://www.codeproject.com/info/eula.aspx
// You are free to use this software in any way you like, except that you
// may not sell this source code.
//
// This software is provided "as is" with no expressed or implied warranty.
// I accept no liability for any damage or loss of business that this
// software may cause.
//
///////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "StyleDialog.h"
void StyleDialog::Init()
{
m_bTransparent = FALSE;
m_TransState = DISABLED;
m_csTitle = "";
m_bIsDragging = FALSE;
m_Controls = 0;
m_bBackgroundChanged = TRUE;
CRect NullRect(0,0,0,0);
m_TitleRect = NullRect;
m_FrameRect = NullRect;
m_ClientRect = NullRect;
m_TransRect = NullRect;
m_FrameOffset.x = 0;
m_FrameOffset.y = 0;
m_OpaqueColor = GetSysColor(COLOR_BACKGROUND);
m_bUseOpaqueStyle = 0;
}
StyleDialog::StyleDialog()
{
Init();
}
StyleDialog::StyleDialog(UINT nIDTemplate, CWnd* pParentWnd)
: CDialog(nIDTemplate, pParentWnd)
{
Init();
}
StyleDialog::StyleDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
: CDialog(lpszTemplateName, pParentWnd)
{
Init();
}
StyleDialog::~StyleDialog()
{
}
BOOL StyleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
if(m_Controls & CTRL_CLIENT)
{
CDialog::GetClientRect(m_FrameRect);
m_cClient.GetWindowRect(m_ClientRect); ScreenToClient(m_ClientRect);
m_TitleRect = m_FrameRect; m_TitleRect.bottom = m_ClientRect.top;
m_TransRect = m_FrameRect;
}
else
{
CRect r(0,0,0,0); CalcWindowRect(r, 0);
m_FrameOffset.x = -r.left; m_FrameOffset.y = -r.top;
GetWindowRect(m_FrameRect); ScreenToClient(m_FrameRect);
m_FrameRect.OffsetRect(m_FrameOffset);
CDialog::GetClientRect(m_ClientRect);
m_TitleRect = m_FrameRect; m_TitleRect.bottom = m_FrameOffset.y;
m_TransRect = m_FrameRect;
m_TransRect.left -= r.left; m_TransRect.top -= r.top;
m_TransRect.right -= r.right; m_TransRect.bottom -= r.bottom;
GetClientRect(m_TransRect);
}
#ifdef USE_LAYERED_WINDOWS
if(m_bTransparent)
{
m_TransState = INACTIVE;
SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(0, 255, LWA_ALPHA);
}
#endif
// this will show up in the task bar
if(m_csTitle.GetLength() > 0)
SetWindowText(m_csTitle);
#ifdef USE_STYLE_TOOLKIT
#ifdef IDC_SD_CLIENT
GetSystemMenu(FALSE)->RemoveMenu(SC_MOVE, MF_BYCOMMAND);
#endif
#ifdef IDC_SD_CANCEL
if(m_Controls & CTRL_CANCEL)
m_cCancel.LoadStdImage(IDR_CANCEL, _T("PNG"));
#endif
#ifdef IDC_SD_MINIMIZE
if(m_Controls & CTRL_MINIMIZE)
m_cMinimize.LoadStdImage(IDR_MINIMIZE, _T("PNG"));
#endif
#ifdef IDC_SD_ABOUT
if(m_Controls & CTRL_ABOUT)
m_cAbout.LoadStdImage(IDR_ABOUT, _T("PNG"));
#endif
#endif
// maximize could be supported but code would have to be added
SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX);
return TRUE;
}
void StyleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
#ifdef USE_STYLE_TOOLKIT
#ifdef IDC_SD_CLIENT
if(m_Controls & CTRL_CLIENT)
DDX_Control(pDX, IDC_SD_CLIENT, m_cClient);
#endif
#ifdef IDC_SD_CANCEL
if(m_Controls & CTRL_CANCEL)
DDX_Control(pDX, IDC_SD_CANCEL, m_cCancel);
#endif
#ifdef IDC_SD_MINIMIZE
if(m_Controls & CTRL_MINIMIZE)
DDX_Control(pDX, IDC_SD_MINIMIZE, m_cMinimize);
#endif
#ifdef IDC_SD_ABOUT
if(m_Controls & CTRL_ABOUT)
DDX_Control(pDX, IDC_SD_ABOUT, m_cAbout);
#endif
#endif
}
BEGIN_MESSAGE_MAP(StyleDialog, CDialog)
#ifdef IDC_SD_CANCEL
ON_BN_CLICKED(IDC_SD_CANCEL, OnSdClose)
#endif
#ifdef IDC_SD_MINIMIZE
ON_BN_CLICKED(IDC_SD_MINIMIZE, OnSdMinimize)
#endif
#ifdef IDC_SD_ABOUT
ON_BN_CLICKED(IDC_SD_ABOUT, OnSdAbout)
#endif
ON_WM_WINDOWPOSCHANGING()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOVE()
ON_WM_ACTIVATE()
ON_WM_RBUTTONDOWN()
ON_WM_NCLBUTTONDOWN()
END_MESSAGE_MAP()
void StyleDialog::SetTransparent(BOOL bTransparent)
{
#ifdef USE_LAYERED_WINDOWS
m_bTransparent = bTransparent;
if(bTransparent)
{
m_TransState = ACTIVE;
if(m_hWnd)
{
SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(0, 255, LWA_ALPHA);
}
}
else
{
m_TransState = DISABLED;
if(m_hWnd)
{
SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
}
}
#endif
}
void StyleDialog::GetClientRect(LPRECT lpRect)
{
lpRect->top = m_ClientRect.top;
lpRect->left = m_ClientRect.left;
lpRect->right = m_ClientRect.right;
lpRect->bottom = m_ClientRect.bottom;
}
void StyleDialog::SetClientRect(CRect rect)
{
m_ClientRect = rect;
}
void StyleDialog::SetTransparentRect(CRect rect)
{
m_TransRect = rect;
}
void StyleDialog::GetFrameRect(LPRECT lpRect)
{
lpRect->top = m_FrameRect.top;
lpRect->left = m_FrameRect.left;
lpRect->right = m_FrameRect.right;
lpRect->bottom = m_FrameRect.bottom;
}
void StyleDialog::GetTitleRect(LPRECT lpRect)
{
lpRect->top = m_TitleRect.top;
lpRect->left = m_TitleRect.left;
lpRect->right = m_TitleRect.right;
lpRect->bottom = m_TitleRect.bottom;
}
void StyleDialog::OnRButtonDown(UINT nFlags, CPoint point)
{
#ifdef IDC_SD_CLIENT
CMenu* pMenu = GetSystemMenu(FALSE);
pMenu->EnableMenuItem(SC_MOVE, MF_BYCOMMAND | MF_DISABLED);
#endif
SendMessage(WM_SYSCOMMAND, SC_KEYMENU, LPARAM(' '));
CDialog::OnRButtonDown(nFlags, point);
}
void StyleDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
if(m_TitleRect.PtInRect(point))
{
SetCapture();
m_GrabPoint = point;
m_bIsDragging = TRUE;
}
CDialog::OnLButtonDown(nFlags, point);
}
void StyleDialog::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if(m_bTransparent && nHitTest == HTCAPTION)
{
ReleaseCapture(); CDialog::ScreenToClient(&point);
CRect r(0,0,0,0); CalcWindowRect(r, 0);
point.x -= r.left; point.y -= r.top;
OnLButtonDown(nHitTest, point);
}
else
{
CDialog::OnNcLButtonDown(nHitTest, point);
}
}
void StyleDialog::OnMouseMove(UINT nFlags, CPoint point)
{
if(m_bIsDragging)
{
if(m_TransState == ACTIVE)
{
m_TransState = INACTIVE;
m_bBackgroundChanged = TRUE;
Invalidate();
}
ClientToScreen(&point);
SetWindowPos( NULL, point.x - m_GrabPoint.x, point.y - m_GrabPoint.y, 0, 0,
SWP_NOZORDER | SWP_NOSIZE);
}
}
void StyleDialog::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_bIsDragging)
{
ReleaseCapture();
m_bIsDragging = FALSE;
if(m_TransState == INACTIVE)
{
m_TransState = ACTIVE;
m_bBackgroundChanged = TRUE;
Invalidate();
}
}
CDialog::OnLButtonUp(nFlags, point);
}
BOOL StyleDialog::OnEraseBkgnd(CDC* pDC)
{
if(!m_bTransparent)
{
CDialog::OnEraseBkgnd(pDC);
}
if(m_TransState == INACTIVE)
{
if(m_bUseOpaqueStyle)
{
#ifdef USE_STYLE_TOOLKIT
m_OpaqueStyle.PaintStyle(pDC, m_TransRect);
#endif
}
else
{
CBrush br; br.CreateSolidBrush(m_OpaqueColor);
pDC->FillRect(m_TransRect, &br);
}
}
else if(m_TransState == ACTIVE)
{
CRect wr; GetWindowRect(wr);
wr.OffsetRect(m_FrameOffset);
int dstx = m_TransRect.left; int dsty = m_TransRect.top;
int width = m_TransRect.Width(); int height = m_TransRect.Height();
int srcx = wr.left + dstx; int srcy = wr.top + dsty;
CDC* pDesk = GetDesktopWindow()->GetDC();
pDC->BitBlt(dstx, dsty, width, height, pDesk, srcx, srcy, SRCCOPY);
GetDesktopWindow()->ReleaseDC(pDesk);
}
#ifdef USE_STYLE_TOOLKIT
if(m_bBackgroundChanged)
{
UpdateFrameControls(pDC);
m_bBackgroundChanged = FALSE;
m_BackGroundStyle.Regenerate();
}
m_BackGroundStyle.PaintStyle(pDC, m_FrameRect);
#endif
return TRUE;
}
void StyleDialog::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
if( (lpwndpos->flags & SWP_FRAMECHANGED) == SWP_FRAMECHANGED)
{
m_bBackgroundChanged = TRUE;
}
CDialog::OnWindowPosChanging(lpwndpos);
}
void StyleDialog::UpdateFrameControls(CDC* pDC)
{
#ifdef USE_STYLE_TOOLKIT
#ifdef IDC_SD_CANCEL
if(m_Controls & CTRL_CANCEL)
m_cCancel.SetBkGnd(pDC);
#endif
#ifdef IDC_SD_MINIMIZE
if(m_Controls & CTRL_MINIMIZE)
m_cMinimize.SetBkGnd(pDC);
#endif
#ifdef IDC_SD_ABOUT
if(m_Controls & CTRL_ABOUT)
m_cAbout.SetBkGnd(pDC);
#endif
#endif
}
#ifdef USE_STYLE_TOOLKIT
void StyleDialog::AddBackGroundStyle(Style style)
{
m_BackGroundStyle = style;
}
void StyleDialog::AddOpaqueStyle(Style style)
{
m_OpaqueStyle = style;
m_bUseOpaqueStyle = TRUE;
}
#endif
void StyleDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
if(m_TransState != DISABLED)
{
if(nState == WA_INACTIVE)
{
m_TransState = INACTIVE;
}
else if(nState == WA_CLICKACTIVE)
{
m_TransState = ACTIVE;
}
else
{
m_TransState = ACTIVE;
}
if(bMinimized == 0)
{
m_bBackgroundChanged = TRUE;
Invalidate();
}
}
CDialog::OnActivate(nState, pWndOther, bMinimized);
}