Sending Hotkeys

M

Michi

Hi.

In an application "XY" which runs in background, I've defined a hotkey
(Printscreen). So whenever I press printscreen, this app starts
acting.
Now I'm trying to write a little console application in c#, which does
some stuff and than sends a printscreen keystroke, so that "XY" should
start acting.
I'm new to C# and I'm totally overstrained with that keystroke stuff.
I did some tryouts with SendInput (user32.dll) (and had a look at
keybd_event() and at last at System.Windows.Forms.Messages) but didn't
get anything to work. All examples I've found so far looked absolutly
complicate and helped me nothing. So I could really need some help.
Many thanks in advance.
Michi
 
M

Michi

Hi.

In an application "XY" which runs in background, I've defined a hotkey
(Printscreen). So whenever I press printscreen, this app starts
acting.
Now I'm trying to write a little console application in c#, which does
some stuff and than sends a printscreen keystroke, so that "XY" should
start acting.
I'm new to C# and I'm totally overstrained with that keystroke stuff.
I did some tryouts with SendInput (user32.dll) (and had a look at
keybd_event() and at last at System.Windows.Forms.Messages) but didn't
get anything to work. All examples I've found so far looked absolutly
complicate and helped me nothing. So I could really need some help.
Many thanks in advance.
Michi

Hi again,
now I've found a working code and managed to change it for my task,
but there are still some questions left.
Here is the code:

[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
public int type;
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
public int type1;
public short wVk1;
public short wScan1;
public int dwFlags1;
public int time1;
public IntPtr dwExtraInfo1;
}

[DllImport("user32.dll")]
static extern int SendInput(uint nInputs, IntPtr pInputs, int
cbSize);

public static void init()
{
INPUT input = new INPUT();
input.type = 0x01; //INPUT_KEYBOARD
input.wVk = 0x2C; //PRINT SCREEN
input.wScan = 0;
input.dwFlags = 0; //key-down
input.time = 0;
input.dwExtraInfo = IntPtr.Zero;
input.type1 = 0x01;
input.wVk1 = 0x2C; //PRINT SCREEN
input.wScan1 = 0;
input.dwFlags1 = 2; //key-up
input.time1 = 0;
input.dwExtraInfo1 = IntPtr.Zero;

IntPtr pI = Marshal.AllocHGlobal(28);
Marshal.StructureToPtr(input, pI, false);
int result;
//Console.WriteLine(Marshal.SizeOf(input)); // = 40
result = SendInput(1, pI, 28); // why 28 ???
}

Now my questions:
Why is cbSize in that example 28? (and not 40) => How can I calculate
that size, if my calculation is wrong?
How can I send Hotkeys like CONTROL + PRINTSCREEN? I tried to expand
the INPUT struct like:
public int type2;
public short wVk2;
public short wScan2;
public int dwFlags2;
public int time2;
public IntPtr dwExtraInfo2;
public int type3;
public short wVk3;
public short wScan3;
public int dwFlags3;
public int time3;
public IntPtr dwExtraInfo3;
and set those like:
....
input.wVk1 = 0x11; // CONTROL
....
so that the sequence is control down, printscreen down, control up and
printscreen up.
According to my calculation passed 80 for cbSize.
But that didn't work.
Can you tell me what I'm doing wrong?

Many thanks
Michi
 
S

Simon Duvall

Hello,

cbSize needs the size allocated for an INPUT struct type, not the
instantiation thereof (which includes additional data, ergo bytes, ergo
diffrerent size), so you can try:

int inpSize = Marshal.SizeOf(typeof(INPUT));

IntPtr pI = Marshal.AllocHGlobal(inpSize);
Marshal.StructureToPtr(input, pI, false);
int result;
//Console.WriteLine(Marshal.SizeOf(inpSize)); // = 40
result = SendInput(1, pI, inpSize); // why 28 ???



Michi said:
Hi.

In an application "XY" which runs in background, I've defined a hotkey
(Printscreen). So whenever I press printscreen, this app starts
acting.
Now I'm trying to write a little console application in c#, which does
some stuff and than sends a printscreen keystroke, so that "XY" should
start acting.
I'm new to C# and I'm totally overstrained with that keystroke stuff.
I did some tryouts with SendInput (user32.dll) (and had a look at
keybd_event() and at last at System.Windows.Forms.Messages) but didn't
get anything to work. All examples I've found so far looked absolutly
complicate and helped me nothing. So I could really need some help.
Many thanks in advance.
Michi

Hi again,
now I've found a working code and managed to change it for my task,
but there are still some questions left.
Here is the code:

[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
public int type;
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
public int type1;
public short wVk1;
public short wScan1;
public int dwFlags1;
public int time1;
public IntPtr dwExtraInfo1;
}

[DllImport("user32.dll")]
static extern int SendInput(uint nInputs, IntPtr pInputs, int
cbSize);

public static void init()
{
INPUT input = new INPUT();
input.type = 0x01; //INPUT_KEYBOARD
input.wVk = 0x2C; //PRINT SCREEN
input.wScan = 0;
input.dwFlags = 0; //key-down
input.time = 0;
input.dwExtraInfo = IntPtr.Zero;
input.type1 = 0x01;
input.wVk1 = 0x2C; //PRINT SCREEN
input.wScan1 = 0;
input.dwFlags1 = 2; //key-up
input.time1 = 0;
input.dwExtraInfo1 = IntPtr.Zero;

IntPtr pI = Marshal.AllocHGlobal(28);
Marshal.StructureToPtr(input, pI, false);
int result;
//Console.WriteLine(Marshal.SizeOf(input)); // = 40
result = SendInput(1, pI, 28); // why 28 ???
}

Now my questions:
Why is cbSize in that example 28? (and not 40) => How can I calculate
that size, if my calculation is wrong?
How can I send Hotkeys like CONTROL + PRINTSCREEN? I tried to expand
the INPUT struct like:
public int type2;
public short wVk2;
public short wScan2;
public int dwFlags2;
public int time2;
public IntPtr dwExtraInfo2;
public int type3;
public short wVk3;
public short wScan3;
public int dwFlags3;
public int time3;
public IntPtr dwExtraInfo3;
and set those like:
...
input.wVk1 = 0x11; // CONTROL
...
so that the sequence is control down, printscreen down, control up and
printscreen up.
According to my calculation passed 80 for cbSize.
But that didn't work.
Can you tell me what I'm doing wrong?

Many thanks
Michi
 
M

Michi

Hi Simon,
first thanks a lot for your help.
I already tried that, but it didn't work.
result = SendInput(1, pI, inpSize);
Console.WriteLine(Marshal.SizeOf(input));
Console.WriteLine(Marshal.SizeOf(typeof(INPUT)));
both return 80 when I try to send 4 keystrokes (Control down,
Printscreen down, Printscreen up, Control up) (?)
both return 40 when I try to send 2 keystrokes (Printscreen down,
Printscreen up) (?)
In all cases in which I tried it with a calculated size "result" was 0
and the keystrokes were not sent.

Maybe there's another error?
Here's my comlete code for 4 keystrokes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Runtime.InteropServices;
using System.Collections;
using System.Runtime.InteropServices.ComTypes;
using System.Globalization;


namespace KT
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter to start...");
Console.ReadLine();
HotkeyAufruf.init();
Console.WriteLine("End?...");
Console.ReadLine();
}
}

public class HotkeyAufruf
{
public HotkeyAufruf()
{
init();
}

[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
public int type;
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
public int type1;
public short wVk1;
public short wScan1;
public int dwFlags1;
public int time1;
public IntPtr dwExtraInfo1;
public int type2;
public short wVk2;
public short wScan2;
public int dwFlags2;
public int time2;
public IntPtr dwExtraInfo2;
public int type3;
public short wVk3;
public short wScan3;
public int dwFlags3;
public int time3;
public IntPtr dwExtraInfo3;
}

[DllImport("user32.dll")]
static extern int SendInput(uint nInputs, IntPtr pInputs, int
cbSize);


public static void init()
{
INPUT input = new INPUT();

// Key combination
// Keys down
input.type = 0x01; //INPUT_KEYBOARD
input.wVk = 0x11; // CONTROL
input.wScan = 0;
input.dwFlags = 0; //key-down
input.time = 0;
input.dwExtraInfo = IntPtr.Zero;

input.type1 = 0x01;
input.wVk1 = 0x2C; //PRINT SCREEN
input.wScan1 = 0;
input.dwFlags1 = 0; //key-down
input.time1 = 0;
input.dwExtraInfo1 = IntPtr.Zero;


// KeysUp
input.type2 = 0x01;
input.wVk2 = 0x2C; //PRINT SCREEN
input.wScan2 = 0;
input.dwFlags2 = 2; //key-up
input.time2 = 0;
input.dwExtraInfo2 = IntPtr.Zero;

input.type3 = 0x01;
input.wVk3 = 0x11; // CONTROL
input.wScan3 = 0;
input.dwFlags3 = 2; //key-up
input.time3 = 0;
input.dwExtraInfo3 = IntPtr.Zero;

int inpSize = Marshal.SizeOf(typeof(INPUT));
IntPtr pI = Marshal.AllocHGlobal(inpSize);
Marshal.StructureToPtr(input, pI, false);
int result;
//Console.WriteLine(Marshal.SizeOf(input));
//Console.WriteLine(Marshal.SizeOf(typeof(INPUT)));
result = SendInput(1, pI, inpSize);


if (result == 0 || Marshal.GetLastWin32Error() != 0)
{
Console.WriteLine(Marshal.GetLastWin32Error());
}
}
}
}

Kind regads
michi


Hello,

cbSize needs the size allocated for an INPUT struct type, not the
instantiation thereof (which includes additional data, ergo bytes, ergo
diffrerent size), so you can try:

            int inpSize = Marshal.SizeOf(typeof(INPUT));

            IntPtr pI = Marshal.AllocHGlobal(inpSize);
            Marshal.StructureToPtr(input, pI, false);
            int result;
            //Console.WriteLine(Marshal.SizeOf(inpSize)); // = 40
            result = SendInput(1, pI, inpSize); // why 28 ???




Hi again,
now I've found a working code and managed to change it for my task,
but there are still some questions left.
Here is the code:
       [StructLayout(LayoutKind.Sequential)]
       public struct INPUT
       {
           public int type;
           public short wVk;
           public short wScan;
           public int dwFlags;
           public int time;
           public IntPtr dwExtraInfo;
           public int type1;
           public short wVk1;
           public short wScan1;
           public int dwFlags1;
           public int time1;
           public IntPtr dwExtraInfo1;
       }
       [DllImport("user32.dll")]
       static extern int SendInput(uint nInputs, IntPtr pInputs,int
cbSize);
       public static void init()
       {
           INPUT input = new INPUT();
           input.type = 0x01; //INPUT_KEYBOARD
           input.wVk = 0x2C; //PRINT SCREEN
           input.wScan = 0;
           input.dwFlags = 0; //key-down
           input.time = 0;
           input.dwExtraInfo = IntPtr.Zero;
           input.type1 = 0x01;
           input.wVk1 = 0x2C; //PRINT SCREEN
           input.wScan1 = 0;
           input.dwFlags1 = 2; //key-up
           input.time1 = 0;
           input.dwExtraInfo1 = IntPtr.Zero;
           IntPtr pI = Marshal.AllocHGlobal(28);
           Marshal.StructureToPtr(input, pI, false);
           int result;
           //Console.WriteLine(Marshal.SizeOf(input)); // = 40
           result = SendInput(1, pI, 28); // why 28 ???
       }
Now my questions:
Why is cbSize in that example 28? (and not 40) => How can I calculate
that size, if my calculation is wrong?
How can I send Hotkeys like CONTROL + PRINTSCREEN? I tried to expand
the INPUT struct like:
           public int type2;
           public short wVk2;
           public short wScan2;
           public int dwFlags2;
           public int time2;
           public IntPtr dwExtraInfo2;
           public int type3;
           public short wVk3;
           public short wScan3;
           public int dwFlags3;
           public int time3;
           public IntPtr dwExtraInfo3;
and set those like:
...
input.wVk1 = 0x11; // CONTROL
...
so that the sequence is control down, printscreen down, control up and
printscreen up.
According to my calculation passed 80 for cbSize.
But that didn't work.
Can you tell me what I'm doing wrong?
Many thanks
Michi- Zitierten Text ausblenden -

- Zitierten Text anzeigen -
 
M

Michi

Hi again.

Forget about my questions. Solved the problem by passing the keys one
by one, using a nested input struct and a fixed size.

Thanks
Michi
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top