// TestSDK.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
static char szAppName[] = "Test SDK_버전 1";
static char szTitle[] = "Test SDK 윈도우즈 프로그램";
MSG msg;
HWND hWnd;
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground= GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName= szAppName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
hWnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
return (FALSE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
#include <stdio.h> // sprintf 함수를 이용하기 위해서 include함
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char temp[80];
PAINTSTRUCT ps;
HDC hdc;
static int count;
// uMsg : OS로부터 전달받은 Paramater 변수
switch(uMsg)
{
case WM_CREATE: // Window 생성시 불려지는 Message
count = 0;
break;
case WM_PAINT: // 출력이 필요한 경우 or 출력을 해도 좋다는 Message
hdc = BeginPaint(hWnd, &ps);
strcpy(temp, "Hello world");
// 아래 코드는 WM_PIAINT가 얼마나 자주 호출되는지 보여주는 코드이다.
// 최소화, 최대화 시키면 숫자 증가함(WM_PAINT는 여러번 호출!)
count++;
sprintf(temp, "Count = %d", count);
TextOut(hdc, 50, 50, temp, strlen(temp));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: // Window 종료시
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
/*
WinMain
일반적인것 처리
1. RegisterClassEx로 Application을 등록시킨다.
2. CreateWindow로 Window를 하나 만든 후 ShowWindow로 그 윈도우를 나타낸다.
3. Message Pumping를 시작한다.
WinPorc
strcpy(temp, "Hello world") 부분을 WM_CREATE에서 코딩한후 실행시키면 안된다.
왜냐면 WM_CREATE와 WM_PAINT등등이 호출되는 시기는 서로 다른 시기이기 때문이다.
WM_CREATE에서 strcpy(temp, "Hello world")과 같이 temp변수를 초기화 해도
CALLBACk 함수는 해당 처리를 마친후 바로 리턴을한다. WM_PAINT가 호출 될때 temp
는 다시 로컬 변수로 선언, 사용된다. 때문에 이것을 해결하려면 temp 변수를
static char temp[80] 으로 선언하여 값이 없어지지 않도록 하면 된다.
*) Message들은 <winuser.h>에 정의되어 있다.
*) Message Pumping
WinMain은 CreateWindow로 Window를 생성한 후, Message Pumping를 계속 수행한다.
System에서 발생하는 연속적인 Message(Event)는 Message Queue에 쌓이게 되는데,
Message Pumping이란 이를 Queue에서 하나씩 꺼내어 처리(DispatchMessage)하는 것을 말한다.
*) WinMain이 Entry-Point라면, WndProc 함수는 누가 호출되는 하는가?
WndProc함수는 Event 발생시 OS에 의해 직접 호출되며, 이때 Message 종류와 내용을
Paramater로 전달받는다. 이렇게 OS에 의해 직접 불려지는 함수를 CALLBACK 함수라고 한다.
WinProc가 호출될 함수라는 정보는 사실, WinMain에서 등록할때 이 함수명을 함수 포인터에
전달하기 때문에 가능해진다.
*) WM_CREATE와 WM_PAINT는 각각 별개이나, 이 두 Message 간의 순서는 는 있다. 윈도우가
생성되면 WM CREATE가 호출되며, 그 후 최초에 화면을 Display 하기 위해 WM_PAINT가 호출된다.
*) 프로그램에 필요한(Message 간에 설쳐서 사용되는) 데이타는 static로 선언한다.
*) Window에서 화면에 숫자를 직접 나타낼수 없다. 때문에 sprintf함수를 이용해서 count -> string로 변환
한다. sprintf함수는 printf함수와 유사하며, printf의 내용을 맨 왼쪽 temp string에 넣어준다.
*/