940 likes | 1.38k Views
Win32 API Programming. 이 계 임. Windows Programming. GUI 기반 Multitasking 환경 장치 독립성 (Device Independent) 일관된 사용자 인터페이스 이벤트 처리 방식 ( 메시지 구동 방식 ) 리소스 사용 메뉴 , 비트맵 , 아이콘. What is API?. API(Application Programming Interface) 운영체제가 응용 프로그램을 위해 제공하는 함수의 집합 . C Library
E N D
Win32 API Programming 이 계 임
Windows Programming • GUI 기반 • Multitasking 환경 • 장치 독립성(Device Independent) • 일관된 사용자 인터페이스 • 이벤트 처리 방식(메시지 구동 방식) • 리소스 사용 • 메뉴, 비트맵, 아이콘
What is API? • API(Application Programming Interface) • 운영체제가 응용 프로그램을 위해 제공하는 함수의 집합. C Library • 응용 프로그램 개발자들이 운영체제가 제공하는 기능들을 사용할 수 있도록 운영체제가 제공하는 함수의 집합. • SDK(S/W Development Kit) • API를 이용하여 프로그램을 개발하는 개발툴 킷 • API와 유사한 의미로 사용됨.
Application 개발 User Application MFC Windows API Kernel GDI User Device Driver H/W System
윈도우즈 프로그램 개발방법 • SDK • API를 사용하여 개발 • Class Library • MFC, OWL 등 클래스 중심의 프로그래밍 • Visual Tools • VB, Delphi 등
Why API? • 운영체제를 이해하기 위해서 반드시 필요함. • 다른 개발 방법을 사용하더라고 API를 결국 알아야 하기 때문. • 프로그램 개발 시 프로그래머의 융통성(flexibility)를 극대화 하기 위해 필요함. 윈도우즈 프로그래밍의 기본
변수 명명 규칙 • Hungarian Notation • 접두어를 사용하여 변수의 자료형 알려줌.
윈도우즈 자료형 • windows.h에 정의
핸들(Handle) • 대상에 붙여진 번호로 32bit 정수값 • 윈도우 핸들, DC 핸들, 펜 핸들, 브러쉬 핸들, 메모리 핸들 등 • 운영체제가 발급하며 사용자는 이 핸들을 사용하기만 한다. • 같은 종류의 핸들은 중복될 수 없다. • 핸들값 저장에 사용되는 자료형 • HWND, HDC, HPEN, HBRUSH 등
WinMain 함수 • 프로그램의 시작점(Entry Point) : 프로그램 초기화 및 시작. • 메인 윈도우를 화면에 만들고 출력. • int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow); • hInstance : 프로그램의 인스턴스 핸들 • hPrevInstance : Win32에서는 항상 NULL • lpszCmdParam : 명령행 인수 • nCmdShow : 프로그램 실행 형태(보통, 최소화, 최대화 등)
WinMain의 역할 • int APIENTRY WinMain(HINSTANCE hInstance, • HINSTANCE hPrevInstance, • LPSTR lpszCmdParam, int nCmdShow) • { • 윈도우 클래스 정의 • 윈도우 클래스 등록 • 윈도우 객체 생성 • 화면에 윈도우 보이기 • Message Loop • }
윈도우 클래스 (WNDCLASS) • 만들어질 윈도우의 특성을 정의하는 구조체 • style : 윈도우스타일(CS_HREDRAW|CS_VREDRAW) • lpfnWndProc : 윈도우의 메시지 처리 함수 이름 • WndProc가 일반적인 이름 • cbClsExtra, cbWndExtra : 예약영역 • hInstance : 프로그램의 인스턴스 핸들 • hIcon, hCursor : 마우스 커서와 아이콘 지정 • LoadCursor(), LoadIcon() 함수로 지정 • hbrBackground : 윈도우의 배경색을 칠한 브러시 지정. • GetStockObject() 함수로 윈도우 기본 브러시 지정 • lpszMenuName : 프로그램이 사용할 메뉴 지정 • lpszClassName : 윈도우 클래스 이름 (문자열)
윈도우 클래스 등록 • 운영체제에 윈도우 클래스 등록 WNDCLASS WndClass; 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)WndProc; WndClass.lpszClassName=lpszClass; WndClass.lpszMenuName=NULL; WndClass.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&WndClass);
윈도우 객체 생성 • HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y, nWidth, hHeight, hWndParent, hMenu, hInst, lpvParam); • lpszClassName : 윈도우 클래스 이름 • lpszWindowName : 윈도우 타이틀 바 문자열 • dwStyle : 윈도우의 형태 지정 • WS_OVERLAPEDWINDOW 사용 • x, y, nWidth, nHeight : 윈도우의 위치와 크기 지정 • CW_USERDEFAULT 사용 • hWndParent : 부모 윈도우의 핸들 • hMenu : 메뉴 핸들 • hInst : 프로그램의 인스턴스 핸들 • hpvParam : CREATESTRUCT 구조체 (NULL) • 만들어진 윈도우는 메모리 상에만 존재할 뿐 화면 출력되지 않음.
윈도우 보이기 • BOOL ShowWindow(hWnd, nCmdShow) • hWnd : 화면에 출력할 윈도우 핸들 • nCmdShow : 윈도우의 화면 출력 방법 • SW_HIDE, SW_MINIMIZE, SW_MAXIMIZE, SW_RESTORE, SW_SHOW, SW_SHOWNORMAL hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow);
메시지 이벤트가 발생한 윈도우 핸들 이벤트의 종류 이벤트 발생 시각 이벤트 발생 위치 이벤트 처리 방식 • 이벤트 발생을 정보화 한 것 메시지 Event 발생 마우스 누름 정보화
WinMain() { } 메시지 루프 운영체제 메시지 어플리케이션 큐 WndProc() { } 윈도우 프로시저 시스템 큐 SendMessage 디폴트 윈도 우 프로시저 PostMessage 메시지 전달 순서 이벤트 발생
메시지 루프 • BOOL GetMessage(lpMsg, hWnd, wFilterMin, wFilterMax); • 메시지 큐에서 메시지를 읽어들임 • 읽은 메시지가 WM_QUIT인 경우에만 FALSE 리턴 메시지 루프 종료 • BOOL TranslateMessage(lpMsg); • 키보드 입력 메시지를 WM_CHAR 메시지로 변환 • BOOL DispatchMessage(lpMsg); • 메시지를 운영체제로 전달하여 운영체제가 윈도우 프로시저를 호출하도록 함 while(GetMessage(&Message,0,0,0) { TranslateMessage(&Message); DispatchMessage(&Message); }
메시지 구조체 (MSG) • 메시지 전달 시 사용 • hWnd : 메시지 받을 윈도우 핸들 • message : 메시지의 종류 • windows.h에 매크로로 정의되어 있음 • wParam : 메시지에 대한 부가 정보 • lParam : 메시지에 대한 부가 정보 • time : 메시지 발생 시간 • pt : 메시지 발생시 마우스 위치 • 메시지의 종류에 따라 wParam, lParam의 의미가 달라짐
윈도우 프로시저 • 사용자/시스템이 전달하는 메시지 처리. • 프로그램의 실질직이고 고유한 처리. • 운영체제에 의해 호출 콜백함수 • LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam); • hWnd : 메시지가 전달될 윈도우 핸들 • iMessage : 메시지의 종류 • wParam : 메시지의 부가 정보 • lParam : 메지시의 부가 정보
윈도우 프로시저 (Continued) • 메시지의 종류에 따른 처리방법을 switch case문을 이용하여 기술 • 디폴트 윈도우 프로시저 : 윈도우 프로시저에서 처리하지 않은 메시지 처리 LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage, WPARAM wParam, LPARAM lParam) { switch(iMessage) { case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd,iMessage,wParam,lParam)); }
Device Context • 출력에 필요한 정보를 담고 있는 구조체 • 폰트, 선의 색상과 굵기, 채움 무늬와 색상, 출력 방법 등 • 모든 GDI 출력 함수는 DC에 대한 핸들을 이용하여 그리기를 수행 • 출력을 위해서는 우선 DC를 얻어야 함 • DC 생성 방법 • GetDC(), ReleaseDC() 함수 이용 • BeginPaint(), EndPaint() 함수 이용 : WM_PAINT 메시지 처리 루틴에서만 사용
WM_PAINT 메시지 • 화면에 무효화 영역(Invalid Region)이 있을 때 발생 • 윈도우의 작업 영역이 지워졌음을 운영체제가 프로그램에 알려줌 • 화면을 보관/복구하는 메커니즘 필요 • 모든 그래픽 출력은 WM_PAINT 메시지 시 처리 • 모든 프로그램은 화면 복원을 위해 출력 내용을 보관하거나 복구할 준비를 해야 함
문자열 출력 함수 • BOOL TextOut(HDC hdc, int x, int y, LPCTSTR lpStr, int cbStr); • UINT SetTextAlign(HDC hdc, UINT fMode); • int DrawText(HDC hdc, LPCTSTR lpStr, int nCount, LPRECT lpRect, UINT uFormat); Rect rt={200,200,400,400}; SetTextAlign(hdc, TA_CENTER); TextOut(hdc, 100, 100, “Hello World”, 11); DrawText(hdc, “Good-Bye”, -1, &rt, DT_CENTER|DT_VCENTER| DT_SINGLELINE);
그래픽 출력 함수 • COLORREF SetPixel(HDC hdc, int x, int y, COLORREF crColor); • DWORD MoveToEx(HDC hdc, int x, int y, LPPOINT lpPoint); • BOOL LineTo(HDC hdc, int x, int y); • BOOL Rectangle(HDC hdc, int left, int top, int right, int bottom); • BOOL Ellipse(HDC hdc, int left, int top, int right, int bottom);
메시지 박스 • int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); • hWnd : 메시지 박스의 오너 윈도우 • lpText : 메시지 박스에 출력할 문자열 • lpCaption : 메시지 박스의 제목 문자열 • uType : 버튼 종류 및 아이콘 종류 • MB_OK, MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL, MB_ABORTRETRYCANCEL 등 • MB_ICONWARNING, MB_ICONINFORMATION, MB_ICONQUESTION, MB_ICONSTOP 등 • 리턴 값으로 눌린 버튼의 ID 전달
윈도우 프로그램 종료 절차 종료 버튼 클릭 또는 Alt+F4 WM_CLOSE 메시지 발생 PostQuitMessage 호출 WM_QUIT 메시지 발생 디폴트 윈도우 프로시저 전달 윈도우 프로시저 전달 WinMain의 메시지 루프 탈출 DestroyWindow 호출 WM_DESTROY 메시지 발생 프로그램 종료
키보드 입력 • WM_KEYDOWN 메시지 • 키보드 입력은 활성 윈도우에만 전달 • 키보드 입력 시 발생 • wParam : 가상키코드 • lParam : 입력된 문자의 반복카운트, 스캔 코드 등의 추가 정보 • WM_CHAR 메시지 • 문자 입력 시 발생 • wParam : 입력된 문자의 ASCII 코드 • lParam : 입력된 문자의 반복카운트, 스캔 코드 등의 추가 정보
무효화 영역 • 윈도우를 다시 그릴 필요가 있는 경우 WM_PAINT 메시지 발생 • 무효화 영역(Invalid Region)이 있음 • WM_PAINT 메시지 처리하면 유효화됨 • BOOL InvalidateRect(HWND hWnd, CONST RECT* lpRect, BOOL bErase); • hWnd의 lpRect 영역을 무효화 영역으로 설정 lpRect를 최소화하여 프로그램 효율을 향상 • bErase : TRUE면 배경을 지우고 다시 그림
키보드 입력 변환 • 메시지 루프의 TranslateMessage 함수는 GetMessage로 꺼낸 메시지가 WM_KEYDOWN 메시지인 경우에 문자키인지를 검사해서 • 문자키인 경우 WM_CHAR 메시지 추가 • 문자키가 아닌 경우 아무 일도 하지 않음 while( GetMessage(&Message,0,0,0) ){ TranslateMessage(&Message); DispatchMessage(&Message); }
시스템 키보드 메시지 • WM_SYSKEYDOWN, WM_SYSKEYUP, WM_SYSCHAR 등 • Alt 키와 함께 입력 • Alt+F4 등 • 보통 운영체제에서 처리 • 윈도우 프로시저에서 처리하는 경우에도 처리 후 반드시 DefWindowProc에 전달하여 운영체제에서 처리하도록 함
마우스 입력 • 마우스 관련 메시지 • WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBCLK, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_RBUTTONDBCLK, WM_MOUSEMOVE, WM_MOUSEWHEEL 등 • lParam : 마우스가 눌린 x, y 좌표 • x 좌표 : LOWORD(lParam) • y 좌표 : HIWORD(lParam) • wParam : 마우스 버튼 상태 및 키보드 조합 키의 상태 • MK_CONTROL, MK_SHIFT, MK_LBUTTON, MK_RBUTTON, MK_MBUTTON 등
더블 클릭 • 프로그램에서 더블 클릭을 사용하려면 윈도우 스타일에 설정해야 함 WndClass.lpfnWndProc = (WNDPROC)WndProc; WndClass.lpszClassName = lpszClassName; WndClass.lpszMenuName = NULL; WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; RegisterClass(&WndClass);
작업영역과 비작업영역 • 작업영역 • Client Area • 프로그램내에서 실제 출력이 이루어지는 영역 • 프로그래밍의 대상 • 비작업영역 • Non Client Area • 타이틀 바, 경계선, 메뉴, 스크롤 바 등의 영역 비작업영역 Non Client Area 작업영역 Client Area
비작업영역 마우스 메시지 • 비작업영역에서의 마우스 메시지는 일반 마우스 메시지에 NC 사용 • WM_NCMOUSEMOVE, WM_NCLBUTTONUP, WM_NCLBUTTONDOWN 등 • 비작업영역 메시지는 운영체제가 사용 • 프로그램 내에서 처리하는 경우에도 반드시 DefWindowProc에 전달해야 함
타이머 메시지 • WM_TIMER 메시지 • 일정한 시간 간격으로 반복 발생하는 메시지 • wParam : 타이머 ID • lParam : 타이머에 설정된 TimerProc 주소 • VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime); • WM_TIMER 메시지 발생시 운영체제가 호출
콜백 함수 • 응용 프로그램이 제공하며 운영체제가 호출하는 함수 • 콜백함수가 호출되는 조건이 이미 정해져 있음 • 콜백함수의 원형을 반드시 지켜야 함
SetTimer & KillTimer • UINT SetTimer(HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc); • hWnd : 타이머 메시지를 받을 윈도우 핸들 • nIDEvent : 타이머 번호 • uElapse : 타이머의 주기 (ms 단위) • lpTimerProc : 타이머 메시지 발생시 호출되는 콜백 함수 • BOOL KillTimer(HWND hWnd, UINT nIDEvent); • 타이머 사용 후 운영체제에 반납
SendMessage • LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); • 강제로 메시지를 발생시킴 • SendMessage 함수는 윈도우 프로시저를 호출하며 윈도우 프로시저가 메시지 처리가 끝낸 다음에야 리턴됨 • PostMessage 함수는 메시지 큐에 메시지를 넣고 바로 리턴됨
윈도우 관리 메시지 • WM_CREATE : 윈도우 생성 시 발생 • 초기화에 적합 (Timer 설정 등) • WM_DESTROY : 윈도우 파괴 시 발생 • 종료 처리에 적합 (Timer 해제 등) • WM_SIZE : 윈도우 크기 변경 시 발생 • WM_MOVE : 윈도우 좌표 변경 시 발생
작업 영역 구하기 • BOOL GetClientRect(HWND hWnd, LPRECT lpRect); • 작업 영역을 차지하는 RECT 구조체를 구하는 함수 • 작업 영역(Client Area)의 RECT 구조체의 LeftTop은 항상 (0,0)이고 RightBottom은 (width, height)로 설정
리소스 • 프로그램은 코드와 데이터로 구성됨 • 비트맵, 아이콘, 메뉴, 문자열 등도 데이터에 포함 • 프로그램 코드의 논리와 무관한 데이터를 리소스라고 함 • 리소스 생성과 코딩의 분리 • 작업이 편리 • 별도의 리소스 컴파일 개발 속도 향상 • 리소스 재사용 • 리소스의 교체만으로 프로그램 기능 변경
리소스의 종류 • 메뉴 • 아이콘 • 커서 • 비트맵 • 액셀러레이터 • 문자열 테이블
메뉴 • 윈도우 클래스에 등록 • WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); • 메뉴 선택시 WM_COMMAND 메시지 전달 • wParam : LOWORD(wParam)에 메뉴 ID 전달 • 액셀러레이터 입력시도 WM_COMMAND 메시지 전달
커서/아이콘 • MAKEINTRESOURCE 매크로 • 정수값 리소스 ID를 문자열로 변환 • 직접 만든 커서/아이콘 사용 가능 WndClass.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1)); WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
액셀러레이터 • 단축키 입력에 사용되는 키 등록 • Shortcut과는 다른 의미 • Shortcut은 메뉴에서 Alt와 함께 문자 입력 • HACCEL LoadAccelerators(HINSTANCE hInstance, LPCTSTR lpTableName); • 리소스에서 액셀러레이터를 읽어옴 • int TranslateAccelerators(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg); • 키보드 메시지를 WM_COMMAND로 변경
문자열 테이블 • 문자열도 리소스의 일종 • 프로그램에서 자주 사용하는 문자열을 등록 • 프로그램내의 문자열의 관리가 쉬워짐 • int LoadString(HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax); • uID : 문자열의 리소스 ID • lpBuffer : 문자열을 읽을 버퍼 • nBufferMax : 버퍼의 최대크기
GDI Object • 그래픽 출력에 사용되는 도구 • 펜, 브러쉬, 비트맵, 폰트 등 • 핸들로 관리 • 따로 도구를 선택하지 않으면 디폴트 도구가 사용됨 • Stock Object • 윈도우즈가 기본적으로 제공하는 GDI Object • 따로 만들거나 파괴 시킬 필요가 없이 사용
GDI Object Handle • HPEN : 선을 그릴 때 사용 • HBRUSH : 면을 채울 때 사용 • HFONT : 문자열 출력에 사용 • HBITMAP : 비트맵 이미지 • HPALETTE : 팔레트 • HRGN : 영역
Stock Object의 사용 • HGDIOBJ GetStockObject(int nObject); • 윈도우즈에 등록된 Stock object에 대한 핸들을 얻는 함수 • HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hObject); • DC내의 GDI 도구 선택시 사용 • 이전에 선택되어 있던 도구의 핸들을 리턴 • 리턴값을 저장했다가 GDI 도구를 복원하는데 사용