0

Problem is that when i press a global hotkey combination (ctrl + space) and hold the buttons down for a sec, the program loops it and brings up A LOT of the same text, like:

"some text" "some more text" "some text" "some more text" "some text" "some more text"

Lets say the user is old and cannot rapidly release the keyboard buttons. How to make the program perform this global hotkey action ONCE? (even if the hotkeys are pressed for a while). I tried (uint)fsModifiers.Control | (uint)fsModifiers.Norepeat but no effect. Thanks in advance!

protected override void WndProc(ref Message keyPressed)
        {
            if (keyPressed.Msg == 0x0312)
            {
                    System.Threading.Thread.Sleep(300);
                    System.Windows.Forms.SendKeys.Send("some text");
                    System.Threading.Thread.Sleep(500);
                    System.Windows.Forms.SendKeys.Send("{TAB}");
                    System.Threading.Thread.Sleep(500);
                    System.Windows.Forms.SendKeys.Send("{TAB}");
                    System.Threading.Thread.Sleep(500);
                    System.Windows.Forms.SendKeys.Send("some more text");
                    MessageBox.Show("DONE", "DONE", MessageBoxButtons.OK, MessageBoxIcon.Information);       
            }
            base.WndProc(ref keyPressed);
        }

    private void Form1_Load(object sender, EventArgs e)
    {
        RegisterHotKey(this.Handle, 1, (uint)fsModifiers.Control , (uint)Keys.Space);
    }

 public enum fsModifiers
        {
            Alt = 0x0001,
            Control = 0x0002,
            Shift = 0x0004,
            Window = 0x0008,
            Norepeat = 0x4000,
        }
Wagner DosAnjos
  • 6,304
  • 1
  • 15
  • 29
G S
  • 5
  • 3
  • Set a variable to the time when the hotkey was fired. As part of your IF condition, make sure that enough time has passed between the last time it was fired and the current time before setting it again. – user1274820 Aug 10 '15 at 19:30
  • Alternatively, you have RegisterHotkey - I assume you have UnregisterHotkey? Why not call that function after the code is executed since it seems you only want to run it once. – user1274820 Aug 10 '15 at 19:34
  • 1
    Good idea :) thanks! – G S Aug 10 '15 at 19:53
  • The comments in the [documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646309(v=vs.85).aspx) says that `fsModifiers.Norepeat` is not supported in Windows Vista. Are you using by any chance still Vista? – Frank J Aug 10 '15 at 20:07
  • Nope, Win7. The idea with unregistering hotkey helped 100%. And with a next button click its registered again, so it can be used multiple times. Big thanks guys! – G S Aug 11 '15 at 18:46
  • In the Windows API, there are few things that can not be done. Never say this is impossible. I wrote small program in WinAPI and it is possible. Temporary timer will help. Look my example. – 18C Nov 23 '17 at 03:34

1 Answers1

1

Written in C++, I don't know C# but the code show a possible solution for problem.

Solution for Alt+F2.

   static bool locked=false; 
   switch(uMsg)
   {
      case WM_HOTKEY:
      {
         if(wParam==ANY_IDENTIFIER_OF_HOTKEY && !locked)
         {
            if(windows < WINDOWS7)
            {
               locked=true;
               SetTimer(hwnd,0x665,40,NULL); 
            } 
            doAnyAction();
         }
         return 0;
      }
      case WM_TIMER:
      {
         if(wParam==0x665)
         { 
            if(!(GetAsyncKeyState(VK_F2)&0x8000)) // detected key-up
            {
               locked=false;
               KillTimer(hwnd, 0x665);
            }
         }
         return 0;
      }
      ...
   }

...

main:

   if(windows>=WINDOWS7)
      RegisterHotKey(hwnd,ANY_IDENTIFIER_OF_HOTKEY,MOD_ALT|0x4000,VK_F2);
   else
      RegisterHotKey(hwnd,ANY_IDENTIFIER_OF_HOTKEY,MOD_ALT,VK_F2);

Newer say it is impossible. It works for me.

18C
  • 2,014
  • 10
  • 16