BLOG ARTICLE 컨트롤 | 1 ARTICLE FOUND

  1. 2007.01.14 컨트롤

컨트롤

programming/API 2007. 1. 14. 23:44
1. 컨트롤
  가. 컨트롤(control)이란 사용자와의 인터페이스를 이루는 도구 (사용자로부터 명령과 입력을 받아들이고
    출력 결과를 보여준다, 즉 입출력 도구)
  나. 프로그램은 실행중에 끊임없이 사용자와 통신을 하는데 컨트롤을 통해 명령과 정보를 받아들이고
    또한 컨트롤을 통해 실행 결과를 사용자에게 보고한다.
  다. 컨트롤도 하나의 윈도우이다. 화면상의 일정한 영역을 차지하며 자신의 고유 메시지를 처리할 수
    있는 능력을 가지고 있으며 차일드 윈도우로 존재한다. 윈도우를 만들 때는 WNDCLASS형의 구조체를
    정의하고 RegisterClass함수로 등록한 후 CreateWindow 함수를 호출한다. 그러나 컨트롤은 윈도우즈가
    운영체제 차원에서 제공하기 때문에 윈도우 클래스를 등록할 필요없이 미리 등록되어 있는 윈도우 클래스를
    사용하기만 하면 된다. 미리 정의된 윈도우 클래스에는 다음과 같은 종류가 있다
  라. 윈도우 클래스의 종류
    윈도우 클래스         |           컨트롤
    ----------------------------------
    button                   |    버튼, 체크, 라디오
    static                   |    텍스트
    scrollbar               |    스크롤바
    edit                      |    에디트
    listbox                   |    리스트 박스
    combobox             |    콤보 박스
  마. 윈도우 클래스들은 시스템 부팅시에 운영체제에 의해 등록되므로 윈도우 클래스를 따로 등록할 필요없이
    CreateWindow함수의 첫 번째 인수로 클래스 이름만 주면 해당 컨트롤을 만들수 있다.

2. button
  가. CreateWindow(TEXT("button"), TEXT("Click Me"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
    20, 20, 100, 25, hWnd, (HMENU)0, g_hInst, NULL);
  == CreateWindow(만들고자 하는 윈도우의 클래스, 캡션, 스타일,
    위치, x위치, y위치, 폭, 높이, 부모 윈도우, 핸들, 부모윈도우 인스턴스 핸들, 사용자정의데이터);
  나. 스타일
    스타일                                           설명
    ------------------------------------------------------------------------------
    BS_PUSHBUTTON                           푸시 버튼
    BS_DEFPUSHBUTTON                     디폴트 푸시 버튼
    BS_CHECKBOX                               체크 박스
    BS_3STATE                                   3가지 상태를 가지는 체크 박스
    BS_AUTOCHECKBOX                       자동 체크 박스
    BS_AUTO3STATE                           3가지 상태를 가지는 자동 체크 박스
    BS_RADIOBUTTON                           라디오 버튼
    BS_AUTORADIOBUTTON                   자동 라디오 버튼
    BS_GROUPBOX                             그룹 박스
  다. 부모와의 통신
    1) 버튼을 클릭할 경우 WM_COMMAND 메시지를 부모 윈도우에게 보내며 이때 전달되는 정보는
      인수                 설명
      --------------------------
      HIWORD(wParam)        통지코드(왜 메시지를 보냈는가를 나타내는 값)
      LOWORD(wParam)       컨트롤의 ID (아홉번째 인수)
      lParam                        메시지를 보낸 차일드 윈도우의 윈도우 핸들
    2) 부모 윈도우는 WM_COMMAND에서 LOWORD(wParam)값을 조사하여 어떤 컨트롤이 눌러졌는지에
      따라 적절한 처리를 한다. WM_COMMAND 메시지는 컨트롤의 통지 메시지뿐만 아니라 메뉴항목,
      엑셀러레이터 등의 명령을 처리하는 중요한 일을 한다. 이름 그대로 버튼을 누르거나, 메뉴를 선택하거나
      엑셀러레이터를 누르는 등 사용자로부터의 명령이 될 만한 것들을 모두 처리한다. 이때 컨트롤의 ID, 메뉴 ID
      엑셀러레이터 ID등은 모두 LOWORD(WPARAM)으로 전달되므로 이 세가지 명령들끼리는 0~65535까지의
      범위에서 상호 중복되지 않는 ID를 가져야한다.
      가) 일반적인 메세지 처리 루틴
        case WM_COMMAND:
          switch( LOWORD(wParam) )     // ID에 따른 분기
             case 메뉴 1: 처리 1; break;
             case 메뉴 2: 처리 2; break;
             case 엑셀러레이터 1: 처리 3; break;
             case 컨트롤 1:
               switch( HIWORD(wParam) )       // 통지 코드에 따른 분기
                 case 통지코드 1: 처리 1; break;
                 case 통지코드 2: 처리 2; break;

3. 체크 박스
  가. 푸시 버튼은 사용자로부터 명령을 받아들이기 위해 사용하는데 비해 체크 박스는 참, 거짓의 진위적인
    선택을 입력받을 때 주로 사용된다. 체크 박스도 푸시버튼과 마찬가지로 차일드 윈도우이며 스타일에
    따라 4가지 종류의 체크박스가 있다.  우선 선택 가능한 옵션의 개수에 따라 두가지 상태를 가지는
    체크박스와 세가지상태를 가지는 체크 박스로 구분된다. 또한 동작 방법에 따라 자동 체크 박스와
    수동 체크 박스로 나누어지는데 수동 체크 박스는 선택/비선택 상태를 부모 윈도우가 직접 바꾸어야
    하며 자동 체크 박스는 스스로 체크 상태를 바꾼다.자동 체크 박스는 별도의 코드를 작성하지 않아도
    체크 상태를 자동으로 토글할 수 있는 장점이 있기는 하지만 체크 상태를 결정하기 위해 좀 더 복잡한
    조건을 점검하기에는 어울리지 않는다.
  나. 컨트롤의 메시지
    1) 체크 박스는 사용자가 마우스로 클릭할 때마다 부모 윈도우로 BN_CLICKED 메시지를 보낸다. 컨트롤이
      부모 윈도우로 보내는 통지 메시지와는 달리 부모 윈도우가 체크 박스의 상태를 알아보거나 상태를
      바꾸고자 할 때도 차일드 윈도우로 메시지를 보낸다. 통지 메시지는 차일드가 부모로 보내는 보고 메시지이고
      그냥 메시지는 부모가 차일드에게 어떤 지시를 내리기 위해 보내는 명령이다. 메시지의 종류는 컨트롤마다
      다르다.
      메시지              설명
      -----------------------------------
      BM_GETCHECK   체크 박스가 현재 체크되어 있는 상태를 조사하며 wParam, lParam은 사용하지 않는다.
                               체크 상태는 리턴값으로 돌려진다.
      BM_SETCHECK  체크 박스의 체크 상태를 변경하며 wParam에 변경할 체크 상태를 지정한다.

      BM_GETCHECK에 의해 리턴되는 값, BM_SETCHECK에 의해 설정되는 체크박스의 상태
      상수                             값          의미
      BM_UNCHECKED           0           현재 체크되어 있지 않다.
      BM_CHECKED               0           현재 체크되어 않다.
      BM_INDETERMINATE      0          체크도 아니고 안 체크도 아닌 상태
                            <------ BN_CLICKED : 클릭되었음 -------------
      부모 윈도우       ------ BM_GETCHECK : 체크 상태 질문 ------->     체크 박스
                             ------ BM_SETCHECK : 체크 상태 변경 ------->

4. 라디오 버튼
  가. BS_RADIOBUTTON, BS_AUTORADIOBUTTON 둘 중 하나의 스타일을 지정하면 라디오 버튼이 되며
    체크 박스와 마찬가지로 수동, 자동의 두가지 종류가 있으며 라디오 버튼이 체크 상태를 스스로 변경
    하는 그렇지 않은가의 차이가 있다. 수동 라디오 버튼이 필요한 상황은 사실상 거의 없으며 대개의
    경우는 자동 라디오 버튼으로 충분하다. 하나의 선택 사항에 대해 여러 개의 라디오 버튼들이
    그룹을 이루어 사용된다는 특징이 있다. 같은 그룹에 속한 라디오 버튼은 오직 하나만 선택 가능
  나. 라디오 버튼의 그룹을 구성하는 방법은 간단하다. 그룹을 이루는 첫 번째 라디오 버튼에만 WS_GROUP
    스타일을 주고 나머지 라디오 버튼은 WS_GROUP 스타일을 주지 않으면 된다. 최초로 WS_GROUP을 가지는
    라디오 버튼부터 다음 WS_GROUP 스타일을 가지는 라디오 버튼 직전까지가 한 그룹이 된다.

5. 에디트
  가. EDIT 윈도우 클래스로부터 생성하며 CREATEWINDOW 함수로 스타일 인수로 지정하면 된다.
    부모 윈도우는 이 메시지를 받았을 때 적절한 처리를 하면 된다.EN_CHANGE 문자열이 변경되었다.
     EN_KILLFOCUS, EN_SETFOCUS 포커스를 잃고 얻었을 때의 메시지가 있다.
  나. 컨트롤도 윈도우와 동격이다. 일단 화면상의 사각영역을 차지한다는 점에 있어서 윈도우와 같은데
    메인 윈도우의 차일드로 존재하며 타이틀 바가 없기 때문에 사용자가 직접 이동시킬 수 없을 뿐이다.
    또한 윈도우처럼 스타일을 가지며 만들 때 지정한 스타일에 따라 모양이나 기능이 달라진다.
    컨트롤이 윈도우라느 결정적인 증거는 스스로 메시지를 처리할 수 있는 능력을 가진다는 점이다.
    버틍을 마우스로 누르면 쑥 들어가는 모양으로 바뀌고 에디트는 키보드 입력을 받으면 문자열을 조립하여
    보여준다. eH한 WM_PAINT 메시지를 처리하기 때문에 스스로 자신을 복구(REPAIR)할 수 있고 부모윈도우가
    메시지를 보내면 그 메시지를 처리한다. 체크 박스는 BM_SETCHECK 메시지를 받으면 WPARAM값에 따라
    자신의 체크 상태를 스스로 변경한다.

6. 리스트 박스
  가. 리스트 박스는 선택 가능한 여러 개의 항목들을 나열해 놓고 그 중 하나(또는 여러개)를 선택하는 컨트롤
    이며 여기서 항목이란 주로 문자열이다. 리스트 박스도 일종의 윈도우이며 "listbox"라는 윈도우 클래스로
    생성한다. 차일드 컨트롤로 생성하는 것이 보통이므로 WS_CHILD|WS_VISIBLE 스타일은 기본적으로 지정
    해야 하며 이 외에 다음과 같은 여러 가지 고유의 스타일을 지정할 수 있다. 어떤 스타일을 지정하는가에
    따라 리스트박스와 모양과 동작이 달라진다.
    스타일                      설명
    LBS_MULIPLESEL    여러개의 항목을 선택 가능, 적용하지 않으면 디폴트로 하나의 선택만 가능
    LBS_NOTIFY             사용자가 목록중 하나를 선택했을 때 부모 윈도우로 통지 메시지를 보낸다.
    LBS_SORT                추가된 항목들을 자동 정렬한다.
    LBS_OWNERDRAW     문자열이 아닌 비트맵이나 그림을 넣을 수 있다..
    LBS_STANDARD        LBS_NOTIFY|LBS_SORT|WS_BORDER
  나. 부모 윈도우로 통지 메시지를 보내는 것이 일반적이르모 LBS_NOTIFY 스타일은 거의 필수적으로 선택
    하는 것이 좋으며 그 외는 필요할 때 선택하면 된다. 부모 윈도우가 리스트 박스를 조작하고자 할때는
    리스트 박스 메시지를 사용한다.
    메시지                      설명
    LB_ADDSTRING         리스트 박스에 항목을 추가 LPARAM으로 추가하고자 하는 문자열의 번지를 넘겨줌
    LB_DELETESTRING    항목을 삭제, WPARAM으로 항목의 번호를 넘겨주면 남은 항목수를 리턴
    LB_GETCURSEL        현재 선택된 항목의 번호를 조사
    LB_GETTEXT            지정한 항목의 문자열을 읽는다. WPARAM에 항목번호, LPARAM에 문자열
    LB_GETCOUNT         항목의 개수를 조사한다.
    LB_SETCURSEL        WPARAM이 지정한 항목을 선택한다
   다. 리스트 박스에서 어떤 사건이 발생했을 때 부모 윈도우로 다음과 같은 통지 메시지를 보낸다.
    메시지                      설명
    LBN_DBLCLK            리스트 박스를 더블 클릭하였다.
    LBN_ERRSPACE       메모리가 부족하다
    LBN_KILLFOCUS       키보드 포커스를 잃었다.
    LBN_SELCANCEL     사용자가 선택을 취소하였다
    LBN_SELCHANGE     사용자에 의해 선택이 변경되었다.
    LBN_SETFOCUS        키보드 포커스를 얻었다.
    자주 사용되는 통지 메시지는 선택이 변경될 때 보내지는 LBN_SELCHANGE이다

7. 콤보 박스
  가. 에디트컨트롤과 리스트 박스를 결합이다. 그래서 목록에 있는 항목중의 하나를 선택할 수도 있고 원하는
    항목이 없을 경우 에디트에 직접 입력해 넣을 수도 있다. combobox 윈도우 클래스를 사용하며 세 가지
    종류가 있는데 스타일로 원하는 종류를 선택
    스타일                        설명
    CBS_SIMPLE              에디트와 리스트 박스를 가지되 리스트 박스가 항상 펼쳐져 있다.
    CBS_DROPDOWN         에디트와 리스트 박스를 가진다.
    CBS_DROPDOWNLIST    리스트 박스만 가지며 에디트에 항목을 입력할 수는 없다.

8. 스크롤 바
  가. 비교적 복잡한 컨트롤로 윈도우의 스크롤 상태를 고나리하기 위해 사용하기도 하며 일정 범위에 있는 값을
    대충 선택할 때도 사용한다. scrollbar 위노우 클래스로 생성하며 수평 스크롤 바일경우 SBS_HORZ 스타일을
    수직 스크롤 일때는 SBS_VERT 스타일을 지정한다.
    BOOL SetScrollRange(HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw);
    (스크롤 바 윈도우 핸들, 표준 또는 별도 스크롤바를 지정하는 값, 최대값, 최소값, ?)
    int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw);
    (?, ?, 현재 위치, ?);
  나. 다른 컨트롤은 WM_COMMAND로 통지메시지를 보내는데 스크롤 바는 WM_HSCROLL, WM_VSCROLL
    이라는 별도의 메시지를 부모 윈도우로 보낸다.
    인수                              설명
    LOWORD(WPARAM)        스크롤 바 내의 어디를 눌렀는가?
    HIWORD(WPARAM)          현재 위치
    LPARAM                          스크롤 바의 윈도우 핸들
  다. LOWORD(WPARAM)으로 전달되는 값은 사용자의 스크로로 요구사항을 나타냄
    값                                                 설명
    SB_LINELEFT, SB_LINEUP               사용자가 왼쪽 화살표를 눌렀음
    SB_LINERIGHT, SB_LINEDOWN         사용자가 오른쪽 화살표를 눌렀음
    SB_PAGELEFT, SB_PAGEUP            사용자가 왼쪽 몸통을 눌렀음
    SB_PAGERIGHT, SB_PAGEDOWN      사용자가 오른쪽 몸통을 눌렀음
    SB_THUMBPOSITION                       스크롤 박스를 드래그한 후 마우스 버튼을 놓았다.
    SB_THUMBTRACK                           스크롤 박스를 드래그하고 있는 중 마우스버튼 놓을때까지 계속 전달

9. 스태틱
  가. 입력은 없고 오로지 문자열만 보여줌 WM_CREATE에서 스태틱 컨트롤을 만들기만 할 뿐 그외의 코드는
    작성할 필요가 없다. 스태틱 컨트롤은 실행중에 부모 윈도우로 통지 메시지를 보낼 필요가 없기 때문에 ID를
    -1로 지정하며 여러개의 스태틱 컨트롤이 있을 모든 경우도 -1의 같은 ID를 사용해도 된다. -1은 ID를 주지
    않는다는 뜻이며 더 이상 컨트롤을 프로그래밍할 필요가 없을 때 사용된다. 물론 필요하면 줄수도 있다.
  나. TextOut으로 출력한 문자열과는 달리 스태틱 컨트롤은 스스로 메시지를 처리할 수 있는 윈도우이기 때문에
    배치해 놓기만 하면 WM_PAINT와 같은 통지 메시지로 복구할 필요가 없다. 또한 색상, 글꼴 크기 등
    운영체제의 세팅이 바뀔 경우 이런 변화에 대해서도 스스로 대처한다는 장점이 있다.
AND