C# 마우스 드래그 시키기
View 16,722 | 작성일2012.10.06 20:36
관련링크
본문
인터넷에서 찾아본 결과 C#에서 마우스를 제어할 수 있을것 같긴한데 별로 자료가 없네요...
애니팡 오토를 만드려고 찾는건데 너무 깊이 파고 들기 싫어서 인터넷에 있는 간단한 자료를 이용했습니다.
어쨌든 마우스 클릭하고 드래그만 하면 되니까요 ㅋ
우선 API의 함수를 가져옵니다.
[DllImport("user32.dll")] static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo); |
사용하는 클래스에 dll Import 로 mouse_event 를 가져옵니다.
참고로 마우스 이벤트에서 사용하는 dwFlags 의 값중에 일부도 가져옵니다.
private const uint MOUSEMOVE = 0x0001; // 마우스 이동
private const uint ABSOLUTEMOVE = 0x8000; // 전역 위치
private const uint LBUTTONDOWN = 0x0002; // 왼쪽 마우스 버튼 눌림
private const uint LBUTTONUP = 0x0004; // 왼쪽 마우스 버튼 떼어짐
private const uint ABSOLUTEMOVE = 0x8000; // 전역 위치
private const uint LBUTTONDOWN = 0x0002; // 왼쪽 마우스 버튼 눌림
private const uint LBUTTONUP = 0x0004; // 왼쪽 마우스 버튼 떼어짐
저 함수만 있다면 간단합니다.
마우스 드래그 라는게
특정위치 마우스 좌표 이동 -> 왼쪽버튼 다운 -> 좌표 이동 -> 왼쪽버튼 릴리즈
이런 동작이거든요.
하지만 명령어만 디립다 쓰면 딱 한가지 문제가 생깁니다.
너~무 빠르다는 겁니다.
직접 재보지는 않았지만 저 명령어를 연달아 쓰면 눈에 보이지도 않을정도로 빠르게 움직입니다.
이는 기껏해야 초당 30~60프레임을 사용하는 게임에서는 적절한 동작이 이루어지지 않을 수 있습니다.
30프레임을 기준으로는 한장, 즉 한프레임을 갱신하는 시간은 약 33ms
60프레임을 쓰는 게임이라면, 16ms 의 시간이 필요합니다.
입력을 따로 쓰레드로 받는 경우도 있으니 완전히 맞아 떨어지지는 않으나 어쨌든 받아들이는 쪽에서 어느정도 시간이 필요한 것 만은 사실입니다.
물론 이것도 오토 프로그램에서 이쁘게 큐구조로 만들어 쓰레드로 처리하면 사람이 드래그 하는것과 비슷한 효과를 낼 수 있으나 솔직히 귀찮았습니다.
절대 권장하는 방법은 아닌데 그냥 sleep 함수로 떼웠습니다.
이벤트 드라이븐 방식의 폼 프로그래밍에서 sleep 함수는 권장하지 않습니다.
왜그런지는 아시는 분은 아실테고 모르시면 글하나 더 쓸게요 ㅋ
어쨌든 파는 제품이 아니니 적당히 sleep 을 써줍니다 ㅋ
저는 마우스를 제어하는 함수를 따로 만들어서 관리했습니다.
가장 많이 쓰는 기능이니 함수화는 어느정도 필요하겠죠?
우선 그래서 동작 가능성을 모두 플래그로 담았습니다
·미리보기 | 소스복사·
- enum direction
- {
- UP, DOWN, LEFT, RIGHT, CLICK
- }
이것은 소스코드
·미리보기 | 소스복사·
- private void movemouse(int i, int j, direction flag)
- {
- Point pt = new Point( x + (j*50) + 30, y + (i*50) +30);
- Cursor.Position = pt;
- mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
- if( flag != direction.CLICK )
- System.Threading.Thread.Sleep(Convert.ToInt32( numericDragSPD.Value ));
- switch (flag)
- {
- case direction.UP:
- pt.Y -= 50;
- Cursor.Position = pt;
- mouse_event(MOUSEMOVE, 0, 5, 0, 0);
- break;
- case direction.DOWN:
- mouse_event(MOUSEMOVE, 0, 5, 0, 0);
- break;
- case direction.LEFT:
- pt.X -= 50;
- Cursor.Position = pt;
- mouse_event(MOUSEMOVE, 5, 0, 0, 0);
- break;
- case direction.RIGHT:
- mouse_event(MOUSEMOVE, 5, 0, 0, 0);
- break;
- case direction.CLICK:
- break;
- }
- if (flag != direction.CLICK)
- System.Threading.Thread.Sleep(Convert.ToInt32(numericDragSPD.Value));
- switch (flag)
- {
- case direction.UP:
- mouse_event(MOUSEMOVE, 0, 10, 0, 0);
- break;
- case direction.DOWN:
- mouse_event(MOUSEMOVE, 0, 10, 0, 0);
- break;
- case direction.LEFT:
- mouse_event(MOUSEMOVE, 10, 0, 0, 0);
- break;
- case direction.RIGHT:
- mouse_event(MOUSEMOVE, 10, 0, 0, 0);
- break;
- case direction.CLICK:
- break;
- }
- if (flag != direction.CLICK)
- System.Threading.Thread.Sleep(Convert.ToInt32(numericDragSPD.Value));
- mouse_event(LBUTTONUP, 0, 0, 0, 0);
- }
sleep 부분은 c#폼에서 입력받고 있습니다^^;