Desenvolvimento - C/C++
C++ - RusKey: mapeando o layout do teclado russo com o alfabeto latino
Com o uso de um hook muito simples, pode-se alterar o significado do que se digita no teclado por qualquer outra coisa...
por Wanderley Caloni JrIntrodução
Com o uso de um hook muito simples, pode-se alterar o significado do que se digita no teclado por qualquer outra coisa. O processo é mais fácil ainda quando o que se quer é uma correspondência numérica exata entre quantas letras foram digitadas e quantos caracteres aparecerão para o usuário.
Este é um programa muito simples que se utiliza dessa técnica para facilitar o aprendizado do layout de um teclado russo. Fiz para uso próprio, mas quem sabe não pode ser útil para mais alguém? Pelo menos a técnica de hook, se usada com criatividade, já é uma coisa que vale a pena aprender.
Por que mapear caracteres
Um alfabeto é uma das muitas maneiras de representar as palavras de uma língua por escrito. Uma palavra escrita é um conjunto de letras que representa os sons que usamos para falar essa palavra. Cada som usado é chamado de fonema.
Assim sendo, embora o alfabeto russo seja diferente do alfabeto latino muitos fonemas são compartilhados. Isso quer dizer que podemos pegar algumas letras do cirílico e traduzir diretamente para algumas letras do nosso alfabeto, e outras letras não. Porém, após a tradução de uma letra no teclado, a posição dela geralmente não é a mesma posição do nosso teclado. Daí temos uma letra de nosso alfabeto em outro lugar. Se for feita uma tradução aproximada entre os dois alfabetos, nossas letras em um teclado russo ficariam dispostas assim:
Um pouco diferente do qwert asdfg ao qual estamos acostumados, né?
Ao digitar usando esse pseudo-layout o treino do layout do teclado russo estaria sendo feito mesmo escrevendo com o alfabeto latino. Legal, não? Poderia programar com as letras todas trocadas, porque a saída final é a mesma. Basta treinar os dedos para acertarem as mesmas letras nos novos lugares. Assim, quando precisasse escrever no alfabeto cirílico saberia melhor onde cada letra fica.
Obs: Embora a maioria das letras consiga ser representada por uma "equivalente" latina com outrasisso não ocorre. Daí optei por ignorar a tradução e colocar uma outra letra que não necessariamente é uma boa tradução do fonema(masnecessária para que se consiga digitar um texto em alfabeto latino).
Conhecimento Prévio
Seria interessante já ter ouvido falar da função SetWindowsHookEx() da API do Windows e seu uso para hook de mensagens.
Usando o código
O código já é um programa por si só. Pode ser utilizado para treinamentosde digitação em outros sistemas de layout de teclado. A única coisa a ser trocada é a correspondência entre as letras, contidas nos dois arrays abaixo:
const TCHAR g_tzRussAlphabet[] = _T("F<RLTAU{B:RKVYJGSHCNED}IOPf,rltau[b;rkvyjgshcned]iop"); const TCHAR g_tzPortAlphabet[] = _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");O código de substituição de caracteres é extremamente simples. Se trata de uma busca no array de caracteres originais e posterior substituição do caractere pelo seu equivalente (mesmo índice) no array de caracteres de substituição:
switch( pMsg->message ) { case WM_CHAR: { LPTSTR ptzChar = _tcschr(g_tzRussAlphabet, (TCHAR) pMsg->wParam); if( ptzChar ) { size_t offset = ptzChar - g_tzRussAlphabet; pMsg->wParam = (WPARAM) g_tzPortAlphabet[offset]; } } }Pontos de Interesse
Durantea depuração de um projeto que faz hook de mensagens global, a atenção merece sertriplicada. Qualquer besteira feita na função de tratamento podecolocar o sistema abaixo (como um MessageBox() chamadopara qualquer mensagem, por exemplo). No entanto, uma vez que você está depurando uma interceptação de mensagem em um processo distinto,geralmente a única coisa que irá travar será esse processo e os que dele dependerem diretamente.