Page 1 of 1

GetAsyncKey and suppressing keystrokes

Posted: Sat Mar 08, 2008 9:40 am
by Susan20
Hi, I control my PB-mp3-player with numpad-keys (via GetAsyncKey) while using Windows Word. It works, but the disadvantage is, that by doing so the keys can be found in the document then. Is there any possibility to prevent these keys from being inserted in the word-document? - Thanks! Susan

Posted: Sat Mar 08, 2008 10:44 am
by tinman
If you are happy to use the Windows API then you could try using hotkeys and catch the #WM_HOTKEY message: http://msdn2.microsoft.com/en-us/librar ... S.85).aspx

Posted: Sat Mar 08, 2008 3:48 pm
by netmaestro
A keyboard hook routine is ideal for this as once you've used the information from the pressed key you can suppress it going to other applications. Here is a sample from my QuickSnap screenshot program that uses the spacebar to take a screenshot without passing the space to any other programs:

DLL code:

Code: Select all

;========================================================
; Program:          SpaceHook.pb
; Author:           netmaestro
; Date:             October 11, 2006
; Version:          1.0
; Project:          QuickSnap
; Target Compiler:  PureBasic 4.0
; Target OS:        Microsoft Windows All
; License:          Free, unrestricted for legal uses 
; Usage:            Compile with PB 4.0 to a shared dll
;                   and make available to QuickSnap
;=========================================================

Global addr.l, KeyboardHook

Procedure Attachprocess(instance)
CompilerIf Defined(KBDLLHOOKSTRUCT, #PB_Structure) = 0
  Structure KBDLLHOOKSTRUCT
    vkCode.l
    scanCode.l
    flags.l
    time.l
    dwExtraInfo.l
  EndStructure
CompilerEndIf
EndProcedure

ProcedureDLL KeyboardProc(ncode,wparam,lparam)
   *keycode.KBDLLHOOKSTRUCT=lparam
    If wParam = #WM_KEYDOWN
      Select *keycode\vkCode
      Case #VK_SPACE
        PokeL(addr,#True)
        ProcedureReturn 1
      EndSelect 
    EndIf
  ProcedureReturn CallNextHookEx_( KeyboardHook, nCode, wParam, lParam )
EndProcedure

ProcedureDLL InitHook(value, hookproc)
  addr = value
  KeyboardHook=hookproc
EndProcedure
Calling code from the QuickSnap program:

Code: Select all

  Global saving.l
  
  hooklib = OpenLibrary(0,"SpaceHook.dll")
  If hooklib
    keyproc=GetFunction(0, "KeyboardProc")
    KeyboardHook=SetWindowsHookEx_(#WH_KEYBOARD_LL,keyproc,hooklib,0)
    CallFunction(0, "InitHook", @saving, KeyboardHook)    
  EndIf
  
  ; more code
  ;
  UnhookWindowsHookEx_(KeyboardHook)
  
The saving variable is checked in the main loop and when it turns to #True, the spacebar keypress is detected. The ProcedureReturn 1 in the dll code tells the OS to remove the keypress from the queue now that you've used it. If you pressed it from Word or notepad or some other program that uses keyboard input, that program will never see it.

Posted: Sat Mar 08, 2008 4:27 pm
by akj
@netmaestro
What is the purpose of this line?

Code: Select all

PokeL(addr,#True)

Posted: Sat Mar 08, 2008 5:18 pm
by netmaestro
addr is the address of the "saving" variable in the main program. It is being set to #True from the DLL.

Posted: Sat Mar 08, 2008 9:55 pm
by Susan20
Thanks a lot for all the answers! Keyboard hook sounds reasonable, but it is not necessary. Using RegisterHotKey and SetWindowCallback has the effect I wanted. The code is only a few lines.

@tinman:
You got me on the right way!!