zj3t

email: euntaejang@gmail.com

Latest Posts

WindowsAPI-첫 번째 예제

By 오후 5:26

윈도우즈 API 완전정복1 - 예제가 있어서 포스팅 해보겠습니다.

<윈도우를 만드는 과정>

WndClass 정의
|
RegisterClass: 윈도우 클래스를 등록
|
CreateWindow :메모리 상에 윈도우를 만듬
|
ShowWindow: 화면에 표시
|  
메시지루프


#include <Windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdPram, int nCmdShow)
{
HWND hWnd;
MSG Message;
 WNDCLASS WndClass;
g_hInst=hInstance;

WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);

hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);

while(GetMessage(&Message,NULL,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage, WPARAM wParam, LPARAM IParam)
{
switch(iMessage){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,IParam));
}

<분석>

-시작점

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdPram, int nCmdShow)

-모든 윈도우즈 프로그램의 시작점은 WinMain 이다.
-APIENTRY 지정나는 윈도우즈 표준 호출 규약인 _stdcall을 사용한다는 뜻이다.

인수                          의미
------------------------------------------------------------------------------------------
hInstance                      프로그램의 인스턴스 핸들이다.

hPrevInstance                16비트와의 호환성을 위한 것이므로 신경X

lpszCmdParam               명령행으로 입력된 프로그램 인수이다.

nCmdShow                    프로그램이 실행될 형태이며 최소화, 보통 모양등이 전달



이중 hInstance 이외에는 잘 사용되지 않는다. 인스턴스(Instance)라는 말은 실행중인 프로그램 하나를 칭하는 용어이다. 윈도우즈는 여러 개의 프로그램이 동시에 실행되는 멀티 태스킹 시스템일 뿐만 아니라 하나의 프로그램이 여러 번 실행될 수도 있다. 이때 실행되고 있는 각각의 프로그램을 프로그램 인스턴스라고 하며 간단히 줄여서 인스턴스라고 한다.

예를 들어 Notepad.exe를 두개 실행시키면 같은 Notepad.exe이지만 OS는 각각 다른 메모리를 사용하는 다른 프로그램으로 인식한다. 각 메모장은 서로 다른 인스턴스 핸들을 가지며 OS는 이 인스턴스 핸들값으로 두 개의 메모장을 서로 구별한다.
즉 hInstance란 프로그램 자체를 일컫는 정수값이며 프로그램 내부에서 자기 자신을 가리키는 1인칭 대명사이다.

많은 API 함수들이 hInstance값을 인수로 요구하는데 그래서 이 예제에서는 WinMain의 인수로 전달된 hInstance값을 전역변수 g_hInst에 대입해 두었다(위의 빨간색 표시). hInstance 인수는 기억 부류가 지역변수이기 때문에 WinMain 밖에서는 사용할 수 없기 때문이다. 이 예제에서는 g_hInst 값을 당장 사용하지 않지만, 앞으로의 예제에서는 이 값을 수시로 사용하게 될 것이다. g_hInst외에 lpszClass라는 전역 문자열이 정의되어 있는데, 이 문자열은 윈도우 클래스를 정의하는데 사용되며 윈도우의 타이틀 바에 표시되기도 한다.

-First 예제에서는 다음 두 변수를 전역으로 선언해 사용하고 있다.

HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");

-메시지 처리 함수

이 프로그램은 두 개의 함수만 정의하고 있다. 하나는 프로그램의 시작점은 WinMain이며 나머지 하나는 WndProc이다. WndProc은 사용자와 시스템이 보내오는 메시지를 처리하는 아주 중요한 일을 한다. 윈도우즈에서는 아주 특별한 경우를 제외하곤ㄴ 이 두 개의 함수가 모두 있어야 한다.

WinMain은 메인 윈도우를 만들고 화면에 윈도우를 표시하기만 할 뿐이며 대부분의 일은 WndProc에서 이루어진다. WinMain은 프로그램을 초기화 하고 시작시키만 하므로 모양이 대체로 일정한데 WndProc은 프로그램의 실질적이고도 고유한 처리를 하는 곳이므로 프로그램에 따라 천차만별로 달라진다.
따라서 소스를 문석할 때 주의깊게 봐야할 부분은 WndProc이다.


-윈도우 클래스

WinMain의 가장 중요한 역할은 메인 윈도우를 만드는 것입니다. 그래야 사용자로부터 입력을 받을 수 있고 결과를 출력할 수 있기 때문입니다. 윈도우를 만들려면 윈도우 클래스를 먼저 등록한 후 CreateWindow 함수를 호출해야 합니다.

윈도우 클래스: -만들어질 윈도우의 여러 가지 특성을 정의하는 구조체
                    -모든 윈도우는 윈도우 클래스의 정보를 기반으로 만들어짐

typedef struct tagWNDCLASS
{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
}WNDCLASS;

style: 윈도우가 어떤 형태를 가질 것인가 지정
       보통( CS_HREDRAW와  CS_VREDRAW가 or 로 연결되 많이 쓰임) 이는 윈도우의 수직        or 수평 크기가 변할 경우 윈도우를 다시 그린다는 뜻

hInstance: 윈도우 클래스를 등록하는 프로그램의 번호 WinMain의 인수로 전달된                           hInstance값을 그대로 대입

-윈도우 생성

1.CreateWindow함수를 사용
(CreateWindow: 윈도우에 관한 모든 정보를 메모리에 만든 후 윈도우를 대표하는 번호인 윈도우 핸들을 리턴)

HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight, hwndParent, hmenu, hinst, IpvParam)

lpszClassName: 생성하고자 하는 윈도우 클래스를 지정하는 문자열

lpszWindowName: 윈도우의 타이틀 바에 나타날 문자열

dwStyle: 만들고자 하는 윈도우의 형태를 지정(보통 WS_OVERLAPPEDWINDOW)

X, Y,n Width, mHeight: 뜻 그래도 이해, (최적화 CW_USEDEFAULT)

hwndParent: NULL로 지정하면 데스크 탑을 부모로 가져 바탕화면 어디서든 돌아다님

hmenu: NULL일 경우 메뉴 없는 윈도우가 만들어짐

hinst: 프로그램의 핸들을 지정

lpvParam: 보통 NULL값을 가짐

2.ShowWindow함수를 사용

Bool ShowWindow(hWnd, nCmdShow);

hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);

이 두 줄의 코드로 윈도우를 화면에 나타내게 한다.

-메시지 루프

while(GetMessage(&Message,NULL,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}

1.BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

메시지 큐에서 메시지를 읽어오는 함수이다. 메시지는 MSG 구조체에 저장된다. 메시지 큐는 시스템이나 사용자로부터 발생된 메시지가 잠시 대기하는 일종의 메시지 임시 저장 영역!!!
즉 반복해서 메시지를 읽어오다가 얽어온 메시지가 WM_QUIT일 경우 FALSE를 리턴 반복문이 멈추게 된다.

2.BOOL TranslateMessage(CONST MSG *lpMsg);

이 함수는 키보드의 눌림(WM_KEYDOWN) 메시지가 발생할 때 문자가 입력되었다는 메시지(WM_CHAR)를 만드는 역할을 한다.

3.LONG DispatchMessage(CONST MSG *lpmsg);

이 함수는 메시지 큐에서 꺼낸 메시지를 윈도우 메시지 처리함수인 WndProc로 전달

-WndProc(윈도우 프로시저)


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage, WPARAM wParam, LPARAM IParam)
{
switch(iMessage){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,IParam));
}

1.인수

hWnd: 메시지를 받을 윈도우 핸들

iMessage: WM_SIZE, WM_KEYDOWN, WM_DESTROY(Alt+F4 등) 등의 값을 가짐

wParam, lParam: iMessage의 메시지에 따른 부가적인 정보를 가짐

2. 구문

PostQuitMessage: WM_QUIT 메시지를 보냄 WM_QUIT 메시지가 전송되면 GetMessage 함수의 리턴값이 FALSE가 되어 루프를 빠져나오게 된다.


-윈도우즈 API 정복1

You Might Also Like

0 개의 댓글