본문 바로가기

공부/윈도우api

[윈도우api] 컨트롤

반응형

컨트롤의 정의

사용자와의 인터페이스를 이루는 도구, 사용자로부터 명령과 입력을 받아들이고 출력 결과를 보여줌

컨트롤도 하나의 윈도우

윈도우즈가 윈도우 클래스들을 시스템 부팅시에 운영체제에 의해 등록됨, 윈도우 클래스를 등록할 필요없이 미리 등록되어 있는 윈도우 클래스를 사용

 

윈도우 클래스 컨트롤
button 버튼, 체크, 라디오
static 텍스트
scrollbar 스크롤 바
edit 에디트
listbox 리스트 박스
combobox 콤보 박스

 

컨트롤의 3요소

1. 스타일

2. 통지 메세지

3. 부모 윈도우가 보내는 메세지

 

버튼

버튼 만들기

컨트롤은 윈도우이기는 하지만 반드시 부모 윈도우의 차일드로 존재해야 함

차일드 컨트롤은 보통 부모 윈도우가 만들어질 때, WM_CREATE메세지가 발생했을 때 만듦

 

CreateWindow(TEXT("button"), TEXT("Click Me"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20,

20, 100, 25, hWnd, (HMENU)9, g_hInst, NULL);

1번째 인수 : 만들고자 하는 윈도우의 윈도우 클래스

2번째 인수 : 윈도우의 타이틀 발에 나타날 윈도우의 제목, 캡션이 필요없고 내용만 있는 컨트롤은

                   NULL로 지정

3번째 인수 : 윈도우의 속성값, 컨트롤은 차일드 윈도우이므로 WS_CHILD스타일을 주어야 함,

                   WS_VISIBLE스타일을 주어야 ShowWindow함수를 호출하지 않아도 됨

                   컨트롤에 따른 고유한 스타일을 추가

4~7번째 인수 : 윈도우의 위치와 크기 지정, 부모 윈도우의 작업영역을 기준으로 한 좌표,

                       좌상단에서의 폭과 높이를 의미

8번째 인수 : 컨트롤의 부모 윈도우 지정

                   부모 윈도우의 작업영역을 기준으로 한 좌표를 생성

                   부모 윈도우에게 통지 메세지를 보내고 부모 윈도우가 파괴될 때 파괴, 부모 윈도우가

                   숨겨지면 자식도 같이 숨겨짐

                   메인윈도우 생성할 때는 부모 윈도우를 NULL로 지정,

                   이는 테스크탑을 부모로 한다는 뜻

9번째 인수 : 윈도우에서 사용할 메뉴의 핸들이지만 차일드 컨트롤은 메뉴를 가지지 않아 컨트롤 ID

                   (컨트롤간의 구분)지정 용도라 사용

                  사용되는 컨트롤이 많다면 #define으로 매크로 상수를 사용할 것

10번째 인수 : 이 윈도우를 만드는 인스턴스의 핸들

11번째 인수 : 사용자 정의 데이터이며 MDI에서 사용하는 구조체인데 일단 무시하고 NULL지정

반환 값 : 생성된 차일드 컨트롤의 윈도우 핸들을 리턴

 

부모와의 통신

부모 윈도우로 통지메세지(notification Message)를 보내 어떤 사건이 발생했는지 알린다

부모 윈도우는 차일드 컨트롤이 보내는 통지메세지를 받아 적절한 처리를 해야 함

버튼을 클릭할 경우 WM_COMMAND메세지를 부모 윈도우에게 보내며 이때 전달되는 정보는 다음과 같음

인수 설명
HIWORD(wParam) 통지코드
LOWORD(wParam) 컨트롤의 ID
lParam 메시지를 보낸 차일드 윈도우의 윈도우 핸들

 

WM_COMMAND메세지는 컨트롤의 통지 메세지뿐만 아니라 메뉴 항목, 액셀러레이터 등의 명령을 처리하는 중요한 일, 사용자로부터의 명령이 될 만한 것들을 모두 처리

WM_COMMAND메세지는 통지 코드별로 처리를 달리해야 함

 

체크박스

체크 박스의 종류

푸쉬 버튼은 사용자로부터 명령을 받아들이기 위해 사용

체크 박스는 참, 거짓의 진위적인 선택을 입력받을 때 주로 사용

"button"클래스를 사용

스타일에 따라 4가지 종류의 체크 박스가 있음

선택 가능한 옵션의 개수에 따라 두 가지 상태를 가지는 체크 박스(BS_CHECKBOX)와 세가지 상태를 가지는 체크 박스(BS_3STATE)로 구분

동작 방법에 따라 자동 체크 박스와 수동 체크 박스로 나누어짐

수동체크 박스는 선택/비선택 상태를 부모 윈도우가 직접 바꾸어야 하며 자동 체크 박스는 스스로 체크 상태를 바꿈

체크 박스의 상태가 변경될 때마다 어떤 처리를 해야하고 체크 조건이 복잡한 경우라면 수동 체크 박스를 사용하고 필요할 때 상태를 조사하기만 하면 될 경우 체크 박스를 이용

 

컨트롤의 메시지

통지 메세지는 차이드가 부모로 보내는 보고 메세지이고 그냥 메세지는 부모가 차일드에게 어떤 지시를 내리기 위해 보내는 명령 (예)SendMessage(c1,BM_GETCHECK,0,0) <- 그냥메세지

메세지의 종류는 컨트롤마다 다름

부모 윈도우가 체크메세지에는 다음 두가지가 있음

메시지 설명
BM_GETCHECK 체크 박스가 현재 체크되어 있는 상태인지를 조사하며 추가정보는 없다.
BM_SETCHECK 체크 박스의 체크 상태를 변경하며 wParam에 변경할 체크 상태를 보내주면 된다.

BM_GETCHECK에 의해 리턴 되는 값, 또는 BM_SETCHECK에 의해 설정되는 체크 박스의 상태는 다음 3가지가 있음

상수 의미
BST_CHECKED 현재 체크되어 있다.
BST_UNCHECKED 현재 체크되어 있지 않다.
BST_INDETERMINATE 체크도 아니고 안체크도 아닌 상태

 

라디오버튼

"button"클래스에 BS_RADIOBUTTON, BS_AUTORADIOBUTTON 둘 중 하나의 스타일을 지정

수동, 자동의 두 가지 종류가 있음

여러 가지 선택 사항중 한 가지만 선택할 필요가 있을 때 사용

하나의 선택 사항에 대해 여러 개의 라디오 버튼들이 그룹을 이루어 사용된다는 특징

같은 그룹에 속한 라디오 버튼은 오직 하나만 선택할 수 있음

최초로 WS_GROUP을 가지는 라디오 버튼부터 다음 WS_GROUP스타일을 가지는 라디오 버튼 직전까지가 한 그룹

그룹 박스는 BS_GROUPBOX스타일로 단순한 눈에 보이기 위한 장식

 

버튼의 ID가 많을 때는 #define, 열거형(첫 열거 상수에만 시작값을 지정하면 나머지는 알아서 1씩 증가하는 값을 가지므로 편집할 때 더 편리)을 이용함

 

BOOL CheckRadioButton(HWND hDlg, int nlDFirst, int nlDLast, int nlDCheck);

처음 선택될 라디오 버튼을 지정

첫번째 인수 : 라디오 버튼을 가지는 부모 윈도우의 핸들

두번째 인수 : 그룹의 시작버튼

세번째 인수 : 그룹의 끝버튼

네번째 인수 : 선택될 버튼의 ID

 

에디트

에디트

가로로 길쭉하게 생겼으며 여기에 문자열 또는 정수를 입력

"edit"윈도우 클래스로부터 생성하며 다음과 같은 스타일 사용가능

스타일 설명
ES_AUTOHSCROLL 수평 스크롤을 지원한다.
ES_AUTOVSCROLL 여러줄 편집시 수직 스크롤을 지원한다.
ES_LEFT 왼쪽 정렬한다.
ES_CENTER 중앙 정렬한다.
ES_RIGHT 오른쪽 정렬한다.
ES_LOWERCASE 소문자로 변환하여 표시한다.
ES_UPPERCASE 대문자로 변환하여 표시한다.
ES_MULTILINE 여러줄을 편집할 수 있도록 한다.
ES_NOHIDESEL 포커스를 잃더라도 선택된 영역을 표시한다.
ES_READONLY 읽기전용으로 만들어 편집을 금지한다.

 

EN_UPDATE는 문자열이 변경된 후 화면에 출력하기 직전에 보내는 메세지

EN_CHANGE는 문자열이 화면으로 출력되고 난 후 보내지는 메세지

 

컨트롤도 윈도우다

컨트롤 = 윈도우

윈도우처럼 스타일을 가지며 지정한 스타일에 따라 모양이나 기능이 달라짐

스스로 메세지를 처리할 수 있는 능력을 가진다

버튼은 마우스로 누르면 쑥 들어가는 모양으로 바뀌고 에디트는 키보 입력을 받으면 문자열을 조립하여 보여줌 또한, WM_PAINT메세지를 처리하기 때문에 스스로 자신을 복구할 수 있고 부모 윈도우가 메세지를 보내면 그 메세지를 처리

 

리스트박스

리스트박스

"listbox"윈도우 클래스

 

스타일

스타일 설명
LBS_MULTIPLESEL 여러개의 항목을 선택할 수 있도록 한다. 이 스타일을 적용하지 않으면 디폴트로 하나만 선택할 수 있다.
LBS_NOTIFY 사용자가 목록중 하나를 선택했을 때 부모 윈도우로 통지 메시지를 보내도록 한다.
LBS_SORT 추가된 항목들을 자동 정렬하도록 한다.
LBS_OWNERDRAW 문자열이 아닌 비트맵이나 그림을 넣을 수 있도록 한다.
LBS_STANDARD LBS_NOTIFY | LBS_SORT | WS_BORDER

 

부모 윈도우가 리스트 박스를 조작하고자 할 때는 리스트 박스 메세지를 사용한다

메시지 설명
LB_ADDSTRING 리스트 박스에 항목을 추가한다. lParam으로 추가하고자 하는 문자열의 번지를 넘겨주면 된다.
LB_DELETESTRING 항목을 삭제한다. wParam으로 항목의 번호를 넘겨주며 남은 문자열수를 리턴한다.
LB_GETCURSEL 현재 선택된 항목의 번호(Index)를 조사해준다.
LB_GETTEXT 지정한 항목의 문자열을 읽는다. wParam에 항목 번호, lParam에 문자열 버퍼의 번지를 넘겨주면 버퍼에 문자열을 채워준다.
LB_GETCOUNT 항목의 개수를 조사한다.
LB_SETCURSEL wParam이 지정한 항목을 선택하도록 한다.

 

리스트박스에서 어떤 사건이 발생했을 때 부모 윈도우로 다음과 같은 통지 메세지를 보냄

메시지 설명
LBN_DBLCLK 리스트 박스를 더블클릭하였다.
LBN_ERRSPACE 메모리가 부족하다.
LBN_KILLFOCUS 키보드 포커스를 잃었다.
LBN_SELCANCEL 사용자가 선택을 취소하였다.
LBN_SELCHANGE 사용자에 의해 선택이 변경되었다.
LBN_SETFOCUS 키보드 포커스를 얻었다.

 

콤보박스

"combobox"윈도우 클래스를 사용, 세 가지 종류의 스타일있음

스타일 설명
CBS_SIMPLE 에디트만 가진다.
CBS_DROPDOWN 에디트와 리스트 박스를 가진다.
CBS_DROPDOWNLIST 리스트 박스만 가지며 에디트에 항목을 입력할 수는 없다.

 

부모윈도우 -> 콤보박스로 메세지 전달

콤보박스 -> 부모윈도우로 전달

= 리스트박스 + 에디트의 메세지

 

스트롤 바

스트롤 바

"scrollbar"윈도우 클래스 사용, 수평 스크롤바(SBS_HORZ)와 수직스크롤바(SBS_VERT)스타일 존재

 

BOOL SetScrollRange(HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw);

스크롤바의 범위 지정

1번째 인수 : 스크롤바의 윈도우 핸들

2번째 인수 : 별도의 스크롤바 컨트롤 지정(SB_CTL), 메인 윈도우에 부착된 표준 스크롤바 지정

3번째 인수 : 최대 값 지정

4번째 인수 : 최소 값 지정

 

int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw);

스크롤바의 현재 위치값 지정

1번째 인수 : 스크롤바의 윈도우 핸들

2번째 인수 : 별도의 스크롤바 컨트롤 지정(SB_CTL), 메인 윈도우에 부착된 표준 스크롤바 지정

3번째 인수 : 스크롤바의 현재 위치

 

스크롤바 -> 부모윈도우로 통지메세지

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 스크롤 박스를 드래그하고 있는 중이다. 이 메시지는 마우스 버튼을 놓을 때까지 계속 전달된다.

 

양끝의 버튼을 누르는 것은 비교적 작은 단위(예를 들어 한 줄씩)로 섬세하게 이동

몸통 부분을 누르는 것은 비교적 큰 단위(예를 들어 한 페이지씩)로 이동

 

스태틱

"static"윈도우 클래스 사용

오로지 문자열을 보여주는 기능이 전부

주로 에디트나 다른 컨트롤 옆에 위치하며 컨트롤의 용도를 설명하는 역할

ID를 -1로 지정

ID -1은 ID를 주지 않는다는 뜻이며 더 이상 이 컨트롤을 프로그래밍할 필요가 없을 때 사용

반응형