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.

1417 lines
42 KiB

  1. // Copyright (c) 1985 - 1999, Microsoft Corporation
  2. //
  3. // MODULE: ConIme.c
  4. //
  5. // PURPOSE: Console IME control.
  6. //
  7. // PLATFORMS: Windows NT-J 3.51
  8. //
  9. // FUNCTIONS:
  10. // WinMain() - calls initialization functions, processes message loop
  11. // WndProc - Processes messages for the main window.
  12. //
  13. // History:
  14. //
  15. // 27.Jul.1995 v-HirShi (Hirotoshi Shimizu) created
  16. //
  17. // COMMENTS:
  18. //
  19. #include "precomp.h"
  20. #pragma hdrstop
  21. // Global Variables
  22. HANDLE LastConsole;
  23. HIMC ghDefaultIMC;
  24. PCONSOLE_TABLE *ConsoleTable;
  25. ULONG NumberOfConsoleTable;
  26. CRITICAL_SECTION ConsoleTableLock; // serialize console table access
  27. #define LockConsoleTable() RtlEnterCriticalSection(&ConsoleTableLock)
  28. #define UnlockConsoleTable() RtlLeaveCriticalSection(&ConsoleTableLock)
  29. BOOL gfDoNotKillFocus;
  30. DWORD dwConsoleThreadId = 0;
  31. #if DBG
  32. ULONG InputExceptionFilter(
  33. PEXCEPTION_POINTERS pexi)
  34. {
  35. if (pexi->ExceptionRecord->ExceptionCode != STATUS_PORT_DISCONNECTED) {
  36. DbgPrint("CONIME: Unexpected exception - %x, pexi = %x\n",
  37. pexi->ExceptionRecord->ExceptionCode, pexi);
  38. DbgBreakPoint();
  39. }
  40. return EXCEPTION_EXECUTE_HANDLER;
  41. }
  42. #else
  43. #define InputExceptionFilter(pexi) EXCEPTION_EXECUTE_HANDLER
  44. #endif
  45. int
  46. APIENTRY
  47. WinMain(
  48. HINSTANCE hInstance,
  49. HINSTANCE hPrevInstance,
  50. LPSTR lpCmdLine,
  51. int nCmdShow
  52. )
  53. {
  54. MSG msg;
  55. WCHAR systemPath[MAX_PATH];
  56. if (GetSystemDirectory ( systemPath, MAX_PATH ) > 0 )
  57. SetCurrentDirectory ( systemPath );
  58. #ifdef CUAS_ENABLE
  59. //
  60. // Disable CUAS on the conime.exe process
  61. //
  62. ImmDisableTextFrameService( -1 );
  63. #endif
  64. if (!InitConsoleIME(hInstance) ) {
  65. DBGPRINT(("CONIME: InitConsoleIME failure!\n"));
  66. return FALSE;
  67. }
  68. else {
  69. DBGPRINT(("CONIME: InitConsoleIME successful!\n"));
  70. }
  71. try {
  72. while (TRUE) {
  73. if (GetMessage(&msg, NULL, 0, 0)) {
  74. TranslateMessage(&msg);
  75. DispatchMessage(&msg);
  76. } else {
  77. break;
  78. }
  79. }
  80. } except (InputExceptionFilter(GetExceptionInformation())) {
  81. if (dwConsoleThreadId)
  82. {
  83. DBGPRINT(("CONIME: Exception on WinMain!!\n"));
  84. UnregisterConsoleIME();
  85. dwConsoleThreadId = 0;
  86. }
  87. }
  88. return (int)msg.wParam;
  89. }
  90. BOOL
  91. InitConsoleIME(
  92. HINSTANCE hInstance
  93. )
  94. {
  95. HANDLE hEvent = NULL;
  96. ATOM atom = 0;
  97. HWND hWnd = NULL;
  98. WNDCLASS ConsoleIMEClass;
  99. int cxExecStart;
  100. int cyExecStart;
  101. WCHAR szMenuName[16]; // The name of Menu
  102. WCHAR szClassName[16]; // The class name of this application
  103. WCHAR szTitle[16]; // The title bar text
  104. #ifdef DEBUG_MODE
  105. WCHAR szAppName[16]; // The name of this application
  106. LoadString(hInstance, IDS_TITLE, szTitle, sizeof(szTitle));
  107. #else
  108. szTitle[0] = L'\0';
  109. #endif
  110. DBGPRINT(("CONIME: Enter InitConsoleIMEl!\n"));
  111. RtlInitializeCriticalSection(&ConsoleTableLock);
  112. ConsoleTable = (PCONSOLE_TABLE *)LocalAlloc(LPTR, CONSOLE_INITIAL_TABLE * sizeof(PCONSOLE_TABLE));
  113. if (ConsoleTable == NULL) {
  114. return FALSE;
  115. }
  116. RtlZeroMemory(ConsoleTable, CONSOLE_INITIAL_TABLE * sizeof(PCONSOLE_TABLE));
  117. NumberOfConsoleTable = CONSOLE_INITIAL_TABLE;
  118. // Load the application name and description strings.
  119. LoadString(hInstance, IDS_MENUNAME, szMenuName, sizeof(szMenuName)/sizeof(szMenuName[0]));
  120. LoadString(hInstance, IDS_CLASSNAME, szClassName, sizeof(szClassName)/sizeof(szClassName[0]));
  121. hEvent = OpenEvent(EVENT_MODIFY_STATE, // Access flag
  122. FALSE, // Inherit
  123. CONSOLEIME_EVENT); // Event object name
  124. if (hEvent == NULL)
  125. {
  126. DBGPRINT(("CONIME: OpenEvent failure! %d\n",GetLastError()));
  127. goto ErrorExit;
  128. }
  129. // Fill in window class structure with parameters that describe the
  130. // main window.
  131. ConsoleIMEClass.style = 0; // Class style(s).
  132. ConsoleIMEClass.lpfnWndProc = WndProc; // Window Procedure
  133. ConsoleIMEClass.cbClsExtra = 0; // No per-class extra data.
  134. ConsoleIMEClass.cbWndExtra = 0; // No per-window extra data.
  135. ConsoleIMEClass.hInstance = hInstance; // Owner of this class
  136. ConsoleIMEClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ID_CONSOLEIME_ICON));
  137. ConsoleIMEClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Cursor
  138. ConsoleIMEClass.hbrBackground = GetStockObject(WHITE_BRUSH); // Default color
  139. ConsoleIMEClass.lpszMenuName = szMenuName; // Menu name from .RC
  140. ConsoleIMEClass.lpszClassName = szClassName; // Class Name
  141. // Register the window class and return FALSE if unsuccesful.
  142. atom = RegisterClass(&ConsoleIMEClass);
  143. if (atom == 0)
  144. {
  145. DBGPRINT(("CONIME: RegisterClass failure! %d\n",GetLastError()));
  146. goto ErrorExit;
  147. }
  148. else {
  149. DBGPRINT(("CONIME: RegisterClass Successful!\n"));
  150. }
  151. // Guess size for now.
  152. cxExecStart = GetSystemMetrics(SM_CXSCREEN);
  153. cyExecStart = GetSystemMetrics(SM_CYMENU);
  154. // Create a main window for this application instance.
  155. hWnd = CreateWindow(szClassName, // See RegisterClass() call.
  156. szTitle, // Text for window title bar.
  157. WS_OVERLAPPEDWINDOW,
  158. cxExecStart - (cxExecStart / 3) ,
  159. cyExecStart ,
  160. cxExecStart / 3 ,
  161. cyExecStart * 10 ,
  162. NULL, // Overlapped has no parent.
  163. NULL, // Use the window class menu.
  164. hInstance,
  165. (LPVOID)NULL);
  166. // If window could not be created, return "failure"
  167. if (hWnd == NULL) {
  168. DBGPRINT(("CONIME: CreateWindow failured! %d\n",GetLastError()));
  169. goto ErrorExit;
  170. }
  171. else{
  172. DBGPRINT(("CONIME: CreateWindow Successful!\n"));
  173. }
  174. if (! RegisterConsoleIME(hWnd, &dwConsoleThreadId))
  175. {
  176. DBGPRINT(("CONIME: RegisterConsoleIME failured! %d\n",GetLastError()));
  177. goto ErrorExit;
  178. }
  179. if (! AttachThreadInput(GetCurrentThreadId(), dwConsoleThreadId, TRUE))
  180. {
  181. DBGPRINT(("CONIME: AttachThreadInput failured! %d\n",GetLastError()));
  182. goto ErrorExit;
  183. }
  184. /*
  185. * dwConsoleThreadId is locked until event sets of hEvent
  186. */
  187. SetEvent(hEvent);
  188. CloseHandle(hEvent);
  189. #ifdef DEBUG_MODE
  190. LoadString(hInstance, IDS_APPNAME, szAppName, sizeof(szAppName));
  191. // Make the window visible; update its client area; and return "success"
  192. ShowWindow(hWnd, SW_MINIMIZE); // Show the window
  193. SetWindowText(hWnd, szAppName);
  194. UpdateWindow(hWnd); // Sends WM_PAINT message
  195. {
  196. int i;
  197. for (i = 0; i < CVMAX; i++) {
  198. ConvertLine[i] = UNICODE_SPACE;
  199. ConvertLineAtr[i] = 0;
  200. }
  201. xPos = 0;
  202. xPosLast = 0;
  203. }
  204. #endif
  205. return TRUE; // We succeeded...
  206. ErrorExit:
  207. if (dwConsoleThreadId)
  208. UnregisterConsoleIME();
  209. if (hWnd)
  210. DestroyWindow(hWnd);
  211. if (atom)
  212. UnregisterClass(szClassName,hInstance);
  213. if (hEvent)
  214. {
  215. SetEvent(hEvent);
  216. CloseHandle(hEvent);
  217. }
  218. return FALSE;
  219. }
  220. //
  221. // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  222. //
  223. // PURPOSE: Processes messages
  224. //
  225. // PARAMETERS:
  226. // hwnd - window handle
  227. // uMessage - message number
  228. // wparam - additional information (dependant of message number)
  229. // lparam - additional information (dependant of message number)
  230. //
  231. // MESSAGES:
  232. //
  233. // WM_COMMAND - exit command
  234. // WM_DESTROY - destroy window
  235. //
  236. // RETURN VALUE:
  237. //
  238. // Depends on the message number.
  239. //
  240. // COMMENTS:
  241. //
  242. //
  243. LRESULT FAR PASCAL WndProc( HWND hWnd,
  244. UINT Message,
  245. WPARAM wParam,
  246. LPARAM lParam)
  247. {
  248. DWORD dwImmRet = 0; // return value of ImmSrvProcessKey()
  249. try {
  250. switch (Message)
  251. {
  252. case CONIME_CREATE:
  253. DBGPRINT(("CONIME: CONIME_CREATE: Console Handle=%08x\n", wParam));
  254. return InsertNewConsole(hWnd,(HANDLE)wParam,(HWND)lParam);
  255. case CONIME_DESTROY:
  256. DBGPRINT(("CONIME: CONIME_DESTROY: Console Handle=%08x\n", wParam));
  257. return RemoveConsole(hWnd, (HANDLE)wParam);
  258. case CONIME_SETFOCUS:
  259. DBGPRINT(("CONIME: CONIME_SETFOCUS: Console Handle=%08x\n", wParam));
  260. return ConsoleSetFocus(hWnd, (HANDLE)wParam, (HKL)lParam);
  261. case CONIME_KILLFOCUS:
  262. DBGPRINT(("CONIME: CONIME_KILLFOCUS: Console Handle=%08x\n", wParam));
  263. return ConsoleKillFocus(hWnd, (HANDLE)wParam);
  264. case CONIME_GET_NLSMODE:
  265. DBGPRINT(("CONIME: CONIME_GET_NLSMODE: Console Handle=%08x\n", wParam));
  266. return GetNLSMode(hWnd, (HANDLE)wParam);
  267. case CONIME_SET_NLSMODE:
  268. DBGPRINT(("CONIME: CONIME_SET_NLSMODE: Console Handle=%08x\n", wParam));
  269. return SetNLSMode(hWnd, (HANDLE)wParam, (DWORD)lParam);
  270. case CONIME_HOTKEY:
  271. DBGPRINT(("CONIME: CONIME_HOTKEY\n"));
  272. return ConimeHotkey(hWnd, (HANDLE)wParam, (DWORD)lParam);
  273. case CONIME_NOTIFY_VK_KANA:
  274. DBGPRINT(("CONIME: CONIME_NOTIFY_VK_KANA\n"));
  275. return ImeUISetConversionMode(hWnd);
  276. case CONIME_NOTIFY_SCREENBUFFERSIZE: {
  277. COORD ScreenBufferSize;
  278. DBGPRINT(("CONIME: CONIME_NOTIFY_SCREENBUFFERSIZE: Console Handle=%08x\n", wParam));
  279. ScreenBufferSize.X = LOWORD(lParam);
  280. ScreenBufferSize.Y = HIWORD(lParam);
  281. return ConsoleScreenBufferSize(hWnd, (HANDLE)wParam, ScreenBufferSize);
  282. }
  283. case CONIME_INPUTLANGCHANGE: {
  284. DBGPRINT(("CONIME: CONIME_INPUTLANGCHANGE: Console Handle=%08x \n",wParam));
  285. ConImeInputLangchange(hWnd, (HANDLE)wParam, (HKL)lParam );
  286. return TRUE;
  287. }
  288. case CONIME_NOTIFY_CODEPAGE: {
  289. BOOL Output;
  290. WORD Codepage;
  291. Codepage = HIWORD(lParam);
  292. Output = LOWORD(lParam);
  293. DBGPRINT(("CONIME: CONIME_NOTIFY_CODEPAGE: Console Handle=%08x %04x %04x\n",wParam, Output, Codepage));
  294. return ConsoleCodepageChange(hWnd, (HANDLE)wParam, Output, Codepage);
  295. }
  296. case WM_KEYDOWN +CONIME_KEYDATA:
  297. case WM_KEYUP +CONIME_KEYDATA:
  298. case WM_SYSKEYDOWN +CONIME_KEYDATA:
  299. case WM_SYSKEYUP +CONIME_KEYDATA:
  300. case WM_DEADCHAR +CONIME_KEYDATA:
  301. case WM_SYSDEADCHAR+CONIME_KEYDATA:
  302. case WM_SYSCHAR +CONIME_KEYDATA:
  303. case WM_CHAR +CONIME_KEYDATA:
  304. CharHandlerFromConsole( hWnd, Message, (ULONG)wParam, (ULONG)lParam );
  305. break;
  306. case WM_KEYDOWN:
  307. case WM_KEYUP:
  308. case WM_SYSKEYDOWN:
  309. case WM_SYSKEYUP:
  310. case WM_DEADCHAR:
  311. case WM_SYSDEADCHAR:
  312. case WM_SYSCHAR:
  313. case WM_CHAR:
  314. CharHandlerToConsole( hWnd, Message, (ULONG)wParam, (ULONG)lParam );
  315. break;
  316. case WM_INPUTLANGCHANGE:
  317. DBGPRINT(("CONIME: CONIME_INPUTLANGCHANGE: Console Handle=%08x \n",wParam));
  318. InputLangchange(hWnd, (DWORD)wParam, (HKL)lParam );
  319. return TRUE;
  320. case WM_INPUTLANGCHANGEREQUEST:
  321. // Console IME never receive this message for this window is hidden
  322. // and doesn't have focus.
  323. //
  324. // However, Hot key of IME_CHOTKEY_IME_NONIME_TOGGLE/IME_THOTKEY_IME_NONIME_TOGGLE
  325. // are send this message by ImmSimulateHotKey API.
  326. //
  327. // If nothing processing by this message, then DefWindowProc calls
  328. // ActivateKeyboardLayout on kernel side.
  329. // And, ActivateKeyboardLayout send WM_INPUTLANGCHANGE message to focus window
  330. // on this message queue.
  331. // It window is console window procedure.
  332. // Console window procedure can do send CONIME_INPUTLANGCHANGE message to
  333. // console IME window.
  334. // In console window is windowed case, this sequence as well.
  335. // But, In console window is full screen case, message queue have not focus.
  336. // WM_INPUTLANGCHANGE message can not send to console window procedure.
  337. //
  338. // This code avoid console full screen mode problem.
  339. // Send message to console window procedure when this window receive it.
  340. //
  341. {
  342. PCONSOLE_TABLE ConTbl;
  343. ConTbl = SearchConsole(LastConsole);
  344. if (ConTbl == NULL) {
  345. return DefWindowProc(hWnd, Message, wParam, lParam);
  346. }
  347. PostMessage(ConTbl->hWndCon, Message, wParam, lParam);
  348. }
  349. return TRUE; // TRUE : process this message by application
  350. case CONIME_INPUTLANGCHANGEREQUEST:
  351. DBGPRINT(("CONIME: CONIME_INPUTLANGCHANGEREQUEST: Console Handle=%08x \n",wParam));
  352. return ConImeInputLangchangeRequest(hWnd, (HANDLE)wParam, (HKL)lParam, CONIME_DIRECT);
  353. case CONIME_INPUTLANGCHANGEREQUESTFORWARD:
  354. DBGPRINT(("CONIME: CONIME_INPUTLANGCHANGEREQUEST: Console Handle=%08x \n",wParam));
  355. return ConImeInputLangchangeRequest(hWnd, (HANDLE)wParam, (HKL)lParam, CONIME_FORWARD);
  356. case CONIME_INPUTLANGCHANGEREQUESTBACKWARD:
  357. DBGPRINT(("CONIME: CONIME_INPUTLANGCHANGEREQUEST: Console Handle=%08x \n",wParam));
  358. return ConImeInputLangchangeRequest(hWnd, (HANDLE)wParam, (HKL)lParam, CONIME_BACKWARD);
  359. #ifdef DEBUG_MODE
  360. case WM_MOVE:
  361. ImeUIMoveCandWin( hWnd );
  362. break;
  363. case WM_COMMAND: // message: command from application menu
  364. // Message packing of wparam and lparam have changed for Win32,
  365. // so use the GET_WM_COMMAND macro to unpack the commnad
  366. switch (LOWORD(wParam)) {
  367. case MM_EXIT:
  368. PostMessage(hWnd,WM_CLOSE,0,0L);
  369. break;
  370. case MM_ACCESS_VIOLATION:
  371. {
  372. PBYTE p = 0;
  373. *p = 0;
  374. }
  375. break;
  376. }
  377. break;
  378. #endif
  379. case WM_IME_STARTCOMPOSITION:
  380. ImeUIStartComposition( hWnd );
  381. break;
  382. case WM_IME_ENDCOMPOSITION:
  383. ImeUIEndComposition( hWnd );
  384. break;
  385. case WM_IME_COMPOSITION:
  386. ImeUIComposition( hWnd, wParam, lParam );
  387. break;
  388. case WM_IME_COMPOSITIONFULL:
  389. break;
  390. case WM_IME_NOTIFY:
  391. if ( !ImeUINotify( hWnd, wParam, lParam ) ) {
  392. return DefWindowProc(hWnd, Message, wParam, lParam);
  393. }
  394. break;
  395. case WM_IME_SETCONTEXT:
  396. //
  397. // The application have to pass WM_IME_SETCONTEXT to DefWindowProc.
  398. // When the application want to handle the IME at the timing of
  399. // focus changing, the application should use WM_GETFOCUS or
  400. // WM_KILLFOCUS.
  401. //
  402. lParam &= ~ISC_SHOWUIALL;
  403. return DefWindowProc( hWnd, Message, wParam, lParam );
  404. case WM_IME_SYSTEM:
  405. switch (wParam) {
  406. case IMS_CLOSEPROPERTYWINDOW:
  407. case IMS_OPENPROPERTYWINDOW:
  408. ImeSysPropertyWindow(hWnd, wParam, lParam);
  409. break;
  410. default:
  411. return DefWindowProc( hWnd, Message, wParam, lParam );
  412. }
  413. break;
  414. case WM_CREATE:
  415. return Create(hWnd);
  416. break;
  417. case WM_DESTROY:
  418. DBGPRINT(("CONIME:Recieve WM_DESTROY\n"));
  419. ExitList(hWnd);
  420. PostQuitMessage(0);
  421. return 0;
  422. break;
  423. case WM_CLOSE:
  424. DBGPRINT(("CONIME:Recieve WM_CLOSE\n"));
  425. DestroyWindow(hWnd);
  426. return 0;
  427. break;
  428. case WM_ENABLE:{
  429. PCONSOLE_TABLE FocusedConsole;
  430. if (!wParam) {
  431. FocusedConsole = SearchConsole(LastConsole);
  432. if (FocusedConsole != NULL &&
  433. FocusedConsole->hConsole != NULL) {
  434. FocusedConsole->Enable = FALSE;
  435. EnableWindow(FocusedConsole->hWndCon,FALSE);
  436. gfDoNotKillFocus = TRUE;
  437. }
  438. }
  439. else{
  440. DWORD i;
  441. LockConsoleTable();
  442. for ( i = 1; i < NumberOfConsoleTable; i ++){
  443. FocusedConsole = ConsoleTable[i];
  444. if (FocusedConsole != NULL)
  445. {
  446. if ((FocusedConsole->hConsole != NULL)&&
  447. (!FocusedConsole->Enable)&&
  448. (!IsWindowEnabled(FocusedConsole->hWndCon))){
  449. EnableWindow(FocusedConsole->hWndCon,TRUE);
  450. FocusedConsole->Enable = TRUE;
  451. if (!FocusedConsole->LateRemove)
  452. SetForegroundWindow(FocusedConsole->hWndCon);
  453. }
  454. }
  455. }
  456. UnlockConsoleTable();
  457. }
  458. return DefWindowProc(hWnd, Message, wParam, lParam);
  459. break;
  460. }
  461. #ifdef DEBUG_MODE
  462. case WM_SETFOCUS:
  463. CreateCaret( hWnd,
  464. NULL,
  465. IsUnicodeFullWidth( ConvertLine[xPos] ) ?
  466. CaretWidth*2 : CaretWidth,
  467. (UINT)cyMetrics );
  468. SetCaretPos( xPos * cxMetrics, 0 );
  469. ShowCaret( hWnd );
  470. break;
  471. case WM_KILLFOCUS:
  472. HideCaret( hWnd );
  473. DestroyCaret();
  474. break;
  475. case WM_PAINT:
  476. {
  477. PAINTSTRUCT pstruc;
  478. HDC hDC;
  479. hDC = BeginPaint(hWnd,&pstruc);
  480. ReDraw(hWnd);
  481. EndPaint(hWnd,&pstruc);
  482. break;
  483. }
  484. #endif
  485. case WM_QUERYENDSESSION:
  486. #ifdef HIRSHI_DEBUG
  487. /*
  488. * If specified ntsd debugger on this process,
  489. * then never catch WM_QUERYENDSESSION when logoff/shutdown because
  490. * this process will terminate when ntsd process terminated.
  491. */
  492. {
  493. int i;
  494. i = MessageBox(hWnd,TEXT("Could you approve exit session?"), TEXT("Console IME"),
  495. MB_ICONSTOP | MB_YESNO);
  496. return (i == IDYES ? TRUE : FALSE);
  497. }
  498. #endif
  499. return TRUE; // Logoff or shutdown time.
  500. case WM_ENDSESSION:
  501. DBGPRINT(("CONIME:Recieve WM_ENDSESSION\n"));
  502. ExitList(hWnd);
  503. return 0;
  504. default: // Passes it on if unproccessed
  505. return DefWindowProc(hWnd, Message, wParam, lParam);
  506. }
  507. } except (InputExceptionFilter(GetExceptionInformation())) {
  508. if (dwConsoleThreadId)
  509. {
  510. DBGPRINT(("CONIME: Exception on WndProc!!\n"));
  511. UnregisterConsoleIME();
  512. dwConsoleThreadId = 0;
  513. DestroyWindow(hWnd);
  514. return 0;
  515. }
  516. }
  517. return TRUE;
  518. }
  519. VOID
  520. ExitList(
  521. HWND hWnd
  522. )
  523. {
  524. ULONG i ,j;
  525. PCONSOLE_TABLE FocusedConsole;
  526. DBGPRINT(("CONIME:ExitList Processing\n"));
  527. ImmAssociateContext(hWnd,ghDefaultIMC);
  528. LockConsoleTable();
  529. for (i = 1; i < NumberOfConsoleTable; i++) {
  530. FocusedConsole = ConsoleTable[i];
  531. if (FocusedConsole != NULL)
  532. {
  533. if (FocusedConsole->hConsole != NULL) {
  534. if (FocusedConsole->Enable) {
  535. ImmDestroyContext(FocusedConsole->hIMC_Original);
  536. if ( FocusedConsole->lpCompStrMem != NULL) {
  537. LocalFree( FocusedConsole->lpCompStrMem );
  538. FocusedConsole->lpCompStrMem = NULL;
  539. }
  540. for (j = 0; j < MAX_LISTCAND; j++){
  541. if (FocusedConsole->lpCandListMem[j] != NULL) {
  542. LocalFree(FocusedConsole->lpCandListMem[j]);
  543. FocusedConsole->lpCandListMem[j] = NULL;
  544. FocusedConsole->CandListMemAllocSize[j] = 0;
  545. }
  546. }
  547. if (FocusedConsole->CandSep != NULL) {
  548. LocalFree(FocusedConsole->CandSep);
  549. FocusedConsole->CandSepAllocSize = 0;
  550. }
  551. FocusedConsole->Enable = FALSE;
  552. }
  553. else
  554. FocusedConsole->LateRemove = TRUE;
  555. }
  556. }
  557. }
  558. LocalFree( ConsoleTable );
  559. ConsoleTable = NULL;
  560. UnlockConsoleTable();
  561. if (dwConsoleThreadId)
  562. {
  563. AttachThreadInput(GetCurrentThreadId(), dwConsoleThreadId, FALSE);
  564. UnregisterConsoleIME();
  565. dwConsoleThreadId = 0;
  566. }
  567. }
  568. BOOL
  569. InsertConsole(
  570. HWND hWnd,
  571. HANDLE hConsole,
  572. HWND hWndConsole
  573. )
  574. {
  575. ULONG i;
  576. PCONSOLE_TABLE FocusedConsole;
  577. i = 1;
  578. do {
  579. for (; i < NumberOfConsoleTable; i++) {
  580. FocusedConsole = ConsoleTable[i];
  581. if (FocusedConsole == NULL)
  582. {
  583. FocusedConsole = LocalAlloc(LPTR, sizeof(CONSOLE_TABLE));
  584. if (FocusedConsole == NULL)
  585. return FALSE;
  586. ConsoleTable[i] = FocusedConsole;
  587. }
  588. if ((FocusedConsole->hConsole != NULL) &&
  589. (FocusedConsole->LateRemove)&&
  590. (FocusedConsole->Enable)) {
  591. RemoveConsoleWorker(hWnd, FocusedConsole);
  592. }
  593. if (FocusedConsole->hConsole == NULL) {
  594. RtlZeroMemory(FocusedConsole, sizeof(CONSOLE_TABLE));
  595. FocusedConsole->lphklList = LocalAlloc(LPTR, sizeof(HKL_TABLE)*HKL_INITIAL_TABLE);
  596. if (FocusedConsole->lphklList == NULL)
  597. {
  598. return FALSE;
  599. }
  600. RtlZeroMemory(FocusedConsole->lphklList, sizeof(HKL_TABLE)*HKL_INITIAL_TABLE);
  601. FocusedConsole->hklListMax = HKL_INITIAL_TABLE ;
  602. FocusedConsole->hIMC_Current = ImmCreateContext();
  603. if (FocusedConsole->hIMC_Current == (HIMC)NULL) {
  604. LocalFree(FocusedConsole);
  605. FocusedConsole = NULL;
  606. return FALSE;
  607. }
  608. FocusedConsole->hIMC_Original = FocusedConsole->hIMC_Current;
  609. FocusedConsole->hConsole = hConsole;
  610. FocusedConsole->hWndCon = hWndConsole;
  611. // FocusedConsole->hklActive = NULL;
  612. FocusedConsole->Enable = TRUE;
  613. // FocusedConsole->LateRemove = FALSE;
  614. // FocusedConsole->fNestCandidate = FALSE;
  615. // FocusedConsole->fInComposition = FALSE;
  616. // FocusedConsole->fInCandidate = FALSE;
  617. FocusedConsole->ScreenBufferSize.X = DEFAULT_TEMP_WIDTH;
  618. FocusedConsole->CompAttrColor[0] = DEFAULT_COMP_ENTERED;
  619. FocusedConsole->CompAttrColor[1] = DEFAULT_COMP_ALREADY_CONVERTED;
  620. FocusedConsole->CompAttrColor[2] = DEFAULT_COMP_CONVERSION;
  621. FocusedConsole->CompAttrColor[3] = DEFAULT_COMP_YET_CONVERTED;
  622. FocusedConsole->CompAttrColor[4] = DEFAULT_COMP_INPUT_ERROR;
  623. FocusedConsole->CompAttrColor[5] = DEFAULT_COMP_INPUT_ERROR;
  624. FocusedConsole->CompAttrColor[6] = DEFAULT_COMP_INPUT_ERROR;
  625. FocusedConsole->CompAttrColor[7] = DEFAULT_COMP_INPUT_ERROR;
  626. GetIMEName(FocusedConsole);
  627. return TRUE;
  628. }
  629. }
  630. } while (GrowConsoleTable());
  631. DBGPRINT(("CONIME: Cannot grow Console Table\n"));
  632. return FALSE;
  633. }
  634. BOOL
  635. GrowConsoleTable(
  636. VOID
  637. )
  638. {
  639. PCONSOLE_TABLE *NewTable;
  640. PCONSOLE_TABLE *OldTable;
  641. ULONG MaxConsoleTable;
  642. MaxConsoleTable = NumberOfConsoleTable + CONSOLE_CONSOLE_TABLE_INCREMENT;
  643. NewTable = (PCONSOLE_TABLE *)LocalAlloc(LPTR, MaxConsoleTable * sizeof(PCONSOLE_TABLE));
  644. if (NewTable == NULL) {
  645. return FALSE;
  646. }
  647. CopyMemory(NewTable, ConsoleTable, NumberOfConsoleTable * sizeof(PCONSOLE_TABLE));
  648. OldTable = ConsoleTable;
  649. ConsoleTable = NewTable;
  650. NumberOfConsoleTable = MaxConsoleTable;
  651. LocalFree(OldTable);
  652. return TRUE;
  653. }
  654. PCONSOLE_TABLE
  655. SearchConsole(
  656. HANDLE hConsole
  657. )
  658. {
  659. ULONG i;
  660. PCONSOLE_TABLE FocusedConsole;
  661. LockConsoleTable();
  662. // conime receive ime message from console before 1st console registered.
  663. // this will happen after restart conime when conime dead by bogus ime's AV or
  664. // other problem
  665. // so this fail safe code is necessary to protect consrv.
  666. if (LastConsole == 0) {
  667. LastConsole = hConsole ;
  668. }
  669. for (i = 1; i < NumberOfConsoleTable; i++) {
  670. FocusedConsole = ConsoleTable[i];
  671. if (FocusedConsole != NULL)
  672. {
  673. if ((FocusedConsole->hConsole == hConsole)&&
  674. (!FocusedConsole->LateRemove)) {
  675. UnlockConsoleTable();
  676. return FocusedConsole;
  677. }
  678. }
  679. }
  680. UnlockConsoleTable();
  681. return NULL;
  682. }
  683. BOOL
  684. RemoveConsole(
  685. HWND hwnd,
  686. HANDLE hConsole
  687. )
  688. {
  689. PCONSOLE_TABLE ConTbl;
  690. BOOL ret;
  691. LockConsoleTable();
  692. ConTbl = SearchConsole(hConsole);
  693. if (ConTbl == NULL)
  694. {
  695. UnlockConsoleTable();
  696. return FALSE;
  697. }
  698. ret = RemoveConsoleWorker(hwnd, ConTbl);
  699. UnlockConsoleTable();
  700. return ret;
  701. }
  702. BOOL
  703. RemoveConsoleWorker(
  704. HWND hwnd,
  705. PCONSOLE_TABLE ConTbl
  706. )
  707. {
  708. DWORD j;
  709. if (ConTbl->Enable) {
  710. ConTbl->hConsole = NULL;
  711. ConTbl->ScreenBufferSize.X = 0;
  712. ConTbl->ConsoleCP = 0;
  713. ConTbl->ConsoleOutputCP = 0;
  714. ConTbl->hklActive = 0;
  715. ImmDestroyContext(ConTbl->hIMC_Original);
  716. if (ConTbl->lpCompStrMem != NULL){
  717. LocalFree(ConTbl->lpCompStrMem);
  718. }
  719. for (j = 0; j < MAX_LISTCAND; j++){
  720. if (ConTbl->lpCandListMem[j] != NULL) {
  721. LocalFree(ConTbl->lpCandListMem[j]);
  722. }
  723. }
  724. if (ConTbl->CandSep != NULL) {
  725. LocalFree(ConTbl->CandSep);
  726. }
  727. if (ConTbl->lphklList != NULL) {
  728. LocalFree(ConTbl->lphklList) ;
  729. }
  730. ConTbl->Enable = FALSE;
  731. ConTbl->LateRemove = FALSE;
  732. }
  733. else
  734. ConTbl->LateRemove = TRUE;
  735. #ifdef DEBUG_MODE
  736. InvalidateRect(hwnd,NULL,TRUE);
  737. #endif
  738. return TRUE;
  739. }
  740. BOOL
  741. InsertNewConsole(
  742. HWND hWnd,
  743. HANDLE hConsole,
  744. HWND hWndConsole
  745. )
  746. {
  747. // conime receive ime message from console before 1st console registered.
  748. // this will happen after restart conime when conime dead by bogus ime's AV or
  749. // other problem
  750. // so this fail safe code is necessary to protect consrv.
  751. if (SearchConsole(hConsole) != NULL) {
  752. return TRUE;
  753. }
  754. LockConsoleTable();
  755. if (!InsertConsole(hWnd, hConsole, hWndConsole)) {
  756. UnlockConsoleTable();
  757. return FALSE;
  758. }
  759. #ifdef DEBUG_MODE
  760. DisplayInformation(hWnd, hConsole);
  761. #endif
  762. ImeUISetOpenStatus( hWndConsole );
  763. UnlockConsoleTable();
  764. return TRUE;
  765. }
  766. BOOL
  767. ConsoleSetFocus(
  768. HWND hWnd,
  769. HANDLE hConsole,
  770. HKL hKL
  771. )
  772. {
  773. PCONSOLE_TABLE ConTbl;
  774. HKL OldhKL;
  775. ConTbl = SearchConsole(hConsole);
  776. if (ConTbl == NULL) {
  777. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  778. return FALSE;
  779. }
  780. if ( gfDoNotKillFocus ){
  781. gfDoNotKillFocus = FALSE;
  782. }
  783. OldhKL = ConTbl->hklActive ;
  784. ConTbl->hklActive = hKL;
  785. ActivateKeyboardLayout(ConTbl->hklActive, 0);
  786. ImmAssociateContext(hWnd, ConTbl->hIMC_Current);
  787. if (OldhKL == 0) {
  788. GetIMEName( ConTbl );
  789. ConTbl->ImmGetProperty = ImmGetProperty(ConTbl->hklActive , IGP_PROPERTY);
  790. }
  791. //v-hirshi Jun.13.1996 #if defined(LATER_DBCS) // kazum
  792. ImmSetActiveContextConsoleIME(hWnd, TRUE);
  793. //v-hirshi Jun.13.1996 #endif
  794. LastConsole = hConsole;
  795. #ifdef DEBUG_MODE
  796. DisplayInformation(hWnd, hConsole);
  797. #endif
  798. ImeUISetOpenStatus( hWnd );
  799. if (ConTbl->lpCompStrMem != NULL)
  800. ReDisplayCompositionStr( hWnd );
  801. return TRUE;
  802. }
  803. BOOL
  804. ConsoleKillFocus(
  805. HWND hWnd,
  806. HANDLE hConsole
  807. )
  808. {
  809. PCONSOLE_TABLE ConTbl;
  810. ConTbl = SearchConsole(hConsole);
  811. if (ConTbl == NULL) {
  812. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  813. return FALSE;
  814. }
  815. if ( gfDoNotKillFocus ){
  816. gfDoNotKillFocus = FALSE;
  817. }
  818. else{
  819. //v-hirshi Jun.13.1996 #if defined(LATER_DBCS) // kazum
  820. ImmSetActiveContextConsoleIME(hWnd, FALSE);
  821. //v-hirshi Jun.13.1996 #endif
  822. ImmAssociateContext(hWnd, ghDefaultIMC);
  823. }
  824. #ifdef DEBUG_MODE
  825. DisplayInformation(hWnd, hConsole);
  826. #endif
  827. return TRUE;
  828. }
  829. BOOL
  830. ConsoleScreenBufferSize(
  831. HWND hWnd,
  832. HANDLE hConsole,
  833. COORD ScreenBufferSize
  834. )
  835. {
  836. PCONSOLE_TABLE ConTbl;
  837. ConTbl = SearchConsole(hConsole);
  838. if (ConTbl == NULL) {
  839. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  840. return FALSE;
  841. }
  842. ConTbl->ScreenBufferSize = ScreenBufferSize;
  843. return TRUE;
  844. }
  845. BOOL
  846. ConImeInputLangchangeRequest(
  847. HWND hWnd,
  848. HANDLE hConsole,
  849. HKL hkl,
  850. int Direction
  851. )
  852. {
  853. PCONSOLE_TABLE ConTbl;
  854. int nLayouts;
  855. LPHKL lphkl;
  856. DWORD RequiredLID = 0;
  857. int StartPos;
  858. int CurrentHklPos;
  859. int i;
  860. ConTbl = SearchConsole(hConsole);
  861. if (ConTbl == NULL) {
  862. DBGPRINT(("CONIME: cannot find registered Console\n"));
  863. return FALSE;
  864. }
  865. switch (ConTbl->ConsoleOutputCP) {
  866. case JAPAN_CODEPAGE:
  867. RequiredLID = LANG_ID_JAPAN;
  868. break;
  869. case PRC_CODEPAGE:
  870. RequiredLID = LANG_ID_PRC;
  871. break;
  872. case KOREA_CODEPAGE:
  873. RequiredLID = LANG_ID_KOREA;
  874. break;
  875. case TAIWAN_CODEPAGE:
  876. RequiredLID = LANG_ID_TAIWAN;
  877. break;
  878. default:
  879. break;
  880. }
  881. if ( !IS_IME_KBDLAYOUT(hkl) ||
  882. ( HKL_TO_LANGID(hkl) == RequiredLID)) {
  883. return TRUE;
  884. }
  885. if (Direction == CONIME_DIRECT) {
  886. return FALSE;
  887. }
  888. nLayouts = GetKeyboardLayoutList(0, NULL);
  889. if (nLayouts == 0) {
  890. return FALSE;
  891. }
  892. lphkl = LocalAlloc(LPTR, nLayouts * sizeof(HKL));
  893. if (lphkl == NULL) {
  894. return FALSE;
  895. }
  896. GetKeyboardLayoutList(nLayouts, lphkl);
  897. for (CurrentHklPos = 0; CurrentHklPos < nLayouts; CurrentHklPos++) {
  898. if (ConTbl->hklActive == lphkl[CurrentHklPos] ) {
  899. break;
  900. }
  901. }
  902. if (CurrentHklPos >= nLayouts) {
  903. LocalFree(lphkl);
  904. return FALSE;
  905. }
  906. StartPos = CurrentHklPos;
  907. for (i = 0; i < nLayouts; i++) {
  908. StartPos+=Direction;
  909. if (StartPos < 0) {
  910. StartPos = nLayouts-1;
  911. }
  912. else if (StartPos >= nLayouts) {
  913. StartPos = 0;
  914. }
  915. if ((( HandleToUlong(lphkl[StartPos]) & 0xf0000000) == 0x00000000) ||
  916. (( HandleToUlong(lphkl[StartPos]) & 0x0000ffff) == RequiredLID)) {
  917. PostMessage( ConTbl->hWndCon,
  918. CM_CONIME_KL_ACTIVATE,
  919. HandleToUlong(lphkl[StartPos]),
  920. 0);
  921. LocalFree(lphkl);
  922. return FALSE;
  923. }
  924. }
  925. LocalFree(lphkl);
  926. return FALSE;
  927. }
  928. BOOL
  929. ConImeInputLangchange(
  930. HWND hWnd,
  931. HANDLE hConsole,
  932. HKL hkl
  933. )
  934. {
  935. PCONSOLE_TABLE ConTbl;
  936. LPCONIME_UIMODEINFO lpModeInfo;
  937. COPYDATASTRUCT CopyData;
  938. INT counter ;
  939. LPHKL_TABLE lphklListNew ;
  940. ConTbl = SearchConsole(hConsole);
  941. if (ConTbl == NULL) {
  942. // cannot find specified console.
  943. // It might be last console lost focus.
  944. // try Last Console.
  945. ConTbl = SearchConsole(LastConsole);
  946. if (ConTbl == NULL) {
  947. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  948. return FALSE;
  949. }
  950. }
  951. if (ConTbl->lphklList == NULL) {
  952. return FALSE;
  953. }
  954. if (IS_IME_KBDLAYOUT(ConTbl->hklActive)) {
  955. for (counter = 0 ; counter < ConTbl->hklListMax ;counter ++)
  956. {
  957. if (ConTbl->lphklList[counter].hkl == 0 || ConTbl->lphklList[counter].hkl == ConTbl->hklActive) {
  958. break;
  959. }
  960. }
  961. if (counter >= ConTbl->hklListMax)
  962. {
  963. ASSERT(counter == ConTbl->hklListMax);
  964. // reallocation
  965. lphklListNew = LocalAlloc(LPTR, sizeof(HKL_TABLE) * (ConTbl->hklListMax + HKL_TABLE_INCREMENT) ) ;
  966. if (lphklListNew != NULL)
  967. {
  968. CopyMemory(lphklListNew , ConTbl->lphklList , sizeof(HKL_TABLE) * ConTbl->hklListMax) ;
  969. ConTbl->hklListMax += HKL_TABLE_INCREMENT ;
  970. LocalFree(ConTbl->lphklList);
  971. ConTbl->lphklList = lphklListNew;
  972. }
  973. else {
  974. return FALSE ;
  975. }
  976. }
  977. ASSERT(ConTbl->lphklList != NULL);
  978. ConTbl->lphklList[counter].hkl = ConTbl->hklActive;
  979. ConTbl->lphklList[counter].dwConversion = ConTbl->dwConversion | (ConTbl->fOpen ? IME_CMODE_OPEN : 0) ;
  980. }
  981. ActivateKeyboardLayout(hkl, 0);
  982. ConTbl->hklActive = hkl;
  983. GetIMEName( ConTbl );
  984. ImeUIOpenStatusWindow(hWnd);
  985. ConTbl->ImmGetProperty = ImmGetProperty(ConTbl->hklActive , IGP_PROPERTY);
  986. lpModeInfo = (LPCONIME_UIMODEINFO)LocalAlloc( LPTR, sizeof(CONIME_UIMODEINFO) ) ;
  987. if ( lpModeInfo == NULL) {
  988. return FALSE;
  989. }
  990. CopyData.dwData = CI_CONIMEMODEINFO ;
  991. CopyData.cbData = sizeof(CONIME_UIMODEINFO) ;
  992. CopyData.lpData = lpModeInfo ;
  993. if (IS_IME_KBDLAYOUT(hkl)) {
  994. for (counter=0; counter < ConTbl->hklListMax ; counter++)
  995. {
  996. if (ConTbl->lphklList[counter].hkl == hkl)
  997. {
  998. SetNLSMode(hWnd, hConsole,ConTbl->lphklList[counter].dwConversion ) ;
  999. ImeUIOpenStatusWindow(hWnd) ;
  1000. if (ImeUIMakeInfoString(ConTbl,
  1001. lpModeInfo))
  1002. {
  1003. ConsoleImeSendMessage( ConTbl->hWndCon,
  1004. (WPARAM)hWnd,
  1005. (LPARAM)&CopyData
  1006. ) ;
  1007. }
  1008. }
  1009. }
  1010. }
  1011. else
  1012. {
  1013. SetNLSMode(hWnd, hConsole,ConTbl->dwConversion & ~IME_CMODE_OPEN ) ;
  1014. lpModeInfo->ModeStringLen = 0 ;
  1015. lpModeInfo->Position = VIEW_RIGHT ;
  1016. ConsoleImeSendMessage( ConTbl->hWndCon,
  1017. (WPARAM)hWnd,
  1018. (LPARAM)&CopyData
  1019. ) ;
  1020. }
  1021. LocalFree( lpModeInfo );
  1022. return TRUE;
  1023. }
  1024. BOOL
  1025. InputLangchange(
  1026. HWND hWnd,
  1027. DWORD CharSet,
  1028. HKL hkl
  1029. )
  1030. {
  1031. PCONSOLE_TABLE ConTbl;
  1032. ConTbl = SearchConsole(LastConsole);
  1033. if (ConTbl == NULL) {
  1034. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  1035. return FALSE;
  1036. }
  1037. ConTbl->hklActive = hkl;
  1038. ActivateKeyboardLayout(ConTbl->hklActive, 0);
  1039. GetIMEName( ConTbl );
  1040. ImeUIOpenStatusWindow(hWnd);
  1041. return TRUE;
  1042. }
  1043. /*
  1044. * Console IME message pump.
  1045. */
  1046. LRESULT
  1047. ConsoleImeSendMessage(
  1048. HWND hWndConsoleIME,
  1049. WPARAM wParam,
  1050. LPARAM lParam
  1051. )
  1052. {
  1053. LRESULT lResult;
  1054. LRESULT fNoTimeout;
  1055. if (hWndConsoleIME == NULL)
  1056. {
  1057. return FALSE;
  1058. }
  1059. fNoTimeout = SendMessageTimeout(hWndConsoleIME,
  1060. WM_COPYDATA,
  1061. wParam,
  1062. lParam,
  1063. SMTO_ABORTIFHUNG | SMTO_NORMAL,
  1064. CONIME_SENDMSG_TIMEOUT,
  1065. &lResult);
  1066. if (fNoTimeout)
  1067. {
  1068. return TRUE;
  1069. }
  1070. /*
  1071. * ConsoleImeMessagePump give up SendMessage to conime.
  1072. * CONIME is hung up.
  1073. * probably, consrv also hung up.
  1074. */
  1075. KdPrint(("ConsoleImeSendMessage: CONIME_SENDMSG_COUNT is hung up\n"));
  1076. return FALSE;
  1077. }
  1078. #ifdef DEBUG_MODE
  1079. int cxMetrics;
  1080. int cyMetrics;
  1081. int cxOverTypeCaret;
  1082. int xPos;
  1083. int xPosLast;
  1084. int CaretWidth; // insert/overtype mode caret width
  1085. WCHAR ConvertLine[CVMAX];
  1086. unsigned char ConvertLineAtr[CVMAX];
  1087. WCHAR DispTitle[] = TEXT(" Console Handle");
  1088. DWORD CompColor[ 8 ] = { RGB( 0, 0, 0 ), // ATTR_INPUT
  1089. RGB( 0, 0, 255 ), // ATTR_TARGET_CONVERTED
  1090. RGB( 0, 255, 0 ), // ATTR_CONVERTED
  1091. RGB( 255, 0, 0 ), // ATTR_TARGET_NOTCONVERTED
  1092. RGB( 255, 0, 255 ), // ATTR_INPUT_ERROR
  1093. RGB( 0, 255, 255 ), // ATTR_DEFAULT
  1094. RGB( 255, 255, 0 ), // ATTR_DEFAULT
  1095. RGB( 255, 255, 255 ) };// ATTR_DEFAULT
  1096. VOID
  1097. DisplayConvInformation(
  1098. HWND hWnd
  1099. )
  1100. {
  1101. RECT Rect;
  1102. HDC lhdc;
  1103. lhdc = GetDC(hWnd);
  1104. GetClientRect(hWnd, &Rect);
  1105. InvalidateRect(hWnd,NULL,FALSE);
  1106. UpdateWindow(hWnd);
  1107. ReleaseDC(hWnd, lhdc);
  1108. }
  1109. VOID
  1110. DisplayInformation(
  1111. HWND hWnd,
  1112. HANDLE hConsole
  1113. )
  1114. {
  1115. PCONSOLE_TABLE ConTbl;
  1116. RECT Rect;
  1117. HDC lhdc;
  1118. ConTbl = SearchConsole(hConsole);
  1119. if (ConTbl == NULL) {
  1120. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  1121. return;
  1122. }
  1123. lhdc = GetDC(hWnd);
  1124. GetClientRect(hWnd, &Rect);
  1125. wsprintf(ConTbl->DispBuf, TEXT("%08x"), (ULONG)hConsole);
  1126. InvalidateRect(hWnd,NULL,FALSE);
  1127. UpdateWindow(hWnd);
  1128. ReleaseDC(hWnd, lhdc);
  1129. }
  1130. VOID
  1131. RealReDraw(
  1132. HDC r_hdc
  1133. )
  1134. {
  1135. PCONSOLE_TABLE ConTbl;
  1136. INT ix, iy, i, rx, sx;
  1137. ULONG cnt;
  1138. int ColorIndex;
  1139. int PrevColorIndex;
  1140. DWORD dwColor;
  1141. iy = 0;
  1142. dwColor = GetTextColor( r_hdc );
  1143. ColorIndex = ( ((int)ConvertLineAtr[0]) < 0 ) ? 0 : (int)ConvertLineAtr[0];
  1144. ColorIndex = ( ColorIndex > 7 ) ? 0 : ColorIndex;
  1145. PrevColorIndex = ColorIndex;
  1146. SetTextColor( r_hdc, CompColor[ ColorIndex ] );
  1147. rx = 0;
  1148. sx = 0;
  1149. for (ix = 0; ix < MAXCOL; ) {
  1150. for (i = ix; i < MAXCOL; i++) {
  1151. if (PrevColorIndex != (int)ConvertLineAtr[i])
  1152. break;
  1153. rx += IsUnicodeFullWidth(ConvertLine[ix]) ? 2 : 1;
  1154. }
  1155. TextOut( r_hdc, sx * cxMetrics, iy, &ConvertLine[ix], i-ix );
  1156. sx = rx;
  1157. ColorIndex = ( ((int)ConvertLineAtr[i]) < 0 ) ? 0 : (int)ConvertLineAtr[i];
  1158. ColorIndex = ( ColorIndex > 7 ) ? 0 : ColorIndex;
  1159. PrevColorIndex = ColorIndex;
  1160. SetTextColor( r_hdc, CompColor[ ColorIndex ] );
  1161. ix = i;
  1162. }
  1163. ix = 0;
  1164. SetTextColor( r_hdc, dwColor );
  1165. iy += cyMetrics;
  1166. TextOut( r_hdc, ix, iy, DispTitle, lstrlenW(DispTitle));
  1167. iy += cyMetrics;
  1168. LockConsoleTable();
  1169. for (cnt = 1; cnt < NumberOfConsoleTable; cnt++, iy += cyMetrics){
  1170. ConTbl = ConsoleTable[cnt];
  1171. if (ConTbl != NULL)
  1172. {
  1173. if (ConTbl->hConsole)
  1174. {
  1175. TextOut( r_hdc, ix, iy, ConTbl->DispBuf, lstrlenW(ConTbl->DispBuf) );
  1176. }
  1177. }
  1178. }
  1179. UnlockConsoleTable();
  1180. return;
  1181. }
  1182. VOID
  1183. ReDraw(
  1184. HWND hWnd
  1185. )
  1186. {
  1187. HDC r_hdc;
  1188. RECT ClientRect;
  1189. GetClientRect(hWnd, &ClientRect);
  1190. r_hdc = GetDC(hWnd);
  1191. FillRect(r_hdc, &ClientRect, GetStockObject(WHITE_BRUSH));
  1192. RealReDraw(r_hdc);
  1193. ReleaseDC(hWnd, r_hdc);
  1194. return;
  1195. }
  1196. #endif