scan.c
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 35k
Category:

Windows Develop

Development Platform:

Visual C++

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. // Updated :1999 Anil Kumar and Maria Jose
  3. // 
  4. #include <windows.h>
  5. #include <mmsystem.h>
  6. #include "kbmain.h"
  7. #include "kbus.h"
  8. #include "resource.h"
  9. #define SCANTIMER 123    //timer identifier
  10. #define NUMOFTIME   2      //after scan this many time of each key, 
  11.                            //back to scan row : a-anilk
  12. #define ROW1 1
  13. #define ROW2 12
  14. #define ROW3 21
  15. #define ROW4 30
  16. #define ROW5 39
  17. #define ROW6 48
  18. #define COL1   1
  19. #define COL2   52
  20. #define COL3   103
  21. #define COL4   153
  22. #define COL4_END  202
  23. #define COL4S     103   //Small KB
  24. #define COL4S_END 143   //Small KB
  25. int count=0;
  26. UINT_PTR TimerS1;       //Timer for scanning
  27. int CurRow;         //current row which is scanning
  28. int CurKey=0;       //current key which is scanning
  29. int LastKey=0;      //Last scanned key in Small keyboard
  30. int ScanState=0;    //State : Row scan / Key scan
  31. int CurCol= COL1;
  32. extern BOOL g_fRealChar; //v-mjgran: The scan key is a real character, writte it
  33. extern BOOL IsDeadKeyPressed(HWND hScannedKey);
  34. extern HWND g_hBitmapLockHwnd;
  35. //
  36. // Make scanning use WINDOWTEXT color : a-anilk
  37. //
  38. /***********************************************/
  39. // Functions in this file
  40. /***********************************************/
  41. #include "scan.h"
  42. void ScanningSound(int what);
  43. /***********************************************/
  44. // Functions in other file
  45. /***********************************************/
  46. #include "ms32dll.h"
  47. /***************************************************************/
  48. void Scanning(int from)
  49. {
  50. count = 0;   //reset this counter of key scan
  51. //Play some sound
  52. ScanningSound(3);
  53. if(kbPref->Actual)
  54. Scanning_Actual(from);
  55. else
  56. Scanning_Block(from);
  57. }
  58. /***************************************************************/
  59. // Actual layout
  60. /***************************************************************/
  61. void Scanning_Actual(int from)
  62. {
  63. ScanState = ScanState + from;
  64. count = 0;   //reset this counter of key scan
  65. switch (ScanState)
  66. {
  67.     case 0:
  68. KillScanTimer(TRUE);
  69. break;
  70. case 1:   //Row scanning
  71. KillScanTimer(FALSE);
  72.         CurKey = 0;  //reset to 0 anyway
  73. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)LineScanProc);
  74. break;
  75. case 2:    //key scanning
  76. KillScanTimer(FALSE);
  77. //101 KB
  78. if(kbPref->KBLayout == 101)
  79. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)KeyScanProc_Actual_101);
  80. //106 KB
  81. else if(kbPref->KBLayout == 106)
  82. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)KeyScanProc_Actual_106);
  83. //102 KB
  84. else
  85. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)KeyScanProc_Actual_102);
  86. break;
  87. default:     //stop scanning and send char
  88. KillScanTimer(FALSE);
  89.         if (smallKb && (LastKey != 0))
  90.     SendChar(lpkeyhwnd[LastKey]);
  91.         else
  92.     SendChar(lpkeyhwnd[CurKey-1]);
  93. g_fRealChar = TRUE; //Sent character
  94. //re-set some vars
  95. ScanState = 0;
  96. CurKey = 0;
  97. //Post a message to call Scanning again to avoid recursive call
  98. PostMessage(kbmainhwnd, WM_USER + 1, 0L, 0L);
  99. break;
  100. }
  101. }
  102. /****************************************************************/
  103. // Scan each row. Both Actual and Block
  104. /****************************************************************/
  105. void CALLBACK LineScanProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  106. { static int row=1;
  107. register int i;
  108. if (count == NUMOFTIME)
  109. { Scanning(-1);
  110. return;
  111. }
  112. switch(row)
  113. {
  114. case 1:
  115. //Reset previous row color
  116. RestoreRowColor(ROW6);
  117. CurRow = ROW1;    //save the current row
  118. for(i=1; i <= lenKBkey; i++)
  119. { if(KBkey[i].posY == ROW1)
  120. { SetWindowLong(lpkeyhwnd[i], 0, 4);
  121. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  122. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  123. }
  124. }
  125. break;
  126. case 2:
  127. //Reset previous row color
  128. RestoreRowColor(ROW1);
  129. CurRow = ROW2;    //save the current row
  130. for(i=1; i <= lenKBkey; i++)
  131. { if(KBkey[i].posY == ROW2)
  132. { SetWindowLong(lpkeyhwnd[i], 0, 4);
  133. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  134. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  135. }
  136. }
  137. break;
  138. case 3:
  139. //Reset previous row color
  140. RestoreRowColor(ROW2);
  141. CurRow = ROW3;    //save the current row
  142. for(i=1; i <= lenKBkey; i++)
  143. { if(KBkey[i].posY == ROW3)
  144. { SetWindowLong(lpkeyhwnd[i], 0, 4);
  145. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  146. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  147. }
  148. }
  149. break;
  150. case 4:
  151. //Reset previous row color
  152. RestoreRowColor(ROW3);
  153. CurRow = ROW4;    //save the current row
  154. for(i=1; i <= lenKBkey; i++)
  155. { if(KBkey[i].posY == ROW4)
  156. { SetWindowLong(lpkeyhwnd[i], 0, 4);
  157. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  158. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  159. }
  160. }
  161. break;
  162. case 5:
  163. //Reset previous row color
  164. RestoreRowColor(ROW4);
  165. CurRow = ROW5;    //save the current row
  166. for(i=1; i <= lenKBkey; i++)
  167. { if(KBkey[i].posY == ROW5)
  168. { SetWindowLong(lpkeyhwnd[i], 0, 4);
  169. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  170. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  171. }
  172. }
  173. break;
  174. case 6:
  175. //Reset previous row color
  176. RestoreRowColor(ROW5);
  177. CurRow = ROW6;    //save the current row
  178. for(i=1; i <= lenKBkey; i++)
  179. { if(KBkey[i].posY == ROW6)
  180. { SetWindowLong(lpkeyhwnd[i], 0, 4);
  181. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  182. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  183. }
  184. }
  185. break;
  186. }
  187. //Play some sound
  188. ScanningSound(1);
  189. row++;
  190. if(row==7)   //last row, reset to 1st row 
  191. { row = 1;
  192. count++;
  193. }
  194. }
  195. /******************************************************************************/
  196. // Scan each key in Actual 101 kb
  197. /******************************************************************************/
  198. void CALLBACK KeyScanProc_Actual_101(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  199. {
  200.     register int j=0;
  201. if(CurKey == 0)
  202. { //move to the correct row
  203. while ((KBkey[j].posY != CurRow) && (j <= lenKBkey))
  204. j++;
  205. CurKey = j;
  206. }
  207. //Skip all the dummy key
  208. for(CurKey;KBkey[CurKey].smallKb == NOTSHOW;CurKey++);
  209. //Scan each key
  210. if (KBkey[CurKey].posY == CurRow)
  211. {
  212. //Just reach the end last time (For Small KB only)
  213. if(LastKey != 0)
  214. { RestoreKeyColor(LastKey);
  215.     //
  216.             //if 97 (LALT) just pass the space in SMALL KB, so don't increment the counter
  217.             //
  218. if(LastKey != 97)  
  219.             {
  220. count++;   //else increment the counter
  221.             }
  222. LastKey = 0;
  223. if (count == NUMOFTIME)
  224. { count = 0;
  225. Scanning_Actual(-1);
  226. return;
  227. }
  228. }
  229. else
  230. RestoreKeyColor(CurKey - 1);
  231.         //Change the key color to black
  232. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  233. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  234. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  235. CurKey++;   //jump to next key
  236. //Reach at the VERY END in Large KB
  237. //Note: It should be 111, but I let it to scan one more so I don't need to write extra code to redraw the last key 
  238. if(!smallKb && CurKey == 112)  
  239. {
  240. count++;   //increment the counter
  241. CurKey = 95;  //set it back to first key (LCTRL) in last row of the kb
  242. }
  243. //reach at the VERY END in Small KB (KB has 117 keys)
  244. else if(smallKb && CurKey == 118)
  245. {
  246. CurKey = 95;  // first key (LCTRL) in last row
  247. LastKey = 117;
  248. }
  249. //After left Alt, jump to 111 (Space) for Small KB
  250. else if(smallKb && CurKey == 98)
  251. {
  252.             CurKey = 111;   //Space in small KB
  253. LastKey = 97;   //LALT
  254. }
  255. //reach at the end of each row
  256. else if(smallKb) 
  257. {
  258.    // the number is one advance than the actual key 
  259. // because it increment one after it scan the key
  260. switch(CurKey)
  261. {
  262. case 14:  //f12
  263. CurKey = 1;
  264. LastKey = 13;
  265. break;
  266. case 32:   //BS
  267. CurKey = 17;  // ~
  268. LastKey = 31;  //BS
  269. break;
  270. case 53:    // |
  271. CurKey = 39;  //TAB
  272. LastKey = 52;  // |
  273. break;
  274. case 74:   //enter
  275. CurKey = 60;    // Cap
  276. LastKey = 73;   //ENTER
  277. break;
  278. case 90:   //right shift
  279. CurKey = 77;   //LSHIFT
  280. LastKey = 89;  //RSHIFT
  281. break;
  282. }
  283. }
  284. }
  285. //End of the row (Large KB).  Reset to beginning of the row
  286. else if (KBkey[CurKey].posY > CurRow && !smallKb)
  287. {
  288. RestoreKeyColor(CurKey - 1);
  289. count++;   //increment the counter
  290. switch (CurRow)
  291. {
  292. case ROW1:
  293. CurKey = 1;  //esc
  294. break;
  295. case ROW2:
  296. CurKey = 17;  // ~
  297. break;
  298. case ROW3:
  299. CurKey = 39;  //TAB
  300. break;
  301. case ROW4:
  302. CurKey = 60;  // CAP
  303. break;
  304. case ROW5:
  305. CurKey = 77;  // LSHIFT
  306. break;
  307. case ROW6:
  308. CurKey = 95;  //LCRL
  309. break;
  310. }
  311. }
  312. //Play some sound
  313. ScanningSound(1);
  314. //We have scan NUMOFTIME for each key in this row, and the user hasn't make 
  315. //any choice. Now go back to scan ROW
  316. if (count == NUMOFTIME)
  317. { count = 0;
  318. Scanning_Actual(-1);
  319. }
  320. }
  321. /******************************************************************************/
  322. // Scan each key in Actual 102 kb
  323. /******************************************************************************/
  324. void CALLBACK KeyScanProc_Actual_102(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  325. {
  326.     register int j=0;
  327. if(CurKey == 0)
  328. { //move to the correct row
  329. while ((KBkey[j].posY != CurRow) && (j <= lenKBkey))
  330. j++;
  331. CurKey = j;
  332. }
  333. //Skip all the dummy key
  334. for(CurKey;KBkey[CurKey].smallKb == NOTSHOW;CurKey++);
  335. //Scan each key
  336. if (KBkey[CurKey].posY == CurRow)
  337. {
  338. //Just reach the end last time (For Small KB only)
  339. if(LastKey != 0)
  340. { RestoreKeyColor(LastKey);
  341.     //
  342.             //if 97 (LALT) just pass the space in SMALL KB, so don't increment the counter
  343.             //
  344. if(LastKey != 97)  
  345.             {
  346. count++;   //else increment the counter
  347.             }
  348. LastKey = 0;
  349. if (count == NUMOFTIME)
  350. { count = 0;
  351. Scanning_Actual(-1);
  352. return;
  353. }
  354. }
  355. else
  356. RestoreKeyColor(CurKey - 1);
  357.         //Change the key color to black
  358. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  359. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  360. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  361. CurKey++;   //jump to next key
  362. //Reach at the VERY END in Large KB
  363. //Note: It should be 111, but I let it to scan one more so I don't need to write extra code to redraw the last key 
  364. if(!smallKb && CurKey == 112)  
  365. {
  366. count++;   //increment the counter
  367. CurKey = 95;  //set it back to first key (LCTRL) in last row of the kb
  368. }
  369. //reach at the VERY END in Small KB (KB has 117 keys)
  370. else if(smallKb && CurKey == 118)
  371. {
  372. CurKey = 95;  // first key (LCTRL) in last row
  373. LastKey = 117;
  374. }
  375. //After left Alt, jump to 111 (Space) for Small KB
  376. else if(smallKb && CurKey == 98)
  377. {
  378.             CurKey = 111;   //Space in small KB
  379. LastKey = 97;   //LALT
  380. }
  381. //reach at the end of each row
  382. else if(smallKb) 
  383. {
  384.    // the number is one advance than the actual key 
  385. // because it increment one after it scan the key
  386. switch(CurKey)
  387. {
  388. case 14:  //f12
  389. CurKey = 1;
  390. LastKey = 13;
  391. break;
  392. case 32:   //BS
  393. CurKey = 17;  // ~
  394. LastKey = 31;  //BS
  395. break;
  396. case 53:    // |
  397. CurKey = 39;  //TAB
  398. LastKey = 52;  // |
  399. break;
  400. case 74:   //enter
  401. CurKey = 60;    // Cap
  402. LastKey = 73;   //ENTER
  403. break;
  404. case 90:   //right shift
  405. CurKey = 77;   //LSHIFT
  406. LastKey = 89;  //RSHIFT
  407. break;
  408. }
  409. }
  410. }
  411. //End of the row (Large KB).  Reset to beginning of the row
  412. else if (KBkey[CurKey].posY > CurRow && !smallKb)
  413. {
  414. RestoreKeyColor(CurKey - 1);
  415. count++;   //increment the counter
  416. switch (CurRow)
  417. {
  418. case ROW1:
  419. CurKey = 1;  //esc
  420. break;
  421. case ROW2:
  422. CurKey = 17;  // ~
  423. break;
  424. case ROW3:
  425. CurKey = 39;  //TAB
  426. break;
  427. case ROW4:
  428. CurKey = 60;  // CAP
  429. break;
  430. case ROW5:
  431. CurKey = 77;  // LSHIFT
  432. break;
  433. case ROW6:
  434. CurKey = 95;  //LCRL
  435. break;
  436. }
  437. }
  438. //Play some sound
  439. ScanningSound(1);
  440. //We have scan NUMOFTIME for each key in this row, and the user hasn't make 
  441. //any choice. Now go back to scan ROW
  442. if (count == NUMOFTIME)
  443. { count = 0;
  444. Scanning_Actual(-1);
  445. }
  446. }
  447. /******************************************************************************/
  448. // Scan each key in Actual 106 kb
  449. /******************************************************************************/
  450. void CALLBACK KeyScanProc_Actual_106(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  451. {
  452.     register int j=0;
  453. if(CurKey == 0)
  454. { //move to the correct row
  455. while ((KBkey[j].posY != CurRow) && (j <= lenKBkey))
  456. j++;
  457. CurKey = j;
  458. }
  459. //Skip all the dummy key
  460. for(CurKey;KBkey[CurKey].smallKb == NOTSHOW;CurKey++);
  461. //Scan each key 
  462. if(KBkey[CurKey].posY == CurRow)
  463. {
  464. //Just reach the end last time (For Small KB only)
  465. if(LastKey != 0)
  466. { RestoreKeyColor(LastKey);
  467.     //
  468.             //These are the keys as exception in SMALL KB.
  469. //They are not reach the end of the road, 
  470.     //so don't increment the counter
  471.             //
  472. if(LastKey != 98 && LastKey != 101 && LastKey != 111)  
  473.             {
  474. count++;   //else increment the counter
  475.             }
  476. LastKey = 0;
  477. if (count == NUMOFTIME)
  478. { count = 0;
  479. Scanning_Actual(-1);
  480. return;
  481. }
  482. }
  483. else
  484. RestoreKeyColor(CurKey - 1);
  485.         //Change the key color to black
  486. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  487. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  488. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  489. CurKey++;   //jump to next key
  490. //Reach at the VERY END in Large KB
  491. //Note: It should be 111, but I let it to scan one more so I don't need to write extra code to redraw the last key 
  492. if(!smallKb && CurKey == 112)  
  493. {
  494. count++;   //increment the counter
  495. CurKey = 95;  //set it back to first key (LCTRL) in last row of the kb
  496. }
  497. //reach at the VERY END in Small KB (KB has 117 keys)
  498. else if(smallKb && CurKey == 118)
  499. {
  500. CurKey = 95;  // first key (LCTRL) in last row
  501. LastKey = 117;
  502. }
  503. //After the NO CONVERT Key, skip the Space in Large KB
  504. else if(smallKb && CurKey == 99)
  505. {
  506.             CurKey = 111;   //CONVERT key
  507. LastKey = 98;   //Japanses
  508. }
  509. //After Space jump back to CONVERT key
  510. else if(smallKb && CurKey == 112)
  511. {
  512.             CurKey = 100;   //CONVERT
  513. LastKey = 111;   // SPACE
  514. }
  515. //After THE Japanese key, jump to 102 (RALT) for Small KB
  516. else if(smallKb && CurKey == 102)
  517. {
  518.             CurKey = 112;   //RALT in small KB
  519. LastKey = 101;   //Japanese Key
  520. }
  521. //reach at the end of each row
  522. else if(smallKb) 
  523. {
  524.    // the number is one advance than the actual key 
  525. // because it increment one after it scan the key
  526. switch(CurKey)
  527. {
  528. case 14:  //f12
  529. CurKey = 1;
  530. LastKey = 13;
  531. break;
  532. case 32:   //BS
  533. CurKey = 17;  // ~
  534. LastKey = 31;  //BS
  535. break;
  536. case 54:    // Enter
  537. CurKey = 39;  //TAB
  538. LastKey = 53;  // |
  539. break;
  540. case 74:   // ''
  541. CurKey = 61;    // Cap
  542. LastKey = 73;   //ENTER
  543. break;
  544. case 90:   //right shift
  545. CurKey = 77;   //LSHIFT
  546. LastKey = 89;  //RSHIFT
  547. break;
  548. }
  549. }
  550. }
  551. //End of the row (Large KB).  Reset to beginning of the row
  552. else if (KBkey[CurKey].posY > CurRow && !smallKb)
  553. {
  554. RestoreKeyColor(CurKey - 1);
  555. count++;   //increment the counter
  556. switch (CurRow)
  557. {
  558. case ROW1:
  559. CurKey = 1;  //esc
  560. break;
  561. case ROW2:
  562. CurKey = 17;  // ~
  563. break;
  564. case ROW3:
  565. CurKey = 39;  //TAB
  566. break;
  567. case ROW4:
  568. CurKey = 61;  // CAP
  569. break;
  570. case ROW5:
  571. CurKey = 77;  // LSHIFT
  572. break;
  573. case ROW6:
  574. CurKey = 95;  //LCRL
  575. break;
  576. }
  577. }
  578. //Play some sound
  579. ScanningSound(1);
  580. //We have scan NUMOFTIME for each key in this row, and the user hasn't make 
  581. //any choice. Now go back to scan ROW
  582. if (count == NUMOFTIME)
  583. { count = 0;
  584. Scanning_Actual(-1);
  585. }
  586. }
  587. /******************************************************************************/
  588. // Restore the whole row's color
  589. /******************************************************************************/
  590. void RestoreRowColor(int Row)
  591. { register int i;
  592. //Reset previous row color
  593. for(i=1; i <= lenKBkey; i++)
  594. {
  595.       if(KBkey[i].posY == Row)
  596. {
  597. if (lpkeyhwnd[i] != g_hBitmapLockHwnd)
  598. {
  599. // v_mjgran: Do no change the color key if Caplock bitmap
  600. SetWindowLong(lpkeyhwnd[i], 0, 0);
  601. }
  602. switch (KBkey[i].ktype)
  603. {
  604. case KNORMAL_TYPE:
  605. case NUMLOCK_TYPE:
  606. case SCROLLOCK_TYPE:
  607. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_WINDOW);
  608. break;
  609. case KMODIFIER_TYPE:
  610. case KDEAD_TYPE:
  611. if (IsDeadKeyPressed(lpkeyhwnd[i]))
  612. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_MENUTEXT);
  613. else
  614. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_MENU);
  615. break;
  616. case LED_NUMLOCK_TYPE:
  617. case LED_SCROLLLOCK_TYPE:
  618. case LED_CAPSLOCK_TYPE:
  619. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_GRAYTEXT);
  620. break;
  621. }
  622. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  623. }
  624. }
  625. }
  626. /****************************************************************************/
  627. // Restore one key color
  628. /****************************************************************************/
  629. void RestoreKeyColor(int i)
  630. {
  631. // index > 0
  632. if(i<=0)
  633. return;
  634. //Skip all the dummy key
  635. for(i; KBkey[i].smallKb == NOTSHOW; i--);
  636. if (lpkeyhwnd[i] != g_hBitmapLockHwnd)
  637. {
  638. // // v_mjgran: Do no change the color key if Caplock bitmap
  639. SetWindowLong(lpkeyhwnd[i], 0, 0);
  640. }
  641. switch (KBkey[i].ktype)
  642. {
  643. case KNORMAL_TYPE:
  644. case NUMLOCK_TYPE:
  645. case SCROLLOCK_TYPE:
  646. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_WINDOW);
  647. break;
  648. case KMODIFIER_TYPE:
  649. case KDEAD_TYPE:
  650. if (IsDeadKeyPressed(lpkeyhwnd[i]))
  651. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_MENUTEXT);
  652. else
  653. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_MENU);
  654. break;
  655. case LED_NUMLOCK_TYPE:
  656. case LED_SCROLLLOCK_TYPE:
  657. case LED_CAPSLOCK_TYPE:
  658. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_GRAYTEXT);
  659. break;
  660. }
  661. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  662. }
  663. /****************************************************************/
  664. // Pass FALSE - Pause
  665. // Pass TRUE  - Reset (start scanning from row 1) 
  666. /****************************************************************/
  667. void KillScanTimer(BOOL reset)
  668. {
  669. KillTimer(kbmainhwnd, SCANTIMER);
  670. RestoreRowColor(CurRow);
  671. //if calling from dialog init, reset these vars to start at the beginning 
  672. if (reset)
  673. { ScanState = 0;
  674. CurKey = 0;
  675. CurRow = ROW1;
  676. }
  677. }
  678. /**********************************************************************/
  679. // Scan in block kb
  680. /**********************************************************************/
  681. void Scanning_Block(int from)
  682. {
  683. ScanState = ScanState + from;
  684. count = 0;   //reset this counter of key scan
  685. switch (ScanState)
  686. {
  687.     case 0:
  688. KillScanTimer(TRUE);
  689. break;
  690. case 1:   //Row scanning
  691. KillScanTimer(FALSE);
  692. CurCol = COL1;    //reset Col to COL1 for next round
  693. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)LineScanProc);
  694. break;
  695. case 2:
  696. KillScanTimer(FALSE);
  697. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)BlockScanProc);
  698. break;
  699. case 3:    //key scanning
  700. KillScanTimer(FALSE);
  701. //Set the coloum back 1 because in Block scan I set it 1 advance
  702. switch(CurCol)
  703. {
  704. case COL1:
  705. CurCol = COL4;
  706. break;
  707. case COL2:
  708. CurCol = COL1;
  709. break;
  710. case COL3:
  711. CurCol = COL2;
  712. break;
  713. case COL4:
  714. CurCol = COL3;
  715. break;
  716. }
  717. //Small KB doesn't has Col4, Set to Col3
  718. if(smallKb && (CurCol == COL4))
  719. CurCol = COL3;
  720. TimerS1 = SetTimer(kbmainhwnd, SCANTIMER, PrefScanTime, (TIMERPROC)KeyScanProc_Block);
  721. break;
  722. default:     //stop scanning and send char
  723. KillScanTimer(FALSE);
  724. //a special for SPACE in Large KB and Block layout
  725. if((!kbPref->Actual) && (!smallKb) && (CurKey == 99))
  726. CurKey++;
  727. SendChar(lpkeyhwnd[CurKey-1]);
  728. g_fRealChar = TRUE; //v-mjgran: Sent character
  729. //re-set some vars
  730. ScanState = 0;
  731. CurKey = 0;
  732. //Post a message to call Scanning again to avoid recursive call
  733. PostMessage(kbmainhwnd, WM_USER + 1, 0L, 0L);
  734. break;
  735. }
  736. }
  737. /*********************************************************************/
  738. // Restore the whole block color in block kb
  739. /*********************************************************************/
  740. void RestoreBlockColor(int ColStart, int ColEnd)
  741. { register int i;
  742. //Find the first key in current row and current col
  743. for(i=1; i <= lenKBkey; i++)
  744. if((KBkey[i].posY == CurRow) && (KBkey[i].posX == ColStart))
  745. break;
  746. while(((KBkey[i].posX < ColEnd) && (KBkey[i].posY == CurRow)) || (KBkey[i].smallKb == NOTSHOW))
  747. {
  748. if(KBkey[i].smallKb == NOTSHOW)
  749. { i++;
  750. continue;
  751. }
  752. if (lpkeyhwnd[i] != g_hBitmapLockHwnd)
  753. {
  754. // // v_mjgran: Do no change the color key if Caplock bitmap
  755. SetWindowLong(lpkeyhwnd[i], 0, 0);
  756. }
  757. switch (KBkey[i].ktype)
  758. {
  759. case KNORMAL_TYPE:
  760. case NUMLOCK_TYPE:
  761. case SCROLLOCK_TYPE:
  762. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_WINDOW);
  763. break;
  764. case KMODIFIER_TYPE:
  765. case KDEAD_TYPE:
  766. if (IsDeadKeyPressed(lpkeyhwnd[i]))
  767. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_MENUTEXT);
  768. else
  769. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_MENU);
  770. break;
  771. case LED_NUMLOCK_TYPE:
  772. case LED_CAPSLOCK_TYPE:
  773. case LED_SCROLLLOCK_TYPE:
  774. SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, COLOR_GRAYTEXT);
  775. break;
  776. }
  777. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  778. i++;
  779. }
  780. }
  781. /*********************************************************************/
  782. // Scan each block in block kb
  783. /*********************************************************************/
  784. void CALLBACK BlockScanProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  785. { register int i;
  786. //We have scan NUMOFTIME for each block in this row, and the user hasn't make 
  787. //any choice. Now go back to scan ROW
  788. if (count == NUMOFTIME)
  789. { count = 0;    //reset the counter
  790. Scanning_Block(-1);
  791. return;
  792. }
  793. //Find the first key in current row and current col
  794. for(i=1; i <= lenKBkey; i++)
  795. if((KBkey[i].posY == CurRow) && (KBkey[i].posX == CurCol))
  796. break;
  797.         switch (CurCol)
  798. {
  799. case COL1:
  800. CurKey = i;    //set the CurKey to the beginning of this block 
  801. //Small KB
  802.             if (smallKb)
  803.             {
  804.                 int j;
  805.         
  806.                 RestoreBlockColor(COL3,COL4);
  807.             
  808.                 for(j=113; j <= 117; j++)  //Hardcoded it!
  809.                     RestoreKeyColor(j); 
  810.             }
  811.            
  812.             else   // Large KB
  813.     RestoreBlockColor(COL4, COL4_END);
  814. //Paint all keys within the Block
  815. while(((KBkey[i].posX < COL2) && (KBkey[i].posY == CurRow)) || (KBkey[i].smallKb == NOTSHOW))
  816. {
  817. if(KBkey[i].smallKb == NOTSHOW)
  818. { i++;
  819. continue;
  820. }
  821. SetWindowLong(lpkeyhwnd[i], 0, 4);
  822. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  823. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  824. i++;
  825. }
  826. CurCol = COL2;  //Jump to next col
  827. break;
  828. case COL2:
  829. CurKey = i;    //set the CurKey to the beginning of this block
  830. RestoreBlockColor(COL1, COL2);
  831.             //In Small KB, skip all the large kb keys
  832.             if (smallKb)
  833.             {
  834.                 while((KBkey[i].smallKb == LARGE) || (KBkey[i].smallKb == NOTSHOW))
  835.                     i++;
  836.             }
  837. //Paint all keys within the Block
  838. while(((KBkey[i].posX < COL3) && (KBkey[i].posY == CurRow)) || (KBkey[i].smallKb == NOTSHOW))
  839. {
  840. if(KBkey[i].smallKb == NOTSHOW)
  841. { i++;
  842. continue;
  843. }
  844. SetWindowLong(lpkeyhwnd[i], 0, 4);
  845. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  846. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  847. i++;
  848. }
  849. CurCol = COL3;   //Jump to next col
  850. break;
  851. case COL3:
  852. //For small KB, skip all the keys only for LARGE kb
  853. if(smallKb)
  854.             {
  855. while(KBkey[i].smallKb == LARGE || KBkey[i].smallKb == NOTSHOW)
  856. i++;
  857.             }
  858. CurKey = i;    //set the CurKey to the beginning of this block
  859.             //Small kb
  860.             if (smallKb && CurKey == 111)   // CurKey == SPACE
  861.             {
  862.                 RestoreKeyColor(111);   // SPACE
  863.                 RestoreKeyColor(112);   // RALT
  864.                 CurKey = i = 113;   //APP KEY
  865.             }
  866.             //Large KB
  867.             else
  868.                 RestoreBlockColor(COL2, COL3);
  869. //Paint all keys within the Block
  870. while(((KBkey[i].posX < COL4) && (KBkey[i].posY == CurRow)) || (KBkey[i].smallKb == NOTSHOW))
  871. {
  872. if(KBkey[i].smallKb == NOTSHOW)
  873. { i++;
  874. continue;
  875. }
  876. SetWindowLong(lpkeyhwnd[i], 0, 4);
  877. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  878. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  879. i++;
  880. }
  881.             if (smallKb)   //Small KB only has 3 columns
  882.             {
  883.                 CurCol = COL1;
  884.                 count++;        // increment the counter
  885.             }
  886.             else    //Large KB
  887.     CurCol = COL4;  //Jump to next col
  888. break;
  889. case COL4:
  890. CurKey = i;    //set the CurKey to the beginning of this block
  891. RestoreBlockColor(COL3, COL4);
  892. //Paint all keys within the Block
  893. while(((KBkey[i].posX < COL4_END) && (KBkey[i].posY == CurRow)) || (KBkey[i].smallKb == NOTSHOW))
  894. {
  895. if(KBkey[i].smallKb == NOTSHOW)
  896. { i++;
  897. continue;
  898. }
  899. SetWindowLong(lpkeyhwnd[i], 0, 4);
  900. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[i], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  901. InvalidateRect(lpkeyhwnd[i], NULL, TRUE);
  902. i++;
  903. }
  904. CurCol = COL1;   //Jump to next col
  905. count++;   //increment the counter
  906. break;
  907. }
  908. //Play some sound
  909. ScanningSound(1);
  910. }
  911. /*********************************************************************/
  912. // Scan each key in a block in block kb
  913. /*********************************************************************/
  914. void CALLBACK KeyScanProc_Block(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  915. { static int last=0;
  916. register int i;
  917. switch (CurCol)
  918. {
  919. case COL1:   //This is actually COL1
  920. //Scanning each key in the Block
  921. if((KBkey[CurKey].posY == CurRow) && (KBkey[CurKey].posX < COL2))
  922. {
  923. if(last != 0)
  924. { RestoreKeyColor(last);
  925. last = 0;
  926. }
  927. else if(CurKey > 1)
  928. RestoreKeyColor(CurKey - 1);
  929. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  930. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  931. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  932. CurKey++;   //jump to next key
  933. }
  934. //Reach last key, reset to first key in the col
  935. else if(KBkey[CurKey].posX >= COL2)
  936. { for(i=1; i <= lenKBkey; i++)
  937. if((KBkey[i].posY == CurRow) && (KBkey[i].posX == COL1))
  938. { last = CurKey -1;   //save the last key for next restore color
  939. CurKey = i;
  940. break;
  941. }
  942. count++;
  943. }
  944. break;
  945. case COL2:   //Actually COL2
  946.         //In small KB, skip all the Large KB keys
  947.         if (smallKb)
  948.         {
  949.             while(KBkey[CurKey].smallKb == LARGE || KBkey[CurKey].smallKb == NOTSHOW)
  950.                 CurKey++;
  951.         }
  952.         //Only for the last row (both Small and Large KB)
  953. if(KBkey[CurKey].name == KB_SPACE)
  954. {
  955.             if (smallKb)    //Small KB
  956.                 RestoreKeyColor(112);   //106
  957. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  958. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  959. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  960. CurKey++;
  961.             if (!smallKb)   //Large KB
  962.             {
  963. count++;
  964. if(count < NUMOFTIME)
  965. CurKey--;
  966.             }
  967.             else    //Small Kb
  968.                 last = 111;      //SPACE (small)
  969. break;
  970. }
  971. //Scanning each key in the Column
  972. if((KBkey[CurKey].posY == CurRow) && (KBkey[CurKey].posX < COL3))
  973. {
  974. if(last != 0)
  975. { RestoreKeyColor(last);
  976. last = 0;
  977. }
  978. else
  979. RestoreKeyColor(CurKey - 1);
  980. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  981. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  982. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  983. CurKey++;   //jump to next key
  984. }
  985. //Reach last key, reset to first key in the col
  986. else if(KBkey[CurKey].posX >= COL3)
  987. {
  988.             if (smallKb && CurKey == 113)    //App Key (small)
  989.             {
  990.                 CurKey = 111;       //SPACE (small)
  991.                 last = 112;         //RALT (small)
  992.             }
  993.             else
  994.             {
  995.                 for(i=1; i <= lenKBkey; i++)
  996.                 {
  997.     if((KBkey[i].posY == CurRow) && (KBkey[i].posX == COL2))
  998.     {
  999.                         //save the last key for next restore color
  1000.                         last = CurKey - 1;
  1001.     CurKey = i;
  1002.     break;
  1003.     }
  1004.                 }
  1005.             }
  1006. count++;
  1007. }
  1008. break;
  1009. case COL3:  //Actually COL3
  1010. //Last Col for SMALL KB
  1011.         //Special case!!  Last scan reach the very end in Samll KB (118)
  1012.         if (CurKey == 118)  
  1013.         {   CurKey = 113;   //Reset to the first one in this col
  1014. count++;
  1015. }
  1016. //Skip all Dummy key
  1017. while(KBkey[CurKey].smallKb == NOTSHOW)
  1018. CurKey++;
  1019. //Scanning each key in the Block
  1020. if((KBkey[CurKey].posY == CurRow) && (KBkey[CurKey].posX < COL4) && 
  1021.            (CurKey <= 117))
  1022. {
  1023. //In small KB, skip all the Large KB keys
  1024. if(smallKb)
  1025.             {
  1026. while(KBkey[CurKey].smallKb == LARGE || KBkey[CurKey].smallKb == NOTSHOW)
  1027. CurKey++;
  1028.             }
  1029. if(last != 0)
  1030. {
  1031.                 RestoreKeyColor(last);
  1032.                 //Special case, reach the end of the small KB
  1033.                 if (last == 118)    //The end in Small KB
  1034.                     CurKey = 113;   //reset to first one in this col
  1035. last = 0;
  1036. }
  1037. else
  1038. RestoreKeyColor(CurKey - 1);
  1039.             //Set the key to black
  1040. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  1041. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  1042. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  1043. CurKey++;   //jump to next key
  1044. }
  1045. //Reach last key, reset to first key in the col
  1046. else if( (KBkey[CurKey].posX >= COL4 || CurKey > 109)  && (CurKey <= 117) )  
  1047. {
  1048.             //reach the very end
  1049.             for(i=1; i <= lenKBkey; i++)
  1050.             {
  1051. if((KBkey[i].posY == CurRow) && (KBkey[i].posX == COL3))
  1052. { last = CurKey - 1;   //save the last key for next restore color
  1053. CurKey = i;
  1054. break;
  1055. }
  1056.             }
  1057. count++;
  1058. }
  1059.         //Small KB reach the last key (117)
  1060.         if (smallKb && (CurKey == 118))
  1061.             last = CurKey -1;
  1062. break;
  1063. case COL4:   //Actual COL4
  1064. //Only LARGE KB has COL4
  1065. //Scanning each key in the Block
  1066.    //large KB and not reach the end
  1067. if((KBkey[CurKey].posY == CurRow) && (KBkey[CurKey].posX < COL4_END) && !smallKb && (CurKey <= 110))
  1068. {
  1069. if(last != 0)
  1070. { RestoreKeyColor(last);
  1071. last = 0;
  1072. }
  1073. else
  1074. RestoreKeyColor(CurKey - 1);
  1075. SetWindowLong(lpkeyhwnd[CurKey], 0, 4);
  1076. DeleteObject((HGDIOBJ)SetClassLongPtr(lpkeyhwnd[CurKey], GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT))));
  1077. InvalidateRect(lpkeyhwnd[CurKey], NULL, TRUE);
  1078. CurKey++;   //jump to next key
  1079. }
  1080. //Reach last key, reset to first key in the col
  1081. else // if(KBkey[CurKey - 1].posX >= COL4_END)
  1082. { for(i=1; i <= lenKBkey; i++)
  1083. if((KBkey[i].posY == CurRow) && (KBkey[i].posX == COL4))
  1084. { last = CurKey - 1;   //save the last key for next restore color
  1085. CurKey = i;
  1086. break;
  1087. }
  1088. count++;
  1089. }
  1090. break;
  1091. }
  1092. //Play some sound
  1093. ScanningSound(1);
  1094. //We have scan NUMOFTIME for each key in this Block, and the user hasn't make 
  1095. //any choice. Now go back to scan BLOCK
  1096. if (count == NUMOFTIME)
  1097. { count = 0;    //reset the counter
  1098. Scanning_Block(-1);
  1099. }
  1100. }
  1101. /*****************************************************************************/
  1102. void ScanningSound(int what)
  1103. {
  1104. //not want sound, then exit
  1105. if(!Prefusesound)
  1106. return;
  1107. switch(what)
  1108. {
  1109. case 2:     // scanning
  1110. PlaySound(MAKEINTRESOURCE(WAV_CLICKDN), hInst, SND_ASYNC|SND_RESOURCE);
  1111. break;
  1112. case 1:      //one level up
  1113. PlaySound(MAKEINTRESOURCE(WAV_CLICKUP), hInst, SND_ASYNC|SND_RESOURCE);
  1114. break;
  1115. case 3:      //switch click
  1116. PlaySound(MAKEINTRESOURCE(WAV_SWITCH_CLICK), hInst, SND_ASYNC|SND_RESOURCE);
  1117. break;
  1118. }
  1119. }