TX Library Help – Version: 00173a, Revision: 175
 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-12-31 23:02:50 +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 //=================================================================================================================
00101 //           $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $
00102 //-----------------------------------------------------------------------------------------------------------------
00109 //}
00110 //=================================================================================================================
00111 
00112 #if !defined (__TXLIB_H_INCLUDED)                                            // <<< THE CODE IS HERE, UNFOLD IT <<<
00113 #define       __TXLIB_H_INCLUDED
00114 
00115 //-----------------------------------------------------------------------------------------------------------------
00116 //{          Version information and configuration
00117 //-----------------------------------------------------------------------------------------------------------------
00118 
00119 //{----------------------------------------------------------------------------------------------------------------
00141 //}----------------------------------------------------------------------------------------------------------------
00143 
00144 #define _TX_VER      _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 175, 2025-12-31 23:02:50 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00145 #define _TX_VERSION  _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 175, 2025-12-31 23:02:50 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00146 #define _TX_AUTHOR   _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 175, 2025-12-31 23:02:50 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $)
00147 
00149 #define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2)  ((0x##ver##u << 16) | 0x##rev##u)
00150 #define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2)  "TXLib [Ver: " #ver ", Rev: " #rev ", Date: " #date "]"
00151 #define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2)  "Copyright (C) " auth
00152 
00153 
00155 //{----------------------------------------------------------------------------------------------------------------
00162 //}----------------------------------------------------------------------------------------------------------------
00163 
00164 #if !defined (_TX_MODULE)
00165     #define   _TX_MODULE      "TXLib"
00166 #endif
00167 
00168 //{----------------------------------------------------------------------------------------------------------------
00172 //}----------------------------------------------------------------------------------------------------------------
00173 
00174 #define __TX_COMPILER__       "Unknown C++, std="   TX_QUOTE (__cplusplus)
00175 
00176 #if    defined (__GNUC__)
00177 
00178     #define _GCC_VER          ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ )
00179 
00180     #undef  __TX_COMPILER__
00181     #define __TX_COMPILER__   "GNU g++ "            TX_QUOTE (__GNUC__)       "."  \
00182                                                     TX_QUOTE (__GNUC_MINOR__) "."  \
00183                                                     TX_QUOTE (__GNUC_PATCHLEVEL__) \
00184                               ", std="              TX_QUOTE (__cplusplus)
00185 #elif  defined (_MSC_VER)
00186 
00187     #undef  __TX_COMPILER__
00188     #define __TX_COMPILER__   "MSVS "               TX_QUOTE (_MSC_VER)            \
00189                               ", std="              TX_QUOTE (__cplusplus)
00190 #endif
00191 
00192 #if    defined (__clang__) || defined (__clang_major__)
00193 
00194     #define _CLANG_VER        ( __clang_major__*100 + __clang_minor__*10 + __clang_patchlevel__ )
00195 
00196     #undef  __TX_COMPILER__
00197     #define __TX_COMPILER__   "Clang "              TX_QUOTE (__clang_major__) "."  \
00198                                                     TX_QUOTE (__clang_minor__) "."  \
00199                                                     TX_QUOTE (__clang_patchlevel__) \
00200                               ", std="              TX_QUOTE (__cplusplus)
00201 #endif
00202 
00203 //-----------------------------------------------------------------------------------------------------------------
00204 
00206 
00207 #define  TX_QUOTE(sym)        _TX_QUOTE (sym)
00208 #define _TX_QUOTE(sym)        #sym
00209 
00210 #define  TX_JOIN(sym1, sym2)  _TX_JOIN (sym1, sym2)
00211 #define _TX_JOIN(sym1, sym2)  sym1 ## sym2
00212 
00214 
00215 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1800)  // MSVC 2013
00216 
00217     #define _TX_CPP11         1
00218     #endif
00219 
00220 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1900)  // MSVC 2015
00221 
00222     #define _TX_CPP11_MSVC15  1
00223     #endif
00224 
00225 //{----------------------------------------------------------------------------------------------------------------
00229 //}----------------------------------------------------------------------------------------------------------------
00230 
00231 #if   !defined (NDEBUG) &&  defined (_DEBUG)
00232     #define _TX_BUILDMODE     "DEBUG"
00233 
00234 #elif !defined (NDEBUG) && !defined (_DEBUG)
00235     #define _TX_BUILDMODE     "Debug"
00236 
00237 #elif  defined (NDEBUG)
00238     #define _TX_BUILDMODE     "Release"
00239 #endif
00240 
00241 //{----------------------------------------------------------------------------------------------------------------
00245 //}----------------------------------------------------------------------------------------------------------------
00246 
00247 #define __TX_FILELINE__       __FILE__ ":" TX_QUOTE (__LINE__)
00248 
00249 //{----------------------------------------------------------------------------------------------------------------
00257 //}----------------------------------------------------------------------------------------------------------------
00258 
00259 #if defined (__GNUC__) || defined (__clang__) || defined (__clang_major__)
00260     #define __TX_FUNCTION__   __PRETTY_FUNCTION__
00261 
00262 #elif defined (__FUNCSIG__)
00263     #define __TX_FUNCTION__   __FUNCSIG__
00264 
00265 #elif defined (__FUNCTION__)
00266     #define __TX_FUNCTION__   __FUNCTION__
00267 
00268 #elif defined (__cplusplus) && (__cplusplus >= 199711L)
00269     #define __TX_FUNCTION__   __func__
00270 
00271 #elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
00272     #define __TX_FUNCTION__   __func__
00273 
00274 #elif defined (__PYTHON__)
00275     #error No Python. No. Using parseltongue languages can lead you to Slytherin.
00276 
00277 #else
00278     #define __TX_FUNCTION__   "(" __TX_FILELINE__ ")"
00279 
00280 #endif
00281 
00282 #if !defined (__func__) && defined (__FUNCTION__)
00283     #define   __func__        __FUNCTION__
00284 #endif
00285 
00286 //}
00287 //-----------------------------------------------------------------------------------------------------------------
00288 
00289 //-----------------------------------------------------------------------------------------------------------------
00290 //{          Compiler- and platform-specific
00292 //-----------------------------------------------------------------------------------------------------------------
00294 
00295 #if (defined (_GCC_VER)   && (_GCC_VER   <  472) && !defined (_CLANG_VER) || \
00296      defined (_CLANG_VER) && (_CLANG_VER <  900)                          || \
00297      defined (_MSC_VER)   && (_MSC_VER   < 1600))  // Minimum requirements are now GCC 4.7.2 or MSVC 10.0 (2010)
00298 
00299     #ifdef __GNUC__
00300     #error
00301     #error ---------------------------------------------------------------------------------------
00302     #endif
00303     #error TXLib.h: This version works only with GCC >= 4.7.2 or MS Visual Studio >= 2010, sorry.
00304     #error
00305     #error Please use TXLib.h previous stable version/revision OR upgrade/install proper compiler.
00306     #error ---------------------------------------------------------------------------------------
00307     #error
00308 
00309 #endif
00310 
00311 //-----------------------------------------------------------------------------------------------------------------
00312 
00313 #if defined (_GCC_VER) && (_GCC_VER >= 492)
00314 #if defined (TX_USE_SPEAK) && !__has_include (<SAPI.h>)
00315 
00316     #ifdef __GNUC__
00317     #error
00318     #error ---------------------------------------------------------------------------------------
00319     #endif
00320     #error You have defined TX_USE_SPEAK, but your compiler do NOT have the library <SAPI.h>.
00321     #error
00322     #error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API
00323     #error necessary for txSpeak() to work.
00324     #error ---------------------------------------------------------------------------------------
00325     #error
00326 
00327 #endif
00328 #endif
00329 
00330 //-----------------------------------------------------------------------------------------------------------------
00331 
00332 #if !defined (WIN32) && !defined (__WIN32__) && !defined(_WIN32) && !defined(_WIN32_WINNT) && !defined (__CYGWIN__)
00333 
00334     #ifdef __GNUC__
00335     #error
00336     #error ---------------------------------------------------------------------------------------
00337     #endif
00338     #error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW or Cygwin) is the only supported OS, sorry.
00339     #error
00340     #error In Linux or MacOS, you should write your own TXLib and share it with your friends, or use wine.
00341     #error ---------------------------------------------------------------------------------------
00342     #error
00343 
00344 #endif
00345 
00346 //-----------------------------------------------------------------------------------------------------------------
00347 
00348 #if  defined (__STRICT_ANSI__) && (_GCC_VER < 1120)  // Try to extend strict ANSI rules
00349 
00350     #undef  __STRICT_ANSI__
00351     #define __STRICT_ANSI__UNDEFINED
00352 
00353     #if defined (_STRING_H_) || defined (_INC_STRING) || defined (_STDIO_H_) || defined (_INC_STDIO)
00354 
00355     #ifdef __GNUC__
00356     #error
00357     #error ---------------------------------------------------------------------------------------
00358     #endif
00359     #error TXLib.h: Should include "TXLib.h" BEFORE <string.h>, <iostream> or <stdio.h> in Strict ANSI mode.
00360     #error
00361     #error REARRANGE your #include directives, or DISABLE ANSI-compliancy by #undef __STRICT_ANSI__.
00362     #error ---------------------------------------------------------------------------------------
00363     #error
00364 
00365     #endif
00366 
00367 #endif
00368 
00369 //-----------------------------------------------------------------------------------------------------------------
00370 
00371 #if !defined (__cplusplus)
00372 
00373     #ifdef __GNUC__
00374     #error
00375     #error ---------------------------------------------------------------------------------------
00376     #endif
00377     #error TXLib.h: Must use C++ to compile TXLib.h. Now you are using C only.
00378     #error
00379     #error CHECK source file EXTENSION. Maybe it is ".C". It must be ".CPP".
00380     #error If your file is named, for example, "Untitled.C", go to menu [File],
00381     #error then [Save As] and rename it to "Untitled.CPP". Please do NOT use spaces.
00382     #error ---------------------------------------------------------------------------------------
00383     #error
00384 
00385 #endif
00386 
00387 //-----------------------------------------------------------------------------------------------------------------
00388 
00389 #if  defined (UNICODE) || defined (_UNICODE)
00390 
00391     #ifdef __GNUC__
00392     #warning TXLib.h: Disabling the UNICODE
00393     #endif
00394 
00395     #undef   UNICODE                                 // Burn Unicode, burn
00396     #undef  _UNICODE
00397 
00398     #if defined (_WINDOWS_H) || defined (_INC_WINDOWS) || defined (_WINDOWS_) || defined (__WINDOWS__)
00399 
00400     #ifdef __GNUC__
00401     #error
00402     #error ---------------------------------------------------------------------------------------
00403     #endif
00404     #error TXLib.h: Should include "TXLib.h" BEFORE or INSTEAD of <Windows.h> in UNICODE mode.
00405     #error
00406     #error REARRANGE your #include directives, or DISABLE the UNICODE mode by #undef UNICODE/_UNICODE.
00407     #error ---------------------------------------------------------------------------------------
00408     #error
00409 
00410     #endif
00411 
00412 #endif
00413 
00414 //-----------------------------------------------------------------------------------------------------------------
00415 
00416 #if  defined (__GNUC__)
00417 
00418     #pragma GCC diagnostic ignored     "-Wpragmas"
00419     #pragma GCC diagnostic ignored     "-Wunknown-pragmas"
00420     #pragma GCC diagnostic ignored     "-Wunknown-warning-option"
00421 
00422     #pragma GCC diagnostic warning     "-Wall"
00423     #pragma GCC diagnostic warning     "-Weffc++"
00424     #pragma GCC diagnostic warning     "-Wextra"
00425 
00426     #pragma GCC diagnostic warning     "-Waggressive-loop-optimizations"
00427     #pragma GCC diagnostic warning     "-Walloc-zero"
00428     #pragma GCC diagnostic warning     "-Walloca"
00429     #pragma GCC diagnostic warning     "-Walloca-larger-than=8192"
00430     #pragma GCC diagnostic warning     "-Warray-bounds"
00431     #pragma GCC diagnostic warning     "-Wcast-align"
00432     #pragma GCC diagnostic warning     "-Wcast-qual"
00433     #pragma GCC diagnostic warning     "-Wchar-subscripts"
00434     #pragma GCC diagnostic warning     "-Wconditionally-supported"
00435     #pragma GCC diagnostic warning     "-Wconversion"
00436     #pragma GCC diagnostic warning     "-Wctor-dtor-privacy"
00437     #pragma GCC diagnostic warning     "-Wdangling-else"
00438     #pragma GCC diagnostic warning     "-Wduplicated-branches"
00439     #pragma GCC diagnostic warning     "-Wempty-body"
00440     #pragma GCC diagnostic warning     "-Wfloat-equal"
00441     #pragma GCC diagnostic warning     "-Wformat-nonliteral"
00442     #pragma GCC diagnostic warning     "-Wformat-overflow=2"
00443     #pragma GCC diagnostic warning     "-Wformat-security"
00444     #pragma GCC diagnostic warning     "-Wformat-signedness"
00445     #pragma GCC diagnostic warning     "-Wformat-truncation=2"
00446     #pragma GCC diagnostic warning     "-Wformat=2"
00447     #pragma GCC diagnostic warning     "-Wlarger-than=8192"
00448     #pragma GCC diagnostic warning     "-Wlogical-op"
00449     #pragma GCC diagnostic warning     "-Wmismatched-tags"
00450     #pragma GCC diagnostic warning     "-Wmissing-declarations"
00451     #pragma GCC diagnostic warning     "-Wnarrowing"
00452     #pragma GCC diagnostic warning     "-Wnon-virtual-dtor"
00453     #pragma GCC diagnostic warning     "-Wnonnull"
00454     #pragma GCC diagnostic warning     "-Wopenmp-simd"
00455     #pragma GCC diagnostic warning     "-Woverloaded-virtual"
00456     #pragma GCC diagnostic warning     "-Wpacked"
00457     #pragma GCC diagnostic warning     "-Wpointer-arith"
00458     #pragma GCC diagnostic warning     "-Wredundant-decls"
00459     #pragma GCC diagnostic warning     "-Wredundant-tags"
00460     #pragma GCC diagnostic warning     "-Wrestrict"
00461     #pragma GCC diagnostic warning     "-Wshadow"
00462     #pragma GCC diagnostic warning     "-Wsign-promo"
00463     #pragma GCC diagnostic warning     "-Wstack-usage=8192"
00464     #pragma GCC diagnostic warning     "-Wstrict-aliasing"
00465     #pragma GCC diagnostic warning     "-Wstrict-null-sentinel"
00466     #pragma GCC diagnostic warning     "-Wstrict-overflow=2"
00467     #pragma GCC diagnostic warning     "-Wstringop-overflow=4"
00468     #pragma GCC diagnostic warning     "-Wsuggest-attribute=noreturn"
00469     #pragma GCC diagnostic warning     "-Wsuggest-final-methods"
00470     #pragma GCC diagnostic warning     "-Wsuggest-final-types"
00471     #pragma GCC diagnostic warning     "-Wsuggest-override"
00472     #pragma GCC diagnostic warning     "-Wswitch-default"
00473     #pragma GCC diagnostic warning     "-Wswitch-enum"
00474     #pragma GCC diagnostic warning     "-Wsync-nand"
00475     #pragma GCC diagnostic warning     "-Wundef"
00476     #pragma GCC diagnostic warning     "-Wunused"
00477     #pragma GCC diagnostic warning     "-Wvarargs"
00478     #pragma GCC diagnostic warning     "-Wvla-larger-than=8192"
00479 
00480     #pragma GCC diagnostic error       "-Wsizeof-array-argument"
00481 
00482     #pragma GCC diagnostic ignored     "-Waddress"
00483     #pragma GCC diagnostic ignored     "-Winline"
00484     #pragma GCC diagnostic ignored     "-Wliteral-suffix"
00485     #pragma GCC diagnostic ignored     "-Wmissing-field-initializers"
00486     #pragma GCC diagnostic ignored     "-Wnonnull-compare"
00487     #pragma GCC diagnostic ignored     "-Wold-style-cast"
00488     #pragma GCC diagnostic ignored     "-Wunreachable-code"
00489     #pragma GCC diagnostic ignored     "-Wunused-const-variable"
00490     #pragma GCC diagnostic ignored     "-Wunused-function"
00491     #pragma GCC diagnostic ignored     "-Wvariadic-macros"
00492 
00493     #pragma GCC diagnostic warning     "-Wunknown-warning-option"
00494     #pragma GCC diagnostic warning     "-Wunknown-pragmas"
00495     #pragma GCC diagnostic warning     "-Wpragmas"
00496 
00497     //{ These warning settings for TXLib.h only and will be re-enabled at end of file:
00498 
00499     #ifndef _CLANG_VER
00500     #pragma GCC push_options
00501     #endif
00502 
00503     #pragma GCC diagnostic push
00504 
00505     #pragma GCC diagnostic ignored     "-Wpragmas"
00506     #pragma GCC diagnostic ignored     "-Wunknown-pragmas"
00507     #pragma GCC diagnostic ignored     "-Wunknown-warning-option"
00508 
00509     #pragma GCC diagnostic ignored     "-Waddress"
00510     #pragma GCC diagnostic ignored     "-Warray-bounds"
00511     #pragma GCC diagnostic ignored     "-Wclobbered"
00512     #pragma GCC diagnostic ignored     "-Wdeprecated-declarations"
00513     #pragma GCC diagnostic ignored     "-Wfloat-equal"
00514     #pragma GCC diagnostic ignored     "-Wformat-nonliteral"
00515     #pragma GCC diagnostic ignored     "-Wformat-zero-length"
00516     #pragma GCC diagnostic ignored     "-Winvalid-source-encoding"
00517     #pragma GCC diagnostic ignored     "-Wlarger-than="
00518     #pragma GCC diagnostic ignored     "-Wmisleading-indentation"
00519     #pragma GCC diagnostic ignored     "-Wnon-virtual-dtor"
00520     #pragma GCC diagnostic ignored     "-Wpacked-not-aligned"
00521     #pragma GCC diagnostic ignored     "-Wpedantic"
00522     #pragma GCC diagnostic ignored     "-Wredundant-decls"
00523     #pragma GCC diagnostic ignored     "-Wshadow"
00524     #pragma GCC diagnostic ignored     "-Wsign-conversion"
00525     #pragma GCC diagnostic ignored     "-Wstrict-aliasing"
00526     #pragma GCC diagnostic ignored     "-Wsuggest-override"
00527     #pragma GCC diagnostic ignored     "-Wunused-label"    // Just for fun in _txCanvas_OnCmdAbout()
00528     #pragma GCC diagnostic ignored     "-Wunused-value"
00529 
00530     #pragma GCC optimize               "no-strict-aliasing"
00531 
00532     #pragma GCC diagnostic warning     "-Wunknown-warning-option"
00533     #pragma GCC diagnostic warning     "-Wunknown-pragmas"
00534     #pragma GCC diagnostic warning     "-Wpragmas"
00535 
00536     #if defined (__CYGWIN__) && !defined (_TX_TESTING)
00537     #pragma GCC system_header          // This is not a fair play, but this is the only way to deal with Cygwin :(
00538     #endif
00539 
00540     //}
00541 
00542     #define _tx_thread                 __thread
00543     #define _tx_decltype( value )      __decltype (value)
00544 
00545     #define     _FORTIFY_SOURCE        2
00546 
00547     #ifndef     MINGW_HAS_SECURE_API
00548         #define MINGW_HAS_SECURE_API   1
00549     #endif
00550 
00551     #if defined (TX_USE_SFML)
00552         #define _GLIBCXX_NDEBUG
00553     #endif
00554 
00555     #ifndef     _GLIBCXX_NDEBUG                  // TXLib enables _GLIBCXX_DEBUG by default. When using third-party libraries
00556         #define _GLIBCXX_DEBUG                   // compiled without _GLIBCXX_DEBUG (SFML, for example), #define _GLIBCXX_NDEBUG
00557         #define _GLIBCXX_DEBUG_PEDANTIC          // *before* including TXLib.h.
00558     #endif
00559 
00560     #if defined (_WIN64) && !defined (__USE_MINGW_ANSI_STDIO)
00561         #define __USE_MINGW_ANSI_STDIO 1         // Removed in x86 because printf ("%g", double) failure, this always prints 0
00562     #endif
00563 
00564     template <typename T>
00565     inline T _txNOP (T value) { return value; }  // To suppress performance warnings in assert etc.
00566 
00567     #ifndef _CLANG_VER
00568 
00569     // From MinGW\include\float.h which is replaced by MinGW\lib\gcc\i686-pc-mingw32\x.x.x\include\float.h
00570     extern "C" __declspec (dllimport)  unsigned __cdecl _controlfp (unsigned control, unsigned mask);
00571     extern "C"                         void     __cdecl _fpreset   ();
00572 
00573     #endif
00574 
00575 #endif
00576 
00577 //-----------------------------------------------------------------------------------------------------------------
00578 
00579 #if  defined (__clang__) || defined (__clang_major__)
00580 
00581     //{ These warning settings for TXLib.h only and will be re-enabled at end of file:
00582 
00583     #pragma clang diagnostic push
00584 
00585     #pragma clang diagnostic ignored   "-Wcast-align"
00586     #pragma clang diagnostic ignored   "-Wfloat-conversion"
00587     #pragma clang diagnostic ignored   "-Wmicrosoft-cast"
00588     #pragma clang diagnostic ignored   "-Wmissing-braces"
00589     #pragma clang diagnostic ignored   "-Wsign-compare"
00590     #pragma clang diagnostic ignored   "-Wstring-plus-int"
00591     #pragma clang diagnostic ignored   "-Wundef"
00592     #pragma clang diagnostic ignored   "-Wundefined-bool-conversion"
00593     #pragma clang diagnostic ignored   "-Wunused-function"
00594     #pragma clang diagnostic ignored   "-Wvariadic-macros"
00595 
00596     //{ CLang-Tidy options
00597     //
00598     // *,-cert-dcl50-cpp,-cert-dcl58-cpp,-cert-err52-cpp,-cert-err58-cpp,-cert-flp30-c,-cert-msc30-c,-cert-msc32-c,
00599     // -cert-msc50-cpp,-cert-msc51-cpp,-clang-analyzer-core.DivideZero,-cppcoreguidelines-avoid-c-arrays,
00600     // -cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,
00601     // -cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-no-malloc,
00602     // -cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,
00603     // -cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access,
00604     // -cppcoreguidelines-pro-type-vararg,-fuchsia-default-arguments-calls,-fuchsia-default-arguments-declarations,
00605     // -fuchsia-overloaded-operator,-google-build-using-namespace,-google-global-names-in-headers,-google-runtime-int,
00606     // -google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments,
00607     // -hicpp-avoid-c-arrays,-hicpp-avoid-goto,-hicpp-braces-around-statements,-hicpp-deprecated-headers,-hicpp-no-array-decay,
00608     // -hicpp-signed-bitwise,-hicpp-use-equals-delete,-hicpp-use-nullptr,-hicpp-vararg,-llvm-include-order,-hicpp-no-malloc,
00609     // -llvm-namespace-comment,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-use-auto,
00610     // -modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-use-default-member-init,-hicpp-use-auto,
00611     // -modernize-use-equals-delete,-modernize-use-nullptr,-modernize-use-trailing-return-type,-modernize-use-using,
00612     // -readability-braces-around-statements,-readability-else-after-return,-readability-implicit-bool-conversion,
00613     // -readability-isolate-declaration,-readability-magic-numbers,-readability-named-parameter,-modernize-loop-convert
00614     //}
00615 
00616     //}
00617 
00618 #endif
00619 
00620 //-----------------------------------------------------------------------------------------------------------------
00621 
00622 #if  defined (_MSC_VER)
00623 
00624     #pragma warning (push, 4)                    // Set maximum warning level. This 'push' is to set the level only. It will NOT be popped.
00625 
00626     #pragma warning (disable:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning
00627 
00628     #pragma warning (disable:    4514)           // Unreferenced inline function has been removed
00629     #pragma warning (disable:    4710)           // Function not inlined
00630     #pragma warning (disable:    4786)           // Identifier was truncated to '255' characters in the debug information
00631 
00632     #pragma warning (error:      4715)           // Not all control paths return a value
00633 
00634     #pragma warning (default:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning  //-V665
00635 
00636     #pragma warning (disable:   26473)           // Don't cast between pointer types where the source type and the target type are the same (type.1).
00637     #pragma warning (disable:   26475)           // Do not use function style C-casts (es.49).
00638     #pragma warning (disable:   26477)           // Use 'nullptr' rather than 0 or NULL (es.47).
00639     #pragma warning (disable:   26481)           // Don't use pointer arithmetic. Use span instead (bounds.1).
00640     #pragma warning (disable:   26826)           // Don't use C-style variable arguments (f.55).
00641 
00642     // These warning settings for TXLib.h only and will be re-enabled at end of file:
00643 
00644     #pragma warning (push)
00645 
00646     #pragma warning (disable:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning
00647 
00648     #pragma warning (disable:    4091)           // 'typedef': ignored on left of '...' when no variable is declared
00649     #pragma warning (disable:    4124)           // Using __fastcall with stack checking is ineffective
00650     #pragma warning (disable:    4127)           // Conditional expression is constant
00651     #pragma warning (disable:    4200)           // Nonstandard extension used: zero-sized array in struct/union
00652     #pragma warning (disable:    4201)           // Nonstandard extension used: nameless struct/union
00653     #pragma warning (disable:    4351)           // New behavior: elements of array will be default initialized
00654     #pragma warning (disable:    4480)           // Nonstandard extension used: specifying underlying type for enum 'type'
00655     #pragma warning (disable:    4481)           // Nonstandard extension used: override specifier 'override'
00656     #pragma warning (disable:    4555)           // Result of expression not used
00657     #pragma warning (disable:    4611)           // Interaction between '_setjmp' and C++ object destruction is non-portable
00658     #pragma warning (disable:    5045)           // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
00659     #pragma warning (disable:    6269)           // Possibly incorrect order of operations: dereference ignored
00660     #pragma warning (disable:    6285)           // (<non-zero constant>) || (<non-zero constant>) is always a non-zero constant. Did you intend to use bitwize-and operator?
00661     #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
00662     #pragma warning (disable:    6326)           // Potential comparison of a constant with another constant
00663     #pragma warning (disable:    6553)           // The annotation for function 'func' on _Param_(N) does not apply to a value type.
00664     #pragma warning (disable:   26135)           // Missing locking annotation
00665     #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).
00666     #pragma warning (disable:   26401)           // Do not delete a raw pointer that is not an owner<T> (i.11).
00667     #pragma warning (disable:   26403)           // Reset or explicitly delete an owner<T> pointer 'name' (r.3).
00668     #pragma warning (disable:   26408)           // Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10).
00669     #pragma warning (disable:   26409)           // Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11).
00670     #pragma warning (disable:   26426)           // Global initializer calls a non-constexpr function 'name' (i.22).
00671     #pragma warning (disable:   26429)           // Symbol 'name' is never tested for nullness, it can be marked as not_null (f.23).
00672     #pragma warning (disable:   26430)           // Symbol 'name' is not tested for nullness on all paths (f.23).
00673     #pragma warning (disable:   26432)           // If you define or delete any default operation in the type 'struct 'name'', define or delete them all (c.21).
00674     #pragma warning (disable:   26435)           // Function 'name' should specify exactly one of 'virtual', 'override', or 'final' (c.128).
00675     #pragma warning (disable:   26438)           // Avoid 'goto' (es.76).
00676     #pragma warning (disable:   26440)           // Function 'name' can be declared 'noexcept' (f.6).
00677     #pragma warning (disable:   26446)           // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).
00678     #pragma warning (disable:   26447)           // The function is declared 'noexcept' but calls function 'func' which may throw exceptions (f.6).
00679     #pragma warning (disable:   26448)           // Consider using gsl::finally if final action is intended (gsl.util).
00680     #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).
00681     #pragma warning (disable:   26455)           // Default constructor may not throw. Declare it 'noexcept' (f.6).
00682     #pragma warning (disable:   26457)           // (void) should not be used to ignore return values, use 'std::ignore =' instead (es.48)
00683     #pragma warning (disable:   26460)           // The reference argument 'stream' for function 'name' can be marked as const (con.3).
00684     #pragma warning (disable:   26461)           // The pointer argument 'name' for function 'name' can be marked as a pointer to const (con.3).
00685     #pragma warning (disable:   26462)           // The value pointed to by 'name' is assigned only once, mark it as a pointer to const (con.4).
00686     #pragma warning (disable:   26482)           // Only index into arrays using constant expressions (bounds.2).
00687     #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).
00688     #pragma warning (disable:   26485)           // Expression 'expr': No array to pointer decay (bounds.3).
00689     #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).
00690     #pragma warning (disable:   26487)           // Don't return a pointer 'name' that may be invalid (lifetime.4).
00691     #pragma warning (disable:   26488)           // Do not dereference a potentially null pointer: 'name'. 'name' was null at line 'n' (lifetime.1).
00692     #pragma warning (disable:   26489)           // Don't dereference a pointer that may be invalid: 'name'. 'name' may have been invalidated at line 'n' (lifetime.1).
00693     #pragma warning (disable:   26490)           // Don't use reinterpret_cast (type.1).
00694     #pragma warning (disable:   26492)           // Don't use const_cast to cast away const or volatile (type.3).
00695     #pragma warning (disable:   26493)           // Don't use C-style casts (type.4).
00696     #pragma warning (disable:   26496)           // The variable 'name' is assigned only once, mark it as const (con.4).
00697     #pragma warning (disable:   26497)           // The function 'name' could be marked constexpr if compile-time evaluation is desired (f.4).
00698     #pragma warning (disable:   26812)           // The enum type 'type' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
00699     #pragma warning (disable:   26814)           // The const variable 'name' can be computed at compile-time. Consider using constexpr (con.5).
00700     #pragma warning (disable:   26822)           // Dereferencing a possibly null pointer '...' (lifetime.1).
00701     #pragma warning (disable:   26823)           // Dereferencing a possibly null pointer '...' (lifetime.1).
00702     #pragma warning (disable:   28125)           // The function must be called from within a try/except block
00703     #pragma warning (disable:   28159)           // Consider using another function instead
00704 
00705     #pragma warning (default:    4616)           // #pragma warning: warning number 'n' not a valid compiler warning  //-V665
00706 
00707     #define _tx_thread          __declspec (thread)
00708     #define _tx_decltype(value)   decltype (value)
00709 
00710     #if !defined (_CLANG_VER)
00711 
00712     #pragma setlocale           ("russian")      // Set source file encoding, see also _TX_CODEPAGE
00713 
00714     #if !defined (NDEBUG)
00715         #pragma check_stack     (      on)       // Turn on stack probes at runtime
00716         #pragma strict_gs_check (push, on)       // Detects stack buffer overruns
00717     #endif
00718 
00719     #define     __attribute__( attr )
00720     #define     _txNOP( value ) ( value )
00721 
00722     #endif
00723 
00724     #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES  1
00725 
00726 #endif
00727 
00728 //-----------------------------------------------------------------------------------------------------------------
00729 
00730 #if !defined (WINVER)
00731     #define   WINVER                   0x0502    // Defaults to Windows XP
00732     #define   WINDOWS_ENABLE_CPLUSPLUS           // Allow use of type-limit macros in <basetsd.h>,
00733 #endif                                           //   they are allowed by default if WINVER >= 0x0600.
00734 
00735 #if !defined (_WIN32_WINNT)
00736     #define   _WIN32_WINNT             WINVER    // Defaults to the same as WINVER
00737 #endif
00738 
00739 #if !defined (_WIN32_IE)
00740     #define   _WIN32_IE                WINVER    // Defaults to the same as WINVER
00741 #endif
00742 
00743 #define stristr(  str1, str2 )         Win32::StrStrIA ((str1), (str2))
00744 #define stristrw( str1, str2 )         Win32::StrStrIW ((str1), (str2))
00745 
00746 //-----------------------------------------------------------------------------------------------------------------
00747 
00748 #define _USE_MATH_DEFINES              1         // Math.h's M_PI etc.
00749 #define __STDC_FORMAT_MACROS           1         // PRIu64 and other PR... macros
00750 #define __STDC_WANT_LIB_EXT1__         1         // String and output *_s functions
00751 
00752 #define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS  // Wow, how long. Kudos, Clang
00753 
00754 #define _ALLOW_RTCc_IN_STL             1         // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc.
00755 
00756 #define NOMINMAX                       1         // Preventing 'min' and 'max' defines in Windows.h
00757 
00758 #if defined (_DEBUG)
00759 #define _SECURE_SCL                    1         // Enable checked STL iterators to throw an exception on incorrect use
00760 #define _HAS_ITERATOR_DEBUGGING        1
00761 #define _LIBCPP_DEBUG                  2
00762 #define _LIBCPP_HARDENING_MODE         _LIBCPP_HARDENING_MODE_DEBUG
00763 #define _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
00764 #endif
00765 
00766 #if defined (_MSC_VER) && defined (_DEBUG)
00767 
00768     #define _CRTDBG_MAP_ALLOC                    // Enable MSVCRT debug heap
00769     #define _new_dbg                   new (_NORMAL_BLOCK, __FILE__, __LINE__)
00770     #define NEW                        new (_NORMAL_BLOCK, __FILE__, __LINE__)
00771 
00772 #else
00773     #define _new_dbg                   new
00774     #define NEW                        new
00775 
00776 #endif
00777 
00778 #if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015
00779 #define _SECURE_SCL_THROWS             1
00780 #endif
00781 
00782 #define     tx_noreturn                __attribute__ (( noreturn           ))
00783 #define     tx_nodiscard               __attribute__ (( warn_unused_result ))
00784 #define     tx_deprecated              __attribute__ (( deprecated         ))
00785 #define     tx_printfy( formatArgN )   __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) ))
00786 #define     tx_scanfy(  formatArgN )   __attribute__ (( format (scanf,  (formatArgN), (formatArgN)+1) ))
00787 
00788 
00789 #if defined (_TX_CPP11)
00790 
00791     #define _tx_delete                 = delete
00792     #define _tx_default                = default
00793     #define _tx_override               override
00794     #define _tx_final                  final
00795 
00796 #else
00797 
00798     #define _tx_delete
00799     #define _tx_default
00800     #define _tx_override
00801     #define _tx_final
00802 
00803 #endif
00804 
00805 namespace std
00806     {
00807     enum nomeow_t { nomeow };                    // Vital addition to the C++ standard. TODO: Should contact C++ std committee.
00808 
00809     #if defined (_CLANG_VER) && (_CLANG_VER < 2000)
00810     void __libcpp_verbose_abort (char const* format, ...);
00811     #endif
00812     }
00813 
00814 //-----------------------------------------------------------------------------------------------------------------
00815 
00817 //}
00818 //-----------------------------------------------------------------------------------------------------------------
00819 
00820 //-----------------------------------------------------------------------------------------------------------------
00821 //{          The Includes
00822 //-----------------------------------------------------------------------------------------------------------------
00823 
00824 #if defined (_MSC_VER)
00825     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
00826 
00827     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
00828     #pragma warning (disable: 4005)              // 'name': macro redefinition
00829 #endif
00830 
00831 //-----------------------------------------------------------------------------------------------------------------
00832 
00833 #include <stdlib.h>
00834 #include <stdio.h>
00835 #include <stdint.h>
00836 #include <string.h>
00837 #include <time.h>
00838 #include <math.h>
00839 #include <float.h>
00840 
00841 #include <vector>
00842 #include <string>
00843 #include <iostream>
00844 #include <sstream>
00845 #include <iomanip>
00846 
00847 #if !defined (__CYGWIN__)
00848 #include <conio.h>
00849 #include <direct.h>
00850 #endif
00851 
00852 #if defined (TX_COMPILED)
00853 #define WIN32_LEAN_AND_MEAN
00854 #endif
00855 
00856 #include <windows.h>
00857 #include <mmsystem.h>
00858 
00859 //-----------------------------------------------------------------------------------------------------------------
00860 //{          Compiler- and platform-specific
00862 //-----------------------------------------------------------------------------------------------------------------
00863 
00864 #if defined (_MSC_VER)
00865     #pragma warning (pop)                        // MSVC: Restore max level
00866 #endif
00867 
00868 #if defined (__STRICT_ANSI__UNDEFINED)
00869     #define  __STRICT_ANSI__                     // Redefine back
00870 #endif
00871 
00872 #if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED)
00873 
00874     #define  strncpy_s( dest, sizeof_dest, src, count )  ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
00875     #define  wcsncpy_s( dest, sizeof_dest, src, count )  ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) )
00876     #define  strncat_s( dest, sizeof_dest, src, count )  ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) )
00877     #define  strerror_s( buf, sizeof_buf, code        )  ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) )
00878     #define  strtok_s(   buf, delim, ctx              )  ( (void)(ctx), strtok ((buf), (delim)) )
00879     #define  fopen_s(    file, name, mode             )  ( *(file) = fopen ((name), (mode)) )
00880     #define _strlwr_s(   str, sizeof_str              )  ( _strlwr (str) )
00881 
00882     #define  ctime_s( buf, sizeof_buf, time    )         ( strncpy ((buf), ctime (time), (sizeof_buf)-1) )
00883     #define _controlfp_s( oldCtl, newCtl, mask )         ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 )
00884 
00885     #define _snprintf_s                                  snprintf
00886     #define _vsnprintf_s( str, sz, trunc, format, arg )  _vsnprintf (str, sz, format, arg)
00887 
00888 #endif
00889 
00890 #if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) )
00891 
00892     #define  getenv_s( sz, buf, sizeof_buf, name )       ({ (void)(sz); const char* _env = getenv (name); \
00893                                                             strncpy ((buf), (_env)? _env : "", (sizeof_buf)-1); })
00894 #endif
00895 
00896 #if defined (__CYGWIN__)
00897 
00898     #undef   __STRICT_ANSI__
00899 
00900     typedef  void                                _exception;
00901 
00902     #define _O_TEXT                              O_TEXT
00903     #define _fdopen                              fdopen
00904     #define _flushall()                          fflush (NULL)
00905     #define _getcwd                              getcwd
00906     #define _getpid                              getpid
00907     #define _stricmp                             strcasecmp
00908     #define _strlwr                              strlwr
00909     #define _strnicmp                            strncasecmp
00910     #define _unlink                              unlink
00911     #define _vsnprintf                           vsnprintf
00912     #define _access                              access
00913     #define _strdup                              strdup
00914 
00915     #define getch                                _getch
00916     #define putch                                _putch
00917     #define kbhit                                _kbhit
00918 
00919 #endif
00920 
00921 #if !defined (PRId64) || \
00922      defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32
00923 
00924     #undef  PRId64
00925     #undef  PRIi64
00926     #undef  PRIo64
00927     #undef  PRIu64
00928     #undef  PRIx64
00929     #undef  PRIX64
00930 
00931     #define PRId64                               "I64d"
00932     #define PRIi64                               "I64i"
00933     #define PRIo64                               "I64o"
00934     #define PRIu64                               "I64u"
00935     #define PRIx64                               "I64x"
00936     #define PRIX64                               "I64X"
00937 
00938 #endif
00939 
00940 //}
00941 //-----------------------------------------------------------------------------------------------------------------
00942 
00943 //}
00944 //-----------------------------------------------------------------------------------------------------------------
00945 
00946 //-----------------------------------------------------------------------------------------------------------------
00947 //{          The namespaces
00948 //-----------------------------------------------------------------------------------------------------------------
00949 
00950 //{----------------------------------------------------------------------------------------------------------------
00953 //}----------------------------------------------------------------------------------------------------------------
00954 
00955 #ifdef FOR_DOXYGEN_ONLY
00956 namespace { namespace TX { }}
00957 #endif
00958 
00961 //-----------------------------------------------------------------------------------------------------------------
00962 
00963 #if defined (TX_COMPILED)  &&  defined (TX_COMPILING)
00964     #undef   TX_COMPILED
00965     #endif
00966 
00967 #if !defined (TX_COMPILED) && !defined (TX_COMPILING)
00968 
00969     #define _TX_BEGIN_NAMESPACE                      namespace { namespace TX {
00970     #define _TX_END_NAMESPACE                        } }
00971 
00972 #else
00973 
00974     #define _TX_BEGIN_NAMESPACE                                  namespace TX {
00975     #define _TX_END_NAMESPACE                        }
00976 
00977 #endif
00978 
00979 //-----------------------------------------------------------------------------------------------------------------
00980 
00981 _TX_BEGIN_NAMESPACE
00982 
00985 //}
00986 //-----------------------------------------------------------------------------------------------------------------
00987 
00988 //=================================================================================================================
00989 //{          TXLIB INTERFACE
00990 //           Интерфейс библиотеки
00991 //=================================================================================================================
00992 
00993 //=================================================================================================================
00994 //{          Initialization
00996 //=================================================================================================================
00998 //{----------------------------------------------------------------------------------------------------------------
01042 //}----------------------------------------------------------------------------------------------------------------
01043 
01044 HWND txCreateWindow (double sizeX, double sizeY, bool centered = true);
01045 
01046 //{----------------------------------------------------------------------------------------------------------------
01073 //}----------------------------------------------------------------------------------------------------------------
01074 
01075 inline HDC& txDC() tx_nodiscard;
01076 
01077 //{----------------------------------------------------------------------------------------------------------------
01113 //}----------------------------------------------------------------------------------------------------------------
01114 
01115 inline RGBQUAD* txVideoMemory() tx_nodiscard;
01116 
01117 //{----------------------------------------------------------------------------------------------------------------
01136 //}----------------------------------------------------------------------------------------------------------------
01137 
01138 bool txSetDefaults (HDC dc = txDC());
01139 
01140 //{----------------------------------------------------------------------------------------------------------------
01159 //}----------------------------------------------------------------------------------------------------------------
01160 
01161 inline bool txOK() tx_nodiscard;
01162 
01163 //{----------------------------------------------------------------------------------------------------------------
01195 //}----------------------------------------------------------------------------------------------------------------
01196 
01197 POINT txGetExtent (HDC dc = txDC()) tx_nodiscard;
01198 
01199 //{----------------------------------------------------------------------------------------------------------------
01216 //}----------------------------------------------------------------------------------------------------------------
01217 
01218 inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard;
01219 
01220 //{----------------------------------------------------------------------------------------------------------------
01238 //}----------------------------------------------------------------------------------------------------------------
01239 
01240 inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard;
01241 
01242 //{----------------------------------------------------------------------------------------------------------------
01254 //}----------------------------------------------------------------------------------------------------------------
01255 
01256 inline HWND txWindow() tx_nodiscard;
01257 
01258 //{----------------------------------------------------------------------------------------------------------------
01267 //}----------------------------------------------------------------------------------------------------------------
01268 
01269 inline const char* txVersion() tx_nodiscard;
01270 
01271 //{----------------------------------------------------------------------------------------------------------------
01280 //}----------------------------------------------------------------------------------------------------------------
01281 
01282 inline unsigned txVersionNumber() tx_nodiscard;
01283 
01284 //{----------------------------------------------------------------------------------------------------------------
01314 //}----------------------------------------------------------------------------------------------------------------
01315 
01316 const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard;
01317 
01319 //{----------------------------------------------------------------------------------------------------------------
01354 //}----------------------------------------------------------------------------------------------------------------
01355 
01356 int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает",
01357                   unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL);
01358 
01359 //{----------------------------------------------------------------------------------------------------------------
01376 //}----------------------------------------------------------------------------------------------------------------
01377 
01378 HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL);
01379 
01380 //}
01381 //=================================================================================================================
01382 
01383 //=================================================================================================================
01384 //{          Setting the parameters
01386 //=================================================================================================================
01388 //{----------------------------------------------------------------------------------------------------------------
01414 //}----------------------------------------------------------------------------------------------------------------
01415 
01416 const COLORREF
01417 #ifdef FOR_DOXYGEN_ONLY
01418     enum txColors {
01419 #endif
01420 
01421     TX_BLACK         = RGB (  0,   0,   0),   
01422     TX_BLUE          = RGB (  0,   0, 128),   
01423     TX_GREEN         = RGB (  0, 128,   0),   
01424     TX_CYAN          = RGB (  0, 128, 128),   
01425     TX_RED           = RGB (128,   0,   0),   
01426     TX_MAGENTA       = RGB (128,   0, 128),   
01427     TX_BROWN         = RGB (128, 128,   0),   
01428     TX_ORANGE        = RGB (255, 128,   0),   
01429     TX_GRAY          = RGB (160, 160, 160),   
01430     TX_DARKGRAY      = RGB (128, 128, 128),   
01431     TX_LIGHTGRAY     = RGB (192, 192, 192),   
01432     TX_LIGHTBLUE     = RGB (  0,   0, 255),   
01433     TX_LIGHTGREEN    = RGB (  0, 255, 128),   
01434     TX_LIGHTCYAN     = RGB (  0, 255, 255),   
01435     TX_LIGHTRED      = RGB (255,   0, 128),   
01436     TX_LIGHTMAGENTA  = RGB (255,   0, 255),   
01437     TX_PINK          = RGB (255, 128, 255),   
01438     TX_YELLOW        = RGB (255, 255, 128),   
01439     TX_WHITE         = RGB (255, 255, 255),   
01440     TX_TRANSPARENT   = 0xFFFFFFFF,            
01441     TX_NULL          = TX_TRANSPARENT,        
01442 
01443 //  Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB(), txRGB2Lab(), txLab2RGB()
01444 
01445     TX_HUE          = 0x04000000,             
01446     TX_SATURATION   = 0x05000000,             
01447     TX_LIGHTNESS    = 0x06000000,             
01448     TX_LAB_L        = 0x07000000,             
01449     TX_LAB_A        = 0x08000000,             
01450     TX_LAB_B        = 0x09000000;             
01451 
01452 #ifdef FOR_DOXYGEN_ONLY
01453     };
01454 #endif
01455 
01457 #define TX_GREY       TX_GRAY
01458 #define TX_DARKGREY   TX_DARKGRAY
01459 #define TX_LIGHTGREY  TX_LIGHTGRAY
01460 
01461 
01462 //{----------------------------------------------------------------------------------------------------------------
01487 //}----------------------------------------------------------------------------------------------------------------
01488 
01489 #ifdef FOR_DOXYGEN_ONLY
01490 COLORREF RGB (int red, int green, int blue);
01491 #endif
01492 
01493 //{----------------------------------------------------------------------------------------------------------------
01512 //}----------------------------------------------------------------------------------------------------------------
01513 
01514 HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC());
01515 
01517 #define txSetColour txSetColor
01518 
01519 
01521 
01522 //{----------------------------------------------------------------------------------------------------------------
01533 //}----------------------------------------------------------------------------------------------------------------
01534 
01535 COLORREF txColor (double red, double green, double blue);
01536 
01538 
01539 //{----------------------------------------------------------------------------------------------------------------
01552 //}----------------------------------------------------------------------------------------------------------------
01553 
01554 COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard;
01555 
01556 //{----------------------------------------------------------------------------------------------------------------
01571 //}----------------------------------------------------------------------------------------------------------------
01572 
01573 HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC());
01574 
01576 #define txSetFillColour txSetFillColor
01577 
01578 
01580 
01581 //{----------------------------------------------------------------------------------------------------------------
01592 //}----------------------------------------------------------------------------------------------------------------
01593 
01594 COLORREF txFillColor (double red, double green, double blue);
01595 
01597 
01598 //{----------------------------------------------------------------------------------------------------------------
01611 //}----------------------------------------------------------------------------------------------------------------
01612 
01613 COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard;
01614 
01615 //{----------------------------------------------------------------------------------------------------------------
01633 //}----------------------------------------------------------------------------------------------------------------
01634 
01635 unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard;
01636 
01637 //{----------------------------------------------------------------------------------------------------------------
01665 //}----------------------------------------------------------------------------------------------------------------
01666 
01667 COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard;
01668 
01669 //{----------------------------------------------------------------------------------------------------------------
01703 //}----------------------------------------------------------------------------------------------------------------
01704 
01705 COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard;
01706 
01707 //{----------------------------------------------------------------------------------------------------------------
01739 //}----------------------------------------------------------------------------------------------------------------
01740 
01741 COLORREF txRGB2Lab (COLORREF rgbColor) tx_nodiscard;
01742 
01743 //{----------------------------------------------------------------------------------------------------------------
01777 //}----------------------------------------------------------------------------------------------------------------
01778 
01779 COLORREF txLab2RGB (COLORREF labColor) tx_nodiscard;
01780 
01781 //{----------------------------------------------------------------------------------------------------------------
01847 //}----------------------------------------------------------------------------------------------------------------
01848 
01849 double txDeltaE (COLORREF rgbColor1, COLORREF rgbColor2) tx_nodiscard;
01850 
01851 //{----------------------------------------------------------------------------------------------------------------
01866 //}----------------------------------------------------------------------------------------------------------------
01867 
01868 double txDeltaE94 (COLORREF rgbColor1, COLORREF rgbColor2) tx_nodiscard;
01869 
01871 //}
01872 //=================================================================================================================
01873 
01874 //=================================================================================================================
01875 //{          Drawing
01877 //=================================================================================================================
01879 //{----------------------------------------------------------------------------------------------------------------
01893 //}----------------------------------------------------------------------------------------------------------------
01894 
01895 bool txClear (HDC dc = txDC());
01896 
01897 //{----------------------------------------------------------------------------------------------------------------
01915 //}----------------------------------------------------------------------------------------------------------------
01916 
01917 inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC());
01918 
01920 
01921 //{----------------------------------------------------------------------------------------------------------------
01939 //}----------------------------------------------------------------------------------------------------------------
01940 
01941 inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC());
01942 
01944 
01945 //{----------------------------------------------------------------------------------------------------------------
01963 //}----------------------------------------------------------------------------------------------------------------
01964 
01965 inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard;
01966 
01967 //{----------------------------------------------------------------------------------------------------------------
01987 //}----------------------------------------------------------------------------------------------------------------
01988 
01989 bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC());
01990 
01991 //{----------------------------------------------------------------------------------------------------------------
02013 //}----------------------------------------------------------------------------------------------------------------
02014 
02015 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC());
02016 
02017 //{----------------------------------------------------------------------------------------------------------------
02037 //}----------------------------------------------------------------------------------------------------------------
02038 
02039 bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC());
02040 
02041 //{----------------------------------------------------------------------------------------------------------------
02061 //}----------------------------------------------------------------------------------------------------------------
02062 
02063 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC());
02064 
02065 //{----------------------------------------------------------------------------------------------------------------
02083 //}----------------------------------------------------------------------------------------------------------------
02084 
02085 bool txCircle (double x, double y, double r);
02086 
02087 //{----------------------------------------------------------------------------------------------------------------
02110 //}----------------------------------------------------------------------------------------------------------------
02111 
02112 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02113 
02114 //{----------------------------------------------------------------------------------------------------------------
02137 //}----------------------------------------------------------------------------------------------------------------
02138 
02139 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02140 
02141 //{----------------------------------------------------------------------------------------------------------------
02164 //}----------------------------------------------------------------------------------------------------------------
02165 
02166 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC());
02167 
02168 //{----------------------------------------------------------------------------------------------------------------
02200 //}----------------------------------------------------------------------------------------------------------------
02201 
02202 bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC());
02203 
02204 //{----------------------------------------------------------------------------------------------------------------
02222 //}----------------------------------------------------------------------------------------------------------------
02223 
02224 inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)
02225     {
02226     (void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3;
02227 
02228     txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n"
02229                   "Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами "
02230                   "как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". "
02231                   "Ну или нарисовать тремя линиями. :)", "TXLib сообщает");
02232     return false;
02233     }
02234 
02235 //{----------------------------------------------------------------------------------------------------------------
02237 
02238 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
02239 
02240 #define txRectandle  Sleep (1000), txRectangle  // Copy-protection for the function below
02241 #define txLine(...)  txLine (__VA_ARGS__); {    //
02242 #define txNotifyIcon }}}}}}}}}} txNotifyIcon    // Не спрашивайте, зачем. Это дичь.
02243 #define txCircle     ;txCircle                  //
02244 #define txSetColor   ;txSetColor                //
02245 #define C0L0RREF     COLORREF                   //
02246 #define OxFFFFFF     0xFFFFFF                   //
02247 #define lO           10                         //
02248 #define lOOO         1000                       //
02249 #define oo                                      //
02250 #define O                                       //
02251 
02253 //}
02254 
02255 //{----------------------------------------------------------------------------------------------------------------
02296 //}----------------------------------------------------------------------------------------------------------------//////
02297                                                                                                                        //
02298 inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist,   //
02299                        double head, double eyes, double wink, double crazy, double smile, double hair, double wind)    //
02300     {                                                                                                                  //
02301     const char __[] =  "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/";           //
02302     //                   |                                |                          |                  |              //
02303     // Не копипастите! _/ \_ Все равно не получится! :) _/ \_  Человечки защищают  _/ \_ этот код! :) _/ \_  Муаххаха! //
02304     //                                                                                                                 //
02305     static int count = GetTickCount(), L = 0;  
02306 
02307     C0L0RREF lineColor = txGetColor();
02308     C0L0RREF fillColor = txGetFillColor();
02309 
02310     txSetColor     (color, 3);
02311     txSetFillColor (color);
02312 
02313     txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY);
02314 
02315     txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY);
02316     txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY);
02317 
02318     txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y);
02319     txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y);
02320 
02321     txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY);
02322 
02323     txLine (x, y - (1 + head) * sizeY, x +  wind/lO        * sizeX, y - (1 + head + hair/lO) * sizeY);
02324     txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
02325     txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY);
02326 
02327     txSetColor     (~color & OxFFFFFF);  // Inverse the color
02328     txSetFillColor (~color & OxFFFFFF);
02329 
02330     txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
02331     txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY);
02332                                               oo
02333     txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]);  //-V112 //-V542
02334                                    oo
02335     // See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow
02336 
02337     txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY);
02338     txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY);
02339     Sleep (lOOO + count%2);
02340 
02341     txSetColor     ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT);
02342     txSetFillColor (TX_TRANSPARENT);
02343 
02344     txCircle (x, y, 4);  //-V112
02345     txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y);
02346 
02347     txSetColor     (lineColor);
02348     txSetFillColor (fillColor);
02349     }
02350 
02352 //}
02353 //=================================================================================================================
02354 
02355 //=================================================================================================================
02356 //{          Drawing text
02358 //=================================================================================================================
02360 //{----------------------------------------------------------------------------------------------------------------
02379 //}----------------------------------------------------------------------------------------------------------------
02380 
02381 bool txTextOut (double x, double y, const char text[], HDC dc = txDC());
02382 
02383 //{----------------------------------------------------------------------------------------------------------------
02385 
02386 #undef txRectandle
02387 #undef txLine
02388 #undef txNotifyIcon
02389 #undef txCircle
02390 #undef txSetColor
02391 #undef C0L0RREF
02392 #undef OxFFFFFF
02393 #undef lO
02394 #undef lOOO
02395 #undef oo
02396 #undef O
02397 
02399 //}
02400 
02401 //{----------------------------------------------------------------------------------------------------------------
02448 //}----------------------------------------------------------------------------------------------------------------
02449 
02450 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
02451                  unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC());
02452 
02453 //{----------------------------------------------------------------------------------------------------------------
02478 //}----------------------------------------------------------------------------------------------------------------
02479 
02480 HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1,
02481                     int bold = FW_DONTCARE, bool italic = false, bool underline = false,
02482                     bool strikeout = false, double angle = 0,
02483                     HDC dc = txDC());
02484 
02485 //{----------------------------------------------------------------------------------------------------------------
02500 //}----------------------------------------------------------------------------------------------------------------
02501 
02502 SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard;
02503 
02504 //{----------------------------------------------------------------------------------------------------------------
02518 //}----------------------------------------------------------------------------------------------------------------
02519 
02520 int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard;
02521 
02522 //{----------------------------------------------------------------------------------------------------------------
02536 //}----------------------------------------------------------------------------------------------------------------
02537 
02538 int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard;
02539 
02540 //{----------------------------------------------------------------------------------------------------------------
02567 //}----------------------------------------------------------------------------------------------------------------
02568 
02569 unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC());
02570 
02571 //{----------------------------------------------------------------------------------------------------------------
02587 //}----------------------------------------------------------------------------------------------------------------
02588 
02589 LOGFONT* txFontExist (const char name[]) tx_nodiscard;
02590 
02592 //}
02593 //=================================================================================================================
02594 
02595 //=================================================================================================================
02596 //{          Drawing to memory DC and image loading
02598 //=================================================================================================================
02600 //{----------------------------------------------------------------------------------------------------------------
02640 //}----------------------------------------------------------------------------------------------------------------
02641 
02642 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard;
02643 
02644 //{----------------------------------------------------------------------------------------------------------------
02747 //}----------------------------------------------------------------------------------------------------------------
02748 
02749 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD**  pixels = NULL) tx_nodiscard;
02750 
02752 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)        tx_nodiscard;
02754 
02755 //{----------------------------------------------------------------------------------------------------------------
02831 //}----------------------------------------------------------------------------------------------------------------
02832 
02833 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0,
02834                  unsigned imageFlags = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard;
02835 
02836 //{----------------------------------------------------------------------------------------------------------------
02868 //}----------------------------------------------------------------------------------------------------------------
02869 
02870 bool txDeleteDC (HDC  dc);
02871 
02873 bool txDeleteDC (HDC* dc);
02875 
02876 //{----------------------------------------------------------------------------------------------------------------
02916 //}----------------------------------------------------------------------------------------------------------------
02917 
02918 bool txBitBlt (HDC destImage,   double xDest,       double yDest, double width, double height,
02919                HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY);
02920 
02921 //{----------------------------------------------------------------------------------------------------------------
02936 //}----------------------------------------------------------------------------------------------------------------
02937 
02938 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0);
02939 
02940 //{----------------------------------------------------------------------------------------------------------------
03000 //}----------------------------------------------------------------------------------------------------------------
03001 
03002 bool txTransparentBlt (HDC destImage,   double xDest,       double yDest,       double width, double height,
03003                        HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK);
03004 
03005 //{----------------------------------------------------------------------------------------------------------------
03021 //}----------------------------------------------------------------------------------------------------------------
03022 
03023 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
03024                               COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0);
03025 
03026 //{----------------------------------------------------------------------------------------------------------------
03131 //}----------------------------------------------------------------------------------------------------------------
03132 
03133 bool txAlphaBlend (HDC destImage,   double xDest,       double yDest,       double width, double height,
03134                    HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0);
03135 
03136 //{----------------------------------------------------------------------------------------------------------------
03153 //}----------------------------------------------------------------------------------------------------------------
03154 
03155 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
03156                           double xSource = 0, double ySource = 0, double alpha = 1.0);
03157 
03158 //{----------------------------------------------------------------------------------------------------------------
03187 //}----------------------------------------------------------------------------------------------------------------
03188 
03189 HDC txUseAlpha (HDC image);
03190 
03191 //{----------------------------------------------------------------------------------------------------------------
03217 //}----------------------------------------------------------------------------------------------------------------
03218 
03219 bool txSaveImage (const char filename[], HDC dc = txDC());
03220 
03222 //}
03223 //=================================================================================================================
03224 
03225 //=================================================================================================================
03226 //{          Utility functions
03228 //=================================================================================================================
03230 //{----------------------------------------------------------------------------------------------------------------
03249 //}----------------------------------------------------------------------------------------------------------------
03250 
03251 double txSleep (double time = 0);
03252 
03253 //{----------------------------------------------------------------------------------------------------------------
03338 //}----------------------------------------------------------------------------------------------------------------
03339 
03340 inline int txBegin();
03341 
03342 //{----------------------------------------------------------------------------------------------------------------
03365 //}----------------------------------------------------------------------------------------------------------------
03366 
03367 inline int txEnd();
03368 
03369 //{----------------------------------------------------------------------------------------------------------------
03391 //}----------------------------------------------------------------------------------------------------------------
03392 
03393 inline void txRedrawWindow();
03394 
03395 //{----------------------------------------------------------------------------------------------------------------
03419 //}----------------------------------------------------------------------------------------------------------------
03420 
03421 inline int txUpdateWindow (int update = true);
03422 
03423 //{----------------------------------------------------------------------------------------------------------------
03440 //}----------------------------------------------------------------------------------------------------------------
03441 
03442 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC());
03443 
03444 //{----------------------------------------------------------------------------------------------------------------
03464 //
03465 //                 +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее"
03466 //                 |
03467 //                 v
03468 //               txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03473 //}----------------------------------------------------------------------------------------------------------------
03474 
03475 //     +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее"
03476 //     |
03477 //     v
03478 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture();
03479 
03480 //{----------------------------------------------------------------------------------------------------------------
03496 //}----------------------------------------------------------------------------------------------------------------
03497 
03498 bool txDestroyWindow (HWND wnd = txWindow());
03499 
03500 //{----------------------------------------------------------------------------------------------------------------
03511 //}----------------------------------------------------------------------------------------------------------------
03512 
03513 double txQueryPerformance() tx_nodiscard;
03514 
03515 //{----------------------------------------------------------------------------------------------------------------
03530 //}----------------------------------------------------------------------------------------------------------------
03532 
03533 #if defined (_TX_CPP11)
03534     template <int txFramesToAverage = 5>
03535 #else
03536     const     int txFramesToAverage = 5;
03537 #endif
03538 
03540 
03541 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard;
03542 
03544 //}
03545 
03546 //=================================================================================================================
03547 //{          Mouse functions
03549 //=================================================================================================================
03551 //{----------------------------------------------------------------------------------------------------------------
03575 //}----------------------------------------------------------------------------------------------------------------
03576 
03577 inline POINT txMousePos() tx_nodiscard;
03578 
03579 //{----------------------------------------------------------------------------------------------------------------
03599 //}----------------------------------------------------------------------------------------------------------------
03600 
03601 inline double txMouseX() tx_nodiscard;
03602 
03603 //{----------------------------------------------------------------------------------------------------------------
03623 //}----------------------------------------------------------------------------------------------------------------
03624 
03625 inline double txMouseY() tx_nodiscard;
03626 
03627 //{----------------------------------------------------------------------------------------------------------------
03659 //}----------------------------------------------------------------------------------------------------------------
03660 
03661 inline unsigned txMouseButtons() tx_nodiscard;
03662 
03663 //{----------------------------------------------------------------------------------------------------------------
03695 //}----------------------------------------------------------------------------------------------------------------
03696 
03697 #ifdef FOR_DOXYGEN_ONLY
03698 inline Mouse& txCatchMouse (bool shouldEat = true);
03699 #endif
03700 
03702 //}
03703 //=================================================================================================================
03704 
03705 //=================================================================================================================
03706 //{          Console functions
03708 //=================================================================================================================
03710 //{----------------------------------------------------------------------------------------------------------------
03752 //}----------------------------------------------------------------------------------------------------------------
03753 
03754 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/);
03755 
03756 //{----------------------------------------------------------------------------------------------------------------
03768 //}----------------------------------------------------------------------------------------------------------------
03769 
03770 unsigned txGetConsoleAttr() tx_nodiscard;
03771 
03772 //{----------------------------------------------------------------------------------------------------------------
03786 //}----------------------------------------------------------------------------------------------------------------
03787 
03788 bool txClearConsole();
03789 
03790 //{----------------------------------------------------------------------------------------------------------------
03810 //}----------------------------------------------------------------------------------------------------------------
03811 
03812 POINT txSetConsoleCursorPos (double x, double y);
03813 
03814 //{----------------------------------------------------------------------------------------------------------------
03827 //}----------------------------------------------------------------------------------------------------------------
03828 
03829 POINT txGetConsoleCursorPos();
03830 
03831 //{----------------------------------------------------------------------------------------------------------------
03844 //}----------------------------------------------------------------------------------------------------------------
03845 
03846 POINT txGetConsoleExtent();
03847 
03848 //{----------------------------------------------------------------------------------------------------------------
03862 //}----------------------------------------------------------------------------------------------------------------
03863 
03864 POINT txGetConsoleFontSize() tx_nodiscard;
03865 
03866 //{----------------------------------------------------------------------------------------------------------------
03882 //}----------------------------------------------------------------------------------------------------------------
03883 
03884 bool txTextCursor (bool blink = true);
03885 
03887 //}
03888 //=================================================================================================================
03889 
03890 //=================================================================================================================
03891 //{          Other staff not related to drawing
03893 //=================================================================================================================
03895 //{----------------------------------------------------------------------------------------------------------------
03924 //}----------------------------------------------------------------------------------------------------------------
03925 
03926 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC);
03927 
03928 //{----------------------------------------------------------------------------------------------------------------
03990 //}----------------------------------------------------------------------------------------------------------------
03991 
03992 int txSpeak (const char* text, ...) tx_printfy (1);
03993 
03994 //{----------------------------------------------------------------------------------------------------------------
04111 //}----------------------------------------------------------------------------------------------------------------
04112 
04113 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
04114                        double zoom = 0, double gain = 1, HWND wnd = txWindow());
04115 
04116 //{----------------------------------------------------------------------------------------------------------------
04130 //}----------------------------------------------------------------------------------------------------------------
04131 
04132 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow());
04133 
04134 //{----------------------------------------------------------------------------------------------------------------
04190 //}----------------------------------------------------------------------------------------------------------------
04191 
04192 bool txGetAsyncKeyState (int key);
04193 
04194 //{----------------------------------------------------------------------------------------------------------------
04231 //}----------------------------------------------------------------------------------------------------------------
04232 
04233 #ifdef FOR_DOXYGEN_ONLY
04234 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3);
04235 #endif
04236 
04237 //{----------------------------------------------------------------------------------------------------------------
04262 //}----------------------------------------------------------------------------------------------------------------
04263 
04264 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1);
04265 
04266 //{----------------------------------------------------------------------------------------------------------------
04342 //}----------------------------------------------------------------------------------------------------------------
04343 
04344 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04345 
04346 template <typename T, typename... ArgsT>
04347 int txPrintf (const char* format, ArgsT... args);
04348 
04349 #define TX_PRINTF(...)  ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) )
04350 
04351 #endif
04352 
04353 //-----------------------------------------------------------------------------------------------------------------
04354 
04355 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY)
04356 
04357 enum width_t     : int {};
04358 enum precision_t : int {};
04359 
04360 inline width_t     width     (int width) { return (width_t)     width; }
04361 inline precision_t precision (int prec)  { return (precision_t) prec;  }
04362 
04363 #endif
04364 
04365 //{----------------------------------------------------------------------------------------------------------------
04384 //}----------------------------------------------------------------------------------------------------------------
04385 
04386 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04387 
04388 template <typename T, typename... ArgsT>
04389 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args);
04390 
04391 #endif
04392 
04393 //{----------------------------------------------------------------------------------------------------------------
04413 //}----------------------------------------------------------------------------------------------------------------
04414 
04415 #if defined (_TX_CPP11) ||  defined (FOR_DOXYGEN_ONLY)
04416 
04417 template <typename T, typename... ArgsT>
04418 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args);
04419 
04420 #endif
04421 
04422 //{----------------------------------------------------------------------------------------------------------------
04440 //}----------------------------------------------------------------------------------------------------------------
04441 
04442 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY)
04443 
04444 template <typename... ArgsT>
04445 std::string txFormat (const char* format, ArgsT... args);
04446 
04447 #endif
04448 
04449 //{----------------------------------------------------------------------------------------------------------------
04521 //}----------------------------------------------------------------------------------------------------------------
04523 
04524 #define sizearr( arr )  ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) )
04525 
04527 //  See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx
04528 
04529 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N];  // ;=P
04530 
04531 //  Another approach
04532 
04533 #if defined (_TX_CPP11_MSVC15)
04534 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; }
04535 #endif
04536 
04538 
04539 #define SIZEARR( arr )  ( sizeof (arr) / sizeof ((arr)[0]) )
04540 
04542 //{----------------------------------------------------------------------------------------------------------------
04561 //}----------------------------------------------------------------------------------------------------------------
04562 
04563 inline int random (int range) tx_deprecated;
04564 
04565 //{----------------------------------------------------------------------------------------------------------------
04590 //}----------------------------------------------------------------------------------------------------------------
04591 
04592 inline double random (double left, double right)                tx_nodiscard tx_deprecated;
04593 
04594 inline double random (std::nomeow_t, double left, double right) tx_nodiscard;
04595 
04596 //{----------------------------------------------------------------------------------------------------------------
04626 //}----------------------------------------------------------------------------------------------------------------
04627 
04628 template <typename Tx, typename Ta, typename Tb>
04629 inline bool In (Tx x, Ta a, Tb b)                tx_nodiscard tx_deprecated;
04630 
04631 template <typename Tx, typename Ta, typename Tb>
04632 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated;
04633 
04634 //{----------------------------------------------------------------------------------------------------------------
04680 //}----------------------------------------------------------------------------------------------------------------
04682 
04683 inline bool In (const POINT& pt, const RECT& rect)                      tx_nodiscard tx_deprecated;
04684 inline bool In (const COORD& pt, const SMALL_RECT& rect)                tx_nodiscard tx_deprecated;
04685 
04687 
04688 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)       tx_nodiscard tx_deprecated;
04689 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated;
04690 
04691 //{----------------------------------------------------------------------------------------------------------------
04710 //}----------------------------------------------------------------------------------------------------------------
04711 
04712 #define MAX( a, b )     ( ((a) > (b))? (a) : (b) )
04713 
04714 template <typename T>
04715 T max (const T& a, const T& b) { return (a > b)? a : b; }  
04716 
04717 //{----------------------------------------------------------------------------------------------------------------
04736 //}----------------------------------------------------------------------------------------------------------------
04737 
04738 #define MIN( a, b )     ( ((a) < (b))? (a) : (b) )
04739 
04740 template <typename T>
04741 T min (const T& a, const T& b) { return (a < b)? a : b; }  
04742 
04743 //{----------------------------------------------------------------------------------------------------------------
04757 //}----------------------------------------------------------------------------------------------------------------
04758 
04759 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L  // MSVC: C99 case
04760 
04761     #define ROUND( x )  ( (long) round (x) )
04762 
04763 #else
04764 
04765     #define ROUND( x )  ( (long) floor ((x) + 0.5) )
04766 
04767 #endif
04768 
04769 //{----------------------------------------------------------------------------------------------------------------
04784 //}----------------------------------------------------------------------------------------------------------------
04785 
04786 uint64_t txHash (const void* buffer, size_t size) tx_nodiscard;
04787 
04788 //{----------------------------------------------------------------------------------------------------------------
04807 //}----------------------------------------------------------------------------------------------------------------
04808 
04809 void tx_fpreset();
04810 
04811 //{----------------------------------------------------------------------------------------------------------------
04820 //}----------------------------------------------------------------------------------------------------------------
04821 
04822 const double txPI = asin (1.0) * 2;
04823 
04824 //{----------------------------------------------------------------------------------------------------------------
04851 //}----------------------------------------------------------------------------------------------------------------
04852 
04853 inline double txSqr (double x)
04854     {
04855     double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0));  // Бурная вычислительная деятельность
04856 
04857     char str[1024] = "";
04858     _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr);
04859     txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL ||
04860         (
04861         txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION),
04862         txMessageBox ("Уйду я от вас", "Злые вы...",  MB_ICONSTOP),
04863         exit (EXIT_FAILURE), 0  //-V2509 //-V2014
04864         );
04865 
04866     txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика!  \0"  // А как это работает, а?  //-V111
04867                                      "С ума сойти...      \0"  //
04868                                      "а КЭП подтверждает  \0"  //       и кто это будет
04869                                      "Главное - отчитаться\0"  //       поддерживать?..
04870                                      "Невероятно, но факт \0"
04871                                      "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21);
04872 
04873     return sqr;  // Все же вернем значение. Мы же не звери
04874     }
04875 
04876 //{----------------------------------------------------------------------------------------------------------------
04898 //}----------------------------------------------------------------------------------------------------------------
04899 
04900 #ifdef FOR_DOXYGEN_ONLY
04901 #define _TX_DESTROY_3D
04902 #endif
04903 
04904 #if defined (_TX_DESTROY_3D)
04905 
04906     #define z  0                   // Читайте "Флатландию" Эбботта!
04907 
04908 #endif
04909 
04910 //{----------------------------------------------------------------------------------------------------------------
04927 //}----------------------------------------------------------------------------------------------------------------
04929 
04930 #define meow   ;
04931 
04932 #if defined (_MSC_VER) && !defined (_CLANG_VER)
04933 #define мяу    meow
04934 #endif
04935 
04936 #define please
04937 
04939 
04940 //{----------------------------------------------------------------------------------------------------------------
04958 //}----------------------------------------------------------------------------------------------------------------
04959 
04960 #define ZERO( type )    zero <type> ()
04961 
04963 template <typename T> inline T zero() tx_nodiscard;
04965 
04966 //{----------------------------------------------------------------------------------------------------------------
04993 //}----------------------------------------------------------------------------------------------------------------
04995 
04996 #define  tx_auto_func(    func )  _tx_auto_fun1 ( __LINE__, func )
04997 #define _tx_auto_fun1( n, func )  _tx_auto_fun2 ( n,        func )
04998 #define _tx_auto_fun2( n, func )  auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; })
04999 
05000 #define tx_finally(...)           tx_auto_func (__VA_ARGS__)
05001 
05002 template <typename T>
05003 struct _tx_auto_func_
05004     {
05005     typedef _tx_auto_func_<T> this_t;
05006     T func_;
05007 
05008     explicit _tx_auto_func_ (T func) : func_ (func) {}
05009             ~_tx_auto_func_ ()       { func_ ();     }
05010 
05011     private:         _tx_auto_func_ ()              _tx_delete;
05012                      _tx_auto_func_ (const this_t&) _tx_delete;
05013              this_t& operator =     (const this_t&) _tx_delete;
05014     };
05015 
05016 template <typename T>
05017 _tx_auto_func_<T> _tx_auto_func  (T   func)
05018     {
05019     return        _tx_auto_func_ <T> (func);
05020     }
05021 
05023 
05024 //{----------------------------------------------------------------------------------------------------------------
05069 //}----------------------------------------------------------------------------------------------------------------
05070 
05071 #if !defined (NDEBUG)
05072     #undef  TX_ASSERT
05073     #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \
05074                                                            "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 )
05075 #else
05076     #undef  TX_ASSERT
05077     #define TX_ASSERT( cond ) ((void) 1)
05078 
05079 #endif
05080 
05081 #ifdef assert
05082     #undef assert
05083 #endif
05084 
05085 #define assert( cond )        TX_ASSERT (cond)
05086 
05087 //{----------------------------------------------------------------------------------------------------------------
05114 //}----------------------------------------------------------------------------------------------------------------
05115 
05116 #if !defined (NDEBUG)
05117     #define asserted          || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.")
05118 
05119 #else
05120     #define asserted          || _txNOP (0)
05121 
05122 #endif
05123 
05124 #define verified              asserted  //!< For compatibility with assert macro
05125 
05127 #define TX_NEEDED             asserted  //!< For compatibility with earlier releases
05128 
05129 
05130 //{----------------------------------------------------------------------------------------------------------------
05158 //}----------------------------------------------------------------------------------------------------------------
05159 
05160 #if !defined (NDEBUG)
05161     #undef  verify
05162     #define verify            assert
05163 
05164 #else
05165     #undef  verify
05166     #define verify( expr )    ( expr )
05167 
05168 #endif
05169 
05170 //{----------------------------------------------------------------------------------------------------------------
05189 //}----------------------------------------------------------------------------------------------------------------
05190 
05191 #if !defined (FOR_DOXYGEN_ONLY)
05192     #define TX_ERROR( ... )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__)
05193 #else
05194     #define TX_ERROR( msg )   ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg)
05195 #endif
05196 
05198     #define TX_THROW          TX_ERROR  //!< For compatibility with earlier TXLib releases
05199 
05200 
05201 //{----------------------------------------------------------------------------------------------------------------
05217 //}----------------------------------------------------------------------------------------------------------------
05218 
05219 #if !defined (NDEBUG)
05220     #define TX_DEBUG_ERROR(...)  TX_ERROR (__VA_ARGS__)
05221 
05222 #else
05223     #define TX_DEBUG_ERROR(...)  ((void) 0)
05224 
05225 #endif
05226 
05227 //{----------------------------------------------------------------------------------------------------------------
05247 //}----------------------------------------------------------------------------------------------------------------
05248 
05249 #ifdef FOR_DOXYGEN_ONLY
05250 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05251 #endif
05252 
05254 
05255 #ifdef _MSC_VER
05256 #define txDump( ... )           _txDump ((const void*)(uintptr_t) __VA_ARGS__)
05257 #else
05258 #define txDump( address, ... )  _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__)
05259 #endif
05260 
05261 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true);
05262 
05264 
05265 //{----------------------------------------------------------------------------------------------------------------
05291 //}----------------------------------------------------------------------------------------------------------------
05292 
05293 #define txStackBackTrace()    _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true);
05294 
05295 //{----------------------------------------------------------------------------------------------------------------
05317 //}----------------------------------------------------------------------------------------------------------------
05319 
05320 std::string txDemangle (const char* mangledName);
05321 char*       txDemangle (const char* mangledName, std::nomeow_t);
05322 
05323 #define txTypename(value)     txDemangle (typeid (value) .name()) .c_str()
05324 
05326 //{----------------------------------------------------------------------------------------------------------------
05353 //}----------------------------------------------------------------------------------------------------------------
05354 
05355 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue);
05356 
05357 //{----------------------------------------------------------------------------------------------------------------
05370 //}----------------------------------------------------------------------------------------------------------------
05372 
05373 #define _                     ,
05374 #define TX_COMMA              ,  //!< Синоним макроса _ (@ref _ "символ подчеркивания")
05375 
05377 
05378 //{----------------------------------------------------------------------------------------------------------------
05438 //}----------------------------------------------------------------------------------------------------------------
05439 
05440 #ifdef FOR_DOXYGEN_ONLY
05441 
05442     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType )
05443 
05444 #else
05445 
05446     // Hand-made DLLIMPORT helper
05447 
05448     #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... )               \
05449             retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \
05450                                                             _txDllImport ((libName), #funcName, (required))
05451 #endif
05452 
05454 //}
05455 //=================================================================================================================
05456 
05457 //=================================================================================================================
05458 //{          Back-hole (I hope, not an ass-hole:) of the library)
05460 //=================================================================================================================
05462 //{----------------------------------------------------------------------------------------------------------------
05614 //}----------------------------------------------------------------------------------------------------------------
05615 
05616 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL);
05617 
05618 //{----------------------------------------------------------------------------------------------------------------
05643 //}----------------------------------------------------------------------------------------------------------------
05644 
05645 bool txLock (bool wait = true);
05646 
05647 //{----------------------------------------------------------------------------------------------------------------
05658 //}----------------------------------------------------------------------------------------------------------------
05660 
05661 bool txUnlock();
05662 
05664 template <typename T> inline T txUnlock (T value);
05666 
05668 
05669 //{----------------------------------------------------------------------------------------------------------------
05692 //}----------------------------------------------------------------------------------------------------------------
05693 
05694 #define txGDI( command, dc )  ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) )
05695 
05696 //{----------------------------------------------------------------------------------------------------------------
05719 //}----------------------------------------------------------------------------------------------------------------
05720 
05721 #ifndef   FOR_DOXYGEN_ONLY
05722 
05723 const int     _TX_CODEPAGE  =   1251;
05724 
05725 #ifndef __CYGWIN__
05726 const char    _TX_LOCALE[]  =  "Russian";
05727 #else
05728 const char    _TX_LOCALE[]  =  "ru_RU.CP1251";
05729 #endif
05730 
05731 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP";
05732 
05733 #endif
05734 
05735 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE);
05736 
05737 //{----------------------------------------------------------------------------------------------------------------
05752 //}----------------------------------------------------------------------------------------------------------------
05753 
05754 int txPause (const char* message, ...) tx_printfy (1);
05755 
05757 //}
05758 //=================================================================================================================
05759 
05760 //=================================================================================================================
05761 //{          Tune-up constants and variables
05763 //=================================================================================================================
05765 //{----------------------------------------------------------------------------------------------------------------
05775 //}----------------------------------------------------------------------------------------------------------------
05776 
05777 #ifndef TX_COMPILED
05778 
05779        char _txLogName[MAX_PATH]          = "~TXLog.log";
05780 
05781 #endif // TX_COMPILED
05782 
05783 extern char _txLogName[];
05784 
05785 //{----------------------------------------------------------------------------------------------------------------
05817 //}----------------------------------------------------------------------------------------------------------------
05818 
05819 #if  defined  (_TX_NOINIT)
05820 
05821     #undef     _TX_NOINIT
05822     #define    _TX_NOINIT                 1
05823 
05824 #else
05825 
05826     #define    _TX_NOINIT                 0
05827 
05828 #endif
05829 
05830 //{----------------------------------------------------------------------------------------------------------------
05874 //}----------------------------------------------------------------------------------------------------------------
05875 
05876 #if !defined (TX_CONSOLE_MODE)
05877 
05878     #define   TX_CONSOLE_MODE             SW_HIDE
05879 
05880 #endif
05881 
05882 //{----------------------------------------------------------------------------------------------------------------
05886 //}----------------------------------------------------------------------------------------------------------------
05887 
05888 #if !defined (TX_CONSOLE_FONT)
05889 
05890     #define   TX_CONSOLE_FONT             "Lucida Console"
05891 
05892 #endif
05893 
05894 //{----------------------------------------------------------------------------------------------------------------
05905 //}----------------------------------------------------------------------------------------------------------------
05906 
05907 #ifndef TX_COMPILED
05908 
05909        int _txWindowStyle                 = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
05910 
05911 #endif // TX_COMPILED
05912 
05913 extern int _txWindowStyle;
05914 
05915 //{----------------------------------------------------------------------------------------------------------------
05918 //}----------------------------------------------------------------------------------------------------------------
05919 
05920 #ifndef TX_COMPILED
05921 
05922        unsigned _txCursorBlinkInterval    = 500;
05923 
05924 #endif // TX_COMPILED
05925 
05926 extern unsigned _txCursorBlinkInterval;
05927 
05928 //{----------------------------------------------------------------------------------------------------------------
05932 //}----------------------------------------------------------------------------------------------------------------
05933 
05934 #ifndef TX_COMPILED
05935 
05936        unsigned _txWindowUpdateInterval   = 25;
05937 
05938 #endif // TX_COMPILED
05939 
05940 extern unsigned _txWindowUpdateInterval;
05941 
05942 //{----------------------------------------------------------------------------------------------------------------
05951 //}----------------------------------------------------------------------------------------------------------------
05952 
05953 #ifdef FOR_DOXYGEN_ONLY
05954 #define       TX_USE_SFML
05955 #endif
05956 
05957 //{----------------------------------------------------------------------------------------------------------------
05960 //}----------------------------------------------------------------------------------------------------------------
05961 
05962 const int _TX_TIMEOUT                     = 1000
05963 
05964 #if  defined  (_TX_ALLOW_TRACE)
05965     * 2
05966 #endif
05967 
05968 #if  defined  (TX_TRACE)
05969     * 3
05970 #endif
05971 
05972 #if  defined  (_TX_USE_DEVPARTNER)
05973     * 10
05974 #endif
05975     ;
05976 
05977 //{----------------------------------------------------------------------------------------------------------------
06018 //}----------------------------------------------------------------------------------------------------------------
06019 
06020 #ifndef TX_COMPILED
06021 
06022        bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
06023                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp) = NULL;
06024 
06025 #endif // TX_COMPILED
06026 
06027 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest,
06028                                HDC src,  int xSrc,  int ySrc,  int wSrc,  int hSrc, DWORD rOp);
06029 
06030 //{----------------------------------------------------------------------------------------------------------------
06033 //}----------------------------------------------------------------------------------------------------------------
06034 
06035 const unsigned _TX_BUFSIZE                =  1024,
06036                _TX_BIGBUFSIZE             = _TX_BUFSIZE *  2,  
06037                _TX_HUGEBUFSIZE            = _TX_BUFSIZE * 20,  
06038 
06039                _TX_STACKSIZE              = 64 * 1024;         
06040 
06041 //{----------------------------------------------------------------------------------------------------------------
06044 //}----------------------------------------------------------------------------------------------------------------
06045 
06046 #if !defined (_TX_EXCEPTIONS_LIMIT)
06047     #define   _TX_EXCEPTIONS_LIMIT        16
06048 #endif
06049 
06050 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT)
06051     #define   _TX_FATAL_EXCEPTIONS_LIMIT  16                   //!< Максимальное количество фатальных исключений.
06052 #endif
06053 
06054 //{----------------------------------------------------------------------------------------------------------------
06057 //}----------------------------------------------------------------------------------------------------------------
06058 
06059 #ifdef FOR_DOXYGEN_ONLY
06060 #define       _TX_FULL_STACKTRACE
06061 #endif
06062 
06063 //{----------------------------------------------------------------------------------------------------------------
06066 //}----------------------------------------------------------------------------------------------------------------
06067 
06068 #ifndef TX_COMPILED
06069 
06070        bool _txProcessSystemWarnings      = true;
06071 
06072 #endif // TX_COMPILED
06073 
06074 extern bool _txProcessSystemWarnings;
06075 
06076 //{----------------------------------------------------------------------------------------------------------------
06090 //}----------------------------------------------------------------------------------------------------------------
06091 
06092 #if !defined  (_TX_WAITABLE_PARENTS)
06093     #define    _TX_WAITABLE_PARENTS       "Winpty-agent.exe:Clion.exe, "            /* 0: CLion32       */ \
06094                                           "Winpty-agent.exe:Clion64.exe, "          /* 1: CLion64       */ \
06095                                           "starter.exe:eclipse.exe, "               /* 2: Eclipse 4     */ \
06096                                           "starter.exe:javaw.exe, "                 /* 3: Eclipse 3     */ \
06097                                           "cmd.exe:devenv.exe, "                    /* 4: MSVS 2003+    */ \
06098                                           "VSDebugConsole.exe:devenv.exe, "         /* 5: MSVS 2019+    */ \
06099                                           "VSDebugConsole.exe:msvsmon.exe, "        /* 6: MSVS 2022 x86 */ \
06100                                           "consolepauser.exe:devcpp.exe, "          /* 7: Dev-Cpp       */ \
06101                                           "cb_console_runner.exe:codeblocks.exe"    /* 8: CodeBlocks 8+ */
06102 #endif
06103 
06104 //{----------------------------------------------------------------------------------------------------------------
06123 //}----------------------------------------------------------------------------------------------------------------
06124 
06125 #if !defined (_TX_ALLOW_KILL_PARENT)            // DISCLAIMER: Я не призываю к убийству родителей.
06126     #define   _TX_ALLOW_KILL_PARENT       true  //             Это технический термин.
06127 #endif                                          //             г_дам юристам привет.
06128 
06129 //{----------------------------------------------------------------------------------------------------------------
06139 //}----------------------------------------------------------------------------------------------------------------
06140 
06141 #ifndef TX_COMPILED
06142 
06143        int    _txWatchdogTimeout          = 10*_TX_TIMEOUT;
06144 
06145 #endif // TX_COMPILED
06146 
06147 extern int    _txWatchdogTimeout;
06148 
06149 //{----------------------------------------------------------------------------------------------------------------
06218 //}----------------------------------------------------------------------------------------------------------------
06220 
06221 #ifdef FOR_DOXYGEN_ONLY
06222 
06223     #define TX_COMPILED
06224 
06225     #endif
06226 
06228 
06230 //}
06231 //=================================================================================================================
06232 
06233 //=================================================================================================================
06234 //{          Internal diagnostics
06236 //=================================================================================================================
06238 //{----------------------------------------------------------------------------------------------------------------
06278 //}----------------------------------------------------------------------------------------------------------------
06279 
06280 #ifdef FOR_DOXYGEN_ONLY
06281 #define _TX_ALLOW_TRACE
06282 #endif
06283 
06284 //{----------------------------------------------------------------------------------------------------------------
06314 //}----------------------------------------------------------------------------------------------------------------
06315 
06316 #ifdef FOR_DOXYGEN_ONLY
06317 #define       TX_TRACE
06318 #endif
06319 
06320 #if !defined (TX_TRACE)
06321     #define   TX_TRACE  { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); }
06322 #endif
06323 
06325 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...);
06327 
06328 //{----------------------------------------------------------------------------------------------------------------
06331 
06332 #ifndef   FOR_DOXYGEN_ONLY
06333 
06334 struct _txLoc
06335     {
06336     const char*   func;
06337     const char*   file;
06338     int           line;
06339 
06340     int           inTX;   // We are inside one of TXLib functions
06341     int           trace;  // Internal TX trace level, when enabled by _TX_ALLOW_TRACE
06342 
06343     const _txLoc* prev;   // Caller's location
06344 
06345     static _txLoc _tx_thread Cur;
06346     };
06347 
06348 struct _txFuncEntry
06349     {
06350     typedef _txFuncEntry this_t;
06351 
06352     _txLoc loc;
06353 
06354     _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; }
06355     void restore()                     { _txLoc::Cur = loc;                           }
06356    ~_txFuncEntry()                     { restore();                                   }
06357 
06358     private:
06359             _txFuncEntry (const this_t&) _tx_delete;
06360     this_t& operator =   (const this_t&) _tx_delete;
06361     };
06362 
06363 #if defined (_GCC_VER)
06364 
06365     inline const char* _txLocSet (_txLoc* _loc, const char* _file, int _line, const char* _func)
06366         { _loc->file = _file; _loc->line = _line; _loc->func = _func; return _func; }
06367 
06368 #else
06369 
06370     #define _txLocSet( _loc, _file, _line, _func ) \
06371         ( (_loc)->file = (_file), (_loc)->line = (_line), (_loc)->func = (_func) )
06372 
06373 #endif
06374 
06375 #define _txLocCurSet()     _txLocSet (&_txLoc::Cur, __FILE__, __LINE__, __TX_FUNCTION__)
06376 
06377 #define _txLocLvlSet(lvl)  { _txLoc::Cur.trace = (lvl); }
06378 
06379 //{----------------------------------------------------------------------------------------------------------------
06380 
06381 #if defined ($0)
06382     #undef   $0
06383     #endif
06384 
06385 #if defined ($1)
06386     #undef   $1
06387     #endif
06388 
06389 #if defined ($2)
06390     #undef   $2
06391     #endif
06392 
06393 #if defined ($3)
06394     #undef   $3
06395     #endif
06396 
06397 #if defined ($4)
06398     #undef   $4
06399     #endif
06400 
06401 #if defined ($5)
06402     #undef   $5
06403     #endif
06404 
06405 #if defined ($6)
06406     #undef   $6
06407     #endif
06408 
06409 #if defined ($7)
06410     #undef   $7
06411     #endif
06412 
06413 #if defined ($8)
06414     #undef   $8
06415     #endif
06416 
06417 #if defined ($9)
06418     #undef   $9
06419     #endif
06420 
06421 #if defined ($)
06422     #undef   $
06423     #endif
06424 
06425 #if defined ($$)
06426     #undef   $$
06427     #endif
06428 
06429 //}
06430 //-----------------------------------------------------------------------------------------------------------------
06431 
06432 #if defined (_TX_ALLOW_TRACE)
06433 
06434     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl);    $;          }
06435 
06436     #define  $           { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } }
06437 
06438     #define  $$          { __txFuncEntry.restore();                                                  }
06439 
06440 #elif defined (_DEBUG)
06441 
06442     #define _txEntry(lvl)  _txFuncEntry __txFuncEntry; {                                 $;          }
06443 
06444     #define  $           { _txLocCurSet();                                                           }
06445 
06446     #define  $$          { __txFuncEntry.restore();                                                  }
06447 
06448 #else
06449 
06450     #define _txEntry(lvl)  ;
06451     #define  $             ;
06452     #define  $$            ;
06453 
06454 #endif
06455 
06456 //{----------------------------------------------------------------------------------------------------------------
06457 
06458 #define      $0            _txEntry (0)  // (Log level unchanged)
06459 #define      $1            _txEntry (1)  // Regular functions
06460 #define      $2            _txEntry (2)  // Resvd
06461 #define      $3            _txEntry (3)  // Init/Cleanup
06462 #define      $4            _txEntry (4)  // Init/Cleanup, misc functions
06463 #define      $5            _txEntry (5)  // Error handling, entry points
06464 #define      $6            _txEntry (6)  // Error handling, main part
06465 #define      $7            _txEntry (7)  // Error handling, misc functions
06466 #define      $8            _txEntry (8)  // Canvas worker thread
06467 #define      $9            _txEntry (9)  // Resvd
06468 
06469 //}
06470 //-----------------------------------------------------------------------------------------------------------------
06471 
06472 #endif // FOR_DOXYGEN_ONLY
06473 
06476 //}----------------------------------------------------------------------------------------------------------------
06477 
06479 //}
06480 //=================================================================================================================
06481 
06482 //=================================================================================================================
06483 //{          Sweet critical section blocking: txAutoLock class
06484 //=================================================================================================================
06485 
06486 //{----------------------------------------------------------------------------------------------------------------
06502 //}----------------------------------------------------------------------------------------------------------------
06503 
06505 extern CRITICAL_SECTION _txCanvas_LockBackBuf;
06507 
06508 class txAutoLock
06509     {
06510     typedef txAutoLock this_t;
06511 
06512     public:
06513 
06514 //{----------------------------------------------------------------------------------------------------------------
06537 //}----------------------------------------------------------------------------------------------------------------
06538 
06539     explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) :
06540         cs_ (cs)
06541         {
06542 $1      if (!cs_) return;
06543 
06544         if (mandatory) {$    EnterCriticalSection (cs_);                   }
06545         else           {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); }
06546         }
06547 
06548 //{----------------------------------------------------------------------------------------------------------------
06561 //}----------------------------------------------------------------------------------------------------------------
06562 
06563     explicit txAutoLock (bool mandatory = true) :
06564         cs_ (NULL)
06565         {
06566 $1      new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory);
06567         }
06568 
06569 //{----------------------------------------------------------------------------------------------------------------
06571 //}----------------------------------------------------------------------------------------------------------------
06572 
06573    ~txAutoLock()
06574         {
06575 $1      if (!cs_) return;
06576 $       LeaveCriticalSection (cs_); cs_ = NULL;
06577         }
06578 
06579 //{----------------------------------------------------------------------------------------------------------------
06582 //}----------------------------------------------------------------------------------------------------------------
06583 
06584     operator bool () const
06585         {
06586 $1      return (cs_ != NULL);
06587         }
06588 
06589 //{----------------------------------------------------------------------------------------------------------------
06591 //}----------------------------------------------------------------------------------------------------------------
06592 
06593 //  private:
06594     CRITICAL_SECTION* cs_;
06595 
06596 //{----------------------------------------------------------------------------------------------------------------
06598 //}----------------------------------------------------------------------------------------------------------------
06600 
06601     private:
06602             txAutoLock (const this_t&) _tx_delete;
06603     this_t& operator = (const this_t&) _tx_delete;
06604 
06606 
06607     };
06608 
06609 //}
06610 //=================================================================================================================
06611 
06612 //=================================================================================================================
06613 //{          Dialogs: txDialog class
06615 //=================================================================================================================
06617 //{----------------------------------------------------------------------------------------------------------------
06638 //}----------------------------------------------------------------------------------------------------------------
06639 
06640 struct txDialog
06641     {
06642     typedef txDialog this_t;
06643 
06644 //{----------------------------------------------------------------------------------------------------------------
06657 //}----------------------------------------------------------------------------------------------------------------
06658 
06659     public:
06660     enum CONTROL
06661         {
06662         DIALOG    = (int) 0x00000000,            
06663         BUTTON    = (int) 0xFFFF0080,            
06664         EDIT      = (int) 0xFFFF0081,            
06665         STATIC    = (int) 0xFFFF0082,            
06666         LISTBOX   = (int) 0xFFFF0083,            
06667         SCROLLBAR = (int) 0xFFFF0084,            
06668         COMBOBOX  = (int) 0xFFFF0085,            
06669         END       = (int) 0x00000000             
06670         };
06671 
06672 //{----------------------------------------------------------------------------------------------------------------
06689 //}----------------------------------------------------------------------------------------------------------------
06690 
06691     public:
06692     struct Layout
06693         {                                        //-V802
06694         CONTROL     wndclass;                    
06695         const char* caption;                     
06696         WORD        id;                          
06697         short        x;                          
06698         short        y;                          
06699         short       sx;                          
06700         short       sy;                          
06701         DWORD       style;                       
06702 
06703         const char* font;                        
06704         WORD        fontsize;                    
06705         };
06706 
06707 //{----------------------------------------------------------------------------------------------------------------
06715 //}----------------------------------------------------------------------------------------------------------------
06716 
06717     public:
06718     txDialog();
06719 
06720 //{----------------------------------------------------------------------------------------------------------------
06730 //}----------------------------------------------------------------------------------------------------------------
06731 
06732     explicit txDialog (const Layout* layout);
06733 
06734 //{----------------------------------------------------------------------------------------------------------------
06736 //}----------------------------------------------------------------------------------------------------------------
06737 
06738     virtual ~txDialog() {};
06739 
06740 //{----------------------------------------------------------------------------------------------------------------
06752 //}----------------------------------------------------------------------------------------------------------------
06753 
06754     const Layout* setLayout (const Layout *layout);
06755 
06756 //{----------------------------------------------------------------------------------------------------------------
06774 //}----------------------------------------------------------------------------------------------------------------
06775 
06776     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam);
06777 
06778 //{----------------------------------------------------------------------------------------------------------------
06794 //}----------------------------------------------------------------------------------------------------------------
06795 
06796     intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0);
06797 
06798 //{----------------------------------------------------------------------------------------------------------------
06811 //}----------------------------------------------------------------------------------------------------------------
06812 
06813     intptr_t dialogBox (WORD resource);
06814 
06815 //{----------------------------------------------------------------------------------------------------------------
06817 //}----------------------------------------------------------------------------------------------------------------
06818 
06819     private:
06820             txDialog   (const this_t&) _tx_delete;
06821     this_t& operator = (const this_t&) _tx_delete;
06822 
06823 //{----------------------------------------------------------------------------------------------------------------
06825 //}----------------------------------------------------------------------------------------------------------------
06826 
06827     protected:
06828     static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
06829 
06830 //{----------------------------------------------------------------------------------------------------------------
06832 //}----------------------------------------------------------------------------------------------------------------
06833 
06834     private:
06835     const Layout* layout_;
06836     };
06837 
06839 //}
06840 //=================================================================================================================
06841 
06842 //=================================================================================================================
06843 //{          Dialogs: Message Map macros
06845 //=================================================================================================================
06847 //{----------------------------------------------------------------------------------------------------------------
06868 //}----------------------------------------------------------------------------------------------------------------
06869 
06870 #define TX_BEGIN_MESSAGE_MAP()                                                                 \
06871     virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \
06872         {                                                                                      \
06873         int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result;     \
06874                                                                                                \
06875         switch (_msg)                                                                          \
06876             {                                                                                  \
06877             case WM_NULL:
06878 
06879 //{----------------------------------------------------------------------------------------------------------------
06898 //}----------------------------------------------------------------------------------------------------------------
06899 
06900 #define TX_HANDLE( id )                                                                        \
06901             break;                                                                             \
06902             case (id):
06903 
06904 //{----------------------------------------------------------------------------------------------------------------
06924 //}----------------------------------------------------------------------------------------------------------------
06925 
06926 #define TX_COMMAND_MAP                                                                         \
06927             default: break;                                                                    \
06928             }                                                                                  \
06929                                                                                                \
06930         if (_msg == WM_COMMAND) switch (LOWORD (_wParam))                                      \
06931             {                                                                                  \
06932             case 0:
06933 
06934 //{----------------------------------------------------------------------------------------------------------------
06953 //}----------------------------------------------------------------------------------------------------------------
06954 
06955 #define TX_END_MESSAGE_MAP                                                                     \
06956             default: break;                                                                    \
06957             }                                                                                  \
06958                                                                                                \
06959         return FALSE;                                                                          \
06960         }
06961 
06963 //}
06964 //=================================================================================================================
06965 
06966 //=================================================================================================================
06967 //{          Dialogs: txDialog example: txInputBox()
06969 //=================================================================================================================
06971 //{----------------------------------------------------------------------------------------------------------------
06991 //}----------------------------------------------------------------------------------------------------------------
06992 
06993 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard;
06994 
06995 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
06996 
06997 const char* txInputBox (const char* text, const char* caption, const char* input)
06998     {
06999     //-------------------------------------------------------------------------------------------------------------
07000     // Если не указаны параметры, приходится использовать хоть какие-то надписи.
07001     // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название.
07002     //-------------------------------------------------------------------------------------------------------------
07003 
07004     if (!text)    text    = "Введите строку:";
07005     if (!caption) caption = txGetModuleFileName (false);
07006     if (!input)   input   = "";
07007 
07008     //-------------------------------------------------------------------------------------------------------------
07009     // Идентификаторы элементов диалога. Они требуются в GetDlgItemText().
07010     // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически.
07011     // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы
07012     // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения,
07013     // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о
07014     //-------------------------------------------------------------------------------------------------------------
07015 
07016     #define ID_TEXT_  101
07017     #define ID_INPUT_ 102
07018 
07019     //-------------------------------------------------------------------------------------------------------------
07020     // Задание макета (вида) диалога в виде массива структур.
07021     // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив
07022     // становится похож на описание ресурса диалога в .rc-файле.
07023     // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com).
07024     //-------------------------------------------------------------------------------------------------------------
07025 
07026     txDialog::Layout layout[] =
07027 
07028     //----------------------+----------+-----------+-----------------+---------------------------------------------
07029     //     Тип элемента     | Имя      | Иденти-   |   Координаты    | Флаги элементов
07030     //     диалога          | элемента | фикатор   |-----------------| (см. описание элементов
07031     //                      |          | элемента  | X | Y |Шир.|Выс.| окон диалога в MSDN)
07032     //----------------------+----------+-----------+---+---+----+----+---------------------------------------------
07033     //                      |          |           |   |   |    |    |
07034         {{ txDialog::DIALOG,  caption,   0,           0,  0, 240,  85                                                    },
07035          { txDialog::STATIC,  text,      ID_TEXT_,   10, 10, 150,  40, SS_LEFT                                           },
07036          { txDialog::EDIT,    input,     ID_INPUT_,  10, 60, 220,  15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP },
07037          { txDialog::BUTTON,  "&OK",     IDOK,      180, 10,  50,  15, BS_DEFPUSHBUTTON                     | WS_TABSTOP },
07038          { txDialog::BUTTON,  "&Cancel", IDCANCEL,  180, 30,  50,  15, BS_PUSHBUTTON                        | WS_TABSTOP },
07039          { txDialog::END                                                                                                 }};
07040 
07041     //-------------------------------------------------------------------------------------------------------------
07042     // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним.
07043     // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она
07044     // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную
07045     // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее
07046     // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG).
07047     //-------------------------------------------------------------------------------------------------------------
07048     struct inputDlg : txDialog
07049         {
07050         char str [1024];
07051 
07052         //---------------------------------------------------------------------------------------------------------
07053 
07054         inputDlg() :
07055             str()
07056             {}
07057 
07058         //---------------------------------------------------------------------------------------------------------
07059 
07060         TX_BEGIN_MESSAGE_MAP()    // Карта сообщений (на самом деле это начало оконной функции).  //-V2525
07061 
07062             TX_COMMAND_MAP        // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch).
07063 
07064                 //-------------------------------------------------------------------------------------------------
07065                 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия
07066                 // диалога строка ввода умрет и текст уже из нее получить.
07067                 // Этот макрос на самом деле превращается в case из оператора switch.
07068                 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP().
07069                 //-------------------------------------------------------------------------------------------------
07070 
07071                 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1);
07072 
07073         TX_END_MESSAGE_MAP        //-V2522
07074 
07075         //---------------------------------------------------------------------------------------------------------
07076         // Конец внутреннего класса диалога
07077         //---------------------------------------------------------------------------------------------------------
07078         };
07079 
07080     //-------------------------------------------------------------------------------------------------------------
07081     // Убираем дефайны, чтобы потом не мешали.
07082     // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом
07083     // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _.
07084     // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны.
07085     //-------------------------------------------------------------------------------------------------------------
07086 
07087     #undef ID_TEXT_
07088     #undef ID_INPUT_
07089 
07090     //-------------------------------------------------------------------------------------------------------------
07091     // Это статический объект, потому что строка в нем должна жить после завершения функции.
07092     //-------------------------------------------------------------------------------------------------------------
07093 
07094     static inputDlg dlg;
07095 
07096     //-------------------------------------------------------------------------------------------------------------
07097     // Передаем layout и запускаем окно диалога
07098     //-------------------------------------------------------------------------------------------------------------
07099 
07100     dlg.dialogBox (layout);
07101 
07102     //-------------------------------------------------------------------------------------------------------------
07103     // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет
07104     // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать
07105     // синтаксически можно, но ведет к серьезным ошибкам.
07106     //-------------------------------------------------------------------------------------------------------------
07107 
07108     return dlg.str;
07109     }
07110 
07111 #endif // TX_COMPILED
07112 
07114 //}
07115 //=================================================================================================================
07116 
07117 //}
07118 //=================================================================================================================
07119 
07120 //=================================================================================================================
07121 //{          TXLIB IMPLEMENTATION
07122 //           Реализация функций библиотеки
07123 //=================================================================================================================
07125 
07126 //-----------------------------------------------------------------------------------------------------------------
07127 //{          The Includes
07128 //-----------------------------------------------------------------------------------------------------------------
07129 
07130 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07131 
07132 _TX_END_NAMESPACE
07133 
07134 //-----------------------------------------------------------------------------------------------------------------
07135 
07136 #if defined (_MSC_VER)
07137     #pragma warning (push, 3)                    // MSVC: At level /Wall, some std headers emit warnings... O_o
07138 
07139     #pragma warning (disable: 4365)              // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
07140     #pragma warning (disable: 4005)              // 'name': macro redefinition
07141 #endif
07142 
07143 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED)
07144     #undef   __STRICT_ANSI__
07145 #endif
07146 
07147 #undef _
07148 
07149 //-----------------------------------------------------------------------------------------------------------------
07150 
07151 #include <stdarg.h>
07152 #include <io.h>
07153 #include <fcntl.h>
07154 #include <process.h>
07155 #include <signal.h>
07156 #include <setjmp.h>
07157 #include <locale.h>
07158 #include <limits.h>
07159 #include <stdint.h>
07160 
07161 #include <map>
07162 #include <numeric>
07163 #include <exception>
07164 #include <stdexcept>
07165 
07166 #include <tlhelp32.h>
07167 #include <shellapi.h>
07168 
07169 #if defined (_GCC_VER)
07170 
07171 #include <shlobj.h>
07172 
07173 #include <cxxabi.h>
07174 #include <unwind.h>
07175 
07176 #endif
07177 
07178 #if defined (__CYGWIN__)
07179 
07180 #include <stdarg.h>
07181 #include <unistd.h>
07182 #include <termios.h>
07183 
07184 #endif
07185 
07186 #if defined (_MSC_VER)
07187 
07188 #include <new.h>
07189 
07190 #include <shlobj.h>
07191 #include <ntstatus.h>
07192 #include <crtdbg.h>
07193 #include <rtcapi.h>
07194 #include <dbghelp.h>
07195 
07196 #endif
07197 
07198 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800)  // MSVC 2013
07199 #include <inttypes.h>
07200 #endif
07201 
07202 //-----------------------------------------------------------------------------------------------------------------
07203 
07204 #if defined (TX_USE_SPEAK) //--------------------------------------------------------------------------------------
07205 #include <SAPI.h>          // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :(
07206 #endif                     //--------------------------------------------------------------------------------------
07207 
07208 //-----------------------------------------------------------------------------------------------------------------
07209 
07210 #if defined (_MSC_VER)
07211     #pragma warning (pop)                        // MSVC: Restore max level
07212 #endif
07213 
07214 #if defined (__STRICT_ANSI__UNDEFINED)
07215     #define  __STRICT_ANSI__                     // Redefine back
07216 #endif
07217 
07218 #define _ ,
07219 
07220 //-----------------------------------------------------------------------------------------------------------------
07221 
07222 _TX_BEGIN_NAMESPACE
07223 
07224 #endif // TX_COMPILED
07225 
07226 //}
07227 //-----------------------------------------------------------------------------------------------------------------
07228 
07229 //=================================================================================================================
07230 //{          DLL functions import, missing types definitions
07232 //=================================================================================================================
07234 
07235 //-----------------------------------------------------------------------------------------------------------------
07236 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers.
07237 //  Copied from Windows SDK 7.0a.
07238 //-----------------------------------------------------------------------------------------------------------------
07239 
07240 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07241 
07242 namespace Win32 {
07243 
07244 #ifndef AC_SRC_ALPHA
07245 #define AC_SRC_ALPHA                             0x01
07246 #endif
07247 
07248 #ifndef SMTO_ERRORONEXIT
07249 #define SMTO_ERRORONEXIT                         0x0020
07250 #endif
07251 
07252 #ifndef NT_CONSOLE_PROPS_SIG
07253 #define NT_CONSOLE_PROPS_SIG                     0xA0000002
07254 #endif
07255 
07256 #ifndef NIIF_INFO
07257 #define NIIF_INFO                                0x00000001
07258 #define NIIF_WARNING                             0x00000002
07259 #define NIIF_ERROR                               0x00000003
07260 #endif
07261 
07262 #ifndef NIF_INFO
07263 #define NIF_STATE                                0x00000008
07264 #define NIF_INFO                                 0x00000010
07265 #endif
07266 
07267 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
07268 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS   0x00000004
07269 #endif
07270 
07271 #ifndef SYMOPT_CASE_INSENSITIVE
07272 #define SYMOPT_CASE_INSENSITIVE                  0x00000001
07273 #define SYMOPT_UNDNAME                           0x00000002
07274 #define SYMOPT_DEFERRED_LOADS                    0x00000004
07275 #define SYMOPT_NO_CPP                            0x00000008
07276 #define SYMOPT_LOAD_LINES                        0x00000010
07277 #define SYMOPT_OMAP_FIND_NEAREST                 0x00000020
07278 #define SYMOPT_LOAD_ANYTHING                     0x00000040
07279 #define SYMOPT_IGNORE_CVREC                      0x00000080
07280 #define SYMOPT_NO_UNQUALIFIED_LOADS              0x00000100
07281 #define SYMOPT_FAIL_CRITICAL_ERRORS              0x00000200
07282 #define SYMOPT_EXACT_SYMBOLS                     0x00000400
07283 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS            0x00000800
07284 #define SYMOPT_IGNORE_NT_SYMPATH                 0x00001000
07285 #define SYMOPT_INCLUDE_32BIT_MODULES             0x00002000
07286 #define SYMOPT_PUBLICS_ONLY                      0x00004000
07287 #define SYMOPT_NO_PUBLICS                        0x00008000
07288 #define SYMOPT_AUTO_PUBLICS                      0x00010000
07289 #define SYMOPT_NO_IMAGE_SEARCH                   0x00020000
07290 #define SYMOPT_SECURE                            0x00040000
07291 #define SYMOPT_NO_PROMPTS                        0x00080000
07292 #define SYMOPT_ALLOW_ZERO_ADDRESS                0x01000000
07293 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT         0x02000000
07294 #define SYMOPT_FAVOR_COMPRESSED                  0x00800000
07295 #define SYMOPT_FLAT_DIRECTORY                    0x00400000
07296 #define SYMOPT_IGNORE_IMAGEDIR                   0x00200000
07297 #define SYMOPT_OVERWRITE                         0x00100000
07298 #define SYMOPT_DEBUG                             0x80000000
07299 #endif
07300 
07301 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66.
07302 
07303 #ifndef STATUS_LONGJUMP
07304 #define STATUS_LONGJUMP                          0x80000026
07305 #endif
07306 
07307 #ifndef STATUS_POSSIBLE_DEADLOCK
07308 #define STATUS_POSSIBLE_DEADLOCK                 0xC0000194
07309 #endif
07310 
07311 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS
07312 #define STATUS_FLOAT_MULTIPLE_FAULTS             0xC00002B4
07313 #endif
07314 
07315 #ifndef STATUS_STACK_BUFFER_OVERRUN
07316 #define STATUS_STACK_BUFFER_OVERRUN              0xC0000409
07317 #endif
07318 
07319 #ifndef STATUS_ASSERTION_FAILURE
07320 #define STATUS_ASSERTION_FAILURE                 0xC0000420
07321 #endif
07322 
07323 #ifndef STATUS_WX86_BREAKPOINT
07324 #define STATUS_WX86_BREAKPOINT                   0x4000001F
07325 #endif
07326 
07327 #ifndef DBG_PRINTEXCEPTION_C
07328 #define DBG_PRINTEXCEPTION_C                     0x40010006  // OutputDebugStringA() call
07329 #endif
07330 
07331 #ifndef DBG_PRINTEXCEPTION_WIDE_C
07332 #define DBG_PRINTEXCEPTION_WIDE_C                0x4001000A  // OutputDebugStringW() call
07333 #endif
07334 
07335 #ifndef DBG_THREAD_NAME
07336 #define DBG_THREAD_NAME                          0x406D1388
07337 #endif
07338 
07339 #define EXCEPTION_CPP_MSC                        0xE06D7363  // '?msc'
07340 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1       0x19930520  // '?msc' version magic, see ehdata.h
07341 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2       0x19930521  // '?msc' version magic
07342 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3       0x19930522  // '?msc' version magic
07343 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1  0x01994000  // '?msc' version magic
07344 
07345 #define EXCEPTION_CPP_GCC                        0x20474343  // ' GCC'
07346 #define EXCEPTION_CPP_GCC_UNWIND                 0x21474343  // '!GCC'
07347 #define EXCEPTION_CPP_GCC_FORCED                 0x22474343  // '"GCC'
07348 
07349 #define EXCEPTION_CLR_FAILURE                    0xE0434f4D  // 'аCOM'
07350 
07351 #define EXCEPTION_CPP_BORLAND_BUILDER            0x0EEDFAE6  // Should never occur here
07352 #define EXCEPTION_CPP_BORLAND_DELPHI             0x0EEDFADE  // Should never occur here
07353 
07354 #pragma pack (push, 1)
07355 
07356 struct CONSOLE_CURSOR_INFO
07357     {
07358     DWORD dwSize;
07359     BOOL bVisible;
07360     };
07361 
07362 struct CONSOLE_FONT_INFO
07363     {
07364     DWORD nFont;
07365     COORD dwFontSize;
07366     };
07367 
07368 struct CONSOLE_FONT_INFOEX
07369     {
07370     ULONG cbSize;
07371     DWORD nFont;
07372     COORD dwFontSize;
07373     UINT  FontFamily;
07374     UINT  FontWeight;
07375     WCHAR FaceName[LF_FACESIZE];
07376     };
07377 
07378 struct DATABLOCK_HEADER
07379     {
07380     DWORD cbSize;
07381     DWORD dwSignature;
07382     };
07383 
07384 struct NT_CONSOLE_PROPS
07385     {
07386     DATABLOCK_HEADER dbh;
07387 
07388     WORD  wFillAttribute;
07389     WORD  wPopupFillAttribute;
07390     COORD dwScreenBufferSize;
07391     COORD dwWindowSize;
07392     COORD dwWindowOrigin;
07393     DWORD nFont;
07394     DWORD nInputBufferSize;
07395     COORD dwFontSize;
07396     UINT  uFontFamily;
07397     UINT  uFontWeight;
07398     WCHAR FaceName[LF_FACESIZE];
07399     UINT  uCursorSize;
07400     BOOL  bFullScreen;
07401     BOOL  bQuickEdit;
07402     BOOL  bInsertMode;
07403     BOOL  bAutoPosition;
07404     UINT  uHistoryBufferSize;
07405     UINT  uNumberOfHistoryBuffers;
07406     BOOL  bHistoryNoDup;
07407 
07408     COLORREF ColorTable[16];
07409     };
07410 
07411 struct FLASHWINFO
07412     {
07413     UINT  cbSize;
07414     HWND  hwnd;
07415     DWORD dwFlags;
07416     UINT  uCount;
07417     DWORD dwTimeout;
07418     };
07419 
07420 enum TBPFLAG
07421     {
07422     TBPF_NOPROGRESS    = 0x0,
07423     TBPF_INDETERMINATE = 0x1,
07424     TBPF_NORMAL        = 0x2,
07425     TBPF_ERROR         = 0x4,
07426     TBPF_PAUSED        = 0x8
07427     };
07428 
07429 #pragma pack (pop)
07430 
07431 const GUID IID_IShellLink             = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07432 const GUID IID_IShellLinkDataList     = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}};
07433 const GUID IID_IPersistFile           = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
07434 
07435 const GUID IID_ITaskbarList3          = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}};
07436 const GUID CLSID_TaskbarList          = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}};
07437 
07438 const GUID CLSID_SpVoice              = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}};
07439 const GUID IID_ISpVoice               = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}};
07440 
07441 typedef DWORD     NTSTATUS;
07442 typedef ULONG_PTR KAFFINITY;
07443 typedef LONG      KPRIORITY;
07444 
07445 struct UNICODE_STRING
07446     {
07447     USHORT   Length;
07448     USHORT   MaximumLength;
07449     wchar_t* Buffer;
07450     };
07451 
07452 struct RTL_DRIVE_LETTER_CURDIR
07453     {
07454     USHORT         Flags;
07455     USHORT         Length;
07456     ULONG          TimeStamp;
07457     UNICODE_STRING DosPath;
07458     };
07459 
07460 struct CURDIR
07461     {
07462     UNICODE_STRING DosPath;
07463     void*          Handle;
07464     };
07465 
07466 struct RTL_USER_PROCESS_PARAMETERS
07467     {
07468     ULONG          AllocationSize;
07469     ULONG          Size;
07470     ULONG          Flags;
07471     ULONG          DebugFlags;
07472     HANDLE         ConsoleHandle;
07473     ULONG          ConsoleFlags;
07474     HANDLE         hStdInput;
07475     HANDLE         hStdOutput;
07476     HANDLE         hStdError;
07477     CURDIR         CurrentDirectory;
07478     UNICODE_STRING DllPath;
07479     UNICODE_STRING ImagePathName;
07480     UNICODE_STRING CommandLine;
07481     wchar_t*       Environment;
07482     ULONG          dwX;
07483     ULONG          dwY;
07484     ULONG          dwXSize;
07485     ULONG          dwYSize;
07486     ULONG          dwXCountChars;
07487     ULONG          dwYCountChars;
07488     ULONG          dwFillAttribute;
07489     ULONG          dwFlags;
07490     ULONG          wShowWindow;
07491     UNICODE_STRING WindowTitle;
07492     UNICODE_STRING Desktop;
07493     UNICODE_STRING ShellInfo;
07494     UNICODE_STRING RuntimeInfo;
07495     RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
07496     };
07497 
07498 struct PEB
07499     {
07500     BYTE  Reserved1[2];
07501     BYTE  BeingDebugged;
07502     BYTE  Reserved2[1];
07503     void* Reserved3[2];
07504     void* Ldr;
07505     RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
07506     void* Reserved4[3];
07507     void* AtlThunkSListPtr;
07508     void* Reserved5;
07509     ULONG Reserved6;
07510     void* Reserved7;
07511     ULONG Reserved8;
07512     ULONG AtlThunkSListPtr32;
07513     void* Reserved9[45];
07514     BYTE  Reserved10[96];
07515     void* PostProcessInitRoutine;
07516     BYTE  Reserved11[128];
07517     void* Reserved12[1];
07518     ULONG SessionId;
07519     };
07520 
07521 struct TEB
07522     {
07523     void* Reserved1[12];
07524     PEB*  ProcessEnvironmentBlock;
07525     void* Reserved2[399];
07526     BYTE  Reserved3[1952];
07527     void* TlsSlots[64];
07528     BYTE  Reserved4[8];
07529     void* Reserved5[26];
07530     void* ReservedForOle;
07531     void* Reserved6[4];
07532     void* TlsExpansionSlots;
07533     };
07534 
07535 struct PROCESS_BASIC_INFORMATION
07536     {
07537     NTSTATUS  ExitStatus;
07538     PEB*      PebBaseAddress;
07539     KAFFINITY AffinityMask;
07540     KPRIORITY BasePriority;
07541     ULONG_PTR UniqueProcessId;
07542     ULONG_PTR InheritedFromUniqueProcessId;
07543     };
07544 
07545 enum ADDRESS_MODE
07546     {
07547     AddrMode1616,
07548     AddrMode1632,
07549     AddrModeReal,
07550     AddrModeFlat
07551     };
07552 
07553 struct ADDRESS64
07554     {
07555     DWORD64      Offset;
07556     WORD         Segment;
07557     ADDRESS_MODE Mode;
07558     };
07559 
07560 struct KDHELP64
07561     {
07562     DWORD64 Thread;
07563     DWORD   ThCallbackStack;
07564     DWORD   ThCallbackBStore;
07565     DWORD   NextCallback;
07566     DWORD   FramePointer;
07567     DWORD64 KiCallUserMode;
07568     DWORD64 KeUserCallbackDispatcher;
07569     DWORD64 SystemRangeStart;
07570     DWORD64 KiUserExceptionDispatcher;
07571     DWORD64 StackBase;
07572     DWORD64 StackLimit;
07573     DWORD64 Reserved[5];
07574     };
07575 
07576 struct STACKFRAME64
07577     {
07578     ADDRESS64 AddrPC;
07579     ADDRESS64 AddrReturn;
07580     ADDRESS64 AddrFrame;
07581     ADDRESS64 AddrStack;
07582     ADDRESS64 AddrBStore;
07583     void*     FuncTableEntry;
07584     DWORD64   Params[4];
07585     BOOL      Far;
07586     BOOL      Virtual;
07587     DWORD64   Reserved[3];
07588     KDHELP64  KdHelp;
07589     };
07590 
07591 struct WOW64_FLOATING_SAVE_AREA
07592     {
07593     DWORD ControlWord;
07594     DWORD StatusWord;
07595     DWORD TagWord;
07596     DWORD ErrorOffset;
07597     DWORD ErrorSelector;
07598     DWORD DataOffset;
07599     DWORD DataSelector;
07600     BYTE  RegisterArea[80];
07601     DWORD Cr0NpxState;
07602     };
07603 
07604 #pragma pack (push, 4)
07605 
07606 struct WOW64_CONTEXT
07607     {
07608     DWORD ContextFlags;
07609 
07610     DWORD Dr0;
07611     DWORD Dr1;
07612     DWORD Dr2;
07613     DWORD Dr3;
07614     DWORD Dr6;
07615     DWORD Dr7;
07616 
07617     WOW64_FLOATING_SAVE_AREA FloatSave;
07618 
07619     DWORD SegGs;
07620     DWORD SegFs;
07621     DWORD SegEs;
07622     DWORD SegDs;
07623 
07624     DWORD Edi;
07625     DWORD Esi;
07626     DWORD Ebx;
07627     DWORD Edx;
07628     DWORD Ecx;
07629     DWORD Eax;
07630 
07631     DWORD Ebp;
07632     DWORD Eip;
07633     DWORD SegCs;
07634     DWORD EFlags;
07635     DWORD Esp;
07636     DWORD SegSs;
07637 
07638     BYTE  ExtendedRegisters[512];
07639     };
07640 
07641 #pragma pack (pop)
07642 
07643 struct SYMBOL_INFO
07644     {
07645     ULONG   SizeOfStruct;
07646     ULONG   TypeIndex;
07647     ULONG64 Reserved[2];
07648     ULONG   info;
07649     ULONG   Size;
07650     ULONG64 ModBase;
07651     ULONG   Flags;
07652     ULONG64 Value;
07653     ULONG64 Address;
07654     ULONG   Register;
07655     ULONG   Scope;
07656     ULONG   Tag;
07657     ULONG   NameLen;
07658     ULONG   MaxNameLen;
07659     char    Name[1];
07660     };
07661 
07662 struct IMAGEHLP_LINE64
07663     {
07664     DWORD   SizeOfStruct;
07665     void*   Key;
07666     DWORD   LineNumber;
07667     char*   FileName;
07668     DWORD64 Address;
07669     };
07670 
07671 typedef bool    (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)   (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead);
07672 typedef void*   (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress);
07673 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)       (HANDLE process, DWORD64 address);
07674 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)     (HANDLE process, HANDLE thread, ADDRESS64* address);
07675 
07676 typedef void (*unexpected_handler)();
07677 
07678 #pragma pack (push, 4)
07679 
07680 struct MINIDUMP_THREAD_CALLBACK
07681     {
07682     ULONG    ThreadId;
07683     HANDLE   ThreadHandle;
07684     CONTEXT  Context;
07685     ULONG    SizeOfContext;
07686     ULONG64  StackBase;
07687     ULONG64  StackEnd;
07688     };
07689 
07690 struct MINIDUMP_THREAD_EX_CALLBACK
07691     {
07692     ULONG    ThreadId;
07693     HANDLE   ThreadHandle;
07694     CONTEXT  Context;
07695     ULONG    SizeOfContext;
07696     ULONG64  StackBase;
07697     ULONG64  StackEnd;
07698     ULONG64  BackingStoreBase;
07699     ULONG64  BackingStoreEnd;
07700     };
07701 
07702 struct MINIDUMP_MODULE_CALLBACK
07703     {
07704     wchar_t* FullPath;
07705     ULONG64  BaseOfImage;
07706     ULONG    SizeOfImage;
07707     ULONG    CheckSum;
07708     ULONG    TimeDateStamp;
07709     VS_FIXEDFILEINFO VersionInfo;
07710     void*    CvRecord;
07711     ULONG    SizeOfCvRecord;
07712     void*    MiscRecord;
07713     ULONG    SizeOfMiscRecord;
07714     };
07715 
07716 struct MINIDUMP_INCLUDE_THREAD_CALLBACK
07717     {
07718     ULONG    ThreadId;
07719     };
07720 
07721 struct MINIDUMP_INCLUDE_MODULE_CALLBACK
07722     {
07723     ULONG64  BaseOfImage;
07724     };
07725 
07726 struct MINIDUMP_MEMORY_INFO
07727     {
07728     ULONG64  BaseAddress;
07729     ULONG64  AllocationBase;
07730     ULONG32  AllocationProtect;
07731     ULONG32  __alignment1;
07732     ULONG64  RegionSize;
07733     ULONG32  State;
07734     ULONG32  Protect;
07735     ULONG32  Type;
07736     ULONG32  __alignment2;
07737     };
07738 
07739 struct MINIDUMP_USER_STREAM
07740     {
07741     ULONG32  Type;
07742     ULONG    BufferSize;
07743     void*    Buffer;
07744     };
07745 
07746 struct MINIDUMP_USER_STREAM_INFORMATION
07747     {
07748     ULONG                 UserStreamCount;
07749     MINIDUMP_USER_STREAM* UserStreamArray;
07750     };
07751 
07752 struct MINIDUMP_CALLBACK_INPUT
07753     {
07754     ULONG    ProcessId;
07755     HANDLE   ProcessHandle;
07756     ULONG    CallbackType;
07757 
07758     union  //-V2514
07759         {
07760         MINIDUMP_THREAD_CALLBACK         Thread;
07761         MINIDUMP_THREAD_EX_CALLBACK      ThreadEx;
07762         MINIDUMP_MODULE_CALLBACK         Module;
07763         MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
07764         MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
07765         };
07766     };
07767 
07768 struct MINIDUMP_CALLBACK_OUTPUT
07769     {
07770     union  //-V2514
07771         {
07772         ULONG ModuleWriteFlags;
07773         ULONG ThreadWriteFlags;
07774         ULONG SecondaryFlags;
07775 
07776         struct
07777             {
07778             ULONG64  MemoryBase;
07779             ULONG    MemorySize;
07780             };
07781 
07782         struct
07783             {
07784             unsigned CheckCancel;
07785             unsigned Cancel;
07786             };
07787 
07788         HANDLE Handle;  //-V117
07789         };
07790 
07791     struct
07792         {
07793         MINIDUMP_MEMORY_INFO VmRegion;
07794         unsigned             Continue;
07795         };
07796 
07797     HRESULT Status;
07798     };
07799 
07800 struct MINIDUMP_EXCEPTION_INFORMATION
07801     {
07802     DWORD               ThreadId;
07803     EXCEPTION_POINTERS* ExceptionPointers;
07804     unsigned            ClientPointers;
07805     };
07806 
07807 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output);
07808 
07809 struct MINIDUMP_CALLBACK_INFORMATION
07810     {
07811     MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
07812     void*                     CallbackParam;
07813     };
07814 
07815 enum MINIDUMP_TYPE
07816     {
07817     MiniDumpNormal                         = 0x00000000,
07818     MiniDumpWithDataSegs                   = 0x00000001,
07819     MiniDumpWithFullMemory                 = 0x00000002,
07820     MiniDumpWithHandleData                 = 0x00000004,
07821     MiniDumpFilterMemory                   = 0x00000008,
07822     MiniDumpScanMemory                     = 0x00000010,
07823     MiniDumpWithUnloadedModules            = 0x00000020,
07824     MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
07825     MiniDumpFilterModulePaths              = 0x00000080,
07826     MiniDumpWithProcessThreadData          = 0x00000100,
07827     MiniDumpWithPrivateReadWriteMemory     = 0x00000200,
07828     MiniDumpWithoutOptionalData            = 0x00000400,
07829     MiniDumpWithFullMemoryInfo             = 0x00000800,
07830     MiniDumpWithThreadInfo                 = 0x00001000,
07831     MiniDumpWithCodeSegs                   = 0x00002000,
07832     MiniDumpWithoutAuxiliaryState          = 0x00004000,
07833     MiniDumpWithFullAuxiliaryState         = 0x00008000,
07834     MiniDumpWithPrivateWriteCopyMemory     = 0x00010000,
07835     MiniDumpIgnoreInaccessibleMemory       = 0x00020000,
07836     MiniDumpWithTokenInformation           = 0x00040000
07837     };
07838 
07839 #ifndef CONTEXT_ALL
07840 #define CONTEXT_ALL              ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS )
07841 #endif
07842 
07843 #pragma pack (pop)
07844 
07845 } // namespace Win32
07846 
07847 #endif // TX_COMPILED
07848 
07849 #define FOREGROUND_BLACK         ( 0                                                         )
07850 #define FOREGROUND_CYAN          ( FOREGROUND_BLUE       | FOREGROUND_GREEN                  )
07851 #define FOREGROUND_MAGENTA       ( FOREGROUND_BLUE       | FOREGROUND_RED                    )
07852 #define FOREGROUND_DARKYELLOW    ( FOREGROUND_GREEN      | FOREGROUND_RED                    )
07853 #define FOREGROUND_LIGHTGRAY     ( FOREGROUND_BLUE       | FOREGROUND_GREEN | FOREGROUND_RED )
07854 #define FOREGROUND_DARKGRAY      (                         FOREGROUND_INTENSITY              )
07855 #define FOREGROUND_LIGHTBLUE     ( FOREGROUND_BLUE       | FOREGROUND_INTENSITY              )
07856 #define FOREGROUND_LIGHTGREEN    ( FOREGROUND_GREEN      | FOREGROUND_INTENSITY              )
07857 #define FOREGROUND_LIGHTCYAN     ( FOREGROUND_CYAN       | FOREGROUND_INTENSITY              )
07858 #define FOREGROUND_LIGHTRED      ( FOREGROUND_RED        | FOREGROUND_INTENSITY              )
07859 #define FOREGROUND_LIGHTMAGENTA  ( FOREGROUND_MAGENTA    | FOREGROUND_INTENSITY              )
07860 #define FOREGROUND_YELLOW        ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY              )
07861 #define FOREGROUND_WHITE         ( FOREGROUND_LIGHTGRAY  | FOREGROUND_INTENSITY              )
07862 
07863 #define BACKGROUND_BLACK         ( 0                                                         )
07864 #define BACKGROUND_CYAN          ( BACKGROUND_BLUE       | BACKGROUND_GREEN                  )
07865 #define BACKGROUND_MAGENTA       ( BACKGROUND_BLUE       | BACKGROUND_RED                    )
07866 #define BACKGROUND_DARKYELLOW    ( BACKGROUND_GREEN      | BACKGROUND_RED                    )
07867 #define BACKGROUND_GRAY          ( BACKGROUND_BLUE       | BACKGROUND_GREEN | BACKGROUND_RED )
07868 #define BACKGROUND_DARKGRAY      (                         BACKGROUND_INTENSITY              )
07869 #define BACKGROUND_LIGHTBLUE     ( BACKGROUND_BLUE       | BACKGROUND_INTENSITY              )
07870 #define BACKGROUND_LIGHTGREEN    ( BACKGROUND_GREEN      | BACKGROUND_INTENSITY              )
07871 #define BACKGROUND_LIGHTCYAN     ( BACKGROUND_CYAN       | BACKGROUND_INTENSITY              )
07872 #define BACKGROUND_LIGHTRED      ( BACKGROUND_RED        | BACKGROUND_INTENSITY              )
07873 #define BACKGROUND_LIGHTMAGENTA  ( BACKGROUND_MAGENTA    | BACKGROUND_INTENSITY              )
07874 #define BACKGROUND_LIGHTYELLOW   ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY              )
07875 #define BACKGROUND_WHITE         ( BACKGROUND_DARKGRAY   | BACKGROUND_INTENSITY              )
07876 
07877 //}
07878 //-----------------------------------------------------------------------------------------------------------------
07879 
07880 //-----------------------------------------------------------------------------------------------------------------
07881 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode.
07882 //  So we have to override them. See: http://stackoverflow.com/questions/39113168
07883 //-----------------------------------------------------------------------------------------------------------------
07884 
07885 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07886 
07887 #if defined (_MSC_VER)
07888                                                     //  MS ABI C++ Exception Layout
07889 namespace Win32 {                                   //  ---------------------------
07890                                                     //
07891 #pragma pack (push, 4)                              //   EXCEPTION_RECORD:
07892                                                     //  +==================================================+
07893 struct ThrowInfo                                    //  |...                                               |
07894     {                                               //  |NumberParameters:        3, 4 or more             |
07895     __int32 attributes;                             //  |ExceptionInformation[0]: MS signature 0x19930520  |
07896     __int32 pmfnUnwind;                             //  |ExceptionInformation[1]: object* thrown           |
07897     __int32 pForwardCompat;                         //  |ExceptionInformation[2]: ThrowInfo* --------------+---+
07898     __int32 pCatchableTypeArray;                    //  |ExceptionInformation[3]: ImageBase (if params > 3)|   |
07899     };                                              //  +==================================================+   |
07900                                                     //                                                         |
07901 struct CatchableTypeArray                           //        ThrowInfo:                                       |
07902     {                                               //        +======================================+ <-------+
07903     __int32 nCatchableTypes;                        //        |   ...                                |
07904     __int32 arrayOfCatchableTypes[];                //  +-----+-- pCatchableTypeArray (ptr/RVA)      |
07905     };                                              //  |     +======================================+
07906                                                     //  |
07907 struct CatchableType                                //  |     CatchableTypeArray:
07908     {                                               //  +---> +======================================+
07909     __int32 properties;                             //        |   ...                                |
07910     __int32 pType;                                  //  +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) |
07911     __int32 thisDisplacement[3]; // struct _PMD     //  |     +======================================+
07912     __int32 sizeOrOffset;                           //  |
07913     __int32 copyFunction;                           //  |     CatchableType:
07914     };                                              //  +---> +====================+
07915                                                     //        | ...                |        std::type_info:
07916 #pragma pack (pop)                                  //        | pType (ptr/RVA) ---+------> +==================+
07917                                                     //        | ...                |        |type_info data    |
07918 } // namespace Win32                                //        +====================+        |...               |
07919                                                     //                                      +==================+
07920 #endif
07921 
07922 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp:
07923 
07924 #define _TX_MSC__CXX_DETECT_RETHROW( exc )                                     \
07925     (                                                                          \
07926     (exc)                                          &&                          \
07927     (exc) -> ExceptionCode    == EXCEPTION_CPP_MSC &&                          \
07928     (exc) -> NumberParameters >= 3                 &&                          \
07929                                                                                \
07930     ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||  \
07931      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||  \
07932      (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \
07933                                                                                \
07934     (exc) -> ExceptionInformation[2] == 0                                      \
07935     )
07936 
07937 #endif // TX_COMPILED
07938 
07939 //}
07940 //-----------------------------------------------------------------------------------------------------------------
07941 
07942 //-----------------------------------------------------------------------------------------------------------------
07943 //{ The corresponding structures for GCC
07944 //
07945 //  From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h
07946 //  See:  http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi
07947 //-----------------------------------------------------------------------------------------------------------------
07948 
07949 #if defined (_GCC_VER)
07950 
07951 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
07952 
07953                                                     // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0].
07954 namespace ABI {                                     // --------------------------------------------------------------
07955                                                     //
07956 struct __cxa_exception                              // Case A: "_Unwind_Exception* A" is independent exception:
07957     {                                               // --------------------------------------------------------
07958     union {                                         //
07959         struct                                      //           __cxa_exception:           std::type_info:
07960             {                                       //       -*--+====================+     +==================+
07961             ::std::type_info* exceptionType;        //        ^  |exceptionType* -----+---->|type_info data    |
07962             void (*exceptionDestructor)(void*);     //        |  |...                 |     |...               |
07963             };                                      //       -1  |                    |     +==================+
07964         struct                                      //        |  |                    |
07965             {                                       // A >----|--+--------------------+
07966             __cxa_exception*  primaryException;     //     |  |  |unwindHeader        |
07967             void (*padding)();                      //    +1  |  |                    |
07968             };                                      //     |  |  |                    |
07969         };                                          //     V  |  |                    |
07970                                                     //    -*---  +====================+
07971     void (*unexpected_handler)();                   //           |object              |
07972     std::terminate_handler    terminateHandler;     //           +--------------------+
07973                                                     //
07974     __cxa_exception*          nextException;        // Case B: "_Unwind_Exception* B" is dependent exception
07975     int                       handlerCount;         // (unwindHeader.exception_class & 1 != 0):
07976     int                       handlerSwitchValue;   // -----------------------------------------------------
07977     const unsigned char*      actionRecord;         //
07978     const unsigned char*      languageSpecificData; //           __cxa_exception:               __cxa_exception:
07979     void*                     catchTemp;            //       -*--+====================+     -*--+=================+
07980     void*                     adjustedPtr;          //        ^  |primaryException* --+--    ^  |exceptionType*   |
07981                                                     //        |  |...                 |  \   |  |...              |
07982     _Unwind_Exception         unwindHeader;         //       -1  |                    |  |   |  |                 |
07983     };                                              //        |  |                    |  |   |  |                 |
07984                                                     // B >----|--+--------------------+  |  -1  +-----------------+
07985 struct __cxa_eh_globals                             //     |  |  |unwindHeader        |  |   |  |unwindHeader     |
07986     {                                               //    +1  |  |                    |  |   |  |                 |
07987     __cxa_exception* caughtExceptions;              //     |  |  |                    |  |   |  |                 |
07988     unsigned int     uncaughtExceptions;            //     V  |  |                    |  \   |  |                 |
07989     };                                              //    -*---  +====================+   -->*--+=================+
07990                                                     //           |...                 |         |object           |
07991 } // namespace ABI                                  //           .                    .         |                 |
07992                                                     //                                          +-----------------+
07993 
07994 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals();
07995 
07996 #endif // TX_COMPILED
07997 
07998 #endif
07999 
08000 //}
08001 //-----------------------------------------------------------------------------------------------------------------
08002 
08003 //-----------------------------------------------------------------------------------------------------------------
08004 //{ Hand-made IAT.
08005 //  Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :(
08006 //-----------------------------------------------------------------------------------------------------------------
08007 
08008 // Hand-made DLLIMPORT helpers
08009 
08010 #define _TX_DLLIMPORT(     lib, retval, name, params )  TX_DLLIMPORT (true,  lib ".dll", retval, name, params, WINAPI)
08011 #define _TX_DLLIMPORT_OPT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI)
08012 #define _TX_DLLIMPORT_CRT( lib, retval, name, params )  TX_DLLIMPORT (false, lib ".dll", retval, name, params, please)
08013 
08014 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) ();
08015 
08016 //-----------------------------------------------------------------------------------------------------------------
08017 
08018 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08019 
08020 namespace Win32 {
08021 
08022 _TX_DLLIMPORT     ("GDI32",    HDC,      CreateCompatibleDC,            (HDC dc));
08023 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateCompatibleBitmap,        (HDC dc, int width, int height));
08024 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetStockObject,                (int object));
08025 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  SelectObject,                  (HDC dc, HGDIOBJ object));
08026 _TX_DLLIMPORT     ("GDI32",    HGDIOBJ,  GetCurrentObject,              (HDC dc, unsigned objectType));
08027 _TX_DLLIMPORT     ("GDI32",    int,      GetObjectA,                    (HGDIOBJ obj, int bufsize, void* buffer));
08028 _TX_DLLIMPORT     ("GDI32",    DWORD,    GetObjectType,                 (HGDIOBJ object));
08029 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteDC,                      (HDC dc));
08030 _TX_DLLIMPORT     ("GDI32",    bool,     DeleteObject,                  (HGDIOBJ object));
08031 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetTextColor,                  (HDC dc, COLORREF color));
08032 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetBkColor,                    (HDC dc, COLORREF color));
08033 _TX_DLLIMPORT     ("GDI32",    int,      SetBkMode,                     (HDC dc, int bkMode));
08034 _TX_DLLIMPORT     ("GDI32",    HFONT,    CreateFontA,                   (int height, int width, int escapement, int orientation,
08035                                                                          int weight, DWORD italic, DWORD underline, DWORD strikeout,
08036                                                                          DWORD charSet, DWORD outputPrec, DWORD clipPrec,
08037                                                                          DWORD quality, DWORD pitchAndFamily, const char face[]));
08038 _TX_DLLIMPORT     ("GDI32",    int,      EnumFontFamiliesExA,           (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc,
08039                                                                          LPARAM lParam, DWORD reserved));
08040 _TX_DLLIMPORT     ("GDI32",    COLORREF, SetPixel,                      (HDC dc, int x, int y, COLORREF color));
08041 _TX_DLLIMPORT     ("GDI32",    COLORREF, GetPixel,                      (HDC dc, int x, int y));
08042 _TX_DLLIMPORT     ("GDI32",    HPEN,     CreatePen,                     (int penStyle, int width, COLORREF color));
08043 _TX_DLLIMPORT     ("GDI32",    HBRUSH,   CreateSolidBrush,              (COLORREF color));
08044 _TX_DLLIMPORT     ("GDI32",    bool,     MoveToEx,                      (HDC dc, int x, int y, POINT* point));
08045 _TX_DLLIMPORT     ("GDI32",    bool,     LineTo,                        (HDC dc, int x, int y));
08046 _TX_DLLIMPORT     ("GDI32",    bool,     Polygon,                       (HDC dc, const POINT points[], int count));
08047 _TX_DLLIMPORT     ("GDI32",    bool,     Polyline,                      (HDC dc, const POINT points[], int count));
08048 _TX_DLLIMPORT     ("GDI32",    bool,     PolyBezier,                    (HDC dc, const POINT points[], int count));
08049 _TX_DLLIMPORT     ("GDI32",    bool,     Rectangle,                     (HDC dc, int x0, int y0, int x1, int y1));
08050 _TX_DLLIMPORT     ("GDI32",    bool,     RoundRect,                     (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY));
08051 _TX_DLLIMPORT     ("GDI32",    bool,     Ellipse,                       (HDC dc, int x0, int y0, int x1, int y1));
08052 _TX_DLLIMPORT     ("GDI32",    bool,     Arc,                           (HDC dc, int x0, int y0, int x1, int y1,
08053                                                                          int xStart, int yStart, int xEnd, int yEnd));
08054 _TX_DLLIMPORT     ("GDI32",    bool,     Pie,                           (HDC dc, int x0, int y0, int x1, int y1,
08055                                                                          int xStart, int yStart, int xEnd, int yEnd));
08056 _TX_DLLIMPORT     ("GDI32",    bool,     Chord,                         (HDC dc, int x0, int y0, int x1, int y1,
08057                                                                          int xStart, int yStart, int xEnd, int yEnd));
08058 _TX_DLLIMPORT     ("GDI32",    bool,     TextOutA,                      (HDC dc, int x, int y, const char string[], int length));
08059 _TX_DLLIMPORT     ("GDI32",    UINT,     SetTextAlign,                  (HDC dc, unsigned mode));
08060 _TX_DLLIMPORT     ("GDI32",    bool,     GetTextExtentPoint32A,         (HDC dc, const char string[], int length, SIZE* size));
08061 _TX_DLLIMPORT     ("GDI32",    bool,     ExtFloodFill,                  (HDC dc, int x, int y, COLORREF color, unsigned type));
08062 _TX_DLLIMPORT     ("GDI32",    bool,     BitBlt,                        (HDC dest, int xDest, int yDest, int width, int height,
08063                                                                          HDC src,  int xSrc,  int ySrc,  DWORD rOp));
08064 _TX_DLLIMPORT     ("GDI32",    bool,     StretchBlt,                    (HDC dest, int xDest, int yDest, int width, int height,
08065                                                                          HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp));
08066 _TX_DLLIMPORT     ("GDI32",    bool,     PlgBlt,                        (HDC dest, const POINT* parallelogram,
08067                                                                          HDC src, int xSrc, int ySrc, int width, int height,
08068                                                                          HBITMAP mask, int xMask, int yMask));
08069 _TX_DLLIMPORT     ("GDI32",    int,      SetDIBitsToDevice,             (HDC dc, int xDest, int yDest, DWORD width, DWORD height,
08070                                                                          int xSrc, int ySrc, unsigned startLine, unsigned numLines,
08071                                                                          const void* data, const BITMAPINFO* info, unsigned colorUse));
08072 _TX_DLLIMPORT     ("GDI32",    int,      GetDIBits,                     (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines,
08073                                                                          void* lpvBits, BITMAPINFO* lpbi, unsigned usage));
08074 _TX_DLLIMPORT     ("GDI32",    bool,     PatBlt,                        (HDC dc, int x0, int y0, int width, int height, DWORD rOp));
08075 _TX_DLLIMPORT     ("GDI32",    int,      SetROP2,                       (HDC dc, int mode));
08076 _TX_DLLIMPORT     ("GDI32",    int,      SetStretchBltMode,             (HDC dc, int mode));
08077 _TX_DLLIMPORT     ("GDI32",    DWORD,    GdiSetBatchLimit,              (DWORD limit));
08078 _TX_DLLIMPORT     ("GDI32",    HBITMAP,  CreateDIBSection,              (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits,
08079                                                                          HANDLE section, DWORD offset));
08080 
08081 _TX_DLLIMPORT     ("User32",   int,      DrawTextA,                     (HDC dc, const char text[], int length, RECT* rect, unsigned format));
08082 _TX_DLLIMPORT     ("User32",   HANDLE,   LoadImageA,                    (HINSTANCE inst, const char name[], unsigned type,
08083                                                                         int sizex, int sizey, unsigned mode));
08084 _TX_DLLIMPORT_OPT ("User32",   bool,     IsHungAppWindow,               (HWND wnd));
08085 _TX_DLLIMPORT_OPT ("User32",   HWND,     GhostWindowFromHungWindow,     (HWND wnd));
08086 _TX_DLLIMPORT_OPT ("User32",   bool,     FlashWindowEx,                 (const FLASHWINFO* flash));
08087 
08088 _TX_DLLIMPORT     ("WinMM",    bool,     PlaySound,                     (const char sound[], HMODULE mod, DWORD mode));
08089 
08090 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     TransparentBlt,                (HDC dest, int destX, int destY, int destWidth, int destHeight,
08091                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
08092                                                                          unsigned transparentColor));
08093 _TX_DLLIMPORT_OPT ("MSImg32",  bool,     AlphaBlend,                    (HDC dest, int destX, int destY, int destWidth, int destHeight,
08094                                                                          HDC src,  int srcX,  int srcY,  int srcWidth,  int srcHeight,
08095                                                                          BLENDFUNCTION blending));
08096 
08097 _TX_DLLIMPORT     ("Kernel32", void,     ExitProcess,                   (unsigned retcode));
08098 _TX_DLLIMPORT     ("Kernel32", bool,     TerminateProcess,              (HANDLE process, unsigned retcode));
08099 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalExit,                     (int retcode));
08100 _TX_DLLIMPORT_OPT ("Kernel32", void,     FatalAppExitA,                 (unsigned action, const char message[]));
08101 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetThreadId,                   (HANDLE thread));
08102 _TX_DLLIMPORT     ("Kernel32", HWND,     GetConsoleWindow,              (void));
08103 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetConsoleFont,                (HANDLE con, DWORD fontIndex));
08104 _TX_DLLIMPORT_OPT ("Kernel32", DWORD,    GetNumberOfConsoleFonts,       (void));
08105 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFont,         (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO*   curFont));
08106 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
08107 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetCurrentConsoleFontEx,       (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont));
08108 _TX_DLLIMPORT_OPT ("Kernel32", void,     RtlCaptureContext,             (CONTEXT* contextRecord));
08109 _TX_DLLIMPORT_OPT ("Kernel32", USHORT,   RtlCaptureStackBackTrace,      (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash));
08110 _TX_DLLIMPORT_OPT ("Kernel32", void*,    AddVectoredExceptionHandler,   (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler));
08111 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler));
08112 _TX_DLLIMPORT_OPT ("Kernel32", bool,     GetModuleHandleEx,             (DWORD flags, const char moduleName[], HMODULE* module));
08113 _TX_DLLIMPORT_OPT ("Kernel32", bool,     IsWow64Process,                (HANDLE process, int* isWow64Process));
08114 _TX_DLLIMPORT_OPT ("Kernel32", bool,     Wow64GetThreadContext,         (HANDLE thread, WOW64_CONTEXT* context));
08115 _TX_DLLIMPORT_OPT ("Kernel32", bool,     SetThreadStackGuarantee,       (unsigned long* stackSize));
08116 
08117 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoInitialize,                  (void*));
08118 _TX_DLLIMPORT     ("OLE32",    HRESULT,  CoCreateInstance,              (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value));
08119 _TX_DLLIMPORT     ("OLE32",    void,     CoUninitialize,                (void));
08120 
08121 _TX_DLLIMPORT     ("Shell32",  HINSTANCE,ShellExecuteA,                 (HWND wnd, const char operation[], const char file[],
08122                                                                          const char parameters[], const char directory[], int showCmd));
08123 
08124 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIA,                      (const char    string[], const char    search[]));
08125 _TX_DLLIMPORT     ("ShlWAPI",  char*,    StrStrIW,                      (const wchar_t string[], const wchar_t search[]));
08126 
08127 _TX_DLLIMPORT_OPT ("NTDLL",    char*,    wine_get_version,              (void));
08128 _TX_DLLIMPORT     ("NTDLL",    NTSTATUS, NtQueryInformationProcess,     (HANDLE process, int infoClass,
08129                                                                          void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo));
08130 
08131 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     exit,                          (int retcode));
08132 _TX_DLLIMPORT_CRT ("MSVCRT",   void,     _cexit,                        (void));
08133 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _fpreset,                      (void));
08134 _TX_DLLIMPORT_CRT ("MSVCRT",   unsigned, _controlfp,                    (unsigned control, unsigned mask));
08135 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthread,                  (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist));
08136 _TX_DLLIMPORT_CRT ("MSVCRT",   uintptr_t,_beginthreadex,                (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*),
08137                                                                          void *arglist, unsigned init_flag, unsigned* thread_addr));
08138 _TX_DLLIMPORT_CRT ("MSVCRT",   char*,    __unDName,                     (char* outStr, const char* mangledName, int outStrLen,
08139                                                                          void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer),
08140                                                                          unsigned short flags));
08141 _TX_DLLIMPORT_CRT ("MSVCRT",   unexpected_handler, set_unexpected,      (unexpected_handler handler));
08142 
08143 _TX_DLLIMPORT_OPT ("OpenGL32", HDC,         wglGetCurrentDC,            (void));
08144 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned,    glGetError,                 (void));
08145 _TX_DLLIMPORT_OPT ("Glu32",    const char*, gluErrorString,             (unsigned error));
08146 
08147 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD,    CommDlgExtendedError,          (void));
08148 
08149 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     MiniDumpWriteDump,             (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType,
08150                                                                          MINIDUMP_EXCEPTION_INFORMATION*   exceptionParam,
08151                                                                          MINIDUMP_USER_STREAM_INFORMATION* userStreamParam,
08152                                                                          MINIDUMP_CALLBACK_INFORMATION*    callbackParam));
08153 
08154 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD,    SymSetOptions,                 (DWORD options));
08155 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
08156 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08157 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08158 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08159 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     SymCleanup,                    (HANDLE process));
08160 _TX_DLLIMPORT_OPT ("DbgHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08161 _TX_DLLIMPORT_OPT ("DbgHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08162                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08163                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08164                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08165                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08166 namespace MinGW {
08167 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD,    SymSetOptions,                 (DWORD options));
08168 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymInitialize,                 (HANDLE process, const char userSearchPath[], bool invadeProcess));
08169 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymFromAddr,                   (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO*     symbol));
08170 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymGetLineFromAddr64,          (HANDLE process, DWORD64 addr, DWORD*   offset, IMAGEHLP_LINE64* line));
08171 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64,  SymGetModuleBase64,            (HANDLE process, DWORD64 addr));
08172 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     SymCleanup,                    (HANDLE process));
08173 _TX_DLLIMPORT_OPT ("MgwHelp*", void*,    SymFunctionTableAccess64,      (HANDLE process, DWORD64 addrBase));
08174 _TX_DLLIMPORT_OPT ("MgwHelp*", bool,     StackWalk64,                   (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord,
08175                                                                          PREAD_PROCESS_MEMORY_ROUTINE64   readMemoryFunc,
08176                                                                          PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc,
08177                                                                          PGET_MODULE_BASE_ROUTINE64       getModuleBaseFunc,
08178                                                                          PTRANSLATE_ADDRESS_ROUTINE64     translateAddressFunc));
08179 } // namespace MinGW
08180 } // namespace Win32
08181 
08182 #endif // TX_COMPILED
08183 
08184 //}
08185 //-----------------------------------------------------------------------------------------------------------------
08186 
08188 //}
08189 //=================================================================================================================
08190 
08191 //=================================================================================================================
08192 //{          Internal function prototypes, macros and constants
08193 //  @name    Прототипы внутренних функций, макросы и константы
08194 //=================================================================================================================
08196 
08197 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08198 
08199 int              _txInitialize();
08200 void             _txCleanup();
08201 
08202 HWND             _txCanvas_CreateWindow      (const SIZE* size);
08203 
08204 bool             _txCanvas_OnCREATE          (HWND wnd);
08205 bool             _txCanvas_OnDESTROY         (HWND wnd);
08206 bool             _txCanvas_OnCLOSE           (HWND);
08207 bool             _txCanvas_OnPAINT           (HWND wnd);
08208 bool             _txCanvas_OnKEY             (HWND wnd, WPARAM vk, LPARAM info, bool down);
08209 bool             _txCanvas_OnCHAR            (HWND wnd, WPARAM ch, LPARAM info);
08210 bool             _txCanvas_OnTIMER           (HWND wnd, WPARAM id);
08211 bool             _txCanvas_OnMOUSEMOVE       (HWND wnd, WPARAM buttons, LPARAM coords);
08212 bool             _txCanvas_OnMOUSELEAVE      (HWND wnd);
08213 bool             _txCanvas_OnCREATEWND       (HWND wnd, WPARAM, LPARAM lpar);
08214 bool             _txCanvas_OnDESTROYWND      (HWND wnd, WPARAM, LPARAM lpar);
08215 bool             _txCanvas_OnCmdCONSOLE      (HWND wnd, WPARAM cmd);
08216 bool             _txCanvas_OnCmdABOUT        (HWND wnd, WPARAM cmd);
08217 
08218 unsigned WINAPI  _txCanvas_ThreadProc        (void* data);
08219 LRESULT CALLBACK _txCanvas_WndProc           (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08220 
08221 HDC              _txBuffer_Create            (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL,
08222                                               RGBQUAD** pixels = NULL) tx_nodiscard;
08223 bool             _txBuffer_Delete            (HDC* dc);
08224 bool             _txBuffer_Select            (HGDIOBJ obj, HDC dc = txDC());
08225 
08226 HWND             _txConsole_Attach();
08227 bool             _txConsole_OK() tx_nodiscard;
08228 bool             _txConsole_Detach           (bool activate);
08229 bool             _txConsole_Draw             (HDC dc);
08230 bool             _txConsole_SetUnicodeFont();
08231 
08232 const char*       txRegisterClass            (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra);
08233 HWND              txCreateExtraWindow        (CREATESTRUCT createData);
08234 HICON            _txCreateTXIcon             (int size) tx_nodiscard;
08235 int              _txSetWindowText            (HWND wnd, const char* textRus, const char* textEng = NULL,
08236                                               int checkOfs = 0, const wchar_t checkLetters[2] = NULL);
08237 int              _txPauseBeforeTermination   (HWND canvas);
08238 int              _txIsParentListed           (const char* list, DWORD* parentPID = NULL) tx_nodiscard;
08239 void             _txActivateWindow           (HWND wnd, unsigned mode);
08240 int              _txGetInput();
08241 
08242 LRESULT CALLBACK _txPlayVideo_WndProc        (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar);
08243 const char*      _txPlayVideo_FindVLC() tx_nodiscard;
08244 
08245 bool             _txCreateShortcut           (const char shortcutName[],
08246                                               const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL,
08247                                               const char description[] = NULL, int cmdShow = SW_SHOWNORMAL,
08248                                               const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0,
08249                                               COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD));
08250 
08251 void*            _tx_DLGTEMPLATE_Create      (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
08252                                               WORD controls, short x, short y, short cx, short cy,
08253                                               const char caption[], const char font[], WORD fontsize,
08254                                               const char menu[]) tx_nodiscard;
08255 
08256 void*            _tx_DLGTEMPLATE_Add         (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
08257                                               short x, short y, short cx, short cy,
08258                                               WORD id, const char wclass[], const char caption[]);
08259 
08260 const char*      _txProcessError             (const char file[], int line, const char func[], unsigned color,
08261                                               const char msg[], va_list args);
08262 void             _txOnTerminate();
08263 void             _txOnUnexpected();
08264 void             _txOnPureCall();
08265 void             _txOnNewHandlerAnsi();
08266 int              _txOnNewHandler             (size_t size);
08267 void             _txOnSignal                 (int signal = 0, int fpe = 0);
08268 BOOL WINAPI      _txOnConsoleCtrlEvent       (DWORD type);
08269 void             _txOnSecurityError          (int code, void*);
08270 void             _txOnSecurityErrorAnsi      (const char* msg, void* ptr, int code);
08271 int              _txOnMatherr                (_exception* except);
08272 void             _txOnInvalidParam           (const wchar_t* expr, const wchar_t* func, const wchar_t* file,
08273                                               unsigned line, uintptr_t);
08274 int              _txOnAllocHook              (int type, void* data, size_t size, int use, long request,
08275                                               const unsigned char* file, int line);
08276 int              _txOnRTCFailure             (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5);
08277 int              _txOnErrorReport            (int type, const char* text, int* ret);
08278 int               tx_glGetError              (int setError = INT_MIN);
08279 
08280 void             _txOnCExit();
08281 void             _txOnExit                   (int      retcode);
08282 void             _txOnFatalExit              (int      retcode);
08283 void             _txOnExitProcess            (unsigned retcode);
08284 void             _txOnFatalAppExitA          (unsigned action, const char message[]);
08285 bool             _txOnTerminateProcess       (HANDLE process, unsigned retcode);
08286 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
08287                  _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter);
08288 void             _txWatchdogTerminator       (void* timeout);  // Only Arnold-type series are supported, not T1000
08289 
08290 long WINAPI      _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc);
08291 long WINAPI      _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc);
08292 long             _txOnExceptionSEH           (EXCEPTION_POINTERS* exc, const char func[]);
08293 intptr_t         _txDumpExceptionSEH         (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]);
08294 intptr_t         _txDumpExceptionObj         (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type);
08295 intptr_t         _txDumpExceptionCPP         (char what[], intptr_t size, unsigned code = 0,
08296                                               unsigned params = 0, const ULONG_PTR info[] = NULL);
08297 
08298 void             _txStackBackTrace           (const char file[] = "?", int line = 0, const char func[] = "?",
08299                                               bool readSource = true);
08300 const char*      _txCaptureStackBackTrace    (int framesToSkip = 0, bool readSource = true,
08301                                               CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread());
08302 int              _txStackWalk                (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL,
08303                                               HANDLE thread = GetCurrentThread());
08304 const char*      _txCaptureStackBackTraceTX  (int framesToSkip = 0, bool readSource = false);
08305 
08306 const char*      _txSymPrintFromAddr         (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2);
08307 bool             _txSymGetFromAddr           (void* addr, Win32::SYMBOL_INFO** symbol = NULL,
08308                                               Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL,
08309                                               const char** source = NULL, int context = 2);
08310 intptr_t         _txReadSource               (char buf[], intptr_t size, const char file[],
08311                                               int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN);
08312 bool             _txCreateMiniDump           (EXCEPTION_POINTERS* exc = NULL);
08313 
08314 uintptr_t        _txSetProcAddress           (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL,
08315                                               int useHotPatching = false, HMODULE module = NULL, bool debug = false);
08316 bool             _txInDll() tx_nodiscard;
08317 PROCESSENTRY32*  _txFindProcess              (unsigned pid = GetCurrentProcessId()) tx_nodiscard;
08318 bool             _txKillProcess              (DWORD pid);
08319 int              _txTaskKill                 (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/);
08320 bool             _txCheckSourceCP            (int needCP = _TX_CODEPAGE, bool verbose = true);
08321 bool             _txGetCommandLine           (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid());
08322 IMAGE_NT_HEADERS*_txGetNtHeaders             (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard;
08323 bool             _txIsConsoleSubsystem();
08324 const char*      _txAppInfo() tx_nodiscard;
08325 
08326 #endif // TX_COMPILED
08327 
08328 inline bool      _txCanvas_OK                () tx_nodiscard;
08329 int              _txCanvas_SetRefreshLock    (int count);
08330 
08331 const char*      _txError                    (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0,
08332                                               const char msg[] = NULL, ...) tx_printfy (5);
08333 
08334 bool             _txIsBadReadPtr             (const void* address);
08335 
08336 intptr_t         _tx_snprintf_s              (char stream[], intptr_t size, const char format[], ...) tx_printfy (3);
08337 intptr_t         _tx_vsnprintf_s             (char stream[], intptr_t size, const char format[], va_list arg);
08338 bool             _txIsTTY                    (int fd);
08339 void              txReopenStdio();
08340 
08341 #if defined (__CYGWIN__)
08342 
08343 int              _getch();
08344 int              _putch (int ch);
08345 int              _kbhit() tx_nodiscard;
08346 
08347 #endif
08348 
08349 //-----------------------------------------------------------------------------------------------------------------
08350 // There are macros for __FILE__ and __LINE__ to work properly.
08351 
08352 #if !defined (NDEBUG)
08353 
08354     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08355                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) && \
08356                                                      (assert (cond), true) )
08357 
08358     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08359                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) && \
08360                                                      (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) )
08361 
08362     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                                                            \
08363                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) &&                                     \
08364                                                      (TX_ERROR ("\a" "Параметр \"%s\" неверен."                                           \
08365                                                                                    " Возможно, этот холст не создан, или уже уничтожен,"  \
08366                                                                                    " или не загрузилась картинка.", #dc), 1) )
08367     #define _TX_DEFAULT_HDC_FAILED( dc )       ( (!(dc) &&                                                                                \
08368                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) &&                                     \
08369                                                      (TX_ERROR ("\a" "%s" "Если вы указали параметр \"%s\", то он неверен.%s",            \
08370                                                                      !txWindow()? "Окно рисования не создано или не в порядке.\n" : "",   \
08371                                                                      #dc,                                                                 \
08372                                                                       txWindow()? " Возможно, этот холст не создан, или уже уничтожен,"   \
08373                                                                                    " или не загрузилась картинка." : ""), 1))             \
08374                                                  ||                                                                                       \
08375                                                  _TX_HDC_FAILED (dc) )
08376 #else
08377 
08378     #define  _TX_ARGUMENT_FAILED( cond )       ( !(cond) &&                                           \
08379                                                      (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0),  1) )
08380 
08381     #define  _TX_TXWINDOW_FAILED()             ( !txOK() &&                                           \
08382                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08383 
08384     #define  _TX_HDC_FAILED( dc )              ( !Win32::GetObjectType (dc) &&                        \
08385                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08386 
08387     #define _TX_DEFAULT_HDC_FAILED( dc )       ( !(dc) &&                                             \
08388                                                      (SetLastErrorEx (ERROR_INVALID_DATA,  0),  1) )
08389 #endif
08390 
08391 //-----------------------------------------------------------------------------------------------------------------
08392 // Take action in debug configuration only.
08393 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'(
08394 
08395 #if !defined (NDEBUG)
08396     #define  _TX_ON_DEBUG( code )              { code; }
08397 #else
08398     #define  _TX_ON_DEBUG( code )              ;
08399 #endif
08400 
08401 //-----------------------------------------------------------------------------------------------------------------
08402 // Invokes an error without location information. "$$" restores TX-related call location context
08403 
08404 #define _TX_UNEXPECTED( ... )                  $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__)
08405 
08406 //-----------------------------------------------------------------------------------------------------------------
08407 // Safe call of a function via its pointer
08408 
08409 #define _TX_CALL(  func, param )               ( (func)? ((func) param) :       0 )
08410 #define _TX_CALLv( func, param )               ( (func)? ((func) param) : (void)0 )
08411 
08412 //-----------------------------------------------------------------------------------------------------------------
08413 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x.
08414 
08415 #define _txWaitFor( cond, time )               { for (DWORD _t = GetTickCount() + (time); \
08416                                                       !(cond) && GetTickCount() < _t;     \
08417                                                       Sleep (_txWindowUpdateInterval))    \
08418                                                       ;                                   \
08419                                                                                           \
08420                                                  if  (!(cond))                            \
08421                                                       _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); }
08422 
08423 //-----------------------------------------------------------------------------------------------------------------
08424 // Detouring in case of SEH mechanism
08425 
08426 #define _txSetJmp()                            ( _txLocSet (&_txDumpExceptionObjLoc, __FILE__, __LINE__, __func__), \
08427                                                  (setjmp (_txDumpExceptionObjJmp) == 0)? true : (_txClearJmp(), false) )
08428 
08429 #define _txClearJmp()                          ( _txLocSet (&_txDumpExceptionObjLoc, NULL, 0, NULL), \
08430                                                  *(unsigned long long*) _txDumpExceptionObjJmp = 0 )
08431 
08432 //-----------------------------------------------------------------------------------------------------------------
08433 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code.
08434 
08435 #if defined (IN)
08436 //  #undef  IN
08437 #endif
08438 
08439 #if defined (OUT)
08440 //  #undef  OUT
08441 #endif
08442 
08444 //}
08445 //=================================================================================================================
08446 
08447 //=================================================================================================================
08448 //{          Internal global data
08450 //
08451 //           Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :)
08452 //
08453 //           Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же.
08454 //           Здесь это сделано только в образовательных целях.
08455 //
08456 //           Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс.
08457 //=================================================================================================================
08459 
08460 #ifndef TX_COMPILED                                                      // <<<<<<< THE CODE IS HERE, UNFOLD IT <<<
08461 
08462 const int                      _TX_IDM_ABOUT               = 40000,      // Идентификаторы системного меню окна
08463                                _TX_IDM_CONSOLE             = 40001,
08464                                _TX_WM_CREATEWND            = 0x7FF0,     // Сообщения для создания/уничтожения
08465                                _TX_WM_DESTROYWND           = 0x7FF1;     // окон в потоке Canvas
08466 
08467 const char                     _TX_VSCODE_PARENTS[]        = "cmd.exe:code.exe, powershell.exe:code.exe";
08468 
08469 //-----------------------------------------------------------------------------------------------------------------
08470 
08471 volatile unsigned              _txCanaryFirst              = 0x776F656D; // A very system value
08472 
08473 int                            _txInitialized              = (_TX_NOINIT +0)? 0 : _txInitialize();
08474 
08475 volatile unsigned              _txMainThreadId             = 0;          // ID потока, где выполняется main()
08476 volatile HANDLE                _txMainThread               = NULL;       // Дексриптор этого потока
08477 
08478 volatile unsigned              _txCanvas_ThreadId          = 0;          // ID потока, владеющего окном холста TXLib
08479 volatile HANDLE                _txCanvas_Thread            = NULL;       // Дексриптор этого потока
08480 volatile HWND                  _txCanvas_Window            = NULL;       // Дескриптор окна холста TXLib
08481 
08482 HDC                            _txCanvas_BackBuf[2]        = {NULL,      // [0] Main TXLib in-memory DC, where user's pictures lies
08483                                                               NULL};     // [1] Image ready for auto-refresh, see txCanvas_OnPAINT()
08484 
08485 RGBQUAD*                       _txCanvas_Pixels            = NULL;       // Memory buffer of _txCanvas_BackBuf[0]
08486 
08487 HBITMAP                        _txStockBitmap              = NULL;       // Equivalent of GetStockObject (BITMAP),
08488                                                                          // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313
08489 
08490 CRITICAL_SECTION               _txCanvas_LockBackBuf       = {0,-1};     // Prevent simultaneous access to back buffer, see txLock()
08491 
08492 UINT_PTR                       _txCanvas_RefreshTimer      = 1;          // Timer ID to redraw TXLib window
08493 volatile int                   _txCanvas_RefreshLock       = 0;          // Blocks auto on-timer canvas update, see txBegin/txEnd
08494 
08495 ::std::vector<HDC>*            _txCanvas_UserDCs           = NULL;       // List of DCs allocated, for auto-free
08496 
08497 volatile bool                  _txConsole_IsBlinking       = true;       // To blink or not to blink, that is the question.
08498 
08499 int                            _txConsole                  = false;      // Only first TXLib module in app can own the console
08500 bool                           _txMain                     = false;      // First TXLib wnd opened (closing it terminates program)
08501 bool                           _txIsDll                    = false;      // TXLib module is in DLL
08502 volatile bool                  _txRunning                  = false;      // main() is still running
08503 volatile bool                  _txExit                     = false;      // exit() is active
08504 
08505 volatile POINT                 _txMousePos                 = {-1,-1};    // Ask Captn Obviouos about it. See txCanvas_OnMOUSE()
08506 volatile unsigned              _txMouseButtons             = 0;
08507 
08508 volatile WNDPROC               _txAltWndProc               = NULL;       // Альтернативная оконная функция. См. txSetWindowsHook().
08509 
08510 _tx_thread _txLoc              _txLoc::Cur                 = {};         // Execution point tracking and trace state, see "$" macro
08511 
08512 volatile int                   _txErrors                   = 0;          // TX_ERROR calls sequential number
08513 volatile int                   _txOGLError                 = 0;          // Last OpenGL error when using tx_glGetError()
08514 volatile long                  _txSENumber                 = 0;          // SEH exceptions sequential number
08515 volatile long                  _txSEFatalNumber            = 0;          // SEH fatal exceptions sequential number
08516 char                           _txDumpSE [_TX_BUFSIZE]     = "";         // SEH dump data area
08517 char                           _txTraceSE[_TX_HUGEBUFSIZE] = "";         // Stack trace data area
08518 
08519 LPTOP_LEVEL_EXCEPTION_FILTER   _txPrevUEFilter             = NULL;       // Previous UnhandledExceptionFilter
08520 
08521 jmp_buf                        _txDumpExceptionObjJmp      = {};         // Hook for _txDumpExceptionObj
08522 _txLoc                         _txDumpExceptionObjLoc      = {};
08523 
08524 const volatile uintptr_t       _txForceImport[]            = { (uintptr_t) ::TerminateProcess,              (uintptr_t) ::ExitProcess,
08525                                                                (uintptr_t) ::FatalExit,                     (uintptr_t) ::FatalAppExitA,
08526                                                                (uintptr_t) ::exit,                          (uintptr_t) Win32::_controlfp,
08527                                                                (uintptr_t) Win32::Polyline,                 (uintptr_t) Win32::PolyBezier,
08528                                                                (uintptr_t) Win32::RoundRect,                (uintptr_t) Win32::RemoveVectoredExceptionHandler,
08529                                                                (uintptr_t) Win32::PlgBlt,                   (uintptr_t) Win32::RtlCaptureStackBackTrace,
08530                                                                (uintptr_t) Win32::SymInitialize,            (uintptr_t) Win32::MinGW::SymInitialize,
08531                                                                (uintptr_t) Win32::SymSetOptions,            (uintptr_t) Win32::MinGW::SymSetOptions,
08532                                                                (uintptr_t) Win32::SymGetLineFromAddr64,     (uintptr_t) Win32::MinGW::SymGetLineFromAddr64,
08533                                                                (uintptr_t) Win32::SymFromAddr,              (uintptr_t) Win32::MinGW::SymFromAddr,
08534                                                                (uintptr_t) Win32::SymCleanup,               (uintptr_t) Win32::MinGW::SymCleanup,
08535                                                                (uintptr_t) Win32::SymGetModuleBase64,       (uintptr_t) Win32::MinGW::SymGetModuleBase64,
08536                                                                (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64,
08537                                                                (uintptr_t) Win32::StackWalk64,              (uintptr_t) Win32::MinGW::StackWalk64,
08538                                                                (uintptr_t) Win32::StrStrIA,                 (uintptr_t) Win32::Wow64GetThreadContext };
08539 
08540 volatile unsigned              _txCanaryLast               = 0x5E2E2E5E; // Another very system value
08541 
08542 #endif // TX_COMPILED
08543 
08544 //-----------------------------------------------------------------------------------------------------------------
08545 
08546 extern volatile unsigned _txCanaryFirst;
08547 extern volatile unsigned _txCanaryLast;
08548 extern volatile HWND     _txCanvas_Window;
08549 extern volatile unsigned _txCanvas_ThreadId;
08550 extern          HDC      _txCanvas_BackBuf[2];
08551 extern          RGBQUAD* _txCanvas_Pixels;
08552 extern volatile int      _txCanvas_RefreshLock;
08553 extern volatile WNDPROC  _txAltWndProc;
08554 extern volatile bool     _txExit;
08555 extern volatile int      _txOGLError;
08556 
08558 //}
08559 //=================================================================================================================
08560 
08561 //=================================================================================================================
08562 //{          TXLib engine init/check/cleanup
08564 //=================================================================================================================
08566 
08567 //-----------------------------------------------------------------------------------------------------------------
08568 //{          Early initialization
08569 //-----------------------------------------------------------------------------------------------------------------
08570 
08571 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08572 
08573 int _txInitialize()
08574     {
08575     if (_txInitialized) return 1;
08576     _txInitialized = 1;
08577 
08578     #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER)  // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx
08579     _CrtSetBreakAlloc (_TX_ALLOC_BREAK);                 // and http://support.microsoft.com/ru-ru/kb/151585
08580     #endif
08581 
08582     #if defined (_TX_ALLOW_TRACE)
08583     _txLocLvlSet (1);
08584     #endif
08585 
08586     _TX_ON_DEBUG (OutputDebugString ("\n");
08587                   OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" "
08588                                      "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n");
08589                   OutputDebugString ("\n"));
08590 
08591     _txMainThreadId = GetCurrentThreadId();
08592     _txMainThread   = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId);
08593 
08594 $3  _txIsDll = _txInDll();
08595 
08596 $   if (!_txIsDll)
08597         {
08598 $       _txConsole = ! FindAtom ("_txConsole");
08599 $       (void)          AddAtom ("_txConsole");  //-V530
08600         }
08601 
08602 $   if (_txConsole)
08603         {
08604 $       _txCheckSourceCP (_TX_CODEPAGE, true);
08605 
08606 $       unsigned long stackSize = _TX_STACKSIZE;
08607 $       _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
08608 
08609 $       _txOnSignal();
08610 
08611 $       if (!*_txLogName || _txLogName[0] == '~')
08612             {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); }
08613 
08614 $       if (!_txIsDll)
08615             {
08616             #ifndef _CLANG_VER
08617 $        // _TX_CALL  (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER)  _txVectoredExceptionHandler));
08618             #endif
08619 
08620 $           _txPrevUEFilter = SetUnhandledExceptionFilter  (   (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter);
08621             }
08622 
08623 $       ::std::set_terminate             (_txOnTerminate);
08624 $       ::std::set_new_handler           (_txOnNewHandlerAnsi);
08625 $       _TX_CALL (Win32::set_unexpected, (_txOnUnexpected));
08626 
08627 $       SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true);
08628 
08629 $       SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
08630 
08631         #if defined (_MSC_VER)
08632 
08633 $       _set_printf_count_output (1);
08634 
08635 $       _set_new_handler (_txOnNewHandler);
08636 $       _set_new_mode (1);
08637 
08638         #if !defined (_CLANG_VER)
08639 
08640 $       _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
08641 $       _CrtSetAllocHook (_txOnAllocHook);
08642 
08643 $       unsigned mode = _CRTDBG_MODE_FILE;
08644 $       if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0;
08645 
08646 $       _CrtSetReportMode (_CRT_WARN,   _CRTDBG_MODE_DEBUG | mode);
08647 $       _CrtSetReportMode (_CRT_ERROR,  _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08648 $       _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW);
08649 $       _CrtSetReportFile (_CRT_WARN,   _CRTDBG_FILE_STDERR);
08650 $       _CrtSetReportFile (_CRT_ERROR,  _CRTDBG_FILE_STDERR);
08651 $       _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
08652 
08653         #endif
08654 
08655 $       _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG);
08656 $       _set_abort_behavior (0,                _CALL_REPORTFAULT);
08657 
08658 $       _RTC_SetErrorFunc              (_txOnRTCFailure);
08659 $       _set_purecall_handler          (_txOnPureCall);
08660 $       _set_invalid_parameter_handler (_txOnInvalidParam);
08661 
08662         #endif
08663 
08664         #if defined (__STDC_LIB_EXT1__)
08665 $       ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi);
08666         #endif
08667 
08668         #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386)
08669 $       __setusermatherr (_txOnMatherr);
08670         #endif
08671 
08672         #if !defined (__CYGWIN__)
08673 $       _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR);
08674         #endif
08675 
08676 $       HWND console = _txConsole_Attach();
08677 $       SetWindowTextA (console, txGetModuleFileName (false));
08678         }
08679 
08680 $   _txSetProcAddress ("ExitProcess",                 (uintptr_t) _txOnExitProcess,                 "KERNEL32.DLL");
08681 $   _txSetProcAddress ("TerminateProcess",            (uintptr_t) _txOnTerminateProcess,            "KERNEL32.DLL");
08682 $   _txSetProcAddress ("FatalExit",                   (uintptr_t) _txOnFatalExit,                   "KERNEL32.DLL");
08683 $   _txSetProcAddress ("FatalAppExitA",               (uintptr_t) _txOnFatalAppExitA,               "KERNEL32.DLL");
08684 $   _txSetProcAddress ("UnhandledExceptionFilter",    (uintptr_t) _txUnhandledExceptionFilter,      "KERNEL32.DLL", true);  //-V601
08685 $   _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL");
08686 $   _txSetProcAddress ("exit",                        (uintptr_t) _txOnExit);
08687 $   _txSetProcAddress ("_cexit",                      (uintptr_t) _txOnCExit);
08688 
08689 $   InitializeCriticalSection (&_txCanvas_LockBackBuf);
08690 
08691 $   HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted;
08692 $   _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted;
08693 $   Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted;
08694 $   Win32::DeleteDC (dc) asserted;
08695 
08696 $   atexit (_txCleanup);
08697 
08698 $   if (_txConsole)
08699         {
08700 $       txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
08701 
08702 $       tx_fpreset();
08703 
08704 $       srand ((unsigned) time (NULL));  //-V202
08705 
08706 $       SetLastError (0);
08707 $       errno = 0;
08708 
08709         #if !defined (__CYGWIN__)
08710 $       _doserrno = 0;
08711         #endif
08712         }
08713 
08714 $   UNREFERENCED_PARAMETER (Win32::CoCreateInstance);             // g++ 5.1.0 bug, false warning "defined but not used"
08715 $   UNREFERENCED_PARAMETER (Win32::AddVectoredExceptionHandler);  //
08716 
08717 $   return 1;
08718     }
08719 
08720 //-----------------------------------------------------------------------------------------------------------------
08721 
08722 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/)
08723     {
08724 $3  const char* sCodePage = NULL;
08725 $   int codePage = 0;
08726 
08727 $   switch (((unsigned const char*) "А") [0])
08728         {
08729         case 192: {$ codePage =  1251; sCodePage = "1251.";          break; }
08730         case 208: {$ codePage = 65001; sCodePage = "UTF-8.";         break; }
08731         case 128: {$ codePage =   866; sCodePage = "866.";           break; }
08732         case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; }
08733         default:  {$ codePage =    -1; sCodePage = "(Unknown)";      break; }
08734         }
08735 
08736 $   if (codePage != needCP && verbose)
08737         {
08738 $       *_txTraceSE = ' ';  // No stack trace please
08739 
08740 $       _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n"
08741                         "This is NOT an error of TXLib itself. Please note:\n\n"
08742                         "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your "
08743                         "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO "
08744                         "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. "
08745                         "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n"
08746                         "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n"
08747                         "You can continue, but Russian messages and symbols may appear unreadable.",
08748                         sCodePage, needCP, needCP);
08749         }
08750 
08751 $   return (codePage == needCP);
08752     }
08753 
08754 //-----------------------------------------------------------------------------------------------------------------
08755 
08756 #ifdef _TX_DEBUG_LOAD
08757 
08758 HMODULE _txLoadLibrary_ (const char* dll, int line);
08759 HMODULE _txLoadLibrary_ (const char* dll, int line)
08760     {
08761     txOutputDebugPrintf (_TX_DEBUG_LOAD "[" __FILE__ ":%04d] Loading \"%s\"... ", line, dll);
08762 
08763     SetLastError (0);
08764     HMODULE lib = LoadLibrary (dll);
08765 
08766     if (lib) txOutputDebugPrintf (_TX_DEBUG_LOAD "SUCSESS [%p]\n", (void*) lib);
08767     else     txOutputDebugPrintf (_TX_DEBUG_LOAD "error %lu\n", GetLastError());
08768 
08769     return lib;
08770     }
08771 
08772 #define LoadLibraryA(dll) _txLoadLibrary_ (dll, __LINE__)
08773 
08774 #endif
08775 
08776 //-----------------------------------------------------------------------------------------------------------------
08777 
08778 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) ()
08779     {
08780     if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL;
08781     if (_TX_ARGUMENT_FAILED (funcName    && *funcName))    return NULL;
08782 
08783     static char dllPaths [4][MAX_PATH] = {};
08784 
08785     if (!*dllPaths[0])
08786         {
08787         const  char dllDir[] = "\\Windows\\";
08788         char*  path = NULL;
08789         size_t sz   = 0;
08790 
08791         // The dllPaths[0] is a directory where executable file is located
08792 
08793         path = dllPaths[0];
08794 
08795         sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0;
08796         if (char* dir = strrchr (path, '\\')) dir[1] = 0;
08797 
08798         // The dllPaths[1] is relative to directory where executable file is located
08799 
08800         path = dllPaths[1];
08801 
08802         sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0;
08803         if (char* dir = strrchr (path, '\\')) dir[0] = 0;
08804 
08805         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08806 
08807         // The dllPaths[2] is relative to TXib.h file used in compilation
08808 
08809         path = dllPaths[2];
08810 
08811         if (strchr (__FILE__, ':'))
08812             {
08813             strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1);
08814             }
08815         else
08816             {
08817             // No way to get include path at compile time using simple call "gcc file.cpp"
08818 
08819             sz = GetCurrentDirectory (MAX_PATH, path); path[sz] = 0;
08820             if (*path) strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1);
08821             }
08822 
08823         if (char* dir = strrchr (path, '\\')) *dir = 0;
08824 
08825         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08826 
08827         // The dllPaths[3] is relative to the TX Setup directory stored in the Registry
08828 
08829         path = dllPaths[3];
08830 
08831         txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH);
08832         if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1);
08833         }
08834 
08835     char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = "";
08836     const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL);  //-V547
08837 
08838     if (arch)
08839         {
08840         assert (arch >= dllFileName);  //-V547
08841 
08842         strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName));
08843         strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName));
08844 
08845         strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName));
08846         strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3);
08847         strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch));
08848         }
08849     else if (dllFileName)  //-V547 //-V2516
08850         {
08851         strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1);
08852         }
08853 
08854     HMODULE   dll = GetModuleHandle (dllFileName);
08855 
08856     if (!dll) dll = GetModuleHandle (dllArch);
08857     if (!dll) dll = GetModuleHandle (dllName);
08858 
08859     for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++)
08860         {
08861         if (!dllPaths[i]) continue;
08862 
08863         char path [MAX_PATH] = "";
08864         strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i]));
08865         size_t len = strlen (path);
08866 
08867         SetDllDirectory (path);
08868 
08869         strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch));
08870         if (!dll && *dllArch) dll = LoadLibrary (path);  //-V547
08871 
08872         strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName));
08873         if (!dll)             dll = LoadLibrary (path);
08874         }
08875 
08876     SetDllDirectory (NULL);
08877 
08878     if (!dll && *dllArch) dll = LoadLibrary (dllArch);
08879     if (!dll)             dll = LoadLibrary (dllName);
08880 
08881     if (!dll  && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".",
08882                                            dllName, (arch? "\" / \"" : ""), dllArch);
08883     if (!dll) return NULL;
08884 
08885     void (*addr)() = (void(*)()) GetProcAddress (dll, funcName);
08886 
08887     if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".",
08888                                            funcName, dllName, (arch? "\" / \"" : ""), dllArch);
08889     return addr;
08890     }
08891 
08892 //-----------------------------------------------------------------------------------------------------------------
08893 
08894 #ifdef _TX_DEBUG_LOAD
08895     #undef LoadLibraryA
08896     #endif
08897 
08898 //-----------------------------------------------------------------------------------------------------------------
08899 
08900 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013
08901     #pragma warning (push)
08902     #pragma warning (disable: 6102)          // Использование 'name' из завершившегося ошибкой вызова функции
08903 #endif
08904 
08905 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue)
08906     {
08907     if (_TX_ARGUMENT_FAILED (keyName)) return 0;
08908 
08909     HKEY hive = NULL;
08910 
08911     #define EQU_(name1, name2)  ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \
08912                                   _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 )
08913 
08914     if      (EQU_("HKLM", "HKEY_LOCAL_MACHINE"))  hive = HKEY_LOCAL_MACHINE;
08915     else if (EQU_("HKCU", "HKEY_CURRENT_USER"))   hive = HKEY_CURRENT_USER;
08916     else if (EQU_("HKCR", "HKEY_CLASSES_ROOT"))   hive = HKEY_CLASSES_ROOT;
08917     else if (EQU_("HKU",  "HKEY_USERS"))          hive = HKEY_USERS;
08918     else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG;
08919 
08920     else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; }
08921 
08922     #undef EQU_
08923 
08924     keyName = strchr (keyName, '\\') + 1;  //-V769
08925     assert (keyName > (const char*) 1);
08926 
08927     HKEY  key  = NULL;
08928     DWORD size = 0;
08929 
08930     bool                               ok  = (RegOpenKeyEx    (hive, keyName,   0, KEY_QUERY_VALUE, &key)         == ERROR_SUCCESS);
08931     if (ok)                            ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, NULL,          &size) == ERROR_SUCCESS);
08932     if (ok && value && size < szValue) ok &= (RegQueryValueEx (key,  valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS);  //-V104
08933     if (key)                           ok &= (RegCloseKey     (key)                                               == ERROR_SUCCESS);
08934 
08935     return size;
08936     }
08937 
08938 #if defined (_MSC_VER) && (_MSC_VER == 1800)
08939     #pragma warning (pop)
08940 #endif
08941 
08942 #endif // TX_COMPILED
08943 
08944 //}
08945 //-----------------------------------------------------------------------------------------------------------------
08946 
08947 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
08948 
08949 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/)
08950     {
08951 $1  if (!_txInitialized) _txInitialized = _txInitialize();
08952 
08953 $   if (HWND wnd = txWindow())
08954         {
08955 $       SetLastErrorEx (ERROR_INVALID_DATA, 0);
08956 $       _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!"));
08957 $       return wnd;
08958         }
08959 
08960 $   if (!_txIsDll)
08961         {
08962 $       _txMain = ! FindAtom ("_txMain");  // Not a thread-safe
08963 $       (void)       AddAtom ("_txMain");  //-V530
08964         }
08965 
08966 $   if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; }  //-V1048
08967 
08968 $   _txRunning = false;
08969 
08970     // Store the size
08971 
08972 $   static SIZE size = { ROUND (sizeX), ROUND (sizeY) };
08973 $   if (centered) { size.cx *= -1; size.cy *= -1; }
08974 
08975     // In Thread, where REAL creation lies...
08976 
08977 $   unsigned id = 0;
08978 $   _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id);
08979 
08980 $   if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."),  (HWND) NULL;
08981 
08982 $   _txWaitFor (_txRunning, 10*_TX_TIMEOUT);
08983 
08984 $   if (!_txRunning)       return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL;
08985 $   if (!txOK())           return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."),     (HWND) NULL;
08986 
08987 $   HWND console = Win32::GetConsoleWindow();
08988 
08989 $   DWORD proc = 0;
08990 $   GetWindowThreadProcessId (console, &proc);
08991 
08992 $   if (console && (proc == GetCurrentProcessId() || _txIsParentListed (_TX_WAITABLE_PARENTS)))
08993         {$ ShowWindow (console, TX_CONSOLE_MODE); }
08994 
08995 $   HMENU menu = GetSystemMenu (txWindow(), false);
08996     if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); }
08997 
08998 $   Win32::GdiSetBatchLimit (1);
08999 
09000 $   SetLastError (0);
09001 
09002 $   errno = 0;
09003 
09004     #if !defined (__CYGWIN__)
09005 $   _doserrno = 0;
09006     #endif
09007 
09008 $   return txWindow();
09009     }
09010 
09011 //-----------------------------------------------------------------------------------------------------------------
09012 
09013 HWND txCreateExtraWindow (CREATESTRUCT createData)
09014     {
09015 $1  if (_TX_TXWINDOW_FAILED()) return NULL;
09016 
09017 $   volatile HWND wnd = NULL;
09018 $   createData.hInstance = (HINSTANCE)(uintptr_t) &wnd;
09019 
09020 $   PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted;
09021 
09022 $   _txWaitFor (wnd, 5*_TX_TIMEOUT);
09023 
09024 $   return wnd;
09025     }
09026 
09027 //-----------------------------------------------------------------------------------------------------------------
09028 
09029 bool txSetDefaults (HDC dc /*= txDC()*/)
09030     {
09031 $1  if (dc == txDC()) txUpdateWindow (false);  //-V601
09032 $   txAutoLock _lock;
09033 
09034 $   RECT r = {};
09035 $   GetClientRect (Win32::GetConsoleWindow(), &r);
09036 $   SIZE szCon = { r.right - r.left, r.bottom - r.top };
09037 
09038 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
09039 
09040 $   CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}};
09041 $   GetConsoleScreenBufferInfo (out, &con);
09042 
09043 $   SIZE szTxt = { (short) (con.srWindow.Right  - con.srWindow.Left + 1),
09044                    (short) (con.srWindow.Bottom - con.srWindow.Top  + 1) };
09045 
09046 //{ Set defaults for graphics layer
09047 
09048 $   _txBuffer_Select (Win32::GetStockObject (WHITE_PEN),   dc) asserted;
09049 $   _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted;
09050 
09051 $   _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx,
09052                                          0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
09053                                          RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
09054                                          DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT),
09055                       dc) asserted;
09056 
09057 $  (Win32::SetTextColor      (dc, TX_WHITE) != CLR_INVALID) asserted;
09058 $   Win32::SetBkMode         (dc, TRANSPARENT)              asserted;
09059 
09060 $   Win32::SetROP2           (dc, R2_COPYPEN)               asserted;
09061 $   Win32::SetStretchBltMode (dc, HALFTONE)                 asserted;
09062 
09063 //}
09064 
09065 $   if (dc != txDC())
09066         {$ return true; }
09067 
09068 //{ Set defaults for console  layer
09069 
09070 $   POINT szCanvas = txGetExtent (dc);
09071 
09072 $   HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)?
09073                        Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx,
09074                                           0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
09075                                           RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
09076                                           DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT)
09077                        :
09078                        Win32::GetStockObject (SYSTEM_FIXED_FONT);
09079 
09080 $   _txBuffer_Select (font, _txCanvas_BackBuf[1]);
09081 //}
09082 
09083 //{ Scroll the console for text to go above top of window and don't mix with graphics
09084 
09085 $   if (con.dwCursorPosition.X) _putch ('\n');
09086 
09087 $   short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top);
09088 
09089 $   con.srWindow.Top    = (short) (con.srWindow.Top    + delta);
09090 $   con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta);
09091 
09092 $   SMALL_RECT src  = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) };
09093 $   CHAR_INFO  fill = { {' '}, FOREGROUND_LIGHTGRAY };
09094 $   COORD      dest = { 0, (short) -delta };  // New UL-corner of src, scroll up
09095 
09096 $   con.dwCursorPosition.X = 0;
09097 $   con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta);
09098 
09099 $   (con.srWindow.Bottom < con.dwSize.Y &&                        // Move the "window"
09100      SetConsoleWindowInfo      (out, true, &con.srWindow))
09101     ||
09102     (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill),    // Or scroll the buffer
09103      SetConsoleCursorPosition  (out, con.dwCursorPosition));
09104 //}
09105 
09106 $   txUpdateWindow (true);  //-V601
09107 
09108     return true;
09109     }
09110 
09111 #endif // TX_COMPILED
09112 
09113 //-----------------------------------------------------------------------------------------------------------------
09114 
09115 inline bool txOK()
09116     {
09117     return (_txCanaryFirst == 0x776F656D &&  // Too well-known values to use constants. You know these values, don't you?
09118             _txCanaryLast  == 0x5E2E2E5E &&
09119             _txCanvas_OK()
09120 
09121     #if defined (_MSC_VER)
09122          && _CrtCheckMemory()
09123     #endif
09124             );
09125     }
09126 
09127 //-----------------------------------------------------------------------------------------------------------------
09128 //{          Cleanup
09129 //-----------------------------------------------------------------------------------------------------------------
09130 
09131 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09132 
09133 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain.
09134 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols
09135 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize().
09136 
09137 void _txOnCExit()
09138     {
09139     OutputDebugString ("\n");
09140 
09141 $5  _txCleanup();
09142 
09143     _TX_CALLv (Win32::_cexit, ());
09144     }
09145 
09146 //-----------------------------------------------------------------------------------------------------------------
09147 
09148 void _txOnExit (int retcode)
09149     {
09150     if (retcode != 0)
09151         {
09152         OutputDebugString ("\n");
09153         txOutputDebugPrintf ("%s - WARNING: %s (%d) called\n", _TX_VERSION, __func__, retcode);
09154         }
09155 
09156 $5  _txCleanup();
09157 
09158     if (retcode != 0)
09159         txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode);
09160 
09161     Win32::exit (retcode);
09162     }
09163 
09164 //-----------------------------------------------------------------------------------------------------------------
09165 
09166 void _txOnExitProcess (unsigned retcode)
09167     {
09168     if (retcode != 0)
09169         {
09170         OutputDebugString ("\n");
09171         txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode);
09172         }
09173 
09174 $5  _txCleanup();
09175 
09176     if (retcode != 0)
09177         txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode);
09178 
09179     Win32::ExitProcess (retcode);
09180     }
09181 
09182 //-----------------------------------------------------------------------------------------------------------------
09183 
09184 bool _txOnTerminateProcess (HANDLE process, unsigned retcode)
09185     {
09186     if (retcode != 0)
09187         {
09188         OutputDebugString ("\n");
09189         txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode);
09190         }
09191 
09192 $5  _txCleanup();
09193 
09194     if (retcode != 0)
09195         txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode);
09196 
09197     return Win32::TerminateProcess (process, retcode);
09198     }
09199 
09200 //-----------------------------------------------------------------------------------------------------------------
09201 
09202 void _txOnFatalExit (int retcode)
09203     {
09204     OutputDebugString ("\n");
09205     txOutputDebugPrintf ("%s - WARNING: %s (%d) called\n", _TX_VERSION, __func__, retcode);
09206 
09207 $5  _txCleanup();
09208 
09209     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode);
09210     _TX_CALLv (Win32::FatalExit, (retcode));
09211 
09212     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode);
09213     Win32::TerminateProcess (GetCurrentProcess(), retcode);
09214     }
09215 
09216 //-----------------------------------------------------------------------------------------------------------------
09217 
09218 void _txOnFatalAppExitA (unsigned action, const char message[])
09219     {
09220     OutputDebugString ("\n");
09221     txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message);
09222 
09223 $5  _txCleanup();
09224 
09225     txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message);
09226     _TX_CALLv (Win32::FatalAppExitA, (action, message));
09227 
09228     txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION);
09229     Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09230     }
09231 
09232 //-----------------------------------------------------------------------------------------------------------------
09233 
09234 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type)
09235     {
09236     OutputDebugString ("\n");
09237     txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type);
09238 
09239 $5  switch (type)
09240         {
09241         case CTRL_LOGOFF_EVENT:
09242         case CTRL_SHUTDOWN_EVENT: $ _txExit = true;
09243                                   $ _txCleanup();
09244         case CTRL_C_EVENT:
09245         case CTRL_CLOSE_EVENT:
09246         case CTRL_BREAK_EVENT:
09247 
09248         default:                  break;  //-V2522
09249         }
09250 
09251 $   return false;
09252     }
09253 
09254 //-----------------------------------------------------------------------------------------------------------------
09255 
09256 void _txCleanup()
09257     {
09258     if (!_txInitialized) return;
09259     else _txInitialized = false;  //-V601
09260 
09261 $3  _txRunning = false;
09262 $   _txConsole_IsBlinking = false;
09263 
09264 $   txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR);
09265 
09266 $   txSetWindowsHook (NULL);
09267 
09268 $   HWND     canvas  = txWindow();
09269 $   HWND     console = Win32::GetConsoleWindow();
09270 $   unsigned thread  = GetCurrentThreadId();
09271 
09272 $   HWND wnd         = (canvas)? canvas : console;
09273 
09274 $   bool externTerm  = (thread != _txMainThreadId &&
09275                         thread != _txCanvas_ThreadId);
09276 
09277 $   DWORD list[1] = {};
09278 $   DWORD ownsConsole = (GetConsoleProcessList (list, 1) <= 1);
09279 
09280 $   int    envPause       = -1;
09281 $   char   envPause_s[10] = "";
09282 $   size_t envPause_sz    = 0;
09283 $   getenv_s (&envPause_sz, envPause_s, sizeof (envPause_s) - 1, "TX_PAUSE");
09284 
09285     if (strcmp (envPause_s, "1") == 0 || _stricmp (envPause_s, "ON")  == 0) {$ envPause = 1; }
09286     if (strcmp (envPause_s, "0") == 0 || _stricmp (envPause_s, "OFF") == 0) {$ envPause = 0; }
09287 
09288 $   DWORD parent = 0;
09289 $   int  isParentWaitable = _txIsParentListed (_TX_WAITABLE_PARENTS, &parent);
09290 
09291 $   if (canvas)
09292         {$ txSleep (5*_txWindowUpdateInterval); }
09293 
09294 $   if (_txConsole)
09295         {
09296 $       if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
09297 
09298 $       if (console)
09299             {
09300 $           EnableWindow     (console, true);
09301 $           _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */);
09302             }
09303         }
09304 
09305 $   if (_txMain && !externTerm && canvas)
09306         {$  _txSetWindowText (canvas,  " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); }
09307 
09308 $   std::cout.flush();
09309 $   std::cerr.flush();
09310 $   std::clog.flush();
09311 $   _flushall();
09312 
09313 $   bool paused = false;
09314 $   if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId))
09315         {
09316 $       if (wnd)
09317             {
09318 $           int isVSCode = _txIsParentListed (_TX_VSCODE_PARENTS);
09319 
09320 $           if (isParentWaitable >= 0 && !isVSCode)
09321                 {$ _txActivateWindow (wnd, 0x10); }
09322 
09323 $           EnableWindow (wnd, true);
09324             }
09325 
09326 $       if ((console && (ownsConsole || canvas || _txErrors || envPause == 1)) && isParentWaitable >= 0 && !(envPause == 0))
09327             {
09328 $           txPause ((_txErrors)?               "\f\n" "[Press F to Pay Respects...]" :
09329                      (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f");
09330 
09331 $           paused = true;
09332             }
09333         }
09334 
09335 $   if (_txConsole && _txWatchdogTimeout >= 0)
09336      {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
09337 
09338 $   if (txWindow())
09339         {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); }
09340 
09341 $   _txWaitFor (!txWindow(), 5*_TX_TIMEOUT);
09342 
09343 $   txSpeak     (NULL);
09344 $   txPlayVideo (NULL);
09345 
09346 $   delete _txCanvas_UserDCs;
09347 $   _txCanvas_UserDCs = NULL;
09348 
09349 $   if (GetCurrentThreadId() != _txMainThreadId)
09350         {$ SuspendThread (_txMainThread);    }  //-V720
09351 $   if (GetCurrentThreadId() != _txCanvas_ThreadId)
09352         {$ SuspendThread (_txCanvas_Thread); }  //-V720
09353 
09354 $   if (_txMainThread)
09355         {$ CloseHandle (_txMainThread)    asserted; _txMainThread    = NULL; }
09356 $   if (_txCanvas_Thread)
09357         {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; }
09358 
09359 $   if (!txWindow())
09360         {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; }
09361 
09362 $   bool parentKilled = false;
09363 $   if (isParentWaitable && !externTerm && paused && _txNOP (_TX_ALLOW_KILL_PARENT))
09364         {
09365 $       console = Win32::GetConsoleWindow();
09366 
09367 $       if (parent)
09368             {$ parentKilled = _txKillProcess (parent); }
09369 
09370 $       if (parent && !parentKilled)
09371             {
09372 $           PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09373 $           PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09374             }
09375         }
09376 
09377 $   if (_txConsole)
09378         {$ _txSetWindowText (console, NULL); }
09379 
09380 $   if (_txMain && _txConsole)
09381         {$ _txConsole_Detach (isParentWaitable && !externTerm && !parentKilled); }  //-V560
09382 
09383 $   std::cout.flush();
09384 $   std::cerr.flush();
09385 $   std::clog.flush();
09386 $   _flushall();
09387 
09388 $   _txSymGetFromAddr (NULL);
09389 
09390     // That's all, folks
09391 
09392     _TX_ON_DEBUG (OutputDebugString ("\n");
09393                   OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n");
09394                   OutputDebugString ("\n"));
09395     }
09396 
09397 //-----------------------------------------------------------------------------------------------------------------
09398 
09399 int txPause (const char* message /*= NULL*/, ...)
09400     {
09401 $3  bool wine    = !!Win32::wine_get_version;
09402 
09403 $   HWND canvas  = txWindow();
09404 $   HWND console = _TX_CALL (Win32::GetConsoleWindow,());
09405 $   HWND wnd     = (canvas)? canvas : console;
09406 $   bool istty0  = _txIsTTY (0);
09407 
09408 $   int attr     = txGetConsoleAttr();
09409 
09410 $   int oldCP    = GetConsoleOutputCP();
09411 $   SetConsoleOutputCP (_TX_CODEPAGE);
09412 
09413     if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; }
09414 
09415     if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); }
09416     else                  {$ message++; }
09417 
09418     if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); }
09419     else                  {$ message++; }
09420 
09421 $   int isVSCode = _txIsParentListed (_TX_VSCODE_PARENTS);
09422 
09423 $   if (!isVSCode)
09424         {$ _txActivateWindow (wnd, 0x10); }
09425 
09426 $   va_list args;
09427 $   va_start (args, message);
09428 $   vfprintf (stderr, message, args);
09429 $   va_end (args);
09430 
09431 $   txOutputDebugPrintf ("%s - WARNING: PAUSE: %s\n", _TX_VERSION, (*message != '\n')? message : message+1);
09432 
09433 $   fflush (stderr);
09434 $   txSleep();
09435 
09436 $   Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF };
09437 $   _TX_CALL (Win32::FlashWindowEx, (&flash));
09438 
09439     if (console) {$ EnableWindow (console, true); }
09440 
09441 $   int ch = EOF;
09442     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09443 
09444 $   for (int i = 1; ; i++)  //-V2530
09445         {
09446 $       Sleep (_txWindowUpdateInterval);
09447 
09448         if (!istty0 && !canvas)                      {$ break; }
09449 
09450         if (!wine && (ch = _txGetInput()) != EOF)    {$ break; }
09451 
09452         if (canvas && !_txCanvas_ThreadId)           {$ break; }
09453 
09454         if (!_TX_CALL (Win32::GetConsoleWindow, ())) {$ break; }
09455 
09456         if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas)))
09457             {$ TX_ERROR ("Похоже, программа зависла :("); break; }
09458 
09459         if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas)))
09460             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; }
09461 
09462         if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL))
09463             {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает");  break; }
09464 
09465         if (!wine && !(i % 100500))
09466             {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...]  \b\b"); }
09467         }
09468 
09469     if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); }
09470 
09471 $   _txSetWindowText (wnd, NULL);
09472 
09473 $   fprintf (stderr, "\n");
09474 
09475     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09476 
09477 $   SetConsoleOutputCP (oldCP);
09478 $   txSetConsoleAttr (attr);
09479 
09480 $   return ch;
09481     }
09482 
09483 //-----------------------------------------------------------------------------------------------------------------
09484 
09485 int _txGetInput()
09486     {
09487 $4  HANDLE con = GetStdHandle (STD_INPUT_HANDLE);
09488 $   int ch = EOF;
09489 
09490 $   DWORD nChars = 0;
09491 $   if (GetConsoleMode (con, &nChars) == 0 &&
09492         PeekNamedPipe  (con, NULL, 0, NULL, &nChars, NULL))
09493         {
09494 $       ch = (nChars)? fgetc (stdin) : EOF;
09495         }
09496 
09497     else if (_kbhit())
09498         {
09499 $       ch = _getch();
09500         }
09501 
09502 #if defined (_MSC_VER) && (_MSC_VER < 1700)
09503 
09504     else if (fseek (stdin, 1, SEEK_CUR) != EOF)
09505         {
09506 $       (void) fseek (stdin, -1, SEEK_CUR);
09507 $       ch = fgetc (stdin);                                // This causes blocking in MSVC 2011 beta
09508         }
09509 
09510 #endif
09511 
09512     if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); }
09513 
09514 $   return ch;
09515     }
09516 
09517 //-----------------------------------------------------------------------------------------------------------------
09518 
09519 bool _txIsTTY (int fd)
09520     {
09521 $4  return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR;
09522     }
09523 
09524 //-----------------------------------------------------------------------------------------------------------------
09525 
09526 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/,
09527                       int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/)
09528     {
09529     struct tools
09530         {
09531         static LRESULT getWindowText (HWND window, wchar_t text[], size_t size)
09532             {
09533 $3          memset (text, 0, size * sizeof (*text));
09534 
09535 $           return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09536             }
09537 
09538         static LRESULT setWindowText (HWND window, wchar_t text[])
09539             {
09540 $1          return SendMessageTimeoutW (window, WM_SETTEXT, 0,             (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL);
09541             }
09542         };
09543 
09544 $1  static wchar_t _tx_thread title    [_TX_BUFSIZE+15] = L"TXLib";
09545 $   static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib";
09546 
09547 $   if (!textRus)
09548         {
09549 $       tools::setWindowText (wnd, oldTitle);
09550 $       return -1;
09551         }
09552 
09553 $   tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09554 $   int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1;
09555 $   memcpy (oldTitle, title, sizeof (oldTitle));
09556 
09557 $   if (textRus)
09558         {
09559 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len);
09560 
09561 $       tools::setWindowText (wnd, title);
09562 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09563         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; }
09564         if (!checkLetters) {$ return -2; }
09565         }
09566 
09567 $   if (textEng)
09568         {
09569 $       MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len);
09570 
09571 $       tools::setWindowText (wnd, title);
09572 $       tools::getWindowText (wnd, title, _TX_BUFSIZE-1);
09573         if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; }
09574         if (!checkLetters) {$ return -2; }
09575         }
09576 
09577 $   return -3;
09578     }
09579 
09580 //-----------------------------------------------------------------------------------------------------------------
09581 
09582 int _txIsParentListed (const char* list, DWORD* parentPID /*= NULL*/)
09583     {
09584 $4  PROCESSENTRY32* info = _txFindProcess();
09585 $   if (!info) return 0;
09586 
09587 $   info = _txFindProcess (info->th32ParentProcessID);
09588 $   if (!info) return 0;
09589 
09590 $   char parent [MAX_PATH] = "";
09591 $   strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1);
09592 $   if (parentPID) *parentPID = info->th32ProcessID;
09593 
09594 $   info = _txFindProcess (info->th32ParentProcessID);          // info: grandparent
09595 
09596 $   char lst[_TX_BUFSIZE] = "";
09597 $   strncpy_s (lst, sizeof (lst), list, strlen (list));
09598 
09599 $   char* ctx = NULL;
09600 $   for (char* p = strtok_s (lst, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx))
09601         {
09602 $       char* gp = strchr (p, ':');
09603 
09604 $       if (gp)
09605             {
09606 $           *gp++ = 0;
09607 
09608 $           if (_stricmp (p, parent) != 0) { continue; }
09609 
09610 $           if (info) if (_stricmp (gp, info->szExeFile) == 0)  // Was &&, but MSVC /analyze is so paranoid
09611                 {$ return islower ((unsigned char) *gp)? +1 : -1; }
09612             }
09613         else
09614             {
09615 $           if (_stricmp (p, parent) == 0)
09616                 {$ return islower ((unsigned char)  *p)? +1 : -1; }
09617             }
09618         }
09619 
09620 $   return 0;
09621     }
09622 
09623 //-----------------------------------------------------------------------------------------------------------------
09624 
09625 void _txWatchdogTerminator (void* timeout)  // Or Watchcat? Possibly will change in future versions
09626     {
09627 $3  if (_TX_ARGUMENT_FAILED (timeout)) return;
09628 
09629 $   Sleep (*(int*) timeout);  //-V206
09630 
09631 $   OutputDebugString ("\n");
09632     txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n",  // Kinda static reflection...
09633                          _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow"));  //-V206
09634 $   DWORD parent = 0;
09635 $   if (_txIsParentListed (_TX_WAITABLE_PARENTS, &parent))
09636         {
09637         txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n",
09638                              _TX_VERSION, __func__, (unsigned long) parent);
09639 
09640 $       _txKillProcess (parent);
09641 
09642 $       HWND console = GetConsoleWindow();
09643 $       PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001);  // Scancode = 0x1C, Count = 1
09644 $       PostMessage (console, WM_KEYUP,   VK_RETURN, 0xC01C0001);  // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1
09645         }
09646 
09647     txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__);
09648 $   Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
09649     }
09650 
09651 #endif // TX_COMPILED
09652 
09653 //}
09654 //-----------------------------------------------------------------------------------------------------------------
09655 
09656 //-----------------------------------------------------------------------------------------------------------------
09657 //{          Tools
09658 //-----------------------------------------------------------------------------------------------------------------
09659 
09660 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
09661 
09662 // You are here, little hacker?
09663 
09664 int _txTaskKill (const char i[] /*= NULL*/,
09665                  const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/,
09666                  unsigned   x   /*= 0*/)
09667     {
09668     // ...so tired of it already...
09669 
09670     #define name          i  // Great name!
09671     #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine
09672     #define pid           x  // Another great name, isn't it?
09673 
09674 $3  if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false;  //-V560 //-V601
09675 
09676 $   wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L"";
09677     if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); }
09678 
09679 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09680 $   assert (sshot); if (!sshot) return 0;  //-V547
09681 
09682 $   int killed = 0;
09683 
09684 $   PROCESSENTRY32 info = { sizeof (info) };
09685 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09686         {
09687         bool kill = false;
09688 
09689         if (!kill && pid  && info.th32ParentProcessID        == pid) {$ kill = true; }  //-V560
09690 
09691         if (!kill && name && _stricmp (info.szExeFile, name) == 0)   {$ kill = true; }
09692 
09693         if (!kill)
09694             {
09695             wchar_t cmdLineW[_TX_BUFSIZE] = L"";
09696             if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; }
09697 
09698             if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW))    {$ kill = true; }
09699             }
09700 
09701         if (kill)
09702             {
09703 $           if (_txKillProcess (info.th32ProcessID))
09704                 {$ killed++; }
09705             }
09706         }
09707 
09708 $   CloseHandle (sshot);
09709 
09710 $   return killed;
09711 
09712     #undef name
09713     #undef cmdLine
09714     #undef pid
09715     }
09716 
09717 //-----------------------------------------------------------------------------------------------------------------
09718 
09719 bool _txKillProcess (DWORD pid)
09720     {
09721 $3  if (_TX_ARGUMENT_FAILED (pid)) return false;
09722 
09723 $   HANDLE token = INVALID_HANDLE_VALUE;
09724 $   OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted;
09725 
09726 $   LUID luid = {};
09727 $   LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted;
09728 
09729 $   TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}};
09730 $   TOKEN_PRIVILEGES old  = {};
09731 
09732 $   DWORD oldSz = 0;
09733 $   AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted;
09734 
09735 $   HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid);
09736 $   if (!proc) return false;
09737 
09738 $   bool ok = !!Win32::TerminateProcess (proc, 0);
09739 $   CloseHandle (proc);
09740 
09741 $   return ok;
09742     }
09743 
09744 //-----------------------------------------------------------------------------------------------------------------
09745 
09746 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/)
09747     {
09748 $4  static PROCESSENTRY32 info = { sizeof (info) };
09749 $   if (!pid) return &info;
09750 
09751 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
09752 $   assert (sshot); if (!sshot) return NULL;  //-V547
09753 
09754 $   for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info))
09755         if (info.th32ProcessID == pid) break;
09756 
09757 $   CloseHandle (sshot);
09758 
09759 $   return &info;
09760     }
09761 
09762 //-----------------------------------------------------------------------------------------------------------------
09763 
09764 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/)
09765     {
09766 $9  if (_TX_ARGUMENT_FAILED (cmdLine))        return false;
09767 $   if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false;  //-V547
09768 
09769 $   if (pid == (unsigned) _getpid())
09770         {
09771 $       wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1);
09772 $       return true;
09773         }
09774 
09775 $   HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
09776     if (!proc) {$ return false; }
09777 
09778 $   Win32::PROCESS_BASIC_INFORMATION pbi = {};
09779 $   bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0);
09780 
09781     // Should use ReadProcessMemory() because the info is actually in another address space
09782 
09783 $   Win32::PEB peb = {};
09784     if (ok && pbi.PebBaseAddress)        {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress,        &peb,    sizeof (peb),    NULL); }
09785 
09786 $   Win32::RTL_USER_PROCESS_PARAMETERS params = {};
09787     if (ok && peb.ProcessParameters)     {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters,     &params, sizeof (params), NULL); }
09788 
09789 $   *cmdLine = 0;
09790     if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine,  //-V106
09791                                                                        MIN  (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2),  //-V202
09792                                                                        NULL); }
09793 $   CloseHandle (proc) asserted;
09794 
09795 $   return ok;
09796     }
09797 
09798 //-----------------------------------------------------------------------------------------------------------------
09799 
09800 #define RVA_(type, module, addr)  ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) )
09801 
09802 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/)
09803     {
09804 $4  assert (module);
09805 
09806 $   IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0);
09807 $   IMAGE_NT_HEADERS* ntHdr  = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew);
09808 
09809 $   return (dosHdr->e_magic  == IMAGE_DOS_SIGNATURE &&
09810             ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL;
09811     }
09812 
09813 //-----------------------------------------------------------------------------------------------------------------
09814 
09815 // TXLib continues to hack the reality to make your life better, sweeter and easier
09816 
09817 #ifdef _CLANG_VER
09818 #pragma clang attribute  push (__attribute__((no_sanitize ("undefined"))), apply_to = function)
09819 #endif
09820 
09821 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/,
09822                              HMODULE module /*= NULL*/, bool debug /*= false*/)
09823     {
09824 $4  if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module);
09825 
09826 $   if (_TX_ARGUMENT_FAILED (funcName)) return 0;
09827 $   if (_TX_ARGUMENT_FAILED (newFunc))  return 0;
09828 
09829 $   if (!module) module = GetModuleHandle (NULL);
09830 $   if (!module) return 0;
09831 
09832 $   HMODULE dll     = (dllName)? GetModuleHandle (dllName)       : NULL;
09833 $   PROC    oldFunc = (dll)?     GetProcAddress  (dll, funcName) : NULL;
09834 
09835 $   if (useHotPatching && oldFunc)
09836         {
09837 $       const size_t jmpSz = 1 + sizeof (DWORD);  // sizeof (JMP rel instruction)
09838 
09839 $       DWORD oldRights = 0;
09840 $       if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0;
09841 
09842         // Overwrite oldFunc prolog with JMP trampoline to newFunc.
09843         // Calling oldFunc from any location will lead to newFunc call anyway.
09844 
09845 $       *(BYTE*)  ((char*)(uintptr_t) oldFunc + 0) = 0xE9;  // JMP rel
09846 $       *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF;  //-V206 //-V112 //-V2007 //-V104 //-V103
09847 
09848 $       FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz);
09849 
09850 $       VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights);
09851 
09852 $       return (uintptr_t) oldFunc;
09853         }
09854 
09855 //  For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255
09856 //  and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html.
09857 
09858 $   IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module);
09859     if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; }
09860 
09861 $   DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
09862 $   IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset);
09863 
09864 $   if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0;  //-V1027
09865 
09866 $   IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL;
09867 $   char*  impDll  = NULL;
09868 $   char*  impName = NULL;
09869 $   void** impPtr  = NULL;
09870 $   bool   found   = false;
09871 
09872     for (; desc->Name; desc++)
09873         {
09874 $       impDll = RVA_ (char*, module, desc->Name);
09875 $       if (dllName && _stricmp (impDll, dllName) != 0) continue;
09876 
09877 $       for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk),
09878              thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk);
09879 
09880              thunk0 && thunk1 && thunk1->u1.Function;
09881 
09882              thunk0++,
09883              thunk1++)
09884             {
09885             impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name;
09886             impPtr  = (void**)(uintptr_t)                         &thunk1->u1.Function;  // Should change it, so this is ptr
09887 
09888             if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL;
09889 
09890             if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName);
09891 
09892             if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) ||
09893                 (impName && _stricmp (funcName, impName) == 0))  //-V560
09894                 {
09895                 found = true;
09896                 break;
09897                 }
09898             }
09899 
09900 $       if (found) break;
09901         }
09902 
09903     if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n",
09904                                     funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found"));
09905 $   if (!found) return 0;
09906 
09907 $   DWORD rights = PAGE_READWRITE;
09908 $   if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0;
09909 
09910 $   *(uintptr_t*) impPtr = newFunc;
09911 
09912 $   VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights);
09913 
09914 $   return (uintptr_t) oldFunc;
09915     }
09916 
09917 #ifdef _CLANG_VER
09918 #pragma clang attribute  pop
09919 #endif
09920 
09921 #undef RVA_
09922 
09923 //-----------------------------------------------------------------------------------------------------------------
09924 
09925 bool _txInDll()
09926     {
09927 $4  MODULEENTRY32 mod = { sizeof (mod) };
09928 
09929 $   HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
09930 $   assert (sshot); if (!sshot) return false;  //-V547
09931 
09932 $   bool inDll = false;
09933 
09934 $   for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod))
09935         {
09936 $       if (!mod.modBaseAddr) continue;
09937 
09938 $       IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr);
09939 
09940 $       inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0);
09941 
09942 $       if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize))  //-V104
09943             {$ break; }
09944         }
09945 
09946 $   CloseHandle (sshot);
09947 $   return inDll;
09948     }
09949 
09950 //-----------------------------------------------------------------------------------------------------------------
09951 
09952 bool _txIsConsoleSubsystem()
09953     {
09954 $4  IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders();
09955 
09956 $   return  ntHdr &&
09957             ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC &&
09958 
09959            (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI ||
09960             ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI);
09961     }
09962 
09963 //-----------------------------------------------------------------------------------------------------------------
09964 
09965 bool _txIsBadReadPtr (const void* address)
09966     {
09967     MEMORY_BASIC_INFORMATION mbi = {};
09968     if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true;
09969 
09970     if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS))  return true;  // Guard page -> bad ptr
09971 
09972     DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
09973 
09974     return !(mbi.Protect & readRights);
09975     }
09976 
09977 //-----------------------------------------------------------------------------------------------------------------
09978 
09979 void _txActivateWindow (HWND wnd, unsigned mode)
09980     {
09981 $1  EnableWindow (wnd, true);
09982 
09983 $   if (mode & 0x20)
09984         {
09985 $       ShowWindow (wnd, SW_MINIMIZE);
09986 $       ShowWindow (wnd, SW_RESTORE);
09987         }
09988 
09989 $   if (mode & 0x10)
09990         {
09991 $       int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0);
09992 
09993 $       AttachThreadInput (GetCurrentThreadId(), focus, true);
09994 
09995 $       ShowWindow (wnd, SW_SHOW);
09996 
09997 $       AllowSetForegroundWindow (ASFW_ANY);
09998 $       LockSetForegroundWindow (LSFW_UNLOCK);
09999 $       keybd_event ((byte) VK_LMENU, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); // https://stackoverflow.com/questions/10740346
10000 $       SetForegroundWindow (wnd);
10001 
10002 $       _txWaitFor (GetForegroundWindow() == wnd, _TX_TIMEOUT);
10003 
10004 $       AttachThreadInput (GetCurrentThreadId(), focus, false);
10005         }
10006 
10007 $   if (mode & 0x08)
10008         {
10009 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
10010         }
10011 
10012 $   if (mode & 0x04)
10013         {
10014 $       SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS);
10015         }
10016 
10017 $   if (mode & 0x02)
10018         {
10019 $       UpdateWindow (wnd);
10020         }
10021 
10022 $   if (mode & 0x01)
10023         {
10024 $       RECT r = {};
10025 $       GetWindowRect (wnd, &r);
10026 $       mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, r.left, r.top, 0, 0);
10027 $       Sleep (100);
10028 $       mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP,   r.left, r.top, 0, 0);
10029 $       Sleep (100);
10030         }
10031     }
10032 
10033 #endif // TX_COMPILED
10034 
10035 //}
10036 //-----------------------------------------------------------------------------------------------------------------
10037 
10039 //}
10040 //=================================================================================================================
10041 
10042 //=================================================================================================================
10043 //{          Internal TXLib window functions     (_txCanvas...)
10045 //=================================================================================================================
10046 
10047 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10048 
10049 unsigned WINAPI _txCanvas_ThreadProc (void* data)
10050     {
10051     #define SetClassLong_  SetClassLongPtr
10052     #define GCL_HICON_     GCLP_HICON
10053     #define GCL_HICONSM_   GCLP_HICONSM
10054     #define GCL_HCURSOR_   GCLP_HCURSOR
10055 
10056 $8  _txCanvas_ThreadId = GetCurrentThreadId();
10057 
10058 $   if (_TX_ARGUMENT_FAILED (data)) return false;  //-V601
10059 
10060 $   unsigned long stackSize = _TX_STACKSIZE;
10061 $   _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize));
10062 
10063 $   HWND wnd = _txCanvas_CreateWindow ((SIZE*) data);
10064 $   if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0;
10065 
10066 $   HICON   icon32 = LoadIcon         (NULL, "_TX_ICON");
10067 $   HICON   icon16 = LoadIcon         (NULL, "_TX_ICONSM");
10068 $   HCURSOR cursor = LoadCursor       (NULL, "_TX_CURSOR");
10069 $   HMENU   menu   = LoadMenu         (NULL, "_TX_MENU");
10070 $   HACCEL  accel  = LoadAccelerators (NULL, "_TX_ACCELERATORS");
10071 
10072 $   SetClassLong_ (wnd, GCL_HICON_,   (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32)));          //-V107 //-V112
10073 $   SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16)));          //-V107
10074 $   SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW)));  //-V107
10075 
10076     if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); }
10077 
10078 $   Win32::GdiSetBatchLimit (1);
10079 
10080     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n"));
10081 
10082 $   _txActivateWindow (wnd, 0x20);
10083 
10084 $   ShowWindow   (wnd, SW_SHOW);
10085 $   UpdateWindow (wnd);
10086 
10087 $   _txRunning = true;
10088 
10089 $   MSG msg = {};
10090 $   while (GetMessage (&msg, NULL, 0, 0))
10091         {
10092         if (!msg.hwnd) {$ continue; }
10093 
10094         if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; }
10095 
10096 $       TranslateMessage (&msg);
10097 $       DispatchMessage  (&msg);
10098 
10099 $       Sleep (0);
10100         }
10101 
10102 $   if (icon16) DestroyIcon (icon16);  // If Explorer is displaying Tray Notification, these
10103 $   if (icon32) DestroyIcon (icon32);  // calls will possibly fail, and we'll get resource leak.
10104 
10105 $   LeaveCriticalSection (&_txCanvas_LockBackBuf);
10106 
10107     _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n"));
10108 
10109 $   if (_txWatchdogTimeout >= 0)
10110         {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); }
10111 
10112 $   if (_txRunning && _txMain)         // Main window is destroyed but main() is still running.
10113         {                              // No chances for good termination, so use exit().
10114 $       _txCleanup();
10115 $       ::exit ((int) msg.wParam);     //-V202 //-V2509 //-V2014
10116         }
10117 
10118 $   _txCanvas_ThreadId = 0;
10119 $   return true;                       //-V601
10120 
10121     #undef SetClassLong
10122     #undef GCL_HICON_
10123     #undef GCL_HICONSM_
10124     #undef GCL_HCURSOR_
10125     }
10126 
10127 //-----------------------------------------------------------------------------------------------------------------
10128 
10129 HWND _txCanvas_CreateWindow (const SIZE* sizePtr)
10130     {
10131 $8  if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL;
10132 
10133 $   bool centered = false;
10134     if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; }
10135 
10136 $   SIZE screen  = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) };
10137 $   RECT rect    = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false);
10138 $   SIZE size    = { rect.right - rect.left, rect.bottom - rect.top };
10139 $   RECT conPos  = {};
10140 
10141 $   HWND console = _TX_CALL (Win32::GetConsoleWindow, ());
10142     if (console) {$ GetWindowRect (console, &conPos); }
10143 
10144 $   const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0);
10145 $   if (!wndClass) return (HWND) NULL;
10146 
10147 $   HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN,
10148                               (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT,
10149                               (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top  : CW_USEDEFAULT,
10150                                size.cx, size.cy, NULL, NULL, NULL, NULL);
10151 $   if (!wnd || !txWindow())
10152         {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; }
10153 
10154 $   HMENU menu = GetSystemMenu (txWindow(), false);
10155     if (!menu) {$ return txWindow(); }
10156 
10157 $   AppendMenu (menu, MF_SEPARATOR, 0, NULL)                       asserted;
10158 $   AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted;
10159 $   AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT,   "&About...")     asserted;
10160 
10161 $   return txWindow();
10162     }
10163 
10164 //-----------------------------------------------------------------------------------------------------------------
10165 
10166 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra)
10167     {
10168 $8  assert (classId);
10169 $   assert (wndProc);
10170 
10171 $   static char name[_TX_BUFSIZE] = "";
10172 $   _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ "
10173                                              _TX_VERSION "  " __FILE__ "  WndClass %08lX "
10174                                              "-------------[%s]-[TXLib]---*/",
10175                                              classId, (unsigned long) GetTickCount(), classId);
10176 $   WNDCLASS wc      = { sizeof (wc) };
10177 
10178 $   wc.lpszClassName = name;
10179 $   wc.lpfnWndProc   = wndProc;
10180 $   wc.style         = style;
10181 $   wc.cbWndExtra    = (wndExtra + 1) * (int) sizeof (long);
10182 
10183 $   wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
10184 $   wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush);
10185 
10186 $   ATOM atom = RegisterClass (&wc);
10187     if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; }
10188 
10189 $   return (const char*)(uintptr_t) atom;
10190     }
10191 
10192 //-----------------------------------------------------------------------------------------------------------------
10193 
10194 int _txCanvas_SetRefreshLock (int count)
10195     {
10196 $8  int oldCount = _txCanvas_RefreshLock;
10197 
10198 $   _txCanvas_RefreshLock = count;
10199 
10200 $   HWND wnd = txWindow();
10201 
10202 $   if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd)
10203         {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
10204 
10205 $   return oldCount;
10206     }
10207 
10208 //-----------------------------------------------------------------------------------------------------------------
10209 
10210 HICON _txCreateTXIcon (int size)
10211     {
10212 $8  if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL;  //-V112 //-V560
10213 
10214 $   const unsigned char image32 [32*32+1] =
10215         "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0"
10216         "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0"
10217         "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0"
10218         "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0"
10219         "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0"
10220         "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0"
10221         "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0"
10222         "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000";
10223 
10224 $   const unsigned char image16 [16*16+1] =
10225         "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990"
10226         "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000";
10227 
10228 $   const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0,
10229                                       0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff };
10230 
10231 $   const unsigned char* image = (size == 32)? image32 : image16;  //-V112
10232 
10233 $   POINT sz = { size, size };
10234 $   HDC dcMask  = _txBuffer_Create (txWindow(), &sz); assert (dcMask);
10235 $   HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor);
10236 
10237 $   for (int i = 0; i < size*size; i++)
10238         {
10239         assert (In (std::nomeow, image[i], '0', '9') ||
10240                 In (std::nomeow, image[i], 'A', 'F'));
10241 
10242         Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']);
10243         }
10244 
10245 $   ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask,  OBJ_BITMAP),
10246                                   (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) };
10247 
10248 $   HICON icon = CreateIconIndirect (&info);
10249 $   assert (icon);
10250 
10251 $   _txBuffer_Delete (&dcMask)  asserted;
10252 $   _txBuffer_Delete (&dcColor) asserted;
10253 
10254 $   return icon;
10255     }
10256 
10257 #endif // TX_COMPILED
10258 
10259 //-----------------------------------------------------------------------------------------------------------------
10260 
10261 inline bool _txCanvas_OK()
10262     {
10263     return _txCanvas_ThreadId   &&
10264            _txCanvas_Window     &&
10265            _txCanvas_BackBuf[0] &&
10266            _txCanvas_BackBuf[1] &&
10267            _txCanvas_Pixels;
10268     }
10269 
10270 //}
10271 //=================================================================================================================
10272 
10273 //=================================================================================================================
10274 //{          Main window event handlers          (_txCanvas_On...)
10276 //=================================================================================================================
10278 
10279 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10280 
10281 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
10282     {
10283 #if defined (_TX_ALLOW_TRACE)
10284 
10285     int inTX = _txLoc::Cur.inTX++;
10286 
10287     if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)",
10288                                      2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar);
10289     _txLoc::Cur.inTX = inTX;
10290 
10291 #endif
10292 
10293 $8  if (msg == WM_KEYDOWN && wpar == VK_F12 &&
10294         GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU))
10295         {
10296 $       _txCanvas_OnCmdABOUT (wnd,      wpar);
10297 $       return DefWindowProc (wnd, msg, wpar, lpar);
10298         }
10299 
10300     WNDPROC altWndProc = _txAltWndProc;  // Cache to prevent change from main thread
10301     if (altWndProc)
10302         {
10303 $       LRESULT res = altWndProc (wnd, msg, wpar, lpar);
10304 $       if (res) return res;
10305         }
10306 
10307     static bool bkErased = false;
10308 
10309     switch (msg)
10310         {
10311         case WM_CREATE:         {$     _txCanvas_OnCREATE     (wnd);                    return 0; }
10312 
10313         case WM_CLOSE:          {$ if (_txCanvas_OnCLOSE      (wnd))  break;       else return 0; }
10314         case WM_DESTROY:        {$     _txCanvas_OnDESTROY    (wnd);                    return 0; }
10315 
10316         case WM_ERASEBKGND:     {$ if (!bkErased) { bkErased = true;  break; }     else return 1; }
10317         case WM_SIZE:           {$                  bkErased = false; break;                      }
10318 
10319         case WM_PAINT:          {$     _txCanvas_OnPAINT      (wnd);                    return 0; }
10320 
10321         case WM_TIMER:          {$     _txCanvas_OnTIMER      (wnd, wpar);              return 0; }
10322 
10323         case WM_KEYUP:          {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, false)) return 0; else break; }
10324         case WM_KEYDOWN:        {$ if (_txCanvas_OnKEY        (wnd, wpar, lpar, true))  return 0; else break; }
10325         case WM_CHAR:           {$ if (_txCanvas_OnCHAR       (wnd, wpar, lpar))        return 0; else break; }
10326 
10327         case WM_LBUTTONUP:
10328         case WM_LBUTTONDOWN:
10329         case WM_RBUTTONUP:
10330         case WM_RBUTTONDOWN:
10331         case WM_MBUTTONUP:
10332         case WM_MBUTTONDOWN:
10333         case WM_MOUSEMOVE:      {$     _txCanvas_OnMOUSEMOVE  (wnd, wpar, lpar);        return 0; }
10334 
10335         case WM_MOUSELEAVE:     {$     _txCanvas_OnMOUSELEAVE (wnd);                    return 0; }
10336 
10337         case _TX_WM_CREATEWND:  {$     _txCanvas_OnCREATEWND  (wnd, wpar, lpar);        return 0; }
10338         case _TX_WM_DESTROYWND: {$     _txCanvas_OnDESTROYWND (wnd, wpar, lpar);        return 0; }
10339 
10340         case WM_NULL:           {$                                                      return 0; }
10341 
10342         default: break;  //-V2522
10343         }
10344 
10345     if (msg == WM_SYSCOMMAND) switch (wpar)
10346         {
10347         case _TX_IDM_ABOUT:     {$     _txCanvas_OnCmdABOUT   (wnd, wpar);              return 0; }
10348         case _TX_IDM_CONSOLE:   {$     _txCanvas_OnCmdCONSOLE (wnd, wpar);              return 0; }
10349 
10350         default: break;  //-V2522
10351         }
10352 
10353 $   return DefWindowProc (wnd, msg, wpar, lpar);
10354     }
10355 
10356 //-----------------------------------------------------------------------------------------------------------------
10357 
10358 bool _txCanvas_OnCREATE (HWND wnd)
10359     {
10360 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10361 
10362 $   _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]);
10363 $   _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL);              assert (_txCanvas_BackBuf[1]);
10364 
10365 $   if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0;
10366 $   assert (_txCanvas_RefreshTimer);
10367 
10368 $   _txCanvas_UserDCs = new ::std::vector <HDC>;
10369 
10370 $   _txCanvas_Window = wnd;
10371 
10372 $   txSetDefaults();
10373 
10374 $   return true;
10375     }
10376 
10377 //-----------------------------------------------------------------------------------------------------------------
10378 
10379 bool _txCanvas_OnDESTROY (HWND wnd)
10380     {
10381 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10382 
10383     // Инициируем остановку цикла сообщений
10384 
10385 $   PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS);
10386 
10387 $   if (!_txCanvas_Window) return false;
10388 
10389     // Indicate that we are about to manually terminate
10390 
10391 $   _txExit = true;
10392 
10393     // Lock GDI resources
10394 
10395 $   bool locked = false;
10396 $   _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT);
10397 $   if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources");
10398 
10399     // Освобождаем пользовательские ресурсы
10400 
10401 $   if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty())
10402         {
10403 $       txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size());  //-V202
10404 $       Sleep (_TX_TIMEOUT);
10405 
10406 $       for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i));
10407 $       _txCanvas_UserDCs->clear();
10408         }
10409 
10410     // Освобождаем ресурсы, связанные с окном
10411 
10412 $   if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted;
10413 
10414 $   if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1])  asserted;
10415 $   if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0])  asserted;
10416 $   _txCanvas_Pixels = NULL;
10417 
10418 $   txUnlock();
10419 
10420     // Indicate that we are destroyed
10421 
10422 $   _txCanvas_Window = NULL;
10423 
10424 $   return true;
10425     }
10426 
10427 //-----------------------------------------------------------------------------------------------------------------
10428 
10429 bool _txCanvas_OnCLOSE (HWND wnd)  //-V2009 //-V2558
10430     {
10431 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10432 $   if (!_txCanvas_OK())           return false;
10433 
10434 $   if (_txMain && _txRunning &&
10435         txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n"
10436                       "Лучше подождать, когда main() завершится - это отображается в заголовке окна.",
10437                       txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false;
10438 $   return true;
10439     }
10440 
10441 //-----------------------------------------------------------------------------------------------------------------
10442 
10443 bool _txCanvas_OnTIMER (HWND wnd, WPARAM)
10444     {
10445 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10446 
10447 $   if (_txCanvas_RefreshLock > 0 || !_txRunning) return false;
10448 
10449 $   InvalidateRect (wnd, NULL, false) asserted;
10450 $   UpdateWindow   (wnd)              asserted;
10451 
10452 $   return true;
10453     }
10454 
10455 //-----------------------------------------------------------------------------------------------------------------
10456 
10457 bool _txCanvas_OnPAINT (HWND wnd)
10458     {
10459 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10460 $   if (!_txCanvas_OK())           return false;
10461 
10462 $   bool forceRedraw = GetAsyncKeyState (VK_MENU)  && GetAsyncKeyState (VK_CONTROL) &&
10463                        GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT);
10464 
10465 $   PAINTSTRUCT ps = {};
10466 $   HDC wndDc = BeginPaint (wnd, &ps);
10467 $   if (!wndDc) return false;
10468 
10469 $   HDC dc0 = _txCanvas_BackBuf[0],
10470         dc1 = _txCanvas_BackBuf[1];
10471 
10472 $   RECT r = {};
10473 $   GetClientRect (wnd, &r) asserted;
10474 $   POINT wndSize = { r.right - r.left, r.bottom - r.top };
10475 
10476 $   POINT dcSize = txGetExtent (dc1);
10477 
10478 $   if ((_txCanvas_RefreshLock <= 0 || forceRedraw) &&
10479         txLock (false))
10480         {
10481 $       Win32::BitBlt          (dc1,   0, 0, dcSize.x,  dcSize.y,  dc0, 0, 0, SRCCOPY);
10482 
10483 $       if (_txConsole >= 0)
10484             {$ _txConsole_Draw (dc1); }
10485 
10486 $       txUnlock();
10487         }
10488 
10489     // Magic 100500 value is used to completely block screen refresh.
10490     // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL.
10491     // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers
10492     // themselves.
10493     // Yes guys, with all your software installed. :(
10494 
10495 $   if (_txCanvas_RefreshLock != 100500)
10496         {
10497         if (_txSwapBuffers)
10498             {
10499 $           _txSwapBuffers     (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10500             }
10501         else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y)
10502             {
10503 $           Win32::BitBlt      (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0,                     SRCCOPY);
10504             }
10505         else
10506             {
10507 $           Win32::SetStretchBltMode (wndDc, HALFTONE);
10508 $           Win32::StretchBlt  (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY);
10509             }
10510         }
10511 
10512 $   EndPaint (wnd, &ps) asserted;
10513 
10514 $   return true;
10515     }
10516 
10517 //-----------------------------------------------------------------------------------------------------------------
10518 
10519 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info)
10520     {
10521 $8  INPUT_RECORD evt[2] = {};
10522 
10523 $   evt[0].EventType                        = KEY_EVENT;
10524 $   evt[0].Event.KeyEvent.bKeyDown          = true;
10525 $   evt[0].Event.KeyEvent.wRepeatCount      = 1;
10526 $   evt[0].Event.KeyEvent.uChar.AsciiChar   = (char) (ch);
10527 $   evt[0].Event.KeyEvent.wVirtualScanCode  = (WORD) (info >> 16);
10528 $   evt[0].Event.KeyEvent.wVirtualKeyCode   = (WORD) MapVirtualKey ((WORD) (info >> 16), 3);  // 3 == MAPVK_VSC_TO_VK_EX
10529 $   evt[0].Event.KeyEvent.dwControlKeyState = 0;
10530 
10531 $   evt[1] = evt[0];
10532 $   evt[1].Event.KeyEvent.bKeyDown          = false;
10533 
10534 $   DWORD written = 0;
10535 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE),  evt, 2, &written);
10536 
10537 $   return true;
10538     }
10539 
10540 //-----------------------------------------------------------------------------------------------------------------
10541 
10542 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down)
10543     {
10544 $8  INPUT_RECORD evt = {};
10545 
10546 $   evt.EventType                           = KEY_EVENT;
10547 $   evt.Event.KeyEvent.bKeyDown             = down;
10548 $   evt.Event.KeyEvent.wRepeatCount         = 1;
10549 $   evt.Event.KeyEvent.uChar.AsciiChar      = (char)  MapVirtualKey ((WORD) vk, 2);           // 2 == MAPVK_VK_TO_CHAR
10550 $   evt.Event.KeyEvent.wVirtualScanCode     = (WORD)  (info >> 16);
10551 $   evt.Event.KeyEvent.wVirtualKeyCode      = (WORD)  vk;
10552 $   evt.Event.KeyEvent.dwControlKeyState    = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0;
10553 
10554 $   if (evt.Event.KeyEvent.uChar.AsciiChar) return false;  // Let TranslateMessage() and WM_CHAR do the job
10555 
10556 $   DWORD written = 0;
10557 $   WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written);
10558 
10559 $   return true;
10560     }
10561 
10562 //-----------------------------------------------------------------------------------------------------------------
10563 
10564 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords)
10565     {
10566 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10567 $   if (!_txCanvas_OK())           return false;
10568 
10569 $   if (_txMousePos.x == -1 && _txMousePos.y == -1)
10570         {
10571 $       TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT };
10572 $       TrackMouseEvent (&track);
10573         }
10574 
10575 $   _txMousePos.x   = LOWORD (coords);
10576 $   _txMousePos.y   = HIWORD (coords);
10577 $   _txMouseButtons = (unsigned) buttons;  //-V202
10578 
10579 $   return true;
10580     }
10581 
10582 //-----------------------------------------------------------------------------------------------------------------
10583 
10584 bool _txCanvas_OnMOUSELEAVE (HWND)
10585     {
10586 $8  _txMousePos.x   = -1;
10587 $   _txMousePos.y   = -1;
10588 $   _txMouseButtons = 0;
10589 
10590 $   return true;
10591     }
10592 
10593 //-----------------------------------------------------------------------------------------------------------------
10594 
10595 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar)
10596     {
10597 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10598 
10599 $   const CREATESTRUCT* create = (CREATESTRUCT*) lpar;
10600 
10601 $   HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style,
10602                                create->x, create->y, create->cx, create->cy,
10603                                create->hwndParent, create->hMenu, NULL, create->lpCreateParams);
10604 
10605 $   *(HWND*) create->hInstance = wnd;
10606 
10607 $   return true;
10608     }
10609 
10610 //-----------------------------------------------------------------------------------------------------------------
10611 
10612 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar)
10613     {
10614 $8  if (_TX_ARGUMENT_FAILED (lpar)) return false;
10615 
10616 $   DestroyWindow ((HWND) lpar);
10617 
10618 $   return false;
10619     }
10620 
10621 //-----------------------------------------------------------------------------------------------------------------
10622 
10623 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd)
10624     {
10625 $8  if (_TX_ARGUMENT_FAILED (wnd)) return false;
10626 
10627 $   HWND console = Win32::GetConsoleWindow();
10628 $   if (!console) return false;
10629 
10630 $   bool visible = !!IsWindowVisible (console);
10631 
10632 $   ShowWindow (console, visible? SW_HIDE : SW_RESTORE);
10633 
10634 $   visible = !!IsWindowVisible (console);
10635 $   CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED);  //-V202
10636 
10637 $   return true;
10638     }
10639 
10640 //-----------------------------------------------------------------------------------------------------------------
10641 
10642 bool _txCanvas_OnCmdABOUT (HWND, WPARAM)
10643     {
10644 $8  //{ Overriding the missing names, if the set is incomplete
10645 
10646     #if defined (__MODULE)
10647         #define ABOUT_NAME_    __MODULE
10648     #else
10649         #define ABOUT_NAME_    "TXLib"
10650     #endif
10651 
10652     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10653 
10654         #ifndef __MODULE
10655         #define __MODULE       "TXLib"                           "\n"  "#define __MODULE to set the name.\n"
10656         #endif
10657 
10658         #ifndef __VERSION
10659         #define __VERSION      "(0.000000000)."                  "\n" "#define __VERSION to set the string value.\n"
10660         #endif
10661 
10662         #ifndef __DESCRIPTION
10663         #define __DESCRIPTION  "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n"
10664         #endif
10665 
10666         #ifndef __AUTHOR
10667         #define __AUTHOR       "(Непонятно кто)."                "\n" "#define __AUTHOR to override this name."
10668         #endif
10669 
10670     #endif
10671     //}
10672 
10673 $   static char text[_TX_BUFSIZE] = "";
10674 
10675 $   _tx_snprintf_s (text, sizeof (text) - 1,
10676 
10677                     "Application:\n\n"
10678 
10679                     #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
10680                         __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n"
10681                     #else
10682                         "Здесь могла бы быть Ваша реклама :)\n"
10683                         "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n"
10684                     #endif
10685 
10686                     "\n" "%s", _txAppInfo());
10687 
10688 $   txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION);
10689 
10690     // And a bit of HTTP-code in C++ function:
10691 
10692     goto http;
10693     http://sizeof.livejournal.com
10694 
10695 $   return true;
10696 
10697     #undef ABOUT_NAME_
10698     }
10699 
10700 #endif // TX_COMPILED
10701 
10703 //}
10704 //=================================================================================================================
10705 
10706 //=================================================================================================================
10707 //{          Console-support functions           (_txConsole...)
10709 //=================================================================================================================
10711 
10712 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10713 
10714 HWND _txConsole_Attach()
10715     {
10716 $1  HWND console = Win32::GetConsoleWindow();
10717 
10718 $   if (!console)
10719         {
10720 $       bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem());
10721 
10722 $       Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb();
10723 $       assert (teb);
10724 $       assert (teb->ProcessEnvironmentBlock);
10725 
10726 $       Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters;
10727 $       assert (params);
10728 
10729 $       if (minimizeConsole)  // The fact that ShowWindow parameter of the program's console is taken from calling
10730                               // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo()
10731                               // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :(
10732                               // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke!
10733             {
10734 $           params->dwFlags    |= STARTF_USESHOWWINDOW;
10735 $           params->wShowWindow = SW_MINIMIZE;
10736             }
10737 
10738 $       AllocConsole();
10739 $       console = Win32::GetConsoleWindow();
10740         }
10741 
10742 $   if (!console) return NULL;
10743 
10744 $   txSetLocale();                                // Устанавливаем русскую кодовую страницу для консоли Windows
10745 
10746 $   _txConsole_SetUnicodeFont();                  // Впечатлительным лучше сюда не смотреть.
10747 
10748 $   if (!_txIsConsoleSubsystem())
10749         {$ txReopenStdio(); }                     // Переоткрываем потоки ввода-вывода, если subsystem != console
10750 
10751 $   return console;
10752     }
10753 
10754 //-----------------------------------------------------------------------------------------------------------------
10755 
10756 int txSetLocale (int codepage /*= _TX_CODEPAGE*/,
10757                  const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/)
10758     {
10759 $1  int oldPage = GetConsoleOutputCP();
10760 
10761     // Устанавливаем нужную кодовую страницу для консоли Windows
10762 
10763 $   if (codepage)
10764         {
10765 $       SetConsoleCP       (codepage);
10766 $       SetConsoleOutputCP (codepage);
10767         }
10768 
10769     // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии
10770     // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным
10771     // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN -
10772     // обозначение кодовой страницы (например, для русского языка - CP1251).
10773 
10774 $   if (locale)
10775         {
10776 $       setlocale (LC_ALL,     locale);
10777 $       setlocale (LC_NUMERIC, "C");              // Return to decimal point (3.14) instead of comma (3,14) in floating numbers
10778         }
10779 
10780     #ifndef __CYGWIN__
10781 
10782 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10783 
10784 $   if (wLocale && !wine)
10785         {
10786 $       _wsetlocale (LC_ALL,     wLocale);
10787 $       _wsetlocale (LC_NUMERIC, L"C");           // L"C" (see above)
10788         }
10789 
10790     #endif
10791 
10792     (void) wLocale;
10793 
10794 $   return oldPage;
10795     }
10796 
10797 //-----------------------------------------------------------------------------------------------------------------
10798 
10799 void txReopenStdio()
10800     {
10801 $1  // Переоткрываем заново <s>Америку</s> потоки ввода-вывода
10802 
10803 $   fflush (stdout);
10804 $   fflush (stderr);
10805 
10806 $   FILE* f = NULL;
10807 
10808     #ifndef __CYGWIN__
10809 
10810 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE),  _O_TEXT), "r"); assert (f); *stdin  = *f;
10811 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f;
10812 $   f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE),  _O_TEXT), "w"); assert (f); *stderr = *f;
10813 
10814     #else
10815 
10816 $   f = _fdopen (STDIN_FILENO,  "r"); assert (f); *stdin  = *f;
10817 $   f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f;
10818 $   f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f;
10819 
10820     #endif
10821 
10822 $   setvbuf (stdin,  NULL, _IONBF, 0);
10823 $   setvbuf (stdout, NULL, _IONBF, 0);
10824 $   setvbuf (stderr, NULL, _IONBF, 0);
10825 
10826 $   ::std::ios::sync_with_stdio();
10827     }
10828 
10829 //-----------------------------------------------------------------------------------------------------------------
10830 
10831 inline bool _txConsole_OK()
10832     {
10833     return Win32::GetConsoleWindow() != NULL;
10834     }
10835 
10836 //-----------------------------------------------------------------------------------------------------------------
10837 
10838 bool _txConsole_Detach (bool activate)
10839     {
10840 $1  HWND console = Win32::GetConsoleWindow();
10841 $   if (!console) return false;
10842 
10843 $   EnableWindow (console, true);
10844 
10845 $   if (activate)
10846         {
10847 $       if (!IsWindowVisible (console))
10848             {$ ShowWindow (console, SW_MINIMIZE); }
10849 
10850 $       _txActivateWindow (console, 0xFF);
10851 $       return true;
10852         }
10853     else
10854         {
10855 $       return !!FreeConsole();
10856         }
10857     }
10858 
10859 //-----------------------------------------------------------------------------------------------------------------
10860 
10861 bool _txConsole_Draw (HDC dc)
10862     {
10863 $8  if (_TX_HDC_FAILED (dc)) return false;
10864 
10865 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10866 
10867 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
10868 $   BOOL ok = GetConsoleScreenBufferInfo (out, &con);
10869 $   if (!ok) return false;
10870 
10871 $   POINT size = { con.srWindow.Right  - con.srWindow.Left + 1,
10872                    con.srWindow.Bottom - con.srWindow.Top  + 1 };
10873 
10874 $   SIZE fontSz = { 12, 16 };
10875 $   Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted;
10876 
10877 $   COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
10878                           0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF };
10879 
10880 $   for (short y = 0; y < size.y; y++)
10881         {
10882         static char chr [_TX_BUFSIZE + 1] = "";  // [con.dwSize.X + 1]; maybe will be truncated
10883         static WORD atr [_TX_BUFSIZE + 1] = {};  // [con.dwSize.X + 1]; maybe will be truncated
10884         COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) };
10885         DWORD read  = 0;
10886 
10887         if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue;
10888         if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue;
10889 
10890         for (int x = 0, xEnd = size.x; x < size.x; x = xEnd)
10891             {
10892             Win32::SetTextColor (dc, pal [ atr[x]       & 0x0F]);
10893             Win32::SetBkColor   (dc, pal [(atr[x] >> 4) & 0x0F]);
10894             Win32::SetBkMode    (dc,      (atr[x]       & 0xF0)? OPAQUE : TRANSPARENT);
10895 
10896             for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;}
10897 
10898             Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)),
10899                                 ROUND (fontSz.cy *  y), chr + x, xEnd - x) asserted;
10900             }
10901         }
10902 
10903 $   Win32::SetTextColor (dc, pal [ con.wAttributes       & 0x0F]);
10904 $   Win32::SetBkColor   (dc, pal [(con.wAttributes >> 4) & 0x0F]);
10905 $   Win32::SetBkMode    (dc, TRANSPARENT);
10906 
10907 $   if (_txConsole_IsBlinking &&
10908         In (std::nomeow, con.dwCursorPosition, con.srWindow) &&
10909         GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval &&
10910         GetForegroundWindow() == txWindow())
10911         {
10912 $       Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)),
10913                             ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1,
10914                             "_", 1) asserted;
10915         }
10916 
10917 $   return true;
10918     }
10919 
10920 #endif // TX_COMPILED
10921 
10922 //-----------------------------------------------------------------------------------------------------------------
10923 //{          Welcome to the Duck Side! Together we will rule the Bathroom!
10924 //-----------------------------------------------------------------------------------------------------------------
10925 
10926 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
10927 
10928 bool _txConsole_SetUnicodeFont()
10929     {
10930 $   const bool wine = !!Win32::wine_get_version;  // Linux::Wine v1.2.2+ compatibility.
10931                                                   // Beer compatibility may be added in future versions...
10932 $   if (wine)                                     // Минздрав РФ предупреждает: чрезмерное употребление wine
10933         {                                         // вредит Вашему здоровью.
10934 $       Win32::GetNumberOfConsoleFonts = NULL;
10935 $       Win32::GetCurrentConsoleFont   = NULL;
10936 $       Win32::SetConsoleFont          = NULL;
10937 
10938 $       return false;
10939         }
10940 
10941     // Начиная с Висты все хорошо...
10942 
10943 $1  if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx)
10944         {
10945 $       HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10946 
10947 $       Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) };
10948 $       if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false;
10949 
10950 $       info.FontFamily = 0x36;                                                    // Unicode fixed-pitch
10951 $       if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2);  // Terminal font is too small
10952 
10953 $       if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0)    // Consolas is allowed too
10954             {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); }
10955 
10956 $       return !!Win32::SetCurrentConsoleFontEx (out, false, &info);
10957         }
10958 
10959     // ...а до этого все не так сладко
10960 
10961 $   const unsigned uniFont = 10;                  // The Internet and W2K sources know this magic number
10962 $   const unsigned uniSize = 20;                  // Size of the font desired, should be > max # of Raster Fonts  //-V2551
10963 $   bool ok = true;
10964 
10965     // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font.
10966 
10967 $   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
10968 
10969 $   unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ());
10970 $   if (fonts && fonts <= uniFont)
10971         {
10972 $       HRESULT init = Win32::CoInitialize (NULL);
10973 $       size_t sz = 0;
10974 
10975 $       char link [MAX_PATH] = "";
10976 $       getenv_s (&sz, link, sizeof (link) - 1, "TEMP");
10977 $       strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1);
10978 
10979 $       char comspec [MAX_PATH] = "";
10980 $       getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC");
10981 
10982 $       (void) _unlink (link);
10983 
10984 $       _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted;
10985 
10986 $       ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32);  // Sic!  //-V112 //-V566
10987         if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); }
10988 
10989 $       (void) _unlink (link);
10990 
10991 $       if (init == S_OK) Win32::CoUninitialize();
10992         }
10993 
10994     // If Unicode font is not already set, do set it.
10995 
10996 $   Win32::CONSOLE_FONT_INFO cur = {};
10997 $   _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur));
10998 
10999 $   ok &= (cur.nFont >= uniFont);
11000     if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); }
11001 
11002 $   HWND console = Win32::GetConsoleWindow();
11003 $   InvalidateRect (console, NULL, false);
11004 $   UpdateWindow   (console);
11005 
11006 $   return ok;
11007     }
11008 
11009 #endif // TX_COMPILED
11010 
11011 //-----------------------------------------------------------------------------------------------------------------
11012 //{          The assistants to the nightmare. You can use it freely to make your own nightmare sweet.
11013 
11014 #define      _TX_TRY                { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error;
11015 #define      _TX_CHECKED( cmd )     { if (FAILED (__tx_error = (cmd))) goto __tx_catch; }
11016 #define      _TX_FAIL               { __tx_error = E_FAIL; goto __tx_catch; }
11017 #define      _TX_RETRY              { __tx_error = S_OK;   goto __tx_try;   }
11018 #define      _TX_OK                 ( SUCCEEDED (__tx_error) )
11019 #define      _TX_CATCH              goto __tx_finally; __tx_catch:
11020 #define      _TX_RETURN             goto __tx_finally;
11021 #define      _TX_FINALLY            __tx_finally:
11022 #define      _TX_ENDTRY             }
11023 
11024 //}
11025 //-----------------------------------------------------------------------------------------------------------------
11026 
11027 // Мало не покажется
11028 
11029 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11030 
11031 bool _txCreateShortcut (const char shortcutName[],
11032                         const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/,
11033                         const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/,
11034                         int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/)
11035     {
11036 $1  if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false;
11037 $   if (_TX_ARGUMENT_FAILED (fileToLink   && *fileToLink))   return false;
11038 
11039     #if defined (__IShellLinkDataList_INTERFACE_DEFINED__)
11040 
11041 $   IShellLink* shellLink = NULL;
11042 $   IShellLinkDataList* dataList = NULL;
11043 $   IPersistFile* file = NULL;
11044 
11045 $   HRESULT init = Win32::CoInitialize (NULL);
11046 
11047     _TX_TRY
11048         {
11049 $       _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink));
11050 $       if (!shellLink) _TX_FAIL;
11051 
11052 $       shellLink->SetPath (fileToLink);
11053 $       shellLink->SetArguments (args);
11054 $       shellLink->SetWorkingDirectory (workDir);
11055 $       shellLink->SetDescription (description);
11056 $       shellLink->SetShowCmd (cmdShow);
11057 $       shellLink->SetIconLocation (iconFile, iconIndex);
11058 
11059 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList));
11060 $       if (!dataList) _TX_FAIL;
11061 
11062 $       Win32::NT_CONSOLE_PROPS props =
11063           {{sizeof (props), NT_CONSOLE_PROPS_SIG},
11064 
11065             FOREGROUND_LIGHTGRAY,                       // wFillAttribute
11066             FOREGROUND_MAGENTA | BACKGROUND_WHITE,      // wPopupFillAttribute
11067            {bufSize.X, bufSize.Y},                      // dwScreenBufferSize
11068            {wndSize.X, wndSize.Y},                      // dwWindowSize
11069            {wndOrg.X,  wndOrg.Y},                       // dwWindowOrigin
11070             0,                                          // nFont
11071             0,                                          // nInputBufferSize
11072            {0, (short) fontSize},                       // dwFontSize
11073             0x36, 400, L"Lucida Console",               // uFontFamily, uFontWeight, FaceName. We're dancing for this!
11074             15,                                         // uCursorSize
11075             0,  1, 1, 0,                                // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition
11076             50, 4, 0,                                   // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup
11077 
11078            {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,  // Palette
11079             0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF}
11080             };
11081 
11082 $       _TX_CHECKED (dataList->AddDataBlock (&props));
11083 
11084 $       _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file));
11085 $       if (!file) _TX_FAIL;
11086 
11087 $       wchar_t wName[MAX_PATH] = L"";
11088 $       MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName));
11089 
11090 $       _TX_CHECKED (file->Save (wName, true));
11091         }
11092 
11093 $   _TX_CATCH
11094 $   _TX_FINALLY
11095 
11096     if (file)         {$ file     ->Release(); }
11097     if (dataList)     {$ dataList ->Release(); }
11098     if (shellLink)    {$ shellLink->Release(); }
11099 
11100     if (init == S_OK) {$ Win32::CoUninitialize(); }
11101 
11102 $   return _TX_OK;
11103     _TX_ENDTRY
11104 
11105     #else
11106 
11107     (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex;
11108     (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg;
11109 
11110 $   return false;
11111 
11112     #endif
11113     }
11114 
11115 #endif // TX_COMPILED
11116 
11117 //}
11118 //-----------------------------------------------------------------------------------------------------------------
11119 
11121 //}
11122 //=================================================================================================================
11123 
11124 //=================================================================================================================
11125 //{          Memory DC functions                 (_txBuffer...)
11127 //=================================================================================================================
11129 
11130 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11131 
11132 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
11133     {
11134 $1  txAutoLock _lock;
11135 
11136 $   HDC wndDC = GetDC (wnd);
11137 $   if (!wndDC) return NULL;
11138 
11139 $   POINT sz = { 1, 1 };
11140 $   if (size) sz = *size;
11141 
11142 $   if (!size && wnd)
11143         {
11144 $       RECT r = {};
11145 $       GetClientRect (wnd, &r) asserted;
11146 
11147 $       sz.x = r.right  - r.left;
11148 $       sz.y = r.bottom - r.top;
11149         }
11150 
11151 $   if (bitmap)
11152         {
11153 $       BITMAP bmap = {};
11154 $       Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted;
11155 
11156 $       sz.x = bmap.bmWidth;
11157 $       sz.y = bmap.bmHeight;
11158         }
11159 
11160 $   RGBQUAD* buf = NULL;
11161 $   if (!pixels) pixels = &buf;
11162 
11163 $   HDC dc = Win32::CreateCompatibleDC (wndDC);
11164 $   if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed");
11165 
11166     #ifndef _TX_DIB_FIX
11167     #define _TX_DIB_FIX
11168     #endif
11169 
11170 $   BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }};
11171 
11172 $   HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0);
11173 $   if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed");
11174 
11175 $   Win32::SelectObject (dc, bmap) asserted;
11176 
11177 $   if (!bitmap)
11178         {
11179 $       if (*pixels)
11180             {
11181 $           RGBQUAD black = { 0, 0, 0, 255 };
11182 $           for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black;  //-V108
11183             }
11184         else
11185             {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; }
11186         }
11187 
11188 $   ReleaseDC (wnd, wndDC) asserted;
11189 
11190 $   return dc;
11191     }
11192 
11193 //-----------------------------------------------------------------------------------------------------------------
11194 
11195 bool _txBuffer_Delete (HDC* dc)
11196     {
11197 $1  if (_TX_ARGUMENT_FAILED (dc)) return false;
11198 $   if (                   !*dc)  return false;
11199 $   if (_TX_HDC_FAILED     (*dc)) return false;
11200 
11201 $   if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false;
11202 
11203 $   txAutoLock _lock;
11204 
11205 $   _txBuffer_Select (Win32::GetStockObject (NULL_PEN),    *dc) asserted;
11206 $   _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH),  *dc) asserted;
11207 $   _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted;
11208 $   _txBuffer_Select (_txStockBitmap,                      *dc);
11209 
11210 $   Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted;
11211 
11212 $   Win32::DeleteDC (*dc) asserted;
11213 
11214 $   *dc = NULL;
11215 
11216 $   return true;
11217     }
11218 
11219 //-----------------------------------------------------------------------------------------------------------------
11220 
11221 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/)
11222     {
11223 $1  if (!obj)                return false;
11224 $   if (_TX_HDC_FAILED (dc)) return false;
11225 
11226 $   if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type");
11227 
11228 $   txAutoLock _lock;
11229 
11230 $   obj = Win32::SelectObject (dc, obj);
11231 $   if (obj) Win32::DeleteObject (obj);
11232 
11233 $   return obj != NULL;
11234     }
11235 
11236 #endif // TX_COMPILED
11237 
11239 //}
11240 //=================================================================================================================
11241 
11242 //=================================================================================================================
11243 //{          Diagnostics
11245 //=================================================================================================================
11247 
11248 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11249 
11250 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/,
11251                       const char* msg  /*= NULL*/, ...)
11252     {                                                                        //---/\---/\-------Это ASCII KOT!--//
11253 $1  va_list arg; va_start (arg, msg);                                        //  {  '-'  }                      //
11254 $$  const char* what = _txProcessError (file, line, func, color, msg, arg);  //  {  0 0  }     Добавь его себе  //
11255     va_end (arg);                                                            //  --> V <--  в исходник, и тебе  //
11256                                                                              //   \ \|/ /      будет, наверно,  //
11257     if (!(msg && msg[0] == '\a')) return what;                               //    \___/  приятно отлаживаться  //
11258                                                                              //---------------долгими ночами:)--//
11259 //  vvvvvvvvvvvvvvvvvv
11260     DebugBreak();   // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться.
11261 //  ^^^^^^^^^^^^^^^^^^
11262 
11263     return what;    // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7).
11264     }
11265 
11266 #endif // TX_COMPILED
11267 
11268 //-----------------------------------------------------------------------------------------------------------------
11269 //{          General runtime check hooks
11270 //-----------------------------------------------------------------------------------------------------------------
11271 
11272 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11273 
11274 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/)
11275     {
11276 $1  if (!sig && !fpe)
11277         {
11278 $       signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11279 $       signal (SIGFPE,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11280 $       signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11281 $       signal (SIGILL,  (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11282 $       signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted;
11283 $       return;
11284         }
11285 
11286     txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe);
11287 
11288 $   if (!*_txLogName || _txLogName[0] == '~')
11289         {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); }
11290 
11291     #define GET_DESCR_(str, code, descr)  case (code): {$ (str) = " " #code ": " descr; break; }
11292 
11293 $   const char* sSig = "Неизвестный тип сигнала";
11294 
11295 $   switch (sig)
11296         {
11297         GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!")
11298         GET_DESCR_ (sSig, SIGILL,  "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.")
11299         GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().")
11300         GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.")
11301         GET_DESCR_ (sSig, SIGFPE,  "Грубая ошибка в вычислениях.")
11302         default:   break;  //-V2522
11303         }
11304 
11305 $   const char* sFPE = "";
11306 
11307     #if defined (_MSC_VER)
11308 
11309     // MSVC provides the FPE code as a MS extension.
11310     // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx
11311 
11312 $   if (sig == SIGFPE) switch (fpe)
11313         {
11314         GET_DESCR_ (sFPE, _FPE_INVALID,        "Результат неверен.")
11315         GET_DESCR_ (sFPE, _FPE_DENORMAL,       "Денормализация.")
11316         GET_DESCR_ (sFPE, _FPE_ZERODIVIDE,     "Деление на ноль.")
11317         GET_DESCR_ (sFPE, _FPE_OVERFLOW,       "Результат слишком большой.")
11318         GET_DESCR_ (sFPE, _FPE_UNDERFLOW,      "Результат слишком маленький.")
11319         GET_DESCR_ (sFPE, _FPE_INEXACT,        "Результат неточен.")
11320         GET_DESCR_ (sFPE, _FPE_UNEMULATED,     "Операция не поддерживается.")
11321         GET_DESCR_ (sFPE, _FPE_SQRTNEG,        "Квадратный корень из отрицательного числа.")
11322         GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW,  "Переполнение стека сопроцессора.")
11323         GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.")
11324         GET_DESCR_ (sFPE, _FPE_EXPLICITGEN,    "Явный вызов исключения.")
11325         default:   break;  //-V2522
11326         }
11327 
11328     #else
11329 $   fpe = 0;
11330     #endif
11331 
11332     #undef GET_DESCR_
11333 
11334 $   signal (sig, (void(*)(int))(uintptr_t)_txOnSignal);
11335 
11336 $   Win32::_fpreset();
11337 
11338 $   _TX_UNEXPECTED ("\a\t"
11339                     "signal (%d, 0x%02X):%s%s "
11340                     "%s%s"
11341                     "С помощью функции signal() вы можете сами обработать эту ошибку.",
11342                     sig, (unsigned) fpe, sSig, sFPE,
11343                     ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1);
11344     }
11345 
11346 //-----------------------------------------------------------------------------------------------------------------
11347 
11348 void _txOnTerminate()
11349     {
11350     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11351 
11352     // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc
11353 
11354 $1  static int terminating = 0;
11355     if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; }
11356 
11357 $   if (!*_txDumpSE)
11358         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11359 
11360 $   _TX_UNEXPECTED ("\t\a"
11361                     "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, "
11362                     "или другая фатальная ошибка C++. "
11363                     "%s"
11364                     "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, "
11365                     "разбирайтесь, в чем дело.\n\n"
11366                     "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE,
11367                     _txDumpSE + 1);
11368     }
11369 
11370 //-----------------------------------------------------------------------------------------------------------------
11371 
11372 void _txOnUnexpected()
11373     {
11374     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11375 
11376 $1  if (!*_txDumpSE)
11377         {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); }
11378 
11379 $   _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n"
11380                     "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете "
11381                     "спецификацию исключений для функций, проверьте, не нарушена ли она."
11382                     "%s"
11383                     "С помощью catch (...) в main() вы можете сами обработать эту ошибку.",
11384                     _txDumpSE + 1);
11385     }
11386 
11387 //-----------------------------------------------------------------------------------------------------------------
11388 
11389 int _txOnMatherr (_exception* exc)
11390     {
11391     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc);
11392 
11393 $1  assert (exc);
11394 
11395     const char* sType = "Неизвестный тип исключения";
11396 
11397     #if !defined (__CYGWIN__)
11398 
11399     #define GET_DESCR_(code, descr)  case (code): {$ sType = "(" #code "): " descr; break; }
11400 
11401 $   switch (exc->type)
11402         {
11403         GET_DESCR_ (_DOMAIN,    "Нарушение области определения");
11404         GET_DESCR_ (_SING,      "Сингулярность аргумента");
11405         GET_DESCR_ (_PLOSS,     "Частичная потеря значимости");
11406         GET_DESCR_ (_TLOSS,     "Полная потеря значимости");
11407         GET_DESCR_ (_OVERFLOW,  "Результат слишком большой");
11408         GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький");
11409         default:   break;  //-V2522
11410         }
11411 
11412     #undef GET_DESCR_
11413 
11414 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n"
11415                     "С помощью __setusermatherr() вы можете сами обработать эту ошибку.",
11416                     exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval);
11417     #else
11418 
11419 $   _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType);
11420 
11421     #endif
11422 
11423     return 0;
11424     }
11425 
11426 //-----------------------------------------------------------------------------------------------------------------
11427 
11428 tx_noreturn void _txOnNewHandlerAnsi()
11429     {
11430     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11431 $1
11432 $   _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n"
11433                     "С помощью std::set_new_handler() вы можете сами обработать эту ошибку "
11434                     "и где-нибудь найти недостающую память.");
11435 
11436 $   throw std::bad_alloc();
11437     }
11438 
11439 //-----------------------------------------------------------------------------------------------------------------
11440 
11441 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code)
11442     {
11443     txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code);
11444 
11445 $1  if (code)
11446         {$ errno = code; }
11447 
11448 $   _TX_UNEXPECTED ("\a"
11449                     "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n"
11450                     "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку "
11451                     "и постараться не выходить за границы массивов.",
11452                     code, msg, (char*) ptr, ptr);
11453     }
11454 
11455 //-----------------------------------------------------------------------------------------------------------------
11456 
11457 int tx_glGetError (int setError /*= INT_MIN*/)
11458     {
11459 $1  _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError;
11460 $   return _txOGLError;
11461     }
11462 
11463 #endif // TX_COMPILED
11464 
11465 //}
11466 //-----------------------------------------------------------------------------------------------------------------
11467 
11468 //-----------------------------------------------------------------------------------------------------------------
11469 //{          MSC Runtime check hooks
11470 //-----------------------------------------------------------------------------------------------------------------
11471 
11472 #if defined (_MSC_VER)
11473 
11474 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11475 
11476 //-----------------------------------------------------------------------------------------------------------------
11477 
11478 int _txOnNewHandler (size_t size)
11479     {
11480     txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size);
11481 $5
11482 $   _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n"
11483                     "С помощью _set_new_handler() вы можете сами обработать эту ошибку "
11484                     "и где-нибудь найти недостающую память.", (unsigned long long) size);
11485 
11486 $   throw std::bad_alloc();
11487     }
11488 
11489 //-----------------------------------------------------------------------------------------------------------------
11490 
11491 void _txOnSecurityError (int code, void* addr)
11492     {
11493     txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr);
11494 $5
11495 $   _TX_UNEXPECTED ("\a"
11496                     "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n"
11497                     "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку "
11498                     "и более торжественно завершить программу. Ставьте же ассерты.", code);
11499 $   abort();
11500     }
11501 
11502 //-----------------------------------------------------------------------------------------------------------------
11503 
11504 void _txOnPureCall()
11505     {
11506     txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__);
11507 $5
11508 $   _TX_UNEXPECTED ("\a"
11509                     "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах "
11510                     "или деструкторах базовых классов - не вызывайте там таких функций.\n\n"
11511                     "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку "
11512                     "и проверить свое знание С++ :)");
11513 $   abort();
11514     }
11515 
11516 //-----------------------------------------------------------------------------------------------------------------
11517 
11518 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr)
11519     {
11520     txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr);
11521 
11522 $5  assert (wExpr);
11523     assert (wFunc);
11524     assert (wFile);
11525 
11526     char expr [_TX_BUFSIZE/2] = "[Unknowm expr]",
11527          func [_TX_BUFSIZE/2] = "[Unknowm func]",
11528          file [MAX_PATH]      = "[Unknowm file]";
11529 
11530 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL);
11531 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL);
11532 $   WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL);
11533 
11534 $$  _txError (file, (int) line, func, 0, "\a"
11535               "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n"
11536               "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr);
11537 $   abort();
11538     }
11539 
11540 //-----------------------------------------------------------------------------------------------------------------
11541 
11542 #if defined (_CLANG_VER) && !defined (_MSC_VER)
11543 
11544 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info)
11545     {
11546 $5  assert (&info);
11547 
11548 $$  _txError (info.__file_, info.__line_, NULL, 0, "\a"
11549               "Оказалось неверно, что %s (%s). Не надо так.\n\n"
11550               "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_);
11551 $   abort();
11552     }
11553 
11554 #endif
11555 
11556 //-----------------------------------------------------------------------------------------------------------------
11557 
11558 #pragma runtime_checks ("", off)
11559 
11560 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...)
11561     {
11562     txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format);
11563 
11564 $5  static long running = 0;
11565 $   while (InterlockedExchange (&running, 1)) Sleep (0);
11566 
11567 $   assert (format);
11568 
11569     // Disable all RTC failures
11570 
11571 $   int nErrors = _RTC_NumErrors();
11572 $   int* errors = NULL;
11573 $   try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;}  //-V104
11574 
11575 $   int err = 0;
11576 $   for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE);  //-V108
11577 
11578 $   char text [_TX_BUFSIZE] = "";
11579 
11580 $   va_list arg; va_start (arg, format);
11581 $   _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg);                  // Get message from the vararg list
11582 $   auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/);  // Get the RTC error number
11583 $   va_end (arg);
11584 
11585 $   const char* sType = "type";
11586 
11587 $   switch (type)
11588        {
11589        case _CRT_ERROR:  $ sType = "ошибка";            break;
11590        case _CRT_ASSERT: $ sType = "логическая ошибка"; break;
11591        case _CRT_WARN:   $ sType = "возможная ошибка";  break;
11592        default:          $                              break;
11593        }
11594 
11595 $   const char* sError = _RTC_GetErrDesc (error);
11596 
11597 $$  _txError (file, line, NULL, 0, "\a"
11598               "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module);
11599 
11600     // The code below will be never executed until the error above will stay fatal:
11601 
11602     // Restore the RTC error types
11603 
11604     #if defined (_MSC_VER)
11605     #pragma warning (push)
11606     #pragma warning (disable: 6385)  // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11607     #endif
11608 
11609 $   for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR));  //-V108
11610 
11611     #if defined (_MSC_VER)
11612     #pragma warning (pop)            // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read.
11613     #endif
11614 
11615 $   InterlockedExchange (&running, 0);
11616 $   return 1;
11617     }
11618 
11619 //-----------------------------------------------------------------------------------------------------------------
11620 
11621 #if (_CLANG_VER >= 2000)
11622 
11623 void ::std::__libcpp_verbose_abort (char const* format, ...)
11624     {
11625 $5  assert (&format);
11626 
11627 $   char msg [_TX_BUFSIZE] = "";
11628 
11629 $   va_list args;
11630 $   va_start (args, format);
11631 $   _snprintf_s (msg, sizeof (msg), format, args);
11632 $   va_end (args);
11633 
11634 $   _TX_UNEXPECTED ("\a\t"
11635                     "Оказалось неверно, что: %s. Не надо так.\n\n"
11636                     "%s%s"
11637                     "С помощью функции signal() вы можете сами обработать эту ошибку.",
11638                     msg,
11639                     ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1);
11640 $   abort();
11641     }
11642 
11643 #endif
11644 
11645 #pragma runtime_checks ("", restore)
11646 
11647 //-----------------------------------------------------------------------------------------------------------------
11648 
11649 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line)
11650     {
11651     #if (_TX_ALLOW_TRACE +0 >= 4)
11652 
11653     static _tx_thread int recursive = 0;
11654     if (recursive) return true;
11655     recursive++;
11656 
11657     #if (_TX_ALLOW_TRACE +0 <= 10)
11658     if (!size) return true;
11659     #endif
11660 
11661     #define GET_DESCR_(str, type)  case (type): { str = #type; break; }
11662 
11663     const char* sType = "Unknown type";
11664     const char* sUse  = "Unknown use";
11665 
11666     switch (_BLOCK_TYPE (type))
11667         {
11668         GET_DESCR_ (sType, _HOOK_ALLOC);
11669         GET_DESCR_ (sType, _HOOK_REALLOC);
11670         GET_DESCR_ (sType, _HOOK_FREE);
11671         default:   break;
11672         }
11673 
11674     switch (use)
11675         {
11676         GET_DESCR_ (sUse,  _NORMAL_BLOCK);
11677         GET_DESCR_ (sUse,  _CRT_BLOCK);
11678         GET_DESCR_ (sUse,  _CLIENT_BLOCK);
11679         GET_DESCR_ (sUse,  _FREE_BLOCK);
11680         GET_DESCR_ (sUse,  _IGNORE_BLOCK);
11681         default:   break;
11682         }
11683 
11684     #undef  GET_DESCR_
11685 
11686     _txTrace ((const char*) file, line, NULL, "%*s"
11687               "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)",
11688               2 * _txLoc::Cur.inTX, "",
11689               type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request);
11690 
11691     recursive--;
11692 
11693     #else
11694 
11695     UNREFERENCED_PARAMETER (type);
11696     UNREFERENCED_PARAMETER (data);
11697     UNREFERENCED_PARAMETER (size);
11698     UNREFERENCED_PARAMETER (use);
11699     UNREFERENCED_PARAMETER (request);
11700     UNREFERENCED_PARAMETER (file);
11701     UNREFERENCED_PARAMETER (line);
11702 
11703     #endif
11704 
11705     return true;  //-V601
11706     }
11707 
11708 //-----------------------------------------------------------------------------------------------------------------
11709 
11710 #endif // TX_COMPILED
11711 
11712 #endif
11713 
11714 //}
11715 //-----------------------------------------------------------------------------------------------------------------
11716 
11717 //-----------------------------------------------------------------------------------------------------------------
11718 //{          SEH staff
11719 //-----------------------------------------------------------------------------------------------------------------
11720 
11721 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
11722 
11723 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc)
11724     {
11725     if (!_txProcessSystemWarnings)
11726         {
11727         DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11728         void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11729 
11730         if (code != DBG_PRINTEXCEPTION_C &&
11731             code != DBG_PRINTEXCEPTION_WIDE_C)
11732             {
11733             txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n",
11734                                  _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings);
11735             }
11736 
11737         return EXCEPTION_CONTINUE_SEARCH;
11738         }
11739     else
11740         {
11741         int inTX = _txLoc::Cur.inTX++;
11742 
11743         long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler");
11744 
11745         _txLoc::Cur.inTX = inTX;
11746         return ret;
11747         }
11748     }
11749 
11750 //-----------------------------------------------------------------------------------------------------------------
11751 
11752 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc)
11753     {
11754     int inTX = _txLoc::Cur.inTX++;
11755 
11756     long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter");
11757 
11758     if (_txPrevUEFilter)
11759         {
11760         if (_txSetJmp())
11761             {
11762             int inTX2 = _txLoc::Cur.inTX++;
11763 
11764             ret = _txPrevUEFilter (exc);
11765 
11766             _txLoc::Cur.inTX = inTX2;
11767             }
11768         else
11769             {
11770 $6          _TX_UNEXPECTED ("\t\a" "%s"
11771                             "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n"
11772                             "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE,
11773                             _txDumpSE + 1);
11774             }
11775         }
11776 
11777     _txLoc::Cur.inTX = inTX;
11778     return ret;
11779     }
11780 
11781 //-----------------------------------------------------------------------------------------------------------------
11782 
11783 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter)
11784     {
11785 $6  _txPrevUEFilter = filter;
11786 
11787     return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter;
11788     }
11789 
11790 //-----------------------------------------------------------------------------------------------------------------
11791 
11792 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[])
11793     {
11794     assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; }  //-V547
11795 
11796     assert (exc->ExceptionRecord);
11797 
11798     assert (func);
11799     assert (func[3] == 'V' || func[3] == 'U');
11800 
11801     bool  unhExc = (func[3] == 'U');
11802     DWORD code   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode    : 0;     //-V560
11803     void* addr   = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL;  //-V560
11804 
11805     if (code == DBG_PRINTEXCEPTION_C                  ||
11806         code == DBG_PRINTEXCEPTION_WIDE_C             ||
11807         code == DBG_THREAD_NAME                       ||
11808         code == STATUS_LONGJUMP                       ||
11809        (code == RPC_S_SERVER_UNAVAILABLE  && !unhExc) ||
11810        (code == RPC_S_CALL_CANCELLED      && !unhExc) ||
11811        (code == EXCEPTION_BREAKPOINT && IsDebuggerPresent()))
11812         return EXCEPTION_CONTINUE_SEARCH;
11813 
11814     ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr;
11815     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11816 
11817               dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr;
11818     if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; }
11819 
11820     _txSENumber = _txSENumber + 1;
11821     if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1;
11822 
11823     OutputDebugString ("");
11824     txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n",
11825                          _TX_VERSION, _txSENumber, func, (unsigned long) code, addr);
11826 
11827 $6  if (*(unsigned long long*) _txDumpExceptionObjJmp)
11828         {
11829 $       txOutputDebugPrintf ("%s - WARNING: #%ld: longjmp to %s() at %s:%d\n", _TX_VERSION, _txSENumber,
11830                              _txDumpExceptionObjLoc.func, _txDumpExceptionObjLoc.file, _txDumpExceptionObjLoc.line);
11831 
11832         longjmp (_txDumpExceptionObjJmp, 1);  //-V2512
11833         }
11834 
11835     tx_fpreset();
11836 
11837     #if defined (_MSC_VER)
11838     if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); }
11839     #endif
11840 
11841 $   bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord));  //-V560
11842 
11843 $   if (primaryException && exc)  //-V560
11844         {
11845 $       unsigned err = GetLastError();
11846 
11847 $       const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc);
11848 
11849 $       _txDumpExceptionSEH (_txDumpSE,  (intptr_t) sizeof (_txDumpSE)  - 1, exc->ExceptionRecord, func);
11850 $       _tx_snprintf_s      (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace);
11851 
11852 $       static _tx_thread DWORD prevCode = 0;
11853 $       static _tx_thread void* prevAddr = NULL;
11854 
11855 $       if (code != prevCode && addr != prevAddr &&
11856             !strstr (_txDumpSE, "Объект исключения C++:"))
11857             {
11858 $           SetLastError (err);
11859 $           _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1);
11860 
11861 $           prevCode = code;
11862 $           prevAddr = addr;
11863             }
11864 
11865 $       SetLastError (err);
11866         }
11867 
11868 $   if (_txDumpSE[0]     == '\a'                         ||
11869         _txSENumber      >= _TX_EXCEPTIONS_LIMIT+0       ||
11870         _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0 ||
11871         exc->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
11872         {
11873 $       _TX_UNEXPECTED ("\a\t" "%s"
11874                         "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.",
11875                         _txDumpSE + 1);
11876 
11877 $       return EXCEPTION_EXECUTE_HANDLER;
11878         }
11879 
11880 $   return EXCEPTION_CONTINUE_SEARCH;
11881     }
11882 
11883 //-----------------------------------------------------------------------------------------------------------------
11884 
11885 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[])  //-V2008
11886     {
11887 $6  assert (what);
11888 $   assert (size >= 0);                     //-V547
11889     assert (exc); if (!exc) {$ return 0; }  //-V547
11890 $   assert (func);
11891 
11892 $   unsigned         code   = exc->ExceptionCode;
11893 $   void*            addr   = exc->ExceptionAddress;
11894 $   unsigned         params = exc->NumberParameters;
11895 $   const ULONG_PTR* info   = exc->ExceptionInformation;
11896 $   void*            object = (params >= 2)? (void*) info[1] : NULL;
11897 
11898 $   char* s = what;
11899 
11900     #define PRINT_(...)  s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__)
11901 
11902 $   const char* sCode  = NULL;
11903 $   const char* sDescr = NULL;
11904 
11905     #define GET_DESCR_(code, descr)  case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; }
11906 
11907 $   switch (code)
11908         {
11909         GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION,         " "  "Нарушение доступа к памяти.")
11910         GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION,      " "  "Недопустимая операция.")
11911         GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION,         " "  "Привилегированная операция.")
11912         GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED,    "\a" "Выход за границы массива. Ставьте ассерты!")
11913         GET_DESCR_ (EXCEPTION_BREAKPOINT,               "\a" "Достигнута точка останова. Удачи в отладке!")
11914         GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT,    "\a" "Нарушение выравнивания данных.")
11915         GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION,      "\a" "Обработчик исключения возвратил неверное значение.")
11916         GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR,            "\a" "Невозможно загрузить нужную страницу памяти.")
11917         GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.")
11918         GET_DESCR_ (EXCEPTION_SINGLE_STEP,              "\a" "Выполнена инструкция машинного кода. Одна штука.")
11919         GET_DESCR_ (EXCEPTION_STACK_OVERFLOW,           "\a" "Ю-ху! Переполнение стека!")
11920         GET_DESCR_ (EXCEPTION_GUARD_PAGE,               "\a" "Попытка доступа к защищенной странице памяти.")
11921         GET_DESCR_ (EXCEPTION_INVALID_HANDLE,           "\a" "Неверный или уже закрытый дескриптор.")
11922         GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK,           "\a" "Возможно, взаимная блокировка ресурсов.")
11923         GET_DESCR_ (STATUS_LONGJUMP,                    " "  "Произошел longjmp().")
11924 
11925         GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK,          "\a" "Ошибка стека при операции с плавающей точкой.")
11926         GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND,     " "  "Денормализация числа с плавающей точкой.")
11927         GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO,       " "  "Деление на ноль при операции с плавающей точкой.")
11928         GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT,       " "  "Неточный результат при операции с плавающей точкой.")
11929         GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION,    " "  "Недопустимая операция с плавающей точкой.")
11930         GET_DESCR_ (EXCEPTION_FLT_OVERFLOW,             " "  "Переполнение при операции с плавающей точкой.")
11931         GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW,            " "  "Потеря значимости при операции с плавающей точкой.")
11932         GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS,       " "  "Множественные ошибки с плавающей точкой.")
11933 
11934         GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO,       "\a" "Целочисленное деление на ноль.")
11935         GET_DESCR_ (EXCEPTION_INT_OVERFLOW,             "\a" "Переполнение при целочисленной операции.")
11936 
11937         GET_DESCR_ (EXCEPTION_CLR_FAILURE,              "\a" "Сбой среды исполнения (CLR).")
11938         GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN,        "\a" "Переполнение стекового буфера!")
11939         GET_DESCR_ (STATUS_ASSERTION_FAILURE,           "\a" "Сработал assert. На этот раз из ядра.")
11940         GET_DESCR_ (STATUS_WX86_BREAKPOINT,             "\a" "Точка останова подсистемы эмуляции x86.")
11941         GET_DESCR_ (RPC_S_UNKNOWN_IF,                   "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).")
11942         GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE,           "\a" "Сервер удаленного вызова процедур (RPC) недоступен.")
11943         GET_DESCR_ (DBG_TERMINATE_THREAD,               "\a" "Отладчик завершил поток сознания.")
11944         GET_DESCR_ (DBG_TERMINATE_PROCESS,              "\a" "Отладчик завершил процесс.")
11945         GET_DESCR_ (DBG_CONTROL_C,                      "\a" "Отладчик получил сигнал прерывания Control+C.")
11946         GET_DESCR_ (DBG_CONTROL_BREAK,                  "\a" "Отладчик получил сигнал прерывания Control+Break.")
11947         GET_DESCR_ (DBG_THREAD_NAME,                    " "  "Отладчик получил указание дать потоку имя.")
11948         GET_DESCR_ (DBG_PRINTEXCEPTION_C,               " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).")
11949         GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C,          " "  "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).")
11950 
11951         GET_DESCR_ (EXCEPTION_CPP_MSC,                  " "  "Исключение С++, вызванное оператором throw.")
11952         GET_DESCR_ (EXCEPTION_CPP_GCC,                  " "  "Исключение С++, вызванное оператором throw.")
11953         GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND,           " "  "Исключение С++, вызванное во время раскрутки стека (rethrow?).")
11954         GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED,           " "  "Исключение С++, вызванное нарушением магии.")
11955         GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER,      "\a" "Это скомпилилось под Билдер? O_O")
11956         GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI,       "\a" "Это же С++. Как это вышло?")
11957 
11958         default: $ break;
11959         }
11960 
11961     #undef GET_DESCR_
11962 
11963 $   if (sDescr)
11964         {
11965 $       PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode);
11966         }
11967     else
11968         {
11969 $       PRINT_ ("\a#%ld: ", _txSENumber);
11970 $       s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
11971                             GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
11972                             s, (DWORD) (size - (s-what)), NULL) - 2;  //-V202
11973 $       PRINT_ ("\r\r");
11974         }
11975 
11976 $   PRINT_ (" (0x%X) при выполнении кода по адресу", code);
11977 $   PRINT_ ((addr? " 0x%p" : " NULL"), addr);
11978 
11979 $   Win32::SYMBOL_INFO*     sym  = NULL;
11980 $   Win32::IMAGEHLP_LINE64* line = NULL;
11981 
11982     if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); }
11983 
11984 $   if (sym  &&                   *sym->Name)      PRINT_ (" в функции %s()", sym->Name);
11985 $   if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber);
11986 
11987 $   if (code == EXCEPTION_ACCESS_VIOLATION ||
11988         code == EXCEPTION_IN_PAGE_ERROR)
11989         {
11990 $       PRINT_ (". Попытка ");
11991 
11992 $       unsigned long op = 0xBADC0DE;
11993 $       const char*  sOp = "(действие не указано)";
11994 
11995 $       if (params >= 1)
11996             {
11997 $           switch (op = (unsigned long) info[0])  //-V202
11998                 {
11999                 case 0:  $ sOp = "прочесть данные";          break;
12000                 case 1:  $ sOp = "записать данные";          break;
12001                 case 8:  $ sOp = "исполнить код";            break;
12002                 default: $ sOp = "совершить операцию 0x%lX"; break;
12003                 }
12004             }
12005 
12006 $       PRINT_ (sOp, op);
12007 
12008 $       if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); }   //-V1048
12009         else             {$ PRINT_ (" (адрес не указан)"); }
12010 
12011 $       if (code == EXCEPTION_IN_PAGE_ERROR)
12012             {
12013 $           PRINT_ (", ошибка ввода-вывода:");
12014 
12015 $           if (params >= 3)
12016                 {
12017 $               unsigned long ntstatus = (unsigned long) info[2];                                 //-V202
12018 
12019 $               PRINT_ (" 0x%lX (", ntstatus);
12020 
12021 $               s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
12022                                     GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
12023                                     s, (DWORD) (size - (s-what)), NULL) - 2;                      //-V202
12024 $               PRINT_ (")");
12025                 }
12026             else
12027                 {$ PRINT_ (" (не указана)"); }
12028             }
12029         }
12030 
12031 $   HMODULE module = NULL;
12032 $   _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module));
12033 
12034 $   if (module)
12035         {
12036 $       static char sModule [MAX_PATH] = "";
12037 $       int ok = GetModuleFileName (module, sModule, sizeof (sModule));
12038 
12039 $       char* ext = (ok? strrchr (sModule, '.') : NULL);
12040 $       if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule));
12041 
12042         if (ok) {$ PRINT_ (" в модуле %s",  sModule); }
12043         else    {$ PRINT_ (" в модуле 0x%p", (void*) module); }
12044         }
12045 
12046 $   PRINT_ (".");
12047 
12048 $   if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0)
12049         {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).",        _TX_EXCEPTIONS_LIMIT+0); }
12050 
12051 $   if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0)
12052         {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); }
12053 
12054 $   PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func);
12055 
12056 $   if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
12057         {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); }
12058 
12059 $   if (exc->ExceptionRecord)
12060         {
12061 $       PRINT_ ("\n\n" "Причина:" "\n\n");
12062 $       s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func);
12063         }
12064 
12065 $   if (code == EXCEPTION_CPP_GCC        ||
12066         code == EXCEPTION_CPP_GCC_UNWIND ||
12067         code == EXCEPTION_CPP_GCC_FORCED ||
12068         code == EXCEPTION_CPP_MSC)
12069         {
12070 $       s += _txDumpExceptionCPP (s,    size - (s-what), code, params, info);
12071         }
12072 
12073     #undef PRINT_
12074 
12075 $   while (s > what && s[-1] == '\n') s--;
12076 $   if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n");
12077 
12078 $   return s - what;
12079     }
12080 
12081 //-----------------------------------------------------------------------------------------------------------------
12082 
12083 intptr_t _txDumpExceptionCPP (char what[], intptr_t size,
12084                               unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/)
12085     {
12086 $6  assert (what);
12087 $   assert (size >= 0);  //-V547
12088 
12089 $   char* s = what;
12090 
12091 $   switch (code)
12092         {
12093         #if defined (_GCC_VER)
12094 
12095         case EXCEPTION_CPP_GCC:
12096         case EXCEPTION_CPP_GCC_UNWIND:
12097         case EXCEPTION_CPP_GCC_FORCED:
12098             {
12099             // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp
12100             //      [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below
12101             //      [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below
12102             //      [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below
12103             //      and figure above near ABI::__cxa_exception definition in this file
12104 
12105 $           const std::type_info* type   = NULL;
12106 $           void*                 object = NULL;
12107 
12108 $           if (params >= 1)
12109                 {
12110 $               _Unwind_Exception*    unwind_exception = (_Unwind_Exception*) info[0];
12111 $               ABI::__cxa_exception* cxa_exception    = (ABI::__cxa_exception*) (unwind_exception + 1) - 1;
12112 
12113 $               type   = cxa_exception->exceptionType;
12114 $               object = cxa_exception + 1;
12115                 }
12116 
12117 $           s += _txDumpExceptionObj (s, size - (s-what), object, 0, type);
12118             }
12119 $           break;
12120 
12121         case 0:  // Not called within SEH chain
12122             {
12123             // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc
12124             //       [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc
12125 
12126             using namespace abi;
12127             using namespace ABI;
12128 
12129 $           ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions;
12130 
12131 $           if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1))  // Dependent exception, case B, see pic above
12132                 {
12133 $               cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1;
12134                 }
12135 
12136 $           if (cxa_exception)
12137                 {
12138 $               verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type());
12139 
12140 $               s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType);
12141                 }
12142             }
12143 $           break;
12144 
12145         #elif defined (_MSC_VER)
12146 
12147         case EXCEPTION_CPP_MSC:
12148             {
12149             // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
12150             //     [2] http://www.openrce.org/articles/full_view/21
12151             //     [3] http://www.openrce.org/articles/full_view/23
12152             //     [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf
12153 
12154 $           const std::type_info* type   = NULL;
12155 $           void*                 object = (params >= 2)? (void*) info[1] : NULL;
12156 $           size_t                szObj  = 0;
12157 
12158 $           if (params >= 3 &&
12159                (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 ||
12160                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 ||
12161                 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 ||
12162                 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1))
12163                 {
12164 $               auto throwInfo = (const Win32::ThrowInfo*) info[2];
12165 
12166 $               if (throwInfo && throwInfo->pCatchableTypeArray)
12167                     {
12168 $                   HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL;  //-V112
12169 
12170                     #define RVA_(type, addr)  ( (type) ((uintptr_t) module + (uintptr_t) (addr)) )
12171 
12172 $                   const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray);
12173 $                   const Win32::CatchableType*      cType  = RVA_(const Win32::CatchableType*,      cArray->arrayOfCatchableTypes[0]);
12174 
12175 $                   type  = RVA_(const std::type_info*, cType->pType);
12176 $                   szObj = cType->sizeOrOffset;  //-V101
12177 
12178                     #undef  RVA_
12179                     }
12180                 }
12181 
12182 $           s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type);
12183             }
12184             break;
12185 
12186         case 0:  // Not called within SEH chain
12187 
12188             // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC:
12189             //
12190             // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception.
12191             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp
12192             //
12193             // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception.
12194             // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp
12195             // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp
12196             // and http://msdn.microsoft.com/en-us/library/ff730818.aspx.
12197             //
12198             // So _txDumpSE information should have been recorded during previous call. Now do nothing.
12199 
12200 $           break;
12201 
12202         #endif
12203 
12204         default:
12205 $           txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code);
12206 $           break;
12207         }
12208 
12209 $   while (s > what && s[-1] == '\n') s--;
12210 $   if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n");
12211 
12212 $   return (s - what);
12213     }
12214 
12215 //-----------------------------------------------------------------------------------------------------------------
12216 
12217 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type)  //-V2008
12218     {
12219 $6  assert (what);
12220 $   assert (size > 0);  //-V547
12221 
12222 $   static char*  s     = NULL; s     = what;
12223 $   static size_t szObj = 0;    szObj = sizeObj;
12224 
12225     #define PRINT_(...)  s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__)
12226 
12227 $   PRINT_ ("\n\n" "Объект исключения C++:");
12228 
12229 $   const char* mangledName = (type)? type->name() : NULL;
12230 
12231 $   char* typeName = NULL;
12232 $   int err = 1;
12233 
12234     #if defined (_GCC_VER)
12235 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err);
12236     #endif
12237 
12238 $   const char* name = (!err && typeName)? typeName : mangledName;  //-V560
12239 
12240 $   if (name &&
12241        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >")           == 0 ||
12242         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >")                   == 0))
12243         {$ name = "std::string"; }
12244 
12245 $   if (name &&
12246        (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *")         == 0 ||
12247         strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 ||
12248         strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*")                  == 0))
12249         {$ name = "std::string*"; }
12250 
12251     if (name) {$ PRINT_ (" %s", name); }
12252 
12253     #if defined (_GCC_VER)
12254 $   free (typeName);
12255     #endif
12256 
12257 $   err = 0;
12258 $   if (mangledName)
12259         {
12260         if (_txSetJmp())
12261             {
12262             #define PRINT_VAL_(fmt, ty, ...)                                                                         \
12263                 else if (*type == typeid (      ty       )) {$ PRINT_ (" = " #fmt, (* (ty* ) object) __VA_ARGS__); } \
12264                 else if (*type == typeid (const ty       )) {$ PRINT_ (" = " #fmt, (* (ty* ) object) __VA_ARGS__); } \
12265                 else if (*type == typeid (      ty*      )) {$ PRINT_ (" = " #fmt, (**(ty**) object) __VA_ARGS__); } \
12266                 else if (*type == typeid (const ty*      )) {$ PRINT_ (" = " #fmt, (**(ty**) object) __VA_ARGS__); } \
12267                 else if (*type == typeid (      ty* const)) {$ PRINT_ (" = " #fmt, (**(ty**) object) __VA_ARGS__); } \
12268                 else if (*type == typeid (const ty* const)) {$ PRINT_ (" = " #fmt, (**(ty**) object) __VA_ARGS__); }
12269             #define NO_
12270 
12271             if (false) ;
12272             PRINT_VAL_ ("%s", char*, NO_)   PRINT_VAL_ ('%c', unsigned char,  NO_)   PRINT_VAL_ (%s,   bool, ? "true" : "false")  //-V206 //-V517
12273             PRINT_VAL_ ( %d,  int,   NO_)   PRINT_VAL_ ( %u,  unsigned int,   NO_)   PRINT_VAL_ (%g,   float,  NO_)               //-V206
12274             PRINT_VAL_ ( %hd, short, NO_)   PRINT_VAL_ ( %hu, unsigned short, NO_)   PRINT_VAL_ (%g,   double, NO_)               //-V206
12275             PRINT_VAL_ ( %ld, long,  NO_)   PRINT_VAL_ ( %lu, unsigned long,  NO_)   PRINT_VAL_ ('%c', char,   NO_)               //-V206
12276             PRINT_VAL_ ("%s", std::string, .c_str())                                                                              //-V206
12277 
12278             else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object))
12279                 {
12280 $               PRINT_ (", what(): \"%s\"", e->what());
12281                 }
12282             else
12283                 {$ err = 1; }
12284             }
12285         else
12286             {$ err = 2; }
12287         }
12288 
12289 $   if (err && object && szObj)
12290         {
12291 $       const unsigned char* buf = (const unsigned char*) object;
12292 
12293 $       if (szObj >= 64) szObj = 64;
12294 
12295 $       PRINT_ (", дамп: [");
12296 $       for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' );
12297 
12298 $       PRINT_ ("]");
12299 $       for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]);
12300 
12301 $       err = 0;
12302         }
12303 
12304 $   if (err)
12305         {$ PRINT_ (" = ??"); }
12306 
12307 $   PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object);  //-V560
12308 
12309     #undef PRINT_VAL_
12310     #undef PRINT_
12311     #undef NO_
12312 
12313 $   return s - what;
12314     }
12315 
12316 #endif // TX_COMPILED
12317 
12318 //}
12319 //-----------------------------------------------------------------------------------------------------------------
12320 
12321 //-----------------------------------------------------------------------------------------------------------------
12322 //{          Stack trace and debug info access
12323 //-----------------------------------------------------------------------------------------------------------------
12324 
12325 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12326 
12327 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/,
12328                                       CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/,
12329                                       HANDLE thread /*= GetCurrentThread()*/)
12330     {
12331 $6  const int maxFrames = 62;  // MS says: < 63
12332 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12333 
12334     if (framesToSkip == -1) {$ return trace; }
12335 
12336 $   static void* capture [maxFrames] = {};
12337 $   int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread);
12338 
12339 $   memset (trace, 0, sizeof (trace));
12340 $   char* s = trace;
12341 
12342 $   bool haveSrcInfo = false;
12343 
12344     #define PRINT_(...)  s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__)
12345 
12346 $   for (int i = 0, n = 0; i < frames; i++)  //-V2530
12347         {
12348 $       void* addr = capture[i];
12349 
12350 $       Win32::SYMBOL_INFO*     sym    = NULL;
12351 $       Win32::IMAGEHLP_LINE64* line   = NULL;
12352 $       const char*             module = NULL;
12353 $       const char*             source = NULL;
12354 $       bool                    inTX   = false;
12355 
12356         if (addr)                {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module);          }
12357         if (readSource && !inTX) {$        _txSymGetFromAddr ((void*) 1,        NULL, NULL,  NULL, &source, 2); }  //-V566
12358 
12359 $       int nl = 0;
12360 $       while (s > trace && s[-1] == '\n') { s--; nl++; }
12361 
12362         #if !defined (_TX_FULL_STACKTRACE)
12363 
12364 $       if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber))))
12365             {$ continue; }
12366 
12367         #endif
12368 
12369 $       PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr);
12370 $       n++;
12371 
12372         if (addr ==                    0)          {$ PRINT_ (" [Неверный фрейм]");        break; }
12373         if (addr == (void*)           -1)          {$ PRINT_ (" [Странный фрейм]");        break; }
12374         if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; }  //-V566
12375 
12376         if (module)                                {$ PRINT_ (" in %s%s",     module, ((sym && *sym->Name)? ": " : "")); }
12377         if (sym  && *sym->Name)                    {$ PRINT_ ("%s()",         sym->Name);                                }
12378         if (line && line->FileName)                {$ PRINT_ (" at %s",       line->FileName);   haveSrcInfo = true;     }
12379         if (line && line->LineNumber)              {$ PRINT_ (":%d",    (int) line->LineNumber); haveSrcInfo = true;     }
12380         if (source)                                {$ PRINT_ (":\n\n" "%s\n", source);                                   }
12381 
12382         if (sym && strcmp (sym->Name , "main") == 0) {$ break; }
12383         }
12384 
12385 $   while (s > trace && s[-1] == '\n') s--;
12386 $   *s = 0;
12387 
12388 $   int bits = sizeof (void*) * CHAR_BIT;
12389     if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ ("TXLib бедствует: Не загрузилась библиотека"); }
12390     if (!Win32::SymSetOptions)                                 {$ PRINT_ (" DbgHelp%d.dll или DbgHelp.dll,", bits); }
12391     if (                         !Win32::MinGW::SymSetOptions) {$ PRINT_ (" MgwHelp%d.dll или MgwHelp.dll,", bits); }
12392     if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ (" отладочная информация недоступна :(\n"); }
12393 
12394 $   while (s > trace && s[-1] == '\n') s--;
12395 $   *s = 0;
12396 
12397 $   if (!haveSrcInfo)
12398         {$ PRINT_ ("\n\n" "TXLib печалится: Нет информации об исходных файлах. Вы не забыли опцию -g при компиляции?"); }
12399 
12400     #if defined (_MSC_VER)
12401     #pragma warning (push)
12402     #pragma warning (disable: 28199)  // Using possibly uninitialized memory '*s'
12403     #endif
12404 
12405 $   while (s > trace && s[-1] == '\n') s--;
12406 $   *s = 0;
12407 
12408     #if defined (_MSC_VER)
12409     #pragma warning (pop)             // Using possibly uninitialized memory '*s'
12410     #endif
12411 
12412     #undef PRINT_
12413 
12414 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12415 
12416     #if !defined (_TX_NO_MINIDUMP)
12417 $   _txCreateMiniDump (exc);
12418     #endif
12419 
12420 $   return trace;
12421     }
12422 
12423 //-----------------------------------------------------------------------------------------------------------------
12424 
12425 // Stack WALKING if the program is DEAD. Dead, Carl!
12426 
12427 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/,
12428                   HANDLE thread /* = GetCurrentThread()*/)
12429     {
12430 $9  namespace MinGW = Win32::MinGW;
12431 
12432 $   assert (capture);
12433 
12434 $   HANDLE process  = GetCurrentProcess();
12435 $   bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId());
12436 
12437 $   CONTEXT ctx = {};
12438 $   ctx.ContextFlags |= CONTEXT_FULL;
12439 
12440 $   int isWow64 = 0;
12441 $   if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64);
12442     else {$ return -1; }
12443 
12444 $   if (context)
12445         {
12446 $       ctx = *context;
12447         }
12448     else
12449         {
12450 $       if (thisThread)
12451             {
12452 $           _TX_CALLv (Win32::RtlCaptureContext, (&ctx));
12453             }
12454         else
12455             {
12456 $           SuspendThread (thread);  //-V720
12457 
12458 $           ctx.ContextFlags = CONTEXT_ALL;
12459 $           bool ok = !!GetThreadContext (thread, &ctx);
12460 
12461 $           if (!ok)
12462                 {
12463 $               ResumeThread (thread);
12464 $               return -1;
12465                 }
12466             }
12467         }
12468 
12469 $   Win32::STACKFRAME64 frame = {};
12470 $   frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat;
12471 
12472 $   int cpu = 0;
12473 
12474     #if defined (_WIN64)
12475 
12476 $   if (isWow64)
12477         {
12478 $       Win32::WOW64_CONTEXT wow64ctx = {};
12479 $       wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL;
12480 
12481 $       if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx)))  // This call fails in WINE,
12482             {                                                               // while EXIT_PROCESS_DEBUG_EVENT
12483             if (!thisThread) {$ ResumeThread (thread); }
12484 $           return 0;
12485             }
12486 
12487 $       cpu = IMAGE_FILE_MACHINE_I386;
12488 
12489 $       frame.AddrPC   .Offset = wow64ctx.Eip;
12490 $       frame.AddrStack.Offset = wow64ctx.Esp;
12491 $       frame.AddrFrame.Offset = wow64ctx.Ebp;
12492         }
12493     else
12494         {
12495 $       cpu = IMAGE_FILE_MACHINE_AMD64;
12496 
12497 $       frame.AddrPC   .Offset = ctx.Rip;
12498 $       frame.AddrStack.Offset = ctx.Rbp;
12499 $       frame.AddrFrame.Offset = ctx.Rsp;
12500         }
12501 
12502     #else
12503 
12504         {
12505 $       cpu = IMAGE_FILE_MACHINE_I386;
12506 
12507 $       frame.AddrPC   .Offset = ctx.Eip;
12508 $       frame.AddrStack.Offset = ctx.Ebp;
12509 $       frame.AddrFrame.Offset = ctx.Esp;
12510         }
12511 
12512     #endif
12513 
12514 $   assert (cpu);
12515 
12516     if (_txSetJmp()) {$ _txSymGetFromAddr ((void*) 1); }  //-V566
12517 
12518 $   int  frames = -1;
12519 
12520 $   for (frames = -framesToSkip; frames < (int) szCapture; frames++)  //-V202 //-V2530
12521         {
12522 $       DWORD64 prev = frame.AddrStack.Offset;
12523 
12524         // Я злой и страшный серый walk. Я в поросятах знаю talk.
12525 
12526         if (!_txSetJmp()) {$ break; }
12527 
12528 #if   defined (_GCC_VER)
12529 
12530         if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12531                                             MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; }
12532 #elif defined (_MSC_VER)
12533 
12534 $       if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL,
12535                                             Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; }
12536 #else
12537         #error _GCC_VER / _MSC_VER not defined
12538 #endif
12539         if (frames < 0) {$ continue; }
12540 
12541 $       void* addr = (void*) frame.AddrPC.Offset;
12542 
12543         if (frame.AddrFrame.Offset == 0)   {$ addr =          0; }  // Bad frame
12544         if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; }  // Strange frame
12545 
12546 $       assert (0 <= frames && frames < (int) szCapture);  //-V202
12547 
12548 $       capture[frames] = addr;                            //-V108
12549         }
12550 
12551     if (!thisThread) {$ ResumeThread (thread); }
12552 
12553 $   return frames;
12554     }
12555 
12556 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl
12557 
12558 //-----------------------------------------------------------------------------------------------------------------
12559 
12560 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/,
12561                         Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/,
12562                         const char** source /*= NULL*/, int context /*= 2*/)
12563     {
12564 $7  static HANDLE process = NULL;
12565 
12566 #if   defined (_GCC_VER)
12567     #define LIB_  Win32::MinGW
12568 
12569 #elif defined (_MSC_VER)
12570     #define LIB_  Win32
12571 
12572 #else
12573     #error _GCC_VER / _MSC_VER not defined
12574 #endif
12575 
12576 $   if (!process && addr)
12577         {
12578 $       process = GetCurrentProcess();
12579 
12580 $       DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES |
12581                         SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS;
12582 
12583 $        _TX_CALL (LIB_::SymSetOptions, (options));
12584 $        _TX_CALL (LIB_::SymInitialize, (process, NULL, true));
12585         }
12586 
12587 $   static DWORD64 mod = 0;
12588 
12589 $   if (module)
12590         {
12591 $       static char sMod [MAX_PATH] = "";
12592 $       memset (sMod, 0, sizeof (sMod));
12593 
12594 $       mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr));
12595 
12596 $       GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH);
12597 
12598 $       char* ext = strrchr (sMod, '.');
12599         if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); }
12600 
12601 $       *module = sMod;
12602         }
12603 
12604 $   static char buffer [_TX_BUFSIZE] = "";
12605 $   static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer;  //-V1032
12606 
12607 $   if (symbol)
12608         {
12609 $       memset (buffer, 0, sizeof (buffer));
12610 
12611 $       sym->MaxNameLen   = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1;
12612 $       sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO);
12613 $       unsigned long long ofs = 0;
12614 
12615 $       int ok = _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym));
12616         if (!ok) {$ return false; }
12617 
12618         if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; }
12619 
12620 $       *symbol = sym;
12621         }
12622 
12623 $   static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line64) };
12624 
12625 $   if (line)
12626         {
12627 $       memset (&line64, 0, sizeof (line64));
12628 
12629 $       DWORD ofs = 0;
12630 $       int ok = _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64));
12631         if (!ok) {$ return false; }
12632 
12633 $       *line = &line64;
12634         }
12635 
12636 $   if (source)
12637         {
12638 $       static char buf [_TX_BUFSIZE] = "";
12639 $       memset (buf, 0, sizeof (buf));
12640 
12641 $       if (line64.FileName && line64.LineNumber)
12642             {
12643 $           _txReadSource (buf, sizeof (buf) - 1, line64.FileName,
12644                           (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber);
12645 
12646 $           *source = buf;
12647             }
12648 
12649         if (!*source || !**source) {$ *source = NULL; }
12650         }
12651 
12652 $   if (!addr && process)
12653         {
12654 $       _TX_CALL (LIB_::SymCleanup, (process));
12655 
12656 $       process = NULL;
12657         }
12658 
12659     #if (_GCC_VER == 481)
12660     #pragma GCC diagnostic push
12661     #pragma GCC system_header
12662     #endif
12663 
12664 $   if (symbol)
12665         {
12666 $       if (strstr  (sym->Name, "::TX::")                                                  ||
12667            (strncmp (sym->Name, "_tx",  3) == 0 && isupper ((unsigned char) sym->Name[3])) ||
12668            (strncmp (sym->Name,  "tx",  2) == 0 && isupper ((unsigned char) sym->Name[2])) ||
12669             strncmp (sym->Name, "_tx_", 4) == 0                                            ||  //-V112
12670             strncmp (sym->Name,  "tx_", 3) == 0)
12671             {
12672 $           return true;
12673             }
12674 
12675     #if (_GCC_VER == 481)
12676     #pragma GCC diagnostic pop
12677     #endif
12678 
12679 $       if (!line || !line64.FileName) return false;
12680 
12681 $       intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1);
12682 
12683 $       return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) &&
12684                (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\');
12685         }
12686 
12687     #undef LIB_
12688 
12689 $   return false;
12690     }
12691 
12692 //-----------------------------------------------------------------------------------------------------------------
12693 
12694 intptr_t _txReadSource (char buf[], intptr_t size, const char file[],
12695                         int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/)
12696     {
12697 $7  assert (buf);
12698 
12699     if (!file || !*file) {$ return 0; }
12700 
12701     if (linStart < 1) {$ linStart = 1;       }
12702     if (linEnd == -1) {$ linEnd   = INT_MAX; }
12703 
12704 $   FILE* f = NULL;
12705 $   fopen_s (&f, file, "r");
12706     if (!f) {$ return 0; }
12707 
12708 $   int n = 1;
12709     while (!feof (f))
12710         {
12711         if (n >= linStart) {$ break; }
12712         while (!feof (f) && fgetc (f) != '\n')
12713             ;
12714         n++;
12715         }
12716 
12717 $   char* s = buf;
12718 
12719     #define SZ_  ( size - 3 - (s - buf) )
12720 
12721 $   while (!feof (f) && SZ_ > 0)
12722         {
12723         if (n > linEnd || _txNOP (SZ_) < 0) {$ break; }
12724 
12725         if (linMark != INT_MIN)
12726             {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : "  "), n); }
12727 
12728 $       int c = 0;
12729 $       while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c;
12730         if (c == EOF) {$ s--; }
12731 
12732         if (SZ_ > 0) {$ *s++ = '\n'; }
12733 $       n++;
12734         }
12735 
12736     if (n <= linEnd && SZ_ <= 0)
12737         {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); }
12738 
12739     #undef SZ_
12740 
12741 $   fclose (f);
12742 
12743     if (s > buf && s[-1] == '\n') {$ s--; }
12744 $   *s = 0;
12745 
12746 $   return (s - buf);
12747     }
12748 
12749 //-----------------------------------------------------------------------------------------------------------------
12750 
12751 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/)
12752     {
12753 $6  const int maxFrames = 62;  // TX says too: < 63
12754 $   static char trace [(MAX_PATH + 1024+1) * maxFrames] = "";
12755 
12756     if (framesToSkip == -1) {$ return trace; }
12757 
12758 $   memset (trace, 0, sizeof (trace));
12759 $   char* s = trace;
12760 
12761     #define SZ_  ( sizeof (trace) - 1 - 3 - (s-trace) )
12762 
12763 $   const _txLoc* loc = &_txLoc::Cur;
12764 
12765     for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; }
12766 
12767 $   for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev)
12768         {
12769         if (i < 0) {$ continue; }
12770 
12771         if (loc->func || loc->file || loc->line)
12772             {
12773 $           s += _tx_snprintf_s     (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""),
12774                                      i, loc->func, loc->file, loc->line);
12775 
12776 $           if (readSource)
12777                 {
12778 $               s += _tx_snprintf_s (s, SZ_, ":\n\n");
12779 $               s += _txReadSource  (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line);
12780                 }
12781             }
12782         }
12783 
12784     #undef SZ_
12785 
12786 $   s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), "");
12787 
12788 $   return trace;
12789     }
12790 
12791 //-----------------------------------------------------------------------------------------------------------------
12792 
12793 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/)
12794     {
12795 $6  static char dumpName[MAX_PATH] = "";
12796     if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); }
12797 
12798 $   HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
12799 
12800     if (!file || file == INVALID_HANDLE_VALUE) {$ return false; }
12801 
12802 $   Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false };
12803 $   Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory);
12804 
12805 $   bool ok = _TX_CALL (Win32::MiniDumpWriteDump, (GetCurrentProcess(), GetCurrentProcessId(), file, type,
12806                                                    ((exc)? &excInfo : NULL), NULL, NULL));
12807 $   CloseHandle (file);
12808 
12809     if (ok) {$ return true;  }
12810     else    {$ return false; }
12811     }
12812 
12813 #endif // TX_COMPILED
12814 
12815 //}
12816 //-----------------------------------------------------------------------------------------------------------------
12817 
12818 //-----------------------------------------------------------------------------------------------------------------
12819 //{          Errors reporting
12820 //-----------------------------------------------------------------------------------------------------------------
12821 
12822 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
12823 
12824 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args)  //-V2008
12825     {
12826     _txErrors = _txErrors + 1;
12827 
12828     DWORD           winErr   = GetLastError();
12829 
12830     int             crtErr   = errno;
12831 
12832     #if !defined (__CYGWIN__)
12833     unsigned long   dosErr   = _doserrno;
12834     #else
12835     unsigned long   dosErr   = 0;
12836     #endif
12837 
12838     unsigned        dlgErr   = _TX_CALL (Win32::CommDlgExtendedError, ());
12839 
12840     unsigned        oglErr   = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError;
12841 
12842     unsigned        threadId = GetCurrentThreadId();
12843 
12844     enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 };
12845     unsigned options = 0;
12846 
12847     for (; msg && *msg; msg++)
12848         {
12849         if      (*msg == '\a') options |= isFatal;
12850         else if (*msg == '\v') options |= isWarning;
12851         else if (*msg == '\b') options |= noMsgBox;
12852         else if (*msg == '\f') options |= fmtOnly;
12853         else if (*msg == '\t') options |= traceSE;
12854         else break;
12855         }
12856 
12857     const char* stkTrace = NULL;
12858     const char*  txTrace = NULL; (void) txTrace;
12859 
12860     if (!(options & fmtOnly))
12861         {
12862         stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace   (2, true);
12863         txTrace  =                                                    _txCaptureStackBackTraceTX (0, true);
12864         }
12865 
12866     static char what[_TX_BIGBUFSIZE*10] = "";
12867     static char str [_TX_BIGBUFSIZE]    = "";
12868     char *s = what;
12869 
12870     #define     PRINT_(...)  s += _tx_snprintf_s  (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12871     #define    VPRINT_(...)  s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__)
12872 
12873                 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" :
12874                                          (options & isFatal)?   "соболезнует..." :
12875                                                                 "сообщает:"));
12876                 PRINT_ ("Программа: %s", txGetModuleFileName());
12877     if (file)   PRINT_ (", файл: %s",    file);
12878     if (line)   PRINT_ (", строка: %d",  line);
12879     if (func)   PRINT_ (", функция: %s", func);
12880                 PRINT_ (",\n\n");
12881 
12882     if (msg)    PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"),
12883                VPRINT_ (msg, args);
12884 
12885     while (s > what && s[-1] == '\n') s--;
12886 
12887                 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s",
12888 
12889                         _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64,
12890 
12891                         "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace,
12892 
12893                         threadId, (threadId == _txMainThreadId)?    " (Main)"   :
12894                                   (threadId == _txCanvas_ThreadId)? " (Canvas)" : "");
12895 
12896     if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr),
12897                 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,  //-V102
12898                                     NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
12899                                     s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2,            //-V202
12900                 s -=  (s[-1] == '.')? 1 : 0,
12901                 PRINT_ (")");
12902 
12903     if (crtErr) PRINT_ (", errno: %d (%s)",                      crtErr, (strerror_s (str, sizeof (str), crtErr), str));
12904     if (dosErr) PRINT_ (", _doserrno: %lu (%s)",                 dosErr, (strerror_s (str, sizeof (str), dosErr), str));
12905     if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)",       oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr)));
12906     if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr);
12907 
12908     #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L)
12909                 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : "");
12910     #else
12911                 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true."  : "");
12912     #endif
12913 
12914     if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) &&
12915        (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func))
12916                 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func);
12917 
12918     txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what);
12919 
12920     if (options & fmtOnly)
12921         {
12922         SetLastError (winErr);
12923 
12924         errno = crtErr;
12925 
12926         #if !defined (__CYGWIN__)
12927         _doserrno = dosErr;
12928         #endif
12929 
12930         return what;
12931         }
12932 
12933     txSetProgress (-1, Win32::TBPF_ERROR);
12934 
12935     unsigned restore = txGetConsoleAttr();
12936     txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED);
12937     if (color) {$ txSetConsoleAttr (color); }
12938 
12939     int oldCP = GetConsoleOutputCP();
12940     SetConsoleOutputCP (_TX_CODEPAGE);
12941 
12942     fprintf (stderr,        "\n" "--------------------------------------------------\n"
12943                                  "%s",
12944                                  what);
12945     if (stkTrace)
12946         {  fprintf (stderr, "\n" "--------------------------------------------------\n"
12947                                  "Стек вызовов:\n\n"
12948                                  "%s\n\n"
12949                                  "--------------------------------------------------\n",
12950                                  stkTrace); }
12951     errno = 0;
12952     char sErrno[256] = "";
12953     FILE* log = NULL;
12954     if (*_txLogName) fopen_s (&log, _txLogName, "a");
12955     strerror_s (sErrno, sizeof (sErrno), errno);
12956 
12957     if (!log)
12958         {$ fprintf (stderr, "\n" "TXLib шокирован: Не открывается лог-файл \"%s\" для записи: Ошибка %d (%s)!\n",
12959                                  _txLogName, errno, sErrno); }
12960 
12961     SetConsoleOutputCP (oldCP);
12962     txSetConsoleAttr (restore);
12963 
12964     if (log)
12965         {
12966         fprintf (log,       "\n" "--------------------------------------------------\n"
12967                                  "%s\n"
12968                                  "--------------------------------------------------\n",
12969                                  what);
12970 
12971         fprintf (log,            "Стек вызовов:\n\n"  //-V576
12972                                  "%s\n",
12973                                  (*_txTraceSE)? _txTraceSE : stkTrace);
12974 
12975         #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG)
12976 
12977         if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace)
12978             {
12979             fprintf (log,   "\n" "--------------------------------------------------\n"
12980                                  "Стек вызовов TX:\n\n"
12981                                  "%s\n",
12982                                  txTrace);
12983             }
12984 
12985         #endif
12986 
12987         fprintf (log,       "\n" "--------------------------------------------------\n"
12988                                  "%s\n\n"
12989                                  "--------------------------------------------------\n",
12990                                  _txAppInfo());
12991         }
12992 
12993     if (log) fclose (log);
12994 
12995     txSleep();
12996 
12997     int ret = 0;
12998 
12999     if (!(options & noMsgBox))
13000         {
13001         txSleep (_txWindowUpdateInterval);
13002 
13003         HWND wnd = GetForegroundWindow();
13004 
13005         PRINT_ ("\n" "Прервать программу?");
13006 
13007         ret = txMessageBox (what, ((options & isWarning)? "Предупреждение"   :
13008                                    (options & isFatal)?   "Фатальная ошибка" :
13009                                                           "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL);
13010         _txActivateWindow (wnd, 0x10);
13011         }
13012 
13013     SetLastError (winErr);
13014 
13015     errno = crtErr;
13016 
13017     #if !defined (__CYGWIN__)
13018     _doserrno = dosErr;
13019     #endif
13020 
13021     if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES)
13022         {
13023         txUnlock();
13024         _txCleanup();
13025         Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE);
13026         }
13027 
13028     #undef  PRINT_
13029     #undef VPRINT_
13030 
13031     return what;
13032     }
13033 
13034 //-----------------------------------------------------------------------------------------------------------------
13035 
13036 #if defined (_MSC_VER)
13037 
13038 int _txOnErrorReport (int type, const char* text, int* ret)
13039     {
13040     assert (text);
13041     assert (ret);
13042 
13043     _txErrors = _txErrors + 1;
13044 
13045     unsigned restore = txGetConsoleAttr();
13046 
13047     switch (type)
13048        {
13049        case _CRT_WARN:   txSetConsoleAttr (FOREGROUND_LIGHTRED);     break;
13050        case _CRT_ERROR:  txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break;
13051        case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW);       break;
13052        default:                                                      break;  //-V2522
13053        }
13054 
13055     const char startReport[] = "Detected memory leaks!\n",
13056                  endReport[] = "Object dump complete.\n";
13057 
13058     if (strcmp (text, startReport) == 0)  // Dirty, dirty hack. А что делать?
13059         {
13060         _txOnErrorReport (type, "\n",                                                                              NULL);
13061         _txOnErrorReport (type, _TX_VERSION " - ERROR: ",                                                          NULL);
13062         _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL);
13063         _txOnErrorReport (type, "\n",                                                                              NULL);
13064         }
13065 
13066     size_t len = strlen (text);
13067     if (text [len-1] != '\n')               txOutputDebugPrintf ("%s",                text);
13068     else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION);
13069     else                                    txOutputDebugPrintf ("%s\n",              text);
13070 
13071     DWORD n = 0;
13072     HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
13073     WriteFile (err, text, (DWORD) strlen (text), &n, NULL);      //-V202
13074 
13075     txSetConsoleAttr (restore);
13076 
13077     if (*_txLogName) do                                          //-V2530
13078         {
13079         HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
13080         if (log == INVALID_HANDLE_VALUE) break;
13081 
13082         SetFilePointer (log, 0, NULL, FILE_END);
13083         WriteFile (log, text, (DWORD) strlen (text), &n, NULL);  //-V202
13084 
13085         CloseHandle (log);
13086         }
13087         while (false);
13088 
13089     if (ret) *ret = 0;
13090 
13091     return (type == _CRT_WARN);
13092     }
13093 
13094 #endif
13095 
13096 //-----------------------------------------------------------------------------------------------------------------
13097 
13098 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/)
13099     {
13100 $5  static wchar_t textW   [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]";
13101 $   static wchar_t headerW [_TX_BUFSIZE    * sizeof (wchar_t)] = L"[NULL header]";
13102 
13103     if (text)   {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text,   -1, textW,   sizearr (textW))   || memset (textW,   0, sizeof (textW));   }
13104     if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); }
13105 
13106 $   txSleep();
13107 
13108 $   int ret = MessageBoxW (NULL, (*textW)? textW : L"[Empty]", (*headerW)? headerW : L"[Empty]",
13109                            flags | MB_SETFOREGROUND | MB_TOPMOST);
13110 
13111 $   GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU);
13112 
13113 $   if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU))
13114         {
13115 $       SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0);
13116 $       _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
13117         }
13118 
13119 $   return ret;
13120     }
13121 
13122 //-----------------------------------------------------------------------------------------------------------------
13123 
13124 bool txGetAsyncKeyState (int key)
13125     {
13126 $1  HWND wnd = GetForegroundWindow();
13127 
13128     return (GetAsyncKeyState (key) & 0x8000) &&
13129            (wnd == txWindow() || wnd == Win32::GetConsoleWindow());
13130     }
13131 
13132 //-----------------------------------------------------------------------------------------------------------------
13133 
13134 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...)
13135     {
13136 $5  if (_TX_ARGUMENT_FAILED (format)) return false;
13137 
13138 $   va_list arg; va_start (arg, format);
13139 $   bool ok = true;
13140 
13141     #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500)
13142 
13143 $   NOTIFYICONDATA nid = { sizeof (nid) };
13144 
13145 $   nid.uFlags      = NIF_ICON | NIF_TIP | NIF_INFO;
13146 $   nid.hWnd        = NULL;
13147 $   nid.uID         = 1;
13148 $   nid.hIcon       = _txCreateTXIcon (16); assert (nid.hIcon);
13149 $   strncpy_s       (nid.szTip,       sizeof (nid.szTip),       "TXLib Information", sizeof (nid.szTip));
13150 $   strncpy_s       (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1);
13151 $   _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg);
13152 $   nid.dwInfoFlags = flags;
13153 
13154 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo);
13155 
13156 $   ok &= !!Shell_NotifyIcon (NIM_ADD,    (::NOTIFYICONDATA*) &nid);
13157 $   ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid);
13158 
13159 $   if (nid.hIcon) DestroyIcon (nid.hIcon) asserted;
13160 
13161     #else
13162 
13163 $   char nid_szInfo[_TX_BUFSIZE] = "";
13164 $   _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg);
13165 $   txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo);
13166 $   ok = false;
13167 
13168 $   (void)flags; (void)title;
13169 
13170     #endif
13171 
13172 $   va_end (arg);
13173     return ok;
13174     }
13175 
13176 //-----------------------------------------------------------------------------------------------------------------
13177 
13178 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...)
13179     {
13180     unsigned id = GetCurrentThreadId();
13181 
13182     const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}};
13183 
13184     char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)];
13185 
13186     char msgStr[_TX_BUFSIZE] = "";
13187     if (msg)
13188         {
13189         va_list arg; va_start (arg, msg);
13190         _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg);
13191         va_end (arg);
13192         }
13193 
13194     txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d)  " "|%*s%s" "%s%s\n",
13195 
13196                          _TX_VERSION, (void*) &_txInitialized,
13197 
13198                          "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit],
13199                          _txLoc::Cur.trace, mark,
13200 
13201                          (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line,
13202                          2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""),
13203 
13204                          ((*msgStr && func)? ": " : ""), msgStr);
13205     }
13206 
13207 //-----------------------------------------------------------------------------------------------------------------
13208 
13209 int txOutputDebugPrintf (const char* format, ...)
13210     {
13211     if (!format) return 0;
13212 
13213     enum { msgbox = 1, print = 2, compr = 4 };
13214     int options = 0;
13215 
13216     for (; format && *format; format++)
13217         {
13218         if      (*format == '\a') options |= msgbox;
13219         else if (*format == '\f') options |= print;
13220         else if (*format == '\r') options |= compr;
13221         else break;
13222         }
13223 
13224     char text[_TX_BIGBUFSIZE] = "";
13225 
13226     va_list arg; va_start (arg, format);
13227     int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg);  //-V202
13228     va_end (arg);
13229 
13230     struct __ { static int trimSpaces (char str[])
13231         {
13232         char *dst = str, *src = str;
13233 
13234         for (char d = ' '; d; src++)
13235             if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; }
13236             else                                                 *dst++ = d = *src;
13237 
13238         return (int) (dst - str - 1);  //-V202
13239         }};
13240 
13241     if (options & compr)  n = __::trimSpaces (text);
13242 
13243     OutputDebugString (text);
13244 
13245     if (options & print)  fprintf (stderr, "%s", text);
13246 
13247     if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION);
13248 
13249     return n;
13250     }
13251 
13252 //-----------------------------------------------------------------------------------------------------------------
13253 
13254 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...)
13255     {
13256     if (!format) return 0;
13257 
13258     va_list arg; va_start (arg, format);
13259     intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg);
13260     va_end (arg);
13261 
13262     return ret;
13263     }
13264 
13265 //-----------------------------------------------------------------------------------------------------------------
13266 
13267 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg)
13268     {
13269     if (!stream || !format) return 0;
13270 
13271     #if defined (_TRUNCATE)
13272     intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg);
13273     #else
13274     intptr_t ret = _vsnprintf   (stream, size,            format, arg);
13275     #endif
13276 
13277     if (ret < 0 && size >= 4)  //-V112
13278         {
13279         const char ellipsis[] = "...";
13280         size_t     szEllipsis = sizeof (ellipsis) - 1;
13281 
13282         strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis);
13283         }
13284 
13285     return (ret >= 0)? ret : size;
13286     }
13287 
13288 //-----------------------------------------------------------------------------------------------------------------
13289 
13290 #if defined (__CYGWIN__)
13291 
13292 int _getch()
13293     {
13294     termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr);
13295 
13296     termios newattr = oldattr;
13297     newattr.c_lflag &= ~(ICANON | ECHO);
13298     tcsetattr (STDIN_FILENO, TCSANOW, &newattr);
13299 
13300     int ch = getchar();
13301 
13302     tcsetattr (STDIN_FILENO, TCSANOW, &oldattr);
13303 
13304     return ch;
13305     }
13306 
13307 //-----------------------------------------------------------------------------------------------------------------
13308 
13309 int _putch (int ch)
13310     {
13311     termios old = {}; tcgetattr (STDOUT_FILENO, &old);
13312 
13313     termios cur = old;
13314     cur.c_lflag &= ~ICANON;
13315     cur.c_lflag |=  ECHO;
13316     tcsetattr (STDOUT_FILENO, TCSANOW, &cur);
13317 
13318     putchar (ch);
13319 
13320     tcsetattr (STDOUT_FILENO, TCSANOW, &old);
13321 
13322     return ch;
13323     }
13324 
13325 //-----------------------------------------------------------------------------------------------------------------
13326 
13327 int _kbhit()
13328     {
13329     termios old = {}; tcgetattr (STDIN_FILENO, &old);
13330 
13331     termios cur = old;
13332     cur.c_lflag &= ~(ICANON | ECHO);
13333     cur.c_cc[VMIN]  = 1;
13334     cur.c_cc[VTIME] = 0;
13335 
13336     tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur);
13337 
13338     fd_set  fd = {}; FD_SET (STDIN_FILENO, &fd);
13339     timeval tv = {};
13340 
13341     int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd);
13342 
13343     tcsetattr (STDIN_FILENO, TCSAFLUSH, &old);
13344 
13345     return res;
13346     }
13347 
13348 #endif
13349 
13350 #endif // TX_COMPILED
13351 
13352 //}
13353 //-----------------------------------------------------------------------------------------------------------------
13354 
13355 //-----------------------------------------------------------------------------------------------------------------
13356 //{          Information
13357 //-----------------------------------------------------------------------------------------------------------------
13358 
13359 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13360 
13361 const char* txGetModuleFileName (bool fileNameOnly /*= true*/)
13362     {
13363 $9  static char name[MAX_PATH] = "";
13364 
13365 $   if (!*name)
13366         {
13367 $       if (!GetModuleFileName (NULL, name, sizeof (name) - 1))
13368             {$ strncpy_s (name, sizeof (name), "~TXApp", 6); }
13369 
13370 $       char* ext = strrchr (name, '.');
13371 $       if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name));
13372         }
13373 
13374 $   assert (*name);
13375 
13376 $   if (fileNameOnly) return name;
13377 
13378 $   static char fullName[MAX_PATH] = "";
13379 $   static char* title = fullName;
13380 
13381 $   if (!*fullName || !*title)
13382         {
13383 $       strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1);
13384 
13385 $             title = strrchr (fullName, '\\'); if (!title) title = fullName;
13386 $       char* ext   = strrchr (fullName,  '.'); if (!ext)   ext   = fullName + strlen (fullName);
13387 
13388 $       size_t sz = sizeof (fullName) - (ext - fullName);
13389 $       strncpy_s (ext, sz-1, " - TXLib", sz);
13390 
13391 $       title++;
13392         }
13393 
13394 $   assert (*title);
13395 
13396 $   return title;
13397     }
13398 
13399 #endif // TX_COMPILED
13400 
13401 //-----------------------------------------------------------------------------------------------------------------
13402 
13403 inline const char* _txAppInfo()
13404     {
13405 $1  time_t timeT     = time (NULL) - clock()/CLOCKS_PER_SEC;  //-V104
13406     char   timeS[32] = "";
13407     ctime_s (timeS, sizeof (timeS), &timeT);
13408 
13409     static char text[_TX_BUFSIZE] = "";
13410     char cwd [MAX_PATH] = "";
13411 
13412     _tx_snprintf_s (text, sizeof (text) - 1,
13413 
13414                     "Developed with:\n\n"
13415                     "The Dumb Artist Library (TX Library)\n"
13416                     _TX_VERSION "\n" _TX_AUTHOR "\n"
13417                     "See license on: http://txlib.ru\n\n"
13418 
13419                     "TXLib file:" "\t" __FILE__ "\n"
13420                     "Compiled:"   "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n"
13421                     "Started:"    "\t" "%.6s %.4s %.8s\n\n"
13422 
13423                     "Run file:"   "\t" "%s\n"
13424                     "Directory:"  "\t" "%s",
13425 
13426     #if   defined (_MSC_VER)
13427                     "MSVC Runtime",
13428     #elif defined (__CYGWIN__)
13429                     "Cygwin Runtime",
13430     #elif defined (_GCC_VER) && defined (_WIN64)
13431                     __mingw_get_crt_info(),
13432     #else
13433                     "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION),
13434     #endif
13435                     (sizeof (void*) == sizeof (DWORD))? 32 : 64,    //-V112
13436 
13437                     timeS + 4, timeS + 20, timeS + 11,              //-V112 These offsets are ANSI standardized
13438                     txGetModuleFileName(),
13439                     _getcwd (cwd, sizeof (cwd) - 1));
13440 
13441     return text;
13442     }
13443 
13444 //}
13445 //-----------------------------------------------------------------------------------------------------------------
13446 
13448 //}
13449 //=================================================================================================================
13450 
13451 //=================================================================================================================
13452 //{          TXLib API implementation
13453 //           Реализация TXLib API
13454 //=================================================================================================================
13455 
13456 inline const char* txVersion()
13457     {
13458     return _TX_VERSION;
13459     }
13460 
13461 //-----------------------------------------------------------------------------------------------------------------
13462 
13463 inline unsigned txVersionNumber()
13464     {
13465     return _TX_VER;  //-V2517
13466     }
13467 
13468 //-----------------------------------------------------------------------------------------------------------------
13469 
13470 inline HWND txWindow()
13471     {
13472 $9  return _txCanvas_Window;
13473     }
13474 
13475 //-----------------------------------------------------------------------------------------------------------------
13476 
13477 inline HDC& txDC()
13478     {
13479     return _txCanvas_BackBuf[0];
13480     }
13481 
13482 //-----------------------------------------------------------------------------------------------------------------
13483 
13484 inline RGBQUAD* txVideoMemory()
13485     {
13486     return _txCanvas_Pixels;
13487     }
13488 
13489 //-----------------------------------------------------------------------------------------------------------------
13490 
13491 inline int txGetExtentX (HDC dc /*= txDC()*/)
13492     {
13493     return txGetExtent (dc) .x;
13494     }
13495 
13496 //-----------------------------------------------------------------------------------------------------------------
13497 
13498 inline int txGetExtentY (HDC dc /*= txDC()*/)
13499     {
13500     return txGetExtent (dc) .y;
13501     }
13502 
13503 //-----------------------------------------------------------------------------------------------------------------
13504 
13505 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
13506 
13507 POINT txGetExtent (HDC dc /*= txDC()*/)
13508     {
13509 $0  static POINT err = {-1, -1};
13510 
13511     if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; };
13512 
13513     if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; }
13514 
13515 $   BITMAP bmap = {};
13516 $   txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted;
13517 
13518 $   POINT  size = { bmap.bmWidth, bmap.bmHeight };
13519 $   return size;
13520     }
13521 
13522 //-----------------------------------------------------------------------------------------------------------------
13523 
13524 bool txDestroyWindow (HWND wnd /*= txWindow()*/)
13525     {
13526 $1  if (!wnd || !txWindow()) return false;
13527 
13528 $   if (wnd != txWindow())
13529         {
13530 $       return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd);
13531         }
13532 
13533 $   if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false;
13534 
13535 $   if (_txMain)
13536         {
13537 $       txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n"
13538                                                "Возвращайтесь через main(), там вам будут рады.\n");
13539 $       Sleep (_TX_TIMEOUT);
13540         }
13541 
13542 $   _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT);
13543 
13544 $   return _txCanvas_Window == NULL;
13545     }
13546 
13547 //-----------------------------------------------------------------------------------------------------------------
13548 
13549 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/)
13550     {
13551 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13552 
13553 $   HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color);
13554 
13555 $   if (!pen) return (HPEN) NULL;
13556 
13557 $   if (!_txBuffer_Select (pen, dc))
13558         {
13559 $       Win32::DeleteObject (pen);
13560 $       return (HPEN) NULL;
13561         }
13562 
13563 $   if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID)
13564         {$ return (HPEN) NULL; }
13565 
13566 $   return pen;
13567     }
13568 
13569 //-----------------------------------------------------------------------------------------------------------------
13570 
13571 COLORREF txColor (double red, double green, double blue)
13572     {
13573 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13574 $   if (green > 1) green = 1; if (green < 0) green = 0;
13575 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13576 
13577 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13578 
13579 $   return txSetColor (color)? color : CLR_INVALID;
13580     }
13581 
13582 //-----------------------------------------------------------------------------------------------------------------
13583 
13584 COLORREF txGetColor (HDC dc /*= txDC()*/)
13585     {
13586 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13587 
13588 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc);
13589 $   assert (obj); if (!obj) return CLR_INVALID;              //-V547
13590 
13591 $   union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {};  //-V2514
13592 
13593 $   int size = Win32::GetObject (obj, 0, NULL);
13594 $   Win32::GetObject (obj, sizeof (buf), &buf) asserted;
13595 
13596 $   return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor;
13597     }
13598 
13599 //-----------------------------------------------------------------------------------------------------------------
13600 
13601 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/)
13602     {
13603 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL;
13604 
13605 $   HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color);
13606 
13607 $   return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL);
13608     }
13609 
13610 //-----------------------------------------------------------------------------------------------------------------
13611 
13612 COLORREF txFillColor (double red, double green, double blue)
13613     {
13614 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13615 $   if (green > 1) green = 1; if (green < 0) green = 0;
13616 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13617 
13618 $   COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255));
13619 
13620 $   return txSetFillColor (color)? color : CLR_INVALID;
13621     }
13622 
13623 //-----------------------------------------------------------------------------------------------------------------
13624 
13625 COLORREF txGetFillColor (HDC dc /*= txDC()*/)
13626     {
13627 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13628 
13629 $   HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc);
13630 $   assert (obj); if (!obj) return CLR_INVALID;  //-V547
13631 
13632 $   LOGBRUSH buf = {};
13633 $   txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted;
13634 
13635 $   return buf.lbColor;
13636     }
13637 
13638 //-----------------------------------------------------------------------------------------------------------------
13639 
13640 bool txClear (HDC dc /*= txDC()*/)
13641     {
13642 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13643 
13644 $   POINT size = txGetExtent (dc);
13645 $   return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc);
13646     }
13647 
13648 //-----------------------------------------------------------------------------------------------------------------
13649 
13650 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/)
13651     {
13652 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13653 
13654 $   txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc);
13655 
13656 $   return true;
13657     }
13658 
13659 //-----------------------------------------------------------------------------------------------------------------
13660 
13661 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/)
13662     {
13663 $1  if (red   > 1) red   = 1; if (red   < 0) red   = 0;
13664 $   if (green > 1) green = 1; if (green < 0) green = 0;
13665 $   if (blue  > 1) blue  = 1; if (blue  < 0) blue  = 0;
13666 
13667 $   return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc);
13668     }
13669 
13670 //-----------------------------------------------------------------------------------------------------------------
13671 
13672 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/)
13673     {
13674 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID;
13675 
13676 $   return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc);
13677     }
13678 
13679 //-----------------------------------------------------------------------------------------------------------------
13680 
13681 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13682     {
13683 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13684 
13685 $   bool ok  = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc);
13686 $        ok &= txGDI ((Win32::LineTo   (dc, ROUND (x1), ROUND (y1)      )), dc);
13687 
13688 $   return ok;
13689     }
13690 
13691 //-----------------------------------------------------------------------------------------------------------------
13692 
13693 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13694     {
13695 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13696 
13697 $   return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13698     }
13699 
13700 //-----------------------------------------------------------------------------------------------------------------
13701 
13702 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/)
13703     {
13704 $1  if (_TX_ARGUMENT_FAILED    (points)) return false;
13705 $   if (_TX_DEFAULT_HDC_FAILED (dc))     return false;
13706 
13707 $   return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc);
13708     }
13709 
13710 //-----------------------------------------------------------------------------------------------------------------
13711 
13712 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/)
13713     {
13714 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13715 
13716 $   return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc);
13717     }
13718 
13719 //-----------------------------------------------------------------------------------------------------------------
13720 
13721 bool txCircle (double x, double y, double r)
13722     {
13723 $1  return txEllipse (x-r, y-r, x+r, y+r);
13724     }
13725 
13726 //-----------------------------------------------------------------------------------------------------------------
13727 
13728 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13729     {
13730 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13731 
13732 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13733 
13734 $   double start =  startAngle               * txPI/180,
13735            end   = (startAngle + totalAngle) * txPI/180;
13736 
13737 $   return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13738                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13739                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13740     }
13741 
13742 //-----------------------------------------------------------------------------------------------------------------
13743 
13744 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13745     {
13746 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13747 
13748 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13749 
13750 $   double start =  startAngle               * txPI/180,
13751            end   = (startAngle + totalAngle) * txPI/180;
13752 
13753 $   return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13754                                      ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13755                                      ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13756     }
13757 
13758 //-----------------------------------------------------------------------------------------------------------------
13759 
13760 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/)
13761     {
13762 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13763 
13764 $   POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) };
13765 
13766 $   double start =  startAngle               * txPI/180,
13767            end   = (startAngle + totalAngle) * txPI/180;
13768 
13769 $   return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1),
13770                                        ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)),
13771                                        ROUND (center.x + 1E3*cos (end)),   ROUND (center.y - 1E3*sin (end)))), dc);
13772     }
13773 
13774 //-----------------------------------------------------------------------------------------------------------------
13775 
13776 bool txFloodFill (double x, double y,
13777                   COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/)
13778     {
13779 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;
13780 
13781 $   if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc);
13782 
13783 $   return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc);
13784     }
13785 
13786 //-----------------------------------------------------------------------------------------------------------------
13787 
13788 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/)
13789     {
13790 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13791 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13792 
13793 $   int len = (int) strlen (text);  //-V202
13794 $   bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc);
13795 
13796 $   return ok;
13797     }
13798 
13799 //-----------------------------------------------------------------------------------------------------------------
13800 
13801 bool txDrawText (double x0, double y0, double x1, double y1, const char text[],
13802                  unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/,
13803                  HDC dc /*= txDC()*/)
13804     {
13805 $1  if (_TX_ARGUMENT_FAILED    (text)) return false;
13806 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return false;
13807 
13808 #if !defined (NDEBUG)
13809 
13810 $   if (x0 > x1)
13811         {
13812 $       SetLastError (ERROR_INVALID_DATA);
13813 $       TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1);
13814         }
13815 
13816 $   if (y0 > y1)
13817         {
13818 $       SetLastError (ERROR_INVALID_DATA);
13819 $       TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1);
13820         }
13821 
13822 #endif
13823 
13824 $   RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) };
13825 
13826 $   if (!strchr (text, '\n')) format |= DT_SINGLELINE;
13827 
13828 $   unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc);
13829 
13830 $   bool ok = false;
13831 
13832 $   if (Win32::DrawText)
13833         {
13834 $       ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc);
13835 $       Win32::GetPixel (dc, 0, 0);
13836 $       ok = true;  //-V519
13837         }
13838     else
13839         {
13840 $       txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text);
13841 $       ok = false;
13842         }
13843 
13844 $   txSetTextAlign (prev, dc);
13845 
13846 $   return ok;
13847     }
13848 
13849 //-----------------------------------------------------------------------------------------------------------------
13850 
13851 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/,
13852                     int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/,
13853                     bool strikeout /*= false*/, double angle /*= 0*/,
13854                     HDC dc /*= txDC()*/)
13855     {
13856 $1  if (_TX_ARGUMENT_FAILED    (name)) return NULL;
13857 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return NULL;
13858 
13859 $   HFONT font = txFontExist (name)?
13860                      Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3),
13861                                         ROUND (angle*10), 0, bold, italic, underline, strikeout,
13862                                         RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
13863                                         DEFAULT_QUALITY, DEFAULT_PITCH, name)
13864                      :
13865                      (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT);
13866 
13867 $   _txBuffer_Select (font, dc);
13868 
13869 $   return font;
13870     }
13871 
13872 //-----------------------------------------------------------------------------------------------------------------
13873 
13874 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/)
13875     {
13876 $1  SIZE size = {-1, -1};
13877 
13878 $   if (_TX_ARGUMENT_FAILED    (text)) return size;
13879 $   if (_TX_DEFAULT_HDC_FAILED (dc))   return size;
13880 
13881 $   size_t len = strlen (text);
13882 $   txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted;  //-V202
13883 
13884 $   return size;
13885     }
13886 
13887 //-----------------------------------------------------------------------------------------------------------------
13888 
13889 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/)
13890     {
13891 $1  return txGetTextExtent (text, dc) .cx;
13892     }
13893 
13894 //-----------------------------------------------------------------------------------------------------------------
13895 
13896 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/)
13897     {
13898 $1  return txGetTextExtent (text, dc) .cy;
13899     }
13900 
13901 //-----------------------------------------------------------------------------------------------------------------
13902 
13903 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/)
13904     {
13905 $1  if (_TX_DEFAULT_HDC_FAILED (dc)) return false;  //-V601
13906 
13907 $   return txGDI ((Win32::SetTextAlign (dc, align)), dc);
13908     }
13909 
13910 //-----------------------------------------------------------------------------------------------------------------
13911 
13912 LOGFONT* txFontExist (const char name[])
13913     {
13914 $1  if (_TX_ARGUMENT_FAILED (name)) return NULL;
13915 
13916 $   static LOGFONT font = {};
13917 $   font.lfCharSet = DEFAULT_CHARSET;
13918 $   strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1);
13919 
13920 $   struct tools
13921         {
13922         static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data)
13923             {
13924 $           if (_TX_ARGUMENT_FAILED (fnt))  return 0;
13925 $           if (_TX_ARGUMENT_FAILED (data)) return 0;
13926 
13927             #ifndef __STRICT_ANSI__
13928 $           return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13929 
13930             #else
13931 $           return  strncmp  (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE);
13932 
13933             #endif
13934             }
13935         };
13936 
13937 $   return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL;
13938     }
13939 
13940 //-----------------------------------------------------------------------------------------------------------------
13941 
13942 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/)
13943     {
13944 $1  if (_TX_ARGUMENT_FAILED    (obj)) return false;
13945 $   if (_TX_DEFAULT_HDC_FAILED (dc))  return false;
13946 
13947 $   return _txBuffer_Select (obj, dc);
13948     }
13949 
13950 //-----------------------------------------------------------------------------------------------------------------
13951 
13952 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/)
13953     {
13954 $1  POINT size = { ROUND (sizeX), ROUND (sizeY) };
13955 
13956 $   HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels);
13957 $   assert (dc); if (!dc) return NULL;  //-V547
13958 
13959 $   txSetDefaults (dc);
13960 
13961 $   if (!_txCanvas_UserDCs) return dc;
13962 
13963 $   txAutoLock _lock;
13964 $   _txCanvas_UserDCs->push_back (dc);
13965 
13966 $   if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE)
13967         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); }  //-V202
13968 
13969 $   return dc;
13970     }
13971 
13972 //-----------------------------------------------------------------------------------------------------------------
13973 
13974 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/)
13975     {
13976 $1  return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels);
13977     }
13978 
13979 //-----------------------------------------------------------------------------------------------------------------
13980 
13981 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels)
13982     {
13983 $1  return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels);
13984     }
13985 
13986 //-----------------------------------------------------------------------------------------------------------------
13987 
13988 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/,
13989                  unsigned imageFlags /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/)
13990     {
13991 $1  if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL;
13992 
13993 $   HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL),
13994                                                  filename, imageFlags, sizeX, sizeY, loadFlags);
13995 $   if (!image) return NULL;
13996 
13997 $   HDC dc = txCreateCompatibleDC (sizeX, sizeY, image);
13998 
13999 $   if (!(loadFlags & LR_LOADFROMFILE)) return dc;
14000 
14001 $   static std::map <std::string, unsigned> loadTimes;
14002 $   std::string file = filename;
14003 $   unsigned time    = GetTickCount();
14004 
14005 $   if ((long) (time - loadTimes [file]) < _TX_TIMEOUT)
14006         {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); }
14007 
14008 $   loadTimes [file] = time;
14009 
14010 $   return dc;
14011     }
14012 
14013 //-----------------------------------------------------------------------------------------------------------------
14014 
14015 bool txDeleteDC (HDC* pdc)
14016     {
14017 $1  if (_TX_ARGUMENT_FAILED (pdc)) return false;
14018 
14019 $   HDC  dc = *pdc;
14020 $   bool ok = _txBuffer_Delete (pdc);
14021 $   if (!ok) return false;
14022 
14023 $   if (!_txCanvas_UserDCs) return ok;
14024 
14025 $   txAutoLock _lock;
14026 
14027 $   for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it)
14028         if (*it == dc)
14029             {
14030 $           std::swap (*it, _txCanvas_UserDCs->back());
14031 $           _txCanvas_UserDCs->pop_back();
14032 $           break;
14033             }
14034 
14035 $   return ok;
14036     }
14037 
14038 //-----------------------------------------------------------------------------------------------------------------
14039 
14040 bool txDeleteDC (HDC dc)
14041     {
14042 $1  return txDeleteDC (&dc);
14043     }
14044 
14045 //-----------------------------------------------------------------------------------------------------------------
14046 
14047 bool txBitBlt (HDC destImage,   double xDest, double yDest, double width, double height,
14048                HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/)
14049     {
14050 $1  if (_TX_HDC_FAILED (destImage))   return false;
14051 $   if (_TX_HDC_FAILED (sourceImage)) return false;
14052 
14053 $   POINT size = txGetExtent (sourceImage);
14054 $   if (!width)  width  = size.x;  //-V550
14055 $   if (!height) height = size.y;  //-V550
14056 
14057 $   return txGDI (!!(Win32::BitBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
14058                                     sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage);
14059     }
14060 
14061 //-----------------------------------------------------------------------------------------------------------------
14062 
14063 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/)
14064     {
14065 $1  if (_TX_TXWINDOW_FAILED()) return false;
14066 
14067 $   return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource);
14068     }
14069 
14070 //-----------------------------------------------------------------------------------------------------------------
14071 
14072 bool txTransparentBlt (HDC destImage,   double xDest, double yDest, double width, double height,
14073                        HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/)
14074     {
14075     // Это проверки того, правильные ли HDC вы передали в функцию.
14076     // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а.
14077     // (!) При первом чтении это можно пропустить.
14078 
14079 $1  if (_TX_HDC_FAILED (destImage))   return false;
14080 $   if (_TX_HDC_FAILED (sourceImage)) return false;
14081 
14082     // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent().
14083     // При первом чтении это можно пропустить.
14084 
14085 $   POINT size = txGetExtent (sourceImage);
14086 $   if (!width)  width  = size.x;  //-V550
14087 $   if (!height) height = size.y;  //-V550
14088 
14089     // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest).
14090     // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только
14091     // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки).
14092     // (!) При первом чтении это можно пропустить.
14093 
14094 #if !defined (NDEBUG)
14095 
14096 $   if (!(0 <= xSource && xSource + width  <= size.x &&
14097           0 <= ySource && ySource + height <= size.y))
14098         {
14099 $       SetLastError (ERROR_INVALID_DATA);
14100 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
14101                   "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
14102         }
14103 
14104 #endif
14105 
14106 $   bool ok = true;
14107 
14108 $   if (Win32::TransparentBlt)
14109         {
14110         // (!) А вот теперь уже надо начать читать.
14111         //
14112         // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function"
14113         // и почитайте про ее параметры.
14114         //
14115         // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не
14116         // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что
14117         // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s>
14118         // это сделано для упрощения вызова функции TransparentBlt().
14119 
14120                                // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки!        // <<--
14121                                //                                                                                                          // <<--
14122                                //                                                                    |||||          ||||||                 // <<--
14123                                //                                                                    vvvvv          vvvvvv                 // <<--
14124                                                                                                                                            // <<--
14125 $       ok &= txGDI (!!(Win32::TransparentBlt (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),               // <<<<
14126                                                sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<<
14127                                                destImage);                                                                                 // <<--
14128                                //                                                                    ^^^^^          ^^^^^^                 // <<--
14129                                //                                                                    |||||          ||||||                 // <<--
14130                                //                                                                                                          // <<--
14131         }                      // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте!     // <<--
14132     else
14133         {
14134 $       ok &= txGDI (!!(Win32::BitBlt         (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
14135                                                sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
14136                                                destImage);
14137         }
14138 
14139     // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что
14140     // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s>
14141     // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL
14142     // или DirectX, будет круто. Хотя это и сложнее.</s>
14143 
14144     // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами,
14145     // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :((
14146 
14147 $   return ok;
14148     }
14149 
14150 //-----------------------------------------------------------------------------------------------------------------
14151 
14152 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage,
14153                        COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/)
14154     {
14155 $1  if (_TX_TXWINDOW_FAILED()) return false;
14156 
14157 $   return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor);
14158     }
14159 
14160 //-----------------------------------------------------------------------------------------------------------------
14161 
14162 bool txAlphaBlend (HDC destImage,   double xDest, double yDest, double width, double height,
14163                    HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
14164     {
14165 $1  if (_TX_HDC_FAILED (destImage))   return false;
14166 $   if (_TX_HDC_FAILED (sourceImage)) return false;
14167 
14168 $   POINT size = txGetExtent (sourceImage);
14169 $   if (!width)  width  = size.x;  //-V550
14170 $   if (!height) height = size.y;  //-V550
14171 
14172 #if !defined (NDEBUG)
14173 
14174 $   if (!(0 <= xSource && xSource + width  <= size.x &&
14175           0 <= ySource && ySource + height <= size.y))
14176         {
14177 $       SetLastError (ERROR_INVALID_DATA);
14178 $       TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, "
14179                   "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y);
14180         }
14181 
14182 #endif
14183 
14184 $   if (alpha < 0) alpha = 0;
14185 $   if (alpha > 1) alpha = 1;
14186 
14187 $   BITMAP bmap = { 0, 0, 0, 0, 0, 24 };
14188 $   bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap);
14189 
14190 $   BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) };  //-V112 //-V821 //-V2551
14191 
14192 $   if (Win32::AlphaBlend)
14193         {
14194 $       ok &= txGDI (!!(Win32::AlphaBlend (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
14195                                            sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)),
14196                                            destImage);
14197         }
14198     else
14199         {
14200 $       ok &= txGDI (!!(Win32::BitBlt     (destImage,   ROUND (xDest),   ROUND (yDest),   ROUND (width), ROUND (height),
14201                                            sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)),
14202                                            destImage);
14203 $       ok = false;  //-V519
14204         }
14205 
14206 $   return ok;
14207     }
14208 
14209 //-----------------------------------------------------------------------------------------------------------------
14210 
14211 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage,
14212                    double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/)
14213     {
14214 $1  if (_TX_TXWINDOW_FAILED()) return false;
14215 
14216 $   return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha);
14217     }
14218 
14219 //-----------------------------------------------------------------------------------------------------------------
14220 
14221 HDC txUseAlpha (HDC image)
14222     {
14223 $1  if (_TX_HDC_FAILED (image)) return NULL;
14224 
14225 $   HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP);
14226 $   if (!bitmap) return NULL;
14227 
14228 $   DIBSECTION dib = {};
14229 $   Win32::GetObject (bitmap, sizeof (dib), &dib) asserted;
14230 
14231 $   POINT      size = {  dib.dsBm.bmWidth, dib.dsBm.bmHeight };
14232 $   BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }};
14233 $   RGBQUAD*   buf  = NULL;
14234 
14235 $   bool isDIB = (dib.dsBm.bmPlanes        == 1                    &&
14236                   dib.dsBm.bmBitsPixel     == sizeof (RGBQUAD) * 8 &&
14237                   dib.dsBmih.biCompression == DIB_RGB_COLORS       &&
14238                   dib.dsBm.bmBits);
14239 $   if (!isDIB)
14240         {
14241 $       buf = new (std::nothrow) RGBQUAD [size.x * size.y];  //-V121
14242 $       if (!buf) return NULL;
14243 
14244 $       Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
14245         }
14246     else
14247         {
14248 $       buf = (RGBQUAD*) dib.dsBm.bmBits;
14249         }
14250 
14251 $   for (int y = 0; y < size.y; y++)
14252     for (int x = 0; x < size.x; x++)
14253         {
14254         RGBQUAD* color = &buf [x + y * size.x];  // Get color at (x, y) within image buffer  //-V108
14255 
14256         color->rgbRed   = (BYTE) ROUND (color->rgbRed   * color->rgbReserved / 255.0);
14257         color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0);
14258         color->rgbBlue  = (BYTE) ROUND (color->rgbBlue  * color->rgbReserved / 255.0);
14259         }
14260 
14261 $   if (!isDIB)
14262         {
14263 $       Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted;
14264 
14265 $       delete[] buf;
14266         }
14267 
14268 $   return image;
14269     }
14270 
14271 //-----------------------------------------------------------------------------------------------------------------
14272 
14273 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/)
14274     {
14275 $1  if (_TX_ARGUMENT_FAILED    (filename)) return false;
14276 $   if (_TX_DEFAULT_HDC_FAILED (dc))       return false;
14277 
14278 $   POINT size = txGetExtent (dc);
14279 
14280 $   size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER),  //-V119
14281            szImg  = (size.x * size.y) * sizeof (RGBQUAD);                   //-V104
14282 
14283 $   BITMAP           bmap = {};
14284 $   BITMAPFILEHEADER hdr  = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs };  //-V202
14285 $   BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB };
14286 
14287 $   RGBQUAD* buf = NULL;
14288 $   bool     ok  = true;
14289 
14290 $   ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap);
14291 
14292     if (!ok) {$ return false; }
14293 
14294 $   if (!bmap.bmBits)
14295         {
14296 $       buf =  new (std::nothrow) RGBQUAD [size.x * size.y];                //-V121
14297 $       ok &= (buf != NULL);
14298 
14299 $       int res = Win32::GetDIBits (dc,  (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y,
14300                                     buf, (BITMAPINFO*) &info, DIB_RGB_COLORS);
14301 
14302         if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); }
14303 
14304 $       ok &= !!res;
14305         }
14306     else
14307         {
14308 $       buf = (RGBQUAD*) bmap.bmBits;
14309         }
14310 
14311 $   FILE* f = NULL;
14312 $   if (ok) fopen_s (&f, filename, "wb");
14313 $   ok &= (f != NULL);
14314 
14315 $   if (ok) ok &= (fwrite (&hdr,  sizeof (hdr),  1, f) == 1);               //-V575 //-V595
14316 $   if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1);
14317 $   if (ok) ok &= (fwrite (buf,   szImg,         1, f) == 1);               //-V575
14318 
14319 $   ok &= (f && fclose (f) == 0);
14320 
14321 $   if (!bmap.bmBits)
14322         {
14323 $       delete[] buf;
14324 $       buf = NULL;
14325         }
14326 
14327 $   return ok;
14328     }
14329 
14330 //-----------------------------------------------------------------------------------------------------------------
14331 
14332 double txSleep (double time)
14333     {
14334 $1  LARGE_INTEGER start = {};
14335     QueryPerformanceCounter (&start) asserted;
14336 
14337     LARGE_INTEGER freq = {};
14338     QueryPerformanceFrequency (&freq) asserted;
14339 
14340     int lock = _txCanvas_RefreshLock;
14341     _txCanvas_RefreshLock = 0;
14342 
14343     HWND wnd = txWindow();
14344     if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); }
14345 
14346     Sleep (ROUND ((time >= 0)? time : 0));
14347 
14348     _txCanvas_RefreshLock = lock;
14349 
14350     LARGE_INTEGER stop = {};
14351     QueryPerformanceCounter (&stop) asserted;
14352 
14353     return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart;
14354     }
14355 
14356 //-----------------------------------------------------------------------------------------------------------------
14357 
14358 bool txLock (bool wait /*= true*/)
14359     {
14360 $0  if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14361 
14362 $   if (wait) {$ return      EnterCriticalSection (&_txCanvas_LockBackBuf), true; }  //-V1048
14363     else      {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf);       }
14364     }
14365 
14366 //-----------------------------------------------------------------------------------------------------------------
14367 
14368 bool txUnlock()
14369     {
14370 $0  LeaveCriticalSection (&_txCanvas_LockBackBuf);
14371 
14372 $   if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0);
14373 $   return false;
14374     }
14375 
14376 #endif // TX_COMPILED
14377 
14378 //-----------------------------------------------------------------------------------------------------------------
14379 
14380 template <typename T>
14381 inline T txUnlock (T value)
14382     {
14383 $1  txUnlock();
14384 $   return value;
14385     }
14386 
14387 //-----------------------------------------------------------------------------------------------------------------
14388 
14389 inline void txRedrawWindow()
14390     {
14391 $1  txSleep (0);
14392     }
14393 
14394 //-----------------------------------------------------------------------------------------------------------------
14395 
14396 inline int txUpdateWindow (int update /*= true*/)
14397     {
14398 $1  return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update);
14399     }
14400 
14401 //-----------------------------------------------------------------------------------------------------------------
14402 
14403 inline int txBegin()
14404     {
14405 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1);
14406 
14407 $   return _txCanvas_RefreshLock;
14408     }
14409 
14410 //-----------------------------------------------------------------------------------------------------------------
14411 
14412 inline int txEnd()
14413     {
14414 $1  _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1);
14415 
14416 $   return _txCanvas_RefreshLock;
14417     }
14418 
14419 //-----------------------------------------------------------------------------------------------------------------
14420 
14421 inline POINT txMousePos()
14422     {
14423 $1  POINT pos = {};
14424 $   GetCursorPos (&pos);
14425 
14426 $   if (txWindow())
14427         {$ ScreenToClient (txWindow(), &pos); }
14428 
14429 $   return pos;
14430     }
14431 
14432 //-----------------------------------------------------------------------------------------------------------------
14433 
14434 inline double txMouseX()
14435     {
14436     return (double) txMousePos() .x;
14437     }
14438 
14439 //-----------------------------------------------------------------------------------------------------------------
14440 
14441 inline double txMouseY()
14442     {
14443     return (double) txMousePos() .y;
14444     }
14445 
14446 //-----------------------------------------------------------------------------------------------------------------
14447 
14448 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
14449 
14450 unsigned txMouseButtons()
14451     {
14452 $1  HWND txWnd      = txWindow();
14453 $   HWND foreground = GetForegroundWindow();
14454 
14455 $   if ((txWnd && (foreground == txWnd)) ||
14456        (!txWnd && (foreground == Win32::GetConsoleWindow())))
14457         {
14458 $       return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) |  // MSB to bit 0
14459                ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) |  // MSB to bit 1
14460                ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13);   // MSB to bit 2
14461         }
14462     else
14463         {$ return 0; }
14464     }
14465 
14466 //-----------------------------------------------------------------------------------------------------------------
14467 
14468 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/)
14469     {
14470     unsigned oldAttr = txGetConsoleAttr();
14471 
14472     SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color);
14473     SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE),  (WORD) color);
14474 
14475     return oldAttr;
14476     }
14477 
14478 //-----------------------------------------------------------------------------------------------------------------
14479 
14480 unsigned txGetConsoleAttr()
14481     {
14482     CONSOLE_SCREEN_BUFFER_INFO con = {};
14483     con.wAttributes = FOREGROUND_LIGHTGRAY;
14484 
14485     GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) ||
14486     GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE),  &con);
14487 
14488     return con.wAttributes;
14489     }
14490 
14491 //-----------------------------------------------------------------------------------------------------------------
14492 
14493 POINT txSetConsoleCursorPos (double x, double y)
14494     {
14495 $1  POINT fontSz = txGetConsoleFontSize();
14496 
14497 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14498 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14499 
14500 $   COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left),
14501                   (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) };
14502 
14503 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted;
14504 
14505 $   POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14506                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14507 $   return prev;
14508     }
14509 
14510 //-----------------------------------------------------------------------------------------------------------------
14511 
14512 POINT txGetConsoleCursorPos()
14513     {
14514 $1  POINT fontSz = txGetConsoleFontSize();
14515 
14516 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14517 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14518 
14519 $   POINT  pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x),
14520                    ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) };
14521 $   return pos;
14522     }
14523 
14524 //-----------------------------------------------------------------------------------------------------------------
14525 
14526 POINT txGetConsoleExtent()
14527     {
14528 $1  CONSOLE_SCREEN_BUFFER_INFO con = {};
14529 $   GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted;
14530 
14531 $   POINT  size = { con.srWindow.Right  - con.srWindow.Left + 1,
14532                     con.srWindow.Bottom - con.srWindow.Top  + 1 };
14533 $   return size;
14534     }
14535 
14536 //-----------------------------------------------------------------------------------------------------------------
14537 
14538 bool txClearConsole()
14539     {
14540 $1  HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
14541 
14542 $   CONSOLE_SCREEN_BUFFER_INFO con = {};
14543 $   GetConsoleScreenBufferInfo (out, &con) asserted;
14544 
14545 $   COORD start = {con.srWindow.Left, con.srWindow.Top};
14546 
14547 $   DWORD len   = (con.srWindow.Right  - con.srWindow.Left + 1) *
14548                   (con.srWindow.Bottom - con.srWindow.Top  + 1);
14549 
14550 $   DWORD written = 0;
14551 $   FillConsoleOutputCharacter (out, 0x20 /*' '*/,    len, start, &written) asserted;  //-V112
14552 $   FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted;
14553 
14554 $   SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted;
14555 
14556 $   return written == len;
14557     }
14558 
14559 //-----------------------------------------------------------------------------------------------------------------
14560 
14561 POINT txGetConsoleFontSize()
14562     {
14563 $1  Win32::CONSOLE_FONT_INFO font = {0, {8, 16}};
14564 
14565 $   _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font));
14566 
14567 $   SIZE size = { font.dwFontSize.X, font.dwFontSize.Y };
14568     if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); }  //-V501
14569 
14570     if (size.cx == 0) {$ size.cx = 1; }
14571     if (size.cy == 0) {$ size.cy = 1; }
14572 
14573 $   POINT sizeFont = { size.cx, size.cy };
14574 $   return sizeFont;
14575     }
14576 
14577 //-----------------------------------------------------------------------------------------------------------------
14578 
14579 bool txTextCursor (bool blink /*= true*/)
14580     {
14581 $1  bool old = _txConsole_IsBlinking;
14582 
14583 $   _txConsole_IsBlinking = blink;
14584 
14585 $   return old;
14586     }
14587 
14588 //-----------------------------------------------------------------------------------------------------------------
14589 
14590 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/)
14591     {
14592 $1  mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT;
14593 $   if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC;
14594 
14595 $   if (!filename) mode = SND_PURGE;
14596 
14597 $   return !!Win32::PlaySound (filename, NULL, mode);
14598     }
14599 
14600 //-----------------------------------------------------------------------------------------------------------------
14601 
14602 int txSpeak (const char* text, ...)
14603     {
14604 $1  bool verbose = false; (void) verbose;
14605 $   bool async   = false; (void) async;
14606 
14607 $   for (; text && *text; text++)
14608         {
14609         if      (*text == '\a') {$ async   = true; }
14610         else if (*text == '\v') {$ verbose = true; }
14611         else break;
14612         }
14613 
14614 $   char textA [_TX_BUFSIZE] = "<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='EN'>"
14615                                "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!"
14616                                "</speak>";
14617 
14618 $   va_list arg; va_start (arg, text);
14619     if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); }
14620 $   va_end (arg);
14621 
14622     if (text && verbose) {$ printf ("%s", textA); }
14623 
14624 #ifdef TX_USE_SPEAK
14625 
14626 $   int time = GetTickCount();
14627 
14628 $   static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L"";
14629 $   MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW));
14630 
14631 $   static ISpVoice* voice = NULL;  // This is bad rough approach. Due to this static, txSpeak() calls are restricted to one .cpp-file.
14632 
14633 $   if (text && !voice)
14634         {
14635 $       HRESULT res = Win32::CoInitialize (NULL);
14636         if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); }
14637         }
14638 
14639 $   if (text && voice)
14640         {
14641 $       Win32::_fpreset();
14642 $       voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL);
14643 $       tx_fpreset();
14644         }
14645 
14646 $   if (!text && voice)
14647         {
14648 $       voice->Release();
14649 $       voice = NULL;
14650 
14651 $       Win32::CoUninitialize();
14652         }
14653 
14654 $   return (voice)? GetTickCount() - time : -1;
14655 
14656 #else
14657 
14658 $   if (text)
14659         {
14660 $       unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK);
14661 
14662 $       txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA);
14663 
14664 $       txSetConsoleAttr (oldAttr);
14665         }
14666 
14667 $   return -1;
14668 
14669 #endif
14670     }
14671 
14672 //-----------------------------------------------------------------------------------------------------------------
14673 
14674 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[],
14675                       double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/)
14676     {
14677 $1  if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1;
14678 
14679 $   int time = GetTickCount();  //-V2551
14680 
14681 $   static char processUID [64] = "";
14682     if (!*processUID)
14683         {
14684 $       FILETIME startTime = {}, null = {};
14685 $       GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted;
14686 $       _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo",
14687                     (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted;
14688         }
14689 
14690 $   if (!fileName)
14691         {
14692 $       _txTaskKill ("vlc.exe", processUID, 0);  // Kill'em all, by command line pattern
14693 $       return 0;
14694         }
14695 
14696 $   static const char* vlcPath = _txPlayVideo_FindVLC();
14697 
14698 $   if (!vlcPath || _access (vlcPath, 0) != 0)
14699         {
14700 $       static int once = false;  //-V601
14701 
14702 $       if (*fileName && !once++)
14703             {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org "
14704                                     "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n"
14705                                     "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n"
14706                                     "P.S. См. мое описание в TXLib Help."); }
14707 $       return INT_MIN;  //-V109
14708         }
14709 
14710 $   bool async = false;
14711     if (*fileName == '\a') {$ async = true; fileName++; }
14712 
14713 $   RECT rect = {};
14714     if (wnd) {$ GetClientRect (wnd, &rect); }
14715 
14716     if (!width)  {$ width  = rect.right;  }
14717     if (!height) {$ height = rect.bottom; }
14718 
14719     // Create a child window to hold the video stream
14720 
14721 $   const char* errPos = "ВНЕЗАПНО";
14722 
14723 $   volatile HWND child = NULL;
14724 $   if (wnd && (wnd == txWindow()))
14725         {
14726 $       const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1);
14727 
14728 $       static int number = 1;
14729 $       CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x,
14730                                     WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass };
14731 $       child = txCreateExtraWindow (createData);
14732 $       if (!child)
14733             {
14734 $           txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14735                                        strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos));
14736 $           return INT_MIN+3;  //-V109
14737             }
14738 
14739 $       BringWindowToTop (child);
14740 
14741 $       wnd = child;
14742         }
14743 
14744     // Build the command line
14745 
14746     if (!zoom && !wnd) {$ zoom = 1; }
14747 
14748 $   char sZoom [64] = "--autoscale";
14749     if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; }  //-V550
14750 
14751 $   static char cmd [MAX_PATH*2 + 1024] = "";
14752 
14753 $   _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit"
14754 
14755                  " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s"
14756 
14757                  " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging"
14758 
14759                  " --ignore-config --reset-config --no-one-instance --play-and-exit"
14760                  " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file"
14761                  " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events",
14762 
14763                  vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted;
14764 
14765 $   txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n",
14766                          x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd);
14767 $   if (!*fileName)
14768         {
14769         if (child) {$ txDestroyWindow (child); }
14770 $       return (intptr_t) cmd;
14771         }
14772 
14773 $   if (!strstr (fileName, "://") && _access (fileName, 0) != 0)
14774         {
14775 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s",
14776                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos));
14777 
14778         if (child) {$ txDestroyWindow (child); }
14779 $       return INT_MIN+1;  //-V109
14780         }
14781 
14782     // Run VLC, run
14783 
14784 $   PROCESS_INFORMATION vlc   = {};
14785 $   STARTUPINFO         start = { sizeof (start) };
14786 $   DWORD               ret   = 0;
14787 
14788 $   if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) &&
14789         vlc.hProcess && vlc.hThread)
14790         {
14791 $       if (child)
14792             {
14793 $           assert (wnd == child);                                           //-V547
14794 $           SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess);  //-V107
14795             }
14796 
14797 $       if (!async)
14798             {
14799 $           WaitForSingleObject (vlc.hProcess, INFINITE);
14800 $           GetExitCodeProcess  (vlc.hProcess, &ret) asserted;
14801             }
14802 
14803 $       if (!child)
14804             {
14805 $           CloseHandle (vlc.hProcess) asserted;
14806             }
14807 
14808 $       CloseHandle (vlc.hThread) asserted;
14809 
14810 $       return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret);  //-V105
14811         }
14812     else
14813         {
14814 $       txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s",
14815                                    strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos));
14816 $       if (child)
14817             {$ txDestroyWindow (child); }
14818 
14819 $       return INT_MIN+4;  //-V112 //-V109
14820         }
14821 
14822     #undef PROCESS_UID_
14823     }
14824 
14825 //-----------------------------------------------------------------------------------------------------------------
14826 
14827 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/)
14828     {
14829 $1  return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd);
14830     }
14831 
14832 //-----------------------------------------------------------------------------------------------------------------
14833 
14834 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
14835     {
14836     const UINT_PTR checkTimer = 1;
14837 
14838     switch (msg)
14839         {
14840         case WM_CREATE:
14841             {
14842 $1          SetTimer  (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted;
14843             }
14844             break;
14845 
14846         case WM_DESTROY:
14847             {
14848 $1          KillTimer (wnd, checkTimer) asserted;
14849 
14850 $           HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14851 
14852 $           if (vlc)
14853                 {
14854 $               Win32::TerminateProcess (vlc, 0);
14855 
14856 $               CloseHandle (vlc) asserted;
14857 
14858 $               SetWindowLongPtr (wnd, GWLP_USERDATA, 0);
14859                 }
14860             }
14861             break;
14862 
14863         case WM_TIMER:
14864             {
14865             HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA);
14866 
14867             if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT)
14868                 {
14869 $1              DestroyWindow (wnd) asserted;
14870                 }
14871             }
14872             break;
14873 
14874         default:  //-V2522
14875             break;
14876         }
14877 
14878     return DefWindowProc (wnd, msg, wpar, lpar);
14879     }
14880 
14881 //-----------------------------------------------------------------------------------------------------------------
14882 
14883 const char* _txPlayVideo_FindVLC()
14884     {
14885 $1  static char vlcPath [MAX_PATH] = "";
14886 
14887 $   if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL))
14888         {
14889         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14890         }
14891 
14892 $   if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL))
14893         {
14894         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14895         }
14896 
14897 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath)))
14898         {
14899         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14900         }
14901 
14902 $   if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath)))
14903         {
14904 $       strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX);
14905 
14906         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14907         }
14908 
14909 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files"    "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14910         {
14911         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14912         }
14913 
14914 $   strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX);  //-V106
14915         {
14916         if (_access (vlcPath, 0) == 0) {$ return vlcPath; }
14917         }
14918 
14919 $   return NULL;
14920     }
14921 
14922 //-----------------------------------------------------------------------------------------------------------------
14923 
14924 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/)
14925     {
14926 $1  static double oldPercent = 100;
14927 
14928     if (percent < 0) {$ percent    = MIN (oldPercent, 100); }
14929     else             {$ oldPercent = percent;               }
14930 
14931 $   HRESULT res = S_FALSE;
14932 
14933     #if defined (__ITaskbarList3_INTERFACE_DEFINED__)
14934 
14935 $   HRESULT init = Win32::CoInitialize (NULL);
14936 
14937 $   bool ok = true;
14938 $   res = S_OK;
14939 
14940 $   ITaskbarList3* taskbar = NULL;
14941     if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); }
14942 $   ok &= !!taskbar && (res == S_OK);
14943 
14944     if (!wnd)              {$ wnd = txWindow(); }
14945     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14946     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14947 
14948     if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); }
14949     if (ok && taskbar)     {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); }
14950     if (ok && taskbar)     {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type);       ok &= (res == S_OK); }
14951 
14952     if (taskbar) {$ taskbar->Release(); }
14953 
14954     if (init == S_OK) {$ Win32::CoUninitialize(); }
14955 
14956     #endif
14957 
14958     (void) type; (void) wnd;
14959 
14960 $   return res;
14961     }
14962 
14963 #endif // TX_COMPILED
14964 
14965 //-----------------------------------------------------------------------------------------------------------------
14966 
14967 // +--<<< Это не те символы, что вы ищете :)
14968 // V      Полезно смотреть не только вверх, но и вниз
14969 
14970 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/)
14971     {
14972 $1  WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc;
14973 $   return  old;
14974     }
14975 
14976 //-----------------------------------------------------------------------------------------------------------------
14977 
14978 //     +--<<< А это, наконец, искомое определение этой функции.
14979 //     |      Смотрите по сторонам! Нужная вам функция где-то рядом.
14980 //     |
14981 //     v
14982 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()
14983     {
14984     txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n"
14985 
14986                   "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n"
14987 
14988                   "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. "
14989                   "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n"
14990 
14991                   "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом "
14992                   "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n"
14993 
14994                   "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы "
14995                   "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n",
14996 
14997                   "Не получилось", MB_ICONSTOP);
14998 
14999     // The truth is out there... (C++files)
15000 
15001     return false;
15002     }
15003 
15004 //-----------------------------------------------------------------------------------------------------------------
15005 
15006 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you.
15007 
15008 inline bool txDisableAutoPause()
15009     {
15010     _txExit = true;
15011     return true;
15012     }
15013 
15014 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword.
15015 
15016 //-----------------------------------------------------------------------------------------------------------------
15017 
15018 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
15019 
15020 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/)
15021     {
15022 $1  assert (!_txIsBadReadPtr (address));
15023 
15024 $   const unsigned char* addr = (const unsigned char*) address;
15025 
15026 $   const int stdout_fileno = 1;           // Not all g++ packages contain STDOUT_FILENO
15027 $   const int _o_u16text    = 0x00020000;  // and _O_U16TEXT
15028 
15029 $   bool     istty   = _txIsTTY (1);
15030 
15031 $   int      mode    = _O_TEXT;
15032 $   int      oldMode = _setmode (stdout_fileno, mode);
15033 
15034 $   unsigned oldCP   =       GetConsoleOutputCP();
15035 $   unsigned cp      = 1251; SetConsoleOutputCP (cp);  //-V581
15036 
15037 $   unsigned attr    = txGetConsoleAttr();
15038 
15039 $   txSetConsoleAttr (FOREGROUND_WHITE);
15040 $   printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : ""));
15041 
15042 $   txSetConsoleAttr (FOREGROUND_YELLOW);
15043 $   for (unsigned x = 0; x < 16; x++) printf ("%02X ", x);
15044 $   for (unsigned x = 0; x < 16; x++) printf ("%X",    x);
15045 
15046 $   const wchar_t* xlat[33] = {L"\xB7"   /* 00 - NUL - NULL             */, L"\x263A" /* 01 - SOH - Start of header      */,
15047                                L"\x263B" /* 02 - STX - Start of text    */, L"\x2665" /* 03 - ETX - End of text          */,
15048                                L"\x2666" /* 04 - EOT - End of transm.   */, L"\x2663" /* 05 - ENQ - Enquiry              */,
15049                                L"\x2660" /* 06 - ACK - Acknowledgment   */, L"\x2022" /* 07 - BEL - Bell                 */,
15050                                L"\x25D8" /* 08 - BS  - Backspace        */, L"\x25CB" /* 09 - HT  - Horizontal tab       */,
15051                                L"\x25D9" /* 10 - LF  - Line feed        */, L"\x2642" /* 11 - VT  - Vertical tab         */,
15052                                L"\x2640" /* 12 - FF  - Form feed        */, L"\x266A" /* 13 - CR  - Carriage return      */,
15053                                L"\x266B" /* 14 - SO  - Shift out        */, L"\x263C" /* 15 - SI  - Shift in             */,
15054                                L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1     */,
15055                                L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3     */,
15056                                L"\xB6"   /* 20 - DC4 - Device control 4 */, L"\xA7"   /* 21 - NAK - Negative ACK         */,
15057                                L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */,
15058                                L"\x2191" /* 24 - CAN - Cancel           */, L"\x2193" /* 25 - EM  - End of medium        */,
15059                                L"\x2192" /* 26 - SUB - Substitute       */, L"\x2190" /* 27 - ESC - Escape               */,
15060                                L"\x221F" /* 28 - FS  - File separator   */, L"\x2194" /* 29 - GS  - Group separator      */,
15061                                L"\x25B2" /* 30 - RS  - Record separator */, L"\x25BC" /* 31 - US  - Unit separator       */,
15062                                L"\x20"   /* 32 - Space */};
15063 
15064 $   for (int y = 0; y < 16; y++, addr += 16)
15065         {
15066         if (cp   != 1251) SetConsoleOutputCP (cp = 1251);  //-V581
15067         (void)_setmode (stdout_fileno, mode = oldMode);
15068 
15069         txSetConsoleAttr (FOREGROUND_YELLOW);
15070 
15071         printf ("\n" "%*p ", (int) sizeof (address) * 2, addr);
15072 
15073         int color = FOREGROUND_LIGHTGREEN;
15074 
15075         for (unsigned x = 0; x < 16; x++)
15076             {
15077             txSetConsoleAttr (color + x/4%2);  //-V112
15078             printf ("%02X ", addr[x]);
15079             }
15080 
15081         for (unsigned x = 0; x < 16; x++)
15082             {
15083             txSetConsoleAttr (color + x/4%2);  //-V112
15084 
15085             unsigned char ch = addr[x];
15086 
15087             if (ch >= sizearr (xlat) || !istty)
15088                 {
15089                 if (cp   != oldCP)      SetConsoleOutputCP (cp = oldCP);  //-V581
15090                 if (mode != oldMode)    (void)_setmode (stdout_fileno, mode = oldMode);
15091 
15092                 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' ');
15093                 }
15094             else
15095                 {
15096                 if (cp   != 1251)       SetConsoleOutputCP (cp = 1251);   //-V581
15097                 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text);
15098 
15099                 wprintf (L"%lls", xlat[ch]);
15100                 }
15101             }
15102         }
15103 
15104 $   (void)_setmode (stdout_fileno, oldMode);
15105 $   printf ("\n");
15106 
15107 $   if (pause && istty)
15108         {
15109 $       txSetConsoleAttr (FOREGROUND_DARKGRAY);
15110 $       txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP);
15111         }
15112 
15113 $   txSetConsoleAttr (FOREGROUND_LIGHTGRAY);
15114 $   printf ("\n");
15115 
15116 $   txSetConsoleAttr (attr);
15117 $   SetConsoleOutputCP (oldCP);
15118     }
15119 
15120 //-----------------------------------------------------------------------------------------------------------------
15121 
15122 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/,
15123                         bool readSource /*= true*/)
15124     {
15125 $1  unsigned attr = txGetConsoleAttr();
15126 $   txSetConsoleAttr (FOREGROUND_LIGHTCYAN);
15127 
15128 $   fprintf (stderr, "\n" "--------------------------------------------------\n"
15129                           "Трассировка стека из \"%s\" at %s:%d:\n\n"
15130                           "%s\n\n"
15131                           "--------------------------------------------------\n\n",
15132                           func, file, line, _txCaptureStackBackTrace (1, readSource));
15133 
15134 $   txSetConsoleAttr (attr);
15135     }
15136 
15137 //-----------------------------------------------------------------------------------------------------------------
15138 
15139 char* txDemangle (const char* mangledName, std::nomeow_t)
15140     {
15141 $1  if (!mangledName) return NULL;
15142 
15143 $   char* typeName = NULL;
15144 
15145     #if defined (_GCC_VER)
15146 
15147 $   int err = 1;
15148 $   typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err;
15149     if (typeName) {$ return typeName; }
15150 
15151     #endif
15152 
15153 $   unsigned short flags = 0;
15154 
15155 $   if (mangledName[0] == '.')
15156         {
15157 $       mangledName++;
15158 $       flags = 0x2800;  // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY
15159         }
15160 
15161 $   typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags));
15162     if (typeName) {$ return typeName; }
15163 
15164 $   return _strdup (mangledName);
15165     }
15166 
15167 //-----------------------------------------------------------------------------------------------------------------
15168 
15169 std::string txDemangle (const char* mangledName)
15170     {
15171 $1  char* typeName = txDemangle (mangledName, std::nomeow);
15172 $   std::string name (typeName? typeName : "");
15173 $   free (typeName);
15174 
15175 $   return name;
15176     }
15177 
15178 //-----------------------------------------------------------------------------------------------------------------
15179 
15180 double txQueryPerformance()
15181     {
15182 $1  int maxTime    =  500;
15183 $   int maxSamples =  100;
15184 $   POINT size     = {100, 100};
15185 
15186 $   HDC dc = _txBuffer_Create (txWindow(), &size, NULL);
15187 $   assert (dc); if (!dc) return -1;                                     //-V547
15188 
15189 $   DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1);  //-V202
15190 $   assert (mask);
15191 
15192 $   LARGE_INTEGER freq = {};
15193 $   QueryPerformanceFrequency (&freq) asserted;
15194 
15195 $   LARGE_INTEGER start = {};
15196 $   QueryPerformanceCounter (&start) asserted;
15197 
15198 $   int samples = 0;
15199 $   while (samples++ < maxSamples)
15200         {
15201 $       LARGE_INTEGER cur = {};
15202 $       QueryPerformanceCounter (&cur) asserted;
15203 
15204 $       double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart;
15205 $       if (t > maxTime) break;
15206 
15207         // Draw test scene
15208 
15209 $       for (int y = 0; y < size.y; y++)
15210         for (int x = 0; x < size.x; x++)     txSetPixel (x, y, TX_BLACK, dc);
15211 
15212 $       for (int y = 0; y < size.y; y += 10)
15213         for (int x = 0; x < size.x; x += 50) txTextOut  (x, y, "*", dc);
15214 
15215 $       txEllipse (0, 0, size.x, size.y, dc);
15216 $       txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc);
15217 
15218 $       txBitBlt (dc, size.x/2.0,          0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
15219 $       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;
15220 $       txBitBlt (dc,          0, size.y/2.0, size.x/2.0, size.y/2.0, dc,          0,          0) asserted;
15221 $       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;
15222         }
15223 
15224 $   mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask);  //-V106 //-V202
15225 $   assert (mask);
15226 
15227 $   _txBuffer_Delete (&dc);
15228 
15229 $   return 3.0 * samples / sqrt (1.0 * size.x * size.y);
15230     }
15231 
15232 //-----------------------------------------------------------------------------------------------------------------
15233 
15234 unsigned txExtractColor (COLORREF color, COLORREF component)
15235     {
15236 $1  switch (component)
15237         {
15238         case TX_RED:
15239         case TX_HUE:
15240         case TX_LAB_L:      $ return (color >>  0) & 0xFF;
15241 
15242         case TX_GREEN:
15243         case TX_SATURATION:
15244         case TX_LAB_A:      $ return (color >>  8) & 0xFF;
15245 
15246         case TX_BLUE:
15247         case TX_LIGHTNESS:
15248         case TX_LAB_B:      $ return (color >> 16) & 0xFF;
15249 
15250         default:            $ return CLR_INVALID;
15251         }
15252     }
15253 
15254 //-----------------------------------------------------------------------------------------------------------------
15255 
15256 template <typename T, typename T2, typename T3>
15257 inline T _txClamp (T val, T2 min, T3 max)
15258     {
15259     return (val < min)? min : (val > max)? max : val;
15260     }
15261 
15262 inline COLORREF _txRGB (double r, double g, double b)
15263     {
15264     return RGB (_txClamp (ROUND (r), 0, 255),
15265                 _txClamp (ROUND (g), 0, 255),
15266                 _txClamp (ROUND (b), 0, 255));
15267     }
15268 
15269 //-----------------------------------------------------------------------------------------------------------------
15270 
15271 COLORREF txRGB2HSL (COLORREF rgbColor)
15272     {
15273 $1  struct xRGB
15274         {
15275         static bool zero (double val)
15276             {
15277             const double prec = 0.001;
15278 
15279             return (fabs (val) < prec);
15280             }
15281         };
15282 
15283 $   double r  = txExtractColor (rgbColor, TX_RED)   / 255.0,  //-V2551
15284            g  = txExtractColor (rgbColor, TX_GREEN) / 255.0,  //-V2551
15285            b  = txExtractColor (rgbColor, TX_BLUE)  / 255.0,  //-V2551
15286 
15287            m1 = MAX (MAX (r, g), b),
15288            m2 = MIN (MIN (r, g), b),
15289            dm = m1 - m2,
15290            sm = m1 + m2,
15291 
15292            h  = 0,
15293            s  = 0,
15294            l  = sm / 2;
15295 
15296 $   if (!xRGB::zero (dm))
15297         {
15298 $       sm = (sm <= 1)? sm : (2-sm);
15299 $       s = (!xRGB::zero (sm))? dm/sm : 0;
15300 
15301 $       double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0,
15302                cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0,
15303                cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0;
15304 
15305 $       if (xRGB::zero (r - m1)) h =     cb - cg;
15306 $       if (xRGB::zero (g - m1)) h = 2 + cr - cb;
15307 $       if (xRGB::zero (b - m1)) h = 4 + cg - cr;
15308         }
15309 
15310 $   h = (h >= 0)? h*60 : h*60 + 360;
15311 
15312 $   return _txRGB (h / 360.0 * 256, s * 255, l * 255);
15313     }
15314 
15315 //-----------------------------------------------------------------------------------------------------------------
15316 
15317 COLORREF txHSL2RGB (COLORREF hslColor)
15318     {
15319 $1  struct xRGB
15320         {
15321         static double calc (double h, double m1, double m2)
15322             {
15323 $2          while (h < 0)   h += 360;
15324 $           while (h > 360) h -= 360;
15325 
15326 $           return (h <  60)? m1 + (m2-m1) *      h  / 60 :
15327                    (h < 180)? m2 :
15328                    (h < 240)? m1 + (m2-m1) * (240-h) / 60 :
15329                               m1;
15330             }
15331         };
15332 
15333 $   int    si = txExtractColor (hslColor, TX_SATURATION);
15334 
15335 $   double h  = txExtractColor (hslColor, TX_HUE)        / 256.0 * 360,
15336            s  = txExtractColor (hslColor, TX_SATURATION) / 255.0,
15337            l  = txExtractColor (hslColor, TX_LIGHTNESS)  / 255.0,
15338 
15339            m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s,
15340            m1 = 2 * l - m2,
15341 
15342            r = (si)? xRGB::calc (h + 120, m1, m2) : l,
15343            g = (si)? xRGB::calc (h,       m1, m2) : l,
15344            b = (si)? xRGB::calc (h - 120, m1, m2) : l;
15345 
15346 $   return _txRGB (r * 255, g * 255, b * 255);
15347     }
15348 
15349 //-----------------------------------------------------------------------------------------------------------------
15350 
15351 COLORREF txRGB2Lab (COLORREF rgbColor)
15352     {
15353     // Convert sRGB to XYZ referring to a D65/2 standard illuminant. See https://www.easyrgb.com/en/math.php
15354 
15355 $1  double r = txExtractColor (rgbColor, TX_RED)   / 255.0,
15356            g = txExtractColor (rgbColor, TX_GREEN) / 255.0,
15357            b = txExtractColor (rgbColor, TX_BLUE)  / 255.0;
15358 
15359 $   r = ((r > 0.04045)? pow ((r + 0.055) / 1.055, 2.4) : r / 12.92) * 100;
15360 $   g = ((g > 0.04045)? pow ((g + 0.055) / 1.055, 2.4) : g / 12.92) * 100;
15361 $   b = ((b > 0.04045)? pow ((b + 0.055) / 1.055, 2.4) : b / 12.92) * 100;
15362 
15363 $   double x = r * 0.4124 + g * 0.3576 + b * 0.1805,
15364            y = r * 0.2126 + g * 0.7152 + b * 0.0722,
15365            z = r * 0.0193 + g * 0.1192 + b * 0.9505;
15366 
15367     // Convert XYZ to Lab referring to a D65/2 standard illuminant. See https://www.easyrgb.com/en/math.php
15368 
15369 $   x /=  95.047;
15370 $   y /= 100.000;
15371 $   z /= 108.883;
15372 
15373 $   x = (x > 0.008856)? pow (x, 1.0/3.0) : 7.787 * x + 16.0/116.0;
15374 $   y = (y > 0.008856)? pow (y, 1.0/3.0) : 7.787 * y + 16.0/116.0;
15375 $   z = (z > 0.008856)? pow (z, 1.0/3.0) : 7.787 * z + 16.0/116.0;
15376 
15377 $   double L = (116.0 * y) - 16.0,
15378            a =  500.0 * (x - y);
15379            b =  200.0 * (y - z);
15380 
15381     // Storing Lab in range [0..255]: L = L * 2.55; a,b = (a,b + 100) * 1.275
15382 
15383 $   return _txRGB (L          / 100.0 * 255,
15384                   (a + 100.0) / 200.0 * 255,
15385                   (b + 100.0) / 200.0 * 255);
15386     }
15387 
15388 //-----------------------------------------------------------------------------------------------------------------
15389 
15390 COLORREF txLab2RGB (COLORREF labColor)
15391     {
15392     // Convert Lab to XYZ referring to a D65/2 standard illuminant. See https://www.easyrgb.com/en/math.php
15393 
15394 $1  double L = txExtractColor (labColor, TX_LAB_L) / 255.0 * 100,
15395            a = txExtractColor (labColor, TX_LAB_A) / 255.0 * 200 - 100.0,
15396            b = txExtractColor (labColor, TX_LAB_B) / 255.0 * 200 - 100.0;
15397 
15398 $   double y =  (L + 16.0) / 116.0,
15399            x =  y + a / 500.0,
15400            z =  y - b / 200.0;
15401 
15402 $   x = (x > pow (0.008856, 3))? x*x*x : (x - 16.0/116.0) / 7.787;
15403 $   y = (y > pow (0.008856, 3))? y*y*y : (y - 16.0/116.0) / 7.787;
15404 $   z = (z > pow (0.008856, 3))? z*z*z : (z - 16.0/116.0) / 7.787;
15405 
15406 $   x *=  95.047;
15407 $   y *= 100.000;
15408 $   z *= 108.883;
15409 
15410     // Convert XYZ to sRGB referring to a D65/2 standard illuminant. See https://www.easyrgb.com/en/math.php
15411 
15412 $   x /= 100;
15413 $   y /= 100;
15414 $   z /= 100;
15415 
15416 $   double r = x *  3.2406 + y * -1.5372 + z * -0.4986,
15417            g = x * -0.9689 + y *  1.8758 + z *  0.0415;
15418 $          b = x *  0.0557 + y * -0.2040 + z *  1.0570;
15419 
15420 $   r = (r > 0.0031308)? 1.055 * pow (r, 1.0/2.4) - 0.055 : 12.92 * r;
15421 $   g = (g > 0.0031308)? 1.055 * pow (g, 1.0/2.4) - 0.055 : 12.92 * g;
15422 $   b = (b > 0.0031308)? 1.055 * pow (b, 1.0/2.4) - 0.055 : 12.92 * b;
15423 
15424 $   return _txRGB (r * 255, g * 255, b * 255);
15425     }
15426 
15427 //-----------------------------------------------------------------------------------------------------------------
15428 
15429 double txDeltaE (COLORREF rgbColor1, COLORREF rgbColor2)
15430     {
15431     // deltaE CIE76. See https://www.easyrgb.com/en/math.php
15432 
15433 $1  COLORREF Lab1 = txRGB2Lab (rgbColor1),
15434              Lab2 = txRGB2Lab (rgbColor2);
15435 
15436 $   double   L1   = txExtractColor (Lab1, TX_LAB_L) / 255.0 * 100,
15437              a1   = txExtractColor (Lab1, TX_LAB_A) / 255.0 * 200 - 100.0,
15438              b1   = txExtractColor (Lab1, TX_LAB_B) / 255.0 * 200 - 100.0;
15439 
15440 $   double   L2   = txExtractColor (Lab2, TX_LAB_L) / 255.0 * 100,
15441              a2   = txExtractColor (Lab2, TX_LAB_A) / 255.0 * 200 - 100.0,
15442              b2   = txExtractColor (Lab2, TX_LAB_B) / 255.0 * 200 - 100.0;
15443 
15444 $   return sqrt ((L2-L1) * (L2-L1) +
15445                  (a2-a1) * (a2-a1) +
15446                  (b2-b1) * (b2-b1));
15447     }
15448 
15449 //-----------------------------------------------------------------------------------------------------------------
15450 
15451 double txDeltaE94 (COLORREF rgbColor1, COLORREF rgbColor2)
15452     {
15453     // deltaE CIE94. See https://www.easyrgb.com/en/math.php
15454 
15455 $1  COLORREF Lab1 = txRGB2Lab (rgbColor1),
15456              Lab2 = txRGB2Lab (rgbColor2);
15457 
15458 $   double   L1   = txExtractColor (Lab1, TX_LAB_L) / 255.0 * 100,
15459              a1   = txExtractColor (Lab1, TX_LAB_A) / 255.0 * 200 - 100.0,
15460              b1   = txExtractColor (Lab1, TX_LAB_B) / 255.0 * 200 - 100.0;
15461 
15462 $   double   L2   = txExtractColor (Lab2, TX_LAB_L) / 255.0 * 100,
15463              a2   = txExtractColor (Lab2, TX_LAB_A) / 255.0 * 200 - 100.0,
15464              b2   = txExtractColor (Lab2, TX_LAB_B) / 255.0 * 200 - 100.0;
15465 
15466 $   double c1 = hypot (a1, b1),
15467            c2 = hypot (a2, b2),
15468 
15469            dL = L2 - L1,
15470            dc = c2 - c1,
15471            dE = sqrt (((L1 - L2) * (L1 - L2)) +
15472                       ((a1 - a2) * (a1 - a2)) +
15473                       ((b1 - b2) * (b1 - b2))),
15474 
15475            dh = dE*dE - dL*dL - dc*dc;
15476 $          dh = (dh > 0)? sqrt (dh) : 0;
15477 
15478            dc /= (1 + (0.045 * c1)),
15479            dh /= (1 + (0.015 * c1));
15480 
15481 $   return sqrt (dL*dL + dc*dc + dh*dh);
15482     }
15483 
15484 //-----------------------------------------------------------------------------------------------------------------
15485 
15486 uint64_t txHash (const void* buffer, size_t size)
15487     {
15488     // DJB2 algorithm, https://en.wikipedia.org/wiki/Daniel_J._Bernstein
15489 
15490 $9  uint64_t hash = 5381;
15491 
15492 $   for (size_t i = 0; i < size; i++)
15493         hash = hash * 33 ^ ((const char*) buffer) [i];
15494 
15495 $   return hash;
15496     }
15497 
15498 //-----------------------------------------------------------------------------------------------------------------
15499 
15500 void tx_fpreset()
15501     {
15502 $1  txAutoLock _lock;
15503 
15504 $   Win32::_fpreset();
15505 
15506 $   unsigned new87 = 0x0008001C;  // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW
15507 
15508     #if !defined (__CYGWIN__)
15509 
15510 $   unsigned old87 = 0;
15511 $   if (_controlfp_s (&old87, 0, 0) == 0)
15512         {$ (void) _controlfp_s (&old87, old87  & ~new87, 0x0008001F); }  // _MCW_EM
15513 
15514     #else
15515 
15516 $   Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F);    // _MCW_EM
15517 
15518     #endif
15519     }
15520 
15521 #endif // TX_COMPILED
15522 
15523 //-----------------------------------------------------------------------------------------------------------------
15524 
15525 #if defined (_TX_CPP11)
15526 template <int txFramesToAverage>
15527 #endif
15528 
15529 double txGetFPS (int minFrames)
15530     {
15531 $1  static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0);
15532 $                     LARGE_INTEGER time  = {};                      QueryPerformanceCounter (&time);
15533 
15534 $   if (time.QuadPart - time0.QuadPart == 0)
15535         {$ return 0; }
15536 
15537 $   LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq);
15538 
15539 $   double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart);
15540 $   time0 = time;
15541 
15542 $   if (txFramesToAverage == 0) return fps;
15543 
15544 $   static _tx_thread double average [txFramesToAverage] = {};
15545 $   static _tx_thread unsigned n = 0;
15546 
15547 $   average [n++ % txFramesToAverage] = fps;
15548 
15549 $   unsigned nn = MIN (n, (unsigned) sizearr (average));
15550 
15551 $   fps = 0;
15552 $   for (unsigned i = 0; i < nn; i++) fps += average[i];
15553 $   fps /= nn;
15554 
15555 $   return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0;
15556     }
15557 
15558 //-----------------------------------------------------------------------------------------------------------------
15559 
15560 template <typename T>
15561 inline T zero() { T __zero = {}; return __zero; }
15562 
15563 //-----------------------------------------------------------------------------------------------------------------
15564 
15565 inline double random (std::nomeow_t, double left, double right)
15566     {
15567     return left + (right - left) * ((double) rand() / RAND_MAX);
15568     }
15569 
15570 //-----------------------------------------------------------------------------------------------------------------
15571 
15572 template <typename Tx, typename Ta, typename Tb>
15573 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b)
15574     {
15575     return a <= x && x <= b;
15576     }
15577 
15578 //-----------------------------------------------------------------------------------------------------------------
15579 
15580 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect)
15581     {
15582     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15583     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15584 
15585     return In (std::nomeow, pt.x, rect.left, rect.right) &&
15586            In (std::nomeow, pt.y, rect.top,  rect.bottom);
15587     }
15588 
15589 //-----------------------------------------------------------------------------------------------------------------
15590 
15591 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect)
15592     {
15593     if (_TX_ARGUMENT_FAILED (&pt))   return false;
15594     if (_TX_ARGUMENT_FAILED (&rect)) return false;
15595 
15596     return In (std::nomeow, pt.X, rect.Left, rect.Right) &&
15597            In (std::nomeow, pt.Y, rect.Top,  rect.Bottom);
15598     }
15599 
15600 //-----------------------------------------------------------------------------------------------------------------
15601 
15602 inline int random (int range)
15603     {
15604     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15605 
15606     return rand() % range;
15607     }
15608 
15609 //-----------------------------------------------------------------------------------------------------------------
15610 
15611 inline double random (double left, double right)
15612     {
15613     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15614 
15615     return random (std::nomeow, left, right);
15616     }
15617 
15618 //-----------------------------------------------------------------------------------------------------------------
15619 
15620 template <typename Tx, typename Ta, typename Tb>
15621 inline bool In (Tx x, Ta a, Tb b)
15622     {
15623     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15624 
15625     return In (std::nomeow, x, a, b);
15626     }
15627 
15628 //-----------------------------------------------------------------------------------------------------------------
15629 
15630 inline bool In (const POINT& pt, const RECT& rect)
15631     {
15632     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15633 
15634     return In (std::nomeow, pt, rect);
15635     }
15636 
15637 //-----------------------------------------------------------------------------------------------------------------
15638 
15639 inline bool In (const COORD& pt, const SMALL_RECT& rect)
15640     {
15641     if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast));  //-V206
15642 
15643     return In (std::nomeow, pt, rect);
15644     }
15645 
15646 //}
15647 //=================================================================================================================
15648 
15649 //=================================================================================================================
15650 //{          txPrintf() implementation
15651 //           Реализация txPrintf()
15652 //=================================================================================================================
15653 
15654 #if defined (_TX_CPP11)
15655 
15656 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt,                                  const T& arg, ArgsT... args);
15657 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);
15658 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);
15659 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);
15660                                          void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15661 
15662 template <typename T>                    void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg);
15663                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int*     arg);
15664                                          void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt);
15665 
15666 //-----------------------------------------------------------------------------------------------------------------
15667 
15668 template <typename T, typename... ArgsT>
15669 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args)
15670     {
15671 $1  assert (fmt);
15672 
15673 $   _txPrintV (stream, format, n,   fmt);
15674 
15675     if (fmt[0] == '%') {$}
15676     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15677 
15678 $   _txPrintV (stream, format, n,   fmt, arg);
15679 
15680 $   _txPrintF (stream, format, n+1, fmt, args...);
15681     }
15682 
15683 //-----------------------------------------------------------------------------------------------------------------
15684 
15685 template <typename T, typename... ArgsT>
15686 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args)
15687     {
15688 $1  assert (&stream);
15689 $   assert (fmt);
15690 
15691 $   _txPrintV (stream, format, n,   fmt);
15692 
15693     if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); }  //-V2006
15694     else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); }
15695 
15696 $   _txPrintV (stream, format, n,   fmt, arg);
15697 
15698 $   _txPrintF (stream, format, n+1, fmt, args...);
15699     }
15700 
15701 //-----------------------------------------------------------------------------------------------------------------
15702 
15703 template <typename T, typename... ArgsT>
15704 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args)
15705     {
15706 $1  assert (&stream);
15707 $   assert (fmt);
15708 
15709 $   _txPrintV (stream, format, n,   fmt);
15710 
15711     if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((int) (prec + 1)); }  //-V2006 //-V1028
15712     else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); }
15713 
15714 $   _txPrintV (stream, format, n,   fmt, arg);
15715 
15716 $   _txPrintF (stream, format, n+1, fmt, args...);
15717     }
15718 
15719 //-----------------------------------------------------------------------------------------------------------------
15720 
15721 template <typename T, typename... ArgsT>
15722 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args)
15723     {
15724 $1  assert (&stream);
15725 $   assert (fmt);
15726 
15727 $   _txPrintV (stream, format, n,   fmt);
15728 
15729     if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((int) (prec + 1)); }  //-V2006 //-V1028
15730     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); }
15731 
15732 $   _txPrintV (stream, format, n,   fmt, arg);
15733 
15734 $   _txPrintF (stream, format, n+1, fmt, args...);
15735     }
15736 
15737 //-----------------------------------------------------------------------------------------------------------------
15738 
15739 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt)
15740     {
15741 $1  assert (fmt);
15742 
15743 $   _txPrintV (stream, format, n,   fmt);
15744 
15745     if (!fmt[0]) {$}
15746     else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); }
15747     }
15748 
15749 //-----------------------------------------------------------------------------------------------------------------
15750 
15751 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt)
15752     {
15753 $1  assert (&stream);
15754 $   assert (fmt);
15755 
15756 $   while (*fmt)
15757         {
15758         if (fmt[0] == '%')
15759             {
15760             if (fmt[1] == '%') fmt++;
15761             else break;
15762             }
15763 
15764         stream << *fmt++;
15765         }
15766 $   }
15767 
15768 //-----------------------------------------------------------------------------------------------------------------
15769 
15770 template <typename T>
15771 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg)
15772     {
15773 $1  assert (&stream);
15774 $   assert (fmt);
15775 
15776 $   if (_TX_ARGUMENT_FAILED (&arg)) return;
15777 
15778     if (fmt[0] == '%') {$}
15779     else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); }
15780 
15781 $   fmt++;
15782 
15783 $   char                    oldFill  = stream.fill (' ');
15784 $   std::ios_base::fmtflags oldFlags = stream.flags();
15785 
15786 $   for (;;) switch (*fmt)
15787         {
15788         case '-': $ stream << std::left;     fmt++; break;
15789         case '+': $ stream << std::showpos;  fmt++; break;
15790         case ' ': $ stream.fill (' ');       fmt++; break;
15791         case '#': $ stream << std::showbase; fmt++; break;
15792         case '0': $ stream.fill ('0');       fmt++; break;
15793 
15794         default:  $ goto end;
15795         }
15796     end:
15797 
15798 $   int width = (*fmt != '*')?                  (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0);
15799 $   int prec  = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0;
15800 
15801     if (width) {$ stream << std::setw (width);        }
15802     if (prec)  {$ stream << std::setprecision (prec); }
15803 
15804 $   fmt += strspn (fmt, "hljztL");
15805 
15806 $   switch (*fmt)
15807         {
15808         case '$':
15809         case '?': $                                              break;
15810 
15811         case 'd':
15812         case 'i':
15813         case 'u': $ stream << std::dec;                          break;
15814 
15815         case 'o': $ stream << std::oct;                          break;
15816 
15817         case 'x': $ stream << std::hex;                          break;
15818         case 'X': $ stream << std::hex        << std::uppercase; break;
15819 
15820         case 'f': $ stream << std::fixed;                        break;
15821         case 'F': $ stream << std::fixed      << std::uppercase; break;
15822 
15823         case 'e': $ stream << std::scientific;                   break;
15824         case 'E': $ stream << std::scientific << std::uppercase; break;
15825 
15826         case 'g': $                                              break;
15827         case 'G': $ stream                    << std::uppercase; break;
15828 
15829         case 'a': $                                              break;
15830         case 'A': $ stream                    << std::uppercase; break;
15831 
15832         case 'c':
15833         case 's':
15834         case 'p': $                                              break;
15835 
15836         default:  $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break;
15837         }
15838 
15839 $   fmt++;
15840 
15841     if (&arg) {$ stream << arg;      }
15842     else      {$ stream << "(null)"; }
15843 
15844 $   stream.fill  (oldFill);
15845 $   stream.flags (oldFlags);
15846     }
15847 
15848 //-----------------------------------------------------------------------------------------------------------------
15849 
15850 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg)  //-V2009
15851     {
15852 $1  assert (fmt);
15853 
15854     if (_TX_ARGUMENT_FAILED (arg)) return;
15855 
15856     if (fmt[0] == '%' && fmt[1] == 'n') {$}
15857     else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); }
15858 
15859 $   *arg = (int) stream.str().length();  //-V202
15860 
15861 $   fmt += 2;
15862     }
15863 
15864 //-----------------------------------------------------------------------------------------------------------------
15865 
15866 template <typename T> inline const T&    _txPrintfNormalizeArg (const T&           arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;}          return arg;         }
15867                       inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); }
15868 
15869 //-----------------------------------------------------------------------------------------------------------------
15870 
15871 template <typename... ArgsT>
15872 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args)
15873     {
15874 $1  if (_TX_ARGUMENT_FAILED (&stream)) return 0;
15875 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15876 
15877 $   const char* fmt = format;
15878 $   _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...);
15879 
15880 $   return (int) stream.str().length();  //-V202
15881     }
15882 
15883 //-----------------------------------------------------------------------------------------------------------------
15884 
15885 template <typename... ArgsT>
15886 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args)
15887     {
15888 $1  if (_TX_ARGUMENT_FAILED (&buffer)) return 0;
15889 $   if (_TX_ARGUMENT_FAILED (&format)) return 0;
15890 
15891 $   if (size > 0) size--;
15892 $   buffer[size] = 0;
15893 
15894 $   if (!size) return 0;
15895 
15896 $   std::ostringstream stream;
15897 $   stream.rdbuf() -> pubsetbuf (buffer, size);
15898 
15899 $   txPrintf (stream, format, args...);
15900 
15901 $   return (int) stream.str().length();  //-V202
15902     }
15903 
15904 //-----------------------------------------------------------------------------------------------------------------
15905 
15906 template <typename... ArgsT>
15907 inline std::string txFormat (const char* format, ArgsT... args)
15908     {
15909 $1  if (_TX_ARGUMENT_FAILED (&format)) return "";
15910 
15911 $   std::ostringstream stream;
15912 
15913 $   txPrintf (stream, format, args...);
15914 
15915 $   return stream.str();
15916     }
15917 
15918 //-----------------------------------------------------------------------------------------------------------------
15919 
15920 template <typename... ArgsT>
15921 inline int txPrintf (const char* format, ArgsT... args)
15922     {
15923 $1  if (_TX_ARGUMENT_FAILED (&format)) return 0;
15924 
15925 $   return printf ("%s", txFormat (format, args...) .c_str());
15926     }
15927 
15928 #endif
15929 
15930 //-----------------------------------------------------------------------------------------------------------------
15931 
15932        int _txPrintfCheck (const char* format, ...) tx_printfy (1);
15933 inline int _txPrintfCheck (const char*,        ...) { return 0; }
15934 
15935 //}
15936 //=================================================================================================================
15937 
15938 //=================================================================================================================
15939 //{          txDialog methods implementation
15940 //           Реализация методов класса txDialog
15941 //
15942 //           See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx
15943 //               [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743
15944 //               [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753
15945 //=================================================================================================================
15946 
15947 #ifndef TX_COMPILED                                                          // <<< THE CODE IS HERE, UNFOLD IT <<<
15948 
15949 txDialog::txDialog () :
15950     layout_ (NULL)
15951     {$1}
15952 
15953 //-----------------------------------------------------------------------------------------------------------------
15954 
15955 txDialog::txDialog (const Layout* layout) :
15956     layout_ (layout)
15957     {$1}
15958 
15959 //-----------------------------------------------------------------------------------------------------------------
15960 
15961 const txDialog::Layout* txDialog::setLayout (const Layout* layout)
15962     {
15963 $1  assert (layout);
15964 
15965 $   return ::std::swap (layout_, layout), layout;
15966     }
15967 
15968 //-----------------------------------------------------------------------------------------------------------------
15969 
15970 intptr_t txDialog::dialogBox (WORD resourceID)
15971     {
15972 $1  const char* resName = (char*)(uintptr_t) resourceID;
15973 
15974 $   if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0;
15975 
15976 $   return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
15977     }
15978 
15979 //-----------------------------------------------------------------------------------------------------------------
15980 
15981 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/)
15982     {
15983 $1  if (!layout)  layout = layout_;
15984 $   if (!layout)  return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0;
15985 
15986 $   if (!bufsize) bufsize = 1024;
15987 
15988 $   DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize);
15989 $   if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0;
15990 
15991 $   const Layout* dlg = &layout[0];
15992 $   const Layout  def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 };
15993 
15994 $   void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize,
15995                                        (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0,
15996                                         dlg->x, dlg->y, dlg->sx, dlg->sy,
15997                                         dlg->caption?  dlg->caption  : def.caption,
15998                                         dlg->font?     dlg->font     : def.font,
15999                                         dlg->fontsize? dlg->fontsize : def.fontsize, NULL);
16000 $   WORD i = 0;
16001 $   for (i = 1; layout[i].wndclass != END; ++i)
16002         {
16003 $       const Layout* item = &layout[i];
16004 
16005 $       ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl),
16006                                    item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy,
16007                                    item->id, (const char*)(uintptr_t) item->wndclass, item->caption);
16008         }
16009 
16010 $   tmpl->cdit = (unsigned short) (i-1);
16011 
16012 $   intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this);
16013 
16014 $   GlobalFree (tmpl);
16015 
16016 $   return res;
16017     }
16018 
16019 //-----------------------------------------------------------------------------------------------------------------
16020 
16021 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM)
16022     {
16023 $1  switch (msg)
16024         {
16025         case WM_INITDIALOG: $ SetForegroundWindow (wnd);
16026                             $ break;
16027 
16028         case WM_COMMAND:    $ switch (LOWORD (wParam))
16029             {
16030             case IDOK:
16031             case IDCANCEL:  $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow());
16032                             $ EndDialog (wnd, (uintptr_t) this);
16033                             $ break;
16034 
16035             default:        $ break;
16036             }
16037                             $ break;
16038         default:            $ break;
16039         }
16040 
16041 $   return FALSE;
16042     }
16043 
16044 //-----------------------------------------------------------------------------------------------------------------
16045 
16046 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
16047     {
16048 $1  static txDialog* this__ = NULL;
16049 $   if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam;
16050 $   if (!this__) return FALSE;
16051 
16052 $   return this__-> dialogProc (wnd, msg, wParam, lParam);  //-V109
16053     }
16054 
16055 //-----------------------------------------------------------------------------------------------------------------
16056 
16057 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle,
16058                               WORD controls, short x, short y, short cx, short cy,
16059                               const char caption[], const char font[], WORD fontsize, const char menu[])
16060     {
16061 $1  if (_TX_ARGUMENT_FAILED (globalMem)) return NULL;
16062 
16063 $   WORD* pw = (WORD*) globalMem;
16064 
16065 $   DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++;
16066 
16067 $   tmpl->style = style;
16068 $   tmpl->dwExtendedStyle = exStyle;
16069 $   tmpl->cdit  = controls;
16070 $   tmpl->x     = x;
16071 $   tmpl->y     = y;
16072 $   tmpl->cx    = cx;
16073 $   tmpl->cy    = cy;
16074 
16075 $   if (menu > (const char*) 0xFFFF)
16076         {
16077 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (menu?    menu    : ""), -1, (wchar_t*) pw,           //-V547
16078                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
16079         }
16080     else
16081         {
16082 $       *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0);
16083 $       *pw++ = (WORD)(uintptr_t)  menu;
16084         }
16085 
16086 $   if (caption)
16087         {
16088 $       pw  += MultiByteToWideChar  (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw,           //-V547
16089                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
16090         }
16091 
16092 $   if (style & DS_SETFONT)
16093         {
16094 $       *pw++ = fontsize;
16095 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, (font?    font    : ""), -1, (wchar_t*) pw,
16096                                     (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF));  //-V202
16097         }
16098 
16099 $   return pw;
16100     }
16101 
16102 //-----------------------------------------------------------------------------------------------------------------
16103 
16104 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle,
16105                            short x, short y, short cx, short cy,
16106                            WORD id, const char wclass[], const char caption[])
16107     {
16108 $1  if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL;
16109 
16110 $   WORD* pw = (LPWORD) dlgTemplatePtr;  // Force align at word boundary
16111 $   ((ULONG&) pw)  += 3;  //-V205
16112 $   ((ULONG&) pw) >>= 2;  //-V205
16113 $   ((ULONG&) pw) <<= 2;  //-V205
16114 
16115 $   DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++;
16116 
16117 $   tmpl->style = style;
16118 $   tmpl->dwExtendedStyle = exStyle;
16119 $   tmpl->x     = x;
16120 $   tmpl->y     = y;
16121 $   tmpl->cx    = cx;
16122 $   tmpl->cy    = cy;
16123 $   tmpl->id    = id;
16124 
16125 $   if (HIWORD (wclass) == 0xFFFF)
16126         {
16127 $       *pw++ = (WORD) (HIWORD ((uintptr_t) wclass));
16128 $       *pw++ = (WORD) (LOWORD ((uintptr_t) wclass));
16129         }
16130     else if (wclass)
16131         {
16132 $       pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw,
16133                                    (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));   //-V202
16134         }
16135     else
16136         {
16137 $       *pw++ = 0;
16138         }
16139 
16140 $   if (caption)
16141          {
16142 $        pw  += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw,
16143                                     (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF));  //-V202
16144          }
16145     else
16146         {
16147 $       *pw++ = 0;
16148         }
16149 
16150 $   *pw++ = 0;
16151 
16152 $   return pw;
16153     }
16154 
16155 #endif // TX_COMPILED
16156 
16157 //}
16158 //=================================================================================================================
16159 
16160 //=================================================================================================================
16161 //{          Cleaning up the utility macros
16162 //           Очистка служебных макросов
16163 //=================================================================================================================
16164 
16165 #undef       $
16166 #undef       $0
16167 #undef       $1
16168 #undef       $2
16169 #undef       $3
16170 #undef       $4
16171 #undef       $5
16172 #undef       $6
16173 #undef       $7
16174 #undef       $8
16175 #undef       $9
16176 #undef       $$
16177 
16178 //}
16179 //=================================================================================================================
16180 
16182 
16183 //=================================================================================================================
16184 //{          Experimental Debugging macros
16186 //=================================================================================================================
16187 
16188 //{----------------------------------------------------------------------------------------------------------------
16311 //}----------------------------------------------------------------------------------------------------------------
16312 
16313 #ifndef __TX_DEBUG_MACROS
16314 #define __TX_DEBUG_MACROS  ("Группа отладочных $-макросов")
16315 
16317 //-----------------------------------------------------------------------------------------------------------------
16318 
16319 #define $H            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_BLACK);
16320 #define $B            txSetConsoleAttr (FOREGROUND_BLUE         | BACKGROUND_BLACK);
16321 #define $G            txSetConsoleAttr (FOREGROUND_GREEN        | BACKGROUND_BLACK);
16322 #define $C            txSetConsoleAttr (FOREGROUND_CYAN         | BACKGROUND_BLACK);
16323 #define $R            txSetConsoleAttr (FOREGROUND_RED          | BACKGROUND_BLACK);
16324 #define $M            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_BLACK);
16325 #define $Y            txSetConsoleAttr (FOREGROUND_DARKYELLOW   | BACKGROUND_BLACK);
16326 #define $d            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_BLACK);
16327 #define $D            txSetConsoleAttr (FOREGROUND_DARKGRAY     | BACKGROUND_BLACK);
16328 #define $b            txSetConsoleAttr (FOREGROUND_LIGHTBLUE    | BACKGROUND_BLACK);
16329 #define $g            txSetConsoleAttr (FOREGROUND_LIGHTGREEN   | BACKGROUND_BLACK);
16330 #define $c            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLACK);
16331 #define $r            txSetConsoleAttr (FOREGROUND_LIGHTRED     | BACKGROUND_BLACK);
16332 #define $m            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK);
16333 #define $y            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLACK);
16334 #define $h            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_BLACK);
16335 
16336 #define $i            txSetConsoleAttr (FOREGROUND_LIGHTCYAN    | BACKGROUND_BLUE);
16337 #define $I            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_BLUE);
16338 #define $o            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_GREEN);
16339 #define $O            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_GREEN);
16340 #define $e            txSetConsoleAttr (FOREGROUND_WHITE        | BACKGROUND_RED);
16341 #define $E            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_RED);
16342 #define $w            txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA);
16343 #define $W            txSetConsoleAttr (FOREGROUND_YELLOW       | BACKGROUND_MAGENTA);
16344 #define $f            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_LIGHTRED);
16345 #define $F            txSetConsoleAttr (FOREGROUND_MAGENTA      | BACKGROUND_LIGHTRED);
16346 #define $l            txSetConsoleAttr (FOREGROUND_BLACK        | BACKGROUND_DARKGRAY);
16347 #define $L            txSetConsoleAttr (FOREGROUND_LIGHTGRAY    | BACKGROUND_DARKGRAY);
16348 
16349 #define $T( cond )    txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED );
16350 
16351 #define $s            _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__);
16352 
16353 #define $sH           $s $H
16354 #define $sB           $s $B
16355 #define $sG           $s $G
16356 #define $sC           $s $C
16357 #define $sR           $s $R
16358 #define $sM           $s $M
16359 #define $sY           $s $Y
16360 #define $sd           $s $d
16361 #define $sD           $s $D
16362 #define $sb           $s $b
16363 #define $sg           $s $g
16364 #define $sc           $s $c
16365 #define $sr           $s $r
16366 #define $sm           $s $m
16367 #define $sy           $s $y
16368 #define $sh           $s $h
16369 
16370 #define $si           $s $i
16371 #define $sI           $s $I
16372 #define $so           $s $o
16373 #define $sO           $s $O
16374 #define $se           $s $e
16375 #define $sE           $s $E
16376 #define $sw           $s $w
16377 #define $sW           $s $W
16378 #define $sf           $s $f
16379 #define $sF           $s $F
16380 #define $sl           $s $l
16381 #define $sL           $s $L
16382 
16383 #define $sT( cond )   $s $T (cond)
16384 
16385 #define $test(cond)   { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \
16386                         else          { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; }
16387 
16388 #define $status(cond) $test (cond)
16389 
16390 #define $unittest( code, expected )                                                                                             \
16391     {                                                                                                                           \
16392     const _tx_decltype (code)     & _result   = (code);       /* Should use auto, but g++ 4.7.2 default std is < 2011 */        \
16393     const _tx_decltype (expected) & _expected = (expected);                                                                     \
16394                                                                                                                                 \
16395     if (_result == _expected)                                                                                                   \
16396         { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; }                                                            \
16397     else                                                                                                                        \
16398         { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \
16399                                                                                                                                 \
16400     $n;                                                                                                                         \
16401     (_result == _expected);                                                                                                     \
16402     }
16403 
16404 //=================================================================================================================
16405 
16406 #define $V(  var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]\n") )
16407 #define $V_( var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "] " ) )
16408 #define $V__(var, ...)        (               _txDumpVar ((var), _tx$PrefixV (      __VA_ARGS__), "]"  ) )
16409 
16410 #define $(   var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n") )
16411 #define $_(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] " ) )
16412 #define $__( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]"  ) )
16413 
16414 #define $x(  var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) )
16415 #define $x_( var, ...)        (               _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "] ",  ::std::ios_base::showbase | ::std::ios_base::hex) )
16416 
16417 #define $v(  var, cond, ...)  { { $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" ); } $n; }
16418 #define $v_( var, cond, ...)  {   $st (cond); _txDumpVar ((var), _tx$Prefix  (#var, __VA_ARGS__), "]" );       }
16419 
16420 #define $$                    { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__);                                   } txOutputDebugPrintf ("\f\n"); }
16421 #define $$_                   { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]",           __LINE__, __func__);                                          } txOutputDebugPrintf ("\f\n"); }
16422 #define $meow(...)            { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); }
16423 
16424 #define $$$(   ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
16425 #define $$$_(  ... )          ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),  "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") )
16426 
16427 #define $$$$(  ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
16428 #define $$$$_( ... )          { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix         (  "[" __TX_FILELINE__ ": " #__VA_ARGS__        " DONE]\n\n"); { __VA_ARGS__; } }
16429 #define $do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n";                                                                                           __VA_ARGS__
16430 #define $DO(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p;                                                                                    __VA_ARGS__
16431 #define $Do(   ... )            ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n";                                                                                        \
16432                                 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__);                                                                      __VA_ARGS__
16433 
16434 #define $n                    { ::std::cerr << "\n";   }
16435 #define $nn                   { ::std::cerr << "\n\n"; }
16436 #define $t                    { ::std::cerr << "\t";   }
16437 
16438 #define _tx$PrefixV(    ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": "          ) : ("["          ) )
16439 #define _tx$Prefix(var, ...)  ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") )
16440 
16441 //-----------------------------------------------------------------------------------------------------------------
16442 
16443 // This will never be documented, he-he. Read the source, Luke.
16444 
16445 #if defined (_DEBUG)
16446     #define $dbg               if (1)
16447     #define $DBG               if (1)
16448     #define $debug             if (1)
16449     #define $DEBUG             if (1)
16450     #define $printf(fmt, ...)  if (1)  printf (        fmt, ##__VA_ARGS__)
16451     #define $PRINTF(fmt, ...)  if (1) fprintf (stderr, fmt, ##__VA_ARGS__)
16452 #else
16453     #define $dbg               if (0)
16454     #define $DBG               if (0)
16455     #define $debug             if (0)
16456     #define $DEBUG             if (0)
16457     #define $printf(...)       if (0)  printf (        fmt, ##__VA_ARGS__)
16458     #define $PRINTF(...)       if (0) fprintf (stderr, fmt, ##__VA_ARGS__)
16459 #endif
16460 
16461 #define $$d    $debug
16462 #define $$w    $$$$
16463 #define $$s    __TX_FILELINE__
16464 #define $$b    { txSleep(); DebugBreak(); }
16465 #define $$p    { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \
16466                                                     __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); }
16467 #define $$P    (     txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) )
16468 #define $ppp   { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); }
16469 #define $pp    { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__,        __TX_FUNCTION__); }
16470 #define $p     { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__);        }
16471 #define $ppp_  { $sy; txPause ("\v[%s ""%s]...",                    __TX_FILELINE__, __TX_FUNCTION__); }
16472 #define $pp_   { $sy; txPause ("\v[%04d %s]...",                    __LINE__,        __TX_FUNCTION__); }
16473 #define $p_    { $sy; txPause ("\v[%s ""%s()]...",                  __TX_FILELINE__, __func__);        }
16474 #define $P     ( txPause ("") )
16475 
16476 //-----------------------------------------------------------------------------------------------------------------
16477 
16478 struct _txSaveConsoleAttr
16479     {
16480     unsigned attr_;
16481 
16482              _txSaveConsoleAttr()           : attr_ (txGetConsoleAttr ()) {}
16483     explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr);  }
16484             ~_txSaveConsoleAttr()                                         { txSetConsoleAttr (attr_); }
16485     };
16486 
16487 //-----------------------------------------------------------------------------------------------------------------
16488 
16489 struct _txDumpVarSuffix
16490     {
16491     typedef _txDumpVarSuffix this_t;
16492 
16493     const char* suffix_;
16494 
16495     explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); }
16496             ~_txDumpVarSuffix()                          { ::std::cerr << suffix_; }
16497 
16498             _txDumpVarSuffix (const this_t&) _tx_delete;
16499     this_t& operator =       (const this_t&) _tx_delete;
16500     };
16501 
16502 //-----------------------------------------------------------------------------------------------------------------
16503 
16504 #define ARGS__        const char* prefix, const char* suffix, std::ios_base::fmtflags flags,                             int deep
16505 #define ARGS_         const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0
16506 #define VALS_         prefix, suffix, flags, deep
16507 #define ERRPTR_(p)  { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; }
16508 
16509 template <typename T, typename StreamT> const T&    _txDumpVal (const T& value, StreamT& stream, ARGS_);
16510 
16511 //-----------------------------------------------------------------------------------------------------------------
16512 
16513 template <typename T> inline const T&               _txDumpVar (const T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16514 template <typename T> inline       T&               _txDumpVar (      T&            value,      ARGS_)      { _txDumpVal (value, std:: cerr, VALS_); return value; }
16515 
16516 template <int N>      inline const char           (&_txDumpVar (const char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16517 template <int N>      inline       char           (&_txDumpVar (      char        (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; }
16518 
16519 template <int N>      inline const wchar_t        (&_txDumpVar (const wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16520 template <int N>      inline       wchar_t        (&_txDumpVar (      wchar_t     (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; }
16521 
16522                       inline const wchar_t&         _txDumpVar (const wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16523                       inline       wchar_t&         _txDumpVar (      wchar_t&      value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16524 
16525                       inline const wchar_t*&        _txDumpVar (const wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16526                       inline       wchar_t*&        _txDumpVar (      wchar_t*&     value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16527 
16528                       inline const std::wstring&    _txDumpVar (const std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16529                       inline       std::wstring&    _txDumpVar (      std::wstring& value,      ARGS_)      { _txDumpVal (value, std::wcerr, VALS_); return value; }
16530 
16531 //-----------------------------------------------------------------------------------------------------------------
16532 
16533 template <typename T, typename StreamT> inline void _txDumpVal (const T&            value, StreamT& stream) { stream <<         value;         }
16534 template             <typename StreamT> inline void _txDumpVal (const char          value, StreamT& stream) { stream <<  "'" << value <<  "'"; }
16535 template             <typename StreamT> inline void _txDumpVal (const wchar_t       value, StreamT& stream) { stream << L"'" << value << L"'"; }
16536 template             <typename StreamT> inline void _txDumpVal (const std::string&  value, StreamT& stream) { stream <<  '"' << value <<  '"'; }
16537 template             <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; }
16538 
16539 template             <typename StreamT> inline void _txDumpVal (const char*         value, StreamT& stream)
16540     {
16541     if (_TX_ARGUMENT_FAILED (&stream)) return;
16542 
16543     if (!_txIsBadReadPtr (value)) stream <<  '"' << value <<  '"';
16544     else if (!value)              stream <<  "(null)";
16545     else                          ERRPTR_ (value);
16546     }
16547 
16548 template             <typename StreamT> inline void _txDumpVal (const wchar_t*      value, StreamT& stream)
16549     {
16550     if (_TX_ARGUMENT_FAILED (&stream)) return;
16551 
16552     if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"';
16553     else if (!value)              stream << L"(null)";
16554     else                          ERRPTR_ (value);
16555     }
16556 
16557 //-----------------------------------------------------------------------------------------------------------------
16558 
16559 template <typename T, typename StreamT>
16560 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__)
16561     {
16562     if (_TX_ARGUMENT_FAILED (&stream)) return value;  //-V778
16563     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16564     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16565 
16566     $sc;
16567     if (!deep) stream << prefix;
16568 
16569     std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags());
16570 
16571     if (!_txIsBadReadPtr (&value))
16572         {
16573         _txDumpVal (value, stream);
16574         }
16575     else
16576         ERRPTR_ (&value);
16577 
16578     stream.flags (old);
16579 
16580     if (!deep) stream << suffix;
16581 
16582     return value;
16583     }
16584 
16585 //-----------------------------------------------------------------------------------------------------------------
16586 
16587 template <typename T, int N>
16588 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N]
16589     {
16590     if (_TX_ARGUMENT_FAILED ( prefix)) return value;
16591     if (_TX_ARGUMENT_FAILED ( suffix)) return value;
16592 
16593     std::ostream& stream = std::cerr;
16594 
16595     $sc; if (!deep) std::cerr << prefix;
16596     $C;  std::cerr << ((deep)? " {" : "{");
16597 
16598     if (!_txIsBadReadPtr (value))
16599         {
16600         for (int i = 0; ; i++)
16601             {
16602             { $sC; stream << "[" << i << "]="; }
16603 
16604             _txDumpVar (value[i], prefix, suffix, flags, deep+1);
16605 
16606             if (i >= N-1) break;
16607 
16608             stream << ", ";
16609             }
16610         }
16611     else
16612         ERRPTR_ (&value);
16613 
16614     $C; std::cerr << "}";
16615     $c; if (!deep) std::cerr << suffix;
16616 
16617     return value;
16618     }
16619 
16620 //-----------------------------------------------------------------------------------------------------------------
16621 
16622 inline int $ptrHTML (FILE* html, const void* ptr, COLORREF backColor = TX_WHITE)
16623     {
16624     COLORREF color = txHash (&ptr, sizeof (ptr)) & 0x00FFFFFF;
16625 
16626     if (txDeltaE94 (color, backColor) < 10) color = ~color & 0x00FFFFFF;
16627 
16628     return fprintf (html, "<font face = \"Monospace\" color = \"#%06lX\">0x%p</font>", color, ptr);
16629     }
16630 
16631 //=================================================================================================================
16632 
16633 inline std::ostream& operator << (std::ostream& stream, const POINT& point)
16634     {
16635     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16636 
16637     if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }";           // NOLINT (clang-diagnostic-undefined-bool-conversion)
16638     else if (!&point)              stream << "(null)";
16639     else ERRPTR_ (&point);
16640 
16641     return stream;
16642     }
16643 
16644 inline std::ostream& operator << (std::ostream& stream, const SIZE& size)
16645     {
16646     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16647 
16648     if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }";          // NOLINT (clang-diagnostic-undefined-bool-conversion)
16649     else       stream << "(null)";
16650 
16651     return stream;
16652     }
16653 
16654 inline std::ostream& operator << (std::ostream& stream, const RECT& rect)
16655     {
16656     if (_TX_ARGUMENT_FAILED (&stream)) return stream;
16657 
16658     if (&rect) stream << "{ left: "  << rect.left  << ", top: "    << rect.top    <<  // NOLINT (clang-diagnostic-undefined-bool-conversion)
16659                          ", right: " << rect.right << ", bottom: " << rect.bottom << " }";
16660 
16661     else       stream << "(null)";
16662 
16663     return stream;
16664     }
16665 
16666 //-----------------------------------------------------------------------------------------------------------------
16667 
16668 #undef ARGS__
16669 #undef ARGS_
16670 #undef VALS_
16671 #undef ERRPTR_
16672 
16673 //-----------------------------------------------------------------------------------------------------------------
16675 
16676 #endif
16677 
16678 //}
16679 //=================================================================================================================
16680 
16682 
16683 //=================================================================================================================
16684 //{          TXAPI calls tracing
16685 //           Трассировка вызовов TXAPI
16686 //=================================================================================================================
16687 
16688 #ifndef   FOR_DOXYGEN_ONLY
16689 
16690 #if defined (_MSC_VER)
16691 #undef  _txLocCurSet
16692 #define _txLocCurSet()                 _txLocSet (&_txLoc::Cur, __FILE__, __LINE__, NULL)
16693 #endif
16694 
16695 #define txAlphaBlend(...)              ( _txLocCurSet(), txAlphaBlend          (__VA_ARGS__) )
16696 #define txArc(...)                     ( _txLocCurSet(), txArc                 (__VA_ARGS__) )
16697 #define txBegin(...)                   ( _txLocCurSet(), txBegin               (__VA_ARGS__) )
16698 #define txBitBlt(...)                  ( _txLocCurSet(), txBitBlt              (__VA_ARGS__) )
16699 #define txChord(...)                   ( _txLocCurSet(), txChord               (__VA_ARGS__) )
16700 #define txCircle(...)                  ( _txLocCurSet(), txCircle              (__VA_ARGS__) )
16701 #define txClear(...)                   ( _txLocCurSet(), txClear               (__VA_ARGS__) )
16702 #define txClearConsole(...)            ( _txLocCurSet(), txClearConsole        (__VA_ARGS__) )
16703 #define txColor(...)                   ( _txLocCurSet(), txColor               (__VA_ARGS__) )
16704 #define txCreateCompatibleDC(...)      ( _txLocCurSet(), txCreateCompatibleDC  (__VA_ARGS__) )
16705 #define txCreateDIBSection(...)        ( _txLocCurSet(), txCreateDIBSection    (__VA_ARGS__) )
16706 #define txCreateExtraWindow(...)       ( _txLocCurSet(), txCreateExtraWindow   (__VA_ARGS__) )
16707 #define txCreateWindow(...)            ( _txLocCurSet(), txCreateWindow        (__VA_ARGS__) )
16708 #define txDC(...)                      ( _txLocCurSet(), txDC                  (__VA_ARGS__) )
16709 #define txDeleteDC(...)                ( _txLocCurSet(), txDeleteDC            (__VA_ARGS__) )
16710 #define txDeltaE(...)                  ( _txLocCurSet(), txDeltaE              (__VA_ARGS__) )
16711 #define txDeltaE94(...)                ( _txLocCurSet(), txDeltaE94            (__VA_ARGS__) )
16712 #define txDemangle(...)                ( _txLocCurSet(), txDemangle            (__VA_ARGS__) )
16713 #define txDestroyWindow(...)           ( _txLocCurSet(), txDestroyWindow       (__VA_ARGS__) )
16714 #define txDisableAutoPause(...)        ( _txLocCurSet(), txDisableAutoPause    (__VA_ARGS__) )
16715 #define txDrawText(...)                ( _txLocCurSet(), txDrawText            (__VA_ARGS__) )
16716 #define txEllipse(...)                 ( _txLocCurSet(), txEllipse             (__VA_ARGS__) )
16717 #define txEnd(...)                     ( _txLocCurSet(), txEnd                 (__VA_ARGS__) )
16718 #define txExtractColor(...)            ( _txLocCurSet(), txExtractColor        (__VA_ARGS__) )
16719 #define txFillColor(...)               ( _txLocCurSet(), txFillColor           (__VA_ARGS__) )
16720 #define txFloodFill(...)               ( _txLocCurSet(), txFloodFill           (__VA_ARGS__) )
16721 #define txFontExist(...)               ( _txLocCurSet(), txFontExist           (__VA_ARGS__) )
16722 #define txFormat(...)                  ( _txLocCurSet(), txFormat              (__VA_ARGS__) )
16723 #define txGetAsyncKeyState(...)        ( _txLocCurSet(), txGetAsyncKeyState    (__VA_ARGS__) )
16724 #define txGetColor(...)                ( _txLocCurSet(), txGetColor            (__VA_ARGS__) )
16725 #define txGetConsoleAttr(...)          ( _txLocCurSet(), txGetConsoleAttr      (__VA_ARGS__) )
16726 #define txGetConsoleCursorPos(...)     ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) )
16727 #define txGetConsoleExtent(...)        ( _txLocCurSet(), txGetConsoleExtent    (__VA_ARGS__) )
16728 #define txGetConsoleFontSize(...)      ( _txLocCurSet(), txGetConsoleFontSize  (__VA_ARGS__) )
16729 #define txGetExtent(...)               ( _txLocCurSet(), txGetExtent           (__VA_ARGS__) )
16730 #define txGetExtentX(...)              ( _txLocCurSet(), txGetExtentX          (__VA_ARGS__) )
16731 #define txGetExtentY(...)              ( _txLocCurSet(), txGetExtentY          (__VA_ARGS__) )
16732 #define txGetFillColor(...)            ( _txLocCurSet(), txGetFillColor        (__VA_ARGS__) )
16733 #define txGetFPS(...)                  ( _txLocCurSet(), txGetFPS              (__VA_ARGS__) )
16734 #define txGetModuleFileName(...)       ( _txLocCurSet(), txGetModuleFileName   (__VA_ARGS__) )
16735 #define txGetPixel(...)                ( _txLocCurSet(), txGetPixel            (__VA_ARGS__) )
16736 #define txGetTextExtent(...)           ( _txLocCurSet(), txGetTextExtent       (__VA_ARGS__) )
16737 #define txGetTextExtentX(...)          ( _txLocCurSet(), txGetTextExtentX      (__VA_ARGS__) )
16738 #define txGetTextExtentY(...)          ( _txLocCurSet(), txGetTextExtentY      (__VA_ARGS__) )
16739 #define txHSL2RGB(...)                 ( _txLocCurSet(), txHSL2RGB             (__VA_ARGS__) )
16740 #define txHash(...)                    ( _txLocCurSet(), txHash                (__VA_ARGS__) )
16741 #define txInputBox(...)                ( _txLocCurSet(), txInputBox            (__VA_ARGS__) )
16742 #define txLab2RGB(...)                 ( _txLocCurSet(), txLab2RGB             (__VA_ARGS__) )
16743 #define txLine(...)                    ( _txLocCurSet(), txLine                (__VA_ARGS__) )
16744 #define txLoadImage(...)               ( _txLocCurSet(), txLoadImage           (__VA_ARGS__) )
16745 #define txLock(...)                    ( _txLocCurSet(), txLock                (__VA_ARGS__) )
16746 #define txMessageBox(...)              ( _txLocCurSet(), txMessageBox          (__VA_ARGS__) )
16747 #define txMouseButtons(...)            ( _txLocCurSet(), txMouseButtons        (__VA_ARGS__) )
16748 #define txMousePos(...)                ( _txLocCurSet(), txMousePos            (__VA_ARGS__) )
16749 #define txMouseX(...)                  ( _txLocCurSet(), txMouseX              (__VA_ARGS__) )
16750 #define txMouseY(...)                  ( _txLocCurSet(), txMouseY              (__VA_ARGS__) )
16751 #define txNotifyIcon(...)              ( _txLocCurSet(), txNotifyIcon          (__VA_ARGS__) )
16752 #define txOK(...)                      ( _txLocCurSet(), txOK                  (__VA_ARGS__) )
16753 #define txOutputDebugPrintf(...)       ( _txLocCurSet(), txOutputDebugPrintf   (__VA_ARGS__) )
16754 #define txPause(...)                   ( _txLocCurSet(), txPause               (__VA_ARGS__) )
16755 #define txPie(...)                     ( _txLocCurSet(), txPie                 (__VA_ARGS__) )
16756 #define txPixel(...)                   ( _txLocCurSet(), txPixel               (__VA_ARGS__) )
16757 #define txPlaySound(...)               ( _txLocCurSet(), txPlaySound           (__VA_ARGS__) )
16758 #define txPlayVideo(...)               ( _txLocCurSet(), txPlayVideo           (__VA_ARGS__) )
16759 #define txPolygon(...)                 ( _txLocCurSet(), txPolygon             (__VA_ARGS__) )
16760 #define txPrintf(...)                  ( _txLocCurSet(), txPrintf              (__VA_ARGS__) )
16761 #define txQueryPerformance(...)        ( _txLocCurSet(), txQueryPerformance    (__VA_ARGS__) )
16762 #define txRectangle(...)               ( _txLocCurSet(), txRectangle           (__VA_ARGS__) )
16763 #define txRedrawWindow(...)            ( _txLocCurSet(), txRedrawWindow        (__VA_ARGS__) )
16764 #define txRegisterClass(...)           ( _txLocCurSet(), txRegisterClass       (__VA_ARGS__) )
16765 #define txRegQuery(...)                ( _txLocCurSet(), txRegQuery            (__VA_ARGS__) )
16766 #define txReopenStdio(...)             ( _txLocCurSet(), txReopenStdio         (__VA_ARGS__) )
16767 #define txRGB2HSL(...)                 ( _txLocCurSet(), txRGB2HSL             (__VA_ARGS__) )
16768 #define txRGB2Lab(...)                 ( _txLocCurSet(), txRGB2Lab             (__VA_ARGS__) )
16769 #define txSaveImage(...)               ( _txLocCurSet(), txSaveImage           (__VA_ARGS__) )
16770 #define txSelectFont(...)              ( _txLocCurSet(), txSelectFont          (__VA_ARGS__) )
16771 #define txSelectObject(...)            ( _txLocCurSet(), txSelectObject        (__VA_ARGS__) )
16772 #define txSetColor(...)                ( _txLocCurSet(), txSetColor            (__VA_ARGS__) )
16773 #define txSetConsoleAttr(...)          ( _txLocCurSet(), txSetConsoleAttr      (__VA_ARGS__) )
16774 #define txSetConsoleCursorPos(...)     ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) )
16775 #define txSetDefaults(...)             ( _txLocCurSet(), txSetDefaults         (__VA_ARGS__) )
16776 #define txSetFillColor(...)            ( _txLocCurSet(), txSetFillColor        (__VA_ARGS__) )
16777 #define txSetLocale(...)               ( _txLocCurSet(), txSetLocale           (__VA_ARGS__) )
16778 #define txSetPixel(...)                ( _txLocCurSet(), txSetPixel            (__VA_ARGS__) )
16779 #define txSetProgress(...)             ( _txLocCurSet(), txSetProgress         (__VA_ARGS__) )
16780 #define txSetTextAlign(...)            ( _txLocCurSet(), txSetTextAlign        (__VA_ARGS__) )
16781 #define txSetWindowsHook(...)          ( _txLocCurSet(), txSetWindowsHook      (__VA_ARGS__) )
16782 #define txSleep(...)                   ( _txLocCurSet(), txSleep               (__VA_ARGS__) )
16783 #define txSpeak(...)                   ( _txLocCurSet(), txSpeak               (__VA_ARGS__) )
16784 #define txTextCursor(...)              ( _txLocCurSet(), txTextCursor          (__VA_ARGS__) )
16785 #define txTextOut(...)                 ( _txLocCurSet(), txTextOut             (__VA_ARGS__) )
16786 #define txTransparentBlt(...)          ( _txLocCurSet(), txTransparentBlt      (__VA_ARGS__) )
16787 #define txTriangle(...)                ( _txLocCurSet(), txTriangle            (__VA_ARGS__) )
16788 #define txUnlock(...)                  ( _txLocCurSet(), txUnlock              (__VA_ARGS__) )
16789 #define txUpdateWindow(...)            ( _txLocCurSet(), txUpdateWindow        (__VA_ARGS__) )
16790 #define txUseAlpha(...)                ( _txLocCurSet(), txUseAlpha            (__VA_ARGS__) )
16791 #define txVersion(...)                 ( _txLocCurSet(), txVersion             (__VA_ARGS__) )
16792 #define txVersionNumber(...)           ( _txLocCurSet(), txVersionNumber       (__VA_ARGS__) )
16793 #define txWindow(...)                  ( _txLocCurSet(), txWindow              (__VA_ARGS__) )
16794 #define tx_fpreset(...)                ( _txLocCurSet(), tx_fpreset            (__VA_ARGS__) )
16795 #define tx_glGetError(...)             ( _txLocCurSet(), tx_glGetError         (__VA_ARGS__) )
16796 #define _txDump(...)                   ( _txLocCurSet(), _txDump               (__VA_ARGS__) )
16797 #define _txStackBackTrace(...)         ( _txLocCurSet(), _txStackBackTrace     (__VA_ARGS__) )
16798 
16799 #endif
16800 
16801 //}
16802 //=================================================================================================================
16803 
16805 //}
16806 //=================================================================================================================
16807 
16808 //-----------------------------------------------------------------------------------------------------------------
16809 //{          The namespaces
16810 //-----------------------------------------------------------------------------------------------------------------
16811 
16814 _TX_END_NAMESPACE
16815 
16818 using namespace TX;                    // Allow easy usage of TXLib functions
16819 
16820 using ::std::cin;                      // Predefined usings to avoid "using namespace std"
16821 using ::std::cout;
16822 using ::std::cerr;
16823 using ::std::string;
16824 using ::std::wcin;
16825 using ::std::wcout;
16826 using ::std::wcerr;
16827 using ::std::wstring;
16828 
16829 //}
16830 //-----------------------------------------------------------------------------------------------------------------
16831 
16832 //-----------------------------------------------------------------------------------------------------------------
16833 //{          Compiler- and platform-specific
16834 //           Адаптация к компиляторам и платформам
16835 //-----------------------------------------------------------------------------------------------------------------
16837 
16838 #if defined (_GCC_VER)
16839 
16840     #pragma GCC diagnostic ignored     "-Wunknown-pragmas"
16841 
16842     #pragma GCC optimize               "strict-aliasing"
16843 
16844     #pragma GCC pop_options
16845     #pragma GCC diagnostic pop
16846 
16847     #pragma GCC diagnostic warning     "-Wunknown-pragmas"
16848 
16849 #endif
16850 
16851 #if defined (_CLANG_VER)
16852     #pragma clang diagnostic pop
16853     #endif
16854 
16855 //-----------------------------------------------------------------------------------------------------------------
16856 
16857 #if defined (_MSC_VER)
16858     #pragma warning (pop)              // Restoring maximum level
16859     #endif
16860 
16862 //}
16863 //-----------------------------------------------------------------------------------------------------------------
16864 
16865 #endif // __TXLIB_H_INCLUDED
16866 
16867 //=================================================================================================================
16868 // EOF
16869 //=================================================================================================================
16870                                                                                                                    
16871                                                                                                                    
16872                                                                                                                    
16873                                                                                                                    
16874                                                                                                                    
16875                                                                                                                    
16876                                                                                                                    
16877                                                                                                                    
16878                                                                                                                    
16879         
16880 
16881 
16882 
16883 
16884 
16885 
16886 
16887 
16888 
16889 
16890 
16891 
16892 
16893 
16894 
16895 
16896 
16897 
16898 
16899