Download presentation
Presentation is loading. Please wait.
Published byBartłomiej Mazurkiewicz Modified 6년 전
1
Windows Programming Chapter 1. Introduction to SDK
Chapter 2. Structures of the SDK Windows Program
2
윈도우 프로그래밍 C언어 + WIN32 SDK (Standard Developer Kit)
표준 개발 키드 윈도에서 프로그래밍할 경우 표준으로 사용해야 할 라이브러리 C++ 언어 + MFC (Microsoft Foundation Class) 목표 SDK에서 제공하는 함수를 어떻게 사용하는가 프로그램 형식을 어떻게 하는가
3
윈도우 프로그램 기본구조(1) 윈도우 프로그래밍 초기화하는 부분
커널에게 허가를 받기 위한, 또는 커널이 점유하고 있는 시스템의 상황을 얻기 위한 커널과의 통신 부분 윈도우 프로그래밍에서는 모든 시스템 자원을 커널이 보유하고 있기 때문에 커널의 허가가 없이는 아무것도 할 수 없다.
4
윈도우 프로그램 기본구조(2) 윈도우 프로그램은 다음 두 개의 함수가 필요 void Init() {
//커널에 초기화 하는 부분 } void messagetranslation() //메시지를 주고 받는 부분
5
윈도우 프로그램 기본구조(3) 실제 프로그램에서도 위의 두 개의 형태로 구성 커널에초기화 하는 부분이 WinMain
메시지를 처리하는 부분이 WndProc int WINAPI WinMain (......) { // 초기화 부분 } LRESULT CALLBACK WndProc (....) // 메시지 처리 루틴
6
윈도우 프로그램 기본구조(5) 실제로 프로그램은 메시지 처리루틴에서 작성
LRESULT CALLBACK WndProc (....) { switch(메시지) case 키보드 눌렸음: 버퍼에 킷값을 저장함 break; case 화면출력해도 됨: 버퍼 내용을 화면에 출력한다. }
7
윈도우 프로그램 기본구조(6) 커널에서 들어온 메시지에 의해서 필요한 부분들을 switch문을 이용하여 처리하여 주는 루틴이 됨. 커널은 필요한 모든 메시지를 초기화한 윈도에 날려줌
8
윈도우 프로그램 기본구조(7) 이런 형태로 WndProc는 다음과 같이 변함
LRESULT CALLBACK WndProc (....) { //필요한 메시지만 처리하고 switch(메시지) case 키보드 눌렸음: 버퍼에 킷값을 저장함 break; case 화면출력해도 됨: 버퍼 내용을 화면에 출력한다. } CallKernel(); //나머지는 커널에게 다시 의뢰를 한다. * CallKernel이라는 함수가 있다는 것이 아니라 위와 같은 형식
9
윈도우 프로그램 기본구조(8) 윈도우 프로그래밍에서 초기화하는 부분을 WinMain
리얼모드 프로그램에서 main()으로 시작하듯 윈도우에서는 WinMain으로 프로그램이 시작 (프로그램이 컴파일될 때 프로그램의 시작점을 바로 WinMain에서부터 찾기 때문)
10
윈도우 프로그램 기본구조(9) int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) hInstance 란 프로그램 인스턴스라고 이야기 하는데 쉽게 보면 어플리케이션 프로그램의 ID hPrevInstance는 같은 프로그램이 이전에 구동되었을 때 설정되는 인스턴이스인데 윈도우95이후부터는 사용을 하지 않으므로 그냥 써준다고 생각하고 무시 szCmdLine는 프로그램과 함께 들어오는 인자들 iCmdShow에는 윈도우가 처음 출력될 때 쓰는 값 (화면에 출력되는 형태가 어떤 형태가 좋은 지를 알려주는 값)
11
초기화 방법(1) 초기화 방법 윈도우 클래스 등록 : RegisterClassEx( )
메인 윈도우 만들기 : CreateWindow( ) int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { RegisterClassEx () ;//클래스를 등록하고 CreateWindow ()//윈도우를 만든다. }
12
초기화 방법(2) 클래스가 두 개일경우에는 RegisterClassEx함수를 이용해서 또하나의 클래스를 등록
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { RegisterClassEx (메인윈도우스타일) ;//클래스를 등록하고 RegisterClassEx (차일드 윈도우 스타일) ;//클래스를 등록하고 CreateWindow ()//메인 윈도우를 만든다. }
13
프로시저(1) 윈도우는 Message Driven방식 : 모든 내용을 메시지를 이용하여 통신을 하는 것이 대부분인 프로그램방식
WinMain함수가 다음과 같은 형식으로 바꾸어져야 함 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { //메인 윈도우 클래스 RegisterClassEx (메인윈도우스타일,프로시저 -> WndProc) ; //차일드 윈도우 클래스 RegisterClassEx (차일드 윈도우 스타일,프로서저 -> ChildProc) ; CreateWindow ()//메인 윈도우를 만든다. }
14
프로시저(2) LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) 메뉴 메시지가 발생되었을 때 처리 } 나머지는 커널에 의뢰
15
프로시저(3) LRESULT CALLBACK ChildProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) 키보드 입력이 있었을 때 처리 } 나머지는 커널에 의뢰
16
WinMAin 분석(1) int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { } ATOM RegisterClassEx( CONST WNDCLASSEX *lpwcx //윈도우 클래스 정보 ); lpwcx는 구조체 : RegisterClassEx를 수행하기 위해서는 WNDCLASSEX 구조체의 변수를 만들고 이 구조체의 맴버에 값을 넣어주고 이것을 RegisterClassEx 에 넘겨주어야 함.
17
WinMain 분석(2) WNDCLASSEX 구조체
typedef struct _WNDCLASSEX { UINT cbSize; //본 구조체의 크기 UINT style; //출력 스타일 WNDPROC lpfnWndProc; //프로시저 함수 int cbClsExtra; //클래스 여분 메모리 int cbWndExtra; //윈도우 여분 메모리 HANDLE hInstance; //윈도우 인스턴스 HICON hIcon; //아이콘 HCURSOR hCursor; //커서 HBRUSH hbrBackground;//배경색 LPCTSTR lpszMenuName; // 메뉴이름 LPCTSTR lpszClassName; //클래스 이름 HICON hIconSm; //작은 아이콘 } WNDCLASSEX;
18
WinMain 분석(3) 클래스를 하나 등록 WNDCLASSEX wndclass ; wndclass.cbSize = sizeof (wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ;
19
WinMain 분석(4) 메인 윈도우를 만드는 작업
hwnd = CreateWindow (szAppName, // 클래스 이름 "Exam02", // 윈도우 이름 WS_OVERLAPPEDWINDOW, // 윈도우 스타일 CW_USEDEFAULT, // 윈도우 출력 위치 x 값 CW_USEDEFAULT, // 윈도우 출력 위치 y 값 CW_USEDEFAULT, // 윈도우 출력 크기 x 값 CW_USEDEFAULT, // 윈도우 출력 크기 y 값 NULL, // 부모 윈도우 핸들 NULL, // 메뉴 이름 hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ;
20
WinMain 분석(5) while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg) ; DispatchMessage (&msg) ; } 프로시저는 메시지를 처리할때마다 수행 프로시절를 호출하는 어떤 루프가 필요하고 이 루프가 바로 MainWnd에 설정 메인 윈도에 설정한 WndProc함수가 계속적으로 호출이 됨
21
Hello.c 의 WndProc 분석(1) LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; switch (iMsg) { case WM_CREATE ://윈도우가 처음 만들어질때 return 0 ; case WM_PAINT ://화면이 출력될때 hdc = BeginPaint (hwnd, &ps) ; main(hdc); EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY ://윈도우가 사라질때 PostQuitMessage (0) ; return 0 ; } //나머지는 알아서 처리하도록.... return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }
22
Hello.c 의 WndProc 분석(2) LRESULT : 결과 저장 32비트 변수 CALLBACK : 콜백 함수
iMsg : 들어오는 메시지 (여기서는 3개의 함수가 처리됨) wParam, lParam : 메시지와 함께 설정되는 여러 정보를 보관하는 변수 PostQuitMessage(0) : 메시지 큐에 종료 메시지 설정. 이때 Winmain의 while루프의 GetMessage 함수는 0을 리턴하고 While루프 종료시 프로그램 종료.
23
Hello.c 의 WndProc 분석(3) 윈도우 프로그래밍 : 핸들을 받아서 그 핸들을 사용하거나 핸들을 만들어서 설정하여 사용 (예) 그릴 화면 핸들을 받고, 라인을 그릴 펜이라는 핸들을 만들고, 펜 이라는 핸들을 이용하여 그릴 화면 핸들에 라인을 그린다. 윈도우 프로그래밍 -> 모든 것을 객체화 이 객체를 컨트롤하기 위해 핸들 사용 (예) HWND (윈도우 핸들) (예) HINSTANCE (인스턴스 핸들) (예) HDC (디바이스 컨텍스트 핸들)
24
메시지 멤버 멤버 의미 wnd 메시지를 받을 윈도우 핸들 message 메시지 종류 wParam
전달된 메시지에 대한 부가적 정보(32bit) lParam “ time 메시지가 발생한 시간 pt 메시지가 발생했을 때의 위치
25
메시지 매크로 상수 windows.h 파일에 메시지별로 매크로 상수로 정의 WM_ 으로 시작 메시지 의미 WM_QUIT
프로그램 종료 WM_LBUTTONDOWN 마우스 왼쪽버튼을 누를 경우 WM_KEYDOWN 키보드의 키를 누를 경우 WM_CHAR 키보드로부터 문자가 입력될 경우 WM_PAINT 화면을 다시 그려야 할 경우 WM_CREATE 윈도우가 처음 만들어 질 때 WM_DESTROY 윈도우가 메모리에서 파괴될 때
26
메시지 처리 MSG구조체 GetMessage 메시지 꺼냄 TranslateMessage 키보드 해석
DispatchMessage 메시지 보냄 WM_QUIT? 종료 WndProc switch (Message) case . 메시지 처리 메시지큐 메시지 입력 Yes No
27
배경색 바꾸기 윈도우 기본 브러시 WHITE_BRUSH BLACK_BRUSH LTGRAY_BRUSH WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); WndClass.hbrBackground=CreateSolidBrush(RGB(0,0,255)); WndClass.hbrBackground =CreateHatchBrush(HS_DIAGCROSS,RGB(255,0,0));
28
커서모양 바꾸기 HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName); WndClass.hCursor=LoadCursor(NULL, IDC_ARROW); 값 설명 모양 IDC_ARROW 화살표 모양 IDC_CROSS 십자 모양 IDC_IBEAM |자 모양 IDC_NO 원 안에 빗금친 모양 IDC_WAIT 모래시계 모양
29
윈도우 타이틀 / 위치 / 크기 바꾸기 hWnd=CreateWindow(szAppName, szTitle, S_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); static char szTitle[]=“내가 만든 윈도우즈 프로그램"; hWnd=CreateWindow(szAppName, szTitle, S_OVERLAPPEDWINDOW, , 100, 300, 200, NULL, NULL, hInstance, NULL); (100, 100)의 위치에 폭 300, 높이 200인 윈도우
30
윈도우 스타일 hWnd=CreateWindow(szAppName, szTitle, S_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) 값 설명 WS_CAPTION 타이틀 바 WS_HSCROLL 수평 스크롤바 WS_VSCROLL 수직 스크롤바 WS_MAXIMIZEBOX 최대화 버튼 WS_MINIMIZEBOX 최소화 버튼 WS_SYSMENU 시스템 메뉴 WS_THICKFRAME 크기조절 가능한 경계선
31
DC(Device Context) DLL(Dynamic Link Library)
커널 : 메모리 관리, 프로그램 실행 유저 : 유저인터페이스, 윈도우 관리 GDI(Graphic Device Interface) : 화면으로 출력되는 모든 글자와 그림은 GDI모듈을 통함 DC : 출력에 필요한 모든 정보를 가지는 데이터 구조체 화면 출력에 필요한 정보들 : 폰트, 선의 색상과 굵기, 채움, 무늬, 색상, 그리기 모드…..
32
문자열 출력:GetDC() GetDC()에 의한 출력
ex1) HDC hdc; switch(iMessage) { case WM_DESTROY; PoseQuitMessage(0); return 0; case WM_LBUTTONDOWN; hdc=GetDC(hWnd); TextOut(hdc, 100, 100, TEXT(“Beautiful KOREA”), 15); ReleaseDC(hWnd, hdc); return 0; }
33
문자열 출력:WM_PAINT() WM_PAINT()에 의한 출력
ex2) HDC hdc; PAINTSTRUCT ps; switch(iMessage) { case WM_DESTROY; PoseQuitMessage(0); return 0; case WM_PAINT; hdc=BeginPaint(hWnd, &ps); TextOut(hdc, 100, 100, TEXT(“Beautiful KOREA”), 15); EndPaint(hWnd, &ps); return 0; }
34
문자열 출력:TextOut() BOOL TextOut(HDC, int nXStart, int nYStart, LPCTSTR lpString, int cbString); ex1) TextOut(hdc, 100, 100, TEXT(“Beautiful KOREA”), 15); ex2) TCHAT *str=TEXT(“Beautiful KOREA”); TExtOut(hdc, 100, 100, str, lstrlen(str)); UINT SetTextAlign(HDC hdc, UINT fMode); 값 설명 TA_TOP 지정한 좌표가 상단 좌표 TA_BUTTOM 지정한 좌표가 하단 좌표 TA_CENTER 지정한 좌표가 수평 중앙 좌표 TA_LEFT 지정한 좌표가 수평 왼쪽 좌표 TA_RIGHT 지정한 좌표가 수평 오른쪽 좌표 TA_UPDATECP(*1) 지정한 좌표대신 CP(Current Position) 를 사용하며 문자열 출력후에 CP 변경 TA_NOUPDATECP CP를 사용하지 않고 지정한 좌표를 사용하며 CP를 변경하지 않음
35
실습(1) 이름, 학과, 학번을 출력하는 윈도우즈프로그램 윈도우 위치 (100, 100) 윈도우 크기 (400, 300)
처음 윈도우를 등록할때 아이콘, 커서(화살표), 배경색(회색)을 바꾸면서,…. wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 출력예 홍길동 모바일게임과
36
문자열 출력:TA_UPDATECP ex1) case WM_PAINT; hdc=BeginPaint(hWnd, &ps); SetTextAlign(hdc, TA_UPDATECP); TextOut(hdc, 200, 60, TEXT(“One “), 4); TextOut(hdc, 200, 80, TEXT(“Two “), 4); TextOut(hdc, 200, 100, TEXT(“Three“), 5); EndPaint(hWnd, &ps); return 0;
37
정수/실수의 출력:wsprintf() ex2) TCHAT str[128]; int Scroe=85; wsprintf(“현재 점수는 %d점 입니다.”, Score); TextOut(hdc, 10, 10, str, lstrlen(str)); 정수 출력 : wsprintf(), API함수 실수출력 : sprintf(), swprintf()
38
문자열 출력함수:DrawText() int DrawText(HDC hdc, LPCTSTR lpString, int nCount, LPRECT lpRect, UINT uFormat); 사각영역을 설정하여 영역 안에 문자열 출력 lpString : 출력할 문자열 nCount : 출력할 문자열의 길이 typedef struct _RECT { LONG left; LONG top; LONG right; LONG bottom; } RECT;
39
문자열 출력함수:DrawText() uFromat : 문자열을 출력할 방법 값 설명 DT_LEFT 수평 왼쪽 정렬
DT_RIGHT 수평 오른쪽 정렬 DT_CENTER 수평 중앙에 출력 DT_BOTTOM 바닥에 출력 DT_VCENTER 수직중앙에 출력 DT_WORDBREAK 오른쪽 끝에서 자동 개행 DT_SINGLELINE 한 줄로 출력 DT_NOCLIP 경계를 벗어나도 문자열을 그대로 출력
40
실습(2) 윈도우크기 : (300,400) 위치 : (100,100) 수평 중앙에 텍스트 : "님은 갔습니다. 아아 사랑하는 나의 님은 갔습니다. 푸른 산빛을 " "깨치고 단풍나무 숲을 향하여 난 작은 길을 걸어서 차마 떨치고 갔습니다." "황금의 꽃같이 굳고 빛나던 옛 맹세는 차디찬 티끌이 되어 한숨의 미풍에" "날아갔습니다."
41
그래픽 출력:GDI함수 COLORREF SetPixel(hdc, nXPos, nYPos, clrref)
(x, y)위치에 clrref 색상의 점 DWORD MoveToEx(hdc, x, y, lpPoint) / BOOL LineTo(hdc, xEnd, yEnd) (x, y)에서 (xEnd, yEnd)까지 직선을 그림 BOOL Rectangle(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect) BOOL Ellipse(hdc, nLeftRect, nTopRect , nRightRect, nBottomRect) (Left, Top) (Right, Bottom)
42
실습(3) (10, 10)의 위치에 빨간점 (50, 50)에서 (300, 90)까지 직선
(50, 100, 200, 180)에 사각형 (220, 100, 400, 200)에 내접하는 타원
43
메시지 박스 int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); lpText : 메시지 박스에 출력할 문자열 lpCaption : 메시지 박스의 타이틀 바에 나타날 제목 문자열 uType : 메시지 종류 값 설명 MB_ABORTRETRYIGNORE Abort, Retry, Ignore 버튼 MB_OK Ok 버튼 MB_OKCANCEL Ok, Cancel 버튼 MB_RETRYCANCEL Retry, Cancel 버튼 MB_YESNO Yes, No 버튼 MB_YESNOCANCEL Yes, No, Cancel 버튼
44
메시지 박스의 아이콘 아이콘 버튼값 값 아이콘 MB_ICONEXCLAMATION, MB_ICONWARNING
MB_ICONINFORMATION, MB_ICONASTERISK MB_ICONQUESTION MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND 값 설명 IDABORT Abort 버튼을 누름 IDCANCEL Cancel “ IDIGNORE Ignore “ IDNO No “ IDOK Ok “ IDRETRY Retry “ IDYES Yes “
45
실습(4) 메시지 박스에 “마우스 왼쪽버튼을 눌렀습니다” 출력 ‘확인’ 버튼
switch(iMessage) { case WM_LBUTTONDOWN: MessageBox(hWnd, TEXT(“마우스 왼쪽 버튼 입력”), TEXT(“메시 지박스”), MB_OK); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; }
Similar presentations