윈도우 API - 사각형 이동시키기 심화 (2024)

게임개발일기

윈도우 API - 사각형 이동시키기 심화

모모 2024. 6. 11. 9:03

URL 복사 이웃추가

본문 기타 기능

신고하기

// Project62.cpp : 애플리케이션에 대한 진입점을 정의합니다.//#include "pch.h"#include "framework.h"#include "Project62.h"#define MAX_LOADSTRING 100// 전역 변수:HINSTANCE hInst; // 현재 인스턴스입니다.WCHAR szTitle[MAX_LOADSTRING] = PROGRAM_TITLE; // 제목 표시줄 텍스트입니다.WCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.POINT ptPos = { 0,0 }; //조작할 죄표의 이동 좌표값// 이 코드 모듈에 포함된 함수의 선언을 전달합니다:ATOM MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY wWinMain(_In_ HINSTANCE hInstance, //프로그램의 인스턴스 _In_opt_ HINSTANCE hPrevInstance, //이전에 실행된 인스턴스 (사용안함) _In_ LPWSTR lpCmdLine, //명령행으로 입력된 프로그램 인수 (안씀) _In_ int nCmdShow) //프로그램이 실행 될 때 형태 (최소 값, 보통 들의 상태값) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 여기에 코드를 입력합니다. // 전역 문자열을 초기화합니다. //LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); //함수 자체를 주석 처리하면 게임 타이틀이 바뀜 LoadStringW(hInstance, IDC_PROJECT62, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); //참 클래스 (구조체등록) // 애플리케이션 초기화를 수행합니다: if (!InitInstance (hInstance, nCmdShow)) // InitInstance(hInstance, nCmdShow) == FALSE { return FALSE; // 초기화가 실패한다면 FALSE를 돌려주겠다. } // 엑셀러레이터 (단축키) 테이블을 읽어 들인다. HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROJECT62)); MSG msg; // 기본 메시지 루프입니다: while (GetMessage(&msg, nullptr, 0, 0)) //메시지를 받아오는 { // 키보드 메세지를 WM_COMMAND로 변경해서 엑셀러레이터가 동작 할 수 있도록 // 해주는 함수 // 엑셀러레이터(단축키) // 즉 키보드가 등록되어 있는 단축키를 눌렀는지를 확인 후, 그에 걸맞는 처리를 // 수행해준다. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); //키보드 입력이 들어 왔을 때의 처리 정보 전달 DispatchMessage(&msg); //메세지를 프로시저에 전달 } //값을 반환받을 때까지 대기 } return (int) msg.wParam;}//// 함수: MyRegisterClass()//// 용도: 창 클래스를 등록합니다.//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; //인스턴스 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJECT62)); //아이콘 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); //커서 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //백그라운드 컬러 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PROJECT62); //메뉴이름 wcex.lpszClassName = szWindowClass; //클래스 이름 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); //작은 아이콘 return RegisterClassExW(&wcex); // 윈도우 클래스 등록}//// 함수: InitInstance(HINSTANCE, int)//// 용도: 인스턴스 핸들을 저장하고 주 창을 만듭니다.//// 주석://// 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고// 주 프로그램 창을 만든 다음 표시합니다.//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다. //화면 해상도 얻기 int nResolutionX = GetSystemMetrics(SM_CXSCREEN); int nResolutionY = GetSystemMetrics(SM_CXSCREEN); //창 화면 띄우 위치 계산 //API의 좌표는 오른쪽으로 향할 수록 X가 커지고 아래쪽을 향할 수록 Y가 커진다. int nWinPosX = (nResolutionX / 2) - (WINSIZEX / 2); int nWinPosY = (nResolutionY / 2) - (WINSIZEY / 2); HWND hWnd = CreateWindowW( szWindowClass, //윈도우 클래스 이름 szTitle, //타이틀 바에 띄우 이름 WS_OVERLAPPEDWINDOW, //윈도우 스타일 nWinPosX, //CW_USEDEFAULT, //윈도우 띄울 화면 좌표x nWinPosY, //윈도우 띄울 화면 좌표y WINSIZEX, //윈도우 가로 사이즈 WINSIZEY, //윈도우 가로 사이즈 nullptr, //부모 윈도우 nullptr, //메뉴 핸들 hInstance, //인스턴스 지정 nullptr); //자식 윈도우를 생성 하면 지정, 그렇지 않으려면 NULL if (!hWnd) { return FALSE; } //윈도우 사이즈 조정 (타이틀 바, 및 메뉴 사이즈, 스크롤 사이즈를 감안해서 계산 //RECT: 1, left, 2. top, 3. width, 4, height RECT rt = { nWinPosX, nWinPosY, nWinPosX + WINSIZEX, nWinPosY + WINSIZEY }; //기준점 다시 계산 // 메뉴바, 타이틀바의 크기를 감안해서 RECT의 크기를 실제 WindowSize로 맞춰줌 // 만약 AdjustWindowRect를 사용하지 않았다면 윈도우의 크기는 메뉴바등을 포함해서 그려지므로, // 작업 공간의 크기는 실제 해상도 보다 작아질 수 있다. AdjustWindowRect(&rt, WS_OVERLAPPEDWINDOW, true); //화면 해상도 다시 얻기 nResolutionX = GetSystemMetrics(SM_CXSCREEN); nResolutionY = GetSystemMetrics(SM_CXSCREEN); //윈도우의 위치를 이동 후 다시 그려줌 MoveWindow(hWnd, nWinPosX, nWinPosY, rt.right - rt.left, rt.bottom - rt.top, TRUE); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;}

//// 함수: WndProc(HWND, UINT, WPARAM, LPARAM)//// 용도: 주 창의 메시지를 처리합니다.//// WM_COMMAND - 애플리케이션 메뉴를 처리합니다.// WM_PAINT - 주 창을 그립니다.// WM_DESTROY - 종료 메시지를 게시하고 반환합니다.////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { 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_CREATE: //타이머를 설정해주는 함수 : 일정 주기마다 메시지를 호출을 하기 위해사용 //1.핸들 2. 타이머 넘버, 3. 호출주기 (1000 == 1초에 한번) SetTimer(hWnd, 1, 10, NULL); //InvalidateRect = { 0, NULL, true }; break; case WM_TIMER: //타이머를 이용해 호출 //1.핸들 2. 다시 그릴 화면의 범위 3, 화면을 지우고 다시 그릴지 아니면 덮어 쓸지 InvalidateRect(hWnd, NULL, true); break;; case WM_KEYDOWN: //키입력받는 선택칸이고, 실행 시킬려면 화면을 지워줘야한다 switch (wParam) { case 'A':case VK_LEFT: ptPos.x = (ptPos.x < 0) ? ptPos.x - 1 : ptPos.x + 15; //ptPos.x - 1 : ptPos.y + 15; 몇칸에 위치할건지 좌표를 바꿔즈는것 break; case 'D' : case VK_RIGHT: ptPos.x = (ptPos.x < 15) ? ptPos.x + 1 : ptPos.x - 15; break; case 'W' : case VK_UP: ptPos.y = (ptPos.y > 0) ? ptPos.y - 1 : ptPos.y + 8; break; case 'S': case VK_DOWN: ptPos.y = (ptPos.y > 15) ? ptPos.y +1 : ptPos.y -8; break; case 'sp': case VK_SPACE: // ptPos = InvalidateRect = { 0, NULL, true }; break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); //Device Context : 출력을 위한 모든 데이터를 가지는 구조체 int roomSIze = WINSIZEY / 9; for (int i = 0; i < 10; i++) { MoveToEx(hdc, 0, i * roomSIze, NULL); //선시작점 LineTo(hdc, WINSIZEX, i * roomSIze); //선긋는거 } for (int i = 0; i < 17; i++) { MoveToEx(hdc, i * roomSIze,0, NULL); //선시작점 LineTo(hdc, i * roomSIze, WINSIZEY); //선긋는거 } int ptX = ptPos.x * roomSIze; int ptY = ptPos.y * roomSIze; Rectangle(hdc, ptX + 10, ptY + 10, ptX + roomSIze - 10, ptY + roomSIze - 10); //틀안에 사각형 그리기 EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}// 정보 대화 상자의 메시지 처리기입니다.INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE;}

// 전역 변수:HINSTANCE hInst; // 현재 인스턴스입니다.WCHAR szTitle[MAX_LOADSTRING] = PROGRAM_TITLE; // 제목 표시줄 텍스트입니다.WCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.POINT ptPos = { 0,0 }; //조작할 죄표의 이동 좌표값

case WM_CREATE: //타이머를 설정해주는 함수 : 일정 주기마다 메시지를 호출을 하기 위해사용 //1.핸들 2. 타이머 넘버, 3. 호출주기 (1000 == 1초에 한번) SetTimer(hWnd, 1, 10, NULL); //InvalidateRect = { 0, NULL, true }; break;case WM_TIMER: //타이머를 이용해 호출 //1.핸들 2. 다시 그릴 화면의 범위 3, 화면을 지우고 다시 그릴지 아니면 덮어 쓸지 InvalidateRect(hWnd, NULL, true); break;;case WM_KEYDOWN: //키입력받는 선택칸이고, 실행 시킬려면 화면을 지워줘야한다 switch (wParam) { case 'A':case VK_LEFT: ptPos.x = (ptPos.x < 0) ? ptPos.x - 1 : ptPos.x + 15; //ptPos.x - 1 : ptPos.y + 15; 몇칸에 위치할건지 좌표를 바꿔즈는것 break; case 'D' : case VK_RIGHT: ptPos.x = (ptPos.x < 15) ? ptPos.x + 1 : ptPos.x - 15; break; case 'W' : case VK_UP: ptPos.y = (ptPos.y > 0) ? ptPos.y - 1 : ptPos.y + 8; break; case 'S': case VK_DOWN: ptPos.y = (ptPos.y > 15) ? ptPos.y +1 : ptPos.y -8; break; case 'sp': case VK_SPACE: // ptPos = InvalidateRect = { 0, NULL, true }; break; }

결과

공감이 글에 공감한 블로거 열고 닫기

댓글쓰기 이 글에 댓글 단 블로거 열고 닫기

인쇄

윈도우 API - 사각형 이동시키기 심화 (2024)
Top Articles
Latest Posts
Article information

Author: Merrill Bechtelar CPA

Last Updated:

Views: 6165

Rating: 5 / 5 (70 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Merrill Bechtelar CPA

Birthday: 1996-05-19

Address: Apt. 114 873 White Lodge, Libbyfurt, CA 93006

Phone: +5983010455207

Job: Legacy Representative

Hobby: Blacksmithing, Urban exploration, Sudoku, Slacklining, Creative writing, Community, Letterboxing

Introduction: My name is Merrill Bechtelar CPA, I am a clean, agreeable, glorious, magnificent, witty, enchanting, comfortable person who loves writing and wants to share my knowledge and understanding with you.