블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday

    → 화면에 무엇인가가 그려져 있는 상황에서 그 위에 다른 무엇인가를 출력하면 원래 그려져 있던 그림은 새로 그려지는 그림에 의해 지워진다.
    → 디스플레이 표면은 2차원적인 평면이므로 새로운 그림이 그려지면 그 아래에 있던 그림은 지워질 수 밖에 없다.
    → 화면에 그려진 그림은 비디오 램에 저장되는데 램이 동시에 두 개의 값을 기억할 수는 없으므로 타원이 있던 자리에 사각형을 그리면 타원은 덮여져 사라지는 것이 당연하다. 그러나 이런 당연한 현상도 그리기 모드를 변경하면 달라진다.
    → 그리기 모드란 도형이 그려질 때 원래 그려져 있던 그림과 새로 그려지는 그림과의 관계를 정의하는 것이다.

    → 2개의 원본 그림이 있을 때(흑백의 경우)
    → COPY는 새로 그려지는 그림이 기존 그림을 덮어 버리는 것이며 원래 그려져 있던 그림은 뒤의 그림에 덮여 사라져 버린다.
    → OR은 두 그림의 대응되는 비트를 OR 연산하여 새로운 값을 만들어 써넣는다. 즉, 두 비트가 모두 1이거나 둘중 하나라도 1이면 1이 쓰여지며 둘다 0일 경우에만 0을 써 넣는다.
    → AND 연산은 두 그림의 교집합 영역만 그려진다.
    → XOR 연산은 두 그림 중 겹쳐지는 부분이 반전되는 효과를 가져온다.
    → 흑백에서의 비트 연산은 0(검정색) 또는 1(흰색)만 있기 때문에 이렇게 이해하기 쉽지만 여러가지 색상을 사용하는 컬러 그래픽 환경에서의 비트 연산은 이보다 훨씬 더 복잡하다. 하지만 개념적으로는 대응되는 비트끼리 흑백에서와 같은 형태의 이진 연산을 하기 때문에 정밀하게 계산해 본다면 결과를 예측할 수도 있다.


    - 그리기 모드의 종류
    → 윈도우즈에서 사용하는 디폴트 그리기 모드는 R2_COPYPEN 모드이다. 그래서 그려지는 그림이 기존 그림을 덮어버린다.
    → 그리기 모드를 변경하는 함수와 현재 설정된 그리기 모드를 구하는 함수는 다음과 같다.

    int SetROP2(HDC hdc, int fnDrawMode);
    int GetROP2(HDC hdc);

    첫 번째 인수 hdc는 그리기 모드를 변경(또는 조사) 하고자 하는 DC의 핸들이며 SetROP2 함수의 두번째 인수에 다음과 같은 그리기 모드값을 넘겨준다.


    - 그리기 모드
    예제

    int sx, sy, oldx, oldy;
    BOOL bNowDraw 
    = FALSE;

    LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      
    return 0;
    }
    LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      
    return 0;
    }
    LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      sx 
    = LOWORD(lParam); // 각 좌표가 저장되고 이것을 다시 oldx에 삽입
      sy = HIWORD(lParam); // 처음 마우스를 누른 위치
      oldx = sx; 
      oldy 
    = sy;
      bNowDraw 
    = TRUE; // 그림을 그린다.
      return 0;
    }
    LRESULT OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      
    if(bNowDraw)
      {
        HDC hdc;
        hdc 
    = GetDC(hWnd); 
        SetROP2(hdc, R2_BLACK); 
    // 항상 검정색이다.
        MoveToEx(hdc, sx, sy, NULL); 
        LineTo(hdc, oldx, oldy); 
    // oldx = sx, oldy = sy
        oldx = LOWORD(lParam); // 새로운 값을 읽는다.(MouseMove된 현재 좌표)
        oldy = HIWORD(lParam); // 지워져야 할 선의 끝 좌표
        MoveToEx(hdc, sx, sy, NULL); // 마우스 클릭시 현재 좌표
        LineTo(hdc, oldx, oldy); // 최종 이동된 좌표
        ReleaseDC(hWnd, hdc);
      }
      
    return 0;
    }
    LRESULT OnLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      
    // 기본모드(R2_COPYPEN)
      HDC hdc;

      bNowDraw 
    = FALSE;
      hdc 
    = GetDC(hWnd);
      MoveToEx(hdc, sx, sy, NULL);
      LineTo(hdc, oldx, oldy);
      ReleaseDC(hWnd, hdc);
      
    return 0;

    → 출력 결과


    - 더블클릭으로 화면 클리어를 위한 소스 수정

    WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

    → 더블클릭 메시지를 받기 위해 윈도우 클래스 스타일에 CS_DBLCLKS 플래그를 추가한다.
    → 보편적으로 많이 사용되는 더블클릭 메시지를 디폴트로 지원하지 않고 꼭 CS_DBLCLKS 플래그를 지정하도록 되어 있는 이유는 더블 클릭을 검출하는데는 그만큼 실행시간의 감소가 요구되며 어떤 프로그램은 더블클릭보다 WM_LBUTTONDOWN을 두 벋 받기를 원할 수 도 있기 때문이다.

    LRESULT OnLbuttonDblclk(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
     InvalidateRect(hWnd, NULL, TRUE); // 화면 클리어
     return 0;
    }
    → InvalidateRect 하수를 호출하여 작업영역 전체를 무효화 해버린다.
    → 위의 예제 코드에서 WM_PAINT 메시지를 처리하지 않으므로 무효영역이 생기면 DefWindowProc이 WM_PAINT 메시지를 처리하며 이 함수는 배경색으로 윈도를 지운다. 따라서 단순히 InvalidateRect 함수만 호출하면 화면이 지워진다.

    '내장형 하드웨어 > WINAPI' 카테고리의 다른 글

    WINAPI - 비트맵 출력, 메모리 DC  (0) 2011.09.15
    WINAPI - RopMode2 실습  (0) 2011.09.09
    WINAPI - 그래픽(색상)  (0) 2011.09.08
    WINAPI - 그래픽(GDI 오브젝트)  (0) 2011.09.07
    WINAPI - WM_COMMAND  (0) 2011.09.06
    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함