Code:
#include <windows.h>
#include <stdio.h>
const CHAR RussianAlphabet[] =
"zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";
const CHAR EnglishAlphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam,
LPARAM lParam);
HINSTANCE hInst;
HHOOK hHook;
HWND hwndglobal;
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
char szWindowName[] = "MyWindow";
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,
LPSTR lpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hInstance = hThisInst;
wcl.lpszClassName = szWindowName;
wcl.lpfnWndProc = WindowFunc;
wcl.style = 0;
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcl.hIconSm = NULL;
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.lpszMenuName = "KeyboardProc";
if(!RegisterClassEx(&wcl)) return 0;
hwnd = CreateWindow(szWindowName,
"Demo a keyboard hook, translate from English to Russian",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hThisInst, NULL);
hInst = hThisInst;
hwndglobal = hwnd;
ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
char str[255];
TEXTMETRIC tm;
SIZE size;
static int X=0, Y=0;
static int maxX, maxY;
static HDC memdc;
static HBITMAP hbit;
HBRUSH hbrush;
switch(message) {
case WM_CREATE:
hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) KeyboardProc,
NULL, GetCurrentThreadId());
maxX = GetSystemMetrics(SM_CXSCREEN);
maxY = GetSystemMetrics(SM_CYSCREEN);
hdc = GetDC(hwnd);
memdc = CreateCompatibleDC(hdc);
hbit = CreateCompatibleBitmap(hdc, maxX, maxY);
SelectObject(memdc, hbit);
hbrush = (HBRUSH) GetStockObject(WHITE_BRUSH);
SelectObject(memdc, hbrush);
PatBlt(memdc, 0, 0, maxX, maxY, PATCOPY);
ReleaseDC(hwnd, hdc);
break;
case WM_CHAR:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
sprintf(str, "%c", (char) wParam);
if((char)wParam == '\r') {
Y = Y + tm.tmHeight + tm.tmExternalLeading;
X = 0;
}
else {
TextOut(memdc, X, Y, str, 1);
TextOut(hdc, X, Y, str, 1);
GetTextExtentPoint32(memdc, str, strlen(str), &size);
X += size.cx;
}
ReleaseDC(hwnd, hdc);
break;
case WM_DESTROY:
UnhookWindowsHookEx(hHook);
DeleteDC(memdc);
DeleteObject(hbit);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
MSG *msg;
msg = (MSG *) lParam;
if(code >= 0)
switch(msg->message) {
case WM_CHAR:
LPTSTR lptstrChar = strchr(RussianAlphabet, msg->wParam);
if( lptstrChar )
{
size_t offset = lptstrChar - RussianAlphabet;
msg->wParam = (WPARAM) EnglishAlphabet[offset];
}
}
return CallNextHookEx(hHook, code, wParam, lParam);
}