본문 바로가기
코스웨어/15년 스마트컨트롤러

2015.11.13 -권오민- WinAPI-2일차

by 알 수 없는 사용자 2015. 11. 13.
728x90
반응형

API

- L을 앞에 붙이는 이유.

        - 아스키 코드로 개발되었다.

                - win32는 16bit의 산물이다.

                        - char를 기본으로 한다.

                - 영어로 개발되었다.

                        - 다른 언어를 표현하는데 문제가 있다.

                                - 유니코드가 개발되었다.

                                        - 아스키 코드도 포함한다.

                                        - wchar이 2byte이다.

                        - First에 대해서

                                - Fi, rs, t 총 3글자로 확인한다.

                                - L을 통해서 wchar로 인지하라고 알려준다.

        - L을 제외하고 2가지의 방법이 더 있다.

                - TEXT("First")

                        - win32

                - _T("First")

                        - MFC

- 유니코드의 반대는 멀티코드이다.

        - 멀티코드

                - 영어는 1byte, 한글은 2byte로 처리한다.

        - 유니코드는 전부 2byte로 처리한다.

◉2-3다양한 변경

●2-3-가. 배경색 바꾸기

- 값의 수정을 통해 배경색을 설정할 수 있다.

- 원형

        - WndClass.hbrBackground=GetStockObject(WHITE_BRUSH);

                - WHITE_BRUSH의 값을 바꾸면 된다.

- 실습 결과

        - WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);

●2-3-나. 커서 바꾸기

- 값의 수정을 통해 커서를 설정할 수 있다.

- 원형

        - WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

- 커서 종류

●2-3-다. 윈도우의 타이틀 바꾸기

- 값의 수정을 통해 타이틀을 설정할 수 있다.

- 원형

        -

- 실습 결과

        - hWnd=CreateWindow(lpszClass, L"Title",WS_OVERLAPPEDWINDOW,

                  CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

                  NULL,(HMENU)NULL,hInstance,NULL);

);

  

●2-3-라. 윈도우의 크기 바꾸기

- 값의 수정을 통해 크기를 설정할 수 있다.

- 실습 결과

        -      hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,

                  100, 100, 300, 300,     =>     100, 100, 200, 200

                  NULL,(HMENU)NULL,hInstance,NULL);

  

●2-3-마. 윈도우 스타일

- 값의 수정을 통해 스타일을 설정할 수 있다.

- CreateWindow의 3번째 인자이다.

- 실습 결과

        - (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VSCROLL | WS_HSCROLL)

        - (WS_OVERLAPPED | WS_CAPTION |WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)

3-1. DC

●3-1-가. DC의 필요성

- DC(Device Context)

        - 장치의 상태를 저장한다.

                - 그래픽 장치

                

        - GDI

                - 추상적이다.

                - 그래픽 카드마다 사양이 다 다르다.

                - 예전 휴대폰 게임이 그러 했다.

                - 극복 방법

                        - 오락을 JAVA로 개발한다.

                                - 가상 머신에 대해서 개발한다.

                                        - 가상 머신이 휴대폰에 들어가면서 해상도에 맞게 한다.

                                - 단점 : 디지털은 확대에 한계가 있다.

                                        - 100%호환이 불가능하다.

                                        - 도트로 출력된다.

                        - 아이폰의 경우 C로 작성하기 때문에 기기별로 전부 만들어야한다.

                                - 최적화가 잘 되어 있다.

●3-1-나. 문자열 출력

- WndProc를 수정하는 것이 API이다.

- GetDC

        - DC에 저장된 상태를 들고 온다.

- ReleaseDC

        - DC도 메모리를 차지하므로 할당 후 반드시 해제 해 주어야한다.

- 창에 그림을 그릴뿐 이다.

        - 가려지거나 모양이 바뀌면 지워진다.

        - 창이 뜰 때 그림을 다시 그린다.

                - 화면에만 떠 있고 기록되어 있는 것은 아니다.

                - 화면이 가려지면 지우고 다시 그린다.

- 실습 결과

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 
 HDC hdc;
  
switch (iMessage)
  {
    
case WM_DESTROY:
      PostQuitMessage(
0);
      
return 0;
    
case WM_LBUTTONDOWN:  //왼쪽 버튼을 눌렀을 때
      hdc = GetDC(hWnd);
      TextOut(hdc, 100, 100, L"안녕하세용", 5);
      ReleaseDC(hWnd, hdc);
      return 0;

  }
  
return(DefWindowProc(hWnd, iMessage, wParam, lParam));

  

        - 그러나 저장을 하지 못 한다.

●3-1-다. WM_PAINT 메시지

- 영향을 받아도 지워지지 않는다.

- 윈도우가 화면을 보관해주지는 않지만, WM_PAINT로 일부가 지워졌다는 메시지를 보낸다.

        - 문자열 출력문을 옮기면, 메시지 루틴에 있으므로 지워지지 않는 것처럼 보인다.

- BeginPaint

        - DC정보를 가져온다.

- EndPaint

        - BeginPaint에서 받은 DC정보를 지운다.

- 실습 결과

case WM_PAINT:
      hdc 
= BeginPaint(hWnd, &ps);
      
TextOut(hdc, 100100, L"안녕하세요1", 6); 

              // (DC정보, 창의 내부 X, 창의 내부 Y, 출력하고 싶은 문자열, 문자열의 길이(글자 갯수:한글도 1개로 취급))
      EndPaint(hWnd, &ps);
      
return 0;

◉3-2. 문자열의 출력

- 화면에 무엇인가를 출력하는 함수들의 첫 번째 인수는 항상 hdc이다.

●3-2-가. TextOut

- TextOut의 출력위치를 수정할 수 있다.

- 실습 결과

          SetTextAlign(hdc, TA_RIGHT);

●3-2-나. DrawText

- 실습 결과

 LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  RECT rt 
= { 100100400300 };  //사각형 : rectangle, RECT 구조체 : 사각형에 필요한 값 4개를 받기위해 int형 4개로 이루어져있다.
  char *str ={TEXT("님은 갔습니다. 아아 사랑하는 나의 님은 갔습니다.")
    TEXT(
"단풍나무 숲을 향하여 난 작은 길을")
    TEXT(
"황금의 꽃같이 굳고 빛나던 옛 맹세는")
    TEXT(
"날아갔습니다.")
};

  
switch (iMessage)
  {
    
case WM_DESTROY:
      PostQuitMessage(
0);
      
return 0;
    
case WM_PAINT:
      hdc 
= BeginPaint(hWnd, &ps);      
      
//TextOut(hdc, 100, 100, L"안녕하세요1", 6);  // (DC정보, 창의 내부 X, 창의 내부 Y, 출력하고 싶은 문자열, 문자열의 길이(글자 갯수:한글도 1개로 취급))
      DrawText(hdc, str, -1, &rt, DT_CENTER | DT_WORDBREAK);
      EndPaint(hWnd, 
&ps);
      
return 0;
  }
  
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

◉3-3. 여러 가지 출력

●3-3-가. 그래픽 출력

- 선 긋기 및 이동

        - (A,B)점에서 (C,D)점 까지 선 긋기.

                - MoveToEx(hdc, A, B, NULL);

                - LineTo(hdc, C, D);

- 사각형

        - Rectangle(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)

                - 인자는 시작점과 끝점의 x, y좌표이다.

        - 정해진 사각형의 내부에 접하는 사각형을 채운다.

                - 따라서 먼저 그려진 도형위에 다음 도형을 그리면 덮어쓴다.

- 타원형

        - Ellipse(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)

                - 사각형과 마찬가지로 시작점과 끝점의 위치 좌표이다.

        - 정해진 사각형의 범위에 내접하는 타원형을 채운다.

                - 따라서 먼저 그려진 도형위에 다음 도형을 그리면 덮어쓴다.

- 실습 결과

case WM_PAINT:
    hdc 
= BeginPaint(hWnd, &ps);
    
Ellipse(hdc, 10050170120);
    
Rectangle(hdc, 100120170150);
    
MoveToEx(hdc, 100150, NULL);
    LineTo(hdc, 135250);
 
   LineTo(hdc, 170150);
    EndPaint(hWnd, 
&ps);
    
return 0;

  

●3-3-나. 메시지 박스

- dos에서 MessageBox를 출력하는 법.

        - MessageBox는 int형을 반환한다.

#include  <windows.h>
#pragma comment(lib,"user32.lib")  //컴파일 할 때 추가해서 컴파일 하겠다.
                            
          //gcc는 x, cl에서만 된다.

int main(void)
{

   int iRet;
  iRet =
MessageBox(NULL, "123", "345", MB_YESNO|MB_ICONINFORMATION);

              //dos에는 핸들러가 없기 때문에 NULL을 넣어준다.
   printf("%d\n", iRet);
  
return 0;
}

- #pragma comment(lib,"user32.lib")

        - 따로 입력해주지 않아도 visual studio가 자동으로 포함해서 컴파일한다.

- 결과

- 플래그 종류

- 아이콘 플래그 종류

- 실습 결과

    case WM_LBUTTONDOWN:
      
MessageBox(hWnd, L"마우스 왼쪽 버튼을 눌렀습니다", L"메시지 박스", MB_OK);
      return 0;

●3-3-다. 메시지 비프

- 일반 문자열

        - 비프음을 내는 출력이다.

                - 소리가 나지 않으므로 생략하도록 한다.

        - 음의 종류

◆4장. 입력

◉4-1. DC

●4-1-가. WM_CHAR 메시지

- CHAR에서 출력을 하게되면 입력할 때는 문제가 없지만, 창을 내리거나 하면 사라진다.

- wParam(word)

        - WndProc의 3번째 인자로서 키보드를 입력 시 값의 ASCII값으로 입력된다.

        - 4byte이므로 WCHAR로 캐스팅 해주는 것이 좋다.

- lParam

        - 아스키 코드 뿐만 아니라 다양한 정보들이 입력된다.

        - 키를 눌렀는지 떼었는지를 알 수 있다.

- 실습 결과

  static WCHAR str[256];  //wchar_t : 2byte 문자열로 처리한다(유니코드).
  int len;
  
switch (iMessage) 
  {
    
case WM_CHAR:  //키보드가 발생하면 동작한다. 
      len = lstrlen(str);  //strlen은 1byte단위로 처리한다.
      str[len] = ((TCHAR)wParam);
      str[len + 
1= 0;
      
InvalidateRect(hWnd, NULL, FALSE);  //윈도우한테 나를 한번 더 그려달라는 메시지(WM_PAINT)를 생성한다.
      return 0;
    
case WM_PAINT:  //InvalidateRect에 의해서 다시 호출 되게 된다.
      hdc = BeginPaint(hWnd, &ps);
      TextOut(hdc, 
100100, str, lstrlen(str));
      EndPaint(hWnd, 
&ps);
      
return 0;


●4-1-나. 무효화 영역

- InvalidateRect

        - 원형

                - BOOL InvlidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase);

        - 무효한 사각형.

        - 윈도우가 다시 그려져야 할 필요가 있을 때마다 호출된다.

        - 창이 겹쳐 그리지 않아도 되는 영역이다.

                - WM_PAINT 메시지를 보낸다.

                        - 단, 마우스 커서 모양은 WM_PAINT를 받지 않는다.

        - window가 아니라 우리가 WM_PAINT를 부를 수 있게 해준다.

        - 2번 인자 : CONST RECT *lpRect

                - Rect 구조체의 영역을 넣어주어야 한다.

                - 0을 넣거나, 주소를 넣지 않으면, 무효화 영역뿐만 아니라 전부 다시 그린다.

                        - 매우 느려진다.

        - 호랑이가 이동한다고 가정할 때, 호랑이가 있던 영역과, 이동할 영역을 다시 그린다.

        - 3번 인자 : BOOL bErase

                - 무효화되기 전에 배경을 모두 지운후 다시 그릴지 아니면 그냥 그릴지 정한다.

                - TRUE이면 지우고 다시 그리고 FALSE이면 지우지 않고 다시 그린다.

- 실습 결과

        - WM_CHAR을 다음과 같이 수정한다.

    case WM_CHAR:
     
 if (32 == (WCHAR)wParam)  //아스키 코드 32=스페이스바
      {                           
//스페이스바를 누르면 전부 지워진다.
        str[0] = 0;
      }
      else
      {
        len = lstrlen(str);
        str[len] = (WCHAR)wParam;
        str[len + 1] = 0;
      }

      InvalidateRect(hWnd, NULL, 
TRUE);
      
return 0;

●4-1-다. WM_KEYDOWN

- 아스키 코드를 제외한 키보드 입력에 대한 가상키 코드이다.

        - 키보드에 종류에 영향을 받지 않는다.

- 키가 눌러지면, 키가 눌려졌다는 메시지가 온다.

- 실습 결과

   static int x = 100;
  
static int y = 100;

    
case WM_KEYDOWN:
      
switch (wParam)   //입력된 값에 맞는 동작을 한다.
      {
        
case VK_LEFT:
          x = x - 8;

           if(0 > x)

           {

                  x = 0;

           }
          break;
        case VK_RIGHT:
          x = x + 8;
          break;
        case VK_UP:
          y = y - 8;
          break;
        case VK_DOWN:
          y = y + 8;
          break;

      }
      InvalidateRect(hWnd, NULL, 
TRUE/*FALSE*/); //지우고 할 때 지우지 않을 때의 결과는 다르다.
      
return 0;
    
case WM_PAINT:  //InvalidateRect에 의해서 다시 호출 되게 된다.
      hdc = BeginPaint(hWnd, &ps);
      
//TextOut(hdc, 100, 100, str, lstrlen(str));
      TextOut(hdc, x, y, L"A", 1);
      EndPaint(hWnd, 
&ps);
      
return 0;

 

        - 시작

        - FALSE의 이동 결과

        - 오른쪽으로 5, 위로 5칸 이동한 결과(TRUE)

        - 오른쪽으로 5, 위로 5칸 이동한 결과(FALSE)

728x90