Sense last key entry on computer, without program being active.

Just starting out? Need help? Post your questions and find answers here.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 301
Joined: Tue Sep 05, 2017 10:07 am

Sense last key entry on computer, without program being active.

Post by matalog »

I have a program that senses mouse movements via

Code: Select all

  XM=DesktopMouseX()
  YM=DesktopMouseY()
That will sense and mouse movement in any program run on my computer wether the PB program is active, selected or not.

Is there a similar command for a keyboard last key press in any program, you know, the last key that was pressed while the PB program is running but not necessarily the active window?
User avatar
idle
Always Here
Always Here
Posts: 5835
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Sense last key entry on computer, without program being active.

Post by idle »

windows

Code: Select all

;-Keyboardhook 
  Structure akey
    ks.a[256]
  EndStructure   
   
  Procedure ProcessKeys(key.s,back=0)  
    
    Debug key 
      
  EndProcedure   
    
  Procedure.i KeyProc(nCode.l,wParam.l,lParam.l)
    
    Protected *keyInput.KBDLLHOOKSTRUCT 
    Static keys.akey 
    Static pos,len  
        
    Protected ret.i, hwnd.i,thwnd.i 
    Protected rs.s=Space(2) 
    Protected doc 
    
    ret = CallNextHookEx_(myKeyhook, nCode, wParam, lParam) 
    
    *keyInput = lParam 
    
    If nCode = #HC_ACTION 
      
      hwnd = GetForegroundWindow_()
          
        Select wParam  
            
          Case #WM_KEYUP
                                 
            keys\ks[*keyInput\vkCode]= $fe
            
            If (GetAsyncKeyState_(#VK_SHIFT) & $8000)  
              keys\ks[#VK_SHIFT]=$fe
            EndIf 
            
            If (GetAsyncKeyState_(#VK_CONTROL) & $8000)  
              keys\ks[#VK_CONTROL]=$fe
            EndIf 
            
            If (GetAsyncKeyState_(#VK_LMENU) & $8000)  
              keys\ks[#VK_LMENU]=$fe
            EndIf 
            
            If (GetAsyncKeyState_(#VK_RMENU) & $8000)  
              keys\ks[#VK_RMENU]=$fe
            EndIf 
            
            If (keys\ks[#VK_ESCAPE] = 0 And keys\ks[#VK_LBUTTON] = 0)
            
              If ToUnicode_(*keyInput\vkCode,*keyInput\scanCode,@keys,@rs,1,2) 
                 ProcessKeys(rs,keys\ks[#VK_BACK])              
              EndIf   
            
            EndIf 
            
            keys\ks[*keyInput\vkCode]=0
            keys\ks[#VK_SHIFT]=0
            keys\ks[#VK_CONTROL]=0
            keys\ks[#VK_LMENU]=0
            keys\ks[#VK_RMENU]=0
            
        EndSelect
       
    EndIf    
    
    ProcedureReturn ret
    
  EndProcedure 
  
  Procedure SetHooks(hInstance=0)
    If hInstance = 0 
      hInstance = GetModuleHandle_(0)
    EndIf 
    If hInstance 
      myKeyhook = SetWindowsHookEx_(#WH_KEYBOARD_LL, @KeyProc(),hInstance,0) 
    Else 
      MessageRequester("hook", "can't get module handle")
    EndIf       
    
  EndProcedure 
  
  Procedure KillHooks()
    UnhookWindowsHookEx_(myKeyhook)
    myKeyHook = 0  
  EndProcedure 
  
  OpenWindow(0,0,0,100,60,"Hook") 
  SetHooks() 
  Repeat 
  Until WaitWindowEvent() = #PB_Event_CloseWindow 
  KillHooks() 
User avatar
matalog
Enthusiast
Enthusiast
Posts: 301
Joined: Tue Sep 05, 2017 10:07 am

Re: Sense last key entry on computer, without program being active.

Post by matalog »

Thanks for that, I'll examine it and see what it uses.

To be clear, I really just want to see if any key has been pressed, that is, if the user is using the keyboard. Does that make it easier?
Rinzwind
Enthusiast
Enthusiast
Posts: 679
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Sense last key entry on computer, without program being active.

Post by Rinzwind »

Mind you, that method does not handle (and kills) 'dead keys (ie US-International keyboard layout)'. Press ' and e to produce é or " and e to get ë.
infratec
Always Here
Always Here
Posts: 7577
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Sense last key entry on computer, without program being active.

Post by infratec »

Use my GetIdleTime() procedure :wink:

https://www.purebasic.fr/english/viewtopic.php?p=615663

It tells you when the last input was done. Mouse or keyboard.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 301
Joined: Tue Sep 05, 2017 10:07 am

Re: Sense last key entry on computer, without program being active.

Post by matalog »

Thanks everyone. Infratec GetIdelTime() is perfect.
Post Reply