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

TXLib.h

См. документацию.
00001 //=================================================================================================================
00002 //           TXLib.h - Библиотека Тупого Художника (The Dumb Artist Library, TX Library, TXLib) - (C) Ilya Dedinsky
00003 //=================================================================================================================
00004 //           [These sections are for folding control  in Code::Blocks]         [$Date: 2025-08-17 06:00:49 +0400 $]
00005 //           [Best viewed with "Fold all on file open" option enabled]         [Best screen/page width = 120 chars]
00006 //                                                                                                                 
00007 //           [If RUSSIAN CHARS below are UNREADABLE, check this file codepage. It should be CP1251, NOT UTF-8 etc.]
00008 //{          [Use RELOAD options in your IDE or editor (CLion / Visual Studio Code / ...), and do NOT use Convert.]
00009 //=================================================================================================================
00102 //           $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $
00103 //-----------------------------------------------------------------------------------------------------------------
00110 //}
00111 //=================================================================================================================
00112 
00113 #if !defined (__TXLIB_H_INCLUDED)                                            // <<< THE CODE IS HERE, UNFOLD IT <<<
00114 #define       __TXLIB_H_INCLUDED
00115 
00116 //-----------------------------------------------------------------------------------------------------------------
00117 //{          Version information and configuration
00118 //-----------------------------------------------------------------------------------------------------------------
00119 
00120 //{----------------------------------------------------------------------------------------------------------------
00142 //}----------------------------------------------------------------------------------------------------------------
00144 
00145 #define _TX_VER      _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-08-17 06:00:49 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00146 #define _TX_VERSION  _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-08-17 06:00:49 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00147 #define _TX_AUTHOR   _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-08-17 06:00:49 +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__) && !defined (__clang__)
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 works only 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/install proper compiler.
00756     #error ---------------------------------------------------------------------------------------
00757     #error
00758 
00759 #endif
00760 
00761 //-----------------------------------------------------------------------------------------------------------------
00762 
00763 #if defined (_GCC_VER) && (_GCC_VER >= 492)
00764 #if defined (TX_USE_SPEAK) && !__has_include (<SAPI.h>)
00765 
00766     #ifdef __GNUC__
00767     #error
00768     #error ---------------------------------------------------------------------------------------
00769     #endif
00770     #error You have defined TX_USE_SPEAK, but your compiler do NOT have the library <SAPI.h>.
00771     #error
00772     #error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API
00773     #error necessary for txSpeak() to work.
00774     #error ---------------------------------------------------------------------------------------
00775     #error
00776 
00777 #endif
00778 #endif
00779 
00780 //-----------------------------------------------------------------------------------------------------------------
00781 
00782 #if !defined (WINVER)
00783     #define   WINVER                   0x0502    // Defaults to Windows XP
00784     #define   WINDOWS_ENABLE_CPLUSPLUS           // Allow use of type-limit macros in <basetsd.h>,
00785 #endif                                           //   they are allowed by default if WINVER >= 0x0600.
00786 
00787 #if !defined (_WIN32_WINNT)
00788     #define   _WIN32_WINNT             WINVER    // Defaults to the same as WINVER
00789 #endif
00790 
00791 #if !defined (_WIN32_IE)
00792     #define   _WIN32_IE                WINVER    // Defaults to the same as WINVER
00793 #endif
00794 
00795 #define stristr(  str1, str2 )         Win32::StrStrIA ((str1), (str2))
00796 #define stristrw( str1, str2 )         Win32::StrStrIW ((str1), (str2))
00797 
00798 //-----------------------------------------------------------------------------------------------------------------
00799 
00800 #define _USE_MATH_DEFINES              1         // Math.h's M_PI etc.
00801 #define __STDC_FORMAT_MACROS           1         // PRIu64 and other PR... macros
00802 #define __STDC_WANT_LIB_EXT1__         1         // String and output *_s functions
00803 
00804 #define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS  // Wow, how long. Kudos, Clang
00805 
00806 #define _ALLOW_RTCc_IN_STL             1         // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc.
00807 
00808 #define NOMINMAX                       1         // Preventing 'min' and 'max' defines in Windows.h
00809 
00810 #if defined (_DEBUG)
00811 #define _SECURE_SCL                    1         // Enable checked STL iterators to throw an exception on incorrect use
00812 #define _HAS_ITERATOR_DEBUGGING        1
00813 #define _LIBCPP_DEBUG                  1
00814 #endif
00815 
00816 #if defined (_MSC_VER) && defined (_DEBUG)
00817 
00818     #define _CRTDBG_MAP_ALLOC                    // Enable MSVCRT debug heap
00819     #define _new_dbg                   new (_NORMAL_BLOCK, __FILE__, __LINE__)
00820     #define NEW                        new (_NORMAL_BLOCK, __FILE__, __LINE__)
00821 
00822 #else
00823     #define _new_dbg                   new
00824     #define NEW                        new
00825 
00826 #endif
00827 
00828 #if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015
00829 #define _SECURE_SCL_THROWS             1
00830 #endif
00831 
00832 #define     tx_noreturn                __attribute__ (( noreturn           ))
00833 #define     tx_nodiscard               __attribute__ (( warn_unused_result ))
00834 #define     tx_deprecated              __attribute__ (( deprecated         ))
00835 #define     tx_printfy( formatArgN )   __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) ))
00836 #define     tx_scanfy(  formatArgN )   __attribute__ (( format (scanf,  (formatArgN), (formatArgN)+1) ))
00837 
00838 
00839 #if defined (_TX_CPP11)
00840 
00841     #define _tx_delete                 = delete
00842     #define _tx_default                = default
00843     #define _tx_override               override
00844     #define _tx_final                  final
00845 
00846 #else
00847 
00848     #define _tx_delete
00849     #define _tx_default
00850     #define _tx_override
00851     #define _tx_final
00852 
00853 #endif
00854 
00855 namespace std { enum nomeow_t { nomeow }; }      // Vital addition to the C++ standard. TODO: Should contact C++ std committee.
00856 
00857 //-----------------------------------------------------------------------------------------------------------------
00858 
00860 //}
00861 //-----------------------------------------------------------------------------------------------------------------
00862 
00863 //-----------------------------------------------------------------------------------------------------------------
00864 //{          The Includes
00865 //-----------------------------------------------------------------------------------------------------------------
00866 
00867 #if defined (_MSC_VER)
00868     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
00869 
00870     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
00871     #pragma warning (disable: 4005)              // 'name': macro redefinition
00872 #endif
00873 
00874 //-----------------------------------------------------------------------------------------------------------------
00875 
00876 #include <stdlib.h>
00877 #include <stdio.h>
00878 #include <string.h>
00879 #include <time.h>
00880 #include <math.h>
00881 #include <float.h>
00882 
00883 #include <vector>
00884 #include <string>
00885 #include <iostream>
00886 #include <sstream>
00887 #include <iomanip>
00888 
00889 #if !defined (__CYGWIN__)
00890 #include <conio.h>
00891 #include <direct.h>
00892 #endif
00893 
00894 #if defined (TX_COMPILED)
00895 #define WIN32_LEAN_AND_MEAN
00896 #endif
00897 
00898 #include <windows.h>
00899 #include <mmsystem.h>
00900 
00901 //-----------------------------------------------------------------------------------------------------------------
00902 //{          Compiler- and platform-specific
00904 //-----------------------------------------------------------------------------------------------------------------
00905 
00906 #if defined (_MSC_VER)
00907     #pragma warning (pop)                        // MSVC: Restore max level
00908 #endif
00909 
00910 #if defined (__STRICT_ANSI__UNDEFINED)
00911     #define  __STRICT_ANSI__                     // Redefine back
00912 #endif
00913 
00914 #if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED)
00915 
00916     #define  strncpy_s( dest, sizeof_dest, src, count )  ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
00917     #define  wcsncpy_s( dest, sizeof_dest, src, count )  ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
00918     #define  strncat_s( dest, sizeof_dest, src, count )  ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) )
00919     #define  strerror_s( buf, sizeof_buf, code        )  ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) )
00920     #define  strtok_s(   buf, delim, ctx              )  ( (void)(ctx), strtok ((buf), (delim)) )
00921     #define  fopen_s(    file, name, mode             )  ( *(file) = fopen ((name), (mode)) )
00922     #define _strlwr_s(   str, sizeof_str              )  ( _strlwr (str) )
00923 
00924     #define  ctime_s( buf, sizeof_buf, time    )         ( strncpy ((buf), ctime (time), (sizeof_buf)-1) )
00925     #define _controlfp_s( oldCtl, newCtl, mask )         ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 )
00926 
00927     #define _snprintf_s                                  snprintf
00928     #define _vsnprintf_s( str, sz, trunc, format, arg )  _vsnprintf (str, sz, format, arg)
00929 
00930 #endif
00931 
00932 #if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) )
00933 
00934     #define  getenv_s( sz, buf, sizeof_buf, name )       ({ (void)(sz); const char* _env = getenv (name); \
00935                                                             strncpy ((buf), (_env)? _env : "", (sizeof_buf)-1); })
00936 #endif
00937 
00938 #if defined (__CYGWIN__)
00939 
00940     #undef   __STRICT_ANSI__
00941 
00942     typedef  void                                _exception;
00943 
00944     #define _O_TEXT                              O_TEXT
00945     #define _fdopen                              fdopen
00946     #define _flushall()                          fflush (NULL)
00947     #define _getcwd                              getcwd
00948     #define _getpid                              getpid
00949     #define _stricmp                             strcasecmp
00950     #define _strlwr                              strlwr
00951     #define _strnicmp                            strncasecmp
00952     #define _unlink                              unlink
00953     #define _vsnprintf                           vsnprintf
00954     #define _access                              access
00955     #define _strdup                              strdup
00956 
00957     #define getch                                _getch
00958     #define putch                                _putch
00959     #define kbhit                                _kbhit
00960 
00961 #endif
00962 
00963 #if !defined (PRId64) || \
00964      defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32
00965 
00966     #undef  PRId64
00967     #undef  PRIi64
00968     #undef  PRIo64
00969     #undef  PRIu64
00970     #undef  PRIx64
00971     #undef  PRIX64
00972 
00973     #define PRId64                               "I64d"
00974     #define PRIi64                               "I64i"
00975     #define PRIo64                               "I64o"
00976     #define PRIu64                               "I64u"
00977     #define PRIx64                               "I64x"
00978     #define PRIX64                               "I64X"
00979 
00980 #endif
00981 
00982 //}
00983 //-----------------------------------------------------------------------------------------------------------------
00984 
00985 //}
00986 //-----------------------------------------------------------------------------------------------------------------
00987 
00988 //-----------------------------------------------------------------------------------------------------------------
00989 //{          The namespaces
00990 //-----------------------------------------------------------------------------------------------------------------
00991 
00992 //{----------------------------------------------------------------------------------------------------------------
00995 //}----------------------------------------------------------------------------------------------------------------
00996 
00997 #ifdef FOR_DOXYGEN_ONLY
00998 namespace { namespace TX { }}
00999 #endif
01000 
01003 //-----------------------------------------------------------------------------------------------------------------
01004 
01005 #if defined (TX_COMPILED)  &&  defined (TX_COMPILING)
01006     #undef   TX_COMPILED
01007     #endif
01008 
01009 #if !defined (TX_COMPILED) && !defined (TX_COMPILING)
01010 
01011     #define _TX_BEGIN_NAMESPACE                      namespace { namespace TX {
01012     #define _TX_END_NAMESPACE                        } }
01013 
01014 #else
01015 
01016     #define _TX_BEGIN_NAMESPACE                                  namespace TX {
01017     #define _TX_END_NAMESPACE                        }
01018 
01019 #endif
01020 
01021 //-----------------------------------------------------------------------------------------------------------------
01022 
01023 _TX_BEGIN_NAMESPACE
01024 
01027 //}
01028 //-----------------------------------------------------------------------------------------------------------------
01029 
01030 //=================================================================================================================
01031 //{          TXLIB INTERFACE
01032 //           Интерфейс библиотеки
01033 //=================================================================================================================
01034 
01035 //=================================================================================================================
01036 //{          Initialization
01038 //=================================================================================================================
01040 //{----------------------------------------------------------------------------------------------------------------
01084 //}----------------------------------------------------------------------------------------------------------------
01085 
01086 HWND txCreateWindow (double sizeX, double sizeY, bool centered = true);
01087 
01088 //{----------------------------------------------------------------------------------------------------------------
01115 //}----------------------------------------------------------------------------------------------------------------
01116 
01117 inline HDC& txDC() tx_nodiscard;
01118 
01119 //{----------------------------------------------------------------------------------------------------------------
01155 //}----------------------------------------------------------------------------------------------------------------
01156 
01157 inline RGBQUAD* txVideoMemory() tx_nodiscard;
01158 
01159 //{----------------------------------------------------------------------------------------------------------------
01178 //}----------------------------------------------------------------------------------------------------------------
01179 
01180 bool txSetDefaults (HDC dc = txDC());
01181 
01182 //{----------------------------------------------------------------------------------------------------------------
01201 //}----------------------------------------------------------------------------------------------------------------
01202 
01203 inline bool txOK() tx_nodiscard;
01204 
01205 //{----------------------------------------------------------------------------------------------------------------
01237 //}----------------------------------------------------------------------------------------------------------------
01238 
01239 POINT txGetExtent (HDC dc = txDC()) tx_nodiscard;
01240 
01241 //{----------------------------------------------------------------------------------------------------------------
01258 //}----------------------------------------------------------------------------------------------------------------
01259 
01260 inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard;
01261 
01262 //{----------------------------------------------------------------------------------------------------------------
01280 //}----------------------------------------------------------------------------------------------------------------
01281 
01282 inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard;
01283 
01284 //{----------------------------------------------------------------------------------------------------------------
01296 //}----------------------------------------------------------------------------------------------------------------
01297 
01298 inline HWND txWindow() tx_nodiscard;
01299 
01300 //{----------------------------------------------------------------------------------------------------------------
01309 //}----------------------------------------------------------------------------------------------------------------
01310 
01311 inline const char* txVersion() tx_nodiscard;
01312 
01313 //{----------------------------------------------------------------------------------------------------------------
01322 //}----------------------------------------------------------------------------------------------------------------
01323 
01324 inline unsigned txVersionNumber() tx_nodiscard;
01325 
01326 //{----------------------------------------------------------------------------------------------------------------
01356 //}----------------------------------------------------------------------------------------------------------------
01357 
01358 const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard;
01359 
01361 //{----------------------------------------------------------------------------------------------------------------
01396 //}----------------------------------------------------------------------------------------------------------------
01397 
01398 int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает",
01399                   unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL);
01400 
01401 //{----------------------------------------------------------------------------------------------------------------
01418 //}----------------------------------------------------------------------------------------------------------------
01419 
01420 HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL);
01421 
01422 //}
01423 //=================================================================================================================
01424 
01425 //=================================================================================================================
01426 //{          Setting the parameters
01428 //=================================================================================================================
01430 //{----------------------------------------------------------------------------------------------------------------
01456 //}----------------------------------------------------------------------------------------------------------------
01457 
01458 const COLORREF
01459 #ifdef FOR_DOXYGEN_ONLY
01460     enum txColors {
01461 #endif
01462 
01463     TX_BLACK         = RGB (  0,   0,   0),   
01464     TX_BLUE          = RGB (  0,   0, 128),   
01465     TX_GREEN         = RGB (  0, 128,   0),   
01466     TX_CYAN          = RGB (  0, 128, 128),   
01467     TX_RED           = RGB (128,   0,   0),   
01468     TX_MAGENTA       = RGB (128,   0, 128),   
01469     TX_BROWN         = RGB (128, 128,   0),   
01470     TX_ORANGE        = RGB (255, 128,   0),   
01471     TX_GRAY          = RGB (160, 160, 160),   
01472     TX_DARKGRAY      = RGB (128, 128, 128),   
01473     TX_LIGHTGRAY     = RGB (192, 192, 192),   
01474     TX_LIGHTBLUE     = RGB (  0,   0, 255),   
01475     TX_LIGHTGREEN    = RGB (  0, 255, 128),   
01476     TX_LIGHTCYAN     = RGB (  0, 255, 255),   
01477     TX_LIGHTRED      = RGB (255,   0, 128),   
01478     TX_LIGHTMAGENTA  = RGB (255,   0, 255),   
01479     TX_PINK          = RGB (255, 128, 255),   
01480     TX_YELLOW        = RGB (255, 255, 128),   
01481     TX_WHITE         = RGB (255, 255, 255),   
01482     TX_TRANSPARENT   = 0xFFFFFFFF,            
01483     TX_NULL          = TX_TRANSPARENT,        
01484     TX_BLM           = TX_BLACK,              
01485     TX_white         = TX_WHITE,              
01486 
01487 //  Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB()
01488 
01489     TX_HUE          = 0x04000000,             
01490     TX_SATURATION   = 0x05000000,             
01491     TX_LIGHTNESS    = 0x06000000;             
01492 
01493 #ifdef FOR_DOXYGEN_ONLY
01494     };
01495 #endif
01496 
01498 #define TX_GREY       TX_GRAY
01499 #define TX_DARKGREY   TX_DARKGRAY
01500 #define TX_LIGHTGREY  TX_LIGHTGRAY
01501 
01502 
01503 //{----------------------------------------------------------------------------------------------------------------
01528 //}----------------------------------------------------------------------------------------------------------------
01529 
01530 #ifdef FOR_DOXYGEN_ONLY
01531 COLORREF RGB (int red, int green, int blue);
01532 #endif
01533 
01534 //{----------------------------------------------------------------------------------------------------------------
01553 //}----------------------------------------------------------------------------------------------------------------
01554 
01555 HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC());
01556 
01558 #define txSetColour txSetColor
01559 
01560 
01562 
01563 //{----------------------------------------------------------------------------------------------------------------
01574 //}----------------------------------------------------------------------------------------------------------------
01575 
01576 COLORREF txColor (double red, double green, double blue);
01577 
01579 
01580 //{----------------------------------------------------------------------------------------------------------------
01593 //}----------------------------------------------------------------------------------------------------------------
01594 
01595 COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard;
01596 
01597 //{----------------------------------------------------------------------------------------------------------------
01612 //}----------------------------------------------------------------------------------------------------------------
01613 
01614 HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC());
01615 
01617 #define txSetFillColour txSetFillColor
01618 
01619 
01621 
01622 //{----------------------------------------------------------------------------------------------------------------
01633 //}----------------------------------------------------------------------------------------------------------------
01634 
01635 COLORREF txFillColor (double red, double green, double blue);
01636 
01638 
01639 //{----------------------------------------------------------------------------------------------------------------
01652 //}----------------------------------------------------------------------------------------------------------------
01653 
01654 COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard;
01655 
01656 //{----------------------------------------------------------------------------------------------------------------
01674 //}----------------------------------------------------------------------------------------------------------------
01675 
01676 unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard;
01677 
01678 //{----------------------------------------------------------------------------------------------------------------
01706 //}----------------------------------------------------------------------------------------------------------------
01707 
01708 COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard;
01709 
01710 //{----------------------------------------------------------------------------------------------------------------
01740 //}----------------------------------------------------------------------------------------------------------------
01741 
01742 COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard;
01743 
01745 //}
01746 //=================================================================================================================
01747 
01748 //=================================================================================================================
01749 //{          Drawing
01751 //=================================================================================================================
01753 //{----------------------------------------------------------------------------------------------------------------
01767 //}----------------------------------------------------------------------------------------------------------------
01768 
01769 bool txClear (HDC dc = txDC());
01770 
01771 //{----------------------------------------------------------------------------------------------------------------
01789 //}----------------------------------------------------------------------------------------------------------------
01790 
01791 inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC());
01792 
01794 
01795 //{----------------------------------------------------------------------------------------------------------------
01813 //}----------------------------------------------------------------------------------------------------------------
01814 
01815 inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC());
01816 
01818 
01819 //{----------------------------------------------------------------------------------------------------------------
01837 //}----------------------------------------------------------------------------------------------------------------
01838 
01839 inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard;
01840 
01841 //{----------------------------------------------------------------------------------------------------------------
01861 //}----------------------------------------------------------------------------------------------------------------
01862 
01863 bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC());
01864 
01865 //{----------------------------------------------------------------------------------------------------------------
01887 //}----------------------------------------------------------------------------------------------------------------
01888 
01889 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC());
01890 
01891 //{----------------------------------------------------------------------------------------------------------------
01911 //}----------------------------------------------------------------------------------------------------------------
01912 
01913 bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC());
01914 
01915 //{----------------------------------------------------------------------------------------------------------------
01935 //}----------------------------------------------------------------------------------------------------------------
01936 
01937 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC());
01938 
01939 //{----------------------------------------------------------------------------------------------------------------
01957 //}----------------------------------------------------------------------------------------------------------------
01958 
01959 bool txCircle (double x, double y, double r);
01960 
01961 //{----------------------------------------------------------------------------------------------------------------
01984 //}----------------------------------------------------------------------------------------------------------------
01985 
01986 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
01987 
01988 //{----------------------------------------------------------------------------------------------------------------
02011 //}----------------------------------------------------------------------------------------------------------------
02012 
02013 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02014 
02015 //{----------------------------------------------------------------------------------------------------------------
02038 //}----------------------------------------------------------------------------------------------------------------
02039 
02040 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02041 
02042 //{----------------------------------------------------------------------------------------------------------------
02074 //}----------------------------------------------------------------------------------------------------------------
02075 
02076 bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC());
02077 
02078 //{----------------------------------------------------------------------------------------------------------------
02096 //}----------------------------------------------------------------------------------------------------------------
02097 
02098 inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)
02099     {
02100     (void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3;
02101 
02102     txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n"
02103                   "Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами "
02104                   "как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". "
02105                   "Ну или нарисовать тремя линиями. :)", "TXLib сообщает");
02106     return false;
02107     }
02108 
02109 //{----------------------------------------------------------------------------------------------------------------
02111 
02112 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
02113 
02114 #define txRectandle  Sleep (1000), txRectangle  // Copy-protection for the function below
02115 #define txLine(...)  txLine (__VA_ARGS__); {    //
02116 #define txNotifyIcon }}}}}}}}}} txNotifyIcon    // Не спрашивайте, зачем. Это дичь.
02117 #define txCircle     ;txCircle                  //
02118 #define txSetColor   ;txSetColor                //
02119 #define C0L0RREF     COLORREF                   //
02120 #define OxFFFFFF     0xFFFFFF                   //
02121 #define lO           10                         //
02122 #define lOOO         1000                       //
02123 #define oo                                      //
02124 #define O                                       //
02125 
02127 //}
02128 
02129 //{----------------------------------------------------------------------------------------------------------------
02170 //}----------------------------------------------------------------------------------------------------------------//////
02171                                                                                                                        //
02172 inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist,   //
02173                        double head, double eyes, double wink, double crazy, double smile, double hair, double wind)    //
02174     {                                                                                                                  //
02175     const char __[] =  "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/";           //
02176     //                   |                                |                          |                  |              //
02177     // Не копипастите! _/ \_ Все равно не получится! :) _/ \_  Человечки защищают  _/ \_ этот код! :) _/ \_  Муаххаха! //
02178     //                                                                                                                 //
02179     static int count = GetTickCount(), L = 0;  
02180 
02181     C0L0RREF lineColor = txGetColor();
02182     C0L0RREF fillColor = txGetFillColor();
02183 
02184     txSetColor     (color, 3);
02185     txSetFillColor (color);
02186 
02187     txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY);
02188 
02189     txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY);
02190     txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY);
02191 
02192     txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y);
02193     txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y);
02194 
02195     txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY);
02196 
02197     txLine (x, y - (1 + head) * sizeY, x +  wind/lO        * sizeX, y - (1 + head + hair/lO) * sizeY);
02198     txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
02199     txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
02200 
02201     txSetColor     (~color & OxFFFFFF);  // Inverse the color
02202     txSetFillColor (~color & OxFFFFFF);
02203 
02204     txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
02205     txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
02206                                               oo
02207     txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]);  //-V112 //-V542
02208                                    oo
02209     // See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow
02210 
02211     txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY);
02212     txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY);
02213     Sleep (lOOO + count%2);
02214 
02215     txSetColor     ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT);
02216     txSetFillColor (TX_TRANSPARENT);
02217 
02218     txCircle (x, y, 4);  //-V112
02219     txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y);
02220 
02221     txSetColor     (lineColor);
02222     txSetFillColor (fillColor);
02223     }
02224 
02226 //}
02227 //=================================================================================================================
02228 
02229 //=================================================================================================================
02230 //{          Drawing text
02232 //=================================================================================================================
02234 //{----------------------------------------------------------------------------------------------------------------
02253 //}----------------------------------------------------------------------------------------------------------------
02254 
02255 bool txTextOut (double x, double y, const char text[], HDC dc = txDC());
02256 
02257 //{----------------------------------------------------------------------------------------------------------------
02259 
02260 #undef txRectandle
02261 #undef txLine
02262 #undef txNotifyIcon
02263 #undef txCircle
02264 #undef txSetColor
02265 #undef C0L0RREF
02266 #undef OxFFFFFF
02267 #undef lO
02268 #undef lOOO
02269 #undef oo
02270 #undef O
02271 
02273 //}
02274 
02275 //{----------------------------------------------------------------------------------------------------------------
02322 //}----------------------------------------------------------------------------------------------------------------
02323 
02324 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
02325                  unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC());
02326 
02327 //{----------------------------------------------------------------------------------------------------------------
02352 //}----------------------------------------------------------------------------------------------------------------
02353 
02354 HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1,
02355                     int bold = FW_DONTCARE, bool italic = false, bool underline = false,
02356                     bool strikeout = false, double angle = 0,
02357                     HDC dc = txDC());
02358 
02359 //{----------------------------------------------------------------------------------------------------------------
02374 //}----------------------------------------------------------------------------------------------------------------
02375 
02376 SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard;
02377 
02378 //{----------------------------------------------------------------------------------------------------------------
02392 //}----------------------------------------------------------------------------------------------------------------
02393 
02394 int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard;
02395 
02396 //{----------------------------------------------------------------------------------------------------------------
02410 //}----------------------------------------------------------------------------------------------------------------
02411 
02412 int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard;
02413 
02414 //{----------------------------------------------------------------------------------------------------------------
02441 //}----------------------------------------------------------------------------------------------------------------
02442 
02443 unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC());
02444 
02445 //{----------------------------------------------------------------------------------------------------------------
02461 //}----------------------------------------------------------------------------------------------------------------
02462 
02463 LOGFONT* txFontExist (const char name[]) tx_nodiscard;
02464 
02466 //}
02467 //=================================================================================================================
02468 
02469 //=================================================================================================================
02470 //{          Drawing to memory DC and image loading
02472 //=================================================================================================================
02474 //{----------------------------------------------------------------------------------------------------------------
02514 //}----------------------------------------------------------------------------------------------------------------
02515 
02516 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard;
02517 
02518 //{----------------------------------------------------------------------------------------------------------------
02621 //}----------------------------------------------------------------------------------------------------------------
02622 
02623 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD**  pixels = NULL) tx_nodiscard;
02624 
02626 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)        tx_nodiscard;
02628 
02629 //{----------------------------------------------------------------------------------------------------------------
02705 //}----------------------------------------------------------------------------------------------------------------
02706 
02707 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0,
02708                  unsigned imageFlags = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard;
02709 
02710 //{----------------------------------------------------------------------------------------------------------------
02742 //}----------------------------------------------------------------------------------------------------------------
02743 
02744 bool txDeleteDC (HDC  dc);
02745 
02747 bool txDeleteDC (HDC* dc);
02749 
02750 //{----------------------------------------------------------------------------------------------------------------
02790 //}----------------------------------------------------------------------------------------------------------------
02791 
02792 bool txBitBlt (HDC destImage,   double xDest,       double yDest, double width, double height,
02793                HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY);
02794 
02795 //{----------------------------------------------------------------------------------------------------------------
02810 //}----------------------------------------------------------------------------------------------------------------
02811 
02812 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0);
02813 
02814 //{----------------------------------------------------------------------------------------------------------------
02874 //}----------------------------------------------------------------------------------------------------------------
02875 
02876 bool txTransparentBlt (HDC destImage,   double xDest,       double yDest,       double width, double height,
02877                        HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK);
02878 
02879 //{----------------------------------------------------------------------------------------------------------------
02895 //}----------------------------------------------------------------------------------------------------------------
02896 
02897 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
02898                               COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0);
02899 
02900 //{----------------------------------------------------------------------------------------------------------------
03005 //}----------------------------------------------------------------------------------------------------------------
03006 
03007 bool txAlphaBlend (HDC destImage,   double xDest,       double yDest,       double width, double height,
03008                    HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0);
03009 
03010 //{----------------------------------------------------------------------------------------------------------------
03027 //}----------------------------------------------------------------------------------------------------------------
03028 
03029 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
03030                           double xSource = 0, double ySource = 0, double alpha = 1.0);
03031 
03032 //{----------------------------------------------------------------------------------------------------------------
03061 //}----------------------------------------------------------------------------------------------------------------
03062 
03063 HDC txUseAlpha (HDC image);
03064 
03065 //{----------------------------------------------------------------------------------------------------------------
03091 //}----------------------------------------------------------------------------------------------------------------
03092 
03093 bool txSaveImage (const char filename[], HDC dc = txDC());
03094 
03096 //}
03097 //=================================================================================================================
03098 
03099 //=================================================================================================================
03100 //{          Utility functions
03102 //=================================================================================================================
03104 //{----------------------------------------------------------------------------------------------------------------
03123 //}----------------------------------------------------------------------------------------------------------------
03124 
03125 double txSleep (double time = 0);
03126 
03127 //{----------------------------------------------------------------------------------------------------------------
03212 //}----------------------------------------------------------------------------------------------------------------
03213 
03214 inline int txBegin();
03215 
03216 //{----------------------------------------------------------------------------------------------------------------
03239 //}----------------------------------------------------------------------------------------------------------------
03240 
03241 inline int txEnd();
03242 
03243 //{----------------------------------------------------------------------------------------------------------------
03265 //}----------------------------------------------------------------------------------------------------------------
03266 
03267 inline void txRedrawWindow();
03268 
03269 //{----------------------------------------------------------------------------------------------------------------
03293 //}----------------------------------------------------------------------------------------------------------------
03294 
03295 inline int txUpdateWindow (int update = true);
03296 
03297 //{----------------------------------------------------------------------------------------------------------------
03314 //}----------------------------------------------------------------------------------------------------------------
03315 
03316 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC());
03317 
03318 //{----------------------------------------------------------------------------------------------------------------
03338 //
03339 //                 +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее"
03340 //                 |
03341 //                 v
03342 //               txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03347 //}----------------------------------------------------------------------------------------------------------------
03348 
03349 //     +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее"
03350 //     |
03351 //     v
03352 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03353 
03354 //{----------------------------------------------------------------------------------------------------------------
03370 //}----------------------------------------------------------------------------------------------------------------
03371 
03372 bool txDestroyWindow (HWND wnd = txWindow());
03373 
03374 //{----------------------------------------------------------------------------------------------------------------
03385 //}----------------------------------------------------------------------------------------------------------------
03386 
03387 double txQueryPerformance() tx_nodiscard;
03388 
03389 //{----------------------------------------------------------------------------------------------------------------
03404 //}----------------------------------------------------------------------------------------------------------------
03406 
03407 #if defined (_TX_CPP11)
03408     template <int txFramesToAverage = 5>
03409 #else
03410     const     int txFramesToAverage = 5;
03411 #endif
03412 
03414 
03415 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard;
03416 
03418 //}
03419 
03420 //=================================================================================================================
03421 //{          Mouse functions
03423 //=================================================================================================================
03425 //{----------------------------------------------------------------------------------------------------------------
03449 //}----------------------------------------------------------------------------------------------------------------
03450 
03451 inline POINT txMousePos() tx_nodiscard;
03452 
03453 //{----------------------------------------------------------------------------------------------------------------
03473 //}----------------------------------------------------------------------------------------------------------------
03474 
03475 inline double txMouseX() tx_nodiscard;
03476 
03477 //{----------------------------------------------------------------------------------------------------------------
03497 //}----------------------------------------------------------------------------------------------------------------
03498 
03499 inline double txMouseY() tx_nodiscard;
03500 
03501 //{----------------------------------------------------------------------------------------------------------------
03533 //}----------------------------------------------------------------------------------------------------------------
03534 
03535 inline unsigned txMouseButtons() tx_nodiscard;
03536 
03537 //{----------------------------------------------------------------------------------------------------------------
03569 //}----------------------------------------------------------------------------------------------------------------
03570 
03571 #ifdef FOR_DOXYGEN_ONLY
03572 inline Mouse& txCatchMouse (bool shouldEat = true);
03573 #endif
03574 
03576 //}
03577 //=================================================================================================================
03578 
03579 //=================================================================================================================
03580 //{          Console functions
03582 //=================================================================================================================
03584 //{----------------------------------------------------------------------------------------------------------------
03626 //}----------------------------------------------------------------------------------------------------------------
03627 
03628 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/);
03629 
03630 //{----------------------------------------------------------------------------------------------------------------
03642 //}----------------------------------------------------------------------------------------------------------------
03643 
03644 unsigned txGetConsoleAttr() tx_nodiscard;
03645 
03646 //{----------------------------------------------------------------------------------------------------------------
03660 //}----------------------------------------------------------------------------------------------------------------
03661 
03662 bool txClearConsole();
03663 
03664 //{----------------------------------------------------------------------------------------------------------------
03684 //}----------------------------------------------------------------------------------------------------------------
03685 
03686 POINT txSetConsoleCursorPos (double x, double y);
03687 
03688 //{----------------------------------------------------------------------------------------------------------------
03701 //}----------------------------------------------------------------------------------------------------------------
03702 
03703 POINT txGetConsoleCursorPos();
03704 
03705 //{----------------------------------------------------------------------------------------------------------------
03718 //}----------------------------------------------------------------------------------------------------------------
03719 
03720 POINT txGetConsoleExtent();
03721 
03722 //{----------------------------------------------------------------------------------------------------------------
03736 //}----------------------------------------------------------------------------------------------------------------
03737 
03738 POINT txGetConsoleFontSize() tx_nodiscard;
03739 
03740 //{----------------------------------------------------------------------------------------------------------------
03756 //}----------------------------------------------------------------------------------------------------------------
03757 
03758 bool txTextCursor (bool blink = true);
03759 
03761 //}
03762 //=================================================================================================================
03763 
03764 //=================================================================================================================
03765 //{          Other staff not related to drawing
03767 //=================================================================================================================
03769 //{----------------------------------------------------------------------------------------------------------------
03798 //}----------------------------------------------------------------------------------------------------------------
03799 
03800 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC);
03801 
03802 //{----------------------------------------------------------------------------------------------------------------
03860 //}----------------------------------------------------------------------------------------------------------------
03861 
03862 int txSpeak (const char* text, ...) tx_printfy (1);
03863 
03864 //{----------------------------------------------------------------------------------------------------------------
03981 //}----------------------------------------------------------------------------------------------------------------
03982 
03983 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
03984                        double zoom = 0, double gain = 1, HWND wnd = txWindow());
03985 
03986 //{----------------------------------------------------------------------------------------------------------------
04000 //}----------------------------------------------------------------------------------------------------------------
04001 
04002 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow());
04003 
04004 //{----------------------------------------------------------------------------------------------------------------
04060 //}----------------------------------------------------------------------------------------------------------------
04061 
04062 bool txGetAsyncKeyState (int key);
04063 
04064 //{----------------------------------------------------------------------------------------------------------------
04101 //}----------------------------------------------------------------------------------------------------------------
04102 
04103 #ifdef FOR_DOXYGEN_ONLY
04104 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
04105 #endif
04106 
04107 //{----------------------------------------------------------------------------------------------------------------
04132 //}----------------------------------------------------------------------------------------------------------------
04133 
04134 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1);
04135 
04136 //{----------------------------------------------------------------------------------------------------------------
04212 //}----------------------------------------------------------------------------------------------------------------
04213 
04214 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04215 
04216 template <typename T, typename... ArgsT>
04217 int txPrintf (const char* format, ArgsT... args);
04218 
04219 #define TX_PRINTF(...)  ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) )
04220 
04221 #endif
04222 
04223 //-----------------------------------------------------------------------------------------------------------------
04224 
04225 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY)
04226 
04227 enum width_t     : int {};
04228 enum precision_t : int {};
04229 
04230 inline width_t     width     (int width) { return (width_t)     width; }
04231 inline precision_t precision (int prec)  { return (precision_t) prec;  }
04232 
04233 #endif
04234 
04235 //{----------------------------------------------------------------------------------------------------------------
04254 //}----------------------------------------------------------------------------------------------------------------
04255 
04256 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04257 
04258 template <typename T, typename... ArgsT>
04259 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args);
04260 
04261 #endif
04262 
04263 //{----------------------------------------------------------------------------------------------------------------
04283 //}----------------------------------------------------------------------------------------------------------------
04284 
04285 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04286 
04287 template <typename T, typename... ArgsT>
04288 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args);
04289 
04290 #endif
04291 
04292 //{----------------------------------------------------------------------------------------------------------------
04310 //}----------------------------------------------------------------------------------------------------------------
04311 
04312 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
04313 
04314 template <typename... ArgsT>
04315 std::string txFormat (const char* format, ArgsT... args);
04316 
04317 #endif
04318 
04319 //{----------------------------------------------------------------------------------------------------------------
04391 //}----------------------------------------------------------------------------------------------------------------
04393 
04394 #define sizearr( arr )  ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) )
04395 
04397 //  See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx
04398 
04399 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N];  // ;=P
04400 
04401 //  Another approach
04402 
04403 #if defined (_TX_CPP11_MSVC15)
04404 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; }
04405 #endif
04406 
04408 
04409 #define SIZEARR( arr )  ( sizeof (arr) / sizeof ((arr)[0]) )
04410 
04412 //{----------------------------------------------------------------------------------------------------------------
04431 //}----------------------------------------------------------------------------------------------------------------
04432 
04433 inline int random (int range) tx_deprecated;
04434 
04435 //{----------------------------------------------------------------------------------------------------------------
04460 //}----------------------------------------------------------------------------------------------------------------
04461 
04462 inline double random (double left, double right)                tx_nodiscard tx_deprecated;
04463 
04464 inline double random (std::nomeow_t, double left, double right) tx_nodiscard;
04465 
04466 //{----------------------------------------------------------------------------------------------------------------
04496 //}----------------------------------------------------------------------------------------------------------------
04497 
04498 template <typename Tx, typename Ta, typename Tb>
04499 inline bool In (Tx x, Ta a, Tb b)                tx_nodiscard tx_deprecated;
04500 
04501 template <typename Tx, typename Ta, typename Tb>
04502 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated;
04503 
04504 //{----------------------------------------------------------------------------------------------------------------
04550 //}----------------------------------------------------------------------------------------------------------------
04552 
04553 inline bool In (const POINT& pt, const RECT& rect)                      tx_nodiscard tx_deprecated;
04554 inline bool In (const COORD& pt, const SMALL_RECT& rect)                tx_nodiscard tx_deprecated;
04555 
04557 
04558 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)       tx_nodiscard tx_deprecated;
04559 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated;
04560 
04561 //{----------------------------------------------------------------------------------------------------------------
04580 //}----------------------------------------------------------------------------------------------------------------
04581 
04582 #define MAX( a, b )     ( ((a) > (b))? (a) : (b) )
04583 
04584 template <typename T>
04585 T max (const T& a, const T& b) { return (a > b)? a : b; }  
04586 
04587 //{----------------------------------------------------------------------------------------------------------------
04606 //}----------------------------------------------------------------------------------------------------------------
04607 
04608 #define MIN( a, b )     ( ((a) < (b))? (a) : (b) )
04609 
04610 template <typename T>
04611 T min (const T& a, const T& b) { return (a < b)? a : b; }  
04612 
04613 //{----------------------------------------------------------------------------------------------------------------
04627 //}----------------------------------------------------------------------------------------------------------------
04628 
04629 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L  // MSVC: C99 case
04630 
04631     #define ROUND( x )  ( (long) round (x) )
04632 
04633 #else
04634 
04635     #define ROUND( x )  ( (long) floor ((x) + 0.5) )
04636 
04637 #endif
04638 
04639 //{----------------------------------------------------------------------------------------------------------------
04658 //}----------------------------------------------------------------------------------------------------------------
04659 
04660 void tx_fpreset();
04661 
04662 //{----------------------------------------------------------------------------------------------------------------
04671 //}----------------------------------------------------------------------------------------------------------------
04672 
04673 const double txPI = asin (1.0) * 2;
04674 
04675 //{----------------------------------------------------------------------------------------------------------------
04702 //}----------------------------------------------------------------------------------------------------------------
04703 
04704 inline double txSqr (double x)
04705     {
04706     double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0));  // Бурная вычислительная деятельность
04707 
04708     char str[1024] = "";
04709     _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr);
04710     txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL ||
04711         (
04712         txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION),
04713         txMessageBox ("Уйду я от вас", "Злые вы...",  MB_ICONSTOP),
04714         exit (EXIT_FAILURE), 0  //-V2509 //-V2014
04715         );
04716 
04717     txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика!  \0"  // А как это работает, а?  //-V111
04718                                      "С ума сойти...      \0"  //
04719                                      "а КЭП подтверждает  \0"  //       и кто это будет
04720                                      "Главное - отчитаться\0"  //       поддерживать?..
04721                                      "Невероятно, но факт \0"
04722                                      "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21);
04723 
04724     return sqr;  // Все же вернем значение. Мы же не звери
04725     }
04726 
04727 //{----------------------------------------------------------------------------------------------------------------
04749 //}----------------------------------------------------------------------------------------------------------------
04750 
04751 #ifdef FOR_DOXYGEN_ONLY
04752 #define _TX_DESTROY_3D
04753 #endif
04754 
04755 #if defined (_TX_DESTROY_3D)
04756 
04757     #define z  0                   // Читайте "Флатландию" Эбботта!
04758 
04759 #endif
04760 
04761 //{----------------------------------------------------------------------------------------------------------------
04778 //}----------------------------------------------------------------------------------------------------------------
04780 
04781 #define meow   ;
04782 
04783 #if defined (_MSC_VER) && !defined (_CLANG_VER)
04784 #define мяу    meow
04785 #endif
04786 
04787 #define please
04788 
04790 
04791 //{----------------------------------------------------------------------------------------------------------------
04809 //}----------------------------------------------------------------------------------------------------------------
04810 
04811 #define ZERO( type )    zero <type> ()
04812 
04814 template <typename T> inline T zero() tx_nodiscard;
04816 
04817 //{----------------------------------------------------------------------------------------------------------------
04844 //}----------------------------------------------------------------------------------------------------------------
04846 
04847 #define  tx_auto_func(    func )  _tx_auto_fun1 ( __LINE__, func )
04848 #define _tx_auto_fun1( n, func )  _tx_auto_fun2 ( n,        func )
04849 #define _tx_auto_fun2( n, func )  auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; })
04850 
04851 #define tx_finally(...)           tx_auto_func (__VA_ARGS__)
04852 
04853 template <typename T>
04854 struct _tx_auto_func_
04855     {
04856     typedef _tx_auto_func_<T> this_t;
04857     T func_;
04858 
04859     explicit _tx_auto_func_ (T func) : func_ (func) {}
04860             ~_tx_auto_func_ ()       { func_ ();     }
04861 
04862     private:         _tx_auto_func_ ()              _tx_delete;
04863                      _tx_auto_func_ (const this_t&) _tx_delete;
04864              this_t& operator =     (const this_t&) _tx_delete;
04865     };
04866 
04867 template <typename T>
04868 _tx_auto_func_<T> _tx_auto_func  (T   func)
04869     {
04870     return        _tx_auto_func_ <T> (func);
04871     }
04872 
04874 
04875 //{----------------------------------------------------------------------------------------------------------------
04920 //}----------------------------------------------------------------------------------------------------------------
04921 
04922 #if !defined (NDEBUG)
04923     #undef  TX_ASSERT
04924     #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \
04925                                                            "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 )
04926 #else
04927     #undef  TX_ASSERT
04928     #define TX_ASSERT( cond ) ((void) 1)
04929 
04930 #endif
04931 
04932 #ifdef assert
04933     #undef assert
04934 #endif
04935 
04936 #define assert( cond )        TX_ASSERT (cond)
04937 
04938 //{----------------------------------------------------------------------------------------------------------------
04965 //}----------------------------------------------------------------------------------------------------------------
04966 
04967 #if !defined (NDEBUG)
04968     #define asserted          || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.")
04969 
04970 #else
04971     #define asserted          || _txNOP (0)
04972 
04973 #endif
04974 
04975 #define verified              asserted  //!< For compatibility with assert macro
04976 
04978 #define TX_NEEDED             asserted  //!< For compatibility with earlier releases
04979 
04980 
04981 //{----------------------------------------------------------------------------------------------------------------
05009 //}----------------------------------------------------------------------------------------------------------------
05010 
05011 #if !defined (NDEBUG)
05012     #undef  verify
05013     #define verify            assert
05014 
05015 #else
05016     #undef  verify
05017     #define verify( expr )    ( expr )
05018 
05019 #endif
05020 
05021 //{----------------------------------------------------------------------------------------------------------------
05040 //}----------------------------------------------------------------------------------------------------------------
05041 
05042 #if !defined (FOR_DOXYGEN_ONLY)
05043     #define TX_ERROR( ... )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__)
05044 #else
05045     #define TX_ERROR( msg )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg)
05046 #endif
05047 
05049     #define TX_THROW          TX_ERROR  //!< For compatibility with earlier TXLib releases
05050 
05051 
05052 //{----------------------------------------------------------------------------------------------------------------
05068 //}----------------------------------------------------------------------------------------------------------------
05069 
05070 #if !defined (NDEBUG)
05071     #define TX_DEBUG_ERROR(...)  TX_ERROR (__VA_ARGS__)
05072 
05073 #else
05074     #define TX_DEBUG_ERROR(...)  ((void) 0)
05075 
05076 #endif
05077 
05078 //{----------------------------------------------------------------------------------------------------------------
05098 //}----------------------------------------------------------------------------------------------------------------
05099 
05100 #ifdef FOR_DOXYGEN_ONLY
05101 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05102 #endif
05103 
05105 
05106 #ifdef _MSC_VER
05107 #define txDump( ... )           _txDump ((const void*)(uintptr_t) __VA_ARGS__)
05108 #else
05109 #define txDump( address, ... )  _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__)
05110 #endif
05111 
05112 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05113 
05115 
05116 //{----------------------------------------------------------------------------------------------------------------
05142 //}----------------------------------------------------------------------------------------------------------------
05143 
05144 #define txStackBackTrace()    _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true);
05145 
05146 //{----------------------------------------------------------------------------------------------------------------
05168 //}----------------------------------------------------------------------------------------------------------------
05170 
05171 std::string txDemangle (const char* mangledName);
05172 char*       txDemangle (const char* mangledName, std::nomeow_t);
05173 
05174 #define txTypename(value)     txDemangle (typeid (value) .name()) .c_str()
05175 
05177 //{----------------------------------------------------------------------------------------------------------------
05204 //}----------------------------------------------------------------------------------------------------------------
05205 
05206 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue);
05207 
05208 //{----------------------------------------------------------------------------------------------------------------
05221 //}----------------------------------------------------------------------------------------------------------------
05223 
05224 #define _                     ,
05225 #define TX_COMMA              ,  //!< Синоним макроса _ (@ref _ "символ подчеркивания")
05226 
05228 
05229 //{----------------------------------------------------------------------------------------------------------------
05289 //}----------------------------------------------------------------------------------------------------------------
05290 
05291 #ifdef FOR_DOXYGEN_ONLY
05292 
05293     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType )
05294 
05295 #else
05296 
05297     // Hand-made DLLIMPORT helper
05298 
05299     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... )               \
05300             retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \
05301                                                             _txDllImport ((libName), #funcName, (required))
05302 #endif
05303 
05305 //}
05306 //=================================================================================================================
05307 
05308 //=================================================================================================================
05309 //{          Back-hole (I hope, not an ass-hole:) of the library)
05311 //=================================================================================================================
05313 //{----------------------------------------------------------------------------------------------------------------
05465 //}----------------------------------------------------------------------------------------------------------------
05466 
05467 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL);
05468 
05469 //{----------------------------------------------------------------------------------------------------------------
05494 //}----------------------------------------------------------------------------------------------------------------
05495 
05496 bool txLock (bool wait = true);
05497 
05498 //{----------------------------------------------------------------------------------------------------------------
05509 //}----------------------------------------------------------------------------------------------------------------
05511 
05512 bool txUnlock();
05513 
05515 template <typename T> inline T txUnlock (T value);
05517 
05519 
05520 //{----------------------------------------------------------------------------------------------------------------
05543 //}----------------------------------------------------------------------------------------------------------------
05544 
05545 #define txGDI( command, dc )  ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) )
05546 
05547 //{----------------------------------------------------------------------------------------------------------------
05570 //}----------------------------------------------------------------------------------------------------------------
05571 
05572 #ifndef   FOR_DOXYGEN_ONLY
05573 
05574 const int     _TX_CODEPAGE  =   1251;
05575 
05576 #ifndef __CYGWIN__
05577 const char    _TX_LOCALE[]  =  "Russian";
05578 #else
05579 const char    _TX_LOCALE[]  =  "ru_RU.CP1251";
05580 #endif
05581 
05582 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP";
05583 
05584 #endif
05585 
05586 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE);
05587 
05588 //{----------------------------------------------------------------------------------------------------------------
05603 //}----------------------------------------------------------------------------------------------------------------
05604 
05605 int txPause (const char* message, ...) tx_printfy (1);
05606 
05608 //}
05609 //=================================================================================================================
05610 
05611 //=================================================================================================================
05612 //{          Tune-up constants and variables
05614 //=================================================================================================================
05616 //{----------------------------------------------------------------------------------------------------------------
05626 //}----------------------------------------------------------------------------------------------------------------
05627 
05628 #ifndef TX_COMPILED
05629 
05630        char _txLogName[MAX_PATH]          = "~TXLog.log";
05631 
05632 #endif // TX_COMPILED
05633 
05634 extern char _txLogName[];
05635 
05636 //{----------------------------------------------------------------------------------------------------------------
05668 //}----------------------------------------------------------------------------------------------------------------
05669 
05670 #if  defined  (_TX_NOINIT)
05671 
05672     #undef     _TX_NOINIT
05673     #define    _TX_NOINIT                 1
05674 
05675 #else
05676 
05677     #define    _TX_NOINIT                 0
05678 
05679 #endif
05680 
05681 //{----------------------------------------------------------------------------------------------------------------
05725 //}----------------------------------------------------------------------------------------------------------------
05726 
05727 #if !defined (TX_CONSOLE_MODE)
05728 
05729     #define   TX_CONSOLE_MODE             SW_HIDE
05730 
05731 #endif
05732 
05733 //{----------------------------------------------------------------------------------------------------------------
05737 //}----------------------------------------------------------------------------------------------------------------
05738 
05739 #if !defined (TX_CONSOLE_FONT)
05740 
05741     #define   TX_CONSOLE_FONT             "Lucida Console"
05742 
05743 #endif
05744 
05745 //{----------------------------------------------------------------------------------------------------------------
05756 //}----------------------------------------------------------------------------------------------------------------
05757 
05758 #ifndef TX_COMPILED
05759 
05760        int _txWindowStyle                 = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
05761 
05762 #endif // TX_COMPILED
05763 
05764 extern int _txWindowStyle;
05765 
05766 //{----------------------------------------------------------------------------------------------------------------
05769 //}----------------------------------------------------------------------------------------------------------------
05770 
05771 #ifndef TX_COMPILED
05772 
05773        unsigned _txCursorBlinkInterval    = 500;
05774 
05775 #endif // TX_COMPILED
05776 
05777 extern unsigned _txCursorBlinkInterval;
05778 
05779 //{----------------------------------------------------------------------------------------------------------------
05783 //}----------------------------------------------------------------------------------------------------------------
05784 
05785 #ifndef TX_COMPILED
05786 
05787        unsigned _txWindowUpdateInterval   = 25;
05788 
05789 #endif // TX_COMPILED
05790 
05791 extern unsigned _txWindowUpdateInterval;
05792 
05793 //{----------------------------------------------------------------------------------------------------------------
05802 //}----------------------------------------------------------------------------------------------------------------
05803 
05804 #ifdef FOR_DOXYGEN_ONLY
05805 #define       TX_USE_SFML
05806 #endif
05807 
05808 //{----------------------------------------------------------------------------------------------------------------
05811 //}----------------------------------------------------------------------------------------------------------------
05812 
05813 const int _TX_TIMEOUT                     = 1000
05814 
05815 #if  defined  (_TX_ALLOW_TRACE)
05816     * 2
05817 #endif
05818 
05819 #if  defined  (TX_TRACE)
05820     * 3
05821 #endif
05822 
05823 #if  defined  (_TX_USE_DEVPARTNER)
05824     * 10
05825 #endif
05826     ;
05827 
05828 //{----------------------------------------------------------------------------------------------------------------
05869 //}----------------------------------------------------------------------------------------------------------------
05870 
05871 #ifndef TX_COMPILED
05872 
05873        bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
05874                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp) = NULL;
05875 
05876 #endif // TX_COMPILED
05877 
05878 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
05879                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp);
05880 
05881 //{----------------------------------------------------------------------------------------------------------------
05884 //}----------------------------------------------------------------------------------------------------------------
05885 
05886 const unsigned _TX_BUFSIZE                =  1024,
05887                _TX_BIGBUFSIZE             = _TX_BUFSIZE *  2,  
05888                _TX_HUGEBUFSIZE            = _TX_BUFSIZE * 20,  
05889 
05890                _TX_STACKSIZE              = 64 * 1024;         
05891 
05892 //{----------------------------------------------------------------------------------------------------------------
05895 //}----------------------------------------------------------------------------------------------------------------
05896 
05897 #if !defined (_TX_EXCEPTIONS_LIMIT)
05898     #define   _TX_EXCEPTIONS_LIMIT        16
05899 #endif
05900 
05901 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT)
05902     #define   _TX_FATAL_EXCEPTIONS_LIMIT  16                   //!< Максимальное количество фатальных исключений.
05903 #endif
05904 
05905 //{----------------------------------------------------------------------------------------------------------------
05908 //}----------------------------------------------------------------------------------------------------------------
05909 
05910 #ifdef FOR_DOXYGEN_ONLY
05911 #define       _TX_FULL_STACKTRACE
05912 #endif
05913 
05914 //{----------------------------------------------------------------------------------------------------------------
05917 //}----------------------------------------------------------------------------------------------------------------
05918 
05919 #ifndef TX_COMPILED
05920 
05921        bool _txProcessSystemWarnings      = true;
05922 
05923 #endif // TX_COMPILED
05924 
05925 extern bool _txProcessSystemWarnings;
05926 
05927 //{----------------------------------------------------------------------------------------------------------------
05941 //}----------------------------------------------------------------------------------------------------------------
05942 
05943 #if !defined  (_TX_WAITABLE_PARENTS)
05944     #define    _TX_WAITABLE_PARENTS       "Winpty-agent.exe:Clion.exe, "            /* 0: CLion32       */ \
05945                                           "Winpty-agent.exe:Clion64.exe, "          /* 1: CLion64       */ \
05946                                           "starter.exe:eclipse.exe, "               /* 2: Eclipse 4     */ \
05947                                           "starter.exe:javaw.exe, "                 /* 3: Eclipse 3     */ \
05948                                           "cmd.exe:devenv.exe, "                    /* 4: MSVS 2003+    */ \
05949                                           "VSDebugConsole.exe:devenv.exe, "         /* 5: MSVS 2019+    */ \
05950                                           "VSDebugConsole.exe:msvsmon.exe, "        /* 6: MSVS 2022 x86 */ \
05951                                           "consolepauser.exe:devcpp.exe, "          /* 7: Dev-Cpp       */ \
05952                                           "cb_console_runner.exe:codeblocks.exe"    /* 8: CodeBlocks 8+ */
05953 #endif
05954 
05955 //{----------------------------------------------------------------------------------------------------------------
05974 //}----------------------------------------------------------------------------------------------------------------
05975 
05976 #if !defined (_TX_ALLOW_KILL_PARENT)            // DISCLAIMER: Я не призываю к убийству родителей.
05977     #define   _TX_ALLOW_KILL_PARENT       true  //             Это технический термин.
05978 #endif                                          //             г_дам юристам привет.
05979 
05980 //{----------------------------------------------------------------------------------------------------------------
05990 //}----------------------------------------------------------------------------------------------------------------
05991 
05992 #ifndef TX_COMPILED
05993 
05994        int    _txWatchdogTimeout          = 10*_TX_TIMEOUT;
05995 
05996 #endif // TX_COMPILED
05997 
05998 extern int    _txWatchdogTimeout;
05999 
06000 //{----------------------------------------------------------------------------------------------------------------
06069 //}----------------------------------------------------------------------------------------------------------------
06071 
06072 #ifdef FOR_DOXYGEN_ONLY
06073 
06074     #define TX_COMPILED
06075 
06076     #endif
06077 
06079 
06081 //}
06082 //=================================================================================================================
06083 
06084 //=================================================================================================================
06085 //{          Internal diagnostics
06087 //=================================================================================================================
06089 //{----------------------------------------------------------------------------------------------------------------
06129 //}----------------------------------------------------------------------------------------------------------------
06130 
06131 #ifdef FOR_DOXYGEN_ONLY
06132 #define _TX_ALLOW_TRACE
06133 #endif
06134 
06135 //{----------------------------------------------------------------------------------------------------------------
06165 //}----------------------------------------------------------------------------------------------------------------
06166 
06167 #ifdef FOR_DOXYGEN_ONLY
06168 #define       TX_TRACE
06169 #endif
06170 
06171 #if !defined (TX_TRACE)
06172     #define   TX_TRACE  { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); }
06173 #endif
06174 
06176 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...);
06178 
06179 //{----------------------------------------------------------------------------------------------------------------
06182 
06183 #ifndef   FOR_DOXYGEN_ONLY
06184 
06185 struct _txLoc
06186     {
06187     const char*   func;
06188     const char*   file;
06189     int           line;
06190 
06191     int           inTX;   // We are inside one of TXLib functions
06192     int           trace;  // Internal TX trace level, when enabled by _TX_ALLOW_TRACE
06193 
06194     const _txLoc* prev;   // Caller's location
06195 
06196     static _txLoc _tx_thread Cur;
06197     };
06198 
06199 struct _txFuncEntry
06200     {
06201     typedef _txFuncEntry this_t;
06202 
06203     _txLoc loc;
06204 
06205     _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; }
06206     void restore()                     { _txLoc::Cur = loc;                           }
06207    ~_txFuncEntry()                     { restore();                                   }
06208 
06209     private:
06210             _txFuncEntry (const this_t&) _tx_delete;
06211     this_t& operator =   (const this_t&) _tx_delete;
06212     };
06213 
06214 #if defined (_GCC_VER)
06215 
06216     inline const char* __txLocCurSet (const char* _file, int _line, const char* _func)
06217         { _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; }
06218 
06219 #else
06220 
06221     #define __txLocCurSet( _file, _line, _func ) \
06222         ( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) )
06223 
06224 #endif
06225 
06226 #define _txLocCurSet()     __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__)
06227 
06228 #define _txLocLvlSet(lvl)  { _txLoc::Cur.trace = (lvl); }
06229 
06230 //{----------------------------------------------------------------------------------------------------------------
06231 
06232 #if defined ($0)
06233     #undef   $0
06234     #endif
06235 
06236 #if defined ($1)
06237     #undef   $1
06238     #endif
06239 
06240 #if defined ($2)
06241     #undef   $2
06242     #endif
06243 
06244 #if defined ($3)
06245     #undef   $3
06246     #endif
06247 
06248 #if defined ($4)
06249     #undef   $4
06250     #endif
06251 
06252 #if defined ($5)
06253     #undef   $5
06254     #endif
06255 
06256 #if defined ($6)
06257     #undef   $6
06258     #endif
06259 
06260 #if defined ($7)
06261     #undef   $7
06262     #endif
06263 
06264 #if defined ($8)
06265     #undef   $8
06266     #endif
06267 
06268 #if defined ($9)
06269     #undef   $9
06270     #endif
06271 
06272 #if defined ($)
06273     #undef   $
06274     #endif
06275 
06276 #if defined ($$)
06277     #undef   $$
06278     #endif
06279 
06280 //}
06281 //-----------------------------------------------------------------------------------------------------------------
06282 
06283 #if defined (_TX_ALLOW_TRACE)
06284 
06285     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl);    $;          }
06286 
06287     #define  $           { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } }
06288 
06289     #define  $$          { __txFuncEntry.restore();                                                  }
06290 
06291 #elif defined (_DEBUG)
06292 
06293     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; {                                 $;          }
06294 
06295     #define  $           { _txLocCurSet();                                                           }
06296 
06297     #define  $$          { __txFuncEntry.restore();                                                  }
06298 
06299 #else
06300 
06301     #define _txEntry(lvl)  ;
06302     #define  $             ;
06303     #define  $$            ;
06304 
06305 #endif
06306 
06307 //{----------------------------------------------------------------------------------------------------------------
06308 
06309 #define      $0            _txEntry (0)  // (Log level unchanged)
06310 #define      $1            _txEntry (1)  // Regular functions
06311 #define      $2            _txEntry (2)  // Resvd
06312 #define      $3            _txEntry (3)  // Init/Cleanup
06313 #define      $4            _txEntry (4)  // Init/Cleanup, misc functions
06314 #define      $5            _txEntry (5)  // Error handling, entry points
06315 #define      $6            _txEntry (6)  // Error handling, main part
06316 #define      $7            _txEntry (7)  // Error handling, misc functions
06317 #define      $8            _txEntry (8)  // Canvas worker thread
06318 #define      $9            _txEntry (9)  // Resvd
06319 
06320 //}
06321 //-----------------------------------------------------------------------------------------------------------------
06322 
06323 #endif // FOR_DOXYGEN_ONLY
06324 
06327 //}----------------------------------------------------------------------------------------------------------------
06328 
06330 //}
06331 //=================================================================================================================
06332 
06333 //=================================================================================================================
06334 //{          Sweet critical section blocking: txAutoLock class
06335 //=================================================================================================================
06336 
06337 //{----------------------------------------------------------------------------------------------------------------
06353 //}----------------------------------------------------------------------------------------------------------------
06354 
06356 extern CRITICAL_SECTION _txCanvas_LockBackBuf;
06358 
06359 class txAutoLock
06360     {
06361     typedef txAutoLock this_t;
06362 
06363     public:
06364 
06365 //{----------------------------------------------------------------------------------------------------------------
06388 //}----------------------------------------------------------------------------------------------------------------
06389 
06390     explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) :
06391         cs_ (cs)
06392         {
06393 $1      if (!cs_) return;
06394 
06395         if (mandatory) {$    EnterCriticalSection (cs_);                   }
06396         else           {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); }
06397         }
06398 
06399 //{----------------------------------------------------------------------------------------------------------------
06412 //}----------------------------------------------------------------------------------------------------------------
06413 
06414     explicit txAutoLock (bool mandatory = true) :
06415         cs_ (NULL)
06416         {
06417 $1      new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory);
06418         }
06419 
06420 //{----------------------------------------------------------------------------------------------------------------
06422 //}----------------------------------------------------------------------------------------------------------------
06423 
06424    ~txAutoLock()
06425         {
06426 $1      if (!cs_) return;
06427 $       LeaveCriticalSection (cs_); cs_ = NULL;
06428         }
06429 
06430 //{----------------------------------------------------------------------------------------------------------------
06433 //}----------------------------------------------------------------------------------------------------------------
06434 
06435     operator bool () const
06436         {
06437 $1      return (cs_ != NULL);
06438         }
06439 
06440 //{----------------------------------------------------------------------------------------------------------------
06442 //}----------------------------------------------------------------------------------------------------------------
06443 
06444 //  private:
06445     CRITICAL_SECTION* cs_;
06446 
06447 //{----------------------------------------------------------------------------------------------------------------
06449 //}----------------------------------------------------------------------------------------------------------------
06451 
06452     private:
06453             txAutoLock (const this_t&) _tx_delete;
06454     this_t& operator = (const this_t&) _tx_delete;
06455 
06457 
06458     };
06459 
06460 //}
06461 //=================================================================================================================
06462 
06463 //=================================================================================================================
06464 //{          Dialogs: txDialog class
06466 //=================================================================================================================
06468 //{----------------------------------------------------------------------------------------------------------------
06489 //}----------------------------------------------------------------------------------------------------------------
06490 
06491 struct txDialog
06492     {
06493     typedef txDialog this_t;
06494 
06495 //{----------------------------------------------------------------------------------------------------------------
06508 //}----------------------------------------------------------------------------------------------------------------
06509 
06510     public:
06511     enum CONTROL
06512         {
06513         DIALOG    = (int) 0x00000000,            
06514         BUTTON    = (int) 0xFFFF0080,            
06515         EDIT      = (int) 0xFFFF0081,            
06516         STATIC    = (int) 0xFFFF0082,            
06517         LISTBOX   = (int) 0xFFFF0083,            
06518         SCROLLBAR = (int) 0xFFFF0084,            
06519         COMBOBOX  = (int) 0xFFFF0085,            
06520         END       = (int) 0x00000000             
06521         };
06522 
06523 //{----------------------------------------------------------------------------------------------------------------
06540 //}----------------------------------------------------------------------------------------------------------------
06541 
06542     public:
06543     struct Layout
06544         {                                        //-V802
06545         CONTROL     wndclass;                    
06546         const char* caption;                     
06547         WORD        id;                          
06548         short        x;                          
06549         short        y;                          
06550         short       sx;                          
06551         short       sy;                          
06552         DWORD       style;                       
06553 
06554         const char* font;                        
06555         WORD        fontsize;                    
06556         };
06557 
06558 //{----------------------------------------------------------------------------------------------------------------
06566 //}----------------------------------------------------------------------------------------------------------------
06567 
06568     public:
06569     txDialog();
06570 
06571 //{----------------------------------------------------------------------------------------------------------------
06581 //}----------------------------------------------------------------------------------------------------------------
06582 
06583     explicit txDialog (const Layout* layout);
06584 
06585 //{----------------------------------------------------------------------------------------------------------------
06587 //}----------------------------------------------------------------------------------------------------------------
06588 
06589     virtual ~txDialog() {};
06590 
06591 //{----------------------------------------------------------------------------------------------------------------
06603 //}----------------------------------------------------------------------------------------------------------------
06604 
06605     const Layout* setLayout (const Layout *layout);
06606 
06607 //{----------------------------------------------------------------------------------------------------------------
06625 //}----------------------------------------------------------------------------------------------------------------
06626 
06627     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam);
06628 
06629 //{----------------------------------------------------------------------------------------------------------------
06645 //}----------------------------------------------------------------------------------------------------------------
06646 
06647     intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0);
06648 
06649 //{----------------------------------------------------------------------------------------------------------------
06662 //}----------------------------------------------------------------------------------------------------------------
06663 
06664     intptr_t dialogBox (WORD resource);
06665 
06666 //{----------------------------------------------------------------------------------------------------------------
06668 //}----------------------------------------------------------------------------------------------------------------
06669 
06670     private:
06671             txDialog   (const this_t&) _tx_delete;
06672     this_t& operator = (const this_t&) _tx_delete;
06673 
06674 //{----------------------------------------------------------------------------------------------------------------
06676 //}----------------------------------------------------------------------------------------------------------------
06677 
06678     protected:
06679     static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
06680 
06681 //{----------------------------------------------------------------------------------------------------------------
06683 //}----------------------------------------------------------------------------------------------------------------
06684 
06685     private:
06686     const Layout* layout_;
06687     };
06688 
06690 //}
06691 //=================================================================================================================
06692 
06693 //=================================================================================================================
06694 //{          Dialogs: Message Map macros
06696 //=================================================================================================================
06698 //{----------------------------------------------------------------------------------------------------------------
06719 //}----------------------------------------------------------------------------------------------------------------
06720 
06721 #define TX_BEGIN_MESSAGE_MAP()                                                                 \
06722     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \
06723         {                                                                                      \
06724         int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result;     \
06725                                                                                                \
06726         switch (_msg)                                                                          \
06727             {                                                                                  \
06728             case WM_NULL:
06729 
06730 //{----------------------------------------------------------------------------------------------------------------
06749 //}----------------------------------------------------------------------------------------------------------------
06750 
06751 #define TX_HANDLE( id )                                                                        \
06752             break;                                                                             \
06753             case (id):
06754 
06755 //{----------------------------------------------------------------------------------------------------------------
06775 //}----------------------------------------------------------------------------------------------------------------
06776 
06777 #define TX_COMMAND_MAP                                                                         \
06778             default: break;                                                                    \
06779             }                                                                                  \
06780                                                                                                \
06781         if (_msg == WM_COMMAND) switch (LOWORD (_wParam))                                      \
06782             {                                                                                  \
06783             case 0:
06784 
06785 //{----------------------------------------------------------------------------------------------------------------
06804 //}----------------------------------------------------------------------------------------------------------------
06805 
06806 #define TX_END_MESSAGE_MAP                                                                     \
06807             default: break;                                                                    \
06808             }                                                                                  \
06809                                                                                                \
06810         return FALSE;                                                                          \
06811         }
06812 
06814 //}
06815 //=================================================================================================================
06816 
06817 //=================================================================================================================
06818 //{          Dialogs: txDialog example: txInputBox()
06820 //=================================================================================================================
06822 //{----------------------------------------------------------------------------------------------------------------
06842 //}----------------------------------------------------------------------------------------------------------------
06843 
06844 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard;
06845 
06846 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06847 
06848 const char* txInputBox (const char* text, const char* caption, const char* input)
06849     {
06850     //-------------------------------------------------------------------------------------------------------------
06851     // Если не указаны параметры, приходится использовать хоть какие-то надписи.
06852     // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название.
06853     //-------------------------------------------------------------------------------------------------------------
06854 
06855     if (!text)    text    = "Введите строку:";
06856     if (!caption) caption = txGetModuleFileName (false);
06857     if (!input)   input   = "";
06858 
06859     //-------------------------------------------------------------------------------------------------------------
06860     // Идентификаторы элементов диалога. Они требуются в GetDlgItemText().
06861     // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически.
06862     // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы
06863     // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения,
06864     // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о
06865     //-------------------------------------------------------------------------------------------------------------
06866 
06867     #define ID_TEXT_  101
06868     #define ID_INPUT_ 102
06869 
06870     //-------------------------------------------------------------------------------------------------------------
06871     // Задание макета (вида) диалога в виде массива структур.
06872     // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив
06873     // становится похож на описание ресурса диалога в .rc-файле.
06874     // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com).
06875     //-------------------------------------------------------------------------------------------------------------
06876 
06877     txDialog::Layout layout[] =
06878 
06879     //----------------------+----------+-----------+-----------------+---------------------------------------------
06880     //     Тип элемента     | Имя      | Иденти-   |   Координаты    | Флаги элементов
06881     //     диалога          | элемента | фикатор   |-----------------| (см. описание элементов
06882     //                      |          | элемента  | X | Y |Шир.|Выс.| окон диалога в MSDN)
06883     //----------------------+----------+-----------+---+---+----+----+---------------------------------------------
06884     //                      |          |           |   |   |    |    |
06885         {{ txDialog::DIALOG,  caption,   0,           0,  0, 240,  85                                                    },
06886          { txDialog::STATIC,  text,      ID_TEXT_,   10, 10, 150,  40, SS_LEFT                                           },
06887          { txDialog::EDIT,    input,     ID_INPUT_,  10, 60, 220,  15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP },
06888          { txDialog::BUTTON,  "&OK",     IDOK,      180, 10,  50,  15, BS_DEFPUSHBUTTON                     | WS_TABSTOP },
06889          { txDialog::BUTTON,  "&Cancel", IDCANCEL,  180, 30,  50,  15, BS_PUSHBUTTON                        | WS_TABSTOP },
06890          { txDialog::END                                                                                                 }};
06891 
06892     //-------------------------------------------------------------------------------------------------------------
06893     // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним.
06894     // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она
06895     // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную
06896     // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее
06897     // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG).
06898     //-------------------------------------------------------------------------------------------------------------
06899     struct inputDlg : txDialog
06900         {
06901         char str [1024];
06902 
06903         //---------------------------------------------------------------------------------------------------------
06904 
06905         inputDlg() :
06906             str()
06907             {}
06908 
06909         //---------------------------------------------------------------------------------------------------------
06910 
06911         TX_BEGIN_MESSAGE_MAP()    // Карта сообщений (на самом деле это начало оконной функции).  //-V2525
06912 
06913             TX_COMMAND_MAP        // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch).
06914 
06915                 //-------------------------------------------------------------------------------------------------
06916                 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия
06917                 // диалога строка ввода умрет и текст уже из нее получить.
06918                 // Этот макрос на самом деле превращается в case из оператора switch.
06919                 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP().
06920                 //-------------------------------------------------------------------------------------------------
06921 
06922                 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1);
06923 
06924         TX_END_MESSAGE_MAP        //-V2522
06925 
06926         //---------------------------------------------------------------------------------------------------------
06927         // Конец внутреннего класса диалога
06928         //---------------------------------------------------------------------------------------------------------
06929         };
06930 
06931     //-------------------------------------------------------------------------------------------------------------
06932     // Убираем дефайны, чтобы потом не мешали.
06933     // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом
06934     // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _.
06935     // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны.
06936     //-------------------------------------------------------------------------------------------------------------
06937 
06938     #undef ID_TEXT_
06939     #undef ID_INPUT_
06940 
06941     //-------------------------------------------------------------------------------------------------------------
06942     // Это статический объект, потому что строка в нем должна жить после завершения функции.
06943     //-------------------------------------------------------------------------------------------------------------
06944 
06945     static inputDlg dlg;
06946 
06947     //-------------------------------------------------------------------------------------------------------------
06948     // Передаем layout и запускаем окно диалога
06949     //-------------------------------------------------------------------------------------------------------------
06950 
06951     dlg.dialogBox (layout);
06952 
06953     //-------------------------------------------------------------------------------------------------------------
06954     // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет
06955     // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать
06956     // синтаксически можно, но ведет к серьезным ошибкам.
06957     //-------------------------------------------------------------------------------------------------------------
06958 
06959     return dlg.str;
06960     }
06961 
06962 #endif // TX_COMPILED
06963 
06965 //}
06966 //=================================================================================================================
06967 
06968 //}
06969 //=================================================================================================================
06970 
06971 //=================================================================================================================
06972 //{          TXLIB IMPLEMENTATION
06973 //           Реализация функций библиотеки
06974 //=================================================================================================================
06976 
06977 //-----------------------------------------------------------------------------------------------------------------
06978 //{          The Includes
06979 //-----------------------------------------------------------------------------------------------------------------
06980 
06981 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06982 
06983 _TX_END_NAMESPACE
06984 
06985 //-----------------------------------------------------------------------------------------------------------------
06986 
06987 #if defined (_MSC_VER)
06988     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
06989 
06990     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
06991     #pragma warning (disable: 4005)              // 'name': macro redefinition
06992 #endif
06993 
06994 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED)
06995     #undef   __STRICT_ANSI__
06996 #endif
06997 
06998 //-----------------------------------------------------------------------------------------------------------------
06999 
07000 #include <stdarg.h>
07001 #include <io.h>
07002 #include <fcntl.h>
07003 #include <process.h>
07004 #include <signal.h>
07005 #include <setjmp.h>
07006 #include <locale.h>
07007 #include <limits.h>
07008 #include <stdint.h>
07009 
07010 #include <map>
07011 #include <numeric>
07012 #include <exception>
07013 #include <stdexcept>
07014 
07015 #include <tlhelp32.h>
07016 #include <shellapi.h>
07017 
07018 #if defined (_GCC_VER)
07019 
07020 #include <shlobj.h>
07021 
07022 #include <cxxabi.h>
07023 #include <unwind.h>
07024 
07025 #endif
07026 
07027 #if defined (__CYGWIN__)
07028 
07029 #include <stdarg.h>
07030 #include <unistd.h>
07031 #include <termios.h>
07032 
07033 #endif
07034 
07035 #if defined (_MSC_VER)
07036 
07037 #include <new.h>
07038 
07039 #include <shlobj.h>
07040 #include <ntstatus.h>
07041 #include <crtdbg.h>
07042 #include <rtcapi.h>
07043 #include <dbghelp.h>
07044 
07045 #endif
07046 
07047 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800)  // MSVC 2013
07048 #include <inttypes.h>
07049 #endif
07050 
07051 //-----------------------------------------------------------------------------------------------------------------
07052 
07053 #if defined (TX_USE_SPEAK) //--------------------------------------------------------------------------------------
07054 #include <SAPI.h>          // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :(
07055 #endif                     //--------------------------------------------------------------------------------------
07056 
07057 //-----------------------------------------------------------------------------------------------------------------
07058 
07059 #if defined (_MSC_VER)
07060     #pragma warning (pop)                        // MSVC: Restore max level
07061 #endif
07062 
07063 #if defined (__STRICT_ANSI__UNDEFINED)
07064     #define  __STRICT_ANSI__                     // Redefine back
07065 #endif
07066 
07067 //-----------------------------------------------------------------------------------------------------------------
07068 
07069 _TX_BEGIN_NAMESPACE
07070 
07071 #endif // TX_COMPILED
07072 
07073 //}
07074 //-----------------------------------------------------------------------------------------------------------------
07075 
07076 //=================================================================================================================
07077 //{          DLL functions import, missing types definitions
07079 //=================================================================================================================
07081 
07082 //-----------------------------------------------------------------------------------------------------------------
07083 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers.
07084 //  Copied from Windows SDK 7.0a.
07085 //-----------------------------------------------------------------------------------------------------------------
07086 
07087 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07088 
07089 namespace Win32 {
07090 
07091 #ifndef AC_SRC_ALPHA
07092 #define AC_SRC_ALPHA                             0x01
07093 #endif
07094 
07095 #ifndef SMTO_ERRORONEXIT
07096 #define SMTO_ERRORONEXIT                         0x0020
07097 #endif
07098 
07099 #ifndef NT_CONSOLE_PROPS_SIG
07100 #define NT_CONSOLE_PROPS_SIG                     0xA0000002
07101 #endif
07102 
07103 #ifndef NIIF_INFO
07104 #define NIIF_INFO                                0x00000001
07105 #define NIIF_WARNING                             0x00000002
07106 #define NIIF_ERROR                               0x00000003
07107 #endif
07108 
07109 #ifndef NIF_INFO
07110 #define NIF_STATE                                0x00000008
07111 #define NIF_INFO                                 0x00000010
07112 #endif
07113 
07114 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
07115 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS   0x00000004
07116 #endif
07117 
07118 #ifndef SYMOPT_CASE_INSENSITIVE
07119 #define SYMOPT_CASE_INSENSITIVE                  0x00000001
07120 #define SYMOPT_UNDNAME                           0x00000002
07121 #define SYMOPT_DEFERRED_LOADS                    0x00000004
07122 #define SYMOPT_NO_CPP                            0x00000008
07123 #define SYMOPT_LOAD_LINES                        0x00000010
07124 #define SYMOPT_OMAP_FIND_NEAREST                 0x00000020
07125 #define SYMOPT_LOAD_ANYTHING                     0x00000040
07126 #define SYMOPT_IGNORE_CVREC                      0x00000080
07127 #define SYMOPT_NO_UNQUALIFIED_LOADS              0x00000100
07128 #define SYMOPT_FAIL_CRITICAL_ERRORS              0x00000200
07129 #define SYMOPT_EXACT_SYMBOLS                     0x00000400
07130 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS            0x00000800
07131 #define SYMOPT_IGNORE_NT_SYMPATH                 0x00001000
07132 #define SYMOPT_INCLUDE_32BIT_MODULES             0x00002000
07133 #define SYMOPT_PUBLICS_ONLY                      0x00004000
07134 #define SYMOPT_NO_PUBLICS                        0x00008000
07135 #define SYMOPT_AUTO_PUBLICS                      0x00010000
07136 #define SYMOPT_NO_IMAGE_SEARCH                   0x00020000
07137 #define SYMOPT_SECURE                            0x00040000
07138 #define SYMOPT_NO_PROMPTS                        0x00080000
07139 #define SYMOPT_ALLOW_ZERO_ADDRESS                0x01000000
07140 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT         0x02000000
07141 #define SYMOPT_FAVOR_COMPRESSED                  0x00800000
07142 #define SYMOPT_FLAT_DIRECTORY                    0x00400000
07143 #define SYMOPT_IGNORE_IMAGEDIR                   0x00200000
07144 #define SYMOPT_OVERWRITE                         0x00100000
07145 #define SYMOPT_DEBUG                             0x80000000
07146 #endif
07147 
07148 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66.
07149 
07150 #ifndef STATUS_POSSIBLE_DEADLOCK
07151 #define STATUS_POSSIBLE_DEADLOCK                 0xC0000194
07152 #endif
07153 
07154 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS
07155 #define STATUS_FLOAT_MULTIPLE_FAULTS             0xC00002B4
07156 #endif
07157 
07158 #ifndef STATUS_STACK_BUFFER_OVERRUN
07159 #define STATUS_STACK_BUFFER_OVERRUN              0xC0000409
07160 #endif
07161 
07162 #ifndef STATUS_ASSERTION_FAILURE
07163 #define STATUS_ASSERTION_FAILURE                 0xC0000420
07164 #endif
07165 
07166 #ifndef STATUS_WX86_BREAKPOINT
07167 #define STATUS_WX86_BREAKPOINT                   0x4000001F
07168 #endif
07169 
07170 #ifndef DBG_PRINTEXCEPTION_C
07171 #define DBG_PRINTEXCEPTION_C                     0x40010006  // OutputDebugStringA() call
07172 #endif
07173 
07174 #ifndef DBG_PRINTEXCEPTION_WIDE_C
07175 #define DBG_PRINTEXCEPTION_WIDE_C                0x4001000A  // OutputDebugStringW() call
07176 #endif
07177 
07178 #ifndef DBG_THREAD_NAME
07179 #define DBG_THREAD_NAME                          0x406D1388
07180 #endif
07181 
07182 #define EXCEPTION_CPP_MSC                        0xE06D7363  // '?msc'
07183 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1       0x19930520  // '?msc' version magic, see ehdata.h
07184 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2       0x19930521  // '?msc' version magic
07185 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3       0x19930522  // '?msc' version magic
07186 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1  0x01994000  // '?msc' version magic
07187 
07188 #define EXCEPTION_CPP_GCC                        0x20474343  // ' GCC'
07189 #define EXCEPTION_CPP_GCC_UNWIND                 0x21474343  // '!GCC'
07190 #define EXCEPTION_CPP_GCC_FORCED                 0x22474343  // '"GCC'
07191 
07192 #define EXCEPTION_CLR_FAILURE                    0xE0434f4D  // 'аCOM'
07193 
07194 #define EXCEPTION_CPP_BORLAND_BUILDER            0x0EEDFAE6  // Should never occur here
07195 #define EXCEPTION_CPP_BORLAND_DELPHI             0x0EEDFADE  // Should never occur here
07196 
07197 #pragma pack (push, 1)
07198 
07199 struct CONSOLE_CURSOR_INFO
07200     {
07201     DWORD dwSize;
07202     BOOL bVisible;
07203     };
07204 
07205 struct CONSOLE_FONT_INFO
07206     {
07207     DWORD nFont;
07208     COORD dwFontSize;
07209     };
07210 
07211 struct CONSOLE_FONT_INFOEX
07212     {
07213     ULONG cbSize;
07214     DWORD nFont;
07215     COORD dwFontSize;
07216     UINT  FontFamily;
07217     UINT  FontWeight;
07218     WCHAR FaceName[LF_FACESIZE];
07219     };
07220 
07221 struct DATABLOCK_HEADER
07222     {
07223     DWORD cbSize;
07224     DWORD dwSignature;
07225     };
07226 
07227 struct NT_CONSOLE_PROPS
07228     {
07229     DATABLOCK_HEADER dbh;
07230 
07231     WORD  wFillAttribute;
07232     WORD  wPopupFillAttribute;
07233     COORD dwScreenBufferSize;
07234     COORD dwWindowSize;
07235     COORD dwWindowOrigin;
07236     DWORD nFont;
07237     DWORD nInputBufferSize;
07238     COORD dwFontSize;
07239     UINT  uFontFamily;
07240     UINT  uFontWeight;
07241     WCHAR FaceName[LF_FACESIZE];
07242     UINT  uCursorSize;
07243     BOOL  bFullScreen;
07244     BOOL  bQuickEdit;
07245     BOOL  bInsertMode;
07246     BOOL  bAutoPosition;
07247     UINT  uHistoryBufferSize;
07248     UINT  uNumberOfHistoryBuffers;
07249     BOOL  bHistoryNoDup;
07250 
07251     COLORREF ColorTable[16];
07252     };
07253 
07254 struct FLASHWINFO
07255     {
07256     UINT  cbSize;
07257     HWND  hwnd;
07258     DWORD dwFlags;
07259     UINT  uCount;
07260     DWORD dwTimeout;
07261     };
07262 
07263 enum TBPFLAG
07264     {
07265     TBPF_NOPROGRESS    = 0x0,
07266     TBPF_INDETERMINATE = 0x1,
07267     TBPF_NORMAL        = 0x2,
07268     TBPF_ERROR         = 0x4,
07269     TBPF_PAUSED        = 0x8
07270     };
07271 
07272 #pragma pack (pop)
07273 
07274 const GUID IID_IShellLink             = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07275 const GUID IID_IShellLinkDataList     = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}};
07276 const GUID IID_IPersistFile           = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07277 
07278 const GUID IID_ITaskbarList3          = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}};
07279 const GUID CLSID_TaskbarList          = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}};
07280 
07281 const GUID CLSID_SpVoice              = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}};
07282 const GUID IID_ISpVoice               = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}};
07283 
07284 typedef DWORD     NTSTATUS;
07285 typedef ULONG_PTR KAFFINITY;
07286 typedef LONG      KPRIORITY;
07287 
07288 struct UNICODE_STRING
07289     {
07290     USHORT   Length;
07291     USHORT   MaximumLength;
07292     wchar_t* Buffer;
07293     };
07294 
07295 struct RTL_DRIVE_LETTER_CURDIR
07296     {
07297     USHORT         Flags;
07298     USHORT         Length;
07299     ULONG          TimeStamp;
07300     UNICODE_STRING DosPath;
07301     };
07302 
07303 struct CURDIR
07304     {
07305     UNICODE_STRING DosPath;
07306     void*          Handle;
07307     };
07308 
07309 struct RTL_USER_PROCESS_PARAMETERS
07310     {
07311     ULONG          AllocationSize;
07312     ULONG          Size;
07313     ULONG          Flags;
07314     ULONG          DebugFlags;
07315     HANDLE         ConsoleHandle;
07316     ULONG          ConsoleFlags;
07317     HANDLE         hStdInput;
07318     HANDLE         hStdOutput;
07319     HANDLE         hStdError;
07320     CURDIR         CurrentDirectory;
07321     UNICODE_STRING DllPath;
07322     UNICODE_STRING ImagePathName;
07323     UNICODE_STRING CommandLine;
07324     wchar_t*       Environment;
07325     ULONG          dwX;
07326     ULONG          dwY;
07327     ULONG          dwXSize;
07328     ULONG          dwYSize;
07329     ULONG          dwXCountChars;
07330     ULONG          dwYCountChars;
07331     ULONG          dwFillAttribute;
07332     ULONG          dwFlags;
07333     ULONG          wShowWindow;
07334     UNICODE_STRING WindowTitle;
07335     UNICODE_STRING Desktop;
07336     UNICODE_STRING ShellInfo;
07337     UNICODE_STRING RuntimeInfo;
07338     RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
07339     };
07340 
07341 struct PEB
07342     {
07343     BYTE  Reserved1[2];
07344     BYTE  BeingDebugged;
07345     BYTE  Reserved2[1];
07346     void* Reserved3[2];
07347     void* Ldr;
07348     RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
07349     void* Reserved4[3];
07350     void* AtlThunkSListPtr;
07351     void* Reserved5;
07352     ULONG Reserved6;
07353     void* Reserved7;
07354     ULONG Reserved8;
07355     ULONG AtlThunkSListPtr32;
07356     void* Reserved9[45];
07357     BYTE  Reserved10[96];
07358     void* PostProcessInitRoutine;
07359     BYTE  Reserved11[128];
07360     void* Reserved12[1];
07361     ULONG SessionId;
07362     };
07363 
07364 struct TEB
07365     {
07366     void* Reserved1[12];
07367     PEB*  ProcessEnvironmentBlock;
07368     void* Reserved2[399];
07369     BYTE  Reserved3[1952];
07370     void* TlsSlots[64];
07371     BYTE  Reserved4[8];
07372     void* Reserved5[26];
07373     void* ReservedForOle;
07374     void* Reserved6[4];
07375     void* TlsExpansionSlots;
07376     };
07377 
07378 struct PROCESS_BASIC_INFORMATION
07379     {
07380     NTSTATUS  ExitStatus;
07381     PEB*      PebBaseAddress;
07382     KAFFINITY AffinityMask;
07383     KPRIORITY BasePriority;
07384     ULONG_PTR UniqueProcessId;
07385     ULONG_PTR InheritedFromUniqueProcessId;
07386     };
07387 
07388 enum ADDRESS_MODE
07389     {
07390     AddrMode1616,
07391     AddrMode1632,
07392     AddrModeReal,
07393     AddrModeFlat
07394     };
07395 
07396 struct ADDRESS64
07397     {
07398     DWORD64      Offset;
07399     WORD         Segment;
07400     ADDRESS_MODE Mode;
07401     };
07402 
07403 struct KDHELP64
07404     {
07405     DWORD64 Thread;
07406     DWORD   ThCallbackStack;
07407     DWORD   ThCallbackBStore;
07408     DWORD   NextCallback;
07409     DWORD   FramePointer;
07410     DWORD64 KiCallUserMode;
07411     DWORD64 KeUserCallbackDispatcher;
07412     DWORD64 SystemRangeStart;
07413     DWORD64 KiUserExceptionDispatcher;
07414     DWORD64 StackBase;
07415     DWORD64 StackLimit;
07416     DWORD64 Reserved[5];
07417     };
07418 
07419 struct STACKFRAME64
07420     {
07421     ADDRESS64 AddrPC;
07422     ADDRESS64 AddrReturn;
07423     ADDRESS64 AddrFrame;
07424     ADDRESS64 AddrStack;
07425     ADDRESS64 AddrBStore;
07426     void*     FuncTableEntry;
07427     DWORD64   Params[4];
07428     BOOL      Far;
07429     BOOL      Virtual;
07430     DWORD64   Reserved[3];
07431     KDHELP64  KdHelp;
07432     };
07433 
07434 struct WOW64_FLOATING_SAVE_AREA
07435     {
07436     DWORD ControlWord;
07437     DWORD StatusWord;
07438     DWORD TagWord;
07439     DWORD ErrorOffset;
07440     DWORD ErrorSelector;
07441     DWORD DataOffset;
07442     DWORD DataSelector;
07443     BYTE  RegisterArea[80];
07444     DWORD Cr0NpxState;
07445     };
07446 
07447 #pragma pack (push, 4)
07448 
07449 struct WOW64_CONTEXT
07450     {
07451     DWORD ContextFlags;
07452 
07453     DWORD Dr0;
07454     DWORD Dr1;
07455     DWORD Dr2;
07456     DWORD Dr3;
07457     DWORD Dr6;
07458     DWORD Dr7;
07459 
07460     WOW64_FLOATING_SAVE_AREA FloatSave;
07461 
07462     DWORD SegGs;
07463     DWORD SegFs;
07464     DWORD SegEs;
07465     DWORD SegDs;
07466 
07467     DWORD Edi;
07468     DWORD Esi;
07469     DWORD Ebx;
07470     DWORD Edx;
07471     DWORD Ecx;
07472     DWORD Eax;
07473 
07474     DWORD Ebp;
07475     DWORD Eip;
07476     DWORD SegCs;
07477     DWORD EFlags;
07478     DWORD Esp;
07479     DWORD SegSs;
07480 
07481     BYTE  ExtendedRegisters[512];
07482     };
07483 
07484 #pragma pack (pop)
07485 
07486 struct SYMBOL_INFO
07487     {
07488     ULONG   SizeOfStruct;
07489     ULONG   TypeIndex;
07490     ULONG64 Reserved[2];
07491     ULONG   info;
07492     ULONG   Size;
07493     ULONG64 ModBase;
07494     ULONG   Flags;
07495     ULONG64 Value;
07496     ULONG64 Address;
07497     ULONG   Register;
07498     ULONG   Scope;
07499     ULONG   Tag;
07500     ULONG   NameLen;
07501     ULONG   MaxNameLen;
07502     char    Name[1];
07503     };
07504 
07505 struct IMAGEHLP_LINE64
07506     {
07507     DWORD   SizeOfStruct;
07508     void*   Key;
07509     DWORD   LineNumber;
07510     char*   FileName;
07511     DWORD64 Address;
07512     };
07513 
07514 typedef bool    (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)   (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead);
07515 typedef void*   (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress);
07516 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)       (HANDLE process, DWORD64 address);
07517 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)     (HANDLE process, HANDLE thread, ADDRESS64* address);
07518 
07519 typedef void (*unexpected_handler)();
07520 
07521 #pragma pack (push, 4)
07522 
07523 struct MINIDUMP_THREAD_CALLBACK
07524     {
07525     ULONG    ThreadId;
07526     HANDLE   ThreadHandle;
07527     CONTEXT  Context;
07528     ULONG    SizeOfContext;
07529     ULONG64  StackBase;
07530     ULONG64  StackEnd;
07531     };
07532 
07533 struct MINIDUMP_THREAD_EX_CALLBACK
07534     {
07535     ULONG    ThreadId;
07536     HANDLE   ThreadHandle;
07537     CONTEXT  Context;
07538     ULONG    SizeOfContext;
07539     ULONG64  StackBase;
07540     ULONG64  StackEnd;
07541     ULONG64  BackingStoreBase;
07542     ULONG64  BackingStoreEnd;
07543     };
07544 
07545 struct MINIDUMP_MODULE_CALLBACK
07546     {
07547     wchar_t* FullPath;
07548     ULONG64  BaseOfImage;
07549     ULONG    SizeOfImage;
07550     ULONG    CheckSum;
07551     ULONG    TimeDateStamp;
07552     VS_FIXEDFILEINFO VersionInfo;
07553     void*    CvRecord;
07554     ULONG    SizeOfCvRecord;
07555     void*    MiscRecord;
07556     ULONG    SizeOfMiscRecord;
07557     };
07558 
07559 struct MINIDUMP_INCLUDE_THREAD_CALLBACK
07560     {
07561     ULONG    ThreadId;
07562     };
07563 
07564 struct MINIDUMP_INCLUDE_MODULE_CALLBACK
07565     {
07566     ULONG64  BaseOfImage;
07567     };
07568 
07569 struct MINIDUMP_MEMORY_INFO
07570     {
07571     ULONG64  BaseAddress;
07572     ULONG64  AllocationBase;
07573     ULONG32  AllocationProtect;
07574     ULONG32  __alignment1;
07575     ULONG64  RegionSize;
07576     ULONG32  State;
07577     ULONG32  Protect;
07578     ULONG32  Type;
07579     ULONG32  __alignment2;
07580     };
07581 
07582 struct MINIDUMP_USER_STREAM
07583     {
07584     ULONG32  Type;
07585     ULONG    BufferSize;
07586     void*    Buffer;
07587     };
07588 
07589 struct MINIDUMP_USER_STREAM_INFORMATION
07590     {
07591     ULONG                 UserStreamCount;
07592     MINIDUMP_USER_STREAM* UserStreamArray;
07593     };
07594 
07595 struct MINIDUMP_CALLBACK_INPUT
07596     {
07597     ULONG    ProcessId;
07598     HANDLE   ProcessHandle;
07599     ULONG    CallbackType;
07600 
07601     union  //-V2514
07602         {
07603         MINIDUMP_THREAD_CALLBACK         Thread;
07604         MINIDUMP_THREAD_EX_CALLBACK      ThreadEx;
07605         MINIDUMP_MODULE_CALLBACK         Module;
07606         MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
07607         MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
07608         };
07609     };
07610 
07611 struct MINIDUMP_CALLBACK_OUTPUT
07612     {
07613     union  //-V2514
07614         {
07615         ULONG ModuleWriteFlags;
07616         ULONG ThreadWriteFlags;
07617         ULONG SecondaryFlags;
07618 
07619         struct
07620             {
07621             ULONG64  MemoryBase;
07622             ULONG    MemorySize;
07623             };
07624 
07625         struct
07626             {
07627             unsigned CheckCancel;
07628             unsigned Cancel;
07629             };
07630 
07631         HANDLE Handle;  //-V117
07632         };
07633 
07634     struct
07635         {
07636         MINIDUMP_MEMORY_INFO VmRegion;
07637         unsigned             Continue;
07638         };
07639 
07640     HRESULT Status;
07641     };
07642 
07643 struct MINIDUMP_EXCEPTION_INFORMATION
07644     {
07645     DWORD               ThreadId;
07646     EXCEPTION_POINTERS* ExceptionPointers;
07647     unsigned            ClientPointers;
07648     };
07649 
07650 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output);
07651 
07652 struct MINIDUMP_CALLBACK_INFORMATION
07653     {
07654     MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
07655     void*                     CallbackParam;
07656     };
07657 
07658 enum MINIDUMP_TYPE
07659     {
07660     MiniDumpNormal                         = 0x00000000,
07661     MiniDumpWithDataSegs                   = 0x00000001,
07662     MiniDumpWithFullMemory                 = 0x00000002,
07663     MiniDumpWithHandleData                 = 0x00000004,
07664     MiniDumpFilterMemory                   = 0x00000008,
07665     MiniDumpScanMemory                     = 0x00000010,
07666     MiniDumpWithUnloadedModules            = 0x00000020,
07667     MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
07668     MiniDumpFilterModulePaths              = 0x00000080,
07669     MiniDumpWithProcessThreadData          = 0x00000100,
07670     MiniDumpWithPrivateReadWriteMemory     = 0x00000200,
07671     MiniDumpWithoutOptionalData            = 0x00000400,
07672     MiniDumpWithFullMemoryInfo             = 0x00000800,
07673     MiniDumpWithThreadInfo                 = 0x00001000,
07674     MiniDumpWithCodeSegs                   = 0x00002000,
07675     MiniDumpWithoutAuxiliaryState          = 0x00004000,
07676     MiniDumpWithFullAuxiliaryState         = 0x00008000,
07677     MiniDumpWithPrivateWriteCopyMemory     = 0x00010000,
07678     MiniDumpIgnoreInaccessibleMemory       = 0x00020000,
07679     MiniDumpWithTokenInformation           = 0x00040000
07680     };
07681 
07682 #ifndef CONTEXT_ALL
07683 #define CONTEXT_ALL              ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS )
07684 #endif
07685 
07686 #pragma pack (pop)
07687 
07688 } // namespace Win32
07689 
07690 #endif // TX_COMPILED
07691 
07692 #define FOREGROUND_BLACK         ( 0                                                         )
07693 #define FOREGROUND_CYAN          ( FOREGROUND_BLUE       | FOREGROUND_GREEN                  )
07694 #define FOREGROUND_MAGENTA       ( FOREGROUND_BLUE       | FOREGROUND_RED                    )
07695 #define FOREGROUND_DARKYELLOW    ( FOREGROUND_GREEN      | FOREGROUND_RED                    )
07696 #define FOREGROUND_LIGHTGRAY     ( FOREGROUND_BLUE       | FOREGROUND_GREEN | FOREGROUND_RED )
07697 #define FOREGROUND_DARKGRAY      (                         FOREGROUND_INTENSITY              )
07698 #define FOREGROUND_LIGHTBLUE     ( FOREGROUND_BLUE       | FOREGROUND_INTENSITY              )
07699 #define FOREGROUND_LIGHTGREEN    ( FOREGROUND_GREEN      | FOREGROUND_INTENSITY              )
07700 #define FOREGROUND_LIGHTCYAN     ( FOREGROUND_CYAN       | FOREGROUND_INTENSITY              )
07701 #define FOREGROUND_LIGHTRED      ( FOREGROUND_RED        | FOREGROUND_INTENSITY              )
07702 #define FOREGROUND_LIGHTMAGENTA  ( FOREGROUND_MAGENTA    | FOREGROUND_INTENSITY              )
07703 #define FOREGROUND_YELLOW        ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY              )
07704 #define FOREGROUND_WHITE         ( FOREGROUND_LIGHTGRAY  | FOREGROUND_INTENSITY              )
07705 
07706 #define BACKGROUND_BLACK         ( 0                                                         )
07707 #define BACKGROUND_CYAN          ( BACKGROUND_BLUE       | BACKGROUND_GREEN                  )
07708 #define BACKGROUND_MAGENTA       ( BACKGROUND_BLUE       | BACKGROUND_RED                    )
07709 #define BACKGROUND_DARKYELLOW    ( BACKGROUND_GREEN      | BACKGROUND_RED                    )
07710 #define BACKGROUND_GRAY          ( BACKGROUND_BLUE       | BACKGROUND_GREEN | BACKGROUND_RED )
07711 #define BACKGROUND_DARKGRAY      (                         BACKGROUND_INTENSITY              )
07712 #define BACKGROUND_LIGHTBLUE     ( BACKGROUND_BLUE       | BACKGROUND_INTENSITY              )
07713 #define BACKGROUND_LIGHTGREEN    ( BACKGROUND_GREEN      | BACKGROUND_INTENSITY              )
07714 #define BACKGROUND_LIGHTCYAN     ( BACKGROUND_CYAN       | BACKGROUND_INTENSITY              )
07715 #define BACKGROUND_LIGHTRED      ( BACKGROUND_RED        | BACKGROUND_INTENSITY              )
07716 #define BACKGROUND_LIGHTMAGENTA  ( BACKGROUND_MAGENTA    | BACKGROUND_INTENSITY              )
07717 #define BACKGROUND_LIGHTYELLOW   ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY              )
07718 #define BACKGROUND_WHITE         ( BACKGROUND_DARKGRAY   | BACKGROUND_INTENSITY              )
07719 
07720 //}
07721 //-----------------------------------------------------------------------------------------------------------------
07722 
07723 //-----------------------------------------------------------------------------------------------------------------
07724 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode.
07725 //  So we have to override them. See: http://stackoverflow.com/questions/39113168
07726 //-----------------------------------------------------------------------------------------------------------------
07727 
07728 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07729 
07730 #if defined (_MSC_VER)
07731                                                     //  MS ABI C++ Exception Layout
07732 namespace Win32 {                                   //  ---------------------------
07733                                                     //
07734 #pragma pack (push, 4)                              //   EXCEPTION_RECORD:
07735                                                     //  +==================================================+
07736 struct ThrowInfo                                    //  |...                                               |
07737     {                                               //  |NumberParameters:        3, 4 or more             |
07738     __int32 attributes;                             //  |ExceptionInformation[0]: MS signature 0x19930520  |
07739     __int32 pmfnUnwind;                             //  |ExceptionInformation[1]: object* thrown           |
07740     __int32 pForwardCompat;                         //  |ExceptionInformation[2]: ThrowInfo* --------------+---+
07741     __int32 pCatchableTypeArray;                    //  |ExceptionInformation[3]: ImageBase (if params > 3)|   |
07742     };                                              //  +==================================================+   |
07743                                                     //                                                         |
07744 struct CatchableTypeArray                           //        ThrowInfo:                                       |
07745     {                                               //        +======================================+ <-------+
07746     __int32 nCatchableTypes;                        //        |   ...                                |
07747     __int32 arrayOfCatchableTypes[];                //  +-----+-- pCatchableTypeArray (ptr/RVA)      |
07748     };                                              //  |     +======================================+
07749                                                     //  |
07750 struct CatchableType                                //  |     CatchableTypeArray:
07751     {                                               //  +---> +======================================+
07752     __int32 properties;                             //        |   ...                                |
07753     __int32 pType;                                  //  +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) |
07754     __int32 thisDisplacement[3]; // struct _PMD     //  |     +======================================+
07755     __int32 sizeOrOffset;                           //  |
07756     __int32 copyFunction;                           //  |     CatchableType:
07757     };                                              //  +---> +====================+
07758                                                     //        | ...                |        std::type_info:
07759 #pragma pack (pop)                                  //        | pType (ptr/RVA) ---+------> +==================+
07760                                                     //        | ...                |        |type_info data    |
07761 } // namespace Win32                                //        +====================+        |...               |
07762                                                     //                                      +==================+
07763 #endif
07764 
07765 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp:
07766 
07767 #define _TX_MSC__CXX_DETECT_RETHROW( exc )                                     \
07768     (                                                                          \
07769     (exc)                                          &&                          \
07770     (exc) -> ExceptionCode    == EXCEPTION_CPP_MSC &&                          \
07771     (exc) -> NumberParameters >= 3                 &&                          \
07772                                                                                \
07773     ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||  \
07774      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||  \
07775      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \
07776                                                                                \
07777     (exc) -> ExceptionInformation[2] == 0                                      \
07778     )
07779 
07780 #endif // TX_COMPILED
07781 
07782 //}
07783 //-----------------------------------------------------------------------------------------------------------------
07784 
07785 //-----------------------------------------------------------------------------------------------------------------
07786 //{ The corresponding structures for GCC
07787 //
07788 //  From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h
07789 //  See:  http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi
07790 //-----------------------------------------------------------------------------------------------------------------
07791 
07792 #if defined (_GCC_VER)
07793 
07794 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07795 
07796                                                     // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0].
07797 namespace ABI {                                     // --------------------------------------------------------------
07798                                                     //
07799 struct __cxa_exception                              // Case A: "_Unwind_Exception* A" is independent exception:
07800     {                                               // --------------------------------------------------------
07801     union {                                         //
07802         struct                                      //           __cxa_exception:           std::type_info:
07803             {                                       //       -*--+====================+     +==================+
07804             ::std::type_info* exceptionType;        //        ^  |exceptionType* -----+---->|type_info data    |
07805             void (*exceptionDestructor)(void*);     //        |  |...                 |     |...               |
07806             };                                      //       -1  |                    |     +==================+
07807         struct                                      //        |  |                    |
07808             {                                       // A >----|--+--------------------+
07809             __cxa_exception*  primaryException;     //     |  |  |unwindHeader        |
07810             void (*padding)();                      //    +1  |  |                    |
07811             };                                      //     |  |  |                    |
07812         };                                          //     V  |  |                    |
07813                                                     //    -*---  +====================+
07814     void (*unexpected_handler)();                   //           |object              |
07815     std::terminate_handler    terminateHandler;     //           +--------------------+
07816                                                     //
07817     __cxa_exception*          nextException;        // Case B: "_Unwind_Exception* B" is dependent exception
07818     int                       handlerCount;         // (unwindHeader.exception_class & 1 != 0):
07819     int                       handlerSwitchValue;   // -----------------------------------------------------
07820     const unsigned char*      actionRecord;         //
07821     const unsigned char*      languageSpecificData; //           __cxa_exception:               __cxa_exception:
07822     void*                     catchTemp;            //       -*--+====================+     -*--+=================+
07823     void*                     adjustedPtr;          //        ^  |primaryException* --+--    ^  |exceptionType*   |
07824                                                     //        |  |...                 |  \   |  |...              |
07825     _Unwind_Exception         unwindHeader;         //       -1  |                    |  |   |  |                 |
07826     };                                              //        |  |                    |  |   |  |                 |
07827                                                     // B >----|--+--------------------+  |  -1  +-----------------+
07828 struct __cxa_eh_globals                             //     |  |  |unwindHeader        |  |   |  |unwindHeader     |
07829     {                                               //    +1  |  |                    |  |   |  |                 |
07830     __cxa_exception* caughtExceptions;              //     |  |  |                    |  |   |  |                 |
07831     unsigned int     uncaughtExceptions;            //     V  |  |                    |  \   |  |                 |
07832     };                                              //    -*---  +====================+   -->*--+=================+
07833                                                     //           |...                 |         |object           |
07834 } // namespace ABI                                  //           .                    .         |                 |
07835                                                     //                                          +-----------------+
07836 
07837 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals();
07838 
07839 #endif // TX_COMPILED
07840 
07841 #endif
07842 
07843 //}
07844 //-----------------------------------------------------------------------------------------------------------------
07845 
07846 //-----------------------------------------------------------------------------------------------------------------
07847 //{ Hand-made IAT.
07848 //  Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :(
07849 //-----------------------------------------------------------------------------------------------------------------
07850 
07851 // Hand-made DLLIMPORT helpers
07852 
07853 #define _TX_DLLIMPORT(     lib, retval, name, params )  TX_DLLIMPORT (true,  lib ".dll", retval, name, params, WINAPI)
07854 #define _TX_DLLIMPORT_OPT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI)
07855 #define _TX_DLLIMPORT_CRT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, please)
07856 
07857 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) ();
07858 
07859 //-----------------------------------------------------------------------------------------------------------------
07860 
07861 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07862 
07863 namespace Win32 {
07864 
07865 _TX_DLLIMPORT     ("GDI32",    HDC,      CreateCompatibleDC,            (HDC dc));
07866 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateCompatibleBitmap,        (HDC dc, int width, int height));
07867 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetStockObject,                (int object));
07868 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  SelectObject,                  (HDC dc, HGDIOBJ object));
07869 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetCurrentObject,              (HDC dc, unsigned objectType));
07870 _TX_DLLIMPORT     ("GDI32",    int,      GetObjectA,                    (HGDIOBJ obj, int bufsize, void* buffer));
07871 _TX_DLLIMPORT     ("GDI32",    DWORD,    GetObjectType,                 (HGDIOBJ object));
07872 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteDC,                      (HDC dc));
07873 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteObject,                  (HGDIOBJ object));
07874 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetTextColor,                  (HDC dc, COLORREF color));
07875 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetBkColor,                    (HDC dc, COLORREF color));
07876 _TX_DLLIMPORT     ("GDI32",    int,      SetBkMode,                     (HDC dc, int bkMode));
07877 _TX_DLLIMPORT     ("GDI32",    HFONT,    CreateFontA,                   (int height, int width, int escapement, int orientation,
07878                                                                          int weight, DWORD italic, DWORD underline, DWORD strikeout,
07879                                                                          DWORD charSet, DWORD outputPrec, DWORD clipPrec,
07880                                                                          DWORD quality, DWORD pitchAndFamily, const char face[]));
07881 _TX_DLLIMPORT     ("GDI32",    int,      EnumFontFamiliesExA,           (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc,
07882                                                                          LPARAM lParam, DWORD reserved));
07883 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetPixel,                      (HDC dc, int x, int y, COLORREF color));
07884 _TX_DLLIMPORT     ("GDI32",    COLORREF, GetPixel,                      (HDC dc, int x, int y));
07885 _TX_DLLIMPORT     ("GDI32",    HPEN,     CreatePen,                     (int penStyle, int width, COLORREF color));
07886 _TX_DLLIMPORT     ("GDI32",    HBRUSH,   CreateSolidBrush,              (COLORREF color));
07887 _TX_DLLIMPORT     ("GDI32",    bool,     MoveToEx,                      (HDC dc, int x, int y, POINT* point));
07888 _TX_DLLIMPORT     ("GDI32",    bool,     LineTo,                        (HDC dc, int x, int y));
07889 _TX_DLLIMPORT     ("GDI32",    bool,     Polygon,                       (HDC dc, const POINT points[], int count));
07890 _TX_DLLIMPORT     ("GDI32",    bool,     Polyline,                      (HDC dc, const POINT points[], int count));
07891 _TX_DLLIMPORT     ("GDI32",    bool,     PolyBezier,                    (HDC dc, const POINT points[], int count));
07892 _TX_DLLIMPORT     ("GDI32",    bool,     Rectangle,                     (HDC dc, int x0, int y0, int x1, int y1));
07893 _TX_DLLIMPORT     ("GDI32",    bool,     RoundRect,                     (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY));
07894 _TX_DLLIMPORT     ("GDI32",    bool,     Ellipse,                       (HDC dc, int x0, int y0, int x1, int y1));
07895 _TX_DLLIMPORT     ("GDI32",    bool,     Arc,                           (HDC dc, int x0, int y0, int x1, int y1,
07896                                                                          int xStart, int yStart, int xEnd, int yEnd));
07897 _TX_DLLIMPORT     ("GDI32",    bool,     Pie,                           (HDC dc, int x0, int y0, int x1, int y1,
07898                                                                          int xStart, int yStart, int xEnd, int yEnd));
07899 _TX_DLLIMPORT     ("GDI32",    bool,     Chord,                         (HDC dc, int x0, int y0, int x1, int y1,
07900                                                                          int xStart, int yStart, int xEnd, int yEnd));
07901 _TX_DLLIMPORT     ("GDI32",    bool,     TextOutA,                      (HDC dc, int x, int y, const char string[], int length));
07902 _TX_DLLIMPORT     ("GDI32",    UINT,     SetTextAlign,                  (HDC dc, unsigned mode));
07903 _TX_DLLIMPORT     ("GDI32",    bool,     GetTextExtentPoint32A,         (HDC dc, const char string[], int length, SIZE* size));
07904 _TX_DLLIMPORT     ("GDI32",    bool,     ExtFloodFill,                  (HDC dc, int x, int y, COLORREF color, unsigned type));
07905 _TX_DLLIMPORT     ("GDI32",    bool,     BitBlt,                        (HDC dest, int xDest, int yDest, int width, int height,
07906                                                                          HDC src,  int xSrc,  int ySrc,  DWORD rOp));
07907 _TX_DLLIMPORT     ("GDI32",    bool,     StretchBlt,                    (HDC dest, int xDest, int yDest, int width, int height,
07908                                                                          HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp));
07909 _TX_DLLIMPORT     ("GDI32",    bool,     PlgBlt,                        (HDC dest, const POINT* parallelogram,
07910                                                                          HDC src, int xSrc, int ySrc, int width, int height,
07911                                                                          HBITMAP mask, int xMask, int yMask));
07912 _TX_DLLIMPORT     ("GDI32",    int,      SetDIBitsToDevice,             (HDC dc, int xDest, int yDest, DWORD width, DWORD height,
07913                                                                          int xSrc, int ySrc, unsigned startLine, unsigned numLines,
07914                                                                          const void* data, const BITMAPINFO* info, unsigned colorUse));
07915 _TX_DLLIMPORT     ("GDI32",    int,      GetDIBits,                     (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines,
07916                                                                          void* lpvBits, BITMAPINFO* lpbi, unsigned usage));
07917 _TX_DLLIMPORT     ("GDI32",    bool,     PatBlt,                        (HDC dc, int x0, int y0, int width, int height, DWORD rOp));
07918 _TX_DLLIMPORT     ("GDI32",    int,      SetROP2,                       (HDC dc, int mode));
07919 _TX_DLLIMPORT     ("GDI32",    int,      SetStretchBltMode,             (HDC dc, int mode));
07920 _TX_DLLIMPORT     ("GDI32",    DWORD,    GdiSetBatchLimit,              (DWORD limit));
07921 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateDIBSection,              (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits,
07922                                                                          HANDLE section, DWORD offset));
07923 
07924 _TX_DLLIMPORT     ("User32",   int,      DrawTextA,                     (HDC dc, const char text[], int length, RECT* rect, unsigned format));
07925 _TX_DLLIMPORT     ("User32",   HANDLE,   LoadImageA,                    (HINSTANCE inst, const char name[], unsigned type,
07926                                                                         int sizex, int sizey, unsigned mode));
07927 _TX_DLLIMPORT_OPT ("User32",   bool,     IsHungAppWindow,               (HWND wnd));
07928 _TX_DLLIMPORT_OPT ("User32",   HWND,     GhostWindowFromHungWindow,     (HWND wnd));
07929 _TX_DLLIMPORT_OPT ("User32",   bool,     FlashWindowEx,                 (const FLASHWINFO* flash));
07930 
07931 _TX_DLLIMPORT     ("WinMM",    bool,     PlaySound,                     (const char sound[], HMODULE mod, DWORD mode));
07932 
07933 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     TransparentBlt,                (HDC dest, int destX, int destY, int destWidth, int destHeight,
07934                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
07935                                                                          unsigned transparentColor));
07936 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     AlphaBlend,                    (HDC dest, int destX, int destY, int destWidth, int destHeight,
07937                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
07938                                                                          BLENDFUNCTION blending));
07939 
07940 _TX_DLLIMPORT     ("Kernel32", void,     ExitProcess,                   (unsigned retcode));
07941 _TX_DLLIMPORT     ("Kernel32", bool,     TerminateProcess,              (HANDLE process, unsigned retcode));
07942 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalExit,                     (int retcode));
07943 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalAppExitA,                 (unsigned action, const char message[]));
07944 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetThreadId,                   (HANDLE thread));
07945 _TX_DLLIMPORT     ("Kernel32", HWND,     GetConsoleWindow,              (void));
07946 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetConsoleFont,                (HANDLE con, DWORD fontIndex));
07947 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetNumberOfConsoleFonts,       (void));
07948 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFont,         (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO*   curFont));
07949 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
07950 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
07951 _TX_DLLIMPORT_OPT ("Kernel32", void,     RtlCaptureContext,             (CONTEXT* contextRecord));
07952 _TX_DLLIMPORT_OPT ("Kernel32", USHORT,   RtlCaptureStackBackTrace,      (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash));
07953 _TX_DLLIMPORT_OPT ("Kernel32", void*,    AddVectoredExceptionHandler,   (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler));
07954 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler));
07955 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetModuleHandleEx,             (DWORD flags, const char moduleName[], HMODULE* module));
07956 _TX_DLLIMPORT_OPT ("Kernel32", bool,     IsWow64Process,                (HANDLE process, int* isWow64Process));
07957 _TX_DLLIMPORT_OPT ("Kernel32", bool,     Wow64GetThreadContext,         (HANDLE thread, WOW64_CONTEXT* context));
07958 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetThreadStackGuarantee,       (unsigned long* stackSize));
07959 
07960 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoInitialize,                  (void*));
07961 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoCreateInstance,              (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value));
07962 _TX_DLLIMPORT     ("OLE32",    void,     CoUninitialize,                (void));
07963 
07964 _TX_DLLIMPORT     ("Shell32",  HINSTANCE,ShellExecuteA,                 (HWND wnd, const char operation[], const char file[],
07965                                                                          const char parameters[], const char directory[], int showCmd));
07966 
07967 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIA,                      (const char    string[], const char    search[]));
07968 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIW,                      (const wchar_t string[], const wchar_t search[]));
07969 
07970 _TX_DLLIMPORT_OPT ("NTDLL",    char*,    wine_get_version,              (void));
07971 _TX_DLLIMPORT     ("NTDLL",    NTSTATUS, NtQueryInformationProcess,     (HANDLE process, int infoClass,
07972                                                                          void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo));
07973 
07974 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     exit,                          (int retcode));
07975 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     _cexit,                        (void));
07976 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _fpreset,                      (void));
07977 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _controlfp,                    (unsigned control, unsigned mask));
07978 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthread,                  (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist));
07979 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthreadex,                (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*),
07980                                                                          void *arglist, unsigned init_flag, unsigned* thread_addr));
07981 _TX_DLLIMPORT_CRT ("MSVCRT",   char*,    __unDName,                     (char* outStr, const char* mangledName, int outStrLen,
07982                                                                          void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer),
07983                                                                          unsigned short flags));
07984 _TX_DLLIMPORT_CRT ("MSVCRT",   unexpected_handler, set_unexpected,      (unexpected_handler handler));
07985 
07986 _TX_DLLIMPORT_OPT ("OpenGL32", HDC,         wglGetCurrentDC,            (void));
07987 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned,    glGetError,                 (void));
07988 _TX_DLLIMPORT_OPT ("Glu32",    const char*, gluErrorString,             (unsigned error));
07989 
07990 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD,    CommDlgExtendedError,          (void));
07991 
07992 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     MiniDumpWriteDump,             (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType,
07993                                                                          MINIDUMP_EXCEPTION_INFORMATION*   exceptionParam,
07994                                                                          MINIDUMP_USER_STREAM_INFORMATION* userStreamParam,
07995                                                                          MINIDUMP_CALLBACK_INFORMATION*    callbackParam));
07996 
07997 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD,    SymSetOptions,                 (DWORD options));
07998 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
07999 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08000 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08001 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08002 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymCleanup,                    (HANDLE process));
08003 _TX_DLLIMPORT_OPT ("DbgHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08004 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08005                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08006                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08007                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08008                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08009 namespace MinGW {
08010 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD,    SymSetOptions,                 (DWORD options));
08011 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
08012 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08013 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08014 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08015 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymCleanup,                    (HANDLE process));
08016 _TX_DLLIMPORT_OPT ("MgwHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08017 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08018                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08019                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08020                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08021                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08022 } // namespace MinGW
08023 } // namespace Win32
08024 
08025 #endif // TX_COMPILED
08026 
08027 //}
08028 //-----------------------------------------------------------------------------------------------------------------
08029 
08031 //}
08032 //=================================================================================================================
08033 
08034 //=================================================================================================================
08035 //{          Internal function prototypes, macros and constants
08036 //  @name    Прототипы внутренних функций, макросы и константы
08037 //=================================================================================================================
08039 
08040 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08041 
08042 int              _txInitialize();
08043 void             _txCleanup();
08044 
08045 HWND             _txCanvas_CreateWindow      (const SIZE* size);
08046 
08047 bool             _txCanvas_OnCREATE          (HWND wnd);
08048 bool             _txCanvas_OnDESTROY         (HWND wnd);
08049 bool             _txCanvas_OnCLOSE           (HWND);
08050 bool             _txCanvas_OnPAINT           (HWND wnd);
08051 bool             _txCanvas_OnKEY             (HWND wnd, WPARAM vk, LPARAM info, bool down);
08052 bool             _txCanvas_OnCHAR            (HWND wnd, WPARAM ch, LPARAM info);
08053 bool             _txCanvas_OnTIMER           (HWND wnd, WPARAM id);
08054 bool             _txCanvas_OnMOUSEMOVE       (HWND wnd, WPARAM buttons, LPARAM coords);
08055 bool             _txCanvas_OnMOUSELEAVE      (HWND wnd);
08056 bool             _txCanvas_OnCREATEWND       (HWND wnd, WPARAM, LPARAM lpar);
08057 bool             _txCanvas_OnDESTROYWND      (HWND wnd, WPARAM, LPARAM lpar);
08058 bool             _txCanvas_OnCmdCONSOLE      (HWND wnd, WPARAM cmd);
08059 bool             _txCanvas_OnCmdABOUT        (HWND wnd, WPARAM cmd);
08060 
08061 unsigned WINAPI  _txCanvas_ThreadProc        (void* data);
08062 LRESULT CALLBACK _txCanvas_WndProc           (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08063 
08064 HDC              _txBuffer_Create            (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL,
08065                                               RGBQUAD** pixels = NULL) tx_nodiscard;
08066 bool             _txBuffer_Delete            (HDC* dc);
08067 bool             _txBuffer_Select            (HGDIOBJ obj, HDC dc = txDC());
08068 
08069 HWND             _txConsole_Attach();
08070 bool             _txConsole_OK() tx_nodiscard;
08071 bool             _txConsole_Detach           (bool activate);
08072 bool             _txConsole_Draw             (HDC dc);
08073 bool             _txConsole_SetUnicodeFont();
08074 
08075 const char*       txRegisterClass            (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra);
08076 HWND              txCreateExtraWindow        (CREATESTRUCT createData);
08077 HICON            _txCreateTXIcon             (int size) tx_nodiscard;
08078 int              _txSetWindowText            (HWND wnd, const char* textRus, const char* textEng = NULL,
08079                                               int checkOfs = 0, const wchar_t checkLetters[2] = NULL);
08080 int              _txPauseBeforeTermination   (HWND canvas);
08081 int              _txIsParentListed           (const char* list, DWORD* parentPID = NULL) tx_nodiscard;
08082 void             _txActivateWindow           (HWND wnd, unsigned mode);
08083 int              _txGetInput();
08084 
08085 LRESULT CALLBACK _txPlayVideo_WndProc        (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08086 const char*      _txPlayVideo_FindVLC() tx_nodiscard;
08087 
08088 bool             _txCreateShortcut           (const char shortcutName[],
08089                                               const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL,
08090                                               const char description[] = NULL, int cmdShow = SW_SHOWNORMAL,
08091                                               const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0,
08092                                               COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD));
08093 
08094 void*            _tx_DLGTEMPLATE_Create      (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
08095                                               WORD controls, short x, short y, short cx, short cy,
08096                                               const char caption[], const char font[], WORD fontsize,
08097                                               const char menu[]) tx_nodiscard;
08098 
08099 void*            _tx_DLGTEMPLATE_Add         (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
08100                                               short x, short y, short cx, short cy,
08101                                               WORD id, const char wclass[], const char caption[]);
08102 
08103 const char*      _txProcessError             (const char file[], int line, const char func[], unsigned color,
08104                                               const char msg[], va_list args);
08105 void             _txOnTerminate();
08106 void             _txOnUnexpected();
08107 void             _txOnPureCall();
08108 void             _txOnNewHandlerAnsi();
08109 int              _txOnNewHandler             (size_t size);
08110 void             _txOnSignal                 (int signal = 0, int fpe = 0);
08111 BOOL WINAPI      _txOnConsoleCtrlEvent       (DWORD type);
08112 void             _txOnSecurityError          (int code, void*);
08113 void             _txOnSecurityErrorAnsi      (const char* msg, void* ptr, int code);
08114 int              _txOnMatherr                (_exception* except);
08115 void             _txOnInvalidParam           (const wchar_t* expr, const wchar_t* func, const wchar_t* file,
08116                                               unsigned line, uintptr_t);
08117 int              _txOnAllocHook              (int type, void* data, size_t size, int use, long request,
08118                                               const unsigned char* file, int line);
08119 int              _txOnRTCFailure             (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5);
08120 int              _txOnErrorReport            (int type, const char* text, int* ret);
08121 int               tx_glGetError              (int setError = INT_MIN);
08122 
08123 void             _txOnCExit();
08124 void             _txOnExit                   (int      retcode);
08125 void             _txOnFatalExit              (int      retcode);
08126 void             _txOnExitProcess            (unsigned retcode);
08127 void             _txOnFatalAppExitA          (unsigned action, const char message[]);
08128 bool             _txOnTerminateProcess       (HANDLE process, unsigned retcode);
08129 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
08130                  _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter);
08131 void             _txWatchdogTerminator       (void* timeout);  // Only Arnold-type series are supported, not T1000
08132 
08133 long WINAPI      _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc);
08134 long WINAPI      _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc);
08135 long             _txOnExceptionSEH           (EXCEPTION_POINTERS* exc, const char func[]);
08136 intptr_t         _txDumpExceptionSEH         (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]);
08137 intptr_t         _txDumpExceptionObj         (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type);
08138 intptr_t         _txDumpExceptionCPP         (char what[], intptr_t size, unsigned code = 0,
08139                                               unsigned params = 0, const ULONG_PTR info[] = NULL);
08140 
08141 void             _txStackBackTrace           (const char file[] = "?", int line = 0, const char func[] = "?",
08142                                               bool readSource = true);
08143 const char*      _txCaptureStackBackTrace    (int framesToSkip = 0, bool readSource = true,
08144                                               CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread());
08145 int              _txStackWalk                (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL,
08146                                               HANDLE thread = GetCurrentThread());
08147 const char*      _txCaptureStackBackTraceTX  (int framesToSkip = 0, bool readSource = false);
08148 
08149 const char*      _txSymPrintFromAddr         (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2);
08150 bool             _txSymGetFromAddr           (void* addr, Win32::SYMBOL_INFO** symbol = NULL,
08151                                               Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL,
08152                                               const char** source = NULL, int context = 2);
08153 intptr_t         _txReadSource               (char buf[], intptr_t size, const char file[],
08154                                               int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN);
08155 bool             _txCreateMiniDump           (EXCEPTION_POINTERS* exc = NULL);
08156 
08157 uintptr_t        _txSetProcAddress           (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL,
08158                                               int useHotPatching = false, HMODULE module = NULL, bool debug = false);
08159 bool             _txInDll() tx_nodiscard;
08160 PROCESSENTRY32*  _txFindProcess              (unsigned pid = GetCurrentProcessId()) tx_nodiscard;
08161 bool             _txKillProcess              (DWORD pid);
08162 int              _txTaskKill                 (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/);
08163 bool             _txCheckSourceCP            (int needCP = _TX_CODEPAGE, bool verbose = true);
08164 bool             _txGetCommandLine           (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid());
08165 IMAGE_NT_HEADERS*_txGetNtHeaders             (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard;
08166 bool             _txIsConsoleSubsystem();
08167 const char*      _txAppInfo() tx_nodiscard;
08168 
08169 #if defined (_CLANG_VER) && !defined (_MSC_VER)
08170 void             _txLibCppDebugFunction      (std::__libcpp_debug_info const& info);
08171 #endif
08172 
08173 #endif // TX_COMPILED
08174 
08175 inline bool      _txCanvas_OK                () tx_nodiscard;
08176 int              _txCanvas_SetRefreshLock    (int count);
08177 
08178 const char*      _txError                    (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0,
08179                                               const char msg[] = NULL, ...) tx_printfy (5);
08180 
08181 bool             _txIsBadReadPtr             (const void* address);
08182 
08183 intptr_t         _tx_snprintf_s              (char stream[], intptr_t size, const char format[], ...) tx_printfy (3);
08184 intptr_t         _tx_vsnprintf_s             (char stream[], intptr_t size, const char format[], va_list arg);
08185 bool             _txIsTTY                    (int fd);
08186 void              txReopenStdio();
08187 
08188 #if defined (__CYGWIN__)
08189 
08190 int              _getch();
08191 int              _putch (int ch);
08192 int              _kbhit() tx_nodiscard;
08193 
08194 #endif
08195 
08196 //-----------------------------------------------------------------------------------------------------------------
08197 // There are macros for __FILE__ and __LINE__ to work properly.
08198 
08199 #if !defined (NDEBUG)
08200 
08201     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08202                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) && \
08203                                                      (assert (cond), true) )
08204 
08205     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08206                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) && \
08207                                                      (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) )
08208 
08209     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                                                            \
08210                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) &&                                     \
08211                                                      (TX_ERROR ("\a" "Параметр \"%s\" неверен."                                           \
08212                                                                                    " Возможно, этот холст не создан, или уже уничтожен,"  \
08213                                                                                    " или не загрузилась картинка.", #dc), 1) )
08214     #define _TX_DEFAULT_HDC_FAILED( dc )       ( (!(dc) &&                                                                                \
08215                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) &&                                     \
08216                                                      (TX_ERROR ("\a" "%s" "Если вы указали параметр \"%s\", то он неверен.%s",            \
08217                                                                      !txWindow()? "Окно рисования не создано или не в порядке.\n" : "",   \
08218                                                                      #dc,                                                                 \
08219                                                                       txWindow()? " Возможно, этот холст не создан, или уже уничтожен,"   \
08220                                                                                    " или не загрузилась картинка." : ""), 1))             \
08221                                                  ||                                                                                       \
08222                                                  _TX_HDC_FAILED (dc) )
08223 #else
08224 
08225     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08226                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) )
08227 
08228     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08229                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08230 
08231     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                        \
08232                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08233 
08234     #define _TX_DEFAULT_HDC_FAILED( dc )       ( !(dc) &&                                             \
08235                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08236 #endif
08237 
08238 //-----------------------------------------------------------------------------------------------------------------
08239 // Take action in debug configuration only.
08240 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'(
08241 
08242 #if !defined (NDEBUG)
08243     #define  _TX_ON_DEBUG( code )              { code; }
08244 #else
08245     #define  _TX_ON_DEBUG( code )              ;
08246 #endif
08247 
08248 //-----------------------------------------------------------------------------------------------------------------
08249 // Invokes an error without location information. "$$" restores TX-related call location context
08250 
08251 #define _TX_UNEXPECTED( ... )                  $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__)
08252 
08253 //-----------------------------------------------------------------------------------------------------------------
08254 // Safe call of a function via its pointer
08255 
08256 #define _TX_CALL(  func, param )               ( (func)? ((func) param) :       0 )
08257 #define _TX_CALLv( func, param )               ( (func)? ((func) param) : (void)0 )
08258 
08259 //-----------------------------------------------------------------------------------------------------------------
08260 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x.
08261 
08262 #define _txWaitFor( cond, time )               { for (DWORD _t = GetTickCount() + (time); \
08263                                                       !(cond) && GetTickCount() < _t;     \
08264                                                       Sleep (_txWindowUpdateInterval))    \
08265                                                       ;                                   \
08266                                                                                           \
08267                                                  if  (!(cond))                            \
08268                                                       _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); }
08269 
08270 //-----------------------------------------------------------------------------------------------------------------
08271 // Detouring in case of SEH mechanism
08272 
08273 #define _txSetJmp()                            ( setjmp (_txDumpExceptionObjJmp) == 0 )
08274 
08275 #define _txClearJmp()                          { *(unsigned long long*) _txDumpExceptionObjJmp = 0; }
08276 
08277 //-----------------------------------------------------------------------------------------------------------------
08278 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code.
08279 
08280 #if defined (IN)
08281 //  #undef  IN
08282 #endif
08283 
08284 #if defined (OUT)
08285 //  #undef  OUT
08286 #endif
08287 
08289 //}
08290 //=================================================================================================================
08291 
08292 //=================================================================================================================
08293 //{          Internal global data
08295 //
08296 //           Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :)
08297 //
08298 //           Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же.
08299 //           Здесь это сделано только в образовательных целях.
08300 //
08301 //           Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс.
08302 //=================================================================================================================
08304 
08305 #ifndef TX_COMPILED                                                      // <<<<<<< THE CODE IS HERE, UNFOLD IT <<<
08306 
08307 const int                      _TX_IDM_ABOUT               = 40000,      // Идентификаторы системного меню окна
08308                                _TX_IDM_CONSOLE             = 40001,
08309                                _TX_WM_CREATEWND            = 0x7FF0,     // Сообщения для создания/уничтожения
08310                                _TX_WM_DESTROYWND           = 0x7FF1;     // окон в потоке Canvas
08311 
08312 const char                     _TX_VSCODE_PARENTS[]        = "cmd.exe:code.exe, powershell.exe:code.exe";
08313 
08314 //-----------------------------------------------------------------------------------------------------------------
08315 
08316 volatile unsigned              _txCanaryFirst              = 0x776F656D; // A very system value
08317 
08318 int                            _txInitialized              = (_TX_NOINIT +0)? 0 : _txInitialize();
08319 
08320 volatile unsigned              _txMainThreadId             = 0;          // ID потока, где выполняется main()
08321 volatile HANDLE                _txMainThread               = NULL;       // Дексриптор этого потока
08322 
08323 volatile unsigned              _txCanvas_ThreadId          = 0;          // ID потока, владеющего окном холста TXLib
08324 volatile HANDLE                _txCanvas_Thread            = NULL;       // Дексриптор этого потока
08325 volatile HWND                  _txCanvas_Window            = NULL;       // Дескриптор окна холста TXLib
08326 
08327 HDC                            _txCanvas_BackBuf[2]        = {NULL,      // [0] Main TXLib in-memory DC, where user's pictures lies
08328                                                               NULL};     // [1] Image ready for auto-refresh, see txCanvas_OnPAINT()
08329 
08330 RGBQUAD*                       _txCanvas_Pixels            = NULL;       // Memory buffer of _txCanvas_BackBuf[0]
08331 
08332 HBITMAP                        _txStockBitmap              = NULL;       // Equivalent of GetStockObject (BITMAP),
08333                                                                          // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313
08334 
08335 CRITICAL_SECTION               _txCanvas_LockBackBuf       = {0,-1};     // Prevent simultaneous access to back buffer, see txLock()
08336 
08337 UINT_PTR                       _txCanvas_RefreshTimer      = 1;          // Timer ID to redraw TXLib window
08338 volatile int                   _txCanvas_RefreshLock       = 0;          // Blocks auto on-timer canvas update, see txBegin/txEnd
08339 
08340 ::std::vector<HDC>*            _txCanvas_UserDCs           = NULL;       // List of DCs allocated, for auto-free
08341 
08342 volatile bool                  _txConsole_IsBlinking       = true;       // To blink or not to blink, that is the question.
08343 
08344 int                            _txConsole                  = false;      // Only first TXLib module in app can own the console
08345 bool                           _txMain                     = false;      // First TXLib wnd opened (closing it terminates program)
08346 bool                           _txIsDll                    = false;      // TXLib module is in DLL
08347 volatile bool                  _txRunning                  = false;      // main() is still running
08348 volatile bool                  _txExit                     = false;      // exit() is active
08349 
08350 volatile POINT                 _txMousePos                 = {-1,-1};    // Ask Captn Obviouos about it. See txCanvas_OnMOUSE()
08351 volatile unsigned              _txMouseButtons             = 0;
08352 
08353 volatile WNDPROC               _txAltWndProc               = NULL;       // Альтернативная оконная функция. См. txSetWindowsHook().
08354 
08355 _tx_thread _txLoc              _txLoc::Cur                 = {};         // Execution point tracking and trace state, see "$" macro
08356 
08357 volatile int                   _txErrors                   = 0;          // TX_ERROR calls sequential number
08358 volatile int                   _txOGLError                 = 0;          // Last OpenGL error when using tx_glGetError()
08359 volatile long                  _txSENumber                 = 0;          // SEH exceptions sequential number
08360 volatile long                  _txSEFatalNumber            = 0;          // SEH fatal exceptions sequential number
08361 char                           _txDumpSE [_TX_BUFSIZE]     = "";         // SEH dump data area
08362 char                           _txTraceSE[_TX_HUGEBUFSIZE] = "";         // Stack trace data area
08363 
08364 LPTOP_LEVEL_EXCEPTION_FILTER   _txPrevUEFilter             = NULL;       // Previous UnhandledExceptionFilter
08365 
08366 jmp_buf                        _txDumpExceptionObjJmp      = {};         // Hook for _txDumpExceptionObj
08367 
08368 const volatile uintptr_t       _txForceImport[]            = { (uintptr_t) ::TerminateProcess,              (uintptr_t) ::ExitProcess,
08369                                                                (uintptr_t) ::FatalExit,                     (uintptr_t) ::FatalAppExitA,
08370                                                                (uintptr_t) ::exit,                          (uintptr_t) Win32::_controlfp,
08371                                                                (uintptr_t) Win32::Polyline,                 (uintptr_t) Win32::PolyBezier,
08372                                                                (uintptr_t) Win32::RoundRect,                (uintptr_t) Win32::RemoveVectoredExceptionHandler,
08373                                                                (uintptr_t) Win32::PlgBlt,                   (uintptr_t) Win32::RtlCaptureStackBackTrace,
08374                                                                (uintptr_t) Win32::SymInitialize,            (uintptr_t) Win32::MinGW::SymInitialize,
08375                                                                (uintptr_t) Win32::SymSetOptions,            (uintptr_t) Win32::MinGW::SymSetOptions,
08376                                                                (uintptr_t) Win32::SymGetLineFromAddr64,     (uintptr_t) Win32::MinGW::SymGetLineFromAddr64,
08377                                                                (uintptr_t) Win32::SymFromAddr,              (uintptr_t) Win32::MinGW::SymFromAddr,
08378                                                                (uintptr_t) Win32::SymCleanup,               (uintptr_t) Win32::MinGW::SymCleanup,
08379                                                                (uintptr_t) Win32::SymGetModuleBase64,       (uintptr_t) Win32::MinGW::SymGetModuleBase64,
08380                                                                (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64,
08381                                                                (uintptr_t) Win32::StackWalk64,              (uintptr_t) Win32::MinGW::StackWalk64,
08382                                                                (uintptr_t) Win32::StrStrIA,                 (uintptr_t) Win32::Wow64GetThreadContext };
08383 
08384 volatile unsigned              _txCanaryLast               = 0x5E2E2E5E; // Another very system value
08385 
08386 #endif // TX_COMPILED
08387 
08388 //-----------------------------------------------------------------------------------------------------------------
08389 
08390 extern volatile unsigned _txCanaryFirst;
08391 extern volatile unsigned _txCanaryLast;
08392 extern volatile HWND     _txCanvas_Window;
08393 extern volatile unsigned _txCanvas_ThreadId;
08394 extern          HDC      _txCanvas_BackBuf[2];
08395 extern          RGBQUAD* _txCanvas_Pixels;
08396 extern volatile int      _txCanvas_RefreshLock;
08397 extern volatile WNDPROC  _txAltWndProc;
08398 extern volatile bool     _txExit;
08399 extern volatile int      _txOGLError;
08400 
08402 //}
08403 //=================================================================================================================
08404 
08405 //=================================================================================================================
08406 //{          TXLib engine init/check/cleanup
08408 //=================================================================================================================
08410 
08411 //-----------------------------------------------------------------------------------------------------------------
08412 //{          Early initialization
08413 //-----------------------------------------------------------------------------------------------------------------
08414 
08415 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08416 
08417 int _txInitialize()
08418     {
08419     if (_txInitialized) return 1;
08420     _txInitialized = 1;
08421 
08422     #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER)  // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx
08423     _CrtSetBreakAlloc (_TX_ALLOC_BREAK);                 // and http://support.microsoft.com/ru-ru/kb/151585
08424     #endif
08425 
08426     #if defined (_TX_ALLOW_TRACE)
08427     _txLocLvlSet (1);
08428     #endif
08429 
08430     _TX_ON_DEBUG (OutputDebugString ("\n");
08431                   OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" "
08432                                      "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n");
08433                   OutputDebugString ("\n"));
08434 
08435     _txMainThreadId = GetCurrentThreadId();
08436     _txMainThread   = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId);
08437 
08438 $3  _txIsDll = _txInDll();
08439 
08440 $   if (!_txIsDll)
08441         {
08442 $       _txConsole = ! FindAtom ("_txConsole");
08443 $       (void)          AddAtom ("_txConsole");  //-V530
08444         }
08445 
08446 $   if (_txConsole)
08447         {
08448 $       _txCheckSourceCP (_TX_CODEPAGE, true);
08449 
08450 $       unsigned long stackSize = _TX_STACKSIZE;
08451 $       _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
08452 
08453 $       _txOnSignal();
08454 
08455 $       if (_txLogName[0] == '~')
08456             {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); }
08457 
08458 $       if (!_txIsDll)
08459             {
08460 $           _TX_CALL  (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER)  _txVectoredExceptionHandler));
08461 $           _txPrevUEFilter = SetUnhandledExceptionFilter  (   (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter);
08462             }
08463 
08464 $       ::std::set_terminate             (_txOnTerminate);
08465 $       ::std::set_new_handler           (_txOnNewHandlerAnsi);
08466 $       _TX_CALL (Win32::set_unexpected, (_txOnUnexpected));
08467 
08468         #if defined (_CLANG_VER) && !defined (_MSC_VER)
08469 $       ::std::__libcpp_debug_function = _txLibCppDebugFunction;
08470         #endif
08471 
08472 $       SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true);
08473 
08474 $       SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
08475 
08476         #if defined (_MSC_VER)
08477 
08478 $       _set_printf_count_output (1);
08479 
08480 $       _set_new_handler (_txOnNewHandler);
08481 $       _set_new_mode (1);
08482 
08483         #if !defined (_CLANG_VER)
08484 
08485 $       _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
08486 $       _CrtSetAllocHook (_txOnAllocHook);
08487 
08488 $       unsigned mode = _CRTDBG_MODE_FILE;
08489 $       if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0;
08490 
08491 $       _CrtSetReportMode (_CRT_WARN,   _CRTDBG_MODE_DEBUG | mode);
08492 $       _CrtSetReportMode (_CRT_ERROR,  _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08493 $       _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08494 $       _CrtSetReportFile (_CRT_WARN,   _CRTDBG_FILE_STDERR);
08495 $       _CrtSetReportFile (_CRT_ERROR,  _CRTDBG_FILE_STDERR);
08496 $       _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
08497 
08498         #endif
08499 
08500 $       _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG);
08501 $       _set_abort_behavior (0,                _CALL_REPORTFAULT);
08502 
08503 $       _RTC_SetErrorFunc              (_txOnRTCFailure);
08504 $       _set_purecall_handler          (_txOnPureCall);
08505 $       _set_invalid_parameter_handler (_txOnInvalidParam);
08506 
08507         #endif
08508 
08509         #if defined (__STDC_LIB_EXT1__)
08510 $       ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi);
08511         #endif
08512 
08513         #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386)
08514 $       __setusermatherr (_txOnMatherr);
08515         #endif
08516 
08517         #if !defined (__CYGWIN__)
08518 $       _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR);
08519         #endif
08520 
08521 $       HWND console = _txConsole_Attach();
08522 $       SetWindowTextA (console, txGetModuleFileName (false));
08523         }
08524 
08525 $   _txSetProcAddress ("ExitProcess",                 (uintptr_t) _txOnExitProcess,                 "KERNEL32.DLL");
08526 $   _txSetProcAddress ("TerminateProcess",            (uintptr_t) _txOnTerminateProcess,            "KERNEL32.DLL");
08527 $   _txSetProcAddress ("FatalExit",                   (uintptr_t) _txOnFatalExit,                   "KERNEL32.DLL");
08528 $   _txSetProcAddress ("FatalAppExitA",               (uintptr_t) _txOnFatalAppExitA,               "KERNEL32.DLL");
08529 $   _txSetProcAddress ("UnhandledExceptionFilter",    (uintptr_t) _txUnhandledExceptionFilter,      "KERNEL32.DLL", true);  //-V601
08530 $   _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL");
08531 $   _txSetProcAddress ("exit",                        (uintptr_t) _txOnExit);
08532 $   _txSetProcAddress ("_cexit",                      (uintptr_t) _txOnCExit);
08533 
08534 $   InitializeCriticalSection (&_txCanvas_LockBackBuf);
08535 
08536 $   HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted;
08537 $   _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted;
08538 $   Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted;
08539 $   Win32::DeleteDC (dc) asserted;
08540 
08541 $   atexit (_txCleanup);
08542 
08543 $   if (_txConsole)
08544         {
08545 $       txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
08546 
08547 $       tx_fpreset();
08548 
08549 $       srand ((unsigned) time (NULL));  //-V202
08550 
08551 $       SetLastError (0);
08552 $       errno = 0;
08553 
08554         #if !defined (__CYGWIN__)
08555 $       _doserrno = 0;
08556         #endif
08557         }
08558 
08559 $   Win32::CoCreateInstance = Win32::CoCreateInstance;  // g++ 5.1.0 bug, false warning "defined but not used"
08560 
08561 $   return 1;
08562     }
08563 
08564 //-----------------------------------------------------------------------------------------------------------------
08565 
08566 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/)
08567     {
08568 $3  const char* sCodePage = NULL;
08569 $   int codePage = 0;
08570 
08571 $   switch (((unsigned const char*) "А") [0])
08572         {
08573         case 192: {$ codePage =  1251; sCodePage = "1251.";          break; }
08574         case 208: {$ codePage = 65001; sCodePage = "UTF-8.";         break; }
08575         case 128: {$ codePage =   866; sCodePage = "866.";           break; }
08576         case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; }
08577         default:  {$ codePage =    -1; sCodePage = "(Unknown)";      break; }
08578         }
08579 
08580 $   if (codePage != needCP && verbose)
08581         {
08582 $       *_txTraceSE = ' ';  // No stack trace please
08583 
08584 $       _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n"
08585                         "This is NOT an error of TXLib itself. Please note:\n\n"
08586                         "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your "
08587                         "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO "
08588                         "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. "
08589                         "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n"
08590                         "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n"
08591                         "You can continue, but Russian messages and symbols may appear unreadable.",
08592                         sCodePage, needCP, needCP);
08593         }
08594 
08595 $   return (codePage == needCP);
08596     }
08597 
08598 //-----------------------------------------------------------------------------------------------------------------
08599 
08600 #ifdef _TX_DEBUG_LOAD
08601 
08602 HMODULE _txLoadLibrary_ (const char* dll, int line);
08603 HMODULE _txLoadLibrary_ (const char* dll, int line)
08604     {
08605     txOutputDebugPrintf (_TX_DEBUG_LOAD "[" __FILE__ ":%04d] Loading \"%s\"... ", line, dll);
08606 
08607     SetLastError (0);
08608     HMODULE lib = LoadLibrary (dll);
08609 
08610     if (lib) txOutputDebugPrintf (_TX_DEBUG_LOAD "SUCSESS [%p]\n", (void*) lib);
08611     else     txOutputDebugPrintf (_TX_DEBUG_LOAD "error %lu\n", GetLastError());
08612 
08613     return lib;
08614     }
08615 
08616 #define LoadLibraryA(dll) _txLoadLibrary_ (dll, __LINE__)
08617 
08618 #endif
08619 
08620 //-----------------------------------------------------------------------------------------------------------------
08621 
08622 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) ()
08623     {
08624     if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL;
08625     if (_TX_ARGUMENT_FAILED (funcName    && *funcName))    return NULL;
08626 
08627     static char dllPaths [4][MAX_PATH] = {};
08628 
08629     if (!*dllPaths[0])
08630         {
08631         const  char dllDir[] = "\\Windows\\";
08632         char*  path = NULL;
08633         size_t sz   = 0;
08634 
08635         // The dllPaths[0] is a directory where executable file is located
08636 
08637         path = dllPaths[0];
08638 
08639         sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0;
08640         if (char* dir = strrchr (path, '\\')) dir[1] = 0;
08641 
08642         // The dllPaths[1] is relative to directory where executable file is located
08643 
08644         path = dllPaths[1];
08645 
08646         sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0;
08647         if (char* dir = strrchr (path, '\\')) dir[0] = 0;
08648 
08649         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08650 
08651         // The dllPaths[2] is relative to TXib.h file used in compilation
08652 
08653         path = dllPaths[2];
08654 
08655         if (strchr (__FILE__, ':'))
08656             {
08657             strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1);
08658             }
08659         else
08660             {
08661             // No way to get include path at compile time using simple call "gcc file.cpp"
08662 
08663             sz = GetCurrentDirectory (MAX_PATH, path); path[sz] = 0;
08664             if (*path) strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1);
08665             }
08666 
08667         if (char* dir = strrchr (path, '\\')) *dir = 0;
08668 
08669         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08670 
08671         // The dllPaths[3] is relative to the TX Setup directory stored in the Registry
08672 
08673         path = dllPaths[3];
08674 
08675         txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH);
08676         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08677         }
08678 
08679     char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = "";
08680     const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL);  //-V547
08681 
08682     if (arch)
08683         {
08684         assert (arch >= dllFileName);  //-V547
08685 
08686         strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName));
08687         strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName));
08688 
08689         strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName));
08690         strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3);
08691         strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch));
08692         }
08693     else if (dllFileName)  //-V547 //-V2516
08694         {
08695         strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1);
08696         }
08697 
08698     HMODULE   dll = GetModuleHandle (dllFileName);
08699 
08700     if (!dll) dll = GetModuleHandle (dllArch);
08701     if (!dll) dll = GetModuleHandle (dllName);
08702 
08703     for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++)
08704         {
08705         if (!dllPaths[i]) continue;
08706 
08707         char path [MAX_PATH] = "";
08708         strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i]));
08709         size_t len = strlen (path);
08710 
08711         SetDllDirectory (path);
08712 
08713         strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch));
08714         if (!dll && *dllArch) dll = LoadLibrary (path);  //-V547
08715 
08716         strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName));
08717         if (!dll)             dll = LoadLibrary (path);
08718         }
08719 
08720     SetDllDirectory (NULL);
08721 
08722     if (!dll && *dllArch) dll = LoadLibrary (dllArch);
08723     if (!dll)             dll = LoadLibrary (dllName);
08724 
08725     if (!dll  && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".",
08726                                            dllName, (arch? "\" / \"" : ""), dllArch);
08727     if (!dll) return NULL;
08728 
08729     void (*addr)() = (void(*)()) GetProcAddress (dll, funcName);
08730 
08731     if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".",
08732                                            funcName, dllName, (arch? "\" / \"" : ""), dllArch);
08733     return addr;
08734     }
08735 
08736 //-----------------------------------------------------------------------------------------------------------------
08737 
08738 #ifdef _TX_DEBUG_LOAD
08739     #undef LoadLibraryA
08740     #endif
08741 
08742 //-----------------------------------------------------------------------------------------------------------------
08743 
08744 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013
08745     #pragma warning (push)
08746     #pragma warning (disable: 6102)          // Использование 'name' из завершившегося ошибкой вызова функции
08747 #endif
08748 
08749 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue)
08750     {
08751     if (_TX_ARGUMENT_FAILED (keyName)) return 0;
08752 
08753     HKEY hive = NULL;
08754 
08755     #define EQU_(name1, name2)  ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \
08756                                   _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 )
08757 
08758     if      (EQU_("HKLM", "HKEY_LOCAL_MACHINE"))  hive = HKEY_LOCAL_MACHINE;
08759     else if (EQU_("HKCU", "HKEY_CURRENT_USER"))   hive = HKEY_CURRENT_USER;
08760     else if (EQU_("HKCR", "HKEY_CLASSES_ROOT"))   hive = HKEY_CLASSES_ROOT;
08761     else if (EQU_("HKU",  "HKEY_USERS"))          hive = HKEY_USERS;
08762     else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG;
08763 
08764     else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; }
08765 
08766     #undef EQU_
08767 
08768     keyName = strchr (keyName, '\\') + 1;  //-V769
08769     assert (keyName > (const char*) 1);
08770 
08771     HKEY  key  = NULL;
08772     DWORD size = 0;
08773 
08774     bool                               ok  = (RegOpenKeyEx    (hive, keyName,   0, KEY_QUERY_VALUE, &key)         == ERROR_SUCCESS);
08775     if (ok)                            ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, NULL,          &size) == ERROR_SUCCESS);
08776     if (ok && value && size < szValue) ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS);  //-V104
08777     if (key)                           ok &= (RegCloseKey     (key)                                               == ERROR_SUCCESS);
08778 
08779     return size;
08780     }
08781 
08782 #if defined (_MSC_VER) && (_MSC_VER == 1800)
08783     #pragma warning (pop)
08784 #endif
08785 
08786 #endif // TX_COMPILED
08787 
08788 //}
08789 //-----------------------------------------------------------------------------------------------------------------
08790 
08791 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08792 
08793 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/)
08794     {
08795 $1  if (!_txInitialized) _txInitialized = _txInitialize();
08796 
08797 $   if (HWND wnd = txWindow())
08798         {
08799 $       SetLastErrorEx (ERROR_INVALID_DATA, 0);
08800 $       _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!"));
08801 $       return wnd;
08802         }
08803 
08804 $   if (!_txIsDll)
08805         {
08806 $       _txMain = ! FindAtom ("_txMain");  // Not a thread-safe
08807 $       (void)       AddAtom ("_txMain");  //-V530
08808         }
08809 
08810 $   if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; }  //-V1048
08811 
08812 $   _txRunning = false;
08813 
08814     // Store the size
08815 
08816 $   static SIZE size = { ROUND (sizeX), ROUND (sizeY) };
08817 $   if (centered) { size.cx *= -1; size.cy *= -1; }
08818 
08819     // In Thread, where REAL creation lies...
08820 
08821 $   unsigned id = 0;
08822 $   _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id);
08823 
08824 $   if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."),  (HWND) NULL;
08825 
08826 $   _txWaitFor (_txRunning, 10*_TX_TIMEOUT);
08827 
08828 $   if (!_txRunning)       return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL;
08829 $   if (!txOK())           return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."),     (HWND) NULL;
08830 
08831 $   HWND console = Win32::GetConsoleWindow();
08832 
08833 $   DWORD proc = 0;
08834 $   GetWindowThreadProcessId (console, &proc);
08835 
08836 $   if (console && (proc == GetCurrentProcessId() || _txIsParentListed (_TX_WAITABLE_PARENTS)))
08837         {$ ShowWindow (console, TX_CONSOLE_MODE); }
08838 
08839 $   HMENU menu = GetSystemMenu (txWindow(), false);
08840     if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); }
08841 
08842 $   Win32::GdiSetBatchLimit (1);
08843 
08844 $   SetLastError (0);
08845 
08846 $   errno = 0;
08847 
08848     #if !defined (__CYGWIN__)
08849 $   _doserrno = 0;
08850     #endif
08851 
08852 $   return txWindow();
08853     }
08854 
08855 //-----------------------------------------------------------------------------------------------------------------
08856 
08857 HWND txCreateExtraWindow (CREATESTRUCT createData)
08858     {
08859 $1  if (_TX_TXWINDOW_FAILED()) return NULL;
08860 
08861 $   volatile HWND wnd = NULL;
08862 $   createData.hInstance = (HINSTANCE)(uintptr_t) &wnd;
08863 
08864 $   PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted;
08865 
08866 $   _txWaitFor (wnd, 5*_TX_TIMEOUT);
08867 
08868 $   return wnd;
08869     }
08870 
08871 //-----------------------------------------------------------------------------------------------------------------
08872 
08873 bool txSetDefaults (HDC dc /*= txDC()*/)
08874     {
08875 $1  if (dc == txDC()) txUpdateWindow (false);  //-V601
08876 $   txAutoLock _lock;
08877 
08878 $   RECT r = {};
08879 $   GetClientRect (Win32::GetConsoleWindow(), &r);
08880 $   SIZE szCon = { r.right - r.left, r.bottom - r.top };
08881 
08882 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
08883 
08884 $   CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}};
08885 $   GetConsoleScreenBufferInfo (out, &con);
08886 
08887 $   SIZE szTxt = { (short) (con.srWindow.Right  - con.srWindow.Left + 1),
08888                    (short) (con.srWindow.Bottom - con.srWindow.Top  + 1) };
08889 
08890 //{ Set defaults for graphics layer
08891 
08892 $   _txBuffer_Select (Win32::GetStockObject (WHITE_PEN),   dc) asserted;
08893 $   _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted;
08894 
08895 $   _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx,
08896                                          0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
08897                                          RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
08898                                          DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT),
08899                       dc) asserted;
08900 
08901 $  (Win32::SetTextColor      (dc, TX_WHITE) != CLR_INVALID) asserted;
08902 $   Win32::SetBkMode         (dc, TRANSPARENT)              asserted;
08903 
08904 $   Win32::SetROP2           (dc, R2_COPYPEN)               asserted;
08905 $   Win32::SetStretchBltMode (dc, HALFTONE)                 asserted;
08906 
08907 //}
08908 
08909 $   if (dc != txDC())
08910         {$ return true; }
08911 
08912 //{ Set defaults for console  layer
08913 
08914 $   POINT szCanvas = txGetExtent (dc);
08915 
08916 $   HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)?
08917                        Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx,
08918                                           0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
08919                                           RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
08920                                           DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT)
08921                        :
08922                        Win32::GetStockObject (SYSTEM_FIXED_FONT);
08923 
08924 $   _txBuffer_Select (font, _txCanvas_BackBuf[1]);
08925 //}
08926 
08927 //{ Scroll the console for text to go above top of window and don't mix with graphics
08928 
08929 $   if (con.dwCursorPosition.X) _putch ('\n');
08930 
08931 $   short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top);
08932 
08933 $   con.srWindow.Top    = (short) (con.srWindow.Top    + delta);
08934 $   con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta);
08935 
08936 $   SMALL_RECT src  = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) };
08937 $   CHAR_INFO  fill = { {' '}, FOREGROUND_LIGHTGRAY };
08938 $   COORD      dest = { 0, (short) -delta };  // New UL-corner of src, scroll up
08939 
08940 $   con.dwCursorPosition.X = 0;
08941 $   con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta);
08942 
08943 $   (con.srWindow.Bottom < con.dwSize.Y &&                        // Move the "window"
08944      SetConsoleWindowInfo      (out, true, &con.srWindow))
08945     ||
08946     (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill),    // Or scroll the buffer
08947      SetConsoleCursorPosition  (out, con.dwCursorPosition));
08948 //}
08949 
08950 $   txUpdateWindow (true);  //-V601
08951 
08952     return true;
08953     }
08954 
08955 #endif // TX_COMPILED
08956 
08957 //-----------------------------------------------------------------------------------------------------------------
08958 
08959 inline bool txOK()
08960     {
08961     return (_txCanaryFirst == 0x776F656D &&  // Too well-known values to use constants. You know these values, don't you?
08962             _txCanaryLast  == 0x5E2E2E5E &&
08963             _txCanvas_OK()
08964 
08965     #if defined (_MSC_VER)
08966          && _CrtCheckMemory()
08967     #endif
08968             );
08969     }
08970 
08971 //-----------------------------------------------------------------------------------------------------------------
08972 //{          Cleanup
08973 //-----------------------------------------------------------------------------------------------------------------
08974 
08975 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08976 
08977 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain.
08978 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols
08979 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize().
08980 
08981 void _txOnCExit()
08982     {
08983     OutputDebugString ("\n");
08984 
08985 $5  _txCleanup();
08986 
08987     _TX_CALLv (Win32::_cexit, ());
08988     }
08989 
08990 //-----------------------------------------------------------------------------------------------------------------
08991 
08992 void _txOnExit (int retcode)
08993     {
08994     if (retcode != 0)
08995         {
08996         OutputDebugString ("\n");
08997         txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode);
08998         }
08999 
09000 $5  _txCleanup();
09001 
09002     if (retcode != 0)
09003         txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode);
09004 
09005     Win32::exit (retcode);
09006     }
09007 
09008 //-----------------------------------------------------------------------------------------------------------------
09009 
09010 void _txOnExitProcess (unsigned retcode)
09011     {
09012     if (retcode != 0)
09013         {
09014         OutputDebugString ("\n");
09015         txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode);
09016         }
09017 
09018 $5  _txCleanup();
09019 
09020     if (retcode != 0)
09021         txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode);
09022 
09023     Win32::ExitProcess (retcode);
09024     }
09025 
09026 //-----------------------------------------------------------------------------------------------------------------
09027 
09028 bool _txOnTerminateProcess (HANDLE process, unsigned retcode)
09029     {
09030     if (retcode != 0)
09031         {
09032         OutputDebugString ("\n");
09033         txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode);
09034         }
09035 
09036 $5  _txCleanup();
09037 
09038     if (retcode != 0)
09039         txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode);
09040 
09041     return Win32::TerminateProcess (process, retcode);
09042     }
09043 
09044 //-----------------------------------------------------------------------------------------------------------------
09045 
09046 void _txOnFatalExit (int retcode)
09047     {
09048     OutputDebugString ("\n");
09049     txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode);
09050 
09051 $5  _txCleanup();
09052 
09053     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode);
09054     _TX_CALLv (Win32::FatalExit, (retcode));
09055 
09056     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode);
09057     Win32::TerminateProcess (GetCurrentProcess(), retcode);
09058     }
09059 
09060 //-----------------------------------------------------------------------------------------------------------------
09061 
09062 void _txOnFatalAppExitA (unsigned action, const char message[])
09063     {
09064     OutputDebugString ("\n");
09065     txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message);
09066 
09067 $5  _txCleanup();
09068 
09069     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message);
09070     _TX_CALLv (Win32::FatalAppExitA, (action, message));
09071 
09072     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION);
09073     Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09074     }
09075 
09076 //-----------------------------------------------------------------------------------------------------------------
09077 
09078 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type)
09079     {
09080     OutputDebugString ("\n");
09081     txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type);
09082 
09083 $5  switch (type)
09084         {
09085         case CTRL_LOGOFF_EVENT:
09086         case CTRL_SHUTDOWN_EVENT: $ _txExit = true;
09087                                   $ _txCleanup();
09088         case CTRL_C_EVENT:
09089         case CTRL_CLOSE_EVENT:
09090         case CTRL_BREAK_EVENT:
09091 
09092         default:                  break;  //-V2522
09093         }
09094 
09095 $   return false;
09096     }
09097 
09098 //-----------------------------------------------------------------------------------------------------------------
09099 
09100 void _txCleanup()
09101     {
09102     if (!_txInitialized) return;
09103     else _txInitialized = false;  //-V601
09104 
09105 $3  _txRunning = false;
09106 $   _txConsole_IsBlinking = false;
09107 
09108 $   txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR);
09109 
09110 $   txSetWindowsHook (NULL);
09111 
09112 $   HWND     canvas  = txWindow();
09113 $   HWND     console = Win32::GetConsoleWindow();
09114 $   unsigned thread  = GetCurrentThreadId();
09115 
09116 $   HWND wnd         = (canvas)? canvas : console;
09117 
09118 $   bool externTerm  = (thread != _txMainThreadId &&
09119                         thread != _txCanvas_ThreadId);
09120 
09121 $   DWORD list[1] = {};
09122 $   DWORD ownsConsole = (GetConsoleProcessList (list, 1) <= 1);
09123 
09124 $   int    envPause       = -1;
09125 $   char   envPause_s[10] = "";
09126 $   size_t envPause_sz    = 0;
09127 $   getenv_s (&envPause_sz, envPause_s, sizeof (envPause_s) - 1, "TX_PAUSE");
09128 
09129     if (strcmp (envPause_s, "1") == 0 || _stricmp (envPause_s, "ON")  == 0) {$ envPause = 1; }
09130     if (strcmp (envPause_s, "0") == 0 || _stricmp (envPause_s, "OFF") == 0) {$ envPause = 0; }
09131 
09132 $   DWORD parent = 0;
09133 $   int  isParentWaitable = _txIsParentListed (_TX_WAITABLE_PARENTS, &parent);
09134 
09135 $   if (canvas)
09136         {$ txSleep (5*_txWindowUpdateInterval); }
09137 
09138 $   if (_txConsole)
09139         {
09140 $       if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
09141 
09142 $       if (console)
09143             {
09144 $           EnableWindow     (console, true);
09145 $           _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */);
09146             }
09147         }
09148 
09149 $   if (_txMain && !externTerm && canvas)
09150         {$  _txSetWindowText (canvas,  " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); }
09151 
09152 $   std::cout.flush();
09153 $   std::cerr.flush();
09154 $   std::clog.flush();
09155 $   _flushall();
09156 
09157 $   bool paused = false;
09158 $   if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId))
09159         {
09160 $       if (wnd)
09161             {
09162 $           int isVSCode = _txIsParentListed (_TX_VSCODE_PARENTS);
09163 
09164 $           if (isParentWaitable >= 0 && !isVSCode)
09165                 {$ _txActivateWindow (wnd, 0x10); }
09166 
09167 $           EnableWindow (wnd, true);
09168             }
09169 
09170 $       if ((console && (ownsConsole || canvas || _txErrors || envPause == 1)) && isParentWaitable >= 0 && !(envPause == 0))
09171             {
09172 $           txPause ((_txErrors)?               "\f\n" "[Press F to Pay Respects...]" :
09173                      (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f");
09174 
09175 $           paused = true;
09176             }
09177         }
09178 
09179 $   if (_txConsole && _txWatchdogTimeout >= 0)
09180      {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09181 
09182 $   if (txWindow())
09183         {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); }
09184 
09185 $   _txWaitFor (!txWindow(), 5*_TX_TIMEOUT);
09186 
09187 $   txSpeak     (NULL);
09188 $   txPlayVideo (NULL);
09189 
09190 $   delete _txCanvas_UserDCs;
09191 $   _txCanvas_UserDCs = NULL;
09192 
09193 $   if (GetCurrentThreadId() != _txMainThreadId)
09194         {$ SuspendThread (_txMainThread);    }  //-V720
09195 $   if (GetCurrentThreadId() != _txCanvas_ThreadId)
09196         {$ SuspendThread (_txCanvas_Thread); }  //-V720
09197 
09198 $   if (_txMainThread)
09199         {$ CloseHandle (_txMainThread)    asserted; _txMainThread    = NULL; }
09200 $   if (_txCanvas_Thread)
09201         {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; }
09202 
09203 $   if (!txWindow())
09204         {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; }
09205 
09206 $   bool parentKilled = false;
09207 $   if (isParentWaitable && !externTerm && paused && _txNOP (_TX_ALLOW_KILL_PARENT))
09208         {
09209 $       console = Win32::GetConsoleWindow();
09210 
09211 $       if (parent)
09212             {$ parentKilled = _txKillProcess (parent); }
09213 
09214 $       if (parent && !parentKilled)
09215             {
09216 $           PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09217 $           PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09218             }
09219         }
09220 
09221 $   if (_txConsole)
09222         {$ _txSetWindowText (console, NULL); }
09223 
09224 $   if (_txMain && _txConsole)
09225         {$ _txConsole_Detach (isParentWaitable && !externTerm && !parentKilled); }  //-V560
09226 
09227 $   std::cout.flush();
09228 $   std::cerr.flush();
09229 $   std::clog.flush();
09230 $   _flushall();
09231 
09232 $   _txSymGetFromAddr (NULL);
09233 
09234     // That's all, folks
09235 
09236     _TX_ON_DEBUG (OutputDebugString ("\n");
09237                   OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n");
09238                   OutputDebugString ("\n"));
09239     }
09240 
09241 //-----------------------------------------------------------------------------------------------------------------
09242 
09243 int txPause (const char* message /*= NULL*/, ...)
09244     {
09245 $3  bool wine    = !!Win32::wine_get_version;
09246 
09247 $   HWND canvas  = txWindow();
09248 $   HWND console = Win32::GetConsoleWindow();
09249 $   HWND wnd     = (canvas)? canvas : console;
09250 $   bool istty0  = _txIsTTY (0);
09251 
09252 $   int attr     = txGetConsoleAttr();
09253 
09254 $   int oldCP    = GetConsoleOutputCP();
09255 $   SetConsoleOutputCP (_TX_CODEPAGE);
09256 
09257     if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; }
09258 
09259     if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); }
09260     else                  {$ message++; }
09261 
09262     if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); }
09263     else                  {$ message++; }
09264 
09265 $   int isVSCode = _txIsParentListed (_TX_VSCODE_PARENTS);
09266 
09267 $   if (!isVSCode)
09268         {$ _txActivateWindow (wnd, 0x10); }
09269 
09270 $   va_list args;
09271 $   va_start (args, message);
09272 $   vfprintf (stderr, message, args);
09273 $   va_end (args);
09274 
09275 $   va_start (args, message);
09276 $   txOutputDebugPrintf ("txPause(): message, args");  // !!! 0xC0000005 reading [-1]
09277 $   va_end (args);
09278 
09279 $   fflush (stderr);
09280 $   txSleep();
09281 
09282 $   Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF };
09283 $   _TX_CALL (Win32::FlashWindowEx, (&flash));
09284 
09285 $   int ch = EOF;
09286     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09287 
09288 $   for (int i = 1; ; i++)  //-V2530
09289         {
09290 $       Sleep (_txWindowUpdateInterval);
09291 
09292         if (!istty0 && !canvas)                   {$ break; }  // No need to run and hide
09293 
09294         if (!wine && (ch = _txGetInput()) != EOF) {$ break; }  // Somebody hit something.
09295 
09296         if (canvas && !_txCanvas_ThreadId)        {$ break; }  // There was a window, and now there is not.
09297 
09298         if (!Win32::GetConsoleWindow())           {$ break; }  // Console was destroyed
09299 
09300         if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas)))
09301             {$ TX_ERROR ("Похоже, программа зависла :("); break; }
09302 
09303         if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas)))
09304             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; }
09305 
09306         if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL))
09307             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает");  break; }
09308 
09309         if (!wine && !(i % 100500))
09310             {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...]  \b\b"); }
09311         }
09312 
09313     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09314 
09315 $   _txSetWindowText (wnd, NULL);
09316 
09317 $   fprintf (stderr, "\n");
09318 
09319     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09320 
09321 $   SetConsoleOutputCP (oldCP);
09322 $   txSetConsoleAttr (attr);
09323 
09324 $   return ch;
09325     }
09326 
09327 //-----------------------------------------------------------------------------------------------------------------
09328 
09329 int _txGetInput()
09330     {
09331 $4  HANDLE con = GetStdHandle (STD_INPUT_HANDLE);
09332 $   int ch = EOF;
09333 
09334 $   DWORD nChars = 0;
09335 $   if (GetConsoleMode (con, &nChars) == 0 &&
09336         PeekNamedPipe  (con, NULL, 0, NULL, &nChars, NULL))
09337         {
09338 $       ch = (nChars)? fgetc (stdin) : EOF;
09339         }
09340 
09341     else if (_kbhit())
09342         {
09343 $       ch = _getch();
09344         }
09345 
09346 #if defined (_MSC_VER) && (_MSC_VER < 1700)
09347 
09348     else if (fseek (stdin, 1, SEEK_CUR) != EOF)
09349         {
09350 $       (void) fseek (stdin, -1, SEEK_CUR);
09351 $       ch = fgetc (stdin);                                // This causes blocking in MSVC 2011 beta
09352         }
09353 
09354 #endif
09355 
09356     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09357 
09358 $   return ch;
09359     }
09360 
09361 //-----------------------------------------------------------------------------------------------------------------
09362 
09363 bool _txIsTTY (int fd)
09364     {
09365 $4  return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR;
09366     }
09367 
09368 //-----------------------------------------------------------------------------------------------------------------
09369 
09370 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/,
09371                       int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/)
09372     {
09373     struct tools
09374         {
09375         static LRESULT getWindowText (HWND window, wchar_t text[], size_t size)
09376             {
09377 $3          memset (text, 0, size * sizeof (*text));
09378 
09379 $           return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09380             }
09381 
09382         static LRESULT setWindowText (HWND window, wchar_t text[])
09383             {
09384 $1          return SendMessageTimeoutW (window, WM_SETTEXT, 0,             (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09385             }
09386         };
09387 
09388 $1  static wchar_t _tx_thread title    [_TX_BUFSIZE+15] = L"TXLib";
09389 $   static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib";
09390 
09391 $   if (!textRus)
09392         {
09393 $       tools::setWindowText (wnd, oldTitle);
09394 $       return -1;
09395         }
09396 
09397 $   tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09398 $   int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1;
09399 $   memcpy (oldTitle, title, sizeof (oldTitle));
09400 
09401 $   if (textRus)
09402         {
09403 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len);
09404 
09405 $       tools::setWindowText (wnd, title);
09406 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09407         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; }
09408         if (!checkLetters) {$ return -2; }
09409         }
09410 
09411 $   if (textEng)
09412         {
09413 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len);
09414 
09415 $       tools::setWindowText (wnd, title);
09416 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09417         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; }
09418         if (!checkLetters) {$ return -2; }
09419         }
09420 
09421 $   return -3;
09422     }
09423 
09424 //-----------------------------------------------------------------------------------------------------------------
09425 
09426 int _txIsParentListed (const char* list, DWORD* parentPID /*= NULL*/)
09427     {
09428 $4  PROCESSENTRY32* info = _txFindProcess();
09429 $   if (!info) return 0;
09430 
09431 $   info = _txFindProcess (info->th32ParentProcessID);
09432 $   if (!info) return 0;
09433 
09434 $   char parent [MAX_PATH] = "";
09435 $   strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1);
09436 $   if (parentPID) *parentPID = info->th32ProcessID;
09437 
09438 $   info = _txFindProcess (info->th32ParentProcessID);          // info: grandparent
09439 
09440 $   char lst[_TX_BUFSIZE] = "";
09441 $   strncpy_s (lst, sizeof (lst), list, strlen (list));
09442 
09443 $   char* ctx = NULL;
09444 $   for (char* p = strtok_s (lst, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx))
09445         {
09446 $       char* gp = strchr (p, ':');
09447 
09448 $       if (gp)
09449             {
09450 $           *gp++ = 0;
09451 
09452 $           if (_stricmp (p, parent) != 0) { continue; }
09453 
09454 $           if (info) if (_stricmp (gp, info->szExeFile) == 0)  // Was &&, but MSVC /analyze is so paranoid
09455                 {$ return islower ((unsigned char) *gp)? +1 : -1; }
09456             }
09457         else
09458             {
09459 $           if (_stricmp (p, parent) == 0)
09460                 {$ return islower ((unsigned char)  *p)? +1 : -1; }
09461             }
09462         }
09463 
09464 $   return 0;
09465     }
09466 
09467 //-----------------------------------------------------------------------------------------------------------------
09468 
09469 void _txWatchdogTerminator (void* timeout)  // Or Watchcat? Possibly will change in future versions
09470     {
09471 $3  if (_TX_ARGUMENT_FAILED (timeout)) return;
09472 
09473 $   Sleep (*(int*) timeout);  //-V206
09474 
09475 $   OutputDebugString ("\n");
09476     txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n",  // Kinda static reflection...
09477                          _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow"));  //-V206
09478 $   DWORD parent = 0;
09479 $   if (_txIsParentListed (_TX_WAITABLE_PARENTS, &parent))
09480         {
09481         txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n",
09482                              _TX_VERSION, __func__, (unsigned long) parent);
09483 
09484 $       _txKillProcess (parent);
09485 
09486 $       HWND console = GetConsoleWindow();
09487 $       PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09488 $       PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09489         }
09490 
09491     txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__);
09492 $   Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09493     }
09494 
09495 #endif // TX_COMPILED
09496 
09497 //}
09498 //-----------------------------------------------------------------------------------------------------------------
09499 
09500 //-----------------------------------------------------------------------------------------------------------------
09501 //{          Tools
09502 //-----------------------------------------------------------------------------------------------------------------
09503 
09504 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09505 
09506 // You are here, little hacker?
09507 
09508 int _txTaskKill (const char i[] /*= NULL*/,
09509                  const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/,
09510                  unsigned   x   /*= 0*/)
09511     {
09512     // ...so tired of it already...
09513 
09514     #define name          i  // Great name!
09515     #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine
09516     #define pid           x  // Another great name, isn't it?
09517 
09518 $3  if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false;  //-V560 //-V601
09519 
09520 $   wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L"";
09521     if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); }
09522 
09523 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09524 $   assert (sshot); if (!sshot) return 0;  //-V547
09525 
09526 $   int killed = 0;
09527 
09528 $   PROCESSENTRY32 info = { sizeof (info) };
09529 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09530         {
09531         bool kill = false;
09532 
09533         if (!kill && pid  && info.th32ParentProcessID        == pid) {$ kill = true; }  //-V560
09534 
09535         if (!kill && name && _stricmp (info.szExeFile, name) == 0)   {$ kill = true; }
09536 
09537         if (!kill)
09538             {
09539             wchar_t cmdLineW[_TX_BUFSIZE] = L"";
09540             if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; }
09541 
09542             if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW))    {$ kill = true; }
09543             }
09544 
09545         if (kill)
09546             {
09547 $           if (_txKillProcess (info.th32ProcessID))
09548                 {$ killed++; }
09549             }
09550         }
09551 
09552 $   CloseHandle (sshot);
09553 
09554 $   return killed;
09555 
09556     #undef name
09557     #undef cmdLine
09558     #undef pid
09559     }
09560 
09561 //-----------------------------------------------------------------------------------------------------------------
09562 
09563 bool _txKillProcess (DWORD pid)
09564     {
09565 $3  if (_TX_ARGUMENT_FAILED (pid)) return false;
09566 
09567 $   HANDLE token = INVALID_HANDLE_VALUE;
09568 $   OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted;
09569 
09570 $   LUID luid = {};
09571 $   LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted;
09572 
09573 $   TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}};
09574 $   TOKEN_PRIVILEGES old  = {};
09575 
09576 $   DWORD oldSz = 0;
09577 $   AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted;
09578 
09579 $   HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid);
09580 $   if (!proc) return false;
09581 
09582 $   bool ok = !!Win32::TerminateProcess (proc, 0);
09583 $   CloseHandle (proc);
09584 
09585 $   return ok;
09586     }
09587 
09588 //-----------------------------------------------------------------------------------------------------------------
09589 
09590 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/)
09591     {
09592 $4  static PROCESSENTRY32 info = { sizeof (info) };
09593 $   if (!pid) return &info;
09594 
09595 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09596 $   assert (sshot); if (!sshot) return NULL;  //-V547
09597 
09598 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09599         if (info.th32ProcessID == pid) break;
09600 
09601 $   CloseHandle (sshot);
09602 
09603 $   return &info;
09604     }
09605 
09606 //-----------------------------------------------------------------------------------------------------------------
09607 
09608 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/)
09609     {
09610 $6  if (_TX_ARGUMENT_FAILED (cmdLine))        return false;
09611 $   if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false;  //-V547
09612 
09613 $   if (pid == (unsigned) _getpid())
09614         {
09615 $       wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1);
09616 $       return true;
09617         }
09618 
09619 $   HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
09620     if (!proc) {$ return false; }
09621 
09622 $   Win32::PROCESS_BASIC_INFORMATION pbi = {};
09623 $   bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0);
09624 
09625     // Should use ReadProcessMemory() because the info is actually in another address space
09626 
09627 $   Win32::PEB peb = {};
09628     if (ok && pbi.PebBaseAddress)        {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress,        &peb,    sizeof (peb),    NULL); }
09629 
09630 $   Win32::RTL_USER_PROCESS_PARAMETERS params = {};
09631     if (ok && peb.ProcessParameters)     {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters,     &params, sizeof (params), NULL); }
09632 
09633 $   *cmdLine = 0;
09634     if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine,  //-V106
09635                                                                        MIN  (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2),  //-V202
09636                                                                        NULL); }
09637 $   CloseHandle (proc) asserted;
09638 
09639 $   return ok;
09640     }
09641 
09642 //-----------------------------------------------------------------------------------------------------------------
09643 
09644 #define RVA_(type, module, addr)  ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) )
09645 
09646 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/)
09647     {
09648 $4  assert (module);
09649 
09650 $   IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0);
09651 $   IMAGE_NT_HEADERS* ntHdr  = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew);
09652 
09653 $   return (dosHdr->e_magic  == IMAGE_DOS_SIGNATURE &&
09654             ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL;
09655     }
09656 
09657 //-----------------------------------------------------------------------------------------------------------------
09658 
09659 // TXLib continues to hack the reality to make your life better, sweeter and easier
09660 
09661 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/,
09662                              HMODULE module /*= NULL*/, bool debug /*= false*/)
09663     {
09664 $4  if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module);
09665 
09666 $   if (_TX_ARGUMENT_FAILED (funcName)) return 0;
09667 $   if (_TX_ARGUMENT_FAILED (newFunc))  return 0;
09668 
09669 $   if (!module) module = GetModuleHandle (NULL);
09670 $   if (!module) return 0;
09671 
09672 $   HMODULE dll     = (dllName)? GetModuleHandle (dllName)       : NULL;
09673 $   PROC    oldFunc = (dll)?     GetProcAddress  (dll, funcName) : NULL;
09674 
09675 $   if (useHotPatching && oldFunc)
09676         {
09677 $       const size_t jmpSz = 1 + sizeof (DWORD);  // sizeof (JMP rel instruction)
09678 
09679 $       DWORD oldRights = 0;
09680 $       if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0;
09681 
09682         // Overwrite oldFunc prolog with JMP trampoline to newFunc.
09683         // Calling oldFunc from any location will lead to newFunc call anyway.
09684 
09685 $       *(BYTE*)  ((char*)(uintptr_t) oldFunc + 0) = 0xE9;  // JMP rel
09686 $       *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF;  //-V206 //-V112 //-V2007 //-V104 //-V103
09687 
09688 $       FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz);
09689 
09690 $       VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights);
09691 
09692 $       return (uintptr_t) oldFunc;
09693         }
09694 
09695 //  For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255
09696 //  and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html.
09697 
09698 $   IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module);
09699     if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; }
09700 
09701 $   DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
09702 $   IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset);
09703 
09704 $   if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0;  //-V1027
09705 
09706 $   IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL;
09707 $   char*  impDll  = NULL;
09708 $   char*  impName = NULL;
09709 $   void** impPtr  = NULL;
09710 $   bool   found   = false;
09711 
09712     for (; desc->Name; desc++)
09713         {
09714 $       impDll = RVA_ (char*, module, desc->Name);
09715 $       if (dllName && _stricmp (impDll, dllName) != 0) continue;
09716 
09717 $       for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk),
09718              thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk);
09719 
09720              thunk0 && thunk1 && thunk1->u1.Function;
09721 
09722              thunk0++,
09723              thunk1++)
09724             {
09725             impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name;
09726             impPtr  = (void**)(uintptr_t)                         &thunk1->u1.Function;  // Should change it, so this is ptr
09727 
09728             if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL;
09729 
09730             if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName);
09731 
09732             if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) ||
09733                 (impName && _stricmp (funcName, impName) == 0))  //-V560
09734                 {
09735                 found = true;
09736                 break;
09737                 }
09738             }
09739 
09740 $       if (found) break;
09741         }
09742 
09743     if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n",
09744                                     funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found"));
09745 $   if (!found) return 0;
09746 
09747 $   DWORD rights = PAGE_READWRITE;
09748 $   if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0;
09749 
09750 $   *(uintptr_t*) impPtr = newFunc;
09751 
09752 $   VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights);
09753 
09754 $   return (uintptr_t) oldFunc;
09755     }
09756 
09757 #undef RVA_
09758 
09759 //-----------------------------------------------------------------------------------------------------------------
09760 
09761 bool _txInDll()
09762     {
09763 $4  MODULEENTRY32 mod = { sizeof (mod) };
09764 
09765 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
09766 $   assert (sshot); if (!sshot) return false;  //-V547
09767 
09768 $   bool inDll = false;
09769 
09770 $   for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod))
09771         {
09772 $       if (!mod.modBaseAddr) continue;
09773 
09774 $       IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr);
09775 
09776 $       inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0);
09777 
09778 $       if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize))  //-V104
09779             {$ break; }
09780         }
09781 
09782 $   CloseHandle (sshot);
09783 $   return inDll;
09784     }
09785 
09786 //-----------------------------------------------------------------------------------------------------------------
09787 
09788 bool _txIsConsoleSubsystem()
09789     {
09790 $4  IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders();
09791 
09792 $   return  ntHdr &&
09793             ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC &&
09794 
09795            (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI ||
09796             ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI);
09797     }
09798 
09799 //-----------------------------------------------------------------------------------------------------------------
09800 
09801 bool _txIsBadReadPtr (const void* address)
09802     {
09803     MEMORY_BASIC_INFORMATION mbi = {};
09804     if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true;
09805 
09806     if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS))  return true;  // Guard page -> bad ptr
09807 
09808     DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
09809 
09810     return !(mbi.Protect & readRights);
09811     }
09812 
09813 //-----------------------------------------------------------------------------------------------------------------
09814 
09815 void _txActivateWindow (HWND wnd, unsigned mode)
09816     {
09817 $1  EnableWindow (wnd, true);
09818 
09819 $   if (mode & 0x20)
09820         {
09821 $       ShowWindow (wnd, SW_MINIMIZE);
09822 $       ShowWindow (wnd, SW_RESTORE);
09823         }
09824 
09825 $   if (mode & 0x10)
09826         {
09827 $       int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0);
09828 
09829 $       AttachThreadInput (GetCurrentThreadId(), focus, true);
09830 
09831 $       ShowWindow (wnd, SW_SHOW);
09832 
09833 $       AllowSetForegroundWindow (ASFW_ANY);
09834 $       LockSetForegroundWindow (LSFW_UNLOCK);
09835 $       keybd_event ((byte) VK_LMENU, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); // https://stackoverflow.com/questions/10740346
09836 $       SetForegroundWindow (wnd);
09837 
09838 $       _txWaitFor (GetForegroundWindow() == wnd, 10*_TX_TIMEOUT);
09839 
09840 $       AttachThreadInput (GetCurrentThreadId(), focus, false);
09841         }
09842 
09843 $   if (mode & 0x08)
09844         {
09845 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
09846         }
09847 
09848 $   if (mode & 0x04)
09849         {
09850 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS);
09851         }
09852 
09853 $   if (mode & 0x02)
09854         {
09855 $       UpdateWindow (wnd);
09856         }
09857 
09858 $   if (mode & 0x01)
09859         {
09860 $       RECT r = {};
09861 $       GetWindowRect (wnd, &r);
09862 $       mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, r.left, r.top, 0, 0);
09863 $       Sleep (100);
09864 $       mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP,   r.left, r.top, 0, 0);
09865 $       Sleep (100);
09866         }
09867     }
09868 
09869 #endif // TX_COMPILED
09870 
09871 //}
09872 //-----------------------------------------------------------------------------------------------------------------
09873 
09875 //}
09876 //=================================================================================================================
09877 
09878 //=================================================================================================================
09879 //{          Internal TXLib window functions     (_txCanvas...)
09881 //=================================================================================================================
09882 
09883 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09884 
09885 unsigned WINAPI _txCanvas_ThreadProc (void* data)
09886     {
09887     #define SetClassLong_  SetClassLongPtr
09888     #define GCL_HICON_     GCLP_HICON
09889     #define GCL_HICONSM_   GCLP_HICONSM
09890     #define GCL_HCURSOR_   GCLP_HCURSOR
09891 
09892 $8  _txCanvas_ThreadId = GetCurrentThreadId();
09893 
09894 $   if (_TX_ARGUMENT_FAILED (data)) return false;  //-V601
09895 
09896 $   unsigned long stackSize = _TX_STACKSIZE;
09897 $   _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
09898 
09899 $   HWND wnd = _txCanvas_CreateWindow ((SIZE*) data);
09900 $   if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0;
09901 
09902 $   HICON   icon32 = LoadIcon         (NULL, "_TX_ICON");
09903 $   HICON   icon16 = LoadIcon         (NULL, "_TX_ICONSM");
09904 $   HCURSOR cursor = LoadCursor       (NULL, "_TX_CURSOR");
09905 $   HMENU   menu   = LoadMenu         (NULL, "_TX_MENU");
09906 $   HACCEL  accel  = LoadAccelerators (NULL, "_TX_ACCELERATORS");
09907 
09908 $   SetClassLong_ (wnd, GCL_HICON_,   (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32)));          //-V107 //-V112
09909 $   SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16)));          //-V107
09910 $   SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW)));  //-V107
09911 
09912     if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); }
09913 
09914 $   Win32::GdiSetBatchLimit (1);
09915 
09916     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n"));
09917 
09918 $   _txActivateWindow (wnd, 0x20);
09919 
09920 $   ShowWindow   (wnd, SW_SHOW);
09921 $   UpdateWindow (wnd);
09922 
09923 $   _txRunning = true;
09924 
09925 $   MSG msg = {};
09926 $   while (GetMessage (&msg, NULL, 0, 0))
09927         {
09928         if (!msg.hwnd) {$ continue; }
09929 
09930         if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; }
09931 
09932 $       TranslateMessage (&msg);
09933 $       DispatchMessage  (&msg);
09934 
09935 $       Sleep (0);
09936         }
09937 
09938 $   if (icon16) DestroyIcon (icon16);  // If Explorer is displaying Tray Notification, these
09939 $   if (icon32) DestroyIcon (icon32);  // calls will possibly fail, and we'll get resource leak.
09940 
09941 $   LeaveCriticalSection (&_txCanvas_LockBackBuf);
09942 
09943     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n"));
09944 
09945 $   if (_txWatchdogTimeout >= 0)
09946         {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09947 
09948 $   if (_txRunning && _txMain)         // Main window is destroyed but main() is still running.
09949         {                              // No chances for good termination, so use exit().
09950 $       _txCleanup();
09951 $       ::exit ((int) msg.wParam);     //-V202 //-V2509 //-V2014
09952         }
09953 
09954 $   _txCanvas_ThreadId = 0;
09955 $   return true;                       //-V601
09956 
09957     #undef SetClassLong
09958     #undef GCL_HICON_
09959     #undef GCL_HICONSM_
09960     #undef GCL_HCURSOR_
09961     }
09962 
09963 //-----------------------------------------------------------------------------------------------------------------
09964 
09965 HWND _txCanvas_CreateWindow (const SIZE* sizePtr)
09966     {
09967 $8  if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL;
09968 
09969 $   bool centered = false;
09970     if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; }
09971 
09972 $   SIZE screen  = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) };
09973 $   RECT rect    = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false);
09974 $   SIZE size    = { rect.right - rect.left, rect.bottom - rect.top };
09975 $   RECT conPos  = {};
09976 
09977 $   HWND console = _TX_CALL (Win32::GetConsoleWindow, ());
09978     if (console) {$ GetWindowRect (console, &conPos); }
09979 
09980 $   const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0);
09981 $   if (!wndClass) return (HWND) NULL;
09982 
09983 $   HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN,
09984                               (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT,
09985                               (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top  : CW_USEDEFAULT,
09986                                size.cx, size.cy, NULL, NULL, NULL, NULL);
09987 $   if (!wnd || !txWindow())
09988         {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; }
09989 
09990 $   HMENU menu = GetSystemMenu (txWindow(), false);
09991     if (!menu) {$ return txWindow(); }
09992 
09993 $   AppendMenu (menu, MF_SEPARATOR, 0, NULL)                       asserted;
09994 $   AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted;
09995 $   AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT,   "&About...")     asserted;
09996 
09997 $   return txWindow();
09998     }
09999 
10000 //-----------------------------------------------------------------------------------------------------------------
10001 
10002 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra)
10003     {
10004 $8  assert (classId);
10005 $   assert (wndProc);
10006 
10007 $   static char name[_TX_BUFSIZE] = "";
10008 $   _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ "
10009                                              _TX_VERSION "  " __FILE__ "  WndClass %08lX "
10010                                              "-------------[%s]-[TXLib]---*/",
10011                                              classId, (unsigned long) GetTickCount(), classId);
10012 $   WNDCLASS wc      = { sizeof (wc) };
10013 
10014 $   wc.lpszClassName = name;
10015 $   wc.lpfnWndProc   = wndProc;
10016 $   wc.style         = style;
10017 $   wc.cbWndExtra    = (wndExtra + 1) * (int) sizeof (long);
10018 
10019 $   wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
10020 $   wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush);
10021 
10022 $   ATOM atom = RegisterClass (&wc);
10023     if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; }
10024 
10025 $   return (const char*)(uintptr_t) atom;
10026     }
10027 
10028 //-----------------------------------------------------------------------------------------------------------------
10029 
10030 int _txCanvas_SetRefreshLock (int count)
10031     {
10032 $8  int oldCount = _txCanvas_RefreshLock;
10033 
10034 $   _txCanvas_RefreshLock = count;
10035 
10036 $   HWND wnd = txWindow();
10037 
10038 $   if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd)
10039         {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
10040 
10041 $   return oldCount;
10042     }
10043 
10044 //-----------------------------------------------------------------------------------------------------------------
10045 
10046 HICON _txCreateTXIcon (int size)
10047     {
10048 $8  if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL;  //-V112 //-V560
10049 
10050 $   const unsigned char image32 [32*32+1] =
10051         "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0"
10052         "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0"
10053         "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0"
10054         "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0"
10055         "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0"
10056         "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0"
10057         "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0"
10058         "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000";
10059 
10060 $   const unsigned char image16 [16*16+1] =
10061         "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990"
10062         "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000";
10063 
10064 $   const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0,
10065                                       0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff };
10066 
10067 $   const unsigned char* image = (size == 32)? image32 : image16;  //-V112
10068 
10069 $   POINT sz = { size, size };
10070 $   HDC dcMask  = _txBuffer_Create (txWindow(), &sz); assert (dcMask);
10071 $   HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor);
10072 
10073 $   for (int i = 0; i < size*size; i++)
10074         {
10075         assert (In (std::nomeow, image[i], '0', '9') ||
10076                 In (std::nomeow, image[i], 'A', 'F'));
10077 
10078         Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']);
10079         }
10080 
10081 $   ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask,  OBJ_BITMAP),
10082                                   (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) };
10083 
10084 $   HICON icon = CreateIconIndirect (&info);
10085 $   assert (icon);
10086 
10087 $   _txBuffer_Delete (&dcMask)  asserted;
10088 $   _txBuffer_Delete (&dcColor) asserted;
10089 
10090 $   return icon;
10091     }
10092 
10093 #endif // TX_COMPILED
10094 
10095 //-----------------------------------------------------------------------------------------------------------------
10096 
10097 inline bool _txCanvas_OK()
10098     {
10099     return _txCanvas_ThreadId   &&
10100            _txCanvas_Window     &&
10101            _txCanvas_BackBuf[0] &&
10102            _txCanvas_BackBuf[1] &&
10103            _txCanvas_Pixels;
10104     }
10105 
10106 //}
10107 //=================================================================================================================
10108 
10109 //=================================================================================================================
10110 //{          Main window event handlers          (_txCanvas_On...)
10112 //=================================================================================================================
10114 
10115 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10116 
10117 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
10118     {
10119 #if defined (_TX_ALLOW_TRACE)
10120 
10121     int inTX = _txLoc::Cur.inTX++;
10122 
10123     if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)",
10124                                      2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar);
10125     _txLoc::Cur.inTX = inTX;
10126 
10127 #endif
10128 
10129 $8  if (msg == WM_KEYDOWN && wpar == VK_F12 &&
10130         GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU))
10131         {
10132 $       _txCanvas_OnCmdABOUT (wnd,      wpar);
10133 $       return DefWindowProc (wnd, msg, wpar, lpar);
10134         }
10135 
10136     WNDPROC altWndProc = _txAltWndProc;  // Cache to prevent change from main thread
10137     if (altWndProc)
10138         {
10139 $       LRESULT res = altWndProc (wnd, msg, wpar, lpar);
10140 $       if (res) return res;
10141         }
10142 
10143     static bool bkErased = false;
10144 
10145     switch (msg)
10146         {
10147         case WM_CREATE:         {$     _txCanvas_OnCREATE     (wnd);                    return 0; }
10148 
10149         case WM_CLOSE:          {$ if (_txCanvas_OnCLOSE      (wnd))  break;       else return 0; }
10150         case WM_DESTROY:        {$     _txCanvas_OnDESTROY    (wnd);                    return 0; }
10151 
10152         case WM_ERASEBKGND:     {$ if (!bkErased) { bkErased = true;  break; }     else return 1; }
10153         case WM_SIZE:           {$                  bkErased = false; break;                      }
10154 
10155         case WM_PAINT:          {$     _txCanvas_OnPAINT      (wnd);                    return 0; }
10156 
10157         case WM_TIMER:          {$     _txCanvas_OnTIMER      (wnd, wpar);              return 0; }
10158 
10159         case WM_KEYUP:          {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, false)) return 0; else break; }
10160         case WM_KEYDOWN:        {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, true))  return 0; else break; }
10161         case WM_CHAR:           {$ if (_txCanvas_OnCHAR       (wnd, wpar, lpar))        return 0; else break; }
10162 
10163         case WM_LBUTTONUP:
10164         case WM_LBUTTONDOWN:
10165         case WM_RBUTTONUP:
10166         case WM_RBUTTONDOWN:
10167         case WM_MBUTTONUP:
10168         case WM_MBUTTONDOWN:
10169         case WM_MOUSEMOVE:      {$     _txCanvas_OnMOUSEMOVE  (wnd, wpar, lpar);        return 0; }
10170 
10171         case WM_MOUSELEAVE:     {$     _txCanvas_OnMOUSELEAVE (wnd);                    return 0; }
10172 
10173         case _TX_WM_CREATEWND:  {$     _txCanvas_OnCREATEWND  (wnd, wpar, lpar);        return 0; }
10174         case _TX_WM_DESTROYWND: {$     _txCanvas_OnDESTROYWND (wnd, wpar, lpar);        return 0; }
10175 
10176         case WM_NULL:           {$                                                      return 0; }
10177 
10178         default: break;  //-V2522
10179         }
10180 
10181     if (msg == WM_SYSCOMMAND) switch (wpar)
10182         {
10183         case _TX_IDM_ABOUT:     {$     _txCanvas_OnCmdABOUT   (wnd, wpar);              return 0; }
10184         case _TX_IDM_CONSOLE:   {$     _txCanvas_OnCmdCONSOLE (wnd, wpar);              return 0; }
10185 
10186         default: break;  //-V2522
10187         }
10188 
10189 $   return DefWindowProc (wnd, msg, wpar, lpar);
10190     }
10191 
10192 //-----------------------------------------------------------------------------------------------------------------
10193 
10194 bool _txCanvas_OnCREATE (HWND wnd)
10195     {
10196 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10197 
10198 $   _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]);
10199 $   _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL);              assert (_txCanvas_BackBuf[1]);
10200 
10201 $   if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0;
10202 $   assert (_txCanvas_RefreshTimer);
10203 
10204 $   _txCanvas_UserDCs = new ::std::vector <HDC>;
10205 
10206 $   _txCanvas_Window = wnd;
10207 
10208 $   txSetDefaults();
10209 
10210 $   return true;
10211     }
10212 
10213 //-----------------------------------------------------------------------------------------------------------------
10214 
10215 bool _txCanvas_OnDESTROY (HWND wnd)
10216     {
10217 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10218 
10219     // Инициируем остановку цикла сообщений
10220 
10221 $   PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS);
10222 
10223 $   if (!_txCanvas_Window) return false;
10224 
10225     // Indicate that we are about to manually terminate
10226 
10227 $   _txExit = true;
10228 
10229     // Lock GDI resources
10230 
10231 $   bool locked = false;
10232 $   _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT);
10233 $   if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources");
10234 
10235     // Освобождаем пользовательские ресурсы
10236 
10237 $   if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty())
10238         {
10239 $       txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size());  //-V202
10240 $       Sleep (_TX_TIMEOUT);
10241 
10242 $       for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i));
10243 $       _txCanvas_UserDCs->clear();
10244         }
10245 
10246     // Освобождаем ресурсы, связанные с окном
10247 
10248 $   if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted;
10249 
10250 $   if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1])  asserted;
10251 $   if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0])  asserted;
10252 $   _txCanvas_Pixels = NULL;
10253 
10254 $   txUnlock();
10255 
10256     // Indicate that we are destroyed
10257 
10258 $   _txCanvas_Window = NULL;
10259 
10260 $   return true;
10261     }
10262 
10263 //-----------------------------------------------------------------------------------------------------------------
10264 
10265 bool _txCanvas_OnCLOSE (HWND wnd)  //-V2009 //-V2558
10266     {
10267 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10268 $   if (!_txCanvas_OK())           return false;
10269 
10270 $   if (_txMain && _txRunning &&
10271         txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n"
10272                       "Лучше подождать, когда main() завершится - это отображается в заголовке окна.",
10273                       txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false;
10274 $   return true;
10275     }
10276 
10277 //-----------------------------------------------------------------------------------------------------------------
10278 
10279 bool _txCanvas_OnTIMER (HWND wnd, WPARAM)
10280     {
10281 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10282 
10283 $   if (_txCanvas_RefreshLock > 0 || !_txRunning) return false;
10284 
10285 $   InvalidateRect (wnd, NULL, false) asserted;
10286 $   UpdateWindow   (wnd)              asserted;
10287 
10288 $   return true;
10289     }
10290 
10291 //-----------------------------------------------------------------------------------------------------------------
10292 
10293 bool _txCanvas_OnPAINT (HWND wnd)
10294     {
10295 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10296 $   if (!_txCanvas_OK())           return false;
10297 
10298 $   bool forceRedraw = GetAsyncKeyState (VK_MENU)  && GetAsyncKeyState (VK_CONTROL) &&
10299                        GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT);
10300 
10301 $   PAINTSTRUCT ps = {};
10302 $   HDC wndDc = BeginPaint (wnd, &ps);
10303 $   if (!wndDc) return false;
10304 
10305 $   HDC dc0 = _txCanvas_BackBuf[0],
10306         dc1 = _txCanvas_BackBuf[1];
10307 
10308 $   RECT r = {};
10309 $   GetClientRect (wnd, &r) asserted;
10310 $   POINT wndSize = { r.right - r.left, r.bottom - r.top };
10311 
10312 $   POINT dcSize = txGetExtent (dc1);
10313 
10314 $   if ((_txCanvas_RefreshLock <= 0 || forceRedraw) &&
10315         txLock (false))
10316         {
10317 $       Win32::BitBlt          (dc1,   0, 0, dcSize.x,  dcSize.y,  dc0, 0, 0, SRCCOPY);
10318 
10319 $       if (_txConsole >= 0)
10320             {$ _txConsole_Draw (dc1); }
10321 
10322 $       txUnlock();
10323         }
10324 
10325     // Magic 100500 value is used to completely block screen refresh.
10326     // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL.
10327     // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers
10328     // themselves.
10329     // Yes guys, with all your software installed. :(
10330 
10331 $   if (_txCanvas_RefreshLock != 100500)
10332         {
10333         if (_txSwapBuffers)
10334             {
10335 $           _txSwapBuffers     (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10336             }
10337         else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y)
10338             {
10339 $           Win32::BitBlt      (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0,                     SRCCOPY);
10340             }
10341         else
10342             {
10343 $           Win32::SetStretchBltMode (wndDc, HALFTONE);
10344 $           Win32::StretchBlt  (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10345             }
10346         }
10347 
10348 $   EndPaint (wnd, &ps) asserted;
10349 
10350 $   return true;
10351     }
10352 
10353 //-----------------------------------------------------------------------------------------------------------------
10354 
10355 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info)
10356     {
10357 $8  INPUT_RECORD evt[2] = {};
10358 
10359 $   evt[0].EventType                        = KEY_EVENT;
10360 $   evt[0].Event.KeyEvent.bKeyDown          = true;
10361 $   evt[0].Event.KeyEvent.wRepeatCount      = 1;
10362 $   evt[0].Event.KeyEvent.uChar.AsciiChar   = (char) (ch);
10363 $   evt[0].Event.KeyEvent.wVirtualScanCode  = (WORD) (info >> 16);
10364 $   evt[0].Event.KeyEvent.wVirtualKeyCode   = (WORD) MapVirtualKey ((WORD) (info >> 16), 3);  // 3 == MAPVK_VSC_TO_VK_EX
10365 $   evt[0].Event.KeyEvent.dwControlKeyState = 0;
10366 
10367 $   evt[1] = evt[0];
10368 $   evt[1].Event.KeyEvent.bKeyDown          = false;
10369 
10370 $   DWORD written = 0;
10371 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE),  evt, 2, &written);
10372 
10373 $   return true;
10374     }
10375 
10376 //-----------------------------------------------------------------------------------------------------------------
10377 
10378 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down)
10379     {
10380 $8  INPUT_RECORD evt = {};
10381 
10382 $   evt.EventType                           = KEY_EVENT;
10383 $   evt.Event.KeyEvent.bKeyDown             = down;
10384 $   evt.Event.KeyEvent.wRepeatCount         = 1;
10385 $   evt.Event.KeyEvent.uChar.AsciiChar      = (char)  MapVirtualKey ((WORD) vk, 2);           // 2 == MAPVK_VK_TO_CHAR
10386 $   evt.Event.KeyEvent.wVirtualScanCode     = (WORD)  (info >> 16);
10387 $   evt.Event.KeyEvent.wVirtualKeyCode      = (WORD)  vk;
10388 $   evt.Event.KeyEvent.dwControlKeyState    = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0;
10389 
10390 $   if (evt.Event.KeyEvent.uChar.AsciiChar) return false;  // Let TranslateMessage() and WM_CHAR do the job
10391 
10392 $   DWORD written = 0;
10393 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written);
10394 
10395 $   return true;
10396     }
10397 
10398 //-----------------------------------------------------------------------------------------------------------------
10399 
10400 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords)
10401     {
10402 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10403 $   if (!_txCanvas_OK())           return false;
10404 
10405 $   if (_txMousePos.x == -1 && _txMousePos.y == -1)
10406         {
10407 $       TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT };
10408 $       TrackMouseEvent (&track);
10409         }
10410 
10411 $   _txMousePos.x   = LOWORD (coords);
10412 $   _txMousePos.y   = HIWORD (coords);
10413 $   _txMouseButtons = (unsigned) buttons;  //-V202
10414 
10415 $   return true;
10416     }
10417 
10418 //-----------------------------------------------------------------------------------------------------------------
10419 
10420 bool _txCanvas_OnMOUSELEAVE (HWND)
10421     {
10422 $8  _txMousePos.x   = -1;
10423 $   _txMousePos.y   = -1;
10424 $   _txMouseButtons = 0;
10425 
10426 $   return true;
10427     }
10428 
10429 //-----------------------------------------------------------------------------------------------------------------
10430 
10431 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar)
10432     {
10433 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10434 
10435 $   const CREATESTRUCT* create = (CREATESTRUCT*) lpar;
10436 
10437 $   HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style,
10438                                create->x, create->y, create->cx, create->cy,
10439                                create->hwndParent, create->hMenu, NULL, create->lpCreateParams);
10440 
10441 $   *(HWND*) create->hInstance = wnd;
10442 
10443 $   return true;
10444     }
10445 
10446 //-----------------------------------------------------------------------------------------------------------------
10447 
10448 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar)
10449     {
10450 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10451 
10452 $   DestroyWindow ((HWND) lpar);
10453 
10454 $   return false;
10455     }
10456 
10457 //-----------------------------------------------------------------------------------------------------------------
10458 
10459 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd)
10460     {
10461 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10462 
10463 $   HWND console = Win32::GetConsoleWindow();
10464 $   if (!console) return false;
10465 
10466 $   bool visible = !!IsWindowVisible (console);
10467 
10468 $   ShowWindow (console, visible? SW_HIDE : SW_RESTORE);
10469 
10470 $   visible = !!IsWindowVisible (console);
10471 $   CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED);  //-V202
10472 
10473 $   return true;
10474     }
10475 
10476 //-----------------------------------------------------------------------------------------------------------------
10477 
10478 bool _txCanvas_OnCmdABOUT (HWND, WPARAM)
10479     {
10480 $8  //{ Overriding the missing names, if the set is incomplete
10481 
10482     #if defined (__MODULE)
10483         #define ABOUT_NAME_    __MODULE
10484     #else
10485         #define ABOUT_NAME_    "TXLib"
10486     #endif
10487 
10488     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10489 
10490         #ifndef __MODULE
10491         #define __MODULE       "TXLib"                           "\n"  "#define __MODULE to set the name.\n"
10492         #endif
10493 
10494         #ifndef __VERSION
10495         #define __VERSION      "(0.000000000)."                  "\n" "#define __VERSION to set the string value.\n"
10496         #endif
10497 
10498         #ifndef __DESCRIPTION
10499         #define __DESCRIPTION  "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n"
10500         #endif
10501 
10502         #ifndef __AUTHOR
10503         #define __AUTHOR       "(Непонятно кто)."                "\n" "#define __AUTHOR to override this name."
10504         #endif
10505 
10506     #endif
10507     //}
10508 
10509 $   static char text[_TX_BUFSIZE] = "";
10510 
10511 $   _tx_snprintf_s (text, sizeof (text) - 1,
10512 
10513                     "Application:\n\n"
10514 
10515                     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10516                         __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n"
10517                     #else
10518                         "Здесь могла бы быть Ваша реклама :)\n"
10519                         "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n"
10520                     #endif
10521 
10522                     "\n" "%s", _txAppInfo());
10523 
10524 $   txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION);
10525 
10526     // And a bit of HTTP-code in C++ function:
10527 
10528     goto http;
10529     http://sizeof.livejournal.com
10530 
10531 $   return true;
10532 
10533     #undef ABOUT_NAME_
10534     }
10535 
10536 #endif // TX_COMPILED
10537 
10539 //}
10540 //=================================================================================================================
10541 
10542 //=================================================================================================================
10543 //{          Console-support functions           (_txConsole...)
10545 //=================================================================================================================
10547 
10548 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10549 
10550 HWND _txConsole_Attach()
10551     {
10552 $1  HWND console = Win32::GetConsoleWindow();
10553 
10554 $   if (!console)
10555         {
10556 $       bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem());
10557 
10558 $       Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb();
10559 $       assert (teb);
10560 $       assert (teb->ProcessEnvironmentBlock);
10561 
10562 $       Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters;
10563 $       assert (params);
10564 
10565 $       if (minimizeConsole)  // The fact that ShowWindow parameter of the program's console is taken from calling
10566                               // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo()
10567                               // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :(
10568                               // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke!
10569             {
10570 $           params->dwFlags    |= STARTF_USESHOWWINDOW;
10571 $           params->wShowWindow = SW_MINIMIZE;
10572             }
10573 
10574 $       AllocConsole();
10575 $       console = Win32::GetConsoleWindow();
10576         }
10577 
10578 $   if (!console) return NULL;
10579 
10580 $   txSetLocale();                                // Устанавливаем русскую кодовую страницу для консоли Windows
10581 
10582 $   _txConsole_SetUnicodeFont();                  // Впечатлительным лучше сюда не смотреть.
10583 
10584 $   if (!_txIsConsoleSubsystem())
10585         {$ txReopenStdio(); }                     // Переоткрываем потоки ввода-вывода, если subsystem != console
10586 
10587 $   return console;
10588     }
10589 
10590 //-----------------------------------------------------------------------------------------------------------------
10591 
10592 int txSetLocale (int codepage /*= _TX_CODEPAGE*/,
10593                  const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/)
10594     {
10595 $1  int oldPage = GetConsoleOutputCP();
10596 
10597     // Устанавливаем нужную кодовую страницу для консоли Windows
10598 
10599 $   if (codepage)
10600         {
10601 $       SetConsoleCP       (codepage);
10602 $       SetConsoleOutputCP (codepage);
10603         }
10604 
10605     // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии
10606     // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным
10607     // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN -
10608     // обозначение кодовой страницы (например, для русского языка - CP1251).
10609 
10610 $   if (locale)
10611         {
10612 $       setlocale (LC_ALL,     locale);
10613 $       setlocale (LC_NUMERIC, "C");              // Return to decimal point (3.14) instead of comma (3,14) in floating numbers
10614         }
10615 
10616     #ifndef __CYGWIN__
10617 
10618 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10619 
10620 $   if (wLocale && !wine)
10621         {
10622 $       _wsetlocale (LC_ALL,     wLocale);
10623 $       _wsetlocale (LC_NUMERIC, L"C");           // L"C" (see above)
10624         }
10625 
10626     #endif
10627 
10628     (void) wLocale;
10629 
10630 $   return oldPage;
10631     }
10632 
10633 //-----------------------------------------------------------------------------------------------------------------
10634 
10635 void txReopenStdio()
10636     {
10637 $1  // Переоткрываем заново <s>Америку</s> потоки ввода-вывода
10638 
10639 $   fflush (stdout);
10640 $   fflush (stderr);
10641 
10642 $   FILE* f = NULL;
10643 
10644     #ifndef __CYGWIN__
10645 
10646 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE),  _O_TEXT), "r"); assert (f); *stdin  = *f;
10647 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f;
10648 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE),  _O_TEXT), "w"); assert (f); *stderr = *f;
10649 
10650     #else
10651 
10652 $   f = _fdopen (STDIN_FILENO,  "r"); assert (f); *stdin  = *f;
10653 $   f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f;
10654 $   f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f;
10655 
10656     #endif
10657 
10658 $   setvbuf (stdin,  NULL, _IONBF, 0);
10659 $   setvbuf (stdout, NULL, _IONBF, 0);
10660 $   setvbuf (stderr, NULL, _IONBF, 0);
10661 
10662 $   ::std::ios::sync_with_stdio();
10663     }
10664 
10665 //-----------------------------------------------------------------------------------------------------------------
10666 
10667 inline bool _txConsole_OK()
10668     {
10669     return Win32::GetConsoleWindow() != NULL;
10670     }
10671 
10672 //-----------------------------------------------------------------------------------------------------------------
10673 
10674 bool _txConsole_Detach (bool activate)
10675     {
10676 $1  HWND console = Win32::GetConsoleWindow();
10677 $   if (!console) return false;
10678 
10679 $   EnableWindow (console, true);
10680 
10681 $   if (activate)
10682         {
10683 $       if (!IsWindowVisible (console))
10684             {$ ShowWindow (console, SW_MINIMIZE); }
10685 
10686 $       _txActivateWindow (console, 0xFF);
10687 $       return true;
10688         }
10689     else
10690         {
10691 $       return !!FreeConsole();
10692         }
10693     }
10694 
10695 //-----------------------------------------------------------------------------------------------------------------
10696 
10697 bool _txConsole_Draw (HDC dc)
10698     {
10699 $8  if (_TX_HDC_FAILED (dc)) return false;
10700 
10701 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10702 
10703 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
10704 $   BOOL ok = GetConsoleScreenBufferInfo (out, &con);
10705 $   if (!ok) return false;
10706 
10707 $   POINT size = { con.srWindow.Right  - con.srWindow.Left + 1,
10708                    con.srWindow.Bottom - con.srWindow.Top  + 1 };
10709 
10710 $   SIZE fontSz = { 12, 16 };
10711 $   Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted;
10712 
10713 $   COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
10714                           0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF };
10715 
10716 $   for (short y = 0; y < size.y; y++)
10717         {
10718         static char chr [_TX_BUFSIZE + 1] = "";  // [con.dwSize.X + 1]; maybe will be truncated
10719         static WORD atr [_TX_BUFSIZE + 1] = {};  // [con.dwSize.X + 1]; maybe will be truncated
10720         COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) };
10721         DWORD read  = 0;
10722 
10723         if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue;
10724         if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue;
10725 
10726         for (int x = 0, xEnd = size.x; x < size.x; x = xEnd)
10727             {
10728             Win32::SetTextColor (dc, pal [ atr[x]       & 0x0F]);
10729             Win32::SetBkColor   (dc, pal [(atr[x] >> 4) & 0x0F]);
10730             Win32::SetBkMode    (dc,      (atr[x]       & 0xF0)? OPAQUE : TRANSPARENT);
10731 
10732             for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;}
10733 
10734             Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)),
10735                                 ROUND (fontSz.cy *  y), chr + x, xEnd - x) asserted;
10736             }
10737         }
10738 
10739 $   Win32::SetTextColor (dc, pal [ con.wAttributes       & 0x0F]);
10740 $   Win32::SetBkColor   (dc, pal [(con.wAttributes >> 4) & 0x0F]);
10741 $   Win32::SetBkMode    (dc, TRANSPARENT);
10742 
10743 $   if (_txConsole_IsBlinking &&
10744         In (std::nomeow, con.dwCursorPosition, con.srWindow) &&
10745         GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval &&
10746         GetForegroundWindow() == txWindow())
10747         {
10748 $       Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)),
10749                             ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1,
10750                             "_", 1) asserted;
10751         }
10752 
10753 $   return true;
10754     }
10755 
10756 #endif // TX_COMPILED
10757 
10758 //-----------------------------------------------------------------------------------------------------------------
10759 //{          Welcome to the Duck Side! Together we will rule the Bathroom!
10760 //-----------------------------------------------------------------------------------------------------------------
10761 
10762 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10763 
10764 bool _txConsole_SetUnicodeFont()
10765     {
10766 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10767                                                   // Beer compatibility may be added in future versions...
10768 $   if (wine)                                     // Минздрав РФ предупреждает: чрезмерное употребление wine
10769         {                                         // вредит Вашему здоровью.
10770 $       Win32::GetNumberOfConsoleFonts = NULL;
10771 $       Win32::GetCurrentConsoleFont   = NULL;
10772 $       Win32::SetConsoleFont          = NULL;
10773 
10774 $       return false;
10775         }
10776 
10777     // Начиная с Висты все хорошо...
10778 
10779 $1  if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx)
10780         {
10781 $       HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10782 
10783 $       Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) };
10784 $       if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false;
10785 
10786 $       info.FontFamily = 0x36;                                                    // Unicode fixed-pitch
10787 $       if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2);  // Terminal font is too small
10788 
10789 $       if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0)    // Consolas is allowed too
10790             {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); }
10791 
10792 $       return !!Win32::SetCurrentConsoleFontEx (out, false, &info);
10793         }
10794 
10795     // ...а до этого все не так сладко
10796 
10797 $   const unsigned uniFont = 10;                  // The Internet and W2K sources know this magic number
10798 $   const unsigned uniSize = 20;                  // Size of the font desired, should be > max # of Raster Fonts  //-V2551
10799 $   bool ok = true;
10800 
10801     // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font.
10802 
10803 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10804 
10805 $   unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ());
10806 $   if (fonts && fonts <= uniFont)
10807         {
10808 $       HRESULT init = Win32::CoInitialize (NULL);
10809 $       size_t sz = 0;
10810 
10811 $       char link [MAX_PATH] = "";
10812 $       getenv_s (&sz, link, sizeof (link) - 1, "TEMP");
10813 $       strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1);
10814 
10815 $       char comspec [MAX_PATH] = "";
10816 $       getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC");
10817 
10818 $       (void) _unlink (link);
10819 
10820 $       _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted;
10821 
10822 $       ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32);  // Sic!  //-V112 //-V566
10823         if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); }
10824 
10825 $       (void) _unlink (link);
10826 
10827 $       if (init == S_OK) Win32::CoUninitialize();
10828         }
10829 
10830     // If Unicode font is not already set, do set it.
10831 
10832 $   Win32::CONSOLE_FONT_INFO cur = {};
10833 $   _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur));
10834 
10835 $   ok &= (cur.nFont >= uniFont);
10836     if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); }
10837 
10838 $   HWND console = Win32::GetConsoleWindow();
10839 $   InvalidateRect (console, NULL, false);
10840 $   UpdateWindow   (console);
10841 
10842 $   return ok;
10843     }
10844 
10845 #endif // TX_COMPILED
10846 
10847 //-----------------------------------------------------------------------------------------------------------------
10848 //{          The assistants to the nightmare. You can use it freely to make your own nightmare sweet.
10849 
10850 #define      _TX_TRY                { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error;
10851 #define      _TX_CHECKED( cmd )     { if (FAILED (__tx_error = (cmd))) goto __tx_catch; }
10852 #define      _TX_FAIL               { __tx_error = E_FAIL; goto __tx_catch; }
10853 #define      _TX_RETRY              { __tx_error = S_OK;   goto __tx_try;   }
10854 #define      _TX_OK                 ( SUCCEEDED (__tx_error) )
10855 #define      _TX_CATCH              goto __tx_finally; __tx_catch:
10856 #define      _TX_RETURN             goto __tx_finally;
10857 #define      _TX_FINALLY            __tx_finally:
10858 #define      _TX_ENDTRY             }
10859 
10860 //}
10861 //-----------------------------------------------------------------------------------------------------------------
10862 
10863 // Мало не покажется
10864 
10865 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10866 
10867 bool _txCreateShortcut (const char shortcutName[],
10868                         const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/,
10869                         const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/,
10870                         int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/)
10871     {
10872 $1  if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false;
10873 $   if (_TX_ARGUMENT_FAILED (fileToLink   && *fileToLink))   return false;
10874 
10875     #if defined (__IShellLinkDataList_INTERFACE_DEFINED__)
10876 
10877 $   IShellLink* shellLink = NULL;
10878 $   IShellLinkDataList* dataList = NULL;
10879 $   IPersistFile* file = NULL;
10880 
10881 $   HRESULT init = Win32::CoInitialize (NULL);
10882 
10883     _TX_TRY
10884         {
10885 $       _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink));
10886 $       if (!shellLink) _TX_FAIL;
10887 
10888 $       shellLink->SetPath (fileToLink);
10889 $       shellLink->SetArguments (args);
10890 $       shellLink->SetWorkingDirectory (workDir);
10891 $       shellLink->SetDescription (description);
10892 $       shellLink->SetShowCmd (cmdShow);
10893 $       shellLink->SetIconLocation (iconFile, iconIndex);
10894 
10895 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList));
10896 $       if (!dataList) _TX_FAIL;
10897 
10898 $       Win32::NT_CONSOLE_PROPS props =
10899           {{sizeof (props), NT_CONSOLE_PROPS_SIG},
10900 
10901             FOREGROUND_LIGHTGRAY,                       // wFillAttribute
10902             FOREGROUND_MAGENTA | BACKGROUND_WHITE,      // wPopupFillAttribute
10903            {bufSize.X, bufSize.Y},                      // dwScreenBufferSize
10904            {wndSize.X, wndSize.Y},                      // dwWindowSize
10905            {wndOrg.X,  wndOrg.Y},                       // dwWindowOrigin
10906             0,                                          // nFont
10907             0,                                          // nInputBufferSize
10908            {0, (short) fontSize},                       // dwFontSize
10909             0x36, 400, L"Lucida Console",               // uFontFamily, uFontWeight, FaceName. We're dancing for this!
10910             15,                                         // uCursorSize
10911             0,  1, 1, 0,                                // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition
10912             50, 4, 0,                                   // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup
10913 
10914            {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,  // Palette
10915             0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF}
10916             };
10917 
10918 $       _TX_CHECKED (dataList->AddDataBlock (&props));
10919 
10920 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file));
10921 $       if (!file) _TX_FAIL;
10922 
10923 $       wchar_t wName[MAX_PATH] = L"";
10924 $       MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName));
10925 
10926 $       _TX_CHECKED (file->Save (wName, true));
10927         }
10928 
10929 $   _TX_CATCH
10930 $   _TX_FINALLY
10931 
10932     if (file)         {$ file     ->Release(); }
10933     if (dataList)     {$ dataList ->Release(); }
10934     if (shellLink)    {$ shellLink->Release(); }
10935 
10936     if (init == S_OK) {$ Win32::CoUninitialize(); }
10937 
10938 $   return _TX_OK;
10939     _TX_ENDTRY
10940 
10941     #else
10942 
10943     (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex;
10944     (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg;
10945 
10946 $   return false;
10947 
10948     #endif
10949     }
10950 
10951 #endif // TX_COMPILED
10952 
10953 //}
10954 //-----------------------------------------------------------------------------------------------------------------
10955 
10957 //}
10958 //=================================================================================================================
10959 
10960 //=================================================================================================================
10961 //{          Memory DC functions                 (_txBuffer...)
10963 //=================================================================================================================
10965 
10966 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10967 
10968 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
10969     {
10970 $1  txAutoLock _lock;
10971 
10972 $   HDC wndDC = GetDC (wnd);
10973 $   if (!wndDC) return NULL;
10974 
10975 $   POINT sz = { 1, 1 };
10976 $   if (size) sz = *size;
10977 
10978 $   if (!size && wnd)
10979         {
10980 $       RECT r = {};
10981 $       GetClientRect (wnd, &r) asserted;
10982 
10983 $       sz.x = r.right  - r.left;
10984 $       sz.y = r.bottom - r.top;
10985         }
10986 
10987 $   if (bitmap)
10988         {
10989 $       BITMAP bmap = {};
10990 $       Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted;
10991 
10992 $       sz.x = bmap.bmWidth;
10993 $       sz.y = bmap.bmHeight;
10994         }
10995 
10996 $   RGBQUAD* buf = NULL;
10997 $   if (!pixels) pixels = &buf;
10998 
10999 $   HDC dc = Win32::CreateCompatibleDC (wndDC);
11000 $   if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed");
11001 
11002     #ifndef _TX_DIB_FIX
11003     #define _TX_DIB_FIX
11004     #endif
11005 
11006 $   BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }};
11007 
11008 $   HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0);
11009 $   if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed");
11010 
11011 $   Win32::SelectObject (dc, bmap) asserted;
11012 
11013 $   if (!bitmap)
11014         {
11015 $       if (*pixels)
11016             {
11017 $           RGBQUAD black = { 0, 0, 0, 255 };
11018 $           for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black;  //-V108
11019             }
11020         else
11021             {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; }
11022         }
11023 
11024 $   ReleaseDC (wnd, wndDC) asserted;
11025 
11026 $   return dc;
11027     }
11028 
11029 //-----------------------------------------------------------------------------------------------------------------
11030 
11031 bool _txBuffer_Delete (HDC* dc)
11032     {
11033 $1  if (_TX_ARGUMENT_FAILED (dc)) return false;
11034 $   if (                   !*dc)  return false;
11035 $   if (_TX_HDC_FAILED     (*dc)) return false;
11036 
11037 $   if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false;
11038 
11039 $   txAutoLock _lock;
11040 
11041 $   _txBuffer_Select (Win32::GetStockObject (NULL_PEN),    *dc) asserted;
11042 $   _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH),  *dc) asserted;
11043 $   _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted;
11044 $   _txBuffer_Select (_txStockBitmap,                      *dc);
11045 
11046 $   Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted;
11047 
11048 $   Win32::DeleteDC (*dc) asserted;
11049 
11050 $   *dc = NULL;
11051 
11052 $   return true;
11053     }
11054 
11055 //-----------------------------------------------------------------------------------------------------------------
11056 
11057 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/)
11058     {
11059 $1  if (!obj)                return false;
11060 $   if (_TX_HDC_FAILED (dc)) return false;
11061 
11062 $   if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type");
11063 
11064 $   txAutoLock _lock;
11065 
11066 $   obj = Win32::SelectObject (dc, obj);
11067 $   if (obj) Win32::DeleteObject (obj);
11068 
11069 $   return obj != NULL;
11070     }
11071 
11072 #endif // TX_COMPILED
11073 
11075 //}
11076 //=================================================================================================================
11077 
11078 //=================================================================================================================
11079 //{          Diagnostics
11081 //=================================================================================================================
11083 
11084 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11085 
11086 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/,
11087                       const char* msg  /*= NULL*/, ...)
11088     {                                                                        //---/\---/\-------Это ASCII KOT!--//
11089 $1  va_list arg; va_start (arg, msg);                                        //  {  '-'  }                      //
11090 $$  const char* what = _txProcessError (file, line, func, color, msg, arg);  //  {  0 0  }     Добавь его себе  //
11091     va_end (arg);                                                            //  --> V <--  в исходник, и тебе  //
11092                                                                              //   \ \|/ /      будет, наверно,  //
11093     if (!(msg && msg[0] == '\a')) return what;                               //    \___/  приятно отлаживаться  //
11094                                                                              //---------------долгими ночами:)--//
11095 //  vvvvvvvvvvvvvvvvvv
11096     DebugBreak();   // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться.
11097 //  ^^^^^^^^^^^^^^^^^^
11098 
11099     return what;    // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7).
11100     }
11101 
11102 #endif // TX_COMPILED
11103 
11104 //-----------------------------------------------------------------------------------------------------------------
11105 //{          General runtime check hooks
11106 //-----------------------------------------------------------------------------------------------------------------
11107 
11108 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11109 
11110 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/)
11111     {
11112 $1  if (!sig && !fpe)
11113         {
11114 $       signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11115 $       signal (SIGFPE,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11116 $       signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11117 $       signal (SIGILL,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11118 $       signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11119 $       return;
11120         }
11121 
11122     txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe);
11123 
11124     #define GET_DESCR_(str, code, descr)  case (code): {$ (str) = " " #code ": " descr; break; }
11125 
11126 $   const char* sSig = "Неизвестный тип сигнала";
11127 
11128 $   switch (sig)
11129         {
11130         GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!")
11131         GET_DESCR_ (sSig, SIGILL,  "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.")
11132         GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().")
11133         GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.")
11134         GET_DESCR_ (sSig, SIGFPE,  "Грубая ошибка в вычислениях.")
11135         default:   break;  //-V2522
11136         }
11137 
11138 $   const char* sFPE = "";
11139 
11140     #if defined (_MSC_VER)
11141 
11142     // MSVC provides the FPE code as a MS extension.
11143     // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx
11144 
11145 $   if (sig == SIGFPE) switch (fpe)
11146         {
11147         GET_DESCR_ (sFPE, _FPE_INVALID,        "Результат неверен.")
11148         GET_DESCR_ (sFPE, _FPE_DENORMAL,       "Денормализация.")
11149         GET_DESCR_ (sFPE, _FPE_ZERODIVIDE,     "Деление на ноль.")
11150         GET_DESCR_ (sFPE, _FPE_OVERFLOW,       "Результат слишком большой.")
11151         GET_DESCR_ (sFPE, _FPE_UNDERFLOW,      "Результат слишком маленький.")
11152         GET_DESCR_ (sFPE, _FPE_INEXACT,        "Результат неточен.")
11153         GET_DESCR_ (sFPE, _FPE_UNEMULATED,     "Операция не поддерживается.")
11154         GET_DESCR_ (sFPE, _FPE_SQRTNEG,        "Квадратный корень из отрицательного числа.")
11155         GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW,  "Переполнение стека сопроцессора.")
11156         GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.")
11157         GET_DESCR_ (sFPE, _FPE_EXPLICITGEN,    "Явный вызов исключения.")
11158         default:   break;  //-V2522
11159         }
11160 
11161     #else
11162 $   fpe = 0;
11163     #endif
11164 
11165     #undef GET_DESCR_
11166 
11167 $   signal (sig, (void(*)(int))(uintptr_t)_txOnSignal);
11168 
11169 $   Win32::_fpreset();
11170 
11171 $   _TX_UNEXPECTED ("\a\t"
11172                     "signal (%d, 0x%02X):%s%s "
11173                     "%s%s"
11174                     "С помощью функции signal() вы можете сами обработать эту ошибку.",
11175                     sig, (unsigned) fpe, sSig, sFPE,
11176                     ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1);
11177     }
11178 
11179 //-----------------------------------------------------------------------------------------------------------------
11180 
11181 void _txOnTerminate()
11182     {
11183     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11184 
11185     // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc
11186 
11187 $1  static int terminating = 0;
11188     if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; }
11189 
11190 $   if (!*_txDumpSE)
11191         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11192 
11193 $   _TX_UNEXPECTED ("\t\a"
11194                     "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, "
11195                     "или другая фатальная ошибка C++. "
11196                     "%s"
11197                     "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, "
11198                     "разбирайтесь, в чем дело.\n\n"
11199                     "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE,
11200                     _txDumpSE + 1);
11201     }
11202 
11203 //-----------------------------------------------------------------------------------------------------------------
11204 
11205 void _txOnUnexpected()
11206     {
11207     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11208 
11209 $1  if (!*_txDumpSE)
11210         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11211 
11212 $   _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n"
11213                     "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете "
11214                     "спецификацию исключений для функций, проверьте, не нарушена ли она."
11215                     "%s"
11216                     "С помощью catch (...) в main() вы можете сами обработать эту ошибку.",
11217                     _txDumpSE + 1);
11218     }
11219 
11220 //-----------------------------------------------------------------------------------------------------------------
11221 
11222 int _txOnMatherr (_exception* exc)
11223     {
11224     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc);
11225 
11226 $1  assert (exc);
11227 
11228     const char* sType = "Неизвестный тип исключения";
11229 
11230     #if !defined (__CYGWIN__)
11231 
11232     #define GET_DESCR_(code, descr)  case (code): {$ sType = "(" #code "): " descr; break; }
11233 
11234 $   switch (exc->type)
11235         {
11236         GET_DESCR_ (_DOMAIN,    "Нарушение области определения");
11237         GET_DESCR_ (_SING,      "Сингулярность аргумента");
11238         GET_DESCR_ (_PLOSS,     "Частичная потеря значимости");
11239         GET_DESCR_ (_TLOSS,     "Полная потеря значимости");
11240         GET_DESCR_ (_OVERFLOW,  "Результат слишком большой");
11241         GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький");
11242         default:   break;  //-V2522
11243         }
11244 
11245     #undef GET_DESCR_
11246 
11247 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n"
11248                     "С помощью __setusermatherr() вы можете сами обработать эту ошибку.",
11249                     exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval);
11250     #else
11251 
11252 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType);
11253 
11254     #endif
11255 
11256     return 0;
11257     }
11258 
11259 //-----------------------------------------------------------------------------------------------------------------
11260 
11261 tx_noreturn void _txOnNewHandlerAnsi()
11262     {
11263     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11264 $1
11265 $   _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n"
11266                     "С помощью std::set_new_handler() вы можете сами обработать эту ошибку "
11267                     "и где-нибудь найти недостающую память.");
11268 
11269 $   throw std::bad_alloc();
11270     }
11271 
11272 //-----------------------------------------------------------------------------------------------------------------
11273 
11274 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code)
11275     {
11276     txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code);
11277 
11278 $1  if (code)
11279         {$ errno = code; }
11280 
11281 $   _TX_UNEXPECTED ("\a"
11282                     "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n"
11283                     "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку "
11284                     "и постараться не выходить за границы массивов.",
11285                     code, msg, (char*) ptr, ptr);
11286     }
11287 
11288 //-----------------------------------------------------------------------------------------------------------------
11289 
11290 int tx_glGetError (int setError /*= INT_MIN*/)
11291     {
11292 $1  _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError;
11293 $   return _txOGLError;
11294     }
11295 
11296 #endif // TX_COMPILED
11297 
11298 //}
11299 //-----------------------------------------------------------------------------------------------------------------
11300 
11301 //-----------------------------------------------------------------------------------------------------------------
11302 //{          MSC Runtime check hooks
11303 //-----------------------------------------------------------------------------------------------------------------
11304 
11305 #if defined (_MSC_VER)
11306 
11307 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11308 
11309 //-----------------------------------------------------------------------------------------------------------------
11310 
11311 int _txOnNewHandler (size_t size)
11312     {
11313     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size);
11314 $5
11315 $   _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n"
11316                     "С помощью _set_new_handler() вы можете сами обработать эту ошибку "
11317                     "и где-нибудь найти недостающую память.", (unsigned long long) size);
11318 
11319 $   throw std::bad_alloc();
11320     }
11321 
11322 //-----------------------------------------------------------------------------------------------------------------
11323 
11324 void _txOnSecurityError (int code, void* addr)
11325     {
11326     txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr);
11327 $5
11328 $   _TX_UNEXPECTED ("\a"
11329                     "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n"
11330                     "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку "
11331                     "и более торжественно завершить программу. Ставьте же ассерты.", code);
11332     }
11333 
11334 //-----------------------------------------------------------------------------------------------------------------
11335 
11336 void _txOnPureCall()
11337     {
11338     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11339 $5
11340 $   _TX_UNEXPECTED ("\a"
11341                     "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах "
11342                     "или деструкторах базовых классов - не вызывайте там таких функций.\n\n"
11343                     "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку "
11344                     "и проверить свое знание С++ :)");
11345     }
11346 
11347 //-----------------------------------------------------------------------------------------------------------------
11348 
11349 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr)
11350     {
11351     txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr);
11352 
11353 $5  assert (wExpr);
11354     assert (wFunc);
11355     assert (wFile);
11356 
11357     char expr [_TX_BUFSIZE/2] = "[Unknowm expr]",
11358          func [_TX_BUFSIZE/2] = "[Unknowm func]",
11359          file [MAX_PATH]      = "[Unknowm file]";
11360 
11361 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL);
11362 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL);
11363 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL);
11364 
11365 $$  _txError (file, (int) line, func, 0, "\a"
11366               "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n"
11367               "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr);
11368     }
11369 
11370 //-----------------------------------------------------------------------------------------------------------------
11371 
11372 #if defined (_CLANG_VER) && !defined (_MSC_VER)
11373 
11374 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info)
11375     {
11376 $5  assert (&info);
11377 
11378 $$  _txError (info.__file_, info.__line_, NULL, 0, "\a"
11379               "Оказалось неверно, что %s (%s). Не надо так.\n\n"
11380               "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_);
11381     }
11382 
11383 #endif
11384 
11385 //-----------------------------------------------------------------------------------------------------------------
11386 
11387 #pragma runtime_checks ("", off)
11388 
11389 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...)
11390     {
11391     txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format);
11392 
11393 $5  static long running = 0;
11394 $   while (InterlockedExchange (&running, 1)) Sleep (0);
11395 
11396 $   assert (format);
11397 
11398     // Disable all RTC failures
11399 
11400 $   int nErrors = _RTC_NumErrors();
11401 $   int* errors = NULL;
11402 $   try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;}  //-V104
11403 
11404 $   int err = 0;
11405 $   for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE);  //-V108
11406 
11407 $   char text [_TX_BUFSIZE] = "";
11408 
11409 $   va_list arg; va_start (arg, format);
11410 $   _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg);                  // Get message from the vararg list
11411 $   auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/);  // Get the RTC error number
11412 $   va_end (arg);
11413 
11414 $   const char* sType = "type";
11415 
11416 $   switch (type)
11417        {
11418        case _CRT_ERROR:  $ sType = "ошибка";            break;
11419        case _CRT_ASSERT: $ sType = "логическая ошибка"; break;
11420        case _CRT_WARN:   $ sType = "возможная ошибка";  break;
11421        default:          $                              break;
11422        }
11423 
11424 $   const char* sError = _RTC_GetErrDesc (error);
11425 
11426 $$  _txError (file, line, NULL, 0, "\a"
11427               "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module);
11428 
11429     // The code below will be never executed until the error above will stay fatal:
11430 
11431     // Restore the RTC error types
11432 
11433     #if defined (_MSC_VER)
11434     #pragma warning (push)
11435     #pragma warning (disable: 6385)  // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11436     #endif
11437 
11438 $   for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR));  //-V108
11439 
11440     #if defined (_MSC_VER)
11441     #pragma warning (pop)            // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11442     #endif
11443 
11444 $   InterlockedExchange (&running, 0);
11445 $   return 1;
11446     }
11447 
11448 #pragma runtime_checks ("", restore)
11449 
11450 //-----------------------------------------------------------------------------------------------------------------
11451 
11452 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line)
11453     {
11454     #if (_TX_ALLOW_TRACE +0 >= 4)
11455 
11456     static _tx_thread int recursive = 0;
11457     if (recursive) return true;
11458     recursive++;
11459 
11460     #if (_TX_ALLOW_TRACE +0 <= 10)
11461     if (!size) return true;
11462     #endif
11463 
11464     #define GET_DESCR_(str, type)  case (type): { str = #type; break; }
11465 
11466     const char* sType = "Unknown type";
11467     const char* sUse  = "Unknown use";
11468 
11469     switch (_BLOCK_TYPE (type))
11470         {
11471         GET_DESCR_ (sType, _HOOK_ALLOC);
11472         GET_DESCR_ (sType, _HOOK_REALLOC);
11473         GET_DESCR_ (sType, _HOOK_FREE);
11474         default:   break;
11475         }
11476 
11477     switch (use)
11478         {
11479         GET_DESCR_ (sUse,  _NORMAL_BLOCK);
11480         GET_DESCR_ (sUse,  _CRT_BLOCK);
11481         GET_DESCR_ (sUse,  _CLIENT_BLOCK);
11482         GET_DESCR_ (sUse,  _FREE_BLOCK);
11483         GET_DESCR_ (sUse,  _IGNORE_BLOCK);
11484         default:   break;
11485         }
11486 
11487     #undef  GET_DESCR_
11488 
11489     _txTrace ((const char*) file, line, NULL, "%*s"
11490               "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)",
11491               2 * _txLoc::Cur.inTX, "",
11492               type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request);
11493 
11494     recursive--;
11495 
11496     #else
11497 
11498     UNREFERENCED_PARAMETER (type);
11499     UNREFERENCED_PARAMETER (data);
11500     UNREFERENCED_PARAMETER (size);
11501     UNREFERENCED_PARAMETER (use);
11502     UNREFERENCED_PARAMETER (request);
11503     UNREFERENCED_PARAMETER (file);
11504     UNREFERENCED_PARAMETER (line);
11505 
11506     #endif
11507 
11508     return true;  //-V601
11509     }
11510 
11511 //-----------------------------------------------------------------------------------------------------------------
11512 
11513 #endif // TX_COMPILED
11514 
11515 #endif
11516 
11517 //}
11518 //-----------------------------------------------------------------------------------------------------------------
11519 
11520 //-----------------------------------------------------------------------------------------------------------------
11521 //{          SEH staff
11522 //-----------------------------------------------------------------------------------------------------------------
11523 
11524 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11525 
11526 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc)
11527     {
11528     if (!_txProcessSystemWarnings)
11529         {
11530         DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11531         void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11532 
11533         if (code != DBG_PRINTEXCEPTION_C &&
11534             code != DBG_PRINTEXCEPTION_WIDE_C)
11535             {
11536             txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n",
11537                                  _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings);
11538             }
11539 
11540         return EXCEPTION_CONTINUE_SEARCH;
11541         }
11542     else
11543         {
11544         int inTX = _txLoc::Cur.inTX++;
11545 
11546         long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler");
11547 
11548         _txLoc::Cur.inTX = inTX;
11549         return ret;
11550         }
11551     }
11552 
11553 //-----------------------------------------------------------------------------------------------------------------
11554 
11555 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc)
11556     {
11557     int inTX = _txLoc::Cur.inTX++;
11558 
11559     long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter");
11560 
11561     if (_txPrevUEFilter)
11562         {
11563         if (_txSetJmp())
11564             {
11565             int inTX2 = _txLoc::Cur.inTX++;
11566 
11567             ret = _txPrevUEFilter (exc);
11568 
11569             _txLoc::Cur.inTX = inTX2;
11570             }
11571         else
11572             {
11573 $6          _txClearJmp();
11574 
11575             _TX_UNEXPECTED ("\t\a" "%s"
11576                             "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n"
11577                             "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE,
11578                             _txDumpSE + 1);
11579             }
11580         }
11581 
11582     _txLoc::Cur.inTX = inTX;
11583     return ret;
11584     }
11585 
11586 //-----------------------------------------------------------------------------------------------------------------
11587 
11588 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter)
11589     {
11590 $6  _txPrevUEFilter = filter;
11591 
11592     return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter;
11593     }
11594 
11595 //-----------------------------------------------------------------------------------------------------------------
11596 
11597 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[])
11598     {
11599     assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; }  //-V547
11600 
11601     assert (exc->ExceptionRecord);
11602 
11603     assert (func);
11604     assert (func[3] == 'V' || func[3] == 'U');
11605 
11606     bool  unhExc = (func[3] == 'U');
11607     DWORD code   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11608     void* addr   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11609 
11610     if (code == DBG_PRINTEXCEPTION_C                  ||
11611         code == DBG_PRINTEXCEPTION_WIDE_C             ||
11612         code == DBG_THREAD_NAME                       ||
11613        (code == RPC_S_SERVER_UNAVAILABLE  && !unhExc) ||
11614        (code == RPC_S_CALL_CANCELLED      && !unhExc) ||
11615        (code == EXCEPTION_BREAKPOINT && IsDebuggerPresent()))
11616         return EXCEPTION_CONTINUE_SEARCH;
11617 
11618     ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr;
11619     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11620 
11621               dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr;
11622     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11623 
11624     _txSENumber = _txSENumber + 1;
11625     if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1;
11626 
11627     OutputDebugString ("\n");
11628     txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n",
11629                          _TX_VERSION, _txSENumber, func, (unsigned long) code, addr);
11630 
11631 $6  if (*(unsigned long long*) _txDumpExceptionObjJmp)
11632         {
11633 $       longjmp (_txDumpExceptionObjJmp, 1);  //-V2512
11634         }
11635 
11636     tx_fpreset();
11637 
11638     #if defined (_MSC_VER)
11639     if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); }
11640     #endif
11641 
11642 $   bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord));  //-V560
11643 
11644 $   if (primaryException && exc)  //-V560
11645         {
11646 $       unsigned err = GetLastError();
11647 
11648 $       const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc);
11649 
11650 $       _txDumpExceptionSEH (_txDumpSE,  (intptr_t) sizeof (_txDumpSE)  - 1, exc->ExceptionRecord, func);
11651 $       _tx_snprintf_s      (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace);
11652 
11653 $       static _tx_thread DWORD prevCode = 0;
11654 $       static _tx_thread void* prevAddr = NULL;
11655 
11656 $       if (code != prevCode && addr != prevAddr &&
11657             !strstr (_txDumpSE, "Объект исключения C++:"))
11658             {
11659 $           SetLastError (err);
11660 $           _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1);
11661 
11662 $           prevCode = code;
11663 $           prevAddr = addr;
11664             }
11665 
11666 $       SetLastError (err);
11667         }
11668 
11669 $   if (_txDumpSE[0]     == '\a'                   ||
11670         _txSENumber      >= _TX_EXCEPTIONS_LIMIT+0 ||
11671         _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
11672         {
11673 $       _TX_UNEXPECTED ("\a\t" "%s"
11674                         "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.",
11675                         _txDumpSE + 1);
11676         }
11677 
11678 $   return EXCEPTION_CONTINUE_SEARCH;
11679     }
11680 
11681 //-----------------------------------------------------------------------------------------------------------------
11682 
11683 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[])  //-V2008
11684     {
11685 $6  assert (what);
11686 $   assert (size >= 0);                     //-V547
11687     assert (exc); if (!exc) {$ return 0; }  //-V547
11688 $   assert (func);
11689 
11690 $   unsigned         code   = exc->ExceptionCode;
11691 $   void*            addr   = exc->ExceptionAddress;
11692 $   unsigned         params = exc->NumberParameters;
11693 $   const ULONG_PTR* info   = exc->ExceptionInformation;
11694 $   void*            object = (params >= 2)? (void*) info[1] : NULL;
11695 
11696 $   char* s = what;
11697 
11698     #define PRINT_(...)  s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__)
11699 
11700 $   const char* sCode  = NULL;
11701 $   const char* sDescr = NULL;
11702 
11703     #define GET_DESCR_(code, descr)  case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; }
11704 
11705 $   switch (code)
11706         {
11707         GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION,         " "  "Нарушение доступа к памяти.")
11708         GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION,      " "  "Недопустимая операция.")
11709         GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION,         " "  "Привилегированная операция.")
11710         GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED,    "\a" "Выход за границы массива. Ставьте ассерты!")
11711         GET_DESCR_ (EXCEPTION_BREAKPOINT,               "\a" "Достигнута точка останова. Удачи в отладке!")
11712         GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT,    "\a" "Нарушение выравнивания данных.")
11713         GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION,      "\a" "Обработчик исключения возвратил неверное значение.")
11714         GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR,            "\a" "Невозможно загрузить нужную страницу памяти.")
11715         GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.")
11716         GET_DESCR_ (EXCEPTION_SINGLE_STEP,              "\a" "Выполнена инструкция машинного кода. Одна штука.")
11717         GET_DESCR_ (EXCEPTION_STACK_OVERFLOW,           "\a" "Ю-ху! Переполнение стека!")
11718         GET_DESCR_ (EXCEPTION_GUARD_PAGE,               "\a" "Попытка доступа к защищенной странице памяти.")
11719         GET_DESCR_ (EXCEPTION_INVALID_HANDLE,           "\a" "Неверный или уже закрытый дескриптор.")
11720         GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK,           "\a" "Возможно, взаимная блокировка ресурсов.")
11721 
11722         GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK,          "\a" "Ошибка стека при операции с плавающей точкой.")
11723         GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND,     " "  "Денормализация числа с плавающей точкой.")
11724         GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO,       " "  "Деление на ноль при операции с плавающей точкой.")
11725         GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT,       " "  "Неточный результат при операции с плавающей точкой.")
11726         GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION,    " "  "Недопустимая операция с плавающей точкой.")
11727         GET_DESCR_ (EXCEPTION_FLT_OVERFLOW,             " "  "Переполнение при операции с плавающей точкой.")
11728         GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW,            " "  "Потеря значимости при операции с плавающей точкой.")
11729         GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS,       " "  "Множественные ошибки с плавающей точкой.")
11730 
11731         GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO,       "\a" "Целочисленное деление на ноль.")
11732         GET_DESCR_ (EXCEPTION_INT_OVERFLOW,             "\a" "Переполнение при целочисленной операции.")
11733 
11734         GET_DESCR_ (EXCEPTION_CLR_FAILURE,              "\a" "Сбой среды исполнения (CLR).")
11735         GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN,        "\a" "Переполнение стекового буфера!")
11736         GET_DESCR_ (STATUS_ASSERTION_FAILURE,           "\a" "Сработал assert. На этот раз из ядра.")
11737         GET_DESCR_ (STATUS_WX86_BREAKPOINT,             "\a" "Точка останова подсистемы эмуляции x86.")
11738         GET_DESCR_ (RPC_S_UNKNOWN_IF,                   "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).")
11739         GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE,           "\a" "Сервер удаленного вызова процедур (RPC) недоступен.")
11740         GET_DESCR_ (DBG_TERMINATE_THREAD,               "\a" "Отладчик завершил поток сознания.")
11741         GET_DESCR_ (DBG_TERMINATE_PROCESS,              "\a" "Отладчик завершил процесс.")
11742         GET_DESCR_ (DBG_CONTROL_C,                      "\a" "Отладчик получил сигнал прерывания Control+C.")
11743         GET_DESCR_ (DBG_CONTROL_BREAK,                  "\a" "Отладчик получил сигнал прерывания Control+Break.")
11744         GET_DESCR_ (DBG_THREAD_NAME,                    " "  "Отладчик получил указание дать потоку имя.")
11745         GET_DESCR_ (DBG_PRINTEXCEPTION_C,               " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).")
11746         GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C,          " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).")
11747 
11748         GET_DESCR_ (EXCEPTION_CPP_MSC,                  " "  "Исключение С++, вызванное оператором throw.")
11749         GET_DESCR_ (EXCEPTION_CPP_GCC,                  " "  "Исключение С++, вызванное оператором throw.")
11750         GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND,           " "  "Исключение С++, вызванное во время раскрутки стека (rethrow?).")
11751         GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED,           " "  "Исключение С++, вызванное нарушением магии.")
11752         GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER,      "\a" "Это скомпилилось под Билдер? O_O")
11753         GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI,       "\a" "Это же С++. Как это вышло?")
11754 
11755         default: $ break;
11756         }
11757 
11758     #undef GET_DESCR_
11759 
11760 $   if (sDescr)
11761         {
11762 $       PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode);
11763         }
11764     else
11765         {
11766 $       PRINT_ ("\a#%ld: ", _txSENumber);
11767 $       s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11768                             GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11769                             s, (DWORD) (size - (s-what)), NULL) - 2;  //-V202
11770 $       PRINT_ ("\r\r");
11771         }
11772 
11773 $   PRINT_ (" (0x%X) при выполнении кода по адресу", code);
11774 $   PRINT_ ((addr? " 0x%p" : " NULL"), addr);
11775 
11776 $   Win32::SYMBOL_INFO*     sym  = NULL;
11777 $   Win32::IMAGEHLP_LINE64* line = NULL;
11778 
11779     if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); }
11780 
11781 $   if (sym  &&                   *sym->Name)      PRINT_ (" в функции %s()", sym->Name);
11782 $   if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber);
11783 
11784 $   if (code == EXCEPTION_ACCESS_VIOLATION ||
11785         code == EXCEPTION_IN_PAGE_ERROR)
11786         {
11787 $       PRINT_ (". Попытка ");
11788 
11789 $       unsigned long op = 0xBADC0DE;
11790 $       const char*  sOp = "(действие не указано)";
11791 
11792 $       if (params >= 1)
11793             {
11794 $           switch (op = (unsigned long) info[0])  //-V202
11795                 {
11796                 case 0:  $ sOp = "прочесть данные";          break;
11797                 case 1:  $ sOp = "записать данные";          break;
11798                 case 8:  $ sOp = "исполнить код";            break;
11799                 default: $ sOp = "совершить операцию 0x%lX"; break;
11800                 }
11801             }
11802 
11803 $       PRINT_ (sOp, op);
11804 
11805 $       if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); }   //-V1048
11806         else             {$ PRINT_ (" (адрес не указан)"); }
11807 
11808 $       if (code == EXCEPTION_IN_PAGE_ERROR)
11809             {
11810 $           PRINT_ (", ошибка ввода-вывода:");
11811 
11812 $           if (params >= 3)
11813                 {
11814 $               unsigned long ntstatus = (unsigned long) info[2];                                 //-V202
11815 
11816 $               PRINT_ (" 0x%lX (", ntstatus);
11817 
11818 $               s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11819                                     GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11820                                     s, (DWORD) (size - (s-what)), NULL) - 2;                      //-V202
11821 $               PRINT_ (")");
11822                 }
11823             else
11824                 {$ PRINT_ (" (не указана)"); }
11825             }
11826         }
11827 
11828 $   HMODULE module = NULL;
11829 $   _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module));
11830 
11831 $   if (module)
11832         {
11833 $       static char sModule [MAX_PATH] = "";
11834 $       int ok = GetModuleFileName (module, sModule, sizeof (sModule));
11835 
11836 $       char* ext = (ok? strrchr (sModule, '.') : NULL);
11837 $       if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule));
11838 
11839         if (ok) {$ PRINT_ (" в модуле %s",  sModule); }
11840         else    {$ PRINT_ (" в модуле 0x%p", (void*) module); }
11841         }
11842 
11843 $   PRINT_ (".");
11844 
11845 $   if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0)
11846         {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).",        _TX_EXCEPTIONS_LIMIT+0); }
11847 
11848 $   if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
11849         {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); }
11850 
11851 $   PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func);
11852 
11853 $   if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
11854         {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); }
11855 
11856 $   if (exc->ExceptionRecord)
11857         {
11858 $       PRINT_ ("\n\n" "Причина:" "\n\n");
11859 $       s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func);
11860         }
11861 
11862 $   if (code == EXCEPTION_CPP_GCC        ||
11863         code == EXCEPTION_CPP_GCC_UNWIND ||
11864         code == EXCEPTION_CPP_GCC_FORCED ||
11865         code == EXCEPTION_CPP_MSC)
11866         {
11867 $       s += _txDumpExceptionCPP (s,    size - (s-what), code, params, info);
11868         }
11869 
11870     #undef PRINT_
11871 
11872 $   while (s > what && s[-1] == '\n') s--;
11873 $   if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n");
11874 
11875 $   return s - what;
11876     }
11877 
11878 //-----------------------------------------------------------------------------------------------------------------
11879 
11880 intptr_t _txDumpExceptionCPP (char what[], intptr_t size,
11881                               unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/)
11882     {
11883 $6  assert (what);
11884 $   assert (size >= 0);  //-V547
11885 
11886 $   char* s = what;
11887 
11888 $   switch (code)
11889         {
11890         #if defined (_GCC_VER)
11891 
11892         case EXCEPTION_CPP_GCC:
11893         case EXCEPTION_CPP_GCC_UNWIND:
11894         case EXCEPTION_CPP_GCC_FORCED:
11895             {
11896             // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp
11897             //      [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below
11898             //      [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below
11899             //      [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below
11900             //      and figure above near ABI::__cxa_exception definition in this file
11901 
11902 $           const std::type_info* type   = NULL;
11903 $           void*                 object = NULL;
11904 
11905 $           if (params >= 1)
11906                 {
11907 $               _Unwind_Exception*    unwind_exception = (_Unwind_Exception*) info[0];
11908 $               ABI::__cxa_exception* cxa_exception    = (ABI::__cxa_exception*) (unwind_exception + 1) - 1;
11909 
11910 $               type   = cxa_exception->exceptionType;
11911 $               object = cxa_exception + 1;
11912                 }
11913 
11914 $           s += _txDumpExceptionObj (s, size - (s-what), object, 0, type);
11915             }
11916 $           break;
11917 
11918         case 0:  // Not called within SEH chain
11919             {
11920             // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc
11921             //       [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc
11922 
11923             using namespace abi;
11924             using namespace ABI;
11925 
11926 $           ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions;
11927 
11928 $           if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1))  // Dependent exception, case B, see pic above
11929                 {
11930 $               cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1;
11931                 }
11932 
11933 $           if (cxa_exception)
11934                 {
11935 $               verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type());
11936 
11937 $               s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType);
11938                 }
11939             }
11940 $           break;
11941 
11942         #elif defined (_MSC_VER)
11943 
11944         case EXCEPTION_CPP_MSC:
11945             {
11946             // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
11947             //     [2] http://www.openrce.org/articles/full_view/21
11948             //     [3] http://www.openrce.org/articles/full_view/23
11949             //     [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf
11950 
11951 $           const std::type_info* type   = NULL;
11952 $           void*                 object = (params >= 2)? (void*) info[1] : NULL;
11953 $           size_t                szObj  = 0;
11954 
11955 $           if (params >= 3 &&
11956                (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||
11957                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||
11958                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 ||
11959                 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1))
11960                 {
11961 $               auto throwInfo = (const Win32::ThrowInfo*) info[2];
11962 
11963 $               if (throwInfo && throwInfo->pCatchableTypeArray)
11964                     {
11965 $                   HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL;  //-V112
11966 
11967                     #define RVA_(type, addr)  ( (type) ((uintptr_t) module + (uintptr_t) (addr)) )
11968 
11969 $                   const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray);
11970 $                   const Win32::CatchableType*      cType  = RVA_(const Win32::CatchableType*,      cArray->arrayOfCatchableTypes[0]);
11971 
11972 $                   type  = RVA_(const std::type_info*, cType->pType);
11973 $                   szObj = cType->sizeOrOffset;  //-V101
11974 
11975                     #undef  RVA_
11976                     }
11977                 }
11978 
11979 $           s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type);
11980             }
11981             break;
11982 
11983         case 0:  // Not called within SEH chain
11984 
11985             // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC:
11986             //
11987             // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception.
11988             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp
11989             //
11990             // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception.
11991             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp
11992             // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp
11993             // and http://msdn.microsoft.com/en-us/library/ff730818.aspx.
11994             //
11995             // So _txDumpSE information should have been recorded during previous call. Now do nothing.
11996 
11997 $           break;
11998 
11999         #endif
12000 
12001         default:
12002 $           txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code);
12003 $           break;
12004         }
12005 
12006 $   while (s > what && s[-1] == '\n') s--;
12007 $   if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n");
12008 
12009 $   return (s - what);
12010     }
12011 
12012 //-----------------------------------------------------------------------------------------------------------------
12013 
12014 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type)  //-V2008
12015     {
12016 $6  assert (what);
12017 $   assert (size > 0);  //-V547
12018 
12019 $   static char*  s     = NULL; s     = what;
12020 $   static size_t szObj = 0;    szObj = sizeObj;
12021 
12022     #define PRINT_(...)  s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__)
12023 
12024 $   PRINT_ ("\n\n" "Объект исключения C++:");
12025 
12026 $   const char* mangledName = (type)? type->name() : NULL;
12027 
12028 $   char* typeName = NULL;
12029 $   int err = 1;
12030 
12031     #if defined (_GCC_VER)
12032 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err);
12033     #endif
12034 
12035 $   const char* name = (!err && typeName)? typeName : mangledName;  //-V560
12036 
12037 $   if (name &&
12038        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >")           == 0 ||
12039         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >")                   == 0))
12040         {$ name = "std::string"; }
12041 
12042 $   if (name &&
12043        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *")         == 0 ||
12044         strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 ||
12045         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*")                  == 0))
12046         {$ name = "std::string*"; }
12047 
12048     if (name) {$ PRINT_ (" %s", name); }
12049 
12050     #if defined (_GCC_VER)
12051 $   free (typeName);
12052     #endif
12053 
12054 $   err = 0;
12055 $   if (mangledName)
12056         {
12057         if (_txSetJmp())
12058             {
12059             #define PRINT_VAL_(fmt, typ, ...)                                                                          \
12060                 else if (*type == typeid (      typ       )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \
12061                 else if (*type == typeid (const typ       )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \
12062                 else if (*type == typeid (      typ*      )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
12063                 else if (*type == typeid (const typ*      )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
12064                 else if (*type == typeid (      typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \
12065                 else if (*type == typeid (const typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); }
12066             #define NO_
12067 
12068             if (false) ;
12069             PRINT_VAL_ ("%s", char*, NO_)   PRINT_VAL_ ('%c', unsigned char,  NO_)   PRINT_VAL_ (%s,   bool, ? "true" : "false")  //-V206 //-V517
12070             PRINT_VAL_ ( %d,  int,   NO_)   PRINT_VAL_ ( %u,  unsigned int,   NO_)   PRINT_VAL_ (%g,   float,  NO_)               //-V206
12071             PRINT_VAL_ ( %hd, short, NO_)   PRINT_VAL_ ( %hu, unsigned short, NO_)   PRINT_VAL_ (%g,   double, NO_)               //-V206
12072             PRINT_VAL_ ( %ld, long,  NO_)   PRINT_VAL_ ( %lu, unsigned long,  NO_)   PRINT_VAL_ ('%c', char,   NO_)               //-V206
12073             PRINT_VAL_ ("%s", std::string, .c_str())                                                                              //-V206
12074 
12075             else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object))
12076                 {
12077 $               PRINT_ (", what(): \"%s\"", e->what());
12078                 }
12079             else
12080                 {$ err = 1; }
12081             }
12082         else
12083             {$ err = 2; }
12084         }
12085 
12086 $   _txClearJmp();
12087 
12088 $   if (err && object && szObj)
12089         {
12090 $       const unsigned char* buf = (const unsigned char*) object;
12091 
12092 $       if (szObj >= 64) szObj = 64;
12093 
12094 $       PRINT_ (", дамп: [");
12095 $       for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' );
12096 
12097 $       PRINT_ ("]");
12098 $       for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]);
12099 
12100 $       err = 0;
12101         }
12102 
12103 $   if (err)
12104         {$ PRINT_ (" = ??"); }
12105 
12106 $   PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object);  //-V560
12107 
12108     #undef PRINT_VAL_
12109     #undef PRINT_
12110     #undef NO_
12111 
12112 $   return s - what;
12113     }
12114 
12115 #endif // TX_COMPILED
12116 
12117 //}
12118 //-----------------------------------------------------------------------------------------------------------------
12119 
12120 //-----------------------------------------------------------------------------------------------------------------
12121 //{          Stack trace and debug info access
12122 //-----------------------------------------------------------------------------------------------------------------
12123 
12124 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12125 
12126 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/,
12127                                       CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/,
12128                                       HANDLE thread /*= GetCurrentThread()*/)
12129     {
12130 $6  const int maxFrames = 62;  // MS says: < 63
12131 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12132 
12133     if (framesToSkip == -1) {$ return trace; }
12134 
12135 $   static void* capture [maxFrames] = {};
12136 $   int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread);
12137 
12138 $   memset (trace, 0, sizeof (trace));
12139 $   char* s = trace;
12140 
12141 $   bool haveSrcInfo = false;
12142 
12143     #define PRINT_(...)  s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__)
12144 
12145 $   for (int i = 0, n = 0; i < frames; i++)  //-V2530
12146         {
12147 $       void* addr = capture[i];
12148 
12149 $       Win32::SYMBOL_INFO*     sym    = NULL;
12150 $       Win32::IMAGEHLP_LINE64* line   = NULL;
12151 $       const char*             module = NULL;
12152 $       const char*             source = NULL;
12153 $       bool                    inTX   = false;
12154 
12155         if (addr)                {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module);          }
12156         if (readSource && !inTX) {$        _txSymGetFromAddr ((void*) 1,        NULL, NULL,  NULL, &source, 2); }  //-V566
12157 
12158 $       int nl = 0;
12159 $       while (s > trace && s[-1] == '\n') { s--; nl++; }
12160 
12161         #if !defined (_TX_FULL_STACKTRACE)
12162 
12163 $       if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber))))
12164             {$ continue; }
12165 
12166         #endif
12167 
12168 $       PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr);
12169 $       n++;
12170 
12171         if (addr ==                    0)          {$ PRINT_ (" [Неверный фрейм]");        break; }
12172         if (addr == (void*)           -1)          {$ PRINT_ (" [Странный фрейм]");        break; }
12173         if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; }  //-V566
12174 
12175         if (module)                                {$ PRINT_ (" in %s%s",     module, ((sym && *sym->Name)? ": " : "")); }
12176         if (sym  && *sym->Name)                    {$ PRINT_ ("%s()",         sym->Name);                                }
12177         if (line && line->FileName)                {$ PRINT_ (" at %s",       line->FileName);   haveSrcInfo = true;     }
12178         if (line && line->LineNumber)              {$ PRINT_ (":%d",    (int) line->LineNumber); haveSrcInfo = true;     }
12179         if (source)                                {$ PRINT_ (":\n\n" "%s\n", source);                                   }
12180 
12181         if (sym && strcmp (sym->Name , "main") == 0) {$ break; }
12182         }
12183 
12184 $   while (s > trace && s[-1] == '\n') s--;
12185 $   *s = 0;
12186 
12187 $   int bits = sizeof (void*) * CHAR_BIT;
12188     if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ ("TXLib бедствует: Не загрузилась библиотека"); }
12189     if (!Win32::SymSetOptions)                                 {$ PRINT_ (" DbgHelp%d.dll или DbgHelp.dll,", bits); }
12190     if (                         !Win32::MinGW::SymSetOptions) {$ PRINT_ (" MgwHelp%d.dll или MgwHelp.dll,", bits); }
12191     if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ (" отладочная информация недоступна :(\n"); }
12192 
12193 $   while (s > trace && s[-1] == '\n') s--;
12194 $   *s = 0;
12195 
12196 $   if (!haveSrcInfo)
12197         {$ PRINT_ ("\n\n" "TXLib печалится: Нет информации об исходных файлах. Вы не забыли опцию -g при компиляции?"); }
12198 
12199     #if defined (_MSC_VER)
12200     #pragma warning (push)
12201     #pragma warning (disable: 28199)  // Using possibly uninitialized memory '*s'
12202     #endif
12203 
12204 $   while (s > trace && s[-1] == '\n') s--;
12205 $   *s = 0;
12206 
12207     #if defined (_MSC_VER)
12208     #pragma warning (pop)             // Using possibly uninitialized memory '*s'
12209     #endif
12210 
12211     #undef PRINT_
12212 
12213 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12214 
12215     #if !defined (_TX_NO_MINIDUMP)
12216 $   _txCreateMiniDump (exc);
12217     #endif
12218 
12219 $   return trace;
12220     }
12221 
12222 //-----------------------------------------------------------------------------------------------------------------
12223 
12224 // Stack WALKING if the program is DEAD. Dead, Carl!
12225 
12226 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/,
12227                   HANDLE thread /* = GetCurrentThread()*/)
12228     {
12229 $6  namespace MinGW = Win32::MinGW;
12230 
12231 $   assert (capture);
12232 
12233 $   HANDLE process  = GetCurrentProcess();
12234 $   bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId());
12235 
12236 $   CONTEXT ctx = {};
12237 $   ctx.ContextFlags |= CONTEXT_FULL;
12238 
12239 $   int isWow64 = 0;
12240 $   if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64);
12241     else {$ return -1; }
12242 
12243 $   if (context)
12244         {
12245 $       ctx = *context;
12246         }
12247     else
12248         {
12249 $       if (thisThread)
12250             {
12251 $           _TX_CALLv (Win32::RtlCaptureContext, (&ctx));
12252             }
12253         else
12254             {
12255 $           SuspendThread (thread);  //-V720
12256 
12257 $           ctx.ContextFlags = CONTEXT_ALL;
12258 $           bool ok = !!GetThreadContext (thread, &ctx);
12259 
12260 $           if (!ok)
12261                 {
12262 $               ResumeThread (thread);
12263 $               return -1;
12264                 }
12265             }
12266         }
12267 
12268 $   Win32::STACKFRAME64 frame = {};
12269 $   frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat;
12270 
12271 $   int cpu = 0;
12272 
12273     #if defined (_WIN64)
12274 
12275 $   if (isWow64)
12276         {
12277 $       Win32::WOW64_CONTEXT wow64ctx = {};
12278 $       wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL;
12279 
12280 $       if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx)))  // This call fails in WINE,
12281             {                                                               // while EXIT_PROCESS_DEBUG_EVENT
12282             if (!thisThread) {$ ResumeThread (thread); }
12283 $           return 0;
12284             }
12285 
12286 $       cpu = IMAGE_FILE_MACHINE_I386;
12287 
12288 $       frame.AddrPC   .Offset = wow64ctx.Eip;
12289 $       frame.AddrStack.Offset = wow64ctx.Esp;
12290 $       frame.AddrFrame.Offset = wow64ctx.Ebp;
12291         }
12292     else
12293         {
12294 $       cpu = IMAGE_FILE_MACHINE_AMD64;
12295 
12296 $       frame.AddrPC   .Offset = ctx.Rip;
12297 $       frame.AddrStack.Offset = ctx.Rbp;
12298 $       frame.AddrFrame.Offset = ctx.Rsp;
12299         }
12300 
12301     #else
12302 
12303         {
12304 $       cpu = IMAGE_FILE_MACHINE_I386;
12305 
12306 $       frame.AddrPC   .Offset = ctx.Eip;
12307 $       frame.AddrStack.Offset = ctx.Ebp;
12308 $       frame.AddrFrame.Offset = ctx.Esp;
12309         }
12310 
12311     #endif
12312 
12313 $   assert (cpu);
12314 
12315     if (_txSetJmp())
12316         {
12317 $       _txSymGetFromAddr ((void*) 1);  //-V566
12318         }
12319 $   _txClearJmp();
12320 
12321 $   int  frames = -1;
12322 
12323 $   for (frames = -framesToSkip; frames < (int) szCapture; frames++)  //-V202 //-V2530
12324         {
12325 $       DWORD64 prev = frame.AddrStack.Offset;
12326 
12327         // Я злой и страшный серый walk. Я в поросятах знаю talk.
12328 
12329         if (!_txSetJmp()) {$ break; }
12330 
12331 #if   defined (_GCC_VER)
12332 
12333         if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12334                                             MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; }
12335 #elif defined (_MSC_VER)
12336 
12337 $       if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12338                                             Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; }
12339 #else
12340         #error _GCC_VER / _MSC_VER not defined
12341 #endif
12342         if (frames < 0) {$ continue; }
12343 
12344 $       void* addr = (void*) frame.AddrPC.Offset;
12345 
12346         if (frame.AddrFrame.Offset == 0)   {$ addr =          0; }  // Bad frame
12347         if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; }  // Strange frame
12348 
12349 $       assert (0 <= frames && frames < (int) szCapture);  //-V202
12350 
12351 $       capture[frames] = addr;                            //-V108
12352         }
12353 
12354 $   _txClearJmp();
12355 
12356     if (!thisThread) {$ ResumeThread (thread); }
12357 
12358 $   return frames;
12359     }
12360 
12361 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl
12362 
12363 //-----------------------------------------------------------------------------------------------------------------
12364 
12365 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/,
12366                         Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/,
12367                         const char** source /*= NULL*/, int context /*= 2*/)
12368     {
12369 $7  static HANDLE process = NULL;
12370 
12371 #if   defined (_GCC_VER)
12372     #define LIB_  Win32::MinGW
12373 
12374 #elif defined (_MSC_VER)
12375     #define LIB_  Win32
12376 
12377 #else
12378     #error _GCC_VER / _MSC_VER not defined
12379 #endif
12380 
12381 $   if (!process && addr)
12382         {
12383 $       process = GetCurrentProcess();
12384 
12385 $       DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES |
12386                         SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS;
12387 
12388 $        _TX_CALL (LIB_::SymSetOptions, (options));
12389 $        _TX_CALL (LIB_::SymInitialize, (process, NULL, true));
12390         }
12391 
12392 $   static DWORD64 mod = 0;
12393 
12394 $   if (module)
12395         {
12396 $       static char sMod [MAX_PATH] = "";
12397 $       memset (sMod, 0, sizeof (sMod));
12398 
12399 $       mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr));
12400 
12401 $       GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH);
12402 
12403 $       char* ext = strrchr (sMod, '.');
12404         if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); }
12405 
12406 $       *module = sMod;
12407         }
12408 
12409 $   static char buffer [_TX_BUFSIZE] = "";
12410 $   static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer;  //-V1032
12411 
12412 $   if (symbol)
12413         {
12414 $       memset (buffer, 0, sizeof (buffer));
12415 
12416 $       sym->MaxNameLen   = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1;
12417 $       sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO);
12418 $       unsigned long long ofs = 0;
12419 
12420 $       _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym));
12421 
12422         if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; }
12423 
12424 $       *symbol = sym;
12425         }
12426 
12427 $   static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line64) };
12428 
12429 $   if (line)
12430         {
12431 $       memset (&line64, 0, sizeof (line64));
12432 
12433 $       DWORD ofs = 0;
12434 $       _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64));
12435 
12436 $       *line = &line64;
12437         }
12438 
12439 $   if (source)
12440         {
12441 $       static char buf [_TX_BUFSIZE] = "";
12442 $       memset (buf, 0, sizeof (buf));
12443 
12444 $       if (line64.FileName && line64.LineNumber)
12445             {
12446 $           _txReadSource (buf, sizeof (buf) - 1, line64.FileName,
12447                           (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber);
12448 
12449 $           *source = buf;
12450             }
12451 
12452         if (!*source || !**source) {$ *source = NULL; }
12453         }
12454 
12455 $   if (!addr && process)
12456         {
12457 $       _TX_CALL (LIB_::SymCleanup, (process));
12458 
12459 $       process = NULL;
12460         }
12461 
12462     #if (_GCC_VER == 481)
12463     #pragma GCC diagnostic push
12464     #pragma GCC system_header
12465     #endif
12466 
12467 $   if (symbol)
12468         {
12469 $       if (strstr  (sym->Name, "::TX::")                                                  ||
12470            (strncmp (sym->Name, "_tx",  3) == 0 && isupper ((unsigned char) sym->Name[3])) ||
12471            (strncmp (sym->Name,  "tx",  2) == 0 && isupper ((unsigned char) sym->Name[2])) ||
12472             strncmp (sym->Name, "_tx_", 4) == 0                                            ||  //-V112
12473             strncmp (sym->Name,  "tx_", 3) == 0)
12474             {
12475 $           return true;
12476             }
12477 
12478     #if (_GCC_VER == 481)
12479     #pragma GCC diagnostic pop
12480     #endif
12481 
12482 $       if (!line || !line64.FileName) return false;
12483 
12484 $       intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1);
12485 
12486 $       return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) &&
12487                (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\');
12488         }
12489 
12490     #undef LIB_
12491 
12492 $   return false;
12493     }
12494 
12495 //-----------------------------------------------------------------------------------------------------------------
12496 
12497 intptr_t _txReadSource (char buf[], intptr_t size, const char file[],
12498                         int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/)
12499     {
12500 $7  assert (buf);
12501 
12502     if (!file || !*file) {$ return 0; }
12503 
12504     if (linStart < 1) {$ linStart = 1;       }
12505     if (linEnd == -1) {$ linEnd   = INT_MAX; }
12506 
12507 $   FILE* f = NULL;
12508 $   fopen_s (&f, file, "r");
12509     if (!f) {$ return 0; }
12510 
12511 $   int n = 1;
12512     while (!feof (f))
12513         {
12514         if (n >= linStart) {$ break; }
12515         while (!feof (f) && fgetc (f) != '\n')
12516             ;
12517         n++;
12518         }
12519 
12520 $   char* s = buf;
12521 
12522     #define SZ_  ( size - 3 - (s - buf) )
12523 
12524 $   while (!feof (f) && SZ_ > 0)
12525         {
12526         if (n > linEnd || _txNOP (SZ_) < 0) {$ break; }
12527 
12528         if (linMark != INT_MIN)
12529             {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : "  "), n); }
12530 
12531 $       int c = 0;
12532 $       while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c;
12533         if (c == EOF) {$ s--; }
12534 
12535         if (SZ_ > 0) {$ *s++ = '\n'; }
12536 $       n++;
12537         }
12538 
12539     if (n <= linEnd && SZ_ <= 0)
12540         {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); }
12541 
12542     #undef SZ_
12543 
12544 $   fclose (f);
12545 
12546     if (s > buf && s[-1] == '\n') {$ s--; }
12547 $   *s = 0;
12548 
12549 $   return (s - buf);
12550     }
12551 
12552 //-----------------------------------------------------------------------------------------------------------------
12553 
12554 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/)
12555     {
12556 $6  const int maxFrames = 62;  // TX says too: < 63
12557 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12558 
12559     if (framesToSkip == -1) {$ return trace; }
12560 
12561 $   memset (trace, 0, sizeof (trace));
12562 $   char* s = trace;
12563 
12564     #define SZ_  ( sizeof (trace) - 1 - 3 - (s-trace) )
12565 
12566 $   const _txLoc* loc = &_txLoc::Cur;
12567 
12568     for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; }
12569 
12570 $   for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev)
12571         {
12572         if (i < 0) {$ continue; }
12573 
12574         if (loc->func || loc->file || loc->line)
12575             {
12576 $           s += _tx_snprintf_s     (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""),
12577                                      i, loc->func, loc->file, loc->line);
12578 
12579 $           if (readSource)
12580                 {
12581 $               s += _tx_snprintf_s (s, SZ_, ":\n\n");
12582 $               s += _txReadSource  (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line);
12583                 }
12584             }
12585         }
12586 
12587     #undef SZ_
12588 
12589 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12590 
12591 $   return trace;
12592     }
12593 
12594 //-----------------------------------------------------------------------------------------------------------------
12595 
12596 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/)
12597     {
12598 $6  static char dumpName[MAX_PATH] = "";
12599     if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); }
12600 
12601 $   HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12602 
12603     if (!file || file == INVALID_HANDLE_VALUE) {$ return false; }
12604 
12605 $   Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false };
12606 $   Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory);
12607 
12608 $   bool ok = _TX_CALL (Win32::MiniDumpWriteDump, (GetCurrentProcess(), GetCurrentProcessId(), file, type,
12609                                                    ((exc)? &excInfo : NULL), NULL, NULL));
12610 $   CloseHandle (file);
12611 
12612     if (ok) {$ return true;  }
12613     else    {$ return false; }
12614     }
12615 
12616 #endif // TX_COMPILED
12617 
12618 //}
12619 //-----------------------------------------------------------------------------------------------------------------
12620 
12621 //-----------------------------------------------------------------------------------------------------------------
12622 //{          Errors reporting
12623 //-----------------------------------------------------------------------------------------------------------------
12624 
12625 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12626 
12627 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args)  //-V2008
12628     {
12629     _txErrors = _txErrors + 1;
12630 
12631     DWORD           winErr   = GetLastError();
12632 
12633     int             crtErr   = errno;
12634 
12635     #if !defined (__CYGWIN__)
12636     unsigned long   dosErr   = _doserrno;
12637     #else
12638     unsigned long   dosErr   = 0;
12639     #endif
12640 
12641     unsigned        dlgErr   = _TX_CALL (Win32::CommDlgExtendedError, ());
12642 
12643     unsigned        oglErr   = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError;
12644 
12645     unsigned        threadId = GetCurrentThreadId();
12646 
12647     enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 };
12648     unsigned options = 0;
12649 
12650     for (; msg && *msg; msg++)
12651         {
12652         if      (*msg == '\a') options |= isFatal;
12653         else if (*msg == '\v') options |= isWarning;
12654         else if (*msg == '\b') options |= noMsgBox;
12655         else if (*msg == '\f') options |= fmtOnly;
12656         else if (*msg == '\t') options |= traceSE;
12657         else break;
12658         }
12659 
12660     const char* stkTrace = NULL;
12661     const char*  txTrace = NULL; (void) txTrace;
12662 
12663     if (!(options & fmtOnly))
12664         {
12665         stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace   (2, true);
12666         txTrace  =                                                    _txCaptureStackBackTraceTX (0, true);
12667         }
12668 
12669     static char what[_TX_BIGBUFSIZE*10] = "";
12670     static char str [_TX_BIGBUFSIZE]    = "";
12671     char *s = what;
12672 
12673     #define     PRINT_(...)  s += _tx_snprintf_s  (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12674     #define    VPRINT_(...)  s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12675 
12676                 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" :
12677                                          (options & isFatal)?   "соболезнует..." :
12678                                                                 "сообщает:"));
12679                 PRINT_ ("Программа: %s", txGetModuleFileName());
12680     if (file)   PRINT_ (", файл: %s",    file);
12681     if (line)   PRINT_ (", строка: %d",  line);
12682     if (func)   PRINT_ (", функция: %s", func);
12683                 PRINT_ (",\n\n");
12684 
12685     if (msg)    PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"),
12686                VPRINT_ (msg, args);
12687 
12688     while (s > what && s[-1] == '\n') s--;
12689 
12690                 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s",
12691 
12692                         _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64,
12693 
12694                         "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace,
12695 
12696                         threadId, (threadId == _txMainThreadId)?    " (Main)"   :
12697                                   (threadId == _txCanvas_ThreadId)? " (Canvas)" : "");
12698 
12699     if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr),
12700                 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
12701                                     NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
12702                                     s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2,            //-V202
12703                 s -=  (s[-1] == '.')? 1 : 0,
12704                 PRINT_ (")");
12705 
12706     if (crtErr) PRINT_ (", errno: %d (%s)",                      crtErr, (strerror_s (str, sizeof (str), crtErr), str));
12707     if (dosErr) PRINT_ (", _doserrno: %lu (%s)",                 dosErr, (strerror_s (str, sizeof (str), dosErr), str));
12708     if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)",       oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr)));
12709     if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr);
12710 
12711     #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L)
12712                 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : "");
12713     #else
12714                 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true."  : "");
12715     #endif
12716 
12717     if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) &&
12718        (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func))
12719                 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func);
12720 
12721     txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what);
12722 
12723     if (options & fmtOnly)
12724         {
12725         SetLastError (winErr);
12726 
12727         errno = crtErr;
12728 
12729         #if !defined (__CYGWIN__)
12730         _doserrno = dosErr;
12731         #endif
12732 
12733         return what;
12734         }
12735 
12736     txSetProgress (-1, Win32::TBPF_ERROR);
12737 
12738     unsigned restore = txGetConsoleAttr();
12739     txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED);
12740     if (color) {$ txSetConsoleAttr (color); }
12741 
12742     int oldCodePage = txSetLocale();
12743 
12744     fprintf (stderr,        "\n" "--------------------------------------------------\n"
12745                                  "%s",
12746                                  what);
12747     if (stkTrace)
12748         {$ fprintf (stderr, "\n" "--------------------------------------------------\n"
12749                                  "Стек вызовов:\n\n"
12750                                  "%s\n\n"
12751                                  "--------------------------------------------------\n",
12752                                  stkTrace); }
12753     errno = 0;
12754     char sErrno[256] = "";
12755     FILE* log = NULL;
12756     if (*_txLogName) fopen_s (&log, _txLogName, "a");
12757     strerror_s (sErrno, sizeof (sErrno), errno);
12758 
12759     if (!log)
12760         {$ fprintf (stderr, "\n" "TXLib шокирован: Не открывается лог-файл \"%s\" для записи: Ошибка %d (%s)!\n",
12761                                  _txLogName, errno, sErrno); }
12762 
12763     SetConsoleOutputCP (oldCodePage);
12764     txSetConsoleAttr (restore);
12765 
12766     if (log)
12767         {
12768         fprintf (log,       "\n" "--------------------------------------------------\n"
12769                                  "%s\n"
12770                                  "--------------------------------------------------\n",
12771                                  what);
12772 
12773         fprintf (log,            "Стек вызовов:\n\n"  //-V576
12774                                  "%s\n",
12775                                  (*_txTraceSE)? _txTraceSE : stkTrace);
12776 
12777         #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG)
12778 
12779         if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace)
12780             {
12781             fprintf (log,   "\n" "--------------------------------------------------\n"
12782                                  "Стек вызовов TX:\n\n"
12783                                  "%s\n",
12784                                  txTrace);
12785             }
12786 
12787         #endif
12788 
12789         fprintf (log,       "\n" "--------------------------------------------------\n"
12790                                  "%s\n\n"
12791                                  "--------------------------------------------------\n",
12792                                  _txAppInfo());
12793         }
12794 
12795     if (log) fclose (log);
12796 
12797     txSleep();
12798 
12799     int ret = 0;
12800 
12801     if (!(options & noMsgBox))
12802         {
12803         txSleep (_txWindowUpdateInterval);
12804 
12805         HWND wnd = GetForegroundWindow();
12806 
12807         PRINT_ ("\n" "Прервать программу?");
12808 
12809         ret = txMessageBox (what, ((options & isWarning)? "Предупреждение"   :
12810                                    (options & isFatal)?   "Фатальная ошибка" :
12811                                                           "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL);
12812         _txActivateWindow (wnd, 0x10);
12813         }
12814 
12815     SetLastError (winErr);
12816 
12817     errno = crtErr;
12818 
12819     #if !defined (__CYGWIN__)
12820     _doserrno = dosErr;
12821     #endif
12822 
12823     if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES)
12824         {
12825         txUnlock();
12826         _txCleanup();
12827         Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
12828         }
12829 
12830     #undef  PRINT_
12831     #undef VPRINT_
12832 
12833     return what;
12834     }
12835 
12836 //-----------------------------------------------------------------------------------------------------------------
12837 
12838 #if defined (_MSC_VER)
12839 
12840 int _txOnErrorReport (int type, const char* text, int* ret)
12841     {
12842     assert (text);
12843     assert (ret);
12844 
12845     _txErrors = _txErrors + 1;
12846 
12847     unsigned restore = txGetConsoleAttr();
12848 
12849     switch (type)
12850        {
12851        case _CRT_WARN:   txSetConsoleAttr (FOREGROUND_LIGHTRED);     break;
12852        case _CRT_ERROR:  txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break;
12853        case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW);       break;
12854        default:                                                      break;  //-V2522
12855        }
12856 
12857     const char startReport[] = "Detected memory leaks!\n",
12858                  endReport[] = "Object dump complete.\n";
12859 
12860     if (strcmp (text, startReport) == 0)  // Dirty, dirty hack. А что делать?
12861         {
12862         _txOnErrorReport (type, "\n",                                                                              NULL);
12863         _txOnErrorReport (type, _TX_VERSION " - ERROR: ",                                                          NULL);
12864         _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL);
12865         _txOnErrorReport (type, "\n",                                                                              NULL);
12866         }
12867 
12868     size_t len = strlen (text);
12869     if (text [len-1] != '\n')               txOutputDebugPrintf ("%s",                text);
12870     else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION);
12871     else                                    txOutputDebugPrintf ("%s\n",              text);
12872 
12873     DWORD n = 0;
12874     HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
12875     WriteFile (err, text, (DWORD) strlen (text), &n, NULL);      //-V202
12876 
12877     txSetConsoleAttr (restore);
12878 
12879     if (*_txLogName) do                                          //-V2530
12880         {
12881         HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12882         if (log == INVALID_HANDLE_VALUE) break;
12883 
12884         SetFilePointer (log, 0, NULL, FILE_END);
12885         WriteFile (log, text, (DWORD) strlen (text), &n, NULL);  //-V202
12886 
12887         CloseHandle (log);
12888         break;
12889         }
12890         while (false);
12891 
12892     if (ret) *ret = 0;
12893 
12894     return (type == _CRT_WARN);
12895     }
12896 
12897 #endif
12898 
12899 //-----------------------------------------------------------------------------------------------------------------
12900 
12901 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/)
12902     {
12903 $5  static wchar_t textW   [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]";
12904 $   static wchar_t headerW [_TX_BUFSIZE    * sizeof (wchar_t)] = L"[NULL header]";
12905 
12906     if (text)   {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text,   -1, textW,   sizearr (textW))   || memset (textW,   0, sizeof (textW));   }
12907     if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); }
12908 
12909 $   txSleep();
12910 
12911 $   HWND wnd = _txCanvas_Window;
12912 $   int  ret = MessageBoxW ((wnd && IsWindowVisible (wnd))? wnd : _TX_CALL (Win32::GetConsoleWindow,()),
12913                             textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST);
12914 
12915 $   GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU);
12916 
12917 $   if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU))
12918         {
12919 $       SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0);
12920 $       _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
12921         }
12922 
12923 $   return ret;
12924     }
12925 
12926 //-----------------------------------------------------------------------------------------------------------------
12927 
12928 bool txGetAsyncKeyState (int key)
12929     {
12930 $1  HWND wnd = GetForegroundWindow();
12931 
12932     return (GetAsyncKeyState (key) & 0x8000) &&
12933            (wnd == txWindow() || wnd == Win32::GetConsoleWindow());
12934     }
12935 
12936 //-----------------------------------------------------------------------------------------------------------------
12937 
12938 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...)
12939     {
12940 $5  if (_TX_ARGUMENT_FAILED (format)) return false;
12941 
12942 $   va_list arg; va_start (arg, format);
12943 $   bool ok = true;
12944 
12945     #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500)
12946 
12947 $   NOTIFYICONDATA nid = { sizeof (nid) };
12948 
12949 $   nid.uFlags      = NIF_ICON | NIF_TIP | NIF_INFO;
12950 $   nid.hWnd        = NULL;
12951 $   nid.uID         = 1;
12952 $   nid.hIcon       = _txCreateTXIcon (16); assert (nid.hIcon);
12953 $   strncpy_s       (nid.szTip,       sizeof (nid.szTip),       "TXLib Information", sizeof (nid.szTip));
12954 $   strncpy_s       (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1);
12955 $   _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg);
12956 $   nid.dwInfoFlags = flags;
12957 
12958 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo);
12959 
12960 $   ok &= !!Shell_NotifyIcon (NIM_ADD,    (::NOTIFYICONDATA*) &nid);
12961 $   ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid);
12962 
12963 $   if (nid.hIcon) DestroyIcon (nid.hIcon) asserted;
12964 
12965     #else
12966 
12967 $   char nid_szInfo[_TX_BUFSIZE] = "";
12968 $   _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg);
12969 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo);
12970 $   ok = false;
12971 
12972 $   (void)flags; (void)title;
12973 
12974     #endif
12975 
12976 $   va_end (arg);
12977     return ok;
12978     }
12979 
12980 //-----------------------------------------------------------------------------------------------------------------
12981 
12982 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...)
12983     {
12984     unsigned id = GetCurrentThreadId();
12985 
12986     const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}};
12987 
12988     char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)];
12989 
12990     char msgStr[_TX_BUFSIZE] = "";
12991     if (msg)
12992         {
12993         va_list arg; va_start (arg, msg);
12994         _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg);
12995         va_end (arg);
12996         }
12997 
12998     txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d)  " "|%*s%s" "%s%s\n",
12999 
13000                          _TX_VERSION, (void*) &_txInitialized,
13001 
13002                          "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit],
13003                          _txLoc::Cur.trace, mark,
13004 
13005                          (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line,
13006                          2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""),
13007 
13008                          ((*msgStr && func)? ": " : ""), msgStr);
13009     }
13010 
13011 //-----------------------------------------------------------------------------------------------------------------
13012 
13013 int txOutputDebugPrintf (const char* format, ...)
13014     {
13015     if (!format) return 0;
13016 
13017     enum { msgbox = 1, print = 2, compr = 4 };
13018     int options = 0;
13019 
13020     for (; format && *format; format++)
13021         {
13022         if      (*format == '\a') options |= msgbox;
13023         else if (*format == '\f') options |= print;
13024         else if (*format == '\r') options |= compr;
13025         else break;
13026         }
13027 
13028     char text[_TX_BIGBUFSIZE] = "";
13029 
13030     va_list arg; va_start (arg, format);
13031     int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg);  //-V202
13032     va_end (arg);
13033 
13034     struct __ { static int trimSpaces (char str[])
13035         {
13036         char *dst = str, *src = str;
13037 
13038         for (char d = ' '; d; src++)
13039             if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; }
13040             else                                                 *dst++ = d = *src;
13041 
13042         return (int) (dst - str - 1);  //-V202
13043         }};
13044 
13045     if (options & compr)  n = __::trimSpaces (text);
13046 
13047     OutputDebugString (text);
13048 
13049     if (options & print)  fprintf (stderr, "%s", text);
13050 
13051     if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION);
13052 
13053     return n;
13054     }
13055 
13056 //-----------------------------------------------------------------------------------------------------------------
13057 
13058 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...)
13059     {
13060     if (!format) return 0;
13061 
13062     va_list arg; va_start (arg, format);
13063     intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg);
13064     va_end (arg);
13065 
13066     return ret;
13067     }
13068 
13069 //-----------------------------------------------------------------------------------------------------------------
13070 
13071 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg)
13072     {
13073     if (!stream || !format) return 0;
13074 
13075     #if defined (_TRUNCATE)
13076     intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg);
13077     #else
13078     intptr_t ret = _vsnprintf   (stream, size,            format, arg);
13079     #endif
13080 
13081     if (ret < 0 && size >= 4)  //-V112
13082         {
13083         const char ellipsis[] = "...";
13084         size_t     szEllipsis = sizeof (ellipsis) - 1;
13085 
13086         strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis);
13087         }
13088 
13089     return (ret >= 0)? ret : size;
13090     }
13091 
13092 //-----------------------------------------------------------------------------------------------------------------
13093 
13094 #if defined (__CYGWIN__)
13095 
13096 int _getch()
13097     {
13098     termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr);
13099 
13100     termios newattr = oldattr;
13101     newattr.c_lflag &= ~(ICANON | ECHO);
13102     tcsetattr (STDIN_FILENO, TCSANOW, &newattr);
13103 
13104     int ch = getchar();
13105 
13106     tcsetattr (STDIN_FILENO, TCSANOW, &oldattr);
13107 
13108     return ch;
13109     }
13110 
13111 //-----------------------------------------------------------------------------------------------------------------
13112 
13113 int _putch (int ch)
13114     {
13115     termios old = {}; tcgetattr (STDOUT_FILENO, &old);
13116 
13117     termios cur = old;
13118     cur.c_lflag &= ~ICANON;
13119     cur.c_lflag |=  ECHO;
13120     tcsetattr (STDOUT_FILENO, TCSANOW, &cur);
13121 
13122     putchar (ch);
13123 
13124     tcsetattr (STDOUT_FILENO, TCSANOW, &old);
13125 
13126     return ch;
13127     }
13128 
13129 //-----------------------------------------------------------------------------------------------------------------
13130 
13131 int _kbhit()
13132     {
13133     termios old = {}; tcgetattr (STDIN_FILENO, &old);
13134 
13135     termios cur = old;
13136     cur.c_lflag &= ~(ICANON | ECHO);
13137     cur.c_cc[VMIN]  = 1;
13138     cur.c_cc[VTIME] = 0;
13139 
13140     tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur);
13141 
13142     fd_set  fd = {}; FD_SET (STDIN_FILENO, &fd);
13143     timeval tv = {};
13144 
13145     int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd);
13146 
13147     tcsetattr (STDIN_FILENO, TCSAFLUSH, &old);
13148 
13149     return res;
13150     }
13151 
13152 #endif
13153 
13154 #endif // TX_COMPILED
13155 
13156 //}
13157 //-----------------------------------------------------------------------------------------------------------------
13158 
13159 //-----------------------------------------------------------------------------------------------------------------
13160 //{          Information
13161 //-----------------------------------------------------------------------------------------------------------------
13162 
13163 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13164 
13165 const char* txGetModuleFileName (bool fileNameOnly /*= true*/)
13166     {
13167     static char name[MAX_PATH] = "";
13168 
13169     if (!*name)
13170         {
13171         if (!GetModuleFileName (NULL, name, sizeof (name) - 1)) strncpy_s (name, sizeof (name), "~TXApp", 6);
13172 
13173         char* ext = strrchr (name, '.');
13174         if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name));
13175         }
13176 
13177     assert (*name);
13178 
13179     if (fileNameOnly) return name;
13180 
13181     static char fullName[MAX_PATH] = "";
13182     static char* title = fullName;
13183 
13184     if (!*fullName || !*title)
13185         {
13186         strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1);
13187 
13188               title = strrchr (fullName, '\\'); if (!title) title = fullName;
13189         char* ext   = strrchr (fullName,  '.'); if (!ext)   ext   = fullName + strlen (fullName);
13190 
13191         size_t sz = sizeof (fullName) - (ext - fullName);
13192         strncpy_s (ext, sz-1, " - TXLib", sz);
13193 
13194         title++;
13195         }
13196 
13197     assert (*title);
13198 
13199     return title;
13200     }
13201 
13202 #endif // TX_COMPILED
13203 
13204 //-----------------------------------------------------------------------------------------------------------------
13205 
13206 inline const char* _txAppInfo()
13207     {
13208 $1  time_t timeT     = time (NULL) - clock()/CLOCKS_PER_SEC;  //-V104
13209     char   timeS[32] = "";
13210     ctime_s (timeS, sizeof (timeS), &timeT);
13211 
13212     static char text[_TX_BUFSIZE] = "";
13213     char cwd [MAX_PATH] = "";
13214 
13215     _tx_snprintf_s (text, sizeof (text) - 1,
13216 
13217                     "Developed with:\n\n"
13218                     "The Dumb Artist Library (TX Library)\n"
13219                     _TX_VERSION "\n" _TX_AUTHOR "\n"
13220                     "See license on: http://txlib.ru\n\n"
13221 
13222                     "TXLib file:" "\t" __FILE__ "\n"
13223                     "Compiled:"   "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n"
13224                     "Started:"    "\t" "%.6s %.4s %.8s\n\n"
13225 
13226                     "Run file:"   "\t" "%s\n"
13227                     "Directory:"  "\t" "%s",
13228 
13229     #if   defined (_MSC_VER)
13230                     "MSVC Runtime",
13231     #elif defined (__CYGWIN__)
13232                     "Cygwin Runtime",
13233     #elif defined (_GCC_VER) && defined (_WIN64)
13234                     __mingw_get_crt_info(),
13235     #else
13236                     "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION),
13237     #endif
13238                     (sizeof (void*) == sizeof (DWORD))? 32 : 64,    //-V112
13239 
13240                     timeS + 4, timeS + 20, timeS + 11,              //-V112 These offsets are ANSI standardized
13241                     txGetModuleFileName(),
13242                     _getcwd (cwd, sizeof (cwd) - 1));
13243 
13244     return text;
13245     }
13246 
13247 //}
13248 //-----------------------------------------------------------------------------------------------------------------
13249 
13251 //}
13252 //=================================================================================================================
13253 
13254 //=================================================================================================================
13255 //{          TXLib API implementation
13256 //           Реализация TXLib API
13257 //=================================================================================================================
13258 
13259 inline const char* txVersion()
13260     {
13261     return _TX_VERSION;
13262     }
13263 
13264 //-----------------------------------------------------------------------------------------------------------------
13265 
13266 inline unsigned txVersionNumber()
13267     {
13268     return _TX_VER;  //-V2517
13269     }
13270 
13271 //-----------------------------------------------------------------------------------------------------------------
13272 
13273 inline HWND txWindow()
13274     {
13275 $9  return _txCanvas_Window;
13276     }
13277 
13278 //-----------------------------------------------------------------------------------------------------------------
13279 
13280 inline HDC& txDC()
13281     {
13282     return _txCanvas_BackBuf[0];
13283     }
13284 
13285 //-----------------------------------------------------------------------------------------------------------------
13286 
13287 inline RGBQUAD* txVideoMemory()
13288     {
13289     return _txCanvas_Pixels;
13290     }
13291 
13292 //-----------------------------------------------------------------------------------------------------------------
13293 
13294 inline int txGetExtentX (HDC dc /*= txDC()*/)
13295     {
13296     return txGetExtent (dc) .x;
13297     }
13298 
13299 //-----------------------------------------------------------------------------------------------------------------
13300 
13301 inline int txGetExtentY (HDC dc /*= txDC()*/)
13302     {
13303     return txGetExtent (dc) .y;
13304     }
13305 
13306 //-----------------------------------------------------------------------------------------------------------------
13307 
13308 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13309 
13310 POINT txGetExtent (HDC dc /*= txDC()*/)
13311     {
13312 $0  static POINT err = {-1, -1};
13313 
13314     if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; };
13315 
13316     if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; }
13317 
13318 $   BITMAP bmap = {};
13319 $   txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted;
13320 
13321 $   POINT  size = { bmap.bmWidth, bmap.bmHeight };
13322 $   return size;
13323     }
13324 
13325 //-----------------------------------------------------------------------------------------------------------------
13326 
13327 bool txDestroyWindow (HWND wnd /*= txWindow()*/)
13328     {
13329 $1  if (!wnd || !txWindow()) return false;
13330 
13331 $   if (wnd != txWindow())
13332         {
13333 $       return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd);
13334         }
13335 
13336 $   if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false;
13337 
13338 $   if (_txMain)
13339         {
13340 $       txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n"
13341                                                "Возвращайтесь через main(), там вам будут рады.\n");
13342 $       Sleep (_TX_TIMEOUT);
13343         }
13344 
13345 $   _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
13346 
13347 $   return _txCanvas_Window == NULL;
13348     }
13349 
13350 //-----------------------------------------------------------------------------------------------------------------
13351 
13352 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/)
13353     {
13354 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13355 
13356 $   HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color);
13357 
13358 $   if (!pen) return (HPEN) NULL;
13359 
13360 $   if (!_txBuffer_Select (pen, dc))
13361         {
13362 $       Win32::DeleteObject (pen);
13363 $       return (HPEN) NULL;
13364         }
13365 
13366 $   if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID)
13367         {$ return (HPEN) NULL; }
13368 
13369 $   return pen;
13370     }
13371 
13372 //-----------------------------------------------------------------------------------------------------------------
13373 
13374 COLORREF txColor (double red, double green, double blue)
13375     {
13376 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13377 $   if (green > 1) green = 1; if (green < 0) green = 0;
13378 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13379 
13380 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13381 
13382 $   return txSetColor (color)? color : CLR_INVALID;
13383     }
13384 
13385 //-----------------------------------------------------------------------------------------------------------------
13386 
13387 COLORREF txGetColor (HDC dc /*= txDC()*/)
13388     {
13389 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13390 
13391 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc);
13392 $   assert (obj); if (!obj) return CLR_INVALID;              //-V547
13393 
13394 $   union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {};  //-V2514
13395 
13396 $   int size = Win32::GetObject (obj, 0, NULL);
13397 $   Win32::GetObject (obj, sizeof (buf), &buf) asserted;
13398 
13399 $   return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor;
13400     }
13401 
13402 //-----------------------------------------------------------------------------------------------------------------
13403 
13404 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/)
13405     {
13406 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13407 
13408 $   HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color);
13409 
13410 $   return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL);
13411     }
13412 
13413 //-----------------------------------------------------------------------------------------------------------------
13414 
13415 COLORREF txFillColor (double red, double green, double blue)
13416     {
13417 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13418 $   if (green > 1) green = 1; if (green < 0) green = 0;
13419 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13420 
13421 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13422 
13423 $   return txSetFillColor (color)? color : CLR_INVALID;
13424     }
13425 
13426 //-----------------------------------------------------------------------------------------------------------------
13427 
13428 COLORREF txGetFillColor (HDC dc /*= txDC()*/)
13429     {
13430 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13431 
13432 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc);
13433 $   assert (obj); if (!obj) return CLR_INVALID;  //-V547
13434 
13435 $   LOGBRUSH buf = {};
13436 $   txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted;
13437 
13438 $   return buf.lbColor;
13439     }
13440 
13441 //-----------------------------------------------------------------------------------------------------------------
13442 
13443 bool txClear (HDC dc /*= txDC()*/)
13444     {
13445 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13446 
13447 $   POINT size = txGetExtent (dc);
13448 $   return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc);
13449     }
13450 
13451 //-----------------------------------------------------------------------------------------------------------------
13452 
13453 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/)
13454     {
13455 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13456 
13457 $   txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc);
13458 
13459 $   return true;
13460     }
13461 
13462 //-----------------------------------------------------------------------------------------------------------------
13463 
13464 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/)
13465     {
13466 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13467 $   if (green > 1) green = 1; if (green < 0) green = 0;
13468 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13469 
13470 $   return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc);
13471     }
13472 
13473 //-----------------------------------------------------------------------------------------------------------------
13474 
13475 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/)
13476     {
13477 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13478 
13479 $   return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc);
13480     }
13481 
13482 //-----------------------------------------------------------------------------------------------------------------
13483 
13484 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13485     {
13486 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13487 
13488 $   bool ok  = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc);
13489 $        ok &= txGDI ((Win32::LineTo   (dc, ROUND (x1), ROUND (y1)      )), dc);
13490 
13491 $   return ok;
13492     }
13493 
13494 //-----------------------------------------------------------------------------------------------------------------
13495 
13496 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13497     {
13498 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13499 
13500 $   return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13501     }
13502 
13503 //-----------------------------------------------------------------------------------------------------------------
13504 
13505 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/)
13506     {
13507 $1  if (_TX_ARGUMENT_FAILED    (points)) return false;
13508 $   if (_TX_DEFAULT_HDC_FAILED (dc))     return false;
13509 
13510 $   return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc);
13511     }
13512 
13513 //-----------------------------------------------------------------------------------------------------------------
13514 
13515 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13516     {
13517 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13518 
13519 $   return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13520     }
13521 
13522 //-----------------------------------------------------------------------------------------------------------------
13523 
13524 bool txCircle (double x, double y, double r)
13525     {
13526 $1  return txEllipse (x-r, y-r, x+r, y+r);
13527     }
13528 
13529 //-----------------------------------------------------------------------------------------------------------------
13530 
13531 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13532     {
13533 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13534 
13535 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13536 
13537 $   double start =  startAngle               * txPI/180,
13538            end   = (startAngle + totalAngle) * txPI/180;
13539 
13540 $   return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13541                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13542                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13543     }
13544 
13545 //-----------------------------------------------------------------------------------------------------------------
13546 
13547 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13548     {
13549 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13550 
13551 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13552 
13553 $   double start =  startAngle               * txPI/180,
13554            end   = (startAngle + totalAngle) * txPI/180;
13555 
13556 $   return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13557                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13558                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13559     }
13560 
13561 //-----------------------------------------------------------------------------------------------------------------
13562 
13563 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13564     {
13565 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13566 
13567 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13568 
13569 $   double start =  startAngle               * txPI/180,
13570            end   = (startAngle + totalAngle) * txPI/180;
13571 
13572 $   return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13573                                        ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13574                                        ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13575     }
13576 
13577 //-----------------------------------------------------------------------------------------------------------------
13578 
13579 bool txFloodFill (double x, double y,
13580                   COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/)
13581     {
13582 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13583 
13584 $   if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc);
13585 
13586 $   return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc);
13587     }
13588 
13589 //-----------------------------------------------------------------------------------------------------------------
13590 
13591 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/)
13592     {
13593 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13594 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13595 
13596 $   int len = (int) strlen (text);  //-V202
13597 $   bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc);
13598 
13599 $   return ok;
13600     }
13601 
13602 //-----------------------------------------------------------------------------------------------------------------
13603 
13604 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
13605                  unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/,
13606                  HDC dc /*= txDC()*/)
13607     {
13608 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13609 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13610 
13611 #if !defined (NDEBUG)
13612 
13613 $   if (x0 > x1)
13614         {
13615 $       SetLastError (ERROR_INVALID_DATA);
13616 $       TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1);
13617         }
13618 
13619 $   if (y0 > y1)
13620         {
13621 $       SetLastError (ERROR_INVALID_DATA);
13622 $       TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1);
13623         }
13624 
13625 #endif
13626 
13627 $   RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) };
13628 
13629 $   if (!strchr (text, '\n')) format |= DT_SINGLELINE;
13630 
13631 $   unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc);
13632 
13633 $   bool ok = false;
13634 
13635 $   if (Win32::DrawText)
13636         {
13637 $       ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc);
13638 $       Win32::GetPixel (dc, 0, 0);
13639 $       ok = true;  //-V519
13640         }
13641     else
13642         {
13643 $       txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text);
13644 $       ok = false;
13645         }
13646 
13647 $   txSetTextAlign (prev, dc);
13648 
13649 $   return ok;
13650     }
13651 
13652 //-----------------------------------------------------------------------------------------------------------------
13653 
13654 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/,
13655                     int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/,
13656                     bool strikeout /*= false*/, double angle /*= 0*/,
13657                     HDC dc /*= txDC()*/)
13658     {
13659 $1  if (_TX_ARGUMENT_FAILED    (name)) return NULL;
13660 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return NULL;
13661 
13662 $   HFONT font = txFontExist (name)?
13663                      Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3),
13664                                         ROUND (angle*10), 0, bold, italic, underline, strikeout,
13665                                         RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
13666                                         DEFAULT_QUALITY, DEFAULT_PITCH, name)
13667                      :
13668                      (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT);
13669 
13670 $   _txBuffer_Select (font, dc);
13671 
13672 $   return font;
13673     }
13674 
13675 //-----------------------------------------------------------------------------------------------------------------
13676 
13677 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/)
13678     {
13679 $1  SIZE size = {-1, -1};
13680 
13681 $   if (_TX_ARGUMENT_FAILED    (text)) return size;
13682 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return size;
13683 
13684 $   size_t len = strlen (text);
13685 $   txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted;  //-V202
13686 
13687 $   return size;
13688     }
13689 
13690 //-----------------------------------------------------------------------------------------------------------------
13691 
13692 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/)
13693     {
13694 $1  return txGetTextExtent (text, dc) .cx;
13695     }
13696 
13697 //-----------------------------------------------------------------------------------------------------------------
13698 
13699 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/)
13700     {
13701 $1  return txGetTextExtent (text, dc) .cy;
13702     }
13703 
13704 //-----------------------------------------------------------------------------------------------------------------
13705 
13706 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/)
13707     {
13708 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;  //-V601
13709 
13710 $   return txGDI ((Win32::SetTextAlign (dc, align)), dc);
13711     }
13712 
13713 //-----------------------------------------------------------------------------------------------------------------
13714 
13715 LOGFONT* txFontExist (const char name[])
13716     {
13717 $1  if (_TX_ARGUMENT_FAILED (name)) return NULL;
13718 
13719 $   static LOGFONT font = {};
13720 $   font.lfCharSet = DEFAULT_CHARSET;
13721 $   strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1);
13722 
13723 $   struct tools
13724         {
13725         static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data)
13726             {
13727 $           if (_TX_ARGUMENT_FAILED (fnt))  return 0;
13728 $           if (_TX_ARGUMENT_FAILED (data)) return 0;
13729 
13730             #ifndef __STRICT_ANSI__
13731 $           return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13732 
13733             #else
13734 $           return  strncmp  (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13735 
13736             #endif
13737             }
13738         };
13739 
13740 $   return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL;
13741     }
13742 
13743 //-----------------------------------------------------------------------------------------------------------------
13744 
13745 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/)
13746     {
13747 $1  if (_TX_ARGUMENT_FAILED    (obj)) return false;
13748 $   if (_TX_DEFAULT_HDC_FAILED (dc))  return false;
13749 
13750 $   return _txBuffer_Select (obj, dc);
13751     }
13752 
13753 //-----------------------------------------------------------------------------------------------------------------
13754 
13755 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
13756     {
13757 $1  POINT size = { ROUND (sizeX), ROUND (sizeY) };
13758 
13759 $   HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels);
13760 $   assert (dc); if (!dc) return NULL;  //-V547
13761 
13762 $   txSetDefaults (dc);
13763 
13764 $   if (!_txCanvas_UserDCs) return dc;
13765 
13766 $   txAutoLock _lock;
13767 $   _txCanvas_UserDCs->push_back (dc);
13768 
13769 $   if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE)
13770         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); }  //-V202
13771 
13772 $   return dc;
13773     }
13774 
13775 //-----------------------------------------------------------------------------------------------------------------
13776 
13777 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/)
13778     {
13779 $1  return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels);
13780     }
13781 
13782 //-----------------------------------------------------------------------------------------------------------------
13783 
13784 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)
13785     {
13786 $1  return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels);
13787     }
13788 
13789 //-----------------------------------------------------------------------------------------------------------------
13790 
13791 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/,
13792                  unsigned imageFlags /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/)
13793     {
13794 $1  if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL;
13795 
13796 $   HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL),
13797                                                  filename, imageFlags, sizeX, sizeY, loadFlags);
13798 $   if (!image) return NULL;
13799 
13800 $   HDC dc = txCreateCompatibleDC (sizeX, sizeY, image);
13801 
13802 $   if (!(loadFlags & LR_LOADFROMFILE)) return dc;
13803 
13804 $   static std::map <std::string, unsigned> loadTimes;
13805 $   std::string file = filename;
13806 $   unsigned time    = GetTickCount();
13807 
13808 $   if ((long) (time - loadTimes [file]) < _TX_TIMEOUT)
13809         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); }
13810 
13811 $   loadTimes [file] = time;
13812 
13813 $   return dc;
13814     }
13815 
13816 //-----------------------------------------------------------------------------------------------------------------
13817 
13818 bool txDeleteDC (HDC* pdc)
13819     {
13820 $1  if (_TX_ARGUMENT_FAILED (pdc)) return false;
13821 
13822 $   HDC  dc = *pdc;
13823 $   bool ok = _txBuffer_Delete (pdc);
13824 $   if (!ok) return false;
13825 
13826 $   if (!_txCanvas_UserDCs) return ok;
13827 
13828 $   txAutoLock _lock;
13829 
13830 $   for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it)
13831         if (*it == dc)
13832             {
13833 $           std::swap (*it, _txCanvas_UserDCs->back());
13834 $           _txCanvas_UserDCs->pop_back();
13835 $           break;
13836             }
13837 
13838 $   return ok;
13839     }
13840 
13841 //-----------------------------------------------------------------------------------------------------------------
13842 
13843 bool txDeleteDC (HDC dc)
13844     {
13845 $1  return txDeleteDC (&dc);
13846     }
13847 
13848 //-----------------------------------------------------------------------------------------------------------------
13849 
13850 bool txBitBlt (HDC destImage,   double xDest, double yDest, double width, double height,
13851                HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/)
13852     {
13853 $1  if (_TX_HDC_FAILED (destImage))   return false;
13854 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13855 
13856 $   POINT size = txGetExtent (sourceImage);
13857 $   if (!width)  width  = size.x;  //-V550
13858 $   if (!height) height = size.y;  //-V550
13859 
13860 $   return txGDI (!!(Win32::BitBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13861                                     sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage);
13862     }
13863 
13864 //-----------------------------------------------------------------------------------------------------------------
13865 
13866 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/)
13867     {
13868 $1  if (_TX_TXWINDOW_FAILED()) return false;
13869 
13870 $   return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource);
13871     }
13872 
13873 //-----------------------------------------------------------------------------------------------------------------
13874 
13875 bool txTransparentBlt (HDC destImage,   double xDest, double yDest, double width, double height,
13876                        HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/)
13877     {
13878     // Это проверки того, правильные ли HDC вы передали в функцию.
13879     // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а.
13880     // При первом чтении это можно пропустить.
13881 
13882 $1  if (_TX_HDC_FAILED (destImage))   return false;
13883 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13884 
13885     // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent().
13886     // При первом чтении это можно пропустить.
13887 
13888 $   POINT size = txGetExtent (sourceImage);
13889 $   if (!width)  width  = size.x;  //-V550
13890 $   if (!height) height = size.y;  //-V550
13891 
13892     // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest).
13893     // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только
13894     // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки).
13895     // При первом чтении это можно пропустить.
13896 
13897 #if !defined (NDEBUG)
13898 
13899 $   if (!(0 <= xSource && xSource + width  <= size.x &&
13900           0 <= ySource && ySource + height <= size.y))
13901         {
13902 $       SetLastError (ERROR_INVALID_DATA);
13903 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
13904                   "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
13905         }
13906 
13907 #endif
13908 
13909 $   bool ok = true;
13910 
13911 $   if (Win32::TransparentBlt)
13912         {
13913         // А вот теперь уже надо начать читать.
13914         //
13915         // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function"
13916         // и почитайте про ее параметры.
13917         //
13918         // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не
13919         // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что
13920         // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s>
13921         // это сделано для упрощения вызова функции TransparentBlt().
13922 
13923                                // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки!        // <<--
13924                                //                                                                                                          // <<--
13925                                //                                                                    |||||          ||||||                 // <<--
13926                                //                                                                    vvvvv          vvvvvv                 // <<--
13927                                                                                                                                            // <<--
13928 $       ok &= txGDI (!!(Win32::TransparentBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),               // <<<<
13929                                                sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<<
13930                                                destImage);                                                                                 // <<--
13931                                //                                                                    ^^^^^          ^^^^^^                 // <<--
13932                                //                                                                    |||||          ||||||                 // <<--
13933                                //                                                                                                          // <<--
13934         }                      // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте!     // <<--
13935     else
13936         {
13937 $       ok &= txGDI (!!(Win32::BitBlt         (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13938                                                sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
13939                                                destImage);
13940         }
13941 
13942     // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что
13943     // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s>
13944     // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL
13945     // или DirectX, будет круто. Хотя это и сложнее.</s>
13946 
13947     // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами,
13948     // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :((
13949 
13950 $   return ok;
13951     }
13952 
13953 //-----------------------------------------------------------------------------------------------------------------
13954 
13955 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
13956                        COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/)
13957     {
13958 $1  if (_TX_TXWINDOW_FAILED()) return false;
13959 
13960 $   return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor);
13961     }
13962 
13963 //-----------------------------------------------------------------------------------------------------------------
13964 
13965 bool txAlphaBlend (HDC destImage,   double xDest, double yDest, double width, double height,
13966                    HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
13967     {
13968 $1  if (_TX_HDC_FAILED (destImage))   return false;
13969 $   if (_TX_HDC_FAILED (sourceImage)) return false;
13970 
13971 $   POINT size = txGetExtent (sourceImage);
13972 $   if (!width)  width  = size.x;  //-V550
13973 $   if (!height) height = size.y;  //-V550
13974 
13975 #if !defined (NDEBUG)
13976 
13977 $   if (!(0 <= xSource && xSource + width  <= size.x &&
13978           0 <= ySource && ySource + height <= size.y))
13979         {
13980 $       SetLastError (ERROR_INVALID_DATA);
13981 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
13982                   "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
13983         }
13984 
13985 #endif
13986 
13987 $   if (alpha < 0) alpha = 0;
13988 $   if (alpha > 1) alpha = 1;
13989 
13990 $   BITMAP bmap = { 0, 0, 0, 0, 0, 24 };
13991 $   bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap);
13992 
13993 $   BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) };  //-V112 //-V821 //-V2551
13994 
13995 $   if (Win32::AlphaBlend)
13996         {
13997 $       ok &= txGDI (!!(Win32::AlphaBlend (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
13998                                            sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)),
13999                                            destImage);
14000         }
14001     else
14002         {
14003 $       ok &= txGDI (!!(Win32::BitBlt     (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
14004                                            sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
14005                                            destImage);
14006 $       ok = false;  //-V519
14007         }
14008 
14009 $   return ok;
14010     }
14011 
14012 //-----------------------------------------------------------------------------------------------------------------
14013 
14014 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
14015                    double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
14016     {
14017 $1  if (_TX_TXWINDOW_FAILED()) return false;
14018 
14019 $   return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha);
14020     }
14021 
14022 //-----------------------------------------------------------------------------------------------------------------
14023 
14024 HDC txUseAlpha (HDC image)
14025     {
14026 $1  if (_TX_HDC_FAILED (image)) return NULL;
14027 
14028 $   HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP);
14029 $   if (!bitmap) return NULL;
14030 
14031 $   DIBSECTION dib = {};
14032 $   Win32::GetObject (bitmap, sizeof (dib), &dib) asserted;
14033 
14034 $   POINT      size = {  dib.dsBm.bmWidth, dib.dsBm.bmHeight };
14035 $   BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }};
14036 $   RGBQUAD*   buf  = NULL;
14037 
14038 $   bool isDIB = (dib.dsBm.bmPlanes        == 1                    &&
14039                   dib.dsBm.bmBitsPixel     == sizeof (RGBQUAD) * 8 &&
14040                   dib.dsBmih.biCompression == DIB_RGB_COLORS       &&
14041                   dib.dsBm.bmBits);
14042 $   if (!isDIB)
14043         {
14044 $       buf = new (std::nothrow) RGBQUAD [size.x * size.y];  //-V121
14045 $       if (!buf) return NULL;
14046 
14047 $       Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
14048         }
14049     else
14050         {
14051 $       buf = (RGBQUAD*) dib.dsBm.bmBits;
14052         }
14053 
14054 $   for (int y = 0; y < size.y; y++)
14055     for (int x = 0; x < size.x; x++)
14056         {
14057         RGBQUAD* color = &buf [x + y * size.x];  // Get color at (x, y) within image buffer  //-V108
14058 
14059         color->rgbRed   = (BYTE) ROUND (color->rgbRed   * color->rgbReserved / 255.0);
14060         color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0);
14061         color->rgbBlue  = (BYTE) ROUND (color->rgbBlue  * color->rgbReserved / 255.0);
14062         }
14063 
14064 $   if (!isDIB)
14065         {
14066 $       Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
14067 
14068 $       delete[] buf;
14069         }
14070 
14071 $   return image;
14072     }
14073 
14074 //-----------------------------------------------------------------------------------------------------------------
14075 
14076 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/)
14077     {
14078 $1  if (_TX_ARGUMENT_FAILED    (filename)) return false;
14079 $   if (_TX_DEFAULT_HDC_FAILED (dc))       return false;
14080 
14081 $   POINT size = txGetExtent (dc);
14082 
14083 $   size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER),  //-V119
14084            szImg  = (size.x * size.y) * sizeof (RGBQUAD);                   //-V104
14085 
14086 $   BITMAP           bmap = {};
14087 $   BITMAPFILEHEADER hdr  = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs };  //-V202
14088 $   BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB };
14089 
14090 $   RGBQUAD* buf = NULL;
14091 $   bool     ok  = true;
14092 
14093 $   ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap);
14094 
14095     if (!ok) {$ return false; }
14096 
14097 $   if (!bmap.bmBits)
14098         {
14099 $       buf =  new (std::nothrow) RGBQUAD [size.x * size.y];                //-V121
14100 $       ok &= (buf != NULL);
14101 
14102 $       int res = Win32::GetDIBits (dc,  (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y,
14103                                     buf, (BITMAPINFO*) &info, DIB_RGB_COLORS);
14104 
14105         if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); }
14106 
14107 $       ok &= !!res;
14108         }
14109     else
14110         {
14111 $       buf = (RGBQUAD*) bmap.bmBits;
14112         }
14113 
14114 $   FILE* f = NULL;
14115 $   if (ok) fopen_s (&f, filename, "wb");
14116 $   ok &= (f != NULL);
14117 
14118 $   if (ok) ok &= (fwrite (&hdr,  sizeof (hdr),  1, f) == 1);               //-V575 //-V595
14119 $   if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1);
14120 $   if (ok) ok &= (fwrite (buf,   szImg,         1, f) == 1);               //-V575
14121 
14122 $   ok &= (f && fclose (f) == 0);
14123 
14124 $   if (!bmap.bmBits)
14125         {
14126 $       delete[] buf;
14127 $       buf = NULL;
14128         }
14129 
14130 $   return ok;
14131     }
14132 
14133 //-----------------------------------------------------------------------------------------------------------------
14134 
14135 double txSleep (double time)
14136     {
14137 $1  LARGE_INTEGER start = {};
14138 $   QueryPerformanceCounter (&start) asserted;
14139 
14140 $   LARGE_INTEGER freq = {};
14141 $   QueryPerformanceFrequency (&freq) asserted;
14142 
14143 $   int lock = _txCanvas_RefreshLock;
14144 $   _txCanvas_RefreshLock = 0;
14145 
14146 $   HWND wnd = txWindow();
14147     if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
14148 
14149 $   Sleep (ROUND ((time >= 0)? time : 0));
14150 
14151 $   _txCanvas_RefreshLock = lock;
14152 
14153 $   LARGE_INTEGER stop = {};
14154 $   QueryPerformanceCounter (&stop) asserted;
14155 
14156 $   return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart;
14157     }
14158 
14159 //-----------------------------------------------------------------------------------------------------------------
14160 
14161 bool txLock (bool wait /*= true*/)
14162     {
14163 $0  if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14164 
14165 $   if (wait) {$ return      EnterCriticalSection (&_txCanvas_LockBackBuf), true; }  //-V1048
14166     else      {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf);       }
14167     }
14168 
14169 //-----------------------------------------------------------------------------------------------------------------
14170 
14171 bool txUnlock()
14172     {
14173 $0  LeaveCriticalSection (&_txCanvas_LockBackBuf);
14174 
14175 $   if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14176 $   return false;
14177     }
14178 
14179 #endif // TX_COMPILED
14180 
14181 //-----------------------------------------------------------------------------------------------------------------
14182 
14183 template <typename T>
14184 inline T txUnlock (T value)
14185     {
14186 $1  txUnlock();
14187 $   return value;
14188     }
14189 
14190 //-----------------------------------------------------------------------------------------------------------------
14191 
14192 inline void txRedrawWindow()
14193     {
14194 $1  txSleep (0);
14195     }
14196 
14197 //-----------------------------------------------------------------------------------------------------------------
14198 
14199 inline int txUpdateWindow (int update /*= true*/)
14200     {
14201 $1  return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update);
14202     }
14203 
14204 //-----------------------------------------------------------------------------------------------------------------
14205 
14206 inline int txBegin()
14207     {
14208 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1);
14209 
14210 $   return _txCanvas_RefreshLock;
14211     }
14212 
14213 //-----------------------------------------------------------------------------------------------------------------
14214 
14215 inline int txEnd()
14216     {
14217 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1);
14218 
14219 $   return _txCanvas_RefreshLock;
14220     }
14221 
14222 //-----------------------------------------------------------------------------------------------------------------
14223 
14224 inline POINT txMousePos()
14225     {
14226 $1  POINT pos = {};
14227 $   GetCursorPos (&pos);
14228 
14229 $   if (txWindow())
14230         {$ ScreenToClient (txWindow(), &pos); }
14231 
14232 $   return pos;
14233     }
14234 
14235 //-----------------------------------------------------------------------------------------------------------------
14236 
14237 inline double txMouseX()
14238     {
14239     return (double) txMousePos() .x;
14240     }
14241 
14242 //-----------------------------------------------------------------------------------------------------------------
14243 
14244 inline double txMouseY()
14245     {
14246     return (double) txMousePos() .y;
14247     }
14248 
14249 //-----------------------------------------------------------------------------------------------------------------
14250 
14251 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14252 
14253 unsigned txMouseButtons()
14254     {
14255 $1  HWND txWnd      = txWindow();
14256 $   HWND foreground = GetForegroundWindow();
14257 
14258 $   if ((txWnd && (foreground == txWnd)) ||
14259        (!txWnd && (foreground == Win32::GetConsoleWindow())))
14260         {
14261 $       return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) |  // MSB to bit 0
14262                ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) |  // MSB to bit 1
14263                ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13);   // MSB to bit 2
14264         }
14265     else
14266         {$ return 0; }
14267     }
14268 
14269 //-----------------------------------------------------------------------------------------------------------------
14270 
14271 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/)
14272     {
14273     unsigned oldAttr = txGetConsoleAttr();
14274 
14275     SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color);
14276     SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE),  (WORD) color);
14277 
14278     return oldAttr;
14279     }
14280 
14281 //-----------------------------------------------------------------------------------------------------------------
14282 
14283 unsigned txGetConsoleAttr()
14284     {
14285     CONSOLE_SCREEN_BUFFER_INFO con = {};
14286     con.wAttributes = FOREGROUND_LIGHTGRAY;
14287 
14288     GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) ||
14289     GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE),  &con);
14290 
14291     return con.wAttributes;
14292     }
14293 
14294 //-----------------------------------------------------------------------------------------------------------------
14295 
14296 POINT txSetConsoleCursorPos (double x, double y)
14297     {
14298 $1  POINT fontSz = txGetConsoleFontSize();
14299 
14300 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14301 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14302 
14303 $   COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left),
14304                   (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) };
14305 
14306 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted;
14307 
14308 $   POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14309                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14310 $   return prev;
14311     }
14312 
14313 //-----------------------------------------------------------------------------------------------------------------
14314 
14315 POINT txGetConsoleCursorPos()
14316     {
14317 $1  POINT fontSz = txGetConsoleFontSize();
14318 
14319 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14320 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14321 
14322 $   POINT  pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14323                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14324 $   return pos;
14325     }
14326 
14327 //-----------------------------------------------------------------------------------------------------------------
14328 
14329 POINT txGetConsoleExtent()
14330     {
14331 $1  CONSOLE_SCREEN_BUFFER_INFO con = {};
14332 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14333 
14334 $   POINT  size = { con.srWindow.Right  - con.srWindow.Left + 1,
14335                     con.srWindow.Bottom - con.srWindow.Top  + 1 };
14336 $   return size;
14337     }
14338 
14339 //-----------------------------------------------------------------------------------------------------------------
14340 
14341 bool txClearConsole()
14342     {
14343 $1  HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
14344 
14345 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14346 $   GetConsoleScreenBufferInfo (out, &con) asserted;
14347 
14348 $   COORD start = {con.srWindow.Left, con.srWindow.Top};
14349 
14350 $   DWORD len   = (con.srWindow.Right  - con.srWindow.Left + 1) *
14351                   (con.srWindow.Bottom - con.srWindow.Top  + 1);
14352 
14353 $   DWORD written = 0;
14354 $   FillConsoleOutputCharacter (out, 0x20 /*' '*/,    len, start, &written) asserted;  //-V112
14355 $   FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted;
14356 
14357 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted;
14358 
14359 $   return written == len;
14360     }
14361 
14362 //-----------------------------------------------------------------------------------------------------------------
14363 
14364 POINT txGetConsoleFontSize()
14365     {
14366 $1  Win32::CONSOLE_FONT_INFO font = {0, {8, 16}};
14367 
14368 $   _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font));
14369 
14370 $   SIZE size = { font.dwFontSize.X, font.dwFontSize.Y };
14371     if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); }  //-V501
14372 
14373     if (size.cx == 0) {$ size.cx = 1; }
14374     if (size.cy == 0) {$ size.cy = 1; }
14375 
14376 $   POINT sizeFont = { size.cx, size.cy };
14377 $   return sizeFont;
14378     }
14379 
14380 //-----------------------------------------------------------------------------------------------------------------
14381 
14382 bool txTextCursor (bool blink /*= true*/)
14383     {
14384 $1  bool old = _txConsole_IsBlinking;
14385 
14386 $   _txConsole_IsBlinking = blink;
14387 
14388 $   return old;
14389     }
14390 
14391 //-----------------------------------------------------------------------------------------------------------------
14392 
14393 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/)
14394     {
14395 $1  mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT;
14396 $   if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC;
14397 
14398 $   if (!filename) mode = SND_PURGE;
14399 
14400 $   return !!Win32::PlaySound (filename, NULL, mode);
14401     }
14402 
14403 //-----------------------------------------------------------------------------------------------------------------
14404 
14405 int txSpeak (const char* text, ...)
14406     {
14407 $1  bool verbose = false; (void) verbose;
14408 $   bool async   = false; (void) async;
14409 
14410 $   for (; text && *text; text++)
14411         {
14412         if      (*text == '\a') {$ async   = true; }
14413         else if (*text == '\v') {$ verbose = true; }
14414         else break;
14415         }
14416 
14417 $   char textA [_TX_BUFSIZE] = "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!";
14418 
14419 $   va_list arg; va_start (arg, text);
14420     if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); }
14421 $   va_end (arg);
14422 
14423     if (text && verbose) {$ printf ("%s", textA); }
14424 
14425 #ifdef TX_USE_SPEAK
14426 
14427 $   int time = GetTickCount();
14428 
14429 $   static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L"";
14430 $   MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW));
14431 
14432 $   static ISpVoice* voice = NULL;
14433 
14434 $   if (text && !voice)
14435         {
14436 $       HRESULT res = Win32::CoInitialize (NULL);
14437         if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); }
14438         }
14439 
14440 $   if (text && voice)
14441         {
14442 $       Win32::_fpreset();
14443 $       voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL);
14444 $       tx_fpreset();
14445         }
14446 
14447 $   if (!text && voice)
14448         {
14449 $       voice->Release();
14450 $       voice = NULL;
14451 
14452 $       Win32::CoUninitialize();
14453         }
14454 
14455 $   return (voice)? GetTickCount() - time : -1;
14456 
14457 #else
14458 
14459 $   if (text)
14460         {
14461 $       unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK);
14462 
14463 $       txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA);
14464 
14465 $       txSetConsoleAttr (oldAttr);
14466         }
14467 
14468 $   return -1;
14469 
14470 #endif
14471     }
14472 
14473 //-----------------------------------------------------------------------------------------------------------------
14474 
14475 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
14476                       double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/)
14477     {
14478 $1  if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1;
14479 
14480 $   int time = GetTickCount();  //-V2551
14481 
14482 $   static char processUID [64] = "";
14483     if (!*processUID)
14484         {
14485 $       FILETIME startTime = {}, null = {};
14486 $       GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted;
14487 $       _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo",
14488                     (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted;
14489         }
14490 
14491 $   if (!fileName)
14492         {
14493 $       _txTaskKill ("vlc.exe", processUID, 0);  // Kill'em all, by command line pattern
14494 $       return 0;
14495         }
14496 
14497 $   static const char* vlcPath = _txPlayVideo_FindVLC();
14498 
14499 $   if (!vlcPath || _access (vlcPath, 0) != 0)
14500         {
14501 $       static int once = false;  //-V601
14502 
14503 $       if (*fileName && !once++)
14504             {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org "
14505                                     "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n"
14506                                     "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n"
14507                                     "P.S. См. мое описание в TXLib Help."); }
14508 $       return INT_MIN;  //-V109
14509         }
14510 
14511 $   bool async = false;
14512     if (*fileName == '\a') {$ async = true; fileName++; }
14513 
14514 $   RECT rect = {};
14515     if (wnd) {$ GetClientRect (wnd, &rect); }
14516 
14517     if (!width)  {$ width  = rect.right;  }
14518     if (!height) {$ height = rect.bottom; }
14519 
14520     // Create a child window to hold the video stream
14521 
14522 $   const char* errPos = "ВНЕЗАПНО";
14523 
14524 $   volatile HWND child = NULL;
14525 $   if (wnd && (wnd == txWindow()))
14526         {
14527 $       const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1);
14528 
14529 $       static int number = 1;
14530 $       CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x,
14531                                     WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass };
14532 $       child = txCreateExtraWindow (createData);
14533 $       if (!child)
14534             {
14535 $           txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14536                                        strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos));
14537 $           return INT_MIN+3;  //-V109
14538             }
14539 
14540 $       BringWindowToTop (child);
14541 
14542 $       wnd = child;
14543         }
14544 
14545     // Build the command line
14546 
14547     if (!zoom && !wnd) {$ zoom = 1; }
14548 
14549 $   char sZoom [64] = "--autoscale";
14550     if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; }  //-V550
14551 
14552 $   static char cmd [MAX_PATH*2 + 1024] = "";
14553 
14554 $   _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit"
14555 
14556                  " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s"
14557 
14558                  " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging"
14559 
14560                  " --ignore-config --reset-config --no-one-instance --play-and-exit"
14561                  " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file"
14562                  " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events",
14563 
14564                  vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted;
14565 
14566 $   txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n",
14567                          x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd);
14568 $   if (!*fileName)
14569         {
14570         if (child) {$ txDestroyWindow (child); }
14571 $       return (intptr_t) cmd;
14572         }
14573 
14574 $   if (!strstr (fileName, "://") && _access (fileName, 0) != 0)
14575         {
14576 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14577                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos));
14578 
14579         if (child) {$ txDestroyWindow (child); }
14580 $       return INT_MIN+1;  //-V109
14581         }
14582 
14583     // Run VLC, run
14584 
14585 $   PROCESS_INFORMATION vlc   = {};
14586 $   STARTUPINFO         start = { sizeof (start) };
14587 $   DWORD               ret   = 0;
14588 
14589 $   if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) &&
14590         vlc.hProcess && vlc.hThread)
14591         {
14592 $       if (child)
14593             {
14594 $           assert (wnd == child);                                           //-V547
14595 $           SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess);  //-V107
14596             }
14597 
14598 $       if (!async)
14599             {
14600 $           WaitForSingleObject (vlc.hProcess, INFINITE);
14601 $           GetExitCodeProcess  (vlc.hProcess, &ret) asserted;
14602             }
14603 
14604 $       if (!child)
14605             {
14606 $           CloseHandle (vlc.hProcess) asserted;
14607             }
14608 
14609 $       CloseHandle (vlc.hThread) asserted;
14610 
14611 $       return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret);  //-V105
14612         }
14613     else
14614         {
14615 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s",
14616                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos));
14617 $       if (child)
14618             {$ txDestroyWindow (child); }
14619 
14620 $       return INT_MIN+4;  //-V112 //-V109
14621         }
14622 
14623     #undef PROCESS_UID_
14624     }
14625 
14626 //-----------------------------------------------------------------------------------------------------------------
14627 
14628 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/)
14629     {
14630 $1  return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd);
14631     }
14632 
14633 //-----------------------------------------------------------------------------------------------------------------
14634 
14635 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
14636     {
14637     const UINT_PTR checkTimer = 1;
14638 
14639     switch (msg)
14640         {
14641         case WM_CREATE:
14642             {
14643 $1          SetTimer  (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted;
14644             }
14645             break;
14646 
14647         case WM_DESTROY:
14648             {
14649 $1          KillTimer (wnd, checkTimer) asserted;
14650 
14651 $           HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14652 
14653 $           if (vlc)
14654                 {
14655 $               Win32::TerminateProcess (vlc, 0);
14656 
14657 $               CloseHandle (vlc) asserted;
14658 
14659 $               SetWindowLongPtr (wnd, GWLP_USERDATA, 0);
14660                 }
14661             }
14662             break;
14663 
14664         case WM_TIMER:
14665             {
14666             HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14667 
14668             if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT)
14669                 {
14670 $1              DestroyWindow (wnd) asserted;
14671                 }
14672             }
14673             break;
14674 
14675         default:  //-V2522
14676             break;
14677         }
14678 
14679     return DefWindowProc (wnd, msg, wpar, lpar);
14680     }
14681 
14682 //-----------------------------------------------------------------------------------------------------------------
14683 
14684 const char* _txPlayVideo_FindVLC()
14685     {
14686 $1  static char vlcPath [MAX_PATH] = "";
14687 
14688 $   if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL))
14689         {
14690         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14691         }
14692 
14693 $   if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL))
14694         {
14695         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14696         }
14697 
14698 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath)))
14699         {
14700         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14701         }
14702 
14703 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath)))
14704         {
14705 $       strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX);
14706 
14707         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14708         }
14709 
14710 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files"    "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14711         {
14712         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14713         }
14714 
14715 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14716         {
14717         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14718         }
14719 
14720 $   return NULL;
14721     }
14722 
14723 //-----------------------------------------------------------------------------------------------------------------
14724 
14725 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/)
14726     {
14727 $1  static double oldPercent = 100;
14728 
14729     if (percent < 0) {$ percent    = MIN (oldPercent, 100); }
14730     else             {$ oldPercent = percent;               }
14731 
14732 $   HRESULT res = S_FALSE;
14733 
14734     #if defined (__ITaskbarList3_INTERFACE_DEFINED__)
14735 
14736 $   HRESULT init = Win32::CoInitialize (NULL);
14737 
14738 $   bool ok = true;
14739 $   res = S_OK;
14740 
14741 $   ITaskbarList3* taskbar = NULL;
14742     if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); }
14743 $   ok &= !!taskbar && (res == S_OK);
14744 
14745     if (!wnd)              {$ wnd = txWindow(); }
14746     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14747     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14748 
14749     if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); }
14750     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14751     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14752 
14753     if (taskbar) {$ taskbar->Release(); }
14754 
14755     if (init == S_OK) {$ Win32::CoUninitialize(); }
14756 
14757     #endif
14758 
14759     (void) type; (void) wnd;
14760 
14761 $   return res;
14762     }
14763 
14764 #endif // TX_COMPILED
14765 
14766 //-----------------------------------------------------------------------------------------------------------------
14767 
14768 // +--<<< Это не те символы, что вы ищете :)
14769 // V      Полезно смотреть не только вверх, но и вниз
14770 
14771 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/)
14772     {
14773 $1  WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc;
14774 $   return  old;
14775     }
14776 
14777 //-----------------------------------------------------------------------------------------------------------------
14778 
14779 //     +--<<< А это, наконец, искомое определение этой функции.
14780 //     |      Смотрите по сторонам! Нужная вам функция где-то рядом.
14781 //     |
14782 //     v
14783 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()
14784     {
14785     txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n"
14786 
14787                   "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n"
14788 
14789                   "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. "
14790                   "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n"
14791 
14792                   "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом "
14793                   "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n"
14794 
14795                   "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы "
14796                   "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n",
14797 
14798                   "Не получилось", MB_ICONSTOP);
14799 
14800     // The truth is out there... (C++files)
14801 
14802     return false;
14803     }
14804 
14805 //-----------------------------------------------------------------------------------------------------------------
14806 
14807 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you.
14808 
14809 inline bool txDisableAutoPause()
14810     {
14811     _txExit = true;
14812     return true;
14813     }
14814 
14815 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword.
14816 
14817 //-----------------------------------------------------------------------------------------------------------------
14818 
14819 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14820 
14821 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/)
14822     {
14823 $1  assert (!_txIsBadReadPtr (address));
14824 
14825 $   const unsigned char* addr = (const unsigned char*) address;
14826 
14827 $   const int stdout_fileno = 1;           // Not all g++ packages contain STDOUT_FILENO
14828 $   const int _o_u16text    = 0x00020000;  // and _O_U16TEXT
14829 
14830 $   bool     istty   = _txIsTTY (1);
14831 
14832 $   int      mode    = _O_TEXT;
14833 $   int      oldMode = _setmode (stdout_fileno, mode);
14834 
14835 $   unsigned oldCP   =       GetConsoleOutputCP();
14836 $   unsigned cp      = 1251; SetConsoleOutputCP (cp);  //-V581
14837 
14838 $   unsigned attr    = txGetConsoleAttr();
14839 
14840 $   txSetConsoleAttr (FOREGROUND_WHITE);
14841 $   printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : ""));
14842 
14843 $   txSetConsoleAttr (FOREGROUND_YELLOW);
14844 $   for (unsigned x = 0; x < 16; x++) printf ("%02X ", x);
14845 $   for (unsigned x = 0; x < 16; x++) printf ("%X",    x);
14846 
14847 $   const wchar_t* xlat[33] = {L"\xB7"   /* 00 - NUL - NULL             */, L"\x263A" /* 01 - SOH - Start of header      */,
14848                                L"\x263B" /* 02 - STX - Start of text    */, L"\x2665" /* 03 - ETX - End of text          */,
14849                                L"\x2666" /* 04 - EOT - End of transm.   */, L"\x2663" /* 05 - ENQ - Enquiry              */,
14850                                L"\x2660" /* 06 - ACK - Acknowledgment   */, L"\x2022" /* 07 - BEL - Bell                 */,
14851                                L"\x25D8" /* 08 - BS  - Backspace        */, L"\x25CB" /* 09 - HT  - Horizontal tab       */,
14852                                L"\x25D9" /* 10 - LF  - Line feed        */, L"\x2642" /* 11 - VT  - Vertical tab         */,
14853                                L"\x2640" /* 12 - FF  - Form feed        */, L"\x266A" /* 13 - CR  - Carriage return      */,
14854                                L"\x266B" /* 14 - SO  - Shift out        */, L"\x263C" /* 15 - SI  - Shift in             */,
14855                                L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1     */,
14856                                L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3     */,
14857                                L"\xB6"   /* 20 - DC4 - Device control 4 */, L"\xA7"   /* 21 - NAK - Negative ACK         */,
14858                                L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */,
14859                                L"\x2191" /* 24 - CAN - Cancel           */, L"\x2193" /* 25 - EM  - End of medium        */,
14860                                L"\x2192" /* 26 - SUB - Substitute       */, L"\x2190" /* 27 - ESC - Escape               */,
14861                                L"\x221F" /* 28 - FS  - File separator   */, L"\x2194" /* 29 - GS  - Group separator      */,
14862                                L"\x25B2" /* 30 - RS  - Record separator */, L"\x25BC" /* 31 - US  - Unit separator       */,
14863                                L"\x20"   /* 32 - Space */};
14864 
14865 $   for (int y = 0; y < 16; y++, addr += 16)
14866         {
14867         if (cp   != 1251) SetConsoleOutputCP (cp = 1251);  //-V581
14868         (void)_setmode (stdout_fileno, mode = oldMode);
14869 
14870         txSetConsoleAttr (FOREGROUND_YELLOW);
14871 
14872         printf ("\n" "%*p ", (int) sizeof (address) * 2, addr);
14873 
14874         int color = FOREGROUND_LIGHTGREEN;
14875 
14876         for (unsigned x = 0; x < 16; x++)
14877             {
14878             txSetConsoleAttr (color + x/4%2);  //-V112
14879             printf ("%02X ", addr[x]);
14880             }
14881 
14882         for (unsigned x = 0; x < 16; x++)
14883             {
14884             txSetConsoleAttr (color + x/4%2);  //-V112
14885 
14886             unsigned char ch = addr[x];
14887 
14888             if (ch >= sizearr (xlat) || !istty)
14889                 {
14890                 if (cp   != oldCP)      SetConsoleOutputCP (cp = oldCP);  //-V581
14891                 if (mode != oldMode)    (void)_setmode (stdout_fileno, mode = oldMode);
14892 
14893                 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' ');
14894                 }
14895             else
14896                 {
14897                 if (cp   != 1251)       SetConsoleOutputCP (cp = 1251);   //-V581
14898                 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text);
14899 
14900                 wprintf (L"%lls", xlat[ch]);
14901                 }
14902             }
14903         }
14904 
14905 $   (void)_setmode (stdout_fileno, oldMode);
14906 $   printf ("\n");
14907 
14908 $   if (pause && istty)
14909         {
14910 $       txSetConsoleAttr (FOREGROUND_DARKGRAY);
14911 $       txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP);
14912         }
14913 
14914 $   txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
14915 $   printf ("\n");
14916 
14917 $   txSetConsoleAttr (attr);
14918 $   SetConsoleOutputCP (oldCP);
14919     }
14920 
14921 //-----------------------------------------------------------------------------------------------------------------
14922 
14923 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/,
14924                         bool readSource /*= true*/)
14925     {
14926 $1  unsigned attr = txGetConsoleAttr();
14927 $   txSetConsoleAttr (FOREGROUND_LIGHTCYAN);
14928 
14929 $   fprintf (stderr, "\n" "--------------------------------------------------\n"
14930                           "Трассировка стека из \"%s\" at %s:%d:\n\n"
14931                           "%s\n\n"
14932                           "--------------------------------------------------\n\n",
14933                           func, file, line, _txCaptureStackBackTrace (1, readSource));
14934 
14935 $   txSetConsoleAttr (attr);
14936     }
14937 
14938 //-----------------------------------------------------------------------------------------------------------------
14939 
14940 char* txDemangle (const char* mangledName, std::nomeow_t)
14941     {
14942 $1  if (!mangledName) return NULL;
14943 
14944 $   char* typeName = NULL;
14945 
14946     #if defined (_GCC_VER)
14947 
14948 $   int err = 1;
14949 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err;
14950     if (typeName) {$ return typeName; }
14951 
14952     #endif
14953 
14954 $   unsigned short flags = 0;
14955 
14956 $   if (mangledName[0] == '.')
14957         {
14958 $       mangledName++;
14959 $       flags = 0x2800;  // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY
14960         }
14961 
14962 $   typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags));
14963     if (typeName) {$ return typeName; }
14964 
14965 $   return _strdup (mangledName);
14966     }
14967 
14968 //-----------------------------------------------------------------------------------------------------------------
14969 
14970 std::string txDemangle (const char* mangledName)
14971     {
14972 $1  char* typeName = txDemangle (mangledName, std::nomeow);
14973 $   std::string name (typeName? typeName : "");
14974 $   free (typeName);
14975 
14976 $   return name;
14977     }
14978 
14979 //-----------------------------------------------------------------------------------------------------------------
14980 
14981 double txQueryPerformance()
14982     {
14983 $1  int maxTime    =  500;
14984 $   int maxSamples =  100;
14985 $   POINT size     = {100, 100};
14986 
14987 $   HDC dc = _txBuffer_Create (txWindow(), &size, NULL);
14988 $   assert (dc); if (!dc) return -1;                                     //-V547
14989 
14990 $   DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1);  //-V202
14991 $   assert (mask);
14992 
14993 $   LARGE_INTEGER freq = {};
14994 $   QueryPerformanceFrequency (&freq) asserted;
14995 
14996 $   LARGE_INTEGER start = {};
14997 $   QueryPerformanceCounter (&start) asserted;
14998 
14999 $   int samples = 0;
15000 $   while (samples++ < maxSamples)
15001         {
15002 $       LARGE_INTEGER cur = {};
15003 $       QueryPerformanceCounter (&cur) asserted;
15004 
15005 $       double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart;
15006 $       if (t > maxTime) break;
15007 
15008         // Draw test scene
15009 
15010 $       for (int y = 0; y < size.y; y++)
15011         for (int x = 0; x < size.x; x++)     txSetPixel (x, y, TX_BLACK, dc);
15012 
15013 $       for (int y = 0; y < size.y; y += 10)
15014         for (int x = 0; x < size.x; x += 50) txTextOut  (x, y, "*", dc);
15015 
15016 $       txEllipse (0, 0, size.x, size.y, dc);
15017 $       txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc);
15018 
15019 $       txBitBlt (dc, size.x/2.0,          0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
15020 $       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;
15021 $       txBitBlt (dc,          0, size.y/2.0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
15022 $       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;
15023         }
15024 
15025 $   mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask);  //-V106 //-V202
15026 $   assert (mask);
15027 
15028 $   _txBuffer_Delete (&dc);
15029 
15030 $   return 3.0 * samples / sqrt (1.0 * size.x * size.y);
15031     }
15032 
15033 //-----------------------------------------------------------------------------------------------------------------
15034 
15035 unsigned txExtractColor (COLORREF color, COLORREF component)
15036     {
15037 $1  switch (component)
15038         {
15039         case TX_RED:
15040         case TX_HUE:        $ return (color >>  0) & 0xFF;
15041 
15042         case TX_GREEN:
15043         case TX_SATURATION: $ return (color >>  8) & 0xFF;
15044 
15045         case TX_BLUE:
15046         case TX_LIGHTNESS:  $ return (color >> 16) & 0xFF;
15047 
15048         default:            $ return CLR_INVALID;
15049         }
15050     }
15051 
15052 //-----------------------------------------------------------------------------------------------------------------
15053 
15054 COLORREF txRGB2HSL (COLORREF rgbColor)
15055     {
15056 $1  struct xRGB
15057         {
15058         static bool zero (double val)
15059             {
15060             const double prec = 0.001;
15061 
15062             return (fabs (val) < prec);
15063             }
15064         };
15065 
15066 $   double r  = txExtractColor (rgbColor, TX_RED)   / 255.0,  //-V2551
15067            g  = txExtractColor (rgbColor, TX_GREEN) / 255.0,  //-V2551
15068            b  = txExtractColor (rgbColor, TX_BLUE)  / 255.0,  //-V2551
15069 
15070            m1 = MAX (MAX (r, g), b),
15071            m2 = MIN (MIN (r, g), b),
15072            dm = m1 - m2,
15073            sm = m1 + m2,
15074 
15075            h  = 0,
15076            s  = 0,
15077            l  = sm / 2;
15078 
15079 $   if (!xRGB::zero (dm))
15080         {
15081 $       sm = (sm <= 1)? sm : (2-sm);
15082 $       s = (!xRGB::zero (sm))? dm/sm : 0;
15083 
15084 $       double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0,
15085                cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0,
15086                cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0;
15087 
15088 $       if (xRGB::zero (r - m1)) h =     cb - cg;
15089 $       if (xRGB::zero (g - m1)) h = 2 + cr - cb;
15090 $       if (xRGB::zero (b - m1)) h = 4 + cg - cr;
15091         }
15092 
15093 $   h = (h >= 0)? h*60 : h*60 + 360;
15094 
15095 $   return RGB (ROUND (h / 360.0 * 256), ROUND (s * 255), ROUND (l * 255));
15096     }
15097 
15098 //-----------------------------------------------------------------------------------------------------------------
15099 
15100 COLORREF txHSL2RGB (COLORREF hslColor)
15101     {
15102 $1  struct xRGB
15103         {
15104         static double calc (double h, double m1, double m2)
15105             {
15106 $2          while (h < 0)   h += 360;
15107 $           while (h > 360) h -= 360;
15108 
15109 $           return (h <  60)? m1 + (m2-m1) *      h  / 60 :
15110                    (h < 180)? m2 :
15111                    (h < 240)? m1 + (m2-m1) * (240-h) / 60 :
15112                               m1;
15113             }
15114         };
15115 
15116 $   int    si = txExtractColor (hslColor, TX_SATURATION);
15117 
15118 $   double h  = txExtractColor (hslColor, TX_HUE)        / 256.0 * 360,
15119            s  = txExtractColor (hslColor, TX_SATURATION) / 255.0,
15120            l  = txExtractColor (hslColor, TX_LIGHTNESS)  / 255.0,
15121 
15122            m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s,
15123            m1 = 2 * l - m2,
15124 
15125            r = (si)? xRGB::calc (h + 120, m1, m2) : l,
15126            g = (si)? xRGB::calc (h,       m1, m2) : l,
15127            b = (si)? xRGB::calc (h - 120, m1, m2) : l;
15128 
15129 $   return RGB (ROUND (r * 255), ROUND (g * 255), ROUND (b * 255));
15130     }
15131 
15132 //-----------------------------------------------------------------------------------------------------------------
15133 
15134 void tx_fpreset()
15135     {
15136 $1  txAutoLock _lock;
15137 
15138 $   Win32::_fpreset();
15139 
15140 $   unsigned new87 = 0x0008001C;  // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW
15141 
15142     #if !defined (__CYGWIN__)
15143 
15144 $   unsigned old87 = 0;
15145 $   if (_controlfp_s (&old87, 0, 0) == 0)
15146         {$ (void) _controlfp_s (&old87, old87  & ~new87, 0x0008001F); }  // _MCW_EM
15147 
15148     #else
15149 
15150 $   Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F);    // _MCW_EM
15151 
15152     #endif
15153     }
15154 
15155 #endif // TX_COMPILED
15156 
15157 //-----------------------------------------------------------------------------------------------------------------
15158 
15159 #if defined (_TX_CPP11)
15160 template <int txFramesToAverage>
15161 #endif
15162 
15163 double txGetFPS (int minFrames)
15164     {
15165 $1  static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0);
15166 $                     LARGE_INTEGER time  = {};                      QueryPerformanceCounter (&time);
15167 
15168 $   if (time.QuadPart - time0.QuadPart == 0)
15169         {$ return 0; }
15170 
15171 $   LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq);
15172 
15173 $   double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart);
15174 $   time0 = time;
15175 
15176 $   if (txFramesToAverage == 0) return fps;
15177 
15178 $   static _tx_thread double average [txFramesToAverage] = {};
15179 $   static _tx_thread unsigned n = 0;
15180 
15181 $   average [n++ % txFramesToAverage] = fps;
15182 
15183 $   unsigned nn = MIN (n, (unsigned) sizearr (average));
15184 
15185 $   fps = 0;
15186 $   for (unsigned i = 0; i < nn; i++) fps += average[i];
15187 $   fps /= nn;
15188 
15189 $   return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0;
15190     }
15191 
15192 //-----------------------------------------------------------------------------------------------------------------
15193 
15194 template <typename T>
15195 inline T zero() { T __zero = {}; return __zero; }
15196 
15197 //-----------------------------------------------------------------------------------------------------------------
15198 
15199 inline double random (std::nomeow_t, double left, double right)
15200     {
15201     return left + (right - left) * ((double) rand() / RAND_MAX);
15202     }
15203 
15204 //-----------------------------------------------------------------------------------------------------------------
15205 
15206 template <typename Tx, typename Ta, typename Tb>
15207 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b)
15208     {
15209     return a <= x && x <= b;
15210     }
15211 
15212 //-----------------------------------------------------------------------------------------------------------------
15213 
15214 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)
15215     {
15216     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15217     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15218 
15219     return In (std::nomeow, pt.x, rect.left, rect.right) &&
15220            In (std::nomeow, pt.y, rect.top,  rect.bottom);
15221     }
15222 
15223 //-----------------------------------------------------------------------------------------------------------------
15224 
15225 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect)
15226     {
15227     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15228     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15229 
15230     return In (std::nomeow, pt.X, rect.Left, rect.Right) &&
15231            In (std::nomeow, pt.Y, rect.Top,  rect.Bottom);
15232     }
15233 
15234 //-----------------------------------------------------------------------------------------------------------------
15235 
15236 inline int random (int range)
15237     {
15238     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15239 
15240     return rand() % range;
15241     }
15242 
15243 //-----------------------------------------------------------------------------------------------------------------
15244 
15245 inline double random (double left, double right)
15246     {
15247     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15248 
15249     return random (std::nomeow, left, right);
15250     }
15251 
15252 //-----------------------------------------------------------------------------------------------------------------
15253 
15254 template <typename Tx, typename Ta, typename Tb>
15255 inline bool In (Tx x, Ta a, Tb b)
15256     {
15257     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15258 
15259     return In (std::nomeow, x, a, b);
15260     }
15261 
15262 //-----------------------------------------------------------------------------------------------------------------
15263 
15264 inline bool In (const POINT& pt, const RECT& rect)
15265     {
15266     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15267 
15268     return In (std::nomeow, pt, rect);
15269     }
15270 
15271 //-----------------------------------------------------------------------------------------------------------------
15272 
15273 inline bool In (const COORD& pt, const SMALL_RECT& rect)
15274     {
15275     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15276 
15277     return In (std::nomeow, pt, rect);
15278     }
15279 
15280 //}
15281 //=================================================================================================================
15282 
15283 //=================================================================================================================
15284 //{          txPrintf() implementation
15285 //           Реализация txPrintf()
15286 //=================================================================================================================
15287 
15288 #if defined (_TX_CPP11)
15289 
15290 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt,                                  const T& arg, ArgsT... args);
15291 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);
15292 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);
15293 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);
15294                                          void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15295 
15296 template <typename T>                    void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg);
15297                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int*     arg);
15298                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15299 
15300 //-----------------------------------------------------------------------------------------------------------------
15301 
15302 template <typename T, typename... ArgsT>
15303 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args)
15304     {
15305 $1  assert (fmt);
15306 
15307 $   _txPrintV (stream, format, n,   fmt);
15308 
15309     if (fmt[0] == '%') {$}
15310     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15311 
15312 $   _txPrintV (stream, format, n,   fmt, arg);
15313 
15314 $   _txPrintF (stream, format, n+1, fmt, args...);
15315     }
15316 
15317 //-----------------------------------------------------------------------------------------------------------------
15318 
15319 template <typename T, typename... ArgsT>
15320 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args)
15321     {
15322 $1  assert (&stream);
15323 $   assert (fmt);
15324 
15325 $   _txPrintV (stream, format, n,   fmt);
15326 
15327     if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); }  //-V2006
15328     else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); }
15329 
15330 $   _txPrintV (stream, format, n,   fmt, arg);
15331 
15332 $   _txPrintF (stream, format, n+1, fmt, args...);
15333     }
15334 
15335 //-----------------------------------------------------------------------------------------------------------------
15336 
15337 template <typename T, typename... ArgsT>
15338 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args)
15339     {
15340 $1  assert (&stream);
15341 $   assert (fmt);
15342 
15343 $   _txPrintV (stream, format, n,   fmt);
15344 
15345     if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((std::streamsize) (prec + 1)); }  //-V2006 //-V1028
15346     else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); }
15347 
15348 $   _txPrintV (stream, format, n,   fmt, arg);
15349 
15350 $   _txPrintF (stream, format, n+1, fmt, args...);
15351     }
15352 
15353 //-----------------------------------------------------------------------------------------------------------------
15354 
15355 template <typename T, typename... ArgsT>
15356 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args)
15357     {
15358 $1  assert (&stream);
15359 $   assert (fmt);
15360 
15361 $   _txPrintV (stream, format, n,   fmt);
15362 
15363     if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((std::streamsize) (prec + 1)); }  //-V2006 //-V1028
15364     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); }
15365 
15366 $   _txPrintV (stream, format, n,   fmt, arg);
15367 
15368 $   _txPrintF (stream, format, n+1, fmt, args...);
15369     }
15370 
15371 //-----------------------------------------------------------------------------------------------------------------
15372 
15373 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt)
15374     {
15375 $1  assert (fmt);
15376 
15377 $   _txPrintV (stream, format, n,   fmt);
15378 
15379     if (!fmt[0]) {$}
15380     else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); }
15381     }
15382 
15383 //-----------------------------------------------------------------------------------------------------------------
15384 
15385 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt)
15386     {
15387 $1  assert (&stream);
15388 $   assert (fmt);
15389 
15390 $   while (*fmt)
15391         {
15392         if (fmt[0] == '%')
15393             {
15394             if (fmt[1] == '%') fmt++;
15395             else break;
15396             }
15397 
15398         stream << *fmt++;
15399         }
15400 $   }
15401 
15402 //-----------------------------------------------------------------------------------------------------------------
15403 
15404 template <typename T>
15405 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg)
15406     {
15407 $1  assert (&stream);
15408 $   assert (fmt);
15409 
15410 $   if (_TX_ARGUMENT_FAILED (&arg)) return;
15411 
15412     if (fmt[0] == '%') {$}
15413     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15414 
15415 $   fmt++;
15416 
15417 $   char                    oldFill  = stream.fill (' ');
15418 $   std::ios_base::fmtflags oldFlags = stream.flags();
15419 
15420 $   for (;;) switch (*fmt)
15421         {
15422         case '-': $ stream << std::left;     fmt++; break;
15423         case '+': $ stream << std::showpos;  fmt++; break;
15424         case ' ': $ stream.fill (' ');       fmt++; break;
15425         case '#': $ stream << std::showbase; fmt++; break;
15426         case '0': $ stream.fill ('0');       fmt++; break;
15427 
15428         default:  $ goto end;
15429         }
15430     end:
15431 
15432 $   int width = (*fmt != '*')?                  (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0);
15433 $   int prec  = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0;
15434 
15435     if (width) {$ stream << std::setw (width);        }
15436     if (prec)  {$ stream << std::setprecision (prec); }
15437 
15438 $   fmt += strspn (fmt, "hljztL");
15439 
15440 $   switch (*fmt)
15441         {
15442         case '$':
15443         case '?': $                                              break;
15444 
15445         case 'd':
15446         case 'i':
15447         case 'u': $ stream << std::dec;                          break;
15448 
15449         case 'o': $ stream << std::oct;                          break;
15450 
15451         case 'x': $ stream << std::hex;                          break;
15452         case 'X': $ stream << std::hex        << std::uppercase; break;
15453 
15454         case 'f': $ stream << std::fixed;                        break;
15455         case 'F': $ stream << std::fixed      << std::uppercase; break;
15456 
15457         case 'e': $ stream << std::scientific;                   break;
15458         case 'E': $ stream << std::scientific << std::uppercase; break;
15459 
15460         case 'g': $                                              break;
15461         case 'G': $ stream                    << std::uppercase; break;
15462 
15463         case 'a': $                                              break;
15464         case 'A': $ stream                    << std::uppercase; break;
15465 
15466         case 'c':
15467         case 's':
15468         case 'p': $                                              break;
15469 
15470         default:  $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break;
15471         }
15472 
15473 $   fmt++;
15474 
15475     if (&arg) {$ stream << arg;      }
15476     else      {$ stream << "(null)"; }
15477 
15478 $   stream.fill  (oldFill);
15479 $   stream.flags (oldFlags);
15480     }
15481 
15482 //-----------------------------------------------------------------------------------------------------------------
15483 
15484 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg)  //-V2009
15485     {
15486 $1  assert (fmt);
15487 
15488     if (_TX_ARGUMENT_FAILED (arg)) return;
15489 
15490     if (fmt[0] == '%' && fmt[1] == 'n') {$}
15491     else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); }
15492 
15493 $   *arg = (int) stream.str().length();  //-V202
15494 
15495 $   fmt += 2;
15496     }
15497 
15498 //-----------------------------------------------------------------------------------------------------------------
15499 
15500 template <typename T> inline const T&    _txPrintfNormalizeArg (const T&           arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;}          return arg;         }
15501                       inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); }
15502 
15503 //-----------------------------------------------------------------------------------------------------------------
15504 
15505 template <typename... ArgsT>
15506 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args)
15507     {
15508 $1  if (_TX_ARGUMENT_FAILED (&stream)) return 0;
15509 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15510 
15511 $   const char* fmt = format;
15512 $   _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...);
15513 
15514 $   return (int) stream.str().length();  //-V202
15515     }
15516 
15517 //-----------------------------------------------------------------------------------------------------------------
15518 
15519 template <typename... ArgsT>
15520 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args)
15521     {
15522 $1  if (_TX_ARGUMENT_FAILED (&buffer)) return 0;
15523 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15524 
15525 $   if (size > 0) size--;
15526 $   buffer[size] = 0;
15527 
15528 $   if (!size) return 0;
15529 
15530 $   std::ostringstream stream;
15531 $   stream.rdbuf() -> pubsetbuf (buffer, size);
15532 
15533 $   txPrintf (stream, format, args...);
15534 
15535 $   return (int) stream.str().length();  //-V202
15536     }
15537 
15538 //-----------------------------------------------------------------------------------------------------------------
15539 
15540 template <typename... ArgsT>
15541 inline std::string txFormat (const char* format, ArgsT... args)
15542     {
15543 $1  if (_TX_ARGUMENT_FAILED (&format)) return "";
15544 
15545 $   std::ostringstream stream;
15546 
15547 $   txPrintf (stream, format, args...);
15548 
15549 $   return stream.str();
15550     }
15551 
15552 //-----------------------------------------------------------------------------------------------------------------
15553 
15554 template <typename... ArgsT>
15555 inline int txPrintf (const char* format, ArgsT... args)
15556     {
15557 $1  if (_TX_ARGUMENT_FAILED (&format)) return 0;
15558 
15559 $   return printf ("%s", txFormat (format, args...) .c_str());
15560     }
15561 
15562 #endif
15563 
15564 //-----------------------------------------------------------------------------------------------------------------
15565 
15566        int _txPrintfCheck (const char* format, ...) tx_printfy (1);
15567 inline int _txPrintfCheck (const char*,        ...) { return 0; }
15568 
15569 //}
15570 //=================================================================================================================
15571 
15572 //=================================================================================================================
15573 //{          txDialog methods implementation
15574 //           Реализация методов класса txDialog
15575 //
15576 //           See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx
15577 //               [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743
15578 //               [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753
15579 //=================================================================================================================
15580 
15581 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
15582 
15583 txDialog::txDialog () :
15584     layout_ (NULL)
15585     {$1}
15586 
15587 //-----------------------------------------------------------------------------------------------------------------
15588 
15589 txDialog::txDialog (const Layout* layout) :
15590     layout_ (layout)
15591     {$1}
15592 
15593 //-----------------------------------------------------------------------------------------------------------------
15594 
15595 const txDialog::Layout* txDialog::setLayout (const Layout* layout)
15596     {
15597 $1  assert (layout);
15598 
15599 $   return ::std::swap (layout_, layout), layout;
15600     }
15601 
15602 //-----------------------------------------------------------------------------------------------------------------
15603 
15604 intptr_t txDialog::dialogBox (WORD resourceID)
15605     {
15606 $1  const char* resName = (char*)(uintptr_t) resourceID;
15607 
15608 $   if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0;
15609 
15610 $   return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15611     }
15612 
15613 //-----------------------------------------------------------------------------------------------------------------
15614 
15615 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/)
15616     {
15617 $1  if (!layout)  layout = layout_;
15618 $   if (!layout)  return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0;
15619 
15620 $   if (!bufsize) bufsize = 1024;
15621 
15622 $   DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize);
15623 $   if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0;
15624 
15625 $   const Layout* dlg = &layout[0];
15626 $   const Layout  def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 };
15627 
15628 $   void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize,
15629                                        (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0,
15630                                         dlg->x, dlg->y, dlg->sx, dlg->sy,
15631                                         dlg->caption?  dlg->caption  : def.caption,
15632                                         dlg->font?     dlg->font     : def.font,
15633                                         dlg->fontsize? dlg->fontsize : def.fontsize, NULL);
15634 $   WORD i = 0;
15635 $   for (i = 1; layout[i].wndclass != END; ++i)
15636         {
15637 $       const Layout* item = &layout[i];
15638 
15639 $       ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl),
15640                                    item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy,
15641                                    item->id, (const char*)(uintptr_t) item->wndclass, item->caption);
15642         }
15643 
15644 $   tmpl->cdit = (unsigned short) (i-1);
15645 
15646 $   intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15647 
15648 $   GlobalFree (tmpl);
15649 
15650 $   return res;
15651     }
15652 
15653 //-----------------------------------------------------------------------------------------------------------------
15654 
15655 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM)
15656     {
15657 $1  switch (msg)
15658         {
15659         case WM_INITDIALOG: $ SetForegroundWindow (wnd);
15660                             $ break;
15661 
15662         case WM_COMMAND:    $ switch (LOWORD (wParam))
15663             {
15664             case IDOK:
15665             case IDCANCEL:  $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow());
15666                             $ EndDialog (wnd, (uintptr_t) this);
15667                             $ break;
15668 
15669             default:        $ break;
15670             }
15671                             $ break;
15672         default:            $ break;
15673         }
15674 
15675 $   return FALSE;
15676     }
15677 
15678 //-----------------------------------------------------------------------------------------------------------------
15679 
15680 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
15681     {
15682 $1  static txDialog* this__ = NULL;
15683 $   if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam;
15684 $   if (!this__) return FALSE;
15685 
15686 $   return this__-> dialogProc (wnd, msg, wParam, lParam);  //-V109
15687     }
15688 
15689 //-----------------------------------------------------------------------------------------------------------------
15690 
15691 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
15692                               WORD controls, short x, short y, short cx, short cy,
15693                               const char caption[], const char font[], WORD fontsize, const char menu[])
15694     {
15695 $1  if (_TX_ARGUMENT_FAILED (globalMem)) return NULL;
15696 
15697 $   WORD* pw = (WORD*) globalMem;
15698 
15699 $   DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++;
15700 
15701 $   tmpl->style = style;
15702 $   tmpl->dwExtendedStyle = exStyle;
15703 $   tmpl->cdit  = controls;
15704 $   tmpl->x     = x;
15705 $   tmpl->y     = y;
15706 $   tmpl->cx    = cx;
15707 $   tmpl->cy    = cy;
15708 
15709 $   if (menu > (const char*) 0xFFFF)
15710         {
15711 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (menu?    menu    : ""), -1, (wchar_t*) pw,           //-V547
15712                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15713         }
15714     else
15715         {
15716 $       *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0);
15717 $       *pw++ = (WORD)(uintptr_t)  menu;
15718         }
15719 
15720 $   if (caption)
15721         {
15722 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw,           //-V547
15723                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15724         }
15725 
15726 $   if (style & DS_SETFONT)
15727         {
15728 $       *pw++ = fontsize;
15729 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, (font?    font    : ""), -1, (wchar_t*) pw,
15730                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
15731         }
15732 
15733 $   return pw;
15734     }
15735 
15736 //-----------------------------------------------------------------------------------------------------------------
15737 
15738 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
15739                            short x, short y, short cx, short cy,
15740                            WORD id, const char wclass[], const char caption[])
15741     {
15742 $1  if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL;
15743 
15744 $   WORD* pw = (LPWORD) dlgTemplatePtr;  // Force align at word boundary
15745 $   ((ULONG&) pw)  += 3;  //-V205
15746 $   ((ULONG&) pw) >>= 2;  //-V205
15747 $   ((ULONG&) pw) <<= 2;  //-V205
15748 
15749 $   DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++;
15750 
15751 $   tmpl->style = style;
15752 $   tmpl->dwExtendedStyle = exStyle;
15753 $   tmpl->x     = x;
15754 $   tmpl->y     = y;
15755 $   tmpl->cx    = cx;
15756 $   tmpl->cy    = cy;
15757 $   tmpl->id    = id;
15758 
15759 $   if (HIWORD (wclass) == 0xFFFF)
15760         {
15761 $       *pw++ = (WORD) (HIWORD ((uintptr_t) wclass));
15762 $       *pw++ = (WORD) (LOWORD ((uintptr_t) wclass));
15763         }
15764     else if (wclass)
15765         {
15766 $       pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw,
15767                                    (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));   //-V202
15768         }
15769     else
15770         {
15771 $       *pw++ = 0;
15772         }
15773 
15774 $   if (caption)
15775          {
15776 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw,
15777                                     (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));  //-V202
15778          }
15779     else
15780         {
15781 $       *pw++ = 0;
15782         }
15783 
15784 $   *pw++ = 0;
15785 
15786 $   return pw;
15787     }
15788 
15789 #endif // TX_COMPILED
15790 
15791 //}
15792 //=================================================================================================================
15793 
15794 //=================================================================================================================
15795 //{          Cleaning up the utility macros
15796 //           Очистка служебных макросов
15797 //=================================================================================================================
15798 
15799 #undef       $
15800 #undef       $0
15801 #undef       $1
15802 #undef       $2
15803 #undef       $3
15804 #undef       $4
15805 #undef       $5
15806 #undef       $6
15807 #undef       $7
15808 #undef       $8
15809 #undef       $9
15810 #undef       $$
15811 
15812 //}
15813 //=================================================================================================================
15814 
15816 
15817 //=================================================================================================================
15818 //{          Experimental Debugging macros
15820 //=================================================================================================================
15821 
15822 //{----------------------------------------------------------------------------------------------------------------
15942 //}----------------------------------------------------------------------------------------------------------------
15943 
15944 #ifndef __TX_DEBUG_MACROS
15945 #define __TX_DEBUG_MACROS  ("Группа отладочных $-макросов")
15946 
15948 //-----------------------------------------------------------------------------------------------------------------
15949 
15950 #define $H            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_BLACK);
15951 #define $B            txSetConsoleAttr (FOREGROUND_BLUE         | BACKGROUND_BLACK);
15952 #define $G            txSetConsoleAttr (FOREGROUND_GREEN        | BACKGROUND_BLACK);
15953 #define $C            txSetConsoleAttr (FOREGROUND_CYAN         | BACKGROUND_BLACK);
15954 #define $R            txSetConsoleAttr (FOREGROUND_RED          | BACKGROUND_BLACK);
15955 #define $M            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_BLACK);
15956 #define $Y            txSetConsoleAttr (FOREGROUND_DARKYELLOW   | BACKGROUND_BLACK);
15957 #define $d            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_BLACK);
15958 #define $D            txSetConsoleAttr (FOREGROUND_DARKGRAY     | BACKGROUND_BLACK);
15959 #define $b            txSetConsoleAttr (FOREGROUND_LIGHTBLUE    | BACKGROUND_BLACK);
15960 #define $g            txSetConsoleAttr (FOREGROUND_LIGHTGREEN   | BACKGROUND_BLACK);
15961 #define $c            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLACK);
15962 #define $r            txSetConsoleAttr (FOREGROUND_LIGHTRED     | BACKGROUND_BLACK);
15963 #define $m            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK);
15964 #define $y            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLACK);
15965 #define $h            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_BLACK);
15966 
15967 #define $i            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLUE);
15968 #define $I            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLUE);
15969 #define $o            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_GREEN);
15970 #define $O            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_GREEN);
15971 #define $e            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_RED);
15972 #define $E            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_RED);
15973 #define $w            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA);
15974 #define $W            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_MAGENTA);
15975 #define $f            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_LIGHTRED);
15976 #define $F            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_LIGHTRED);
15977 #define $l            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_DARKGRAY);
15978 #define $L            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_DARKGRAY);
15979 
15980 #define $T( cond )    txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED );
15981 
15982 #define $s            _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__);
15983 
15984 #define $sH           $s $H
15985 #define $sB           $s $B
15986 #define $sG           $s $G
15987 #define $sC           $s $C
15988 #define $sR           $s $R
15989 #define $sM           $s $M
15990 #define $sY           $s $Y
15991 #define $sd           $s $d
15992 #define $sD           $s $D
15993 #define $sb           $s $b
15994 #define $sg           $s $g
15995 #define $sc           $s $c
15996 #define $sr           $s $r
15997 #define $sm           $s $m
15998 #define $sy           $s $y
15999 #define $sh           $s $h
16000 
16001 #define $si           $s $i
16002 #define $sI           $s $I
16003 #define $so           $s $o
16004 #define $sO           $s $O
16005 #define $se           $s $e
16006 #define $sE           $s $E
16007 #define $sw           $s $w
16008 #define $sW           $s $W
16009 #define $sf           $s $f
16010 #define $sF           $s $F
16011 #define $sl           $s $l
16012 #define $sL           $s $L
16013 
16014 #define $sT( cond )   $s $T (cond)
16015 
16016 #define $test(cond)   { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \
16017                         else          { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; }
16018 
16019 #define $status(cond) $test (cond)
16020 
16021 #define $unittest( code, expected )                                                                                             \
16022     {                                                                                                                           \
16023     const _tx_decltype (code)     & _result   = (code);       /* Should use auto, but g++ 4.7.2 default std is < 2011 */        \
16024     const _tx_decltype (expected) & _expected = (expected);                                                                     \
16025                                                                                                                                 \
16026     if (_result == _expected)                                                                                                   \
16027         { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; }                                                            \
16028     else                                                                                                                        \
16029         { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \
16030                                                                                                                                 \
16031     $n;                                                                                                                         \
16032     (_result == _expected);                                                                                                     \
16033     }
16034 
16035 //=================================================================================================================
16036 
16037 #define $V(  var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]\n") )
16038 #define $V_( var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "] " ) )
16039 #define $V__(var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]"  ) )
16040 
16041 #define $(   var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n") )
16042 #define $_(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] " ) )
16043 #define $__( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]"  ) )
16044 
16045 #define $x(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) )
16046 #define $x_( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] ",  ::std::ios_base::showbase | ::std::ios_base::hex) )
16047 
16048 #define $v(  var, cond, ...)  { { $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" ); } $n; }
16049 #define $v_( var, cond, ...)  {   $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" );       }
16050 
16051 #define $$                    { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__);                                   } txOutputDebugPrintf ("\f\n"); }
16052 #define $$_                   { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]",           __LINE__, __func__);                                          } txOutputDebugPrintf ("\f\n"); }
16053 #define $meow(...)            { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); }
16054 
16055 #define $$$(   ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
16056 #define $$$_(  ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),  "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
16057 
16058 #define $$$$(  ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
16059 #define $$$$_( ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         (  "[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
16060 #define $do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n";                                                                                           __VA_ARGS__
16061 #define $DO(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p;                                                                                    __VA_ARGS__
16062 #define $Do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n";                                                                                        \
16063                                 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__);                                                                      __VA_ARGS__
16064 
16065 #define $n                    { ::std::cerr << "\n";   }
16066 #define $nn                   { ::std::cerr << "\n\n"; }
16067 #define $t                    { ::std::cerr << "\t";   }
16068 
16069 #define _tx$PrefixV(    ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": "          ) : ("["          ) )
16070 #define _tx$Prefix(var, ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") )
16071 
16072 //-----------------------------------------------------------------------------------------------------------------
16073 
16074 // This will never be documented, he-he. Read the source, Luke.
16075 
16076 #if defined (_DEBUG)
16077     #define $dbg               if (1)
16078     #define $DBG               if (1)
16079     #define $debug             if (1)
16080     #define $DEBUG             if (1)
16081     #define $printf(fmt, ...)  if (1)  printf (        fmt, ##__VA_ARGS__)
16082     #define $PRINTF(fmt, ...)  if (1) fprintf (stderr, fmt, ##__VA_ARGS__)
16083 #else
16084     #define $dbg               if (0)
16085     #define $DBG               if (0)
16086     #define $debug             if (0)
16087     #define $DEBUG             if (0)
16088     #define $printf(...)       if (0)  printf (        fmt, ##__VA_ARGS__)
16089     #define $PRINTF(...)       if (0) fprintf (stderr, fmt, ##__VA_ARGS__)
16090 #endif
16091 
16092 #define $$d    $debug
16093 #define $$w    $$$$
16094 #define $$s    __TX_FILELINE__
16095 #define $$b    { txSleep(); DebugBreak(); }
16096 #define $$p    { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \
16097                                                     __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); }
16098 #define $$P    (     txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) )
16099 #define $ppp   { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); }
16100 #define $pp    { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__,        __TX_FUNCTION__); }
16101 #define $p     { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__);        }
16102 #define $ppp_  { $sy; txPause ("\v[%s ""%s]...",                    __TX_FILELINE__, __TX_FUNCTION__); }
16103 #define $pp_   { $sy; txPause ("\v[%04d %s]...",                    __LINE__,        __TX_FUNCTION__); }
16104 #define $p_    { $sy; txPause ("\v[%s ""%s()]...",                  __TX_FILELINE__, __func__);        }
16105 #define $P     ( txPause ("") )
16106 
16107 //-----------------------------------------------------------------------------------------------------------------
16108 
16109 struct _txSaveConsoleAttr
16110     {
16111     unsigned attr_;
16112 
16113              _txSaveConsoleAttr()           : attr_ (txGetConsoleAttr ()) {}
16114     explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr);  }
16115             ~_txSaveConsoleAttr()                                         { txSetConsoleAttr (attr_); }
16116     };
16117 
16118 //-----------------------------------------------------------------------------------------------------------------
16119 
16120 struct _txDumpVarSuffix
16121     {
16122     typedef _txDumpVarSuffix this_t;
16123 
16124     const char* suffix_;
16125 
16126     explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); }
16127             ~_txDumpVarSuffix()                          { ::std::cerr << suffix_; }
16128 
16129             _txDumpVarSuffix (const this_t&) _tx_delete;
16130     this_t& operator =       (const this_t&) _tx_delete;
16131     };
16132 
16133 //-----------------------------------------------------------------------------------------------------------------
16134 
16135 #define ARGS__        const char* prefix, const char* suffix, std::ios_base::fmtflags flags,                             int deep
16136 #define ARGS_         const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0
16137 #define VALS_         prefix, suffix, flags, deep
16138 #define ERRPTR_(p)  { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; }
16139 
16140 template <typename T, typename StreamT> const T&    _txDumpVal (const T& value, StreamT& stream, ARGS_);
16141 
16142 //-----------------------------------------------------------------------------------------------------------------
16143 
16144 template <typename T> inline const T&               _txDumpVar (const T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16145 template <typename T> inline       T&               _txDumpVar (      T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16146 
16147 template <int N>      inline const char           (&_txDumpVar (const char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16148 template <int N>      inline       char           (&_txDumpVar (      char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16149 
16150 template <int N>      inline const wchar_t        (&_txDumpVar (const wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16151 template <int N>      inline       wchar_t        (&_txDumpVar (      wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16152 
16153                       inline const wchar_t&         _txDumpVar (const wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16154                       inline       wchar_t&         _txDumpVar (      wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16155 
16156                       inline const wchar_t*&        _txDumpVar (const wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16157                       inline       wchar_t*&        _txDumpVar (      wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16158 
16159                       inline const std::wstring&    _txDumpVar (const std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16160                       inline       std::wstring&    _txDumpVar (      std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16161 
16162 //-----------------------------------------------------------------------------------------------------------------
16163 
16164 template <typename T, typename StreamT> inline void _txDumpVal (const T&            value, StreamT& stream) { stream <<         value;         }
16165 template             <typename StreamT> inline void _txDumpVal (const char          value, StreamT& stream) { stream <<  "'" << value <<  "'"; }
16166 template             <typename StreamT> inline void _txDumpVal (const wchar_t       value, StreamT& stream) { stream << L"'" << value << L"'"; }
16167 template             <typename StreamT> inline void _txDumpVal (const std::string&  value, StreamT& stream) { stream <<  '"' << value <<  '"'; }
16168 template             <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; }
16169 
16170 template             <typename StreamT> inline void _txDumpVal (const char*         value, StreamT& stream)
16171     {
16172     if (_TX_ARGUMENT_FAILED (&stream)) return;
16173 
16174     if (!_txIsBadReadPtr (value)) stream <<  '"' << value <<  '"';
16175     else if (!value)              stream <<  "(null)";
16176     else                          ERRPTR_ (value);
16177     }
16178 
16179 template             <typename StreamT> inline void _txDumpVal (const wchar_t*      value, StreamT& stream)
16180     {
16181     if (_TX_ARGUMENT_FAILED (&stream)) return;
16182 
16183     if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"';
16184     else if (!value)              stream << L"(null)";
16185     else                          ERRPTR_ (value);
16186     }
16187 
16188 //-----------------------------------------------------------------------------------------------------------------
16189 
16190 template <typename T, typename StreamT>
16191 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__)
16192     {
16193     if (_TX_ARGUMENT_FAILED (&stream)) return value;  //-V778
16194     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16195     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16196 
16197     $sc;
16198     if (!deep) stream << prefix;
16199 
16200     std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags());
16201 
16202     if (!_txIsBadReadPtr (&value))
16203         {
16204         _txDumpVal (value, stream);
16205         }
16206     else
16207         ERRPTR_ (&value);
16208 
16209     stream.flags (old);
16210 
16211     if (!deep) stream << suffix;
16212 
16213     return value;
16214     }
16215 
16216 //-----------------------------------------------------------------------------------------------------------------
16217 
16218 template <typename T, int N>
16219 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N]
16220     {
16221     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16222     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16223 
16224     std::ostream& stream = std::cerr;
16225 
16226     $sc; if (!deep) std::cerr << prefix;
16227     $C;  std::cerr << ((deep)? " {" : "{");
16228 
16229     if (!_txIsBadReadPtr (value))
16230         {
16231         for (int i = 0; ; i++)
16232             {
16233             { $sC; stream << "[" << i << "]="; }
16234 
16235             _txDumpVar (value[i], prefix, suffix, flags, deep+1);
16236 
16237             if (i >= N-1) break;
16238 
16239             stream << ", ";
16240             }
16241         }
16242     else
16243         ERRPTR_ (&value);
16244 
16245     $C; std::cerr << "}";
16246     $c; if (!deep) std::cerr << suffix;
16247 
16248     return value;
16249     }
16250 
16251 //=================================================================================================================
16252 
16253 inline std::ostream& operator << (std::ostream& stream, const POINT& point)
16254     {
16255     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16256 
16257     if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }";           // NOLINT (clang-diagnostic-undefined-bool-conversion)
16258     else if (!&point)              stream << "(null)";
16259     else ERRPTR_ (&point);
16260 
16261     return stream;
16262     }
16263 
16264 inline std::ostream& operator << (std::ostream& stream, const SIZE& size)
16265     {
16266     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16267 
16268     if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }";          // NOLINT (clang-diagnostic-undefined-bool-conversion)
16269     else       stream << "(null)";
16270 
16271     return stream;
16272     }
16273 
16274 inline std::ostream& operator << (std::ostream& stream, const RECT& rect)
16275     {
16276     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16277 
16278     if (&rect) stream << "{ left: "  << rect.left  << ", top: "    << rect.top    <<  // NOLINT (clang-diagnostic-undefined-bool-conversion)
16279                          ", right: " << rect.right << ", bottom: " << rect.bottom << " }";
16280 
16281     else       stream << "(null)";
16282 
16283     return stream;
16284     }
16285 
16286 //-----------------------------------------------------------------------------------------------------------------
16287 
16288 #undef ARGS__
16289 #undef ARGS_
16290 #undef VALS_
16291 #undef ERRPTR_
16292 
16293 //-----------------------------------------------------------------------------------------------------------------
16295 
16296 #endif
16297 
16298 //}
16299 //=================================================================================================================
16300 
16302 
16303 //=================================================================================================================
16304 //{          TXAPI calls tracing
16305 //           Трассировка вызовов TXAPI
16306 //=================================================================================================================
16307 
16308 #ifndef   FOR_DOXYGEN_ONLY
16309 
16310 #if defined (_MSC_VER)
16311 #undef  _txLocCurSet
16312 #define _txLocCurSet()                 __txLocCurSet (__FILE__, __LINE__, NULL)
16313 #endif
16314 
16315 #define txAlphaBlend(...)              ( _txLocCurSet(), txAlphaBlend          (__VA_ARGS__) )
16316 #define txArc(...)                     ( _txLocCurSet(), txArc                 (__VA_ARGS__) )
16317 #define txBegin(...)                   ( _txLocCurSet(), txBegin               (__VA_ARGS__) )
16318 #define txBitBlt(...)                  ( _txLocCurSet(), txBitBlt              (__VA_ARGS__) )
16319 #define txChord(...)                   ( _txLocCurSet(), txChord               (__VA_ARGS__) )
16320 #define txCircle(...)                  ( _txLocCurSet(), txCircle              (__VA_ARGS__) )
16321 #define txClear(...)                   ( _txLocCurSet(), txClear               (__VA_ARGS__) )
16322 #define txClearConsole(...)            ( _txLocCurSet(), txClearConsole        (__VA_ARGS__) )
16323 #define txColor(...)                   ( _txLocCurSet(), txColor               (__VA_ARGS__) )
16324 #define txCreateCompatibleDC(...)      ( _txLocCurSet(), txCreateCompatibleDC  (__VA_ARGS__) )
16325 #define txCreateDIBSection(...)        ( _txLocCurSet(), txCreateDIBSection    (__VA_ARGS__) )
16326 #define txCreateExtraWindow(...)       ( _txLocCurSet(), txCreateExtraWindow   (__VA_ARGS__) )
16327 #define txCreateWindow(...)            ( _txLocCurSet(), txCreateWindow        (__VA_ARGS__) )
16328 #define txDC(...)                      ( _txLocCurSet(), txDC                  (__VA_ARGS__) )
16329 #define txDeleteDC(...)                ( _txLocCurSet(), txDeleteDC            (__VA_ARGS__) )
16330 #define txDemangle(...)                ( _txLocCurSet(), txDemangle            (__VA_ARGS__) )
16331 #define txDestroyWindow(...)           ( _txLocCurSet(), txDestroyWindow       (__VA_ARGS__) )
16332 #define txDisableAutoPause(...)        ( _txLocCurSet(), txDisableAutoPause    (__VA_ARGS__) )
16333 #define txDrawText(...)                ( _txLocCurSet(), txDrawText            (__VA_ARGS__) )
16334 #define txEllipse(...)                 ( _txLocCurSet(), txEllipse             (__VA_ARGS__) )
16335 #define txEnd(...)                     ( _txLocCurSet(), txEnd                 (__VA_ARGS__) )
16336 #define txExtractColor(...)            ( _txLocCurSet(), txExtractColor        (__VA_ARGS__) )
16337 #define txFillColor(...)               ( _txLocCurSet(), txFillColor           (__VA_ARGS__) )
16338 #define txFloodFill(...)               ( _txLocCurSet(), txFloodFill           (__VA_ARGS__) )
16339 #define txFontExist(...)               ( _txLocCurSet(), txFontExist           (__VA_ARGS__) )
16340 #define txFormat(...)                  ( _txLocCurSet(), txFormat              (__VA_ARGS__) )
16341 #define txGetAsyncKeyState(...)        ( _txLocCurSet(), txGetAsyncKeyState    (__VA_ARGS__) )
16342 #define txGetColor(...)                ( _txLocCurSet(), txGetColor            (__VA_ARGS__) )
16343 #define txGetConsoleAttr(...)          ( _txLocCurSet(), txGetConsoleAttr      (__VA_ARGS__) )
16344 #define txGetConsoleCursorPos(...)     ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) )
16345 #define txGetConsoleExtent(...)        ( _txLocCurSet(), txGetConsoleExtent    (__VA_ARGS__) )
16346 #define txGetConsoleFontSize(...)      ( _txLocCurSet(), txGetConsoleFontSize  (__VA_ARGS__) )
16347 #define txGetExtent(...)               ( _txLocCurSet(), txGetExtent           (__VA_ARGS__) )
16348 #define txGetExtentX(...)              ( _txLocCurSet(), txGetExtentX          (__VA_ARGS__) )
16349 #define txGetExtentY(...)              ( _txLocCurSet(), txGetExtentY          (__VA_ARGS__) )
16350 #define txGetFillColor(...)            ( _txLocCurSet(), txGetFillColor        (__VA_ARGS__) )
16351 #define txGetFPS(...)                  ( _txLocCurSet(), txGetFPS              (__VA_ARGS__) )
16352 #define txGetModuleFileName(...)       ( _txLocCurSet(), txGetModuleFileName   (__VA_ARGS__) )
16353 #define txGetPixel(...)                ( _txLocCurSet(), txGetPixel            (__VA_ARGS__) )
16354 #define txGetTextExtent(...)           ( _txLocCurSet(), txGetTextExtent       (__VA_ARGS__) )
16355 #define txGetTextExtentX(...)          ( _txLocCurSet(), txGetTextExtentX      (__VA_ARGS__) )
16356 #define txGetTextExtentY(...)          ( _txLocCurSet(), txGetTextExtentY      (__VA_ARGS__) )
16357 #define txHSL2RGB(...)                 ( _txLocCurSet(), txHSL2RGB             (__VA_ARGS__) )
16358 #define txInputBox(...)                ( _txLocCurSet(), txInputBox            (__VA_ARGS__) )
16359 #define txLine(...)                    ( _txLocCurSet(), txLine                (__VA_ARGS__) )
16360 #define txLoadImage(...)               ( _txLocCurSet(), txLoadImage           (__VA_ARGS__) )
16361 #define txLock(...)                    ( _txLocCurSet(), txLock                (__VA_ARGS__) )
16362 #define txMessageBox(...)              ( _txLocCurSet(), txMessageBox          (__VA_ARGS__) )
16363 #define txMouseButtons(...)            ( _txLocCurSet(), txMouseButtons        (__VA_ARGS__) )
16364 #define txMousePos(...)                ( _txLocCurSet(), txMousePos            (__VA_ARGS__) )
16365 #define txMouseX(...)                  ( _txLocCurSet(), txMouseX              (__VA_ARGS__) )
16366 #define txMouseY(...)                  ( _txLocCurSet(), txMouseY              (__VA_ARGS__) )
16367 #define txNotifyIcon(...)              ( _txLocCurSet(), txNotifyIcon          (__VA_ARGS__) )
16368 #define txOK(...)                      ( _txLocCurSet(), txOK                  (__VA_ARGS__) )
16369 #define txOutputDebugPrintf(...)       ( _txLocCurSet(), txOutputDebugPrintf   (__VA_ARGS__) )
16370 #define txPause(...)                   ( _txLocCurSet(), txPause               (__VA_ARGS__) )
16371 #define txPie(...)                     ( _txLocCurSet(), txPie                 (__VA_ARGS__) )
16372 #define txPixel(...)                   ( _txLocCurSet(), txPixel               (__VA_ARGS__) )
16373 #define txPlaySound(...)               ( _txLocCurSet(), txPlaySound           (__VA_ARGS__) )
16374 #define txPlayVideo(...)               ( _txLocCurSet(), txPlayVideo           (__VA_ARGS__) )
16375 #define txPolygon(...)                 ( _txLocCurSet(), txPolygon             (__VA_ARGS__) )
16376 #define txPrintf(...)                  ( _txLocCurSet(), txPrintf              (__VA_ARGS__) )
16377 #define txQueryPerformance(...)        ( _txLocCurSet(), txQueryPerformance    (__VA_ARGS__) )
16378 #define txRectangle(...)               ( _txLocCurSet(), txRectangle           (__VA_ARGS__) )
16379 #define txRedrawWindow(...)            ( _txLocCurSet(), txRedrawWindow        (__VA_ARGS__) )
16380 #define txRegisterClass(...)           ( _txLocCurSet(), txRegisterClass       (__VA_ARGS__) )
16381 #define txRegQuery(...)                ( _txLocCurSet(), txRegQuery            (__VA_ARGS__) )
16382 #define txReopenStdio(...)             ( _txLocCurSet(), txReopenStdio         (__VA_ARGS__) )
16383 #define txRGB2HSL(...)                 ( _txLocCurSet(), txRGB2HSL             (__VA_ARGS__) )
16384 #define txSaveImage(...)               ( _txLocCurSet(), txSaveImage           (__VA_ARGS__) )
16385 #define txSelectFont(...)              ( _txLocCurSet(), txSelectFont          (__VA_ARGS__) )
16386 #define txSelectObject(...)            ( _txLocCurSet(), txSelectObject        (__VA_ARGS__) )
16387 #define txSetColor(...)                ( _txLocCurSet(), txSetColor            (__VA_ARGS__) )
16388 #define txSetConsoleAttr(...)          ( _txLocCurSet(), txSetConsoleAttr      (__VA_ARGS__) )
16389 #define txSetConsoleCursorPos(...)     ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) )
16390 #define txSetDefaults(...)             ( _txLocCurSet(), txSetDefaults         (__VA_ARGS__) )
16391 #define txSetFillColor(...)            ( _txLocCurSet(), txSetFillColor        (__VA_ARGS__) )
16392 #define txSetLocale(...)               ( _txLocCurSet(), txSetLocale           (__VA_ARGS__) )
16393 #define txSetPixel(...)                ( _txLocCurSet(), txSetPixel            (__VA_ARGS__) )
16394 #define txSetProgress(...)             ( _txLocCurSet(), txSetProgress         (__VA_ARGS__) )
16395 #define txSetTextAlign(...)            ( _txLocCurSet(), txSetTextAlign        (__VA_ARGS__) )
16396 #define txSetWindowsHook(...)          ( _txLocCurSet(), txSetWindowsHook      (__VA_ARGS__) )
16397 #define txSleep(...)                   ( _txLocCurSet(), txSleep               (__VA_ARGS__) )
16398 #define txSpeak(...)                   ( _txLocCurSet(), txSpeak               (__VA_ARGS__) )
16399 #define txTextCursor(...)              ( _txLocCurSet(), txTextCursor          (__VA_ARGS__) )
16400 #define txTextOut(...)                 ( _txLocCurSet(), txTextOut             (__VA_ARGS__) )
16401 #define txTransparentBlt(...)          ( _txLocCurSet(), txTransparentBlt      (__VA_ARGS__) )
16402 #define txTriangle(...)                ( _txLocCurSet(), txTriangle            (__VA_ARGS__) )
16403 #define txUnlock(...)                  ( _txLocCurSet(), txUnlock              (__VA_ARGS__) )
16404 #define txUpdateWindow(...)            ( _txLocCurSet(), txUpdateWindow        (__VA_ARGS__) )
16405 #define txUseAlpha(...)                ( _txLocCurSet(), txUseAlpha            (__VA_ARGS__) )
16406 #define txVersion(...)                 ( _txLocCurSet(), txVersion             (__VA_ARGS__) )
16407 #define txVersionNumber(...)           ( _txLocCurSet(), txVersionNumber       (__VA_ARGS__) )
16408 #define txWindow(...)                  ( _txLocCurSet(), txWindow              (__VA_ARGS__) )
16409 #define tx_fpreset(...)                ( _txLocCurSet(), tx_fpreset            (__VA_ARGS__) )
16410 #define tx_glGetError(...)             ( _txLocCurSet(), tx_glGetError         (__VA_ARGS__) )
16411 #define _txDump(...)                   ( _txLocCurSet(), _txDump               (__VA_ARGS__) )
16412 #define _txStackBackTrace(...)         ( _txLocCurSet(), _txStackBackTrace     (__VA_ARGS__) )
16413 
16414 #endif
16415 
16416 //}
16417 //=================================================================================================================
16418 
16420 //}
16421 //=================================================================================================================
16422 
16423 //-----------------------------------------------------------------------------------------------------------------
16424 //{          The namespaces
16425 //-----------------------------------------------------------------------------------------------------------------
16426 
16429 _TX_END_NAMESPACE
16430 
16433 using namespace TX;                    // Allow easy usage of TXLib functions
16434 
16435 using ::std::cin;                      // Predefined usings to avoid "using namespace std"
16436 using ::std::cout;
16437 using ::std::cerr;
16438 using ::std::string;
16439 using ::std::wcin;
16440 using ::std::wcout;
16441 using ::std::wcerr;
16442 using ::std::wstring;
16443 
16444 //}
16445 //-----------------------------------------------------------------------------------------------------------------
16446 
16447 //-----------------------------------------------------------------------------------------------------------------
16448 //{          Compiler- and platform-specific
16449 //           Адаптация к компиляторам и платформам
16450 //-----------------------------------------------------------------------------------------------------------------
16452 
16453 #if defined (_GCC_VER)
16454 
16455     #pragma GCC optimize               "strict-aliasing"
16456 
16457     #pragma GCC pop_options
16458     #pragma GCC diagnostic pop
16459 
16460     #endif
16461 
16462 #if defined (_CLANG_VER)
16463 
16464     #pragma clang diagnostic pop
16465 
16466     #endif
16467 
16468 //-----------------------------------------------------------------------------------------------------------------
16469 
16470 #if defined (_MSC_VER)
16471 
16472     #pragma warning (pop)              // Restoring maximum level
16473 
16474     #endif
16475 
16476 #if defined (__INTEL_COMPILER)
16477 
16478     #pragma warning (default:  174)    // Remark: expression has no effect
16479     #pragma warning (default:  304)    // Remark: access control not specified ("public" by default)
16480     #pragma warning (default:  444)    // Remark: destructor for base class "..." is not virtual
16481     #pragma warning (default:  522)    // Remark: function redeclared "inline" after being called
16482     #pragma warning (default: 1684)    // Conversion from pointer to same-sized integral type (potential portability problem)
16483 
16484     #pragma warning (disable:  981)    // Remark: operands are evaluated in unspecified order
16485 
16486     #endif
16487 
16489 //}
16490 //-----------------------------------------------------------------------------------------------------------------
16491 
16492 #endif // __TXLIB_H_INCLUDED
16493 
16494 //=================================================================================================================
16495 // EOF
16496 //=================================================================================================================
16497                                                                                                                    
16498                                                                                                                    
16499