FallSimulator/TXLib.h
Андрей 41947390a0
Add files via upload
Adding TXLibrary C++ header file.
2019-09-20 15:11:22 +03:00

8499 lines
359 KiB
C++

//=================================================================================================================
// [These sections are for folding control in Code::Blocks]
//{ [Best viewed with "Fold all on file open" option enabled] [best screen width is 115 chars]
//=================================================================================================================
//!
//! @file TXLib.h
//! @brief Áèáëèîòåêà Òóïîãî Õóäîæíèêà (The Dumb Artist Library, TX Library, TXLib).
//!
//! $Version: 00172a, Revision: 104 $
//! $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $
//! $Date: 2014-08-09 16:37:26 +0400 $
//!
//! TX Library - êîìïàêòíàÿ áèáëèîòåêà äâóìåðíîé ãðàôèêè äëÿ Win32 íà Ñ++.
//! Ýòî íåáîëüøàÿ "ïåñî÷íèöà" äëÿ íà÷èíàþùèõ ðåàëèçîâàíà ñ öåëüþ ïîìî÷ü èì â èçó÷åíèè
//! ïðîñòåéøèõ ïðèíöèïîâ ïðîãðàììèðîâàíèÿ. Äîêóìåíòàöèÿ íà ðóññêîì ÿçûêå.
//!
//! Ôèëîñîôèÿ<sup><a href=#Refs><small>1</small></a></sup> TX Library - îáëåã÷èòü ïåðâûå øàãè
//! â ïðîãðàììèðîâàíèè è ïîäòîëêíóòü ê òâîð÷åñòâó è ñàìîñòîÿòåëüíîñòè.
//!
//! TX Library is a tiny 2D graphics library for Win32 written in C++. This is a small
//! sandbox for the very beginners to help them to learn basic programming principles.
//! The documentation is currently in Russian.
//!
//! Îôèöèàëüíûé ñàéò áèáëèîòåêè: <a href=http://txlib.ru>txlib.ru.</a>
//!
//! Ñì. òàêæå <a href=http://txlib.sourceforge.net>ñòðàíèöó ïðîåêòà íà SourceForge.</a>
//!
//! @warning <b>Ýòî àëüôà-âåðñèÿ. Äëÿ èñïîëüçîâàíèÿ òðåáóåòñÿ ñîãëàñîâàíèå ñ àâòîðîì áèáëèîòåêè.</b> @nn
//! Ïðàâèëà èñïîëüçîâàíèÿ ìàòåðèàëîâ áèáëèîòåêè è ñàéòà ñì. íà <a href=http://txlib.ru>
//! îôèöèàëüíîì ñàéòå.</a>
//!
//! @par Òðåêåðû íà SourceForge:
//! - <a href=https://sourceforge.net/tracker/?func=add&group_id=213688&atid=1026710> <b>Ñîîáùèòü îá îøèáêå </b></a>
//! - <a href=https://sourceforge.net/tracker/?func=add&group_id=213688&atid=1026713> <b>Ïðåäëîæèòü óëó÷øåíèå</b></a>
//!
//! @par Ëèòåðàòóðà <a name=Refs>
//! -# <a href=http://storage.ded32.net.ru/Materials/ConferencePseudoScientific-2003.pdf>
//! Ñàëüíèêîâ Â.Í., Èëüèí Â.Â., Øàðêî Ô.Ñ., Ìèòèíà Í.Â., Áåëàÿ È.Â., Èíäóêàåâ À.Ê., Äåäèíñêèé È.Ð.
//! Ñòðóêòóðà è äèíàìèêà ïîâåäåí÷åñêèõ ðåàêöèé â óñëîâèÿõ èíôîðìàöèîííîé ïåðåãðóçêè. <i>Batman
//! Proceedings in Sheep Philosophy,</i> 2003, Vol. 22. pp. 23-24.</a>
//!
// $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $
//-----------------------------------------------------------------------------------------------------------------
//!
//! @defgroup Drawing Ðèñîâàíèå
//! @defgroup Mouse Ïîääåðæêà ìûøè
//! @defgroup Dialogs Äèàëîãîâûå îêíà
//! @defgroup Misc Ðàçíîå
//! @defgroup Service Ñëóæåáíîå
//! @defgroup Technical Òåõíè÷åñêèå äåòàëè
//}
//=================================================================================================================
#if !defined (__TXLIB_H_INCLUDED) // <<<<<<<<< The code is here, unfold it <<<<<<<<<<<<<<<<<<<<<<<<<
#define __TXLIB_H_INCLUDED
//-----------------------------------------------------------------------------------------------------------------
//{ Version information
//-----------------------------------------------------------------------------------------------------------------
//! @cond INTERNAL
#define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2) "TXLib [Ver: " #ver ", Rev: " #rev "]"
#define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2) "Copyright (C) " auth
#define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2) ((0x##ver << 16) | 0x##rev)
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Òåêóùàÿ âåðñèÿ áèáëèîòåêè.
//!
//! @code
//! #define _TX_VERSION "TXLib [Version: 1.72a, Revision 50]" (ïðèìåð)
//! #define _TX_AUTHOR "Copyright (C) Ded (Ilya Dedinsky, http://txlib.ru)"
//! @endcode
//! Ýòè êîíñòàíòû àâòîìàòè÷åñêè îáíîâëÿþòñÿ ïðè èçìåíåíèè âåðñèè.
//!
//! @see txVersion()
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define _TX_VERSION _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00172a, 104, 2014-08-09 16:37:26 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
#define _TX_AUTHOR _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00172a, 104, 2014-08-09 16:37:26 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Âåðñèÿ áèáëèîòåêè â öåëî÷èñëåííîì ôîðìàòå.
//!
//! Ôîðìàò: ñòàðøåå ñëîâî - íîìåð âåðñèè, ìëàäøåå - íîìåð ðåâèçèè, â äâîè÷íî-äåñÿòè÷íîì ôîðìàòå.
//! Íàïðèìåð, @c 0x172a0050 - âåðñèÿ @c 0.172a, ðåâèçèÿ @c 50.
//!
//! Ýòà êîíñòàíòà àâòîìàòè÷åñêè îáíîâëÿåòñÿ ïðè èçìåíåíèè âåðñèè.
//!
//! @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, 00172a, 104, 2014-08-09 16:37:26 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
//}
//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
//{ 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.
#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], then
#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)
#ifdef __GNUC__
#error
#error --------------------------------------------------------------------------------------------------------
#endif
#error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW) is the only supported system, sorry.
#error
#error In Linux or iOS, you should write your own TXLib and share it with your friends,
#error 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 <Windows.h> in UNICODE mode.
#error
#error REARRANGE your #include directives, or DISABLE the UNICODE mode.
#error --------------------------------------------------------------------------------------------------------
#error
#endif
#endif
#if defined (__STRICT_ANSI__) // Try to extend strict ANSI rules
#ifdef __GNUC__
#warning TXLib.h: Trying to extend strict ANSI compatibility
#endif
#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 <string.h> or <stdio.h> in Strict ANSI mode.
#error
#error REARRANGE your #include directives, or DISABLE ANSI-compliancy.
#error --------------------------------------------------------------------------------------------------------
#error
#endif
#endif
#if defined (__GNUC__)
#define _GCC_VER ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ )
#if defined (_GCC_VER) && (_GCC_VER >= 420)
#if (_GCC_VER >= 460)
#pragma GCC diagnostic push
#endif
#pragma GCC optimize ("no-strict-aliasing")
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wunreachable-code"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-label" // Just for fun in _txCanvas_OnCmdAbout()
#pragma GCC diagnostic ignored "-Winline"
#define _TX_THREAD __thread
#else
#define _TX_THREAD
#endif
#define _TX_CHECK_FORMAT( at ) __attribute__ (( format (printf, (at), (at)+1) ))
template <typename T>
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" unsigned int __cdecl _controlfp (unsigned int unNew, unsigned int unMask);
extern "C" void __cdecl _fpreset (void);
#else
#define _TX_CHECK_FORMAT( at )
#define _txNOP( value ) ( value )
#endif
#if defined (_MSC_VER)
#pragma warning (push, 4) // Set maximum warning level
#pragma warning (disable: 4127) // conditional expression is constant
#pragma warning (disable: 4351) // new behavior: elements of array will be default initialized
#pragma warning (disable: 4702) // unreachable code
#define _TX_THREAD __declspec (thread)
#endif
#if defined (_MSC_VER) && (_MSC_VER == 1200) // MSVC 6 (1998)
#define _MSC_VER_6 // Flag the bad dog
#pragma warning (disable: 4511) // copy constructor could not be generated
#pragma warning (disable: 4512) // assignment operator could not be generated
#pragma warning (disable: 4514) // unreferenced inline function has been removed
#pragma warning (disable: 4663) // C++ language change: to explicitly specialize class template
#pragma warning (disable: 4710) // function not inlined
#pragma warning (disable: 4786) // identifier was truncated to '255' characters in the debug information
#if !defined (WINVER)
#define WINVER 0x0400 // MSVC 6: Defaults to Windows 95
#endif
#if !defined (NDEBUG)
#define _CRTDBG_MAP_ALLOC 1 // Set debug mode heap allocation
#endif
#endif
#if defined (_MSC_VER) && (_MSC_VER >= 1400) // MSVC 8 (2005) or greater
#pragma warning (disable: 26135) // missing locking annotation
#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 setlocale ("russian") // Set source file encoding, see also _TX_CP
#if !defined (NDEBUG)
#pragma check_stack (on) // Turn on stack probes at runtime
#pragma strict_gs_check (push, on) // Detects stack buffer overruns
#endif
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
#define _TX_TRUNCATE , _TRUNCATE
#else
#define strcpy_s strcpy // MSVC prior to 8 (2005) versions and GCC
#define strncpy_s strncpy // do NOT have secure variants of these
#define strncat_s strncat // functions, so use insecure ones.
#define wcsncpy_s wcsncpy // ...
#define _snprintf_s _snprintf //
#define _vsnprintf_s _vsnprintf //
#define strerror_s( buf, code ) ( strncpy ((buf), strerror (code), sizeof(buf)-1) )
#define ctime_s( buf, sizeof_buf, time ) ( strncpy ((buf), ctime (time), (sizeof_buf)-1) )
#define getenv_s( sz, buf, sizeof_buf, name ) ( (void)(sz), strncpy ((buf), getenv (name), (sizeof_buf)-1) )
#define strtok_s( buf, delim, ctx ) ( (void)(ctx), strtok ((buf), (delim)) )
#if !( defined (_GCC_VER) && (_GCC_VER == 471) && defined (__x86_64__) ) // GCC 4.7.1 x64 already has it
#define _controlfp_s( oldCtl, newCtl, mask ) ( *(oldCtl) = _controlfp (newCtl, mask), 0 )
#endif
#define _TX_TRUNCATE
#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: 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 (WINVER)
#define WINVER 0x0500 // Defaults to Windows 2000
#define WINDOWS_ENABLE_CPLUSPLUS // Allow use of type-limit macros in <basetsd.h>,
#endif // they 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 _USE_MATH_DEFINES // math.h's M_PI etc.
//! @} @endcond
//}
//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
//{ The Includes
//-----------------------------------------------------------------------------------------------------------------
#ifdef _MSC_VER_6
#pragma warning (push, 3) // MSVC 6: At level 4, some std headers emit warnings O_o
#endif
//-----------------------------------------------------------------------------------------------------------------
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <process.h>
#include <signal.h>
#include <locale.h>
#include <time.h>
#include <float.h>
#include <math.h>
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <exception>
#include <stdexcept>
#include <conio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <shellapi.h>
#include <shlobj.h>
#if defined (_MSC_VER)
#include <crtdbg.h>
#endif
//-----------------------------------------------------------------------------------------------------------------
#ifdef _MSC_VER_6
#pragma warning (pop) // MSVC 6: Restore max level
#endif
#ifdef __STRICT_ANSI__UNDEFINED
#define __STRICT_ANSI__ // Redefine back
#endif
//}
//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
//{ The namespaces
//-----------------------------------------------------------------------------------------------------------------
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Àíîíèìíîå ïðîñòðàíñòâî èìåí äëÿ çàùèòû îò êîíôëèêòîâ ïðè ñáîðêå ìíîãîôàéëîâîãî ïðîåêòà.
//}----------------------------------------------------------------------------------------------------------------
#ifdef FOR_DOXYGEN_ONLY
namespace { namespace TX { }}
#endif
//}
//-----------------------------------------------------------------------------------------------------------------
/*! @cond INTERNAL */
namespace { namespace TX { // <<<<<<<<< The main code is here, unfold it <<<<<<<<<<<<<<<<<<<<
/*! @endcond */
//=================================================================================================================
//{ TXLIB INTERFACE
// Èíòåðôåéñ áèáëèîòåêè
//=================================================================================================================
//=================================================================================================================
//{ Initialization
//! @name Èíèöèàëèçàöèÿ áèáëèîòåêè
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ñîçäàíèå îêíà ðèñîâàíèÿ
//!
//! @param sizeX Ðàçìåð îêíà ïî ãîðèçîíòàëè (â ïèêñåëÿõ)
//! @param sizeY Ðàçìåð îêíà ïî âåðòèêàëè (â ïèêñåëÿõ)
//! @param centered Öåíòðèðîâàíèå îêíà íà äèñïëåå
//!
//! @return Äåñêðèïòîð (ñèñòåìíûé íîìåð) îêíà TXLib. Åñëè îêíî íå ñîçäàíî, âîçâðàùàåòñÿ NULL.
//!
//! @note Óñòàíàâëèâàþòñÿ ïàðàìåòðû ðèñîâàíèÿ ïî óìîë÷àíèþ, ñì. ôóíêöèþ txSetDefaults().
//!
//! @warning Åñëè èñïîëüçóåòñÿ ìíîãîôàéëîâûé ïðîåêò (ñ ðàçäåëüíîé êîìïèëÿöèåé), òî ãðàôè÷åñêèå ôóíêöèè TXLib,
//! âûçâàííûå èç ôàéëà ïðîåêòà, áóäóò ðàáîòàòü òîëüêî ñ òåì îêíîì, êîòîðîå ñîçäàíî <b>â ýòîì æå ôàéëå</b>
//! ïðîåêòà. Åñëè ïðîåêò ñîñòîèò, ñêàæåì, èç ôàéëîâ @c main.cpp è @c game.cpp, è â ôàéëå @c main.cpp
//! ñîçäàåòñÿ ãðàôè÷åñêîå îêíî, òî ôóíêöèè èç @c game.cpp íå ñìîãóò ðèñîâàòü â íåì. (Îäíàêî @c game.cpp
//! ñìîæåò ñîçäàòü ñâîå ñîáñòâåííîå îêíî.) @n
//! Åñëè òàêîé ïðîãðàììå íóæíî îäíî îêíî, òî â ïðîåêò ñëåäóåò âêëþ÷èòü ôàéë, îòâåòñòâåííûé çà ðèñîâàíèå,
//! ñêàæåì, @c graphics.cpp, è âûâîäèòü ãðàôèêó òîëüêî ÷åðåç ôóíêöèè ýòîãî ôàéëà. Òàêîé ôàéë (èëè
//! áèáëèîòåêó) â áîëüøèõ ïðîåêòàõ ÷àñòî íàçûâàþò ãðàôè÷åñêèì äâèæêîì. @nn
//! Òî æå êàñàåòñÿ è èñïîëüçîâàíèÿ TXLib â @b DLL.
//!
//! @note Âñïîìîãàòåëüíûå îêíà ìîãóò ñîçäàâàòüñÿ ïî îäíîìó íà êàæäûé ôàéë ìíîãîôàéëîâîãî ïðîåêòà èëè çàãðóæåííóþ
//! DLL. Äëÿ çàêðûòèÿ âñïîìîãàòåëüíûõ îêîí èñïîëüçóåòñÿ txDestroyWindow(). Äëÿ çàêðûòèÿ ãëàâíîãî íàäî
//! âûéòè èç main().
//!
//! @warning Îäíîâðåìåííîå ñîçäàíèå íåñêîëüêèõ îêîí íå ïîòîêîáåçîïàñíî (not thread-safe). @nn
//! Ìíîãîîêîííàÿ ïðîãðàìà íà TXLib òîðìîçèò, äà è îäíîîêîííàÿ òîæå íå îòëè÷àåòñÿ âûñîêîé ñêîðîñòüþ. ×òîáû
//! èçáàâèòüñÿ îò ýòîãî, áðîñüòå TXLib è èñïîëüçóéòå äðóãèå îêîííûå áèáëèîòåêè (<a href=http://qt-project.org>Qt</a>,
//! <a href=http://wxwidgets.org>wxWidgets</a>, <a href=http://gtk.org>GTK+</a> è ò.ä., ñì. òàêæå <a href=http://libsdl.org>
//! SDL</a>, <a href=http://opengl.org>OpenGL</a> è ò.ï.) èëè íàïèøèòå ñâîþ. Ïîìíèòå, ÷òî öåëü TXLib -
//! îáëåã÷èòü ïåðâûå øàãè, íî ïîòîì ñòàòü íåíóæíîé.
//!
//! @see txOK(), txWindow(), txDC(), _txWindowStyle, _txConsoleMode, _txConsoleFont, _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 Óñòàíîâêà ïàðàìåòðîâ ðèñîâàíèÿ ïî óìîë÷àíèþ.
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @par Ïàðàìåòðû ïî óìîë÷àíèþ:
//! - Ëèíèè - öâåò áåëûé (TX_WHITE), òîëùèíà 1
//! - Çàëèâêà - öâåò áåëûé (TX_WHITE)
//! - Øðèôò - Ñèñòåìíûé øðèôò, öâåò áåëûé (TX_WHITE)
//! - Ðàñòðîâàÿ îïåðàöèÿ - êîïèðîâàíèå öâåòà (R2_COPYPEN)
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txSelectFont(), txSetROP2()
//!
//! @usage @code
//! txSetDefaults();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSetDefaults();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ïðîâåðêà ïðàâèëüíîñòè ðàáîòû áèáëèîòåêè
//!
//! @return Ñîñòîÿíèå áèáëèîòåêè: true - áèáëèîòåêà â ïîðÿäêå, false - íå â ïîðÿäêå.
//!
//! "Áèáëèîòåêà íå â ïîðÿäêå" îçíà÷àåò, ÷òî åå âíóòðåííèå äàííûå íåâåðíû. Ñàìàÿ ïðîñòàÿ ïðè÷èíà -
//! íå îòêðûòî îêíî, îäíàêî ìîãóò áûòü è äðóãèå ïðîáëåìû.
//!
//! @see txCreateWindow()
//!
//! @usage @code
//! txCreateWindow (800, 600);
//! if (!txOK())
//! {
//! txMessageBox ("Íå ñìîãëà ñîçäàòü îêíî", "Èçâèíèòå", MB_ICONSTOP);
//! return;
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline bool txOK();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò ðàçìåð îêíà ðèñîâàíèÿ â âèäå ñòðóêòóðû POINT.
//!
//! @return Ðàçìåð îêíà ðèñîâàíèÿ â âèäå ñòðóêòóðû POINT, ñîäåðæàùåé êîìïîíåíòû @c x è @c y.
//!
//! @see txGetExtentX(), txGetExtentY()
//!
//! @usage @code
//! POINT size = txGetExtent();
//!
//! txLine (0, 0, size.x, size.y);
//! txLine (0, size.y, size.x, 0);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetExtent();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò øèðèíó îêíà ðèñîâàíèÿ.
//!
//! @return Øèðèíà îêíà ðèñîâàíèÿ.
//!
//! @see txGetExtent(), txGetExtentY()
//!
//! @usage @code
//! txSetTextAlign (TA_CENTER);
//! txTextOut (txGetExtentX() / 2, 100, "Oh, oh, you're in the [army]middle now");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txGetExtentX();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò âûñîòó îêíà ðèñîâàíèÿ.
//!
//! @return Âûñîòà îêíà ðèñîâàíèÿ.
//!
//! @see txGetExtent(), txGetExtentX()
//!
//! @usage @code
//! void DrawHouse (int height);
//! ...
//! DrawHouse (txGetExtentY() / 2);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txGetExtentY();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò äåñêðèïòîð êîíòåêñòà ðèñîâàíèÿ õîëñòà
//!
//! @return Äåñêðèïòîð (ñèñòåìíûé íîìåð, handler) êîíòåêñòà ðèñîâàíèÿ (device context, DC) õîëñòà (HDC).
//!
//! @note HDC âîçâðàùàåòñÿ â âèäå ññûëêè, ÷òî ïîçâîëÿåò ïîäìåíèòü åãî. Ïåðåä ïîäìåíîé íàäî ñîõðàíèòü ñòàðûé
//! äåñêðèïòîð èëè îñâîáîäèòü åãî ñ ïîìîùüþ txDeleteDC(). Äî ïîäìåíû ðèñîâàíèå äîëæíî áûòü çàáëîêèðîâàíî
//! ñ ïîìîùüþ txLock() è ïîñëå ïîäìåíû ðàçáëîêèðîâàíî ñ ïîìîùüþ txUnlock().
//!
//! @see txWindow(), 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();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò äåñêðèïòîð îêíà õîëñòà
//!
//! @return Äåñêðèïòîð (ñèñòåìíûé íîìåð, handler) îêíà õîëñòà
//!
//! @see txDC(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! SetWindowText (txWindow(), "Íîâûå çàãîëîâêè - òåïåðü è â âàøèõ îêíàõ!");
//! txMessageBox ("Ðàñïèøèòåñü", "Ïîëó÷èòå", MB_ICONINFORMATION);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline HWND txWindow();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Âîçâðàùàåò ñòðîêó ñ èíôîðìàöèåé î òåêóùåé âåðñèè áèáëèîòåêè.
//!
//! @return Ñòðîêà ñ èíôîðìàöèåé î òåêóùåé âåðñèè áèáëèîòåêè.
//!
//! @usage @code
//! printf ("I personally love %s\n", txVersion());
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline const char* txVersion();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Âîçâðàùàåò íîìåð âåðñèè áèáëèîòåêè.
//!
//! @return Íîìåð âåðñèè áèáëèîòåêè.
//!
//! @usage @code
//! printf ("My magic number is %x\n", txVersionNumber());
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline unsigned txVersionNumber();
//{----------------------------------------------------------------------------------------------------------------
//! @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);
//! txSleep (50);
//! }
//!
//! txMessageBox ("Âîò òàêîé âîò progress bar", "TXLib forever)");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
const char* txGetModuleFileName (bool fileNameOnly = true);
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ 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_RED);
//! 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), //!< Òåìíî-ñèíèé öâåò. <i>Ïëîõî âèäåí.</i>
TX_GREEN = RGB ( 0, 128, 0), //!< Çåëåíûé öâåò.
TX_CYAN = RGB ( 0, 128, 128), //!< Áèðþçîâûé öâåò.
TX_RED = RGB (128, 0, 0), //!< Òåìíî-êðàñíûé öâåò. <i>Ñëèøêîì òåìíûé.</i>
TX_MAGENTA = RGB (128, 0, 128), //!< Òåìíî-ìàëèíîâûé öâåò.
TX_BROWN = RGB (128, 128, 0), //!< Êîðè÷íåâûé öâåò. <i>Íåêðàñèâûé. Do it yourself with RGB().</i>
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), //!< Ñâåòëî-êðàñíûé öâåò. <i>Íå ñàìîãî ëó÷øåãî îòòåíêà.</i>
TX_LIGHTMAGENTA = RGB (255, 0, 255), //!< Ñâåòëî-ìàëèíîâûé öâåò. <i>Åùå ìåíåå ëó÷øåãî îòòåíêà.</i>
TX_PINK = RGB (255, 128, 255), //!< Ðîçîâûé ãëàìóðíûé :)
TX_YELLOW = RGB (255, 255, 128), //!< Æåëòûé öâåò.
TX_WHITE = RGB (255, 255, 255), //!< Áåëûé öâåò.
TX_TRANSPARENT = 0xFFFFFFFF, //!< Ïðîçðà÷íûé öâåò. <i>Îòêëþ÷àåò ðèñîâàíèå.</i>
TX_NULL = TX_TRANSPARENT, //!< Ïðîçðà÷íûé öâåò. <i>Îòêëþ÷àåò ðèñîâàíèå.</i>
// Öâåòîâûå êàíàëû (êîìïîíåíòû) - ñì. txExtractColor(), txRGB2HSL(), txHSL2RGB()
TX_HUE = 0x04000000, //!< Öâåòîâîé òîí öâåòà â ìîäåëè HSL
TX_SATURATION = 0x05000000, //!< Íàñûùåííîñòü öâåòà â ìîäåëè HSL
TX_LIGHTNESS = 0x06000000; //!< Ñâåòëîòà öâåòà â ìîäåëè HSL
#ifdef FOR_DOXYGEN_ONLY
};
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @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 Òîëùèíà ëèíèé
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txColor(), txGetColor(), txFillColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage @code
//! txSetColor (TX_RED);
//! txSetColor (RGB (255, 128, 0), 5);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSetColor (COLORREF color, double thickness = 1);
//! @cond INTERNAL
#define txSetColour txSetColor
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óñòàíàâëèâàåò òåêóùèé öâåò ëèíèé è òåêñòà.
//!
//! @param red Êîëè÷åñòâî êðàñíîãî öâåòà â èíòåðâàëå [0; 1]
//! @param green Êîëè÷åñòâî çåëåíîãî öâåòà â èíòåðâàëå [0; 1]
//! @param blue Êîëè÷åñòâî ñèíåãî öâåòà â èíòåðâàëå [0; 1]
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor()
//!
//! @usage @code
//! txColor (1.0, 1.0, 0.0); // Êðàñíûé + çåëåíûé = æåëòûé
//! txColor (1.0, 0.5, 0.25); // Íå÷òî îðàíæåâîå
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txColor (double red, double green, double blue);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò òåêóùèé öâåò ëèíèé è òåêñòà.
//!
//! @return Òåêóùèé öâåò ëèíèé è òåêñòà, ñì. txColors, RGB()
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage @code
//! COLORREF color = txGetColor();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txGetColor();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óñòàíàâëèâàåò òåêóùèé öâåò çàïîëíåíèÿ ôèãóð.
//!
//! @param color Öâåò çàïîëíåíèÿ, ñì. txColors, RGB()
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txFillColor(), txGetFillColor(), txColor(), txGetColor(), txColors, RGB()
//!
//! @usage @code
//! txSetFillColor (TX_RED);
//! txSetFillColor (RGB (255, 128, 0));
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSetFillColor (COLORREF color);
//! @cond INTERNAL
#define txSetFillColour txSetFillColor
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óñòàíàâëèâàåò òåêóùèé öâåò çàïîëíåíèÿ ôèãóð.
//!
//! @param red Êîëè÷åñòâî êðàñíîãî öâåòà â èíòåðâàëå [0; 1]
//! @param green Êîëè÷åñòâî çåëåíîãî öâåòà â èíòåðâàëå [0; 1]
//! @param blue Êîëè÷åñòâî ñèíåãî öâåòà â èíòåðâàëå [0; 1]
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txSetFillColor(), txGetFillColor(), txSetColor(), txGetColor()
//!
//! @usage @code
//! txFillColor (1.0, 0.5, 0.25);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txFillColor (double red, double green, double blue);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò òåêóùèé öâåò çàïîëíåíèÿ ôèãóð.
//!
//! @return Òåêóùèé öâåò çàïîëíåíèÿ ôèãóð, ñì. txColors, RGB()
//!
//! @see txSetFillColor(), txGetFillColor(), txSetColor(), txGetColor(), txColors, RGB()
//!
//! @usage @code
//! COLORREF color = txGetFillColor();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txGetFillColor();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óñòàíàâëèâàåò ðåæèì âçàèìîäåéñòâèÿ öâåòîâ ïðè ðèñîâàíèè.
//!
//! Ïðè ðèñîâàíèè ãðàôè÷åñêàÿ áèáëèîòåêà ìîæåò íå ïðîñòî êðàñèòü ïèêñåëè íà ýêðàíå, à ñìåøèâàòü öâåòà
//! ýêðàíà è òåêóùèå öâåòà ëèíèé è çàïîëíåíèÿ.
//!
//! @param mode Ðåæèì ñìåøèâàíèÿ öâåòîâ
//!
//! @return Ïðåäûäóùèé ðåæèì âçàèìîäåéñòâèÿ öâåòîâ, ñì. txColors, RGB()
//!
//! @title Ðåæèìû âçàèìîäåéñòâèÿ öâåòîâ:
//! @table @tr R2_COPYPEN @td Ïèêñåëè = öâåòà êèñòè (ñàìûé íîðìàëüíûé ðåæèì :)
//! @tr R2_NOTCOPYPEN @td Ïèêñåëè = ~êèñòü
//! @tbr
//! @tr R2_BLACK @td Ïèêñåëè = ÷åðíûé öâåò (öâåò êèñòè èãíîðèðóåòñÿ)
//! @tr R2_WHITE @td Ïèêñåëè = áåëûé öâåò (öâåò êèñòè èãíîðèðóåòñÿ)
//! @tr R2_NOT @td Ïèêñåëè = ~ïèêñåëè (öâåò êèñòè èãíîðèðóåòñÿ)
//! @tbr
//! @tr R2_XORPEN @td Ïèêñåëè = ïèêñåëè ^ êèñòü (óäîáíûé ðåæèì, cì. ïðèìåð íèæå)
//! @tr R2_NOTXORPEN @td Ïèêñåëè = ~ (ïèêñåëè ^ êèñòü)
//! @tbr
//! @tr R2_MASKPEN @td Ïèêñåëè = ïèêñåëè & êèñòü
//! @tr R2_NOTMASKPEN @td Ïèêñåëè = ~ (ïèêñåëè & êèñòü)
//! @tr R2_MASKNOTPEN @td Ïèêñåëè = ïèêñåëè & ~êèñòü
//! @tr R2_MASKPENNOT @td Ïèêñåëè = ~ïèêñåëè & êèñòü
//! @tbr
//! @tr R2_MERGEPEN @td Ïèêñåëè = ïèêñåëè | êèñòü
//! @tr R2_NOTMERGEPEN @td Ïèêñåëè = ~ (ïèêñåëè | êèñòü)
//! @tr R2_MERGENOTPEN @td Ïèêñåëè = ïèêñåëè | ~êèñòü
//! @tr R2_MERGEPENNOT @td Ïèêñåëè = ~ïèêñåëè | êèñòü
//! @tbr
//! @tr R2_NOP @td Ïèêñåëè âîîáùå íå èçìåíÿþòñÿ.
//! @endtable
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txSetColor (TX_WHITE, 5); // Ïðè ðèñîâàíèè áåëûì öâåòîì â ðåæèìå
//! txSetROP2 (R2_XORPEN); // R2_XORPEN öâåòà íà ýêðàíå èíâåðòèðóþòñÿ
//!
//! txLine (100, 100, 200, 200); // Ðèñóåì ïåðâûé ðàç - ëèíèÿ ïîÿâëÿåòñÿ
//! txSleep (1000);
//! txLine (100, 100, 200, 200); // Ðèñóåì âòîðîé ðàç - ëèíèÿ èñ÷åçàåò (íåìíîãî óëè÷íîé ìàãèè)
//!
//! txSetROP2 (R2_COPYPEN); // Âîññòàíàâëèâàåì íîðìàëüíûé ðåæèì
//! txLine (100, 100, 200, 200); // Ðèñóåì ïåðâûé ðàç - ëèíèÿ ïîÿâëÿåòñÿ
//!
//! txLine (100, 100, 200, 200); // Ðèñóåì ïåðâûé ðàç - ëèíèÿ îñòàåòñÿ, êòî áû ìîã ïîäóìàòü
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSetROP2 (int mode = R2_COPYPEN);
//{----------------------------------------------------------------------------------------------------------------
//! @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);
//!
//! Äðóãèå ïðèìåðû ñì. â ôóíêöèÿõ AppearText(), AppearEarth() Ïðèìåðà 5 ("Öèêëû").
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txExtractColor (COLORREF color, COLORREF component);
//{----------------------------------------------------------------------------------------------------------------
//! @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 äî 255 <b>(íå äî 360).</b>
//! - Íàñûùåííîñòü (Saturation), îò 0 äî 255.
//! - Ñâåòëîòà (Lightness), îò 0 äî 255.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(), txExtractColor(),
//! txRGB2HSL(), txHSL2RGB()
//!
//! @usage @code
//! COLORREF hslColor = txRGB2HSL (TX_RED);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
COLORREF txRGB2HSL (COLORREF rgbColor);
//{----------------------------------------------------------------------------------------------------------------
//! @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 äî 255 <b>(íå äî 360).</b>
//! - Íàñûùåííîñòü (Saturation), îò 0 äî 255.
//! - Ñâåòëîòà (Lightness), îò 0 äî 255.
//!
//! @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);
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Drawing
//! @name Ðèñîâàíèå ôèãóð
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ñòèðàåò õîëñò òåêóùèì öâåòîì çàïîëíåíèÿ.
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txSetFillColor(), txFillColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage @code
//! txClear();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txClear();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ïèêñåëü (òî÷êó íà ýêðàíå).
//!
//! @param x Õ-êîîðäèíàòà òî÷êè
//! @param y Y-êîîðäèíàòà òî÷êè
//! @param color Öâåò òî÷êè, ñì. txColors, RGB()
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txPixel(), txGetPixel(), txColors, RGB()
//!
//! @usage @code
//! txSetPixel (100, 100, TX_RED);
//! txSetPixel (100, 100, RGB (255, 128, 0));
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline bool txSetPixel (double x, double y, COLORREF color);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ïèêñåëü (òî÷êó íà ýêðàíå).
//!
//! @param x Õ-êîîðäèíàòà òî÷êè
//! @param y Y-êîîðäèíàòà òî÷êè
//! @param red Êîëè÷åñòâî êðàñíîãî öâåòà â èíòåðâàëå [0; 1]
//! @param green Êîëè÷åñòâî çåëåíîãî öâåòà â èíòåðâàëå [0; 1]
//! @param blue Êîëè÷åñòâî ñèíåãî öâåòà â èíòåðâàëå [0; 1]
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txSetPixel(), txGetPixel()
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò òåêóùèé öâåò òî÷êè (ïèêñåëÿ) íà ýêðàíå.
//!
//! @param x Õ-êîîðäèíàòà òî÷êè
//! @param y Y-êîîðäèíàòà òî÷êè
//!
//! @return Òåêóùèé öâåò ïèêñåëÿ, ñì. txColors, RGB()
//!
//! @see txSetPixel(), txPixel(), txColors, RGB()
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ëèíèþ.
//!
//! @param x0 X-êîîðäèíàòà íà÷àëüíîé òî÷êè
//! @param y0 Y-êîîðäèíàòà íà÷àëüíîé òî÷êè
//! @param x1 X-êîîðäèíàòà êîíå÷íîé òî÷êè
//! @param y1 Y-êîîðäèíàòà êîíå÷íîé òî÷êè
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! Öâåò è òîëùèíà ëèíèè çàäàåòñÿ ôóíêöèåé txSetColor().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txLine(), txRectangle(), txPolygon(), txEllipse(), txCircle(), txArc(), txPie(), txChord()
//!
//! @usage @code
//! txLine (100, 200, 400, 500);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txLine (double x0, double y0, double x1, double y1);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ïðÿìîóãîëüíèê.
//!
//! @param x0 X-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà
//! @param y0 Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà
//! @param x1 X-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà
//! @param y1 Y-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà
//!
//! @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 â MSDN.com
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txRectangle (double x0, double y0, double x1, double y1);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ëîìàíóþ ëèíèþ èëè ìíîãîóãîëüíèê.
//!
//! @param points Ìàññèâ ñòðóêòóð POINT ñ êîîðäèíàòàìè òî÷åê
//! @param numPoints Êîëè÷åñòâî òî÷åê â ìàññèâå
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! Öâåò è òîëùèíà ëèíèé çàäàåòñÿ ôóíêöèåé txSetColor(), öâåò çàïîëíåíèÿ - txSetFillColor().
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ýëëèïñ.
//!
//! @param x0 X-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà ïðÿìîóãîëüíèêà, îïèñàííîãî âîêðóã ýëëèïñà
//! @param y0 Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà îïèñàííîãî ïðÿìîóãîëüíèêà
//! @param x1 X-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà îïèñàííîãî ïðÿìîóãîëüíèêà
//! @param y1 Y-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà îïèñàííîãî ïðÿìîóãîëüíèêà
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò îêðóæíîñòü èëè êðóã.
//!
//! @param 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 Âåëè÷èíà äóãè (â ãðàäóñàõ)
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ñåêòîð ýëëèïñà.
//!
//! @param x0 X-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà ïðÿìîóãîëüíèêà, îïèñàííîãî âîêðóã ýëëèïñà, ñîäåðæàùåãî äóãó (ñì. txEllipse)
//! @param y0 Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà ïðÿìîóãîëüíèêà
//! @param x1 X-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà ïðÿìîóãîëüíèêà
//! @param y1 Y-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà ïðÿìîóãîëüíèêà
//! @param startAngle Óãîë ìåæäó íàïðàâëåíèåì îñè OX è íà÷àëîì ñåêòîðà (â ãðàäóñàõ)
//! @param totalAngle Âåëè÷èíà ñåêòîðà (â ãðàäóñàõ)
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò õîðäó ýëëèïñà.
//!
//! @param x0 X-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà ïðÿìîóãîëüíèêà, îïèñàííîãî âîêðóã ýëëèïñà, ñîäåðæàùåãî äóãó (ñì. txEllipse)
//! @param y0 Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà ïðÿìîóãîëüíèêà
//! @param x1 X-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà ïðÿìîóãîëüíèêà
//! @param y1 Y-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà ïðÿìîóãîëüíèêà
//! @param startAngle Óãîë ìåæäó íàïðàâëåíèåì îñè OX è íà÷àëîì õîðäû (â ãðàäóñàõ)
//! @param totalAngle Âåëè÷èíà õîðäû (â ãðàäóñàõ)
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Çàëèâàåò ïðîèçâîëüíûé êîíòóð òåêóùèì öâåòîì çàïîëíåíèÿ.
//!
//! @param x Õ-êîîðäèíàòà òî÷êè íà÷àëà çàëèâêè
//! @param y Y-êîîðäèíàòà òî÷êè íà÷àëà çàëèâêè
//! @param color Öâåò çàëèâàåìîé îáëàñòè (TX_TRANSPARENT - àâòîîïðåäåëåíèå)
//! @param mode Ðåæèì çàëèâêè (FLOODFILLSURFACE - çàëèâêà îäíîðîäíîãî ôîíà)
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! Öâåò çàïîëíåíèÿ çàäàåòñÿ ôóíêöèåé txSetFillColor(). Íå ðåêîìåíäóåòñÿ äëÿ ïðèìåíåíèÿ - ðàáîòàåò
//! äîâîëüíî ìåäëåííî.
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ôóíêöèÿ, êîòîðàÿ äîëæíà áû ðèñîâàòü òðåóãîëüíèê.
//!
//! @param x1 Õ-êîîðäèíàòà 1 òî÷êè
//! @param y1 Y-êîîðäèíàòà 1 òî÷êè
//! @param x2 Õ-êîîðäèíàòà 2 òî÷êè
//! @param y2 Y-êîîðäèíàòà 2 òî÷êè
//! @param x3 Õ-êîîðäèíàòà 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 "Ïðèìåð ñ ôóíêöèÿìè ñ ïàðàìåòðàìè"
//}----------------------------------------------------------------------------------------------------------------
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;
MessageBox (txWindow(),
"Ýòà ôóíêöèÿ íå ðåàëèçîâàíà â áèáëèîòåêå, ïîòîìó ÷òî âû ñàìè ëåãêî ìîæåòå ðåàëèçîâàòü åå\n"
"êàê ôóíêöèþ ñ ïàðàìåòðàìè, èñïîëüçóÿ txPolygon(). Ñì. \"Ïðèìåð ñ ôóíêöèÿìè ñ ïàðàìåòðàìè\". ",
"TXLib ñîîáùàåò", MB_ICONINFORMATION);
return false;
}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò ÷åëîâå÷êà.
//!
//! @param 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
//}----------------------------------------------------------------------------------------------------------------
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);
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Drawing text
//! @name Ðàáîòà ñ òåêñòîì
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò òåêñò.
//!
//! @param x Õ-êîîðäèíàòà íà÷àëüíîé òî÷êè òåêñòà
//! @param y Y-êîîðäèíàòà íà÷àëüíîé òî÷êè òåêñòà
//! @param text Òåêñòîâàÿ ñòðîêà
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! Öâåò òåêñòà çàäàåòñÿ ôóíêöèåé txSetColor(), âûðàâíèâàíèå - txSetTextAlign().
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txSelectFont(), txSetTextAign(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txTextOut (100, 100, "Çäåñü ìîãëà áû áûòü Âàøà ðåêëàìà.");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txTextOut (double x, double y, const char text[]);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðèñóåò òåêñò, ðàçìåùåííûé â ïðÿìîóãîëüíîé îáëàñòè.
//!
//! @param x0 X-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà îáëàñòè
//! @param y0 Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà îáëàñòè
//! @param x1 X-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà îáëàñòè
//! @param y1 Y-êîîðäèíàòà íèæíåãî ïðàâîãî óãëà îáëàñòè
//! @param text Òåêñòîâàÿ ñòðîêà
//! @param format Ôëàãè ôîðìàòèðîâàíèÿ òåêñòà
//!
//! @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>Àâòîìàòè÷åñêèé ïåðåíîñ</b> òåêñòà íà íåñêîëüêî ñòðîê âêëþ÷àåòñÿ, åñëè òåêñò ñîñòîèò èç íåñêîëüêèõ
//! ñòðîê (åñòü õîòÿ áû îäèí ñèìâîë íîâîé ñòðîêè @b @c \\n).
//!
//! Åñëè íàäî îòôîðìàòèðîâàòü òåêñò íå ïî öåíòðó, à ïî ëåâîìó èëè ïðàâîìó êðàþ, òî íå çàáóäüòå óêàçàòü
//! îñòàëüíûå ôëàãè ôîðìàòèðîâàíèÿ, åñëè îíè íóæíû: @c DT_VCENTER (âåðòèêàëüíîå öåíòðèðîâàíèå) @c |
//! @c DT_WORDBREAK (ïåðåíîñ ïî ñëîâàì) @c | @c DT_WORD_ELLIPSIS (ñòàâèòü ìíîãîòî÷èå â êîíöå, åñëè òåêñò
//! íå óìåùàåòñÿ). Ñì. çíà÷åíèå ôëàãîâ ïî óìîë÷àíèþ.
//!
//! @see txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB(),
//! txTextOut(), txSelectFont(), txGetTextExtent(), txGetTextExtentX(), txGetTextExtentY()
//!
//! @usage @code
//! txSetColor (TX_BLACK);
//! txSetFillColor (TX_DARKGRAY); Win32::RoundRect (txDC(), 105, 105, 205, 255, 30, 30);
//! txSetFillColor (TX_WHITE); Win32::RoundRect (txDC(), 100, 100, 200, 250, 30, 30);
//!
//! txSelectFont ("Arial", 20, 0, FW_BOLD);
//! txDrawText (100, 100, 200, 250, "I hate it when I'm studying "
//! "and a Velociraptor throws bananas on me.\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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âûáèðàåò òåêóùèé øðèôò.
//!
//! @param name Íàçâàíèå øðèôòà
//! @param sizeY Âûñîòà áóêâ (ðàçìåð ïî Y)
//! @param sizeX Øèðèíà áóêâ
//! @param bold Æèðíîñòü øðèôòà (îò 0 äî 1000)
//! @param italic Êóðñèâ
//! @param underline Ïîä÷åðêèâàíèå
//! @param strikeout Çà÷åðêèâàíèå
//! @param angle Óãîë ïîâîðîòà òåêñòà (â ãðàäóñàõ)
//!
//! @return Âñåãäà true. Åñëè øðèôò íå áûë íàéäåí, òî óñòàíàâëèâàåòñÿ ñèñòåìíûé øðèôò Windows
//! @c (SYSTEM_FIXED_FONT, ñì. MSDN). Ñóùåñòâîâàíèå øðèôòà ìîæíî ïðîâåðèòü ôóíêöèåé txFontExist.
//!
//! @see txTextOut(), txFontExist()
//!
//! @usage @code
//! txSelectFont ("Comic Sans MS", 40);
//! txTextOut (100, 100, "È çäåñü ìîãëà áû áûòü Âàøà ðåêëàìà.");
//! txSelectFont ("Comic Sans MS", 40, 10, false, true, false, true, 15);
//! txTextOut (100, 200, "Íî åå ïî÷åìó-òî íåò.");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool 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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âû÷èñëÿåò ðàçìåðû òåêñòîâîé íàäïèñè.
//!
//! @param text Òåêñòîâàÿ ñòðîêà
//!
//! @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[]);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âû÷èñëÿåò øèðèíó òåêñòîâîé íàäïèñè.
//!
//! @param text Òåêñòîâàÿ ñòðîêà
//!
//! @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[]);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âû÷èñëÿåò âûñîòó òåêñòîâîé íàäïèñè.
//!
//! @param text Òåêñòîâàÿ ñòðîêà
//!
//! @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[]);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óñòàíàâëèâàåò òåêóùåå âûðàâíèâàíèå òåêñòà.
//!
//! @param align Ôëàãè âûðàâíèâàíèÿ
//!
//! @return Ïðåäûäóùåå ñîñòîÿíèå âûðàâíèâàíèÿ òåêñòà.
//!
//! @title Ôëàãè âûðàâíèâàíèÿ: @table
//! @tr TA_BASELINE @td Òî÷êà (X,Y) îïðåäåëÿåò áàçîâóþ ëèíèþ òåêñòà.
//! @tr TA_BOTTOM @td Òî÷êà (X,Y) îïðåäåëÿåò íèæíþþ ñòîðîíó îïèñàííîãî ïðÿìîóãîëüíèêà (òåêñò ëåæèò âûøå ýòîé òî÷êè).
//! @tr TA_TOP @td Òî÷êà (X,Y) îïðåäåëÿåò âåðõíþþ ñòîðîíó îïèñàííîãî ïðÿìîóãîëüíèêà (òåêñò ëåæèò íèæå ýòîé òî÷êè).
//! @tbr
//! @tr TA_CENTER @td Òåêñò áóäåò âûðîâíåí ïî ãîðèçîíòàëè îòíîñèòåëüíî òî÷êè (X,Y).
//! @tr TA_LEFT @td Òî÷êà (X,Y) îïðåäåëÿåò ëåâóþ ñòîðîíó îïèñàííîãî ïðÿìîóãîëüíèêà (òåêñò ëåæèò ïðàâåå ýòîé òî÷êè).
//! @tr TA_RIGHT @td Òî÷êà (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);
//{----------------------------------------------------------------------------------------------------------------
//! @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, "Êîìèê ëè Ñàíñ?");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
LOGFONT* txFontExist (const char name[]);
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ 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
//!
//! @return Äåñêðèïòîð (ñèñòåìíûé íîìåð, âûäàííûé Windows) ñîçäàííîãî õîëñòà (êîíòåêñòà ðèñîâàíèÿ).
//!
//! @warning Ñîçäàííûé êîíòåêñò çàòåì áóäåò íóæíî @b îáÿçàòåëüíî óäàëèòü ïðè ïîìîùè txDeleteDC(). @n
//! <small>When the program will be shutting down, TXLib will try to delete DCs which were not deleted,
//! but this is not guaranteed.</small>
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC()
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Çàãðóæàåò èç ôàéëà èçîáðàæåíèå â ôîðìàòå BMP. Äåëàåò ýòî äîâîëüíî ìåäëåííî.
//!
//! @param filename Èìÿ ôàéëà ñ èçîáðàæåíèåì â ôîðìàòå BMP
//! @param imageFlags Òèï çàãðóæàåìîãî èçîáðàæåíèÿ, ñì. íèæå
//! @param loadFlags Ôëàãè çàãðóçêè èçîáðàæåíèÿ, ñì. íèæå
//!
//! @return Äåñêðèïòîð ñîçäàííîãî êîíòåêñòà ðèñîâàíèÿ â ïàìÿòè, ñ çàãðóæåííûì èçîáðàæåíèåì.
//! Åñëè èçîáðàæåíèå íå çàãðóæåíî (íå íàéäåí ôàéë, íåâåðíûé ôîðìàò ôàéëà è ò.ä.), òî NULL.
//!
//! @warning Èçîáðàæåíèå çàãðóæàåòñÿ â ñîçäàâàåìûé êîíòåêñò ðèñîâàíèÿ â ïàìÿòè ("âèðòóàëüíûé õîëñò"), êîòîðûé çàòåì
//! áóäåò íóæíî <b>îáÿçàòåëüíî óäàëèòü</b> ïðè ïîìîùè txDeleteDC(). @n
//! <small>When the program will be shutting down, TXLib will try to delete DCs which were not deleted,
//! but this is not guaranteed.</small>
//!
//! @note Èçîáðàæåíèÿ ïîääåðæèâàþòñÿ <b>òîëüêî â ôîðìàòå BMP.</b> Åñëè âçÿòü ôàéë äðóãîãî ôîðìàòà, íàïðèìåð JPG,
//! è ïåðåèìåíîâàòü åãî ñî ñìåíîé ðàñøèðåíèÿ íà BMP, òî îò ýòîãî ôîðìàò íå èçìåíèòñÿ. Òàêîå èçîáðàæåíèå
//! çàãðóæåíî íå áóäåò.
//!
//! Åñëè ôóíêöèÿ âåðíóëà NULL, òî íàäî ïðåæäå âñåãî <b>ïðîâåðèòü íàëè÷èå ôàéëà èçîáðàæåíèÿ</b> ïî
//! óêàçàííîìó â ïðîãðàììå ïóòè è ôîðìàò ôàéëà. Åñëè ïóòü ê ôàéëó íå óêàçàí (èëè óêàçàí êàê íåïîëíûé),
//! òî ïóòü îòñ÷èòûâàåòñÿ îò òåêóùåé ïàïêè ïðîãðàììû, êîòîðàÿ ìîæåò íå ñîâïàäàòü òåêóùåé ïàïêîé ñðåäû
//! ïðîãðàììèðîâàíèÿ. Òåêóùóþ ïàïêó ïðîãðàììû ìîæíî ïîñìîòðåòü ïî êîìàíäå About â ñèñòåìíîì ìåíþ
//! (îíà óêàçàíà òàì êàê "Run from").
//!
//! @note <b>Íå íàäî ÷àñòî çàãðóæàòü</b> îäíî è òî æå èçîáðàæåíèå, îñîáåííî â öèêëå. Îò ýòîãî ïðîãðàììà íà÷èíàåò
//! òîðìîçèòü! @n
//! @note Çàãðóçèòå îäèí ðàç @a ïåðåä öèêëîì, ïîòîì èñïîëüçóéòå ìíîãî ðàç. Ïîñìîòðèòå, êàê ýòî ñäåëàíî â ïðèìåðå
//! TX\Examples\Tennis\Tennis.cpp.
//!
//! @title Òèïû èçîáðàæåíèé:
//! @table @tr IMAGE_BITMAP @td Çàãðóæàåò ðèñóíîê â ôîðìàòå BMP
//! @tr IMAGE_CURSOR @td Çàãðóæàåò êóðñîð
//! @tr IMAGE_ICON @td Çàãðóæàåò èêîíêó
//! @endtable
//!
//! @title Ôëàãè çàãðóçêè:
//! @table @tr LR_CREATEDIBSECTION @td Ñîçäàåò DIB (device-indepandent bitmap), óäîáíóþ äëÿ ïðÿìîãî äîñòóïà ê äàííûì
//! @tr LR_LOADFROMFILE @td Çàãðóæàåò èç ôàéëà (åñëè ýòîò ôëàã íå óêàçàí, òî çàãðóæàåò èç ðåñóðñà)
//! @tr Îñòàëüíûå ôëàãè çàãðóçêè @td ñì. íà MSDN.com, ïîèñê "LoadImage function".
//! @endtable
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC(), txBitBlt(), txAlphaBlend(), txTransparentBlt()
//!
//! @usage Ïðèìåð èñïîëüçîâàíèÿ ñì. â ôàéëå TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC background_FromTXLibHelp = txLoadImage ("Resources\\Images\\Background.bmp");
//!
//! if (!background_FromTXLibHelp)
//! txMessageBox ("Íå ìîãó çàãðóçèòü ôîí èç Background.bmp", "Äà, ÿ ñêîïèðîâàë ýòî èç ïðèìåðà");
//!
//! // Íå íàäî ÷àñòî çàãðóæàòü îäíî è òî æå èçîáðàæåíèå, îñîáåííî â öèêëå - ïðîãðàììà áóäåò òîðìîçèòü!
//! // Çàãðóçèòå îäèí ðàç ïåðåä öèêëîì, ïîòîì èñïîëüçóéòå ìíîãî ðàç.
//! // Ïîñìîòðèòå, êàê ñäåëàíî â ïðèìåðå TX\Examples\Tennis\Tennis.cpp.
//!
//! txBitBlt (txDC(), 0, 0, 800, 600, background_FromTXLibHelp, 0, 0);
//!
//! ...
//! txDeleteDC (background_FromTXLibHelp);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
HDC txLoadImage (const char filename[], unsigned imageFlags = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óíè÷òîæàåò õîëñò (êîíòåêñò ðèñîâàíèÿ, DC) â ïàìÿòè.
//!
//! @param dc Êîíòåêñò ðèñîâàíèÿ äëÿ óíè÷òîæåíèÿ. @n
//! Åñëè ïåðåäàí óêàçàòåëü, òî ïîñëå óíè÷òîæåíèÿ ïî óêàçàòåëþ çàïèñûâàåòñÿ NULL.
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @see txCreateWindow(), txCreateCompatibleDC(), txLoadImage(), txDeleteDC()
//!
//! @usage Ïðèìåð èñïîëüçîâàíèÿ ñì. â ôàéëå TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC background_FromTXLibHelp = txLoadImage ("Resources\\Images\\Background.bmp");
//!
//! if (!background_FromTXLibHelp)
//! txMessageBox ("Íå ìîãó çàãðóçèòü ôîí èç Background.bmp, è ÿ ñêîïèðîâàë ýòî èç ïðèìåðà.", "Oh, not now");
//!
//! // Ñì. âàæíûé êîììåíòàðèé â ïðèìåðå ê ôóíêöèè txLoadImage!
//!
//! txBitBlt (txDC(), 0, 0, 800, 600, background_FromTXLibHelp, 0, 0);
//!
//! ...
//! txDeleteDC (background_FromTXLibHelp);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
//@ {
bool txDeleteDC (HDC dc);
//! @cond INTERNAL
bool txDeleteDC (HDC* dc);
//! @endcond
//@ }
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Êîïèðóåò èçîáðàæåíèå ñ îäíîãî õîëñòà (êîíòåêñòà ðèñîâàíèÿ, DC) íà äðóãîé.
//!
//! @param dest Êîíòåêñò íàçíà÷åíèÿ (êóäà êîïèðîâàòü)
//! @param xDest Õ-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-ïðèåìíèêà
//! @param yDest Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-ïðèåìíèêà
//! @param width Øèðèíà êîïèðóåìîãî èçîáðàæåíèÿ
//! @param height Âûñîòà êîïèðóåìîãî èçîáðàæåíèÿ
//! @param src Êîíòåêñò èñòî÷íèêà (îòêóäà êîïèðîâàòü)
//! @param xSrc Õ-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-èñòî÷íèêà
//! @param ySrc Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-èñòî÷íèêà
//! @param rOp Ðàñòðîâàÿ îïåðàöèÿ êîïèðîâàíèÿ
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @warning Åñëè êîíòåêñòû íàçíà÷åíèÿ èëè èñòî÷íèêà ðàâíû NULL, òî îíè íå ñóùåñòâóþò è êîïèðîâàíèå âûçîâåò îøèáêó.
//! Íàèáîëåå ÷àñòàÿ ïðè÷èíà - îøèáêà ïðè çàãðóçêå ôàéëà èçîáðàæåíèÿ è îòñóòñòâèå ïðîâåðêè íà ýòó îøèáêó.
//! Ïðèìåð ñ ïðîâåðêîé íà ïðàâèëüíîñòü çàãðóçêè ñì. íèæå.
//!
//! @title Ðåæèìû êîïèðîâàíèÿ:
//! @table @tr SRCCOPY @td Ïðîñòî êîïèðóåò :) - ñàìûé ðàñïðîñòðàíåííûé ðåæèì
//! @tbr
//! @tr BLACKNESS @td Çàïîëíÿåò õîëñò-ïðèåìíèê ÷åðíûì öâåòîì (õîëñò-èñòî÷íèê èãíîðèðóåòñÿ).
//! @tr WHITENESS @td Çàïîëíÿåò õîëñò-ïðèåìíèê áåëûì öâåòîì (õîëñò-èñòî÷íèê èãíîðèðóåòñÿ).
//! @tr DSTINVERT @td Èíâåðòèðóåò öâåòà íà õîëñòå-ïðèåìíèêå (õîëñò-èñòî÷íèê èãíîðèðóåòñÿ).
//! @tr PATCOPY @td Êîïèðóåò öâåò òåêóùåé êèñòè õîëñòà-ïðèåìíèêà.
//! @tbr
//! @tr MERGECOPY @td Ïðèåìíèê = ïðèåìíèê & öâåò òåêóùåé êèñòè èñòî÷íèêà.
//! @tr MERGEPAINT @td Ïðèåìíèê = ~ ïðèåìíèê | èñòî÷íèê
//! @tr NOTSRCCOPY @td Ïðèåìíèê = ~ èñòî÷íèê
//! @tr NOTSRCERASE @td Ïðèåìíèê = ~ (ïðèåìíèê | èñòî÷íèê)
//! @tr PATINVERT @td Ïðèåìíèê = êèñòü ïðèåìíèêà ^ ïðèåìíèê
//! @tr PATPAINT @td Ïðèåìíèê = (êèñòü ïðèåìíèêà | ~èñòî÷íèê) | ïðèåìíèê
//! @tr SRCAND @td Ïðèåìíèê = ïðèåìíèê & èñòî÷íèê
//! @tr SRCERASE @td Ïðèåìíèê = ~ïðèåìíèê & èñòî÷íèê
//! @tr SRCINVERT @td Ïðèåìíèê = ïðèåìíèê ^ èñòî÷íèê
//! @tr SRCPAINT @td Ïðèåìíèê = ïðèåìíèê | èñòî÷íèê
//! @endtable
//!
//! @see txAlphaBlend(), txTransparentBlt(), txSetColor(), txGetColor(), txSetFillColor(), txGetFillColor(), txColors, RGB()
//!
//! @usage Ïðèìåð èñïîëüçîâàíèÿ ñì. â ôàéëå TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC background_FromTXLibHelp = txLoadImage ("Resources\\Images\\Background.bmp");
//!
//! if (!background_FromTXLibHelp)
//! ("Íå ìîãó ôîí èç çàãðóçèòü Background.bmp, è äà, ÿ âçÿë ýòîò êîä èç ïðèìåðà.", "Once again :(");
//!
//! // Ñì. âàæíûé êîììåíòàðèé â ïðèìåðå ê ôóíêöèè txLoadImage!
//!
//! txBitBlt (txDC(), 0, 0, 800, 600, background_FromTXLibHelp, 0, 0);
//!
//! ...
//! txDeleteDC (background_FromTXLibHelp);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txBitBlt (HDC dest, double xDest, double yDest, double width, double height,
HDC src, double xSrc = 0, double ySrc = 0, DWORD rOp = SRCCOPY);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Êîïèðóåò èçîáðàæåíèå ñ îäíîãî õîëñòà (êîíòåêñòà ðèñîâàíèÿ, DC) íà äðóãîé
//! ñ ó÷åòîì ïðîçðà÷íîñòè.
//!
//! @param dest Êîíòåêñò íàçíà÷åíèÿ (êóäà êîïèðîâàòü)
//! @param xDest Õ-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-ïðèåìíèêà
//! @param yDest Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-ïðèåìíèêà
//! @param width Øèðèíà êîïèðóåìîãî èçîáðàæåíèÿ, íåîòðèöàòåëüíàÿ
//! @param height Âûñîòà êîïèðóåìîãî èçîáðàæåíèÿ, íåîòðèöàòåëüíàÿ
//! @param src Êîíòåêñò èñòî÷íèêà (îòêóäà êîïèðîâàòü)
//! @param xSrc Õ-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-èñòî÷íèêà
//! @param ySrc Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-èñòî÷íèêà
//! @param transColor Öâåò, êîòîðûé áóäåò ñ÷èòàòüñÿ ïðîçðà÷íûì
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @warning Åñëè êîíòåêñòû íàçíà÷åíèÿ èëè èñòî÷íèêà ðàâíû NULL, òî îíè íå ñóùåñòâóþò è êîïèðîâàíèå âûçîâåò îøèáêó.
//! Íàèáîëåå ÷àñòàÿ ïðè÷èíà - îøèáêà ïðè çàãðóçêå ôàéëà èçîáðàæåíèÿ è îòñóòñòâèå ïðîâåðêè íà ýòó îøèáêó.
//! Ïðèìåð ñ ïðîâåðêîé íà ïðàâèëüíîñòü çàãðóçêè ñì. íèæå.
//!
//! Ñòàíäàðòíàÿ ôóíêöèÿ 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, îíà âîîáùå ëó÷øå.
//!
//! @see txBitBlt(), txTransparentBlt(), txLoadImage(), txCreateCompatibleDC()
//!
//! @usage Ïðèìåð èñïîëüçîâàíèÿ ñì. â ôàéëå TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC superman_FromTXLibHelp = txLoadImage ("Resources\\Images\\Superman.bmp");
//!
//! if (!superman_FromTXLibHelp)
//! txMessageBox ("Cannot load superman, all the monsters will succeed (I copied them from TXLib Help)", "Sorry");
//!
//! // Ñì. âàæíûé êîììåíòàðèé â ïðèìåðå ê ôóíêöèè txLoadImage!
//!
//! txTransparentBlt (txDC(), 0, 0, 800, 600, superman_FromTXLibHelp, 0, 0);
//!
//! // À ìîæíî è òàê:
//! Win32::TransparentBlt (txDC(), 0, 0, 800, 600, superman_FromTXLibHelp, 0, 0, 80, 60, -1); // 10-êðàòíîå óâåëè÷åíèå
//! // Ïîçíàé ìîùü Win32 GDI, îòêàçàâøèñü îò TXLib'à! :) ñì. TransparentBlt â MSDN.com.
//!
//! ...
//! txDeleteDC (superman_FromTXLibHelp); // So pity :( But he was only a copy from TXLib Help.
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txTransparentBlt (HDC dest, double xDest, double yDest, double width, double height,
HDC src, double xSrc = 0, double ySrc = 0, COLORREF transColor = TX_BLACK);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Êîïèðóåò èçîáðàæåíèå ñ îäíîãî õîëñòà (êîíòåêñòà ðèñîâàíèÿ, DC) íà äðóãîé
//! ñ ó÷åòîì ïðîçðà÷íîñòè.
//!
//! @param dest Êîíòåêñò íàçíà÷åíèÿ (êóäà êîïèðîâàòü)
//! @param xDest Õ-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-ïðèåìíèêà
//! @param yDest Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-ïðèåìíèêà
//! @param width Øèðèíà êîïèðóåìîãî èçîáðàæåíèÿ, íåîòðèöàòåëüíàÿ
//! @param height Âûñîòà êîïèðóåìîãî èçîáðàæåíèÿ, íåîòðèöàòåëüíàÿ
//! @param src Êîíòåêñò èñòî÷íèêà (îòêóäà êîïèðîâàòü). Äîëæåí èìåòü 32-áèòîâûé ôîðìàò è àëüôà-êàíàë (ñì. íèæå).
//! @param xSrc Õ-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-èñòî÷íèêà, äîëæíà áûòü â ïðåäåëàõ ðàçìåðà èñòî÷íèêà.
//! @param ySrc Y-êîîðäèíàòà âåðõíåãî ëåâîãî óãëà èçîáðàæåíèÿ-èñòî÷íèêà, äîëæíà áûòü â ïðåäåëàõ ðàçìåðà èñòî÷íèêà.
//! @param alpha Îáùàÿ ïðîçðà÷íîñòü èçîáðàæåíèÿ, â äîïîëíåíèå ê àëüôà-êàíàëó (0 - âñå ïðîçðà÷íî, 1 - èñïîëüçîâàòü òîëüêî àëüôà-êàíàë).
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @warning Åñëè êîíòåêñòû íàçíà÷åíèÿ èëè èñòî÷íèêà ðàâíû NULL, òî îíè íå ñóùåñòâóþò è êîïèðîâàíèå âûçîâåò îøèáêó.
//! Íàèáîëåå ÷àñòàÿ ïðè÷èíà - îøèáêà ïðè çàãðóçêå ôàéëà èçîáðàæåíèÿ è îòñóòñòâèå ïðîâåðêè íà ýòó îøèáêó.
//! Ïðèìåð ñ ïðîâåðêîé íà ïðàâèëüíîñòü çàãðóçêè ñì. íèæå.
//!
//! Èçîáðàæåíèå-èñòî÷íèê è èçîáðàæåíèå-ïðèåìíèê íå ìîãóò íàëàãàòüñÿ äðóã íà äðóãà.
//!
//! @note Èçîáðàæåíèå äîëæíî áûòü çàãðóæåíî ñ ïîìîùüþ txLoadImage() è èìåòü <b>32-áèòîâûé RGBA-ôîðìàò.</b>
//! Äîïîëíèòåëüíûé êàíàë <b>(A, àëüôà-êàíàë)</b> ýòîãî ôîðìàòà îòâå÷àåò çà ïðîçðà÷íîñòü ó÷àñòêîâ
//! èçîáðàæåíèÿ. 24-áèòîâûé ôîðìàò (TrueColor RGB) ôóíêöèÿ txAlphaBlend íå ïîääåðæèâàåò.
//!
//! Àëüôà-êàíàë ìîæíî ñäåëàòü, íàïðèìåð, â Adobe Photoshop, êîìàíäîé "Íîâûé êàíàë (New Channel)" â ïàëèòðå
//! êàíàëîâ (Channels). ×åðíûé öâåò â àëüôà-êàíàëå ñîîòâåòñòâóåò ïîëíîé ïðîçðà÷íîñòè, áåëûé - ïîëíîé
//! íåïðîçðà÷íîñòè. <b>Ïðè ýòîì â ïðîçðà÷íûõ îáëàñòÿõ ñàìî èçîáðàæåíèå (â êàíàëàõ R, G, B) äîëæíî áûòü
//! ÷åðíûì, è ÷åì ïðîçðà÷íåå, òåì ÷åðíåå.</b> Ñì. èçîáðàæåíèå ñ àëüôà-êàíàëîì â ïðèìåðå
//! TX\Examples\Tennis\Tennis.cpp (ôàéë ñ òåííèñíîé ðàêåòêîé: TX\Examples\Tennis\Resources\Images\Racket.bmp).
//!
//! Ñòðîãî ãîâîðÿ, íàäî äîìíîæèòü êàíàëû R,G,B íà àëüôà-êàíàë: <tt>R,G,B *= A</tt>. Ïîëó÷èòñÿ âîò ÷òî:
//!
//! - Åñëè çíà÷åíèå àëüôà-êàíàëà äëÿ íåêîòîðîãî ïèêñåëÿ ðàâíî 0 (ïîëíàÿ ïðîçðà÷íîñòü), òîãäà çíà÷åíèÿ
//! êàíàëîâ R,G,B äëÿ ýòîãî ïèêñåëÿ òàêæå ñòàíóò 0 (ýòî ÷åðíûé öâåò).
//! - Åñëè çíà÷åíèå àëüôà-êàíàëà äëÿ íåêîòîðîãî ïèêñåëÿ ðàâíî 255 (ïîëíàÿ íåïðîçðà÷íîñòü), òîãäà çíà÷åíèÿ
//! êàíàëîâ R,G,B äëÿ ýòîãî ïèêñåëÿ íå èçìåíÿòñÿ.
//! - Äëÿ äðóãèõ çíà÷åíèé àëüôà-êàíàëà, ïèêñåëè èçîáðàæåíèÿ ñòàíóò òåìíåå.
//!
//! Â Photoshop ýòî ìîæíî ñäåëàòü êîìàíäîé <b>Image @d Apply Image</b> ñ ïàðàìåòðàìè:
//! @table @tr Source: @td <i>Èìÿ ôàéëà ñ êàðòèíêîé</i>
//! @tr Layer: @td Background
//! @tr @b Channel: @td <b> Alpha 1</b>
//! @tr Blending: @td Multiply
//! @tr Opacity: @td 100%
//! @endtable
//!
//! @note Ñòàíäàðòíàÿ ôóíêöèÿ AlphaBlend èç Win32 API ìîæåò ìàñøòàáèðîâàòü èçîáðàæåíèå. Â txAlphaBlend ýòî
//! óáðàíî äëÿ óïðîùåíèÿ èñïîëüçîâàíèÿ. If you still need image scaling, use original function AlphaBlend
//! and don't mess with stupid TX-based tools. (See implementation of txAlphaBlend in TXLib.h).
//!
//! @see txBitBlt(), txTransparentBlt(), txLoadImage(), txCreateCompatibleDC()
//!
//! @usage Ïðèìåð èñïîëüçîâàíèÿ ñì. â ôàéëå TX\Examples\Tennis\Tennis.cpp.
//! @code
//! HDC batman_FromTXLibHelp = txLoadImage ("Resources\\Images\\Batman.bmp");
//!
//! if (!batman_FromTXLibHelp)
//! txMessageBox ("Call to Batman failed because I copied it from TXLib Help", "Do save yourself");
//!
//! // Ñì. âàæíûé êîììåíòàðèé â ïðèìåðå ê ôóíêöèè txLoadImage!
//!
//! txAlphaBlend (txDC(), 0, 0, 800, 600, batman_FromTXLibHelp, 0, 0);
//!
//! ...
//! txDeleteDC (batman_FromTXLibHelp); // Don't worry, batman will return in "Batman returns" movie, later...
//! ...
//!
//! return batman_FromTXLibHelp; // ...and there he comes -- in TXLib copy form
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txAlphaBlend (HDC dest, double xDest, double yDest, double width, double height,
HDC src, double xSrc = 0, double ySrc = 0, double alpha = 1.0);
//! @}
//}
//=================================================================================================================
//{ Utility functions
//! @name Âñïîìîãàòåëüíûå ôóíêöèè
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Çàäåðæèâàåò âûïîëíåíèå ïðîãðàììû íà îïðåäåëåííîå âðåìÿ.
//!
//! @param time Çàäåðæêà â ìèëëèñåêóíäàõ.
//!
//! @return Çàäåðæêà â ìèëëèñåêóíäàõ, ïðîèçîøåäøàÿ â äåéñòâèòåëüíîñòè.
//!
//! @note <b>Ïåðåä íà÷àëîì çàäåðæêè èçîáðàæåíèå â îêíå îáÿçàòåëüíî îáíîâèòñÿ,</b> äàæå åñëè ðèñîâàíèå
//! çàáëîêèðîâàíî ÷åðåç txBegin().
//!
//! @see txBegin(), txEnd(), txUpdateWindow()
//!
//! @usage @code
//! txSleep (500); // ÏÏ: Ïîñïàòü Ïîëñåêóíäû
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
double txSleep (double time);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Áëîêèðóåò îáíîâëåíèå èçîáðàæåíèÿ îêíà, âî èçáåæàíèå ìèãàíèÿ.
//!
//! Äëÿ ñíÿòèÿ áëîêèðîâêè èñïîëüçóåòñÿ ôóíêöèÿ txEnd().
//!
//! Åñëè â ïðîãðàììå òðåáóåòñÿ çàäåðæêà, òî èñïîëüçóéòå ôóíêöèþ txSleep(), òàê êàê îíà àâòîìàòè÷åñêè
//! îáíîâëÿåò èçîáðàæåíèå, íåçàâèñèìî îò ñîñòîÿíèÿ áëîêèðîâêè.
//!
//! @warning Èçáåãàéòå áëîêèðîâàíèÿ íà äîëãîå âðåìÿ. Ýòî ìîæåò ïðèâåñòè ê äåôåêòàì èçîáðàæåíèÿ â îêíå.
//!
//! @note Åñëè íàæàòà êëàâèøà Alt+PrintScreen, òî áëîêèðîâêà âðåìåííî îòìåíÿåòñÿ.
//!
//! @return Çíà÷åíèå ñ÷åò÷èêà áëîêèðîâêè (åñëè 0, òî ðèñîâàíèå ðàçáëîêèðîâàíî).
//!
//! @see txEnd(), txSleep(), txUpdateWindow(), txTextCursor()
//!
//! @usage @code
//! txBegin(); // Çäåñü èçîáðàæåíèå "çàìåðçíåò"
//! txSetFillColor (TX_WHITE);
//! txClear(); // Ýòî âûçâàëî áû ìèãàíèå áåç txBegin()
//! txSetFillColor (TX_RED);
//! txRectangle (100, 100, 200, 200);
//! txEnd(); // Çäåñü ìû ñðàçó óâèäèì îêîí÷àòåëüíûé ðèñóíîê
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txBegin();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ðàçáëîêèðóåò îáíîâëåíèå îêíà, çàáëîêèðîâàííîå ôóíêöèåé txBegin().
//!
//! @warning Åñëè txBegin() âûçûâàëàñü íåñêîëüêî ðàç, òî äëÿ ñíÿòèÿ áëîêèðîâêè òðåáóåòñÿ ñòîëüêî æå ðàç âûçâàòü
//! txEnd().
//!
//! @note Åñëè íàæàòà êëàâèøà Alt+PrintScreen, òî áëîêèðîâêà âðåìåííî îòìåíÿåòñÿ.
//!
//! @return Çíà÷åíèå ñ÷åò÷èêà áëîêèðîâêè (åñëè 0, òî ðèñîâàíèå ðàçáëîêèðîâàíî).
//!
//! @see txBegin(), txSleep(), txUpdateWindow(), txTextCursor()
//!
//! @usage @code
//! txBegin(); // Çäåñü èçîáðàæåíèå "çàìåðçíåò"
//! txSetFillColor (TX_WHITE);
//! txClear(); // Ýòî âûçâàëî áû ìèãàíèå áåç txBegin()
//! txSetFillColor (TX_RED);
//! txRectangle (100, 100, 200, 200);
//! txEnd(); // Çäåñü ìû ñðàçó óâèäèì îêîí÷àòåëüíûé ðèñóíîê
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txEnd();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Ðàçðåøàåò èëè çàïðåùàåò àâòîìàòè÷åñêîå îáíîâëåíèå èçîáðàæåíèÿ â îêíå.
//!
//! @param update Ðåæèì îáíîâëåíèÿ (true - ðàçðåøèòü, false - çàïðåòèòü).
//!
//! @return Ïðåäûäóùåå ñîñòîÿíèå ðåæèìà îáíîâëåíèÿ.
//!
//!  îòëè÷èå îò txBegin() è txEnd(), êîòîðûå ïîääåðæèâàþò âëîæåííûå âûçîâû è ðàáîòàþò êàê "ñêîáêè äëÿ
//! çàìåðçàíèÿ êàðòèíêè", txUpdateWindow() ïîçâîëÿåò ÿâíî óñòàíîâèòü èëè ñíÿòü áëîêèðîâêó àâòîìàòè÷åñêîãî
//! îáíîâëåíèÿ.
//!
//! Áîëåå ïîëíóþ èíôîðìàöèþ î áëîêèðîâêå ñì. â ôóíêöèÿõ txBegin(), txEnd() è txSleep().
//!
//! @see txBegin(), txEnd(), txSleep(), txUpdateWindow(), txTextCursor(), txLock(), txUnlock(), txGDI()
//!
//! @usage @code
//! txUpdateWindow (false);
//! ...
//! txUpdateWindow();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txUpdateWindow (int update = true);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Óñòàíàâëèâàåò òåêóùèé îáúåêò GDI.
//!
//! @param obj Äåñêðèïòîð îáúåêòà GDI
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @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 Óíè÷òîæàåò îêíî TXLib.
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @warning Åñëè óíè÷òîæàåòñÿ ãëàâíîå îêíî TXLib, ôóíêöèÿ main() ïðåðûâàåòñÿ è ïðîãðàììà àâòîìàòè÷åñêè çàâåðøàåòñÿ.
//! Ïðè ýòîì @b íå ãàðàíòèðóåòñÿ ïðàâèëüíîå çàâåðøåíèå ïðîãðàììû, ïîýòîìó òàê äåëàòü @b íå ðåêîìåíäóåòñÿ.
//!
//! @see txCreateWindow()
//!
//! @usage @code
//! txDestroyWindow(); // Farewell to the world
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txDestroyWindow();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Îöåíèâàåò ñêîðîñòü ðàáîòû êîìïüþòåðà.
//!
//! @return Ñêîðîñòü ðàáîòû (ãðàôè÷åñêèõ îïåðàöèé) â óñëîâíûõ åäèíèöàõ.
//!
//! @see txSleep()
//!
//! @usage @code
//! if (txQueryPerformance() < 1) printf ("Õî÷åòñÿ íîâûé êîìïüþòåð");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
double txQueryPerformance();
//! @}
//}
//=================================================================================================================
//{ Mouse functions
//! @name Ðàáîòà ñ ìûøüþ
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Âîçâðàùàåò ïîçèöèþ Ìûøè!
//!
//! @return Ïîçèöèÿ ìûøè êàê ñòðóêòóðà POINT.
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! RECT area = { 100, 100, 110, 110 };
//!
//! while (txMouseButtons() != 1)
//! {
//! if (In (txMousePos(), area)) txTextOut (100, 100, "What are you doing here?!");
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline POINT txMousePos();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Âîçâðàùàåò Õ-Êîîðäèíàòó Ìûøè!
//!
//! @return Õ-êîîðäèíàòà ìûøè.
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! while (txMouseButtons() != 1)
//! {
//! txCircle (txMouseX(), txMouseY(), 20);
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txMouseX();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Âîçâðàùàåò Y-Êîîðäèíàòó Ìûøè!
//!
//! @return Y-êîîðäèíàòà ìûøè.
//!
//! @see txMouseX(), txMouseY(), txMousePos(), txMouseButtons()
//!
//! @usage @code
//! while (txMouseButtons() != 1)
//! {
//! txCircle (txMouseX(), txMouseY(), 20);
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txMouseY();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Mouse
//! @brief Âîçâðàùàåò ñîñòîÿíèå Êíîïîê Ìûøè!
//!
//! @return Ñîñòîÿíèå Êíîïîê Ìûøè!
//!
//!  âîçâðàùàåìîì çíà÷åíèè âûñòàâëåííûé â åäèíèöó 1-é (ìëàäøèé) áèò îçíà÷àåò íàæàòóþ ëåâóþ Êíîïêó Ìûøè,
//! 2-é - ïðàâóþ. @n
//! Íàïðèìåð, âîçâðàùåííîå ÷èñëî 3 (äâîè÷íîå 11) îçíà÷àåò îäíîâðåìåííîå íàæàòèå ëåâîé è ïðàâîé Êíîïîê.
//!
//! @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);
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
inline int txMouseButtons();
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Console functions
//! @name Ôóíêöèè êîíñîëè
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Óñòàíàâëèâàåò öâåòîâûå àòðèáóòû êîíñîëè.
//!
//! @param colors Öâåòîâûå àòðèáóòû êîíñîëè.
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @b Àòðèáóòû - ýòî öâåò òåêñòà (colorText) è öâåò ôîíà (colorBackground), îáúåäèíåííûå âìåñòå: @nn
//! <tt>colors = colorText + colorBackground * 16</tt> @nn
//! ëèáî @nn
//! <tt>colors = colorText | (colorBackground \<\< 4)</tt> @nn
//! Öâåòà àòðèáóòîâ @b íå èìåþò íèêàêîãî îòíîøåíèÿ ê öâåòàì ðèñîâàíèÿ, çàäàâàåìûìè @ref txColors "TX_..."
//! êîíñòàíòàìè, RGB(), txSetColor(), txColor(), txSetFillColor(), txFillColor() è ò.ä. Çíà÷åíèÿ öâåòîâ
//! ñì. íèæå.
//!
//! @title Çíà÷åíèÿ öâåòîâ àòðèáóòîâ
//! @table @tr Dec @td @c Hex @td @td Dec @td @c Hex @td
//! @tbr
//! @tr 0 = @td @c 0x0 @td = ×åðíûé, @td 8 = @td @c 0x8 @td = Òåìíî-ñåðûé,
//! @tr 1 = @td @c 0x1 @td = Ñèíèé, @td 9 = @td @c 0x9 @td = Ñâåòëî-ñèíèé,
//! @tr 2 = @td @c 0x2 @td = Çåëåíûé, @td 10 = @td @c 0xA @td = Ñâåòëî-çåëåíûé,
//! @tr 3 = @td @c 0x3 @td = Ñèíå-çåëåíûé, @td 11 = @td @c 0xB @td = Ñâåòëî-ñèíå-çåëåíûé,
//! @tr 4 = @td @c 0x4 @td = Êðàñíûé, @td 12 = @td @c 0xC @td = Ñâåòëî-êðàñíûé,
//! @tr 5 = @td @c 0x5 @td = Ìàëèíîâûé, @td 13 = @td @c 0xD @td = Ñâåòëî-ìàëèíîâûé,
//! @tr 6 = @td @c 0x6 @td = Òåìíî-æåëòûé, @td 14 = @td @c 0xE @td = Æåëòûé,
//! @tr 7 = @td @c 0x7 @td = Ñåðûé, @td 15 = @td @c 0xF @td = Áåëûé.
//! @endtable
//!
//!  øåñòíàäöàòèðè÷íîé ñèñòåìå ñ÷èñëåíèÿ àòðèáóòû çàäàâàòü ìîæíî ïðîùå: åñëè íóæåí, ñêàæåì, æåëòûé öâåò
//! íà ñèíåì ôîíå, òî åãî êîä áóäåò @c 0x1e (ñòàðøàÿ öèôðà - ñòàðøèå 4 áèòà - ýòî öâåò ôîíà, ìëàäøàÿ
//! öèôðà - ìëàäøèå 4 áèòà - ýòî öâåò òåêñòà).
//!
//! @see txTextCursor(), txGetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleCursorPos(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! txSetConsoleAttr (0x1E);
//! printf ("À â íåáå 0x1 åñòü ãîðîä 0xE"); // (c) Á. Ãðåáåíùèêîâ
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txSetConsoleAttr (unsigned colors = 0x07);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò òåêóùèå öâåòîâûå àòðèáóòû êîíñîëè.
//!
//! @return Òåêóùèå öâåòîâûå àòðèáóòû êîíñîëè. Ñì. txSetConsoleAttr().
//!
//! @see txTextCursor(), txSetConsoleAttr(), txSetConsoleCursorPos(), txGetConsoleCursorPos(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! unsigned attr = txGetConsoleAttr();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned txGetConsoleAttr();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Ñòèðàåò òåêñò êîíñîëè.
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! Ïðè ñòèðàíèè èñïîëüçóþòñÿ òåêóùèå àòðèáóòû (öâåòà òåêñòà è ôîíà) êîíñîëè.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txGetConsoleCursorPos(),
//! 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(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! txSetConsoleCursorPos (txGetExtentX(), txGetExtentY()); // Öåíòð Âñåëåííîé
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txSetConsoleCursorPos (double x, double y);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò ïîçèöèþ ìèãàþùåãî êóðñîðà êîíñîëè.
//!
//! @return Ïîëîæåíèå ìèãàþùåãî êóðñîðà â ñòðóêòóðå POINT.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txSetConsoleCursorPos(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! POINT pos = txGetConsoleCursorPos();
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleCursorPos();
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Drawing
//! @brief Âîçâðàùàåò ðàçìåðû øðèôòà êîíñîëè.
//!
//! @return Ðàçìåðû øðèôòà êîíñîëè â ïèêñåëÿõ, â ñòðóêòóðå POINT.
//!
//! @see txTextCursor(), txSetConsoleAttr(), txGetConsoleAttr(), txSetConsoleCursorPos(),
//! txGetConsoleFontSize(), txClearConsole()
//!
//! @usage @code
//! POINT size = txGetConsoleFontSize();
//! txSetConsoleCursorPos (5 * size.x, 10 * size.y); // À òåïåðü ìèãàé òàì
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleFontSize();
//{----------------------------------------------------------------------------------------------------------------
//! @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 Ðåæèì âîñïðîèçâåäåíèÿ
//!
//! @return Åñëè îïåðàöèÿ áûëà óñïåøíà - true, èíà÷å - false.
//!
//! @title Ðåæèìû âîñïðîèçâåäåíèÿ: @table
//! @tr SND_ASYNC @td Çâóê ïðîèãðûâàåòñÿ îäíîâðåìåííî ñ ðàáîòîé ïðîãðàììû. @n
//! ×òîáû îòìåíèòü çâó÷àíèå, âûçîâèòå txPlaySound (NULL).
//! @tr SND_SYNC @td Âûïîëíåíèå ïðîãðàììû ïðèîñòàíàâëèâàåòñÿ äî îêîí÷àíèÿ âîñïðîèçâåäåíèÿ çâóêà.
//! @tr SND_LOOP @td Çàöèêëèâàòü çâóê ïðè âîñïðîèçâåäåíèè. @n
//! ×òîáû îòìåíèòü çâó÷àíèå, âûçîâèòå txPlaySound (NULL).
//! @tbr
//! @tr SND_NODEFAULT @td Íå èñïîëüçîâàòü çâóê ïî óìîë÷àíèþ, åñëè íåëüçÿ ïðîèãðàòü óêàçàííûé çâóêîâîé ôàéë.
//! @tr SND_NOSTOP @td Åñëè êàêîé-ëèáî çâóê óæå ïðîèãðûâàåòñÿ, íå îñòàíàâëèâàòü åãî äëÿ çàïóñêà óêàçàííîãî çâóêà.
//! @tr SND_APPLICATION @td Ïðîèãðûâàòü çâóê, èñïîëüçóÿ ïðîãðàììó, çàðåãèñòðèðîâàííóþ äëÿ äàííîãî òèïà çâóêîâûõ ôàéëîâ.
//! @endtable
//!
//! @note Ïîääåðæèâàþòñÿ òîëüêî ôàéëû â ôîðìàòå WAV. Îñòàëüíûå ôîðìàòû (MP3 è äð.) íàäî ïåðåêîäèðîâàòü.
//! Ïåðåèìåíîâàíèå ñî ñìåíîé ðàñøèðåíèÿ íå ïîìîæåò, êàê è â ñëó÷àå ñ ôîðìàòîì êàðòèíîê â txLoadImage().
//!
//! @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 Âûâîäèò ñîîáùåíèå â îêíå ñ ïîìîùüþ ôóíêöèè MessageBox.
//!
//! @param text Òåêñò ñîîáùåíèÿ
//! @param header Çàãîëîâîê ñîîáùåíèÿ
//! @param flags Ôëàãè îòîáðàæåíèÿ ñîîáùåíèÿ
//!
//! @return Çíà÷åíèå, âîçâðàùàåìîå ôóíêöèåé MessageBox.
//!
//! @warning Òåêñò íå äîëæåí ïðåâûøàòü _TX_BIGBUFSIZE ñèìâîëîâ, à çàãîëîâîê @d _TX_BIGBUFSIZE ñèìâîëîâ, èíà÷å îíè
//! îáðåçàþòñÿ.
//!
//! @note Âìåñòî <tt><b>txMessageBox (text, header, flags)</b></tt> ìîæíî èñïîëüçîâàòü ñòàíäàðòíóþ ôóíêöèþ Win32
//! <tt><b>MessageBox (txWindow(), text, header, flags)</b></tt>. Îòëè÷èÿ txMessageBox â òîì, ÷òî îíà
//! àâòîìàòè÷åñêè ïîäñòàâëÿåò îêíî-ðîäèòåëü, è â òîì, ÷òî ïðè âûâîäå â îêíî ñòðî÷êè ïåðåâîäÿòñÿ â ôîðìàò
//! UNICODE. Ýòî âàæíî ëèøü â òîì ñëó÷àå, êîãäà <i>â ðåãèîíàëüíûõ íàñòðîéêàõ êîíòðîëüíîé ïàíåëè Windows
//! íåâåðíî óñòàíîâëåíà êîäîâàÿ ñòðàíèöà äëÿ ïðîãðàìì, íå ïîääåðæèâàþùèõ UNICODE.</i>  îñòàëüíûõ ñëó÷àÿõ
//! íóæäû â @c txMessageBox íåò.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txNotifyIcon()
//!
//! @usage @code
//! if (txMessageBox ("Ïîëó÷èëîñü?", "Ïðî÷òè ìåíÿ", MB_YESNO) == IDYES)
//! {
//! MessageBox (txWindow(), "Õâàòèò è îáû÷íîãî MessageBox()", "Win32 ñîîáùàåò", 0);
//! }
//! else
//! txMessageBox ("Ñïàñàåì îò êðàêîçÿáë âìåñòî ðóññêèõ áóêâ. Ãàðàíòèÿ. Íåäîðîãî.");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned txMessageBox (const char* text, const char* header = "TXLib ñîîáùàåò", unsigned flags = 0);
//{----------------------------------------------------------------------------------------------------------------
//! @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. Äëÿ ýòîãî íàäî ëèáî <b>âêëþ÷èòü TXLib.h âìåñòî @c windows.h èëè ïåðåä íèì.</b>
//! Ëèáî íàäî ñàìîñòîÿòåëüíî îïðåäåëèòü @c (\#define) ýòó êîíñòàíòó.
//! <small>Ñ âåðñèåé Internet Explorer ýòî ñâÿçàíî ïîòîìó, ÷òî ïðè åãî óñòàíîâêå â Windows îáíîâëÿþòñÿ
//! ìíîãèå êîìïîíåíòû (íàïðèìåð, @c shell32.dll è @c comctl32.dll), êîòîðûå âëèÿþò íà ôóíêöèîíàëüíîñòü
//! ñèñòåìû íåçàâèñèìî îò èñïîëüçîâàíèÿ áðàóçåðà). Ñàì Internet Explorer â îòîáðàæåíèè ñîîáùåíèÿ
//! íå ó÷àñòâóåò.</small>
//! - Ñîîáùåíèå íå äîëæíî ïðåâûøàòü _TX_BUFSIZE ñèìâîëîâ, èíà÷å îíî îáðåçàåòñÿ.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox()
//!
//! @usage @code
//! int hours = 3, minutes = 10;
//! const char station[] = "Þìó";
//! ...
//! txNotifyIcon (NIIF_INFO, "Óâàæàåìûå ïàññàæèðû",
//! "Ïîåçä íà %s îòïðàâëÿåòñÿ â %d:%d.", station, hours, minutes);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) _TX_CHECK_FORMAT (3);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Âûâîäèò ñîîáùåíèå â îòëàä÷èêå.
//!
//! @param format Ñòðîêà äëÿ ïå÷àòè, êàê â printf().
//!
//! @return Êîëè÷åñòâî íàïå÷àòàííûõ ñèìâîëîâ.
//!
//! Ôóíêöèÿ ôîðìèðóåò ñîîáùåíèå ïî ïðàâèëàì printf() è ïåðåäàåò åãî â OutputDebugString(). Åå âûâîä ìîæíî
//! ïåðåõâàòèòü îòëàä÷èêîì èëè óòèëèòàìè-ëîããåðàìè, íàïðèìåð,
//! <a href=http://technet.microsoft.com/ru-ru/sysinternals/bb896647%28en-us%29.aspx>DbgView</a>.
//! Åñëè ýòîãî íå ñäåëàòü, è íå çàäàòü ïåðâûé ñèìâîë @c '\\a' (ñì. íèæå), òî î ñîîáùåíèè íèêòî íå óçíàåò. :(
//! @note
//! - Åñëè ïåðâûé ñèìâîë â ñòðîêå @c '\\a', òî ñîîáùåíèå òàêæå äóáëèðóåòñÿ txMessageBox().
//! - Åñëè ïåðâûé èëè âòîðîé ñèìâîë â ñòðîêå @c '\\f', òî ñîîáùåíèå òàêæå äóáëèðóåòñÿ printf().
//!
//! @warning Ñîîáùåíèå íå äîëæíî ïðåâûøàòü _TX_BIGBUFSIZE ñèìâîëîâ, èíà÷å îíî îáðåçàåòñÿ.
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR(), txNotifyIcon(), txMessageBox()
//!
//! @usage @code
//! int x = 42;
//! ...
//! txOutputDebugPrintf ("Íèêòî íå óçíàåò, ÷òî %d.", x);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
int txOutputDebugPrintf (const char format[], ...) _TX_CHECK_FORMAT (1);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Âû÷èñëåíèå ðàçìåðà ìàññèâà â ýëåìåíòàõ
//!
//! @param arr Èìÿ ìàññèâà
//!
//! @return Ðàçìåð ìàññèâà â ýëåìåíòàõ (íå â áàéòàõ).
//!
//! Ìàêðîñ sizearr() âû÷èñëÿåò ðàçìåð ìàññèâà â ýëåìåíòàõ, ïðîâåðÿÿ, ìîæíî ëè åãî ïðàâèëüíî âû÷èñëèòü ïðè
//! êîìïèëÿöèè.
//!
//! Ìàêðîñ SIZEARR() ïðîñòî äåëèò ðàçìåð âñåãî ìàññèâà â áàéòàõ íà ðàçìåð åãî ýëåìåíòà, ïîëó÷àåòñÿ ðàçìåð
//! ìàññèâà â ýëåìåíòàõ.
//! Îí <b>íå ïðîâåðÿåò,</b> ìîæíî ëè åãî ïðàâèëüíî âû÷èñëèòü, è ïðè íåïðàâèëüíîì èñïîëüçîâàíèè ìîæåò
//! âûäàòü <b>íåâåðíûé ðàçìåð.</b>
//!
//! @warning SIZEARR() âûäàåò íåâåðíûé ðàçìåð, åñëè îïðåäåëåíèå ìàññèâà âìåñòå ñ åãî ðàçìåðîì, èçâåñòíûì ïðè
//! êîìïèëÿöèè, íåäîñòóïíî â ìåñòå èñïîëüçîâàíèÿ SIZEARR(). Ñì. ïðèìåð íèæå.
//!
//! @note  Microsoft Visual Studio 6 ìàêðîñ 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, òàê ÷òî âñå ïðîñòî.
//!
//! 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 <int size>
//! 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
//}----------------------------------------------------------------------------------------------------------------
//! @{
#ifndef _MSC_VER_6
#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 <typename T, int N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N]; // ;)
//! @endcond
#endif
//! Çàìåíà ìàêðîñó sizearr() äëÿ ðàáîòû â Microsoft Visual Studio 6
#define SIZEARR( arr ) ( sizeof (arr) / sizeof (0[arr]) )
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ïðîâåðêà, íàõîäèòñÿ ëè ïàðàìåòð õ âíóòðè çàìêíóòîãî èíòåðâàëà [a; b]
//!
//! @param x Ïðîâåðÿåìûé ïàðàìåòð
//! @param a Ëåâàÿ ãðàíèöà (âêëþ÷èòåëüíî)
//! @param b Ïðàâàÿ ãðàíèöà (âêëþ÷èòåëüíî)
//!
//! @return Åñëè a <= x && x <= b, òî èñòèíà, åñëè íåò - ëîæü
//!
//! @usage @code
//! while (txMouseButtons() != 1)
//! {
//! if (In (txMouseX(), 110, 120)) txTextOut (100, 100, "Meet the wall!");
//! txSleep (0);
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
template <typename T>
inline bool In (T x, T a, T b);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ïðîâåðêà, íàõîäèòñÿ ëè òî÷êà pt âíóòðè ïðÿìîóãîëüíèêà rect
//!
//! @param pt Ïðîâåðÿåìàÿ òî÷êà â âèäå <tt> POINT {x, y} </tt>
//! @param rect Ïðÿìîóãîëüíèê â âèäå <tt> RECT {left, top, right, bottom} </tt>
//!
//! @return Ðåçóëüòàò ïðîâåðêè
//!
//! Óäîáíî äëÿ ðåàëèçàöèè ýêðàííûõ êíîïîê, íàæèìàåìûõ êóðñîðîì ìûøè.
//!
//! @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);
inline bool In (const COORD& pt, const SMALL_RECT& rect);
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ãåíåðàòîð ñëó÷àéíûõ ÷èñåë
//!
//! @param range Ïðàâàÿ ãðàíèöà äèàïàçîíà (@b íå âêëþ÷àÿ ñàìó ãðàíèöó).
//!
//! @return Ñëó÷àéíîå öåëîå ÷èñëî â äèàïàçîíå [0; range).
//!
//! Âû åùå ïîìíèòå, ÷òî îçíà÷àþò ðàçíûå ñêîáî÷êè â îáîçíà÷åíèè èíòåðâàëîâ? :)
//!
//! @usage @code
//! char message[100] = "Maybe...";
//! sprintf ("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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ãåíåðàòîð ñëó÷àéíûõ ÷èñåë
//!
//! @param left Ëåâàÿ ãðàíèöà äèàïàçîíà (@b âêëþ÷àÿ ñàìó ãðàíèöó).
//! @param right Ïðàâàÿ ãðàíèöà äèàïàçîíà (@b âêëþ÷àÿ ñàìó ãðàíèöó).
//!
//! @return Ñëó÷àéíîå öåëîå ÷èñëî â äèàïàçîíå [left; right].
//!
//! Âû âñå åùå ïîìíèòå, ÷òî îçíà÷àþò ðàçíûå ñêîáî÷êè â îáîçíà÷åíèè èíòåðâàëîâ? :)
//!
//! @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);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Âîçâðàùàåò ìàêñèìàëüíîå èç äâóõ ÷èñåë
//!
//! @param a Îäíî èç ÷èñåë :)
//! @param b Äðóãîå èç ÷èñåë :)
//!
//! @return Ìàêñèìàëüíîå èç äâóõ ÷èñåë a è b
//!
//! @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) )
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Âîçâðàùàåò ìèíèìàëüíîå èç äâóõ ÷èñåë
//!
//! @param a Îäíî èç ÷èñåë :)
//! @param b Äðóãîå èç ÷èñåë :)
//!
//! @return Ìèíèìàëüíîå èç äâóõ ÷èñåë a è b
//!
//! @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) )
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Îêðóãëÿåò ÷èñëî äî öåëîãî
//!
//! @param x ×èñëî
//!
//! @return Îêðóãëåííîå ÷èñëî, ïðåîáðàçîâàííîå â òèï @c int
//!
//! @usage @code
//! double weight = 5.5; // 5.5 kilos is the weight of Maru in 2012.
//! int Maru = ROUND (weight); // Should use ROUND() because Maru is so round.
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 case
#define ROUND( x ) ( (int) round (x) )
#else
#define ROUND( x ) ( (int) floor ((x) + 0.5) )
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief ×èñëî Ïè
//!
//! @usage @code
//! if (txPI == 1) txMessageBox ("Âû ïîïàëè â äðóãóþ Âñåëåííóþ.", "Ïîçäðàâëÿåì", MB_ICONSTOP);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
const double txPI = asin (1.0) * 2;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief <i>Î÷åíü óäîáíîå</i> âîçâåäåíèå ÷èñëà â êâàäðàò.
//!
//! @param x ×èñëî äëÿ âîçâåäåíèÿ â íåãî
//!
//! @return Êâàäðàò, ïîëó÷åííûé ïóòåì âîçâåäåíèÿ â íåãî ÷èñëà, çàäàííîãî äëÿ âîçâåäåíèÿ â êâàäðàò
//!
//! @note Ýòî ïðèìåð, êàê <b> íå íàäî </b> ïèñàòü êîä: txSqr() @d ôóíêöèÿ ñ "ìåäâåæüåé óñëóãîé". Èíîãäà âñòðå÷àþòñÿ
//! òå, êòî ëþáèò ïå÷àòàòü â ôóíêöèè ðåçóëüòàò åå âû÷èñëåíèé <small> (íå äàííûå äëÿ îòëàäêè, à èìåííî ðåçóëüòàò),
//! </small> âìåñòî òîãî, ÷òîáû ïðîñòî âîçâðàùàòü åãî òóäà, ãäå ýòó ôóíêöèþ âûçûâàëè. Ïóñòü ýòè ëþäè âîñïîëüçóþòñÿ
//! ïðèâåäåííîé 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!" "!!" "!!" " Âû ðàäû???? ", sqr);
txMessageBox (str, "Ïîëó÷åí ÎÒÂÅÒ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDNO ||
(
txMessageBox ("Æàëü...", "À ÿ òàê ñòàðàëàñü", MB_ICONINFORMATION),
txMessageBox ("Óéäó ÿ îò âàñ ", "Çëûå âû...", MB_ICONSTOP),
exit (EXIT_FAILURE), 0
);
txNotifyIcon (1, NULL, "\n%s\n", "Âûñøàÿ ìàòåìàòèêà! \0" // À êàê ýòî ðàáîòàåò, à?
"Ñ óìà ñîéòè... \0" //
"à ÊÝÏ ïîäòâåðæäàåò \0" // è êòî ýòî áóäåò
"Ãëàâíîå - îò÷èòàòüñÿ\0" // ïîääåðæèâàòü?..
"Íåâåðîÿòíî, íî ôàêò \0"
"Êòî áû ìîã ïîäóìàòü?\0" + GetTickCount() % 6 * 21);
return sqr; // Âñå æå âåðíåì çíà÷åíèå. Ìû æå íå çâåðè
}
//{----------------------------------------------------------------------------------------------------------------
//! @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 <type> ()
//! @cond INTERNAL
template <typename T> inline T zero();
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Àâòîìàòè÷åñêèé âûçîâ ôóíêöèè ïðè çàâåðøåíèè äðóãîé ôóíêöèè (àíàëîã @c __finally)
//!
//! @param param_t Òèï ïàðàìåòðà àâòîìàòè÷åñêè âûçûâàåìîé ôóíêöèè
//! @param param Èìÿ ïàðàìåòðà àâòîìàòè÷åñêè âûçûâàåìîé ôóíêöèè
//! @param func Òåëî àâòîìàòè÷åñêè âûçûâàåìîé ôóíêöèè (ôèãóðíûå ñêîáêè íå îáÿçàòåëüíû)
//!
//! @par Ìàêðîñ <tt>TX_AUTO_FUNC (param_t, param, func)</tt>
//! @note
//! - Äëÿ àâòîìàòè÷åñêè âûçûâàåìîé ôóíêöèè äîïóñêàåòñÿ òîëüêî @a îäèí ïàðàìåòð.
//! - Åãî òèï @c param_t è èìÿ @c param äîëæíû ñîîòâåòñòâîâàòü îïðåäåëåíèþ ïåðåìåííîé, äîñòóïíîé â òåêóùåé
//! îáëàñòè âèäèìîñòè.
//! Ïàðàìåòð âûçûâàåìîé ôóíêöèè áóäåò ñâÿçàí ñ ýòîé ïåðåìåííîé ÷åðåç ññûëêó.
//! - Ñèíîíèì: TX_FINALLY
//!
//! @warning  Microsoft Visual Studio 6 è 2003 â îòëàäî÷íîé êîíôèãóðàöèè (Debug) ýòîò ìàêðîñ ðàáîòàòü íå áóäåò,
//! ñì. <a href="http://support.microsoft.com/kb/199057">MS KB Article 199057</a>. Ìîæíî îáõîäèòüñÿ
//! ìàêðîñîì @c _TX_AUTO_FUNC, ñì. åãî îïðåäåëåíèå â èñõîäíîì òåêñòå ðÿäîì ñ îïðåäåëåíèåì @c TX_AUTO_FUNC.
//!
//! @par Ìàêðîñ <tt>tx_auto_func (func)</tt>
//! @note
//! - @a Âñå ïåðåìåííûå âûçûâàåìîé ôóíêöèè ñâÿçûâàþòñÿ ñ ïåðåìåííûìè âíåøíåé ôóíêöèè ïî ññûëêå.
//! - Èõ íàçâàíèÿ è òèïû @a íå óêàçûâàþòñÿ. Óêàçûâàåòñÿ òîëüêî òåëî âûçûâàåìîé ôóíêöèè.
//! - Ýòà ôîðìà èñïîëüçóåò ëÿìáäà-ôóíêöèè @c C++0x, ïîýòîìó ïðè êîìïèëÿöèè òðåáóåòñÿ <i>MSVS 2010</i>
//! èëè <i>GCC íå íèæå âåðñèè 4.5 ñ êëþ÷îì êîìïèëÿöèè @c -std=c++0x èëè @c -std=c++11.</i>
//! - Ñèíîíèì: tx_finally
//!
//! @see txAutoLock
//!
//! @usage @code
//! void f1()
//! {
//! int x = 1;
//! TX_AUTO_FUNC (int, x, $(x)); // Will be printed at return
//!
//! FILE* f = fopen (__FILE__".o.txt", "w"); // Will be closed at return
//! TX_AUTO_FUNC (FILE*, f, fclose (f));
//!
//! fprintf (f, "start: x = %d\n", x); // Do some job
//! x = 2; // Do some job
//! }
//!
//! void f2() // Do the same. For C++0x only
//! {
//! int x = 1;
//! tx_auto_func ($(x)); // More simple usage
//!
//! FILE* f = fopen (__FILE__".o.txt", "w");
//! tx_auto_func (fclose (f)); // More simple usage
//!
//! fprintf (f, "start: x = %d\n", x);
//! x = 2;
//! }
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
//{ C++03 version
#define TX_AUTO_FUNC( param_t, param, func ) \
_TX_AUTO_FUNC( __LINE__, param_t, param, func )
#define _TX_AUTO_FUNC( n, param_t, param, func ) \
_TX_AUTO_FUN2( n, param_t, param, func )
#define _TX_AUTO_FUN2( n, param_t, param, func ) \
struct _TX_AUTO_FUNC_##n \
{ \
typedef _TX_AUTO_FUNC_##n this_t; \
param_t& param; \
\
_TX_AUTO_FUNC_##n (param_t& __p) : param (__p) { } \
~_TX_AUTO_FUNC_##n () { func; } \
\
private: this_t& operator= (const this_t&) { return *this; } \
} \
_TX_AUTO_FUNC_##n (param)
//}
//{ C++0x version, use MSVS 2010 or GCC v.4.5+ and -std=c++0x in command line
#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; })
template <typename T>
struct _tx_auto_func_
{
typedef _tx_auto_func_ this_t;
T func_;
_tx_auto_func_ (T func) : func_ (func) {}
~_tx_auto_func_ () { func_(); }
private: this_t& operator= (const this_t&) { return *this; }
};
template <typename T>
_tx_auto_func_<T> _tx_auto_func (T func)
{
return _tx_auto_func_ <T> (func);
}
//}
//{ Compatibility
#define TX_FINALLY( param_t, param, func ) TX_AUTO_FUNC (param_t, param, func)
#define tx_finally( func ) tx_auto_func (func)
//}
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Çàìåíà ñòàíäàðòíîãî ìàêðîñà assert(), ñ âûäà÷åé ñîîáùåíèÿ ÷åðåç txMessageBox(), êîíñîëü è
//! OutputDebugString().
//!
//! @param cond Óñëîâèå äëÿ ïðîâåðêè
//!
//! @return Íå îïðåäåëåíî
//!
//! Åñëè óñëîâèå, ïðîâåðÿåìîå assert(), èñòèííî, òî ìàêðîñ íè÷åãî íå äåëàåò. @n
//! Åñëè óñëîâèå îêàçûâàåòñÿ ëîæíî, òî âûâîäèòñÿ äèàãíîñòè÷åñêîå ñîîáùåíèå è ïðîãðàììà àâàðèéíî
//! çàâåðøàåòñÿ.
//!
//! @warning <b>Ïðè êîìïèëÿöèè â ðåæèìå Release (èëè åñëè îïðåäåëåí NDEBUG) assert ïðåâðàùàåòñÿ â ïóñòîé îïåðàòîð.</b> @n
//! Íå íàäî ïîìåùàòü â assert() äåéñòâèÿ, êîòîðûå âàæíû äëÿ ðàáîòû àëãîðèìà!
//!
//! @note Åñëè óñëîâèå @c cond ìîæåò áûòü âû÷èñëåíî óæå âî âðåìÿ êîìïèëÿöèè êàê ëîæíîå, êîìïèëÿòîð ìîæåò
//! ïðåäóïðåäèòü îá ýòîì (êàê î äåëåíèè íà 0).
//! @note <small>See: <a href=http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf> "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</a>, page 15.</small>
//!
//! @see asserted, verified, verify(), TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox(),
//! txNotifyIcon(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! assert (0 <= i && i < ARRAY_SIZE);
//!
//! FILE* input = fopen ("a.txt", "r");
//! assert (input);
//!
//! // Ýòîò âûçîâ fgets() ÍÅ áóäåò âûïîëíåí â ðåæèìå Release:
//! assert (fgets (str, sizeof (str) - 1, input));
//!
//! // Çäåñü âñå áóäåò ïðàâèëüíî:
//! bool ok = (fclose (input) == 0);
//! assert (ok);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG)
#undef assert
#define assert( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ÂÍÅÇÀÏÍÎ: Ëîãè÷åñêàÿ îøèáêà: " \
"Íåâåðíî, ÷òî \"%s\"." TX_COMMA #cond), \
0/(int)!!(cond)) : 1 )
#else
#undef assert
#define assert( cond ) ((void) 1)
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Âûâîäèò äèàãíîñòè÷åñêîå ñîîáùåíèå â ñëó÷àå íóëåâîãî èëè ëîæíîãî ðåçóëüòàòà.
//!
//! @return Âñåãäà 0
//!
//! Ñóôôèêñíàÿ ôîðìà ìàêðîñà assert(), íå òåðÿþùàÿ â ðåæèìå Release èñïîëíåíèÿ ïðåäèêàòà.
//!
//! @note <b>Ïðåäïîëàãàåòñÿ, ÷òî îïåðàöèÿ â ñëó÷àå íåóñïåõà âîçâðàùàåò 0 èëè false.</b> @n@n
//! <b>Ïðè êîìïèëÿöèè â ðåæèìå Release (èëè åñëè îïðåäåëåí NDEBUG) asserted ïðåâðàùàåòñÿ â ïóñòîå ìåñòî.</b>
//!
//! @see assert(), verify(), verified, TX_ERROR(), TX_DEBUG_ERROR(), txOutputDebugPrintf(), txMessageBox(),
//! txNotifyIcon(), __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(), __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 @c GCC â ðåæèìå ñòðîãîãî ñîîòâåòñòâèÿ ñòàíäàðòó ANSI (ñ êëþ÷îì êîìàíäíîé ñòðîêè <tt>-ansi</tt>) è
//! Microsoft Visual Studio âåðñèé 6 è 2003 íå ïîääåðæèâàþò ìàêðîñû ñ ïåðåìåííûì ÷èñëîì ïàðàìåòðîâ.
//! Ïîýòîìó, åñëè ïàðàìåòðîâ íåñêîëüêî, îíè ðàçäåëÿþòñÿ @b _ (@ref _ "ñèìâîëîì ïîä÷åðêèâàíèÿ",
//! ïåðåîïðåäåëåííûì â çàïÿòóþ) èëè ñèìâîëîì TX_COMMA, âìåñòî íàñòîÿùåé çàïÿòîé, òàê êàê TX_ERROR @d ìàêðîñ. @n
//! Åñëè â ïðîåêòå èñïîëüçóþòñÿ áèáëèîòåêè <a href=http://boost.org><tt>boost</tt></a>, òî èõ íàäî âêëþ÷àòü
//! @b äî @c TXLib.h è âìåñòî ñèìâîëà ïîä÷åðêèâàíèÿ ïîëüçîâàòüñÿ TX_COMMA, òàê êàê @c boost èñïîëüçóåò
//! ñèìâîë ïîä÷åðêèâàíèÿ êàê ñâîé ñîáñòâåííûé ñëóæåáíûé ìàêðîñ â ìîäóëå @c boost::preprocessor, @strike
//! ãäå òâîðèòñÿ äåôàéíîâûé àäÚ. @endstrike
//!
//! @return Âñåãäà false
//!
//! @see _, TX_COMMA, assert(), asserted, verify(), verified, TX_DEBUG_ERROR(), txOutputDebugPrintf(),
//! txMessageBox(), txNotifyIcon(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! TX_ERROR ("Íå ñìîã ïðî÷èòàòü 'Âîéíó è ìèð'. Îòìàçêà %d: íå íàøåë '%s'", reasonNum, fileName);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
// Variadic macros not supported in Strict ANSI mode and in MSVC prior to MSVC 8 (2005)
#if defined (__STRICT_ANSI__) || defined (_MSC_VER) && (_MSC_VER < 1400)
#define TX_ERROR( msg ) _txError (__FILE__, __LINE__, __TX_FUNCTION__, msg)
#else
#define TX_ERROR( ... ) _txError (__FILE__, __LINE__, __TX_FUNCTION__, __VA_ARGS__)
#endif
//! @cond INTERNAL
#define TX_THROW TX_ERROR //!< For compatibility with earlier releases
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Âûâîäèò ðàçâåðíóòîå äèàãíîñòè÷åñêîå ñîîáùåíèå â îòëàäî÷íîì ðåæèìå.
//!
//! Îïèñàíèå ñì. â TX_ERROR.
//!
//! @note  ðåæèìå Release ýòîò ìàêðîñ íå âûâîäèò íè÷åãî.
//!
//! @see _, TX_COMMA, assert(), asserted, verify(), verified, TX_ERROR(), txOutputDebugPrintf(),
//! txMessageBox(), txNotifyIcon(), __TX_FILELINE__, __TX_FUNCTION__
//!
//! @usage @code
//! TX_DEBUG_ERROR ("Òàê è íå ñìîã ïðî÷èòàòü 'Âîéíó è ìèð'. Îòìàçêà %d: ïîòåðÿë '%s'", reasonNum, fileName);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (NDEBUG)
#define TX_DEBUG_ERROR TX_ERROR
#else
#define TX_DEBUG_ERROR(m) ((void) 0)
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ðàñïå÷àòûâàåò äàìï îáëàñòè ïàìÿòè â êîíñîëè.
//!
//! @param address Àäðåñ íà÷àëà ðàñïå÷àòêè.
//! @param name Íàçâàíèå ðàñïå÷àòêè (óñåêàåòñÿ äî 8 ñèìâîëîâ).
//!
//! @note Ðàñïå÷àòûâàåòñÿ îáëàñòü ïàìÿòè ðàçìåðîì 256 áàéò. @nn
//! Ïîñëå ðàñïå÷àòêè àòðèáóòû êîíñîëè ñáðàñûâàþòñÿ â 0x07 (ñâåòëî-ñåðûé íà ÷åðíîì).
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! const char text[] = "Êàæäîìó ëåêòîðó - â ïîðòôåëü ïî âåêòîðó";
//! txDump (text);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
void txDump (const void* address, const char name[] = "txDump()");
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ìàêðîñ, ïîçâîëÿþùèé ïåðåäàòü ïåðåìåííîå ÷èñëî ïàðàìåòðîâ â êàêîé-ëèáî äðóãîé ìàêðîñ.
//!
//! @note <b>Ñèìâîë ïîä÷åðêèâàíèÿ è ñèìâîë TX_COMMA ïðîñòî ïåðåîïðåäåëÿþòñÿ â çàïÿòóþ.</b>
//!
//! @see TX_ERROR(), TX_DEBUG_ERROR()
//!
//! @usage @code
//! TX_ERROR ("Ñëèøêîì óìíûé àáçàö: ðîìàí 'Âîéíà è ìèð', ôàéë '%s', ñòðîêà %d" _ fileName _ lineNum);
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#define _ ,
#define TX_COMMA , //!< Ñèíîíèì ìàêðîñà _ (@ref _ "ñèìâîë ïîä÷åðêèâàíèÿ")
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Èìÿ è âåðñèÿ òåêóùåãî êîìïèëÿòîðà
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (__GNUC__)
#define __TX_COMPILER__ "GNU g++ " TX_PREPROCESS (__GNUC__) "." \
TX_PREPROCESS (__GNUC_MINOR__) "." \
TX_PREPROCESS (__GNUC_PATCHLEVEL__) \
", std=" TX_PREPROCESS (__cplusplus)
#elif defined (_MSC_VER)
#define __TX_COMPILER__ "MSVS " TX_PREPROCESS (_MSC_VER) \
", std=" TX_PREPROCESS (__cplusplus)
#elif defined (__INTEL_COMPILER)
#define __TX_COMPILER__ "Intel C++ " TX_PREPROCESS (__INTEL_COMPILER) \
", std=" TX_PREPROCESS (__cplusplus)
#else
#define __TX_COMPILER__ "Unknown C++, std=" TX_PREPROCESS (__cplusplus)
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Ìàêðîñ, ðàñêðûâàþùèéñÿ â èìÿ ôàéëà è íîìåð ñòðîêè ôàéëà, ãäå îí âñòðåòèëñÿ.
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define __TX_FILELINE__ __FILE__ " (" TX_PREPROCESS (__LINE__) ")"
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Èìÿ òåêóùåé ôóíêöèè
//!
//! @warning Åñëè îïðåäåëåíèå èìåíè ôóíêöèè íå ïîääåðæèâàåòñÿ êîìïèëÿòîðîì, òî __TX_FUNCTION__ ðàñêðûâàåòñÿ â èìÿ
//! èñõîäíîãî ôàéëà è íîìåð ñòðîêè.
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if defined (__GNUC__)
#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 (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
#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
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @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
//! @{ @cond INTERNAL
#define TX_PREPROCESS( sym ) _TX_QUOTE (sym)
#define _TX_QUOTE( sym ) #sym
//! @endcond
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Èìÿ ìîäóëÿ TXLib, âõîäèò â äèàãíîñòè÷åñêèå ñîîáùåíèÿ.
//!
//! @note Ìîæíî ïåðåîïðåäåëÿòü äî âêëþ÷åíèÿ ôàéëà TXLib.h.
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#if !defined (_TX_MODULE)
#define _TX_MODULE "TXLib"
#endif
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Back-hole (I hope, not an ass-hole:) of the library)
//! @name Î÷åíü ñëóæåáíûå ôóíêöèè
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Óñòàíàâëèâàåò àëüòåðíàòèâíóþ ôóíêöèþ îáðàáîòêè îêîííûõ ñîîáùåíèé Windows (îêîííóþ ôóíêöèþ) äëÿ îêíà
//! TXLib.
//!
//! @param wndProc Íîâàÿ îêîííàÿ ôóíêöèÿ îêíà TXLib. @n
//! Åñëè NULL, òî òåêóùàÿ îêîííàÿ ôóíêöèÿ óäàëÿåòñÿ è óñòàíàâëèâàåòñÿ ñòàíäàðòíàÿ.
//!
//! @return Àäðåñ ïðåäûäóùåé îêîííîé ôóíêöèè äëÿ îêíà TXLib.
//!
//! Çàäàííàÿ îêîííàÿ ôóíêöèÿ áóäåò âûçûâàòüñÿ @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 èç äèñïåò÷åðà çàäà÷, èëè èç áîëåå ïðîäâèíóòîãî äèñïåò÷åðà
//! <a href=http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx> Process Explorer</a>. Åñëè Âû
//! áåðåòå íà ñåáÿ îáðàáîòêó îêîííûõ ñîîáùåíèé, äåëàéòå åå ïî ïðàâèëàì Win32 (ñì. MSDN), âêëþ÷àÿ âûçîâ
//! DefWindowProc().
//!
//! @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);
//!
//! int main()
//! {
//! txCreateWindow (GetSystemMetrics (SM_CXSCREEN) / 4, GetSystemMetrics (SM_CYSCREEN) / 4);
//!
//! txSetWindowsHook (MyWndProc);
//!
//! txDrawText (0, 0, txGetExtentX(), txGetExtentY(), "MOV txWindow, eax [please]");
//!
//! return 0;
//! }
//!
//! LRESULT CALLBACK MyWndProc (HWND window, UINT message, WPARAM wParam, LPARAM lParam)
//! {
//! if (message == WM_MOVE) txMessageBox (" I like to MOVe it, MOVe it", "TXLib 2 Real", MB_ICONINFORMATION);
//!
//! static int i = 0;
//! if (i++ % 10 == 0) printf ("\b" "%c", "-\\|/" [i/10 % 4]); // Ïððîïïïåëëëëåðððð
//!
//! return 0; // Ïðîäîëæèòü îáðàáîòêó ñîîáùåíèÿ ñðåäñòâàìè TXLib
//! }
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Áëîêèðîâêà õîëñòà (êîíòåêñòà ðèñîâàíèÿ).
//!
//! @param wait Îæèäàòü êîíöà ïåðåðèñîâêè îêíà âñïîìîãàòåëüíûì ïîòîêîì
//!
//! @return Ñîñòîÿíèå áëîêèðîâêè
//!
//! Ïåðåä âûçîâîì ëþáûõ ôóíêöèé Win32 GDI íåîáõîäèìî çàáëîêèðîâàòü õîëñò ôóíêöèåé txLock() è çàòåì
//! ðàçáëîêèðîâàòü ñ ïîìîùüþ txUnlock(). Ýòî ñâÿçàíî ñ òåì, ÷òî îáíîâëåíèå ñîäåðæèìîãî îêíà (äëÿ òåõ, êòî
//! çíàåò Win32: îáðàáîòêà ñîîáùåíèÿ WM_PAINT) â áèáëèîòåêå TXLib ïðîèñõîäèò â îòäåëüíîì âñïîìîãàòåëüíîì
//! ïîòîêå. Íàäîëãî áëîêèðîâàòü åãî íåëüçÿ - ïðè çàáëîêèðîâàííîì ïîòîêå îêíî íå îáíîâëÿåòñÿ.
//!
//! txLock() èñïîëüçóåò EnterCriticalSection(), è ôèçè÷åñêè ïðèîñòàíàâëèâàåò ïîòîê, îáíîâëÿþùèé îêíî, òàê
//! ÷òî íàäîëãî áëîêèðîâàòü íåëüçÿ. Èíà÷å òîðìîçèòñÿ îáðàáîòêà îêîííûõ ñîîáùåíèé, îêíî ïåðåñòàåò
//! ðåàãèðîâàòü íà äåéñòâèÿ ïîëüçîâàòåëÿ è ïåðåðèñîâûâàòüñÿ. Íåëüçÿ òàêæå âûçûâàòü txSleep() èëè Sleep()
//! ïðè çàáëîêèðîâàííîì ïîòîêå.
//!
//! txLock() / txUnlock() - ýòî íèçêîóðîâíåâûé ìåõàíèçì. Îí îòëè÷àåòñÿ îò áîëåå ïðîñòîãî âûñîêîóðîâíåâîãî
//! ìåõàíèçìà txBegin() / txEnd() / txUpdateWindow(), êîòîðûé íå ïðèîñòàíàâëèâàåò ïîòîê, à ïðîñòî
//! îòêëþ÷àåò ïðèíóäèòåëüíîå ïîñòîÿííîå îáíîâëåíèå îêíà.
//!
//! @see txDC(), txLock(), txUnlock(), txGDI()
//!
//! @usage Ñì. èñõîäíûé òåêñò ôóíêöèé _txCanvas_OnPAINT() è _txConsole_Draw() â TXLib.h.
//}----------------------------------------------------------------------------------------------------------------
bool txLock (bool wait = true);
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Ðàçáëîêèðîâêà õîëñòà
//!
//! @return Ñîñòîÿíèå áëîêèðîâêè (âñåãäà false).
//!
//! Áîëåå ïîäðîáíî ñì. â îïèñàíèè txLock().
//!
//! @see txDC(), txLock(), txGDI()
//!
//! @usage Ñì. èñõîäíûé òåêñò ôóíêöèé _txCanvas_OnPAINT() è _txConsole_Draw() â TXLib.h.
//}----------------------------------------------------------------------------------------------------------------
//! @{
bool txUnlock();
//! @cond INTERNAL
template <typename T> inline T txUnlock (T value);
//! @endcond
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Âûçîâ ôóíêöèè Win32 GDI ñ àâòîìàòè÷åñêîé áëîêèðîâêîé è ðàçáëîêèðîâêîé.
//!
//! @param command Êîìàíäà GDI (âîçìîæíî, âîçâðàùàþùàÿ çíà÷åíèå)
//!
//! @return Çíà÷åíèå, âîçâðàùàåìîå âûçûâàåìîé ôóíêöèåé GDI. Åñëè ñèñòåìà ðèñîâàíèÿ íå ãîòîâà, âîçâðàùàåòñÿ
//! çíà÷åíèå false.
//!
//! @note Åñëè ñèñòåìà ðèñîâàíèÿ íå ãîòîâà (txDC() âîçâðàùàåò NULL), òî êîìàíäà GDI íå âûïîëíÿåòñÿ, à txGDI()
//! âîçâðàùàåò çíà÷åíèå false. @n
//!
//! @note Åñëè â âûçîâå ôóíêöèè GDI èñïîëüçóþòñÿ çàïÿòûå, òî èñïîëüçóéòå äâîéíûå ñêîáêè, ÷òîáû ïîëó÷èëñÿ îäèí
//! ïàðàìåòð, òàê êàê txGDI() âñå-òàêè ìàêðîñ.
//!
//! @see txDC(), txLock(), txUnlock()
//!
//! @usage @code
//! txGDI (( Rectangle (txDC(), x1, y1, x2, y2) )); // Íå çàáóäüòå ïðî äâå ((ÄÂÅ)) ñêîáêè
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
#define txGDI( command ) txUnlock ( (txLock(), (command)) )
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Tune-up constants and variables
//! @name Íàñòðîå÷íûå êîíñòàíòû è ïåðåìåííûå
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Çàïðåò ðàííåé èíèöèàëèçàöèè TXLib
//!
//! Åñëè êîíñòàíòà îïðåäåëåíà ñ ïîìîùüþ \#define @a äî âêëþ÷åíèÿ TXLib.h â ïðîãðàììó, ðàííÿÿ èíèöèàëèçàöèÿ
//! (äî çàïóñêà ôóíêöèè @c main) @b íå ïðîâîäèòñÿ.
//!
//! @note Ðàííÿÿ èíèöèàëèçàöèÿ âêëþ÷àåò:
//! - Îòêðûòèå îêíà êîíñîëè,
//! - Óñòàíîâêó êîäîâîé ñòðàíèöû _TX_CP (1251) êîíñîëè äëÿ ïîääåðæêè ðóññêîãî ÿçûêà,
//! - Óñòàíîâêó ðóññêîé ëîêàëè ñòàíäàðòíîé áèáëèîòåêè,
//! - Ïåðåèíèöèàëèçàöèÿ áèáëèîòåê stdio è iostream íà ñëó÷àé, åñëè ïðèëîæåíèå íå ñêîìïîíîâàíî êàê êîíñîëüíîå
//! è áèáëèîòåêè îñòàëèñü íåèíèöèàëèçèðîâàíû,
//! - Ïåðåõâàò ñèñòåìíûõ ñèãíàëîâ (äåëåíèå íà 0, îáðàùåíèå ïî íåâåðíîìó àäðåñó è ò.ä.),
//! - Ïåðåõâàò íåîáðàáîòàííûõ èñêëþ÷åíèé,
//! - Ñìåíà çàãîëîâêà êîíñîëüíîãî îêíà,
//! - Óñòàíîâêà ðåæèìà ïàóçû ïî çàâåðøåíèè ïðîãðàììû, ÷òîáû îêíî çàêðûâàëîñü íå ñðàçó,
//! - Ïîäàâëåíèå ïàóçû ïðè çàïóñêå èç ñðåä ïðîãðàììèðîâàíèÿ, çàñòàâëÿþùåé íàæèìàòü íà êëàâèøó äâà ðàçà. @nn
//!
//! @note Åñëè ðàííÿÿ èíèöèàëèçàöèÿ çàïðåùåíà, íî â EXE-ôàéëå ñîçäàåòñÿ îêíî TXLib ñ ïîìîùüþ txCreateWindow(),
//! òî áèáëèîòåêà âñå ðàâíî áóäåò èíèöèàëèçèðîâàíà. Â @b DLL ðàííÿÿ èíèöèàëèçàöèÿ íèêîãäà @b íå ïðîâîäèòñÿ. @nn
//!
//! @note Ðàííÿÿ èíèöèàëèçàöèÿ íå ïîòîêîáåçîïàñíà (not thread-safe).
//!
//! @see txCreateWindow(), _TX_ALLOW_KILL_PARENT, _TX_WAITABLE_PARENTS, _txConsoleMode
//!
//! @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 @d Ñêðûâàòü êîíñîëüíîå îêíî.
//!
//! @note Ïåðåìåííàÿ óñòàíàâëèâàåòñÿ @b äî îòêðûòèÿ îêíà áèáëèîòåêè.
//!
//! @see _TX_NOINIT
//!
//! @usage @code
//! _txConsoleMode = SW_HIDE; // Âñåãäà ñêðûâàòü êîíñîëüíîå îêíî
//! txCreateWindow (800, 600);
//!
//! _txConsoleMode = SW_SHOW; // Âñåãäà ïîêàçûâàòü êîíñîëüíîå îêíî
//! txCreateWindow (800, 600);
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned _txConsoleMode = SW_HIDE;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Ñòèëü ãðàôè÷åñêîãî îêíà áèáëèîòåêè.
//!
//! @note
//! - Ïåðåìåííàÿ óñòàíàâëèâàåòñÿ @b äî îòêðûòèÿ îêíà áèáëèîòåêè.
//!
//! @usage @code
//! _txWindowStyle &= ~WS_CAPTION; // FullScreen: îêíî áåç çàãîëîâêà, ðàçìåðîì ñ ýêðàí
//! txCreateWindow (GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN));
//!
//! printf ("Çàêðîéòå ìåíÿ ÷åðåç Alt+F4\n");
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
unsigned _txWindowStyle = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Øðèôò êîíñîëè
//! @note Ïåðåìåííàÿ óñòàíàâëèâàåòñÿ @b äî îòêðûòèÿ îêíà áèáëèîòåêè.
//}----------------------------------------------------------------------------------------------------------------
const char* _txConsoleFont = "Lucida Console";
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Èíòåðâàë ìèãàíèÿ êóðñîðà êîíñîëè (ìñ)
//}----------------------------------------------------------------------------------------------------------------
unsigned _txCursorBlinkInterval = 500;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Èíòåðâàë îáíîâëåíèÿ õîëñòà (ìñ)
//! @note Ïåðåìåííàÿ óñòàíàâëèâàåòñÿ @b äî îòêðûòèÿ îêíà áèáëèîòåêè.
//}----------------------------------------------------------------------------------------------------------------
int _txWindowUpdateInterval = 25;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Òàéìàóò îïåðàöèé îæèäàíèÿ (ìñ)
//}----------------------------------------------------------------------------------------------------------------
#if !defined (TX_TRACE)
const int _TX_TIMEOUT = 1000
#else
const int _TX_TIMEOUT = 5000
#endif
#if defined (_TX_USE_DEVPARTNER)
* 10
#endif
;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Ðàçìåðû âíóòðåííèõ ñòàòè÷åñêèõ ñòðîêîâûõ áóôåðîâ TXLib
//}----------------------------------------------------------------------------------------------------------------
const unsigned _TX_BUFSIZE = 1024;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Ðàçìåðû âíóòðåííèõ ñòàòè÷åñêèõ ñòðîêîâûõ áóôåðîâ TXLib
//}----------------------------------------------------------------------------------------------------------------
const unsigned _TX_BIGBUFSIZE = 2048;
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Ñïèñîê çàïóñêàþùèõ ïðîãðàìì, êîòîðûå æäóò íàæàòèÿ êëàâèøè ïîñëå çàâåðøåíèÿ ïðîöåññà TXLib.
//!
//! Åñëè ïðîãðàììà ïåðå÷èñëåíà â ñïèñêå è TXLib çàïóùåíà èç íåå, òî ïðè çàâåðøåíèè TXLib óêàçàííàÿ
//! ïðîãðàììà áóäåò çàêðûòà. (Ýòî ïðîèçîéäåò, åñëè íå îòêðûòî ãðàôè÷åñêîå îêíî TXLib, à åñòü òîëüêî îêíî
//! êîíñîëè.)
//!
//! Ïðîãðàììû ðàçäåëÿþòñÿ ïðîáåëîì èëè çàïÿòîé. Äîïóñêàåòñÿ óêàçàíèå ðîäèòåëÿ çàïóñêàþùåé ïðîãðàììû, ïîñëå
//! äâîåòî÷èÿ.
//!
//! Ìîæåò çàäàâàòüñÿ ïåðåä âêëþ÷åíèåì TXLib.h â ïðîãðàììó.
//!
//! @see _TX_ALLOW_KILL_PARENT, _TX_NOINIT
//}----------------------------------------------------------------------------------------------------------------
// TX_VEGETABLE_PRINTERS
#if !defined (_TX_WAITABLE_PARENTS)
#define _TX_WAITABLE_PARENTS "cmd.exe:devenv.exe, " /* MSVS 2003-2010 */ \
"vcspawn.exe:msdev.exe, " /* MSVS 6 */ \
"cb_console_runner.exe:codeblocks.exe, " /* CodeBlocks 8-10 */ \
"cmd.exe:console_runner.exe, " /* CodeBlocks 1 */ \
"starter.exe:eclipse.exe, " /* Eclipse 4 */ \
"starter.exe:javaw.exe, " /* Eclipse 3 */ \
"consolepauser.exe:devcpp.exe" /* Dev-Cpp */
#endif
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Ðàçðåøàòü ïðèíóäèòåëüíîå çàâåðøåíèå âûçûâàþùèõ ïðîãðàìì, æäóùèõ íàæàòèÿ êëàâèø ïîñëå çàâåðøåíèÿ TXLib.
//!
//! Èíà÷å îòìåíÿåòñÿ ñîáñòâåííàÿ ïàóçà äî íàæàòèÿ êëàâèøè, âñòðîåííàÿ â TXLib, è ïóñòü òîãäà ïàóçó äåëàåò
//! âûçûâàþùèé ïðîöåññ.
//!
//! Ñïèñîê âûçûâàþùèõ ïðîãðàìì, êîòîðûå ìîãóò äåëàòü òàêóþ ïàóçó, çàäàåòñÿ â _TX_WAITABLE_PARENTS.
//!
//! Ìîæåò çàäàâàòüñÿ ïåðåä âêëþ÷åíèåì TXLib.h â ïðîãðàììó.
//!
//! Ñì. òàêæå îïðåäåëåíèå ýòîé êîíñòàíòû â ôàéëå TXLib.h.
//!
//! @see _TX_WAITABLE_PARENTS, _TX_NOINIT
//!
//! @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 // ã-äàì þðèñòàì ïðèâåò.
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Internal diagnostics
//! @name Âíóòðåííÿÿ äèàãíîñòèêà
//=================================================================================================================
//! @{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Âêëþ÷àåò/îòêëþ÷àåò âíóòðåííþþ òðàññèðîâêó èñïîëíåíèÿ êîäà áèáëèîòåêè.
//!
//! Òðàññèðîâêà èäåò ÷åðåç ìàêðîñ TX_TRACE, êîòîðûé ïîäñòàâëÿåòñÿ ïåðåä êàæäûì îïåðàòîðîì (statement).
//! Ïî óìîë÷àíèþ òðàññèðîâêà âûêëþ÷åíà.
//!
//! Ïî óìîë÷àíèþ òðàññèðîâêà âåäåòñÿ ÷åðåç ôóíêöèþ OutputDebugString(), åå âûâîä ìîæíî ïåðåõâàòèòü
//! óòèëèòàìè-ëîããåðàìè, íàïðèìåð, <a href=http://technet.microsoft.com/ru-ru/sysinternals/bb896647%28en-us%29.aspx>
//! DbgView</a>. Ýòî ìîæíî èçìåíèòü, ïåðåîïðåäåëèâ ìàêðîñ TX_TRACE äî âêëþ÷åíèÿ TXLib.h â ïðîãðàììó.
//!
//! @warning Òðàññèðîâêà @b î÷åíü òîðìîçèò âûïîëíåíèå ïðîãðàììû, îñîáåííî ïðè îòëàäêå â Microsoft Visual Studio.
//!  ýòîì ñëó÷àå ëó÷øå ïîëüçîâàòüñÿ DbgView (ñì. âûøå) è çàïóñêàòü îòëàæèâàåìóþ ïðîãðàììó îòäåëüíî,
//! à íå èç-ïîä îòëàä÷èêà Visual Studio.
//!
//! _TX_ALLOW_TRACE è TX_TRACE çàäàþòñÿ ïåðåä âêëþ÷åíèåì TXLib.h â ïðîãðàììó.
//!
//! @usage @code
//! #define _TX_ALLOW_TRACE // Äëÿ ïðîñìîòðà òðàññû çàïóñòèòü DbgView
//! #include "TXLib.h"
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#ifdef FOR_DOXYGEN_ONLY
#define _TX_ALLOW_TRACE
#endif
#if defined (_TX_ALLOW_TRACE)
#undef $
#define $ { _txFile = __FILE__; _txLine = __LINE__; _txFunc = __TX_FUNCTION__; TX_TRACE; }
#undef $1
#define $1 _txFuncEntry __txFuncEntry; $
#elif defined (_DEBUG)
#undef $
#define $ { _txFile = __FILE__; _txLine = __LINE__; _txFunc = __TX_FUNCTION__; }
#undef $1
#define $1 _txFuncEntry __txFuncEntry; $
#else
#undef $
#define $ ;
#undef $1
#define $1 ;
#endif
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @cond _OFF
extern int _txInitialized;
extern unsigned volatile _txMainThreadId;
extern unsigned volatile _txCanvas_ThreadId;
extern bool _txConsole;
extern bool _txMain;
extern bool _txIsDll;
extern bool volatile _txRunning;
extern bool volatile _txExit;
extern bool volatile _txAllowTrace;
extern const char* volatile _txFile;
extern int volatile _txLine;
extern const char* volatile _txFunc;
extern _TX_THREAD int volatile _txInTX;
//! @endcond
//! @cond INTERNAL
struct _txFuncEntry
{
_txFuncEntry() { _txInTX++; }
~_txFuncEntry() { _txInTX--; }
};
//! @endcond
//}----------------------------------------------------------------------------------------------------------------
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Technical
//! @brief Òðàññèðóåò èñïîëíåíèå êîäà ÷åðåç OutputDebugString().
//!
//! Ïî óìîë÷àíèþ òðàññèðîâêà âåäåòñÿ ÷åðåç ôóíêöèþ OutputDebugString(), åå âûâîä ìîæíî ïåðåõâàòèòü
//! óòèëèòàìè-ëîããåðàìè, íàïðèìåð, <a href=http://technet.microsoft.com/ru-ru/sysinternals/bb896647%28en-us%29.aspx>
//! DbgView</a>. Äëÿ "ðàñêðàñêè" ëîãà åñòü ôàéë <tt>TX\Dev\DbgView.ini,</tt> åãî íàäî çàãðóçèòü â 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__ "\n");
//! #include "TXLib.h"
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
//! @{
#ifdef FOR_DOXYGEN_ONLY
#define TX_TRACE
#endif
#if !defined (TX_TRACE)
#define TX_TRACE if (_txAllowTrace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__);
#endif
//! @}
//{----------------------------------------------------------------------------------------------------------------
//! @cond INTERNAL
void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...);
void _txTrace (const char file[], int line, const char func[], const char msg[] /* = NULL */, ...)
{
unsigned id = GetCurrentThreadId();
const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}};
char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txInTX > 0)];
char msgStr[_TX_BUFSIZE] = "";
if (msg)
{
va_list arg; va_start (arg, msg);
_vsnprintf_s (msgStr, sizeof (msgStr) - 1 _TX_TRUNCATE, msg, arg);
va_end (arg);
}
txOutputDebugPrintf ("%s - %p %c%c%c%c%c%c [%c] - %s (%d) " "|%*s%s" "%s%s\n",
_TX_VERSION, (void*) &_txInitialized,
"cC"[_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], "tT"[_txAllowTrace],
mark, (file? file : "(NULL file)"), line, (_txInTX - 1) * 2, "", (func? func : ""),
(*msgStr? ": " : ""), msgStr);
}
//! @endcond
//}----------------------------------------------------------------------------------------------------------------
//=================================================================================================================
//{ Sweet critical section blocking: txAutoLock class
//=================================================================================================================
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Service
//! @brief Êëàññ äëÿ àâòîìàòè÷åñêîé áëîêèðîâêè è ðàçáëîêèðîâêè êðèòè÷åñêîé ñåêöèè.
//!
//! Íà÷èíàÿ ñ <a href=http://progbook.ru/2008/08/03/sovremennoe-proektirovanie-na-c-andrejj.html>
//! Àëåêñàíäðåñêó,</a> åãî ïèøóò âñå è îí ïðîñò, êàê ïðîáêà: â êîíñòðóêòîðå @d EnterCriticalSection(),
//! â äåñòðóêòîðå @d 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
{
public:
//{----------------------------------------------------------------------------------------------------------------
//! @brief Êîíñòðóêòîð, áëîêèðóåò êðèòè÷åñêóþ ñåêöèþ
//!
//! @param cs Êðèòè÷åñêàÿ ñåêöèÿ äëÿ áëîêèðîâêè
//! @param mandatory Åñëè @c true, òî áëîêèðîâàòü îáÿçàòåëüíî (EnterCriticalSection). @n
//! Åñëè @c false, òî òîëüêî ïûòàòüñÿ áëîêèðîâàòü (TryEnterCriticalSection).
//! @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
//}----------------------------------------------------------------------------------------------------------------
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).
//! @usage @code
//! void foobar()
//! {
//! txAutoLock lock; // Çäåñü âûçîâåòñÿ txLock()
//! ...
//! } // à çäåñü txUnlock()
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
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 txAutoLock&);
txAutoLock& operator = (const txAutoLock&);
//! @}
};
//}
//=================================================================================================================
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ 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.
//!
//! @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
{
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Dialogs
//! @brief Êîíñòàíòû äëÿ çàäàíèÿ òèïà êîíòðîëà.
//!
//! Âìåñòî êîíñòàíò ìîæíî èñïîëüçîâàòü íàçâàíèÿ îêîííûõ êëàññîâ, ïðåîáðàçîâàííûå ê òèïó txDialog::CONTROL.
//!
//! @see txDialog::Layout, txDialog::setLayout()
//!
//! @usage @code
//! Cì. ðåàëèçàöèþ ôóíêöèè txInputBox().
//! @endcode
//!
//! @hideinitializer
//}----------------------------------------------------------------------------------------------------------------
public:
enum CONTROL
{
DIALOG = 0x00000000, //!< Íà÷àëî îïèñàíèÿ äèàëîãà
BUTTON = 0xFFFF0080, //!< Êíîïêà
EDIT = 0xFFFF0081, //!< Ðåäàêòèðóåìûé òåêñò
STATIC = 0xFFFF0082, //!< Íåðåäàêòèðóåìûé ýëåìåíò (òåêñò, êàðòèíêà è ò.ä.)
LISTBOX = 0xFFFF0083, //!< Ñïèñîê ñ ïðîêðóòêîé
SCROLLBAR = 0xFFFF0084, //!< Ïîëîñà ïðîêðóòêè
COMBOBOX = 0xFFFF0085, //!< Êîìáèíèðîâàííûé ñïèñîê
END = 0x00000000 //!< Êîíåö îïèñàíèÿ äèàëîãà
};
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Dialogs
//! @brief Êëàññ äëÿ îïèñàíèÿ ýëåìåíòà äèàëîãîâîãî îêíà (êîíòðîëà)
//!
//! Ìàññèâ òàêèõ ñòðóêòóð çàäàåò îïèñàíèå ìàêåòà äèàëîãîâîãî îêíà. Ýòî îïèñàíèå ïîõîæå íà çàäàíèå äèàëîãà
//! â ðåñóðñíîì ñêðèïòå (.rc):
//!
//! - Íóëåâîé ýëåìåíò îïèñûâàåò äèàëîãîâîå îêíî â öåëîì
//! - Îñòàëüíûå ýëåìåíòû îïèñûâàþò êîíòðîëû (ïîðÿäîê çàäàíèÿ ïàðàìåòðîâ êîíòðîëà ïîõîæ íà ïîðÿäîê
//! ïàðàìåòðîâ â ðåñóðñíîì ñêðèïòå)
//! - Ïîñëåäíèé ýëåìåíò - txDialog::END èëè {NULL}
//!
//! @see txDialog::setLayout(), txDialog::dialogBox(), txDialog::dialogProc()
//!
//! @usage @code
//! Cì. ðåàëèçàöèþ ôóíêöèè txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
public:
struct Layout
{
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
//}----------------------------------------------------------------------------------------------------------------
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 â <a href=msdn.com>MSDN</a>.
//!
//! Ýòó ôóíêöèþ íàäî ïåðåîïðåäåëèòü äëÿ îáðàáîòêè ñîáûòèé îêíà, èëè ïîñòðîèòü åå ñ ïîìîùüþ ìàêðîñîâ
//! 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
//! Ïî óìîë÷àíèþ - àäðåñ îáúåêòà <i>(this),</i> äëÿ êîòîðîãî áûëà çàïóùåíà txDialog::dialogBox().
//!
//! @see txDialog::dialogProc(), txDialog::setLayout(), txDialog::Layout, txDialog
//!
//! @usage @code
//! Cì. ðåàëèçàöèþ ôóíêöèè txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
INT_PTR dialogBox (const Layout* layout = NULL, size_t bufsize = 0);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Çàïóñêàåò äèàëîãîâîå îêíî.
//!
//! @param resource Èäåíòèôèêàòîð äèàëîãîâîãî ðåñóðñà
//!
//! @return Çíà÷åíèå, óêàçàííîå â ôóíêöèè EndDialog(). @n
//! Ïî óìîë÷àíèþ - àäðåñ îáúåêòà <i>(this),</i> äëÿ êîòîðîãî áûëà çàïóùåíà txDialog::dialogBox().
//!
//! @see txDialog::dialogProc()
//!
//! @usage @code
//! Cì. ðåàëèçàöèþ ôóíêöèè txInputBox().
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
INT_PTR dialogBox (WORD resource);
//{----------------------------------------------------------------------------------------------------------------
//! @brief Çàêðûòûå êîíñòðóêòîð êîïèðîâàíèÿ è îïåðàòîð ïðèñâàèâàíèÿ.
//}----------------------------------------------------------------------------------------------------------------
private:
txDialog (const txDialog&);
txDialog& operator = (const txDialog&);
//{----------------------------------------------------------------------------------------------------------------
//! Íàñòîÿùàÿ äèàëîãîâàÿ ôóíêöèÿ (íå txDialog::dialogProc(), ò.ê. ôóíêöèÿ îêíà in32 äîëæíà áûòü ñòàòè÷åñêîé).
//}----------------------------------------------------------------------------------------------------------------
private:
static ptrdiff_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).
//!
//! @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) \
{ \
(void)_wnd; (void)_msg; (void)_wParam; (void)_lParam; \
\
switch (_msg) \
{ \
case WM_NULL:
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Çàãîëîâîê îáðàáîò÷èêà ñîîáùåíèÿ (Message handler) êàðòû ñîîáùåíèé.
//!
//! @param id Èäåíòèôèêàòîð ñîîáùåíèÿ
//!
//! @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) â êàðòå ñîîáùåíèé.
//!
//! @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 Çàâåðøèòåëü êàðòû ñîîáùåíèé.
//!
//! @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() áóäåò
//! âûçûâàòüñÿ íåñêîëüêî ðàç, òî äëÿ ñîõðàíåíèÿ ñòðîêè åå íåîáõîäèìî êîïèðîâàòü â äðóãóþ ñòðîêó ïðè ïîìîùè
//! <i>strcpy()</i>.
//!
//! @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);
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() // Îáíóëåíèå âñåé ñòðîêè. Íå ðàáîòàåò íà ñòàðûõ
{ // êîìïèëÿòîðàõ, ïîýòîìó åùå ðàç:
memset (str, 0, sizeof (str)); // Îáíóëåíèå âñåé ñòðîêè
}
//---------------------------------------------------------------------------------------------------------
TX_BEGIN_MESSAGE_MAP() // Êàðòà ñîîáùåíèé. Íà ñàìîì äåëå ýòî íà÷àëî îêîííîé ôóíêöèè.
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
//---------------------------------------------------------------------------------------------------------
// Êîíåö âíóòðåííåãî êëàññà äèàëîãà
//---------------------------------------------------------------------------------------------------------
};
//-------------------------------------------------------------------------------------------------------------
// Óáèðàåì äåôàéíû, ÷òîáû ïîòîì íå ìåøàëè.
// Îò ýòîãî îíè ïîëó÷àþòñÿ "ëîêàëüíîãî äåéñòâèÿ", êàê áóäòî ó íèõ áûëà áû îáëàñòü âèäèìîñòè -
// ôóíêöèÿ. Íà ñàìîì äåëå ýòî ñäåëàíî âðó÷íóþ ÷åðåç #undef. ×òîáû ïîä÷åðêíóòü èõ ëîêàëüíóþ
// ïðèðîäó, ó íèõ èìåíà çàêàí÷èâàþòñÿ íà _. Òàêèå äåéôàéíû ïîòîì íå ïåðåêîñÿ÷àò âåñü êîä ïîñëå
// òîãî êàê, ôàêòè÷åñêè, ñòàëè óæå íå íóæíû.
//-------------------------------------------------------------------------------------------------------------
#undef ID_TEXT_
#undef ID_INPUT_
//-------------------------------------------------------------------------------------------------------------
// Ýòî ñòàòè÷åñêèé îáúåêò, ïîòîìó ÷òî ñòðîêà â íåì äîëæíà æèòü ïîñëå çàâåðøåíèÿ ôóíêöèè.
//-------------------------------------------------------------------------------------------------------------
static inputDlg dlg;
//-------------------------------------------------------------------------------------------------------------
// Ïåðåäàåì layout è çàïóñêàåì îêíî äèàëîãà
//-------------------------------------------------------------------------------------------------------------
dlg.dialogBox (layout);
//-------------------------------------------------------------------------------------------------------------
// Âîçâðàùàåì àäðåñ ñòðîêè èç ñòàòè÷åñêîãî îáúåêòà. Òàê ìîæíî äåëàòü, ïîòîìó ÷òî ñòàòè÷åñêèé
// îáúåêò íå óìðåò ïðè âûõîäå èç ôóíêöèè è ñòðîêà â íåì, ñîîòâåòñòâåííî, òîæå. Àäðåñ
// íåñòàòè÷åñêèõ ïåðåìåííûõ ïåðåäàâàòü ñèíòàêñè÷åñêè ìîæíî, íî âåäåò ê ñåðüåçíûì îøèáêàì.
//-------------------------------------------------------------------------------------------------------------
return dlg.str;
}
//! @}
//}
//=================================================================================================================
//}
//=================================================================================================================
//=================================================================================================================
//{ TXLIB IMPLEMENTATION
// Ðåàëèçàöèÿ ôóíêöèé áèáëèîòåêè
//=================================================================================================================
//! @cond INTERNAL
//=================================================================================================================
//{ [Internal] Function prototypes, macros and constants
// Ïðîòîòèïû âíóòðåííèõ ôóíêöèé, ìàêðîñû è êîíñòàíòû
//=================================================================================================================
const int _TX_CP = 1251; // Èíôîðìàöèÿ î ëîêàëè
const char _TX_LC_CTYPE[] = "Russian";
const wchar_t _TX_LC_CTYPE_W[] = L"Russian_Russia.ACP";
const int _TX_IDM_ABOUT = 40000; // Èäåíòèôèêàòîðû ñèñòåìíîãî ìåíþ îêíà
const int _TX_IDM_CONSOLE = 40001;
//-----------------------------------------------------------------------------------------------------------------
int _txInitialize();
void _txCleanup();
HWND _txCanvas_CreateWindow (SIZE* size);
inline bool _txCanvas_OK();
bool _txCanvas_OnCREATE (HWND wnd);
bool _txCanvas_OnDESTROY (HWND wnd);
bool _txCanvas_OnCLOSE (HWND);
bool _txCanvas_OnPAINT (HWND wnd);
bool _txCanvas_OnKEYDOWN (HWND wnd, WPARAM vk, LPARAM info);
bool _txCanvas_OnCHAR (HWND wnd, WPARAM ch, LPARAM info);
bool _txCanvas_OnTIMER (HWND wnd, WPARAM id);
bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords);
bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd);
bool _txCanvas_OnCmdABOUT (HWND wnd, WPARAM cmd);
unsigned WINAPI _txCanvas_ThreadProc (void* data);
LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
int _txCanvas_SetRefreshLock (int count);
HDC _txBuffer_Create (HWND wnd, const POINT* size = NULL, HBITMAP bmap = NULL);
bool _txBuffer_Delete (HDC* dc);
bool _txBuffer_Select (HGDIOBJ obj, HDC dc = txDC());
HWND _txConsole_Attach();
bool _txConsole_OK();
bool _txConsole_Detach (bool activate);
bool _txConsole_Draw (HDC dc);
bool _txConsole_SetUnicodeFont();
int _txSetFinishedText (HWND wnd);
void _txPauseBeforeTermination (HWND canvas);
bool _txIsParentWaitable (DWORD* parentPID = NULL);
PROCESSENTRY32* _txFindProcess (unsigned pid = GetCurrentProcessId());
bool _txKillProcess (DWORD pid);
PROC _txSetProcAddress (HMODULE module, const char* dllName, const char* funcName, PROC newFunc);
bool _txInDll();
int _txGetInput();
void _tx_cexit();
bool _txCreateShortcut (const char shortcutName[],
const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL,
const char description[] = NULL, int cmdShow = SW_SHOWNORMAL,
const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0,
COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD));
void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
WORD controls, short x, short y, short cx, short cy,
const char caption[], const char font[], WORD fontsize,
HANDLE menu);
void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
short x, short y, short cx, short cy,
WORD id, const char wclass[], const char caption[]);
const char* _txError (const char file[] = NULL, int line = 0, const char func[] = NULL,
const char msg[] = NULL, ...) _TX_CHECK_FORMAT (4);
HICON _txCreateTXIcon (int size);
void _txOnSignal (int signal = 0, int fpe = 0);
void _txOnTerminate();
void _txOnUnexpected();
FARPROC _txDllImport (const char dllFileName[], const char funcName[], bool required = true);
//-----------------------------------------------------------------------------------------------------------------
// These are macros for __FILE__ and __LINE__ to work properly.
#if !defined (NDEBUG)
#define _TX_IF_ARGUMENT_FAILED( cond ) if (!assert (cond) && (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1))
#define _TX_IF_TXWINDOW_FAILED if ( !txOK() && (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \
(TX_ERROR ("\a" "Îêíî ðèñîâàíèÿ íå ñîçäàíî èëè íå â ïîðÿäêå"), 1))
#else
#define _TX_IF_ARGUMENT_FAILED( cond ) if (! (cond) && (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1))
#define _TX_IF_TXWINDOW_FAILED if ( !txOK() && (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1))
#endif
// Take action in debug configuration only.
// Definition ({ expr; }) would be better, but some old dinosaurs (yes it is MSVC 6) reject it. So sad. :'(
#if !defined (NDEBUG)
#define _TX_ON_DEBUG( code ) { code; }
#else
#define _TX_ON_DEBUG( code ) ;
#endif
// This is a macro because cond is an expression and not always a function. Lack of lambdas in pre-C++0x.
#define _txWaitFor( cond, time ) { for (DWORD _t = GetTickCount() + (time); \
!(cond) && GetTickCount() < _t; \
Sleep (_txWindowUpdateInterval)) ; \
if (!(cond)) \
_txTrace (__FILE__, __LINE__, "WARNING: Timeout: " #cond "."); }
//}
//=================================================================================================================
//=================================================================================================================
//{ [Internal] DLL functions import
//! @name Èìïîðò âíåøíèõ áèáëèîòåê
//=================================================================================================================
//! @{
FARPROC _txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)
{
_TX_IF_ARGUMENT_FAILED (!(dllFileName && !*dllFileName)) return NULL;
_TX_IF_ARGUMENT_FAILED ( funcName && *funcName) return NULL;
HMODULE dll = GetModuleHandle (dllFileName);
if (!dll && dllFileName) dll = LoadLibrary (dllFileName);
if (!dll && required) TX_ERROR ("\a" "Cannot load library \"%s\"" _ dllFileName);
if (!dll) return NULL;
FARPROC addr = GetProcAddress (dll, funcName);
if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s\"" _ funcName _ dllFileName);
return addr;
}
//-----------------------------------------------------------------------------------------------------------------
// Import helpers
// Ìàëàÿ ìåõàíèçàöèÿ
//-----------------------------------------------------------------------------------------------------------------
#define _TX_DLLIMPORT( lib, retval, name, params ) \
retval (WINAPI* name) params = (retval (WINAPI*) params) _txDllImport (lib ".dll", #name, true)
#define _TX_DLLIMPORT_OPT( lib, retval, name, params ) \
retval (WINAPI* name) params = (retval (WINAPI*) params) _txDllImport (lib ".dll", #name, false)
//-----------------------------------------------------------------------------------------------------------------
// Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :(
//{ <tears>
namespace Win32 {
#ifdef _MSC_VER_6
struct CONSOLE_FONT_INFO;
#endif
struct NT_CONSOLE_PROPS;
struct CONSOLE_FONT_INFOEX;
_TX_DLLIMPORT ("GDI32", HDC, CreateCompatibleDC, (HDC dc));
_TX_DLLIMPORT ("GDI32", HBITMAP, CreateCompatibleBitmap, (HDC dc, int width, int height));
_TX_DLLIMPORT ("GDI32", HGDIOBJ, GetStockObject, (int object));
_TX_DLLIMPORT ("GDI32", HGDIOBJ, SelectObject, (HDC dc, HGDIOBJ object));
_TX_DLLIMPORT ("GDI32", HGDIOBJ, GetCurrentObject, (HDC dc, unsigned objectType));
_TX_DLLIMPORT ("GDI32", int, GetObjectA, (HGDIOBJ obj, int bufsize, void* buffer));
_TX_DLLIMPORT ("GDI32", DWORD, GetObjectType, (HGDIOBJ object));
_TX_DLLIMPORT ("GDI32", BOOL, DeleteDC, (HDC dc));
_TX_DLLIMPORT ("GDI32", BOOL, DeleteObject, (HGDIOBJ object));
_TX_DLLIMPORT ("GDI32", COLORREF, SetTextColor, (HDC dc, COLORREF color));
_TX_DLLIMPORT ("GDI32", COLORREF, SetBkColor, (HDC dc, COLORREF color));
_TX_DLLIMPORT ("GDI32", int, SetBkMode, (HDC dc, int bkMode));
_TX_DLLIMPORT ("GDI32", HFONT, CreateFontA, (int height, int width, int escapement, int orientation,
int weight, DWORD italic, DWORD underline, DWORD strikeout,
DWORD charSet, DWORD outputPrec, DWORD clipPrec,
DWORD quality, DWORD pitchAndFamily, const char face[]));
_TX_DLLIMPORT ("GDI32", int, EnumFontFamiliesExA, (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc,
LPARAM lParam, DWORD reserved));
_TX_DLLIMPORT ("GDI32", COLORREF, SetPixel, (HDC dc, int x, int y, COLORREF color));
_TX_DLLIMPORT ("GDI32", COLORREF, GetPixel, (HDC dc, int x, int y));
_TX_DLLIMPORT ("GDI32", HPEN, CreatePen, (int penStyle, int width, COLORREF color));
_TX_DLLIMPORT ("GDI32", HBRUSH, CreateSolidBrush, (COLORREF color));
_TX_DLLIMPORT ("GDI32", BOOL, MoveToEx, (HDC dc, int x, int y, POINT* point));
_TX_DLLIMPORT ("GDI32", BOOL, LineTo, (HDC dc, int x, int y));
_TX_DLLIMPORT ("GDI32", BOOL, Polygon, (HDC dc, const POINT points[], int count));
_TX_DLLIMPORT ("GDI32", BOOL, Rectangle, (HDC dc, int x0, int y0, int x1, int y1));
_TX_DLLIMPORT ("GDI32", BOOL, RoundRect, (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY));
_TX_DLLIMPORT ("GDI32", BOOL, Ellipse, (HDC dc, int x0, int y0, int x1, int y1));
_TX_DLLIMPORT ("GDI32", BOOL, Arc, (HDC dc, int x0, int y0, int x1, int y1,
int xStart, int yStart, int xEnd, int yEnd));
_TX_DLLIMPORT ("GDI32", BOOL, Pie, (HDC dc, int x0, int y0, int x1, int y1,
int xStart, int yStart, int xEnd, int yEnd));
_TX_DLLIMPORT ("GDI32", BOOL, Chord, (HDC dc, int x0, int y0, int x1, int y1,
int xStart, int yStart, int xEnd, int yEnd));
_TX_DLLIMPORT ("GDI32", BOOL, TextOutA, (HDC dc, int x, int y, const char string[], int length));
_TX_DLLIMPORT ("GDI32", UINT, SetTextAlign, (HDC dc, unsigned mode));
_TX_DLLIMPORT ("GDI32", BOOL, GetTextExtentPoint32A, (HDC dc, const char string[], int length, SIZE* size));
_TX_DLLIMPORT ("GDI32", BOOL, ExtFloodFill, (HDC dc, int x, int y, COLORREF color, unsigned type));
_TX_DLLIMPORT ("GDI32", BOOL, BitBlt, (HDC dest, int xDest, int yDest, int width, int height,
HDC src, int xSrc, int ySrc, DWORD rOp));
_TX_DLLIMPORT ("GDI32", int, SetDIBitsToDevice, (HDC dc, int xDest, int yDest, DWORD width, DWORD height,
int xSrc, int ySrc, unsigned startLine, unsigned numLines,
const void* data, const BITMAPINFO* info, unsigned colorUse));
_TX_DLLIMPORT ("GDI32", int, GetDIBits, (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines,
void* lpvBits, BITMAPINFO* lpbi, unsigned usage));
_TX_DLLIMPORT ("GDI32", BOOL, PatBlt, (HDC dc, int x0, int y0, int width, int height, DWORD rOp));
_TX_DLLIMPORT ("GDI32", int, SetROP2, (HDC dc, int mode));
_TX_DLLIMPORT ("GDI32", HRGN, CreateRectRgn, (int x0, int y0, int x1, int y1));
_TX_DLLIMPORT ("GDI32", BOOL, GetBitmapDimensionEx, (HBITMAP bitmap, SIZE* dimensions));
_TX_DLLIMPORT ("User32", int, DrawTextA, (HDC dc, const char text[], int length, RECT* rect, unsigned format));
_TX_DLLIMPORT ("User32", HANDLE, LoadImageA, (HINSTANCE inst, const char name[], unsigned type,
int sizex, int sizey, unsigned mode));
_TX_DLLIMPORT_OPT ("User32", BOOL, IsHungAppWindow, (HWND wnd));
_TX_DLLIMPORT_OPT ("User32", HWND, GhostWindowFromHungWindow,(HWND wnd));
_TX_DLLIMPORT ("WinMM", BOOL, PlaySound, (const char sound[], HMODULE mod, DWORD mode));
_TX_DLLIMPORT_OPT ("MSImg32", BOOL, TransparentBlt, (HDC dest, int destX, int destY, int destWidth, int destHeight,
HDC src, int srcX, int srcY, int srcWidth, int srcHeight,
unsigned transparentColor));
_TX_DLLIMPORT_OPT ("MSImg32", BOOL, AlphaBlend, (HDC dest, int destX, int destY, int destWidth, int destHeight,
HDC src, int srcX, int srcY, int srcWidth, int srcHeight,
BLENDFUNCTION blending));
_TX_DLLIMPORT ("Kernel32", HWND, GetConsoleWindow, (void));
_TX_DLLIMPORT_OPT ("Kernel32", BOOL, SetConsoleFont, (HANDLE con, DWORD fontIndex));
_TX_DLLIMPORT_OPT ("Kernel32", BOOL, GetConsoleFontInfo, (HANDLE con, bool fullScr, DWORD nFonts, CONSOLE_FONT_INFO* info));
_TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetNumberOfConsoleFonts, (void));
_TX_DLLIMPORT_OPT ("Kernel32", BOOL, GetCurrentConsoleFont, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO* curFont));
_TX_DLLIMPORT_OPT ("Kernel32", BOOL, GetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
_TX_DLLIMPORT_OPT ("Kernel32", BOOL, SetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
_TX_DLLIMPORT ("OLE32", HRESULT, CoInitialize, (void*));
_TX_DLLIMPORT ("OLE32", HRESULT, CoCreateInstance, (REFCLSID clsid, LPUNKNOWN, DWORD, REFIID iid, PVOID* value));
_TX_DLLIMPORT ("OLE32", void, CoUninitialize, (void));
_TX_DLLIMPORT ("Shell32", HINSTANCE,ShellExecuteA, (HWND wnd, const char operation[], const char file[],
const char parameters[], const char directory[], int showCmd));
_TX_DLLIMPORT_OPT ("NTDLL", char*, wine_get_version, (void));
_TX_DLLIMPORT_OPT ("MSVCRT", void, _cexit, (void));
//-----------------------------------------------------------------------------------------------------------------
// Another issue, some of structs, consts and interfaces aren't defined in MinGW some ealry headers.
// Copied from Windows SDK 7.0a.
#ifndef AC_SRC_ALPHA
#define AC_SRC_ALPHA 0x01
#endif
#ifndef SMTO_ERRORONEXIT
#define SMTO_ERRORONEXIT 0x0020
#endif
#ifndef NT_CONSOLE_PROPS_SIG
#define NT_CONSOLE_PROPS_SIG 0xA0000002
#endif
#ifndef NIIF_INFO
#define NIIF_INFO 0x00000001
#define NIIF_WARNING 0x00000002
#define NIIF_ERROR 0x00000003
#endif
#ifndef NIF_INFO
#define NIF_STATE 0x00000008
#define NIF_INFO 0x00000010
#endif
#pragma pack (push, 1)
#ifdef _MSC_VER_6
struct CONSOLE_FONT_INFO
{
DWORD nFont;
COORD dwFontSize;
};
struct NOTIFYICONDATA
{
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
CHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
} u;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
};
#endif
struct CONSOLE_FONT_INFOEX
{
ULONG cbSize;
DWORD nFont;
COORD dwFontSize;
UINT FontFamily;
UINT FontWeight;
WCHAR FaceName[LF_FACESIZE];
};
struct DATABLOCK_HEADER
{
DWORD cbSize;
DWORD dwSignature;
};
struct NT_CONSOLE_PROPS
{
DATABLOCK_HEADER dbh;
WORD wFillAttribute;
WORD wPopupFillAttribute;
COORD dwScreenBufferSize;
COORD dwWindowSize;
COORD dwWindowOrigin;
DWORD nFont;
DWORD nInputBufferSize;
COORD dwFontSize;
UINT uFontFamily;
UINT uFontWeight;
WCHAR FaceName[LF_FACESIZE];
UINT uCursorSize;
BOOL bFullScreen;
BOOL bQuickEdit;
BOOL bInsertMode;
BOOL bAutoPosition;
UINT uHistoryBufferSize;
UINT uNumberOfHistoryBuffers;
BOOL bHistoryNoDup;
COLORREF ColorTable[16];
};
#pragma pack (pop)
#undef INTERFACE
#define INTERFACE IShellLinkDataList
DECLARE_INTERFACE_ (IShellLinkDataList, IUnknown)
{
// *** IUnknown methods ***
STDMETHOD (QueryInterface) (THIS_ REFIID iid, void** value) PURE;
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
STDMETHOD_(ULONG, Release) (THIS) PURE;
// *** IShellLinkDataList methods ***
STDMETHOD (AddDataBlock) (THIS_ void* dataBlock) PURE;
STDMETHOD (CopyDataBlock) (THIS_ DWORD sig, void** dataBlock) PURE;
STDMETHOD (RemoveDataBlock) (THIS_ DWORD sig) PURE;
STDMETHOD (GetFlags) (THIS_ DWORD* flags) PURE;
STDMETHOD (SetFlags) (THIS_ DWORD flags) PURE;
protected:
virtual ~IShellLinkDataList();
};
const GUID IID_IShellLink = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
const GUID IID_IShellLinkDataList = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}};
const GUID IID_IPersistFile = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
#undef INTERFACE
} // namespace Win32
#ifdef _MSC_VER_6
using namespace Win32;
#endif
//} </tears>
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ [Internal] Global data
//! @name Ãëîáàëüíûå äàííûå
//
// Äàííûå íå óïàêîâàíû â ñòðóêòóðó èëè êëàññ, äëÿ òîãî, ÷òîáû ýòî ñäåëàëè Âû ñàìè :)
//
// Åñëè âû ïèøåòå ñâîþ áèáëèîòåêó è èñïîëüçóåòå TXLib.h êàê ïðèìåðó, íå ñëåäóéòå åìó è íå äåëàéòå òàê æå.
// Çäåñü ýòî ñäåëàíî òîëüêî â îáðàçîâàòåëüíûõ öåëÿõ.
//
// Áóäüòå ïðàêòè÷íåå, ñäåëàéòå ñòðóêòóðó è ãëîáàëüíóþ ôóíêöèþ äëÿ äîñòóïà ê íåé.
//=================================================================================================================
//! @{
int _txInitialized = _TX_NOINIT || _txInitialize();
unsigned volatile _txMainThreadId = 0; // ID ïîòîêà, ãäå âûïîëíÿåòñÿ main()
unsigned volatile _txCanvas_ThreadId = 0; // ID ïîòîêà, âëàäåþùåãî îêíîì õîëñòà TXLib
HANDLE volatile _txCanvas_Thread = NULL; // Äåêñðèïòîð ýòîãî ïîòîêà
HWND volatile _txCanvas_Window = NULL; // Äåñêðèïòîð îêíà õîëñòà TXLib
UINT _txCanvas_RefreshTimer = 0; // Timer to redraw TXLib window
int volatile _txCanvas_RefreshLock = 0; // Blocks auto on-timer canvas update, see txBegin/txEnd
HDC _txCanvas_BackBuf[2] = {NULL, // [0] Main working TXLib memory DC, where user picture lies
NULL}; // [1] Image ready for auto-refresh, see txCanvas_OnPAINT()
CRITICAL_SECTION _txCanvas_LockBackBuf = {0,-1}; // Prevent simultaneous access to back buffer, see txLock()
std::vector<HDC>* _txCanvas_UserDCs = NULL; // List of DCs allocated, for auto-free
bool volatile _txConsole_IsBlinking = true; // To blink or not to blink, that is the question.
bool _txConsole = false; // Only first TXLib module in app owns it
bool _txMain = false; // First TXLib wnd opened (closing it terminates program)
bool _txIsDll = false; // TXLib module is in DLL
bool volatile _txRunning = false; // main() is still running
bool volatile _txExit = false; // exit() is active
bool volatile _txAllowTrace = true; // Internal TX trace is active
POINT _txMousePos = {0}; // Ask Captn Obviouos about it. See txCanvas_OnMOUSE()
int _txMouseButtons = 0;
WNDPROC volatile _txAltWndProc = NULL; // Àëüòåðíàòèâíàÿ îêîííàÿ ôóíêöèÿ. Ñì. txSetWindowsHook().
const char* volatile _txFile = NULL; // Current execution point tracking, see $ macro
int volatile _txLine = 0;
const char* volatile _txFunc = NULL;
_TX_THREAD int volatile _txInTX = 0; // We are inside one of TXLib's functions
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ TXLib engine init/check/cleanup
//! @name Èíèöèàëèçàöèÿ/ïðîâåðêà/çàâåðøåíèå TXLib
//=================================================================================================================
//! @{
//-----------------------------------------------------------------------------------------------------------------
//{ Early initialization
//-----------------------------------------------------------------------------------------------------------------
int _txInitialize()
{
#if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER)
_CrtSetBreakAlloc (_TX_ALLOC_BREAK);
#endif
_TX_ON_DEBUG (OutputDebugString ("\n");
OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" "
"compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n");
OutputDebugString ("\n"));
_txMainThreadId = GetCurrentThreadId();
$1 _txIsDll = _txInDll();
$ if (!_txIsDll)
{
$ _txConsole = ! FindAtom ("_txConsole"); // Not a thread-safe
$ (void) AddAtom ("_txConsole");
}
$ if (_txConsole)
{
$ _txOnSignal();
$ SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
#if defined (_MSC_VER)
$ _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
$ _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
$ _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_WNDW);
$ _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_WNDW);
$ _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR);
$ _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
$ _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
#endif
#ifndef _MSC_VER_6
$ std::set_unexpected (_txOnUnexpected);
$ std::set_terminate (_txOnTerminate);
#endif
$ HWND console = _txConsole_Attach();
$ SetWindowTextA (console, txGetModuleFileName (false));
}
$ InitializeCriticalSection (&_txCanvas_LockBackBuf);
$ _txCanvas_UserDCs = new std::vector <HDC>;
#if defined (_GCC_VER)
$ _txSetProcAddress (GetModuleHandle (NULL), "MSVCRT.DLL", "_cexit", (PROC) _tx_cexit); // See _tx_cexit()
#endif
$ atexit (_txCleanup);
$ (void) Win32::SetDIBitsToDevice; // Just to suppress "defined but not used" warning
$ (void) Win32::GetDIBits;
$ (void) Win32::RoundRect;
$ (void) Win32::CreateRectRgn;
$ (void) Win32::GetBitmapDimensionEx;
$ (void) Win32::GetConsoleFontInfo;
$ if (_txConsole)
{
$ txSetConsoleAttr (0x07);
$ SetLastError (0);
$ unsigned old87 = 0, new87 = 0x0008001C; // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW
$ if (_controlfp_s (&old87, 0, 0) == 0)
{ $ (void) _controlfp_s (&old87, old87 & ~new87, 0x0008001F /* _MCW_EM */); }
}
$ return 1;
}
//}
//-----------------------------------------------------------------------------------------------------------------
HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/)
{
$1 if (!_txInitialized) _txInitialized = _txInitialize();
$ if (txWindow())
{
$ SetLastErrorEx (ERROR_INVALID_DATA, 0);
$ _TX_ON_DEBUG (TX_ERROR ("\a" "Îêíî ðèñîâàíèÿ óæå ñîçäàíî"));
$ return txWindow();
}
$ if (!_txIsDll)
{
$ _txMain = ! FindAtom ("_txMain"); // Not a thread-safe
$ (void) AddAtom ("_txMain");
}
$ if (_txWindowUpdateInterval < 10) { $ _txWindowUpdateInterval = 10; }
$ _txRunning = false;
// Store the size
$ static SIZE size = { ROUND (sizeX), ROUND (sizeY) };
$ if (centered) { size.cx *= -1; size.cy *= -1; }
// In Thread, where REAL creation lies...
#if !( defined (_MSC_VER) && (_MSC_VER < 1400) && !defined (_MT) )
$ unsigned id = 0;
$ _txCanvas_Thread = (HANDLE) _beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id);
#else
$ DWORD id = 0;
$ _txCanvas_Thread = CreateThread (NULL, 0, (PTHREAD_START_ROUTINE)_txCanvas_ThreadProc, &size, 0, &id);
#endif
$ if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."), (HWND)NULL;
$ _txWaitFor (_txRunning, 30*_TX_TIMEOUT);
$ if (!_txRunning) return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."),(HWND)NULL;
$ if (!txOK()) return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."), (HWND)NULL;
$ Sleep (100);
$ errno = _doserrno = 0;
$ SetLastError (0);
$ return txWindow();
}
//-----------------------------------------------------------------------------------------------------------------
bool txSetDefaults()
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ txUpdateWindow (false);
$ txAutoLock _lock;
$ RECT r = {0};
$ GetClientRect (_txCanvas_Window, &r) asserted;
$ SIZE szCanvas = { r.right - r.left, r.bottom - r.top };
$ GetClientRect (Win32::GetConsoleWindow(), &r) asserted;
$ SIZE szCon = { r.right - r.left, r.bottom - r.top };
$ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
$ CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {0}, 0, {0, 0, 80-1, 25-1}, {80, 25}};
$ GetConsoleScreenBufferInfo (out, &con);
$ SIZE szTxt = { (short) (con.srWindow.Right - con.srWindow.Left + 1),
(short) (con.srWindow.Bottom - con.srWindow.Top + 1) };
//{ Set defaults for graphics layer
$ _txBuffer_Select (Win32::GetStockObject (WHITE_PEN), txDC()) asserted;
$ _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), txDC()) asserted;
$ _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx,
0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH, _txConsoleFont),
txDC()) asserted;
$ (Win32::SetTextColor (txDC(), TX_WHITE) != CLR_INVALID) asserted;
$ Win32::SetBkMode (txDC(), TRANSPARENT) asserted;
$ Win32::SetROP2 (txDC(), R2_COPYPEN) asserted;
//}
//{ Set defaults for console layer
$ HGDIOBJ font = txFontExist (_txConsoleFont)?
Win32::CreateFont ((int) (1.0 * szCanvas.cy/szTxt.cy), (int) (1.0 * szCanvas.cx/szTxt.cx),
0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH, _txConsoleFont)
:
Win32::GetStockObject (SYSTEM_FIXED_FONT);
$ _txBuffer_Select (font, _txCanvas_BackBuf[1]) asserted;
//}
//{ Scroll the console for text to go above top of window and don't mix with graphics
$ if (con.dwCursorPosition.X) _putch ('\n');
$ short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top);
$ con.srWindow.Top = (short) (con.srWindow.Top + delta);
$ con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta);
$ SMALL_RECT src = {0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) };
$ CHAR_INFO fill = {{' '}, 0x07}; // Fill with spaces, light-gray on black
$ COORD dest = {0, (short) -delta}; // New UL-corner of src, scroll up
$ con.dwCursorPosition.X = 0;
$ con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta);
$ (con.srWindow.Bottom < con.dwSize.Y && // Move the "window"
SetConsoleWindowInfo (out, true, &con.srWindow))
||
(ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill), // Or scroll the buffer
SetConsoleCursorPosition (out, con.dwCursorPosition));
//}
$ txUpdateWindow (true);
return true;
}
//-----------------------------------------------------------------------------------------------------------------
inline bool txOK()
{
$1 return _txCanvas_OK();
}
//-----------------------------------------------------------------------------------------------------------------
// In GCC, implicit std(MSVCRT.dll)::_cexit() call before _txCleanup leads to hands in _cexit handlers chain.
// So redefining std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols in linking
// serveral modules including TXLib.h. See _txSetProcAddress() call in _txInitialize().
#if defined (_GCC_VER)
void _tx_cexit()
{
$1 _txCleanup();
if (Win32::_cexit) { $ Win32::_cexit(); }
$ return;
}
#endif
//-----------------------------------------------------------------------------------------------------------------
void _txCleanup()
{
$1 if (!_txInitialized) return;
else _txInitialized = false;
$ txSleep (_txWindowUpdateInterval);
$ _txRunning = false;
$ _txConsole_IsBlinking = false;
$ HWND canvas = txWindow();
$ HWND console = Win32::GetConsoleWindow();
$ unsigned thread = GetCurrentThreadId();
$ HWND wnd = (canvas)? canvas : console;
$ bool externTerm = (thread != _txMainThreadId &&
thread != _txCanvas_ThreadId);
$ DWORD parent = 0;
$ bool waitableParent = !externTerm && _txIsParentWaitable (&parent);
$ if (_txConsole)
{
$ if (_txMain) txSetConsoleAttr (0x07);
$ if (console) EnableWindow (console, true);
}
$ if (_txMain && !externTerm && wnd != NULL)
{ $ _txSetFinishedText (wnd); }
$ if ((canvas? _txMain : _txConsole && !waitableParent) && !_txExit &&
thread == _txMainThreadId)
{
$ if (wnd)
{
$ ShowWindow (wnd, SW_SHOW);
$ EnableWindow (wnd, true);
$ SetForegroundWindow (wnd);
$ BringWindowToTop (wnd);
$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW);
}
$ if (console)
{ $ _txPauseBeforeTermination (canvas); }
}
$ if (txWindow())
{ $ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); }
$ _txWaitFor (!txWindow(), 5*_TX_TIMEOUT);
$ if (!txWindow())
{ $ DeleteCriticalSection (&_txCanvas_LockBackBuf); _txCanvas_LockBackBuf = ZERO (CRITICAL_SECTION); }
$ if (_txCanvas_Thread)
{ $ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; }
$ delete _txCanvas_UserDCs; _txCanvas_UserDCs = NULL;
$ if (_txMain && canvas && waitableParent && _txNOP (_TX_ALLOW_KILL_PARENT))
{ $ waitableParent |= !_txKillProcess (parent); }
$ if (_txMain && _txConsole)
{ $ _txConsole_Detach (waitableParent && !externTerm); }
_TX_ON_DEBUG (OutputDebugString ("\n");
OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n");
OutputDebugString ("\n"));
}
//-----------------------------------------------------------------------------------------------------------------
int _txSetFinishedText (HWND wnd)
{
struct tools
{
static LRESULT getWindowText (HWND window, wchar_t text[], int size)
{
$1 memset (text, 0, size * sizeof (*text));
$ return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
}
static LRESULT setWindowText (HWND window, wchar_t text[])
{
$1 return SendMessageTimeoutW (window, WM_SETTEXT, 0, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
}
};
$1 static wchar_t title [_TX_BUFSIZE+15] = L"TXLib";
$ tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
$ unsigned len = (unsigned) wcslen (title); if (len >= _TX_BUFSIZE) len = _TX_BUFSIZE-1;
$ MultiByteToWideChar (_TX_CP, 0, " [ÇÀÂÅÐØÅÍÎ]", -1, title + len, _TX_BUFSIZE - len);
$ tools::setWindowText (wnd, title);
$ tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
$ if (len <= _TX_BUFSIZE-1-2 && title [len+2] == /* 'Ç' */ (wchar_t) 0x0417) return 0;
$ MultiByteToWideChar (_TX_CP, 0, " [FINISHED]", -1, title + len, _TX_BUFSIZE - len);
$ tools::setWindowText (wnd, title);
$ tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
$ if (len <= _TX_BUFSIZE-1-2 && title [len+2] == /* 'F' */ (wchar_t) 0x0046) return 1;
$ return 2;
}
//-----------------------------------------------------------------------------------------------------------------
void _txPauseBeforeTermination (HWND canvas)
{
$1 while (_kbhit()) (void)_getch();
$ CONSOLE_SCREEN_BUFFER_INFO con = {{0}};
$ bool kbRedir = !GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con);
$ bool kbWait = (_txGetInput() == EOF);
$ bool wine = !!Win32::wine_get_version;
$ if (kbWait && !canvas && !kbRedir && !wine)
{
$ printf ("\n" "[Íàæìèòå ëþáóþ êëàâèøó äëÿ çàâåðøåíèÿ]");
}
$ for (int i = 1; ; i++)
{
$ Sleep (_txWindowUpdateInterval);
if (!kbWait || (kbRedir && !canvas)) { $ break; } // No need to run and hide
if (!wine && _txGetInput() != EOF) { $ break; } // Somebody hit something.
if (canvas && !_txCanvas_ThreadId) { $ break; } // There was a window, and now there is not.
if (!Win32::GetConsoleWindow()) { $ break; } // Console was destroyed
if (Win32::GhostWindowFromHungWindow && Win32::GhostWindowFromHungWindow (canvas))
{ $ TX_ERROR ("Ïðèëîæåíèå çàâèñëî è áóäåò çàêðûòî."); break; }
if (canvas && Win32::IsHungAppWindow && Win32::IsHungAppWindow (canvas))
{ $ _txTrace (__FILE__, __LINE__, "WARNING: Ïðèëîæåíèå çàâèñëî è áóäåò çàêðûòî."); break; }
if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL))
{ $ _txTrace (__FILE__, __LINE__, "WARNING: Ïðèëîæåíèå íå îòâå÷àåò è áóäåò çàêðûòî."); break; }
if (!wine && !(i % 100500))
{ $ printf ("\r" "[Òàê íàæìèòå æå êàêóþ-íèáóäü êëàâèøó äëÿ ìîåãî çàâåðøåíèÿ]"); }
}
$ while (!wine && _kbhit()) (void)_getch();
$ printf ("\n");
}
//-----------------------------------------------------------------------------------------------------------------
int _txGetInput()
{
$1 HANDLE con = GetStdHandle (STD_INPUT_HANDLE);
$ DWORD nchars = 0;
$ if (GetConsoleMode (con, &nchars) == 0 &&
PeekNamedPipe (con, NULL, 0, NULL, &nchars, NULL))
{
$ return (nchars)? fgetc (stdin) : EOF;
}
$ if (_kbhit())
{
$ return _getch();
}
#if defined (_MSC_VER) && (_MSC_VER < 1700)
$ if (fseek (stdin, 1, SEEK_CUR) != EOF)
{
$ (void) fseek (stdin, -1, SEEK_CUR);
$ return fgetc (stdin); // This causes blocking in MSVC 2011 beta
}
#endif
$ return EOF;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txIsParentWaitable (DWORD* parentPID /*= NULL*/)
{
$1 PROCESSENTRY32* info = _txFindProcess();
$ if (!info) return false;
$ info = _txFindProcess (info->th32ParentProcessID);
$ if (!info) return false;
$ char parent [MAX_PATH] = "";
$ strncpy_s (parent, info->szExeFile, sizeof (parent) - 1);
$ if (parentPID) *parentPID = info->th32ProcessID;
$ info = _txFindProcess (info->th32ParentProcessID); // info: grandparent
$ char list[_TX_BUFSIZE] = _TX_WAITABLE_PARENTS;
$ char* ctx = NULL;
$ for (char* p = strtok_s (list, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx))
{
$ char* gp = strchr (p, ':');
$ if (gp)
{
$ *gp++ = 0;
$ if (_stricmp (p, parent) != 0) { continue; }
$ if (info) if (_stricmp (gp, info->szExeFile) == 0) // Was &&, but OMG MSVC /analyze..
{ $ return true; }
}
else
{
$ if (_stricmp (p, parent) == 0)
{ $ return true; }
}
}
$ return false;
}
//-----------------------------------------------------------------------------------------------------------------
PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/)
{
$1 static PROCESSENTRY32 info = { sizeof (info) };
$ if (!pid) return &info;
$ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
$ assert (sshot); if (!sshot) return NULL;
$ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
if (info.th32ProcessID == pid) break;
$ CloseHandle (sshot);
$ return &info;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txInDll()
{
$1 MODULEENTRY32 mod = { sizeof (mod) };
$ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
$ assert (sshot); if (!sshot) return false;
$ bool inDll = false;
$ for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod))
{
$ if (!mod.modBaseAddr) continue;
$ IMAGE_DOS_HEADER* dosHdr = (IMAGE_DOS_HEADER*) mod.modBaseAddr;
$ IMAGE_NT_HEADERS* ntHdr = (IMAGE_NT_HEADERS*) (mod.modBaseAddr + dosHdr->e_lfanew);
$ inDll = (dosHdr->e_magic == IMAGE_DOS_SIGNATURE &&
ntHdr->Signature == IMAGE_NT_SIGNATURE &&
(ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0);
$ if (In ((BYTE*)(ptrdiff_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize)) break;
}
$ CloseHandle (sshot);
$ return inDll;
}
//-----------------------------------------------------------------------------------------------------------------
// You are here, little hacker?
bool _txKillProcess (DWORD pid)
{
$1 _TX_IF_ARGUMENT_FAILED (pid) return false;
$ HANDLE token = INVALID_HANDLE_VALUE;
$ OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted;
$ LUID luid = {0};
$ LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted;
$ TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}};
$ TOKEN_PRIVILEGES old = {0};
$ DWORD oldSz = 0;
$ AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted;
$ HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid);
$ if (!proc) return false;
$ bool ok = !!TerminateProcess (proc, 0);
$ CloseHandle (proc);
$ return ok;
}
//-----------------------------------------------------------------------------------------------------------------
// TXLib continues to hack the reality to make your life better, sweeter and easier
PROC _txSetProcAddress (HMODULE module, const char* dllName, const char* funcName, PROC newFunc)
{
$1 _TX_IF_ARGUMENT_FAILED (module) return NULL;
$ _TX_IF_ARGUMENT_FAILED (dllName) return NULL;
$ _TX_IF_ARGUMENT_FAILED (newFunc) return NULL;
$ HMODULE dll = GetModuleHandle (dllName);
$ if (!dll) return NULL;
$ PROC oldFunc = GetProcAddress (dll, funcName);
$ if (!oldFunc) return NULL;
#define RVA_( type, addr ) ( (type) ((ptrdiff_t) module + (ptrdiff_t) (addr)) )
$ IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, 0);
$ IMAGE_NT_HEADERS* ntHdr = RVA_ (IMAGE_NT_HEADERS*, dosHdr->e_lfanew);
$ if (dosHdr->e_magic != IMAGE_DOS_SIGNATURE ||
ntHdr ->Signature != IMAGE_NT_SIGNATURE) return NULL;
$ DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
$ IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, impOffset);
$ if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return NULL;
$ IMAGE_THUNK_DATA* thunk = NULL;
$ bool found = false;
for (; desc->Name; desc++)
{
$ if (_stricmp (RVA_ (const char*, desc->Name), dllName) != 0) continue;
$ for (thunk = RVA_ (IMAGE_THUNK_DATA*, desc->FirstThunk); thunk->u1.Function; thunk++)
if ((ptrdiff_t) thunk->u1.Function == (ptrdiff_t) oldFunc) { found = true; break; }
$ if (found) break;
}
$ if (!found) return NULL;
$ *(PROC*)& thunk->u1.Function = newFunc; // In different MS-SDKs this field has different types (DWORD/DWORD*/etc)
$ return oldFunc;
#undef RVA_
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ [Internal] TXLib window functions (_txCanvas...)
//! @name Ôóíêöèè îêíà TXLib (_txCanvas...)
//=================================================================================================================
//{
#if defined (_MSC_VER_6) || defined (_GCC_VER) && (_GCC_VER <= 345)
#define SetClassLong_ SetClassLong
#define GCL_HICON_ GCL_HICON
#define GCL_HICONSM_ GCL_HICONSM
#define GCL_HCURSOR_ GCL_HCURSOR
#else
#define SetClassLong_ SetClassLongPtr
#define GCL_HICON_ GCLP_HICON
#define GCL_HICONSM_ GCLP_HICONSM
#define GCL_HCURSOR_ GCLP_HCURSOR
#endif
//}
unsigned WINAPI _txCanvas_ThreadProc (void* data)
{
$1 _txCanvas_ThreadId = GetCurrentThreadId();
$ _TX_IF_ARGUMENT_FAILED (data) return false;
$ HWND wnd = _txCanvas_CreateWindow ((SIZE*) data);
$ if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas"), 0;
$ HICON icon32 = LoadIcon (GetModuleHandle (NULL), "_TX_ICON");
$ HICON icon16 = LoadIcon (GetModuleHandle (NULL), "_TX_ICONSM");
$ HCURSOR cursor = LoadCursor (GetModuleHandle (NULL), "_TX_CURSOR");
$ SetClassLong_ (wnd, GCL_HICON_, (DWORD)(ptrdiff_t) (icon32? icon32 : _txCreateTXIcon (32)));
$ SetClassLong_ (wnd, GCL_HICONSM_, (DWORD)(ptrdiff_t) (icon16? icon16 : _txCreateTXIcon (16)));
$ SetClassLong_ (wnd, GCL_HCURSOR_, (DWORD)(ptrdiff_t) (cursor? cursor : LoadCursor (NULL, IDC_ARROW)));
$ HACCEL accel = LoadAccelerators (NULL, "_TX_ACCELERATORS");
_TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n"));
$ _txRunning = true;
$ ShowWindow (wnd, SW_SHOW);
$ SetForegroundWindow (wnd);
$ UpdateWindow (wnd);
$ MSG msg = {0};
$ while (GetMessage (&msg, NULL, 0, 0))
{
$ if (!msg.hwnd) continue;
$ if (accel != NULL && TranslateAccelerator (wnd, accel, &msg)) continue;
$ TranslateMessage (&msg);
$ DispatchMessage (&msg);
$ Sleep (0);
}
$ if (icon16) DestroyIcon (icon16); // If Explorer is displaying Tray Notification, these
$ if (icon32) DestroyIcon (icon32); // calls will possibly fail, and we'll get resource leak.
$ LeaveCriticalSection (&_txCanvas_LockBackBuf);
$ if (_txRunning && _txMain) // Main window is destroyed but main() is still running.
{ // No chances for good termination, so use exit().
$ exit ((int) msg.wParam);
}
_TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n"));
$ _txCanvas_ThreadId = 0;
$ return true;
}
//{
#undef SetClassLong
#undef GCL_HICON_
#undef GCL_HICONSM_
#undef GCL_HCURSOR_
//}
//-----------------------------------------------------------------------------------------------------------------
HWND _txCanvas_CreateWindow (SIZE* size)
{
$1 _TX_IF_ARGUMENT_FAILED (size) return NULL;
$ static char className[_TX_BUFSIZE] = "";
$ _snprintf_s (className, sizeof (className) - 1 _TX_TRUNCATE,
"/*---[TXLib]-------------------------- "
_TX_VERSION " " __FILE__ " WndClass %08X "
"--------------------------[TXLib]---*/", (int) GetTickCount());
$ WNDCLASSEX wc = { sizeof (wc) };
$ wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
$ wc.lpfnWndProc = _txCanvas_WndProc;
$ wc.hCursor = LoadCursor (NULL, IDC_ARROW);
$ wc.hbrBackground = (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH);
$ wc.lpszClassName = className;
$ ATOM wndclass = RegisterClassEx (&wc);
$ if (!wndclass) return TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed" _ className), (HWND) NULL;
$ int centered = false;
$ if (size->cx < 0 && size->cy < 0) { size->cx *= -1; size->cy *= -1; centered = true; }
$ SIZE scr = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) };
$ RECT r = { 0, 0, size->cx, size->cy }; AdjustWindowRect (&r, _txWindowStyle, false);
$ SIZE sz = { r.right - r.left, r.bottom - r.top };
$ HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, className, txGetModuleFileName (false), _txWindowStyle,
centered? scr.cx/2 - sz.cx/2 : CW_USEDEFAULT,
centered? scr.cy/2 - sz.cy/2 : CW_USEDEFAULT,
sz.cx, sz.cy, NULL, NULL, NULL, NULL);
$ if (!wnd || !txWindow()) return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx (\"%s\") failed" _ className), (HWND) NULL;
$ HMENU menu = GetSystemMenu (txWindow(), false);
$ if (!menu) return txWindow();
$ AppendMenu (menu, MF_SEPARATOR, 0, NULL) asserted;
$ AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted;
$ AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT, "&About...") asserted;
$ HWND console = Win32::GetConsoleWindow();
$ DWORD proc = 0;
$ GetWindowThreadProcessId (console, &proc);
$ if (console && (proc == GetCurrentProcessId() || _txIsParentWaitable()))
{ $ ShowWindow (console, _txConsoleMode); }
$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED));
$ return txWindow();
}
//-----------------------------------------------------------------------------------------------------------------
inline bool _txCanvas_OK()
{
$1 return _txCanvas_ThreadId &&
_txCanvas_Window &&
_txCanvas_BackBuf[0] &&
_txCanvas_BackBuf[1];
}
//-----------------------------------------------------------------------------------------------------------------
int _txCanvas_SetRefreshLock (int count)
{
$1 int oldCount = _txCanvas_RefreshLock;
$ _txCanvas_RefreshLock = count;
$ HWND wnd = txWindow();
$ if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd)
{ $ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
$ return oldCount;
}
//-----------------------------------------------------------------------------------------------------------------
HICON _txCreateTXIcon (int size)
{
$1 _TX_IF_ARGUMENT_FAILED (size == 32 || size == 16) return NULL;
$ const char image32 [32*32+1] =
"00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0"
"0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0"
"0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0"
"0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0"
"0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0"
"0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0"
"0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0"
"0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000";
$ const char image16 [16*16+1] =
"0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990"
"0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000";
$ const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0,
0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff };
$ const char* image = (size == 32)? image32 : image16;
$ POINT sz = { size, size };
$ HDC dcMask = _txBuffer_Create (txWindow(), &sz); assert (dcMask);
$ HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor);
$ for (int i = 0; i < size*size; i++)
{
assert (In (image[i], '0', '9') || In (image[i], 'A', 'F'));
Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']);
}
$ ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask, OBJ_BITMAP),
(HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) };
$ HICON icon = CreateIconIndirect (&info);
$ assert (icon);
$ _txBuffer_Delete (&dcMask) asserted;
$ _txBuffer_Delete (&dcColor) asserted;
$ return icon;
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ [Internal] Main window event handlers (_txCanvas_On...)
//! @name Ñîáûòèÿ îñíîâíîãî îêíà (_txCanvas_On...)
//=================================================================================================================
//! @{
LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
{
#ifdef _TX_ALLOW_TRACE
_txInTX++;
if (_txAllowTrace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__,
"%*s" "0x%X <- 0x%03X (0x%08X, 0x%08lX)", 12 - _txInTX*2, "", wnd, msg, wpar, lpar);
_txInTX--;
#endif
$1 if (msg == WM_KEYDOWN && wpar == VK_F12 &&
GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU))
{
$ _txCanvas_OnCmdABOUT (wnd, wpar);
$ return DefWindowProc (wnd, msg, wpar, lpar);
}
WNDPROC altWndProc = _txAltWndProc; // Cache to prevent change from main thread
if (altWndProc)
{
$ LRESULT res = altWndProc (wnd, msg, wpar, lpar);
$ if (res) return res;
}
switch (msg)
{
case WM_CREATE: $ _txCanvas_OnCREATE (wnd); return 0;
case WM_CLOSE: $ if (_txCanvas_OnCLOSE (wnd)) break; else return 0;
case WM_DESTROY: $ _txCanvas_OnDESTROY (wnd); return 0;
case WM_PAINT: $ _txCanvas_OnPAINT (wnd); return 0;
case WM_TIMER: $ _txCanvas_OnTIMER (wnd, wpar); return 0;
case WM_KEYDOWN: $ _txCanvas_OnKEYDOWN (wnd, wpar, lpar); return 0;
case WM_CHAR: $ _txCanvas_OnCHAR (wnd, wpar, lpar); return 0;
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MOUSEMOVE: $ _txCanvas_OnMOUSEMOVE (wnd, wpar, lpar); return 0;
default: break;
}
if (msg == WM_SYSCOMMAND) switch (wpar)
{
case _TX_IDM_ABOUT: $ _txCanvas_OnCmdABOUT (wnd, wpar); return 0;
case _TX_IDM_CONSOLE: $ _txCanvas_OnCmdCONSOLE (wnd, wpar); return 0;
default: break;
}
$ return DefWindowProc (wnd, msg, wpar, lpar);
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnCREATE (HWND wnd)
{
$1 _TX_IF_ARGUMENT_FAILED (wnd) return false;
$ _txCanvas_BackBuf[0] = _txBuffer_Create (wnd); assert (_txCanvas_BackBuf[0]);
$ _txCanvas_BackBuf[1] = _txBuffer_Create (wnd); assert (_txCanvas_BackBuf[1]);
$ SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL) asserted;
$ _txCanvas_Window = wnd;
$ txSetDefaults();
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnDESTROY (HWND wnd)
{
$1 _TX_IF_ARGUMENT_FAILED (wnd) return false;
// Èíèöèèðóåì îñòàíîâêó öèêëà ñîîáùåíèé
$ PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS);
$ if (!_txCanvas_Window) return false;
// Indicate that we are about to manually terminate
$ _txExit = true;
// Lock GDI resources
$ bool locked = false;
$ _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT);
$ if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources");
// Îñâîáîæäàåì ïîëüçîâàòåëüñêèå ðåñóðñû
$ if (_txCanvas_UserDCs && _txCanvas_UserDCs->size())
{
$ txNotifyIcon (NIIF_ERROR, NULL, "Âû çàáûëè îñâîáîäèòü %d HDC.", (int) _txCanvas_UserDCs->size());
$ Sleep (_TX_TIMEOUT);
$ for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i));
$ _txCanvas_UserDCs->clear();
}
// Îñâîáîæäàåì ðåñóðñû, ñâÿçàííûå ñ îêíîì
$ if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted;
$ if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1]) asserted;
$ if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0]) asserted;
$ txUnlock();
// Indicate that we are destroyed
$ _txCanvas_Window = NULL;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnCLOSE (HWND wnd)
{
$1 _TX_IF_ARGUMENT_FAILED (wnd && _txCanvas_OK()) return false;
$ if (_txMain && _txRunning &&
txMessageBox ("Ôóíêöèÿ main() íå çàâåðøåíà. Ïðîãðàììà âñå åùå ðàáîòàåò. Ïðåðâàòü àâàðèéíî? \n\n"
"Ëó÷øå ïîäîæäàòü, êîãäà main() çàâåðøèòñÿ - ýòî îòîáðàæàåòñÿ â çàãîëîâêå îêíà.",
txGetModuleFileName (false), MB_OKCANCEL | MB_ICONSTOP) != IDOK) return false;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnTIMER (HWND wnd, WPARAM)
{
$1 _TX_IF_ARGUMENT_FAILED (wnd) return false;
$ if (_txCanvas_RefreshLock > 0 || !_txRunning) return false;
$ InvalidateRect (wnd, NULL, false) asserted;
$ UpdateWindow (wnd) asserted;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnPAINT (HWND wnd)
{
$1 _TX_IF_ARGUMENT_FAILED (wnd && _txCanvas_OK()) return false;
$ bool forceRedraw = GetAsyncKeyState (VK_MENU) && GetAsyncKeyState (VK_CONTROL) &&
GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT);
$ PAINTSTRUCT ps = {0};
$ HDC dc = BeginPaint (wnd, &ps);
$ if (!dc) return false;
$ RECT r = {0};
$ GetClientRect (wnd, &r) asserted;
$ POINT size = { r.right - r.left, r.bottom - r.top };
$ if ((_txCanvas_RefreshLock <= 0 || forceRedraw) &&
txLock (false))
{
$ Win32::BitBlt (_txCanvas_BackBuf[1], 0, 0, size.x, size.y, txDC(), 0, 0, SRCCOPY);
$ _txConsole_Draw (_txCanvas_BackBuf[1]);
$ txUnlock();
}
// Magic 100500 value is used to completely block screen refresh.
// Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL.
// Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers
// themselves.
// Yes guys, with all your software installed. :(
$ if (_txCanvas_RefreshLock != 100500)
{ $ Win32::BitBlt (dc, 0, 0, size.x, size.y, _txCanvas_BackBuf[1], 0, 0, SRCCOPY); }
$ EndPaint (wnd, &ps) asserted;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnKEYDOWN (HWND, WPARAM vk, LPARAM info)
{
$1 INPUT_RECORD evt = {0};
$ evt.EventType = KEY_EVENT;
$ evt.Event.KeyEvent.bKeyDown = true;
$ evt.Event.KeyEvent.wRepeatCount = 1;
$ evt.Event.KeyEvent.uChar.AsciiChar = (unsigned char) MapVirtualKey ((WORD) vk, 2); // 2 == MAPVK_VK_TO_CHAR
$ evt.Event.KeyEvent.wVirtualScanCode = (unsigned char) (info >> 16);
$ evt.Event.KeyEvent.wVirtualKeyCode = (WORD) vk;
$ evt.Event.KeyEvent.dwControlKeyState = (info & (1 << 24))? ENHANCED_KEY : 0;
$ if (evt.Event.KeyEvent.uChar.AsciiChar) return false; // Let TranslateMessage() and WM_CHAR do the job
$ DWORD written = 0;
$ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written);
$ return false;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info)
{
$1 INPUT_RECORD evt = {0};
$ evt.EventType = KEY_EVENT;
$ evt.Event.KeyEvent.bKeyDown = true;
$ evt.Event.KeyEvent.wRepeatCount = 1;
$ evt.Event.KeyEvent.uChar.AsciiChar = (unsigned char) (ch);
$ evt.Event.KeyEvent.wVirtualScanCode = (unsigned char) (info >> 16);
$ evt.Event.KeyEvent.wVirtualKeyCode = (WORD) MapVirtualKey ((WORD) (info >> 16), 3); // 3 == MAPVK_VSC_TO_VK_EX
$ evt.Event.KeyEvent.dwControlKeyState = 0;
$ DWORD written = 0;
$ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written);
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnMOUSEMOVE (HWND, WPARAM buttons, LPARAM coords)
{
$1 _TX_IF_ARGUMENT_FAILED (_txCanvas_OK()) return false;
$ _txMousePos.x = LOWORD (coords);
$ _txMousePos.y = HIWORD (coords);
$ _txMouseButtons = (int) buttons;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd)
{
$1 _TX_IF_ARGUMENT_FAILED (wnd) return false;
$ HWND console = Win32::GetConsoleWindow();
$ if (!console) return false;
$ bool visible = !!IsWindowVisible (console);
$ ShowWindow (console, visible? SW_HIDE : SW_SHOW);
$ visible = !!IsWindowVisible (console);
$ CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED);
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txCanvas_OnCmdABOUT (HWND, WPARAM)
{
$1 //{ Overriding the missing names, if the set is uncomplete
#if defined (__MODULE)
#define ABOUT_NAME_ __MODULE
#else
#define ABOUT_NAME_ "TXLib"
#endif
#if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
#ifndef __MODULE
#define __MODULE "TXLib" "\n" "#define __MODULE to set the name.\n"
#endif
#ifndef __VERSION
#define __VERSION "(0.000000000)." "\n" "#define __VERSION to set the string value.\n"
#endif
#ifndef __DESCRIPTION
#define __DESCRIPTION "(Äà, ìíå ëåíü çàäàòü îïèñàíèå)." "\n" "#define __DESCRIPTION to override project role.\n"
#endif
#ifndef __AUTHOR
#define __AUTHOR "(Íåïîíÿòíî êòî)." "\n" "#define __AUTHOR to override this name."
#endif
#endif
//}
$ time_t timeT = time (NULL) - clock()/CLOCKS_PER_SEC;
$ char timeS[32] = "";
$ ctime_s (timeS, sizeof (timeS), &timeT);
$ static char text[_TX_BUFSIZE] = "";
$ char cwd [MAX_PATH] = "";
$ _snprintf_s (text, sizeof (text) - 1 _TX_TRUNCATE,
"Application:\n"
#if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
__MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n"
#else
"Çäåñü ìîãëà áû áûòü Âàøà ðåêëàìà :)\n"
"#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n"
#endif
"\n" "Developed with:\n\n"
"The Dumb Artist Library (TX Library) - " _TX_VERSION "\n" _TX_AUTHOR "\n"
"See license on: http://txlib.ru\n\n"
"TXLib file:" "\t" __FILE__ "\n"
"Compiled:" "\t" __DATE__ " " __TIME__ ", " _TX_BUILDMODE ", " __TX_COMPILER__ "\n"
"Started:" "\t" "%.6s %.4s %.8s\n\n"
"Run file:" "\t" "%s\n"
"Directory:" "\t" "%s",
timeS + 4, timeS + 20, timeS + 11, // These offsets are ANSI standardized
txGetModuleFileName(),
_getcwd (cwd, sizeof (cwd) - 1));
$ txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION);
// And a bit of HTTP-code in C++ function:
goto http;
http://txlib.ru // See valuable refs here :)
$ return true;
#undef ABOUT_NAME_
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ [Internal] Console-support functions (_txConsole...)
//! @name Ôóíêöèè êîíñîëüíîãî îêíà (_txConsole...)
//=================================================================================================================
//! @{
HWND _txConsole_Attach()
{
$1 HWND console = Win32::GetConsoleWindow();
$ if (!console)
{
$ FreeConsole();
$ AllocConsole();
}
$ console = Win32::GetConsoleWindow();
$ if (!console) return NULL;
// Linux::Wine v1.2.2+ compatibility.
// Beer compatibility will be added in future versions.
// Ìèíçäðàâ ÐÔ ïðåäóïðåæäàåò: ÷ðåçìåðíîå óïîòðåáëåíèå wine âðåäèò Âàøåìó çäîðîâüþ.
$ if (Win32::wine_get_version)
{
$ Win32::GetNumberOfConsoleFonts = NULL;
$ Win32::GetCurrentConsoleFont = NULL;
$ Win32::SetConsoleFont = NULL;
}
// Óñòàíàâëèâàåì ðóññêóþ êîäîâóþ ñòðàíèöó äëÿ êîíñîëè Windows
$ SetConsoleCP (_TX_CP); // 1251
$ SetConsoleOutputCP (_TX_CP); // 1251
// Óñòàíàâëèâàåì ðóññêóþ êîäîâóþ ñòðàíèöó äëÿ ñòàíäàðòíîé áèáëèîòåêè, èíà÷å íå áóäóò ðàáîòàòü Unicode-âåðñèè
// ôóíêöèé (wprintf, ...). Åñëè êîìïèëèòå ñ ïîìîùüþ gcc è ñîáèðàåòåñü èñïîëüçîâàòü L"unicode-ñòðîêè" ñ ðóññêèì
// ÿçûêîì, óêàæèòå îïöèè â êîìàíäíîé ñòðîêå êîìïèëÿòîðà g++: -finput-charset=CP1251 -fexec-charset=CP1251.
$ setlocale (LC_CTYPE, _TX_LC_CTYPE); // "Russian"
$ if (!Win32::wine_get_version) _wsetlocale (LC_CTYPE, _TX_LC_CTYPE_W); // L"Russian_Russia.ACP"
$ static bool done = false;
$ if (done) return console;
// Âïå÷àòëèòåëüíûì ëó÷øå ñþäà íå ñìîòðåòü.
$ if (!Win32::wine_get_version)
{ $ _txConsole_SetUnicodeFont(); }
#ifndef _CONSOLE
// Ïåðåîòêðûâàåì çàíîâî <s>Àìåðèêó</s> ïîòîêè ââîäà-âûâîäà, åñëè subsystem != console
$ *stdin = *_fdopen (_open_osfhandle ((DWORD)(ptrdiff_t) GetStdHandle (STD_INPUT_HANDLE), _O_TEXT), "r");
$ fflush (stdout); *stdout = *_fdopen (_open_osfhandle ((DWORD)(ptrdiff_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w");
$ fflush (stderr); *stderr = *_fdopen (_open_osfhandle ((DWORD)(ptrdiff_t) GetStdHandle (STD_ERROR_HANDLE), _O_TEXT), "w");
$ setvbuf (stdin, NULL, _IONBF, 0);
$ setvbuf (stdout, NULL, _IONBF, 0);
$ setvbuf (stderr, NULL, _IONBF, 0);
$ std::ios::sync_with_stdio();
#endif
// That's all, folks
$ done = true;
$ return console;
}
//-----------------------------------------------------------------------------------------------------------------
inline bool _txConsole_OK()
{
$1 return Win32::GetConsoleWindow() != NULL;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txConsole_Detach (bool activate)
{
$1 HWND console = Win32::GetConsoleWindow();
$ if (!console) return false;
$ EnableWindow (console, true);
$ ShowWindow (console, SW_SHOW);
$ if (activate)
{
$ SetForegroundWindow (console);
$ BringWindowToTop (console);
}
$ return !!FreeConsole();
}
//-----------------------------------------------------------------------------------------------------------------
bool _txConsole_Draw (HDC dc)
{
$1 _TX_IF_ARGUMENT_FAILED (dc) return false;
$ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
$ CONSOLE_SCREEN_BUFFER_INFO con = {{0}};
$ BOOL ok = GetConsoleScreenBufferInfo (out, &con);
$ if (!ok) return false;
$ POINT size = { con.srWindow.Right - con.srWindow.Left + 1,
con.srWindow.Bottom - con.srWindow.Top + 1 };
$ SIZE fontSz = { 12, 16 };
$ Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted;
$ COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF };
$ for (int y = 0; y < size.y; y++)
{
static char chr [_TX_BUFSIZE + 1] = ""; // [con.dwSize.X + 1]; maybe will be truncated
static WORD atr [_TX_BUFSIZE + 1] = {0}; // [con.dwSize.X + 1]; maybe will be truncated
COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) };
DWORD read = 0;
if (!ReadConsoleOutputCharacter (out, chr, SIZEARR (chr) - 1, coord, &read)) continue;
if (!ReadConsoleOutputAttribute (out, atr, SIZEARR (atr) - 1, coord, &read)) continue;
for (int x = 0, xEnd = size.x; x < size.x; x = xEnd)
{
Win32::SetTextColor (dc, pal [ atr[x] & 0x0F]);
Win32::SetBkColor (dc, pal [(atr[x] >> 4) & 0x0F]);
Win32::SetBkMode (dc, (atr[x] & 0xF0)? OPAQUE : TRANSPARENT);
for (xEnd = x+1; atr[xEnd] == atr[x] && xEnd < size.x; xEnd++) ;
Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)),
ROUND (fontSz.cy * y), chr + x, xEnd - x) asserted;
}
}
$ Win32::SetTextColor (dc, pal [ con.wAttributes & 0x0F]);
$ Win32::SetBkColor (dc, pal [(con.wAttributes >> 4) & 0x0F]);
$ Win32::SetBkMode (dc, TRANSPARENT);
$ if (_txConsole_IsBlinking &&
In (con.dwCursorPosition, con.srWindow) &&
GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval &&
GetForegroundWindow() == txWindow())
{
$ Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)),
ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1,
"_", 1) asserted;
}
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
//{ Welcome to the Duck Side! Together we will rule the Bathroom!
//-----------------------------------------------------------------------------------------------------------------
bool _txConsole_SetUnicodeFont()
{
// Íà÷èíàÿ ñ Âèñòû âñå õîðîøî...
$1 if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx)
{
$ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
$ Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) };
$ if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false;
$ info.FontFamily = 0x36; // Unicode fixed-pitch
$ if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2); // Terminal font is too small
$ wcsncpy_s (info.FaceName, L"Lucida Console", SIZEARR (info.FaceName));
$ return !!Win32::SetCurrentConsoleFontEx (out, false, &info);
}
// ...à äî ýòîãî âñå íå òàê ñëàäêî
$ const unsigned uniFont = 10; // The Internet and W2K sources know this magic number
$ const unsigned uniSize = 20; // Size of the font desired, should be > max of Raster Fonts
$ bool ok = true;
// Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font.
$ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
$ if (Win32::GetNumberOfConsoleFonts && Win32::GetNumberOfConsoleFonts() <= uniFont)
{
$ HRESULT init = Win32::CoInitialize (NULL);
$ size_t sz = 0;
$ char link [MAX_PATH] = "";
$ getenv_s (&sz, link, sizeof (link) - 1, "TEMP");
$ strncat_s (link, "\\~txLink.lnk", sizeof (link) - 1);
$ char comspec [MAX_PATH] = "";
$ getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC");
$ (void) _unlink (link);
$ _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted;
$ ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32); // Sic!
if (ok) { $ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); }
$ (void) _unlink (link);
$ if (init == S_OK) Win32::CoUninitialize();
}
// If Unicode font is not already set, do set it.
$ CONSOLE_FONT_INFO cur = {0};
if (Win32::GetCurrentConsoleFont) { $ Win32::GetCurrentConsoleFont (out, false, &cur); }
$ ok &= (cur.nFont >= uniFont);
if (!ok) { $ ok &= Win32::SetConsoleFont && Win32::SetConsoleFont (out, uniFont); }
$ HWND console = Win32::GetConsoleWindow();
$ InvalidateRect (console, NULL, false);
$ UpdateWindow (console);
$ return ok;
}
//-----------------------------------------------------------------------------------------------------------------
//{ The nightmare helpers
#define _TX_TRY { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error;
#define _TX_CHECKED( cmd ) { if (FAILED (__tx_error = (cmd))) goto __tx_catch; }
#define _TX_FAIL { __tx_error = E_FAIL; goto __tx_catch; }
#define _TX_RETRY { __tx_error = S_OK; goto __tx_try; }
#define _TX_OK ( SUCCEEDED (__tx_error) )
#define _TX_CATCH goto __tx_finally; __tx_catch:
#define _TX_RETURN goto __tx_finally;
#define _TX_FINALLY __tx_finally:
#define _TX_ENDTRY }
//}
//-----------------------------------------------------------------------------------------------------------------
// Ìàëî íå ïîêàæåòñÿ
bool _txCreateShortcut (const char shortcutName[],
const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/,
const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/,
int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/)
{
$1 _TX_IF_ARGUMENT_FAILED (shortcutName && *shortcutName) return false;
$ _TX_IF_ARGUMENT_FAILED (fileToLink && *fileToLink) return false;
$ IShellLink* shellLink = NULL;
$ Win32::IShellLinkDataList* dataList = NULL;
$ IPersistFile* file = NULL;
$ HRESULT init = Win32::CoInitialize (NULL);
_TX_TRY
{
$ _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink));
$ if (!shellLink) _TX_FAIL;
$ shellLink->SetPath (fileToLink);
$ shellLink->SetArguments (args);
$ shellLink->SetWorkingDirectory (workDir);
$ shellLink->SetDescription (description);
$ shellLink->SetShowCmd (cmdShow);
$ shellLink->SetIconLocation (iconFile, iconIndex);
$ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList));
$ if (!dataList) _TX_FAIL;
$ Win32::NT_CONSOLE_PROPS props =
{{sizeof (props), NT_CONSOLE_PROPS_SIG},
0x07, 0xF5, // wFillAttribute, wPopupFillAttribute
{bufSize.X, bufSize.Y}, // dwScreenBufferSize
{wndSize.X, wndSize.Y}, // dwWindowSize
{wndOrg.X, wndOrg.Y}, // dwWindowOrigin
0, // nFont
0, // nInputBufferSize
{0, (short) fontSize}, // dwFontSize
0x36, 400, L"Lucida Console", // uFontFamily, uFontWeight, FaceName. We're dancing for this!
15, // uCursorSize
0, 1, 1, 0, // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition
50, 4, 0, // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup
{0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF}
};
$ _TX_CHECKED (dataList->AddDataBlock (&props));
$ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file));
$ if (!file) _TX_FAIL;
$ wchar_t wName[MAX_PATH] = L"";
$ MultiByteToWideChar (_TX_CP, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName));
$ _TX_CHECKED (file->Save (wName, true));
}
$ _TX_CATCH
$ _TX_FINALLY
$ if (file) file ->Release();
$ if (dataList) dataList ->Release();
$ if (shellLink) shellLink->Release();
$ if (init == S_OK) Win32::CoUninitialize();
$ return _TX_OK;
_TX_ENDTRY
}
//}
//-----------------------------------------------------------------------------------------------------------------
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ [Internal] Memory DC functions (_txBuffer...)
//! @name Ôóíêöèè "âèðòóàëüíîãî õîëñòà" (ãðàôè÷åñêîãî áóôåðà, _txBuffer...)
//=================================================================================================================
//! @{
HDC _txBuffer_Create (HWND wnd, const POINT* size, HBITMAP bitmap)
{
$1 txAutoLock _lock;
$ HDC wndDC = GetDC (wnd);
$ if (!wndDC) return NULL;
$ RECT r = {0};
$ if (wnd) GetClientRect (wnd, &r) asserted;
$ POINT sz = { r.right - r.left, r.bottom - r.top };
$ if (!size) size = &sz;
$ HDC dc = Win32::CreateCompatibleDC (wndDC);
$ if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed");
$ HBITMAP bmap = bitmap? bitmap : Win32::CreateCompatibleBitmap (wndDC, size->x, size->y);
$ if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed");
$ Win32::SelectObject (dc, bmap) asserted;
$ if (!bitmap) Win32::PatBlt (dc, 0, 0, size->x, size->y, BLACKNESS) asserted;
$ ReleaseDC (wnd, wndDC) asserted;
$ return dc;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txBuffer_Delete (HDC* dc)
{
$1 _TX_IF_ARGUMENT_FAILED (dc) return false;
$ if (!*dc) return false;
$ if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false;
$ txAutoLock _lock;
$ _txBuffer_Select (Win32::GetStockObject (NULL_PEN), *dc) asserted;
$ _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH), *dc) asserted;
$ _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted;
$ _txBuffer_Select (Win32::CreateCompatibleBitmap (*dc, 0, 0), *dc) asserted;
$ Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted;
$ Win32::DeleteDC (*dc) asserted;
$ *dc = NULL;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/)
{
$1 _TX_IF_ARGUMENT_FAILED (obj) return false;
$ _TX_IF_ARGUMENT_FAILED (dc) return false;
$ if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type");
$ txAutoLock _lock;
$ obj = Win32::SelectObject (dc, obj);
$ if (obj) Win32::DeleteObject (obj) asserted;
$ return obj != NULL;
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ Diagnostics
//! @name Äèàãíîñòèêà
//=================================================================================================================
//! @{
void _txOnSignal (int sig/* = 0*/, int fpe/* = 0*/)
{
if (!sig && !fpe)
{
$1 signal (SIGSEGV, (void(*)(int))_txOnSignal) != SIG_ERR asserted;
$ signal (SIGFPE, (void(*)(int))_txOnSignal) != SIG_ERR asserted;
$ signal (SIGABRT, (void(*)(int))_txOnSignal) != SIG_ERR asserted;
$ signal (SIGILL, (void(*)(int))_txOnSignal) != SIG_ERR asserted;
$ signal (SIGTERM, (void(*)(int))_txOnSignal) != SIG_ERR asserted;
$ return;
}
const char* sSig = ": Íåèçâåñòíûé òèï ñèãíàëà";
const char* sFPE = ": Íåèçâåñòíûé òèï èñêëþ÷åíèÿ";
#define GET_DESCR_( str, code, descr ) case (code): { (str) = #code ": " descr; break; }
switch (sig)
{
GET_DESCR_ (sSig, SIGSEGV, "Äîñòóï ïî íåâåðíîìó óêàçàòåëþ. Ñòàâüòå àññåðòû!")
GET_DESCR_ (sSig, SIGILL, "Ïîïûòêà âûïîëíèòü íåäîïóñòèìóþ îïåðàöèþ. Ïðîâåðüòå óêàçàòåëè íà ôóíêöèè.")
GET_DESCR_ (sSig, SIGABRT, "Àâàðèéíîå çàâåðøåíèå ïðîãðàììû, âûçâàíà ôóíêöèÿ abort().")
GET_DESCR_ (sSig, SIGTERM, "Ïîëó÷åí ñèãíàë ïðèíóäèòåëüíîãî çàâåðøåíèÿ ïðîãðàììû.")
GET_DESCR_ (sSig, SIGFPE, "Ãðóáàÿ îøèáêà â âû÷èñëåíèÿõ, äåëåíèå íà 0 èëè ÷òî-íèáóäü åùå")
default: break;
}
if (sig == SIGFPE) switch (fpe)
{
GET_DESCR_ (sFPE, 0x81 /* _FPE_INVALID */, "Ðåçóëüòàò íåâåðåí")
GET_DESCR_ (sFPE, 0x82 /* _FPE_DENORMAL */, "Äåíîðìàëèçàöèÿ")
GET_DESCR_ (sFPE, 0x83 /* _FPE_ZERODIVIDE */, "Äåëåíèå íà íîëü")
GET_DESCR_ (sFPE, 0x84 /* _FPE_OVERFLOW */, "Ðåçóëüòàò ñëèøêîì áîëüøîé")
GET_DESCR_ (sFPE, 0x85 /* _FPE_UNDERFLOW */, "Ðåçóëüòàò ñëèøêîì ìàëåíüêèé")
GET_DESCR_ (sFPE, 0x86 /* _FPE_INEXACT */, "Íåòî÷íûé ðåçóëüòàò")
GET_DESCR_ (sFPE, 0x87 /* _FPE_UNEMULATED */, "Îïåðàöèÿ íå ïîääåðæèâàåòñÿ")
GET_DESCR_ (sFPE, 0x88 /* _FPE_SQRTNEG */, "Êâàäðàòíûé êîðåíü èç îòðèöàòåëüíîãî ÷èñëà")
GET_DESCR_ (sFPE, 0x8A /* _FPE_STACKOVERFLOW */, "Ïåðåïîëíåíèå ñòåêà ñîïðîöåññîðà")
GET_DESCR_ (sFPE, 0x8B /* _FPE_STACKUNDERFLOW */, "Â ñòåêå ñîïðîöåññîðà íå õâàòàåò äàííûõ")
GET_DESCR_ (sFPE, 0x8C /* _FPE_EXPLICITGEN */, "ßâíûé âûçîâ èñêëþ÷åíèÿ")
default: break;
}
#undef GET_DESCR_
_fpreset();
if (sig == SIGFPE && fpe)
_txError (NULL, 0, NULL, "signal (%d, 0x%02X): %s, %s." _ sig _ fpe _ sSig _ sFPE);
else
_txError (NULL, 0, NULL, "signal (%d): %s" _ sig _ sSig);
_txExit = true;
_txCleanup();
}
//-----------------------------------------------------------------------------------------------------------------
void _txOnUnexpected()
{
_txError (NULL, 0, NULL,
"std::unexpected(): Íåîáðàáîòàííîå èñêëþ÷åíèå. Ïðîâåðüòå ñâîè catch-áëîêè. Ïåðåõâàòèòå catch (...). \n\n"
"Åñëè âû (çðÿ) èñïîëüçóåòå ñïåöèôèêàöèþ èñêëþ÷åíèé äëÿ ôóíêöèé, ïðîâåðüòå, íå íàðóøåíà ëè îíà.");
}
//-----------------------------------------------------------------------------------------------------------------
void _txOnTerminate()
{
_txError (NULL, 0, NULL,
"std::terminate(): Ïðîãðàììà áóäåò çàâåðøåíà èç-çà íåïåðåõâà÷åííîãî èñêëþ÷åíèÿ â ôóíêöèè main() èëè â äåñòðóêòîðå. \n\n"
"Èñïîëüçóéòå try/catch áëîêè, ïåðåõâàòûâàéòå catch (...), ðàçáèðàéòåñü, â ÷åì äåëî.");
}
//-----------------------------------------------------------------------------------------------------------------
const char* _txError (const char file[] /*= NULL*/, int line /*= 0*/, const char func[] /*= NULL*/,
const char msg [] /*= NULL*/, ...)
{
va_list arg; va_start (arg, msg);
static int nCalls = 0; nCalls++;
DWORD winerr = GetLastError();
int crterr = errno;
int doserr = _doserrno;
unsigned threadId = GetCurrentThreadId();
bool isFatal = (msg && *msg == '\a')? (msg++, true) : false;
bool fmtOnly = (msg && *msg == '\f')? (msg++, true) : false;
static char what[_TX_BIGBUFSIZE] = "";
static char str [_TX_BIGBUFSIZE] = "";
char *s = what;
#define SZARG_(n) sizeof (what) - 1 - (n) - (s-what) _TX_TRUNCATE
s += _snprintf_s (s, SZARG_(1), "TXLib ñîîáùàåò:\n\n");
s += _snprintf_s (s, SZARG_(1), "Ïðîãðàììà: %s, ", txGetModuleFileName());
if (file) s += _snprintf_s (s, SZARG_(1), "ôàéë: %s, ", file);
if (line) s += _snprintf_s (s, SZARG_(1), "ñòðîêà: %d, ", line);
if (func) s += _snprintf_s (s, SZARG_(1), "ôóíêöèÿ: %s.", func);
s += _snprintf_s (s, SZARG_(1), "\n\n");
if (msg) s += _snprintf_s (s, SZARG_(1), "%s: ", (file || line || func)? "Ñîîáùåíèå" : "ÂÍÅÇÀÏÍÎ"),
s += _vsnprintf_s (s, SZARG_(1), msg, arg),
s += _snprintf_s (s, SZARG_(1), "\n\n");
s += _snprintf_s (s, SZARG_(1), "#%d: %s, Instance: 0x%p, Flags: %c%c%c%c%c%c, Thread: 0x%08X%s",
nCalls, _TX_VERSION, (void*) &_txInitialized,
"cC"[_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], "tT"[_txAllowTrace],
threadId,
(threadId == _txMainThreadId)? " (Main)" :
(threadId == _txCanvas_ThreadId)? " (Canvas)" : "");
if (winerr) s += _snprintf_s (s, SZARG_(0), ", GetLastError(): %lu (", winerr),
s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, winerr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2,
s -= (s[-1] == '.')? 1 : 0,
s += _snprintf_s (s, SZARG_(1), ")");
if (crterr) s += _snprintf_s (s, SZARG_(1), ", errno: %d (%s)", crterr, (strerror_s (str, crterr), str));
if (doserr) s += _snprintf_s (s, SZARG_(1), ", _doserrno: %d (%s)", doserr, (strerror_s (str, doserr), str));
s += _snprintf_s (s, SZARG_(1), ". %s\n", std::uncaught_exception()? "std::uncaught_exception(): true." : "");
if (_txInTX > 0 && !(_txLine == line && file && _stricmp (_txFile, file) == 0))
s += _snprintf_s (s, SZARG_(1), "From: %s (%d) %s.\n", _txFile, _txLine, _txFunc);
#undef SZARG_
va_end (arg);
struct tools
{
static char* compressSpaces (char* dest, const char* src)
{
char* dst = dest;
for (char last = ' '; *src; src++)
if (isspace ((unsigned char)(*src))) { if (last != ' ') *dst++ = last = ' '; }
else *dst++ = last = *src;
if (dst > dest && dst[-1] == ' ') dst--;
*dst++ = '\n'; *dst++ = 0;
return dest;
}
static char* replace (char* dest, const char* src, char find, char repl)
{
size_t i = 0;
for (; src[i]; i++) dest[i] = (src[i] == find)? repl : src[i];
dest[i] = 0;
return dest;
}
};
$ txOutputDebugPrintf ("%s - %s", _TX_VERSION, tools::compressSpaces (str, what));
if (fmtOnly) return what;
tools::replace (str, what, '\v', ' ');
printf ("\n" "--------------------------------------------------\n"
"%s"
"--------------------------------------------------\n", str);
tools::replace (str, what, '\v', '\n');
txMessageBox (str, isFatal? "Ôàòàëüíàÿ îøèáêà" : "Îøèáêà â ïðîãðàììå", MB_ICONSTOP | MB_TOPMOST | MB_SYSTEMMODAL);
if (!isFatal) return what;
if (!IsDebuggerPresent()) exit (EXIT_FAILURE);
// vvvvvvvvvvvvvvvvvv
DebugBreak(); //>>> Âû â îòëàä÷èêå. Åñòü øàíñ ïîñìîòðåòü ïåðåìåííûå è ðàçîáðàòüñÿ.
// ^^^^^^^^^^^^^^^^^^
return what; //>>> Óõîäèòå èç ôóíêöèè ïîøàãîâîé îòëàäêîé (F10/F11). Ñëåäèòå çà ñòåêîì âûçîâîâ (Alt+7).
}
//-----------------------------------------------------------------------------------------------------------------
int txOutputDebugPrintf (const char format[], ...)
{
if (!format) return 0;
bool msgbox = (*format == '\a')? (format++, true) : false;
bool print = (*format == '\f')? (format++, true) : false;
char str[_TX_BIGBUFSIZE] = "";
va_list arg; va_start (arg, format);
int n = _vsnprintf_s (str, sizeof (str) - 1 _TX_TRUNCATE, format, arg);
va_end (arg);
OutputDebugString (str);
if (print)
fprintf (stderr, "%s", str);
if (msgbox)
txMessageBox (str, "Îêàçûâàåòñÿ, ÷òî", MB_ICONEXCLAMATION | MB_TOPMOST);
return n;
}
//-----------------------------------------------------------------------------------------------------------------
unsigned txMessageBox (const char* text, const char* header, unsigned flags /*= 0*/)
{
static wchar_t textW [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]";
static wchar_t headerW [_TX_BUFSIZE * sizeof (wchar_t)] = L"[NULL header]";
if (text) MultiByteToWideChar (_TX_CP, 0, text, -1, textW, SIZEARR (textW)) || memset (textW, 0, sizeof (textW));
if (header) MultiByteToWideChar (_TX_CP, 0, header, -1, headerW, SIZEARR (headerW)) || memset (headerW, 0, sizeof (headerW));
HWND wnd = _txCanvas_Window;
return MessageBoxW ((wnd? wnd : Win32::GetConsoleWindow()), textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST);
}
//-----------------------------------------------------------------------------------------------------------------
const char* txGetModuleFileName (bool fileNameOnly /*= true*/)
{
static char name[MAX_PATH] = "";
if (!*name) GetModuleFileName (NULL, name, sizeof (name) - 1) || strcpy_s (name, "");
assert (*name);
if (fileNameOnly) return name;
static char fullName[MAX_PATH] = "";
strncpy_s (fullName, name, sizeof (fullName) - 1);
char* title = strrchr (fullName, '\\'); if (!title) title = fullName;
char* ext = strrchr (fullName, '.'); if (!ext) ext = fullName + strlen (fullName);
size_t sz = sizeof (fullName) - (ext - fullName) - 1;
#if defined (_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES) && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES
strncpy_s (ext, sz, " - TXLib", sz);
#else
strncpy (ext, " - TXLib", sz);
#endif
return title + 1;
}
//-----------------------------------------------------------------------------------------------------------------
bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...)
{
$1 _TX_IF_ARGUMENT_FAILED (format) return false;
$ va_list arg; va_start (arg, format);
$ bool ok = true;
#if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500)
$ NOTIFYICONDATA nid = { sizeof (nid) };
$ nid.uFlags = NIF_ICON | NIF_TIP | NIF_INFO;
$ nid.hWnd = NULL;
$ nid.uID = 1;
$ nid.hIcon = _txCreateTXIcon (16); assert (nid.hIcon);
$ strncpy_s (nid.szTip, "TXLib Information", sizeof (nid.szTip));
$ strncpy_s (nid.szInfoTitle, (title? title : "TXLib ñîîáùàåò"), sizeof (nid.szInfoTitle) - 1);
$ _vsnprintf_s (nid.szInfo, sizeof (nid.szInfo) _TX_TRUNCATE, format, arg);
$ nid.dwInfoFlags = flags;
$ txOutputDebugPrintf (_TX_VERSION " - Icon notification: %s: %s\n", nid.szInfoTitle, nid.szInfo);
$ ok &= !!Shell_NotifyIcon (NIM_ADD, (::NOTIFYICONDATA*) &nid);
$ ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid);
$ if (nid.hIcon) DestroyIcon (nid.hIcon) asserted;
#else
$ char nid_szInfo[_TX_BUFSIZE] = "";
$ _vsnprintf_s (nid_szInfo, sizeof (nid_szInfo) _TX_TRUNCATE, format, arg);
$ txOutputDebugPrintf (_TX_VERSION " - Icon notification (NOT displayed): %s: %s\n", title, nid_szInfo);
$ ok = false;
$ (void)flags; (void)title;
#endif
$ va_end (arg);
$ return ok;
}
//! @}
//}
//=================================================================================================================
//=================================================================================================================
//{ TXLib API implementation
// Ðåàëèçàöèÿ TXLib API
//=================================================================================================================
inline const char* txVersion()
{
return _TX_VERSION;
}
//-----------------------------------------------------------------------------------------------------------------
inline unsigned txVersionNumber()
{
return _TX_VER;
}
//-----------------------------------------------------------------------------------------------------------------
POINT txGetExtent()
{
$1 _TX_IF_TXWINDOW_FAILED return ZERO (POINT);
$ RECT r = {0};
$ GetClientRect (txWindow(), &r);
$ POINT size = { r.right - r.left, r.bottom - r.top };
$ return size;
}
//-----------------------------------------------------------------------------------------------------------------
int txGetExtentX()
{
$1 return txGetExtent().x;
}
//-----------------------------------------------------------------------------------------------------------------
int txGetExtentY()
{
$1 return txGetExtent().y;
}
//-----------------------------------------------------------------------------------------------------------------
inline HDC& txDC()
{
$1 return _txCanvas_BackBuf[0];
}
//-----------------------------------------------------------------------------------------------------------------
inline HWND txWindow()
{
$1 return _txCanvas_Window;
}
//-----------------------------------------------------------------------------------------------------------------
bool txDestroyWindow()
{
$1 if (!txWindow()) return false;
$ if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false;
$ if (_txMain)
{
$ txNotifyIcon (NIIF_WARNING, NULL, "\n" "Î÷åíü, î÷åíü ïëîõî çàâåðøàòü ïðîãðàììó ÷åðåç txDestroyWindow(). \n\n"
"Âîçâðàùàéòåñü ÷åðåç main(), òàì âàì áóäóò ðàäû.\n");
$ Sleep (_TX_TIMEOUT);
}
$ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
$ return _txCanvas_Window == NULL;
}
//-----------------------------------------------------------------------------------------------------------------
bool txSetColor (COLORREF color, double thickness /*= 1*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ return _txBuffer_Select (Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color))
&&
txGDI ((Win32::SetTextColor (txDC(), color)));
}
//-----------------------------------------------------------------------------------------------------------------
bool txColor (double red, double green, double blue)
{
$1 if (red > 1) red = 1; if (red < 0) red = 0;
$ if (green > 1) green = 1; if (green < 0) green = 0;
$ if (blue > 1) blue = 1; if (blue < 0) blue = 0;
$ return txSetColor (RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)));
}
//-----------------------------------------------------------------------------------------------------------------
COLORREF txGetColor()
{
$1 _TX_IF_TXWINDOW_FAILED return CLR_INVALID;
$ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (txDC(), OBJ_PEN)));
$ assert (obj); if (!obj) return CLR_INVALID;
$ union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {{0}};
$ int size = Win32::GetObject (obj, 0, NULL);
$ Win32::GetObject (obj, sizeof (buf), &buf) asserted;
$ return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor;
}
//-----------------------------------------------------------------------------------------------------------------
bool txSetFillColor (COLORREF color)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ return _txBuffer_Select ((color == TX_TRANSPARENT)? Win32::GetStockObject (HOLLOW_BRUSH) :
Win32::CreateSolidBrush (color));
}
//-----------------------------------------------------------------------------------------------------------------
bool txFillColor (double red, double green, double blue)
{
$1 if (red > 1) red = 1; if (red < 0) red = 0;
$ if (green > 1) green = 1; if (green < 0) green = 0;
$ if (blue > 1) blue = 1; if (blue < 0) blue = 0;
$ return txSetFillColor (RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)));
}
//-----------------------------------------------------------------------------------------------------------------
COLORREF txGetFillColor()
{
$1 _TX_IF_TXWINDOW_FAILED return CLR_INVALID;
$ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (txDC(), OBJ_BRUSH)));
$ assert (obj); if (!obj) return CLR_INVALID;
$ LOGBRUSH buf = {0};
$ txGDI ((Win32::GetObject (obj, sizeof (buf), &buf))) asserted;
$ return buf.lbColor;
}
//-----------------------------------------------------------------------------------------------------------------
bool txSetROP2 (int mode /*= R2_COPYPEN*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ return txGDI (!!(Win32::SetROP2 (txDC(), mode)));
}
//-----------------------------------------------------------------------------------------------------------------
bool txClear()
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ POINT size = txGetExtent();
$ return txGDI (!!(Win32::PatBlt (txDC(), 0, 0, size.x, size.y, PATCOPY)));
}
//-----------------------------------------------------------------------------------------------------------------
inline bool txSetPixel (double x, double y, COLORREF color)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ txGDI ((Win32::SetPixel (txDC(), ROUND (x), ROUND (y), color)));
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
inline bool txPixel (double x, double y, double red, double green, double blue)
{
$1 if (red > 1) red = 1; if (red < 0) red = 0;
$ if (green > 1) green = 1; if (green < 0) green = 0;
$ if (blue > 1) blue = 1; if (blue < 0) blue = 0;
$ return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)));
}
//-----------------------------------------------------------------------------------------------------------------
inline COLORREF txGetPixel (double x, double y)
{
$1 _TX_IF_TXWINDOW_FAILED return CLR_INVALID;
$ return txGDI ((Win32::GetPixel (txDC(), ROUND (x), ROUND (y))));
}
//-----------------------------------------------------------------------------------------------------------------
bool txLine (double x0, double y0, double x1, double y1)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ txGDI ((Win32::MoveToEx (txDC(), ROUND (x0), ROUND (y0), NULL))) asserted;
$ txGDI ((Win32::LineTo (txDC(), ROUND (x1), ROUND (y1) ))) asserted;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool txRectangle (double x0, double y0, double x1, double y1)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ txGDI ((Win32::Rectangle (txDC(), ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1)))) asserted;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool txPolygon (const POINT points[], int numPoints)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (points) return false;
$ return txGDI (!!(Win32::Polygon (txDC(), points, numPoints)));
}
//-----------------------------------------------------------------------------------------------------------------
bool txEllipse (double x0, double y0, double x1, double y1)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ txGDI ((Win32::Ellipse (txDC(), ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1)))) asserted;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool txCircle (double x, double y, double r)
{
$1 return txEllipse (x-r, y-r, x+r, y+r);
}
//-----------------------------------------------------------------------------------------------------------------
bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
$ double start = startAngle * txPI/180,
end = (startAngle + totalAngle) * txPI/180;
$ return txGDI (!!(Win32::Arc (txDC(), ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))));
}
//-----------------------------------------------------------------------------------------------------------------
bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
$ double start = startAngle * txPI/180,
end = (startAngle + totalAngle) * txPI/180;
$ return txGDI (!!(Win32::Pie (txDC(), ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))));
}
//-----------------------------------------------------------------------------------------------------------------
bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
$ double start = startAngle * txPI/180,
end = (startAngle + totalAngle) * txPI/180;
$ return txGDI (!!(Win32::Chord (txDC(), ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))));
}
//-----------------------------------------------------------------------------------------------------------------
bool txFloodFill (double x, double y,
COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ if (color == TX_TRANSPARENT) color = txGetPixel (x, y);
$ return txGDI (!!(Win32::ExtFloodFill (txDC(), ROUND (x), ROUND (y), color, mode)));
}
//-----------------------------------------------------------------------------------------------------------------
bool txTextOut (double x, double y, const char text[])
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (text) return false;
$ int len = (int) strlen (text);
$ txGDI (!!(Win32::TextOut (txDC(), ROUND (x), ROUND (y), text, len))) asserted;
$ SIZE size = {0};
$ txGDI ((Win32::GetTextExtentPoint32 (txDC(), text, len, &size))) asserted;
$ RECT r = { ROUND (x), ROUND (y), ROUND (x + size.cx), ROUND (y + size.cy) };
$ InvalidateRect (txWindow(), &r, false) asserted;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (text) return false;
$ RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) };
$ if (!strchr (text, '\n')) format |= DT_SINGLELINE;
$ unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP);
if (Win32::DrawText) { $ txGDI ((Win32::DrawText (txDC(), text, -1, &r, format))) asserted; }
$ txSetTextAlign (prev);
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
bool 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*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (name) return false;
$ _txBuffer_Select (txFontExist (name)?
Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3),
ROUND (angle*10), 0, bold, italic, underline, strikeout,
RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH, name)
:
Win32::GetStockObject (SYSTEM_FIXED_FONT));
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
SIZE txGetTextExtent (const char text[])
{
$1 SIZE size = {0};
$ _TX_IF_TXWINDOW_FAILED return size;
$ _TX_IF_ARGUMENT_FAILED (text) return size;
$ txGDI ((Win32::GetTextExtentPoint32 (txDC(), text, (int) strlen (text), &size))) asserted;
$ return size;
}
//-----------------------------------------------------------------------------------------------------------------
int txGetTextExtentX (const char text[])
{
$1 return txGetTextExtent (text) .cx;
}
//-----------------------------------------------------------------------------------------------------------------
int txGetTextExtentY (const char text[])
{
$1 return txGetTextExtent (text) .cy;
}
//-----------------------------------------------------------------------------------------------------------------
unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/)
{
$1 _TX_IF_TXWINDOW_FAILED return 0;
$ return txGDI ((Win32::SetTextAlign (txDC(), align)));
}
//-----------------------------------------------------------------------------------------------------------------
LOGFONT* txFontExist (const char name[])
{
$1 _TX_IF_TXWINDOW_FAILED return NULL;
$ _TX_IF_ARGUMENT_FAILED (name) return NULL;
$ static LOGFONT font = {0};
$ font.lfCharSet = DEFAULT_CHARSET;
$ strncpy_s (font.lfFaceName, name, sizeof (font.lfFaceName) - 1);
$ struct tools
{
static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data)
{
$ _TX_IF_ARGUMENT_FAILED (fnt) return 0;
$ _TX_IF_ARGUMENT_FAILED (data) return 0;
#ifndef __STRICT_ANSI__
$ return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
#else
$ return strncmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
#endif
}
};
$ return txGDI ((Win32::EnumFontFamiliesEx (txDC(), &font, tools::enumFonts, (LPARAM) &font, 0))) == 0? &font : NULL;
}
//-----------------------------------------------------------------------------------------------------------------
bool txSelectObject (HGDIOBJ obj)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (obj) return false;
$ return _txBuffer_Select (obj);
}
//-----------------------------------------------------------------------------------------------------------------
HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/)
{
$1 _TX_IF_TXWINDOW_FAILED return NULL;
$ POINT size = { ROUND (sizeX), ROUND (sizeY) };
$ HDC dc = _txBuffer_Create (txWindow(), &size, bitmap);
$ assert (dc); if (!dc) return NULL;
$ if (!_txCanvas_UserDCs) return dc;
$ txAutoLock _lock;
$ _txCanvas_UserDCs->push_back (dc);
$ if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE)
{ $ txNotifyIcon (NIIF_WARNING, NULL, "Âû çàãðóçèëè óæå %d HDC, ñèñòåìå ìîæåò ñòàòü ïëîõî.", (int) _txCanvas_UserDCs->size()); }
$ return dc;
}
//-----------------------------------------------------------------------------------------------------------------
HDC txLoadImage (const char filename[], unsigned imageFlags /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/)
{
$1 _TX_IF_TXWINDOW_FAILED return NULL;
$ _TX_IF_ARGUMENT_FAILED (filename && *filename) return NULL;
$ HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL),
filename, imageFlags, 0, 0, loadFlags);
$ if (!image) return NULL;
$ HDC dc = txCreateCompatibleDC (0, 0, image);
$ if (!(loadFlags & LR_LOADFROMFILE)) return dc;
$ static std::map <std::string, unsigned> loadTimes;
$ std::string file = filename;
$ unsigned time = GetTickCount();
$ if ((long) (time - loadTimes [file]) < _TX_TIMEOUT)
{ $ txNotifyIcon (NIIF_WARNING, NULL, "Âû çàãðóæàåòå \"%s\" ñëèøêîì ÷àñòî, ïðîãðàììà áóäåò òîðìîçèòü.", filename); }
$ loadTimes [file] = time;
$ return dc;
}
//-----------------------------------------------------------------------------------------------------------------
bool txDeleteDC (HDC* pdc)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (pdc) return false;
$ HDC dc = *pdc;
$ bool ok = _txBuffer_Delete (pdc);
$ if (!ok) return false;
$ if (!_txCanvas_UserDCs) return ok;
$ txAutoLock _lock;
$ std::vector <HDC> ::iterator i = std::find (_txCanvas_UserDCs->begin(), _txCanvas_UserDCs->end(), dc);
$ if (i != _txCanvas_UserDCs->end()) { std::swap (*i, _txCanvas_UserDCs->back()); _txCanvas_UserDCs->pop_back(); }
$ return ok;
}
//-----------------------------------------------------------------------------------------------------------------
bool txDeleteDC (HDC dc)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ return txDeleteDC (&dc);
}
//-----------------------------------------------------------------------------------------------------------------
bool txBitBlt (HDC dest, double xDest, double yDest, double width, double height,
HDC src, double xSrc /*= 0*/, double ySrc /*= 0*/, DWORD rOp /*= SRCCOPY*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (dest) return false;
$ _TX_IF_ARGUMENT_FAILED (src) return false;
$ return txGDI (!!(Win32::BitBlt (dest, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height),
src, ROUND (xSrc), ROUND (ySrc), rOp)));
}
//-----------------------------------------------------------------------------------------------------------------
bool txTransparentBlt (HDC dest, double xDest, double yDest, double width, double height,
HDC src, double xSrc /*= 0*/, double ySrc /*= 0*/, COLORREF transColor /*= TX_BLACK*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (dest) return false;
$ _TX_IF_ARGUMENT_FAILED (src) return false;
$ return (Win32::TransparentBlt)?
txGDI (!!(Win32::TransparentBlt (dest, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height),
src, ROUND (xSrc), ROUND (ySrc), ROUND (width), ROUND (height), transColor)))
:
txGDI (!!(Win32::BitBlt (dest, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height),
src, ROUND (xSrc), ROUND (ySrc), SRCCOPY))), false;
}
//-----------------------------------------------------------------------------------------------------------------
bool txAlphaBlend (HDC dest, double xDest, double yDest, double width, double height,
HDC src, double xSrc /*= 0*/, double ySrc /*= 0*/, double alpha /*= 1.0*/)
{
$1 _TX_IF_TXWINDOW_FAILED return false;
$ _TX_IF_ARGUMENT_FAILED (dest) return false;
$ _TX_IF_ARGUMENT_FAILED (src) return false;
$ if (alpha < 0) alpha = 0;
$ if (alpha > 1) alpha = 1;
$ BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), AC_SRC_ALPHA };
$ return (Win32::AlphaBlend)?
txGDI (!!(Win32::AlphaBlend (dest, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height),
src, ROUND (xSrc), ROUND (ySrc), ROUND (width), ROUND (height), blend)))
:
txGDI (!!(Win32::BitBlt (dest, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height),
src, ROUND (xSrc), ROUND (ySrc), SRCCOPY))), false;
}
//-----------------------------------------------------------------------------------------------------------------
inline int txUpdateWindow (int update /*= true*/)
{
$1 return _txCanvas_SetRefreshLock (update >= 0? !update : -update);
}
//-----------------------------------------------------------------------------------------------------------------
inline int txBegin()
{
$1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1);
$ return _txCanvas_RefreshLock;
}
//-----------------------------------------------------------------------------------------------------------------
inline int txEnd()
{
$1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1);
$ return _txCanvas_RefreshLock;
}
//-----------------------------------------------------------------------------------------------------------------
double txSleep (double time)
{
$1 LARGE_INTEGER start = {{0}};
$ QueryPerformanceCounter (&start) asserted;
$ LARGE_INTEGER freq = {{0}};
$ QueryPerformanceFrequency (&freq) asserted;
$ int lock = _txCanvas_RefreshLock;
$ _txCanvas_RefreshLock = 0;
$ HWND wnd = txWindow();
if (wnd) { $ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW) asserted; }
$ Sleep (ROUND (time));
$ _txCanvas_RefreshLock = lock;
$ LARGE_INTEGER stop = {{0}};
$ QueryPerformanceCounter (&stop) asserted;
$ return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart;
}
//-----------------------------------------------------------------------------------------------------------------
bool txLock (bool wait /*= true*/)
{
$1 if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
$ if (wait) { $ return EnterCriticalSection (&_txCanvas_LockBackBuf), true; }
else { $ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf); }
}
//-----------------------------------------------------------------------------------------------------------------
bool txUnlock()
{
$1 LeaveCriticalSection (&_txCanvas_LockBackBuf);
$ if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
$ return false;
}
//-----------------------------------------------------------------------------------------------------------------
template <typename T>
inline T txUnlock (T value)
{
$1 txUnlock();
$ return value;
}
//-----------------------------------------------------------------------------------------------------------------
inline POINT txMousePos()
{
$1 _TX_IF_TXWINDOW_FAILED return ZERO (POINT);
$ return _txMousePos;
}
//-----------------------------------------------------------------------------------------------------------------
inline int txMouseX()
{
$1 return _txMousePos.x;
}
//-----------------------------------------------------------------------------------------------------------------
inline int txMouseY()
{
$1 return _txMousePos.y;
}
//-----------------------------------------------------------------------------------------------------------------
inline int txMouseButtons()
{
$1 _TX_IF_TXWINDOW_FAILED return 0;
$ return _txMouseButtons;
}
//-----------------------------------------------------------------------------------------------------------------
bool txSetConsoleAttr (unsigned color /*= 0x07*/)
{
$1 return !!SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color);
}
//-----------------------------------------------------------------------------------------------------------------
unsigned txGetConsoleAttr()
{
$1 CONSOLE_SCREEN_BUFFER_INFO con = {{0}};
$ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con);
$ return con.wAttributes;
}
//-----------------------------------------------------------------------------------------------------------------
POINT txSetConsoleCursorPos (double x, double y)
{
$1 POINT fontSz = txGetConsoleFontSize();
$ CONSOLE_SCREEN_BUFFER_INFO con = {{0}};
$ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
$ COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left),
(short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) };
$ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted;
$ POINT prev = { ROUND (1.0 * (con.dwCursorPosition.X - con.srWindow.Left) / fontSz.x),
ROUND (1.0 * (con.dwCursorPosition.Y - con.srWindow.Top ) / fontSz.y) };
$ return prev;
}
//-----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleCursorPos()
{
$1 POINT fontSz = txGetConsoleFontSize();
$ CONSOLE_SCREEN_BUFFER_INFO con = {{0}};
$ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
$ POINT pos = { ROUND (1.0 * (con.dwCursorPosition.X - con.srWindow.Left) / fontSz.x),
ROUND (1.0 * (con.dwCursorPosition.Y - con.srWindow.Top ) / fontSz.y) };
$ return pos;
}
//-----------------------------------------------------------------------------------------------------------------
bool txClearConsole()
{
$1 HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
$ CONSOLE_SCREEN_BUFFER_INFO con = {{0}};
$ GetConsoleScreenBufferInfo (out, &con) asserted;
$ COORD start = {con.srWindow.Left, con.srWindow.Top};
$ DWORD len = (con.srWindow.Right - con.srWindow.Left + 1) *
(con.srWindow.Bottom - con.srWindow.Top + 1);
$ DWORD written = 0;
$ FillConsoleOutputCharacter (out, 0x20 /*' '*/, len, start, &written) asserted;
$ FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted;
$ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted;
$ return written == len;
}
//-----------------------------------------------------------------------------------------------------------------
POINT txGetConsoleFontSize()
{
$1 CONSOLE_FONT_INFO font = {0, {8, 16}};
$ if (Win32::GetCurrentConsoleFont)
{ $ Win32::GetCurrentConsoleFont (GetStdHandle (STD_OUTPUT_HANDLE), false, &font) asserted; }
$ SIZE size = { font.dwFontSize.X, font.dwFontSize.Y };
$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size));
$ POINT sizeFont = { size.cx, size.cy };
$ return sizeFont;
}
//-----------------------------------------------------------------------------------------------------------------
bool txTextCursor (bool blink /*= true*/)
{
$1 bool old = _txConsole_IsBlinking;
$ _txConsole_IsBlinking = blink;
$ return old;
}
//-----------------------------------------------------------------------------------------------------------------
bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/)
{
$1 _TX_IF_ARGUMENT_FAILED (!(filename && !*filename)) return false;
$ mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT;
$ if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC;
$ if (!filename) mode = SND_PURGE;
$ return !!Win32::PlaySound (filename, NULL, mode);
}
//-----------------------------------------------------------------------------------------------------------------
// +--<<< Ýòî âðÿä ëè èìååò îòíîøåíèå ê òîìó, ÷òî âû èùåòå :)
// V Ïîëåçíî ñìîòðåòü íå òîëüêî ââåðõ, íî è âíèç
WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/)
{
$1 WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc;
$ return old;
}
//-----------------------------------------------------------------------------------------------------------------
// +--<<< À ýòî, íàêîíåö, èñêîìîå îïðåäåëåíèå ýòîé ôóíêöèè.
// | Ñìîòðèòå ïî ñòîðîíàì! Íóæíàÿ âàì ôóíêöèÿ ãäå-òî ðÿäîì.
// |
// v
bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()
{
$1 txMessageBox ("Ýòî çàïëàíèðîâàííàÿ îøèáêà. Òàêîå áûâàåò. Âû õîòåëè âûçâàòü:\n\n"
"txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n"
"Õîòü âû äîëãî [êîïèðîâàëè]íàáèðàëè ýòî èìÿ, íà ñàìîì äåëå ýòà ôóíêöèÿ íå ðåàëèçîâàíà. "
"Åñòü äðóãàÿ ôóíêöèÿ, êîòîðàÿ óáèðàåò àâòî-ïàóçó â êîíöå ïðîãðàììû, íî â õåëïå ïðî íåå íå íàïèñàíî.\n\n"
"Íî íå âñå òàê ïëîõî. Îïðåäåëåíèå íóæíîé ôóíêöèè åñòü â èñõîäíûõ òåêñòàõ TXLib.h, îíî ëåæèò ðÿäîì "
"ñ îïðåäåëåíèåì òîé ôóíêöèè ñ äëèííûì íàçâàíèåì, êîòîðóþ âû ñåé÷àñ âûçâàëè.\n\n"
"Íàæìèòå â ðåäàêòîðå Ctrl+O, íàéäèòå è îòêðîéòå ôàéë TXLib.h (îí ëåæèò â ïàïêå, êóäà âû "
"óñòàíîâèëè TXLib), çàòåì íàæìèòå Ctrl+F è èùèòå \"txIDontWant\". Óäà÷è!\n\n",
"Íå ïîëó÷èëîñü", MB_ICONSTOP);
// The truth is out there... (C++files)
$ return false;
}
//-----------------------------------------------------------------------------------------------------------------
// Bingo! Now you are learned to use the Sources, Luke. And may the Source be with you.
inline bool txDisableAutoPause()
{
$1 _txExit = true;
$ return true;
}
//-----------------------------------------------------------------------------------------------------------------
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)
{
$1 const char msg[] = "\0/À ÿ - ÷åëîâå÷åê èç áèáëèîòåêè!\0/Ìåíÿ îáúÿñíÿëè íà óðîêå!\0/Íàïèøè ìåíÿ ñàì!\0/";
static unsigned count = GetTickCount(), L = 0;
$ COLORREF lineColor = txGetColor();
COLORREF fillColor = txGetFillColor();
$ txSetColor (TX_DARKGRAY);
txSetFillColor (TX_TRANSPARENT);
$ txRectangle (x - sizeX/2, y - sizeY, x + sizeX/2, y);
txCircle (x, y, 4);
$ txSetColor (color);
txSetFillColor (color);
$ txLine (x + twist * sizeX, y - 0.35 * sizeY, x, y - 0.7 * sizeY);
$ txLine (x, y - 0.7 * sizeY, x - sizeX/2, y - (0.7 + handL) * sizeY);
txLine (x, y - 0.7 * sizeY, x + sizeX/2, y - (0.7 + handR) * sizeY);
$ txLine (x + twist * sizeX, y - 0.35 * sizeY, x - sizeX/2, y);
txLine (x + twist * sizeX, y - 0.35 * sizeY, x + sizeX/2, y);
$ txCircle (x, y - (0.85 + head) * sizeY, 0.15 * sizeY);
$ txLine (x, y - (1 + head) * sizeY, x + wind/10 * sizeX, y - (1 + head + hair/10) * sizeY);
txLine (x, y - (1 + head) * sizeY, x + (wind/10 - 0.1) * sizeX, y - (1 + head + hair/10) * sizeY);
txLine (x, y - (1 + head) * sizeY, x + (wind/10 + 0.1) * sizeX, y - (1 + head + hair/10) * sizeY);
$ txSetColor (~color & 0xFFFFFF);
txSetFillColor (~color & 0xFFFFFF);
$ txLine (x, y - (0.8 + head - 0.05 * smile/2) * sizeY, x - 0.05 * sizeY, y - (0.8 + head + 0.05 * smile/2) * sizeY),
txLine (x, y - (0.8 + head - 0.05 * smile/2) * sizeY, x + 0.05 * sizeY, y - (0.8 + head + 0.05 * smile/2) * sizeY),
txNotifyIcon (4, (const char*)!! (L+'L')[msg], "\n%s\n", msg + (count++ % 3)["\"<"]);
$ txCircle (x - 0.05 * sizeY, y - (0.9 + head - 0.02 * crazy) * sizeY, eyes * (1 + 0.5*wink) * 0.02 * sizeY),
txCircle (x + 0.05 * sizeY, y - (0.9 + head + 0.02 * crazy) * sizeY, eyes * (1 - 0.5*wink) * 0.02 * sizeY),
Sleep (1000 + count%2);
$ txSetColor (lineColor);
txSetFillColor (fillColor);
}
//-----------------------------------------------------------------------------------------------------------------
void txDump (const void* address, const char name[] /*= "txDump()"*/)
{
const unsigned char* p = (const unsigned char*) address;
int x = 0;
txSetConsoleAttr (0x0F);
printf ("\n%8.8s ", name? name : "");
txSetConsoleAttr (0x0E);
for (x = 0; x < 16; x++) printf ("%02X ", x);
for (x = 0; x < 16; x++) printf ("%X", x);
for (int y = 0; y < 16; y++, p += 16)
{
txSetConsoleAttr (0x0E);
printf ("\n" "%8p ", p);
for (x = 0; x < 16; x++) { txSetConsoleAttr (0x0A + x/4%2); printf ("%02X ", p[x]); }
for (x = 0; x < 16; x++) { txSetConsoleAttr (0x0A + x/4%2); printf ("%c", isprint (p[x])? p[x] : '.'); }
}
txSetConsoleAttr (0x07);
printf ("\n");
}
//-----------------------------------------------------------------------------------------------------------------
double txQueryPerformance()
{
$1 int maxTime = 500;
$ int maxSamples = 100;
$ POINT size = {500, 500};
$ HDC dc = _txBuffer_Create (txWindow(), &size, NULL);
$ assert (dc); if (!dc) return -1;
$ DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1);
$ assert (mask);
$ LARGE_INTEGER freq = {{0}};
$ QueryPerformanceFrequency (&freq) asserted;
$ LARGE_INTEGER start = {{0}};
$ QueryPerformanceCounter (&start) asserted;
$ int samples = 0;
$ while (samples++ < maxSamples)
{
$ LARGE_INTEGER cur = {{0}};
$ QueryPerformanceCounter (&cur) asserted;
$ double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart;
$ if (t > maxTime) break;
// Draw test scene
$ for (int y = 0; y < size.y; y += 10)
for (int x = 0; x < size.x; x += 10) Win32::TextOut (dc, x, y, "*", 1);
$ Win32::Ellipse (dc, 0, 0, size.x, size.y);
$ Win32::ExtFloodFill (dc, size.x/2, size.y/2, TX_TRANSPARENT, FLOODFILLSURFACE);
$ txBitBlt (dc, size.x/2, 0, size.x/2, size.y/2, dc, 0, 0) asserted;
$ txBitBlt (dc, size.x/2, size.y/2, size.x/2, size.y/2, dc, 0, size.y/2) asserted;
$ txBitBlt (dc, 0, size.y/2, size.x/2, size.y/2, dc, 0, 0) asserted;
$ txBitBlt (dc, size.x/2, size.y/2, size.x/2, size.y/2, dc, size.x/2, 0) asserted;
}
$ mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask);
$ assert (mask);
$ _txBuffer_Delete (&dc);
$ return 15.0 * samples / sqrt (1.0 * size.x * size.y);
}
//-----------------------------------------------------------------------------------------------------------------
int txExtractColor (COLORREF color, COLORREF component)
{
$1 switch (component)
{
case TX_RED:
case TX_HUE: $ return (color >> 0) & 0xFF;
case TX_GREEN:
case TX_SATURATION: $ return (color >> 8) & 0xFF;
case TX_BLUE:
case TX_LIGHTNESS: $ return (color >> 16) & 0xFF;
default: $ return CLR_INVALID;
}
}
//-----------------------------------------------------------------------------------------------------------------
COLORREF txRGB2HSL (COLORREF rgbColor)
{
$1 int r = txExtractColor (rgbColor, TX_RED),
g = txExtractColor (rgbColor, TX_GREEN),
b = txExtractColor (rgbColor, TX_BLUE);
$ double m1 = MAX (MAX (r, g), b) / 255.0,
m2 = MIN (MIN (r, g), b) / 255.0,
dm = m1 - m2,
sm = m1 + m2,
ir = r / 255.0,
ig = g / 255.0,
ib = b / 255.0,
ih = 0,
is = 0,
il = sm / 2;
$ const double prec = 0.001;
$ if (fabs (dm) < prec)
{
$ is = dm / ((sm <= 1)? sm : (2-sm));
$ double cr = (m1 - ir) / dm,
cg = (m1 - ig) / dm,
cb = (m1 - ib) / dm;
$ if (fabs (ir - m1) < prec) ih = cb - cg;
$ if (fabs (ig - m1) < prec) ih = 2 + cr - cb;
$ if (fabs (ib - m1) < prec) ih = 4 + cg - cr;
}
$ ih = (ih >= 0)? ih*60 : ih*60 + 360;
$ return RGB (ROUND (ih / 360 * 255), ROUND (is * 255), ROUND (il * 255));
}
//-----------------------------------------------------------------------------------------------------------------
COLORREF txHSL2RGB (COLORREF hslColor)
{
$1 struct xRGB
{
static double calc (double h, double m1, double m2)
{
$ if (h < 0) h += 360;
$ if (h > 360) h -= 360;
$ return (h < 60)? m1 + (m2-m1) * h / 60 :
(h < 180)? m2 :
(h < 240)? m1 + (m2-m1) * (240-h) / 60 :
m1;
}
};
$ int h = txExtractColor (hslColor, TX_HUE),
s = txExtractColor (hslColor, TX_SATURATION),
l = txExtractColor (hslColor, TX_LIGHTNESS);
$ double ih = h / 255.0 * 360.0,
il = l / 100.0,
is = s / 100.0,
m2 = (il <= 0.5)? il * (1 + is) : il + is - il * is,
m1 = 2 * il - m2,
ir = s? xRGB::calc (ih + 120, m1, m2) : il,
ig = s? xRGB::calc (ih, m1, m2) : il,
ib = s? xRGB::calc (ih - 120, m1, m2) : il;
$ return RGB (ROUND (ir * 255), ROUND (ig * 255), ROUND (ib * 255));
}
//-----------------------------------------------------------------------------------------------------------------
template <typename T>
inline bool In (T x, T a, T b)
{
return a <= x && x <= b;
}
//-----------------------------------------------------------------------------------------------------------------
inline bool In (const POINT& pt, const RECT& rect)
{
_TX_IF_ARGUMENT_FAILED (&pt) return 0;
_TX_IF_ARGUMENT_FAILED (&rect) return 0;
return In (pt.x, rect.left, rect.right) &&
In (pt.y, rect.top, rect.bottom);
}
//-----------------------------------------------------------------------------------------------------------------
inline bool In (const COORD& pt, const SMALL_RECT& rect)
{
_TX_IF_ARGUMENT_FAILED (&pt) return 0;
_TX_IF_ARGUMENT_FAILED (&rect) return 0;
return In (pt.X, rect.Left, rect.Right) &&
In (pt.Y, rect.Top, rect.Bottom);
}
//-----------------------------------------------------------------------------------------------------------------
inline int random (int range)
{
return rand() % range;
}
//-----------------------------------------------------------------------------------------------------------------
inline double random (double left, double right)
{
return left + (right - left) * ((double) rand() / RAND_MAX);
}
//-----------------------------------------------------------------------------------------------------------------
template <typename T>
inline T zero()
#ifdef _MSC_VER_6
{ T __zero = {0}; return __zero; }
#else
{ T __zero = { }; return __zero; }
#endif
//}
//=================================================================================================================
//=================================================================================================================
//{ txDialog methods implementation
// Ðåàëèçàöèÿ ìåòîäîâ êëàññà txDialog
//=================================================================================================================
txDialog::txDialog () :
layout_ (NULL)
{$1}
//-----------------------------------------------------------------------------------------------------------------
txDialog::txDialog (const Layout* layout) :
layout_ (layout)
{$1}
//-----------------------------------------------------------------------------------------------------------------
const txDialog::Layout* txDialog::setLayout (const Layout* layout)
{
$1 return std::swap (layout_, layout), layout;
}
//-----------------------------------------------------------------------------------------------------------------
INT_PTR txDialog::dialogBox (WORD resourceID)
{
$1 const char* resName = (char*)(ptrdiff_t) resourceID;
$ if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Íå íàéäåí ðåñóðñ äèàëîãà %d" _ resourceID), 0;
$ return DialogBoxParam (NULL, resName, NULL, dialogProc__, (LPARAM) this);
}
//-----------------------------------------------------------------------------------------------------------------
INT_PTR txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/)
{
$1 if (!layout) layout = layout_;
$ if (!layout) return TX_DEBUG_ERROR ("Íå óñòàíîâëåí äèíàìè÷åñêèé øàáëîí äèàëîãà"), 0;
$ if (!bufsize) bufsize = 1024;
$ DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize);
$ if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Íåò ïàìÿòè äëÿ øàáëîíà äèàëîãà"), 0;
$ const Layout* dlg = &layout[0];
$ const Layout def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 };
$ void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize,
(dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0,
dlg->x, dlg->y, dlg->sx, dlg->sy,
dlg->caption? dlg->caption : def.caption,
dlg->font? dlg->font : def.font,
dlg->fontsize? dlg->fontsize : def.fontsize, NULL);
$ WORD i = 0;
$ for (i = 1; layout[i].wndclass != END; ++i)
{
$ const Layout* item = &layout[i];
$ ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl),
item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy,
item->id, (const char*) item->wndclass, item->caption);
}
$ tmpl->cdit = (unsigned short) (i-1);
$ INT_PTR res = DialogBoxIndirectParam (NULL, tmpl, NULL, dialogProc__, (LPARAM) this);
$ GlobalFree (tmpl);
$ return res;
}
//-----------------------------------------------------------------------------------------------------------------
int txDialog::dialogProc (HWND, UINT, WPARAM, LPARAM)
{
$1 return FALSE;
}
//-----------------------------------------------------------------------------------------------------------------
ptrdiff_t CALLBACK txDialog::dialogProc__ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
$1 static txDialog* this__ = NULL;
$ if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam;
$ if (!this__) return FALSE;
$ switch (msg)
{
case WM_INITDIALOG: $ SetForegroundWindow (wnd); break;
case WM_COMMAND: $ switch (LOWORD (wParam))
{
case IDOK:
case IDCANCEL: $ SetForegroundWindow (txWindow());
$ EndDialog (wnd, (INT_PTR) this__); break;
default: $ break;
}
default: $ break;
}
$ return this__-> dialogProc (wnd, msg, wParam, lParam);
}
//-----------------------------------------------------------------------------------------------------------------
void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
WORD controls, short x, short y, short cx, short cy,
const char caption[], const char font[], WORD fontsize, HANDLE menu)
{
$1 _TX_IF_ARGUMENT_FAILED (globalMem) return NULL;
$ WORD* pw = (WORD*) globalMem;
$ DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++;
$ tmpl->style = style;
$ tmpl->dwExtendedStyle = exStyle;
$ tmpl->cdit = controls;
$ tmpl->x = x;
$ tmpl->y = y;
$ tmpl->cx = cx;
$ tmpl->cy = cy;
$ *pw++ = (WORD)(ptrdiff_t) NULL;
$ *pw++ = (WORD)(ptrdiff_t) menu;
$ if (caption)
{
$ pw += MultiByteToWideChar (_TX_CP, 0, caption? caption : "", -1, (wchar_t*) pw,
(int) (bufsize? bufsize - ((char*)pw - (char*)globalMem) : 0xFFFF));
}
$ if (style & DS_SETFONT)
{
$ *pw++ = fontsize;
$ pw += MultiByteToWideChar (_TX_CP, 0, font? font : "", -1, (wchar_t*) pw,
(int) (bufsize? bufsize - ((char*)pw - (char*)globalMem) : 0xFFFF));
}
$ return pw;
}
//-----------------------------------------------------------------------------------------------------------------
void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
short x, short y, short cx, short cy,
WORD id, const char wclass[], const char caption[])
{
$1 _TX_IF_ARGUMENT_FAILED (dlgTemplatePtr) return NULL;
$ WORD* pw = (LPWORD) dlgTemplatePtr; // Force align at word boundary
$ (ULONG&) pw += 3;
$ (ULONG&) pw >>= 2;
$ (ULONG&) pw <<= 2;
$ DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++;
$ tmpl->style = style;
$ tmpl->dwExtendedStyle = exStyle;
$ tmpl->x = x;
$ tmpl->y = y;
$ tmpl->cx = cx;
$ tmpl->cy = cy;
$ tmpl->id = id;
$ if (HIWORD (wclass) == 0xFFFF)
{
$ *pw++ = (WORD) (HIWORD ((ptrdiff_t) wclass));
$ *pw++ = (WORD) (LOWORD ((ptrdiff_t) wclass));
}
else if (wclass)
{
$ pw += MultiByteToWideChar (_TX_CP, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw,
(int) (bufsize? bufsize - ((char*)pw - (char*)dlgTemplatePtr) : 0xFFFF));
}
else
{
$ *pw++ = 0;
}
$ if (caption)
{
$ pw += MultiByteToWideChar (_TX_CP, 0, caption, -1, (wchar_t*) pw,
(int) (bufsize? bufsize - ((char*)pw - (char*)dlgTemplatePtr) : 0xFFFF));
}
else
{
$ *pw++ = 0;
}
$ *pw++ = 0;
$ return pw;
}
//}
//=================================================================================================================
//=================================================================================================================
//{ Cleaning up the utility macros
// Î÷èñòêà ñëóæåáíûõ ìàêðîñîâ
//=================================================================================================================
#undef $
//}
//=================================================================================================================
//! @endcond
//}
//=================================================================================================================
/*! @cond INTERNAL */
} } // namespace TX, anonymous namespace
/*! @endcond */
//-----------------------------------------------------------------------------------------------------------------
//{ Easy using of TX:: and some of std::
//-----------------------------------------------------------------------------------------------------------------
using namespace TX; // Allow easy usage of TXLib functions
using ::std::cin; // Predefined usings to avoid "using namespace std"
using ::std::cout;
using ::std::cerr;
using ::std::string;
//}
//-----------------------------------------------------------------------------------------------------------------
//=================================================================================================================
//{ [Experimental] Debugging macros
//! @name Ýêñïåðèìåíòàëüíûå îòëàäî÷íûå ìàêðîñû
//=================================================================================================================
//{----------------------------------------------------------------------------------------------------------------
//! @ingroup Misc
//! @brief Îòëàäî÷íàÿ ïå÷àòü ïåðåìåííîé âî âðåìÿ âû÷èñëåíèÿ âûðàæåíèÿ èëè ó÷àñòêà êîäà
//! âî âðåìÿ åãî âûïîëíåíèÿ
//!
//! @warning Ýòè ìàêðîñû ìîãóò èçìåíèòüñÿ â áóäóùèõ âåðñèÿõ.
//!
//! @title Íàçíà÷åíèå: @table
//! @tr <tt> $ (x) </tt> @td Ïå÷àòü èìåíè è çíà÷åíèÿ ïåðåìåííîé @c x âíóòðè âûðàæåíèÿ.
//! @tr <tt> $_(x) </tt> @td Ïå÷àòü òîëüêî çíà÷åíèÿ ïåðåìåííîé @c x âíóòðè âûðàæåíèÿ.
//! @tbr
//! @tr <tt> $$ (expr) </tt> @td Ïå÷àòü âûðàæåíèÿ, åãî âû÷èñëåíèå, ïå÷àòü è âîçâðàò çíà÷åíèÿ. @n
//! Åñëè âûðàæåíèå ñîäåðæèò îïåðàòîð "çàïÿòàÿ", íå âçÿòûé â ñêîáêè,
//! íåîáõîäèìî îêðóæàòü expr åùå îäíîé ïàðîé ñêîáîê.
//! @tr <tt> $$_(expr) </tt> @td Òî æå, ÷òî è <tt>$$(expr),</tt> íî âòîðàÿ ïå÷àòü èäåò áåç íîâîé ñòðîêè.
//! @tbr
//! @tr <tt> $$$ (expr) </tt> @td Òî æå, ÷òî è <tt>$$(expr),</tt> íî äëÿ îïåðàòîðîâ èëè áëîêîâ êîäà (áåç âîçâðàòà çíà÷åíèÿ).
//! @tr <tt> $$$_(expr) </tt> @td Òî æå, ÷òî è <tt>$$$(expr),</tt> íî âòîðàÿ ïå÷àòü èäåò áåç íîâîé ñòðîêè.
//! @tbr
//! @tr <tt> $$$$ </tt> @td Ïå÷àòü ìåñòîïîëîæåíèÿ â êîäå.
//! @tr <tt> $$$$_ </tt> @td Ïå÷àòü ìåñòîïîëîæåíèÿ â êîäå (òîëüêî èìÿ ôóíêöèè).
//! @tr <tt> $n </tt> @td Ïåðåâîä ñòðîêè (ïå÷àòü @c '\\n').
//! @endtable
//!
//! @title Óñòàíîâêà àòðèáóòîâ ñèìâîëîâ êîíñîëè: @table
//! @tr @c $d @td Ñâåòëî-ñåðûé öâåò @td @td @c $T @td Ïðîçðà÷íûé öâåò
//! @tr @c $b @td Ñâåòëî-ñèíèé öâåò @td @td @c $B @td Òåìíî-ñèíèé öâåò
//! @tr @c $g @td Ñâåòëî-çåëåíûé öâåò @td @td @c $G @td Òåìíî-çåëåíûé öâåò
//! @tr @c $c @td Ñâåòëî-áèðþçîâûé öâåò @td @td @c $C @td Òåìíî-áèðþçîâûé öâåò
//! @tr @c $r @td Ñâåòëî-êðàñíûé öâåò @td @td @c $R @td Òåìíî-êðàñíûé öâåò
//! @tr @c $m @td Ñâåòëî-ìàëèíîâûé öâåò @td @td @c $M @td Òåìíî-ìàëèíîâûé öâåò
//! @tr @c $y @td Æåëòûé öâåò @td @td @c $Y @td Òåìíî-æåëòûé öâåò
//! @tr @c $t @td Áåëûé öâåò @td @td @c $D @td Òåìíî-ñåðûé öâåò
//! @endtable
//! @title @table
//! @tr @c $a @td Assertion @td Ñâåòëî-çåëåíûé íà çåëåíîì @td
//! @td @c $A @td Assertion bold @td Æåëòûé íà çåëåíîì @td
//! @tr @c $i @td Information @td Ñâåòëî-ñèíèé íà ñèíåì @td
//! @td @c $I @td Information bold @td Æåëòûé íà ñèíåì @td
//! @tr @c $w @td Warning @td Ñâåòëî-ìàëèíîâûé íà ìàëèíîâîì @td
//! @td @c $W @td Warning bold @td Æåëòûé íà ìàëèíîâîì @td
//! @tr @c $e @td Error @td Ñâåòëî-êðàñíûé íà êðàñíîì @td
//! @td @c $E @td Error bold @td Æåëòûé íà êðàñíîì @td
//! @tr @c $f @td Fatal @td ×åðíûé íà ñâåòëî-êðàñíîì @td
//! @td @c $F @td Fatal bold @td Ìàëèíîâûé íà ñâåòëî-êðàñíîì @td
//! @tr @c $l @td Location @td ×åðíûé íà òåìíî-ñåðîì @td
//! @td @c $L @td Location bold @td Ñâåòëî-ñåðûé íà òåìíî-ñåðîì @td
//! @endtable
//! @title @table
//! @tr @c $s @td Çàïîìíèòü àòðèáóòû. Ïðè âûõîäå èç áëîêà êîäà àòðèáóòû âîññòàíàâëèâàþòñÿ.
//! @endtable
//!
//! @see assert(), asserted, __TX_FILELINE__, __TX_FUNCTION__, TX_ERROR
//!
//! @usage @code
//! $g // green
//! int x = 5;
//! int y = $(x) + 1;
//! $$( x = $(y) + 2 );
//!
//! $r // red
//! double xy = $$( pow (x, y) );
//!
//! $$$$
//! double h = $$(( $(x) = x*x, y = y*y, sqrt ($(x+y)) ));
//!
//! $$( txCreateWindow (800, 600) );
//!
//! $d // default color
//! $$$( if ($(xy) < $(h)) { $s return $(h); } )
//!
//! $$$$
//! @endcode
//}----------------------------------------------------------------------------------------------------------------
#ifndef __TX_DEBUG_MACROS
#define __TX_DEBUG_MACROS ("Ãðóïïà îòëàäî÷íûõ $-ìàêðîñîâ")
//! @cond INTERNAL
#define $_(var) _txDump (var)
#define $(var) ( _txDump ((var), "[" #var " = ", "] ") )
#define $$(cmd) ( std::cerr << "\n[" __TX_FILELINE__ ": " #cmd "]\n", \
_txDump ((cmd),"\n[" __TX_FILELINE__ ": " #cmd ": ", ", DONE]\n") )
#define $$_(cmd) ( std::cerr << "\n[" __TX_FILELINE__ ": " #cmd "]\n", \
_txDump ((cmd), "[" __TX_FILELINE__ ": " #cmd ": ", ", DONE]\n") )
#define $$$(cmd) { std::cerr << "\n[" __TX_FILELINE__ ": " #cmd "]\n"; \
_txDumpSuffix ("\n[" __TX_FILELINE__ ": " #cmd " DONE]\n"); { cmd; } }
#define $$$_(cmd) { std::cerr << "\n[" __TX_FILELINE__ ": " #cmd "]\n"; \
_txDumpSuffix ( "[" __TX_FILELINE__ ": " #cmd " DONE]\n"); { cmd; } }
#define $$$$ { txOutputDebugPrintf ("\f\n"); \
{ $s $l txOutputDebugPrintf ("\f" "[%s (%d) %s]", __FILE__, __LINE__, __TX_FUNCTION__); } txOutputDebugPrintf ("\f\n"); }
#define $$$$_ { txOutputDebugPrintf ("\f\n"); \
{ $s $l txOutputDebugPrintf ("\f" "[%s]", __func__); } txOutputDebugPrintf ("\f\n"); }
#define $n std::cerr << "\n";
#define $s _txSaveConsoleAttr __txSaveConsoleAttr;
#define $T txSetConsoleAttr (0x00);
#define $B txSetConsoleAttr (0x01);
#define $G txSetConsoleAttr (0x02);
#define $C txSetConsoleAttr (0x03);
#define $R txSetConsoleAttr (0x04);
#define $M txSetConsoleAttr (0x05);
#define $Y txSetConsoleAttr (0x06);
#define $d txSetConsoleAttr (0x07);
#define $D txSetConsoleAttr (0x08);
#define $b txSetConsoleAttr (0x09);
#define $g txSetConsoleAttr (0x0a);
#define $c txSetConsoleAttr (0x0b);
#define $r txSetConsoleAttr (0x0c);
#define $m txSetConsoleAttr (0x0d);
#define $y txSetConsoleAttr (0x0e);
#define $t txSetConsoleAttr (0x0f);
#define $i txSetConsoleAttr (0x1b);
#define $I txSetConsoleAttr (0x1e);
#define $a txSetConsoleAttr (0x2a);
#define $A txSetConsoleAttr (0x2e);
#define $e txSetConsoleAttr (0x4f);
#define $E txSetConsoleAttr (0x4e);
#define $w txSetConsoleAttr (0x5d);
#define $W txSetConsoleAttr (0x5e);
#define $f txSetConsoleAttr (0xc0);
#define $F txSetConsoleAttr (0xc5);
#define $l txSetConsoleAttr (0x80);
#define $L txSetConsoleAttr (0x87);
//-----------------------------------------------------------------------------------------------------------------
#if !defined (_MSC_VER_6)
template <typename T> inline
const T& _txDump (const T& value, const char* prefix = "", const char* suffix = "")
{
std::cerr << prefix << value << suffix;
return value;
}
#endif
template <typename T> inline
T& _txDump ( T& value, const char* prefix = "", const char* suffix = "")
{
std::cerr << prefix << value << suffix;
return value;
}
struct _txDumpSuffix
{
const char* suffix_;
inline _txDumpSuffix (const char* suffix = "") : suffix_ (suffix) {}
inline ~_txDumpSuffix() { std::cerr << suffix_; }
_txDumpSuffix (const _txDumpSuffix&);
_txDumpSuffix& operator = (const _txDumpSuffix&);
};
struct _txSaveConsoleAttr
{
unsigned attr_;
inline _txSaveConsoleAttr() : attr_ (txGetConsoleAttr ()) {}
inline _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr); }
inline ~_txSaveConsoleAttr() { txSetConsoleAttr (attr_); }
};
//! @endcond
#endif
//}
//=================================================================================================================
//-----------------------------------------------------------------------------------------------------------------
//{ Compiler- and platform-specific
// Àäàïòàöèÿ ê êîìïèëÿòîðàì è ïëàòôîðìàì
//-----------------------------------------------------------------------------------------------------------------
//! @cond INTERNAL
#if defined (_GCC_VER) && (_GCC_VER >= 420)
#pragma GCC optimize ("strict-aliasing")
#if (_GCC_VER >= 460)
#pragma GCC diagnostic pop
#else
#pragma GCC diagnostic warning "-Wstrict-aliasing"
#pragma GCC diagnostic warning "-Wshadow"
#endif
// Still block this warnings to avoid reporting about "= {0}" or "= {}" init style,
// and old style cast used in Windows.h RGB() macro.
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wold-style-cast"
// These warnings really occur at end of compilation, so block them too.
#pragma GCC diagnostic ignored "-Wunreachable-code"
#pragma GCC diagnostic ignored "-Wunused-label"
#pragma GCC diagnostic ignored "-Winline"
#endif
//-----------------------------------------------------------------------------------------------------------------
#if defined (_MSC_VER)
#pragma warning (default: 4127) // conditional expression is constant
#pragma warning (default: 4351) // new behavior: elements of array will be default initialized
#pragma warning (default: 4511) // copy constructor could not be generated
#pragma warning (default: 4512) // assignment operator could not be generated
#pragma warning (default: 4663) // C++ language change: to explicitly specialize class template
#pragma warning (default: 4702) // unreachable code
#if (_MSC_VER >= 1400) // MSVC 8 (2005) or greater
#pragma warning (default: 26135) // missing locking annotation
#pragma warning (default: 28125) // the function must be called from within a try/except block
#pragma warning (default: 28159) // consider using another function instead
#endif
// This warning really occur at end of compilation, so still block it.
#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
#endif
#if defined (__INTEL_COMPILER)
#pragma warning (default: 174) // remark: expression has no effect
#pragma warning (default: 304) // remark: access control not specified ("public" by default)
#pragma warning (default: 522) // remark: function redeclared "inline" after being called
#pragma warning (default: 981) // remark: operands are evaluated in unspecified order
#pragma warning (default: 1684) // conversion from pointer to same-sized integral type (potential portability problem)
#endif
//! @endcond
//}
//-----------------------------------------------------------------------------------------------------------------
#endif // __TXLIB_H_INCLUDED
//=================================================================================================================
// EOF
//=================================================================================================================