½ºÅ©·ÑµÇ´Â Å©·¹µðÆ® ´ÙÀ̾ó·Î±×
(Scrolling
Credits Dialog)
ÀÌ ³»¿ëÀº Äڵ屸·ç(http://www.codeguru.com)¿¡¼ °¡Á®¿Â °ÍÀÔ´Ï´Ù.
¼Ò½ºÄÚµå ¹Þ±â (credits.h/cpp) : ¾Æ·¡ÀÇ ¼Ò½º¿Í °°Àº °Í.
Å©·¹µðÆ® ´ÙÀ̾ó·Î±×¶õ º¸Åë, ¿µÈ°¡ ³¡³ ÈÄ, ¸¸µå´Âµ¥ Âü¿©ÇÑ »ç¶÷µéÀÇ À̸§ÀÌ Á× È¸é¿¡ ½ºÅ©·ÑµÇ´Â °Íó·³, ¾î¶² ÇÁ·Î±×·¥¿¡¼ ƯÁ¤ÇÑ Å° ½ÃÄö½º¸¦ ´·ÈÀ» ¶§ ±× Á¦Ç° Á¦ÀÛ¿¡ Âü¿©ÇÑ »ç¶÷µéÀÇ À̸§ÀÌ Á× ½ºÅ©·ÑµÇ´Â ´ëÈ»óÀÚ¸¦ ¸»ÇÑ´Ù.
ÀÌ ´ÙÀ̾ó·Î±×´Â »ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ »ö±ò°ú ÆùÆ®·Î ±ÛÀ» º¸¿©ÁÖ°í ¶ÇÇÑ ½ºÅ©·ÑµÇ´Â ȸ鿡 ºñÆ®¸Êµµ º¸¿©ÁØ´Ù. ³ªÅ¸³»°í ½ÍÀº ±ÛÀ» CPP ÆÄÀÏ ¾È¿¡ Á¤ÀÇµÈ °íÁ¤ ¹è¿¿¡ ½á³Ö°í, ´Ù¸¥ ÆùÆ®, »ö µîÀ» »ç¿ëÇϱâ À§Çؼ escape sequenceÀ» »ç¿ëÇÑ´Ù.
Å©·¹µðÆ®´Â ¼øȯÇϸé¼, ½ÃÀÛºÎÅÍ °è¼Ó ¹Ýº¹ÇÏ¿© µ¹¾Æ°£´Ù.
´Ü°è
1. ¸®¼Ò½º ¿¡µðÅ͸¦ »ç¿ëÇÏ¿© ´ÙÀ̾ó·Î±×¸¦ Çϳª ¸¸µç´Ù. ID´Â IDD_DISPLAY ¶ó°í ÇÑ´Ù.
´ÙÀ̾ó·Î±×¿¡ ÀÖ´Â OK ¹öÆ°Àº »ç¿ëÀÚ°¡ ´ÙÀ̾ó·Î±×¸¦ ¾ø¾Ö±â À§ÇØ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
2. Å©·¹µðÆ® Ç¥½Ã À©µµ¿ì¸¦ static text ·Î »ý¼ºÇÑ´Ù. (ÃæºÐÈ÷ Å« Å©±â·Î ¸¸µç´Ù.)
ÀÌ ÅؽºÆ®¹Ú½º¸¦ IDC_DISPLAY_STATIC À̶ó°í À̸§ Áþ´Â´Ù. (ȤÀº »ç¿ëÀÚÀÇ ¸¶À½¿¡ µå´Â ´Ù¸¥ À̸§À¸·Î, ÇÏÁö¸¸ ´Ù¸¥ À̸§À» »ç¿ëÇÑ´Ù¸é, ÀÌ ±Û¿¡¼ Á¦°øÇÏ´Â ¼Ò½ºÄڵ忡¼ IDC_DISPLAY_STATIC À» »ç¿ëÀÚ°¡ ¸¸µç »õ·Î¿î À̸§À¸·Î ¹Ù²ãÁÖ¾î¾ß ÇÑ´Ù.)
3. Ŭ·¡½º À§Àúµå¸¦ »ç¿ëÇÏ¿© ÀÌ ´ÙÀ̾ó·Î±×¹Ú½º¿¡ ¿¬°áµÉ »õ·Î¿î Ŭ·¡½º¸¦ ¸¸µç´Ù.
Ŭ·¡½º¸íÀº CCredits·Î ÇÏ°í, Base Class ´Â CDialog·Î ÇÑ´Ù.
4. Ŭ·¡½º À§Àúµå·Î ´ÙÀ½ÀÇ ÇÔ¼ö¿Í ¸Þ½ÃÁö Çڵ鷯µéÀ» ¸¸µç´Ù.
virtual void OnOK();
afx_msg
void OnPaint();
virtual
BOOL OnInitDialog();
afx_msg
void OnTimer(UINT nIDEvent);
afx_msg
void OnDestroy();
5. ¾Æ·¡ ¼Ò½º ÄÚµåÀÇ ±½Àº ±Û¾¾ºÎºÐÀÌ Á÷Á¢ Ãß°¡ÇÑ ºÎºÐÀÌ´Ù. º¹»ç-ºÙ¿©³Ö±â¸¦ ÇÏ¸é µÈ´Ù. ¼Ò½ºÄڵ尡 ÇÊ¿äÇÏ´Ù¸é À§ÀÇ ¸µÅ©¿¡¼ ¹ÞÀ» ¼ö ÀÖ´Ù.
6. ¾Æ·¡ Äڵ带 ´Ù ³ÖÀº ÈÄ, ´Ù¸¥ °÷¿¡¼ DoModal() ÇÔ¼ö·Î ºÒ·¯ »ç¿ëÇÏ¸é µÈ´Ù.
¿¹¸¦ µé¾î AboutBox¿¡¼ ºÒ·¯¿Â´Ù°í »ý°¢Çϸé AboutBoxÀÇ ´ÙÀ̾ó·Î±×¿¡ ¹öÆ° Çϳª¸¦ Ãß°¡ÇÏ°í ±× ¹öÆ°ÀÇ Çڵ鷯¿¡ ´ÙÀ½Ã³·³ Äڵ带 ³ÖÀ¸¸é µÈ´Ù.
±×¸²À» Ãâ·ÂÇÒ °æ¿ì ¹Ì¸® ±×¸²À» ¸¸µé¾î µÎ´Â °ÍÀ» ÀØÁö ¸» °Í
#include "Credits.h" |
=============¼Ò½º ÄÚµå===================
// credits.h : header file
//
/////////////////////////////////////////////////////////////////////////////
//
CCredits dialog
#define DISPLAY_TIMER_ID 150 //
timer id
class CCredits : public CDialog
{
// Construction
public:
CCredits(CWnd*
pParent = NULL); // standard constructor
RECT m_ScrollRect,r;
// rect of Static Text frame
int nArrIndex,nCounter;
// work ints
CString
m_szWork; //
holds display line
BOOL m_bFirstTime;
BOOL
m_bDrawText;
int
nClip;
int
nCurrentFontHeight;
CWnd*
m_pDisplayFrame;
CBitmap
m_bmpWork; //
bitmap holder
CBitmap* pBmpOld;
//
other bitmap work members
CBitmap*
m_bmpCurrent;
HBITMAP
m_hBmpOld;
CSize
m_size; //
drawing helpers
CPoint
m_pt;
BITMAP
m_bmpInfo;
CDC
m_dcMem;
BOOL
m_bProcessingBitmap;
// Dialog Data
//{{AFX_DATA(CCredits)
enum
{ IDD = IDD_DISPLAY };
//}}AFX_DATA
//
Overrides
// ClassWizard
generated virtual function overrides
//{{AFX_VIRTUAL(CCredits)
protected:
virtual
void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
//
Implementation
protected:
//
Generated message map functions
//{{AFX_MSG(CCredits)
virtual
void OnOK(); //
<-----Ŭ·¡½º À§Àúµå¿¡¼ Ãß°¡ÇÑ ºÎºÐ
afx_msg
void OnPaint(); //
<-----Ŭ·¡½º À§Àúµå¿¡¼ Ãß°¡ÇÑ ºÎºÐ
virtual
BOOL OnInitDialog(); //
<-----Ŭ·¡½º À§Àúµå¿¡¼ Ãß°¡ÇÑ ºÎºÐ
afx_msg
void OnTimer(UINT nIDEvent); // <-----Ŭ·¡½º
À§Àúµå¿¡¼ Ãß°¡ÇÑ ºÎºÐ
afx_msg
void OnDestroy(); //
<-----Ŭ·¡½º À§Àúµå¿¡¼ Ãß°¡ÇÑ ºÎºÐ
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
credits.cpp : implementation file
//**************************************************************************
//
Note : ½ºÅ©·ÑµÇ´Â ȸ鿡´Â ±×¸²µµ ³ªÅ¸³ª°Ô ÇÒ ¼ö Àִµ¥, ÀÌ ¿¹Á¦¿¡¼´Â
//
ID°¡
"BITMAP1" ÀÎ ºñÆ®¸Ê Çϳª¸¦
»ç¿ëÇß´Ù.
// ¿©±â¼ ÁÖÀÇÇÒ Á¡Àº ÀÌ ID ¿¡ µû¿ÈÇ¥µµ Æ÷ÇԵȴٴ °ÍÀÌ´Ù.
//
( "BITMAP1"
not BITMAP1 )
// ±×¸®°í
pArrCredit[] ¹è¿¿¡ ±×¸²ÀÇ À̸§À» ³ÖÀ» ¶§ ÆÄÀϸí°ú
// escape sequence »çÀÌ¿¡ ºó
°ø°£À» µÎ¸é ¾ÈµÈ´Ù.
// ( "BITMAP1\b" = ¿ÇÀº °æ¿ì, "BITMAP1 \b" = Ʋ¸° °æ¿ì)
#include "stdafx.h"
#include "resource.h"
#include
"credits.h"
#ifdef _DEBUG
#undef THIS_FILE
static char
BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define SCROLLAMOUNT -1
#define
DISPLAY_SLOW 70
#define DISPLAY_MEDIUM 40
#define
DISPLAY_FAST 10
#define DISPLAY_SPEED DISPLAY_MEDIUM
#define
RED RGB(255,0,0)
#define
GREEN RGB(0,255,0)
#define
BLUE RGB(0,0,255)
#define
WHITE RGB(255,255,255)
#define
YELLOW RGB(255,255,0)
#define
TURQUOISE RGB(0,255,255)
#define
PURPLE RGB(255,0,255)
#define
BLACK RGB(0,0,0)
#define
BACKGROUND_COLOR
BLACK
#define TOP_LEVEL_TITLE_COLOR
RED
#define TOP_LEVEL_GROUP_COLOR YELLOW
#define
GROUP_TITLE_COLOR TURQUOISE
#define
NORMAL_TEXT_COLOR WHITE
//
ÆùÆ®ÀÇ ³ôÀ̸¦ Á¤ÇÏ´Â ºÎºÐ
#define TOP_LEVEL_TITLE_HEIGHT 21
#define
TOP_LEVEL_GROUP_HEIGHT 19
#define
GROUP_TITLE_HEIGHT 17
#define NORMAL_TEXT_HEIGHT
15
// Ãâ·ÂÇÒ ¹®Àڹ述ú
ÇÔ²² ¾²ÀÏ escape sequence¸¦ Á¤ÀÇÇÏ´Â ºÎºÐ
// Å« ±ÛÀÚ¿¡¼ ÀÛÀº ±ÛÀÚ¼øÀ¸·Î Ç¥½ÃµÇ¾î ÀÖ´Ù.
#define TOP_LEVEL_TITLE '\n'
#define TOP_LEVEL_GROUP
'\r'
#define GROUP_TITLE '\t'
#define NORMAL_TEXT '\f'
#define DISPLAY_BITMAP '\b'
#define ARRAYCOUNT 8 //
Ãâ·ÂµÉ ¹®ÀåÀÇ °¹¼ö
// Ãâ·ÂµÉ ¹®ÀåÀ» °íÁ¤¹è¿¿¡ ³Ö´Â´Ù.
char *pArrCredit[] = { "Å©·¹µðÆ® ´ÙÀ̾ó·Î±×\n",
"",
"BITMAP1\b",
// ºñÆ®¸Ê ID¿¡´Â µû¿ÈÇ¥µµ Æ÷ÇԵǾî ÀÖ´Ù.
"TOP
LEVEL TITLE\n",
"TOP
LEVEL GROUP\r",
"GROUP
TITLE\t",
"NORMAL
TEXT\f",
"" };
/////////////////////////////////////////////////////////////////////////////
// CCredits dialog
CCredits::CCredits(CWnd* pParent /*=NULL*/)
: CDialog(CCredits::IDD,
pParent)
{
//{{AFX_DATA_INIT(CCredits)
//}}AFX_DATA_INIT
}
void CCredits::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCredits)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCredits, CDialog)
//{{AFX_MSG_MAP(CCredits)
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCredits message handlers
void CCredits::OnOK()
{
KillTimer(DISPLAY_TIMER_ID);
CDialog::OnOK();
}
//************************************************************************
// InitDialog
//
// Setup
the display rect and start the timer.
//************************************************************************
BOOL CCredits::OnInitDialog()
{
CDialog::OnInitDialog();
BOOL bRet;
UINT nRet;
nCurrentFontHeight = NORMAL_TEXT_HEIGHT;
CClientDC dc(this);
bRet = m_dcMem.CreateCompatibleDC(&dc);
m_bProcessingBitmap=FALSE;
nArrIndex=0;
nCounter=1;
nClip=0;
m_bFirstTime=TRUE;
m_bDrawText=FALSE;
m_hBmpOld = 0;
m_pDisplayFrame=(CWnd*)GetDlgItem(IDC_DISPLAY_STATIC);
// If you assert here, you
did not assign your static display control
// the IDC_ value that was
used in the GetDlgItem(...). This is the
// control that will display
the credits.
_ASSERTE(m_pDisplayFrame);
m_pDisplayFrame->GetClientRect(&m_ScrollRect);
nRet = SetTimer(DISPLAY_TIMER_ID,DISPLAY_SPEED,NULL);
_ASSERTE(nRet != 0);
return TRUE; // return
TRUE unless you set the focus to a control
//
EXCEPTION: OCX Property Pages should return FALSE
}
//************************************************************************
// OnTimer
//
// On
each of the display timers, scroll the window 1 unit. Each 20
// units, fetch the next array element and
load into work string. Call
// Invalidate and UpdateWindow to invoke the
OnPaint which will paint
// the contents of the newly updated work string.
//************************************************************************
void CCredits::OnTimer(UINT nIDEvent)
{
if (nIDEvent != DISPLAY_TIMER_ID)
{
CDialog::OnTimer(nIDEvent);
return;
}
if (!m_bProcessingBitmap)
if (nCounter++ % nCurrentFontHeight
== 0) { // every x timer events, show new line
nCounter=1;
m_szWork
= pArrCredit[nArrIndex++];
if
(nArrIndex > ARRAYCOUNT-1) nArrIndex=0;
nClip
= 0;
m_bDrawText=TRUE;
}
m_pDisplayFrame->ScrollWindow(0,SCROLLAMOUNT,&m_ScrollRect,&m_ScrollRect);
nClip = nClip + abs(SCROLLAMOUNT);
CRect r;
CWnd* pWnd = GetDlgItem(IDC_DISPLAY_STATIC);
ASSERT_VALID(pWnd);
pWnd->GetClientRect(&r);
pWnd->ClientToScreen(r);
ScreenToClient(&r);
InvalidateRect(r,FALSE);
// FALSE does not erase background
CDialog::OnTimer(nIDEvent);
}
//************************************************************************
// OnPaint
//
// Send
the newly updated work string to the display rect.
//************************************************************************
void CCredits::OnPaint()
{
CPaintDC
dc(this); // device context for painting
PAINTSTRUCT
ps;
CDC* pDc = m_pDisplayFrame->BeginPaint(&ps);
pDc->SetBkMode(TRANSPARENT);
//*********************************************************************
// FONT
SELECTION
CFont m_fntArial;
CFont* pOldFont;
BOOL bSuccess;
BOOL bUnderline;
BOOL bItalic;
if (!m_szWork.IsEmpty())
switch (m_szWork[m_szWork.GetLength()-1]
) {
case NORMAL_TEXT:
default:
bItalic
= FALSE;
bUnderline
= FALSE;
nCurrentFontHeight
= NORMAL_TEXT_HEIGHT;
bSuccess
= m_fntArial.CreateFont(NORMAL_TEXT_HEIGHT, 0, 0, 0,
FW_THIN,
bItalic, bUnderline, 0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
PROOF_QUALITY,
VARIABLE_PITCH
| 0x04 | FF_DONTCARE, (LPSTR)"Arial");
pDc->SetTextColor(NORMAL_TEXT_COLOR);
pOldFont
= pDc->SelectObject(&m_fntArial);
break;
case TOP_LEVEL_GROUP:
bItalic
= FALSE;
bUnderline
= FALSE;
nCurrentFontHeight
= TOP_LEVEL_GROUP_HEIGHT;
bSuccess
= m_fntArial.CreateFont(TOP_LEVEL_GROUP_HEIGHT, 0, 0, 0,
FW_BOLD,
bItalic, bUnderline, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
VARIABLE_PITCH
| 0x04 | FF_DONTCARE, (LPSTR)"Arial");
pDc->SetTextColor(TOP_LEVEL_GROUP_COLOR);
pOldFont
= pDc->SelectObject(&m_fntArial);
break;
case GROUP_TITLE:
bItalic
= FALSE;
bUnderline
= FALSE;
nCurrentFontHeight
= GROUP_TITLE_HEIGHT;
bSuccess
= m_fntArial.CreateFont(GROUP_TITLE_HEIGHT, 0, 0, 0,
FW_BOLD,
bItalic, bUnderline, 0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
PROOF_QUALITY,
VARIABLE_PITCH
| 0x04 | FF_DONTCARE, (LPSTR)"Arial");
pDc->SetTextColor(GROUP_TITLE_COLOR);
pOldFont
= pDc->SelectObject(&m_fntArial);
break;
case TOP_LEVEL_TITLE:
bItalic
= FALSE;
bUnderline
= TRUE;
nCurrentFontHeight
= TOP_LEVEL_TITLE_HEIGHT;
bSuccess
= m_fntArial.CreateFont(TOP_LEVEL_TITLE_HEIGHT, 0, 0, 0,
FW_BOLD,
bItalic, bUnderline, 0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
PROOF_QUALITY,
VARIABLE_PITCH
| 0x04 | FF_DONTCARE, (LPSTR)"Arial");
pDc->SetTextColor(TOP_LEVEL_TITLE_COLOR);
pOldFont
= pDc->SelectObject(&m_fntArial);
break;
case DISPLAY_BITMAP:
if
(!m_bProcessingBitmap) {
CString
szBitmap = m_szWork.Left(m_szWork.GetLength()-1);
if
(!m_bmpWork.LoadBitmap((const char *)szBitmap)) {
CString
str;
str.Format("Could
not find bitmap resource \"%s\". "
"Be
sure to assign the bitmap a QUOTED resource name", szBitmap);
KillTimer(DISPLAY_TIMER_ID);
MessageBox(str);
return;
}
m_bmpCurrent
= &m_bmpWork;
m_bmpCurrent->GetObject(sizeof(BITMAP),
&m_bmpInfo);
m_size.cx
= m_bmpInfo.bmWidth; // width of
dest rect
RECT
workRect;
m_pDisplayFrame->GetClientRect(&workRect);
m_pDisplayFrame->ClientToScreen(&workRect);
ScreenToClient(&workRect);
//
upper left point of dest
m_pt.x
= (workRect.right -
((workRect.right-workRect.left)/2)
- (m_bmpInfo.bmWidth/2));
m_pt.y
= workRect.bottom;
pBmpOld
= m_dcMem.SelectObject(m_bmpCurrent);
if
(m_hBmpOld == 0) m_hBmpOld = (HBITMAP) pBmpOld->GetSafeHandle();
m_bProcessingBitmap = TRUE;
}
break;
}
CBrush
bBrush(BLACK);
CBrush* pOldBrush;
pOldBrush = pDc->SelectObject(&bBrush);
// Only fill rect comprised
of gap left by bottom of scrolling window
r=m_ScrollRect;
r.top = r.bottom-abs(SCROLLAMOUNT);
pDc->DPtoLP(&r);
if (m_bFirstTime) {
m_bFirstTime=FALSE;
pDc->FillRect(&m_ScrollRect,&bBrush);
} else
pDc->FillRect(&r,&bBrush);
r=m_ScrollRect;
r.top = r.bottom-nClip;
if (!m_bProcessingBitmap)
{
int
x = pDc->DrawText((const char *)m_szWork, m_szWork.GetLength()-1, &r,
DT_TOP|
DT_CENTER| DT_NOPREFIX | DT_SINGLELINE);
m_bDrawText=FALSE;
} else {
dc.StretchBlt(
m_pt.x, m_pt.y-nClip, m_size.cx, nClip, &m_dcMem, 0, 0,
m_bmpInfo.bmWidth-1,
nClip, SRCCOPY );
if
(nClip > m_bmpInfo.bmHeight) {
m_bmpWork.DeleteObject();
m_bProcessingBitmap
= FALSE;
nClip=0;
m_szWork.Empty();
nCounter=1;
}
pDc->SelectObject(pOldBrush);
bBrush.DeleteObject();
m_pDisplayFrame->EndPaint(&ps);
return;
}
pDc->SelectObject(pOldBrush);
bBrush.DeleteObject();
if (!m_szWork.IsEmpty())
{
pDc->SelectObject(pOldFont);
m_fntArial.DeleteObject();
}
m_pDisplayFrame->EndPaint(&ps);
//
Do not call CDialog::OnPaint() for painting messages
}
void CCredits::OnDestroy()
{
CDialog::OnDestroy();
m_dcMem.SelectObject(CBitmap::FromHandle(m_hBmpOld));
m_bmpWork.DeleteObject();
}
- the end of this article -