Подпишитесь на наш Telegram-канал, чтобы всегда быть в курсе важных обновлений! Перейти

[C++] Console

Эксперт
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
994
Реакции
1,209
Для чего и зачем сами решайте.
Выкрики: "Можно проще!" - оставьте при себе. Сделано в таком виде - значит так нужно.
Больше как памятка для себя....


Код:
Expand Collapse Copy
#pragma once
#include <string>
#include <Windows.h>

namespace Console
{
    enum ConsoleColor {
        Black = 0,
        Blue = 1,
        Green = 2,
        Cyan = 3,
        Red = 4,
        Magenta = 5,
        Brown = 6,
        LightGray = 7,
        DarkGray = 8,
        LightBlue = 9,
        LightGreen = 10,
        LightCyan = 11,
        LightRed = 12,
        LightMagenta = 13,
        Yellow = 14,
        White = 15
    };
 
    class cConsole
    {
    public:
        static cConsole& Singleton() {
            static cConsole pObject;
            return pObject;
        }

        cConsole() = default;
        ~cConsole() = default;
 
        inline BOOL  set_title(_In_ LPCSTR lpConsoleTitle) {
            return SetConsoleTitleA(lpConsoleTitle);
        }
 
        inline bool  printf(_In_ const char* fmt, ...)
        {
            if (!hStdOut)
                return false;

            char buf[1024];
            va_list va;

            va_start(va, fmt);
            _vsnprintf_s(buf, 1024, fmt, va);
            va_end(va);

            return !!WriteConsoleA(hStdOut, buf, static_cast<DWORD>(strlen(buf)), nullptr, nullptr);
        }
        inline bool  printf(_In_ int color, _In_ const char* fmt, ...)
        {
            if (!hStdOut)
                return false;

            char buf[1024];
            va_list va;

            va_start(va, fmt);
            _vsnprintf_s(buf, 1024, fmt, va);
            va_end(va);
            set_color(color);

            BOOL Result = WriteConsoleA(hStdOut, buf, static_cast<DWORD>(strlen(buf)), nullptr, nullptr);
            set_default();
            return Result;
        }

        inline bool  wprintf(_In_ const wchar_t* fmt, ...)
        {
            if (!hStdOut)
                return false;

            wchar_t buf[1024];
            va_list va;

            va_start(va, fmt);
            _vsnwprintf_s(buf, 1024, fmt, va);
            va_end(va);

            return !!WriteConsoleW(hStdOut, buf, static_cast<DWORD>(wcslen(buf)), nullptr, nullptr);
        }
        inline bool  wprintf(_In_ int color, _In_ const wchar_t* fmt, ...)
        {
            if (!hStdOut)
                return false;

            wchar_t buf[1024];
            va_list va;

            va_start(va, fmt);
            _vsnwprintf_s(buf, 1024, fmt, va);
            va_end(va);
            set_color(color);

            BOOL Result = WriteConsoleW(hStdOut, buf, static_cast<DWORD>(wcslen(buf)), nullptr, nullptr);
            set_default();
            return Result;
        }
 
        inline BOOL  set_color(_In_ int color) {
            return SetConsoleTextAttribute(hStdOut, color);
        }
        inline BOOL  set_default() {
            return SetConsoleTextAttribute(hStdOut, csbi.wAttributes);
        }
    
        inline void  AttachConsole() {
            hStdOut_old = GetStdHandle(STD_OUTPUT_HANDLE);
            hStdErr_old = GetStdHandle(STD_ERROR_HANDLE);
            hStdIn_old = GetStdHandle(STD_INPUT_HANDLE);

            ::AllocConsole() && ::AttachConsole(GetCurrentProcessId());

            hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
            hStdErr = GetStdHandle(STD_ERROR_HANDLE);
            hStdIn = GetStdHandle(STD_INPUT_HANDLE);

            SetConsoleMode(hStdOut,
                ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);

            SetConsoleMode(hStdIn,
                ENABLE_INSERT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT | ENABLE_QUICK_EDIT_MODE);

            GetConsoleScreenBufferInfo(hStdOut, &csbi);
        }
        inline void  DetachConsole() {
            if (hStdOut && hStdErr && hStdIn) {
                FreeConsole();

                if (hStdOut_old)
                    SetStdHandle(STD_OUTPUT_HANDLE, hStdOut_old);
                if (hStdErr_old)
                    SetStdHandle(STD_ERROR_HANDLE, hStdErr_old);
                if (hStdIn_old)
                    SetStdHandle(STD_INPUT_HANDLE, hStdIn_old);
            }
        }
    private:
        HANDLE hStdOut;
        HANDLE hStdErr;
        HANDLE hStdIn;

        HANDLE hStdOut_old;
        HANDLE hStdErr_old;
        HANDLE hStdIn_old;

        CONSOLE_SCREEN_BUFFER_INFO csbi;
    };
    inline cConsole& Console() {
        return cConsole::Singleton();
    }
};


#define LOG_A(...)           \
                       Console::Console().printf(__VA_ARGS__);
#define LOGCOLOR_A(col,...)  \
                       Console::Console().printf(col,__VA_ARGS__);

#define LOG_W(...)           \
                       Console::Console().wprintf(__VA_ARGS__);
#define LOGCOLOR_W(col,...)  \
                       Console::Console().wprintf(col,__VA_ARGS__);

#define LOG_TRACE_A(...)    LOGCOLOR_A(Console::ConsoleColor::Cyan, "TRACE:: "##__VA_ARGS__)
#define LOG_ERROR_A(...)    LOGCOLOR_A(Console::ConsoleColor::Red,  "ERROR:: "##__VA_ARGS__)
#define LOG_WARNING_A(...)  LOGCOLOR_A(Console::ConsoleColor::Brown,"WARNING:: "##__VA_ARGS__)

#define LOG_TRACE_W(...)    LOGCOLOR_W(Console::ConsoleColor::Cyan, L"TRACE:: "##__VA_ARGS__)
#define LOG_ERROR_W(...)    LOGCOLOR_W(Console::ConsoleColor::Red,  L"ERROR:: "##__VA_ARGS__)
#define LOG_WARNING_W(...)  LOGCOLOR_W(Console::ConsoleColor::Brown,L"WARNING:: "##__VA_ARGS__)

#if defined(_UNICODE)
#define LOG(...)          LOG_W(__VA_ARGS__)
#define LOGCOLOR(col,...) LOGCOLOR_W(col,__VA_ARGS__)
#define LOG_TRACE(...)    LOG_TRACE_W(__VA_ARGS__)
#define LOG_ERROR(...)    LOG_ERROR_W(__VA_ARGS__)
#define LOG_WARNING(...)  LOG_WARNING_W(__VA_ARGS__)
#else
#define LOG(...)          LOG_A(__VA_ARGS__)
#define LOGCOLOR(col,...) LOGCOLOR_A(col,__VA_ARGS__)
#define LOG_TRACE(...)    LOG_TRACE_A(__VA_ARGS__)
#define LOG_ERROR(...)    LOG_ERROR_A(__VA_ARGS__)
#define LOG_WARNING(...)  LOG_WARNING_A(__VA_ARGS__)
#endif

Ex:
Код:
Expand Collapse Copy
unsigned __stdcall BeginFunction(LPVOID lpParam)
{
    Console::Console().AttachConsole();
    Console::Console().set_title("Console Demo");

    LOG("LOG: Line  = %d\n",__LINE__);
    LOGCOLOR(Console::LightMagenta, "LOGCOLOR  %Ts\n", "args");
    LOG_TRACE("LOG_TRACE %s\n", __FUNCTION__);
    LOG_ERROR("LOG_ERROR 0x%X\n", 0x100990);
    LOG_WARNING("LOG_WARNING 0x%X\n", 0x10022);
    
    Console::Console().DetachConsole();
    return 0L;
}

pCenfFtV.png
 
Почему inline, а не forceilnline?
По идее если ты хочешь заинлайнить функцию то логичнее использовать именно его.
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Может я конечно придираюсь , но почему в разных участках кода используется bool, а где-то BOOL. Не особо вписывается под одну стилистику кода и глаза режет.
 
Может я конечно придираюсь , но почему в разных участках кода используется bool, а где-то BOOL. Не особо вписывается под одну стилистику кода и глаза режет.
BOOL - обычно тайпдеф на int)
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Да ,ну. Серьёзно? :roflanebalo: Тут дело не в тайпдефах , а в эстетичности кода
Эстетичность кода?) Ну прости, я не знал шо ты шариш за тайпдеф =)))
Как кому нравится тот так и делает :da:
 
Да ,ну. Серьёзно? :roflanebalo: Тут дело не в тайпдефах , а в эстетичности кода
Практически все WinApi функции, которые использовались здесь, имеют "тип возврата" - BOOL. Так что действительно есть эстетический смысл использовать везде BOOL. Но специфика общего проекта(а предоставленный код это просто маленький кусочек проекта, при чем класс урезан до минимала) и этап отладки(а так же эксперименты) требуют использовать логику(bool). По большому счету, в подавляющем большинстве случаев, особой разницы тут нету, к тому же я сделал пометку:
Сделано в таком виде - значит так нужно.

Но не что не мешает перелопатить код как вам нужно. Это просто общая концепция))
 
Назад
Сверху Снизу