I want to make a keyboard hook that send keys to Audacity , althought you are working on other app. I have two the separate parts, one from a forum sample and the other is the hook. I need to find the process that runs audacity to pass the keys. If someone has experience with this, it would be great.
Thanks everybody in advanced.
first part from forum viewtopic.php?f=2&t=21639&hilit=hook modified:
Code: Select all
'run audacity.exe, send key
' Windows console app
'
#include once "windows.bi"
dim as integer pid,res
dim as string tfn,txt
dim as HANDLE kproc,edit = 0,hWnd = 0
dim as STARTUPINFO si
si.cb=len(si)
dim as PROCESS_INFORMATION pi
declare function Get_hWnd (pid as integer) as hWnd
'
tfn="C:\Program Files (x86)\Audacity\audacity.exe" 'may need complete path
res=CreateProcess(NULL,tfn,NULL,NULL,NULL,_
NULL,NULL,NULL,@si,@pi)
'
if res=0 then
print "Failed to start Audacity"
print "Press a key to Exit"
sleep
end
end if
'
'wait for process initialization
res=WaitForInputIdle(pi.hProcess,2000) 'error if res<>0
'
'get notepad's hWnd from process id
pid=pi.dwProcessId
hWnd=Get_hWnd(pid) 'error if hWnd=0
'
'get notepad's "Edit" window hWnd
'edit=FindWindowEx(hWnd,Null,"Edit",Null) 'error if edit=0
'
'send it some text
txt="Hello World!"
'res=SendMessage(hWnd,WM_SETTEXT,Null,cast(LPARAM,strptr(txt)))
PostMessage(hWnd,WM_KEYDOWN, VK_F1,0)
print "Sleeping to Exit.."
sleep
'
'This kills the notepad instance, brutally
kproc=OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE,FALSE,pid)
if kproc>0 then
res=TerminateProcess(kproc,0) 'fail if res=FALSE
CloseHandle(kproc)
end if
'end
'
function Get_hWnd(pid as integer) as hWnd
'
dim as integer ProcID
dim as HWND hWnd=0
'
hWnd=FindWindow(NULL,NULL)
do while hWnd>0
if GetParent(hwnd)=0 then
GetWindowThreadProcessId(hWnd,@ProcID)
if ProcID=pid then
return hWnd
end if
end if
hWnd=GetWindow(hWnd,GW_HWNDNEXT)
loop
'
return 0
'
end function
Code: Select all
#include once "windows.bi"
#include once "crt.bi"
#include once "fbgfx.bi"
using fb
'
declare function On_Key(idHook as integer,_
lpfn as HOOKPROC) as integer
'
declare function KBProc1(ByVal Code As integer, _
ByVal wParam As integer,_
ByVal lParam As integer) As integer
'
dim shared KBHandle as HHOOK
dim shared hwnd as HWND
dim as integer res
dim shared as integer idKey,LastKey
'
type _hookstruct_ 'see MDSN "KeyboardProc"
as ubyte state : 1
as ubyte prevkey : 1
as ubyte alt : 1
as ubyte reserved : 4
as ubyte extended : 1
scancode as ushort
repeat as uinteger
end type
'
Function WndProc( byval hWnd as HWND,_
byval uMsg as uint,_
byval wParam as uint,_
byval lParam as uint) as uint
dim hDC as HDC
dim ps as PAINTSTRUCT
select case uMsg
case WM_PAINT
hDC = BeginPaint( hWnd, @ps )
'' Update the display.
EndPaint( hWnd, @ps )
case WM_DESTROY
PostQuitMessage( null )
Return 0
end select
return DefWindowProc( hWnd, uMsg, wParam, lParam )
end function
function WinMain ( byval hInstance as HINSTANCE,_
byval hPrevInstance as HINSTANCE,_
lpCmdLine as string,_
byval nCmdShow as uint ) as uint
dim msg as MSG
dim wc as WNDCLASSEX
with wc
.cbSize = sizeof( WNDCLASSEX )
.style = CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
.lpfnWndProc = cast( WNDPROC, @WndProc )
.cbClsExtra = null
.cbWndExtra = null
.hInstance = hInstance
.hbrBackground = cast( HBRUSH,COLOR_WINDOW + 1 )
.lpszMenuName = null
.lpszClassName = @"mywindow"
.hIcon = null
.hCursor = LoadCursor ( null, IDC_ARROW )
.hIconSm = 0
end with
RegisterClassEx( @wc )
hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,_
"mywindow",_
"Test",_
WS_OVERLAPPEDWINDOW,_
0,0,500,370,_
null, null,_
hInstance, null )
ShowWindow( hWnd, SW_SHOWNORMAL )
On_Key(37,@KBProc1) 'see MultiKey scancodes, winuser.bi
while (GetMessage(@msg, NULL, 0, 0))
TranslateMessage(@msg)
DispatchMessage(@msg)
Wend
UnhookWindowsHookEx(KBHandle)
Print "Sleeping to Exit.. press a key"
return msg.wParam
End Function
end WinMain( GetModuleHandle( null ), null, command$, SW_NORMAL )
'
function On_Key(idHook as integer,_
lpfn as HOOKPROC) as integer
idKey=idHook
'KBHandle=SetWindowsHookEx(WH_KEYBOARD,_
KBHandle=SetWindowsHookEx(WH_KEYBOARD_LL,_
lpfn,_
NULL,_
0)
End function
'
Dim Shared As KBDLLHOOKSTRUCT kbdStruct
function KBProc1(ByVal Code As integer, _
ByVal wParam As integer,_
ByVal lParam As integer) As integer
Print "HOOK procedure..."
If (Code >= 0) Then
' the action is valid: HC_ACTION.
if (wParam = WM_KEYDOWN)Then
' lParam is the pointer to the struct containing the data needed, so cast and assign it to kdbStruct.
kbdStruct = *(Cast(KBDLLHOOKSTRUCT Ptr,lParam))
' a key (non-system) is pressed.
if (kbdStruct.vkCode = VK_F1) Then
' F1 is pressed!
MessageBox(NULL, "F1 is pressed!", "key pressed", MB_ICONINFORMATION)
'Dim As HWND WindowToFind = FindWindow(null, "???????")
'PostMessage(WindowToFind,WM_KEYDOWN, VK_F1,0)
End If
End if
End If
'
'pass-on keys we don't want
KBProc1=CallNextHookEx(KBHandle,_
Code, wParam, lParam)
End Function