Restored from previous forum. Originally posted by GPI.
 Is it possible to get the pressed key of every programm and check and modified it, that the active applikation thinks, that an other key is pressed?
For example, i press F1 and the Programm think, i pressed F2.
Why do i need this?
I had bought a keyboard with special keys. One problem is, that the f-keys are also used for special command (open e-mail, etc). The problem is, that this f-key are default with the special commands. I say, that the special-commands are ignored, but not for f5-f8. So i want to write a programm, that can redefinied the keys.
PII 333, 256MB, Asus TNT2Ultra 32MB, AWE Gold 64 4MB
			
			
									
									
						How to catch and change EVERY(!) key
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by DemonHell.
 
To catch keypresses you have to create a callback procedure within a separate DLL. Otherwise you`ll only get keypresses when your apps window has focus
I`ll have a root about for the source code later (must remember to label my backup CD`s !)
But simply put, you get the keycode as a parameter in the callback function, examine it..change it if needed, then pass that on to the default window callback procedure so other apps can access it.
			
			
									
									
						Yup, I did something similar a while back...wrote my own keyboard handler to take care of the "multimedia keys" on the keyboard to control winamp instead of the stupid media player built into the keyboard driver !Originally posted by GPI
Is it possible to get the pressed key of every programm and check and modified it, that the active applikation thinks, that an other key is pressed?
To catch keypresses you have to create a callback procedure within a separate DLL. Otherwise you`ll only get keypresses when your apps window has focus

I`ll have a root about for the source code later (must remember to label my backup CD`s !)
But simply put, you get the keycode as a parameter in the callback function, examine it..change it if needed, then pass that on to the default window callback procedure so other apps can access it.
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by DemonHell.
 
OK.. the first code is the DLL keysnooping code.
(compiled as "dnkbd.dll")
 The next bit is snipped from a very long source, but should give you 
a good idea of what I was doing..
Maybe the entire filtering/code changing code could be moved inside the DLL ..I just used sendmessage_() so I could debug more easily!
			
			
									
									
						OK.. the first code is the DLL keysnooping code.
(compiled as "dnkbd.dll")
Code: Select all
Global hHook.l,msgwnd.l
hHook.l=0
msgwnd.l=0
Procedure.l Keylog(idHook.l,wParam.l,lParam.l)
Shared msgwnd.l
 If msgwnd=0
  msgwnd=findwindowex_(0,0,"STATIC","DnKBD")
 EndIf
 If (idHook>=0)And (wParam=255)
   kc.l=(lparam & $00FF0000)>>16
   kw.l=((lparam & $FF000000)>>24)
   postmessage_(msgwnd,#WM_USER+28,kw,kc)
   ProcedureReturn 0
 EndIf
 ProcedureReturn CallNextHookEx_(hHook,idHook,wParam,lParam)
EndProcedure 
ProcedureDLL.l Init(DLLMod.l,hwnd.l)
 msgwnd.l=hwnd.l
 If hHook0
  messagebox_(0,"Hook already installed","ERROR",#MB_OK)
  unhookwindowshookex_(hHook)
 EndIf
 
 hHook.l=SetWindowsHookEx_(#WH_KEYBOARD,@Keylog(),DLLMod,0)
 If hHook=0
  messagebox_(0,"HOOK INIT ERROR","ERROR",#MB_OK)
 EndIf
 ProcedureReturn hHook
EndProcedure
ProcedureDLL Unhook(hHook)
 If hHook0
  UnHookWindowsHookEx_(hHook)
 EndIf
EndProcedure
a good idea of what I was doing..
Code: Select all
Procedure.l TRAYPROC(hwnd.l,message.l,wParam.l,lParam.l)
 If (message=#WM_USER+28)
  ;## Just to see what keycodes were pressed
  ;## Just do a Select/Case/EndSelect loop to filter and change
  Debug str(wParam)+" "+str(lParam) 
 Endif
 ProcedureReturn CallWindowProc_(oldProc,hwnd,message,wParam,lParam)
EndProcedure
ol.l= OpenLibrary(0,"dnkbd.dll")
If ol=0
 messagebox_(0,"Couldnt find dnkbd.dll","ERROR",#MB_OK)
 End
EndIf
If (IsFunction(0,"_Init")=0)
 messagebox_(0,"Bad dnkbd.dll","ERROR",#MB_OK)
 Closelibrary(0)
 End 
EndIf
MyHwnd.l=createwindowex_(0,"STATIC",appname$,0,0,0,0,0,0,0,0,0)
oldProc.l=GetWindowLong_(MyHwnd,#GWL_WNDPROC)
SetWindowLong_(MyHwnd,#GWL_WNDPROC,@TRAYPROC())
KBD_Hook.l=CallFunction(0,"_Init",ol,MyHwnd)
Repeat
 waitmessage_()
Forever
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by GPI.
Dont work right. I get only message, when the programm-window is active, not global for all programms.
my prg:
main-prg 
PII 333, 256MB, Asus TNT2Ultra 32MB, AWE Gold 64 4MB
			
			
									
									
						Dont work right. I get only message, when the programm-window is active, not global for all programms.
my prg:
Code: Select all
Global scan 
Global hookid 
ProcedureDLL hook(w1,w2,w3) 
 scan=w3>>16&$ff 
 
 ProcedureReturn CallNextHookEx_(hookid,w1,w2,w3) 
EndProcedure 
ProcedureDLL sethookid(x) 
 hookid=x 
EndProcedure 
ProcedureDLL doit() 
 ss=scan:scan=0 
 ProcedureReturn ss 
EndProcedure 
ProcedureDLL AttachProcess(Instance) 
EndProcedure 
ProcedureDLL DetachProcess(Instance) 
EndProcedure 
ProcedureDLL AttachThread(Instance) 
EndProcedure 
ProcedureDLL DetachThread(Instance) 
EndProcedure
Code: Select all
Global hookid 
Global hook_hmod 
hook_hmod=OpenLibrary(0, "C:\Programme\PureBasic\Compilers\purebasic.dll") 
Procedure dehook() 
 If hookid 
  UnhookWindowsHookEx_(hookid) 
 EndIf 
EndProcedure 
Procedure inithook(ins,thr) 
 dehook() 
 ;hookid=SetWindowsHookEx_(#WH_GETMESSAGE,IsFunction(0,"hook"),ins,thr) 
 hookid=SetWindowsHookEx_(#WH_Keyboard,IsFunction(0,"hook"),ins,thr) 
 CallFunction(0,"sethookid",hookid) 
 ProcedureReturn hookid 
EndProcedure 
 
If hook_hmod 
 hook=inithook(hook_hmod,0) 
 OpenWindow(0,0,400,320,240,#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget| #PB_Window_SizeGadget,"Test") 
 CreateGadgetList(WindowID(0)) 
 ListViewGadget(0,0,0,320,240) 
 If hookid 
  AddGadgetItem(0,0,"Hook install"+Hex(hookid)) 
 Else 
  AddGadgetItem(0,0,"Hook error") 
 EndIf  
 Repeat 
  scan=CallFunction(0,"doit") 
  ;Debug scan  
  If scan0 
   AddGadgetItem(0,0,"#down: " +Str(scan)) 
  EndIf 
 Until WindowEvent()=#pb_event_closewindow 
 
 dehook() 
 CloseLibrary(0) 
 CloseWindow(0) 
EndIf 
PII 333, 256MB, Asus TNT2Ultra 32MB, AWE Gold 64 4MB
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by DemonHell.
 
I`m not 100% sure about this, but it could be down the the way windows does its event handling. In my example, I sent a message to another procedure in the main program code.. that gets sent regardless of if the window has focus or not.
In your code, you don`t do the message, and rely on the CallNextHookEx_() to pass on the keypress to your program.
Maybe windows doesn`t bother to pass keypress events on to windows that aren`t active??
			
			
									
									
						Oops, looking back at the source I scrapped together..I didn`t even call the Init function in the DLL ! But, looking at your source, I see you figured that for yourselfOriginally posted by GPI
Dont work right. I get only message, when the programm-window is active, not global for all programms.

I`m not 100% sure about this, but it could be down the the way windows does its event handling. In my example, I sent a message to another procedure in the main program code.. that gets sent regardless of if the window has focus or not.
In your code, you don`t do the message, and rely on the CallNextHookEx_() to pass on the keypress to your program.
Maybe windows doesn`t bother to pass keypress events on to windows that aren`t active??
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm