home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
appwiz
/
logowiz
/
cstm1dlg.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-05
|
11KB
|
358 lines
// cstm1dlg.cpp : implementation file
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "logowiz.h"
#include "cstm1dlg.h"
#include "logowaw.h"
#ifdef _PSEUDO_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// these are expected to be in the same order as the radio buttons corresponding to these choices
// they are also assumed to start at zero
#define RAD_UPLEFT 0 // logo goes in upper left corner
#define RAD_LOLEFT 1 // logo goes in lower left corner
#define RAD_LORIGHT 2 // logo goes in lower right corner
#define RAD_NOLOGO 3 // no logo
// other buttons
#define BT_PRESS_ME 4 // press me button (keep below radio button set)
#define BT_DLGPIC 5 // dialog box picture (keep at bottom of list: not part of radio button set)
// Size of dialog box bitmap
#define BMP_LEFT 16
#define BMP_TOP 16
#define BMP_WIDTH 195
#define BMP_HEIGHT 147
// Other values used for drawing around the dialog box bitmap
#define RIGHT_YELLOW (163 + BMP_LEFT)
#define BOTTOM_YELLOW_DLGU 197
#define RIGHT_GRAY_DLGU 125
/////////////////////////////////////////////////////////////////////////////
// CCustom1Dlg dialog
CCustom1Dlg::CCustom1Dlg()
: CAppWizStepDlg(CCustom1Dlg::IDD)
{
//{{AFX_DATA_INIT(CCustom1Dlg)
m_nLogoSpot = -1;
m_nPressMe = FALSE;
//}}AFX_DATA_INIT
}
void CCustom1Dlg::DoDataExchange(CDataExchange* pDX)
{
CAppWizStepDlg::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCustom1Dlg)
DDX_Radio(pDX, IDC_LOGO_UL, m_nLogoSpot);
DDX_Check(pDX, IDC_PRESS_ME, m_nPressMe);
//}}AFX_DATA_MAP
}
// set appropriate entries in the dictionary
// Parameters:
// bWriteSymbol - Boolean value determining whether we need to write (TRUE) or delete (FALSE)
// a dictionary value
// strName - the dictionary value we're working with
void CCustom1Dlg::SetSymbol(BOOL bWriteSymbol, LPCTSTR strName)
{
if (bWriteSymbol)
logowizaw.m_Dictionary.SetAt(strName, CString("1"));
else
logowizaw.m_Dictionary.RemoveKey(strName);
}
// This is called whenever the user presses Next, Back, or Finish with this step
// present. Do all validation & data exchange from the dialog in this function.
BOOL CCustom1Dlg::OnDismiss()
{
if (!UpdateData(TRUE))
return FALSE;
// set the template variables
SetSymbol(m_nLogoSpot == RAD_UPLEFT, _T("LOGO_UPLEFT"));
SetSymbol(m_nLogoSpot == RAD_LOLEFT, _T("LOGO_LOLEFT"));
SetSymbol(m_nLogoSpot == RAD_LORIGHT, _T("LOGO_LORIGHT"));
// don't need to set a symbol for LOGO_NONE
SetSymbol(RAD_UPLEFT || RAD_LOLEFT || RAD_LORIGHT, _T("LOGO_YES"));
SetSymbol(m_nPressMe == TRUE, _T("PRESS_ME_DIALOG"));
return TRUE; // return FALSE if the dialog shouldn't be dismissed
}
BEGIN_MESSAGE_MAP(CCustom1Dlg, CAppWizStepDlg)
ON_CONTROL_RANGE(BN_CLICKED, IDC_LOGO_UL, IDC_LOGO_NONE, OnLogoClicked)
//{{AFX_MSG_MAP(CCustom1Dlg)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_PRESS_ME, OnPressMe)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCustom1Dlg message handlers
// draw a logo on the AppWiz page in the right place. will erase the old logo if one exists
// Parameters:
// nOldID - logo location to erase (if it exists)
// nNewID - logo location to draw in now
void CCustom1Dlg::DrawLogo(int nOldID, int nNewID)
{
CDC* pdc = GetDC();
if (nNewID == nOldID && nOldID >= RAD_UPLEFT) // redraw without erase if same spot
{
DrawBitmap(pdc, IDB_LOGO_SMALL, nNewID);
return;
}
if (nOldID >= RAD_UPLEFT) // there is an old ID present, so erase it
EraseBitmap(pdc, nOldID);
// draw the logo in the new spot
DrawBitmap(pdc, IDB_LOGO_SMALL, nNewID);
}
// Determine the rectangle we need to draw the desired bitmap in
// there are three kinds of bitmaps expected here:
// 1. the 'big' bitmap with the picture of the dialog box on it
// 2. the 'baby' bitmap that represents the logo that shifts around on the 'big' bitmap
// 3. the 'press me' bitmap that goes in the middle of the dialog box
void CCustom1Dlg::GetBitmapRect(int nLocID, LPRECT rect)
{
if (nLocID == BT_DLGPIC) // major bitmap
{
rect->left = BMP_LEFT;
rect->top = BMP_TOP;
rect->right = BMP_LEFT + BMP_WIDTH;
rect->bottom = BMP_TOP + BMP_HEIGHT;
return;
}
else if (nLocID == BT_PRESS_ME) // looking for location of 'press me' bitmap
{
rect->left = BMP_LEFT - 10 + (BMP_WIDTH - m_nPressWidth)/2;
rect->top = BMP_TOP + (BMP_HEIGHT - m_nPressHeight)/2;
rect->right = rect->left + m_nPressWidth;
rect->bottom = rect->top + m_nPressHeight;
return;
}
else if (nLocID == RAD_NOLOGO) // no baby bitmap needed
{
rect->top = rect->bottom = rect->left = rect->right = 0;
return;
}
// figure out where to put the baby bitmap (small logo)
if (nLocID == RAD_LOLEFT || nLocID == RAD_LORIGHT)
rect->top = BMP_TOP + BMP_HEIGHT - 30;
else
rect->top = BMP_TOP + 25;
if (nLocID == RAD_LOLEFT || nLocID == RAD_UPLEFT)
rect->left = BMP_LEFT + 15;
else
rect->left = BMP_LEFT + BMP_WIDTH - 30;
rect->right = rect->left + m_nLogoWidth;
rect->bottom = rect->top + m_nLogoHeight;
}
// erase a bitmap. do NOT call this from OnPaint. doing so causes an infinite recursion
// and crashes MSVC very nicely (not). (MSVC will crash in this case only because the
// program you are actually running is the IDE itself. If you do this kind of stuff in
// a different .exe, you will crash that .exe instead.)
void CCustom1Dlg::EraseBitmap(CDC* pdc, int nLocID)
{
RECT rect;
GetBitmapRect(nLocID, &rect);
RedrawWindow(&rect, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
}
// draw a bitmap
// Parameters:
// pdc - device context to draw in
// nBitmapID - which bitmap to draw
// nLocID - where to draw it
void CCustom1Dlg::DrawBitmap(CDC* pdc, int nBitmapID, int nLocID)
{
CDC dcMem;
RECT rect;
if (nLocID == RAD_NOLOGO) // nothing to do
return;
if (!dcMem.CreateCompatibleDC(pdc))
return;
CBitmap picture;
picture.LoadBitmap(nBitmapID);
BITMAP bitmap;
picture.GetObject(sizeof (BITMAP), &bitmap);
GetBitmapRect(nLocID, &rect);
CBitmap* pOldBitmap = dcMem.SelectObject(&picture);
pdc->BitBlt(rect.left, rect.top, bitmap.bmWidth, bitmap.bmHeight, &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pOldBitmap);
}
// user clicked one of the logo location radio buttons
void CCustom1Dlg::OnLogoClicked(UINT /* nCmdID */)
{
int oldLogoSpot = m_nLogoSpot;
UpdateData();
DrawLogo(oldLogoSpot, m_nLogoSpot);
}
void CCustom1Dlg::OnPressMe()
{
UpdateData();
CPaintDC dc(this); // device context for painting
// this erase forces a redraw of the 'press me' button area.
// if we don't do a RedrawWindow (such as is done in EraseBitmap()),
// the bitmap won't paint regardless of the value of m_nPressMe.
// by restricting the area that gets redrawn (erased first in this
// case), we avoid flicker.
EraseBitmap(&dc, BT_PRESS_ME);
if (m_nPressMe)
DrawBitmap(&dc, IDB_PRESS_ME, BT_PRESS_ME);
}
BOOL CCustom1Dlg::OnInitDialog()
{
CAppWizStepDlg::OnInitDialog();
// pick up sizing information for the logo
SetBitmapSize(IDB_LOGO_SMALL, &m_nLogoWidth, &m_nLogoHeight);
// pick up sizing information for the 'press me' button
SetBitmapSize(IDB_PRESS_ME, &m_nPressWidth, &m_nPressHeight);
m_nLogoSpot = IDC_LOGO_LL - IDC_LOGO_UL;
m_nPressMe = TRUE;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// initialize the bitmap size for the specified bitmap ID
void CCustom1Dlg::SetBitmapSize(int nID, int* pwidth, int* pheight)
{
CBitmap picture;
picture.LoadBitmap(nID);
BITMAP bitmap;
picture.GetObject(sizeof (BITMAP), &bitmap);
*pwidth = bitmap.bmWidth;
*pheight = bitmap.bmHeight;
}
// returns which dialog box bitmap we need (with or without help button on it as appropriate)
int CCustom1Dlg::GetDlgBitmapID()
{
if (logowizaw.m_Dictionary.Lookup(_T("HELP"), CString("1")))
return IDB_DLGPIC_WHELP;
else
return IDB_DLGPIC_NOHLP;
}
void CCustom1Dlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
CBitmap pattern;
pattern.LoadBitmap(IDB_YELLOW_PATTERN);
CBrush brush(&pattern);
RECT rectBmp;
GetBitmapRect(BT_DLGPIC, &rectBmp);
CPen penBogus(PS_SOLID, 0, COLORREF(0));
CPen* pOldPen = dc.SelectObject(&penBogus); // Remember current pen.
DrawBitmap(&dc, GetDlgBitmapID(), BT_DLGPIC); // major bitmap (dialog box picture)
DrawBitmap(&dc, IDB_LOGO_SMALL, m_nLogoSpot); // baby bitmap (logo to go on above)
if (m_nPressMe)
DrawBitmap(&dc, IDB_PRESS_ME, BT_PRESS_ME); // 'press me' button
// Since the other two bitmaps are contained entirely on the major bitmap, we only have
// to worry about the major one when we draw the background. If all of the bitmaps
// were not contained in the same rectangle, we would have to worry about all of them
// when drawing the background.
// Draw yellow ABOVE bitmap(s)
RECT rect = {0, 0, 0, 0};
rect.bottom = rectBmp.top;
rect.right = RIGHT_YELLOW + 1;
dc.DPtoLP(&rect);
dc.FillRect(&rect, &brush);
// draw yellow to LEFT of bitmap(s)
rect.left = 0;
rect.top = rectBmp.top;
rect.right = rectBmp.left;
rect.bottom = rectBmp.bottom;
dc.DPtoLP(&rect);
dc.FillRect(&rect, &brush);
// Draw yellow BELOW bitmap(s)
rect.left = 0;
rect.top = 0;
rect.right = 1;
rect.bottom = BOTTOM_YELLOW_DLGU;
MapDialogRect(&rect);
rect.right = RIGHT_YELLOW + 1;
rect.top = rectBmp.bottom;
dc.DPtoLP(&rect);
dc.FillRect(&rect, &brush);
// Draw right border lines
CPen penGray(PS_SOLID, 0, 0x00808080);
dc.SelectObject(&penGray);
dc.MoveTo(rect.right, 0);
POINT point;
point.x = rect.right;
point.y = rectBmp.top;
dc.DPtoLP(&point);
dc.LineTo(point.x, point.y);
point.x = rect.right;
point.y = rectBmp.bottom;
dc.DPtoLP(&point);
dc.MoveTo(point.x, point.y);
dc.LineTo(point.x, rect.bottom);
CPen penWhite(PS_SOLID, 0, 0x00ffffff);
dc.SelectObject(&penWhite);
dc.MoveTo(rect.right+1, 0);
point.x = rect.right+1;
point.y = rectBmp.top;
dc.DPtoLP(&point);
dc.LineTo(point.x, point.y);
point.x = rect.right+1;
point.y = rectBmp.bottom;
dc.DPtoLP(&point);
dc.MoveTo(point.x, point.y);
dc.LineTo(point.x, rect.bottom);
// Restore original pen
dc.SelectObject(pOldPen);
}