MFC, 동적 버튼 생성, 색을 입히고 클릭 이벤트 설정

MFC, 동적 버튼 생성, 색을 입히고 클릭 이벤트 설정



MFC에서 동적으로 버튼을 생성하고 클릭 이벤트를 설정합니다. 동적 버튼이란 동적으로 색상을 변경하는 것을 의미합니다. 아래 그림처럼 색상이 다양합니다.


위의 첨부 파일을 다운 받으셔서 실행하시면 확인이 됩니다.


MFC 동적 버튼 생성 - 색과 클릭 이벤트 생성[MFC, 동적 버튼 생성, 색을 입히고 클릭 이벤트 설정]

프로그램 개요


- 버튼의 동적 생성.

- 버튼 클릭 시, 색상이 변하며 메시지 박스가 생성.


달랑 두 가지 기능이 있습니다. 버튼을 동적으로 생성하고 색을 입히고, 클릭 이벤트도 설정합니다.


우선, 아래와 같이 4개의 함수와 1개의 변수를 설정합니다.


1
2
3
4
5
6
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
void addButton(CButton* createButton);
void ClearButton();
 
CArray<CButton*> m_arrButton;
cs


간단하게 설명하면 이렇습니다.


- OnCommand : 클릭 이벤트

- OnDrawItem : 색상 입히기

- addButton : 동적 버튼 생성 함수

- ClearButton : 메모리 해제

- CArray : 동적 버튼 저장소


프로그램은 버튼을 클릭함으로써 시작됩니다. 별로 어렵지 않죠?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void CTest_DynamicCreation_ButtonDlg::OnBnClickedButton1()
{
    UpdateData(TRUE);
 
    if(m_nBtnNumber > 20)
    {
        MessageBox(_T("20 미만으로 설정하세요"));
        return;
    }
 
    if(m_arrButton.GetSize() > 0)
        ClearButton();
    
    for(int i = 0; i <= m_nBtnNumber; i++)
    {
        int left = 10 + (i * 30+ i * 2;
        int top = 40;
        int right = 10 + (i * 30+ (i * 2+ 30;
        int bottom = 65;
 
        CButton* createButton = new CButton;
        createButton->Create(NULL, BS_PUSHBUTTON | WS_VISIBLE
        | WS_CHILD | BS_OWNERDRAW, CRect(left, top, right, bottom), this2000 + i);
        addButton(createButton);
    }
 
    Invalidate(TRUE);
}
cs


위의 소스에서 BS_OWNERDRAW 옵션을 주지 않으면 색을 입힐 수 없습니다. 그리고 맨 마지막에 2000 + i를 함으로써, nID도 구분해 줍니다.

addButton() 함수에선 단순히, CArray에 생성된 버튼을 저장합니다.


1
2
3
4
void CTest_DynamicCreation_ButtonDlg::addButton(CButton* createButton)
{
    m_arrButton.Add(createButton);
}
cs


버튼에 색을 입히기 위해선 OnDrawItem 함수를 반드시 다시 정의 해야 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void CTest_DynamicCreation_ButtonDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    UINT uStyle = DFCS_BUTTONPUSH;
 
    ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);
 
    if (lpDrawItemStruct->itemState & ODS_SELECTED)
        uStyle |= DFCS_PUSHED;
 
    ::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle);
 
    CDC dc;
    dc.Attach(lpDrawItemStruct->hDC);
 
    RECT rect;
    rect = lpDrawItemStruct->rcItem;
 
    if(nIDCtl >= 2000 && nIDCtl < nIDCtl + m_arrButton.GetSize())
    {
        for(int i = 0; i < m_arrButton.GetSize(); i++)
        {
            if(nIDCtl == 2000 + i)
            {
                dc.FillSolidRect(&rect, RGB(static_cast<unsigned int>(rand() % 254),
                 static_cast<unsigned int>(rand() % 254), static_cast<unsigned int>(rand() % 254)));
                break;
            }
        }
    }
 
    //CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
cs


24번 줄의 dc.FillSolidRect를 통해서 다이얼로그에 버튼을 그립니다.


MFC - 동적으로 버튼 생성, 색을 입히고 클릭 이벤트 설정[MFC, 동적 버튼 생성, 색을 입히고 클릭 이벤트 설정]


OnCommand에선 nID를 기준으로 버튼을 식별할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BOOL CTest_DynamicCreation_ButtonDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
    if(wParam >= 2000 && wParam < 2000 + m_arrButton.GetSize())
    {
        for(int i = 0; i < m_arrButton.GetSize(); i++)
        {
            if(2000 + i == wParam)
            {
                CString strTmp;
                strTmp.Format("%d번 버튼", i + 1);
                MessageBox(strTmp);
            }
        }
    }
 
    return CDialog::OnCommand(wParam, lParam);
cs


메모리 해제 시엔, 버튼 객체를 하나씩 만들어 해제해 줍니다.


1
2
3
4
5
6
7
8
9
10
11
void CTest_DynamicCreation_ButtonDlg::ClearButton()
{
    for(int i = 0; i < m_arrButton.GetSize(); i++)
    {
        CButton* deleteButton = m_arrButton.GetAt(i);
        delete deleteButton;
        deleteButton = NULL;
    }
 
    m_arrButton.RemoveAll();    m_arrButton.FreeExtra();
}
cs


RemoveAll()은 모든 객체를 지우겠다는 의미이고, FreeExtra()는 사용하지 않는 메모리를 반납하겠다는 의미입니다. 당연히, 함께 써줘야 합니다.


ps. MFC는 사람을 바보 만드는데 재주가 있는 듯.


MFC, 동적 버튼 생성, 색을 입히고 클릭 이벤트 설정

댓글(0)

Designed by JB FACTORY