Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

548 lines
15 KiB

  1. //******************************************************************************
  2. // File: \wacker\tdll\keyedit.c Created: 6/5/98 By: Dwayne M. Newsome
  3. //
  4. // Copyright 1998 by Hilgraeve Inc. --- Monroe, MI
  5. // All rights reserved
  6. //
  7. // Description:
  8. // This file represents a window procedure for a key edit control. This
  9. // catches key strokes and displays them as appropiate for defining key macros
  10. // This is used by the key dialog for the keyname and key macro edit boxes.
  11. //
  12. // $Revision: 4 $
  13. // $Date: 8/15/01 4:56p $
  14. // $Id: keyedit.c 1.2 1998/06/12 07:20:41 dmn Exp $
  15. //
  16. //******************************************************************************
  17. #include <windows.h>
  18. #pragma hdrstop
  19. #include "stdtyp.h"
  20. #include "mc.h"
  21. #ifdef INCL_KEY_MACROS
  22. #include <term\res.h>
  23. #include <tdll\assert.h>
  24. #include "globals.h"
  25. #include "keyutil.h"
  26. #include "chars.h"
  27. #include "htchar.h"
  28. static void insertKeyAndDisplay( KEYDEF aKey, keyMacro * aKeyMacro, HWND aEditCtrl );
  29. static int processKeyMsg( UINT aMsg, UINT aVirtKey, UINT aKeyData, HWND aEditCtrl );
  30. static void removeKeyAndDisplay( keyMacro * aKeyMacro, HWND aEditCtrl );
  31. //******************************************************************************
  32. // Method:
  33. // keyEditWindowProc
  34. //
  35. // Description:
  36. // This is the window procedure for the key edit control
  37. //
  38. // Arguments:
  39. // hwnd - Handle of window
  40. // uMsg - Message to be processed
  41. // wParam - First message parameter
  42. // lParam - Second window parameter
  43. //
  44. // Returns:
  45. // The return value is the result of the message processing and depends on the
  46. // message sent
  47. //
  48. // Throws:
  49. // None
  50. //
  51. // Author: Dwayne M. Newsome, 6/5/98
  52. //
  53. //
  54. LRESULT CALLBACK keyEditWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  55. {
  56. BOOL lMessageProcessed = FALSE;
  57. BOOL lKeyProcessed = FALSE;
  58. keyMacro * pKeyMacro = NULL;
  59. LRESULT lResult = 0;
  60. KEYDEF lKey;
  61. MSG lMsg;
  62. switch ( uMsg )
  63. {
  64. case WM_KEYDOWN:
  65. case WM_SYSKEYDOWN:
  66. {
  67. if ( processKeyMsg( uMsg, wParam, lParam, hwnd ) )
  68. {
  69. lMessageProcessed = TRUE;
  70. lKeyProcessed = TRUE;
  71. }
  72. break;
  73. }
  74. //
  75. // this command gets sent just after the wm_keydown for the F1 key. I
  76. // could not find a manifest constant for this value anywhere. I believe
  77. // it is sent as a result of CWinApp or CWinThread pre translate message in
  78. // the processing of accelerator keys. Anyway, this fixes the problem of
  79. // help popping up after we do an insert of the F1 key into a key
  80. // definition. DMN - 08/21/96
  81. //
  82. case 0x004d:
  83. {
  84. pKeyMacro = (keyMacro *)GetWindowLongPtr( hwnd, GWLP_USERDATA );
  85. assert( pKeyMacro );
  86. if ( pKeyMacro )
  87. {
  88. if( pKeyMacro->insertMode == TRUE)
  89. {
  90. pKeyMacro->insertMode = FALSE;
  91. lMessageProcessed = TRUE;
  92. }
  93. }
  94. break;
  95. }
  96. //
  97. // handle the case of entering ALT key sequences such as ALT-128. The keys
  98. // pressed while ALT is held down are captured and processed as a whole
  99. // here when the ALT key is released. The keys are captured in such a
  100. // way as to allow up to 4 keys pressed and to not require leading zeros
  101. // for example ALT-27 ALT-0027 are treated the same.
  102. //
  103. case WM_KEYUP:
  104. case WM_SYSKEYUP:
  105. if ( wParam == VK_MENU )
  106. {
  107. pKeyMacro = (keyMacro *)GetWindowLongPtr( hwnd, GWLP_USERDATA );
  108. assert( pKeyMacro );
  109. if ( pKeyMacro )
  110. {
  111. if (( pKeyMacro->altKeyCount > 0 ) &&
  112. ( pKeyMacro->altKeyValue >= 0 &&
  113. pKeyMacro->altKeyValue <= 255 ))
  114. {
  115. KEYDEF lKey = pKeyMacro->altKeyValue;
  116. insertKeyAndDisplay( lKey, pKeyMacro, hwnd );
  117. pKeyMacro->insertMode = FALSE;
  118. }
  119. }
  120. pKeyMacro->altKeyCount = 0;
  121. pKeyMacro->altKeyValue = 0;
  122. lMessageProcessed = TRUE;
  123. lKeyProcessed = TRUE;
  124. }
  125. break;
  126. case WM_CHAR:
  127. case WM_SYSCHAR:
  128. pKeyMacro = (keyMacro *)GetWindowLongPtr( hwnd, GWLP_USERDATA );
  129. assert( pKeyMacro );
  130. if ( pKeyMacro )
  131. {
  132. lMsg.message = uMsg;
  133. lMsg.wParam = wParam;
  134. lMsg.lParam = lParam;
  135. lKey = TranslateToKey( &lMsg );
  136. if ( lKey != 0x000d && (TCHAR)lKey != 0x0009 )
  137. {
  138. insertKeyAndDisplay( lKey, pKeyMacro, hwnd );
  139. pKeyMacro->insertMode = FALSE;
  140. lMessageProcessed = TRUE;
  141. }
  142. return 0;
  143. }
  144. break;
  145. case WM_CONTEXTMENU:
  146. lMessageProcessed = TRUE;
  147. break;
  148. case WM_LBUTTONDOWN:
  149. SetFocus( hwnd );
  150. SendMessage( hwnd, EM_SETSEL, 32767, 32767 );
  151. lMessageProcessed = TRUE;
  152. break;
  153. default:
  154. break;
  155. }
  156. //
  157. // if we did not process the key then let the edit control process it
  158. //
  159. if ( !lMessageProcessed )
  160. {
  161. pKeyMacro = (keyMacro *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  162. if ( pKeyMacro )
  163. {
  164. lResult = CallWindowProc( pKeyMacro->lpWndProc, hwnd, uMsg, wParam, lParam );
  165. }
  166. }
  167. else if( lKeyProcessed )
  168. {
  169. MSG msg;
  170. PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE);
  171. }
  172. return lResult;
  173. }
  174. //******************************************************************************
  175. // Method:
  176. // insertKeyAndDisplay
  177. //
  178. // Description:
  179. // Inserts the specified key into the keyMacro structure provided and displays
  180. // the new key definition(s) in the edit control provided.
  181. //
  182. // Arguments:
  183. // aKey - The key to add
  184. // aKeyMacro - The current macro definition being acted on
  185. // aEditCtrl - The edit control to update
  186. //
  187. // Returns:
  188. // void
  189. //
  190. // Throws:
  191. // None
  192. //
  193. // Author: Dwayne M. Newsome, 06/08/1998
  194. //
  195. //
  196. void insertKeyAndDisplay( KEYDEF aKey, keyMacro * aKeyMacro, HWND aEditCtrl )
  197. {
  198. TCHAR keyString[2048];
  199. int lStrLen;
  200. if ( aKeyMacro->keyCount == 1 )
  201. {
  202. aKeyMacro->keyName = aKey;
  203. keysGetDisplayString( &aKeyMacro->keyName, 1, keyString, sizeof(keyString) );
  204. SetWindowText( aEditCtrl, keyString );
  205. lStrLen = StrCharGetStrLength( keyString );
  206. SendMessage( aEditCtrl, EM_SETSEL, lStrLen, lStrLen );
  207. }
  208. else
  209. {
  210. if ( aKeyMacro->macroLen == aKeyMacro->keyCount )
  211. {
  212. aKeyMacro->keyMacro[aKeyMacro->macroLen - 1] = aKey;
  213. }
  214. else
  215. {
  216. aKeyMacro->keyMacro[aKeyMacro->macroLen] = aKey;
  217. aKeyMacro->macroLen++;
  218. }
  219. keysGetDisplayString( aKeyMacro->keyMacro, aKeyMacro->macroLen,
  220. keyString, sizeof(keyString) );
  221. SetWindowText( aEditCtrl, keyString );
  222. lStrLen = StrCharGetStrLength( keyString );
  223. SendMessage( aEditCtrl, EM_SETSEL, lStrLen, lStrLen );
  224. }
  225. return;
  226. }
  227. //******************************************************************************
  228. // Method:
  229. // processKeyMsg
  230. //
  231. // Description:
  232. //
  233. // Arguments:
  234. // uMsg
  235. //
  236. // Returns:
  237. // int
  238. //
  239. // Throws:
  240. // None
  241. //
  242. // Author: Dwayne M. Newsome, 6/5/98
  243. //
  244. //
  245. int processKeyMsg( UINT aMsg, UINT aVirtKey, UINT aKeyData, HWND aEditCtrl )
  246. {
  247. KEYDEF lKey;
  248. KEYDEF lOrgKey;
  249. int lReturn = FALSE;
  250. keyMacro * pKeyMacro = NULL;
  251. MSG lMsg;
  252. lMsg.message = aMsg;
  253. lMsg.wParam = aVirtKey;
  254. lMsg.lParam = aKeyData;
  255. lKey = TranslateToKey( &lMsg );
  256. if( lKey == 0 )
  257. {
  258. return FALSE;
  259. }
  260. if ( keysIsKeyHVK( lKey ) )
  261. {
  262. pKeyMacro = (keyMacro *)GetWindowLongPtr( aEditCtrl, GWLP_USERDATA );
  263. assert( pKeyMacro );
  264. if ( !pKeyMacro )
  265. {
  266. return FALSE;
  267. }
  268. lOrgKey = lKey;
  269. lKey = (TCHAR)lKey;
  270. switch( lKey )
  271. {
  272. case VK_INSERT:
  273. case VK_INSERT | EXTENDED_KEY:
  274. if( pKeyMacro->insertMode == TRUE)
  275. {
  276. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  277. pKeyMacro->insertMode = FALSE;
  278. lReturn = TRUE;
  279. }
  280. else
  281. {
  282. pKeyMacro->insertMode = TRUE;
  283. lReturn = TRUE;
  284. }
  285. break;
  286. //
  287. // all forms of pressing F1 send a help message after the keydown
  288. // message except for the alt f1 combination. So if we are in
  289. // insert mode we insert the key pressed and leave the insert mode
  290. // on so when we catch the help message we know not to display help
  291. // and turn off insert mode. If the key pressed is alt F1 we turn
  292. // insert mode off here as there is no help message generated.
  293. //
  294. case VK_F1:
  295. if( pKeyMacro->insertMode == TRUE)
  296. {
  297. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  298. lReturn = TRUE;
  299. }
  300. if ( lKey & ALT_KEY )
  301. {
  302. pKeyMacro->insertMode = FALSE;
  303. }
  304. break;
  305. case VK_BACK:
  306. if( pKeyMacro->insertMode == TRUE )
  307. {
  308. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  309. pKeyMacro->insertMode = FALSE;
  310. lReturn = TRUE;
  311. }
  312. else
  313. {
  314. removeKeyAndDisplay( pKeyMacro, aEditCtrl );
  315. lReturn = TRUE;
  316. }
  317. break;
  318. case VK_TAB:
  319. case VK_TAB | SHIFT_KEY | VIRTUAL_KEY:
  320. case VK_CANCEL:
  321. case VK_PAUSE:
  322. case VK_ESCAPE:
  323. case VK_SNAPSHOT:
  324. case VK_NUMLOCK:
  325. case VK_CAPITAL:
  326. case VK_SCROLL:
  327. case VK_RETURN:
  328. case VK_RETURN | EXTENDED_KEY:
  329. if(pKeyMacro->insertMode == TRUE)
  330. {
  331. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  332. pKeyMacro->insertMode = FALSE;
  333. lReturn = TRUE;
  334. }
  335. break;
  336. case VK_SPACE:
  337. lKey = ' ';
  338. insertKeyAndDisplay( lKey, pKeyMacro, aEditCtrl );
  339. pKeyMacro->insertMode = FALSE;
  340. lReturn = TRUE;
  341. break;
  342. case VK_PRIOR:
  343. case VK_NEXT:
  344. case VK_HOME:
  345. case VK_END:
  346. case VK_PRIOR | EXTENDED_KEY:
  347. case VK_NEXT | EXTENDED_KEY:
  348. case VK_HOME | EXTENDED_KEY:
  349. case VK_END | EXTENDED_KEY:
  350. case VK_UP:
  351. case VK_DOWN:
  352. case VK_LEFT:
  353. case VK_RIGHT:
  354. case VK_UP | SHIFT_KEY:
  355. case VK_DOWN | SHIFT_KEY:
  356. case VK_LEFT | SHIFT_KEY:
  357. case VK_RIGHT | SHIFT_KEY:
  358. case VK_UP | EXTENDED_KEY:
  359. case VK_DOWN | EXTENDED_KEY:
  360. case VK_LEFT | EXTENDED_KEY:
  361. case VK_RIGHT | EXTENDED_KEY:
  362. case VK_UP | SHIFT_KEY | EXTENDED_KEY:
  363. case VK_DOWN | SHIFT_KEY | EXTENDED_KEY:
  364. case VK_LEFT | SHIFT_KEY | EXTENDED_KEY:
  365. case VK_RIGHT | SHIFT_KEY | EXTENDED_KEY:
  366. case VK_DELETE:
  367. case VK_DELETE | EXTENDED_KEY:
  368. if(pKeyMacro->insertMode == TRUE)
  369. {
  370. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  371. pKeyMacro->insertMode = FALSE;
  372. }
  373. lReturn = TRUE;
  374. break;
  375. case VK_CLEAR:
  376. case VK_EREOF:
  377. case VK_PA1:
  378. break;
  379. case VK_NUMPAD0:
  380. case VK_NUMPAD1:
  381. case VK_NUMPAD2:
  382. case VK_NUMPAD3:
  383. case VK_NUMPAD4:
  384. case VK_NUMPAD5:
  385. case VK_NUMPAD6:
  386. case VK_NUMPAD7:
  387. case VK_NUMPAD8:
  388. case VK_NUMPAD9:
  389. //
  390. // if the ALT is down capture other key presses for later
  391. // processing on the ALT key up
  392. //
  393. if ( lOrgKey & ALT_KEY )
  394. {
  395. if ( pKeyMacro->altKeyCount <= 3 )
  396. {
  397. if ( pKeyMacro->altKeyCount == 0 )
  398. {
  399. pKeyMacro->altKeyValue = 0;
  400. }
  401. pKeyMacro->altKeyValue *= 10;
  402. pKeyMacro->altKeyValue += aVirtKey - VK_NUMPAD0;
  403. pKeyMacro->altKeyCount++;
  404. }
  405. }
  406. else
  407. {
  408. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  409. pKeyMacro->insertMode = FALSE;
  410. lReturn = TRUE;
  411. }
  412. break;
  413. default:
  414. insertKeyAndDisplay( lOrgKey, pKeyMacro, aEditCtrl );
  415. lReturn = TRUE;
  416. pKeyMacro->insertMode = FALSE;
  417. break;
  418. }
  419. }
  420. return lReturn;
  421. }
  422. //******************************************************************************
  423. // Method:
  424. // removeKeyAndDisplay
  425. //
  426. // Description:
  427. // Removes the specified key into the keyMacro structure provided and displays
  428. // the new key definition(s) in the edit control provided.
  429. //
  430. // Arguments:
  431. // aKeyMacro - The current macro definition being acted on
  432. // aEditCtrl - The edit control to update
  433. //
  434. // Returns:
  435. // void
  436. //
  437. // Throws:
  438. // None
  439. //
  440. // Author: Dwayne M. Newsome, 06/08/1998
  441. //
  442. //
  443. void removeKeyAndDisplay( keyMacro * aKeyMacro, HWND aEditCtrl )
  444. {
  445. TCHAR keyString[2048];
  446. int lStrLen;
  447. if ( aKeyMacro->keyCount == 1 )
  448. {
  449. aKeyMacro->keyName = 0;
  450. TCHAR_Fill(keyString, TEXT('\0'), sizeof(keyString) / sizeof(TCHAR));
  451. SetWindowText( aEditCtrl, keyString );
  452. lStrLen = strlen( keyString );
  453. SendMessage( aEditCtrl, EM_SETSEL, lStrLen, lStrLen );
  454. }
  455. else
  456. {
  457. if ( aKeyMacro->macroLen > 0 )
  458. {
  459. aKeyMacro->macroLen--;
  460. aKeyMacro->keyMacro[aKeyMacro->macroLen] = 0;
  461. keysGetDisplayString( aKeyMacro->keyMacro, aKeyMacro->macroLen,
  462. keyString, sizeof(keyString) );
  463. SetWindowText( aEditCtrl, keyString );
  464. lStrLen = strlen( keyString );
  465. SendMessage( aEditCtrl, EM_SETSEL, lStrLen, lStrLen );
  466. }
  467. }
  468. return;
  469. }
  470. #endif