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 정훈승