일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Desktop
- c
- 함수
- Win32
- 티스토리
- Javascript
- 알고리즘
- 배열
- Tips강좌
- VS ERROR
- 연산자
- CS
- 김성엽
- 백준
- c#
- c++
- Windows
- Direct2D
- doit코틀린프로그래밍
- 문법
- 이지스퍼블리싱
- tipssoft
- 프로그래밍
- Programming
- 지식나눔강좌
- Kotlin
- 포인터
- Tips프로그래밍강좌
- Visual Studio
- 리뷰
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
Win32 프로그램 생성하기 1 본문
Win32 프로그래밍을 진행합니다.
⁕ 참고
본 문서는 Win32를 마스터하지 않은 상태로 '나'에게 맞추어 작성되었으므로 용어나 설명에 있어 난해한 부분이 일부 존재할 수 있습니다. 수정이 필요한 부분, 혹은 함께 글을 읽으면서 이해하기 어렵거나 부연 설명이 필요한 부분이 있다면 댓글로 달아주시기 바랍니다.
엔트리 포인트
우리가 C/C++ 콘솔 프로그램[# 이하 콘솔 프로그램]을 작성할 때 가장 먼저 작성하는 함수는 main이었습니다. 콘솔 프로그램은 여러 복잡한 UI 요소가 존재하지 않고, 텍스트로 이용자와 소통합니다. 그리고 대개 동시 처리를 하지 않고 순차적으로 일을 처리하는 절차 지향을 따르고 있습니다. 따라서 main 하나만 있으면 어떤 프로그램이던 일단 실행은 합니다.
Win32, 지금은 Windows Desktop이라는 이름으로 붙여진 프로그래밍은 GUI 기반 프로그래밍을 할 때 유용(?)하다고 할 수 있습니다. Win32 프로그래밍의 엔트리 포인트는 콘솔 프로그램과 다릅니다. 사용하는 텍스트 인코딩에 다르지만 WinMain, wWinMain이 엔트리 포인트입니다. 콘솔 프로그램의 main과 대응하는 프로그램이죠. 이 둘의 차이 중 가장 큰 것은 시작할 때 콘솔 창이 나오느냐[# stackoverflow.com/questions/18709403/winmain-vs-main-c]입니다.
함수 원형
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
Win32 프로그램의 엔트리 포인트는 위와 같은 모양을 하고 있습니다. 콘솔 프로그램에서는 괄호 안에 아무것도 적지 않거나 void, 혹은 그 외의 가변인자[# int argc, char* argv]와 같이 인자의 모양을 선택할 수 있었습니다. 그러나 Win32 프로그램은 기본적으로 OS에 종속적이다보니 위 형식을 꼭 맞춰주어야 합니다.
이제 네 가지 인자를 살펴보겠습니다.
hInstance
HINSTANCE 자료형으로 정의된 hInstance 인자는 OS에서 프로세스를 관리하기 위해 만든 고유한 ID 값을 가지고 있다고 생각하면 됩니다. 함수 원형에서 보여드린 네 개의 인자 중에 가장 많이 사용하는 인자라고 생각하면 됩니다.
hPrevInstance
이 값은 무조건 0, NULL이 들어갑니다. 예전, 구석기 시대쯤에 사용하던 인자인데 간단히 설명하면 같은 프로그램 중에 바로 전 실행된 인스턴스값[# 위에 설명한 hInstance라 생각하면 됩니다.]을 가져옵니다. 이 말이 무어냐 하면, 우리가 크롬을 실행시킨다고 또 실행을 못하는 것은 아니잖아요? A 프로그램을 실행하고 - B 프로그램을 실행하고 - 다시 A 프로그램을 실행하면 현재 A 프로그램 두 개가 열려 있습니다. 이후에 실행된 A 프로그램의 hPrevInstance에 이전에 실행된 hInstance가 들어 있다고 생각하면 됩니다. 보안 문제로 이용되지 않고, 이전에 개발된 프로그램과 호환성을 위해 남겨져 있습니다.
lpCmdLine
프로그램을 시작할 때, 명령줄로 들어오는 값이 들어 있습니다. 콘솔 프로그램에서 아래의 인자 중 argv에 들어가는 내용이 들어가는 것이라고 보면 됩니다.
int main(int argc, char* argv)
nCmdShow
GUI 프로그램은 실행시키면 창이 나타납니다. 창이 열릴 때, 최대화로 창이 열리기도, 최소화로 창이 열리기도 합니다. 프로그램이 열릴 때, 창이 어떤 방식으로 열릴 것인지를 이 값으로 사용합니다.
윈도우 프로시저
우리가 많이 사용하는 프로그램들은 GUI 기반으로 이루어져 있습니다. GUI에서 맨 위[# 왼쪽 상단]부터 요소를 생성하더라도 순서대로 실행되지 않습니다.
따라서 프로그램은 사용자가 어떤 기능을 실행시키던 그에 맞게 대응해야 합니다. 마치 마트에서 캐셔[# 계산원]가 고객들이 선택한 물건을 계산해주기 위해 항시 대기하고 있는 것처럼 프로그램도 사용자 입력에 반응하려면 항시 대기하고 있어야합니다.
그래서 나온 것이 윈도우 프로시저입니다. 일반적으로 프로그램이 입력에 반응하려면 항시 입력을 하는지 체크를 하고 있어야 합니다. 그러나 입력 체크를 위해 항시 작업하면, 입력을 할 수가 없습니다.
입력을 하기 전에 입력을 했는지 파악하기 위해 프로그램이 계속 돌고 있기 때문이죠. 즉, 입력을 체크하기 위해 입력을 하지 못하는 순환논리에 빠지게 되는 것입니다. 그래서 Windows에서는 입력을 확인하는 작업을 프로그램이 아니라 OS에 넘겨버렸습니다.
정확하지는 않더라도 기본 구조라 생각하면 되겠습니다. 입력과 반응은 프로그램이 맡고, 입력이 있는지는 OS가 확인합니다. 프로그램에 입력이 있으면 OS에서 그에 걸맞은 행동을 하도록 프로그램에 유도하는 것이죠.
이런 식으로 OS가 사용자 입력에 반응해 프로그램이 올바른 행동을 할 수 있도록 하는 장치라고 생각하면 되겠습니다. 일반적으로 윈도우 프로시저는 WndProc, 혹은 WindowProc라고 이름 붙입니다.
# Windows와 Window는 다른 명칭입니다.
간혹, Windows와 Window를 혼용할 수 있습니다. 그러나 Windows 운영체제에서 Windows와 Window는 서로 의미하는 바가 다릅니다. Windows는 운영체제 제품군의 이름이고, Window는 일반적으로 프로그램을 열 때 나오는 창의 개념으로 이해하면 쉽습니다. 뒤의 s 유무에 따라 의미하는 바가 전혀 다르니 참고하세요.
글을 작성하다 보면, Windows와 Window를 혼용할 우려가 있습니다. 따라서 운영체제를 설명할 때는 Windows로, 프로그램의 창을 의미할 때는 윈도우라 칭하겠습니다. 다른 포스트에서는 모르겠지만, 정확한 설명을 위해 이 시리즈에서만큼은 설명한 것처럼 용어를 표현합니다.
추가로 Win과 Wnd도 그와 비슷한 맥락입니다. Win은 운영체제 Windows의 약자이고, Wnd는 윈도우(Window)에서 따온 약자입니다.
윈도우 프로시저의 함수 원형은 아래와 같습니다.
함수 원형
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
윈도우 프로시저는 Win32 프로그래밍을 처음 시작하는 분이라면 함수 이름 빼고는 굉장히 낯설 것이라 생각합니다. 그래서 하나하나 살펴보겠습니다.
LRESULT
함수의 반환형입니다. 이 값은 윈도우 프로시저에서 관리하는 메시지에 따라 달라집니다. 때문에 각 메시지를 참조하는 문서를 보면 반환 값이 포함되어 있습니다. 각 메시지의 내용은 MSDN에서 찾아볼 수 있습니다. 대개 사용을 잘 하지 않습니다.
CALLBACK
함수 호출 규약입니다. ALT + F12를 이용하면 CALLBACK이 정의된 위치로 이동할 수 있습니다. __stdcall이라 작성되어 있을텐데, Win32에서 사용하는 기본 호출 규약입니다. C/C++ 기본 호출 규약과 다릅니다.
HWND hWnd
윈도우 프로시저는 UI, 혹은 해당 메시지가 어디에서 보내진 것인지를 확인하는 값입니다. 각종 버튼, 윈도우 핸들과 같은 정보가 들어 있습니다.
UINT uMsg
이벤트에 따라 지정된 메시지의 식별값입니다.
WPARAM wParam
LPARAM lParam
메시지에 따라 들어오는 값이 다릅니다. 두 인자에는 메시지의 부가 정보가 들어갑니다. 예를 들어 왼쪽 마우스 클릭을 의미하는 WM_LBUTTONDOWN은 wParam에 아래의 값이 들어갑니다.
상수 | 값 | 의미 |
MK_CONTROL | 0x0008 | CTRL 키 눌림 |
MK_LBUTTON | 0x0001 | 왼쪽 마우스 눌림 |
MK_SHIFT | 0x0004 | SHIFT 키 눌림 |
# MS DOCS : WM_LBUTTONDOWN
# MS DOCS : WM_LBUTTONDOWN
lParam에는 마우스 클릭을 한 좌표가 들어 있습니다.
윈도우 프로시저 인자의 경우, WinMain의 인자와 달리 모두 중요한 인자이니 꼭 어떤 값이 들어간다를 알고 계셔야합니다. 물론, 이벤트만 알고 있으면 MS DOCS에서 찾아서 보셔도 좋습니다.
# index
'DEV > C C++' 카테고리의 다른 글
Win32 프로그램 생성하기 3 (0) | 2021.04.02 |
---|---|
Win32 프로그램 생성하기 2 (0) | 2021.04.01 |
Visual Studio 2019에서 프로젝트 만들기 (0) | 2020.09.07 |
C: 반복문 (0) | 2020.09.07 |
C: volatile 키워드 (0) | 2020.08.22 |