5월14일C++(다중상속,virtual로 접근) API(그래픽...)

2010. 5. 14. 16:532010년/5월


class Tico
{
  publuc:
      car a;
}
클래스안에 클래스르 넣으면 어떻게 될까~?
객체는 상속을 받을수가 있고 단일 객체도 있고 객체들이 모아놓은 객체도 있다.
그래서 객체안에 객체를 하나 구성으로 사용하여  클래스를 사용할수 있다;
상속도 다중상속도 있다. 우리가 어제까지 한 것은 단일 상속이다.
Tip....Java는 단인상속만 가능하다~
class Tico : public car,test,


보다시피 SCA클래스에 iPrice 변수를 하나 생성했고 TIco가 다중상속을 받았다. 그리고 car클래스에서 iPrice와 SCA클래스의iPrice가 같다. 그래서  어느 클래스의 iPrice를 사용할때 스코프(::) 해야한다.
Tip 자바에서 스코프를 extends<== 씀

다음은 Tico 클래스안에 car클래스와 같은 State()함수를 만들었다 그리고... main에서  포인터로 지정해서 car *와 Tico *를 생성후에 State()를 불렀다.







포인터같은경우 만들경우  Tico 포인터를 만든거와 car의 포인터를 만든것의 차이점이 위에 그림과 같다.  그래서 둘다 State()를 찍어줄경우 Tico는 Tico의 State를 출력해주고 car는 car의 State를 출력해준다.
그러면 각 클래스가 틀리기때문에 포인터는 각클래스의 State를 출력해준다. 포인터의 위대함~
tip . 객체를 배열로 생성가능~ 그럼 생성자와 소멸자도 배열의 크기만큼 호출함 ㅠ




어렵게 생각하면 어려운데 간단하게 생각하면 쉽다.
클래스 포인터를 생성시 부모 포인터와 자식 포인터경우 부모포인터에서는 자식을 값을 넣을수 있다 이는 자식클래스가 부모클래스도 상속받고 자식클래스가 있기때문에 할수있다
하지만 자식포인터는 부모클래스를 가르킬수없다 이는 상속은 받았지만 부모클래스에서는 자식클래스정보가없다 그래서 안된다.


====================================================================================
==================================virtual============================================
====================================================================================

부모와 자식을 클래스를 기반으로 할경우 제일 중요한 기법이 있다 이는 아까 했던 부모 클래스 포인터같은경우는 상속된 자식클래스의 모든 곳을 접근할수 있다 그래서 상속된 자식이 많은경우 부모클래스포인터는 아주 절대적인 힘을 가지게 된다. 하지만 단점이 있다. 큰단점은 바로 부모클래스와 자식클래스 같은 이름이 같은 함수있을경우 접근할경우 결국에는 부모클래스의 객체만 보게 된다. 이것을 벗어나기위해서 하는 바로 virtual 이라는 것이다. 이것을 사용할경우 부모클래스의 포인터가 어떤 객체든 전부 다 접근하고 볼수있다. 아주 강력하다.
tip. Java같은경우 이런 부모클래스중에 최상위 클래스를 object라는 이름으로 구현하여 보다 쉽게 최근만든 클래스까지 접근해서 사용가능.
====================


동적할당이다 빨간줄이 있는 경우는 C에서의 동적할당이다 그래서 malloc로 사용하고 free로 반환을 했다 그리고 컴파일 돌렸는데... 클래스 A의  생성자가 호출되지 않는다.


하지만 C++에서 메모리 할당인 new와 delete를 했을경우 생성자가 생성되었다.. 이것의 차이가 무엇일까"?


객체를 동적할당할경우 malloc를 사용하지 말라는것이다. 생성자가 없으니깐..
개인적으로 봤을때 객체라는 개념이 c++이후로 나왔기때문에 기존의 C에서 사용하는 동적할당인 malloc보다 new 사용하라는것 같다.




자 동적할당을 배열로 10개를 생성했다.
뭐 간단하다. 몇개 선언할것인지 배열로 10적어주고
그냥 deleta할때는 [] 아무것도 적어주지않고 배열 닫아 주기하면 된다.
















tip> 함수 포인터 .....

팁이라기보단  잘몰랐던 사실이다.  기본적으로 함수를 포인터로 사용할때 void test() 함수가 원형이다 그럼 이함수를 받기 위해서 포인터르 원형..










===================================================================
===================================================================
#include<windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
HINSTANCE g_hlnst;    //전역변수
HWND hWndMain;
LPCTSTR lpszClass=TEXT("Class");//전역변수, 윈도우클래스를 정의하는데 사용, 타이틀바에 표시됨.

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevlnstance,LPSTR lpszCmdParam, int nCmdShow)
//엔트리포인트는 main()이 아니라 WinMain(),이다.
//윈도우를 만들고 화면에 표시하기만 할 뿐, 대부분의 일은 아래의 함수에서 이루어진다.
//WinMain에서 하는 가장 중요한 일은 메인 윈도우를 만드는 일이다.
{

  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;//만들어질 윈도우의 여러가지 특성을 정의하는 구조체
  g_hlnst=hInstance;//메인함수의 첫번째 인자인 hInstance를 전역변수에 대입

  WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
  WndClass.cbWndExtra=0;//않을 때는 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; //윈도우의 메시지 처리함수를 지정(여기는 WndProc)
  WndClass.lpszClassName=lpszClass;//이름지정, 전역변수를 대입하므로 "First"가 들어감
  WndClass.lpszMenuName=NULL;//메뉴지정, NULL이므로 생략
  WndClass.style=CS_HREDRAW|CS_VREDRAW;  //윈도우의 스타일 정의
  RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
  //윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.
  
  hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL|WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,
    CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
  //등록된 클래스를 기본으로 실제 윈도우 생성(메모리에 진입)
  //이 함수의 인자들은 위에서 등록한 내용들이 각각의 인자로 들어온다.
  //이 함수는 윈도우에 관한 모든 정보를 메모리에 만든후 대표 번호인 윈도우 핸들을 반환한다.
  
  ShowWindow(hWnd,nCmdShow); //화면에 출력하는 함수. //첫번째 인자는 출력하고자 하는 윈도
  //우의 핸들이며 CreateWindow함수가 리턴한 값이다. 두번째 인자는 출력하는 방법 지정.

  //아래의 While문은 프로그램 메시지를 처리하는 부분이다.
  while(GetMessage(&Message,NULL,0,0)) //메시지를 읽어들여서 false가 리턴될때 까지 반복
  {
    TranslateMessage(&Message); //키보드에 이벤트가 발생하면 그 것을 나타 내 준다.
    DispatchMessage(&Message);  //받은 메시지를 WndProc함수로 전달한다
          //그러면 그 함수에서 메시지를 점검하여 동작하게 된다.
  }
  return (int)Message.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam, LPARAM lParam)
//사용자와 시스템이 보내오는 메시지를 처리하는 함수. (운영체제에 의해 호출)
{
  HDC hdc;
  PAINTSTRUCT ps;
  HBRUSH MyBrush,OldBrush;
  HPEN MyPen, OldPen;
  switch (iMessage) 
  {
  case WM_CREATE:
    hWndMain=hWnd;
    return 0;
  case WM_PAINT:
    hdc=BeginPaint(hWnd,&ps);
  
  //  MyBrush=(HBRUSH)GetStockObject(GRAY_BRUSH); //윈도우가 제공하는 브러쉬사용
  //  OldBrush=(HBRUSH)SelectObject(hdc,MyBrush); //DC에 선택 
  //  MyPen=(HPEN)GetStockObject(WHITE_PEN);  
    MyBrush=CreateHatchBrush(HS_DIAGCROSS,RGB(255,50,255));
    OldBrush=(HBRUSH)SelectObject(hdc,MyBrush);
    MyPen=CreatePen(PS_SOLID,1,RGB(0,0,255));  
    OldPen=(HPEN)SelectObject(hdc,MyPen);
    
    Rectangle(hdc,50,50,300,200);
    
    SelectObject(hdc,OldBrush);
    SelectObject(hdc,OldPen);
    DeleteObject(MyPen);
    DeleteObject(MyBrush);
    EndPaint(hWnd,&ps);
    return 0;
  case WM_DESTROY:   //사용자가 프로그램을 끝내려고 한다면
    PostQuitMessage(0);//이 함수를 호출하여 &message에 FALSE를 리턴한다.
    return 0;


  }
  return(DefWindowProc(hWnd,iMessage,wParam,lParam));//실제로 각 이벤트들이
      //수행되는 부분이다. (default이므로 별다른 코드가 필요없다.)
}
===============================================================
===============================================================
#include<windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
HINSTANCE g_hlnst;    //전역변수
HWND hWndMain;
LPCTSTR lpszClass=TEXT("Class");//전역변수, 윈도우클래스를 정의하는데 사용, 타이틀바에 표시됨.

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevlnstance,LPSTR lpszCmdParam, int nCmdShow)
//엔트리포인트는 main()이 아니라 WinMain(),이다.
//윈도우를 만들고 화면에 표시하기만 할 뿐, 대부분의 일은 아래의 함수에서 이루어진다.
//WinMain에서 하는 가장 중요한 일은 메인 윈도우를 만드는 일이다.
{

  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;//만들어질 윈도우의 여러가지 특성을 정의하는 구조체
  g_hlnst=hInstance;//메인함수의 첫번째 인자인 hInstance를 전역변수에 대입

  WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
  WndClass.cbWndExtra=0;//않을 때는 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; //윈도우의 메시지 처리함수를 지정(여기는 WndProc)
  WndClass.lpszClassName=lpszClass;//이름지정, 전역변수를 대입하므로 "First"가 들어감
  WndClass.lpszMenuName=NULL;//메뉴지정, NULL이므로 생략
  WndClass.style=CS_HREDRAW|CS_VREDRAW;  //윈도우의 스타일 정의
  RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
  //윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.
  
  hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL|WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,
    CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
  //등록된 클래스를 기본으로 실제 윈도우 생성(메모리에 진입)
  //이 함수의 인자들은 위에서 등록한 내용들이 각각의 인자로 들어온다.
  //이 함수는 윈도우에 관한 모든 정보를 메모리에 만든후 대표 번호인 윈도우 핸들을 반환한다.
  
  ShowWindow(hWnd,nCmdShow); //화면에 출력하는 함수. //첫번째 인자는 출력하고자 하는 윈도
  //우의 핸들이며 CreateWindow함수가 리턴한 값이다. 두번째 인자는 출력하는 방법 지정.

  //아래의 While문은 프로그램 메시지를 처리하는 부분이다.
  while(GetMessage(&Message,NULL,0,0)) //메시지를 읽어들여서 false가 리턴될때 까지 반복
  {
    TranslateMessage(&Message); //키보드에 이벤트가 발생하면 그 것을 나타 내 준다.
    DispatchMessage(&Message);  //받은 메시지를 WndProc함수로 전달한다
          //그러면 그 함수에서 메시지를 점검하여 동작하게 된다.
  }
  return (int)Message.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam, LPARAM lParam)
//사용자와 시스템이 보내오는 메시지를 처리하는 함수. (운영체제에 의해 호출)
{
  HDC hdc;
  PAINTSTRUCT ps;
  HBRUSH MyBrush,OldBrush;
  HPEN MyPen, OldPen;
  switch (iMessage) 
  {
  case WM_CREATE:
    hWndMain=hWnd;
    return 0;
  case WM_PAINT:
    hdc=BeginPaint(hWnd,&ps);
  
  //  MyBrush=(HBRUSH)GetStockObject(GRAY_BRUSH); //윈도우가 제공하는 브러쉬사용
  //  OldBrush=(HBRUSH)SelectObject(hdc,MyBrush); //DC에 선택 
  //  MyPen=(HPEN)GetStockObject(WHITE_PEN);  
    MyBrush=CreateHatchBrush(HS_DIAGCROSS,RGB(255,50,255));
    OldBrush=(HBRUSH)SelectObject(hdc,MyBrush);
    MyPen=CreatePen(PS_SOLID,1,RGB(0,0,255));  
    OldPen=(HPEN)SelectObject(hdc,MyPen);
    
    Rectangle(hdc,50,50,300,200);
    
    SelectObject(hdc,OldBrush);
    SelectObject(hdc,OldPen);
    DeleteObject(MyPen);
    DeleteObject(MyBrush);
    EndPaint(hWnd,&ps);
    return 0;
  case WM_DESTROY:   //사용자가 프로그램을 끝내려고 한다면
    PostQuitMessage(0);//이 함수를 호출하여 &message에 FALSE를 리턴한다.
    return 0;


  }
  return(DefWindowProc(hWnd,iMessage,wParam,lParam));//실제로 각 이벤트들이
      //수행되는 부분이다. (default이므로 별다른 코드가 필요없다.)
}
===============================================================
==============================================================
#include<windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
HINSTANCE g_hlnst;    //전역변수
HWND hWndMain;
LPCTSTR lpszClass=TEXT("Class");//전역변수, 윈도우클래스를 정의하는데 사용, 타이틀바에 표시됨.

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevlnstance,LPSTR lpszCmdParam, int nCmdShow)
//엔트리포인트는 main()이 아니라 WinMain(),이다.
//윈도우를 만들고 화면에 표시하기만 할 뿐, 대부분의 일은 아래의 함수에서 이루어진다.
//WinMain에서 하는 가장 중요한 일은 메인 윈도우를 만드는 일이다.
{

  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;//만들어질 윈도우의 여러가지 특성을 정의하는 구조체
  g_hlnst=hInstance;//메인함수의 첫번째 인자인 hInstance를 전역변수에 대입

  WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
  WndClass.cbWndExtra=0;//않을 때는 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; //윈도우의 메시지 처리함수를 지정(여기는 WndProc)
  WndClass.lpszClassName=lpszClass;//이름지정, 전역변수를 대입하므로 "First"가 들어감
  WndClass.lpszMenuName=NULL;//메뉴지정, NULL이므로 생략
  WndClass.style=CS_HREDRAW|CS_VREDRAW;  //윈도우의 스타일 정의
  RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
  //윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.
  
  hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL|WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,
    600,450, NULL,(HMENU)NULL,hInstance,NULL);
  //등록된 클래스를 기본으로 실제 윈도우 생성(메모리에 진입)
  //이 함수의 인자들은 위에서 등록한 내용들이 각각의 인자로 들어온다.
  //이 함수는 윈도우에 관한 모든 정보를 메모리에 만든후 대표 번호인 윈도우 핸들을 반환한다.
  
  ShowWindow(hWnd,nCmdShow); //화면에 출력하는 함수. //첫번째 인자는 출력하고자 하는 윈도
  //우의 핸들이며 CreateWindow함수가 리턴한 값이다. 두번째 인자는 출력하는 방법 지정.

  //아래의 While문은 프로그램 메시지를 처리하는 부분이다.
  while(GetMessage(&Message,NULL,0,0)) //메시지를 읽어들여서 false가 리턴될때 까지 반복
  {
    TranslateMessage(&Message); //키보드에 이벤트가 발생하면 그 것을 나타 내 준다.
    DispatchMessage(&Message);  //받은 메시지를 WndProc함수로 전달한다
          //그러면 그 함수에서 메시지를 점검하여 동작하게 된다.
  }
  return (int)Message.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam, LPARAM lParam)
//사용자와 시스템이 보내오는 메시지를 처리하는 함수. (운영체제에 의해 호출)
{
  HDC hdc;
  PAINTSTRUCT ps;
  int i;
  HBRUSH MyBrush,OldBrush;
  HPEN MyPen,OldPen;
  switch (iMessage) 
  {
  case WM_PAINT:
    hdc=BeginPaint(hWnd,&ps);
    for(i=0;i<600;i+=4)
    {
      MoveToEx(hdc,0,i,NULL);
      LineTo(hdc,600,i);

    }  
    for(i=0;i<600;i+=4)
    {
      MoveToEx(hdc,i,0,NULL);
      LineTo(hdc,i,600);

    }  
    MyBrush=CreateSolidBrush(RGB(0,255,0));
    OldBrush=(HBRUSH)SelectObject(hdc,MyBrush);
    MyPen=CreatePen(PS_SOLID,5,RGB(255,0,0));
    OldPen=(HPEN)SelectObject(hdc,MyPen);
    Ellipse(hdc,420,20,550,150);
    
    SelectObject(hdc,GetStockObject(NULL_BRUSH));
    Ellipse(hdc,20,20,150,150);
    
    SelectObject(hdc,MyBrush);
    SelectObject(hdc,GetStockObject(NULL_PEN));
    
    Ellipse(hdc,220,20,350,150);
    
    Rectangle(hdc,20,200,150,330);
    
    DeleteObject(SelectObject(hdc,OldBrush));
    DeleteObject(MyPen);
    EndPaint(hWnd,&ps);
    return 0;
  case WM_DESTROY:   //사용자가 프로그램을 끝내려고 한다면
    PostQuitMessage(0);//이 함수를 호출하여 &message에 FALSE를 리턴한다.
    return 0;


  }
  return(DefWindowProc(hWnd,iMessage,wParam,lParam));//실제로 각 이벤트들이
      //수행되는 부분이다. (default이므로 별다른 코드가 필요없다.)
}
=================================================
================================================
그래픽 175쪽 메뉴를 눌려 곡선,직선,원,사각형 그리기
#include<windows.h>
#include
 "resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
HINSTANCE g_hlnst;    //전역변수
HWND hWndMain;
LPCTSTR lpszClass=TEXT("Class");//전역변수, 윈도우클래스를 정의하는데 사용, 타이틀바에 표시됨.

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevlnstance,LPSTR lpszCmdParam, int nCmdShow)
//엔트리포인트는 main()이 아니라 WinMain(),이다.
//윈도우를 만들고 화면에 표시하기만 할 뿐, 대부분의 일은 아래의 함수에서 이루어진다.
//WinMain에서 하는 가장 중요한 일은 메인 윈도우를 만드는 일이다.
{

  HACCEL hAccel;
  hAccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1));
  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;//만들어질 윈도우의 여러가지 특성을 정의하는 구조체
  g_hlnst=hInstance;//메인함수의 첫번째 인자인 hInstance를 전역변수에 대입

  WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
  WndClass.cbWndExtra=0;//않을 때는 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; //윈도우의 메시지 처리함수를 지정(여기는 WndProc)
  WndClass.lpszClassName=lpszClass;//이름지정, 전역변수를 대입하므로 "First"가 들어감
  WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);//메뉴지정, NULL이므로 생략
  WndClass.style=CS_HREDRAW|CS_VREDRAW;  //윈도우의 스타일 정의
  RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
  //윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.

  hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL|WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,
    CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
  //등록된 클래스를 기본으로 실제 윈도우 생성(메모리에 진입)
  //이 함수의 인자들은 위에서 등록한 내용들이 각각의 인자로 들어온다.
  //이 함수는 윈도우에 관한 모든 정보를 메모리에 만든후 대표 번호인 윈도우 핸들을 반환한다.

  ShowWindow(hWnd,nCmdShow); //화면에 출력하는 함수. //첫번째 인자는 출력하고자 하는 윈도
  //우의 핸들이며 CreateWindow함수가 리턴한 값이다. 두번째 인자는 출력하는 방법 지정.

  //아래의 While문은 프로그램 메시지를 처리하는 부분이다.
  while(GetMessage(&Message,NULL,0,0)) //메시지를 읽어들여서 false가 리턴될때 까지 반복
  {
    if(!TranslateAccelerator(hWnd,hAccel,&Message))
    {
      TranslateMessage(&Message); //키보드에 이벤트가 발생하면 그 것을 나타 내 준다.
      DispatchMessage(&Message);  //받은 메시지를 WndProc함수로 전달한다
      //그러면 그 함수에서 메시지를 점검하여 동작하게 된다.
    }
  }
  return (int)Message.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam, LPARAM lParam)
//사용자와 시스템이 보내오는 메시지를 처리하는 함수. (운영체제에 의해 호출)
{
  HDC hdc;
  PAINTSTRUCT ps;
  static int state=1// 도형 선택모드 초기값 자유곡선
  static int tx=0;  //각 도형 마우스 오른쪽 버튼 업후에  출력가능한지 하기
  static int sx,sy,oldx,oldy; //초기 x,y좌표 이동후 x,y,좌표 변수
  static bool bNowDraw=FALSE; //마우스 눌리고 이동시 확인할 참거짓 변수
  switch (iMessage) 
  {
  case WM_COMMAND:  //메뉴버튼 눌릴때 동작
    switch(LOWORD(wParam))
    {
    case ID_40001://자유곡선
      MessageBox(hWnd,TEXT("자유곡선메뉴를 선택했습니다."),TEXT("자유곡선"),MB_OK);
      SetWindowText(hWnd,TEXT("자유곡선")); //타이틀이름 변경
      state=1//자유곡선은 1
      return 0;
    case ID_40002://직선
      MessageBox(hWnd,TEXT("직선메뉴를 선택했습니다."),TEXT("직선"),MB_OK);
      SetWindowText(hWnd,TEXT("직선"));//타이틀이름 변경
      state=2;  //직선은 2
      return 0;
    case ID_40003://원
      MessageBox(hWnd,TEXT("원메뉴를 선택했습니다."),TEXT("원"),MB_OK);
      SetWindowText(hWnd,TEXT("원"));//타이틀이름 변경
      state=3;//원으 3
      return 0;
    case ID_40004://사각형
      MessageBox(hWnd,TEXT("사각형메뉴를 선택했습니다."),TEXT("사각형"),MB_OK);
      SetWindowText(hWnd,TEXT("사각형"));//타이틀이름 변경
      state=4;//사각형은 4
      return 0;
    case ID_40005:
      MessageBox(hWnd,TEXT("종료하겠습니다."),TEXT("종료"),MB_OK);
      DestroyWindow(hWnd);//종료버튼입력후
      break;
    }

  case WM_LBUTTONDOWN:
    sx=LOWORD(lParam);//마우수 오른쪽 입력시 그좌표값을 sx와 sy에 입력
    sy=HIWORD(lParam);
    oldx=sx; //직선 그리기위해서 초기값 만들어주기
    oldy=sy;
    bNowDraw=TRUE; //마우스 눌리면 참으로 변경
    return 0;
  case WM_MOUSEMOVE:
    if(state==1&&bNowDraw)  //마우스 눌리고 메뉴값이 자유곡선선택사항시
    {
      hdc=GetDC(hWnd);
      MoveToEx(hdc,sx,sy,NULL);
      sx=LOWORD(lParam);
      sy=HIWORD(lParam);
      LineTo(hdc,sx,sy);
      ReleaseDC(hWnd,hdc);
      tx=0;      //tx=0을 넣어 마우스업일때 상황보기
    }
    else if(state==2&&bNowDraw) //직선 값이들어올경우
    {
      hdc=GetDC(hWnd);
      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);
      tx=1;
    }
    else if(state==3&&bNowDraw) //원 값이들어올경우
    {
    hdc=GetDC(hWnd);
      SetROP2(hdc,R2_WHITE);  //원이깨지므로  오직 흰색만 나오게함
      oldx=LOWORD(lParam);
      oldy=HIWORD(lParam);
      ReleaseDC(hWnd,hdc);
      tx=2;
    //  SendMessage(hWnd,WM_PAINT,0,0);

    }
    else if(state==4&&bNowDraw)
    {
      hdc=GetDC(hWnd);
      SetROP2(hdc,R2_WHITE); //사각형도 크기를 늘리고 지우면 깨짐
      oldx=LOWORD(lParam);
      oldy=HIWORD(lParam);
      Rectangle(hdc,sx,sy,oldx,oldy);
      ReleaseDC(hWnd,hdc);
      tx=3;
    }
    return 0;
  case WM_LBUTTONUP:
    bNowDraw=FALSE;
    hdc=GetDC(hWnd);
    if(tx==1)
    {

      MoveToEx(hdc,sx,sy,NULL);
      LineTo(hdc,oldx,oldy);

    }
      else if(tx==2)
    {
    Ellipse(hdc,sx,sy,oldx,oldy);

    }
    else if(tx==3)
    {
    Rectangle(hdc,sx,sy,oldx,oldy);

    }
    ReleaseDC(hWnd,hdc);
    return 0;  
/*  case WM_PAINT:
    hdc=BeginPaint(hWnd,&ps);
    //  SetROP2(hdc,R2_WHITE);  //원이깨지므로  오직 흰색만 나오게함
      oldx=LOWORD(lParam);
      oldy=HIWORD(lParam);
    Ellipse(hdc,sx,sy,oldx,oldy);
    EndPaint(hWnd,&ps);
    return 0;
*/

  case WM_DESTROY:   //사용자가 프로그램을 끝내려고 한다면
    PostQuitMessage(0);//이 함수를 호출하여 &message에 FALSE를 리턴한다.
    return 0;


  }
  return(DefWindowProc(hWnd,iMessage,wParam,lParam));//실제로 각 이벤트들이
  //수행되는 부분이다. (default이므로 별다른 코드가 필요없다.)
}