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.

709 lines
19 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* insert2.c - MW insertion routines */
  5. #define NOGDICAPMASKS
  6. #define NOCLIPBOARD
  7. #define NOCTLMGR
  8. #define NOWINSTYLES
  9. #ifndef KOREA
  10. #define NOSYSMETRICS
  11. #endif
  12. #define NOMENUS
  13. #define NOICON
  14. #define NOKEYSTATE
  15. #define NOSYSCOMMANDS
  16. #define NOSHOWWINDOW
  17. #define NOATOM
  18. #define NOBRUSH
  19. #define NOCREATESTRUCT
  20. #define NOFONT
  21. #define NOCLIPBOARD
  22. #define NODRAWTEXT
  23. #define NOPEN
  24. #define NOREGION
  25. #define NOSCROLL
  26. #define NOMB
  27. #define NOOPENFILE
  28. #define NOSOUND
  29. #define NOCOMM
  30. #define NOWH
  31. #define NOWINOFFSETS
  32. #define NOWNDCLASS
  33. #include <windows.h>
  34. #include "mw.h"
  35. #include "doslib.h"
  36. #include "propdefs.h"
  37. #include "dispdefs.h"
  38. #include "fmtdefs.h"
  39. #include "cmddefs.h"
  40. #include "wwdefs.h"
  41. #include "docdefs.h"
  42. #define NOKCCODES
  43. #include "ch.h"
  44. #include "winddefs.h"
  45. #include "fontdefs.h"
  46. #include "debug.h"
  47. #ifdef DEBUG
  48. extern int vTune;
  49. #endif
  50. #ifdef KOREA /* Use in KcInputNext..., 90.12.27 sangl */
  51. extern int IsInterim;
  52. #endif
  53. extern int vdlIns;
  54. extern int vxpIns;
  55. extern int vfTextBltValid;
  56. extern int vdypCursLineIns;
  57. extern struct FLI vfli;
  58. extern struct SEL selCur;
  59. extern int vdypBase;
  60. extern int vypBaseIns;
  61. extern int vxpMacIns;
  62. extern int vdypAfter;
  63. extern typeCP cpInsert; /* Beginning cp of insert block */
  64. extern int ichInsert; /* Number of chars used in rgchInsert */
  65. extern typeCP cpMinCur;
  66. extern typeCP cpMacCur;
  67. extern int docCur;
  68. extern struct CHP vchpInsert;
  69. extern struct WWD rgwwd[];
  70. extern struct WWD *pwwdCur;
  71. extern int wwCur;
  72. extern int wwMac;
  73. extern int vfSeeSel;
  74. extern int vfFocus;
  75. #ifdef DBCS
  76. extern int donteat; /* see disp.c */
  77. #endif
  78. unsigned WHsecGetTime()
  79. { /* Get the time (in hundredths of seconds) into a normalized word */
  80. /* Ignore current hour, just minutes/seconds/hundredths */
  81. struct TIM tim;
  82. OsTime( &tim );
  83. return ( (unsigned)tim.minutes * 6000 +
  84. (unsigned)tim.sec * 100 +
  85. (unsigned)tim.hsec );
  86. }
  87. /* V A L I D A T E T E X T B L T */
  88. ValidateTextBlt()
  89. { /* Validate info sufficient for TextOut and ScrollCurWw calls in Insert */
  90. /* In particular: vdlIns, vxpIns, vdypBase, vdypFont */
  91. int NEAR FCpInsertInDl( typeCP, struct EDL * );
  92. extern int vfInsFontTooTall;
  93. extern struct FMI vfmiScreen;
  94. extern int ferror;
  95. extern int vfInsEnd;
  96. int dypFontAscent;
  97. int dypFontDescent;
  98. register struct EDL *pedl;
  99. int yp;
  100. typeCP cpBegin;
  101. /* Routine assumes ww == wwDocument */
  102. Assert( pwwdCur == &wwdCurrentDoc );
  103. { /* Look for a valid dl containing selCur.cpFirst */
  104. /* We should usually be able to find one */
  105. int dlGuess = vdlIns;
  106. struct EDL *dndl=&(**wwdCurrentDoc.hdndl)[0];
  107. if ( (dlGuess < wwdCurrentDoc.dlMac) &&
  108. FCpInsertInDl( selCur.cpFirst, pedl = &dndl[ dlGuess ] ))
  109. { /* vdlIns is already correct */
  110. cpBegin = pedl->cpMin;
  111. }
  112. else
  113. { /* Search for valid dl containing insertion point */
  114. /* Use linear search, all dl's may not be valid */
  115. int dl;
  116. for ( pedl = dndl, dl = 0; dl < wwdCurrentDoc.dlMac; dl++, pedl++ )
  117. {
  118. if ( FCpInsertInDl( selCur.cpFirst, pedl ) )
  119. { /* Found it */
  120. vdlIns = dl;
  121. cpBegin = pedl->cpMin;
  122. break;
  123. }
  124. }
  125. if (dl >= wwdCurrentDoc.dlMac)
  126. { /* No valid dl contains the cp -- must update whole screen */
  127. cpBegin = CpBeginLine( &vdlIns, selCur.cpFirst );
  128. }
  129. }
  130. }
  131. /* Special case for splat: locate insert point at end of previous line */
  132. pedl = &(**wwdCurrentDoc.hdndl) [vdlIns];
  133. if (pedl->fSplat && (vdlIns > 0) && selCur.cpFirst == pedl->cpMin)
  134. { /* Splat on current line */
  135. /* Check for pedl->cpMin above is necessary for the special case */
  136. /* in which the QD buffer is at the beginning of the splat line */
  137. pedl--;
  138. if (pedl->fValid && !pedl->fSplat)
  139. { /* Locate cursor at end of previous line */
  140. vdlIns--;
  141. cpBegin = pedl->cpMin;
  142. ClearInsertLine();
  143. selCur.fEndOfLine = TRUE;
  144. vfInsEnd = TRUE;
  145. ToggleSel( selCur.cpFirst, selCur.cpLim, TRUE );
  146. }
  147. else
  148. {
  149. pedl++;
  150. goto CheckEnd;
  151. }
  152. }
  153. else
  154. { /* Eliminate end of line cursor if not before a splat */
  155. CheckEnd:
  156. if (selCur.fEndOfLine)
  157. {
  158. ClearInsertLine();
  159. selCur.fEndOfLine = FALSE;
  160. vfInsEnd = FALSE;
  161. ToggleSel( selCur.cpFirst, selCur.cpLim, TRUE );
  162. }
  163. }
  164. /* Assure we obtained a good vdlIns */
  165. Assert( vdlIns < wwdCurrentDoc.dlMac );
  166. Assert( ((selCur.cpFirst >= pedl->cpMin) &&
  167. (selCur.cpFirst <= pedl->cpMin + pedl->dcpMac)));
  168. FormatLine(docCur, cpBegin, 0, cpMacCur, flmSandMode);
  169. vxpIns = DxpDiff(0, (int) (selCur.cpFirst - cpBegin), &vxpIns) + vfli.xpLeft +
  170. xpSelBar - wwdCurrentDoc.xpMin;
  171. vdypBase = vfli.dypBase;
  172. vdypAfter = vfli.dypAfter;
  173. vdypCursLineIns = min(vfli.dypFont, vfli.dypLine - vdypAfter);
  174. vxpMacIns = vfli.xpMarg;
  175. LoadFont(docCur, &vchpInsert, mdFontChk);
  176. ferror = FALSE; // running out of memory here is OK. Must clear this
  177. // or important calls will needlessly fail.
  178. // (8.6.91) D. Kent
  179. #ifdef KOREA // jinwoo: 92, 9, 28
  180. /* For y position of display, 920604 KDLEE */
  181. #ifdef NODESC
  182. { extern HDC vhMDC;
  183. TEXTMETRIC tm;
  184. GetTextMetrics (vhMDC, (LPTEXTMETRIC)&tm);
  185. if (tm.tmCharSet==HANGEUL_CHARSET)
  186. vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp;
  187. else
  188. vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp - vdypBase;
  189. }
  190. #else /* NODESC */
  191. vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp - vdypBase;
  192. #endif /* NODESC */
  193. #else /* KOREA */
  194. vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp - vdypBase;
  195. #endif // KOREA: jinwoo: 92, 9, 28
  196. dypFontAscent = vfmiScreen.dypAscent + vfmiScreen.dypLeading;
  197. dypFontDescent = vfmiScreen.dypDescent;
  198. if (vchpInsert.hpsPos)
  199. {
  200. if (vchpInsert.hpsPos < hpsNegMin)
  201. {
  202. vypBaseIns -= ypSubSuper; /* Superscript */
  203. dypFontAscent += ypSubSuper;
  204. }
  205. else
  206. {
  207. vypBaseIns += ypSubSuper; /* Subscript */
  208. dypFontDescent += ypSubSuper;
  209. }
  210. }
  211. /* Set if current font is too tall to display on insert line */
  212. vfInsFontTooTall = (imax( dypFontAscent, vfli.dypLine - vfli.dypBase ) +
  213. imax( dypFontDescent, vfli.dypBase )) > vfli.dypLine;
  214. vfTextBltValid = true;
  215. }
  216. int NEAR FCpInsertInDl( cp, pedl )
  217. typeCP cp;
  218. register struct EDL *pedl;
  219. { /* Return TRUE if insert point cp is in dl & dl is valid, FALSE otherwise */
  220. if ( (pedl->fValid) && (cp >= pedl->cpMin) )
  221. { /* dl is valid & cp is at or below starting cp of dl */
  222. if ( (cp < pedl->cpMin + pedl->dcpMac) ||
  223. ((cp == cpMacCur) && (cp == pedl->cpMin + pedl->dcpMac)) )
  224. { /* cp is on line dl */
  225. if (pedl->yp <= wwdCurrentDoc.ypMac)
  226. { /* dl is complete, i.e. not cut off at bottom of window */
  227. return TRUE;
  228. }
  229. }
  230. }
  231. return FALSE;
  232. }
  233. #ifdef FOOTNOTES
  234. /* F E D I T F T N */
  235. int FEditFtn(cpFirst, cpLim)
  236. typeCP cpFirst, cpLim;
  237. { /* Return true if edit includes an end of footnote mark */
  238. struct FNTB **hfntb;
  239. typeCP cp;
  240. if ((hfntb = HfntbGet(docCur)) == 0 ||
  241. cpLim < (cp = (*hfntb)->rgfnd[0].cpFtn))
  242. return false;
  243. if (cpFirst < cp ||
  244. CpRefFromFtn(docCur, cpFirst) != CpRefFromFtn(docCur, cpLim))
  245. {
  246. Error(IDPMTFtnLoad);
  247. return fTrue;
  248. }
  249. return fFalse;
  250. }
  251. #endif /* FOOTNOTES */
  252. /* U P D A T E O T H E R W W S */
  253. #ifdef CASHMERE
  254. UpdateOtherWws(fInval)
  255. BOOL fInval;
  256. {
  257. int ww = 0;
  258. struct WWD *pwwd = rgwwd;
  259. {{
  260. while (ww < wwMac)
  261. {
  262. if (ww != wwCur && (pwwd++)->doc == docCur)
  263. {{
  264. typeCP cpI = cpInsert + ichInsert;
  265. typeCP cpH = CpMax(cpI, cpInsLastInval);
  266. typeCP cpL = CpMin(cpInsLastInval, cpI);
  267. typeCP dcp;
  268. if ((dcp = cpH - cpL) != cp0 || fInval)
  269. AdjustCp(docCur, cpL, dcp, dcp);
  270. cpInsLastInval = cpI;
  271. return;
  272. }}
  273. ww++;
  274. }
  275. }}
  276. }
  277. #endif /* CASHMERE */
  278. /* K C I N P U T N E X T K E Y */
  279. KcInputNextKey()
  280. { /* Get next available key/event from Windows */
  281. /* Returns key code or kcNil if a non-key event */
  282. /* Updates the screen if there is time before events arrive */
  283. extern HWND vhWnd; /* WINDOWS: Handle of the current document display window*/
  284. extern MSG vmsgLast; /* WINDOWS: last message gotten */
  285. extern int vfInsLast;
  286. extern int vfCommandKey;
  287. extern int vfShiftKey;
  288. extern int vfAwfulNoise;
  289. int i;
  290. int kc;
  291. for ( ;; )
  292. {
  293. if ( FImportantMsgPresent() )
  294. goto GotMessage;
  295. /* No events waiting -- if none show up for a while, update the screen */
  296. #ifdef CASHMERE
  297. UpdateOtherWws( FALSE );
  298. #endif
  299. { /* Dawdle for a time, looking for keys, before updating the screen */
  300. unsigned WHsecGetTime();
  301. unsigned wHsec;
  302. wHsec = WHsecGetTime();
  303. do
  304. {
  305. if ( FImportantMsgPresent() )
  306. goto GotMessage;
  307. } while ( WHsecGetTime() - wHsec < dwHsecKeyDawdle );
  308. }
  309. #ifdef DEBUG
  310. if (vTune)
  311. continue; /* Bag background update while debugging to see how we fare */
  312. #endif
  313. Scribble( 8, 'U' );
  314. ClearInsertLine();
  315. UpdateWw(wwCur, fTrue);
  316. ToggleSel(selCur.cpFirst, selCur.cpLim, fTrue);
  317. Scribble( 8, ' ' );
  318. if ( FImportantMsgPresent() )
  319. goto GotMessage;
  320. vfAwfulNoise = FALSE;
  321. PutCpInWwHz( selCur.cpFirst );
  322. EndLongOp( NULL );
  323. if ( FImportantMsgPresent() )
  324. goto GotMessage;
  325. if ( !vfTextBltValid )
  326. ValidateTextBlt();
  327. /* Nothing has happened for a while, let's blink the cursor */
  328. {
  329. unsigned WHsecGetTime();
  330. unsigned wHsecBlink = GetCaretBlinkTime() / 10;
  331. unsigned wHsecLastBlink=WHsecGetTime() + wHsecBlink/2;
  332. for ( ;; )
  333. {
  334. unsigned wHsecT;
  335. if ( FImportantMsgPresent() )
  336. goto GotMessage;
  337. /* Another app may have stolen the focus away from us while we called
  338. PeekMessage(), in which case we should end Alpha mode. */
  339. if (!vfFocus)
  340. return kcNil;
  341. UpdateDisplay( TRUE );
  342. if ( (wHsecT = WHsecGetTime()) - wHsecLastBlink >= wHsecBlink )
  343. {
  344. DrawInsertLine();
  345. wHsecLastBlink = wHsecT;
  346. }
  347. }
  348. }
  349. continue;
  350. GotMessage:
  351. #ifdef DBCS
  352. #ifdef KOREA /* Need to GetMessage for F-Key during Interim,90.12.27 sangl */
  353. if ( ((kc=KcAlphaKeyMessage( &vmsgLast )) != kcNil) || IsInterim)
  354. #else
  355. if ((kc=KcAlphaKeyMessage( &vmsgLast )) != kcNil)
  356. #endif
  357. {
  358. if (vmsgLast.wParam == VK_EXECUTE)
  359. return( kcNil );
  360. if (vmsgLast.message == WM_KEYDOWN)
  361. {
  362. switch (kc) {
  363. default:
  364. break;
  365. case kcAlphaVirtual:
  366. /* This means we can't anticipate the key's meaning
  367. before translation */
  368. #ifdef KOREA /* Need GetMesssage for direc keys, etc during interim 90.12.26 sangl */
  369. if ( FNonAlphaKeyMessage( &vmsgLast, FALSE ) && !IsInterim)
  370. #else
  371. if ( FNonAlphaKeyMessage( &vmsgLast, FALSE ) )
  372. #endif
  373. /* This is a non-alpha key message */
  374. return kcNil;
  375. if ( !donteat ) {
  376. GetMessage( (LPMSG)&vmsgLast, NULL, 0, 0 );
  377. #ifdef DBCS
  378. // kksuzuka #9193 NECAI95
  379. // got message is WM_KEYDOWN by PeekMessage( )
  380. // but got message is WM_IME_STARTCOMPOSITION by GetMessage()
  381. // We need DispatchMessage( WM_IME_STARTCOMPOSITION )
  382. if ( vmsgLast.message == 0x10d ) // WM_IME_STARTCOMPOSITION
  383. DispatchMessage( (LPMSG)&vmsgLast );
  384. #endif
  385. }
  386. else {
  387. /* not eat message because FimportantMsgPresent has
  388. ** eaten KEY_DOWN message
  389. */
  390. donteat = FALSE;
  391. }
  392. /*
  393. ** When KKAPP window open, this message is offten wrong.
  394. ** we must check it is really WM_KEYDOWN
  395. */
  396. #ifdef KOREA /* for level 3, 90.12.26 sangl */
  397. if ((vmsgLast.message == WM_CHAR) || (vmsgLast.message == WM_INTERIM)) {
  398. #else
  399. if ( vmsgLast.message == WM_CHAR ) {
  400. #endif
  401. return vmsgLast.wParam;
  402. }
  403. if ( vmsgLast.message != WM_KEYDOWN ) {
  404. return kcNil;
  405. }
  406. TranslateMessage( &vmsgLast );
  407. continue;
  408. } /* switch kc */
  409. } /* if keydown */
  410. if ( !donteat ) {
  411. GetMessage( (LPMSG) &vmsgLast, NULL, 0, 0 );
  412. #ifdef KOREA /* for level 3, 91.1.21 by Sangl */
  413. if ( (vmsgLast.message==WM_CHAR)||(vmsgLast.message==WM_INTERIM) ) {
  414. #else
  415. if ( vmsgLast.message == WM_CHAR ) {
  416. #endif
  417. return vmsgLast.wParam;
  418. }
  419. } /* dont eat */
  420. else {
  421. donteat = FALSE;
  422. }
  423. } /* if kc != kcNil */
  424. #else
  425. if ((kc=KcAlphaKeyMessage( &vmsgLast )) != kcNil)
  426. {
  427. if (vmsgLast.message == WM_KEYDOWN)
  428. {
  429. switch (kc) {
  430. default:
  431. break;
  432. case kcAlphaVirtual:
  433. /* This means we can't anticipate the key's meaning
  434. before translation */
  435. if ( FNonAlphaKeyMessage( &vmsgLast, FALSE ) )
  436. /* This is a non-alpha key message */
  437. return kcNil;
  438. GetMessage( (LPMSG)&vmsgLast, NULL, 0, 0 );
  439. TranslateMessage( &vmsgLast );
  440. continue;
  441. }
  442. }
  443. GetMessage( (LPMSG) &vmsgLast, NULL, 0, 0 );
  444. }
  445. #endif
  446. return kc;
  447. } /* End of for ( ;; ) loop to process messages */
  448. }
  449. #ifdef KOREA /* 90.12.29 sangl */
  450. KcInputNextHan()
  451. { /* Get next available key/event from Windows */
  452. /* Returns key code or kcNil if a non-key event */
  453. /* Updates the screen if there is time before events arrive */
  454. extern HWND vhWnd; /* WINDOWS: Handle of the current document display window*/
  455. extern MSG vmsgLast; /* WINDOWS: last message gotten */
  456. extern int vfInsLast;
  457. extern int vfCommandKey;
  458. extern int vfShiftKey;
  459. extern int vfAwfulNoise;
  460. int i;
  461. int kc;
  462. int tmp;
  463. tmp = vfInsLast;
  464. tmp = vfCommandKey;
  465. tmp = vfShiftKey;
  466. tmp = vfAwfulNoise;
  467. tmp = vmsgLast.message;
  468. tmp = vmsgLast.wParam;
  469. for ( ;; )
  470. {
  471. if ( FImportantMsgPresent() )
  472. goto GotMessage;
  473. /* No events waiting -- if none show up for a while, update the screen */
  474. { /* Dawdle for a time, looking for keys, before updating the screen */
  475. unsigned WHsecGetTime();
  476. unsigned wHsec;
  477. wHsec = WHsecGetTime();
  478. do
  479. {
  480. if ( FImportantMsgPresent() )
  481. goto GotMessage;
  482. } while ( WHsecGetTime() - wHsec < dwHsecKeyDawdle );
  483. }
  484. #ifdef DEBUG
  485. if (vTune)
  486. continue; /* Bag background update while debugging to see how we fare */
  487. #endif
  488. if ( FImportantMsgPresent() )
  489. goto GotMessage;
  490. /* vfAwfulNoise = FALSE;
  491. PutCpInWwHz( selCur.cpFirst );
  492. EndLongOp( NULL );*/
  493. if ( FImportantMsgPresent() )
  494. goto GotMessage;
  495. /* Nothing has happened for a while, let's blink the cursor */
  496. {
  497. unsigned WHsecGetTime();
  498. unsigned wHsecBlink = GetCaretBlinkTime() / 10;
  499. unsigned wHsecLastBlink=WHsecGetTime() + wHsecBlink/2;
  500. KillTimer( vhWnd, tidCaret );
  501. for ( ;; )
  502. {
  503. unsigned wHsecT;
  504. if ( FImportantMsgPresent() ) {
  505. SetTimer( vhWnd, tidCaret, GetCaretBlinkTime(), (FARPROC)NULL );
  506. goto GotMessage;
  507. }
  508. /* Another app may have stolen the focus away from us while we called
  509. PeekMessage(), in which case we should end Alpha mode. */
  510. if (!vfFocus) {
  511. SetTimer( vhWnd, tidCaret, GetCaretBlinkTime(), (FARPROC)NULL );
  512. return kcNil;
  513. }
  514. if ( (wHsecT = WHsecGetTime()) - wHsecLastBlink >= wHsecBlink )
  515. {
  516. DrawInsertLine();
  517. wHsecLastBlink = wHsecT;
  518. }
  519. }
  520. }
  521. continue;
  522. GotMessage:
  523. { // MSCH bklee 12/22/94
  524. #define VK_PROCESSKEY 0xE5 // New finalize message. bklee.
  525. #include "ime.h"
  526. MSG msg;
  527. extern BOOL fInterim;
  528. if (fInterim) {
  529. if (PeekMessage ((LPMSG)&msg, vhWnd, WM_KEYDOWN, WM_SYSKEYUP, PM_NOYIELD | PM_NOREMOVE )) {
  530. if ( msg.wParam == VK_MENU || msg.wParam == VK_PROCESSKEY )
  531. return VK_MENU;
  532. else if( msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT ) {
  533. HANDLE hIme;
  534. LPIMESTRUCT lpIme;
  535. DWORD dwConversionMode;
  536. hIme = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE,(LONG)sizeof(IMESTRUCT));
  537. if (hIme && (lpIme = (LPIMESTRUCT)GlobalLock(hIme))) {
  538. lpIme->fnc = IME_GETCONVERSIONMODE;
  539. GlobalUnlock(hIme);
  540. dwConversionMode = SendIMEMessage (GetFocus(), MAKELONG(hIme,0));
  541. GlobalFree(hIme);
  542. }
  543. if (dwConversionMode & IME_MODE_HANJACONVERT) // Hanja conversion mode
  544. return VK_MENU;
  545. }
  546. }
  547. }
  548. }
  549. if( vmsgLast.wParam == VK_EXECUTE )
  550. vmsgLast.wParam = VK_RETURN;
  551. /* To GetMessage for Func/Ctrl/direc keys, 90.4.4, Sang-Weon */
  552. if ( ((kc=KcAlphaKeyMessage(&vmsgLast))!=kcNil) || IsInterim )
  553. {
  554. if( vmsgLast.wParam == VK_EXECUTE )
  555. return kcNil;
  556. if (vmsgLast.message == WM_KEYDOWN)
  557. {
  558. switch (kc) {
  559. default:
  560. break;
  561. case kcAlphaVirtual:
  562. /* This means we can't anticipate the key's meaning
  563. before translation */
  564. if ( FNonAlphaKeyMessage(&vmsgLast, FALSE) && !IsInterim )
  565. /* This is a non-alpha key message */
  566. return kcNil;
  567. if ( !donteat ) {
  568. GetMessage( (LPMSG)&vmsgLast, NULL, 0, 0 );
  569. }
  570. else {
  571. /* not eat message because FimportantMsgPresent has
  572. ** eaten KEY_DOWN message
  573. */
  574. donteat = FALSE;
  575. }
  576. /*
  577. ** When KKAPP window open, this message is offten wrong.
  578. ** we must check it is really WM_KEYDOWN
  579. */
  580. if ( (vmsgLast.message==WM_CHAR)||(vmsgLast.message==WM_INTERIM) ) {
  581. return vmsgLast.wParam;
  582. }
  583. if ( vmsgLast.message != WM_KEYDOWN ) {
  584. return kcNil;
  585. }
  586. TranslateMessage( &vmsgLast );
  587. continue;
  588. } /* switch kc */
  589. } /* if keydown */
  590. if ( !donteat ) {
  591. GetMessage( (LPMSG) &vmsgLast, NULL, 0, 0 );
  592. if ( (vmsgLast.message==WM_CHAR)||(vmsgLast.message==WM_INTERIM) ) {
  593. return vmsgLast.wParam;
  594. }
  595. } /* dont eat */
  596. else {
  597. donteat = FALSE;
  598. }
  599. } /* if kc != kcNil */
  600. return kc;
  601. } /* End of for ( ;; ) loop to process messages */
  602. }
  603. #endif /* ifdef KOREA */