• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1191
  • Last Modified:

Keyboard hook without DLL

Can anybody help me to create a keyboard hook in delphi without using DLLs?
I would appreciate if someone can provide some WORKING samples..

- Other method would also help me if keyboard hook is not practical without using a dll.
- I need to get all the key presses even if my application is not in focus. That's is the main requirement.
- I need to limit the whole application to a single exe.
0
jimsweb
Asked:
jimsweb
2 Solutions
 
mlmccCommented:
What is the purpose of this program?

Why do you want to capture all keypresses even those unrelated to your program?

mlmcc
0
 
jimswebAuthor Commented:
;-)
thanks for ur comments.
Definitely not for a keylogger.
I work with mainframes and involves mostly console windows. so i am planning to automate snd popup some windows as user types on the console window. hope this helps.
0
 
aikimarkCommented:
There are some 3270 emulators written in Delphi.  One of my RTP-DIG members wrote one back in the 90s.  There are third party 3270 emulators that might provide hooks for the user events you need to trap.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jimswebAuthor Commented:
I have worked on tn3270 and IBM's pcom etc. None of these are having this hook feture AFAIK.
Moreover i'm planning for an ' intelliscense' type popus over the cosole window. so, somehow i need to find out a good hookup mechanism. thanks for ur comments.
0
 
aikimarkCommented:
I just spoke with the member and he mentioned that he had two possible solutions.  In addition to the 3270 emulator, he also wrote a keyboard hook.  The places he posted his emulator no longer exists, so he'll look at his files when he gets home.  With any luck, he'll join this question thread and provide you with a solution.
0
 
jimswebAuthor Commented:
Thanks a lot.
0
 
nzkiwi100Commented:
Jim as Mark says I have a background in MVS UI 3270 data stream programming and 3270 emulator development in Delphi Java and C, and have also recently written a simple Windows tray program that hooks the keyboard and is able to catch keystrokes on their way to the emulator or any other windows program. Both of these are in the 5000 line size area so I probably cant list them here. However the hook thing is interesting so I think covering that may help you and others - see attached code

Ther are 3 functions
  - KeyBdSetHook  -- done once when your program starts      
  - KeyBdRemoveHook  -- done when your program ends
  - KeyBdHookProc -- called by Windows for every key stroke so its got to be fast. Also note that it can throw away key strokes (by not calling CallNextHookEx) and cause other keystrokes to be sent to the application !  In this extract the call to PostMessage signals the rest of my app to do its thing while allowing Windows to continue processing keystrokes when the function terminates.

Compiled as 31 bi code this is tested and works on XP and Win7
//-------------------------------------------------------------------------
// Key board functions
//-------------------------------------------------------------------------

function KeyBdHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT ; stdcall ;
const
  VK_W = $00000057 ;
  VK_MOD = $FF ;
type
  TKbDllHookStruct = record
    vkCode: DWORD ;
    scanCode: DWORD ;
    flags: DWORD ;
    time: DWORD ;
    dwExtraInfo: Pointer ;
  end ;
  PKbDllHookStruct = ^TKbDllHookStruct ;
  TByte4 = array[0..3] of byte ;
  PByte4 = ^TByte4 ;
var
  kbh: PKbDllHookStruct ;
  ctrl,alt: byte ;
  PKey4: PByte4 ;
  Key: string[1] ;
begin
  if code = HC_ACTION then
    begin
      { this procedure is called every time a keyboard message is processed }
      if (wParam = WM_KEYDOWN) then
        begin
          ctrl := GetAsyncKeyState(VK_CONTROL) shr ((sizeof(short)*8)-1) ;
          alt := GetAsyncKeyState(VK_MENU) shr ((sizeof(short)*8)-1) ;
          if (ctrl = VK_MOD) and (alt = VK_MOD) then
            begin
              // shift := GetAsyncKeyState(VK_SHIFT) shr ((sizeof(short)*8)-1) ;
              kbh := Pointer(lParam) ;
              ZrdLaunchForm.DebugMsg(
                Format('HookKeyBd co: %d wp: %8.8x vkc: %8.8x scn: %8.8x flg: %8.8x ctrl: %2.2x alt: %2.2x',
                [code,wParam,kbh^.vkCode,kbh^.scanCode,kbh^.flags,ctrl,alt]),4) ;
              { convert DWORD form of key into string }
              PKey4 := addr(kbh^.vkCode) ;        { point at DWORD }
              Key[0] := chr($01) ;                { set length }
              Move(PKey4[0],Key[1],1) ;           { extract key from string }
              { check if key pressed is in search key string }
              if pos(key,SearchKeys) > 0 then
                begin
                  SendFlg := True ;
                  SaveKey := kbh^.vkCode ;
                  Result := 1 ;
                  ZrdLaunchForm.DebugMsg(Format('Ctrl+Alt+%s (%8.8x) selected',
                    [Key,SaveKey]),1) ;
                end
              else
                Result := CallNextHookEx(KeyBdHookHandle, Code, wParam, lParam) ;
            end
          else
            Result := CallNextHookEx(KeyBdHookHandle, Code, wParam, lParam) ;
        end
      else
        begin
          if SendFlg then
            begin
              ctrl := GetAsyncKeyState(VK_CONTROL) shr ((sizeof(short)*8)-1) ;
              alt := GetAsyncKeyState(VK_MENU) shr ((sizeof(short)*8)-1) ;
              if (ctrl <> VK_MOD) and
                (alt <> VK_MOD) then
                begin
                  SendFlg := False ;
                  { try GetFocusData() }
                  FocusDataText := ZrdLaunchForm.GetFocusData ;
                  { post saved kbh.vkCode to our DefaultHandler() procedure }
                  PostMessage(ZrdLaunchForm.Handle,ZrdLaunchKeyMsg,SaveKey,0) ;
                  ZrdLaunchForm.DebugMsg(Format('SaveKey: %8.8x',[SaveKey]),4) ;
                end ;
            end ;
          Result := CallNextHookEx(KeyBdHookHandle, Code, wParam, lParam) ;
        end ;
    end
  else
    { call the next hook in the chain. NB: that leaving this out would
      effectively remove this message}
    Result := CallNextHookEx(KeyBdHookHandle, Code, wParam, lParam) ;
end ;

function TZrdLaunchForm.KeyBdSetHook: Boolean ; stdcall ;
begin
  Result := FALSE ;
  DebugMsg('Keyboard hooked',1) ;
  if not KeyBdIsHooked then  { make sure the key board hook is not already set }
    begin
      DesktopWin := GetDesktopWindow ;     { get a handle to the desktop window }
      { set this hook as a system level hook }
      KeyBdHookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, KeyBdHookProc, HInstance, 0) ;
      Result := KeyBdHookHandle <> 0 ;     { indicate if the hook was set right }
      KeyBdIsHooked := Result ;      { set local variable if hook was set }
      DebugMsg(Format('KeyBdSetHook hh: %8.8x',[KeyBdHookHandle]),4) ;
    end ;
end ;

function TZrdLaunchForm.KeyBdRemoveHook: Boolean ; stdcall ;
var
  rcb: BOOL ;
  rc: integer ;
begin
  Result := FALSE ;
  DebugMsg('Keyboard hook removed',1) ;
  if (KeyBdIsHooked) and (KeyBdHookHandle <> 0) then     { remove the hook }
    begin
      rcb := UnhookWindowsHookEx(KeyBdHookHandle) ;
      rc := integer(rcb) ;
      DebugMsg(Format('KeyBdRemoveHook hh: %8.8x rc: %d',
        [KeyBdHookHandle,rc]),4) ;
      if rcb then
        begin
          KeyBdIsHooked := False ;      { reset the local variable }
          Result := True ;
        end
      else
        Result := False ;
    end ;
end ;

Open in new window

0
 
aikimarkCommented:
Welcome (back), nzkiwi100.
0
 
jimswebAuthor Commented:
Thanks everyone.
@ nzkiwi100
It is highly appreciated if you could put the same on an article in the article section.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now