reactos操作系统实现(173)

IntTranslateKbdMessage函数实现键盘消息转换,实现代码如下:

#001  BOOL FASTCALL

#002  IntTranslateKbdMessage(LPMSG lpMsg,

#003                         HKL dwhkl)

#004  {

#005     PTHREADINFO pti;

#006     static INT dead_char = 0;

#007     LONG UState = 0;

#008     WCHAR wp[2] = { 0 };

#009     MSG NewMsg = { 0 };

#010     PKBDTABLES keyLayout;

#011     BOOL Result = FALSE;

#012     DWORD ScanCode = 0;

#013 

 

获取当前线程的线程信息。

#014     pti = PsGetCurrentThreadWin32Thread();

 

获取键盘布局表。

#015     keyLayout = pti->KeyboardLayout->KBTables;

#016     if( !keyLayout )

#017        return FALSE;

#018 

 

如果消息不是按键按下,就返回,不需要进行转换。

#019     if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)

#020        return FALSE;

#021 

 

从消息里获取键盘的扫描码。

#022     ScanCode = (lpMsg->lParam >> 16) & 0xff;

#023 

 

获取当前光标所在位置。

#024     /* All messages have to contain the cursor point. */

#025     IntGetCursorLocation(pti->Desktop->WindowStation,

#026                          &NewMsg.pt);

#027 

 

把键码值转换为内部的UNICODE表示。

#028     UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,

#029                             gQueueKeyStateTable, wp, 2, 0,

#030                             keyLayout );

#031 

 

转换成功。

#032     if (UState == 1)

#033     {

 

转换为新的消息是用户字符消息,还是系统字符消息。

#034        NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;

 

DEAD按键处理。

#035        if (dead_char)

#036        {

#037           ULONG i;

#038           WCHAR first, second;

#039           DPRINT("PREVIOUS DEAD CHAR: %c/n", dead_char);

#040 

#041           for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )

#042           {

#043              first = keyLayout->pDeadKey[i].dwBoth >> 16;

#044              second = keyLayout->pDeadKey[i].dwBoth;

#045              if (first == dead_char && second == wp[0])

#046              {

#047                 wp[0] = keyLayout->pDeadKey[i].wchComposed;

#048                 dead_char = 0;

#049                 break;

#050              }

#051           }

#052 

#053           DPRINT("FINAL CHAR: %c/n", wp[0]);

#054        }

#055 

#056        if (dead_char)

#057        {

#058           NewMsg.hwnd = lpMsg->hwnd;

#059           NewMsg.wParam = dead_char;

#060           NewMsg.lParam = lpMsg->lParam;

#061           dead_char = 0;

#062           MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);

#063        }

#064 

#065        NewMsg.hwnd = lpMsg->hwnd;

#066        NewMsg.wParam = wp[0];

#067        NewMsg.lParam = lpMsg->lParam;

#068        DPRINT( "CHAR='%c' %04x %08x/n", wp[0], wp[0], lpMsg->lParam );

 

把消息放到队列里。

#069        MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);

#070        Result = TRUE;

#071     }

#072     else if (UState == -1)

#073     {

 

转换不成功时生成的消息。

#074        NewMsg.message =

#075           (lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;

#076        NewMsg.hwnd = lpMsg->hwnd;

#077        NewMsg.wParam = wp[0];

#078        NewMsg.lParam = lpMsg->lParam;

#079        dead_char = wp[0];

#080        MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);

#081        Result = TRUE;

#082     }

#083 

#084     return Result;

#085  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值