- 컨트롤이란 사용자와의 인터페이스를 이루는 도구이다.
- 사용자가 프로그램을 제어하는 수단이다.
- 하나의 윈도우이다.
파일 타입을 선택하는 콤보박스, 탭 크기를 입력하는 에디트, 옵션을 선택하는 체크 박스와 라디오 버튼 등의 컨트롤들이 배치되어 있다.
대화상자는 현재 설정된 옵션 상태를 컨트롤을 통해 사용자에게 보여주고 사용자는 컨트롤을 조작하여 옵션을 변경한다.
화면상의 일정한 영역을 차지하며 자신의 고유 메시지를 처리할 수 있는 능력을 가지고 있다.
표준컨트롤
윈도우 클래스 |
컨 트 롤 |
button |
버튼, 체크, 라디오 |
static |
텍스트 |
scrollbar |
스크롤 바 |
edit |
에디트 |
listbox |
라스트 박스 |
combobox |
콤보 박스 |
2. Button 주의할 점
winmain에서
LPCTSTR lpszClass = TEXT("MyButton");
으로 수정한다.
이 프로젝트의 경우 Button이라는 클래스명은 윈도우즈가 미리 사용하고 있기 때문에 예제명으로 쓸수 없다. 그래서 윈도우 클래스를 MyButton이라는 이름으로 정의 했다.
그리고 WM_PAINT에서
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
를 입력해야 실행결과를 바로 볼 수 있다. 그렇지 않으면 한참동안을 기다리게 된다. ㅋㅋ 스 타 일 설 명 BS_PUSHBUTTON 푸시 버튼 BS_DEFPUSHBUTTON 디폴트 푸시버튼 BS_CHECKBOX 체크 박스 BS_3STATE 3가지 상태를 가지는 체크 박스 BS_AUTOCHECKBOX 자동 체크 박스 BS_AUTO3STATE 3가지 상태를 가지는 자동 체크 박스 BS_RADIOBUTTON 라디오 버튼 BS_AUTORADIOBUTTON 자동 라디오 버튼 BS_GROUPBOX 그룹 박스
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
CreateWindow(TEXT("button"),TEXT("Click Me"),WS_CHILD|WS_VISIBLE|
BS_PUSHBUTTON,20,20,100,25,hWnd,(HMENU)0,g_hInst,NULL);
CreateWindow(TEXT("button"),TEXT("Me Two"),WS_CHILD|WS_VISIBLE|
BS_PUSHBUTTON,20,50,100,25,hWnd,(HMENU)1,g_hInst,NULL);
return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case 0:
MessageBox(hWnd,TEXT("First Button Clicked"),TEXT("Button"),MB_OK);
break;
case 1:
MessageBox(hWnd,TEXT("Second Button Clicked"),TEXT("Button"),MB_OK);
break;
}
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PostQuitMessage(0);
return 0;
}
3. 버튼 만들기
- 컨트롤은 윈도우이기는 하지만 홀로 사용될 수 없으며 반드시 부모 윈도우의 차일드로 존재해야 한다.
- 컨트롤도 하나의 윈도우이므로 CreateWindow 함수를 호출하여 만든다.
CreateWindow(TEXT("button"),TEXT("Click Me"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
20,20,100,25,hWnd,(HMENU)0,g_Inst,NULL);
CreateWindow(윈도우클래스명,사용자에게보이는문구,스타일,시작위치X,시작위치Y,폭,높이,부모윈도우,ID,핸들,NULL);
- button
: 만들고자 하는 윈도우의 윈도우 클래스이다. 컨트롤은 운영체제에 의해 윈도우 클래스가 미리 등록되어 있으므로 별도로 등록할 필요없이 이 인수에 만들고자 하는 컨트롤의 윈도우 클래스명을 적어주면 된다. 대소문자는 구분하지 않는다.
- Click Me
: 윈도우 타이틀 바에 나타날 윈도우의 제목이다. 한글도 물론 사용가능
- 스타일
: 윈도우의 속성 값이다. 컨트롤은 차일드 윈도우이므로 예외없이 WS_CHILD | WS_VISIBLE 스타일을 반드시 주어야 ShowWindow 함수를 호출하지 않아도 컨트롤이 화면에 나타난다. 그 외 컨트롤에 따른 고유한 스타일을 추가로 지정한다. 버튼의 스타일 값은 BS_로 시작한다.
- 위치
: 4번째부터 7번째까지는 윈도우의 위치와 크기를 지정한다.
- 부모 윈도우
: 자식 윈도우는 항상 부모의 위쪽에 나타나며 부모와 운명을 같이 하는데 부모가 최소화되거나 숨겨지면 자식도 같이 숨겨지며 부모가 파쾨되면 자식도 같이 파괴된다. 메인 윈도우를 생성할 때는 부모 윈도우를 NULL로 지정하는데 이는 부모가 없다는 뜻이 아니라 데스크탑을 부모로 한다는 뜻이다. WM_CREATE에서 생성되는 컨트롤으 부모는 통상 이 메시지를 처리하고 있는 부모인 hWnd가 된다
- ID
: 윈도우에서 사용할 메뉴의 핸들이다. 컨트롤의 ID는 컨트롤간의 구분을 위해 사용하는 것이므로 한 부모 아래의 컨트롤끼리 중복되지 않는 한 자유롭게 지정할 수 있다.
4. 부모와의 통신
버튼을 클릭할 경우 WM_COMMAND 메시지를 부모 윈도우에게 보낸다.
인 수 |
설 명 |
HIWORD(wParam) |
통지 메시지 |
LOWORD(wParam) |
컨트롤의 ID |
lParam |
윈도우의 핸들 |
wParam | |
통지메시지 HIWORD |
컨트롤 ID LOWORD |
lParam |
윈도우 핸들 |
|
ID |
핸들 |
버튼1 |
0 |
hB1 |
버튼2 |
1 |
hB2 |
버튼 컨트롤 -> 부모 윈도우
WM_COMMAND 발생
wParam | |
BN_CLICKED |
1 |
lParam |
hB1 |
통지메시지는 차일드 컨트롤이 왜 메시지를 보냈는가를 나타내는 값이다. 버튼의 경우 통지메시지는 항상 사용자가 자신을 클릭했다는 의미의 BN_CLICKED이다.
부모 윈도우는 WM_COMMAND에서 LOWORD(wParam)값을 조사하여 어떤 컨트롤이 눌러졌는지에 따라 적절한 처리를 한다.
WM_COMMAND 메시지는 컨트롤의 통지 메시지뿐만 아니라 메뉴 항목, 액셀러레이터 등의 명령을 처리하는 중요한 일을 한다. 컨트롤의 ID, 메뉴 ID, 액셀러레이터 ID등은 모두 LOWORD(wParam)으로 전달된다.
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;
.........
}
break;
}
return 0;
사용자로부터 명령을 많이 받아들이는 프로그램일수록 WM_COMMAND 메시지 처리는 더욱 복잡해진다. 버튼을 늘리려면 CreateWindow 함수를 추가한다.
예)프로그램 종료하기 버튼 추가
case WM_CREATE :
............
CreateWindow(TEXT("button"),TEXT("EXIT"),WS_CHILD|WS_VISIBLE|
BS_PUSHBUTTON,20,80,100,25,hWnd,(HMENU)2,g_hInst,NULL);
case WM_COMMAND :
............
case 2:
DestroyWindow(hWnd);
break;
WM_COMMAND에서 2번 버튼이 통지 메시지를 보냈을 때 DestroyWindow함수로 메인 윈도우를 파괴하여 프로그램을 종료한다.