LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam);
void processKey();
void register_hook();
void unregister_hook();
void MsgLoop();
####
typedef struct delayed {
INPUT data;
struct delayed * next;
} delayed;
typedef unsigned char byte;
void send_string (const wchar_t * str);
void send_cmd(int time, byte vkcode);
void sendDelayedKeys();
void paste_from_clpb(int dk)
####
#include
#include
#include "stdio.h"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "hook.h"
#include "send_string.h"
HHOOK hook;
int delayedSize = 0;
delayed * start = NULL;
delayed * last = NULL;
LRESULT CALLBACK HookCallback( int nCode, WPARAM wParam, LPARAM lParam ) {
KBDLLHOOKSTRUCT * p = ( KBDLLHOOKSTRUCT * ) lParam;
int kup = p->flags & LLKHF_UP;
int alt = p->flags & LLKHF_ALTDOWN;
int ext = p->flags & LLKHF_EXTENDED;
processKey( kup, p->vkCode, alt, ext );
return CallNextHookEx( hook, nCode, wParam, lParam );
}
void processKey( int kup, int vkCode, int alt, int ext ) {
//printf ("processKey in C\n");
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
EXTEND( SP, 4 );
PUSHs( sv_2mortal( newSViv(kup) ) );
PUSHs( sv_2mortal( newSViv(vkCode) ) );
PUSHs( sv_2mortal( newSViv(alt) ) );
PUSHs( sv_2mortal( newSViv(ext) ) );
PUTBACK;
//count = call_pv( "Adder", G_SCALAR );
int count = call_pv( "Win32::Shortkeys::Kbh::process_key", G_DISCARD );
PUTBACK;
FREETMPS;
LEAVE;
if ( count != 0 ) croak("Big trouble\n");
}
void MsgLoop() {
MSG message;
while ( GetMessage( &message, NULL, 0, 0 ) ) {
TranslateMessage(&message);
DispatchMessage(&message);
}
}
void register_hook() {
HMODULE hMod = (HMODULE) GetModuleHandle(NULL);
hook = SetWindowsHookEx( WH_KEYBOARD_LL, HookCallback, hMod, 0 );
}
void unregister_hook() {
UnhookWindowsHookEx(hook);
DWORD hookThreadId = GetCurrentThreadId();
PostThreadMessage( hookThreadId, WM_QUIT, 0, 0L );
}
void send_string( const wchar_t * str ) {
printf( "send_string : %s L:%i\n", str, wcslen(str) );
INPUT inp [2];
memset( inp, 0, sizeof(INPUT) );
inp [0] . type = INPUT_KEYBOARD;
/**
* KEYEVENTF_UNICODE flag send the string as Unicode characters.
* Unicode makes life easy because you don't have
* to synthesize capital letters using the Shift key. Without KEYEVENTF_ UNICODE,
* you'd have to send capital E as
* followed by e, with down/up events for each, for a total of four keystrokes.
*/
// to avoid shift, and so on
inp [0] . ki . dwFlags = KEYEVENTF_UNICODE;
inp [1] = inp [0];
inp [1] . ki . dwFlags |= KEYEVENTF_KEYUP;
int count = 0;
const wchar_t * p;
for ( p = str; *p; p++ ) {
count++;
if (delayedSize > 0 && count ==1 ){
inp[0].ki.wVk = inp[1].ki.wVk = LOBYTE(VkKeyScan(*p));
//inp[0].ki.wScan = inp[1].ki.wScan = *p;
} else {
inp[0].ki.wVk = inp[1].ki.wVk = 0;
//inp[0].ki.wScan = inp[1].ki.wScan = *p;
}
inp[0].ki.wScan = inp[1].ki.wScan = *p;
printf("wScan has %i\n", *p);
SendInput(2, inp, sizeof(INPUT));
if (count ==1){
sendDelayedKeys();
}
}//for
}
void send_cmd(int time, byte vkcode){
time*=2; //doubler le nombre de touche delete à envoyer
int size = time;
INPUT i[size];
//printf ("sendCmd : %d \n", cont++);
ZeroMemory(&i,sizeof(i));
int sendKey = 0;
int j;
for (j=0;j