d256fa2d04e9b2a750158f6989f54b6e2c737000
[reactos.git] / reactos / subsys / system / usetup / console.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/console.c
23 * PURPOSE: Console support functions
24 * PROGRAMMER: Eric Kohl
25 */
26
27 /* INCLUDES ******************************************************************/
28
29 #include "precomp.h"
30 #include <ddk/ntddblue.h>
31
32 #include "usetup.h"
33 #include "console.h"
34
35 #define NDEBUG
36 #include <debug.h>
37
38
39 /* GLOBALS ******************************************************************/
40
41 static HANDLE StdInput = INVALID_HANDLE_VALUE;
42 static HANDLE StdOutput = INVALID_HANDLE_VALUE;
43
44 static SHORT xScreen = 0;
45 static SHORT yScreen = 0;
46
47
48 NTSTATUS
49 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo);
50
51
52 /* FUNCTIONS *****************************************************************/
53
54
55
56 NTSTATUS
57 AllocConsole(VOID)
58 {
59 OBJECT_ATTRIBUTES ObjectAttributes;
60 IO_STATUS_BLOCK IoStatusBlock;
61 UNICODE_STRING Name;
62 NTSTATUS Status;
63 CONSOLE_SCREEN_BUFFER_INFO csbi;
64
65 /* Open the screen */
66 RtlInitUnicodeString(&Name,
67 L"\\??\\BlueScreen");
68 InitializeObjectAttributes(&ObjectAttributes,
69 &Name,
70 0,
71 NULL,
72 NULL);
73 Status = NtOpenFile (&StdOutput,
74 FILE_ALL_ACCESS,
75 &ObjectAttributes,
76 &IoStatusBlock,
77 0,
78 FILE_SYNCHRONOUS_IO_ALERT);
79 if (!NT_SUCCESS(Status))
80 return(Status);
81
82 /* Open the keyboard */
83 RtlInitUnicodeString(&Name,
84 L"\\??\\Keyboard");
85 InitializeObjectAttributes(&ObjectAttributes,
86 &Name,
87 0,
88 NULL,
89 NULL);
90 Status = NtOpenFile (&StdInput,
91 FILE_ALL_ACCESS,
92 &ObjectAttributes,
93 &IoStatusBlock,
94 0,
95 FILE_SYNCHRONOUS_IO_ALERT);
96 if (!NT_SUCCESS(Status))
97 return(Status);
98
99 GetConsoleScreenBufferInfo(&csbi);
100
101 xScreen = csbi.dwSize.X;
102 yScreen = csbi.dwSize.Y;
103
104 return(Status);
105 }
106
107
108 VOID
109 FreeConsole(VOID)
110 {
111 DPRINT("FreeConsole() called\n");
112
113 if (StdInput != INVALID_HANDLE_VALUE)
114 NtClose(StdInput);
115
116 if (StdOutput != INVALID_HANDLE_VALUE)
117 NtClose(StdOutput);
118
119 DPRINT("FreeConsole() done\n");
120 }
121
122
123
124
125 NTSTATUS
126 WriteConsole(PCHAR Buffer,
127 ULONG NumberOfCharsToWrite,
128 PULONG NumberOfCharsWritten)
129 {
130 IO_STATUS_BLOCK IoStatusBlock;
131 NTSTATUS Status = STATUS_SUCCESS;
132
133 Status = NtWriteFile(StdOutput,
134 NULL,
135 NULL,
136 NULL,
137 &IoStatusBlock,
138 Buffer,
139 NumberOfCharsToWrite,
140 NULL,
141 NULL);
142
143 if (NT_SUCCESS(Status) && NumberOfCharsWritten != NULL)
144 {
145 *NumberOfCharsWritten = IoStatusBlock.Information;
146 }
147
148 return(Status);
149 }
150
151
152 #if 0
153 /*--------------------------------------------------------------
154 * ReadConsoleA
155 */
156 BOOL
157 STDCALL
158 ReadConsoleA(HANDLE hConsoleInput,
159 LPVOID lpBuffer,
160 DWORD nNumberOfCharsToRead,
161 LPDWORD lpNumberOfCharsRead,
162 LPVOID lpReserved)
163 {
164 KEY_EVENT_RECORD KeyEventRecord;
165 BOOL stat = TRUE;
166 PCHAR Buffer = (PCHAR)lpBuffer;
167 DWORD Result;
168 int i;
169
170 for (i=0; (stat && i<nNumberOfCharsToRead);)
171 {
172 stat = ReadFile(hConsoleInput,
173 &KeyEventRecord,
174 sizeof(KEY_EVENT_RECORD),
175 &Result,
176 NULL);
177 if (stat && KeyEventRecord.bKeyDown && KeyEventRecord.uChar.AsciiChar != 0)
178 {
179 Buffer[i] = KeyEventRecord.uChar.AsciiChar;
180 i++;
181 }
182 }
183 if (lpNumberOfCharsRead != NULL)
184 {
185 *lpNumberOfCharsRead = i;
186 }
187 return(stat);
188 }
189 #endif
190
191
192 NTSTATUS
193 ReadConsoleInput(PINPUT_RECORD Buffer)
194 {
195 IO_STATUS_BLOCK Iosb;
196 NTSTATUS Status;
197
198 Buffer->EventType = KEY_EVENT;
199 Status = NtReadFile(StdInput,
200 NULL,
201 NULL,
202 NULL,
203 &Iosb,
204 &Buffer->Event.KeyEvent,
205 sizeof(KEY_EVENT_RECORD),
206 NULL,
207 0);
208
209 return(Status);
210 }
211
212
213 NTSTATUS
214 ReadConsoleOutputCharacters(LPSTR lpCharacter,
215 ULONG nLength,
216 COORD dwReadCoord,
217 PULONG lpNumberOfCharsRead)
218 {
219 IO_STATUS_BLOCK IoStatusBlock;
220 OUTPUT_CHARACTER Buffer;
221 NTSTATUS Status;
222
223 Buffer.dwCoord = dwReadCoord;
224
225 Status = NtDeviceIoControlFile(StdOutput,
226 NULL,
227 NULL,
228 NULL,
229 &IoStatusBlock,
230 IOCTL_CONSOLE_READ_OUTPUT_CHARACTER,
231 &Buffer,
232 sizeof(OUTPUT_CHARACTER),
233 (PVOID)lpCharacter,
234 nLength);
235
236 if (NT_SUCCESS(Status) && lpNumberOfCharsRead != NULL)
237 {
238 *lpNumberOfCharsRead = Buffer.dwTransfered;
239 }
240
241 return(Status);
242 }
243
244
245 NTSTATUS
246 ReadConsoleOutputAttributes(PUSHORT lpAttribute,
247 ULONG nLength,
248 COORD dwReadCoord,
249 PULONG lpNumberOfAttrsRead)
250 {
251 IO_STATUS_BLOCK IoStatusBlock;
252 OUTPUT_ATTRIBUTE Buffer;
253 NTSTATUS Status;
254
255 Buffer.dwCoord = dwReadCoord;
256
257 Status = NtDeviceIoControlFile(StdOutput,
258 NULL,
259 NULL,
260 NULL,
261 &IoStatusBlock,
262 IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE,
263 &Buffer,
264 sizeof(OUTPUT_ATTRIBUTE),
265 (PVOID)lpAttribute,
266 nLength);
267
268 if (NT_SUCCESS(Status) && lpNumberOfAttrsRead != NULL)
269 {
270 *lpNumberOfAttrsRead = Buffer.dwTransfered;
271 }
272
273 return(Status);
274 }
275
276
277 NTSTATUS
278 WriteConsoleOutputCharacters(LPCSTR lpCharacter,
279 ULONG nLength,
280 COORD dwWriteCoord)
281 {
282 IO_STATUS_BLOCK IoStatusBlock;
283 PCHAR Buffer;
284 COORD *pCoord;
285 PCHAR pText;
286 NTSTATUS Status;
287
288 Buffer = RtlAllocateHeap(ProcessHeap,
289 0,
290 nLength + sizeof(COORD));
291 pCoord = (COORD *)Buffer;
292 pText = (PCHAR)(pCoord + 1);
293
294 *pCoord = dwWriteCoord;
295 memcpy(pText, lpCharacter, nLength);
296
297 Status = NtDeviceIoControlFile(StdOutput,
298 NULL,
299 NULL,
300 NULL,
301 &IoStatusBlock,
302 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
303 NULL,
304 0,
305 Buffer,
306 nLength + sizeof(COORD));
307
308 RtlFreeHeap(ProcessHeap,
309 0,
310 Buffer);
311
312 return(Status);
313 }
314
315
316 NTSTATUS
317 WriteConsoleOutputCharactersW(LPCWSTR lpCharacter,
318 ULONG nLength,
319 COORD dwWriteCoord)
320 {
321 IO_STATUS_BLOCK IoStatusBlock;
322 PCHAR Buffer;
323 COORD *pCoord;
324 PCHAR pText;
325 NTSTATUS Status;
326 ULONG i;
327
328 Buffer = RtlAllocateHeap(ProcessHeap,
329 0,
330 nLength + sizeof(COORD));
331 pCoord = (COORD *)Buffer;
332 pText = (PCHAR)(pCoord + 1);
333
334 *pCoord = dwWriteCoord;
335
336 /* FIXME: use real unicode->oem conversion */
337 for (i = 0; i < nLength; i++)
338 pText[i] = (CHAR)lpCharacter[i];
339 pText[i] = 0;
340
341 Status = NtDeviceIoControlFile(StdOutput,
342 NULL,
343 NULL,
344 NULL,
345 &IoStatusBlock,
346 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
347 NULL,
348 0,
349 Buffer,
350 nLength + sizeof(COORD));
351
352 RtlFreeHeap(ProcessHeap,
353 0,
354 Buffer);
355
356 return(Status);
357 }
358
359
360 NTSTATUS
361 WriteConsoleOutputAttributes(CONST USHORT *lpAttribute,
362 ULONG nLength,
363 COORD dwWriteCoord,
364 PULONG lpNumberOfAttrsWritten)
365 {
366 IO_STATUS_BLOCK IoStatusBlock;
367 PUSHORT Buffer;
368 COORD *pCoord;
369 PUSHORT pAttrib;
370 NTSTATUS Status;
371
372 Buffer = RtlAllocateHeap(ProcessHeap,
373 0,
374 nLength * sizeof(USHORT) + sizeof(COORD));
375 pCoord = (COORD *)Buffer;
376 pAttrib = (PUSHORT)(pCoord + 1);
377
378 *pCoord = dwWriteCoord;
379 memcpy(pAttrib, lpAttribute, nLength * sizeof(USHORT));
380
381 Status = NtDeviceIoControlFile(StdOutput,
382 NULL,
383 NULL,
384 NULL,
385 &IoStatusBlock,
386 IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE,
387 NULL,
388 0,
389 Buffer,
390 nLength * sizeof(USHORT) + sizeof(COORD));
391
392 RtlFreeHeap(ProcessHeap,
393 0,
394 Buffer);
395
396 return(Status);
397 }
398
399
400 NTSTATUS
401 FillConsoleOutputAttribute(USHORT wAttribute,
402 ULONG nLength,
403 COORD dwWriteCoord,
404 PULONG lpNumberOfAttrsWritten)
405 {
406 IO_STATUS_BLOCK IoStatusBlock;
407 OUTPUT_ATTRIBUTE Buffer;
408 NTSTATUS Status;
409
410 Buffer.wAttribute = wAttribute;
411 Buffer.nLength = nLength;
412 Buffer.dwCoord = dwWriteCoord;
413
414 Status = NtDeviceIoControlFile(StdOutput,
415 NULL,
416 NULL,
417 NULL,
418 &IoStatusBlock,
419 IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
420 &Buffer,
421 sizeof(OUTPUT_ATTRIBUTE),
422 &Buffer,
423 sizeof(OUTPUT_ATTRIBUTE));
424
425 if (NT_SUCCESS(Status))
426 {
427 *lpNumberOfAttrsWritten = Buffer.dwTransfered;
428 }
429
430 return(Status);
431 }
432
433
434 NTSTATUS
435 FillConsoleOutputCharacter(CHAR Character,
436 ULONG Length,
437 COORD WriteCoord,
438 PULONG NumberOfCharsWritten)
439 {
440 IO_STATUS_BLOCK IoStatusBlock;
441 OUTPUT_CHARACTER Buffer;
442 NTSTATUS Status;
443
444 Buffer.cCharacter = Character;
445 Buffer.nLength = Length;
446 Buffer.dwCoord = WriteCoord;
447
448 Status = NtDeviceIoControlFile(StdOutput,
449 NULL,
450 NULL,
451 NULL,
452 &IoStatusBlock,
453 IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
454 &Buffer,
455 sizeof(OUTPUT_CHARACTER),
456 &Buffer,
457 sizeof(OUTPUT_CHARACTER));
458
459 if (NT_SUCCESS(Status))
460 {
461 *NumberOfCharsWritten = Buffer.dwTransfered;
462 }
463
464 return(Status);
465 }
466
467
468 #if 0
469 /*--------------------------------------------------------------
470 * GetConsoleMode
471 */
472 WINBASEAPI
473 BOOL
474 WINAPI
475 GetConsoleMode(
476 HANDLE hConsoleHandle,
477 LPDWORD lpMode
478 )
479 {
480 CONSOLE_MODE Buffer;
481 DWORD dwBytesReturned;
482
483 if (DeviceIoControl (hConsoleHandle,
484 IOCTL_CONSOLE_GET_MODE,
485 NULL,
486 0,
487 &Buffer,
488 sizeof(CONSOLE_MODE),
489 &dwBytesReturned,
490 NULL))
491 {
492 *lpMode = Buffer.dwMode;
493 SetLastError (ERROR_SUCCESS);
494 return TRUE;
495 }
496
497 SetLastError(0); /* FIXME: What error code? */
498 return FALSE;
499 }
500
501
502 /*--------------------------------------------------------------
503 * GetConsoleCursorInfo
504 */
505 WINBASEAPI
506 BOOL
507 WINAPI
508 GetConsoleCursorInfo(
509 HANDLE hConsoleOutput,
510 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
511 )
512 {
513 DWORD dwBytesReturned;
514
515 if (DeviceIoControl (hConsoleOutput,
516 IOCTL_CONSOLE_GET_CURSOR_INFO,
517 NULL,
518 0,
519 lpConsoleCursorInfo,
520 sizeof(CONSOLE_CURSOR_INFO),
521 &dwBytesReturned,
522 NULL))
523 return TRUE;
524
525 return FALSE;
526 }
527
528
529 NTSTATUS
530 SetConsoleMode(HANDLE hConsoleHandle,
531 ULONG dwMode)
532 {
533 IO_STATUS_BLOCK IoStatusBlock;
534 NTSTATUS Status;
535 CONSOLE_MODE Buffer;
536
537 Buffer.dwMode = dwMode;
538
539 Status = NtDeviceIoControlFile(hConsoleHandle,
540 NULL,
541 NULL,
542 NULL,
543 &IoStatusBlock,
544 IOCTL_CONSOLE_SET_MODE,
545 &Buffer,
546 sizeof(CONSOLE_MODE),
547 NULL,
548 0);
549
550 return(Status);
551 }
552 #endif
553
554
555 NTSTATUS
556 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo)
557 {
558 IO_STATUS_BLOCK IoStatusBlock;
559 NTSTATUS Status;
560
561 Status = NtDeviceIoControlFile(StdOutput,
562 NULL,
563 NULL,
564 NULL,
565 &IoStatusBlock,
566 IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
567 NULL,
568 0,
569 ConsoleScreenBufferInfo,
570 sizeof(CONSOLE_SCREEN_BUFFER_INFO));
571
572 return(Status);
573 }
574
575
576 NTSTATUS
577 SetConsoleCursorInfo(PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
578 {
579 IO_STATUS_BLOCK IoStatusBlock;
580 NTSTATUS Status;
581
582 Status = NtDeviceIoControlFile(StdOutput,
583 NULL,
584 NULL,
585 NULL,
586 &IoStatusBlock,
587 IOCTL_CONSOLE_SET_CURSOR_INFO,
588 (PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
589 sizeof(CONSOLE_CURSOR_INFO),
590 NULL,
591 0);
592
593 return(Status);
594 }
595
596
597 NTSTATUS
598 SetConsoleCursorPosition(COORD dwCursorPosition)
599 {
600 CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
601 IO_STATUS_BLOCK IoStatusBlock;
602 NTSTATUS Status;
603
604 Status = GetConsoleScreenBufferInfo(&ConsoleScreenBufferInfo);
605 if (!NT_SUCCESS(Status))
606 return(Status);
607
608 ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
609 ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
610
611 Status = NtDeviceIoControlFile(StdOutput,
612 NULL,
613 NULL,
614 NULL,
615 &IoStatusBlock,
616 IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
617 &ConsoleScreenBufferInfo,
618 sizeof(CONSOLE_SCREEN_BUFFER_INFO),
619 NULL,
620 0);
621
622 return(Status);
623 }
624
625
626 NTSTATUS
627 SetConsoleTextAttribute(USHORT wAttributes)
628 {
629 IO_STATUS_BLOCK IoStatusBlock;
630 NTSTATUS Status;
631
632 Status = NtDeviceIoControlFile(StdOutput,
633 NULL,
634 NULL,
635 NULL,
636 &IoStatusBlock,
637 IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
638 &wAttributes,
639 sizeof(USHORT),
640 NULL,
641 0);
642
643 return(Status);
644 }
645
646
647
648
649 VOID
650 ConInKey(PINPUT_RECORD Buffer)
651 {
652
653 while (TRUE)
654 {
655 ReadConsoleInput(Buffer);
656
657 if ((Buffer->EventType == KEY_EVENT) &&
658 (Buffer->Event.KeyEvent.bKeyDown == TRUE))
659 break;
660 }
661 }
662
663
664 VOID
665 ConOutChar(CHAR c)
666 {
667 ULONG Written;
668
669 WriteConsole(&c,
670 1,
671 &Written);
672 }
673
674
675 VOID
676 ConOutPuts(LPSTR szText)
677 {
678 ULONG Written;
679
680 WriteConsole(szText,
681 strlen(szText),
682 &Written);
683 WriteConsole("\n",
684 1,
685 &Written);
686 }
687
688
689 VOID
690 ConOutPrintf(LPSTR szFormat, ...)
691 {
692 CHAR szOut[256];
693 DWORD dwWritten;
694 va_list arg_ptr;
695
696 va_start(arg_ptr, szFormat);
697 vsprintf(szOut, szFormat, arg_ptr);
698 va_end(arg_ptr);
699
700 WriteConsole(szOut,
701 strlen(szOut),
702 &dwWritten);
703 }
704
705
706
707
708
709 SHORT
710 GetCursorX(VOID)
711 {
712 CONSOLE_SCREEN_BUFFER_INFO csbi;
713
714 GetConsoleScreenBufferInfo(&csbi);
715
716 return(csbi.dwCursorPosition.X);
717 }
718
719
720 SHORT
721 GetCursorY(VOID)
722 {
723 CONSOLE_SCREEN_BUFFER_INFO csbi;
724
725 GetConsoleScreenBufferInfo(&csbi);
726
727 return(csbi.dwCursorPosition.Y);
728 }
729
730
731 VOID
732 GetScreenSize(SHORT *maxx,
733 SHORT *maxy)
734 {
735 CONSOLE_SCREEN_BUFFER_INFO csbi;
736
737 GetConsoleScreenBufferInfo(&csbi);
738
739 if (maxx)
740 *maxx = csbi.dwSize.X;
741
742 if (maxy)
743 *maxy = csbi.dwSize.Y;
744 }
745
746
747 VOID
748 SetCursorType(BOOL bInsert,
749 BOOL bVisible)
750 {
751 CONSOLE_CURSOR_INFO cci;
752
753 cci.dwSize = bInsert ? 10 : 99;
754 cci.bVisible = bVisible;
755
756 SetConsoleCursorInfo(&cci);
757 }
758
759
760 VOID
761 SetCursorXY(SHORT x,
762 SHORT y)
763 {
764 COORD coPos;
765
766 coPos.X = x;
767 coPos.Y = y;
768 SetConsoleCursorPosition(coPos);
769 }
770
771
772 VOID
773 ClearScreen(VOID)
774 {
775 COORD coPos;
776 ULONG Written;
777
778 coPos.X = 0;
779 coPos.Y = 0;
780
781 FillConsoleOutputAttribute(0x17,
782 xScreen * yScreen,
783 coPos,
784 &Written);
785
786 FillConsoleOutputCharacter(' ',
787 xScreen * yScreen,
788 coPos,
789 &Written);
790 }
791
792
793 VOID
794 SetStatusText(char* fmt, ...)
795 {
796 char Buffer[128];
797 va_list ap;
798 COORD coPos;
799 ULONG Written;
800
801 va_start(ap, fmt);
802 vsprintf(Buffer, fmt, ap);
803 va_end(ap);
804
805 coPos.X = 0;
806 coPos.Y = yScreen - 1;
807
808 FillConsoleOutputAttribute(0x70,
809 xScreen,
810 coPos,
811 &Written);
812
813 FillConsoleOutputCharacter(' ',
814 xScreen,
815 coPos,
816 &Written);
817
818 WriteConsoleOutputCharacters(Buffer,
819 strlen(Buffer),
820 coPos);
821 }
822
823
824 VOID
825 InvertTextXY(SHORT x, SHORT y, SHORT col, SHORT row)
826 {
827 COORD coPos;
828 ULONG Written;
829
830 for (coPos.Y = y; coPos.Y < y + row; coPos.Y++)
831 {
832 coPos.X = x;
833
834 FillConsoleOutputAttribute(0x71,
835 col,
836 coPos,
837 &Written);
838 }
839 }
840
841
842 VOID
843 NormalTextXY(SHORT x, SHORT y, SHORT col, SHORT row)
844 {
845 COORD coPos;
846 ULONG Written;
847
848 for (coPos.Y = y; coPos.Y < y + row; coPos.Y++)
849 {
850 coPos.X = x;
851
852 FillConsoleOutputAttribute(0x17,
853 col,
854 coPos,
855 &Written);
856 }
857 }
858
859
860 VOID
861 SetTextXY(SHORT x, SHORT y, PCHAR Text)
862 {
863 COORD coPos;
864
865 coPos.X = x;
866 coPos.Y = y;
867
868 WriteConsoleOutputCharacters(Text,
869 strlen(Text),
870 coPos);
871 }
872
873
874 VOID
875 SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text)
876 {
877 COORD coPos;
878 ULONG Length;
879 ULONG Written;
880
881 coPos.X = x;
882 coPos.Y = y;
883
884 Length = wcslen(Text);
885 if (Length > len - 1)
886 {
887 Length = len - 1;
888 }
889
890 FillConsoleOutputAttribute(0x70,
891 len,
892 coPos,
893 &Written);
894
895 WriteConsoleOutputCharactersW(Text,
896 Length,
897 coPos);
898
899 coPos.X += Length;
900 FillConsoleOutputCharacter('_',
901 1,
902 coPos,
903 &Written);
904
905 if (len > Length + 1)
906 {
907 coPos.X++;
908 FillConsoleOutputCharacter(' ',
909 len - Length - 1,
910 coPos,
911 &Written);
912 }
913 }
914
915
916 VOID
917 SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text)
918 {
919 COORD coPos;
920 ULONG Length;
921 ULONG Written;
922
923 coPos.X = x;
924 coPos.Y = y;
925
926 Length = strlen(Text);
927
928 WriteConsoleOutputCharacters(Text,
929 Length,
930 coPos);
931
932 coPos.Y++;
933 FillConsoleOutputCharacter(0xCD,
934 Length,
935 coPos,
936 &Written);
937 }
938
939
940 VOID
941 SetInvertedTextXY(SHORT x, SHORT y, PCHAR Text)
942 {
943 COORD coPos;
944 ULONG Length;
945 ULONG Written;
946
947 coPos.X = x;
948 coPos.Y = y;
949
950 Length = strlen(Text);
951
952 FillConsoleOutputAttribute(0x71,
953 Length,
954 coPos,
955 &Written);
956
957 WriteConsoleOutputCharacters(Text,
958 Length,
959 coPos);
960 }
961
962
963 VOID
964 SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text)
965 {
966 COORD coPos;
967 ULONG Length;
968 ULONG Written;
969
970 coPos.X = x;
971 coPos.Y = y;
972
973 Length = strlen(Text);
974
975 FillConsoleOutputAttribute(0x1F,
976 Length,
977 coPos,
978 &Written);
979
980 WriteConsoleOutputCharacters(Text,
981 Length,
982 coPos);
983 }
984
985
986 VOID
987 PrintTextXY(SHORT x, SHORT y, char* fmt, ...)
988 {
989 char buffer[512];
990 va_list ap;
991 COORD coPos;
992
993 va_start(ap, fmt);
994 vsprintf(buffer, fmt, ap);
995 va_end(ap);
996
997 coPos.X = x;
998 coPos.Y = y;
999
1000 WriteConsoleOutputCharacters(buffer,
1001 strlen(buffer),
1002 coPos);
1003 }
1004
1005
1006 VOID
1007 PrintTextXYN(SHORT x, SHORT y, SHORT len, char* fmt, ...)
1008 {
1009 char buffer[512];
1010 va_list ap;
1011 COORD coPos;
1012 ULONG Length;
1013 ULONG Written;
1014
1015 va_start(ap, fmt);
1016 vsprintf(buffer, fmt, ap);
1017 va_end(ap);
1018
1019 coPos.X = x;
1020 coPos.Y = y;
1021
1022 Length = strlen(buffer);
1023 if (Length > len - 1)
1024 {
1025 Length = len - 1;
1026 }
1027
1028 WriteConsoleOutputCharacters(buffer,
1029 Length,
1030 coPos);
1031
1032 coPos.X += Length;
1033
1034 if (len > Length)
1035 {
1036 FillConsoleOutputCharacter(' ',
1037 len - Length,
1038 coPos,
1039 &Written);
1040 }
1041 }
1042
1043
1044 /* EOF */