#include <windows.h>

#define DIVISIONS 5

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR  szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Checker1") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
    
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
    
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("Program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
    
     hwnd = CreateWindow (szAppName, TEXT ("Checker1 Mouse Hit-Test Demo"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
    
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
    
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static int  fState[DIVISIONS][DIVISIONS] ;
     static int  cxBlock, cyBlock, Counting ;
     HDC         hdc ;
     int         x, y ;
     PAINTSTRUCT ps ;
     RECT        rect ;
    
     switch (message)
     {

     case WM_SIZE :
          Counting = 3 ;
          cxBlock = LOWORD (lParam) / DIVISIONS ;
          cyBlock = HIWORD (lParam) / DIVISIONS ;
          return 0 ;
         
     case WM_LBUTTONDOWN :
          Counting++;
          x = LOWORD (lParam) / cxBlock ;
          y = HIWORD (lParam) / cyBlock ;
         
          if (x < DIVISIONS && y < DIVISIONS && !fState [x][y])
          {
               switch(Counting%2)
               {
               case 0 :
                   fState [x][y] ^= 1 ; break;
               case 1:
                   fState [x][y] ^= 2 ; break;
               }

               rect.left   = x * cxBlock ;
               rect.top    = y * cyBlock ;
               rect.right  = (x + 1) * cxBlock ;
               rect.bottom = (y + 1) * cyBlock ;
              
               InvalidateRect (hwnd, &rect, FALSE) ;
          }
          else
               MessageBeep (0) ;
          return 0 ;
         
     case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;
         
          for (x = 0 ; x < DIVISIONS ; x++)
          for (y = 0 ; y < DIVISIONS ; y++)
          {
               Rectangle (hdc, x * cxBlock, y * cyBlock,
                         (x + 1) * cxBlock, (y + 1) * cyBlock) ;
                   
               if (fState [x][y] == 1)
               {
                    MoveToEx (hdc,  x * cxBlock,  y * cyBlock, NULL) ;
                    LineTo   (hdc, (x+1) * cxBlock, (y+1) * cyBlock) ;
                    MoveToEx (hdc,  x * cxBlock, (y+1) * cyBlock, NULL) ;
                    LineTo   (hdc, (x+1) * cxBlock,  y * cyBlock) ;
               }
               if (fState [x][y] == 2)
               {
                    Ellipse (hdc, x * cxBlock, y * cyBlock,
                         (x + 1) * cxBlock, (y + 1) * cyBlock) ;
               }
          }
          EndPaint (hwnd, &ps) ;
          return 0 ;
              
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}



기존 소스는 동그라미만 그려진다.
이 소스가 오델로 게임의 베이스라나...뭐래나....

첫번째 수정은,
한번 그려진 네모칸에는 더이상 그려지지 않고

두번째 수정은,
한번은 동그라미, 한번은 엑스표가 그려지게 하였다.

칸수를 더 늘리고
엑스표를 검은색 동그라미로 바꾸고
오델로 규칙을 적용하면, 오델로 게임이 완성되겠지?
Posted by 정훈승



원, 네모, 선 그리기 과제입니다.
타입을 선택할 수 없으며, 순서대로 그려집니다.
스페이스를 누르면 초기화됩니다.

Counting이라는 변수를 스태틱으로 선언해주고 초기값을 3으로 줍니다.
마우스를 한번 누를때마다 Counting이 1씩 올라갑니다.
Counting++

Counting을 3으로 나눠준 몫의 나머지로 어떤 타입으로 그릴지 정해줍니다.
Switch(Counting%3)

0은 원, 1은 네모, 2는 선

참~~~ 쉽쬬잉
Posted by 정훈승
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    MessageBox(NULL, TEXT("Hello, Windows!"), TEXT("First Message"), 0);
    return 0;
}


프로젝트 생성할때는 반드시 윈도우즈 응용프로그램(Windows 어플리캐이션)으로 해야한다. 1학년때 배우는 C 혹은 C++을 할때, 윈도우즈 콘솔로 프로젝트 생성하는게 버릇이 된사람은 주의를 하도록 하자. PC환경에 따라 상관없을 수도 있겠지만 정석대로 하는게 아무래도 좋지 아니한가
(비주얼6.0, 2005, 2008 상관없다)

가장 기초적인 윈도우즈 프로그래밍을 위한 소스다. 위 소스를 다 입력하면 메시지막스가 튀어나온다. 콘솔창에서만(도스창) 프로그래밍하다가 윈도우로 오면 느낌이 아주 신선하다.

마지막학기에 듣는 윈도우즈프로그래밍 수업이다.
어느정도 할 줄 안다고 자만하지 않고, 최선을 다하겠다. (사실 따지고보면 존나 허접)


교재는 찰스 페졸드의 Programming Windows (5th Edition) 이다. 존나 비싸고 존나 무겁다.
찰스페졸드라는 사람은 빌게이츠와 더불어 실질적인 윈도우즈 개발자라 한다.
실제 윈도우즈 만든 사람이 쓴 책이고, 거기다 출판사도 Microsoft 다. 이 두가지 사실만으로도 간지가 흐르지 아니한가
Posted by 정훈승
KOREA University/C++2009. 1. 12. 16:08

블록 생성하고
점수 계산하고
밑으로 떨어지면 죽고...
바는 마우스클릭된 상태에 움직인다.

문제는 존나 깜빡인다는 것,
더블버퍼링을 책보고 존나 해도 왜 난 잘 안될까...ㅠㅠ

문제가 다음버전에서 해결되길 바라며



Posted by 정훈승
KOREA University/C++2009. 1. 8. 22:28
사용자 삽입 이미지


API로 만든 간단한 예제게임
저 귀여운(?) 얼굴을 클릭하면 카운트가 올라간다.
제한시간은 10초
Posted by 정훈승
KOREA University/C++2009. 1. 3. 16:47
SimplePaint2 와 SimplePaint3 로 알려진 그 문제!!! (한빛미디어 교재)




네이버나 다음이나 구글이나 똑바로 된 소스가 없냐...
이거 푸는데 좀 고생고생했다.
이건 소스공개를 하지 않겠다.
나중에 해피캠퍼스에 올려야지 ㅡㅡ;;;

사용자 삽입 이미지
Posted by 정훈승
KOREA University/C++2009. 1. 1. 19:08
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=TEXT("정훈승 SimplePaint");
enum {ID_R1=101, ID_R2, ID_R3, ID_R4, ID_R5, ID_R6, ID_R7, ID_R8, ID_R9 }; // 색상정보 정의
enum {ID_S1=201, ID_S2, ID_S3, ID_S4, ID_S5 }; // 선굵기정보 정의
HWND r1, r2, r3, r4, r5, r6, r7, r8, r9, s1, s2, s3, s4, s5;
// 핸들값
int Graph=0;
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 HACCEL hAccel;
// 엑셀러레이터를 위해
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 //WndClass.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);;
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1); // 메뉴 추가
 WndClass.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 RegisterClass(&WndClass);
 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 hAccel=LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); // 엑셀러레이터를 위해
 
 while (GetMessage(&Message,NULL,0,0)) {
  if(!TranslateAccelerator(hWnd, hAccel, &Message)) { //
엑셀러레이터를 위해
   TranslateMessage(&Message);
   DispatchMessage(&Message);
  }
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static int sx, sy, oldx, oldy;
// 마우스 현재 위치와 브러쉬 중첩을 위해
 static int jhs;
// case문을 효율적으로 활용하기 위해
 HPEN MyPen, OldPen;
// 펜을 위해
 static COLORREF Color=RGB(0,0,0); // 색상초기값 검정
 static Size=1;
// 선굵기 초기값 1
 static BOOL bNowDraw=FALSE; // 처음엔 선이 안그어지게 설정(마우스를 클릭해야 그어짐)
 
 switch (iMessage) {
 case WM_CREATE:
  CreateWindow(TEXT("button"), TEXT("Color▼"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
   5, 5, 110, 300, hWnd, (HMENU)0, g_hInst, NULL);
  r1=CreateWindow(TEXT("button"), TEXT("검정색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
   10, 20, 100, 30, hWnd, (HMENU)ID_R1, g_hInst, NULL);
  r2=CreateWindow(TEXT("button"), TEXT("빨강색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 50, 100, 30, hWnd, (HMENU)ID_R2, g_hInst, NULL);
  r3=CreateWindow(TEXT("button"), TEXT("파랑색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 80, 100, 30, hWnd, (HMENU)ID_R3, g_hInst, NULL);
  r4=CreateWindow(TEXT("button"), TEXT("초록색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 110, 100, 30, hWnd, (HMENU)ID_R4, g_hInst, NULL);
  r5=CreateWindow(TEXT("button"), TEXT("보라색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 140, 100, 30, hWnd, (HMENU)ID_R5, g_hInst, NULL);
  r6=CreateWindow(TEXT("button"), TEXT("크림슨색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 170, 100, 30, hWnd, (HMENU)ID_R6, g_hInst, NULL);
  r7=CreateWindow(TEXT("button"), TEXT("오렌지색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 200, 100, 30, hWnd, (HMENU)ID_R7, g_hInst, NULL);
  r8=CreateWindow(TEXT("button"), TEXT("분홍색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 230, 100, 30, hWnd, (HMENU)ID_R8, g_hInst, NULL);
  r9=CreateWindow(TEXT("button"), TEXT("황금색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 260, 100, 30, hWnd, (HMENU)ID_R9, g_hInst, NULL);
  CreateWindow(TEXT("button"), TEXT("Size▼"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
   130, 5, 110, 180, hWnd, (HMENU)0, g_hInst, NULL);
  s1=CreateWindow(TEXT("button"), TEXT("선굵기1"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
   135, 20, 100, 30, hWnd, (HMENU)ID_S1, g_hInst, NULL);
  s2=CreateWindow(TEXT("button"), TEXT("선굵기2"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 50, 100, 30, hWnd, (HMENU)ID_S2, g_hInst, NULL);
  s3=CreateWindow(TEXT("button"), TEXT("선굵기3"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 80, 100, 30, hWnd, (HMENU)ID_S3, g_hInst, NULL);
  s4=CreateWindow(TEXT("button"), TEXT("선굵기4"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 110, 100, 30, hWnd, (HMENU)ID_S4, g_hInst, NULL);
  s5=CreateWindow(TEXT("button"), TEXT("선굵기5"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 140, 100, 30, hWnd, (HMENU)ID_S5, g_hInst, NULL);
  CheckRadioButton(hWnd,ID_R1,ID_R9,ID_R1);
  CheckRadioButton(hWnd,ID_S1,ID_S5,ID_S1);
  break;
 case WM_COMMAND:
  switch(LOWORD(wParam)) {
  case ID_R1: Color=RGB(0, 0, 0); break; // 검정색
  case ID_R2: Color=RGB(255, 0, 0); break; // 빨강색
  case ID_R3: Color=RGB(0, 0, 255); break;
// 파랑색
  case ID_R4: Color=RGB(0, 140, 0); break;
// 초록색
  case ID_R5: Color=RGB(130, 0, 130); break;
// 보라색
  case ID_R6: Color=RGB(129, 0, 45); break; // 크림슨색
  case ID_R7: Color=RGB(255, 138, 0); break;
// 오렌지색
  case ID_R8: Color=RGB(255, 100, 255); break; // 분홍색
  case ID_R9: Color=RGB(255, 174, 0); break;
// 황금색
 
  case ID_S1: Size=1; break;
  case ID_S2: Size=2; break;
  case ID_S3: Size=3; break;
  case ID_S4: Size=4; break;
  case ID_S5: Size=5; break;
  case IDM_FILE_MENU1:
   jhs = 1; // case문을 효율적으로 활용하기 위해 임의 숫자를 입력
   MessageBox(hWnd, TEXT("자유곡선을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU2:
   jhs = 2;
   MessageBox(hWnd, TEXT("직선을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU3:
   jhs = 3;
   MessageBox(hWnd, TEXT("원을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU4:
   jhs = 4;
   MessageBox(hWnd, TEXT("사각형을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU5:
   MessageBox(hWnd, TEXT("화면을 초기화합니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   InvalidateRect(hWnd,NULL,TRUE);
   return 0;
  case IDM_FILE_EXIT:
   DestroyWindow(hWnd);
   break;
  case IDM_COLOR1:
   MessageBox(hWnd, TEXT("Black 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(0, 0, 0); return 0;
  case IDM_COLOR2:
   MessageBox(hWnd, TEXT("Red 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 0, 0); return 0;
  case IDM_COLOR3:
   MessageBox(hWnd, TEXT("Blue 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(0, 0, 255); return 0;  
  case IDM_COLOR4:
   MessageBox(hWnd, TEXT("Green 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(0, 140, 0); return 0;  
  case IDM_COLOR5:
   MessageBox(hWnd, TEXT("Violet 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(130, 0, 130); return 0;  
  case IDM_COLOR6:
   MessageBox(hWnd, TEXT("Crimson 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(129, 0, 45); return 0;
  case IDM_COLOR7:
   MessageBox(hWnd, TEXT("Orange 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 138, 0); return 0;
  case IDM_COLOR8:
   MessageBox(hWnd, TEXT("Pink 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 100, 255); return 0;
  case IDM_COLOR9:
   MessageBox(hWnd, TEXT("Gold 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 174, 0); return 0;
  case IDM_SIZE1: MessageBox(hWnd, TEXT("매우 얇게 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=1; return 0;
  case IDM_SIZE2: MessageBox(hWnd, TEXT("얇게  선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=2; return 0;
  case IDM_SIZE3: MessageBox(hWnd, TEXT("보통 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=3; return 0;
  case IDM_SIZE4: MessageBox(hWnd, TEXT("굵게 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=4; return 0;
  case IDM_SIZE5: MessageBox(hWnd, TEXT("매우 굵게 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=5; return 0;
  }
  return 0;
 case WM_LBUTTONDOWN:
  sx = LOWORD(lParam); // 마우스 현재 위치
  sy = HIWORD(lParam);
  oldx = sx;
// 브러쉬 중첩
  oldy = sy;
  bNowDraw = TRUE;
  return 0;
 case WM_MOUSEMOVE:
  if(bNowDraw) {
   hdc = GetDC(hWnd);
   switch(jhs) {
   case 1:
// 자유곡선
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    MoveToEx(hdc, sx, sy, NULL);
    sx=LOWORD(lParam);
    sy=HIWORD(lParam);
    LineTo(hdc, sx, sy);
    SelectObject(hdc, OldPen);
    DeleteObject(MyPen);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 2:
// 선
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    SetROP2(hdc, R2_NOTXORPEN);
    MoveToEx(hdc, sx, sy, NULL);
    LineTo(hdc, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    MoveToEx(hdc, sx ,sy, NULL);
    LineTo(hdc, oldx, oldy);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 3:
// 원
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    SetROP2(hdc, R2_NOTXORPEN);
    Ellipse(hdc, sx, sy, oldx, oldy);
    sx=LOWORD(lParam);
    sy=HIWORD(lParam);
    Ellipse(hdc, sx, sy, oldx, oldy);
    SelectObject(hdc, OldPen);
    DeleteObject(MyPen);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 4:
// 사각형
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    SetROP2(hdc, R2_NOTXORPEN);
    Rectangle(hdc, sx, sy, oldx, oldy);
    sx=LOWORD(lParam);
    sy=HIWORD(lParam);
    Rectangle(hdc, sx, sy, oldx, oldy);
    SelectObject(hdc, OldPen);
    DeleteObject(MyPen);
    ReleaseDC(hWnd, hdc);
    return 0;
   }
   MyPen=CreatePen(PS_SOLID, Size, Color); // 초기값 자유곡선
   OldPen=(HPEN)SelectObject(hdc, MyPen);
   MoveToEx(hdc, sx, sy, NULL);
   sx=LOWORD(lParam);
   sy=HIWORD(lParam);
   LineTo(hdc, sx, sy);
   SelectObject(hdc, OldPen);
   DeleteObject(MyPen);
   ReleaseDC(hWnd, hdc);
  }
  return 0;
 
 case WM_LBUTTONUP:
  bNowDraw = FALSE; // 마우스를 땠을 때 선 안그어짐
  hdc = GetDC(hWnd);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);
  TextOut(hdc, 1, 320, TEXT("ㆍ초기값 : 자유곡선, 매우 얇게"), 30);
  TextOut(hdc, 1, 345, TEXT("ㆍ자유곡선 선택 : Ctrl+I"), 24);
  TextOut(hdc, 1, 370, TEXT("ㆍ직선 선택 : Ctrl+L    "), 24);
  TextOut(hdc, 1, 395, TEXT("ㆍ원 선택 : Ctrl+E      "), 24);
  TextOut(hdc, 1, 420, TEXT("ㆍ사각형 선택 : Ctrl+R  "), 24);
  TextOut(hdc, 1, 445, TEXT("ㆍ화면 초기화 : Ctrl+S  "), 24);
  TextOut(hdc, 1, 470, TEXT("ㆍ프로그램 종료 : Ctrl+X"), 24);
  EndPaint(hWnd, &ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

SimplePaint 문제로 유명한 그 소스의 해답이라고 말하고 싶다.


첨보는 사람은 그냥 존나 긴~ 쏘스라고만 생각하겠지만
차근차근 공부하면 뭔말인지 다 이해가 감
리소스 추가는 셀프^^
Posted by 정훈승
KOREA University/C++2008. 12. 28. 17:01
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("정훈승 자유주제3");
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&WndClass);
 hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
 ShowWindow(hWnd, nCmdShow);
 while(GetMessage(&Message, NULL, 0, 0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 int i, j;
 static int sx, sy;
 switch(iMessage) {
 case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);
  for(i=0; i<768; i=i+17)
  {
   MoveToEx(hdc,0,i,NULL);
   LineTo(hdc,1024,i);
  }
  for(j=0; j<1024; j=j+17)
  {
   MoveToEx(hdc,j,0,NULL);
   LineTo(hdc,j,768);
  }
  EndPaint(hWnd, &ps);
  return 0;
 case WM_LBUTTONDOWN:
  hdc=GetDC(hWnd);
  sx=LOWORD(lParam);
  sy=HIWORD(lParam);
  TextOut(hdc, sx, sy, TEXT("●"), 2);
  ReleaseDC(hWnd, hdc);
  return 0;
 case WM_RBUTTONDOWN:
  hdc=GetDC(hWnd);
  sx=LOWORD(lParam);
  sy=HIWORD(lParam);
  TextOut(hdc, sx, sy, TEXT("○"), 2);
  ReleaseDC(hWnd, hdc);
  return 0;
 
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

이 소스는 아주 간단한 소스다.
내가 짰으면서도 너무 아이디어가 기발-_-해서 공유한다.

윈도우즈프로그래밍(API) 초반부 단계 숙제용으로 탁월한 예가 될 것이다.

화면에 바둑판을 그려놓고
왼쪽버튼 누르면 검정색돌, 오른쪽버튼 누르면 흰색돌

아주 기초적인 지식으로 이따구 것을 만들어서 숙제 제출하면
아마 담당 교수님이나 담당 강의선생생님께 칭찬을 들을것이라 예상된다.
Posted by 정훈승
KOREA University/C++2008. 12. 28. 16:56
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=TEXT("정훈승 RopMode2");
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 HACCEL hAccel; // 엑셀러레이터를 위해
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1); // 메뉴 추가
 WndClass.style=CS_HREDRAW | CS_VREDRAW;
 RegisterClass(&WndClass);
 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 hAccel=LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); // 엑셀러레이터를 위해
 
 while (GetMessage(&Message,NULL,0,0)) {
  if(!TranslateAccelerator(hWnd, hAccel, &Message)) { // 엑셀러레이터를 위해
   TranslateMessage(&Message);
   DispatchMessage(&Message);
  }
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 static int sx, sy, oldx, oldy; // 마우스 현재 위치와 브러쉬 중첩을 위해
 static BOOL bNowDraw = FALSE;
 HDC hdc;
 static int jhs; // case문을 효율적으로 활용하기 위해
 HBRUSH MyBrush, OldBrush; // 브러쉬를 위해
 switch (iMessage) {
 case WM_COMMAND:
  switch(LOWORD(wParam)) {
  case IDM_FILE_MENU1:
   jhs = 1; // case문을 효율적으로 활용하기 위해 임의 숫자를 입력
   MessageBox(hWnd, TEXT("자유곡선을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_MENU2:
   jhs = 2;
   MessageBox(hWnd, TEXT("선을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_MENU3:
   jhs = 3;
   MessageBox(hWnd, TEXT("원을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_MENU4:
   jhs = 4;
   MessageBox(hWnd, TEXT("사각형을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_EXIT:
   DestroyWindow(hWnd);
   break;
  }
 case WM_LBUTTONDOWN:
  sx = LOWORD(lParam); // 마우스 현재 위치
  sy = HIWORD(lParam);
  oldx = sx; // 브러쉬 중첩
  oldy = sy;
  bNowDraw = TRUE;
  return 0;
 case WM_MOUSEMOVE:
  if(bNowDraw) {
   hdc = GetDC(hWnd);
   switch(jhs) {
   case 1: // 자유곡선
    MoveToEx(hdc, sx, sy, NULL);
    sx = LOWORD(lParam);
    sy = HIWORD(lParam);
    LineTo(hdc, sx, sy);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 2: // 선
    SetROP2(hdc, R2_NOT);
    MoveToEx(hdc, sx, sy, NULL);
    LineTo(hdc, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    MoveToEx(hdc, sx ,sy, NULL);
    LineTo(hdc, oldx, oldy);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 3: // 원
    MyBrush = CreateSolidBrush(RGB(0,0,0));
    OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
    SetROP2(hdc, R2_NOT);
    SelectObject(hdc,GetStockObject(NULL_BRUSH));
    Ellipse(hdc, sx, sy, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    Ellipse(hdc, sx, sy, oldx, oldy);
    DeleteObject(SelectObject(hdc, OldBrush));
    ReleaseDC(hWnd, hdc);
    return 0;
   case 4: // 사각형
    MyBrush = CreateSolidBrush(RGB(0,0,0));
    OldBrush = (HBRUSH)SelectObject(hdc,MyBrush);
    SetROP2(hdc, R2_NOT);
    SelectObject(hdc,GetStockObject(NULL_BRUSH));
    Rectangle(hdc, sx, sy, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    Rectangle(hdc, sx, sy, oldx, oldy);
    DeleteObject(SelectObject(hdc, OldBrush));
    ReleaseDC(hWnd, hdc);
    return 0;
   }
   return 0;
  }
 case WM_LBUTTONUP:
  bNowDraw = FALSE; // 마우스를 땠을 때 선 안그어짐
  hdc = GetDC(hWnd);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


RopMode2 로 자~알 알려진 그 문제다.

메뉴에서 해당 그리기모드로 선택하면 그 그리기모드가 된다.

1. 자유곡선
2. 그냥 선
3. 원
4. 사각형

이렇게 4가지 모드를 지원하고, 각 모드는 단축키가 있다.

네이버에 이거 구라쏘스 존나 많던데,
내 쏘스 본사람은 행운아

※ 내 소스가 드래그가 안되서 Ctrl+C, Ctrl+V 신공이 안먹혀서 욕을 할 수도 있겠지만,
나는 프로그래밍 소스는 직접 쳐봐야 한다는 신념을 가지고 있다.
한번쯤 직접 쳐보고, 오타 수정하면서 해야 실력이 일취월장 할 것이다.
Posted by 정훈승
KOREA University/C++2008. 12. 28. 16:51
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("keydown2");
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&WndClass);
 hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
 ShowWindow(hWnd, nCmdShow);
 while(GetMessage(&Message, NULL, 0, 0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static int x=100;
 static int y=100;
 static TCHAR str[256]={'A'};
 
 switch(iMessage) {
 case WM_KEYDOWN:
  switch(wParam) {
  case VK_LEFT: x-=8; break;
  case VK_RIGHT: x+=8; break;
  case VK_UP:  y-=8; break;
  case VK_DOWN: y+=8; break;
  case VK_SPACE: // 여기부터
   if(str[0]=='A')
   {
    str[0]='#';
   }
   else
   {
    str[0]='A';
   } // 여기까지가 키포인트
  }
  InvalidateRect(hWnd,NULL,TRUE);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  TextOut(hdc,x,y,str,lstrlen(str));
  EndPaint(hWnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

KeyDown2 문제로 유명한 그 문제

스페이스 누르면 A에서 #으로 바뀐다. 그리고 다시 스페이스 누르면 #에서 A로 다시...

2년전에 MFC를 존나 공부한적이 있었는데, 그때 쫌 해놨더니
API공부하고 있는 요즘, 존나 수월하게 진도가 나가고 있다.
Posted by 정훈승