728x90
300x250
[MFC] 윈도우 프로그래밍 기초 - 스크롤바(Scroll Bar) 제어

 

Visual Basic이나 다른 언어에서도 스크롤바 제어 기능이 있는데 MFC의 스크롤바 제어기능은 정말 강력합니다.

 

 

이 기능을 다 제어할 수 있습니다.

참으로 잠재력이 있는 친구입니다.

 

위의 그림의 기능을 하나 하나 다 구현할 수 있습니다.

 

우리는 이번 실습에서 스크롤바를 구현해보도록 하겠습니다.

 


1. 결과물

 

 

 


2. 실습

 

2-1. 레이아웃 설계

 

 

 

Control ID

 Caption

범주(T)

 맴버 변수(N)

 이벤트 처리기

 참고사항

 IDC_STATIC

 너의 몸무게

 

 

 

 

 IDC_STATIC

 너의 애인수

 

 

 

 

 IDC_STATIC

 사람갯수

 

 

 

 

 IDC_STATIC

 키

 

 

 

 

 IDC_BUTTON1

 확인해보기

 

 

 OnBnClickedButton1

 

 IDC_SIZEBAR

 해당없음

 VALUE

 m_size

 

스크롤 범위

 최소값 0

 최대값 255

 해당없음 

 CONTROL

 m_ScrollSize

 

 

 IDC_HONEYBAR

 해당없음

 VALUE

 m_honey

 

스크롤 범위

 최소값 0

 최대값 255 

 해당없음

 CONTROL

 m_ScrollHoney

 

 

 IDC_PEOPLEBAR 

 해당없음

 VALUE

 m_people

 

스크롤 범위

최소값 0

 최대값 255

 해당없음

 CONTROL

 m_ScrollPeople

 

 

 IDC_HEIGHTBAR

 해당없음

 VALUE

 m_height

 

스크롤 범위

 최소값 0

 최대값 255

 해당없음

 CONTROL

 m_ScrollHeight

 

 

 

CExampleDlg 클래스 뷰에서 WM_HSCROLL과 WM_VSCROLL을 OnAdd OnHScroll 추가를 클릭해서 아래의 그림처럼 만들어줍니다. 

 

 

 

 

 


2-2. 코드 구현

 


BOOL CExampleDlg::OnInitDialog()

{

       // 중략

 
        // TODO: 여기에 추가 초기화 작업을 추가합니다.
         m_ScrollSize.SetScrollRange(0, 255);
         m_ScrollHoney.SetScrollRange(0, 255);
         m_ScrollPeople.SetScrollRange(0, 255);
         m_ScrollHeight.SetScrollRange(0, 255);

        

         return TRUE;

}

(사용자 프로젝트명)Dlg.cpp -> BOOL CExampleDlg::OnInitDialog() - 스크롤 범위 지정

 

 

 

 


// CExampleDlg 대화 상자
class CExampleDlg : public CDialogEx

{

      // 중략

 

public:

      // 중략
       void CommonScroll(UINT nSBCode, UINT nPos, CScrollBar& pScrollBar);

      // 중략

}

 (사용자 프로젝트명).h에 함수 원형 만들어보기

 

사실은 이 함수 만든 이유가 OnHScroll ( ), OnVScroll ( )에 두번 구현하기 귀찮아서 함수 만든겁니다.

 


void CExampleDlg::CommonScroll(UINT nSBCode, UINT nPos, CScrollBar& pScrollBar){

 

  switch (nSBCode)
  {

 


             case SB_LINEUP:
                    pScrollBar.SetScrollPos(pScrollBar.GetScrollPos() - 1);
                    break;

 

             case SB_LINEDOWN:
                    pScrollBar.SetScrollPos(pScrollBar.GetScrollPos() + 1);
                    break;

 

             case SB_PAGEUP:
                    pScrollBar.SetScrollPos(pScrollBar.GetScrollPos() - 2);
                    break;

 

             case SB_PAGEDOWN:
                    pScrollBar.SetScrollPos(pScrollBar.GetScrollPos() + 2);
                    break;

 

             case SB_TOP:
                    pScrollBar.SetScrollPos(0);
                    break;

 

             case SB_BOTTOM: // Scroll - 아래 사진 참조
                    pScrollBar.SetScrollPos(pScrollBar.GetScrollLimit());
                    break;

 

             case SB_THUMBTRACK: // Scroll - Dragging
                    pScrollBar.SetScrollPos(nPos);
                    break;

 

             default:
                    break;
        }

 

 

* eg) Bottom (나머지 영역도 다 여기에 해당되는 조작을 의미함.)

 

 

 

 

 


}
{
       // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

       CommonScroll(nSBCode, nPos, *pScrollBar);

       UpdateData(TRUE);

       CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);

       UpdateData(FALSE);

 (사용자 프로젝트명)Dlg.cpp - OnVScroll ( ) 함수 코딩

 
void CExampleDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
        // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

        CommonScroll(nSBCode, nPos, *pScrollBar);
 
        UpdateData(TRUE);

        CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);

        UpdateData(FALSE);

}

 (사용자 프로젝트명)Dlg.cpp - OnHScroll ( ) 함수 코딩

 

 

 
void CExampleDlg::OnBnClickedButton1()
{
       CString strPeople, strHoney, strHeight, strSize;
       CString strResult;

 

       strPeople.Format(_T("사람의 수:%d\n"), m_people);
       strHoney.Format(_T("애인의 수:%d\n"), m_honey);
       strHeight.Format(_T("나의 키:%d\n"), m_height);
       strSize.Format(_T("나의 몸무게:%d\n"), m_size);

 

       strResult.Append(strPeople);
       strResult.Append(strHoney);
       strResult.Append(strHeight);
       strResult.Append(strSize);

 

       AfxMessageBox(strResult);

}

  (사용자 프로젝트명)Dlg.cpp - OnBnClickedButton1 ( ) 함수 코딩

 

 


3. 이론

 

a. 스크롤바 컨트롤 멤버 함수

CScrollBar 클래스를 사용함.

 

함수 

설명 

 int GetScrollPos()

 스크롤바의 현재 위치 값을 획득하기 위해서 사용

 int SetScrollPos(int nPos, BOOL bRedraw)

 스크롤바의 위치를 설정하기 위해 사용

 void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos)

 스크롤바의 범위(min, max)를 획득하기 위해 사용

 void SetScrollRange(int nMinPos, int nMaxPos)

 스크롤바의 범위(min, max)를 설정하기 위해 사용

 void ShowScrollBar(BOOL bShow = TRUE)

 스크롤바를 화면에 보이게 하거나 감추기 위해서 사용

 -> TRUE, FALSE

 BOOL EnableScrollBar(UINT nArrowFlags = ESB_ENABLE_BOTH)

 스크롤바의 양쪽 화살표 사용 여부

 -> TRUE, FALSE

 BOOL SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw)

 SCROLL_INFO 구조체를 사용하여 스크롤바의 범위와 위치를

 지정하기 위해 사용

 BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo, UINT nMask);

 SCROLL INFO 구조체 형태의 데이터를 매개변수로 전달하여

 스크롤바의 범위와 위치를 획득함.

 int GetScrollLimit ( )

 스크롤바의 이동 한계 값을 획득하기 위해서 사용.

 

b. 스크롤바 컨트롤 멤버 함수

 

 afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
 afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); 

nSBCode:스크롤바의 동작 코드

nPos: 스크롤바가 이동된 위치 값

pScrollBar : 메시지가 발생된 스크롤 바의 포인터 

 

반응형
728x90
300x250
[MFC] 윈도우 프로그래밍 기초 - 리스트박스 컨트롤(Listbox Control)

 

짬좀 차신 여러분 지금까지 오신 걸 환영합니다.

여러분들은 다양한 컨트롤들을 체험해보시고 계십니다.?

 

 

먼저

결과물을 확인해보겠습니다.

 


1. 결과물

 

 


2. 레이아웃 설계

 

 

알아서 디자인 하시는 거 알죠??

 

 컨트롤 ID

 CAPTION

 범주(T)

 맴버 변수(N)

 이벤트 처리기

 IDC_STATIC

 계급

 X

 X

 X

 IDC_STATIC

 이름

 X

 X

 X

 IDC_LIST1

 

 Control

 m_ListLevel

 X

 IDC_LIST2

 

 Control

 m_ListName

 X

 IDC_BUTTON1

 조회

 X

 X

 OnBnClickedButton1

 IDC_BUTTON2

 이름 선택 삭제

 X

 X

 OnBnClickedButton2 

 


3. 코드 작성

 

 // CExampleDlg 메시지 처리기

BOOL CExampleDlg::OnInitDialog()
{

            // 중략

            // TODO: 여기에 추가 초기화 작업을 추가합니다.
            m_ListLevel.InsertString(0, _T("이병"));
            m_ListLevel.InsertString(1, _T("일병"));
            m_ListLevel.InsertString(2, _T("상병"));
            m_ListLevel.InsertString(3, _T("병장"));

            

            m_ListName.InsertString(0, _T("도도1"));
            m_ListName.InsertString(1, _T("도도2"));
            m_ListName.InsertString(2, _T("도도3"));
            m_ListName.InsertString(3, _T("도도4"));

 

               return TRUE;

}

 (사용자 프로젝트명)Dlg.cpp - OnInitDialog() 함수 내 입력

 

 



{
        CString strTmp, strMsg;
        int levelidx = m_ListLevel.GetCurSel();
        int nameidx = m_ListName.GetCurSel();

 

        // 계급장
        if (levelidx != -1 && nameidx != -1)
       {
              m_ListLevel.GetText(levelidx, strTmp);

              strMsg.Append(strTmp + " "); // 1. strMsg에 m_ListLevel의 값 = 입력 추가

              m_ListName.GetText(nameidx, strTmp);

              strMsg.Append(strTmp);   // 2. strMsg에 m_ListName의 값 = 입력 추가

              AfxMessageBox(strMsg);   // 3. 출력

         }
         else
              AfxMessageBox(_T("선택 후 사용해라. 좋은 말할때"));


}


void CExampleDlg::OnBnClickedButton2()
{
         CString strMsg;
         int idx;

         idx = m_ListName.GetCurSel();

 

         if (idx == -1)
        {
               strMsg.Format(_T("idx:%d, 선택 후 사용하세요."), idx);
               AfxMessageBox(strMsg);
         }
         else
               m_ListName.DeleteString(idx);

 

}
 

 ExampleDlg.cpp -> 버튼 이벤트 처리
 -> OnBnClickedButton1(  ), OnBnClickedButton2(  )

 


4. 몇 가지 ListBox 소개

 

ListBox에서 컨트롤 맴버 함수에 대해 소개하겠습니다.

리스트박스 컨트롤은 CListBox 클래스를 사용하며, CListBox 클래스는 다음과 같은 멤버 함수들을 가지고 있습니다.

 

afxwin에 위치함.

함수 원형 

설명 

 int AddString(LPCTSTR lpszItem)

 리스트 박스의 문자열 항목을 추가할 때 사용함. (순서 상관없이)

 int InsertString(int nIndex, LPCTSTR lpszItem)

 리스트 박스의 문자열 항목 추가에 사용함. (특정 위치, 순서 있음.)

 int DeleteString(UINT nIndex)

 특정 위치의 항목을 삭제함.

 void ResetContent( )

 리스트 박스의 내용 초기화

 int GetCurSel( )

 리스트 박스 내 현재 선택한 값의 인덱스 값 반환

 int SetCurSel( int nSelect )

 특정 아이템을 선택함.

 -> 원하는 인덱스에 커서를 위치시키고 싶을 때

 void GetText(int nIndex, CString & rString)

 int GetText(_In_ int nIndex, _Pre_notnull_ _Post_z_ LPTSTR lpszBuffer) const;
 void GetText(int nIndex, CString& rString) const;
 int GetTextLen(int nIndex) const;

 특정 인덱스에 위치한 문자열을 획득

 ex) CString aaa;라고 선언

 

 m_List1.GetText( 0, aaa); 라고 하면

 가져올 수 있음.

 

 int GetTextLen(int nIndex) const;

 특정 인덱스의 문자열 길이를 반환

 

 콤보박스(ComboBox)는 사용법이 거의 같으므로 생략합니다.

 

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - Edit Control(에디트 컨트롤) - 택스트상자

 

이번에 만들 건 Edit Control입니다.

여러분은 아마 지금쯤이면 어느 정도 짬좀 찼을 거 같습니다.

 

 

이번에 만들 건 텍스트 상자라고도 볼 수 있는 Edit Control 입니다.

 

 

이렇게 생긴거 하나 만들어 보겠습니다.

 


1. 결과물

 

 

(레이아웃)

 

 

말 안해도 자동으로 레이아웃 그리고 계셔야 합니다.

 

짬 찼으니깐요.

자동으로 못 그리면, 다시 이전 강의로 돌아가세요. 제발~(Please)

 

컨트롤 ID

Caption

범주(T)

변수 이름(N)

최대 문자 수

이벤트 처리기이름 

ReadOnly

IDC_STATIC

입력

 

 

 

 

 

IDC_STATIC

출력

 

 

 

 

 

IDC_EDIT1

 

Value

m_strName

5

 

 

IDC_EDIT2

 

Value

m_printName

5

 

 True

IDC_BUTTON1

입력해보기

 

 

 

OnBnClickedButton

 

 


2. 소스 코드 작성

  
void CExampleDlg::OnBnClickedButton1()
{
      UpdateData(TRUE);
      m_printName = m_strName;
       UpdateData(FALSE);
}

 

코드 내용 - 이벤트 버튼에 관한 코드 

 


3. 설명 - UpdateData에 대해서

 

Visual Basic이나 다른 프로그래밍 언어에선 UpdateData() 이딴거 안써도 솔직히 바로 바뀝니다.

MFC는 불편합니다.

 

실시간 변화를 할 수 없기에 인위적으로 변화를 하도록 제어하고 있습니다.

깊은 의미는 동시접근을 임의로 하지 못하도록 마치 신호등처럼 제어하고 있습니다.

 

 

 

 

운영체제론이라는 책에서 배울 수 있습니다.

교착상태를 예방하기 위해 이러한 원리를 적용한 것입니다.

 

정확한 의미는 우리하고 관련없으므로 생략합니다.

 

 


UpdateData의 함수 원형은 아래와 같습니다.

 

BOOL UpdateData(BOOL bSaveAndValidate = TRUE);

 

-> bSaveAndValidate의 상태는

BOOL 형태이니깐

 

TRUE

 

OR

 

FALSE

 

두 가지 밖에 안됩니다.

 

TRUE 상태에선 변경 작업을 허용합니다.

FALSE 상태에선 변경 작업을 끝냅니다.

 


동작해보면 잘 돌아갑니다. 참 쉽죠??

 

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - (라디오 버튼) + 그룹박스

 

정말 쉽습니다.

 

http://yyman.tistory.com/506 / [MFC] 윈도우 프로그래밍 기초 - 체크 박스 + 버튼 응용 실습 예제

 

오늘 글의 초점은 아래의 결과물을 만드는 것입니다.

 


1. 결과물

 

결과물 먼저 볼까요?

 

 


2. 실습

 

a. 레이아웃 디자인

 

 

 

 

 앞에 글의 레이아웃 모습

 우리가 만들 레이아웃

 

현명하고 지혜로운 사람들은 잘 아시겠지만, 기존꺼 그대로 이어서 하시면 됩니다.

Radio 박스 레이아웃 설계만 하나 알려드리겠습니다.

 


a-1) Radio 박스 설계

 

* 이해를 위한 큰 나무 보기

 

 

* 주의사항 - Radio 박스는 체크박스 컨트롤과 달리 Group 항목을 설정해주지 않으면,

CButton 클래스 형식의 맴버 함수를 만들 수 없습니다.

추가된 라디오 버튼들을 하나씩 선택하여 속성 창에 있는 속성 항목에서 Group 항목을 True로 변경해야 합니다.

 

전 귀찮아서 위의 그림처럼 전체 다 선택했습니다. 그래도 상관없습니다.

 

 

 

 Group -> False 항목을

 

 True로 바꿔주고 변수 추가합니다.

 

 

컨트롤 ID 

 변수명

 Control 유형

 범주(T)

 변수 유형

 IDC_RADIO1

 m_RadioButton1

 라디오 박스

 Control

 CButton

 IDC_RADIO2 

 m_RadioButton2 

 라디오 박스 

 Control 

 CButton 

 IDC_RADIO3

 m_RadioButton3

 라디오 박스

 Control

 CButton

 IDC_STATIC1 

 

 그룹박스

 

 

 IDC_STATIC2 

 

 그룹박스

 

 

 

추가해서 만들 아이템의 구성요소입니다.

다 만들고 나면, 다시 Radio 1, 2, 3을 선택합니다.

 

아래와 같이 설정합니다.

 

 

 

 

 Group -> True 항목을

 

 False로 바꿔줍니다.

 

그러면 Radio 버튼 설계는 끝났습니다.

 


b. 코드

 

 

 

 (사용자 프로젝트명)ControlDlg.cpp

 

 

 

 

  (사용자 프로젝트명)ControlDlg.cpp 내에 BOOL CMFCControlDlg::OnInitDialog() 내부에 구현

 지난 번 강의에선 SetDlgItem( )로 컨트롤 Caption을 변경하였는데,

 이번에는 우리가 만든 변수를 직접 접근하여 변경하는 방법을 넣었습니다.

 같은 동작을 하니깐 오해하지 말고 두 가지 방법이 있구나 이 정도로 아셨으면 합니다.

 

 

 

 void CMFCControlDlg::OnBnClickedButton1()
 {
        // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

         CString szMsg_Name;
         CString szMsg_Menu;
         CString szMsg;

 

         if (m_CheckBox1.GetCheck() == BST_CHECKED)
         {
              GetDlgItemText(IDC_CHECK1, szMsg_Name);
              szMsg_Name.Append(_T("님\n"));
         }

         else if (m_CheckBox2.GetCheck() == BST_CHECKED)
         {
              GetDlgItemText(IDC_CHECK2, szMsg_Name);
              szMsg_Name.Append(_T("님\n"));
         }

         else if (m_CheckBox3.GetCheck() == BST_CHECKED)
        {
              GetDlgItemText(IDC_CHECK3, szMsg_Name);
              szMsg_Name.Append(_T("님\n"));
        }

 

         // 추가 - Radio 예제

        if (m_RadioButton1.GetCheck() == BST_CHECKED)
        {
              //GetDlgItemText(IDC_RADIO1, szMsg);
               m_RadioButton1.GetWindowTextW(szMsg_Menu);
               szMsg_Menu.Append(_T("- 요리 형"));
        }

         else if (m_RadioButton2.GetCheck() == BST_CHECKED)
        {
              //GetDlgItemText(IDC_RADIO2, szMsg);
               m_RadioButton2.GetWindowTextW(szMsg_Menu);
               szMsg_Menu.Append(_T("- 요리 형"));
         }

 

          else if (m_RadioButton3.GetCheck() == BST_CHECKED)
         {
               //GetDlgItemText(IDC_RADIO3, szMsg);
               m_RadioButton3.GetWindowTextW(szMsg_Menu);
               szMsg_Menu.Append(_T("- 요리 형"));
         }

 

         szMsg_Menu.Append(_T("\n음식하세요."));

         szMsg.Append(szMsg_Name);
         szMsg.Append(szMsg_Menu);

         AfxMessageBox(szMsg);

 

 }

 (사용자 프로젝트명)ControlDlg.cpp 내에 void CMFCControlDlg::OnBnClickedButton1() 내부에 구현

 

 지난 번 글에서는 GetDlgItem( )로 컨트롤 Caption의 값을 CString 형 변수에 전달하였는데,

 이번에는 만든 변수를 접근하여 가져오는 방법을 넣었습니다.

 

 

구현 끝... 수고하세요.

반응형

+ Recent posts