1

I am currently doing a program which will Announce and Countdown from example lets say 5 minutes, So when you press Start button it will count down from 5 minutes to 0,

The thing that I would like to have is this:

If I am in a full-screen game, for example World of Warcraft , League of Legends, or any game with full screen graphics and I press Numpad 8, I want the program to click start on Button 1.

This should be possible since I've seen it before but I don't know how to do it.

BrunoLM
  • 97,872
  • 84
  • 296
  • 452
Frequenzy
  • 11
  • 2
  • So you want to make a global hotkey that works even when a full-screen application has the focus? What do you mean by "I want the Program to click start on Button 1", though? This is the only time you refer to "Button 1". – Justin Apr 11 '11 at 19:00
  • If the user presses 'Numpad 8' in WoW, you want to somehow intercept that keystroke and pass it to your program? It looks like what you want is a keyboard hook. Try http://stackoverflow.com/questions/1776664/c-low-level-keyboard-hook-not-working, among many others. – Jim Mischel Apr 11 '11 at 19:02
  • Justin: What i want is when i press Numpad 8 in for example WoW i want my C# Program to use my Button which is named 'Start' Jim Mischel: I didnt quite understand that since im quite a newbie :) – Frequenzy Apr 11 '11 at 19:17
  • It's a hard problem. Keyboard input usually goes to the active window. You're trying to intercept the event and make it go to two places. You will have to master some fairly advanced concepts if you want to know how that works. The question I linked shows the concept and one implementation. It's up to you to learn more about low-level keyboard hooks and adapt what you learn to your situation. – Jim Mischel Apr 11 '11 at 19:44
  • Ok thanks Jim , i think i might have another idea on how to fix my problem tho but dunno how to :p If i forexample made a new Form , how could i make so its Ontop of All windows all the time ? is that possible in Fullscreen ?^^ – Frequenzy Apr 11 '11 at 19:54
  • I think the bigger question here is: what problem are you trying to solve? That is, why do you need to capture keystrokes that were meant for another program? And, no, you can't guarantee that your program will always be on top. See http://blogs.msdn.com/b/oldnewthing/archive/2011/03/10/10138969.aspx – Jim Mischel Apr 11 '11 at 20:07
  • There is a method to place a form on top of all other windows, but I'm not sure how well it works with full screen Direct 3D applications. For lack of further knowledge, I'd have to agree with Jim that you can't guarantee your form will always be on top. However, if you somehow to manage to keep your form on top at all times, you have to realize that all keystrokes will now be sent to your form, and none to the full screen game. – Ayush Apr 11 '11 at 20:26
  • Yea i realize that the keystrokes will be sent to my form instead of the game but thats not what i were gonna use it for :p – Frequenzy Apr 11 '11 at 20:39
  • Blizzard tends to frown upon third party applications hooking things their game is using. This is one of the mechanisms ToS-breaking software uses to provide bots, false network glitches and single-point-of-control multiboxing. Beware, don't get banned! – djdanlib Apr 11 '11 at 21:09
  • Alright i have the solution for me :P definitly I just found this-> http://channel9.msdn.com/Forums/TechOff/225782-Shortcut-keys-to-buttons-in-C-program But i dont know how to pull it off :p anyone intressed in helping me ? – Frequenzy Apr 11 '11 at 22:26

1 Answers1

0

I tested it on League of Legends and Terraria. The following works:

public static class WindowsAPI
{
    public enum HookType : int
    {
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_HARDWARE = 8,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct KeyboardHookStruct
    {
        public int VirtualKeyCode;
        public int ScanCode;
        public int Flags;
        public int Time;
        public int ExtraInfo;
    }

    public delegate IntPtr HookProc(int nCode, IntPtr wp, IntPtr lp);

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern IntPtr SetWindowsHookEx(HookType idHook, HookProc lpfn, IntPtr hInstance, uint threadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern bool UnhookWindowsHookEx(IntPtr hHook);

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern IntPtr CallNextHookEx(HookType idHook, int nCode, IntPtr wParam, IntPtr lParam);
}

Then to "hook" it up:

public partial class Form1 : Form
{
    private IntPtr kbhook = IntPtr.Zero;

    private void Form1_Load(object sender, EventArgs e)
    {
        kbhook = WindowsAPI.SetWindowsHookEx(WindowsAPI.HookType.WH_KEYBOARD_LL, HandleKeyPress, IntPtr.Zero, 0);

        if (kbhook == IntPtr.Zero)
            Application.Exit();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        WindowsAPI.UnhookWindowsHookEx(kbhook);
    }


    private IntPtr HandleKeyPress(int nCode, IntPtr wp, IntPtr lp)
    {
        WindowsAPI.KeyboardHookStruct MyKeyboardHookStruct =
            (WindowsAPI.KeyboardHookStruct)Marshal.PtrToStructure(lp, typeof(WindowsAPI.KeyboardHookStruct));

        var key = (Keys)MyKeyboardHookStruct.VirtualKeyCode;

        // **********************************
        // if the pressed key is Keys.NumPad8
        if (key == Keys.NumPad8)
        {
            button1_Click(null, EventArgs.Empty);
        }

        return WindowsAPI.CallNextHookEx(WindowsAPI.HookType.WH_KEYBOARD_LL, nCode, wp, lp);
    }
}

pinvoke.net may have outdated code samples, but it helps to know the method signatures.

BrunoLM
  • 97,872
  • 84
  • 296
  • 452