훈, IT 공부/C,C++,MFC

[MFC]MFC 버튼을 이용한 프로젝트 #1 버튼 추가 + 사이즈조절

IT훈이 2018. 5. 7.
반응형

MFC 프로젝트

 

2018.04.30 MFC 22일차

 

 MFC의 이해를 위해서는 프로젝트를 진행하는것이 굉장히 도움이 된다. 단순히 공부를 할 때와는 다르게 실력이 늘어나는 것을 느낄 수 있을 것이다. 구글의 도움을 받으면서 이곳 저곳 삽질을 하다 보면 어느 순간 이해를 하면서 어떻게 해야하는지 보이게 될 것이다.

 

 이 프로젝트는 다음 프로젝트와 연결되어서 진행한다. 윈도우 메시지의 이해와 함수들의 이해를 위해서는 복사 붙여넣기 방식 코딩은 절대 하면 안된다. 반드시 함수 하나하나 이해하고 넘어가야 한다. 반복하다보면 어느순간 손이 익을 것이라 생각한다. 절대 생각없이 코딩을 하면 안된다. 코드를 작성하기 위해서 어떤 함수와 메시지컨트롤 들이 필요한지는 몇 분 소요하던지검색 및 공부 후 진행하는 것을 추천한다. 

 깊은 공부가 아닌 이런게 있네~~ 이 정도로 시작하면 좋을 것 같다.

 

MFC 프로젝트 버튼 추가 사이즈 조절

 

VS Version : Microsoft Visual Studio 2008 

OS : window 10

 

기 능

1. 사용자가 값 두개를 입력한 뒤 버튼을 누르거나 동작을 시키면 버튼이 사용자의 값 두개 만큼 생성된다. 

2. 생성된 버튼은 정사각형 ( 가로세로동일 ) 이 되어야한다. 

3. 버튼은 사용자가 Dialog 윈도우 크기를 줄이고 늘리면 동일하게 커지고 작아져야한다.

 

○ 사용된 클래스

- CWnd::CButton : 버튼객체를 생성할 수 있는 클래스

- CGdiObject::CPen : GDI 를 위해서 있는 도구, 선의 색 굵기 지정이 가능하다.

- CRect : 좌표를 저장한다. 

- CString : 문자열을 다루는 클래스

 

 사용된 함수  

- SelectObject() - GDI에 사용할 객체를 선택한다.( CPen, CBrush, CBitmap,CPalette ... )

- MoveTo(int x, int y) - 화면에 선을 긋는 시작점 위치

- LineTo(int x, int y) - 화면에 선을 긋는 끝지점 위치

- DelectObject() - 생성된 GDI 객체를 제거한다. 

- GetClientRect() - 클라이언트 기준에서의 화면 좌표를 받아온다. 

- SetWindowPos(윈도우 위치여부,int x, int y, int width, int height, 속성사용여부) - 윈도우의 위치 크기를 설정한다. 

 

 사용된 메시지

- ON_WM_SIZE() :  윈도우 창의 크기를 변경할 때 발생하는 윈도우 메시지 

- ON_BN_CLICKED() : 버튼을 눌렀을때 발생하는 메시지 ( 메시지 컨트롤을 연결해주어야한다. )

 

 

동작되는 방식

 

실행시 첫 화면

 화면은 기본 600*660 크기로 설정하고 높이 60의 공간에는 컨트롤들을 위치시켰다. 실질적으로 활용되는 버튼의 공간은 600*600의 공간이다.

 

 

숫자 입력 후 확인 버튼

 숫자를 입력하면 버튼이 정렬되어서 생성이 되는 것을 확인 할 수 있다. 간격부분이 모두 동일해야 한다. 물론 5 * 10 이렇게 입력을 해도 생성이 된다. 단 이렇게 입력하면 정사각형 모양으로는 나타나지 않는다. 추가 할 수 있는 기능이지만 굳이 핵심이 아니기 때문이다.

 

사이즈 조절시 상태

입력을 3*3 하고 나면 9개의 버튼이 생성된다. 이후에 윈도우의 사이즈를 조절하면 버튼이 일정하게 커지고 작아지는 것을 확인할 수 있다. 

 

 

핵심 코드부분

void CBtnSizeDlg::OnSize(UINT nType, int cx, int cy)
{
    CDialog::OnSize(nType, cx, cy);
 
    if( m_pBtn == NULL )
        return ;
    if( m_pBtn != NULL && m_pBtnRect == NULL )
        m_pBtnRect = new CRect[m_nCnt];    
 
    // 입성
    CRect Rect = 0;
    
    GetClientRect(&Rect);                // 윈도우의 클라이언트 좌표 획득
 
    
    int i = 0;
    for(; i < m_nCnt; i++ )                // 버튼의 좌표 획득
    {
        m_pBtn[i].GetClientRect(m_pBtnRect[i]);
    } 
 
    int nLeft = 0;                        // 버튼의 초기좌표 
    int nTop = 0;
    int nWidth;                            // 버튼의 넓이 - 윈도우의 크기에 따라 버튼의 크기가 다르기 때문에 윈도우의 크기에 맞게
    int nHeight;                        // 버튼의 높이 - 윈도우의 크기에 따라 버튼의 크기가 달라진다.
 
    nTop = 60+10;                            // 세로는 60부터 시작한다. 빨간줄 10의 약속한 폭
    nLeft = 10;                                // 가로는 10부터 시작한다. 
 
    nHeight = Rect.Height() - 60 - 20 - (5 * (m_nRightEdit - 1));    // 모든 버튼의 높이가 나온다.
    nHeight = nHeight / m_nRightEdit;                                // 버튼 하나의 높이가 나온다.
 
    nWidth = Rect.Width() - 20 - (5 * (m_nLeftEdit - 1));            // 이렇게만 하면 모든 버튼의 총 너비 합이 나온다.
    nWidth = nWidth / m_nLeftEdit;                                // 버튼 하나의 너비가 나온다.
    
    for( i = 0; i < m_nCnt; i++)
    {
        if ( i % m_nLeftEdit == 0 && i != 0 )
        {
            nLeft = 10;
            nTop = nTop + 5 + nHeight;
        }
        m_pBtn[i].SetWindowPos(NULL,nLeft,nTop,nWidth,nHeight,0);
        nLeft = nLeft + 5 + nWidth;
    }
}

 30행~41번행에서 버튼의 값을 계산하여서 반복문을 사용하여 43번 행에서 버튼의 위치를 바꾼다.

 

● 후기

 처음에 문제를 잘못 이해하고 잘못된 방향으로 이해없이 코딩을 하다보니 삽질하는 부분이 조금 많이 있었다. 크기를 일정하게 변경하는 부분에서 버튼하나하나 따로 기능을 가지게끔 작성을 하려 했고, 각 버튼은 위치에 따라서 커지는 속도가 달라지는 부분들 등등 같은 문제를 다르게 해석을 한다고 고생을 조금 했다. 생각을 재정비 한 뒤애 다시 작성할 때는 어떻게 해야하는지 머리속에 생각이나서 처음부터 다시 새롭게 코드를 작성하였고, 어렵지 않게 완성 할 수 있었다. 

 윈도우와 클라이언트 크기와 위치에 관련되어서 정확한 이해를 하게된 계기가 되었다.

 

 

BtnSizeDlg.cpp
다운로드
BtnSizeDlg.h
다운로드

참고 소스파일

 

 

 

 

반응형

댓글