Bonjour a tous !
J'ai commencé un projet ou je souhaiterai pouvoir faire poper le clavier virtuel ( ça c'est la partie facile ) au moment ou l'utilisateur clique sur un contrôleur ou il est possible d’écrire ( textbox dans une page web, notepad, words, cellule excel, .... )( ça c'est la partie ou j'ai des soucis ).
Après enquête j'ai découvert les "Windows Messages", j'arrive à récupérer le processus sur lequel le focus est :
Code C/C++ :
HWND GetGlobalFocus()
{
// remember focus window for the current thread
HWND hWndLocalFocus = GetFocus();
// find foreground window
HWND hWndFore = GetForegroundWindow();
if (hWndFore == NULL)
return NULL;
// get IDs of the current thread and the thread that
// owns foreground window
DWORD dwCurrID = GetCurrentThreadId();
DWORD dwForeID = GetWindowThreadProcessId(hWndFore, NULL);
// if the current thread owns foreground window then just
// return hWndLocalFocus
if (dwForeID == dwCurrID)
return hWndLocalFocus;
// attach input states of the current thread and the foreground
// thread
if (!AttachThreadInput(dwCurrID, dwForeID, TRUE))
return NULL;
// now the current thread and the foreground thread have common
// input state and we can query for a focus window
HWND hWndGlobalFocus = GetFocus();
// detach threads
AttachThreadInput(dwCurrID, dwForeID, FALSE);
// restore local focus
SetFocus(hWndLocalFocus);
return hWndGlobalFocus;
}
unsigned long GetTargetThreadIdFromWindow()
{
HWND targetWnd;
HANDLE hProcess;
unsigned long processID = 0;
targetWnd = GetGlobalFocus();
return GetWindowThreadProcessId(targetWnd, &processID);
}
et donc j'injecte ma petite DLL dedans :
Code C/C++ :
HINSTANCE hinst = LoadLibrary(L"WindowsHookDLL.dll");
MSG uMsg;
cout << "load DLL: " << hinst << endl;
system("PAUSE");
if(!hinst){
cout << "ERROR DLL" << endl;
system("PAUSE");
return 0;
}
typedef void (*Install)(unsigned long);
typedef void (*Uninstall)();
Install install = (Install) GetProcAddress(hinst, "install");
Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");
while(true){
system("CLS");
PrintActualWindow();
unsigned long threadID = GetTargetThreadIdFromWindow();
cout << "ThreadID: "<< threadID<<endl;
install(threadID);
//Sleep(2000);
}
uninstall();
system("PAUSE");
return 0;
petite DLL qui écoute les windows messages :
Code C/C++ :
#include <iostream>
//#include <string>
#include <windows.h>
#include <fstream>
#include "WindowsMessages.h";
using namespace std;
HINSTANCE hinst;
#pragma data_seg(".shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
LRESULT CALLBACK MessageHookProcedure(int code, WPARAM wParam, LPARAM lParam){
WindowsMessages WM = WindowsMessages(((CWPSTRUCT*)lParam)->message);
boolean jump = WM.getMessageJump();
if(!jump){
ofstream myfile;
myfile.open ("D:/test.txt", ios::out | ios::app );
myfile << "get: " << WM.getMessageCode() << " " << WM.getMessageName() << "n";
myfile.close();
}
return CallNextHookEx(hhk,code,wParam,lParam);
}
extern "C" __declspec(dllexport) void install() {
hhk = SetWindowsHookEx(WH_CALLWNDPROC, MessageHookProcedure, hinst, NULL);
}
extern "C" __declspec(dllexport) void uninstall() {
UnhookWindowsHookEx(hhk);
}
BOOL WINAPI DllMain( __in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved){
hinst = hinstDLL;
return TRUE;
}
ma class WindowsMessages c'est juste histoire d'avoir tous les windows messages ID ( le numéro hexa ) et le nom en chaine de caractère, histoire de pouvoir lire le log.
Le truc c'est que je reçois des milliards de messages différent , je sais pas lequel je dois attraper ou même si ce message existe.
Des idées ?
Merci !