프날 오토핫키 강좌  v2

⚠ 이 강좌는 오토핫키 v2를 다룹니다

지금 보시는 강좌는 과거 오랜 시간동안 알려진 오토핫키(v1.1)의 차세대 버전인 오토핫키 v2를 다루고 있습니다.
만약 구버전인 '오토핫키 v1.1'의 강좌를 찾으신다면 프날 오토핫키 강좌(https://pnal.kr)를 봐주시면 되지만, 새로 오토핫키를 배우신다면 v2 버전을 배우시는 것을 강력히 추천드립니다.

72. 컨트롤 생성하기


드디어 우리가 만든 창에 컨트롤을 추가해봅시다. 이번 강의 내용을 통해 아래와 같은 GUI 창을 실제로 똑같이 모방해볼 수 있습니다.

버튼, 입력 상자, 체크 박스와 라디오 버튼, 각기 다른 형태의 목록형 선택 상자와 슬라이더가 있는 프로그램의 모습 사진 1. 여러 컨트롤이 배치된 창의 모습

Gui 객체의 Add() 메서드

지난 강에서 Gui 객체의 여러 속성과 메서드를 배웠습니다. 그 중에서 Add() 메서드가 있었는데, 자세히 살펴보진 않았습니다. Add() 메서드는 창에 컨트롤을 추가하는 역할이기 때문에, 이번 강에서 자세히 살펴보기 위함입니다. 메서드의 원형은 아래와 같습니다.

Gui.Add(ControlType [, Options, Text])
Gui.Add() 메서드의 원형

ControlType에는 넣을 컨트롤의 종류를, Options에는 컨트롤의 옵션을, Text는 컨트롤에 적힐 글을 인수로 전달해주어야 합니다. 모두 문자열로 적어주면 됩니다.

1. ControlType

창에 넣을 컨트롤의 종류입니다. 컨트롤의 종류로는 아래 목록 중 하나를 선택하여 넣을 수 있습니다.

컨트롤명설명예시
Text단순한 글Text
Edit입력 상자
Button버튼
Picture사진초록 원 안에 흰색 p가 그려져있는 프날 로고
CheckBox체크 박스
Radio라디오 버튼
DropDownList드롭 다운 리스트
ListBox리스트
Slider슬라이더

모든 컨트롤을 적은 것은 아닙니다. 사용할 수 있는 모든 컨트롤 종류는 공식 문서의 GUI Control Types 페이지를 참고하시기 바랍니다

창에 넣기 원하는 컨트롤을 문자열 형태로 적어주면 끝입니다. 추가로, Picture 컨트롤은 Pic, DropDownList 컨트롤은 DDL로 줄여쓸 수 있습니다.

2. Options

Options 매개변수는 컨트롤의 성질과 위치 등을 설정할 수 있게 합니다. 따라서 여러 컨트롤을 정확한 위치에 배치하기 위해서는 반드시 적어주어야 합니다. 옵션 종류가 많기 때문에, 크게 ① 위치와 크기에 관한 옵션, ② 위치 및 크기와는 관련 없는 옵션으로 나누어서 살펴보겠습니다.

지금까지 그래왔던 것처럼 문자열로 적어주고, 여러 옵션을 적용할 경우 각 옵션 사이를 띄워줍니다. "x100 y100 Disabled"와 같이 말이죠.

위치와 크기에 관한 옵션

옵션설명
x컨트롤이 나타날 가로 위치(x좌표)를 설정. x좌표와 같이 사용.
y컨트롤이 나타날 세로 위치(y좌표)를 설정. y좌표와 같이 사용.
w컨트롤의 너비. w너비와 같이 사용.
h컨트롤의 높이. h높이와 같이 사용.
r컨트롤의 높이(항목의 개수를 기준으로). r항목개수와 같이 사용.

창 안에서 컨트롤을 배치하는 것이기 때문에 당연히 클라이언트 좌표를 사용합니다. 보통은 Window Spy를 사용하지 않고, 감으로(?) 숫자를 넣어보며 적용하여 그 결과를 맞추는 식으로 개발하게 됩니다. 위치에 x100을 넣어보고, 좀 왼쪽인 것 같으면 x120으로 수정해보고... 뭐 이런식이죠. 기존 컨트롤의 위치를 바탕삼아 좌표를 계산하면 쉽습니다.

높이와 너비는 대부분의 컨트롤에서 자동으로 설정되니, 필요한 경우에만 설정해줄 수 있습니다.

그리고, 사실 위치를 잡을 때 x100 y100과 같은 식으로 적지 않고도 x+10 y+10이나 xP와 같이 좀 고급(?)으로 적어주는 방법이 있습니다. 이는 이전 컨트롤의 위치 관계를 따져서 상대적인 위치로 설정해주는 것인데, 기초 강좌인 여기서는 다루지 않겠습니다.

위치 및 크기와는 관련 없는 옵션

옵션설명
c일부 컨트롤의 텍스트 색상을 설정. c0xRRGGBB와 같이 사용.
Disabled컨트롤을 비활성화 시킴 (사용자가 상호작용하지 못하게 회색 처리함)
VScroll길이가 긴 컨트롤의 스크롤 바 설정. -VScroll은 스크롤바를 없애고, +VSCroll은 생기게 함.

더많은 옵션이 있지만 기초 강좌에서 다루기 어려운 내용이 포함되어 있고, 또 잘 사용되지 않는 옵션도 있어서 생략을 많이 했습니다. 그러나 프로그램 개발을 많이 해볼수록 필요로 하는 옵션이 늘어날 것입니다. 그땐 오토핫키 공식 문서를 참고해주세요.

Tip: Edit 컨트롤의 옵션

Edit 컨트롤은 추가로 쓸 수 있는 옵션이 더 있습니다.

Edit 옵션설명
Limit글자 수 제한 (예: Limit10)
Lowercase소문자로만 입력되게 함
Uppercase대문자로만 입력되게 함
Number숫자만 입력되게 함 (붙여넣기를 방지할 순 없음)
Password입력값을 ●으로 가림 (Password*와 같이 써서 가리는 문자를 설정할수도 있음)
ReadOnly읽기 전용 모드 (수정은 불가능하나, 스크롤 및 복사는 됨)

자주 쓰는 옵션만 적어두었습니다. 참고로, Edit 컨트롤에 여러 줄을 입력하게 하고 싶으면 h 값을 늘려서 높이를 충분하게 만드세요.

3. Text

Options 매개변수에 이어서 Text 매개변수입니다. 컨트롤에 적히는 내용을 설정해줄 수 있습니다. 창의 구성에서 배웠죠? 컨트롤에 있는 '내용(Text)'이 있습니다. ControlSetText로 직접 내용을 바꿔보기도 했고요.

Text 컨트롤의 글씨, Button 컨트롤의 버튼 속 글씨, CheckBox 옆 글씨... 이들이 모두 내용입니다. 한마디로 눈에 보이는 모든 글씨를 설정해줄 수 있습니다.

...MyGui.Add("Text", "x100 y100", "Hello, world!")
"Hello, world!"라고 적힌 Text 컨트롤을 생성하는 구문

참고로, 항목을 담는 컨트롤인 DropDownList와 ListBox는 이 매개변수를 이용하여 기본적으로 담겨있는 항목을 설정할 수 있습니다. 다만 문자열을 이용하지 않고 항목 문자열이 담긴 배열을 이용합니다. (그래서 배열 강좌를 GUI 강좌보다 먼저 진행했습니다!)

예를 들어서, 아래와 같이 작성하면 기본적으로 [사과][바나나][토마토]가 들어가있는 상태로 DropDownList 컨트롤이 생성됩니다.

...MyGui.Add("DropDownList", "x100 y100", ["사과", "바나나", "토마토"])
사과, 바나나, 토마토가 입력되어있는 드롭 다운 리스트의 모습 사진 2. 생성된 DropDownList의 모습

너무 많은 정보가 한번에 들어왔죠? 실제로 Gui 창에 컨트롤을 배치해보면서 연습해 보겠습니다. 걱정하지 마시고, 천천히 따라와보시면 됩니다. 딱 한 번만 해봐도 확실히 이해가 되거든요.

Tip: Add() 메서드의 반환값

컨트롤을 Gui 객체에 추가하는 메서드인 Add()는 반환값이 있는 함수입니다.

Add()GuiControl 객체를 만들어서 반환하는데, 즉 컨트롤 또한 객체입니다. 당연히 각 컨트롤에도 속성과 메서드가 있겠죠. 일단 아래와 같이 Add() 함수의 결과를 변수에 담으면, 해당 변수는 GuiControl 객체(=컨트롤 객체)가 담긴 변수가 된다는 점만 이해하고 넘어가시면 됩니다. 때가 되면 그 사용법을 알아보겠습니다.

실습

1. 만들어진 창을 보고 컨트롤 분석해보기

일단 연습삼아 제가 만든 GUI 창을 분석해 보겠습니다.

클릭이라고 적혀 있는 버튼과 입력이라고 적혀있는 에디트 컨트롤, 된장찌개 김치찌개 기타 라는 세 가지 메뉴가 적힌 리스트 박스 컨트롤이 있는 창 사진 3. 여러 컨트롤이 배치된 창의 모습

빨간 선은 설명을 위한 보조선입니다. 각 컨트롤별로 분석을 해보죠.

분석 1: Button 컨트롤

클릭이라고 적힌 버튼이 전체 GUI를 기준으로 왼쪽 편에 있습니다. x좌표와 y좌표는 사진만 봐서 모르겠지만, 보조선 ①을 보아 x좌표와 y좌표의 값은 같아 보이네요. 대충 x30 y30과 같은 형태일 것입니다.

너비는 어느정돈지 모르겠는데, 일단 x30 y30으로 위치를 가늠했으므로 너비가 30보단 커보입니다. 약 80정도로 가정해 보겠습니다. 높이는 기본 높이같아 보이니 따로 적어주지 않겠습니다.

분석 2: Edit 컨트롤

입력이라고 적힌 입력 상자가 버튼의 아래에 있습니다. 당연히 y좌표는 버튼의 y좌표 + 버튼의 높이 + 버튼과 입력 상자 사이의 여백일 것입니다. 보조선 ②가 그 점을 짚고 있습니다.

버튼의 높이는 대략 20 정도로 보이므로(버튼의 기본 높이가 그 쯤 됩니다.) y좌표는 30 + 20 + 10(여백) 정도로 가늠할 수 있겠으나, 이런식으로 수치를 미리 생각하는 것은 별 도움이 되지 않습니다. 일단 버튼의 위치와 크기를 정확히 잡은 이후, 그 버튼을 기준으로 이 입력 상자의 y좌표를 계산해보는 것이 좋습니다.

그 외에 너비는 버튼과 같네요. 높이 또한 기본 높이 같습니다.

분석 3: DropDownList 컨트롤

된장찌개, 김치찌개, 기타라는 목록이 있는 DropDownList 컨트롤이 버튼과 입력 상자의 오른쪽에 있습니다. 당연히 x좌표는 버튼의 x좌표 + 버튼의 너비 + 버튼과 리스트 사이의 여백보다 큽니다. 보조선 ③을 보니 버튼과 y좌표가 같아 보입니다. 너비도 버튼과 비슷한 것 같고요.

2. 창 모방해서 만들어보기

이제 위에서 분석한 내용을 토대로 창을 만들어 보겠습니다. 쉽게 보기 위해 위의 사진을 다시 한 번 가져와 보겠습니다.

클릭이라고 적혀 있는 버튼과 입력이라고 적혀있는 에디트 컨트롤, 된장찌개 김치찌개 기타 라는 세 가지 메뉴가 적힌 리스트 박스 컨트롤이 있는 창 사진 4. 우리가 최종적으로 만들 목표! (사진 10과 같음)

먼저 아무것도 없는 빈 GUI 창을 만들어야겠죠. 사진 11을 보니 제목(Title)은 72강 연습 입니다. 크기와 너비는 아직 모르니까 넉넉하게 400x300으로 작성해 보겠습니다.

1Main := Gui(, "72강 연습")
2Main.Show("w400 h300")
제목을 가진 Gui 객체를 만든 후, 이를 400x300 크기로 표시함

Gui 객체의 변수명을 Main으로 설정했습니다. 변수명은 유의미하게 지어주는 것이 좋기 때문에, 만약 이 창이 프로그램의 메인 화면일 경우 Main은 적절한 이름입니다.

이제 버튼을 추가해 보겠습니다. 보통은 왼쪽 위에 있는 컨트롤부터 배치해야 그 이후 컨트롤을 배치하기도 쉽고, 관리하기도 편합니다. 대충 x30 y30에 너비가 100정도 되는 버튼을 만들어 보겠습니다.

1Main := Gui(, "72강 연습")
2Main.Add("Button", "x30 y30 w100", "클릭")
3Main.Show("w400 h300")
버튼 추가 (2번 줄)

위와 같이 컨트롤은 Gui.Show()를 하기 전에 추가해주는 것이 좋은 습관이자 관례입니다. 이제 만들어진 창을 살펴볼까요?

클릭이라고 적혀 있는 버튼이 있는 창 클릭이라고 적혀 있는 버튼이 있는 창
사진 5~6. 버튼이 배치된 모습(좌)과 수정한 모습(우)

왼쪽 사진을 보면 생각보다 버튼의 너비가 크고, 위치도 묘하게 붕 뜬 것 같습니다. 위치를 조금 더 구석으로 넣기 위해 x30 y30x20 y20으로 하고, 너비도 w70으로 수정해 보니 사진 13과 같이 원하는 모양대로 수정되었습니다. 이런 식으로 GUI 창을 생성할 땐 여러 시도가 있어야 합니다.

1Main := Gui(, "72강 연습")
2Main.Add("Button", "x20 y20 w70", "클릭")
3Main.Add("Edit", "x20 y50 w70", "입력")
4Main.Show("w400 h300")
입력 상자 추가 (3번 줄)

이제 위와 같이 적어주어 Edit 컨트롤을 추가해 주었습니다. 버튼과 x좌표 및 너비가 같으므로 x20 w70을 적용해주었고, y좌표는 버튼의 y좌표와 높이, 여백을 고려하여 y50을 적용했습니다. 위치가 이상하면 수정하면 되니까 대충 적어보자고요.

클릭이라고 적혀 있는 버튼과 Edit 컨트롤이 추가된 창 사진 7. Edit 컨트롤이 추가된 창

적절한 위치와 크기인 것 같습니다. 버튼과 입력 상자 사이의 여백은 약 10px 정도가 되었네요. 느끼셨겠지만, 처음 버튼의 위치만 잘 정했다면 그 다음 컨트롤은 이를 기준으로 쉽게 위치를 가늠할 수 있습니다.

마지막으로 DropDownList를 배치해 보겠습니다. 아래 코드를 보기 전에, 스스로 한 번 배치해 보세요.

1Main := Gui(, "72강 연습")
2Main.Add("Button", "x20 y20 w70", "클릭")
4Main.Add("DropDownList", "x100 y20 w70 h50", ["된장찌개", "김치찌개", "기타"])
3Main.Add("Edit", "x20 y100 w70", "입력")
5Main.Show("w400 h300")
드롭 다운 리스트 추가 (4번 줄)

버튼과 y좌표와 너비가 같으므로 y20 w70을 적용했고, x좌표는 버튼의 너비와 여백을 고려하여 x100으로 설정했습니다. DDL의 경우 높이는 리스트 안의 내용에 맞게 자동 조정되므로, 따로 설정하지 않았습니다.

참고로 각 컨트롤마다 기본 높이가 묘하게 다릅니다. 정확히 찾아보진 않았고 개인적인 감상으로는 Edit는 Button보다 1px 정도 두꺼워 보입니다. 저는 Button의 기본 높이는 20px이고 Edit의 기본 높이는 19px로 가정하고 개발하곤 합니다. 본 강좌에서는 이러한 점을 고려하지 않았으므로, 두 컨트롤 모두 기본 높이를 20px로 가정합니다.

클릭이라고 적혀 있는 버튼과 입력이라고 적혀있는 에디트 컨트롤, 된장찌개 김치찌개 기타 라는 세 가지 메뉴가 적힌 리스트 박스 컨트롤이 있는 창 사진 8. 최종적으로 만들어진 화면

이제 위와 같이 창의 크기를 컨트롤에 맞게 줄이면 됩니다. 참고로 창의 너비와 높이를 설정하지 않아도 자동으로 설정되는 경우가 많지만, 원하는 크기와 높이가 나오지 않아서 수동으로 설정해주는 경우가 꽤 있습니다.

마지막으로, 여백과 크기를 재정비 해줍니다.

클릭이라고 적혀 있는 버튼과 입력이라고 적혀있는 에디트 컨트롤, 된장찌개 김치찌개 기타 라는 세 가지 메뉴가 적힌 드롭다운리스트 컨트롤이 있는 창 사진 9. Button과 Edit 사이의 여백 재설정

이제 원하는 GUI를 약간은 만들 수 있습니다!

질문하러 가기