프로그래밍 공부
작성일
2023. 6. 14. 21:39
작성자
WDmil
728x90

윈도우 API

 

Microsoft Windows 운영체제에서 개발자가 응용프로그램을 작성할 때 사용하는

응용프로그램 인터페이스(Application Programming Interface)이다.

 

이 API는 Windows 운영체제와 상호작용을 하기 위한 기능을 제공하며, 응용프로그램이 하드웨어

파일시스템 그리고 그래픽등의 리소스에 접근하고 조작할 수 있도록 해준다.


이러한 윈도우 API의 동작방식은 일반적인 함수처럼 동작하며, 다음과 같이 이루어진다.

 

메시지 -> 메시지큐 -> 메시지 루프 -> 윈도우 프로시저


  • 메시지 ( Message )
    • 윈도우간의 통신에 사용되는 데이터 구조
    • 응용 프로그램이나 운영체제로 부터 이벤트에 대한 알림을 받거나 작업을 요청, 응답 받는데 사용된다.
  • 메시지 큐 ( Message Queue)
    • 메시지의 데이터구조를 큐 형태로 보관하는 컨테이너
    • FIFO (선입선출) 구조로 이루어지며, 이벤트에 대한 알림을 받았을때 등 메시지를 대기시키는 컨테이너이다.
  • 메시지 루프 ( Message loop )
    • 메시지를 윈도우 시스템에서 받아온 후, 해당되는 메시지를 알맞은 처리과정으로 전달하는 루프문.
    • while를 통해 구현된다.
  • 윈도우 프로시저 ( WIndow Procedure )
    • 받아온 메시지를 원하는 데이터값으로 처리하기 위한 코드 를 말한다.
    • 메시지에 해당하는 동작을 수행하고 필요한 경우, 조작이나 업데이트 등을 작업하는 코드뭉치이다.

윈도우 함수를 사용하여, 데이터를 처리하게 되는데.

 

이러한 함수를 사용하기 위해 문자열 타입을 지정해주어야 한다.

 

문자열 타입은 다음과 같다.


  1. LPSTR (Long Pointer To a String)
    • LPSTR은 가변적 문자열 데이터를 가리키는 포인터 이다.
    • long pointer str = char*
    • 해당 포인터를 통해 문자열 데이터를 수정하거나 복사, 변경 작업을 수행한다.
    • 주로 ANSI 문자열을 처리하는데 사용된다. [ ANSI 문자열은 1바이트로 각 문자를 표현, 영어 및 일부 특수문자를 표현할 수 있다. ]
  2. LPCSTR ( Long Pointer To a Const String )
    • LPCSTR은 읽기 전용 상수 문자열 데이털르 가리키는 상수 포인터 이다.
    • long pointer const str = const char*
    • 해당 포인터를 통해 문자열 데이터를 수정할 수 없다. 그럼으로 읽기전용으로만 사용되기에. 안전하게 문자열 참조가 가능하다.
    • 주로 ANSI 문자열을 처리하는데 사용되며, 읽거나 출력하는 작업에 활용된다.
  3. LPWSTR ( Long Pointer To a Wide String )
    • LPWSTR은 가변적인 유니코드 문자열 데이터를 가리키는 포인터 이다.
    • long pointer string = wchar_t*
    • 해당 포인터를 통해 문자열 데이터를 수정하고, 복사 변경 하는 작업을 수행할 수 있다.
    • 주로 유니코드 문자열을 처리하는데 사용되며, 다국어 문자 및 특수문자를 수정, 읽기, 출력 작업에 활용된다.
  4. LPCWSTR ( Long Pointer To a Const Wide String )
    • LPCWSTR은 읽기 전용 상수 유니코드 문자열 데이터를 가리키는 상수 포인터 이다.
    • long pointer const string = const wchar_t*
    • 해당 포인터를 통해 문자열 데이터를 수정할 수 없다. 그럼으로 읽기전용으로만 사용되기에. 안전하게 문자열 참조가 가능하다.
    • 주로 유니코드 문자열을 처리하는데 사용되며, 읽거나 출력하는 작업에 활용된다.

이러한 윈도우 API는 다음과 같은 스텍 정리구조를 가진다.

  • STD_CALL
    • 호출당한 함수에서 스텍을 정리한다.

다음은 윈도우 API를 활용하여 빈 화면을 출력하는 코드 예시 이다.

#include <Windows.h>
#include <cassert>
/*
	API : application program interface
	윈도우를 표현하기 위해 사용하는 함수 들의 인터페이스 를 윈도우 API 라고 한다.

	int main은 콘솔을 띄우는 창.
	윈도우 API는 int APIENTRY WinMain 이라고 사용한다.
	
	솔루션 설정 -> 고급 -> 문자집합 -> 멀티바이트 문자집합 으로 변경한다.
	링커 -> 시스템 -> 하위시스템 -> 콘솔 에서 창 으로 변경

*/

LRESULT CALLBACK WndProc(HWND handle, UINT message, WPARAM wparam, LPARAM lParam);

// ENTRY : 여기서부터 진입한다. , WinMain : 윈도우에서 main으로 사용한다.
int APIENTRY WinMain( // 운영체제에서 필요할 때 호출되는 함수
	HINSTANCE hInstance, // 윈도우의 창의 실체를 말한다. 창을 띄우는 자체에 대한 식별자 를 말한다.
	HINSTANCE prevInstace, // 이전에 대한 정보값.
	LPSTR lpszCmdParam, // 문자열. 형식. 헝가리안 표기법 을 사용한다.
	int nCmdShow // cmd : 명령프롬프트.[ command window ] 화면에 어떤식으로 나타낼 것인가. 문자열형태로 나타낼것인가 를 표시한것.
	// 위 항목들은 작성하지 않아도 자동으로 들어간다. nullptr 같은 느낌
)
{
	WNDCLASSA wnd_class; // A : ASCII 윈도우에 지정할것 이라는 의미.

	wnd_class.cbClsExtra = 0;
	wnd_class.cbWndExtra = 0; // 확장된 공간을 사용할 것 인가.
	wnd_class.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); // 백그라운드 색상을 어떻게 사용할 것 인가.
	wnd_class.hCursor = LoadCursor(nullptr, IDC_CROSS); // 커서 모양을 십자가 모양으로 사용하겠다. 라는 의미.
	wnd_class.hIcon = LoadIcon(nullptr, IDI_ERROR); // 프로그램 실행했을 때 작업표시줄에 나타나는 아이콘 모양을 ERROR로 표시할것 이다.
	wnd_class.hInstance = hInstance;
	wnd_class.lpfnWndProc = WndProc; // 윈도우의 포인터와 함수펑션을 연결해주는 역할
	wnd_class.lpszClassName = "First Window"; // 파일화 시켰을 때, 클래스 이름을 정의해주는것.
	wnd_class.lpszMenuName = nullptr; // 메뉴바 를 이야기한다.
	wnd_class.style = CS_HREDRAW | CS_VREDRAW; // 수평 또는 수직이 바뀌었을 때 다시그려준다는 의미.

	RegisterClassA(&wnd_class); // 위 클래스 항목들을 레지스터에 등록하여 이름으로 찾아쓸 수 있다.

	HWND hwnd = CreateWindowA
	(
		"First Window",
		"Hello, Window!",
		WS_OVERLAPPEDWINDOW, // 스타일 중 하나. 여러개중 하나 선택하여 사용가능.
		0, 
		0,
		1080,
		720,
		nullptr, // 윈도우의 부가창을 만드는 것.
		nullptr, // 메뉴
		hInstance,
		nullptr
	); // 화면을 구성하였다.
	
	assert(hwnd != nullptr);

	ShowWindow(hwnd, nCmdShow);
	ShowCursor(TRUE);

	MSG message;
	ZeroMemory(&message, sizeof(MSG)); // 윈도우 메모리 초기화 방식.

	while (GetMessage(&message, nullptr, 0, 0))
	{
		TranslateMessage(&message);
		DispatchMessage(&message);
	}

	DestroyWindow(hwnd); // 윈도우 창 날리기
	UnregisterClassA("First Window", hInstance); // 윈도우 창을 해제해준다.

	return 0;
}

LRESULT CALLBACK WndProc(HWND handle, UINT message, WPARAM wparam, LPARAM lParam)
{
	static POINT position;
	static POINT start;
	static POINT end;
	static BOOL is_clicked = FALSE; // 마우스 클릭 여부 확인.
	
	static RECT rect1 = { 100, 100, 200, 200 };
	static RECT rect2 = { 300, 300, 400, 400 };
	static BOOL is_intersect = FALSE;
	
	switch (message) // 들어온 메세지 처리하는 부분.
	{
	case WM_LBUTTONDOWN:
		MessageBoxA(nullptr, "Helo, WIndow!", "ERROR!!" , MB_OKCANCEL);
		break;
	case WM_CLOSE:
	case WM_DESTROY:
		PostQuitMessage(0); // 메세지에 0 이 들어오면서 윈도우를 종료해준다. 문제가 없으면 0 있으면 1이 리턴된다.
		break;
	default:
		return DefWindowProcA(handle, message, wparam, lParam); // 처리 안한게 있는 상태라면 이곳으로 리턴시킨다.
	}

	return 0;
}

728x90