1 / 37

MFC 와 마우스

MFC 와 마우스. Department of Digital Contents Sang Il Park. Review: Rgn: 다각형 영역 객체. 다각형 (Polygon). 점들의 집합으로 정의됨. Review: CRgn: 다각형 영역 객체. 사용방법. 점의 배열. 점 갯수. style. CRgn rgn rgn.CreatePolygonRgn( CPoint * pt, int nNumber, int nStyle) dc.PaintRgn(&rgn);. nStyle: ALTERNATE or WINDING.

mills
Télécharger la présentation

MFC 와 마우스

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. MFC와 마우스 Department of Digital Contents Sang Il Park

  2. Review: Rgn: 다각형 영역 객체 • 다각형 (Polygon) 점들의 집합으로 정의됨

  3. Review: CRgn: 다각형 영역 객체 • 사용방법 점의 배열 점 갯수 style CRgn rgn rgn.CreatePolygonRgn( CPoint * pt, int nNumber, int nStyle) dc.PaintRgn(&rgn); nStyle: ALTERNATE or WINDING

  4. Review: CRgn: 다각형 영역 체 • 예제 CRgn rgn; CPoint ptVertex[5]; ptVertex[0] = CPoint(180,80); ptVertex[1] = CPoint(100,160); ptVertex[2] = CPoint(120,260); ptVertex[3] = CPoint(240,260); ptVertex[4] = CPoint(260,160); rgn.CreatePolygonRgn( ptVertex, 5, ALTERNATE); dc.PaintRgn(&rgn);

  5. Review: CBitmap • 사용법 : Brush에 맵핑 리소스 아이디 CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); CBrush brush(&bitmap); dc.SelectObject(&brush); dc.Rectangle(0,0,200,200);

  6. Review: BITMAP 정보 보기 • 비트맵 정보 intCBitmap::GetBitmap (BITMAP* pBitMap) ; struct BITMAP { int bmType; int bmWidth; // 비트맵의 폭(픽셀 단위) int bmHeight; // 비트맵의 높이(픽셀 단위) int bmWidthBytes; BYTE bmPlanes; BYTE bmBitsPixel; LPVOID bmBits; };

  7. Review: Bitmap Block Transfer • 한 점씩 그리지 않고 한꺼번에 메모리로 보낸다 (Block) (Transfer) • 절차: • 원래의 도화지가 있다 CPaintDC dc; • 또 다른 도화지 준비CDC memDc;CDC::CreateCompatibleDC(..); • 그 도화지에 그림 그리기CDC::SelectObject(…); • 원래의 도화지로 그린거 오려붙이기dc.BitBlt(…); Bit Block Transfer (BitBlt)

  8. Review: Bitmap Block Transfer CPaintDC dc(this); CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); BITMAP bmpInfo; bitmap.GetBitmap(&bmpInfo); CDC memDc; memDc.CreateCompatibleDC(&dc); memDc.SelectObject(&bitmap); dc.BitBlt(100, 100, bmpInfo.bmWidth, bmpInfo.bmHeight, &memDC, 0, 0, SRCCOPY);

  9. pSrcDC (메모리 디바이스 컨텍스트) ySrc xSrc (스크린 디바이스 컨텍스트) y nWidth x nHeight Review: Bitmap Block Transfer 그림을 복사하는 방법 SRCCOPY, • 비트맵 출력 함수 BOOL BitBlt (int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) ; nWidth nHeight

  10. 좀 더 진보된 그리기 방법:Double Buffering

  11. 여태까지 그림 그리는 방법은… • 그림을 다시 그릴 때 그리는 과정이 보인다. • 특히 느린 컴퓨터를 사용할 때.. • Why??? • 그림을 다시 그릴 때 깜박거린다. • 원래 내용을 무효화(invalidate) 한다 = 먼저 하얗게 지운다

  12. Double Buffering • 두 개의 Device Context(도화지)를 이용함. • 1. 그림을 그리는 용도 (Back Buffer) • 2. 그림을 보여주는 용도 (Front Screen Buffer)

  13. Memory에 그림그리고 넘겨주기 • 절차: • 1. 메모리DC 만들기 (CreateCompatibleDC) • 2. 그림그릴 메모리 만들기 (CreateCompatibleBitmap) • 3. DC와 Bitmap을 연결 (SelectObject) • 4. 그림 그리기 • 5. 그려진 그림을 화면DC로 BitBlt 한꺼번에  그림을 다른 도화지에 그리고, 도화지를 빠르게 바꿔 치기 한다 Double Buffering

  14. Memory에 그림그리고 넘겨주기 한꺼번에 CPaintDC dc(this); CRect rect; GetClientRect(&rect); CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap bitmap; bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height()); memDC.SelectObject(&bitmap); memDC.Rectangle(0,0,100,100); dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);

  15. Double Buffering using bitmap • 그림이 빨리 그려진다. • 그러나 여전히 깜박인다???  화면을 매번 깨끗이 지우기 때문!  “화면을 지울 필요가 있다”라는 메시지를 받아서 지우지 말자고 하자. 해결책: WM_ERASEBKGND 메시지 핸들러를 만들어 아무 일도 하지 말자고 한다. ( 뒷 장 참고)

  16. WM_ERASEBKGND 핸들러 추가 • WM_ERASEBKGND: 화면을 지울 때(하얗게 칠할 때) 불리는 메시지

  17. WM_ERASEBKGND 핸들러 추가 • WM_ERASEBKGND: 화면을 지울 때(하얗게 칠할 때) 불리는 메시지 • 화면을 지우지 않게 하기 위해 아무일도 하지 않고 그냥 return BOOL CChildView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default // return CWnd::OnEraseBkgnd(pDC); return true; }

  18. MFC와 마우스

  19. 마우스 마우스 장치 드라이버 시스템 메시지 대기열 응용 프로그램 메시지 대기열 메시지 핸들러 메시지 메시지 메시지 루프 마우스 기초 (1/2) • 마우스 처리 • 윈도우 운영체제는 마우스와 관련된 모든 변화를 메시지 형태로 프로그램에게 전달한다.

  20. 마우스 기초 (2/2) • 마우스 메시지 전달 • 마우스 메시지는 마우스 커서 밑에 있는 윈도우가 받는다. 마우스 메시지를 프레임 윈도우로 전달 마우스 메시지를 뷰로 전달

  21. 메시지 발생 시점 WM_LBUTTONDOWN 왼쪽 버튼을 누를 때 WM_LBUTTONUP 왼쪽 버튼을 뗄 때 WM_LBUTTONDBLCLK 왼쪽 버튼을 더블 클릭할 때 WM_MBUTTONDOWN 가운데 버튼을 누를 때 WM_MBUTTONUP 가운데 버튼을 뗄 때 WM_MBUTTONDBLCLK 가운데 버튼을 더블 클릭할 때 WM_RBUTTONDOWN 오른쪽 버튼을 누를 때 WM_RBUTTONUP 오른쪽 버튼을 뗄 때 WM_RBUTTONDBLCLK 오른쪽 버튼을 더블 클릭할 때 WM_MOUSEMOVE 마우스를 움직일 때 클라이언트 영역 마우스 메시지 (1/5) • 클라이언트 영역 마우스 메시지

  22. 클라이언트 영역 마우스 메시지 (1/5) • 메시지 발생 과정 (왼쪽마우스의 경우) 마우스를 움직일 때 왼쪽 버튼 클릭 왼쪽 버튼 클릭 + 드래그 왼쪽 버튼 더블 클릭 WM_MOUSEMOVE WM_LBUTTONDOWN WM_LBUTTONDOWN WM_LBUTTONDOWN WM_MOUSEMOVE WM_LBUTTONUP WM_MOUSEMOVE WM_LBUTTONUP WM_MOUSEMOVE WM_MOUSEMOVE WM_LBUTTONDBLCLK WM_MOUSEMOVE WM_MOUSEMOVE WM_LBUTTONUP WM_MOUSEMOVE WM_LBUTTONUP

  23. 메시지 메시지맵 매크로 메시지 핸들러 WM_LBUTTONDOWN ON_WM_LBUTTONDOWN() OnLButtonDown WM_LBUTTONUP ON_WM_LBUTTONUP() OnLButtonUp WM_LBUTTONDBLCLK ON_WM_LBUTTONDBLCLK() OnLButtonDblClk WM_MBUTTONDOWN ON_WM_MBUTTONDOWN() OnMButtonDown WM_MBUTTONUP ON_WM_MBUTTONUP() OnMButtonUp WM_MBUTTONDBLCLK ON_WM_MBUTTONDBLCLK() OnMButtonDblClk WM_RBUTTONDOWN ON_WM_RBUTTONDOWN() OnRButtonDown WM_RBUTTONUP ON_WM_RBUTTONUP() OnRButtonUp WM_RBUTTONDBLCLK ON_WM_RBUTTONDBLCLK() OnRButtonDblClk WM_MOUSEMOVE ON_WM_MOUSEMOVE() OnMouseMove 클라이언트 영역 마우스 메시지 (2/5) • 클라이언트 영역 마우스 메시지 핸들러

  24. 윈도우 메시지 핸들러 추가법 • CChildView의 Properties 창에서 추가할 수 있다

  25. 비트 매스크 의미 MK_CONTROL Ctrl 키가 눌렸을 때 MK_SHIFT Shift 키가 눌렸을 때 MK_LBUTTON 마우스 왼쪽 버튼이 눌렸을 때 MK_MBUTTON 마우스 가운데 버튼이 눌렸을 때 MK_RBUTTON 마우스 오른쪽 버튼이 눌렸을 때 클라이언트 영역 마우스 메시지 (3/5) • 메시지 핸들러 형태 • nFlags • 메시지가 생성될 때의 키보드나 마우스 버튼의 상태를 나타내는 비트 매스크 afx_msg void On##### (UINT nFlags, CPoint point) ;

  26. 클라이언트 영역 마우스 메시지 (3/5) • 메시지 핸들러 형태 • nFlags afx_msg void On##### (UINT nFlags, CPoint point) ; void CChildView::OnLButtonDown(UINT nFlags, CPoint point) { if(nFlags & MK_SHIFT){ // 만약 Shift 키가 눌렸다면 ... } CWnd ::OnLButtonDown(nFlags, point); }

  27. 클라이언트 영역 마우스 메시지 (4/5) • 메시지 핸들러 형태 • point • 메시지가 생성될 때의 마우스 커서 위치(클라이언트 좌표) afx_msg void On##### (UINT nFlags, CPoint point) ; void CChildView::OnLButtonDown(UINT nFlags, CPoint point) { CClientDC dc(this); CPoint pt = point; dc.Rectangle(pt.x-100, pt.y+100, pt.x+100, pt.y-100); CWnd ::OnLButtonDown(nFlags, point); }

  28. 연습: line 긋는 프로그램 • 화면에 마우스를 이용하여 line을 긋는다. • Line 을 그리기 위해서는 • 시작점, 끝점을 기억한다. • 마우스 버튼 Down 시 • 시작점을 입력 • 마우스 버튼 Up 시 • 끝점을 입력 • Line 긋기

  29. 연습: line 긋는 프로그램2 • 화면에 마우스를 이용하여 line을 긋는다. • 마우스가 움직일 때 중간 과정을 보여준다 • Line 을 그리기 위해서는 • 시작점, 끝점을 기억한다. • 마우스 버튼 Down 시 • 시작점을 입력 • 마우스 Move 시 • 끝점을 입력 • Line 긋기 • 마우스 버튼 Up 시 • 끝점을 입력 • Line 긋기

  30. 문제점? • 마우스가 밖으로 나가 버리면???

  31. API 함수 MFC 함수 의미 SetCapture() CWnd::SetCapture() 마우스 캡처를 시작한다. ReleaseCapture() 없음 마우스 캡처를 해제한다. GetCapture() CWnd::GetCapture() 어느 윈도우가 현재 마우스 캡처를 하고 있는지 알아낸다. 마우스 캡쳐 • 용도 • 마우스 캡처를 하면 마우스 커서의 위치에 관계없이 마우스 메시지를 받을 수 있다. • 관련 함수

  32. 메시지 발생 시점 WM_NCLBUTTONDOWN 왼쪽 버튼을 누를 때 WM_NCLBUTTONUP 왼쪽 버튼을 뗄 때 WM_NCLBUTTONDBLCLK 왼쪽 버튼을 더블 클릭할 때 WM_NCMBUTTONDOWN 가운데 버튼을 누를 때 WM_NCMBUTTONUP 가운데 버튼을 뗄 때 WM_NCMBUTTONDBLCLK 가운데 버튼을 더블 클릭할 때 WM_NCRBUTTONDOWN 오른쪽 버튼을 누를 때 WM_NCRBUTTONUP 오른쪽 버튼을 뗄 때 WM_NCRBUTTONDBLCLK 오른쪽 버튼을 더블 클릭할 때 WM_NCMOUSEMOVE 마우스를 움직일 때 비 클라이언트 영역 마우스 메시지 (1/4) • 비 클라이언트 영역 마우스 메시지

  33. 메시지 메시지맵 매크로 메시지 핸들러 WM_NCLBUTTONDOWN ON_WM_NCLBUTTONDOWN() OnNcLButtonDown WM_NCLBUTTONUP ON_WM_NCLBUTTONUP() OnNcLButtonUp WM_NCLBUTTONDBLCLK ON_WM_NCLBUTTONDBLCLK() OnNcLButtonDblClk WM_NCMBUTTONDOWN ON_WM_NCMBUTTONDOWN() OnNcMButtonDown WM_NCMBUTTONUP ON_WM_NCMBUTTONUP() OnNcMButtonUp WM_NCMBUTTONDBLCLK ON_WM_NCMBUTTONDBLCLK() OnNcMButtonDblClk WM_NCRBUTTONDOWN ON_WM_NCRBUTTONDOWN() OnNcRButtonDown WM_NCRBUTTONUP ON_WM_NCRBUTTONUP() OnNcRButtonUp WM_NCRBUTTONDBLCLK ON_WM_NCRBUTTONDBLCLK() OnNcRButtonDblClk WM_NCMOUSEMOVE ON_WM_NCMOUSEMOVE() OnNcMouseMove 비 클라이언트 영역 마우스 메시지 (2/4) • 비 클라이언트 영역 마우스 메시지 핸들러

  34. 비 클라이언트 영역 마우스 메시지 (3/4) • 메시지 핸들러 형태 • nHitTest • 메시지가 생성될 때의 마우스 커서 위치를 나타내는 상수값  다음 페이지 표 참조 • point • 메시지가 생성될 때의 마우스 커서 위치(스크린 좌표) • 클라이언트 좌표로 변환하려면 CWnd::ScreenToClient() 함수를 사용 afx_msg void OnNc* (UINT nHitTest, CPoint point) ;

  35. 상수값 의미 HTCAPTION 타이틀바 HTCLIENT 클라이언트 영역 HTCLOSE 종료 버튼 HTHSCROLL 가로 스크롤 바 HTMENU 메뉴 HTMAXBUTTON 또는 HTZOOM 최대화 버튼 HTMINBUTTON 또는 HTREDUCE 최소화 버튼 HTSYSMENU 시스템 메뉴 HTVSCROLL 세로 스크롤 바 비 클라이언트 영역 마우스 메시지 (4/4) • nHitTest

  36. 이외 마우스와 관련된 것들 • 집에서 읽어 볼 것: 교재 pp 214~220 • 마우스 포인터의 모양 지정: • 마우스 동작 범위 지정 HCURSOR SetCursor (HCURSOR hCursor) ; ::ClipCursor (lpRect pRect) ;

  37. 휴강 공고 • 3월 31일(화요일), 4월 2일(목요일)은 수업이 없음! • 보강 계획: 차후 공고

More Related