using System; using System.Windows.Forms; using Decal.Adapter; namespace Mag.Shared { public static class PostMessageTools { // http://msdn.microsoft.com/en-us/library/dd375731%28v=vs.85%29.aspx private const byte VK_RETURN = 0x0D; private const byte VK_SHIFT = 0x10; private const byte VK_CONTROL = 0x11; private const byte VK_PAUSE = 0x13; private const byte VK_SPACE = 0x20; private static byte ScanCode(char Char) { switch (char.ToLower(Char)) { case 'a': return 0x1E; case 'b': return 0x30; case 'c': return 0x2E; case 'd': return 0x20; case 'e': return 0x12; case 'f': return 0x21; case 'g': return 0x22; case 'h': return 0x23; case 'i': return 0x17; case 'j': return 0x24; case 'k': return 0x25; case 'l': return 0x26; case 'm': return 0x32; case 'n': return 0x31; case 'o': return 0x18; case 'p': return 0x19; case 'q': return 0x10; case 'r': return 0x13; case 's': return 0x1F; case 't': return 0x14; case 'u': return 0x16; case 'v': return 0x2F; case 'w': return 0x11; case 'x': return 0x2D; case 'y': return 0x15; case 'z': return 0x2C; case '/': return 0x35; case ' ': return 0x39; } return 0; } private static byte CharCode(char Char) { switch (char.ToLower(Char)) { case 'a': return 0x41; case 'b': return 0x42; case 'c': return 0x43; case 'd': return 0x44; case 'e': return 0x45; case 'f': return 0x46; case 'g': return 0x47; case 'h': return 0x48; case 'i': return 0x49; case 'j': return 0x4A; case 'k': return 0x4B; case 'l': return 0x4C; case 'm': return 0x4D; case 'n': return 0x4E; case 'o': return 0x4F; case 'p': return 0x50; case 'q': return 0x51; case 'r': return 0x52; case 's': return 0x53; case 't': return 0x54; case 'u': return 0x55; case 'v': return 0x56; case 'w': return 0x57; case 'x': return 0x58; case 'y': return 0x59; case 'z': return 0x5A; case '/': return 0xBF; case ' ': return 0x20; } return 0x20; } public static void SendEnter() { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)VK_RETURN, (UIntPtr)0x001C0001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_RETURN, (UIntPtr)0xC01C0001); } public static void SendPause() { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)VK_PAUSE, (UIntPtr)0x00450001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_PAUSE, (UIntPtr)0xC0450001); } static Timer _spaceReleaseTimer; static DateTime _spaceSendTime; static int _spaceHoldTimeMilliseconds; static bool _spaceAddShift; static bool _spaceAddW; static bool _spaceAddZ; static bool _spaceAddX; static bool _spaceAddC; public static void SendSpace(int msToHoldDown = 0, bool addShift = false, bool addW = false, bool addZ = false, bool addX = false, bool addC = false) { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)VK_SPACE, (UIntPtr)0x00390001); if (msToHoldDown == 0) { if (addShift) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)VK_SHIFT, (UIntPtr)0x002A0001); if (addW) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('w'), (UIntPtr)0x00110001); if (addZ) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('z'), (UIntPtr)0x002C0001); if (addX) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('x'), (UIntPtr)0x002D0001); if (addC) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('c'), (UIntPtr)0x002E0001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_SPACE, (UIntPtr)0xC0390001); if (addW) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('w'), (UIntPtr)0xC0110001); if (addZ) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('z'), (UIntPtr)0xC02C0001); if (addX) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('x'), (UIntPtr)0xC02D0001); if (addC) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('c'), (UIntPtr)0xC02E0001); if (addShift) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_SHIFT, (UIntPtr)0xC02A0001); } else { if (_spaceReleaseTimer == null) { _spaceReleaseTimer = new Timer(); _spaceReleaseTimer.Tick += new EventHandler(SpaceReleaseTimer_Tick); _spaceReleaseTimer.Interval = 1; } _spaceSendTime = DateTime.UtcNow; _spaceHoldTimeMilliseconds = msToHoldDown; _spaceAddShift = addShift; _spaceAddW = addW; _spaceAddZ = addZ; _spaceAddX = addX; _spaceAddC = addC; _spaceReleaseTimer.Start(); } } static void SpaceReleaseTimer_Tick(object sender, EventArgs e) { if (_spaceSendTime.AddMilliseconds(_spaceHoldTimeMilliseconds) <= DateTime.UtcNow) { _spaceReleaseTimer.Stop(); if (_spaceAddShift) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)VK_SHIFT, (UIntPtr)0x002A0001); if (_spaceAddW) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('w'), (UIntPtr)0x00110001); if (_spaceAddZ) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('z'), (UIntPtr)0x002C0001); if (_spaceAddX) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('x'), (UIntPtr)0x002D0001); if (_spaceAddC) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode('c'), (UIntPtr)0x002E0001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_SPACE, (UIntPtr)0xC0390001); if (_spaceAddW) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('w'), (UIntPtr)0xC0110001); if (_spaceAddZ) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('z'), (UIntPtr)0xC02C0001); if (_spaceAddX) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('x'), (UIntPtr)0xC02D0001); if (_spaceAddC) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode('c'), (UIntPtr)0xC02E0001); if (_spaceAddShift) User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_SHIFT, (UIntPtr)0xC02A0001); } } static Timer _movementReleaseTimer; static DateTime _movementSendTime; static int _movementHoldTimeMilliseconds; static char _movementKey; public static void SendMovement(char ch, int msToHoldDown = 0) { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode(ch), (UIntPtr)(0x00000001 + ScanCode(ch) * 0x10000)); if (msToHoldDown == 0) { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode(ch), (UIntPtr)(0xC0000001 + ScanCode(ch) * 0x10000)); } else { if (_movementReleaseTimer == null) { _movementReleaseTimer = new Timer(); _movementReleaseTimer.Tick += new EventHandler(MovementReleaseTimer_Tick); _movementReleaseTimer.Interval = 1; } _movementSendTime = DateTime.Now; _movementHoldTimeMilliseconds = msToHoldDown; _movementKey = ch; _movementReleaseTimer.Start(); } } static void MovementReleaseTimer_Tick(object sender, EventArgs e) { if (_movementSendTime.AddMilliseconds(_movementHoldTimeMilliseconds) <= DateTime.Now) { _movementReleaseTimer.Stop(); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode(_movementKey), (UIntPtr)(0xC0000001 + ScanCode(_movementKey) * 0x10000)); } } public static void SendCntrl(char ch) { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)VK_CONTROL, (UIntPtr)0x001D0001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)CharCode(ch), (UIntPtr)0x00100001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)CharCode(ch), (UIntPtr)0xC0100001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)VK_CONTROL, (UIntPtr)0xC01D0001); } public static void SendAltF4() { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_DESTROY, new IntPtr(0), new UIntPtr(0)); } /// /// Opens/Closes fellowship view /// public static void SendF4() { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)0x00000073, (UIntPtr)0x003E0001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)0x00000073, (UIntPtr)0xC03E0001); } /// /// Opens/Closes main pack view /// public static void SendF12() { User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)0x0000007B, (UIntPtr)0x00580001); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)0x0000007B, (UIntPtr)0xC0580001); } public static void SendMsg(string msg) { foreach (char ch in msg) { byte code = CharCode(ch); uint lparam = (uint)((ScanCode(ch) << 0x10) | 1); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYDOWN, (IntPtr)code, (UIntPtr)(lparam)); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_KEYUP, (IntPtr)code, (UIntPtr)(0xC0000000 | lparam)); } } public static void ClickOK() { User32.RECT rect = new User32.RECT(); User32.GetWindowRect(CoreManager.Current.Decal.Hwnd, ref rect); // The reason why we click at both of these positions is some clients will be running windowed, and some windowless. This will hit both locations SendMouseClick(rect.Width / 2, rect.Height / 2 + 18); SendMouseClick(rect.Width / 2, rect.Height / 2 + 25); SendMouseClick(rect.Width / 2, rect.Height / 2 + 31); } public static void ClickYes() { User32.RECT rect = new User32.RECT(); User32.GetWindowRect(CoreManager.Current.Decal.Hwnd, ref rect); // 800x600 +32 works, +33 does not work on single/double/tripple line boxes // 1600x1200 +31 works, +32 does not work on single/double/tripple line boxes // The reason why we click at both of these positions is some clients will be running windowed, and some windowless. This will hit both locations SendMouseClick(rect.Width / 2 - 80, rect.Height / 2 + 18); SendMouseClick(rect.Width / 2 - 80, rect.Height / 2 + 25); SendMouseClick(rect.Width / 2 - 80, rect.Height / 2 + 31); } public static void ClickNo() { User32.RECT rect = new User32.RECT(); User32.GetWindowRect(CoreManager.Current.Decal.Hwnd, ref rect); // The reason why we click at both of these positions is some clients will be running windowed, and some windowless. This will hit both locations SendMouseClick(rect.Width / 2 + 80, rect.Height / 2 + 18); SendMouseClick(rect.Width / 2 + 80, rect.Height / 2 + 25); SendMouseClick(rect.Width / 2 + 80, rect.Height / 2 + 31); } public static void SendMouseClick(int x, int y) { int loc = (y * 0x10000) + x; User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_MOUSEMOVE, (IntPtr)0x00000000, (UIntPtr)loc); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_LBUTTONDOWN, (IntPtr)0x00000001, (UIntPtr)loc); User32.PostMessage(CoreManager.Current.Decal.Hwnd, User32.WM_LBUTTONUP, (IntPtr)0x00000000, (UIntPtr)loc); } } }