1 / 21

Windows Programming 제대로 배우기

Windows Programming 제대로 배우기. Chapter 3. Mouse Event. 학습 목표. 마우스 대한 이벤트를 컨트롤 하는 방법에 대해서 설명. 마우스의 클라이언트 영역. - 마우스가 클릭하였을 때 마우스에 대한 메시지가 발생되는데 클라이언트 영역과 비클라이언트 영역에 분리되어 다르게 나타남 클라이언트 영역이란 윈도우 타이틀바와 외곽선을 제외한 즉 실지로 WM_PAINT 메시지에 의해서 그래픽을 출력하는 영역 이 영역에서 마우스가 움직이거나 클릭하였을 경우에 발생하는 메시지 리스트.

gracie
Download Presentation

Windows Programming 제대로 배우기

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. Windows Programming제대로 배우기 Chapter 3. Mouse Event

  2. 학습 목표 마우스 대한 이벤트를 컨트롤 하는 방법에 대해서 설명

  3. 마우스의 클라이언트 영역 - 마우스가 클릭하였을 때 마우스에 대한 메시지가 발생되는데 클라이언트 영역과 비클라이언트 영역에 분리되어 다르게 나타남 • 클라이언트 영역이란 윈도우 타이틀바와 외곽선을 제외한 즉 실지로 WM_PAINT 메시지에 의해서 그래픽을 출력하는 영역 • 이 영역에서 마우스가 움직이거나 클릭하였을 경우에 발생하는 메시지 리스트

  4. 마우스 관련 메세지

  5. 마우스 예제 내용 WM_LBUTTONDOWN메시지를 이용하여 마우스가 클릭되었을 때 몇 번 클릭되었는가를 나타내는 프로그램 예제 설명 • switch문에 WM_LBUTTONDOWN을 설정하여 좌측 마우스 버튼이 눌려졌을 때 마우스 이벤트를 얻음 case WM_LBUTTONDOWN: • case WM_LBUTTONDOWN: count++; break;

  6. #include <stdio.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static int count; char temp[80]; switch(uMsg) { case WM_CREATE : count = 0; break; case WM_PAINT : hdc = BeginPaint(hWnd, &ps); count++; sprintf(temp, "Count = %d", count); TextOut(hdc, 50, 50, temp, strlen(temp)); EndPaint(hWnd, &ps); break; case WM_DESTROY : PostQuitMessage(0); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  7. 재출력의 필요성 • 마우스를 눌러도 count가 바뀌지 않음 (윈도우를 움직이면 count가 변경됨) • 무엇이 문제인가? • 윈도우에서는 InvalidateRect함수를 사용하여 윈도우를 다시 그려야한다는 메시지를 발생시켜야 함. • InvalidateRect함수는 WM_PAINT메세지를 해당 윈도우에 보낸다.

  8. InvalidateRect 함수 InvalidateRect( HWND hWnd , // 윈도우 핸들 - 식별자 CONST RECT *lpRect, BOOL bErase); // 영역 부분이 NULL이면 윈도우 전체 영역이 다시 그려지게 됨

  9. #include <stdio.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static int count; char temp[80]; switch(uMsg) { case WM_CREATE : count = 0; break; case WM_PAINT : hdc = BeginPaint(hWnd, &ps); sprintf(temp, "Count = %d", count); TextOut(hdc, 50, 50, temp, strlen(temp)); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN : count++; InvalidateRect(hWnd, NULL, TRUE); break; case WM_RBUTTONDOWN : count--; InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY : PostQuitMessage(0); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  10. Event Driven과 Programming Style • Event-Driven에서 제각각 발생하는 메시지를 가지고 처리하는 프로그래밍 방식 • 데이터를 중심으로 어디선가 누군가에 의해 (Event) 변경이 되면, 즉각 재출력을 하여 다시 그 결과를 반영하도록 함 • 윈도우 프로그램에서는 데이터를 중심으로 설계 필요

  11. #include <stdio.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static int count; char temp[80]; switch(uMsg) { case WM_CREATE : count = 0; break; case WM_PAINT : hdc = BeginPaint(hWnd, &ps); sprintf(temp, "Count = %d", count); TextOut(hdc, 50, 50, temp, strlen(temp)); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN : count++; InvalidateRect(hWnd, NULL, TRUE); break; case WM_RBUTTONDOWN : count--; InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY : PostQuitMessage(0); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } 데이타변경 데이터 출력

  12. Data Toggling • Toggle 이란? • 한번 누르면 켜지고 다시 한번 누르면 꺼지는 방식 • 프로그램에서는 자주 특정 변수를 일정한 방법으로 Toggle시켜 사용함

  13. 기본적인 Toggle 방법 • 1, 0 Toggle int flag = 1; flag = 1-flag; // flag = !flag; • 1, -1 Toggle int flag = 1; flag = flag*-1; // flag *= -1; • 0,1,2를 순차적으로 반복하는 Round Toggle int flag = 0; flag++; flag %= 3;

  14. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; char temp[80]; static int m_bFlag; switch(uMsg) { case WM_CREATE : m_bFlag = 1; break; case WM_PAINT : hdc = BeginPaint(hWnd, &ps); if(m_bFlag) strcpy(temp, "Toggle"); else strcpy(temp, ""); TextOut(hdc, 100, 100, temp, strlen(temp)); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN : m_bFlag = !m_bFlag; InvalidateRect(hWnd, NULL, TRUE); break; case WM_RBUTTONDOWN : break; case WM_DESTROY : PostQuitMessage(0); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } 데이타변경 데이터 출력

  15. 마우스 예제 • 화면 중앙에 자기가 원하는 텍스트 스트링을 나타낸 후 마우스 왼쪽 버튼을 누르면 글자를 왼쪽으로, 오른쪽 버튼을 누르면 글자를 오른쪽으로 이동하는 프로그램 작성 • 힌트 : TextOut 함수의 좌표를 이용함

  16. // 필요 데이터 선언 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static char m_Str[80]; static POINT m_Point; static RECT m_Bound; int chSize = 8; switch(uMsg) { case WM_CREATE : strcpy(m_Str, "Moving Str"); GetClientRect(hWnd, &m_Bound); m_Point = CenterPoint(m_Bound); m_Point.x -= (strlen(m_Str)*chSize)/2; break; case WM_PAINT : hdc = BeginPaint(hWnd, &ps); TextOut(hdc, m_Point.x, m_Point.y, m_Str, strlen(m_Str)); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN : m_Point.x -= 20; InvalidateRect(hWnd, NULL, TRUE); break; case WM_RBUTTONDOWN : m_Point.x += 20; InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY : PostQuitMessage(0); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } // 윈도우 타이틀바를 제외한 전체 영역을 Client Area 라고 하는데, 이 영역에 관한 정보를 돌려주는 함수 // 적절한 초기화 // 화면 출력 // 마우스 이벤트 처리

  17. POINT CenterPoint(RECT& r) { POINT p; p.x = (r.left + r.right) /2; p.y = (r.top + r.bottom) /2; return p; }

  18. 마우스 파라미터 lParam - 마우스가 눌려졌을 경우에 어느 부분이 눌려졌다는 정보를 기록하는 변수 • 32비트 LONG형 • 마우스 정보를 입력하여 정보를 알려주게 됨 • 상위 16비트 : Y 좌표 • 하위 16비트 : X 좌표 LOWORD, HIWORD • 32비트를 16비트로 나누어주는 함수 int y=HIWORD(lParam) int x=LOWORD(lParam)

  19. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; char temp[80]; char *buttondata[4]={"안눌림 ","좌측버튼","우측버튼","양쪽눌림"}; POINT point; switch (iMsg) { case WM_CREATE : return 0 ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; EndPaint (hwnd, &ps) ; return 0 ;

  20. case WM_LBUTTONUP: point.x=LOWORD(lParam); point.y=HIWORD(lParam); wsprintf(temp,"좌측버튼놓음:%04d : %04d", point.x,point.y); hdc=GetDC(hwnd); TextOut(hdc,0,40,temp,strlen(temp)); ReleaseDC(hwnd,hdc); break; case WM_RBUTTONDOWN: point.x=LOWORD(lParam); point.y=HIWORD(lParam); wsprintf(temp,"우측버튼눌림:%04d : %04d", point.x,point.y); hdc=GetDC(hwnd); TextOut(hdc,0,60,temp,strlen(temp)); ReleaseDC(hwnd,hdc); break; case WM_LBUTTONDOWN: //포인트 구조체에 좌표 정보를 넣는다. point.x=LOWORD(lParam); point.y=HIWORD(lParam); //temp에 위치를 넣고 출력 wsprintf(temp,"좌측버튼눌림:%04d : %04d", point.x,point.y); //DC를 받고 문자열을 출력한다. hdc=GetDC(hwnd); TextOut(hdc,0,20,temp,strlen(temp)); ReleaseDC(hwnd,hdc); break;

  21. case WM_MOUSEMOVE: point.x=LOWORD(lParam); point.y=HIWORD(lParam); wsprintf(temp,"키눌림:%s 위치:%04d : %04d", buttondata[wParam],point.x,point.y); hdc=GetDC(hwnd); TextOut(hdc,0,0,temp,strlen(temp)); ReleaseDC(hwnd,hdc); break; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } case WM_RBUTTONUP: point.x=LOWORD(lParam); point.y=HIWORD(lParam); wsprintf(temp,"우측버튼놓음:%04d : %04d", point.x,point.y); hdc=GetDC(hwnd); TextOut(hdc,0,80,temp,strlen(temp)); ReleaseDC(hwnd,hdc); break;

More Related