#pragma comment(linker, "/subsystem:windows")
//--------------------------------------------------
#define _WIN32_WINNT 0x0501//
#define WINVER 0x0501//
//--------------------------------------------------
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
static int xPos, yPos;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrev,
LPSTR lpCmdLine,
int nShowCmd)
{
g_hInst = hInstance;
//AllocConsole(); // 콘솔창 생성
// freopen("CONOUT$", //콘솔을
// "wt", //text write모드로
// stdout); //stdoutrhk 연결
//1. 위도우 클래스 만들기 (10가지를 다 정확히 입력하지 않으면 화면이 뜨지 않는다.)
WNDCLASS wc; //미리정의된 10개 항목을 채우는 클래스 (WNDCLASSEX 12개 항목 10개 항목에 작은 아이콘, 구조체 크기를 포함한다.)
MSG Message;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH);
wc.hCursor = LoadCursor ( 0, IDC_CROSS);
wc.hIcon = LoadIcon ( 0, IDI_WINLOGO );
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName= "First";
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
//2. 윈도우 클래스 등록하기.
RegisterClass( & wc ); // 등록을 하는 함수도 2가지가 있다. RegisterClass와 RegisterClassEx가 있다.
//WNDCLASS로 만들었으면 RegisterClass로 등록하고 WNDCLASSEX로 만들었으면 RegisterClassEx로 등록
//3. 등록된 클래스를 사용해서 윈도우 만들기.
// typedef long HWND; // 윈도우의 번호를 담을때 사용
HWND hwnd = CreateWindowEx(0 , // 확장 윈도우 스타일
"First", // 윈도우 클래스 이름
"안녕", // 창이름
WS_OVERLAPPEDWINDOW,// & ~WS_THICKFRAME & ~WS_MAXIMIZE , // 기본 Window Styles : & ~ 연산으로 기존스타일 제거하기
// WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, // X,Y,W:176,H:245
0, // 부모 윈도우 핸들( 번호 )
0, // 메뉴 핸들( 번호 )
hInstance, // 인스턴스 핸들
0); // 생성인자.( MDI 만들때 사용 )
//
//CreateWindowEx는 CreateWindow가 가지는 11개에 확장 윈도우 스타일 1가지 인자를 더 가져서 12가지 인자를 가진다.
//4. 윈도우 보여주기
ShowWindow(hwnd, nShowCmd); // 화면 전체 무효화 - WM_PAINT 발생
UpdateWindow(hwnd); // WM_PAINT 를 즉시 처리
// 반응 속도가 빠른것처럼 보이게 한다.
while(GetMessage(&Message,0,0,0)) //메시지 큐에 가서 메시지를 꺼내오고 가져온 메시지를 윈도우 클래스에 등록된 메세지 처리함수로 전달한다.
{
TranslateMessage(&Message);
DispatchMessage(&Message);//가져온 메시지를 윈도우 클래스에 등록된 메시지 처리함수로 전달한다.
}
MessageBox(0, "알겠나요?","물음",MB_OKCANCEL);//종료되지 않게 하기 위해
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
static HBITMAP hBitmap;
static int bx = 0, by= 0 ,oldbx = 0 , oldby = 0;
switch(iMessage){
//화면에 항상 hello라는 메시지를 보여 주고 싶다. - 어디서 출력?
//- WM_PAINT에서 출력
case WM_ERASEBKGND: // 배경을 안지운다.
SetTimer(hwnd, 1, 10, 0);
return 0;
case WM_TIMER:
{
if(wParam == 1)
{
if(GetAsyncKeyState(VK_LEFT) & 0xFF00)
{
xPos -= 8; InvalidateRect(hwnd, 0, FALSE);
}
if(GetAsyncKeyState(VK_RIGHT) & 0xFF00)
{
xPos += 8; InvalidateRect(hwnd, 0, FALSE);
}
if(GetAsyncKeyState(VK_UP) & 0xFF00)
{
yPos -= 8; InvalidateRect(hwnd, 0, FALSE);
}
if(GetAsyncKeyState(VK_DOWN) & 0xFF00)
{
yPos += 8; InvalidateRect(hwnd, 0, FALSE);
}
}
}
return 0;
case WM_CREATE:
{
HDC hdc = GetDC(hwnd);
hBitmap = CreateCompatibleBitmap(hdc, 1024, 768);
//====================비트맵에 동일하게 그리기
HDC mem = CreateCompatibleDC(hdc);
HBITMAP old = (HBITMAP)SelectObject(mem,hBitmap);
PatBlt(mem, 0,0, 1024,768,BLACKNESS);//비트맵의 기본색상을 검정으로한다.
SelectObject(mem, old);
DeleteDC(mem);
//====================비트맵에 동일하게 그리기
ReleaseDC(hwnd, hdc);
}
return 0;
/*case WM_KEYDOWN:
{
switch(wParam)
{
case VK_LEFT : xPos += 8; break;
case VK_RIGHT : xPos -= 8; break;
case VK_UP : yPos += 8; break;
case VK_DOWN : yPos -= 8; break;
default : return 0;
}
InvalidateRect(hwnd, 0, FALSE);
}
return 0;*/
case WM_LBUTTONDOWN:
{
POINTS pt = MAKEPOINTS(lParam);
HDC hdc = GetDC(hwnd);
Rectangle(hdc, pt.x, pt.y ,pt.x+50, pt.y+50);
//====================비트맵에 동일하게 그리기
HDC mem = CreateCompatibleDC(hdc);
HBITMAP old = (HBITMAP)SelectObject(mem,hBitmap);
Rectangle(mem, pt.x, pt.y, pt.x+50 ,pt.y+50);
SelectObject(mem, old);
DeleteDC(mem);
//====================비트맵에 동일하게 그리기
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
//====================무효화 영역의 크기를 얻는다.
RECT rc = ps.rcPaint;
int w = rc.right - rc.left;
int h = rc.bottom - rc.top;
//====================비트맵에 동일하게 그리기
HDC mem = CreateCompatibleDC(hdc);
HBITMAP old = (HBITMAP)SelectObject(mem,hBitmap);
BitBlt(hdc, xPos,yPos,w,h,mem, rc.left,rc.top, SRCCOPY); // 캡쳐한 비트맵을 화면에 뿌린다.
SelectObject(mem, old);
DeleteDC(mem);
//====================비트맵에 동일하게 그리기
EndPaint(hwnd, &ps);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0 ;
}
return(DefWindowProc(hwnd,iMessage,wParam,lParam));
}