Source code of Windows XP (NT5)
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.

750 lines
17 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* cmd.c -- key handling for WRITE */
  5. #define NOCTLMGR
  6. #define NOWINSTYLES
  7. #define NOSYSMETRICS
  8. #define NOICON
  9. #define NOSYSCOMMANDS
  10. #define NORASTEROPS
  11. #define NOSHOWWINDOW
  12. //#define NOATOM
  13. #define NOCREATESTRUCT
  14. #define NODRAWTEXT
  15. #define NOCLIPBOARD
  16. #define NOGDICAPMASKS
  17. #define NOHDC
  18. #define NOBRUSH
  19. #define NOPEN
  20. #define NOFONT
  21. #define NOWNDCLASS
  22. #define NOCOMM
  23. #define NOSOUND
  24. #define NORESOURCE
  25. #define NOOPENFILE
  26. #define NOWH
  27. #define NOCOLOR
  28. #include <windows.h>
  29. #include "mw.h"
  30. #include "cmddefs.h"
  31. #include "dispdefs.h"
  32. #include "code.h"
  33. #include "ch.h"
  34. #include "docdefs.h"
  35. #include "editdefs.h"
  36. #include "debug.h"
  37. #include "fmtdefs.h"
  38. #include "winddefs.h"
  39. #include "propdefs.h"
  40. #include "wwdefs.h"
  41. #include "menudefs.h"
  42. #if defined(OLE)
  43. #include "obj.h"
  44. #endif
  45. #ifdef KOREA
  46. #include <ime.h>
  47. extern BOOL fInterim; // MSCH bklee 12/22/94
  48. #endif
  49. int vfAltKey;
  50. extern int vfPictSel;
  51. extern int vfCommandKey;
  52. extern int vfShiftKey;
  53. extern int vfGotoKeyMode;
  54. extern int vfInsertOn;
  55. extern struct WWD rgwwd[];
  56. extern struct SEL selCur; /* Current selection (i.e., sel in current ww) */
  57. extern int vkMinus;
  58. #ifdef JAPAN //T-HIROYN Win3.1
  59. int KeyAltNum = FALSE;
  60. #endif
  61. int fnCutEdit();
  62. int fnCopyEdit();
  63. int fnPasteEdit();
  64. int fnUndoEdit();
  65. FCheckToggleKeyMessage( pmsg )
  66. register MSG *pmsg;
  67. { /* If the passed message is an up- or down- transition of a
  68. keyboard toggle key (e.g. shift), update our global flags & return
  69. TRUE; if not, return FALSE */
  70. switch ( pmsg->message ) {
  71. case WM_KEYDOWN:
  72. case WM_KEYUP:
  73. case WM_SYSKEYDOWN:
  74. case WM_SYSKEYUP:
  75. switch( pmsg->wParam ) {
  76. case VK_SHIFT:
  77. case VK_CONTROL:
  78. case VK_MENU:
  79. SetShiftFlags();
  80. return TRUE;
  81. #if 0
  82. #ifdef DEBUG
  83. default:
  84. {
  85. char msg[100];
  86. wsprintf(msg,"%s\t0x%x\n\r",(LPSTR)((pmsg->message == WM_KEYDOWN) ?
  87. "keydown" : "keyup"), pmsg->wParam);
  88. OutputDebugString(msg);
  89. }
  90. #endif
  91. #endif
  92. }
  93. #ifdef JAPAN //T-HIROYN
  94. if(vfAltKey){
  95. if(pmsg->wParam >= VK_NUMPAD0 && pmsg->wParam <= VK_NUMPAD9 ) {
  96. KeyAltNum = TRUE;
  97. }
  98. } else {
  99. KeyAltNum = FALSE;
  100. }
  101. #endif
  102. }
  103. return FALSE;
  104. }
  105. SetShiftFlags()
  106. {
  107. extern int vfShiftKey; /* Whether shift is down */
  108. extern int vfCommandKey; /* Whether ctrl key is down */
  109. MSG msg;
  110. PeekMessage(&msg, (HWND)NULL, NULL, NULL, PM_NOREMOVE);
  111. vfShiftKey = GetKeyState( VK_SHIFT ) < 0;
  112. vfCommandKey = GetKeyState( VK_CONTROL ) < 0;
  113. vfAltKey = GetKeyState( VK_MENU ) < 0;
  114. #if 0
  115. #ifdef DEBUG
  116. {
  117. char msg[100];
  118. wsprintf(msg,"%s\t%s\t%s\n\r",
  119. (LPSTR)(vfShiftKey ? "Shift":"OFF"),
  120. (LPSTR)(vfCommandKey ? "Control":"OFF"),
  121. (LPSTR)(vfAltKey ? "Alt":"OFF"));
  122. OutputDebugString(msg);
  123. }
  124. #endif
  125. #endif
  126. }
  127. KcAlphaKeyMessage( pmsg )
  128. register MSG *pmsg;
  129. { /* If the passed message is a key-down transition for a key
  130. that is processed by the Alpha Mode loop, return a kc
  131. code for it. If not, return kcNil.
  132. If the key is a virtual key that must be translated,
  133. return kcAlphaVirtual */
  134. int kc;
  135. if (pmsg->hwnd != wwdCurrentDoc.wwptr)
  136. return kcNil;
  137. kc = pmsg->wParam;
  138. switch (pmsg->message) {
  139. default:
  140. break;
  141. case WM_KEYDOWN:
  142. #ifdef DINPUT
  143. { char rgch[100];
  144. wsprintf(rgch," KcAlphaKeyMessage(WM_KEYDOWN) kc=pmsg->wParam==%X\n\r",kc);
  145. CommSz(rgch);
  146. }
  147. #endif
  148. if (vfAltKey)
  149. return kcAlphaVirtual;
  150. if (vfCommandKey)
  151. { /* Alpha mode control keys */
  152. if (vfShiftKey && kc == (kkNonReqHyphen & ~wKcCommandMask))
  153. return kcNonReqHyphen;
  154. else if (kc == (kksPageBreak & ~wKcCommandMask))
  155. return KcFromKks( kksPageBreak );
  156. }
  157. else
  158. { /* There are two classes of Alpha Mode virtual keys:
  159. (1) Keys that can successfully be filtered out
  160. and processed at the virtual key level
  161. (2) Keys that must be translated first
  162. We assume here that there is NOT a third class of key
  163. that will cause synchronous messages to be sent to our
  164. window proc when TranslateMessage is called. */
  165. switch (kc) {
  166. default:
  167. return kcAlphaVirtual;
  168. case VK_F1: /* THIS IS A COPY OF THE ACCELERATOR TABLE, */
  169. /* AND MUST BE UPDATED IN SYNC WITH THE TABLE */
  170. case VK_F2:
  171. case VK_F3:
  172. case VK_F4:
  173. case VK_F5:
  174. case VK_F6:
  175. case VK_F7:
  176. case VK_F8:
  177. return kcNil;
  178. case kcDelNext & ~wKcCommandMask:
  179. /* If selection, return kcNil, else return kcDelNext */
  180. return (selCur.cpFirst < selCur.cpLim) ? kcNil : kcDelNext;
  181. case kcDelPrev & ~wKcCommandMask:
  182. /* New standard for Win 3.0... Backspace key deletes
  183. the selection if there is one (implemented by faking
  184. a Delete keypress) ..pault 6/20/89 */
  185. if (selCur.cpFirst < selCur.cpLim)
  186. {
  187. pmsg->wParam = (kcDelNext & ~wKcCommandMask);
  188. return(kcNil);
  189. }
  190. /* else process as before... */
  191. case kcTab & ~wKcCommandMask:
  192. case kcReturn & ~wKcCommandMask:
  193. return kc | wKcCommandMask;
  194. }
  195. }
  196. break;
  197. #ifdef KOREA /* interim support by sangl 90.12.23 */
  198. case WM_INTERIM:
  199. #endif
  200. case WM_CHAR:
  201. #ifdef KOREA
  202. if(pmsg->message == WM_INTERIM) // MSCH bklee 12/22/94
  203. fInterim = TRUE;
  204. else fInterim = FALSE;
  205. #endif
  206. #ifdef DINPUT
  207. { char rgch[100];
  208. wsprintf(rgch," KcAlphaKeyMessage(WM_CHAR) returning kc==%X\n\r",kc);
  209. CommSz(rgch);
  210. }
  211. #endif
  212. #ifdef PRINTMERGE
  213. if (kc < ' ')
  214. /* CTRL-key. The print merge brackets are treated as commands,
  215. since they require special handling in AlphaMode().
  216. All others are directly inserted. */
  217. switch ( kc ) {
  218. case kcLFld & ~wKcCommandMask:
  219. case kcRFld & ~wKcCommandMask:
  220. kc |= wKcCommandMask;
  221. break;
  222. }
  223. #endif
  224. #ifdef JAPAN
  225. // inhibit form inputing Alt + Numkey T-HIROYN WIN3.1
  226. if(KeyAltNum) {
  227. _beep();
  228. KeyAltNum = FALSE;
  229. return kcNil;
  230. }
  231. #endif
  232. return kc;
  233. } /* end switch (msg.message) */
  234. #ifdef DINPUT
  235. CommSz(" KcAlphaKeyMessage(not WM_CHAR or WM_KEYDOWN) returning kc==kcNil");
  236. #endif
  237. return kcNil;
  238. }
  239. #ifdef KOREA
  240. CHAR chDelete;
  241. typeCP cpConversion;
  242. extern int docCur;
  243. extern CHAR *vpchFetch;
  244. extern int IsInterim;
  245. extern typeCP cpMacCur;
  246. #endif
  247. FNonAlphaKeyMessage( pmsg, fAct )
  248. register MSG *pmsg;
  249. int fAct; /* Whether to act on the passed key */
  250. {
  251. extern HMENU vhMenu;
  252. extern HWND hParentWw;
  253. int kc;
  254. int message;
  255. if (pmsg->hwnd != wwdCurrentDoc.wwptr)
  256. return FALSE;
  257. message = pmsg->message;
  258. kc = pmsg->wParam | wKcCommandMask;
  259. /* Check for Alt-Bksp */
  260. if ((message == WM_SYSKEYDOWN) && (kc == (VK_BACK | wKcCommandMask)))
  261. /* Alt-Backspace = UNDO */
  262. {
  263. if (fAct)
  264. PhonyMenuAccelerator( EDIT, imiUndo, fnUndoEdit );
  265. return TRUE;
  266. }
  267. /* Only look at key down messages */
  268. if (message != WM_KEYDOWN)
  269. return FALSE;
  270. #ifdef DINPUT
  271. { char rgch[100];
  272. wsprintf(rgch," FNonAlphaKeyMessage(keydown) kc==%X\n\r",kc);
  273. CommSz(rgch);
  274. }
  275. #endif
  276. /* Translate CTRL keys by mapping valid kk & kks codes to valid kc codes */
  277. if ( vfCommandKey )
  278. {
  279. if (vfShiftKey)
  280. switch ( kc ) { /* Handle CTRL-SHIFT keys */
  281. default:
  282. goto CtrlKey;
  283. #if 0
  284. #ifdef DEBUG
  285. case kksTest:
  286. case kksEatWinMemory:
  287. case kksFreeWinMemory:
  288. case kksEatMemory:
  289. case kksFreeMemory:
  290. kc = KcFromKks( kc );
  291. break;
  292. #endif
  293. #endif
  294. }
  295. else /* Handle CTRL keys */
  296. {
  297. CtrlKey:
  298. switch ( kc ) {
  299. case kkUpScrollLock:
  300. case kkDownScrollLock:
  301. case kkTopDoc:
  302. case kkEndDoc:
  303. case kkTopScreen:
  304. case kkEndScreen:
  305. case kkCopy:
  306. #ifdef CASHMERE /* These keys not supported by MEMO */
  307. case kkNonReqHyphen:
  308. case kkNonBrkSpace:
  309. case kkNLEnter:
  310. #endif
  311. case kkWordLeft:
  312. case kkWordRight:
  313. kc = KcFromKk( kc ); /* Translate control code */
  314. #ifdef DINPUT
  315. { char rgch[100];
  316. wsprintf(rgch," FNonAlphaKeyMessage, translated kc %X\n\r",kc);
  317. CommSz(rgch);
  318. }
  319. #endif
  320. break;
  321. default:
  322. #ifdef DINPUT
  323. CommSz(" FNonAlphaKeyMessage returning false, nonsupported kc\n\r");
  324. #endif
  325. return FALSE;
  326. }
  327. }
  328. } /* end of if (vfCommandKey) */
  329. /* Act on valid kc codes */
  330. #ifdef DINPUT
  331. CommSz(" FNonAlphaKeyMessage processing valid kc codes\n\r");
  332. #endif
  333. switch ( kc ) {
  334. /* ---- CURSOR KEYS ---- */
  335. case kcEndLine:
  336. case kcBeginLine:
  337. case kcLeft:
  338. case kcRight:
  339. case kcWordRight:
  340. case kcWordLeft:
  341. if (fAct)
  342. {
  343. ClearInsertLine();
  344. MoveLeftRight( kc );
  345. }
  346. break;
  347. case kcUp:
  348. case kcDown:
  349. case kcUpScrollLock:
  350. case kcDownScrollLock:
  351. case kcPageUp:
  352. case kcPageDown:
  353. case kcTopDoc:
  354. case kcEndDoc:
  355. case kcEndScreen:
  356. case kcTopScreen:
  357. if (fAct)
  358. {
  359. ClearInsertLine();
  360. MoveUpDown( kc );
  361. }
  362. break;
  363. case kcGoto: /* Modifies next cursor key */
  364. if (!fAct)
  365. break;
  366. vfGotoKeyMode = true;
  367. goto NoClearGoto;
  368. /* Phony Menu Accelerator Keys */
  369. case kcNewUndo:
  370. {
  371. if (fAct)
  372. PhonyMenuAccelerator( EDIT, imiUndo, fnUndoEdit );
  373. return TRUE;
  374. }
  375. case kcCopy:
  376. case kcNewCopy:
  377. if (fAct)
  378. PhonyMenuAccelerator( EDIT, imiCopy, fnCopyEdit );
  379. break;
  380. case kcNewPaste:
  381. case VK_INSERT | wKcCommandMask:
  382. if (fAct && (vfShiftKey || (kc == kcNewPaste)))
  383. {
  384. #if defined(OLE)
  385. vbObjLinkOnly = FALSE;
  386. #endif
  387. PhonyMenuAccelerator( EDIT, imiPaste, fnPasteEdit );
  388. }
  389. break;
  390. case kcNewCut:
  391. case VK_DELETE | wKcCommandMask:
  392. if (vfShiftKey || (kc == kcNewCut))
  393. { /* SHIFT-DELETE = Cut */
  394. if (fAct)
  395. PhonyMenuAccelerator( EDIT, imiCut, fnCutEdit );
  396. }
  397. else
  398. { /* DELETE = Clear */
  399. if (fAct)
  400. fnClearEdit(FALSE);
  401. }
  402. break;
  403. case VK_ESCAPE | wKcCommandMask:
  404. /* The ESC key does: if editing a running head or foot, return to doc
  405. else beep */
  406. if (!fAct)
  407. break;
  408. if (wwdCurrentDoc.fEditHeader || wwdCurrentDoc.fEditFooter)
  409. { /* Return to document from editing header/footer */
  410. extern HWND vhDlgRunning;
  411. SendMessage( vhDlgRunning, WM_CLOSE, 0, (LONG) 0 );
  412. return TRUE;
  413. }
  414. else
  415. _beep();
  416. break;
  417. #ifdef KOREA
  418. case VK_HANJA | wKcCommandMask:
  419. if(IsInterim) break;
  420. if (selCur.cpFirst == cpMacCur) {
  421. _beep();
  422. break;
  423. }
  424. cpConversion = selCur.cpFirst;
  425. Select( cpConversion, cpConversion+1 ); // 2/9/93
  426. FetchCp( docCur, cpConversion, 0, fcmChars );
  427. chDelete = *vpchFetch;
  428. { HANDLE hKs;
  429. LPIMESTRUCT lpKs;
  430. LPSTR lp;
  431. hKs = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE,(LONG)sizeof(IMESTRUCT));
  432. lpKs = (LPIMESTRUCT)GlobalLock(hKs);
  433. lpKs->fnc = IME_HANJAMODE;
  434. lpKs->wParam = IME_REQUEST_CONVERT;
  435. lpKs->dchSource = (WORD)( &(lpKs->lParam1) );
  436. lp = lpSource( lpKs );
  437. *lp++ = *vpchFetch++;
  438. *lp++ = *vpchFetch;
  439. *lp++ = '\0';
  440. GlobalUnlock(hKs);
  441. if(SendIMEMessage (hParentWw, MAKELONG(hKs,0)))
  442. selCur.cpLim = selCur.cpFirst + 2;
  443. else
  444. Select( cpConversion, cpConversion ); // 2/9/93
  445. GlobalFree(hKs);
  446. }
  447. break;
  448. #endif /* KOREA */
  449. #if 0
  450. #ifdef DEBUG
  451. case kcEatWinMemory:
  452. if (!fAct)
  453. break;
  454. CmdEatWinMemory();
  455. break;
  456. case kcFreeWinMemory:
  457. if (!fAct)
  458. break;
  459. CmdFreeWinMemory();
  460. break;
  461. case kcEatMemory:
  462. {
  463. if (!fAct)
  464. break;
  465. CmdEatMemory();
  466. break;
  467. }
  468. case kcFreeMemory:
  469. if (!fAct)
  470. break;
  471. CmdFreeMemory();
  472. break;
  473. case kcTest:
  474. if (!fAct)
  475. break;
  476. fnTest();
  477. break;
  478. #endif
  479. #endif
  480. default:
  481. return FALSE;
  482. } /* end of switch (kc) */
  483. vfGotoKeyMode = false;
  484. NoClearGoto:
  485. return TRUE;
  486. }
  487. #ifdef DEBUG
  488. ScribbleHex( dch, wHex, cDigits )
  489. int dch; /* Screen position at which to show Last digit (see fnScribble) */
  490. unsigned wHex; /* hex # to show*/
  491. int cDigits; /* # of digits to show */
  492. {
  493. extern fnScribble( int dchPos, CHAR ch );
  494. for ( ; cDigits--; wHex >>= 4 )
  495. {
  496. int i=wHex & 0x0F;
  497. fnScribble( dch++, (i >= 0x0A) ? i + ('A' - 0x0A) : i + '0' );
  498. }
  499. }
  500. #endif /* DEBUG */
  501. #ifdef DEBUG
  502. #ifdef OURHEAP
  503. CHAR (**vhrgbDebug)[] = 0;
  504. int vrgbSize = 0;
  505. #else
  506. #define iHandleMax 100
  507. HANDLE rgHandle[ iHandleMax ];
  508. int iHandleMac;
  509. unsigned cwEaten = 0;
  510. #endif
  511. CmdEatMemory()
  512. { /* For debugging purposes, eat up memory */
  513. #ifdef OURHEAP /* Restore this with a LocalCompact when are
  514. operational under the Windows heap */
  515. int **HAllocate();
  516. int cwEat = cwHeapFree > 208 ? cwHeapFree - 208 : 20;
  517. if (vrgbSize == 0)
  518. vhrgbDebug = (CHAR (**)[])HAllocate(cwEat);
  519. else
  520. FChngSizeH(vhrgbDebug, cwEat + vrgbSize, true);
  521. vrgbSize += cwEat;
  522. CmdShowMemory();
  523. #endif /* OURHEAP */
  524. }
  525. CmdFreeMemory()
  526. { /* Free up the memory we stole */
  527. #ifdef OURHEAP
  528. if (vhrgbDebug != 0)
  529. FreeH(vhrgbDebug);
  530. vhrgbDebug = (CHAR (**)[]) 0;
  531. vrgbSize = 0;
  532. CmdShowMemory();
  533. #endif
  534. }
  535. extern CHAR szMode[];
  536. extern int docMode;
  537. extern int vfSizeMode;
  538. #ifdef OURHEAP
  539. CmdShowMemory()
  540. #else
  541. CmdShowMemory(cw)
  542. int cw;
  543. #endif
  544. {
  545. extern CHAR szFree[];
  546. CHAR *pch = szMode;
  547. #ifdef OURHEAP
  548. /* cch = */ ncvtu( cwHeapFree, &pch );
  549. #else
  550. ncvtu(cw, &pch);
  551. #endif
  552. blt( szFree, pch, CchSz( szFree ));
  553. vfSizeMode = true;
  554. /* docMode = -1; */
  555. DrawMode();
  556. }
  557. CmdEatWinMemory()
  558. {
  559. #ifndef OURHEAP
  560. unsigned cwEat;
  561. int cPage;
  562. int fThrowPage = TRUE;
  563. extern int cPageMinReq;
  564. extern int ibpMax;
  565. while (true)
  566. {
  567. while ((cwEat = ((unsigned)LocalCompact((WORD)0) / sizeof(int))) > 0 &&
  568. iHandleMac < iHandleMax)
  569. {
  570. if ((rgHandle [iHandleMac] = (HANDLE)HAllocate(cwEat)) == hOverflow)
  571. goto AllocFail;
  572. else
  573. {
  574. ++iHandleMac;
  575. cwEaten += cwEat;
  576. CmdShowMemory(cwEaten);
  577. }
  578. if (iHandleMac >= iHandleMax)
  579. goto AllocFail;
  580. if ((rgHandle [iHandleMac] = (HANDLE)HAllocate(10)) == hOverflow)
  581. goto AllocFail;
  582. else
  583. {
  584. ++iHandleMac;
  585. cwEaten += 10;
  586. CmdShowMemory(cwEaten);
  587. }
  588. }
  589. if (iHandleMac >= iHandleMax)
  590. goto AllocFail;
  591. cPage = cPageUnused();
  592. Assert(cPage + 2 < ibpMax);
  593. if (fThrowPage)
  594. {
  595. /* figure out how many bytes we need to invoke the situation
  596. where we need to throw some pages out to get the space */
  597. cwEat = ((cPage+2) * 128) / sizeof(int);
  598. cPageMinReq = ibpMax - cPage - 2;
  599. }
  600. else
  601. {
  602. cwEat = ((cPage-2) * 128) / sizeof(int);
  603. cPageMinReq = ibpMax - cPage;
  604. }
  605. if ((rgHandle[ iHandleMac++ ] = (HANDLE)HAllocate(cwEat)) == hOverflow)
  606. {
  607. iHandleMac--;
  608. break;
  609. }
  610. cwEaten += cwEat;
  611. CmdShowMemory(cwEaten);
  612. }
  613. AllocFail: /* Allocation failed, or we ran out of slots */
  614. CmdShowMemory( cwEaten );
  615. #endif
  616. }
  617. CmdFreeWinMemory()
  618. {
  619. #ifndef OURHEAP
  620. unsigned cwFree = 0;
  621. Assert(iHandleMac <= iHandleMax);
  622. while (iHandleMac > 0)
  623. {
  624. HANDLE h = rgHandle[ iHandleMac - 1];
  625. if ( (h != NULL) && (h != hOverflow))
  626. {
  627. cwFree += (unsigned)LocalSize(h) / sizeof(int);
  628. FreeH( h );
  629. }
  630. iHandleMac--;
  631. }
  632. cwEaten = 0;
  633. CmdShowMemory(cwFree);
  634. #endif
  635. }
  636. #endif /* DEBUG */