C#에서 마우스 매크로 만드는 것을 차례대로 진행 해보겠습니다. (코드는 맨 마지막에 있습니다!)
만들어본 후엔 필요한 기능을 추가하셔서 사용하시면 되겠습니다. (어렵지 않아요~)
먼저 Visual Studio에서 Windows Form 만들기를 해줍니다.
전 .NET Framework 를 사용하였는데 .NET Core를 선택하셔도 상관 없습니다.
.NET Framework는 Windows 에서만 사용 가능하고
.NET Core는 다른 운영체제에서도 사용 가능합니다. 점차 .NET Core를 밀고 있는 추세입니다만
전 윈도우로 하니깐 그냥 프레임워크로 가겠슴돠
이름은 MouseMacro 입니다. ㄱㄱ
다른 기능 다 필요없습니다. 일단 폼 크기를 마음대로 줄여줍니다.
그리고 오른쪽 하단에 있는 속성 창에서 딱 두가지만 세팅해줍니다. (폼 클릭하고도 속성창이 안보이면 F4 누르세요)
FormBorderStyle = FixedToolWindow
Text = Mouse Macro
로 설정해주겠습니다. 훌륭한 UI 세팅으로 여기까지 따라하셨다면 벌써 70% 완성했습니다.
이제 F7을 눌러서 (혹은 마우스 오른쪽 클릭-> 코드 보기) 코드 보기로 갑시다.
MouseMacro를 오른쪽 클릭하면 사진처럼 새 항목을 추가할 수 있게 됩니다. 눌러줍시다.
클래스를 새로 만들겁니다. 이름은 HookManager로 결정하겠습니다.
Win32 API 를 사용할 것이기 때문에 코드를 복사 붙여넣기 하면 됩니다.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MouseMacro
{
public class HookManager
{
#region WindowsAPI_Mouse Event
[DllImport("user32.dll" ) ]
static extern void mouse_event (uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo ) ;
const uint MOUSEEVENTF_MOVE = 0x0001 ;
const uint MOUSEEVENTF_ABSOLUTE = 0x8000 ;
const uint MOUSEEVENTF_LEFTDOWN = 0x0002 ;
const uint MOUSEEVENTF_LEFTUP = 0x0004 ;
const uint MOUSEEVENTF_RIGHTDOWN = 0x0008 ;
const uint MOUSEEVENTF_RIGHTUP = 0x00010 ;
const uint MOUSEEVENTF_WHEEL = 0x0800 ;
#endregion
#region WindowsAPI_Key Hook
[DllImport("user32.dll" ) ]
private static extern IntPtr SetWindowsHookEx (int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId ) ;
[DllImport("user32.dll" ) ]
private static extern bool UnhookWindowsHookEx (IntPtr hInstance ) ;
[DllImport("user32.dll" ) ]
private static extern IntPtr CallNextHookEx (IntPtr idHook, int nCode, int wParam, IntPtr lParam ) ;
[DllImport("kernel32.dll" ) ]
private static extern IntPtr LoadLibrary (string lpFileName ) ;
private delegate IntPtr LowLevelKeyboardProc (int nCode, IntPtr wParam, IntPtr lParam ) ;
private LowLevelKeyboardProc lowLevelKeyboardProc = HookProc;
const int WH_KEYBOARD_LL = 13 ;
const int WM_KEYDOWN = 256 ;
const int WM_KEYUP = 257 ;
const int WM_SYSKEYDOWN = 260 ;
private static IntPtr hookId = IntPtr.Zero;
#endregion
private static Point preMousePosition;
private static int leftControl = 1 ;
private static int controlKey = 0 ;
private static uint wheel = 120 ;
private static uint backWheel = unchecked ((uint )-120 );
public void SetHook ( )
{
IntPtr hInstance = LoadLibrary("User32" );
hookId = SetWindowsHookEx(WH_KEYBOARD_LL, lowLevelKeyboardProc, hInstance, 0 );
}
public void UnHook ( )
{
UnhookWindowsHookEx(hookId);
}
public static IntPtr HookProc (int code, IntPtr wParam, IntPtr lParam )
{
if (code >= 0 )
{
if (wParam == (IntPtr)WM_KEYDOWN)
{
Keys key = (Keys)Marshal.ReadInt32(lParam);
switch (key)
{
case Keys.NumPad0:
mouse_event(MOUSEEVENTF_LEFTDOWN, 0 , 0 , 0 , 0 );
mouse_event(MOUSEEVENTF_LEFTUP, 0 , 0 , 0 , 0 );
return (IntPtr)1 ;
case Keys.NumPad1:
Cursor.Position = new Point(preMousePosition.X, preMousePosition.Y);
return (IntPtr)1 ;
case Keys.NumPad4:
preMousePosition = Cursor.Position;
return (IntPtr)1 ;
case Keys.LControlKey:
controlKey |= leftControl;
break ;
case Keys.Up:
if (controlKey > 0 )
{
mouse_event(MOUSEEVENTF_WHEEL, 0 , 0 , wheel, 0 );
return (IntPtr)1 ;
}
break ;
case Keys.Down:
if (controlKey > 0 )
{
mouse_event(MOUSEEVENTF_WHEEL, 0 , 0 , backWheel, 0 );
return (IntPtr)1 ;
}
break ;
}
}
else if (wParam == (IntPtr)WM_KEYUP)
{
Keys key = (Keys)Marshal.ReadInt32(lParam);
switch (key)
{
case Keys.LControlKey:
controlKey &= ~leftControl;
break ;
}
}
}
return CallNextHookEx(hookId, code, (int )wParam, lParam);
}
}
}
코드가 좀 길지만 다른 곳은 보지 말고 (관심 있다면 살펴봐도 좋습니다.)
public static IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam)
이 곳만 보고 입 맛에 맞게 수정하면 됩니다.
로직을 설명해보면
if (code >= 0) // 무언가 키 이벤트가 발생했다.
if (wParam == (IntPtr)WM_KEYDOWN) //ㅇㅇ 키가 눌렸다고!
Keys key = (Keys)Marshal.ReadInt32(lParam)
key == Keys.???
이제 key가 무엇인지에 따라 동작을 해주면 됩니다.
(참고로 Alt 키는 wParam == WM_SYSKEYDOWN)
(Label 또는 MessageBox에 출력해서 값을 봐보는 것도 좋습니당)
위의 샘플 코드는 numpad4 : 현재 마우스 위치를 저장하고
numpad1 : 저장 된 마우스 위치로 마우스 커서 이동
numpad0 : 마우스 클릭 발생
ctrl + 마우스 위/아래 : ctrl + wheel을 구현한 것으로 확대, 축소 기능입니다.
자세한 것은 코드를 분석해보시면 되겠습니다. 친절하게 마우스와 키 값에 대한 링크도 해두었습니다!
이제 마무리로 HookManager를 인스턴스화 해서 사용하면 됩니다.
이벤트 두 개만 추가해봅시다. 다시 폼 뷰로 돌아와서 속성 창의 번개 모양을 클릭해줍니다.
그러면 이벤트를 등록할 수 있게 됩니다.
Load를 더블 클릭하면 코드가 자동으로 생성되는데 다시 폼뷰로 돌아와
FormClosing도 더블 클릭해줍니다.
이제 마지막 코드입니다. 간단해유
using System;
using System.Drawing;
using System.Windows.Forms;
namespace MouseMacro
{
public partial class Form1 : Form
{
private HookManager hookManager;
public Form1 ( )
{
InitializeComponent();
}
private void Form1_Load (object sender, EventArgs e )
{
int x = Screen.PrimaryScreen.Bounds.Width - this .Size.Width;
int y = 0 ;
this .Location = new Point(x, y);
hookManager = new HookManager();
hookManager.SetHook();
}
private void Form1_FormClosing (object sender, FormClosingEventArgs e )
{
hookManager.UnHook();
}
}
}
로드 될 때 폼을 오른쪽 상단에 배치하고 훅을 시작합니다.
폼이 꺼질 때 훅을 해제 해주며 마무리 합니다.
여기까지 다 만드셨다면 간단한 마우스 매크로 성공입니다! 실행해서 확인해 보시고..
추가 기능은 HookManager의 HookProc 를 수정해서 사용해보세요~