📄 console.c
字号:
/* * Unit tests for console API * * Copyright (c) 2003 Eric Pouech * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "wine/test.h"#include <windows.h>#include <stdio.h>/* DEFAULT_ATTRIB is used for all initial filling of the console. * all modifications are made with TEST_ATTRIB so that we could check * what has to be modified or not */#define TEST_ATTRIB (BACKGROUND_BLUE | FOREGROUND_GREEN)#define DEFAULT_ATTRIB (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED)/* when filling the screen with non-blank chars, this macro defines * what character should be at position 'c' */#define CONTENT(c) ('A' + (((c).Y * 17 + (c).X) % 23))#define okCURSOR(hCon, c) do { \ CONSOLE_SCREEN_BUFFER_INFO __sbi; \ BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \ __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \ ok(expect, "Expected cursor at (%d,%d), got (%d,%d)", \ (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \} while (0)#define okCHAR(hCon, c, ch, attr) do { \ char __ch; WORD __attr; DWORD __len; BOOL expect; \ expect = ReadConsoleOutputCharacter((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \ ok(expect, "At (%d,%d): expecting char '%c'/%02x got '%c'/%02x", (c).X, (c).Y, (ch), (ch), __ch, __ch); \ expect = ReadConsoleOutputAttribute((hCon), &__attr, 1, (c), &__len) == 1 && __len == 1 && __attr == (attr); \ ok(expect, "At (%d,%d): expecting attr %04x got %04x", (c).X, (c).Y, (attr), __attr); \} while (0)/* FIXME: this could be optimized on a speed point of view */static void resetContent(HANDLE hCon, COORD sbSize, BOOL content){ COORD c; WORD attr = DEFAULT_ATTRIB; char ch; DWORD len; for (c.X = 0; c.X < sbSize.X; c.X++) { for (c.Y = 0; c.Y < sbSize.Y; c.Y++) { ch = (content) ? CONTENT(c) : ' '; WriteConsoleOutputAttribute(hCon, &attr, 1, c, &len); WriteConsoleOutputCharacterA(hCon, &ch, 1, c, &len); } }}static void testCursor(HANDLE hCon, COORD sbSize){ COORD c; c.X = c.Y = 0; ok(SetConsoleCursorPosition(0, c) == 0, "No handle"); ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError: expecting %u got %lu", ERROR_INVALID_HANDLE, GetLastError()); c.X = c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left"); okCURSOR(hCon, c); c.X = sbSize.X - 1; c.Y = sbSize.Y - 1; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in lower-right"); okCURSOR(hCon, c); c.X = sbSize.X; c.Y = sbSize.Y - 1; ok(SetConsoleCursorPosition(hCon, c) == 0, "Cursor is outside"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu", ERROR_INVALID_PARAMETER, GetLastError()); c.X = sbSize.X - 1; c.Y = sbSize.Y; ok(SetConsoleCursorPosition(hCon, c) == 0, "Cursor is outside"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu", ERROR_INVALID_PARAMETER, GetLastError()); c.X = -1; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) == 0, "Cursor is outside"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu", ERROR_INVALID_PARAMETER, GetLastError()); c.X = 0; c.Y = -1; ok(SetConsoleCursorPosition(hCon, c) == 0, "Cursor is outside"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu", ERROR_INVALID_PARAMETER, GetLastError());}static void testWriteSimple(HANDLE hCon, COORD sbSize){ COORD c; DWORD len; const char* mytest = "abcdefg"; const int mylen = strlen(mytest); /* single line write */ c.X = c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (c.X = 0; c.X < mylen; c.X++) { okCHAR(hCon, c, mytest[c.X], TEST_ATTRIB); } okCURSOR(hCon, c); okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);}static void testWriteNotWrappedNotProcessed(HANDLE hCon, COORD sbSize){ COORD c; DWORD len, mode; const char* mytest = "abcd\nf\tg"; const int mylen = strlen(mytest); int p; ok(GetConsoleMode(hCon, &mode) && SetConsoleMode(hCon, mode & ~(ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT)), "clearing wrap at EOL & processed output"); /* write line, wrapping disabled, buffer exceeds sb width */ c.X = sbSize.X - 3; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (p = mylen - 3; p < mylen; p++) { c.X = sbSize.X - 3 + p % 3; okCHAR(hCon, c, mytest[p], TEST_ATTRIB); } c.X = 0; c.Y = 1; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); p = sbSize.X - 3 + mylen % 3; c.X = p; c.Y = 0; okCURSOR(hCon, c); /* write line, wrapping disabled, strings end on end of line */ c.X = sbSize.X - mylen; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (p = 0; p < mylen; p++) { c.X = sbSize.X - mylen + p; okCHAR(hCon, c, mytest[p], TEST_ATTRIB); } c.X = 0; c.Y = 1; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); p = sbSize.X - mylen; c.X = p; c.Y = 0; okCURSOR(hCon, c);}static void testWriteNotWrappedProcessed(HANDLE hCon, COORD sbSize){ COORD c; DWORD len, mode; const char* mytest = "abcd\nf\tg"; const int mylen = strlen(mytest); const int mylen2 = strchr(mytest, '\n') - mytest; int p; ok(GetConsoleMode(hCon, &mode) && SetConsoleMode(hCon, (mode | ENABLE_PROCESSED_OUTPUT) & ~ENABLE_WRAP_AT_EOL_OUTPUT), "clearing wrap at EOL & setting processed output"); /* write line, wrapping disabled, buffer exceeds sb width */ c.X = sbSize.X - 5; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-5"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (c.X = sbSize.X - 5; c.X < sbSize.X - 1; c.X++) { okCHAR(hCon, c, mytest[c.X - sbSize.X + 5], TEST_ATTRIB); } okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); c.X = 0; c.Y++; okCHAR(hCon, c, mytest[5], TEST_ATTRIB); for (c.X = 1; c.X < 8; c.X++) okCHAR(hCon, c, ' ', TEST_ATTRIB); okCHAR(hCon, c, mytest[7], TEST_ATTRIB); c.X++; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); okCURSOR(hCon, c); /* write line, wrapping disabled, strings end on end of line */ c.X = sbSize.X - 4; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-4"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (c.X = sbSize.X - 4; c.X < sbSize.X; c.X++) { okCHAR(hCon, c, mytest[c.X - sbSize.X + 4], TEST_ATTRIB); } c.X = 0; c.Y++; okCHAR(hCon, c, mytest[5], TEST_ATTRIB); for (c.X = 1; c.X < 8; c.X++) okCHAR(hCon, c, ' ', TEST_ATTRIB); okCHAR(hCon, c, mytest[7], TEST_ATTRIB); c.X++; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); okCURSOR(hCon, c); /* write line, wrapping disabled, strings end after end of line */ c.X = sbSize.X - 3; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-4"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (p = mylen2 - 3; p < mylen2; p++) { c.X = sbSize.X - 3 + p % 3; okCHAR(hCon, c, mytest[p], TEST_ATTRIB); } c.X = 0; c.Y = 1; okCHAR(hCon, c, mytest[5], TEST_ATTRIB); for (c.X = 1; c.X < 8; c.X++) okCHAR(hCon, c, ' ', TEST_ATTRIB); okCHAR(hCon, c, mytest[7], TEST_ATTRIB); c.X++; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); okCURSOR(hCon, c);}static void testWriteWrappedNotProcessed(HANDLE hCon, COORD sbSize){ COORD c; DWORD len, mode; const char* mytest = "abcd\nf\tg"; const int mylen = strlen(mytest); int p; ok(GetConsoleMode(hCon, &mode) && SetConsoleMode(hCon,(mode | ENABLE_WRAP_AT_EOL_OUTPUT) & ~(ENABLE_PROCESSED_OUTPUT)), "setting wrap at EOL & clearing processed output"); /* write line, wrapping enabled, buffer doesn't exceed sb width */ c.X = sbSize.X - 9; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-9"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole"); c.Y = 0; for (p = 0; p < mylen; p++) { c.X = sbSize.X - 9 + p; okCHAR(hCon, c, mytest[p], TEST_ATTRIB); } c.X = sbSize.X - 9 + mylen; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); c.X = 0; c.Y = 1; okCHAR(hCon, c, ' ', DEFAULT_ATTRIB); /* write line, wrapping enabled, buffer does exceed sb width */ c.X = sbSize.X - 3; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3"); ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -