TX Library Help – Version: 00173a, Revision: 173
 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: 2024-04-10 21:00:00 +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, 173, 2024-04-10 21:00:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00146 #define _TX_VERSION  _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-04-10 21:00:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00147 #define _TX_AUTHOR   _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-04-10 21:00:00 +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 nesessary for txSpeak() to work.
00774     #error ---------------------------------------------------------------------------------------
00775     #error
00776 
00777 #endif
00778 #endif
00779 
00780 //-----------------------------------------------------------------------------------------------------------------
00781 
00782 #if !defined (WINVER)
00783     #define   WINVER                   0x0500    // Defaults to Windows 2000
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), strncpy ((buf), getenv (name), (sizeof_buf)-1) )
00935 
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 //{----------------------------------------------------------------------------------------------------------------
02711 //}----------------------------------------------------------------------------------------------------------------
02712 
02713 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0,
02714                  unsigned imageType = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard;
02715 
02716 //{----------------------------------------------------------------------------------------------------------------
02748 //}----------------------------------------------------------------------------------------------------------------
02749 
02750 bool txDeleteDC (HDC  dc);
02751 
02753 bool txDeleteDC (HDC* dc);
02755 
02756 //{----------------------------------------------------------------------------------------------------------------
02796 //}----------------------------------------------------------------------------------------------------------------
02797 
02798 bool txBitBlt (HDC destImage,   double xDest,       double yDest, double width, double height,
02799                HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY);
02800 
02801 //{----------------------------------------------------------------------------------------------------------------
02816 //}----------------------------------------------------------------------------------------------------------------
02817 
02818 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0);
02819 
02820 //{----------------------------------------------------------------------------------------------------------------
02880 //}----------------------------------------------------------------------------------------------------------------
02881 
02882 bool txTransparentBlt (HDC destImage,   double xDest,       double yDest,       double width, double height,
02883                        HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK);
02884 
02885 //{----------------------------------------------------------------------------------------------------------------
02901 //}----------------------------------------------------------------------------------------------------------------
02902 
02903 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
02904                               COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0);
02905 
02906 //{----------------------------------------------------------------------------------------------------------------
03011 //}----------------------------------------------------------------------------------------------------------------
03012 
03013 bool txAlphaBlend (HDC destImage,   double xDest,       double yDest,       double width, double height,
03014                    HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0);
03015 
03016 //{----------------------------------------------------------------------------------------------------------------
03033 //}----------------------------------------------------------------------------------------------------------------
03034 
03035 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
03036                           double xSource = 0, double ySource = 0, double alpha = 1.0);
03037 
03038 //{----------------------------------------------------------------------------------------------------------------
03067 //}----------------------------------------------------------------------------------------------------------------
03068 
03069 HDC txUseAlpha (HDC image);
03070 
03071 //{----------------------------------------------------------------------------------------------------------------
03097 //}----------------------------------------------------------------------------------------------------------------
03098 
03099 bool txSaveImage (const char filename[], HDC dc = txDC());
03100 
03102 //}
03103 //=================================================================================================================
03104 
03105 //=================================================================================================================
03106 //{          Utility functions
03108 //=================================================================================================================
03110 //{----------------------------------------------------------------------------------------------------------------
03129 //}----------------------------------------------------------------------------------------------------------------
03130 
03131 double txSleep (double time = 0);
03132 
03133 //{----------------------------------------------------------------------------------------------------------------
03218 //}----------------------------------------------------------------------------------------------------------------
03219 
03220 inline int txBegin();
03221 
03222 //{----------------------------------------------------------------------------------------------------------------
03245 //}----------------------------------------------------------------------------------------------------------------
03246 
03247 inline int txEnd();
03248 
03249 //{----------------------------------------------------------------------------------------------------------------
03271 //}----------------------------------------------------------------------------------------------------------------
03272 
03273 inline void txRedrawWindow();
03274 
03275 //{----------------------------------------------------------------------------------------------------------------
03299 //}----------------------------------------------------------------------------------------------------------------
03300 
03301 inline int txUpdateWindow (int update = true);
03302 
03303 //{----------------------------------------------------------------------------------------------------------------
03320 //}----------------------------------------------------------------------------------------------------------------
03321 
03322 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC());
03323 
03324 //{----------------------------------------------------------------------------------------------------------------
03344 //
03345 //                 +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее"
03346 //                 |
03347 //                 v
03348 //               txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03353 //}----------------------------------------------------------------------------------------------------------------
03354 
03355 //     +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее"
03356 //     |
03357 //     v
03358 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03359 
03360 //{----------------------------------------------------------------------------------------------------------------
03376 //}----------------------------------------------------------------------------------------------------------------
03377 
03378 bool txDestroyWindow (HWND wnd = txWindow());
03379 
03380 //{----------------------------------------------------------------------------------------------------------------
03391 //}----------------------------------------------------------------------------------------------------------------
03392 
03393 double txQueryPerformance() tx_nodiscard;
03394 
03395 //{----------------------------------------------------------------------------------------------------------------
03410 //}----------------------------------------------------------------------------------------------------------------
03412 
03413 #if defined (_TX_CPP11)
03414     template <int txFramesToAverage = 5>
03415 #else
03416     const     int txFramesToAverage = 5;
03417 #endif
03418 
03420 
03421 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard;
03422 
03424 //}
03425 
03426 //=================================================================================================================
03427 //{          Mouse functions
03429 //=================================================================================================================
03431 //{----------------------------------------------------------------------------------------------------------------
03455 //}----------------------------------------------------------------------------------------------------------------
03456 
03457 inline POINT txMousePos() tx_nodiscard;
03458 
03459 //{----------------------------------------------------------------------------------------------------------------
03479 //}----------------------------------------------------------------------------------------------------------------
03480 
03481 inline double txMouseX() tx_nodiscard;
03482 
03483 //{----------------------------------------------------------------------------------------------------------------
03503 //}----------------------------------------------------------------------------------------------------------------
03504 
03505 inline double txMouseY() tx_nodiscard;
03506 
03507 //{----------------------------------------------------------------------------------------------------------------
03539 //}----------------------------------------------------------------------------------------------------------------
03540 
03541 inline unsigned txMouseButtons() tx_nodiscard;
03542 
03543 //{----------------------------------------------------------------------------------------------------------------
03575 //}----------------------------------------------------------------------------------------------------------------
03576 
03577 #ifdef FOR_DOXYGEN_ONLY
03578 inline Mouse& txCatchMouse (bool shouldEat = true);
03579 #endif
03580 
03582 //}
03583 //=================================================================================================================
03584 
03585 //=================================================================================================================
03586 //{          Console functions
03588 //=================================================================================================================
03590 //{----------------------------------------------------------------------------------------------------------------
03632 //}----------------------------------------------------------------------------------------------------------------
03633 
03634 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/);
03635 
03636 //{----------------------------------------------------------------------------------------------------------------
03648 //}----------------------------------------------------------------------------------------------------------------
03649 
03650 unsigned txGetConsoleAttr() tx_nodiscard;
03651 
03652 //{----------------------------------------------------------------------------------------------------------------
03666 //}----------------------------------------------------------------------------------------------------------------
03667 
03668 bool txClearConsole();
03669 
03670 //{----------------------------------------------------------------------------------------------------------------
03690 //}----------------------------------------------------------------------------------------------------------------
03691 
03692 POINT txSetConsoleCursorPos (double x, double y);
03693 
03694 //{----------------------------------------------------------------------------------------------------------------
03707 //}----------------------------------------------------------------------------------------------------------------
03708 
03709 POINT txGetConsoleCursorPos();
03710 
03711 //{----------------------------------------------------------------------------------------------------------------
03724 //}----------------------------------------------------------------------------------------------------------------
03725 
03726 POINT txGetConsoleExtent();
03727 
03728 //{----------------------------------------------------------------------------------------------------------------
03742 //}----------------------------------------------------------------------------------------------------------------
03743 
03744 POINT txGetConsoleFontSize() tx_nodiscard;
03745 
03746 //{----------------------------------------------------------------------------------------------------------------
03762 //}----------------------------------------------------------------------------------------------------------------
03763 
03764 bool txTextCursor (bool blink = true);
03765 
03767 //}
03768 //=================================================================================================================
03769 
03770 //=================================================================================================================
03771 //{          Other staff not related to drawing
03773 //=================================================================================================================
03775 //{----------------------------------------------------------------------------------------------------------------
03804 //}----------------------------------------------------------------------------------------------------------------
03805 
03806 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC);
03807 
03808 //{----------------------------------------------------------------------------------------------------------------
03866 //}----------------------------------------------------------------------------------------------------------------
03867 
03868 int txSpeak (const char* text, ...) tx_printfy (1);
03869 
03870 //{----------------------------------------------------------------------------------------------------------------
03987 //}----------------------------------------------------------------------------------------------------------------
03988 
03989 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
03990                        double zoom = 0, double gain = 1, HWND wnd = txWindow());
03991 
03992 //{----------------------------------------------------------------------------------------------------------------
04006 //}----------------------------------------------------------------------------------------------------------------
04007 
04008 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow());
04009 
04010 //{----------------------------------------------------------------------------------------------------------------
04066 //}----------------------------------------------------------------------------------------------------------------
04067 
04068 bool txGetAsyncKeyState (int key);
04069 
04070 //{----------------------------------------------------------------------------------------------------------------
04107 //}----------------------------------------------------------------------------------------------------------------
04108 
04109 #ifdef FOR_DOXYGEN_ONLY
04110 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
04111 #endif
04112 
04113 //{----------------------------------------------------------------------------------------------------------------
04138 //}----------------------------------------------------------------------------------------------------------------
04139 
04140 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1);
04141 
04142 //{----------------------------------------------------------------------------------------------------------------
04218 //}----------------------------------------------------------------------------------------------------------------
04219 
04220 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04221 
04222 template <typename T, typename... ArgsT>
04223 int txPrintf (const char* format, ArgsT... args);
04224 
04225 #define TX_PRINTF(...)  ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) )
04226 
04227 #endif
04228 
04229 //-----------------------------------------------------------------------------------------------------------------
04230 
04231 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY)
04232 
04233 enum width_t     : int {};
04234 enum precision_t : int {};
04235 
04236 inline width_t     width     (int width) { return (width_t)     width; }
04237 inline precision_t precision (int prec)  { return (precision_t) prec;  }
04238 
04239 #endif
04240 
04241 //{----------------------------------------------------------------------------------------------------------------
04260 //}----------------------------------------------------------------------------------------------------------------
04261 
04262 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04263 
04264 template <typename T, typename... ArgsT>
04265 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args);
04266 
04267 #endif
04268 
04269 //{----------------------------------------------------------------------------------------------------------------
04289 //}----------------------------------------------------------------------------------------------------------------
04290 
04291 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04292 
04293 template <typename T, typename... ArgsT>
04294 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args);
04295 
04296 #endif
04297 
04298 //{----------------------------------------------------------------------------------------------------------------
04316 //}----------------------------------------------------------------------------------------------------------------
04317 
04318 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
04319 
04320 template <typename... ArgsT>
04321 std::string txFormat (const char* format, ArgsT... args);
04322 
04323 #endif
04324 
04325 //{----------------------------------------------------------------------------------------------------------------
04397 //}----------------------------------------------------------------------------------------------------------------
04399 
04400 #define sizearr( arr )  ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) )
04401 
04403 //  See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx
04404 
04405 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N];  // ;=P
04406 
04407 //  Another approach
04408 
04409 #if defined (_TX_CPP11_MSVC15)
04410 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; }
04411 #endif
04412 
04414 
04415 #define SIZEARR( arr )  ( sizeof (arr) / sizeof ((arr)[0]) )
04416 
04418 //{----------------------------------------------------------------------------------------------------------------
04437 //}----------------------------------------------------------------------------------------------------------------
04438 
04439 inline int random (int range) tx_deprecated;
04440 
04441 //{----------------------------------------------------------------------------------------------------------------
04466 //}----------------------------------------------------------------------------------------------------------------
04467 
04468 inline double random (double left, double right)                tx_nodiscard tx_deprecated;
04469 
04470 inline double random (std::nomeow_t, double left, double right) tx_nodiscard;
04471 
04472 //{----------------------------------------------------------------------------------------------------------------
04502 //}----------------------------------------------------------------------------------------------------------------
04503 
04504 template <typename Tx, typename Ta, typename Tb>
04505 inline bool In (Tx x, Ta a, Tb b)                tx_nodiscard tx_deprecated;
04506 
04507 template <typename Tx, typename Ta, typename Tb>
04508 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated;
04509 
04510 //{----------------------------------------------------------------------------------------------------------------
04556 //}----------------------------------------------------------------------------------------------------------------
04558 
04559 inline bool In (const POINT& pt, const RECT& rect)                      tx_nodiscard tx_deprecated;
04560 inline bool In (const COORD& pt, const SMALL_RECT& rect)                tx_nodiscard tx_deprecated;
04561 
04563 
04564 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)       tx_nodiscard tx_deprecated;
04565 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated;
04566 
04567 //{----------------------------------------------------------------------------------------------------------------
04586 //}----------------------------------------------------------------------------------------------------------------
04587 
04588 #define MAX( a, b )     ( ((a) > (b))? (a) : (b) )
04589 
04590 template <typename T>
04591 T max (const T& a, const T& b) { return (a > b)? a : b; }  
04592 
04593 //{----------------------------------------------------------------------------------------------------------------
04612 //}----------------------------------------------------------------------------------------------------------------
04613 
04614 #define MIN( a, b )     ( ((a) < (b))? (a) : (b) )
04615 
04616 template <typename T>
04617 T min (const T& a, const T& b) { return (a < b)? a : b; }  
04618 
04619 //{----------------------------------------------------------------------------------------------------------------
04633 //}----------------------------------------------------------------------------------------------------------------
04634 
04635 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L  // MSVC: C99 case
04636 
04637     #define ROUND( x )  ( (long) round (x) )
04638 
04639 #else
04640 
04641     #define ROUND( x )  ( (long) floor ((x) + 0.5) )
04642 
04643 #endif
04644 
04645 //{----------------------------------------------------------------------------------------------------------------
04664 //}----------------------------------------------------------------------------------------------------------------
04665 
04666 void tx_fpreset();
04667 
04668 //{----------------------------------------------------------------------------------------------------------------
04677 //}----------------------------------------------------------------------------------------------------------------
04678 
04679 const double txPI = asin (1.0) * 2;
04680 
04681 //{----------------------------------------------------------------------------------------------------------------
04708 //}----------------------------------------------------------------------------------------------------------------
04709 
04710 inline double txSqr (double x)
04711     {
04712     double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0));  // Бурная вычислительная деятельность
04713 
04714     char str[1024] = "";
04715     _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr);
04716     txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL ||
04717         (
04718         txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION),
04719         txMessageBox ("Уйду я от вас", "Злые вы...",  MB_ICONSTOP),
04720         exit (EXIT_FAILURE), 0  //-V2509 //-V2014
04721         );
04722 
04723     txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика!  \0"  // А как это работает, а?  //-V111
04724                                      "С ума сойти...      \0"  //
04725                                      "а КЭП подтверждает  \0"  //       и кто это будет
04726                                      "Главное - отчитаться\0"  //       поддерживать?..
04727                                      "Невероятно, но факт \0"
04728                                      "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21);
04729 
04730     return sqr;  // Все же вернем значение. Мы же не звери
04731     }
04732 
04733 //{----------------------------------------------------------------------------------------------------------------
04755 //}----------------------------------------------------------------------------------------------------------------
04756 
04757 #ifdef FOR_DOXYGEN_ONLY
04758 #define _TX_DESTROY_3D
04759 #endif
04760 
04761 #if defined (_TX_DESTROY_3D)
04762 
04763     #define z  0                   // Читайте "Флатландию" Эбботта!
04764 
04765 #endif
04766 
04767 //{----------------------------------------------------------------------------------------------------------------
04784 //}----------------------------------------------------------------------------------------------------------------
04786 
04787 #define meow   ;
04788 
04789 #if defined (_MSC_VER) && !defined (_CLANG_VER)
04790 #define мяу    meow
04791 #endif
04792 
04793 #define please
04794 
04796 
04797 //{----------------------------------------------------------------------------------------------------------------
04815 //}----------------------------------------------------------------------------------------------------------------
04816 
04817 #define ZERO( type )    zero <type> ()
04818 
04820 template <typename T> inline T zero() tx_nodiscard;
04822 
04823 //{----------------------------------------------------------------------------------------------------------------
04850 //}----------------------------------------------------------------------------------------------------------------
04852 
04853 #define  tx_auto_func(    func )  _tx_auto_fun1 ( __LINE__, func )
04854 #define _tx_auto_fun1( n, func )  _tx_auto_fun2 ( n,        func )
04855 #define _tx_auto_fun2( n, func )  auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; })
04856 
04857 #define tx_finally(...)           tx_auto_func (__VA_ARGS__)
04858 
04859 template <typename T>
04860 struct _tx_auto_func_
04861     {
04862     typedef _tx_auto_func_<T> this_t;
04863     T func_;
04864 
04865     explicit _tx_auto_func_ (T func) : func_ (func) {}
04866             ~_tx_auto_func_ ()       { func_ ();     }
04867 
04868     private:         _tx_auto_func_ ()              _tx_delete;
04869                      _tx_auto_func_ (const this_t&) _tx_delete;
04870              this_t& operator =     (const this_t&) _tx_delete;
04871     };
04872 
04873 template <typename T>
04874 _tx_auto_func_<T> _tx_auto_func  (T   func)
04875     {
04876     return        _tx_auto_func_ <T> (func);
04877     }
04878 
04880 
04881 //{----------------------------------------------------------------------------------------------------------------
04926 //}----------------------------------------------------------------------------------------------------------------
04927 
04928 #if !defined (NDEBUG)
04929     #undef  TX_ASSERT
04930     #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \
04931                                                            "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 )
04932 #else
04933     #undef  TX_ASSERT
04934     #define TX_ASSERT( cond ) ((void) 1)
04935 
04936 #endif
04937 
04938 #ifdef assert
04939     #undef assert
04940 #endif
04941 
04942 #define assert( cond )        TX_ASSERT (cond)
04943 
04944 //{----------------------------------------------------------------------------------------------------------------
04971 //}----------------------------------------------------------------------------------------------------------------
04972 
04973 #if !defined (NDEBUG)
04974     #define asserted          || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.")
04975 
04976 #else
04977     #define asserted          || _txNOP (0)
04978 
04979 #endif
04980 
04981 #define verified              asserted  //!< For compatibility with assert macro
04982 
04984 #define TX_NEEDED             asserted  //!< For compatibility with earlier releases
04985 
04986 
04987 //{----------------------------------------------------------------------------------------------------------------
05015 //}----------------------------------------------------------------------------------------------------------------
05016 
05017 #if !defined (NDEBUG)
05018     #undef  verify
05019     #define verify            assert
05020 
05021 #else
05022     #undef  verify
05023     #define verify( expr )    ( expr )
05024 
05025 #endif
05026 
05027 //{----------------------------------------------------------------------------------------------------------------
05046 //}----------------------------------------------------------------------------------------------------------------
05047 
05048 #if !defined (FOR_DOXYGEN_ONLY)
05049     #define TX_ERROR( ... )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__)
05050 #else
05051     #define TX_ERROR( msg )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg)
05052 #endif
05053 
05055     #define TX_THROW          TX_ERROR  //!< For compatibility with earlier TXLib releases
05056 
05057 
05058 //{----------------------------------------------------------------------------------------------------------------
05074 //}----------------------------------------------------------------------------------------------------------------
05075 
05076 #if !defined (NDEBUG)
05077     #define TX_DEBUG_ERROR(...)  TX_ERROR (__VA_ARGS__)
05078 
05079 #else
05080     #define TX_DEBUG_ERROR(...)  ((void) 0)
05081 
05082 #endif
05083 
05084 //{----------------------------------------------------------------------------------------------------------------
05104 //}----------------------------------------------------------------------------------------------------------------
05105 
05106 #ifdef FOR_DOXYGEN_ONLY
05107 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05108 #endif
05109 
05111 
05112 #ifdef _MSC_VER
05113 #define txDump( ... )           _txDump ((const void*)(uintptr_t) __VA_ARGS__)
05114 #else
05115 #define txDump( address, ... )  _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__)
05116 #endif
05117 
05118 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05119 
05121 
05122 //{----------------------------------------------------------------------------------------------------------------
05148 //}----------------------------------------------------------------------------------------------------------------
05149 
05150 #define txStackBackTrace()    _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true);
05151 
05152 //{----------------------------------------------------------------------------------------------------------------
05174 //}----------------------------------------------------------------------------------------------------------------
05176 
05177 std::string txDemangle (const char* mangledName);
05178 char*       txDemangle (const char* mangledName, std::nomeow_t);
05179 
05180 #define txTypename(value)     txDemangle (typeid (value) .name()) .c_str()
05181 
05183 //{----------------------------------------------------------------------------------------------------------------
05210 //}----------------------------------------------------------------------------------------------------------------
05211 
05212 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue);
05213 
05214 //{----------------------------------------------------------------------------------------------------------------
05227 //}----------------------------------------------------------------------------------------------------------------
05229 
05230 #define _                     ,
05231 #define TX_COMMA              ,  //!< Синоним макроса _ (@ref _ "символ подчеркивания")
05232 
05234 
05235 //{----------------------------------------------------------------------------------------------------------------
05295 //}----------------------------------------------------------------------------------------------------------------
05296 
05297 #ifdef FOR_DOXYGEN_ONLY
05298 
05299     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType )
05300 
05301 #else
05302 
05303     // Hand-made DLLIMPORT helper
05304 
05305     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... )               \
05306             retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \
05307                                                             _txDllImport ((libName), #funcName, (required))
05308 #endif
05309 
05311 //}
05312 //=================================================================================================================
05313 
05314 //=================================================================================================================
05315 //{          Back-hole (I hope, not an ass-hole:) of the library)
05317 //=================================================================================================================
05319 //{----------------------------------------------------------------------------------------------------------------
05471 //}----------------------------------------------------------------------------------------------------------------
05472 
05473 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL);
05474 
05475 //{----------------------------------------------------------------------------------------------------------------
05500 //}----------------------------------------------------------------------------------------------------------------
05501 
05502 bool txLock (bool wait = true);
05503 
05504 //{----------------------------------------------------------------------------------------------------------------
05515 //}----------------------------------------------------------------------------------------------------------------
05517 
05518 bool txUnlock();
05519 
05521 template <typename T> inline T txUnlock (T value);
05523 
05525 
05526 //{----------------------------------------------------------------------------------------------------------------
05549 //}----------------------------------------------------------------------------------------------------------------
05550 
05551 #define txGDI( command, dc )  ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) )
05552 
05553 //{----------------------------------------------------------------------------------------------------------------
05576 //}----------------------------------------------------------------------------------------------------------------
05577 
05578 #ifndef   FOR_DOXYGEN_ONLY
05579 
05580 const int     _TX_CODEPAGE  =   1251;
05581 
05582 #ifndef __CYGWIN__
05583 const char    _TX_LOCALE[]  =  "Russian";
05584 #else
05585 const char    _TX_LOCALE[]  =  "ru_RU.CP1251";
05586 #endif
05587 
05588 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP";
05589 
05590 #endif
05591 
05592 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE);
05593 
05594 //{----------------------------------------------------------------------------------------------------------------
05607 //}----------------------------------------------------------------------------------------------------------------
05608 
05609 int txPause (const char* message, ...) tx_printfy (1);
05610 
05612 //}
05613 //=================================================================================================================
05614 
05615 //=================================================================================================================
05616 //{          Tune-up constants and variables
05618 //=================================================================================================================
05620 //{----------------------------------------------------------------------------------------------------------------
05630 //}----------------------------------------------------------------------------------------------------------------
05631 
05632 #ifndef TX_COMPILED
05633 
05634        char _txLogName[MAX_PATH]          = "";
05635 
05636 #endif // TX_COMPILED
05637 
05638 extern char _txLogName[];
05639 
05640 //{----------------------------------------------------------------------------------------------------------------
05672 //}----------------------------------------------------------------------------------------------------------------
05673 
05674 #if  defined  (_TX_NOINIT)
05675 
05676     #undef     _TX_NOINIT
05677     #define    _TX_NOINIT                 1
05678 
05679 #else
05680 
05681     #define    _TX_NOINIT                 0
05682 
05683 #endif
05684 
05685 //{----------------------------------------------------------------------------------------------------------------
05729 //}----------------------------------------------------------------------------------------------------------------
05730 
05731 #if !defined (TX_CONSOLE_MODE)
05732 
05733     #define   TX_CONSOLE_MODE             SW_HIDE
05734 
05735 #endif
05736 
05737 //{----------------------------------------------------------------------------------------------------------------
05741 //}----------------------------------------------------------------------------------------------------------------
05742 
05743 #if !defined (TX_CONSOLE_FONT)
05744 
05745     #define   TX_CONSOLE_FONT             "Lucida Console"
05746 
05747 #endif
05748 
05749 //{----------------------------------------------------------------------------------------------------------------
05760 //}----------------------------------------------------------------------------------------------------------------
05761 
05762 #ifndef TX_COMPILED
05763 
05764        int _txWindowStyle                 = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
05765 
05766 #endif // TX_COMPILED
05767 
05768 extern int _txWindowStyle;
05769 
05770 //{----------------------------------------------------------------------------------------------------------------
05773 //}----------------------------------------------------------------------------------------------------------------
05774 
05775 #ifndef TX_COMPILED
05776 
05777        unsigned _txCursorBlinkInterval    = 500;
05778 
05779 #endif // TX_COMPILED
05780 
05781 extern unsigned _txCursorBlinkInterval;
05782 
05783 //{----------------------------------------------------------------------------------------------------------------
05787 //}----------------------------------------------------------------------------------------------------------------
05788 
05789 #ifndef TX_COMPILED
05790 
05791        unsigned _txWindowUpdateInterval   = 25;
05792 
05793 #endif // TX_COMPILED
05794 
05795 extern unsigned _txWindowUpdateInterval;
05796 
05797 //{----------------------------------------------------------------------------------------------------------------
05806 //}----------------------------------------------------------------------------------------------------------------
05807 
05808 #ifdef FOR_DOXYGEN_ONLY
05809 #define       TX_USE_SFML
05810 #endif
05811 
05812 //{----------------------------------------------------------------------------------------------------------------
05815 //}----------------------------------------------------------------------------------------------------------------
05816 
05817 const int _TX_TIMEOUT                     = 1000
05818 
05819 #if  defined  (_TX_ALLOW_TRACE)
05820     * 2
05821 #endif
05822 
05823 #if  defined  (TX_TRACE)
05824     * 3
05825 #endif
05826 
05827 #if  defined  (_TX_USE_DEVPARTNER)
05828     * 10
05829 #endif
05830     ;
05831 
05832 //{----------------------------------------------------------------------------------------------------------------
05873 //}----------------------------------------------------------------------------------------------------------------
05874 
05875 #ifndef TX_COMPILED
05876 
05877        bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
05878                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp) = NULL;
05879 
05880 #endif // TX_COMPILED
05881 
05882 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
05883                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp);
05884 
05885 //{----------------------------------------------------------------------------------------------------------------
05888 //}----------------------------------------------------------------------------------------------------------------
05889 
05890 const unsigned _TX_BUFSIZE                =  1024,
05891                _TX_BIGBUFSIZE             = _TX_BUFSIZE *  2,  
05892                _TX_HUGEBUFSIZE            = _TX_BUFSIZE * 20,  
05893 
05894                _TX_STACKSIZE              = 64 * 1024;         
05895 
05896 //{----------------------------------------------------------------------------------------------------------------
05899 //}----------------------------------------------------------------------------------------------------------------
05900 
05901 #if !defined (_TX_EXCEPTIONS_LIMIT)
05902     #define   _TX_EXCEPTIONS_LIMIT        16
05903 #endif
05904 
05905 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT)
05906     #define   _TX_FATAL_EXCEPTIONS_LIMIT  16                   //!< Максимальное количество фатальных исключений.
05907 #endif
05908 
05909 //{----------------------------------------------------------------------------------------------------------------
05912 //}----------------------------------------------------------------------------------------------------------------
05913 
05914 #ifdef FOR_DOXYGEN_ONLY
05915 #define       _TX_FULL_STACKTRACE
05916 #endif
05917 
05918 //{----------------------------------------------------------------------------------------------------------------
05921 //}----------------------------------------------------------------------------------------------------------------
05922 
05923 #ifndef TX_COMPILED
05924 
05925        bool _txProcessSystemWarnings      = true;
05926 
05927 #endif // TX_COMPILED
05928 
05929 extern bool _txProcessSystemWarnings;
05930 
05931 //{----------------------------------------------------------------------------------------------------------------
05945 //}----------------------------------------------------------------------------------------------------------------
05946 
05947 #if !defined  (_TX_WAITABLE_PARENTS)
05948     #define    _TX_WAITABLE_PARENTS       "Winpty-agent.exe:Clion.exe, "            /* 0: CLion32       */ \
05949                                           "Winpty-agent.exe:Clion64.exe, "          /* 1: CLion64       */ \
05950                                           "starter.exe:eclipse.exe, "               /* 2: Eclipse 4     */ \
05951                                           "starter.exe:javaw.exe, "                 /* 3: Eclipse 3     */ \
05952                                           "cmd.exe:devenv.exe, "                    /* 4: MSVS 2003+    */ \
05953                                           "VSDebugConsole.exe:devenv.exe, "         /* 5: MSVS 2019+    */ \
05954                                           "VSDebugConsole.exe:msvsmon.exe, "        /* 6: MSVS 2022 x86 */ \
05955                                           "consolepauser.exe:devcpp.exe, "          /* 7: Dev-Cpp       */ \
05956                                           "cb_console_runner.exe:codeblocks.exe"    /* 8: CodeBlocks 8+ */
05957 #endif
05958 
05959 //{----------------------------------------------------------------------------------------------------------------
05978 //}----------------------------------------------------------------------------------------------------------------
05979 
05980 #if !defined (_TX_ALLOW_KILL_PARENT)            // DISCLAIMER: Я не призываю к убийству родителей.
05981     #define   _TX_ALLOW_KILL_PARENT       true  //             Это технический термин.
05982 #endif                                          //             г_дам юристам привет.
05983 
05984 //{----------------------------------------------------------------------------------------------------------------
05994 //}----------------------------------------------------------------------------------------------------------------
05995 
05996 #ifndef TX_COMPILED
05997 
05998        int    _txWatchdogTimeout          = 10*_TX_TIMEOUT;
05999 
06000 #endif // TX_COMPILED
06001 
06002 extern int    _txWatchdogTimeout;
06003 
06004 //{----------------------------------------------------------------------------------------------------------------
06073 //}----------------------------------------------------------------------------------------------------------------
06075 
06076 #ifdef FOR_DOXYGEN_ONLY
06077 
06078     #define TX_COMPILED
06079 
06080     #endif
06081 
06083 
06085 //}
06086 //=================================================================================================================
06087 
06088 //=================================================================================================================
06089 //{          Internal diagnostics
06091 //=================================================================================================================
06093 //{----------------------------------------------------------------------------------------------------------------
06133 //}----------------------------------------------------------------------------------------------------------------
06134 
06135 #ifdef FOR_DOXYGEN_ONLY
06136 #define _TX_ALLOW_TRACE
06137 #endif
06138 
06139 //{----------------------------------------------------------------------------------------------------------------
06169 //}----------------------------------------------------------------------------------------------------------------
06170 
06171 #ifdef FOR_DOXYGEN_ONLY
06172 #define       TX_TRACE
06173 #endif
06174 
06175 #if !defined (TX_TRACE)
06176     #define   TX_TRACE  { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); }
06177 #endif
06178 
06180 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...);
06182 
06183 //{----------------------------------------------------------------------------------------------------------------
06186 
06187 #ifndef   FOR_DOXYGEN_ONLY
06188 
06189 struct _txLoc
06190     {
06191     const char*   func;
06192     const char*   file;
06193     int           line;
06194 
06195     int           inTX;   // We are inside one of TXLib functions
06196     int           trace;  // Internal TX trace level, when enabled by _TX_ALLOW_TRACE
06197 
06198     const _txLoc* prev;   // Caller's location
06199 
06200     static _txLoc _tx_thread Cur;
06201     };
06202 
06203 struct _txFuncEntry
06204     {
06205     typedef _txFuncEntry this_t;
06206 
06207     _txLoc loc;
06208 
06209     _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; }
06210     void restore()                     { _txLoc::Cur = loc;                           }
06211    ~_txFuncEntry()                     { restore();                                   }
06212 
06213     private:
06214             _txFuncEntry (const this_t&) _tx_delete;
06215     this_t& operator =   (const this_t&) _tx_delete;
06216     };
06217 
06218 #if defined (_GCC_VER)
06219 
06220     inline const char* __txLocCurSet (const char* _file, int _line, const char* _func)
06221         { _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; }
06222 
06223 #else
06224 
06225     #define __txLocCurSet( _file, _line, _func ) \
06226         ( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) )
06227 
06228 #endif
06229 
06230 #define _txLocCurSet()     __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__)
06231 
06232 #define _txLocLvlSet(lvl)  { _txLoc::Cur.trace = (lvl); }
06233 
06234 //{----------------------------------------------------------------------------------------------------------------
06235 
06236 #if defined ($0)
06237     #undef   $0
06238     #endif
06239 
06240 #if defined ($1)
06241     #undef   $1
06242     #endif
06243 
06244 #if defined ($2)
06245     #undef   $2
06246     #endif
06247 
06248 #if defined ($3)
06249     #undef   $3
06250     #endif
06251 
06252 #if defined ($4)
06253     #undef   $4
06254     #endif
06255 
06256 #if defined ($5)
06257     #undef   $5
06258     #endif
06259 
06260 #if defined ($6)
06261     #undef   $6
06262     #endif
06263 
06264 #if defined ($7)
06265     #undef   $7
06266     #endif
06267 
06268 #if defined ($8)
06269     #undef   $8
06270     #endif
06271 
06272 #if defined ($9)
06273     #undef   $9
06274     #endif
06275 
06276 #if defined ($)
06277     #undef   $
06278     #endif
06279 
06280 #if defined ($$)
06281     #undef   $$
06282     #endif
06283 
06284 //}
06285 //-----------------------------------------------------------------------------------------------------------------
06286 
06287 #if defined (_TX_ALLOW_TRACE)
06288 
06289     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl);    $;          }
06290 
06291     #define  $           { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } }
06292 
06293     #define  $$          { __txFuncEntry.restore();                                                  }
06294 
06295 #elif defined (_DEBUG)
06296 
06297     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; {                                 $;          }
06298 
06299     #define  $           { _txLocCurSet();                                                           }
06300 
06301     #define  $$          { __txFuncEntry.restore();                                                  }
06302 
06303 #else
06304 
06305     #define _txEntry(lvl)  ;
06306     #define  $             ;
06307     #define  $$            ;
06308 
06309 #endif
06310 
06311 //{----------------------------------------------------------------------------------------------------------------
06312 
06313 #define      $0            _txEntry (0)  // (Log level unchanged)
06314 #define      $1            _txEntry (1)  // Regular functions
06315 #define      $2            _txEntry (2)  // Resvd
06316 #define      $3            _txEntry (3)  // Init/Cleanup
06317 #define      $4            _txEntry (4)  // Init/Cleanup, misc functions
06318 #define      $5            _txEntry (5)  // Error handling, entry points
06319 #define      $6            _txEntry (6)  // Error handling, main part
06320 #define      $7            _txEntry (7)  // Error handling, misc functions
06321 #define      $8            _txEntry (8)  // Canvas worker thread
06322 #define      $9            _txEntry (9)  // Resvd
06323 
06324 //}
06325 //-----------------------------------------------------------------------------------------------------------------
06326 
06327 #endif // FOR_DOXYGEN_ONLY
06328 
06331 //}----------------------------------------------------------------------------------------------------------------
06332 
06334 //}
06335 //=================================================================================================================
06336 
06337 //=================================================================================================================
06338 //{          Sweet critical section blocking: txAutoLock class
06339 //=================================================================================================================
06340 
06341 //{----------------------------------------------------------------------------------------------------------------
06357 //}----------------------------------------------------------------------------------------------------------------
06358 
06360 extern CRITICAL_SECTION _txCanvas_LockBackBuf;
06362 
06363 class txAutoLock
06364     {
06365     typedef txAutoLock this_t;
06366 
06367     public:
06368 
06369 //{----------------------------------------------------------------------------------------------------------------
06392 //}----------------------------------------------------------------------------------------------------------------
06393 
06394     explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) :
06395         cs_ (cs)
06396         {
06397 $1      if (!cs_) return;
06398 
06399         if (mandatory) {$    EnterCriticalSection (cs_);                   }
06400         else           {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); }
06401         }
06402 
06403 //{----------------------------------------------------------------------------------------------------------------
06416 //}----------------------------------------------------------------------------------------------------------------
06417 
06418     explicit txAutoLock (bool mandatory = true) :
06419         cs_ (NULL)
06420         {
06421 $1      new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory);
06422         }
06423 
06424 //{----------------------------------------------------------------------------------------------------------------
06426 //}----------------------------------------------------------------------------------------------------------------
06427 
06428    ~txAutoLock()
06429         {
06430 $1      if (!cs_) return;
06431 $       LeaveCriticalSection (cs_); cs_ = NULL;
06432         }
06433 
06434 //{----------------------------------------------------------------------------------------------------------------
06437 //}----------------------------------------------------------------------------------------------------------------
06438 
06439     operator bool () const
06440         {
06441 $1      return (cs_ != NULL);
06442         }
06443 
06444 //{----------------------------------------------------------------------------------------------------------------
06446 //}----------------------------------------------------------------------------------------------------------------
06447 
06448 //  private:
06449     CRITICAL_SECTION* cs_;
06450 
06451 //{----------------------------------------------------------------------------------------------------------------
06453 //}----------------------------------------------------------------------------------------------------------------
06455 
06456     private:
06457             txAutoLock (const this_t&) _tx_delete;
06458     this_t& operator = (const this_t&) _tx_delete;
06459 
06461 
06462     };
06463 
06464 //}
06465 //=================================================================================================================
06466 
06467 //=================================================================================================================
06468 //{          Dialogs: txDialog class
06470 //=================================================================================================================
06472 //{----------------------------------------------------------------------------------------------------------------
06493 //}----------------------------------------------------------------------------------------------------------------
06494 
06495 struct txDialog
06496     {
06497     typedef txDialog this_t;
06498 
06499 //{----------------------------------------------------------------------------------------------------------------
06512 //}----------------------------------------------------------------------------------------------------------------
06513 
06514     public:
06515     enum CONTROL
06516         {
06517         DIALOG    = (int) 0x00000000,            
06518         BUTTON    = (int) 0xFFFF0080,            
06519         EDIT      = (int) 0xFFFF0081,            
06520         STATIC    = (int) 0xFFFF0082,            
06521         LISTBOX   = (int) 0xFFFF0083,            
06522         SCROLLBAR = (int) 0xFFFF0084,            
06523         COMBOBOX  = (int) 0xFFFF0085,            
06524         END       = (int) 0x00000000             
06525         };
06526 
06527 //{----------------------------------------------------------------------------------------------------------------
06544 //}----------------------------------------------------------------------------------------------------------------
06545 
06546     public:
06547     struct Layout
06548         {                                        //-V802
06549         CONTROL     wndclass;                    
06550         const char* caption;                     
06551         WORD        id;                          
06552         short        x;                          
06553         short        y;                          
06554         short       sx;                          
06555         short       sy;                          
06556         DWORD       style;                       
06557 
06558         const char* font;                        
06559         WORD        fontsize;                    
06560         };
06561 
06562 //{----------------------------------------------------------------------------------------------------------------
06570 //}----------------------------------------------------------------------------------------------------------------
06571 
06572     public:
06573     txDialog();
06574 
06575 //{----------------------------------------------------------------------------------------------------------------
06585 //}----------------------------------------------------------------------------------------------------------------
06586 
06587     explicit txDialog (const Layout* layout);
06588 
06589 //{----------------------------------------------------------------------------------------------------------------
06591 //}----------------------------------------------------------------------------------------------------------------
06592 
06593     virtual ~txDialog() {};
06594 
06595 //{----------------------------------------------------------------------------------------------------------------
06607 //}----------------------------------------------------------------------------------------------------------------
06608 
06609     const Layout* setLayout (const Layout *layout);
06610 
06611 //{----------------------------------------------------------------------------------------------------------------
06629 //}----------------------------------------------------------------------------------------------------------------
06630 
06631     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam);
06632 
06633 //{----------------------------------------------------------------------------------------------------------------
06649 //}----------------------------------------------------------------------------------------------------------------
06650 
06651     intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0);
06652 
06653 //{----------------------------------------------------------------------------------------------------------------
06666 //}----------------------------------------------------------------------------------------------------------------
06667 
06668     intptr_t dialogBox (WORD resource);
06669 
06670 //{----------------------------------------------------------------------------------------------------------------
06672 //}----------------------------------------------------------------------------------------------------------------
06673 
06674     private:
06675             txDialog   (const this_t&) _tx_delete;
06676     this_t& operator = (const this_t&) _tx_delete;
06677 
06678 //{----------------------------------------------------------------------------------------------------------------
06680 //}----------------------------------------------------------------------------------------------------------------
06681 
06682     protected:
06683     static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
06684 
06685 //{----------------------------------------------------------------------------------------------------------------
06687 //}----------------------------------------------------------------------------------------------------------------
06688 
06689     private:
06690     const Layout* layout_;
06691     };
06692 
06694 //}
06695 //=================================================================================================================
06696 
06697 //=================================================================================================================
06698 //{          Dialogs: Message Map macros
06700 //=================================================================================================================
06702 //{----------------------------------------------------------------------------------------------------------------
06723 //}----------------------------------------------------------------------------------------------------------------
06724 
06725 #define TX_BEGIN_MESSAGE_MAP()                                                                 \
06726     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \
06727         {                                                                                      \
06728         int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result;     \
06729                                                                                                \
06730         switch (_msg)                                                                          \
06731             {                                                                                  \
06732             case WM_NULL:
06733 
06734 //{----------------------------------------------------------------------------------------------------------------
06753 //}----------------------------------------------------------------------------------------------------------------
06754 
06755 #define TX_HANDLE( id )                                                                        \
06756             break;                                                                             \
06757             case (id):
06758 
06759 //{----------------------------------------------------------------------------------------------------------------
06779 //}----------------------------------------------------------------------------------------------------------------
06780 
06781 #define TX_COMMAND_MAP                                                                         \
06782             default: break;                                                                    \
06783             }                                                                                  \
06784                                                                                                \
06785         if (_msg == WM_COMMAND) switch (LOWORD (_wParam))                                      \
06786             {                                                                                  \
06787             case 0:
06788 
06789 //{----------------------------------------------------------------------------------------------------------------
06808 //}----------------------------------------------------------------------------------------------------------------
06809 
06810 #define TX_END_MESSAGE_MAP                                                                     \
06811             default: break;                                                                    \
06812             }                                                                                  \
06813                                                                                                \
06814         return FALSE;                                                                          \
06815         }
06816 
06818 //}
06819 //=================================================================================================================
06820 
06821 //=================================================================================================================
06822 //{          Dialogs: txDialog example: txInputBox()
06824 //=================================================================================================================
06826 //{----------------------------------------------------------------------------------------------------------------
06846 //}----------------------------------------------------------------------------------------------------------------
06847 
06848 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard;
06849 
06850 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06851 
06852 const char* txInputBox (const char* text, const char* caption, const char* input)
06853     {
06854     //-------------------------------------------------------------------------------------------------------------
06855     // Если не указаны параметры, приходится использовать хоть какие-то надписи.
06856     // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название.
06857     //-------------------------------------------------------------------------------------------------------------
06858 
06859     if (!text)    text    = "Введите строку:";
06860     if (!caption) caption = txGetModuleFileName (false);
06861     if (!input)   input   = "";
06862 
06863     //-------------------------------------------------------------------------------------------------------------
06864     // Идентификаторы элементов диалога. Они требуются в GetDlgItemText().
06865     // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически.
06866     // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы
06867     // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения,
06868     // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о
06869     //-------------------------------------------------------------------------------------------------------------
06870 
06871     #define ID_TEXT_  101
06872     #define ID_INPUT_ 102
06873 
06874     //-------------------------------------------------------------------------------------------------------------
06875     // Задание макета (вида) диалога в виде массива структур.
06876     // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив
06877     // становится похож на описание ресурса диалога в .rc-файле.
06878     // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com).
06879     //-------------------------------------------------------------------------------------------------------------
06880 
06881     txDialog::Layout layout[] =
06882 
06883     //----------------------+----------+-----------+-----------------+---------------------------------------------
06884     //     Тип элемента     | Имя      | Иденти-   |   Координаты    | Флаги элементов
06885     //     диалога          | элемента | фикатор   |-----------------| (см. описание элементов
06886     //                      |          | элемента  | X | Y |Шир.|Выс.| окон диалога в MSDN)
06887     //----------------------+----------+-----------+---+---+----+----+---------------------------------------------
06888     //                      |          |           |   |   |    |    |
06889         {{ txDialog::DIALOG,  caption,   0,           0,  0, 240,  85                                                    },
06890          { txDialog::STATIC,  text,      ID_TEXT_,   10, 10, 150,  40, SS_LEFT                                           },
06891          { txDialog::EDIT,    input,     ID_INPUT_,  10, 60, 220,  15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP },
06892          { txDialog::BUTTON,  "&OK",     IDOK,      180, 10,  50,  15, BS_DEFPUSHBUTTON                     | WS_TABSTOP },
06893          { txDialog::BUTTON,  "&Cancel", IDCANCEL,  180, 30,  50,  15, BS_PUSHBUTTON                        | WS_TABSTOP },
06894          { txDialog::END                                                                                                 }};
06895 
06896     //-------------------------------------------------------------------------------------------------------------
06897     // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним.
06898     // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она
06899     // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную
06900     // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее
06901     // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG).
06902     //-------------------------------------------------------------------------------------------------------------
06903     struct inputDlg : txDialog
06904         {
06905         char str [1024];
06906 
06907         //---------------------------------------------------------------------------------------------------------
06908 
06909         inputDlg() :
06910             str()
06911             {}
06912 
06913         //---------------------------------------------------------------------------------------------------------
06914 
06915         TX_BEGIN_MESSAGE_MAP()    // Карта сообщений (на самом деле это начало оконной функции).  //-V2525
06916 
06917             TX_COMMAND_MAP        // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch).
06918 
06919                 //-------------------------------------------------------------------------------------------------
06920                 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия
06921                 // диалога строка ввода умрет и текст уже из нее получить.
06922                 // Этот макрос на самом деле превращается в case из оператора switch.
06923                 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP().
06924                 //-------------------------------------------------------------------------------------------------
06925 
06926                 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1);
06927 
06928         TX_END_MESSAGE_MAP        //-V2522
06929 
06930         //---------------------------------------------------------------------------------------------------------
06931         // Конец внутреннего класса диалога
06932         //---------------------------------------------------------------------------------------------------------
06933         };
06934 
06935     //-------------------------------------------------------------------------------------------------------------
06936     // Убираем дефайны, чтобы потом не мешали.
06937     // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом
06938     // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _.
06939     // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны.
06940     //-------------------------------------------------------------------------------------------------------------
06941 
06942     #undef ID_TEXT_
06943     #undef ID_INPUT_
06944 
06945     //-------------------------------------------------------------------------------------------------------------
06946     // Это статический объект, потому что строка в нем должна жить после завершения функции.
06947     //-------------------------------------------------------------------------------------------------------------
06948 
06949     static inputDlg dlg;
06950 
06951     //-------------------------------------------------------------------------------------------------------------
06952     // Передаем layout и запускаем окно диалога
06953     //-------------------------------------------------------------------------------------------------------------
06954 
06955     dlg.dialogBox (layout);
06956 
06957     //-------------------------------------------------------------------------------------------------------------
06958     // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет
06959     // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать
06960     // синтаксически можно, но ведет к серьезным ошибкам.
06961     //-------------------------------------------------------------------------------------------------------------
06962 
06963     return dlg.str;
06964     }
06965 
06966 #endif // TX_COMPILED
06967 
06969 //}
06970 //=================================================================================================================
06971 
06972 //}
06973 //=================================================================================================================
06974 
06975 //=================================================================================================================
06976 //{          TXLIB IMPLEMENTATION
06977 //           Реализация функций библиотеки
06978 //=================================================================================================================
06980 
06981 //-----------------------------------------------------------------------------------------------------------------
06982 //{          The Includes
06983 //-----------------------------------------------------------------------------------------------------------------
06984 
06985 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06986 
06987 _TX_END_NAMESPACE
06988 
06989 //-----------------------------------------------------------------------------------------------------------------
06990 
06991 #if defined (_MSC_VER)
06992     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
06993 
06994     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
06995     #pragma warning (disable: 4005)              // 'name': macro redefinition
06996 #endif
06997 
06998 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED)
06999     #undef   __STRICT_ANSI__
07000 #endif
07001 
07002 //-----------------------------------------------------------------------------------------------------------------
07003 
07004 #include <stdarg.h>
07005 #include <io.h>
07006 #include <fcntl.h>
07007 #include <process.h>
07008 #include <signal.h>
07009 #include <setjmp.h>
07010 #include <locale.h>
07011 #include <limits.h>
07012 #include <stdint.h>
07013 
07014 #include <map>
07015 #include <numeric>
07016 #include <exception>
07017 #include <stdexcept>
07018 
07019 #include <tlhelp32.h>
07020 #include <shellapi.h>
07021 
07022 #if defined (_GCC_VER)
07023 
07024 #include <shlobj.h>
07025 
07026 #include <cxxabi.h>
07027 #include <unwind.h>
07028 
07029 #endif
07030 
07031 #if defined (__CYGWIN__)
07032 
07033 #include <stdarg.h>
07034 #include <unistd.h>
07035 #include <termios.h>
07036 
07037 #endif
07038 
07039 #if defined (_MSC_VER)
07040 
07041 #include <new.h>
07042 
07043 #include <shlobj.h>
07044 #include <ntstatus.h>
07045 #include <crtdbg.h>
07046 #include <rtcapi.h>
07047 #include <dbghelp.h>
07048 
07049 #endif
07050 
07051 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800)  // MSVC 2013
07052 #include <inttypes.h>
07053 #endif
07054 
07055 //-----------------------------------------------------------------------------------------------------------------
07056 
07057 #if defined (TX_USE_SPEAK) //--------------------------------------------------------------------------------------
07058 #include <SAPI.h>          // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :(
07059 #endif                     //--------------------------------------------------------------------------------------
07060 
07061 //-----------------------------------------------------------------------------------------------------------------
07062 
07063 #if defined (_MSC_VER)
07064     #pragma warning (pop)                        // MSVC: Restore max level
07065 #endif
07066 
07067 #if defined (__STRICT_ANSI__UNDEFINED)
07068     #define  __STRICT_ANSI__                     // Redefine back
07069 #endif
07070 
07071 //-----------------------------------------------------------------------------------------------------------------
07072 
07073 _TX_BEGIN_NAMESPACE
07074 
07075 #endif // TX_COMPILED
07076 
07077 //}
07078 //-----------------------------------------------------------------------------------------------------------------
07079 
07080 //=================================================================================================================
07081 //{          DLL functions import, missing types definitions
07083 //=================================================================================================================
07085 
07086 //-----------------------------------------------------------------------------------------------------------------
07087 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers.
07088 //  Copied from Windows SDK 7.0a.
07089 //-----------------------------------------------------------------------------------------------------------------
07090 
07091 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07092 
07093 namespace Win32 {
07094 
07095 #ifndef AC_SRC_ALPHA
07096 #define AC_SRC_ALPHA                             0x01
07097 #endif
07098 
07099 #ifndef SMTO_ERRORONEXIT
07100 #define SMTO_ERRORONEXIT                         0x0020
07101 #endif
07102 
07103 #ifndef NT_CONSOLE_PROPS_SIG
07104 #define NT_CONSOLE_PROPS_SIG                     0xA0000002
07105 #endif
07106 
07107 #ifndef NIIF_INFO
07108 #define NIIF_INFO                                0x00000001
07109 #define NIIF_WARNING                             0x00000002
07110 #define NIIF_ERROR                               0x00000003
07111 #endif
07112 
07113 #ifndef NIF_INFO
07114 #define NIF_STATE                                0x00000008
07115 #define NIF_INFO                                 0x00000010
07116 #endif
07117 
07118 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
07119 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS   0x00000004
07120 #endif
07121 
07122 #ifndef SYMOPT_CASE_INSENSITIVE
07123 #define SYMOPT_CASE_INSENSITIVE                  0x00000001
07124 #define SYMOPT_UNDNAME                           0x00000002
07125 #define SYMOPT_DEFERRED_LOADS                    0x00000004
07126 #define SYMOPT_NO_CPP                            0x00000008
07127 #define SYMOPT_LOAD_LINES                        0x00000010
07128 #define SYMOPT_OMAP_FIND_NEAREST                 0x00000020
07129 #define SYMOPT_LOAD_ANYTHING                     0x00000040
07130 #define SYMOPT_IGNORE_CVREC                      0x00000080
07131 #define SYMOPT_NO_UNQUALIFIED_LOADS              0x00000100
07132 #define SYMOPT_FAIL_CRITICAL_ERRORS              0x00000200
07133 #define SYMOPT_EXACT_SYMBOLS                     0x00000400
07134 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS            0x00000800
07135 #define SYMOPT_IGNORE_NT_SYMPATH                 0x00001000
07136 #define SYMOPT_INCLUDE_32BIT_MODULES             0x00002000
07137 #define SYMOPT_PUBLICS_ONLY                      0x00004000
07138 #define SYMOPT_NO_PUBLICS                        0x00008000
07139 #define SYMOPT_AUTO_PUBLICS                      0x00010000
07140 #define SYMOPT_NO_IMAGE_SEARCH                   0x00020000
07141 #define SYMOPT_SECURE                            0x00040000
07142 #define SYMOPT_NO_PROMPTS                        0x00080000
07143 #define SYMOPT_ALLOW_ZERO_ADDRESS                0x01000000
07144 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT         0x02000000
07145 #define SYMOPT_FAVOR_COMPRESSED                  0x00800000
07146 #define SYMOPT_FLAT_DIRECTORY                    0x00400000
07147 #define SYMOPT_IGNORE_IMAGEDIR                   0x00200000
07148 #define SYMOPT_OVERWRITE                         0x00100000
07149 #define SYMOPT_DEBUG                             0x80000000
07150 #endif
07151 
07152 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66.
07153 
07154 #ifndef STATUS_POSSIBLE_DEADLOCK
07155 #define STATUS_POSSIBLE_DEADLOCK                 0xC0000194
07156 #endif
07157 
07158 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS
07159 #define STATUS_FLOAT_MULTIPLE_FAULTS             0xC00002B4
07160 #endif
07161 
07162 #ifndef STATUS_STACK_BUFFER_OVERRUN
07163 #define STATUS_STACK_BUFFER_OVERRUN              0xC0000409
07164 #endif
07165 
07166 #ifndef STATUS_ASSERTION_FAILURE
07167 #define STATUS_ASSERTION_FAILURE                 0xC0000420
07168 #endif
07169 
07170 #ifndef STATUS_WX86_BREAKPOINT
07171 #define STATUS_WX86_BREAKPOINT                   0x4000001F
07172 #endif
07173 
07174 #ifndef DBG_PRINTEXCEPTION_C
07175 #define DBG_PRINTEXCEPTION_C                     0x40010006  // OutputDebugStringA() call
07176 #endif
07177 
07178 #ifndef DBG_PRINTEXCEPTION_WIDE_C
07179 #define DBG_PRINTEXCEPTION_WIDE_C                0x4001000A  // OutputDebugStringW() call
07180 #endif
07181 
07182 #ifndef DBG_THREAD_NAME
07183 #define DBG_THREAD_NAME                          0x406D1388
07184 #endif
07185 
07186 #define EXCEPTION_CPP_MSC                        0xE06D7363  // '?msc'
07187 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1       0x19930520  // '?msc' version magic, see ehdata.h
07188 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2       0x19930521  // '?msc' version magic
07189 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3       0x19930522  // '?msc' version magic
07190 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1  0x01994000  // '?msc' version magic
07191 
07192 #define EXCEPTION_CPP_GCC                        0x20474343  // ' GCC'
07193 #define EXCEPTION_CPP_GCC_UNWIND                 0x21474343  // '!GCC'
07194 #define EXCEPTION_CPP_GCC_FORCED                 0x22474343  // '"GCC'
07195 
07196 #define EXCEPTION_CLR_FAILURE                    0xE0434f4D  // 'аCOM'
07197 
07198 #define EXCEPTION_CPP_BORLAND_BUILDER            0x0EEDFAE6  // Should never occur here
07199 #define EXCEPTION_CPP_BORLAND_DELPHI             0x0EEDFADE  // Should never occur here
07200 
07201 #pragma pack (push, 1)
07202 
07203 struct CONSOLE_CURSOR_INFO
07204     {
07205     DWORD dwSize;
07206     BOOL bVisible;
07207     };
07208 
07209 struct CONSOLE_FONT_INFO
07210     {
07211     DWORD nFont;
07212     COORD dwFontSize;
07213     };
07214 
07215 struct CONSOLE_FONT_INFOEX
07216     {
07217     ULONG cbSize;
07218     DWORD nFont;
07219     COORD dwFontSize;
07220     UINT  FontFamily;
07221     UINT  FontWeight;
07222     WCHAR FaceName[LF_FACESIZE];
07223     };
07224 
07225 struct DATABLOCK_HEADER
07226     {
07227     DWORD cbSize;
07228     DWORD dwSignature;
07229     };
07230 
07231 struct NT_CONSOLE_PROPS
07232     {
07233     DATABLOCK_HEADER dbh;
07234 
07235     WORD  wFillAttribute;
07236     WORD  wPopupFillAttribute;
07237     COORD dwScreenBufferSize;
07238     COORD dwWindowSize;
07239     COORD dwWindowOrigin;
07240     DWORD nFont;
07241     DWORD nInputBufferSize;
07242     COORD dwFontSize;
07243     UINT  uFontFamily;
07244     UINT  uFontWeight;
07245     WCHAR FaceName[LF_FACESIZE];
07246     UINT  uCursorSize;
07247     BOOL  bFullScreen;
07248     BOOL  bQuickEdit;
07249     BOOL  bInsertMode;
07250     BOOL  bAutoPosition;
07251     UINT  uHistoryBufferSize;
07252     UINT  uNumberOfHistoryBuffers;
07253     BOOL  bHistoryNoDup;
07254 
07255     COLORREF ColorTable[16];
07256     };
07257 
07258 struct FLASHWINFO
07259     {
07260     UINT  cbSize;
07261     HWND  hwnd;
07262     DWORD dwFlags;
07263     UINT  uCount;
07264     DWORD dwTimeout;
07265     };
07266 
07267 enum TBPFLAG
07268     {
07269     TBPF_NOPROGRESS    = 0x0,
07270     TBPF_INDETERMINATE = 0x1,
07271     TBPF_NORMAL        = 0x2,
07272     TBPF_ERROR         = 0x4,
07273     TBPF_PAUSED        = 0x8
07274     };
07275 
07276 #pragma pack (pop)
07277 
07278 const GUID IID_IShellLink             = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07279 const GUID IID_IShellLinkDataList     = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}};
07280 const GUID IID_IPersistFile           = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07281 
07282 const GUID IID_ITaskbarList3          = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}};
07283 const GUID CLSID_TaskbarList          = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}};
07284 
07285 const GUID CLSID_SpVoice              = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}};
07286 const GUID IID_ISpVoice               = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}};
07287 
07288 typedef DWORD     NTSTATUS;
07289 typedef ULONG_PTR KAFFINITY;
07290 typedef LONG      KPRIORITY;
07291 
07292 struct UNICODE_STRING
07293     {
07294     USHORT   Length;
07295     USHORT   MaximumLength;
07296     wchar_t* Buffer;
07297     };
07298 
07299 struct RTL_DRIVE_LETTER_CURDIR
07300     {
07301     USHORT         Flags;
07302     USHORT         Length;
07303     ULONG          TimeStamp;
07304     UNICODE_STRING DosPath;
07305     };
07306 
07307 struct CURDIR
07308     {
07309     UNICODE_STRING DosPath;
07310     void*          Handle;
07311     };
07312 
07313 struct RTL_USER_PROCESS_PARAMETERS
07314     {
07315     ULONG          AllocationSize;
07316     ULONG          Size;
07317     ULONG          Flags;
07318     ULONG          DebugFlags;
07319     HANDLE         ConsoleHandle;
07320     ULONG          ConsoleFlags;
07321     HANDLE         hStdInput;
07322     HANDLE         hStdOutput;
07323     HANDLE         hStdError;
07324     CURDIR         CurrentDirectory;
07325     UNICODE_STRING DllPath;
07326     UNICODE_STRING ImagePathName;
07327     UNICODE_STRING CommandLine;
07328     wchar_t*       Environment;
07329     ULONG          dwX;
07330     ULONG          dwY;
07331     ULONG          dwXSize;
07332     ULONG          dwYSize;
07333     ULONG          dwXCountChars;
07334     ULONG          dwYCountChars;
07335     ULONG          dwFillAttribute;
07336     ULONG          dwFlags;
07337     ULONG          wShowWindow;
07338     UNICODE_STRING WindowTitle;
07339     UNICODE_STRING Desktop;
07340     UNICODE_STRING ShellInfo;
07341     UNICODE_STRING RuntimeInfo;
07342     RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
07343     };
07344 
07345 struct PEB
07346     {
07347     BYTE  Reserved1[2];
07348     BYTE  BeingDebugged;
07349     BYTE  Reserved2[1];
07350     void* Reserved3[2];
07351     void* Ldr;
07352     RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
07353     void* Reserved4[3];
07354     void* AtlThunkSListPtr;
07355     void* Reserved5;
07356     ULONG Reserved6;
07357     void* Reserved7;
07358     ULONG Reserved8;
07359     ULONG AtlThunkSListPtr32;
07360     void* Reserved9[45];
07361     BYTE  Reserved10[96];
07362     void* PostProcessInitRoutine;
07363     BYTE  Reserved11[128];
07364     void* Reserved12[1];
07365     ULONG SessionId;
07366     };
07367 
07368 struct TEB
07369     {
07370     void* Reserved1[12];
07371     PEB*  ProcessEnvironmentBlock;
07372     void* Reserved2[399];
07373     BYTE  Reserved3[1952];
07374     void* TlsSlots[64];
07375     BYTE  Reserved4[8];
07376     void* Reserved5[26];
07377     void* ReservedForOle;
07378     void* Reserved6[4];
07379     void* TlsExpansionSlots;
07380     };
07381 
07382 struct PROCESS_BASIC_INFORMATION
07383     {
07384     NTSTATUS  ExitStatus;
07385     PEB*      PebBaseAddress;
07386     KAFFINITY AffinityMask;
07387     KPRIORITY BasePriority;
07388     ULONG_PTR UniqueProcessId;
07389     ULONG_PTR InheritedFromUniqueProcessId;
07390     };
07391 
07392 enum ADDRESS_MODE
07393     {
07394     AddrMode1616,
07395     AddrMode1632,
07396     AddrModeReal,
07397     AddrModeFlat
07398     };
07399 
07400 struct ADDRESS64
07401     {
07402     DWORD64      Offset;
07403     WORD         Segment;
07404     ADDRESS_MODE Mode;
07405     };
07406 
07407 struct KDHELP64
07408     {
07409     DWORD64 Thread;
07410     DWORD   ThCallbackStack;
07411     DWORD   ThCallbackBStore;
07412     DWORD   NextCallback;
07413     DWORD   FramePointer;
07414     DWORD64 KiCallUserMode;
07415     DWORD64 KeUserCallbackDispatcher;
07416     DWORD64 SystemRangeStart;
07417     DWORD64 KiUserExceptionDispatcher;
07418     DWORD64 StackBase;
07419     DWORD64 StackLimit;
07420     DWORD64 Reserved[5];
07421     };
07422 
07423 struct STACKFRAME64
07424     {
07425     ADDRESS64 AddrPC;
07426     ADDRESS64 AddrReturn;
07427     ADDRESS64 AddrFrame;
07428     ADDRESS64 AddrStack;
07429     ADDRESS64 AddrBStore;
07430     void*     FuncTableEntry;
07431     DWORD64   Params[4];
07432     BOOL      Far;
07433     BOOL      Virtual;
07434     DWORD64   Reserved[3];
07435     KDHELP64  KdHelp;
07436     };
07437 
07438 struct WOW64_FLOATING_SAVE_AREA
07439     {
07440     DWORD ControlWord;
07441     DWORD StatusWord;
07442     DWORD TagWord;
07443     DWORD ErrorOffset;
07444     DWORD ErrorSelector;
07445     DWORD DataOffset;
07446     DWORD DataSelector;
07447     BYTE  RegisterArea[80];
07448     DWORD Cr0NpxState;
07449     };
07450 
07451 #pragma pack (push, 4)
07452 
07453 struct WOW64_CONTEXT
07454     {
07455     DWORD ContextFlags;
07456 
07457     DWORD Dr0;
07458     DWORD Dr1;
07459     DWORD Dr2;
07460     DWORD Dr3;
07461     DWORD Dr6;
07462     DWORD Dr7;
07463 
07464     WOW64_FLOATING_SAVE_AREA FloatSave;
07465 
07466     DWORD SegGs;
07467     DWORD SegFs;
07468     DWORD SegEs;
07469     DWORD SegDs;
07470 
07471     DWORD Edi;
07472     DWORD Esi;
07473     DWORD Ebx;
07474     DWORD Edx;
07475     DWORD Ecx;
07476     DWORD Eax;
07477 
07478     DWORD Ebp;
07479     DWORD Eip;
07480     DWORD SegCs;
07481     DWORD EFlags;
07482     DWORD Esp;
07483     DWORD SegSs;
07484 
07485     BYTE  ExtendedRegisters[512];
07486     };
07487 
07488 #pragma pack (pop)
07489 
07490 struct SYMBOL_INFO
07491     {
07492     ULONG   SizeOfStruct;
07493     ULONG   TypeIndex;
07494     ULONG64 Reserved[2];
07495     ULONG   info;
07496     ULONG   Size;
07497     ULONG64 ModBase;
07498     ULONG   Flags;
07499     ULONG64 Value;
07500     ULONG64 Address;
07501     ULONG   Register;
07502     ULONG   Scope;
07503     ULONG   Tag;
07504     ULONG   NameLen;
07505     ULONG   MaxNameLen;
07506     char    Name[1];
07507     };
07508 
07509 struct IMAGEHLP_LINE64
07510     {
07511     DWORD   SizeOfStruct;
07512     void*   Key;
07513     DWORD   LineNumber;
07514     char*   FileName;
07515     DWORD64 Address;
07516     };
07517 
07518 typedef bool    (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)   (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead);
07519 typedef void*   (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress);
07520 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)       (HANDLE process, DWORD64 address);
07521 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)     (HANDLE process, HANDLE thread, ADDRESS64* address);
07522 
07523 typedef void (*unexpected_handler)();
07524 
07525 #pragma pack (push, 4)
07526 
07527 #if !defined (_TX_NO_MINIDUMP)
07528 
07529 struct MINIDUMP_THREAD_CALLBACK
07530     {
07531     ULONG    ThreadId;
07532     HANDLE   ThreadHandle;
07533     CONTEXT  Context;
07534     ULONG    SizeOfContext;
07535     ULONG64  StackBase;
07536     ULONG64  StackEnd;
07537     };
07538 
07539 struct MINIDUMP_THREAD_EX_CALLBACK
07540     {
07541     ULONG    ThreadId;
07542     HANDLE   ThreadHandle;
07543     CONTEXT  Context;
07544     ULONG    SizeOfContext;
07545     ULONG64  StackBase;
07546     ULONG64  StackEnd;
07547     ULONG64  BackingStoreBase;
07548     ULONG64  BackingStoreEnd;
07549     };
07550 
07551 struct MINIDUMP_MODULE_CALLBACK
07552     {
07553     wchar_t* FullPath;
07554     ULONG64  BaseOfImage;
07555     ULONG    SizeOfImage;
07556     ULONG    CheckSum;
07557     ULONG    TimeDateStamp;
07558     VS_FIXEDFILEINFO VersionInfo;
07559     void*    CvRecord;
07560     ULONG    SizeOfCvRecord;
07561     void*    MiscRecord;
07562     ULONG    SizeOfMiscRecord;
07563     };
07564 
07565 struct MINIDUMP_INCLUDE_THREAD_CALLBACK
07566     {
07567     ULONG    ThreadId;
07568     };
07569 
07570 struct MINIDUMP_INCLUDE_MODULE_CALLBACK
07571     {
07572     ULONG64  BaseOfImage;
07573     };
07574 
07575 struct MINIDUMP_MEMORY_INFO
07576     {
07577     ULONG64  BaseAddress;
07578     ULONG64  AllocationBase;
07579     ULONG32  AllocationProtect;
07580     ULONG32  __alignment1;
07581     ULONG64  RegionSize;
07582     ULONG32  State;
07583     ULONG32  Protect;
07584     ULONG32  Type;
07585     ULONG32  __alignment2;
07586     };
07587 
07588 struct MINIDUMP_USER_STREAM
07589     {
07590     ULONG32  Type;
07591     ULONG    BufferSize;
07592     void*    Buffer;
07593     };
07594 
07595 struct MINIDUMP_USER_STREAM_INFORMATION
07596     {
07597     ULONG                 UserStreamCount;
07598     MINIDUMP_USER_STREAM* UserStreamArray;
07599     };
07600 
07601 struct MINIDUMP_CALLBACK_INPUT
07602     {
07603     ULONG    ProcessId;
07604     HANDLE   ProcessHandle;
07605     ULONG    CallbackType;
07606 
07607     union  //-V2514
07608         {
07609         MINIDUMP_THREAD_CALLBACK         Thread;
07610         MINIDUMP_THREAD_EX_CALLBACK      ThreadEx;
07611         MINIDUMP_MODULE_CALLBACK         Module;
07612         MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
07613         MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
07614         };
07615     };
07616 
07617 struct MINIDUMP_CALLBACK_OUTPUT
07618     {
07619     union  //-V2514
07620         {
07621         ULONG ModuleWriteFlags;
07622         ULONG ThreadWriteFlags;
07623         ULONG SecondaryFlags;
07624 
07625         struct
07626             {
07627             ULONG64  MemoryBase;
07628             ULONG    MemorySize;
07629             };
07630 
07631         struct
07632             {
07633             unsigned CheckCancel;
07634             unsigned Cancel;
07635             };
07636 
07637         HANDLE Handle;  //-V117
07638         };
07639 
07640     struct
07641         {
07642         MINIDUMP_MEMORY_INFO VmRegion;
07643         unsigned             Continue;
07644         };
07645 
07646     HRESULT Status;
07647     };
07648 
07649 struct MINIDUMP_EXCEPTION_INFORMATION
07650     {
07651     DWORD               ThreadId;
07652     EXCEPTION_POINTERS* ExceptionPointers;
07653     unsigned            ClientPointers;
07654     };
07655 
07656 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output);
07657 
07658 struct MINIDUMP_CALLBACK_INFORMATION
07659     {
07660     MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
07661     void*                     CallbackParam;
07662     };
07663 
07664 #endif // _TX_NO_MINIDUMP
07665 
07666 enum MINIDUMP_TYPE
07667     {
07668     MiniDumpNormal                         = 0x00000000,
07669     MiniDumpWithDataSegs                   = 0x00000001,
07670     MiniDumpWithFullMemory                 = 0x00000002,
07671     MiniDumpWithHandleData                 = 0x00000004,
07672     MiniDumpFilterMemory                   = 0x00000008,
07673     MiniDumpScanMemory                     = 0x00000010,
07674     MiniDumpWithUnloadedModules            = 0x00000020,
07675     MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
07676     MiniDumpFilterModulePaths              = 0x00000080,
07677     MiniDumpWithProcessThreadData          = 0x00000100,
07678     MiniDumpWithPrivateReadWriteMemory     = 0x00000200,
07679     MiniDumpWithoutOptionalData            = 0x00000400,
07680     MiniDumpWithFullMemoryInfo             = 0x00000800,
07681     MiniDumpWithThreadInfo                 = 0x00001000,
07682     MiniDumpWithCodeSegs                   = 0x00002000,
07683     MiniDumpWithoutAuxiliaryState          = 0x00004000,
07684     MiniDumpWithFullAuxiliaryState         = 0x00008000,
07685     MiniDumpWithPrivateWriteCopyMemory     = 0x00010000,
07686     MiniDumpIgnoreInaccessibleMemory       = 0x00020000,
07687     MiniDumpWithTokenInformation           = 0x00040000
07688     };
07689 
07690 #ifndef CONTEXT_ALL
07691 #define CONTEXT_ALL              ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS )
07692 #endif
07693 
07694 #pragma pack (pop)
07695 
07696 } // namespace Win32
07697 
07698 #endif // TX_COMPILED
07699 
07700 #define FOREGROUND_BLACK         ( 0                                                         )
07701 #define FOREGROUND_CYAN          ( FOREGROUND_BLUE       | FOREGROUND_GREEN                  )
07702 #define FOREGROUND_MAGENTA       ( FOREGROUND_BLUE       | FOREGROUND_RED                    )
07703 #define FOREGROUND_DARKYELLOW    ( FOREGROUND_GREEN      | FOREGROUND_RED                    )
07704 #define FOREGROUND_LIGHTGRAY     ( FOREGROUND_BLUE       | FOREGROUND_GREEN | FOREGROUND_RED )
07705 #define FOREGROUND_DARKGRAY      (                         FOREGROUND_INTENSITY              )
07706 #define FOREGROUND_LIGHTBLUE     ( FOREGROUND_BLUE       | FOREGROUND_INTENSITY              )
07707 #define FOREGROUND_LIGHTGREEN    ( FOREGROUND_GREEN      | FOREGROUND_INTENSITY              )
07708 #define FOREGROUND_LIGHTCYAN     ( FOREGROUND_CYAN       | FOREGROUND_INTENSITY              )
07709 #define FOREGROUND_LIGHTRED      ( FOREGROUND_RED        | FOREGROUND_INTENSITY              )
07710 #define FOREGROUND_LIGHTMAGENTA  ( FOREGROUND_MAGENTA    | FOREGROUND_INTENSITY              )
07711 #define FOREGROUND_YELLOW        ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY              )
07712 #define FOREGROUND_WHITE         ( FOREGROUND_LIGHTGRAY  | FOREGROUND_INTENSITY              )
07713 
07714 #define BACKGROUND_BLACK         ( 0                                                         )
07715 #define BACKGROUND_CYAN          ( BACKGROUND_BLUE       | BACKGROUND_GREEN                  )
07716 #define BACKGROUND_MAGENTA       ( BACKGROUND_BLUE       | BACKGROUND_RED                    )
07717 #define BACKGROUND_DARKYELLOW    ( BACKGROUND_GREEN      | BACKGROUND_RED                    )
07718 #define BACKGROUND_GRAY          ( BACKGROUND_BLUE       | BACKGROUND_GREEN | BACKGROUND_RED )
07719 #define BACKGROUND_DARKGRAY      (                         BACKGROUND_INTENSITY              )
07720 #define BACKGROUND_LIGHTBLUE     ( BACKGROUND_BLUE       | BACKGROUND_INTENSITY              )
07721 #define BACKGROUND_LIGHTGREEN    ( BACKGROUND_GREEN      | BACKGROUND_INTENSITY              )
07722 #define BACKGROUND_LIGHTCYAN     ( BACKGROUND_CYAN       | BACKGROUND_INTENSITY              )
07723 #define BACKGROUND_LIGHTRED      ( BACKGROUND_RED        | BACKGROUND_INTENSITY              )
07724 #define BACKGROUND_LIGHTMAGENTA  ( BACKGROUND_MAGENTA    | BACKGROUND_INTENSITY              )
07725 #define BACKGROUND_LIGHTYELLOW   ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY              )
07726 #define BACKGROUND_WHITE         ( BACKGROUND_DARKGRAY   | BACKGROUND_INTENSITY              )
07727 
07728 //}
07729 //-----------------------------------------------------------------------------------------------------------------
07730 
07731 //-----------------------------------------------------------------------------------------------------------------
07732 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode.
07733 //  So we have to override them. See: http://stackoverflow.com/questions/39113168
07734 //-----------------------------------------------------------------------------------------------------------------
07735 
07736 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07737 
07738 #if defined (_MSC_VER)
07739                                                     //  MS ABI C++ Exception Layout
07740 namespace Win32 {                                   //  ---------------------------
07741                                                     //
07742 #pragma pack (push, 4)                              //   EXCEPTION_RECORD:
07743                                                     //  +==================================================+
07744 struct ThrowInfo                                    //  |...                                               |
07745     {                                               //  |NumberParameters:        3, 4 or more             |
07746     __int32 attributes;                             //  |ExceptionInformation[0]: MS signature 0x19930520  |
07747     __int32 pmfnUnwind;                             //  |ExceptionInformation[1]: object* thrown           |
07748     __int32 pForwardCompat;                         //  |ExceptionInformation[2]: ThrowInfo* --------------+---+
07749     __int32 pCatchableTypeArray;                    //  |ExceptionInformation[3]: ImageBase (if params > 3)|   |
07750     };                                              //  +==================================================+   |
07751                                                     //                                                         |
07752 struct CatchableTypeArray                           //        ThrowInfo:                                       |
07753     {                                               //        +======================================+ <-------+
07754     __int32 nCatchableTypes;                        //        |   ...                                |
07755     __int32 arrayOfCatchableTypes[];                //  +-----+-- pCatchableTypeArray (ptr/RVA)      |
07756     };                                              //  |     +======================================+
07757                                                     //  |
07758 struct CatchableType                                //  |     CatchableTypeArray:
07759     {                                               //  +---> +======================================+
07760     __int32 properties;                             //        |   ...                                |
07761     __int32 pType;                                  //  +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) |
07762     __int32 thisDisplacement[3]; // struct _PMD     //  |     +======================================+
07763     __int32 sizeOrOffset;                           //  |
07764     __int32 copyFunction;                           //  |     CatchableType:
07765     };                                              //  +---> +====================+
07766                                                     //        | ...                |        std::type_info:
07767 #pragma pack (pop)                                  //        | pType (ptr/RVA) ---+------> +==================+
07768                                                     //        | ...                |        |type_info data    |
07769 } // namespace Win32                                //        +====================+        |...               |
07770                                                     //                                      +==================+
07771 #endif
07772 
07773 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp:
07774 
07775 #define _TX_MSC__CXX_DETECT_RETHROW( exc )                                     \
07776     (                                                                          \
07777     (exc)                                          &&                          \
07778     (exc) -> ExceptionCode    == EXCEPTION_CPP_MSC &&                          \
07779     (exc) -> NumberParameters >= 3                 &&                          \
07780                                                                                \
07781     ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||  \
07782      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||  \
07783      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \
07784                                                                                \
07785     (exc) -> ExceptionInformation[2] == 0                                      \
07786     )
07787 
07788 #endif // TX_COMPILED
07789 
07790 //}
07791 //-----------------------------------------------------------------------------------------------------------------
07792 
07793 //-----------------------------------------------------------------------------------------------------------------
07794 //{ The corresponding structures for GCC
07795 //
07796 //  From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h
07797 //  See:  http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi
07798 //-----------------------------------------------------------------------------------------------------------------
07799 
07800 #if defined (_GCC_VER)
07801 
07802 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07803 
07804                                                     // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0].
07805 namespace ABI {                                     // --------------------------------------------------------------
07806                                                     //
07807 struct __cxa_exception                              // Case A: "_Unwind_Exception* A" is undependent exception:
07808     {                                               // --------------------------------------------------------
07809     union {                                         //
07810         struct                                      //           __cxa_exception:           std::type_info:
07811             {                                       //       -*--+====================+     +==================+
07812             ::std::type_info* exceptionType;        //        ^  |exceptionType* -----+---->|type_info data    |
07813             void (*exceptionDestructor)(void*);     //        |  |...                 |     |...               |
07814             };                                      //       -1  |                    |     +==================+
07815         struct                                      //        |  |                    |
07816             {                                       // A >----|--+--------------------+
07817             __cxa_exception*  primaryException;     //     |  |  |unwindHeader        |
07818             void (*padding)();                      //    +1  |  |                    |
07819             };                                      //     |  |  |                    |
07820         };                                          //     V  |  |                    |
07821                                                     //    -*---  +====================+
07822     void (*unexpected_handler)();                   //           |object              |
07823     std::terminate_handler    terminateHandler;     //           +--------------------+
07824                                                     //
07825     __cxa_exception*          nextException;        // Case B: "_Unwind_Exception* B" is dependent exception
07826     int                       handlerCount;         // (unwindHeader.exception_class & 1 != 0):
07827     int                       handlerSwitchValue;   // -----------------------------------------------------
07828     const unsigned char*      actionRecord;         //
07829     const unsigned char*      languageSpecificData; //           __cxa_exception:               __cxa_exception:
07830     void*                     catchTemp;            //       -*--+====================+     -*--+=================+
07831     void*                     adjustedPtr;          //        ^  |primaryException* --+--    ^  |exceptionType*   |
07832                                                     //        |  |...                 |  \   |  |...              |
07833     _Unwind_Exception         unwindHeader;         //       -1  |                    |  |   |  |                 |
07834     };                                              //        |  |                    |  |   |  |                 |
07835                                                     // B >----|--+--------------------+  |  -1  +-----------------+
07836 struct __cxa_eh_globals                             //     |  |  |unwindHeader        |  |   |  |unwindHeader     |
07837     {                                               //    +1  |  |                    |  |   |  |                 |
07838     __cxa_exception* caughtExceptions;              //     |  |  |                    |  |   |  |                 |
07839     unsigned int     uncaughtExceptions;            //     V  |  |                    |  \   |  |                 |
07840     };                                              //    -*---  +====================+   -->*--+=================+
07841                                                     //           |...                 |         |object           |
07842 } // namespace ABI                                  //           .                    .         |                 |
07843                                                     //                                          +-----------------+
07844 
07845 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals();
07846 
07847 #endif // TX_COMPILED
07848 
07849 #endif
07850 
07851 //}
07852 //-----------------------------------------------------------------------------------------------------------------
07853 
07854 //-----------------------------------------------------------------------------------------------------------------
07855 //{ Hand-made IAT.
07856 //  Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :(
07857 //-----------------------------------------------------------------------------------------------------------------
07858 
07859 // Hand-made DLLIMPORT helpers
07860 
07861 #define _TX_DLLIMPORT(     lib, retval, name, params )  TX_DLLIMPORT (true,  lib ".dll", retval, name, params, WINAPI)
07862 #define _TX_DLLIMPORT_OPT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI)
07863 #define _TX_DLLIMPORT_CRT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, please)
07864 
07865 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) ();
07866 
07867 //-----------------------------------------------------------------------------------------------------------------
07868 
07869 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07870 
07871 namespace Win32 {
07872 
07873 _TX_DLLIMPORT     ("GDI32",    HDC,      CreateCompatibleDC,            (HDC dc));
07874 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateCompatibleBitmap,        (HDC dc, int width, int height));
07875 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetStockObject,                (int object));
07876 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  SelectObject,                  (HDC dc, HGDIOBJ object));
07877 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetCurrentObject,              (HDC dc, unsigned objectType));
07878 _TX_DLLIMPORT     ("GDI32",    int,      GetObjectA,                    (HGDIOBJ obj, int bufsize, void* buffer));
07879 _TX_DLLIMPORT     ("GDI32",    DWORD,    GetObjectType,                 (HGDIOBJ object));
07880 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteDC,                      (HDC dc));
07881 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteObject,                  (HGDIOBJ object));
07882 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetTextColor,                  (HDC dc, COLORREF color));
07883 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetBkColor,                    (HDC dc, COLORREF color));
07884 _TX_DLLIMPORT     ("GDI32",    int,      SetBkMode,                     (HDC dc, int bkMode));
07885 _TX_DLLIMPORT     ("GDI32",    HFONT,    CreateFontA,                   (int height, int width, int escapement, int orientation,
07886                                                                          int weight, DWORD italic, DWORD underline, DWORD strikeout,
07887                                                                          DWORD charSet, DWORD outputPrec, DWORD clipPrec,
07888                                                                          DWORD quality, DWORD pitchAndFamily, const char face[]));
07889 _TX_DLLIMPORT     ("GDI32",    int,      EnumFontFamiliesExA,           (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc,
07890                                                                          LPARAM lParam, DWORD reserved));
07891 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetPixel,                      (HDC dc, int x, int y, COLORREF color));
07892 _TX_DLLIMPORT     ("GDI32",    COLORREF, GetPixel,                      (HDC dc, int x, int y));
07893 _TX_DLLIMPORT     ("GDI32",    HPEN,     CreatePen,                     (int penStyle, int width, COLORREF color));
07894 _TX_DLLIMPORT     ("GDI32",    HBRUSH,   CreateSolidBrush,              (COLORREF color));
07895 _TX_DLLIMPORT     ("GDI32",    bool,     MoveToEx,                      (HDC dc, int x, int y, POINT* point));
07896 _TX_DLLIMPORT     ("GDI32",    bool,     LineTo,                        (HDC dc, int x, int y));
07897 _TX_DLLIMPORT     ("GDI32",    bool,     Polygon,                       (HDC dc, const POINT points[], int count));
07898 _TX_DLLIMPORT     ("GDI32",    bool,     Polyline,                      (HDC dc, const POINT points[], int count));
07899 _TX_DLLIMPORT     ("GDI32",    bool,     PolyBezier,                    (HDC dc, const POINT points[], int count));
07900 _TX_DLLIMPORT     ("GDI32",    bool,     Rectangle,                     (HDC dc, int x0, int y0, int x1, int y1));
07901 _TX_DLLIMPORT     ("GDI32",    bool,     RoundRect,                     (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY));
07902 _TX_DLLIMPORT     ("GDI32",    bool,     Ellipse,                       (HDC dc, int x0, int y0, int x1, int y1));
07903 _TX_DLLIMPORT     ("GDI32",    bool,     Arc,                           (HDC dc, int x0, int y0, int x1, int y1,
07904                                                                          int xStart, int yStart, int xEnd, int yEnd));
07905 _TX_DLLIMPORT     ("GDI32",    bool,     Pie,                           (HDC dc, int x0, int y0, int x1, int y1,
07906                                                                          int xStart, int yStart, int xEnd, int yEnd));
07907 _TX_DLLIMPORT     ("GDI32",    bool,     Chord,                         (HDC dc, int x0, int y0, int x1, int y1,
07908                                                                          int xStart, int yStart, int xEnd, int yEnd));
07909 _TX_DLLIMPORT     ("GDI32",    bool,     TextOutA,                      (HDC dc, int x, int y, const char string[], int length));
07910 _TX_DLLIMPORT     ("GDI32",    UINT,     SetTextAlign,                  (HDC dc, unsigned mode));
07911 _TX_DLLIMPORT     ("GDI32",    bool,     GetTextExtentPoint32A,         (HDC dc, const char string[], int length, SIZE* size));
07912 _TX_DLLIMPORT     ("GDI32",    bool,     ExtFloodFill,                  (HDC dc, int x, int y, COLORREF color, unsigned type));
07913 _TX_DLLIMPORT     ("GDI32",    bool,     BitBlt,                        (HDC dest, int xDest, int yDest, int width, int height,
07914                                                                          HDC src,  int xSrc,  int ySrc,  DWORD rOp));
07915 _TX_DLLIMPORT     ("GDI32",    bool,     StretchBlt,                    (HDC dest, int xDest, int yDest, int width, int height,
07916                                                                          HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp));
07917 _TX_DLLIMPORT     ("GDI32",    bool,     PlgBlt,                        (HDC dest, const POINT* parallelogram,
07918                                                                          HDC src, int xSrc, int ySrc, int width, int height,
07919                                                                          HBITMAP mask, int xMask, int yMask));
07920 _TX_DLLIMPORT     ("GDI32",    int,      SetDIBitsToDevice,             (HDC dc, int xDest, int yDest, DWORD width, DWORD height,
07921                                                                          int xSrc, int ySrc, unsigned startLine, unsigned numLines,
07922                                                                          const void* data, const BITMAPINFO* info, unsigned colorUse));
07923 _TX_DLLIMPORT     ("GDI32",    int,      GetDIBits,                     (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines,
07924                                                                          void* lpvBits, BITMAPINFO* lpbi, unsigned usage));
07925 _TX_DLLIMPORT     ("GDI32",    bool,     PatBlt,                        (HDC dc, int x0, int y0, int width, int height, DWORD rOp));
07926 _TX_DLLIMPORT     ("GDI32",    int,      SetROP2,                       (HDC dc, int mode));
07927 _TX_DLLIMPORT     ("GDI32",    int,      SetStretchBltMode,             (HDC dc, int mode));
07928 _TX_DLLIMPORT     ("GDI32",    DWORD,    GdiSetBatchLimit,              (DWORD limit));
07929 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateDIBSection,              (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits,
07930                                                                          HANDLE section, DWORD offset));
07931 
07932 _TX_DLLIMPORT     ("User32",   int,      DrawTextA,                     (HDC dc, const char text[], int length, RECT* rect, unsigned format));
07933 _TX_DLLIMPORT     ("User32",   HANDLE,   LoadImageA,                    (HINSTANCE inst, const char name[], unsigned type,
07934                                                                         int sizex, int sizey, unsigned mode));
07935 _TX_DLLIMPORT_OPT ("User32",   bool,     IsHungAppWindow,               (HWND wnd));
07936 _TX_DLLIMPORT_OPT ("User32",   HWND,     GhostWindowFromHungWindow,     (HWND wnd));
07937 _TX_DLLIMPORT_OPT ("User32",   bool,     FlashWindowEx,                 (const FLASHWINFO* flash));
07938 
07939 _TX_DLLIMPORT     ("WinMM",    bool,     PlaySound,                     (const char sound[], HMODULE mod, DWORD mode));
07940 
07941 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     TransparentBlt,                (HDC dest, int destX, int destY, int destWidth, int destHeight,
07942                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
07943                                                                          unsigned transparentColor));
07944 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     AlphaBlend,                    (HDC dest, int destX, int destY, int destWidth, int destHeight,
07945                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
07946                                                                          BLENDFUNCTION blending));
07947 
07948 _TX_DLLIMPORT     ("Kernel32", void,     ExitProcess,                   (unsigned retcode));
07949 _TX_DLLIMPORT     ("Kernel32", bool,     TerminateProcess,              (HANDLE process, unsigned retcode));
07950 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalExit,                     (int retcode));
07951 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalAppExitA,                 (unsigned action, const char message[]));
07952 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetThreadId,                   (HANDLE thread));
07953 _TX_DLLIMPORT     ("Kernel32", HWND,     GetConsoleWindow,              (void));
07954 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetConsoleFont,                (HANDLE con, DWORD fontIndex));
07955 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetNumberOfConsoleFonts,       (void));
07956 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFont,         (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO*   curFont));
07957 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
07958 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
07959 _TX_DLLIMPORT_OPT ("Kernel32", void,     RtlCaptureContext,             (CONTEXT* contextRecord));
07960 _TX_DLLIMPORT_OPT ("Kernel32", USHORT,   RtlCaptureStackBackTrace,      (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash));
07961 _TX_DLLIMPORT_OPT ("Kernel32", void*,    AddVectoredExceptionHandler,   (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler));
07962 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler));
07963 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetModuleHandleEx,             (DWORD flags, const char moduleName[], HMODULE* module));
07964 _TX_DLLIMPORT_OPT ("Kernel32", bool,     IsWow64Process,                (HANDLE process, int* isWow64Process));
07965 _TX_DLLIMPORT_OPT ("Kernel32", bool,     Wow64GetThreadContext,         (HANDLE thread, WOW64_CONTEXT* context));
07966 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetThreadStackGuarantee,       (unsigned long* stackSize));
07967 
07968 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoInitialize,                  (void*));
07969 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoCreateInstance,              (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value));
07970 _TX_DLLIMPORT     ("OLE32",    void,     CoUninitialize,                (void));
07971 
07972 _TX_DLLIMPORT     ("Shell32",  HINSTANCE,ShellExecuteA,                 (HWND wnd, const char operation[], const char file[],
07973                                                                          const char parameters[], const char directory[], int showCmd));
07974 
07975 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIA,                      (const char    string[], const char    search[]));
07976 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIW,                      (const wchar_t string[], const wchar_t search[]));
07977 
07978 _TX_DLLIMPORT_OPT ("NTDLL",    char*,    wine_get_version,              (void));
07979 _TX_DLLIMPORT     ("NTDLL",    NTSTATUS, NtQueryInformationProcess,     (HANDLE process, int infoClass,
07980                                                                          void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo));
07981 
07982 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     exit,                          (int retcode));
07983 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     _cexit,                        (void));
07984 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _fpreset,                      (void));
07985 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _controlfp,                    (unsigned control, unsigned mask));
07986 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthread,                  (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist));
07987 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthreadex,                (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*),
07988                                                                          void *arglist, unsigned init_flag, unsigned* thread_addr));
07989 _TX_DLLIMPORT_CRT ("MSVCRT",   char*,    __unDName,                     (char* outStr, const char* mangledName, int outStrLen,
07990                                                                          void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer),
07991                                                                          unsigned short flags));
07992 _TX_DLLIMPORT_CRT ("MSVCRT",   unexpected_handler, set_unexpected,      (unexpected_handler handler));
07993 
07994 _TX_DLLIMPORT_OPT ("OpenGL32", HDC,         wglGetCurrentDC,            (void));
07995 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned,    glGetError,                 (void));
07996 _TX_DLLIMPORT_OPT ("Glu32",    const char*, gluErrorString,             (unsigned error));
07997 
07998 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD,    CommDlgExtendedError,          (void));
07999 
08000 #if !defined (_TX_NO_MINIDUMP)
08001 
08002 _TX_DLLIMPORT_OPT ("DbgCo*",   bool,     MiniDumpWriteDump,             (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType,
08003                                                                          MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, MINIDUMP_CALLBACK_INFORMATION* callbackParam));
08004 _TX_DLLIMPORT_OPT ("DbgCore*", bool,     MiniDumpWriteDump2,            (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType,
08005                                                                          MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, MINIDUMP_CALLBACK_INFORMATION* callbackParam));
08006 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     MiniDumpWriteDump3,            (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType,
08007                                                                          MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, MINIDUMP_CALLBACK_INFORMATION* callbackParam));
08008 #endif
08009 
08010 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD,    SymSetOptions,                 (DWORD options));
08011 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
08012 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08013 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08014 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08015 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymCleanup,                    (HANDLE process));
08016 _TX_DLLIMPORT_OPT ("DbgHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08017 _TX_DLLIMPORT_OPT ("DbgHelp*", 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 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD,    SymSetOptions,                 (DWORD options));
08024 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
08025 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08026 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08027 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08028 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymCleanup,                    (HANDLE process));
08029 _TX_DLLIMPORT_OPT ("MgwHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08030 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08031                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08032                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08033                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08034                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08035 } // namespace MinGW
08036 } // namespace Win32
08037 
08038 #endif // TX_COMPILED
08039 
08040 //}
08041 //-----------------------------------------------------------------------------------------------------------------
08042 
08044 //}
08045 //=================================================================================================================
08046 
08047 //=================================================================================================================
08048 //{          Internal function prototypes, macros and constants
08049 //  @name    Прототипы внутренних функций, макросы и константы
08050 //=================================================================================================================
08052 
08053 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08054 
08055 int              _txInitialize();
08056 void             _txCleanup();
08057 
08058 HWND             _txCanvas_CreateWindow      (const SIZE* size);
08059 
08060 bool             _txCanvas_OnCREATE          (HWND wnd);
08061 bool             _txCanvas_OnDESTROY         (HWND wnd);
08062 bool             _txCanvas_OnCLOSE           (HWND);
08063 bool             _txCanvas_OnPAINT           (HWND wnd);
08064 bool             _txCanvas_OnKEY             (HWND wnd, WPARAM vk, LPARAM info, bool down);
08065 bool             _txCanvas_OnCHAR            (HWND wnd, WPARAM ch, LPARAM info);
08066 bool             _txCanvas_OnTIMER           (HWND wnd, WPARAM id);
08067 bool             _txCanvas_OnMOUSEMOVE       (HWND wnd, WPARAM buttons, LPARAM coords);
08068 bool             _txCanvas_OnMOUSELEAVE      (HWND wnd);
08069 bool             _txCanvas_OnCREATEWND       (HWND wnd, WPARAM, LPARAM lpar);
08070 bool             _txCanvas_OnDESTROYWND      (HWND wnd, WPARAM, LPARAM lpar);
08071 bool             _txCanvas_OnCmdCONSOLE      (HWND wnd, WPARAM cmd);
08072 bool             _txCanvas_OnCmdABOUT        (HWND wnd, WPARAM cmd);
08073 
08074 unsigned WINAPI  _txCanvas_ThreadProc        (void* data);
08075 LRESULT CALLBACK _txCanvas_WndProc           (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08076 
08077 HDC              _txBuffer_Create            (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL,
08078                                               RGBQUAD** pixels = NULL) tx_nodiscard;
08079 bool             _txBuffer_Delete            (HDC* dc);
08080 bool             _txBuffer_Select            (HGDIOBJ obj, HDC dc = txDC());
08081 
08082 HWND             _txConsole_Attach();
08083 bool             _txConsole_OK() tx_nodiscard;
08084 bool             _txConsole_Detach           (bool activate);
08085 bool             _txConsole_Draw             (HDC dc);
08086 bool             _txConsole_SetUnicodeFont();
08087 
08088 const char*       txRegisterClass            (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra);
08089 HWND              txCreateExtraWindow        (CREATESTRUCT createData);
08090 HICON            _txCreateTXIcon             (int size) tx_nodiscard;
08091 int              _txSetWindowText            (HWND wnd, const char* textRus, const char* textEng = NULL,
08092                                               int checkOfs = 0, const wchar_t checkLetters[2] = NULL);
08093 int              _txPauseBeforeTermination   (HWND canvas);
08094 int              _txIsParentWaitable         (DWORD* parentPID = NULL) tx_nodiscard;
08095 void             _txActivateWindow           (HWND wnd, unsigned mode);
08096 int              _txGetInput();
08097 
08098 LRESULT CALLBACK _txPlayVideo_WndProc        (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08099 const char*      _txPlayVideo_FindVLC() tx_nodiscard;
08100 
08101 bool             _txCreateShortcut           (const char shortcutName[],
08102                                               const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL,
08103                                               const char description[] = NULL, int cmdShow = SW_SHOWNORMAL,
08104                                               const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0,
08105                                               COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD));
08106 
08107 void*            _tx_DLGTEMPLATE_Create      (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
08108                                               WORD controls, short x, short y, short cx, short cy,
08109                                               const char caption[], const char font[], WORD fontsize,
08110                                               const char menu[]) tx_nodiscard;
08111 
08112 void*            _tx_DLGTEMPLATE_Add         (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
08113                                               short x, short y, short cx, short cy,
08114                                               WORD id, const char wclass[], const char caption[]);
08115 
08116 const char*      _txProcessError             (const char file[], int line, const char func[], unsigned color,
08117                                               const char msg[], va_list args);
08118 void             _txOnTerminate();
08119 void             _txOnUnexpected();
08120 void             _txOnPureCall();
08121 void             _txOnNewHandlerAnsi();
08122 int              _txOnNewHandler             (size_t size);
08123 void             _txOnSignal                 (int signal = 0, int fpe = 0);
08124 BOOL WINAPI      _txOnConsoleCtrlEvent       (DWORD type);
08125 void             _txOnSecurityError          (int code, void*);
08126 void             _txOnSecurityErrorAnsi      (const char* msg, void* ptr, int code);
08127 int              _txOnMatherr                (_exception* except);
08128 void             _txOnInvalidParam           (const wchar_t* expr, const wchar_t* func, const wchar_t* file,
08129                                               unsigned line, uintptr_t);
08130 int              _txOnAllocHook              (int type, void* data, size_t size, int use, long request,
08131                                               const unsigned char* file, int line);
08132 int              _txOnRTCFailure             (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5);
08133 int              _txOnErrorReport            (int type, const char* text, int* ret);
08134 int               tx_glGetError              (int setError = INT_MIN);
08135 
08136 void             _txOnCExit();
08137 void             _txOnExit                   (int      retcode);
08138 void             _txOnFatalExit              (int      retcode);
08139 void             _txOnExitProcess            (unsigned retcode);
08140 void             _txOnFatalAppExitA          (unsigned action, const char message[]);
08141 bool             _txOnTerminateProcess       (HANDLE process, unsigned retcode);
08142 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
08143                  _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter);
08144 void             _txWatchdogTerminator       (void* timeout);  // Only Arnold-type series are supported, not T1000
08145 
08146 long WINAPI      _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc);
08147 long WINAPI      _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc);
08148 long             _txOnExceptionSEH           (EXCEPTION_POINTERS* exc, const char func[]);
08149 intptr_t         _txDumpExceptionSEH         (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]);
08150 intptr_t         _txDumpExceptionObj         (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type);
08151 intptr_t         _txDumpExceptionCPP         (char what[], intptr_t size, unsigned code = 0,
08152                                               unsigned params = 0, const ULONG_PTR info[] = NULL);
08153 
08154 void             _txStackBackTrace           (const char file[] = "?", int line = 0, const char func[] = "?",
08155                                               bool readSource = true);
08156 const char*      _txCaptureStackBackTrace    (int framesToSkip = 0, bool readSource = true,
08157                                               CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread());
08158 int              _txStackWalk                (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL,
08159                                               HANDLE thread = GetCurrentThread());
08160 const char*      _txCaptureStackBackTraceTX  (int framesToSkip = 0, bool readSource = false);
08161 
08162 const char*      _txSymPrintFromAddr         (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2);
08163 bool             _txSymGetFromAddr           (void* addr, Win32::SYMBOL_INFO** symbol = NULL,
08164                                               Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL,
08165                                               const char** source = NULL, int context = 2);
08166 intptr_t         _txReadSource               (char buf[], intptr_t size, const char file[],
08167                                               int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN);
08168 uintptr_t        _txSetProcAddress           (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL,
08169                                               int useHotPatching = false, HMODULE module = NULL, bool debug = false);
08170 bool             _txCreateMiniDump           (EXCEPTION_POINTERS* exc = NULL);
08171 
08172 bool             _txInDll() tx_nodiscard;
08173 PROCESSENTRY32*  _txFindProcess              (unsigned pid = GetCurrentProcessId()) tx_nodiscard;
08174 bool             _txKillProcess              (DWORD pid);
08175 int              _txTaskKill                 (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/);
08176 bool             _txCheckSourceCP            (int needCP = _TX_CODEPAGE, bool verbose = true);
08177 bool             _txGetCommandLine           (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid());
08178 IMAGE_NT_HEADERS*_txGetNtHeaders             (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard;
08179 bool             _txIsConsoleSubsystem();
08180 const char*      _txAppInfo() tx_nodiscard;
08181 
08182 #if defined (_CLANG_VER) && !defined (_MSC_VER)
08183 void             _txLibCppDebugFunction      (std::__libcpp_debug_info const& info);
08184 #endif
08185 
08186 #endif // TX_COMPILED
08187 
08188 inline bool      _txCanvas_OK                () tx_nodiscard;
08189 int              _txCanvas_SetRefreshLock    (int count);
08190 
08191 const char*      _txError                    (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0,
08192                                               const char msg[] = NULL, ...) tx_printfy (5);
08193 
08194 bool             _txIsBadReadPtr             (const void* address);
08195 
08196 intptr_t         _tx_snprintf_s              (char stream[], intptr_t size, const char format[], ...) tx_printfy (3);
08197 intptr_t         _tx_vsnprintf_s             (char stream[], intptr_t size, const char format[], va_list arg);
08198 bool             _txIsTTY                    (int fd);
08199 void              txReopenStdio();
08200 
08201 #if defined (__CYGWIN__)
08202 
08203 int              _getch();
08204 int              _putch (int ch);
08205 int              _kbhit() tx_nodiscard;
08206 
08207 #endif
08208 
08209 //-----------------------------------------------------------------------------------------------------------------
08210 // There are macros for __FILE__ and __LINE__ to work properly.
08211 
08212 #if !defined (NDEBUG)
08213 
08214     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08215                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) && \
08216                                                      (assert (cond), true) )
08217 
08218     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08219                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) && \
08220                                                      (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) )
08221 
08222     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                                                            \
08223                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) &&                                     \
08224                                                      (TX_ERROR ("\a" "Параметр \"%s\" неверен."                                           \
08225                                                                                    " Возможно, этот холст не создан, или уже уничтожен, " \
08226                                                                                     "или не загрузилась картинка.", #dc), 1) )
08227     #define _TX_DEFAULT_HDC_FAILED( dc )       ( !(dc) &&                                                                                 \
08228                                                      (TX_ERROR ("\a" "%s"                                                                 \
08229                                                                      "Если вы указали параметр \"%s\", то он неверен.%s",                 \
08230                                                                      (!txWindow()? "Окно рисования не создано или не в порядке.\n" : ""), \
08231                                                                      #dc,                                                                 \
08232                                                                      ( txWindow()? " Возможно, этот холст не создан, или уже уничтожен, " \
08233                                                                                     "или не загрузилась картинка." : "")), 1) )
08234 #else
08235 
08236     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08237                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) )
08238 
08239     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08240                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08241 
08242     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                        \
08243                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08244 
08245     #define _TX_DEFAULT_HDC_FAILED( dc )       ( !(dc) &&                                             \
08246                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08247 #endif
08248 
08249 //-----------------------------------------------------------------------------------------------------------------
08250 // Take action in debug configuration only.
08251 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'(
08252 
08253 #if !defined (NDEBUG)
08254     #define  _TX_ON_DEBUG( code )              { code; }
08255 #else
08256     #define  _TX_ON_DEBUG( code )              ;
08257 #endif
08258 
08259 //-----------------------------------------------------------------------------------------------------------------
08260 // Invokes an error without location information. "$$" restores TX-related call location context
08261 
08262 #define _TX_UNEXPECTED( ... )                  $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__)
08263 
08264 //-----------------------------------------------------------------------------------------------------------------
08265 // Safe call of a function via its pointer
08266 
08267 #define _TX_CALL(  func, param )               ( (func)? ((func) param) :       0 )
08268 #define _TX_CALLv( func, param )               ( (func)? ((func) param) : (void)0 )
08269 
08270 //-----------------------------------------------------------------------------------------------------------------
08271 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x.
08272 
08273 #define _txWaitFor( cond, time )               { for (DWORD _t = GetTickCount() + (time); \
08274                                                       !(cond) && GetTickCount() < _t;     \
08275                                                       Sleep (_txWindowUpdateInterval))    \
08276                                                       ;                                   \
08277                                                                                           \
08278                                                  if  (!(cond))                            \
08279                                                       _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); }
08280 
08281 //-----------------------------------------------------------------------------------------------------------------
08282 // Detouring in case of SEH mechanism
08283 
08284 #define _txSetJmp()                            ( setjmp (_txDumpExceptionObjJmp) == 0 )
08285 
08286 #define _txClearJmp()                          { *(unsigned long long*) _txDumpExceptionObjJmp = 0; }
08287 
08288 //-----------------------------------------------------------------------------------------------------------------
08289 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code.
08290 
08291 #if defined (IN)
08292 //  #undef  IN
08293 #endif
08294 
08295 #if defined (OUT)
08296 //  #undef  OUT
08297 #endif
08298 
08300 //}
08301 //=================================================================================================================
08302 
08303 //=================================================================================================================
08304 //{          Internal global data
08306 //
08307 //           Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :)
08308 //
08309 //           Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же.
08310 //           Здесь это сделано только в образовательных целях.
08311 //
08312 //           Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс.
08313 //=================================================================================================================
08315 
08316 #ifndef TX_COMPILED                                                      // <<<<<<< THE CODE IS HERE, UNFOLD IT <<<
08317 
08318 const int                      _TX_IDM_ABOUT               = 40000,      // Идентификаторы системного меню окна
08319                                _TX_IDM_CONSOLE             = 40001,
08320                                _TX_WM_CREATEWND            = 0x7FF0,     // Сообщения для создания/уничтожения
08321                                _TX_WM_DESTROYWND           = 0x7FF1;     // окон в потоке Canvas
08322 
08323 //-----------------------------------------------------------------------------------------------------------------
08324 
08325 volatile unsigned              _txCanaryFirst              = 0x776F656D; // A very system value
08326 
08327 int                            _txInitialized              = (_TX_NOINIT +0)? 0 : _txInitialize();
08328 
08329 volatile unsigned              _txMainThreadId             = 0;          // ID потока, где выполняется main()
08330 volatile HANDLE                _txMainThread               = NULL;       // Дексриптор этого потока
08331 
08332 volatile unsigned              _txCanvas_ThreadId          = 0;          // ID потока, владеющего окном холста TXLib
08333 volatile HANDLE                _txCanvas_Thread            = NULL;       // Дексриптор этого потока
08334 volatile HWND                  _txCanvas_Window            = NULL;       // Дескриптор окна холста TXLib
08335 
08336 HDC                            _txCanvas_BackBuf[2]        = {NULL,      // [0] Main TXLib in-memory DC, where user's pictures lies
08337                                                               NULL};     // [1] Image ready for auto-refresh, see txCanvas_OnPAINT()
08338 
08339 RGBQUAD*                       _txCanvas_Pixels            = NULL;       // Memory buffer of _txCanvas_BackBuf[0]
08340 
08341 HBITMAP                        _txStockBitmap              = NULL;       // Equivalent of GetStockObject (BITMAP),
08342                                                                          // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313
08343 
08344 CRITICAL_SECTION               _txCanvas_LockBackBuf       = {0,-1};     // Prevent simultaneous access to back buffer, see txLock()
08345 
08346 UINT_PTR                       _txCanvas_RefreshTimer      = 1;          // Timer ID to redraw TXLib window
08347 volatile int                   _txCanvas_RefreshLock       = 0;          // Blocks auto on-timer canvas update, see txBegin/txEnd
08348 
08349 ::std::vector<HDC>*            _txCanvas_UserDCs           = NULL;       // List of DCs allocated, for auto-free
08350 
08351 volatile bool                  _txConsole_IsBlinking       = true;       // To blink or not to blink, that is the question.
08352 
08353 int                            _txConsole                  = false;      // Only first TXLib module in app can own the console
08354 bool                           _txMain                     = false;      // First TXLib wnd opened (closing it terminates program)
08355 bool                           _txIsDll                    = false;      // TXLib module is in DLL
08356 volatile bool                  _txRunning                  = false;      // main() is still running
08357 volatile bool                  _txExit                     = false;      // exit() is active
08358 
08359 volatile POINT                 _txMousePos                 = {-1,-1};    // Ask Captn Obviouos about it. See txCanvas_OnMOUSE()
08360 volatile unsigned              _txMouseButtons             = 0;
08361 
08362 volatile WNDPROC               _txAltWndProc               = NULL;       // Альтернативная оконная функция. См. txSetWindowsHook().
08363 
08364 _tx_thread _txLoc              _txLoc::Cur                 = {};         // Execution point tracking and trace state, see "$" macro
08365 
08366 volatile int                   _txErrors                   = 0;          // TX_ERROR calls sequental number
08367 volatile int                   _txOGLError                 = 0;          // Last OpenGL error when using tx_glGetError()
08368 volatile long                  _txSENumber                 = 0;          // SEH exceptions sequental number
08369 volatile long                  _txSEFatalNumber            = 0;          // SEH fatal exceptions sequental number
08370 char                           _txDumpSE [_TX_BUFSIZE]     = "";         // SEH dump data area
08371 char                           _txTraceSE[_TX_HUGEBUFSIZE] = "";         // Stack trace data area
08372 
08373 LPTOP_LEVEL_EXCEPTION_FILTER   _txPrevUEFilter             = NULL;       // Previous UnhandledExceptionFilter
08374 
08375 jmp_buf                        _txDumpExceptionObjJmp      = {};         // Hook for _txDumpExceptionObj
08376 
08377 const volatile uintptr_t       _txForceImport[]            = { (uintptr_t) ::TerminateProcess,              (uintptr_t) ::ExitProcess,
08378                                                                (uintptr_t) ::FatalExit,                     (uintptr_t) ::FatalAppExitA,
08379                                                                (uintptr_t) ::exit,                          (uintptr_t) Win32::_controlfp,
08380                                                                (uintptr_t) Win32::Polyline,                 (uintptr_t) Win32::PolyBezier,
08381                                                                (uintptr_t) Win32::RoundRect,                (uintptr_t) Win32::RemoveVectoredExceptionHandler,
08382                                                                (uintptr_t) Win32::PlgBlt,                   (uintptr_t) Win32::RtlCaptureStackBackTrace,
08383                                                                (uintptr_t) Win32::SymInitialize,            (uintptr_t) Win32::MinGW::SymInitialize,
08384                                                                (uintptr_t) Win32::SymSetOptions,            (uintptr_t) Win32::MinGW::SymSetOptions,
08385                                                                (uintptr_t) Win32::SymGetLineFromAddr64,     (uintptr_t) Win32::MinGW::SymGetLineFromAddr64,
08386                                                                (uintptr_t) Win32::SymFromAddr,              (uintptr_t) Win32::MinGW::SymFromAddr,
08387                                                                (uintptr_t) Win32::SymCleanup,               (uintptr_t) Win32::MinGW::SymCleanup,
08388                                                                (uintptr_t) Win32::SymGetModuleBase64,       (uintptr_t) Win32::MinGW::SymGetModuleBase64,
08389                                                                (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64,
08390                                                                (uintptr_t) Win32::StackWalk64,              (uintptr_t) Win32::MinGW::StackWalk64,
08391                                                                (uintptr_t) Win32::StrStrIA,                 (uintptr_t) Win32::Wow64GetThreadContext };
08392 
08393 volatile unsigned              _txCanaryLast               = 0x5E2E2E5E; // Another very system value
08394 
08395 #endif // TX_COMPILED
08396 
08397 //-----------------------------------------------------------------------------------------------------------------
08398 
08399 extern volatile unsigned _txCanaryFirst;
08400 extern volatile unsigned _txCanaryLast;
08401 extern volatile HWND     _txCanvas_Window;
08402 extern volatile unsigned _txCanvas_ThreadId;
08403 extern          HDC      _txCanvas_BackBuf[2];
08404 extern          RGBQUAD* _txCanvas_Pixels;
08405 extern volatile int      _txCanvas_RefreshLock;
08406 extern volatile WNDPROC  _txAltWndProc;
08407 extern volatile bool     _txExit;
08408 extern volatile int      _txOGLError;
08409 
08411 //}
08412 //=================================================================================================================
08413 
08414 //=================================================================================================================
08415 //{          TXLib engine init/check/cleanup
08417 //=================================================================================================================
08419 
08420 //-----------------------------------------------------------------------------------------------------------------
08421 //{          Early initialization
08422 //-----------------------------------------------------------------------------------------------------------------
08423 
08424 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08425 
08426 int _txInitialize()
08427     {
08428     if (_txInitialized) return 1;
08429     _txInitialized = 1;
08430 
08431     #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER)  // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx
08432     _CrtSetBreakAlloc (_TX_ALLOC_BREAK);                 // and http://support.microsoft.com/ru-ru/kb/151585
08433     #endif
08434 
08435     #if defined (_TX_ALLOW_TRACE)
08436     _txLocLvlSet (1);
08437     #endif
08438 
08439     _TX_ON_DEBUG (OutputDebugString ("\n");
08440                   OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" "
08441                                      "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n");
08442                   OutputDebugString ("\n"));
08443 
08444     _txMainThreadId = GetCurrentThreadId();
08445     _txMainThread   = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId);
08446 
08447 $3  _txIsDll = _txInDll();
08448 
08449 $   if (!_txIsDll)
08450         {
08451 $       _txConsole = ! FindAtom ("_txConsole");
08452 $       (void)          AddAtom ("_txConsole");  //-V530
08453         }
08454 
08455 $   if (_txConsole)
08456         {
08457 $       _txCheckSourceCP (_TX_CODEPAGE, true);
08458 
08459 $       unsigned long stackSize = _TX_STACKSIZE;
08460 $       _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
08461 
08462 $       _txOnSignal();
08463 
08464 $       if (!*_txLogName)
08465             {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); }
08466 
08467 $       if (!_txIsDll)
08468             {
08469 $           _TX_CALL  (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER)  _txVectoredExceptionHandler));
08470 $           _txPrevUEFilter = SetUnhandledExceptionFilter  (   (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter);
08471             }
08472 
08473 $       ::std::set_terminate             (_txOnTerminate);
08474 $       ::std::set_new_handler           (_txOnNewHandlerAnsi);
08475 $       _TX_CALL (Win32::set_unexpected, (_txOnUnexpected));
08476 
08477         #if defined (_CLANG_VER) && !defined (_MSC_VER)
08478 $       ::std::__libcpp_debug_function = _txLibCppDebugFunction;
08479         #endif
08480 
08481 $       SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true);
08482 
08483 $       SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
08484 
08485         #if defined (_MSC_VER)
08486 
08487 $       _set_printf_count_output (1);
08488 
08489 $       _set_new_handler (_txOnNewHandler);
08490 $       _set_new_mode (1);
08491 
08492         #if !defined (_CLANG_VER)
08493 
08494 $       _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
08495 $       _CrtSetAllocHook (_txOnAllocHook);
08496 
08497 $       unsigned mode = _CRTDBG_MODE_FILE;
08498 $       if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0;
08499 
08500 $       _CrtSetReportMode (_CRT_WARN,   _CRTDBG_MODE_DEBUG | mode);
08501 $       _CrtSetReportMode (_CRT_ERROR,  _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08502 $       _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08503 $       _CrtSetReportFile (_CRT_WARN,   _CRTDBG_FILE_STDERR);
08504 $       _CrtSetReportFile (_CRT_ERROR,  _CRTDBG_FILE_STDERR);
08505 $       _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
08506 
08507         #endif
08508 
08509 $       _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG);
08510 $       _set_abort_behavior (0,                _CALL_REPORTFAULT);
08511 
08512 $       _RTC_SetErrorFunc              (_txOnRTCFailure);
08513 $       _set_purecall_handler          (_txOnPureCall);
08514 $       _set_invalid_parameter_handler (_txOnInvalidParam);
08515 
08516         #endif
08517 
08518         #if defined (__STDC_LIB_EXT1__)
08519 $       ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi);
08520         #endif
08521 
08522         #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386)
08523 $       __setusermatherr (_txOnMatherr);
08524         #endif
08525 
08526         #if !defined (__CYGWIN__)
08527 $       _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR);
08528         #endif
08529 
08530 $       HWND console = _txConsole_Attach();
08531 $       SetWindowTextA (console, txGetModuleFileName (false));
08532         }
08533 
08534 $   _txSetProcAddress ("ExitProcess",                 (uintptr_t) _txOnExitProcess,                 "KERNEL32.DLL");
08535 $   _txSetProcAddress ("TerminateProcess",            (uintptr_t) _txOnTerminateProcess,            "KERNEL32.DLL");
08536 $   _txSetProcAddress ("FatalExit",                   (uintptr_t) _txOnFatalExit,                   "KERNEL32.DLL");
08537 $   _txSetProcAddress ("FatalAppExitA",               (uintptr_t) _txOnFatalAppExitA,               "KERNEL32.DLL");
08538 $   _txSetProcAddress ("UnhandledExceptionFilter",    (uintptr_t) _txUnhandledExceptionFilter,      "KERNEL32.DLL", true);  //-V601
08539 $   _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL");
08540 $   _txSetProcAddress ("exit",                        (uintptr_t) _txOnExit);
08541 $   _txSetProcAddress ("_cexit",                      (uintptr_t) _txOnCExit);
08542 
08543 $   InitializeCriticalSection (&_txCanvas_LockBackBuf);
08544 
08545 $   HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted;
08546 $   _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted;
08547 $   Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted;
08548 $   Win32::DeleteDC (dc) asserted;
08549 
08550 $   atexit (_txCleanup);
08551 
08552 $   if (_txConsole)
08553         {
08554 $       txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
08555 
08556 $       tx_fpreset();
08557 
08558 $       srand ((unsigned) time (NULL));  //-V202
08559 
08560 $       SetLastError (0);
08561 $       errno = 0;
08562 
08563         #if !defined (__CYGWIN__)
08564 $       _doserrno = 0;
08565         #endif
08566         }
08567 
08568 $   Win32::CoCreateInstance = Win32::CoCreateInstance;  // g++ 5.1.0 bug, false warning "defined but not used"
08569 
08570 $   return 1;
08571     }
08572 
08573 //-----------------------------------------------------------------------------------------------------------------
08574 
08575 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/)
08576     {
08577 $3  const char* sCodePage = NULL;
08578 $   int codePage = 0;
08579 
08580 $   switch (((unsigned const char*) "А") [0])
08581         {
08582         case 192: {$ codePage =  1251; sCodePage = "1251.";          break; }
08583         case 208: {$ codePage = 65001; sCodePage = "UTF-8.";         break; }
08584         case 128: {$ codePage =   866; sCodePage = "866.";           break; }
08585         case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; }
08586         default:  {$ codePage =    -1; sCodePage = "(Unknown)";      break; }
08587         }
08588 
08589 $   if (codePage != needCP && verbose)
08590         {
08591 $       *_txTraceSE = ' ';  // No stack trace please
08592 
08593 $       _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n"
08594                         "This is NOT an error of TXLib itself. Please note:\n\n"
08595                         "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your "
08596                         "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO "
08597                         "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. "
08598                         "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n"
08599                         "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n"
08600                         "You can continue, but Russian messages and symbols may appear unreadable.",
08601                         sCodePage, needCP, needCP);
08602         }
08603 
08604 $   return (codePage == needCP);
08605     }
08606 
08607 //-----------------------------------------------------------------------------------------------------------------
08608 
08609 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) ()
08610     {
08611     if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL;
08612     if (_TX_ARGUMENT_FAILED (funcName    && *funcName))    return NULL;
08613 
08614     static char dllPaths [2][MAX_PATH] = {"", ""};
08615 
08616     if (!*dllPaths[0])
08617         {
08618         const char dllDir[]  = "\\Windows\\";
08619 
08620         // dllPaths[0] is relative to the TX Setup directory stored in the Registry
08621 
08622         char* path = dllPaths[0];
08623 
08624         txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH);
08625         strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08626 
08627         // dllPaths[1] is relative to TXib.h file used in compilation
08628 
08629         path = dllPaths[1];
08630 
08631         if (strchr (__FILE__, ':'))
08632             {
08633             strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1);
08634             }
08635         else
08636             {
08637             GetCurrentDirectory (MAX_PATH, path);
08638             strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1);
08639             }
08640 
08641         if (char* dir = strrchr (path, '\\')) *dir = 0;
08642 
08643         strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08644         }
08645 
08646     char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = "";
08647     const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL);  //-V547
08648 
08649     if (arch)
08650         {
08651         assert (arch >= dllFileName);  //-V547
08652 
08653         strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName));
08654         strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName));
08655 
08656         strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName));
08657         strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3);
08658         strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch));
08659         }
08660     else if (dllFileName)  //-V547 //-V2516
08661         {
08662         strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1);
08663         }
08664 
08665     HMODULE   dll = GetModuleHandle (dllFileName);
08666 
08667     if (!dll) dll = GetModuleHandle (dllArch);
08668     if (!dll) dll = GetModuleHandle (dllName);
08669 
08670     for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++)
08671         {
08672         char path [MAX_PATH] = "";
08673         strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i]));
08674         size_t len = strlen (path);
08675 
08676         strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch));
08677         if (!dll) dll = LoadLibrary (path);  //-V547
08678 
08679         strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName));
08680         if (!dll) dll = LoadLibrary (path);
08681         }
08682 
08683     if (!dll)     dll = LoadLibrary (dllArch);
08684     if (!dll)     dll = LoadLibrary (dllName);
08685 
08686     if (!dll  && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".",               dllName, (arch? "\" / \"" : ""), dllArch);
08687     if (!dll) return NULL;
08688 
08689     void (*addr)() = (void(*)()) GetProcAddress (dll, funcName);
08690 
08691     if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".", funcName, dllName, (arch? "\" / \"" : ""), dllArch);
08692     return addr;
08693     }
08694 
08695 //-----------------------------------------------------------------------------------------------------------------
08696 
08697 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013
08698     #pragma warning (push)
08699     #pragma warning (disable: 6102)          // Использование 'name' из завершившегося ошибкой вызова функции
08700 #endif
08701 
08702 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue)
08703     {
08704     if (_TX_ARGUMENT_FAILED (keyName)) return 0;
08705 
08706     HKEY hive = NULL;
08707 
08708     #define EQU_(name1, name2)  ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \
08709                                   _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 )
08710 
08711     if      (EQU_("HKLM", "HKEY_LOCAL_MACHINE"))  hive = HKEY_LOCAL_MACHINE;
08712     else if (EQU_("HKCU", "HKEY_CURRENT_USER"))   hive = HKEY_CURRENT_USER;
08713     else if (EQU_("HKCR", "HKEY_CLASSES_ROOT"))   hive = HKEY_CLASSES_ROOT;
08714     else if (EQU_("HKU",  "HKEY_USERS"))          hive = HKEY_USERS;
08715     else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG;
08716 
08717     else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; }
08718 
08719     #undef EQU_
08720 
08721     keyName = strchr (keyName, '\\') + 1;  //-V769
08722     assert (keyName > (const char*) 1);
08723 
08724     HKEY  key  = NULL;
08725     DWORD size = 0;
08726 
08727     bool                               ok  = (RegOpenKeyEx    (hive, keyName,   0, KEY_QUERY_VALUE, &key)         == ERROR_SUCCESS);
08728     if (ok)                            ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, NULL,          &size) == ERROR_SUCCESS);
08729     if (ok && value && size < szValue) ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS);  //-V104
08730     if (key)                           ok &= (RegCloseKey     (key)                                               == ERROR_SUCCESS);
08731 
08732     return size;
08733     }
08734 
08735 #if defined (_MSC_VER) && (_MSC_VER == 1800)
08736     #pragma warning (pop)
08737 #endif
08738 
08739 #endif // TX_COMPILED
08740 
08741 //}
08742 //-----------------------------------------------------------------------------------------------------------------
08743 
08744 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08745 
08746 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/)
08747     {
08748 $1  if (!_txInitialized) _txInitialized = _txInitialize();
08749 
08750 $   if (HWND wnd = txWindow())
08751         {
08752 $       SetLastErrorEx (ERROR_INVALID_DATA, 0);
08753 $       _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!"));
08754 $       return wnd;
08755         }
08756 
08757 $   if (!_txIsDll)
08758         {
08759 $       _txMain = ! FindAtom ("_txMain");  // Not a thread-safe
08760 $       (void)       AddAtom ("_txMain");  //-V530
08761         }
08762 
08763 $   if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; }  //-V1048
08764 
08765 $   _txRunning = false;
08766 
08767     // Store the size
08768 
08769 $   static SIZE size = { ROUND (sizeX), ROUND (sizeY) };
08770 $   if (centered) { size.cx *= -1; size.cy *= -1; }
08771 
08772     // In Thread, where REAL creation lies...
08773 
08774 $   unsigned id = 0;
08775 $   _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id);
08776 
08777 $   if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."),  (HWND) NULL;
08778 
08779 $   _txWaitFor (_txRunning, 10*_TX_TIMEOUT);
08780 
08781 $   if (!_txRunning)       return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL;
08782 $   if (!txOK())           return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."),     (HWND) NULL;
08783 
08784 $   HWND console = Win32::GetConsoleWindow();
08785 
08786 $   DWORD proc = 0;
08787 $   GetWindowThreadProcessId (console, &proc);
08788 
08789 $   if (console && (proc == GetCurrentProcessId() || _txIsParentWaitable()))
08790         {$ ShowWindow (console, TX_CONSOLE_MODE); }
08791 
08792 $   HMENU menu = GetSystemMenu (txWindow(), false);
08793     if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); }
08794 
08795 $   Win32::GdiSetBatchLimit (1);
08796 
08797 $   SetLastError (0);
08798 
08799 $   errno = 0;
08800 
08801     #if !defined (__CYGWIN__)
08802 $   _doserrno = 0;
08803     #endif
08804 
08805 $   return txWindow();
08806     }
08807 
08808 //-----------------------------------------------------------------------------------------------------------------
08809 
08810 HWND txCreateExtraWindow (CREATESTRUCT createData)
08811     {
08812 $1  if (_TX_TXWINDOW_FAILED()) return NULL;
08813 
08814 $   volatile HWND wnd = NULL;
08815 $   createData.hInstance = (HINSTANCE)(uintptr_t) &wnd;
08816 
08817 $   PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted;
08818 
08819 $   _txWaitFor (wnd, 5*_TX_TIMEOUT);
08820 
08821 $   return wnd;
08822     }
08823 
08824 //-----------------------------------------------------------------------------------------------------------------
08825 
08826 bool txSetDefaults (HDC dc /*= txDC()*/)
08827     {
08828 $1  if (dc == txDC()) txUpdateWindow (false);  //-V601
08829 $   txAutoLock _lock;
08830 
08831 $   RECT r = {};
08832 $   GetClientRect (Win32::GetConsoleWindow(), &r);
08833 $   SIZE szCon = { r.right - r.left, r.bottom - r.top };
08834 
08835 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
08836 
08837 $   CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}};
08838 $   GetConsoleScreenBufferInfo (out, &con);
08839 
08840 $   SIZE szTxt = { (short) (con.srWindow.Right  - con.srWindow.Left + 1),
08841                    (short) (con.srWindow.Bottom - con.srWindow.Top  + 1) };
08842 
08843 //{ Set defaults for graphics layer
08844 
08845 $   _txBuffer_Select (Win32::GetStockObject (WHITE_PEN),   dc) asserted;
08846 $   _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted;
08847 
08848 $   _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx,
08849                                          0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
08850                                          RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
08851                                          DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT),
08852                       dc) asserted;
08853 
08854 $  (Win32::SetTextColor      (dc, TX_WHITE) != CLR_INVALID) asserted;
08855 $   Win32::SetBkMode         (dc, TRANSPARENT)              asserted;
08856 
08857 $   Win32::SetROP2           (dc, R2_COPYPEN)               asserted;
08858 $   Win32::SetStretchBltMode (dc, HALFTONE)                 asserted;
08859 
08860 //}
08861 
08862 $   if (dc != txDC())
08863         {$ return true; }
08864 
08865 //{ Set defaults for console  layer
08866 
08867 $   POINT szCanvas = txGetExtent (dc);
08868 
08869 $   HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)?
08870                        Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx,
08871                                           0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
08872                                           RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
08873                                           DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT)
08874                        :
08875                        Win32::GetStockObject (SYSTEM_FIXED_FONT);
08876 
08877 $   _txBuffer_Select (font, _txCanvas_BackBuf[1]);
08878 //}
08879 
08880 //{ Scroll the console for text to go above top of window and don't mix with graphics
08881 
08882 $   if (con.dwCursorPosition.X) _putch ('\n');
08883 
08884 $   short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top);
08885 
08886 $   con.srWindow.Top    = (short) (con.srWindow.Top    + delta);
08887 $   con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta);
08888 
08889 $   SMALL_RECT src  = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) };
08890 $   CHAR_INFO  fill = { {' '}, FOREGROUND_LIGHTGRAY };
08891 $   COORD      dest = { 0, (short) -delta };  // New UL-corner of src, scroll up
08892 
08893 $   con.dwCursorPosition.X = 0;
08894 $   con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta);
08895 
08896 $   (con.srWindow.Bottom < con.dwSize.Y &&                        // Move the "window"
08897      SetConsoleWindowInfo      (out, true, &con.srWindow))
08898     ||
08899     (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill),    // Or scroll the buffer
08900      SetConsoleCursorPosition  (out, con.dwCursorPosition));
08901 //}
08902 
08903 $   txUpdateWindow (true);  //-V601
08904 
08905     return true;
08906     }
08907 
08908 #endif // TX_COMPILED
08909 
08910 //-----------------------------------------------------------------------------------------------------------------
08911 
08912 inline bool txOK()
08913     {
08914     return (_txCanaryFirst == 0x776F656D &&  // Too well-known values to use constants. You know these values, don't you?
08915             _txCanaryLast  == 0x5E2E2E5E &&
08916             _txCanvas_OK()
08917 
08918     #if defined (_MSC_VER)
08919          && _CrtCheckMemory()
08920     #endif
08921             );
08922     }
08923 
08924 //-----------------------------------------------------------------------------------------------------------------
08925 //{          Cleanup
08926 //-----------------------------------------------------------------------------------------------------------------
08927 
08928 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08929 
08930 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain.
08931 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols
08932 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize().
08933 
08934 void _txOnCExit()
08935     {
08936     OutputDebugString ("\n");
08937 
08938 $5  _txCleanup();
08939 
08940     _TX_CALLv (Win32::_cexit, ());
08941     }
08942 
08943 //-----------------------------------------------------------------------------------------------------------------
08944 
08945 void _txOnExit (int retcode)
08946     {
08947     if (retcode != 0)
08948         {
08949         OutputDebugString ("\n");
08950         txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode);
08951         }
08952 
08953 $5  _txCleanup();
08954 
08955     if (retcode != 0)
08956         txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode);
08957 
08958     Win32::exit (retcode);
08959     }
08960 
08961 //-----------------------------------------------------------------------------------------------------------------
08962 
08963 void _txOnExitProcess (unsigned retcode)
08964     {
08965     if (retcode != 0)
08966         {
08967         OutputDebugString ("\n");
08968         txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode);
08969         }
08970 
08971 $5  _txCleanup();
08972 
08973     if (retcode != 0)
08974         txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode);
08975 
08976     Win32::ExitProcess (retcode);
08977     }
08978 
08979 //-----------------------------------------------------------------------------------------------------------------
08980 
08981 bool _txOnTerminateProcess (HANDLE process, unsigned retcode)
08982     {
08983     if (retcode != 0)
08984         {
08985         OutputDebugString ("\n");
08986         txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode);
08987         }
08988 
08989 $5  _txCleanup();
08990 
08991     if (retcode != 0)
08992         txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode);
08993 
08994     return Win32::TerminateProcess (process, retcode);
08995     }
08996 
08997 //-----------------------------------------------------------------------------------------------------------------
08998 
08999 void _txOnFatalExit (int retcode)
09000     {
09001     OutputDebugString ("\n");
09002     txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode);
09003 
09004 $5  _txCleanup();
09005 
09006     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode);
09007     _TX_CALLv (Win32::FatalExit, (retcode));
09008 
09009     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode);
09010     Win32::TerminateProcess (GetCurrentProcess(), retcode);
09011     }
09012 
09013 //-----------------------------------------------------------------------------------------------------------------
09014 
09015 void _txOnFatalAppExitA (unsigned action, const char message[])
09016     {
09017     OutputDebugString ("\n");
09018     txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message);
09019 
09020 $5  _txCleanup();
09021 
09022     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message);
09023     _TX_CALLv (Win32::FatalAppExitA, (action, message));
09024 
09025     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION);
09026     Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09027     }
09028 
09029 //-----------------------------------------------------------------------------------------------------------------
09030 
09031 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type)
09032     {
09033     OutputDebugString ("\n");
09034     txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type);
09035 
09036 $5  switch (type)
09037         {
09038         case CTRL_LOGOFF_EVENT:
09039         case CTRL_SHUTDOWN_EVENT: $ _txExit = true;
09040                                   $ _txCleanup();
09041         case CTRL_C_EVENT:
09042         case CTRL_CLOSE_EVENT:
09043         case CTRL_BREAK_EVENT:
09044 
09045         default:                  break;  //-V2522
09046         }
09047 
09048 $   return false;
09049     }
09050 
09051 //-----------------------------------------------------------------------------------------------------------------
09052 
09053 void _txCleanup()
09054     {
09055     if (!_txInitialized) return;
09056     else _txInitialized = false;  //-V601
09057 
09058 $3  _txRunning = false;
09059 $   _txConsole_IsBlinking = false;
09060 
09061 $   txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR);
09062 
09063 $   txSetWindowsHook (NULL);
09064 
09065 $   HWND canvas     = txWindow();
09066 $   HWND console    = Win32::GetConsoleWindow();
09067 $   unsigned thread = GetCurrentThreadId();
09068 
09069 $   HWND wnd        = (canvas)? canvas : console;
09070 
09071 $   bool externTerm = (thread != _txMainThreadId &&
09072                        thread != _txCanvas_ThreadId);
09073 
09074 $   DWORD parent = 0;
09075 $   int  isParentWaitable = _txIsParentWaitable (&parent);
09076 $   bool waitableParent   = !externTerm && isParentWaitable;
09077 
09078 $   if (canvas)
09079         {$ txSleep (5*_txWindowUpdateInterval); }
09080 
09081 $   if (_txConsole)
09082         {
09083 $       if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
09084 
09085 $       if (console)
09086             {
09087 $           EnableWindow     (console, true);
09088 $           _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */);
09089             }
09090         }
09091 
09092 $   if (_txMain && !externTerm && canvas)
09093         {$  _txSetWindowText (canvas,  " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); }
09094 
09095 $   std::cout.flush();
09096 $   std::cerr.flush();
09097 $   std::clog.flush();
09098 $   _flushall();
09099 
09100 $   bool paused = false;
09101 $   if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId))
09102         {
09103 $       if (wnd)
09104             {
09105 $           if (isParentWaitable >= 0)
09106                 {$ _txActivateWindow (wnd, 0x08); }
09107 
09108 $           EnableWindow (wnd, true);
09109             }
09110 
09111 $       if (console && isParentWaitable >= 0)
09112             {
09113 $           txPause ((_txErrors)?               "\f\n" "[Press F to Pay Respects...]" :
09114                      (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f");
09115 
09116 $           paused = true;
09117             }
09118         }
09119 
09120 $   if (_txConsole && _txWatchdogTimeout >= 0)
09121      {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09122 
09123 $   if (txWindow())
09124         {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); }
09125 
09126 $   _txWaitFor (!txWindow(), 5*_TX_TIMEOUT);
09127 
09128 $   txSpeak     (NULL);
09129 $   txPlayVideo (NULL);
09130 
09131 $   delete _txCanvas_UserDCs;
09132 $   _txCanvas_UserDCs = NULL;
09133 
09134 $   if (GetCurrentThreadId() != _txMainThreadId)
09135         {$ SuspendThread (_txMainThread);    }  //-V720
09136 $   if (GetCurrentThreadId() != _txCanvas_ThreadId)
09137         {$ SuspendThread (_txCanvas_Thread); }  //-V720
09138 
09139 $   if (_txMainThread)
09140         {$ CloseHandle (_txMainThread)    asserted; _txMainThread    = NULL; }
09141 $   if (_txCanvas_Thread)
09142         {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; }
09143 
09144 $   if (!txWindow())
09145         {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; }
09146 
09147 $   bool parentKilled = false;
09148 $   if (waitableParent && paused && _txNOP (_TX_ALLOW_KILL_PARENT))
09149         {
09150 $       console = Win32::GetConsoleWindow();
09151 
09152 $       if (parent)
09153             {$ parentKilled = _txKillProcess (parent); }
09154 
09155 $       if (parent && !parentKilled)
09156             {
09157 $           PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09158 $           PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09159             }
09160         }
09161 
09162 $   if (_txConsole)
09163         {$ _txSetWindowText (console, NULL); }
09164 
09165 $   if (_txMain && _txConsole)
09166         {$ _txConsole_Detach (waitableParent && !parentKilled && !externTerm); }  //-V560
09167 
09168 $   std::cout.flush();
09169 $   std::cerr.flush();
09170 $   std::clog.flush();
09171 $   _flushall();
09172 
09173 $   _txSymGetFromAddr (NULL);
09174 
09175     // That's all, folks
09176 
09177     _TX_ON_DEBUG (OutputDebugString ("\n");
09178                   OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n");
09179                   OutputDebugString ("\n"));
09180     }
09181 
09182 //-----------------------------------------------------------------------------------------------------------------
09183 
09184 int txPause (const char* message /*= NULL*/, ...)
09185     {
09186 $3  bool wine    = !!Win32::wine_get_version;
09187 
09188 $   HWND canvas  = txWindow();
09189 $   HWND console = Win32::GetConsoleWindow();
09190 $   HWND wnd     = (canvas)? canvas : console;
09191 $   bool istty0  = _txIsTTY (0);
09192 
09193 $   int attr     = txGetConsoleAttr();
09194 
09195 $   int oldCP    = GetConsoleOutputCP();
09196 $   SetConsoleOutputCP (_TX_CODEPAGE);
09197 
09198     if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; }
09199 
09200     if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); }
09201     else                  {$ message++; }
09202 
09203     if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); }
09204     else                  {$ message++; }
09205 
09206 $   _txActivateWindow (wnd, 0x08);
09207 
09208 $   va_list args;
09209 $   va_start (args, message);
09210 $   vfprintf (stderr, message, args);
09211 $   txOutputDebugPrintf (message, args);
09212 $   va_end (args);
09213 
09214 $   fflush (stderr);
09215 $   txSleep();
09216 
09217 $   Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF };
09218 $   _TX_CALL (Win32::FlashWindowEx, (&flash));
09219 
09220 $   int ch = EOF;
09221     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09222 
09223 $   for (int i = 1; ; i++)  //-V2530
09224         {
09225 $       Sleep (_txWindowUpdateInterval);
09226 
09227         if (!istty0 && !canvas)                   {$ break; }  // No need to run and hide
09228 
09229         if (!wine && (ch = _txGetInput()) != EOF) {$ break; }  // Somebody hit something.
09230 
09231         if (canvas && !_txCanvas_ThreadId)        {$ break; }  // There was a window, and now there is not.
09232 
09233         if (!Win32::GetConsoleWindow())           {$ break; }  // Console was destroyed
09234 
09235         if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas)))
09236             {$ TX_ERROR ("Похоже, программа зависла :("); break; }
09237 
09238         if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas)))
09239             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; }
09240 
09241         if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL))
09242             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает");  break; }
09243 
09244         if (!wine && !(i % 100500))
09245             {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...]  \b\b"); }
09246         }
09247 
09248     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09249 
09250 $   _txSetWindowText (wnd, NULL);
09251 
09252 $   fprintf (stderr, "\n");
09253 
09254     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09255 
09256 $   SetConsoleOutputCP (oldCP);
09257 $   txSetConsoleAttr (attr);
09258 
09259 $   return ch;
09260     }
09261 
09262 //-----------------------------------------------------------------------------------------------------------------
09263 
09264 int _txGetInput()
09265     {
09266 $4  HANDLE con = GetStdHandle (STD_INPUT_HANDLE);
09267 $   int ch = EOF;
09268 
09269 $   DWORD nChars = 0;
09270 $   if (GetConsoleMode (con, &nChars) == 0 &&
09271         PeekNamedPipe  (con, NULL, 0, NULL, &nChars, NULL))
09272         {
09273 $       ch = (nChars)? fgetc (stdin) : EOF;
09274         }
09275 
09276     else if (_kbhit())
09277         {
09278 $       ch = _getch();
09279         }
09280 
09281 #if defined (_MSC_VER) && (_MSC_VER < 1700)
09282 
09283     else if (fseek (stdin, 1, SEEK_CUR) != EOF)
09284         {
09285 $       (void) fseek (stdin, -1, SEEK_CUR);
09286 $       ch = fgetc (stdin);                                // This causes blocking in MSVC 2011 beta
09287         }
09288 
09289 #endif
09290 
09291     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09292 
09293 $   return ch;
09294     }
09295 
09296 //-----------------------------------------------------------------------------------------------------------------
09297 
09298 bool _txIsTTY (int fd)
09299     {
09300 $4  return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR;
09301     }
09302 
09303 //-----------------------------------------------------------------------------------------------------------------
09304 
09305 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/,
09306                       int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/)
09307     {
09308     struct tools
09309         {
09310         static LRESULT getWindowText (HWND window, wchar_t text[], size_t size)
09311             {
09312 $3          memset (text, 0, size * sizeof (*text));
09313 
09314 $           return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09315             }
09316 
09317         static LRESULT setWindowText (HWND window, wchar_t text[])
09318             {
09319 $1          return SendMessageTimeoutW (window, WM_SETTEXT, 0,             (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09320             }
09321         };
09322 
09323 $1  static wchar_t _tx_thread title    [_TX_BUFSIZE+15] = L"TXLib";
09324 $   static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib";
09325 
09326 $   if (!textRus)
09327         {
09328 $       tools::setWindowText (wnd, oldTitle);
09329 $       return -1;
09330         }
09331 
09332 $   tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09333 $   int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1;
09334 $   memcpy (oldTitle, title, sizeof (oldTitle));
09335 
09336 $   if (textRus)
09337         {
09338 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len);
09339 
09340 $       tools::setWindowText (wnd, title);
09341 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09342         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; }
09343         if (!checkLetters) {$ return -2; }
09344         }
09345 
09346 $   if (textEng)
09347         {
09348 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len);
09349 
09350 $       tools::setWindowText (wnd, title);
09351 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09352         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; }
09353         if (!checkLetters) {$ return -2; }
09354         }
09355 
09356 $   return -3;
09357     }
09358 
09359 //-----------------------------------------------------------------------------------------------------------------
09360 
09361 int _txIsParentWaitable (DWORD* parentPID /*= NULL*/)
09362     {
09363 $4  PROCESSENTRY32* info = _txFindProcess();
09364 $   if (!info) return 0;
09365 
09366 $   info = _txFindProcess (info->th32ParentProcessID);
09367 $   if (!info) return 0;
09368 
09369 $   char parent [MAX_PATH] = "";
09370 $   strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1);
09371 $   if (parentPID) *parentPID = info->th32ProcessID;
09372 
09373 $   info = _txFindProcess (info->th32ParentProcessID);          // info: grandparent
09374 
09375 $   char list[_TX_BUFSIZE] = _TX_WAITABLE_PARENTS;
09376 $   char* ctx = NULL;
09377 
09378 $   for (char* p = strtok_s (list, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx))
09379         {
09380 $       char* gp = strchr (p, ':');
09381 
09382 $       if (gp)
09383             {
09384 $           *gp++ = 0;
09385 
09386 $           if (_stricmp (p, parent) != 0) { continue; }
09387 
09388 $           if (info) if (_stricmp (gp, info->szExeFile) == 0)  // Was &&, but MSVC /analyze is so paranoid
09389                 {$ return islower ((unsigned char) *gp)? +1 : -1; }
09390             }
09391         else
09392             {
09393 $           if (_stricmp (p, parent) == 0)
09394                 {$ return islower ((unsigned char)  *p)? +1 : -1; }
09395             }
09396         }
09397 
09398 $   return 0;
09399     }
09400 
09401 //-----------------------------------------------------------------------------------------------------------------
09402 
09403 void _txWatchdogTerminator (void* timeout)  // Or Watchcat? Possibly will change in future versions
09404     {
09405 $3  if (_TX_ARGUMENT_FAILED (timeout)) return;
09406 
09407 $   Sleep (*(int*) timeout);  //-V206
09408 
09409 $   OutputDebugString ("\n");
09410     txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n",  // Kinda static reflection...
09411                          _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow"));  //-V206
09412 $   DWORD parent = 0;
09413 $   if (_txIsParentWaitable (&parent))
09414         {
09415         txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n",
09416                              _TX_VERSION, __func__, (unsigned long) parent);
09417 
09418 $       _txKillProcess (parent);
09419 
09420 $       HWND console = GetConsoleWindow();
09421 $       PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09422 $       PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09423         }
09424 
09425     txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__);
09426 $   Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09427     }
09428 
09429 #endif // TX_COMPILED
09430 
09431 //}
09432 //-----------------------------------------------------------------------------------------------------------------
09433 
09434 //-----------------------------------------------------------------------------------------------------------------
09435 //{          Tools
09436 //-----------------------------------------------------------------------------------------------------------------
09437 
09438 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09439 
09440 // You are here, little hacker?
09441 
09442 int _txTaskKill (const char i[] /*= NULL*/,
09443                  const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/,
09444                  unsigned   x   /*= 0*/)
09445     {
09446     // ...so tired of it already...
09447 
09448     #define name          i  // Great name!
09449     #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine
09450     #define pid           x  // Another great name, isn't it?
09451 
09452 $3  if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false;  //-V560 //-V601
09453 
09454 $   wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L"";
09455     if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); }
09456 
09457 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09458 $   assert (sshot); if (!sshot) return 0;  //-V547
09459 
09460 $   int killed = 0;
09461 
09462 $   PROCESSENTRY32 info = { sizeof (info) };
09463 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09464         {
09465         bool kill = false;
09466 
09467         if (!kill && pid  && info.th32ParentProcessID        == pid) {$ kill = true; }  //-V560
09468 
09469         if (!kill && name && _stricmp (info.szExeFile, name) == 0)   {$ kill = true; }
09470 
09471         if (!kill)
09472             {
09473             wchar_t cmdLineW[_TX_BUFSIZE] = L"";
09474             if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; }
09475 
09476             if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW))    {$ kill = true; }
09477             }
09478 
09479         if (kill)
09480             {
09481 $           if (_txKillProcess (info.th32ProcessID))
09482                 {$ killed++; }
09483             }
09484         }
09485 
09486 $   CloseHandle (sshot);
09487 
09488 $   return killed;
09489 
09490     #undef name
09491     #undef cmdLine
09492     #undef pid
09493     }
09494 
09495 //-----------------------------------------------------------------------------------------------------------------
09496 
09497 bool _txKillProcess (DWORD pid)
09498     {
09499 $3  if (_TX_ARGUMENT_FAILED (pid)) return false;
09500 
09501 $   HANDLE token = INVALID_HANDLE_VALUE;
09502 $   OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted;
09503 
09504 $   LUID luid = {};
09505 $   LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted;
09506 
09507 $   TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}};
09508 $   TOKEN_PRIVILEGES old  = {};
09509 
09510 $   DWORD oldSz = 0;
09511 $   AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted;
09512 
09513 $   HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid);
09514 $   if (!proc) return false;
09515 
09516 $   bool ok = !!Win32::TerminateProcess (proc, 0);
09517 $   CloseHandle (proc);
09518 
09519 $   return ok;
09520     }
09521 
09522 //-----------------------------------------------------------------------------------------------------------------
09523 
09524 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/)
09525     {
09526 $4  static PROCESSENTRY32 info = { sizeof (info) };
09527 $   if (!pid) return &info;
09528 
09529 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09530 $   assert (sshot); if (!sshot) return NULL;  //-V547
09531 
09532 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09533         if (info.th32ProcessID == pid) break;
09534 
09535 $   CloseHandle (sshot);
09536 
09537 $   return &info;
09538     }
09539 
09540 //-----------------------------------------------------------------------------------------------------------------
09541 
09542 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/)
09543     {
09544 $6  if (_TX_ARGUMENT_FAILED (cmdLine))        return false;
09545 $   if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false;  //-V547
09546 
09547 $   if (pid == (unsigned) _getpid())
09548         {
09549 $       wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1);
09550 $       return true;
09551         }
09552 
09553 $   HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
09554     if (!proc) {$ return false; }
09555 
09556 $   Win32::PROCESS_BASIC_INFORMATION pbi = {};
09557 $   bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0);
09558 
09559     // Should use ReadProcessMemory() because the info is actually in another address space
09560 
09561 $   Win32::PEB peb = {};
09562     if (ok && pbi.PebBaseAddress)        {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress,        &peb,    sizeof (peb),    NULL); }
09563 
09564 $   Win32::RTL_USER_PROCESS_PARAMETERS params = {};
09565     if (ok && peb.ProcessParameters)     {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters,     &params, sizeof (params), NULL); }
09566 
09567 $   *cmdLine = 0;
09568     if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine,  //-V106
09569                                                                        MIN  (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2),  //-V202
09570                                                                        NULL); }
09571 $   CloseHandle (proc) asserted;
09572 
09573 $   return ok;
09574     }
09575 
09576 //-----------------------------------------------------------------------------------------------------------------
09577 
09578 #define RVA_(type, module, addr)  ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) )
09579 
09580 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/)
09581     {
09582 $4  assert (module);
09583 
09584 $   IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0);
09585 $   IMAGE_NT_HEADERS* ntHdr  = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew);
09586 
09587 $   return (dosHdr->e_magic  == IMAGE_DOS_SIGNATURE &&
09588             ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL;
09589     }
09590 
09591 //-----------------------------------------------------------------------------------------------------------------
09592 
09593 // TXLib continues to hack the reality to make your life better, sweeter and easier
09594 
09595 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/,
09596                              HMODULE module /*= NULL*/, bool debug /*= false*/)
09597     {
09598 $4  if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module);
09599 
09600 $   if (_TX_ARGUMENT_FAILED (funcName)) return 0;
09601 $   if (_TX_ARGUMENT_FAILED (newFunc))  return 0;
09602 
09603 $   if (!module) module = GetModuleHandle (NULL);
09604 $   if (!module) return 0;
09605 
09606 $   HMODULE dll     = (dllName)? GetModuleHandle (dllName)       : NULL;
09607 $   PROC    oldFunc = (dll)?     GetProcAddress  (dll, funcName) : NULL;
09608 
09609 $   if (useHotPatching && oldFunc)
09610         {
09611 $       const size_t jmpSz = 1 + sizeof (DWORD);  // sizeof (JMP rel instruction)
09612 
09613 $       DWORD oldRights = 0;
09614 $       if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0;
09615 
09616         // Overwrite oldFunc prolog with JMP trampoline to newFunc.
09617         // Calling oldFunc from any location will lead to newFunc call anyway.
09618 
09619 $       *(BYTE*)  ((char*)(uintptr_t) oldFunc + 0) = 0xE9;  // JMP rel
09620 $       *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF;  //-V206 //-V112 //-V2007 //-V104 //-V103
09621 
09622 $       FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz);
09623 
09624 $       VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights);
09625 
09626 $       return (uintptr_t) oldFunc;
09627         }
09628 
09629 //  For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255
09630 //  and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html.
09631 
09632 $   IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module);
09633     if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; }
09634 
09635 $   DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
09636 $   IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset);
09637 
09638 $   if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0;  //-V1027
09639 
09640 $   IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL;
09641 $   char*  impDll  = NULL;
09642 $   char*  impName = NULL;
09643 $   void** impPtr  = NULL;
09644 $   bool   found   = false;
09645 
09646     for (; desc->Name; desc++)
09647         {
09648 $       impDll = RVA_ (char*, module, desc->Name);
09649 $       if (dllName && _stricmp (impDll, dllName) != 0) continue;
09650 
09651 $       for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk),
09652              thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk);
09653 
09654              thunk0 && thunk1 && thunk1->u1.Function;
09655 
09656              thunk0++,
09657              thunk1++)
09658             {
09659             impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name;
09660             impPtr  = (void**)(uintptr_t)                         &thunk1->u1.Function;  // Should change it, so this is ptr
09661 
09662             if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL;
09663 
09664             if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName);
09665 
09666             if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) ||
09667                 (impName && _stricmp (funcName, impName) == 0))  //-V560
09668                 {
09669                 found = true;
09670                 break;
09671                 }
09672             }
09673 
09674 $       if (found) break;
09675         }
09676 
09677     if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n",
09678                                     funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found"));
09679 $   if (!found) return 0;
09680 
09681 $   DWORD rights = PAGE_READWRITE;
09682 $   if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0;
09683 
09684 $   *(uintptr_t*) impPtr = newFunc;
09685 
09686 $   VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights);
09687 
09688 $   return (uintptr_t) oldFunc;
09689     }
09690 
09691 #undef RVA_
09692 
09693 //-----------------------------------------------------------------------------------------------------------------
09694 
09695 bool _txInDll()
09696     {
09697 $4  MODULEENTRY32 mod = { sizeof (mod) };
09698 
09699 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
09700 $   assert (sshot); if (!sshot) return false;  //-V547
09701 
09702 $   bool inDll = false;
09703 
09704 $   for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod))
09705         {
09706 $       if (!mod.modBaseAddr) continue;
09707 
09708 $       IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr);
09709 
09710 $       inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0);
09711 
09712 $       if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize))  //-V104
09713             {$ break; }
09714         }
09715 
09716 $   CloseHandle (sshot);
09717 $   return inDll;
09718     }
09719 
09720 //-----------------------------------------------------------------------------------------------------------------
09721 
09722 bool _txIsConsoleSubsystem()
09723     {
09724 $4  IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders();
09725 
09726 $   return  ntHdr &&
09727             ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC &&
09728 
09729            (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI ||
09730             ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI);
09731     }
09732 
09733 //-----------------------------------------------------------------------------------------------------------------
09734 
09735 bool _txIsBadReadPtr (const void* address)
09736     {
09737     MEMORY_BASIC_INFORMATION mbi = {};
09738     if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true;
09739 
09740     if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS))  return true;  // Guard page -> bad ptr
09741 
09742     DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
09743 
09744     return !(mbi.Protect & readRights);
09745     }
09746 
09747 //-----------------------------------------------------------------------------------------------------------------
09748 
09749 void _txActivateWindow (HWND wnd, unsigned mode)
09750     {
09751 $1  EnableWindow (wnd, true);
09752 
09753 $   if (mode & 0x10)
09754         {
09755 $       ShowWindow (wnd, SW_MINIMIZE);
09756 $       ShowWindow (wnd, SW_RESTORE);
09757         }
09758 
09759 $   if (mode & 0x08)
09760         {
09761 $       int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0);
09762 
09763 $       AttachThreadInput   (GetCurrentThreadId(), focus, true);
09764 $       SetForegroundWindow (wnd);
09765 $       AttachThreadInput   (GetCurrentThreadId(), focus, false);
09766         }
09767 
09768 $   if (mode & 0x04)
09769         {
09770 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
09771         }
09772 
09773 $   if (mode & 0x02)
09774         {
09775 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS);
09776         }
09777 
09778 $   if (mode & 0x01)
09779         {
09780 $       UpdateWindow (wnd);
09781         }
09782     }
09783 
09784 #endif // TX_COMPILED
09785 
09786 //}
09787 //-----------------------------------------------------------------------------------------------------------------
09788 
09790 //}
09791 //=================================================================================================================
09792 
09793 //=================================================================================================================
09794 //{          Internal TXLib window functions     (_txCanvas...)
09796 //=================================================================================================================
09797 
09798 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09799 
09800 unsigned WINAPI _txCanvas_ThreadProc (void* data)
09801     {
09802     #define SetClassLong_  SetClassLongPtr
09803     #define GCL_HICON_     GCLP_HICON
09804     #define GCL_HICONSM_   GCLP_HICONSM
09805     #define GCL_HCURSOR_   GCLP_HCURSOR
09806 
09807 $8  _txCanvas_ThreadId = GetCurrentThreadId();
09808 
09809 $   if (_TX_ARGUMENT_FAILED (data)) return false;  //-V601
09810 
09811 $   unsigned long stackSize = _TX_STACKSIZE;
09812 $   _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
09813 
09814 $   HWND wnd = _txCanvas_CreateWindow ((SIZE*) data);
09815 $   if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0;
09816 
09817 $   HICON   icon32 = LoadIcon         (NULL, "_TX_ICON");
09818 $   HICON   icon16 = LoadIcon         (NULL, "_TX_ICONSM");
09819 $   HCURSOR cursor = LoadCursor       (NULL, "_TX_CURSOR");
09820 $   HMENU   menu   = LoadMenu         (NULL, "_TX_MENU");
09821 $   HACCEL  accel  = LoadAccelerators (NULL, "_TX_ACCELERATORS");
09822 
09823 $   SetClassLong_ (wnd, GCL_HICON_,   (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32)));          //-V107 //-V112
09824 $   SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16)));          //-V107
09825 $   SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW)));  //-V107
09826 
09827     if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); }
09828 
09829 $   Win32::GdiSetBatchLimit (1);
09830 
09831     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n"));
09832 
09833 $   _txActivateWindow (wnd, 0x10);
09834 
09835 $   ShowWindow   (wnd, SW_SHOW);
09836 $   UpdateWindow (wnd);
09837 
09838 $   _txRunning = true;
09839 
09840 $   MSG msg = {};
09841 $   while (GetMessage (&msg, NULL, 0, 0))
09842         {
09843         if (!msg.hwnd) {$ continue; }
09844 
09845         if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; }
09846 
09847 $       TranslateMessage (&msg);
09848 $       DispatchMessage  (&msg);
09849 
09850 $       Sleep (0);
09851         }
09852 
09853 $   if (icon16) DestroyIcon (icon16);  // If Explorer is displaying Tray Notification, these
09854 $   if (icon32) DestroyIcon (icon32);  // calls will possibly fail, and we'll get resource leak.
09855 
09856 $   LeaveCriticalSection (&_txCanvas_LockBackBuf);
09857 
09858     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n"));
09859 
09860 $   if (_txWatchdogTimeout >= 0)
09861         {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09862 
09863 $   if (_txRunning && _txMain)         // Main window is destroyed but main() is still running.
09864         {                              // No chances for good termination, so use exit().
09865 $       _txCleanup();
09866 $       ::exit ((int) msg.wParam);     //-V202 //-V2509 //-V2014
09867         }
09868 
09869 $   _txCanvas_ThreadId = 0;
09870 $   return true;                       //-V601
09871 
09872     #undef SetClassLong
09873     #undef GCL_HICON_
09874     #undef GCL_HICONSM_
09875     #undef GCL_HCURSOR_
09876     }
09877 
09878 //-----------------------------------------------------------------------------------------------------------------
09879 
09880 HWND _txCanvas_CreateWindow (const SIZE* sizePtr)
09881     {
09882 $8  if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL;
09883 
09884 $   bool centered = false;
09885     if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; }
09886 
09887 $   SIZE screen  = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) };
09888 $   RECT rect    = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false);
09889 $   SIZE size    = { rect.right - rect.left, rect.bottom - rect.top };
09890 $   RECT conPos  = {};
09891 
09892 $   HWND console = _TX_CALL (Win32::GetConsoleWindow, ());
09893     if (console) {$ GetWindowRect (console, &conPos); }
09894 
09895 $   const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0);
09896 $   if (!wndClass) return (HWND) NULL;
09897 
09898 $   HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN,
09899                               (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT,
09900                               (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top  : CW_USEDEFAULT,
09901                                size.cx, size.cy, NULL, NULL, NULL, NULL);
09902 $   if (!wnd || !txWindow())
09903         {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; }
09904 
09905 $   HMENU menu = GetSystemMenu (txWindow(), false);
09906     if (!menu) {$ return txWindow(); }
09907 
09908 $   AppendMenu (menu, MF_SEPARATOR, 0, NULL)                       asserted;
09909 $   AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted;
09910 $   AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT,   "&About...")     asserted;
09911 
09912 $   return txWindow();
09913     }
09914 
09915 //-----------------------------------------------------------------------------------------------------------------
09916 
09917 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra)
09918     {
09919 $8  assert (classId);
09920 $   assert (wndProc);
09921 
09922 $   static char name[_TX_BUFSIZE] = "";
09923 $   _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ "
09924                                              _TX_VERSION "  " __FILE__ "  WndClass %08lX "
09925                                              "-------------[%s]-[TXLib]---*/",
09926                                              classId, (unsigned long) GetTickCount(), classId);
09927 $   WNDCLASS wc      = { sizeof (wc) };
09928 
09929 $   wc.lpszClassName = name;
09930 $   wc.lpfnWndProc   = wndProc;
09931 $   wc.style         = style;
09932 $   wc.cbWndExtra    = (wndExtra + 1) * (int) sizeof (long);
09933 
09934 $   wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
09935 $   wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush);
09936 
09937 $   ATOM atom = RegisterClass (&wc);
09938     if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; }
09939 
09940 $   return (const char*)(uintptr_t) atom;
09941     }
09942 
09943 //-----------------------------------------------------------------------------------------------------------------
09944 
09945 int _txCanvas_SetRefreshLock (int count)
09946     {
09947 $8  int oldCount = _txCanvas_RefreshLock;
09948 
09949 $   _txCanvas_RefreshLock = count;
09950 
09951 $   HWND wnd = txWindow();
09952 
09953 $   if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd)
09954         {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
09955 
09956 $   return oldCount;
09957     }
09958 
09959 //-----------------------------------------------------------------------------------------------------------------
09960 
09961 HICON _txCreateTXIcon (int size)
09962     {
09963 $8  if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL;  //-V112 //-V560
09964 
09965 $   const unsigned char image32 [32*32+1] =
09966         "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0"
09967         "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0"
09968         "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0"
09969         "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0"
09970         "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0"
09971         "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0"
09972         "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0"
09973         "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000";
09974 
09975 $   const unsigned char image16 [16*16+1] =
09976         "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990"
09977         "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000";
09978 
09979 $   const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0,
09980                                       0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff };
09981 
09982 $   const unsigned char* image = (size == 32)? image32 : image16;  //-V112
09983 
09984 $   POINT sz = { size, size };
09985 $   HDC dcMask  = _txBuffer_Create (txWindow(), &sz); assert (dcMask);
09986 $   HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor);
09987 
09988 $   for (int i = 0; i < size*size; i++)
09989         {
09990         assert (In (std::nomeow, image[i], '0', '9') ||
09991                 In (std::nomeow, image[i], 'A', 'F'));
09992 
09993         Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']);
09994         }
09995 
09996 $   ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask,  OBJ_BITMAP),
09997                                   (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) };
09998 
09999 $   HICON icon = CreateIconIndirect (&info);
10000 $   assert (icon);
10001 
10002 $   _txBuffer_Delete (&dcMask)  asserted;
10003 $   _txBuffer_Delete (&dcColor) asserted;
10004 
10005 $   return icon;
10006     }
10007 
10008 #endif // TX_COMPILED
10009 
10010 //-----------------------------------------------------------------------------------------------------------------
10011 
10012 inline bool _txCanvas_OK()
10013     {
10014     return _txCanvas_ThreadId   &&
10015            _txCanvas_Window     &&
10016            _txCanvas_BackBuf[0] &&
10017            _txCanvas_BackBuf[1] &&
10018            _txCanvas_Pixels;
10019     }
10020 
10021 //}
10022 //=================================================================================================================
10023 
10024 //=================================================================================================================
10025 //{          Main window event handlers          (_txCanvas_On...)
10027 //=================================================================================================================
10029 
10030 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10031 
10032 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
10033     {
10034 #if defined (_TX_ALLOW_TRACE)
10035 
10036     int inTX = _txLoc::Cur.inTX++;
10037 
10038     if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)",
10039                                      2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar);
10040     _txLoc::Cur.inTX = inTX;
10041 
10042 #endif
10043 
10044 $8  if (msg == WM_KEYDOWN && wpar == VK_F12 &&
10045         GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU))
10046         {
10047 $       _txCanvas_OnCmdABOUT (wnd,      wpar);
10048 $       return DefWindowProc (wnd, msg, wpar, lpar);
10049         }
10050 
10051     WNDPROC altWndProc = _txAltWndProc;  // Cache to prevent change from main thread
10052     if (altWndProc)
10053         {
10054 $       LRESULT res = altWndProc (wnd, msg, wpar, lpar);
10055 $       if (res) return res;
10056         }
10057 
10058     static bool bkErased = false;
10059 
10060     switch (msg)
10061         {
10062         case WM_CREATE:         {$     _txCanvas_OnCREATE     (wnd);                    return 0; }
10063 
10064         case WM_CLOSE:          {$ if (_txCanvas_OnCLOSE      (wnd))  break;       else return 0; }
10065         case WM_DESTROY:        {$     _txCanvas_OnDESTROY    (wnd);                    return 0; }
10066 
10067         case WM_ERASEBKGND:     {$ if (!bkErased) { bkErased = true;  break; }     else return 1; }
10068         case WM_SIZE:           {$                  bkErased = false; break;                      }
10069 
10070         case WM_PAINT:          {$     _txCanvas_OnPAINT      (wnd);                    return 0; }
10071 
10072         case WM_TIMER:          {$     _txCanvas_OnTIMER      (wnd, wpar);              return 0; }
10073 
10074         case WM_KEYUP:          {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, false)) return 0; else break; }
10075         case WM_KEYDOWN:        {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, true))  return 0; else break; }
10076         case WM_CHAR:           {$ if (_txCanvas_OnCHAR       (wnd, wpar, lpar))        return 0; else break; }
10077 
10078         case WM_LBUTTONUP:
10079         case WM_LBUTTONDOWN:
10080         case WM_RBUTTONUP:
10081         case WM_RBUTTONDOWN:
10082         case WM_MBUTTONUP:
10083         case WM_MBUTTONDOWN:
10084         case WM_MOUSEMOVE:      {$     _txCanvas_OnMOUSEMOVE  (wnd, wpar, lpar);        return 0; }
10085 
10086         case WM_MOUSELEAVE:     {$     _txCanvas_OnMOUSELEAVE (wnd);                    return 0; }
10087 
10088         case _TX_WM_CREATEWND:  {$     _txCanvas_OnCREATEWND  (wnd, wpar, lpar);        return 0; }
10089         case _TX_WM_DESTROYWND: {$     _txCanvas_OnDESTROYWND (wnd, wpar, lpar);        return 0; }
10090 
10091         case WM_NULL:           {$                                                      return 0; }
10092 
10093         default: break;  //-V2522
10094         }
10095 
10096     if (msg == WM_SYSCOMMAND) switch (wpar)
10097         {
10098         case _TX_IDM_ABOUT:     {$     _txCanvas_OnCmdABOUT   (wnd, wpar);              return 0; }
10099         case _TX_IDM_CONSOLE:   {$     _txCanvas_OnCmdCONSOLE (wnd, wpar);              return 0; }
10100 
10101         default: break;  //-V2522
10102         }
10103 
10104 $   return DefWindowProc (wnd, msg, wpar, lpar);
10105     }
10106 
10107 //-----------------------------------------------------------------------------------------------------------------
10108 
10109 bool _txCanvas_OnCREATE (HWND wnd)
10110     {
10111 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10112 
10113 $   _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]);
10114 $   _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL);              assert (_txCanvas_BackBuf[1]);
10115 
10116 $   if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0;
10117 $   assert (_txCanvas_RefreshTimer);
10118 
10119 $   _txCanvas_UserDCs = new ::std::vector <HDC>;
10120 
10121 $   _txCanvas_Window = wnd;
10122 
10123 $   txSetDefaults();
10124 
10125 $   return true;
10126     }
10127 
10128 //-----------------------------------------------------------------------------------------------------------------
10129 
10130 bool _txCanvas_OnDESTROY (HWND wnd)
10131     {
10132 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10133 
10134     // Инициируем остановку цикла сообщений
10135 
10136 $   PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS);
10137 
10138 $   if (!_txCanvas_Window) return false;
10139 
10140     // Indicate that we are about to manually terminate
10141 
10142 $   _txExit = true;
10143 
10144     // Lock GDI resources
10145 
10146 $   bool locked = false;
10147 $   _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT);
10148 $   if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources");
10149 
10150     // Освобождаем пользовательские ресурсы
10151 
10152 $   if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty())
10153         {
10154 $       txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size());  //-V202
10155 $       Sleep (_TX_TIMEOUT);
10156 
10157 $       for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i));
10158 $       _txCanvas_UserDCs->clear();
10159         }
10160 
10161     // Освобождаем ресурсы, связанные с окном
10162 
10163 $   if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted;
10164 
10165 $   if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1])  asserted;
10166 $   if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0])  asserted;
10167 $   _txCanvas_Pixels = NULL;
10168 
10169 $   txUnlock();
10170 
10171     // Indicate that we are destroyed
10172 
10173 $   _txCanvas_Window = NULL;
10174 
10175 $   return true;
10176     }
10177 
10178 //-----------------------------------------------------------------------------------------------------------------
10179 
10180 bool _txCanvas_OnCLOSE (HWND wnd)  //-V2009 //-V2558
10181     {
10182 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10183 $   if (!_txCanvas_OK())           return false;
10184 
10185 $   if (_txMain && _txRunning &&
10186         txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n"
10187                       "Лучше подождать, когда main() завершится - это отображается в заголовке окна.",
10188                       txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false;
10189 $   return true;
10190     }
10191 
10192 //-----------------------------------------------------------------------------------------------------------------
10193 
10194 bool _txCanvas_OnTIMER (HWND wnd, WPARAM)
10195     {
10196 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10197 
10198 $   if (_txCanvas_RefreshLock > 0 || !_txRunning) return false;
10199 
10200 $   InvalidateRect (wnd, NULL, false) asserted;
10201 $   UpdateWindow   (wnd)              asserted;
10202 
10203 $   return true;
10204     }
10205 
10206 //-----------------------------------------------------------------------------------------------------------------
10207 
10208 bool _txCanvas_OnPAINT (HWND wnd)
10209     {
10210 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10211 $   if (!_txCanvas_OK())           return false;
10212 
10213 $   bool forceRedraw = GetAsyncKeyState (VK_MENU)  && GetAsyncKeyState (VK_CONTROL) &&
10214                        GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT);
10215 
10216 $   PAINTSTRUCT ps = {};
10217 $   HDC wndDc = BeginPaint (wnd, &ps);
10218 $   if (!wndDc) return false;
10219 
10220 $   HDC dc0 = _txCanvas_BackBuf[0],
10221         dc1 = _txCanvas_BackBuf[1];
10222 
10223 $   RECT r = {};
10224 $   GetClientRect (wnd, &r) asserted;
10225 $   POINT wndSize = { r.right - r.left, r.bottom - r.top };
10226 
10227 $   POINT dcSize = txGetExtent (dc1);
10228 
10229 $   if ((_txCanvas_RefreshLock <= 0 || forceRedraw) &&
10230         txLock (false))
10231         {
10232 $       Win32::BitBlt          (dc1,   0, 0, dcSize.x,  dcSize.y,  dc0, 0, 0, SRCCOPY);
10233 
10234 $       if (_txConsole >= 0)
10235             {$ _txConsole_Draw (dc1); }
10236 
10237 $       txUnlock();
10238         }
10239 
10240     // Magic 100500 value is used to completely block screen refresh.
10241     // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL.
10242     // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers
10243     // themselves.
10244     // Yes guys, with all your software installed. :(
10245 
10246 $   if (_txCanvas_RefreshLock != 100500)
10247         {
10248         if (_txSwapBuffers)
10249             {
10250 $           _txSwapBuffers     (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10251             }
10252         else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y)
10253             {
10254 $           Win32::BitBlt      (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0,                     SRCCOPY);
10255             }
10256         else
10257             {
10258 $           Win32::SetStretchBltMode (wndDc, HALFTONE);
10259 $           Win32::StretchBlt  (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10260             }
10261         }
10262 
10263 $   EndPaint (wnd, &ps) asserted;
10264 
10265 $   return true;
10266     }
10267 
10268 //-----------------------------------------------------------------------------------------------------------------
10269 
10270 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info)
10271     {
10272 $8  INPUT_RECORD evt[2] = {};
10273 
10274 $   evt[0].EventType                        = KEY_EVENT;
10275 $   evt[0].Event.KeyEvent.bKeyDown          = true;
10276 $   evt[0].Event.KeyEvent.wRepeatCount      = 1;
10277 $   evt[0].Event.KeyEvent.uChar.AsciiChar   = (char) (ch);
10278 $   evt[0].Event.KeyEvent.wVirtualScanCode  = (WORD) (info >> 16);
10279 $   evt[0].Event.KeyEvent.wVirtualKeyCode   = (WORD) MapVirtualKey ((WORD) (info >> 16), 3);  // 3 == MAPVK_VSC_TO_VK_EX
10280 $   evt[0].Event.KeyEvent.dwControlKeyState = 0;
10281 
10282 $   evt[1] = evt[0];
10283 $   evt[1].Event.KeyEvent.bKeyDown          = false;
10284 
10285 $   DWORD written = 0;
10286 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE),  evt, 2, &written);
10287 
10288 $   return true;
10289     }
10290 
10291 //-----------------------------------------------------------------------------------------------------------------
10292 
10293 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down)
10294     {
10295 $8  INPUT_RECORD evt = {};
10296 
10297 $   evt.EventType                           = KEY_EVENT;
10298 $   evt.Event.KeyEvent.bKeyDown             = down;
10299 $   evt.Event.KeyEvent.wRepeatCount         = 1;
10300 $   evt.Event.KeyEvent.uChar.AsciiChar      = (char)  MapVirtualKey ((WORD) vk, 2);           // 2 == MAPVK_VK_TO_CHAR
10301 $   evt.Event.KeyEvent.wVirtualScanCode     = (WORD)  (info >> 16);
10302 $   evt.Event.KeyEvent.wVirtualKeyCode      = (WORD)  vk;
10303 $   evt.Event.KeyEvent.dwControlKeyState    = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0;
10304 
10305 $   if (evt.Event.KeyEvent.uChar.AsciiChar) return false;  // Let TranslateMessage() and WM_CHAR do the job
10306 
10307 $   DWORD written = 0;
10308 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written);
10309 
10310 $   return true;
10311     }
10312 
10313 //-----------------------------------------------------------------------------------------------------------------
10314 
10315 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords)
10316     {
10317 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10318 $   if (!_txCanvas_OK())           return false;
10319 
10320 $   if (_txMousePos.x == -1 && _txMousePos.y == -1)
10321         {
10322 $       TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT };
10323 $       TrackMouseEvent (&track);
10324         }
10325 
10326 $   _txMousePos.x   = LOWORD (coords);
10327 $   _txMousePos.y   = HIWORD (coords);
10328 $   _txMouseButtons = (unsigned) buttons;  //-V202
10329 
10330 $   return true;
10331     }
10332 
10333 //-----------------------------------------------------------------------------------------------------------------
10334 
10335 bool _txCanvas_OnMOUSELEAVE (HWND)
10336     {
10337 $8  _txMousePos.x   = -1;
10338 $   _txMousePos.y   = -1;
10339 $   _txMouseButtons = 0;
10340 
10341 $   return true;
10342     }
10343 
10344 //-----------------------------------------------------------------------------------------------------------------
10345 
10346 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar)
10347     {
10348 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10349 
10350 $   const CREATESTRUCT* create = (CREATESTRUCT*) lpar;
10351 
10352 $   HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style,
10353                                create->x, create->y, create->cx, create->cy,
10354                                create->hwndParent, create->hMenu, NULL, create->lpCreateParams);
10355 
10356 $   *(HWND*) create->hInstance = wnd;
10357 
10358 $   return true;
10359     }
10360 
10361 //-----------------------------------------------------------------------------------------------------------------
10362 
10363 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar)
10364     {
10365 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10366 
10367 $   DestroyWindow ((HWND) lpar);
10368 
10369 $   return false;
10370     }
10371 
10372 //-----------------------------------------------------------------------------------------------------------------
10373 
10374 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd)
10375     {
10376 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10377 
10378 $   HWND console = Win32::GetConsoleWindow();
10379 $   if (!console) return false;
10380 
10381 $   bool visible = !!IsWindowVisible (console);
10382 
10383 $   ShowWindow (console, visible? SW_HIDE : SW_RESTORE);
10384 
10385 $   visible = !!IsWindowVisible (console);
10386 $   CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED);  //-V202
10387 
10388 $   return true;
10389     }
10390 
10391 //-----------------------------------------------------------------------------------------------------------------
10392 
10393 bool _txCanvas_OnCmdABOUT (HWND, WPARAM)
10394     {
10395 $8  //{ Overriding the missing names, if the set is uncomplete
10396 
10397     #if defined (__MODULE)
10398         #define ABOUT_NAME_    __MODULE
10399     #else
10400         #define ABOUT_NAME_    "TXLib"
10401     #endif
10402 
10403     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10404 
10405         #ifndef __MODULE
10406         #define __MODULE       "TXLib"                           "\n"  "#define __MODULE to set the name.\n"
10407         #endif
10408 
10409         #ifndef __VERSION
10410         #define __VERSION      "(0.000000000)."                  "\n" "#define __VERSION to set the string value.\n"
10411         #endif
10412 
10413         #ifndef __DESCRIPTION
10414         #define __DESCRIPTION  "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n"
10415         #endif
10416 
10417         #ifndef __AUTHOR
10418         #define __AUTHOR       "(Непонятно кто)."                "\n" "#define __AUTHOR to override this name."
10419         #endif
10420 
10421     #endif
10422     //}
10423 
10424 $   static char text[_TX_BUFSIZE] = "";
10425 
10426 $   _tx_snprintf_s (text, sizeof (text) - 1,
10427 
10428                     "Application:\n\n"
10429 
10430                     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10431                         __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n"
10432                     #else
10433                         "Здесь могла бы быть Ваша реклама :)\n"
10434                         "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n"
10435                     #endif
10436 
10437                     "\n" "%s", _txAppInfo());
10438 
10439 $   txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION);
10440 
10441     // And a bit of HTTP-code in C++ function:
10442 
10443     goto http;
10444     http://sizeof.livejournal.com
10445 
10446 $   return true;
10447 
10448     #undef ABOUT_NAME_
10449     }
10450 
10451 #endif // TX_COMPILED
10452 
10454 //}
10455 //=================================================================================================================
10456 
10457 //=================================================================================================================
10458 //{          Console-support functions           (_txConsole...)
10460 //=================================================================================================================
10462 
10463 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10464 
10465 HWND _txConsole_Attach()
10466     {
10467 $1  HWND console = Win32::GetConsoleWindow();
10468 
10469 $   if (!console)
10470         {
10471 $       bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem());
10472 
10473 $       Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb();
10474 $       assert (teb);
10475 $       assert (teb->ProcessEnvironmentBlock);
10476 
10477 $       Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters;
10478 $       assert (params);
10479 
10480 $       if (minimizeConsole)  // The fact that ShowWindow parameter of the program's console is taken from calling
10481                               // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo()
10482                               // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :(
10483                               // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke!..
10484             {
10485 $           params->dwFlags    |= STARTF_USESHOWWINDOW;
10486 $           params->wShowWindow = SW_MINIMIZE;
10487             }
10488 
10489 $       AllocConsole();
10490 $       console = Win32::GetConsoleWindow();
10491         }
10492 
10493 $   if (!console) return NULL;
10494 
10495 $   txSetLocale();                                // Устанавливаем русскую кодовую страницу для консоли Windows
10496 
10497 $   _txConsole_SetUnicodeFont();                  // Впечатлительным лучше сюда не смотреть.
10498 
10499 $   if (!_txIsConsoleSubsystem())
10500         {$ txReopenStdio(); }                     // Переоткрываем потоки ввода-вывода, если subsystem != console
10501 
10502 $   return console;
10503     }
10504 
10505 //-----------------------------------------------------------------------------------------------------------------
10506 
10507 int txSetLocale (int codepage /*= _TX_CODEPAGE*/,
10508                  const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/)
10509     {
10510 $1  int oldPage = GetConsoleOutputCP();
10511 
10512     // Устанавливаем нужную кодовую страницу для консоли Windows
10513 
10514 $   if (codepage)
10515         {
10516 $       SetConsoleCP       (codepage);
10517 $       SetConsoleOutputCP (codepage);
10518         }
10519 
10520     // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии
10521     // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным
10522     // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN -
10523     // обозначение кодовой страницы (например, для русского языка - CP1251).
10524 
10525 $   if (locale)
10526         {
10527 $       setlocale (LC_ALL,     locale);
10528 $       setlocale (LC_NUMERIC, "C");              // Return to decimal point (3.14) instead of comma (3,14) in floating numbers
10529         }
10530 
10531     #ifndef __CYGWIN__
10532 
10533 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10534 
10535 $   if (wLocale && !wine)
10536         {
10537 $       _wsetlocale (LC_ALL,     wLocale);
10538 $       _wsetlocale (LC_NUMERIC, L"C");           // L"C" (see above)
10539         }
10540 
10541     #endif
10542 
10543     (void) wLocale;
10544 
10545 $   return oldPage;
10546     }
10547 
10548 //-----------------------------------------------------------------------------------------------------------------
10549 
10550 void txReopenStdio()
10551     {
10552 $1  // Переоткрываем заново <s>Америку</s> потоки ввода-вывода
10553 
10554 $   fflush (stdout);
10555 $   fflush (stderr);
10556 
10557 $   FILE* f = NULL;
10558 
10559     #ifndef __CYGWIN__
10560 
10561 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE),  _O_TEXT), "r"); assert (f); *stdin  = *f;
10562 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f;
10563 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE),  _O_TEXT), "w"); assert (f); *stderr = *f;
10564 
10565     #else
10566 
10567 $   f = _fdopen (STDIN_FILENO,  "r"); assert (f); *stdin  = *f;
10568 $   f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f;
10569 $   f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f;
10570 
10571     #endif
10572 
10573 $   setvbuf (stdin,  NULL, _IONBF, 0);
10574 $   setvbuf (stdout, NULL, _IONBF, 0);
10575 $   setvbuf (stderr, NULL, _IONBF, 0);
10576 
10577 $   ::std::ios::sync_with_stdio();
10578     }
10579 
10580 //-----------------------------------------------------------------------------------------------------------------
10581 
10582 inline bool _txConsole_OK()
10583     {
10584     return Win32::GetConsoleWindow() != NULL;
10585     }
10586 
10587 //-----------------------------------------------------------------------------------------------------------------
10588 
10589 bool _txConsole_Detach (bool activate)
10590     {
10591 $1  HWND console = Win32::GetConsoleWindow();
10592 $   if (!console) return false;
10593 
10594 $   EnableWindow (console, true);
10595 
10596 $   if (activate)
10597         {
10598 $       if (!IsWindowVisible (console))
10599             {$ ShowWindow (console, SW_MINIMIZE); }
10600 
10601 $       _txActivateWindow (console, 0xFF);
10602 $       return true;
10603         }
10604     else
10605         {
10606 $       return !!FreeConsole();
10607         }
10608     }
10609 
10610 //-----------------------------------------------------------------------------------------------------------------
10611 
10612 bool _txConsole_Draw (HDC dc)
10613     {
10614 $8  if (_TX_HDC_FAILED (dc)) return false;
10615 
10616 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10617 
10618 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
10619 $   BOOL ok = GetConsoleScreenBufferInfo (out, &con);
10620 $   if (!ok) return false;
10621 
10622 $   POINT size = { con.srWindow.Right  - con.srWindow.Left + 1,
10623                    con.srWindow.Bottom - con.srWindow.Top  + 1 };
10624 
10625 $   SIZE fontSz = { 12, 16 };
10626 $   Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted;
10627 
10628 $   COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
10629                           0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF };
10630 
10631 $   for (short y = 0; y < size.y; y++)
10632         {
10633         static char chr [_TX_BUFSIZE + 1] = "";  // [con.dwSize.X + 1]; maybe will be truncated
10634         static WORD atr [_TX_BUFSIZE + 1] = {};  // [con.dwSize.X + 1]; maybe will be truncated
10635         COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) };
10636         DWORD read  = 0;
10637 
10638         if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue;
10639         if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue;
10640 
10641         for (int x = 0, xEnd = size.x; x < size.x; x = xEnd)
10642             {
10643             Win32::SetTextColor (dc, pal [ atr[x]       & 0x0F]);
10644             Win32::SetBkColor   (dc, pal [(atr[x] >> 4) & 0x0F]);
10645             Win32::SetBkMode    (dc,      (atr[x]       & 0xF0)? OPAQUE : TRANSPARENT);
10646 
10647             for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;}
10648 
10649             Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)),
10650                                 ROUND (fontSz.cy *  y), chr + x, xEnd - x) asserted;
10651             }
10652         }
10653 
10654 $   Win32::SetTextColor (dc, pal [ con.wAttributes       & 0x0F]);
10655 $   Win32::SetBkColor   (dc, pal [(con.wAttributes >> 4) & 0x0F]);
10656 $   Win32::SetBkMode    (dc, TRANSPARENT);
10657 
10658 $   if (_txConsole_IsBlinking &&
10659         In (std::nomeow, con.dwCursorPosition, con.srWindow) &&
10660         GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval &&
10661         GetForegroundWindow() == txWindow())
10662         {
10663 $       Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)),
10664                             ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1,
10665                             "_", 1) asserted;
10666         }
10667 
10668 $   return true;
10669     }
10670 
10671 #endif // TX_COMPILED
10672 
10673 //-----------------------------------------------------------------------------------------------------------------
10674 //{          Welcome to the Duck Side! Together we will rule the Bathroom!
10675 //-----------------------------------------------------------------------------------------------------------------
10676 
10677 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10678 
10679 bool _txConsole_SetUnicodeFont()
10680     {
10681 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10682                                                   // Beer compatibility may be added in future versions...
10683 $   if (wine)                                     // Минздрав РФ предупреждает: чрезмерное употребление wine
10684         {                                         // вредит Вашему здоровью.
10685 $       Win32::GetNumberOfConsoleFonts = NULL;
10686 $       Win32::GetCurrentConsoleFont   = NULL;
10687 $       Win32::SetConsoleFont          = NULL;
10688 
10689 $       return false;
10690         }
10691 
10692     // Начиная с Висты все хорошо...
10693 
10694 $1  if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx)
10695         {
10696 $       HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10697 
10698 $       Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) };
10699 $       if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false;
10700 
10701 $       info.FontFamily = 0x36;                                                    // Unicode fixed-pitch
10702 $       if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2);  // Terminal font is too small
10703 
10704 $       if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0)    // Consolas is allowed too
10705             {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); }
10706 
10707 $       return !!Win32::SetCurrentConsoleFontEx (out, false, &info);
10708         }
10709 
10710     // ...а до этого все не так сладко
10711 
10712 $   const unsigned uniFont = 10;                  // The Internet and W2K sources know this magic number
10713 $   const unsigned uniSize = 20;                  // Size of the font desired, should be > max # of Raster Fonts  //-V2551
10714 $   bool ok = true;
10715 
10716     // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font.
10717 
10718 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10719 
10720 $   unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ());
10721 $   if (fonts && fonts <= uniFont)
10722         {
10723 $       HRESULT init = Win32::CoInitialize (NULL);
10724 $       size_t sz = 0;
10725 
10726 $       char link [MAX_PATH] = "";
10727 $       getenv_s (&sz, link, sizeof (link) - 1, "TEMP");
10728 $       strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1);
10729 
10730 $       char comspec [MAX_PATH] = "";
10731 $       getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC");
10732 
10733 $       (void) _unlink (link);
10734 
10735 $       _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted;
10736 
10737 $       ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32);  // Sic!  //-V112 //-V566
10738         if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); }
10739 
10740 $       (void) _unlink (link);
10741 
10742 $       if (init == S_OK) Win32::CoUninitialize();
10743         }
10744 
10745     // If Unicode font is not already set, do set it.
10746 
10747 $   Win32::CONSOLE_FONT_INFO cur = {};
10748 $   _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur));
10749 
10750 $   ok &= (cur.nFont >= uniFont);
10751     if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); }
10752 
10753 $   HWND console = Win32::GetConsoleWindow();
10754 $   InvalidateRect (console, NULL, false);
10755 $   UpdateWindow   (console);
10756 
10757 $   return ok;
10758     }
10759 
10760 #endif // TX_COMPILED
10761 
10762 //-----------------------------------------------------------------------------------------------------------------
10763 //{          The assistants to the nightmare. You can use it freely to make your own nightmare sweet.
10764 
10765 #define      _TX_TRY                { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error;
10766 #define      _TX_CHECKED( cmd )     { if (FAILED (__tx_error = (cmd))) goto __tx_catch; }
10767 #define      _TX_FAIL               { __tx_error = E_FAIL; goto __tx_catch; }
10768 #define      _TX_RETRY              { __tx_error = S_OK;   goto __tx_try;   }
10769 #define      _TX_OK                 ( SUCCEEDED (__tx_error) )
10770 #define      _TX_CATCH              goto __tx_finally; __tx_catch:
10771 #define      _TX_RETURN             goto __tx_finally;
10772 #define      _TX_FINALLY            __tx_finally:
10773 #define      _TX_ENDTRY             }
10774 
10775 //}
10776 //-----------------------------------------------------------------------------------------------------------------
10777 
10778 // Мало не покажется
10779 
10780 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10781 
10782 bool _txCreateShortcut (const char shortcutName[],
10783                         const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/,
10784                         const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/,
10785                         int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/)
10786     {
10787 $1  if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false;
10788 $   if (_TX_ARGUMENT_FAILED (fileToLink   && *fileToLink))   return false;
10789 
10790     #if defined (__IShellLinkDataList_INTERFACE_DEFINED__)
10791 
10792 $   IShellLink* shellLink = NULL;
10793 $   IShellLinkDataList* dataList = NULL;
10794 $   IPersistFile* file = NULL;
10795 
10796 $   HRESULT init = Win32::CoInitialize (NULL);
10797 
10798     _TX_TRY
10799         {
10800 $       _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink));
10801 $       if (!shellLink) _TX_FAIL;
10802 
10803 $       shellLink->SetPath (fileToLink);
10804 $       shellLink->SetArguments (args);
10805 $       shellLink->SetWorkingDirectory (workDir);
10806 $       shellLink->SetDescription (description);
10807 $       shellLink->SetShowCmd (cmdShow);
10808 $       shellLink->SetIconLocation (iconFile, iconIndex);
10809 
10810 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList));
10811 $       if (!dataList) _TX_FAIL;
10812 
10813 $       Win32::NT_CONSOLE_PROPS props =
10814           {{sizeof (props), NT_CONSOLE_PROPS_SIG},
10815 
10816             FOREGROUND_LIGHTGRAY,                       // wFillAttribute
10817             FOREGROUND_MAGENTA | BACKGROUND_WHITE,      // wPopupFillAttribute
10818            {bufSize.X, bufSize.Y},                      // dwScreenBufferSize
10819            {wndSize.X, wndSize.Y},                      // dwWindowSize
10820            {wndOrg.X,  wndOrg.Y},                       // dwWindowOrigin
10821             0,                                          // nFont
10822             0,                                          // nInputBufferSize
10823            {0, (short) fontSize},                       // dwFontSize
10824             0x36, 400, L"Lucida Console",               // uFontFamily, uFontWeight, FaceName. We're dancing for this!
10825             15,                                         // uCursorSize
10826             0,  1, 1, 0,                                // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition
10827             50, 4, 0,                                   // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup
10828 
10829            {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,  // Palette
10830             0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF}
10831             };
10832 
10833 $       _TX_CHECKED (dataList->AddDataBlock (&props));
10834 
10835 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file));
10836 $       if (!file) _TX_FAIL;
10837 
10838 $       wchar_t wName[MAX_PATH] = L"";
10839 $       MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName));
10840 
10841 $       _TX_CHECKED (file->Save (wName, true));
10842         }
10843 
10844 $   _TX_CATCH
10845 $   _TX_FINALLY
10846 
10847     if (file)         {$ file     ->Release(); }
10848     if (dataList)     {$ dataList ->Release(); }
10849     if (shellLink)    {$ shellLink->Release(); }
10850 
10851     if (init == S_OK) {$ Win32::CoUninitialize(); }
10852 
10853 $   return _TX_OK;
10854     _TX_ENDTRY
10855 
10856     #else
10857 
10858     (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex;
10859     (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg;
10860 
10861 $   return false;
10862 
10863     #endif
10864     }
10865 
10866 #endif // TX_COMPILED
10867 
10868 //}
10869 //-----------------------------------------------------------------------------------------------------------------
10870 
10872 //}
10873 //=================================================================================================================
10874 
10875 //=================================================================================================================
10876 //{          Memory DC functions                 (_txBuffer...)
10878 //=================================================================================================================
10880 
10881 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10882 
10883 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
10884     {
10885 $1  txAutoLock _lock;
10886 
10887 $   HDC wndDC = GetDC (wnd);
10888 $   if (!wndDC) return NULL;
10889 
10890 $   POINT sz = { 1, 1 };
10891 $   if (size) sz = *size;
10892 
10893 $   if (!size && wnd)
10894         {
10895 $       RECT r = {};
10896 $       GetClientRect (wnd, &r) asserted;
10897 
10898 $       sz.x = r.right  - r.left;
10899 $       sz.y = r.bottom - r.top;
10900         }
10901 
10902 $   if (bitmap)
10903         {
10904 $       BITMAP bmap = {};
10905 $       Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted;
10906 
10907 $       sz.x = bmap.bmWidth;
10908 $       sz.y = bmap.bmHeight;
10909         }
10910 
10911 $   RGBQUAD* buf = NULL;
10912 $   if (!pixels) pixels = &buf;
10913 
10914 $   HDC dc = Win32::CreateCompatibleDC (wndDC);
10915 $   if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed");
10916 
10917     #ifndef _TX_DIB_FIX
10918     #define _TX_DIB_FIX
10919     #endif
10920 
10921 $   BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }};
10922 
10923 $   HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0);
10924 $   if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed");
10925 
10926 $   Win32::SelectObject (dc, bmap) asserted;
10927 
10928 $   if (!bitmap)
10929         {
10930 $       if (*pixels)
10931             {
10932 $           RGBQUAD black = { 0, 0, 0, 255 };
10933 $           for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black;  //-V108
10934             }
10935         else
10936             {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; }
10937         }
10938 
10939 $   ReleaseDC (wnd, wndDC) asserted;
10940 
10941 $   return dc;
10942     }
10943 
10944 //-----------------------------------------------------------------------------------------------------------------
10945 
10946 bool _txBuffer_Delete (HDC* dc)
10947     {
10948 $1  if (_TX_ARGUMENT_FAILED (dc)) return false;
10949 $   if (                   !*dc)  return false;
10950 $   if (_TX_HDC_FAILED     (*dc)) return false;
10951 
10952 $   if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false;
10953 
10954 $   txAutoLock _lock;
10955 
10956 $   _txBuffer_Select (Win32::GetStockObject (NULL_PEN),    *dc) asserted;
10957 $   _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH),  *dc) asserted;
10958 $   _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted;
10959 $   _txBuffer_Select (_txStockBitmap,                      *dc);
10960 
10961 $   Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted;
10962 
10963 $   Win32::DeleteDC (*dc) asserted;
10964 
10965 $   *dc = NULL;
10966 
10967 $   return true;
10968     }
10969 
10970 //-----------------------------------------------------------------------------------------------------------------
10971 
10972 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/)
10973     {
10974 $1  if (!obj)                return false;
10975 $   if (_TX_HDC_FAILED (dc)) return false;
10976 
10977 $   if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type");
10978 
10979 $   txAutoLock _lock;
10980 
10981 $   obj = Win32::SelectObject (dc, obj);
10982 $   if (obj) Win32::DeleteObject (obj);
10983 
10984 $   return obj != NULL;
10985     }
10986 
10987 #endif // TX_COMPILED
10988 
10990 //}
10991 //=================================================================================================================
10992 
10993 //=================================================================================================================
10994 //{          Diagnostics
10996 //=================================================================================================================
10998 
10999 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11000 
11001 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/,
11002                       const char* msg  /*= NULL*/, ...)
11003     {                                                                        //---/\---/\-------Это ASCII KOT!--//
11004 $1  va_list arg; va_start (arg, msg);                                        //  {  '-'  }                      //
11005 $$  const char* what = _txProcessError (file, line, func, color, msg, arg);  //  {  0 0  }     Добавь его себе  //
11006     va_end (arg);                                                            //  --> V <--  в исходник, и тебе  //
11007                                                                              //   \ \|/ /      будет, наверно,  //
11008     if (!(msg && msg[0] == '\a')) return what;                               //    \___/  приятно отлаживаться  //
11009                                                                              //---------------долгими ночами:)--//
11010 //  vvvvvvvvvvvvvvvvvv
11011     DebugBreak();   // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться.
11012 //  ^^^^^^^^^^^^^^^^^^
11013 
11014     return what;    // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7).
11015     }
11016 
11017 #endif // TX_COMPILED
11018 
11019 //-----------------------------------------------------------------------------------------------------------------
11020 //{          General runtime check hooks
11021 //-----------------------------------------------------------------------------------------------------------------
11022 
11023 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11024 
11025 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/)
11026     {
11027 $1  if (!sig && !fpe)
11028         {
11029 $       signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11030 $       signal (SIGFPE,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11031 $       signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11032 $       signal (SIGILL,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11033 $       signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11034 $       return;
11035         }
11036 
11037     txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe);
11038 
11039     #define GET_DESCR_(str, code, descr)  case (code): {$ (str) = " " #code ": " descr; break; }
11040 
11041 $   const char* sSig = "Неизвестный тип сигнала";
11042 
11043 $   switch (sig)
11044         {
11045         GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!")
11046         GET_DESCR_ (sSig, SIGILL,  "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.")
11047         GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().")
11048         GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.")
11049         GET_DESCR_ (sSig, SIGFPE,  "Грубая ошибка в вычислениях.")
11050         default:   break;  //-V2522
11051         }
11052 
11053 $   const char* sFPE = "";
11054 
11055     #if defined (_MSC_VER)
11056 
11057     // MSVC provides the FPE code as a MS extension.
11058     // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx
11059 
11060 $   if (sig == SIGFPE) switch (fpe)
11061         {
11062         GET_DESCR_ (sFPE, _FPE_INVALID,        "Результат неверен.")
11063         GET_DESCR_ (sFPE, _FPE_DENORMAL,       "Денормализация.")
11064         GET_DESCR_ (sFPE, _FPE_ZERODIVIDE,     "Деление на ноль.")
11065         GET_DESCR_ (sFPE, _FPE_OVERFLOW,       "Результат слишком большой.")
11066         GET_DESCR_ (sFPE, _FPE_UNDERFLOW,      "Результат слишком маленький.")
11067         GET_DESCR_ (sFPE, _FPE_INEXACT,        "Результат неточен.")
11068         GET_DESCR_ (sFPE, _FPE_UNEMULATED,     "Операция не поддерживается.")
11069         GET_DESCR_ (sFPE, _FPE_SQRTNEG,        "Квадратный корень из отрицательного числа.")
11070         GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW,  "Переполнение стека сопроцессора.")
11071         GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.")
11072         GET_DESCR_ (sFPE, _FPE_EXPLICITGEN,    "Явный вызов исключения.")
11073         default:   break;  //-V2522
11074         }
11075 
11076     #else
11077 $   fpe = 0;
11078     #endif
11079 
11080     #undef GET_DESCR_
11081 
11082 $   signal (sig, (void(*)(int))(uintptr_t)_txOnSignal);
11083 
11084 $   Win32::_fpreset();
11085 
11086 $   _TX_UNEXPECTED ("\a\t"
11087                     "signal (%d, 0x%02X):%s%s "
11088                     "%s%s"
11089                     "С помощью функции signal() вы можете сами обработать эту ошибку.",
11090                     sig, (unsigned) fpe, sSig, sFPE,
11091                     ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1);
11092     }
11093 
11094 //-----------------------------------------------------------------------------------------------------------------
11095 
11096 void _txOnTerminate()
11097     {
11098     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11099 
11100     // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc
11101 
11102 $1  static int terminating = 0;
11103     if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; }
11104 
11105 $   if (!*_txDumpSE)
11106         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11107 
11108 $   _TX_UNEXPECTED ("\t\a"
11109                     "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, "
11110                     "или другая фатальная ошибка C++. "
11111                     "%s"
11112                     "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, "
11113                     "разбирайтесь, в чем дело.\n\n"
11114                     "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE,
11115                     _txDumpSE + 1);
11116     }
11117 
11118 //-----------------------------------------------------------------------------------------------------------------
11119 
11120 void _txOnUnexpected()
11121     {
11122     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11123 
11124 $1  if (!*_txDumpSE)
11125         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11126 
11127 $   _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n"
11128                     "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете "
11129                     "спецификацию исключений для функций, проверьте, не нарушена ли она."
11130                     "%s"
11131                     "С помощью catch (...) в main() вы можете сами обработать эту ошибку.",
11132                     _txDumpSE + 1);
11133     }
11134 
11135 //-----------------------------------------------------------------------------------------------------------------
11136 
11137 int _txOnMatherr (_exception* exc)
11138     {
11139     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc);
11140 
11141 $1  assert (exc);
11142 
11143     const char* sType = "Неизвестный тип исключения";
11144 
11145     #if !defined (__CYGWIN__)
11146 
11147     #define GET_DESCR_(code, descr)  case (code): {$ sType = "(" #code "): " descr; break; }
11148 
11149 $   switch (exc->type)
11150         {
11151         GET_DESCR_ (_DOMAIN,    "Нарушение области определения");
11152         GET_DESCR_ (_SING,      "Сингулярность аргумента");
11153         GET_DESCR_ (_PLOSS,     "Частичная потеря значимости");
11154         GET_DESCR_ (_TLOSS,     "Полная потеря значимости");
11155         GET_DESCR_ (_OVERFLOW,  "Результат слишком большой");
11156         GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький");
11157         default:   break;  //-V2522
11158         }
11159 
11160     #undef GET_DESCR_
11161 
11162 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n"
11163                     "С помощью __setusermatherr() вы можете сами обработать эту ошибку.",
11164                     exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval);
11165     #else
11166 
11167 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType);
11168 
11169     #endif
11170 
11171     return 0;
11172     }
11173 
11174 //-----------------------------------------------------------------------------------------------------------------
11175 
11176 tx_noreturn void _txOnNewHandlerAnsi()
11177     {
11178     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11179 $1
11180 $   _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n"
11181                     "С помощью std::set_new_handler() вы можете сами обработать эту ошибку "
11182                     "и где-нибудь найти недостающую память.");
11183 
11184 $   throw std::bad_alloc();
11185     }
11186 
11187 //-----------------------------------------------------------------------------------------------------------------
11188 
11189 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code)
11190     {
11191     txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code);
11192 
11193 $1  if (code)
11194         {$ errno = code; }
11195 
11196 $   _TX_UNEXPECTED ("\a"
11197                     "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n"
11198                     "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку "
11199                     "и постараться не выходить за границы массивов.",
11200                     code, msg, (char*) ptr, ptr);
11201     }
11202 
11203 //-----------------------------------------------------------------------------------------------------------------
11204 
11205 int tx_glGetError (int setError /*= INT_MIN*/)
11206     {
11207 $1  _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError;
11208 $   return _txOGLError;
11209     }
11210 
11211 #endif // TX_COMPILED
11212 
11213 //}
11214 //-----------------------------------------------------------------------------------------------------------------
11215 
11216 //-----------------------------------------------------------------------------------------------------------------
11217 //{          MSC Runtime check hooks
11218 //-----------------------------------------------------------------------------------------------------------------
11219 
11220 #if defined (_MSC_VER)
11221 
11222 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11223 
11224 //-----------------------------------------------------------------------------------------------------------------
11225 
11226 int _txOnNewHandler (size_t size)
11227     {
11228     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size);
11229 $5
11230 $   _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n"
11231                     "С помощью _set_new_handler() вы можете сами обработать эту ошибку "
11232                     "и где-нибудь найти недостающую память.", (unsigned long long) size);
11233 
11234 $   throw std::bad_alloc();
11235     }
11236 
11237 //-----------------------------------------------------------------------------------------------------------------
11238 
11239 void _txOnSecurityError (int code, void* addr)
11240     {
11241     txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr);
11242 $5
11243 $   _TX_UNEXPECTED ("\a"
11244                     "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n"
11245                     "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку "
11246                     "и более торжественно завершить программу. Ставьте же ассерты.", code);
11247     }
11248 
11249 //-----------------------------------------------------------------------------------------------------------------
11250 
11251 void _txOnPureCall()
11252     {
11253     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11254 $5
11255 $   _TX_UNEXPECTED ("\a"
11256                     "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах "
11257                     "или деструкторах базовых классов - не вызывайте там таких функций.\n\n"
11258                     "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку "
11259                     "и проверить свое знание С++ :)");
11260     }
11261 
11262 //-----------------------------------------------------------------------------------------------------------------
11263 
11264 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr)
11265     {
11266     txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr);
11267 
11268 $5  assert (wExpr);
11269     assert (wFunc);
11270     assert (wFile);
11271 
11272     char expr [_TX_BUFSIZE/2] = "[Unknowm expr]",
11273          func [_TX_BUFSIZE/2] = "[Unknowm func]",
11274          file [MAX_PATH]      = "[Unknowm file]";
11275 
11276 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL);
11277 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL);
11278 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL);
11279 
11280 $$  _txError (file, (int) line, func, 0, "\a"
11281               "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n"
11282               "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr);
11283     }
11284 
11285 //-----------------------------------------------------------------------------------------------------------------
11286 
11287 #if defined (_CLANG_VER) && !defined (_MSC_VER)
11288 
11289 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info)
11290     {
11291 $5  assert (&info);
11292 
11293 $$  _txError (info.__file_, info.__line_, NULL, 0, "\a"
11294               "Оказалось неверно, что %s (%s). Не надо так.\n\n"
11295               "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_);
11296     }
11297 
11298 #endif
11299 
11300 //-----------------------------------------------------------------------------------------------------------------
11301 
11302 #pragma runtime_checks ("", off)
11303 
11304 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...)
11305     {
11306     txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format);
11307 
11308 $5  static long running = 0;
11309 $   while (InterlockedExchange (&running, 1)) Sleep (0);
11310 
11311 $   assert (format);
11312 
11313     // Disable all RTC failures
11314 
11315 $   int nErrors = _RTC_NumErrors();
11316 $   int* errors = NULL;
11317 $   try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;}  //-V104
11318 
11319 $   int err = 0;
11320 $   for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE);  //-V108
11321 
11322 $   char text [_TX_BUFSIZE] = "";
11323 
11324 $   va_list arg; va_start (arg, format);
11325 $   _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg);                  // Get message from the vararg list
11326 $   auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/);  // Get the RTC error number
11327 $   va_end (arg);
11328 
11329 $   const char* sType = "type";
11330 
11331 $   switch (type)
11332        {
11333        case _CRT_ERROR:  $ sType = "ошибка";            break;
11334        case _CRT_ASSERT: $ sType = "логическая ошибка"; break;
11335        case _CRT_WARN:   $ sType = "возможная ошибка";  break;
11336        default:          $                              break;
11337        }
11338 
11339 $   const char* sError = _RTC_GetErrDesc (error);
11340 
11341 $$  _txError (file, line, NULL, 0, "\a"
11342               "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module);
11343 
11344     // The code below will be never executed until the error above will stay fatal:
11345 
11346     // Restore the RTC error types
11347 
11348     #if defined (_MSC_VER)
11349     #pragma warning (push)
11350     #pragma warning (disable: 6385)  // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11351     #endif
11352 
11353 $   for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR));  //-V108
11354 
11355     #if defined (_MSC_VER)
11356     #pragma warning (pop)            // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11357     #endif
11358 
11359 $   InterlockedExchange (&running, 0);
11360 $   return 1;
11361     }
11362 
11363 #pragma runtime_checks ("", restore)
11364 
11365 //-----------------------------------------------------------------------------------------------------------------
11366 
11367 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line)
11368     {
11369     #if (_TX_ALLOW_TRACE +0 >= 4)
11370 
11371     static _tx_thread int recursive = 0;
11372     if (recursive) return true;
11373     recursive++;
11374 
11375     #if (_TX_ALLOW_TRACE +0 <= 10)
11376     if (!size) return true;
11377     #endif
11378 
11379     #define GET_DESCR_(str, type)  case (type): { str = #type; break; }
11380 
11381     const char* sType = "Unknown type";
11382     const char* sUse  = "Unknown use";
11383 
11384     switch (_BLOCK_TYPE (type))
11385         {
11386         GET_DESCR_ (sType, _HOOK_ALLOC);
11387         GET_DESCR_ (sType, _HOOK_REALLOC);
11388         GET_DESCR_ (sType, _HOOK_FREE);
11389         default:   break;
11390         }
11391 
11392     switch (use)
11393         {
11394         GET_DESCR_ (sUse,  _NORMAL_BLOCK);
11395         GET_DESCR_ (sUse,  _CRT_BLOCK);
11396         GET_DESCR_ (sUse,  _CLIENT_BLOCK);
11397         GET_DESCR_ (sUse,  _FREE_BLOCK);
11398         GET_DESCR_ (sUse,  _IGNORE_BLOCK);
11399         default:   break;
11400         }
11401 
11402     #undef  GET_DESCR_
11403 
11404     _txTrace ((const char*) file, line, NULL, "%*s"
11405               "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)",
11406               2 * _txLoc::Cur.inTX, "",
11407               type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request);
11408 
11409     recursive--;
11410 
11411     #else
11412 
11413     UNREFERENCED_PARAMETER (type);
11414     UNREFERENCED_PARAMETER (data);
11415     UNREFERENCED_PARAMETER (size);
11416     UNREFERENCED_PARAMETER (use);
11417     UNREFERENCED_PARAMETER (request);
11418     UNREFERENCED_PARAMETER (file);
11419     UNREFERENCED_PARAMETER (line);
11420 
11421     #endif
11422 
11423     return true;  //-V601
11424     }
11425 
11426 //-----------------------------------------------------------------------------------------------------------------
11427 
11428 #endif // TX_COMPILED
11429 
11430 #endif
11431 
11432 //}
11433 //-----------------------------------------------------------------------------------------------------------------
11434 
11435 //-----------------------------------------------------------------------------------------------------------------
11436 //{          SEH staff
11437 //-----------------------------------------------------------------------------------------------------------------
11438 
11439 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11440 
11441 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc)
11442     {
11443     if (!_txProcessSystemWarnings)
11444         {
11445         DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11446         void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11447 
11448         if (code != DBG_PRINTEXCEPTION_C &&
11449             code != DBG_PRINTEXCEPTION_WIDE_C)
11450             {
11451             txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n",
11452                                  _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings);
11453             }
11454 
11455         return (!(exc && exc->ExceptionRecord && exc->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))?
11456                 EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER;
11457         }
11458     else
11459         {
11460         int inTX = _txLoc::Cur.inTX++;
11461 
11462         long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler");
11463 
11464         _txLoc::Cur.inTX = inTX;
11465         return ret;
11466         }
11467     }
11468 
11469 //-----------------------------------------------------------------------------------------------------------------
11470 
11471 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc)
11472     {
11473     int inTX = _txLoc::Cur.inTX++;
11474 
11475     long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter");
11476 
11477     if (_txPrevUEFilter)
11478         {
11479         if (_txSetJmp())
11480             {
11481             int inTX2 = _txLoc::Cur.inTX++;
11482 
11483             ret = _txPrevUEFilter (exc);
11484 
11485             _txLoc::Cur.inTX = inTX2;
11486             }
11487         else
11488             {
11489 $6          _txClearJmp();
11490 
11491             _TX_UNEXPECTED ("\t\a" "%s"
11492                             "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n"
11493                             "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE,
11494                             _txDumpSE + 1);
11495             }
11496         }
11497 
11498     _txLoc::Cur.inTX = inTX;
11499     return ret;
11500     }
11501 
11502 //-----------------------------------------------------------------------------------------------------------------
11503 
11504 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter)
11505     {
11506 $6  _txPrevUEFilter = filter;
11507 
11508     return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter;
11509     }
11510 
11511 //-----------------------------------------------------------------------------------------------------------------
11512 
11513 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[])
11514     {
11515     assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; }  //-V547
11516 
11517     assert (exc->ExceptionRecord);
11518 
11519     assert (func);
11520     assert (func[3] == 'V' || func[3] == 'U');
11521 
11522     bool  unhExc = (func[3] == 'U');
11523     DWORD code   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11524     void* addr   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11525 
11526     if (code == DBG_PRINTEXCEPTION_C                 ||
11527         code == DBG_PRINTEXCEPTION_WIDE_C            ||
11528         code == DBG_THREAD_NAME                      ||
11529 
11530         #ifdef  _TX_SKIP_EXCEPTION
11531         code == _TX_SKIP_EXCEPTION                   ||
11532         #endif
11533 
11534        (code == RPC_S_SERVER_UNAVAILABLE && !unhExc) ||
11535        (code == RPC_S_CALL_CANCELLED     && !unhExc) ||
11536        (code == EXCEPTION_BREAKPOINT     && IsDebuggerPresent()))
11537         {
11538         return EXCEPTION_CONTINUE_SEARCH;
11539         }
11540 
11541     ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr;
11542     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11543 
11544               dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr;
11545     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11546 
11547     _txSENumber = _txSENumber + 1;
11548     if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1;
11549 
11550     OutputDebugString ("\n");
11551     txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n",
11552                          _TX_VERSION, _txSENumber, func, (unsigned long) code, addr);
11553 
11554 $6  if (*(unsigned long long*) _txDumpExceptionObjJmp)
11555         {
11556 $       longjmp (_txDumpExceptionObjJmp, 1);  //-V2512
11557         }
11558 
11559     tx_fpreset();
11560 
11561     #if defined (_MSC_VER)
11562     if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); }
11563     #endif
11564 
11565 $   bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord));  //-V560
11566 
11567 $   if (primaryException && exc)  //-V560
11568         {
11569 $       unsigned err = GetLastError();
11570 
11571 $       const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc);
11572 
11573 $       _txDumpExceptionSEH (_txDumpSE,  (intptr_t) sizeof (_txDumpSE)  - 1, exc->ExceptionRecord, func);
11574 $       _tx_snprintf_s      (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace);
11575 
11576 $       static _tx_thread DWORD prevCode = 0;
11577 $       static _tx_thread void* prevAddr = NULL;
11578 
11579 $       if (code != prevCode && addr != prevAddr &&
11580             !strstr (_txDumpSE, "Объект исключения C++:"))
11581             {
11582 $           SetLastError (err);
11583 $           _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1);
11584 
11585 $           prevCode = code;
11586 $           prevAddr = addr;
11587             }
11588 
11589 $       SetLastError (err);
11590         }
11591 
11592 $   if (_txDumpSE[0]     == '\a'                   ||
11593         _txSENumber      >= _TX_EXCEPTIONS_LIMIT+0 ||
11594         _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
11595         {
11596 $       _TX_UNEXPECTED ("\a\t" "%s"
11597                         "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.",
11598                         _txDumpSE + 1);
11599         }
11600 
11601 $       return (!(exc && exc->ExceptionRecord && exc->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))?
11602                 EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER;
11603     }
11604 
11605 //-----------------------------------------------------------------------------------------------------------------
11606 
11607 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[])  //-V2008
11608     {
11609 $6  assert (what);
11610 $   assert (size >= 0);                     //-V547
11611     assert (exc); if (!exc) {$ return 0; }  //-V547
11612 $   assert (func);
11613 
11614 $   unsigned         code   = exc->ExceptionCode;
11615 $   void*            addr   = exc->ExceptionAddress;
11616 $   unsigned         params = exc->NumberParameters;
11617 $   const ULONG_PTR* info   = exc->ExceptionInformation;
11618 $   void*            object = (params >= 2)? (void*) info[1] : NULL;
11619 
11620 $   char* s = what;
11621 
11622     #define PRINT_(...)  s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__)
11623 
11624 $   const char* sCode  = NULL;
11625 $   const char* sDescr = NULL;
11626 
11627     #define GET_DESCR_(code, descr)  case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; }
11628 
11629 $   switch (code)
11630         {
11631         GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION,         " "  "Нарушение доступа к памяти.")
11632         GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION,      " "  "Недопустимая операция.")
11633         GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION,         " "  "Привилегированная операция.")
11634         GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED,    "\a" "Выход за границы массива. Ставьте ассерты!")
11635         GET_DESCR_ (EXCEPTION_BREAKPOINT,               "\a" "Достигнута точка останова. Удачи в отладке!")
11636         GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT,    "\a" "Нарушение выравнивания данных.")
11637         GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION,      "\a" "Обработчик исключения возвратил неверное значение.")
11638         GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR,            "\a" "Невозможно загрузить нужную страницу памяти.")
11639         GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.")
11640         GET_DESCR_ (EXCEPTION_SINGLE_STEP,              "\a" "Выполнена инструкция машинного кода. Одна штука.")
11641         GET_DESCR_ (EXCEPTION_STACK_OVERFLOW,           "\a" "Ю-ху! Переполнение стека!")
11642         GET_DESCR_ (EXCEPTION_GUARD_PAGE,               "\a" "Попытка доступа к защищенной странице памяти.")
11643         GET_DESCR_ (EXCEPTION_INVALID_HANDLE,           "\a" "Неверный или уже закрытый дескриптор.")
11644         GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK,           "\a" "Возможно, взаимная блокировка ресурсов.")
11645 
11646         GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK,          "\a" "Ошибка стека при операции с плавающей точкой.")
11647         GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND,     " "  "Денормализация числа с плавающей точкой.")
11648         GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO,       " "  "Деление на ноль при операции с плавающей точкой.")
11649         GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT,       " "  "Неточный результат при операции с плавающей точкой.")
11650         GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION,    " "  "Недопустимая операция с плавающей точкой.")
11651         GET_DESCR_ (EXCEPTION_FLT_OVERFLOW,             " "  "Переполнение при операции с плавающей точкой.")
11652         GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW,            " "  "Потеря значимости при операции с плавающей точкой.")
11653         GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS,       " "  "Множественные ошибки с плавающей точкой.")
11654 
11655         GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO,       "\a" "Целочисленное деление на ноль.")
11656         GET_DESCR_ (EXCEPTION_INT_OVERFLOW,             "\a" "Переполнение при целочисленной операции.")
11657 
11658         GET_DESCR_ (EXCEPTION_CLR_FAILURE,              "\a" "Сбой среды исполнения (CLR).")
11659         GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN,        "\a" "Переполнение стекового буфера!")
11660         GET_DESCR_ (STATUS_ASSERTION_FAILURE,           "\a" "Сработал assert. На этот раз из ядра.")
11661         GET_DESCR_ (STATUS_WX86_BREAKPOINT,             "\a" "Точка останова подсистемы эмуляции x86.")
11662         GET_DESCR_ (RPC_S_UNKNOWN_IF,                   "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).")
11663         GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE,           "\a" "Сервер удаленного вызова процедур (RPC) недоступен.")
11664         GET_DESCR_ (DBG_TERMINATE_THREAD,               "\a" "Отладчик завершил поток сознания.")
11665         GET_DESCR_ (DBG_TERMINATE_PROCESS,              "\a" "Отладчик завершил процесс.")
11666         GET_DESCR_ (DBG_CONTROL_C,                      "\a" "Отладчик получил сигнал прерывания Control+C.")
11667         GET_DESCR_ (DBG_CONTROL_BREAK,                  "\a" "Отладчик получил сигнал прерывания Control+Break.")
11668         GET_DESCR_ (DBG_THREAD_NAME,                    " "  "Отладчик получил указание дать потоку имя.")
11669         GET_DESCR_ (DBG_PRINTEXCEPTION_C,               " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).")
11670         GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C,          " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).")
11671 
11672         GET_DESCR_ (EXCEPTION_CPP_MSC,                  " "  "Исключение MSC С++, вызванное оператором throw.")
11673         GET_DESCR_ (EXCEPTION_CPP_GCC,                  " "  "Исключение GNU С++, вызванное оператором throw.")
11674         GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND,           " "  "Исключение GNU С++, вызванное во время раскрутки стека (rethrow?).")
11675         GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED,           " "  "Исключение GNU С++, вызванное нарушением магии.")
11676         GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER,      "\a" "Это скомпилилось под Билдер? O_O")
11677         GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI,       "\a" "Это же С++. Как это вышло?")
11678 
11679         default: $ break;
11680         }
11681 
11682     #undef GET_DESCR_
11683 
11684 $   if (sDescr)
11685         {
11686 $       PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode);
11687         }
11688     else
11689         {
11690 $       PRINT_ ("\a#%ld: ", _txSENumber);
11691 $       s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11692                             GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11693                             s, (DWORD) (size - (s-what)), NULL) - 2;  //-V202
11694 $       PRINT_ ("\r\r");
11695         }
11696 
11697 $   PRINT_ (" (0x%X) при выполнении кода по адресу", code);
11698 $   PRINT_ ((addr? " 0x%p" : " NULL"), addr);
11699 
11700 $   Win32::SYMBOL_INFO*     sym  = NULL;
11701 $   Win32::IMAGEHLP_LINE64* line = NULL;
11702 
11703     if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); }
11704 
11705 $   if (sym  &&                   *sym->Name)      PRINT_ (" в функции %s()", sym->Name);
11706 $   if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber);
11707 
11708 $   if (code == EXCEPTION_ACCESS_VIOLATION ||
11709         code == EXCEPTION_IN_PAGE_ERROR)
11710         {
11711 $       PRINT_ (". Попытка ");
11712 
11713 $       unsigned long op = 0xBADC0DE;
11714 $       const char*  sOp = "(действие не указано)";
11715 
11716 $       if (params >= 1)
11717             {
11718 $           switch (op = (unsigned long) info[0])  //-V202
11719                 {
11720                 case 0:  $ sOp = "прочесть данные";          break;
11721                 case 1:  $ sOp = "записать данные";          break;
11722                 case 8:  $ sOp = "исполнить код";            break;
11723                 default: $ sOp = "совершить операцию 0x%lX"; break;
11724                 }
11725             }
11726 
11727 $       PRINT_ (sOp, op);
11728 
11729 $       if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); }   //-V1048
11730         else             {$ PRINT_ (" (адрес не указан)"); }
11731 
11732 $       if (code == EXCEPTION_IN_PAGE_ERROR)
11733             {
11734 $           PRINT_ (", ошибка ввода-вывода:");
11735 
11736 $           if (params >= 3)
11737                 {
11738 $               unsigned long ntstatus = (unsigned long) info[2];                                 //-V202
11739 
11740 $               PRINT_ (" 0x%lX (", ntstatus);
11741 
11742 $               s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11743                                     GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11744                                     s, (DWORD) (size - (s-what)), NULL) - 2;                      //-V202
11745 $               PRINT_ (")");
11746                 }
11747             else
11748                 {$ PRINT_ (" (не указана)"); }
11749             }
11750         }
11751 
11752 $   HMODULE module = NULL;
11753 $   _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module));
11754 
11755 $   if (module)
11756         {
11757 $       static char sModule [MAX_PATH] = "";
11758 $       int ok = GetModuleFileName (module, sModule, sizeof (sModule));
11759 
11760 $       char* ext = (ok? strrchr (sModule, '.') : NULL);
11761 $       if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule));
11762 
11763         if (ok) {$ PRINT_ (" в модуле %s",  sModule); }
11764         else    {$ PRINT_ (" в модуле 0x%p", (void*) module); }
11765         }
11766 
11767 $   PRINT_ (".");
11768 
11769 $   if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0)
11770         {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).",        _TX_EXCEPTIONS_LIMIT+0); }
11771 
11772 $   if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
11773         {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); }
11774 
11775 $   PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func);
11776 
11777 $   if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
11778         {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); }
11779 
11780 $   if (exc->ExceptionRecord)
11781         {
11782 $       PRINT_ ("\n\n" "Причина:" "\n\n");
11783 $       s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func);
11784         }
11785 
11786 $   if (code == EXCEPTION_CPP_GCC        ||
11787         code == EXCEPTION_CPP_GCC_UNWIND ||
11788         code == EXCEPTION_CPP_GCC_FORCED ||
11789         code == EXCEPTION_CPP_MSC)
11790         {
11791 $       s += _txDumpExceptionCPP (s,    size - (s-what), code, params, info);
11792         }
11793 
11794     #undef PRINT_
11795 
11796 $   while (s > what && s[-1] == '\n') s--;
11797 $   if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n");
11798 
11799 $   return s - what;
11800     }
11801 
11802 //-----------------------------------------------------------------------------------------------------------------
11803 
11804 intptr_t _txDumpExceptionCPP (char what[], intptr_t size,
11805                               unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/)
11806     {
11807 $6  assert (what);
11808 $   assert (size >= 0);  //-V547
11809 
11810 $   char* s = what;
11811 
11812 $   switch (code)
11813         {
11814         #if defined (_GCC_VER)
11815 
11816         case EXCEPTION_CPP_GCC:
11817         case EXCEPTION_CPP_GCC_UNWIND:
11818         case EXCEPTION_CPP_GCC_FORCED:
11819             {
11820             // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp
11821             //      [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below
11822             //      [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below
11823             //      [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below
11824             //      and figure above near ABI::__cxa_exception definition in this file
11825 
11826 $           const std::type_info* type   = NULL;
11827 $           void*                 object = NULL;
11828 
11829 $           if (params >= 1)
11830                 {
11831 $               _Unwind_Exception*    unwind_exception = (_Unwind_Exception*) info[0];
11832 $               ABI::__cxa_exception* cxa_exception    = (ABI::__cxa_exception*) (unwind_exception + 1) - 1;
11833 
11834 $               type   = cxa_exception->exceptionType;
11835 $               object = cxa_exception + 1;
11836                 }
11837 
11838 $           s += _txDumpExceptionObj (s, size - (s-what), object, 0, type);
11839             }
11840 $           break;
11841 
11842         case 0:  // Not called within SEH chain
11843             {
11844             // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc
11845             //       [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc
11846 
11847             using namespace abi;
11848 
11849 $           ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions;
11850 
11851 $           if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1))  // Dependent exception, case B, see pic above
11852                 {
11853 $               cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1;
11854                 }
11855 
11856 $           if (cxa_exception)
11857                 {
11858 $               verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type());
11859 
11860 $               s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType);
11861                 }
11862             }
11863 $           break;
11864 
11865         #elif defined (_MSC_VER)
11866 
11867         case EXCEPTION_CPP_MSC:
11868             {
11869             // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
11870             //     [2] http://www.openrce.org/articles/full_view/21
11871             //     [3] http://www.openrce.org/articles/full_view/23
11872             //     [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf
11873 
11874 $           const std::type_info* type   = NULL;
11875 $           void*                 object = (params >= 2)? (void*) info[1] : NULL;
11876 $           size_t                szObj  = 0;
11877 
11878 $           if (params >= 3 &&
11879                (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||
11880                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||
11881                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 ||
11882                 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1))
11883                 {
11884 $               auto throwInfo = (const Win32::ThrowInfo*) info[2];
11885 
11886 $               if (throwInfo && throwInfo->pCatchableTypeArray)
11887                     {
11888 $                   HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL;  //-V112
11889 
11890                     #define RVA_(type, addr)  ( (type) ((uintptr_t) module + (uintptr_t) (addr)) )
11891 
11892 $                   const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray);
11893 $                   const Win32::CatchableType*      cType  = RVA_(const Win32::CatchableType*,      cArray->arrayOfCatchableTypes[0]);
11894 
11895 $                   type  = RVA_(const std::type_info*, cType->pType);
11896 $                   szObj = cType->sizeOrOffset;  //-V101
11897 
11898                     #undef  RVA_
11899                     }
11900                 }
11901 
11902 $           s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type);
11903             }
11904             break;
11905 
11906         case 0:  // Not called within SEH chain
11907 
11908             // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC:
11909             //
11910             // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception.
11911             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp
11912             //
11913             // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception.
11914             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp
11915             // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp
11916             // and http://msdn.microsoft.com/en-us/library/ff730818.aspx.
11917             //
11918             // So _txDumpSE information should have been recorded during previous call. Now do nothing.
11919 
11920 $           break;
11921 
11922         #endif
11923 
11924         default:
11925 $           txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code);
11926 $           break;
11927         }
11928 
11929 $   while (s > what && s[-1] == '\n') s--;
11930 $   if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n");
11931 
11932 $   return (s - what);
11933     }
11934 
11935 //-----------------------------------------------------------------------------------------------------------------
11936 
11937 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type)  //-V2008
11938     {
11939 $6  assert (what);
11940 $   assert (size > 0);  //-V547
11941 
11942 $   static char*  s     = NULL; s     = what;
11943 $   static size_t szObj = 0;    szObj = sizeObj;
11944 
11945     #define PRINT_(...)  s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__)
11946 
11947 $   PRINT_ ("\n\n" "Объект исключения C++:");
11948 
11949 $   const char* mangledName = (type)? type->name() : NULL;
11950 
11951 $   char* typeName = NULL;
11952 $   int err = 1;
11953 
11954     #if defined (_GCC_VER)
11955 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err);
11956     #endif
11957 
11958 $   const char* name = (!err && typeName)? typeName : mangledName;  //-V560
11959 
11960 $   if (name &&
11961        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >")           == 0 ||
11962         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >")                   == 0))
11963         {$ name = "std::string"; }
11964 
11965 $   if (name &&
11966        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *")         == 0 ||
11967         strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 ||
11968         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*")                  == 0))
11969         {$ name = "std::string*"; }
11970 
11971     if (name) {$ PRINT_ (" %s", name); }
11972 
11973     #if defined (_GCC_VER)
11974 $   free (typeName);
11975     #endif
11976 
11977 $   err = 0;
11978 $   if (mangledName)
11979         {
11980         if (_txSetJmp())
11981             {
11982             #define PRINT_VAL_(fmt, typ, ...)                                                                          \
11983                 else if (*type == typeid (      typ       )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \
11984                 else if (*type == typeid (const typ       )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \
11985                 else if (*type == typeid (      typ*      )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
11986                 else if (*type == typeid (const typ*      )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
11987                 else if (*type == typeid (      typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
11988                 else if (*type == typeid (const typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); }
11989             #define NO_
11990 
11991             if (false) ;
11992             PRINT_VAL_ ("%s", char*, NO_)   PRINT_VAL_ ('%c', unsigned char,  NO_)   PRINT_VAL_ (%s,   bool, ? "true" : "false")  //-V206 //-V517
11993             PRINT_VAL_ ( %d,  int,   NO_)   PRINT_VAL_ ( %u,  unsigned int,   NO_)   PRINT_VAL_ (%g,   float,  NO_)               //-V206
11994             PRINT_VAL_ ( %hd, short, NO_)   PRINT_VAL_ ( %hu, unsigned short, NO_)   PRINT_VAL_ (%g,   double, NO_)               //-V206
11995             PRINT_VAL_ ( %ld, long,  NO_)   PRINT_VAL_ ( %lu, unsigned long,  NO_)   PRINT_VAL_ ('%c', char,   NO_)               //-V206
11996             PRINT_VAL_ ("%s", std::string, .c_str())                                                                              //-V206
11997 
11998             else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object))
11999                 {
12000 $               PRINT_ (", what(): \"%s\"", e->what());
12001                 }
12002             else
12003                 {$ err = 1; }
12004             }
12005         else
12006             {$ err = 2; }
12007         }
12008 
12009 $   _txClearJmp();
12010 
12011 $   if (err && object && szObj)
12012         {
12013 $       const unsigned char* buf = (const unsigned char*) object;
12014 
12015 $       if (szObj >= 64) szObj = 64;
12016 
12017 $       PRINT_ (", дамп: [");
12018 $       for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' );
12019 
12020 $       PRINT_ ("]");
12021 $       for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]);
12022 
12023 $       err = 0;
12024         }
12025 
12026 $   if (err)
12027         {$ PRINT_ (" = ??"); }
12028 
12029 $   PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object);  //-V560
12030 
12031     #undef PRINT_VAL_
12032     #undef PRINT_
12033     #undef NO_
12034 
12035 $   return s - what;
12036     }
12037 
12038 #endif // TX_COMPILED
12039 
12040 //}
12041 //-----------------------------------------------------------------------------------------------------------------
12042 
12043 //-----------------------------------------------------------------------------------------------------------------
12044 //{          Stack trace and debug info access
12045 //-----------------------------------------------------------------------------------------------------------------
12046 
12047 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12048 
12049 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/,
12050                                       CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/,
12051                                       HANDLE thread /*= GetCurrentThread()*/)
12052     {
12053 $6  const int maxFrames = 62;  // MS says: < 63
12054 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12055 
12056     if (framesToSkip == -1) {$ return trace; }
12057 
12058 $   static void* capture [maxFrames] = {};
12059 $   int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread);
12060 
12061 $   memset (trace, 0, sizeof (trace));
12062 $   char* s = trace;
12063 
12064     #define PRINT_(...)  s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__)
12065 
12066 $   for (int i = 0, n = 0; i < frames; i++)  //-V2530
12067         {
12068 $       void* addr = capture[i];
12069 
12070 $       Win32::SYMBOL_INFO*     sym    = NULL;
12071 $       Win32::IMAGEHLP_LINE64* line   = NULL;
12072 $       const char*             module = NULL;
12073 $       const char*             source = NULL;
12074 $       bool                    inTX   = false;
12075 
12076         if (addr)                {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module);          }
12077         if (readSource && !inTX) {$        _txSymGetFromAddr ((void*) 1,        NULL, NULL,  NULL, &source, 2); }  //-V566
12078 
12079 $       int nl = 0;
12080 $       while (s > trace && s[-1] == '\n') { s--; nl++; }
12081 
12082         #if !defined (_TX_FULL_STACKTRACE)
12083 
12084 $       if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber))))
12085             {$ continue; }
12086 
12087         #endif
12088 
12089 $       PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr);
12090 $       n++;
12091 
12092         if (addr ==                    0)          {$ PRINT_ (" [Неверный фрейм]");        break; }
12093         if (addr == (void*)           -1)          {$ PRINT_ (" [Странный фрейм]");        break; }
12094         if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; }  //-V566
12095 
12096         if (module)                                {$ PRINT_ (" in %s%s",     module, ((sym && *sym->Name)? ": " : "")); }
12097         if (sym  && *sym->Name)                    {$ PRINT_ ("%s()",         sym->Name);                                }
12098         if (line && line->FileName)                {$ PRINT_ (" at %s",       line->FileName);                           }
12099         if (line && line->LineNumber)              {$ PRINT_ (" (%d)",  (int) line->LineNumber);                         }
12100         if (source)                                {$ PRINT_ (":\n\n" "%s\n", source);                                   }
12101 
12102         if (sym && strcmp (sym->Name , "main") == 0) {$ break; }
12103         }
12104 
12105     #if defined (_MSC_VER)
12106     #pragma warning (push)
12107     #pragma warning (disable: 28199)  // Using possibly uninitialized memory '*s'
12108     #endif
12109 
12110 $   while (s > trace && s[-1] == '\n') s--;
12111 $   *s = 0;
12112 
12113     #if defined (_MSC_VER)
12114     #pragma warning (pop)             // Using possibly uninitialized memory '*s'
12115     #endif
12116 
12117     #undef PRINT_
12118 
12119 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12120 
12121 $   _txCreateMiniDump (exc);
12122 
12123 $   return trace;
12124     }
12125 
12126 //-----------------------------------------------------------------------------------------------------------------
12127 
12128 // Stack WALKING if the program is DEAD. Dead, Carl!
12129 
12130 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/,
12131                   HANDLE thread /* = GetCurrentThread()*/)
12132     {
12133 $6  namespace MinGW = Win32::MinGW;
12134 
12135 $   assert (capture);
12136 
12137 $   HANDLE process  = GetCurrentProcess();
12138 $   bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId());
12139 
12140 $   CONTEXT ctx = {};
12141 $   ctx.ContextFlags |= CONTEXT_FULL;
12142 
12143 $   int isWow64 = 0;
12144 $   if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64);
12145     else {$ return -1; }
12146 
12147 $   if (context)
12148         {
12149 $       ctx = *context;
12150         }
12151     else
12152         {
12153 $       if (thisThread)
12154             {
12155 $           _TX_CALLv (Win32::RtlCaptureContext, (&ctx));
12156             }
12157         else
12158             {
12159 $           SuspendThread (thread);  //-V720
12160 
12161 $           ctx.ContextFlags = CONTEXT_ALL;
12162 $           bool ok = !!GetThreadContext (thread, &ctx);
12163 
12164 $           if (!ok)
12165                 {
12166 $               ResumeThread (thread);
12167 $               return -1;
12168                 }
12169             }
12170         }
12171 
12172 $   Win32::STACKFRAME64 frame = {};
12173 $   frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat;
12174 
12175 $   int cpu = 0;
12176 
12177     #if defined (_WIN64)
12178 
12179 $   if (isWow64)
12180         {
12181 $       Win32::WOW64_CONTEXT wow64ctx = {};
12182 $       wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL;
12183 
12184 $       if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx)))  // This call fails in WINE,
12185             {                                                               // while EXIT_PROCESS_DEBUG_EVENT
12186             if (!thisThread) {$ ResumeThread (thread); }
12187 $           return 0;
12188             }
12189 
12190 $       cpu = IMAGE_FILE_MACHINE_I386;
12191 
12192 $       frame.AddrPC   .Offset = wow64ctx.Eip;
12193 $       frame.AddrStack.Offset = wow64ctx.Esp;
12194 $       frame.AddrFrame.Offset = wow64ctx.Ebp;
12195         }
12196     else
12197         {
12198 $       cpu = IMAGE_FILE_MACHINE_AMD64;
12199 
12200 $       frame.AddrPC   .Offset = ctx.Rip;
12201 $       frame.AddrStack.Offset = ctx.Rbp;
12202 $       frame.AddrFrame.Offset = ctx.Rsp;
12203         }
12204 
12205     #else
12206 
12207         {
12208 $       cpu = IMAGE_FILE_MACHINE_I386;
12209 
12210 $       frame.AddrPC   .Offset = ctx.Eip;
12211 $       frame.AddrStack.Offset = ctx.Ebp;
12212 $       frame.AddrFrame.Offset = ctx.Esp;
12213         }
12214 
12215     #endif
12216 
12217 $   assert (cpu);
12218 
12219     if (_txSetJmp())
12220         {
12221 $       _txSymGetFromAddr ((void*) 1);  //-V566
12222         }
12223 $   _txClearJmp();
12224 
12225 $   int  frames = -1;
12226 
12227 $   for (frames = -framesToSkip; frames < (int) szCapture; frames++)  //-V202 //-V2530
12228         {
12229 $       DWORD64 prev = frame.AddrStack.Offset;
12230 
12231         // Я злой и страшный серый walk. Я в поросятах знаю talk.
12232 
12233         if (!_txSetJmp()) {$ break; }
12234 
12235 #if   defined (_GCC_VER)
12236 
12237         if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12238                                             MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; }
12239 #elif defined (_MSC_VER)
12240 
12241 $       if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12242                                             Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; }
12243 #else
12244         #error _GCC_VER / _MSC_VER not defined
12245 #endif
12246         if (frames < 0) {$ continue; }
12247 
12248 $       void* addr = (void*) frame.AddrPC.Offset;
12249 
12250         if (frame.AddrFrame.Offset == 0)   {$ addr =          0; }  // Bad frame
12251         if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; }  // Strange frame
12252 
12253 $       assert (0 <= frames && frames < (int) szCapture);  //-V202
12254 
12255 $       capture[frames] = addr;                            //-V108
12256         }
12257 
12258 $   _txClearJmp();
12259 
12260     if (!thisThread) {$ ResumeThread (thread); }
12261 
12262 $   return frames;
12263     }
12264 
12265 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl
12266 
12267 //-----------------------------------------------------------------------------------------------------------------
12268 
12269 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/,
12270                         Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/,
12271                         const char** source /*= NULL*/, int context /*= 2*/)
12272     {
12273 $7  static HANDLE process = NULL;
12274 
12275 #if   defined (_GCC_VER)
12276     #define LIB_  Win32::MinGW
12277 
12278 #elif defined (_MSC_VER)
12279     #define LIB_  Win32
12280 
12281 #else
12282     #error _GCC_VER / _MSC_VER not defined
12283 #endif
12284 
12285 $   if (!process && addr)
12286         {
12287 $       process = GetCurrentProcess();
12288 
12289 $       DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES |
12290                         SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS;
12291 
12292 $        _TX_CALL (LIB_::SymSetOptions, (options));
12293 $        _TX_CALL (LIB_::SymInitialize, (process, NULL, true));
12294         }
12295 
12296 $   static DWORD64 mod = 0;
12297 
12298 $   if (module)
12299         {
12300 $       static char sMod [MAX_PATH] = "";
12301 $       memset (sMod, 0, sizeof (sMod));
12302 
12303 $       mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr));
12304 
12305 $       GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH);
12306 
12307 $       char* ext = strrchr (sMod, '.');
12308         if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); }
12309 
12310 $       *module = sMod;
12311         }
12312 
12313 $   static char buffer [_TX_BUFSIZE] = "";
12314 $   static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer;  //-V1032
12315 
12316 $   if (symbol)
12317         {
12318 $       memset (buffer, 0, sizeof (buffer));
12319 
12320 $       sym->MaxNameLen   = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1;
12321 $       sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO);
12322 $       unsigned long long ofs = 0;
12323 
12324 $       _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym));
12325 
12326         if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; }
12327 
12328 $       *symbol = sym;
12329         }
12330 
12331 $   static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line) };
12332 
12333 $   if (line)
12334         {
12335 $       memset (&line64, 0, sizeof (line64));
12336 
12337 $       DWORD ofs = 0;
12338 $       _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64));
12339 
12340 $       *line = &line64;
12341         }
12342 
12343 $   if (source)
12344         {
12345 $       static char buf [_TX_BUFSIZE] = "";
12346 $       memset (buf, 0, sizeof (buf));
12347 
12348 $       if (line64.FileName && line64.LineNumber)
12349             {
12350 $           _txReadSource (buf, sizeof (buf) - 1, line64.FileName,
12351                           (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber);
12352 
12353 $           *source = buf;
12354             }
12355 
12356         if (!*source || !**source) {$ *source = NULL; }
12357         }
12358 
12359 $   if (!addr && process)
12360         {
12361 $       _TX_CALL (LIB_::SymCleanup, (process));
12362 
12363 $       process = NULL;
12364         }
12365 
12366     #if (_GCC_VER == 481)
12367     #pragma GCC diagnostic push
12368     #pragma GCC system_header
12369     #endif
12370 
12371 $   if (symbol)
12372         {
12373 $       if (strstr  (sym->Name, "::TX::")                                                  ||
12374            (strncmp (sym->Name, "_tx",  3) == 0 && isupper ((unsigned char) sym->Name[3])) ||
12375            (strncmp (sym->Name,  "tx",  2) == 0 && isupper ((unsigned char) sym->Name[2])) ||
12376             strncmp (sym->Name, "_tx_", 4) == 0                                            ||  //-V112
12377             strncmp (sym->Name,  "tx_", 3) == 0)
12378             {
12379 $           return true;
12380             }
12381 
12382     #if (_GCC_VER == 481)
12383     #pragma GCC diagnostic pop
12384     #endif
12385 
12386 $       if (!line || !line64.FileName) return false;
12387 
12388 $       intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1);
12389 
12390 $       return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) &&
12391                (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\');
12392         }
12393 
12394     #undef LIB_
12395 
12396 $   return false;
12397     }
12398 
12399 //-----------------------------------------------------------------------------------------------------------------
12400 
12401 intptr_t _txReadSource (char buf[], intptr_t size, const char file[],
12402                         int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/)
12403     {
12404 $7  assert (buf);
12405 
12406     if (!file || !*file) {$ return 0; }
12407 
12408     if (linStart < 1) {$ linStart = 1;       }
12409     if (linEnd == -1) {$ linEnd   = INT_MAX; }
12410 
12411 $   FILE* f = NULL;
12412 $   fopen_s (&f, file, "r");
12413     if (!f) {$ return 0; }
12414 
12415 $   int n = 1;
12416     while (!feof (f))
12417         {
12418         if (n >= linStart) {$ break; }
12419         while (!feof (f) && fgetc (f) != '\n')
12420             ;
12421         n++;
12422         }
12423 
12424 $   char* s = buf;
12425 
12426     #define SZ_  ( size - 3 - (s - buf) )
12427 
12428 $   while (!feof (f) && SZ_ > 0)
12429         {
12430         if (n > linEnd || _txNOP (SZ_) < 0) {$ break; }
12431 
12432         if (linMark != INT_MIN)
12433             {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : "  "), n); }
12434 
12435 $       int c = 0;
12436 $       while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c;
12437         if (c == EOF) {$ s--; }
12438 
12439         if (SZ_ > 0) {$ *s++ = '\n'; }
12440 $       n++;
12441         }
12442 
12443     if (n <= linEnd && SZ_ <= 0)
12444         {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); }
12445 
12446     #undef SZ_
12447 
12448 $   fclose (f);
12449 
12450     if (s > buf && s[-1] == '\n') {$ s--; }
12451 $   *s = 0;
12452 
12453 $   return (s - buf);
12454     }
12455 
12456 //-----------------------------------------------------------------------------------------------------------------
12457 
12458 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/)
12459     {
12460 $6  const int maxFrames = 62;  // TX says too: < 63
12461 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12462 
12463     if (framesToSkip == -1) {$ return trace; }
12464 
12465 $   memset (trace, 0, sizeof (trace));
12466 $   char* s = trace;
12467 
12468     #define SZ_  ( sizeof (trace) - 1 - 3 - (s-trace) )
12469 
12470 $   const _txLoc* loc = &_txLoc::Cur;
12471 
12472     for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; }
12473 
12474 $   for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev)
12475         {
12476         if (i < 0) {$ continue; }
12477 
12478         if (loc->func || loc->file || loc->line)
12479             {
12480 $           s += _tx_snprintf_s     (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""),
12481                                      i, loc->func, loc->file, loc->line);
12482 
12483 $           if (readSource)
12484                 {
12485 $               s += _tx_snprintf_s (s, SZ_, ":\n\n");
12486 $               s += _txReadSource  (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line);
12487                 }
12488             }
12489         }
12490 
12491     #undef SZ_
12492 
12493 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12494 
12495 $   return trace;
12496     }
12497 
12498 //-----------------------------------------------------------------------------------------------------------------
12499 
12500 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/)
12501     {
12502     #if !defined (_TX_NO_MINIDUMP)
12503 
12504 $6  static char dumpName[MAX_PATH] = "";
12505     if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); }
12506 
12507 $   HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12508 
12509     if (!file || file == INVALID_HANDLE_VALUE) {$ return false; }
12510 
12511 $   Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false };
12512 $   Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory);
12513 
12514 $   bool        ok = _TX_CALL (Win32::MiniDumpWriteDump,  (GetCurrentProcess(), GetCurrentProcessId(), file, type, ((exc)? &excInfo : NULL), NULL, NULL));
12515     if (!ok) {$ ok = _TX_CALL (Win32::MiniDumpWriteDump2, (GetCurrentProcess(), GetCurrentProcessId(), file, type, ((exc)? &excInfo : NULL), NULL, NULL)); }
12516     if (!ok) {$ ok = _TX_CALL (Win32::MiniDumpWriteDump3, (GetCurrentProcess(), GetCurrentProcessId(), file, type, ((exc)? &excInfo : NULL), NULL, NULL)); }
12517 
12518 $   CloseHandle (file);
12519 
12520     if (ok) {$ return true;  }
12521     else    {$ return false; }
12522 
12523     #else
12524 
12525     return (!!exc);
12526 
12527     #endif
12528     }
12529 
12530 #endif // TX_COMPILED
12531 
12532 //}
12533 //-----------------------------------------------------------------------------------------------------------------
12534 
12535 //-----------------------------------------------------------------------------------------------------------------
12536 //{          Errors reporting
12537 //-----------------------------------------------------------------------------------------------------------------
12538 
12539 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12540 
12541 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args)  //-V2008
12542     {
12543     _txErrors = _txErrors + 1;
12544 
12545     DWORD           winErr   = GetLastError();
12546 
12547     int             crtErr   = errno;
12548 
12549     #if !defined (__CYGWIN__)
12550     unsigned long   dosErr   = _doserrno;
12551     #else
12552     unsigned long   dosErr   = 0;
12553     #endif
12554 
12555     unsigned        dlgErr   = _TX_CALL (Win32::CommDlgExtendedError, ());
12556 
12557     unsigned        oglErr   = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError;
12558 
12559     unsigned        threadId = GetCurrentThreadId();
12560 
12561     enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 };
12562     unsigned options = 0;
12563 
12564     for (; msg && *msg; msg++)
12565         {
12566         if      (*msg == '\a') options |= isFatal;
12567         else if (*msg == '\v') options |= isWarning;
12568         else if (*msg == '\b') options |= noMsgBox;
12569         else if (*msg == '\f') options |= fmtOnly;
12570         else if (*msg == '\t') options |= traceSE;
12571         else break;
12572         }
12573 
12574     const char* stkTrace = NULL;
12575     const char*  txTrace = NULL; (void) txTrace;
12576 
12577     if (!(options & fmtOnly))
12578         {
12579         stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace   (2, true);
12580         txTrace  =                                                    _txCaptureStackBackTraceTX (0, true);
12581         }
12582 
12583     static char what[_TX_BIGBUFSIZE*10] = "";
12584     static char str [_TX_BIGBUFSIZE]    = "";
12585     char *s = what;
12586 
12587     #define     PRINT_(...)  s += _tx_snprintf_s  (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12588     #define    VPRINT_(...)  s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12589 
12590                 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" :
12591                                          (options & isFatal)?   "соболезнует..." :
12592                                                                 "сообщает:"));
12593                 PRINT_ ("Программа: %s", txGetModuleFileName());
12594     if (file)   PRINT_ (", файл: %s",    file);
12595     if (line)   PRINT_ (", строка: %d",  line);
12596     if (func)   PRINT_ (", функция: %s", func);
12597                 PRINT_ (",\n\n");
12598 
12599     if (msg)    PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"),
12600                VPRINT_ (msg, args);
12601 
12602     while (s > what && s[-1] == '\n') s--;
12603 
12604                 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s",
12605 
12606                         _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64,
12607 
12608                         "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace,
12609 
12610                         threadId, (threadId == _txMainThreadId)?    " (Main)"   :
12611                                   (threadId == _txCanvas_ThreadId)? " (Canvas)" : "");
12612 
12613     if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr),
12614                 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
12615                                     NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
12616                                     s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2,            //-V202
12617                 s -=  (s[-1] == '.')? 1 : 0,
12618                 PRINT_ (")");
12619 
12620     if (crtErr) PRINT_ (", errno: %d (%s)",                      crtErr, (strerror_s (str, sizeof (str), crtErr), str));
12621     if (dosErr) PRINT_ (", _doserrno: %lu (%s)",                 dosErr, (strerror_s (str, sizeof (str), dosErr), str));
12622     if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)",       oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr)));
12623     if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr);
12624 
12625     #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L)
12626                 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : "");
12627     #else
12628                 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true."  : "");
12629     #endif
12630 
12631     if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) &&
12632        (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func))
12633                 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func);
12634 
12635     txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what);
12636 
12637     if (options & fmtOnly)
12638         {
12639         SetLastError (winErr);
12640 
12641         errno = crtErr;
12642 
12643         #if !defined (__CYGWIN__)
12644         _doserrno = dosErr;
12645         #endif
12646 
12647         return what;
12648         }
12649 
12650     txSetProgress (-1, Win32::TBPF_ERROR);
12651 
12652     unsigned restore = txGetConsoleAttr();
12653     txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED);
12654     if (color) {$ txSetConsoleAttr (color); }
12655 
12656     int oldCodePage = txSetLocale();
12657 
12658     fprintf (stderr,      "\n" "--------------------------------------------------\n"
12659                                "%s\n"
12660                                "--------------------------------------------------\n",
12661                                what);
12662 
12663     if (stkTrace && strstr (stkTrace, ".exe: "))
12664         {$ fprintf (stderr,    "Стек вызовов:\n\n"
12665                                "%s\n\n"
12666                                "--------------------------------------------------\n",
12667                                stkTrace); }
12668 
12669     SetConsoleOutputCP (oldCodePage);
12670     txSetConsoleAttr (restore);
12671 
12672     if (*_txLogName) do  //-V2530
12673         {
12674         FILE* log = NULL; fopen_s (&log, _txLogName, "a");
12675         if (!log) {$ break; }
12676 
12677         fprintf (log,     "\n" "--------------------------------------------------\n"
12678                                "%s\n"
12679                                "--------------------------------------------------\n",
12680                                what);
12681 
12682         fprintf (log,          "Стек вызовов:\n\n"  //-V576
12683                                "%s\n",
12684                                (*_txTraceSE)? _txTraceSE : stkTrace);
12685 
12686         #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG)
12687 
12688         if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace)
12689             {
12690             fprintf (log, "\n" "--------------------------------------------------\n"
12691                                "Стек вызовов TX:\n\n"
12692                                "%s\n",
12693                                txTrace);
12694             }
12695 
12696         #endif
12697 
12698         fprintf (log,     "\n" "--------------------------------------------------\n"
12699                                "%s\n\n"
12700                                "--------------------------------------------------\n",
12701                                _txAppInfo());
12702         fclose (log);
12703         break;
12704         }
12705         while (false);
12706 
12707     txSleep();
12708 
12709     int ret = 0;
12710 
12711     if (!(options & noMsgBox))
12712         {
12713         txSleep (_txWindowUpdateInterval);
12714 
12715         PRINT_ ("\n" "Прервать программу?");
12716 
12717         ret = txMessageBox (what, ((options & isWarning)? "Предупреждение"   :
12718                                    (options & isFatal)?   "Фатальная ошибка" :
12719                                                           "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL);
12720         }
12721 
12722     SetLastError (winErr);
12723 
12724     errno = crtErr;
12725 
12726     #if !defined (__CYGWIN__)
12727     _doserrno = dosErr;
12728     #endif
12729 
12730     if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES)
12731         {
12732         txUnlock();
12733         _txCleanup();
12734         Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
12735         }
12736 
12737     #undef  PRINT_
12738     #undef VPRINT_
12739 
12740     return what;
12741     }
12742 
12743 //-----------------------------------------------------------------------------------------------------------------
12744 
12745 #if defined (_MSC_VER)
12746 
12747 int _txOnErrorReport (int type, const char* text, int* ret)
12748     {
12749     assert (text);
12750     assert (ret);
12751 
12752     _txErrors = _txErrors + 1;
12753 
12754     unsigned restore = txGetConsoleAttr();
12755 
12756     switch (type)
12757        {
12758        case _CRT_WARN:   txSetConsoleAttr (FOREGROUND_LIGHTRED);     break;
12759        case _CRT_ERROR:  txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break;
12760        case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW);       break;
12761        default:                                                      break;  //-V2522
12762        }
12763 
12764     const char startReport[] = "Detected memory leaks!\n",
12765                  endReport[] = "Object dump complete.\n";
12766 
12767     if (strcmp (text, startReport) == 0)  // Dirty, dirty hack. А что делать?
12768         {
12769         _txOnErrorReport (type, "\n",                                                                              NULL);
12770         _txOnErrorReport (type, _TX_VERSION " - ERROR: ",                                                          NULL);
12771         _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL);
12772         _txOnErrorReport (type, "\n",                                                                              NULL);
12773         }
12774 
12775     size_t len = strlen (text);
12776     if (text [len-1] != '\n')               txOutputDebugPrintf ("%s",                text);
12777     else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION);
12778     else                                    txOutputDebugPrintf ("%s\n",              text);
12779 
12780     DWORD n = 0;
12781     HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
12782     WriteFile (err, text, (DWORD) strlen (text), &n, NULL);      //-V202
12783 
12784     txSetConsoleAttr (restore);
12785 
12786     if (*_txLogName) do                                          //-V2530
12787         {
12788         HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12789         if (log == INVALID_HANDLE_VALUE) break;
12790 
12791         SetFilePointer (log, 0, NULL, FILE_END);
12792         WriteFile (log, text, (DWORD) strlen (text), &n, NULL);  //-V202
12793 
12794         CloseHandle (log);
12795         break;
12796         }
12797         while (false);
12798 
12799     if (ret) *ret = 0;
12800 
12801     return (type == _CRT_WARN);
12802     }
12803 
12804 #endif
12805 
12806 //-----------------------------------------------------------------------------------------------------------------
12807 
12808 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/)
12809     {
12810 $5  static wchar_t textW   [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]";
12811 $   static wchar_t headerW [_TX_BUFSIZE    * sizeof (wchar_t)] = L"[NULL header]";
12812 
12813     if (text)   {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text,   -1, textW,   sizearr (textW))   || memset (textW,   0, sizeof (textW));   }
12814     if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); }
12815 
12816 $   txSleep();
12817 
12818 $   HWND wnd = _txCanvas_Window;
12819 $   int  ret = MessageBoxW ((wnd && IsWindowVisible (wnd))? wnd : _TX_CALL (Win32::GetConsoleWindow,()),
12820                             textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST);
12821 
12822 $   GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU);
12823 
12824 $   if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU))
12825         {
12826 $       SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0);
12827 $       _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
12828         }
12829 
12830 $   return ret;
12831     }
12832 
12833 //-----------------------------------------------------------------------------------------------------------------
12834 
12835 bool txGetAsyncKeyState (int key)
12836     {
12837 $1  HWND wnd = GetForegroundWindow();
12838 
12839     return (GetAsyncKeyState (key) & 0x8000) &&
12840            (wnd == txWindow() || wnd == Win32::GetConsoleWindow());
12841     }
12842 
12843 //-----------------------------------------------------------------------------------------------------------------
12844 
12845 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...)
12846     {
12847 $5  if (_TX_ARGUMENT_FAILED (format)) return false;
12848 
12849 $   va_list arg; va_start (arg, format);
12850 $   bool ok = true;
12851 
12852     #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500)
12853 
12854 $   NOTIFYICONDATA nid = { sizeof (nid) };
12855 
12856 $   nid.uFlags      = NIF_ICON | NIF_TIP | NIF_INFO;
12857 $   nid.hWnd        = NULL;
12858 $   nid.uID         = 1;
12859 $   nid.hIcon       = _txCreateTXIcon (16); assert (nid.hIcon);
12860 $   strncpy_s       (nid.szTip,       sizeof (nid.szTip),       "TXLib Information", sizeof (nid.szTip));
12861 $   strncpy_s       (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1);
12862 $   _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg);
12863 $   nid.dwInfoFlags = flags;
12864 
12865 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo);
12866 
12867 $   ok &= !!Shell_NotifyIcon (NIM_ADD,    (::NOTIFYICONDATA*) &nid);
12868 $   ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid);
12869 
12870 $   if (nid.hIcon) DestroyIcon (nid.hIcon) asserted;
12871 
12872     #else
12873 
12874 $   char nid_szInfo[_TX_BUFSIZE] = "";
12875 $   _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg);
12876 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo);
12877 $   ok = false;
12878 
12879 $   (void)flags; (void)title;
12880 
12881     #endif
12882 
12883 $   va_end (arg);
12884     return ok;
12885     }
12886 
12887 //-----------------------------------------------------------------------------------------------------------------
12888 
12889 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...)
12890     {
12891     unsigned id = GetCurrentThreadId();
12892 
12893     const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}};
12894 
12895     char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)];
12896 
12897     char msgStr[_TX_BUFSIZE] = "";
12898     if (msg)
12899         {
12900         va_list arg; va_start (arg, msg);
12901         _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg);
12902         va_end (arg);
12903         }
12904 
12905     txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d)  " "|%*s%s" "%s%s\n",
12906 
12907                          _TX_VERSION, (void*) &_txInitialized,
12908 
12909                          "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit],
12910                          _txLoc::Cur.trace, mark,
12911 
12912                          (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line,
12913                          2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""),
12914 
12915                          ((*msgStr && func)? ": " : ""), msgStr);
12916     }
12917 
12918 //-----------------------------------------------------------------------------------------------------------------
12919 
12920 int txOutputDebugPrintf (const char* format, ...)
12921     {
12922     if (!format) return 0;
12923 
12924     enum { msgbox = 1, print = 2, compr = 4 };
12925     int options = 0;
12926 
12927     for (; format && *format; format++)
12928         {
12929         if      (*format == '\a') options |= msgbox;
12930         else if (*format == '\f') options |= print;
12931         else if (*format == '\r') options |= compr;
12932         else break;
12933         }
12934 
12935     char text[_TX_BIGBUFSIZE] = "";
12936 
12937     va_list arg; va_start (arg, format);
12938     int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg);  //-V202
12939     va_end (arg);
12940 
12941     struct __ { static int trimSpaces (char str[])
12942         {
12943         char *dst = str, *src = str;
12944 
12945         for (char d = ' '; d; src++)
12946             if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; }
12947             else                                                 *dst++ = d = *src;
12948 
12949         return (int) (dst - str - 1);  //-V202
12950         }};
12951 
12952     if (options & compr)  n = __::trimSpaces (text);
12953 
12954     OutputDebugString (text);
12955 
12956     if (options & print)  fprintf (stderr, "%s", text);
12957 
12958     if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION);
12959 
12960     return n;
12961     }
12962 
12963 //-----------------------------------------------------------------------------------------------------------------
12964 
12965 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...)
12966     {
12967     if (!format) return 0;
12968 
12969     va_list arg; va_start (arg, format);
12970     intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg);
12971     va_end (arg);
12972 
12973     return ret;
12974     }
12975 
12976 //-----------------------------------------------------------------------------------------------------------------
12977 
12978 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg)
12979     {
12980     if (!stream || !format) return 0;
12981 
12982     #if defined (_TRUNCATE)
12983     intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg);
12984     #else
12985     intptr_t ret = _vsnprintf   (stream, size,            format, arg);
12986     #endif
12987 
12988     if (ret < 0 && size >= 4)  //-V112
12989         {
12990         const char ellipsis[] = "...";
12991         size_t     szEllipsis = sizeof (ellipsis) - 1;
12992 
12993         strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis);
12994         }
12995 
12996     return (ret >= 0)? ret : size;
12997     }
12998 
12999 //-----------------------------------------------------------------------------------------------------------------
13000 
13001 #if defined (__CYGWIN__)
13002 
13003 int _getch()
13004     {
13005     termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr);
13006 
13007     termios newattr = oldattr;
13008     newattr.c_lflag &= ~(ICANON | ECHO);
13009     tcsetattr (STDIN_FILENO, TCSANOW, &newattr);
13010 
13011     int ch = getchar();
13012 
13013     tcsetattr (STDIN_FILENO, TCSANOW, &oldattr);
13014 
13015     return ch;
13016     }
13017 
13018 //-----------------------------------------------------------------------------------------------------------------
13019 
13020 int _putch (int ch)
13021     {
13022     termios old = {}; tcgetattr (STDOUT_FILENO, &old);
13023 
13024     termios cur = old;
13025     cur.c_lflag &= ~ICANON;
13026     cur.c_lflag |=  ECHO;
13027     tcsetattr (STDOUT_FILENO, TCSANOW, &cur);
13028 
13029     putchar (ch);
13030 
13031     tcsetattr (STDOUT_FILENO, TCSANOW, &old);
13032 
13033     return ch;
13034     }
13035 
13036 //-----------------------------------------------------------------------------------------------------------------
13037 
13038 int _kbhit()
13039     {
13040     termios old = {}; tcgetattr (STDIN_FILENO, &old);
13041 
13042     termios cur = old;
13043     cur.c_lflag &= ~(ICANON | ECHO);
13044     cur.c_cc[VMIN]  = 1;
13045     cur.c_cc[VTIME] = 0;
13046 
13047     tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur);
13048 
13049     fd_set  fd = {}; FD_SET (STDIN_FILENO, &fd);
13050     timeval tv = {};
13051 
13052     int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd);
13053 
13054     tcsetattr (STDIN_FILENO, TCSAFLUSH, &old);
13055 
13056     return res;
13057     }
13058 
13059 #endif
13060 
13061 #endif // TX_COMPILED
13062 
13063 //}
13064 //-----------------------------------------------------------------------------------------------------------------
13065 
13066 //-----------------------------------------------------------------------------------------------------------------
13067 //{          Information
13068 //-----------------------------------------------------------------------------------------------------------------
13069 
13070 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13071 
13072 const char* txGetModuleFileName (bool fileNameOnly /*= true*/)
13073     {
13074     static char name[MAX_PATH] = "";
13075 
13076     if (!*name)
13077         {
13078         if (!GetModuleFileName (NULL, name, sizeof (name) - 1)) *name = 0;
13079 
13080         char* ext = strrchr (name, '.');
13081         if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name));
13082         }
13083 
13084     assert (*name);
13085 
13086     if (fileNameOnly) return name;
13087 
13088     static char fullName[MAX_PATH] = "";
13089     strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1);
13090 
13091     char* title = strrchr (fullName, '\\'); if (!title) title = fullName;
13092     char* ext   = strrchr (fullName,  '.'); if (!ext)   ext   = fullName + strlen (fullName);
13093 
13094     size_t sz = sizeof (fullName) - (ext - fullName);
13095     strncpy_s (ext, sz-1, " - TXLib", sz);
13096 
13097     return title + 1;
13098     }
13099 
13100 #endif // TX_COMPILED
13101 
13102 //-----------------------------------------------------------------------------------------------------------------
13103 
13104 inline const char* _txAppInfo()
13105     {
13106 $1  time_t timeT     = time (NULL) - clock()/CLOCKS_PER_SEC;  //-V104
13107     char   timeS[32] = "";
13108     ctime_s (timeS, sizeof (timeS), &timeT);
13109 
13110     static char text[_TX_BUFSIZE] = "";
13111     char cwd [MAX_PATH] = "";
13112 
13113     _tx_snprintf_s (text, sizeof (text) - 1,
13114 
13115                     "Developed with:\n\n"
13116                     "The Dumb Artist Library (TX Library)\n"
13117                     _TX_VERSION "\n" _TX_AUTHOR "\n"
13118                     "See license on: http://txlib.ru\n\n"
13119 
13120                     "TXLib file:" "\t" __FILE__ "\n"
13121                     "Compiled:"   "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n"
13122                     "Started:"    "\t" "%.6s %.4s %.8s\n\n"
13123 
13124                     "Run file:"   "\t" "%s\n"
13125                     "Directory:"  "\t" "%s",
13126 
13127     #if   defined (_MSC_VER)
13128                     "MSVC Runtime",
13129     #elif defined (__CYGWIN__)
13130                     "Cygwin Runtime",
13131     #elif defined (_GCC_VER) && defined (_WIN64)
13132                     __mingw_get_crt_info(),
13133     #else
13134                     "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION),
13135     #endif
13136                     (sizeof (void*) == sizeof (DWORD))? 32 : 64,    //-V112
13137 
13138                     timeS + 4, timeS + 20, timeS + 11,              //-V112 These offsets are ANSI standardized
13139                     txGetModuleFileName(),
13140                     _getcwd (cwd, sizeof (cwd) - 1));
13141 
13142     return text;
13143     }
13144 
13145 //}
13146 //-----------------------------------------------------------------------------------------------------------------
13147 
13149 //}
13150 //=================================================================================================================
13151 
13152 //=================================================================================================================
13153 //{          TXLib API implementation
13154 //           Реализация TXLib API
13155 //=================================================================================================================
13156 
13157 inline const char* txVersion()
13158     {
13159     return _TX_VERSION;
13160     }
13161 
13162 //-----------------------------------------------------------------------------------------------------------------
13163 
13164 inline unsigned txVersionNumber()
13165     {
13166     return _TX_VER;  //-V2517
13167     }
13168 
13169 //-----------------------------------------------------------------------------------------------------------------
13170 
13171 inline HWND txWindow()
13172     {
13173 $9  return _txCanvas_Window;
13174     }
13175 
13176 //-----------------------------------------------------------------------------------------------------------------
13177 
13178 inline HDC& txDC()
13179     {
13180     return _txCanvas_BackBuf[0];
13181     }
13182 
13183 //-----------------------------------------------------------------------------------------------------------------
13184 
13185 inline RGBQUAD* txVideoMemory()
13186     {
13187     return _txCanvas_Pixels;
13188     }
13189 
13190 //-----------------------------------------------------------------------------------------------------------------
13191 
13192 inline int txGetExtentX (HDC dc /*= txDC()*/)
13193     {
13194     return txGetExtent (dc) .x;
13195     }
13196 
13197 //-----------------------------------------------------------------------------------------------------------------
13198 
13199 inline int txGetExtentY (HDC dc /*= txDC()*/)
13200     {
13201     return txGetExtent (dc) .y;
13202     }
13203 
13204 //-----------------------------------------------------------------------------------------------------------------
13205 
13206 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13207 
13208 POINT txGetExtent (HDC dc /*= txDC()*/)
13209     {
13210 $0  static POINT err = {-1, -1};
13211 
13212     if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; };
13213 
13214     if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; }
13215 
13216 $   BITMAP bmap = {};
13217 $   txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted;
13218 
13219 $   POINT  size = { bmap.bmWidth, bmap.bmHeight };
13220 $   return size;
13221     }
13222 
13223 //-----------------------------------------------------------------------------------------------------------------
13224 
13225 bool txDestroyWindow (HWND wnd /*= txWindow()*/)
13226     {
13227 $1  if (!wnd || !txWindow()) return false;
13228 
13229 $   if (wnd != txWindow())
13230         {
13231 $       return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd);
13232         }
13233 
13234 $   if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false;
13235 
13236 $   if (_txMain)
13237         {
13238 $       txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n"
13239                                                "Возвращайтесь через main(), там вам будут рады.\n");
13240 $       Sleep (_TX_TIMEOUT);
13241         }
13242 
13243 $   _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
13244 
13245 $   return _txCanvas_Window == NULL;
13246     }
13247 
13248 //-----------------------------------------------------------------------------------------------------------------
13249 
13250 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/)
13251     {
13252 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13253 
13254 $   HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color);
13255 
13256 $   if (!pen) return (HPEN) NULL;
13257 
13258 $   if (!_txBuffer_Select (pen, dc))
13259         {
13260 $       Win32::DeleteObject (pen);
13261 $       return (HPEN) NULL;
13262         }
13263 
13264 $   if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID)
13265         {$ return (HPEN) NULL; }
13266 
13267 $   return pen;
13268     }
13269 
13270 //-----------------------------------------------------------------------------------------------------------------
13271 
13272 COLORREF txColor (double red, double green, double blue)
13273     {
13274 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13275 $   if (green > 1) green = 1; if (green < 0) green = 0;
13276 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13277 
13278 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13279 
13280 $   return txSetColor (color)? color : CLR_INVALID;
13281     }
13282 
13283 //-----------------------------------------------------------------------------------------------------------------
13284 
13285 COLORREF txGetColor (HDC dc /*= txDC()*/)
13286     {
13287 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13288 
13289 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc);
13290 $   assert (obj); if (!obj) return CLR_INVALID;              //-V547
13291 
13292 $   union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {};  //-V2514
13293 
13294 $   int size = Win32::GetObject (obj, 0, NULL);
13295 $   Win32::GetObject (obj, sizeof (buf), &buf) asserted;
13296 
13297 $   return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor;
13298     }
13299 
13300 //-----------------------------------------------------------------------------------------------------------------
13301 
13302 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/)
13303     {
13304 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13305 
13306 $   HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color);
13307 
13308 $   return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL);
13309     }
13310 
13311 //-----------------------------------------------------------------------------------------------------------------
13312 
13313 COLORREF txFillColor (double red, double green, double blue)
13314     {
13315 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13316 $   if (green > 1) green = 1; if (green < 0) green = 0;
13317 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13318 
13319 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13320 
13321 $   return txSetFillColor (color)? color : CLR_INVALID;
13322     }
13323 
13324 //-----------------------------------------------------------------------------------------------------------------
13325 
13326 COLORREF txGetFillColor (HDC dc /*= txDC()*/)
13327     {
13328 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13329 
13330 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc);
13331 $   assert (obj); if (!obj) return CLR_INVALID;  //-V547
13332 
13333 $   LOGBRUSH buf = {};
13334 $   txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted;
13335 
13336 $   return buf.lbColor;
13337     }
13338 
13339 //-----------------------------------------------------------------------------------------------------------------
13340 
13341 bool txClear (HDC dc /*= txDC()*/)
13342     {
13343 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13344 
13345 $   POINT size = txGetExtent (dc);
13346 $   return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc);
13347     }
13348 
13349 //-----------------------------------------------------------------------------------------------------------------
13350 
13351 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/)
13352     {
13353 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13354 
13355 $   txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc);
13356 
13357 $   return true;
13358     }
13359 
13360 //-----------------------------------------------------------------------------------------------------------------
13361 
13362 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/)
13363     {
13364 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13365 $   if (green > 1) green = 1; if (green < 0) green = 0;
13366 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13367 
13368 $   return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc);
13369     }
13370 
13371 //-----------------------------------------------------------------------------------------------------------------
13372 
13373 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/)
13374     {
13375 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13376 
13377 $   return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc);
13378     }
13379 
13380 //-----------------------------------------------------------------------------------------------------------------
13381 
13382 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13383     {
13384 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13385 
13386 $   bool ok  = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc);
13387 $        ok &= txGDI ((Win32::LineTo   (dc, ROUND (x1), ROUND (y1)      )), dc);
13388 
13389 $   return ok;
13390     }
13391 
13392 //-----------------------------------------------------------------------------------------------------------------
13393 
13394 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13395     {
13396 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13397 
13398 $   return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13399     }
13400 
13401 //-----------------------------------------------------------------------------------------------------------------
13402 
13403 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/)
13404     {
13405 $1  if (_TX_ARGUMENT_FAILED    (points)) return false;
13406 $   if (_TX_DEFAULT_HDC_FAILED (dc))     return false;
13407 
13408 $   return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc);
13409     }
13410 
13411 //-----------------------------------------------------------------------------------------------------------------
13412 
13413 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13414     {
13415 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13416 
13417 $   return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13418     }
13419 
13420 //-----------------------------------------------------------------------------------------------------------------
13421 
13422 bool txCircle (double x, double y, double r)
13423     {
13424 $1  return txEllipse (x-r, y-r, x+r, y+r);
13425     }
13426 
13427 //-----------------------------------------------------------------------------------------------------------------
13428 
13429 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13430     {
13431 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13432 
13433 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13434 
13435 $   double start =  startAngle               * txPI/180,
13436            end   = (startAngle + totalAngle) * txPI/180;
13437 
13438 $   return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13439                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13440                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13441     }
13442 
13443 //-----------------------------------------------------------------------------------------------------------------
13444 
13445 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13446     {
13447 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13448 
13449 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13450 
13451 $   double start =  startAngle               * txPI/180,
13452            end   = (startAngle + totalAngle) * txPI/180;
13453 
13454 $   return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13455                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13456                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13457     }
13458 
13459 //-----------------------------------------------------------------------------------------------------------------
13460 
13461 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13462     {
13463 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13464 
13465 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13466 
13467 $   double start =  startAngle               * txPI/180,
13468            end   = (startAngle + totalAngle) * txPI/180;
13469 
13470 $   return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13471                                        ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13472                                        ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13473     }
13474 
13475 //-----------------------------------------------------------------------------------------------------------------
13476 
13477 bool txFloodFill (double x, double y,
13478                   COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/)
13479     {
13480 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13481 
13482 $   if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc);
13483 
13484 $   return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc);
13485     }
13486 
13487 //-----------------------------------------------------------------------------------------------------------------
13488 
13489 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/)
13490     {
13491 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13492 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13493 
13494 $   int len = (int) strlen (text);  //-V202
13495 $   bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc);
13496 
13497 $   return ok;
13498     }
13499 
13500 //-----------------------------------------------------------------------------------------------------------------
13501 
13502 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
13503                  unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/,
13504                  HDC dc /*= txDC()*/)
13505     {
13506 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13507 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13508 
13509 #if !defined (NDEBUG)
13510 
13511 $   if (x0 > x1)
13512         {
13513 $       SetLastError (ERROR_INVALID_DATA);
13514 $       TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1);
13515         }
13516 
13517 $   if (y0 > y1)
13518         {
13519 $       SetLastError (ERROR_INVALID_DATA);
13520 $       TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1);
13521         }
13522 
13523 #endif
13524 
13525 $   RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) };
13526 
13527 $   if (!strchr (text, '\n')) format |= DT_SINGLELINE;
13528 
13529 $   unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc);
13530 
13531 $   bool ok = false;
13532 
13533 $   if (Win32::DrawText)
13534         {
13535 $       ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc);
13536 $       Win32::GetPixel (dc, 0, 0);
13537 $       ok = true;  //-V519
13538         }
13539     else
13540         {
13541 $       txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text);
13542 $       ok = false;
13543         }
13544 
13545 $   txSetTextAlign (prev, dc);
13546 
13547 $   return ok;
13548     }
13549 
13550 //-----------------------------------------------------------------------------------------------------------------
13551 
13552 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/,
13553                     int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/,
13554                     bool strikeout /*= false*/, double angle /*= 0*/,
13555                     HDC dc /*= txDC()*/)
13556     {
13557 $1  if (_TX_ARGUMENT_FAILED    (name)) return NULL;
13558 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return NULL;
13559 
13560 $   HFONT font = txFontExist (name)?
13561                      Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3),
13562                                         ROUND (angle*10), 0, bold, italic, underline, strikeout,
13563                                         RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
13564                                         DEFAULT_QUALITY, DEFAULT_PITCH, name)
13565                      :
13566                      (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT);
13567 
13568 $   _txBuffer_Select (font, dc);
13569 
13570 $   return font;
13571     }
13572 
13573 //-----------------------------------------------------------------------------------------------------------------
13574 
13575 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/)
13576     {
13577 $1  SIZE size = {-1, -1};
13578 
13579 $   if (_TX_ARGUMENT_FAILED    (text)) return size;
13580 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return size;
13581 
13582 $   size_t len = strlen (text);
13583 $   txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted;  //-V202
13584 
13585 $   return size;
13586     }
13587 
13588 //-----------------------------------------------------------------------------------------------------------------
13589 
13590 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/)
13591     {
13592 $1  return txGetTextExtent (text, dc) .cx;
13593     }
13594 
13595 //-----------------------------------------------------------------------------------------------------------------
13596 
13597 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/)
13598     {
13599 $1  return txGetTextExtent (text, dc) .cy;
13600     }
13601 
13602 //-----------------------------------------------------------------------------------------------------------------
13603 
13604 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/)
13605     {
13606 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;  //-V601
13607 
13608 $   return txGDI ((Win32::SetTextAlign (dc, align)), dc);
13609     }
13610 
13611 //-----------------------------------------------------------------------------------------------------------------
13612 
13613 LOGFONT* txFontExist (const char name[])
13614     {
13615 $1  if (_TX_ARGUMENT_FAILED (name)) return NULL;
13616 
13617 $   static LOGFONT font = {};
13618 $   font.lfCharSet = DEFAULT_CHARSET;
13619 $   strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1);
13620 
13621 $   struct tools
13622         {
13623         static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data)
13624             {
13625 $           if (_TX_ARGUMENT_FAILED (fnt))  return 0;
13626 $           if (_TX_ARGUMENT_FAILED (data)) return 0;
13627 
13628             #ifndef __STRICT_ANSI__
13629 $           return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13630 
13631             #else
13632 $           return  strncmp  (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13633 
13634             #endif
13635             }
13636         };
13637 
13638 $   return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL;
13639     }
13640 
13641 //-----------------------------------------------------------------------------------------------------------------
13642 
13643 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/)
13644     {
13645 $1  if (_TX_ARGUMENT_FAILED    (obj)) return false;
13646 $   if (_TX_DEFAULT_HDC_FAILED (dc))  return false;
13647 
13648 $   return _txBuffer_Select (obj, dc);
13649     }
13650 
13651 //-----------------------------------------------------------------------------------------------------------------
13652 
13653 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
13654     {
13655 $1  POINT size = { ROUND (sizeX), ROUND (sizeY) };
13656 
13657 $   HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels);
13658 $   assert (dc); if (!dc) return NULL;  //-V547
13659 
13660 $   txSetDefaults (dc);
13661 
13662 $   if (!_txCanvas_UserDCs) return dc;
13663 
13664 $   txAutoLock _lock;
13665 $   _txCanvas_UserDCs->push_back (dc);
13666 
13667 $   if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE)
13668         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); }  //-V202
13669 
13670 $   return dc;
13671     }
13672 
13673 //-----------------------------------------------------------------------------------------------------------------
13674 
13675 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/)
13676     {
13677 $1  return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels);
13678     }
13679 
13680 //-----------------------------------------------------------------------------------------------------------------
13681 
13682 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)
13683     {
13684 $1  return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels);
13685     }
13686 
13687 //-----------------------------------------------------------------------------------------------------------------
13688 
13689 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/,
13690                  unsigned imageType /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/)
13691     {
13692 $1  if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL;
13693 
13694 $   HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL),
13695                                                  filename, imageType, sizeX, sizeY, loadFlags | LR_CREATEDIBSECTION);
13696 $   if (!image) return NULL;
13697 
13698 $   HDC dc = txCreateCompatibleDC (sizeX, sizeY, image);
13699 
13700 $   if (!(loadFlags & LR_LOADFROMFILE)) return dc;
13701 
13702 $   static std::map <std::string, unsigned> loadTimes;
13703 $   std::string file = filename;
13704 $   unsigned time    = GetTickCount();
13705 
13706 $   if ((long) (time - loadTimes [file]) < _TX_TIMEOUT)
13707         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); }
13708 
13709 $   loadTimes [file] = time;
13710 
13711 $   return dc;
13712     }
13713 
13714 //-----------------------------------------------------------------------------------------------------------------
13715 
13716 bool txDeleteDC (HDC* pdc)
13717     {
13718 $1  if (_TX_ARGUMENT_FAILED (pdc)) return false;
13719 
13720 $   HDC  dc = *pdc;
13721 $   bool ok = _txBuffer_Delete (pdc);
13722 $   if (!ok) return false;
13723 
13724 $   if (!_txCanvas_UserDCs) return ok;
13725 
13726 $   txAutoLock _lock;
13727 
13728 $   for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it)
13729         if (*it == dc)
13730             {
13731 $           std::swap (*it, _txCanvas_UserDCs->back());
13732 $           _txCanvas_UserDCs->pop_back();
13733 $           break;
13734             }
13735 
13736 $   return ok;
13737     }
13738 
13739 //-----------------------------------------------------------------------------------------------------------------
13740 
13741 bool txDeleteDC (HDC dc)
13742     {
13743 $1  return txDeleteDC (&dc);
13744     }
13745 
13746 //-----------------------------------------------------------------------------------------------------------------
13747 
13748 bool txBitBlt (HDC destImage,   double xDest, double yDest, double width, double height,
13749                HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/)
13750     {
13751 $1  if (_TX_HDC_FAILED (destImage))   return false;
13752 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13753 
13754 $   POINT size = txGetExtent (sourceImage);
13755 $   if (!width)  width  = size.x;  //-V550
13756 $   if (!height) height = size.y;  //-V550
13757 
13758 $   return txGDI (!!(Win32::BitBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13759                                     sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage);
13760     }
13761 
13762 //-----------------------------------------------------------------------------------------------------------------
13763 
13764 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/)
13765     {
13766 $1  if (_TX_TXWINDOW_FAILED()) return false;
13767 
13768 $   return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource);
13769     }
13770 
13771 //-----------------------------------------------------------------------------------------------------------------
13772 
13773 bool txTransparentBlt (HDC destImage,   double xDest, double yDest, double width, double height,
13774                        HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/)
13775     {
13776     // Это проверки того, правильные ли HDC вы передали в функцию.
13777     // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а.
13778     // При первом чтении это можно пропустить.
13779 
13780 $1  if (_TX_HDC_FAILED (destImage))   return false;
13781 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13782 
13783     // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent().
13784     // При первом чтении это можно пропустить.
13785 
13786 $   POINT size = txGetExtent (sourceImage);
13787 $   if (!width)  width  = size.x;  //-V550
13788 $   if (!height) height = size.y;  //-V550
13789 
13790     // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest).
13791     // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только
13792     // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки).
13793     // При первом чтении это можно пропустить.
13794 
13795 #if !defined (NDEBUG)
13796 
13797 $   if (!(0 <= xSource && xSource + width  <= size.x &&
13798           0 <= ySource && ySource + height <= size.y))
13799         {
13800 $       SetLastError (ERROR_INVALID_DATA);
13801 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
13802                   "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
13803         }
13804 
13805 #endif
13806 
13807 $   bool ok = true;
13808 
13809 $   if (Win32::TransparentBlt)
13810         {
13811         // А вот теперь уже надо начать читать.
13812         //
13813         // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function"
13814         // и почитайте про ее параметры.
13815         //
13816         // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не
13817         // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что
13818         // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s>
13819         // это сделано для упрощения вызова функции TransparentBlt().
13820 
13821                                // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки!        // <<--
13822                                //                                                                                                          // <<--
13823                                //                                                                    |||||          ||||||                 // <<--
13824                                //                                                                    vvvvv          vvvvvv                 // <<--
13825                                                                                                                                            // <<--
13826 $       ok &= txGDI (!!(Win32::TransparentBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),               // <<<<
13827                                                sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<<
13828                                                destImage);                                                                                 // <<--
13829                                //                                                                    ^^^^^          ^^^^^^                 // <<--
13830                                //                                                                    |||||          ||||||                 // <<--
13831                                //                                                                                                          // <<--
13832         }                      // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте!     // <<--
13833     else
13834         {
13835 $       ok &= txGDI (!!(Win32::BitBlt         (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13836                                                sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
13837                                                destImage);
13838         }
13839 
13840     // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что
13841     // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s>
13842     // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL
13843     // или DirectX, будет круто. Хотя это и сложнее.</s>
13844 
13845     // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами,
13846     // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :((
13847 
13848 $   return ok;
13849     }
13850 
13851 //-----------------------------------------------------------------------------------------------------------------
13852 
13853 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
13854                        COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/)
13855     {
13856 $1  if (_TX_TXWINDOW_FAILED()) return false;
13857 
13858 $   return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor);
13859     }
13860 
13861 //-----------------------------------------------------------------------------------------------------------------
13862 
13863 bool txAlphaBlend (HDC destImage,   double xDest, double yDest, double width, double height,
13864                    HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
13865     {
13866 $1  if (_TX_HDC_FAILED (destImage))   return false;
13867 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13868 
13869 $   POINT size = txGetExtent (sourceImage);
13870 $   if (!width)  width  = size.x;  //-V550
13871 $   if (!height) height = size.y;  //-V550
13872 
13873 #if !defined (NDEBUG)
13874 
13875 $   if (!(0 <= xSource && xSource + width  <= size.x &&
13876           0 <= ySource && ySource + height <= size.y))
13877         {
13878 $       SetLastError (ERROR_INVALID_DATA);
13879 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
13880                   "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
13881         }
13882 
13883 #endif
13884 
13885 $   if (alpha < 0) alpha = 0;
13886 $   if (alpha > 1) alpha = 1;
13887 
13888 $   BITMAP bmap = { 0, 0, 0, 0, 0, 24 };
13889 $   bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap);
13890 
13891 $   BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) };  //-V112 //-V821 //-V2551
13892 
13893 $   if (Win32::AlphaBlend)
13894         {
13895 $       ok &= txGDI (!!(Win32::AlphaBlend (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13896                                            sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)),
13897                                            destImage);
13898         }
13899     else
13900         {
13901 $       ok &= txGDI (!!(Win32::BitBlt     (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13902                                            sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
13903                                            destImage);
13904 $       ok = false;  //-V519
13905         }
13906 
13907 $   return ok;
13908     }
13909 
13910 //-----------------------------------------------------------------------------------------------------------------
13911 
13912 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
13913                    double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
13914     {
13915 $1  if (_TX_TXWINDOW_FAILED()) return false;
13916 
13917 $   return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha);
13918     }
13919 
13920 //-----------------------------------------------------------------------------------------------------------------
13921 
13922 HDC txUseAlpha (HDC image)
13923     {
13924 $1  if (_TX_HDC_FAILED (image)) return NULL;
13925 
13926 $   HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP);
13927 $   if (!bitmap) return NULL;
13928 
13929 $   DIBSECTION dib = {};
13930 $   Win32::GetObject (bitmap, sizeof (dib), &dib) asserted;
13931 
13932 $   POINT      size = {  dib.dsBm.bmWidth, dib.dsBm.bmHeight };
13933 $   BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }};
13934 $   RGBQUAD*   buf  = NULL;
13935 
13936 $   bool isDIB = (dib.dsBm.bmPlanes        == 1                    &&
13937                   dib.dsBm.bmBitsPixel     == sizeof (RGBQUAD) * 8 &&
13938                   dib.dsBmih.biCompression == DIB_RGB_COLORS       &&
13939                   dib.dsBm.bmBits);
13940 $   if (!isDIB)
13941         {
13942 $       buf = new (std::nothrow) RGBQUAD [size.x * size.y];  //-V121
13943 $       if (!buf) return NULL;
13944 
13945 $       Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
13946         }
13947     else
13948         {
13949 $       buf = (RGBQUAD*) dib.dsBm.bmBits;
13950         }
13951 
13952 $   for (int y = 0; y < size.y; y++)
13953     for (int x = 0; x < size.x; x++)
13954         {
13955         RGBQUAD* color = &buf [x + y * size.x];  // Get color at (x, y) within image buffer  //-V108
13956 
13957         color->rgbRed   = (BYTE) ROUND (color->rgbRed   * color->rgbReserved / 255.0);
13958         color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0);
13959         color->rgbBlue  = (BYTE) ROUND (color->rgbBlue  * color->rgbReserved / 255.0);
13960         }
13961 
13962 $   if (!isDIB)
13963         {
13964 $       Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
13965 
13966 $       delete[] buf;
13967         }
13968 
13969 $   return image;
13970     }
13971 
13972 //-----------------------------------------------------------------------------------------------------------------
13973 
13974 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/)
13975     {
13976 $1  if (_TX_ARGUMENT_FAILED    (filename)) return false;
13977 $   if (_TX_DEFAULT_HDC_FAILED (dc))       return false;
13978 
13979 $   POINT size = txGetExtent (dc);
13980 
13981 $   size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER),  //-V119
13982            szImg  = (size.x * size.y) * sizeof (RGBQUAD);                   //-V104
13983 
13984 $   BITMAP           bmap = {};
13985 $   BITMAPFILEHEADER hdr  = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs };  //-V202
13986 $   BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB };
13987 
13988 $   RGBQUAD* buf = NULL;
13989 $   bool     ok  = true;
13990 
13991 $   ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap);
13992 
13993     if (!ok) {$ return false; }
13994 
13995 $   if (!bmap.bmBits)
13996         {
13997 $       buf =  new (std::nothrow) RGBQUAD [size.x * size.y];                //-V121
13998 $       ok &= (buf != NULL);
13999 
14000 $       int res = Win32::GetDIBits (dc,  (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y,
14001                                     buf, (BITMAPINFO*) &info, DIB_RGB_COLORS);
14002 
14003         if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); }
14004 
14005 $       ok &= !!res;
14006         }
14007     else
14008         {
14009 $       buf = (RGBQUAD*) bmap.bmBits;
14010         }
14011 
14012 $   FILE* f = NULL;
14013 $   if (ok) fopen_s (&f, filename, "wb");
14014 $   ok &= (f != NULL);
14015 
14016 $   if (ok) ok &= (fwrite (&hdr,  sizeof (hdr),  1, f) == 1);               //-V575 //-V595
14017 $   if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1);
14018 $   if (ok) ok &= (fwrite (buf,   szImg,         1, f) == 1);               //-V575
14019 
14020 $   ok &= (f && fclose (f) == 0);
14021 
14022 $   if (!bmap.bmBits)
14023         {
14024 $       delete[] buf;
14025 $       buf = NULL;
14026         }
14027 
14028 $   return ok;
14029     }
14030 
14031 //-----------------------------------------------------------------------------------------------------------------
14032 
14033 double txSleep (double time)
14034     {
14035 $1  LARGE_INTEGER start = {};
14036 $   QueryPerformanceCounter (&start) asserted;
14037 
14038 $   LARGE_INTEGER freq = {};
14039 $   QueryPerformanceFrequency (&freq) asserted;
14040 
14041 $   int lock = _txCanvas_RefreshLock;
14042 $   _txCanvas_RefreshLock = 0;
14043 
14044 $   HWND wnd = txWindow();
14045     if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
14046 
14047 $   Sleep (ROUND ((time >= 0)? time : 0));
14048 
14049 $   _txCanvas_RefreshLock = lock;
14050 
14051 $   LARGE_INTEGER stop = {};
14052 $   QueryPerformanceCounter (&stop) asserted;
14053 
14054 $   return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart;
14055     }
14056 
14057 //-----------------------------------------------------------------------------------------------------------------
14058 
14059 bool txLock (bool wait /*= true*/)
14060     {
14061 $0  if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14062 
14063 $   if (wait) {$ return      EnterCriticalSection (&_txCanvas_LockBackBuf), true; }  //-V1048
14064     else      {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf);       }
14065     }
14066 
14067 //-----------------------------------------------------------------------------------------------------------------
14068 
14069 bool txUnlock()
14070     {
14071 $0  LeaveCriticalSection (&_txCanvas_LockBackBuf);
14072 
14073 $   if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14074 $   return false;
14075     }
14076 
14077 #endif // TX_COMPILED
14078 
14079 //-----------------------------------------------------------------------------------------------------------------
14080 
14081 template <typename T>
14082 inline T txUnlock (T value)
14083     {
14084 $1  txUnlock();
14085 $   return value;
14086     }
14087 
14088 //-----------------------------------------------------------------------------------------------------------------
14089 
14090 inline void txRedrawWindow()
14091     {
14092 $1  txSleep (0);
14093     }
14094 
14095 //-----------------------------------------------------------------------------------------------------------------
14096 
14097 inline int txUpdateWindow (int update /*= true*/)
14098     {
14099 $1  return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update);
14100     }
14101 
14102 //-----------------------------------------------------------------------------------------------------------------
14103 
14104 inline int txBegin()
14105     {
14106 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1);
14107 
14108 $   return _txCanvas_RefreshLock;
14109     }
14110 
14111 //-----------------------------------------------------------------------------------------------------------------
14112 
14113 inline int txEnd()
14114     {
14115 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1);
14116 
14117 $   return _txCanvas_RefreshLock;
14118     }
14119 
14120 //-----------------------------------------------------------------------------------------------------------------
14121 
14122 inline POINT txMousePos()
14123     {
14124 $1  POINT pos = {};
14125 $   GetCursorPos (&pos);
14126 
14127 $   if (txWindow())
14128         {$ ScreenToClient (txWindow(), &pos); }
14129 
14130 $   return pos;
14131     }
14132 
14133 //-----------------------------------------------------------------------------------------------------------------
14134 
14135 inline double txMouseX()
14136     {
14137     return (double) txMousePos() .x;
14138     }
14139 
14140 //-----------------------------------------------------------------------------------------------------------------
14141 
14142 inline double txMouseY()
14143     {
14144     return (double) txMousePos() .y;
14145     }
14146 
14147 //-----------------------------------------------------------------------------------------------------------------
14148 
14149 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14150 
14151 unsigned txMouseButtons()
14152     {
14153 $1  HWND txWnd      = txWindow();
14154 $   HWND foreground = GetForegroundWindow();
14155 
14156 $   if ((txWnd && (foreground == txWnd)) ||
14157        (!txWnd && (foreground == Win32::GetConsoleWindow())))
14158         {
14159 $       return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) |  // MSB to bit 0
14160                ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) |  // MSB to bit 1
14161                ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13);   // MSB to bit 2
14162         }
14163     else
14164         {$ return 0; }
14165     }
14166 
14167 //-----------------------------------------------------------------------------------------------------------------
14168 
14169 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/)
14170     {
14171     unsigned oldAttr = txGetConsoleAttr();
14172 
14173     SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color);
14174     SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE),  (WORD) color);
14175 
14176     return oldAttr;
14177     }
14178 
14179 //-----------------------------------------------------------------------------------------------------------------
14180 
14181 unsigned txGetConsoleAttr()
14182     {
14183     CONSOLE_SCREEN_BUFFER_INFO con = {};
14184     con.wAttributes = FOREGROUND_LIGHTGRAY;
14185 
14186     GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) ||
14187     GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE),  &con);
14188 
14189     return con.wAttributes;
14190     }
14191 
14192 //-----------------------------------------------------------------------------------------------------------------
14193 
14194 POINT txSetConsoleCursorPos (double x, double y)
14195     {
14196 $1  POINT fontSz = txGetConsoleFontSize();
14197 
14198 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14199 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14200 
14201 $   COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left),
14202                   (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) };
14203 
14204 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted;
14205 
14206 $   POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14207                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14208 $   return prev;
14209     }
14210 
14211 //-----------------------------------------------------------------------------------------------------------------
14212 
14213 POINT txGetConsoleCursorPos()
14214     {
14215 $1  POINT fontSz = txGetConsoleFontSize();
14216 
14217 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14218 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14219 
14220 $   POINT  pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14221                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14222 $   return pos;
14223     }
14224 
14225 //-----------------------------------------------------------------------------------------------------------------
14226 
14227 POINT txGetConsoleExtent()
14228     {
14229 $1  CONSOLE_SCREEN_BUFFER_INFO con = {};
14230 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14231 
14232 $   POINT  size = { con.srWindow.Right  - con.srWindow.Left + 1,
14233                     con.srWindow.Bottom - con.srWindow.Top  + 1 };
14234 $   return size;
14235     }
14236 
14237 //-----------------------------------------------------------------------------------------------------------------
14238 
14239 bool txClearConsole()
14240     {
14241 $1  HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
14242 
14243 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14244 $   GetConsoleScreenBufferInfo (out, &con) asserted;
14245 
14246 $   COORD start = {con.srWindow.Left, con.srWindow.Top};
14247 
14248 $   DWORD len   = (con.srWindow.Right  - con.srWindow.Left + 1) *
14249                   (con.srWindow.Bottom - con.srWindow.Top  + 1);
14250 
14251 $   DWORD written = 0;
14252 $   FillConsoleOutputCharacter (out, 0x20 /*' '*/,    len, start, &written) asserted;  //-V112
14253 $   FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted;
14254 
14255 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted;
14256 
14257 $   return written == len;
14258     }
14259 
14260 //-----------------------------------------------------------------------------------------------------------------
14261 
14262 POINT txGetConsoleFontSize()
14263     {
14264 $1  Win32::CONSOLE_FONT_INFO font = {0, {8, 16}};
14265 
14266 $   _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font));
14267 
14268 $   SIZE size = { font.dwFontSize.X, font.dwFontSize.Y };
14269     if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); }  //-V501
14270 
14271     if (size.cx == 0) {$ size.cx = 1; }
14272     if (size.cy == 0) {$ size.cy = 1; }
14273 
14274 $   POINT sizeFont = { size.cx, size.cy };
14275 $   return sizeFont;
14276     }
14277 
14278 //-----------------------------------------------------------------------------------------------------------------
14279 
14280 bool txTextCursor (bool blink /*= true*/)
14281     {
14282 $1  bool old = _txConsole_IsBlinking;
14283 
14284 $   _txConsole_IsBlinking = blink;
14285 
14286 $   return old;
14287     }
14288 
14289 //-----------------------------------------------------------------------------------------------------------------
14290 
14291 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/)
14292     {
14293 $1  mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT;
14294 $   if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC;
14295 
14296 $   if (!filename) mode = SND_PURGE;
14297 
14298 $   return !!Win32::PlaySound (filename, NULL, mode);
14299     }
14300 
14301 //-----------------------------------------------------------------------------------------------------------------
14302 
14303 int txSpeak (const char* text, ...)
14304     {
14305 $1  bool verbose = false; (void) verbose;
14306 $   bool async   = false; (void) async;
14307 
14308 $   for (; text && *text; text++)
14309         {
14310         if      (*text == '\a') {$ async   = true; }
14311         else if (*text == '\v') {$ verbose = true; }
14312         else break;
14313         }
14314 
14315 $   char textA [_TX_BUFSIZE] = "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!";
14316 
14317 $   va_list arg; va_start (arg, text);
14318     if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); }
14319 $   va_end (arg);
14320 
14321     if (text && verbose) {$ printf ("%s", textA); }
14322 
14323 #ifdef TX_USE_SPEAK
14324 
14325 $   int time = GetTickCount();
14326 
14327 $   static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L"";
14328 $   MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW));
14329 
14330 $   static ISpVoice* voice = NULL;
14331 
14332 $   if (text && !voice)
14333         {
14334 $       HRESULT res = Win32::CoInitialize (NULL);
14335         if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); }
14336         }
14337 
14338 $   if (text && voice)
14339         {
14340 $       Win32::_fpreset();
14341 $       voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL);
14342 $       tx_fpreset();
14343         }
14344 
14345 $   if (!text && voice)
14346         {
14347 $       voice->Release();
14348 $       voice = NULL;
14349 
14350 $       Win32::CoUninitialize();
14351         }
14352 
14353 $   return (voice)? GetTickCount() - time : -1;
14354 
14355 #else
14356 
14357 $   if (text)
14358         {
14359 $       unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK);
14360 
14361 $       txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA);
14362 
14363 $       txSetConsoleAttr (oldAttr);
14364         }
14365 
14366 $   return -1;
14367 
14368 #endif
14369     }
14370 
14371 //-----------------------------------------------------------------------------------------------------------------
14372 
14373 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
14374                       double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/)
14375     {
14376 $1  if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1;
14377 
14378 $   int time = GetTickCount();  //-V2551
14379 
14380 $   static char processUID [64] = "";
14381     if (!*processUID)
14382         {
14383 $       FILETIME startTime = {}, null = {};
14384 $       GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted;
14385 $       _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo",
14386                     (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted;
14387         }
14388 
14389 $   if (!fileName)
14390         {
14391 $       _txTaskKill ("vlc.exe", processUID, 0);  // Kill'em all, by command line pattern
14392 $       return 0;
14393         }
14394 
14395 $   static const char* vlcPath = _txPlayVideo_FindVLC();
14396 
14397 $   if (!vlcPath || _access (vlcPath, 0) != 0)
14398         {
14399 $       static int once = false;  //-V601
14400 
14401 $       if (*fileName && !once++)
14402             {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org "
14403                                     "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n"
14404                                     "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n"
14405                                     "P.S. См. мое описание в TXLib Help."); }
14406 $       return INT_MIN;  //-V109
14407         }
14408 
14409 $   bool async = false;
14410     if (*fileName == '\a') {$ async = true; fileName++; }
14411 
14412 $   RECT rect = {};
14413     if (wnd) {$ GetClientRect (wnd, &rect); }
14414 
14415     if (!width)  {$ width  = rect.right;  }
14416     if (!height) {$ height = rect.bottom; }
14417 
14418     // Create a child window to hold the video stream
14419 
14420 $   const char* errPos = "ВНЕЗАПНО";
14421 
14422 $   volatile HWND child = NULL;
14423 $   if (wnd && (wnd == txWindow()))
14424         {
14425 $       const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1);
14426 
14427 $       static int number = 1;
14428 $       CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x,
14429                                     WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass };
14430 $       child = txCreateExtraWindow (createData);
14431 $       if (!child)
14432             {
14433 $           txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14434                                        strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos));
14435 $           return INT_MIN+3;  //-V109
14436             }
14437 
14438 $       BringWindowToTop (child);
14439 
14440 $       wnd = child;
14441         }
14442 
14443     // Build the command line
14444 
14445     if (!zoom && !wnd) {$ zoom = 1; }
14446 
14447 $   char sZoom [64] = "--autoscale";
14448     if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; }  //-V550
14449 
14450 $   static char cmd [MAX_PATH*2 + 1024] = "";
14451 
14452 $   _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit"
14453 
14454                  " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s"
14455 
14456                  " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging"
14457 
14458                  " --ignore-config --reset-config --no-one-instance --play-and-exit"
14459                  " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file"
14460                  " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events",
14461 
14462                  vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted;
14463 
14464 $   txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n",
14465                          x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd);
14466 $   if (!*fileName)
14467         {
14468         if (child) {$ txDestroyWindow (child); }
14469 $       return (intptr_t) cmd;
14470         }
14471 
14472 $   if (!strstr (fileName, "://") && _access (fileName, 0) != 0)
14473         {
14474 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14475                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos));
14476 
14477         if (child) {$ txDestroyWindow (child); }
14478 $       return INT_MIN+1;  //-V109
14479         }
14480 
14481     // Run VLC, run
14482 
14483 $   PROCESS_INFORMATION vlc   = {};
14484 $   STARTUPINFO         start = { sizeof (start) };
14485 $   DWORD               ret   = 0;
14486 
14487 $   if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) &&
14488         vlc.hProcess && vlc.hThread)
14489         {
14490 $       if (child)
14491             {
14492 $           assert (wnd == child);                                           //-V547
14493 $           SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess);  //-V107
14494             }
14495 
14496 $       if (!async)
14497             {
14498 $           WaitForSingleObject (vlc.hProcess, INFINITE);
14499 $           GetExitCodeProcess  (vlc.hProcess, &ret) asserted;
14500             }
14501 
14502 $       if (!child)
14503             {
14504 $           CloseHandle (vlc.hProcess) asserted;
14505             }
14506 
14507 $       CloseHandle (vlc.hThread) asserted;
14508 
14509 $       return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret);  //-V105
14510         }
14511     else
14512         {
14513 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s",
14514                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos));
14515 $       if (child)
14516             {$ txDestroyWindow (child); }
14517 
14518 $       return INT_MIN+4;  //-V112 //-V109
14519         }
14520 
14521     #undef PROCESS_UID_
14522     }
14523 
14524 //-----------------------------------------------------------------------------------------------------------------
14525 
14526 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/)
14527     {
14528 $1  return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd);
14529     }
14530 
14531 //-----------------------------------------------------------------------------------------------------------------
14532 
14533 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
14534     {
14535     const UINT_PTR checkTimer = 1;
14536 
14537     switch (msg)
14538         {
14539         case WM_CREATE:
14540             {
14541 $1          SetTimer  (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted;
14542             }
14543             break;
14544 
14545         case WM_DESTROY:
14546             {
14547 $1          KillTimer (wnd, checkTimer) asserted;
14548 
14549 $           HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14550 
14551 $           if (vlc)
14552                 {
14553 $               Win32::TerminateProcess (vlc, 0);
14554 
14555 $               CloseHandle (vlc) asserted;
14556 
14557 $               SetWindowLongPtr (wnd, GWLP_USERDATA, 0);
14558                 }
14559             }
14560             break;
14561 
14562         case WM_TIMER:
14563             {
14564             HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14565 
14566             if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT)
14567                 {
14568 $1              DestroyWindow (wnd) asserted;
14569                 }
14570             }
14571             break;
14572 
14573         default:  //-V2522
14574             break;
14575         }
14576 
14577     return DefWindowProc (wnd, msg, wpar, lpar);
14578     }
14579 
14580 //-----------------------------------------------------------------------------------------------------------------
14581 
14582 const char* _txPlayVideo_FindVLC()
14583     {
14584 $1  static char vlcPath [MAX_PATH] = "";
14585 
14586 $   if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL))
14587         {
14588         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14589         }
14590 
14591 $   if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL))
14592         {
14593         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14594         }
14595 
14596 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath)))
14597         {
14598         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14599         }
14600 
14601 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath)))
14602         {
14603 $       strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX);
14604 
14605         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14606         }
14607 
14608 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files"    "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14609         {
14610         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14611         }
14612 
14613 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14614         {
14615         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14616         }
14617 
14618 $   return NULL;
14619     }
14620 
14621 //-----------------------------------------------------------------------------------------------------------------
14622 
14623 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/)
14624     {
14625 $1  static double oldPercent = 100;
14626 
14627     if (percent < 0) {$ percent    = MIN (oldPercent, 100); }
14628     else             {$ oldPercent = percent;               }
14629 
14630 $   HRESULT res = S_FALSE;
14631 
14632     #if defined (__ITaskbarList3_INTERFACE_DEFINED__)
14633 
14634 $   HRESULT init = Win32::CoInitialize (NULL);
14635 
14636 $   bool ok = true;
14637 $   res = S_OK;
14638 
14639 $   ITaskbarList3* taskbar = NULL;
14640     if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); }
14641 $   ok &= !!taskbar && (res == S_OK);
14642 
14643     if (!wnd)              {$ wnd = txWindow(); }
14644     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14645     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14646 
14647     if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); }
14648     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14649     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14650 
14651     if (taskbar) {$ taskbar->Release(); }
14652 
14653     if (init == S_OK) {$ Win32::CoUninitialize(); }
14654 
14655     #endif
14656 
14657     (void) type; (void) wnd;
14658 
14659 $   return res;
14660     }
14661 
14662 #endif // TX_COMPILED
14663 
14664 //-----------------------------------------------------------------------------------------------------------------
14665 
14666 // +--<<< Это не те символы, что вы ищете :)
14667 // V      Полезно смотреть не только вверх, но и вниз
14668 
14669 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/)
14670     {
14671 $1  WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc;
14672 $   return  old;
14673     }
14674 
14675 //-----------------------------------------------------------------------------------------------------------------
14676 
14677 //     +--<<< А это, наконец, искомое определение этой функции.
14678 //     |      Смотрите по сторонам! Нужная вам функция где-то рядом.
14679 //     |
14680 //     v
14681 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()
14682     {
14683     txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n"
14684 
14685                   "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n"
14686 
14687                   "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. "
14688                   "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n"
14689 
14690                   "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом "
14691                   "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n"
14692 
14693                   "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы "
14694                   "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n",
14695 
14696                   "Не получилось", MB_ICONSTOP);
14697 
14698     // The truth is out there... (C++files)
14699 
14700     return false;
14701     }
14702 
14703 //-----------------------------------------------------------------------------------------------------------------
14704 
14705 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you.
14706 
14707 inline bool txDisableAutoPause()
14708     {
14709     _txExit = true;
14710     return true;
14711     }
14712 
14713 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword.
14714 
14715 //-----------------------------------------------------------------------------------------------------------------
14716 
14717 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14718 
14719 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/)
14720     {
14721 $1  assert (!_txIsBadReadPtr (address));
14722 
14723 $   const unsigned char* addr = (const unsigned char*) address;
14724 
14725 $   const int stdout_fileno = 1;           // Not all g++ packages contain STDOUT_FILENO
14726 $   const int _o_u16text    = 0x00020000;  // and _O_U16TEXT
14727 
14728 $   bool     istty   = _txIsTTY (1);
14729 
14730 $   int      mode    = _O_TEXT;
14731 $   int      oldMode = _setmode (stdout_fileno, mode);
14732 
14733 $   unsigned oldCP   =       GetConsoleOutputCP();
14734 $   unsigned cp      = 1251; SetConsoleOutputCP (cp);  //-V581
14735 
14736 $   unsigned attr    = txGetConsoleAttr();
14737 
14738 $   txSetConsoleAttr (FOREGROUND_WHITE);
14739 $   printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : ""));
14740 
14741 $   txSetConsoleAttr (FOREGROUND_YELLOW);
14742 $   for (unsigned x = 0; x < 16; x++) printf ("%02X ", x);
14743 $   for (unsigned x = 0; x < 16; x++) printf ("%X",    x);
14744 
14745 $   const wchar_t* xlat[33] = {L"\xB7"   /* 00 - NUL - NULL             */, L"\x263A" /* 01 - SOH - Start of header      */,
14746                                L"\x263B" /* 02 - STX - Start of text    */, L"\x2665" /* 03 - ETX - End of text          */,
14747                                L"\x2666" /* 04 - EOT - End of transm.   */, L"\x2663" /* 05 - ENQ - Enquiry              */,
14748                                L"\x2660" /* 06 - ACK - Acknowledgment   */, L"\x2022" /* 07 - BEL - Bell                 */,
14749                                L"\x25D8" /* 08 - BS  - Backspace        */, L"\x25CB" /* 09 - HT  - Horizontal tab       */,
14750                                L"\x25D9" /* 10 - LF  - Line feed        */, L"\x2642" /* 11 - VT  - Vertical tab         */,
14751                                L"\x2640" /* 12 - FF  - Form feed        */, L"\x266A" /* 13 - CR  - Carriage return      */,
14752                                L"\x266B" /* 14 - SO  - Shift out        */, L"\x263C" /* 15 - SI  - Shift in             */,
14753                                L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1     */,
14754                                L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3     */,
14755                                L"\xB6"   /* 20 - DC4 - Device control 4 */, L"\xA7"   /* 21 - NAK - Negative ACK         */,
14756                                L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */,
14757                                L"\x2191" /* 24 - CAN - Cancel           */, L"\x2193" /* 25 - EM  - End of medium        */,
14758                                L"\x2192" /* 26 - SUB - Substitute       */, L"\x2190" /* 27 - ESC - Escape               */,
14759                                L"\x221F" /* 28 - FS  - File separator   */, L"\x2194" /* 29 - GS  - Group separator      */,
14760                                L"\x25B2" /* 30 - RS  - Record separator */, L"\x25BC" /* 31 - US  - Unit separator       */,
14761                                L"\x20"   /* 32 - Space */};
14762 
14763 $   for (int y = 0; y < 16; y++, addr += 16)
14764         {
14765         if (cp   != 1251) SetConsoleOutputCP (cp = 1251);  //-V581
14766         (void)_setmode (stdout_fileno, mode = oldMode);
14767 
14768         txSetConsoleAttr (FOREGROUND_YELLOW);
14769 
14770         printf ("\n" "%*p ", (int) sizeof (address) * 2, addr);
14771 
14772         int color = FOREGROUND_LIGHTGREEN;
14773 
14774         for (unsigned x = 0; x < 16; x++)
14775             {
14776             txSetConsoleAttr (color + x/4%2);  //-V112
14777             printf ("%02X ", addr[x]);
14778             }
14779 
14780         for (unsigned x = 0; x < 16; x++)
14781             {
14782             txSetConsoleAttr (color + x/4%2);  //-V112
14783 
14784             unsigned char ch = addr[x];
14785 
14786             if (ch >= sizearr (xlat) || !istty)
14787                 {
14788                 if (cp   != oldCP)      SetConsoleOutputCP (cp = oldCP);  //-V581
14789                 if (mode != oldMode)    (void)_setmode (stdout_fileno, mode = oldMode);
14790 
14791                 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' ');
14792                 }
14793             else
14794                 {
14795                 if (cp   != 1251)       SetConsoleOutputCP (cp = 1251);   //-V581
14796                 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text);
14797 
14798                 wprintf (L"%lls", xlat[ch]);
14799                 }
14800             }
14801         }
14802 
14803 $   (void)_setmode (stdout_fileno, oldMode);
14804 $   printf ("\n");
14805 
14806 $   if (pause && istty)
14807         {
14808 $       txSetConsoleAttr (FOREGROUND_DARKGRAY);
14809 $       txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP);
14810         }
14811 
14812 $   txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
14813 $   printf ("\n");
14814 
14815 $   txSetConsoleAttr (attr);
14816 $   SetConsoleOutputCP (oldCP);
14817     }
14818 
14819 //-----------------------------------------------------------------------------------------------------------------
14820 
14821 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/,
14822                         bool readSource /*= true*/)
14823     {
14824 $1  unsigned attr = txGetConsoleAttr();
14825 $   txSetConsoleAttr (FOREGROUND_LIGHTCYAN);
14826 
14827 $   fprintf (stderr, "\n" "--------------------------------------------------\n"
14828                           "Трассировка стека из \"%s\" at %s:%d:\n\n"
14829                           "%s\n\n"
14830                           "--------------------------------------------------\n\n",
14831                           func, file, line, _txCaptureStackBackTrace (1, readSource));
14832 
14833 $   txSetConsoleAttr (attr);
14834     }
14835 
14836 //-----------------------------------------------------------------------------------------------------------------
14837 
14838 char* txDemangle (const char* mangledName, std::nomeow_t)
14839     {
14840 $1  if (!mangledName) return NULL;
14841 
14842 $   char* typeName = NULL;
14843 
14844     #if defined (_GCC_VER)
14845 
14846 $   int err = 1;
14847 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err;
14848     if (typeName) {$ return typeName; }
14849 
14850     #endif
14851 
14852 $   unsigned short flags = 0;
14853 
14854 $   if (mangledName[0] == '.')
14855         {
14856 $       mangledName++;
14857 $       flags = 0x2800;  // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY
14858         }
14859 
14860 $   typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags));
14861     if (typeName) {$ return typeName; }
14862 
14863 $   return _strdup (mangledName);
14864     }
14865 
14866 //-----------------------------------------------------------------------------------------------------------------
14867 
14868 std::string txDemangle (const char* mangledName)
14869     {
14870 $1  char* typeName = txDemangle (mangledName, std::nomeow);
14871 $   std::string name (typeName? typeName : "");
14872 $   free (typeName);
14873 
14874 $   return name;
14875     }
14876 
14877 //-----------------------------------------------------------------------------------------------------------------
14878 
14879 double txQueryPerformance()
14880     {
14881 $1  int maxTime    =  500;
14882 $   int maxSamples =  100;
14883 $   POINT size     = {100, 100};
14884 
14885 $   HDC dc = _txBuffer_Create (txWindow(), &size, NULL);
14886 $   assert (dc); if (!dc) return -1;                                     //-V547
14887 
14888 $   DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1);  //-V202
14889 $   assert (mask);
14890 
14891 $   LARGE_INTEGER freq = {};
14892 $   QueryPerformanceFrequency (&freq) asserted;
14893 
14894 $   LARGE_INTEGER start = {};
14895 $   QueryPerformanceCounter (&start) asserted;
14896 
14897 $   int samples = 0;
14898 $   while (samples++ < maxSamples)
14899         {
14900 $       LARGE_INTEGER cur = {};
14901 $       QueryPerformanceCounter (&cur) asserted;
14902 
14903 $       double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart;
14904 $       if (t > maxTime) break;
14905 
14906         // Draw test scene
14907 
14908 $       for (int y = 0; y < size.y; y++)
14909         for (int x = 0; x < size.x; x++)     txSetPixel (x, y, TX_BLACK, dc);
14910 
14911 $       for (int y = 0; y < size.y; y += 10)
14912         for (int x = 0; x < size.x; x += 50) txTextOut  (x, y, "*", dc);
14913 
14914 $       txEllipse (0, 0, size.x, size.y, dc);
14915 $       txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc);
14916 
14917 $       txBitBlt (dc, size.x/2.0,          0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
14918 $       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;
14919 $       txBitBlt (dc,          0, size.y/2.0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
14920 $       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;
14921         }
14922 
14923 $   mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask);  //-V106 //-V202
14924 $   assert (mask);
14925 
14926 $   _txBuffer_Delete (&dc);
14927 
14928 $   return 3.0 * samples / sqrt (1.0 * size.x * size.y);
14929     }
14930 
14931 //-----------------------------------------------------------------------------------------------------------------
14932 
14933 unsigned txExtractColor (COLORREF color, COLORREF component)
14934     {
14935 $1  switch (component)
14936         {
14937         case TX_RED:
14938         case TX_HUE:        $ return (color >>  0) & 0xFF;
14939 
14940         case TX_GREEN:
14941         case TX_SATURATION: $ return (color >>  8) & 0xFF;
14942 
14943         case TX_BLUE:
14944         case TX_LIGHTNESS:  $ return (color >> 16) & 0xFF;
14945 
14946         default:            $ return CLR_INVALID;
14947         }
14948     }
14949 
14950 //-----------------------------------------------------------------------------------------------------------------
14951 
14952 COLORREF txRGB2HSL (COLORREF rgbColor)
14953     {
14954 $1  struct xRGB
14955         {
14956         static bool zero (double val)
14957             {
14958             const double prec = 0.001;
14959 
14960             return (fabs (val) < prec);
14961             }
14962         };
14963 
14964 $   double r  = txExtractColor (rgbColor, TX_RED)   / 255.0,  //-V2551
14965            g  = txExtractColor (rgbColor, TX_GREEN) / 255.0,  //-V2551
14966            b  = txExtractColor (rgbColor, TX_BLUE)  / 255.0,  //-V2551
14967 
14968            m1 = MAX (MAX (r, g), b),
14969            m2 = MIN (MIN (r, g), b),
14970            dm = m1 - m2,
14971            sm = m1 + m2,
14972 
14973            h  = 0,
14974            s  = 0,
14975            l  = sm / 2;
14976 
14977 $   if (!xRGB::zero (dm))
14978         {
14979 $       sm = (sm <= 1)? sm : (2-sm);
14980 $       s = (!xRGB::zero (sm))? dm/sm : 0;
14981 
14982 $       double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0,
14983                cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0,
14984                cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0;
14985 
14986 $       if (xRGB::zero (r - m1)) h =     cb - cg;
14987 $       if (xRGB::zero (g - m1)) h = 2 + cr - cb;
14988 $       if (xRGB::zero (b - m1)) h = 4 + cg - cr;
14989         }
14990 
14991 $   h = (h >= 0)? h*60 : h*60 + 360;
14992 
14993 $   return RGB (ROUND (h / 360.0 * 256), ROUND (s * 255), ROUND (l * 255));
14994     }
14995 
14996 //-----------------------------------------------------------------------------------------------------------------
14997 
14998 COLORREF txHSL2RGB (COLORREF hslColor)
14999     {
15000 $1  struct xRGB
15001         {
15002         static double calc (double h, double m1, double m2)
15003             {
15004 $2          while (h < 0)   h += 360;
15005 $           while (h > 360) h -= 360;
15006 
15007 $           return (h <  60)? m1 + (m2-m1) *      h  / 60 :
15008                    (h < 180)? m2 :
15009                    (h < 240)? m1 + (m2-m1) * (240-h) / 60 :
15010                               m1;
15011             }
15012         };
15013 
15014 $   int    si = txExtractColor (hslColor, TX_SATURATION);
15015 
15016 $   double h  = txExtractColor (hslColor, TX_HUE)        / 256.0 * 360,
15017            s  = txExtractColor (hslColor, TX_SATURATION) / 255.0,
15018            l  = txExtractColor (hslColor, TX_LIGHTNESS)  / 255.0,
15019 
15020            m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s,
15021            m1 = 2 * l - m2,
15022 
15023            r = (si)? xRGB::calc (h + 120, m1, m2) : l,
15024            g = (si)? xRGB::calc (h,       m1, m2) : l,
15025            b = (si)? xRGB::calc (h - 120, m1, m2) : l;
15026 
15027 $   return RGB (ROUND (r * 255), ROUND (g * 255), ROUND (b * 255));
15028     }
15029 
15030 //-----------------------------------------------------------------------------------------------------------------
15031 
15032 void tx_fpreset()
15033     {
15034 $1  txAutoLock _lock;
15035 
15036 $   Win32::_fpreset();
15037 
15038 $   unsigned new87 = 0x0008001C;  // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW
15039 
15040     #if !defined (__CYGWIN__)
15041 
15042 $   unsigned old87 = 0;
15043 $   if (_controlfp_s (&old87, 0, 0) == 0)
15044         {$ (void) _controlfp_s (&old87, old87  & ~new87, 0x0008001F); }  // _MCW_EM
15045 
15046     #else
15047 
15048 $   Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F);    // _MCW_EM
15049 
15050     #endif
15051     }
15052 
15053 #endif // TX_COMPILED
15054 
15055 //-----------------------------------------------------------------------------------------------------------------
15056 
15057 #if defined (_TX_CPP11)
15058 template <int txFramesToAverage>
15059 #endif
15060 
15061 double txGetFPS (int minFrames)
15062     {
15063 $1  static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0);
15064 $                     LARGE_INTEGER time  = {};                      QueryPerformanceCounter (&time);
15065 
15066 $   if (time.QuadPart - time0.QuadPart == 0)
15067         {$ return 0; }
15068 
15069 $   LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq);
15070 
15071 $   double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart);
15072 $   time0 = time;
15073 
15074 $   if (txFramesToAverage == 0) return fps;
15075 
15076 $   static _tx_thread double average [txFramesToAverage] = {};
15077 $   static _tx_thread unsigned n = 0;
15078 
15079 $   average [n++ % txFramesToAverage] = fps;
15080 
15081 $   unsigned nn = MIN (n, (unsigned) sizearr (average));
15082 
15083 $   fps = 0;
15084 $   for (unsigned i = 0; i < nn; i++) fps += average[i];
15085 $   fps /= nn;
15086 
15087 $   return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0;
15088     }
15089 
15090 //-----------------------------------------------------------------------------------------------------------------
15091 
15092 template <typename T>
15093 inline T zero() { T __zero = {}; return __zero; }
15094 
15095 //-----------------------------------------------------------------------------------------------------------------
15096 
15097 inline double random (std::nomeow_t, double left, double right)
15098     {
15099     return left + (right - left) * ((double) rand() / RAND_MAX);
15100     }
15101 
15102 //-----------------------------------------------------------------------------------------------------------------
15103 
15104 template <typename Tx, typename Ta, typename Tb>
15105 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b)
15106     {
15107     return a <= x && x <= b;
15108     }
15109 
15110 //-----------------------------------------------------------------------------------------------------------------
15111 
15112 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)
15113     {
15114     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15115     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15116 
15117     return In (std::nomeow, pt.x, rect.left, rect.right) &&
15118            In (std::nomeow, pt.y, rect.top,  rect.bottom);
15119     }
15120 
15121 //-----------------------------------------------------------------------------------------------------------------
15122 
15123 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect)
15124     {
15125     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15126     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15127 
15128     return In (std::nomeow, pt.X, rect.Left, rect.Right) &&
15129            In (std::nomeow, pt.Y, rect.Top,  rect.Bottom);
15130     }
15131 
15132 //-----------------------------------------------------------------------------------------------------------------
15133 
15134 inline int random (int range)
15135     {
15136     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15137 
15138     return rand() % range;
15139     }
15140 
15141 //-----------------------------------------------------------------------------------------------------------------
15142 
15143 inline double random (double left, double right)
15144     {
15145     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15146 
15147     return random (std::nomeow, left, right);
15148     }
15149 
15150 //-----------------------------------------------------------------------------------------------------------------
15151 
15152 template <typename Tx, typename Ta, typename Tb>
15153 inline bool In (Tx x, Ta a, Tb b)
15154     {
15155     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15156 
15157     return In (std::nomeow, x, a, b);
15158     }
15159 
15160 //-----------------------------------------------------------------------------------------------------------------
15161 
15162 inline bool In (const POINT& pt, const RECT& rect)
15163     {
15164     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15165 
15166     return In (std::nomeow, pt, rect);
15167     }
15168 
15169 //-----------------------------------------------------------------------------------------------------------------
15170 
15171 inline bool In (const COORD& pt, const SMALL_RECT& rect)
15172     {
15173     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15174 
15175     return In (std::nomeow, pt, rect);
15176     }
15177 
15178 //}
15179 //=================================================================================================================
15180 
15181 //=================================================================================================================
15182 //{          txPrintf() implementation
15183 //           Реализация txPrintf()
15184 //=================================================================================================================
15185 
15186 #if defined (_TX_CPP11)
15187 
15188 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt,                                  const T& arg, ArgsT... args);
15189 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);
15190 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);
15191 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);
15192                                          void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15193 
15194 template <typename T>                    void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg);
15195                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int*     arg);
15196                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15197 
15198 //-----------------------------------------------------------------------------------------------------------------
15199 
15200 template <typename T, typename... ArgsT>
15201 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args)
15202     {
15203 $1  assert (fmt);
15204 
15205 $   _txPrintV (stream, format, n,   fmt);
15206 
15207     if (fmt[0] == '%') {$}
15208     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15209 
15210 $   _txPrintV (stream, format, n,   fmt, arg);
15211 
15212 $   _txPrintF (stream, format, n+1, fmt, args...);
15213     }
15214 
15215 //-----------------------------------------------------------------------------------------------------------------
15216 
15217 template <typename T, typename... ArgsT>
15218 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args)
15219     {
15220 $1  assert (&stream);
15221 $   assert (fmt);
15222 
15223 $   _txPrintV (stream, format, n,   fmt);
15224 
15225     if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); }  //-V2006
15226     else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); }
15227 
15228 $   _txPrintV (stream, format, n,   fmt, arg);
15229 
15230 $   _txPrintF (stream, format, n+1, fmt, args...);
15231     }
15232 
15233 //-----------------------------------------------------------------------------------------------------------------
15234 
15235 template <typename T, typename... ArgsT>
15236 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args)
15237     {
15238 $1  assert (&stream);
15239 $   assert (fmt);
15240 
15241 $   _txPrintV (stream, format, n,   fmt);
15242 
15243     if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((std::streamsize) (prec + 1)); }  //-V2006 //-V1028
15244     else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); }
15245 
15246 $   _txPrintV (stream, format, n,   fmt, arg);
15247 
15248 $   _txPrintF (stream, format, n+1, fmt, args...);
15249     }
15250 
15251 //-----------------------------------------------------------------------------------------------------------------
15252 
15253 template <typename T, typename... ArgsT>
15254 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args)
15255     {
15256 $1  assert (&stream);
15257 $   assert (fmt);
15258 
15259 $   _txPrintV (stream, format, n,   fmt);
15260 
15261     if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((std::streamsize) (prec + 1)); }  //-V2006 //-V1028
15262     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); }
15263 
15264 $   _txPrintV (stream, format, n,   fmt, arg);
15265 
15266 $   _txPrintF (stream, format, n+1, fmt, args...);
15267     }
15268 
15269 //-----------------------------------------------------------------------------------------------------------------
15270 
15271 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt)
15272     {
15273 $1  assert (fmt);
15274 
15275 $   _txPrintV (stream, format, n,   fmt);
15276 
15277     if (!fmt[0]) {$}
15278     else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); }
15279     }
15280 
15281 //-----------------------------------------------------------------------------------------------------------------
15282 
15283 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt)
15284     {
15285 $1  assert (&stream);
15286 $   assert (fmt);
15287 
15288 $   while (*fmt)
15289         {
15290         if (fmt[0] == '%')
15291             {
15292             if (fmt[1] == '%') fmt++;
15293             else break;
15294             }
15295 
15296         stream << *fmt++;
15297         }
15298 $   }
15299 
15300 //-----------------------------------------------------------------------------------------------------------------
15301 
15302 template <typename T>
15303 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg)
15304     {
15305 $1  assert (&stream);
15306 $   assert (fmt);
15307 
15308 $   if (_TX_ARGUMENT_FAILED (&arg)) return;
15309 
15310     if (fmt[0] == '%') {$}
15311     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15312 
15313 $   fmt++;
15314 
15315 $   char                    oldFill  = stream.fill (' ');
15316 $   std::ios_base::fmtflags oldFlags = stream.flags();
15317 
15318 $   for (;;) switch (*fmt)
15319         {
15320         case '-': $ stream << std::left;     fmt++; break;
15321         case '+': $ stream << std::showpos;  fmt++; break;
15322         case ' ': $ stream.fill (' ');       fmt++; break;
15323         case '#': $ stream << std::showbase; fmt++; break;
15324         case '0': $ stream.fill ('0');       fmt++; break;
15325 
15326         default:  $ goto end;
15327         }
15328     end:
15329 
15330 $   int width = (*fmt != '*')?                  (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0);
15331 $   int prec  = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0;
15332 
15333     if (width) {$ stream << std::setw (width);        }
15334     if (prec)  {$ stream << std::setprecision (prec); }
15335 
15336 $   fmt += strspn (fmt, "hljztL");
15337 
15338 $   switch (*fmt)
15339         {
15340         case '$':
15341         case '?': $                                              break;
15342 
15343         case 'd':
15344         case 'i':
15345         case 'u': $ stream << std::dec;                          break;
15346 
15347         case 'o': $ stream << std::oct;                          break;
15348 
15349         case 'x': $ stream << std::hex;                          break;
15350         case 'X': $ stream << std::hex        << std::uppercase; break;
15351 
15352         case 'f': $ stream << std::fixed;                        break;
15353         case 'F': $ stream << std::fixed      << std::uppercase; break;
15354 
15355         case 'e': $ stream << std::scientific;                   break;
15356         case 'E': $ stream << std::scientific << std::uppercase; break;
15357 
15358         case 'g': $                                              break;
15359         case 'G': $ stream                    << std::uppercase; break;
15360 
15361         case 'a': $                                              break;
15362         case 'A': $ stream                    << std::uppercase; break;
15363 
15364         case 'c':
15365         case 's':
15366         case 'p': $                                              break;
15367 
15368         default:  $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break;
15369         }
15370 
15371 $   fmt++;
15372 
15373     if (&arg) {$ stream << arg;      }
15374     else      {$ stream << "(null)"; }
15375 
15376 $   stream.fill  (oldFill);
15377 $   stream.flags (oldFlags);
15378     }
15379 
15380 //-----------------------------------------------------------------------------------------------------------------
15381 
15382 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg)  //-V2009
15383     {
15384 $1  assert (fmt);
15385 
15386     if (_TX_ARGUMENT_FAILED (arg)) return;
15387 
15388     if (fmt[0] == '%' && fmt[1] == 'n') {$}
15389     else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); }
15390 
15391 $   *arg = (int) stream.str().length();  //-V202
15392 
15393 $   fmt += 2;
15394     }
15395 
15396 //-----------------------------------------------------------------------------------------------------------------
15397 
15398 template <typename T> inline const T&    _txPrintfNormalizeArg (const T&           arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;}          return arg;         }
15399                       inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); }
15400 
15401 //-----------------------------------------------------------------------------------------------------------------
15402 
15403 template <typename... ArgsT>
15404 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args)
15405     {
15406 $1  if (_TX_ARGUMENT_FAILED (&stream)) return 0;
15407 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15408 
15409 $   const char* fmt = format;
15410 $   _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...);
15411 
15412 $   return (int) stream.str().length();  //-V202
15413     }
15414 
15415 //-----------------------------------------------------------------------------------------------------------------
15416 
15417 template <typename... ArgsT>
15418 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args)
15419     {
15420 $1  if (_TX_ARGUMENT_FAILED (&buffer)) return 0;
15421 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15422 
15423 $   if (size > 0) size--;
15424 $   buffer[size] = 0;
15425 
15426 $   if (!size) return 0;
15427 
15428 $   std::ostringstream stream;
15429 $   stream.rdbuf() -> pubsetbuf (buffer, size);
15430 
15431 $   txPrintf (stream, format, args...);
15432 
15433 $   return (int) stream.str().length();  //-V202
15434     }
15435 
15436 //-----------------------------------------------------------------------------------------------------------------
15437 
15438 template <typename... ArgsT>
15439 inline std::string txFormat (const char* format, ArgsT... args)
15440     {
15441 $1  if (_TX_ARGUMENT_FAILED (&format)) return "";
15442 
15443 $   std::ostringstream stream;
15444 
15445 $   txPrintf (stream, format, args...);
15446 
15447 $   return stream.str();
15448     }
15449 
15450 //-----------------------------------------------------------------------------------------------------------------
15451 
15452 template <typename... ArgsT>
15453 inline int txPrintf (const char* format, ArgsT... args)
15454     {
15455 $1  if (_TX_ARGUMENT_FAILED (&format)) return 0;
15456 
15457 $   return printf ("%s", txFormat (format, args...) .c_str());
15458     }
15459 
15460 #endif
15461 
15462 //-----------------------------------------------------------------------------------------------------------------
15463 
15464        int _txPrintfCheck (const char* format, ...) tx_printfy (1);
15465 inline int _txPrintfCheck (const char*,        ...) { return 0; }
15466 
15467 //}
15468 //=================================================================================================================
15469 
15470 //=================================================================================================================
15471 //{          txDialog methods implementation
15472 //           Реализация методов класса txDialog
15473 //
15474 //           See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx
15475 //               [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743
15476 //               [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753
15477 //=================================================================================================================
15478 
15479 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
15480 
15481 txDialog::txDialog () :
15482     layout_ (NULL)
15483     {$1}
15484 
15485 //-----------------------------------------------------------------------------------------------------------------
15486 
15487 txDialog::txDialog (const Layout* layout) :
15488     layout_ (layout)
15489     {$1}
15490 
15491 //-----------------------------------------------------------------------------------------------------------------
15492 
15493 const txDialog::Layout* txDialog::setLayout (const Layout* layout)
15494     {
15495 $1  assert (layout);
15496 
15497 $   return ::std::swap (layout_, layout), layout;
15498     }
15499 
15500 //-----------------------------------------------------------------------------------------------------------------
15501 
15502 intptr_t txDialog::dialogBox (WORD resourceID)
15503     {
15504 $1  const char* resName = (char*)(uintptr_t) resourceID;
15505 
15506 $   if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0;
15507 
15508 $   return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15509     }
15510 
15511 //-----------------------------------------------------------------------------------------------------------------
15512 
15513 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/)
15514     {
15515 $1  if (!layout)  layout = layout_;
15516 $   if (!layout)  return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0;
15517 
15518 $   if (!bufsize) bufsize = 1024;
15519 
15520 $   DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize);
15521 $   if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0;
15522 
15523 $   const Layout* dlg = &layout[0];
15524 $   const Layout  def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 };
15525 
15526 $   void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize,
15527                                        (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0,
15528                                         dlg->x, dlg->y, dlg->sx, dlg->sy,
15529                                         dlg->caption?  dlg->caption  : def.caption,
15530                                         dlg->font?     dlg->font     : def.font,
15531                                         dlg->fontsize? dlg->fontsize : def.fontsize, NULL);
15532 $   WORD i = 0;
15533 $   for (i = 1; layout[i].wndclass != END; ++i)
15534         {
15535 $       const Layout* item = &layout[i];
15536 
15537 $       ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl),
15538                                    item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy,
15539                                    item->id, (const char*)(uintptr_t) item->wndclass, item->caption);
15540         }
15541 
15542 $   tmpl->cdit = (unsigned short) (i-1);
15543 
15544 $   intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15545 
15546 $   GlobalFree (tmpl);
15547 
15548 $   return res;
15549     }
15550 
15551 //-----------------------------------------------------------------------------------------------------------------
15552 
15553 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM)
15554     {
15555 $1  switch (msg)
15556         {
15557         case WM_INITDIALOG: $ SetForegroundWindow (wnd);
15558                             $ break;
15559 
15560         case WM_COMMAND:    $ switch (LOWORD (wParam))
15561             {
15562             case IDOK:
15563             case IDCANCEL:  $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow());
15564                             $ EndDialog (wnd, (uintptr_t) this);
15565                             $ break;
15566 
15567             default:        $ break;
15568             }
15569                             $ break;
15570         default:            $ break;
15571         }
15572 
15573 $   return FALSE;
15574     }
15575 
15576 //-----------------------------------------------------------------------------------------------------------------
15577 
15578 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
15579     {
15580 $1  static txDialog* this__ = NULL;
15581 $   if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam;
15582 $   if (!this__) return FALSE;
15583 
15584 $   return this__-> dialogProc (wnd, msg, wParam, lParam);  //-V109
15585     }
15586 
15587 //-----------------------------------------------------------------------------------------------------------------
15588 
15589 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
15590                               WORD controls, short x, short y, short cx, short cy,
15591                               const char caption[], const char font[], WORD fontsize, const char menu[])
15592     {
15593 $1  if (_TX_ARGUMENT_FAILED (globalMem)) return NULL;
15594 
15595 $   WORD* pw = (WORD*) globalMem;
15596 
15597 $   DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++;
15598 
15599 $   tmpl->style = style;
15600 $   tmpl->dwExtendedStyle = exStyle;
15601 $   tmpl->cdit  = controls;
15602 $   tmpl->x     = x;
15603 $   tmpl->y     = y;
15604 $   tmpl->cx    = cx;
15605 $   tmpl->cy    = cy;
15606 
15607 $   if (menu > (const char*) 0xFFFF)
15608         {
15609 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (menu?    menu    : ""), -1, (wchar_t*) pw,           //-V547
15610                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15611         }
15612     else
15613         {
15614 $       *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0);
15615 $       *pw++ = (WORD)(uintptr_t)  menu;
15616         }
15617 
15618 $   if (caption)
15619         {
15620 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw,           //-V547
15621                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15622         }
15623 
15624 $   if (style & DS_SETFONT)
15625         {
15626 $       *pw++ = fontsize;
15627 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, (font?    font    : ""), -1, (wchar_t*) pw,
15628                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15629         }
15630 
15631 $   return pw;
15632     }
15633 
15634 //-----------------------------------------------------------------------------------------------------------------
15635 
15636 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
15637                            short x, short y, short cx, short cy,
15638                            WORD id, const char wclass[], const char caption[])
15639     {
15640 $1  if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL;
15641 
15642 $   WORD* pw = (LPWORD) dlgTemplatePtr;  // Force align at word boundary
15643 $   ((ULONG&) pw)  += 3;  //-V205
15644 $   ((ULONG&) pw) >>= 2;  //-V205
15645 $   ((ULONG&) pw) <<= 2;  //-V205
15646 
15647 $   DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++;
15648 
15649 $   tmpl->style = style;
15650 $   tmpl->dwExtendedStyle = exStyle;
15651 $   tmpl->x     = x;
15652 $   tmpl->y     = y;
15653 $   tmpl->cx    = cx;
15654 $   tmpl->cy    = cy;
15655 $   tmpl->id    = id;
15656 
15657 $   if (HIWORD (wclass) == 0xFFFF)
15658         {
15659 $       *pw++ = (WORD) (HIWORD ((uintptr_t) wclass));
15660 $       *pw++ = (WORD) (LOWORD ((uintptr_t) wclass));
15661         }
15662     else if (wclass)
15663         {
15664 $       pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw,
15665                                    (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));   //-V202
15666         }
15667     else
15668         {
15669 $       *pw++ = 0;
15670         }
15671 
15672 $   if (caption)
15673          {
15674 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw,
15675                                     (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));  //-V202
15676          }
15677     else
15678         {
15679 $       *pw++ = 0;
15680         }
15681 
15682 $   *pw++ = 0;
15683 
15684 $   return pw;
15685     }
15686 
15687 #endif // TX_COMPILED
15688 
15689 //}
15690 //=================================================================================================================
15691 
15692 //=================================================================================================================
15693 //{          Cleaning up the utility macros
15694 //           Очистка служебных макросов
15695 //=================================================================================================================
15696 
15697 #undef       $
15698 #undef       $0
15699 #undef       $1
15700 #undef       $2
15701 #undef       $3
15702 #undef       $4
15703 #undef       $5
15704 #undef       $6
15705 #undef       $7
15706 #undef       $8
15707 #undef       $9
15708 #undef       $$
15709 
15710 //}
15711 //=================================================================================================================
15712 
15714 
15715 //=================================================================================================================
15716 //{          Experimental Debugging macros
15718 //=================================================================================================================
15719 
15720 //{----------------------------------------------------------------------------------------------------------------
15840 //}----------------------------------------------------------------------------------------------------------------
15841 
15842 #ifndef __TX_DEBUG_MACROS
15843 #define __TX_DEBUG_MACROS  ("Группа отладочных $-макросов")
15844 
15846 //-----------------------------------------------------------------------------------------------------------------
15847 
15848 #define $H            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_BLACK);
15849 #define $B            txSetConsoleAttr (FOREGROUND_BLUE         | BACKGROUND_BLACK);
15850 #define $G            txSetConsoleAttr (FOREGROUND_GREEN        | BACKGROUND_BLACK);
15851 #define $C            txSetConsoleAttr (FOREGROUND_CYAN         | BACKGROUND_BLACK);
15852 #define $R            txSetConsoleAttr (FOREGROUND_RED          | BACKGROUND_BLACK);
15853 #define $M            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_BLACK);
15854 #define $Y            txSetConsoleAttr (FOREGROUND_DARKYELLOW   | BACKGROUND_BLACK);
15855 #define $d            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_BLACK);
15856 #define $D            txSetConsoleAttr (FOREGROUND_DARKGRAY     | BACKGROUND_BLACK);
15857 #define $b            txSetConsoleAttr (FOREGROUND_LIGHTBLUE    | BACKGROUND_BLACK);
15858 #define $g            txSetConsoleAttr (FOREGROUND_LIGHTGREEN   | BACKGROUND_BLACK);
15859 #define $c            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLACK);
15860 #define $r            txSetConsoleAttr (FOREGROUND_LIGHTRED     | BACKGROUND_BLACK);
15861 #define $m            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK);
15862 #define $y            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLACK);
15863 #define $h            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_BLACK);
15864 
15865 #define $i            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLUE);
15866 #define $I            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLUE);
15867 #define $o            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_GREEN);
15868 #define $O            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_GREEN);
15869 #define $e            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_RED);
15870 #define $E            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_RED);
15871 #define $w            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA);
15872 #define $W            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_MAGENTA);
15873 #define $f            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_LIGHTRED);
15874 #define $F            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_LIGHTRED);
15875 #define $l            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_DARKGRAY);
15876 #define $L            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_DARKGRAY);
15877 
15878 #define $T( cond )    txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED );
15879 
15880 #define $s            _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__);
15881 
15882 #define $sH           $s $H
15883 #define $sB           $s $B
15884 #define $sG           $s $G
15885 #define $sC           $s $C
15886 #define $sR           $s $R
15887 #define $sM           $s $M
15888 #define $sY           $s $Y
15889 #define $sd           $s $d
15890 #define $sD           $s $D
15891 #define $sb           $s $b
15892 #define $sg           $s $g
15893 #define $sc           $s $c
15894 #define $sr           $s $r
15895 #define $sm           $s $m
15896 #define $sy           $s $y
15897 #define $sh           $s $h
15898 
15899 #define $si           $s $i
15900 #define $sI           $s $I
15901 #define $so           $s $o
15902 #define $sO           $s $O
15903 #define $se           $s $e
15904 #define $sE           $s $E
15905 #define $sw           $s $w
15906 #define $sW           $s $W
15907 #define $sf           $s $f
15908 #define $sF           $s $F
15909 #define $sl           $s $l
15910 #define $sL           $s $L
15911 
15912 #define $sT( cond )   $s $T (cond)
15913 
15914 #define $test(cond)   { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \
15915                         else          { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; }
15916 
15917 #define $status(cond) $test (cond)
15918 
15919 #define $unittest( code, expected )                                                                                             \
15920     {                                                                                                                           \
15921     const _tx_decltype (code)     & _result   = (code);       /* Should use auto, but g++ 4.7.2 default std is < 2011 */        \
15922     const _tx_decltype (expected) & _expected = (expected);                                                                     \
15923                                                                                                                                 \
15924     if (_result == _expected)                                                                                                   \
15925         { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; }                                                            \
15926     else                                                                                                                        \
15927         { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \
15928                                                                                                                                 \
15929     $n;                                                                                                                         \
15930     (_result == _expected);                                                                                                     \
15931     }
15932 
15933 //=================================================================================================================
15934 
15935 #define $V(  var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]\n") )
15936 #define $V_( var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "] " ) )
15937 #define $V__(var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]"  ) )
15938 
15939 #define $(   var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n") )
15940 #define $_(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] " ) )
15941 #define $__( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]"  ) )
15942 
15943 #define $x(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) )
15944 #define $x_( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] ",  ::std::ios_base::showbase | ::std::ios_base::hex) )
15945 
15946 #define $v(  var, cond, ...)  { { $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" ); } $n; }
15947 #define $v_( var, cond, ...)  {   $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" );       }
15948 
15949 #define $$                    { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__);                                   } txOutputDebugPrintf ("\f\n"); }
15950 #define $$_                   { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]",           __LINE__, __func__);                                          } txOutputDebugPrintf ("\f\n"); }
15951 #define $meow(...)            { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); }
15952 
15953 #define $$$(   ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
15954 #define $$$_(  ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),  "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
15955 
15956 #define $$$$(  ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
15957 #define $$$$_( ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         (  "[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
15958 #define $do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n";                                                                                           __VA_ARGS__
15959 #define $DO(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p;                                                                                    __VA_ARGS__
15960 #define $Do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n";                                                                                        \
15961                                 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__);                                                                      __VA_ARGS__
15962 
15963 #define $n                    { ::std::cerr << "\n";   }
15964 #define $nn                   { ::std::cerr << "\n\n"; }
15965 #define $t                    { ::std::cerr << "\t";   }
15966 
15967 #define _tx$PrefixV(    ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": "          ) : ("["          ) )
15968 #define _tx$Prefix(var, ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") )
15969 
15970 //-----------------------------------------------------------------------------------------------------------------
15971 
15972 // This will never be documented, he-he. Read the source, Luke.
15973 
15974 #if defined (_DEBUG)
15975     #define $dbg               if (1)
15976     #define $DBG               if (1)
15977     #define $debug             if (1)
15978     #define $DEBUG             if (1)
15979     #define $printf(fmt, ...)  if (1)  printf (        fmt, ##__VA_ARGS__)
15980     #define $PRINTF(fmt, ...)  if (1) fprintf (stderr, fmt, ##__VA_ARGS__)
15981 #else
15982     #define $dbg               if (0)
15983     #define $DBG               if (0)
15984     #define $debug             if (0)
15985     #define $DEBUG             if (0)
15986     #define $printf(...)       if (0)  printf (        fmt, ##__VA_ARGS__)
15987     #define $PRINTF(...)       if (0) fprintf (stderr, fmt, ##__VA_ARGS__)
15988 #endif
15989 
15990 #define $$d    $debug
15991 #define $$w    $$$$
15992 #define $$s    __TX_FILELINE__
15993 #define $$b    { txSleep(); DebugBreak(); }
15994 #define $$p    { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \
15995                                                     __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); }
15996 #define $$P    (     txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) )
15997 #define $ppp   { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); }
15998 #define $pp    { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__,        __TX_FUNCTION__); }
15999 #define $p     { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__);        }
16000 #define $ppp_  { $sy; txPause ("\v[%s ""%s]...",                    __TX_FILELINE__, __TX_FUNCTION__); }
16001 #define $pp_   { $sy; txPause ("\v[%04d %s]...",                    __LINE__,        __TX_FUNCTION__); }
16002 #define $p_    { $sy; txPause ("\v[%s ""%s()]...",                  __TX_FILELINE__, __func__);        }
16003 #define $P     ( txPause ("") )
16004 
16005 //-----------------------------------------------------------------------------------------------------------------
16006 
16007 struct _txSaveConsoleAttr
16008     {
16009     unsigned attr_;
16010 
16011              _txSaveConsoleAttr()           : attr_ (txGetConsoleAttr ()) {}
16012     explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr);  }
16013             ~_txSaveConsoleAttr()                                         { txSetConsoleAttr (attr_); }
16014     };
16015 
16016 //-----------------------------------------------------------------------------------------------------------------
16017 
16018 struct _txDumpVarSuffix
16019     {
16020     typedef _txDumpVarSuffix this_t;
16021 
16022     const char* suffix_;
16023 
16024     explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); }
16025             ~_txDumpVarSuffix()                          { ::std::cerr << suffix_; }
16026 
16027             _txDumpVarSuffix (const this_t&) _tx_delete;
16028     this_t& operator =       (const this_t&) _tx_delete;
16029     };
16030 
16031 //-----------------------------------------------------------------------------------------------------------------
16032 
16033 #define ARGS__        const char* prefix, const char* suffix, std::ios_base::fmtflags flags,                             int deep
16034 #define ARGS_         const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0
16035 #define VALS_         prefix, suffix, flags, deep
16036 #define ERRPTR_(p)  { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; }
16037 
16038 template <typename T, typename StreamT> const T&    _txDumpVal (const T& value, StreamT& stream, ARGS_);
16039 
16040 //-----------------------------------------------------------------------------------------------------------------
16041 
16042 template <typename T> inline const T&               _txDumpVar (const T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16043 template <typename T> inline       T&               _txDumpVar (      T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16044 
16045 template <int N>      inline const char           (&_txDumpVar (const char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16046 template <int N>      inline       char           (&_txDumpVar (      char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16047 
16048 template <int N>      inline const wchar_t        (&_txDumpVar (const wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16049 template <int N>      inline       wchar_t        (&_txDumpVar (      wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16050 
16051                       inline const wchar_t&         _txDumpVar (const wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16052                       inline       wchar_t&         _txDumpVar (      wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16053 
16054                       inline const wchar_t*&        _txDumpVar (const wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16055                       inline       wchar_t*&        _txDumpVar (      wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16056 
16057                       inline const std::wstring&    _txDumpVar (const std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16058                       inline       std::wstring&    _txDumpVar (      std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16059 
16060 //-----------------------------------------------------------------------------------------------------------------
16061 
16062 template <typename T, typename StreamT> inline void _txDumpVal (const T&            value, StreamT& stream) { stream <<         value;         }
16063 template             <typename StreamT> inline void _txDumpVal (const char          value, StreamT& stream) { stream <<  "'" << value <<  "'"; }
16064 template             <typename StreamT> inline void _txDumpVal (const wchar_t       value, StreamT& stream) { stream << L"'" << value << L"'"; }
16065 template             <typename StreamT> inline void _txDumpVal (const std::string&  value, StreamT& stream) { stream <<  '"' << value <<  '"'; }
16066 template             <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; }
16067 
16068 template             <typename StreamT> inline void _txDumpVal (const char*         value, StreamT& stream)
16069     {
16070     if (_TX_ARGUMENT_FAILED (&stream)) return;
16071 
16072     if (!_txIsBadReadPtr (value)) stream <<  '"' << value <<  '"';
16073     else if (!value)              stream <<  "(null)";
16074     else                          ERRPTR_ (value);
16075     }
16076 
16077 template             <typename StreamT> inline void _txDumpVal (const wchar_t*      value, StreamT& stream)
16078     {
16079     if (_TX_ARGUMENT_FAILED (&stream)) return;
16080 
16081     if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"';
16082     else if (!value)              stream << L"(null)";
16083     else                          ERRPTR_ (value);
16084     }
16085 
16086 //-----------------------------------------------------------------------------------------------------------------
16087 
16088 template <typename T, typename StreamT>
16089 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__)
16090     {
16091     if (_TX_ARGUMENT_FAILED (&stream)) return value;  //-V778
16092     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16093     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16094 
16095     $sc;
16096     if (!deep) stream << prefix;
16097 
16098     std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags());
16099 
16100     if (!_txIsBadReadPtr (&value))
16101         {
16102         _txDumpVal (value, stream);
16103         }
16104     else
16105         ERRPTR_ (&value);
16106 
16107     stream.flags (old);
16108 
16109     if (!deep) stream << suffix;
16110 
16111     return value;
16112     }
16113 
16114 //-----------------------------------------------------------------------------------------------------------------
16115 
16116 template <typename T, int N>
16117 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N]
16118     {
16119     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16120     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16121 
16122     std::ostream& stream = std::cerr;
16123 
16124     $sc; if (!deep) std::cerr << prefix;
16125     $C;  std::cerr << ((deep)? " {" : "{");
16126 
16127     if (!_txIsBadReadPtr (value))
16128         {
16129         for (int i = 0; ; i++)
16130             {
16131             { $sC; stream << "[" << i << "]="; }
16132 
16133             _txDumpVar (value[i], prefix, suffix, flags, deep+1);
16134 
16135             if (i >= N-1) break;
16136 
16137             stream << ", ";
16138             }
16139         }
16140     else
16141         ERRPTR_ (&value);
16142 
16143     $C; std::cerr << "}";
16144     $c; if (!deep) std::cerr << suffix;
16145 
16146     return value;
16147     }
16148 
16149 //=================================================================================================================
16150 
16151 inline std::ostream& operator << (std::ostream& stream, const POINT& point)
16152     {
16153     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16154 
16155     if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }";           // NOLINT (clang-diagnostic-undefined-bool-conversion)
16156     else if (!&point)              stream << "(null)";
16157     else ERRPTR_ (&point);
16158 
16159     return stream;
16160     }
16161 
16162 inline std::ostream& operator << (std::ostream& stream, const SIZE& size)
16163     {
16164     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16165 
16166     if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }";          // NOLINT (clang-diagnostic-undefined-bool-conversion)
16167     else       stream << "(null)";
16168 
16169     return stream;
16170     }
16171 
16172 inline std::ostream& operator << (std::ostream& stream, const RECT& rect)
16173     {
16174     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16175 
16176     if (&rect) stream << "{ left: "  << rect.left  << ", top: "    << rect.top    <<  // NOLINT (clang-diagnostic-undefined-bool-conversion)
16177                          ", right: " << rect.right << ", bottom: " << rect.bottom << " }";
16178 
16179     else       stream << "(null)";
16180 
16181     return stream;
16182     }
16183 
16184 //-----------------------------------------------------------------------------------------------------------------
16185 
16186 #undef ARGS__
16187 #undef ARGS_
16188 #undef VALS_
16189 #undef ERRPTR_
16190 
16191 //-----------------------------------------------------------------------------------------------------------------
16193 
16194 #endif
16195 
16196 //}
16197 //=================================================================================================================
16198 
16200 
16201 //=================================================================================================================
16202 //{          TXAPI calls tracing
16203 //           Трассировка вызовов TXAPI
16204 //=================================================================================================================
16205 
16206 #ifndef   FOR_DOXYGEN_ONLY
16207 
16208 #if defined (_MSC_VER)
16209 #undef  _txLocCurSet
16210 #define _txLocCurSet()                 __txLocCurSet (__FILE__, __LINE__, NULL)
16211 #endif
16212 
16213 #define txAlphaBlend(...)              ( _txLocCurSet(), txAlphaBlend          (__VA_ARGS__) )
16214 #define txArc(...)                     ( _txLocCurSet(), txArc                 (__VA_ARGS__) )
16215 #define txBegin(...)                   ( _txLocCurSet(), txBegin               (__VA_ARGS__) )
16216 #define txBitBlt(...)                  ( _txLocCurSet(), txBitBlt              (__VA_ARGS__) )
16217 #define txChord(...)                   ( _txLocCurSet(), txChord               (__VA_ARGS__) )
16218 #define txCircle(...)                  ( _txLocCurSet(), txCircle              (__VA_ARGS__) )
16219 #define txClear(...)                   ( _txLocCurSet(), txClear               (__VA_ARGS__) )
16220 #define txClearConsole(...)            ( _txLocCurSet(), txClearConsole        (__VA_ARGS__) )
16221 #define txColor(...)                   ( _txLocCurSet(), txColor               (__VA_ARGS__) )
16222 #define txCreateCompatibleDC(...)      ( _txLocCurSet(), txCreateCompatibleDC  (__VA_ARGS__) )
16223 #define txCreateDIBSection(...)        ( _txLocCurSet(), txCreateDIBSection    (__VA_ARGS__) )
16224 #define txCreateExtraWindow(...)       ( _txLocCurSet(), txCreateExtraWindow   (__VA_ARGS__) )
16225 #define txCreateWindow(...)            ( _txLocCurSet(), txCreateWindow        (__VA_ARGS__) )
16226 #define txDC(...)                      ( _txLocCurSet(), txDC                  (__VA_ARGS__) )
16227 #define txDeleteDC(...)                ( _txLocCurSet(), txDeleteDC            (__VA_ARGS__) )
16228 #define txDemangle(...)                ( _txLocCurSet(), txDemangle            (__VA_ARGS__) )
16229 #define txDestroyWindow(...)           ( _txLocCurSet(), txDestroyWindow       (__VA_ARGS__) )
16230 #define txDisableAutoPause(...)        ( _txLocCurSet(), txDisableAutoPause    (__VA_ARGS__) )
16231 #define txDrawText(...)                ( _txLocCurSet(), txDrawText            (__VA_ARGS__) )
16232 #define txEllipse(...)                 ( _txLocCurSet(), txEllipse             (__VA_ARGS__) )
16233 #define txEnd(...)                     ( _txLocCurSet(), txEnd                 (__VA_ARGS__) )
16234 #define txExtractColor(...)            ( _txLocCurSet(), txExtractColor        (__VA_ARGS__) )
16235 #define txFillColor(...)               ( _txLocCurSet(), txFillColor           (__VA_ARGS__) )
16236 #define txFloodFill(...)               ( _txLocCurSet(), txFloodFill           (__VA_ARGS__) )
16237 #define txFontExist(...)               ( _txLocCurSet(), txFontExist           (__VA_ARGS__) )
16238 #define txFormat(...)                  ( _txLocCurSet(), txFormat              (__VA_ARGS__) )
16239 #define txGetAsyncKeyState(...)        ( _txLocCurSet(), txGetAsyncKeyState    (__VA_ARGS__) )
16240 #define txGetColor(...)                ( _txLocCurSet(), txGetColor            (__VA_ARGS__) )
16241 #define txGetConsoleAttr(...)          ( _txLocCurSet(), txGetConsoleAttr      (__VA_ARGS__) )
16242 #define txGetConsoleCursorPos(...)     ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) )
16243 #define txGetConsoleExtent(...)        ( _txLocCurSet(), txGetConsoleExtent    (__VA_ARGS__) )
16244 #define txGetConsoleFontSize(...)      ( _txLocCurSet(), txGetConsoleFontSize  (__VA_ARGS__) )
16245 #define txGetExtent(...)               ( _txLocCurSet(), txGetExtent           (__VA_ARGS__) )
16246 #define txGetExtentX(...)              ( _txLocCurSet(), txGetExtentX          (__VA_ARGS__) )
16247 #define txGetExtentY(...)              ( _txLocCurSet(), txGetExtentY          (__VA_ARGS__) )
16248 #define txGetFillColor(...)            ( _txLocCurSet(), txGetFillColor        (__VA_ARGS__) )
16249 #define txGetFPS(...)                  ( _txLocCurSet(), txGetFPS              (__VA_ARGS__) )
16250 #define txGetModuleFileName(...)       ( _txLocCurSet(), txGetModuleFileName   (__VA_ARGS__) )
16251 #define txGetPixel(...)                ( _txLocCurSet(), txGetPixel            (__VA_ARGS__) )
16252 #define txGetTextExtent(...)           ( _txLocCurSet(), txGetTextExtent       (__VA_ARGS__) )
16253 #define txGetTextExtentX(...)          ( _txLocCurSet(), txGetTextExtentX      (__VA_ARGS__) )
16254 #define txGetTextExtentY(...)          ( _txLocCurSet(), txGetTextExtentY      (__VA_ARGS__) )
16255 #define txHSL2RGB(...)                 ( _txLocCurSet(), txHSL2RGB             (__VA_ARGS__) )
16256 #define txInputBox(...)                ( _txLocCurSet(), txInputBox            (__VA_ARGS__) )
16257 #define txLine(...)                    ( _txLocCurSet(), txLine                (__VA_ARGS__) )
16258 #define txLoadImage(...)               ( _txLocCurSet(), txLoadImage           (__VA_ARGS__) )
16259 #define txLock(...)                    ( _txLocCurSet(), txLock                (__VA_ARGS__) )
16260 #define txMessageBox(...)              ( _txLocCurSet(), txMessageBox          (__VA_ARGS__) )
16261 #define txMouseButtons(...)            ( _txLocCurSet(), txMouseButtons        (__VA_ARGS__) )
16262 #define txMousePos(...)                ( _txLocCurSet(), txMousePos            (__VA_ARGS__) )
16263 #define txMouseX(...)                  ( _txLocCurSet(), txMouseX              (__VA_ARGS__) )
16264 #define txMouseY(...)                  ( _txLocCurSet(), txMouseY              (__VA_ARGS__) )
16265 #define txNotifyIcon(...)              ( _txLocCurSet(), txNotifyIcon          (__VA_ARGS__) )
16266 #define txOK(...)                      ( _txLocCurSet(), txOK                  (__VA_ARGS__) )
16267 #define txOutputDebugPrintf(...)       ( _txLocCurSet(), txOutputDebugPrintf   (__VA_ARGS__) )
16268 #define txPause(...)                   ( _txLocCurSet(), txPause               (__VA_ARGS__) )
16269 #define txPie(...)                     ( _txLocCurSet(), txPie                 (__VA_ARGS__) )
16270 #define txPixel(...)                   ( _txLocCurSet(), txPixel               (__VA_ARGS__) )
16271 #define txPlaySound(...)               ( _txLocCurSet(), txPlaySound           (__VA_ARGS__) )
16272 #define txPlayVideo(...)               ( _txLocCurSet(), txPlayVideo           (__VA_ARGS__) )
16273 #define txPolygon(...)                 ( _txLocCurSet(), txPolygon             (__VA_ARGS__) )
16274 #define txPrintf(...)                  ( _txLocCurSet(), txPrintf              (__VA_ARGS__) )
16275 #define txQueryPerformance(...)        ( _txLocCurSet(), txQueryPerformance    (__VA_ARGS__) )
16276 #define txRectangle(...)               ( _txLocCurSet(), txRectangle           (__VA_ARGS__) )
16277 #define txRedrawWindow(...)            ( _txLocCurSet(), txRedrawWindow        (__VA_ARGS__) )
16278 #define txRegisterClass(...)           ( _txLocCurSet(), txRegisterClass       (__VA_ARGS__) )
16279 #define txRegQuery(...)                ( _txLocCurSet(), txRegQuery            (__VA_ARGS__) )
16280 #define txReopenStdio(...)             ( _txLocCurSet(), txReopenStdio         (__VA_ARGS__) )
16281 #define txRGB2HSL(...)                 ( _txLocCurSet(), txRGB2HSL             (__VA_ARGS__) )
16282 #define txSaveImage(...)               ( _txLocCurSet(), txSaveImage           (__VA_ARGS__) )
16283 #define txSelectFont(...)              ( _txLocCurSet(), txSelectFont          (__VA_ARGS__) )
16284 #define txSelectObject(...)            ( _txLocCurSet(), txSelectObject        (__VA_ARGS__) )
16285 #define txSetColor(...)                ( _txLocCurSet(), txSetColor            (__VA_ARGS__) )
16286 #define txSetConsoleAttr(...)          ( _txLocCurSet(), txSetConsoleAttr      (__VA_ARGS__) )
16287 #define txSetConsoleCursorPos(...)     ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) )
16288 #define txSetDefaults(...)             ( _txLocCurSet(), txSetDefaults         (__VA_ARGS__) )
16289 #define txSetFillColor(...)            ( _txLocCurSet(), txSetFillColor        (__VA_ARGS__) )
16290 #define txSetLocale(...)               ( _txLocCurSet(), txSetLocale           (__VA_ARGS__) )
16291 #define txSetPixel(...)                ( _txLocCurSet(), txSetPixel            (__VA_ARGS__) )
16292 #define txSetProgress(...)             ( _txLocCurSet(), txSetProgress         (__VA_ARGS__) )
16293 #define txSetTextAlign(...)            ( _txLocCurSet(), txSetTextAlign        (__VA_ARGS__) )
16294 #define txSetWindowsHook(...)          ( _txLocCurSet(), txSetWindowsHook      (__VA_ARGS__) )
16295 #define txSleep(...)                   ( _txLocCurSet(), txSleep               (__VA_ARGS__) )
16296 #define txSpeak(...)                   ( _txLocCurSet(), txSpeak               (__VA_ARGS__) )
16297 #define txTextCursor(...)              ( _txLocCurSet(), txTextCursor          (__VA_ARGS__) )
16298 #define txTextOut(...)                 ( _txLocCurSet(), txTextOut             (__VA_ARGS__) )
16299 #define txTransparentBlt(...)          ( _txLocCurSet(), txTransparentBlt      (__VA_ARGS__) )
16300 #define txTriangle(...)                ( _txLocCurSet(), txTriangle            (__VA_ARGS__) )
16301 #define txUnlock(...)                  ( _txLocCurSet(), txUnlock              (__VA_ARGS__) )
16302 #define txUpdateWindow(...)            ( _txLocCurSet(), txUpdateWindow        (__VA_ARGS__) )
16303 #define txUseAlpha(...)                ( _txLocCurSet(), txUseAlpha            (__VA_ARGS__) )
16304 #define txVersion(...)                 ( _txLocCurSet(), txVersion             (__VA_ARGS__) )
16305 #define txVersionNumber(...)           ( _txLocCurSet(), txVersionNumber       (__VA_ARGS__) )
16306 #define txWindow(...)                  ( _txLocCurSet(), txWindow              (__VA_ARGS__) )
16307 #define tx_fpreset(...)                ( _txLocCurSet(), tx_fpreset            (__VA_ARGS__) )
16308 #define tx_glGetError(...)             ( _txLocCurSet(), tx_glGetError         (__VA_ARGS__) )
16309 #define _txDump(...)                   ( _txLocCurSet(), _txDump               (__VA_ARGS__) )
16310 #define _txStackBackTrace(...)         ( _txLocCurSet(), _txStackBackTrace     (__VA_ARGS__) )
16311 
16312 #endif
16313 
16314 //}
16315 //=================================================================================================================
16316 
16318 //}
16319 //=================================================================================================================
16320 
16321 //-----------------------------------------------------------------------------------------------------------------
16322 //{          The namespaces
16323 //-----------------------------------------------------------------------------------------------------------------
16324 
16327 _TX_END_NAMESPACE
16328 
16331 using namespace TX;                    // Allow easy usage of TXLib functions
16332 
16333 using ::std::cin;                      // Predefined usings to avoid "using namespace std"
16334 using ::std::cout;
16335 using ::std::cerr;
16336 using ::std::string;
16337 using ::std::wcin;
16338 using ::std::wcout;
16339 using ::std::wcerr;
16340 using ::std::wstring;
16341 
16342 //}
16343 //-----------------------------------------------------------------------------------------------------------------
16344 
16345 //-----------------------------------------------------------------------------------------------------------------
16346 //{          Compiler- and platform-specific
16347 //           Адаптация к компиляторам и платформам
16348 //-----------------------------------------------------------------------------------------------------------------
16350 
16351 #if defined (_GCC_VER)
16352 
16353     #pragma GCC optimize               "strict-aliasing"
16354 
16355     #pragma GCC pop_options
16356     #pragma GCC diagnostic pop
16357 
16358     #endif
16359 
16360 #if defined (_CLANG_VER)
16361 
16362     #pragma clang diagnostic pop
16363 
16364     #endif
16365 
16366 //-----------------------------------------------------------------------------------------------------------------
16367 
16368 #if defined (_MSC_VER)
16369 
16370     #pragma warning (pop)              // Restoring maximum level
16371 
16372     #endif
16373 
16374 #if defined (__INTEL_COMPILER)
16375 
16376     #pragma warning (default:  174)    // Remark: expression has no effect
16377     #pragma warning (default:  304)    // Remark: access control not specified ("public" by default)
16378     #pragma warning (default:  444)    // Remark: destructor for base class "..." is not virtual
16379     #pragma warning (default:  522)    // Remark: function redeclared "inline" after being called
16380     #pragma warning (default: 1684)    // Conversion from pointer to same-sized integral type (potential portability problem)
16381 
16382     #pragma warning (disable:  981)    // Remark: operands are evaluated in unspecified order
16383 
16384     #endif
16385 
16387 //}
16388 //-----------------------------------------------------------------------------------------------------------------
16389 
16390 #endif // __TXLIB_H_INCLUDED
16391 
16392 //=================================================================================================================
16393 // EOF                                                                                                             
16394 //=================================================================================================================
16395                                                                                                                    
16396                                                                                                                    
16397                                                                                                                    
16398                                                                                                                    
16399