본문 바로가기

old drawer/C, C++, MFC

[MFC] SDI 환경에서 버튼의 동적 생성과 메시지를 처리하는 방법

[질문 내용]

mfc위자드로 CView로 상속받은 (SDI)프로젝트를 생성했습니다.

그리고 뷰에 1행에 동적으로 버튼을 행맞춰서 만들고 싶은데, 아무리 생각해도 모르겠군요.
동적으로 말입니다. 4개든 10개든.... 그리고 각 버튼을 눌렀을때 메시지박스가 나와 "현재버튼은
1입니다." 같이 나왔으면 합니다. 다시말해 이벤트 핸들러도 동적으로 만들어야 합니다.

너무나 어려워 질문드립니다.

[답변 내용]

안녕하세요~!

먼저 동적으로 버튼을 5개 생성시킨다고 가정하고 해더파일에

  #define MAX_BUTTON_COUNT  5

라고 먼저 정의하고, 버튼을 동적으로 만들어서 사용해야하니까 동적으로
생성된 버튼을 관리할 변수를 선언해야겠죠? 클래스 선언부에 말이죠!!

private:
CButton *mp_test_button[MAX_BUTTON_COUNT];

라고 추가하신후에, 먼저 1행이 의미하는게 정확하게 먼지 모르겠지만
가로방향으로 같이 위치하는 거라고 가정하고 먼저 생성시키는것을 살펴보면
다음과 같습니다. WM_CREATE를 핸들러로 등록하고 다음과 같이 코드를
추가하면 됩니다.

int CViewbuttonView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if(CView::OnCreate(lpCreateStruct) == -1) return -1;

  CString str;
  for(int i = 0; i < MAX_BUTTON_COUNT; i++){
      str.Format("Test %d", i + 1);
      mp_test_button[i] = new CButton();
      mp_test_button[i]->Create(str, WS_CHILD | WS_VISIBLE |
          BS_PUSHBUTTON, CRect(10 + i*100, 10, 100 + i*100, 36),
                    this, 25000 + i);
  }
  return 0;
}

이렇게 하면 버튼이 생성될겁니다. 한줄로 주루룩~~  ^^; 각 버튼을 구별하는
아이디는 25000, 25001, 25002, 25003, 25004로 정해집니다. 각 버튼을
누르면 이 번호에 해당하는 메시지가 WM_COMMAND 메시지와 함게 발생합니다.
물론 버튼의 ID는 wParam 메시지에 들어가구요...

그럼 버튼을 눌렀을때 메시지를 처리할 방법을 생각해보죠~ CView를 클래스
위저드로 보면 OnCommand라는 메소드를 추가할수 있습니다. 그곳에서
동적으로 메시지를 처리할수 있습니다. 다음을 보시죠~ ^^;

BOOL CViewbuttonView::OnCommand(WPARAM wParam, LPARAM lParam)
{
  if(wParam >= 25000 && wParam < 25000 + MAX_BUTTON_COUNT){
      CString str;
      str.Format("저는 %d번 버튼임다.~~ ^^;", wParam - 25000 + 1);
      AfxMessageBox(str);
  }

  return CView::OnCommand(wParam, lParam);
}

버튼에 의해서 발생하는 메시지는 25000~25004 사이의 값을테고 발생한
메시지에 25000을 빼면 각 버튼의 값이 정해지죠~ 0~4로, 하지만 화면에는
1~5로 변경해서 출력해야 하기때문에 1을 더해주면 됩니다. ^^;

자~ 이제는 동적으로 생성된 버튼을 삭제해야겠죠~! WM_DESTROY 메시지
핸들러에서 처리하면 됨다. 아래를 보세요~

void CViewbuttonView::OnDestroy()
{
  for(int i = 0; i < MAX_BUTTON_COUNT; i++){
      delete mp_test_button[i];
  }

  CView::OnDestroy();
}

동적으로 만들어진 객체를 다 파괴하면 됨다. ^^; 어렵지 않죠?