TX Library Help – Version: 00173a, Revision: 174
 ALL  Windows graphics in a sandbox

TXLib.h

См. документацию.
00001 //=================================================================================================================
00002 //           TXLib.h - Библиотека Тупого Художника (The Dumb Artist Library, TX Library, TXLib) - (C) Ilya Dedinsky
00003 //=================================================================================================================
00004 //           [These sections are for folding control  in Code::Blocks]         [$Date: 2025-05-31 01:13:58 +0400 $]
00005 //           [Best viewed with "Fold all on file open" option enabled]         [Best screen/page width = 120 chars]
00006 //                                                                                                                 
00007 //           [If RUSSIAN CHARS below are UNREADABLE, check this file codepage. It should be CP1251, NOT UTF-8 etc.]
00008 //{          [Use RELOAD options in your IDE or editor (CLion / Visual Studio Code / ...), and do NOT use Convert.]
00009 //=================================================================================================================
00102 //           $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $
00103 //-----------------------------------------------------------------------------------------------------------------
00110 //}
00111 //=================================================================================================================
00112 
00113 #if !defined (__TXLIB_H_INCLUDED)                                            // <<< THE CODE IS HERE, UNFOLD IT <<<
00114 #define       __TXLIB_H_INCLUDED
00115 
00116 //-----------------------------------------------------------------------------------------------------------------
00117 //{          Version information and configuration
00118 //-----------------------------------------------------------------------------------------------------------------
00119 
00120 //{----------------------------------------------------------------------------------------------------------------
00142 //}----------------------------------------------------------------------------------------------------------------
00144 
00145 #define _TX_VER      _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-05-31 01:13:58 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00146 #define _TX_VERSION  _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-05-31 01:13:58 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00147 #define _TX_AUTHOR   _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-05-31 01:13:58 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00148 
00150 #define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2)  ((0x##ver##u << 16) | 0x##rev##u)
00151 #define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2)  "TXLib [Ver: " #ver ", Rev: " #rev ", Date: " #date "]"
00152 #define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2)  "Copyright (C) " auth
00153 
00154 
00156 //{----------------------------------------------------------------------------------------------------------------
00163 //}----------------------------------------------------------------------------------------------------------------
00164 
00165 #if !defined (_TX_MODULE)
00166     #define   _TX_MODULE      "TXLib"
00167 #endif
00168 
00169 //{----------------------------------------------------------------------------------------------------------------
00173 //}----------------------------------------------------------------------------------------------------------------
00174 
00175 #if    defined (__GNUC__)
00176 
00177     #define _GCC_VER          ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ )
00178 
00179     #define __TX_COMPILER__   "GNU g++ "            TX_QUOTE (__GNUC__)       "."  \
00180                                                     TX_QUOTE (__GNUC_MINOR__) "."  \
00181                                                     TX_QUOTE (__GNUC_PATCHLEVEL__) \
00182                               ", std="              TX_QUOTE (__cplusplus)
00183 
00184 #elif  defined (__clang__) || defined (__clang_major__)
00185 
00186     #define _CLANG_VER        ( __clang_major__*100 + __clang_minor__*10 + __clang_patchlevel__ )
00187 
00188     #define __TX_COMPILER__   "Clang "              TX_QUOTE (__clang_major__) "."  \
00189                                                     TX_QUOTE (__clang_minor__) "."  \
00190                                                     TX_QUOTE (__clang_patchlevel__) \
00191                               ", std="              TX_QUOTE (__cplusplus)
00192 #elif  defined (_MSC_VER)
00193 
00194     #define __TX_COMPILER__   "MSVS "               TX_QUOTE (_MSC_VER)            \
00195                               ", std="              TX_QUOTE (__cplusplus)
00196 
00197 #elif  defined (__INTEL_COMPILER)
00198 
00199     #define __TX_COMPILER__   "Intel C++ "          TX_QUOTE (__INTEL_COMPILER)    \
00200                               ", std="              TX_QUOTE (__cplusplus)
00201 #else
00202 
00203     #define __TX_COMPILER__   "Unknown C++, std="   TX_QUOTE (__cplusplus)
00204     #endif
00205 
00207 
00208 #define  TX_QUOTE(sym)        _TX_QUOTE (sym)
00209 #define _TX_QUOTE(sym)        #sym
00210 
00211 #define  TX_JOIN(sym1, sym2)  _TX_JOIN (sym1, sym2)
00212 #define _TX_JOIN(sym1, sym2)  sym1 ## sym2
00213 
00215 
00216 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1800)  // MSVC 2013
00217 
00218     #define _TX_CPP11         1
00219     #endif
00220 
00221 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1900)  // MSVC 2015
00222 
00223     #define _TX_CPP11_MSVC15  1
00224     #endif
00225 
00226 //{----------------------------------------------------------------------------------------------------------------
00230 //}----------------------------------------------------------------------------------------------------------------
00231 
00232 #if   !defined (NDEBUG) &&  defined (_DEBUG)
00233     #define _TX_BUILDMODE     "DEBUG"
00234 
00235 #elif !defined (NDEBUG) && !defined (_DEBUG)
00236     #define _TX_BUILDMODE     "Debug"
00237 
00238 #elif  defined (NDEBUG)
00239     #define _TX_BUILDMODE     "Release"
00240 #endif
00241 
00242 //{----------------------------------------------------------------------------------------------------------------
00246 //}----------------------------------------------------------------------------------------------------------------
00247 
00248 #define __TX_FILELINE__       __FILE__ ":" TX_QUOTE (__LINE__)
00249 
00250 //{----------------------------------------------------------------------------------------------------------------
00258 //}----------------------------------------------------------------------------------------------------------------
00259 
00260 #if defined (__GNUC__) || defined (__clang__) || defined (__clang_major__)
00261     #define __TX_FUNCTION__   __PRETTY_FUNCTION__
00262 
00263 #elif defined (__FUNCSIG__)
00264     #define __TX_FUNCTION__   __FUNCSIG__
00265 
00266 #elif defined (__FUNCTION__)
00267     #define __TX_FUNCTION__   __FUNCTION__
00268 
00269 #elif defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)
00270     #define __TX_FUNCTION__   __FUNCTION__
00271 
00272 #elif defined (__BORLANDC__) && (__BORLANDC__ >= 0x550)
00273     #define __TX_FUNCTION__   __FUNC__
00274 
00275 #elif defined (__cplusplus) && (__cplusplus >= 199711L)
00276     #define __TX_FUNCTION__   __func__
00277 
00278 #elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
00279     #define __TX_FUNCTION__   __func__
00280 
00281 #elif defined (__PYTHON__)
00282     #error No Python. No. Using parseltongue languages can lead you to Slytherin.
00283 
00284 #else
00285     #define __TX_FUNCTION__   "(" __TX_FILELINE__ ")"
00286 
00287 #endif
00288 
00289 #if !defined (__func__) && defined (__FUNCTION__)
00290     #define   __func__        __FUNCTION__
00291 
00292 #endif
00293 
00294 //}
00295 //-----------------------------------------------------------------------------------------------------------------
00296 
00297 //-----------------------------------------------------------------------------------------------------------------
00298 //{          Compiler- and platform-specific
00300 //-----------------------------------------------------------------------------------------------------------------
00302 
00303 #if !defined (__cplusplus)
00304 
00305     #ifdef __GNUC__
00306     #error
00307     #error ---------------------------------------------------------------------------------------
00308     #endif
00309     #error TXLib.h: Must use C++ to compile TXLib.h. Now you are using C only.
00310     #error
00311     #error CHECK source file EXTENSION. Maybe it is ".C". It must be ".CPP".
00312     #error If your file is named, for example, "Untitled.C", go to menu [File],
00313     #error then [Save As] and rename it to "Untitled.CPP". Please do NOT use spaces.
00314     #error ---------------------------------------------------------------------------------------
00315     #error
00316 
00317 #endif
00318 
00319 //-----------------------------------------------------------------------------------------------------------------
00320 
00321 #if !defined (WIN32) && !defined (__WIN32__) && !defined(_WIN32) && !defined(_WIN32_WINNT) && !defined (__CYGWIN__)
00322 
00323     #ifdef __GNUC__
00324     #error
00325     #error ---------------------------------------------------------------------------------------
00326     #endif
00327     #error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW or Cygwin) is the only supported OS, sorry.
00328     #error
00329     #error In Linux or MacOS, you should write your own TXLib and share it with your friends, or use wine.
00330     #error ---------------------------------------------------------------------------------------
00331     #error
00332 
00333 #endif
00334 
00335 //-----------------------------------------------------------------------------------------------------------------
00336 
00337 #if  defined (UNICODE) || defined (_UNICODE)
00338 
00339     #ifdef __GNUC__
00340     #warning TXLib.h: Disabling the UNICODE
00341     #endif
00342 
00343     #undef   UNICODE                                 // Burn Unicode, burn
00344     #undef  _UNICODE
00345 
00346     #if defined (_WINDOWS_H) || defined (_INC_WINDOWS) || defined (_WINDOWS_) || defined (__WINDOWS__)
00347 
00348     #ifdef __GNUC__
00349     #error
00350     #error ---------------------------------------------------------------------------------------
00351     #endif
00352     #error TXLib.h: Should include "TXLib.h" BEFORE or INSTEAD of <Windows.h> in UNICODE mode.
00353     #error
00354     #error REARRANGE your #include directives, or DISABLE the UNICODE mode by #undef UNICODE/_UNICODE.
00355     #error ---------------------------------------------------------------------------------------
00356     #error
00357 
00358     #endif
00359 
00360 #endif
00361 
00362 //-----------------------------------------------------------------------------------------------------------------
00363 
00364 #if  defined (__STRICT_ANSI__) && (_GCC_VER < 1120)  // Try to extend strict ANSI rules
00365 
00366     #undef  __STRICT_ANSI__
00367     #define __STRICT_ANSI__UNDEFINED
00368 
00369     #if defined (_STRING_H_) || defined (_INC_STRING) || defined (_STDIO_H_) || defined (_INC_STDIO)
00370 
00371     #ifdef __GNUC__
00372     #error
00373     #error ---------------------------------------------------------------------------------------
00374     #endif
00375     #error TXLib.h: Should include "TXLib.h" BEFORE <string.h> or <stdio.h> in Strict ANSI mode.
00376     #error
00377     #error REARRANGE your #include directives, or DISABLE ANSI-compliancy by #undef __STRICT_ANSI__.
00378     #error ---------------------------------------------------------------------------------------
00379     #error
00380 
00381     #endif
00382 
00383 #endif
00384 
00385 //-----------------------------------------------------------------------------------------------------------------
00386 
00387 #if  defined (__GNUC__)
00388 
00389     #pragma GCC diagnostic ignored     "-Wpragmas"
00390 
00391     #pragma GCC diagnostic warning     "-Wall"
00392     #pragma GCC diagnostic warning     "-Weffc++"
00393     #pragma GCC diagnostic warning     "-Wextra"
00394 
00395     #pragma GCC diagnostic warning     "-Waggressive-loop-optimizations"
00396     #pragma GCC diagnostic warning     "-Walloc-zero"
00397     #pragma GCC diagnostic warning     "-Walloca"
00398     #pragma GCC diagnostic warning     "-Walloca-larger-than=8192"
00399     #pragma GCC diagnostic warning     "-Warray-bounds"
00400     #pragma GCC diagnostic warning     "-Wcast-align"
00401     #pragma GCC diagnostic warning     "-Wcast-qual"
00402     #pragma GCC diagnostic warning     "-Wchar-subscripts"
00403     #pragma GCC diagnostic warning     "-Wconditionally-supported"
00404     #pragma GCC diagnostic warning     "-Wconversion"
00405     #pragma GCC diagnostic warning     "-Wctor-dtor-privacy"
00406     #pragma GCC diagnostic warning     "-Wdangling-else"
00407     #pragma GCC diagnostic warning     "-Wduplicated-branches"
00408     #pragma GCC diagnostic warning     "-Wempty-body"
00409     #pragma GCC diagnostic warning     "-Wfloat-equal"
00410     #pragma GCC diagnostic warning     "-Wformat-nonliteral"
00411     #pragma GCC diagnostic warning     "-Wformat-overflow=2"
00412     #pragma GCC diagnostic warning     "-Wformat-security"
00413     #pragma GCC diagnostic warning     "-Wformat-signedness"
00414     #pragma GCC diagnostic warning     "-Wformat-truncation=2"
00415     #pragma GCC diagnostic warning     "-Wformat=2"
00416     #pragma GCC diagnostic warning     "-Wlarger-than=8192"
00417     #pragma GCC diagnostic warning     "-Wlogical-op"
00418     #pragma GCC diagnostic warning     "-Wmismatched-tags"
00419     #pragma GCC diagnostic warning     "-Wmissing-declarations"
00420     #pragma GCC diagnostic warning     "-Wnarrowing"
00421     #pragma GCC diagnostic warning     "-Wnon-virtual-dtor"
00422     #pragma GCC diagnostic warning     "-Wnonnull"
00423     #pragma GCC diagnostic warning     "-Wopenmp-simd"
00424     #pragma GCC diagnostic warning     "-Woverloaded-virtual"
00425     #pragma GCC diagnostic warning     "-Wpacked"
00426     #pragma GCC diagnostic warning     "-Wpointer-arith"
00427     #pragma GCC diagnostic warning     "-Wredundant-decls"
00428     #pragma GCC diagnostic warning     "-Wredundant-tags"
00429     #pragma GCC diagnostic warning     "-Wrestrict"
00430     #pragma GCC diagnostic warning     "-Wshadow"
00431     #pragma GCC diagnostic warning     "-Wsign-promo"
00432     #pragma GCC diagnostic warning     "-Wstack-usage=8192"
00433     #pragma GCC diagnostic warning     "-Wstrict-aliasing"
00434     #pragma GCC diagnostic warning     "-Wstrict-null-sentinel"
00435     #pragma GCC diagnostic warning     "-Wstrict-overflow=2"
00436     #pragma GCC diagnostic warning     "-Wstringop-overflow=4"
00437     #pragma GCC diagnostic warning     "-Wsuggest-attribute=noreturn"
00438     #pragma GCC diagnostic warning     "-Wsuggest-final-methods"
00439     #pragma GCC diagnostic warning     "-Wsuggest-final-types"
00440     #pragma GCC diagnostic warning     "-Wsuggest-override"
00441     #pragma GCC diagnostic warning     "-Wswitch-default"
00442     #pragma GCC diagnostic warning     "-Wswitch-enum"
00443     #pragma GCC diagnostic warning     "-Wsync-nand"
00444     #pragma GCC diagnostic warning     "-Wundef"
00445     #pragma GCC diagnostic warning     "-Wunused"
00446     #pragma GCC diagnostic warning     "-Wvarargs"
00447     #pragma GCC diagnostic warning     "-Wvla-larger-than=8192"
00448 
00449     #pragma GCC diagnostic error       "-Wsizeof-array-argument"
00450 
00451     #pragma GCC diagnostic ignored     "-Waddress"
00452     #pragma GCC diagnostic ignored     "-Winline"
00453     #pragma GCC diagnostic ignored     "-Wliteral-suffix"
00454     #pragma GCC diagnostic ignored     "-Wmissing-field-initializers"
00455     #pragma GCC diagnostic ignored     "-Wnonnull-compare"
00456     #pragma GCC diagnostic ignored     "-Wold-style-cast"
00457     #pragma GCC diagnostic ignored     "-Wunreachable-code"
00458     #pragma GCC diagnostic ignored     "-Wunused-const-variable"
00459     #pragma GCC diagnostic ignored     "-Wunused-function"
00460     #pragma GCC diagnostic ignored     "-Wvariadic-macros"
00461 
00462     #pragma GCC diagnostic warning     "-Wpragmas"
00463 
00464     //{ These warning settings for TXLib.h only and will be re-enabled at end of file:
00465 
00466     #pragma GCC push_options
00467     #pragma GCC diagnostic push
00468 
00469     #pragma GCC diagnostic ignored     "-Wpragmas"
00470 
00471     #pragma GCC diagnostic ignored     "-Wpedantic"
00472     #pragma GCC diagnostic ignored     "-Waddress"
00473     #pragma GCC diagnostic ignored     "-Warray-bounds"
00474     #pragma GCC diagnostic ignored     "-Wclobbered"
00475     #pragma GCC diagnostic ignored     "-Wdeprecated-declarations"
00476     #pragma GCC diagnostic ignored     "-Wfloat-equal"
00477     #pragma GCC diagnostic ignored     "-Wformat-nonliteral"
00478     #pragma GCC diagnostic ignored     "-Wlarger-than="
00479     #pragma GCC diagnostic ignored     "-Wmisleading-indentation"
00480     #pragma GCC diagnostic ignored     "-Wnon-virtual-dtor"
00481     #pragma GCC diagnostic ignored     "-Wredundant-decls"
00482     #pragma GCC diagnostic ignored     "-Wshadow"
00483     #pragma GCC diagnostic ignored     "-Wsign-conversion"
00484     #pragma GCC diagnostic ignored     "-Wstrict-aliasing"
00485     #pragma GCC diagnostic ignored     "-Wsuggest-override"
00486     #pragma GCC diagnostic ignored     "-Wunused-label"    // Just for fun in _txCanvas_OnCmdAbout()
00487     #pragma GCC diagnostic ignored     "-Wunused-value"
00488     #pragma GCC diagnostic ignored     "-Wformat-zero-length"
00489     #pragma GCC diagnostic ignored     "-Wpacked-not-aligned"
00490     #pragma GCC optimize               "no-strict-aliasing"
00491 
00492     #pragma GCC diagnostic warning     "-Wpragmas"
00493 
00494     #if defined (__CYGWIN__) && !defined (_TX_TESTING)
00495     #pragma GCC system_header                    // This is not a fair play, but this is the only way to deal with Cygwin :(
00496     #endif
00497 
00498     //}
00499 
00500     #define _tx_thread                 __thread
00501     #define _tx_decltype(value)        __decltype (value)
00502 
00503     #define     _FORTIFY_SOURCE        2
00504 
00505     #ifndef     MINGW_HAS_SECURE_API
00506         #define MINGW_HAS_SECURE_API   1
00507     #endif
00508 
00509     #if defined (TX_USE_SFML)
00510         #define _GLIBCXX_NDEBUG
00511     #endif
00512 
00513     #ifndef     _GLIBCXX_NDEBUG                  // TXLib enables _GLIBCXX_DEBUG by default. When using third-party libraries
00514         #define _GLIBCXX_DEBUG                   // compiled without _GLIBCXX_DEBUG (SFML, for example), #define _GLIBCXX_NDEBUG
00515         #define _GLIBCXX_DEBUG_PEDANTIC          // *before* including TXLib.h.
00516     #endif
00517 
00518     #if defined (_WIN64)                         // removed in x86 because printf ("%g", double) failure, this prints 0 always
00519     #ifndef     __USE_MINGW_ANSI_STDIO
00520         #define __USE_MINGW_ANSI_STDIO 1
00521     #endif
00522     #endif
00523 
00524     template <typename T>
00525     inline T _txNOP (T value)          { return value; }   // To suppress performance warnings in assert etc.
00526 
00527     // From MinGW\include\float.h which is replaced by MinGW\lib\gcc\i686-pc-mingw32\x.x.x\include\float.h
00528     extern "C" __declspec (dllimport)  unsigned __cdecl _controlfp (unsigned control, unsigned mask);
00529     extern "C"                         void     __cdecl _fpreset   ();
00530 
00531 #else
00532 
00533     #define     __attribute__( attr )
00534     #define     _txNOP( value )        ( value )
00535 
00536 #endif
00537 
00538 //-----------------------------------------------------------------------------------------------------------------
00539 
00540 #if  defined (__clang__) || defined (__clang_major__)
00541 
00542     #pragma clang diagnostic ignored   "-Wunknown-pragmas"
00543 
00544     #pragma clang diagnostic warning   "-Wall"
00545     #pragma clang diagnostic warning   "-Weffc++"
00546     #pragma clang diagnostic warning   "-Wextra"
00547 
00548     #pragma clang diagnostic warning   "-Wcast-qual"
00549     #pragma clang diagnostic warning   "-Wchar-subscripts"
00550     #pragma clang diagnostic warning   "-Wconversion"
00551     #pragma clang diagnostic warning   "-Wctor-dtor-privacy"
00552     #pragma clang diagnostic warning   "-Wempty-body"
00553     #pragma clang diagnostic warning   "-Wfloat-equal"
00554     #pragma clang diagnostic warning   "-Wformat"
00555     #pragma clang diagnostic warning   "-Wformat-nonliteral"
00556     #pragma clang diagnostic warning   "-Wformat-security"
00557     #pragma clang diagnostic warning   "-Wmissing-declarations"
00558     #pragma clang diagnostic warning   "-Wnon-virtual-dtor"
00559     #pragma clang diagnostic warning   "-Woverloaded-virtual"
00560     #pragma clang diagnostic warning   "-Wpacked"
00561     #pragma clang diagnostic warning   "-Wpointer-arith"
00562     #pragma clang diagnostic warning   "-Wredundant-decls"
00563     #pragma clang diagnostic warning   "-Wshadow"
00564     #pragma clang diagnostic warning   "-Wsign-promo"
00565     #pragma clang diagnostic warning   "-Wstrict-aliasing"
00566     #pragma clang diagnostic warning   "-Wstrict-overflow"
00567     #pragma clang diagnostic warning   "-Wswitch-default"
00568     #pragma clang diagnostic warning   "-Wswitch-enum"
00569     #pragma clang diagnostic warning   "-Wunused"
00570 
00571     #pragma clang diagnostic ignored   "-Winvalid-source-encoding"
00572     #pragma clang diagnostic ignored   "-Wunused-const-variable"
00573     #pragma clang diagnostic ignored   "-Wunused-variable"
00574 
00575     #pragma clang diagnostic warning   "-Wunknown-pragmas"
00576 
00577     //{ These warning settings for TXLib.h only and will be re-enabled at end of file:
00578 
00579     #pragma clang diagnostic push
00580 
00581     #pragma clang diagnostic ignored   "-Wunknown-pragmas"
00582 
00583     #pragma clang diagnostic ignored   "-Wpedantic"
00584     #pragma clang diagnostic ignored   "-Wcast-align"
00585     #pragma clang diagnostic ignored   "-Wfloat-conversion"
00586     #pragma clang diagnostic ignored   "-Wmicrosoft-cast"
00587     #pragma clang diagnostic ignored   "-Wmisleading-indentation"
00588     #pragma clang diagnostic ignored   "-Wmissing-braces"
00589     #pragma clang diagnostic ignored   "-Wmissing-field-initializers"
00590     #pragma clang diagnostic ignored   "-Wnon-virtual-dtor"
00591     #pragma clang diagnostic ignored   "-Wsign-compare"
00592     #pragma clang diagnostic ignored   "-Wsign-conversion"
00593     #pragma clang diagnostic ignored   "-Wstring-plus-int"
00594     #pragma clang diagnostic ignored   "-Wundef"
00595     #pragma clang diagnostic ignored   "-Wundefined-bool-conversion"
00596     #pragma clang diagnostic ignored   "-Wunused-function"
00597     #pragma clang diagnostic ignored   "-Wunused-value"
00598     #pragma clang diagnostic ignored   "-Wvariadic-macros"
00599 
00600     #pragma clang diagnostic warning   "-Wunknown-pragmas"
00601 
00602     //{ CLang-Tidy options
00603     //
00604     // *,-cert-dcl50-cpp,-cert-dcl58-cpp,-cert-err52-cpp,-cert-err58-cpp,-cert-flp30-c,-cert-msc30-c,-cert-msc32-c,
00605     // -cert-msc50-cpp,-cert-msc51-cpp,-clang-analyzer-core.DivideZero,-cppcoreguidelines-avoid-c-arrays,
00606     // -cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,
00607     // -cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-no-malloc,
00608     // -cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,
00609     // -cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access,
00610     // -cppcoreguidelines-pro-type-vararg,-fuchsia-default-arguments-calls,-fuchsia-default-arguments-declarations,
00611     // -fuchsia-overloaded-operator,-google-build-using-namespace,-google-global-names-in-headers,-google-runtime-int,
00612     // -google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments,
00613     // -hicpp-avoid-c-arrays,-hicpp-avoid-goto,-hicpp-braces-around-statements,-hicpp-deprecated-headers,-hicpp-no-array-decay,
00614     // -hicpp-signed-bitwise,-hicpp-use-equals-delete,-hicpp-use-nullptr,-hicpp-vararg,-llvm-include-order,-hicpp-no-malloc,
00615     // -llvm-namespace-comment,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-use-auto,
00616     // -modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-use-default-member-init,-hicpp-use-auto,
00617     // -modernize-use-equals-delete,-modernize-use-nullptr,-modernize-use-trailing-return-type,-modernize-use-using,
00618     // -readability-braces-around-statements,-readability-else-after-return,-readability-implicit-bool-conversion,
00619     // -readability-isolate-declaration,-readability-magic-numbers,-readability-named-parameter,-modernize-loop-convert
00620     //}
00621 
00622     //}
00623 
00624 #endif
00625 
00626 //-----------------------------------------------------------------------------------------------------------------
00627 
00628 #if  defined (_MSC_VER)
00629 
00630     #pragma warning (push, 4)                    // Set maximum warning level. This 'push' is to set the level only. It will NOT be popped.
00631 
00632     #pragma warning (disable:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning
00633 
00634     #pragma warning (disable:    4514)           // Unreferenced inline function has been removed
00635     #pragma warning (disable:    4710)           // Function not inlined
00636     #pragma warning (disable:    4786)           // Identifier was truncated to '255' characters in the debug information
00637 
00638     #pragma warning (error:      4715)           // Not all control paths return a value
00639 
00640     #pragma warning (default:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning  //-V665
00641 
00642     #pragma warning (disable:   26473)           // Don't cast between pointer types where the source type and the target type are the same (type.1).
00643     #pragma warning (disable:   26475)           // Do not use function style C-casts (es.49).
00644     #pragma warning (disable:   26477)           // Use 'nullptr' rather than 0 or NULL (es.47).
00645     #pragma warning (disable:   26481)           // Don't use pointer arithmetic. Use span instead (bounds.1).
00646     #pragma warning (disable:   26826)           // Don't use C-style variable arguments (f.55).
00647 
00648     // These warning settings for TXLib.h only and will be re-enabled at end of file:
00649 
00650     #pragma warning (push)
00651 
00652     #pragma warning (disable:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning
00653 
00654     #pragma warning (disable:    4091)           // 'typedef': ignored on left of '...' when no variable is declared
00655     #pragma warning (disable:    4124)           // Using __fastcall with stack checking is ineffective
00656     #pragma warning (disable:    4127)           // Conditional expression is constant
00657     #pragma warning (disable:    4200)           // Nonstandard extension used: zero-sized array in struct/union
00658     #pragma warning (disable:    4201)           // Nonstandard extension used: nameless struct/union
00659     #pragma warning (disable:    4351)           // New behavior: elements of array will be default initialized
00660     #pragma warning (disable:    4480)           // Nonstandard extension used: specifying underlying type for enum 'type'
00661     #pragma warning (disable:    4481)           // Nonstandard extension used: override specifier 'override'
00662     #pragma warning (disable:    4555)           // Result of expression not used
00663     #pragma warning (disable:    4611)           // Interaction between '_setjmp' and C++ object destruction is non-portable
00664     #pragma warning (disable:    5045)           // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
00665     #pragma warning (disable:    6269)           // Possibly incorrect order of operations: dereference ignored
00666     #pragma warning (disable:    6285)           // (<non-zero constant>) || (<non-zero constant>) is always a non-zero constant. Did you intend to use bitwize-and operator?
00667     #pragma warning (disable:    6319)           // Use of the comma-operator in a tested expression causes the left argument to be ignored when it has no side-effects
00668     #pragma warning (disable:    6326)           // Potential comparison of a constant with another constant
00669     #pragma warning (disable:    6553)           // The annotation for function 'func' on _Param_(N) does not apply to a value type.
00670     #pragma warning (disable:   26135)           // Missing locking annotation
00671     #pragma warning (disable:   26400)           // Do not assign the result of an allocation or a function call with an owner<T> return value to a raw pointer, use owner<T> instead (i.11).
00672     #pragma warning (disable:   26401)           // Do not delete a raw pointer that is not an owner<T> (i.11).
00673     #pragma warning (disable:   26403)           // Reset or explicitly delete an owner<T> pointer 'name' (r.3).
00674     #pragma warning (disable:   26408)           // Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10).
00675     #pragma warning (disable:   26409)           // Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11).
00676     #pragma warning (disable:   26426)           // Global initializer calls a non-constexpr function 'name' (i.22).
00677     #pragma warning (disable:   26429)           // Symbol 'name' is never tested for nullness, it can be marked as not_null (f.23).
00678     #pragma warning (disable:   26430)           // Symbol 'name' is not tested for nullness on all paths (f.23).
00679     #pragma warning (disable:   26432)           // If you define or delete any default operation in the type 'struct 'name'', define or delete them all (c.21).
00680     #pragma warning (disable:   26435)           // Function 'name' should specify exactly one of 'virtual', 'override', or 'final' (c.128).
00681     #pragma warning (disable:   26438)           // Avoid 'goto' (es.76).
00682     #pragma warning (disable:   26440)           // Function 'name' can be declared 'noexcept' (f.6).
00683     #pragma warning (disable:   26446)           // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).
00684     #pragma warning (disable:   26447)           // The function is declared 'noexcept' but calls function 'func' which may throw exceptions (f.6).
00685     #pragma warning (disable:   26448)           // Consider using gsl::finally if final action is intended (gsl.util).
00686     #pragma warning (disable:   26451)           // Arithmetic overflow: Using operator 'op' on a n-byte value and then casting the result to a m-byte value. Cast the value to the wider type before calling operator 'op' to avoid overflow (io.2).
00687     #pragma warning (disable:   26455)           // Default constructor may not throw. Declare it 'noexcept' (f.6).
00688     #pragma warning (disable:   26457)           // (void) should not be used to ignore return values, use 'std::ignore =' instead (es.48)
00689     #pragma warning (disable:   26460)           // The reference argument 'stream' for function 'name' can be marked as const (con.3).
00690     #pragma warning (disable:   26461)           // The pointer argument 'name' for function 'name' can be marked as a pointer to const (con.3).
00691     #pragma warning (disable:   26462)           // The value pointed to by 'name' is assigned only once, mark it as a pointer to const (con.4).
00692     #pragma warning (disable:   26482)           // Only index into arrays using constant expressions (bounds.2).
00693     #pragma warning (disable:   26483)           // Value 'value' is outside the bounds (min, max) of variable 'name'. Only index into arrays using constant expressions that are within bounds of the array (bounds.2).
00694     #pragma warning (disable:   26485)           // Expression 'expr': No array to pointer decay (bounds.3).
00695     #pragma warning (disable:   26486)           // Don't pass a pointer that may be invalid to a function. Parameter 'n' 'name' in call to 'name' may be invalid (lifetime.3).
00696     #pragma warning (disable:   26487)           // Don't return a pointer 'name' that may be invalid (lifetime.4).
00697     #pragma warning (disable:   26488)           // Do not dereference a potentially null pointer: 'name'. 'name' was null at line 'n' (lifetime.1).
00698     #pragma warning (disable:   26489)           // Don't dereference a pointer that may be invalid: 'name'. 'name' may have been invalidated at line 'n' (lifetime.1).
00699     #pragma warning (disable:   26490)           // Don't use reinterpret_cast (type.1).
00700     #pragma warning (disable:   26492)           // Don't use const_cast to cast away const or volatile (type.3).
00701     #pragma warning (disable:   26493)           // Don't use C-style casts (type.4).
00702     #pragma warning (disable:   26496)           // The variable 'name' is assigned only once, mark it as const (con.4).
00703     #pragma warning (disable:   26497)           // The function 'name' could be marked constexpr if compile-time evaluation is desired (f.4).
00704     #pragma warning (disable:   26812)           // The enum type 'type' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
00705     #pragma warning (disable:   26814)           // The const variable 'name' can be computed at compile-time. Consider using constexpr (con.5).
00706     #pragma warning (disable:   26822)           // Dereferencing a possibly null pointer '...' (lifetime.1).
00707     #pragma warning (disable:   26823)           // Dereferencing a possibly null pointer '...' (lifetime.1).
00708     #pragma warning (disable:   28125)           // The function must be called from within a try/except block
00709     #pragma warning (disable:   28159)           // Consider using another function instead
00710 
00711     #pragma warning (default:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning  //-V665
00712 
00713     #define _tx_thread          __declspec (thread)
00714     #define _tx_decltype(value)   decltype (value)
00715 
00716     #if !defined (_CLANG_VER)
00717 
00718     #pragma setlocale           ("russian")      // Set source file encoding, see also _TX_CODEPAGE
00719 
00720     #if !defined (NDEBUG)
00721         #pragma check_stack     (      on)       // Turn on stack probes at runtime
00722         #pragma strict_gs_check (push, on)       // Detects stack buffer overruns
00723     #endif
00724 
00725     #endif
00726 
00727     #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES  1
00728 
00729 #endif
00730 
00731 //-----------------------------------------------------------------------------------------------------------------
00732 
00733 #if  defined (__INTEL_COMPILER)
00734 
00735     #pragma warning (disable:    174)            // Remark: expression has no effect
00736     #pragma warning (disable:    304)            // Remark: access control not specified ("public" by default)
00737     #pragma warning (disable:    444)            // Remark: destructor for base class "..." is not virtual
00738     #pragma warning (disable:    522)            // Remark: function "..." redeclared "inline" after being called
00739     #pragma warning (disable:    981)            // Remark: operands are evaluated in unspecified order
00740     #pragma warning (disable:   1684)            // Conversion from pointer to same-sized integral type (potential portability problem)
00741 
00742 #endif
00743 
00744 //-----------------------------------------------------------------------------------------------------------------
00745 
00746 #if (defined (_GCC_VER) && (_GCC_VER <  472)  || \
00747      defined (_MSC_VER) && (_MSC_VER < 1600)) // Minimum requirements are now GCC 4.7.2 or MSVC 10.0 (2010)
00748 
00749     #ifdef __GNUC__
00750     #error
00751     #error ---------------------------------------------------------------------------------------
00752     #endif
00753     #error TXLib.h: This version will NOT work with GCC < 4.7.2 or MS Visual Studio < 2010, sorry.
00754     #error
00755     #error Please use TXLib.h previous stable version/revision OR upgrade your compiler.
00756     #error ---------------------------------------------------------------------------------------
00757     #error
00758 
00759 #endif
00760 
00761 //-----------------------------------------------------------------------------------------------------------------
00762 
00763 #if defined (_GCC_VER) && (_GCC_VER >= 492)
00764 #if defined (TX_USE_SPEAK) && !__has_include (<SAPI.h>)
00765 
00766     #ifdef __GNUC__
00767     #error
00768     #error ---------------------------------------------------------------------------------------
00769     #endif
00770     #error You have defined TX_USE_SPEAK, but your compiler do NOT have the library <SAPI.h>.
00771     #error
00772     #error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API
00773     #error necessary for txSpeak() to work.
00774     #error ---------------------------------------------------------------------------------------
00775     #error
00776 
00777 #endif
00778 #endif
00779 
00780 //-----------------------------------------------------------------------------------------------------------------
00781 
00782 #if !defined (WINVER)
00783     #define   WINVER                   0x0502    // Defaults to Windows XP
00784     #define   WINDOWS_ENABLE_CPLUSPLUS           // Allow use of type-limit macros in <basetsd.h>,
00785 #endif                                           //   they are allowed by default if WINVER >= 0x0600.
00786 
00787 #if !defined (_WIN32_WINNT)
00788     #define   _WIN32_WINNT             WINVER    // Defaults to the same as WINVER
00789 #endif
00790 
00791 #if !defined (_WIN32_IE)
00792     #define   _WIN32_IE                WINVER    // Defaults to the same as WINVER
00793 #endif
00794 
00795 #define stristr(  str1, str2 )         Win32::StrStrIA ((str1), (str2))
00796 #define stristrw( str1, str2 )         Win32::StrStrIW ((str1), (str2))
00797 
00798 //-----------------------------------------------------------------------------------------------------------------
00799 
00800 #define _USE_MATH_DEFINES              1         // Math.h's M_PI etc.
00801 #define __STDC_FORMAT_MACROS           1         // PRIu64 and other PR... macros
00802 #define __STDC_WANT_LIB_EXT1__         1         // String and output *_s functions
00803 
00804 #define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS  // Wow, how long. Kudos, Clang
00805 
00806 #define _ALLOW_RTCc_IN_STL             1         // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc.
00807 
00808 #define NOMINMAX                       1         // Preventing 'min' and 'max' defines in Windows.h
00809 
00810 #if defined (_DEBUG)
00811 #define _SECURE_SCL                    1         // Enable checked STL iterators to throw an exception on incorrect use
00812 #define _HAS_ITERATOR_DEBUGGING        1
00813 #define _LIBCPP_DEBUG                  1
00814 #endif
00815 
00816 #if defined (_MSC_VER) && defined (_DEBUG)
00817 
00818     #define _CRTDBG_MAP_ALLOC                    // Enable MSVCRT debug heap
00819     #define _new_dbg                   new (_NORMAL_BLOCK, __FILE__, __LINE__)
00820     #define NEW                        new (_NORMAL_BLOCK, __FILE__, __LINE__)
00821 
00822 #else
00823     #define _new_dbg                   new
00824     #define NEW                        new
00825 
00826 #endif
00827 
00828 #if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015
00829 #define _SECURE_SCL_THROWS             1
00830 #endif
00831 
00832 #define     tx_noreturn                __attribute__ (( noreturn           ))
00833 #define     tx_nodiscard               __attribute__ (( warn_unused_result ))
00834 #define     tx_deprecated              __attribute__ (( deprecated         ))
00835 #define     tx_printfy( formatArgN )   __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) ))
00836 #define     tx_scanfy(  formatArgN )   __attribute__ (( format (scanf,  (formatArgN), (formatArgN)+1) ))
00837 
00838 
00839 #if defined (_TX_CPP11)
00840 
00841     #define _tx_delete                 = delete
00842     #define _tx_default                = default
00843     #define _tx_override               override
00844     #define _tx_final                  final
00845 
00846 #else
00847 
00848     #define _tx_delete
00849     #define _tx_default
00850     #define _tx_override
00851     #define _tx_final
00852 
00853 #endif
00854 
00855 namespace std { enum nomeow_t { nomeow }; }      // Vital addition to the C++ standard. TODO: Should contact C++ std committee.
00856 
00857 //-----------------------------------------------------------------------------------------------------------------
00858 
00860 //}
00861 //-----------------------------------------------------------------------------------------------------------------
00862 
00863 //-----------------------------------------------------------------------------------------------------------------
00864 //{          The Includes
00865 //-----------------------------------------------------------------------------------------------------------------
00866 
00867 #if defined (_MSC_VER)
00868     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
00869 
00870     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
00871     #pragma warning (disable: 4005)              // 'name': macro redefinition
00872 #endif
00873 
00874 //-----------------------------------------------------------------------------------------------------------------
00875 
00876 #include <stdlib.h>
00877 #include <stdio.h>
00878 #include <string.h>
00879 #include <time.h>
00880 #include <math.h>
00881 #include <float.h>
00882 
00883 #include <vector>
00884 #include <string>
00885 #include <iostream>
00886 #include <sstream>
00887 #include <iomanip>
00888 
00889 #if !defined (__CYGWIN__)
00890 #include <conio.h>
00891 #include <direct.h>
00892 #endif
00893 
00894 #if defined (TX_COMPILED)
00895 #define WIN32_LEAN_AND_MEAN
00896 #endif
00897 
00898 #include <windows.h>
00899 #include <mmsystem.h>
00900 
00901 //-----------------------------------------------------------------------------------------------------------------
00902 //{          Compiler- and platform-specific
00904 //-----------------------------------------------------------------------------------------------------------------
00905 
00906 #if defined (_MSC_VER)
00907     #pragma warning (pop)                        // MSVC: Restore max level
00908 #endif
00909 
00910 #if defined (__STRICT_ANSI__UNDEFINED)
00911     #define  __STRICT_ANSI__                     // Redefine back
00912 #endif
00913 
00914 #if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED)
00915 
00916     #define  strncpy_s( dest, sizeof_dest, src, count )  ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
00917     #define  wcsncpy_s( dest, sizeof_dest, src, count )  ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
00918     #define  strncat_s( dest, sizeof_dest, src, count )  ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) )
00919     #define  strerror_s( buf, sizeof_buf, code        )  ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) )
00920     #define  strtok_s(   buf, delim, ctx              )  ( (void)(ctx), strtok ((buf), (delim)) )
00921     #define  fopen_s(    file, name, mode             )  ( *(file) = fopen ((name), (mode)) )
00922     #define _strlwr_s(   str, sizeof_str              )  ( _strlwr (str) )
00923 
00924     #define  ctime_s( buf, sizeof_buf, time    )         ( strncpy ((buf), ctime (time), (sizeof_buf)-1) )
00925     #define _controlfp_s( oldCtl, newCtl, mask )         ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 )
00926 
00927     #define _snprintf_s                                  snprintf
00928     #define _vsnprintf_s( str, sz, trunc, format, arg )  _vsnprintf (str, sz, format, arg)
00929 
00930 #endif
00931 
00932 #if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) )
00933 
00934     #define  getenv_s( sz, buf, sizeof_buf, name )       ({ (void)(sz); const char* _env = getenv (name); \
00935                                                             strncpy ((buf), (_env)? _env : "", (sizeof_buf)-1); })
00936 #endif
00937 
00938 #if defined (__CYGWIN__)
00939 
00940     #undef   __STRICT_ANSI__
00941 
00942     typedef  void                                _exception;
00943 
00944     #define _O_TEXT                              O_TEXT
00945     #define _fdopen                              fdopen
00946     #define _flushall()                          fflush (NULL)
00947     #define _getcwd                              getcwd
00948     #define _getpid                              getpid
00949     #define _stricmp                             strcasecmp
00950     #define _strlwr                              strlwr
00951     #define _strnicmp                            strncasecmp
00952     #define _unlink                              unlink
00953     #define _vsnprintf                           vsnprintf
00954     #define _access                              access
00955     #define _strdup                              strdup
00956 
00957     #define getch                                _getch
00958     #define putch                                _putch
00959     #define kbhit                                _kbhit
00960 
00961 #endif
00962 
00963 #if !defined (PRId64) || \
00964      defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32
00965 
00966     #undef  PRId64
00967     #undef  PRIi64
00968     #undef  PRIo64
00969     #undef  PRIu64
00970     #undef  PRIx64
00971     #undef  PRIX64
00972 
00973     #define PRId64                               "I64d"
00974     #define PRIi64                               "I64i"
00975     #define PRIo64                               "I64o"
00976     #define PRIu64                               "I64u"
00977     #define PRIx64                               "I64x"
00978     #define PRIX64                               "I64X"
00979 
00980 #endif
00981 
00982 //}
00983 //-----------------------------------------------------------------------------------------------------------------
00984 
00985 //}
00986 //-----------------------------------------------------------------------------------------------------------------
00987 
00988 //-----------------------------------------------------------------------------------------------------------------
00989 //{          The namespaces
00990 //-----------------------------------------------------------------------------------------------------------------
00991 
00992 //{----------------------------------------------------------------------------------------------------------------
00995 //}----------------------------------------------------------------------------------------------------------------
00996 
00997 #ifdef FOR_DOXYGEN_ONLY
00998 namespace { namespace TX { }}
00999 #endif
01000 
01003 //-----------------------------------------------------------------------------------------------------------------
01004 
01005 #if defined (TX_COMPILED)  &&  defined (TX_COMPILING)
01006     #undef   TX_COMPILED
01007     #endif
01008 
01009 #if !defined (TX_COMPILED) && !defined (TX_COMPILING)
01010 
01011     #define _TX_BEGIN_NAMESPACE                      namespace { namespace TX {
01012     #define _TX_END_NAMESPACE                        } }
01013 
01014 #else
01015 
01016     #define _TX_BEGIN_NAMESPACE                                  namespace TX {
01017     #define _TX_END_NAMESPACE                        }
01018 
01019 #endif
01020 
01021 //-----------------------------------------------------------------------------------------------------------------
01022 
01023 _TX_BEGIN_NAMESPACE
01024 
01027 //}
01028 //-----------------------------------------------------------------------------------------------------------------
01029 
01030 //=================================================================================================================
01031 //{          TXLIB INTERFACE
01032 //           Интерфейс библиотеки
01033 //=================================================================================================================
01034 
01035 //=================================================================================================================
01036 //{          Initialization
01038 //=================================================================================================================
01040 //{----------------------------------------------------------------------------------------------------------------
01084 //}----------------------------------------------------------------------------------------------------------------
01085 
01086 HWND txCreateWindow (double sizeX, double sizeY, bool centered = true);
01087 
01088 //{----------------------------------------------------------------------------------------------------------------
01115 //}----------------------------------------------------------------------------------------------------------------
01116 
01117 inline HDC& txDC() tx_nodiscard;
01118 
01119 //{----------------------------------------------------------------------------------------------------------------
01155 //}----------------------------------------------------------------------------------------------------------------
01156 
01157 inline RGBQUAD* txVideoMemory() tx_nodiscard;
01158 
01159 //{----------------------------------------------------------------------------------------------------------------
01178 //}----------------------------------------------------------------------------------------------------------------
01179 
01180 bool txSetDefaults (HDC dc = txDC());
01181 
01182 //{----------------------------------------------------------------------------------------------------------------
01201 //}----------------------------------------------------------------------------------------------------------------
01202 
01203 inline bool txOK() tx_nodiscard;
01204 
01205 //{----------------------------------------------------------------------------------------------------------------
01237 //}----------------------------------------------------------------------------------------------------------------
01238 
01239 POINT txGetExtent (HDC dc = txDC()) tx_nodiscard;
01240 
01241 //{----------------------------------------------------------------------------------------------------------------
01258 //}----------------------------------------------------------------------------------------------------------------
01259 
01260 inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard;
01261 
01262 //{----------------------------------------------------------------------------------------------------------------
01280 //}----------------------------------------------------------------------------------------------------------------
01281 
01282 inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard;
01283 
01284 //{----------------------------------------------------------------------------------------------------------------
01296 //}----------------------------------------------------------------------------------------------------------------
01297 
01298 inline HWND txWindow() tx_nodiscard;
01299 
01300 //{----------------------------------------------------------------------------------------------------------------
01309 //}----------------------------------------------------------------------------------------------------------------
01310 
01311 inline const char* txVersion() tx_nodiscard;
01312 
01313 //{----------------------------------------------------------------------------------------------------------------
01322 //}----------------------------------------------------------------------------------------------------------------
01323 
01324 inline unsigned txVersionNumber() tx_nodiscard;
01325 
01326 //{----------------------------------------------------------------------------------------------------------------
01356 //}----------------------------------------------------------------------------------------------------------------
01357 
01358 const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard;
01359 
01361 //{----------------------------------------------------------------------------------------------------------------
01396 //}----------------------------------------------------------------------------------------------------------------
01397 
01398 int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает",
01399                   unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL);
01400 
01401 //{----------------------------------------------------------------------------------------------------------------
01418 //}----------------------------------------------------------------------------------------------------------------
01419 
01420 HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL);
01421 
01422 //}
01423 //=================================================================================================================
01424 
01425 //=================================================================================================================
01426 //{          Setting the parameters
01428 //=================================================================================================================
01430 //{----------------------------------------------------------------------------------------------------------------
01456 //}----------------------------------------------------------------------------------------------------------------
01457 
01458 const COLORREF
01459 #ifdef FOR_DOXYGEN_ONLY
01460     enum txColors {
01461 #endif
01462 
01463     TX_BLACK         = RGB (  0,   0,   0),   
01464     TX_BLUE          = RGB (  0,   0, 128),   
01465     TX_GREEN         = RGB (  0, 128,   0),   
01466     TX_CYAN          = RGB (  0, 128, 128),   
01467     TX_RED           = RGB (128,   0,   0),   
01468     TX_MAGENTA       = RGB (128,   0, 128),   
01469     TX_BROWN         = RGB (128, 128,   0),   
01470     TX_ORANGE        = RGB (255, 128,   0),   
01471     TX_GRAY          = RGB (160, 160, 160),   
01472     TX_DARKGRAY      = RGB (128, 128, 128),   
01473     TX_LIGHTGRAY     = RGB (192, 192, 192),   
01474     TX_LIGHTBLUE     = RGB (  0,   0, 255),   
01475     TX_LIGHTGREEN    = RGB (  0, 255, 128),   
01476     TX_LIGHTCYAN     = RGB (  0, 255, 255),   
01477     TX_LIGHTRED      = RGB (255,   0, 128),   
01478     TX_LIGHTMAGENTA  = RGB (255,   0, 255),   
01479     TX_PINK          = RGB (255, 128, 255),   
01480     TX_YELLOW        = RGB (255, 255, 128),   
01481     TX_WHITE         = RGB (255, 255, 255),   
01482     TX_TRANSPARENT   = 0xFFFFFFFF,            
01483     TX_NULL          = TX_TRANSPARENT,        
01484     TX_BLM           = TX_BLACK,              
01485     TX_white         = TX_WHITE,              
01486 
01487 //  Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB()
01488 
01489     TX_HUE          = 0x04000000,             
01490     TX_SATURATION   = 0x05000000,             
01491     TX_LIGHTNESS    = 0x06000000;             
01492 
01493 #ifdef FOR_DOXYGEN_ONLY
01494     };
01495 #endif
01496 
01498 #define TX_GREY       TX_GRAY
01499 #define TX_DARKGREY   TX_DARKGRAY
01500 #define TX_LIGHTGREY  TX_LIGHTGRAY
01501 
01502 
01503 //{----------------------------------------------------------------------------------------------------------------
01528 //}----------------------------------------------------------------------------------------------------------------
01529 
01530 #ifdef FOR_DOXYGEN_ONLY
01531 COLORREF RGB (int red, int green, int blue);
01532 #endif
01533 
01534 //{----------------------------------------------------------------------------------------------------------------
01553 //}----------------------------------------------------------------------------------------------------------------
01554 
01555 HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC());
01556 
01558 #define txSetColour txSetColor
01559 
01560 
01562 
01563 //{----------------------------------------------------------------------------------------------------------------
01574 //}----------------------------------------------------------------------------------------------------------------
01575 
01576 COLORREF txColor (double red, double green, double blue);
01577 
01579 
01580 //{----------------------------------------------------------------------------------------------------------------
01593 //}----------------------------------------------------------------------------------------------------------------
01594 
01595 COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard;
01596 
01597 //{----------------------------------------------------------------------------------------------------------------
01612 //}----------------------------------------------------------------------------------------------------------------
01613 
01614 HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC());
01615 
01617 #define txSetFillColour txSetFillColor
01618 
01619 
01621 
01622 //{----------------------------------------------------------------------------------------------------------------
01633 //}----------------------------------------------------------------------------------------------------------------
01634 
01635 COLORREF txFillColor (double red, double green, double blue);
01636 
01638 
01639 //{----------------------------------------------------------------------------------------------------------------
01652 //}----------------------------------------------------------------------------------------------------------------
01653 
01654 COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard;
01655 
01656 //{----------------------------------------------------------------------------------------------------------------
01674 //}----------------------------------------------------------------------------------------------------------------
01675 
01676 unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard;
01677 
01678 //{----------------------------------------------------------------------------------------------------------------
01706 //}----------------------------------------------------------------------------------------------------------------
01707 
01708 COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard;
01709 
01710 //{----------------------------------------------------------------------------------------------------------------
01740 //}----------------------------------------------------------------------------------------------------------------
01741 
01742 COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard;
01743 
01745 //}
01746 //=================================================================================================================
01747 
01748 //=================================================================================================================
01749 //{          Drawing
01751 //=================================================================================================================
01753 //{----------------------------------------------------------------------------------------------------------------
01767 //}----------------------------------------------------------------------------------------------------------------
01768 
01769 bool txClear (HDC dc = txDC());
01770 
01771 //{----------------------------------------------------------------------------------------------------------------
01789 //}----------------------------------------------------------------------------------------------------------------
01790 
01791 inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC());
01792 
01794 
01795 //{----------------------------------------------------------------------------------------------------------------
01813 //}----------------------------------------------------------------------------------------------------------------
01814 
01815 inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC());
01816 
01818 
01819 //{----------------------------------------------------------------------------------------------------------------
01837 //}----------------------------------------------------------------------------------------------------------------
01838 
01839 inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard;
01840 
01841 //{----------------------------------------------------------------------------------------------------------------
01861 //}----------------------------------------------------------------------------------------------------------------
01862 
01863 bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC());
01864 
01865 //{----------------------------------------------------------------------------------------------------------------
01887 //}----------------------------------------------------------------------------------------------------------------
01888 
01889 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC());
01890 
01891 //{----------------------------------------------------------------------------------------------------------------
01911 //}----------------------------------------------------------------------------------------------------------------
01912 
01913 bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC());
01914 
01915 //{----------------------------------------------------------------------------------------------------------------
01935 //}----------------------------------------------------------------------------------------------------------------
01936 
01937 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC());
01938 
01939 //{----------------------------------------------------------------------------------------------------------------
01957 //}----------------------------------------------------------------------------------------------------------------
01958 
01959 bool txCircle (double x, double y, double r);
01960 
01961 //{----------------------------------------------------------------------------------------------------------------
01984 //}----------------------------------------------------------------------------------------------------------------
01985 
01986 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
01987 
01988 //{----------------------------------------------------------------------------------------------------------------
02011 //}----------------------------------------------------------------------------------------------------------------
02012 
02013 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02014 
02015 //{----------------------------------------------------------------------------------------------------------------
02038 //}----------------------------------------------------------------------------------------------------------------
02039 
02040 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02041 
02042 //{----------------------------------------------------------------------------------------------------------------
02074 //}----------------------------------------------------------------------------------------------------------------
02075 
02076 bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC());
02077 
02078 //{----------------------------------------------------------------------------------------------------------------
02096 //}----------------------------------------------------------------------------------------------------------------
02097 
02098 inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)
02099     {
02100     (void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3;
02101 
02102     txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n"
02103                   "Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами "
02104                   "как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". "
02105                   "Ну или нарисовать тремя линиями. :)", "TXLib сообщает");
02106     return false;
02107     }
02108 
02109 //{----------------------------------------------------------------------------------------------------------------
02111 
02112 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
02113 
02114 #define txRectandle  Sleep (1000), txRectangle  // Copy-protection for the function below
02115 #define txLine(...)  txLine (__VA_ARGS__); {    //
02116 #define txNotifyIcon }}}}}}}}}} txNotifyIcon    // Не спрашивайте, зачем. Это дичь.
02117 #define txCircle     ;txCircle                  //
02118 #define txSetColor   ;txSetColor                //
02119 #define C0L0RREF     COLORREF                   //
02120 #define OxFFFFFF     0xFFFFFF                   //
02121 #define lO           10                         //
02122 #define lOOO         1000                       //
02123 #define oo                                      //
02124 #define O                                       //
02125 
02127 //}
02128 
02129 //{----------------------------------------------------------------------------------------------------------------
02170 //}----------------------------------------------------------------------------------------------------------------//////
02171                                                                                                                        //
02172 inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist,   //
02173                        double head, double eyes, double wink, double crazy, double smile, double hair, double wind)    //
02174     {                                                                                                                  //
02175     const char __[] =  "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/";           //
02176     //                   |                                |                          |                  |              //
02177     // Не копипастите! _/ \_ Все равно не получится! :) _/ \_  Человечки защищают  _/ \_ этот код! :) _/ \_  Муаххаха! //
02178     //                                                                                                                 //
02179     static int count = GetTickCount(), L = 0;  
02180 
02181     C0L0RREF lineColor = txGetColor();
02182     C0L0RREF fillColor = txGetFillColor();
02183 
02184     txSetColor     (color, 3);
02185     txSetFillColor (color);
02186 
02187     txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY);
02188 
02189     txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY);
02190     txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY);
02191 
02192     txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y);
02193     txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y);
02194 
02195     txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY);
02196 
02197     txLine (x, y - (1 + head) * sizeY, x +  wind/lO        * sizeX, y - (1 + head + hair/lO) * sizeY);
02198     txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
02199     txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
02200 
02201     txSetColor     (~color & OxFFFFFF);  // Inverse the color
02202     txSetFillColor (~color & OxFFFFFF);
02203 
02204     txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
02205     txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
02206                                               oo
02207     txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]);  //-V112 //-V542
02208                                    oo
02209     // See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow
02210 
02211     txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY);
02212     txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY);
02213     Sleep (lOOO + count%2);
02214 
02215     txSetColor     ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT);
02216     txSetFillColor (TX_TRANSPARENT);
02217 
02218     txCircle (x, y, 4);  //-V112
02219     txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y);
02220 
02221     txSetColor     (lineColor);
02222     txSetFillColor (fillColor);
02223     }
02224 
02226 //}
02227 //=================================================================================================================
02228 
02229 //=================================================================================================================
02230 //{          Drawing text
02232 //=================================================================================================================
02234 //{----------------------------------------------------------------------------------------------------------------
02253 //}----------------------------------------------------------------------------------------------------------------
02254 
02255 bool txTextOut (double x, double y, const char text[], HDC dc = txDC());
02256 
02257 //{----------------------------------------------------------------------------------------------------------------
02259 
02260 #undef txRectandle
02261 #undef txLine
02262 #undef txNotifyIcon
02263 #undef txCircle
02264 #undef txSetColor
02265 #undef C0L0RREF
02266 #undef OxFFFFFF
02267 #undef lO
02268 #undef lOOO
02269 #undef oo
02270 #undef O
02271 
02273 //}
02274 
02275 //{----------------------------------------------------------------------------------------------------------------
02322 //}----------------------------------------------------------------------------------------------------------------
02323 
02324 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
02325                  unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC());
02326 
02327 //{----------------------------------------------------------------------------------------------------------------
02352 //}----------------------------------------------------------------------------------------------------------------
02353 
02354 HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1,
02355                     int bold = FW_DONTCARE, bool italic = false, bool underline = false,
02356                     bool strikeout = false, double angle = 0,
02357                     HDC dc = txDC());
02358 
02359 //{----------------------------------------------------------------------------------------------------------------
02374 //}----------------------------------------------------------------------------------------------------------------
02375 
02376 SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard;
02377 
02378 //{----------------------------------------------------------------------------------------------------------------
02392 //}----------------------------------------------------------------------------------------------------------------
02393 
02394 int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard;
02395 
02396 //{----------------------------------------------------------------------------------------------------------------
02410 //}----------------------------------------------------------------------------------------------------------------
02411 
02412 int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard;
02413 
02414 //{----------------------------------------------------------------------------------------------------------------
02441 //}----------------------------------------------------------------------------------------------------------------
02442 
02443 unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC());
02444 
02445 //{----------------------------------------------------------------------------------------------------------------
02461 //}----------------------------------------------------------------------------------------------------------------
02462 
02463 LOGFONT* txFontExist (const char name[]) tx_nodiscard;
02464 
02466 //}
02467 //=================================================================================================================
02468 
02469 //=================================================================================================================
02470 //{          Drawing to memory DC and image loading
02472 //=================================================================================================================
02474 //{----------------------------------------------------------------------------------------------------------------
02514 //}----------------------------------------------------------------------------------------------------------------
02515 
02516 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard;
02517 
02518 //{----------------------------------------------------------------------------------------------------------------
02621 //}----------------------------------------------------------------------------------------------------------------
02622 
02623 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD**  pixels = NULL) tx_nodiscard;
02624 
02626 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)        tx_nodiscard;
02628 
02629 //{----------------------------------------------------------------------------------------------------------------
02705 //}----------------------------------------------------------------------------------------------------------------
02706 
02707 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0,
02708                  unsigned imageFlags = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard;
02709 
02710 //{----------------------------------------------------------------------------------------------------------------
02742 //}----------------------------------------------------------------------------------------------------------------
02743 
02744 bool txDeleteDC (HDC  dc);
02745 
02747 bool txDeleteDC (HDC* dc);
02749 
02750 //{----------------------------------------------------------------------------------------------------------------
02790 //}----------------------------------------------------------------------------------------------------------------
02791 
02792 bool txBitBlt (HDC destImage,   double xDest,       double yDest, double width, double height,
02793                HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY);
02794 
02795 //{----------------------------------------------------------------------------------------------------------------
02810 //}----------------------------------------------------------------------------------------------------------------
02811 
02812 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0);
02813 
02814 //{----------------------------------------------------------------------------------------------------------------
02874 //}----------------------------------------------------------------------------------------------------------------
02875 
02876 bool txTransparentBlt (HDC destImage,   double xDest,       double yDest,       double width, double height,
02877                        HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK);
02878 
02879 //{----------------------------------------------------------------------------------------------------------------
02895 //}----------------------------------------------------------------------------------------------------------------
02896 
02897 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
02898                               COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0);
02899 
02900 //{----------------------------------------------------------------------------------------------------------------
03005 //}----------------------------------------------------------------------------------------------------------------
03006 
03007 bool txAlphaBlend (HDC destImage,   double xDest,       double yDest,       double width, double height,
03008                    HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0);
03009 
03010 //{----------------------------------------------------------------------------------------------------------------
03027 //}----------------------------------------------------------------------------------------------------------------
03028 
03029 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
03030                           double xSource = 0, double ySource = 0, double alpha = 1.0);
03031 
03032 //{----------------------------------------------------------------------------------------------------------------
03061 //}----------------------------------------------------------------------------------------------------------------
03062 
03063 HDC txUseAlpha (HDC image);
03064 
03065 //{----------------------------------------------------------------------------------------------------------------
03091 //}----------------------------------------------------------------------------------------------------------------
03092 
03093 bool txSaveImage (const char filename[], HDC dc = txDC());
03094 
03096 //}
03097 //=================================================================================================================
03098 
03099 //=================================================================================================================
03100 //{          Utility functions
03102 //=================================================================================================================
03104 //{----------------------------------------------------------------------------------------------------------------
03123 //}----------------------------------------------------------------------------------------------------------------
03124 
03125 double txSleep (double time = 0);
03126 
03127 //{----------------------------------------------------------------------------------------------------------------
03212 //}----------------------------------------------------------------------------------------------------------------
03213 
03214 inline int txBegin();
03215 
03216 //{----------------------------------------------------------------------------------------------------------------
03239 //}----------------------------------------------------------------------------------------------------------------
03240 
03241 inline int txEnd();
03242 
03243 //{----------------------------------------------------------------------------------------------------------------
03265 //}----------------------------------------------------------------------------------------------------------------
03266 
03267 inline void txRedrawWindow();
03268 
03269 //{----------------------------------------------------------------------------------------------------------------
03293 //}----------------------------------------------------------------------------------------------------------------
03294 
03295 inline int txUpdateWindow (int update = true);
03296 
03297 //{----------------------------------------------------------------------------------------------------------------
03314 //}----------------------------------------------------------------------------------------------------------------
03315 
03316 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC());
03317 
03318 //{----------------------------------------------------------------------------------------------------------------
03338 //
03339 //                 +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее"
03340 //                 |
03341 //                 v
03342 //               txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03347 //}----------------------------------------------------------------------------------------------------------------
03348 
03349 //     +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее"
03350 //     |
03351 //     v
03352 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03353 
03354 //{----------------------------------------------------------------------------------------------------------------
03370 //}----------------------------------------------------------------------------------------------------------------
03371 
03372 bool txDestroyWindow (HWND wnd = txWindow());
03373 
03374 //{----------------------------------------------------------------------------------------------------------------
03385 //}----------------------------------------------------------------------------------------------------------------
03386 
03387 double txQueryPerformance() tx_nodiscard;
03388 
03389 //{----------------------------------------------------------------------------------------------------------------
03404 //}----------------------------------------------------------------------------------------------------------------
03406 
03407 #if defined (_TX_CPP11)
03408     template <int txFramesToAverage = 5>
03409 #else
03410     const     int txFramesToAverage = 5;
03411 #endif
03412 
03414 
03415 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard;
03416 
03418 //}
03419 
03420 //=================================================================================================================
03421 //{          Mouse functions
03423 //=================================================================================================================
03425 //{----------------------------------------------------------------------------------------------------------------
03449 //}----------------------------------------------------------------------------------------------------------------
03450 
03451 inline POINT txMousePos() tx_nodiscard;
03452 
03453 //{----------------------------------------------------------------------------------------------------------------
03473 //}----------------------------------------------------------------------------------------------------------------
03474 
03475 inline double txMouseX() tx_nodiscard;
03476 
03477 //{----------------------------------------------------------------------------------------------------------------
03497 //}----------------------------------------------------------------------------------------------------------------
03498 
03499 inline double txMouseY() tx_nodiscard;
03500 
03501 //{----------------------------------------------------------------------------------------------------------------
03533 //}----------------------------------------------------------------------------------------------------------------
03534 
03535 inline unsigned txMouseButtons() tx_nodiscard;
03536 
03537 //{----------------------------------------------------------------------------------------------------------------
03569 //}----------------------------------------------------------------------------------------------------------------
03570 
03571 #ifdef FOR_DOXYGEN_ONLY
03572 inline Mouse& txCatchMouse (bool shouldEat = true);
03573 #endif
03574 
03576 //}
03577 //=================================================================================================================
03578 
03579 //=================================================================================================================
03580 //{          Console functions
03582 //=================================================================================================================
03584 //{----------------------------------------------------------------------------------------------------------------
03626 //}----------------------------------------------------------------------------------------------------------------
03627 
03628 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/);
03629 
03630 //{----------------------------------------------------------------------------------------------------------------
03642 //}----------------------------------------------------------------------------------------------------------------
03643 
03644 unsigned txGetConsoleAttr() tx_nodiscard;
03645 
03646 //{----------------------------------------------------------------------------------------------------------------
03660 //}----------------------------------------------------------------------------------------------------------------
03661 
03662 bool txClearConsole();
03663 
03664 //{----------------------------------------------------------------------------------------------------------------
03684 //}----------------------------------------------------------------------------------------------------------------
03685 
03686 POINT txSetConsoleCursorPos (double x, double y);
03687 
03688 //{----------------------------------------------------------------------------------------------------------------
03701 //}----------------------------------------------------------------------------------------------------------------
03702 
03703 POINT txGetConsoleCursorPos();
03704 
03705 //{----------------------------------------------------------------------------------------------------------------
03718 //}----------------------------------------------------------------------------------------------------------------
03719 
03720 POINT txGetConsoleExtent();
03721 
03722 //{----------------------------------------------------------------------------------------------------------------
03736 //}----------------------------------------------------------------------------------------------------------------
03737 
03738 POINT txGetConsoleFontSize() tx_nodiscard;
03739 
03740 //{----------------------------------------------------------------------------------------------------------------
03756 //}----------------------------------------------------------------------------------------------------------------
03757 
03758 bool txTextCursor (bool blink = true);
03759 
03761 //}
03762 //=================================================================================================================
03763 
03764 //=================================================================================================================
03765 //{          Other staff not related to drawing
03767 //=================================================================================================================
03769 //{----------------------------------------------------------------------------------------------------------------
03798 //}----------------------------------------------------------------------------------------------------------------
03799 
03800 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC);
03801 
03802 //{----------------------------------------------------------------------------------------------------------------
03860 //}----------------------------------------------------------------------------------------------------------------
03861 
03862 int txSpeak (const char* text, ...) tx_printfy (1);
03863 
03864 //{----------------------------------------------------------------------------------------------------------------
03981 //}----------------------------------------------------------------------------------------------------------------
03982 
03983 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
03984                        double zoom = 0, double gain = 1, HWND wnd = txWindow());
03985 
03986 //{----------------------------------------------------------------------------------------------------------------
04000 //}----------------------------------------------------------------------------------------------------------------
04001 
04002 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow());
04003 
04004 //{----------------------------------------------------------------------------------------------------------------
04060 //}----------------------------------------------------------------------------------------------------------------
04061 
04062 bool txGetAsyncKeyState (int key);
04063 
04064 //{----------------------------------------------------------------------------------------------------------------
04101 //}----------------------------------------------------------------------------------------------------------------
04102 
04103 #ifdef FOR_DOXYGEN_ONLY
04104 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
04105 #endif
04106 
04107 //{----------------------------------------------------------------------------------------------------------------
04132 //}----------------------------------------------------------------------------------------------------------------
04133 
04134 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1);
04135 
04136 //{----------------------------------------------------------------------------------------------------------------
04212 //}----------------------------------------------------------------------------------------------------------------
04213 
04214 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04215 
04216 template <typename T, typename... ArgsT>
04217 int txPrintf (const char* format, ArgsT... args);
04218 
04219 #define TX_PRINTF(...)  ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) )
04220 
04221 #endif
04222 
04223 //-----------------------------------------------------------------------------------------------------------------
04224 
04225 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY)
04226 
04227 enum width_t     : int {};
04228 enum precision_t : int {};
04229 
04230 inline width_t     width     (int width) { return (width_t)     width; }
04231 inline precision_t precision (int prec)  { return (precision_t) prec;  }
04232 
04233 #endif
04234 
04235 //{----------------------------------------------------------------------------------------------------------------
04254 //}----------------------------------------------------------------------------------------------------------------
04255 
04256 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04257 
04258 template <typename T, typename... ArgsT>
04259 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args);
04260 
04261 #endif
04262 
04263 //{----------------------------------------------------------------------------------------------------------------
04283 //}----------------------------------------------------------------------------------------------------------------
04284 
04285 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04286 
04287 template <typename T, typename... ArgsT>
04288 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args);
04289 
04290 #endif
04291 
04292 //{----------------------------------------------------------------------------------------------------------------
04310 //}----------------------------------------------------------------------------------------------------------------
04311 
04312 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
04313 
04314 template <typename... ArgsT>
04315 std::string txFormat (const char* format, ArgsT... args);
04316 
04317 #endif
04318 
04319 //{----------------------------------------------------------------------------------------------------------------
04391 //}----------------------------------------------------------------------------------------------------------------
04393 
04394 #define sizearr( arr )  ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) )
04395 
04397 //  See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx
04398 
04399 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N];  // ;=P
04400 
04401 //  Another approach
04402 
04403 #if defined (_TX_CPP11_MSVC15)
04404 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; }
04405 #endif
04406 
04408 
04409 #define SIZEARR( arr )  ( sizeof (arr) / sizeof ((arr)[0]) )
04410 
04412 //{----------------------------------------------------------------------------------------------------------------
04431 //}----------------------------------------------------------------------------------------------------------------
04432 
04433 inline int random (int range) tx_deprecated;
04434 
04435 //{----------------------------------------------------------------------------------------------------------------
04460 //}----------------------------------------------------------------------------------------------------------------
04461 
04462 inline double random (double left, double right)                tx_nodiscard tx_deprecated;
04463 
04464 inline double random (std::nomeow_t, double left, double right) tx_nodiscard;
04465 
04466 //{----------------------------------------------------------------------------------------------------------------
04496 //}----------------------------------------------------------------------------------------------------------------
04497 
04498 template <typename Tx, typename Ta, typename Tb>
04499 inline bool In (Tx x, Ta a, Tb b)                tx_nodiscard tx_deprecated;
04500 
04501 template <typename Tx, typename Ta, typename Tb>
04502 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated;
04503 
04504 //{----------------------------------------------------------------------------------------------------------------
04550 //}----------------------------------------------------------------------------------------------------------------
04552 
04553 inline bool In (const POINT& pt, const RECT& rect)                      tx_nodiscard tx_deprecated;
04554 inline bool In (const COORD& pt, const SMALL_RECT& rect)                tx_nodiscard tx_deprecated;
04555 
04557 
04558 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)       tx_nodiscard tx_deprecated;
04559 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated;
04560 
04561 //{----------------------------------------------------------------------------------------------------------------
04580 //}----------------------------------------------------------------------------------------------------------------
04581 
04582 #define MAX( a, b )     ( ((a) > (b))? (a) : (b) )
04583 
04584 template <typename T>
04585 T max (const T& a, const T& b) { return (a > b)? a : b; }  
04586 
04587 //{----------------------------------------------------------------------------------------------------------------
04606 //}----------------------------------------------------------------------------------------------------------------
04607 
04608 #define MIN( a, b )     ( ((a) < (b))? (a) : (b) )
04609 
04610 template <typename T>
04611 T min (const T& a, const T& b) { return (a < b)? a : b; }  
04612 
04613 //{----------------------------------------------------------------------------------------------------------------
04627 //}----------------------------------------------------------------------------------------------------------------
04628 
04629 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L  // MSVC: C99 case
04630 
04631     #define ROUND( x )  ( (long) round (x) )
04632 
04633 #else
04634 
04635     #define ROUND( x )  ( (long) floor ((x) + 0.5) )
04636 
04637 #endif
04638 
04639 //{----------------------------------------------------------------------------------------------------------------
04658 //}----------------------------------------------------------------------------------------------------------------
04659 
04660 void tx_fpreset();
04661 
04662 //{----------------------------------------------------------------------------------------------------------------
04671 //}----------------------------------------------------------------------------------------------------------------
04672 
04673 const double txPI = asin (1.0) * 2;
04674 
04675 //{----------------------------------------------------------------------------------------------------------------
04702 //}----------------------------------------------------------------------------------------------------------------
04703 
04704 inline double txSqr (double x)
04705     {
04706     double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0));  // Бурная вычислительная деятельность
04707 
04708     char str[1024] = "";
04709     _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr);
04710     txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL ||
04711         (
04712         txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION),
04713         txMessageBox ("Уйду я от вас", "Злые вы...",  MB_ICONSTOP),
04714         exit (EXIT_FAILURE), 0  //-V2509 //-V2014
04715         );
04716 
04717     txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика!  \0"  // А как это работает, а?  //-V111
04718                                      "С ума сойти...      \0"  //
04719                                      "а КЭП подтверждает  \0"  //       и кто это будет
04720                                      "Главное - отчитаться\0"  //       поддерживать?..
04721                                      "Невероятно, но факт \0"
04722                                      "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21);
04723 
04724     return sqr;  // Все же вернем значение. Мы же не звери
04725     }
04726 
04727 //{----------------------------------------------------------------------------------------------------------------
04749 //}----------------------------------------------------------------------------------------------------------------
04750 
04751 #ifdef FOR_DOXYGEN_ONLY
04752 #define _TX_DESTROY_3D
04753 #endif
04754 
04755 #if defined (_TX_DESTROY_3D)
04756 
04757     #define z  0                   // Читайте "Флатландию" Эбботта!
04758 
04759 #endif
04760 
04761 //{----------------------------------------------------------------------------------------------------------------
04778 //}----------------------------------------------------------------------------------------------------------------
04780 
04781 #define meow   ;
04782 
04783 #if defined (_MSC_VER) && !defined (_CLANG_VER)
04784 #define мяу    meow
04785 #endif
04786 
04787 #define please
04788 
04790 
04791 //{----------------------------------------------------------------------------------------------------------------
04809 //}----------------------------------------------------------------------------------------------------------------
04810 
04811 #define ZERO( type )    zero <type> ()
04812 
04814 template <typename T> inline T zero() tx_nodiscard;
04816 
04817 //{----------------------------------------------------------------------------------------------------------------
04844 //}----------------------------------------------------------------------------------------------------------------
04846 
04847 #define  tx_auto_func(    func )  _tx_auto_fun1 ( __LINE__, func )
04848 #define _tx_auto_fun1( n, func )  _tx_auto_fun2 ( n,        func )
04849 #define _tx_auto_fun2( n, func )  auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; })
04850 
04851 #define tx_finally(...)           tx_auto_func (__VA_ARGS__)
04852 
04853 template <typename T>
04854 struct _tx_auto_func_
04855     {
04856     typedef _tx_auto_func_<T> this_t;
04857     T func_;
04858 
04859     explicit _tx_auto_func_ (T func) : func_ (func) {}
04860             ~_tx_auto_func_ ()       { func_ ();     }
04861 
04862     private:         _tx_auto_func_ ()              _tx_delete;
04863                      _tx_auto_func_ (const this_t&) _tx_delete;
04864              this_t& operator =     (const this_t&) _tx_delete;
04865     };
04866 
04867 template <typename T>
04868 _tx_auto_func_<T> _tx_auto_func  (T   func)
04869     {
04870     return        _tx_auto_func_ <T> (func);
04871     }
04872 
04874 
04875 //{----------------------------------------------------------------------------------------------------------------
04920 //}----------------------------------------------------------------------------------------------------------------
04921 
04922 #if !defined (NDEBUG)
04923     #undef  TX_ASSERT
04924     #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \
04925                                                            "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 )
04926 #else
04927     #undef  TX_ASSERT
04928     #define TX_ASSERT( cond ) ((void) 1)
04929 
04930 #endif
04931 
04932 #ifdef assert
04933     #undef assert
04934 #endif
04935 
04936 #define assert( cond )        TX_ASSERT (cond)
04937 
04938 //{----------------------------------------------------------------------------------------------------------------
04965 //}----------------------------------------------------------------------------------------------------------------
04966 
04967 #if !defined (NDEBUG)
04968     #define asserted          || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.")
04969 
04970 #else
04971     #define asserted          || _txNOP (0)
04972 
04973 #endif
04974 
04975 #define verified              asserted  //!< For compatibility with assert macro
04976 
04978 #define TX_NEEDED             asserted  //!< For compatibility with earlier releases
04979 
04980 
04981 //{----------------------------------------------------------------------------------------------------------------
05009 //}----------------------------------------------------------------------------------------------------------------
05010 
05011 #if !defined (NDEBUG)
05012     #undef  verify
05013     #define verify            assert
05014 
05015 #else
05016     #undef  verify
05017     #define verify( expr )    ( expr )
05018 
05019 #endif
05020 
05021 //{----------------------------------------------------------------------------------------------------------------
05040 //}----------------------------------------------------------------------------------------------------------------
05041 
05042 #if !defined (FOR_DOXYGEN_ONLY)
05043     #define TX_ERROR( ... )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__)
05044 #else
05045     #define TX_ERROR( msg )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg)
05046 #endif
05047 
05049     #define TX_THROW          TX_ERROR  //!< For compatibility with earlier TXLib releases
05050 
05051 
05052 //{----------------------------------------------------------------------------------------------------------------
05068 //}----------------------------------------------------------------------------------------------------------------
05069 
05070 #if !defined (NDEBUG)
05071     #define TX_DEBUG_ERROR(...)  TX_ERROR (__VA_ARGS__)
05072 
05073 #else
05074     #define TX_DEBUG_ERROR(...)  ((void) 0)
05075 
05076 #endif
05077 
05078 //{----------------------------------------------------------------------------------------------------------------
05098 //}----------------------------------------------------------------------------------------------------------------
05099 
05100 #ifdef FOR_DOXYGEN_ONLY
05101 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05102 #endif
05103 
05105 
05106 #ifdef _MSC_VER
05107 #define txDump( ... )           _txDump ((const void*)(uintptr_t) __VA_ARGS__)
05108 #else
05109 #define txDump( address, ... )  _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__)
05110 #endif
05111 
05112 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05113 
05115 
05116 //{----------------------------------------------------------------------------------------------------------------
05142 //}----------------------------------------------------------------------------------------------------------------
05143 
05144 #define txStackBackTrace()    _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true);
05145 
05146 //{----------------------------------------------------------------------------------------------------------------
05168 //}----------------------------------------------------------------------------------------------------------------
05170 
05171 std::string txDemangle (const char* mangledName);
05172 char*       txDemangle (const char* mangledName, std::nomeow_t);
05173 
05174 #define txTypename(value)     txDemangle (typeid (value) .name()) .c_str()
05175 
05177 //{----------------------------------------------------------------------------------------------------------------
05204 //}----------------------------------------------------------------------------------------------------------------
05205 
05206 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue);
05207 
05208 //{----------------------------------------------------------------------------------------------------------------
05221 //}----------------------------------------------------------------------------------------------------------------
05223 
05224 #define _                     ,
05225 #define TX_COMMA              ,  //!< Синоним макроса _ (@ref _ "символ подчеркивания")
05226 
05228 
05229 //{----------------------------------------------------------------------------------------------------------------
05289 //}----------------------------------------------------------------------------------------------------------------
05290 
05291 #ifdef FOR_DOXYGEN_ONLY
05292 
05293     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType )
05294 
05295 #else
05296 
05297     // Hand-made DLLIMPORT helper
05298 
05299     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... )               \
05300             retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \
05301                                                             _txDllImport ((libName), #funcName, (required))
05302 #endif
05303 
05305 //}
05306 //=================================================================================================================
05307 
05308 //=================================================================================================================
05309 //{          Back-hole (I hope, not an ass-hole:) of the library)
05311 //=================================================================================================================
05313 //{----------------------------------------------------------------------------------------------------------------
05465 //}----------------------------------------------------------------------------------------------------------------
05466 
05467 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL);
05468 
05469 //{----------------------------------------------------------------------------------------------------------------
05494 //}----------------------------------------------------------------------------------------------------------------
05495 
05496 bool txLock (bool wait = true);
05497 
05498 //{----------------------------------------------------------------------------------------------------------------
05509 //}----------------------------------------------------------------------------------------------------------------
05511 
05512 bool txUnlock();
05513 
05515 template <typename T> inline T txUnlock (T value);
05517 
05519 
05520 //{----------------------------------------------------------------------------------------------------------------
05543 //}----------------------------------------------------------------------------------------------------------------
05544 
05545 #define txGDI( command, dc )  ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) )
05546 
05547 //{----------------------------------------------------------------------------------------------------------------
05570 //}----------------------------------------------------------------------------------------------------------------
05571 
05572 #ifndef   FOR_DOXYGEN_ONLY
05573 
05574 const int     _TX_CODEPAGE  =   1251;
05575 
05576 #ifndef __CYGWIN__
05577 const char    _TX_LOCALE[]  =  "Russian";
05578 #else
05579 const char    _TX_LOCALE[]  =  "ru_RU.CP1251";
05580 #endif
05581 
05582 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP";
05583 
05584 #endif
05585 
05586 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE);
05587 
05588 //{----------------------------------------------------------------------------------------------------------------
05603 //}----------------------------------------------------------------------------------------------------------------
05604 
05605 int txPause (const char* message, ...) tx_printfy (1);
05606 
05608 //}
05609 //=================================================================================================================
05610 
05611 //=================================================================================================================
05612 //{          Tune-up constants and variables
05614 //=================================================================================================================
05616 //{----------------------------------------------------------------------------------------------------------------
05626 //}----------------------------------------------------------------------------------------------------------------
05627 
05628 #ifndef TX_COMPILED
05629 
05630        char _txLogName[MAX_PATH]          = "";
05631 
05632 #endif // TX_COMPILED
05633 
05634 extern char _txLogName[];
05635 
05636 //{----------------------------------------------------------------------------------------------------------------
05668 //}----------------------------------------------------------------------------------------------------------------
05669 
05670 #if  defined  (_TX_NOINIT)
05671 
05672     #undef     _TX_NOINIT
05673     #define    _TX_NOINIT                 1
05674 
05675 #else
05676 
05677     #define    _TX_NOINIT                 0
05678 
05679 #endif
05680 
05681 //{----------------------------------------------------------------------------------------------------------------
05725 //}----------------------------------------------------------------------------------------------------------------
05726 
05727 #if !defined (TX_CONSOLE_MODE)
05728 
05729     #define   TX_CONSOLE_MODE             SW_HIDE
05730 
05731 #endif
05732 
05733 //{----------------------------------------------------------------------------------------------------------------
05737 //}----------------------------------------------------------------------------------------------------------------
05738 
05739 #if !defined (TX_CONSOLE_FONT)
05740 
05741     #define   TX_CONSOLE_FONT             "Lucida Console"
05742 
05743 #endif
05744 
05745 //{----------------------------------------------------------------------------------------------------------------
05756 //}----------------------------------------------------------------------------------------------------------------
05757 
05758 #ifndef TX_COMPILED
05759 
05760        int _txWindowStyle                 = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
05761 
05762 #endif // TX_COMPILED
05763 
05764 extern int _txWindowStyle;
05765 
05766 //{----------------------------------------------------------------------------------------------------------------
05769 //}----------------------------------------------------------------------------------------------------------------
05770 
05771 #ifndef TX_COMPILED
05772 
05773        unsigned _txCursorBlinkInterval    = 500;
05774 
05775 #endif // TX_COMPILED
05776 
05777 extern unsigned _txCursorBlinkInterval;
05778 
05779 //{----------------------------------------------------------------------------------------------------------------
05783 //}----------------------------------------------------------------------------------------------------------------
05784 
05785 #ifndef TX_COMPILED
05786 
05787        unsigned _txWindowUpdateInterval   = 25;
05788 
05789 #endif // TX_COMPILED
05790 
05791 extern unsigned _txWindowUpdateInterval;
05792 
05793 //{----------------------------------------------------------------------------------------------------------------
05802 //}----------------------------------------------------------------------------------------------------------------
05803 
05804 #ifdef FOR_DOXYGEN_ONLY
05805 #define       TX_USE_SFML
05806 #endif
05807 
05808 //{----------------------------------------------------------------------------------------------------------------
05811 //}----------------------------------------------------------------------------------------------------------------
05812 
05813 const int _TX_TIMEOUT                     = 1000
05814 
05815 #if  defined  (_TX_ALLOW_TRACE)
05816     * 2
05817 #endif
05818 
05819 #if  defined  (TX_TRACE)
05820     * 3
05821 #endif
05822 
05823 #if  defined  (_TX_USE_DEVPARTNER)
05824     * 10
05825 #endif
05826     ;
05827 
05828 //{----------------------------------------------------------------------------------------------------------------
05869 //}----------------------------------------------------------------------------------------------------------------
05870 
05871 #ifndef TX_COMPILED
05872 
05873        bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
05874                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp) = NULL;
05875 
05876 #endif // TX_COMPILED
05877 
05878 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
05879                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp);
05880 
05881 //{----------------------------------------------------------------------------------------------------------------
05884 //}----------------------------------------------------------------------------------------------------------------
05885 
05886 const unsigned _TX_BUFSIZE                =  1024,
05887                _TX_BIGBUFSIZE             = _TX_BUFSIZE *  2,  
05888                _TX_HUGEBUFSIZE            = _TX_BUFSIZE * 20,  
05889 
05890                _TX_STACKSIZE              = 64 * 1024;         
05891 
05892 //{----------------------------------------------------------------------------------------------------------------
05895 //}----------------------------------------------------------------------------------------------------------------
05896 
05897 #if !defined (_TX_EXCEPTIONS_LIMIT)
05898     #define   _TX_EXCEPTIONS_LIMIT        16
05899 #endif
05900 
05901 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT)
05902     #define   _TX_FATAL_EXCEPTIONS_LIMIT  16                   //!< Максимальное количество фатальных исключений.
05903 #endif
05904 
05905 //{----------------------------------------------------------------------------------------------------------------
05908 //}----------------------------------------------------------------------------------------------------------------
05909 
05910 #ifdef FOR_DOXYGEN_ONLY
05911 #define       _TX_FULL_STACKTRACE
05912 #endif
05913 
05914 //{----------------------------------------------------------------------------------------------------------------
05917 //}----------------------------------------------------------------------------------------------------------------
05918 
05919 #ifndef TX_COMPILED
05920 
05921        bool _txProcessSystemWarnings      = true;
05922 
05923 #endif // TX_COMPILED
05924 
05925 extern bool _txProcessSystemWarnings;
05926 
05927 //{----------------------------------------------------------------------------------------------------------------
05941 //}----------------------------------------------------------------------------------------------------------------
05942 
05943 #if !defined  (_TX_WAITABLE_PARENTS)
05944     #define    _TX_WAITABLE_PARENTS       "Winpty-agent.exe:Clion.exe, "            /* 0: CLion32       */ \
05945                                           "Winpty-agent.exe:Clion64.exe, "          /* 1: CLion64       */ \
05946                                           "starter.exe:eclipse.exe, "               /* 2: Eclipse 4     */ \
05947                                           "starter.exe:javaw.exe, "                 /* 3: Eclipse 3     */ \
05948                                           "cmd.exe:devenv.exe, "                    /* 4: MSVS 2003+    */ \
05949                                           "VSDebugConsole.exe:devenv.exe, "         /* 5: MSVS 2019+    */ \
05950                                           "VSDebugConsole.exe:msvsmon.exe, "        /* 6: MSVS 2022 x86 */ \
05951                                           "consolepauser.exe:devcpp.exe, "          /* 7: Dev-Cpp       */ \
05952                                           "cb_console_runner.exe:codeblocks.exe"    /* 8: CodeBlocks 8+ */
05953 #endif
05954 
05955 //{----------------------------------------------------------------------------------------------------------------
05974 //}----------------------------------------------------------------------------------------------------------------
05975 
05976 #if !defined (_TX_ALLOW_KILL_PARENT)            // DISCLAIMER: Я не призываю к убийству родителей.
05977     #define   _TX_ALLOW_KILL_PARENT       true  //             Это технический термин.
05978 #endif                                          //             г_дам юристам привет.
05979 
05980 //{----------------------------------------------------------------------------------------------------------------
05990 //}----------------------------------------------------------------------------------------------------------------
05991 
05992 #ifndef TX_COMPILED
05993 
05994        int    _txWatchdogTimeout          = 10*_TX_TIMEOUT;
05995 
05996 #endif // TX_COMPILED
05997 
05998 extern int    _txWatchdogTimeout;
05999 
06000 //{----------------------------------------------------------------------------------------------------------------
06069 //}----------------------------------------------------------------------------------------------------------------
06071 
06072 #ifdef FOR_DOXYGEN_ONLY
06073 
06074     #define TX_COMPILED
06075 
06076     #endif
06077 
06079 
06081 //}
06082 //=================================================================================================================
06083 
06084 //=================================================================================================================
06085 //{          Internal diagnostics
06087 //=================================================================================================================
06089 //{----------------------------------------------------------------------------------------------------------------
06129 //}----------------------------------------------------------------------------------------------------------------
06130 
06131 #ifdef FOR_DOXYGEN_ONLY
06132 #define _TX_ALLOW_TRACE
06133 #endif
06134 
06135 //{----------------------------------------------------------------------------------------------------------------
06165 //}----------------------------------------------------------------------------------------------------------------
06166 
06167 #ifdef FOR_DOXYGEN_ONLY
06168 #define       TX_TRACE
06169 #endif
06170 
06171 #if !defined (TX_TRACE)
06172     #define   TX_TRACE  { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); }
06173 #endif
06174 
06176 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...);
06178 
06179 //{----------------------------------------------------------------------------------------------------------------
06182 
06183 #ifndef   FOR_DOXYGEN_ONLY
06184 
06185 struct _txLoc
06186     {
06187     const char*   func;
06188     const char*   file;
06189     int           line;
06190 
06191     int           inTX;   // We are inside one of TXLib functions
06192     int           trace;  // Internal TX trace level, when enabled by _TX_ALLOW_TRACE
06193 
06194     const _txLoc* prev;   // Caller's location
06195 
06196     static _txLoc _tx_thread Cur;
06197     };
06198 
06199 struct _txFuncEntry
06200     {
06201     typedef _txFuncEntry this_t;
06202 
06203     _txLoc loc;
06204 
06205     _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; }
06206     void restore()                     { _txLoc::Cur = loc;                           }
06207    ~_txFuncEntry()                     { restore();                                   }
06208 
06209     private:
06210             _txFuncEntry (const this_t&) _tx_delete;
06211     this_t& operator =   (const this_t&) _tx_delete;
06212     };
06213 
06214 #if defined (_GCC_VER)
06215 
06216     inline const char* __txLocCurSet (const char* _file, int _line, const char* _func)
06217         { _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; }
06218 
06219 #else
06220 
06221     #define __txLocCurSet( _file, _line, _func ) \
06222         ( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) )
06223 
06224 #endif
06225 
06226 #define _txLocCurSet()     __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__)
06227 
06228 #define _txLocLvlSet(lvl)  { _txLoc::Cur.trace = (lvl); }
06229 
06230 //{----------------------------------------------------------------------------------------------------------------
06231 
06232 #if defined ($0)
06233     #undef   $0
06234     #endif
06235 
06236 #if defined ($1)
06237     #undef   $1
06238     #endif
06239 
06240 #if defined ($2)
06241     #undef   $2
06242     #endif
06243 
06244 #if defined ($3)
06245     #undef   $3
06246     #endif
06247 
06248 #if defined ($4)
06249     #undef   $4
06250     #endif
06251 
06252 #if defined ($5)
06253     #undef   $5
06254     #endif
06255 
06256 #if defined ($6)
06257     #undef   $6
06258     #endif
06259 
06260 #if defined ($7)
06261     #undef   $7
06262     #endif
06263 
06264 #if defined ($8)
06265     #undef   $8
06266     #endif
06267 
06268 #if defined ($9)
06269     #undef   $9
06270     #endif
06271 
06272 #if defined ($)
06273     #undef   $
06274     #endif
06275 
06276 #if defined ($$)
06277     #undef   $$
06278     #endif
06279 
06280 //}
06281 //-----------------------------------------------------------------------------------------------------------------
06282 
06283 #if defined (_TX_ALLOW_TRACE)
06284 
06285     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl);    $;          }
06286 
06287     #define  $           { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } }
06288 
06289     #define  $$          { __txFuncEntry.restore();                                                  }
06290 
06291 #elif defined (_DEBUG)
06292 
06293     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; {                                 $;          }
06294 
06295     #define  $           { _txLocCurSet();                                                           }
06296 
06297     #define  $$          { __txFuncEntry.restore();                                                  }
06298 
06299 #else
06300 
06301     #define _txEntry(lvl)  ;
06302     #define  $             ;
06303     #define  $$            ;
06304 
06305 #endif
06306 
06307 //{----------------------------------------------------------------------------------------------------------------
06308 
06309 #define      $0            _txEntry (0)  // (Log level unchanged)
06310 #define      $1            _txEntry (1)  // Regular functions
06311 #define      $2            _txEntry (2)  // Resvd
06312 #define      $3            _txEntry (3)  // Init/Cleanup
06313 #define      $4            _txEntry (4)  // Init/Cleanup, misc functions
06314 #define      $5            _txEntry (5)  // Error handling, entry points
06315 #define      $6            _txEntry (6)  // Error handling, main part
06316 #define      $7            _txEntry (7)  // Error handling, misc functions
06317 #define      $8            _txEntry (8)  // Canvas worker thread
06318 #define      $9            _txEntry (9)  // Resvd
06319 
06320 //}
06321 //-----------------------------------------------------------------------------------------------------------------
06322 
06323 #endif // FOR_DOXYGEN_ONLY
06324 
06327 //}----------------------------------------------------------------------------------------------------------------
06328 
06330 //}
06331 //=================================================================================================================
06332 
06333 //=================================================================================================================
06334 //{          Sweet critical section blocking: txAutoLock class
06335 //=================================================================================================================
06336 
06337 //{----------------------------------------------------------------------------------------------------------------
06353 //}----------------------------------------------------------------------------------------------------------------
06354 
06356 extern CRITICAL_SECTION _txCanvas_LockBackBuf;
06358 
06359 class txAutoLock
06360     {
06361     typedef txAutoLock this_t;
06362 
06363     public:
06364 
06365 //{----------------------------------------------------------------------------------------------------------------
06388 //}----------------------------------------------------------------------------------------------------------------
06389 
06390     explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) :
06391         cs_ (cs)
06392         {
06393 $1      if (!cs_) return;
06394 
06395         if (mandatory) {$    EnterCriticalSection (cs_);                   }
06396         else           {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); }
06397         }
06398 
06399 //{----------------------------------------------------------------------------------------------------------------
06412 //}----------------------------------------------------------------------------------------------------------------
06413 
06414     explicit txAutoLock (bool mandatory = true) :
06415         cs_ (NULL)
06416         {
06417 $1      new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory);
06418         }
06419 
06420 //{----------------------------------------------------------------------------------------------------------------
06422 //}----------------------------------------------------------------------------------------------------------------
06423 
06424    ~txAutoLock()
06425         {
06426 $1      if (!cs_) return;
06427 $       LeaveCriticalSection (cs_); cs_ = NULL;
06428         }
06429 
06430 //{----------------------------------------------------------------------------------------------------------------
06433 //}----------------------------------------------------------------------------------------------------------------
06434 
06435     operator bool () const
06436         {
06437 $1      return (cs_ != NULL);
06438         }
06439 
06440 //{----------------------------------------------------------------------------------------------------------------
06442 //}----------------------------------------------------------------------------------------------------------------
06443 
06444 //  private:
06445     CRITICAL_SECTION* cs_;
06446 
06447 //{----------------------------------------------------------------------------------------------------------------
06449 //}----------------------------------------------------------------------------------------------------------------
06451 
06452     private:
06453             txAutoLock (const this_t&) _tx_delete;
06454     this_t& operator = (const this_t&) _tx_delete;
06455 
06457 
06458     };
06459 
06460 //}
06461 //=================================================================================================================
06462 
06463 //=================================================================================================================
06464 //{          Dialogs: txDialog class
06466 //=================================================================================================================
06468 //{----------------------------------------------------------------------------------------------------------------
06489 //}----------------------------------------------------------------------------------------------------------------
06490 
06491 struct txDialog
06492     {
06493     typedef txDialog this_t;
06494 
06495 //{----------------------------------------------------------------------------------------------------------------
06508 //}----------------------------------------------------------------------------------------------------------------
06509 
06510     public:
06511     enum CONTROL
06512         {
06513         DIALOG    = (int) 0x00000000,            
06514         BUTTON    = (int) 0xFFFF0080,            
06515         EDIT      = (int) 0xFFFF0081,            
06516         STATIC    = (int) 0xFFFF0082,            
06517         LISTBOX   = (int) 0xFFFF0083,            
06518         SCROLLBAR = (int) 0xFFFF0084,            
06519         COMBOBOX  = (int) 0xFFFF0085,            
06520         END       = (int) 0x00000000             
06521         };
06522 
06523 //{----------------------------------------------------------------------------------------------------------------
06540 //}----------------------------------------------------------------------------------------------------------------
06541 
06542     public:
06543     struct Layout
06544         {                                        //-V802
06545         CONTROL     wndclass;                    
06546         const char* caption;                     
06547         WORD        id;                          
06548         short        x;                          
06549         short        y;                          
06550         short       sx;                          
06551         short       sy;                          
06552         DWORD       style;                       
06553 
06554         const char* font;                        
06555         WORD        fontsize;                    
06556         };
06557 
06558 //{----------------------------------------------------------------------------------------------------------------
06566 //}----------------------------------------------------------------------------------------------------------------
06567 
06568     public:
06569     txDialog();
06570 
06571 //{----------------------------------------------------------------------------------------------------------------
06581 //}----------------------------------------------------------------------------------------------------------------
06582 
06583     explicit txDialog (const Layout* layout);
06584 
06585 //{----------------------------------------------------------------------------------------------------------------
06587 //}----------------------------------------------------------------------------------------------------------------
06588 
06589     virtual ~txDialog() {};
06590 
06591 //{----------------------------------------------------------------------------------------------------------------
06603 //}----------------------------------------------------------------------------------------------------------------
06604 
06605     const Layout* setLayout (const Layout *layout);
06606 
06607 //{----------------------------------------------------------------------------------------------------------------
06625 //}----------------------------------------------------------------------------------------------------------------
06626 
06627     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam);
06628 
06629 //{----------------------------------------------------------------------------------------------------------------
06645 //}----------------------------------------------------------------------------------------------------------------
06646 
06647     intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0);
06648 
06649 //{----------------------------------------------------------------------------------------------------------------
06662 //}----------------------------------------------------------------------------------------------------------------
06663 
06664     intptr_t dialogBox (WORD resource);
06665 
06666 //{----------------------------------------------------------------------------------------------------------------
06668 //}----------------------------------------------------------------------------------------------------------------
06669 
06670     private:
06671             txDialog   (const this_t&) _tx_delete;
06672     this_t& operator = (const this_t&) _tx_delete;
06673 
06674 //{----------------------------------------------------------------------------------------------------------------
06676 //}----------------------------------------------------------------------------------------------------------------
06677 
06678     protected:
06679     static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
06680 
06681 //{----------------------------------------------------------------------------------------------------------------
06683 //}----------------------------------------------------------------------------------------------------------------
06684 
06685     private:
06686     const Layout* layout_;
06687     };
06688 
06690 //}
06691 //=================================================================================================================
06692 
06693 //=================================================================================================================
06694 //{          Dialogs: Message Map macros
06696 //=================================================================================================================
06698 //{----------------------------------------------------------------------------------------------------------------
06719 //}----------------------------------------------------------------------------------------------------------------
06720 
06721 #define TX_BEGIN_MESSAGE_MAP()                                                                 \
06722     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \
06723         {                                                                                      \
06724         int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result;     \
06725                                                                                                \
06726         switch (_msg)                                                                          \
06727             {                                                                                  \
06728             case WM_NULL:
06729 
06730 //{----------------------------------------------------------------------------------------------------------------
06749 //}----------------------------------------------------------------------------------------------------------------
06750 
06751 #define TX_HANDLE( id )                                                                        \
06752             break;                                                                             \
06753             case (id):
06754 
06755 //{----------------------------------------------------------------------------------------------------------------
06775 //}----------------------------------------------------------------------------------------------------------------
06776 
06777 #define TX_COMMAND_MAP                                                                         \
06778             default: break;                                                                    \
06779             }                                                                                  \
06780                                                                                                \
06781         if (_msg == WM_COMMAND) switch (LOWORD (_wParam))                                      \
06782             {                                                                                  \
06783             case 0:
06784 
06785 //{----------------------------------------------------------------------------------------------------------------
06804 //}----------------------------------------------------------------------------------------------------------------
06805 
06806 #define TX_END_MESSAGE_MAP                                                                     \
06807             default: break;                                                                    \
06808             }                                                                                  \
06809                                                                                                \
06810         return FALSE;                                                                          \
06811         }
06812 
06814 //}
06815 //=================================================================================================================
06816 
06817 //=================================================================================================================
06818 //{          Dialogs: txDialog example: txInputBox()
06820 //=================================================================================================================
06822 //{----------------------------------------------------------------------------------------------------------------
06842 //}----------------------------------------------------------------------------------------------------------------
06843 
06844 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard;
06845 
06846 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06847 
06848 const char* txInputBox (const char* text, const char* caption, const char* input)
06849     {
06850     //-------------------------------------------------------------------------------------------------------------
06851     // Если не указаны параметры, приходится использовать хоть какие-то надписи.
06852     // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название.
06853     //-------------------------------------------------------------------------------------------------------------
06854 
06855     if (!text)    text    = "Введите строку:";
06856     if (!caption) caption = txGetModuleFileName (false);
06857     if (!input)   input   = "";
06858 
06859     //-------------------------------------------------------------------------------------------------------------
06860     // Идентификаторы элементов диалога. Они требуются в GetDlgItemText().
06861     // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически.
06862     // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы
06863     // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения,
06864     // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о
06865     //-------------------------------------------------------------------------------------------------------------
06866 
06867     #define ID_TEXT_  101
06868     #define ID_INPUT_ 102
06869 
06870     //-------------------------------------------------------------------------------------------------------------
06871     // Задание макета (вида) диалога в виде массива структур.
06872     // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив
06873     // становится похож на описание ресурса диалога в .rc-файле.
06874     // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com).
06875     //-------------------------------------------------------------------------------------------------------------
06876 
06877     txDialog::Layout layout[] =
06878 
06879     //----------------------+----------+-----------+-----------------+---------------------------------------------
06880     //     Тип элемента     | Имя      | Иденти-   |   Координаты    | Флаги элементов
06881     //     диалога          | элемента | фикатор   |-----------------| (см. описание элементов
06882     //                      |          | элемента  | X | Y |Шир.|Выс.| окон диалога в MSDN)
06883     //----------------------+----------+-----------+---+---+----+----+---------------------------------------------
06884     //                      |          |           |   |   |    |    |
06885         {{ txDialog::DIALOG,  caption,   0,           0,  0, 240,  85                                                    },
06886          { txDialog::STATIC,  text,      ID_TEXT_,   10, 10, 150,  40, SS_LEFT                                           },
06887          { txDialog::EDIT,    input,     ID_INPUT_,  10, 60, 220,  15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP },
06888          { txDialog::BUTTON,  "&OK",     IDOK,      180, 10,  50,  15, BS_DEFPUSHBUTTON                     | WS_TABSTOP },
06889          { txDialog::BUTTON,  "&Cancel", IDCANCEL,  180, 30,  50,  15, BS_PUSHBUTTON                        | WS_TABSTOP },
06890          { txDialog::END                                                                                                 }};
06891 
06892     //-------------------------------------------------------------------------------------------------------------
06893     // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним.
06894     // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она
06895     // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную
06896     // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее
06897     // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG).
06898     //-------------------------------------------------------------------------------------------------------------
06899     struct inputDlg : txDialog
06900         {
06901         char str [1024];
06902 
06903         //---------------------------------------------------------------------------------------------------------
06904 
06905         inputDlg() :
06906             str()
06907             {}
06908 
06909         //---------------------------------------------------------------------------------------------------------
06910 
06911         TX_BEGIN_MESSAGE_MAP()    // Карта сообщений (на самом деле это начало оконной функции).  //-V2525
06912 
06913             TX_COMMAND_MAP        // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch).
06914 
06915                 //-------------------------------------------------------------------------------------------------
06916                 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия
06917                 // диалога строка ввода умрет и текст уже из нее получить.
06918                 // Этот макрос на самом деле превращается в case из оператора switch.
06919                 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP().
06920                 //-------------------------------------------------------------------------------------------------
06921 
06922                 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1);
06923 
06924         TX_END_MESSAGE_MAP        //-V2522
06925 
06926         //---------------------------------------------------------------------------------------------------------
06927         // Конец внутреннего класса диалога
06928         //---------------------------------------------------------------------------------------------------------
06929         };
06930 
06931     //-------------------------------------------------------------------------------------------------------------
06932     // Убираем дефайны, чтобы потом не мешали.
06933     // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом
06934     // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _.
06935     // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны.
06936     //-------------------------------------------------------------------------------------------------------------
06937 
06938     #undef ID_TEXT_
06939     #undef ID_INPUT_
06940 
06941     //-------------------------------------------------------------------------------------------------------------
06942     // Это статический объект, потому что строка в нем должна жить после завершения функции.
06943     //-------------------------------------------------------------------------------------------------------------
06944 
06945     static inputDlg dlg;
06946 
06947     //-------------------------------------------------------------------------------------------------------------
06948     // Передаем layout и запускаем окно диалога
06949     //-------------------------------------------------------------------------------------------------------------
06950 
06951     dlg.dialogBox (layout);
06952 
06953     //-------------------------------------------------------------------------------------------------------------
06954     // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет
06955     // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать
06956     // синтаксически можно, но ведет к серьезным ошибкам.
06957     //-------------------------------------------------------------------------------------------------------------
06958 
06959     return dlg.str;
06960     }
06961 
06962 #endif // TX_COMPILED
06963 
06965 //}
06966 //=================================================================================================================
06967 
06968 //}
06969 //=================================================================================================================
06970 
06971 //=================================================================================================================
06972 //{          TXLIB IMPLEMENTATION
06973 //           Реализация функций библиотеки
06974 //=================================================================================================================
06976 
06977 //-----------------------------------------------------------------------------------------------------------------
06978 //{          The Includes
06979 //-----------------------------------------------------------------------------------------------------------------
06980 
06981 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06982 
06983 _TX_END_NAMESPACE
06984 
06985 //-----------------------------------------------------------------------------------------------------------------
06986 
06987 #if defined (_MSC_VER)
06988     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
06989 
06990     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
06991     #pragma warning (disable: 4005)              // 'name': macro redefinition
06992 #endif
06993 
06994 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED)
06995     #undef   __STRICT_ANSI__
06996 #endif
06997 
06998 //-----------------------------------------------------------------------------------------------------------------
06999 
07000 #include <stdarg.h>
07001 #include <io.h>
07002 #include <fcntl.h>
07003 #include <process.h>
07004 #include <signal.h>
07005 #include <setjmp.h>
07006 #include <locale.h>
07007 #include <limits.h>
07008 #include <stdint.h>
07009 
07010 #include <map>
07011 #include <numeric>
07012 #include <exception>
07013 #include <stdexcept>
07014 
07015 #include <tlhelp32.h>
07016 #include <shellapi.h>
07017 
07018 #if defined (_GCC_VER)
07019 
07020 #include <shlobj.h>
07021 
07022 #include <cxxabi.h>
07023 #include <unwind.h>
07024 
07025 #endif
07026 
07027 #if defined (__CYGWIN__)
07028 
07029 #include <stdarg.h>
07030 #include <unistd.h>
07031 #include <termios.h>
07032 
07033 #endif
07034 
07035 #if defined (_MSC_VER)
07036 
07037 #include <new.h>
07038 
07039 #include <shlobj.h>
07040 #include <ntstatus.h>
07041 #include <crtdbg.h>
07042 #include <rtcapi.h>
07043 #include <dbghelp.h>
07044 
07045 #endif
07046 
07047 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800)  // MSVC 2013
07048 #include <inttypes.h>
07049 #endif
07050 
07051 //-----------------------------------------------------------------------------------------------------------------
07052 
07053 #if defined (TX_USE_SPEAK) //--------------------------------------------------------------------------------------
07054 #include <SAPI.h>          // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :(
07055 #endif                     //--------------------------------------------------------------------------------------
07056 
07057 //-----------------------------------------------------------------------------------------------------------------
07058 
07059 #if defined (_MSC_VER)
07060     #pragma warning (pop)                        // MSVC: Restore max level
07061 #endif
07062 
07063 #if defined (__STRICT_ANSI__UNDEFINED)
07064     #define  __STRICT_ANSI__                     // Redefine back
07065 #endif
07066 
07067 //-----------------------------------------------------------------------------------------------------------------
07068 
07069 _TX_BEGIN_NAMESPACE
07070 
07071 #endif // TX_COMPILED
07072 
07073 //}
07074 //-----------------------------------------------------------------------------------------------------------------
07075 
07076 //=================================================================================================================
07077 //{          DLL functions import, missing types definitions
07079 //=================================================================================================================
07081 
07082 //-----------------------------------------------------------------------------------------------------------------
07083 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers.
07084 //  Copied from Windows SDK 7.0a.
07085 //-----------------------------------------------------------------------------------------------------------------
07086 
07087 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07088 
07089 namespace Win32 {
07090 
07091 #ifndef AC_SRC_ALPHA
07092 #define AC_SRC_ALPHA                             0x01
07093 #endif
07094 
07095 #ifndef SMTO_ERRORONEXIT
07096 #define SMTO_ERRORONEXIT                         0x0020
07097 #endif
07098 
07099 #ifndef NT_CONSOLE_PROPS_SIG
07100 #define NT_CONSOLE_PROPS_SIG                     0xA0000002
07101 #endif
07102 
07103 #ifndef NIIF_INFO
07104 #define NIIF_INFO                                0x00000001
07105 #define NIIF_WARNING                             0x00000002
07106 #define NIIF_ERROR                               0x00000003
07107 #endif
07108 
07109 #ifndef NIF_INFO
07110 #define NIF_STATE                                0x00000008
07111 #define NIF_INFO                                 0x00000010
07112 #endif
07113 
07114 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
07115 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS   0x00000004
07116 #endif
07117 
07118 #ifndef SYMOPT_CASE_INSENSITIVE
07119 #define SYMOPT_CASE_INSENSITIVE                  0x00000001
07120 #define SYMOPT_UNDNAME                           0x00000002
07121 #define SYMOPT_DEFERRED_LOADS                    0x00000004
07122 #define SYMOPT_NO_CPP                            0x00000008
07123 #define SYMOPT_LOAD_LINES                        0x00000010
07124 #define SYMOPT_OMAP_FIND_NEAREST                 0x00000020
07125 #define SYMOPT_LOAD_ANYTHING                     0x00000040
07126 #define SYMOPT_IGNORE_CVREC                      0x00000080
07127 #define SYMOPT_NO_UNQUALIFIED_LOADS              0x00000100
07128 #define SYMOPT_FAIL_CRITICAL_ERRORS              0x00000200
07129 #define SYMOPT_EXACT_SYMBOLS                     0x00000400
07130 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS            0x00000800
07131 #define SYMOPT_IGNORE_NT_SYMPATH                 0x00001000
07132 #define SYMOPT_INCLUDE_32BIT_MODULES             0x00002000
07133 #define SYMOPT_PUBLICS_ONLY                      0x00004000
07134 #define SYMOPT_NO_PUBLICS                        0x00008000
07135 #define SYMOPT_AUTO_PUBLICS                      0x00010000
07136 #define SYMOPT_NO_IMAGE_SEARCH                   0x00020000
07137 #define SYMOPT_SECURE                            0x00040000
07138 #define SYMOPT_NO_PROMPTS                        0x00080000
07139 #define SYMOPT_ALLOW_ZERO_ADDRESS                0x01000000
07140 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT         0x02000000
07141 #define SYMOPT_FAVOR_COMPRESSED                  0x00800000
07142 #define SYMOPT_FLAT_DIRECTORY                    0x00400000
07143 #define SYMOPT_IGNORE_IMAGEDIR                   0x00200000
07144 #define SYMOPT_OVERWRITE                         0x00100000
07145 #define SYMOPT_DEBUG                             0x80000000
07146 #endif
07147 
07148 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66.
07149 
07150 #ifndef STATUS_POSSIBLE_DEADLOCK
07151 #define STATUS_POSSIBLE_DEADLOCK                 0xC0000194
07152 #endif
07153 
07154 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS
07155 #define STATUS_FLOAT_MULTIPLE_FAULTS             0xC00002B4
07156 #endif
07157 
07158 #ifndef STATUS_STACK_BUFFER_OVERRUN
07159 #define STATUS_STACK_BUFFER_OVERRUN              0xC0000409
07160 #endif
07161 
07162 #ifndef STATUS_ASSERTION_FAILURE
07163 #define STATUS_ASSERTION_FAILURE                 0xC0000420
07164 #endif
07165 
07166 #ifndef STATUS_WX86_BREAKPOINT
07167 #define STATUS_WX86_BREAKPOINT                   0x4000001F
07168 #endif
07169 
07170 #ifndef DBG_PRINTEXCEPTION_C
07171 #define DBG_PRINTEXCEPTION_C                     0x40010006  // OutputDebugStringA() call
07172 #endif
07173 
07174 #ifndef DBG_PRINTEXCEPTION_WIDE_C
07175 #define DBG_PRINTEXCEPTION_WIDE_C                0x4001000A  // OutputDebugStringW() call
07176 #endif
07177 
07178 #ifndef DBG_THREAD_NAME
07179 #define DBG_THREAD_NAME                          0x406D1388
07180 #endif
07181 
07182 #define EXCEPTION_CPP_MSC                        0xE06D7363  // '?msc'
07183 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1       0x19930520  // '?msc' version magic, see ehdata.h
07184 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2       0x19930521  // '?msc' version magic
07185 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3       0x19930522  // '?msc' version magic
07186 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1  0x01994000  // '?msc' version magic
07187 
07188 #define EXCEPTION_CPP_GCC                        0x20474343  // ' GCC'
07189 #define EXCEPTION_CPP_GCC_UNWIND                 0x21474343  // '!GCC'
07190 #define EXCEPTION_CPP_GCC_FORCED                 0x22474343  // '"GCC'
07191 
07192 #define EXCEPTION_CLR_FAILURE                    0xE0434f4D  // 'аCOM'
07193 
07194 #define EXCEPTION_CPP_BORLAND_BUILDER            0x0EEDFAE6  // Should never occur here
07195 #define EXCEPTION_CPP_BORLAND_DELPHI             0x0EEDFADE  // Should never occur here
07196 
07197 #pragma pack (push, 1)
07198 
07199 struct CONSOLE_CURSOR_INFO
07200     {
07201     DWORD dwSize;
07202     BOOL bVisible;
07203     };
07204 
07205 struct CONSOLE_FONT_INFO
07206     {
07207     DWORD nFont;
07208     COORD dwFontSize;
07209     };
07210 
07211 struct CONSOLE_FONT_INFOEX
07212     {
07213     ULONG cbSize;
07214     DWORD nFont;
07215     COORD dwFontSize;
07216     UINT  FontFamily;
07217     UINT  FontWeight;
07218     WCHAR FaceName[LF_FACESIZE];
07219     };
07220 
07221 struct DATABLOCK_HEADER
07222     {
07223     DWORD cbSize;
07224     DWORD dwSignature;
07225     };
07226 
07227 struct NT_CONSOLE_PROPS
07228     {
07229     DATABLOCK_HEADER dbh;
07230 
07231     WORD  wFillAttribute;
07232     WORD  wPopupFillAttribute;
07233     COORD dwScreenBufferSize;
07234     COORD dwWindowSize;
07235     COORD dwWindowOrigin;
07236     DWORD nFont;
07237     DWORD nInputBufferSize;
07238     COORD dwFontSize;
07239     UINT  uFontFamily;
07240     UINT  uFontWeight;
07241     WCHAR FaceName[LF_FACESIZE];
07242     UINT  uCursorSize;
07243     BOOL  bFullScreen;
07244     BOOL  bQuickEdit;
07245     BOOL  bInsertMode;
07246     BOOL  bAutoPosition;
07247     UINT  uHistoryBufferSize;
07248     UINT  uNumberOfHistoryBuffers;
07249     BOOL  bHistoryNoDup;
07250 
07251     COLORREF ColorTable[16];
07252     };
07253 
07254 struct FLASHWINFO
07255     {
07256     UINT  cbSize;
07257     HWND  hwnd;
07258     DWORD dwFlags;
07259     UINT  uCount;
07260     DWORD dwTimeout;
07261     };
07262 
07263 enum TBPFLAG
07264     {
07265     TBPF_NOPROGRESS    = 0x0,
07266     TBPF_INDETERMINATE = 0x1,
07267     TBPF_NORMAL        = 0x2,
07268     TBPF_ERROR         = 0x4,
07269     TBPF_PAUSED        = 0x8
07270     };
07271 
07272 #pragma pack (pop)
07273 
07274 const GUID IID_IShellLink             = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07275 const GUID IID_IShellLinkDataList     = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}};
07276 const GUID IID_IPersistFile           = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07277 
07278 const GUID IID_ITaskbarList3          = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}};
07279 const GUID CLSID_TaskbarList          = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}};
07280 
07281 const GUID CLSID_SpVoice              = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}};
07282 const GUID IID_ISpVoice               = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}};
07283 
07284 typedef DWORD     NTSTATUS;
07285 typedef ULONG_PTR KAFFINITY;
07286 typedef LONG      KPRIORITY;
07287 
07288 struct UNICODE_STRING
07289     {
07290     USHORT   Length;
07291     USHORT   MaximumLength;
07292     wchar_t* Buffer;
07293     };
07294 
07295 struct RTL_DRIVE_LETTER_CURDIR
07296     {
07297     USHORT         Flags;
07298     USHORT         Length;
07299     ULONG          TimeStamp;
07300     UNICODE_STRING DosPath;
07301     };
07302 
07303 struct CURDIR
07304     {
07305     UNICODE_STRING DosPath;
07306     void*          Handle;
07307     };
07308 
07309 struct RTL_USER_PROCESS_PARAMETERS
07310     {
07311     ULONG          AllocationSize;
07312     ULONG          Size;
07313     ULONG          Flags;
07314     ULONG          DebugFlags;
07315     HANDLE         ConsoleHandle;
07316     ULONG          ConsoleFlags;
07317     HANDLE         hStdInput;
07318     HANDLE         hStdOutput;
07319     HANDLE         hStdError;
07320     CURDIR         CurrentDirectory;
07321     UNICODE_STRING DllPath;
07322     UNICODE_STRING ImagePathName;
07323     UNICODE_STRING CommandLine;
07324     wchar_t*       Environment;
07325     ULONG          dwX;
07326     ULONG          dwY;
07327     ULONG          dwXSize;
07328     ULONG          dwYSize;
07329     ULONG          dwXCountChars;
07330     ULONG          dwYCountChars;
07331     ULONG          dwFillAttribute;
07332     ULONG          dwFlags;
07333     ULONG          wShowWindow;
07334     UNICODE_STRING WindowTitle;
07335     UNICODE_STRING Desktop;
07336     UNICODE_STRING ShellInfo;
07337     UNICODE_STRING RuntimeInfo;
07338     RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
07339     };
07340 
07341 struct PEB
07342     {
07343     BYTE  Reserved1[2];
07344     BYTE  BeingDebugged;
07345     BYTE  Reserved2[1];
07346     void* Reserved3[2];
07347     void* Ldr;
07348     RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
07349     void* Reserved4[3];
07350     void* AtlThunkSListPtr;
07351     void* Reserved5;
07352     ULONG Reserved6;
07353     void* Reserved7;
07354     ULONG Reserved8;
07355     ULONG AtlThunkSListPtr32;
07356     void* Reserved9[45];
07357     BYTE  Reserved10[96];
07358     void* PostProcessInitRoutine;
07359     BYTE  Reserved11[128];
07360     void* Reserved12[1];
07361     ULONG SessionId;
07362     };
07363 
07364 struct TEB
07365     {
07366     void* Reserved1[12];
07367     PEB*  ProcessEnvironmentBlock;
07368     void* Reserved2[399];
07369     BYTE  Reserved3[1952];
07370     void* TlsSlots[64];
07371     BYTE  Reserved4[8];
07372     void* Reserved5[26];
07373     void* ReservedForOle;
07374     void* Reserved6[4];
07375     void* TlsExpansionSlots;
07376     };
07377 
07378 struct PROCESS_BASIC_INFORMATION
07379     {
07380     NTSTATUS  ExitStatus;
07381     PEB*      PebBaseAddress;
07382     KAFFINITY AffinityMask;
07383     KPRIORITY BasePriority;
07384     ULONG_PTR UniqueProcessId;
07385     ULONG_PTR InheritedFromUniqueProcessId;
07386     };
07387 
07388 enum ADDRESS_MODE
07389     {
07390     AddrMode1616,
07391     AddrMode1632,
07392     AddrModeReal,
07393     AddrModeFlat
07394     };
07395 
07396 struct ADDRESS64
07397     {
07398     DWORD64      Offset;
07399     WORD         Segment;
07400     ADDRESS_MODE Mode;
07401     };
07402 
07403 struct KDHELP64
07404     {
07405     DWORD64 Thread;
07406     DWORD   ThCallbackStack;
07407     DWORD   ThCallbackBStore;
07408     DWORD   NextCallback;
07409     DWORD   FramePointer;
07410     DWORD64 KiCallUserMode;
07411     DWORD64 KeUserCallbackDispatcher;
07412     DWORD64 SystemRangeStart;
07413     DWORD64 KiUserExceptionDispatcher;
07414     DWORD64 StackBase;
07415     DWORD64 StackLimit;
07416     DWORD64 Reserved[5];
07417     };
07418 
07419 struct STACKFRAME64
07420     {
07421     ADDRESS64 AddrPC;
07422     ADDRESS64 AddrReturn;
07423     ADDRESS64 AddrFrame;
07424     ADDRESS64 AddrStack;
07425     ADDRESS64 AddrBStore;
07426     void*     FuncTableEntry;
07427     DWORD64   Params[4];
07428     BOOL      Far;
07429     BOOL      Virtual;
07430     DWORD64   Reserved[3];
07431     KDHELP64  KdHelp;
07432     };
07433 
07434 struct WOW64_FLOATING_SAVE_AREA
07435     {
07436     DWORD ControlWord;
07437     DWORD StatusWord;
07438     DWORD TagWord;
07439     DWORD ErrorOffset;
07440     DWORD ErrorSelector;
07441     DWORD DataOffset;
07442     DWORD DataSelector;
07443     BYTE  RegisterArea[80];
07444     DWORD Cr0NpxState;
07445     };
07446 
07447 #pragma pack (push, 4)
07448 
07449 struct WOW64_CONTEXT
07450     {
07451     DWORD ContextFlags;
07452 
07453     DWORD Dr0;
07454     DWORD Dr1;
07455     DWORD Dr2;
07456     DWORD Dr3;
07457     DWORD Dr6;
07458     DWORD Dr7;
07459 
07460     WOW64_FLOATING_SAVE_AREA FloatSave;
07461 
07462     DWORD SegGs;
07463     DWORD SegFs;
07464     DWORD SegEs;
07465     DWORD SegDs;
07466 
07467     DWORD Edi;
07468     DWORD Esi;
07469     DWORD Ebx;
07470     DWORD Edx;
07471     DWORD Ecx;
07472     DWORD Eax;
07473 
07474     DWORD Ebp;
07475     DWORD Eip;
07476     DWORD SegCs;
07477     DWORD EFlags;
07478     DWORD Esp;
07479     DWORD SegSs;
07480 
07481     BYTE  ExtendedRegisters[512];
07482     };
07483 
07484 #pragma pack (pop)
07485 
07486 struct SYMBOL_INFO
07487     {
07488     ULONG   SizeOfStruct;
07489     ULONG   TypeIndex;
07490     ULONG64 Reserved[2];
07491     ULONG   info;
07492     ULONG   Size;
07493     ULONG64 ModBase;
07494     ULONG   Flags;
07495     ULONG64 Value;
07496     ULONG64 Address;
07497     ULONG   Register;
07498     ULONG   Scope;
07499     ULONG   Tag;
07500     ULONG   NameLen;
07501     ULONG   MaxNameLen;
07502     char    Name[1];
07503     };
07504 
07505 struct IMAGEHLP_LINE64
07506     {
07507     DWORD   SizeOfStruct;
07508     void*   Key;
07509     DWORD   LineNumber;
07510     char*   FileName;
07511     DWORD64 Address;
07512     };
07513 
07514 typedef bool    (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)   (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead);
07515 typedef void*   (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress);
07516 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)       (HANDLE process, DWORD64 address);
07517 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)     (HANDLE process, HANDLE thread, ADDRESS64* address);
07518 
07519 typedef void (*unexpected_handler)();
07520 
07521 #pragma pack (push, 4)
07522 
07523 struct MINIDUMP_THREAD_CALLBACK
07524     {
07525     ULONG    ThreadId;
07526     HANDLE   ThreadHandle;
07527     CONTEXT  Context;
07528     ULONG    SizeOfContext;
07529     ULONG64  StackBase;
07530     ULONG64  StackEnd;
07531     };
07532 
07533 struct MINIDUMP_THREAD_EX_CALLBACK
07534     {
07535     ULONG    ThreadId;
07536     HANDLE   ThreadHandle;
07537     CONTEXT  Context;
07538     ULONG    SizeOfContext;
07539     ULONG64  StackBase;
07540     ULONG64  StackEnd;
07541     ULONG64  BackingStoreBase;
07542     ULONG64  BackingStoreEnd;
07543     };
07544 
07545 struct MINIDUMP_MODULE_CALLBACK
07546     {
07547     wchar_t* FullPath;
07548     ULONG64  BaseOfImage;
07549     ULONG    SizeOfImage;
07550     ULONG    CheckSum;
07551     ULONG    TimeDateStamp;
07552     VS_FIXEDFILEINFO VersionInfo;
07553     void*    CvRecord;
07554     ULONG    SizeOfCvRecord;
07555     void*    MiscRecord;
07556     ULONG    SizeOfMiscRecord;
07557     };
07558 
07559 struct MINIDUMP_INCLUDE_THREAD_CALLBACK
07560     {
07561     ULONG    ThreadId;
07562     };
07563 
07564 struct MINIDUMP_INCLUDE_MODULE_CALLBACK
07565     {
07566     ULONG64  BaseOfImage;
07567     };
07568 
07569 struct MINIDUMP_MEMORY_INFO
07570     {
07571     ULONG64  BaseAddress;
07572     ULONG64  AllocationBase;
07573     ULONG32  AllocationProtect;
07574     ULONG32  __alignment1;
07575     ULONG64  RegionSize;
07576     ULONG32  State;
07577     ULONG32  Protect;
07578     ULONG32  Type;
07579     ULONG32  __alignment2;
07580     };
07581 
07582 struct MINIDUMP_USER_STREAM
07583     {
07584     ULONG32  Type;
07585     ULONG    BufferSize;
07586     void*    Buffer;
07587     };
07588 
07589 struct MINIDUMP_USER_STREAM_INFORMATION
07590     {
07591     ULONG                 UserStreamCount;
07592     MINIDUMP_USER_STREAM* UserStreamArray;
07593     };
07594 
07595 struct MINIDUMP_CALLBACK_INPUT
07596     {
07597     ULONG    ProcessId;
07598     HANDLE   ProcessHandle;
07599     ULONG    CallbackType;
07600 
07601     union  //-V2514
07602         {
07603         MINIDUMP_THREAD_CALLBACK         Thread;
07604         MINIDUMP_THREAD_EX_CALLBACK      ThreadEx;
07605         MINIDUMP_MODULE_CALLBACK         Module;
07606         MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
07607         MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
07608         };
07609     };
07610 
07611 struct MINIDUMP_CALLBACK_OUTPUT
07612     {
07613     union  //-V2514
07614         {
07615         ULONG ModuleWriteFlags;
07616         ULONG ThreadWriteFlags;
07617         ULONG SecondaryFlags;
07618 
07619         struct
07620             {
07621             ULONG64  MemoryBase;
07622             ULONG    MemorySize;
07623             };
07624 
07625         struct
07626             {
07627             unsigned CheckCancel;
07628             unsigned Cancel;
07629             };
07630 
07631         HANDLE Handle;  //-V117
07632         };
07633 
07634     struct
07635         {
07636         MINIDUMP_MEMORY_INFO VmRegion;
07637         unsigned             Continue;
07638         };
07639 
07640     HRESULT Status;
07641     };
07642 
07643 struct MINIDUMP_EXCEPTION_INFORMATION
07644     {
07645     DWORD               ThreadId;
07646     EXCEPTION_POINTERS* ExceptionPointers;
07647     unsigned            ClientPointers;
07648     };
07649 
07650 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output);
07651 
07652 struct MINIDUMP_CALLBACK_INFORMATION
07653     {
07654     MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
07655     void*                     CallbackParam;
07656     };
07657 
07658 enum MINIDUMP_TYPE
07659     {
07660     MiniDumpNormal                         = 0x00000000,
07661     MiniDumpWithDataSegs                   = 0x00000001,
07662     MiniDumpWithFullMemory                 = 0x00000002,
07663     MiniDumpWithHandleData                 = 0x00000004,
07664     MiniDumpFilterMemory                   = 0x00000008,
07665     MiniDumpScanMemory                     = 0x00000010,
07666     MiniDumpWithUnloadedModules            = 0x00000020,
07667     MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
07668     MiniDumpFilterModulePaths              = 0x00000080,
07669     MiniDumpWithProcessThreadData          = 0x00000100,
07670     MiniDumpWithPrivateReadWriteMemory     = 0x00000200,
07671     MiniDumpWithoutOptionalData            = 0x00000400,
07672     MiniDumpWithFullMemoryInfo             = 0x00000800,
07673     MiniDumpWithThreadInfo                 = 0x00001000,
07674     MiniDumpWithCodeSegs                   = 0x00002000,
07675     MiniDumpWithoutAuxiliaryState          = 0x00004000,
07676     MiniDumpWithFullAuxiliaryState         = 0x00008000,
07677     MiniDumpWithPrivateWriteCopyMemory     = 0x00010000,
07678     MiniDumpIgnoreInaccessibleMemory       = 0x00020000,
07679     MiniDumpWithTokenInformation           = 0x00040000
07680     };
07681 
07682 #ifndef CONTEXT_ALL
07683 #define CONTEXT_ALL              ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS )
07684 #endif
07685 
07686 #pragma pack (pop)
07687 
07688 } // namespace Win32
07689 
07690 #endif // TX_COMPILED
07691 
07692 #define FOREGROUND_BLACK         ( 0                                                         )
07693 #define FOREGROUND_CYAN          ( FOREGROUND_BLUE       | FOREGROUND_GREEN                  )
07694 #define FOREGROUND_MAGENTA       ( FOREGROUND_BLUE       | FOREGROUND_RED                    )
07695 #define FOREGROUND_DARKYELLOW    ( FOREGROUND_GREEN      | FOREGROUND_RED                    )
07696 #define FOREGROUND_LIGHTGRAY     ( FOREGROUND_BLUE       | FOREGROUND_GREEN | FOREGROUND_RED )
07697 #define FOREGROUND_DARKGRAY      (                         FOREGROUND_INTENSITY              )
07698 #define FOREGROUND_LIGHTBLUE     ( FOREGROUND_BLUE       | FOREGROUND_INTENSITY              )
07699 #define FOREGROUND_LIGHTGREEN    ( FOREGROUND_GREEN      | FOREGROUND_INTENSITY              )
07700 #define FOREGROUND_LIGHTCYAN     ( FOREGROUND_CYAN       | FOREGROUND_INTENSITY              )
07701 #define FOREGROUND_LIGHTRED      ( FOREGROUND_RED        | FOREGROUND_INTENSITY              )
07702 #define FOREGROUND_LIGHTMAGENTA  ( FOREGROUND_MAGENTA    | FOREGROUND_INTENSITY              )
07703 #define FOREGROUND_YELLOW        ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY              )
07704 #define FOREGROUND_WHITE         ( FOREGROUND_LIGHTGRAY  | FOREGROUND_INTENSITY              )
07705 
07706 #define BACKGROUND_BLACK         ( 0                                                         )
07707 #define BACKGROUND_CYAN          ( BACKGROUND_BLUE       | BACKGROUND_GREEN                  )
07708 #define BACKGROUND_MAGENTA       ( BACKGROUND_BLUE       | BACKGROUND_RED                    )
07709 #define BACKGROUND_DARKYELLOW    ( BACKGROUND_GREEN      | BACKGROUND_RED                    )
07710 #define BACKGROUND_GRAY          ( BACKGROUND_BLUE       | BACKGROUND_GREEN | BACKGROUND_RED )
07711 #define BACKGROUND_DARKGRAY      (                         BACKGROUND_INTENSITY              )
07712 #define BACKGROUND_LIGHTBLUE     ( BACKGROUND_BLUE       | BACKGROUND_INTENSITY              )
07713 #define BACKGROUND_LIGHTGREEN    ( BACKGROUND_GREEN      | BACKGROUND_INTENSITY              )
07714 #define BACKGROUND_LIGHTCYAN     ( BACKGROUND_CYAN       | BACKGROUND_INTENSITY              )
07715 #define BACKGROUND_LIGHTRED      ( BACKGROUND_RED        | BACKGROUND_INTENSITY              )
07716 #define BACKGROUND_LIGHTMAGENTA  ( BACKGROUND_MAGENTA    | BACKGROUND_INTENSITY              )
07717 #define BACKGROUND_LIGHTYELLOW   ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY              )
07718 #define BACKGROUND_WHITE         ( BACKGROUND_DARKGRAY   | BACKGROUND_INTENSITY              )
07719 
07720 //}
07721 //-----------------------------------------------------------------------------------------------------------------
07722 
07723 //-----------------------------------------------------------------------------------------------------------------
07724 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode.
07725 //  So we have to override them. See: http://stackoverflow.com/questions/39113168
07726 //-----------------------------------------------------------------------------------------------------------------
07727 
07728 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07729 
07730 #if defined (_MSC_VER)
07731                                                     //  MS ABI C++ Exception Layout
07732 namespace Win32 {                                   //  ---------------------------
07733                                                     //
07734 #pragma pack (push, 4)                              //   EXCEPTION_RECORD:
07735                                                     //  +==================================================+
07736 struct ThrowInfo                                    //  |...                                               |
07737     {                                               //  |NumberParameters:        3, 4 or more             |
07738     __int32 attributes;                             //  |ExceptionInformation[0]: MS signature 0x19930520  |
07739     __int32 pmfnUnwind;                             //  |ExceptionInformation[1]: object* thrown           |
07740     __int32 pForwardCompat;                         //  |ExceptionInformation[2]: ThrowInfo* --------------+---+
07741     __int32 pCatchableTypeArray;                    //  |ExceptionInformation[3]: ImageBase (if params > 3)|   |
07742     };                                              //  +==================================================+   |
07743                                                     //                                                         |
07744 struct CatchableTypeArray                           //        ThrowInfo:                                       |
07745     {                                               //        +======================================+ <-------+
07746     __int32 nCatchableTypes;                        //        |   ...                                |
07747     __int32 arrayOfCatchableTypes[];                //  +-----+-- pCatchableTypeArray (ptr/RVA)      |
07748     };                                              //  |     +======================================+
07749                                                     //  |
07750 struct CatchableType                                //  |     CatchableTypeArray:
07751     {                                               //  +---> +======================================+
07752     __int32 properties;                             //        |   ...                                |
07753     __int32 pType;                                  //  +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) |
07754     __int32 thisDisplacement[3]; // struct _PMD     //  |     +======================================+
07755     __int32 sizeOrOffset;                           //  |
07756     __int32 copyFunction;                           //  |     CatchableType:
07757     };                                              //  +---> +====================+
07758                                                     //        | ...                |        std::type_info:
07759 #pragma pack (pop)                                  //        | pType (ptr/RVA) ---+------> +==================+
07760                                                     //        | ...                |        |type_info data    |
07761 } // namespace Win32                                //        +====================+        |...               |
07762                                                     //                                      +==================+
07763 #endif
07764 
07765 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp:
07766 
07767 #define _TX_MSC__CXX_DETECT_RETHROW( exc )                                     \
07768     (                                                                          \
07769     (exc)                                          &&                          \
07770     (exc) -> ExceptionCode    == EXCEPTION_CPP_MSC &&                          \
07771     (exc) -> NumberParameters >= 3                 &&                          \
07772                                                                                \
07773     ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||  \
07774      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||  \
07775      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \
07776                                                                                \
07777     (exc) -> ExceptionInformation[2] == 0                                      \
07778     )
07779 
07780 #endif // TX_COMPILED
07781 
07782 //}
07783 //-----------------------------------------------------------------------------------------------------------------
07784 
07785 //-----------------------------------------------------------------------------------------------------------------
07786 //{ The corresponding structures for GCC
07787 //
07788 //  From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h
07789 //  See:  http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi
07790 //-----------------------------------------------------------------------------------------------------------------
07791 
07792 #if defined (_GCC_VER)
07793 
07794 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07795 
07796                                                     // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0].
07797 namespace ABI {                                     // --------------------------------------------------------------
07798                                                     //
07799 struct __cxa_exception                              // Case A: "_Unwind_Exception* A" is independent exception:
07800     {                                               // --------------------------------------------------------
07801     union {                                         //
07802         struct                                      //           __cxa_exception:           std::type_info:
07803             {                                       //       -*--+====================+     +==================+
07804             ::std::type_info* exceptionType;        //        ^  |exceptionType* -----+---->|type_info data    |
07805             void (*exceptionDestructor)(void*);     //        |  |...                 |     |...               |
07806             };                                      //       -1  |                    |     +==================+
07807         struct                                      //        |  |                    |
07808             {                                       // A >----|--+--------------------+
07809             __cxa_exception*  primaryException;     //     |  |  |unwindHeader        |
07810             void (*padding)();                      //    +1  |  |                    |
07811             };                                      //     |  |  |                    |
07812         };                                          //     V  |  |                    |
07813                                                     //    -*---  +====================+
07814     void (*unexpected_handler)();                   //           |object              |
07815     std::terminate_handler    terminateHandler;     //           +--------------------+
07816                                                     //
07817     __cxa_exception*          nextException;        // Case B: "_Unwind_Exception* B" is dependent exception
07818     int                       handlerCount;         // (unwindHeader.exception_class & 1 != 0):
07819     int                       handlerSwitchValue;   // -----------------------------------------------------
07820     const unsigned char*      actionRecord;         //
07821     const unsigned char*      languageSpecificData; //           __cxa_exception:               __cxa_exception:
07822     void*                     catchTemp;            //       -*--+====================+     -*--+=================+
07823     void*                     adjustedPtr;          //        ^  |primaryException* --+--    ^  |exceptionType*   |
07824                                                     //        |  |...                 |  \   |  |...              |
07825     _Unwind_Exception         unwindHeader;         //       -1  |                    |  |   |  |                 |
07826     };                                              //        |  |                    |  |   |  |                 |
07827                                                     // B >----|--+--------------------+  |  -1  +-----------------+
07828 struct __cxa_eh_globals                             //     |  |  |unwindHeader        |  |   |  |unwindHeader     |
07829     {                                               //    +1  |  |                    |  |   |  |                 |
07830     __cxa_exception* caughtExceptions;              //     |  |  |                    |  |   |  |                 |
07831     unsigned int     uncaughtExceptions;            //     V  |  |                    |  \   |  |                 |
07832     };                                              //    -*---  +====================+   -->*--+=================+
07833                                                     //           |...                 |         |object           |
07834 } // namespace ABI                                  //           .                    .         |                 |
07835                                                     //                                          +-----------------+
07836 
07837 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals();
07838 
07839 #endif // TX_COMPILED
07840 
07841 #endif
07842 
07843 //}
07844 //-----------------------------------------------------------------------------------------------------------------
07845 
07846 //-----------------------------------------------------------------------------------------------------------------
07847 //{ Hand-made IAT.
07848 //  Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :(
07849 //-----------------------------------------------------------------------------------------------------------------
07850 
07851 // Hand-made DLLIMPORT helpers
07852 
07853 #define _TX_DLLIMPORT(     lib, retval, name, params )  TX_DLLIMPORT (true,  lib ".dll", retval, name, params, WINAPI)
07854 #define _TX_DLLIMPORT_OPT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI)
07855 #define _TX_DLLIMPORT_CRT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, please)
07856 
07857 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) ();
07858 
07859 //-----------------------------------------------------------------------------------------------------------------
07860 
07861 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07862 
07863 namespace Win32 {
07864 
07865 _TX_DLLIMPORT     ("GDI32",    HDC,      CreateCompatibleDC,            (HDC dc));
07866 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateCompatibleBitmap,        (HDC dc, int width, int height));
07867 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetStockObject,                (int object));
07868 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  SelectObject,                  (HDC dc, HGDIOBJ object));
07869 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetCurrentObject,              (HDC dc, unsigned objectType));
07870 _TX_DLLIMPORT     ("GDI32",    int,      GetObjectA,                    (HGDIOBJ obj, int bufsize, void* buffer));
07871 _TX_DLLIMPORT     ("GDI32",    DWORD,    GetObjectType,                 (HGDIOBJ object));
07872 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteDC,                      (HDC dc));
07873 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteObject,                  (HGDIOBJ object));
07874 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetTextColor,                  (HDC dc, COLORREF color));
07875 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetBkColor,                    (HDC dc, COLORREF color));
07876 _TX_DLLIMPORT     ("GDI32",    int,      SetBkMode,                     (HDC dc, int bkMode));
07877 _TX_DLLIMPORT     ("GDI32",    HFONT,    CreateFontA,                   (int height, int width, int escapement, int orientation,
07878                                                                          int weight, DWORD italic, DWORD underline, DWORD strikeout,
07879                                                                          DWORD charSet, DWORD outputPrec, DWORD clipPrec,
07880                                                                          DWORD quality, DWORD pitchAndFamily, const char face[]));
07881 _TX_DLLIMPORT     ("GDI32",    int,      EnumFontFamiliesExA,           (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc,
07882                                                                          LPARAM lParam, DWORD reserved));
07883 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetPixel,                      (HDC dc, int x, int y, COLORREF color));
07884 _TX_DLLIMPORT     ("GDI32",    COLORREF, GetPixel,                      (HDC dc, int x, int y));
07885 _TX_DLLIMPORT     ("GDI32",    HPEN,     CreatePen,                     (int penStyle, int width, COLORREF color));
07886 _TX_DLLIMPORT     ("GDI32",    HBRUSH,   CreateSolidBrush,              (COLORREF color));
07887 _TX_DLLIMPORT     ("GDI32",    bool,     MoveToEx,                      (HDC dc, int x, int y, POINT* point));
07888 _TX_DLLIMPORT     ("GDI32",    bool,     LineTo,                        (HDC dc, int x, int y));
07889 _TX_DLLIMPORT     ("GDI32",    bool,     Polygon,                       (HDC dc, const POINT points[], int count));
07890 _TX_DLLIMPORT     ("GDI32",    bool,     Polyline,                      (HDC dc, const POINT points[], int count));
07891 _TX_DLLIMPORT     ("GDI32",    bool,     PolyBezier,                    (HDC dc, const POINT points[], int count));
07892 _TX_DLLIMPORT     ("GDI32",    bool,     Rectangle,                     (HDC dc, int x0, int y0, int x1, int y1));
07893 _TX_DLLIMPORT     ("GDI32",    bool,     RoundRect,                     (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY));
07894 _TX_DLLIMPORT     ("GDI32",    bool,     Ellipse,                       (HDC dc, int x0, int y0, int x1, int y1));
07895 _TX_DLLIMPORT     ("GDI32",    bool,     Arc,                           (HDC dc, int x0, int y0, int x1, int y1,
07896                                                                          int xStart, int yStart, int xEnd, int yEnd));
07897 _TX_DLLIMPORT     ("GDI32",    bool,     Pie,                           (HDC dc, int x0, int y0, int x1, int y1,
07898                                                                          int xStart, int yStart, int xEnd, int yEnd));
07899 _TX_DLLIMPORT     ("GDI32",    bool,     Chord,                         (HDC dc, int x0, int y0, int x1, int y1,
07900                                                                          int xStart, int yStart, int xEnd, int yEnd));
07901 _TX_DLLIMPORT     ("GDI32",    bool,     TextOutA,                      (HDC dc, int x, int y, const char string[], int length));
07902 _TX_DLLIMPORT     ("GDI32",    UINT,     SetTextAlign,                  (HDC dc, unsigned mode));
07903 _TX_DLLIMPORT     ("GDI32",    bool,     GetTextExtentPoint32A,         (HDC dc, const char string[], int length, SIZE* size));
07904 _TX_DLLIMPORT     ("GDI32",    bool,     ExtFloodFill,                  (HDC dc, int x, int y, COLORREF color, unsigned type));
07905 _TX_DLLIMPORT     ("GDI32",    bool,     BitBlt,                        (HDC dest, int xDest, int yDest, int width, int height,
07906                                                                          HDC src,  int xSrc,  int ySrc,  DWORD rOp));
07907 _TX_DLLIMPORT     ("GDI32",    bool,     StretchBlt,                    (HDC dest, int xDest, int yDest, int width, int height,
07908                                                                          HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp));
07909 _TX_DLLIMPORT     ("GDI32",    bool,     PlgBlt,                        (HDC dest, const POINT* parallelogram,
07910                                                                          HDC src, int xSrc, int ySrc, int width, int height,
07911                                                                          HBITMAP mask, int xMask, int yMask));
07912 _TX_DLLIMPORT     ("GDI32",    int,      SetDIBitsToDevice,             (HDC dc, int xDest, int yDest, DWORD width, DWORD height,
07913                                                                          int xSrc, int ySrc, unsigned startLine, unsigned numLines,
07914                                                                          const void* data, const BITMAPINFO* info, unsigned colorUse));
07915 _TX_DLLIMPORT     ("GDI32",    int,      GetDIBits,                     (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines,
07916                                                                          void* lpvBits, BITMAPINFO* lpbi, unsigned usage));
07917 _TX_DLLIMPORT     ("GDI32",    bool,     PatBlt,                        (HDC dc, int x0, int y0, int width, int height, DWORD rOp));
07918 _TX_DLLIMPORT     ("GDI32",    int,      SetROP2,                       (HDC dc, int mode));
07919 _TX_DLLIMPORT     ("GDI32",    int,      SetStretchBltMode,             (HDC dc, int mode));
07920 _TX_DLLIMPORT     ("GDI32",    DWORD,    GdiSetBatchLimit,              (DWORD limit));
07921 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateDIBSection,              (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits,
07922                                                                          HANDLE section, DWORD offset));
07923 
07924 _TX_DLLIMPORT     ("User32",   int,      DrawTextA,                     (HDC dc, const char text[], int length, RECT* rect, unsigned format));
07925 _TX_DLLIMPORT     ("User32",   HANDLE,   LoadImageA,                    (HINSTANCE inst, const char name[], unsigned type,
07926                                                                         int sizex, int sizey, unsigned mode));
07927 _TX_DLLIMPORT_OPT ("User32",   bool,     IsHungAppWindow,               (HWND wnd));
07928 _TX_DLLIMPORT_OPT ("User32",   HWND,     GhostWindowFromHungWindow,     (HWND wnd));
07929 _TX_DLLIMPORT_OPT ("User32",   bool,     FlashWindowEx,                 (const FLASHWINFO* flash));
07930 
07931 _TX_DLLIMPORT     ("WinMM",    bool,     PlaySound,                     (const char sound[], HMODULE mod, DWORD mode));
07932 
07933 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     TransparentBlt,                (HDC dest, int destX, int destY, int destWidth, int destHeight,
07934                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
07935                                                                          unsigned transparentColor));
07936 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     AlphaBlend,                    (HDC dest, int destX, int destY, int destWidth, int destHeight,
07937                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
07938                                                                          BLENDFUNCTION blending));
07939 
07940 _TX_DLLIMPORT     ("Kernel32", void,     ExitProcess,                   (unsigned retcode));
07941 _TX_DLLIMPORT     ("Kernel32", bool,     TerminateProcess,              (HANDLE process, unsigned retcode));
07942 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalExit,                     (int retcode));
07943 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalAppExitA,                 (unsigned action, const char message[]));
07944 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetThreadId,                   (HANDLE thread));
07945 _TX_DLLIMPORT     ("Kernel32", HWND,     GetConsoleWindow,              (void));
07946 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetConsoleFont,                (HANDLE con, DWORD fontIndex));
07947 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetNumberOfConsoleFonts,       (void));
07948 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFont,         (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO*   curFont));
07949 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
07950 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
07951 _TX_DLLIMPORT_OPT ("Kernel32", void,     RtlCaptureContext,             (CONTEXT* contextRecord));
07952 _TX_DLLIMPORT_OPT ("Kernel32", USHORT,   RtlCaptureStackBackTrace,      (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash));
07953 _TX_DLLIMPORT_OPT ("Kernel32", void*,    AddVectoredExceptionHandler,   (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler));
07954 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler));
07955 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetModuleHandleEx,             (DWORD flags, const char moduleName[], HMODULE* module));
07956 _TX_DLLIMPORT_OPT ("Kernel32", bool,     IsWow64Process,                (HANDLE process, int* isWow64Process));
07957 _TX_DLLIMPORT_OPT ("Kernel32", bool,     Wow64GetThreadContext,         (HANDLE thread, WOW64_CONTEXT* context));
07958 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetThreadStackGuarantee,       (unsigned long* stackSize));
07959 
07960 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoInitialize,                  (void*));
07961 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoCreateInstance,              (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value));
07962 _TX_DLLIMPORT     ("OLE32",    void,     CoUninitialize,                (void));
07963 
07964 _TX_DLLIMPORT     ("Shell32",  HINSTANCE,ShellExecuteA,                 (HWND wnd, const char operation[], const char file[],
07965                                                                          const char parameters[], const char directory[], int showCmd));
07966 
07967 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIA,                      (const char    string[], const char    search[]));
07968 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIW,                      (const wchar_t string[], const wchar_t search[]));
07969 
07970 _TX_DLLIMPORT_OPT ("NTDLL",    char*,    wine_get_version,              (void));
07971 _TX_DLLIMPORT     ("NTDLL",    NTSTATUS, NtQueryInformationProcess,     (HANDLE process, int infoClass,
07972                                                                          void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo));
07973 
07974 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     exit,                          (int retcode));
07975 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     _cexit,                        (void));
07976 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _fpreset,                      (void));
07977 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _controlfp,                    (unsigned control, unsigned mask));
07978 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthread,                  (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist));
07979 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthreadex,                (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*),
07980                                                                          void *arglist, unsigned init_flag, unsigned* thread_addr));
07981 _TX_DLLIMPORT_CRT ("MSVCRT",   char*,    __unDName,                     (char* outStr, const char* mangledName, int outStrLen,
07982                                                                          void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer),
07983                                                                          unsigned short flags));
07984 _TX_DLLIMPORT_CRT ("MSVCRT",   unexpected_handler, set_unexpected,      (unexpected_handler handler));
07985 
07986 _TX_DLLIMPORT_OPT ("OpenGL32", HDC,         wglGetCurrentDC,            (void));
07987 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned,    glGetError,                 (void));
07988 _TX_DLLIMPORT_OPT ("Glu32",    const char*, gluErrorString,             (unsigned error));
07989 
07990 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD,    CommDlgExtendedError,          (void));
07991 
07992 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     MiniDumpWriteDump,             (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType,
07993                                                                          MINIDUMP_EXCEPTION_INFORMATION*   exceptionParam,
07994                                                                          MINIDUMP_USER_STREAM_INFORMATION* userStreamParam,
07995                                                                          MINIDUMP_CALLBACK_INFORMATION*    callbackParam));
07996 
07997 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD,    SymSetOptions,                 (DWORD options));
07998 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
07999 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08000 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08001 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08002 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymCleanup,                    (HANDLE process));
08003 _TX_DLLIMPORT_OPT ("DbgHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08004 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08005                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08006                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08007                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08008                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08009 namespace MinGW {
08010 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD,    SymSetOptions,                 (DWORD options));
08011 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
08012 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08013 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08014 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08015 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymCleanup,                    (HANDLE process));
08016 _TX_DLLIMPORT_OPT ("MgwHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08017 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08018                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08019                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08020                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08021                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08022 } // namespace MinGW
08023 } // namespace Win32
08024 
08025 #endif // TX_COMPILED
08026 
08027 //}
08028 //-----------------------------------------------------------------------------------------------------------------
08029 
08031 //}
08032 //=================================================================================================================
08033 
08034 //=================================================================================================================
08035 //{          Internal function prototypes, macros and constants
08036 //  @name    Прототипы внутренних функций, макросы и константы
08037 //=================================================================================================================
08039 
08040 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08041 
08042 int              _txInitialize();
08043 void             _txCleanup();
08044 
08045 HWND             _txCanvas_CreateWindow      (const SIZE* size);
08046 
08047 bool             _txCanvas_OnCREATE          (HWND wnd);
08048 bool             _txCanvas_OnDESTROY         (HWND wnd);
08049 bool             _txCanvas_OnCLOSE           (HWND);
08050 bool             _txCanvas_OnPAINT           (HWND wnd);
08051 bool             _txCanvas_OnKEY             (HWND wnd, WPARAM vk, LPARAM info, bool down);
08052 bool             _txCanvas_OnCHAR            (HWND wnd, WPARAM ch, LPARAM info);
08053 bool             _txCanvas_OnTIMER           (HWND wnd, WPARAM id);
08054 bool             _txCanvas_OnMOUSEMOVE       (HWND wnd, WPARAM buttons, LPARAM coords);
08055 bool             _txCanvas_OnMOUSELEAVE      (HWND wnd);
08056 bool             _txCanvas_OnCREATEWND       (HWND wnd, WPARAM, LPARAM lpar);
08057 bool             _txCanvas_OnDESTROYWND      (HWND wnd, WPARAM, LPARAM lpar);
08058 bool             _txCanvas_OnCmdCONSOLE      (HWND wnd, WPARAM cmd);
08059 bool             _txCanvas_OnCmdABOUT        (HWND wnd, WPARAM cmd);
08060 
08061 unsigned WINAPI  _txCanvas_ThreadProc        (void* data);
08062 LRESULT CALLBACK _txCanvas_WndProc           (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08063 
08064 HDC              _txBuffer_Create            (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL,
08065                                               RGBQUAD** pixels = NULL) tx_nodiscard;
08066 bool             _txBuffer_Delete            (HDC* dc);
08067 bool             _txBuffer_Select            (HGDIOBJ obj, HDC dc = txDC());
08068 
08069 HWND             _txConsole_Attach();
08070 bool             _txConsole_OK() tx_nodiscard;
08071 bool             _txConsole_Detach           (bool activate);
08072 bool             _txConsole_Draw             (HDC dc);
08073 bool             _txConsole_SetUnicodeFont();
08074 
08075 const char*       txRegisterClass            (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra);
08076 HWND              txCreateExtraWindow        (CREATESTRUCT createData);
08077 HICON            _txCreateTXIcon             (int size) tx_nodiscard;
08078 int              _txSetWindowText            (HWND wnd, const char* textRus, const char* textEng = NULL,
08079                                               int checkOfs = 0, const wchar_t checkLetters[2] = NULL);
08080 int              _txPauseBeforeTermination   (HWND canvas);
08081 int              _txIsParentWaitable         (DWORD* parentPID = NULL) tx_nodiscard;
08082 void             _txActivateWindow           (HWND wnd, unsigned mode);
08083 int              _txGetInput();
08084 
08085 LRESULT CALLBACK _txPlayVideo_WndProc        (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08086 const char*      _txPlayVideo_FindVLC() tx_nodiscard;
08087 
08088 bool             _txCreateShortcut           (const char shortcutName[],
08089                                               const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL,
08090                                               const char description[] = NULL, int cmdShow = SW_SHOWNORMAL,
08091                                               const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0,
08092                                               COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD));
08093 
08094 void*            _tx_DLGTEMPLATE_Create      (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
08095                                               WORD controls, short x, short y, short cx, short cy,
08096                                               const char caption[], const char font[], WORD fontsize,
08097                                               const char menu[]) tx_nodiscard;
08098 
08099 void*            _tx_DLGTEMPLATE_Add         (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
08100                                               short x, short y, short cx, short cy,
08101                                               WORD id, const char wclass[], const char caption[]);
08102 
08103 const char*      _txProcessError             (const char file[], int line, const char func[], unsigned color,
08104                                               const char msg[], va_list args);
08105 void             _txOnTerminate();
08106 void             _txOnUnexpected();
08107 void             _txOnPureCall();
08108 void             _txOnNewHandlerAnsi();
08109 int              _txOnNewHandler             (size_t size);
08110 void             _txOnSignal                 (int signal = 0, int fpe = 0);
08111 BOOL WINAPI      _txOnConsoleCtrlEvent       (DWORD type);
08112 void             _txOnSecurityError          (int code, void*);
08113 void             _txOnSecurityErrorAnsi      (const char* msg, void* ptr, int code);
08114 int              _txOnMatherr                (_exception* except);
08115 void             _txOnInvalidParam           (const wchar_t* expr, const wchar_t* func, const wchar_t* file,
08116                                               unsigned line, uintptr_t);
08117 int              _txOnAllocHook              (int type, void* data, size_t size, int use, long request,
08118                                               const unsigned char* file, int line);
08119 int              _txOnRTCFailure             (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5);
08120 int              _txOnErrorReport            (int type, const char* text, int* ret);
08121 int               tx_glGetError              (int setError = INT_MIN);
08122 
08123 void             _txOnCExit();
08124 void             _txOnExit                   (int      retcode);
08125 void             _txOnFatalExit              (int      retcode);
08126 void             _txOnExitProcess            (unsigned retcode);
08127 void             _txOnFatalAppExitA          (unsigned action, const char message[]);
08128 bool             _txOnTerminateProcess       (HANDLE process, unsigned retcode);
08129 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
08130                  _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter);
08131 void             _txWatchdogTerminator       (void* timeout);  // Only Arnold-type series are supported, not T1000
08132 
08133 long WINAPI      _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc);
08134 long WINAPI      _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc);
08135 long             _txOnExceptionSEH           (EXCEPTION_POINTERS* exc, const char func[]);
08136 intptr_t         _txDumpExceptionSEH         (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]);
08137 intptr_t         _txDumpExceptionObj         (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type);
08138 intptr_t         _txDumpExceptionCPP         (char what[], intptr_t size, unsigned code = 0,
08139                                               unsigned params = 0, const ULONG_PTR info[] = NULL);
08140 
08141 void             _txStackBackTrace           (const char file[] = "?", int line = 0, const char func[] = "?",
08142                                               bool readSource = true);
08143 const char*      _txCaptureStackBackTrace    (int framesToSkip = 0, bool readSource = true,
08144                                               CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread());
08145 int              _txStackWalk                (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL,
08146                                               HANDLE thread = GetCurrentThread());
08147 const char*      _txCaptureStackBackTraceTX  (int framesToSkip = 0, bool readSource = false);
08148 
08149 const char*      _txSymPrintFromAddr         (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2);
08150 bool             _txSymGetFromAddr           (void* addr, Win32::SYMBOL_INFO** symbol = NULL,
08151                                               Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL,
08152                                               const char** source = NULL, int context = 2);
08153 intptr_t         _txReadSource               (char buf[], intptr_t size, const char file[],
08154                                               int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN);
08155 bool             _txCreateMiniDump           (EXCEPTION_POINTERS* exc = NULL);
08156 
08157 uintptr_t        _txSetProcAddress           (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL,
08158                                               int useHotPatching = false, HMODULE module = NULL, bool debug = false);
08159 bool             _txInDll() tx_nodiscard;
08160 PROCESSENTRY32*  _txFindProcess              (unsigned pid = GetCurrentProcessId()) tx_nodiscard;
08161 bool             _txKillProcess              (DWORD pid);
08162 int              _txTaskKill                 (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/);
08163 bool             _txCheckSourceCP            (int needCP = _TX_CODEPAGE, bool verbose = true);
08164 bool             _txGetCommandLine           (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid());
08165 IMAGE_NT_HEADERS*_txGetNtHeaders             (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard;
08166 bool             _txIsConsoleSubsystem();
08167 const char*      _txAppInfo() tx_nodiscard;
08168 
08169 #if defined (_CLANG_VER) && !defined (_MSC_VER)
08170 void             _txLibCppDebugFunction      (std::__libcpp_debug_info const& info);
08171 #endif
08172 
08173 #endif // TX_COMPILED
08174 
08175 inline bool      _txCanvas_OK                () tx_nodiscard;
08176 int              _txCanvas_SetRefreshLock    (int count);
08177 
08178 const char*      _txError                    (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0,
08179                                               const char msg[] = NULL, ...) tx_printfy (5);
08180 
08181 bool             _txIsBadReadPtr             (const void* address);
08182 
08183 intptr_t         _tx_snprintf_s              (char stream[], intptr_t size, const char format[], ...) tx_printfy (3);
08184 intptr_t         _tx_vsnprintf_s             (char stream[], intptr_t size, const char format[], va_list arg);
08185 bool             _txIsTTY                    (int fd);
08186 void              txReopenStdio();
08187 
08188 #if defined (__CYGWIN__)
08189 
08190 int              _getch();
08191 int              _putch (int ch);
08192 int              _kbhit() tx_nodiscard;
08193 
08194 #endif
08195 
08196 //-----------------------------------------------------------------------------------------------------------------
08197 // There are macros for __FILE__ and __LINE__ to work properly.
08198 
08199 #if !defined (NDEBUG)
08200 
08201     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08202                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) && \
08203                                                      (assert (cond), true) )
08204 
08205     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08206                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) && \
08207                                                      (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) )
08208 
08209     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                                                            \
08210                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) &&                                     \
08211                                                      (TX_ERROR ("\a" "Параметр \"%s\" неверен."                                           \
08212                                                                                    " Возможно, этот холст не создан, или уже уничтожен, " \
08213                                                                                     "или не загрузилась картинка.", #dc), 1) )
08214     #define _TX_DEFAULT_HDC_FAILED( dc )       ( !(dc) &&                                                                                 \
08215                                                      (TX_ERROR ("\a" "%s"                                                                 \
08216                                                                      "Если вы указали параметр \"%s\", то он неверен.%s",                 \
08217                                                                      (!txWindow()? "Окно рисования не создано или не в порядке.\n" : ""), \
08218                                                                      #dc,                                                                 \
08219                                                                      ( txWindow()? " Возможно, этот холст не создан, или уже уничтожен, " \
08220                                                                                     "или не загрузилась картинка." : "")), 1) )
08221 #else
08222 
08223     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08224                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) )
08225 
08226     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08227                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08228 
08229     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                        \
08230                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08231 
08232     #define _TX_DEFAULT_HDC_FAILED( dc )       ( !(dc) &&                                             \
08233                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08234 #endif
08235 
08236 //-----------------------------------------------------------------------------------------------------------------
08237 // Take action in debug configuration only.
08238 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'(
08239 
08240 #if !defined (NDEBUG)
08241     #define  _TX_ON_DEBUG( code )              { code; }
08242 #else
08243     #define  _TX_ON_DEBUG( code )              ;
08244 #endif
08245 
08246 //-----------------------------------------------------------------------------------------------------------------
08247 // Invokes an error without location information. "$$" restores TX-related call location context
08248 
08249 #define _TX_UNEXPECTED( ... )                  $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__)
08250 
08251 //-----------------------------------------------------------------------------------------------------------------
08252 // Safe call of a function via its pointer
08253 
08254 #define _TX_CALL(  func, param )               ( (func)? ((func) param) :       0 )
08255 #define _TX_CALLv( func, param )               ( (func)? ((func) param) : (void)0 )
08256 
08257 //-----------------------------------------------------------------------------------------------------------------
08258 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x.
08259 
08260 #define _txWaitFor( cond, time )               { for (DWORD _t = GetTickCount() + (time); \
08261                                                       !(cond) && GetTickCount() < _t;     \
08262                                                       Sleep (_txWindowUpdateInterval))    \
08263                                                       ;                                   \
08264                                                                                           \
08265                                                  if  (!(cond))                            \
08266                                                       _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); }
08267 
08268 //-----------------------------------------------------------------------------------------------------------------
08269 // Detouring in case of SEH mechanism
08270 
08271 #define _txSetJmp()                            ( setjmp (_txDumpExceptionObjJmp) == 0 )
08272 
08273 #define _txClearJmp()                          { *(unsigned long long*) _txDumpExceptionObjJmp = 0; }
08274 
08275 //-----------------------------------------------------------------------------------------------------------------
08276 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code.
08277 
08278 #if defined (IN)
08279 //  #undef  IN
08280 #endif
08281 
08282 #if defined (OUT)
08283 //  #undef  OUT
08284 #endif
08285 
08287 //}
08288 //=================================================================================================================
08289 
08290 //=================================================================================================================
08291 //{          Internal global data
08293 //
08294 //           Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :)
08295 //
08296 //           Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же.
08297 //           Здесь это сделано только в образовательных целях.
08298 //
08299 //           Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс.
08300 //=================================================================================================================
08302 
08303 #ifndef TX_COMPILED                                                      // <<<<<<< THE CODE IS HERE, UNFOLD IT <<<
08304 
08305 const int                      _TX_IDM_ABOUT               = 40000,      // Идентификаторы системного меню окна
08306                                _TX_IDM_CONSOLE             = 40001,
08307                                _TX_WM_CREATEWND            = 0x7FF0,     // Сообщения для создания/уничтожения
08308                                _TX_WM_DESTROYWND           = 0x7FF1;     // окон в потоке Canvas
08309 
08310 //-----------------------------------------------------------------------------------------------------------------
08311 
08312 volatile unsigned              _txCanaryFirst              = 0x776F656D; // A very system value
08313 
08314 int                            _txInitialized              = (_TX_NOINIT +0)? 0 : _txInitialize();
08315 
08316 volatile unsigned              _txMainThreadId             = 0;          // ID потока, где выполняется main()
08317 volatile HANDLE                _txMainThread               = NULL;       // Дексриптор этого потока
08318 
08319 volatile unsigned              _txCanvas_ThreadId          = 0;          // ID потока, владеющего окном холста TXLib
08320 volatile HANDLE                _txCanvas_Thread            = NULL;       // Дексриптор этого потока
08321 volatile HWND                  _txCanvas_Window            = NULL;       // Дескриптор окна холста TXLib
08322 
08323 HDC                            _txCanvas_BackBuf[2]        = {NULL,      // [0] Main TXLib in-memory DC, where user's pictures lies
08324                                                               NULL};     // [1] Image ready for auto-refresh, see txCanvas_OnPAINT()
08325 
08326 RGBQUAD*                       _txCanvas_Pixels            = NULL;       // Memory buffer of _txCanvas_BackBuf[0]
08327 
08328 HBITMAP                        _txStockBitmap              = NULL;       // Equivalent of GetStockObject (BITMAP),
08329                                                                          // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313
08330 
08331 CRITICAL_SECTION               _txCanvas_LockBackBuf       = {0,-1};     // Prevent simultaneous access to back buffer, see txLock()
08332 
08333 UINT_PTR                       _txCanvas_RefreshTimer      = 1;          // Timer ID to redraw TXLib window
08334 volatile int                   _txCanvas_RefreshLock       = 0;          // Blocks auto on-timer canvas update, see txBegin/txEnd
08335 
08336 ::std::vector<HDC>*            _txCanvas_UserDCs           = NULL;       // List of DCs allocated, for auto-free
08337 
08338 volatile bool                  _txConsole_IsBlinking       = true;       // To blink or not to blink, that is the question.
08339 
08340 int                            _txConsole                  = false;      // Only first TXLib module in app can own the console
08341 bool                           _txMain                     = false;      // First TXLib wnd opened (closing it terminates program)
08342 bool                           _txIsDll                    = false;      // TXLib module is in DLL
08343 volatile bool                  _txRunning                  = false;      // main() is still running
08344 volatile bool                  _txExit                     = false;      // exit() is active
08345 
08346 volatile POINT                 _txMousePos                 = {-1,-1};    // Ask Captn Obviouos about it. See txCanvas_OnMOUSE()
08347 volatile unsigned              _txMouseButtons             = 0;
08348 
08349 volatile WNDPROC               _txAltWndProc               = NULL;       // Альтернативная оконная функция. См. txSetWindowsHook().
08350 
08351 _tx_thread _txLoc              _txLoc::Cur                 = {};         // Execution point tracking and trace state, see "$" macro
08352 
08353 volatile int                   _txErrors                   = 0;          // TX_ERROR calls sequential number
08354 volatile int                   _txOGLError                 = 0;          // Last OpenGL error when using tx_glGetError()
08355 volatile long                  _txSENumber                 = 0;          // SEH exceptions sequential number
08356 volatile long                  _txSEFatalNumber            = 0;          // SEH fatal exceptions sequential number
08357 char                           _txDumpSE [_TX_BUFSIZE]     = "";         // SEH dump data area
08358 char                           _txTraceSE[_TX_HUGEBUFSIZE] = "";         // Stack trace data area
08359 
08360 LPTOP_LEVEL_EXCEPTION_FILTER   _txPrevUEFilter             = NULL;       // Previous UnhandledExceptionFilter
08361 
08362 jmp_buf                        _txDumpExceptionObjJmp      = {};         // Hook for _txDumpExceptionObj
08363 
08364 const volatile uintptr_t       _txForceImport[]            = { (uintptr_t) ::TerminateProcess,              (uintptr_t) ::ExitProcess,
08365                                                                (uintptr_t) ::FatalExit,                     (uintptr_t) ::FatalAppExitA,
08366                                                                (uintptr_t) ::exit,                          (uintptr_t) Win32::_controlfp,
08367                                                                (uintptr_t) Win32::Polyline,                 (uintptr_t) Win32::PolyBezier,
08368                                                                (uintptr_t) Win32::RoundRect,                (uintptr_t) Win32::RemoveVectoredExceptionHandler,
08369                                                                (uintptr_t) Win32::PlgBlt,                   (uintptr_t) Win32::RtlCaptureStackBackTrace,
08370                                                                (uintptr_t) Win32::SymInitialize,            (uintptr_t) Win32::MinGW::SymInitialize,
08371                                                                (uintptr_t) Win32::SymSetOptions,            (uintptr_t) Win32::MinGW::SymSetOptions,
08372                                                                (uintptr_t) Win32::SymGetLineFromAddr64,     (uintptr_t) Win32::MinGW::SymGetLineFromAddr64,
08373                                                                (uintptr_t) Win32::SymFromAddr,              (uintptr_t) Win32::MinGW::SymFromAddr,
08374                                                                (uintptr_t) Win32::SymCleanup,               (uintptr_t) Win32::MinGW::SymCleanup,
08375                                                                (uintptr_t) Win32::SymGetModuleBase64,       (uintptr_t) Win32::MinGW::SymGetModuleBase64,
08376                                                                (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64,
08377                                                                (uintptr_t) Win32::StackWalk64,              (uintptr_t) Win32::MinGW::StackWalk64,
08378                                                                (uintptr_t) Win32::StrStrIA,                 (uintptr_t) Win32::Wow64GetThreadContext };
08379 
08380 volatile unsigned              _txCanaryLast               = 0x5E2E2E5E; // Another very system value
08381 
08382 #endif // TX_COMPILED
08383 
08384 //-----------------------------------------------------------------------------------------------------------------
08385 
08386 extern volatile unsigned _txCanaryFirst;
08387 extern volatile unsigned _txCanaryLast;
08388 extern volatile HWND     _txCanvas_Window;
08389 extern volatile unsigned _txCanvas_ThreadId;
08390 extern          HDC      _txCanvas_BackBuf[2];
08391 extern          RGBQUAD* _txCanvas_Pixels;
08392 extern volatile int      _txCanvas_RefreshLock;
08393 extern volatile WNDPROC  _txAltWndProc;
08394 extern volatile bool     _txExit;
08395 extern volatile int      _txOGLError;
08396 
08398 //}
08399 //=================================================================================================================
08400 
08401 //=================================================================================================================
08402 //{          TXLib engine init/check/cleanup
08404 //=================================================================================================================
08406 
08407 //-----------------------------------------------------------------------------------------------------------------
08408 //{          Early initialization
08409 //-----------------------------------------------------------------------------------------------------------------
08410 
08411 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08412 
08413 int _txInitialize()
08414     {
08415     if (_txInitialized) return 1;
08416     _txInitialized = 1;
08417 
08418     #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER)  // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx
08419     _CrtSetBreakAlloc (_TX_ALLOC_BREAK);                 // and http://support.microsoft.com/ru-ru/kb/151585
08420     #endif
08421 
08422     #if defined (_TX_ALLOW_TRACE)
08423     _txLocLvlSet (1);
08424     #endif
08425 
08426     _TX_ON_DEBUG (OutputDebugString ("\n");
08427                   OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" "
08428                                      "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n");
08429                   OutputDebugString ("\n"));
08430 
08431     _txMainThreadId = GetCurrentThreadId();
08432     _txMainThread   = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId);
08433 
08434 $3  _txIsDll = _txInDll();
08435 
08436 $   if (!_txIsDll)
08437         {
08438 $       _txConsole = ! FindAtom ("_txConsole");
08439 $       (void)          AddAtom ("_txConsole");  //-V530
08440         }
08441 
08442 $   if (_txConsole)
08443         {
08444 $       _txCheckSourceCP (_TX_CODEPAGE, true);
08445 
08446 $       unsigned long stackSize = _TX_STACKSIZE;
08447 $       _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
08448 
08449 $       _txOnSignal();
08450 
08451 $       if (!*_txLogName)
08452             {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); }
08453 
08454 $       if (!_txIsDll)
08455             {
08456 $           _TX_CALL  (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER)  _txVectoredExceptionHandler));
08457 $           _txPrevUEFilter = SetUnhandledExceptionFilter  (   (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter);
08458             }
08459 
08460 $       ::std::set_terminate             (_txOnTerminate);
08461 $       ::std::set_new_handler           (_txOnNewHandlerAnsi);
08462 $       _TX_CALL (Win32::set_unexpected, (_txOnUnexpected));
08463 
08464         #if defined (_CLANG_VER) && !defined (_MSC_VER)
08465 $       ::std::__libcpp_debug_function = _txLibCppDebugFunction;
08466         #endif
08467 
08468 $       SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true);
08469 
08470 $       SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
08471 
08472         #if defined (_MSC_VER)
08473 
08474 $       _set_printf_count_output (1);
08475 
08476 $       _set_new_handler (_txOnNewHandler);
08477 $       _set_new_mode (1);
08478 
08479         #if !defined (_CLANG_VER)
08480 
08481 $       _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
08482 $       _CrtSetAllocHook (_txOnAllocHook);
08483 
08484 $       unsigned mode = _CRTDBG_MODE_FILE;
08485 $       if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0;
08486 
08487 $       _CrtSetReportMode (_CRT_WARN,   _CRTDBG_MODE_DEBUG | mode);
08488 $       _CrtSetReportMode (_CRT_ERROR,  _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08489 $       _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08490 $       _CrtSetReportFile (_CRT_WARN,   _CRTDBG_FILE_STDERR);
08491 $       _CrtSetReportFile (_CRT_ERROR,  _CRTDBG_FILE_STDERR);
08492 $       _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
08493 
08494         #endif
08495 
08496 $       _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG);
08497 $       _set_abort_behavior (0,                _CALL_REPORTFAULT);
08498 
08499 $       _RTC_SetErrorFunc              (_txOnRTCFailure);
08500 $       _set_purecall_handler          (_txOnPureCall);
08501 $       _set_invalid_parameter_handler (_txOnInvalidParam);
08502 
08503         #endif
08504 
08505         #if defined (__STDC_LIB_EXT1__)
08506 $       ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi);
08507         #endif
08508 
08509         #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386)
08510 $       __setusermatherr (_txOnMatherr);
08511         #endif
08512 
08513         #if !defined (__CYGWIN__)
08514 $       _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR);
08515         #endif
08516 
08517 $       HWND console = _txConsole_Attach();
08518 $       SetWindowTextA (console, txGetModuleFileName (false));
08519         }
08520 
08521 $   _txSetProcAddress ("ExitProcess",                 (uintptr_t) _txOnExitProcess,                 "KERNEL32.DLL");
08522 $   _txSetProcAddress ("TerminateProcess",            (uintptr_t) _txOnTerminateProcess,            "KERNEL32.DLL");
08523 $   _txSetProcAddress ("FatalExit",                   (uintptr_t) _txOnFatalExit,                   "KERNEL32.DLL");
08524 $   _txSetProcAddress ("FatalAppExitA",               (uintptr_t) _txOnFatalAppExitA,               "KERNEL32.DLL");
08525 $   _txSetProcAddress ("UnhandledExceptionFilter",    (uintptr_t) _txUnhandledExceptionFilter,      "KERNEL32.DLL", true);  //-V601
08526 $   _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL");
08527 $   _txSetProcAddress ("exit",                        (uintptr_t) _txOnExit);
08528 $   _txSetProcAddress ("_cexit",                      (uintptr_t) _txOnCExit);
08529 
08530 $   InitializeCriticalSection (&_txCanvas_LockBackBuf);
08531 
08532 $   HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted;
08533 $   _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted;
08534 $   Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted;
08535 $   Win32::DeleteDC (dc) asserted;
08536 
08537 $   atexit (_txCleanup);
08538 
08539 $   if (_txConsole)
08540         {
08541 $       txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
08542 
08543 $       tx_fpreset();
08544 
08545 $       srand ((unsigned) time (NULL));  //-V202
08546 
08547 $       SetLastError (0);
08548 $       errno = 0;
08549 
08550         #if !defined (__CYGWIN__)
08551 $       _doserrno = 0;
08552         #endif
08553         }
08554 
08555 $   Win32::CoCreateInstance = Win32::CoCreateInstance;  // g++ 5.1.0 bug, false warning "defined but not used"
08556 
08557 $   return 1;
08558     }
08559 
08560 //-----------------------------------------------------------------------------------------------------------------
08561 
08562 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/)
08563     {
08564 $3  const char* sCodePage = NULL;
08565 $   int codePage = 0;
08566 
08567 $   switch (((unsigned const char*) "А") [0])
08568         {
08569         case 192: {$ codePage =  1251; sCodePage = "1251.";          break; }
08570         case 208: {$ codePage = 65001; sCodePage = "UTF-8.";         break; }
08571         case 128: {$ codePage =   866; sCodePage = "866.";           break; }
08572         case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; }
08573         default:  {$ codePage =    -1; sCodePage = "(Unknown)";      break; }
08574         }
08575 
08576 $   if (codePage != needCP && verbose)
08577         {
08578 $       *_txTraceSE = ' ';  // No stack trace please
08579 
08580 $       _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n"
08581                         "This is NOT an error of TXLib itself. Please note:\n\n"
08582                         "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your "
08583                         "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO "
08584                         "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. "
08585                         "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n"
08586                         "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n"
08587                         "You can continue, but Russian messages and symbols may appear unreadable.",
08588                         sCodePage, needCP, needCP);
08589         }
08590 
08591 $   return (codePage == needCP);
08592     }
08593 
08594 //-----------------------------------------------------------------------------------------------------------------
08595 
08596 #ifdef _TX_DEBUG_LOAD
08597 
08598 HMODULE _txLoadLibrary_ (const char* dll, int line);
08599 HMODULE _txLoadLibrary_ (const char* dll, int line)
08600     {
08601     txOutputDebugPrintf (_TX_DEBUG_LOAD "[" __FILE__ ":%04d] Loading \"%s\"... ", line, dll);
08602 
08603     SetLastError (0);
08604     HMODULE lib = LoadLibrary (dll);
08605 
08606     if (lib) txOutputDebugPrintf (_TX_DEBUG_LOAD "SUCSESS [%p]\n", (void*) lib);
08607     else     txOutputDebugPrintf (_TX_DEBUG_LOAD "error %lu\n", GetLastError());
08608 
08609     return lib;
08610     }
08611 
08612 #define LoadLibraryA(dll) _txLoadLibrary_ (dll, __LINE__)
08613 
08614 #endif
08615 
08616 //-----------------------------------------------------------------------------------------------------------------
08617 
08618 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) ()
08619     {
08620     if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL;
08621     if (_TX_ARGUMENT_FAILED (funcName    && *funcName))    return NULL;
08622 
08623     static char dllPaths [4][MAX_PATH] = {};
08624 
08625     if (!*dllPaths[0])
08626         {
08627         const  char dllDir[] = "\\Windows\\";
08628         char*  path = NULL;
08629         size_t sz   = 0;
08630 
08631         // The dllPaths[0] is a directory where executable file is located
08632 
08633         path = dllPaths[0];
08634 
08635         sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0;
08636         if (char* dir = strrchr (path, '\\')) dir[1] = 0;
08637 
08638         // The dllPaths[1] is relative to directory where executable file is located
08639 
08640         path = dllPaths[1];
08641 
08642         sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0;
08643         if (char* dir = strrchr (path, '\\')) dir[0] = 0;
08644 
08645         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08646 
08647         // The dllPaths[2] is relative to TXib.h file used in compilation
08648 
08649         path = dllPaths[2];
08650 
08651         if (strchr (__FILE__, ':'))
08652             {
08653             strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1);
08654             }
08655         else
08656             {
08657             // No way to get include path at compile time using simple call "gcc file.cpp"
08658 
08659             sz = GetCurrentDirectory (MAX_PATH, path); path[sz] = 0;
08660             if (*path) strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1);
08661             }
08662 
08663         if (char* dir = strrchr (path, '\\')) *dir = 0;
08664 
08665         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08666 
08667         // The dllPaths[3] is relative to the TX Setup directory stored in the Registry
08668 
08669         path = dllPaths[3];
08670 
08671         txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH);
08672         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08673         }
08674 
08675     char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = "";
08676     const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL);  //-V547
08677 
08678     if (arch)
08679         {
08680         assert (arch >= dllFileName);  //-V547
08681 
08682         strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName));
08683         strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName));
08684 
08685         strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName));
08686         strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3);
08687         strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch));
08688         }
08689     else if (dllFileName)  //-V547 //-V2516
08690         {
08691         strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1);
08692         }
08693 
08694     HMODULE   dll = GetModuleHandle (dllFileName);
08695 
08696     if (!dll) dll = GetModuleHandle (dllArch);
08697     if (!dll) dll = GetModuleHandle (dllName);
08698 
08699     for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++)
08700         {
08701         if (!dllPaths[i]) continue;
08702 
08703         char path [MAX_PATH] = "";
08704         strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i]));
08705         size_t len = strlen (path);
08706 
08707         SetDllDirectory (path);
08708 
08709         strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch));
08710         if (!dll && *dllArch) dll = LoadLibrary (path);  //-V547
08711 
08712         strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName));
08713         if (!dll)             dll = LoadLibrary (path);
08714         }
08715 
08716     SetDllDirectory (NULL);
08717 
08718     if (!dll && *dllArch) dll = LoadLibrary (dllArch);
08719     if (!dll)             dll = LoadLibrary (dllName);
08720 
08721     if (!dll  && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".",
08722                                            dllName, (arch? "\" / \"" : ""), dllArch);
08723     if (!dll) return NULL;
08724 
08725     void (*addr)() = (void(*)()) GetProcAddress (dll, funcName);
08726 
08727     if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".",
08728                                            funcName, dllName, (arch? "\" / \"" : ""), dllArch);
08729     return addr;
08730     }
08731 
08732 //-----------------------------------------------------------------------------------------------------------------
08733 
08734 #ifdef _TX_DEBUG_LOAD
08735     #undef LoadLibraryA
08736     #endif
08737 
08738 //-----------------------------------------------------------------------------------------------------------------
08739 
08740 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013
08741     #pragma warning (push)
08742     #pragma warning (disable: 6102)          // Использование 'name' из завершившегося ошибкой вызова функции
08743 #endif
08744 
08745 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue)
08746     {
08747     if (_TX_ARGUMENT_FAILED (keyName)) return 0;
08748 
08749     HKEY hive = NULL;
08750 
08751     #define EQU_(name1, name2)  ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \
08752                                   _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 )
08753 
08754     if      (EQU_("HKLM", "HKEY_LOCAL_MACHINE"))  hive = HKEY_LOCAL_MACHINE;
08755     else if (EQU_("HKCU", "HKEY_CURRENT_USER"))   hive = HKEY_CURRENT_USER;
08756     else if (EQU_("HKCR", "HKEY_CLASSES_ROOT"))   hive = HKEY_CLASSES_ROOT;
08757     else if (EQU_("HKU",  "HKEY_USERS"))          hive = HKEY_USERS;
08758     else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG;
08759 
08760     else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; }
08761 
08762     #undef EQU_
08763 
08764     keyName = strchr (keyName, '\\') + 1;  //-V769
08765     assert (keyName > (const char*) 1);
08766 
08767     HKEY  key  = NULL;
08768     DWORD size = 0;
08769 
08770     bool                               ok  = (RegOpenKeyEx    (hive, keyName,   0, KEY_QUERY_VALUE, &key)         == ERROR_SUCCESS);
08771     if (ok)                            ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, NULL,          &size) == ERROR_SUCCESS);
08772     if (ok && value && size < szValue) ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS);  //-V104
08773     if (key)                           ok &= (RegCloseKey     (key)                                               == ERROR_SUCCESS);
08774 
08775     return size;
08776     }
08777 
08778 #if defined (_MSC_VER) && (_MSC_VER == 1800)
08779     #pragma warning (pop)
08780 #endif
08781 
08782 #endif // TX_COMPILED
08783 
08784 //}
08785 //-----------------------------------------------------------------------------------------------------------------
08786 
08787 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08788 
08789 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/)
08790     {
08791 $1  if (!_txInitialized) _txInitialized = _txInitialize();
08792 
08793 $   if (HWND wnd = txWindow())
08794         {
08795 $       SetLastErrorEx (ERROR_INVALID_DATA, 0);
08796 $       _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!"));
08797 $       return wnd;
08798         }
08799 
08800 $   if (!_txIsDll)
08801         {
08802 $       _txMain = ! FindAtom ("_txMain");  // Not a thread-safe
08803 $       (void)       AddAtom ("_txMain");  //-V530
08804         }
08805 
08806 $   if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; }  //-V1048
08807 
08808 $   _txRunning = false;
08809 
08810     // Store the size
08811 
08812 $   static SIZE size = { ROUND (sizeX), ROUND (sizeY) };
08813 $   if (centered) { size.cx *= -1; size.cy *= -1; }
08814 
08815     // In Thread, where REAL creation lies...
08816 
08817 $   unsigned id = 0;
08818 $   _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id);
08819 
08820 $   if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."),  (HWND) NULL;
08821 
08822 $   _txWaitFor (_txRunning, 10*_TX_TIMEOUT);
08823 
08824 $   if (!_txRunning)       return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL;
08825 $   if (!txOK())           return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."),     (HWND) NULL;
08826 
08827 $   HWND console = Win32::GetConsoleWindow();
08828 
08829 $   DWORD proc = 0;
08830 $   GetWindowThreadProcessId (console, &proc);
08831 
08832 $   if (console && (proc == GetCurrentProcessId() || _txIsParentWaitable()))
08833         {$ ShowWindow (console, TX_CONSOLE_MODE); }
08834 
08835 $   HMENU menu = GetSystemMenu (txWindow(), false);
08836     if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); }
08837 
08838 $   Win32::GdiSetBatchLimit (1);
08839 
08840 $   SetLastError (0);
08841 
08842 $   errno = 0;
08843 
08844     #if !defined (__CYGWIN__)
08845 $   _doserrno = 0;
08846     #endif
08847 
08848 $   return txWindow();
08849     }
08850 
08851 //-----------------------------------------------------------------------------------------------------------------
08852 
08853 HWND txCreateExtraWindow (CREATESTRUCT createData)
08854     {
08855 $1  if (_TX_TXWINDOW_FAILED()) return NULL;
08856 
08857 $   volatile HWND wnd = NULL;
08858 $   createData.hInstance = (HINSTANCE)(uintptr_t) &wnd;
08859 
08860 $   PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted;
08861 
08862 $   _txWaitFor (wnd, 5*_TX_TIMEOUT);
08863 
08864 $   return wnd;
08865     }
08866 
08867 //-----------------------------------------------------------------------------------------------------------------
08868 
08869 bool txSetDefaults (HDC dc /*= txDC()*/)
08870     {
08871 $1  if (dc == txDC()) txUpdateWindow (false);  //-V601
08872 $   txAutoLock _lock;
08873 
08874 $   RECT r = {};
08875 $   GetClientRect (Win32::GetConsoleWindow(), &r);
08876 $   SIZE szCon = { r.right - r.left, r.bottom - r.top };
08877 
08878 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
08879 
08880 $   CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}};
08881 $   GetConsoleScreenBufferInfo (out, &con);
08882 
08883 $   SIZE szTxt = { (short) (con.srWindow.Right  - con.srWindow.Left + 1),
08884                    (short) (con.srWindow.Bottom - con.srWindow.Top  + 1) };
08885 
08886 //{ Set defaults for graphics layer
08887 
08888 $   _txBuffer_Select (Win32::GetStockObject (WHITE_PEN),   dc) asserted;
08889 $   _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted;
08890 
08891 $   _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx,
08892                                          0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
08893                                          RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
08894                                          DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT),
08895                       dc) asserted;
08896 
08897 $  (Win32::SetTextColor      (dc, TX_WHITE) != CLR_INVALID) asserted;
08898 $   Win32::SetBkMode         (dc, TRANSPARENT)              asserted;
08899 
08900 $   Win32::SetROP2           (dc, R2_COPYPEN)               asserted;
08901 $   Win32::SetStretchBltMode (dc, HALFTONE)                 asserted;
08902 
08903 //}
08904 
08905 $   if (dc != txDC())
08906         {$ return true; }
08907 
08908 //{ Set defaults for console  layer
08909 
08910 $   POINT szCanvas = txGetExtent (dc);
08911 
08912 $   HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)?
08913                        Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx,
08914                                           0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
08915                                           RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
08916                                           DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT)
08917                        :
08918                        Win32::GetStockObject (SYSTEM_FIXED_FONT);
08919 
08920 $   _txBuffer_Select (font, _txCanvas_BackBuf[1]);
08921 //}
08922 
08923 //{ Scroll the console for text to go above top of window and don't mix with graphics
08924 
08925 $   if (con.dwCursorPosition.X) _putch ('\n');
08926 
08927 $   short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top);
08928 
08929 $   con.srWindow.Top    = (short) (con.srWindow.Top    + delta);
08930 $   con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta);
08931 
08932 $   SMALL_RECT src  = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) };
08933 $   CHAR_INFO  fill = { {' '}, FOREGROUND_LIGHTGRAY };
08934 $   COORD      dest = { 0, (short) -delta };  // New UL-corner of src, scroll up
08935 
08936 $   con.dwCursorPosition.X = 0;
08937 $   con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta);
08938 
08939 $   (con.srWindow.Bottom < con.dwSize.Y &&                        // Move the "window"
08940      SetConsoleWindowInfo      (out, true, &con.srWindow))
08941     ||
08942     (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill),    // Or scroll the buffer
08943      SetConsoleCursorPosition  (out, con.dwCursorPosition));
08944 //}
08945 
08946 $   txUpdateWindow (true);  //-V601
08947 
08948     return true;
08949     }
08950 
08951 #endif // TX_COMPILED
08952 
08953 //-----------------------------------------------------------------------------------------------------------------
08954 
08955 inline bool txOK()
08956     {
08957     return (_txCanaryFirst == 0x776F656D &&  // Too well-known values to use constants. You know these values, don't you?
08958             _txCanaryLast  == 0x5E2E2E5E &&
08959             _txCanvas_OK()
08960 
08961     #if defined (_MSC_VER)
08962          && _CrtCheckMemory()
08963     #endif
08964             );
08965     }
08966 
08967 //-----------------------------------------------------------------------------------------------------------------
08968 //{          Cleanup
08969 //-----------------------------------------------------------------------------------------------------------------
08970 
08971 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08972 
08973 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain.
08974 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols
08975 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize().
08976 
08977 void _txOnCExit()
08978     {
08979     OutputDebugString ("\n");
08980 
08981 $5  _txCleanup();
08982 
08983     _TX_CALLv (Win32::_cexit, ());
08984     }
08985 
08986 //-----------------------------------------------------------------------------------------------------------------
08987 
08988 void _txOnExit (int retcode)
08989     {
08990     if (retcode != 0)
08991         {
08992         OutputDebugString ("\n");
08993         txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode);
08994         }
08995 
08996 $5  _txCleanup();
08997 
08998     if (retcode != 0)
08999         txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode);
09000 
09001     Win32::exit (retcode);
09002     }
09003 
09004 //-----------------------------------------------------------------------------------------------------------------
09005 
09006 void _txOnExitProcess (unsigned retcode)
09007     {
09008     if (retcode != 0)
09009         {
09010         OutputDebugString ("\n");
09011         txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode);
09012         }
09013 
09014 $5  _txCleanup();
09015 
09016     if (retcode != 0)
09017         txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode);
09018 
09019     Win32::ExitProcess (retcode);
09020     }
09021 
09022 //-----------------------------------------------------------------------------------------------------------------
09023 
09024 bool _txOnTerminateProcess (HANDLE process, unsigned retcode)
09025     {
09026     if (retcode != 0)
09027         {
09028         OutputDebugString ("\n");
09029         txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode);
09030         }
09031 
09032 $5  _txCleanup();
09033 
09034     if (retcode != 0)
09035         txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode);
09036 
09037     return Win32::TerminateProcess (process, retcode);
09038     }
09039 
09040 //-----------------------------------------------------------------------------------------------------------------
09041 
09042 void _txOnFatalExit (int retcode)
09043     {
09044     OutputDebugString ("\n");
09045     txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode);
09046 
09047 $5  _txCleanup();
09048 
09049     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode);
09050     _TX_CALLv (Win32::FatalExit, (retcode));
09051 
09052     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode);
09053     Win32::TerminateProcess (GetCurrentProcess(), retcode);
09054     }
09055 
09056 //-----------------------------------------------------------------------------------------------------------------
09057 
09058 void _txOnFatalAppExitA (unsigned action, const char message[])
09059     {
09060     OutputDebugString ("\n");
09061     txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message);
09062 
09063 $5  _txCleanup();
09064 
09065     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message);
09066     _TX_CALLv (Win32::FatalAppExitA, (action, message));
09067 
09068     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION);
09069     Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09070     }
09071 
09072 //-----------------------------------------------------------------------------------------------------------------
09073 
09074 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type)
09075     {
09076     OutputDebugString ("\n");
09077     txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type);
09078 
09079 $5  switch (type)
09080         {
09081         case CTRL_LOGOFF_EVENT:
09082         case CTRL_SHUTDOWN_EVENT: $ _txExit = true;
09083                                   $ _txCleanup();
09084         case CTRL_C_EVENT:
09085         case CTRL_CLOSE_EVENT:
09086         case CTRL_BREAK_EVENT:
09087 
09088         default:                  break;  //-V2522
09089         }
09090 
09091 $   return false;
09092     }
09093 
09094 //-----------------------------------------------------------------------------------------------------------------
09095 
09096 void _txCleanup()
09097     {
09098     if (!_txInitialized) return;
09099     else _txInitialized = false;  //-V601
09100 
09101 $3  _txRunning = false;
09102 $   _txConsole_IsBlinking = false;
09103 
09104 $   txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR);
09105 
09106 $   txSetWindowsHook (NULL);
09107 
09108 $   HWND     canvas  = txWindow();
09109 $   HWND     console = Win32::GetConsoleWindow();
09110 $   unsigned thread  = GetCurrentThreadId();
09111 
09112 $   HWND wnd         = (canvas)? canvas : console;
09113 
09114 $   bool externTerm  = (thread != _txMainThreadId &&
09115                         thread != _txCanvas_ThreadId);
09116 
09117 $   DWORD list[1] = {};
09118 $   DWORD ownsConsole = (GetConsoleProcessList (list, 1) <= 1);
09119 
09120 $   int    envPause       = -1;
09121 $   char   envPause_s[10] = "";
09122 $   size_t envPause_sz    = 0;
09123 $   getenv_s (&envPause_sz, envPause_s, sizeof (envPause_s) - 1, "TX_PAUSE");
09124 
09125     if (strcmp (envPause_s, "1") == 0 || _stricmp (envPause_s, "ON")  == 0) {$ envPause = 1; }
09126     if (strcmp (envPause_s, "0") == 0 || _stricmp (envPause_s, "OFF") == 0) {$ envPause = 0; }
09127 
09128 $   DWORD parent = 0;
09129 $   int  isParentWaitable = _txIsParentWaitable (&parent);
09130 
09131 $   if (canvas)
09132         {$ txSleep (5*_txWindowUpdateInterval); }
09133 
09134 $   if (_txConsole)
09135         {
09136 $       if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
09137 
09138 $       if (console)
09139             {
09140 $           EnableWindow     (console, true);
09141 $           _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */);
09142             }
09143         }
09144 
09145 $   if (_txMain && !externTerm && canvas)
09146         {$  _txSetWindowText (canvas,  " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); }
09147 
09148 $   std::cout.flush();
09149 $   std::cerr.flush();
09150 $   std::clog.flush();
09151 $   _flushall();
09152 
09153 $   bool paused = false;
09154 $   if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId))
09155         {
09156 $       if (wnd)
09157             {
09158 $           if (isParentWaitable >= 0)
09159                 {$ _txActivateWindow (wnd, 0x08); }
09160 
09161 $           EnableWindow (wnd, true);
09162             }
09163 
09164 $       if ((console && (ownsConsole || canvas || _txErrors || envPause == 1)) && isParentWaitable >= 0 && !(envPause == 0))
09165             {
09166 $           txPause ((_txErrors)?               "\f\n" "[Press F to Pay Respects...]" :
09167                      (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f");
09168 
09169 $           paused = true;
09170             }
09171         }
09172 
09173 $   if (_txConsole && _txWatchdogTimeout >= 0)
09174      {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09175 
09176 $   if (txWindow())
09177         {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); }
09178 
09179 $   _txWaitFor (!txWindow(), 5*_TX_TIMEOUT);
09180 
09181 $   txSpeak     (NULL);
09182 $   txPlayVideo (NULL);
09183 
09184 $   delete _txCanvas_UserDCs;
09185 $   _txCanvas_UserDCs = NULL;
09186 
09187 $   if (GetCurrentThreadId() != _txMainThreadId)
09188         {$ SuspendThread (_txMainThread);    }  //-V720
09189 $   if (GetCurrentThreadId() != _txCanvas_ThreadId)
09190         {$ SuspendThread (_txCanvas_Thread); }  //-V720
09191 
09192 $   if (_txMainThread)
09193         {$ CloseHandle (_txMainThread)    asserted; _txMainThread    = NULL; }
09194 $   if (_txCanvas_Thread)
09195         {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; }
09196 
09197 $   if (!txWindow())
09198         {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; }
09199 
09200 $   bool parentKilled = false;
09201 $   if (isParentWaitable && !externTerm && paused && _txNOP (_TX_ALLOW_KILL_PARENT))
09202         {
09203 $       console = Win32::GetConsoleWindow();
09204 
09205 $       if (parent)
09206             {$ parentKilled = _txKillProcess (parent); }
09207 
09208 $       if (parent && !parentKilled)
09209             {
09210 $           PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09211 $           PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09212             }
09213         }
09214 
09215 $   if (_txConsole)
09216         {$ _txSetWindowText (console, NULL); }
09217 
09218 $   if (_txMain && _txConsole)
09219         {$ _txConsole_Detach (isParentWaitable && !externTerm && !parentKilled); }  //-V560
09220 
09221 $   std::cout.flush();
09222 $   std::cerr.flush();
09223 $   std::clog.flush();
09224 $   _flushall();
09225 
09226 $   _txSymGetFromAddr (NULL);
09227 
09228     // That's all, folks
09229 
09230     _TX_ON_DEBUG (OutputDebugString ("\n");
09231                   OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n");
09232                   OutputDebugString ("\n"));
09233     }
09234 
09235 //-----------------------------------------------------------------------------------------------------------------
09236 
09237 int txPause (const char* message /*= NULL*/, ...)
09238     {
09239 $3  bool wine    = !!Win32::wine_get_version;
09240 
09241 $   HWND canvas  = txWindow();
09242 $   HWND console = Win32::GetConsoleWindow();
09243 $   HWND wnd     = (canvas)? canvas : console;
09244 $   bool istty0  = _txIsTTY (0);
09245 
09246 $   int attr     = txGetConsoleAttr();
09247 
09248 $   int oldCP    = GetConsoleOutputCP();
09249 $   SetConsoleOutputCP (_TX_CODEPAGE);
09250 
09251     if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; }
09252 
09253     if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); }
09254     else                  {$ message++; }
09255 
09256     if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); }
09257     else                  {$ message++; }
09258 
09259 $   _txActivateWindow (wnd, 0x08);
09260 
09261 $   va_list args;
09262 $   va_start (args, message);
09263 $   vfprintf (stderr, message, args);
09264 $   txOutputDebugPrintf (message, args);
09265 $   va_end (args);
09266 
09267 $   fflush (stderr);
09268 $   txSleep();
09269 
09270 $   Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF };
09271 $   _TX_CALL (Win32::FlashWindowEx, (&flash));
09272 
09273 $   int ch = EOF;
09274     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09275 
09276 $   for (int i = 1; ; i++)  //-V2530
09277         {
09278 $       Sleep (_txWindowUpdateInterval);
09279 
09280         if (!istty0 && !canvas)                   {$ break; }  // No need to run and hide
09281 
09282         if (!wine && (ch = _txGetInput()) != EOF) {$ break; }  // Somebody hit something.
09283 
09284         if (canvas && !_txCanvas_ThreadId)        {$ break; }  // There was a window, and now there is not.
09285 
09286         if (!Win32::GetConsoleWindow())           {$ break; }  // Console was destroyed
09287 
09288         if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas)))
09289             {$ TX_ERROR ("Похоже, программа зависла :("); break; }
09290 
09291         if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas)))
09292             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; }
09293 
09294         if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL))
09295             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает");  break; }
09296 
09297         if (!wine && !(i % 100500))
09298             {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...]  \b\b"); }
09299         }
09300 
09301     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09302 
09303 $   _txSetWindowText (wnd, NULL);
09304 
09305 $   fprintf (stderr, "\n");
09306 
09307     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09308 
09309 $   SetConsoleOutputCP (oldCP);
09310 $   txSetConsoleAttr (attr);
09311 
09312 $   return ch;
09313     }
09314 
09315 //-----------------------------------------------------------------------------------------------------------------
09316 
09317 int _txGetInput()
09318     {
09319 $4  HANDLE con = GetStdHandle (STD_INPUT_HANDLE);
09320 $   int ch = EOF;
09321 
09322 $   DWORD nChars = 0;
09323 $   if (GetConsoleMode (con, &nChars) == 0 &&
09324         PeekNamedPipe  (con, NULL, 0, NULL, &nChars, NULL))
09325         {
09326 $       ch = (nChars)? fgetc (stdin) : EOF;
09327         }
09328 
09329     else if (_kbhit())
09330         {
09331 $       ch = _getch();
09332         }
09333 
09334 #if defined (_MSC_VER) && (_MSC_VER < 1700)
09335 
09336     else if (fseek (stdin, 1, SEEK_CUR) != EOF)
09337         {
09338 $       (void) fseek (stdin, -1, SEEK_CUR);
09339 $       ch = fgetc (stdin);                                // This causes blocking in MSVC 2011 beta
09340         }
09341 
09342 #endif
09343 
09344     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09345 
09346 $   return ch;
09347     }
09348 
09349 //-----------------------------------------------------------------------------------------------------------------
09350 
09351 bool _txIsTTY (int fd)
09352     {
09353 $4  return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR;
09354     }
09355 
09356 //-----------------------------------------------------------------------------------------------------------------
09357 
09358 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/,
09359                       int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/)
09360     {
09361     struct tools
09362         {
09363         static LRESULT getWindowText (HWND window, wchar_t text[], size_t size)
09364             {
09365 $3          memset (text, 0, size * sizeof (*text));
09366 
09367 $           return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09368             }
09369 
09370         static LRESULT setWindowText (HWND window, wchar_t text[])
09371             {
09372 $1          return SendMessageTimeoutW (window, WM_SETTEXT, 0,             (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09373             }
09374         };
09375 
09376 $1  static wchar_t _tx_thread title    [_TX_BUFSIZE+15] = L"TXLib";
09377 $   static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib";
09378 
09379 $   if (!textRus)
09380         {
09381 $       tools::setWindowText (wnd, oldTitle);
09382 $       return -1;
09383         }
09384 
09385 $   tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09386 $   int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1;
09387 $   memcpy (oldTitle, title, sizeof (oldTitle));
09388 
09389 $   if (textRus)
09390         {
09391 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len);
09392 
09393 $       tools::setWindowText (wnd, title);
09394 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09395         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; }
09396         if (!checkLetters) {$ return -2; }
09397         }
09398 
09399 $   if (textEng)
09400         {
09401 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len);
09402 
09403 $       tools::setWindowText (wnd, title);
09404 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09405         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; }
09406         if (!checkLetters) {$ return -2; }
09407         }
09408 
09409 $   return -3;
09410     }
09411 
09412 //-----------------------------------------------------------------------------------------------------------------
09413 
09414 int _txIsParentWaitable (DWORD* parentPID /*= NULL*/)
09415     {
09416 $4  PROCESSENTRY32* info = _txFindProcess();
09417 $   if (!info) return 0;
09418 
09419 $   info = _txFindProcess (info->th32ParentProcessID);
09420 $   if (!info) return 0;
09421 
09422 $   char parent [MAX_PATH] = "";
09423 $   strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1);
09424 $   if (parentPID) *parentPID = info->th32ProcessID;
09425 
09426 $   info = _txFindProcess (info->th32ParentProcessID);          // info: grandparent
09427 
09428 $   char list[_TX_BUFSIZE] = _TX_WAITABLE_PARENTS;
09429 $   char* ctx = NULL;
09430 
09431 $   for (char* p = strtok_s (list, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx))
09432         {
09433 $       char* gp = strchr (p, ':');
09434 
09435 $       if (gp)
09436             {
09437 $           *gp++ = 0;
09438 
09439 $           if (_stricmp (p, parent) != 0) { continue; }
09440 
09441 $           if (info) if (_stricmp (gp, info->szExeFile) == 0)  // Was &&, but MSVC /analyze is so paranoid
09442                 {$ return islower ((unsigned char) *gp)? +1 : -1; }
09443             }
09444         else
09445             {
09446 $           if (_stricmp (p, parent) == 0)
09447                 {$ return islower ((unsigned char)  *p)? +1 : -1; }
09448             }
09449         }
09450 
09451 $   return 0;
09452     }
09453 
09454 //-----------------------------------------------------------------------------------------------------------------
09455 
09456 void _txWatchdogTerminator (void* timeout)  // Or Watchcat? Possibly will change in future versions
09457     {
09458 $3  if (_TX_ARGUMENT_FAILED (timeout)) return;
09459 
09460 $   Sleep (*(int*) timeout);  //-V206
09461 
09462 $   OutputDebugString ("\n");
09463     txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n",  // Kinda static reflection...
09464                          _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow"));  //-V206
09465 $   DWORD parent = 0;
09466 $   if (_txIsParentWaitable (&parent))
09467         {
09468         txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n",
09469                              _TX_VERSION, __func__, (unsigned long) parent);
09470 
09471 $       _txKillProcess (parent);
09472 
09473 $       HWND console = GetConsoleWindow();
09474 $       PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09475 $       PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09476         }
09477 
09478     txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__);
09479 $   Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09480     }
09481 
09482 #endif // TX_COMPILED
09483 
09484 //}
09485 //-----------------------------------------------------------------------------------------------------------------
09486 
09487 //-----------------------------------------------------------------------------------------------------------------
09488 //{          Tools
09489 //-----------------------------------------------------------------------------------------------------------------
09490 
09491 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09492 
09493 // You are here, little hacker?
09494 
09495 int _txTaskKill (const char i[] /*= NULL*/,
09496                  const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/,
09497                  unsigned   x   /*= 0*/)
09498     {
09499     // ...so tired of it already...
09500 
09501     #define name          i  // Great name!
09502     #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine
09503     #define pid           x  // Another great name, isn't it?
09504 
09505 $3  if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false;  //-V560 //-V601
09506 
09507 $   wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L"";
09508     if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); }
09509 
09510 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09511 $   assert (sshot); if (!sshot) return 0;  //-V547
09512 
09513 $   int killed = 0;
09514 
09515 $   PROCESSENTRY32 info = { sizeof (info) };
09516 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09517         {
09518         bool kill = false;
09519 
09520         if (!kill && pid  && info.th32ParentProcessID        == pid) {$ kill = true; }  //-V560
09521 
09522         if (!kill && name && _stricmp (info.szExeFile, name) == 0)   {$ kill = true; }
09523 
09524         if (!kill)
09525             {
09526             wchar_t cmdLineW[_TX_BUFSIZE] = L"";
09527             if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; }
09528 
09529             if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW))    {$ kill = true; }
09530             }
09531 
09532         if (kill)
09533             {
09534 $           if (_txKillProcess (info.th32ProcessID))
09535                 {$ killed++; }
09536             }
09537         }
09538 
09539 $   CloseHandle (sshot);
09540 
09541 $   return killed;
09542 
09543     #undef name
09544     #undef cmdLine
09545     #undef pid
09546     }
09547 
09548 //-----------------------------------------------------------------------------------------------------------------
09549 
09550 bool _txKillProcess (DWORD pid)
09551     {
09552 $3  if (_TX_ARGUMENT_FAILED (pid)) return false;
09553 
09554 $   HANDLE token = INVALID_HANDLE_VALUE;
09555 $   OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted;
09556 
09557 $   LUID luid = {};
09558 $   LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted;
09559 
09560 $   TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}};
09561 $   TOKEN_PRIVILEGES old  = {};
09562 
09563 $   DWORD oldSz = 0;
09564 $   AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted;
09565 
09566 $   HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid);
09567 $   if (!proc) return false;
09568 
09569 $   bool ok = !!Win32::TerminateProcess (proc, 0);
09570 $   CloseHandle (proc);
09571 
09572 $   return ok;
09573     }
09574 
09575 //-----------------------------------------------------------------------------------------------------------------
09576 
09577 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/)
09578     {
09579 $4  static PROCESSENTRY32 info = { sizeof (info) };
09580 $   if (!pid) return &info;
09581 
09582 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09583 $   assert (sshot); if (!sshot) return NULL;  //-V547
09584 
09585 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09586         if (info.th32ProcessID == pid) break;
09587 
09588 $   CloseHandle (sshot);
09589 
09590 $   return &info;
09591     }
09592 
09593 //-----------------------------------------------------------------------------------------------------------------
09594 
09595 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/)
09596     {
09597 $6  if (_TX_ARGUMENT_FAILED (cmdLine))        return false;
09598 $   if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false;  //-V547
09599 
09600 $   if (pid == (unsigned) _getpid())
09601         {
09602 $       wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1);
09603 $       return true;
09604         }
09605 
09606 $   HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
09607     if (!proc) {$ return false; }
09608 
09609 $   Win32::PROCESS_BASIC_INFORMATION pbi = {};
09610 $   bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0);
09611 
09612     // Should use ReadProcessMemory() because the info is actually in another address space
09613 
09614 $   Win32::PEB peb = {};
09615     if (ok && pbi.PebBaseAddress)        {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress,        &peb,    sizeof (peb),    NULL); }
09616 
09617 $   Win32::RTL_USER_PROCESS_PARAMETERS params = {};
09618     if (ok && peb.ProcessParameters)     {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters,     &params, sizeof (params), NULL); }
09619 
09620 $   *cmdLine = 0;
09621     if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine,  //-V106
09622                                                                        MIN  (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2),  //-V202
09623                                                                        NULL); }
09624 $   CloseHandle (proc) asserted;
09625 
09626 $   return ok;
09627     }
09628 
09629 //-----------------------------------------------------------------------------------------------------------------
09630 
09631 #define RVA_(type, module, addr)  ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) )
09632 
09633 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/)
09634     {
09635 $4  assert (module);
09636 
09637 $   IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0);
09638 $   IMAGE_NT_HEADERS* ntHdr  = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew);
09639 
09640 $   return (dosHdr->e_magic  == IMAGE_DOS_SIGNATURE &&
09641             ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL;
09642     }
09643 
09644 //-----------------------------------------------------------------------------------------------------------------
09645 
09646 // TXLib continues to hack the reality to make your life better, sweeter and easier
09647 
09648 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/,
09649                              HMODULE module /*= NULL*/, bool debug /*= false*/)
09650     {
09651 $4  if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module);
09652 
09653 $   if (_TX_ARGUMENT_FAILED (funcName)) return 0;
09654 $   if (_TX_ARGUMENT_FAILED (newFunc))  return 0;
09655 
09656 $   if (!module) module = GetModuleHandle (NULL);
09657 $   if (!module) return 0;
09658 
09659 $   HMODULE dll     = (dllName)? GetModuleHandle (dllName)       : NULL;
09660 $   PROC    oldFunc = (dll)?     GetProcAddress  (dll, funcName) : NULL;
09661 
09662 $   if (useHotPatching && oldFunc)
09663         {
09664 $       const size_t jmpSz = 1 + sizeof (DWORD);  // sizeof (JMP rel instruction)
09665 
09666 $       DWORD oldRights = 0;
09667 $       if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0;
09668 
09669         // Overwrite oldFunc prolog with JMP trampoline to newFunc.
09670         // Calling oldFunc from any location will lead to newFunc call anyway.
09671 
09672 $       *(BYTE*)  ((char*)(uintptr_t) oldFunc + 0) = 0xE9;  // JMP rel
09673 $       *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF;  //-V206 //-V112 //-V2007 //-V104 //-V103
09674 
09675 $       FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz);
09676 
09677 $       VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights);
09678 
09679 $       return (uintptr_t) oldFunc;
09680         }
09681 
09682 //  For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255
09683 //  and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html.
09684 
09685 $   IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module);
09686     if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; }
09687 
09688 $   DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
09689 $   IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset);
09690 
09691 $   if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0;  //-V1027
09692 
09693 $   IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL;
09694 $   char*  impDll  = NULL;
09695 $   char*  impName = NULL;
09696 $   void** impPtr  = NULL;
09697 $   bool   found   = false;
09698 
09699     for (; desc->Name; desc++)
09700         {
09701 $       impDll = RVA_ (char*, module, desc->Name);
09702 $       if (dllName && _stricmp (impDll, dllName) != 0) continue;
09703 
09704 $       for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk),
09705              thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk);
09706 
09707              thunk0 && thunk1 && thunk1->u1.Function;
09708 
09709              thunk0++,
09710              thunk1++)
09711             {
09712             impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name;
09713             impPtr  = (void**)(uintptr_t)                         &thunk1->u1.Function;  // Should change it, so this is ptr
09714 
09715             if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL;
09716 
09717             if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName);
09718 
09719             if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) ||
09720                 (impName && _stricmp (funcName, impName) == 0))  //-V560
09721                 {
09722                 found = true;
09723                 break;
09724                 }
09725             }
09726 
09727 $       if (found) break;
09728         }
09729 
09730     if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n",
09731                                     funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found"));
09732 $   if (!found) return 0;
09733 
09734 $   DWORD rights = PAGE_READWRITE;
09735 $   if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0;
09736 
09737 $   *(uintptr_t*) impPtr = newFunc;
09738 
09739 $   VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights);
09740 
09741 $   return (uintptr_t) oldFunc;
09742     }
09743 
09744 #undef RVA_
09745 
09746 //-----------------------------------------------------------------------------------------------------------------
09747 
09748 bool _txInDll()
09749     {
09750 $4  MODULEENTRY32 mod = { sizeof (mod) };
09751 
09752 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
09753 $   assert (sshot); if (!sshot) return false;  //-V547
09754 
09755 $   bool inDll = false;
09756 
09757 $   for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod))
09758         {
09759 $       if (!mod.modBaseAddr) continue;
09760 
09761 $       IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr);
09762 
09763 $       inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0);
09764 
09765 $       if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize))  //-V104
09766             {$ break; }
09767         }
09768 
09769 $   CloseHandle (sshot);
09770 $   return inDll;
09771     }
09772 
09773 //-----------------------------------------------------------------------------------------------------------------
09774 
09775 bool _txIsConsoleSubsystem()
09776     {
09777 $4  IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders();
09778 
09779 $   return  ntHdr &&
09780             ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC &&
09781 
09782            (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI ||
09783             ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI);
09784     }
09785 
09786 //-----------------------------------------------------------------------------------------------------------------
09787 
09788 bool _txIsBadReadPtr (const void* address)
09789     {
09790     MEMORY_BASIC_INFORMATION mbi = {};
09791     if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true;
09792 
09793     if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS))  return true;  // Guard page -> bad ptr
09794 
09795     DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
09796 
09797     return !(mbi.Protect & readRights);
09798     }
09799 
09800 //-----------------------------------------------------------------------------------------------------------------
09801 
09802 void _txActivateWindow (HWND wnd, unsigned mode)
09803     {
09804 $1  EnableWindow (wnd, true);
09805 
09806 $   if (mode & 0x10)
09807         {
09808 $       ShowWindow (wnd, SW_MINIMIZE);
09809 $       ShowWindow (wnd, SW_RESTORE);
09810         }
09811 
09812 $   if (mode & 0x08)
09813         {
09814 $       int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0);
09815 
09816 $       AttachThreadInput   (GetCurrentThreadId(), focus, true);
09817 $       SetForegroundWindow (wnd);
09818 $       AttachThreadInput   (GetCurrentThreadId(), focus, false);
09819         }
09820 
09821 $   if (mode & 0x04)
09822         {
09823 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
09824         }
09825 
09826 $   if (mode & 0x02)
09827         {
09828 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS);
09829         }
09830 
09831 $   if (mode & 0x01)
09832         {
09833 $       UpdateWindow (wnd);
09834         }
09835     }
09836 
09837 #endif // TX_COMPILED
09838 
09839 //}
09840 //-----------------------------------------------------------------------------------------------------------------
09841 
09843 //}
09844 //=================================================================================================================
09845 
09846 //=================================================================================================================
09847 //{          Internal TXLib window functions     (_txCanvas...)
09849 //=================================================================================================================
09850 
09851 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09852 
09853 unsigned WINAPI _txCanvas_ThreadProc (void* data)
09854     {
09855     #define SetClassLong_  SetClassLongPtr
09856     #define GCL_HICON_     GCLP_HICON
09857     #define GCL_HICONSM_   GCLP_HICONSM
09858     #define GCL_HCURSOR_   GCLP_HCURSOR
09859 
09860 $8  _txCanvas_ThreadId = GetCurrentThreadId();
09861 
09862 $   if (_TX_ARGUMENT_FAILED (data)) return false;  //-V601
09863 
09864 $   unsigned long stackSize = _TX_STACKSIZE;
09865 $   _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
09866 
09867 $   HWND wnd = _txCanvas_CreateWindow ((SIZE*) data);
09868 $   if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0;
09869 
09870 $   HICON   icon32 = LoadIcon         (NULL, "_TX_ICON");
09871 $   HICON   icon16 = LoadIcon         (NULL, "_TX_ICONSM");
09872 $   HCURSOR cursor = LoadCursor       (NULL, "_TX_CURSOR");
09873 $   HMENU   menu   = LoadMenu         (NULL, "_TX_MENU");
09874 $   HACCEL  accel  = LoadAccelerators (NULL, "_TX_ACCELERATORS");
09875 
09876 $   SetClassLong_ (wnd, GCL_HICON_,   (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32)));          //-V107 //-V112
09877 $   SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16)));          //-V107
09878 $   SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW)));  //-V107
09879 
09880     if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); }
09881 
09882 $   Win32::GdiSetBatchLimit (1);
09883 
09884     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n"));
09885 
09886 $   _txActivateWindow (wnd, 0x10);
09887 
09888 $   ShowWindow   (wnd, SW_SHOW);
09889 $   UpdateWindow (wnd);
09890 
09891 $   _txRunning = true;
09892 
09893 $   MSG msg = {};
09894 $   while (GetMessage (&msg, NULL, 0, 0))
09895         {
09896         if (!msg.hwnd) {$ continue; }
09897 
09898         if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; }
09899 
09900 $       TranslateMessage (&msg);
09901 $       DispatchMessage  (&msg);
09902 
09903 $       Sleep (0);
09904         }
09905 
09906 $   if (icon16) DestroyIcon (icon16);  // If Explorer is displaying Tray Notification, these
09907 $   if (icon32) DestroyIcon (icon32);  // calls will possibly fail, and we'll get resource leak.
09908 
09909 $   LeaveCriticalSection (&_txCanvas_LockBackBuf);
09910 
09911     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n"));
09912 
09913 $   if (_txWatchdogTimeout >= 0)
09914         {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09915 
09916 $   if (_txRunning && _txMain)         // Main window is destroyed but main() is still running.
09917         {                              // No chances for good termination, so use exit().
09918 $       _txCleanup();
09919 $       ::exit ((int) msg.wParam);     //-V202 //-V2509 //-V2014
09920         }
09921 
09922 $   _txCanvas_ThreadId = 0;
09923 $   return true;                       //-V601
09924 
09925     #undef SetClassLong
09926     #undef GCL_HICON_
09927     #undef GCL_HICONSM_
09928     #undef GCL_HCURSOR_
09929     }
09930 
09931 //-----------------------------------------------------------------------------------------------------------------
09932 
09933 HWND _txCanvas_CreateWindow (const SIZE* sizePtr)
09934     {
09935 $8  if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL;
09936 
09937 $   bool centered = false;
09938     if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; }
09939 
09940 $   SIZE screen  = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) };
09941 $   RECT rect    = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false);
09942 $   SIZE size    = { rect.right - rect.left, rect.bottom - rect.top };
09943 $   RECT conPos  = {};
09944 
09945 $   HWND console = _TX_CALL (Win32::GetConsoleWindow, ());
09946     if (console) {$ GetWindowRect (console, &conPos); }
09947 
09948 $   const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0);
09949 $   if (!wndClass) return (HWND) NULL;
09950 
09951 $   HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN,
09952                               (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT,
09953                               (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top  : CW_USEDEFAULT,
09954                                size.cx, size.cy, NULL, NULL, NULL, NULL);
09955 $   if (!wnd || !txWindow())
09956         {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; }
09957 
09958 $   HMENU menu = GetSystemMenu (txWindow(), false);
09959     if (!menu) {$ return txWindow(); }
09960 
09961 $   AppendMenu (menu, MF_SEPARATOR, 0, NULL)                       asserted;
09962 $   AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted;
09963 $   AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT,   "&About...")     asserted;
09964 
09965 $   return txWindow();
09966     }
09967 
09968 //-----------------------------------------------------------------------------------------------------------------
09969 
09970 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra)
09971     {
09972 $8  assert (classId);
09973 $   assert (wndProc);
09974 
09975 $   static char name[_TX_BUFSIZE] = "";
09976 $   _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ "
09977                                              _TX_VERSION "  " __FILE__ "  WndClass %08lX "
09978                                              "-------------[%s]-[TXLib]---*/",
09979                                              classId, (unsigned long) GetTickCount(), classId);
09980 $   WNDCLASS wc      = { sizeof (wc) };
09981 
09982 $   wc.lpszClassName = name;
09983 $   wc.lpfnWndProc   = wndProc;
09984 $   wc.style         = style;
09985 $   wc.cbWndExtra    = (wndExtra + 1) * (int) sizeof (long);
09986 
09987 $   wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
09988 $   wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush);
09989 
09990 $   ATOM atom = RegisterClass (&wc);
09991     if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; }
09992 
09993 $   return (const char*)(uintptr_t) atom;
09994     }
09995 
09996 //-----------------------------------------------------------------------------------------------------------------
09997 
09998 int _txCanvas_SetRefreshLock (int count)
09999     {
10000 $8  int oldCount = _txCanvas_RefreshLock;
10001 
10002 $   _txCanvas_RefreshLock = count;
10003 
10004 $   HWND wnd = txWindow();
10005 
10006 $   if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd)
10007         {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
10008 
10009 $   return oldCount;
10010     }
10011 
10012 //-----------------------------------------------------------------------------------------------------------------
10013 
10014 HICON _txCreateTXIcon (int size)
10015     {
10016 $8  if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL;  //-V112 //-V560
10017 
10018 $   const unsigned char image32 [32*32+1] =
10019         "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0"
10020         "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0"
10021         "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0"
10022         "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0"
10023         "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0"
10024         "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0"
10025         "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0"
10026         "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000";
10027 
10028 $   const unsigned char image16 [16*16+1] =
10029         "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990"
10030         "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000";
10031 
10032 $   const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0,
10033                                       0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff };
10034 
10035 $   const unsigned char* image = (size == 32)? image32 : image16;  //-V112
10036 
10037 $   POINT sz = { size, size };
10038 $   HDC dcMask  = _txBuffer_Create (txWindow(), &sz); assert (dcMask);
10039 $   HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor);
10040 
10041 $   for (int i = 0; i < size*size; i++)
10042         {
10043         assert (In (std::nomeow, image[i], '0', '9') ||
10044                 In (std::nomeow, image[i], 'A', 'F'));
10045 
10046         Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']);
10047         }
10048 
10049 $   ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask,  OBJ_BITMAP),
10050                                   (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) };
10051 
10052 $   HICON icon = CreateIconIndirect (&info);
10053 $   assert (icon);
10054 
10055 $   _txBuffer_Delete (&dcMask)  asserted;
10056 $   _txBuffer_Delete (&dcColor) asserted;
10057 
10058 $   return icon;
10059     }
10060 
10061 #endif // TX_COMPILED
10062 
10063 //-----------------------------------------------------------------------------------------------------------------
10064 
10065 inline bool _txCanvas_OK()
10066     {
10067     return _txCanvas_ThreadId   &&
10068            _txCanvas_Window     &&
10069            _txCanvas_BackBuf[0] &&
10070            _txCanvas_BackBuf[1] &&
10071            _txCanvas_Pixels;
10072     }
10073 
10074 //}
10075 //=================================================================================================================
10076 
10077 //=================================================================================================================
10078 //{          Main window event handlers          (_txCanvas_On...)
10080 //=================================================================================================================
10082 
10083 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10084 
10085 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
10086     {
10087 #if defined (_TX_ALLOW_TRACE)
10088 
10089     int inTX = _txLoc::Cur.inTX++;
10090 
10091     if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)",
10092                                      2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar);
10093     _txLoc::Cur.inTX = inTX;
10094 
10095 #endif
10096 
10097 $8  if (msg == WM_KEYDOWN && wpar == VK_F12 &&
10098         GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU))
10099         {
10100 $       _txCanvas_OnCmdABOUT (wnd,      wpar);
10101 $       return DefWindowProc (wnd, msg, wpar, lpar);
10102         }
10103 
10104     WNDPROC altWndProc = _txAltWndProc;  // Cache to prevent change from main thread
10105     if (altWndProc)
10106         {
10107 $       LRESULT res = altWndProc (wnd, msg, wpar, lpar);
10108 $       if (res) return res;
10109         }
10110 
10111     static bool bkErased = false;
10112 
10113     switch (msg)
10114         {
10115         case WM_CREATE:         {$     _txCanvas_OnCREATE     (wnd);                    return 0; }
10116 
10117         case WM_CLOSE:          {$ if (_txCanvas_OnCLOSE      (wnd))  break;       else return 0; }
10118         case WM_DESTROY:        {$     _txCanvas_OnDESTROY    (wnd);                    return 0; }
10119 
10120         case WM_ERASEBKGND:     {$ if (!bkErased) { bkErased = true;  break; }     else return 1; }
10121         case WM_SIZE:           {$                  bkErased = false; break;                      }
10122 
10123         case WM_PAINT:          {$     _txCanvas_OnPAINT      (wnd);                    return 0; }
10124 
10125         case WM_TIMER:          {$     _txCanvas_OnTIMER      (wnd, wpar);              return 0; }
10126 
10127         case WM_KEYUP:          {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, false)) return 0; else break; }
10128         case WM_KEYDOWN:        {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, true))  return 0; else break; }
10129         case WM_CHAR:           {$ if (_txCanvas_OnCHAR       (wnd, wpar, lpar))        return 0; else break; }
10130 
10131         case WM_LBUTTONUP:
10132         case WM_LBUTTONDOWN:
10133         case WM_RBUTTONUP:
10134         case WM_RBUTTONDOWN:
10135         case WM_MBUTTONUP:
10136         case WM_MBUTTONDOWN:
10137         case WM_MOUSEMOVE:      {$     _txCanvas_OnMOUSEMOVE  (wnd, wpar, lpar);        return 0; }
10138 
10139         case WM_MOUSELEAVE:     {$     _txCanvas_OnMOUSELEAVE (wnd);                    return 0; }
10140 
10141         case _TX_WM_CREATEWND:  {$     _txCanvas_OnCREATEWND  (wnd, wpar, lpar);        return 0; }
10142         case _TX_WM_DESTROYWND: {$     _txCanvas_OnDESTROYWND (wnd, wpar, lpar);        return 0; }
10143 
10144         case WM_NULL:           {$                                                      return 0; }
10145 
10146         default: break;  //-V2522
10147         }
10148 
10149     if (msg == WM_SYSCOMMAND) switch (wpar)
10150         {
10151         case _TX_IDM_ABOUT:     {$     _txCanvas_OnCmdABOUT   (wnd, wpar);              return 0; }
10152         case _TX_IDM_CONSOLE:   {$     _txCanvas_OnCmdCONSOLE (wnd, wpar);              return 0; }
10153 
10154         default: break;  //-V2522
10155         }
10156 
10157 $   return DefWindowProc (wnd, msg, wpar, lpar);
10158     }
10159 
10160 //-----------------------------------------------------------------------------------------------------------------
10161 
10162 bool _txCanvas_OnCREATE (HWND wnd)
10163     {
10164 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10165 
10166 $   _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]);
10167 $   _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL);              assert (_txCanvas_BackBuf[1]);
10168 
10169 $   if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0;
10170 $   assert (_txCanvas_RefreshTimer);
10171 
10172 $   _txCanvas_UserDCs = new ::std::vector <HDC>;
10173 
10174 $   _txCanvas_Window = wnd;
10175 
10176 $   txSetDefaults();
10177 
10178 $   return true;
10179     }
10180 
10181 //-----------------------------------------------------------------------------------------------------------------
10182 
10183 bool _txCanvas_OnDESTROY (HWND wnd)
10184     {
10185 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10186 
10187     // Инициируем остановку цикла сообщений
10188 
10189 $   PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS);
10190 
10191 $   if (!_txCanvas_Window) return false;
10192 
10193     // Indicate that we are about to manually terminate
10194 
10195 $   _txExit = true;
10196 
10197     // Lock GDI resources
10198 
10199 $   bool locked = false;
10200 $   _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT);
10201 $   if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources");
10202 
10203     // Освобождаем пользовательские ресурсы
10204 
10205 $   if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty())
10206         {
10207 $       txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size());  //-V202
10208 $       Sleep (_TX_TIMEOUT);
10209 
10210 $       for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i));
10211 $       _txCanvas_UserDCs->clear();
10212         }
10213 
10214     // Освобождаем ресурсы, связанные с окном
10215 
10216 $   if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted;
10217 
10218 $   if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1])  asserted;
10219 $   if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0])  asserted;
10220 $   _txCanvas_Pixels = NULL;
10221 
10222 $   txUnlock();
10223 
10224     // Indicate that we are destroyed
10225 
10226 $   _txCanvas_Window = NULL;
10227 
10228 $   return true;
10229     }
10230 
10231 //-----------------------------------------------------------------------------------------------------------------
10232 
10233 bool _txCanvas_OnCLOSE (HWND wnd)  //-V2009 //-V2558
10234     {
10235 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10236 $   if (!_txCanvas_OK())           return false;
10237 
10238 $   if (_txMain && _txRunning &&
10239         txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n"
10240                       "Лучше подождать, когда main() завершится - это отображается в заголовке окна.",
10241                       txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false;
10242 $   return true;
10243     }
10244 
10245 //-----------------------------------------------------------------------------------------------------------------
10246 
10247 bool _txCanvas_OnTIMER (HWND wnd, WPARAM)
10248     {
10249 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10250 
10251 $   if (_txCanvas_RefreshLock > 0 || !_txRunning) return false;
10252 
10253 $   InvalidateRect (wnd, NULL, false) asserted;
10254 $   UpdateWindow   (wnd)              asserted;
10255 
10256 $   return true;
10257     }
10258 
10259 //-----------------------------------------------------------------------------------------------------------------
10260 
10261 bool _txCanvas_OnPAINT (HWND wnd)
10262     {
10263 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10264 $   if (!_txCanvas_OK())           return false;
10265 
10266 $   bool forceRedraw = GetAsyncKeyState (VK_MENU)  && GetAsyncKeyState (VK_CONTROL) &&
10267                        GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT);
10268 
10269 $   PAINTSTRUCT ps = {};
10270 $   HDC wndDc = BeginPaint (wnd, &ps);
10271 $   if (!wndDc) return false;
10272 
10273 $   HDC dc0 = _txCanvas_BackBuf[0],
10274         dc1 = _txCanvas_BackBuf[1];
10275 
10276 $   RECT r = {};
10277 $   GetClientRect (wnd, &r) asserted;
10278 $   POINT wndSize = { r.right - r.left, r.bottom - r.top };
10279 
10280 $   POINT dcSize = txGetExtent (dc1);
10281 
10282 $   if ((_txCanvas_RefreshLock <= 0 || forceRedraw) &&
10283         txLock (false))
10284         {
10285 $       Win32::BitBlt          (dc1,   0, 0, dcSize.x,  dcSize.y,  dc0, 0, 0, SRCCOPY);
10286 
10287 $       if (_txConsole >= 0)
10288             {$ _txConsole_Draw (dc1); }
10289 
10290 $       txUnlock();
10291         }
10292 
10293     // Magic 100500 value is used to completely block screen refresh.
10294     // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL.
10295     // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers
10296     // themselves.
10297     // Yes guys, with all your software installed. :(
10298 
10299 $   if (_txCanvas_RefreshLock != 100500)
10300         {
10301         if (_txSwapBuffers)
10302             {
10303 $           _txSwapBuffers     (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10304             }
10305         else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y)
10306             {
10307 $           Win32::BitBlt      (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0,                     SRCCOPY);
10308             }
10309         else
10310             {
10311 $           Win32::SetStretchBltMode (wndDc, HALFTONE);
10312 $           Win32::StretchBlt  (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10313             }
10314         }
10315 
10316 $   EndPaint (wnd, &ps) asserted;
10317 
10318 $   return true;
10319     }
10320 
10321 //-----------------------------------------------------------------------------------------------------------------
10322 
10323 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info)
10324     {
10325 $8  INPUT_RECORD evt[2] = {};
10326 
10327 $   evt[0].EventType                        = KEY_EVENT;
10328 $   evt[0].Event.KeyEvent.bKeyDown          = true;
10329 $   evt[0].Event.KeyEvent.wRepeatCount      = 1;
10330 $   evt[0].Event.KeyEvent.uChar.AsciiChar   = (char) (ch);
10331 $   evt[0].Event.KeyEvent.wVirtualScanCode  = (WORD) (info >> 16);
10332 $   evt[0].Event.KeyEvent.wVirtualKeyCode   = (WORD) MapVirtualKey ((WORD) (info >> 16), 3);  // 3 == MAPVK_VSC_TO_VK_EX
10333 $   evt[0].Event.KeyEvent.dwControlKeyState = 0;
10334 
10335 $   evt[1] = evt[0];
10336 $   evt[1].Event.KeyEvent.bKeyDown          = false;
10337 
10338 $   DWORD written = 0;
10339 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE),  evt, 2, &written);
10340 
10341 $   return true;
10342     }
10343 
10344 //-----------------------------------------------------------------------------------------------------------------
10345 
10346 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down)
10347     {
10348 $8  INPUT_RECORD evt = {};
10349 
10350 $   evt.EventType                           = KEY_EVENT;
10351 $   evt.Event.KeyEvent.bKeyDown             = down;
10352 $   evt.Event.KeyEvent.wRepeatCount         = 1;
10353 $   evt.Event.KeyEvent.uChar.AsciiChar      = (char)  MapVirtualKey ((WORD) vk, 2);           // 2 == MAPVK_VK_TO_CHAR
10354 $   evt.Event.KeyEvent.wVirtualScanCode     = (WORD)  (info >> 16);
10355 $   evt.Event.KeyEvent.wVirtualKeyCode      = (WORD)  vk;
10356 $   evt.Event.KeyEvent.dwControlKeyState    = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0;
10357 
10358 $   if (evt.Event.KeyEvent.uChar.AsciiChar) return false;  // Let TranslateMessage() and WM_CHAR do the job
10359 
10360 $   DWORD written = 0;
10361 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written);
10362 
10363 $   return true;
10364     }
10365 
10366 //-----------------------------------------------------------------------------------------------------------------
10367 
10368 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords)
10369     {
10370 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10371 $   if (!_txCanvas_OK())           return false;
10372 
10373 $   if (_txMousePos.x == -1 && _txMousePos.y == -1)
10374         {
10375 $       TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT };
10376 $       TrackMouseEvent (&track);
10377         }
10378 
10379 $   _txMousePos.x   = LOWORD (coords);
10380 $   _txMousePos.y   = HIWORD (coords);
10381 $   _txMouseButtons = (unsigned) buttons;  //-V202
10382 
10383 $   return true;
10384     }
10385 
10386 //-----------------------------------------------------------------------------------------------------------------
10387 
10388 bool _txCanvas_OnMOUSELEAVE (HWND)
10389     {
10390 $8  _txMousePos.x   = -1;
10391 $   _txMousePos.y   = -1;
10392 $   _txMouseButtons = 0;
10393 
10394 $   return true;
10395     }
10396 
10397 //-----------------------------------------------------------------------------------------------------------------
10398 
10399 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar)
10400     {
10401 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10402 
10403 $   const CREATESTRUCT* create = (CREATESTRUCT*) lpar;
10404 
10405 $   HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style,
10406                                create->x, create->y, create->cx, create->cy,
10407                                create->hwndParent, create->hMenu, NULL, create->lpCreateParams);
10408 
10409 $   *(HWND*) create->hInstance = wnd;
10410 
10411 $   return true;
10412     }
10413 
10414 //-----------------------------------------------------------------------------------------------------------------
10415 
10416 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar)
10417     {
10418 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10419 
10420 $   DestroyWindow ((HWND) lpar);
10421 
10422 $   return false;
10423     }
10424 
10425 //-----------------------------------------------------------------------------------------------------------------
10426 
10427 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd)
10428     {
10429 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10430 
10431 $   HWND console = Win32::GetConsoleWindow();
10432 $   if (!console) return false;
10433 
10434 $   bool visible = !!IsWindowVisible (console);
10435 
10436 $   ShowWindow (console, visible? SW_HIDE : SW_RESTORE);
10437 
10438 $   visible = !!IsWindowVisible (console);
10439 $   CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED);  //-V202
10440 
10441 $   return true;
10442     }
10443 
10444 //-----------------------------------------------------------------------------------------------------------------
10445 
10446 bool _txCanvas_OnCmdABOUT (HWND, WPARAM)
10447     {
10448 $8  //{ Overriding the missing names, if the set is incomplete
10449 
10450     #if defined (__MODULE)
10451         #define ABOUT_NAME_    __MODULE
10452     #else
10453         #define ABOUT_NAME_    "TXLib"
10454     #endif
10455 
10456     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10457 
10458         #ifndef __MODULE
10459         #define __MODULE       "TXLib"                           "\n"  "#define __MODULE to set the name.\n"
10460         #endif
10461 
10462         #ifndef __VERSION
10463         #define __VERSION      "(0.000000000)."                  "\n" "#define __VERSION to set the string value.\n"
10464         #endif
10465 
10466         #ifndef __DESCRIPTION
10467         #define __DESCRIPTION  "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n"
10468         #endif
10469 
10470         #ifndef __AUTHOR
10471         #define __AUTHOR       "(Непонятно кто)."                "\n" "#define __AUTHOR to override this name."
10472         #endif
10473 
10474     #endif
10475     //}
10476 
10477 $   static char text[_TX_BUFSIZE] = "";
10478 
10479 $   _tx_snprintf_s (text, sizeof (text) - 1,
10480 
10481                     "Application:\n\n"
10482 
10483                     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10484                         __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n"
10485                     #else
10486                         "Здесь могла бы быть Ваша реклама :)\n"
10487                         "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n"
10488                     #endif
10489 
10490                     "\n" "%s", _txAppInfo());
10491 
10492 $   txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION);
10493 
10494     // And a bit of HTTP-code in C++ function:
10495 
10496     goto http;
10497     http://sizeof.livejournal.com
10498 
10499 $   return true;
10500 
10501     #undef ABOUT_NAME_
10502     }
10503 
10504 #endif // TX_COMPILED
10505 
10507 //}
10508 //=================================================================================================================
10509 
10510 //=================================================================================================================
10511 //{          Console-support functions           (_txConsole...)
10513 //=================================================================================================================
10515 
10516 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10517 
10518 HWND _txConsole_Attach()
10519     {
10520 $1  HWND console = Win32::GetConsoleWindow();
10521 
10522 $   if (!console)
10523         {
10524 $       bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem());
10525 
10526 $       Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb();
10527 $       assert (teb);
10528 $       assert (teb->ProcessEnvironmentBlock);
10529 
10530 $       Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters;
10531 $       assert (params);
10532 
10533 $       if (minimizeConsole)  // The fact that ShowWindow parameter of the program's console is taken from calling
10534                               // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo()
10535                               // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :(
10536                               // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke!..
10537             {
10538 $           params->dwFlags    |= STARTF_USESHOWWINDOW;
10539 $           params->wShowWindow = SW_MINIMIZE;
10540             }
10541 
10542 $       AllocConsole();
10543 $       console = Win32::GetConsoleWindow();
10544         }
10545 
10546 $   if (!console) return NULL;
10547 
10548 $   txSetLocale();                                // Устанавливаем русскую кодовую страницу для консоли Windows
10549 
10550 $   _txConsole_SetUnicodeFont();                  // Впечатлительным лучше сюда не смотреть.
10551 
10552 $   if (!_txIsConsoleSubsystem())
10553         {$ txReopenStdio(); }                     // Переоткрываем потоки ввода-вывода, если subsystem != console
10554 
10555 $   return console;
10556     }
10557 
10558 //-----------------------------------------------------------------------------------------------------------------
10559 
10560 int txSetLocale (int codepage /*= _TX_CODEPAGE*/,
10561                  const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/)
10562     {
10563 $1  int oldPage = GetConsoleOutputCP();
10564 
10565     // Устанавливаем нужную кодовую страницу для консоли Windows
10566 
10567 $   if (codepage)
10568         {
10569 $       SetConsoleCP       (codepage);
10570 $       SetConsoleOutputCP (codepage);
10571         }
10572 
10573     // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии
10574     // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным
10575     // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN -
10576     // обозначение кодовой страницы (например, для русского языка - CP1251).
10577 
10578 $   if (locale)
10579         {
10580 $       setlocale (LC_ALL,     locale);
10581 $       setlocale (LC_NUMERIC, "C");              // Return to decimal point (3.14) instead of comma (3,14) in floating numbers
10582         }
10583 
10584     #ifndef __CYGWIN__
10585 
10586 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10587 
10588 $   if (wLocale && !wine)
10589         {
10590 $       _wsetlocale (LC_ALL,     wLocale);
10591 $       _wsetlocale (LC_NUMERIC, L"C");           // L"C" (see above)
10592         }
10593 
10594     #endif
10595 
10596     (void) wLocale;
10597 
10598 $   return oldPage;
10599     }
10600 
10601 //-----------------------------------------------------------------------------------------------------------------
10602 
10603 void txReopenStdio()
10604     {
10605 $1  // Переоткрываем заново <s>Америку</s> потоки ввода-вывода
10606 
10607 $   fflush (stdout);
10608 $   fflush (stderr);
10609 
10610 $   FILE* f = NULL;
10611 
10612     #ifndef __CYGWIN__
10613 
10614 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE),  _O_TEXT), "r"); assert (f); *stdin  = *f;
10615 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f;
10616 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE),  _O_TEXT), "w"); assert (f); *stderr = *f;
10617 
10618     #else
10619 
10620 $   f = _fdopen (STDIN_FILENO,  "r"); assert (f); *stdin  = *f;
10621 $   f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f;
10622 $   f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f;
10623 
10624     #endif
10625 
10626 $   setvbuf (stdin,  NULL, _IONBF, 0);
10627 $   setvbuf (stdout, NULL, _IONBF, 0);
10628 $   setvbuf (stderr, NULL, _IONBF, 0);
10629 
10630 $   ::std::ios::sync_with_stdio();
10631     }
10632 
10633 //-----------------------------------------------------------------------------------------------------------------
10634 
10635 inline bool _txConsole_OK()
10636     {
10637     return Win32::GetConsoleWindow() != NULL;
10638     }
10639 
10640 //-----------------------------------------------------------------------------------------------------------------
10641 
10642 bool _txConsole_Detach (bool activate)
10643     {
10644 $1  HWND console = Win32::GetConsoleWindow();
10645 $   if (!console) return false;
10646 
10647 $   EnableWindow (console, true);
10648 
10649 $   if (activate)
10650         {
10651 $       if (!IsWindowVisible (console))
10652             {$ ShowWindow (console, SW_MINIMIZE); }
10653 
10654 $       _txActivateWindow (console, 0xFF);
10655 $       return true;
10656         }
10657     else
10658         {
10659 $       return !!FreeConsole();
10660         }
10661     }
10662 
10663 //-----------------------------------------------------------------------------------------------------------------
10664 
10665 bool _txConsole_Draw (HDC dc)
10666     {
10667 $8  if (_TX_HDC_FAILED (dc)) return false;
10668 
10669 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10670 
10671 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
10672 $   BOOL ok = GetConsoleScreenBufferInfo (out, &con);
10673 $   if (!ok) return false;
10674 
10675 $   POINT size = { con.srWindow.Right  - con.srWindow.Left + 1,
10676                    con.srWindow.Bottom - con.srWindow.Top  + 1 };
10677 
10678 $   SIZE fontSz = { 12, 16 };
10679 $   Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted;
10680 
10681 $   COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
10682                           0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF };
10683 
10684 $   for (short y = 0; y < size.y; y++)
10685         {
10686         static char chr [_TX_BUFSIZE + 1] = "";  // [con.dwSize.X + 1]; maybe will be truncated
10687         static WORD atr [_TX_BUFSIZE + 1] = {};  // [con.dwSize.X + 1]; maybe will be truncated
10688         COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) };
10689         DWORD read  = 0;
10690 
10691         if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue;
10692         if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue;
10693 
10694         for (int x = 0, xEnd = size.x; x < size.x; x = xEnd)
10695             {
10696             Win32::SetTextColor (dc, pal [ atr[x]       & 0x0F]);
10697             Win32::SetBkColor   (dc, pal [(atr[x] >> 4) & 0x0F]);
10698             Win32::SetBkMode    (dc,      (atr[x]       & 0xF0)? OPAQUE : TRANSPARENT);
10699 
10700             for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;}
10701 
10702             Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)),
10703                                 ROUND (fontSz.cy *  y), chr + x, xEnd - x) asserted;
10704             }
10705         }
10706 
10707 $   Win32::SetTextColor (dc, pal [ con.wAttributes       & 0x0F]);
10708 $   Win32::SetBkColor   (dc, pal [(con.wAttributes >> 4) & 0x0F]);
10709 $   Win32::SetBkMode    (dc, TRANSPARENT);
10710 
10711 $   if (_txConsole_IsBlinking &&
10712         In (std::nomeow, con.dwCursorPosition, con.srWindow) &&
10713         GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval &&
10714         GetForegroundWindow() == txWindow())
10715         {
10716 $       Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)),
10717                             ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1,
10718                             "_", 1) asserted;
10719         }
10720 
10721 $   return true;
10722     }
10723 
10724 #endif // TX_COMPILED
10725 
10726 //-----------------------------------------------------------------------------------------------------------------
10727 //{          Welcome to the Duck Side! Together we will rule the Bathroom!
10728 //-----------------------------------------------------------------------------------------------------------------
10729 
10730 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10731 
10732 bool _txConsole_SetUnicodeFont()
10733     {
10734 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10735                                                   // Beer compatibility may be added in future versions...
10736 $   if (wine)                                     // Минздрав РФ предупреждает: чрезмерное употребление wine
10737         {                                         // вредит Вашему здоровью.
10738 $       Win32::GetNumberOfConsoleFonts = NULL;
10739 $       Win32::GetCurrentConsoleFont   = NULL;
10740 $       Win32::SetConsoleFont          = NULL;
10741 
10742 $       return false;
10743         }
10744 
10745     // Начиная с Висты все хорошо...
10746 
10747 $1  if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx)
10748         {
10749 $       HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10750 
10751 $       Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) };
10752 $       if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false;
10753 
10754 $       info.FontFamily = 0x36;                                                    // Unicode fixed-pitch
10755 $       if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2);  // Terminal font is too small
10756 
10757 $       if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0)    // Consolas is allowed too
10758             {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); }
10759 
10760 $       return !!Win32::SetCurrentConsoleFontEx (out, false, &info);
10761         }
10762 
10763     // ...а до этого все не так сладко
10764 
10765 $   const unsigned uniFont = 10;                  // The Internet and W2K sources know this magic number
10766 $   const unsigned uniSize = 20;                  // Size of the font desired, should be > max # of Raster Fonts  //-V2551
10767 $   bool ok = true;
10768 
10769     // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font.
10770 
10771 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10772 
10773 $   unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ());
10774 $   if (fonts && fonts <= uniFont)
10775         {
10776 $       HRESULT init = Win32::CoInitialize (NULL);
10777 $       size_t sz = 0;
10778 
10779 $       char link [MAX_PATH] = "";
10780 $       getenv_s (&sz, link, sizeof (link) - 1, "TEMP");
10781 $       strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1);
10782 
10783 $       char comspec [MAX_PATH] = "";
10784 $       getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC");
10785 
10786 $       (void) _unlink (link);
10787 
10788 $       _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted;
10789 
10790 $       ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32);  // Sic!  //-V112 //-V566
10791         if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); }
10792 
10793 $       (void) _unlink (link);
10794 
10795 $       if (init == S_OK) Win32::CoUninitialize();
10796         }
10797 
10798     // If Unicode font is not already set, do set it.
10799 
10800 $   Win32::CONSOLE_FONT_INFO cur = {};
10801 $   _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur));
10802 
10803 $   ok &= (cur.nFont >= uniFont);
10804     if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); }
10805 
10806 $   HWND console = Win32::GetConsoleWindow();
10807 $   InvalidateRect (console, NULL, false);
10808 $   UpdateWindow   (console);
10809 
10810 $   return ok;
10811     }
10812 
10813 #endif // TX_COMPILED
10814 
10815 //-----------------------------------------------------------------------------------------------------------------
10816 //{          The assistants to the nightmare. You can use it freely to make your own nightmare sweet.
10817 
10818 #define      _TX_TRY                { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error;
10819 #define      _TX_CHECKED( cmd )     { if (FAILED (__tx_error = (cmd))) goto __tx_catch; }
10820 #define      _TX_FAIL               { __tx_error = E_FAIL; goto __tx_catch; }
10821 #define      _TX_RETRY              { __tx_error = S_OK;   goto __tx_try;   }
10822 #define      _TX_OK                 ( SUCCEEDED (__tx_error) )
10823 #define      _TX_CATCH              goto __tx_finally; __tx_catch:
10824 #define      _TX_RETURN             goto __tx_finally;
10825 #define      _TX_FINALLY            __tx_finally:
10826 #define      _TX_ENDTRY             }
10827 
10828 //}
10829 //-----------------------------------------------------------------------------------------------------------------
10830 
10831 // Мало не покажется
10832 
10833 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10834 
10835 bool _txCreateShortcut (const char shortcutName[],
10836                         const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/,
10837                         const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/,
10838                         int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/)
10839     {
10840 $1  if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false;
10841 $   if (_TX_ARGUMENT_FAILED (fileToLink   && *fileToLink))   return false;
10842 
10843     #if defined (__IShellLinkDataList_INTERFACE_DEFINED__)
10844 
10845 $   IShellLink* shellLink = NULL;
10846 $   IShellLinkDataList* dataList = NULL;
10847 $   IPersistFile* file = NULL;
10848 
10849 $   HRESULT init = Win32::CoInitialize (NULL);
10850 
10851     _TX_TRY
10852         {
10853 $       _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink));
10854 $       if (!shellLink) _TX_FAIL;
10855 
10856 $       shellLink->SetPath (fileToLink);
10857 $       shellLink->SetArguments (args);
10858 $       shellLink->SetWorkingDirectory (workDir);
10859 $       shellLink->SetDescription (description);
10860 $       shellLink->SetShowCmd (cmdShow);
10861 $       shellLink->SetIconLocation (iconFile, iconIndex);
10862 
10863 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList));
10864 $       if (!dataList) _TX_FAIL;
10865 
10866 $       Win32::NT_CONSOLE_PROPS props =
10867           {{sizeof (props), NT_CONSOLE_PROPS_SIG},
10868 
10869             FOREGROUND_LIGHTGRAY,                       // wFillAttribute
10870             FOREGROUND_MAGENTA | BACKGROUND_WHITE,      // wPopupFillAttribute
10871            {bufSize.X, bufSize.Y},                      // dwScreenBufferSize
10872            {wndSize.X, wndSize.Y},                      // dwWindowSize
10873            {wndOrg.X,  wndOrg.Y},                       // dwWindowOrigin
10874             0,                                          // nFont
10875             0,                                          // nInputBufferSize
10876            {0, (short) fontSize},                       // dwFontSize
10877             0x36, 400, L"Lucida Console",               // uFontFamily, uFontWeight, FaceName. We're dancing for this!
10878             15,                                         // uCursorSize
10879             0,  1, 1, 0,                                // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition
10880             50, 4, 0,                                   // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup
10881 
10882            {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,  // Palette
10883             0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF}
10884             };
10885 
10886 $       _TX_CHECKED (dataList->AddDataBlock (&props));
10887 
10888 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file));
10889 $       if (!file) _TX_FAIL;
10890 
10891 $       wchar_t wName[MAX_PATH] = L"";
10892 $       MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName));
10893 
10894 $       _TX_CHECKED (file->Save (wName, true));
10895         }
10896 
10897 $   _TX_CATCH
10898 $   _TX_FINALLY
10899 
10900     if (file)         {$ file     ->Release(); }
10901     if (dataList)     {$ dataList ->Release(); }
10902     if (shellLink)    {$ shellLink->Release(); }
10903 
10904     if (init == S_OK) {$ Win32::CoUninitialize(); }
10905 
10906 $   return _TX_OK;
10907     _TX_ENDTRY
10908 
10909     #else
10910 
10911     (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex;
10912     (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg;
10913 
10914 $   return false;
10915 
10916     #endif
10917     }
10918 
10919 #endif // TX_COMPILED
10920 
10921 //}
10922 //-----------------------------------------------------------------------------------------------------------------
10923 
10925 //}
10926 //=================================================================================================================
10927 
10928 //=================================================================================================================
10929 //{          Memory DC functions                 (_txBuffer...)
10931 //=================================================================================================================
10933 
10934 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10935 
10936 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
10937     {
10938 $1  txAutoLock _lock;
10939 
10940 $   HDC wndDC = GetDC (wnd);
10941 $   if (!wndDC) return NULL;
10942 
10943 $   POINT sz = { 1, 1 };
10944 $   if (size) sz = *size;
10945 
10946 $   if (!size && wnd)
10947         {
10948 $       RECT r = {};
10949 $       GetClientRect (wnd, &r) asserted;
10950 
10951 $       sz.x = r.right  - r.left;
10952 $       sz.y = r.bottom - r.top;
10953         }
10954 
10955 $   if (bitmap)
10956         {
10957 $       BITMAP bmap = {};
10958 $       Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted;
10959 
10960 $       sz.x = bmap.bmWidth;
10961 $       sz.y = bmap.bmHeight;
10962         }
10963 
10964 $   RGBQUAD* buf = NULL;
10965 $   if (!pixels) pixels = &buf;
10966 
10967 $   HDC dc = Win32::CreateCompatibleDC (wndDC);
10968 $   if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed");
10969 
10970     #ifndef _TX_DIB_FIX
10971     #define _TX_DIB_FIX
10972     #endif
10973 
10974 $   BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }};
10975 
10976 $   HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0);
10977 $   if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed");
10978 
10979 $   Win32::SelectObject (dc, bmap) asserted;
10980 
10981 $   if (!bitmap)
10982         {
10983 $       if (*pixels)
10984             {
10985 $           RGBQUAD black = { 0, 0, 0, 255 };
10986 $           for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black;  //-V108
10987             }
10988         else
10989             {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; }
10990         }
10991 
10992 $   ReleaseDC (wnd, wndDC) asserted;
10993 
10994 $   return dc;
10995     }
10996 
10997 //-----------------------------------------------------------------------------------------------------------------
10998 
10999 bool _txBuffer_Delete (HDC* dc)
11000     {
11001 $1  if (_TX_ARGUMENT_FAILED (dc)) return false;
11002 $   if (                   !*dc)  return false;
11003 $   if (_TX_HDC_FAILED     (*dc)) return false;
11004 
11005 $   if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false;
11006 
11007 $   txAutoLock _lock;
11008 
11009 $   _txBuffer_Select (Win32::GetStockObject (NULL_PEN),    *dc) asserted;
11010 $   _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH),  *dc) asserted;
11011 $   _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted;
11012 $   _txBuffer_Select (_txStockBitmap,                      *dc);
11013 
11014 $   Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted;
11015 
11016 $   Win32::DeleteDC (*dc) asserted;
11017 
11018 $   *dc = NULL;
11019 
11020 $   return true;
11021     }
11022 
11023 //-----------------------------------------------------------------------------------------------------------------
11024 
11025 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/)
11026     {
11027 $1  if (!obj)                return false;
11028 $   if (_TX_HDC_FAILED (dc)) return false;
11029 
11030 $   if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type");
11031 
11032 $   txAutoLock _lock;
11033 
11034 $   obj = Win32::SelectObject (dc, obj);
11035 $   if (obj) Win32::DeleteObject (obj);
11036 
11037 $   return obj != NULL;
11038     }
11039 
11040 #endif // TX_COMPILED
11041 
11043 //}
11044 //=================================================================================================================
11045 
11046 //=================================================================================================================
11047 //{          Diagnostics
11049 //=================================================================================================================
11051 
11052 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11053 
11054 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/,
11055                       const char* msg  /*= NULL*/, ...)
11056     {                                                                        //---/\---/\-------Это ASCII KOT!--//
11057 $1  va_list arg; va_start (arg, msg);                                        //  {  '-'  }                      //
11058 $$  const char* what = _txProcessError (file, line, func, color, msg, arg);  //  {  0 0  }     Добавь его себе  //
11059     va_end (arg);                                                            //  --> V <--  в исходник, и тебе  //
11060                                                                              //   \ \|/ /      будет, наверно,  //
11061     if (!(msg && msg[0] == '\a')) return what;                               //    \___/  приятно отлаживаться  //
11062                                                                              //---------------долгими ночами:)--//
11063 //  vvvvvvvvvvvvvvvvvv
11064     DebugBreak();   // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться.
11065 //  ^^^^^^^^^^^^^^^^^^
11066 
11067     return what;    // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7).
11068     }
11069 
11070 #endif // TX_COMPILED
11071 
11072 //-----------------------------------------------------------------------------------------------------------------
11073 //{          General runtime check hooks
11074 //-----------------------------------------------------------------------------------------------------------------
11075 
11076 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11077 
11078 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/)
11079     {
11080 $1  if (!sig && !fpe)
11081         {
11082 $       signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11083 $       signal (SIGFPE,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11084 $       signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11085 $       signal (SIGILL,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11086 $       signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11087 $       return;
11088         }
11089 
11090     txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe);
11091 
11092     #define GET_DESCR_(str, code, descr)  case (code): {$ (str) = " " #code ": " descr; break; }
11093 
11094 $   const char* sSig = "Неизвестный тип сигнала";
11095 
11096 $   switch (sig)
11097         {
11098         GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!")
11099         GET_DESCR_ (sSig, SIGILL,  "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.")
11100         GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().")
11101         GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.")
11102         GET_DESCR_ (sSig, SIGFPE,  "Грубая ошибка в вычислениях.")
11103         default:   break;  //-V2522
11104         }
11105 
11106 $   const char* sFPE = "";
11107 
11108     #if defined (_MSC_VER)
11109 
11110     // MSVC provides the FPE code as a MS extension.
11111     // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx
11112 
11113 $   if (sig == SIGFPE) switch (fpe)
11114         {
11115         GET_DESCR_ (sFPE, _FPE_INVALID,        "Результат неверен.")
11116         GET_DESCR_ (sFPE, _FPE_DENORMAL,       "Денормализация.")
11117         GET_DESCR_ (sFPE, _FPE_ZERODIVIDE,     "Деление на ноль.")
11118         GET_DESCR_ (sFPE, _FPE_OVERFLOW,       "Результат слишком большой.")
11119         GET_DESCR_ (sFPE, _FPE_UNDERFLOW,      "Результат слишком маленький.")
11120         GET_DESCR_ (sFPE, _FPE_INEXACT,        "Результат неточен.")
11121         GET_DESCR_ (sFPE, _FPE_UNEMULATED,     "Операция не поддерживается.")
11122         GET_DESCR_ (sFPE, _FPE_SQRTNEG,        "Квадратный корень из отрицательного числа.")
11123         GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW,  "Переполнение стека сопроцессора.")
11124         GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.")
11125         GET_DESCR_ (sFPE, _FPE_EXPLICITGEN,    "Явный вызов исключения.")
11126         default:   break;  //-V2522
11127         }
11128 
11129     #else
11130 $   fpe = 0;
11131     #endif
11132 
11133     #undef GET_DESCR_
11134 
11135 $   signal (sig, (void(*)(int))(uintptr_t)_txOnSignal);
11136 
11137 $   Win32::_fpreset();
11138 
11139 $   _TX_UNEXPECTED ("\a\t"
11140                     "signal (%d, 0x%02X):%s%s "
11141                     "%s%s"
11142                     "С помощью функции signal() вы можете сами обработать эту ошибку.",
11143                     sig, (unsigned) fpe, sSig, sFPE,
11144                     ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1);
11145     }
11146 
11147 //-----------------------------------------------------------------------------------------------------------------
11148 
11149 void _txOnTerminate()
11150     {
11151     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11152 
11153     // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc
11154 
11155 $1  static int terminating = 0;
11156     if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; }
11157 
11158 $   if (!*_txDumpSE)
11159         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11160 
11161 $   _TX_UNEXPECTED ("\t\a"
11162                     "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, "
11163                     "или другая фатальная ошибка C++. "
11164                     "%s"
11165                     "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, "
11166                     "разбирайтесь, в чем дело.\n\n"
11167                     "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE,
11168                     _txDumpSE + 1);
11169     }
11170 
11171 //-----------------------------------------------------------------------------------------------------------------
11172 
11173 void _txOnUnexpected()
11174     {
11175     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11176 
11177 $1  if (!*_txDumpSE)
11178         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11179 
11180 $   _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n"
11181                     "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете "
11182                     "спецификацию исключений для функций, проверьте, не нарушена ли она."
11183                     "%s"
11184                     "С помощью catch (...) в main() вы можете сами обработать эту ошибку.",
11185                     _txDumpSE + 1);
11186     }
11187 
11188 //-----------------------------------------------------------------------------------------------------------------
11189 
11190 int _txOnMatherr (_exception* exc)
11191     {
11192     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc);
11193 
11194 $1  assert (exc);
11195 
11196     const char* sType = "Неизвестный тип исключения";
11197 
11198     #if !defined (__CYGWIN__)
11199 
11200     #define GET_DESCR_(code, descr)  case (code): {$ sType = "(" #code "): " descr; break; }
11201 
11202 $   switch (exc->type)
11203         {
11204         GET_DESCR_ (_DOMAIN,    "Нарушение области определения");
11205         GET_DESCR_ (_SING,      "Сингулярность аргумента");
11206         GET_DESCR_ (_PLOSS,     "Частичная потеря значимости");
11207         GET_DESCR_ (_TLOSS,     "Полная потеря значимости");
11208         GET_DESCR_ (_OVERFLOW,  "Результат слишком большой");
11209         GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький");
11210         default:   break;  //-V2522
11211         }
11212 
11213     #undef GET_DESCR_
11214 
11215 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n"
11216                     "С помощью __setusermatherr() вы можете сами обработать эту ошибку.",
11217                     exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval);
11218     #else
11219 
11220 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType);
11221 
11222     #endif
11223 
11224     return 0;
11225     }
11226 
11227 //-----------------------------------------------------------------------------------------------------------------
11228 
11229 tx_noreturn void _txOnNewHandlerAnsi()
11230     {
11231     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11232 $1
11233 $   _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n"
11234                     "С помощью std::set_new_handler() вы можете сами обработать эту ошибку "
11235                     "и где-нибудь найти недостающую память.");
11236 
11237 $   throw std::bad_alloc();
11238     }
11239 
11240 //-----------------------------------------------------------------------------------------------------------------
11241 
11242 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code)
11243     {
11244     txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code);
11245 
11246 $1  if (code)
11247         {$ errno = code; }
11248 
11249 $   _TX_UNEXPECTED ("\a"
11250                     "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n"
11251                     "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку "
11252                     "и постараться не выходить за границы массивов.",
11253                     code, msg, (char*) ptr, ptr);
11254     }
11255 
11256 //-----------------------------------------------------------------------------------------------------------------
11257 
11258 int tx_glGetError (int setError /*= INT_MIN*/)
11259     {
11260 $1  _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError;
11261 $   return _txOGLError;
11262     }
11263 
11264 #endif // TX_COMPILED
11265 
11266 //}
11267 //-----------------------------------------------------------------------------------------------------------------
11268 
11269 //-----------------------------------------------------------------------------------------------------------------
11270 //{          MSC Runtime check hooks
11271 //-----------------------------------------------------------------------------------------------------------------
11272 
11273 #if defined (_MSC_VER)
11274 
11275 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11276 
11277 //-----------------------------------------------------------------------------------------------------------------
11278 
11279 int _txOnNewHandler (size_t size)
11280     {
11281     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size);
11282 $5
11283 $   _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n"
11284                     "С помощью _set_new_handler() вы можете сами обработать эту ошибку "
11285                     "и где-нибудь найти недостающую память.", (unsigned long long) size);
11286 
11287 $   throw std::bad_alloc();
11288     }
11289 
11290 //-----------------------------------------------------------------------------------------------------------------
11291 
11292 void _txOnSecurityError (int code, void* addr)
11293     {
11294     txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr);
11295 $5
11296 $   _TX_UNEXPECTED ("\a"
11297                     "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n"
11298                     "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку "
11299                     "и более торжественно завершить программу. Ставьте же ассерты.", code);
11300     }
11301 
11302 //-----------------------------------------------------------------------------------------------------------------
11303 
11304 void _txOnPureCall()
11305     {
11306     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11307 $5
11308 $   _TX_UNEXPECTED ("\a"
11309                     "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах "
11310                     "или деструкторах базовых классов - не вызывайте там таких функций.\n\n"
11311                     "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку "
11312                     "и проверить свое знание С++ :)");
11313     }
11314 
11315 //-----------------------------------------------------------------------------------------------------------------
11316 
11317 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr)
11318     {
11319     txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr);
11320 
11321 $5  assert (wExpr);
11322     assert (wFunc);
11323     assert (wFile);
11324 
11325     char expr [_TX_BUFSIZE/2] = "[Unknowm expr]",
11326          func [_TX_BUFSIZE/2] = "[Unknowm func]",
11327          file [MAX_PATH]      = "[Unknowm file]";
11328 
11329 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL);
11330 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL);
11331 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL);
11332 
11333 $$  _txError (file, (int) line, func, 0, "\a"
11334               "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n"
11335               "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr);
11336     }
11337 
11338 //-----------------------------------------------------------------------------------------------------------------
11339 
11340 #if defined (_CLANG_VER) && !defined (_MSC_VER)
11341 
11342 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info)
11343     {
11344 $5  assert (&info);
11345 
11346 $$  _txError (info.__file_, info.__line_, NULL, 0, "\a"
11347               "Оказалось неверно, что %s (%s). Не надо так.\n\n"
11348               "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_);
11349     }
11350 
11351 #endif
11352 
11353 //-----------------------------------------------------------------------------------------------------------------
11354 
11355 #pragma runtime_checks ("", off)
11356 
11357 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...)
11358     {
11359     txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format);
11360 
11361 $5  static long running = 0;
11362 $   while (InterlockedExchange (&running, 1)) Sleep (0);
11363 
11364 $   assert (format);
11365 
11366     // Disable all RTC failures
11367 
11368 $   int nErrors = _RTC_NumErrors();
11369 $   int* errors = NULL;
11370 $   try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;}  //-V104
11371 
11372 $   int err = 0;
11373 $   for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE);  //-V108
11374 
11375 $   char text [_TX_BUFSIZE] = "";
11376 
11377 $   va_list arg; va_start (arg, format);
11378 $   _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg);                  // Get message from the vararg list
11379 $   auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/);  // Get the RTC error number
11380 $   va_end (arg);
11381 
11382 $   const char* sType = "type";
11383 
11384 $   switch (type)
11385        {
11386        case _CRT_ERROR:  $ sType = "ошибка";            break;
11387        case _CRT_ASSERT: $ sType = "логическая ошибка"; break;
11388        case _CRT_WARN:   $ sType = "возможная ошибка";  break;
11389        default:          $                              break;
11390        }
11391 
11392 $   const char* sError = _RTC_GetErrDesc (error);
11393 
11394 $$  _txError (file, line, NULL, 0, "\a"
11395               "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module);
11396 
11397     // The code below will be never executed until the error above will stay fatal:
11398 
11399     // Restore the RTC error types
11400 
11401     #if defined (_MSC_VER)
11402     #pragma warning (push)
11403     #pragma warning (disable: 6385)  // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11404     #endif
11405 
11406 $   for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR));  //-V108
11407 
11408     #if defined (_MSC_VER)
11409     #pragma warning (pop)            // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11410     #endif
11411 
11412 $   InterlockedExchange (&running, 0);
11413 $   return 1;
11414     }
11415 
11416 #pragma runtime_checks ("", restore)
11417 
11418 //-----------------------------------------------------------------------------------------------------------------
11419 
11420 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line)
11421     {
11422     #if (_TX_ALLOW_TRACE +0 >= 4)
11423 
11424     static _tx_thread int recursive = 0;
11425     if (recursive) return true;
11426     recursive++;
11427 
11428     #if (_TX_ALLOW_TRACE +0 <= 10)
11429     if (!size) return true;
11430     #endif
11431 
11432     #define GET_DESCR_(str, type)  case (type): { str = #type; break; }
11433 
11434     const char* sType = "Unknown type";
11435     const char* sUse  = "Unknown use";
11436 
11437     switch (_BLOCK_TYPE (type))
11438         {
11439         GET_DESCR_ (sType, _HOOK_ALLOC);
11440         GET_DESCR_ (sType, _HOOK_REALLOC);
11441         GET_DESCR_ (sType, _HOOK_FREE);
11442         default:   break;
11443         }
11444 
11445     switch (use)
11446         {
11447         GET_DESCR_ (sUse,  _NORMAL_BLOCK);
11448         GET_DESCR_ (sUse,  _CRT_BLOCK);
11449         GET_DESCR_ (sUse,  _CLIENT_BLOCK);
11450         GET_DESCR_ (sUse,  _FREE_BLOCK);
11451         GET_DESCR_ (sUse,  _IGNORE_BLOCK);
11452         default:   break;
11453         }
11454 
11455     #undef  GET_DESCR_
11456 
11457     _txTrace ((const char*) file, line, NULL, "%*s"
11458               "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)",
11459               2 * _txLoc::Cur.inTX, "",
11460               type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request);
11461 
11462     recursive--;
11463 
11464     #else
11465 
11466     UNREFERENCED_PARAMETER (type);
11467     UNREFERENCED_PARAMETER (data);
11468     UNREFERENCED_PARAMETER (size);
11469     UNREFERENCED_PARAMETER (use);
11470     UNREFERENCED_PARAMETER (request);
11471     UNREFERENCED_PARAMETER (file);
11472     UNREFERENCED_PARAMETER (line);
11473 
11474     #endif
11475 
11476     return true;  //-V601
11477     }
11478 
11479 //-----------------------------------------------------------------------------------------------------------------
11480 
11481 #endif // TX_COMPILED
11482 
11483 #endif
11484 
11485 //}
11486 //-----------------------------------------------------------------------------------------------------------------
11487 
11488 //-----------------------------------------------------------------------------------------------------------------
11489 //{          SEH staff
11490 //-----------------------------------------------------------------------------------------------------------------
11491 
11492 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11493 
11494 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc)
11495     {
11496     if (!_txProcessSystemWarnings)
11497         {
11498         DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11499         void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11500 
11501         if (code != DBG_PRINTEXCEPTION_C &&
11502             code != DBG_PRINTEXCEPTION_WIDE_C)
11503             {
11504             txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n",
11505                                  _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings);
11506             }
11507 
11508         return EXCEPTION_CONTINUE_SEARCH;
11509         }
11510     else
11511         {
11512         int inTX = _txLoc::Cur.inTX++;
11513 
11514         long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler");
11515 
11516         _txLoc::Cur.inTX = inTX;
11517         return ret;
11518         }
11519     }
11520 
11521 //-----------------------------------------------------------------------------------------------------------------
11522 
11523 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc)
11524     {
11525     int inTX = _txLoc::Cur.inTX++;
11526 
11527     long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter");
11528 
11529     if (_txPrevUEFilter)
11530         {
11531         if (_txSetJmp())
11532             {
11533             int inTX2 = _txLoc::Cur.inTX++;
11534 
11535             ret = _txPrevUEFilter (exc);
11536 
11537             _txLoc::Cur.inTX = inTX2;
11538             }
11539         else
11540             {
11541 $6          _txClearJmp();
11542 
11543             _TX_UNEXPECTED ("\t\a" "%s"
11544                             "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n"
11545                             "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE,
11546                             _txDumpSE + 1);
11547             }
11548         }
11549 
11550     _txLoc::Cur.inTX = inTX;
11551     return ret;
11552     }
11553 
11554 //-----------------------------------------------------------------------------------------------------------------
11555 
11556 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter)
11557     {
11558 $6  _txPrevUEFilter = filter;
11559 
11560     return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter;
11561     }
11562 
11563 //-----------------------------------------------------------------------------------------------------------------
11564 
11565 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[])
11566     {
11567     assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; }  //-V547
11568 
11569     assert (exc->ExceptionRecord);
11570 
11571     assert (func);
11572     assert (func[3] == 'V' || func[3] == 'U');
11573 
11574     bool  unhExc = (func[3] == 'U');
11575     DWORD code   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11576     void* addr   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11577 
11578     if (code == DBG_PRINTEXCEPTION_C                  ||
11579         code == DBG_PRINTEXCEPTION_WIDE_C             ||
11580         code == DBG_THREAD_NAME                       ||
11581        (code == RPC_S_SERVER_UNAVAILABLE  && !unhExc) ||
11582        (code == RPC_S_CALL_CANCELLED      && !unhExc) ||
11583        (code == EXCEPTION_BREAKPOINT && IsDebuggerPresent()))
11584         return EXCEPTION_CONTINUE_SEARCH;
11585 
11586     ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr;
11587     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11588 
11589               dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr;
11590     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11591 
11592     _txSENumber = _txSENumber + 1;
11593     if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1;
11594 
11595     OutputDebugString ("\n");
11596     txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n",
11597                          _TX_VERSION, _txSENumber, func, (unsigned long) code, addr);
11598 
11599 $6  if (*(unsigned long long*) _txDumpExceptionObjJmp)
11600         {
11601 $       longjmp (_txDumpExceptionObjJmp, 1);  //-V2512
11602         }
11603 
11604     tx_fpreset();
11605 
11606     #if defined (_MSC_VER)
11607     if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); }
11608     #endif
11609 
11610 $   bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord));  //-V560
11611 
11612 $   if (primaryException && exc)  //-V560
11613         {
11614 $       unsigned err = GetLastError();
11615 
11616 $       const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc);
11617 
11618 $       _txDumpExceptionSEH (_txDumpSE,  (intptr_t) sizeof (_txDumpSE)  - 1, exc->ExceptionRecord, func);
11619 $       _tx_snprintf_s      (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace);
11620 
11621 $       static _tx_thread DWORD prevCode = 0;
11622 $       static _tx_thread void* prevAddr = NULL;
11623 
11624 $       if (code != prevCode && addr != prevAddr &&
11625             !strstr (_txDumpSE, "Объект исключения C++:"))
11626             {
11627 $           SetLastError (err);
11628 $           _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1);
11629 
11630 $           prevCode = code;
11631 $           prevAddr = addr;
11632             }
11633 
11634 $       SetLastError (err);
11635         }
11636 
11637 $   if (_txDumpSE[0]     == '\a'                   ||
11638         _txSENumber      >= _TX_EXCEPTIONS_LIMIT+0 ||
11639         _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
11640         {
11641 $       _TX_UNEXPECTED ("\a\t" "%s"
11642                         "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.",
11643                         _txDumpSE + 1);
11644         }
11645 
11646 $   return EXCEPTION_CONTINUE_SEARCH;
11647     }
11648 
11649 //-----------------------------------------------------------------------------------------------------------------
11650 
11651 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[])  //-V2008
11652     {
11653 $6  assert (what);
11654 $   assert (size >= 0);                     //-V547
11655     assert (exc); if (!exc) {$ return 0; }  //-V547
11656 $   assert (func);
11657 
11658 $   unsigned         code   = exc->ExceptionCode;
11659 $   void*            addr   = exc->ExceptionAddress;
11660 $   unsigned         params = exc->NumberParameters;
11661 $   const ULONG_PTR* info   = exc->ExceptionInformation;
11662 $   void*            object = (params >= 2)? (void*) info[1] : NULL;
11663 
11664 $   char* s = what;
11665 
11666     #define PRINT_(...)  s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__)
11667 
11668 $   const char* sCode  = NULL;
11669 $   const char* sDescr = NULL;
11670 
11671     #define GET_DESCR_(code, descr)  case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; }
11672 
11673 $   switch (code)
11674         {
11675         GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION,         " "  "Нарушение доступа к памяти.")
11676         GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION,      " "  "Недопустимая операция.")
11677         GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION,         " "  "Привилегированная операция.")
11678         GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED,    "\a" "Выход за границы массива. Ставьте ассерты!")
11679         GET_DESCR_ (EXCEPTION_BREAKPOINT,               "\a" "Достигнута точка останова. Удачи в отладке!")
11680         GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT,    "\a" "Нарушение выравнивания данных.")
11681         GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION,      "\a" "Обработчик исключения возвратил неверное значение.")
11682         GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR,            "\a" "Невозможно загрузить нужную страницу памяти.")
11683         GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.")
11684         GET_DESCR_ (EXCEPTION_SINGLE_STEP,              "\a" "Выполнена инструкция машинного кода. Одна штука.")
11685         GET_DESCR_ (EXCEPTION_STACK_OVERFLOW,           "\a" "Ю-ху! Переполнение стека!")
11686         GET_DESCR_ (EXCEPTION_GUARD_PAGE,               "\a" "Попытка доступа к защищенной странице памяти.")
11687         GET_DESCR_ (EXCEPTION_INVALID_HANDLE,           "\a" "Неверный или уже закрытый дескриптор.")
11688         GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK,           "\a" "Возможно, взаимная блокировка ресурсов.")
11689 
11690         GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK,          "\a" "Ошибка стека при операции с плавающей точкой.")
11691         GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND,     " "  "Денормализация числа с плавающей точкой.")
11692         GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO,       " "  "Деление на ноль при операции с плавающей точкой.")
11693         GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT,       " "  "Неточный результат при операции с плавающей точкой.")
11694         GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION,    " "  "Недопустимая операция с плавающей точкой.")
11695         GET_DESCR_ (EXCEPTION_FLT_OVERFLOW,             " "  "Переполнение при операции с плавающей точкой.")
11696         GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW,            " "  "Потеря значимости при операции с плавающей точкой.")
11697         GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS,       " "  "Множественные ошибки с плавающей точкой.")
11698 
11699         GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO,       "\a" "Целочисленное деление на ноль.")
11700         GET_DESCR_ (EXCEPTION_INT_OVERFLOW,             "\a" "Переполнение при целочисленной операции.")
11701 
11702         GET_DESCR_ (EXCEPTION_CLR_FAILURE,              "\a" "Сбой среды исполнения (CLR).")
11703         GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN,        "\a" "Переполнение стекового буфера!")
11704         GET_DESCR_ (STATUS_ASSERTION_FAILURE,           "\a" "Сработал assert. На этот раз из ядра.")
11705         GET_DESCR_ (STATUS_WX86_BREAKPOINT,             "\a" "Точка останова подсистемы эмуляции x86.")
11706         GET_DESCR_ (RPC_S_UNKNOWN_IF,                   "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).")
11707         GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE,           "\a" "Сервер удаленного вызова процедур (RPC) недоступен.")
11708         GET_DESCR_ (DBG_TERMINATE_THREAD,               "\a" "Отладчик завершил поток сознания.")
11709         GET_DESCR_ (DBG_TERMINATE_PROCESS,              "\a" "Отладчик завершил процесс.")
11710         GET_DESCR_ (DBG_CONTROL_C,                      "\a" "Отладчик получил сигнал прерывания Control+C.")
11711         GET_DESCR_ (DBG_CONTROL_BREAK,                  "\a" "Отладчик получил сигнал прерывания Control+Break.")
11712         GET_DESCR_ (DBG_THREAD_NAME,                    " "  "Отладчик получил указание дать потоку имя.")
11713         GET_DESCR_ (DBG_PRINTEXCEPTION_C,               " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).")
11714         GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C,          " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).")
11715 
11716         GET_DESCR_ (EXCEPTION_CPP_MSC,                  " "  "Исключение С++, вызванное оператором throw.")
11717         GET_DESCR_ (EXCEPTION_CPP_GCC,                  " "  "Исключение С++, вызванное оператором throw.")
11718         GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND,           " "  "Исключение С++, вызванное во время раскрутки стека (rethrow?).")
11719         GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED,           " "  "Исключение С++, вызванное нарушением магии.")
11720         GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER,      "\a" "Это скомпилилось под Билдер? O_O")
11721         GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI,       "\a" "Это же С++. Как это вышло?")
11722 
11723         default: $ break;
11724         }
11725 
11726     #undef GET_DESCR_
11727 
11728 $   if (sDescr)
11729         {
11730 $       PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode);
11731         }
11732     else
11733         {
11734 $       PRINT_ ("\a#%ld: ", _txSENumber);
11735 $       s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11736                             GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11737                             s, (DWORD) (size - (s-what)), NULL) - 2;  //-V202
11738 $       PRINT_ ("\r\r");
11739         }
11740 
11741 $   PRINT_ (" (0x%X) при выполнении кода по адресу", code);
11742 $   PRINT_ ((addr? " 0x%p" : " NULL"), addr);
11743 
11744 $   Win32::SYMBOL_INFO*     sym  = NULL;
11745 $   Win32::IMAGEHLP_LINE64* line = NULL;
11746 
11747     if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); }
11748 
11749 $   if (sym  &&                   *sym->Name)      PRINT_ (" в функции %s()", sym->Name);
11750 $   if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber);
11751 
11752 $   if (code == EXCEPTION_ACCESS_VIOLATION ||
11753         code == EXCEPTION_IN_PAGE_ERROR)
11754         {
11755 $       PRINT_ (". Попытка ");
11756 
11757 $       unsigned long op = 0xBADC0DE;
11758 $       const char*  sOp = "(действие не указано)";
11759 
11760 $       if (params >= 1)
11761             {
11762 $           switch (op = (unsigned long) info[0])  //-V202
11763                 {
11764                 case 0:  $ sOp = "прочесть данные";          break;
11765                 case 1:  $ sOp = "записать данные";          break;
11766                 case 8:  $ sOp = "исполнить код";            break;
11767                 default: $ sOp = "совершить операцию 0x%lX"; break;
11768                 }
11769             }
11770 
11771 $       PRINT_ (sOp, op);
11772 
11773 $       if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); }   //-V1048
11774         else             {$ PRINT_ (" (адрес не указан)"); }
11775 
11776 $       if (code == EXCEPTION_IN_PAGE_ERROR)
11777             {
11778 $           PRINT_ (", ошибка ввода-вывода:");
11779 
11780 $           if (params >= 3)
11781                 {
11782 $               unsigned long ntstatus = (unsigned long) info[2];                                 //-V202
11783 
11784 $               PRINT_ (" 0x%lX (", ntstatus);
11785 
11786 $               s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11787                                     GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11788                                     s, (DWORD) (size - (s-what)), NULL) - 2;                      //-V202
11789 $               PRINT_ (")");
11790                 }
11791             else
11792                 {$ PRINT_ (" (не указана)"); }
11793             }
11794         }
11795 
11796 $   HMODULE module = NULL;
11797 $   _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module));
11798 
11799 $   if (module)
11800         {
11801 $       static char sModule [MAX_PATH] = "";
11802 $       int ok = GetModuleFileName (module, sModule, sizeof (sModule));
11803 
11804 $       char* ext = (ok? strrchr (sModule, '.') : NULL);
11805 $       if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule));
11806 
11807         if (ok) {$ PRINT_ (" в модуле %s",  sModule); }
11808         else    {$ PRINT_ (" в модуле 0x%p", (void*) module); }
11809         }
11810 
11811 $   PRINT_ (".");
11812 
11813 $   if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0)
11814         {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).",        _TX_EXCEPTIONS_LIMIT+0); }
11815 
11816 $   if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
11817         {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); }
11818 
11819 $   PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func);
11820 
11821 $   if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
11822         {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); }
11823 
11824 $   if (exc->ExceptionRecord)
11825         {
11826 $       PRINT_ ("\n\n" "Причина:" "\n\n");
11827 $       s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func);
11828         }
11829 
11830 $   if (code == EXCEPTION_CPP_GCC        ||
11831         code == EXCEPTION_CPP_GCC_UNWIND ||
11832         code == EXCEPTION_CPP_GCC_FORCED ||
11833         code == EXCEPTION_CPP_MSC)
11834         {
11835 $       s += _txDumpExceptionCPP (s,    size - (s-what), code, params, info);
11836         }
11837 
11838     #undef PRINT_
11839 
11840 $   while (s > what && s[-1] == '\n') s--;
11841 $   if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n");
11842 
11843 $   return s - what;
11844     }
11845 
11846 //-----------------------------------------------------------------------------------------------------------------
11847 
11848 intptr_t _txDumpExceptionCPP (char what[], intptr_t size,
11849                               unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/)
11850     {
11851 $6  assert (what);
11852 $   assert (size >= 0);  //-V547
11853 
11854 $   char* s = what;
11855 
11856 $   switch (code)
11857         {
11858         #if defined (_GCC_VER)
11859 
11860         case EXCEPTION_CPP_GCC:
11861         case EXCEPTION_CPP_GCC_UNWIND:
11862         case EXCEPTION_CPP_GCC_FORCED:
11863             {
11864             // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp
11865             //      [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below
11866             //      [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below
11867             //      [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below
11868             //      and figure above near ABI::__cxa_exception definition in this file
11869 
11870 $           const std::type_info* type   = NULL;
11871 $           void*                 object = NULL;
11872 
11873 $           if (params >= 1)
11874                 {
11875 $               _Unwind_Exception*    unwind_exception = (_Unwind_Exception*) info[0];
11876 $               ABI::__cxa_exception* cxa_exception    = (ABI::__cxa_exception*) (unwind_exception + 1) - 1;
11877 
11878 $               type   = cxa_exception->exceptionType;
11879 $               object = cxa_exception + 1;
11880                 }
11881 
11882 $           s += _txDumpExceptionObj (s, size - (s-what), object, 0, type);
11883             }
11884 $           break;
11885 
11886         case 0:  // Not called within SEH chain
11887             {
11888             // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc
11889             //       [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc
11890 
11891             using namespace abi;
11892 
11893 $           ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions;
11894 
11895 $           if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1))  // Dependent exception, case B, see pic above
11896                 {
11897 $               cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1;
11898                 }
11899 
11900 $           if (cxa_exception)
11901                 {
11902 $               verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type());
11903 
11904 $               s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType);
11905                 }
11906             }
11907 $           break;
11908 
11909         #elif defined (_MSC_VER)
11910 
11911         case EXCEPTION_CPP_MSC:
11912             {
11913             // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
11914             //     [2] http://www.openrce.org/articles/full_view/21
11915             //     [3] http://www.openrce.org/articles/full_view/23
11916             //     [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf
11917 
11918 $           const std::type_info* type   = NULL;
11919 $           void*                 object = (params >= 2)? (void*) info[1] : NULL;
11920 $           size_t                szObj  = 0;
11921 
11922 $           if (params >= 3 &&
11923                (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||
11924                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||
11925                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 ||
11926                 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1))
11927                 {
11928 $               auto throwInfo = (const Win32::ThrowInfo*) info[2];
11929 
11930 $               if (throwInfo && throwInfo->pCatchableTypeArray)
11931                     {
11932 $                   HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL;  //-V112
11933 
11934                     #define RVA_(type, addr)  ( (type) ((uintptr_t) module + (uintptr_t) (addr)) )
11935 
11936 $                   const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray);
11937 $                   const Win32::CatchableType*      cType  = RVA_(const Win32::CatchableType*,      cArray->arrayOfCatchableTypes[0]);
11938 
11939 $                   type  = RVA_(const std::type_info*, cType->pType);
11940 $                   szObj = cType->sizeOrOffset;  //-V101
11941 
11942                     #undef  RVA_
11943                     }
11944                 }
11945 
11946 $           s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type);
11947             }
11948             break;
11949 
11950         case 0:  // Not called within SEH chain
11951 
11952             // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC:
11953             //
11954             // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception.
11955             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp
11956             //
11957             // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception.
11958             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp
11959             // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp
11960             // and http://msdn.microsoft.com/en-us/library/ff730818.aspx.
11961             //
11962             // So _txDumpSE information should have been recorded during previous call. Now do nothing.
11963 
11964 $           break;
11965 
11966         #endif
11967 
11968         default:
11969 $           txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code);
11970 $           break;
11971         }
11972 
11973 $   while (s > what && s[-1] == '\n') s--;
11974 $   if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n");
11975 
11976 $   return (s - what);
11977     }
11978 
11979 //-----------------------------------------------------------------------------------------------------------------
11980 
11981 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type)  //-V2008
11982     {
11983 $6  assert (what);
11984 $   assert (size > 0);  //-V547
11985 
11986 $   static char*  s     = NULL; s     = what;
11987 $   static size_t szObj = 0;    szObj = sizeObj;
11988 
11989     #define PRINT_(...)  s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__)
11990 
11991 $   PRINT_ ("\n\n" "Объект исключения C++:");
11992 
11993 $   const char* mangledName = (type)? type->name() : NULL;
11994 
11995 $   char* typeName = NULL;
11996 $   int err = 1;
11997 
11998     #if defined (_GCC_VER)
11999 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err);
12000     #endif
12001 
12002 $   const char* name = (!err && typeName)? typeName : mangledName;  //-V560
12003 
12004 $   if (name &&
12005        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >")           == 0 ||
12006         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >")                   == 0))
12007         {$ name = "std::string"; }
12008 
12009 $   if (name &&
12010        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *")         == 0 ||
12011         strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 ||
12012         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*")                  == 0))
12013         {$ name = "std::string*"; }
12014 
12015     if (name) {$ PRINT_ (" %s", name); }
12016 
12017     #if defined (_GCC_VER)
12018 $   free (typeName);
12019     #endif
12020 
12021 $   err = 0;
12022 $   if (mangledName)
12023         {
12024         if (_txSetJmp())
12025             {
12026             #define PRINT_VAL_(fmt, typ, ...)                                                                          \
12027                 else if (*type == typeid (      typ       )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \
12028                 else if (*type == typeid (const typ       )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \
12029                 else if (*type == typeid (      typ*      )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
12030                 else if (*type == typeid (const typ*      )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
12031                 else if (*type == typeid (      typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
12032                 else if (*type == typeid (const typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); }
12033             #define NO_
12034 
12035             if (false) ;
12036             PRINT_VAL_ ("%s", char*, NO_)   PRINT_VAL_ ('%c', unsigned char,  NO_)   PRINT_VAL_ (%s,   bool, ? "true" : "false")  //-V206 //-V517
12037             PRINT_VAL_ ( %d,  int,   NO_)   PRINT_VAL_ ( %u,  unsigned int,   NO_)   PRINT_VAL_ (%g,   float,  NO_)               //-V206
12038             PRINT_VAL_ ( %hd, short, NO_)   PRINT_VAL_ ( %hu, unsigned short, NO_)   PRINT_VAL_ (%g,   double, NO_)               //-V206
12039             PRINT_VAL_ ( %ld, long,  NO_)   PRINT_VAL_ ( %lu, unsigned long,  NO_)   PRINT_VAL_ ('%c', char,   NO_)               //-V206
12040             PRINT_VAL_ ("%s", std::string, .c_str())                                                                              //-V206
12041 
12042             else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object))
12043                 {
12044 $               PRINT_ (", what(): \"%s\"", e->what());
12045                 }
12046             else
12047                 {$ err = 1; }
12048             }
12049         else
12050             {$ err = 2; }
12051         }
12052 
12053 $   _txClearJmp();
12054 
12055 $   if (err && object && szObj)
12056         {
12057 $       const unsigned char* buf = (const unsigned char*) object;
12058 
12059 $       if (szObj >= 64) szObj = 64;
12060 
12061 $       PRINT_ (", дамп: [");
12062 $       for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' );
12063 
12064 $       PRINT_ ("]");
12065 $       for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]);
12066 
12067 $       err = 0;
12068         }
12069 
12070 $   if (err)
12071         {$ PRINT_ (" = ??"); }
12072 
12073 $   PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object);  //-V560
12074 
12075     #undef PRINT_VAL_
12076     #undef PRINT_
12077     #undef NO_
12078 
12079 $   return s - what;
12080     }
12081 
12082 #endif // TX_COMPILED
12083 
12084 //}
12085 //-----------------------------------------------------------------------------------------------------------------
12086 
12087 //-----------------------------------------------------------------------------------------------------------------
12088 //{          Stack trace and debug info access
12089 //-----------------------------------------------------------------------------------------------------------------
12090 
12091 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12092 
12093 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/,
12094                                       CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/,
12095                                       HANDLE thread /*= GetCurrentThread()*/)
12096     {
12097 $6  const int maxFrames = 62;  // MS says: < 63
12098 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12099 
12100     if (framesToSkip == -1) {$ return trace; }
12101 
12102 $   static void* capture [maxFrames] = {};
12103 $   int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread);
12104 
12105 $   memset (trace, 0, sizeof (trace));
12106 $   char* s = trace;
12107 
12108 $   bool haveSrcInfo = false;
12109 
12110     #define PRINT_(...)  s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__)
12111 
12112 $   for (int i = 0, n = 0; i < frames; i++)  //-V2530
12113         {
12114 $       void* addr = capture[i];
12115 
12116 $       Win32::SYMBOL_INFO*     sym    = NULL;
12117 $       Win32::IMAGEHLP_LINE64* line   = NULL;
12118 $       const char*             module = NULL;
12119 $       const char*             source = NULL;
12120 $       bool                    inTX   = false;
12121 
12122         if (addr)                {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module);          }
12123         if (readSource && !inTX) {$        _txSymGetFromAddr ((void*) 1,        NULL, NULL,  NULL, &source, 2); }  //-V566
12124 
12125 $       int nl = 0;
12126 $       while (s > trace && s[-1] == '\n') { s--; nl++; }
12127 
12128         #if !defined (_TX_FULL_STACKTRACE)
12129 
12130 $       if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber))))
12131             {$ continue; }
12132 
12133         #endif
12134 
12135 $       PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr);
12136 $       n++;
12137 
12138         if (addr ==                    0)          {$ PRINT_ (" [Неверный фрейм]");        break; }
12139         if (addr == (void*)           -1)          {$ PRINT_ (" [Странный фрейм]");        break; }
12140         if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; }  //-V566
12141 
12142         if (module)                                {$ PRINT_ (" in %s%s",     module, ((sym && *sym->Name)? ": " : "")); }
12143         if (sym  && *sym->Name)                    {$ PRINT_ ("%s()",         sym->Name);                                }
12144         if (line && line->FileName)                {$ PRINT_ (" at %s",       line->FileName);   haveSrcInfo = true;     }
12145         if (line && line->LineNumber)              {$ PRINT_ (":%d",    (int) line->LineNumber); haveSrcInfo = true;     }
12146         if (source)                                {$ PRINT_ (":\n\n" "%s\n", source);                                   }
12147 
12148         if (sym && strcmp (sym->Name , "main") == 0) {$ break; }
12149         }
12150 
12151 $   while (s > trace && s[-1] == '\n') s--;
12152 $   *s = 0;
12153 
12154 $   int bits = sizeof (void*) * CHAR_BIT;
12155     if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ ("TXLib отмечает: Не загрузилась библиотека "); }
12156     if (!Win32::SymSetOptions)                                 {$ PRINT_ ("DbgHelp%d.dll или DbgHelp.dll", bits); }
12157     if (                         !Win32::MinGW::SymSetOptions) {$ PRINT_ ("MgwHelp%d.dll или MgwHelp.dll", bits); }
12158     if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ (". Отладочная информация недоступна :(\n"); }
12159 
12160 $   while (s > trace && s[-1] == '\n') s--;
12161 $   *s = 0;
12162 
12163 $   if (!haveSrcInfo)
12164         {$ PRINT_ ("\n\n" "TXLib печалится: Нет информации об исходных файлах. Вы не забыли опцию -g при компиляции?"); }
12165 
12166     #if defined (_MSC_VER)
12167     #pragma warning (push)
12168     #pragma warning (disable: 28199)  // Using possibly uninitialized memory '*s'
12169     #endif
12170 
12171 $   while (s > trace && s[-1] == '\n') s--;
12172 $   *s = 0;
12173 
12174     #if defined (_MSC_VER)
12175     #pragma warning (pop)             // Using possibly uninitialized memory '*s'
12176     #endif
12177 
12178     #undef PRINT_
12179 
12180 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12181 
12182     #if !defined (_TX_NO_MINIDUMP)
12183 $   _txCreateMiniDump (exc);
12184     #endif
12185 
12186 $   return trace;
12187     }
12188 
12189 //-----------------------------------------------------------------------------------------------------------------
12190 
12191 // Stack WALKING if the program is DEAD. Dead, Carl!
12192 
12193 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/,
12194                   HANDLE thread /* = GetCurrentThread()*/)
12195     {
12196 $6  namespace MinGW = Win32::MinGW;
12197 
12198 $   assert (capture);
12199 
12200 $   HANDLE process  = GetCurrentProcess();
12201 $   bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId());
12202 
12203 $   CONTEXT ctx = {};
12204 $   ctx.ContextFlags |= CONTEXT_FULL;
12205 
12206 $   int isWow64 = 0;
12207 $   if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64);
12208     else {$ return -1; }
12209 
12210 $   if (context)
12211         {
12212 $       ctx = *context;
12213         }
12214     else
12215         {
12216 $       if (thisThread)
12217             {
12218 $           _TX_CALLv (Win32::RtlCaptureContext, (&ctx));
12219             }
12220         else
12221             {
12222 $           SuspendThread (thread);  //-V720
12223 
12224 $           ctx.ContextFlags = CONTEXT_ALL;
12225 $           bool ok = !!GetThreadContext (thread, &ctx);
12226 
12227 $           if (!ok)
12228                 {
12229 $               ResumeThread (thread);
12230 $               return -1;
12231                 }
12232             }
12233         }
12234 
12235 $   Win32::STACKFRAME64 frame = {};
12236 $   frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat;
12237 
12238 $   int cpu = 0;
12239 
12240     #if defined (_WIN64)
12241 
12242 $   if (isWow64)
12243         {
12244 $       Win32::WOW64_CONTEXT wow64ctx = {};
12245 $       wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL;
12246 
12247 $       if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx)))  // This call fails in WINE,
12248             {                                                               // while EXIT_PROCESS_DEBUG_EVENT
12249             if (!thisThread) {$ ResumeThread (thread); }
12250 $           return 0;
12251             }
12252 
12253 $       cpu = IMAGE_FILE_MACHINE_I386;
12254 
12255 $       frame.AddrPC   .Offset = wow64ctx.Eip;
12256 $       frame.AddrStack.Offset = wow64ctx.Esp;
12257 $       frame.AddrFrame.Offset = wow64ctx.Ebp;
12258         }
12259     else
12260         {
12261 $       cpu = IMAGE_FILE_MACHINE_AMD64;
12262 
12263 $       frame.AddrPC   .Offset = ctx.Rip;
12264 $       frame.AddrStack.Offset = ctx.Rbp;
12265 $       frame.AddrFrame.Offset = ctx.Rsp;
12266         }
12267 
12268     #else
12269 
12270         {
12271 $       cpu = IMAGE_FILE_MACHINE_I386;
12272 
12273 $       frame.AddrPC   .Offset = ctx.Eip;
12274 $       frame.AddrStack.Offset = ctx.Ebp;
12275 $       frame.AddrFrame.Offset = ctx.Esp;
12276         }
12277 
12278     #endif
12279 
12280 $   assert (cpu);
12281 
12282     if (_txSetJmp())
12283         {
12284 $       _txSymGetFromAddr ((void*) 1);  //-V566
12285         }
12286 $   _txClearJmp();
12287 
12288 $   int  frames = -1;
12289 
12290 $   for (frames = -framesToSkip; frames < (int) szCapture; frames++)  //-V202 //-V2530
12291         {
12292 $       DWORD64 prev = frame.AddrStack.Offset;
12293 
12294         // Я злой и страшный серый walk. Я в поросятах знаю talk.
12295 
12296         if (!_txSetJmp()) {$ break; }
12297 
12298 #if   defined (_GCC_VER)
12299 
12300         if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12301                                             MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; }
12302 #elif defined (_MSC_VER)
12303 
12304 $       if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12305                                             Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; }
12306 #else
12307         #error _GCC_VER / _MSC_VER not defined
12308 #endif
12309         if (frames < 0) {$ continue; }
12310 
12311 $       void* addr = (void*) frame.AddrPC.Offset;
12312 
12313         if (frame.AddrFrame.Offset == 0)   {$ addr =          0; }  // Bad frame
12314         if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; }  // Strange frame
12315 
12316 $       assert (0 <= frames && frames < (int) szCapture);  //-V202
12317 
12318 $       capture[frames] = addr;                            //-V108
12319         }
12320 
12321 $   _txClearJmp();
12322 
12323     if (!thisThread) {$ ResumeThread (thread); }
12324 
12325 $   return frames;
12326     }
12327 
12328 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl
12329 
12330 //-----------------------------------------------------------------------------------------------------------------
12331 
12332 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/,
12333                         Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/,
12334                         const char** source /*= NULL*/, int context /*= 2*/)
12335     {
12336 $7  static HANDLE process = NULL;
12337 
12338 #if   defined (_GCC_VER)
12339     #define LIB_  Win32::MinGW
12340 
12341 #elif defined (_MSC_VER)
12342     #define LIB_  Win32
12343 
12344 #else
12345     #error _GCC_VER / _MSC_VER not defined
12346 #endif
12347 
12348 $   if (!process && addr)
12349         {
12350 $       process = GetCurrentProcess();
12351 
12352 $       DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES |
12353                         SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS;
12354 
12355 $        _TX_CALL (LIB_::SymSetOptions, (options));
12356 $        _TX_CALL (LIB_::SymInitialize, (process, NULL, true));
12357         }
12358 
12359 $   static DWORD64 mod = 0;
12360 
12361 $   if (module)
12362         {
12363 $       static char sMod [MAX_PATH] = "";
12364 $       memset (sMod, 0, sizeof (sMod));
12365 
12366 $       mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr));
12367 
12368 $       GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH);
12369 
12370 $       char* ext = strrchr (sMod, '.');
12371         if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); }
12372 
12373 $       *module = sMod;
12374         }
12375 
12376 $   static char buffer [_TX_BUFSIZE] = "";
12377 $   static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer;  //-V1032
12378 
12379 $   if (symbol)
12380         {
12381 $       memset (buffer, 0, sizeof (buffer));
12382 
12383 $       sym->MaxNameLen   = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1;
12384 $       sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO);
12385 $       unsigned long long ofs = 0;
12386 
12387 $       _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym));
12388 
12389         if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; }
12390 
12391 $       *symbol = sym;
12392         }
12393 
12394 $   static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line64) };
12395 
12396 $   if (line)
12397         {
12398 $       memset (&line64, 0, sizeof (line64));
12399 
12400 $       DWORD ofs = 0;
12401 $       _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64));
12402 
12403 $       *line = &line64;
12404         }
12405 
12406 $   if (source)
12407         {
12408 $       static char buf [_TX_BUFSIZE] = "";
12409 $       memset (buf, 0, sizeof (buf));
12410 
12411 $       if (line64.FileName && line64.LineNumber)
12412             {
12413 $           _txReadSource (buf, sizeof (buf) - 1, line64.FileName,
12414                           (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber);
12415 
12416 $           *source = buf;
12417             }
12418 
12419         if (!*source || !**source) {$ *source = NULL; }
12420         }
12421 
12422 $   if (!addr && process)
12423         {
12424 $       _TX_CALL (LIB_::SymCleanup, (process));
12425 
12426 $       process = NULL;
12427         }
12428 
12429     #if (_GCC_VER == 481)
12430     #pragma GCC diagnostic push
12431     #pragma GCC system_header
12432     #endif
12433 
12434 $   if (symbol)
12435         {
12436 $       if (strstr  (sym->Name, "::TX::")                                                  ||
12437            (strncmp (sym->Name, "_tx",  3) == 0 && isupper ((unsigned char) sym->Name[3])) ||
12438            (strncmp (sym->Name,  "tx",  2) == 0 && isupper ((unsigned char) sym->Name[2])) ||
12439             strncmp (sym->Name, "_tx_", 4) == 0                                            ||  //-V112
12440             strncmp (sym->Name,  "tx_", 3) == 0)
12441             {
12442 $           return true;
12443             }
12444 
12445     #if (_GCC_VER == 481)
12446     #pragma GCC diagnostic pop
12447     #endif
12448 
12449 $       if (!line || !line64.FileName) return false;
12450 
12451 $       intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1);
12452 
12453 $       return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) &&
12454                (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\');
12455         }
12456 
12457     #undef LIB_
12458 
12459 $   return false;
12460     }
12461 
12462 //-----------------------------------------------------------------------------------------------------------------
12463 
12464 intptr_t _txReadSource (char buf[], intptr_t size, const char file[],
12465                         int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/)
12466     {
12467 $7  assert (buf);
12468 
12469     if (!file || !*file) {$ return 0; }
12470 
12471     if (linStart < 1) {$ linStart = 1;       }
12472     if (linEnd == -1) {$ linEnd   = INT_MAX; }
12473 
12474 $   FILE* f = NULL;
12475 $   fopen_s (&f, file, "r");
12476     if (!f) {$ return 0; }
12477 
12478 $   int n = 1;
12479     while (!feof (f))
12480         {
12481         if (n >= linStart) {$ break; }
12482         while (!feof (f) && fgetc (f) != '\n')
12483             ;
12484         n++;
12485         }
12486 
12487 $   char* s = buf;
12488 
12489     #define SZ_  ( size - 3 - (s - buf) )
12490 
12491 $   while (!feof (f) && SZ_ > 0)
12492         {
12493         if (n > linEnd || _txNOP (SZ_) < 0) {$ break; }
12494 
12495         if (linMark != INT_MIN)
12496             {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : "  "), n); }
12497 
12498 $       int c = 0;
12499 $       while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c;
12500         if (c == EOF) {$ s--; }
12501 
12502         if (SZ_ > 0) {$ *s++ = '\n'; }
12503 $       n++;
12504         }
12505 
12506     if (n <= linEnd && SZ_ <= 0)
12507         {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); }
12508 
12509     #undef SZ_
12510 
12511 $   fclose (f);
12512 
12513     if (s > buf && s[-1] == '\n') {$ s--; }
12514 $   *s = 0;
12515 
12516 $   return (s - buf);
12517     }
12518 
12519 //-----------------------------------------------------------------------------------------------------------------
12520 
12521 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/)
12522     {
12523 $6  const int maxFrames = 62;  // TX says too: < 63
12524 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12525 
12526     if (framesToSkip == -1) {$ return trace; }
12527 
12528 $   memset (trace, 0, sizeof (trace));
12529 $   char* s = trace;
12530 
12531     #define SZ_  ( sizeof (trace) - 1 - 3 - (s-trace) )
12532 
12533 $   const _txLoc* loc = &_txLoc::Cur;
12534 
12535     for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; }
12536 
12537 $   for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev)
12538         {
12539         if (i < 0) {$ continue; }
12540 
12541         if (loc->func || loc->file || loc->line)
12542             {
12543 $           s += _tx_snprintf_s     (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""),
12544                                      i, loc->func, loc->file, loc->line);
12545 
12546 $           if (readSource)
12547                 {
12548 $               s += _tx_snprintf_s (s, SZ_, ":\n\n");
12549 $               s += _txReadSource  (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line);
12550                 }
12551             }
12552         }
12553 
12554     #undef SZ_
12555 
12556 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12557 
12558 $   return trace;
12559     }
12560 
12561 //-----------------------------------------------------------------------------------------------------------------
12562 
12563 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/)
12564     {
12565 $6  static char dumpName[MAX_PATH] = "";
12566     if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); }
12567 
12568 $   HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12569 
12570     if (!file || file == INVALID_HANDLE_VALUE) {$ return false; }
12571 
12572 $   Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false };
12573 $   Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory);
12574 
12575 $   bool ok = _TX_CALL (Win32::MiniDumpWriteDump, (GetCurrentProcess(), GetCurrentProcessId(), file, type,
12576                                                    ((exc)? &excInfo : NULL), NULL, NULL));
12577 $   CloseHandle (file);
12578 
12579     if (ok) {$ return true;  }
12580     else    {$ return false; }
12581     }
12582 
12583 #endif // TX_COMPILED
12584 
12585 //}
12586 //-----------------------------------------------------------------------------------------------------------------
12587 
12588 //-----------------------------------------------------------------------------------------------------------------
12589 //{          Errors reporting
12590 //-----------------------------------------------------------------------------------------------------------------
12591 
12592 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12593 
12594 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args)  //-V2008
12595     {
12596     _txErrors = _txErrors + 1;
12597 
12598     DWORD           winErr   = GetLastError();
12599 
12600     int             crtErr   = errno;
12601 
12602     #if !defined (__CYGWIN__)
12603     unsigned long   dosErr   = _doserrno;
12604     #else
12605     unsigned long   dosErr   = 0;
12606     #endif
12607 
12608     unsigned        dlgErr   = _TX_CALL (Win32::CommDlgExtendedError, ());
12609 
12610     unsigned        oglErr   = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError;
12611 
12612     unsigned        threadId = GetCurrentThreadId();
12613 
12614     enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 };
12615     unsigned options = 0;
12616 
12617     for (; msg && *msg; msg++)
12618         {
12619         if      (*msg == '\a') options |= isFatal;
12620         else if (*msg == '\v') options |= isWarning;
12621         else if (*msg == '\b') options |= noMsgBox;
12622         else if (*msg == '\f') options |= fmtOnly;
12623         else if (*msg == '\t') options |= traceSE;
12624         else break;
12625         }
12626 
12627     const char* stkTrace = NULL;
12628     const char*  txTrace = NULL; (void) txTrace;
12629 
12630     if (!(options & fmtOnly))
12631         {
12632         stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace   (2, true);
12633         txTrace  =                                                    _txCaptureStackBackTraceTX (0, true);
12634         }
12635 
12636     static char what[_TX_BIGBUFSIZE*10] = "";
12637     static char str [_TX_BIGBUFSIZE]    = "";
12638     char *s = what;
12639 
12640     #define     PRINT_(...)  s += _tx_snprintf_s  (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12641     #define    VPRINT_(...)  s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12642 
12643                 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" :
12644                                          (options & isFatal)?   "соболезнует..." :
12645                                                                 "сообщает:"));
12646                 PRINT_ ("Программа: %s", txGetModuleFileName());
12647     if (file)   PRINT_ (", файл: %s",    file);
12648     if (line)   PRINT_ (", строка: %d",  line);
12649     if (func)   PRINT_ (", функция: %s", func);
12650                 PRINT_ (",\n\n");
12651 
12652     if (msg)    PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"),
12653                VPRINT_ (msg, args);
12654 
12655     while (s > what && s[-1] == '\n') s--;
12656 
12657                 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s",
12658 
12659                         _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64,
12660 
12661                         "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace,
12662 
12663                         threadId, (threadId == _txMainThreadId)?    " (Main)"   :
12664                                   (threadId == _txCanvas_ThreadId)? " (Canvas)" : "");
12665 
12666     if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr),
12667                 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
12668                                     NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
12669                                     s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2,            //-V202
12670                 s -=  (s[-1] == '.')? 1 : 0,
12671                 PRINT_ (")");
12672 
12673     if (crtErr) PRINT_ (", errno: %d (%s)",                      crtErr, (strerror_s (str, sizeof (str), crtErr), str));
12674     if (dosErr) PRINT_ (", _doserrno: %lu (%s)",                 dosErr, (strerror_s (str, sizeof (str), dosErr), str));
12675     if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)",       oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr)));
12676     if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr);
12677 
12678     #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L)
12679                 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : "");
12680     #else
12681                 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true."  : "");
12682     #endif
12683 
12684     if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) &&
12685        (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func))
12686                 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func);
12687 
12688     txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what);
12689 
12690     if (options & fmtOnly)
12691         {
12692         SetLastError (winErr);
12693 
12694         errno = crtErr;
12695 
12696         #if !defined (__CYGWIN__)
12697         _doserrno = dosErr;
12698         #endif
12699 
12700         return what;
12701         }
12702 
12703     txSetProgress (-1, Win32::TBPF_ERROR);
12704 
12705     unsigned restore = txGetConsoleAttr();
12706     txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED);
12707     if (color) {$ txSetConsoleAttr (color); }
12708 
12709     int oldCodePage = txSetLocale();
12710 
12711     fprintf (stderr,      "\n" "--------------------------------------------------\n"
12712                                "%s\n"
12713                                "--------------------------------------------------\n",
12714                                what);
12715 
12716     if (stkTrace && strstr (stkTrace, ".exe: "))
12717         {$ fprintf (stderr,    "Стек вызовов:\n\n"
12718                                "%s\n\n"
12719                                "--------------------------------------------------\n",
12720                                stkTrace); }
12721 
12722     SetConsoleOutputCP (oldCodePage);
12723     txSetConsoleAttr (restore);
12724 
12725     if (*_txLogName) do  //-V2530
12726         {
12727         FILE* log = NULL; fopen_s (&log, _txLogName, "a");
12728         if (!log) {$ break; }
12729 
12730         fprintf (log,     "\n" "--------------------------------------------------\n"
12731                                "%s\n"
12732                                "--------------------------------------------------\n",
12733                                what);
12734 
12735         fprintf (log,          "Стек вызовов:\n\n"  //-V576
12736                                "%s\n",
12737                                (*_txTraceSE)? _txTraceSE : stkTrace);
12738 
12739         #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG)
12740 
12741         if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace)
12742             {
12743             fprintf (log, "\n" "--------------------------------------------------\n"
12744                                "Стек вызовов TX:\n\n"
12745                                "%s\n",
12746                                txTrace);
12747             }
12748 
12749         #endif
12750 
12751         fprintf (log,     "\n" "--------------------------------------------------\n"
12752                                "%s\n\n"
12753                                "--------------------------------------------------\n",
12754                                _txAppInfo());
12755         fclose (log);
12756         break;
12757         }
12758         while (false);
12759 
12760     txSleep();
12761 
12762     int ret = 0;
12763 
12764     if (!(options & noMsgBox))
12765         {
12766         txSleep (_txWindowUpdateInterval);
12767 
12768         PRINT_ ("\n" "Прервать программу?");
12769 
12770         ret = txMessageBox (what, ((options & isWarning)? "Предупреждение"   :
12771                                    (options & isFatal)?   "Фатальная ошибка" :
12772                                                           "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL);
12773         }
12774 
12775     SetLastError (winErr);
12776 
12777     errno = crtErr;
12778 
12779     #if !defined (__CYGWIN__)
12780     _doserrno = dosErr;
12781     #endif
12782 
12783     if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES)
12784         {
12785         txUnlock();
12786         _txCleanup();
12787         Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
12788         }
12789 
12790     #undef  PRINT_
12791     #undef VPRINT_
12792 
12793     return what;
12794     }
12795 
12796 //-----------------------------------------------------------------------------------------------------------------
12797 
12798 #if defined (_MSC_VER)
12799 
12800 int _txOnErrorReport (int type, const char* text, int* ret)
12801     {
12802     assert (text);
12803     assert (ret);
12804 
12805     _txErrors = _txErrors + 1;
12806 
12807     unsigned restore = txGetConsoleAttr();
12808 
12809     switch (type)
12810        {
12811        case _CRT_WARN:   txSetConsoleAttr (FOREGROUND_LIGHTRED);     break;
12812        case _CRT_ERROR:  txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break;
12813        case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW);       break;
12814        default:                                                      break;  //-V2522
12815        }
12816 
12817     const char startReport[] = "Detected memory leaks!\n",
12818                  endReport[] = "Object dump complete.\n";
12819 
12820     if (strcmp (text, startReport) == 0)  // Dirty, dirty hack. А что делать?
12821         {
12822         _txOnErrorReport (type, "\n",                                                                              NULL);
12823         _txOnErrorReport (type, _TX_VERSION " - ERROR: ",                                                          NULL);
12824         _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL);
12825         _txOnErrorReport (type, "\n",                                                                              NULL);
12826         }
12827 
12828     size_t len = strlen (text);
12829     if (text [len-1] != '\n')               txOutputDebugPrintf ("%s",                text);
12830     else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION);
12831     else                                    txOutputDebugPrintf ("%s\n",              text);
12832 
12833     DWORD n = 0;
12834     HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
12835     WriteFile (err, text, (DWORD) strlen (text), &n, NULL);      //-V202
12836 
12837     txSetConsoleAttr (restore);
12838 
12839     if (*_txLogName) do                                          //-V2530
12840         {
12841         HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12842         if (log == INVALID_HANDLE_VALUE) break;
12843 
12844         SetFilePointer (log, 0, NULL, FILE_END);
12845         WriteFile (log, text, (DWORD) strlen (text), &n, NULL);  //-V202
12846 
12847         CloseHandle (log);
12848         break;
12849         }
12850         while (false);
12851 
12852     if (ret) *ret = 0;
12853 
12854     return (type == _CRT_WARN);
12855     }
12856 
12857 #endif
12858 
12859 //-----------------------------------------------------------------------------------------------------------------
12860 
12861 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/)
12862     {
12863 $5  static wchar_t textW   [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]";
12864 $   static wchar_t headerW [_TX_BUFSIZE    * sizeof (wchar_t)] = L"[NULL header]";
12865 
12866     if (text)   {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text,   -1, textW,   sizearr (textW))   || memset (textW,   0, sizeof (textW));   }
12867     if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); }
12868 
12869 $   txSleep();
12870 
12871 $   HWND wnd = _txCanvas_Window;
12872 $   int  ret = MessageBoxW ((wnd && IsWindowVisible (wnd))? wnd : _TX_CALL (Win32::GetConsoleWindow,()),
12873                             textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST);
12874 
12875 $   GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU);
12876 
12877 $   if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU))
12878         {
12879 $       SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0);
12880 $       _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
12881         }
12882 
12883 $   return ret;
12884     }
12885 
12886 //-----------------------------------------------------------------------------------------------------------------
12887 
12888 bool txGetAsyncKeyState (int key)
12889     {
12890 $1  HWND wnd = GetForegroundWindow();
12891 
12892     return (GetAsyncKeyState (key) & 0x8000) &&
12893            (wnd == txWindow() || wnd == Win32::GetConsoleWindow());
12894     }
12895 
12896 //-----------------------------------------------------------------------------------------------------------------
12897 
12898 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...)
12899     {
12900 $5  if (_TX_ARGUMENT_FAILED (format)) return false;
12901 
12902 $   va_list arg; va_start (arg, format);
12903 $   bool ok = true;
12904 
12905     #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500)
12906 
12907 $   NOTIFYICONDATA nid = { sizeof (nid) };
12908 
12909 $   nid.uFlags      = NIF_ICON | NIF_TIP | NIF_INFO;
12910 $   nid.hWnd        = NULL;
12911 $   nid.uID         = 1;
12912 $   nid.hIcon       = _txCreateTXIcon (16); assert (nid.hIcon);
12913 $   strncpy_s       (nid.szTip,       sizeof (nid.szTip),       "TXLib Information", sizeof (nid.szTip));
12914 $   strncpy_s       (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1);
12915 $   _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg);
12916 $   nid.dwInfoFlags = flags;
12917 
12918 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo);
12919 
12920 $   ok &= !!Shell_NotifyIcon (NIM_ADD,    (::NOTIFYICONDATA*) &nid);
12921 $   ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid);
12922 
12923 $   if (nid.hIcon) DestroyIcon (nid.hIcon) asserted;
12924 
12925     #else
12926 
12927 $   char nid_szInfo[_TX_BUFSIZE] = "";
12928 $   _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg);
12929 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo);
12930 $   ok = false;
12931 
12932 $   (void)flags; (void)title;
12933 
12934     #endif
12935 
12936 $   va_end (arg);
12937     return ok;
12938     }
12939 
12940 //-----------------------------------------------------------------------------------------------------------------
12941 
12942 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...)
12943     {
12944     unsigned id = GetCurrentThreadId();
12945 
12946     const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}};
12947 
12948     char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)];
12949 
12950     char msgStr[_TX_BUFSIZE] = "";
12951     if (msg)
12952         {
12953         va_list arg; va_start (arg, msg);
12954         _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg);
12955         va_end (arg);
12956         }
12957 
12958     txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d)  " "|%*s%s" "%s%s\n",
12959 
12960                          _TX_VERSION, (void*) &_txInitialized,
12961 
12962                          "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit],
12963                          _txLoc::Cur.trace, mark,
12964 
12965                          (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line,
12966                          2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""),
12967 
12968                          ((*msgStr && func)? ": " : ""), msgStr);
12969     }
12970 
12971 //-----------------------------------------------------------------------------------------------------------------
12972 
12973 int txOutputDebugPrintf (const char* format, ...)
12974     {
12975     if (!format) return 0;
12976 
12977     enum { msgbox = 1, print = 2, compr = 4 };
12978     int options = 0;
12979 
12980     for (; format && *format; format++)
12981         {
12982         if      (*format == '\a') options |= msgbox;
12983         else if (*format == '\f') options |= print;
12984         else if (*format == '\r') options |= compr;
12985         else break;
12986         }
12987 
12988     char text[_TX_BIGBUFSIZE] = "";
12989 
12990     va_list arg; va_start (arg, format);
12991     int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg);  //-V202
12992     va_end (arg);
12993 
12994     struct __ { static int trimSpaces (char str[])
12995         {
12996         char *dst = str, *src = str;
12997 
12998         for (char d = ' '; d; src++)
12999             if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; }
13000             else                                                 *dst++ = d = *src;
13001 
13002         return (int) (dst - str - 1);  //-V202
13003         }};
13004 
13005     if (options & compr)  n = __::trimSpaces (text);
13006 
13007     OutputDebugString (text);
13008 
13009     if (options & print)  fprintf (stderr, "%s", text);
13010 
13011     if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION);
13012 
13013     return n;
13014     }
13015 
13016 //-----------------------------------------------------------------------------------------------------------------
13017 
13018 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...)
13019     {
13020     if (!format) return 0;
13021 
13022     va_list arg; va_start (arg, format);
13023     intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg);
13024     va_end (arg);
13025 
13026     return ret;
13027     }
13028 
13029 //-----------------------------------------------------------------------------------------------------------------
13030 
13031 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg)
13032     {
13033     if (!stream || !format) return 0;
13034 
13035     #if defined (_TRUNCATE)
13036     intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg);
13037     #else
13038     intptr_t ret = _vsnprintf   (stream, size,            format, arg);
13039     #endif
13040 
13041     if (ret < 0 && size >= 4)  //-V112
13042         {
13043         const char ellipsis[] = "...";
13044         size_t     szEllipsis = sizeof (ellipsis) - 1;
13045 
13046         strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis);
13047         }
13048 
13049     return (ret >= 0)? ret : size;
13050     }
13051 
13052 //-----------------------------------------------------------------------------------------------------------------
13053 
13054 #if defined (__CYGWIN__)
13055 
13056 int _getch()
13057     {
13058     termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr);
13059 
13060     termios newattr = oldattr;
13061     newattr.c_lflag &= ~(ICANON | ECHO);
13062     tcsetattr (STDIN_FILENO, TCSANOW, &newattr);
13063 
13064     int ch = getchar();
13065 
13066     tcsetattr (STDIN_FILENO, TCSANOW, &oldattr);
13067 
13068     return ch;
13069     }
13070 
13071 //-----------------------------------------------------------------------------------------------------------------
13072 
13073 int _putch (int ch)
13074     {
13075     termios old = {}; tcgetattr (STDOUT_FILENO, &old);
13076 
13077     termios cur = old;
13078     cur.c_lflag &= ~ICANON;
13079     cur.c_lflag |=  ECHO;
13080     tcsetattr (STDOUT_FILENO, TCSANOW, &cur);
13081 
13082     putchar (ch);
13083 
13084     tcsetattr (STDOUT_FILENO, TCSANOW, &old);
13085 
13086     return ch;
13087     }
13088 
13089 //-----------------------------------------------------------------------------------------------------------------
13090 
13091 int _kbhit()
13092     {
13093     termios old = {}; tcgetattr (STDIN_FILENO, &old);
13094 
13095     termios cur = old;
13096     cur.c_lflag &= ~(ICANON | ECHO);
13097     cur.c_cc[VMIN]  = 1;
13098     cur.c_cc[VTIME] = 0;
13099 
13100     tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur);
13101 
13102     fd_set  fd = {}; FD_SET (STDIN_FILENO, &fd);
13103     timeval tv = {};
13104 
13105     int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd);
13106 
13107     tcsetattr (STDIN_FILENO, TCSAFLUSH, &old);
13108 
13109     return res;
13110     }
13111 
13112 #endif
13113 
13114 #endif // TX_COMPILED
13115 
13116 //}
13117 //-----------------------------------------------------------------------------------------------------------------
13118 
13119 //-----------------------------------------------------------------------------------------------------------------
13120 //{          Information
13121 //-----------------------------------------------------------------------------------------------------------------
13122 
13123 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13124 
13125 const char* txGetModuleFileName (bool fileNameOnly /*= true*/)
13126     {
13127     static char name[MAX_PATH] = "";
13128 
13129     if (!*name)
13130         {
13131         if (!GetModuleFileName (NULL, name, sizeof (name) - 1)) *name = 0;
13132 
13133         char* ext = strrchr (name, '.');
13134         if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name));
13135         }
13136 
13137     assert (*name);
13138 
13139     if (fileNameOnly) return name;
13140 
13141     static char fullName[MAX_PATH] = "";
13142     strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1);
13143 
13144     char* title = strrchr (fullName, '\\'); if (!title) title = fullName;
13145     char* ext   = strrchr (fullName,  '.'); if (!ext)   ext   = fullName + strlen (fullName);
13146 
13147     size_t sz = sizeof (fullName) - (ext - fullName);
13148     strncpy_s (ext, sz-1, " - TXLib", sz);
13149 
13150     return title + 1;
13151     }
13152 
13153 #endif // TX_COMPILED
13154 
13155 //-----------------------------------------------------------------------------------------------------------------
13156 
13157 inline const char* _txAppInfo()
13158     {
13159 $1  time_t timeT     = time (NULL) - clock()/CLOCKS_PER_SEC;  //-V104
13160     char   timeS[32] = "";
13161     ctime_s (timeS, sizeof (timeS), &timeT);
13162 
13163     static char text[_TX_BUFSIZE] = "";
13164     char cwd [MAX_PATH] = "";
13165 
13166     _tx_snprintf_s (text, sizeof (text) - 1,
13167 
13168                     "Developed with:\n\n"
13169                     "The Dumb Artist Library (TX Library)\n"
13170                     _TX_VERSION "\n" _TX_AUTHOR "\n"
13171                     "See license on: http://txlib.ru\n\n"
13172 
13173                     "TXLib file:" "\t" __FILE__ "\n"
13174                     "Compiled:"   "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n"
13175                     "Started:"    "\t" "%.6s %.4s %.8s\n\n"
13176 
13177                     "Run file:"   "\t" "%s\n"
13178                     "Directory:"  "\t" "%s",
13179 
13180     #if   defined (_MSC_VER)
13181                     "MSVC Runtime",
13182     #elif defined (__CYGWIN__)
13183                     "Cygwin Runtime",
13184     #elif defined (_GCC_VER) && defined (_WIN64)
13185                     __mingw_get_crt_info(),
13186     #else
13187                     "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION),
13188     #endif
13189                     (sizeof (void*) == sizeof (DWORD))? 32 : 64,    //-V112
13190 
13191                     timeS + 4, timeS + 20, timeS + 11,              //-V112 These offsets are ANSI standardized
13192                     txGetModuleFileName(),
13193                     _getcwd (cwd, sizeof (cwd) - 1));
13194 
13195     return text;
13196     }
13197 
13198 //}
13199 //-----------------------------------------------------------------------------------------------------------------
13200 
13202 //}
13203 //=================================================================================================================
13204 
13205 //=================================================================================================================
13206 //{          TXLib API implementation
13207 //           Реализация TXLib API
13208 //=================================================================================================================
13209 
13210 inline const char* txVersion()
13211     {
13212     return _TX_VERSION;
13213     }
13214 
13215 //-----------------------------------------------------------------------------------------------------------------
13216 
13217 inline unsigned txVersionNumber()
13218     {
13219     return _TX_VER;  //-V2517
13220     }
13221 
13222 //-----------------------------------------------------------------------------------------------------------------
13223 
13224 inline HWND txWindow()
13225     {
13226 $9  return _txCanvas_Window;
13227     }
13228 
13229 //-----------------------------------------------------------------------------------------------------------------
13230 
13231 inline HDC& txDC()
13232     {
13233     return _txCanvas_BackBuf[0];
13234     }
13235 
13236 //-----------------------------------------------------------------------------------------------------------------
13237 
13238 inline RGBQUAD* txVideoMemory()
13239     {
13240     return _txCanvas_Pixels;
13241     }
13242 
13243 //-----------------------------------------------------------------------------------------------------------------
13244 
13245 inline int txGetExtentX (HDC dc /*= txDC()*/)
13246     {
13247     return txGetExtent (dc) .x;
13248     }
13249 
13250 //-----------------------------------------------------------------------------------------------------------------
13251 
13252 inline int txGetExtentY (HDC dc /*= txDC()*/)
13253     {
13254     return txGetExtent (dc) .y;
13255     }
13256 
13257 //-----------------------------------------------------------------------------------------------------------------
13258 
13259 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13260 
13261 POINT txGetExtent (HDC dc /*= txDC()*/)
13262     {
13263 $0  static POINT err = {-1, -1};
13264 
13265     if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; };
13266 
13267     if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; }
13268 
13269 $   BITMAP bmap = {};
13270 $   txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted;
13271 
13272 $   POINT  size = { bmap.bmWidth, bmap.bmHeight };
13273 $   return size;
13274     }
13275 
13276 //-----------------------------------------------------------------------------------------------------------------
13277 
13278 bool txDestroyWindow (HWND wnd /*= txWindow()*/)
13279     {
13280 $1  if (!wnd || !txWindow()) return false;
13281 
13282 $   if (wnd != txWindow())
13283         {
13284 $       return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd);
13285         }
13286 
13287 $   if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false;
13288 
13289 $   if (_txMain)
13290         {
13291 $       txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n"
13292                                                "Возвращайтесь через main(), там вам будут рады.\n");
13293 $       Sleep (_TX_TIMEOUT);
13294         }
13295 
13296 $   _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
13297 
13298 $   return _txCanvas_Window == NULL;
13299     }
13300 
13301 //-----------------------------------------------------------------------------------------------------------------
13302 
13303 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/)
13304     {
13305 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13306 
13307 $   HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color);
13308 
13309 $   if (!pen) return (HPEN) NULL;
13310 
13311 $   if (!_txBuffer_Select (pen, dc))
13312         {
13313 $       Win32::DeleteObject (pen);
13314 $       return (HPEN) NULL;
13315         }
13316 
13317 $   if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID)
13318         {$ return (HPEN) NULL; }
13319 
13320 $   return pen;
13321     }
13322 
13323 //-----------------------------------------------------------------------------------------------------------------
13324 
13325 COLORREF txColor (double red, double green, double blue)
13326     {
13327 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13328 $   if (green > 1) green = 1; if (green < 0) green = 0;
13329 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13330 
13331 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13332 
13333 $   return txSetColor (color)? color : CLR_INVALID;
13334     }
13335 
13336 //-----------------------------------------------------------------------------------------------------------------
13337 
13338 COLORREF txGetColor (HDC dc /*= txDC()*/)
13339     {
13340 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13341 
13342 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc);
13343 $   assert (obj); if (!obj) return CLR_INVALID;              //-V547
13344 
13345 $   union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {};  //-V2514
13346 
13347 $   int size = Win32::GetObject (obj, 0, NULL);
13348 $   Win32::GetObject (obj, sizeof (buf), &buf) asserted;
13349 
13350 $   return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor;
13351     }
13352 
13353 //-----------------------------------------------------------------------------------------------------------------
13354 
13355 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/)
13356     {
13357 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13358 
13359 $   HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color);
13360 
13361 $   return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL);
13362     }
13363 
13364 //-----------------------------------------------------------------------------------------------------------------
13365 
13366 COLORREF txFillColor (double red, double green, double blue)
13367     {
13368 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13369 $   if (green > 1) green = 1; if (green < 0) green = 0;
13370 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13371 
13372 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13373 
13374 $   return txSetFillColor (color)? color : CLR_INVALID;
13375     }
13376 
13377 //-----------------------------------------------------------------------------------------------------------------
13378 
13379 COLORREF txGetFillColor (HDC dc /*= txDC()*/)
13380     {
13381 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13382 
13383 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc);
13384 $   assert (obj); if (!obj) return CLR_INVALID;  //-V547
13385 
13386 $   LOGBRUSH buf = {};
13387 $   txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted;
13388 
13389 $   return buf.lbColor;
13390     }
13391 
13392 //-----------------------------------------------------------------------------------------------------------------
13393 
13394 bool txClear (HDC dc /*= txDC()*/)
13395     {
13396 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13397 
13398 $   POINT size = txGetExtent (dc);
13399 $   return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc);
13400     }
13401 
13402 //-----------------------------------------------------------------------------------------------------------------
13403 
13404 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/)
13405     {
13406 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13407 
13408 $   txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc);
13409 
13410 $   return true;
13411     }
13412 
13413 //-----------------------------------------------------------------------------------------------------------------
13414 
13415 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/)
13416     {
13417 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13418 $   if (green > 1) green = 1; if (green < 0) green = 0;
13419 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13420 
13421 $   return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc);
13422     }
13423 
13424 //-----------------------------------------------------------------------------------------------------------------
13425 
13426 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/)
13427     {
13428 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13429 
13430 $   return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc);
13431     }
13432 
13433 //-----------------------------------------------------------------------------------------------------------------
13434 
13435 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13436     {
13437 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13438 
13439 $   bool ok  = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc);
13440 $        ok &= txGDI ((Win32::LineTo   (dc, ROUND (x1), ROUND (y1)      )), dc);
13441 
13442 $   return ok;
13443     }
13444 
13445 //-----------------------------------------------------------------------------------------------------------------
13446 
13447 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13448     {
13449 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13450 
13451 $   return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13452     }
13453 
13454 //-----------------------------------------------------------------------------------------------------------------
13455 
13456 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/)
13457     {
13458 $1  if (_TX_ARGUMENT_FAILED    (points)) return false;
13459 $   if (_TX_DEFAULT_HDC_FAILED (dc))     return false;
13460 
13461 $   return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc);
13462     }
13463 
13464 //-----------------------------------------------------------------------------------------------------------------
13465 
13466 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13467     {
13468 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13469 
13470 $   return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13471     }
13472 
13473 //-----------------------------------------------------------------------------------------------------------------
13474 
13475 bool txCircle (double x, double y, double r)
13476     {
13477 $1  return txEllipse (x-r, y-r, x+r, y+r);
13478     }
13479 
13480 //-----------------------------------------------------------------------------------------------------------------
13481 
13482 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13483     {
13484 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13485 
13486 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13487 
13488 $   double start =  startAngle               * txPI/180,
13489            end   = (startAngle + totalAngle) * txPI/180;
13490 
13491 $   return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13492                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13493                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13494     }
13495 
13496 //-----------------------------------------------------------------------------------------------------------------
13497 
13498 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13499     {
13500 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13501 
13502 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13503 
13504 $   double start =  startAngle               * txPI/180,
13505            end   = (startAngle + totalAngle) * txPI/180;
13506 
13507 $   return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13508                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13509                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13510     }
13511 
13512 //-----------------------------------------------------------------------------------------------------------------
13513 
13514 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13515     {
13516 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13517 
13518 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13519 
13520 $   double start =  startAngle               * txPI/180,
13521            end   = (startAngle + totalAngle) * txPI/180;
13522 
13523 $   return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13524                                        ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13525                                        ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13526     }
13527 
13528 //-----------------------------------------------------------------------------------------------------------------
13529 
13530 bool txFloodFill (double x, double y,
13531                   COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/)
13532     {
13533 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13534 
13535 $   if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc);
13536 
13537 $   return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc);
13538     }
13539 
13540 //-----------------------------------------------------------------------------------------------------------------
13541 
13542 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/)
13543     {
13544 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13545 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13546 
13547 $   int len = (int) strlen (text);  //-V202
13548 $   bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc);
13549 
13550 $   return ok;
13551     }
13552 
13553 //-----------------------------------------------------------------------------------------------------------------
13554 
13555 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
13556                  unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/,
13557                  HDC dc /*= txDC()*/)
13558     {
13559 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13560 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13561 
13562 #if !defined (NDEBUG)
13563 
13564 $   if (x0 > x1)
13565         {
13566 $       SetLastError (ERROR_INVALID_DATA);
13567 $       TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1);
13568         }
13569 
13570 $   if (y0 > y1)
13571         {
13572 $       SetLastError (ERROR_INVALID_DATA);
13573 $       TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1);
13574         }
13575 
13576 #endif
13577 
13578 $   RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) };
13579 
13580 $   if (!strchr (text, '\n')) format |= DT_SINGLELINE;
13581 
13582 $   unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc);
13583 
13584 $   bool ok = false;
13585 
13586 $   if (Win32::DrawText)
13587         {
13588 $       ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc);
13589 $       Win32::GetPixel (dc, 0, 0);
13590 $       ok = true;  //-V519
13591         }
13592     else
13593         {
13594 $       txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text);
13595 $       ok = false;
13596         }
13597 
13598 $   txSetTextAlign (prev, dc);
13599 
13600 $   return ok;
13601     }
13602 
13603 //-----------------------------------------------------------------------------------------------------------------
13604 
13605 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/,
13606                     int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/,
13607                     bool strikeout /*= false*/, double angle /*= 0*/,
13608                     HDC dc /*= txDC()*/)
13609     {
13610 $1  if (_TX_ARGUMENT_FAILED    (name)) return NULL;
13611 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return NULL;
13612 
13613 $   HFONT font = txFontExist (name)?
13614                      Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3),
13615                                         ROUND (angle*10), 0, bold, italic, underline, strikeout,
13616                                         RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
13617                                         DEFAULT_QUALITY, DEFAULT_PITCH, name)
13618                      :
13619                      (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT);
13620 
13621 $   _txBuffer_Select (font, dc);
13622 
13623 $   return font;
13624     }
13625 
13626 //-----------------------------------------------------------------------------------------------------------------
13627 
13628 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/)
13629     {
13630 $1  SIZE size = {-1, -1};
13631 
13632 $   if (_TX_ARGUMENT_FAILED    (text)) return size;
13633 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return size;
13634 
13635 $   size_t len = strlen (text);
13636 $   txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted;  //-V202
13637 
13638 $   return size;
13639     }
13640 
13641 //-----------------------------------------------------------------------------------------------------------------
13642 
13643 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/)
13644     {
13645 $1  return txGetTextExtent (text, dc) .cx;
13646     }
13647 
13648 //-----------------------------------------------------------------------------------------------------------------
13649 
13650 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/)
13651     {
13652 $1  return txGetTextExtent (text, dc) .cy;
13653     }
13654 
13655 //-----------------------------------------------------------------------------------------------------------------
13656 
13657 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/)
13658     {
13659 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;  //-V601
13660 
13661 $   return txGDI ((Win32::SetTextAlign (dc, align)), dc);
13662     }
13663 
13664 //-----------------------------------------------------------------------------------------------------------------
13665 
13666 LOGFONT* txFontExist (const char name[])
13667     {
13668 $1  if (_TX_ARGUMENT_FAILED (name)) return NULL;
13669 
13670 $   static LOGFONT font = {};
13671 $   font.lfCharSet = DEFAULT_CHARSET;
13672 $   strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1);
13673 
13674 $   struct tools
13675         {
13676         static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data)
13677             {
13678 $           if (_TX_ARGUMENT_FAILED (fnt))  return 0;
13679 $           if (_TX_ARGUMENT_FAILED (data)) return 0;
13680 
13681             #ifndef __STRICT_ANSI__
13682 $           return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13683 
13684             #else
13685 $           return  strncmp  (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13686 
13687             #endif
13688             }
13689         };
13690 
13691 $   return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL;
13692     }
13693 
13694 //-----------------------------------------------------------------------------------------------------------------
13695 
13696 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/)
13697     {
13698 $1  if (_TX_ARGUMENT_FAILED    (obj)) return false;
13699 $   if (_TX_DEFAULT_HDC_FAILED (dc))  return false;
13700 
13701 $   return _txBuffer_Select (obj, dc);
13702     }
13703 
13704 //-----------------------------------------------------------------------------------------------------------------
13705 
13706 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
13707     {
13708 $1  POINT size = { ROUND (sizeX), ROUND (sizeY) };
13709 
13710 $   HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels);
13711 $   assert (dc); if (!dc) return NULL;  //-V547
13712 
13713 $   txSetDefaults (dc);
13714 
13715 $   if (!_txCanvas_UserDCs) return dc;
13716 
13717 $   txAutoLock _lock;
13718 $   _txCanvas_UserDCs->push_back (dc);
13719 
13720 $   if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE)
13721         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); }  //-V202
13722 
13723 $   return dc;
13724     }
13725 
13726 //-----------------------------------------------------------------------------------------------------------------
13727 
13728 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/)
13729     {
13730 $1  return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels);
13731     }
13732 
13733 //-----------------------------------------------------------------------------------------------------------------
13734 
13735 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)
13736     {
13737 $1  return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels);
13738     }
13739 
13740 //-----------------------------------------------------------------------------------------------------------------
13741 
13742 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/,
13743                  unsigned imageFlags /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/)
13744     {
13745 $1  if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL;
13746 
13747 $   HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL),
13748                                                  filename, imageFlags, sizeX, sizeY, loadFlags);
13749 $   if (!image) return NULL;
13750 
13751 $   HDC dc = txCreateCompatibleDC (sizeX, sizeY, image);
13752 
13753 $   if (!(loadFlags & LR_LOADFROMFILE)) return dc;
13754 
13755 $   static std::map <std::string, unsigned> loadTimes;
13756 $   std::string file = filename;
13757 $   unsigned time    = GetTickCount();
13758 
13759 $   if ((long) (time - loadTimes [file]) < _TX_TIMEOUT)
13760         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); }
13761 
13762 $   loadTimes [file] = time;
13763 
13764 $   return dc;
13765     }
13766 
13767 //-----------------------------------------------------------------------------------------------------------------
13768 
13769 bool txDeleteDC (HDC* pdc)
13770     {
13771 $1  if (_TX_ARGUMENT_FAILED (pdc)) return false;
13772 
13773 $   HDC  dc = *pdc;
13774 $   bool ok = _txBuffer_Delete (pdc);
13775 $   if (!ok) return false;
13776 
13777 $   if (!_txCanvas_UserDCs) return ok;
13778 
13779 $   txAutoLock _lock;
13780 
13781 $   for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it)
13782         if (*it == dc)
13783             {
13784 $           std::swap (*it, _txCanvas_UserDCs->back());
13785 $           _txCanvas_UserDCs->pop_back();
13786 $           break;
13787             }
13788 
13789 $   return ok;
13790     }
13791 
13792 //-----------------------------------------------------------------------------------------------------------------
13793 
13794 bool txDeleteDC (HDC dc)
13795     {
13796 $1  return txDeleteDC (&dc);
13797     }
13798 
13799 //-----------------------------------------------------------------------------------------------------------------
13800 
13801 bool txBitBlt (HDC destImage,   double xDest, double yDest, double width, double height,
13802                HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/)
13803     {
13804 $1  if (_TX_HDC_FAILED (destImage))   return false;
13805 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13806 
13807 $   POINT size = txGetExtent (sourceImage);
13808 $   if (!width)  width  = size.x;  //-V550
13809 $   if (!height) height = size.y;  //-V550
13810 
13811 $   return txGDI (!!(Win32::BitBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13812                                     sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage);
13813     }
13814 
13815 //-----------------------------------------------------------------------------------------------------------------
13816 
13817 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/)
13818     {
13819 $1  if (_TX_TXWINDOW_FAILED()) return false;
13820 
13821 $   return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource);
13822     }
13823 
13824 //-----------------------------------------------------------------------------------------------------------------
13825 
13826 bool txTransparentBlt (HDC destImage,   double xDest, double yDest, double width, double height,
13827                        HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/)
13828     {
13829     // Это проверки того, правильные ли HDC вы передали в функцию.
13830     // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а.
13831     // При первом чтении это можно пропустить.
13832 
13833 $1  if (_TX_HDC_FAILED (destImage))   return false;
13834 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13835 
13836     // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent().
13837     // При первом чтении это можно пропустить.
13838 
13839 $   POINT size = txGetExtent (sourceImage);
13840 $   if (!width)  width  = size.x;  //-V550
13841 $   if (!height) height = size.y;  //-V550
13842 
13843     // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest).
13844     // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только
13845     // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки).
13846     // При первом чтении это можно пропустить.
13847 
13848 #if !defined (NDEBUG)
13849 
13850 $   if (!(0 <= xSource && xSource + width  <= size.x &&
13851           0 <= ySource && ySource + height <= size.y))
13852         {
13853 $       SetLastError (ERROR_INVALID_DATA);
13854 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
13855                   "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
13856         }
13857 
13858 #endif
13859 
13860 $   bool ok = true;
13861 
13862 $   if (Win32::TransparentBlt)
13863         {
13864         // А вот теперь уже надо начать читать.
13865         //
13866         // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function"
13867         // и почитайте про ее параметры.
13868         //
13869         // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не
13870         // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что
13871         // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s>
13872         // это сделано для упрощения вызова функции TransparentBlt().
13873 
13874                                // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки!        // <<--
13875                                //                                                                                                          // <<--
13876                                //                                                                    |||||          ||||||                 // <<--
13877                                //                                                                    vvvvv          vvvvvv                 // <<--
13878                                                                                                                                            // <<--
13879 $       ok &= txGDI (!!(Win32::TransparentBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),               // <<<<
13880                                                sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<<
13881                                                destImage);                                                                                 // <<--
13882                                //                                                                    ^^^^^          ^^^^^^                 // <<--
13883                                //                                                                    |||||          ||||||                 // <<--
13884                                //                                                                                                          // <<--
13885         }                      // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте!     // <<--
13886     else
13887         {
13888 $       ok &= txGDI (!!(Win32::BitBlt         (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13889                                                sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
13890                                                destImage);
13891         }
13892 
13893     // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что
13894     // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s>
13895     // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL
13896     // или DirectX, будет круто. Хотя это и сложнее.</s>
13897 
13898     // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами,
13899     // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :((
13900 
13901 $   return ok;
13902     }
13903 
13904 //-----------------------------------------------------------------------------------------------------------------
13905 
13906 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
13907                        COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/)
13908     {
13909 $1  if (_TX_TXWINDOW_FAILED()) return false;
13910 
13911 $   return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor);
13912     }
13913 
13914 //-----------------------------------------------------------------------------------------------------------------
13915 
13916 bool txAlphaBlend (HDC destImage,   double xDest, double yDest, double width, double height,
13917                    HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
13918     {
13919 $1  if (_TX_HDC_FAILED (destImage))   return false;
13920 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13921 
13922 $   POINT size = txGetExtent (sourceImage);
13923 $   if (!width)  width  = size.x;  //-V550
13924 $   if (!height) height = size.y;  //-V550
13925 
13926 #if !defined (NDEBUG)
13927 
13928 $   if (!(0 <= xSource && xSource + width  <= size.x &&
13929           0 <= ySource && ySource + height <= size.y))
13930         {
13931 $       SetLastError (ERROR_INVALID_DATA);
13932 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
13933                   "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
13934         }
13935 
13936 #endif
13937 
13938 $   if (alpha < 0) alpha = 0;
13939 $   if (alpha > 1) alpha = 1;
13940 
13941 $   BITMAP bmap = { 0, 0, 0, 0, 0, 24 };
13942 $   bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap);
13943 
13944 $   BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) };  //-V112 //-V821 //-V2551
13945 
13946 $   if (Win32::AlphaBlend)
13947         {
13948 $       ok &= txGDI (!!(Win32::AlphaBlend (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13949                                            sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)),
13950                                            destImage);
13951         }
13952     else
13953         {
13954 $       ok &= txGDI (!!(Win32::BitBlt     (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13955                                            sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
13956                                            destImage);
13957 $       ok = false;  //-V519
13958         }
13959 
13960 $   return ok;
13961     }
13962 
13963 //-----------------------------------------------------------------------------------------------------------------
13964 
13965 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
13966                    double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
13967     {
13968 $1  if (_TX_TXWINDOW_FAILED()) return false;
13969 
13970 $   return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha);
13971     }
13972 
13973 //-----------------------------------------------------------------------------------------------------------------
13974 
13975 HDC txUseAlpha (HDC image)
13976     {
13977 $1  if (_TX_HDC_FAILED (image)) return NULL;
13978 
13979 $   HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP);
13980 $   if (!bitmap) return NULL;
13981 
13982 $   DIBSECTION dib = {};
13983 $   Win32::GetObject (bitmap, sizeof (dib), &dib) asserted;
13984 
13985 $   POINT      size = {  dib.dsBm.bmWidth, dib.dsBm.bmHeight };
13986 $   BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }};
13987 $   RGBQUAD*   buf  = NULL;
13988 
13989 $   bool isDIB = (dib.dsBm.bmPlanes        == 1                    &&
13990                   dib.dsBm.bmBitsPixel     == sizeof (RGBQUAD) * 8 &&
13991                   dib.dsBmih.biCompression == DIB_RGB_COLORS       &&
13992                   dib.dsBm.bmBits);
13993 $   if (!isDIB)
13994         {
13995 $       buf = new (std::nothrow) RGBQUAD [size.x * size.y];  //-V121
13996 $       if (!buf) return NULL;
13997 
13998 $       Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
13999         }
14000     else
14001         {
14002 $       buf = (RGBQUAD*) dib.dsBm.bmBits;
14003         }
14004 
14005 $   for (int y = 0; y < size.y; y++)
14006     for (int x = 0; x < size.x; x++)
14007         {
14008         RGBQUAD* color = &buf [x + y * size.x];  // Get color at (x, y) within image buffer  //-V108
14009 
14010         color->rgbRed   = (BYTE) ROUND (color->rgbRed   * color->rgbReserved / 255.0);
14011         color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0);
14012         color->rgbBlue  = (BYTE) ROUND (color->rgbBlue  * color->rgbReserved / 255.0);
14013         }
14014 
14015 $   if (!isDIB)
14016         {
14017 $       Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
14018 
14019 $       delete[] buf;
14020         }
14021 
14022 $   return image;
14023     }
14024 
14025 //-----------------------------------------------------------------------------------------------------------------
14026 
14027 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/)
14028     {
14029 $1  if (_TX_ARGUMENT_FAILED    (filename)) return false;
14030 $   if (_TX_DEFAULT_HDC_FAILED (dc))       return false;
14031 
14032 $   POINT size = txGetExtent (dc);
14033 
14034 $   size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER),  //-V119
14035            szImg  = (size.x * size.y) * sizeof (RGBQUAD);                   //-V104
14036 
14037 $   BITMAP           bmap = {};
14038 $   BITMAPFILEHEADER hdr  = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs };  //-V202
14039 $   BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB };
14040 
14041 $   RGBQUAD* buf = NULL;
14042 $   bool     ok  = true;
14043 
14044 $   ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap);
14045 
14046     if (!ok) {$ return false; }
14047 
14048 $   if (!bmap.bmBits)
14049         {
14050 $       buf =  new (std::nothrow) RGBQUAD [size.x * size.y];                //-V121
14051 $       ok &= (buf != NULL);
14052 
14053 $       int res = Win32::GetDIBits (dc,  (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y,
14054                                     buf, (BITMAPINFO*) &info, DIB_RGB_COLORS);
14055 
14056         if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); }
14057 
14058 $       ok &= !!res;
14059         }
14060     else
14061         {
14062 $       buf = (RGBQUAD*) bmap.bmBits;
14063         }
14064 
14065 $   FILE* f = NULL;
14066 $   if (ok) fopen_s (&f, filename, "wb");
14067 $   ok &= (f != NULL);
14068 
14069 $   if (ok) ok &= (fwrite (&hdr,  sizeof (hdr),  1, f) == 1);               //-V575 //-V595
14070 $   if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1);
14071 $   if (ok) ok &= (fwrite (buf,   szImg,         1, f) == 1);               //-V575
14072 
14073 $   ok &= (f && fclose (f) == 0);
14074 
14075 $   if (!bmap.bmBits)
14076         {
14077 $       delete[] buf;
14078 $       buf = NULL;
14079         }
14080 
14081 $   return ok;
14082     }
14083 
14084 //-----------------------------------------------------------------------------------------------------------------
14085 
14086 double txSleep (double time)
14087     {
14088 $1  LARGE_INTEGER start = {};
14089 $   QueryPerformanceCounter (&start) asserted;
14090 
14091 $   LARGE_INTEGER freq = {};
14092 $   QueryPerformanceFrequency (&freq) asserted;
14093 
14094 $   int lock = _txCanvas_RefreshLock;
14095 $   _txCanvas_RefreshLock = 0;
14096 
14097 $   HWND wnd = txWindow();
14098     if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
14099 
14100 $   Sleep (ROUND ((time >= 0)? time : 0));
14101 
14102 $   _txCanvas_RefreshLock = lock;
14103 
14104 $   LARGE_INTEGER stop = {};
14105 $   QueryPerformanceCounter (&stop) asserted;
14106 
14107 $   return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart;
14108     }
14109 
14110 //-----------------------------------------------------------------------------------------------------------------
14111 
14112 bool txLock (bool wait /*= true*/)
14113     {
14114 $0  if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14115 
14116 $   if (wait) {$ return      EnterCriticalSection (&_txCanvas_LockBackBuf), true; }  //-V1048
14117     else      {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf);       }
14118     }
14119 
14120 //-----------------------------------------------------------------------------------------------------------------
14121 
14122 bool txUnlock()
14123     {
14124 $0  LeaveCriticalSection (&_txCanvas_LockBackBuf);
14125 
14126 $   if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14127 $   return false;
14128     }
14129 
14130 #endif // TX_COMPILED
14131 
14132 //-----------------------------------------------------------------------------------------------------------------
14133 
14134 template <typename T>
14135 inline T txUnlock (T value)
14136     {
14137 $1  txUnlock();
14138 $   return value;
14139     }
14140 
14141 //-----------------------------------------------------------------------------------------------------------------
14142 
14143 inline void txRedrawWindow()
14144     {
14145 $1  txSleep (0);
14146     }
14147 
14148 //-----------------------------------------------------------------------------------------------------------------
14149 
14150 inline int txUpdateWindow (int update /*= true*/)
14151     {
14152 $1  return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update);
14153     }
14154 
14155 //-----------------------------------------------------------------------------------------------------------------
14156 
14157 inline int txBegin()
14158     {
14159 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1);
14160 
14161 $   return _txCanvas_RefreshLock;
14162     }
14163 
14164 //-----------------------------------------------------------------------------------------------------------------
14165 
14166 inline int txEnd()
14167     {
14168 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1);
14169 
14170 $   return _txCanvas_RefreshLock;
14171     }
14172 
14173 //-----------------------------------------------------------------------------------------------------------------
14174 
14175 inline POINT txMousePos()
14176     {
14177 $1  POINT pos = {};
14178 $   GetCursorPos (&pos);
14179 
14180 $   if (txWindow())
14181         {$ ScreenToClient (txWindow(), &pos); }
14182 
14183 $   return pos;
14184     }
14185 
14186 //-----------------------------------------------------------------------------------------------------------------
14187 
14188 inline double txMouseX()
14189     {
14190     return (double) txMousePos() .x;
14191     }
14192 
14193 //-----------------------------------------------------------------------------------------------------------------
14194 
14195 inline double txMouseY()
14196     {
14197     return (double) txMousePos() .y;
14198     }
14199 
14200 //-----------------------------------------------------------------------------------------------------------------
14201 
14202 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14203 
14204 unsigned txMouseButtons()
14205     {
14206 $1  HWND txWnd      = txWindow();
14207 $   HWND foreground = GetForegroundWindow();
14208 
14209 $   if ((txWnd && (foreground == txWnd)) ||
14210        (!txWnd && (foreground == Win32::GetConsoleWindow())))
14211         {
14212 $       return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) |  // MSB to bit 0
14213                ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) |  // MSB to bit 1
14214                ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13);   // MSB to bit 2
14215         }
14216     else
14217         {$ return 0; }
14218     }
14219 
14220 //-----------------------------------------------------------------------------------------------------------------
14221 
14222 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/)
14223     {
14224     unsigned oldAttr = txGetConsoleAttr();
14225 
14226     SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color);
14227     SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE),  (WORD) color);
14228 
14229     return oldAttr;
14230     }
14231 
14232 //-----------------------------------------------------------------------------------------------------------------
14233 
14234 unsigned txGetConsoleAttr()
14235     {
14236     CONSOLE_SCREEN_BUFFER_INFO con = {};
14237     con.wAttributes = FOREGROUND_LIGHTGRAY;
14238 
14239     GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) ||
14240     GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE),  &con);
14241 
14242     return con.wAttributes;
14243     }
14244 
14245 //-----------------------------------------------------------------------------------------------------------------
14246 
14247 POINT txSetConsoleCursorPos (double x, double y)
14248     {
14249 $1  POINT fontSz = txGetConsoleFontSize();
14250 
14251 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14252 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14253 
14254 $   COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left),
14255                   (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) };
14256 
14257 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted;
14258 
14259 $   POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14260                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14261 $   return prev;
14262     }
14263 
14264 //-----------------------------------------------------------------------------------------------------------------
14265 
14266 POINT txGetConsoleCursorPos()
14267     {
14268 $1  POINT fontSz = txGetConsoleFontSize();
14269 
14270 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14271 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14272 
14273 $   POINT  pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14274                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14275 $   return pos;
14276     }
14277 
14278 //-----------------------------------------------------------------------------------------------------------------
14279 
14280 POINT txGetConsoleExtent()
14281     {
14282 $1  CONSOLE_SCREEN_BUFFER_INFO con = {};
14283 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14284 
14285 $   POINT  size = { con.srWindow.Right  - con.srWindow.Left + 1,
14286                     con.srWindow.Bottom - con.srWindow.Top  + 1 };
14287 $   return size;
14288     }
14289 
14290 //-----------------------------------------------------------------------------------------------------------------
14291 
14292 bool txClearConsole()
14293     {
14294 $1  HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
14295 
14296 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14297 $   GetConsoleScreenBufferInfo (out, &con) asserted;
14298 
14299 $   COORD start = {con.srWindow.Left, con.srWindow.Top};
14300 
14301 $   DWORD len   = (con.srWindow.Right  - con.srWindow.Left + 1) *
14302                   (con.srWindow.Bottom - con.srWindow.Top  + 1);
14303 
14304 $   DWORD written = 0;
14305 $   FillConsoleOutputCharacter (out, 0x20 /*' '*/,    len, start, &written) asserted;  //-V112
14306 $   FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted;
14307 
14308 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted;
14309 
14310 $   return written == len;
14311     }
14312 
14313 //-----------------------------------------------------------------------------------------------------------------
14314 
14315 POINT txGetConsoleFontSize()
14316     {
14317 $1  Win32::CONSOLE_FONT_INFO font = {0, {8, 16}};
14318 
14319 $   _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font));
14320 
14321 $   SIZE size = { font.dwFontSize.X, font.dwFontSize.Y };
14322     if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); }  //-V501
14323 
14324     if (size.cx == 0) {$ size.cx = 1; }
14325     if (size.cy == 0) {$ size.cy = 1; }
14326 
14327 $   POINT sizeFont = { size.cx, size.cy };
14328 $   return sizeFont;
14329     }
14330 
14331 //-----------------------------------------------------------------------------------------------------------------
14332 
14333 bool txTextCursor (bool blink /*= true*/)
14334     {
14335 $1  bool old = _txConsole_IsBlinking;
14336 
14337 $   _txConsole_IsBlinking = blink;
14338 
14339 $   return old;
14340     }
14341 
14342 //-----------------------------------------------------------------------------------------------------------------
14343 
14344 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/)
14345     {
14346 $1  mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT;
14347 $   if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC;
14348 
14349 $   if (!filename) mode = SND_PURGE;
14350 
14351 $   return !!Win32::PlaySound (filename, NULL, mode);
14352     }
14353 
14354 //-----------------------------------------------------------------------------------------------------------------
14355 
14356 int txSpeak (const char* text, ...)
14357     {
14358 $1  bool verbose = false; (void) verbose;
14359 $   bool async   = false; (void) async;
14360 
14361 $   for (; text && *text; text++)
14362         {
14363         if      (*text == '\a') {$ async   = true; }
14364         else if (*text == '\v') {$ verbose = true; }
14365         else break;
14366         }
14367 
14368 $   char textA [_TX_BUFSIZE] = "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!";
14369 
14370 $   va_list arg; va_start (arg, text);
14371     if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); }
14372 $   va_end (arg);
14373 
14374     if (text && verbose) {$ printf ("%s", textA); }
14375 
14376 #ifdef TX_USE_SPEAK
14377 
14378 $   int time = GetTickCount();
14379 
14380 $   static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L"";
14381 $   MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW));
14382 
14383 $   static ISpVoice* voice = NULL;
14384 
14385 $   if (text && !voice)
14386         {
14387 $       HRESULT res = Win32::CoInitialize (NULL);
14388         if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); }
14389         }
14390 
14391 $   if (text && voice)
14392         {
14393 $       Win32::_fpreset();
14394 $       voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL);
14395 $       tx_fpreset();
14396         }
14397 
14398 $   if (!text && voice)
14399         {
14400 $       voice->Release();
14401 $       voice = NULL;
14402 
14403 $       Win32::CoUninitialize();
14404         }
14405 
14406 $   return (voice)? GetTickCount() - time : -1;
14407 
14408 #else
14409 
14410 $   if (text)
14411         {
14412 $       unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK);
14413 
14414 $       txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA);
14415 
14416 $       txSetConsoleAttr (oldAttr);
14417         }
14418 
14419 $   return -1;
14420 
14421 #endif
14422     }
14423 
14424 //-----------------------------------------------------------------------------------------------------------------
14425 
14426 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
14427                       double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/)
14428     {
14429 $1  if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1;
14430 
14431 $   int time = GetTickCount();  //-V2551
14432 
14433 $   static char processUID [64] = "";
14434     if (!*processUID)
14435         {
14436 $       FILETIME startTime = {}, null = {};
14437 $       GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted;
14438 $       _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo",
14439                     (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted;
14440         }
14441 
14442 $   if (!fileName)
14443         {
14444 $       _txTaskKill ("vlc.exe", processUID, 0);  // Kill'em all, by command line pattern
14445 $       return 0;
14446         }
14447 
14448 $   static const char* vlcPath = _txPlayVideo_FindVLC();
14449 
14450 $   if (!vlcPath || _access (vlcPath, 0) != 0)
14451         {
14452 $       static int once = false;  //-V601
14453 
14454 $       if (*fileName && !once++)
14455             {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org "
14456                                     "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n"
14457                                     "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n"
14458                                     "P.S. См. мое описание в TXLib Help."); }
14459 $       return INT_MIN;  //-V109
14460         }
14461 
14462 $   bool async = false;
14463     if (*fileName == '\a') {$ async = true; fileName++; }
14464 
14465 $   RECT rect = {};
14466     if (wnd) {$ GetClientRect (wnd, &rect); }
14467 
14468     if (!width)  {$ width  = rect.right;  }
14469     if (!height) {$ height = rect.bottom; }
14470 
14471     // Create a child window to hold the video stream
14472 
14473 $   const char* errPos = "ВНЕЗАПНО";
14474 
14475 $   volatile HWND child = NULL;
14476 $   if (wnd && (wnd == txWindow()))
14477         {
14478 $       const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1);
14479 
14480 $       static int number = 1;
14481 $       CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x,
14482                                     WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass };
14483 $       child = txCreateExtraWindow (createData);
14484 $       if (!child)
14485             {
14486 $           txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14487                                        strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos));
14488 $           return INT_MIN+3;  //-V109
14489             }
14490 
14491 $       BringWindowToTop (child);
14492 
14493 $       wnd = child;
14494         }
14495 
14496     // Build the command line
14497 
14498     if (!zoom && !wnd) {$ zoom = 1; }
14499 
14500 $   char sZoom [64] = "--autoscale";
14501     if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; }  //-V550
14502 
14503 $   static char cmd [MAX_PATH*2 + 1024] = "";
14504 
14505 $   _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit"
14506 
14507                  " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s"
14508 
14509                  " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging"
14510 
14511                  " --ignore-config --reset-config --no-one-instance --play-and-exit"
14512                  " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file"
14513                  " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events",
14514 
14515                  vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted;
14516 
14517 $   txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n",
14518                          x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd);
14519 $   if (!*fileName)
14520         {
14521         if (child) {$ txDestroyWindow (child); }
14522 $       return (intptr_t) cmd;
14523         }
14524 
14525 $   if (!strstr (fileName, "://") && _access (fileName, 0) != 0)
14526         {
14527 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14528                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos));
14529 
14530         if (child) {$ txDestroyWindow (child); }
14531 $       return INT_MIN+1;  //-V109
14532         }
14533 
14534     // Run VLC, run
14535 
14536 $   PROCESS_INFORMATION vlc   = {};
14537 $   STARTUPINFO         start = { sizeof (start) };
14538 $   DWORD               ret   = 0;
14539 
14540 $   if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) &&
14541         vlc.hProcess && vlc.hThread)
14542         {
14543 $       if (child)
14544             {
14545 $           assert (wnd == child);                                           //-V547
14546 $           SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess);  //-V107
14547             }
14548 
14549 $       if (!async)
14550             {
14551 $           WaitForSingleObject (vlc.hProcess, INFINITE);
14552 $           GetExitCodeProcess  (vlc.hProcess, &ret) asserted;
14553             }
14554 
14555 $       if (!child)
14556             {
14557 $           CloseHandle (vlc.hProcess) asserted;
14558             }
14559 
14560 $       CloseHandle (vlc.hThread) asserted;
14561 
14562 $       return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret);  //-V105
14563         }
14564     else
14565         {
14566 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s",
14567                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos));
14568 $       if (child)
14569             {$ txDestroyWindow (child); }
14570 
14571 $       return INT_MIN+4;  //-V112 //-V109
14572         }
14573 
14574     #undef PROCESS_UID_
14575     }
14576 
14577 //-----------------------------------------------------------------------------------------------------------------
14578 
14579 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/)
14580     {
14581 $1  return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd);
14582     }
14583 
14584 //-----------------------------------------------------------------------------------------------------------------
14585 
14586 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
14587     {
14588     const UINT_PTR checkTimer = 1;
14589 
14590     switch (msg)
14591         {
14592         case WM_CREATE:
14593             {
14594 $1          SetTimer  (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted;
14595             }
14596             break;
14597 
14598         case WM_DESTROY:
14599             {
14600 $1          KillTimer (wnd, checkTimer) asserted;
14601 
14602 $           HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14603 
14604 $           if (vlc)
14605                 {
14606 $               Win32::TerminateProcess (vlc, 0);
14607 
14608 $               CloseHandle (vlc) asserted;
14609 
14610 $               SetWindowLongPtr (wnd, GWLP_USERDATA, 0);
14611                 }
14612             }
14613             break;
14614 
14615         case WM_TIMER:
14616             {
14617             HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14618 
14619             if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT)
14620                 {
14621 $1              DestroyWindow (wnd) asserted;
14622                 }
14623             }
14624             break;
14625 
14626         default:  //-V2522
14627             break;
14628         }
14629 
14630     return DefWindowProc (wnd, msg, wpar, lpar);
14631     }
14632 
14633 //-----------------------------------------------------------------------------------------------------------------
14634 
14635 const char* _txPlayVideo_FindVLC()
14636     {
14637 $1  static char vlcPath [MAX_PATH] = "";
14638 
14639 $   if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL))
14640         {
14641         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14642         }
14643 
14644 $   if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL))
14645         {
14646         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14647         }
14648 
14649 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath)))
14650         {
14651         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14652         }
14653 
14654 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath)))
14655         {
14656 $       strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX);
14657 
14658         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14659         }
14660 
14661 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files"    "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14662         {
14663         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14664         }
14665 
14666 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14667         {
14668         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14669         }
14670 
14671 $   return NULL;
14672     }
14673 
14674 //-----------------------------------------------------------------------------------------------------------------
14675 
14676 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/)
14677     {
14678 $1  static double oldPercent = 100;
14679 
14680     if (percent < 0) {$ percent    = MIN (oldPercent, 100); }
14681     else             {$ oldPercent = percent;               }
14682 
14683 $   HRESULT res = S_FALSE;
14684 
14685     #if defined (__ITaskbarList3_INTERFACE_DEFINED__)
14686 
14687 $   HRESULT init = Win32::CoInitialize (NULL);
14688 
14689 $   bool ok = true;
14690 $   res = S_OK;
14691 
14692 $   ITaskbarList3* taskbar = NULL;
14693     if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); }
14694 $   ok &= !!taskbar && (res == S_OK);
14695 
14696     if (!wnd)              {$ wnd = txWindow(); }
14697     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14698     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14699 
14700     if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); }
14701     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14702     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14703 
14704     if (taskbar) {$ taskbar->Release(); }
14705 
14706     if (init == S_OK) {$ Win32::CoUninitialize(); }
14707 
14708     #endif
14709 
14710     (void) type; (void) wnd;
14711 
14712 $   return res;
14713     }
14714 
14715 #endif // TX_COMPILED
14716 
14717 //-----------------------------------------------------------------------------------------------------------------
14718 
14719 // +--<<< Это не те символы, что вы ищете :)
14720 // V      Полезно смотреть не только вверх, но и вниз
14721 
14722 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/)
14723     {
14724 $1  WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc;
14725 $   return  old;
14726     }
14727 
14728 //-----------------------------------------------------------------------------------------------------------------
14729 
14730 //     +--<<< А это, наконец, искомое определение этой функции.
14731 //     |      Смотрите по сторонам! Нужная вам функция где-то рядом.
14732 //     |
14733 //     v
14734 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()
14735     {
14736     txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n"
14737 
14738                   "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n"
14739 
14740                   "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. "
14741                   "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n"
14742 
14743                   "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом "
14744                   "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n"
14745 
14746                   "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы "
14747                   "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n",
14748 
14749                   "Не получилось", MB_ICONSTOP);
14750 
14751     // The truth is out there... (C++files)
14752 
14753     return false;
14754     }
14755 
14756 //-----------------------------------------------------------------------------------------------------------------
14757 
14758 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you.
14759 
14760 inline bool txDisableAutoPause()
14761     {
14762     _txExit = true;
14763     return true;
14764     }
14765 
14766 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword.
14767 
14768 //-----------------------------------------------------------------------------------------------------------------
14769 
14770 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14771 
14772 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/)
14773     {
14774 $1  assert (!_txIsBadReadPtr (address));
14775 
14776 $   const unsigned char* addr = (const unsigned char*) address;
14777 
14778 $   const int stdout_fileno = 1;           // Not all g++ packages contain STDOUT_FILENO
14779 $   const int _o_u16text    = 0x00020000;  // and _O_U16TEXT
14780 
14781 $   bool     istty   = _txIsTTY (1);
14782 
14783 $   int      mode    = _O_TEXT;
14784 $   int      oldMode = _setmode (stdout_fileno, mode);
14785 
14786 $   unsigned oldCP   =       GetConsoleOutputCP();
14787 $   unsigned cp      = 1251; SetConsoleOutputCP (cp);  //-V581
14788 
14789 $   unsigned attr    = txGetConsoleAttr();
14790 
14791 $   txSetConsoleAttr (FOREGROUND_WHITE);
14792 $   printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : ""));
14793 
14794 $   txSetConsoleAttr (FOREGROUND_YELLOW);
14795 $   for (unsigned x = 0; x < 16; x++) printf ("%02X ", x);
14796 $   for (unsigned x = 0; x < 16; x++) printf ("%X",    x);
14797 
14798 $   const wchar_t* xlat[33] = {L"\xB7"   /* 00 - NUL - NULL             */, L"\x263A" /* 01 - SOH - Start of header      */,
14799                                L"\x263B" /* 02 - STX - Start of text    */, L"\x2665" /* 03 - ETX - End of text          */,
14800                                L"\x2666" /* 04 - EOT - End of transm.   */, L"\x2663" /* 05 - ENQ - Enquiry              */,
14801                                L"\x2660" /* 06 - ACK - Acknowledgment   */, L"\x2022" /* 07 - BEL - Bell                 */,
14802                                L"\x25D8" /* 08 - BS  - Backspace        */, L"\x25CB" /* 09 - HT  - Horizontal tab       */,
14803                                L"\x25D9" /* 10 - LF  - Line feed        */, L"\x2642" /* 11 - VT  - Vertical tab         */,
14804                                L"\x2640" /* 12 - FF  - Form feed        */, L"\x266A" /* 13 - CR  - Carriage return      */,
14805                                L"\x266B" /* 14 - SO  - Shift out        */, L"\x263C" /* 15 - SI  - Shift in             */,
14806                                L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1     */,
14807                                L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3     */,
14808                                L"\xB6"   /* 20 - DC4 - Device control 4 */, L"\xA7"   /* 21 - NAK - Negative ACK         */,
14809                                L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */,
14810                                L"\x2191" /* 24 - CAN - Cancel           */, L"\x2193" /* 25 - EM  - End of medium        */,
14811                                L"\x2192" /* 26 - SUB - Substitute       */, L"\x2190" /* 27 - ESC - Escape               */,
14812                                L"\x221F" /* 28 - FS  - File separator   */, L"\x2194" /* 29 - GS  - Group separator      */,
14813                                L"\x25B2" /* 30 - RS  - Record separator */, L"\x25BC" /* 31 - US  - Unit separator       */,
14814                                L"\x20"   /* 32 - Space */};
14815 
14816 $   for (int y = 0; y < 16; y++, addr += 16)
14817         {
14818         if (cp   != 1251) SetConsoleOutputCP (cp = 1251);  //-V581
14819         (void)_setmode (stdout_fileno, mode = oldMode);
14820 
14821         txSetConsoleAttr (FOREGROUND_YELLOW);
14822 
14823         printf ("\n" "%*p ", (int) sizeof (address) * 2, addr);
14824 
14825         int color = FOREGROUND_LIGHTGREEN;
14826 
14827         for (unsigned x = 0; x < 16; x++)
14828             {
14829             txSetConsoleAttr (color + x/4%2);  //-V112
14830             printf ("%02X ", addr[x]);
14831             }
14832 
14833         for (unsigned x = 0; x < 16; x++)
14834             {
14835             txSetConsoleAttr (color + x/4%2);  //-V112
14836 
14837             unsigned char ch = addr[x];
14838 
14839             if (ch >= sizearr (xlat) || !istty)
14840                 {
14841                 if (cp   != oldCP)      SetConsoleOutputCP (cp = oldCP);  //-V581
14842                 if (mode != oldMode)    (void)_setmode (stdout_fileno, mode = oldMode);
14843 
14844                 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' ');
14845                 }
14846             else
14847                 {
14848                 if (cp   != 1251)       SetConsoleOutputCP (cp = 1251);   //-V581
14849                 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text);
14850 
14851                 wprintf (L"%lls", xlat[ch]);
14852                 }
14853             }
14854         }
14855 
14856 $   (void)_setmode (stdout_fileno, oldMode);
14857 $   printf ("\n");
14858 
14859 $   if (pause && istty)
14860         {
14861 $       txSetConsoleAttr (FOREGROUND_DARKGRAY);
14862 $       txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP);
14863         }
14864 
14865 $   txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
14866 $   printf ("\n");
14867 
14868 $   txSetConsoleAttr (attr);
14869 $   SetConsoleOutputCP (oldCP);
14870     }
14871 
14872 //-----------------------------------------------------------------------------------------------------------------
14873 
14874 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/,
14875                         bool readSource /*= true*/)
14876     {
14877 $1  unsigned attr = txGetConsoleAttr();
14878 $   txSetConsoleAttr (FOREGROUND_LIGHTCYAN);
14879 
14880 $   fprintf (stderr, "\n" "--------------------------------------------------\n"
14881                           "Трассировка стека из \"%s\" at %s:%d:\n\n"
14882                           "%s\n\n"
14883                           "--------------------------------------------------\n\n",
14884                           func, file, line, _txCaptureStackBackTrace (1, readSource));
14885 
14886 $   txSetConsoleAttr (attr);
14887     }
14888 
14889 //-----------------------------------------------------------------------------------------------------------------
14890 
14891 char* txDemangle (const char* mangledName, std::nomeow_t)
14892     {
14893 $1  if (!mangledName) return NULL;
14894 
14895 $   char* typeName = NULL;
14896 
14897     #if defined (_GCC_VER)
14898 
14899 $   int err = 1;
14900 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err;
14901     if (typeName) {$ return typeName; }
14902 
14903     #endif
14904 
14905 $   unsigned short flags = 0;
14906 
14907 $   if (mangledName[0] == '.')
14908         {
14909 $       mangledName++;
14910 $       flags = 0x2800;  // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY
14911         }
14912 
14913 $   typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags));
14914     if (typeName) {$ return typeName; }
14915 
14916 $   return _strdup (mangledName);
14917     }
14918 
14919 //-----------------------------------------------------------------------------------------------------------------
14920 
14921 std::string txDemangle (const char* mangledName)
14922     {
14923 $1  char* typeName = txDemangle (mangledName, std::nomeow);
14924 $   std::string name (typeName? typeName : "");
14925 $   free (typeName);
14926 
14927 $   return name;
14928     }
14929 
14930 //-----------------------------------------------------------------------------------------------------------------
14931 
14932 double txQueryPerformance()
14933     {
14934 $1  int maxTime    =  500;
14935 $   int maxSamples =  100;
14936 $   POINT size     = {100, 100};
14937 
14938 $   HDC dc = _txBuffer_Create (txWindow(), &size, NULL);
14939 $   assert (dc); if (!dc) return -1;                                     //-V547
14940 
14941 $   DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1);  //-V202
14942 $   assert (mask);
14943 
14944 $   LARGE_INTEGER freq = {};
14945 $   QueryPerformanceFrequency (&freq) asserted;
14946 
14947 $   LARGE_INTEGER start = {};
14948 $   QueryPerformanceCounter (&start) asserted;
14949 
14950 $   int samples = 0;
14951 $   while (samples++ < maxSamples)
14952         {
14953 $       LARGE_INTEGER cur = {};
14954 $       QueryPerformanceCounter (&cur) asserted;
14955 
14956 $       double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart;
14957 $       if (t > maxTime) break;
14958 
14959         // Draw test scene
14960 
14961 $       for (int y = 0; y < size.y; y++)
14962         for (int x = 0; x < size.x; x++)     txSetPixel (x, y, TX_BLACK, dc);
14963 
14964 $       for (int y = 0; y < size.y; y += 10)
14965         for (int x = 0; x < size.x; x += 50) txTextOut  (x, y, "*", dc);
14966 
14967 $       txEllipse (0, 0, size.x, size.y, dc);
14968 $       txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc);
14969 
14970 $       txBitBlt (dc, size.x/2.0,          0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
14971 $       txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc,          0, size.y/2.0) asserted;
14972 $       txBitBlt (dc,          0, size.y/2.0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
14973 $       txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, size.x/2.0,          0) asserted;
14974         }
14975 
14976 $   mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask);  //-V106 //-V202
14977 $   assert (mask);
14978 
14979 $   _txBuffer_Delete (&dc);
14980 
14981 $   return 3.0 * samples / sqrt (1.0 * size.x * size.y);
14982     }
14983 
14984 //-----------------------------------------------------------------------------------------------------------------
14985 
14986 unsigned txExtractColor (COLORREF color, COLORREF component)
14987     {
14988 $1  switch (component)
14989         {
14990         case TX_RED:
14991         case TX_HUE:        $ return (color >>  0) & 0xFF;
14992 
14993         case TX_GREEN:
14994         case TX_SATURATION: $ return (color >>  8) & 0xFF;
14995 
14996         case TX_BLUE:
14997         case TX_LIGHTNESS:  $ return (color >> 16) & 0xFF;
14998 
14999         default:            $ return CLR_INVALID;
15000         }
15001     }
15002 
15003 //-----------------------------------------------------------------------------------------------------------------
15004 
15005 COLORREF txRGB2HSL (COLORREF rgbColor)
15006     {
15007 $1  struct xRGB
15008         {
15009         static bool zero (double val)
15010             {
15011             const double prec = 0.001;
15012 
15013             return (fabs (val) < prec);
15014             }
15015         };
15016 
15017 $   double r  = txExtractColor (rgbColor, TX_RED)   / 255.0,  //-V2551
15018            g  = txExtractColor (rgbColor, TX_GREEN) / 255.0,  //-V2551
15019            b  = txExtractColor (rgbColor, TX_BLUE)  / 255.0,  //-V2551
15020 
15021            m1 = MAX (MAX (r, g), b),
15022            m2 = MIN (MIN (r, g), b),
15023            dm = m1 - m2,
15024            sm = m1 + m2,
15025 
15026            h  = 0,
15027            s  = 0,
15028            l  = sm / 2;
15029 
15030 $   if (!xRGB::zero (dm))
15031         {
15032 $       sm = (sm <= 1)? sm : (2-sm);
15033 $       s = (!xRGB::zero (sm))? dm/sm : 0;
15034 
15035 $       double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0,
15036                cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0,
15037                cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0;
15038 
15039 $       if (xRGB::zero (r - m1)) h =     cb - cg;
15040 $       if (xRGB::zero (g - m1)) h = 2 + cr - cb;
15041 $       if (xRGB::zero (b - m1)) h = 4 + cg - cr;
15042         }
15043 
15044 $   h = (h >= 0)? h*60 : h*60 + 360;
15045 
15046 $   return RGB (ROUND (h / 360.0 * 256), ROUND (s * 255), ROUND (l * 255));
15047     }
15048 
15049 //-----------------------------------------------------------------------------------------------------------------
15050 
15051 COLORREF txHSL2RGB (COLORREF hslColor)
15052     {
15053 $1  struct xRGB
15054         {
15055         static double calc (double h, double m1, double m2)
15056             {
15057 $2          while (h < 0)   h += 360;
15058 $           while (h > 360) h -= 360;
15059 
15060 $           return (h <  60)? m1 + (m2-m1) *      h  / 60 :
15061                    (h < 180)? m2 :
15062                    (h < 240)? m1 + (m2-m1) * (240-h) / 60 :
15063                               m1;
15064             }
15065         };
15066 
15067 $   int    si = txExtractColor (hslColor, TX_SATURATION);
15068 
15069 $   double h  = txExtractColor (hslColor, TX_HUE)        / 256.0 * 360,
15070            s  = txExtractColor (hslColor, TX_SATURATION) / 255.0,
15071            l  = txExtractColor (hslColor, TX_LIGHTNESS)  / 255.0,
15072 
15073            m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s,
15074            m1 = 2 * l - m2,
15075 
15076            r = (si)? xRGB::calc (h + 120, m1, m2) : l,
15077            g = (si)? xRGB::calc (h,       m1, m2) : l,
15078            b = (si)? xRGB::calc (h - 120, m1, m2) : l;
15079 
15080 $   return RGB (ROUND (r * 255), ROUND (g * 255), ROUND (b * 255));
15081     }
15082 
15083 //-----------------------------------------------------------------------------------------------------------------
15084 
15085 void tx_fpreset()
15086     {
15087 $1  txAutoLock _lock;
15088 
15089 $   Win32::_fpreset();
15090 
15091 $   unsigned new87 = 0x0008001C;  // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW
15092 
15093     #if !defined (__CYGWIN__)
15094 
15095 $   unsigned old87 = 0;
15096 $   if (_controlfp_s (&old87, 0, 0) == 0)
15097         {$ (void) _controlfp_s (&old87, old87  & ~new87, 0x0008001F); }  // _MCW_EM
15098 
15099     #else
15100 
15101 $   Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F);    // _MCW_EM
15102 
15103     #endif
15104     }
15105 
15106 #endif // TX_COMPILED
15107 
15108 //-----------------------------------------------------------------------------------------------------------------
15109 
15110 #if defined (_TX_CPP11)
15111 template <int txFramesToAverage>
15112 #endif
15113 
15114 double txGetFPS (int minFrames)
15115     {
15116 $1  static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0);
15117 $                     LARGE_INTEGER time  = {};                      QueryPerformanceCounter (&time);
15118 
15119 $   if (time.QuadPart - time0.QuadPart == 0)
15120         {$ return 0; }
15121 
15122 $   LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq);
15123 
15124 $   double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart);
15125 $   time0 = time;
15126 
15127 $   if (txFramesToAverage == 0) return fps;
15128 
15129 $   static _tx_thread double average [txFramesToAverage] = {};
15130 $   static _tx_thread unsigned n = 0;
15131 
15132 $   average [n++ % txFramesToAverage] = fps;
15133 
15134 $   unsigned nn = MIN (n, (unsigned) sizearr (average));
15135 
15136 $   fps = 0;
15137 $   for (unsigned i = 0; i < nn; i++) fps += average[i];
15138 $   fps /= nn;
15139 
15140 $   return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0;
15141     }
15142 
15143 //-----------------------------------------------------------------------------------------------------------------
15144 
15145 template <typename T>
15146 inline T zero() { T __zero = {}; return __zero; }
15147 
15148 //-----------------------------------------------------------------------------------------------------------------
15149 
15150 inline double random (std::nomeow_t, double left, double right)
15151     {
15152     return left + (right - left) * ((double) rand() / RAND_MAX);
15153     }
15154 
15155 //-----------------------------------------------------------------------------------------------------------------
15156 
15157 template <typename Tx, typename Ta, typename Tb>
15158 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b)
15159     {
15160     return a <= x && x <= b;
15161     }
15162 
15163 //-----------------------------------------------------------------------------------------------------------------
15164 
15165 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)
15166     {
15167     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15168     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15169 
15170     return In (std::nomeow, pt.x, rect.left, rect.right) &&
15171            In (std::nomeow, pt.y, rect.top,  rect.bottom);
15172     }
15173 
15174 //-----------------------------------------------------------------------------------------------------------------
15175 
15176 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect)
15177     {
15178     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15179     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15180 
15181     return In (std::nomeow, pt.X, rect.Left, rect.Right) &&
15182            In (std::nomeow, pt.Y, rect.Top,  rect.Bottom);
15183     }
15184 
15185 //-----------------------------------------------------------------------------------------------------------------
15186 
15187 inline int random (int range)
15188     {
15189     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15190 
15191     return rand() % range;
15192     }
15193 
15194 //-----------------------------------------------------------------------------------------------------------------
15195 
15196 inline double random (double left, double right)
15197     {
15198     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15199 
15200     return random (std::nomeow, left, right);
15201     }
15202 
15203 //-----------------------------------------------------------------------------------------------------------------
15204 
15205 template <typename Tx, typename Ta, typename Tb>
15206 inline bool In (Tx x, Ta a, Tb b)
15207     {
15208     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15209 
15210     return In (std::nomeow, x, a, b);
15211     }
15212 
15213 //-----------------------------------------------------------------------------------------------------------------
15214 
15215 inline bool In (const POINT& pt, const RECT& rect)
15216     {
15217     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15218 
15219     return In (std::nomeow, pt, rect);
15220     }
15221 
15222 //-----------------------------------------------------------------------------------------------------------------
15223 
15224 inline bool In (const COORD& pt, const SMALL_RECT& rect)
15225     {
15226     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15227 
15228     return In (std::nomeow, pt, rect);
15229     }
15230 
15231 //}
15232 //=================================================================================================================
15233 
15234 //=================================================================================================================
15235 //{          txPrintf() implementation
15236 //           Реализация txPrintf()
15237 //=================================================================================================================
15238 
15239 #if defined (_TX_CPP11)
15240 
15241 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt,                                  const T& arg, ArgsT... args);
15242 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width,                   const T& arg, ArgsT... args);
15243 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt,                precision_t prec, const T& arg, ArgsT... args);
15244 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args);
15245                                          void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15246 
15247 template <typename T>                    void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg);
15248                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int*     arg);
15249                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15250 
15251 //-----------------------------------------------------------------------------------------------------------------
15252 
15253 template <typename T, typename... ArgsT>
15254 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args)
15255     {
15256 $1  assert (fmt);
15257 
15258 $   _txPrintV (stream, format, n,   fmt);
15259 
15260     if (fmt[0] == '%') {$}
15261     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15262 
15263 $   _txPrintV (stream, format, n,   fmt, arg);
15264 
15265 $   _txPrintF (stream, format, n+1, fmt, args...);
15266     }
15267 
15268 //-----------------------------------------------------------------------------------------------------------------
15269 
15270 template <typename T, typename... ArgsT>
15271 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args)
15272     {
15273 $1  assert (&stream);
15274 $   assert (fmt);
15275 
15276 $   _txPrintV (stream, format, n,   fmt);
15277 
15278     if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); }  //-V2006
15279     else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); }
15280 
15281 $   _txPrintV (stream, format, n,   fmt, arg);
15282 
15283 $   _txPrintF (stream, format, n+1, fmt, args...);
15284     }
15285 
15286 //-----------------------------------------------------------------------------------------------------------------
15287 
15288 template <typename T, typename... ArgsT>
15289 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args)
15290     {
15291 $1  assert (&stream);
15292 $   assert (fmt);
15293 
15294 $   _txPrintV (stream, format, n,   fmt);
15295 
15296     if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((std::streamsize) (prec + 1)); }  //-V2006 //-V1028
15297     else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); }
15298 
15299 $   _txPrintV (stream, format, n,   fmt, arg);
15300 
15301 $   _txPrintF (stream, format, n+1, fmt, args...);
15302     }
15303 
15304 //-----------------------------------------------------------------------------------------------------------------
15305 
15306 template <typename T, typename... ArgsT>
15307 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args)
15308     {
15309 $1  assert (&stream);
15310 $   assert (fmt);
15311 
15312 $   _txPrintV (stream, format, n,   fmt);
15313 
15314     if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((std::streamsize) (prec + 1)); }  //-V2006 //-V1028
15315     else {$ TX_ERROR ("\"%%*.*\" required to setwidth (%d) and setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, prec, fmt, txTypename (arg), n, format); }
15316 
15317 $   _txPrintV (stream, format, n,   fmt, arg);
15318 
15319 $   _txPrintF (stream, format, n+1, fmt, args...);
15320     }
15321 
15322 //-----------------------------------------------------------------------------------------------------------------
15323 
15324 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt)
15325     {
15326 $1  assert (fmt);
15327 
15328 $   _txPrintV (stream, format, n,   fmt);
15329 
15330     if (!fmt[0]) {$}
15331     else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); }
15332     }
15333 
15334 //-----------------------------------------------------------------------------------------------------------------
15335 
15336 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt)
15337     {
15338 $1  assert (&stream);
15339 $   assert (fmt);
15340 
15341 $   while (*fmt)
15342         {
15343         if (fmt[0] == '%')
15344             {
15345             if (fmt[1] == '%') fmt++;
15346             else break;
15347             }
15348 
15349         stream << *fmt++;
15350         }
15351 $   }
15352 
15353 //-----------------------------------------------------------------------------------------------------------------
15354 
15355 template <typename T>
15356 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg)
15357     {
15358 $1  assert (&stream);
15359 $   assert (fmt);
15360 
15361 $   if (_TX_ARGUMENT_FAILED (&arg)) return;
15362 
15363     if (fmt[0] == '%') {$}
15364     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15365 
15366 $   fmt++;
15367 
15368 $   char                    oldFill  = stream.fill (' ');
15369 $   std::ios_base::fmtflags oldFlags = stream.flags();
15370 
15371 $   for (;;) switch (*fmt)
15372         {
15373         case '-': $ stream << std::left;     fmt++; break;
15374         case '+': $ stream << std::showpos;  fmt++; break;
15375         case ' ': $ stream.fill (' ');       fmt++; break;
15376         case '#': $ stream << std::showbase; fmt++; break;
15377         case '0': $ stream.fill ('0');       fmt++; break;
15378 
15379         default:  $ goto end;
15380         }
15381     end:
15382 
15383 $   int width = (*fmt != '*')?                  (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0);
15384 $   int prec  = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0;
15385 
15386     if (width) {$ stream << std::setw (width);        }
15387     if (prec)  {$ stream << std::setprecision (prec); }
15388 
15389 $   fmt += strspn (fmt, "hljztL");
15390 
15391 $   switch (*fmt)
15392         {
15393         case '$':
15394         case '?': $                                              break;
15395 
15396         case 'd':
15397         case 'i':
15398         case 'u': $ stream << std::dec;                          break;
15399 
15400         case 'o': $ stream << std::oct;                          break;
15401 
15402         case 'x': $ stream << std::hex;                          break;
15403         case 'X': $ stream << std::hex        << std::uppercase; break;
15404 
15405         case 'f': $ stream << std::fixed;                        break;
15406         case 'F': $ stream << std::fixed      << std::uppercase; break;
15407 
15408         case 'e': $ stream << std::scientific;                   break;
15409         case 'E': $ stream << std::scientific << std::uppercase; break;
15410 
15411         case 'g': $                                              break;
15412         case 'G': $ stream                    << std::uppercase; break;
15413 
15414         case 'a': $                                              break;
15415         case 'A': $ stream                    << std::uppercase; break;
15416 
15417         case 'c':
15418         case 's':
15419         case 'p': $                                              break;
15420 
15421         default:  $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break;
15422         }
15423 
15424 $   fmt++;
15425 
15426     if (&arg) {$ stream << arg;      }
15427     else      {$ stream << "(null)"; }
15428 
15429 $   stream.fill  (oldFill);
15430 $   stream.flags (oldFlags);
15431     }
15432 
15433 //-----------------------------------------------------------------------------------------------------------------
15434 
15435 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg)  //-V2009
15436     {
15437 $1  assert (fmt);
15438 
15439     if (_TX_ARGUMENT_FAILED (arg)) return;
15440 
15441     if (fmt[0] == '%' && fmt[1] == 'n') {$}
15442     else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); }
15443 
15444 $   *arg = (int) stream.str().length();  //-V202
15445 
15446 $   fmt += 2;
15447     }
15448 
15449 //-----------------------------------------------------------------------------------------------------------------
15450 
15451 template <typename T> inline const T&    _txPrintfNormalizeArg (const T&           arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;}          return arg;         }
15452                       inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); }
15453 
15454 //-----------------------------------------------------------------------------------------------------------------
15455 
15456 template <typename... ArgsT>
15457 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args)
15458     {
15459 $1  if (_TX_ARGUMENT_FAILED (&stream)) return 0;
15460 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15461 
15462 $   const char* fmt = format;
15463 $   _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...);
15464 
15465 $   return (int) stream.str().length();  //-V202
15466     }
15467 
15468 //-----------------------------------------------------------------------------------------------------------------
15469 
15470 template <typename... ArgsT>
15471 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args)
15472     {
15473 $1  if (_TX_ARGUMENT_FAILED (&buffer)) return 0;
15474 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15475 
15476 $   if (size > 0) size--;
15477 $   buffer[size] = 0;
15478 
15479 $   if (!size) return 0;
15480 
15481 $   std::ostringstream stream;
15482 $   stream.rdbuf() -> pubsetbuf (buffer, size);
15483 
15484 $   txPrintf (stream, format, args...);
15485 
15486 $   return (int) stream.str().length();  //-V202
15487     }
15488 
15489 //-----------------------------------------------------------------------------------------------------------------
15490 
15491 template <typename... ArgsT>
15492 inline std::string txFormat (const char* format, ArgsT... args)
15493     {
15494 $1  if (_TX_ARGUMENT_FAILED (&format)) return "";
15495 
15496 $   std::ostringstream stream;
15497 
15498 $   txPrintf (stream, format, args...);
15499 
15500 $   return stream.str();
15501     }
15502 
15503 //-----------------------------------------------------------------------------------------------------------------
15504 
15505 template <typename... ArgsT>
15506 inline int txPrintf (const char* format, ArgsT... args)
15507     {
15508 $1  if (_TX_ARGUMENT_FAILED (&format)) return 0;
15509 
15510 $   return printf ("%s", txFormat (format, args...) .c_str());
15511     }
15512 
15513 #endif
15514 
15515 //-----------------------------------------------------------------------------------------------------------------
15516 
15517        int _txPrintfCheck (const char* format, ...) tx_printfy (1);
15518 inline int _txPrintfCheck (const char*,        ...) { return 0; }
15519 
15520 //}
15521 //=================================================================================================================
15522 
15523 //=================================================================================================================
15524 //{          txDialog methods implementation
15525 //           Реализация методов класса txDialog
15526 //
15527 //           See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx
15528 //               [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743
15529 //               [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753
15530 //=================================================================================================================
15531 
15532 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
15533 
15534 txDialog::txDialog () :
15535     layout_ (NULL)
15536     {$1}
15537 
15538 //-----------------------------------------------------------------------------------------------------------------
15539 
15540 txDialog::txDialog (const Layout* layout) :
15541     layout_ (layout)
15542     {$1}
15543 
15544 //-----------------------------------------------------------------------------------------------------------------
15545 
15546 const txDialog::Layout* txDialog::setLayout (const Layout* layout)
15547     {
15548 $1  assert (layout);
15549 
15550 $   return ::std::swap (layout_, layout), layout;
15551     }
15552 
15553 //-----------------------------------------------------------------------------------------------------------------
15554 
15555 intptr_t txDialog::dialogBox (WORD resourceID)
15556     {
15557 $1  const char* resName = (char*)(uintptr_t) resourceID;
15558 
15559 $   if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0;
15560 
15561 $   return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15562     }
15563 
15564 //-----------------------------------------------------------------------------------------------------------------
15565 
15566 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/)
15567     {
15568 $1  if (!layout)  layout = layout_;
15569 $   if (!layout)  return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0;
15570 
15571 $   if (!bufsize) bufsize = 1024;
15572 
15573 $   DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize);
15574 $   if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0;
15575 
15576 $   const Layout* dlg = &layout[0];
15577 $   const Layout  def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 };
15578 
15579 $   void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize,
15580                                        (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0,
15581                                         dlg->x, dlg->y, dlg->sx, dlg->sy,
15582                                         dlg->caption?  dlg->caption  : def.caption,
15583                                         dlg->font?     dlg->font     : def.font,
15584                                         dlg->fontsize? dlg->fontsize : def.fontsize, NULL);
15585 $   WORD i = 0;
15586 $   for (i = 1; layout[i].wndclass != END; ++i)
15587         {
15588 $       const Layout* item = &layout[i];
15589 
15590 $       ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl),
15591                                    item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy,
15592                                    item->id, (const char*)(uintptr_t) item->wndclass, item->caption);
15593         }
15594 
15595 $   tmpl->cdit = (unsigned short) (i-1);
15596 
15597 $   intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15598 
15599 $   GlobalFree (tmpl);
15600 
15601 $   return res;
15602     }
15603 
15604 //-----------------------------------------------------------------------------------------------------------------
15605 
15606 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM)
15607     {
15608 $1  switch (msg)
15609         {
15610         case WM_INITDIALOG: $ SetForegroundWindow (wnd);
15611                             $ break;
15612 
15613         case WM_COMMAND:    $ switch (LOWORD (wParam))
15614             {
15615             case IDOK:
15616             case IDCANCEL:  $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow());
15617                             $ EndDialog (wnd, (uintptr_t) this);
15618                             $ break;
15619 
15620             default:        $ break;
15621             }
15622                             $ break;
15623         default:            $ break;
15624         }
15625 
15626 $   return FALSE;
15627     }
15628 
15629 //-----------------------------------------------------------------------------------------------------------------
15630 
15631 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
15632     {
15633 $1  static txDialog* this__ = NULL;
15634 $   if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam;
15635 $   if (!this__) return FALSE;
15636 
15637 $   return this__-> dialogProc (wnd, msg, wParam, lParam);  //-V109
15638     }
15639 
15640 //-----------------------------------------------------------------------------------------------------------------
15641 
15642 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
15643                               WORD controls, short x, short y, short cx, short cy,
15644                               const char caption[], const char font[], WORD fontsize, const char menu[])
15645     {
15646 $1  if (_TX_ARGUMENT_FAILED (globalMem)) return NULL;
15647 
15648 $   WORD* pw = (WORD*) globalMem;
15649 
15650 $   DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++;
15651 
15652 $   tmpl->style = style;
15653 $   tmpl->dwExtendedStyle = exStyle;
15654 $   tmpl->cdit  = controls;
15655 $   tmpl->x     = x;
15656 $   tmpl->y     = y;
15657 $   tmpl->cx    = cx;
15658 $   tmpl->cy    = cy;
15659 
15660 $   if (menu > (const char*) 0xFFFF)
15661         {
15662 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (menu?    menu    : ""), -1, (wchar_t*) pw,           //-V547
15663                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15664         }
15665     else
15666         {
15667 $       *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0);
15668 $       *pw++ = (WORD)(uintptr_t)  menu;
15669         }
15670 
15671 $   if (caption)
15672         {
15673 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw,           //-V547
15674                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15675         }
15676 
15677 $   if (style & DS_SETFONT)
15678         {
15679 $       *pw++ = fontsize;
15680 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, (font?    font    : ""), -1, (wchar_t*) pw,
15681                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15682         }
15683 
15684 $   return pw;
15685     }
15686 
15687 //-----------------------------------------------------------------------------------------------------------------
15688 
15689 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
15690                            short x, short y, short cx, short cy,
15691                            WORD id, const char wclass[], const char caption[])
15692     {
15693 $1  if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL;
15694 
15695 $   WORD* pw = (LPWORD) dlgTemplatePtr;  // Force align at word boundary
15696 $   ((ULONG&) pw)  += 3;  //-V205
15697 $   ((ULONG&) pw) >>= 2;  //-V205
15698 $   ((ULONG&) pw) <<= 2;  //-V205
15699 
15700 $   DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++;
15701 
15702 $   tmpl->style = style;
15703 $   tmpl->dwExtendedStyle = exStyle;
15704 $   tmpl->x     = x;
15705 $   tmpl->y     = y;
15706 $   tmpl->cx    = cx;
15707 $   tmpl->cy    = cy;
15708 $   tmpl->id    = id;
15709 
15710 $   if (HIWORD (wclass) == 0xFFFF)
15711         {
15712 $       *pw++ = (WORD) (HIWORD ((uintptr_t) wclass));
15713 $       *pw++ = (WORD) (LOWORD ((uintptr_t) wclass));
15714         }
15715     else if (wclass)
15716         {
15717 $       pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw,
15718                                    (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));   //-V202
15719         }
15720     else
15721         {
15722 $       *pw++ = 0;
15723         }
15724 
15725 $   if (caption)
15726          {
15727 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw,
15728                                     (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));  //-V202
15729          }
15730     else
15731         {
15732 $       *pw++ = 0;
15733         }
15734 
15735 $   *pw++ = 0;
15736 
15737 $   return pw;
15738     }
15739 
15740 #endif // TX_COMPILED
15741 
15742 //}
15743 //=================================================================================================================
15744 
15745 //=================================================================================================================
15746 //{          Cleaning up the utility macros
15747 //           Очистка служебных макросов
15748 //=================================================================================================================
15749 
15750 #undef       $
15751 #undef       $0
15752 #undef       $1
15753 #undef       $2
15754 #undef       $3
15755 #undef       $4
15756 #undef       $5
15757 #undef       $6
15758 #undef       $7
15759 #undef       $8
15760 #undef       $9
15761 #undef       $$
15762 
15763 //}
15764 //=================================================================================================================
15765 
15767 
15768 //=================================================================================================================
15769 //{          Experimental Debugging macros
15771 //=================================================================================================================
15772 
15773 //{----------------------------------------------------------------------------------------------------------------
15893 //}----------------------------------------------------------------------------------------------------------------
15894 
15895 #ifndef __TX_DEBUG_MACROS
15896 #define __TX_DEBUG_MACROS  ("Группа отладочных $-макросов")
15897 
15899 //-----------------------------------------------------------------------------------------------------------------
15900 
15901 #define $H            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_BLACK);
15902 #define $B            txSetConsoleAttr (FOREGROUND_BLUE         | BACKGROUND_BLACK);
15903 #define $G            txSetConsoleAttr (FOREGROUND_GREEN        | BACKGROUND_BLACK);
15904 #define $C            txSetConsoleAttr (FOREGROUND_CYAN         | BACKGROUND_BLACK);
15905 #define $R            txSetConsoleAttr (FOREGROUND_RED          | BACKGROUND_BLACK);
15906 #define $M            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_BLACK);
15907 #define $Y            txSetConsoleAttr (FOREGROUND_DARKYELLOW   | BACKGROUND_BLACK);
15908 #define $d            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_BLACK);
15909 #define $D            txSetConsoleAttr (FOREGROUND_DARKGRAY     | BACKGROUND_BLACK);
15910 #define $b            txSetConsoleAttr (FOREGROUND_LIGHTBLUE    | BACKGROUND_BLACK);
15911 #define $g            txSetConsoleAttr (FOREGROUND_LIGHTGREEN   | BACKGROUND_BLACK);
15912 #define $c            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLACK);
15913 #define $r            txSetConsoleAttr (FOREGROUND_LIGHTRED     | BACKGROUND_BLACK);
15914 #define $m            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK);
15915 #define $y            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLACK);
15916 #define $h            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_BLACK);
15917 
15918 #define $i            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLUE);
15919 #define $I            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLUE);
15920 #define $o            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_GREEN);
15921 #define $O            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_GREEN);
15922 #define $e            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_RED);
15923 #define $E            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_RED);
15924 #define $w            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA);
15925 #define $W            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_MAGENTA);
15926 #define $f            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_LIGHTRED);
15927 #define $F            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_LIGHTRED);
15928 #define $l            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_DARKGRAY);
15929 #define $L            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_DARKGRAY);
15930 
15931 #define $T( cond )    txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED );
15932 
15933 #define $s            _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__);
15934 
15935 #define $sH           $s $H
15936 #define $sB           $s $B
15937 #define $sG           $s $G
15938 #define $sC           $s $C
15939 #define $sR           $s $R
15940 #define $sM           $s $M
15941 #define $sY           $s $Y
15942 #define $sd           $s $d
15943 #define $sD           $s $D
15944 #define $sb           $s $b
15945 #define $sg           $s $g
15946 #define $sc           $s $c
15947 #define $sr           $s $r
15948 #define $sm           $s $m
15949 #define $sy           $s $y
15950 #define $sh           $s $h
15951 
15952 #define $si           $s $i
15953 #define $sI           $s $I
15954 #define $so           $s $o
15955 #define $sO           $s $O
15956 #define $se           $s $e
15957 #define $sE           $s $E
15958 #define $sw           $s $w
15959 #define $sW           $s $W
15960 #define $sf           $s $f
15961 #define $sF           $s $F
15962 #define $sl           $s $l
15963 #define $sL           $s $L
15964 
15965 #define $sT( cond )   $s $T (cond)
15966 
15967 #define $test(cond)   { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \
15968                         else          { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; }
15969 
15970 #define $status(cond) $test (cond)
15971 
15972 #define $unittest( code, expected )                                                                                             \
15973     {                                                                                                                           \
15974     const _tx_decltype (code)     & _result   = (code);       /* Should use auto, but g++ 4.7.2 default std is < 2011 */        \
15975     const _tx_decltype (expected) & _expected = (expected);                                                                     \
15976                                                                                                                                 \
15977     if (_result == _expected)                                                                                                   \
15978         { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; }                                                            \
15979     else                                                                                                                        \
15980         { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \
15981                                                                                                                                 \
15982     $n;                                                                                                                         \
15983     (_result == _expected);                                                                                                     \
15984     }
15985 
15986 //=================================================================================================================
15987 
15988 #define $V(  var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]\n") )
15989 #define $V_( var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "] " ) )
15990 #define $V__(var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]"  ) )
15991 
15992 #define $(   var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n") )
15993 #define $_(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] " ) )
15994 #define $__( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]"  ) )
15995 
15996 #define $x(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) )
15997 #define $x_( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] ",  ::std::ios_base::showbase | ::std::ios_base::hex) )
15998 
15999 #define $v(  var, cond, ...)  { { $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" ); } $n; }
16000 #define $v_( var, cond, ...)  {   $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" );       }
16001 
16002 #define $$                    { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__);                                   } txOutputDebugPrintf ("\f\n"); }
16003 #define $$_                   { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]",           __LINE__, __func__);                                          } txOutputDebugPrintf ("\f\n"); }
16004 #define $meow(...)            { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); }
16005 
16006 #define $$$(   ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
16007 #define $$$_(  ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),  "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
16008 
16009 #define $$$$(  ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
16010 #define $$$$_( ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         (  "[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
16011 #define $do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n";                                                                                           __VA_ARGS__
16012 #define $DO(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p;                                                                                    __VA_ARGS__
16013 #define $Do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n";                                                                                        \
16014                                 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__);                                                                      __VA_ARGS__
16015 
16016 #define $n                    { ::std::cerr << "\n";   }
16017 #define $nn                   { ::std::cerr << "\n\n"; }
16018 #define $t                    { ::std::cerr << "\t";   }
16019 
16020 #define _tx$PrefixV(    ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": "          ) : ("["          ) )
16021 #define _tx$Prefix(var, ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") )
16022 
16023 //-----------------------------------------------------------------------------------------------------------------
16024 
16025 // This will never be documented, he-he. Read the source, Luke.
16026 
16027 #if defined (_DEBUG)
16028     #define $dbg               if (1)
16029     #define $DBG               if (1)
16030     #define $debug             if (1)
16031     #define $DEBUG             if (1)
16032     #define $printf(fmt, ...)  if (1)  printf (        fmt, ##__VA_ARGS__)
16033     #define $PRINTF(fmt, ...)  if (1) fprintf (stderr, fmt, ##__VA_ARGS__)
16034 #else
16035     #define $dbg               if (0)
16036     #define $DBG               if (0)
16037     #define $debug             if (0)
16038     #define $DEBUG             if (0)
16039     #define $printf(...)       if (0)  printf (        fmt, ##__VA_ARGS__)
16040     #define $PRINTF(...)       if (0) fprintf (stderr, fmt, ##__VA_ARGS__)
16041 #endif
16042 
16043 #define $$d    $debug
16044 #define $$w    $$$$
16045 #define $$s    __TX_FILELINE__
16046 #define $$b    { txSleep(); DebugBreak(); }
16047 #define $$p    { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \
16048                                                     __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); }
16049 #define $$P    (     txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) )
16050 #define $ppp   { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); }
16051 #define $pp    { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__,        __TX_FUNCTION__); }
16052 #define $p     { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__);        }
16053 #define $ppp_  { $sy; txPause ("\v[%s ""%s]...",                    __TX_FILELINE__, __TX_FUNCTION__); }
16054 #define $pp_   { $sy; txPause ("\v[%04d %s]...",                    __LINE__,        __TX_FUNCTION__); }
16055 #define $p_    { $sy; txPause ("\v[%s ""%s()]...",                  __TX_FILELINE__, __func__);        }
16056 #define $P     ( txPause ("") )
16057 
16058 //-----------------------------------------------------------------------------------------------------------------
16059 
16060 struct _txSaveConsoleAttr
16061     {
16062     unsigned attr_;
16063 
16064              _txSaveConsoleAttr()           : attr_ (txGetConsoleAttr ()) {}
16065     explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr);  }
16066             ~_txSaveConsoleAttr()                                         { txSetConsoleAttr (attr_); }
16067     };
16068 
16069 //-----------------------------------------------------------------------------------------------------------------
16070 
16071 struct _txDumpVarSuffix
16072     {
16073     typedef _txDumpVarSuffix this_t;
16074 
16075     const char* suffix_;
16076 
16077     explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); }
16078             ~_txDumpVarSuffix()                          { ::std::cerr << suffix_; }
16079 
16080             _txDumpVarSuffix (const this_t&) _tx_delete;
16081     this_t& operator =       (const this_t&) _tx_delete;
16082     };
16083 
16084 //-----------------------------------------------------------------------------------------------------------------
16085 
16086 #define ARGS__        const char* prefix, const char* suffix, std::ios_base::fmtflags flags,                             int deep
16087 #define ARGS_         const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0
16088 #define VALS_         prefix, suffix, flags, deep
16089 #define ERRPTR_(p)  { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; }
16090 
16091 template <typename T, typename StreamT> const T&    _txDumpVal (const T& value, StreamT& stream, ARGS_);
16092 
16093 //-----------------------------------------------------------------------------------------------------------------
16094 
16095 template <typename T> inline const T&               _txDumpVar (const T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16096 template <typename T> inline       T&               _txDumpVar (      T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16097 
16098 template <int N>      inline const char           (&_txDumpVar (const char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16099 template <int N>      inline       char           (&_txDumpVar (      char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16100 
16101 template <int N>      inline const wchar_t        (&_txDumpVar (const wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16102 template <int N>      inline       wchar_t        (&_txDumpVar (      wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16103 
16104                       inline const wchar_t&         _txDumpVar (const wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16105                       inline       wchar_t&         _txDumpVar (      wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16106 
16107                       inline const wchar_t*&        _txDumpVar (const wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16108                       inline       wchar_t*&        _txDumpVar (      wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16109 
16110                       inline const std::wstring&    _txDumpVar (const std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16111                       inline       std::wstring&    _txDumpVar (      std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16112 
16113 //-----------------------------------------------------------------------------------------------------------------
16114 
16115 template <typename T, typename StreamT> inline void _txDumpVal (const T&            value, StreamT& stream) { stream <<         value;         }
16116 template             <typename StreamT> inline void _txDumpVal (const char          value, StreamT& stream) { stream <<  "'" << value <<  "'"; }
16117 template             <typename StreamT> inline void _txDumpVal (const wchar_t       value, StreamT& stream) { stream << L"'" << value << L"'"; }
16118 template             <typename StreamT> inline void _txDumpVal (const std::string&  value, StreamT& stream) { stream <<  '"' << value <<  '"'; }
16119 template             <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; }
16120 
16121 template             <typename StreamT> inline void _txDumpVal (const char*         value, StreamT& stream)
16122     {
16123     if (_TX_ARGUMENT_FAILED (&stream)) return;
16124 
16125     if (!_txIsBadReadPtr (value)) stream <<  '"' << value <<  '"';
16126     else if (!value)              stream <<  "(null)";
16127     else                          ERRPTR_ (value);
16128     }
16129 
16130 template             <typename StreamT> inline void _txDumpVal (const wchar_t*      value, StreamT& stream)
16131     {
16132     if (_TX_ARGUMENT_FAILED (&stream)) return;
16133 
16134     if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"';
16135     else if (!value)              stream << L"(null)";
16136     else                          ERRPTR_ (value);
16137     }
16138 
16139 //-----------------------------------------------------------------------------------------------------------------
16140 
16141 template <typename T, typename StreamT>
16142 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__)
16143     {
16144     if (_TX_ARGUMENT_FAILED (&stream)) return value;  //-V778
16145     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16146     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16147 
16148     $sc;
16149     if (!deep) stream << prefix;
16150 
16151     std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags());
16152 
16153     if (!_txIsBadReadPtr (&value))
16154         {
16155         _txDumpVal (value, stream);
16156         }
16157     else
16158         ERRPTR_ (&value);
16159 
16160     stream.flags (old);
16161 
16162     if (!deep) stream << suffix;
16163 
16164     return value;
16165     }
16166 
16167 //-----------------------------------------------------------------------------------------------------------------
16168 
16169 template <typename T, int N>
16170 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N]
16171     {
16172     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16173     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16174 
16175     std::ostream& stream = std::cerr;
16176 
16177     $sc; if (!deep) std::cerr << prefix;
16178     $C;  std::cerr << ((deep)? " {" : "{");
16179 
16180     if (!_txIsBadReadPtr (value))
16181         {
16182         for (int i = 0; ; i++)
16183             {
16184             { $sC; stream << "[" << i << "]="; }
16185 
16186             _txDumpVar (value[i], prefix, suffix, flags, deep+1);
16187 
16188             if (i >= N-1) break;
16189 
16190             stream << ", ";
16191             }
16192         }
16193     else
16194         ERRPTR_ (&value);
16195 
16196     $C; std::cerr << "}";
16197     $c; if (!deep) std::cerr << suffix;
16198 
16199     return value;
16200     }
16201 
16202 //=================================================================================================================
16203 
16204 inline std::ostream& operator << (std::ostream& stream, const POINT& point)
16205     {
16206     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16207 
16208     if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }";           // NOLINT (clang-diagnostic-undefined-bool-conversion)
16209     else if (!&point)              stream << "(null)";
16210     else ERRPTR_ (&point);
16211 
16212     return stream;
16213     }
16214 
16215 inline std::ostream& operator << (std::ostream& stream, const SIZE& size)
16216     {
16217     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16218 
16219     if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }";          // NOLINT (clang-diagnostic-undefined-bool-conversion)
16220     else       stream << "(null)";
16221 
16222     return stream;
16223     }
16224 
16225 inline std::ostream& operator << (std::ostream& stream, const RECT& rect)
16226     {
16227     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16228 
16229     if (&rect) stream << "{ left: "  << rect.left  << ", top: "    << rect.top    <<  // NOLINT (clang-diagnostic-undefined-bool-conversion)
16230                          ", right: " << rect.right << ", bottom: " << rect.bottom << " }";
16231 
16232     else       stream << "(null)";
16233 
16234     return stream;
16235     }
16236 
16237 //-----------------------------------------------------------------------------------------------------------------
16238 
16239 #undef ARGS__
16240 #undef ARGS_
16241 #undef VALS_
16242 #undef ERRPTR_
16243 
16244 //-----------------------------------------------------------------------------------------------------------------
16246 
16247 #endif
16248 
16249 //}
16250 //=================================================================================================================
16251 
16253 
16254 //=================================================================================================================
16255 //{          TXAPI calls tracing
16256 //           Трассировка вызовов TXAPI
16257 //=================================================================================================================
16258 
16259 #ifndef   FOR_DOXYGEN_ONLY
16260 
16261 #if defined (_MSC_VER)
16262 #undef  _txLocCurSet
16263 #define _txLocCurSet()                 __txLocCurSet (__FILE__, __LINE__, NULL)
16264 #endif
16265 
16266 #define txAlphaBlend(...)              ( _txLocCurSet(), txAlphaBlend          (__VA_ARGS__) )
16267 #define txArc(...)                     ( _txLocCurSet(), txArc                 (__VA_ARGS__) )
16268 #define txBegin(...)                   ( _txLocCurSet(), txBegin               (__VA_ARGS__) )
16269 #define txBitBlt(...)                  ( _txLocCurSet(), txBitBlt              (__VA_ARGS__) )
16270 #define txChord(...)                   ( _txLocCurSet(), txChord               (__VA_ARGS__) )
16271 #define txCircle(...)                  ( _txLocCurSet(), txCircle              (__VA_ARGS__) )
16272 #define txClear(...)                   ( _txLocCurSet(), txClear               (__VA_ARGS__) )
16273 #define txClearConsole(...)            ( _txLocCurSet(), txClearConsole        (__VA_ARGS__) )
16274 #define txColor(...)                   ( _txLocCurSet(), txColor               (__VA_ARGS__) )
16275 #define txCreateCompatibleDC(...)      ( _txLocCurSet(), txCreateCompatibleDC  (__VA_ARGS__) )
16276 #define txCreateDIBSection(...)        ( _txLocCurSet(), txCreateDIBSection    (__VA_ARGS__) )
16277 #define txCreateExtraWindow(...)       ( _txLocCurSet(), txCreateExtraWindow   (__VA_ARGS__) )
16278 #define txCreateWindow(...)            ( _txLocCurSet(), txCreateWindow        (__VA_ARGS__) )
16279 #define txDC(...)                      ( _txLocCurSet(), txDC                  (__VA_ARGS__) )
16280 #define txDeleteDC(...)                ( _txLocCurSet(), txDeleteDC            (__VA_ARGS__) )
16281 #define txDemangle(...)                ( _txLocCurSet(), txDemangle            (__VA_ARGS__) )
16282 #define txDestroyWindow(...)           ( _txLocCurSet(), txDestroyWindow       (__VA_ARGS__) )
16283 #define txDisableAutoPause(...)        ( _txLocCurSet(), txDisableAutoPause    (__VA_ARGS__) )
16284 #define txDrawText(...)                ( _txLocCurSet(), txDrawText            (__VA_ARGS__) )
16285 #define txEllipse(...)                 ( _txLocCurSet(), txEllipse             (__VA_ARGS__) )
16286 #define txEnd(...)                     ( _txLocCurSet(), txEnd                 (__VA_ARGS__) )
16287 #define txExtractColor(...)            ( _txLocCurSet(), txExtractColor        (__VA_ARGS__) )
16288 #define txFillColor(...)               ( _txLocCurSet(), txFillColor           (__VA_ARGS__) )
16289 #define txFloodFill(...)               ( _txLocCurSet(), txFloodFill           (__VA_ARGS__) )
16290 #define txFontExist(...)               ( _txLocCurSet(), txFontExist           (__VA_ARGS__) )
16291 #define txFormat(...)                  ( _txLocCurSet(), txFormat              (__VA_ARGS__) )
16292 #define txGetAsyncKeyState(...)        ( _txLocCurSet(), txGetAsyncKeyState    (__VA_ARGS__) )
16293 #define txGetColor(...)                ( _txLocCurSet(), txGetColor            (__VA_ARGS__) )
16294 #define txGetConsoleAttr(...)          ( _txLocCurSet(), txGetConsoleAttr      (__VA_ARGS__) )
16295 #define txGetConsoleCursorPos(...)     ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) )
16296 #define txGetConsoleExtent(...)        ( _txLocCurSet(), txGetConsoleExtent    (__VA_ARGS__) )
16297 #define txGetConsoleFontSize(...)      ( _txLocCurSet(), txGetConsoleFontSize  (__VA_ARGS__) )
16298 #define txGetExtent(...)               ( _txLocCurSet(), txGetExtent           (__VA_ARGS__) )
16299 #define txGetExtentX(...)              ( _txLocCurSet(), txGetExtentX          (__VA_ARGS__) )
16300 #define txGetExtentY(...)              ( _txLocCurSet(), txGetExtentY          (__VA_ARGS__) )
16301 #define txGetFillColor(...)            ( _txLocCurSet(), txGetFillColor        (__VA_ARGS__) )
16302 #define txGetFPS(...)                  ( _txLocCurSet(), txGetFPS              (__VA_ARGS__) )
16303 #define txGetModuleFileName(...)       ( _txLocCurSet(), txGetModuleFileName   (__VA_ARGS__) )
16304 #define txGetPixel(...)                ( _txLocCurSet(), txGetPixel            (__VA_ARGS__) )
16305 #define txGetTextExtent(...)           ( _txLocCurSet(), txGetTextExtent       (__VA_ARGS__) )
16306 #define txGetTextExtentX(...)          ( _txLocCurSet(), txGetTextExtentX      (__VA_ARGS__) )
16307 #define txGetTextExtentY(...)          ( _txLocCurSet(), txGetTextExtentY      (__VA_ARGS__) )
16308 #define txHSL2RGB(...)                 ( _txLocCurSet(), txHSL2RGB             (__VA_ARGS__) )
16309 #define txInputBox(...)                ( _txLocCurSet(), txInputBox            (__VA_ARGS__) )
16310 #define txLine(...)                    ( _txLocCurSet(), txLine                (__VA_ARGS__) )
16311 #define txLoadImage(...)               ( _txLocCurSet(), txLoadImage           (__VA_ARGS__) )
16312 #define txLock(...)                    ( _txLocCurSet(), txLock                (__VA_ARGS__) )
16313 #define txMessageBox(...)              ( _txLocCurSet(), txMessageBox          (__VA_ARGS__) )
16314 #define txMouseButtons(...)            ( _txLocCurSet(), txMouseButtons        (__VA_ARGS__) )
16315 #define txMousePos(...)                ( _txLocCurSet(), txMousePos            (__VA_ARGS__) )
16316 #define txMouseX(...)                  ( _txLocCurSet(), txMouseX              (__VA_ARGS__) )
16317 #define txMouseY(...)                  ( _txLocCurSet(), txMouseY              (__VA_ARGS__) )
16318 #define txNotifyIcon(...)              ( _txLocCurSet(), txNotifyIcon          (__VA_ARGS__) )
16319 #define txOK(...)                      ( _txLocCurSet(), txOK                  (__VA_ARGS__) )
16320 #define txOutputDebugPrintf(...)       ( _txLocCurSet(), txOutputDebugPrintf   (__VA_ARGS__) )
16321 #define txPause(...)                   ( _txLocCurSet(), txPause               (__VA_ARGS__) )
16322 #define txPie(...)                     ( _txLocCurSet(), txPie                 (__VA_ARGS__) )
16323 #define txPixel(...)                   ( _txLocCurSet(), txPixel               (__VA_ARGS__) )
16324 #define txPlaySound(...)               ( _txLocCurSet(), txPlaySound           (__VA_ARGS__) )
16325 #define txPlayVideo(...)               ( _txLocCurSet(), txPlayVideo           (__VA_ARGS__) )
16326 #define txPolygon(...)                 ( _txLocCurSet(), txPolygon             (__VA_ARGS__) )
16327 #define txPrintf(...)                  ( _txLocCurSet(), txPrintf              (__VA_ARGS__) )
16328 #define txQueryPerformance(...)        ( _txLocCurSet(), txQueryPerformance    (__VA_ARGS__) )
16329 #define txRectangle(...)               ( _txLocCurSet(), txRectangle           (__VA_ARGS__) )
16330 #define txRedrawWindow(...)            ( _txLocCurSet(), txRedrawWindow        (__VA_ARGS__) )
16331 #define txRegisterClass(...)           ( _txLocCurSet(), txRegisterClass       (__VA_ARGS__) )
16332 #define txRegQuery(...)                ( _txLocCurSet(), txRegQuery            (__VA_ARGS__) )
16333 #define txReopenStdio(...)             ( _txLocCurSet(), txReopenStdio         (__VA_ARGS__) )
16334 #define txRGB2HSL(...)                 ( _txLocCurSet(), txRGB2HSL             (__VA_ARGS__) )
16335 #define txSaveImage(...)               ( _txLocCurSet(), txSaveImage           (__VA_ARGS__) )
16336 #define txSelectFont(...)              ( _txLocCurSet(), txSelectFont          (__VA_ARGS__) )
16337 #define txSelectObject(...)            ( _txLocCurSet(), txSelectObject        (__VA_ARGS__) )
16338 #define txSetColor(...)                ( _txLocCurSet(), txSetColor            (__VA_ARGS__) )
16339 #define txSetConsoleAttr(...)          ( _txLocCurSet(), txSetConsoleAttr      (__VA_ARGS__) )
16340 #define txSetConsoleCursorPos(...)     ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) )
16341 #define txSetDefaults(...)             ( _txLocCurSet(), txSetDefaults         (__VA_ARGS__) )
16342 #define txSetFillColor(...)            ( _txLocCurSet(), txSetFillColor        (__VA_ARGS__) )
16343 #define txSetLocale(...)               ( _txLocCurSet(), txSetLocale           (__VA_ARGS__) )
16344 #define txSetPixel(...)                ( _txLocCurSet(), txSetPixel            (__VA_ARGS__) )
16345 #define txSetProgress(...)             ( _txLocCurSet(), txSetProgress         (__VA_ARGS__) )
16346 #define txSetTextAlign(...)            ( _txLocCurSet(), txSetTextAlign        (__VA_ARGS__) )
16347 #define txSetWindowsHook(...)          ( _txLocCurSet(), txSetWindowsHook      (__VA_ARGS__) )
16348 #define txSleep(...)                   ( _txLocCurSet(), txSleep               (__VA_ARGS__) )
16349 #define txSpeak(...)                   ( _txLocCurSet(), txSpeak               (__VA_ARGS__) )
16350 #define txTextCursor(...)              ( _txLocCurSet(), txTextCursor          (__VA_ARGS__) )
16351 #define txTextOut(...)                 ( _txLocCurSet(), txTextOut             (__VA_ARGS__) )
16352 #define txTransparentBlt(...)          ( _txLocCurSet(), txTransparentBlt      (__VA_ARGS__) )
16353 #define txTriangle(...)                ( _txLocCurSet(), txTriangle            (__VA_ARGS__) )
16354 #define txUnlock(...)                  ( _txLocCurSet(), txUnlock              (__VA_ARGS__) )
16355 #define txUpdateWindow(...)            ( _txLocCurSet(), txUpdateWindow        (__VA_ARGS__) )
16356 #define txUseAlpha(...)                ( _txLocCurSet(), txUseAlpha            (__VA_ARGS__) )
16357 #define txVersion(...)                 ( _txLocCurSet(), txVersion             (__VA_ARGS__) )
16358 #define txVersionNumber(...)           ( _txLocCurSet(), txVersionNumber       (__VA_ARGS__) )
16359 #define txWindow(...)                  ( _txLocCurSet(), txWindow              (__VA_ARGS__) )
16360 #define tx_fpreset(...)                ( _txLocCurSet(), tx_fpreset            (__VA_ARGS__) )
16361 #define tx_glGetError(...)             ( _txLocCurSet(), tx_glGetError         (__VA_ARGS__) )
16362 #define _txDump(...)                   ( _txLocCurSet(), _txDump               (__VA_ARGS__) )
16363 #define _txStackBackTrace(...)         ( _txLocCurSet(), _txStackBackTrace     (__VA_ARGS__) )
16364 
16365 #endif
16366 
16367 //}
16368 //=================================================================================================================
16369 
16371 //}
16372 //=================================================================================================================
16373 
16374 //-----------------------------------------------------------------------------------------------------------------
16375 //{          The namespaces
16376 //-----------------------------------------------------------------------------------------------------------------
16377 
16380 _TX_END_NAMESPACE
16381 
16384 using namespace TX;                    // Allow easy usage of TXLib functions
16385 
16386 using ::std::cin;                      // Predefined usings to avoid "using namespace std"
16387 using ::std::cout;
16388 using ::std::cerr;
16389 using ::std::string;
16390 using ::std::wcin;
16391 using ::std::wcout;
16392 using ::std::wcerr;
16393 using ::std::wstring;
16394 
16395 //}
16396 //-----------------------------------------------------------------------------------------------------------------
16397 
16398 //-----------------------------------------------------------------------------------------------------------------
16399 //{          Compiler- and platform-specific
16400 //           Адаптация к компиляторам и платформам
16401 //-----------------------------------------------------------------------------------------------------------------
16403 
16404 #if defined (_GCC_VER)
16405 
16406     #pragma GCC optimize               "strict-aliasing"
16407 
16408     #pragma GCC pop_options
16409     #pragma GCC diagnostic pop
16410 
16411     #endif
16412 
16413 #if defined (_CLANG_VER)
16414 
16415     #pragma clang diagnostic pop
16416 
16417     #endif
16418 
16419 //-----------------------------------------------------------------------------------------------------------------
16420 
16421 #if defined (_MSC_VER)
16422 
16423     #pragma warning (pop)              // Restoring maximum level
16424 
16425     #endif
16426 
16427 #if defined (__INTEL_COMPILER)
16428 
16429     #pragma warning (default:  174)    // Remark: expression has no effect
16430     #pragma warning (default:  304)    // Remark: access control not specified ("public" by default)
16431     #pragma warning (default:  444)    // Remark: destructor for base class "..." is not virtual
16432     #pragma warning (default:  522)    // Remark: function redeclared "inline" after being called
16433     #pragma warning (default: 1684)    // Conversion from pointer to same-sized integral type (potential portability problem)
16434 
16435     #pragma warning (disable:  981)    // Remark: operands are evaluated in unspecified order
16436 
16437     #endif
16438 
16440 //}
16441 //-----------------------------------------------------------------------------------------------------------------
16442 
16443 #endif // __TXLIB_H_INCLUDED
16444 
16445 //=================================================================================================================
16446 // EOF
16447 //=================================================================================================================
16448                                                                                                                    
16449                                                                                                                    
16450    
16451 
16452 
16453 
16454 
16455 
16456 
16457 
16458 
16459 
16460 
16461 
16462 
16463 
16464 
16465 
16466 
16467 
16468 
16469 
16470 
16471 
16472 
16473 
16474 
16475 
16476 
16477 
16478 
16479 
16480 
16481 
16482 
16483 
16484 
16485 
16486 
16487 
16488 
16489 
16490 
16491 
16492 
16493 
16494 
16495 
16496 
16497 
16498 
16499