KOREA University/C++2009. 1. 12. 16:08

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

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

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



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


윈도우즈 프로그래밍 프로젝트를 시작하며...

블록게임을 구현해본다.

Version 0.01
- 마우스로 바 조절
- 공은 45도로만 움직임
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 정훈승
KOREA University/C++2008. 12. 28. 16:47
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("Hello world");
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)
{
 switch(iMessage) {
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

윈도우즈프로그래밍(API)의 가장 기본적인 소스다.
흔히 말해 이런걸 Hello world 라고 하지...

학습적인 차원에서 이런건 통째로 외워주는 센스
Posted by 정훈승
KOREA University/C++2008. 12. 7. 12:38

#include <iostream>
using namespace std;

const int MaxSize = 100;

class Set {
private:
 int len; // 집합의 원소개수
 char members[MaxSize]; // 집합을 저장하는 배열
 int find(char ch); // 원소를 찾는다
public:
 Set() { len = 0; } // 공집합 생성자
 int getLength() { return len; } // 집합에 있는 원소의 개수를 반환
 void showset(); // 집합 출력
 bool isMember(char ch); // 집합의 원소인지 검사

 Set operator +(char ch); // 원소 추가
 Set operator -(char ch); // 원소 제거
 Set operator +(Set ob2); // 합집합
 Set operator -(Set ob2); // 차집합
 bool operator <(Set ob2); // 부분집합 확인
 bool operator >(Set ob2); // 부분집합 확인
 Set operator &(Set ob2); // 교집합
 Set operator |(Set ob2); // 대칭차집합
};

int Set::find(char ch) // ch에 명시된 원소의 색인을 찾아서 반환, 없으면 -1를 반환
{
 for (int i=0; i<len; i++) { if(members[i] == ch) return i; }
 return -1;
}

void Set::showset() // 집합의 원소들 출력
{
 cout << "{ ";
 for(int i=0; i<len; i++) { cout << members[i] << " "; }

 cout << "}\n";
}

bool Set::isMember(char ch) // ch가 집합이면 트루, 아니면 폴스
{
 if(find(ch) != -1) return true;
 return false;
}

Set Set::operator +(char ch) // 집합에 유일한 원소 추가
{
 Set newset; // 객체생성
 if(len == MaxSize)
 {
  cout << "Set is Full.\n";
  return *this; // 현재 집합을 반환
 }

 newset = *this; // 현재 집합을 복사

 if(find(ch) == -1) // 추가하려는 원소가 이미 존재하는지 검사하고, 존재하지않으면 추가
 {
  newset.members[newset.len] = ch;
  newset.len++;
 }

 return newset; // 갱신된 집합을 반환
}

Set Set::operator -(char ch) // 집합으로부터 원소 하나 제거
{
 Set newset;
 int i = find(ch); // 원소가 없다면 i는 -1

 for(int j=0; j<len; j++) // 남아있는 원소들을 복사하고 제거된 원소의 빈자리를 채움
 {
  if(j != i) newset = newset+members[j];
 }
 return newset;
}

Set Set::operator +(Set ob2) // 합집합
{
 Set newset = *this; // 첫번째 집합 복사

 for(int i=0; i<ob2.len; i++) { newset = newset + ob2.members[i]; } // 유일한 원소들 추가

 return newset; // 갱신된 집합 반환
}

Set Set::operator -(Set ob2) // 차집합
{
 Set newset = *this; // 첫번째 집합 복사

 for(int i=0; i<ob2.len; i++) newset = newset-ob2.members[i]; // 두번째 집합의 원소들 제거

 return newset; // 갱신된 집합 반환
}

bool Set::operator <(Set ob2) // 좌변의 집합이 우변의 집합의 부분집합인가? 트루 or 폴스
{
 if(len > ob2.len) return false; // ob1의 원소의 개수가 더 많으면 폴스
 for(int i=0; i<len; i++) { if(ob2.find(members[i] == -1)) return false; }

 return true;
}

bool Set::operator >(Set ob2) // 우변의 집합이 좌변의 집합의 부분집합인가? 트루 or 폴스
{
 if(len < ob2.len) return false; // ob1의 원소의 개수가 더 적으면 폴스
 for(int i=0; i<ob2.len; i++) { if(ob2.find(members[i] == -1)) return false; }

 return true;
}

Set Set::operator &(Set ob2) // 교집합
{
 Set newset;

 for(int i=0; i<len; i++)
  if(ob2.find(members[i]) != -1) // 두 집합에 모두 포함되어있는 원소 추가
   newset = newset + members[i];

 return newset;
}

Set Set::operator |(Set ob2) // 대칭차집합
{
 Set newset = *this;

 for(int i=0; i<ob2.len; i++)
 {
  newset = newset + ob2.members[i]; // 일단 합집합을 하고
 }

 Set newset2;

 for(int j=0; j<len; j++)
 {
  if(ob2.find(members[j]) != -1)
  {
   newset2 = newset2 + members[j]; // 합집합 한거에서 교집합 뺀다
   newset = newset - newset2;
  }
 }

 return newset;
}

int main()
{
 Set s1;
 Set s2;
 Set s3; // 공집합 3개 생성

 s1 = s1 + 'A';
 s1 = s1 + 'B';
 s1 = s1 + 'C';

 cout << "s1 after adding A B C: ";
 s1.showset();

 cout << "\n";

 cout << "Testing for membership using isMember().\n";
 if(s1.isMember('B'))
  cout << "B is a member of s1.\n";
 else
  cout << "B is not a member of s1.\n";

 if(s1.isMember('T'))
  cout << "T is a member of s1.\n";
 else
  cout << "T is not a member of s1.\n";

 cout << "\n";

 s1 = s1 - 'B';
 cout << "s1 after s1 = s1 - 'B' : ";
 s1.showset();

 s1 = s1 - 'A';
 cout << "s1 after s1 = s1 - 'A' : ";
 s1.showset();

 s1 = s1 - 'C';
 cout << "s1 after s1 = s1 - 'C' : ";
 s1.showset();

 cout << "\n";

 s1 = s1 + 'A';
 s1 = s1 + 'B';
 s1 = s1 + 'C';
 cout << "s1 after adding A B C: ";
 s1.showset(); // A B C

 cout << "\n- - - - - - - - - - - - - - - - - - - -\n\n";

 s2 = s2 + 'A';
 s2 = s2 + 'X';
 s2 = s2 + 'W';
 cout << "s2 after adding A X W: ";
 s2.showset(); // A X W

 cout << "\n- - - - - - - - - - - - - - - - - - - -\n\n";

 s3 = s1 + s2;
 cout << "s3 after s3 = s1 + s2: ";
 s3.showset(); // A B C W X

 cout << "\n";

 s3 = s3 - s1;
 cout << "s3 after s3 = s3 - s1: ";
 s3.showset(); // X W

 cout << "\n";

 cout << "s2 after s2 = s2 - s2: ";
 s2 = s2 - s2;
 s2.showset(); // s2에서 s2빼니까 아무것도 안남는다
 
 cout << "\n";

 s2 = s2 + 'C';
 s2 = s2 + 'B';
 s2 = s2 + 'A'; // ABC를 역순으로 추가

 cout << "s2 after adding C B A: ";
 s2.showset(); // C B A

 cout << "\n\n━━━━━━━━━━━━━━━━━━━━━━\n\n\n";

 Set s4;
 Set s5;
 Set s6;
 Set s7;

 s4 = s4 + 'A';
 s4 = s4 + 'B';
 s4 = s4 + 'C';
 s4 = s4 + 'D';
 cout << "s4: ";
 s4.showset(); // A B C D

 s5 = s5 + 'B';
 s5 = s5 + 'C';
 s5 = s5 + 'S';
 s5 = s5 + 'P';
 cout << "s5: ";
 s5.showset(); // B C S P

 cout << "\n";

 s6 = s4 & s5;
 cout << "s4와 s5의 교집합: ";
 s6.showset(); // B C

 cout << "\n";

 s7 = s4 | s5;
 cout << "s4와 s5의 대칭차집합 ";
 s7.showset(); // A D S P

 return 0;
}


이런 기초적인 프로그래밍 이론들은
나중에 큰 프로젝트에 디딤돌이 될 것이다...

진짜다 구라 아님 -_-
Posted by 정훈승