수업기록 #winapi
API
Application Programming Iterface
운영체제 마다 api가 존재한다. 우리는 윈도우 기반의 winapi (winapi32) 이다.
winapi는 C언어 기반의 api (C++은 mfc)임.
첫 화면 윈도우 초기화 구문 : 윈도우(창)의 초기화 및 생성을 하는 곳
API부터 모든 문자는 유니코드 기반의 문자. 대문자 형식은 typedef된 것들.
핸들 16진수 형태의 고유 식별 번호
About 함수 도움말 : 정보 띄워주는 함수
라이브러리 : 남이 작성한 코드를 암호화하여 사용하기 위한 파일
GDI : 그래픽 디바이스 인터페이스 - > 화면처리와 그래픽 담당 명령어 집합 알파 블렌드? GDI +
디바이스 컨텍스트 : 출력에 관한 정보를 가지고 있는 구조체
수업 기록 재정리
전역 변수
HINSTANCE hInst; // 현재 인스턴스입니다.
WCHAR szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트입니다.
WCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.함수의 전방선언
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);- 보통 h가 붙으면 핸들
메인 함수
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_DEFAULTWINDOW, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 애플리케이션 초기화를 수행합니다:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DEFAULTWINDOW));
MSG msg;
// 기본 메시지 루프입니다:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
함수의 진입점이라고 보면 좋음
szWindowClass 는 실행 파일이라고 보아도 무방함
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DEFAULTWINDOW));단축키를 불러오는 객체
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}메시지 큐에서 메시지를 가져오는 함수 메시지 큐의 경우, 메시지가 있다면 true / 없다면 block(대기) / 종료 메시지가 왔을 때 (false) 반환함.
만약, 메시지가 종료 메시지가 아니고, 단축키 테이블에 등록된 것이 아니라면 메시지를 해석하고 DispatchMessage(&msg); 한다.
이때 DispatchMessage(&msg); 안에는 winproc(윈도우 프로시저)가 들어있어서, 메시지에 따라 호출이 된다.
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex; // 윈도우 창 생성을 위해 값을 채워야할 구조체
wcex.cbSize = sizeof(WNDCLASSEX); // 자기 자신의 사이즈를 저장
wcex.style = CS_HREDRAW | CS_VREDRAW;
// 가로 다시 그리기 | 세로 다시 그리기
// 윈도우 창의 스타일 정의, 초기화 되는 값이 창의 수평, 수직 크기가 변할 경우 다시 그리기를 말하는 옵션
wcex.lpfnWndProc = WndProc;
// 메세지 처리기 함수의 이름을 전달
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
// 윈도우가 특수한 목적으로 사용하는 여분의 공간(일종의 예약 영역)
wcex.hInstance = hInstance;
// 윈도우 클래스를 사용하는 프로그램의 번호를 설정, main함수 매개 변수 전달 값이 자동 사용
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DEFAULTWINDOW));
// 윈도우 차이 사용할 아이콘 지정
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
// 창에서 사용할 마우스 커서
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
// 창 배경 색상
wcex.lpszMenuName = NULL; //MAKEINTRESOURCEW(IDC_DEFAULTWINDOW);
// 창 메뉴
wcex.lpszClassName = szWindowClass;
// 실행 파일 이름 지정
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
// 창 상단의 아이콘
return RegisterClassExW(&wcex);
}BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
HWND hWnd = CreateWindowW(szWindowClass, // 클래스 이름(실행 파일 이름)
szTitle, // 창 위에 띄울 문자열
WS_OVERLAPPEDWINDOW, // 윈도우 창 스타일 옵션(기본 창 모양)
CW_USEDEFAULT, 0, // 창 생성 위치(X, Y 좌표)
800, 600, // 창의 가로, 세로 사이즈
nullptr, // 부모 윈도우 핸들
nullptr, // 윈도우에서 사용할 메뉴 핸들
hInstance, // 윈도우를 만드는 주체
nullptr); // 운영체제가 특수한 목적으로 사용
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}RECT rc{ 100, 100, 200, 200 };
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
SetTimer(hWnd, 0, 0, 0);
// 타이머 설치 함수
// 1. 윈도우 핸들
// 2. 타이머 id
// 3. 타이머 주기(default 1 / 1000)
// 4. NULL인 경우 3 매개 변수 주기로 WM_TIMER 메세지를 발생시킴
break;
case WM_TIMER:
InvalidateRect(hWnd, 0, TRUE);
// 윈도우 갱신 함수
// 1. 갱신할 윈도우 핸들
// 2. 윈도우 갱신 범위(NULL 인 경우 화면 전체 영역)
// 3. TRUE : 그려져 있지 않는 부분도 갱신
// FALSE : 새로 그리는 부분만 갱신
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 메뉴 선택을 구문 분석합니다:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
// dc : 출력에 관한 정보를 갖고 있는 구조체
HDC hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
EndPaint(hWnd, &ps);
}
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_RIGHT:
rc.left += 10;
rc.right += 10;
break;
case VK_LEFT:
rc.left -= 10;
rc.right -= 10;
break;
case VK_UP:
rc.top -= 10;
rc.bottom -= 10;
break;
case VK_DOWN:
rc.top += 10;
rc.bottom += 10;
break;
case VK_SPACE:
break;
case VK_ESCAPE:
DestroyWindow(hWnd);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}25-04-07 함수 호출 규약 25-04-07 뭐라고 그려와라~ 25-04-07 스페이스 바 누르면 총알 발싸~