//=================================================================================================================
// TXLib.h - Библиотека Тупого Художника (The Dumb Artist Library, TX Library, TXLib) - (C) Ilya Dedinsky
//=================================================================================================================
// [These sections are for folding control in Code::Blocks] [$Date: 2024-03-06 23:40:00 +0400 $]
// [Best viewed with "Fold all on file open" option enabled] [Best screen/page width = 120 chars]
//
// [If RUSSIAN CHARS below are UNREADABLE, check this file codepage. It should be CP1251, NOT UTF-8 etc.]
//{ [Use RELOAD options in your IDE or editor (CLion / Visual Studio Code / ...), and do NOT use Convert.]
//=================================================================================================================
//!
//! @file TXLib.h
//! @brief Библиотека Тупого Художника (The Dumb Artist Library, TX Library, TXLib).
//!
//! И.Р. Дединский @n
//! Кафедра информатики и вычислительной математики МФТИ @n
//! Кафедра системного программирования МФТИ
//!
//! $Version: 00173a, Revision: 173 $
//! $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) $
//! $Date: 2024-03-06 23:40:00 +0400 $
//!
//! TX Library -- компактная библиотека двумерной графики для MS Windows на С++. Это небольшая "песочница"
//! для начинающих реализована с целью помочь им в изучении простейших принципов программирования.
//! Документация на русском языке. Философия TX Library -- облегчить первые шаги в программировании
//! и подтолкнуть к творчеству и самостоятельности.
//!
//! TX Library is a tiny 2D graphics library for MS Windows written in C++. This is a small sandbox for the
//! very beginners to help them to learn basic programming principles. The documentation is in Russian.
//!
//! Официальный сайт библиотеки: txlib.ru. @n
//! См. также страницу проекта на SourceForge.
//!
//! Онлайн-документация: здесь.
//! Короткая ссылка: gg.gg/TXLib.
//!
//! Учебник TXBook по программированию: здесь.
//! Короткая ссылка: gg.gg/TXBook.
//!
//! @section Setup Установка и использование библиотеки
//!
//! Скачать библиотеку:
//! на сайте sourceforge.net. См. также раздел @ref TXLibSetup "Установка библиотеки".
//!
//! @note Библиотека TXLib состоит из единственного файла и не требует никаких настроек в среде
//! программирования, чтобы облегчить ее установку и работу для начинающих.
//!
//! @note Файл библиотеки большой и может компилироваться долго, поэтому обратите внимание на возможность
//! использования прекомпилированной версии в проектак с раздельной компиляцией. См. макрос @ref TX_COMPILED.
//! Также можно определить макрос @c WIN32_LEAN_AND_MEAN до включения @c TXLib.h в программу.
//!
//! -# Скачайте программу установки,
//! загрузка по ссылке начнется автоматически. Ее имя имеет вид TXLib-v0173a.rar.exe. Цифры могут
//! отличаться (это номер версии), расширение @c .exe может не отображаться, в зависимости от настроек Windows.
//! -# Запустите скачанную программу установки. Программа установки -- это саморазархивирующийся
//! архив, она не требует особых прав для запуска.
//! -# На рабочем столе появится "Ярлык для TX". Откройте его и запустите систему помощи TXLib Help,
//! изучите ее. Простейший пример см.
//! здесь. Другие примеры см.
//! в папке Examples, в папке Examples/Demo.
//! @nn
//! - Если при установке происходят ошибки или запуск программы установки невозможен, откройте файл библиотеки
//! @c TXLib.h отсюда, сохраните (Ctrl+S)
//! его в свою рабочую папку, где вы сохраняете свои программы.
//! Пользуйтесь системой помощи
//! онлайн.
//! @nn
//! -# Для полной обработки ошибок библиотеке требуются модули, которые желательно установить (скопировать) в папку
//! Windows. Устанавливать эти библиотеки не обязательно. Программы, использующие TXLib, запускаются и без них.
//! @nn
//! -# Модули библиотеки Microsoft DBGHELP для доступа к отладочным символам Microsoft:
//! - @c dbghelp32.dll или dbghe32.dll - для 32-разрядных программ (либо @c dbghelp.dll, 32-разрядная версия),
//! - @c dbghelp64.dll или dbghe64.dll - для 64-разрядных программ (либо @c dbghelp.dll, 64-разрядная версия),
//! @nn
//! -# Модули библиотеки DrMinGW для доступа
//! к отладочным символам MinGW компилятора GCC @c g++:
//! - @c mgwhelp32.dll или mgwhe32.dll - для 32-разрядных программ (либо @c mgwhelp.dll, 32-разрядная версия),
//! - @c mgwhelp64.dll или mgwhe64.dll - для 64-разрядных программ (либо @c mgwhelp.dll, 64-разрядная версия).
//!
//! Суффиксы @c 32 и @c 64 помогают отличить 32-разрядную и 64-разрядную версии DLL-файлов библиотек.
//! Например, @c dbghelp32.dll -- это просто переименованная 32-разрядная версия файла @c dbghelp.dll.
//!
//! Cамораспаковывающийся архив с этими библиотеками можно скачать
//! здесь.
//!
//! Для наиболее полной диагностики ошибок полностью отключайте оптимизацию при компиляции. Например,
//! для компилятора GCC @c g++ -- с помощью ключа командной строки @c -O0. Разные среды программирования
//! позволяют задать эти ключи по-разному, например, в CodeBlocks через Главное меню -- Settings --
//! Compiler -- (Global Compiler Settings) -- (Compiler Settings) -- Other Options.
//!
//! @note Кодовая страница в редакторе среды разработки должна быть установлена как Windows CP1251, проверьте
//! это. В разных средах разработки она устанавливается по-разному, например, в CodeBlocks через
//! Главное меню -- Settings -- Editor -- (General Settings) -- Other Settings -- Encoding. Иначе
//! русские буквы в сообщениях TXLib будут отображаться неправильно.
//!
//! @warning Это альфа-версия. Для использования библиотеки требуется согласование с ее автором. @n
//! Правила использования материалов библиотеки и сайта см. на
//! официальном сайте TXLib.
//!
//! @par Баг-трекер на GitHub:
//! - Сообщить об ошибке
//!
// $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) $
//-----------------------------------------------------------------------------------------------------------------
//!
//! @defgroup Drawing Рисование
//! @defgroup Mouse Поддержка Мыши!
//! @defgroup Dialogs Диалоговые окна
//! @defgroup Misc Разное
//! @defgroup Technical Технические детали
//}
//=================================================================================================================
#if !defined (__TXLIB_H_INCLUDED) // <<< THE CODE IS HERE, UNFOLD IT <<<
#define __TXLIB_H_INCLUDED
//-----------------------------------------------------------------------------------------------------------------
//{ Version information and configuration
//-----------------------------------------------------------------------------------------------------------------
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Текущая версия библиотеки.
//!
//! Версия библиотеки в целочисленном формате: старшее слово -- номер версии, младшее -- номер ревизии,
//! в двоично-десятичном формате. Например, @c 0x172a0050 -- версия @c 0.172a, ревизия @c 50.
//! @code
//! #define _TX_VERSION "TXLib [Ver: 1.73a, Rev: 164, Date: 2020-01-30 05:00:00 +0300]" //
//! #define _TX_AUTHOR "Copyright (C) Ded (Ilya Dedinsky, http://txlib.ru)" // ПРИМЕР
//! #define _TX_VER 0x173a0000 //
//! @endcode
//! Эти константы автоматически обновляются при изменении версии.
//!
//! @see txVersion()
//!
//! @usage @code
//! #if !(defined (_TX_VER) && (_TX_VER >= 0x172a0000))
//! #error Must use TXLib.h version >= 1.72 to compile this.
//! #endif
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define _TX_VER _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-03-06 23:40:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) ", $)
#define _TX_VERSION _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-03-06 23:40:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) ", $)
#define _TX_AUTHOR _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-03-06 23:40:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) ", $)
//! @cond INTERNAL
#define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2) ((0x##ver##u << 16) | 0x##rev##u)
#define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2) "TXLib [Ver: " #ver ", Rev: " #rev ", Date: " #date "]"
#define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2) "Copyright (C) " auth
//! @endcond
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Имя модуля TXLib. Входит в диагностические сообщения.
//!
//! @note Можно переопределять до включения файла TXLib.h.
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (_TX_MODULE)
#define _TX_MODULE "TXLib"
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Имя и версия текущего компилятора
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (__GNUC__)
#define _GCC_VER ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ )
#define __TX_COMPILER__ "GNU g++ " TX_QUOTE (__GNUC__) "." \
TX_QUOTE (__GNUC_MINOR__) "." \
TX_QUOTE (__GNUC_PATCHLEVEL__) \
", std=" TX_QUOTE (__cplusplus)
#elif defined (__clang__) || defined (__clang_major__)
#define _CLANG_VER ( __clang_major__*100 + __clang_minor__*10 + __clang_patchlevel__ )
#define __TX_COMPILER__ "Clang " TX_QUOTE (__clang_major__) "." \
TX_QUOTE (__clang_minor__) "." \
TX_QUOTE (__clang_patchlevel__) \
", std=" TX_QUOTE (__cplusplus)
#elif defined (_MSC_VER)
#define __TX_COMPILER__ "MSVS " TX_QUOTE (_MSC_VER) \
", std=" TX_QUOTE (__cplusplus)
#elif defined (__INTEL_COMPILER)
#define __TX_COMPILER__ "Intel C++ " TX_QUOTE (__INTEL_COMPILER) \
", std=" TX_QUOTE (__cplusplus)
#else
#define __TX_COMPILER__ "Unknown C++, std=" TX_QUOTE (__cplusplus)
#endif
//! @cond INTERNAL
#define TX_QUOTE(sym) _TX_QUOTE (sym)
#define _TX_QUOTE(sym) #sym
#define TX_JOIN(sym1, sym2) _TX_JOIN (sym1, sym2)
#define _TX_JOIN(sym1, sym2) sym1 ## sym2
//! @endcond
#if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013
#define _TX_CPP11 1
#endif
#if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1900) // MSVC 2015
#define _TX_CPP11_MSVC15 1
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Имя режима сборки
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG) && defined (_DEBUG)
#define _TX_BUILDMODE "DEBUG"
#elif !defined (NDEBUG) && !defined (_DEBUG)
#define _TX_BUILDMODE "Debug"
#elif defined (NDEBUG)
#define _TX_BUILDMODE "Release"
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Макрос, раскрывающийся в имя файла и номер строки файла, где он встретился.
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define __TX_FILELINE__ __FILE__ ":" TX_QUOTE (__LINE__)
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Имя текущей функции
//!
//! @warning Если определение имени функции не поддерживается компилятором, то __TX_FUNCTION__ раскрывается в имя
//! исходного файла и номер строки.
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (__GNUC__) || defined (__clang__) || defined (__clang_major__)
#define __TX_FUNCTION__ __PRETTY_FUNCTION__
#elif defined (__FUNCSIG__)
#define __TX_FUNCTION__ __FUNCSIG__
#elif defined (__FUNCTION__)
#define __TX_FUNCTION__ __FUNCTION__
#elif defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)
#define __TX_FUNCTION__ __FUNCTION__
#elif defined (__BORLANDC__) && (__BORLANDC__ >= 0x550)
#define __TX_FUNCTION__ __FUNC__
#elif defined (__cplusplus) && (__cplusplus >= 199711L)
#define __TX_FUNCTION__ __func__
#elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define __TX_FUNCTION__ __func__
#elif defined (__PYTHON__)
#error No Python. No. Using parseltongue languages can lead you to Slytherin.
#else
#define __TX_FUNCTION__ "(" __TX_FILELINE__ ")"
#endif
#if !defined (__func__) && defined (__FUNCTION__)
#define __func__ __FUNCTION__
#endif
//}
//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
//{ Compiler- and platform-specific
//! @name Адаптация к компиляторам и платформам
//-----------------------------------------------------------------------------------------------------------------
//! @{ @cond INTERNAL
#if !defined (__cplusplus)
#ifdef __GNUC__
#error
#error ---------------------------------------------------------------------------------------
#endif
#error TXLib.h: Must use C++ to compile TXLib.h. Now you are using C only.
#error
#error CHECK source file EXTENSION. Maybe it is ".C". It must be ".CPP".
#error If your file is named, for example, "Untitled.C", go to menu [File],
#error then [Save As] and rename it to "Untitled.CPP". Please do NOT use spaces.
#error ---------------------------------------------------------------------------------------
#error
#endif
//-----------------------------------------------------------------------------------------------------------------
#if !defined (WIN32) && !defined (__WIN32__) && !defined(_WIN32) && !defined(_WIN32_WINNT) && !defined (__CYGWIN__)
#ifdef __GNUC__
#error
#error ---------------------------------------------------------------------------------------
#endif
#error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW or Cygwin) is the only supported OS, sorry.
#error
#error In Linux or MacOS, you should write your own TXLib and share it with your friends, or use wine.
#error ---------------------------------------------------------------------------------------
#error
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (UNICODE) || defined (_UNICODE)
#ifdef __GNUC__
#warning TXLib.h: Disabling the UNICODE
#endif
#undef UNICODE // Burn Unicode, burn
#undef _UNICODE
#if defined (_WINDOWS_H) || defined (_INC_WINDOWS) || defined (_WINDOWS_) || defined (__WINDOWS__)
#ifdef __GNUC__
#error
#error ---------------------------------------------------------------------------------------
#endif
#error TXLib.h: Should include "TXLib.h" BEFORE or INSTEAD of in UNICODE mode.
#error
#error REARRANGE your #include directives, or DISABLE the UNICODE mode by #undef UNICODE/_UNICODE.
#error ---------------------------------------------------------------------------------------
#error
#endif
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (__STRICT_ANSI__) && (_GCC_VER < 1120) // Try to extend strict ANSI rules
#undef __STRICT_ANSI__
#define __STRICT_ANSI__UNDEFINED
#if defined (_STRING_H_) || defined (_INC_STRING) || defined (_STDIO_H_) || defined (_INC_STDIO)
#ifdef __GNUC__
#error
#error ---------------------------------------------------------------------------------------
#endif
#error TXLib.h: Should include "TXLib.h" BEFORE or in Strict ANSI mode.
#error
#error REARRANGE your #include directives, or DISABLE ANSI-compliancy by #undef __STRICT_ANSI__.
#error ---------------------------------------------------------------------------------------
#error
#endif
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic warning "-Wall"
#pragma GCC diagnostic warning "-Weffc++"
#pragma GCC diagnostic warning "-Wextra"
#pragma GCC diagnostic warning "-Waggressive-loop-optimizations"
#pragma GCC diagnostic warning "-Walloc-zero"
#pragma GCC diagnostic warning "-Walloca"
#pragma GCC diagnostic warning "-Walloca-larger-than=8192"
#pragma GCC diagnostic warning "-Warray-bounds"
#pragma GCC diagnostic warning "-Wcast-align"
#pragma GCC diagnostic warning "-Wcast-qual"
#pragma GCC diagnostic warning "-Wchar-subscripts"
#pragma GCC diagnostic warning "-Wconditionally-supported"
#pragma GCC diagnostic warning "-Wconversion"
#pragma GCC diagnostic warning "-Wctor-dtor-privacy"
#pragma GCC diagnostic warning "-Wdangling-else"
#pragma GCC diagnostic warning "-Wduplicated-branches"
#pragma GCC diagnostic warning "-Wempty-body"
#pragma GCC diagnostic warning "-Wfloat-equal"
#pragma GCC diagnostic warning "-Wformat-nonliteral"
#pragma GCC diagnostic warning "-Wformat-overflow=2"
#pragma GCC diagnostic warning "-Wformat-security"
#pragma GCC diagnostic warning "-Wformat-signedness"
#pragma GCC diagnostic warning "-Wformat-truncation=2"
#pragma GCC diagnostic warning "-Wformat=2"
#pragma GCC diagnostic warning "-Wlarger-than=8192"
#pragma GCC diagnostic warning "-Wlogical-op"
#pragma GCC diagnostic warning "-Wmismatched-tags"
#pragma GCC diagnostic warning "-Wmissing-declarations"
#pragma GCC diagnostic warning "-Wnarrowing"
#pragma GCC diagnostic warning "-Wnon-virtual-dtor"
#pragma GCC diagnostic warning "-Wnonnull"
#pragma GCC diagnostic warning "-Wopenmp-simd"
#pragma GCC diagnostic warning "-Woverloaded-virtual"
#pragma GCC diagnostic warning "-Wpacked"
#pragma GCC diagnostic warning "-Wpointer-arith"
// #pragma GCC diagnostic warning "-Wredundant-decls"
// #pragma GCC diagnostic warning "-Wredundant-tags"
#pragma GCC diagnostic warning "-Wrestrict"
#pragma GCC diagnostic warning "-Wshadow"
#pragma GCC diagnostic warning "-Wsign-promo"
#pragma GCC diagnostic warning "-Wstack-usage=8192"
#pragma GCC diagnostic warning "-Wstrict-aliasing"
#pragma GCC diagnostic warning "-Wstrict-null-sentinel"
#pragma GCC diagnostic warning "-Wstrict-overflow=2"
#pragma GCC diagnostic warning "-Wstringop-overflow=4"
#pragma GCC diagnostic warning "-Wsuggest-attribute=noreturn"
#pragma GCC diagnostic warning "-Wsuggest-final-methods"
#pragma GCC diagnostic warning "-Wsuggest-final-types"
#pragma GCC diagnostic warning "-Wsuggest-override"
#pragma GCC diagnostic warning "-Wswitch-default"
#pragma GCC diagnostic warning "-Wswitch-enum"
#pragma GCC diagnostic warning "-Wsync-nand"
#pragma GCC diagnostic warning "-Wundef"
#pragma GCC diagnostic warning "-Wunused"
#pragma GCC diagnostic warning "-Wvarargs"
#pragma GCC diagnostic warning "-Wvla-larger-than=8192"
#pragma GCC diagnostic error "-Wsizeof-array-argument"
#pragma GCC diagnostic ignored "-Waddress"
#pragma GCC diagnostic ignored "-Winline"
#pragma GCC diagnostic ignored "-Wliteral-suffix"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunreachable-code"
#pragma GCC diagnostic ignored "-Wunused-const-variable"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#pragma GCC diagnostic warning "-Wpragmas"
//{ These warning settings for TXLib.h only and will be re-enabled at end of file:
#pragma GCC push_options
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wpedantic"
#pragma GCC diagnostic ignored "-Waddress"
#pragma GCC diagnostic ignored "-Warray-bounds"
#pragma GCC diagnostic ignored "-Wclobbered"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wlarger-than="
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wredundant-decls"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wunused-label" // Just for fun in _txCanvas_OnCmdAbout()
#pragma GCC diagnostic ignored "-Wunused-value"
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#pragma GCC diagnostic ignored "-Wpacked-not-aligned"
#pragma GCC optimize "no-strict-aliasing"
#pragma GCC diagnostic warning "-Wpragmas"
#if defined (__CYGWIN__) && !defined (_TX_TESTING)
#pragma GCC system_header // This is not a fair play, but this is the only way to deal with Cygwin :(
#endif
//}
#define _tx_thread __thread
#define _tx_decltype(value) __decltype (value)
#define _FORTIFY_SOURCE 2
#ifndef MINGW_HAS_SECURE_API
#define MINGW_HAS_SECURE_API 1
#endif
#if defined (TX_USE_SFML)
#define _GLIBCXX_NDEBUG
#endif
#ifndef _GLIBCXX_NDEBUG // TXLib enables _GLIBCXX_DEBUG by default. When using third-party libraries
#define _GLIBCXX_DEBUG // compiled without _GLIBCXX_DEBUG (SFML, for example), #define _GLIBCXX_NDEBUG
#define _GLIBCXX_DEBUG_PEDANTIC // *before* including TXLib.h.
#endif
#if defined (_WIN64) // removed in x86 because printf ("%g", double) failure, this prints 0 always
#ifndef __USE_MINGW_ANSI_STDIO
#define __USE_MINGW_ANSI_STDIO 1
#endif
#endif
template
inline T _txNOP (T value) { return value; } // To suppress performance warnings in assert etc.
// From MinGW\include\float.h which is replaced by MinGW\lib\gcc\i686-pc-mingw32\x.x.x\include\float.h
extern "C" __declspec (dllimport) unsigned __cdecl _controlfp (unsigned control, unsigned mask);
extern "C" void __cdecl _fpreset ();
#else
#define __attribute__( attr )
#define _txNOP( value ) ( value )
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (__clang__) || defined (__clang_major__)
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic warning "-Wall"
#pragma clang diagnostic warning "-Weffc++"
#pragma clang diagnostic warning "-Wextra"
#pragma clang diagnostic warning "-Wcast-qual"
#pragma clang diagnostic warning "-Wchar-subscripts"
#pragma clang diagnostic warning "-Wconversion"
#pragma clang diagnostic warning "-Wctor-dtor-privacy"
#pragma clang diagnostic warning "-Wempty-body"
#pragma clang diagnostic warning "-Wfloat-equal"
#pragma clang diagnostic warning "-Wformat"
#pragma clang diagnostic warning "-Wformat-nonliteral"
#pragma clang diagnostic warning "-Wformat-security"
#pragma clang diagnostic warning "-Wmissing-declarations"
#pragma clang diagnostic warning "-Wnon-virtual-dtor"
#pragma clang diagnostic warning "-Woverloaded-virtual"
#pragma clang diagnostic warning "-Wpacked"
#pragma clang diagnostic warning "-Wpointer-arith"
#pragma clang diagnostic warning "-Wredundant-decls"
#pragma clang diagnostic warning "-Wshadow"
#pragma clang diagnostic warning "-Wsign-promo"
#pragma clang diagnostic warning "-Wstrict-aliasing"
#pragma clang diagnostic warning "-Wstrict-overflow"
#pragma clang diagnostic warning "-Wswitch-default"
#pragma clang diagnostic warning "-Wswitch-enum"
#pragma clang diagnostic warning "-Wunused"
#pragma clang diagnostic ignored "-Winvalid-source-encoding"
#pragma clang diagnostic ignored "-Wunused-const-variable"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic warning "-Wunknown-pragmas"
//{ These warning settings for TXLib.h only and will be re-enabled at end of file:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wpedantic"
#pragma clang diagnostic ignored "-Wcast-align"
#pragma clang diagnostic ignored "-Wfloat-conversion"
#pragma clang diagnostic ignored "-Wmicrosoft-cast"
#pragma clang diagnostic ignored "-Wmisleading-indentation"
#pragma clang diagnostic ignored "-Wmissing-braces"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#pragma clang diagnostic ignored "-Wsign-compare"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wstring-plus-int"
#pragma clang diagnostic ignored "-Wundef"
#pragma clang diagnostic ignored "-Wundefined-bool-conversion"
#pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wunused-value"
#pragma clang diagnostic ignored "-Wvariadic-macros"
#pragma clang diagnostic warning "-Wunknown-pragmas"
//{ CLang-Tidy options
//
// *,-cert-dcl50-cpp,-cert-dcl58-cpp,-cert-err52-cpp,-cert-err58-cpp,-cert-flp30-c,-cert-msc30-c,-cert-msc32-c,
// -cert-msc50-cpp,-cert-msc51-cpp,-clang-analyzer-core.DivideZero,-cppcoreguidelines-avoid-c-arrays,
// -cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,
// -cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-no-malloc,
// -cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,
// -cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access,
// -cppcoreguidelines-pro-type-vararg,-fuchsia-default-arguments-calls,-fuchsia-default-arguments-declarations,
// -fuchsia-overloaded-operator,-google-build-using-namespace,-google-global-names-in-headers,-google-runtime-int,
// -google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments,
// -hicpp-avoid-c-arrays,-hicpp-avoid-goto,-hicpp-braces-around-statements,-hicpp-deprecated-headers,-hicpp-no-array-decay,
// -hicpp-signed-bitwise,-hicpp-use-equals-delete,-hicpp-use-nullptr,-hicpp-vararg,-llvm-include-order,-hicpp-no-malloc,
// -llvm-namespace-comment,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-use-auto,
// -modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-use-default-member-init,-hicpp-use-auto,
// -modernize-use-equals-delete,-modernize-use-nullptr,-modernize-use-trailing-return-type,-modernize-use-using,
// -readability-braces-around-statements,-readability-else-after-return,-readability-implicit-bool-conversion,
// -readability-isolate-declaration,-readability-magic-numbers,-readability-named-parameter,-modernize-loop-convert
//}
//}
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (_MSC_VER)
#pragma warning (push, 4) // Set maximum warning level. This 'push' is to set the level only. It will NOT be popped.
#pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning
#pragma warning (disable: 4514) // Unreferenced inline function has been removed
#pragma warning (disable: 4710) // Function not inlined
#pragma warning (disable: 4786) // Identifier was truncated to '255' characters in the debug information
#pragma warning (error: 4715) // Not all control paths return a value
#pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665
#pragma warning (disable: 26473) // Don't cast between pointer types where the source type and the target type are the same (type.1).
#pragma warning (disable: 26475) // Do not use function style C-casts (es.49).
#pragma warning (disable: 26477) // Use 'nullptr' rather than 0 or NULL (es.47).
#pragma warning (disable: 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
#pragma warning (disable: 26826) // Don't use C-style variable arguments (f.55).
// These warning settings for TXLib.h only and will be re-enabled at end of file:
#pragma warning (push)
#pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning
#pragma warning (disable: 4091) // 'typedef': ignored on left of '...' when no variable is declared
#pragma warning (disable: 4124) // Using __fastcall with stack checking is ineffective
#pragma warning (disable: 4127) // Conditional expression is constant
#pragma warning (disable: 4200) // Nonstandard extension used: zero-sized array in struct/union
#pragma warning (disable: 4201) // Nonstandard extension used: nameless struct/union
#pragma warning (disable: 4351) // New behavior: elements of array will be default initialized
#pragma warning (disable: 4480) // Nonstandard extension used: specifying underlying type for enum 'type'
#pragma warning (disable: 4481) // Nonstandard extension used: override specifier 'override'
#pragma warning (disable: 4555) // Result of expression not used
#pragma warning (disable: 4611) // Interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning (disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#pragma warning (disable: 6269) // Possibly incorrect order of operations: dereference ignored
#pragma warning (disable: 6285) // () || () is always a non-zero constant. Did you intend to use bitwize-and operator?
#pragma warning (disable: 6319) // Use of the comma-operator in a tested expression causes the left argument to be ignored when it has no side-effects
#pragma warning (disable: 6326) // Potential comparison of a constant with another constant
#pragma warning (disable: 6553) // The annotation for function 'func' on _Param_(N) does not apply to a value type.
#pragma warning (disable: 26135) // Missing locking annotation
#pragma warning (disable: 26400) // Do not assign the result of an allocation or a function call with an owner return value to a raw pointer, use owner instead (i.11).
#pragma warning (disable: 26401) // Do not delete a raw pointer that is not an owner (i.11).
#pragma warning (disable: 26403) // Reset or explicitly delete an owner pointer 'name' (r.3).
#pragma warning (disable: 26408) // Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10).
#pragma warning (disable: 26409) // Avoid calling new and delete explicitly, use std::make_unique instead (r.11).
#pragma warning (disable: 26426) // Global initializer calls a non-constexpr function 'name' (i.22).
#pragma warning (disable: 26429) // Symbol 'name' is never tested for nullness, it can be marked as not_null (f.23).
#pragma warning (disable: 26430) // Symbol 'name' is not tested for nullness on all paths (f.23).
#pragma warning (disable: 26432) // If you define or delete any default operation in the type 'struct 'name'', define or delete them all (c.21).
#pragma warning (disable: 26435) // Function 'name' should specify exactly one of 'virtual', 'override', or 'final' (c.128).
#pragma warning (disable: 26438) // Avoid 'goto' (es.76).
#pragma warning (disable: 26440) // Function 'name' can be declared 'noexcept' (f.6).
#pragma warning (disable: 26446) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).
#pragma warning (disable: 26447) // The function is declared 'noexcept' but calls function 'func' which may throw exceptions (f.6).
#pragma warning (disable: 26448) // Consider using gsl::finally if final action is intended (gsl.util).
#pragma warning (disable: 26451) // Arithmetic overflow: Using operator 'op' on a n-byte value and then casting the result to a m-byte value. Cast the value to the wider type before calling operator 'op' to avoid overflow (io.2).
#pragma warning (disable: 26455) // Default constructor may not throw. Declare it 'noexcept' (f.6).
#pragma warning (disable: 26457) // (void) should not be used to ignore return values, use 'std::ignore =' instead (es.48)
#pragma warning (disable: 26460) // The reference argument 'stream' for function 'name' can be marked as const (con.3).
#pragma warning (disable: 26461) // The pointer argument 'name' for function 'name' can be marked as a pointer to const (con.3).
#pragma warning (disable: 26462) // The value pointed to by 'name' is assigned only once, mark it as a pointer to const (con.4).
#pragma warning (disable: 26482) // Only index into arrays using constant expressions (bounds.2).
#pragma warning (disable: 26483) // Value 'value' is outside the bounds (min, max) of variable 'name'. Only index into arrays using constant expressions that are within bounds of the array (bounds.2).
#pragma warning (disable: 26485) // Expression 'expr': No array to pointer decay (bounds.3).
#pragma warning (disable: 26486) // Don't pass a pointer that may be invalid to a function. Parameter 'n' 'name' in call to 'name' may be invalid (lifetime.3).
#pragma warning (disable: 26487) // Don't return a pointer 'name' that may be invalid (lifetime.4).
#pragma warning (disable: 26488) // Do not dereference a potentially null pointer: 'name'. 'name' was null at line 'n' (lifetime.1).
#pragma warning (disable: 26489) // Don't dereference a pointer that may be invalid: 'name'. 'name' may have been invalidated at line 'n' (lifetime.1).
#pragma warning (disable: 26490) // Don't use reinterpret_cast (type.1).
#pragma warning (disable: 26492) // Don't use const_cast to cast away const or volatile (type.3).
#pragma warning (disable: 26493) // Don't use C-style casts (type.4).
#pragma warning (disable: 26496) // The variable 'name' is assigned only once, mark it as const (con.4).
#pragma warning (disable: 26497) // The function 'name' could be marked constexpr if compile-time evaluation is desired (f.4).
#pragma warning (disable: 26812) // The enum type 'type' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
#pragma warning (disable: 26814) // The const variable 'name' can be computed at compile-time. Consider using constexpr (con.5).
#pragma warning (disable: 26822) // Dereferencing a possibly null pointer '...' (lifetime.1).
#pragma warning (disable: 26823) // Dereferencing a possibly null pointer '...' (lifetime.1).
#pragma warning (disable: 28125) // The function must be called from within a try/except block
#pragma warning (disable: 28159) // Consider using another function instead
#pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665
#define _tx_thread __declspec (thread)
#define _tx_decltype(value) decltype (value)
#if !defined (_CLANG_VER)
#pragma setlocale ("russian") // Set source file encoding, see also _TX_CODEPAGE
#if !defined (NDEBUG)
#pragma check_stack ( on) // Turn on stack probes at runtime
#pragma strict_gs_check (push, on) // Detects stack buffer overruns
#endif
#endif
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (__INTEL_COMPILER)
#pragma warning (disable: 174) // Remark: expression has no effect
#pragma warning (disable: 304) // Remark: access control not specified ("public" by default)
#pragma warning (disable: 444) // Remark: destructor for base class "..." is not virtual
#pragma warning (disable: 522) // Remark: function "..." redeclared "inline" after being called
#pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order
#pragma warning (disable: 1684) // Conversion from pointer to same-sized integral type (potential portability problem)
#endif
//-----------------------------------------------------------------------------------------------------------------
#if (defined (_GCC_VER) && (_GCC_VER < 472) || \
defined (_MSC_VER) && (_MSC_VER < 1600)) // Minimum requirements are now GCC 4.7.2 or MSVC 10.0 (2010)
#ifdef __GNUC__
#error
#error ---------------------------------------------------------------------------------------
#endif
#error TXLib.h: This version will NOT work with GCC < 4.7.2 or MS Visual Studio < 2010, sorry.
#error
#error Please use TXLib.h previous stable version/revision OR upgrade your compiler.
#error ---------------------------------------------------------------------------------------
#error
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (_GCC_VER) && (_GCC_VER >= 492)
#if defined (TX_USE_SPEAK) && !__has_include ()
#ifdef __GNUC__
#error
#error ---------------------------------------------------------------------------------------
#endif
#error You have defined TX_USE_SPEAK, but your compiler do NOT have the library .
#error
#error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API
#error nesessary for txSpeak() to work.
#error ---------------------------------------------------------------------------------------
#error
#endif
#endif
//-----------------------------------------------------------------------------------------------------------------
#if !defined (WINVER)
#define WINVER 0x0500 // Defaults to Windows 2000
#define WINDOWS_ENABLE_CPLUSPLUS // Allow use of type-limit macros in ,
#endif // they are allowed by default if WINVER >= 0x0600.
#if !defined (_WIN32_WINNT)
#define _WIN32_WINNT WINVER // Defaults to the same as WINVER
#endif
#if !defined (_WIN32_IE)
#define _WIN32_IE WINVER // Defaults to the same as WINVER
#endif
#define stristr( str1, str2 ) Win32::StrStrIA ((str1), (str2))
#define stristrw( str1, str2 ) Win32::StrStrIW ((str1), (str2))
//-----------------------------------------------------------------------------------------------------------------
#define _USE_MATH_DEFINES 1 // Math.h's M_PI etc.
#define __STDC_FORMAT_MACROS 1 // PRIu64 and other PR... macros
#define __STDC_WANT_LIB_EXT1__ 1 // String and output *_s functions
#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS // Wow, how long. Kudos, Clang
#define _ALLOW_RTCc_IN_STL 1 // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc.
#define NOMINMAX 1 // Preventing 'min' and 'max' defines in Windows.h
#if defined (_DEBUG)
#define _SECURE_SCL 1 // Enable checked STL iterators to throw an exception on incorrect use
#define _HAS_ITERATOR_DEBUGGING 1
#define _LIBCPP_DEBUG 1
#endif
#if defined (_MSC_VER) && defined (_DEBUG)
#define _CRTDBG_MAP_ALLOC // Enable MSVCRT debug heap
#define _new_dbg new (_NORMAL_BLOCK, __FILE__, __LINE__)
#define NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)
#else
#define _new_dbg new
#define NEW new
#endif
#if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015
#define _SECURE_SCL_THROWS 1
#endif
#define tx_noreturn __attribute__ (( noreturn ))
#define tx_nodiscard __attribute__ (( warn_unused_result ))
#define tx_deprecated __attribute__ (( deprecated ))
#define tx_printfy( formatArgN ) __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) ))
#define tx_scanfy( formatArgN ) __attribute__ (( format (scanf, (formatArgN), (formatArgN)+1) ))
#if defined (_TX_CPP11)
#define _tx_delete = delete
#define _tx_default = default
#define _tx_override override
#define _tx_final final
#else
#define _tx_delete
#define _tx_default
#define _tx_override
#define _tx_final
#endif
namespace std { enum nomeow_t { nomeow }; } // Vital addition to the C++ standard. TODO: Should contact C++ std committee.
//-----------------------------------------------------------------------------------------------------------------
//! @} @endcond
//}
//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
//{ The Includes
//-----------------------------------------------------------------------------------------------------------------
#if defined (_MSC_VER)
#pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o
#pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
#pragma warning (disable: 4005) // 'name': macro redefinition
#endif
//-----------------------------------------------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if !defined (__CYGWIN__)
#include
#include
#endif
#if defined (TX_COMPILED)
#define WIN32_LEAN_AND_MEAN
#endif
#include
#include
//-----------------------------------------------------------------------------------------------------------------
//{ Compiler- and platform-specific
//! @name Адаптация к компиляторам и платформам
//-----------------------------------------------------------------------------------------------------------------
#if defined (_MSC_VER)
#pragma warning (pop) // MSVC: Restore max level
#endif
#if defined (__STRICT_ANSI__UNDEFINED)
#define __STRICT_ANSI__ // Redefine back
#endif
#if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED)
#define strncpy_s( dest, sizeof_dest, src, count ) ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
#define wcsncpy_s( dest, sizeof_dest, src, count ) ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
#define strncat_s( dest, sizeof_dest, src, count ) ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) )
#define strerror_s( buf, sizeof_buf, code ) ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) )
#define strtok_s( buf, delim, ctx ) ( (void)(ctx), strtok ((buf), (delim)) )
#define fopen_s( file, name, mode ) ( *(file) = fopen ((name), (mode)) )
#define _strlwr_s( str, sizeof_str ) ( _strlwr (str) )
#define ctime_s( buf, sizeof_buf, time ) ( strncpy ((buf), ctime (time), (sizeof_buf)-1) )
#define _controlfp_s( oldCtl, newCtl, mask ) ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 )
#define _snprintf_s snprintf
#define _vsnprintf_s( str, sz, trunc, format, arg ) _vsnprintf (str, sz, format, arg)
#endif
#if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) )
#define getenv_s( sz, buf, sizeof_buf, name ) ( (void)(sz), strncpy ((buf), getenv (name), (sizeof_buf)-1) )
#endif
#if defined (__CYGWIN__)
#undef __STRICT_ANSI__
typedef void _exception;
#define _O_TEXT O_TEXT
#define _fdopen fdopen
#define _flushall() fflush (NULL)
#define _getcwd getcwd
#define _getpid getpid
#define _stricmp strcasecmp
#define _strlwr strlwr
#define _strnicmp strncasecmp
#define _unlink unlink
#define _vsnprintf vsnprintf
#define _access access
#define _strdup strdup
#define getch _getch
#define putch _putch
#define kbhit _kbhit
#endif
#if !defined (PRId64) || \
defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32
#undef PRId64
#undef PRIi64
#undef PRIo64
#undef PRIu64
#undef PRIx64
#undef PRIX64
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#endif
//}
//-----------------------------------------------------------------------------------------------------------------
//}
//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
//{ The namespaces
//-----------------------------------------------------------------------------------------------------------------
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Анонимное пространство имен для защиты от конфликтов при сборке многофайлового проекта.
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
namespace { namespace TX { }}
#endif
/*! @cond INTERNAL */
//-----------------------------------------------------------------------------------------------------------------
#if defined (TX_COMPILED) && defined (TX_COMPILING)
#undef TX_COMPILED
#endif
#if !defined (TX_COMPILED) && !defined (TX_COMPILING)
#define _TX_BEGIN_NAMESPACE namespace { namespace TX {
#define _TX_END_NAMESPACE } }
#else
#define _TX_BEGIN_NAMESPACE namespace TX {
#define _TX_END_NAMESPACE }
#endif
//-----------------------------------------------------------------------------------------------------------------
_TX_BEGIN_NAMESPACE
/*! @endcond */
//}
//-----------------------------------------------------------------------------------------------------------------
//=================================================================================================================
//{ TXLIB INTERFACE
// Интерфейс библиотеки
//=================================================================================================================
//=================================================================================================================
//{ Initialization
//! @name Инициализация библиотеки
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Создание окна рисования
//!
//! @param sizeX Размер окна по горизонтали (в пикселях).
//! @param sizeY Размер окна по вертикали (в пикселях).
//! @param centered Центрирование окна на дисплее. Необязательно. Если не указано, то окно центрируется.
//!
//! @return Дескриптор (системный номер) окна TXLib. Если окно не создано, возвращается NULL.
//!
//! @note Устанавливаются параметры рисования по умолчанию, см. функцию txSetDefaults().
//!
//! @warning Если используется многофайловый проект (с раздельной компиляцией), то графические функции TXLib,
//! вызванные из файла проекта, будут работать только с тем окном, которое создано в этом же файле
//! проекта. Если проект состоит, скажем, из файлов @c main.cpp и @c game.cpp, и в файле @c main.cpp
//! создается графическое окно, то функции из @c game.cpp не смогут рисовать в нем. (Однако @c game.cpp
//! сможет создать свое собственное окно.) @n
//! Если такой программе нужно одно окно, то в проект следует включить файл, ответственный за рисование,
//! скажем, @c graphics.cpp, и выводить графику только через функции этого файла. Такой файл (или
//! библиотеку) в больших проектах часто называют графическим движком. @nn
//! Это влияет не только на фунции рисования, но и на такие функции, как @ref txMouseX(), @ref txMouseY(),
//! @ref txMousePos() и другие, прямо или косвенно зависящие от создания окна рисования. @nn
//! То же касается и использования TXLib в @b DLL.
//!
//! @note Вспомогательные окна могут создаваться по одному на каждый файл многофайлового проекта или загруженную
//! DLL. Для закрытия вспомогательных окон используется txDestroyWindow(). Для закрытия главного надо
//! выйти из main().
//!
//! @warning Одновременное создание нескольких окон не потокобезопасно (not thread-safe). @nn
//! Многооконная программа на TXLib тормозит, да и однооконная тоже не отличается высокой скоростью. Чтобы
//! избавиться от этого, бросьте TXLib и используйте другие оконные библиотеки:
//! Qt, wxWidgets, GTK+ и т.д., или
//! библиотеки, специально разработанные для создания игр: SFML (она
//! простая), SDL и другие. Вы можете написать и свою собственную оконную
//! библиотеку, основанную на OpenGL @strike и получится SFML или SDL:),
//! @endstrike или DirectX. Помните, что цель TXLib -- облегчить первые шаги, но потом стать ненужной.
//!
//! @see txOK(), txWindow(), txDC(), txVideoMemory(), _txWindowStyle, TX_CONSOLE_MODE, TX_CONSOLE_FONT,
//! _txCursorBlinkInterval, _txWindowUpdateInterval, _TX_NOINIT, _TX_ALLOW_TRACE, TX_TRACE
//!
//! @usage @code
//! txCreateWindow ( 800, 600); // Окно 800х600, центрировано
//! txCreateWindow (1024, 768, false); // Окно 1024х768, не центрировано
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HWND txCreateWindow (double sizeX, double sizeY, bool centered = true);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает холст (дескриптор контекста рисования, HDC) окна рисования TXLib.
//!
//! @return Дескриптор (системный номер, handler) контекста рисования (device context, DC) холста TXLib (TXLib HDC).
//!
//! @note Возвращаемый дескриптор -- @b не оконный контекст рисования окна TXLib. TXLib реализует двойную
//! буферизацию. Все рисовательные действия происходят со скрытым HDC, находящемся в памяти, и его
//! содержимое периодически автоматически копируется на экран. Это иногда приводит к мерцанию.
//! Автоматическое копирование можно выключить функцией txBegin() и обратно включить функцией txEnd(),
//! в этом случае содержимое окна можно перерисовать функциями txRedrawWindow() или txSleep(). @nn
//! Дополнительную информацию об автоматическом обновлении см. в функциях txBegin(), txEnd(), txUpdateWindow(),
//! txRedrawWindow() и txSleep().
//!
//! @note Этот HDC возвращается в виде ссылки, что позволяет подменить его. Тогда TXLib будет периодически копировать
//! на экран изображение уже из вашего буфера. Перед подменой надо сохранить старый дескриптор или освободить
//! его с помощью txDeleteDC(). Во время подмены рисование должно быть заблокировано с помощью txLock()
//! и после разблокировано с помощью txUnlock().
//!
//! @see txWindow(), txBegin(), txEnd(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! txBitBlt (txDC(), 0, 0, 100, 100, txDC(), 0, 0);
//! txBitBlt (txDC(), 100, 0, 100, 100, txDC(), 0, 0);
//! txBitBlt (txDC(), 0, 100, 100, 100, txDC(), 0, 0);
//! txBitBlt (txDC(), 100, 100, 100, 100, txDC(), 0, 0);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline HDC& txDC() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает буфер памяти, связанный с холстом (HDC) TXLib.
//!
//! @return Указатель на массив структур RGBQUAD, -- буфера памяти, связанного с HDC холста TXLib.
//!
//! Прямой доступ к буферу памяти HDC позволяет работать с ним с очень высокой скоростью. Правда, рисовать
//! можно только отдельные пиксели. Это полезно, в основном, если вы пишете собственный графический рендер
//! (так напишите же его!).
//!
//! Буфер памяти HDC -- двумерный массив, размеры которого соответствуют ширине и высоте холста (HDC). Но он
//! возвращается как указатель на одномерный массив, поэтому двумерную адресацию к нему надо вести вручную.
//!
//! @note Кроме того, "Y-ось" этого массива направлена @b вверх, а не вниз, как в окне TXLib. Поэтому для нужного
//! пикселя его смещение от начала массива нужно рассчитывать с помощью формулы x + (-y + sizeY) * sizeX,
//! где @c sizeX и @c sizeY -- размеры окна TXLib. Иначе изображение будет перевернуто вверх ногами.
//!
//! @warning Будьте осторожны, не выходите за границы массива, последствия будут непредсказуемыми.
//!
//! @note Во время работы с буфером автоматическое обновление окна TXLib должно быть заблокировано с помощью txLock()
//! и после разблокировано с помощью txUnlock(). @nn
//!
//! @note HDC TXLib -- @b не оконный контекст рисования окна TXLib. TXLib реализует двойную буферизацию. Все
//! рисовательные действия происходят со скрытым HDC, находящемся в памяти (его возвращает txGetDC()),
//! и его содержимое периодически автоматически копируется на экран. Это иногда приводит к мерцанию.
//! Автоматическое копирование можно выключить функцией txBegin() и обратно включить функцией txEnd(),
//! в этом случае содержимое окна можно перерисовать функциями txRedrawWindow() или txSleep(). @nn
//! Дополнительную информацию об автоматическом обновлении см. в функциях txBegin(), txEnd(), txUpdateWindow(),
//! txRedrawWindow() и txSleep().
//!
//! @see txCreateDIBSection(), txDC(), txWindow(), txBegin(), txEnd(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! Пример см. в файле PhongDemo.cpp из папки TX\Examples\Demo.
//! Также см. пример в помощи по функции txCreateDIBSection().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline RGBQUAD* txVideoMemory() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Установка параметров рисования по умолчанию.
//!
//! @param dc Дескриптор контекста рисования (холста) для установки параметров. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @par Параметры по умолчанию:
//! - Линии -- цвет белый (TX_WHITE), толщина 1
//! - Заливка -- цвет белый (TX_WHITE)
//! - Шрифт -- Системный, цвет белый (TX_WHITE)
//! - Растровая операция -- копирование цвета (R2_COPYPEN)
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txSelectFont()
//!
//! @usage @code
//! txSetDefaults();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSetDefaults (HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Проверка правильности работы библиотеки
//!
//! @return Состояние библиотеки: true -- библиотека в порядке, false -- не в порядке.
//!
//! "Библиотека не в порядке" означает, что ее внутренние данные неверны. Самая простая причина -
//! не открыто окно, однако могут быть и другие проблемы.
//!
//! @see txCreateWindow()
//!
//! @usage @code
//! txCreateWindow (800, 600);
//! if (!txOK())
//! {
//! txMessageBox ("Не смогла создать окно", "Извините", MB_ICONSTOP);
//! return;
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline bool txOK() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает размер окна, картинки или холста в виде структуры POINT.
//!
//! @param dc Дескриптор контекста рисования (холста) с загруженной или созданной картинкой, размеры которого
//! нужно определить. Необязателен. Если не указан или равен txDC(), возвращаются размеры окна TXLib.
//!
//! @return Размер окна, картинки или холста в виде структуры POINT, содержащей компоненты @c x и @c y.
//!
//! @note Если окно не создано, возвращается размер экрана.
//!
//! @see txGetExtentX(), txGetExtentY()
//!
//! @usage @code
//! txCreateWindow (800, 600);
//!
//! HDC image = txLoadImage ("TX/Wizard/TX Application/VS/HTML/1033/TX Application_resize.bmp");
//!
//! POINT center = { txGetExtentX() / 2, txGetExtentY() / 2 };
//! POINT size = txGetExtent (image);
//!
//! txBitBlt (center.x, center.y, image); // This is krivo
//!
//! txBitBlt (center.x - size.x/2, center.y - size.y/2, image); // This is centered
//!
//! txSetColor (TX_WHITE, 3);
//! txSetFillColor (TX_TRANSPARENT);
//! txCircle (center.x, center.y, hypot (size.x, size.y) / 2);
//! txCircle (center.x, center.y, 10);
//!
//! txDeleteDC (image);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetExtent (HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает ширину окна или холста.
//!
//! @param dc Дескриптор контекста рисования (холста), ширина которого возвращается. Необязателен. Если не указан
//! или равен txDC(), возвращаются ширина окна TXLib.
//!
//! @return Ширина окна рисования.
//!
//! @note Если окно не создано, возвращается ширина экрана.
//!
//! @see txGetExtent(), txGetExtentY()
//!
//! @usage @code
//! txSetTextAlign (TA_CENTER);
//! txTextOut (txGetExtentX() / 2, 100, "Oh, oh, you're in the [army]middle now");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает высоту окна или холста.
//!
//! @param dc Дескриптор контекста рисования (холста), высота которого возвращается. Необязателен. Если не указан
//! или равен txDC(), возвращается высота окна TXLib.
//!
//! @return Высота окна рисования.
//!
//! @note Если окно не создано, возвращается высота экрана.
//!
//! @see txGetExtent(), txGetExtentX()
//!
//! @usage @code
//! void DrawHouse (int height);
//! ...
//! DrawHouse (txGetExtentY() / 2);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает дескриптор окна рисования
//!
//! @return Дескриптор (системный номер, handler) окна холста.
//!
//! @see txDC(), txVideoMemory(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! SetWindowText (txWindow(), "Новые заголовки -- теперь и в ваших окнах!");
//! txMessageBox ("Распишитесь", "Получите", MB_ICONINFORMATION);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline HWND txWindow() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Возвращает строку с информацией о текущей версии библиотеки.
//!
//! @return Строка с информацией о текущей версии библиотеки.
//!
//! @usage @code
//! printf ("I personally love %s\n", txVersion());
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline const char* txVersion() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Возвращает номер версии библиотеки.
//!
//! @return Номер версии библиотеки.
//!
//! @usage @code
//! printf ("My magic number is %x\n", txVersionNumber());
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline unsigned txVersionNumber() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Возвращает имя исполняемого файла или изначальный заголовок окна TXLib.
//!
//! @param fileNameOnly Возвратить только полное имя исполняемого файла, полученного через Win32 функцию
//! GetFileModuleName (NULL, ...). Необязательно. Если не указано, то возвращается полное
//! имя исполняемого файла.
//!
//! @return fileNameOnly = true: Имя исполняемого файла. @n
//! fileNameOnly = false: Изначальный заголовок окна TXLib.
//!
//! @note Возвращается @b статическая строка.
//!
//! @see txWindow(), txVersion(), txVersionNumber()
//!
//! @usage @code
//! printf ("Смотрите на заголовок окна!");
//!
//! for (int done = 0; done <= 100; done++)
//! {
//! char title [1024] = "";
//! sprintf (title, "%s - [%-10.*s] %d%%", txGetModuleFileName (false), done/10, "||||||||||", done);
//!
//! SetWindowText (txWindow(), title);
//! SetWindowText (Win32::GetConsoleWindow(), title);
//! txSleep (50);
//! }
//!
//! txMessageBox ("Вот такой вот progress bar", "TXLib forever)");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard;
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выводит различные сообщения в окне с помощью функции MessageBox.
//!
//! @param text Текст сообщения. В принципе, необязательно, но зачем вы тогда меня вызывали?
//! @param header Заголовок сообщения. Необязательно.
//! @param flags Флаги отображения сообщения. Необязательно.
//!
//! @return Значение, возвращаемое функцией MessageBox.
//!
//! @warning Текст не должен превышать _TX_BIGBUFSIZE символов, а заголовок -- _TX_BIGBUFSIZE символов, иначе они
//! обрезаются.
//!
//! @note Вместо txMessageBox (text, header, flags) можно использовать стандартную функцию Win32
//! MessageBox (txWindow(), text, header, flags). Отличия txMessageBox в том, что она
//! автоматически подставляет окно-родитель, и в том, что при выводе в окно строчки переводятся в формат
//! UNICODE. Это важно лишь в том случае, когда в региональных настройках контрольной панели Windows
//! неверно установлена кодовая страница для программ, не поддерживающих UNICODE. В остальных случаях
//! нужды в @c txMessageBox нет.@nn
//!
//! @note При отображении окна @c txMessageBox программу можно завершить, нажав клавиши клавиатуры @c Shift,
//! @c Control и @c Alt одновременно с нажатием мышкой на кнопку окна @c [Отмена] или @c [Cancel]. Это
//! полезно, если окно @c txMessageBox постоянно отображается в цикле и программу нельтзя завершить
//! нажатием на кнопку закрытия основного окна.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txNotifyIcon(), txSpeak(), txStackBackTrace()
//!
//! @usage @code
//! if (txMessageBox ("Получилось?", "Прочти меня", MB_YESNO) == IDYES)
//! {
//! MessageBox (txWindow(), "Хватит и обычного MessageBox()", "Win32 сообщает", 0);
//! }
//! else
//! txMessageBox ("Спасаем от кракозябл вместо русских букв, без регистрации и СМС.");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает",
unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Устанавливает Progress bar окна на панели задач.
//! @strike Весело и вкусно @endstrike Красиво и иногда полезно.
//!
//! @param percent Процент завершения операции, от 0 до 100, определяющий размер Progress bar'a на панели задач.
//! @param type Тип Progress bar'a. задается одним из флагов Win32::TBPF_NORMAL, Win32::TBPF_ERROR,
//! Win32::TBPF_PAUSED, Win32::TBPF_NOPROGRESS, Win32::TBPF_INDETERMINATE. Описание флагов
//! смотрите в Интернете. Необязательно. Если не указано, то используется Win32::TBPF_NORMAL.
//! @param wnd Окно для задания Progress bar'a. Необязательно. Если не указано, то используется txWindow().
//!
//! @return Ошибка выполнения функции. Если возвращаемое значение равно 0 @c (S_OK), то операция успешна.
//!
//! @usage @code
//! txSetProgress (146, Win32::TBPF_NORMAL); // 146%, or 100%, that is the question.
//! // Whether 'tis nobler in the mind to suffer...
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL);
//}
//=================================================================================================================
//=================================================================================================================
//{ Setting the parameters
//! @name Установка цветов и режимов рисования
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Названия предопределенных цветов.
//!
//! См. TX_BLACK, TX_BLUE и другие цвета в списке выше.
//!
//! Если кому-то эти цвета не нравятся (что неудивительно), всегда можно сделать свои с помощью RGB().
//! См. пример ниже.
//!
//! @see txSetColor(), txSetFillColor(), txGetColor(), txGetFillColor(), txGetPixel(), RGB()
//!
//! @usage @code
//! #include "TXLib.h"
//!
//! const COLORREF MY_DEEP_ROMANTIC_BLUE = RGB ( 0, 0, 129),
//! MY_SHINING_MOONLIGHT = RGB (128, 255, 64);
//! ...
//!
//! txSetColor (TX_YELLOW); // Устанавливаем желтый цвет линий
//! txSetFillColor (TX_NULL); // Заливка фигур будет прозрачная
//!
//! txSetFillColor (MY_DEEP_ROMANTIC_BLUE); // А.И. Куинджи, "Лунная ночь на Днепре"
//! txSetColor (MY_SHINING_MOONLIGHT); // http://tanais.info/art/pic/kuindzhi1.html
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
const COLORREF
#ifdef FOR_DOXYGEN_ONLY
enum txColors {
#endif
TX_BLACK = RGB ( 0, 0, 0), //!< Черный цвет.
TX_BLUE = RGB ( 0, 0, 128), //!< Темно-синий цвет. Плохо виден.
TX_GREEN = RGB ( 0, 128, 0), //!< Зеленый цвет.
TX_CYAN = RGB ( 0, 128, 128), //!< Бирюзовый цвет.
TX_RED = RGB (128, 0, 0), //!< Темно-красный цвет. Слишком темный.
TX_MAGENTA = RGB (128, 0, 128), //!< Темно-малиновый цвет.
TX_BROWN = RGB (128, 128, 0), //!< Коричневый цвет. Некрасивый. Do it yourself with RGB().
TX_ORANGE = RGB (255, 128, 0), //!< Оранжевый цвет.
TX_GRAY = RGB (160, 160, 160), //!< Серый цвет.
TX_DARKGRAY = RGB (128, 128, 128), //!< Темно-серый цвет.
TX_LIGHTGRAY = RGB (192, 192, 192), //!< Светло-серый цвет.
TX_LIGHTBLUE = RGB ( 0, 0, 255), //!< Светло-синий цвет.
TX_LIGHTGREEN = RGB ( 0, 255, 128), //!< Светло-зеленый цвет.
TX_LIGHTCYAN = RGB ( 0, 255, 255), //!< Светло-бирюзовый цвет.
TX_LIGHTRED = RGB (255, 0, 128), //!< Светло-красный цвет. Не самого лучшего оттенка.
TX_LIGHTMAGENTA = RGB (255, 0, 255), //!< Светло-малиновый цвет. Еще менее лучшего оттенка.
TX_PINK = RGB (255, 128, 255), //!< Розовый гламурный :)
TX_YELLOW = RGB (255, 255, 128), //!< Желтый цвет.
TX_WHITE = RGB (255, 255, 255), //!< Белый цвет.
TX_TRANSPARENT = 0xFFFFFFFF, //!< Прозрачный цвет. Отключает рисование. //-V112
TX_NULL = TX_TRANSPARENT, //!< Прозрачный цвет. Отключает рисование.
TX_BLM = TX_BLACK, //!< Альтернативный политкорректный трендовый цвет!
TX_white = TX_WHITE, //!< BLM-compatible name for this color.
// Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB()
TX_HUE = 0x04000000, //!< Цветовой тон цвета в модели HSL, @b [0; 255]
TX_SATURATION = 0x05000000, //!< Насыщенность цвета в модели HSL, @b [0; 255]
TX_LIGHTNESS = 0x06000000; //!< Светлота цвета в модели HSL, @b [0; 255]
#ifdef FOR_DOXYGEN_ONLY
};
#endif
//! @cond INTERNAL
#define TX_GREY TX_GRAY
#define TX_DARKGREY TX_DARKGRAY
#define TX_LIGHTGREY TX_LIGHTGRAY
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Создает (смешивает) цвет из трех базовых цветов (компонент).
//!
//! @param red Количество красного цвета в интервале [0; 255].
//! @param green Количество зеленого цвета в интервале [0; 255].
//! @param blue Количество синего цвета в интервале [0; 255].
//!
//! @return Созданный цвет в формате COLORREF.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txExtractColor(),
//! txRGB2HSL(), txHSL2RGB()
//!
//! @usage @code
//! txSetColor (RGB (255, 128, 0)); // Красный + половина зеленого = оранжевый
//!
//! int red = 20, green = 200, blue = 20;
//! COLORREF color = RGB (red, green, blue);
//! txSetFillColor (color);
//!
//! const COLORREF SKY_COLOR = RGB (0, 128, 255); // Создаем константу для нового цвета
//!
//! ...
//! txSetFillColor (SKY_COLOR); // Используем ее
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
COLORREF RGB (int red, int green, int blue);
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает текущий цвет и толщину линий, цвет текста.
//!
//! @param color Цвет линий и текста, см. txColors, RGB().
//! @param thickness Толщина линий. Необязательна. Если не указана, то 1 пиксель.
//! @param dc Дескриптор контекста рисования (холста) для установки цвета. Необязателен.
//!
//! @return Перо, созданное при установке цвета. При ошибке возвращается NULL.
//!
//! @see txSetFillColor(), txGetColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage @code
//! txSetColor (TX_YELLOW); // Цвет линий будет желтым
//! txSetColor (RGB (255, 128, 0), 5); // Оранжевые линии толщиной 5 пикселей
//!
//! txSetColor (RGB (255, 255, 0)); // Желтый = Красный + зеленый (другой способ указания цвета)
//! txSetColor (RGB (255, 128, 64)); // Нечто оранжевое
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC());
//! @cond INTERNAL
#define txSetColour txSetColor
//! @endcond
//! @cond INTERNAL
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает текущий цвет линий и текста.
//!
//! @param red Количество красного цвета в интервале [0; 1].
//! @param green Количество зеленого цвета в интервале [0; 1].
//! @param blue Количество синего цвета в интервале [0; 1].
//!
//! @return Цвет RGB, соответствующий указанной комбинации основных цветов. При ошибке возвращается CLR_INVALID.
//!
//! @see txSetColor(), txSetFillColor(), txGetColor(), txGetFillColor()
//}----------------------------------------------------------------------------------------------------------------
COLORREF txColor (double red, double green, double blue);
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает текущий цвет линий и текста.
//!
//! @param dc Дескриптор контекста рисования (холста) для возврата цвета. Необязателен.
//!
//! @return Текущий цвет линий и текста, см. txColors, RGB().
//!
//! @see txSetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage @code
//! COLORREF color = txGetColor();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает текущий цвет заполнения фигур.
//!
//! @param color Цвет заполнения, см. txColors, RGB().
//! @param dc Дескриптор контекста рисования (холста) для установки цвета. Необязателен.
//!
//! @return Кисть, созданная при установке цвета. При ошибке возвращается NULL.
//!
//! @see txSetColor(), txGetFillColor(), txGetColor(), txColors, RGB()
//!
//! @usage @code
//! txSetFillColor (TX_LIGHTGREEN);
//! txSetFillColor (RGB (255, 128, 0));
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC());
//! @cond INTERNAL
#define txSetFillColour txSetFillColor
//! @endcond
//! @cond INTERNAL
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает текущий цвет заполнения фигур.
//!
//! @param red Количество красного цвета в интервале [0; 1].
//! @param green Количество зеленого цвета в интервале [0; 1].
//! @param blue Количество синего цвета в интервале [0; 1].
//!
//! @return Цвет RGB, соответствующий указанной комбинации основных цветов. При ошибке возвращается CLR_INVALID.
//!
//! @see txSetFillColor(), txSetColor(), txGetFillColor(), txGetColor()
//}----------------------------------------------------------------------------------------------------------------
COLORREF txFillColor (double red, double green, double blue);
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает текущий цвет заполнения фигур.
//!
//! @param dc Дескриптор контекста рисования (холста) для возврата цвета. Необязателен.
//!
//! @return Текущий цвет заполнения фигур, см. txColors, RGB().
//!
//! @see txSetFillColor(), txSetColor(), txGetColor(), txColors, RGB()
//!
//! @usage @code
//! COLORREF color = txGetFillColor();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Извлекает цветовую компоненту (цветовой канал) из смешанного цвета.
//!
//! @param color Смешанный цвет.
//! @param component Извлекаемая компонента, см. txColors.
//!
//! @return Цветовая компонента, см. txColors.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txExtractColor(),
//! txRGB2HSL(), txHSL2RGB()
//!
//! @usage @code
//! int red = txExtractColor (color, TX_RED);
//! int lightness = txExtractColor (TX_BLUE, TX_LIGHTNESS); // В интервале от 0 до 255
//!
//! Другие примеры см. в функциях AppearText(), AppearEarth() Примера 5 ("Циклы").
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Преобразует цвет из формата RGB в формат HSL.
//!
//! @param rgbColor Преобразуемый цвет в формате @strike ЕГЭ @endstrike RGB.
//!
//! @return Созданный цвет в виде COLORREF.
//!
//! Формат @b RGB определяется как
//!
//! - Красная компонента цвета (Red), от 0 до 255.
//! - Зеленая компонента цвета (Green), от 0 до 255.
//! - Синяя компонента цвета (Blue), от 0 до 255.
//!
//! Формат @b HSL определяется как
//!
//! - Цветовой тон (Hue), от 0 до @b 255 (@b не до 360).
//! - Насыщенность (Saturation), от 0 до @b 255 (@b не до 100).
//! - Светлота (Lightness), от 0 до @b 255 (@b не до 100).
//!
//! @note Точность преобразования не идеальна. При преобразовании RGB->HSL->RGB может набежать погрешность до 5.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txExtractColor(),
//! txRGB2HSL(), txHSL2RGB()
//!
//! @usage @code
//! COLORREF hslColor = txRGB2HSL (TX_RED);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Преобразует цвет из формата HSL в формат RGB.
//!
//! @param hslColor Преобразуемый цвет в формате HSL.
//!
//! @return Созданный цвет в виде COLORREF.
//!
//! Формат @b RGB определяется как
//!
//! - Красная компонента цвета (Red), от 0 до 255.
//! - Зеленая компонента цвета (Green), от 0 до 255.
//! - Синяя компонента цвета (Blue), от 0 до 255.
//!
//! Формат @b HSL определяется как
//!
//! - Цветовой тон (Hue), от 0 до @b 255 (@b не до 360).
//! - Насыщенность (Saturation), от 0 до @b 255 (@b не до 100).
//! - Светлота (Lightness), от 0 до @b 255 (@b не до 100).
//!
//! @note Точность преобразования не идеальна. При преобразовании RGB->HSL->RGB может набежать погрешность до 5.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txExtractColor(),
//! txRGB2HSL(), txHSL2RGB()
//!
//! @usage @code
//! int hue = 10, saturation = 128, lightness = 128;
//! COLORREF hslColor = RGB (hue, saturation, lightness);
//! txSetColor (txHSL2RGB (hslColor));
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard;
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Drawing
//! @name Рисование фигур
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Стирает холст текущим цветом заполнения.
//!
//! @param dc Дескриптор контекста рисования (холста) для стирания. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @see txSetFillColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage @code
//! txSetFillColor (TX_BLUE); // Кто-то хотел синий фон?
//! txClear();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txClear (HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует пиксель (точку на экране).
//!
//! @param x X-координата точки.
//! @param y Y-координата точки.
//! @param color Цвет точки, см. txColors, RGB().
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @see txGetPixel(), txColors, RGB(), txVideoMemory()
//!
//! @usage @code
//! txSetPixel (100, 100, TX_LIGHTRED); // Красная точка! http://www.google.ru/search?q=коты+и+красная+точка
//!
//! txSetPixel (100, 100, RGB (255, 128, 0));
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC());
//! @cond INTERNAL
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует пиксель (точку на экране).
//!
//! @param x X-координата точки.
//! @param y Y-координата точки.
//! @param red Количество красного цвета в интервале [0; 1].
//! @param green Количество зеленого цвета в интервале [0; 1].
//! @param blue Количество синего цвета в интервале [0; 1].
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @see txSetPixel(), txGetPixel(), txVideoMemory()
//!
//! @usage @code
//! txSetPixel (100, 100, 1.0, 0.5, 0.25);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC());
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает текущий цвет точки (пикселя) на экране.
//!
//! @param x X-координата точки.
//! @param y Y-координата точки.
//! @param dc Дескриптор контекста рисования (холста) для возврата цвета. Необязателен.
//!
//! @return Текущий цвет пикселя, см. txColors, RGB().
//!
//! @see txSetPixel(), txColors, RGB(), txVideoMemory()
//!
//! @usage @code
//! COLORREF color = txGetPixel (100, 200);
//!
//! if (txGetPixel (x, y) == TX_RED)
//! CarCrash (x, y); // Mess with the red -- die like the rest
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует линию.
//!
//! @param x0 X-координата начальной точки.
//! @param y0 Y-координата начальной точки.
//! @param x1 X-координата конечной точки.
//! @param y1 Y-координата конечной точки.
//! @param dc Дескриптор контекста рисования (холста) для рисования линии. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линии задается функцией txSetColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txLine (10, 50, 100, 500); // Правда бедный примерчик, да?
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует прямоугольник.
//!
//! @param x0 X-координата верхнего левого угла.
//! @param y0 Y-координата верхнего левого угла.
//! @param x1 X-координата нижнего правого угла.
//! @param y1 Y-координата нижнего правого угла.
//! @param dc Дескриптор контекста рисования (холста) для рисования прямоугольника. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txRectangle (100, 200, 400, 500);
//!
//! Win32::RoundRect (txDC(), 100, 200, 400, 500, 30, 30); // И такое есть. Погуглите "RoundRect function".
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует ломаную линию или многоугольник.
//!
//! @param points Массив структур POINT с координатами точек.
//! @param numPoints Количество точек в массиве.
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//! Если нужно нарисовать ломаную линию, а не многоугольник, используйте прозрачный цвет заполнения (TX_TRANSPARENT).
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! POINT star[5] = {{150, 300}, {200, 100}, {250, 300}, {100, 200}, {300, 200}};
//! txPolygon (star, 5); // Я кривая звездочка
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует эллипс.
//!
//! @param x0 X-координата верхнего левого угла прямоугольника, описанного вокруг эллипса.
//! @param y0 Y-координата верхнего левого угла описанного прямоугольника.
//! @param x1 X-координата нижнего правого угла описанного прямоугольника.
//! @param y1 Y-координата нижнего правого угла описанного прямоугольника.
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txEllipse (100, 100, 300, 200);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует окружность или круг.
//!
//! @param x X-координата центра.
//! @param y Y-координата центра.
//! @param r Радиус.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txCircle (100, 100, 10);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txCircle (double x, double y, double r);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует дугу эллипса.
//!
//! @param x0 X-координата верхнего левого угла прямоугольника, описанного вокруг эллипса, содержащего
//! дугу (см. txEllipse).
//! @param y0 Y-координата верхнего левого угла прямоугольника.
//! @param x1 X-координата нижнего правого угла прямоугольника.
//! @param y1 Y-координата нижнего правого угла прямоугольника.
//! @param startAngle Угол между направлением оси OX и началом дуги (в градусах).
//! @param totalAngle Величина дуги (в градусах).
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txArc (100, 100, 300, 200, 45, 270);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует сектор эллипса.
//!
//! @param x0 X-координата верхнего левого угла прямоугольника, описанного вокруг эллипса, содержащего
//! дугу (см. txEllipse).
//! @param y0 Y-координата верхнего левого угла прямоугольника.
//! @param x1 X-координата нижнего правого угла прямоугольника.
//! @param y1 Y-координата нижнего правого угла прямоугольника.
//! @param startAngle Угол между направлением оси OX и началом сектора (в градусах).
//! @param totalAngle Величина сектора (в градусах).
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txPie (100, 100, 300, 200, 0, 180); // Enter Pacman
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует хорду эллипса.
//!
//! @param x0 X-координата верхнего левого угла прямоугольника, описанного вокруг эллипса, содержащего
//! дугу (см. txEllipse).
//! @param y0 Y-координата верхнего левого угла прямоугольника.
//! @param x1 X-координата нижнего правого угла прямоугольника.
//! @param y1 Y-координата нижнего правого угла прямоугольника.
//! @param startAngle Угол между направлением оси OX и началом хорды (в градусах).
//! @param totalAngle Величина хорды (в градусах).
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет и толщина линий задается функцией txSetColor(), цвет заполнения -- txSetFillColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txChord (100, 100, 300, 200, 45, 270);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Заливает произвольный контур текущим цветом заполнения.
//!
//! @param x X-координата точки начала заливки.
//! @param y Y-координата точки начала заливки.
//! @param color Цвет заливаемой области. Необязателен. Если не указан, то используется TX_TRANSPARENT --
//! автоопределение цвета.
//! @param mode Режим заливки. Необязателен. Если не указан, то используется FLOODFILLSURFACE -- заливка
//! однородного фона.
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет заполнения задается функцией txSetFillColor(). Не рекомендуется для применения, так как работает
//! довольно медленно. Лучше Используйте txPolygon().
//!
//! @title Режимы заливки: @table
//! @tr FLOODFILLSURFACE @td -- Заливать область, указанную цветом color.
//! @tr FLOODFILLBORDER @td -- Заливать до границы, указанной цветом color.
//! @endtable
//!
//! @see txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txSetFillColor (TX_PINK);
//! txLine (100, 200, 150, 100);
//! txLine (150, 100, 200, 200);
//! txLine (200, 200, 100, 200);
//! txFloodFill (150, 150);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Функция, которая должна бы рисовать треугольник.
//!
//! @param x1 X-координата 1-й точки.
//! @param y1 Y-координата 1-й точки.
//! @param x2 X-координата 2-й точки.
//! @param y2 Y-координата 2-й точки.
//! @param x3 X-координата 3-й точки.
//! @param y3 Y-координата 3-й точки.
//!
//! @return Если операция была бы успешна -- true, иначе -- false.
//!
//! @see txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @par См. также:
//! @ref Tutor_Params "Пример с функциями с параметрами"
//}----------------------------------------------------------------------------------------------------------------
inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)
{
(void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3;
txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n"
"Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами "
"как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". "
"Ну или нарисовать тремя линиями. :)", "TXLib сообщает");
return false;
}
//{----------------------------------------------------------------------------------------------------------------
//! @cond INTERNAL
bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
#define txRectandle Sleep (1000), txRectangle // Copy-protection for the function below
#define txLine(...) txLine (__VA_ARGS__); { //
#define txNotifyIcon }}}}}}}}}} txNotifyIcon // Не спрашивайте, зачем. Это дичь.
#define txCircle ;txCircle //
#define txSetColor ;txSetColor //
#define C0L0RREF COLORREF //
#define OxFFFFFF 0xFFFFFF //
#define lO 10 //
#define lOOO 1000 //
#define oo //
#define O //
//! @endcond
//}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует человечка.
//!
//! Это пример функции, которую Вы могли бы написать и сами.
//!
//! @param x X-координата человечка.
//! @param y Y-координата человечка.
//! @param sizeX Ширина человечка.
//! @param sizeY Высота человечка (также определяет размер головы).
//! @param color Цвет человечка.
//! @param handL Высота подъема левой руки (относительно высоты человечка).
//! @param handR Высота подъема правой руки (относительно высоты человечка).
//! @param twist Смещение @a спины (относительно ширины человечка).
//! @param head Высота @a подъема головы (относительно высоты человечка).
//! @param eyes Величина глаз (относительно размера головы).
//! @param wink Моргание глаз (0 -- оба открыты, -1 -- закрыт левый, +1 -- закрыт правый).
//! @param crazy Смещение глаз по вертикали (относительно размера головы).
//! @param smile Улыбка (относительно размера головы).
//! @param hair Длина волос (относительно размера головы).
//! @param wind Ветер, развевающий волосы (относительно размера головы).
//!
//! @see txSetFillColor(), txColors, RGB(), txLine(), txCircle()
//!
//! @usage @code
//! txCreateWindow (800, 600);
//!
//! //-----------+---+----+-----+-----+----------+-----+-----+-----+----+----+----+-----+-----+----+-----
//! // | x | y |sizeX|sizeY| color |handL|handR|twist|head|eyes|wink|crazy|smile|hair|wind
//! //-----------+---+----+-----+-----+----------+-----+-----+-----+----+----+----+-----+-----+----+-----
//! // | | | | | | | | | | | | | | |
//! txDrawMan (125, 250, 200, 200, TX_WHITE, 0, 0, 0, 0, 0.8, 0, 0, 1.0, 0, 0);
//! txDrawMan (325, 250, 100, 200, TX_YELLOW, 0, 0, 0, 0, 0.8, 0, 0, -1.0, 2, 0);
//! txDrawMan (525, 250, 200, 100, TX_ORANGE, 0, 0, 0, 0, 1.0, 0, -1, 0.3, 1, 0);
//! txDrawMan (725, 250, 100, 100, TX_LIGHTRED, 0, 0, 0, 0, 1.0, 0, 1, -0.3, 3, 0);
//!
//! txDrawMan (125, 550, 200, 200, TX_WHITE, 0.3, 0.3, 0, 0, 0.8, -1, 1, 0.5, 2, -1);
//! txDrawMan (325, 550, 100, 200, TX_YELLOW, -0.5, -0.5, 0, 0.1, 0.8, 1, 0, -0.5, 3, 5);
//! txDrawMan (525, 550, 200, 100, TX_ORANGE, -0.5, 0.3, 0.2, 0, 0.8, -1, 1, 0.0, 10, -5);
//! txDrawMan (725, 550, 100, 100, TX_LIGHTRED, 0.3, -0.5, -0.4, 0, 0.8, 1, -1, 0.0, 1, 1);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------//////
//
inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist, //
double head, double eyes, double wink, double crazy, double smile, double hair, double wind) //
{ //
const char __[] = "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/"; //
// | | | | //
// Не копипастите! _/ \_ Все равно не получится! :) _/ \_ Человечки защищают _/ \_ этот код! :) _/ \_ Муаххаха! //
// //
static int count = GetTickCount(), L = 0; //////////////////////////////////////////////////////////////////////////
C0L0RREF lineColor = txGetColor();
C0L0RREF fillColor = txGetFillColor();
txSetColor (color, 3);
txSetFillColor (color);
txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY);
txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY);
txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY);
txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y);
txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y);
txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY);
txLine (x, y - (1 + head) * sizeY, x + wind/lO * sizeX, y - (1 + head + hair/lO) * sizeY);
txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
txSetColor (~color & OxFFFFFF); // Inverse the color
txSetFillColor (~color & OxFFFFFF);
txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
oo
txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]); //-V112 //-V542
oo
// See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow
txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY);
txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY);
Sleep (lOOO + count%2);
txSetColor ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT);
txSetFillColor (TX_TRANSPARENT);
txCircle (x, y, 4); //-V112
txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y);
txSetColor (lineColor);
txSetFillColor (fillColor);
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Drawing text
//! @name Работа с текстом
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует текст.
//!
//! @param x X-координата начальной точки текста.
//! @param y Y-координата начальной точки текста.
//! @param text Текстовая строка.
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет текста задается функцией txSetColor(), выравнивание (влево/вправо/по центру) -- txSetTextAlign().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txSelectFont(), txSetTextAlign(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txTextOut (100, 100, "Здесь могла бы быть Ваша реклама.");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txTextOut (double x, double y, const char text[], HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @cond INTERNAL
#undef txRectandle
#undef txLine
#undef txNotifyIcon
#undef txCircle
#undef txSetColor
#undef C0L0RREF
#undef OxFFFFFF
#undef lO
#undef lOOO
#undef oo
#undef O
//! @endcond
//}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Рисует текст, размещенный в прямоугольной области.
//!
//! @param x0 X-координата верхнего левого угла области.
//! @param y0 Y-координата верхнего левого угла области.
//! @param x1 X-координата нижнего правого угла области.
//! @param y1 Y-координата нижнего правого угла области.
//! @param text Текстовая строка.
//! @param format Флаги форматирования текста. Необязательны. Если не указаны, то используется: центрирование,
//! перенос по словам и добавление многоточия, если надпись не умещается в область.
//! @param dc Дескриптор контекста рисования (холста) для рисования. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! Цвет текста задается функцией txSetColor(), выравнивание (влево/вправо/по центру) -- txSetTextAlign().
//!
//! @note Не выводит ничего, если координаты идут в неверном порядке (если x0 \> x1 или y0 \> y1).
//!
//! Флаги форматирования текста см. в MSDN (http://msdn.com), искать "DrawText Function (Windows)":
//! http://msdn.microsoft.com/en-us/library/dd162498%28VS.85%29.aspx.
//!
//! Автоматический перенос текста на несколько строк включается, если текст состоит из нескольких
//! строк (есть хотя бы один символ новой строки @b @c \\n).
//!
//! Если надо отформатировать текст не по центру, а по левому или правому краю, то не забудьте указать
//! остальные флаги форматирования, если они нужны: @c DT_VCENTER (вертикальное центрирование) @c |
//! @c DT_WORDBREAK (перенос по словам) @c | @c DT_WORD_ELLIPSIS (ставить многоточие в конце, если текст
//! не умещается). См. значение флагов по умолчанию.
//!
//! @note Вертикальное центрирование работает только для надписей, в которых нет символа новой строки @c \\n.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txTextOut(), txSelectFont(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txCreateWindow (800, 600);
//!
//! txSetColor (TX_BLACK);
//! txSetFillColor (TX_DARKGRAY); Win32::RoundRect (txDC(), 105, 205, 705, 405, 30, 30);
//! txSetFillColor (TX_WHITE); Win32::RoundRect (txDC(), 100, 200, 700, 400, 30, 30);
//!
//! txSelectFont ("Arial", 20, 0, FW_BOLD);
//! txDrawText (100, 250, 700, 350, "Котики говорят: Мяу!,\n"
//! "Собачки говорят: Гав!,\n\n"
//! "Программисты говорят: Ты КОММИТ НА ГИТХАБ СДЕЛАЛ?!?!!");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Выбирает текущий шрифт, его размер и другие атрибуты.
//!
//! @param name Название шрифта.
//! @param sizeY Высота букв (размер по @c Y).
//! @param sizeX Ширина букв. Необязательна. Если не указана, то берется 1/3 от высоты.
//! @param bold Жирность шрифта (от 0 до 1000). Необязательна. Если не указана, то берется обычный шрифт.
//! @param italic Курсив. Необязателен.
//! @param underline Подчеркивание. Необязательно.
//! @param strikeout Перечеркивание. Необязательно.
//! @param angle Угол поворота текста (в градусах). Необязателен.
//! @param dc Дескриптор контекста рисования (холста) для выбора шрифта. Необязателен.
//!
//! @return Выбранный шрифт. Если он не был найден, то устанавливается системный шрифт Windows
//! @c (SYSTEM_FIXED_FONT, см. MSDN). Существование шрифта можно проверить функцией txFontExist().
//!
//! @see txTextOut(), txDrawText(), txFontExist()
//!
//! @usage @code
//! txSelectFont ("Comic Sans MS", 40);
//! txTextOut (100, 100, "И здесь могла бы быть Ваша реклама.");
//! txSelectFont ("Comic Sans MS", 40, 10, FW_BOLD, true, false, true, 15);
//! txTextOut (100, 200, "Но ее почему-то нет.");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1,
int bold = FW_DONTCARE, bool italic = false, bool underline = false,
bool strikeout = false, double angle = 0,
HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Вычисляет размеры текстовой надписи.
//!
//! @param text Текстовая строка.
//! @param dc Дескриптор контекста рисования (холста), где планируется разместить надпись. Необязателен.
//!
//! @return Размеры надписи в структуре SIZE.
//!
//! @see txTextOut(), txSelectFont(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! SIZE size = txGetTextExtent (text);
//! txTextOut (100 + size.cx / 2, 200 + size.cy / 2, text);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Вычисляет ширину текстовой надписи.
//!
//! @param text Текстовая строка.
//! @param dc Дескриптор контекста рисования (холста), где планируется разместить надпись. Необязателен.
//!
//! @return Ширина надписи.
//!
//! @see txTextOut(), txSelectFont(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txTextOut (100 + txGetTextExtentX (text) / 2, 200 + txGetTextExtentY (text) / 2, text);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Вычисляет высоту текстовой надписи.
//!
//! @param text Текстовая строка.
//! @param dc Дескриптор контекста рисования (холста), где планируется разместить надпись. Необязателен.
//!
//! @return Высота надписи.
//!
//! @see txTextOut(), txSelectFont(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txTextOut (100 + txGetTextExtentX (text) / 2, 200 + txGetTextExtentY (text) / 2, text);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает текущее выравнивание текста (влево/вправо/по центру).
//!
//! @param align Флаги выравнивания. Необязательны. Если не указаны, то используются центрирование по горизонтали.
//! @param dc Дескриптор контекста рисования (холста), где планируется разместить надпись. Необязателен.
//!
//! @return Предыдущее состояние выравнивания текста.
//!
//! @title Флаги выравнивания: @table
//! @tr TA_LEFT @td Текст выравнивается влево. Точка @c (X,Y) определяет левую границу текста.
//! @tr TA_RIGHT @td Текст выравнивается вправо. Точка @c (X,Y) определяет правую границу текста.
//! @tr TA_CENTER @td Текст центрируется по горизонтали относительно точки @ (X,Y).
//! @tbr
//! @tr TA_BASELINE @td Точка @c (X,Y) определяет базовую линию текста.
//! @tr TA_BOTTOM @td Точка @c (X,Y) определяет нижнюю границу текста.
//! @tr TA_TOP @td Точка @c (X,Y) определяет верхнюю границу текста.
//! @endtable
//!
//! @see txTextOut(), txSelectFont(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txSetTextAlign (TA_RIGHT);
//! txTextOut (700, 100, "Чтобы доступ был легок и быстр,");
//! txTextOut (700, 150, "Переменную клади в регистр.");
//! txSetTextAlign();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ищет шрифт по его названию.
//!
//! @param name Название шрифта.
//!
//! @return Информация о шрифте в структуре LOGFONT. Если шрифт не найден, возвращает NULL.
//!
//! @see txTextOut(), txSelectFont()
//!
//! @usage @code
//! if (txFontExist ("Comic Sans MS")) txSelectFont ("Comic Sans MS", 30);
//! else txSelectFont ("Times New Roman", 30);
//!
//! txTextOut (100, 100, "Комик ли Санс?"); // google.ru/search?q=philosoraptor
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
LOGFONT* txFontExist (const char name[]) tx_nodiscard;
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Drawing to memory DC and image loading
//! @name Рисование в памяти (на "виртуальном холсте") и загрузка изображений
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Создает дополнительный холст (контекст рисования, Device Context, DC) в памяти.
//!
//! @param sizeX Ширина холста.
//! @param sizeY Высота холста.
//! @param bitmap Bitmap to be associated with DC (optional). If omitted, color bitmap will be created
//! automatically via Win32::CreateDIBSection.
//! @param pixels This parameter is optional and may be omitted. When bitmap == NULL, a DIBSection will be
//! created (see above) and this parameter will be associated with its pixels colors array pointer.
//! See txCreateDIBSection() function below. Also, txCreateDIBSection() is preferred when using
//! per-pixel transparency. See txVideoMemory() for @b important notes.
//!
//! @return Системный номер (по-научному @d дескриптор, handle), выданный Windows для созданного холста (по-научному
//! @d контекста рисования, Device Context, DC). Вместе получается Handle of Device Context == HDC.
//!
//! После создания на этом холсте можно рисовать, как и на основном окне TXLib, используя параметр @c dc
//! функций рисования. Созданный холст имеет свои собственные настройки цветов, шрифтов и т.д., отличные
//! от настроек основного окна TXLib. Чтобы увидеть результат рисования, скопируйте изображение холста
//! на экран с помощью функций txBitBlt(), txTransparentBlt() или txAlphaBlend().
//!
//! @warning Созданный контекст затем будет нужно @b обязательно удалить при помощи txDeleteDC(). @n
//! When the program will be shutting down, TXLib will try to delete DCs which were not deleted,
//! but this is not guaranteed. При этом удаляется и @c bitmap, будьте внимательны.
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC(), txSaveImage(), txGetExtent(),
//! txCreateDIBSection(), txVideoMemory()
//!
//! @usage @code
//! HDC save = txCreateCompatibleDC (100, 100);
//!
//! txBitBlt (save, 0, 0, 100, 100, txDC(), 0, 0); // Сохраняем фон
//!
//! txTextOut (20, 20, "Boo!");
//! txSleep (2000);
//!
//! txBitBlt (txDC(), 0, 0, 100, 100, save, 0, 0); // Текст исчезает
//!
//! txDeleteDC (save);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Создает аппаратно-независимый дополнительный холст (контекст рисования, Device Context, DC) в памяти
//! с возможностью прямого доступа к нему как к массиву.
//!
//! @param sizeX Ширина холста.
//! @param sizeY Высота холста.
//! @param pixels Указатель на переменную, которая будет использоваться для доступа к пикселям изображения.
//! Необязателен. Эта переменная должна быть указателем на массив структур RGBQUAD, каждая
//! из которых описывает цвет одного пикселя. @b Не надо создавать самому этот массив!
//! Его создаст txCreateDIBSection() и вернет через этот указательный параметр. Объявите
//! только указатель и занулите его, потом его адрес передайте в функцию.
//!
//! @return Дескриптор созданного аппаратно-независимого холста (контекста рисования).
//!
//! После создания на этом холсте можно рисовать, как и на основном окне TXLib, используя параметр @c dc
//! функций рисования. Созданный холст имеет свои собственные настройки цветов, шрифтов и т.д., отличные
//! от настроек основного окна TXLib. Чтобы увидеть результат рисования, скопируйте изображение холста
//! на экран с помощью функций txBitBlt(), txTransparentBlt() или txAlphaBlend().
//!
//! Самое важное, что аппаратно-независимые холсты, создаваемые этой функцией, позволяют напрямую и быстро
//! изменять цвета пикселей изображения, а также его прозрачность в каждой точке. См. пример использования.
//!
//! Для прямого доступа к пикселям холста, как к массиву, надо объявить указатель на массив структур
//! RGBQUAD и передать адрес этого указателя в качестве третьего параметра функции txCreateDIBSection().
//! Она изменит значение этого указателя так, что он станет указывать на массив цветов пикселей холста.
//!
//! Массив @p pixels одномерный, но по сути он описывает двумерное изображение. Поэтому с ним надо
//! работать как с двумерным прямоугольным массивом, физически расположенным в одномерном массиве:
//! вручную вычислять смещение от начала массива до нужного пикселя и после этого адресоваться к массиву.
//! (Так обычно делают, размещая двумерные массивы в динамической памяти.) См. пример использования.
//!
//! @note Кроме того, "Y-ось" этого массива направлена @b вверх, а не вниз, как в окне TXLib. Поэтому для нужного
//! пикселя его смещение от начала массива нужно рассчитывать с помощью формулы x + (-y + sizeY) * sizeX,
//! где @c sizeX и @c sizeY -- размеры изображения. Иначе изображение будет перевернуто вверх ногами. @nn
//!
//! @note Однако если @b перед включением @c TXLib.h в программу будет определен макрос #define _TX_DIB_FIX -1*
//! или #define _TX_DIB_FIX @b - то этого переворота не будет, ось Y будет направлена снизу вверх.
//!
//! @warning Будьте осторожны, не выходите за границы массива, последствия будут непредсказуемыми. @nn
//!
//! @warning Созданный контекст затем будет нужно @b обязательно удалить при помощи txDeleteDC(). @n
//! When the program will be shutting down, TXLib will try to delete DCs which were not deleted,
//! but this is not guaranteed.
//!
//! @note Память под массив RGBQUAD выделять @b не надо и освобождать его @b не надо, этим занимается сама
//! txCreateDIBSection() вместе с txDeleteDC(). @nn
//!
//! @note Аппаратно-независимые холсты -- это контексты устройств, связанные с аппаратно-независимыми растрами
//! (Device Independent Bitmaps, DIB) Windows.
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC(), txSaveImage(), txGetExtent(),
//! txCreateCompatibleDC()
//!
//! @usage @code
//! int main()
//! {
//! txCreateWindow (800, 600);
//!
//! POINT size = txGetExtent();
//!
//! txSetFillColor (TX_BLACK);
//! txTextCursor (false);
//! txBegin();
//!
//! HDC src = GetDC (HWND_DESKTOP); // Get HDC from Windows Desktop
//!
//! RGBQUAD* buf = NULL; // Do NOT actually create the array!
//! HDC dc = txCreateDIBSection (size.x, size.y, &buf);
//! assert (dc); assert (buf); // Here, 'buf' points to an array created
//! // by txCreateDIBSection()
//! while (!GetAsyncKeyState (VK_ESCAPE))
//! {
//! txBitBlt (dc, 0, 0, size.x, size.y, src);
//!
//! for (int y = 0; y < size.y; y++)
//! for (int x = 0; x < size.x; x++)
//! {
//! RGBQUAD* color = & buf [x + y * size.x]; // Get color at (x, y) within image buffer
//!
//! double r = hypot (x - size.x/2, y - size.y/2);
//! double alpha = sin (0.05 * r) * 0.25 + 0.5;
//!
//! color->rgbReserved = (BYTE) ROUND (255 * alpha); // Set alpha-channel (transparency)
//! }
//!
//! txUseAlpha (dc) asserted; // Premultiply colors with alpha
//!
//! txClear();
//! txAlphaBlend (txDC(), 0, 0, 0, 0, dc);
//!
//! printf ("FPS %.0lf\t\t\r", txGetFPS());
//! txSleep (0);
//! }
//!
//! txSaveImage ("TxFilter.bmp", dc);
//!
//! txDeleteDC (dc);
//! ReleaseDC (HWND_DESKTOP, src); // Free Windows Desktop HDC
//!
//! return 0;
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels = NULL) tx_nodiscard;
//! @cond INTERNAL
HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) tx_nodiscard;
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Загружает из файла изображение в формате BMP. Делает это довольно медленно.
//!
//! @param filename Имя файла с изображением в формате BMP.
//! @param sizeX Размер загружаемого изображения. Необязателен. Если не указан, используется
//! оригинальный размер рисунка из файла.
//! @param sizeY Размер загружаемого изображения. Необязателен. Если не указан, используется
//! оригинальный размер рисунка из файла.
//! @param imageType Тип загружаемого изображения, см. ниже. Необязателен. Если не указан, загружается
//! рисунок в формате BMP.
//! @param loadFlags Флаги загрузки изображения, см. ниже. Необязательны. Если не указаны, загрузка идет
//! из файла.
//!
//! @return Дескриптор созданного контекста рисования в памяти, с загруженным изображением.
//! Если изображение не загружено (не найден файл, неверный формат файла и т.д.), то NULL.
//!
//! @warning Изображение загружается в автоматически создаваемый контекст рисования в памяти ("виртуальный холст"),
//! который затем будет нужно обязательно удалить при помощи txDeleteDC(). @nn
//! When the program will be shutting down, TXLib will try to delete DCs which were not deleted,
//! but this is not guaranteed.
//!
//! @note
//! -# Изображения поддерживаются только в формате BMP. Если взять файл другого формата, например JPG,
//! и переименовать его со сменой расширения на BMP, то от этого формат не изменится. Такое изображение
//! загружено не будет.
//! @nn
//! -# Если функция вернула NULL, то надо прежде всего проверить наличие файла изображения по
//! указанному в программе пути и формат файла. Если путь к файлу не указан (или указан как неполный),
//! то путь отсчитывается от текущей папки программы, которая может не совпадать текущей папкой среды
//! программирования. Текущую папку программы можно посмотреть по команде About в системном меню
//! (она указана там как "Run from").
//! @nn
//! -# Если файл по-прежнему не загружается, откройте его в редакторе Microsoft Paint (нажмите
//! \ mspaint \) или другой программе обработки изображений и сохраните его
//! заново как изображение в формате BMP. Это иногда бывает нужно для файлов, преобразованных из других
//! форматов программами-конверторами или сайтами для преобразования изображений.
//! @nn
//! -# Если изображение в файле содержит альфа-канал (информацию о прозрачности), то его цвета должны
//! находиться в формате Premultiplied Alpha. См. замечания к функции txAlphaBlend().
//! @nn
//! -# Если изображение в файле с альфа-каналом @b не находится в формате Premultiplied Alpha, то после
//! вызова txLoadImage() нужно вызвать функцию txUseAlpha(). Однако не надо этого делать, если цвета в файле
//! @b уже находятся в формате Premultiplied Alpha, иначе картинка станет темнее. Также не надо вызывать
//! txUseAlpha() несколько раз для одного и того же изображения.
//! @nn
//! -# Не надо часто загружать одно и то же изображение, особенно в цикле. От этого программа начинает
//! тормозить! @n
//! Загрузите один раз @a перед циклом, потом используйте много раз. Посмотрите, как это сделано в примере
//! TX\Examples\Tennis\Tennis.cpp.
//!
//! @title Типы загружаемых изображений:
//! @table @tr IMAGE_BITMAP @td Рисунок в формате BMP
//! @tr IMAGE_CURSOR @td Курсор в формате CUR или ANI
//! @tr IMAGE_ICON @td Иконка в формате ICO
//! @endtable
//!
//! @title Флаги загрузки:
//! @table @tr LR_CREATEDIBSECTION @td Создает DIB (device-independent bitmap), удобную для прямого доступа к данным
//! @tr LR_LOADFROMFILE @td Загружает из файла (если этот флаг не указан, то загружает из ресурса EXE-файла)
//! @tr Остальные флаги загрузки @td см. на MSDN.com, поиск "LoadImage function".
//! @endtable
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC(), txBitBlt(), txAlphaBlend(),
//! txTransparentBlt(), txSaveImage(), txGetExtent()
//!
//! @usage Пример использования см. в файле TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC background_CopiedFromHelp = txLoadImage ("Resources\\Images\\Background.bmp");
//!
//! if (!background_CopiedFromHelp)
//! txMessageBox ("Не могу загрузить фон из Background.bmp", "Да, я скопировал это из примера");
//!
//! // Не надо часто загружать одно и то же изображение, особенно в цикле -- программа будет тормозить!
//! // Загрузите один раз перед циклом, потом используйте много раз.
//! // Посмотрите, как сделано в примере TX\Examples\Tennis\Tennis.cpp.
//!
//! txBitBlt (txDC(), 0, 0, 800, 600, background_CopiedFromHelp, 0, 0);
//!
//! ...
//! txDeleteDC (background_CopiedFromHelp);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0,
unsigned imageType = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Уничтожает холст (контекст рисования, DC) в памяти.
//!
//! @param dc Контекст рисования для уничтожения. @n
//! Если передан указатель на контекст, то после уничтожения по указателю записывается NULL.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @note Эту функцию нужно обязательно вызывать, если картинка, загруженная с помощью txLoadImage() или виртуальный
//! холст, созданный с помощью txTransparentBlt() или txCreateDIBSection(), больше не нужны. Иначе настанет
//! @strike полный треш @endstrike у Windows могут закончиться свободные дескрипторы HDC, и начнется общее
//! торможение всей работы Windows и проблемы с рисованием во всех программах. Может быть, поосле этого придется
//! перезапускать компьютер.
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC(), txSaveImage(), txGetExtent(),
//! txCreateDIBSection()
//!
//! @usage Пример использования см. в файле TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC background_CopiedFromHelp = txLoadImage ("Resources\\Images\\Background.bmp");
//!
//! if (!background_CopiedFromHelp)
//! txMessageBox ("Не могу загрузить фон из Background.bmp, и я скопировал это из примера.", "Oh, not now");
//!
//! // См. важный комментарий в примере к функции txLoadImage!
//!
//! txBitBlt (txDC(), 0, 0, 800, 600, background_CopiedFromHelp, 0, 0);
//!
//! ...
//! txDeleteDC (background_CopiedFromHelp);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txDeleteDC (HDC dc);
//! @cond INTERNAL
bool txDeleteDC (HDC* dc);
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Копирует изображение с одного холста (контекста рисования, DC) на другой.
//!
//! @param destImage Контекст назначения (куда копировать). Для копирования в окно TXLib укажите txDC().
//! @param xDest X-координата верхнего левого угла копируемого изображения.
//! @param yDest Y-координата верхнего левого угла копируемого изображения.
//! @param width Ширина копируемой области. Если равна 0, то равна ширине изображения-источника.
//! @param height Высота копируемой области. Если равна 0, то равна высоте изображения-источника.
//! @param sourceImage Контекст источника (откуда копировать).
//! @param xSource X-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param ySource Y-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param operation Вид операции копирования. Список видов гуглите по запросу "BitBlt function MSDN".
//! Необязательен. Если не указан, то @c SRCCOPY (обычное копирование изображения).
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @warning Если контексты источника равен NULL, то он не существует и копирование вызовет ошибку.
//! Наиболее частая причина -- ошибка при загрузке файла изображения и отсутствие проверки на эту ошибку.
//! Пример с проверкой на правильность загрузки см. ниже.
//!
//! @see txAlphaBlend(), txTransparentBlt(), txSaveImage(), txGetExtent(), txSetColor(), txGetColor(),
//! txSetFillColor(), txGetFillColor(), txColors, RGB(), txCreateDIBSection()
//!
//! @usage Пример использования см. в файле TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC background_CopiedFromHelp = txLoadImage ("Resources\\Images\\Background.bmp");
//!
//! if (!background_CopiedFromHelp)
//! txMessageBox ("Не могу фон из загрузить Background.bmp, и да, я взял этот код из примера.", "Once again :(");
//!
//! // См. важный комментарий в примере к функции txLoadImage!
//!
//! txBitBlt (txDC(), 0, 0, 800, 600, background_CopiedFromHelp);
//!
//! ...
//! txDeleteDC (background_CopiedFromHelp);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height,
HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Копирует изображение на экран.
//!
//! @param xDest X-координата верхнего левого угла копируемого изображения.
//! @param yDest Y-координата верхнего левого угла копируемого изображения.
//! @param sourceImage Копируемое изображение.
//! @param xSource X-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param ySource Y-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! См. описание в функции txBitBlt() выше.
//}----------------------------------------------------------------------------------------------------------------
inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Копирует изображение с одного холста (контекста рисования, DC) на другой с учетом прозрачности.
//!
//! @param destImage Контекст назначения (куда копировать). Для копирования в окно TXLib укажите txDC().
//! @param xDest X-координата верхнего левого угла копируемого изображения.
//! @param yDest Y-координата верхнего левого угла копируемого изображения.
//! @param width Ширина копируемой области. Если равна 0, то автоматически берется из размера источника.
//! @param height Высота копируемой области. Если равна 0, то автоматически берется из размера источника.
//! @param sourceImage Контекст источника (откуда копировать).
//! @param xSource X-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param ySource Y-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param transColor Цвет, который будет считаться прозрачным. Необязателен. Если не указан, то TX_BLACK.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @warning Если контекст источника равен NULL, то он не существует и копирование вызовет ошибку.
//! Наиболее частая причина -- ошибка при загрузке файла изображения и отсутствие проверки на эту ошибку.
//! Пример с проверкой на правильность загрузки см. ниже. @nn
//!
//! @warning Изображение-источник и изображение-приемник не могут налагаться друг на друга. @nn
//!
//! @warning Если прямоугольник копируемой области не полностью лежит внутри изображения-источника, то функция
//! работать не будет. Такое бывает, если xSource или ySource отрицательны, или величина (xSource + width)
//! больше ширины изображения-источника, или величина (ySource + height) больше высоты изображения-источника.
//!
//! Стандартная функция TransparentBlt из Win32 API может масштабировать изображение. В txTransparentBlt
//! это убрано для упрощения использования. If you need image scaling, use original function
//! TransparentBlt and don't mess with stupid TX-based tools. (See implementation of txTransparentBlt in TXLib.h).
//!
//! @note Если TransparentBlt не работает, используйте функцию AlphaBlend, она вообще лучше.
//!
//! @note Стандартная функция @c Win32::TransparentBlt из Win32 API @b может масштабировать изображение. В txTransparentBlt
//! это @b убрано для упрощения использования. If you still need image scaling, use original function Win32::TransparentBlt
//! and don't mess with stupid TX-based tools. (See implementation of txTransparentBlt in TX library source:
//! open @ref TXLib.h file in your editor and search for txTransparentBlt function @b definition.)
//!
//! @see txBitBlt(), txAlphaBlend(), txLoadImage(), txCreateCompatibleDC(), txSaveImage(), txGetExtent(),
//! txCreateDIBSection()
//!
//! @usage Пример использования см. в файле TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC superman_CopiedFromHelp = txLoadImage ("Resources\\Images\\Superman.bmp");
//!
//! if (!superman_CopiedFromHelp)
//! txMessageBox ("Cannot load superman, all the monsters will succeed (I copied them from TXLib Help)", "Sorry");
//!
//! // См. важный комментарий в примере к функции txLoadImage!
//!
//! txTransparentBlt (txDC(), 0, 0, 800, 600, superman_CopiedFromHelp);
//!
//! // А можно и так:
//! Win32::TransparentBlt (txDC(), 0, 0, 800, 600, superman_CopiedFromHelp, 0, 0, 80, 60, -1); // 10x zoom
//! // Познай мощь Win32 GDI, отказавшись от TXLib'а! :) см. TransparentBlt в MSDN.com.
//!
//! ...
//! txDeleteDC (superman_CopiedFromHelp); // So pity :( But he was only a copy from TXLib Help.
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height,
HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Копирует изображение на экран с учетом прозрачности.
//!
//! @param xDest X-координата верхнего левого угла копируемого изображения.
//! @param yDest Y-координата верхнего левого угла копируемого изображения.
//! @param sourceImage Копируемое изображение.
//! @param transColor Цвет, который будет считаться прозрачным. Необязателен. Если не указан, то TX_BLACK.
//! @param xSource X-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param ySource Y-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! См. описание в функции txTransparentBlt() выше.
//}----------------------------------------------------------------------------------------------------------------
inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Копирует изображение с одного холста (контекста рисования, DC) на другой с учетом полупрозрачности.
//!
//! @param destImage Контекст назначения (куда копировать). Для копирования в окно TXLib укажите txDC().
//! @param xDest X-координата верхнего левого угла копируемого изображения.
//! @param yDest Y-координата верхнего левого угла копируемого изображения.
//! @param width Ширина копируемой области. Если равна 0, то равна ширине изображения-источника.
//! @param height Высота копируемой области. Если равна 0, то равна высоте изображения-источника.
//! @param sourceImage Контекст источника (откуда копировать). Должен иметь 32-битовый формат и альфа-канал (см. ниже).
//! @param xSource X-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param ySource Y-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param alpha Общая прозрачность изображения, в дополнение к альфа-каналу (0 -- все прозрачно, 1 -- использовать
//! только альфа-канал). Необязательна. Если не указана, то 1.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @warning Если контекст источника равен NULL, то он не существует и копирование вызовет ошибку.
//! Наиболее частая причина -- ошибка при загрузке файла изображения и отсутствие проверки на эту ошибку.
//! Пример с проверкой на правильность загрузки см. ниже. @nn
//!
//! @warning Изображение-источник и изображение-приемник не могут налагаться друг на друга. @nn
//!
//! @warning Если прямоугольник копируемой области не полностью лежит внутри изображения-источника, то функция
//! работать не будет. Такое бывает, если xSource или ySource отрицательны, или величина (xSource + width)
//! больше ширины изображения-источника, или величина (ySource + height) больше высоты изображения-источника.
//!
//! @note Изображение-источник должно быть загружено с помощью txLoadImage() и иметь 32-битовый RGBA-формат.
//! Дополнительный канал (A: альфа-канал) 32-битового формата отвечает за попиксельную прозрачность
//! участков изображения: для каждого пикселя в этом канале значение 0 означает его полную прозрачность,
//! значение 255 -- полную непрозрачность, промежуточные значения -- полупрозрачность. @nn
//!
//! Пустое 32-битовое изображение-источник также может быть создано с помощью функций txCreateCompatibleDC()
//! или txCreateDIBSection(). После создания на этом изображении можно рисовать, как на основном окне TXLib,
//! используя параметр @c dc функций рисования фигур.
//!
//! @warning Если изображение не имеет альфа-канала, или его альфа-канал полностью черный, то txAlphaBlend() может
//! решить, что изображение полностью прозрачно и не выведет на экран ничего. @nn
//!
//! Если изображение-источник создано с помощью txCreateDIBSection() или txLoadImage(), то txAlphaBlend()
//! может использовать как общую прозрачность, задачаемую параметром @p alpha, так и попиксельную прозрачность,
//! задаваемую альфа-каналом.
//!
//! Если изображение имеет 24-битовый RGB-формат файлов (TrueColor), то это подразумевает, что попиксельной
//! прозрачности нет и все пиксели изображения имеют равную прозрачность, задающуюся параметром @c alpha. @nn
//!
//! Имейте в виду, что многие графические редакторы сохраняют изображение в 32-битовом формате, даже если вы
//! явно указываете 24-битовый формат или формат TrueColor. Если при этом в изображении нет альфа-канала,
//! то txAlphaBlend не выведет ничего. Так происходит, например, если сохранять картинку в Microsoft Paint,
//! который не умеет создавать альфа-каналы и при этом сохраняет всегда в 32-битовом формате. Для таких случаев
//! надо использовать txTransparentBlt. @nn
//!
//! Для BMP-файла альфа-канал можно сделать, например, в Adobe Photoshop, командой "Новый канал (New Channel)"
//! в палитре каналов (Channels). Черный цвет в альфа-канале соответствует полной прозрачности, белый --
//! полной непрозрачности. При этом в прозрачных областях само изображение (в каналах R, G, B) должно
//! быть черным, и чем прозрачнее, тем чернее. Такой формат цвета называется Premultiplied Alpha.
//! См. изображение с альфа-каналом в примере TX\Examples\Tennis\Tennis.cpp (файл с теннисной ракеткой:
//! TX\Examples\Tennis\Resources\Images\Racket.bmp).
//!
//! Иначе говоря, при пересчете в формат Premultiplied Alpha надо домножить цвета в каналах R,G,B
//! на значения альфа-канале @c A: R,G,B *= A / 255.0. Получится вот что:
//!
//! - Если значение альфа-канала для некоторого пикселя равно 0 (полная прозрачность), тогда значения
//! каналов R,G,B для этого пикселя также станут 0 (это черный цвет).
//! - Если значение альфа-канала для некоторого пикселя равно 255 (полная непрозрачность), тогда значения
//! каналов R,G,B для этого пикселя не изменятся.
//! - Для других значений альфа-канала, пиксели изображения станут темнее.
//!
//! В редакторе Adobe Photoshop это можно сделать командой Image -- Apply Image с параметрами:
//! @table @tr Source: @td Имя файла с картинкой
//! @tr Layer: @td Background
//! @tr @b Channel: @td Alpha 1
//! @tr Blending: @td Multiply
//! @tr Opacity: @td 100%
//! @endtable
//!
//! Если изображение с альфа-каналом @b не находится в формате Premultiplied Alpha @strike и вам лень
//! читать что, что написано выше, @endstrike то для перевода в этот формат можно использовать функцию
//! txUseAlpha(). Однако не надо вызывать txUseAlpha() несколько раз для одного и того же уже загруженного
//! изображения, иначе оно может становиться темнее и темнее.
//!
//! @see txBitBlt(), txTransparentBlt(), txLoadImage(), txCreateCompatibleDC(), txSaveImage(), txGetExtent(),
//! txCreateDIBSection(), txUseAlpha()
//!
//! @usage Пример использования см. в файле TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC batman_CopiedFromHelp = txLoadImage ("Resources\\Images\\Batman.bmp");
//!
//! if (!batman_CopiedFromHelp)
//! txMessageBox ("Call to Batman failed because I copied it from TXLib Help", "Do save yourself");
//!
//! txUseAlpha (batman_CopiedFromHelp); // If image colors are not premultiplied, see above
//!
//! // См. важный комментарий в примере к функции txLoadImage!
//!
//! txAlphaBlend (txDC(), 0, 0, 800, 600, batman_CopiedFromHelp);
//!
//! ...
//! txDeleteDC (batman_CopiedFromHelp); // Don't worry, batman will return in "Batman returns" movie, later...
//! ...
//!
//! return batman_CopiedFromHelp; // ...and there he comes -- in TXLib copy form
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height,
HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Копирует изображение на экран с учетом полупрозрачности.
//!
//! @param xDest X-координата верхнего левого угла копируемого изображения.
//! @param yDest Y-координата верхнего левого угла копируемого изображения.
//! @param sourceImage Копируемое изображение.
//! @param xSource X-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param ySource Y-координата верхнего левого угла копируемой области внутри изображения-источника.
//! Необязательна. Если не указана, то 0.
//! @param alpha Общая прозрачность изображения, в дополнение к альфа-каналу (0 -- все прозрачно,
//! 1 -- использовать только альфа-канал). Необязательна. Если не указана, то 1.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! См. описание в функции txAlphaBlend() выше.
//}----------------------------------------------------------------------------------------------------------------
inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
double xSource = 0, double ySource = 0, double alpha = 1.0);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Пересчитывает цвета пикселей с учетом прозрачности (переводит цвета в формат Premultiplied Alpha).
//!
//! @param image Дескриптор холста, изображение которого пересчитывается.
//!
//! @return Если операция была успешна, возвращается исходный HDC, иначе -- NULL.
//!
//! Пересчет цветов в каналах R,G,B в формат Premultiplied Alpha с учетом значения в альфа-канале
//! @c A идет по формуле R,G,B *= A / 255.0. Получается вот что:
//!
//! - Если значение альфа-канала для некоторого пикселя равно 0 (полная прозрачность), тогда значения
//! каналов R,G,B для этого пикселя также станут 0 (это черный цвет).
//! - Если значение альфа-канала для некоторого пикселя равно 255 (полная непрозрачность), тогда значения
//! каналов R,G,B для этого пикселя не изменятся.
//! - Для других значений альфа-канала, пиксели изображения станут темнее.
//!
//! Пересчет цветов пикселей с учетом их прозрачности в формат Premultiplied Alpha необходим:
//!
//! - В случае ручного изменения цветов, пример см. в функции txCreateDIBSection().
//! - После загрузки картинок из файла с помощью txLoadImage(), если цвета изображения в нем не были заранее
//! домножены на альфа-канал в Adobe Photoshop или аналогичной программе (см. замечания к функции @ref
//! txAlphaBlend).
//!
//! См. также замечания к функции txAlphaBlend().
//!
//! @see txCreateCompatibleDC(), txCreateDIBSection(), txLoadImage(), txDeleteDC(), txAlphaBlend()
//!
//! @usage См. в функции txCreateDIBSection().
//}----------------------------------------------------------------------------------------------------------------
HDC txUseAlpha (HDC image);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Сохраняет в файл изображение в формате BMP.
//!
//! @param filename Имя файла с расширением "BMP", куда будет записано изображение в формате BMP.
//! @param dc Дескриптор холста, изображение которого сохраняется в файл. Необязателен. Если txDC(),
//! сохраняется изображение окна TXLib.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @see txCreateCompatibleDC(), txLoadImage(), txDeleteDC(), txBitBlt(), txAlphaBlend(), txTransparentBlt()
//!
//! @usage @code
//! txDrawMan (50, 110, 100, 100, TX_YELLOW, 0.3, -0.5, -0.4, 0, 0.8, 1, -1, 0.5, 1, 1);
//!
//! HDC dc = txCreateCompatibleDC (100, 110);
//! txBitBlt (dc, 0, 0, 100, 110, txDC());
//! txSaveImage ("TXLibMan.bmp", dc);
//!
//! txBitBlt (dc, 0, 0, 100, 110, txDC());
//! txBitBlt (txDC(), 200, 200, 0, 0, dc);
//! txAlphaBlend (txDC(), 100, 100, 0, 0, dc, 0, 0, 0.25, 0);
//! txDeleteDC (dc);
//!
//! txSaveImage ("ScreenShot.bmp");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSaveImage (const char filename[], HDC dc = txDC());
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Utility functions
//! @name Вспомогательные функции
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Задерживает выполнение программы на определенное время.
//!
//! @param time Задержка в миллисекундах. Необязательна. Если не указана, то используется минимальная возможная
//! задержка.
//!
//! @return Реальное время задержки в миллисекундах.
//!
//! @note Перед началом задержки изображение в окне обязательно обновится, даже если рисование
//! заблокировано через txBegin(). @nn
//! Более полную информацию об обновлении изображения окна см. в функции txBegin(). См. также txEnd(),
//! txRedrawWindow(), txUpdateWindow().
//!
//! @see txBegin(), txEnd(), txUpdateWindow(), txDC()
//!
//! @usage @code
//! txSleep (500); // ПП: Поспать Полсекунды
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
double txSleep (double time = 0);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Блокирует обновление изображения окна, во избежание мигания.
//!
//! Для снятия блокировки используется функция txEnd().
//!
//! TXLib реализует двойную буферизацию. Все рисовательные действия происходят со скрытым HDC, находящемся
//! в памяти, и его содержимое периодически автоматически копируется на экран. Это иногда приводит к мерцанию.
//! Автоматическое копирование можно выключить функцией txBegin() и обратно включить функцией txEnd(),
//! в этом случае содержимое окна можно перерисовать функциями txRedrawWindow() или txSleep().
//!
//! Если в программе требуется задержка, то используйте функции txRedrawWindow() или txSleep(), так как они
//! автоматически обновляют изображение, независимо от состояния блокировки.
//!
//! @warning Избегайте блокирования на долгое время. Это может привести к дефектам изображения в окне.
//!
//! @note Если нажата клавиша Alt+PrintScreen, то блокировка временно отменяется.
//!
//! @return Значение счетчика блокировки (если 0, то рисование разблокировано).
//!
//! @see txEnd(), txSleep(), txUpdateWindow(), txDC(), txVideoMemory(), txTextCursor()
//!
//! @usage @code
//! txBegin(); // Здесь изображение "замерзнет"
//! txSetFillColor (TX_WHITE);
//! txClear(); // Это вызвало бы мигание без txBegin()
//! txSetFillColor (TX_RED);
//! txRectangle (100, 100, 200, 200);
//! txEnd(); // Здесь мы сразу увидим окончательный рисунок
//!
//! //
//! // Как правильно использовать блокировку обновления окна в циклах:
//! //
//!
//! int x = 0, y = 0;
//!
//! txBegin(); // Отключаем автоматическое обновление окна
//!
//! while (!GetAsyncKeyState (VK_ESCAPE)) // Цикл, пока не нажата клавиша ESCAPE
//! {
//! txSetFillColor (TX_BLACK);
//! txClear(); // Очищаем окно
//!
//! txSetFillColor (TX_DARKGRAY); // Рисуем объект. По-нормальному это надо сделать в отдельной
//! txCircle (x, y, 50); // функции. На экране это рисование пока не будет видно,
//! txSetFillColor (TX_LIGHTGRAY); // из-за отключенного обновления и двойной буферизации.
//! txCircle (x, y, 30);
//! txSetFillColor (TX_WHITE);
//! txCircle (x, y, 10);
//!
//! x += 5; // Изменяем координаты объекта
//! y += 5;
//!
//! txSleep (50); // Делаем задержку. При этом изображение окна обновляется.
//! }
//!
//! txEnd(); // После цикла включаем автоматическое обновление окна
//!
//! //
//! // Как *НЕ* правильно использовать блокировку:
//! //
//!
//! txBegin();
//!
//! while (!GetAsyncKeyState (VK_ESCAPE))
//! {
//! txSetFillColor (TX_BLACK); // Очищаем окно
//! txClear();
//! txSleep (50); // Первая ошибка: окно обновляется в нелогичный момент,
//! // когда оно только что очищено. Мы увидим только черный фон.
//!
//! txSetFillColor (TX_DARKGRAY); // Рисуем объект, но он не будет виден.
//! txCircle (x, y, 50);
//! txSetFillColor (TX_LIGHTGRAY);
//! txCircle (x, y, 30);
//! txSetFillColor (TX_WHITE);
//! txCircle (x, y, 10);
//!
//! x += 5;
//! y += 5;
//!
//! txEnd(); // Вторая ошибка: при первом же обороте цикла отключается
//! } // блокировка обновления, от чего изображение начинает мигать.
//!
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txBegin();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Разблокирует обновление окна, заблокированное функцией txBegin().
//!
//! @warning Если txBegin() вызывалась несколько раз, то для снятия блокировки нужно столько же раз вызвать txEnd().
//!
//! @return Значение счетчика блокировки (если 0, то рисование разблокировано).
//!
//! Более полную информацию об автоматическом обновлении см. в функции txBegin(). См. также txRedrawWindow(),
//! txUpdateWindow(), txSleep().
//!
//! @note Если нажата клавиша Alt+PrintScreen, то блокировка временно отменяется.
//!
//! @see txBegin(), txSleep(), txUpdateWindow(), txDC(), txVideoMemory(), txTextCursor()
//!
//! @usage @code
//! txBegin(); // Здесь изображение "замерзнет"
//! txSetFillColor (TX_WHITE);
//! txClear(); // Это вызвало бы мигание без txBegin()
//! txSetFillColor (TX_RED);
//! txRectangle (100, 100, 200, 200);
//! txEnd(); // Здесь мы сразу увидим окончательный рисунок
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txEnd();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Обновляет изображение в окне TXLib вручную.
//!
//! Более полную информацию об автоматическом обновлении см. в функции txBegin(). См. также txEnd(),
//! txUpdateWindow(), txSleep().
//!
//! @warning Реализация этой функции неэффективна: она вызывает txSleep (0), что вызывает задержку. Чтобы сделать более
//! эффективную реализацию, посмотрите исходный текст функций txRedrawWindow() и txSleep() и сделайте лучше.
//! Либо напишите свою, более быструю библиотеку на основе Win32 GDI, GDI Plus, OpenGL, DirectX, SDL или SFML.
//!
//! @see txWindow(), txBegin(), txEnd(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! txBegin(); // Выключаем автоматическое обновление экрана
//!
//! txCircle (100, 100, 50); // Рисуем -- изображение не появляется
//!
//! Sleep (3000); // не txSleep()! txSleep() сама обновит изображение на экране
//!
//! txRedrawWindow(); // Обновляем экран вручную -- изображение появляется
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline void txRedrawWindow();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Разрешает или запрещает автоматическое обновление изображения в окне.
//!
//! @param update Режим обновления (true -- разрешить, false -- запретить). Необязателен. Если не указан, то
//! "разрешить".
//!
//! @return Предыдущее состояние режима обновления.
//!
//! В отличие от txBegin() и txEnd(), которые поддерживают вложенные вызовы и работают как "скобки для
//! замерзания картинки", txUpdateWindow() позволяет явно установить или снять блокировку автоматического
//! обновления экрана.
//!
//! Более полную информацию об автоматическом обновлении см. в функции txBegin(). См. также txEnd(),
//! txRedrawWindow(), txSleep().
//!
//! @see txBegin(), txEnd(), txSleep(), txUpdateWindow(), txDC(), txVideoMemory(), txTextCursor(), txLock(),
//! txUnlock(), txGDI()
//!
//! @usage @code
//! txUpdateWindow (false);
//! ...
//! txUpdateWindow();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txUpdateWindow (int update = true);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Устанавливает текущий активный объект GDI.
//!
//! @param obj Дескриптор объекта GDI.
//! @param dc Холст (контекст рисования), в котором устанавливается текущий активный объект GDI. Необязателен.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @note Предыдущий выбранный объект того же типа (PEN/BRUSH/BITMAP и т.п.), как и @c obj, @b уничтожается.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txSelectFont()
//!
//! @usage @code
//! HPEN pen = CreatePen (PS_DASH, 1, RGB (255, 128, 0));
//! txSelectObject (pen);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSelectObject (HGDIOBJ obj, HDC dc = txDC());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Делает нечто иногда удобное. См. название функции.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! У этой функции есть синоним с простым понятным названием, поищите его в файле библиотеки, около
//! @a определения этой функции. Или можно @strike скопировать @endstrike набрать это километровое имя
//! и посмотреть, что получится.
//!
//! @see txCreateWindow(), txSleep()
//!
//! @usage @code
//! int main()
//! {
//! txCreateWindow (800, 600);
//!
//! txSetTextAlign (TA_CENTER);
//! txTextOut (txGetExtentX()/2, txGetExtentY()/2, "Press any key to exit!");
//! @endcode
//
// +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее"
// |
// v
// txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
//! @code txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
//! return 0;
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
// +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее"
// |
// v
bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Уничтожает окно.
//!
//! @param wnd Дескриптор окна для уничтожения. Необязательно. Если не указан, уничтожается окно TXLib.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @warning Если уничтожается окно TXLib, функция main() принудительно прерывается и программа завершается.
//! При этом @b не гарантируется правильное завершение программы, поэтому так делать @b не рекомендуется.
//!
//! @see txCreateWindow()
//!
//! @usage @code
//! txDestroyWindow(); // Farewell to the world
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txDestroyWindow (HWND wnd = txWindow());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Оценивает скорость работы компьютера.
//!
//! @return Скорость работы (графических операций) в условных единицах.
//!
//! @see txSleep(), txGetFPS()
//!
//! @usage @code
//! if (txQueryPerformance() < 1) printf ("Хочется новый компьютер");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
double txQueryPerformance() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Выдает количество кадров (вызовов этой функции) в секунду.
//!
//! @param minFrames Количество вызовов, после которых FPS начинает усредняться по последним @c txFramesToAverage
//! кадрам. Необязательно. Если не указано, используется txFramesToAverage.
//!
//! @return FPS (Frames per Second), т.е. количество кадров (вызовов этой функции) в секунду.
//!
//! @note Когда количество вызовов этой функции превысит @p minFrames, FPS начинает усредняться по последним
//! @c txFramesToAverage кадрам. Максимальный интервал усреднения -- @c txFramesToAverage кадров.
//!
//! @see txSleep(), txQueryPerformance()
//!
//! @usage См. в функции txCreateDIBSection().
//}----------------------------------------------------------------------------------------------------------------
//! @cond INTERNAL
#if defined (_TX_CPP11)
template
#else
const int txFramesToAverage = 5;
#endif
//! @endcond
double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard;
//! @}
//}
//=================================================================================================================
//{ Mouse functions
//! @name Работа с Мышью!
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Возвращает позицию Мыши!
//!
//! @return Позиция Мыши! как структура POINT, отсчитывающаяся от левого верхнего угла окна.
//!
//! @note Если окна TXLib нет @strike (какой ужас!), @endstrike то координаты отсчитываются от верхнего левого
//! угла экрана.
//!
//! @warning Будьте осторожны в многофайловом проекте. Если эта функция вызвана не из того файла, где открыто окно,
//! координаты будут отсчитываться от верхнего левого угла экрана, а не от угла окна. См. замечания по
//! многофайловому проекту для функции @ref txCreateWindow().
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! RECT area = { 100, 100, 110, 110 };
//!
//! while (txMouseButtons() != 1)
//! {
//! if (In (txMousePos(), area)) txTextOut (100, 100, "http://vk.com/TiShtoTamDelaesh?!");
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline POINT txMousePos() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Возвращает X-Координату Мыши!
//!
//! @return X-координата Мыши!, отсчитывающаяся от левого верхнего угла окна.
//!
//! @note Если окна TXLib нет @strike (какой ужас!), @endstrike то координаты отсчитываются от верхнего левого
//! угла экрана.
//!
//! @warning Будьте осторожны в многофайловом проекте. См. замечание для функции @ref txMousePos().
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! while (txMouseButtons() != 1)
//! {
//! txCircle (txMouseX(), txMouseY(), 20);
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline double txMouseX() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Возвращает Y-Координату Мыши!
//!
//! @return Y-координата Мыши!, отсчитывающаяся от левого верхнего угла окна.
//!
//! @note Если окна TXLib нет @strike (какой ужас!), @endstrike то координаты отсчитываются от верхнего левого
//! угла экрана.
//!
//! @warning Будьте осторожны в многофайловом проекте. См. замечание для функции @ref txMousePos().
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! while (txMouseButtons() != 1)
//! {
//! txCircle (txMouseX(), txMouseY(), 20);
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline double txMouseY() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Возвращает состояние Кнопок Мыши!
//!
//! @return Состояние Кнопок Мыши!
//!
//! В возвращаемом значении выставленный в единицу 1-й (младший) бит означает нажатую левую Кнопку Мыши!,
//! 2-й -- правую Кнопку. @n
//! Например, возвращенное число 3 (двоичное 11) означает одновременное нажатие левой и правой Кнопок.
//!
//! @warning Если окно TXLib или соответствующее ему консольное окно неактивно, то возвращается @c 0. @nn
//!
//! @warning Будьте осторожны в многофайловом проекте. Если эта функция вызвана не из того файла, где открыто окно,
//! будет всегда возвращаться 0. См. замечания по многофайловому проекту для функции @ref txCreateWindow(). @nn
//!
//! @warning Если нужно проверить состояние Кнопок Мыши! в любом случае, то можно пользоваться функцией @c GetAsyncKeyState()
//! с аргументами @c VK_LBUTTON, @c VK_RBUTTON или @c VK_MBUTTON. Старший бит 16-битового слова (битовая
//! маска @c 0x8000) покажет состояние соответствующей Кнопки Мыши! (см. пример).
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! while (txMouseButtons() != 3)
//! {
//! if (txMouseButtons() & 1) txCircle (txMouseX(), txMouseY(), 20);
//! if (txMouseButtons() & 2) txLine (txMouseX(), txMouseY(), 0, 0);
//!
//! if (GetAsyncKeyState (VK_LBUTTON) & 0x8000) printf ("VK_LBUTTON ");
//!
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline unsigned txMouseButtons() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Ловит Мышь!
//!
//! @param shouldEat To eat, or not to eat: that is the question.
//!
//! @return Пойманная Мышь!
//!
//! @note Эту функцию можно применять, только если Вы -- Кот. =^..^= @n
//! Поэтому в текущей версии она не реализована :)
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! void CatsLife()
//! {
//! try
//! {
//! while (true)
//! {
//! Mouse mouse = txCatchMouse();
//! Eat (mouse);
//! txSleep();
//! }
//! }
//!
//! catch (Mouse& mouse)
//! {
//! Eat (mouse); // Just do eat (R). Anyway
//! }
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
inline Mouse& txCatchMouse (bool shouldEat = true);
#endif
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Console functions
//! @name Функции консоли
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает цветовые атрибуты консоли.
//!
//! @param colors Цветовые атрибуты консоли. Необязательны. Если не указаны, то цвет -- светло-серый.
//!
//! @return Предыдущие цветовые атрибуты консоли.
//!
//! @b Атрибуты -- это цвет текста (colorText) и цвет фона (colorBackground), объединенные вместе: @nn
//! colors = colorText + colorBackground * 16 @nn
//! либо @nn
//! colors = colorText | (colorBackground \<\< 4) @nn
//! Цвета атрибутов @b не имеют никакого отношения к цветам рисования, задаваемыми @ref txColors "TX_..."
//! константами, RGB(), txSetColor(), txSetFillColor() и т.д. Значения цветов см. ниже.
//!
//! @title Значения цветов атрибутов
//! @table @tr Dec @td @c Hex @td @td Dec @td @c Hex @td
//! @tbr
//! @tr 0 = @td @c 0x0 @td = BLACK (Черный), @td 8 = @td @c 0x8 @td = DARKGRAY (Темно-серый),
//! @tr 1 = @td @c 0x1 @td = BLUE (Синий), @td 9 = @td @c 0x9 @td = LIGHTBLUE (Светло-синий),
//! @tr 2 = @td @c 0x2 @td = GREEN (Зеленый), @td 10 = @td @c 0xA @td = LIGHTGREEN (Светло-зеленый),
//! @tr 3 = @td @c 0x3 @td = CYAN (Сине-зеленый), @td 11 = @td @c 0xB @td = LIGHTCYAN (Светло-сине-зеленый),
//! @tr 4 = @td @c 0x4 @td = RED (Красный), @td 12 = @td @c 0xC @td = LIGHTRED (Светло-красный),
//! @tr 5 = @td @c 0x5 @td = MAGENTA (Малиновый), @td 13 = @td @c 0xD @td = LIGHTMAGENTA (Светло-малиновый),
//! @tr 6 = @td @c 0x6 @td = DARKYELLOW (Темно-желтый), @td 14 = @td @c 0xE @td = YELLOW (Желтый),
//! @tr 7 = @td @c 0x7 @td = LIGHTGRAY (Светло-серый), @td 15 = @td @c 0xF @td = WHITE (Белый).
//! @endtable
//!
//! Цвета букв образуются соединением слов @c FOREGROUND_\<название цвета\>, например, @c FOREGROUND_WHITE. @nn
//! Цвета фона образуются соединением слов @c BACKGROUND_\<название цвета\>, например, @c BACKGROUND_CYAN.
//!
//! В шестнадцатеричной системе счисления атрибуты задавать так: если нужен, скажем, желтый цвет
//! на синем фоне, то его код будет @c 0x1e (старшая цифра -- старшие 4 бита -- это цвет фона, младшая
//! цифра -- младшие 4 бита -- это цвет текста).
//!
//! @see txTextCursor(), txGetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleCursorPos(), txGetConsoleExtent(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLUE);
//! printf ("А в небе 0x1 есть город 0xE"); // (c) Б. Гребенщиков
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает текущие цветовые атрибуты консоли.
//!
//! @return Текущие цветовые атрибуты консоли. См. txSetConsoleAttr().
//!
//! @see txTextCursor(), txSetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleCursorPos(), txGetConsoleExtent(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! unsigned attr = txGetConsoleAttr();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned txGetConsoleAttr() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Стирает текст консоли.
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! При стирании используются текущие атрибуты (цвета текста и фона) консоли.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txGetConsoleCursorPos(), txGetConsoleExtent(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! txClearConsole(); // Ну вот и все, дружок
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txClearConsole();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Устанавливает позицию мигающего курсора консоли.
//!
//! @param x X-координата курсора в пикселях.
//! @param y Y-координата курсора в пикселях.
//!
//! @return Предыдущее положение мигающего курсора в пикселях, в
//! структуре POINT.
//!
//! @note Нельзя установить совсем любую позицию. Текст в консоли расположен по прямоугольной сетке, размер
//! которой зависит от размеров шрифта консоли. Устанавливаемая позиция округляется, чтобы курсор попал
//! в ячейку сетки. См. пример к функции txGetConsoleFontSize().
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txGetConsoleCursorPos(), txGetConsoleExtent(),
//! txClearConsole()
//!
//! @usage @code
//! txSetConsoleCursorPos (txGetExtentX(), txGetExtentY()); // Центр Вселенной
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txSetConsoleCursorPos (double x, double y);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает позицию мигающего курсора консоли.
//!
//! @return Положение мигающего курсора в пикселях, в
//! структуре POINT.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleExtent(),
//! txClearConsole()
//!
//! @usage @code
//! POINT pos = txGetConsoleCursorPos();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleCursorPos();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает размер консоли.
//!
//! @return Положение мигающего курсора в @b символах, в
//! структуре POINT.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleExtent(),
//! txClearConsole()
//!
//! @usage @code
//! POINT size = txGetConsoleExtent();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleExtent();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Возвращает размеры шрифта консоли.
//!
//! @return Размеры шрифта консоли в пикселях, в
//! структуре POINT.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleExtent(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! POINT size = txGetConsoleFontSize();
//! txSetConsoleCursorPos (5 * size.x, 10 * size.y); // А теперь мигай вот там
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleFontSize() tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Запрещает или разрешает рисование мигающего курсора в окне.
//!
//! @param blink false -- запретить мигающий курсор. Если не указано, то мигание разрешается.
//!
//! @return Предыдущее значение состояния курсора.
//!
//! @see txSetConsoleAttr(), txGetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleCursorPos(),
//! txGetConsoleFontSize(), txClearConsole(), txCreateWindow(), txUpdateWindow(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! txTextCursor (false);
//! ...
//! txTextCursor();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txTextCursor (bool blink = true);
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Other staff not related to drawing
//! @name Другие полезные функции, не связанные с рисованием
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Воспроизводит звуковой файл.
//!
//! @param filename Имя звукового файла, включая расширение. Если не указано или NULL, то останавливает звук.
//! @param mode Режим воспроизведения. Необязательно. Если не указан, то SND_ASYNC (см. ниже).
//!
//! @return Если операция была успешна -- true, иначе -- false.
//!
//! @title Режимы воспроизведения: @table
//! @tr @c SND_ASYNC @td Звук проигрывается одновременно с работой программы. @n
//! Чтобы отменить звучание, вызовите txPlaySound (NULL).
//! @tr @c SND_SYNC @td Выполнение программы приостанавливается до окончания воспроизведения звука.
//! @tr @c SND_LOOP @td Зацикливать звук при воспроизведении. @n
//! Чтобы отменить звучание, вызовите txPlaySound (NULL).
//! @tbr
//! @tr @c SND_NODEFAULT @td Не использовать звук по умолчанию, если нельзя проиграть указанный звуковой файл.
//! @tr @c SND_NOSTOP @td Если какой-либо звук уже проигрывается, @b не останавливать его для запуска указанного звука.
//! @tr @c SND_APPLICATION @td Проигрывать звук, используя программу, зарегистрированную для данного типа звуковых файлов.
//! @endtable
//!
//! @note Поддерживаются только файлы в формате WAV. Остальные форматы (MP3 и др.) надо перекодировать в WAV.
//! Переименование со сменой расширения не поможет, как и в случае с форматом картинок в txLoadImage().
//!
//! @see txSpeak(), txPlayVideo()
//!
//! @usage @code
//! txPlaySound ("tada.wav"); // So happy that this always exists
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Читает @strike мысли @endstrike текст вслух.
//!
//! @param text Текст для @strike внеклассного @endstrike чтения, как для функции @c printf().
//!
//! @return Время чтения текста в миллисекундах (если не указана опция @c \\a). Если -1, то текст не прочитался. :(
//!
//! Для использования этой функции укажите перед включением файла @c TXLib.h определите имя @c TX_USE_SPEAK
//! командой \#define TX_USE_SPEAK @b до строки с \#include "TXLib.h" для того, чтобы TXLib задействовал
//! библиотеку Microsoft Speech API (SAPI.h). См. пример использования ниже.
//!
//! Текст читается голосом, установленным по умолчанию в Панели управления Windows. Если голос поддерживает русский
//! язык (начиная с Windows 8.1), то можно использовать русские фразы. До Windows 8.1 они не проговариваются. Если
//! голос читает плохо, или с акцентом, то смените его в Панели Управления Windows.
//!
//! @note Если текст начинается с символа @c \\v, то он еще и печатается на экране (сам символ @c \\v не печатается). @nn
//!
//! @note Если текст начинается с символа @c \\a, то он проговаривается асинхронно: txSpeak() возвращается сразу после
//! вызова, и чтение идет параллельно с работой программы. Без этой опции txSpeak() делает паузу в программе,
//! ожидая конца чтения, и только потом возвращается. @nn
//!
//! @note Если текст начинается с символа @c <, то он трактуется как формат SSML (см. ниже). @nn
//!
//! @note Если строка с текстом пустая (не считая @c \\v и @c \\a), то txSpeak() лучше скажет что-то более важное, чем
//! просто молчание. :)
//!
//! @warning Для работы этой функции TXLib требует наличия файла @c SAPI.h из стандартной библиотеки Windows. Не на всех
//! платформах он есть. Если этот файл не найден, то будет ошибка компиляции. @nn
//! Этот файл точно есть в Visual Studio или в этой сборке платформы MinGW: https://nuwen.net/mingw.html
//!
//! @note Вы можете настраивать синтез речи, используя язык разметки @b SSML (Speech Synthesis Markup Language).
//! Признаком наличия разметки SSML является наличие открывающей угловой скобки @c < в начале сообщения (после
//! опций @c \\v и @c \\a). В этом случае будьте осторожны с амперсандами @c &, кавычками и знаками "меньше"
//! @c \< и "больше" @c \>, а также другими спецсимволами XML. Если вы не знаете, как задавать их в XML, то
//! не используйте. Формату SSML нужно строго соответствовать, иначе программа упадет, @strike как это принято
//! у Microsoft. @endstrike @nn
//! Если вам не нравится, что надо каждый раз указывать заголовок SSML, то вам это правильно не нравится.
//! Сделайте функцию-обертку над txSpeak, заодно познакомитесь, как делать функции с переменным числом параметров.
//! Не забудьте о @c vsnprintf @ (vsprintf), эти функции сэкономят вам немало сил.
//!
//! @see txPlaySound(), txPlayVideo(), txMessageBox(), txOutputDebugPrintf(), txPause()
//!
//! @usage @code
//! #define TX_USE_SPEAK
//! #include "TXLib.h"
//!
//! int main()
//! {
//! txSpeak ("TX Library is cool!");
//!
//! txSpeak ("\vДобрый вечер, котики. Вы все мыши. Goog evening, kittens. You are all mices.");
//!
//! txSpeak ("" // SSML format
//! "Goog evening, kittens. You are all mices."
//! "");
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txSpeak (const char* text, ...) tx_printfy (1);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Проигрывает видео.
//!
//! @param x X-координата верхнего левого угла видео. См. предупреждение ниже.
//! @param y Y-координата верхнего левого угла видео. См. предупреждение ниже.
//! @param width Ширина видео. Если 0, то равно ширине окна. Также см. предупреждение ниже.
//! @param height Высота видео. Если 0, то равно высоте окна. Также см. предупреждение ниже.
//! @param fileName Имя видеофайла (включая расширение) или любого другого источника, с которым работает VideoLAN
//! (rtsp://, http:// и т.д.). Если имя -- пустая строка @c (""), то проводится только проверка
//! на наличие видеопроигрывателя.
//! @param zoom Масштаб изображения. Необязателен. Если не указан, то равен 0 (Автомасштабирование).
//! @param gain Громкость звука, от 0 до 8 (800%). Необязательна. Если не указана, то равна 1 (100%).
//! @param wnd Окно, в котором воспроизводится видео. Необязательно. Если не указано, то используется
//! окно TXLib.
//!
//! @return Время воспроизведения в миллисекундах (если не указана опция @c \\a). Если меньше или равно 0,
//! то видео не запустилось. :( См. коды ошибок ниже.
//! @nn
//! Если указана опция @c \\a, то возвращаемое значение -- дескриптор (HWND) окна видеопотока
//! (см. "Асинхронное воспроизведение").
//!
//! @title Возвращаемые значения в случае ошибки: @table
//! @tr @c INT_MIN @td Не найден видеопроигрыватель.
//! @tr @c INT_MIN+1 @td Не найден видеофайл.
//! @tr @c INT_MIN+2 @td Внутренняя ошибка регистрации класса окна видеопотока.
//! @tr @c INT_MIN+3 @td Внутренняя ошибка создания окна видеопотока.
//! @tr @c INT_MIN+4 @td Внутренняя ошибка запуска VideoLAN.
//! @tr Другие отрицательные значения @td Код завершения процесса VideoLAN с обратным знаком.
//! @endtable
//!
//! @par Асинхронное воспроизведение видео
//! @n
//! Если в параметре @c fileName самым первым символом поставить символ @c \\a, то файл будет
//! воспроизводиться асинхронно: txPlayVideo() возвратится сразу после вызова, а воспроизведение
//! видео пойдет параллельно с работой программы. Само имя файла на диске менять не надо.
//! Воспроизведение завершится, когда закончится видеофайл, или когда будет закрыто окно TXLib.
//! См. пример использования.
//! @nn
//! Без этой опции txPlayVideo() делает паузу в программе, ожидая конца воспроизведения, и только
//! потом возвращается.
//! @nn
//! В случае асинхронного воспрооизведения возвращаемым значением функции txPlayVideo() будет не
//! время ее работы, а дескриптор окна видеопотока (HWND). С его помощью можно контролировать это
//! окно, его положение на экране, размеры, видимость и другие свойства. См. функции
//! MoveWindow(),
//! ShowWindow()
//! и многие другие в MSDN. Гуглите. Также см. пример использования.
//! @nn
//! Досрочно прервать асинхронное воспроизведение можно, уничтожив окно видеопотока с помощью
//! функции txDestroyWindow().
//! @nn
//! Принудительно завершить асинхронное воспроизведение @b всех видео можно, сделав вызов
//! txPlayVideo (NULL).
//!
//! @warning Если в последнем параметре @c (wnd) указано @b не окно TXLib, а какое-либо другое, то координаты
//! видео @c x, @c y и его размеры @c width, @c height игнорируются. В этом слчае видеопоток будет
//! занимать всю клиентскую область окна, указанного параметром @c wnd. См. пример использования.
//!
//! @note Воспроизведение видео требует установки внешней программы @c VideoLAN @c (vlc.exe) версии 3.0 или
//! новее. Ее можно скачать с официального сайта VideoLAN.org.
//! Без установки @c VideoLAN видео воспроизводиться не будет и выведется сообщение об ошибке.
//! @nn
//! Если после установки VideoLAN программа @c (vlc.exe) все равно не найдена и выводится
//! сообщение об этой ошибке, то установите не 64-битную версию VideoLAN, а 32-битную @c (x86).
//!
//! @see Кот Мару!, txPlaySound(), txSpeak(),
//! txMessageBox(), txOutputDebugPrintf(), txPause()
//!
//! @usage @code
//! // Кот Мару, 24 000 000+ просмотров. А ты чего добился в жизни? :)
//!
//! #define MARU_ON_YOUTUBE "http://ded32.net.ru/www.youtube.com-watch-z_AbfPXTKms"
//! // Cached from www.youtube.com/watch/z_AbfPXTKms
//! int main() // Because Google prevents direct playing from Youtube
//! {
//! txCreateWindow (800, 500);
//! txSetFillColor (TX_BLUE);
//! txClear();
//!
//! txDrawText (0, 0, txGetExtentX(), txGetExtentY(), "Press ESC to stop!");
//! txSleep();
//!
//! if (txPlayVideo ("") <= 0) return TX_ERROR ("А чего вы хотели? VideoLAN не найден..."), 1;
//!
//! txPlayVideo ("\a" MARU_ON_YOUTUBE);
//!
//! txPlayVideo (580, 330, 200, 150, MARU_ON_YOUTUBE, 0, 0);
//!
//! // Для тех, кто [добился] дождался...
//!
//! system ("cmd.exe /c start /min notepad.exe");
//! double dt = 0.04 / (txQueryPerformance() + 1);
//!
//! HWND notepad = FindWindow ("Notepad", NULL);
//! if (!notepad) return 1;
//!
//! txPlayVideo ("\a" MARU_ON_YOUTUBE, 0, 1, notepad);
//!
//! HWND wnd = (HWND) txPlayVideo (0, 330, 200, 150, "\a" MARU_ON_YOUTUBE, 0, 0);
//!
//! for (double t = 0; !GetAsyncKeyState (VK_ESCAPE); t += dt)
//! {
//! static const POINT cent = { GetSystemMetrics (SM_CXSCREEN) / 2, GetSystemMetrics (SM_CYSCREEN) / 2 };
//! static const POINT size = { 500, 400 };
//!
//! MoveWindow (notepad, cent.x + ROUND (cent.y/2 * cos (t)) - size.x/2,
//! cent.y - ROUND (cent.y/2 * sin (t)) - size.y/2, size.x, size.y, false);
//!
//! ShowWindow (notepad, SW_RESTORE);
//!
//! MoveWindow (wnd, ROUND (t*100) % 1000 - 200, 330, 200, 150, false);
//!
//! Sleep (20);
//! }
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
double zoom = 0, double gain = 1, HWND wnd = txWindow());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Проигрывает видео.
//!
//! @param fileName Имя видеофайла (включая расширение) или любого другого источника, с которым работает VideoLAN
//! (rtsp://, http:// и т.д.). Если имя -- пустая строка @c (""), то проводится проверка на наличие
//! видеопроигрывателя.
//! @param zoom Масштаб изображения. Необязателен. Если не указан, то равен 0 (Автомасштабирование).
//! @param gain Громкость звука, от 0 до 8 (800%). Необязательна. Если не указана, то равна 1 (100%).
//! @param wnd Окно, в котором воспроизводится видео. Необязательно. Если не указано, то используется окно TXLib.
//!
//! @return См. в функции txPlayVideo() выше.
//!
//! См. описание в функции txPlayVideo() выше.
//}----------------------------------------------------------------------------------------------------------------
intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow());
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Проверяет, нажата ли указанная клавиша.
//!
//! @param key Код (номер) клавиши, как правило, заданный константой (VK_SPACE, VK_LEFT, 'W' и т.п.)
//!
//! @return true, если указанная клавиша нажата, false -- если не нажата.
//!
//! @note В отличие от оригинальной функции GetAsyncKeyState(), возвращает false, если окно TXLib не активно.
//!
//! @usage @code
//! void PlayBall();
//!
//! int main()
//! {
//! txCreateWindow (800, 600);
//!
//! PlayBall();
//! }
//!
//! void PlayBall()
//! {
//! int x = 100, y = 100;
//! int vx = 5, vy = 7;
//! int ax = 0, ay = 1;
//! int dt = 1;
//!
//! txSetColor (TX_LIGHTGREEN);
//! txSetFillColor (TX_GREEN);
//!
//! while (!txGetAsyncKeyState (VK_ESCAPE)) // Погуглите любой код VK_...,
//! { // и найдете их все
//! txCircle (x, y, 20);
//!
//! vx += ax * dt; // First velocity, then position: this gives more precision
//! vy += ay * dt; // See: http://en.wikipedia.org/wiki/Backward_Euler_method
//!
//! x += vx * dt;
//! y += vy * dt;
//!
//! if (x > 800) { vx = -vx; x = 800; } // = 800 is not the precise solution. Can you make it better?
//! if (x < 0) { vx = -vx; x = 0; }
//! if (y > 600) { vy = -vy; y = 600; }
//! if (y < 0) { vy = -vy; y = 0; }
//!
//! if (txGetAsyncKeyState (VK_LEFT)) vx--;
//! if (txGetAsyncKeyState (VK_RIGHT)) vx++;
//! if (txGetAsyncKeyState (VK_UP)) vy--;
//! if (txGetAsyncKeyState (VK_DOWN)) vy++;
//! if (txGetAsyncKeyState (VK_SPACE)) vx = vy = 0;
//! if (txGetAsyncKeyState ('M')) printf ("Meow ");
//!
//! txSleep (20);
//! }
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txGetAsyncKeyState (int key);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выводит всплывающее сообщение в системном трее.
//!
//! @param flags Флаги сообщения.
//! @param title Заголовок сообщения.
//! @param format Строка для печати, как в printf().
//!
//! @title Флаги сообщения:
//! @table @tr @c NIIF_INFO @td Информация
//! @tr @c NIIF_WARNING @td Предупреждение
//! @tr @c NIIF_ERROR @td Сообщение об ошибке
//! @endtable
//!
//! @return Удалось ли отобразить сообщение.
//!
//! Функция формирует сообщение по правилам printf() и выводит во всплывающем окне.
//!
//! @warning
//! - Эта функция требует, чтобы при компиляции константа версии Internet Explorer @c (_WIN32_IE) была
//! задана не ниже 0x0500. Для этого надо либо включить TXLib.h вместо @c windows.h или перед ним.
//! Либо надо самостоятельно определить @c (\#define) эту константу. @n
//! С версией Internet Explorer это связано потому, что при его установке в Windows обновляются
//! многие компоненты (например, @c shell32.dll и @c comctl32.dll), которые влияют на функциональность
//! системы независимо от использования браузера). Сам Internet Explorer в отображении сообщения
//! не участвует.
//! - Сообщение не должно превышать _TX_BUFSIZE символов, иначе оно обрезается.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox(), txSpeak(), txPause()
//!
//! @usage @code
//! int hours = 3, minutes = 10;
//! const char station[] = "Юму";
//! ...
//! txNotifyIcon (NIIF_INFO, "Уважаемые пассажиры",
//! "Поезд на %s отправляется в %d:%d.", station, hours, minutes);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выводит сообщение в отладчике.
//!
//! @param format Строка для печати, как в printf().
//!
//! @return Количество напечатанных символов.
//!
//! Функция формирует сообщение по правилам printf() и передает его в OutputDebugString(). Ее вывод можно
//! перехватить отладчиком или утилитами-логгерами, например,
//! DbgView.
//! Если этого не сделать, и не задать первый символ @c '\\a' (см. ниже), то о сообщении никто не узнает. :(
//! @note
//! - Если первый символ в строке @c '\\a', то сообщение также дублируется txMessageBox().
//! - Если первый или второй символ в строке @c '\\f', то сообщение также дублируется printf().
//!
//! @warning Сообщение не должно превышать _TX_BIGBUFSIZE символов, иначе оно обрезается.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR(), txPrintf(), txNotifyIcon(), txMessageBox(), txStackBackTrace(), txPause()
//!
//! @usage @code
//! int x = 7;
//! ...
//! txOutputDebugPrintf ("Никто не узнает, что %d.\n", x);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txOutputDebugPrintf (const char format[], ...) tx_printfy (1);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Добрый дядюшка Принтф. Теперь шаболонный.
//!
//! @param format Строка для печати, все как в вашем любимом printf().
//! @param args Значения для печати.
//!
//! @return Количество напечатанных символов.
//!
//! Функция работает аналогично @c printf(). Однако, в силу применения @strike сноубордических @endstrike
//! вариадических шаблонов, она типобезопасна @d сама определяет тип печатаемых аргументов и подставляет
//! нужные символы преобразования типов. Допускается применение универсального символа типа @c %$ (или @c %?)
//! вместо других символов типов, таких как %d, %i, %c, %s, %p, %g и других.
//!
//! txPrintf() позволяет распечатывать типы, не встроенные в язык С++: строки С++ @c (std::string),
//! некоторые типы Win32 (например, @c POINT) и ваши собственные типы. Для того, чтобы ваши типы могли
//! печататься, надо определить пользовательский оператор вывода в поток STL. Вот, например, как определен
//! оператор вывода для структуры POINT:
//! @code
//! std::ostream& operator << (std::ostream& stream, const POINT& point)
//! {
//! stream << "{ x: " << point.x << ", y: " << point.y << " }";
//! return stream;
//! }
//! @endcode
//! Вы можете определить свой оператор вывода аналогично.
//!
//! На самом деле функция txPrintf() @d это обертка над операторами потокового вывода STL: @c operator @c <<.
//! Чудес не бывает, и в любом случае вывод пользовательских типов и автоматический подбор преобразований так
//! или иначе был бы основан на семействе перегруженных функций. Вместо того, чтобы создавать такое семейство
//! с нуля, TXLib использует уже существующий оператор @c <<, уже перегруженный для всех стандартных типов,
//! и про который все хорошо знают.
//!
//! @note Если нужно передать спецификаторы ширины или точности в виде переменных (для форматов @c %*, @c %.* или
//! @c %*.*), их нужно оборачивать в конструкции @c width() и @c precision() с помощью соответствующих функций.
//! См. пример ниже. @nn
//! - width_t width (int) @d Функция, оборачивающая спецификатор ширины в тип enum @c width_t.
//! - precision_t precision (int) @d Функция, оборачивающая спецификатор точности в тип enum @c precision_t.
//!
//! @warning Функция довольно медленная и жадная на ресурсы: во-первых, в силу применения весьма неоптимальных потоков
//! вывода STL @c (std::ostream), во-вторых, вывод сначала идет в строку (через поток @c std::ostringstream),
//! и только потом печатается. @nn
//! Если хочется быстрее и экономнее @d юзайте обычный принтф, он относительно быстрый. Или, как это принято
//! в @c TXLib @d делайте сами.
//!
//! Идея реализации взята у @strike признанного демона современного С++ @endstrike (Alexandrescu A., "Variadic
//! Templates are Funadic", Going Native 2012, Redmond, WA, USA, https://www.youtube.com/watch?v=dD57tJjkumE,
//! краткий обзор докладов см. https://habr.com/ru/post/139064).
//!
//! Есть также макрос TX_PRINTF (format, ...), который проверяет аргументы согласно спецификации
//! стандартной функции @c printf() и потом вызывает txPrintf(). Но он отвергает %c %$ (%?), требует точного
//! соответствия символов преобразований типов и не позволяет передавать типы, не встроенные изначально в язык
//! С++ (структурные и классовые типы). Используйте его, если в дальнейшем вы планируете перейти на обычный
//! @c printf().
//!
//! @warning Эта функция доступна только если ваш компилятор поддерживает стандарт C++11 (g++ с опцией @c -std=c++11
//! или выше, Microsoft Visual Studio 2013 или выше). Используйте макрос _TX_CPP11, который определен, если
//! компилятор поддерживает стандарт C++11.
//!
//! @see txFormat(), TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txNotifyIcon(), txMessageBox(), txPause()
//!
//! @usage @code
//! // +--+--+---+---+----+-----+---+--+
//! // |2 |3 | 4 | 5 | 6 | 7 | 8 | |
//! // +--+--+---+---+----+-----+---+--+
//! txPrintf ("|%$|%s|%5s|%*d|%.*f|%*.*$|%*$|%%|\n", // Arg#1
//! // | | | | | | | | |
//! // +--+--+---+---+----+-----+---+--+
//! 12, // Arg#2
//! "Cats power!", // Arg#3
//! std::string ("meow"), // Arg#4
//! width (10), 56, // Arg#5
//! precision (3), 3.141592653, // Arg#6
//! width (15), precision (6), 2.718281828, // Arg#7
//! width (20), POINT { 10, 20 }); // Arg#8
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
template
int txPrintf (const char* format, ArgsT... args);
#define TX_PRINTF(...) ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) )
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY)
enum width_t : int {};
enum precision_t : int {};
inline width_t width (int width) { return (width_t) width; }
inline precision_t precision (int prec) { return (precision_t) prec; }
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Печатает в строковый поток вывода, как sprintf().
//!
//! @param format Строка, как в sprintf().
//! @param stream Строковый поток вывода.
//! @param args Значения для печати.
//!
//! @return Количество напечатанных символов.
//!
//! @warning Эта функция доступна только если ваш компилятор поддерживает стандарт C++11 (g++ с опцией @c -std=c++11
//! или выше, MSVC 2013 или выше). Используйте макрос _TX_CPP11, который определен, если компилятор поддерживает
//! стандарт C++11.
//!
//! @see txPrintf(), TX_ERROR(), TX_DEBUG_ERROR(), txPrintf(), txNotifyIcon(), txMessageBox(), txStackBackTrace(),
//! txPause()
//!
//! @usage См. пример в функции txPrintf() выше.
//!
//}----------------------------------------------------------------------------------------------------------------
#if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
template
int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args);
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Печатает в строковый буфер, как sprintf().
//!
//! @param format Строка, как в sprintf().
//! @param buffer Буфер для вывода.
//! @param size Длина буфера вывода.
//! @param args Значения для печати.
//!
//! @return Количество напечатанных символов.
//!
//! @warning Эта функция доступна только если ваш компилятор поддерживает стандарт C++11 (g++ с опцией @c -std=c++11
//! или выше, MSVC 2013 или выше). Используйте макрос _TX_CPP11, который определен, если компилятор поддерживает
//! стандарт C++11.
//!
//! @see txPrintf(), TX_ERROR(), TX_DEBUG_ERROR(), txPrintf(), txNotifyIcon(), txMessageBox(), txStackBackTrace(),
//! txPause()
//!
//! @usage См. пример в функции txPrintf() выше.
//!
//}----------------------------------------------------------------------------------------------------------------
#if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
template
int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args);
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Форматирует строку, как sprintf().
//!
//! @param format Строка, как в sprintf().
//! @param args Значения для печати.
//!
//! @return Отформатированная строка в виде @c std::string.
//!
//! @warning Эта функция доступна только если ваш компилятор поддерживает стандарт C++11 (g++ с опцией @c -std=c++11
//! или выше, MSVC 2013 или выше). Используйте макрос _TX_CPP11, который определен, если компилятор поддерживает
//! стандарт C++11.
//!
//! @see txPrintf(), TX_ERROR(), TX_DEBUG_ERROR(), txPrintf(), txNotifyIcon(), txMessageBox(), txStackBackTrace(),
//! txPause()
//!
//! @usage См. пример в функции txPrintf() выше.
//!
//}----------------------------------------------------------------------------------------------------------------
#if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
template
std::string txFormat (const char* format, ArgsT... args);
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Вычисление размера массива в элементах
//!
//! @param arr Имя массива.
//!
//! @return Размер массива в элементах (не в байтах).
//!
//! Макрос sizearr() вычисляет размер массива в элементах, проверяя, можно ли его правильно вычислить при
//! компиляции.
//!
//! Макрос SIZEARR() просто делит размер всего массива в байтах на размер его элемента, получается размер
//! массива в элементах. @n
//! Он не проверяет, можно ли его правильно вычислить, и при неправильном использовании может
//! выдать неверный размер.
//!
//! @warning SIZEARR() выдает неверный размер, если определение массива вместе с его размером, известным при
//! компиляции, недоступно в месте использования SIZEARR(). См. пример ниже.
//!
//! @usage @code
//! void test()
//! {
//! // Размер этого массива, хоть и не указан, но может быть автоматически определен
//! // компилятором при компиляции программы. Он равен 4 (четыре структуры POINT).
//!
//! POINT coord[] = { {110, 110}, {120, 120}, {130, 110}, {140, 120} };
//!
//! // Здесь размер массива известен при компиляции, т.к. он был определен тут же.
//!
//! for (int i = 0; i < sizearr (coord) - 1; i++)
//! txLine (coord[i].x, coord[i].y, coord[i+1].x, coord[i+1].y);
//!
//! DrawLines1 (coord); // Попытка передать массив без передачи размера.
//! DrawLines2 (coord, sizearr (coord)); // Правильная передача размера массива.
//!
//! DrawLines3 (coord); // В принципе, можно и так, но тут ВОДЯТСЯ ШАБЛОНЫ.
//! }
//!
//! // Функции DrawLines1 и DrawLines2 определены так:
//!
//! void DrawLines1 (const POINT coord[])
//! {
//! // Массивы в Си передаются как указатели на начало массива. Поэтому:
//! // 1) sizearr здесь выдаст ошибку компиляции, и ее легко будет найти.
//! // 2) SIZEARR здесь неверно посчитает размер, что намного хуже, чем ошибка компиляции,
//! // т.к. он будет равен sizeof (POINT*) / sizeof (POINT) == 4/8 == 0, что станет
//! // трудноуловимой логической ошибкой времени исполнения.
//!
//! for (int i = 0; i < sizearr (coord) - 1; i++)
//! txLine (coord[i].x, coord[i].y, coord[i+1].x, coord[i+1].y);
//! }
//!
//! void DrawLines2 (const POINT coord[], int n)
//! {
//! // Здесь размер приходит как параметр n, так что все просто. Вызывающая сторона (функция
//! // test) правильно вычисляет его и передает функции DrawLines2, которая им пользуется.
//!
//! for (int i = 0; i < n - 1; i++)
//! txLine (coord[i].x, coord[i].y, coord[i+1].x, coord[i+1].y);
//! }
//!
//! // HIC SVNT TEMPLATES
//!
//! template
//! void DrawLines3 (const POINT (&coord) [size])
//! {
//! for (int i = 0; i < size - 1; i++)
//! txLine (coord[i].x, coord[i].y, coord[i+1].x, coord[i+1].y);
//! }
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define sizearr( arr ) ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) )
//! @cond INTERNAL
// See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx
template char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N]; // ;=P
// Another approach
#if defined (_TX_CPP11_MSVC15)
template constexpr size_t countof (const T (&) [N] ) { return N; }
#endif
//! @endcond
#define SIZEARR( arr ) ( sizeof (arr) / sizeof ((arr)[0]) )
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Генератор случайных чисел
//!
//! @param range Правая граница диапазона (@b не включая саму границу).
//!
//! @return Случайное целое число в диапазоне [0; range).
//!
//! Вы еще помните, что означают разные скобочки в обозначении интервалов? :)
//!
//! @warning Эта функция может мяукать. @strike Just because it can. @endstrike Потому что она не часть стандарта С++
//! или Windows, а зависит от TXLib'а. Если это вам не нравится, вы можете написать ее сами, с помощью
//! стандартной функции rand() и операции остатка от деления %. Подсказка: rand() % range.
//!
//! @usage @code
//! char message[100] = "Maybe...";
//! sprintf (message, "You SUDDENLY got %d bucks now. But note that tax rate is $%d.", random (100), 100);
//! txMessageBox (message, "Lottery");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int random (int range) tx_deprecated;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Генератор случайных чисел
//!
//! @param left Левая граница диапазона (@b включая саму границу).
//! @param right Правая граница диапазона (@b включая саму границу).
//!
//! @return Случайное целое число в диапазоне [left; right].
//!
//! Вы все еще помните, что означают разные скобочки в обозначении интервалов? :)
//!
//! @warning Эта функция может мяукать. @strike Just in case. @endstrike Потому что она не часть стандарта С++
//! или Windows, а зависит от TXLib'а. Если это вам не нравится, вы можете написать ее сами, с помощью
//! стандартной функции rand() и небольшой @strike уличной @endstrike магии с делением на RAND_MAX и
//! @strike таинственной @endstrike операцией вычитания.
//!
//! @usage @code
//! int money = random (-100, +100);
//! if (money < 0)
//! {
//! char message[100] = "Maybe...";
//! sprintf ("Проиграли в лотерею? Отдайте долг в %d рублей", -money);
//! txMessageBox (message, "Быстро!");
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline double random (double left, double right) tx_nodiscard tx_deprecated;
inline double random (std::nomeow_t, double left, double right) tx_nodiscard;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Проверка, находится ли параметр х внутри замкнутого интервала [a; b]
//!
//! @param x Проверяемый параметр.
//! @param a Левая граница (включительно).
//! @param b Правая граница (включительно).
//!
//! @return Если a \<= x && x \<= b, то истина, если нет -- ложь.
//!
//! @note Параметры этой функции названы не по смыслу: просто @c a и просто @c b. Так как @c a - это минимальное
//! значение, лучше бы назвать этот параметр @c min или как-либо еще, но осмысленно. Пусть математики
//! и любят короткие обозначения, но мы будем любить осмысленные - потому что мы круче. :)) На самом деле
//! это потому, что математики много пишут рукой, и писать длинные имена им сложно, а программисты набирают
//! текст в редакторе, где это делать проще. Не будем обижать математиков, они крутые. @b MLM - Math Lives
//! Matter! :) @nn
//! Когда будете писать свою аналогичную функцию (а вы точно будете ее писать, см. предупреждение), назовите
//! параметры осмысленно. Не следуйте плохим примерам из TXLib'а! (Они там есть для этого специально.)
//!
//! @warning Эта функция может мяукать. @strike Because cats are power! @endstrike Потому что она не часть стандарта
//! С++ или Windows, а зависит от TXLib'а. Если это вам не нравится, вы можете написать ее сами, используя
//! неравенства.
//!
//! @usage @code
//! while (txMouseButtons() != 1)
//! {
//! if (In (txMouseX(), 110, 120)) txTextOut (100, 100, "Meet the wall!");
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
template
inline bool In (Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated;
template
inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Проверка, находится ли точка pt внутри прямоугольника rect
//!
//! @param pt Проверяемая точка в виде POINT {x, y} .
//! @param rect Прямоугольник в виде RECT {left, top, right, bottom} .
//!
//! @return Результат проверки.
//!
//! Удобно для реализации экранных кнопок, нажимаемых курсором мыши.
//!
//! @warning Эта функция может мяукать. @strike Because cats are always right. @endstrike Потому что она не часть
//! стандарта С++ или Windows, а зависит от TXLib'а. Если это вам не нравится, вы можете написать ее сами.
//!
//! @usage @code
//! RECT button = { 100, 100, 150, 120 };
//!
//! txSetFillColor (TX_LIGHTGRAY);
//! txRectangle (button.left, button.top, button.right, button.bottom);
//!
//! txSetTextAlign();
//! txSetFillColor (TX_WHITE);
//! txTextOut (125, 115, "Cookie");
//!
//! for (;;)
//! {
//! if (In (txMousePos(), button))
//! {
//! txSetFillColor (TX_TRANSPARENT);
//! txRectangle (button.left, button.top, button.right, button.bottom);
//!
//! if (txMouseButtons())
//! {
//! txSetFillColor (TX_DARKGRAY);
//! txRectangle (button.left, button.top, button.right, button.bottom);
//!
//! txSetFillColor (TX_WHITE);
//! txTextOut (125, 115, "You got cookie");
//!
//! break;
//! }
//! }
//!
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
//! @{
inline bool In (const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated;
inline bool In (const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated;
//! @}
inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated;
inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Возвращает максимальное из двух чисел
//!
//! @param a Одно из чисел :)
//! @param b Другое из чисел :)
//!
//! @return Максимальное из двух чисел a и b.
//!
//! @warning Это @b макрос, и аргументы @c a и @c b могут вычисляться в нем два раза. Поэтому не используйте в нем
//! побочных действий @c ++, @c --, @c += и т.п. Например, @b не пишите так: int m = MAX (++x, y += 2);
//!
//! @see MIN()
//!
//! @usage @code
//! if (MAX (3, 7) != 7) printf ("Your CPU is broken, throw it away.");
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define MAX( a, b ) ( ((a) > (b))? (a) : (b) )
template
T max (const T& a, const T& b) { return (a > b)? a : b; } //!< Функциональная версия макроса @ref MAX @ingroup Misc
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Возвращает минимальное из двух чисел
//!
//! @param a Одно из чисел :)
//! @param b Другое из чисел :)
//!
//! @return Минимальное из двух чисел a и b.
//!
//! @warning Это @b макрос, и аргументы @c a и @c b могут вычисляться в нем два раза. Поэтому не используйте в нем
//! побочных действий @c ++, @c --, @c += и т.п. Например, @b не пишите так: int m = MIN (x--, y /= 2);
//!
//! @see MAX()
//!
//! @usage @code
//! if (MIN (3, 7) != 3) printf ("Your CPU is still broken, throw it away twice.");
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define MIN( a, b ) ( ((a) < (b))? (a) : (b) )
template
T min (const T& a, const T& b) { return (a < b)? a : b; } //!< Функциональная версия макроса @ref MIN @ingroup Misc
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Округляет число до целого
//!
//! @param x Число. @strike А вы как думали? @endstrike
//!
//! @return Округленное число, преобразованное в тип @c long.
//!
//! @usage @code
//! double weight = 5.5; // 5.5 kilos is the weight of Maru the Cat in 2012.
//! long Maru = ROUND (weight); // Should use ROUND() because Maru is so round. And long.
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // MSVC: C99 case
#define ROUND( x ) ( (long) round (x) )
#else
#define ROUND( x ) ( (long) floor ((x) + 0.5) )
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Переинициализирует математический сопроцессор
//!
//! Сбрасывает состояние математического сопроцессора, вызывая _fpreset() и разрешая генерацию исключений сопроцессора
//! для неверного результата (_EM_INVALID), денормализации (_EM_DENORMAL), деления на ноль (_EM_ZERODIVIDE), переполнения
//! (_EM_OVERFLOW) и антипереполнения (_EM_UNDERFLOW). Обычный вызов _fpreset() эти исключения маскирует, в результате
//! чего вычислительные ошибки могут оказаться незамеченными.
//!
//! Если вы хотите замаскировать эти исключения, вызывайте обычный _fpreset(), и затем проверяйте результат вычислений
//! на достоверность хотя бы с помощью std::isfinite (x).
//!
//! @note Поведение TXLib по умолчанию -- @b генерация этих исключений и их @b перехват TXLib'ом в виде @b ошибки. @nn
//! См. [1] пример работы с этими исключениями,
//! [2] статью о них.
//!
//! @usage @code
//! tx_fpreset();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
void tx_fpreset();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Число Пи
//!
//! @usage @code
//! if (txPI == 1) txMessageBox ("Вы попали в другую Вселенную.", "Поздравляем", MB_ICONSTOP);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
const double txPI = asin (1.0) * 2;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Очень удобное возведение числа в квадрат.
//!
//! @param x Число для возведения в него. (Кого? (Who?))
//!
//! @return Квадрат, полученный путем возведения в него числа, заданного для возведения в квадрат.
//!
//! @note Это пример, как не надо писать код: txSqr() -- функция с "медвежьей услугой". Иногда встречаются
//! те, кто любит печатать в функции результат ее вычислений (не данные для отладки, а именно результат),
//! вместо того, чтобы просто возвращать его туда, где эту функцию вызывали. Пусть эти люди воспользуются
//! приведенной txSqr() для какого-нибудь нужного дела, особенно в цикле. Пример, конечно, несколько преувеличен.
//! См. в исходном тексте код этой навязчивой радости.
//!
//! @usage @code
//! printf ("\n" "Радиус\t\t" "Площадь круга\n\n");
//!
//! for (double r = 100; r > 0; r--)
//! {
//! printf ("%6.2lf...", r);
//!
//! double square = M_PI * txSqr (r); // Надолго запомним эту площадь!
//! printf ("\b\b\b \t");
//!
//! printf ("%-.2lf\n", square);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline double txSqr (double x)
{
double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0)); // Бурная вычислительная деятельность
char str[1024] = "";
_snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr);
txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL ||
(
txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION),
txMessageBox ("Уйду я от вас", "Злые вы...", MB_ICONSTOP),
exit (EXIT_FAILURE), 0 //-V2509 //-V2014
);
txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика! \0" // А как это работает, а? //-V111
"С ума сойти... \0" //
"а КЭП подтверждает \0" // и кто это будет
"Главное - отчитаться\0" // поддерживать?..
"Невероятно, но факт \0"
"Кто бы мог подумать?\0" + GetTickCount() % 6 * 21);
return sqr; // Все же вернем значение. Мы же не звери
}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ну просто очень удобный макрос.
//!
//! @warning Это еще один пример, как не надо писать код. @nn
//! Макрос определен так: @nn
//! \#define z 0 @nn
//! Замечательный макрос! Теперь на одну переменную в программе стало меньше. :((
//!
//! @note (Используйте @c \#undef. С @c \#undef ваша программа станет
//! мягкой и шелковистой.)
//!
//! @usage @code
//! #define _TX_DESTROY_3D
//! #include "TXLib.h"
//!
//! // А теперь попробуйте объявить переменную z для расчета 3-D координат x, y, z:
//!
//! int z = 0; // Да! TXLib уничтожает трехмерность! Очень круто. :=/
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
#define _TX_DESTROY_3D
#endif
#if defined (_TX_DESTROY_3D)
#define z 0 // Читайте "Флатландию" Эбботта!
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Еще парочка макросов.
//!
//! @c please увеличивает вероятность успешного выполнения кода*.
//!
//! @c meow -- ...просто мяу :)
//!
//! @note * Это шутка :)
//!
//! @usage @code
//! #include "TXLib.h"
//!
//! int x = rand() meow // Как же без котиков?
//! int y = rand() meow
//! if (x+y > RAMD_MAX/2) please x = y = 0;
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define meow ;
#if defined (_MSC_VER) && !defined (_CLANG_VER)
#define мяу meow
#endif
#define please
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Обнулитель типов, не имеющих конструкторов
//!
//! @param type Имя типа.
//!
//! @return Значение типа @p type, покомпонентно инициализированное по умолчанию (для встроенных типов -- нулем).
//!
//! @usage @code
//! void f (POINT p);
//! ...
//!
//! POINT z = {}; f (z); // Так без ZERO
//!
//! f (ZERO (POINT)); // Так с ZERO
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define ZERO( type ) zero ()
//! @cond INTERNAL
template inline T zero() tx_nodiscard;
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Автоматический вызов функции при завершении другой функции (аналог @c __finally)
//!
//! @param func Тело автоматически вызываемой функции (фигурные скобки не обязательны).
//!
//! @note - @a Все переменные вызываемой функции связываются с переменными внешней функции по ссылке.
//! - Их названия и типы @a не указываются. Указывается только тело вызываемой функции.
//! - Синоним: tx_finally
//!
//! @see txAutoLock
//!
//! @usage @code
//! void some_func()
//! {
//! int x = 1;
//! tx_auto_func ($(x)); // Will be printed at return
//!
//! FILE* f = fopen (__FILE__".o.txt", "w");
//! tx_auto_func (fclose (f)); // Will be closed at return
//!
//! fprintf (f, "start: x = %d\n", x); // Do some job
//! x = 2; // Do some job
//! }
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define tx_auto_func( func ) _tx_auto_fun1 ( __LINE__, func )
#define _tx_auto_fun1( n, func ) _tx_auto_fun2 ( n, func )
#define _tx_auto_fun2( n, func ) auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; })
#define tx_finally(...) tx_auto_func (__VA_ARGS__)
template
struct _tx_auto_func_
{
typedef _tx_auto_func_ this_t;
T func_;
explicit _tx_auto_func_ (T func) : func_ (func) {}
~_tx_auto_func_ () { func_ (); }
private: _tx_auto_func_ () _tx_delete;
_tx_auto_func_ (const this_t&) _tx_delete;
this_t& operator = (const this_t&) _tx_delete;
};
template
_tx_auto_func_ _tx_auto_func (T func)
{
return _tx_auto_func_ (func);
}
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Замена стандартного макроса assert(), с выдачей сообщения через txMessageBox(), консоль и OutputDebugString().
//!
//! @param cond Условие для проверки.
//!
//! @return Не определено.
//!
//! Если условие, проверяемое TX_ASSERT(), истинно, то макрос ничего не делает. @n
//! Если условие оказывается ложно, то выводится диагностическое сообщение и программа аварийно завершается.
//!
//! @warning При компиляции в режиме Release (или если определен NDEBUG) TX_ASSERT превращается в пустой оператор. @n
//! Не надо помещать в TX_ASSERT() или в assert() действия, которые важны для работы алгоритма!
//!
//! @note Если условие @c cond может быть вычислено уже во время компиляции как ложное, компилятор может
//! предупредить об этом (как о делении на 0).
//! @note See: "JPL Institutional Coding
//! Standard for the C Programming Language", Jet Propulsion Laboratory, California Institute of Technology,
//! JPL DOCID D-60411, Ver. 1.0, March 3, 2009, page 15. @nn
//!
//! @note Стандартный макрос assert() переопределяется так, что становится эквивалентен TX_ASSERT().
//!
//! @warning Кто не юзает assert(), тот ест баги на десерт!
//!
//! @see asserted, verified, verify(), TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox(),
//! txNotifyIcon(), txStackBackTrace(), txPause(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! TX_ASSERT (0 <= i && i < ARRAY_SIZE);
//! assert (0 <= i && i < ARRAY_SIZE); // То же самое, что и TX_ASSERT
//!
//! FILE* input = fopen ("a.txt", "r");
//! TX_ASSERT (input);
//! assert (input); // То же самое, что и TX_ASSERT
//!
//! // Этот вызов fgets() НЕ будет выполнен в режиме Release:
//! assert (fgets (str, sizeof (str) - 1, input));
//!
//! // Здесь все будет правильно:
//! bool ok = (fclose (input) == 0);
//! TX_ASSERT (ok);
//! assert (ok); // То же самое, что и TX_ASSERT
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG)
#undef TX_ASSERT
#define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \
"Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 )
#else
#undef TX_ASSERT
#define TX_ASSERT( cond ) ((void) 1)
#endif
#ifdef assert
#undef assert
#endif
#define assert( cond ) TX_ASSERT (cond)
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выводит диагностическое сообщение в случае нулевого или ложного результата.
//!
//! @return Всегда 0.
//!
//! Суффиксная форма макроса assert(), не теряющая в режиме Release исполнения предиката.
//!
//! @note Предполагается, что операция в случае неуспеха возвращает 0 или false. @n@n
//! При компиляции в режиме Release (или если определен NDEBUG) asserted превращается в пустое место.
//!
//! @see assert(), verify(), verified, TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox(),
//! txNotifyIcon(), txStackBackTrace(), txPause(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! FILE* input = fopen ("a.txt", "r"); assert (input);
//!
//! // Этот вызов fgets() будет выполнен в любом случае:
//! fgets (str, sizeof (str) - 1, input) asserted;
//!
//! // Этот вызов fgets() НЕ будет выполнен в режиме Release:
//! assert (fgets (str, sizeof (str) - 1, input));
//!
//! (fclose (input) != 0) asserted;
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG)
#define asserted || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.")
#else
#define asserted || _txNOP (0)
#endif
#define verified asserted //!< For compatibility with assert macro
//! @cond INTERNAL
#define TX_NEEDED asserted //!< For compatibility with earlier releases
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выполняет команду (вычисляет выражение) и проверяет результат.
//!
//! @param expr Команда (выражение).
//!
//! @return 1, если выражение @p expr истинно, иначе 0.
//!
//! Если условие, проверяемое verify(), истинно, то макрос ничего не делает. @n
//! Если условие оказывается ложно, то выводится диагностическое сообщение и программа аварийно завершается.
//!
//! @note Действие макроса аналогично assert(), но при компиляции в режиме Release (или если определен NDEBUG)
//! verify @b не превращается в пустой оператор.
//!
//! @see verified, assert(), asserted, TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox(),
//! txNotifyIcon(), txStackBackTrace(), txPause(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! FILE* input = verify (fopen ("a.txt", "r"));
//!
//! // Этот вызов fgets() БУДЕТ выполнен в режиме Release:
//! verify (fgets (str, sizeof (str) - 1, input));
//!
//! // Здесь все тоже будет правильно:
//! verify (fclose (input) == 0);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG)
#undef verify
#define verify assert
#else
#undef verify
#define verify( expr ) ( expr )
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выводит развернутое диагностическое сообщение.
//!
//! @param msg Сообщение с произвольным количеством параметров в стиле функции @c printf().
//!
//! @note Этот макрос может распечатывать стек вызовов функций в консоли. По этому поводу см. замечания к функции
//! txStackBackTrace() и раздел @ref TXLibSetup "Установка библиотеки", п.4.
//!
//! @return Всегда false.
//!
//! @see _, TX_COMMA, assert(), asserted, verify(), verified, TX_DEBUG_ERROR(), txOutputDebugPrintf(),
//! txMessageBox(), txNotifyIcon(), txStackBackTrace(), txPause(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! TX_ERROR ("Не смог прочитать 'Войну и мир'. Отмазка %d: не нашел '%s'", reasonNum, fileName);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (FOR_DOXYGEN_ONLY)
#define TX_ERROR( ... ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__)
#else
#define TX_ERROR( msg ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg)
#endif
//! @cond INTERNAL
#define TX_THROW TX_ERROR //!< For compatibility with earlier TXLib releases
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Выводит развернутое диагностическое сообщение в отладочном режиме.
//!
//! Описание см. в TX_ERROR.
//!
//! @note В режиме Release этот макрос не выводит ничего.
//!
//! @see _, TX_COMMA, assert(), asserted, verify(), verified, TX_ERROR(), txOutputDebugPrintf(),
//! txMessageBox(), txNotifyIcon(), txStackBackTrace(), txPause(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! TX_DEBUG_ERROR ("Так и не смог прочитать 'Войну и мир'. Отмазка %d: потерял '%s'", reasonNum, fileName);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG)
#define TX_DEBUG_ERROR(...) TX_ERROR (__VA_ARGS__)
#else
#define TX_DEBUG_ERROR(...) ((void) 0)
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Распечатывает дамп области памяти в консоли.
//!
//! @param address Адрес начала распечатки.
//! @param pause Делать ли паузу в конце распечатки. Необязательно.
//! @param name Название распечатки (усекается до 8 символов). Необязательно.
//!
//! @note Распечатывается область памяти размером 256 байт.
//!
//! @see txStackBackTrace(), TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! const char text[] = "Каждому лектору -- в портфель по вектору";
//! txDump (text);
//!
//! SetConsoleOutputCP (437); // Будет отображаться псевдографика, но НЕ русские буквы
//! txDump (text);
//! SetConsoleOutputCP (1251);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
void txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
#endif
//! @cond INTERNAL
#ifdef _MSC_VER
#define txDump( ... ) _txDump ((const void*)(uintptr_t) __VA_ARGS__)
#else
#define txDump( address, ... ) _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__)
#endif
void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Распечатывает текущий стек вызовов функций в консоли.
//!
//! @warning Для корректной работы этой функкции требуются модули, которые нужно установить (скопировать)
//! в папку Windows. См. раздел @ref TXLibSetup "Установка библиотеки", п.4.
//!
//! @note Для наиболее корректной работы этой функции полностью отключайте оптимизацию при компиляции. Например,
//! для компилятора GCC @c g++ -- с помощью ключа командной строки @c -O0. Разные среды программирования
//! позволяют задать эти ключи по-разному, например, в CodeBlocks через Главное меню -- Settings --
//! Compiler -- (Global Compiler Settings) -- (Compiler Settings) -- Other Options.
//!
//! @see txDump(), TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! void Recursion() // http://google.ru/search?q=%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F
//! {
//! txStackBackTrace();
//!
//! printf ("Press any key...\n");
//! _getch();
//!
//! Recursion();
//! }
//! @endcode
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define txStackBackTrace() _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Преобразует декорированное имя С++ в название типа.
//!
//! @param mangledName Декорированное (mangled) имя.
//!
//! @return Строка с полным названием типа.
//!
//! Что такое декорирование имен
//! (name mangling) см. здесь.
//!
//! @warning Если используется форма функции, возвращающая @c char*, вы должны сами освободить память,
//! занимаемую строкой, с помощью вызова @c free(), иначе будет утечка памяти.
//!
//! @see txDump(), txStackBackTrace(), TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! auto type = txDemangle (typeid (std::string) .name());
//! std::cout << "The real type of std::string is: " << type << ", muahhaha! :)\n";
//!
//! std::cout << "Call is shorter, but result is the same: " << txTypename (std::string) << ", muahhaha, too.\n";
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
//! @{
std::string txDemangle (const char* mangledName);
char* txDemangle (const char* mangledName, std::nomeow_t);
#define txTypename(value) txDemangle (typeid (value) .name()) .c_str()
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Читает информацию из реестра Windows.
//!
//! @param keyName Имя ключа реестра (см. ниже)
//! @param valueName Имя параметра ключа
//! @param value Буфер, в который записывается значение
//! @param szValue Размер буфера
//!
//! @return Количество байт, записанных в буфер @strike сос мыслом @endstrike со значением value
//!
//! @note Имя ключа реестра @c keyName @b обязательно должно начинаться c имени или обозначения одного из разделов:
//!
//! @table @tr Обозначение @td Ключ реестра
//! @tr @c HKLM @td @c HKEY_LOCAL_MACHINE
//! @tr @c HKCU @td @c HKEY_CURRENT_USER
//! @tr @c HKCR @td @c HKEY_CLASSES_ROOT
//! @tr @c HKU @td @c HKEY_USERS
//! @tr @c HKCC @td @c HKEY_CURRENT_CONFIG
//! @endtable
//!
//! @usage @code
//! char path[MAX_PATH] = "(not installed)";
//! txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, sizeof (path));
//!
//! printf ("TX Library is installed in: \"%s\"\n", path);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Макрос, позволяющий передать переменное число параметров в какой-либо другой макрос.
//!
//! @note Символ подчеркивания и символ TX_COMMA просто переопределяются в запятую.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! TX_ERROR ("Слишком умный абзац: роман 'Война и мир', файл '%s', строка %d" _ fileName _ lineNum);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define _ ,
#define TX_COMMA , //!< Синоним макроса _ (@ref _ "символ подчеркивания")
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Импортирует функцию из динамической библиотеки @с .dll.
//!
//! Макрос создает указатель на функцию, пригодный для вызова так, как будто это была бы сама функция.
//!
//! @param required @a (true/false) Обязательно ли требуется импортировать функцию. Если обязательно, то в случае
//! отсутствия функции будет фатальная ошибка.
//! @param libName @a (char*) Имя библиотеки, включая расширение (обычно @c .dll).
//! @param retValType Тип возвращаемого значения импортируемой функции.
//! @param funcName @a (char*) Имя импортируемой функции.
//! @param funcParams Параметры импортируемой функции.
//! @param callType Тип вызова импортируемой функции (для функций Windows - @c WINAPI).
//!
//! @warning Если параметр @c required равен @c false, и функция в библиотеке не найдена, или библиотека не загрузилась,
//! то указатель на функцию будет @c NULL и при ее вызове программа упадет. Проверяйте, равен ли нулю указатель
//! перед таким вызовом.
//!
//! @usage @code
//! namespace ComDlg32
//! {
//! TX_DLLIMPORT (false, "ComDlg32.dll", bool, GetOpenFileNameA, (OPENFILENAMEA* ofnStruct), WINAPI);
//! TX_DLLIMPORT (false, "ComDlg32.dll", bool, GetSaveFileNameA, (OPENFILENAMEA* ofnStruct), WINAPI);
//! }
//!
//! int main()
//! {
//! char fileName[MAX_PATH] = "";
//!
//! OPENFILENAME ofn = { sizeof (ofn), txWindow() }; // +-- Загадка Жака Фреско... на размышление дается 20 секунд
//! // V
//! ofn.lpstrTitle = "\xcd\xe5\x20\xea\xee\xef\xe8\xef\xe0\xf1\xf2\xfc\x2c\x20\xe0\x20\xf0\xe0\xe7\xe1\xe5\xf0\xe8"
//! "\xf1\xfc\x20\xe8\x20\xf1\xe4\xe5\xeb\xe0\xe9\x20\xf4\xf3\xed\xea\xf6\xe8\xfe\x21\x21\x21";
//!
//! ofn.lpstrFile = fileName;
//! ofn.nMaxFile = sizeof (fileName);
//!
//! ofn.lpstrFilter = "C++ Files\0" "*.cpp\0" // ofn.nFilterIndex = 1. Please change it!
//! "X-- Files\0" "*.xpp\0" // ofn.nFilterIndex = 2. Remove it if you didn't simply copied this code
//! "All Files\0" "*.*\0"; // ofn.nFilterIndex = 3
//! ofn.nFilterIndex = 1;
//!
//! ofn.lpstrInitialDir = NULL;
//!
//! ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
//! // ofn.FlagsEx = OFN_EX_NOPLACESBAR;
//!
//! bool oldPSW = _txProcessSystemWarnings;
//! _txProcessSystemWarnings = false; // Just do it. (C) NAN - Not a Nike :)
//!
//! if (ComDlg32::GetOpenFileNameA)
//! ComDlg32::GetOpenFileNameA (&ofn); // Весьма полезная функция, отображает диалог выбора файла.
//!
//! _txProcessSystemWarnings = oldPSW; // Just do it too.
//!
//! printf ("\n" "GetOpenFileName() returned: fileName = \"%s\"\n", fileName);
//! }
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
#define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType )
#else
// Hand-made DLLIMPORT helper
#define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... ) \
retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \
_txDllImport ((libName), #funcName, (required))
#endif
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Back-hole (I hope, not an ass-hole:) of the library)
//! @name Очень служебные функции
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Устанавливает альтернативную функцию обработки оконных сообщений Windows (оконную функцию) для окна
//! TXLib.
//!
//! @param wndProc Новая оконная функция окна TXLib. @n
//! Если не указана или NULL, то текущая альтернативная оконная функция удаляется и устанавливается
//! стандартная.
//!
//! @return Адрес предыдущей оконной функции для окна TXLib.
//!
//! Используйте эту функцию, чтобы самому обрабатывать сообщения Windows, например, сообщения от колесика
//! Мыши. См. примеры такой обработки в примере использования ниже.
//!
//! Заданная оконная функция @c wndProc будет вызываться @b до обработки события средствами TXLib.
//! Она должна быть функцией со следующим прототипом:
//! @code
//! LRESULT CALLBACK NewWndProc (HWND window, UINT message, WPARAM wParam, LPARAM lParam);
//! @endcode
//!
//! @warning Ваша оконная функция будет вызываться из вспомогательного (второго) потока, создаваемого @ref
//! txCreateWindow(). Это @b не тот же самый поток, в котором выполняется main(). В связи с этим будьте
//! внимательны при работе с глобальными переменными или их аналогами, т.к. может возникнуть "гонка
//! потоков" (race condition).
//!
//! @warning Если ваша оконная функция вернет значение, не равное 0, то стандартная обработка сообщений средствами
//! TXLib производиться @b не будет. Из-за этого, возможно, окно даже не сможет нормально закрыться. Придется
//! завершать программу с помощью Alt-Ctrl-Del из диспетчера задач, или из более продвинутого диспетчера
//! Process Explorer. Если Вы
//! берете на себя обработку оконных сообщений, делайте ее по правилам Win32 (см. в MSDN), включая вызов
//! DefWindowProc(). Этот вызов особенно важен, если вы обрабатываете сообщение @c WM_CLOSE.
//!
//! @note Полностью поменять оконную функцию можно с помощью функций SetWindowLong или SetWindowLongPtr:
//! @code
//! WNDPROC OldWndProc = (WNDPROC) SetWindowLongPtr (txWindow(), GWL_WNDPROC, (LONG_PTR) NewWndProc);
//! @endcode
//! При этом надо обязательно всегда вызывать старую оконную функцию с помощью CallWindowProc, (см. MSDN),
//! иначе последствия будут такими же плачевными, как описаны выше.
//!
//! @see txCreateWindow(), txDialog, txInputBox()
//!
//! @usage @code
//! LRESULT CALLBACK MyWndProc (HWND window, UINT message, WPARAM wParam, LPARAM lParam);
//! void SetColors (COLORREF lineColor, COLORREF fillColor, int op);
//! void DrawCursor (POINT pos, int size);
//! void DrawShoot (POINT pos, int size);
//!
//! int main()
//! {
//! _txWindowStyle |= WS_THICKFRAME;
//! txCreateWindow (GetSystemMetrics (SM_CXSCREEN) / 4, GetSystemMetrics (SM_CYSCREEN) / 4);
//!
//! txSetWindowsHook (MyWndProc);
//!
//! POINT sz = txGetExtent();
//!
//! txSelectFont ("Lucida Console", 30, 15);
//! txDrawText (0, 0, sz.x, sz.y, "MOV txWindow, eax [please]");
//!
//! txSelectFont ("Lucida Console", 15, 7.5);
//! txDrawText (0, sz.y/2, sz.x, sz.y, "(Info for the cats: NO MOUSE HERE)");
//!
//! return 0;
//! }
//!
//! LRESULT CALLBACK MyWndProc (HWND window, UINT message, WPARAM wParam, LPARAM lParam)
//! {
//! static bool wheelMsg = false;
//! static POINT pos = {-10, -10};
//! const int size = 20;
//!
//! if (message == WM_MOUSEMOVE)
//! {
//! DrawCursor (pos, size);
//! DrawCursor (pos = {LOWORD (lParam), HIWORD (lParam)}, size);
//!
//! txUpdateWindow();
//! }
//!
//! if (message == WM_LBUTTONDOWN)
//! {
//! DrawCursor (pos, size);
//! DrawShoot (pos, size);
//! DrawCursor (pos, size);
//!
//! txUpdateWindow();
//!
//! txPlaySound ("C:\\Windows\\Media\\ir_begin.wav");
//! }
//!
//! if (message == WM_MOUSEWHEEL)
//! {
//! int wheel = (short) HIWORD (wParam) / WHEEL_DELTA;
//!
//! RECT rect = {}; GetWindowRect (window, &rect);
//!
//! POINT sz = { rect.right - rect.left, rect.bottom - rect.top };
//!
//! wheelMsg = true;
//! MoveWindow (window, rect.left - wheel, rect.top - wheel, sz.x + wheel*2, sz.y + wheel*2, true);
//! wheelMsg = false;
//! }
//!
//! if (message == WM_MOVE && !wheelMsg)
//! {
//! txMessageBox (" I like to MOVe it, MOVe it", "TXLib 2 Real", MB_ICONINFORMATION);
//! wheelMsg = false;
//! }
//!
//! if (message == WM_SETCURSOR && LOWORD (lParam) == HTCLIENT)
//! {
//! SetCursor (NULL); // Hide the mouse cursor
//! return true; // Не продолжать обработку сообщения средствами TXLib
//! }
//!
//! static int i = 0;
//! if (i++ % 15 == 0)
//! {
//! char str[2] = {"-\\|/" [i/15 % 4]}; // Прропппеллллерррр
//! SetWindowText (txWindow(), str);
//! }
//!
//! return false; // Продолжить обработку сообщения средствами TXLib
//! }
//!
//! void DrawCursor (POINT pos, int size)
//! {
//! SetColors (TX_YELLOW, TX_TRANSPARENT, R2_XORPEN);
//!
//! txCircle (pos.x, pos.y, size/2);
//! txLine (pos.x-size, pos.y, pos.x+size, pos.y);
//! txLine (pos.x, pos.y-size, pos.x, pos.y+size);
//!
//! Win32::SetROP2 (txDC(), R2_COPYPEN);
//! }
//!
//! void DrawShoot (POINT pos, int size)
//! {
//! SetColors (RGB (255, 64, 0), RGB (255, 64, 0), R2_COPYPEN);
//!
//! for (int i = 0; i < 5; i++)
//! txCircle (pos.x + rand() % (size*2) - size,
//! pos.y + rand() % (size*2) - size, rand() % (size/2) + size/2);
//! }
//!
//! void SetColors (COLORREF lineColor, COLORREF fillColor, int op)
//! {
//! txSetColor (lineColor);
//! txSetFillColor (fillColor);
//! Win32::SetROP2 (txDC(), op);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Блокирует холст (контекст рисования).
//!
//! @param wait Ожидать конца перерисовки окна вспомогательным потоком. Если не указано, то "ожидать".
//!
//! @return Состояние блокировки.
//!
//! Перед вызовом любых функций Win32 GDI необходимо заблокировать холст функцией txLock() и затем
//! разблокировать с помощью txUnlock(). Это связано с тем, что обновление содержимого окна (для тех, кто
//! знает Win32: обработка сообщения WM_PAINT) в библиотеке TXLib происходит в отдельном вспомогательном
//! потоке. Надолго блокировать его нельзя -- при заблокированном потоке окно не обновляется.
//!
//! txLock() использует EnterCriticalSection(), и физически приостанавливает поток, обновляющий окно, так
//! что надолго блокировать нельзя. Иначе тормозится обработка оконных сообщений, окно перестает
//! реагировать на действия пользователя и перерисовываться. Нельзя также вызывать txSleep() или Sleep()
//! при заблокированном потоке.
//!
//! txLock() / txUnlock() -- это низкоуровневый механизм. Он отличается от более простого высокоуровневого
//! механизма txBegin() / txEnd() / txUpdateWindow(), который не приостанавливает поток, а просто
//! отключает принудительное постоянное обновление окна.
//!
//! @see txDC(), txVideoMemory(), txLock(), txUnlock(), txGDI()
//!
//! @usage См. исходный текст функций _txCanvas_OnPAINT() и _txConsole_Draw() в TXLib.h.
//}----------------------------------------------------------------------------------------------------------------
bool txLock (bool wait = true);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Разблокирует холст
//!
//! @return Состояние блокировки (всегда false).
//!
//! Более подробно см. в описании txLock().
//!
//! @see txDC(), txVideoMemory(), txLock(), txGDI()
//!
//! @usage См. исходный текст функций _txCanvas_OnPAINT() и _txConsole_Draw() в TXLib.h.
//}----------------------------------------------------------------------------------------------------------------
//! @{
bool txUnlock();
//! @cond INTERNAL
template inline T txUnlock (T value);
//! @endcond
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Вызывает функции Win32 GDI с автоматической блокировкой и разблокировкой.
//!
//! @param command Функция GDI (возможно, возвращающая значение).
//! @param dc Дескриптор контекста рисования (холста), использующийся в вызове функции GDI (см. параметр
//! @c command).
//!
//! @return Значение, возвращаемое вызываемой функцией GDI.
//!
//! @note Если параметр dc соответствует основному холсту TXLib (совпадает с возвращаемым значением txDC()),
//! то на время выполнения функции GDI поток, обновляющий окно TXLib, блокируется. @n
//!
//! @note Если в вызове функции GDI используются запятые, то используйте двойные скобки, чтобы получился один
//! параметр, так как txGDI() это все же макрос.
//!
//! @see txDC(), txVideoMemory(), txLock(), txUnlock()
//!
//! @usage @code
//! txGDI (( Rectangle (txDC(), x1, y1, x2, y2) )); // Не забудьте про две ((ДВЕ)) скобки
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define txGDI( command, dc ) ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) )
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Меняет кодовую страницу консоли и локаль стандартной библиотеки С++.
//!
//! @param codepage Номер новой кодовой страницы консоли. Если не указано, то 1251.
//! @param locale Новая локаль (информация о языке) стандартной библиотеки С++.
//! Если не указано, то "Russian" или "ru_RU.CP1251".
//! @param wLocale Новая локаль стандартной библиотеки С++ для wide character funstions.
//! Если не указано, то L"Russian_Russia.ACP".
//!
//! @return Номер старой кодовой страницы консоли.
//!
//! - Список кодовых страниц консоли
//! - Список имен локалей C++
//!
//! @warning Если устанавливается кодовая страница не 1251, возможны нарушения в работе строковых функций C++
//! и вывода текста в консоль.
//!
//! @see txClearConsole(), txSetConsoleAttr() и другие консольные функции, txReopenStdio()
//!
//! @usage @code
//! txSetLocale (866, "Russian_Russia.866", L"Russian_Russia.866");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifndef FOR_DOXYGEN_ONLY
const int _TX_CODEPAGE = 1251;
#ifndef __CYGWIN__
const char _TX_LOCALE[] = "Russian";
#else
const char _TX_LOCALE[] = "ru_RU.CP1251";
#endif
const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP";
#endif
int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Приостанавливает программу до нажатия на любую клавишу.
//!
//! @param message Сообщение, выводимое в консоль через stderr, в формате printf(). Необязательно.
//!
//! @note При нажатии Ctrl+C программа аварийно завершается.
//!
//! @see txMessageBox(), TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! txPause ("Привет от system (\"pause\");");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txPause (const char* message, ...) tx_printfy (1);
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Tune-up constants and variables
//! @name Настроечные константы и переменные
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Имя лог-файла TXLib
//!
//! В эту строку надо @b скопировать нужное вам имя лог-файла.
//!
//! По умолчанию файл создается во время ошибки в одной папке с запущенной программой, имеет то же имя, что
//! и файл программы, с добавлением расширения @c ".log".
//!
//! @note Устанавливать имя лог-файла надо в начале работы программы, до появления первой ошибки.
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
char _txLogName[MAX_PATH] = "";
#endif // TX_COMPILED
extern char _txLogName[];
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Запрет ранней инициализации TXLib
//!
//! Если константа определена с помощью \#define @a до включения TXLib.h в программу, ранняя инициализация
//! (до запуска функции @c main) @b не проводится.
//!
//! @note Ранняя инициализация включает:
//! - Открытие окна консоли,
//! - Установку кодовой страницы _TX_CODEPAGE (1251) консоли для поддержки русского языка,
//! - Установку русской локали стандартной библиотеки C++ ("Russian" / "ru_RU.CP1251" и L"Russian_Russia.ACP"),
//! - Переинициализация библиотек stdio и iostream на случай, если приложение не скомпоновано как консольное
//! и библиотеки остались неинициализированы,
//! - Перехват системных сигналов (деление на 0, арифметические ошибки, обращение по неверному адресу и т.д.),
//! - Перехват необработанных исключений,
//! - Смена заголовка консольного окна,
//! - Установка режима паузы по завершении программы, чтобы окно закрывалось не сразу,
//! - Подавление паузы при запуске из сред программирования, заставляющей нажимать на клавишу два раза. @n
//!
//! @note Если ранняя инициализация запрещена, но в EXE-файле создается окно TXLib с помощью txCreateWindow(),
//! то библиотека все равно будет инициализирована. В @b DLL ранняя инициализация никогда @b не проводится. @nn
//!
//! @note Ранняя инициализация не потокобезопасна (not thread-safe).
//!
//! @see txCreateWindow(), _TX_ALLOW_KILL_PARENT, _TX_WAITABLE_PARENTS, _txWatchdogTimeout, TX_CONSOLE_MODE
//!
//! @usage @code
//! #define _TX_NOINIT
//! #include "TXLib.h"
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (_TX_NOINIT)
#undef _TX_NOINIT
#define _TX_NOINIT 1
#else
#define _TX_NOINIT 0
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Режим отображения консольного окна. Допустимы любые флаги функции ShowWindow.
//!
//! По умолчанию: @c SW_HIDE -- Скрывать консольное окно после показа графического окна.
//!
//! Если ваше приложение консольное, то оно будет запускаться с открытым @strike черным печальным @endstrike
//! консольным окном, которое скроется при открытии графического окна. Это может выглядеть как мигание
//! консольного окна. Чтобы этого не было, можно создать неконсольное приложение, которое изначально
//! запускается без видимого консольного окна и при его запуске нет эффекта такого мигания.
//!
//! @title Создать неконсольное приложение можно: @table
//! @tr Для компиляторов @c g++ (MinGW, Cygwin) и @c clang, используемых в CodeBlocks, CLion и т.п.
//! @td -- Указав компилятору ключ @c -mwindows и убрав ключ @c -mconsole.
//! @tr Для компиляторов семейства Microsoft Visual Studio
//! @td -- Создав @b не проект консольного приложения, а "Desktop Application" или аналогичный.
//! @endtable
//!
//! @note Константа задается @b до включения файла @ref TXLib.h в программу. @nn
//!
//! @warning Если вы создали неконсольное приложение (см. выше), но запускаете его из среды пограммирования
//! (например, CodeBlocks), то вы можете увидеть другое консольное окно служебной программы, с помощью
//! которой среда программирования запускает ваше приложение. Если вы запустите ваше неконсольное
//! приложение не из среды пограммирования, а непосредственно из Проводника, то вы не увидите
//! никаких лишних консольных окон.
//!
//! @note Btw, if you do not like that console window text is painted over graphic canvas window, set the
//! undocumented variable @c _txConsole to negative value.
//!
//! @see _TX_NOINIT
//!
//! @usage @code
//! #define TX_CONSOLE_MODE SW_HIDE // Скрыть консольное окно при открытии графического окна
//! #include "TXLib.h" // (Поведение по умолчанию)
//! ...
//! txCreateWindow (800, 600);
//!
//! #define TX_CONSOLE_MODE SW_SHOW // Всегда показывать консольное окно, например, для отладки
//! #include "TXLib.h"
//! ...
//! txCreateWindow (800, 600);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (TX_CONSOLE_MODE)
#define TX_CONSOLE_MODE SW_HIDE
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Шрифт консоли
//! @note Константа задается @b до включения файла @ref TXLib.h в программу.
//}----------------------------------------------------------------------------------------------------------------
#if !defined (TX_CONSOLE_FONT)
#define TX_CONSOLE_FONT "Lucida Console"
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Стиль графического окна библиотеки.
//! @note Переменная устанавливается @b до открытия окна библиотеки.
//!
//! @usage @code
//! _txWindowStyle &= ~WS_CAPTION; // FullScreen: окно без заголовка, размером с экран
//! txCreateWindow (GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN));
//!
//! printf ("Закройте меня через Alt+F4\n");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
int _txWindowStyle = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
#endif // TX_COMPILED
extern int _txWindowStyle;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Интервал мигания курсора консоли (мс)
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
unsigned _txCursorBlinkInterval = 500;
#endif // TX_COMPILED
extern unsigned _txCursorBlinkInterval;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Интервал обновления холста (мс)
//! @note Переменная устанавливается @b до открытия окна библиотеки.
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
unsigned _txWindowUpdateInterval = 25;
#endif // TX_COMPILED
extern unsigned _txWindowUpdateInterval;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Макрос, разрешающий использовать TXLib вместе с графической библиотекой SFML
//! @note Этот макрос задается @b перед включением TXLib.h в программу.
//! @usage @code
//! #define TX_USE_SFML
//! #include "TXLib.h"
//! #include
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
#define TX_USE_SFML
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Таймаут операций ожидания событий (мс)
//}----------------------------------------------------------------------------------------------------------------
const int _TX_TIMEOUT = 1000
#if defined (_TX_ALLOW_TRACE)
* 2
#endif
#if defined (TX_TRACE)
* 3
#endif
#if defined (_TX_USE_DEVPARTNER)
* 10
#endif
;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Указатель на функцию, выводящую изображение непосредственно в окно TXLib во время обработки WM_PAINT.
//!
//! Если равен NULL, то используется Win32::BitBlt.
//!
//! Вы можете переопределить значение этого указателя, чтобы он указывал на вашу функцию, и тогда
//! TXLib будет выводить изображение в окно через нее. Имейте в виду, что эта функция будет вызываться
//! в отдельном потоке.
//!
//! Параметры этой функции гуглите: "StretchBlt function".
//!
//! @see txSetWindowsHook(), txBitBlt(), txAlphaBlend()
//!
//! @usage @code
//! #include "TXLib.h"
//!
//! bool MySwapBuffers (HDC dest, int xDest, int yDest, int wDest, int hDest,
//! HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp)
//! {
//! return txAlphaBlend (dest, xDest, yDest, wSrc-xSrc, hSrc-ySrc, src, xSrc, ySrc, 0.01);
//! }
//!
//! int main()
//! {
//! _txSwapBuffers = MySwapBuffers; // That's it
//!
//! txCreateWindow (800, 600);
//!
//! txSetFillColor (TX_NULL);
//! txRectangle (10, 10, txGetExtentX() - 10, txGetExtentY() - 10);
//!
//! for (int x = 50; x <= txGetExtentX() - 50; x += 20)
//! {
//! txCircle (x, txGetExtentY()/2, 10);
//! txSleep (100);
//! }
//!
//! txSleep (3000);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp) = NULL;
#endif // TX_COMPILED
extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Размеры внутренних статических строковых буферов TXLib
//}----------------------------------------------------------------------------------------------------------------
const unsigned _TX_BUFSIZE = 1024,
_TX_BIGBUFSIZE = _TX_BUFSIZE * 2, //!< Размеры больших статических буферов.
_TX_HUGEBUFSIZE = _TX_BUFSIZE * 20, //!< Размеры очень больших статических буферов.
_TX_STACKSIZE = 64 * 1024; //!< Минимальный размер стека для потоков программы.
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Максимальное количество исключений в программе.
//}----------------------------------------------------------------------------------------------------------------
#if !defined (_TX_EXCEPTIONS_LIMIT)
#define _TX_EXCEPTIONS_LIMIT 16
#endif
#if !defined (_TX_FATAL_EXCEPTIONS_LIMIT)
#define _TX_FATAL_EXCEPTIONS_LIMIT 16 //!< Максимальное количество фатальных исключений.
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Если определено, не исключать адреса без отладочной информации из трассировок стека.
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
#define _TX_FULL_STACKTRACE
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Если определено, обрабатывать ошибки в программе перед всеми другими обработчиками ошибок.
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
bool _txProcessSystemWarnings = true;
#endif // TX_COMPILED
extern bool _txProcessSystemWarnings;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Список запускающих программ, которые ждут нажатия клавиши после завершения процесса TXLib.
//!
//! Если программа перечислена в списке и TXLib запущена из нее, то при завершении TXLib указанная программа
//! будет закрыта. (Это произойдет, если не открыто графическое окно TXLib, а есть только окно консоли.)
//!
//! Программы разделяются пробелом или запятой. Допускается указание родителя запускающей программы, после
//! двоеточия. Имя программы, начинающееся с большой буквы - спец. случай для консоли CLion, см. функции
//! _txCleanup() и _txIsParentWaitable() в исходном тексте @ref TXLib.h.
//!
//! Может задаваться перед включением TXLib.h в программу.
//!
//! @see _TX_ALLOW_KILL_PARENT, _TX_NOINIT, _txCleanup(), _txIsParentWaitable(), _txWatchdogTimeout
//}----------------------------------------------------------------------------------------------------------------
#if !defined (_TX_WAITABLE_PARENTS)
#define _TX_WAITABLE_PARENTS "Winpty-agent.exe:Clion.exe, " /* 0: CLion32 */ \
"Winpty-agent.exe:Clion64.exe, " /* 1: CLion64 */ \
"starter.exe:eclipse.exe, " /* 2: Eclipse 4 */ \
"starter.exe:javaw.exe, " /* 3: Eclipse 3 */ \
"cmd.exe:devenv.exe, " /* 4: MSVS 2003+ */ \
"VSDebugConsole.exe:devenv.exe, " /* 5: MSVS 2019+ */ \
"VSDebugConsole.exe:msvsmon.exe, " /* 6: MSVS 2022 x86 */ \
"consolepauser.exe:devcpp.exe, " /* 7: Dev-Cpp */ \
"cb_console_runner.exe:codeblocks.exe" /* 8: CodeBlocks 8+ */
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Разрешать принудительное завершение вызывающих программ, ждущих нажатия клавиш после завершения TXLib.
//!
//! Иначе отменяется собственная пауза до нажатия клавиши, встроенная в TXLib, и пусть тогда паузу делает
//! вызывающий процесс.
//!
//! Список вызывающих программ, которые могут делать такую паузу, задается в _TX_WAITABLE_PARENTS.
//!
//! @note Макрос должен задаваться @b перед включением TXLib.h в программу.
//!
//! См. также определение этой константы в файле TXLib.h.
//!
//! @see _TX_WAITABLE_PARENTS, _TX_NOINIT, _txWatchdogTimeout
//!
//! @usage @code
//! #define _TX_ALLOW_KILL_PARENT false
//! #include "TXLib.h"
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#if !defined (_TX_ALLOW_KILL_PARENT) // DISCLAIMER: Я не призываю к убийству родителей.
#define _TX_ALLOW_KILL_PARENT true // Это технический термин.
#endif // г_дам юристам привет.
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Лимит времени на завершение программы, начиная от завершения функции main() или от вызова exit(), в мс.
//!
//! Если значение меньше 0, то время не лимитируется.
//!
//! @note Для предотвращения зависания программы при выходе TXLib запускает отдельный сторожевой поток (watchdog
//! thread), который ожидает _txWatchdogTimeout миллисекунд, а затем принудительно завершает программу.
//!
//! @see _TX_WAITABLE_PARENTS, _TX_NOINIT
//}----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED
int _txWatchdogTimeout = 10*_TX_TIMEOUT;
#endif // TX_COMPILED
extern int _txWatchdogTimeout;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Макросы для поддержки прекомпиляции TX Library.
//!
//! Не секрет, что файл @c TXLib.h очень большой и, как следствие, долго компилируется. Для ускорения сборки
//! проектов обычно используется техника раздельной компиляции, когда в проект входят не один, а несколько
//! .cpp-файлов. В этом случае, если изменен только один такой файл, перекомпилироваться будет
//! только он, а результаты компиляции остальных файлов присоединяются на этапе линковки, что гораздо быстрее.
//!
//! Однако библиотека TX Library представляет собой единственный заголовочный .h-файл, а заголовочные
//! файлы перекомпилирются каждый раз, при каждой сборке. Это существенно замедляло работу с библиотекой.
//!
//! Теперь файл @c TXLib.h внутри разделен на части, которые могут по-разному вести себя при компиляции.
//!
//! Если при компиляции @b перед включением файла @c TXLib.h определен макрос @c TX_COMPILED, то компилироваться
//! будет меньшая часть файла, порядка одной трети. Эта часть содержит то, что обязательно надо включать в
//! каждую компиляцию: определения констант, структур и классов, прототипы функций, шаблоны, макросы и др.
//! При этом около двух третей файла, которые содержат определения нешаблонных функций, не будут компилироваться.
//! (Строго говоря, код этих двух третей обычно не помещают в заголовочные файлы, но, так как библиотека построена
//! по принципу единственного файла для упрощения работы с ней, такой код она вынуждена содержать.)
//!
//! Чтобы в проекте были доступны откомпилированные определения всех необходимых функций библиотеки, в него нужно
//! добавить еще один файл, включив в него @с TXLib.h и определив в нем макрос @c TX_COMPILING. Это приведет к
//! компиляции всего содержимого библиотеки, и ее машинный код станет доступен всей программе. В примере ниже
//! этот файл назван @c TXLib.cpp, но имя может быть любое. Для компиляции этого файла потребуется время,
//! но затем он перестанет участвовать в компиляции, так как его содержимое не будет изменяться, и общее время
//! сборки проекта сократится, от 1.5 до 3 раз.
//!
//! @warning Не следует помещать в этот файл ничего, кроме директив @c \#define @c TX_COMPILING и @c \#include "TXLib.h",
//! так как при изменении содержимого этого файла среда программирования снова перекомпилирует его, на что
//! вновь потребуется большое время.
//!
//! Также для ускорения компиляции можно определить макрос @c WIN32_LEAN_AND_MEAN @b до включения @c TXLib.h
//! в программу.
//!
//! @warning Макрос @c WIN32_LEAN_AND_MEAN задается автоматически при задании макроса @c TX_COMPILED. Если при этом не
//! видны определения каких-либо сущностей, определенных в @c Windows.h (функций, структур, классов, констант
//! и т.п.), включите в программу файлы, определяющие эти сущности, вручную.
//!
//! @note Если определены макросы @c TX_COMPILED или @c TX_COMPILING, анонимное пространство имен, окружающее пространство
//! имен @c TX, не используется.
//!
//! @usage @code
//! // Оба файла ниже должны входить в один и тот же проект Visual Studio или другой среды
//! // программирования (IDE). Для добавления файла в проект используйте возможности вашей среды
//! // программирования.
//!
//! //-----------------------------------------------
//! // Main.cpp: Файл с текстом программы
//! //-----------------------------------------------
//!
//! #define TX_COMPILED // Обязательно ПЕРЕД командой #include
//! #include "TXLib.h"
//!
//! int main()
//! {
//! txCreateWindow (800, 600);
//! ...
//! }
//!
//! //-----------------------------------------------
//! // TXLib.cpp: Файл для прекомпиляции TXLib
//! //-----------------------------------------------
//!
//! #define TX_COMPILING // Обязательно ПЕРЕД командой #include
//! #include "TXLib.h"
//!
//! // [Больше в этом файле ничего нет]
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
//! @{
#ifdef FOR_DOXYGEN_ONLY
#define TX_COMPILED
#endif
//! @}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Internal diagnostics
//! @name Внутренняя диагностика
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Включает/отключает внутреннюю трассировку исполнения кода библиотеки.
//!
//! Трассировка идет через макрос TX_TRACE, который подставляется перед каждым оператором (statement).
//! По умолчанию трассировка выключена.
//!
//! По умолчанию трассировка ведется через функцию OutputDebugString(), ее вывод можно перехватить
//! утилитами-логгерами, например,
//! DbgView. Это можно изменить, переопределив макрос TX_TRACE до включения TXLib.h в программу.
//!
//! @warning Трассировка @b очень тормозит выполнение программы, особенно при отладке в Microsoft Visual Studio.
//! В этом случае лучше пользоваться DbgView (см. выше) и запускать отлаживаемую программу отдельно,
//! а не из-под отладчика Visual Studio.
//!
//! @note _TX_ALLOW_TRACE и TX_TRACE задаются @b перед включением TXLib.h в программу.
//!
//! @title Уровни трассировки: @table
//! @tr 1 @td Regular functions
//! @tr 2 @td Reserved
//! @tr 3 @td Init/Cleanup
//! @tr 4 @td Init/Cleanup, misc functions
//! @tr 5 @td Error handling, entry points
//! @tr 6 @td Error handling, main part
//! @tr 7 @td Error handling, misc functions
//! @tr 8 @td Canvas worker thread
//! @tr 9 @td Reserved
//! @endtable
//!
//! @usage @code
//! // Для просмотра трассы запустите DbgView ДО запуска программы!
//!
//! #define _TX_ALLOW_TRACE 1 // Трассировать только обычные функции TXLib (уровень 1).
//! #include "TXLib.h"
//!
//! #define _DEBUG // Не трассировать, но собирать информацию о вызовах
//! #include "TXLib.h" // функций TXLib для возможной трассировки стека.
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
#define _TX_ALLOW_TRACE
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Трассирует исполнение кода через OutputDebugString().
//!
//! По умолчанию трассировка ведется через функцию OutputDebugString(), ее вывод можно перехватить
//! утилитами-логгерами, например,
//! DbgView. Для "раскраски" лога есть файл TX\Dev\DbgView.ini, его надо загрузить в DbgView
//! через меню Edit/Filter/Load (Ctrl+L).
//!
//! С помощью TX_TRACE можно трассировать код самой библиотеки TXLib. Для этого надо разрешить трассировку
//! TXLib, определив макрос _TX_ALLOW_TRACE перед включением файла TXLib.h в программу. По умолчанию
//! трассировка TXLib выключена.
//!
//! TX_TRACE можно переопределить в свой код. Тогда, если трассировка библиотеки разрешена, он будет
//! вызываться почти перед каждой исполняемой строкой TXLib. Может быть, это кому-нибудь будет интересно.
//!
//! @usage @code
//! int main()
//! {
//! ...
//! TX_TRACE; // Через DbgView увидим имя файла и номер выполняемой строки
//! ...
//! }
//! @endcode
//! @code
//! #define TX_TRACE printf (__TX_FILELINE__ "\t" __TX_FUNCTION__ "\n");
//! #include "TXLib.h"
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
#define TX_TRACE
#endif
#if !defined (TX_TRACE)
#define TX_TRACE { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); }
#endif
//! @cond INTERNAL
void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...);
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @{
//! @cond INTERNAL
#ifndef FOR_DOXYGEN_ONLY
struct _txLoc
{
const char* func;
const char* file;
int line;
int inTX; // We are inside one of TXLib functions
int trace; // Internal TX trace level, when enabled by _TX_ALLOW_TRACE
const _txLoc* prev; // Caller's location
static _txLoc _tx_thread Cur;
};
struct _txFuncEntry
{
typedef _txFuncEntry this_t;
_txLoc loc;
_txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; }
void restore() { _txLoc::Cur = loc; }
~_txFuncEntry() { restore(); }
private:
_txFuncEntry (const this_t&) _tx_delete;
this_t& operator = (const this_t&) _tx_delete;
};
#if defined (_GCC_VER)
inline const char* __txLocCurSet (const char* _file, int _line, const char* _func)
{ _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; }
#else
#define __txLocCurSet( _file, _line, _func ) \
( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) )
#endif
#define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__)
#define _txLocLvlSet(lvl) { _txLoc::Cur.trace = (lvl); }
//{----------------------------------------------------------------------------------------------------------------
#if defined ($0)
#undef $0
#endif
#if defined ($1)
#undef $1
#endif
#if defined ($2)
#undef $2
#endif
#if defined ($3)
#undef $3
#endif
#if defined ($4)
#undef $4
#endif
#if defined ($5)
#undef $5
#endif
#if defined ($6)
#undef $6
#endif
#if defined ($7)
#undef $7
#endif
#if defined ($8)
#undef $8
#endif
#if defined ($9)
#undef $9
#endif
#if defined ($)
#undef $
#endif
#if defined ($$)
#undef $$
#endif
//}
//-----------------------------------------------------------------------------------------------------------------
#if defined (_TX_ALLOW_TRACE)
#define _txEntry(lvl) _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl); $; }
#define $ { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } }
#define $$ { __txFuncEntry.restore(); }
#elif defined (_DEBUG)
#define _txEntry(lvl) _txFuncEntry __txFuncEntry; { $; }
#define $ { _txLocCurSet(); }
#define $$ { __txFuncEntry.restore(); }
#else
#define _txEntry(lvl) ;
#define $ ;
#define $$ ;
#endif
//{----------------------------------------------------------------------------------------------------------------
#define $0 _txEntry (0) // (Log level unchanged)
#define $1 _txEntry (1) // Regular functions
#define $2 _txEntry (2) // Resvd
#define $3 _txEntry (3) // Init/Cleanup
#define $4 _txEntry (4) // Init/Cleanup, misc functions
#define $5 _txEntry (5) // Error handling, entry points
#define $6 _txEntry (6) // Error handling, main part
#define $7 _txEntry (7) // Error handling, misc functions
#define $8 _txEntry (8) // Canvas worker thread
#define $9 _txEntry (9) // Resvd
//}
//-----------------------------------------------------------------------------------------------------------------
#endif // FOR_DOXYGEN_ONLY
//! @endcond
//! @}
//}----------------------------------------------------------------------------------------------------------------
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Sweet critical section blocking: txAutoLock class
//=================================================================================================================
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Класс для автоматической блокировки и разблокировки критической секции.
//!
//! Начиная с
//! Александреску, его пишут все и он прост, как пробка: в конструкторе -- EnterCriticalSection(),
//! в деструкторе -- LeaveCriticalSection(). Это @c RAII в чистом виде: вы никогда не забудете разблочить
//! секцию and your thread show will always go on.
//!
//! Некоторые добавления: есть возможность вызвать TryEnterCriticalSection(), и, если она не заблочила
//! секцию, деструктор ее не разблочивает. Есть оператор для проверки, заблочилась ли секция или нет
//! (см. конструкторы класса и оператор @c bool).
//!
//! @note Класс не инициализирует и не удаляет критическую секцию. Только синхронизирует. Остальное сами-сами :)
//!
//! @see txLock(), txUnlock(), txGDI()
//}----------------------------------------------------------------------------------------------------------------
//! @cond _OFF
extern CRITICAL_SECTION _txCanvas_LockBackBuf;
//! @endcond
class txAutoLock
{
typedef txAutoLock this_t;
public:
//{----------------------------------------------------------------------------------------------------------------
//! @brief Конструктор, блокирует критическую секцию
//!
//! @param cs Критическая секция для блокировки.
//! @param mandatory Если @c true, то блокировать обязательно (EnterCriticalSection). @n
//! Если @c false, то только пытаться блокировать (TryEnterCriticalSection). @n
//! Если не указано, то блокировка обязательна.
//! @usage @code
//! CRITICAL_SECTION cs = {}; // This is not a Counter Strike
//!
//! void foo()
//! {
//! txAutoLock lock (&cs); // Здесь вызовется EnterCriticalSection()
//! ...
//! } // а здесь LeaveCriticalsection()
//!
//! void bar()
//! {
//! txAutoLock lock (&cs, false); // TryEnterCriticalSection()
//! if (!lock) return; // ну не смогла
//! ...
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) :
cs_ (cs)
{
$1 if (!cs_) return;
if (mandatory) {$ EnterCriticalSection (cs_); }
else {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); }
}
//{----------------------------------------------------------------------------------------------------------------
//! @brief Конструктор для блокировки холста TXLib
//!
//! @param mandatory Если @c true, то блокировать @b обязательно, как в @ref txLock (true). @n
//! Если @c false, то только @b пытаться блокировать, как в @ref txLock (false). @n
//! Если не указано, то блокировка обязательна.
//! @usage @code
//! void foobar()
//! {
//! txAutoLock lock; // Здесь вызовется txLock()
//! ...
//! } // а здесь txUnlock()
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
explicit txAutoLock (bool mandatory = true) :
cs_ (NULL)
{
$1 new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory);
}
//{----------------------------------------------------------------------------------------------------------------
//! @brief Деструктор, разблокирует секцию
//}----------------------------------------------------------------------------------------------------------------
~txAutoLock()
{
$1 if (!cs_) return;
$ LeaveCriticalSection (cs_); cs_ = NULL;
}
//{----------------------------------------------------------------------------------------------------------------
//! @brief Позволяет проверить, заблокировалась секция или нет
//! @usage См. в txAutoLock::AutoLock (CRITICAL_SECTION&, bool)
//}----------------------------------------------------------------------------------------------------------------
operator bool () const
{
$1 return (cs_ != NULL);
}
//{----------------------------------------------------------------------------------------------------------------
//! Блокируемая критическая секция
//}----------------------------------------------------------------------------------------------------------------
// private:
CRITICAL_SECTION* cs_;
//{----------------------------------------------------------------------------------------------------------------
//! Такой вот копирайт.
//}----------------------------------------------------------------------------------------------------------------
//! @{
private:
txAutoLock (const this_t&) _tx_delete;
this_t& operator = (const this_t&) _tx_delete;
//! @}
};
//}
//=================================================================================================================
//=================================================================================================================
//{ Dialogs: txDialog class
//! @name Работа с диалоговыми окнами. Класс txDialog
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Dialogs
//! @brief Базовый класс для диалоговых окон.
//!
//! Для создания своего диалогового окна нужно:
//! -# Унаследовать свой класс из этого базового класса;
//! -# Задать состав и расположение элементов управления (контролов) функцией txDialog::setLayout(), или
//! указать карту расположения при показе диалогового окна функцией txDialog::dialogBox();
//! -# Переопределить в своем классе функцию txDialog::dialogProc() для обработки событий диалогового
//! окна или построить карту реакций на команды с помощью макросов TX_BEGIN_MESSAGE_MAP(),
//! TX_END_MESSAGE_MAP, TX_COMMAND_MAP.
//!
//! @note Этот класс предоставляет только базовую функциональность диалоговых окон и только базовые сведения
//! по ним. Для его полноценного использования нужно знать, как работать с диалоговыми окнами в Windows.
//!
//! @see txDialog::setLayout(), txDialog::dialogProc(), txDialog::Layout, TX_BEGIN_MESSAGE_MAP(),
//! TX_END_MESSAGE_MAP, TX_COMMAND_MAP
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
struct txDialog
{
typedef txDialog this_t;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Dialogs
//! @brief Константы для задания типа контрола.
//!
//! Вместо констант можно использовать названия оконных классов, преобразованные к типу txDialog::CONTROL.
//!
//! @see txDialog::Layout, txDialog::setLayout()
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
public:
enum CONTROL
{
DIALOG = (int) 0x00000000, //!< Начало описания диалога
BUTTON = (int) 0xFFFF0080, //!< Кнопка
EDIT = (int) 0xFFFF0081, //!< Редактируемый текст
STATIC = (int) 0xFFFF0082, //!< Нередактируемый элемент (текст, картинка и т.д.)
LISTBOX = (int) 0xFFFF0083, //!< Список с прокруткой
SCROLLBAR = (int) 0xFFFF0084, //!< Полоса прокрутки
COMBOBOX = (int) 0xFFFF0085, //!< Комбинированный список
END = (int) 0x00000000 //!< Конец описания диалога
};
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Dialogs
//! @brief Класс для описания элемента диалогового окна (контрола)
//!
//! Массив таких структур задает описание макета диалогового окна. Это описание похоже на задание диалога
//! в ресурсном скрипте (.rc):
//!
//! - Нулевой элемент описывает диалоговое окно в целом
//! - Остальные элементы описывают контролы (порядок задания параметров контрола похож на порядок
//! параметров в ресурсном скрипте)
//! - Последний элемент -- txDialog::END или {NULL}
//!
//! @see txDialog::setLayout(), txDialog::dialogBox(), txDialog::dialogProc()
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
public:
struct Layout
{ //-V802
CONTROL wndclass; //!< Тип контрола
const char* caption; //!< Название или текст
WORD id; //!< Идентификатор контрола
short x; //!< Координата верхнего левого угла
short y; //!< Координата нижнего правого угла
short sx; //!< Размер по X
short sy; //!< Размер по Y
DWORD style; //!< Стиль контрола
const char* font; //!< Шрифт диалогового окна
WORD fontsize; //!< Размер шрифта диалогового окна
};
//{----------------------------------------------------------------------------------------------------------------
//! @brief Конструктор.
//!
//! @see txDialog::txDialog (const txDialog::Layout*)
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
public:
txDialog();
//{----------------------------------------------------------------------------------------------------------------
//! @brief Конструктор.
//!
//! @param layout Макет диалогового окна.
//!
//! @see txDialog::Layout, txDialog::setLayout()
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
explicit txDialog (const Layout* layout);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Деструктор.
//}----------------------------------------------------------------------------------------------------------------
virtual ~txDialog() {};
//{----------------------------------------------------------------------------------------------------------------
//! @brief Устанавливает текущий макет диалогового окна.
//!
//! @param layout Макет диалогового окна.
//!
//! @return Предыдущий макет.
//!
//! @see txDialog::Layout, txDialog::txDialog (const txDialog::Layout*), txDialog::dialogBox()
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
const Layout* setLayout (const Layout *layout);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Функция обработки сообщений диалогового окна.
//!
//! @param _wnd Дескриптор окна.
//! @param _msg Номер сообщения.
//! @param _wParam 1-й параметр сообщения (WORD).
//! @param _lParam 2-й параметр сообщения (DWORD).
//!
//! @return В большинстве случаев false, детальнее см. DialogProc в MSDN.
//!
//! Эту функцию надо переопределить для обработки событий окна, или построить ее с помощью макросов
//! TX_BEGIN_MESSAGE_MAP(), TX_END_MESSAGE_MAP, TX_COMMAND_MAP.
//!
//! @see txDialog::dialogBox(), TX_BEGIN_MESSAGE_MAP(), TX_END_MESSAGE_MAP, TX_COMMAND_MAP
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Запускает диалоговое окно.
//!
//! @param layout Макет диалогового окна. @n
//! Если не указан -- используется значение, заданное txDialog::setLayout() или конструктором
//! txDialog::txDialog (const txDialog::Layout*).
//! @param bufsize Размер буфера для создания шаблона диалога. Если не указан -- размер по умолчанию.
//!
//! @return Значение, указанное в функции EndDialog(). @n
//! По умолчанию -- адрес объекта (this), для которого была запущена txDialog::dialogBox().
//!
//! @see txDialog::dialogProc(), txDialog::setLayout(), txDialog::Layout, txDialog
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Запускает диалоговое окно.
//!
//! @param resource Идентификатор диалогового ресурса.
//!
//! @return Значение, указанное в функции EndDialog(). @n
//! По умолчанию -- адрес объекта (this), для которого была запущена txDialog::dialogBox().
//!
//! @see txDialog::dialogProc()
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
intptr_t dialogBox (WORD resource);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Закрытые конструктор копирования и оператор присваивания.
//}----------------------------------------------------------------------------------------------------------------
private:
txDialog (const this_t&) _tx_delete;
this_t& operator = (const this_t&) _tx_delete;
//{----------------------------------------------------------------------------------------------------------------
//! Настоящая диалоговая функция (не txDialog::dialogProc(), т.к. функция окна in32 должна быть статической).
//}----------------------------------------------------------------------------------------------------------------
protected:
static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
//{----------------------------------------------------------------------------------------------------------------
//! Текущий макет диалога.
//}----------------------------------------------------------------------------------------------------------------
private:
const Layout* layout_;
};
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Dialogs: Message Map macros
//! @name Макросы для построения статической карты сообщений (Message Map)
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Заголовок карты сообщений (Message Map).
//!
//! @par Раскрывается в
//! @code
//! virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) override
//! {
//! int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam);
//!
//! switch (_msg)
//! {
//! @endcode
//!
//! @see TX_BEGIN_MESSAGE_MAP(), TX_END_MESSAGE_MAP, TX_HANDLE(), TX_COMMAND_MAP, txDialog::dialogProc(), txDialog
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define TX_BEGIN_MESSAGE_MAP() \
virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \
{ \
int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result; \
\
switch (_msg) \
{ \
case WM_NULL:
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Заголовок обработчика сообщения (Message handler) карты сообщений.
//!
//! @param id Идентификатор сообщения.
//!
//! @par Раскрывается в
//! @code
//! break;
//! case (id):
//! @endcode
//!
//! @see TX_BEGIN_MESSAGE_MAP(), TX_END_MESSAGE_MAP, TX_HANDLE(), TX_COMMAND_MAP, txDialog::dialogProc(), txDialog
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define TX_HANDLE( id ) \
break; \
case (id):
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Начало карты команд (Command map) в карте сообщений.
//!
//! @par Раскрывается в
//! @code
//! } // Конец switch (_msg)
//!
//! if (_msg == WM_COMMAND)
//! switch (LOWORD (_wParam))
//! {
//! @endcode
//!
//! @see TX_BEGIN_MESSAGE_MAP(), TX_END_MESSAGE_MAP, TX_HANDLE(), TX_COMMAND_MAP, txDialog::dialogProc(), txDialog
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define TX_COMMAND_MAP \
default: break; \
} \
\
if (_msg == WM_COMMAND) switch (LOWORD (_wParam)) \
{ \
case 0:
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Завершитель карты сообщений.
//!
//! @par Раскрывается в
//! @code
//! } // Конец switch (_msg) или switch (LOWORD (_wParam))
//!
//! return FALSE;
//! }
//! @endcode
//!
//! @see TX_BEGIN_MESSAGE_MAP(), TX_END_MESSAGE_MAP, TX_HANDLE(), TX_COMMAND_MAP, txDialog::dialogProc(), txDialog
//!
//! @usage @code
//! Cм. реализацию функции txInputBox().
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define TX_END_MESSAGE_MAP \
default: break; \
} \
\
return FALSE; \
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Dialogs: txDialog example: txInputBox()
//! @name Пример использования класса диалога: функция txInputBox()
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Dialogs
//! @brief Ввод строки в отдельном окне.
//!
//! @param text Текст с вопросом. Необязательно.
//! @param caption Заголовок окна. Необязательно.
//! @param input Значение строки по умолчанию. Необязательно.
//!
//! @return Введенная строка (статическая переменная функции).
//!
//! @warning Возвращаемая строка -- статическая, и обновляется при каждом вызове функции. Если txInputBox() будет
//! вызываться несколько раз, то для сохранения строки ее необходимо копировать в другую строку при помощи
//! strcpy().
//!
//! @see txDialog, TX_BEGIN_MESSAGE_MAP, TX_BEGIN_COMMAND_MAP, TX_HANDLE, TX_END_MESSAGE_MAP
//!
//! @usage @code
//! const char* name = txInputBox ("So what's ur name?!?!", "System", "Sorry I'm Vasya Pupkin");
//! txMessageBox (name, "Aaand nooowww.. the winner iiis...");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard;
#ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<<
const char* txInputBox (const char* text, const char* caption, const char* input)
{
//-------------------------------------------------------------------------------------------------------------
// Если не указаны параметры, приходится использовать хоть какие-то надписи.
// txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название.
//-------------------------------------------------------------------------------------------------------------
if (!text) text = "Введите строку:";
if (!caption) caption = txGetModuleFileName (false);
if (!input) input = "";
//-------------------------------------------------------------------------------------------------------------
// Идентификаторы элементов диалога. Они требуются в GetDlgItemText().
// Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически.
// У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы
// ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения,
// динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о
//-------------------------------------------------------------------------------------------------------------
#define ID_TEXT_ 101
#define ID_INPUT_ 102
//-------------------------------------------------------------------------------------------------------------
// Задание макета (вида) диалога в виде массива структур.
// С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив
// становится похож на описание ресурса диалога в .rc-файле.
// См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com).
//-------------------------------------------------------------------------------------------------------------
txDialog::Layout layout[] =
//----------------------+----------+-----------+-----------------+---------------------------------------------
// Тип элемента | Имя | Иденти- | Координаты | Флаги элементов
// диалога | элемента | фикатор |-----------------| (см. описание элементов
// | | элемента | X | Y |Шир.|Выс.| окон диалога в MSDN)
//----------------------+----------+-----------+---+---+----+----+---------------------------------------------
// | | | | | | |
{{ txDialog::DIALOG, caption, 0, 0, 0, 240, 85 },
{ txDialog::STATIC, text, ID_TEXT_, 10, 10, 150, 40, SS_LEFT },
{ txDialog::EDIT, input, ID_INPUT_, 10, 60, 220, 15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP },
{ txDialog::BUTTON, "&OK", IDOK, 180, 10, 50, 15, BS_DEFPUSHBUTTON | WS_TABSTOP },
{ txDialog::BUTTON, "&Cancel", IDCANCEL, 180, 30, 50, 15, BS_PUSHBUTTON | WS_TABSTOP },
{ txDialog::END }};
//-------------------------------------------------------------------------------------------------------------
// Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним.
// Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она
// построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную
// функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее
// адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG).
//-------------------------------------------------------------------------------------------------------------
struct inputDlg : txDialog
{
char str [1024];
//---------------------------------------------------------------------------------------------------------
inputDlg() :
str()
{}
//---------------------------------------------------------------------------------------------------------
TX_BEGIN_MESSAGE_MAP() // Карта сообщений (на самом деле это начало оконной функции). //-V2525
TX_COMMAND_MAP // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch).
//-------------------------------------------------------------------------------------------------
// При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия
// диалога строка ввода умрет и текст уже из нее получить.
// Этот макрос на самом деле превращается в case из оператора switch.
// _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP().
//-------------------------------------------------------------------------------------------------
TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1);
TX_END_MESSAGE_MAP //-V2522
//---------------------------------------------------------------------------------------------------------
// Конец внутреннего класса диалога
//---------------------------------------------------------------------------------------------------------
};
//-------------------------------------------------------------------------------------------------------------
// Убираем дефайны, чтобы потом не мешали.
// От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом
// деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _.
// Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны.
//-------------------------------------------------------------------------------------------------------------
#undef ID_TEXT_
#undef ID_INPUT_
//-------------------------------------------------------------------------------------------------------------
// Это статический объект, потому что строка в нем должна жить после завершения функции.
//-------------------------------------------------------------------------------------------------------------
static inputDlg dlg;
//-------------------------------------------------------------------------------------------------------------
// Передаем layout и запускаем окно диалога
//-------------------------------------------------------------------------------------------------------------
dlg.dialogBox (layout);
//-------------------------------------------------------------------------------------------------------------
// Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет
// при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать
// синтаксически можно, но ведет к серьезным ошибкам.
//-------------------------------------------------------------------------------------------------------------
return dlg.str;
}
#endif // TX_COMPILED
//! @}
//}
//=================================================================================================================
//}
//=================================================================================================================
//=================================================================================================================
//{ TXLIB IMPLEMENTATION
// Реализация функций библиотеки
//=================================================================================================================
//! @cond INTERNAL {
//-----------------------------------------------------------------------------------------------------------------
//{ The Includes
//-----------------------------------------------------------------------------------------------------------------
#ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<<
_TX_END_NAMESPACE
//-----------------------------------------------------------------------------------------------------------------
#if defined (_MSC_VER)
#pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o
#pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
#pragma warning (disable: 4005) // 'name': macro redefinition
#endif
#if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED)
#undef __STRICT_ANSI__
#endif
//-----------------------------------------------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include