VirtualDJ SendInput
Posted: 06 Aug 2010, 11:43
Iv been trying to send keyboard shortcuts to Virtual DJ, the usual send Keys do not work on virtual DJ as it uses direct Input which bypasses windows usual keyboard input.
Here is the class im using to accomplish this.
plus an example to use it. the form just contains 3 buttons to play deck a deck b and auto play
the comport accepts input from a diy hardware controller i built.
Here is the class im using to accomplish this.
Code: Select all
using System.Runtime.InteropServices;
using System;
using System.Globalization;
public struct HardwareInput
{
public uint uMsg;
public ushort wParamL;
public ushort wParamH;
}
public struct KeyboardInput
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
public struct MouseInput
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Explicit)]
public struct Input
{
// Fields Change 8 to 4 for 32bit
[FieldOffset(8)]
public HardwareInput hi;
[FieldOffset(8)]
public KeyboardInput ki;
[FieldOffset(8)]
public MouseInput mi;
[FieldOffset(0)]
public IntPtr type;
}
public enum VK : ushort
{
ADD = 0x6b,
BACK = 8,
CONTROL = 0x11,
DECIMAL = 110,
DELETE = 0x2e,
DIVIDE = 0x6f,
DOWN = 40,
END = 0x23,
ESCAPE = 0x1b,
EXECUTE = 0x2b,
F1 = 0x70,
F10 = 0x79,
F11 = 0x7a,
F12 = 0x7b,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 120,
HELP = 0x2f,
HOME = 0x24,
INSERT = 0x2d,
LEFT = 0x25,
LWIN = 0x5b,
M = 0x4d,
MEDIA_NEXT_TRACK = 0xb0,
MEDIA_PLAY_PAUSE = 0xb3,
MEDIA_PREV_TRACK = 0xb1,
MEDIA_STOP = 0xb2,
MENU = 0x12,
MULTIPLY = 0x6a,
NEXT = 0x22,
NUMPAD0 = 0x60,
NUMPAD1 = 0x61,
NUMPAD2 = 0x62,
NUMPAD3 = 0x63,
NUMPAD4 = 100,
NUMPAD5 = 0x65,
NUMPAD6 = 0x66,
NUMPAD7 = 0x67,
NUMPAD8 = 0x68,
NUMPAD9 = 0x69,
OEM_1 = 0xba,
OEM_2 = 0xbf,
OEM_3 = 0xc0,
OEM_COMMA = 0xbc,
OEM_MINUS = 0xbd,
OEM_PERIOD = 190,
OEM_PLUS = 0xbb,
PRINT = 0x2a,
PRIOR = 0x21,
RETURN = 13,
RIGHT = 0x27,
RWIN = 0x5c,
SELECT = 0x29,
SEPARATOR = 0x6c,
SHIFT = 0x10,
SNAPSHOT = 0x2c,
SUBTRACT = 0x6d,
TAB = 9,
UP = 0x26
}
public class VDJcontroller
{
// Fields
private const int INPUT_HARDWARE = 2;
private const int INPUT_KEYBOARD = 1;
private const int INPUT_MOUSE = 0;
private const int KEYEVENTF_EXTENDEDKEY = 1;
private const int KEYEVENTF_KEYDOWN = 0;
private const int KEYEVENTF_KEYUP = 2;
private const int KEYEVENTF_SCANCODE = 8;
private const int KEYEVENTF_UNICODE = 4;
public IntPtr TargetWindowHandle;
private const int VK_M = 0x4d;
private const int VK_NUMLOCK = 0x90;
// Methods
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public void GetWindowHandle(string ClassName, string WindowTitle)
{
this.TargetWindowHandle = FindWindow(ClassName, WindowTitle);
}
[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, Input[] pInputs, int cbSize);
public void SendVDJKeyboardInput(string ScanCode, bool ShiftKey, bool CtrlKey, bool AltKey)
{
uint num;
SetForegroundWindow(this.TargetWindowHandle);
Input[] pInputs = new Input[1];
pInputs[0].type = (IntPtr) 1;
if (ShiftKey)
{
pInputs[0].ki.dwFlags = 0;
pInputs[0].ki.wVk = 0x10;
pInputs[0].ki.wScan = 0x2a;
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
}
if (CtrlKey)
{
pInputs[0].ki.dwFlags = 0;
pInputs[0].ki.wVk = 0x11;
pInputs[0].ki.wScan = 0x1d;
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
}
if (AltKey)
{
pInputs[0].ki.dwFlags = 0;
pInputs[0].ki.wVk = 0x12;
pInputs[0].ki.wScan = 0x38;
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
}
pInputs[0].ki.dwFlags = 0;
pInputs[0].ki.wVk = 0x4d;
pInputs[0].ki.wScan = ushort.Parse(ScanCode, NumberStyles.HexNumber);
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
pInputs[0].ki.dwFlags = 2;
pInputs[0].ki.wVk = 0x4d;
pInputs[0].ki.wScan = ushort.Parse(ScanCode, NumberStyles.HexNumber);
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
if (ShiftKey)
{
pInputs[0].ki.dwFlags = 2;
pInputs[0].ki.wVk = 0x10;
pInputs[0].ki.wScan = 0x2a;
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
}
if (CtrlKey)
{
pInputs[0].ki.dwFlags = 2;
pInputs[0].ki.wVk = 0x11;
pInputs[0].ki.wScan = 0x1d;
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
}
if (AltKey)
{
pInputs[0].ki.dwFlags = 2;
pInputs[0].ki.wVk = 0x12;
pInputs[0].ki.wScan = 0x38;
num = SendInput(1, pInputs, Marshal.SizeOf(pInputs[0]));
}
}
[DllImport("user32.dll")]
private static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
the comport accepts input from a diy hardware controller i built.
Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace mattDac
{
public partial class Form1 : Form
{
private static System.IO.Ports.SerialPort serialPort1;
private VDJcontroller myController = new VDJcontroller();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.myController.GetWindowHandle("VIRTUALDJ", "VIRTUALDJ");
if (this.myController.TargetWindowHandle == IntPtr.Zero)
{
MessageBox.Show("Virtual DJ is not running. Stop the mapper, start VDJ and run it again.");
Application.Exit();
}
try
{
serialPort1 = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
serialPort1.DtrEnable = true;
serialPort1.Open();
// attach function to delegate (one time)
serialPort1.DataReceived += OnReceived;
}
catch (System.IO.IOException)
{
MessageBox.Show("COM PORT 4 not found, Ensure DAC is conected and Device manager shows device as COM4");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
/*
* scancodes
* hex 01 = Escape key
* hex 02 = 1 or ! key
* hex 03 = 2 or @ key
* hex 04 = 3 or # key
* hex 05 = 4 or $ key
* hex 06 = 5 or % key
* hex 07 = 6 or ^ key
* hex 08 = 7 or & key
* hex 09 = 8 or * key
* hex 0A = 9 or ( key
* hex 0B = 0 or ) key
* hex 0C = - or _ key
* hex 0D = = or + key
* hex 0E = Backspace key
* hex 0F = Tab key
* hex 10 = q or Q key
* hex 11 = w or W key
* hex 12 = e or E key
* hex 13 = r or R key
* hex 14 = t or T key
* hex 15 = y or Y key
* hex 16 = u or U key
* hex 17 = i or I key
* hex 18 = o or O key
* hex 19 = p or P key
* hex 1A = [ or { key
* hex 1B = ] or } key
* hex 1E = a or A key
* hex 1F = s or S key
* hex 20 = d or D key
* hex 21 = f or F key
* hex 22 = g or G key
* hex 23 = h or H key
* hex 24 = j or J key
* hex 25 = k or K key
* hex 26 = l or L key
* hex 27 = ; or : key
* hex 28 = ' or " key
* hex 29 = ` or ~ key
* hex 2B = \ or | key
* hex 2C = z or Z key
* hex 2D = x or X key
* hex 2E = c or C key
* hex 2F = v or V key
* hex 30 = b or B key
* hex 31 = n or N key
* hex 32 = m or M key
* hex 33 = , or < key
* hex 34 = . or > key
* hex 35 = / or ? key
* hex 3B = F1 key
* hex 3C = F2 key
* hex 3D = F3 key
* hex 3E = F4 key
* hex 3F = F5 key
* hex 40 = F6 key
* hex 41 = F7 key
* hex 42 = F8 key
* hex 43 = F9 key
* hex 44 = F10 key
* */
private void OnReceived(object sender, SerialDataReceivedEventArgs c)
{
try
{
// write out text coming back from the arduino
string read = serialPort1.ReadLine();
string[] split = read.Split(new Char[] { ',' });
if (split[0]=="play1")
{
this.myController.SendVDJKeyboardInput("15", true, true, true);
}
if (split[0] == "play2")
{
this.myController.SendVDJKeyboardInput("14", true, true, true);
}
if (split[0] == "play3")
{
this.myController.SendVDJKeyboardInput("13", true, true, true);
}
}catch(Exception ex){
MessageBox.Show(ex.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
this.myController.SendVDJKeyboardInput("15", true, true, true);
}
private void button2_Click(object sender, EventArgs e)
{
this.myController.SendVDJKeyboardInput("14", true, true, true);
}
private void button3_Click(object sender, EventArgs e)
{
this.myController.SendVDJKeyboardInput("13", true, true, true);
}
}
}