Notices

Closed Thread
 
Thread Tools Display Modes
Old 01-09-2014, 09:58 AM   #1
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default Keyboard emulator for Saitek Pro Flight Switch Panel

OLD VERSION!

Current thread here


This application enables you to use the Saitek Pro Flight Switch Panel (PZ55) with Digital Combat Simulator

Status = 100% working in DCS.
Did you like this program? Give positive reputation to me and Raf and [FSF]Ian, thanks!

Project is made in C#.

Download files. Project homepage. Sourcecode, use as you please.

--------------------------------------------------------------------------------------------------------------------------------------------------------
Installation
--------------------------------------------------------------------------------------------------------------------------------------------------------
  • Unzip the files into the folder where you want to keep the program.
  • You start the application by executing ProUsbPanels.exe

--------------------------------------------------------------------------------------------------------------------------------------------------------
Short Youtube video explaining how to use the program (old version)

--------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------------------------------------------
Updating the application
--------------------------------------------------------------------------------------------------------------------------------------------------------
Unzip new version over the old.
If for some reason the profile files are changed, i.e. the structure in which the data is stored, delete or rename the old ones and create new profile files. I won't make it backward compatible etc, it takes only a few min to make a profile. New profile format will not happen often if at all anymore. (Just in case it happens)

--------------------------------------------------------------------------------------------------------------------------------------------------------
Important notes
--------------------------------------------------------------------------------------------------------------------------------------------------------
When opening the external text editor by clicking the button for the first time you get the the dialog "Windows can't open this file" dialog. That is because Windows is not familiar with the file type "*.pup_bindings". What you do is click "Select a program from a list of installed programs" and click "OK".
From the next dialog choose "Notepad" and click "OK". This way Windows knows what to use next time you want to open a profile file.


--------------------------------------------------------------------------------------------------------------------------------------------------------
For landing gear light support read this.
--------------------------------------------------------------------------------------------------------------------------------------------------------
You need to install DCS-BIOS. Status today (11 Jan 2015) is that the A-10C and UH-1H are supported.
Please download and read the Flight Panels & DCS-BIOS Guide.
Attached Thumbnails
Click image for larger version

Name:	main_window.png
Views:	1541
Size:	287.8 KB
ID:	93044   Click image for larger version

Name:	profile_file.png
Views:	892
Size:	45.4 KB
ID:	93045  

Last edited by ArturDCS; 08-03-2015 at 07:15 AM. Reason: Spelling
ArturDCS is offline  
Old 01-09-2014, 05:57 PM   #2
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

reserved

Last edited by ArturDCS; 01-20-2014 at 03:07 PM. Reason: reserved
ArturDCS is offline  
Old 01-10-2014, 12:36 PM   #3
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

Anyone have any idea why e.g. LCONTROL doesn't work? If I send LCONTROL + F only F is received and the fuel switch is turned on/off. (UH-1H Huey)
But when I am in OPTIONS -> CONTROLS it is properly received.

VirtualKeyCodes as defined in http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx .
KEYEVENTF_EXTENDEDKEY used as specified on MSDN.
Code:
            /*Extended-Key Flag
                The extended-key flag indicates whether the keystroke message originated from one of the additional keys on the 
             * enhanced keyboard. 
             * The extended keys consist of the 
             * ALT and CTRL keys on the RIGHT HAND side of the keyboard; 
             * The INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; 
             * the NUM LOCK key; the BREAK (CTRL+PAUSE) key; the PRINT SCRN key; and the divide (/) and ENTER keys in the numeric
             * keypad. The extended-key flag is set if the key is an extended key.*/
Code:
 public static void SendKeys(VirtualKeyCode[] virtualKeyCodes)
        {
            var inputs = new WindowsAPI.INPUT[virtualKeyCodes.Count()];

            var modifierCount = 0;
            foreach (var virtualKeyCode in virtualKeyCodes)
            {
                if (Common.IsModifierKey(virtualKeyCode))
                {
                    modifierCount++;
                }
            }
            //Add modifiers
            for (var i = 0; i < virtualKeyCodes.Count(); i++)
            {
                var virtualKeyCode = virtualKeyCodes[i];
                if (Common.IsModifierKey(virtualKeyCode))
                {
                    inputs[i].type = WindowsAPI.INPUT_KEYBOARD;
                    inputs[i].ki.time = 0;
                    inputs[i].ki.dwFlags = WindowsAPI.KEYEVENTF_SCANCODE;
                  
                    if (Common.IsExtendedKey(virtualKeyCode))
                    {
                        inputs[i].ki.dwFlags |= WindowsAPI.KEYEVENTF_EXTENDEDKEY;
                    }
                    inputs[i].ki.wVk = 0;
                    inputs[i].ki.wScan = (ushort)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0);
                    inputs[i].ki.dwExtraInfo = WindowsAPI.GetMessageExtraInfo();
                }
                i++;
            }

            //Add normal keys
            for (var i = modifierCount; i < virtualKeyCodes.Count(); i++)
            {
                var virtualKeyCode = virtualKeyCodes[i];
                if (!Common.IsModifierKey(virtualKeyCode))
                {
                    inputs[i].type = WindowsAPI.INPUT_KEYBOARD;
                    inputs[i].ki.time = 0;
                    inputs[i].ki.dwFlags = WindowsAPI.KEYEVENTF_SCANCODE;
                    inputs[i].ki.wVk = 0;
                    
                    inputs[i].ki.wScan = (ushort)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0);
                    inputs[i].ki.dwExtraInfo = WindowsAPI.GetMessageExtraInfo();
                    i++;
                }
            }

            IntPtr hwnd = WindowsAPI.FindWindow("DCS");
            if (hwnd == IntPtr.Zero)
            {
                hwnd = WindowsAPI.FindWindow("Digital Combat Simulator");
            }
            if (hwnd != IntPtr.Zero)
            {
                WindowsAPI.SetForegroundWindow(hwnd);
                WindowsAPI.SwitchWindow(hwnd);
            }
            WindowsAPI.SendInput((uint)inputs.Count(), inputs, Marshal.SizeOf(typeof(WindowsAPI.INPUT)));

            for (var i = 0; i < inputs.Count(); i++)
            {
                inputs[i].ki.dwFlags |= WindowsAPI.KEYEVENTF_KEYUP;
            }
            Array.Reverse(inputs);
            //Release same keys
            WindowsAPI.SendInput((uint)inputs.Count(), inputs, Marshal.SizeOf(typeof(WindowsAPI.INPUT)));
        }

Any help appreciated!
ArturDCS is offline  
Old 01-10-2014, 09:28 PM   #4
jay43
Member
 
jay43's Avatar
 
Join Date: Mar 2013
Location: Kingston Surrey UK
Posts: 672
Reputation power: 5
jay43 will become famous soon enough
Default

Have a look here http://forums.eagle.ru/showthread.ph...anels+readerit may help you lots have tried to get these to work and some have had some success.
__________________
Eagles may soar high but weasel's don't get sucked into jet engines.
Spoiler:

System Spec.
Monitors: Samsung 570DX & Rift CV1
Mobo: MFG Godlike gaming X-99
CPU: Intel i7 5930K @ 3.50Ghz
RAM: 35gb
GPU: EVGA Nvidia GTX 980Ti VR Ready
Cooling: Predator 360
Power Supply: OCZ ZX Series 80 Plus Gold
Drives: Samsung SSD's 1tb, 500g plus others with OS Win10 64 bit
jay43 is offline  
Old 01-11-2014, 09:42 AM   #5
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

Quote:
Originally Posted by jay43 View Post
Have a look here http://forums.eagle.ru/showthread.ph...anels+readerit may help you lots have tried to get these to work and some have had some success.
Thanks, yes it was Raf's project that gave me the inspiration to do this one. Problem was USB programming and he showed it was relatively easy using LibUSB which I didn't know existed. So after reading that thread I bought myself this switch panel.
Yes his project works and I have been trying to figure out how exactly the Java Robot class calls the window API for sending the key presses but I have not been able to find exact information.
Either it is not possible or I am missing some small puzzle. Today I will try inside the Frogfot module and see whether that too reacts the same way.
I will also implement long key presses (user setting) in my application and key binding profile save/save as/open to work properly.
ArturDCS is offline  
Old 01-12-2014, 11:54 AM   #6
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

v0.2 available.

Problem with LCONTROL/RCONTROL/LALT/RALT/LSHIFT/RSHIFT still unsolved.
Added key binding profile handling and length key presses.
ArturDCS is offline  
Old 01-13-2014, 06:15 AM   #7
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

Got it! Robot.keyPress uses the keybd_event API.
Quote:
Originally Posted by MSDN
The keyboard driver's interrupt handler calls the keybd_event function.Note This function has been superseded. Use SendInput instead.
Why most posts I found pointed to using SendInput which is fully understandable.

I will change it to keybd_event funtion and compile and upload v 0.3 today.

Code:
        public static void SendKeys(VirtualKeyCode[] virtualKeyCodes, KeyPressLength keyPressLength)
        {
            /*
            //keybd_event
            http://msdn.microsoft.com/en-us/library/windows/desktop/ms646304%28v=vs.85%29.aspx
            // Simulate a key press
            WindowsAPI.keybd_event(VK_NUMLOCK,
                         0x45,
                         KEYEVENTF_EXTENDEDKEY | 0,
                         0);

            // Simulate a key release
            WindowsAPI.keybd_event(VK_NUMLOCK,
                         0x45,
                         KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
                         0);
            */
            IntPtr hwnd = WindowsAPI.FindWindow("DCS");
            if (hwnd == IntPtr.Zero)
            {
                hwnd = WindowsAPI.FindWindow("Digital Combat Simulator");
            }
            if (hwnd != IntPtr.Zero)
            {
                WindowsAPI.SetForegroundWindow(hwnd);
                WindowsAPI.SwitchWindow(hwnd);
            }

            //Press modifiers
            for (var i = 0; i < virtualKeyCodes.Count(); i++)
            {
                var virtualKeyCode = virtualKeyCodes[i];
                if (Common.IsModifierKey(virtualKeyCode))
                {
                    Common.DebugP(Enum.GetName(typeof(VirtualKeyCode), virtualKeyCode) + " is MODIFIER = " + Common.IsExtendedKey(virtualKeyCode)); 
                    if (Common.IsExtendedKey(virtualKeyCode))
                    {
                        WindowsAPI.keybd_event((byte)virtualKeyCode, (byte)WindowsAPI.MapVirtualKey((uint)virtualKeyCode,0),(int)WindowsAPI.KEYEVENTF_EXTENDEDKEY | 0,0);
                    }else
                    {
                        WindowsAPI.keybd_event((byte)virtualKeyCode, (byte)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0), 0, 0);
                    }
                }
            }

            //Press normal keys
            for (var i = 0; i < virtualKeyCodes.Count(); i++)
            {
                var virtualKeyCode = virtualKeyCodes[i];
                if (!Common.IsModifierKey(virtualKeyCode))
                {
                    WindowsAPI.keybd_event((byte)virtualKeyCode, (byte)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0), 0, 0);
                }
            }

            if(keyPressLength != KeyPressLength.Zero)
            {
                var startMilliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                var nowMilliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                while(nowMilliseconds - startMilliseconds < (int)keyPressLength)
                {
                    Common.DebugP("Will wait " + keyPressLength + " ms before releasing keys");
                    nowMilliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                }
            }
            
            //Release normal keys
            for (var i = 0; i < virtualKeyCodes.Count(); i++)
            {
                var virtualKeyCode = virtualKeyCodes[i];
                if (!Common.IsModifierKey(virtualKeyCode))
                {
                    WindowsAPI.keybd_event((byte)virtualKeyCode, (byte)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0), (int)WindowsAPI.KEYEVENTF_KEYUP, 0);
                }
            }

            //Release modifiers
            for (var i = 0; i < virtualKeyCodes.Count(); i++)
            {
                var virtualKeyCode = virtualKeyCodes[i];
                if (Common.IsModifierKey(virtualKeyCode))
                {
                    Common.DebugP(Enum.GetName(typeof(VirtualKeyCode), virtualKeyCode) + " is MODIFIER = " + Common.IsExtendedKey(virtualKeyCode));
                    if (Common.IsExtendedKey(virtualKeyCode))
                    {
                        WindowsAPI.keybd_event((byte)virtualKeyCode, (byte)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0), (int)(WindowsAPI.KEYEVENTF_EXTENDEDKEY | WindowsAPI.KEYEVENTF_KEYUP), 0);
                    }
                    else
                    {
                        WindowsAPI.keybd_event((byte)virtualKeyCode, (byte)WindowsAPI.MapVirtualKey((uint)virtualKeyCode, 0), (int)WindowsAPI.KEYEVENTF_KEYUP, 0);
                    }
                }
            }

        }
ArturDCS is offline  
Old 01-13-2014, 09:05 AM   #8
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

Version v0.3 is up.

Commit:
Changed Windows API from SendInput to keybd_event. After this LCONTROL, RCONTROL etc works in game & under OPTIONS -> CONTROLS. Added refresh button, to be used when editing the profile with text editor in the background. Proper About page.

Please Observe!
There are some funny stuff going on at least from my keyboard when reading key input. For example [Alt Gr] ends up as LCONTROL + RMENU which in turn doesn't work in game for a command which has "RAlt" specified. You can edit a "funny" profile using a ASCII editor and remove the "LCONTROL +" and save. Use the "Refresh" button to refresh the profile in the GUI and it should work.
ArturDCS is offline  
Old 01-13-2014, 05:24 PM   #9
goonybird
Junior Member
 
goonybird's Avatar
 
Join Date: Oct 2005
Location: Columbus, Ohio, USA
Posts: 37
Reputation power: 0
goonybird is an unknown quantity at this point
Send a message via ICQ to goonybird Send a message via MSN to goonybird
Default

Finally! I am able to use everything in my cockpit!... Thank you for your work! Will be giving this a full testing tomorrow, just had time to test the landing gear knob...the first problem I came across,though, was the graphic... the labeling was cut off:


also, I haven't explored it fully, the letter "C"seems not to work with "LCont"
Aside from the graphic, will give this a full "wring-out" tomorrow.... Thanks again!!!
goonybird is offline  
Old 01-14-2014, 05:27 AM   #10
ArturDCS
Member
 
Join Date: Dec 2013
Posts: 262
Reputation power: 3
ArturDCS will become famous soon enough
Default

Quote:
Originally Posted by goonybird View Post
Thank you for your work!
Thank you for the feedback.

Quote:
Originally Posted by goonybird View Post
the letter "C"seems not to work with "LCont"
Correct, I have the same thing.
What you have to do is :
  • add the key "C" to that switch.
  • Save the profile
  • Open the profile in Notepad.
  • Check the command for the switch, it should read OSKeyPress{FiftyMilliSec,VK_C}
  • Edit it so it reads OSKeyPress{FiftyMilliSec,LCONTROL + VK_C}.
  • Refresh the profile in the Flight Panels
and you should be good to go.
This is a special feature (CTRL + C, others too?) and I don't know why it is like that. I won't look into to it at this moment as there are other combinations/keys that gives "funny" or no readings in the GUI. The main this is that the profile can be edited manually and after that it works.

Quote:
Originally Posted by goonybird View Post
the first problem I came across,though, was the graphic... the labeling was cut off:
Thanks for the screenshot! Yesterday I experienced this when I changed a property in the Window (when programming) so I changed this back and it looks OK on my computer, funny you have something completely different. This must be something related to Microsoft WPF and I will look into it today.

Here are the virtual key codes that are used when reading user input in the textboxes (some are not related to the keyboard and not in use):
Code:
LBUTTON
RBUTTON
CANCEL
MBUTTON
XBUTTON1
XBUTTON2
BACK
TAB
CLEAR
RETURN
SHIFT
CONTROL
MENU
PAUSE
CAPITAL
KANA
HANGEUL
HANGUL
JUNJA
FINAL
HANJA
KANJI
ESCAPE
CONVERT
NONCONVERT
ACCEPT
MODECHANGE
SPACE
PRIOR
NEXT
END
HOME
LEFT
UP
RIGHT
DOWN
SELECT
PRINT
EXECUTE
SNAPSHOT
INSERT
DELETE
HELP
VK_0
VK_1
VK_2
VK_3
VK_4
VK_5
VK_6
VK_7
VK_8
VK_9
VK_A
VK_B
VK_C
VK_D
VK_E
VK_F
VK_G
VK_H
VK_I
VK_J
VK_K
VK_L
VK_M
VK_N
VK_O
VK_P
VK_Q
VK_R
VK_S
VK_T
VK_U
VK_V
VK_W
VK_X
VK_Y
VK_Z
LWIN
RWIN
APPS
SLEEP
NUMPAD0
NUMPAD1
NUMPAD2
NUMPAD3
NUMPAD4
NUMPAD5
NUMPAD6
NUMPAD7
NUMPAD8
NUMPAD9
MULTIPLY
ADD
SEPARATOR
SUBTRACT
DECIMAL
DIVIDE
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12
F13
F14
F15
F16
F17
F18
F19
F20
F21
F22
F23
F24
NUMLOCK
SCROLL
LSHIFT
RSHIFT
LCONTROL
RCONTROL
LMENU
RMENU
BROWSER_BACK
BROWSER_FORWARD
BROWSER_REFRESH
BROWSER_STOP
BROWSER_SEARCH
BROWSER_FAVORITES
BROWSER_HOME
VOLUME_MUTE
VOLUME_DOWN
VOLUME_UP
MEDIA_NEXT_TRACK
MEDIA_PREV_TRACK
MEDIA_STOP
MEDIA_PLAY_PAUSE
LAUNCH_MAIL
LAUNCH_MEDIA_SELECT
LAUNCH_APP1
LAUNCH_APP2
OEM_1
OEM_PLUS
OEM_COMMA
OEM_MINUS
OEM_PERIOD
OEM_2
OEM_3
OEM_4
OEM_5
OEM_6
OEM_7
OEM_8
OEM_102
PROCESSKEY
PACKET
ATTN
CRSEL
EXSEL
EREOF
PLAY
ZOOM
NONAME
PA1
OEM_CLEAR
ArturDCS is offline  
Closed Thread

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT. The time now is 08:45 AM. vBulletin Skin by ForumMonkeys. Powered by vBulletin®.
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.