#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// Foward declarations of functions included in this code module:
// 함수, 코드 모듈 선언.
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
//윈도우 메인
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
/*
+ hInstance 프로그램의 인스턴스 핸들
+ hPrevInstance 바로 앞에 실행된 현재 프로그램의 인스턴스 핸들.
없을 경우는 NULL이 되며 WIN32에서는 항상 NULL이다.
호환성을 위해서만 존재하는 인수이므로 신경쓰지 않아도 된다.
+ lpCmdLine 명령행으로 입력된 프로그램 인수이다. 도스의 argv인수에 해당한다.
+ nCmdShow 프로그램이 실행될 형태이며 최소화, 보통모양 등이 전달된다.
*/
{
// TODO: Place code here.
MSG msg; //구조체 : 시스템의 변화에 대한 정보 저장 (메시지)
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
//LoadString : 리소스에서 문자열을 읽어 지정한 메모리에 채워준다
LoadString(hInstance, IDC_CH_2, szWindowClass, MAX_LOADSTRING);
//클래스를 기록하다.
MyRegisterClass(hInstance);
//초기화
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
//액셀러레이터 테이블의 핸들들
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CH_2);
/*
LoadAccelerators :
응용 프로그램의 리소스에 정의된 액셀러레이터 테이블을 읽어온다.
액셀러레이터 테이블은 응용 프로그램이 사용하는 단축키의 목록을 가지는 리소스이다.
이 함수로 읽어온 액셀러레이터 테이블은 메시지 루프에서 TranslateAccelerator 함수에 의해 해석되어
WM_COMMAND 메시지로 변환된다. 이 함수로 읽어온 액셀러레이터 테이블은 응용 프로그램이 종료될 때
자동으로 파괴되므로 직접 파괴해주지 않아도 된다.
*/
// 메세지 루프문
while (GetMessage(&msg, NULL, 0, 0)) //메시지 전달
//메시지 큐(발생된 메시지가 잠시 대기. 임시저장 영역)에서 메시지를 읽어들인다.
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg); //키보드의 눌림 메시지가 발생할 때 문자가 입력되었다는 메시지를 만드는역할
DispatchMessage(&msg); //큐에서 꺼낸 메시지를 프로그램의 메시지 처리 함수(WndProc)로 전달한다
}
}
return msg.wParam;
//wParam, lParam : 전달된 메시지에 대한 부가적인 정보를 가진다. 메시지 별로 다르다.
}
ATOM MyRegisterClass(HINSTANCE hInstance) //윈도우 클래스 등록
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; //윈도우가 어떤 형태를 가질 것인가를 지정하는 멤버
wcex.lpfnWndProc = (WNDPROC)WndProc; //이 멤버는 윈도우의 메시지 처리 함수를 지정한다.
// 메시지가 발생할 때마다 여기서 지정한 함수가 호출되며
// 이 함수가 모든 메시지를 처리한다
wcex.cbClsExtra = 0; //윈도우즈가 내부적으로 사용하며 아주 특수한 목적에
wcex.cbWndExtra = 0; //사용되는 여분의 공간
wcex.hInstance = hInstance; //윈도우 클래스를 등록하는 프로그램의 번호 (winmain에서의 값을 그대로 대입)
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_CH_2); //윈도우가 사용할 마우스 커서와 아이콘을 지정
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //윈도우 배경 색상을 채색할 브러시를 지정하는 멤버
wcex.lpszMenuName = (LPCSTR)IDC_CH_2; //이 프로그램이 사용할 메뉴를 지정한다(메뉴 사용하지않을 경우 null대임)
wcex.lpszClassName = szWindowClass; //윈도우 클래스의 이름을 정의한다(CreatWindow함수에서 이를 참조하여 윈도우를 만든다.)
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, //윈도우 생성
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
//IpszClassName : 생성하고자 하는 윈도우의 클래스를 지정하는 문자열
//IpszWindowName : 타이틀 바에 나타날 문자열
//dwStyle : 윈도우 형태 지정
//X,Y, nWidth, nHeiget : 윈도우의 크기와 위치를 지정 (CW_USEDEFAULT: 윈도우가 화면 크기에 맞게 적당히 크기와 위치 설정)
//hWndParent : 부모 윈도우의 핸들 지정 (없을 경우 NULL)
//hmenu : 메뉴의 핸들 지정
//hInst : 프로그램의 핸들 지정 (WinMain에서 hInstance 대입)
//IpvParam : CREATESTRUCT 구조체의 번지. 특수 목적에 사용, 보통 NULL 사용
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow); //윈도우 보여주기
UpdateWindow(hWnd); //보여준거 뒤의 가려진부분을 윈도우에 알려줌
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
//운영체제에 의해 호출되는 응용 프로그램내의 함수를 콜백(CallBack) 함수
//메시지 처리하는부분
//hWnd : 메시지를 받을 윈도우의 핸들
//iMessage : 어떤 종류의 메시지인가, 어떤변화가 발생했는가에 대한 정보
//wParam, ;Param : iMessage의 메시지에 따른 부가적인 정보를 가진다.
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
static int x;
static int y;
static BOOL bnowDraw=FALSE;
//WndProc은 메시지 처리 했을 경우 반드시 0을 리턴해야한다.
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT: //화면을 다시 그려야 할 필요가 있을 때 발생한다.
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt); //윈도우의 좌표를 구해준다.
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //윈도우가 메모리에서 파괴될 때 발생한다.
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN: //마우스 왼쪽 버튼을 누를때 발생
x=LOWORD(lParam);
y=HIWORD(lParam);
bnowDraw=TRUE;
return 0;
case WM_MOUSEMOVE: //마우스를 움직일 떄 발생
if (bnowDraw==TRUE) {
hdc=GetDC(hWnd);
MoveToEx(hdc,x,y,NULL);
x=LOWORD(lParam);
y=HIWORD(lParam);
LineTo(hdc,x,y);
ReleaseDC(hWnd,hdc);
}
return 0;
case WM_LBUTTONUP: //마우스 오른쪽 버튼을 올렸을 때 발생
bnowDraw=FALSE;
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam); //설정된값이외에는 디폴트값으로 넘겨준다
//DefWindowProc : 시스템 메뉴를 더블클릭하거나 Alt+f4를 누르면 프로그램이 종료된다.
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam)); //DialogBox등의 함수로 생성한 대화상자를 종료한다
return TRUE;
}
break;
}
return FALSE;
}