Приветствую. Передо мной стоит задача на лету "заменять" коды клавиш клавиатуры. Как это сделать? Я перехватывал с помощью глобального хука все нажатия в системе Код (Text): #define _DEBUG_ #include "stdafx.h" #include <stdio.h> #include "debug.h" #pragma comment(linker, "/SECTION:.rds,RWS") #pragma data_seg(".rds")//Shared data among all instances. HHOOK g_MainHhook = 0; struct HINSTANCE__ * g_MainHandle = 0; struct HINSTANCE__ * g_hThread = 0; DWORD g_ThreadId = 0; #pragma data_seg() extern "C" LRESULT __declspec(dllexport) CALLBACK KeyboardProc( int nCode, WPARAM wParam, LPARAM lParam) { LRESULT RetVal; DbgPrintEx("%c[0x%02X | 0x%08X] key\n",wParam ,wParam, wParam); RetVal = CallNextHookEx( g_MainHhook, nCode, wParam, lParam ); return RetVal; } //----------------------------------------------------------------------- extern "C" __declspec(dllexport) BOOL __stdcall HookAddProc() { g_MainHhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,g_MainHandle,0); if(!g_MainHhook) { DbgPrintEx("Error set hook : %d\n",GetLastError()); return FALSE; } else { DbgPrintEx("Hooks injected : 0x%08X\n",(ULONG)g_MainHhook); return TRUE; } } //----------------------------------------------------------------------- extern "C" __declspec(dllexport) BOOL __stdcall HookDelProc() { if(!g_MainHhook) { DbgPrintEx("Error delete hook : %d no handle\n",GetLastError()); return FALSE; } else { UnhookWindowsHookEx(g_MainHhook); DbgPrintEx("Hooks deleted: 0x%08X\n",(ULONG)g_MainHhook); return TRUE; } } //----------------------------------------------------------------------- BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { DbgPrintEx("Hook Library : %s\n","loaded"); if(ul_reason_for_call == DLL_PROCESS_ATTACH) { g_MainHandle = (struct HINSTANCE__ *)hModule; } return TRUE; } //----------------------------------------------------------------------- Перехватываются но не заменяются, т.е. в замена wParam в CallBack функции никчему не приводит... Решил попробовать Subclassing, но остановился на том что не могу перечислить адреса функций окон.. Код (Text): #include "stdafx.h" #include <windows.h> #include "debug.h" void EnableDebugPrivilege() { HANDLE hToken; TOKEN_PRIVILEGES tokenPriv; LUID luidDebug; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME , &luidDebug)) { tokenPriv.PrivilegeCount = 1; tokenPriv.Privileges [0].Luid = luidDebug; tokenPriv.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL); } if(LookupPrivilegeValue(NULL,SE_MACHINE_ACCOUNT_NAME,&luidDebug)) { tokenPriv.PrivilegeCount = 2; tokenPriv.Privileges [0].Luid = luidDebug; tokenPriv.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL); } } } BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam) { WNDPROC pProc = 0; //printf("\tChild : HANDLE : 0x%08X, PARAM : 0x%08X, WNDPROC : 0x%08X\n",hwnd,lParam,pProc); if(IsWindowUnicode(hwnd)) { pProc = (WNDPROC)GetWindowLongW(hwnd,GWL_WNDPROC); } else { pProc = (WNDPROC)GetWindowLongA(hwnd,GWL_WNDPROC); } if(pProc != 0) { DbgPrintEx("\t\t_PROC : %d\n",pProc); } return TRUE; } BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { WNDPROC pProc = 0; if(IsWindowUnicode(hwnd)) { pProc = (WNDPROC)GetWindowLongW(hwnd,GWL_WNDPROC); <----------- ERROR ACCESS DENIED ! } else { pProc = (WNDPROC)GetWindowLongA(hwnd,GWL_WNDPROC); } DbgPrintEx("HANDLE : 0x%08X, PARAM : 0x%08X, WNDPROC : 0x%08X\n",hwnd,lParam,pProc); EnumChildWindows(hwnd,&EnumChildProc,lParam); return TRUE; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { EnableDebugPrivilege(); EnumWindows(EnumWindowsProc,0); return 0; } Может быть, кто-нибудь уже делал такое? Буду благодарен.
WIN32 Не...я не твой проверял )) Я проверил лишь то,что если изменять значение виртуального кода нажатой клавиши в хуке на WH_GETMESSAGE, то мы увидим то, что ожидаем. В хуке WH_KEYBOARD_LL - это работать не будет.
Код (Text): GetMsgProc proc nCode:DWORD, wParam:DWORD, lParam:DWORD cmp nCode,0 jnz @ret mov edi, lParam mov eax, dword ptr [edi+4] .if eax == WM_CHAR add edi, 8 mov al, 'a' ;тут вводишь тот символ, который тебе нужен stosb .endif @ret: invoke CallNextHookEx,hHook,nCode,wParam,lParam ret GetMsgProc endp