TX Library Help – Version: 00173a, Revision: 173
|
00001 //================================================================================================================= 00002 // TXLib.h - Библиотека Тупого Художника (The Dumb Artist Library, TX Library, TXLib) - (C) Ilya Dedinsky 00003 //================================================================================================================= 00004 // [These sections are for folding control in Code::Blocks] [$Date: 2024-04-10 21:00:00 +0400 $] 00005 // [Best viewed with "Fold all on file open" option enabled] [Best screen/page width = 120 chars] 00006 // 00007 // [If RUSSIAN CHARS below are UNREADABLE, check this file codepage. It should be CP1251, NOT UTF-8 etc.] 00008 //{ [Use RELOAD options in your IDE or editor (CLion / Visual Studio Code / ...), and do NOT use Convert.] 00009 //================================================================================================================= 00102 // $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $ 00103 //----------------------------------------------------------------------------------------------------------------- 00110 //} 00111 //================================================================================================================= 00112 00113 #if !defined (__TXLIB_H_INCLUDED) // <<< THE CODE IS HERE, UNFOLD IT <<< 00114 #define __TXLIB_H_INCLUDED 00115 00116 //----------------------------------------------------------------------------------------------------------------- 00117 //{ Version information and configuration 00118 //----------------------------------------------------------------------------------------------------------------- 00119 00120 //{---------------------------------------------------------------------------------------------------------------- 00142 //}---------------------------------------------------------------------------------------------------------------- 00144 00145 #define _TX_VER _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-04-10 21:00:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00146 #define _TX_VERSION _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-04-10 21:00:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00147 #define _TX_AUTHOR _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 173, 2024-04-10 21:00:00 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00148 00150 #define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2) ((0x##ver##u << 16) | 0x##rev##u) 00151 #define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2) "TXLib [Ver: " #ver ", Rev: " #rev ", Date: " #date "]" 00152 #define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2) "Copyright (C) " auth 00153 00154 00156 //{---------------------------------------------------------------------------------------------------------------- 00163 //}---------------------------------------------------------------------------------------------------------------- 00164 00165 #if !defined (_TX_MODULE) 00166 #define _TX_MODULE "TXLib" 00167 #endif 00168 00169 //{---------------------------------------------------------------------------------------------------------------- 00173 //}---------------------------------------------------------------------------------------------------------------- 00174 00175 #if defined (__GNUC__) 00176 00177 #define _GCC_VER ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ ) 00178 00179 #define __TX_COMPILER__ "GNU g++ " TX_QUOTE (__GNUC__) "." \ 00180 TX_QUOTE (__GNUC_MINOR__) "." \ 00181 TX_QUOTE (__GNUC_PATCHLEVEL__) \ 00182 ", std=" TX_QUOTE (__cplusplus) 00183 00184 #elif defined (__clang__) || defined (__clang_major__) 00185 00186 #define _CLANG_VER ( __clang_major__*100 + __clang_minor__*10 + __clang_patchlevel__ ) 00187 00188 #define __TX_COMPILER__ "Clang " TX_QUOTE (__clang_major__) "." \ 00189 TX_QUOTE (__clang_minor__) "." \ 00190 TX_QUOTE (__clang_patchlevel__) \ 00191 ", std=" TX_QUOTE (__cplusplus) 00192 #elif defined (_MSC_VER) 00193 00194 #define __TX_COMPILER__ "MSVS " TX_QUOTE (_MSC_VER) \ 00195 ", std=" TX_QUOTE (__cplusplus) 00196 00197 #elif defined (__INTEL_COMPILER) 00198 00199 #define __TX_COMPILER__ "Intel C++ " TX_QUOTE (__INTEL_COMPILER) \ 00200 ", std=" TX_QUOTE (__cplusplus) 00201 #else 00202 00203 #define __TX_COMPILER__ "Unknown C++, std=" TX_QUOTE (__cplusplus) 00204 #endif 00205 00207 00208 #define TX_QUOTE(sym) _TX_QUOTE (sym) 00209 #define _TX_QUOTE(sym) #sym 00210 00211 #define TX_JOIN(sym1, sym2) _TX_JOIN (sym1, sym2) 00212 #define _TX_JOIN(sym1, sym2) sym1 ## sym2 00213 00215 00216 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 00217 00218 #define _TX_CPP11 1 00219 #endif 00220 00221 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1900) // MSVC 2015 00222 00223 #define _TX_CPP11_MSVC15 1 00224 #endif 00225 00226 //{---------------------------------------------------------------------------------------------------------------- 00230 //}---------------------------------------------------------------------------------------------------------------- 00231 00232 #if !defined (NDEBUG) && defined (_DEBUG) 00233 #define _TX_BUILDMODE "DEBUG" 00234 00235 #elif !defined (NDEBUG) && !defined (_DEBUG) 00236 #define _TX_BUILDMODE "Debug" 00237 00238 #elif defined (NDEBUG) 00239 #define _TX_BUILDMODE "Release" 00240 #endif 00241 00242 //{---------------------------------------------------------------------------------------------------------------- 00246 //}---------------------------------------------------------------------------------------------------------------- 00247 00248 #define __TX_FILELINE__ __FILE__ ":" TX_QUOTE (__LINE__) 00249 00250 //{---------------------------------------------------------------------------------------------------------------- 00258 //}---------------------------------------------------------------------------------------------------------------- 00259 00260 #if defined (__GNUC__) || defined (__clang__) || defined (__clang_major__) 00261 #define __TX_FUNCTION__ __PRETTY_FUNCTION__ 00262 00263 #elif defined (__FUNCSIG__) 00264 #define __TX_FUNCTION__ __FUNCSIG__ 00265 00266 #elif defined (__FUNCTION__) 00267 #define __TX_FUNCTION__ __FUNCTION__ 00268 00269 #elif defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 600) 00270 #define __TX_FUNCTION__ __FUNCTION__ 00271 00272 #elif defined (__BORLANDC__) && (__BORLANDC__ >= 0x550) 00273 #define __TX_FUNCTION__ __FUNC__ 00274 00275 #elif defined (__cplusplus) && (__cplusplus >= 199711L) 00276 #define __TX_FUNCTION__ __func__ 00277 00278 #elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 00279 #define __TX_FUNCTION__ __func__ 00280 00281 #elif defined (__PYTHON__) 00282 #error No Python. No. Using parseltongue languages can lead you to Slytherin. 00283 00284 #else 00285 #define __TX_FUNCTION__ "(" __TX_FILELINE__ ")" 00286 00287 #endif 00288 00289 #if !defined (__func__) && defined (__FUNCTION__) 00290 #define __func__ __FUNCTION__ 00291 00292 #endif 00293 00294 //} 00295 //----------------------------------------------------------------------------------------------------------------- 00296 00297 //----------------------------------------------------------------------------------------------------------------- 00298 //{ Compiler- and platform-specific 00300 //----------------------------------------------------------------------------------------------------------------- 00302 00303 #if !defined (__cplusplus) 00304 00305 #ifdef __GNUC__ 00306 #error 00307 #error --------------------------------------------------------------------------------------- 00308 #endif 00309 #error TXLib.h: Must use C++ to compile TXLib.h. Now you are using C only. 00310 #error 00311 #error CHECK source file EXTENSION. Maybe it is ".C". It must be ".CPP". 00312 #error If your file is named, for example, "Untitled.C", go to menu [File], 00313 #error then [Save As] and rename it to "Untitled.CPP". Please do NOT use spaces. 00314 #error --------------------------------------------------------------------------------------- 00315 #error 00316 00317 #endif 00318 00319 //----------------------------------------------------------------------------------------------------------------- 00320 00321 #if !defined (WIN32) && !defined (__WIN32__) && !defined(_WIN32) && !defined(_WIN32_WINNT) && !defined (__CYGWIN__) 00322 00323 #ifdef __GNUC__ 00324 #error 00325 #error --------------------------------------------------------------------------------------- 00326 #endif 00327 #error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW or Cygwin) is the only supported OS, sorry. 00328 #error 00329 #error In Linux or MacOS, you should write your own TXLib and share it with your friends, or use wine. 00330 #error --------------------------------------------------------------------------------------- 00331 #error 00332 00333 #endif 00334 00335 //----------------------------------------------------------------------------------------------------------------- 00336 00337 #if defined (UNICODE) || defined (_UNICODE) 00338 00339 #ifdef __GNUC__ 00340 #warning TXLib.h: Disabling the UNICODE 00341 #endif 00342 00343 #undef UNICODE // Burn Unicode, burn 00344 #undef _UNICODE 00345 00346 #if defined (_WINDOWS_H) || defined (_INC_WINDOWS) || defined (_WINDOWS_) || defined (__WINDOWS__) 00347 00348 #ifdef __GNUC__ 00349 #error 00350 #error --------------------------------------------------------------------------------------- 00351 #endif 00352 #error TXLib.h: Should include "TXLib.h" BEFORE or INSTEAD of <Windows.h> in UNICODE mode. 00353 #error 00354 #error REARRANGE your #include directives, or DISABLE the UNICODE mode by #undef UNICODE/_UNICODE. 00355 #error --------------------------------------------------------------------------------------- 00356 #error 00357 00358 #endif 00359 00360 #endif 00361 00362 //----------------------------------------------------------------------------------------------------------------- 00363 00364 #if defined (__STRICT_ANSI__) && (_GCC_VER < 1120) // Try to extend strict ANSI rules 00365 00366 #undef __STRICT_ANSI__ 00367 #define __STRICT_ANSI__UNDEFINED 00368 00369 #if defined (_STRING_H_) || defined (_INC_STRING) || defined (_STDIO_H_) || defined (_INC_STDIO) 00370 00371 #ifdef __GNUC__ 00372 #error 00373 #error --------------------------------------------------------------------------------------- 00374 #endif 00375 #error TXLib.h: Should include "TXLib.h" BEFORE <string.h> or <stdio.h> in Strict ANSI mode. 00376 #error 00377 #error REARRANGE your #include directives, or DISABLE ANSI-compliancy by #undef __STRICT_ANSI__. 00378 #error --------------------------------------------------------------------------------------- 00379 #error 00380 00381 #endif 00382 00383 #endif 00384 00385 //----------------------------------------------------------------------------------------------------------------- 00386 00387 #if defined (__GNUC__) 00388 00389 #pragma GCC diagnostic ignored "-Wpragmas" 00390 00391 #pragma GCC diagnostic warning "-Wall" 00392 #pragma GCC diagnostic warning "-Weffc++" 00393 #pragma GCC diagnostic warning "-Wextra" 00394 00395 #pragma GCC diagnostic warning "-Waggressive-loop-optimizations" 00396 #pragma GCC diagnostic warning "-Walloc-zero" 00397 #pragma GCC diagnostic warning "-Walloca" 00398 #pragma GCC diagnostic warning "-Walloca-larger-than=8192" 00399 #pragma GCC diagnostic warning "-Warray-bounds" 00400 #pragma GCC diagnostic warning "-Wcast-align" 00401 #pragma GCC diagnostic warning "-Wcast-qual" 00402 #pragma GCC diagnostic warning "-Wchar-subscripts" 00403 #pragma GCC diagnostic warning "-Wconditionally-supported" 00404 #pragma GCC diagnostic warning "-Wconversion" 00405 #pragma GCC diagnostic warning "-Wctor-dtor-privacy" 00406 #pragma GCC diagnostic warning "-Wdangling-else" 00407 #pragma GCC diagnostic warning "-Wduplicated-branches" 00408 #pragma GCC diagnostic warning "-Wempty-body" 00409 #pragma GCC diagnostic warning "-Wfloat-equal" 00410 #pragma GCC diagnostic warning "-Wformat-nonliteral" 00411 #pragma GCC diagnostic warning "-Wformat-overflow=2" 00412 #pragma GCC diagnostic warning "-Wformat-security" 00413 #pragma GCC diagnostic warning "-Wformat-signedness" 00414 #pragma GCC diagnostic warning "-Wformat-truncation=2" 00415 #pragma GCC diagnostic warning "-Wformat=2" 00416 #pragma GCC diagnostic warning "-Wlarger-than=8192" 00417 #pragma GCC diagnostic warning "-Wlogical-op" 00418 #pragma GCC diagnostic warning "-Wmismatched-tags" 00419 #pragma GCC diagnostic warning "-Wmissing-declarations" 00420 #pragma GCC diagnostic warning "-Wnarrowing" 00421 #pragma GCC diagnostic warning "-Wnon-virtual-dtor" 00422 #pragma GCC diagnostic warning "-Wnonnull" 00423 #pragma GCC diagnostic warning "-Wopenmp-simd" 00424 #pragma GCC diagnostic warning "-Woverloaded-virtual" 00425 #pragma GCC diagnostic warning "-Wpacked" 00426 #pragma GCC diagnostic warning "-Wpointer-arith" 00427 // #pragma GCC diagnostic warning "-Wredundant-decls" 00428 // #pragma GCC diagnostic warning "-Wredundant-tags" 00429 #pragma GCC diagnostic warning "-Wrestrict" 00430 #pragma GCC diagnostic warning "-Wshadow" 00431 #pragma GCC diagnostic warning "-Wsign-promo" 00432 #pragma GCC diagnostic warning "-Wstack-usage=8192" 00433 #pragma GCC diagnostic warning "-Wstrict-aliasing" 00434 #pragma GCC diagnostic warning "-Wstrict-null-sentinel" 00435 #pragma GCC diagnostic warning "-Wstrict-overflow=2" 00436 #pragma GCC diagnostic warning "-Wstringop-overflow=4" 00437 #pragma GCC diagnostic warning "-Wsuggest-attribute=noreturn" 00438 #pragma GCC diagnostic warning "-Wsuggest-final-methods" 00439 #pragma GCC diagnostic warning "-Wsuggest-final-types" 00440 #pragma GCC diagnostic warning "-Wsuggest-override" 00441 #pragma GCC diagnostic warning "-Wswitch-default" 00442 #pragma GCC diagnostic warning "-Wswitch-enum" 00443 #pragma GCC diagnostic warning "-Wsync-nand" 00444 #pragma GCC diagnostic warning "-Wundef" 00445 #pragma GCC diagnostic warning "-Wunused" 00446 #pragma GCC diagnostic warning "-Wvarargs" 00447 #pragma GCC diagnostic warning "-Wvla-larger-than=8192" 00448 00449 #pragma GCC diagnostic error "-Wsizeof-array-argument" 00450 00451 #pragma GCC diagnostic ignored "-Waddress" 00452 #pragma GCC diagnostic ignored "-Winline" 00453 #pragma GCC diagnostic ignored "-Wliteral-suffix" 00454 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 00455 #pragma GCC diagnostic ignored "-Wnonnull-compare" 00456 #pragma GCC diagnostic ignored "-Wold-style-cast" 00457 #pragma GCC diagnostic ignored "-Wunreachable-code" 00458 #pragma GCC diagnostic ignored "-Wunused-const-variable" 00459 #pragma GCC diagnostic ignored "-Wunused-function" 00460 #pragma GCC diagnostic ignored "-Wvariadic-macros" 00461 00462 #pragma GCC diagnostic warning "-Wpragmas" 00463 00464 //{ These warning settings for TXLib.h only and will be re-enabled at end of file: 00465 00466 #pragma GCC push_options 00467 #pragma GCC diagnostic push 00468 00469 #pragma GCC diagnostic ignored "-Wpragmas" 00470 00471 #pragma GCC diagnostic ignored "-Wpedantic" 00472 #pragma GCC diagnostic ignored "-Waddress" 00473 #pragma GCC diagnostic ignored "-Warray-bounds" 00474 #pragma GCC diagnostic ignored "-Wclobbered" 00475 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00476 #pragma GCC diagnostic ignored "-Wfloat-equal" 00477 #pragma GCC diagnostic ignored "-Wformat-nonliteral" 00478 #pragma GCC diagnostic ignored "-Wlarger-than=" 00479 #pragma GCC diagnostic ignored "-Wmisleading-indentation" 00480 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 00481 #pragma GCC diagnostic ignored "-Wredundant-decls" 00482 #pragma GCC diagnostic ignored "-Wshadow" 00483 #pragma GCC diagnostic ignored "-Wsign-conversion" 00484 #pragma GCC diagnostic ignored "-Wstrict-aliasing" 00485 #pragma GCC diagnostic ignored "-Wsuggest-override" 00486 #pragma GCC diagnostic ignored "-Wunused-label" // Just for fun in _txCanvas_OnCmdAbout() 00487 #pragma GCC diagnostic ignored "-Wunused-value" 00488 #pragma GCC diagnostic ignored "-Wformat-zero-length" 00489 #pragma GCC diagnostic ignored "-Wpacked-not-aligned" 00490 #pragma GCC optimize "no-strict-aliasing" 00491 00492 #pragma GCC diagnostic warning "-Wpragmas" 00493 00494 #if defined (__CYGWIN__) && !defined (_TX_TESTING) 00495 #pragma GCC system_header // This is not a fair play, but this is the only way to deal with Cygwin :( 00496 #endif 00497 00498 //} 00499 00500 #define _tx_thread __thread 00501 #define _tx_decltype(value) __decltype (value) 00502 00503 #define _FORTIFY_SOURCE 2 00504 00505 #ifndef MINGW_HAS_SECURE_API 00506 #define MINGW_HAS_SECURE_API 1 00507 #endif 00508 00509 #if defined (TX_USE_SFML) 00510 #define _GLIBCXX_NDEBUG 00511 #endif 00512 00513 #ifndef _GLIBCXX_NDEBUG // TXLib enables _GLIBCXX_DEBUG by default. When using third-party libraries 00514 #define _GLIBCXX_DEBUG // compiled without _GLIBCXX_DEBUG (SFML, for example), #define _GLIBCXX_NDEBUG 00515 #define _GLIBCXX_DEBUG_PEDANTIC // *before* including TXLib.h. 00516 #endif 00517 00518 #if defined (_WIN64) // removed in x86 because printf ("%g", double) failure, this prints 0 always 00519 #ifndef __USE_MINGW_ANSI_STDIO 00520 #define __USE_MINGW_ANSI_STDIO 1 00521 #endif 00522 #endif 00523 00524 template <typename T> 00525 inline T _txNOP (T value) { return value; } // To suppress performance warnings in assert etc. 00526 00527 // From MinGW\include\float.h which is replaced by MinGW\lib\gcc\i686-pc-mingw32\x.x.x\include\float.h 00528 extern "C" __declspec (dllimport) unsigned __cdecl _controlfp (unsigned control, unsigned mask); 00529 extern "C" void __cdecl _fpreset (); 00530 00531 #else 00532 00533 #define __attribute__( attr ) 00534 #define _txNOP( value ) ( value ) 00535 00536 #endif 00537 00538 //----------------------------------------------------------------------------------------------------------------- 00539 00540 #if defined (__clang__) || defined (__clang_major__) 00541 00542 #pragma clang diagnostic ignored "-Wunknown-pragmas" 00543 00544 #pragma clang diagnostic warning "-Wall" 00545 #pragma clang diagnostic warning "-Weffc++" 00546 #pragma clang diagnostic warning "-Wextra" 00547 00548 #pragma clang diagnostic warning "-Wcast-qual" 00549 #pragma clang diagnostic warning "-Wchar-subscripts" 00550 #pragma clang diagnostic warning "-Wconversion" 00551 #pragma clang diagnostic warning "-Wctor-dtor-privacy" 00552 #pragma clang diagnostic warning "-Wempty-body" 00553 #pragma clang diagnostic warning "-Wfloat-equal" 00554 #pragma clang diagnostic warning "-Wformat" 00555 #pragma clang diagnostic warning "-Wformat-nonliteral" 00556 #pragma clang diagnostic warning "-Wformat-security" 00557 #pragma clang diagnostic warning "-Wmissing-declarations" 00558 #pragma clang diagnostic warning "-Wnon-virtual-dtor" 00559 #pragma clang diagnostic warning "-Woverloaded-virtual" 00560 #pragma clang diagnostic warning "-Wpacked" 00561 #pragma clang diagnostic warning "-Wpointer-arith" 00562 #pragma clang diagnostic warning "-Wredundant-decls" 00563 #pragma clang diagnostic warning "-Wshadow" 00564 #pragma clang diagnostic warning "-Wsign-promo" 00565 #pragma clang diagnostic warning "-Wstrict-aliasing" 00566 #pragma clang diagnostic warning "-Wstrict-overflow" 00567 #pragma clang diagnostic warning "-Wswitch-default" 00568 #pragma clang diagnostic warning "-Wswitch-enum" 00569 #pragma clang diagnostic warning "-Wunused" 00570 00571 #pragma clang diagnostic ignored "-Winvalid-source-encoding" 00572 #pragma clang diagnostic ignored "-Wunused-const-variable" 00573 #pragma clang diagnostic ignored "-Wunused-variable" 00574 00575 #pragma clang diagnostic warning "-Wunknown-pragmas" 00576 00577 //{ These warning settings for TXLib.h only and will be re-enabled at end of file: 00578 00579 #pragma clang diagnostic push 00580 00581 #pragma clang diagnostic ignored "-Wunknown-pragmas" 00582 00583 #pragma clang diagnostic ignored "-Wpedantic" 00584 #pragma clang diagnostic ignored "-Wcast-align" 00585 #pragma clang diagnostic ignored "-Wfloat-conversion" 00586 #pragma clang diagnostic ignored "-Wmicrosoft-cast" 00587 #pragma clang diagnostic ignored "-Wmisleading-indentation" 00588 #pragma clang diagnostic ignored "-Wmissing-braces" 00589 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 00590 #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 00591 #pragma clang diagnostic ignored "-Wsign-compare" 00592 #pragma clang diagnostic ignored "-Wsign-conversion" 00593 #pragma clang diagnostic ignored "-Wstring-plus-int" 00594 #pragma clang diagnostic ignored "-Wundef" 00595 #pragma clang diagnostic ignored "-Wundefined-bool-conversion" 00596 #pragma clang diagnostic ignored "-Wunused-function" 00597 #pragma clang diagnostic ignored "-Wunused-value" 00598 #pragma clang diagnostic ignored "-Wvariadic-macros" 00599 00600 #pragma clang diagnostic warning "-Wunknown-pragmas" 00601 00602 //{ CLang-Tidy options 00603 // 00604 // *,-cert-dcl50-cpp,-cert-dcl58-cpp,-cert-err52-cpp,-cert-err58-cpp,-cert-flp30-c,-cert-msc30-c,-cert-msc32-c, 00605 // -cert-msc50-cpp,-cert-msc51-cpp,-clang-analyzer-core.DivideZero,-cppcoreguidelines-avoid-c-arrays, 00606 // -cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage, 00607 // -cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-no-malloc, 00608 // -cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic, 00609 // -cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access, 00610 // -cppcoreguidelines-pro-type-vararg,-fuchsia-default-arguments-calls,-fuchsia-default-arguments-declarations, 00611 // -fuchsia-overloaded-operator,-google-build-using-namespace,-google-global-names-in-headers,-google-runtime-int, 00612 // -google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments, 00613 // -hicpp-avoid-c-arrays,-hicpp-avoid-goto,-hicpp-braces-around-statements,-hicpp-deprecated-headers,-hicpp-no-array-decay, 00614 // -hicpp-signed-bitwise,-hicpp-use-equals-delete,-hicpp-use-nullptr,-hicpp-vararg,-llvm-include-order,-hicpp-no-malloc, 00615 // -llvm-namespace-comment,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-use-auto, 00616 // -modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-use-default-member-init,-hicpp-use-auto, 00617 // -modernize-use-equals-delete,-modernize-use-nullptr,-modernize-use-trailing-return-type,-modernize-use-using, 00618 // -readability-braces-around-statements,-readability-else-after-return,-readability-implicit-bool-conversion, 00619 // -readability-isolate-declaration,-readability-magic-numbers,-readability-named-parameter,-modernize-loop-convert 00620 //} 00621 00622 //} 00623 00624 #endif 00625 00626 //----------------------------------------------------------------------------------------------------------------- 00627 00628 #if defined (_MSC_VER) 00629 00630 #pragma warning (push, 4) // Set maximum warning level. This 'push' is to set the level only. It will NOT be popped. 00631 00632 #pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning 00633 00634 #pragma warning (disable: 4514) // Unreferenced inline function has been removed 00635 #pragma warning (disable: 4710) // Function not inlined 00636 #pragma warning (disable: 4786) // Identifier was truncated to '255' characters in the debug information 00637 00638 #pragma warning (error: 4715) // Not all control paths return a value 00639 00640 #pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665 00641 00642 #pragma warning (disable: 26473) // Don't cast between pointer types where the source type and the target type are the same (type.1). 00643 #pragma warning (disable: 26475) // Do not use function style C-casts (es.49). 00644 #pragma warning (disable: 26477) // Use 'nullptr' rather than 0 or NULL (es.47). 00645 #pragma warning (disable: 26481) // Don't use pointer arithmetic. Use span instead (bounds.1). 00646 #pragma warning (disable: 26826) // Don't use C-style variable arguments (f.55). 00647 00648 // These warning settings for TXLib.h only and will be re-enabled at end of file: 00649 00650 #pragma warning (push) 00651 00652 #pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning 00653 00654 #pragma warning (disable: 4091) // 'typedef': ignored on left of '...' when no variable is declared 00655 #pragma warning (disable: 4124) // Using __fastcall with stack checking is ineffective 00656 #pragma warning (disable: 4127) // Conditional expression is constant 00657 #pragma warning (disable: 4200) // Nonstandard extension used: zero-sized array in struct/union 00658 #pragma warning (disable: 4201) // Nonstandard extension used: nameless struct/union 00659 #pragma warning (disable: 4351) // New behavior: elements of array will be default initialized 00660 #pragma warning (disable: 4480) // Nonstandard extension used: specifying underlying type for enum 'type' 00661 #pragma warning (disable: 4481) // Nonstandard extension used: override specifier 'override' 00662 #pragma warning (disable: 4555) // Result of expression not used 00663 #pragma warning (disable: 4611) // Interaction between '_setjmp' and C++ object destruction is non-portable 00664 #pragma warning (disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified 00665 #pragma warning (disable: 6269) // Possibly incorrect order of operations: dereference ignored 00666 #pragma warning (disable: 6285) // (<non-zero constant>) || (<non-zero constant>) is always a non-zero constant. Did you intend to use bitwize-and operator? 00667 #pragma warning (disable: 6319) // Use of the comma-operator in a tested expression causes the left argument to be ignored when it has no side-effects 00668 #pragma warning (disable: 6326) // Potential comparison of a constant with another constant 00669 #pragma warning (disable: 6553) // The annotation for function 'func' on _Param_(N) does not apply to a value type. 00670 #pragma warning (disable: 26135) // Missing locking annotation 00671 #pragma warning (disable: 26400) // Do not assign the result of an allocation or a function call with an owner<T> return value to a raw pointer, use owner<T> instead (i.11). 00672 #pragma warning (disable: 26401) // Do not delete a raw pointer that is not an owner<T> (i.11). 00673 #pragma warning (disable: 26403) // Reset or explicitly delete an owner<T> pointer 'name' (r.3). 00674 #pragma warning (disable: 26408) // Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10). 00675 #pragma warning (disable: 26409) // Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11). 00676 #pragma warning (disable: 26426) // Global initializer calls a non-constexpr function 'name' (i.22). 00677 #pragma warning (disable: 26429) // Symbol 'name' is never tested for nullness, it can be marked as not_null (f.23). 00678 #pragma warning (disable: 26430) // Symbol 'name' is not tested for nullness on all paths (f.23). 00679 #pragma warning (disable: 26432) // If you define or delete any default operation in the type 'struct 'name'', define or delete them all (c.21). 00680 #pragma warning (disable: 26435) // Function 'name' should specify exactly one of 'virtual', 'override', or 'final' (c.128). 00681 #pragma warning (disable: 26438) // Avoid 'goto' (es.76). 00682 #pragma warning (disable: 26440) // Function 'name' can be declared 'noexcept' (f.6). 00683 #pragma warning (disable: 26446) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4). 00684 #pragma warning (disable: 26447) // The function is declared 'noexcept' but calls function 'func' which may throw exceptions (f.6). 00685 #pragma warning (disable: 26448) // Consider using gsl::finally if final action is intended (gsl.util). 00686 #pragma warning (disable: 26451) // Arithmetic overflow: Using operator 'op' on a n-byte value and then casting the result to a m-byte value. Cast the value to the wider type before calling operator 'op' to avoid overflow (io.2). 00687 #pragma warning (disable: 26455) // Default constructor may not throw. Declare it 'noexcept' (f.6). 00688 #pragma warning (disable: 26457) // (void) should not be used to ignore return values, use 'std::ignore =' instead (es.48) 00689 #pragma warning (disable: 26460) // The reference argument 'stream' for function 'name' can be marked as const (con.3). 00690 #pragma warning (disable: 26461) // The pointer argument 'name' for function 'name' can be marked as a pointer to const (con.3). 00691 #pragma warning (disable: 26462) // The value pointed to by 'name' is assigned only once, mark it as a pointer to const (con.4). 00692 #pragma warning (disable: 26482) // Only index into arrays using constant expressions (bounds.2). 00693 #pragma warning (disable: 26483) // Value 'value' is outside the bounds (min, max) of variable 'name'. Only index into arrays using constant expressions that are within bounds of the array (bounds.2). 00694 #pragma warning (disable: 26485) // Expression 'expr': No array to pointer decay (bounds.3). 00695 #pragma warning (disable: 26486) // Don't pass a pointer that may be invalid to a function. Parameter 'n' 'name' in call to 'name' may be invalid (lifetime.3). 00696 #pragma warning (disable: 26487) // Don't return a pointer 'name' that may be invalid (lifetime.4). 00697 #pragma warning (disable: 26488) // Do not dereference a potentially null pointer: 'name'. 'name' was null at line 'n' (lifetime.1). 00698 #pragma warning (disable: 26489) // Don't dereference a pointer that may be invalid: 'name'. 'name' may have been invalidated at line 'n' (lifetime.1). 00699 #pragma warning (disable: 26490) // Don't use reinterpret_cast (type.1). 00700 #pragma warning (disable: 26492) // Don't use const_cast to cast away const or volatile (type.3). 00701 #pragma warning (disable: 26493) // Don't use C-style casts (type.4). 00702 #pragma warning (disable: 26496) // The variable 'name' is assigned only once, mark it as const (con.4). 00703 #pragma warning (disable: 26497) // The function 'name' could be marked constexpr if compile-time evaluation is desired (f.4). 00704 #pragma warning (disable: 26812) // The enum type 'type' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). 00705 #pragma warning (disable: 26814) // The const variable 'name' can be computed at compile-time. Consider using constexpr (con.5). 00706 #pragma warning (disable: 26822) // Dereferencing a possibly null pointer '...' (lifetime.1). 00707 #pragma warning (disable: 26823) // Dereferencing a possibly null pointer '...' (lifetime.1). 00708 #pragma warning (disable: 28125) // The function must be called from within a try/except block 00709 #pragma warning (disable: 28159) // Consider using another function instead 00710 00711 #pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665 00712 00713 #define _tx_thread __declspec (thread) 00714 #define _tx_decltype(value) decltype (value) 00715 00716 #if !defined (_CLANG_VER) 00717 00718 #pragma setlocale ("russian") // Set source file encoding, see also _TX_CODEPAGE 00719 00720 #if !defined (NDEBUG) 00721 #pragma check_stack ( on) // Turn on stack probes at runtime 00722 #pragma strict_gs_check (push, on) // Detects stack buffer overruns 00723 #endif 00724 00725 #endif 00726 00727 #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 00728 00729 #endif 00730 00731 //----------------------------------------------------------------------------------------------------------------- 00732 00733 #if defined (__INTEL_COMPILER) 00734 00735 #pragma warning (disable: 174) // Remark: expression has no effect 00736 #pragma warning (disable: 304) // Remark: access control not specified ("public" by default) 00737 #pragma warning (disable: 444) // Remark: destructor for base class "..." is not virtual 00738 #pragma warning (disable: 522) // Remark: function "..." redeclared "inline" after being called 00739 #pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order 00740 #pragma warning (disable: 1684) // Conversion from pointer to same-sized integral type (potential portability problem) 00741 00742 #endif 00743 00744 //----------------------------------------------------------------------------------------------------------------- 00745 00746 #if (defined (_GCC_VER) && (_GCC_VER < 472) || \ 00747 defined (_MSC_VER) && (_MSC_VER < 1600)) // Minimum requirements are now GCC 4.7.2 or MSVC 10.0 (2010) 00748 00749 #ifdef __GNUC__ 00750 #error 00751 #error --------------------------------------------------------------------------------------- 00752 #endif 00753 #error TXLib.h: This version will NOT work with GCC < 4.7.2 or MS Visual Studio < 2010, sorry. 00754 #error 00755 #error Please use TXLib.h previous stable version/revision OR upgrade your compiler. 00756 #error --------------------------------------------------------------------------------------- 00757 #error 00758 00759 #endif 00760 00761 //----------------------------------------------------------------------------------------------------------------- 00762 00763 #if defined (_GCC_VER) && (_GCC_VER >= 492) 00764 #if defined (TX_USE_SPEAK) && !__has_include (<SAPI.h>) 00765 00766 #ifdef __GNUC__ 00767 #error 00768 #error --------------------------------------------------------------------------------------- 00769 #endif 00770 #error You have defined TX_USE_SPEAK, but your compiler do NOT have the library <SAPI.h>. 00771 #error 00772 #error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API 00773 #error nesessary for txSpeak() to work. 00774 #error --------------------------------------------------------------------------------------- 00775 #error 00776 00777 #endif 00778 #endif 00779 00780 //----------------------------------------------------------------------------------------------------------------- 00781 00782 #if !defined (WINVER) 00783 #define WINVER 0x0500 // Defaults to Windows 2000 00784 #define WINDOWS_ENABLE_CPLUSPLUS // Allow use of type-limit macros in <basetsd.h>, 00785 #endif // they are allowed by default if WINVER >= 0x0600. 00786 00787 #if !defined (_WIN32_WINNT) 00788 #define _WIN32_WINNT WINVER // Defaults to the same as WINVER 00789 #endif 00790 00791 #if !defined (_WIN32_IE) 00792 #define _WIN32_IE WINVER // Defaults to the same as WINVER 00793 #endif 00794 00795 #define stristr( str1, str2 ) Win32::StrStrIA ((str1), (str2)) 00796 #define stristrw( str1, str2 ) Win32::StrStrIW ((str1), (str2)) 00797 00798 //----------------------------------------------------------------------------------------------------------------- 00799 00800 #define _USE_MATH_DEFINES 1 // Math.h's M_PI etc. 00801 #define __STDC_FORMAT_MACROS 1 // PRIu64 and other PR... macros 00802 #define __STDC_WANT_LIB_EXT1__ 1 // String and output *_s functions 00803 00804 #define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS // Wow, how long. Kudos, Clang 00805 00806 #define _ALLOW_RTCc_IN_STL 1 // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc. 00807 00808 #define NOMINMAX 1 // Preventing 'min' and 'max' defines in Windows.h 00809 00810 #if defined (_DEBUG) 00811 #define _SECURE_SCL 1 // Enable checked STL iterators to throw an exception on incorrect use 00812 #define _HAS_ITERATOR_DEBUGGING 1 00813 #define _LIBCPP_DEBUG 1 00814 #endif 00815 00816 #if defined (_MSC_VER) && defined (_DEBUG) 00817 00818 #define _CRTDBG_MAP_ALLOC // Enable MSVCRT debug heap 00819 #define _new_dbg new (_NORMAL_BLOCK, __FILE__, __LINE__) 00820 #define NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) 00821 00822 #else 00823 #define _new_dbg new 00824 #define NEW new 00825 00826 #endif 00827 00828 #if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015 00829 #define _SECURE_SCL_THROWS 1 00830 #endif 00831 00832 #define tx_noreturn __attribute__ (( noreturn )) 00833 #define tx_nodiscard __attribute__ (( warn_unused_result )) 00834 #define tx_deprecated __attribute__ (( deprecated )) 00835 #define tx_printfy( formatArgN ) __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) )) 00836 #define tx_scanfy( formatArgN ) __attribute__ (( format (scanf, (formatArgN), (formatArgN)+1) )) 00837 00838 00839 #if defined (_TX_CPP11) 00840 00841 #define _tx_delete = delete 00842 #define _tx_default = default 00843 #define _tx_override override 00844 #define _tx_final final 00845 00846 #else 00847 00848 #define _tx_delete 00849 #define _tx_default 00850 #define _tx_override 00851 #define _tx_final 00852 00853 #endif 00854 00855 namespace std { enum nomeow_t { nomeow }; } // Vital addition to the C++ standard. TODO: Should contact C++ std committee. 00856 00857 //----------------------------------------------------------------------------------------------------------------- 00858 00860 //} 00861 //----------------------------------------------------------------------------------------------------------------- 00862 00863 //----------------------------------------------------------------------------------------------------------------- 00864 //{ The Includes 00865 //----------------------------------------------------------------------------------------------------------------- 00866 00867 #if defined (_MSC_VER) 00868 #pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o 00869 00870 #pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch 00871 #pragma warning (disable: 4005) // 'name': macro redefinition 00872 #endif 00873 00874 //----------------------------------------------------------------------------------------------------------------- 00875 00876 #include <stdlib.h> 00877 #include <stdio.h> 00878 #include <string.h> 00879 #include <time.h> 00880 #include <math.h> 00881 #include <float.h> 00882 00883 #include <vector> 00884 #include <string> 00885 #include <iostream> 00886 #include <sstream> 00887 #include <iomanip> 00888 00889 #if !defined (__CYGWIN__) 00890 #include <conio.h> 00891 #include <direct.h> 00892 #endif 00893 00894 #if defined (TX_COMPILED) 00895 #define WIN32_LEAN_AND_MEAN 00896 #endif 00897 00898 #include <windows.h> 00899 #include <mmsystem.h> 00900 00901 //----------------------------------------------------------------------------------------------------------------- 00902 //{ Compiler- and platform-specific 00904 //----------------------------------------------------------------------------------------------------------------- 00905 00906 #if defined (_MSC_VER) 00907 #pragma warning (pop) // MSVC: Restore max level 00908 #endif 00909 00910 #if defined (__STRICT_ANSI__UNDEFINED) 00911 #define __STRICT_ANSI__ // Redefine back 00912 #endif 00913 00914 #if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED) 00915 00916 #define strncpy_s( dest, sizeof_dest, src, count ) ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) ) 00917 #define wcsncpy_s( dest, sizeof_dest, src, count ) ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) ) 00918 #define strncat_s( dest, sizeof_dest, src, count ) ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) ) 00919 #define strerror_s( buf, sizeof_buf, code ) ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) ) 00920 #define strtok_s( buf, delim, ctx ) ( (void)(ctx), strtok ((buf), (delim)) ) 00921 #define fopen_s( file, name, mode ) ( *(file) = fopen ((name), (mode)) ) 00922 #define _strlwr_s( str, sizeof_str ) ( _strlwr (str) ) 00923 00924 #define ctime_s( buf, sizeof_buf, time ) ( strncpy ((buf), ctime (time), (sizeof_buf)-1) ) 00925 #define _controlfp_s( oldCtl, newCtl, mask ) ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 ) 00926 00927 #define _snprintf_s snprintf 00928 #define _vsnprintf_s( str, sz, trunc, format, arg ) _vsnprintf (str, sz, format, arg) 00929 00930 #endif 00931 00932 #if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) ) 00933 00934 #define getenv_s( sz, buf, sizeof_buf, name ) ( (void)(sz), strncpy ((buf), getenv (name), (sizeof_buf)-1) ) 00935 00936 #endif 00937 00938 #if defined (__CYGWIN__) 00939 00940 #undef __STRICT_ANSI__ 00941 00942 typedef void _exception; 00943 00944 #define _O_TEXT O_TEXT 00945 #define _fdopen fdopen 00946 #define _flushall() fflush (NULL) 00947 #define _getcwd getcwd 00948 #define _getpid getpid 00949 #define _stricmp strcasecmp 00950 #define _strlwr strlwr 00951 #define _strnicmp strncasecmp 00952 #define _unlink unlink 00953 #define _vsnprintf vsnprintf 00954 #define _access access 00955 #define _strdup strdup 00956 00957 #define getch _getch 00958 #define putch _putch 00959 #define kbhit _kbhit 00960 00961 #endif 00962 00963 #if !defined (PRId64) || \ 00964 defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32 00965 00966 #undef PRId64 00967 #undef PRIi64 00968 #undef PRIo64 00969 #undef PRIu64 00970 #undef PRIx64 00971 #undef PRIX64 00972 00973 #define PRId64 "I64d" 00974 #define PRIi64 "I64i" 00975 #define PRIo64 "I64o" 00976 #define PRIu64 "I64u" 00977 #define PRIx64 "I64x" 00978 #define PRIX64 "I64X" 00979 00980 #endif 00981 00982 //} 00983 //----------------------------------------------------------------------------------------------------------------- 00984 00985 //} 00986 //----------------------------------------------------------------------------------------------------------------- 00987 00988 //----------------------------------------------------------------------------------------------------------------- 00989 //{ The namespaces 00990 //----------------------------------------------------------------------------------------------------------------- 00991 00992 //{---------------------------------------------------------------------------------------------------------------- 00995 //}---------------------------------------------------------------------------------------------------------------- 00996 00997 #ifdef FOR_DOXYGEN_ONLY 00998 namespace { namespace TX { }} 00999 #endif 01000 01003 //----------------------------------------------------------------------------------------------------------------- 01004 01005 #if defined (TX_COMPILED) && defined (TX_COMPILING) 01006 #undef TX_COMPILED 01007 #endif 01008 01009 #if !defined (TX_COMPILED) && !defined (TX_COMPILING) 01010 01011 #define _TX_BEGIN_NAMESPACE namespace { namespace TX { 01012 #define _TX_END_NAMESPACE } } 01013 01014 #else 01015 01016 #define _TX_BEGIN_NAMESPACE namespace TX { 01017 #define _TX_END_NAMESPACE } 01018 01019 #endif 01020 01021 //----------------------------------------------------------------------------------------------------------------- 01022 01023 _TX_BEGIN_NAMESPACE 01024 01027 //} 01028 //----------------------------------------------------------------------------------------------------------------- 01029 01030 //================================================================================================================= 01031 //{ TXLIB INTERFACE 01032 // Интерфейс библиотеки 01033 //================================================================================================================= 01034 01035 //================================================================================================================= 01036 //{ Initialization 01038 //================================================================================================================= 01040 //{---------------------------------------------------------------------------------------------------------------- 01084 //}---------------------------------------------------------------------------------------------------------------- 01085 01086 HWND txCreateWindow (double sizeX, double sizeY, bool centered = true); 01087 01088 //{---------------------------------------------------------------------------------------------------------------- 01115 //}---------------------------------------------------------------------------------------------------------------- 01116 01117 inline HDC& txDC() tx_nodiscard; 01118 01119 //{---------------------------------------------------------------------------------------------------------------- 01155 //}---------------------------------------------------------------------------------------------------------------- 01156 01157 inline RGBQUAD* txVideoMemory() tx_nodiscard; 01158 01159 //{---------------------------------------------------------------------------------------------------------------- 01178 //}---------------------------------------------------------------------------------------------------------------- 01179 01180 bool txSetDefaults (HDC dc = txDC()); 01181 01182 //{---------------------------------------------------------------------------------------------------------------- 01201 //}---------------------------------------------------------------------------------------------------------------- 01202 01203 inline bool txOK() tx_nodiscard; 01204 01205 //{---------------------------------------------------------------------------------------------------------------- 01237 //}---------------------------------------------------------------------------------------------------------------- 01238 01239 POINT txGetExtent (HDC dc = txDC()) tx_nodiscard; 01240 01241 //{---------------------------------------------------------------------------------------------------------------- 01258 //}---------------------------------------------------------------------------------------------------------------- 01259 01260 inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard; 01261 01262 //{---------------------------------------------------------------------------------------------------------------- 01280 //}---------------------------------------------------------------------------------------------------------------- 01281 01282 inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard; 01283 01284 //{---------------------------------------------------------------------------------------------------------------- 01296 //}---------------------------------------------------------------------------------------------------------------- 01297 01298 inline HWND txWindow() tx_nodiscard; 01299 01300 //{---------------------------------------------------------------------------------------------------------------- 01309 //}---------------------------------------------------------------------------------------------------------------- 01310 01311 inline const char* txVersion() tx_nodiscard; 01312 01313 //{---------------------------------------------------------------------------------------------------------------- 01322 //}---------------------------------------------------------------------------------------------------------------- 01323 01324 inline unsigned txVersionNumber() tx_nodiscard; 01325 01326 //{---------------------------------------------------------------------------------------------------------------- 01356 //}---------------------------------------------------------------------------------------------------------------- 01357 01358 const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard; 01359 01361 //{---------------------------------------------------------------------------------------------------------------- 01396 //}---------------------------------------------------------------------------------------------------------------- 01397 01398 int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает", 01399 unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL); 01400 01401 //{---------------------------------------------------------------------------------------------------------------- 01418 //}---------------------------------------------------------------------------------------------------------------- 01419 01420 HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL); 01421 01422 //} 01423 //================================================================================================================= 01424 01425 //================================================================================================================= 01426 //{ Setting the parameters 01428 //================================================================================================================= 01430 //{---------------------------------------------------------------------------------------------------------------- 01456 //}---------------------------------------------------------------------------------------------------------------- 01457 01458 const COLORREF 01459 #ifdef FOR_DOXYGEN_ONLY 01460 enum txColors { 01461 #endif 01462 01463 TX_BLACK = RGB ( 0, 0, 0), 01464 TX_BLUE = RGB ( 0, 0, 128), 01465 TX_GREEN = RGB ( 0, 128, 0), 01466 TX_CYAN = RGB ( 0, 128, 128), 01467 TX_RED = RGB (128, 0, 0), 01468 TX_MAGENTA = RGB (128, 0, 128), 01469 TX_BROWN = RGB (128, 128, 0), 01470 TX_ORANGE = RGB (255, 128, 0), 01471 TX_GRAY = RGB (160, 160, 160), 01472 TX_DARKGRAY = RGB (128, 128, 128), 01473 TX_LIGHTGRAY = RGB (192, 192, 192), 01474 TX_LIGHTBLUE = RGB ( 0, 0, 255), 01475 TX_LIGHTGREEN = RGB ( 0, 255, 128), 01476 TX_LIGHTCYAN = RGB ( 0, 255, 255), 01477 TX_LIGHTRED = RGB (255, 0, 128), 01478 TX_LIGHTMAGENTA = RGB (255, 0, 255), 01479 TX_PINK = RGB (255, 128, 255), 01480 TX_YELLOW = RGB (255, 255, 128), 01481 TX_WHITE = RGB (255, 255, 255), 01482 TX_TRANSPARENT = 0xFFFFFFFF, 01483 TX_NULL = TX_TRANSPARENT, 01484 TX_BLM = TX_BLACK, 01485 TX_white = TX_WHITE, 01486 01487 // Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB() 01488 01489 TX_HUE = 0x04000000, 01490 TX_SATURATION = 0x05000000, 01491 TX_LIGHTNESS = 0x06000000; 01492 01493 #ifdef FOR_DOXYGEN_ONLY 01494 }; 01495 #endif 01496 01498 #define TX_GREY TX_GRAY 01499 #define TX_DARKGREY TX_DARKGRAY 01500 #define TX_LIGHTGREY TX_LIGHTGRAY 01501 01502 01503 //{---------------------------------------------------------------------------------------------------------------- 01528 //}---------------------------------------------------------------------------------------------------------------- 01529 01530 #ifdef FOR_DOXYGEN_ONLY 01531 COLORREF RGB (int red, int green, int blue); 01532 #endif 01533 01534 //{---------------------------------------------------------------------------------------------------------------- 01553 //}---------------------------------------------------------------------------------------------------------------- 01554 01555 HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC()); 01556 01558 #define txSetColour txSetColor 01559 01560 01562 01563 //{---------------------------------------------------------------------------------------------------------------- 01574 //}---------------------------------------------------------------------------------------------------------------- 01575 01576 COLORREF txColor (double red, double green, double blue); 01577 01579 01580 //{---------------------------------------------------------------------------------------------------------------- 01593 //}---------------------------------------------------------------------------------------------------------------- 01594 01595 COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard; 01596 01597 //{---------------------------------------------------------------------------------------------------------------- 01612 //}---------------------------------------------------------------------------------------------------------------- 01613 01614 HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC()); 01615 01617 #define txSetFillColour txSetFillColor 01618 01619 01621 01622 //{---------------------------------------------------------------------------------------------------------------- 01633 //}---------------------------------------------------------------------------------------------------------------- 01634 01635 COLORREF txFillColor (double red, double green, double blue); 01636 01638 01639 //{---------------------------------------------------------------------------------------------------------------- 01652 //}---------------------------------------------------------------------------------------------------------------- 01653 01654 COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard; 01655 01656 //{---------------------------------------------------------------------------------------------------------------- 01674 //}---------------------------------------------------------------------------------------------------------------- 01675 01676 unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard; 01677 01678 //{---------------------------------------------------------------------------------------------------------------- 01706 //}---------------------------------------------------------------------------------------------------------------- 01707 01708 COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard; 01709 01710 //{---------------------------------------------------------------------------------------------------------------- 01740 //}---------------------------------------------------------------------------------------------------------------- 01741 01742 COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard; 01743 01745 //} 01746 //================================================================================================================= 01747 01748 //================================================================================================================= 01749 //{ Drawing 01751 //================================================================================================================= 01753 //{---------------------------------------------------------------------------------------------------------------- 01767 //}---------------------------------------------------------------------------------------------------------------- 01768 01769 bool txClear (HDC dc = txDC()); 01770 01771 //{---------------------------------------------------------------------------------------------------------------- 01789 //}---------------------------------------------------------------------------------------------------------------- 01790 01791 inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC()); 01792 01794 01795 //{---------------------------------------------------------------------------------------------------------------- 01813 //}---------------------------------------------------------------------------------------------------------------- 01814 01815 inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC()); 01816 01818 01819 //{---------------------------------------------------------------------------------------------------------------- 01837 //}---------------------------------------------------------------------------------------------------------------- 01838 01839 inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard; 01840 01841 //{---------------------------------------------------------------------------------------------------------------- 01861 //}---------------------------------------------------------------------------------------------------------------- 01862 01863 bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01864 01865 //{---------------------------------------------------------------------------------------------------------------- 01887 //}---------------------------------------------------------------------------------------------------------------- 01888 01889 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01890 01891 //{---------------------------------------------------------------------------------------------------------------- 01911 //}---------------------------------------------------------------------------------------------------------------- 01912 01913 bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC()); 01914 01915 //{---------------------------------------------------------------------------------------------------------------- 01935 //}---------------------------------------------------------------------------------------------------------------- 01936 01937 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01938 01939 //{---------------------------------------------------------------------------------------------------------------- 01957 //}---------------------------------------------------------------------------------------------------------------- 01958 01959 bool txCircle (double x, double y, double r); 01960 01961 //{---------------------------------------------------------------------------------------------------------------- 01984 //}---------------------------------------------------------------------------------------------------------------- 01985 01986 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 01987 01988 //{---------------------------------------------------------------------------------------------------------------- 02011 //}---------------------------------------------------------------------------------------------------------------- 02012 02013 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 02014 02015 //{---------------------------------------------------------------------------------------------------------------- 02038 //}---------------------------------------------------------------------------------------------------------------- 02039 02040 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 02041 02042 //{---------------------------------------------------------------------------------------------------------------- 02074 //}---------------------------------------------------------------------------------------------------------------- 02075 02076 bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC()); 02077 02078 //{---------------------------------------------------------------------------------------------------------------- 02096 //}---------------------------------------------------------------------------------------------------------------- 02097 02098 inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3) 02099 { 02100 (void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3; 02101 02102 txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n" 02103 "Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами " 02104 "как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". " 02105 "Ну или нарисовать тремя линиями. :)", "TXLib сообщает"); 02106 return false; 02107 } 02108 02109 //{---------------------------------------------------------------------------------------------------------------- 02111 02112 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3); 02113 02114 #define txRectandle Sleep (1000), txRectangle // Copy-protection for the function below 02115 #define txLine(...) txLine (__VA_ARGS__); { // 02116 #define txNotifyIcon }}}}}}}}}} txNotifyIcon // Не спрашивайте, зачем. Это дичь. 02117 #define txCircle ;txCircle // 02118 #define txSetColor ;txSetColor // 02119 #define C0L0RREF COLORREF // 02120 #define OxFFFFFF 0xFFFFFF // 02121 #define lO 10 // 02122 #define lOOO 1000 // 02123 #define oo // 02124 #define O // 02125 02127 //} 02128 02129 //{---------------------------------------------------------------------------------------------------------------- 02170 //}----------------------------------------------------------------------------------------------------------------////// 02171 // 02172 inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist, // 02173 double head, double eyes, double wink, double crazy, double smile, double hair, double wind) // 02174 { // 02175 const char __[] = "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/"; // 02176 // | | | | // 02177 // Не копипастите! _/ \_ Все равно не получится! :) _/ \_ Человечки защищают _/ \_ этот код! :) _/ \_ Муаххаха! // 02178 // // 02179 static int count = GetTickCount(), L = 0; 02180 02181 C0L0RREF lineColor = txGetColor(); 02182 C0L0RREF fillColor = txGetFillColor(); 02183 02184 txSetColor (color, 3); 02185 txSetFillColor (color); 02186 02187 txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY); 02188 02189 txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY); 02190 txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY); 02191 02192 txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y); 02193 txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y); 02194 02195 txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY); 02196 02197 txLine (x, y - (1 + head) * sizeY, x + wind/lO * sizeX, y - (1 + head + hair/lO) * sizeY); 02198 txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY); 02199 txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY); 02200 02201 txSetColor (~color & OxFFFFFF); // Inverse the color 02202 txSetFillColor (~color & OxFFFFFF); 02203 02204 txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY); 02205 txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY); 02206 oo 02207 txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]); //-V112 //-V542 02208 oo 02209 // See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow 02210 02211 txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY); 02212 txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY); 02213 Sleep (lOOO + count%2); 02214 02215 txSetColor ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT); 02216 txSetFillColor (TX_TRANSPARENT); 02217 02218 txCircle (x, y, 4); //-V112 02219 txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y); 02220 02221 txSetColor (lineColor); 02222 txSetFillColor (fillColor); 02223 } 02224 02226 //} 02227 //================================================================================================================= 02228 02229 //================================================================================================================= 02230 //{ Drawing text 02232 //================================================================================================================= 02234 //{---------------------------------------------------------------------------------------------------------------- 02253 //}---------------------------------------------------------------------------------------------------------------- 02254 02255 bool txTextOut (double x, double y, const char text[], HDC dc = txDC()); 02256 02257 //{---------------------------------------------------------------------------------------------------------------- 02259 02260 #undef txRectandle 02261 #undef txLine 02262 #undef txNotifyIcon 02263 #undef txCircle 02264 #undef txSetColor 02265 #undef C0L0RREF 02266 #undef OxFFFFFF 02267 #undef lO 02268 #undef lOOO 02269 #undef oo 02270 #undef O 02271 02273 //} 02274 02275 //{---------------------------------------------------------------------------------------------------------------- 02322 //}---------------------------------------------------------------------------------------------------------------- 02323 02324 bool txDrawText (double x0, double y0, double x1, double y1, const char text[], 02325 unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC()); 02326 02327 //{---------------------------------------------------------------------------------------------------------------- 02352 //}---------------------------------------------------------------------------------------------------------------- 02353 02354 HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1, 02355 int bold = FW_DONTCARE, bool italic = false, bool underline = false, 02356 bool strikeout = false, double angle = 0, 02357 HDC dc = txDC()); 02358 02359 //{---------------------------------------------------------------------------------------------------------------- 02374 //}---------------------------------------------------------------------------------------------------------------- 02375 02376 SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard; 02377 02378 //{---------------------------------------------------------------------------------------------------------------- 02392 //}---------------------------------------------------------------------------------------------------------------- 02393 02394 int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard; 02395 02396 //{---------------------------------------------------------------------------------------------------------------- 02410 //}---------------------------------------------------------------------------------------------------------------- 02411 02412 int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard; 02413 02414 //{---------------------------------------------------------------------------------------------------------------- 02441 //}---------------------------------------------------------------------------------------------------------------- 02442 02443 unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC()); 02444 02445 //{---------------------------------------------------------------------------------------------------------------- 02461 //}---------------------------------------------------------------------------------------------------------------- 02462 02463 LOGFONT* txFontExist (const char name[]) tx_nodiscard; 02464 02466 //} 02467 //================================================================================================================= 02468 02469 //================================================================================================================= 02470 //{ Drawing to memory DC and image loading 02472 //================================================================================================================= 02474 //{---------------------------------------------------------------------------------------------------------------- 02514 //}---------------------------------------------------------------------------------------------------------------- 02515 02516 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard; 02517 02518 //{---------------------------------------------------------------------------------------------------------------- 02621 //}---------------------------------------------------------------------------------------------------------------- 02622 02623 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels = NULL) tx_nodiscard; 02624 02626 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) tx_nodiscard; 02628 02629 //{---------------------------------------------------------------------------------------------------------------- 02711 //}---------------------------------------------------------------------------------------------------------------- 02712 02713 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0, 02714 unsigned imageType = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard; 02715 02716 //{---------------------------------------------------------------------------------------------------------------- 02748 //}---------------------------------------------------------------------------------------------------------------- 02749 02750 bool txDeleteDC (HDC dc); 02751 02753 bool txDeleteDC (HDC* dc); 02755 02756 //{---------------------------------------------------------------------------------------------------------------- 02796 //}---------------------------------------------------------------------------------------------------------------- 02797 02798 bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height, 02799 HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY); 02800 02801 //{---------------------------------------------------------------------------------------------------------------- 02816 //}---------------------------------------------------------------------------------------------------------------- 02817 02818 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0); 02819 02820 //{---------------------------------------------------------------------------------------------------------------- 02880 //}---------------------------------------------------------------------------------------------------------------- 02881 02882 bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height, 02883 HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK); 02884 02885 //{---------------------------------------------------------------------------------------------------------------- 02901 //}---------------------------------------------------------------------------------------------------------------- 02902 02903 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage, 02904 COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0); 02905 02906 //{---------------------------------------------------------------------------------------------------------------- 03011 //}---------------------------------------------------------------------------------------------------------------- 03012 03013 bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height, 03014 HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0); 03015 03016 //{---------------------------------------------------------------------------------------------------------------- 03033 //}---------------------------------------------------------------------------------------------------------------- 03034 03035 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage, 03036 double xSource = 0, double ySource = 0, double alpha = 1.0); 03037 03038 //{---------------------------------------------------------------------------------------------------------------- 03067 //}---------------------------------------------------------------------------------------------------------------- 03068 03069 HDC txUseAlpha (HDC image); 03070 03071 //{---------------------------------------------------------------------------------------------------------------- 03097 //}---------------------------------------------------------------------------------------------------------------- 03098 03099 bool txSaveImage (const char filename[], HDC dc = txDC()); 03100 03102 //} 03103 //================================================================================================================= 03104 03105 //================================================================================================================= 03106 //{ Utility functions 03108 //================================================================================================================= 03110 //{---------------------------------------------------------------------------------------------------------------- 03129 //}---------------------------------------------------------------------------------------------------------------- 03130 03131 double txSleep (double time = 0); 03132 03133 //{---------------------------------------------------------------------------------------------------------------- 03218 //}---------------------------------------------------------------------------------------------------------------- 03219 03220 inline int txBegin(); 03221 03222 //{---------------------------------------------------------------------------------------------------------------- 03245 //}---------------------------------------------------------------------------------------------------------------- 03246 03247 inline int txEnd(); 03248 03249 //{---------------------------------------------------------------------------------------------------------------- 03271 //}---------------------------------------------------------------------------------------------------------------- 03272 03273 inline void txRedrawWindow(); 03274 03275 //{---------------------------------------------------------------------------------------------------------------- 03299 //}---------------------------------------------------------------------------------------------------------------- 03300 03301 inline int txUpdateWindow (int update = true); 03302 03303 //{---------------------------------------------------------------------------------------------------------------- 03320 //}---------------------------------------------------------------------------------------------------------------- 03321 03322 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC()); 03323 03324 //{---------------------------------------------------------------------------------------------------------------- 03344 // 03345 // +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее" 03346 // | 03347 // v 03348 // txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture(); 03353 //}---------------------------------------------------------------------------------------------------------------- 03354 03355 // +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее" 03356 // | 03357 // v 03358 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture(); 03359 03360 //{---------------------------------------------------------------------------------------------------------------- 03376 //}---------------------------------------------------------------------------------------------------------------- 03377 03378 bool txDestroyWindow (HWND wnd = txWindow()); 03379 03380 //{---------------------------------------------------------------------------------------------------------------- 03391 //}---------------------------------------------------------------------------------------------------------------- 03392 03393 double txQueryPerformance() tx_nodiscard; 03394 03395 //{---------------------------------------------------------------------------------------------------------------- 03410 //}---------------------------------------------------------------------------------------------------------------- 03412 03413 #if defined (_TX_CPP11) 03414 template <int txFramesToAverage = 5> 03415 #else 03416 const int txFramesToAverage = 5; 03417 #endif 03418 03420 03421 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard; 03422 03424 //} 03425 03426 //================================================================================================================= 03427 //{ Mouse functions 03429 //================================================================================================================= 03431 //{---------------------------------------------------------------------------------------------------------------- 03455 //}---------------------------------------------------------------------------------------------------------------- 03456 03457 inline POINT txMousePos() tx_nodiscard; 03458 03459 //{---------------------------------------------------------------------------------------------------------------- 03479 //}---------------------------------------------------------------------------------------------------------------- 03480 03481 inline double txMouseX() tx_nodiscard; 03482 03483 //{---------------------------------------------------------------------------------------------------------------- 03503 //}---------------------------------------------------------------------------------------------------------------- 03504 03505 inline double txMouseY() tx_nodiscard; 03506 03507 //{---------------------------------------------------------------------------------------------------------------- 03539 //}---------------------------------------------------------------------------------------------------------------- 03540 03541 inline unsigned txMouseButtons() tx_nodiscard; 03542 03543 //{---------------------------------------------------------------------------------------------------------------- 03575 //}---------------------------------------------------------------------------------------------------------------- 03576 03577 #ifdef FOR_DOXYGEN_ONLY 03578 inline Mouse& txCatchMouse (bool shouldEat = true); 03579 #endif 03580 03582 //} 03583 //================================================================================================================= 03584 03585 //================================================================================================================= 03586 //{ Console functions 03588 //================================================================================================================= 03590 //{---------------------------------------------------------------------------------------------------------------- 03632 //}---------------------------------------------------------------------------------------------------------------- 03633 03634 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/); 03635 03636 //{---------------------------------------------------------------------------------------------------------------- 03648 //}---------------------------------------------------------------------------------------------------------------- 03649 03650 unsigned txGetConsoleAttr() tx_nodiscard; 03651 03652 //{---------------------------------------------------------------------------------------------------------------- 03666 //}---------------------------------------------------------------------------------------------------------------- 03667 03668 bool txClearConsole(); 03669 03670 //{---------------------------------------------------------------------------------------------------------------- 03690 //}---------------------------------------------------------------------------------------------------------------- 03691 03692 POINT txSetConsoleCursorPos (double x, double y); 03693 03694 //{---------------------------------------------------------------------------------------------------------------- 03707 //}---------------------------------------------------------------------------------------------------------------- 03708 03709 POINT txGetConsoleCursorPos(); 03710 03711 //{---------------------------------------------------------------------------------------------------------------- 03724 //}---------------------------------------------------------------------------------------------------------------- 03725 03726 POINT txGetConsoleExtent(); 03727 03728 //{---------------------------------------------------------------------------------------------------------------- 03742 //}---------------------------------------------------------------------------------------------------------------- 03743 03744 POINT txGetConsoleFontSize() tx_nodiscard; 03745 03746 //{---------------------------------------------------------------------------------------------------------------- 03762 //}---------------------------------------------------------------------------------------------------------------- 03763 03764 bool txTextCursor (bool blink = true); 03765 03767 //} 03768 //================================================================================================================= 03769 03770 //================================================================================================================= 03771 //{ Other staff not related to drawing 03773 //================================================================================================================= 03775 //{---------------------------------------------------------------------------------------------------------------- 03804 //}---------------------------------------------------------------------------------------------------------------- 03805 03806 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC); 03807 03808 //{---------------------------------------------------------------------------------------------------------------- 03866 //}---------------------------------------------------------------------------------------------------------------- 03867 03868 int txSpeak (const char* text, ...) tx_printfy (1); 03869 03870 //{---------------------------------------------------------------------------------------------------------------- 03987 //}---------------------------------------------------------------------------------------------------------------- 03988 03989 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[], 03990 double zoom = 0, double gain = 1, HWND wnd = txWindow()); 03991 03992 //{---------------------------------------------------------------------------------------------------------------- 04006 //}---------------------------------------------------------------------------------------------------------------- 04007 04008 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow()); 04009 04010 //{---------------------------------------------------------------------------------------------------------------- 04066 //}---------------------------------------------------------------------------------------------------------------- 04067 04068 bool txGetAsyncKeyState (int key); 04069 04070 //{---------------------------------------------------------------------------------------------------------------- 04107 //}---------------------------------------------------------------------------------------------------------------- 04108 04109 #ifdef FOR_DOXYGEN_ONLY 04110 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3); 04111 #endif 04112 04113 //{---------------------------------------------------------------------------------------------------------------- 04138 //}---------------------------------------------------------------------------------------------------------------- 04139 04140 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1); 04141 04142 //{---------------------------------------------------------------------------------------------------------------- 04218 //}---------------------------------------------------------------------------------------------------------------- 04219 04220 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04221 04222 template <typename T, typename... ArgsT> 04223 int txPrintf (const char* format, ArgsT... args); 04224 04225 #define TX_PRINTF(...) ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) ) 04226 04227 #endif 04228 04229 //----------------------------------------------------------------------------------------------------------------- 04230 04231 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY) 04232 04233 enum width_t : int {}; 04234 enum precision_t : int {}; 04235 04236 inline width_t width (int width) { return (width_t) width; } 04237 inline precision_t precision (int prec) { return (precision_t) prec; } 04238 04239 #endif 04240 04241 //{---------------------------------------------------------------------------------------------------------------- 04260 //}---------------------------------------------------------------------------------------------------------------- 04261 04262 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04263 04264 template <typename T, typename... ArgsT> 04265 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args); 04266 04267 #endif 04268 04269 //{---------------------------------------------------------------------------------------------------------------- 04289 //}---------------------------------------------------------------------------------------------------------------- 04290 04291 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04292 04293 template <typename T, typename... ArgsT> 04294 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args); 04295 04296 #endif 04297 04298 //{---------------------------------------------------------------------------------------------------------------- 04316 //}---------------------------------------------------------------------------------------------------------------- 04317 04318 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04319 04320 template <typename... ArgsT> 04321 std::string txFormat (const char* format, ArgsT... args); 04322 04323 #endif 04324 04325 //{---------------------------------------------------------------------------------------------------------------- 04397 //}---------------------------------------------------------------------------------------------------------------- 04399 04400 #define sizearr( arr ) ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) ) 04401 04403 // See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx 04404 04405 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N]; // ;=P 04406 04407 // Another approach 04408 04409 #if defined (_TX_CPP11_MSVC15) 04410 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; } 04411 #endif 04412 04414 04415 #define SIZEARR( arr ) ( sizeof (arr) / sizeof ((arr)[0]) ) 04416 04418 //{---------------------------------------------------------------------------------------------------------------- 04437 //}---------------------------------------------------------------------------------------------------------------- 04438 04439 inline int random (int range) tx_deprecated; 04440 04441 //{---------------------------------------------------------------------------------------------------------------- 04466 //}---------------------------------------------------------------------------------------------------------------- 04467 04468 inline double random (double left, double right) tx_nodiscard tx_deprecated; 04469 04470 inline double random (std::nomeow_t, double left, double right) tx_nodiscard; 04471 04472 //{---------------------------------------------------------------------------------------------------------------- 04502 //}---------------------------------------------------------------------------------------------------------------- 04503 04504 template <typename Tx, typename Ta, typename Tb> 04505 inline bool In (Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated; 04506 04507 template <typename Tx, typename Ta, typename Tb> 04508 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated; 04509 04510 //{---------------------------------------------------------------------------------------------------------------- 04556 //}---------------------------------------------------------------------------------------------------------------- 04558 04559 inline bool In (const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated; 04560 inline bool In (const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated; 04561 04563 04564 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated; 04565 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated; 04566 04567 //{---------------------------------------------------------------------------------------------------------------- 04586 //}---------------------------------------------------------------------------------------------------------------- 04587 04588 #define MAX( a, b ) ( ((a) > (b))? (a) : (b) ) 04589 04590 template <typename T> 04591 T max (const T& a, const T& b) { return (a > b)? a : b; } 04592 04593 //{---------------------------------------------------------------------------------------------------------------- 04612 //}---------------------------------------------------------------------------------------------------------------- 04613 04614 #define MIN( a, b ) ( ((a) < (b))? (a) : (b) ) 04615 04616 template <typename T> 04617 T min (const T& a, const T& b) { return (a < b)? a : b; } 04618 04619 //{---------------------------------------------------------------------------------------------------------------- 04633 //}---------------------------------------------------------------------------------------------------------------- 04634 04635 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // MSVC: C99 case 04636 04637 #define ROUND( x ) ( (long) round (x) ) 04638 04639 #else 04640 04641 #define ROUND( x ) ( (long) floor ((x) + 0.5) ) 04642 04643 #endif 04644 04645 //{---------------------------------------------------------------------------------------------------------------- 04664 //}---------------------------------------------------------------------------------------------------------------- 04665 04666 void tx_fpreset(); 04667 04668 //{---------------------------------------------------------------------------------------------------------------- 04677 //}---------------------------------------------------------------------------------------------------------------- 04678 04679 const double txPI = asin (1.0) * 2; 04680 04681 //{---------------------------------------------------------------------------------------------------------------- 04708 //}---------------------------------------------------------------------------------------------------------------- 04709 04710 inline double txSqr (double x) 04711 { 04712 double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0)); // Бурная вычислительная деятельность 04713 04714 char str[1024] = ""; 04715 _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr); 04716 txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL || 04717 ( 04718 txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION), 04719 txMessageBox ("Уйду я от вас", "Злые вы...", MB_ICONSTOP), 04720 exit (EXIT_FAILURE), 0 //-V2509 //-V2014 04721 ); 04722 04723 txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика! \0" // А как это работает, а? //-V111 04724 "С ума сойти... \0" // 04725 "а КЭП подтверждает \0" // и кто это будет 04726 "Главное - отчитаться\0" // поддерживать?.. 04727 "Невероятно, но факт \0" 04728 "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21); 04729 04730 return sqr; // Все же вернем значение. Мы же не звери 04731 } 04732 04733 //{---------------------------------------------------------------------------------------------------------------- 04755 //}---------------------------------------------------------------------------------------------------------------- 04756 04757 #ifdef FOR_DOXYGEN_ONLY 04758 #define _TX_DESTROY_3D 04759 #endif 04760 04761 #if defined (_TX_DESTROY_3D) 04762 04763 #define z 0 // Читайте "Флатландию" Эбботта! 04764 04765 #endif 04766 04767 //{---------------------------------------------------------------------------------------------------------------- 04784 //}---------------------------------------------------------------------------------------------------------------- 04786 04787 #define meow ; 04788 04789 #if defined (_MSC_VER) && !defined (_CLANG_VER) 04790 #define мяу meow 04791 #endif 04792 04793 #define please 04794 04796 04797 //{---------------------------------------------------------------------------------------------------------------- 04815 //}---------------------------------------------------------------------------------------------------------------- 04816 04817 #define ZERO( type ) zero <type> () 04818 04820 template <typename T> inline T zero() tx_nodiscard; 04822 04823 //{---------------------------------------------------------------------------------------------------------------- 04850 //}---------------------------------------------------------------------------------------------------------------- 04852 04853 #define tx_auto_func( func ) _tx_auto_fun1 ( __LINE__, func ) 04854 #define _tx_auto_fun1( n, func ) _tx_auto_fun2 ( n, func ) 04855 #define _tx_auto_fun2( n, func ) auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; }) 04856 04857 #define tx_finally(...) tx_auto_func (__VA_ARGS__) 04858 04859 template <typename T> 04860 struct _tx_auto_func_ 04861 { 04862 typedef _tx_auto_func_<T> this_t; 04863 T func_; 04864 04865 explicit _tx_auto_func_ (T func) : func_ (func) {} 04866 ~_tx_auto_func_ () { func_ (); } 04867 04868 private: _tx_auto_func_ () _tx_delete; 04869 _tx_auto_func_ (const this_t&) _tx_delete; 04870 this_t& operator = (const this_t&) _tx_delete; 04871 }; 04872 04873 template <typename T> 04874 _tx_auto_func_<T> _tx_auto_func (T func) 04875 { 04876 return _tx_auto_func_ <T> (func); 04877 } 04878 04880 04881 //{---------------------------------------------------------------------------------------------------------------- 04926 //}---------------------------------------------------------------------------------------------------------------- 04927 04928 #if !defined (NDEBUG) 04929 #undef TX_ASSERT 04930 #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \ 04931 "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 ) 04932 #else 04933 #undef TX_ASSERT 04934 #define TX_ASSERT( cond ) ((void) 1) 04935 04936 #endif 04937 04938 #ifdef assert 04939 #undef assert 04940 #endif 04941 04942 #define assert( cond ) TX_ASSERT (cond) 04943 04944 //{---------------------------------------------------------------------------------------------------------------- 04971 //}---------------------------------------------------------------------------------------------------------------- 04972 04973 #if !defined (NDEBUG) 04974 #define asserted || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.") 04975 04976 #else 04977 #define asserted || _txNOP (0) 04978 04979 #endif 04980 04981 #define verified asserted //!< For compatibility with assert macro 04982 04984 #define TX_NEEDED asserted //!< For compatibility with earlier releases 04985 04986 04987 //{---------------------------------------------------------------------------------------------------------------- 05015 //}---------------------------------------------------------------------------------------------------------------- 05016 05017 #if !defined (NDEBUG) 05018 #undef verify 05019 #define verify assert 05020 05021 #else 05022 #undef verify 05023 #define verify( expr ) ( expr ) 05024 05025 #endif 05026 05027 //{---------------------------------------------------------------------------------------------------------------- 05046 //}---------------------------------------------------------------------------------------------------------------- 05047 05048 #if !defined (FOR_DOXYGEN_ONLY) 05049 #define TX_ERROR( ... ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__) 05050 #else 05051 #define TX_ERROR( msg ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg) 05052 #endif 05053 05055 #define TX_THROW TX_ERROR //!< For compatibility with earlier TXLib releases 05056 05057 05058 //{---------------------------------------------------------------------------------------------------------------- 05074 //}---------------------------------------------------------------------------------------------------------------- 05075 05076 #if !defined (NDEBUG) 05077 #define TX_DEBUG_ERROR(...) TX_ERROR (__VA_ARGS__) 05078 05079 #else 05080 #define TX_DEBUG_ERROR(...) ((void) 0) 05081 05082 #endif 05083 05084 //{---------------------------------------------------------------------------------------------------------------- 05104 //}---------------------------------------------------------------------------------------------------------------- 05105 05106 #ifdef FOR_DOXYGEN_ONLY 05107 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true); 05108 #endif 05109 05111 05112 #ifdef _MSC_VER 05113 #define txDump( ... ) _txDump ((const void*)(uintptr_t) __VA_ARGS__) 05114 #else 05115 #define txDump( address, ... ) _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__) 05116 #endif 05117 05118 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true); 05119 05121 05122 //{---------------------------------------------------------------------------------------------------------------- 05148 //}---------------------------------------------------------------------------------------------------------------- 05149 05150 #define txStackBackTrace() _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true); 05151 05152 //{---------------------------------------------------------------------------------------------------------------- 05174 //}---------------------------------------------------------------------------------------------------------------- 05176 05177 std::string txDemangle (const char* mangledName); 05178 char* txDemangle (const char* mangledName, std::nomeow_t); 05179 05180 #define txTypename(value) txDemangle (typeid (value) .name()) .c_str() 05181 05183 //{---------------------------------------------------------------------------------------------------------------- 05210 //}---------------------------------------------------------------------------------------------------------------- 05211 05212 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue); 05213 05214 //{---------------------------------------------------------------------------------------------------------------- 05227 //}---------------------------------------------------------------------------------------------------------------- 05229 05230 #define _ , 05231 #define TX_COMMA , //!< Синоним макроса _ (@ref _ "символ подчеркивания") 05232 05234 05235 //{---------------------------------------------------------------------------------------------------------------- 05295 //}---------------------------------------------------------------------------------------------------------------- 05296 05297 #ifdef FOR_DOXYGEN_ONLY 05298 05299 #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType ) 05300 05301 #else 05302 05303 // Hand-made DLLIMPORT helper 05304 05305 #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... ) \ 05306 retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \ 05307 _txDllImport ((libName), #funcName, (required)) 05308 #endif 05309 05311 //} 05312 //================================================================================================================= 05313 05314 //================================================================================================================= 05315 //{ Back-hole (I hope, not an ass-hole:) of the library) 05317 //================================================================================================================= 05319 //{---------------------------------------------------------------------------------------------------------------- 05471 //}---------------------------------------------------------------------------------------------------------------- 05472 05473 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL); 05474 05475 //{---------------------------------------------------------------------------------------------------------------- 05500 //}---------------------------------------------------------------------------------------------------------------- 05501 05502 bool txLock (bool wait = true); 05503 05504 //{---------------------------------------------------------------------------------------------------------------- 05515 //}---------------------------------------------------------------------------------------------------------------- 05517 05518 bool txUnlock(); 05519 05521 template <typename T> inline T txUnlock (T value); 05523 05525 05526 //{---------------------------------------------------------------------------------------------------------------- 05549 //}---------------------------------------------------------------------------------------------------------------- 05550 05551 #define txGDI( command, dc ) ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) ) 05552 05553 //{---------------------------------------------------------------------------------------------------------------- 05576 //}---------------------------------------------------------------------------------------------------------------- 05577 05578 #ifndef FOR_DOXYGEN_ONLY 05579 05580 const int _TX_CODEPAGE = 1251; 05581 05582 #ifndef __CYGWIN__ 05583 const char _TX_LOCALE[] = "Russian"; 05584 #else 05585 const char _TX_LOCALE[] = "ru_RU.CP1251"; 05586 #endif 05587 05588 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP"; 05589 05590 #endif 05591 05592 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE); 05593 05594 //{---------------------------------------------------------------------------------------------------------------- 05607 //}---------------------------------------------------------------------------------------------------------------- 05608 05609 int txPause (const char* message, ...) tx_printfy (1); 05610 05612 //} 05613 //================================================================================================================= 05614 05615 //================================================================================================================= 05616 //{ Tune-up constants and variables 05618 //================================================================================================================= 05620 //{---------------------------------------------------------------------------------------------------------------- 05630 //}---------------------------------------------------------------------------------------------------------------- 05631 05632 #ifndef TX_COMPILED 05633 05634 char _txLogName[MAX_PATH] = ""; 05635 05636 #endif // TX_COMPILED 05637 05638 extern char _txLogName[]; 05639 05640 //{---------------------------------------------------------------------------------------------------------------- 05672 //}---------------------------------------------------------------------------------------------------------------- 05673 05674 #if defined (_TX_NOINIT) 05675 05676 #undef _TX_NOINIT 05677 #define _TX_NOINIT 1 05678 05679 #else 05680 05681 #define _TX_NOINIT 0 05682 05683 #endif 05684 05685 //{---------------------------------------------------------------------------------------------------------------- 05729 //}---------------------------------------------------------------------------------------------------------------- 05730 05731 #if !defined (TX_CONSOLE_MODE) 05732 05733 #define TX_CONSOLE_MODE SW_HIDE 05734 05735 #endif 05736 05737 //{---------------------------------------------------------------------------------------------------------------- 05741 //}---------------------------------------------------------------------------------------------------------------- 05742 05743 #if !defined (TX_CONSOLE_FONT) 05744 05745 #define TX_CONSOLE_FONT "Lucida Console" 05746 05747 #endif 05748 05749 //{---------------------------------------------------------------------------------------------------------------- 05760 //}---------------------------------------------------------------------------------------------------------------- 05761 05762 #ifndef TX_COMPILED 05763 05764 int _txWindowStyle = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU; 05765 05766 #endif // TX_COMPILED 05767 05768 extern int _txWindowStyle; 05769 05770 //{---------------------------------------------------------------------------------------------------------------- 05773 //}---------------------------------------------------------------------------------------------------------------- 05774 05775 #ifndef TX_COMPILED 05776 05777 unsigned _txCursorBlinkInterval = 500; 05778 05779 #endif // TX_COMPILED 05780 05781 extern unsigned _txCursorBlinkInterval; 05782 05783 //{---------------------------------------------------------------------------------------------------------------- 05787 //}---------------------------------------------------------------------------------------------------------------- 05788 05789 #ifndef TX_COMPILED 05790 05791 unsigned _txWindowUpdateInterval = 25; 05792 05793 #endif // TX_COMPILED 05794 05795 extern unsigned _txWindowUpdateInterval; 05796 05797 //{---------------------------------------------------------------------------------------------------------------- 05806 //}---------------------------------------------------------------------------------------------------------------- 05807 05808 #ifdef FOR_DOXYGEN_ONLY 05809 #define TX_USE_SFML 05810 #endif 05811 05812 //{---------------------------------------------------------------------------------------------------------------- 05815 //}---------------------------------------------------------------------------------------------------------------- 05816 05817 const int _TX_TIMEOUT = 1000 05818 05819 #if defined (_TX_ALLOW_TRACE) 05820 * 2 05821 #endif 05822 05823 #if defined (TX_TRACE) 05824 * 3 05825 #endif 05826 05827 #if defined (_TX_USE_DEVPARTNER) 05828 * 10 05829 #endif 05830 ; 05831 05832 //{---------------------------------------------------------------------------------------------------------------- 05873 //}---------------------------------------------------------------------------------------------------------------- 05874 05875 #ifndef TX_COMPILED 05876 05877 bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest, 05878 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp) = NULL; 05879 05880 #endif // TX_COMPILED 05881 05882 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest, 05883 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp); 05884 05885 //{---------------------------------------------------------------------------------------------------------------- 05888 //}---------------------------------------------------------------------------------------------------------------- 05889 05890 const unsigned _TX_BUFSIZE = 1024, 05891 _TX_BIGBUFSIZE = _TX_BUFSIZE * 2, 05892 _TX_HUGEBUFSIZE = _TX_BUFSIZE * 20, 05893 05894 _TX_STACKSIZE = 64 * 1024; 05895 05896 //{---------------------------------------------------------------------------------------------------------------- 05899 //}---------------------------------------------------------------------------------------------------------------- 05900 05901 #if !defined (_TX_EXCEPTIONS_LIMIT) 05902 #define _TX_EXCEPTIONS_LIMIT 16 05903 #endif 05904 05905 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT) 05906 #define _TX_FATAL_EXCEPTIONS_LIMIT 16 //!< Максимальное количество фатальных исключений. 05907 #endif 05908 05909 //{---------------------------------------------------------------------------------------------------------------- 05912 //}---------------------------------------------------------------------------------------------------------------- 05913 05914 #ifdef FOR_DOXYGEN_ONLY 05915 #define _TX_FULL_STACKTRACE 05916 #endif 05917 05918 //{---------------------------------------------------------------------------------------------------------------- 05921 //}---------------------------------------------------------------------------------------------------------------- 05922 05923 #ifndef TX_COMPILED 05924 05925 bool _txProcessSystemWarnings = true; 05926 05927 #endif // TX_COMPILED 05928 05929 extern bool _txProcessSystemWarnings; 05930 05931 //{---------------------------------------------------------------------------------------------------------------- 05945 //}---------------------------------------------------------------------------------------------------------------- 05946 05947 #if !defined (_TX_WAITABLE_PARENTS) 05948 #define _TX_WAITABLE_PARENTS "Winpty-agent.exe:Clion.exe, " /* 0: CLion32 */ \ 05949 "Winpty-agent.exe:Clion64.exe, " /* 1: CLion64 */ \ 05950 "starter.exe:eclipse.exe, " /* 2: Eclipse 4 */ \ 05951 "starter.exe:javaw.exe, " /* 3: Eclipse 3 */ \ 05952 "cmd.exe:devenv.exe, " /* 4: MSVS 2003+ */ \ 05953 "VSDebugConsole.exe:devenv.exe, " /* 5: MSVS 2019+ */ \ 05954 "VSDebugConsole.exe:msvsmon.exe, " /* 6: MSVS 2022 x86 */ \ 05955 "consolepauser.exe:devcpp.exe, " /* 7: Dev-Cpp */ \ 05956 "cb_console_runner.exe:codeblocks.exe" /* 8: CodeBlocks 8+ */ 05957 #endif 05958 05959 //{---------------------------------------------------------------------------------------------------------------- 05978 //}---------------------------------------------------------------------------------------------------------------- 05979 05980 #if !defined (_TX_ALLOW_KILL_PARENT) // DISCLAIMER: Я не призываю к убийству родителей. 05981 #define _TX_ALLOW_KILL_PARENT true // Это технический термин. 05982 #endif // г_дам юристам привет. 05983 05984 //{---------------------------------------------------------------------------------------------------------------- 05994 //}---------------------------------------------------------------------------------------------------------------- 05995 05996 #ifndef TX_COMPILED 05997 05998 int _txWatchdogTimeout = 10*_TX_TIMEOUT; 05999 06000 #endif // TX_COMPILED 06001 06002 extern int _txWatchdogTimeout; 06003 06004 //{---------------------------------------------------------------------------------------------------------------- 06073 //}---------------------------------------------------------------------------------------------------------------- 06075 06076 #ifdef FOR_DOXYGEN_ONLY 06077 06078 #define TX_COMPILED 06079 06080 #endif 06081 06083 06085 //} 06086 //================================================================================================================= 06087 06088 //================================================================================================================= 06089 //{ Internal diagnostics 06091 //================================================================================================================= 06093 //{---------------------------------------------------------------------------------------------------------------- 06133 //}---------------------------------------------------------------------------------------------------------------- 06134 06135 #ifdef FOR_DOXYGEN_ONLY 06136 #define _TX_ALLOW_TRACE 06137 #endif 06138 06139 //{---------------------------------------------------------------------------------------------------------------- 06169 //}---------------------------------------------------------------------------------------------------------------- 06170 06171 #ifdef FOR_DOXYGEN_ONLY 06172 #define TX_TRACE 06173 #endif 06174 06175 #if !defined (TX_TRACE) 06176 #define TX_TRACE { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); } 06177 #endif 06178 06180 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...); 06182 06183 //{---------------------------------------------------------------------------------------------------------------- 06186 06187 #ifndef FOR_DOXYGEN_ONLY 06188 06189 struct _txLoc 06190 { 06191 const char* func; 06192 const char* file; 06193 int line; 06194 06195 int inTX; // We are inside one of TXLib functions 06196 int trace; // Internal TX trace level, when enabled by _TX_ALLOW_TRACE 06197 06198 const _txLoc* prev; // Caller's location 06199 06200 static _txLoc _tx_thread Cur; 06201 }; 06202 06203 struct _txFuncEntry 06204 { 06205 typedef _txFuncEntry this_t; 06206 06207 _txLoc loc; 06208 06209 _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; } 06210 void restore() { _txLoc::Cur = loc; } 06211 ~_txFuncEntry() { restore(); } 06212 06213 private: 06214 _txFuncEntry (const this_t&) _tx_delete; 06215 this_t& operator = (const this_t&) _tx_delete; 06216 }; 06217 06218 #if defined (_GCC_VER) 06219 06220 inline const char* __txLocCurSet (const char* _file, int _line, const char* _func) 06221 { _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; } 06222 06223 #else 06224 06225 #define __txLocCurSet( _file, _line, _func ) \ 06226 ( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) ) 06227 06228 #endif 06229 06230 #define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__) 06231 06232 #define _txLocLvlSet(lvl) { _txLoc::Cur.trace = (lvl); } 06233 06234 //{---------------------------------------------------------------------------------------------------------------- 06235 06236 #if defined ($0) 06237 #undef $0 06238 #endif 06239 06240 #if defined ($1) 06241 #undef $1 06242 #endif 06243 06244 #if defined ($2) 06245 #undef $2 06246 #endif 06247 06248 #if defined ($3) 06249 #undef $3 06250 #endif 06251 06252 #if defined ($4) 06253 #undef $4 06254 #endif 06255 06256 #if defined ($5) 06257 #undef $5 06258 #endif 06259 06260 #if defined ($6) 06261 #undef $6 06262 #endif 06263 06264 #if defined ($7) 06265 #undef $7 06266 #endif 06267 06268 #if defined ($8) 06269 #undef $8 06270 #endif 06271 06272 #if defined ($9) 06273 #undef $9 06274 #endif 06275 06276 #if defined ($) 06277 #undef $ 06278 #endif 06279 06280 #if defined ($$) 06281 #undef $$ 06282 #endif 06283 06284 //} 06285 //----------------------------------------------------------------------------------------------------------------- 06286 06287 #if defined (_TX_ALLOW_TRACE) 06288 06289 #define _txEntry(lvl) _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl); $; } 06290 06291 #define $ { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } } 06292 06293 #define $$ { __txFuncEntry.restore(); } 06294 06295 #elif defined (_DEBUG) 06296 06297 #define _txEntry(lvl) _txFuncEntry __txFuncEntry; { $; } 06298 06299 #define $ { _txLocCurSet(); } 06300 06301 #define $$ { __txFuncEntry.restore(); } 06302 06303 #else 06304 06305 #define _txEntry(lvl) ; 06306 #define $ ; 06307 #define $$ ; 06308 06309 #endif 06310 06311 //{---------------------------------------------------------------------------------------------------------------- 06312 06313 #define $0 _txEntry (0) // (Log level unchanged) 06314 #define $1 _txEntry (1) // Regular functions 06315 #define $2 _txEntry (2) // Resvd 06316 #define $3 _txEntry (3) // Init/Cleanup 06317 #define $4 _txEntry (4) // Init/Cleanup, misc functions 06318 #define $5 _txEntry (5) // Error handling, entry points 06319 #define $6 _txEntry (6) // Error handling, main part 06320 #define $7 _txEntry (7) // Error handling, misc functions 06321 #define $8 _txEntry (8) // Canvas worker thread 06322 #define $9 _txEntry (9) // Resvd 06323 06324 //} 06325 //----------------------------------------------------------------------------------------------------------------- 06326 06327 #endif // FOR_DOXYGEN_ONLY 06328 06331 //}---------------------------------------------------------------------------------------------------------------- 06332 06334 //} 06335 //================================================================================================================= 06336 06337 //================================================================================================================= 06338 //{ Sweet critical section blocking: txAutoLock class 06339 //================================================================================================================= 06340 06341 //{---------------------------------------------------------------------------------------------------------------- 06357 //}---------------------------------------------------------------------------------------------------------------- 06358 06360 extern CRITICAL_SECTION _txCanvas_LockBackBuf; 06362 06363 class txAutoLock 06364 { 06365 typedef txAutoLock this_t; 06366 06367 public: 06368 06369 //{---------------------------------------------------------------------------------------------------------------- 06392 //}---------------------------------------------------------------------------------------------------------------- 06393 06394 explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) : 06395 cs_ (cs) 06396 { 06397 $1 if (!cs_) return; 06398 06399 if (mandatory) {$ EnterCriticalSection (cs_); } 06400 else {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); } 06401 } 06402 06403 //{---------------------------------------------------------------------------------------------------------------- 06416 //}---------------------------------------------------------------------------------------------------------------- 06417 06418 explicit txAutoLock (bool mandatory = true) : 06419 cs_ (NULL) 06420 { 06421 $1 new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory); 06422 } 06423 06424 //{---------------------------------------------------------------------------------------------------------------- 06426 //}---------------------------------------------------------------------------------------------------------------- 06427 06428 ~txAutoLock() 06429 { 06430 $1 if (!cs_) return; 06431 $ LeaveCriticalSection (cs_); cs_ = NULL; 06432 } 06433 06434 //{---------------------------------------------------------------------------------------------------------------- 06437 //}---------------------------------------------------------------------------------------------------------------- 06438 06439 operator bool () const 06440 { 06441 $1 return (cs_ != NULL); 06442 } 06443 06444 //{---------------------------------------------------------------------------------------------------------------- 06446 //}---------------------------------------------------------------------------------------------------------------- 06447 06448 // private: 06449 CRITICAL_SECTION* cs_; 06450 06451 //{---------------------------------------------------------------------------------------------------------------- 06453 //}---------------------------------------------------------------------------------------------------------------- 06455 06456 private: 06457 txAutoLock (const this_t&) _tx_delete; 06458 this_t& operator = (const this_t&) _tx_delete; 06459 06461 06462 }; 06463 06464 //} 06465 //================================================================================================================= 06466 06467 //================================================================================================================= 06468 //{ Dialogs: txDialog class 06470 //================================================================================================================= 06472 //{---------------------------------------------------------------------------------------------------------------- 06493 //}---------------------------------------------------------------------------------------------------------------- 06494 06495 struct txDialog 06496 { 06497 typedef txDialog this_t; 06498 06499 //{---------------------------------------------------------------------------------------------------------------- 06512 //}---------------------------------------------------------------------------------------------------------------- 06513 06514 public: 06515 enum CONTROL 06516 { 06517 DIALOG = (int) 0x00000000, 06518 BUTTON = (int) 0xFFFF0080, 06519 EDIT = (int) 0xFFFF0081, 06520 STATIC = (int) 0xFFFF0082, 06521 LISTBOX = (int) 0xFFFF0083, 06522 SCROLLBAR = (int) 0xFFFF0084, 06523 COMBOBOX = (int) 0xFFFF0085, 06524 END = (int) 0x00000000 06525 }; 06526 06527 //{---------------------------------------------------------------------------------------------------------------- 06544 //}---------------------------------------------------------------------------------------------------------------- 06545 06546 public: 06547 struct Layout 06548 { //-V802 06549 CONTROL wndclass; 06550 const char* caption; 06551 WORD id; 06552 short x; 06553 short y; 06554 short sx; 06555 short sy; 06556 DWORD style; 06557 06558 const char* font; 06559 WORD fontsize; 06560 }; 06561 06562 //{---------------------------------------------------------------------------------------------------------------- 06570 //}---------------------------------------------------------------------------------------------------------------- 06571 06572 public: 06573 txDialog(); 06574 06575 //{---------------------------------------------------------------------------------------------------------------- 06585 //}---------------------------------------------------------------------------------------------------------------- 06586 06587 explicit txDialog (const Layout* layout); 06588 06589 //{---------------------------------------------------------------------------------------------------------------- 06591 //}---------------------------------------------------------------------------------------------------------------- 06592 06593 virtual ~txDialog() {}; 06594 06595 //{---------------------------------------------------------------------------------------------------------------- 06607 //}---------------------------------------------------------------------------------------------------------------- 06608 06609 const Layout* setLayout (const Layout *layout); 06610 06611 //{---------------------------------------------------------------------------------------------------------------- 06629 //}---------------------------------------------------------------------------------------------------------------- 06630 06631 virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam); 06632 06633 //{---------------------------------------------------------------------------------------------------------------- 06649 //}---------------------------------------------------------------------------------------------------------------- 06650 06651 intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0); 06652 06653 //{---------------------------------------------------------------------------------------------------------------- 06666 //}---------------------------------------------------------------------------------------------------------------- 06667 06668 intptr_t dialogBox (WORD resource); 06669 06670 //{---------------------------------------------------------------------------------------------------------------- 06672 //}---------------------------------------------------------------------------------------------------------------- 06673 06674 private: 06675 txDialog (const this_t&) _tx_delete; 06676 this_t& operator = (const this_t&) _tx_delete; 06677 06678 //{---------------------------------------------------------------------------------------------------------------- 06680 //}---------------------------------------------------------------------------------------------------------------- 06681 06682 protected: 06683 static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam); 06684 06685 //{---------------------------------------------------------------------------------------------------------------- 06687 //}---------------------------------------------------------------------------------------------------------------- 06688 06689 private: 06690 const Layout* layout_; 06691 }; 06692 06694 //} 06695 //================================================================================================================= 06696 06697 //================================================================================================================= 06698 //{ Dialogs: Message Map macros 06700 //================================================================================================================= 06702 //{---------------------------------------------------------------------------------------------------------------- 06723 //}---------------------------------------------------------------------------------------------------------------- 06724 06725 #define TX_BEGIN_MESSAGE_MAP() \ 06726 virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \ 06727 { \ 06728 int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result; \ 06729 \ 06730 switch (_msg) \ 06731 { \ 06732 case WM_NULL: 06733 06734 //{---------------------------------------------------------------------------------------------------------------- 06753 //}---------------------------------------------------------------------------------------------------------------- 06754 06755 #define TX_HANDLE( id ) \ 06756 break; \ 06757 case (id): 06758 06759 //{---------------------------------------------------------------------------------------------------------------- 06779 //}---------------------------------------------------------------------------------------------------------------- 06780 06781 #define TX_COMMAND_MAP \ 06782 default: break; \ 06783 } \ 06784 \ 06785 if (_msg == WM_COMMAND) switch (LOWORD (_wParam)) \ 06786 { \ 06787 case 0: 06788 06789 //{---------------------------------------------------------------------------------------------------------------- 06808 //}---------------------------------------------------------------------------------------------------------------- 06809 06810 #define TX_END_MESSAGE_MAP \ 06811 default: break; \ 06812 } \ 06813 \ 06814 return FALSE; \ 06815 } 06816 06818 //} 06819 //================================================================================================================= 06820 06821 //================================================================================================================= 06822 //{ Dialogs: txDialog example: txInputBox() 06824 //================================================================================================================= 06826 //{---------------------------------------------------------------------------------------------------------------- 06846 //}---------------------------------------------------------------------------------------------------------------- 06847 06848 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard; 06849 06850 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 06851 06852 const char* txInputBox (const char* text, const char* caption, const char* input) 06853 { 06854 //------------------------------------------------------------------------------------------------------------- 06855 // Если не указаны параметры, приходится использовать хоть какие-то надписи. 06856 // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название. 06857 //------------------------------------------------------------------------------------------------------------- 06858 06859 if (!text) text = "Введите строку:"; 06860 if (!caption) caption = txGetModuleFileName (false); 06861 if (!input) input = ""; 06862 06863 //------------------------------------------------------------------------------------------------------------- 06864 // Идентификаторы элементов диалога. Они требуются в GetDlgItemText(). 06865 // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически. 06866 // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы 06867 // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения, 06868 // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о 06869 //------------------------------------------------------------------------------------------------------------- 06870 06871 #define ID_TEXT_ 101 06872 #define ID_INPUT_ 102 06873 06874 //------------------------------------------------------------------------------------------------------------- 06875 // Задание макета (вида) диалога в виде массива структур. 06876 // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив 06877 // становится похож на описание ресурса диалога в .rc-файле. 06878 // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com). 06879 //------------------------------------------------------------------------------------------------------------- 06880 06881 txDialog::Layout layout[] = 06882 06883 //----------------------+----------+-----------+-----------------+--------------------------------------------- 06884 // Тип элемента | Имя | Иденти- | Координаты | Флаги элементов 06885 // диалога | элемента | фикатор |-----------------| (см. описание элементов 06886 // | | элемента | X | Y |Шир.|Выс.| окон диалога в MSDN) 06887 //----------------------+----------+-----------+---+---+----+----+--------------------------------------------- 06888 // | | | | | | | 06889 {{ txDialog::DIALOG, caption, 0, 0, 0, 240, 85 }, 06890 { txDialog::STATIC, text, ID_TEXT_, 10, 10, 150, 40, SS_LEFT }, 06891 { txDialog::EDIT, input, ID_INPUT_, 10, 60, 220, 15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP }, 06892 { txDialog::BUTTON, "&OK", IDOK, 180, 10, 50, 15, BS_DEFPUSHBUTTON | WS_TABSTOP }, 06893 { txDialog::BUTTON, "&Cancel", IDCANCEL, 180, 30, 50, 15, BS_PUSHBUTTON | WS_TABSTOP }, 06894 { txDialog::END }}; 06895 06896 //------------------------------------------------------------------------------------------------------------- 06897 // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним. 06898 // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она 06899 // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную 06900 // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее 06901 // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG). 06902 //------------------------------------------------------------------------------------------------------------- 06903 struct inputDlg : txDialog 06904 { 06905 char str [1024]; 06906 06907 //--------------------------------------------------------------------------------------------------------- 06908 06909 inputDlg() : 06910 str() 06911 {} 06912 06913 //--------------------------------------------------------------------------------------------------------- 06914 06915 TX_BEGIN_MESSAGE_MAP() // Карта сообщений (на самом деле это начало оконной функции). //-V2525 06916 06917 TX_COMMAND_MAP // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch). 06918 06919 //------------------------------------------------------------------------------------------------- 06920 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия 06921 // диалога строка ввода умрет и текст уже из нее получить. 06922 // Этот макрос на самом деле превращается в case из оператора switch. 06923 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP(). 06924 //------------------------------------------------------------------------------------------------- 06925 06926 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1); 06927 06928 TX_END_MESSAGE_MAP //-V2522 06929 06930 //--------------------------------------------------------------------------------------------------------- 06931 // Конец внутреннего класса диалога 06932 //--------------------------------------------------------------------------------------------------------- 06933 }; 06934 06935 //------------------------------------------------------------------------------------------------------------- 06936 // Убираем дефайны, чтобы потом не мешали. 06937 // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом 06938 // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _. 06939 // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны. 06940 //------------------------------------------------------------------------------------------------------------- 06941 06942 #undef ID_TEXT_ 06943 #undef ID_INPUT_ 06944 06945 //------------------------------------------------------------------------------------------------------------- 06946 // Это статический объект, потому что строка в нем должна жить после завершения функции. 06947 //------------------------------------------------------------------------------------------------------------- 06948 06949 static inputDlg dlg; 06950 06951 //------------------------------------------------------------------------------------------------------------- 06952 // Передаем layout и запускаем окно диалога 06953 //------------------------------------------------------------------------------------------------------------- 06954 06955 dlg.dialogBox (layout); 06956 06957 //------------------------------------------------------------------------------------------------------------- 06958 // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет 06959 // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать 06960 // синтаксически можно, но ведет к серьезным ошибкам. 06961 //------------------------------------------------------------------------------------------------------------- 06962 06963 return dlg.str; 06964 } 06965 06966 #endif // TX_COMPILED 06967 06969 //} 06970 //================================================================================================================= 06971 06972 //} 06973 //================================================================================================================= 06974 06975 //================================================================================================================= 06976 //{ TXLIB IMPLEMENTATION 06977 // Реализация функций библиотеки 06978 //================================================================================================================= 06980 06981 //----------------------------------------------------------------------------------------------------------------- 06982 //{ The Includes 06983 //----------------------------------------------------------------------------------------------------------------- 06984 06985 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 06986 06987 _TX_END_NAMESPACE 06988 06989 //----------------------------------------------------------------------------------------------------------------- 06990 06991 #if defined (_MSC_VER) 06992 #pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o 06993 06994 #pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch 06995 #pragma warning (disable: 4005) // 'name': macro redefinition 06996 #endif 06997 06998 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED) 06999 #undef __STRICT_ANSI__ 07000 #endif 07001 07002 //----------------------------------------------------------------------------------------------------------------- 07003 07004 #include <stdarg.h> 07005 #include <io.h> 07006 #include <fcntl.h> 07007 #include <process.h> 07008 #include <signal.h> 07009 #include <setjmp.h> 07010 #include <locale.h> 07011 #include <limits.h> 07012 #include <stdint.h> 07013 07014 #include <map> 07015 #include <numeric> 07016 #include <exception> 07017 #include <stdexcept> 07018 07019 #include <tlhelp32.h> 07020 #include <shellapi.h> 07021 07022 #if defined (_GCC_VER) 07023 07024 #include <shlobj.h> 07025 07026 #include <cxxabi.h> 07027 #include <unwind.h> 07028 07029 #endif 07030 07031 #if defined (__CYGWIN__) 07032 07033 #include <stdarg.h> 07034 #include <unistd.h> 07035 #include <termios.h> 07036 07037 #endif 07038 07039 #if defined (_MSC_VER) 07040 07041 #include <new.h> 07042 07043 #include <shlobj.h> 07044 #include <ntstatus.h> 07045 #include <crtdbg.h> 07046 #include <rtcapi.h> 07047 #include <dbghelp.h> 07048 07049 #endif 07050 07051 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 07052 #include <inttypes.h> 07053 #endif 07054 07055 //----------------------------------------------------------------------------------------------------------------- 07056 07057 #if defined (TX_USE_SPEAK) //-------------------------------------------------------------------------------------- 07058 #include <SAPI.h> // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :( 07059 #endif //-------------------------------------------------------------------------------------- 07060 07061 //----------------------------------------------------------------------------------------------------------------- 07062 07063 #if defined (_MSC_VER) 07064 #pragma warning (pop) // MSVC: Restore max level 07065 #endif 07066 07067 #if defined (__STRICT_ANSI__UNDEFINED) 07068 #define __STRICT_ANSI__ // Redefine back 07069 #endif 07070 07071 //----------------------------------------------------------------------------------------------------------------- 07072 07073 _TX_BEGIN_NAMESPACE 07074 07075 #endif // TX_COMPILED 07076 07077 //} 07078 //----------------------------------------------------------------------------------------------------------------- 07079 07080 //================================================================================================================= 07081 //{ DLL functions import, missing types definitions 07083 //================================================================================================================= 07085 07086 //----------------------------------------------------------------------------------------------------------------- 07087 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers. 07088 // Copied from Windows SDK 7.0a. 07089 //----------------------------------------------------------------------------------------------------------------- 07090 07091 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07092 07093 namespace Win32 { 07094 07095 #ifndef AC_SRC_ALPHA 07096 #define AC_SRC_ALPHA 0x01 07097 #endif 07098 07099 #ifndef SMTO_ERRORONEXIT 07100 #define SMTO_ERRORONEXIT 0x0020 07101 #endif 07102 07103 #ifndef NT_CONSOLE_PROPS_SIG 07104 #define NT_CONSOLE_PROPS_SIG 0xA0000002 07105 #endif 07106 07107 #ifndef NIIF_INFO 07108 #define NIIF_INFO 0x00000001 07109 #define NIIF_WARNING 0x00000002 07110 #define NIIF_ERROR 0x00000003 07111 #endif 07112 07113 #ifndef NIF_INFO 07114 #define NIF_STATE 0x00000008 07115 #define NIF_INFO 0x00000010 07116 #endif 07117 07118 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 07119 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x00000004 07120 #endif 07121 07122 #ifndef SYMOPT_CASE_INSENSITIVE 07123 #define SYMOPT_CASE_INSENSITIVE 0x00000001 07124 #define SYMOPT_UNDNAME 0x00000002 07125 #define SYMOPT_DEFERRED_LOADS 0x00000004 07126 #define SYMOPT_NO_CPP 0x00000008 07127 #define SYMOPT_LOAD_LINES 0x00000010 07128 #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 07129 #define SYMOPT_LOAD_ANYTHING 0x00000040 07130 #define SYMOPT_IGNORE_CVREC 0x00000080 07131 #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 07132 #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 07133 #define SYMOPT_EXACT_SYMBOLS 0x00000400 07134 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 07135 #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 07136 #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 07137 #define SYMOPT_PUBLICS_ONLY 0x00004000 07138 #define SYMOPT_NO_PUBLICS 0x00008000 07139 #define SYMOPT_AUTO_PUBLICS 0x00010000 07140 #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 07141 #define SYMOPT_SECURE 0x00040000 07142 #define SYMOPT_NO_PROMPTS 0x00080000 07143 #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 07144 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 07145 #define SYMOPT_FAVOR_COMPRESSED 0x00800000 07146 #define SYMOPT_FLAT_DIRECTORY 0x00400000 07147 #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 07148 #define SYMOPT_OVERWRITE 0x00100000 07149 #define SYMOPT_DEBUG 0x80000000 07150 #endif 07151 07152 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66. 07153 07154 #ifndef STATUS_POSSIBLE_DEADLOCK 07155 #define STATUS_POSSIBLE_DEADLOCK 0xC0000194 07156 #endif 07157 07158 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS 07159 #define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4 07160 #endif 07161 07162 #ifndef STATUS_STACK_BUFFER_OVERRUN 07163 #define STATUS_STACK_BUFFER_OVERRUN 0xC0000409 07164 #endif 07165 07166 #ifndef STATUS_ASSERTION_FAILURE 07167 #define STATUS_ASSERTION_FAILURE 0xC0000420 07168 #endif 07169 07170 #ifndef STATUS_WX86_BREAKPOINT 07171 #define STATUS_WX86_BREAKPOINT 0x4000001F 07172 #endif 07173 07174 #ifndef DBG_PRINTEXCEPTION_C 07175 #define DBG_PRINTEXCEPTION_C 0x40010006 // OutputDebugStringA() call 07176 #endif 07177 07178 #ifndef DBG_PRINTEXCEPTION_WIDE_C 07179 #define DBG_PRINTEXCEPTION_WIDE_C 0x4001000A // OutputDebugStringW() call 07180 #endif 07181 07182 #ifndef DBG_THREAD_NAME 07183 #define DBG_THREAD_NAME 0x406D1388 07184 #endif 07185 07186 #define EXCEPTION_CPP_MSC 0xE06D7363 // '?msc' 07187 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 0x19930520 // '?msc' version magic, see ehdata.h 07188 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 0x19930521 // '?msc' version magic 07189 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 0x19930522 // '?msc' version magic 07190 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1 0x01994000 // '?msc' version magic 07191 07192 #define EXCEPTION_CPP_GCC 0x20474343 // ' GCC' 07193 #define EXCEPTION_CPP_GCC_UNWIND 0x21474343 // '!GCC' 07194 #define EXCEPTION_CPP_GCC_FORCED 0x22474343 // '"GCC' 07195 07196 #define EXCEPTION_CLR_FAILURE 0xE0434f4D // 'аCOM' 07197 07198 #define EXCEPTION_CPP_BORLAND_BUILDER 0x0EEDFAE6 // Should never occur here 07199 #define EXCEPTION_CPP_BORLAND_DELPHI 0x0EEDFADE // Should never occur here 07200 07201 #pragma pack (push, 1) 07202 07203 struct CONSOLE_CURSOR_INFO 07204 { 07205 DWORD dwSize; 07206 BOOL bVisible; 07207 }; 07208 07209 struct CONSOLE_FONT_INFO 07210 { 07211 DWORD nFont; 07212 COORD dwFontSize; 07213 }; 07214 07215 struct CONSOLE_FONT_INFOEX 07216 { 07217 ULONG cbSize; 07218 DWORD nFont; 07219 COORD dwFontSize; 07220 UINT FontFamily; 07221 UINT FontWeight; 07222 WCHAR FaceName[LF_FACESIZE]; 07223 }; 07224 07225 struct DATABLOCK_HEADER 07226 { 07227 DWORD cbSize; 07228 DWORD dwSignature; 07229 }; 07230 07231 struct NT_CONSOLE_PROPS 07232 { 07233 DATABLOCK_HEADER dbh; 07234 07235 WORD wFillAttribute; 07236 WORD wPopupFillAttribute; 07237 COORD dwScreenBufferSize; 07238 COORD dwWindowSize; 07239 COORD dwWindowOrigin; 07240 DWORD nFont; 07241 DWORD nInputBufferSize; 07242 COORD dwFontSize; 07243 UINT uFontFamily; 07244 UINT uFontWeight; 07245 WCHAR FaceName[LF_FACESIZE]; 07246 UINT uCursorSize; 07247 BOOL bFullScreen; 07248 BOOL bQuickEdit; 07249 BOOL bInsertMode; 07250 BOOL bAutoPosition; 07251 UINT uHistoryBufferSize; 07252 UINT uNumberOfHistoryBuffers; 07253 BOOL bHistoryNoDup; 07254 07255 COLORREF ColorTable[16]; 07256 }; 07257 07258 struct FLASHWINFO 07259 { 07260 UINT cbSize; 07261 HWND hwnd; 07262 DWORD dwFlags; 07263 UINT uCount; 07264 DWORD dwTimeout; 07265 }; 07266 07267 enum TBPFLAG 07268 { 07269 TBPF_NOPROGRESS = 0x0, 07270 TBPF_INDETERMINATE = 0x1, 07271 TBPF_NORMAL = 0x2, 07272 TBPF_ERROR = 0x4, 07273 TBPF_PAUSED = 0x8 07274 }; 07275 07276 #pragma pack (pop) 07277 07278 const GUID IID_IShellLink = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 07279 const GUID IID_IShellLinkDataList = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}}; 07280 const GUID IID_IPersistFile = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 07281 07282 const GUID IID_ITaskbarList3 = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}}; 07283 const GUID CLSID_TaskbarList = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}}; 07284 07285 const GUID CLSID_SpVoice = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}}; 07286 const GUID IID_ISpVoice = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}}; 07287 07288 typedef DWORD NTSTATUS; 07289 typedef ULONG_PTR KAFFINITY; 07290 typedef LONG KPRIORITY; 07291 07292 struct UNICODE_STRING 07293 { 07294 USHORT Length; 07295 USHORT MaximumLength; 07296 wchar_t* Buffer; 07297 }; 07298 07299 struct RTL_DRIVE_LETTER_CURDIR 07300 { 07301 USHORT Flags; 07302 USHORT Length; 07303 ULONG TimeStamp; 07304 UNICODE_STRING DosPath; 07305 }; 07306 07307 struct CURDIR 07308 { 07309 UNICODE_STRING DosPath; 07310 void* Handle; 07311 }; 07312 07313 struct RTL_USER_PROCESS_PARAMETERS 07314 { 07315 ULONG AllocationSize; 07316 ULONG Size; 07317 ULONG Flags; 07318 ULONG DebugFlags; 07319 HANDLE ConsoleHandle; 07320 ULONG ConsoleFlags; 07321 HANDLE hStdInput; 07322 HANDLE hStdOutput; 07323 HANDLE hStdError; 07324 CURDIR CurrentDirectory; 07325 UNICODE_STRING DllPath; 07326 UNICODE_STRING ImagePathName; 07327 UNICODE_STRING CommandLine; 07328 wchar_t* Environment; 07329 ULONG dwX; 07330 ULONG dwY; 07331 ULONG dwXSize; 07332 ULONG dwYSize; 07333 ULONG dwXCountChars; 07334 ULONG dwYCountChars; 07335 ULONG dwFillAttribute; 07336 ULONG dwFlags; 07337 ULONG wShowWindow; 07338 UNICODE_STRING WindowTitle; 07339 UNICODE_STRING Desktop; 07340 UNICODE_STRING ShellInfo; 07341 UNICODE_STRING RuntimeInfo; 07342 RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; 07343 }; 07344 07345 struct PEB 07346 { 07347 BYTE Reserved1[2]; 07348 BYTE BeingDebugged; 07349 BYTE Reserved2[1]; 07350 void* Reserved3[2]; 07351 void* Ldr; 07352 RTL_USER_PROCESS_PARAMETERS* ProcessParameters; 07353 void* Reserved4[3]; 07354 void* AtlThunkSListPtr; 07355 void* Reserved5; 07356 ULONG Reserved6; 07357 void* Reserved7; 07358 ULONG Reserved8; 07359 ULONG AtlThunkSListPtr32; 07360 void* Reserved9[45]; 07361 BYTE Reserved10[96]; 07362 void* PostProcessInitRoutine; 07363 BYTE Reserved11[128]; 07364 void* Reserved12[1]; 07365 ULONG SessionId; 07366 }; 07367 07368 struct TEB 07369 { 07370 void* Reserved1[12]; 07371 PEB* ProcessEnvironmentBlock; 07372 void* Reserved2[399]; 07373 BYTE Reserved3[1952]; 07374 void* TlsSlots[64]; 07375 BYTE Reserved4[8]; 07376 void* Reserved5[26]; 07377 void* ReservedForOle; 07378 void* Reserved6[4]; 07379 void* TlsExpansionSlots; 07380 }; 07381 07382 struct PROCESS_BASIC_INFORMATION 07383 { 07384 NTSTATUS ExitStatus; 07385 PEB* PebBaseAddress; 07386 KAFFINITY AffinityMask; 07387 KPRIORITY BasePriority; 07388 ULONG_PTR UniqueProcessId; 07389 ULONG_PTR InheritedFromUniqueProcessId; 07390 }; 07391 07392 enum ADDRESS_MODE 07393 { 07394 AddrMode1616, 07395 AddrMode1632, 07396 AddrModeReal, 07397 AddrModeFlat 07398 }; 07399 07400 struct ADDRESS64 07401 { 07402 DWORD64 Offset; 07403 WORD Segment; 07404 ADDRESS_MODE Mode; 07405 }; 07406 07407 struct KDHELP64 07408 { 07409 DWORD64 Thread; 07410 DWORD ThCallbackStack; 07411 DWORD ThCallbackBStore; 07412 DWORD NextCallback; 07413 DWORD FramePointer; 07414 DWORD64 KiCallUserMode; 07415 DWORD64 KeUserCallbackDispatcher; 07416 DWORD64 SystemRangeStart; 07417 DWORD64 KiUserExceptionDispatcher; 07418 DWORD64 StackBase; 07419 DWORD64 StackLimit; 07420 DWORD64 Reserved[5]; 07421 }; 07422 07423 struct STACKFRAME64 07424 { 07425 ADDRESS64 AddrPC; 07426 ADDRESS64 AddrReturn; 07427 ADDRESS64 AddrFrame; 07428 ADDRESS64 AddrStack; 07429 ADDRESS64 AddrBStore; 07430 void* FuncTableEntry; 07431 DWORD64 Params[4]; 07432 BOOL Far; 07433 BOOL Virtual; 07434 DWORD64 Reserved[3]; 07435 KDHELP64 KdHelp; 07436 }; 07437 07438 struct WOW64_FLOATING_SAVE_AREA 07439 { 07440 DWORD ControlWord; 07441 DWORD StatusWord; 07442 DWORD TagWord; 07443 DWORD ErrorOffset; 07444 DWORD ErrorSelector; 07445 DWORD DataOffset; 07446 DWORD DataSelector; 07447 BYTE RegisterArea[80]; 07448 DWORD Cr0NpxState; 07449 }; 07450 07451 #pragma pack (push, 4) 07452 07453 struct WOW64_CONTEXT 07454 { 07455 DWORD ContextFlags; 07456 07457 DWORD Dr0; 07458 DWORD Dr1; 07459 DWORD Dr2; 07460 DWORD Dr3; 07461 DWORD Dr6; 07462 DWORD Dr7; 07463 07464 WOW64_FLOATING_SAVE_AREA FloatSave; 07465 07466 DWORD SegGs; 07467 DWORD SegFs; 07468 DWORD SegEs; 07469 DWORD SegDs; 07470 07471 DWORD Edi; 07472 DWORD Esi; 07473 DWORD Ebx; 07474 DWORD Edx; 07475 DWORD Ecx; 07476 DWORD Eax; 07477 07478 DWORD Ebp; 07479 DWORD Eip; 07480 DWORD SegCs; 07481 DWORD EFlags; 07482 DWORD Esp; 07483 DWORD SegSs; 07484 07485 BYTE ExtendedRegisters[512]; 07486 }; 07487 07488 #pragma pack (pop) 07489 07490 struct SYMBOL_INFO 07491 { 07492 ULONG SizeOfStruct; 07493 ULONG TypeIndex; 07494 ULONG64 Reserved[2]; 07495 ULONG info; 07496 ULONG Size; 07497 ULONG64 ModBase; 07498 ULONG Flags; 07499 ULONG64 Value; 07500 ULONG64 Address; 07501 ULONG Register; 07502 ULONG Scope; 07503 ULONG Tag; 07504 ULONG NameLen; 07505 ULONG MaxNameLen; 07506 char Name[1]; 07507 }; 07508 07509 struct IMAGEHLP_LINE64 07510 { 07511 DWORD SizeOfStruct; 07512 void* Key; 07513 DWORD LineNumber; 07514 char* FileName; 07515 DWORD64 Address; 07516 }; 07517 07518 typedef bool (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64) (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead); 07519 typedef void* (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress); 07520 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64) (HANDLE process, DWORD64 address); 07521 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64) (HANDLE process, HANDLE thread, ADDRESS64* address); 07522 07523 typedef void (*unexpected_handler)(); 07524 07525 #pragma pack (push, 4) 07526 07527 #if !defined (_TX_NO_MINIDUMP) 07528 07529 struct MINIDUMP_THREAD_CALLBACK 07530 { 07531 ULONG ThreadId; 07532 HANDLE ThreadHandle; 07533 CONTEXT Context; 07534 ULONG SizeOfContext; 07535 ULONG64 StackBase; 07536 ULONG64 StackEnd; 07537 }; 07538 07539 struct MINIDUMP_THREAD_EX_CALLBACK 07540 { 07541 ULONG ThreadId; 07542 HANDLE ThreadHandle; 07543 CONTEXT Context; 07544 ULONG SizeOfContext; 07545 ULONG64 StackBase; 07546 ULONG64 StackEnd; 07547 ULONG64 BackingStoreBase; 07548 ULONG64 BackingStoreEnd; 07549 }; 07550 07551 struct MINIDUMP_MODULE_CALLBACK 07552 { 07553 wchar_t* FullPath; 07554 ULONG64 BaseOfImage; 07555 ULONG SizeOfImage; 07556 ULONG CheckSum; 07557 ULONG TimeDateStamp; 07558 VS_FIXEDFILEINFO VersionInfo; 07559 void* CvRecord; 07560 ULONG SizeOfCvRecord; 07561 void* MiscRecord; 07562 ULONG SizeOfMiscRecord; 07563 }; 07564 07565 struct MINIDUMP_INCLUDE_THREAD_CALLBACK 07566 { 07567 ULONG ThreadId; 07568 }; 07569 07570 struct MINIDUMP_INCLUDE_MODULE_CALLBACK 07571 { 07572 ULONG64 BaseOfImage; 07573 }; 07574 07575 struct MINIDUMP_MEMORY_INFO 07576 { 07577 ULONG64 BaseAddress; 07578 ULONG64 AllocationBase; 07579 ULONG32 AllocationProtect; 07580 ULONG32 __alignment1; 07581 ULONG64 RegionSize; 07582 ULONG32 State; 07583 ULONG32 Protect; 07584 ULONG32 Type; 07585 ULONG32 __alignment2; 07586 }; 07587 07588 struct MINIDUMP_USER_STREAM 07589 { 07590 ULONG32 Type; 07591 ULONG BufferSize; 07592 void* Buffer; 07593 }; 07594 07595 struct MINIDUMP_USER_STREAM_INFORMATION 07596 { 07597 ULONG UserStreamCount; 07598 MINIDUMP_USER_STREAM* UserStreamArray; 07599 }; 07600 07601 struct MINIDUMP_CALLBACK_INPUT 07602 { 07603 ULONG ProcessId; 07604 HANDLE ProcessHandle; 07605 ULONG CallbackType; 07606 07607 union //-V2514 07608 { 07609 MINIDUMP_THREAD_CALLBACK Thread; 07610 MINIDUMP_THREAD_EX_CALLBACK ThreadEx; 07611 MINIDUMP_MODULE_CALLBACK Module; 07612 MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; 07613 MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; 07614 }; 07615 }; 07616 07617 struct MINIDUMP_CALLBACK_OUTPUT 07618 { 07619 union //-V2514 07620 { 07621 ULONG ModuleWriteFlags; 07622 ULONG ThreadWriteFlags; 07623 ULONG SecondaryFlags; 07624 07625 struct 07626 { 07627 ULONG64 MemoryBase; 07628 ULONG MemorySize; 07629 }; 07630 07631 struct 07632 { 07633 unsigned CheckCancel; 07634 unsigned Cancel; 07635 }; 07636 07637 HANDLE Handle; //-V117 07638 }; 07639 07640 struct 07641 { 07642 MINIDUMP_MEMORY_INFO VmRegion; 07643 unsigned Continue; 07644 }; 07645 07646 HRESULT Status; 07647 }; 07648 07649 struct MINIDUMP_EXCEPTION_INFORMATION 07650 { 07651 DWORD ThreadId; 07652 EXCEPTION_POINTERS* ExceptionPointers; 07653 unsigned ClientPointers; 07654 }; 07655 07656 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output); 07657 07658 struct MINIDUMP_CALLBACK_INFORMATION 07659 { 07660 MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; 07661 void* CallbackParam; 07662 }; 07663 07664 #endif // _TX_NO_MINIDUMP 07665 07666 enum MINIDUMP_TYPE 07667 { 07668 MiniDumpNormal = 0x00000000, 07669 MiniDumpWithDataSegs = 0x00000001, 07670 MiniDumpWithFullMemory = 0x00000002, 07671 MiniDumpWithHandleData = 0x00000004, 07672 MiniDumpFilterMemory = 0x00000008, 07673 MiniDumpScanMemory = 0x00000010, 07674 MiniDumpWithUnloadedModules = 0x00000020, 07675 MiniDumpWithIndirectlyReferencedMemory = 0x00000040, 07676 MiniDumpFilterModulePaths = 0x00000080, 07677 MiniDumpWithProcessThreadData = 0x00000100, 07678 MiniDumpWithPrivateReadWriteMemory = 0x00000200, 07679 MiniDumpWithoutOptionalData = 0x00000400, 07680 MiniDumpWithFullMemoryInfo = 0x00000800, 07681 MiniDumpWithThreadInfo = 0x00001000, 07682 MiniDumpWithCodeSegs = 0x00002000, 07683 MiniDumpWithoutAuxiliaryState = 0x00004000, 07684 MiniDumpWithFullAuxiliaryState = 0x00008000, 07685 MiniDumpWithPrivateWriteCopyMemory = 0x00010000, 07686 MiniDumpIgnoreInaccessibleMemory = 0x00020000, 07687 MiniDumpWithTokenInformation = 0x00040000 07688 }; 07689 07690 #ifndef CONTEXT_ALL 07691 #define CONTEXT_ALL ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS ) 07692 #endif 07693 07694 #pragma pack (pop) 07695 07696 } // namespace Win32 07697 07698 #endif // TX_COMPILED 07699 07700 #define FOREGROUND_BLACK ( 0 ) 07701 #define FOREGROUND_CYAN ( FOREGROUND_BLUE | FOREGROUND_GREEN ) 07702 #define FOREGROUND_MAGENTA ( FOREGROUND_BLUE | FOREGROUND_RED ) 07703 #define FOREGROUND_DARKYELLOW ( FOREGROUND_GREEN | FOREGROUND_RED ) 07704 #define FOREGROUND_LIGHTGRAY ( FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ) 07705 #define FOREGROUND_DARKGRAY ( FOREGROUND_INTENSITY ) 07706 #define FOREGROUND_LIGHTBLUE ( FOREGROUND_BLUE | FOREGROUND_INTENSITY ) 07707 #define FOREGROUND_LIGHTGREEN ( FOREGROUND_GREEN | FOREGROUND_INTENSITY ) 07708 #define FOREGROUND_LIGHTCYAN ( FOREGROUND_CYAN | FOREGROUND_INTENSITY ) 07709 #define FOREGROUND_LIGHTRED ( FOREGROUND_RED | FOREGROUND_INTENSITY ) 07710 #define FOREGROUND_LIGHTMAGENTA ( FOREGROUND_MAGENTA | FOREGROUND_INTENSITY ) 07711 #define FOREGROUND_YELLOW ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY ) 07712 #define FOREGROUND_WHITE ( FOREGROUND_LIGHTGRAY | FOREGROUND_INTENSITY ) 07713 07714 #define BACKGROUND_BLACK ( 0 ) 07715 #define BACKGROUND_CYAN ( BACKGROUND_BLUE | BACKGROUND_GREEN ) 07716 #define BACKGROUND_MAGENTA ( BACKGROUND_BLUE | BACKGROUND_RED ) 07717 #define BACKGROUND_DARKYELLOW ( BACKGROUND_GREEN | BACKGROUND_RED ) 07718 #define BACKGROUND_GRAY ( BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED ) 07719 #define BACKGROUND_DARKGRAY ( BACKGROUND_INTENSITY ) 07720 #define BACKGROUND_LIGHTBLUE ( BACKGROUND_BLUE | BACKGROUND_INTENSITY ) 07721 #define BACKGROUND_LIGHTGREEN ( BACKGROUND_GREEN | BACKGROUND_INTENSITY ) 07722 #define BACKGROUND_LIGHTCYAN ( BACKGROUND_CYAN | BACKGROUND_INTENSITY ) 07723 #define BACKGROUND_LIGHTRED ( BACKGROUND_RED | BACKGROUND_INTENSITY ) 07724 #define BACKGROUND_LIGHTMAGENTA ( BACKGROUND_MAGENTA | BACKGROUND_INTENSITY ) 07725 #define BACKGROUND_LIGHTYELLOW ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY ) 07726 #define BACKGROUND_WHITE ( BACKGROUND_DARKGRAY | BACKGROUND_INTENSITY ) 07727 07728 //} 07729 //----------------------------------------------------------------------------------------------------------------- 07730 07731 //----------------------------------------------------------------------------------------------------------------- 07732 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode. 07733 // So we have to override them. See: http://stackoverflow.com/questions/39113168 07734 //----------------------------------------------------------------------------------------------------------------- 07735 07736 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07737 07738 #if defined (_MSC_VER) 07739 // MS ABI C++ Exception Layout 07740 namespace Win32 { // --------------------------- 07741 // 07742 #pragma pack (push, 4) // EXCEPTION_RECORD: 07743 // +==================================================+ 07744 struct ThrowInfo // |... | 07745 { // |NumberParameters: 3, 4 or more | 07746 __int32 attributes; // |ExceptionInformation[0]: MS signature 0x19930520 | 07747 __int32 pmfnUnwind; // |ExceptionInformation[1]: object* thrown | 07748 __int32 pForwardCompat; // |ExceptionInformation[2]: ThrowInfo* --------------+---+ 07749 __int32 pCatchableTypeArray; // |ExceptionInformation[3]: ImageBase (if params > 3)| | 07750 }; // +==================================================+ | 07751 // | 07752 struct CatchableTypeArray // ThrowInfo: | 07753 { // +======================================+ <-------+ 07754 __int32 nCatchableTypes; // | ... | 07755 __int32 arrayOfCatchableTypes[]; // +-----+-- pCatchableTypeArray (ptr/RVA) | 07756 }; // | +======================================+ 07757 // | 07758 struct CatchableType // | CatchableTypeArray: 07759 { // +---> +======================================+ 07760 __int32 properties; // | ... | 07761 __int32 pType; // +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) | 07762 __int32 thisDisplacement[3]; // struct _PMD // | +======================================+ 07763 __int32 sizeOrOffset; // | 07764 __int32 copyFunction; // | CatchableType: 07765 }; // +---> +====================+ 07766 // | ... | std::type_info: 07767 #pragma pack (pop) // | pType (ptr/RVA) ---+------> +==================+ 07768 // | ... | |type_info data | 07769 } // namespace Win32 // +====================+ |... | 07770 // +==================+ 07771 #endif 07772 07773 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp: 07774 07775 #define _TX_MSC__CXX_DETECT_RETHROW( exc ) \ 07776 ( \ 07777 (exc) && \ 07778 (exc) -> ExceptionCode == EXCEPTION_CPP_MSC && \ 07779 (exc) -> NumberParameters >= 3 && \ 07780 \ 07781 ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 || \ 07782 (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 || \ 07783 (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \ 07784 \ 07785 (exc) -> ExceptionInformation[2] == 0 \ 07786 ) 07787 07788 #endif // TX_COMPILED 07789 07790 //} 07791 //----------------------------------------------------------------------------------------------------------------- 07792 07793 //----------------------------------------------------------------------------------------------------------------- 07794 //{ The corresponding structures for GCC 07795 // 07796 // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h 07797 // See: http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi 07798 //----------------------------------------------------------------------------------------------------------------- 07799 07800 #if defined (_GCC_VER) 07801 07802 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07803 07804 // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0]. 07805 namespace ABI { // -------------------------------------------------------------- 07806 // 07807 struct __cxa_exception // Case A: "_Unwind_Exception* A" is undependent exception: 07808 { // -------------------------------------------------------- 07809 union { // 07810 struct // __cxa_exception: std::type_info: 07811 { // -*--+====================+ +==================+ 07812 ::std::type_info* exceptionType; // ^ |exceptionType* -----+---->|type_info data | 07813 void (*exceptionDestructor)(void*); // | |... | |... | 07814 }; // -1 | | +==================+ 07815 struct // | | | 07816 { // A >----|--+--------------------+ 07817 __cxa_exception* primaryException; // | | |unwindHeader | 07818 void (*padding)(); // +1 | | | 07819 }; // | | | | 07820 }; // V | | | 07821 // -*--- +====================+ 07822 void (*unexpected_handler)(); // |object | 07823 std::terminate_handler terminateHandler; // +--------------------+ 07824 // 07825 __cxa_exception* nextException; // Case B: "_Unwind_Exception* B" is dependent exception 07826 int handlerCount; // (unwindHeader.exception_class & 1 != 0): 07827 int handlerSwitchValue; // ----------------------------------------------------- 07828 const unsigned char* actionRecord; // 07829 const unsigned char* languageSpecificData; // __cxa_exception: __cxa_exception: 07830 void* catchTemp; // -*--+====================+ -*--+=================+ 07831 void* adjustedPtr; // ^ |primaryException* --+-- ^ |exceptionType* | 07832 // | |... | \ | |... | 07833 _Unwind_Exception unwindHeader; // -1 | | | | | | 07834 }; // | | | | | | | 07835 // B >----|--+--------------------+ | -1 +-----------------+ 07836 struct __cxa_eh_globals // | | |unwindHeader | | | |unwindHeader | 07837 { // +1 | | | | | | | 07838 __cxa_exception* caughtExceptions; // | | | | | | | | 07839 unsigned int uncaughtExceptions; // V | | | \ | | | 07840 }; // -*--- +====================+ -->*--+=================+ 07841 // |... | |object | 07842 } // namespace ABI // . . | | 07843 // +-----------------+ 07844 07845 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals(); 07846 07847 #endif // TX_COMPILED 07848 07849 #endif 07850 07851 //} 07852 //----------------------------------------------------------------------------------------------------------------- 07853 07854 //----------------------------------------------------------------------------------------------------------------- 07855 //{ Hand-made IAT. 07856 // Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :( 07857 //----------------------------------------------------------------------------------------------------------------- 07858 07859 // Hand-made DLLIMPORT helpers 07860 07861 #define _TX_DLLIMPORT( lib, retval, name, params ) TX_DLLIMPORT (true, lib ".dll", retval, name, params, WINAPI) 07862 #define _TX_DLLIMPORT_OPT( lib, retval, name, params ) TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI) 07863 #define _TX_DLLIMPORT_CRT( lib, retval, name, params ) TX_DLLIMPORT (false, lib ".dll", retval, name, params, please) 07864 07865 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) (); 07866 07867 //----------------------------------------------------------------------------------------------------------------- 07868 07869 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07870 07871 namespace Win32 { 07872 07873 _TX_DLLIMPORT ("GDI32", HDC, CreateCompatibleDC, (HDC dc)); 07874 _TX_DLLIMPORT ("GDI32", HBITMAP, CreateCompatibleBitmap, (HDC dc, int width, int height)); 07875 _TX_DLLIMPORT ("GDI32", HGDIOBJ, GetStockObject, (int object)); 07876 _TX_DLLIMPORT ("GDI32", HGDIOBJ, SelectObject, (HDC dc, HGDIOBJ object)); 07877 _TX_DLLIMPORT ("GDI32", HGDIOBJ, GetCurrentObject, (HDC dc, unsigned objectType)); 07878 _TX_DLLIMPORT ("GDI32", int, GetObjectA, (HGDIOBJ obj, int bufsize, void* buffer)); 07879 _TX_DLLIMPORT ("GDI32", DWORD, GetObjectType, (HGDIOBJ object)); 07880 _TX_DLLIMPORT ("GDI32", bool, DeleteDC, (HDC dc)); 07881 _TX_DLLIMPORT ("GDI32", bool, DeleteObject, (HGDIOBJ object)); 07882 _TX_DLLIMPORT ("GDI32", COLORREF, SetTextColor, (HDC dc, COLORREF color)); 07883 _TX_DLLIMPORT ("GDI32", COLORREF, SetBkColor, (HDC dc, COLORREF color)); 07884 _TX_DLLIMPORT ("GDI32", int, SetBkMode, (HDC dc, int bkMode)); 07885 _TX_DLLIMPORT ("GDI32", HFONT, CreateFontA, (int height, int width, int escapement, int orientation, 07886 int weight, DWORD italic, DWORD underline, DWORD strikeout, 07887 DWORD charSet, DWORD outputPrec, DWORD clipPrec, 07888 DWORD quality, DWORD pitchAndFamily, const char face[])); 07889 _TX_DLLIMPORT ("GDI32", int, EnumFontFamiliesExA, (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc, 07890 LPARAM lParam, DWORD reserved)); 07891 _TX_DLLIMPORT ("GDI32", COLORREF, SetPixel, (HDC dc, int x, int y, COLORREF color)); 07892 _TX_DLLIMPORT ("GDI32", COLORREF, GetPixel, (HDC dc, int x, int y)); 07893 _TX_DLLIMPORT ("GDI32", HPEN, CreatePen, (int penStyle, int width, COLORREF color)); 07894 _TX_DLLIMPORT ("GDI32", HBRUSH, CreateSolidBrush, (COLORREF color)); 07895 _TX_DLLIMPORT ("GDI32", bool, MoveToEx, (HDC dc, int x, int y, POINT* point)); 07896 _TX_DLLIMPORT ("GDI32", bool, LineTo, (HDC dc, int x, int y)); 07897 _TX_DLLIMPORT ("GDI32", bool, Polygon, (HDC dc, const POINT points[], int count)); 07898 _TX_DLLIMPORT ("GDI32", bool, Polyline, (HDC dc, const POINT points[], int count)); 07899 _TX_DLLIMPORT ("GDI32", bool, PolyBezier, (HDC dc, const POINT points[], int count)); 07900 _TX_DLLIMPORT ("GDI32", bool, Rectangle, (HDC dc, int x0, int y0, int x1, int y1)); 07901 _TX_DLLIMPORT ("GDI32", bool, RoundRect, (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY)); 07902 _TX_DLLIMPORT ("GDI32", bool, Ellipse, (HDC dc, int x0, int y0, int x1, int y1)); 07903 _TX_DLLIMPORT ("GDI32", bool, Arc, (HDC dc, int x0, int y0, int x1, int y1, 07904 int xStart, int yStart, int xEnd, int yEnd)); 07905 _TX_DLLIMPORT ("GDI32", bool, Pie, (HDC dc, int x0, int y0, int x1, int y1, 07906 int xStart, int yStart, int xEnd, int yEnd)); 07907 _TX_DLLIMPORT ("GDI32", bool, Chord, (HDC dc, int x0, int y0, int x1, int y1, 07908 int xStart, int yStart, int xEnd, int yEnd)); 07909 _TX_DLLIMPORT ("GDI32", bool, TextOutA, (HDC dc, int x, int y, const char string[], int length)); 07910 _TX_DLLIMPORT ("GDI32", UINT, SetTextAlign, (HDC dc, unsigned mode)); 07911 _TX_DLLIMPORT ("GDI32", bool, GetTextExtentPoint32A, (HDC dc, const char string[], int length, SIZE* size)); 07912 _TX_DLLIMPORT ("GDI32", bool, ExtFloodFill, (HDC dc, int x, int y, COLORREF color, unsigned type)); 07913 _TX_DLLIMPORT ("GDI32", bool, BitBlt, (HDC dest, int xDest, int yDest, int width, int height, 07914 HDC src, int xSrc, int ySrc, DWORD rOp)); 07915 _TX_DLLIMPORT ("GDI32", bool, StretchBlt, (HDC dest, int xDest, int yDest, int width, int height, 07916 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp)); 07917 _TX_DLLIMPORT ("GDI32", bool, PlgBlt, (HDC dest, const POINT* parallelogram, 07918 HDC src, int xSrc, int ySrc, int width, int height, 07919 HBITMAP mask, int xMask, int yMask)); 07920 _TX_DLLIMPORT ("GDI32", int, SetDIBitsToDevice, (HDC dc, int xDest, int yDest, DWORD width, DWORD height, 07921 int xSrc, int ySrc, unsigned startLine, unsigned numLines, 07922 const void* data, const BITMAPINFO* info, unsigned colorUse)); 07923 _TX_DLLIMPORT ("GDI32", int, GetDIBits, (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines, 07924 void* lpvBits, BITMAPINFO* lpbi, unsigned usage)); 07925 _TX_DLLIMPORT ("GDI32", bool, PatBlt, (HDC dc, int x0, int y0, int width, int height, DWORD rOp)); 07926 _TX_DLLIMPORT ("GDI32", int, SetROP2, (HDC dc, int mode)); 07927 _TX_DLLIMPORT ("GDI32", int, SetStretchBltMode, (HDC dc, int mode)); 07928 _TX_DLLIMPORT ("GDI32", DWORD, GdiSetBatchLimit, (DWORD limit)); 07929 _TX_DLLIMPORT ("GDI32", HBITMAP, CreateDIBSection, (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits, 07930 HANDLE section, DWORD offset)); 07931 07932 _TX_DLLIMPORT ("User32", int, DrawTextA, (HDC dc, const char text[], int length, RECT* rect, unsigned format)); 07933 _TX_DLLIMPORT ("User32", HANDLE, LoadImageA, (HINSTANCE inst, const char name[], unsigned type, 07934 int sizex, int sizey, unsigned mode)); 07935 _TX_DLLIMPORT_OPT ("User32", bool, IsHungAppWindow, (HWND wnd)); 07936 _TX_DLLIMPORT_OPT ("User32", HWND, GhostWindowFromHungWindow, (HWND wnd)); 07937 _TX_DLLIMPORT_OPT ("User32", bool, FlashWindowEx, (const FLASHWINFO* flash)); 07938 07939 _TX_DLLIMPORT ("WinMM", bool, PlaySound, (const char sound[], HMODULE mod, DWORD mode)); 07940 07941 _TX_DLLIMPORT_OPT ("MSImg32", bool, TransparentBlt, (HDC dest, int destX, int destY, int destWidth, int destHeight, 07942 HDC src, int srcX, int srcY, int srcWidth, int srcHeight, 07943 unsigned transparentColor)); 07944 _TX_DLLIMPORT_OPT ("MSImg32", bool, AlphaBlend, (HDC dest, int destX, int destY, int destWidth, int destHeight, 07945 HDC src, int srcX, int srcY, int srcWidth, int srcHeight, 07946 BLENDFUNCTION blending)); 07947 07948 _TX_DLLIMPORT ("Kernel32", void, ExitProcess, (unsigned retcode)); 07949 _TX_DLLIMPORT ("Kernel32", bool, TerminateProcess, (HANDLE process, unsigned retcode)); 07950 _TX_DLLIMPORT_OPT ("Kernel32", void, FatalExit, (int retcode)); 07951 _TX_DLLIMPORT_OPT ("Kernel32", void, FatalAppExitA, (unsigned action, const char message[])); 07952 _TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetThreadId, (HANDLE thread)); 07953 _TX_DLLIMPORT ("Kernel32", HWND, GetConsoleWindow, (void)); 07954 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetConsoleFont, (HANDLE con, DWORD fontIndex)); 07955 _TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetNumberOfConsoleFonts, (void)); 07956 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetCurrentConsoleFont, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO* curFont)); 07957 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont)); 07958 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont)); 07959 _TX_DLLIMPORT_OPT ("Kernel32", void, RtlCaptureContext, (CONTEXT* contextRecord)); 07960 _TX_DLLIMPORT_OPT ("Kernel32", USHORT, RtlCaptureStackBackTrace, (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash)); 07961 _TX_DLLIMPORT_OPT ("Kernel32", void*, AddVectoredExceptionHandler, (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler)); 07962 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler)); 07963 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetModuleHandleEx, (DWORD flags, const char moduleName[], HMODULE* module)); 07964 _TX_DLLIMPORT_OPT ("Kernel32", bool, IsWow64Process, (HANDLE process, int* isWow64Process)); 07965 _TX_DLLIMPORT_OPT ("Kernel32", bool, Wow64GetThreadContext, (HANDLE thread, WOW64_CONTEXT* context)); 07966 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetThreadStackGuarantee, (unsigned long* stackSize)); 07967 07968 _TX_DLLIMPORT ("OLE32", HRESULT, CoInitialize, (void*)); 07969 _TX_DLLIMPORT ("OLE32", HRESULT, CoCreateInstance, (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value)); 07970 _TX_DLLIMPORT ("OLE32", void, CoUninitialize, (void)); 07971 07972 _TX_DLLIMPORT ("Shell32", HINSTANCE,ShellExecuteA, (HWND wnd, const char operation[], const char file[], 07973 const char parameters[], const char directory[], int showCmd)); 07974 07975 _TX_DLLIMPORT ("ShlWAPI", char*, StrStrIA, (const char string[], const char search[])); 07976 _TX_DLLIMPORT ("ShlWAPI", char*, StrStrIW, (const wchar_t string[], const wchar_t search[])); 07977 07978 _TX_DLLIMPORT_OPT ("NTDLL", char*, wine_get_version, (void)); 07979 _TX_DLLIMPORT ("NTDLL", NTSTATUS, NtQueryInformationProcess, (HANDLE process, int infoClass, 07980 void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo)); 07981 07982 _TX_DLLIMPORT_CRT ("MSVCRT", void, exit, (int retcode)); 07983 _TX_DLLIMPORT_CRT ("MSVCRT", void, _cexit, (void)); 07984 _TX_DLLIMPORT_CRT ("MSVCRT", unsigned, _fpreset, (void)); 07985 _TX_DLLIMPORT_CRT ("MSVCRT", unsigned, _controlfp, (unsigned control, unsigned mask)); 07986 _TX_DLLIMPORT_CRT ("MSVCRT", uintptr_t,_beginthread, (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist)); 07987 _TX_DLLIMPORT_CRT ("MSVCRT", uintptr_t,_beginthreadex, (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*), 07988 void *arglist, unsigned init_flag, unsigned* thread_addr)); 07989 _TX_DLLIMPORT_CRT ("MSVCRT", char*, __unDName, (char* outStr, const char* mangledName, int outStrLen, 07990 void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer), 07991 unsigned short flags)); 07992 _TX_DLLIMPORT_CRT ("MSVCRT", unexpected_handler, set_unexpected, (unexpected_handler handler)); 07993 07994 _TX_DLLIMPORT_OPT ("OpenGL32", HDC, wglGetCurrentDC, (void)); 07995 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned, glGetError, (void)); 07996 _TX_DLLIMPORT_OPT ("Glu32", const char*, gluErrorString, (unsigned error)); 07997 07998 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD, CommDlgExtendedError, (void)); 07999 08000 #if !defined (_TX_NO_MINIDUMP) 08001 08002 _TX_DLLIMPORT_OPT ("DbgCo*", bool, MiniDumpWriteDump, (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType, 08003 MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, MINIDUMP_CALLBACK_INFORMATION* callbackParam)); 08004 _TX_DLLIMPORT_OPT ("DbgCore*", bool, MiniDumpWriteDump2, (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType, 08005 MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, MINIDUMP_CALLBACK_INFORMATION* callbackParam)); 08006 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, MiniDumpWriteDump3, (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType, 08007 MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, MINIDUMP_CALLBACK_INFORMATION* callbackParam)); 08008 #endif 08009 08010 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD, SymSetOptions, (DWORD options)); 08011 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymInitialize, (HANDLE process, const char userSearchPath[], bool invadeProcess)); 08012 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymFromAddr, (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO* symbol)); 08013 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymGetLineFromAddr64, (HANDLE process, DWORD64 addr, DWORD* offset, IMAGEHLP_LINE64* line)); 08014 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64, SymGetModuleBase64, (HANDLE process, DWORD64 addr)); 08015 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymCleanup, (HANDLE process)); 08016 _TX_DLLIMPORT_OPT ("DbgHelp*", void*, SymFunctionTableAccess64, (HANDLE process, DWORD64 addrBase)); 08017 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, StackWalk64, (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord, 08018 PREAD_PROCESS_MEMORY_ROUTINE64 readMemoryFunc, 08019 PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc, 08020 PGET_MODULE_BASE_ROUTINE64 getModuleBaseFunc, 08021 PTRANSLATE_ADDRESS_ROUTINE64 translateAddressFunc)); 08022 namespace MinGW { 08023 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD, SymSetOptions, (DWORD options)); 08024 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymInitialize, (HANDLE process, const char userSearchPath[], bool invadeProcess)); 08025 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymFromAddr, (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO* symbol)); 08026 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymGetLineFromAddr64, (HANDLE process, DWORD64 addr, DWORD* offset, IMAGEHLP_LINE64* line)); 08027 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64, SymGetModuleBase64, (HANDLE process, DWORD64 addr)); 08028 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymCleanup, (HANDLE process)); 08029 _TX_DLLIMPORT_OPT ("MgwHelp*", void*, SymFunctionTableAccess64, (HANDLE process, DWORD64 addrBase)); 08030 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, StackWalk64, (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord, 08031 PREAD_PROCESS_MEMORY_ROUTINE64 readMemoryFunc, 08032 PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc, 08033 PGET_MODULE_BASE_ROUTINE64 getModuleBaseFunc, 08034 PTRANSLATE_ADDRESS_ROUTINE64 translateAddressFunc)); 08035 } // namespace MinGW 08036 } // namespace Win32 08037 08038 #endif // TX_COMPILED 08039 08040 //} 08041 //----------------------------------------------------------------------------------------------------------------- 08042 08044 //} 08045 //================================================================================================================= 08046 08047 //================================================================================================================= 08048 //{ Internal function prototypes, macros and constants 08049 // @name Прототипы внутренних функций, макросы и константы 08050 //================================================================================================================= 08052 08053 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08054 08055 int _txInitialize(); 08056 void _txCleanup(); 08057 08058 HWND _txCanvas_CreateWindow (const SIZE* size); 08059 08060 bool _txCanvas_OnCREATE (HWND wnd); 08061 bool _txCanvas_OnDESTROY (HWND wnd); 08062 bool _txCanvas_OnCLOSE (HWND); 08063 bool _txCanvas_OnPAINT (HWND wnd); 08064 bool _txCanvas_OnKEY (HWND wnd, WPARAM vk, LPARAM info, bool down); 08065 bool _txCanvas_OnCHAR (HWND wnd, WPARAM ch, LPARAM info); 08066 bool _txCanvas_OnTIMER (HWND wnd, WPARAM id); 08067 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords); 08068 bool _txCanvas_OnMOUSELEAVE (HWND wnd); 08069 bool _txCanvas_OnCREATEWND (HWND wnd, WPARAM, LPARAM lpar); 08070 bool _txCanvas_OnDESTROYWND (HWND wnd, WPARAM, LPARAM lpar); 08071 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd); 08072 bool _txCanvas_OnCmdABOUT (HWND wnd, WPARAM cmd); 08073 08074 unsigned WINAPI _txCanvas_ThreadProc (void* data); 08075 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar); 08076 08077 HDC _txBuffer_Create (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL, 08078 RGBQUAD** pixels = NULL) tx_nodiscard; 08079 bool _txBuffer_Delete (HDC* dc); 08080 bool _txBuffer_Select (HGDIOBJ obj, HDC dc = txDC()); 08081 08082 HWND _txConsole_Attach(); 08083 bool _txConsole_OK() tx_nodiscard; 08084 bool _txConsole_Detach (bool activate); 08085 bool _txConsole_Draw (HDC dc); 08086 bool _txConsole_SetUnicodeFont(); 08087 08088 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra); 08089 HWND txCreateExtraWindow (CREATESTRUCT createData); 08090 HICON _txCreateTXIcon (int size) tx_nodiscard; 08091 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng = NULL, 08092 int checkOfs = 0, const wchar_t checkLetters[2] = NULL); 08093 int _txPauseBeforeTermination (HWND canvas); 08094 int _txIsParentWaitable (DWORD* parentPID = NULL) tx_nodiscard; 08095 void _txActivateWindow (HWND wnd, unsigned mode); 08096 int _txGetInput(); 08097 08098 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar); 08099 const char* _txPlayVideo_FindVLC() tx_nodiscard; 08100 08101 bool _txCreateShortcut (const char shortcutName[], 08102 const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL, 08103 const char description[] = NULL, int cmdShow = SW_SHOWNORMAL, 08104 const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0, 08105 COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD)); 08106 08107 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle, 08108 WORD controls, short x, short y, short cx, short cy, 08109 const char caption[], const char font[], WORD fontsize, 08110 const char menu[]) tx_nodiscard; 08111 08112 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle, 08113 short x, short y, short cx, short cy, 08114 WORD id, const char wclass[], const char caption[]); 08115 08116 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, 08117 const char msg[], va_list args); 08118 void _txOnTerminate(); 08119 void _txOnUnexpected(); 08120 void _txOnPureCall(); 08121 void _txOnNewHandlerAnsi(); 08122 int _txOnNewHandler (size_t size); 08123 void _txOnSignal (int signal = 0, int fpe = 0); 08124 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type); 08125 void _txOnSecurityError (int code, void*); 08126 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code); 08127 int _txOnMatherr (_exception* except); 08128 void _txOnInvalidParam (const wchar_t* expr, const wchar_t* func, const wchar_t* file, 08129 unsigned line, uintptr_t); 08130 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, 08131 const unsigned char* file, int line); 08132 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5); 08133 int _txOnErrorReport (int type, const char* text, int* ret); 08134 int tx_glGetError (int setError = INT_MIN); 08135 08136 void _txOnCExit(); 08137 void _txOnExit (int retcode); 08138 void _txOnFatalExit (int retcode); 08139 void _txOnExitProcess (unsigned retcode); 08140 void _txOnFatalAppExitA (unsigned action, const char message[]); 08141 bool _txOnTerminateProcess (HANDLE process, unsigned retcode); 08142 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI 08143 _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter); 08144 void _txWatchdogTerminator (void* timeout); // Only Arnold-type series are supported, not T1000 08145 08146 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc); 08147 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc); 08148 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[]); 08149 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]); 08150 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type); 08151 intptr_t _txDumpExceptionCPP (char what[], intptr_t size, unsigned code = 0, 08152 unsigned params = 0, const ULONG_PTR info[] = NULL); 08153 08154 void _txStackBackTrace (const char file[] = "?", int line = 0, const char func[] = "?", 08155 bool readSource = true); 08156 const char* _txCaptureStackBackTrace (int framesToSkip = 0, bool readSource = true, 08157 CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread()); 08158 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL, 08159 HANDLE thread = GetCurrentThread()); 08160 const char* _txCaptureStackBackTraceTX (int framesToSkip = 0, bool readSource = false); 08161 08162 const char* _txSymPrintFromAddr (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2); 08163 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol = NULL, 08164 Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL, 08165 const char** source = NULL, int context = 2); 08166 intptr_t _txReadSource (char buf[], intptr_t size, const char file[], 08167 int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN); 08168 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL, 08169 int useHotPatching = false, HMODULE module = NULL, bool debug = false); 08170 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc = NULL); 08171 08172 bool _txInDll() tx_nodiscard; 08173 PROCESSENTRY32* _txFindProcess (unsigned pid = GetCurrentProcessId()) tx_nodiscard; 08174 bool _txKillProcess (DWORD pid); 08175 int _txTaskKill (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/); 08176 bool _txCheckSourceCP (int needCP = _TX_CODEPAGE, bool verbose = true); 08177 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid()); 08178 IMAGE_NT_HEADERS*_txGetNtHeaders (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard; 08179 bool _txIsConsoleSubsystem(); 08180 const char* _txAppInfo() tx_nodiscard; 08181 08182 #if defined (_CLANG_VER) && !defined (_MSC_VER) 08183 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info); 08184 #endif 08185 08186 #endif // TX_COMPILED 08187 08188 inline bool _txCanvas_OK () tx_nodiscard; 08189 int _txCanvas_SetRefreshLock (int count); 08190 08191 const char* _txError (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0, 08192 const char msg[] = NULL, ...) tx_printfy (5); 08193 08194 bool _txIsBadReadPtr (const void* address); 08195 08196 intptr_t _tx_snprintf_s (char stream[], intptr_t size, const char format[], ...) tx_printfy (3); 08197 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg); 08198 bool _txIsTTY (int fd); 08199 void txReopenStdio(); 08200 08201 #if defined (__CYGWIN__) 08202 08203 int _getch(); 08204 int _putch (int ch); 08205 int _kbhit() tx_nodiscard; 08206 08207 #endif 08208 08209 //----------------------------------------------------------------------------------------------------------------- 08210 // There are macros for __FILE__ and __LINE__ to work properly. 08211 08212 #if !defined (NDEBUG) 08213 08214 #define _TX_ARGUMENT_FAILED( cond ) ( !(cond) && \ 08215 (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1) && \ 08216 (assert (cond), true) ) 08217 08218 #define _TX_TXWINDOW_FAILED() ( !txOK() && \ 08219 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08220 (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) ) 08221 08222 #define _TX_HDC_FAILED( dc ) ( !Win32::GetObjectType (dc) && \ 08223 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08224 (TX_ERROR ("\a" "Параметр \"%s\" неверен." \ 08225 " Возможно, этот холст не создан, или уже уничтожен, " \ 08226 "или не загрузилась картинка.", #dc), 1) ) 08227 #define _TX_DEFAULT_HDC_FAILED( dc ) ( !(dc) && \ 08228 (TX_ERROR ("\a" "%s" \ 08229 "Если вы указали параметр \"%s\", то он неверен.%s", \ 08230 (!txWindow()? "Окно рисования не создано или не в порядке.\n" : ""), \ 08231 #dc, \ 08232 ( txWindow()? " Возможно, этот холст не создан, или уже уничтожен, " \ 08233 "или не загрузилась картинка." : "")), 1) ) 08234 #else 08235 08236 #define _TX_ARGUMENT_FAILED( cond ) ( !(cond) && \ 08237 (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1) ) 08238 08239 #define _TX_TXWINDOW_FAILED() ( !txOK() && \ 08240 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08241 08242 #define _TX_HDC_FAILED( dc ) ( !Win32::GetObjectType (dc) && \ 08243 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08244 08245 #define _TX_DEFAULT_HDC_FAILED( dc ) ( !(dc) && \ 08246 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08247 #endif 08248 08249 //----------------------------------------------------------------------------------------------------------------- 08250 // Take action in debug configuration only. 08251 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'( 08252 08253 #if !defined (NDEBUG) 08254 #define _TX_ON_DEBUG( code ) { code; } 08255 #else 08256 #define _TX_ON_DEBUG( code ) ; 08257 #endif 08258 08259 //----------------------------------------------------------------------------------------------------------------- 08260 // Invokes an error without location information. "$$" restores TX-related call location context 08261 08262 #define _TX_UNEXPECTED( ... ) $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__) 08263 08264 //----------------------------------------------------------------------------------------------------------------- 08265 // Safe call of a function via its pointer 08266 08267 #define _TX_CALL( func, param ) ( (func)? ((func) param) : 0 ) 08268 #define _TX_CALLv( func, param ) ( (func)? ((func) param) : (void)0 ) 08269 08270 //----------------------------------------------------------------------------------------------------------------- 08271 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x. 08272 08273 #define _txWaitFor( cond, time ) { for (DWORD _t = GetTickCount() + (time); \ 08274 !(cond) && GetTickCount() < _t; \ 08275 Sleep (_txWindowUpdateInterval)) \ 08276 ; \ 08277 \ 08278 if (!(cond)) \ 08279 _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); } 08280 08281 //----------------------------------------------------------------------------------------------------------------- 08282 // Detouring in case of SEH mechanism 08283 08284 #define _txSetJmp() ( setjmp (_txDumpExceptionObjJmp) == 0 ) 08285 08286 #define _txClearJmp() { *(unsigned long long*) _txDumpExceptionObjJmp = 0; } 08287 08288 //----------------------------------------------------------------------------------------------------------------- 08289 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code. 08290 08291 #if defined (IN) 08292 // #undef IN 08293 #endif 08294 08295 #if defined (OUT) 08296 // #undef OUT 08297 #endif 08298 08300 //} 08301 //================================================================================================================= 08302 08303 //================================================================================================================= 08304 //{ Internal global data 08306 // 08307 // Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :) 08308 // 08309 // Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же. 08310 // Здесь это сделано только в образовательных целях. 08311 // 08312 // Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс. 08313 //================================================================================================================= 08315 08316 #ifndef TX_COMPILED // <<<<<<< THE CODE IS HERE, UNFOLD IT <<< 08317 08318 const int _TX_IDM_ABOUT = 40000, // Идентификаторы системного меню окна 08319 _TX_IDM_CONSOLE = 40001, 08320 _TX_WM_CREATEWND = 0x7FF0, // Сообщения для создания/уничтожения 08321 _TX_WM_DESTROYWND = 0x7FF1; // окон в потоке Canvas 08322 08323 //----------------------------------------------------------------------------------------------------------------- 08324 08325 volatile unsigned _txCanaryFirst = 0x776F656D; // A very system value 08326 08327 int _txInitialized = (_TX_NOINIT +0)? 0 : _txInitialize(); 08328 08329 volatile unsigned _txMainThreadId = 0; // ID потока, где выполняется main() 08330 volatile HANDLE _txMainThread = NULL; // Дексриптор этого потока 08331 08332 volatile unsigned _txCanvas_ThreadId = 0; // ID потока, владеющего окном холста TXLib 08333 volatile HANDLE _txCanvas_Thread = NULL; // Дексриптор этого потока 08334 volatile HWND _txCanvas_Window = NULL; // Дескриптор окна холста TXLib 08335 08336 HDC _txCanvas_BackBuf[2] = {NULL, // [0] Main TXLib in-memory DC, where user's pictures lies 08337 NULL}; // [1] Image ready for auto-refresh, see txCanvas_OnPAINT() 08338 08339 RGBQUAD* _txCanvas_Pixels = NULL; // Memory buffer of _txCanvas_BackBuf[0] 08340 08341 HBITMAP _txStockBitmap = NULL; // Equivalent of GetStockObject (BITMAP), 08342 // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313 08343 08344 CRITICAL_SECTION _txCanvas_LockBackBuf = {0,-1}; // Prevent simultaneous access to back buffer, see txLock() 08345 08346 UINT_PTR _txCanvas_RefreshTimer = 1; // Timer ID to redraw TXLib window 08347 volatile int _txCanvas_RefreshLock = 0; // Blocks auto on-timer canvas update, see txBegin/txEnd 08348 08349 ::std::vector<HDC>* _txCanvas_UserDCs = NULL; // List of DCs allocated, for auto-free 08350 08351 volatile bool _txConsole_IsBlinking = true; // To blink or not to blink, that is the question. 08352 08353 int _txConsole = false; // Only first TXLib module in app can own the console 08354 bool _txMain = false; // First TXLib wnd opened (closing it terminates program) 08355 bool _txIsDll = false; // TXLib module is in DLL 08356 volatile bool _txRunning = false; // main() is still running 08357 volatile bool _txExit = false; // exit() is active 08358 08359 volatile POINT _txMousePos = {-1,-1}; // Ask Captn Obviouos about it. See txCanvas_OnMOUSE() 08360 volatile unsigned _txMouseButtons = 0; 08361 08362 volatile WNDPROC _txAltWndProc = NULL; // Альтернативная оконная функция. См. txSetWindowsHook(). 08363 08364 _tx_thread _txLoc _txLoc::Cur = {}; // Execution point tracking and trace state, see "$" macro 08365 08366 volatile int _txErrors = 0; // TX_ERROR calls sequental number 08367 volatile int _txOGLError = 0; // Last OpenGL error when using tx_glGetError() 08368 volatile long _txSENumber = 0; // SEH exceptions sequental number 08369 volatile long _txSEFatalNumber = 0; // SEH fatal exceptions sequental number 08370 char _txDumpSE [_TX_BUFSIZE] = ""; // SEH dump data area 08371 char _txTraceSE[_TX_HUGEBUFSIZE] = ""; // Stack trace data area 08372 08373 LPTOP_LEVEL_EXCEPTION_FILTER _txPrevUEFilter = NULL; // Previous UnhandledExceptionFilter 08374 08375 jmp_buf _txDumpExceptionObjJmp = {}; // Hook for _txDumpExceptionObj 08376 08377 const volatile uintptr_t _txForceImport[] = { (uintptr_t) ::TerminateProcess, (uintptr_t) ::ExitProcess, 08378 (uintptr_t) ::FatalExit, (uintptr_t) ::FatalAppExitA, 08379 (uintptr_t) ::exit, (uintptr_t) Win32::_controlfp, 08380 (uintptr_t) Win32::Polyline, (uintptr_t) Win32::PolyBezier, 08381 (uintptr_t) Win32::RoundRect, (uintptr_t) Win32::RemoveVectoredExceptionHandler, 08382 (uintptr_t) Win32::PlgBlt, (uintptr_t) Win32::RtlCaptureStackBackTrace, 08383 (uintptr_t) Win32::SymInitialize, (uintptr_t) Win32::MinGW::SymInitialize, 08384 (uintptr_t) Win32::SymSetOptions, (uintptr_t) Win32::MinGW::SymSetOptions, 08385 (uintptr_t) Win32::SymGetLineFromAddr64, (uintptr_t) Win32::MinGW::SymGetLineFromAddr64, 08386 (uintptr_t) Win32::SymFromAddr, (uintptr_t) Win32::MinGW::SymFromAddr, 08387 (uintptr_t) Win32::SymCleanup, (uintptr_t) Win32::MinGW::SymCleanup, 08388 (uintptr_t) Win32::SymGetModuleBase64, (uintptr_t) Win32::MinGW::SymGetModuleBase64, 08389 (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64, 08390 (uintptr_t) Win32::StackWalk64, (uintptr_t) Win32::MinGW::StackWalk64, 08391 (uintptr_t) Win32::StrStrIA, (uintptr_t) Win32::Wow64GetThreadContext }; 08392 08393 volatile unsigned _txCanaryLast = 0x5E2E2E5E; // Another very system value 08394 08395 #endif // TX_COMPILED 08396 08397 //----------------------------------------------------------------------------------------------------------------- 08398 08399 extern volatile unsigned _txCanaryFirst; 08400 extern volatile unsigned _txCanaryLast; 08401 extern volatile HWND _txCanvas_Window; 08402 extern volatile unsigned _txCanvas_ThreadId; 08403 extern HDC _txCanvas_BackBuf[2]; 08404 extern RGBQUAD* _txCanvas_Pixels; 08405 extern volatile int _txCanvas_RefreshLock; 08406 extern volatile WNDPROC _txAltWndProc; 08407 extern volatile bool _txExit; 08408 extern volatile int _txOGLError; 08409 08411 //} 08412 //================================================================================================================= 08413 08414 //================================================================================================================= 08415 //{ TXLib engine init/check/cleanup 08417 //================================================================================================================= 08419 08420 //----------------------------------------------------------------------------------------------------------------- 08421 //{ Early initialization 08422 //----------------------------------------------------------------------------------------------------------------- 08423 08424 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08425 08426 int _txInitialize() 08427 { 08428 if (_txInitialized) return 1; 08429 _txInitialized = 1; 08430 08431 #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER) // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx 08432 _CrtSetBreakAlloc (_TX_ALLOC_BREAK); // and http://support.microsoft.com/ru-ru/kb/151585 08433 #endif 08434 08435 #if defined (_TX_ALLOW_TRACE) 08436 _txLocLvlSet (1); 08437 #endif 08438 08439 _TX_ON_DEBUG (OutputDebugString ("\n"); 08440 OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" " 08441 "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n"); 08442 OutputDebugString ("\n")); 08443 08444 _txMainThreadId = GetCurrentThreadId(); 08445 _txMainThread = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId); 08446 08447 $3 _txIsDll = _txInDll(); 08448 08449 $ if (!_txIsDll) 08450 { 08451 $ _txConsole = ! FindAtom ("_txConsole"); 08452 $ (void) AddAtom ("_txConsole"); //-V530 08453 } 08454 08455 $ if (_txConsole) 08456 { 08457 $ _txCheckSourceCP (_TX_CODEPAGE, true); 08458 08459 $ unsigned long stackSize = _TX_STACKSIZE; 08460 $ _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize)); 08461 08462 $ _txOnSignal(); 08463 08464 $ if (!*_txLogName) 08465 {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); } 08466 08467 $ if (!_txIsDll) 08468 { 08469 $ _TX_CALL (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER) _txVectoredExceptionHandler)); 08470 $ _txPrevUEFilter = SetUnhandledExceptionFilter ( (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter); 08471 } 08472 08473 $ ::std::set_terminate (_txOnTerminate); 08474 $ ::std::set_new_handler (_txOnNewHandlerAnsi); 08475 $ _TX_CALL (Win32::set_unexpected, (_txOnUnexpected)); 08476 08477 #if defined (_CLANG_VER) && !defined (_MSC_VER) 08478 $ ::std::__libcpp_debug_function = _txLibCppDebugFunction; 08479 #endif 08480 08481 $ SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true); 08482 08483 $ SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); 08484 08485 #if defined (_MSC_VER) 08486 08487 $ _set_printf_count_output (1); 08488 08489 $ _set_new_handler (_txOnNewHandler); 08490 $ _set_new_mode (1); 08491 08492 #if !defined (_CLANG_VER) 08493 08494 $ _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF); 08495 $ _CrtSetAllocHook (_txOnAllocHook); 08496 08497 $ unsigned mode = _CRTDBG_MODE_FILE; 08498 $ if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0; 08499 08500 $ _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_DEBUG | mode); 08501 $ _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW); 08502 $ _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW); 08503 $ _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR); 08504 $ _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR); 08505 $ _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR); 08506 08507 #endif 08508 08509 $ _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG); 08510 $ _set_abort_behavior (0, _CALL_REPORTFAULT); 08511 08512 $ _RTC_SetErrorFunc (_txOnRTCFailure); 08513 $ _set_purecall_handler (_txOnPureCall); 08514 $ _set_invalid_parameter_handler (_txOnInvalidParam); 08515 08516 #endif 08517 08518 #if defined (__STDC_LIB_EXT1__) 08519 $ ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi); 08520 #endif 08521 08522 #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386) 08523 $ __setusermatherr (_txOnMatherr); 08524 #endif 08525 08526 #if !defined (__CYGWIN__) 08527 $ _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR); 08528 #endif 08529 08530 $ HWND console = _txConsole_Attach(); 08531 $ SetWindowTextA (console, txGetModuleFileName (false)); 08532 } 08533 08534 $ _txSetProcAddress ("ExitProcess", (uintptr_t) _txOnExitProcess, "KERNEL32.DLL"); 08535 $ _txSetProcAddress ("TerminateProcess", (uintptr_t) _txOnTerminateProcess, "KERNEL32.DLL"); 08536 $ _txSetProcAddress ("FatalExit", (uintptr_t) _txOnFatalExit, "KERNEL32.DLL"); 08537 $ _txSetProcAddress ("FatalAppExitA", (uintptr_t) _txOnFatalAppExitA, "KERNEL32.DLL"); 08538 $ _txSetProcAddress ("UnhandledExceptionFilter", (uintptr_t) _txUnhandledExceptionFilter, "KERNEL32.DLL", true); //-V601 08539 $ _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL"); 08540 $ _txSetProcAddress ("exit", (uintptr_t) _txOnExit); 08541 $ _txSetProcAddress ("_cexit", (uintptr_t) _txOnCExit); 08542 08543 $ InitializeCriticalSection (&_txCanvas_LockBackBuf); 08544 08545 $ HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted; 08546 $ _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted; 08547 $ Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted; 08548 $ Win32::DeleteDC (dc) asserted; 08549 08550 $ atexit (_txCleanup); 08551 08552 $ if (_txConsole) 08553 { 08554 $ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 08555 08556 $ tx_fpreset(); 08557 08558 $ srand ((unsigned) time (NULL)); //-V202 08559 08560 $ SetLastError (0); 08561 $ errno = 0; 08562 08563 #if !defined (__CYGWIN__) 08564 $ _doserrno = 0; 08565 #endif 08566 } 08567 08568 $ Win32::CoCreateInstance = Win32::CoCreateInstance; // g++ 5.1.0 bug, false warning "defined but not used" 08569 08570 $ return 1; 08571 } 08572 08573 //----------------------------------------------------------------------------------------------------------------- 08574 08575 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/) 08576 { 08577 $3 const char* sCodePage = NULL; 08578 $ int codePage = 0; 08579 08580 $ switch (((unsigned const char*) "А") [0]) 08581 { 08582 case 192: {$ codePage = 1251; sCodePage = "1251."; break; } 08583 case 208: {$ codePage = 65001; sCodePage = "UTF-8."; break; } 08584 case 128: {$ codePage = 866; sCodePage = "866."; break; } 08585 case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; } 08586 default: {$ codePage = -1; sCodePage = "(Unknown)"; break; } 08587 } 08588 08589 $ if (codePage != needCP && verbose) 08590 { 08591 $ *_txTraceSE = ' '; // No stack trace please 08592 08593 $ _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n" 08594 "This is NOT an error of TXLib itself. Please note:\n\n" 08595 "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your " 08596 "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO " 08597 "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. " 08598 "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n" 08599 "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n" 08600 "You can continue, but Russian messages and symbols may appear unreadable.", 08601 sCodePage, needCP, needCP); 08602 } 08603 08604 $ return (codePage == needCP); 08605 } 08606 08607 //----------------------------------------------------------------------------------------------------------------- 08608 08609 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) () 08610 { 08611 if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL; 08612 if (_TX_ARGUMENT_FAILED (funcName && *funcName)) return NULL; 08613 08614 static char dllPaths [2][MAX_PATH] = {"", ""}; 08615 08616 if (!*dllPaths[0]) 08617 { 08618 const char dllDir[] = "\\Windows\\"; 08619 08620 // dllPaths[0] is relative to the TX Setup directory stored in the Registry 08621 08622 char* path = dllPaths[0]; 08623 08624 txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH); 08625 strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08626 08627 // dllPaths[1] is relative to TXib.h file used in compilation 08628 08629 path = dllPaths[1]; 08630 08631 if (strchr (__FILE__, ':')) 08632 { 08633 strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1); 08634 } 08635 else 08636 { 08637 GetCurrentDirectory (MAX_PATH, path); 08638 strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1); 08639 } 08640 08641 if (char* dir = strrchr (path, '\\')) *dir = 0; 08642 08643 strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08644 } 08645 08646 char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = ""; 08647 const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL); //-V547 08648 08649 if (arch) 08650 { 08651 assert (arch >= dllFileName); //-V547 08652 08653 strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName)); 08654 strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName)); 08655 08656 strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName)); 08657 strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3); 08658 strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch)); 08659 } 08660 else if (dllFileName) //-V547 //-V2516 08661 { 08662 strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1); 08663 } 08664 08665 HMODULE dll = GetModuleHandle (dllFileName); 08666 08667 if (!dll) dll = GetModuleHandle (dllArch); 08668 if (!dll) dll = GetModuleHandle (dllName); 08669 08670 for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++) 08671 { 08672 char path [MAX_PATH] = ""; 08673 strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i])); 08674 size_t len = strlen (path); 08675 08676 strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch)); 08677 if (!dll) dll = LoadLibrary (path); //-V547 08678 08679 strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName)); 08680 if (!dll) dll = LoadLibrary (path); 08681 } 08682 08683 if (!dll) dll = LoadLibrary (dllArch); 08684 if (!dll) dll = LoadLibrary (dllName); 08685 08686 if (!dll && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".", dllName, (arch? "\" / \"" : ""), dllArch); 08687 if (!dll) return NULL; 08688 08689 void (*addr)() = (void(*)()) GetProcAddress (dll, funcName); 08690 08691 if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".", funcName, dllName, (arch? "\" / \"" : ""), dllArch); 08692 return addr; 08693 } 08694 08695 //----------------------------------------------------------------------------------------------------------------- 08696 08697 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013 08698 #pragma warning (push) 08699 #pragma warning (disable: 6102) // Использование 'name' из завершившегося ошибкой вызова функции 08700 #endif 08701 08702 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue) 08703 { 08704 if (_TX_ARGUMENT_FAILED (keyName)) return 0; 08705 08706 HKEY hive = NULL; 08707 08708 #define EQU_(name1, name2) ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \ 08709 _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 ) 08710 08711 if (EQU_("HKLM", "HKEY_LOCAL_MACHINE")) hive = HKEY_LOCAL_MACHINE; 08712 else if (EQU_("HKCU", "HKEY_CURRENT_USER")) hive = HKEY_CURRENT_USER; 08713 else if (EQU_("HKCR", "HKEY_CLASSES_ROOT")) hive = HKEY_CLASSES_ROOT; 08714 else if (EQU_("HKU", "HKEY_USERS")) hive = HKEY_USERS; 08715 else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG; 08716 08717 else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; } 08718 08719 #undef EQU_ 08720 08721 keyName = strchr (keyName, '\\') + 1; //-V769 08722 assert (keyName > (const char*) 1); 08723 08724 HKEY key = NULL; 08725 DWORD size = 0; 08726 08727 bool ok = (RegOpenKeyEx (hive, keyName, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS); 08728 if (ok) ok &= (RegQueryValueEx (key, valueName, NULL, NULL, NULL, &size) == ERROR_SUCCESS); 08729 if (ok && value && size < szValue) ok &= (RegQueryValueEx (key, valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS); //-V104 08730 if (key) ok &= (RegCloseKey (key) == ERROR_SUCCESS); 08731 08732 return size; 08733 } 08734 08735 #if defined (_MSC_VER) && (_MSC_VER == 1800) 08736 #pragma warning (pop) 08737 #endif 08738 08739 #endif // TX_COMPILED 08740 08741 //} 08742 //----------------------------------------------------------------------------------------------------------------- 08743 08744 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08745 08746 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/) 08747 { 08748 $1 if (!_txInitialized) _txInitialized = _txInitialize(); 08749 08750 $ if (HWND wnd = txWindow()) 08751 { 08752 $ SetLastErrorEx (ERROR_INVALID_DATA, 0); 08753 $ _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!")); 08754 $ return wnd; 08755 } 08756 08757 $ if (!_txIsDll) 08758 { 08759 $ _txMain = ! FindAtom ("_txMain"); // Not a thread-safe 08760 $ (void) AddAtom ("_txMain"); //-V530 08761 } 08762 08763 $ if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; } //-V1048 08764 08765 $ _txRunning = false; 08766 08767 // Store the size 08768 08769 $ static SIZE size = { ROUND (sizeX), ROUND (sizeY) }; 08770 $ if (centered) { size.cx *= -1; size.cy *= -1; } 08771 08772 // In Thread, where REAL creation lies... 08773 08774 $ unsigned id = 0; 08775 $ _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id); 08776 08777 $ if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."), (HWND) NULL; 08778 08779 $ _txWaitFor (_txRunning, 10*_TX_TIMEOUT); 08780 08781 $ if (!_txRunning) return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL; 08782 $ if (!txOK()) return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."), (HWND) NULL; 08783 08784 $ HWND console = Win32::GetConsoleWindow(); 08785 08786 $ DWORD proc = 0; 08787 $ GetWindowThreadProcessId (console, &proc); 08788 08789 $ if (console && (proc == GetCurrentProcessId() || _txIsParentWaitable())) 08790 {$ ShowWindow (console, TX_CONSOLE_MODE); } 08791 08792 $ HMENU menu = GetSystemMenu (txWindow(), false); 08793 if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); } 08794 08795 $ Win32::GdiSetBatchLimit (1); 08796 08797 $ SetLastError (0); 08798 08799 $ errno = 0; 08800 08801 #if !defined (__CYGWIN__) 08802 $ _doserrno = 0; 08803 #endif 08804 08805 $ return txWindow(); 08806 } 08807 08808 //----------------------------------------------------------------------------------------------------------------- 08809 08810 HWND txCreateExtraWindow (CREATESTRUCT createData) 08811 { 08812 $1 if (_TX_TXWINDOW_FAILED()) return NULL; 08813 08814 $ volatile HWND wnd = NULL; 08815 $ createData.hInstance = (HINSTANCE)(uintptr_t) &wnd; 08816 08817 $ PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted; 08818 08819 $ _txWaitFor (wnd, 5*_TX_TIMEOUT); 08820 08821 $ return wnd; 08822 } 08823 08824 //----------------------------------------------------------------------------------------------------------------- 08825 08826 bool txSetDefaults (HDC dc /*= txDC()*/) 08827 { 08828 $1 if (dc == txDC()) txUpdateWindow (false); //-V601 08829 $ txAutoLock _lock; 08830 08831 $ RECT r = {}; 08832 $ GetClientRect (Win32::GetConsoleWindow(), &r); 08833 $ SIZE szCon = { r.right - r.left, r.bottom - r.top }; 08834 08835 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 08836 08837 $ CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}}; 08838 $ GetConsoleScreenBufferInfo (out, &con); 08839 08840 $ SIZE szTxt = { (short) (con.srWindow.Right - con.srWindow.Left + 1), 08841 (short) (con.srWindow.Bottom - con.srWindow.Top + 1) }; 08842 08843 //{ Set defaults for graphics layer 08844 08845 $ _txBuffer_Select (Win32::GetStockObject (WHITE_PEN), dc) asserted; 08846 $ _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted; 08847 08848 $ _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx, 08849 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 08850 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 08851 DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT), 08852 dc) asserted; 08853 08854 $ (Win32::SetTextColor (dc, TX_WHITE) != CLR_INVALID) asserted; 08855 $ Win32::SetBkMode (dc, TRANSPARENT) asserted; 08856 08857 $ Win32::SetROP2 (dc, R2_COPYPEN) asserted; 08858 $ Win32::SetStretchBltMode (dc, HALFTONE) asserted; 08859 08860 //} 08861 08862 $ if (dc != txDC()) 08863 {$ return true; } 08864 08865 //{ Set defaults for console layer 08866 08867 $ POINT szCanvas = txGetExtent (dc); 08868 08869 $ HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)? 08870 Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx, 08871 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 08872 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 08873 DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT) 08874 : 08875 Win32::GetStockObject (SYSTEM_FIXED_FONT); 08876 08877 $ _txBuffer_Select (font, _txCanvas_BackBuf[1]); 08878 //} 08879 08880 //{ Scroll the console for text to go above top of window and don't mix with graphics 08881 08882 $ if (con.dwCursorPosition.X) _putch ('\n'); 08883 08884 $ short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top); 08885 08886 $ con.srWindow.Top = (short) (con.srWindow.Top + delta); 08887 $ con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta); 08888 08889 $ SMALL_RECT src = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) }; 08890 $ CHAR_INFO fill = { {' '}, FOREGROUND_LIGHTGRAY }; 08891 $ COORD dest = { 0, (short) -delta }; // New UL-corner of src, scroll up 08892 08893 $ con.dwCursorPosition.X = 0; 08894 $ con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta); 08895 08896 $ (con.srWindow.Bottom < con.dwSize.Y && // Move the "window" 08897 SetConsoleWindowInfo (out, true, &con.srWindow)) 08898 || 08899 (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill), // Or scroll the buffer 08900 SetConsoleCursorPosition (out, con.dwCursorPosition)); 08901 //} 08902 08903 $ txUpdateWindow (true); //-V601 08904 08905 return true; 08906 } 08907 08908 #endif // TX_COMPILED 08909 08910 //----------------------------------------------------------------------------------------------------------------- 08911 08912 inline bool txOK() 08913 { 08914 return (_txCanaryFirst == 0x776F656D && // Too well-known values to use constants. You know these values, don't you? 08915 _txCanaryLast == 0x5E2E2E5E && 08916 _txCanvas_OK() 08917 08918 #if defined (_MSC_VER) 08919 && _CrtCheckMemory() 08920 #endif 08921 ); 08922 } 08923 08924 //----------------------------------------------------------------------------------------------------------------- 08925 //{ Cleanup 08926 //----------------------------------------------------------------------------------------------------------------- 08927 08928 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08929 08930 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain. 08931 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols 08932 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize(). 08933 08934 void _txOnCExit() 08935 { 08936 OutputDebugString ("\n"); 08937 08938 $5 _txCleanup(); 08939 08940 _TX_CALLv (Win32::_cexit, ()); 08941 } 08942 08943 //----------------------------------------------------------------------------------------------------------------- 08944 08945 void _txOnExit (int retcode) 08946 { 08947 if (retcode != 0) 08948 { 08949 OutputDebugString ("\n"); 08950 txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode); 08951 } 08952 08953 $5 _txCleanup(); 08954 08955 if (retcode != 0) 08956 txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode); 08957 08958 Win32::exit (retcode); 08959 } 08960 08961 //----------------------------------------------------------------------------------------------------------------- 08962 08963 void _txOnExitProcess (unsigned retcode) 08964 { 08965 if (retcode != 0) 08966 { 08967 OutputDebugString ("\n"); 08968 txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode); 08969 } 08970 08971 $5 _txCleanup(); 08972 08973 if (retcode != 0) 08974 txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode); 08975 08976 Win32::ExitProcess (retcode); 08977 } 08978 08979 //----------------------------------------------------------------------------------------------------------------- 08980 08981 bool _txOnTerminateProcess (HANDLE process, unsigned retcode) 08982 { 08983 if (retcode != 0) 08984 { 08985 OutputDebugString ("\n"); 08986 txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode); 08987 } 08988 08989 $5 _txCleanup(); 08990 08991 if (retcode != 0) 08992 txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode); 08993 08994 return Win32::TerminateProcess (process, retcode); 08995 } 08996 08997 //----------------------------------------------------------------------------------------------------------------- 08998 08999 void _txOnFatalExit (int retcode) 09000 { 09001 OutputDebugString ("\n"); 09002 txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode); 09003 09004 $5 _txCleanup(); 09005 09006 txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode); 09007 _TX_CALLv (Win32::FatalExit, (retcode)); 09008 09009 txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode); 09010 Win32::TerminateProcess (GetCurrentProcess(), retcode); 09011 } 09012 09013 //----------------------------------------------------------------------------------------------------------------- 09014 09015 void _txOnFatalAppExitA (unsigned action, const char message[]) 09016 { 09017 OutputDebugString ("\n"); 09018 txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message); 09019 09020 $5 _txCleanup(); 09021 09022 txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message); 09023 _TX_CALLv (Win32::FatalAppExitA, (action, message)); 09024 09025 txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION); 09026 Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 09027 } 09028 09029 //----------------------------------------------------------------------------------------------------------------- 09030 09031 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type) 09032 { 09033 OutputDebugString ("\n"); 09034 txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type); 09035 09036 $5 switch (type) 09037 { 09038 case CTRL_LOGOFF_EVENT: 09039 case CTRL_SHUTDOWN_EVENT: $ _txExit = true; 09040 $ _txCleanup(); 09041 case CTRL_C_EVENT: 09042 case CTRL_CLOSE_EVENT: 09043 case CTRL_BREAK_EVENT: 09044 09045 default: break; //-V2522 09046 } 09047 09048 $ return false; 09049 } 09050 09051 //----------------------------------------------------------------------------------------------------------------- 09052 09053 void _txCleanup() 09054 { 09055 if (!_txInitialized) return; 09056 else _txInitialized = false; //-V601 09057 09058 $3 _txRunning = false; 09059 $ _txConsole_IsBlinking = false; 09060 09061 $ txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR); 09062 09063 $ txSetWindowsHook (NULL); 09064 09065 $ HWND canvas = txWindow(); 09066 $ HWND console = Win32::GetConsoleWindow(); 09067 $ unsigned thread = GetCurrentThreadId(); 09068 09069 $ HWND wnd = (canvas)? canvas : console; 09070 09071 $ bool externTerm = (thread != _txMainThreadId && 09072 thread != _txCanvas_ThreadId); 09073 09074 $ DWORD parent = 0; 09075 $ int isParentWaitable = _txIsParentWaitable (&parent); 09076 $ bool waitableParent = !externTerm && isParentWaitable; 09077 09078 $ if (canvas) 09079 {$ txSleep (5*_txWindowUpdateInterval); } 09080 09081 $ if (_txConsole) 09082 { 09083 $ if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 09084 09085 $ if (console) 09086 { 09087 $ EnableWindow (console, true); 09088 $ _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); 09089 } 09090 } 09091 09092 $ if (_txMain && !externTerm && canvas) 09093 {$ _txSetWindowText (canvas, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); } 09094 09095 $ std::cout.flush(); 09096 $ std::cerr.flush(); 09097 $ std::clog.flush(); 09098 $ _flushall(); 09099 09100 $ bool paused = false; 09101 $ if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId)) 09102 { 09103 $ if (wnd) 09104 { 09105 $ if (isParentWaitable >= 0) 09106 {$ _txActivateWindow (wnd, 0x08); } 09107 09108 $ EnableWindow (wnd, true); 09109 } 09110 09111 $ if (console && isParentWaitable >= 0) 09112 { 09113 $ txPause ((_txErrors)? "\f\n" "[Press F to Pay Respects...]" : 09114 (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f"); 09115 09116 $ paused = true; 09117 } 09118 } 09119 09120 $ if (_txConsole && _txWatchdogTimeout >= 0) 09121 {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); } 09122 09123 $ if (txWindow()) 09124 {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); } 09125 09126 $ _txWaitFor (!txWindow(), 5*_TX_TIMEOUT); 09127 09128 $ txSpeak (NULL); 09129 $ txPlayVideo (NULL); 09130 09131 $ delete _txCanvas_UserDCs; 09132 $ _txCanvas_UserDCs = NULL; 09133 09134 $ if (GetCurrentThreadId() != _txMainThreadId) 09135 {$ SuspendThread (_txMainThread); } //-V720 09136 $ if (GetCurrentThreadId() != _txCanvas_ThreadId) 09137 {$ SuspendThread (_txCanvas_Thread); } //-V720 09138 09139 $ if (_txMainThread) 09140 {$ CloseHandle (_txMainThread) asserted; _txMainThread = NULL; } 09141 $ if (_txCanvas_Thread) 09142 {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; } 09143 09144 $ if (!txWindow()) 09145 {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; } 09146 09147 $ bool parentKilled = false; 09148 $ if (waitableParent && paused && _txNOP (_TX_ALLOW_KILL_PARENT)) 09149 { 09150 $ console = Win32::GetConsoleWindow(); 09151 09152 $ if (parent) 09153 {$ parentKilled = _txKillProcess (parent); } 09154 09155 $ if (parent && !parentKilled) 09156 { 09157 $ PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001); // Scancode = 0x1C, Count = 1 09158 $ PostMessage (console, WM_KEYUP, VK_RETURN, 0xC01C0001); // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1 09159 } 09160 } 09161 09162 $ if (_txConsole) 09163 {$ _txSetWindowText (console, NULL); } 09164 09165 $ if (_txMain && _txConsole) 09166 {$ _txConsole_Detach (waitableParent && !parentKilled && !externTerm); } //-V560 09167 09168 $ std::cout.flush(); 09169 $ std::cerr.flush(); 09170 $ std::clog.flush(); 09171 $ _flushall(); 09172 09173 $ _txSymGetFromAddr (NULL); 09174 09175 // That's all, folks 09176 09177 _TX_ON_DEBUG (OutputDebugString ("\n"); 09178 OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n"); 09179 OutputDebugString ("\n")); 09180 } 09181 09182 //----------------------------------------------------------------------------------------------------------------- 09183 09184 int txPause (const char* message /*= NULL*/, ...) 09185 { 09186 $3 bool wine = !!Win32::wine_get_version; 09187 09188 $ HWND canvas = txWindow(); 09189 $ HWND console = Win32::GetConsoleWindow(); 09190 $ HWND wnd = (canvas)? canvas : console; 09191 $ bool istty0 = _txIsTTY (0); 09192 09193 $ int attr = txGetConsoleAttr(); 09194 09195 $ int oldCP = GetConsoleOutputCP(); 09196 $ SetConsoleOutputCP (_TX_CODEPAGE); 09197 09198 if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; } 09199 09200 if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); } 09201 else {$ message++; } 09202 09203 if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); } 09204 else {$ message++; } 09205 09206 $ _txActivateWindow (wnd, 0x08); 09207 09208 $ va_list args; 09209 $ va_start (args, message); 09210 $ vfprintf (stderr, message, args); 09211 $ txOutputDebugPrintf (message, args); 09212 $ va_end (args); 09213 09214 $ fflush (stderr); 09215 $ txSleep(); 09216 09217 $ Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF }; 09218 $ _TX_CALL (Win32::FlashWindowEx, (&flash)); 09219 09220 $ int ch = EOF; 09221 if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); } 09222 09223 $ for (int i = 1; ; i++) //-V2530 09224 { 09225 $ Sleep (_txWindowUpdateInterval); 09226 09227 if (!istty0 && !canvas) {$ break; } // No need to run and hide 09228 09229 if (!wine && (ch = _txGetInput()) != EOF) {$ break; } // Somebody hit something. 09230 09231 if (canvas && !_txCanvas_ThreadId) {$ break; } // There was a window, and now there is not. 09232 09233 if (!Win32::GetConsoleWindow()) {$ break; } // Console was destroyed 09234 09235 if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas))) 09236 {$ TX_ERROR ("Похоже, программа зависла :("); break; } 09237 09238 if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas))) 09239 {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; } 09240 09241 if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL)) 09242 {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает"); break; } 09243 09244 if (!wine && !(i % 100500)) 09245 {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...] \b\b"); } 09246 } 09247 09248 if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); } 09249 09250 $ _txSetWindowText (wnd, NULL); 09251 09252 $ fprintf (stderr, "\n"); 09253 09254 if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); } 09255 09256 $ SetConsoleOutputCP (oldCP); 09257 $ txSetConsoleAttr (attr); 09258 09259 $ return ch; 09260 } 09261 09262 //----------------------------------------------------------------------------------------------------------------- 09263 09264 int _txGetInput() 09265 { 09266 $4 HANDLE con = GetStdHandle (STD_INPUT_HANDLE); 09267 $ int ch = EOF; 09268 09269 $ DWORD nChars = 0; 09270 $ if (GetConsoleMode (con, &nChars) == 0 && 09271 PeekNamedPipe (con, NULL, 0, NULL, &nChars, NULL)) 09272 { 09273 $ ch = (nChars)? fgetc (stdin) : EOF; 09274 } 09275 09276 else if (_kbhit()) 09277 { 09278 $ ch = _getch(); 09279 } 09280 09281 #if defined (_MSC_VER) && (_MSC_VER < 1700) 09282 09283 else if (fseek (stdin, 1, SEEK_CUR) != EOF) 09284 { 09285 $ (void) fseek (stdin, -1, SEEK_CUR); 09286 $ ch = fgetc (stdin); // This causes blocking in MSVC 2011 beta 09287 } 09288 09289 #endif 09290 09291 if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); } 09292 09293 $ return ch; 09294 } 09295 09296 //----------------------------------------------------------------------------------------------------------------- 09297 09298 bool _txIsTTY (int fd) 09299 { 09300 $4 return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR; 09301 } 09302 09303 //----------------------------------------------------------------------------------------------------------------- 09304 09305 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/, 09306 int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/) 09307 { 09308 struct tools 09309 { 09310 static LRESULT getWindowText (HWND window, wchar_t text[], size_t size) 09311 { 09312 $3 memset (text, 0, size * sizeof (*text)); 09313 09314 $ return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL); 09315 } 09316 09317 static LRESULT setWindowText (HWND window, wchar_t text[]) 09318 { 09319 $1 return SendMessageTimeoutW (window, WM_SETTEXT, 0, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL); 09320 } 09321 }; 09322 09323 $1 static wchar_t _tx_thread title [_TX_BUFSIZE+15] = L"TXLib"; 09324 $ static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib"; 09325 09326 $ if (!textRus) 09327 { 09328 $ tools::setWindowText (wnd, oldTitle); 09329 $ return -1; 09330 } 09331 09332 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09333 $ int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1; 09334 $ memcpy (oldTitle, title, sizeof (oldTitle)); 09335 09336 $ if (textRus) 09337 { 09338 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len); 09339 09340 $ tools::setWindowText (wnd, title); 09341 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09342 if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; } 09343 if (!checkLetters) {$ return -2; } 09344 } 09345 09346 $ if (textEng) 09347 { 09348 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len); 09349 09350 $ tools::setWindowText (wnd, title); 09351 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09352 if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; } 09353 if (!checkLetters) {$ return -2; } 09354 } 09355 09356 $ return -3; 09357 } 09358 09359 //----------------------------------------------------------------------------------------------------------------- 09360 09361 int _txIsParentWaitable (DWORD* parentPID /*= NULL*/) 09362 { 09363 $4 PROCESSENTRY32* info = _txFindProcess(); 09364 $ if (!info) return 0; 09365 09366 $ info = _txFindProcess (info->th32ParentProcessID); 09367 $ if (!info) return 0; 09368 09369 $ char parent [MAX_PATH] = ""; 09370 $ strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1); 09371 $ if (parentPID) *parentPID = info->th32ProcessID; 09372 09373 $ info = _txFindProcess (info->th32ParentProcessID); // info: grandparent 09374 09375 $ char list[_TX_BUFSIZE] = _TX_WAITABLE_PARENTS; 09376 $ char* ctx = NULL; 09377 09378 $ for (char* p = strtok_s (list, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx)) 09379 { 09380 $ char* gp = strchr (p, ':'); 09381 09382 $ if (gp) 09383 { 09384 $ *gp++ = 0; 09385 09386 $ if (_stricmp (p, parent) != 0) { continue; } 09387 09388 $ if (info) if (_stricmp (gp, info->szExeFile) == 0) // Was &&, but MSVC /analyze is so paranoid 09389 {$ return islower ((unsigned char) *gp)? +1 : -1; } 09390 } 09391 else 09392 { 09393 $ if (_stricmp (p, parent) == 0) 09394 {$ return islower ((unsigned char) *p)? +1 : -1; } 09395 } 09396 } 09397 09398 $ return 0; 09399 } 09400 09401 //----------------------------------------------------------------------------------------------------------------- 09402 09403 void _txWatchdogTerminator (void* timeout) // Or Watchcat? Possibly will change in future versions 09404 { 09405 $3 if (_TX_ARGUMENT_FAILED (timeout)) return; 09406 09407 $ Sleep (*(int*) timeout); //-V206 09408 09409 $ OutputDebugString ("\n"); 09410 txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n", // Kinda static reflection... 09411 _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow")); //-V206 09412 $ DWORD parent = 0; 09413 $ if (_txIsParentWaitable (&parent)) 09414 { 09415 txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n", 09416 _TX_VERSION, __func__, (unsigned long) parent); 09417 09418 $ _txKillProcess (parent); 09419 09420 $ HWND console = GetConsoleWindow(); 09421 $ PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001); // Scancode = 0x1C, Count = 1 09422 $ PostMessage (console, WM_KEYUP, VK_RETURN, 0xC01C0001); // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1 09423 } 09424 09425 txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__); 09426 $ Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 09427 } 09428 09429 #endif // TX_COMPILED 09430 09431 //} 09432 //----------------------------------------------------------------------------------------------------------------- 09433 09434 //----------------------------------------------------------------------------------------------------------------- 09435 //{ Tools 09436 //----------------------------------------------------------------------------------------------------------------- 09437 09438 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 09439 09440 // You are here, little hacker? 09441 09442 int _txTaskKill (const char i[] /*= NULL*/, 09443 const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/, 09444 unsigned x /*= 0*/) 09445 { 09446 // ...so tired of it already... 09447 09448 #define name i // Great name! 09449 #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine 09450 #define pid x // Another great name, isn't it? 09451 09452 $3 if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false; //-V560 //-V601 09453 09454 $ wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L""; 09455 if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); } 09456 09457 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 09458 $ assert (sshot); if (!sshot) return 0; //-V547 09459 09460 $ int killed = 0; 09461 09462 $ PROCESSENTRY32 info = { sizeof (info) }; 09463 $ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info)) 09464 { 09465 bool kill = false; 09466 09467 if (!kill && pid && info.th32ParentProcessID == pid) {$ kill = true; } //-V560 09468 09469 if (!kill && name && _stricmp (info.szExeFile, name) == 0) {$ kill = true; } 09470 09471 if (!kill) 09472 { 09473 wchar_t cmdLineW[_TX_BUFSIZE] = L""; 09474 if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; } 09475 09476 if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW)) {$ kill = true; } 09477 } 09478 09479 if (kill) 09480 { 09481 $ if (_txKillProcess (info.th32ProcessID)) 09482 {$ killed++; } 09483 } 09484 } 09485 09486 $ CloseHandle (sshot); 09487 09488 $ return killed; 09489 09490 #undef name 09491 #undef cmdLine 09492 #undef pid 09493 } 09494 09495 //----------------------------------------------------------------------------------------------------------------- 09496 09497 bool _txKillProcess (DWORD pid) 09498 { 09499 $3 if (_TX_ARGUMENT_FAILED (pid)) return false; 09500 09501 $ HANDLE token = INVALID_HANDLE_VALUE; 09502 $ OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted; 09503 09504 $ LUID luid = {}; 09505 $ LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted; 09506 09507 $ TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}}; 09508 $ TOKEN_PRIVILEGES old = {}; 09509 09510 $ DWORD oldSz = 0; 09511 $ AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted; 09512 09513 $ HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid); 09514 $ if (!proc) return false; 09515 09516 $ bool ok = !!Win32::TerminateProcess (proc, 0); 09517 $ CloseHandle (proc); 09518 09519 $ return ok; 09520 } 09521 09522 //----------------------------------------------------------------------------------------------------------------- 09523 09524 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/) 09525 { 09526 $4 static PROCESSENTRY32 info = { sizeof (info) }; 09527 $ if (!pid) return &info; 09528 09529 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 09530 $ assert (sshot); if (!sshot) return NULL; //-V547 09531 09532 $ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info)) 09533 if (info.th32ProcessID == pid) break; 09534 09535 $ CloseHandle (sshot); 09536 09537 $ return &info; 09538 } 09539 09540 //----------------------------------------------------------------------------------------------------------------- 09541 09542 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/) 09543 { 09544 $6 if (_TX_ARGUMENT_FAILED (cmdLine)) return false; 09545 $ if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false; //-V547 09546 09547 $ if (pid == (unsigned) _getpid()) 09548 { 09549 $ wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1); 09550 $ return true; 09551 } 09552 09553 $ HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid); 09554 if (!proc) {$ return false; } 09555 09556 $ Win32::PROCESS_BASIC_INFORMATION pbi = {}; 09557 $ bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0); 09558 09559 // Should use ReadProcessMemory() because the info is actually in another address space 09560 09561 $ Win32::PEB peb = {}; 09562 if (ok && pbi.PebBaseAddress) {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress, &peb, sizeof (peb), NULL); } 09563 09564 $ Win32::RTL_USER_PROCESS_PARAMETERS params = {}; 09565 if (ok && peb.ProcessParameters) {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters, ¶ms, sizeof (params), NULL); } 09566 09567 $ *cmdLine = 0; 09568 if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine, //-V106 09569 MIN (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2), //-V202 09570 NULL); } 09571 $ CloseHandle (proc) asserted; 09572 09573 $ return ok; 09574 } 09575 09576 //----------------------------------------------------------------------------------------------------------------- 09577 09578 #define RVA_(type, module, addr) ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) ) 09579 09580 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/) 09581 { 09582 $4 assert (module); 09583 09584 $ IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0); 09585 $ IMAGE_NT_HEADERS* ntHdr = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew); 09586 09587 $ return (dosHdr->e_magic == IMAGE_DOS_SIGNATURE && 09588 ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL; 09589 } 09590 09591 //----------------------------------------------------------------------------------------------------------------- 09592 09593 // TXLib continues to hack the reality to make your life better, sweeter and easier 09594 09595 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/, 09596 HMODULE module /*= NULL*/, bool debug /*= false*/) 09597 { 09598 $4 if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module); 09599 09600 $ if (_TX_ARGUMENT_FAILED (funcName)) return 0; 09601 $ if (_TX_ARGUMENT_FAILED (newFunc)) return 0; 09602 09603 $ if (!module) module = GetModuleHandle (NULL); 09604 $ if (!module) return 0; 09605 09606 $ HMODULE dll = (dllName)? GetModuleHandle (dllName) : NULL; 09607 $ PROC oldFunc = (dll)? GetProcAddress (dll, funcName) : NULL; 09608 09609 $ if (useHotPatching && oldFunc) 09610 { 09611 $ const size_t jmpSz = 1 + sizeof (DWORD); // sizeof (JMP rel instruction) 09612 09613 $ DWORD oldRights = 0; 09614 $ if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0; 09615 09616 // Overwrite oldFunc prolog with JMP trampoline to newFunc. 09617 // Calling oldFunc from any location will lead to newFunc call anyway. 09618 09619 $ *(BYTE*) ((char*)(uintptr_t) oldFunc + 0) = 0xE9; // JMP rel 09620 $ *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF; //-V206 //-V112 //-V2007 //-V104 //-V103 09621 09622 $ FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz); 09623 09624 $ VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights); 09625 09626 $ return (uintptr_t) oldFunc; 09627 } 09628 09629 // For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255 09630 // and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html. 09631 09632 $ IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module); 09633 if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; } 09634 09635 $ DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 09636 $ IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset); 09637 09638 $ if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0; //-V1027 09639 09640 $ IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL; 09641 $ char* impDll = NULL; 09642 $ char* impName = NULL; 09643 $ void** impPtr = NULL; 09644 $ bool found = false; 09645 09646 for (; desc->Name; desc++) 09647 { 09648 $ impDll = RVA_ (char*, module, desc->Name); 09649 $ if (dllName && _stricmp (impDll, dllName) != 0) continue; 09650 09651 $ for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk), 09652 thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk); 09653 09654 thunk0 && thunk1 && thunk1->u1.Function; 09655 09656 thunk0++, 09657 thunk1++) 09658 { 09659 impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name; 09660 impPtr = (void**)(uintptr_t) &thunk1->u1.Function; // Should change it, so this is ptr 09661 09662 if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL; 09663 09664 if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName); 09665 09666 if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) || 09667 (impName && _stricmp (funcName, impName) == 0)) //-V560 09668 { 09669 found = true; 09670 break; 09671 } 09672 } 09673 09674 $ if (found) break; 09675 } 09676 09677 if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n", 09678 funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found")); 09679 $ if (!found) return 0; 09680 09681 $ DWORD rights = PAGE_READWRITE; 09682 $ if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0; 09683 09684 $ *(uintptr_t*) impPtr = newFunc; 09685 09686 $ VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights); 09687 09688 $ return (uintptr_t) oldFunc; 09689 } 09690 09691 #undef RVA_ 09692 09693 //----------------------------------------------------------------------------------------------------------------- 09694 09695 bool _txInDll() 09696 { 09697 $4 MODULEENTRY32 mod = { sizeof (mod) }; 09698 09699 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); 09700 $ assert (sshot); if (!sshot) return false; //-V547 09701 09702 $ bool inDll = false; 09703 09704 $ for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod)) 09705 { 09706 $ if (!mod.modBaseAddr) continue; 09707 09708 $ IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr); 09709 09710 $ inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0); 09711 09712 $ if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize)) //-V104 09713 {$ break; } 09714 } 09715 09716 $ CloseHandle (sshot); 09717 $ return inDll; 09718 } 09719 09720 //----------------------------------------------------------------------------------------------------------------- 09721 09722 bool _txIsConsoleSubsystem() 09723 { 09724 $4 IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders(); 09725 09726 $ return ntHdr && 09727 ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC && 09728 09729 (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI || 09730 ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI); 09731 } 09732 09733 //----------------------------------------------------------------------------------------------------------------- 09734 09735 bool _txIsBadReadPtr (const void* address) 09736 { 09737 MEMORY_BASIC_INFORMATION mbi = {}; 09738 if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true; 09739 09740 if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) return true; // Guard page -> bad ptr 09741 09742 DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY; 09743 09744 return !(mbi.Protect & readRights); 09745 } 09746 09747 //----------------------------------------------------------------------------------------------------------------- 09748 09749 void _txActivateWindow (HWND wnd, unsigned mode) 09750 { 09751 $1 EnableWindow (wnd, true); 09752 09753 $ if (mode & 0x10) 09754 { 09755 $ ShowWindow (wnd, SW_MINIMIZE); 09756 $ ShowWindow (wnd, SW_RESTORE); 09757 } 09758 09759 $ if (mode & 0x08) 09760 { 09761 $ int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0); 09762 09763 $ AttachThreadInput (GetCurrentThreadId(), focus, true); 09764 $ SetForegroundWindow (wnd); 09765 $ AttachThreadInput (GetCurrentThreadId(), focus, false); 09766 } 09767 09768 $ if (mode & 0x04) 09769 { 09770 $ SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); 09771 } 09772 09773 $ if (mode & 0x02) 09774 { 09775 $ SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS); 09776 } 09777 09778 $ if (mode & 0x01) 09779 { 09780 $ UpdateWindow (wnd); 09781 } 09782 } 09783 09784 #endif // TX_COMPILED 09785 09786 //} 09787 //----------------------------------------------------------------------------------------------------------------- 09788 09790 //} 09791 //================================================================================================================= 09792 09793 //================================================================================================================= 09794 //{ Internal TXLib window functions (_txCanvas...) 09796 //================================================================================================================= 09797 09798 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 09799 09800 unsigned WINAPI _txCanvas_ThreadProc (void* data) 09801 { 09802 #define SetClassLong_ SetClassLongPtr 09803 #define GCL_HICON_ GCLP_HICON 09804 #define GCL_HICONSM_ GCLP_HICONSM 09805 #define GCL_HCURSOR_ GCLP_HCURSOR 09806 09807 $8 _txCanvas_ThreadId = GetCurrentThreadId(); 09808 09809 $ if (_TX_ARGUMENT_FAILED (data)) return false; //-V601 09810 09811 $ unsigned long stackSize = _TX_STACKSIZE; 09812 $ _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize)); 09813 09814 $ HWND wnd = _txCanvas_CreateWindow ((SIZE*) data); 09815 $ if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0; 09816 09817 $ HICON icon32 = LoadIcon (NULL, "_TX_ICON"); 09818 $ HICON icon16 = LoadIcon (NULL, "_TX_ICONSM"); 09819 $ HCURSOR cursor = LoadCursor (NULL, "_TX_CURSOR"); 09820 $ HMENU menu = LoadMenu (NULL, "_TX_MENU"); 09821 $ HACCEL accel = LoadAccelerators (NULL, "_TX_ACCELERATORS"); 09822 09823 $ SetClassLong_ (wnd, GCL_HICON_, (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32))); //-V107 //-V112 09824 $ SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16))); //-V107 09825 $ SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW))); //-V107 09826 09827 if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); } 09828 09829 $ Win32::GdiSetBatchLimit (1); 09830 09831 _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n")); 09832 09833 $ _txActivateWindow (wnd, 0x10); 09834 09835 $ ShowWindow (wnd, SW_SHOW); 09836 $ UpdateWindow (wnd); 09837 09838 $ _txRunning = true; 09839 09840 $ MSG msg = {}; 09841 $ while (GetMessage (&msg, NULL, 0, 0)) 09842 { 09843 if (!msg.hwnd) {$ continue; } 09844 09845 if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; } 09846 09847 $ TranslateMessage (&msg); 09848 $ DispatchMessage (&msg); 09849 09850 $ Sleep (0); 09851 } 09852 09853 $ if (icon16) DestroyIcon (icon16); // If Explorer is displaying Tray Notification, these 09854 $ if (icon32) DestroyIcon (icon32); // calls will possibly fail, and we'll get resource leak. 09855 09856 $ LeaveCriticalSection (&_txCanvas_LockBackBuf); 09857 09858 _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n")); 09859 09860 $ if (_txWatchdogTimeout >= 0) 09861 {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); } 09862 09863 $ if (_txRunning && _txMain) // Main window is destroyed but main() is still running. 09864 { // No chances for good termination, so use exit(). 09865 $ _txCleanup(); 09866 $ ::exit ((int) msg.wParam); //-V202 //-V2509 //-V2014 09867 } 09868 09869 $ _txCanvas_ThreadId = 0; 09870 $ return true; //-V601 09871 09872 #undef SetClassLong 09873 #undef GCL_HICON_ 09874 #undef GCL_HICONSM_ 09875 #undef GCL_HCURSOR_ 09876 } 09877 09878 //----------------------------------------------------------------------------------------------------------------- 09879 09880 HWND _txCanvas_CreateWindow (const SIZE* sizePtr) 09881 { 09882 $8 if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL; 09883 09884 $ bool centered = false; 09885 if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; } 09886 09887 $ SIZE screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; 09888 $ RECT rect = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false); 09889 $ SIZE size = { rect.right - rect.left, rect.bottom - rect.top }; 09890 $ RECT conPos = {}; 09891 09892 $ HWND console = _TX_CALL (Win32::GetConsoleWindow, ()); 09893 if (console) {$ GetWindowRect (console, &conPos); } 09894 09895 $ const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0); 09896 $ if (!wndClass) return (HWND) NULL; 09897 09898 $ HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN, 09899 (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT, 09900 (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top : CW_USEDEFAULT, 09901 size.cx, size.cy, NULL, NULL, NULL, NULL); 09902 $ if (!wnd || !txWindow()) 09903 {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; } 09904 09905 $ HMENU menu = GetSystemMenu (txWindow(), false); 09906 if (!menu) {$ return txWindow(); } 09907 09908 $ AppendMenu (menu, MF_SEPARATOR, 0, NULL) asserted; 09909 $ AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted; 09910 $ AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT, "&About...") asserted; 09911 09912 $ return txWindow(); 09913 } 09914 09915 //----------------------------------------------------------------------------------------------------------------- 09916 09917 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra) 09918 { 09919 $8 assert (classId); 09920 $ assert (wndProc); 09921 09922 $ static char name[_TX_BUFSIZE] = ""; 09923 $ _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ " 09924 _TX_VERSION " " __FILE__ " WndClass %08lX " 09925 "-------------[%s]-[TXLib]---*/", 09926 classId, (unsigned long) GetTickCount(), classId); 09927 $ WNDCLASS wc = { sizeof (wc) }; 09928 09929 $ wc.lpszClassName = name; 09930 $ wc.lpfnWndProc = wndProc; 09931 $ wc.style = style; 09932 $ wc.cbWndExtra = (wndExtra + 1) * (int) sizeof (long); 09933 09934 $ wc.hCursor = LoadCursor (NULL, IDC_ARROW); 09935 $ wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush); 09936 09937 $ ATOM atom = RegisterClass (&wc); 09938 if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; } 09939 09940 $ return (const char*)(uintptr_t) atom; 09941 } 09942 09943 //----------------------------------------------------------------------------------------------------------------- 09944 09945 int _txCanvas_SetRefreshLock (int count) 09946 { 09947 $8 int oldCount = _txCanvas_RefreshLock; 09948 09949 $ _txCanvas_RefreshLock = count; 09950 09951 $ HWND wnd = txWindow(); 09952 09953 $ if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd) 09954 {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); } 09955 09956 $ return oldCount; 09957 } 09958 09959 //----------------------------------------------------------------------------------------------------------------- 09960 09961 HICON _txCreateTXIcon (int size) 09962 { 09963 $8 if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL; //-V112 //-V560 09964 09965 $ const unsigned char image32 [32*32+1] = 09966 "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0" 09967 "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0" 09968 "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0" 09969 "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0" 09970 "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0" 09971 "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0" 09972 "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0" 09973 "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000"; 09974 09975 $ const unsigned char image16 [16*16+1] = 09976 "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990" 09977 "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000"; 09978 09979 $ const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0, 09980 0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff }; 09981 09982 $ const unsigned char* image = (size == 32)? image32 : image16; //-V112 09983 09984 $ POINT sz = { size, size }; 09985 $ HDC dcMask = _txBuffer_Create (txWindow(), &sz); assert (dcMask); 09986 $ HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor); 09987 09988 $ for (int i = 0; i < size*size; i++) 09989 { 09990 assert (In (std::nomeow, image[i], '0', '9') || 09991 In (std::nomeow, image[i], 'A', 'F')); 09992 09993 Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']); 09994 } 09995 09996 $ ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask, OBJ_BITMAP), 09997 (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) }; 09998 09999 $ HICON icon = CreateIconIndirect (&info); 10000 $ assert (icon); 10001 10002 $ _txBuffer_Delete (&dcMask) asserted; 10003 $ _txBuffer_Delete (&dcColor) asserted; 10004 10005 $ return icon; 10006 } 10007 10008 #endif // TX_COMPILED 10009 10010 //----------------------------------------------------------------------------------------------------------------- 10011 10012 inline bool _txCanvas_OK() 10013 { 10014 return _txCanvas_ThreadId && 10015 _txCanvas_Window && 10016 _txCanvas_BackBuf[0] && 10017 _txCanvas_BackBuf[1] && 10018 _txCanvas_Pixels; 10019 } 10020 10021 //} 10022 //================================================================================================================= 10023 10024 //================================================================================================================= 10025 //{ Main window event handlers (_txCanvas_On...) 10027 //================================================================================================================= 10029 10030 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10031 10032 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) 10033 { 10034 #if defined (_TX_ALLOW_TRACE) 10035 10036 int inTX = _txLoc::Cur.inTX++; 10037 10038 if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)", 10039 2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar); 10040 _txLoc::Cur.inTX = inTX; 10041 10042 #endif 10043 10044 $8 if (msg == WM_KEYDOWN && wpar == VK_F12 && 10045 GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU)) 10046 { 10047 $ _txCanvas_OnCmdABOUT (wnd, wpar); 10048 $ return DefWindowProc (wnd, msg, wpar, lpar); 10049 } 10050 10051 WNDPROC altWndProc = _txAltWndProc; // Cache to prevent change from main thread 10052 if (altWndProc) 10053 { 10054 $ LRESULT res = altWndProc (wnd, msg, wpar, lpar); 10055 $ if (res) return res; 10056 } 10057 10058 static bool bkErased = false; 10059 10060 switch (msg) 10061 { 10062 case WM_CREATE: {$ _txCanvas_OnCREATE (wnd); return 0; } 10063 10064 case WM_CLOSE: {$ if (_txCanvas_OnCLOSE (wnd)) break; else return 0; } 10065 case WM_DESTROY: {$ _txCanvas_OnDESTROY (wnd); return 0; } 10066 10067 case WM_ERASEBKGND: {$ if (!bkErased) { bkErased = true; break; } else return 1; } 10068 case WM_SIZE: {$ bkErased = false; break; } 10069 10070 case WM_PAINT: {$ _txCanvas_OnPAINT (wnd); return 0; } 10071 10072 case WM_TIMER: {$ _txCanvas_OnTIMER (wnd, wpar); return 0; } 10073 10074 case WM_KEYUP: {$ if (_txCanvas_OnKEY (wnd, wpar, lpar, false)) return 0; else break; } 10075 case WM_KEYDOWN: {$ if (_txCanvas_OnKEY (wnd, wpar, lpar, true)) return 0; else break; } 10076 case WM_CHAR: {$ if (_txCanvas_OnCHAR (wnd, wpar, lpar)) return 0; else break; } 10077 10078 case WM_LBUTTONUP: 10079 case WM_LBUTTONDOWN: 10080 case WM_RBUTTONUP: 10081 case WM_RBUTTONDOWN: 10082 case WM_MBUTTONUP: 10083 case WM_MBUTTONDOWN: 10084 case WM_MOUSEMOVE: {$ _txCanvas_OnMOUSEMOVE (wnd, wpar, lpar); return 0; } 10085 10086 case WM_MOUSELEAVE: {$ _txCanvas_OnMOUSELEAVE (wnd); return 0; } 10087 10088 case _TX_WM_CREATEWND: {$ _txCanvas_OnCREATEWND (wnd, wpar, lpar); return 0; } 10089 case _TX_WM_DESTROYWND: {$ _txCanvas_OnDESTROYWND (wnd, wpar, lpar); return 0; } 10090 10091 case WM_NULL: {$ return 0; } 10092 10093 default: break; //-V2522 10094 } 10095 10096 if (msg == WM_SYSCOMMAND) switch (wpar) 10097 { 10098 case _TX_IDM_ABOUT: {$ _txCanvas_OnCmdABOUT (wnd, wpar); return 0; } 10099 case _TX_IDM_CONSOLE: {$ _txCanvas_OnCmdCONSOLE (wnd, wpar); return 0; } 10100 10101 default: break; //-V2522 10102 } 10103 10104 $ return DefWindowProc (wnd, msg, wpar, lpar); 10105 } 10106 10107 //----------------------------------------------------------------------------------------------------------------- 10108 10109 bool _txCanvas_OnCREATE (HWND wnd) 10110 { 10111 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10112 10113 $ _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]); 10114 $ _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL); assert (_txCanvas_BackBuf[1]); 10115 10116 $ if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0; 10117 $ assert (_txCanvas_RefreshTimer); 10118 10119 $ _txCanvas_UserDCs = new ::std::vector <HDC>; 10120 10121 $ _txCanvas_Window = wnd; 10122 10123 $ txSetDefaults(); 10124 10125 $ return true; 10126 } 10127 10128 //----------------------------------------------------------------------------------------------------------------- 10129 10130 bool _txCanvas_OnDESTROY (HWND wnd) 10131 { 10132 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10133 10134 // Инициируем остановку цикла сообщений 10135 10136 $ PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS); 10137 10138 $ if (!_txCanvas_Window) return false; 10139 10140 // Indicate that we are about to manually terminate 10141 10142 $ _txExit = true; 10143 10144 // Lock GDI resources 10145 10146 $ bool locked = false; 10147 $ _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT); 10148 $ if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources"); 10149 10150 // Освобождаем пользовательские ресурсы 10151 10152 $ if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty()) 10153 { 10154 $ txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size()); //-V202 10155 $ Sleep (_TX_TIMEOUT); 10156 10157 $ for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i)); 10158 $ _txCanvas_UserDCs->clear(); 10159 } 10160 10161 // Освобождаем ресурсы, связанные с окном 10162 10163 $ if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted; 10164 10165 $ if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1]) asserted; 10166 $ if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0]) asserted; 10167 $ _txCanvas_Pixels = NULL; 10168 10169 $ txUnlock(); 10170 10171 // Indicate that we are destroyed 10172 10173 $ _txCanvas_Window = NULL; 10174 10175 $ return true; 10176 } 10177 10178 //----------------------------------------------------------------------------------------------------------------- 10179 10180 bool _txCanvas_OnCLOSE (HWND wnd) //-V2009 //-V2558 10181 { 10182 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10183 $ if (!_txCanvas_OK()) return false; 10184 10185 $ if (_txMain && _txRunning && 10186 txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n" 10187 "Лучше подождать, когда main() завершится - это отображается в заголовке окна.", 10188 txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false; 10189 $ return true; 10190 } 10191 10192 //----------------------------------------------------------------------------------------------------------------- 10193 10194 bool _txCanvas_OnTIMER (HWND wnd, WPARAM) 10195 { 10196 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10197 10198 $ if (_txCanvas_RefreshLock > 0 || !_txRunning) return false; 10199 10200 $ InvalidateRect (wnd, NULL, false) asserted; 10201 $ UpdateWindow (wnd) asserted; 10202 10203 $ return true; 10204 } 10205 10206 //----------------------------------------------------------------------------------------------------------------- 10207 10208 bool _txCanvas_OnPAINT (HWND wnd) 10209 { 10210 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10211 $ if (!_txCanvas_OK()) return false; 10212 10213 $ bool forceRedraw = GetAsyncKeyState (VK_MENU) && GetAsyncKeyState (VK_CONTROL) && 10214 GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT); 10215 10216 $ PAINTSTRUCT ps = {}; 10217 $ HDC wndDc = BeginPaint (wnd, &ps); 10218 $ if (!wndDc) return false; 10219 10220 $ HDC dc0 = _txCanvas_BackBuf[0], 10221 dc1 = _txCanvas_BackBuf[1]; 10222 10223 $ RECT r = {}; 10224 $ GetClientRect (wnd, &r) asserted; 10225 $ POINT wndSize = { r.right - r.left, r.bottom - r.top }; 10226 10227 $ POINT dcSize = txGetExtent (dc1); 10228 10229 $ if ((_txCanvas_RefreshLock <= 0 || forceRedraw) && 10230 txLock (false)) 10231 { 10232 $ Win32::BitBlt (dc1, 0, 0, dcSize.x, dcSize.y, dc0, 0, 0, SRCCOPY); 10233 10234 $ if (_txConsole >= 0) 10235 {$ _txConsole_Draw (dc1); } 10236 10237 $ txUnlock(); 10238 } 10239 10240 // Magic 100500 value is used to completely block screen refresh. 10241 // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL. 10242 // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers 10243 // themselves. 10244 // Yes guys, with all your software installed. :( 10245 10246 $ if (_txCanvas_RefreshLock != 100500) 10247 { 10248 if (_txSwapBuffers) 10249 { 10250 $ _txSwapBuffers (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY); 10251 } 10252 else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y) 10253 { 10254 $ Win32::BitBlt (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, SRCCOPY); 10255 } 10256 else 10257 { 10258 $ Win32::SetStretchBltMode (wndDc, HALFTONE); 10259 $ Win32::StretchBlt (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY); 10260 } 10261 } 10262 10263 $ EndPaint (wnd, &ps) asserted; 10264 10265 $ return true; 10266 } 10267 10268 //----------------------------------------------------------------------------------------------------------------- 10269 10270 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info) 10271 { 10272 $8 INPUT_RECORD evt[2] = {}; 10273 10274 $ evt[0].EventType = KEY_EVENT; 10275 $ evt[0].Event.KeyEvent.bKeyDown = true; 10276 $ evt[0].Event.KeyEvent.wRepeatCount = 1; 10277 $ evt[0].Event.KeyEvent.uChar.AsciiChar = (char) (ch); 10278 $ evt[0].Event.KeyEvent.wVirtualScanCode = (WORD) (info >> 16); 10279 $ evt[0].Event.KeyEvent.wVirtualKeyCode = (WORD) MapVirtualKey ((WORD) (info >> 16), 3); // 3 == MAPVK_VSC_TO_VK_EX 10280 $ evt[0].Event.KeyEvent.dwControlKeyState = 0; 10281 10282 $ evt[1] = evt[0]; 10283 $ evt[1].Event.KeyEvent.bKeyDown = false; 10284 10285 $ DWORD written = 0; 10286 $ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), evt, 2, &written); 10287 10288 $ return true; 10289 } 10290 10291 //----------------------------------------------------------------------------------------------------------------- 10292 10293 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down) 10294 { 10295 $8 INPUT_RECORD evt = {}; 10296 10297 $ evt.EventType = KEY_EVENT; 10298 $ evt.Event.KeyEvent.bKeyDown = down; 10299 $ evt.Event.KeyEvent.wRepeatCount = 1; 10300 $ evt.Event.KeyEvent.uChar.AsciiChar = (char) MapVirtualKey ((WORD) vk, 2); // 2 == MAPVK_VK_TO_CHAR 10301 $ evt.Event.KeyEvent.wVirtualScanCode = (WORD) (info >> 16); 10302 $ evt.Event.KeyEvent.wVirtualKeyCode = (WORD) vk; 10303 $ evt.Event.KeyEvent.dwControlKeyState = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0; 10304 10305 $ if (evt.Event.KeyEvent.uChar.AsciiChar) return false; // Let TranslateMessage() and WM_CHAR do the job 10306 10307 $ DWORD written = 0; 10308 $ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written); 10309 10310 $ return true; 10311 } 10312 10313 //----------------------------------------------------------------------------------------------------------------- 10314 10315 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords) 10316 { 10317 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10318 $ if (!_txCanvas_OK()) return false; 10319 10320 $ if (_txMousePos.x == -1 && _txMousePos.y == -1) 10321 { 10322 $ TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT }; 10323 $ TrackMouseEvent (&track); 10324 } 10325 10326 $ _txMousePos.x = LOWORD (coords); 10327 $ _txMousePos.y = HIWORD (coords); 10328 $ _txMouseButtons = (unsigned) buttons; //-V202 10329 10330 $ return true; 10331 } 10332 10333 //----------------------------------------------------------------------------------------------------------------- 10334 10335 bool _txCanvas_OnMOUSELEAVE (HWND) 10336 { 10337 $8 _txMousePos.x = -1; 10338 $ _txMousePos.y = -1; 10339 $ _txMouseButtons = 0; 10340 10341 $ return true; 10342 } 10343 10344 //----------------------------------------------------------------------------------------------------------------- 10345 10346 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar) 10347 { 10348 $8 if (_TX_ARGUMENT_FAILED (lpar)) return false; 10349 10350 $ const CREATESTRUCT* create = (CREATESTRUCT*) lpar; 10351 10352 $ HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style, 10353 create->x, create->y, create->cx, create->cy, 10354 create->hwndParent, create->hMenu, NULL, create->lpCreateParams); 10355 10356 $ *(HWND*) create->hInstance = wnd; 10357 10358 $ return true; 10359 } 10360 10361 //----------------------------------------------------------------------------------------------------------------- 10362 10363 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar) 10364 { 10365 $8 if (_TX_ARGUMENT_FAILED (lpar)) return false; 10366 10367 $ DestroyWindow ((HWND) lpar); 10368 10369 $ return false; 10370 } 10371 10372 //----------------------------------------------------------------------------------------------------------------- 10373 10374 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd) 10375 { 10376 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10377 10378 $ HWND console = Win32::GetConsoleWindow(); 10379 $ if (!console) return false; 10380 10381 $ bool visible = !!IsWindowVisible (console); 10382 10383 $ ShowWindow (console, visible? SW_HIDE : SW_RESTORE); 10384 10385 $ visible = !!IsWindowVisible (console); 10386 $ CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED); //-V202 10387 10388 $ return true; 10389 } 10390 10391 //----------------------------------------------------------------------------------------------------------------- 10392 10393 bool _txCanvas_OnCmdABOUT (HWND, WPARAM) 10394 { 10395 $8 //{ Overriding the missing names, if the set is uncomplete 10396 10397 #if defined (__MODULE) 10398 #define ABOUT_NAME_ __MODULE 10399 #else 10400 #define ABOUT_NAME_ "TXLib" 10401 #endif 10402 10403 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR) 10404 10405 #ifndef __MODULE 10406 #define __MODULE "TXLib" "\n" "#define __MODULE to set the name.\n" 10407 #endif 10408 10409 #ifndef __VERSION 10410 #define __VERSION "(0.000000000)." "\n" "#define __VERSION to set the string value.\n" 10411 #endif 10412 10413 #ifndef __DESCRIPTION 10414 #define __DESCRIPTION "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n" 10415 #endif 10416 10417 #ifndef __AUTHOR 10418 #define __AUTHOR "(Непонятно кто)." "\n" "#define __AUTHOR to override this name." 10419 #endif 10420 10421 #endif 10422 //} 10423 10424 $ static char text[_TX_BUFSIZE] = ""; 10425 10426 $ _tx_snprintf_s (text, sizeof (text) - 1, 10427 10428 "Application:\n\n" 10429 10430 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR) 10431 __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n" 10432 #else 10433 "Здесь могла бы быть Ваша реклама :)\n" 10434 "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n" 10435 #endif 10436 10437 "\n" "%s", _txAppInfo()); 10438 10439 $ txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION); 10440 10441 // And a bit of HTTP-code in C++ function: 10442 10443 goto http; 10444 http://sizeof.livejournal.com 10445 10446 $ return true; 10447 10448 #undef ABOUT_NAME_ 10449 } 10450 10451 #endif // TX_COMPILED 10452 10454 //} 10455 //================================================================================================================= 10456 10457 //================================================================================================================= 10458 //{ Console-support functions (_txConsole...) 10460 //================================================================================================================= 10462 10463 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10464 10465 HWND _txConsole_Attach() 10466 { 10467 $1 HWND console = Win32::GetConsoleWindow(); 10468 10469 $ if (!console) 10470 { 10471 $ bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem()); 10472 10473 $ Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb(); 10474 $ assert (teb); 10475 $ assert (teb->ProcessEnvironmentBlock); 10476 10477 $ Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters; 10478 $ assert (params); 10479 10480 $ if (minimizeConsole) // The fact that ShowWindow parameter of the program's console is taken from calling 10481 // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo() 10482 // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :( 10483 // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke!.. 10484 { 10485 $ params->dwFlags |= STARTF_USESHOWWINDOW; 10486 $ params->wShowWindow = SW_MINIMIZE; 10487 } 10488 10489 $ AllocConsole(); 10490 $ console = Win32::GetConsoleWindow(); 10491 } 10492 10493 $ if (!console) return NULL; 10494 10495 $ txSetLocale(); // Устанавливаем русскую кодовую страницу для консоли Windows 10496 10497 $ _txConsole_SetUnicodeFont(); // Впечатлительным лучше сюда не смотреть. 10498 10499 $ if (!_txIsConsoleSubsystem()) 10500 {$ txReopenStdio(); } // Переоткрываем потоки ввода-вывода, если subsystem != console 10501 10502 $ return console; 10503 } 10504 10505 //----------------------------------------------------------------------------------------------------------------- 10506 10507 int txSetLocale (int codepage /*= _TX_CODEPAGE*/, 10508 const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/) 10509 { 10510 $1 int oldPage = GetConsoleOutputCP(); 10511 10512 // Устанавливаем нужную кодовую страницу для консоли Windows 10513 10514 $ if (codepage) 10515 { 10516 $ SetConsoleCP (codepage); 10517 $ SetConsoleOutputCP (codepage); 10518 } 10519 10520 // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии 10521 // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным 10522 // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN - 10523 // обозначение кодовой страницы (например, для русского языка - CP1251). 10524 10525 $ if (locale) 10526 { 10527 $ setlocale (LC_ALL, locale); 10528 $ setlocale (LC_NUMERIC, "C"); // Return to decimal point (3.14) instead of comma (3,14) in floating numbers 10529 } 10530 10531 #ifndef __CYGWIN__ 10532 10533 $ const bool wine = !!Win32::wine_get_version; // Linux::Wine v1.2.2+ compatibility. 10534 10535 $ if (wLocale && !wine) 10536 { 10537 $ _wsetlocale (LC_ALL, wLocale); 10538 $ _wsetlocale (LC_NUMERIC, L"C"); // L"C" (see above) 10539 } 10540 10541 #endif 10542 10543 (void) wLocale; 10544 10545 $ return oldPage; 10546 } 10547 10548 //----------------------------------------------------------------------------------------------------------------- 10549 10550 void txReopenStdio() 10551 { 10552 $1 // Переоткрываем заново <s>Америку</s> потоки ввода-вывода 10553 10554 $ fflush (stdout); 10555 $ fflush (stderr); 10556 10557 $ FILE* f = NULL; 10558 10559 #ifndef __CYGWIN__ 10560 10561 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE), _O_TEXT), "r"); assert (f); *stdin = *f; 10562 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f; 10563 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE), _O_TEXT), "w"); assert (f); *stderr = *f; 10564 10565 #else 10566 10567 $ f = _fdopen (STDIN_FILENO, "r"); assert (f); *stdin = *f; 10568 $ f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f; 10569 $ f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f; 10570 10571 #endif 10572 10573 $ setvbuf (stdin, NULL, _IONBF, 0); 10574 $ setvbuf (stdout, NULL, _IONBF, 0); 10575 $ setvbuf (stderr, NULL, _IONBF, 0); 10576 10577 $ ::std::ios::sync_with_stdio(); 10578 } 10579 10580 //----------------------------------------------------------------------------------------------------------------- 10581 10582 inline bool _txConsole_OK() 10583 { 10584 return Win32::GetConsoleWindow() != NULL; 10585 } 10586 10587 //----------------------------------------------------------------------------------------------------------------- 10588 10589 bool _txConsole_Detach (bool activate) 10590 { 10591 $1 HWND console = Win32::GetConsoleWindow(); 10592 $ if (!console) return false; 10593 10594 $ EnableWindow (console, true); 10595 10596 $ if (activate) 10597 { 10598 $ if (!IsWindowVisible (console)) 10599 {$ ShowWindow (console, SW_MINIMIZE); } 10600 10601 $ _txActivateWindow (console, 0xFF); 10602 $ return true; 10603 } 10604 else 10605 { 10606 $ return !!FreeConsole(); 10607 } 10608 } 10609 10610 //----------------------------------------------------------------------------------------------------------------- 10611 10612 bool _txConsole_Draw (HDC dc) 10613 { 10614 $8 if (_TX_HDC_FAILED (dc)) return false; 10615 10616 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10617 10618 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 10619 $ BOOL ok = GetConsoleScreenBufferInfo (out, &con); 10620 $ if (!ok) return false; 10621 10622 $ POINT size = { con.srWindow.Right - con.srWindow.Left + 1, 10623 con.srWindow.Bottom - con.srWindow.Top + 1 }; 10624 10625 $ SIZE fontSz = { 12, 16 }; 10626 $ Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted; 10627 10628 $ COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, 10629 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF }; 10630 10631 $ for (short y = 0; y < size.y; y++) 10632 { 10633 static char chr [_TX_BUFSIZE + 1] = ""; // [con.dwSize.X + 1]; maybe will be truncated 10634 static WORD atr [_TX_BUFSIZE + 1] = {}; // [con.dwSize.X + 1]; maybe will be truncated 10635 COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) }; 10636 DWORD read = 0; 10637 10638 if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue; 10639 if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue; 10640 10641 for (int x = 0, xEnd = size.x; x < size.x; x = xEnd) 10642 { 10643 Win32::SetTextColor (dc, pal [ atr[x] & 0x0F]); 10644 Win32::SetBkColor (dc, pal [(atr[x] >> 4) & 0x0F]); 10645 Win32::SetBkMode (dc, (atr[x] & 0xF0)? OPAQUE : TRANSPARENT); 10646 10647 for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;} 10648 10649 Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)), 10650 ROUND (fontSz.cy * y), chr + x, xEnd - x) asserted; 10651 } 10652 } 10653 10654 $ Win32::SetTextColor (dc, pal [ con.wAttributes & 0x0F]); 10655 $ Win32::SetBkColor (dc, pal [(con.wAttributes >> 4) & 0x0F]); 10656 $ Win32::SetBkMode (dc, TRANSPARENT); 10657 10658 $ if (_txConsole_IsBlinking && 10659 In (std::nomeow, con.dwCursorPosition, con.srWindow) && 10660 GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval && 10661 GetForegroundWindow() == txWindow()) 10662 { 10663 $ Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)), 10664 ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1, 10665 "_", 1) asserted; 10666 } 10667 10668 $ return true; 10669 } 10670 10671 #endif // TX_COMPILED 10672 10673 //----------------------------------------------------------------------------------------------------------------- 10674 //{ Welcome to the Duck Side! Together we will rule the Bathroom! 10675 //----------------------------------------------------------------------------------------------------------------- 10676 10677 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10678 10679 bool _txConsole_SetUnicodeFont() 10680 { 10681 $ const bool wine = !!Win32::wine_get_version; // Linux::Wine v1.2.2+ compatibility. 10682 // Beer compatibility may be added in future versions... 10683 $ if (wine) // Минздрав РФ предупреждает: чрезмерное употребление wine 10684 { // вредит Вашему здоровью. 10685 $ Win32::GetNumberOfConsoleFonts = NULL; 10686 $ Win32::GetCurrentConsoleFont = NULL; 10687 $ Win32::SetConsoleFont = NULL; 10688 10689 $ return false; 10690 } 10691 10692 // Начиная с Висты все хорошо... 10693 10694 $1 if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx) 10695 { 10696 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10697 10698 $ Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) }; 10699 $ if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false; 10700 10701 $ info.FontFamily = 0x36; // Unicode fixed-pitch 10702 $ if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2); // Terminal font is too small 10703 10704 $ if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0) // Consolas is allowed too 10705 {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); } 10706 10707 $ return !!Win32::SetCurrentConsoleFontEx (out, false, &info); 10708 } 10709 10710 // ...а до этого все не так сладко 10711 10712 $ const unsigned uniFont = 10; // The Internet and W2K sources know this magic number 10713 $ const unsigned uniSize = 20; // Size of the font desired, should be > max # of Raster Fonts //-V2551 10714 $ bool ok = true; 10715 10716 // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font. 10717 10718 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10719 10720 $ unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ()); 10721 $ if (fonts && fonts <= uniFont) 10722 { 10723 $ HRESULT init = Win32::CoInitialize (NULL); 10724 $ size_t sz = 0; 10725 10726 $ char link [MAX_PATH] = ""; 10727 $ getenv_s (&sz, link, sizeof (link) - 1, "TEMP"); 10728 $ strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1); 10729 10730 $ char comspec [MAX_PATH] = ""; 10731 $ getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC"); 10732 10733 $ (void) _unlink (link); 10734 10735 $ _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted; 10736 10737 $ ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32); // Sic! //-V112 //-V566 10738 if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); } 10739 10740 $ (void) _unlink (link); 10741 10742 $ if (init == S_OK) Win32::CoUninitialize(); 10743 } 10744 10745 // If Unicode font is not already set, do set it. 10746 10747 $ Win32::CONSOLE_FONT_INFO cur = {}; 10748 $ _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur)); 10749 10750 $ ok &= (cur.nFont >= uniFont); 10751 if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); } 10752 10753 $ HWND console = Win32::GetConsoleWindow(); 10754 $ InvalidateRect (console, NULL, false); 10755 $ UpdateWindow (console); 10756 10757 $ return ok; 10758 } 10759 10760 #endif // TX_COMPILED 10761 10762 //----------------------------------------------------------------------------------------------------------------- 10763 //{ The assistants to the nightmare. You can use it freely to make your own nightmare sweet. 10764 10765 #define _TX_TRY { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error; 10766 #define _TX_CHECKED( cmd ) { if (FAILED (__tx_error = (cmd))) goto __tx_catch; } 10767 #define _TX_FAIL { __tx_error = E_FAIL; goto __tx_catch; } 10768 #define _TX_RETRY { __tx_error = S_OK; goto __tx_try; } 10769 #define _TX_OK ( SUCCEEDED (__tx_error) ) 10770 #define _TX_CATCH goto __tx_finally; __tx_catch: 10771 #define _TX_RETURN goto __tx_finally; 10772 #define _TX_FINALLY __tx_finally: 10773 #define _TX_ENDTRY } 10774 10775 //} 10776 //----------------------------------------------------------------------------------------------------------------- 10777 10778 // Мало не покажется 10779 10780 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10781 10782 bool _txCreateShortcut (const char shortcutName[], 10783 const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/, 10784 const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/, 10785 int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/) 10786 { 10787 $1 if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false; 10788 $ if (_TX_ARGUMENT_FAILED (fileToLink && *fileToLink)) return false; 10789 10790 #if defined (__IShellLinkDataList_INTERFACE_DEFINED__) 10791 10792 $ IShellLink* shellLink = NULL; 10793 $ IShellLinkDataList* dataList = NULL; 10794 $ IPersistFile* file = NULL; 10795 10796 $ HRESULT init = Win32::CoInitialize (NULL); 10797 10798 _TX_TRY 10799 { 10800 $ _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink)); 10801 $ if (!shellLink) _TX_FAIL; 10802 10803 $ shellLink->SetPath (fileToLink); 10804 $ shellLink->SetArguments (args); 10805 $ shellLink->SetWorkingDirectory (workDir); 10806 $ shellLink->SetDescription (description); 10807 $ shellLink->SetShowCmd (cmdShow); 10808 $ shellLink->SetIconLocation (iconFile, iconIndex); 10809 10810 $ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList)); 10811 $ if (!dataList) _TX_FAIL; 10812 10813 $ Win32::NT_CONSOLE_PROPS props = 10814 {{sizeof (props), NT_CONSOLE_PROPS_SIG}, 10815 10816 FOREGROUND_LIGHTGRAY, // wFillAttribute 10817 FOREGROUND_MAGENTA | BACKGROUND_WHITE, // wPopupFillAttribute 10818 {bufSize.X, bufSize.Y}, // dwScreenBufferSize 10819 {wndSize.X, wndSize.Y}, // dwWindowSize 10820 {wndOrg.X, wndOrg.Y}, // dwWindowOrigin 10821 0, // nFont 10822 0, // nInputBufferSize 10823 {0, (short) fontSize}, // dwFontSize 10824 0x36, 400, L"Lucida Console", // uFontFamily, uFontWeight, FaceName. We're dancing for this! 10825 15, // uCursorSize 10826 0, 1, 1, 0, // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition 10827 50, 4, 0, // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup 10828 10829 {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, // Palette 10830 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF} 10831 }; 10832 10833 $ _TX_CHECKED (dataList->AddDataBlock (&props)); 10834 10835 $ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file)); 10836 $ if (!file) _TX_FAIL; 10837 10838 $ wchar_t wName[MAX_PATH] = L""; 10839 $ MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName)); 10840 10841 $ _TX_CHECKED (file->Save (wName, true)); 10842 } 10843 10844 $ _TX_CATCH 10845 $ _TX_FINALLY 10846 10847 if (file) {$ file ->Release(); } 10848 if (dataList) {$ dataList ->Release(); } 10849 if (shellLink) {$ shellLink->Release(); } 10850 10851 if (init == S_OK) {$ Win32::CoUninitialize(); } 10852 10853 $ return _TX_OK; 10854 _TX_ENDTRY 10855 10856 #else 10857 10858 (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex; 10859 (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg; 10860 10861 $ return false; 10862 10863 #endif 10864 } 10865 10866 #endif // TX_COMPILED 10867 10868 //} 10869 //----------------------------------------------------------------------------------------------------------------- 10870 10872 //} 10873 //================================================================================================================= 10874 10875 //================================================================================================================= 10876 //{ Memory DC functions (_txBuffer...) 10878 //================================================================================================================= 10880 10881 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10882 10883 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/) 10884 { 10885 $1 txAutoLock _lock; 10886 10887 $ HDC wndDC = GetDC (wnd); 10888 $ if (!wndDC) return NULL; 10889 10890 $ POINT sz = { 1, 1 }; 10891 $ if (size) sz = *size; 10892 10893 $ if (!size && wnd) 10894 { 10895 $ RECT r = {}; 10896 $ GetClientRect (wnd, &r) asserted; 10897 10898 $ sz.x = r.right - r.left; 10899 $ sz.y = r.bottom - r.top; 10900 } 10901 10902 $ if (bitmap) 10903 { 10904 $ BITMAP bmap = {}; 10905 $ Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted; 10906 10907 $ sz.x = bmap.bmWidth; 10908 $ sz.y = bmap.bmHeight; 10909 } 10910 10911 $ RGBQUAD* buf = NULL; 10912 $ if (!pixels) pixels = &buf; 10913 10914 $ HDC dc = Win32::CreateCompatibleDC (wndDC); 10915 $ if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed"); 10916 10917 #ifndef _TX_DIB_FIX 10918 #define _TX_DIB_FIX 10919 #endif 10920 10921 $ BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }}; 10922 10923 $ HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0); 10924 $ if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed"); 10925 10926 $ Win32::SelectObject (dc, bmap) asserted; 10927 10928 $ if (!bitmap) 10929 { 10930 $ if (*pixels) 10931 { 10932 $ RGBQUAD black = { 0, 0, 0, 255 }; 10933 $ for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black; //-V108 10934 } 10935 else 10936 {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; } 10937 } 10938 10939 $ ReleaseDC (wnd, wndDC) asserted; 10940 10941 $ return dc; 10942 } 10943 10944 //----------------------------------------------------------------------------------------------------------------- 10945 10946 bool _txBuffer_Delete (HDC* dc) 10947 { 10948 $1 if (_TX_ARGUMENT_FAILED (dc)) return false; 10949 $ if ( !*dc) return false; 10950 $ if (_TX_HDC_FAILED (*dc)) return false; 10951 10952 $ if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false; 10953 10954 $ txAutoLock _lock; 10955 10956 $ _txBuffer_Select (Win32::GetStockObject (NULL_PEN), *dc) asserted; 10957 $ _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH), *dc) asserted; 10958 $ _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted; 10959 $ _txBuffer_Select (_txStockBitmap, *dc); 10960 10961 $ Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted; 10962 10963 $ Win32::DeleteDC (*dc) asserted; 10964 10965 $ *dc = NULL; 10966 10967 $ return true; 10968 } 10969 10970 //----------------------------------------------------------------------------------------------------------------- 10971 10972 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/) 10973 { 10974 $1 if (!obj) return false; 10975 $ if (_TX_HDC_FAILED (dc)) return false; 10976 10977 $ if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type"); 10978 10979 $ txAutoLock _lock; 10980 10981 $ obj = Win32::SelectObject (dc, obj); 10982 $ if (obj) Win32::DeleteObject (obj); 10983 10984 $ return obj != NULL; 10985 } 10986 10987 #endif // TX_COMPILED 10988 10990 //} 10991 //================================================================================================================= 10992 10993 //================================================================================================================= 10994 //{ Diagnostics 10996 //================================================================================================================= 10998 10999 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11000 11001 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/, 11002 const char* msg /*= NULL*/, ...) 11003 { //---/\---/\-------Это ASCII KOT!--// 11004 $1 va_list arg; va_start (arg, msg); // { '-' } // 11005 $$ const char* what = _txProcessError (file, line, func, color, msg, arg); // { 0 0 } Добавь его себе // 11006 va_end (arg); // --> V <-- в исходник, и тебе // 11007 // \ \|/ / будет, наверно, // 11008 if (!(msg && msg[0] == '\a')) return what; // \___/ приятно отлаживаться // 11009 //---------------долгими ночами:)--// 11010 // vvvvvvvvvvvvvvvvvv 11011 DebugBreak(); // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться. 11012 // ^^^^^^^^^^^^^^^^^^ 11013 11014 return what; // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7). 11015 } 11016 11017 #endif // TX_COMPILED 11018 11019 //----------------------------------------------------------------------------------------------------------------- 11020 //{ General runtime check hooks 11021 //----------------------------------------------------------------------------------------------------------------- 11022 11023 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11024 11025 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/) 11026 { 11027 $1 if (!sig && !fpe) 11028 { 11029 $ signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11030 $ signal (SIGFPE, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11031 $ signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11032 $ signal (SIGILL, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11033 $ signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11034 $ return; 11035 } 11036 11037 txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe); 11038 11039 #define GET_DESCR_(str, code, descr) case (code): {$ (str) = " " #code ": " descr; break; } 11040 11041 $ const char* sSig = "Неизвестный тип сигнала"; 11042 11043 $ switch (sig) 11044 { 11045 GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!") 11046 GET_DESCR_ (sSig, SIGILL, "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.") 11047 GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().") 11048 GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.") 11049 GET_DESCR_ (sSig, SIGFPE, "Грубая ошибка в вычислениях.") 11050 default: break; //-V2522 11051 } 11052 11053 $ const char* sFPE = ""; 11054 11055 #if defined (_MSC_VER) 11056 11057 // MSVC provides the FPE code as a MS extension. 11058 // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx 11059 11060 $ if (sig == SIGFPE) switch (fpe) 11061 { 11062 GET_DESCR_ (sFPE, _FPE_INVALID, "Результат неверен.") 11063 GET_DESCR_ (sFPE, _FPE_DENORMAL, "Денормализация.") 11064 GET_DESCR_ (sFPE, _FPE_ZERODIVIDE, "Деление на ноль.") 11065 GET_DESCR_ (sFPE, _FPE_OVERFLOW, "Результат слишком большой.") 11066 GET_DESCR_ (sFPE, _FPE_UNDERFLOW, "Результат слишком маленький.") 11067 GET_DESCR_ (sFPE, _FPE_INEXACT, "Результат неточен.") 11068 GET_DESCR_ (sFPE, _FPE_UNEMULATED, "Операция не поддерживается.") 11069 GET_DESCR_ (sFPE, _FPE_SQRTNEG, "Квадратный корень из отрицательного числа.") 11070 GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW, "Переполнение стека сопроцессора.") 11071 GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.") 11072 GET_DESCR_ (sFPE, _FPE_EXPLICITGEN, "Явный вызов исключения.") 11073 default: break; //-V2522 11074 } 11075 11076 #else 11077 $ fpe = 0; 11078 #endif 11079 11080 #undef GET_DESCR_ 11081 11082 $ signal (sig, (void(*)(int))(uintptr_t)_txOnSignal); 11083 11084 $ Win32::_fpreset(); 11085 11086 $ _TX_UNEXPECTED ("\a\t" 11087 "signal (%d, 0x%02X):%s%s " 11088 "%s%s" 11089 "С помощью функции signal() вы можете сами обработать эту ошибку.", 11090 sig, (unsigned) fpe, sSig, sFPE, 11091 ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1); 11092 } 11093 11094 //----------------------------------------------------------------------------------------------------------------- 11095 11096 void _txOnTerminate() 11097 { 11098 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11099 11100 // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc 11101 11102 $1 static int terminating = 0; 11103 if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; } 11104 11105 $ if (!*_txDumpSE) 11106 {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); } 11107 11108 $ _TX_UNEXPECTED ("\t\a" 11109 "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, " 11110 "или другая фатальная ошибка C++. " 11111 "%s" 11112 "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, " 11113 "разбирайтесь, в чем дело.\n\n" 11114 "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE, 11115 _txDumpSE + 1); 11116 } 11117 11118 //----------------------------------------------------------------------------------------------------------------- 11119 11120 void _txOnUnexpected() 11121 { 11122 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11123 11124 $1 if (!*_txDumpSE) 11125 {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); } 11126 11127 $ _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n" 11128 "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете " 11129 "спецификацию исключений для функций, проверьте, не нарушена ли она." 11130 "%s" 11131 "С помощью catch (...) в main() вы можете сами обработать эту ошибку.", 11132 _txDumpSE + 1); 11133 } 11134 11135 //----------------------------------------------------------------------------------------------------------------- 11136 11137 int _txOnMatherr (_exception* exc) 11138 { 11139 txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc); 11140 11141 $1 assert (exc); 11142 11143 const char* sType = "Неизвестный тип исключения"; 11144 11145 #if !defined (__CYGWIN__) 11146 11147 #define GET_DESCR_(code, descr) case (code): {$ sType = "(" #code "): " descr; break; } 11148 11149 $ switch (exc->type) 11150 { 11151 GET_DESCR_ (_DOMAIN, "Нарушение области определения"); 11152 GET_DESCR_ (_SING, "Сингулярность аргумента"); 11153 GET_DESCR_ (_PLOSS, "Частичная потеря значимости"); 11154 GET_DESCR_ (_TLOSS, "Полная потеря значимости"); 11155 GET_DESCR_ (_OVERFLOW, "Результат слишком большой"); 11156 GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький"); 11157 default: break; //-V2522 11158 } 11159 11160 #undef GET_DESCR_ 11161 11162 $ _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n" 11163 "С помощью __setusermatherr() вы можете сами обработать эту ошибку.", 11164 exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval); 11165 #else 11166 11167 $ _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType); 11168 11169 #endif 11170 11171 return 0; 11172 } 11173 11174 //----------------------------------------------------------------------------------------------------------------- 11175 11176 tx_noreturn void _txOnNewHandlerAnsi() 11177 { 11178 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11179 $1 11180 $ _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n" 11181 "С помощью std::set_new_handler() вы можете сами обработать эту ошибку " 11182 "и где-нибудь найти недостающую память."); 11183 11184 $ throw std::bad_alloc(); 11185 } 11186 11187 //----------------------------------------------------------------------------------------------------------------- 11188 11189 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code) 11190 { 11191 txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code); 11192 11193 $1 if (code) 11194 {$ errno = code; } 11195 11196 $ _TX_UNEXPECTED ("\a" 11197 "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n" 11198 "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку " 11199 "и постараться не выходить за границы массивов.", 11200 code, msg, (char*) ptr, ptr); 11201 } 11202 11203 //----------------------------------------------------------------------------------------------------------------- 11204 11205 int tx_glGetError (int setError /*= INT_MIN*/) 11206 { 11207 $1 _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError; 11208 $ return _txOGLError; 11209 } 11210 11211 #endif // TX_COMPILED 11212 11213 //} 11214 //----------------------------------------------------------------------------------------------------------------- 11215 11216 //----------------------------------------------------------------------------------------------------------------- 11217 //{ MSC Runtime check hooks 11218 //----------------------------------------------------------------------------------------------------------------- 11219 11220 #if defined (_MSC_VER) 11221 11222 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11223 11224 //----------------------------------------------------------------------------------------------------------------- 11225 11226 int _txOnNewHandler (size_t size) 11227 { 11228 txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size); 11229 $5 11230 $ _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n" 11231 "С помощью _set_new_handler() вы можете сами обработать эту ошибку " 11232 "и где-нибудь найти недостающую память.", (unsigned long long) size); 11233 11234 $ throw std::bad_alloc(); 11235 } 11236 11237 //----------------------------------------------------------------------------------------------------------------- 11238 11239 void _txOnSecurityError (int code, void* addr) 11240 { 11241 txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr); 11242 $5 11243 $ _TX_UNEXPECTED ("\a" 11244 "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n" 11245 "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку " 11246 "и более торжественно завершить программу. Ставьте же ассерты.", code); 11247 } 11248 11249 //----------------------------------------------------------------------------------------------------------------- 11250 11251 void _txOnPureCall() 11252 { 11253 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11254 $5 11255 $ _TX_UNEXPECTED ("\a" 11256 "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах " 11257 "или деструкторах базовых классов - не вызывайте там таких функций.\n\n" 11258 "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку " 11259 "и проверить свое знание С++ :)"); 11260 } 11261 11262 //----------------------------------------------------------------------------------------------------------------- 11263 11264 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr) 11265 { 11266 txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr); 11267 11268 $5 assert (wExpr); 11269 assert (wFunc); 11270 assert (wFile); 11271 11272 char expr [_TX_BUFSIZE/2] = "[Unknowm expr]", 11273 func [_TX_BUFSIZE/2] = "[Unknowm func]", 11274 file [MAX_PATH] = "[Unknowm file]"; 11275 11276 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL); 11277 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL); 11278 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL); 11279 11280 $$ _txError (file, (int) line, func, 0, "\a" 11281 "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n" 11282 "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr); 11283 } 11284 11285 //----------------------------------------------------------------------------------------------------------------- 11286 11287 #if defined (_CLANG_VER) && !defined (_MSC_VER) 11288 11289 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info) 11290 { 11291 $5 assert (&info); 11292 11293 $$ _txError (info.__file_, info.__line_, NULL, 0, "\a" 11294 "Оказалось неверно, что %s (%s). Не надо так.\n\n" 11295 "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_); 11296 } 11297 11298 #endif 11299 11300 //----------------------------------------------------------------------------------------------------------------- 11301 11302 #pragma runtime_checks ("", off) 11303 11304 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...) 11305 { 11306 txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format); 11307 11308 $5 static long running = 0; 11309 $ while (InterlockedExchange (&running, 1)) Sleep (0); 11310 11311 $ assert (format); 11312 11313 // Disable all RTC failures 11314 11315 $ int nErrors = _RTC_NumErrors(); 11316 $ int* errors = NULL; 11317 $ try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;} //-V104 11318 11319 $ int err = 0; 11320 $ for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE); //-V108 11321 11322 $ char text [_TX_BUFSIZE] = ""; 11323 11324 $ va_list arg; va_start (arg, format); 11325 $ _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg); // Get message from the vararg list 11326 $ auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/); // Get the RTC error number 11327 $ va_end (arg); 11328 11329 $ const char* sType = "type"; 11330 11331 $ switch (type) 11332 { 11333 case _CRT_ERROR: $ sType = "ошибка"; break; 11334 case _CRT_ASSERT: $ sType = "логическая ошибка"; break; 11335 case _CRT_WARN: $ sType = "возможная ошибка"; break; 11336 default: $ break; 11337 } 11338 11339 $ const char* sError = _RTC_GetErrDesc (error); 11340 11341 $$ _txError (file, line, NULL, 0, "\a" 11342 "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module); 11343 11344 // The code below will be never executed until the error above will stay fatal: 11345 11346 // Restore the RTC error types 11347 11348 #if defined (_MSC_VER) 11349 #pragma warning (push) 11350 #pragma warning (disable: 6385) // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read. 11351 #endif 11352 11353 $ for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR)); //-V108 11354 11355 #if defined (_MSC_VER) 11356 #pragma warning (pop) // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read. 11357 #endif 11358 11359 $ InterlockedExchange (&running, 0); 11360 $ return 1; 11361 } 11362 11363 #pragma runtime_checks ("", restore) 11364 11365 //----------------------------------------------------------------------------------------------------------------- 11366 11367 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line) 11368 { 11369 #if (_TX_ALLOW_TRACE +0 >= 4) 11370 11371 static _tx_thread int recursive = 0; 11372 if (recursive) return true; 11373 recursive++; 11374 11375 #if (_TX_ALLOW_TRACE +0 <= 10) 11376 if (!size) return true; 11377 #endif 11378 11379 #define GET_DESCR_(str, type) case (type): { str = #type; break; } 11380 11381 const char* sType = "Unknown type"; 11382 const char* sUse = "Unknown use"; 11383 11384 switch (_BLOCK_TYPE (type)) 11385 { 11386 GET_DESCR_ (sType, _HOOK_ALLOC); 11387 GET_DESCR_ (sType, _HOOK_REALLOC); 11388 GET_DESCR_ (sType, _HOOK_FREE); 11389 default: break; 11390 } 11391 11392 switch (use) 11393 { 11394 GET_DESCR_ (sUse, _NORMAL_BLOCK); 11395 GET_DESCR_ (sUse, _CRT_BLOCK); 11396 GET_DESCR_ (sUse, _CLIENT_BLOCK); 11397 GET_DESCR_ (sUse, _FREE_BLOCK); 11398 GET_DESCR_ (sUse, _IGNORE_BLOCK); 11399 default: break; 11400 } 11401 11402 #undef GET_DESCR_ 11403 11404 _txTrace ((const char*) file, line, NULL, "%*s" 11405 "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)", 11406 2 * _txLoc::Cur.inTX, "", 11407 type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request); 11408 11409 recursive--; 11410 11411 #else 11412 11413 UNREFERENCED_PARAMETER (type); 11414 UNREFERENCED_PARAMETER (data); 11415 UNREFERENCED_PARAMETER (size); 11416 UNREFERENCED_PARAMETER (use); 11417 UNREFERENCED_PARAMETER (request); 11418 UNREFERENCED_PARAMETER (file); 11419 UNREFERENCED_PARAMETER (line); 11420 11421 #endif 11422 11423 return true; //-V601 11424 } 11425 11426 //----------------------------------------------------------------------------------------------------------------- 11427 11428 #endif // TX_COMPILED 11429 11430 #endif 11431 11432 //} 11433 //----------------------------------------------------------------------------------------------------------------- 11434 11435 //----------------------------------------------------------------------------------------------------------------- 11436 //{ SEH staff 11437 //----------------------------------------------------------------------------------------------------------------- 11438 11439 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11440 11441 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc) 11442 { 11443 if (!_txProcessSystemWarnings) 11444 { 11445 DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode : 0; //-V560 11446 void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL; //-V560 11447 11448 if (code != DBG_PRINTEXCEPTION_C && 11449 code != DBG_PRINTEXCEPTION_WIDE_C) 11450 { 11451 txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n", 11452 _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings); 11453 } 11454 11455 return (!(exc && exc->ExceptionRecord && exc->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))? 11456 EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER; 11457 } 11458 else 11459 { 11460 int inTX = _txLoc::Cur.inTX++; 11461 11462 long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler"); 11463 11464 _txLoc::Cur.inTX = inTX; 11465 return ret; 11466 } 11467 } 11468 11469 //----------------------------------------------------------------------------------------------------------------- 11470 11471 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc) 11472 { 11473 int inTX = _txLoc::Cur.inTX++; 11474 11475 long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter"); 11476 11477 if (_txPrevUEFilter) 11478 { 11479 if (_txSetJmp()) 11480 { 11481 int inTX2 = _txLoc::Cur.inTX++; 11482 11483 ret = _txPrevUEFilter (exc); 11484 11485 _txLoc::Cur.inTX = inTX2; 11486 } 11487 else 11488 { 11489 $6 _txClearJmp(); 11490 11491 _TX_UNEXPECTED ("\t\a" "%s" 11492 "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n" 11493 "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE, 11494 _txDumpSE + 1); 11495 } 11496 } 11497 11498 _txLoc::Cur.inTX = inTX; 11499 return ret; 11500 } 11501 11502 //----------------------------------------------------------------------------------------------------------------- 11503 11504 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter) 11505 { 11506 $6 _txPrevUEFilter = filter; 11507 11508 return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter; 11509 } 11510 11511 //----------------------------------------------------------------------------------------------------------------- 11512 11513 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[]) 11514 { 11515 assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; } //-V547 11516 11517 assert (exc->ExceptionRecord); 11518 11519 assert (func); 11520 assert (func[3] == 'V' || func[3] == 'U'); 11521 11522 bool unhExc = (func[3] == 'U'); 11523 DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode : 0; //-V560 11524 void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL; //-V560 11525 11526 if (code == DBG_PRINTEXCEPTION_C || 11527 code == DBG_PRINTEXCEPTION_WIDE_C || 11528 code == DBG_THREAD_NAME || 11529 11530 #ifdef _TX_SKIP_EXCEPTION 11531 code == _TX_SKIP_EXCEPTION || 11532 #endif 11533 11534 (code == RPC_S_SERVER_UNAVAILABLE && !unhExc) || 11535 (code == RPC_S_CALL_CANCELLED && !unhExc) || 11536 (code == EXCEPTION_BREAKPOINT && IsDebuggerPresent())) 11537 { 11538 return EXCEPTION_CONTINUE_SEARCH; 11539 } 11540 11541 ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr; 11542 if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; } 11543 11544 dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr; 11545 if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; } 11546 11547 _txSENumber = _txSENumber + 1; 11548 if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1; 11549 11550 OutputDebugString ("\n"); 11551 txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n", 11552 _TX_VERSION, _txSENumber, func, (unsigned long) code, addr); 11553 11554 $6 if (*(unsigned long long*) _txDumpExceptionObjJmp) 11555 { 11556 $ longjmp (_txDumpExceptionObjJmp, 1); //-V2512 11557 } 11558 11559 tx_fpreset(); 11560 11561 #if defined (_MSC_VER) 11562 if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); } 11563 #endif 11564 11565 $ bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord)); //-V560 11566 11567 $ if (primaryException && exc) //-V560 11568 { 11569 $ unsigned err = GetLastError(); 11570 11571 $ const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc); 11572 11573 $ _txDumpExceptionSEH (_txDumpSE, (intptr_t) sizeof (_txDumpSE) - 1, exc->ExceptionRecord, func); 11574 $ _tx_snprintf_s (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace); 11575 11576 $ static _tx_thread DWORD prevCode = 0; 11577 $ static _tx_thread void* prevAddr = NULL; 11578 11579 $ if (code != prevCode && addr != prevAddr && 11580 !strstr (_txDumpSE, "Объект исключения C++:")) 11581 { 11582 $ SetLastError (err); 11583 $ _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1); 11584 11585 $ prevCode = code; 11586 $ prevAddr = addr; 11587 } 11588 11589 $ SetLastError (err); 11590 } 11591 11592 $ if (_txDumpSE[0] == '\a' || 11593 _txSENumber >= _TX_EXCEPTIONS_LIMIT+0 || 11594 _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0) 11595 { 11596 $ _TX_UNEXPECTED ("\a\t" "%s" 11597 "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.", 11598 _txDumpSE + 1); 11599 } 11600 11601 $ return (!(exc && exc->ExceptionRecord && exc->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))? 11602 EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER; 11603 } 11604 11605 //----------------------------------------------------------------------------------------------------------------- 11606 11607 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]) //-V2008 11608 { 11609 $6 assert (what); 11610 $ assert (size >= 0); //-V547 11611 assert (exc); if (!exc) {$ return 0; } //-V547 11612 $ assert (func); 11613 11614 $ unsigned code = exc->ExceptionCode; 11615 $ void* addr = exc->ExceptionAddress; 11616 $ unsigned params = exc->NumberParameters; 11617 $ const ULONG_PTR* info = exc->ExceptionInformation; 11618 $ void* object = (params >= 2)? (void*) info[1] : NULL; 11619 11620 $ char* s = what; 11621 11622 #define PRINT_(...) s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__) 11623 11624 $ const char* sCode = NULL; 11625 $ const char* sDescr = NULL; 11626 11627 #define GET_DESCR_(code, descr) case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; } 11628 11629 $ switch (code) 11630 { 11631 GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION, " " "Нарушение доступа к памяти.") 11632 GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION, " " "Недопустимая операция.") 11633 GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION, " " "Привилегированная операция.") 11634 GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "\a" "Выход за границы массива. Ставьте ассерты!") 11635 GET_DESCR_ (EXCEPTION_BREAKPOINT, "\a" "Достигнута точка останова. Удачи в отладке!") 11636 GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT, "\a" "Нарушение выравнивания данных.") 11637 GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION, "\a" "Обработчик исключения возвратил неверное значение.") 11638 GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR, "\a" "Невозможно загрузить нужную страницу памяти.") 11639 GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.") 11640 GET_DESCR_ (EXCEPTION_SINGLE_STEP, "\a" "Выполнена инструкция машинного кода. Одна штука.") 11641 GET_DESCR_ (EXCEPTION_STACK_OVERFLOW, "\a" "Ю-ху! Переполнение стека!") 11642 GET_DESCR_ (EXCEPTION_GUARD_PAGE, "\a" "Попытка доступа к защищенной странице памяти.") 11643 GET_DESCR_ (EXCEPTION_INVALID_HANDLE, "\a" "Неверный или уже закрытый дескриптор.") 11644 GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK, "\a" "Возможно, взаимная блокировка ресурсов.") 11645 11646 GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK, "\a" "Ошибка стека при операции с плавающей точкой.") 11647 GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND, " " "Денормализация числа с плавающей точкой.") 11648 GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO, " " "Деление на ноль при операции с плавающей точкой.") 11649 GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT, " " "Неточный результат при операции с плавающей точкой.") 11650 GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION, " " "Недопустимая операция с плавающей точкой.") 11651 GET_DESCR_ (EXCEPTION_FLT_OVERFLOW, " " "Переполнение при операции с плавающей точкой.") 11652 GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW, " " "Потеря значимости при операции с плавающей точкой.") 11653 GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS, " " "Множественные ошибки с плавающей точкой.") 11654 11655 GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO, "\a" "Целочисленное деление на ноль.") 11656 GET_DESCR_ (EXCEPTION_INT_OVERFLOW, "\a" "Переполнение при целочисленной операции.") 11657 11658 GET_DESCR_ (EXCEPTION_CLR_FAILURE, "\a" "Сбой среды исполнения (CLR).") 11659 GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN, "\a" "Переполнение стекового буфера!") 11660 GET_DESCR_ (STATUS_ASSERTION_FAILURE, "\a" "Сработал assert. На этот раз из ядра.") 11661 GET_DESCR_ (STATUS_WX86_BREAKPOINT, "\a" "Точка останова подсистемы эмуляции x86.") 11662 GET_DESCR_ (RPC_S_UNKNOWN_IF, "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).") 11663 GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE, "\a" "Сервер удаленного вызова процедур (RPC) недоступен.") 11664 GET_DESCR_ (DBG_TERMINATE_THREAD, "\a" "Отладчик завершил поток сознания.") 11665 GET_DESCR_ (DBG_TERMINATE_PROCESS, "\a" "Отладчик завершил процесс.") 11666 GET_DESCR_ (DBG_CONTROL_C, "\a" "Отладчик получил сигнал прерывания Control+C.") 11667 GET_DESCR_ (DBG_CONTROL_BREAK, "\a" "Отладчик получил сигнал прерывания Control+Break.") 11668 GET_DESCR_ (DBG_THREAD_NAME, " " "Отладчик получил указание дать потоку имя.") 11669 GET_DESCR_ (DBG_PRINTEXCEPTION_C, " " "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).") 11670 GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C, " " "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).") 11671 11672 GET_DESCR_ (EXCEPTION_CPP_MSC, " " "Исключение MSC С++, вызванное оператором throw.") 11673 GET_DESCR_ (EXCEPTION_CPP_GCC, " " "Исключение GNU С++, вызванное оператором throw.") 11674 GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND, " " "Исключение GNU С++, вызванное во время раскрутки стека (rethrow?).") 11675 GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED, " " "Исключение GNU С++, вызванное нарушением магии.") 11676 GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER, "\a" "Это скомпилилось под Билдер? O_O") 11677 GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI, "\a" "Это же С++. Как это вышло?") 11678 11679 default: $ break; 11680 } 11681 11682 #undef GET_DESCR_ 11683 11684 $ if (sDescr) 11685 { 11686 $ PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode); 11687 } 11688 else 11689 { 11690 $ PRINT_ ("\a#%ld: ", _txSENumber); 11691 $ s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 11692 GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 11693 s, (DWORD) (size - (s-what)), NULL) - 2; //-V202 11694 $ PRINT_ ("\r\r"); 11695 } 11696 11697 $ PRINT_ (" (0x%X) при выполнении кода по адресу", code); 11698 $ PRINT_ ((addr? " 0x%p" : " NULL"), addr); 11699 11700 $ Win32::SYMBOL_INFO* sym = NULL; 11701 $ Win32::IMAGEHLP_LINE64* line = NULL; 11702 11703 if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); } 11704 11705 $ if (sym && *sym->Name) PRINT_ (" в функции %s()", sym->Name); 11706 $ if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber); 11707 11708 $ if (code == EXCEPTION_ACCESS_VIOLATION || 11709 code == EXCEPTION_IN_PAGE_ERROR) 11710 { 11711 $ PRINT_ (". Попытка "); 11712 11713 $ unsigned long op = 0xBADC0DE; 11714 $ const char* sOp = "(действие не указано)"; 11715 11716 $ if (params >= 1) 11717 { 11718 $ switch (op = (unsigned long) info[0]) //-V202 11719 { 11720 case 0: $ sOp = "прочесть данные"; break; 11721 case 1: $ sOp = "записать данные"; break; 11722 case 8: $ sOp = "исполнить код"; break; 11723 default: $ sOp = "совершить операцию 0x%lX"; break; 11724 } 11725 } 11726 11727 $ PRINT_ (sOp, op); 11728 11729 $ if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); } //-V1048 11730 else {$ PRINT_ (" (адрес не указан)"); } 11731 11732 $ if (code == EXCEPTION_IN_PAGE_ERROR) 11733 { 11734 $ PRINT_ (", ошибка ввода-вывода:"); 11735 11736 $ if (params >= 3) 11737 { 11738 $ unsigned long ntstatus = (unsigned long) info[2]; //-V202 11739 11740 $ PRINT_ (" 0x%lX (", ntstatus); 11741 11742 $ s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 11743 GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 11744 s, (DWORD) (size - (s-what)), NULL) - 2; //-V202 11745 $ PRINT_ (")"); 11746 } 11747 else 11748 {$ PRINT_ (" (не указана)"); } 11749 } 11750 } 11751 11752 $ HMODULE module = NULL; 11753 $ _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module)); 11754 11755 $ if (module) 11756 { 11757 $ static char sModule [MAX_PATH] = ""; 11758 $ int ok = GetModuleFileName (module, sModule, sizeof (sModule)); 11759 11760 $ char* ext = (ok? strrchr (sModule, '.') : NULL); 11761 $ if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule)); 11762 11763 if (ok) {$ PRINT_ (" в модуле %s", sModule); } 11764 else {$ PRINT_ (" в модуле 0x%p", (void*) module); } 11765 } 11766 11767 $ PRINT_ ("."); 11768 11769 $ if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0) 11770 {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).", _TX_EXCEPTIONS_LIMIT+0); } 11771 11772 $ if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0) 11773 {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); } 11774 11775 $ PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func); 11776 11777 $ if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE) 11778 {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); } 11779 11780 $ if (exc->ExceptionRecord) 11781 { 11782 $ PRINT_ ("\n\n" "Причина:" "\n\n"); 11783 $ s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func); 11784 } 11785 11786 $ if (code == EXCEPTION_CPP_GCC || 11787 code == EXCEPTION_CPP_GCC_UNWIND || 11788 code == EXCEPTION_CPP_GCC_FORCED || 11789 code == EXCEPTION_CPP_MSC) 11790 { 11791 $ s += _txDumpExceptionCPP (s, size - (s-what), code, params, info); 11792 } 11793 11794 #undef PRINT_ 11795 11796 $ while (s > what && s[-1] == '\n') s--; 11797 $ if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n"); 11798 11799 $ return s - what; 11800 } 11801 11802 //----------------------------------------------------------------------------------------------------------------- 11803 11804 intptr_t _txDumpExceptionCPP (char what[], intptr_t size, 11805 unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/) 11806 { 11807 $6 assert (what); 11808 $ assert (size >= 0); //-V547 11809 11810 $ char* s = what; 11811 11812 $ switch (code) 11813 { 11814 #if defined (_GCC_VER) 11815 11816 case EXCEPTION_CPP_GCC: 11817 case EXCEPTION_CPP_GCC_UNWIND: 11818 case EXCEPTION_CPP_GCC_FORCED: 11819 { 11820 // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp 11821 // [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below 11822 // [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below 11823 // [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below 11824 // and figure above near ABI::__cxa_exception definition in this file 11825 11826 $ const std::type_info* type = NULL; 11827 $ void* object = NULL; 11828 11829 $ if (params >= 1) 11830 { 11831 $ _Unwind_Exception* unwind_exception = (_Unwind_Exception*) info[0]; 11832 $ ABI::__cxa_exception* cxa_exception = (ABI::__cxa_exception*) (unwind_exception + 1) - 1; 11833 11834 $ type = cxa_exception->exceptionType; 11835 $ object = cxa_exception + 1; 11836 } 11837 11838 $ s += _txDumpExceptionObj (s, size - (s-what), object, 0, type); 11839 } 11840 $ break; 11841 11842 case 0: // Not called within SEH chain 11843 { 11844 // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc 11845 // [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc 11846 11847 using namespace abi; 11848 11849 $ ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions; 11850 11851 $ if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1)) // Dependent exception, case B, see pic above 11852 { 11853 $ cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1; 11854 } 11855 11856 $ if (cxa_exception) 11857 { 11858 $ verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type()); 11859 11860 $ s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType); 11861 } 11862 } 11863 $ break; 11864 11865 #elif defined (_MSC_VER) 11866 11867 case EXCEPTION_CPP_MSC: 11868 { 11869 // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273 11870 // [2] http://www.openrce.org/articles/full_view/21 11871 // [3] http://www.openrce.org/articles/full_view/23 11872 // [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf 11873 11874 $ const std::type_info* type = NULL; 11875 $ void* object = (params >= 2)? (void*) info[1] : NULL; 11876 $ size_t szObj = 0; 11877 11878 $ if (params >= 3 && 11879 (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 || 11880 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 || 11881 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 || 11882 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1)) 11883 { 11884 $ auto throwInfo = (const Win32::ThrowInfo*) info[2]; 11885 11886 $ if (throwInfo && throwInfo->pCatchableTypeArray) 11887 { 11888 $ HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL; //-V112 11889 11890 #define RVA_(type, addr) ( (type) ((uintptr_t) module + (uintptr_t) (addr)) ) 11891 11892 $ const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray); 11893 $ const Win32::CatchableType* cType = RVA_(const Win32::CatchableType*, cArray->arrayOfCatchableTypes[0]); 11894 11895 $ type = RVA_(const std::type_info*, cType->pType); 11896 $ szObj = cType->sizeOrOffset; //-V101 11897 11898 #undef RVA_ 11899 } 11900 } 11901 11902 $ s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type); 11903 } 11904 break; 11905 11906 case 0: // Not called within SEH chain 11907 11908 // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC: 11909 // 11910 // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception. 11911 // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp 11912 // 11913 // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception. 11914 // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp 11915 // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp 11916 // and http://msdn.microsoft.com/en-us/library/ff730818.aspx. 11917 // 11918 // So _txDumpSE information should have been recorded during previous call. Now do nothing. 11919 11920 $ break; 11921 11922 #endif 11923 11924 default: 11925 $ txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code); 11926 $ break; 11927 } 11928 11929 $ while (s > what && s[-1] == '\n') s--; 11930 $ if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n"); 11931 11932 $ return (s - what); 11933 } 11934 11935 //----------------------------------------------------------------------------------------------------------------- 11936 11937 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type) //-V2008 11938 { 11939 $6 assert (what); 11940 $ assert (size > 0); //-V547 11941 11942 $ static char* s = NULL; s = what; 11943 $ static size_t szObj = 0; szObj = sizeObj; 11944 11945 #define PRINT_(...) s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__) 11946 11947 $ PRINT_ ("\n\n" "Объект исключения C++:"); 11948 11949 $ const char* mangledName = (type)? type->name() : NULL; 11950 11951 $ char* typeName = NULL; 11952 $ int err = 1; 11953 11954 #if defined (_GCC_VER) 11955 $ typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); 11956 #endif 11957 11958 $ const char* name = (!err && typeName)? typeName : mangledName; //-V560 11959 11960 $ if (name && 11961 (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >") == 0 || 11962 strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >") == 0)) 11963 {$ name = "std::string"; } 11964 11965 $ if (name && 11966 (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *") == 0 || 11967 strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 || 11968 strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*") == 0)) 11969 {$ name = "std::string*"; } 11970 11971 if (name) {$ PRINT_ (" %s", name); } 11972 11973 #if defined (_GCC_VER) 11974 $ free (typeName); 11975 #endif 11976 11977 $ err = 0; 11978 $ if (mangledName) 11979 { 11980 if (_txSetJmp()) 11981 { 11982 #define PRINT_VAL_(fmt, typ, ...) \ 11983 else if (*type == typeid ( typ )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \ 11984 else if (*type == typeid (const typ )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \ 11985 else if (*type == typeid ( typ* )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 11986 else if (*type == typeid (const typ* )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 11987 else if (*type == typeid ( typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 11988 else if (*type == typeid (const typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } 11989 #define NO_ 11990 11991 if (false) ; 11992 PRINT_VAL_ ("%s", char*, NO_) PRINT_VAL_ ('%c', unsigned char, NO_) PRINT_VAL_ (%s, bool, ? "true" : "false") //-V206 //-V517 11993 PRINT_VAL_ ( %d, int, NO_) PRINT_VAL_ ( %u, unsigned int, NO_) PRINT_VAL_ (%g, float, NO_) //-V206 11994 PRINT_VAL_ ( %hd, short, NO_) PRINT_VAL_ ( %hu, unsigned short, NO_) PRINT_VAL_ (%g, double, NO_) //-V206 11995 PRINT_VAL_ ( %ld, long, NO_) PRINT_VAL_ ( %lu, unsigned long, NO_) PRINT_VAL_ ('%c', char, NO_) //-V206 11996 PRINT_VAL_ ("%s", std::string, .c_str()) //-V206 11997 11998 else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object)) 11999 { 12000 $ PRINT_ (", what(): \"%s\"", e->what()); 12001 } 12002 else 12003 {$ err = 1; } 12004 } 12005 else 12006 {$ err = 2; } 12007 } 12008 12009 $ _txClearJmp(); 12010 12011 $ if (err && object && szObj) 12012 { 12013 $ const unsigned char* buf = (const unsigned char*) object; 12014 12015 $ if (szObj >= 64) szObj = 64; 12016 12017 $ PRINT_ (", дамп: ["); 12018 $ for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' ); 12019 12020 $ PRINT_ ("]"); 12021 $ for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]); 12022 12023 $ err = 0; 12024 } 12025 12026 $ if (err) 12027 {$ PRINT_ (" = ??"); } 12028 12029 $ PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object); //-V560 12030 12031 #undef PRINT_VAL_ 12032 #undef PRINT_ 12033 #undef NO_ 12034 12035 $ return s - what; 12036 } 12037 12038 #endif // TX_COMPILED 12039 12040 //} 12041 //----------------------------------------------------------------------------------------------------------------- 12042 12043 //----------------------------------------------------------------------------------------------------------------- 12044 //{ Stack trace and debug info access 12045 //----------------------------------------------------------------------------------------------------------------- 12046 12047 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 12048 12049 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/, 12050 CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/, 12051 HANDLE thread /*= GetCurrentThread()*/) 12052 { 12053 $6 const int maxFrames = 62; // MS says: < 63 12054 $ static char trace [(MAX_PATH + 1024+1) * maxFrames] = ""; 12055 12056 if (framesToSkip == -1) {$ return trace; } 12057 12058 $ static void* capture [maxFrames] = {}; 12059 $ int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread); 12060 12061 $ memset (trace, 0, sizeof (trace)); 12062 $ char* s = trace; 12063 12064 #define PRINT_(...) s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__) 12065 12066 $ for (int i = 0, n = 0; i < frames; i++) //-V2530 12067 { 12068 $ void* addr = capture[i]; 12069 12070 $ Win32::SYMBOL_INFO* sym = NULL; 12071 $ Win32::IMAGEHLP_LINE64* line = NULL; 12072 $ const char* module = NULL; 12073 $ const char* source = NULL; 12074 $ bool inTX = false; 12075 12076 if (addr) {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module); } 12077 if (readSource && !inTX) {$ _txSymGetFromAddr ((void*) 1, NULL, NULL, NULL, &source, 2); } //-V566 12078 12079 $ int nl = 0; 12080 $ while (s > trace && s[-1] == '\n') { s--; nl++; } 12081 12082 #if !defined (_TX_FULL_STACKTRACE) 12083 12084 $ if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber)))) 12085 {$ continue; } 12086 12087 #endif 12088 12089 $ PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr); 12090 $ n++; 12091 12092 if (addr == 0) {$ PRINT_ (" [Неверный фрейм]"); break; } 12093 if (addr == (void*) -1) {$ PRINT_ (" [Странный фрейм]"); break; } 12094 if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; } //-V566 12095 12096 if (module) {$ PRINT_ (" in %s%s", module, ((sym && *sym->Name)? ": " : "")); } 12097 if (sym && *sym->Name) {$ PRINT_ ("%s()", sym->Name); } 12098 if (line && line->FileName) {$ PRINT_ (" at %s", line->FileName); } 12099 if (line && line->LineNumber) {$ PRINT_ (" (%d)", (int) line->LineNumber); } 12100 if (source) {$ PRINT_ (":\n\n" "%s\n", source); } 12101 12102 if (sym && strcmp (sym->Name , "main") == 0) {$ break; } 12103 } 12104 12105 #if defined (_MSC_VER) 12106 #pragma warning (push) 12107 #pragma warning (disable: 28199) // Using possibly uninitialized memory '*s' 12108 #endif 12109 12110 $ while (s > trace && s[-1] == '\n') s--; 12111 $ *s = 0; 12112 12113 #if defined (_MSC_VER) 12114 #pragma warning (pop) // Using possibly uninitialized memory '*s' 12115 #endif 12116 12117 #undef PRINT_ 12118 12119 $ s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), ""); 12120 12121 $ _txCreateMiniDump (exc); 12122 12123 $ return trace; 12124 } 12125 12126 //----------------------------------------------------------------------------------------------------------------- 12127 12128 // Stack WALKING if the program is DEAD. Dead, Carl! 12129 12130 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/, 12131 HANDLE thread /* = GetCurrentThread()*/) 12132 { 12133 $6 namespace MinGW = Win32::MinGW; 12134 12135 $ assert (capture); 12136 12137 $ HANDLE process = GetCurrentProcess(); 12138 $ bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId()); 12139 12140 $ CONTEXT ctx = {}; 12141 $ ctx.ContextFlags |= CONTEXT_FULL; 12142 12143 $ int isWow64 = 0; 12144 $ if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64); 12145 else {$ return -1; } 12146 12147 $ if (context) 12148 { 12149 $ ctx = *context; 12150 } 12151 else 12152 { 12153 $ if (thisThread) 12154 { 12155 $ _TX_CALLv (Win32::RtlCaptureContext, (&ctx)); 12156 } 12157 else 12158 { 12159 $ SuspendThread (thread); //-V720 12160 12161 $ ctx.ContextFlags = CONTEXT_ALL; 12162 $ bool ok = !!GetThreadContext (thread, &ctx); 12163 12164 $ if (!ok) 12165 { 12166 $ ResumeThread (thread); 12167 $ return -1; 12168 } 12169 } 12170 } 12171 12172 $ Win32::STACKFRAME64 frame = {}; 12173 $ frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat; 12174 12175 $ int cpu = 0; 12176 12177 #if defined (_WIN64) 12178 12179 $ if (isWow64) 12180 { 12181 $ Win32::WOW64_CONTEXT wow64ctx = {}; 12182 $ wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL; 12183 12184 $ if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx))) // This call fails in WINE, 12185 { // while EXIT_PROCESS_DEBUG_EVENT 12186 if (!thisThread) {$ ResumeThread (thread); } 12187 $ return 0; 12188 } 12189 12190 $ cpu = IMAGE_FILE_MACHINE_I386; 12191 12192 $ frame.AddrPC .Offset = wow64ctx.Eip; 12193 $ frame.AddrStack.Offset = wow64ctx.Esp; 12194 $ frame.AddrFrame.Offset = wow64ctx.Ebp; 12195 } 12196 else 12197 { 12198 $ cpu = IMAGE_FILE_MACHINE_AMD64; 12199 12200 $ frame.AddrPC .Offset = ctx.Rip; 12201 $ frame.AddrStack.Offset = ctx.Rbp; 12202 $ frame.AddrFrame.Offset = ctx.Rsp; 12203 } 12204 12205 #else 12206 12207 { 12208 $ cpu = IMAGE_FILE_MACHINE_I386; 12209 12210 $ frame.AddrPC .Offset = ctx.Eip; 12211 $ frame.AddrStack.Offset = ctx.Ebp; 12212 $ frame.AddrFrame.Offset = ctx.Esp; 12213 } 12214 12215 #endif 12216 12217 $ assert (cpu); 12218 12219 if (_txSetJmp()) 12220 { 12221 $ _txSymGetFromAddr ((void*) 1); //-V566 12222 } 12223 $ _txClearJmp(); 12224 12225 $ int frames = -1; 12226 12227 $ for (frames = -framesToSkip; frames < (int) szCapture; frames++) //-V202 //-V2530 12228 { 12229 $ DWORD64 prev = frame.AddrStack.Offset; 12230 12231 // Я злой и страшный серый walk. Я в поросятах знаю talk. 12232 12233 if (!_txSetJmp()) {$ break; } 12234 12235 #if defined (_GCC_VER) 12236 12237 if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL, 12238 MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; } 12239 #elif defined (_MSC_VER) 12240 12241 $ if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL, 12242 Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; } 12243 #else 12244 #error _GCC_VER / _MSC_VER not defined 12245 #endif 12246 if (frames < 0) {$ continue; } 12247 12248 $ void* addr = (void*) frame.AddrPC.Offset; 12249 12250 if (frame.AddrFrame.Offset == 0) {$ addr = 0; } // Bad frame 12251 if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; } // Strange frame 12252 12253 $ assert (0 <= frames && frames < (int) szCapture); //-V202 12254 12255 $ capture[frames] = addr; //-V108 12256 } 12257 12258 $ _txClearJmp(); 12259 12260 if (!thisThread) {$ ResumeThread (thread); } 12261 12262 $ return frames; 12263 } 12264 12265 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl 12266 12267 //----------------------------------------------------------------------------------------------------------------- 12268 12269 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/, 12270 Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/, 12271 const char** source /*= NULL*/, int context /*= 2*/) 12272 { 12273 $7 static HANDLE process = NULL; 12274 12275 #if defined (_GCC_VER) 12276 #define LIB_ Win32::MinGW 12277 12278 #elif defined (_MSC_VER) 12279 #define LIB_ Win32 12280 12281 #else 12282 #error _GCC_VER / _MSC_VER not defined 12283 #endif 12284 12285 $ if (!process && addr) 12286 { 12287 $ process = GetCurrentProcess(); 12288 12289 $ DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES | 12290 SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS; 12291 12292 $ _TX_CALL (LIB_::SymSetOptions, (options)); 12293 $ _TX_CALL (LIB_::SymInitialize, (process, NULL, true)); 12294 } 12295 12296 $ static DWORD64 mod = 0; 12297 12298 $ if (module) 12299 { 12300 $ static char sMod [MAX_PATH] = ""; 12301 $ memset (sMod, 0, sizeof (sMod)); 12302 12303 $ mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr)); 12304 12305 $ GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH); 12306 12307 $ char* ext = strrchr (sMod, '.'); 12308 if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); } 12309 12310 $ *module = sMod; 12311 } 12312 12313 $ static char buffer [_TX_BUFSIZE] = ""; 12314 $ static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer; //-V1032 12315 12316 $ if (symbol) 12317 { 12318 $ memset (buffer, 0, sizeof (buffer)); 12319 12320 $ sym->MaxNameLen = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1; 12321 $ sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO); 12322 $ unsigned long long ofs = 0; 12323 12324 $ _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym)); 12325 12326 if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; } 12327 12328 $ *symbol = sym; 12329 } 12330 12331 $ static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line) }; 12332 12333 $ if (line) 12334 { 12335 $ memset (&line64, 0, sizeof (line64)); 12336 12337 $ DWORD ofs = 0; 12338 $ _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64)); 12339 12340 $ *line = &line64; 12341 } 12342 12343 $ if (source) 12344 { 12345 $ static char buf [_TX_BUFSIZE] = ""; 12346 $ memset (buf, 0, sizeof (buf)); 12347 12348 $ if (line64.FileName && line64.LineNumber) 12349 { 12350 $ _txReadSource (buf, sizeof (buf) - 1, line64.FileName, 12351 (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber); 12352 12353 $ *source = buf; 12354 } 12355 12356 if (!*source || !**source) {$ *source = NULL; } 12357 } 12358 12359 $ if (!addr && process) 12360 { 12361 $ _TX_CALL (LIB_::SymCleanup, (process)); 12362 12363 $ process = NULL; 12364 } 12365 12366 #if (_GCC_VER == 481) 12367 #pragma GCC diagnostic push 12368 #pragma GCC system_header 12369 #endif 12370 12371 $ if (symbol) 12372 { 12373 $ if (strstr (sym->Name, "::TX::") || 12374 (strncmp (sym->Name, "_tx", 3) == 0 && isupper ((unsigned char) sym->Name[3])) || 12375 (strncmp (sym->Name, "tx", 2) == 0 && isupper ((unsigned char) sym->Name[2])) || 12376 strncmp (sym->Name, "_tx_", 4) == 0 || //-V112 12377 strncmp (sym->Name, "tx_", 3) == 0) 12378 { 12379 $ return true; 12380 } 12381 12382 #if (_GCC_VER == 481) 12383 #pragma GCC diagnostic pop 12384 #endif 12385 12386 $ if (!line || !line64.FileName) return false; 12387 12388 $ intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1); 12389 12390 $ return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) && 12391 (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\'); 12392 } 12393 12394 #undef LIB_ 12395 12396 $ return false; 12397 } 12398 12399 //----------------------------------------------------------------------------------------------------------------- 12400 12401 intptr_t _txReadSource (char buf[], intptr_t size, const char file[], 12402 int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/) 12403 { 12404 $7 assert (buf); 12405 12406 if (!file || !*file) {$ return 0; } 12407 12408 if (linStart < 1) {$ linStart = 1; } 12409 if (linEnd == -1) {$ linEnd = INT_MAX; } 12410 12411 $ FILE* f = NULL; 12412 $ fopen_s (&f, file, "r"); 12413 if (!f) {$ return 0; } 12414 12415 $ int n = 1; 12416 while (!feof (f)) 12417 { 12418 if (n >= linStart) {$ break; } 12419 while (!feof (f) && fgetc (f) != '\n') 12420 ; 12421 n++; 12422 } 12423 12424 $ char* s = buf; 12425 12426 #define SZ_ ( size - 3 - (s - buf) ) 12427 12428 $ while (!feof (f) && SZ_ > 0) 12429 { 12430 if (n > linEnd || _txNOP (SZ_) < 0) {$ break; } 12431 12432 if (linMark != INT_MIN) 12433 {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : " "), n); } 12434 12435 $ int c = 0; 12436 $ while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c; 12437 if (c == EOF) {$ s--; } 12438 12439 if (SZ_ > 0) {$ *s++ = '\n'; } 12440 $ n++; 12441 } 12442 12443 if (n <= linEnd && SZ_ <= 0) 12444 {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); } 12445 12446 #undef SZ_ 12447 12448 $ fclose (f); 12449 12450 if (s > buf && s[-1] == '\n') {$ s--; } 12451 $ *s = 0; 12452 12453 $ return (s - buf); 12454 } 12455 12456 //----------------------------------------------------------------------------------------------------------------- 12457 12458 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/) 12459 { 12460 $6 const int maxFrames = 62; // TX says too: < 63 12461 $ static char trace [(MAX_PATH + 1024+1) * maxFrames] = ""; 12462 12463 if (framesToSkip == -1) {$ return trace; } 12464 12465 $ memset (trace, 0, sizeof (trace)); 12466 $ char* s = trace; 12467 12468 #define SZ_ ( sizeof (trace) - 1 - 3 - (s-trace) ) 12469 12470 $ const _txLoc* loc = &_txLoc::Cur; 12471 12472 for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; } 12473 12474 $ for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev) 12475 { 12476 if (i < 0) {$ continue; } 12477 12478 if (loc->func || loc->file || loc->line) 12479 { 12480 $ s += _tx_snprintf_s (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""), 12481 i, loc->func, loc->file, loc->line); 12482 12483 $ if (readSource) 12484 { 12485 $ s += _tx_snprintf_s (s, SZ_, ":\n\n"); 12486 $ s += _txReadSource (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line); 12487 } 12488 } 12489 } 12490 12491 #undef SZ_ 12492 12493 $ s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), ""); 12494 12495 $ return trace; 12496 } 12497 12498 //----------------------------------------------------------------------------------------------------------------- 12499 12500 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/) 12501 { 12502 #if !defined (_TX_NO_MINIDUMP) 12503 12504 $6 static char dumpName[MAX_PATH] = ""; 12505 if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); } 12506 12507 $ HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 12508 12509 if (!file || file == INVALID_HANDLE_VALUE) {$ return false; } 12510 12511 $ Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false }; 12512 $ Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory); 12513 12514 $ bool ok = _TX_CALL (Win32::MiniDumpWriteDump, (GetCurrentProcess(), GetCurrentProcessId(), file, type, ((exc)? &excInfo : NULL), NULL, NULL)); 12515 if (!ok) {$ ok = _TX_CALL (Win32::MiniDumpWriteDump2, (GetCurrentProcess(), GetCurrentProcessId(), file, type, ((exc)? &excInfo : NULL), NULL, NULL)); } 12516 if (!ok) {$ ok = _TX_CALL (Win32::MiniDumpWriteDump3, (GetCurrentProcess(), GetCurrentProcessId(), file, type, ((exc)? &excInfo : NULL), NULL, NULL)); } 12517 12518 $ CloseHandle (file); 12519 12520 if (ok) {$ return true; } 12521 else {$ return false; } 12522 12523 #else 12524 12525 return (!!exc); 12526 12527 #endif 12528 } 12529 12530 #endif // TX_COMPILED 12531 12532 //} 12533 //----------------------------------------------------------------------------------------------------------------- 12534 12535 //----------------------------------------------------------------------------------------------------------------- 12536 //{ Errors reporting 12537 //----------------------------------------------------------------------------------------------------------------- 12538 12539 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 12540 12541 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args) //-V2008 12542 { 12543 _txErrors = _txErrors + 1; 12544 12545 DWORD winErr = GetLastError(); 12546 12547 int crtErr = errno; 12548 12549 #if !defined (__CYGWIN__) 12550 unsigned long dosErr = _doserrno; 12551 #else 12552 unsigned long dosErr = 0; 12553 #endif 12554 12555 unsigned dlgErr = _TX_CALL (Win32::CommDlgExtendedError, ()); 12556 12557 unsigned oglErr = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError; 12558 12559 unsigned threadId = GetCurrentThreadId(); 12560 12561 enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 }; 12562 unsigned options = 0; 12563 12564 for (; msg && *msg; msg++) 12565 { 12566 if (*msg == '\a') options |= isFatal; 12567 else if (*msg == '\v') options |= isWarning; 12568 else if (*msg == '\b') options |= noMsgBox; 12569 else if (*msg == '\f') options |= fmtOnly; 12570 else if (*msg == '\t') options |= traceSE; 12571 else break; 12572 } 12573 12574 const char* stkTrace = NULL; 12575 const char* txTrace = NULL; (void) txTrace; 12576 12577 if (!(options & fmtOnly)) 12578 { 12579 stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace (2, true); 12580 txTrace = _txCaptureStackBackTraceTX (0, true); 12581 } 12582 12583 static char what[_TX_BIGBUFSIZE*10] = ""; 12584 static char str [_TX_BIGBUFSIZE] = ""; 12585 char *s = what; 12586 12587 #define PRINT_(...) s += _tx_snprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__) 12588 #define VPRINT_(...) s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__) 12589 12590 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" : 12591 (options & isFatal)? "соболезнует..." : 12592 "сообщает:")); 12593 PRINT_ ("Программа: %s", txGetModuleFileName()); 12594 if (file) PRINT_ (", файл: %s", file); 12595 if (line) PRINT_ (", строка: %d", line); 12596 if (func) PRINT_ (", функция: %s", func); 12597 PRINT_ (",\n\n"); 12598 12599 if (msg) PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"), 12600 VPRINT_ (msg, args); 12601 12602 while (s > what && s[-1] == '\n') s--; 12603 12604 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s", 12605 12606 _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64, 12607 12608 "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace, 12609 12610 threadId, (threadId == _txMainThreadId)? " (Main)" : 12611 (threadId == _txCanvas_ThreadId)? " (Canvas)" : ""); 12612 12613 if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr), 12614 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 12615 NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 12616 s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2, //-V202 12617 s -= (s[-1] == '.')? 1 : 0, 12618 PRINT_ (")"); 12619 12620 if (crtErr) PRINT_ (", errno: %d (%s)", crtErr, (strerror_s (str, sizeof (str), crtErr), str)); 12621 if (dosErr) PRINT_ (", _doserrno: %lu (%s)", dosErr, (strerror_s (str, sizeof (str), dosErr), str)); 12622 if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)", oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr))); 12623 if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr); 12624 12625 #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L) 12626 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : ""); 12627 #else 12628 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true." : ""); 12629 #endif 12630 12631 if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) && 12632 (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func)) 12633 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func); 12634 12635 txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what); 12636 12637 if (options & fmtOnly) 12638 { 12639 SetLastError (winErr); 12640 12641 errno = crtErr; 12642 12643 #if !defined (__CYGWIN__) 12644 _doserrno = dosErr; 12645 #endif 12646 12647 return what; 12648 } 12649 12650 txSetProgress (-1, Win32::TBPF_ERROR); 12651 12652 unsigned restore = txGetConsoleAttr(); 12653 txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED); 12654 if (color) {$ txSetConsoleAttr (color); } 12655 12656 int oldCodePage = txSetLocale(); 12657 12658 fprintf (stderr, "\n" "--------------------------------------------------\n" 12659 "%s\n" 12660 "--------------------------------------------------\n", 12661 what); 12662 12663 if (stkTrace && strstr (stkTrace, ".exe: ")) 12664 {$ fprintf (stderr, "Стек вызовов:\n\n" 12665 "%s\n\n" 12666 "--------------------------------------------------\n", 12667 stkTrace); } 12668 12669 SetConsoleOutputCP (oldCodePage); 12670 txSetConsoleAttr (restore); 12671 12672 if (*_txLogName) do //-V2530 12673 { 12674 FILE* log = NULL; fopen_s (&log, _txLogName, "a"); 12675 if (!log) {$ break; } 12676 12677 fprintf (log, "\n" "--------------------------------------------------\n" 12678 "%s\n" 12679 "--------------------------------------------------\n", 12680 what); 12681 12682 fprintf (log, "Стек вызовов:\n\n" //-V576 12683 "%s\n", 12684 (*_txTraceSE)? _txTraceSE : stkTrace); 12685 12686 #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG) 12687 12688 if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace) 12689 { 12690 fprintf (log, "\n" "--------------------------------------------------\n" 12691 "Стек вызовов TX:\n\n" 12692 "%s\n", 12693 txTrace); 12694 } 12695 12696 #endif 12697 12698 fprintf (log, "\n" "--------------------------------------------------\n" 12699 "%s\n\n" 12700 "--------------------------------------------------\n", 12701 _txAppInfo()); 12702 fclose (log); 12703 break; 12704 } 12705 while (false); 12706 12707 txSleep(); 12708 12709 int ret = 0; 12710 12711 if (!(options & noMsgBox)) 12712 { 12713 txSleep (_txWindowUpdateInterval); 12714 12715 PRINT_ ("\n" "Прервать программу?"); 12716 12717 ret = txMessageBox (what, ((options & isWarning)? "Предупреждение" : 12718 (options & isFatal)? "Фатальная ошибка" : 12719 "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL); 12720 } 12721 12722 SetLastError (winErr); 12723 12724 errno = crtErr; 12725 12726 #if !defined (__CYGWIN__) 12727 _doserrno = dosErr; 12728 #endif 12729 12730 if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES) 12731 { 12732 txUnlock(); 12733 _txCleanup(); 12734 Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 12735 } 12736 12737 #undef PRINT_ 12738 #undef VPRINT_ 12739 12740 return what; 12741 } 12742 12743 //----------------------------------------------------------------------------------------------------------------- 12744 12745 #if defined (_MSC_VER) 12746 12747 int _txOnErrorReport (int type, const char* text, int* ret) 12748 { 12749 assert (text); 12750 assert (ret); 12751 12752 _txErrors = _txErrors + 1; 12753 12754 unsigned restore = txGetConsoleAttr(); 12755 12756 switch (type) 12757 { 12758 case _CRT_WARN: txSetConsoleAttr (FOREGROUND_LIGHTRED); break; 12759 case _CRT_ERROR: txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break; 12760 case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW); break; 12761 default: break; //-V2522 12762 } 12763 12764 const char startReport[] = "Detected memory leaks!\n", 12765 endReport[] = "Object dump complete.\n"; 12766 12767 if (strcmp (text, startReport) == 0) // Dirty, dirty hack. А что делать? 12768 { 12769 _txOnErrorReport (type, "\n", NULL); 12770 _txOnErrorReport (type, _TX_VERSION " - ERROR: ", NULL); 12771 _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL); 12772 _txOnErrorReport (type, "\n", NULL); 12773 } 12774 12775 size_t len = strlen (text); 12776 if (text [len-1] != '\n') txOutputDebugPrintf ("%s", text); 12777 else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION); 12778 else txOutputDebugPrintf ("%s\n", text); 12779 12780 DWORD n = 0; 12781 HANDLE err = GetStdHandle (STD_ERROR_HANDLE); 12782 WriteFile (err, text, (DWORD) strlen (text), &n, NULL); //-V202 12783 12784 txSetConsoleAttr (restore); 12785 12786 if (*_txLogName) do //-V2530 12787 { 12788 HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 12789 if (log == INVALID_HANDLE_VALUE) break; 12790 12791 SetFilePointer (log, 0, NULL, FILE_END); 12792 WriteFile (log, text, (DWORD) strlen (text), &n, NULL); //-V202 12793 12794 CloseHandle (log); 12795 break; 12796 } 12797 while (false); 12798 12799 if (ret) *ret = 0; 12800 12801 return (type == _CRT_WARN); 12802 } 12803 12804 #endif 12805 12806 //----------------------------------------------------------------------------------------------------------------- 12807 12808 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/) 12809 { 12810 $5 static wchar_t textW [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]"; 12811 $ static wchar_t headerW [_TX_BUFSIZE * sizeof (wchar_t)] = L"[NULL header]"; 12812 12813 if (text) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text, -1, textW, sizearr (textW)) || memset (textW, 0, sizeof (textW)); } 12814 if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); } 12815 12816 $ txSleep(); 12817 12818 $ HWND wnd = _txCanvas_Window; 12819 $ int ret = MessageBoxW ((wnd && IsWindowVisible (wnd))? wnd : _TX_CALL (Win32::GetConsoleWindow,()), 12820 textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST); 12821 12822 $ GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU); 12823 12824 $ if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU)) 12825 { 12826 $ SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0); 12827 $ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT); 12828 } 12829 12830 $ return ret; 12831 } 12832 12833 //----------------------------------------------------------------------------------------------------------------- 12834 12835 bool txGetAsyncKeyState (int key) 12836 { 12837 $1 HWND wnd = GetForegroundWindow(); 12838 12839 return (GetAsyncKeyState (key) & 0x8000) && 12840 (wnd == txWindow() || wnd == Win32::GetConsoleWindow()); 12841 } 12842 12843 //----------------------------------------------------------------------------------------------------------------- 12844 12845 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...) 12846 { 12847 $5 if (_TX_ARGUMENT_FAILED (format)) return false; 12848 12849 $ va_list arg; va_start (arg, format); 12850 $ bool ok = true; 12851 12852 #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500) 12853 12854 $ NOTIFYICONDATA nid = { sizeof (nid) }; 12855 12856 $ nid.uFlags = NIF_ICON | NIF_TIP | NIF_INFO; 12857 $ nid.hWnd = NULL; 12858 $ nid.uID = 1; 12859 $ nid.hIcon = _txCreateTXIcon (16); assert (nid.hIcon); 12860 $ strncpy_s (nid.szTip, sizeof (nid.szTip), "TXLib Information", sizeof (nid.szTip)); 12861 $ strncpy_s (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1); 12862 $ _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg); 12863 $ nid.dwInfoFlags = flags; 12864 12865 $ txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo); 12866 12867 $ ok &= !!Shell_NotifyIcon (NIM_ADD, (::NOTIFYICONDATA*) &nid); 12868 $ ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid); 12869 12870 $ if (nid.hIcon) DestroyIcon (nid.hIcon) asserted; 12871 12872 #else 12873 12874 $ char nid_szInfo[_TX_BUFSIZE] = ""; 12875 $ _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg); 12876 $ txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo); 12877 $ ok = false; 12878 12879 $ (void)flags; (void)title; 12880 12881 #endif 12882 12883 $ va_end (arg); 12884 return ok; 12885 } 12886 12887 //----------------------------------------------------------------------------------------------------------------- 12888 12889 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...) 12890 { 12891 unsigned id = GetCurrentThreadId(); 12892 12893 const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}}; 12894 12895 char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)]; 12896 12897 char msgStr[_TX_BUFSIZE] = ""; 12898 if (msg) 12899 { 12900 va_list arg; va_start (arg, msg); 12901 _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg); 12902 va_end (arg); 12903 } 12904 12905 txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d) " "|%*s%s" "%s%s\n", 12906 12907 _TX_VERSION, (void*) &_txInitialized, 12908 12909 "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], 12910 _txLoc::Cur.trace, mark, 12911 12912 (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line, 12913 2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""), 12914 12915 ((*msgStr && func)? ": " : ""), msgStr); 12916 } 12917 12918 //----------------------------------------------------------------------------------------------------------------- 12919 12920 int txOutputDebugPrintf (const char* format, ...) 12921 { 12922 if (!format) return 0; 12923 12924 enum { msgbox = 1, print = 2, compr = 4 }; 12925 int options = 0; 12926 12927 for (; format && *format; format++) 12928 { 12929 if (*format == '\a') options |= msgbox; 12930 else if (*format == '\f') options |= print; 12931 else if (*format == '\r') options |= compr; 12932 else break; 12933 } 12934 12935 char text[_TX_BIGBUFSIZE] = ""; 12936 12937 va_list arg; va_start (arg, format); 12938 int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg); //-V202 12939 va_end (arg); 12940 12941 struct __ { static int trimSpaces (char str[]) 12942 { 12943 char *dst = str, *src = str; 12944 12945 for (char d = ' '; d; src++) 12946 if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; } 12947 else *dst++ = d = *src; 12948 12949 return (int) (dst - str - 1); //-V202 12950 }}; 12951 12952 if (options & compr) n = __::trimSpaces (text); 12953 12954 OutputDebugString (text); 12955 12956 if (options & print) fprintf (stderr, "%s", text); 12957 12958 if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION); 12959 12960 return n; 12961 } 12962 12963 //----------------------------------------------------------------------------------------------------------------- 12964 12965 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...) 12966 { 12967 if (!format) return 0; 12968 12969 va_list arg; va_start (arg, format); 12970 intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg); 12971 va_end (arg); 12972 12973 return ret; 12974 } 12975 12976 //----------------------------------------------------------------------------------------------------------------- 12977 12978 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg) 12979 { 12980 if (!stream || !format) return 0; 12981 12982 #if defined (_TRUNCATE) 12983 intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg); 12984 #else 12985 intptr_t ret = _vsnprintf (stream, size, format, arg); 12986 #endif 12987 12988 if (ret < 0 && size >= 4) //-V112 12989 { 12990 const char ellipsis[] = "..."; 12991 size_t szEllipsis = sizeof (ellipsis) - 1; 12992 12993 strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis); 12994 } 12995 12996 return (ret >= 0)? ret : size; 12997 } 12998 12999 //----------------------------------------------------------------------------------------------------------------- 13000 13001 #if defined (__CYGWIN__) 13002 13003 int _getch() 13004 { 13005 termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr); 13006 13007 termios newattr = oldattr; 13008 newattr.c_lflag &= ~(ICANON | ECHO); 13009 tcsetattr (STDIN_FILENO, TCSANOW, &newattr); 13010 13011 int ch = getchar(); 13012 13013 tcsetattr (STDIN_FILENO, TCSANOW, &oldattr); 13014 13015 return ch; 13016 } 13017 13018 //----------------------------------------------------------------------------------------------------------------- 13019 13020 int _putch (int ch) 13021 { 13022 termios old = {}; tcgetattr (STDOUT_FILENO, &old); 13023 13024 termios cur = old; 13025 cur.c_lflag &= ~ICANON; 13026 cur.c_lflag |= ECHO; 13027 tcsetattr (STDOUT_FILENO, TCSANOW, &cur); 13028 13029 putchar (ch); 13030 13031 tcsetattr (STDOUT_FILENO, TCSANOW, &old); 13032 13033 return ch; 13034 } 13035 13036 //----------------------------------------------------------------------------------------------------------------- 13037 13038 int _kbhit() 13039 { 13040 termios old = {}; tcgetattr (STDIN_FILENO, &old); 13041 13042 termios cur = old; 13043 cur.c_lflag &= ~(ICANON | ECHO); 13044 cur.c_cc[VMIN] = 1; 13045 cur.c_cc[VTIME] = 0; 13046 13047 tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur); 13048 13049 fd_set fd = {}; FD_SET (STDIN_FILENO, &fd); 13050 timeval tv = {}; 13051 13052 int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd); 13053 13054 tcsetattr (STDIN_FILENO, TCSAFLUSH, &old); 13055 13056 return res; 13057 } 13058 13059 #endif 13060 13061 #endif // TX_COMPILED 13062 13063 //} 13064 //----------------------------------------------------------------------------------------------------------------- 13065 13066 //----------------------------------------------------------------------------------------------------------------- 13067 //{ Information 13068 //----------------------------------------------------------------------------------------------------------------- 13069 13070 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 13071 13072 const char* txGetModuleFileName (bool fileNameOnly /*= true*/) 13073 { 13074 static char name[MAX_PATH] = ""; 13075 13076 if (!*name) 13077 { 13078 if (!GetModuleFileName (NULL, name, sizeof (name) - 1)) *name = 0; 13079 13080 char* ext = strrchr (name, '.'); 13081 if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name)); 13082 } 13083 13084 assert (*name); 13085 13086 if (fileNameOnly) return name; 13087 13088 static char fullName[MAX_PATH] = ""; 13089 strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1); 13090 13091 char* title = strrchr (fullName, '\\'); if (!title) title = fullName; 13092 char* ext = strrchr (fullName, '.'); if (!ext) ext = fullName + strlen (fullName); 13093 13094 size_t sz = sizeof (fullName) - (ext - fullName); 13095 strncpy_s (ext, sz-1, " - TXLib", sz); 13096 13097 return title + 1; 13098 } 13099 13100 #endif // TX_COMPILED 13101 13102 //----------------------------------------------------------------------------------------------------------------- 13103 13104 inline const char* _txAppInfo() 13105 { 13106 $1 time_t timeT = time (NULL) - clock()/CLOCKS_PER_SEC; //-V104 13107 char timeS[32] = ""; 13108 ctime_s (timeS, sizeof (timeS), &timeT); 13109 13110 static char text[_TX_BUFSIZE] = ""; 13111 char cwd [MAX_PATH] = ""; 13112 13113 _tx_snprintf_s (text, sizeof (text) - 1, 13114 13115 "Developed with:\n\n" 13116 "The Dumb Artist Library (TX Library)\n" 13117 _TX_VERSION "\n" _TX_AUTHOR "\n" 13118 "See license on: http://txlib.ru\n\n" 13119 13120 "TXLib file:" "\t" __FILE__ "\n" 13121 "Compiled:" "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n" 13122 "Started:" "\t" "%.6s %.4s %.8s\n\n" 13123 13124 "Run file:" "\t" "%s\n" 13125 "Directory:" "\t" "%s", 13126 13127 #if defined (_MSC_VER) 13128 "MSVC Runtime", 13129 #elif defined (__CYGWIN__) 13130 "Cygwin Runtime", 13131 #elif defined (_GCC_VER) && defined (_WIN64) 13132 __mingw_get_crt_info(), 13133 #else 13134 "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION), 13135 #endif 13136 (sizeof (void*) == sizeof (DWORD))? 32 : 64, //-V112 13137 13138 timeS + 4, timeS + 20, timeS + 11, //-V112 These offsets are ANSI standardized 13139 txGetModuleFileName(), 13140 _getcwd (cwd, sizeof (cwd) - 1)); 13141 13142 return text; 13143 } 13144 13145 //} 13146 //----------------------------------------------------------------------------------------------------------------- 13147 13149 //} 13150 //================================================================================================================= 13151 13152 //================================================================================================================= 13153 //{ TXLib API implementation 13154 // Реализация TXLib API 13155 //================================================================================================================= 13156 13157 inline const char* txVersion() 13158 { 13159 return _TX_VERSION; 13160 } 13161 13162 //----------------------------------------------------------------------------------------------------------------- 13163 13164 inline unsigned txVersionNumber() 13165 { 13166 return _TX_VER; //-V2517 13167 } 13168 13169 //----------------------------------------------------------------------------------------------------------------- 13170 13171 inline HWND txWindow() 13172 { 13173 $9 return _txCanvas_Window; 13174 } 13175 13176 //----------------------------------------------------------------------------------------------------------------- 13177 13178 inline HDC& txDC() 13179 { 13180 return _txCanvas_BackBuf[0]; 13181 } 13182 13183 //----------------------------------------------------------------------------------------------------------------- 13184 13185 inline RGBQUAD* txVideoMemory() 13186 { 13187 return _txCanvas_Pixels; 13188 } 13189 13190 //----------------------------------------------------------------------------------------------------------------- 13191 13192 inline int txGetExtentX (HDC dc /*= txDC()*/) 13193 { 13194 return txGetExtent (dc) .x; 13195 } 13196 13197 //----------------------------------------------------------------------------------------------------------------- 13198 13199 inline int txGetExtentY (HDC dc /*= txDC()*/) 13200 { 13201 return txGetExtent (dc) .y; 13202 } 13203 13204 //----------------------------------------------------------------------------------------------------------------- 13205 13206 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 13207 13208 POINT txGetExtent (HDC dc /*= txDC()*/) 13209 { 13210 $0 static POINT err = {-1, -1}; 13211 13212 if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; }; 13213 13214 if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; } 13215 13216 $ BITMAP bmap = {}; 13217 $ txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted; 13218 13219 $ POINT size = { bmap.bmWidth, bmap.bmHeight }; 13220 $ return size; 13221 } 13222 13223 //----------------------------------------------------------------------------------------------------------------- 13224 13225 bool txDestroyWindow (HWND wnd /*= txWindow()*/) 13226 { 13227 $1 if (!wnd || !txWindow()) return false; 13228 13229 $ if (wnd != txWindow()) 13230 { 13231 $ return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd); 13232 } 13233 13234 $ if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false; 13235 13236 $ if (_txMain) 13237 { 13238 $ txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n" 13239 "Возвращайтесь через main(), там вам будут рады.\n"); 13240 $ Sleep (_TX_TIMEOUT); 13241 } 13242 13243 $ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT); 13244 13245 $ return _txCanvas_Window == NULL; 13246 } 13247 13248 //----------------------------------------------------------------------------------------------------------------- 13249 13250 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/) 13251 { 13252 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13253 13254 $ HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color); 13255 13256 $ if (!pen) return (HPEN) NULL; 13257 13258 $ if (!_txBuffer_Select (pen, dc)) 13259 { 13260 $ Win32::DeleteObject (pen); 13261 $ return (HPEN) NULL; 13262 } 13263 13264 $ if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID) 13265 {$ return (HPEN) NULL; } 13266 13267 $ return pen; 13268 } 13269 13270 //----------------------------------------------------------------------------------------------------------------- 13271 13272 COLORREF txColor (double red, double green, double blue) 13273 { 13274 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13275 $ if (green > 1) green = 1; if (green < 0) green = 0; 13276 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13277 13278 $ COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)); 13279 13280 $ return txSetColor (color)? color : CLR_INVALID; 13281 } 13282 13283 //----------------------------------------------------------------------------------------------------------------- 13284 13285 COLORREF txGetColor (HDC dc /*= txDC()*/) 13286 { 13287 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13288 13289 $ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc); 13290 $ assert (obj); if (!obj) return CLR_INVALID; //-V547 13291 13292 $ union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {}; //-V2514 13293 13294 $ int size = Win32::GetObject (obj, 0, NULL); 13295 $ Win32::GetObject (obj, sizeof (buf), &buf) asserted; 13296 13297 $ return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor; 13298 } 13299 13300 //----------------------------------------------------------------------------------------------------------------- 13301 13302 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/) 13303 { 13304 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13305 13306 $ HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color); 13307 13308 $ return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL); 13309 } 13310 13311 //----------------------------------------------------------------------------------------------------------------- 13312 13313 COLORREF txFillColor (double red, double green, double blue) 13314 { 13315 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13316 $ if (green > 1) green = 1; if (green < 0) green = 0; 13317 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13318 13319 $ COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)); 13320 13321 $ return txSetFillColor (color)? color : CLR_INVALID; 13322 } 13323 13324 //----------------------------------------------------------------------------------------------------------------- 13325 13326 COLORREF txGetFillColor (HDC dc /*= txDC()*/) 13327 { 13328 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13329 13330 $ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc); 13331 $ assert (obj); if (!obj) return CLR_INVALID; //-V547 13332 13333 $ LOGBRUSH buf = {}; 13334 $ txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted; 13335 13336 $ return buf.lbColor; 13337 } 13338 13339 //----------------------------------------------------------------------------------------------------------------- 13340 13341 bool txClear (HDC dc /*= txDC()*/) 13342 { 13343 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13344 13345 $ POINT size = txGetExtent (dc); 13346 $ return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc); 13347 } 13348 13349 //----------------------------------------------------------------------------------------------------------------- 13350 13351 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/) 13352 { 13353 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13354 13355 $ txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc); 13356 13357 $ return true; 13358 } 13359 13360 //----------------------------------------------------------------------------------------------------------------- 13361 13362 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/) 13363 { 13364 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13365 $ if (green > 1) green = 1; if (green < 0) green = 0; 13366 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13367 13368 $ return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc); 13369 } 13370 13371 //----------------------------------------------------------------------------------------------------------------- 13372 13373 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/) 13374 { 13375 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13376 13377 $ return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc); 13378 } 13379 13380 //----------------------------------------------------------------------------------------------------------------- 13381 13382 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13383 { 13384 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13385 13386 $ bool ok = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc); 13387 $ ok &= txGDI ((Win32::LineTo (dc, ROUND (x1), ROUND (y1) )), dc); 13388 13389 $ return ok; 13390 } 13391 13392 //----------------------------------------------------------------------------------------------------------------- 13393 13394 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13395 { 13396 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13397 13398 $ return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc); 13399 } 13400 13401 //----------------------------------------------------------------------------------------------------------------- 13402 13403 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/) 13404 { 13405 $1 if (_TX_ARGUMENT_FAILED (points)) return false; 13406 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13407 13408 $ return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc); 13409 } 13410 13411 //----------------------------------------------------------------------------------------------------------------- 13412 13413 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13414 { 13415 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13416 13417 $ return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc); 13418 } 13419 13420 //----------------------------------------------------------------------------------------------------------------- 13421 13422 bool txCircle (double x, double y, double r) 13423 { 13424 $1 return txEllipse (x-r, y-r, x+r, y+r); 13425 } 13426 13427 //----------------------------------------------------------------------------------------------------------------- 13428 13429 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13430 { 13431 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13432 13433 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13434 13435 $ double start = startAngle * txPI/180, 13436 end = (startAngle + totalAngle) * txPI/180; 13437 13438 $ return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13439 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13440 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13441 } 13442 13443 //----------------------------------------------------------------------------------------------------------------- 13444 13445 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13446 { 13447 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13448 13449 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13450 13451 $ double start = startAngle * txPI/180, 13452 end = (startAngle + totalAngle) * txPI/180; 13453 13454 $ return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13455 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13456 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13457 } 13458 13459 //----------------------------------------------------------------------------------------------------------------- 13460 13461 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13462 { 13463 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13464 13465 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13466 13467 $ double start = startAngle * txPI/180, 13468 end = (startAngle + totalAngle) * txPI/180; 13469 13470 $ return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13471 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13472 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13473 } 13474 13475 //----------------------------------------------------------------------------------------------------------------- 13476 13477 bool txFloodFill (double x, double y, 13478 COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/) 13479 { 13480 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13481 13482 $ if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc); 13483 13484 $ return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc); 13485 } 13486 13487 //----------------------------------------------------------------------------------------------------------------- 13488 13489 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/) 13490 { 13491 $1 if (_TX_ARGUMENT_FAILED (text)) return false; 13492 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13493 13494 $ int len = (int) strlen (text); //-V202 13495 $ bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc); 13496 13497 $ return ok; 13498 } 13499 13500 //----------------------------------------------------------------------------------------------------------------- 13501 13502 bool txDrawText (double x0, double y0, double x1, double y1, const char text[], 13503 unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/, 13504 HDC dc /*= txDC()*/) 13505 { 13506 $1 if (_TX_ARGUMENT_FAILED (text)) return false; 13507 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13508 13509 #if !defined (NDEBUG) 13510 13511 $ if (x0 > x1) 13512 { 13513 $ SetLastError (ERROR_INVALID_DATA); 13514 $ TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1); 13515 } 13516 13517 $ if (y0 > y1) 13518 { 13519 $ SetLastError (ERROR_INVALID_DATA); 13520 $ TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1); 13521 } 13522 13523 #endif 13524 13525 $ RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) }; 13526 13527 $ if (!strchr (text, '\n')) format |= DT_SINGLELINE; 13528 13529 $ unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc); 13530 13531 $ bool ok = false; 13532 13533 $ if (Win32::DrawText) 13534 { 13535 $ ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc); 13536 $ Win32::GetPixel (dc, 0, 0); 13537 $ ok = true; //-V519 13538 } 13539 else 13540 { 13541 $ txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text); 13542 $ ok = false; 13543 } 13544 13545 $ txSetTextAlign (prev, dc); 13546 13547 $ return ok; 13548 } 13549 13550 //----------------------------------------------------------------------------------------------------------------- 13551 13552 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/, 13553 int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/, 13554 bool strikeout /*= false*/, double angle /*= 0*/, 13555 HDC dc /*= txDC()*/) 13556 { 13557 $1 if (_TX_ARGUMENT_FAILED (name)) return NULL; 13558 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13559 13560 $ HFONT font = txFontExist (name)? 13561 Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3), 13562 ROUND (angle*10), 0, bold, italic, underline, strikeout, 13563 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 13564 DEFAULT_QUALITY, DEFAULT_PITCH, name) 13565 : 13566 (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT); 13567 13568 $ _txBuffer_Select (font, dc); 13569 13570 $ return font; 13571 } 13572 13573 //----------------------------------------------------------------------------------------------------------------- 13574 13575 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/) 13576 { 13577 $1 SIZE size = {-1, -1}; 13578 13579 $ if (_TX_ARGUMENT_FAILED (text)) return size; 13580 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return size; 13581 13582 $ size_t len = strlen (text); 13583 $ txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted; //-V202 13584 13585 $ return size; 13586 } 13587 13588 //----------------------------------------------------------------------------------------------------------------- 13589 13590 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/) 13591 { 13592 $1 return txGetTextExtent (text, dc) .cx; 13593 } 13594 13595 //----------------------------------------------------------------------------------------------------------------- 13596 13597 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/) 13598 { 13599 $1 return txGetTextExtent (text, dc) .cy; 13600 } 13601 13602 //----------------------------------------------------------------------------------------------------------------- 13603 13604 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/) 13605 { 13606 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; //-V601 13607 13608 $ return txGDI ((Win32::SetTextAlign (dc, align)), dc); 13609 } 13610 13611 //----------------------------------------------------------------------------------------------------------------- 13612 13613 LOGFONT* txFontExist (const char name[]) 13614 { 13615 $1 if (_TX_ARGUMENT_FAILED (name)) return NULL; 13616 13617 $ static LOGFONT font = {}; 13618 $ font.lfCharSet = DEFAULT_CHARSET; 13619 $ strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1); 13620 13621 $ struct tools 13622 { 13623 static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data) 13624 { 13625 $ if (_TX_ARGUMENT_FAILED (fnt)) return 0; 13626 $ if (_TX_ARGUMENT_FAILED (data)) return 0; 13627 13628 #ifndef __STRICT_ANSI__ 13629 $ return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE); 13630 13631 #else 13632 $ return strncmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE); 13633 13634 #endif 13635 } 13636 }; 13637 13638 $ return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL; 13639 } 13640 13641 //----------------------------------------------------------------------------------------------------------------- 13642 13643 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/) 13644 { 13645 $1 if (_TX_ARGUMENT_FAILED (obj)) return false; 13646 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13647 13648 $ return _txBuffer_Select (obj, dc); 13649 } 13650 13651 //----------------------------------------------------------------------------------------------------------------- 13652 13653 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/) 13654 { 13655 $1 POINT size = { ROUND (sizeX), ROUND (sizeY) }; 13656 13657 $ HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels); 13658 $ assert (dc); if (!dc) return NULL; //-V547 13659 13660 $ txSetDefaults (dc); 13661 13662 $ if (!_txCanvas_UserDCs) return dc; 13663 13664 $ txAutoLock _lock; 13665 $ _txCanvas_UserDCs->push_back (dc); 13666 13667 $ if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE) 13668 {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); } //-V202 13669 13670 $ return dc; 13671 } 13672 13673 //----------------------------------------------------------------------------------------------------------------- 13674 13675 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/) 13676 { 13677 $1 return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels); 13678 } 13679 13680 //----------------------------------------------------------------------------------------------------------------- 13681 13682 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) 13683 { 13684 $1 return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels); 13685 } 13686 13687 //----------------------------------------------------------------------------------------------------------------- 13688 13689 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/, 13690 unsigned imageType /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/) 13691 { 13692 $1 if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL; 13693 13694 $ HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL), 13695 filename, imageType, sizeX, sizeY, loadFlags | LR_CREATEDIBSECTION); 13696 $ if (!image) return NULL; 13697 13698 $ HDC dc = txCreateCompatibleDC (sizeX, sizeY, image); 13699 13700 $ if (!(loadFlags & LR_LOADFROMFILE)) return dc; 13701 13702 $ static std::map <std::string, unsigned> loadTimes; 13703 $ std::string file = filename; 13704 $ unsigned time = GetTickCount(); 13705 13706 $ if ((long) (time - loadTimes [file]) < _TX_TIMEOUT) 13707 {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); } 13708 13709 $ loadTimes [file] = time; 13710 13711 $ return dc; 13712 } 13713 13714 //----------------------------------------------------------------------------------------------------------------- 13715 13716 bool txDeleteDC (HDC* pdc) 13717 { 13718 $1 if (_TX_ARGUMENT_FAILED (pdc)) return false; 13719 13720 $ HDC dc = *pdc; 13721 $ bool ok = _txBuffer_Delete (pdc); 13722 $ if (!ok) return false; 13723 13724 $ if (!_txCanvas_UserDCs) return ok; 13725 13726 $ txAutoLock _lock; 13727 13728 $ for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it) 13729 if (*it == dc) 13730 { 13731 $ std::swap (*it, _txCanvas_UserDCs->back()); 13732 $ _txCanvas_UserDCs->pop_back(); 13733 $ break; 13734 } 13735 13736 $ return ok; 13737 } 13738 13739 //----------------------------------------------------------------------------------------------------------------- 13740 13741 bool txDeleteDC (HDC dc) 13742 { 13743 $1 return txDeleteDC (&dc); 13744 } 13745 13746 //----------------------------------------------------------------------------------------------------------------- 13747 13748 bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height, 13749 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/) 13750 { 13751 $1 if (_TX_HDC_FAILED (destImage)) return false; 13752 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13753 13754 $ POINT size = txGetExtent (sourceImage); 13755 $ if (!width) width = size.x; //-V550 13756 $ if (!height) height = size.y; //-V550 13757 13758 $ return txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13759 sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage); 13760 } 13761 13762 //----------------------------------------------------------------------------------------------------------------- 13763 13764 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/) 13765 { 13766 $1 if (_TX_TXWINDOW_FAILED()) return false; 13767 13768 $ return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource); 13769 } 13770 13771 //----------------------------------------------------------------------------------------------------------------- 13772 13773 bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height, 13774 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/) 13775 { 13776 // Это проверки того, правильные ли HDC вы передали в функцию. 13777 // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а. 13778 // При первом чтении это можно пропустить. 13779 13780 $1 if (_TX_HDC_FAILED (destImage)) return false; 13781 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13782 13783 // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent(). 13784 // При первом чтении это можно пропустить. 13785 13786 $ POINT size = txGetExtent (sourceImage); 13787 $ if (!width) width = size.x; //-V550 13788 $ if (!height) height = size.y; //-V550 13789 13790 // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest). 13791 // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только 13792 // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки). 13793 // При первом чтении это можно пропустить. 13794 13795 #if !defined (NDEBUG) 13796 13797 $ if (!(0 <= xSource && xSource + width <= size.x && 13798 0 <= ySource && ySource + height <= size.y)) 13799 { 13800 $ SetLastError (ERROR_INVALID_DATA); 13801 $ TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, " 13802 "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y); 13803 } 13804 13805 #endif 13806 13807 $ bool ok = true; 13808 13809 $ if (Win32::TransparentBlt) 13810 { 13811 // А вот теперь уже надо начать читать. 13812 // 13813 // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function" 13814 // и почитайте про ее параметры. 13815 // 13816 // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не 13817 // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что 13818 // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s> 13819 // это сделано для упрощения вызова функции TransparentBlt(). 13820 13821 // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки! // <<-- 13822 // // <<-- 13823 // ||||| |||||| // <<-- 13824 // vvvvv vvvvvv // <<-- 13825 // <<-- 13826 $ ok &= txGDI (!!(Win32::TransparentBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), // <<<< 13827 sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<< 13828 destImage); // <<-- 13829 // ^^^^^ ^^^^^^ // <<-- 13830 // ||||| |||||| // <<-- 13831 // // <<-- 13832 } // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте! // <<-- 13833 else 13834 { 13835 $ ok &= txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13836 sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)), 13837 destImage); 13838 } 13839 13840 // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что 13841 // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s> 13842 // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL 13843 // или DirectX, будет круто. Хотя это и сложнее.</s> 13844 13845 // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами, 13846 // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :(( 13847 13848 $ return ok; 13849 } 13850 13851 //----------------------------------------------------------------------------------------------------------------- 13852 13853 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage, 13854 COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/) 13855 { 13856 $1 if (_TX_TXWINDOW_FAILED()) return false; 13857 13858 $ return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor); 13859 } 13860 13861 //----------------------------------------------------------------------------------------------------------------- 13862 13863 bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height, 13864 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/) 13865 { 13866 $1 if (_TX_HDC_FAILED (destImage)) return false; 13867 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13868 13869 $ POINT size = txGetExtent (sourceImage); 13870 $ if (!width) width = size.x; //-V550 13871 $ if (!height) height = size.y; //-V550 13872 13873 #if !defined (NDEBUG) 13874 13875 $ if (!(0 <= xSource && xSource + width <= size.x && 13876 0 <= ySource && ySource + height <= size.y)) 13877 { 13878 $ SetLastError (ERROR_INVALID_DATA); 13879 $ TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, " 13880 "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y); 13881 } 13882 13883 #endif 13884 13885 $ if (alpha < 0) alpha = 0; 13886 $ if (alpha > 1) alpha = 1; 13887 13888 $ BITMAP bmap = { 0, 0, 0, 0, 0, 24 }; 13889 $ bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap); 13890 13891 $ BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) }; //-V112 //-V821 //-V2551 13892 13893 $ if (Win32::AlphaBlend) 13894 { 13895 $ ok &= txGDI (!!(Win32::AlphaBlend (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13896 sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)), 13897 destImage); 13898 } 13899 else 13900 { 13901 $ ok &= txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13902 sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)), 13903 destImage); 13904 $ ok = false; //-V519 13905 } 13906 13907 $ return ok; 13908 } 13909 13910 //----------------------------------------------------------------------------------------------------------------- 13911 13912 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage, 13913 double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/) 13914 { 13915 $1 if (_TX_TXWINDOW_FAILED()) return false; 13916 13917 $ return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha); 13918 } 13919 13920 //----------------------------------------------------------------------------------------------------------------- 13921 13922 HDC txUseAlpha (HDC image) 13923 { 13924 $1 if (_TX_HDC_FAILED (image)) return NULL; 13925 13926 $ HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP); 13927 $ if (!bitmap) return NULL; 13928 13929 $ DIBSECTION dib = {}; 13930 $ Win32::GetObject (bitmap, sizeof (dib), &dib) asserted; 13931 13932 $ POINT size = { dib.dsBm.bmWidth, dib.dsBm.bmHeight }; 13933 $ BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }}; 13934 $ RGBQUAD* buf = NULL; 13935 13936 $ bool isDIB = (dib.dsBm.bmPlanes == 1 && 13937 dib.dsBm.bmBitsPixel == sizeof (RGBQUAD) * 8 && 13938 dib.dsBmih.biCompression == DIB_RGB_COLORS && 13939 dib.dsBm.bmBits); 13940 $ if (!isDIB) 13941 { 13942 $ buf = new (std::nothrow) RGBQUAD [size.x * size.y]; //-V121 13943 $ if (!buf) return NULL; 13944 13945 $ Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted; 13946 } 13947 else 13948 { 13949 $ buf = (RGBQUAD*) dib.dsBm.bmBits; 13950 } 13951 13952 $ for (int y = 0; y < size.y; y++) 13953 for (int x = 0; x < size.x; x++) 13954 { 13955 RGBQUAD* color = &buf [x + y * size.x]; // Get color at (x, y) within image buffer //-V108 13956 13957 color->rgbRed = (BYTE) ROUND (color->rgbRed * color->rgbReserved / 255.0); 13958 color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0); 13959 color->rgbBlue = (BYTE) ROUND (color->rgbBlue * color->rgbReserved / 255.0); 13960 } 13961 13962 $ if (!isDIB) 13963 { 13964 $ Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted; 13965 13966 $ delete[] buf; 13967 } 13968 13969 $ return image; 13970 } 13971 13972 //----------------------------------------------------------------------------------------------------------------- 13973 13974 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/) 13975 { 13976 $1 if (_TX_ARGUMENT_FAILED (filename)) return false; 13977 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13978 13979 $ POINT size = txGetExtent (dc); 13980 13981 $ size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), //-V119 13982 szImg = (size.x * size.y) * sizeof (RGBQUAD); //-V104 13983 13984 $ BITMAP bmap = {}; 13985 $ BITMAPFILEHEADER hdr = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs }; //-V202 13986 $ BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }; 13987 13988 $ RGBQUAD* buf = NULL; 13989 $ bool ok = true; 13990 13991 $ ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap); 13992 13993 if (!ok) {$ return false; } 13994 13995 $ if (!bmap.bmBits) 13996 { 13997 $ buf = new (std::nothrow) RGBQUAD [size.x * size.y]; //-V121 13998 $ ok &= (buf != NULL); 13999 14000 $ int res = Win32::GetDIBits (dc, (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y, 14001 buf, (BITMAPINFO*) &info, DIB_RGB_COLORS); 14002 14003 if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); } 14004 14005 $ ok &= !!res; 14006 } 14007 else 14008 { 14009 $ buf = (RGBQUAD*) bmap.bmBits; 14010 } 14011 14012 $ FILE* f = NULL; 14013 $ if (ok) fopen_s (&f, filename, "wb"); 14014 $ ok &= (f != NULL); 14015 14016 $ if (ok) ok &= (fwrite (&hdr, sizeof (hdr), 1, f) == 1); //-V575 //-V595 14017 $ if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1); 14018 $ if (ok) ok &= (fwrite (buf, szImg, 1, f) == 1); //-V575 14019 14020 $ ok &= (f && fclose (f) == 0); 14021 14022 $ if (!bmap.bmBits) 14023 { 14024 $ delete[] buf; 14025 $ buf = NULL; 14026 } 14027 14028 $ return ok; 14029 } 14030 14031 //----------------------------------------------------------------------------------------------------------------- 14032 14033 double txSleep (double time) 14034 { 14035 $1 LARGE_INTEGER start = {}; 14036 $ QueryPerformanceCounter (&start) asserted; 14037 14038 $ LARGE_INTEGER freq = {}; 14039 $ QueryPerformanceFrequency (&freq) asserted; 14040 14041 $ int lock = _txCanvas_RefreshLock; 14042 $ _txCanvas_RefreshLock = 0; 14043 14044 $ HWND wnd = txWindow(); 14045 if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); } 14046 14047 $ Sleep (ROUND ((time >= 0)? time : 0)); 14048 14049 $ _txCanvas_RefreshLock = lock; 14050 14051 $ LARGE_INTEGER stop = {}; 14052 $ QueryPerformanceCounter (&stop) asserted; 14053 14054 $ return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart; 14055 } 14056 14057 //----------------------------------------------------------------------------------------------------------------- 14058 14059 bool txLock (bool wait /*= true*/) 14060 { 14061 $0 if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0); 14062 14063 $ if (wait) {$ return EnterCriticalSection (&_txCanvas_LockBackBuf), true; } //-V1048 14064 else {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf); } 14065 } 14066 14067 //----------------------------------------------------------------------------------------------------------------- 14068 14069 bool txUnlock() 14070 { 14071 $0 LeaveCriticalSection (&_txCanvas_LockBackBuf); 14072 14073 $ if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0); 14074 $ return false; 14075 } 14076 14077 #endif // TX_COMPILED 14078 14079 //----------------------------------------------------------------------------------------------------------------- 14080 14081 template <typename T> 14082 inline T txUnlock (T value) 14083 { 14084 $1 txUnlock(); 14085 $ return value; 14086 } 14087 14088 //----------------------------------------------------------------------------------------------------------------- 14089 14090 inline void txRedrawWindow() 14091 { 14092 $1 txSleep (0); 14093 } 14094 14095 //----------------------------------------------------------------------------------------------------------------- 14096 14097 inline int txUpdateWindow (int update /*= true*/) 14098 { 14099 $1 return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update); 14100 } 14101 14102 //----------------------------------------------------------------------------------------------------------------- 14103 14104 inline int txBegin() 14105 { 14106 $1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1); 14107 14108 $ return _txCanvas_RefreshLock; 14109 } 14110 14111 //----------------------------------------------------------------------------------------------------------------- 14112 14113 inline int txEnd() 14114 { 14115 $1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1); 14116 14117 $ return _txCanvas_RefreshLock; 14118 } 14119 14120 //----------------------------------------------------------------------------------------------------------------- 14121 14122 inline POINT txMousePos() 14123 { 14124 $1 POINT pos = {}; 14125 $ GetCursorPos (&pos); 14126 14127 $ if (txWindow()) 14128 {$ ScreenToClient (txWindow(), &pos); } 14129 14130 $ return pos; 14131 } 14132 14133 //----------------------------------------------------------------------------------------------------------------- 14134 14135 inline double txMouseX() 14136 { 14137 return (double) txMousePos() .x; 14138 } 14139 14140 //----------------------------------------------------------------------------------------------------------------- 14141 14142 inline double txMouseY() 14143 { 14144 return (double) txMousePos() .y; 14145 } 14146 14147 //----------------------------------------------------------------------------------------------------------------- 14148 14149 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 14150 14151 unsigned txMouseButtons() 14152 { 14153 $1 HWND txWnd = txWindow(); 14154 $ HWND foreground = GetForegroundWindow(); 14155 14156 $ if ((txWnd && (foreground == txWnd)) || 14157 (!txWnd && (foreground == Win32::GetConsoleWindow()))) 14158 { 14159 $ return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) | // MSB to bit 0 14160 ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) | // MSB to bit 1 14161 ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13); // MSB to bit 2 14162 } 14163 else 14164 {$ return 0; } 14165 } 14166 14167 //----------------------------------------------------------------------------------------------------------------- 14168 14169 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/) 14170 { 14171 unsigned oldAttr = txGetConsoleAttr(); 14172 14173 SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color); 14174 SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE), (WORD) color); 14175 14176 return oldAttr; 14177 } 14178 14179 //----------------------------------------------------------------------------------------------------------------- 14180 14181 unsigned txGetConsoleAttr() 14182 { 14183 CONSOLE_SCREEN_BUFFER_INFO con = {}; 14184 con.wAttributes = FOREGROUND_LIGHTGRAY; 14185 14186 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) || 14187 GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE), &con); 14188 14189 return con.wAttributes; 14190 } 14191 14192 //----------------------------------------------------------------------------------------------------------------- 14193 14194 POINT txSetConsoleCursorPos (double x, double y) 14195 { 14196 $1 POINT fontSz = txGetConsoleFontSize(); 14197 14198 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14199 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14200 14201 $ COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left), 14202 (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) }; 14203 14204 $ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted; 14205 14206 $ POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x), 14207 ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) }; 14208 $ return prev; 14209 } 14210 14211 //----------------------------------------------------------------------------------------------------------------- 14212 14213 POINT txGetConsoleCursorPos() 14214 { 14215 $1 POINT fontSz = txGetConsoleFontSize(); 14216 14217 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14218 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14219 14220 $ POINT pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x), 14221 ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) }; 14222 $ return pos; 14223 } 14224 14225 //----------------------------------------------------------------------------------------------------------------- 14226 14227 POINT txGetConsoleExtent() 14228 { 14229 $1 CONSOLE_SCREEN_BUFFER_INFO con = {}; 14230 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14231 14232 $ POINT size = { con.srWindow.Right - con.srWindow.Left + 1, 14233 con.srWindow.Bottom - con.srWindow.Top + 1 }; 14234 $ return size; 14235 } 14236 14237 //----------------------------------------------------------------------------------------------------------------- 14238 14239 bool txClearConsole() 14240 { 14241 $1 HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 14242 14243 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14244 $ GetConsoleScreenBufferInfo (out, &con) asserted; 14245 14246 $ COORD start = {con.srWindow.Left, con.srWindow.Top}; 14247 14248 $ DWORD len = (con.srWindow.Right - con.srWindow.Left + 1) * 14249 (con.srWindow.Bottom - con.srWindow.Top + 1); 14250 14251 $ DWORD written = 0; 14252 $ FillConsoleOutputCharacter (out, 0x20 /*' '*/, len, start, &written) asserted; //-V112 14253 $ FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted; 14254 14255 $ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted; 14256 14257 $ return written == len; 14258 } 14259 14260 //----------------------------------------------------------------------------------------------------------------- 14261 14262 POINT txGetConsoleFontSize() 14263 { 14264 $1 Win32::CONSOLE_FONT_INFO font = {0, {8, 16}}; 14265 14266 $ _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font)); 14267 14268 $ SIZE size = { font.dwFontSize.X, font.dwFontSize.Y }; 14269 if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); } //-V501 14270 14271 if (size.cx == 0) {$ size.cx = 1; } 14272 if (size.cy == 0) {$ size.cy = 1; } 14273 14274 $ POINT sizeFont = { size.cx, size.cy }; 14275 $ return sizeFont; 14276 } 14277 14278 //----------------------------------------------------------------------------------------------------------------- 14279 14280 bool txTextCursor (bool blink /*= true*/) 14281 { 14282 $1 bool old = _txConsole_IsBlinking; 14283 14284 $ _txConsole_IsBlinking = blink; 14285 14286 $ return old; 14287 } 14288 14289 //----------------------------------------------------------------------------------------------------------------- 14290 14291 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/) 14292 { 14293 $1 mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT; 14294 $ if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC; 14295 14296 $ if (!filename) mode = SND_PURGE; 14297 14298 $ return !!Win32::PlaySound (filename, NULL, mode); 14299 } 14300 14301 //----------------------------------------------------------------------------------------------------------------- 14302 14303 int txSpeak (const char* text, ...) 14304 { 14305 $1 bool verbose = false; (void) verbose; 14306 $ bool async = false; (void) async; 14307 14308 $ for (; text && *text; text++) 14309 { 14310 if (*text == '\a') {$ async = true; } 14311 else if (*text == '\v') {$ verbose = true; } 14312 else break; 14313 } 14314 14315 $ char textA [_TX_BUFSIZE] = "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!"; 14316 14317 $ va_list arg; va_start (arg, text); 14318 if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); } 14319 $ va_end (arg); 14320 14321 if (text && verbose) {$ printf ("%s", textA); } 14322 14323 #ifdef TX_USE_SPEAK 14324 14325 $ int time = GetTickCount(); 14326 14327 $ static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L""; 14328 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW)); 14329 14330 $ static ISpVoice* voice = NULL; 14331 14332 $ if (text && !voice) 14333 { 14334 $ HRESULT res = Win32::CoInitialize (NULL); 14335 if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); } 14336 } 14337 14338 $ if (text && voice) 14339 { 14340 $ Win32::_fpreset(); 14341 $ voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL); 14342 $ tx_fpreset(); 14343 } 14344 14345 $ if (!text && voice) 14346 { 14347 $ voice->Release(); 14348 $ voice = NULL; 14349 14350 $ Win32::CoUninitialize(); 14351 } 14352 14353 $ return (voice)? GetTickCount() - time : -1; 14354 14355 #else 14356 14357 $ if (text) 14358 { 14359 $ unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK); 14360 14361 $ txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA); 14362 14363 $ txSetConsoleAttr (oldAttr); 14364 } 14365 14366 $ return -1; 14367 14368 #endif 14369 } 14370 14371 //----------------------------------------------------------------------------------------------------------------- 14372 14373 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[], 14374 double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/) 14375 { 14376 $1 if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1; 14377 14378 $ int time = GetTickCount(); //-V2551 14379 14380 $ static char processUID [64] = ""; 14381 if (!*processUID) 14382 { 14383 $ FILETIME startTime = {}, null = {}; 14384 $ GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted; 14385 $ _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo", 14386 (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted; 14387 } 14388 14389 $ if (!fileName) 14390 { 14391 $ _txTaskKill ("vlc.exe", processUID, 0); // Kill'em all, by command line pattern 14392 $ return 0; 14393 } 14394 14395 $ static const char* vlcPath = _txPlayVideo_FindVLC(); 14396 14397 $ if (!vlcPath || _access (vlcPath, 0) != 0) 14398 { 14399 $ static int once = false; //-V601 14400 14401 $ if (*fileName && !once++) 14402 {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org " 14403 "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n" 14404 "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n" 14405 "P.S. См. мое описание в TXLib Help."); } 14406 $ return INT_MIN; //-V109 14407 } 14408 14409 $ bool async = false; 14410 if (*fileName == '\a') {$ async = true; fileName++; } 14411 14412 $ RECT rect = {}; 14413 if (wnd) {$ GetClientRect (wnd, &rect); } 14414 14415 if (!width) {$ width = rect.right; } 14416 if (!height) {$ height = rect.bottom; } 14417 14418 // Create a child window to hold the video stream 14419 14420 $ const char* errPos = "ВНЕЗАПНО"; 14421 14422 $ volatile HWND child = NULL; 14423 $ if (wnd && (wnd == txWindow())) 14424 { 14425 $ const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1); 14426 14427 $ static int number = 1; 14428 $ CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x, 14429 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass }; 14430 $ child = txCreateExtraWindow (createData); 14431 $ if (!child) 14432 { 14433 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s", 14434 strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos)); 14435 $ return INT_MIN+3; //-V109 14436 } 14437 14438 $ BringWindowToTop (child); 14439 14440 $ wnd = child; 14441 } 14442 14443 // Build the command line 14444 14445 if (!zoom && !wnd) {$ zoom = 1; } 14446 14447 $ char sZoom [64] = "--autoscale"; 14448 if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; } //-V550 14449 14450 $ static char cmd [MAX_PATH*2 + 1024] = ""; 14451 14452 $ _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit" 14453 14454 " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s" 14455 14456 " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging" 14457 14458 " --ignore-config --reset-config --no-one-instance --play-and-exit" 14459 " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file" 14460 " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events", 14461 14462 vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted; 14463 14464 $ txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n", 14465 x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd); 14466 $ if (!*fileName) 14467 { 14468 if (child) {$ txDestroyWindow (child); } 14469 $ return (intptr_t) cmd; 14470 } 14471 14472 $ if (!strstr (fileName, "://") && _access (fileName, 0) != 0) 14473 { 14474 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s", 14475 strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos)); 14476 14477 if (child) {$ txDestroyWindow (child); } 14478 $ return INT_MIN+1; //-V109 14479 } 14480 14481 // Run VLC, run 14482 14483 $ PROCESS_INFORMATION vlc = {}; 14484 $ STARTUPINFO start = { sizeof (start) }; 14485 $ DWORD ret = 0; 14486 14487 $ if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) && 14488 vlc.hProcess && vlc.hThread) 14489 { 14490 $ if (child) 14491 { 14492 $ assert (wnd == child); //-V547 14493 $ SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess); //-V107 14494 } 14495 14496 $ if (!async) 14497 { 14498 $ WaitForSingleObject (vlc.hProcess, INFINITE); 14499 $ GetExitCodeProcess (vlc.hProcess, &ret) asserted; 14500 } 14501 14502 $ if (!child) 14503 { 14504 $ CloseHandle (vlc.hProcess) asserted; 14505 } 14506 14507 $ CloseHandle (vlc.hThread) asserted; 14508 14509 $ return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret); //-V105 14510 } 14511 else 14512 { 14513 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s", 14514 strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos)); 14515 $ if (child) 14516 {$ txDestroyWindow (child); } 14517 14518 $ return INT_MIN+4; //-V112 //-V109 14519 } 14520 14521 #undef PROCESS_UID_ 14522 } 14523 14524 //----------------------------------------------------------------------------------------------------------------- 14525 14526 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/) 14527 { 14528 $1 return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd); 14529 } 14530 14531 //----------------------------------------------------------------------------------------------------------------- 14532 14533 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) 14534 { 14535 const UINT_PTR checkTimer = 1; 14536 14537 switch (msg) 14538 { 14539 case WM_CREATE: 14540 { 14541 $1 SetTimer (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted; 14542 } 14543 break; 14544 14545 case WM_DESTROY: 14546 { 14547 $1 KillTimer (wnd, checkTimer) asserted; 14548 14549 $ HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA); 14550 14551 $ if (vlc) 14552 { 14553 $ Win32::TerminateProcess (vlc, 0); 14554 14555 $ CloseHandle (vlc) asserted; 14556 14557 $ SetWindowLongPtr (wnd, GWLP_USERDATA, 0); 14558 } 14559 } 14560 break; 14561 14562 case WM_TIMER: 14563 { 14564 HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA); 14565 14566 if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT) 14567 { 14568 $1 DestroyWindow (wnd) asserted; 14569 } 14570 } 14571 break; 14572 14573 default: //-V2522 14574 break; 14575 } 14576 14577 return DefWindowProc (wnd, msg, wpar, lpar); 14578 } 14579 14580 //----------------------------------------------------------------------------------------------------------------- 14581 14582 const char* _txPlayVideo_FindVLC() 14583 { 14584 $1 static char vlcPath [MAX_PATH] = ""; 14585 14586 $ if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL)) 14587 { 14588 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14589 } 14590 14591 $ if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL)) 14592 { 14593 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14594 } 14595 14596 $ if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath))) 14597 { 14598 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14599 } 14600 14601 $ if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath))) 14602 { 14603 $ strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX); 14604 14605 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14606 } 14607 14608 $ strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files" "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX); //-V106 14609 { 14610 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14611 } 14612 14613 $ strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX); //-V106 14614 { 14615 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14616 } 14617 14618 $ return NULL; 14619 } 14620 14621 //----------------------------------------------------------------------------------------------------------------- 14622 14623 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/) 14624 { 14625 $1 static double oldPercent = 100; 14626 14627 if (percent < 0) {$ percent = MIN (oldPercent, 100); } 14628 else {$ oldPercent = percent; } 14629 14630 $ HRESULT res = S_FALSE; 14631 14632 #if defined (__ITaskbarList3_INTERFACE_DEFINED__) 14633 14634 $ HRESULT init = Win32::CoInitialize (NULL); 14635 14636 $ bool ok = true; 14637 $ res = S_OK; 14638 14639 $ ITaskbarList3* taskbar = NULL; 14640 if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); } 14641 $ ok &= !!taskbar && (res == S_OK); 14642 14643 if (!wnd) {$ wnd = txWindow(); } 14644 if (ok && taskbar) {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); } 14645 if (ok && taskbar) {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type); ok &= (res == S_OK); } 14646 14647 if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); } 14648 if (ok && taskbar) {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); } 14649 if (ok && taskbar) {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type); ok &= (res == S_OK); } 14650 14651 if (taskbar) {$ taskbar->Release(); } 14652 14653 if (init == S_OK) {$ Win32::CoUninitialize(); } 14654 14655 #endif 14656 14657 (void) type; (void) wnd; 14658 14659 $ return res; 14660 } 14661 14662 #endif // TX_COMPILED 14663 14664 //----------------------------------------------------------------------------------------------------------------- 14665 14666 // +--<<< Это не те символы, что вы ищете :) 14667 // V Полезно смотреть не только вверх, но и вниз 14668 14669 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/) 14670 { 14671 $1 WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc; 14672 $ return old; 14673 } 14674 14675 //----------------------------------------------------------------------------------------------------------------- 14676 14677 // +--<<< А это, наконец, искомое определение этой функции. 14678 // | Смотрите по сторонам! Нужная вам функция где-то рядом. 14679 // | 14680 // v 14681 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture() 14682 { 14683 txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n" 14684 14685 "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n" 14686 14687 "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. " 14688 "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n" 14689 14690 "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом " 14691 "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n" 14692 14693 "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы " 14694 "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n", 14695 14696 "Не получилось", MB_ICONSTOP); 14697 14698 // The truth is out there... (C++files) 14699 14700 return false; 14701 } 14702 14703 //----------------------------------------------------------------------------------------------------------------- 14704 14705 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you. 14706 14707 inline bool txDisableAutoPause() 14708 { 14709 _txExit = true; 14710 return true; 14711 } 14712 14713 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword. 14714 14715 //----------------------------------------------------------------------------------------------------------------- 14716 14717 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 14718 14719 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/) 14720 { 14721 $1 assert (!_txIsBadReadPtr (address)); 14722 14723 $ const unsigned char* addr = (const unsigned char*) address; 14724 14725 $ const int stdout_fileno = 1; // Not all g++ packages contain STDOUT_FILENO 14726 $ const int _o_u16text = 0x00020000; // and _O_U16TEXT 14727 14728 $ bool istty = _txIsTTY (1); 14729 14730 $ int mode = _O_TEXT; 14731 $ int oldMode = _setmode (stdout_fileno, mode); 14732 14733 $ unsigned oldCP = GetConsoleOutputCP(); 14734 $ unsigned cp = 1251; SetConsoleOutputCP (cp); //-V581 14735 14736 $ unsigned attr = txGetConsoleAttr(); 14737 14738 $ txSetConsoleAttr (FOREGROUND_WHITE); 14739 $ printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : "")); 14740 14741 $ txSetConsoleAttr (FOREGROUND_YELLOW); 14742 $ for (unsigned x = 0; x < 16; x++) printf ("%02X ", x); 14743 $ for (unsigned x = 0; x < 16; x++) printf ("%X", x); 14744 14745 $ const wchar_t* xlat[33] = {L"\xB7" /* 00 - NUL - NULL */, L"\x263A" /* 01 - SOH - Start of header */, 14746 L"\x263B" /* 02 - STX - Start of text */, L"\x2665" /* 03 - ETX - End of text */, 14747 L"\x2666" /* 04 - EOT - End of transm. */, L"\x2663" /* 05 - ENQ - Enquiry */, 14748 L"\x2660" /* 06 - ACK - Acknowledgment */, L"\x2022" /* 07 - BEL - Bell */, 14749 L"\x25D8" /* 08 - BS - Backspace */, L"\x25CB" /* 09 - HT - Horizontal tab */, 14750 L"\x25D9" /* 10 - LF - Line feed */, L"\x2642" /* 11 - VT - Vertical tab */, 14751 L"\x2640" /* 12 - FF - Form feed */, L"\x266A" /* 13 - CR - Carriage return */, 14752 L"\x266B" /* 14 - SO - Shift out */, L"\x263C" /* 15 - SI - Shift in */, 14753 L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1 */, 14754 L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3 */, 14755 L"\xB6" /* 20 - DC4 - Device control 4 */, L"\xA7" /* 21 - NAK - Negative ACK */, 14756 L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */, 14757 L"\x2191" /* 24 - CAN - Cancel */, L"\x2193" /* 25 - EM - End of medium */, 14758 L"\x2192" /* 26 - SUB - Substitute */, L"\x2190" /* 27 - ESC - Escape */, 14759 L"\x221F" /* 28 - FS - File separator */, L"\x2194" /* 29 - GS - Group separator */, 14760 L"\x25B2" /* 30 - RS - Record separator */, L"\x25BC" /* 31 - US - Unit separator */, 14761 L"\x20" /* 32 - Space */}; 14762 14763 $ for (int y = 0; y < 16; y++, addr += 16) 14764 { 14765 if (cp != 1251) SetConsoleOutputCP (cp = 1251); //-V581 14766 (void)_setmode (stdout_fileno, mode = oldMode); 14767 14768 txSetConsoleAttr (FOREGROUND_YELLOW); 14769 14770 printf ("\n" "%*p ", (int) sizeof (address) * 2, addr); 14771 14772 int color = FOREGROUND_LIGHTGREEN; 14773 14774 for (unsigned x = 0; x < 16; x++) 14775 { 14776 txSetConsoleAttr (color + x/4%2); //-V112 14777 printf ("%02X ", addr[x]); 14778 } 14779 14780 for (unsigned x = 0; x < 16; x++) 14781 { 14782 txSetConsoleAttr (color + x/4%2); //-V112 14783 14784 unsigned char ch = addr[x]; 14785 14786 if (ch >= sizearr (xlat) || !istty) 14787 { 14788 if (cp != oldCP) SetConsoleOutputCP (cp = oldCP); //-V581 14789 if (mode != oldMode) (void)_setmode (stdout_fileno, mode = oldMode); 14790 14791 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' '); 14792 } 14793 else 14794 { 14795 if (cp != 1251) SetConsoleOutputCP (cp = 1251); //-V581 14796 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text); 14797 14798 wprintf (L"%lls", xlat[ch]); 14799 } 14800 } 14801 } 14802 14803 $ (void)_setmode (stdout_fileno, oldMode); 14804 $ printf ("\n"); 14805 14806 $ if (pause && istty) 14807 { 14808 $ txSetConsoleAttr (FOREGROUND_DARKGRAY); 14809 $ txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP); 14810 } 14811 14812 $ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 14813 $ printf ("\n"); 14814 14815 $ txSetConsoleAttr (attr); 14816 $ SetConsoleOutputCP (oldCP); 14817 } 14818 14819 //----------------------------------------------------------------------------------------------------------------- 14820 14821 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/, 14822 bool readSource /*= true*/) 14823 { 14824 $1 unsigned attr = txGetConsoleAttr(); 14825 $ txSetConsoleAttr (FOREGROUND_LIGHTCYAN); 14826 14827 $ fprintf (stderr, "\n" "--------------------------------------------------\n" 14828 "Трассировка стека из \"%s\" at %s:%d:\n\n" 14829 "%s\n\n" 14830 "--------------------------------------------------\n\n", 14831 func, file, line, _txCaptureStackBackTrace (1, readSource)); 14832 14833 $ txSetConsoleAttr (attr); 14834 } 14835 14836 //----------------------------------------------------------------------------------------------------------------- 14837 14838 char* txDemangle (const char* mangledName, std::nomeow_t) 14839 { 14840 $1 if (!mangledName) return NULL; 14841 14842 $ char* typeName = NULL; 14843 14844 #if defined (_GCC_VER) 14845 14846 $ int err = 1; 14847 $ typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err; 14848 if (typeName) {$ return typeName; } 14849 14850 #endif 14851 14852 $ unsigned short flags = 0; 14853 14854 $ if (mangledName[0] == '.') 14855 { 14856 $ mangledName++; 14857 $ flags = 0x2800; // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY 14858 } 14859 14860 $ typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags)); 14861 if (typeName) {$ return typeName; } 14862 14863 $ return _strdup (mangledName); 14864 } 14865 14866 //----------------------------------------------------------------------------------------------------------------- 14867 14868 std::string txDemangle (const char* mangledName) 14869 { 14870 $1 char* typeName = txDemangle (mangledName, std::nomeow); 14871 $ std::string name (typeName? typeName : ""); 14872 $ free (typeName); 14873 14874 $ return name; 14875 } 14876 14877 //----------------------------------------------------------------------------------------------------------------- 14878 14879 double txQueryPerformance() 14880 { 14881 $1 int maxTime = 500; 14882 $ int maxSamples = 100; 14883 $ POINT size = {100, 100}; 14884 14885 $ HDC dc = _txBuffer_Create (txWindow(), &size, NULL); 14886 $ assert (dc); if (!dc) return -1; //-V547 14887 14888 $ DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1); //-V202 14889 $ assert (mask); 14890 14891 $ LARGE_INTEGER freq = {}; 14892 $ QueryPerformanceFrequency (&freq) asserted; 14893 14894 $ LARGE_INTEGER start = {}; 14895 $ QueryPerformanceCounter (&start) asserted; 14896 14897 $ int samples = 0; 14898 $ while (samples++ < maxSamples) 14899 { 14900 $ LARGE_INTEGER cur = {}; 14901 $ QueryPerformanceCounter (&cur) asserted; 14902 14903 $ double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart; 14904 $ if (t > maxTime) break; 14905 14906 // Draw test scene 14907 14908 $ for (int y = 0; y < size.y; y++) 14909 for (int x = 0; x < size.x; x++) txSetPixel (x, y, TX_BLACK, dc); 14910 14911 $ for (int y = 0; y < size.y; y += 10) 14912 for (int x = 0; x < size.x; x += 50) txTextOut (x, y, "*", dc); 14913 14914 $ txEllipse (0, 0, size.x, size.y, dc); 14915 $ txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc); 14916 14917 $ txBitBlt (dc, size.x/2.0, 0, size.x/2.0, size.y/2.0, dc, 0, 0) asserted; 14918 $ txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, 0, size.y/2.0) asserted; 14919 $ txBitBlt (dc, 0, size.y/2.0, size.x/2.0, size.y/2.0, dc, 0, 0) asserted; 14920 $ txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, size.x/2.0, 0) asserted; 14921 } 14922 14923 $ mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask); //-V106 //-V202 14924 $ assert (mask); 14925 14926 $ _txBuffer_Delete (&dc); 14927 14928 $ return 3.0 * samples / sqrt (1.0 * size.x * size.y); 14929 } 14930 14931 //----------------------------------------------------------------------------------------------------------------- 14932 14933 unsigned txExtractColor (COLORREF color, COLORREF component) 14934 { 14935 $1 switch (component) 14936 { 14937 case TX_RED: 14938 case TX_HUE: $ return (color >> 0) & 0xFF; 14939 14940 case TX_GREEN: 14941 case TX_SATURATION: $ return (color >> 8) & 0xFF; 14942 14943 case TX_BLUE: 14944 case TX_LIGHTNESS: $ return (color >> 16) & 0xFF; 14945 14946 default: $ return CLR_INVALID; 14947 } 14948 } 14949 14950 //----------------------------------------------------------------------------------------------------------------- 14951 14952 COLORREF txRGB2HSL (COLORREF rgbColor) 14953 { 14954 $1 struct xRGB 14955 { 14956 static bool zero (double val) 14957 { 14958 const double prec = 0.001; 14959 14960 return (fabs (val) < prec); 14961 } 14962 }; 14963 14964 $ double r = txExtractColor (rgbColor, TX_RED) / 255.0, //-V2551 14965 g = txExtractColor (rgbColor, TX_GREEN) / 255.0, //-V2551 14966 b = txExtractColor (rgbColor, TX_BLUE) / 255.0, //-V2551 14967 14968 m1 = MAX (MAX (r, g), b), 14969 m2 = MIN (MIN (r, g), b), 14970 dm = m1 - m2, 14971 sm = m1 + m2, 14972 14973 h = 0, 14974 s = 0, 14975 l = sm / 2; 14976 14977 $ if (!xRGB::zero (dm)) 14978 { 14979 $ sm = (sm <= 1)? sm : (2-sm); 14980 $ s = (!xRGB::zero (sm))? dm/sm : 0; 14981 14982 $ double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0, 14983 cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0, 14984 cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0; 14985 14986 $ if (xRGB::zero (r - m1)) h = cb - cg; 14987 $ if (xRGB::zero (g - m1)) h = 2 + cr - cb; 14988 $ if (xRGB::zero (b - m1)) h = 4 + cg - cr; 14989 } 14990 14991 $ h = (h >= 0)? h*60 : h*60 + 360; 14992 14993 $ return RGB (ROUND (h / 360.0 * 256), ROUND (s * 255), ROUND (l * 255)); 14994 } 14995 14996 //----------------------------------------------------------------------------------------------------------------- 14997 14998 COLORREF txHSL2RGB (COLORREF hslColor) 14999 { 15000 $1 struct xRGB 15001 { 15002 static double calc (double h, double m1, double m2) 15003 { 15004 $2 while (h < 0) h += 360; 15005 $ while (h > 360) h -= 360; 15006 15007 $ return (h < 60)? m1 + (m2-m1) * h / 60 : 15008 (h < 180)? m2 : 15009 (h < 240)? m1 + (m2-m1) * (240-h) / 60 : 15010 m1; 15011 } 15012 }; 15013 15014 $ int si = txExtractColor (hslColor, TX_SATURATION); 15015 15016 $ double h = txExtractColor (hslColor, TX_HUE) / 256.0 * 360, 15017 s = txExtractColor (hslColor, TX_SATURATION) / 255.0, 15018 l = txExtractColor (hslColor, TX_LIGHTNESS) / 255.0, 15019 15020 m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s, 15021 m1 = 2 * l - m2, 15022 15023 r = (si)? xRGB::calc (h + 120, m1, m2) : l, 15024 g = (si)? xRGB::calc (h, m1, m2) : l, 15025 b = (si)? xRGB::calc (h - 120, m1, m2) : l; 15026 15027 $ return RGB (ROUND (r * 255), ROUND (g * 255), ROUND (b * 255)); 15028 } 15029 15030 //----------------------------------------------------------------------------------------------------------------- 15031 15032 void tx_fpreset() 15033 { 15034 $1 txAutoLock _lock; 15035 15036 $ Win32::_fpreset(); 15037 15038 $ unsigned new87 = 0x0008001C; // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW 15039 15040 #if !defined (__CYGWIN__) 15041 15042 $ unsigned old87 = 0; 15043 $ if (_controlfp_s (&old87, 0, 0) == 0) 15044 {$ (void) _controlfp_s (&old87, old87 & ~new87, 0x0008001F); } // _MCW_EM 15045 15046 #else 15047 15048 $ Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F); // _MCW_EM 15049 15050 #endif 15051 } 15052 15053 #endif // TX_COMPILED 15054 15055 //----------------------------------------------------------------------------------------------------------------- 15056 15057 #if defined (_TX_CPP11) 15058 template <int txFramesToAverage> 15059 #endif 15060 15061 double txGetFPS (int minFrames) 15062 { 15063 $1 static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0); 15064 $ LARGE_INTEGER time = {}; QueryPerformanceCounter (&time); 15065 15066 $ if (time.QuadPart - time0.QuadPart == 0) 15067 {$ return 0; } 15068 15069 $ LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq); 15070 15071 $ double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart); 15072 $ time0 = time; 15073 15074 $ if (txFramesToAverage == 0) return fps; 15075 15076 $ static _tx_thread double average [txFramesToAverage] = {}; 15077 $ static _tx_thread unsigned n = 0; 15078 15079 $ average [n++ % txFramesToAverage] = fps; 15080 15081 $ unsigned nn = MIN (n, (unsigned) sizearr (average)); 15082 15083 $ fps = 0; 15084 $ for (unsigned i = 0; i < nn; i++) fps += average[i]; 15085 $ fps /= nn; 15086 15087 $ return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0; 15088 } 15089 15090 //----------------------------------------------------------------------------------------------------------------- 15091 15092 template <typename T> 15093 inline T zero() { T __zero = {}; return __zero; } 15094 15095 //----------------------------------------------------------------------------------------------------------------- 15096 15097 inline double random (std::nomeow_t, double left, double right) 15098 { 15099 return left + (right - left) * ((double) rand() / RAND_MAX); 15100 } 15101 15102 //----------------------------------------------------------------------------------------------------------------- 15103 15104 template <typename Tx, typename Ta, typename Tb> 15105 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) 15106 { 15107 return a <= x && x <= b; 15108 } 15109 15110 //----------------------------------------------------------------------------------------------------------------- 15111 15112 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) 15113 { 15114 if (_TX_ARGUMENT_FAILED (&pt)) return false; 15115 if (_TX_ARGUMENT_FAILED (&rect)) return false; 15116 15117 return In (std::nomeow, pt.x, rect.left, rect.right) && 15118 In (std::nomeow, pt.y, rect.top, rect.bottom); 15119 } 15120 15121 //----------------------------------------------------------------------------------------------------------------- 15122 15123 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) 15124 { 15125 if (_TX_ARGUMENT_FAILED (&pt)) return false; 15126 if (_TX_ARGUMENT_FAILED (&rect)) return false; 15127 15128 return In (std::nomeow, pt.X, rect.Left, rect.Right) && 15129 In (std::nomeow, pt.Y, rect.Top, rect.Bottom); 15130 } 15131 15132 //----------------------------------------------------------------------------------------------------------------- 15133 15134 inline int random (int range) 15135 { 15136 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15137 15138 return rand() % range; 15139 } 15140 15141 //----------------------------------------------------------------------------------------------------------------- 15142 15143 inline double random (double left, double right) 15144 { 15145 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15146 15147 return random (std::nomeow, left, right); 15148 } 15149 15150 //----------------------------------------------------------------------------------------------------------------- 15151 15152 template <typename Tx, typename Ta, typename Tb> 15153 inline bool In (Tx x, Ta a, Tb b) 15154 { 15155 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15156 15157 return In (std::nomeow, x, a, b); 15158 } 15159 15160 //----------------------------------------------------------------------------------------------------------------- 15161 15162 inline bool In (const POINT& pt, const RECT& rect) 15163 { 15164 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15165 15166 return In (std::nomeow, pt, rect); 15167 } 15168 15169 //----------------------------------------------------------------------------------------------------------------- 15170 15171 inline bool In (const COORD& pt, const SMALL_RECT& rect) 15172 { 15173 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15174 15175 return In (std::nomeow, pt, rect); 15176 } 15177 15178 //} 15179 //================================================================================================================= 15180 15181 //================================================================================================================= 15182 //{ txPrintf() implementation 15183 // Реализация txPrintf() 15184 //================================================================================================================= 15185 15186 #if defined (_TX_CPP11) 15187 15188 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args); 15189 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args); 15190 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args); 15191 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args); 15192 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt); 15193 15194 template <typename T> void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg); 15195 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg); 15196 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt); 15197 15198 //----------------------------------------------------------------------------------------------------------------- 15199 15200 template <typename T, typename... ArgsT> 15201 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args) 15202 { 15203 $1 assert (fmt); 15204 15205 $ _txPrintV (stream, format, n, fmt); 15206 15207 if (fmt[0] == '%') {$} 15208 else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); } 15209 15210 $ _txPrintV (stream, format, n, fmt, arg); 15211 15212 $ _txPrintF (stream, format, n+1, fmt, args...); 15213 } 15214 15215 //----------------------------------------------------------------------------------------------------------------- 15216 15217 template <typename T, typename... ArgsT> 15218 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args) 15219 { 15220 $1 assert (&stream); 15221 $ assert (fmt); 15222 15223 $ _txPrintV (stream, format, n, fmt); 15224 15225 if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); } //-V2006 15226 else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); } 15227 15228 $ _txPrintV (stream, format, n, fmt, arg); 15229 15230 $ _txPrintF (stream, format, n+1, fmt, args...); 15231 } 15232 15233 //----------------------------------------------------------------------------------------------------------------- 15234 15235 template <typename T, typename... ArgsT> 15236 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args) 15237 { 15238 $1 assert (&stream); 15239 $ assert (fmt); 15240 15241 $ _txPrintV (stream, format, n, fmt); 15242 15243 if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((std::streamsize) (prec + 1)); } //-V2006 //-V1028 15244 else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); } 15245 15246 $ _txPrintV (stream, format, n, fmt, arg); 15247 15248 $ _txPrintF (stream, format, n+1, fmt, args...); 15249 } 15250 15251 //----------------------------------------------------------------------------------------------------------------- 15252 15253 template <typename T, typename... ArgsT> 15254 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args) 15255 { 15256 $1 assert (&stream); 15257 $ assert (fmt); 15258 15259 $ _txPrintV (stream, format, n, fmt); 15260 15261 if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((std::streamsize) (prec + 1)); } //-V2006 //-V1028 15262 else {$ TX_ERROR ("\"%%*.*\" required to setwidth (%d) and setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, prec, fmt, txTypename (arg), n, format); } 15263 15264 $ _txPrintV (stream, format, n, fmt, arg); 15265 15266 $ _txPrintF (stream, format, n+1, fmt, args...); 15267 } 15268 15269 //----------------------------------------------------------------------------------------------------------------- 15270 15271 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt) 15272 { 15273 $1 assert (fmt); 15274 15275 $ _txPrintV (stream, format, n, fmt); 15276 15277 if (!fmt[0]) {$} 15278 else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); } 15279 } 15280 15281 //----------------------------------------------------------------------------------------------------------------- 15282 15283 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt) 15284 { 15285 $1 assert (&stream); 15286 $ assert (fmt); 15287 15288 $ while (*fmt) 15289 { 15290 if (fmt[0] == '%') 15291 { 15292 if (fmt[1] == '%') fmt++; 15293 else break; 15294 } 15295 15296 stream << *fmt++; 15297 } 15298 $ } 15299 15300 //----------------------------------------------------------------------------------------------------------------- 15301 15302 template <typename T> 15303 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg) 15304 { 15305 $1 assert (&stream); 15306 $ assert (fmt); 15307 15308 $ if (_TX_ARGUMENT_FAILED (&arg)) return; 15309 15310 if (fmt[0] == '%') {$} 15311 else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); } 15312 15313 $ fmt++; 15314 15315 $ char oldFill = stream.fill (' '); 15316 $ std::ios_base::fmtflags oldFlags = stream.flags(); 15317 15318 $ for (;;) switch (*fmt) 15319 { 15320 case '-': $ stream << std::left; fmt++; break; 15321 case '+': $ stream << std::showpos; fmt++; break; 15322 case ' ': $ stream.fill (' '); fmt++; break; 15323 case '#': $ stream << std::showbase; fmt++; break; 15324 case '0': $ stream.fill ('0'); fmt++; break; 15325 15326 default: $ goto end; 15327 } 15328 end: 15329 15330 $ int width = (*fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0); 15331 $ int prec = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0; 15332 15333 if (width) {$ stream << std::setw (width); } 15334 if (prec) {$ stream << std::setprecision (prec); } 15335 15336 $ fmt += strspn (fmt, "hljztL"); 15337 15338 $ switch (*fmt) 15339 { 15340 case '$': 15341 case '?': $ break; 15342 15343 case 'd': 15344 case 'i': 15345 case 'u': $ stream << std::dec; break; 15346 15347 case 'o': $ stream << std::oct; break; 15348 15349 case 'x': $ stream << std::hex; break; 15350 case 'X': $ stream << std::hex << std::uppercase; break; 15351 15352 case 'f': $ stream << std::fixed; break; 15353 case 'F': $ stream << std::fixed << std::uppercase; break; 15354 15355 case 'e': $ stream << std::scientific; break; 15356 case 'E': $ stream << std::scientific << std::uppercase; break; 15357 15358 case 'g': $ break; 15359 case 'G': $ stream << std::uppercase; break; 15360 15361 case 'a': $ break; 15362 case 'A': $ stream << std::uppercase; break; 15363 15364 case 'c': 15365 case 's': 15366 case 'p': $ break; 15367 15368 default: $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break; 15369 } 15370 15371 $ fmt++; 15372 15373 if (&arg) {$ stream << arg; } 15374 else {$ stream << "(null)"; } 15375 15376 $ stream.fill (oldFill); 15377 $ stream.flags (oldFlags); 15378 } 15379 15380 //----------------------------------------------------------------------------------------------------------------- 15381 15382 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg) //-V2009 15383 { 15384 $1 assert (fmt); 15385 15386 if (_TX_ARGUMENT_FAILED (arg)) return; 15387 15388 if (fmt[0] == '%' && fmt[1] == 'n') {$} 15389 else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); } 15390 15391 $ *arg = (int) stream.str().length(); //-V202 15392 15393 $ fmt += 2; 15394 } 15395 15396 //----------------------------------------------------------------------------------------------------------------- 15397 15398 template <typename T> inline const T& _txPrintfNormalizeArg (const T& arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;} return arg; } 15399 inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); } 15400 15401 //----------------------------------------------------------------------------------------------------------------- 15402 15403 template <typename... ArgsT> 15404 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args) 15405 { 15406 $1 if (_TX_ARGUMENT_FAILED (&stream)) return 0; 15407 $ if (_TX_ARGUMENT_FAILED (&format)) return 0; 15408 15409 $ const char* fmt = format; 15410 $ _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...); 15411 15412 $ return (int) stream.str().length(); //-V202 15413 } 15414 15415 //----------------------------------------------------------------------------------------------------------------- 15416 15417 template <typename... ArgsT> 15418 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args) 15419 { 15420 $1 if (_TX_ARGUMENT_FAILED (&buffer)) return 0; 15421 $ if (_TX_ARGUMENT_FAILED (&format)) return 0; 15422 15423 $ if (size > 0) size--; 15424 $ buffer[size] = 0; 15425 15426 $ if (!size) return 0; 15427 15428 $ std::ostringstream stream; 15429 $ stream.rdbuf() -> pubsetbuf (buffer, size); 15430 15431 $ txPrintf (stream, format, args...); 15432 15433 $ return (int) stream.str().length(); //-V202 15434 } 15435 15436 //----------------------------------------------------------------------------------------------------------------- 15437 15438 template <typename... ArgsT> 15439 inline std::string txFormat (const char* format, ArgsT... args) 15440 { 15441 $1 if (_TX_ARGUMENT_FAILED (&format)) return ""; 15442 15443 $ std::ostringstream stream; 15444 15445 $ txPrintf (stream, format, args...); 15446 15447 $ return stream.str(); 15448 } 15449 15450 //----------------------------------------------------------------------------------------------------------------- 15451 15452 template <typename... ArgsT> 15453 inline int txPrintf (const char* format, ArgsT... args) 15454 { 15455 $1 if (_TX_ARGUMENT_FAILED (&format)) return 0; 15456 15457 $ return printf ("%s", txFormat (format, args...) .c_str()); 15458 } 15459 15460 #endif 15461 15462 //----------------------------------------------------------------------------------------------------------------- 15463 15464 int _txPrintfCheck (const char* format, ...) tx_printfy (1); 15465 inline int _txPrintfCheck (const char*, ...) { return 0; } 15466 15467 //} 15468 //================================================================================================================= 15469 15470 //================================================================================================================= 15471 //{ txDialog methods implementation 15472 // Реализация методов класса txDialog 15473 // 15474 // See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx 15475 // [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743 15476 // [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753 15477 //================================================================================================================= 15478 15479 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 15480 15481 txDialog::txDialog () : 15482 layout_ (NULL) 15483 {$1} 15484 15485 //----------------------------------------------------------------------------------------------------------------- 15486 15487 txDialog::txDialog (const Layout* layout) : 15488 layout_ (layout) 15489 {$1} 15490 15491 //----------------------------------------------------------------------------------------------------------------- 15492 15493 const txDialog::Layout* txDialog::setLayout (const Layout* layout) 15494 { 15495 $1 assert (layout); 15496 15497 $ return ::std::swap (layout_, layout), layout; 15498 } 15499 15500 //----------------------------------------------------------------------------------------------------------------- 15501 15502 intptr_t txDialog::dialogBox (WORD resourceID) 15503 { 15504 $1 const char* resName = (char*)(uintptr_t) resourceID; 15505 15506 $ if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0; 15507 15508 $ return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this); 15509 } 15510 15511 //----------------------------------------------------------------------------------------------------------------- 15512 15513 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/) 15514 { 15515 $1 if (!layout) layout = layout_; 15516 $ if (!layout) return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0; 15517 15518 $ if (!bufsize) bufsize = 1024; 15519 15520 $ DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize); 15521 $ if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0; 15522 15523 $ const Layout* dlg = &layout[0]; 15524 $ const Layout def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 }; 15525 15526 $ void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize, 15527 (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0, 15528 dlg->x, dlg->y, dlg->sx, dlg->sy, 15529 dlg->caption? dlg->caption : def.caption, 15530 dlg->font? dlg->font : def.font, 15531 dlg->fontsize? dlg->fontsize : def.fontsize, NULL); 15532 $ WORD i = 0; 15533 $ for (i = 1; layout[i].wndclass != END; ++i) 15534 { 15535 $ const Layout* item = &layout[i]; 15536 15537 $ ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl), 15538 item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy, 15539 item->id, (const char*)(uintptr_t) item->wndclass, item->caption); 15540 } 15541 15542 $ tmpl->cdit = (unsigned short) (i-1); 15543 15544 $ intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this); 15545 15546 $ GlobalFree (tmpl); 15547 15548 $ return res; 15549 } 15550 15551 //----------------------------------------------------------------------------------------------------------------- 15552 15553 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM) 15554 { 15555 $1 switch (msg) 15556 { 15557 case WM_INITDIALOG: $ SetForegroundWindow (wnd); 15558 $ break; 15559 15560 case WM_COMMAND: $ switch (LOWORD (wParam)) 15561 { 15562 case IDOK: 15563 case IDCANCEL: $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow()); 15564 $ EndDialog (wnd, (uintptr_t) this); 15565 $ break; 15566 15567 default: $ break; 15568 } 15569 $ break; 15570 default: $ break; 15571 } 15572 15573 $ return FALSE; 15574 } 15575 15576 //----------------------------------------------------------------------------------------------------------------- 15577 15578 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) 15579 { 15580 $1 static txDialog* this__ = NULL; 15581 $ if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam; 15582 $ if (!this__) return FALSE; 15583 15584 $ return this__-> dialogProc (wnd, msg, wParam, lParam); //-V109 15585 } 15586 15587 //----------------------------------------------------------------------------------------------------------------- 15588 15589 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle, 15590 WORD controls, short x, short y, short cx, short cy, 15591 const char caption[], const char font[], WORD fontsize, const char menu[]) 15592 { 15593 $1 if (_TX_ARGUMENT_FAILED (globalMem)) return NULL; 15594 15595 $ WORD* pw = (WORD*) globalMem; 15596 15597 $ DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++; 15598 15599 $ tmpl->style = style; 15600 $ tmpl->dwExtendedStyle = exStyle; 15601 $ tmpl->cdit = controls; 15602 $ tmpl->x = x; 15603 $ tmpl->y = y; 15604 $ tmpl->cx = cx; 15605 $ tmpl->cy = cy; 15606 15607 $ if (menu > (const char*) 0xFFFF) 15608 { 15609 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (menu? menu : ""), -1, (wchar_t*) pw, //-V547 15610 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15611 } 15612 else 15613 { 15614 $ *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0); 15615 $ *pw++ = (WORD)(uintptr_t) menu; 15616 } 15617 15618 $ if (caption) 15619 { 15620 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw, //-V547 15621 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15622 } 15623 15624 $ if (style & DS_SETFONT) 15625 { 15626 $ *pw++ = fontsize; 15627 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (font? font : ""), -1, (wchar_t*) pw, 15628 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15629 } 15630 15631 $ return pw; 15632 } 15633 15634 //----------------------------------------------------------------------------------------------------------------- 15635 15636 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle, 15637 short x, short y, short cx, short cy, 15638 WORD id, const char wclass[], const char caption[]) 15639 { 15640 $1 if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL; 15641 15642 $ WORD* pw = (LPWORD) dlgTemplatePtr; // Force align at word boundary 15643 $ ((ULONG&) pw) += 3; //-V205 15644 $ ((ULONG&) pw) >>= 2; //-V205 15645 $ ((ULONG&) pw) <<= 2; //-V205 15646 15647 $ DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++; 15648 15649 $ tmpl->style = style; 15650 $ tmpl->dwExtendedStyle = exStyle; 15651 $ tmpl->x = x; 15652 $ tmpl->y = y; 15653 $ tmpl->cx = cx; 15654 $ tmpl->cy = cy; 15655 $ tmpl->id = id; 15656 15657 $ if (HIWORD (wclass) == 0xFFFF) 15658 { 15659 $ *pw++ = (WORD) (HIWORD ((uintptr_t) wclass)); 15660 $ *pw++ = (WORD) (LOWORD ((uintptr_t) wclass)); 15661 } 15662 else if (wclass) 15663 { 15664 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw, 15665 (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF)); //-V202 15666 } 15667 else 15668 { 15669 $ *pw++ = 0; 15670 } 15671 15672 $ if (caption) 15673 { 15674 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw, 15675 (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF)); //-V202 15676 } 15677 else 15678 { 15679 $ *pw++ = 0; 15680 } 15681 15682 $ *pw++ = 0; 15683 15684 $ return pw; 15685 } 15686 15687 #endif // TX_COMPILED 15688 15689 //} 15690 //================================================================================================================= 15691 15692 //================================================================================================================= 15693 //{ Cleaning up the utility macros 15694 // Очистка служебных макросов 15695 //================================================================================================================= 15696 15697 #undef $ 15698 #undef $0 15699 #undef $1 15700 #undef $2 15701 #undef $3 15702 #undef $4 15703 #undef $5 15704 #undef $6 15705 #undef $7 15706 #undef $8 15707 #undef $9 15708 #undef $$ 15709 15710 //} 15711 //================================================================================================================= 15712 15714 15715 //================================================================================================================= 15716 //{ Experimental Debugging macros 15718 //================================================================================================================= 15719 15720 //{---------------------------------------------------------------------------------------------------------------- 15840 //}---------------------------------------------------------------------------------------------------------------- 15841 15842 #ifndef __TX_DEBUG_MACROS 15843 #define __TX_DEBUG_MACROS ("Группа отладочных $-макросов") 15844 15846 //----------------------------------------------------------------------------------------------------------------- 15847 15848 #define $H txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_BLACK); 15849 #define $B txSetConsoleAttr (FOREGROUND_BLUE | BACKGROUND_BLACK); 15850 #define $G txSetConsoleAttr (FOREGROUND_GREEN | BACKGROUND_BLACK); 15851 #define $C txSetConsoleAttr (FOREGROUND_CYAN | BACKGROUND_BLACK); 15852 #define $R txSetConsoleAttr (FOREGROUND_RED | BACKGROUND_BLACK); 15853 #define $M txSetConsoleAttr (FOREGROUND_MAGENTA | BACKGROUND_BLACK); 15854 #define $Y txSetConsoleAttr (FOREGROUND_DARKYELLOW | BACKGROUND_BLACK); 15855 #define $d txSetConsoleAttr (FOREGROUND_LIGHTGRAY | BACKGROUND_BLACK); 15856 #define $D txSetConsoleAttr (FOREGROUND_DARKGRAY | BACKGROUND_BLACK); 15857 #define $b txSetConsoleAttr (FOREGROUND_LIGHTBLUE | BACKGROUND_BLACK); 15858 #define $g txSetConsoleAttr (FOREGROUND_LIGHTGREEN | BACKGROUND_BLACK); 15859 #define $c txSetConsoleAttr (FOREGROUND_LIGHTCYAN | BACKGROUND_BLACK); 15860 #define $r txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK); 15861 #define $m txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK); 15862 #define $y txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLACK); 15863 #define $h txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_BLACK); 15864 15865 #define $i txSetConsoleAttr (FOREGROUND_LIGHTCYAN | BACKGROUND_BLUE); 15866 #define $I txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLUE); 15867 #define $o txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_GREEN); 15868 #define $O txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_GREEN); 15869 #define $e txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_RED); 15870 #define $E txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_RED); 15871 #define $w txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA); 15872 #define $W txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_MAGENTA); 15873 #define $f txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_LIGHTRED); 15874 #define $F txSetConsoleAttr (FOREGROUND_MAGENTA | BACKGROUND_LIGHTRED); 15875 #define $l txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_DARKGRAY); 15876 #define $L txSetConsoleAttr (FOREGROUND_LIGHTGRAY | BACKGROUND_DARKGRAY); 15877 15878 #define $T( cond ) txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED ); 15879 15880 #define $s _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__); 15881 15882 #define $sH $s $H 15883 #define $sB $s $B 15884 #define $sG $s $G 15885 #define $sC $s $C 15886 #define $sR $s $R 15887 #define $sM $s $M 15888 #define $sY $s $Y 15889 #define $sd $s $d 15890 #define $sD $s $D 15891 #define $sb $s $b 15892 #define $sg $s $g 15893 #define $sc $s $c 15894 #define $sr $s $r 15895 #define $sm $s $m 15896 #define $sy $s $y 15897 #define $sh $s $h 15898 15899 #define $si $s $i 15900 #define $sI $s $I 15901 #define $so $s $o 15902 #define $sO $s $O 15903 #define $se $s $e 15904 #define $sE $s $E 15905 #define $sw $s $w 15906 #define $sW $s $W 15907 #define $sf $s $f 15908 #define $sF $s $F 15909 #define $sl $s $l 15910 #define $sL $s $L 15911 15912 #define $sT( cond ) $s $T (cond) 15913 15914 #define $test(cond) { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \ 15915 else { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; } 15916 15917 #define $status(cond) $test (cond) 15918 15919 #define $unittest( code, expected ) \ 15920 { \ 15921 const _tx_decltype (code) & _result = (code); /* Should use auto, but g++ 4.7.2 default std is < 2011 */ \ 15922 const _tx_decltype (expected) & _expected = (expected); \ 15923 \ 15924 if (_result == _expected) \ 15925 { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; } \ 15926 else \ 15927 { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \ 15928 \ 15929 $n; \ 15930 (_result == _expected); \ 15931 } 15932 15933 //================================================================================================================= 15934 15935 #define $V( var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "]\n") ) 15936 #define $V_( var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "] " ) ) 15937 #define $V__(var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "]" ) ) 15938 15939 #define $( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]\n") ) 15940 #define $_( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "] " ) ) 15941 #define $__( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ) ) 15942 15943 #define $x( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) ) 15944 #define $x_( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "] ", ::std::ios_base::showbase | ::std::ios_base::hex) ) 15945 15946 #define $v( var, cond, ...) { { $st (cond); _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ); } $n; } 15947 #define $v_( var, cond, ...) { $st (cond); _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ); } 15948 15949 #define $$ { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__); } txOutputDebugPrintf ("\f\n"); } 15950 #define $$_ { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]", __LINE__, __func__); } txOutputDebugPrintf ("\f\n"); } 15951 #define $meow(...) { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); } 15952 15953 #define $$$( ... ) ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") ) 15954 #define $$$_( ... ) ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__), "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") ) 15955 15956 #define $$$$( ... ) { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__ " DONE]\n\n"); { __VA_ARGS__; } } 15957 #define $$$$_( ... ) { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix ( "[" __TX_FILELINE__ ": " #__VA_ARGS__ " DONE]\n\n"); { __VA_ARGS__; } } 15958 #define $do( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; __VA_ARGS__ 15959 #define $DO( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p; __VA_ARGS__ 15960 #define $Do( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; \ 15961 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__); __VA_ARGS__ 15962 15963 #define $n { ::std::cerr << "\n"; } 15964 #define $nn { ::std::cerr << "\n\n"; } 15965 #define $t { ::std::cerr << "\t"; } 15966 15967 #define _tx$PrefixV( ...) ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " ) : ("[" ) ) 15968 #define _tx$Prefix(var, ...) ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") ) 15969 15970 //----------------------------------------------------------------------------------------------------------------- 15971 15972 // This will never be documented, he-he. Read the source, Luke. 15973 15974 #if defined (_DEBUG) 15975 #define $dbg if (1) 15976 #define $DBG if (1) 15977 #define $debug if (1) 15978 #define $DEBUG if (1) 15979 #define $printf(fmt, ...) if (1) printf ( fmt, ##__VA_ARGS__) 15980 #define $PRINTF(fmt, ...) if (1) fprintf (stderr, fmt, ##__VA_ARGS__) 15981 #else 15982 #define $dbg if (0) 15983 #define $DBG if (0) 15984 #define $debug if (0) 15985 #define $DEBUG if (0) 15986 #define $printf(...) if (0) printf ( fmt, ##__VA_ARGS__) 15987 #define $PRINTF(...) if (0) fprintf (stderr, fmt, ##__VA_ARGS__) 15988 #endif 15989 15990 #define $$d $debug 15991 #define $$w $$$$ 15992 #define $$s __TX_FILELINE__ 15993 #define $$b { txSleep(); DebugBreak(); } 15994 #define $$p { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \ 15995 __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); } 15996 #define $$P ( txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) ) 15997 #define $ppp { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); } 15998 #define $pp { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__, __TX_FUNCTION__); } 15999 #define $p { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__); } 16000 #define $ppp_ { $sy; txPause ("\v[%s ""%s]...", __TX_FILELINE__, __TX_FUNCTION__); } 16001 #define $pp_ { $sy; txPause ("\v[%04d %s]...", __LINE__, __TX_FUNCTION__); } 16002 #define $p_ { $sy; txPause ("\v[%s ""%s()]...", __TX_FILELINE__, __func__); } 16003 #define $P ( txPause ("") ) 16004 16005 //----------------------------------------------------------------------------------------------------------------- 16006 16007 struct _txSaveConsoleAttr 16008 { 16009 unsigned attr_; 16010 16011 _txSaveConsoleAttr() : attr_ (txGetConsoleAttr ()) {} 16012 explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr); } 16013 ~_txSaveConsoleAttr() { txSetConsoleAttr (attr_); } 16014 }; 16015 16016 //----------------------------------------------------------------------------------------------------------------- 16017 16018 struct _txDumpVarSuffix 16019 { 16020 typedef _txDumpVarSuffix this_t; 16021 16022 const char* suffix_; 16023 16024 explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); } 16025 ~_txDumpVarSuffix() { ::std::cerr << suffix_; } 16026 16027 _txDumpVarSuffix (const this_t&) _tx_delete; 16028 this_t& operator = (const this_t&) _tx_delete; 16029 }; 16030 16031 //----------------------------------------------------------------------------------------------------------------- 16032 16033 #define ARGS__ const char* prefix, const char* suffix, std::ios_base::fmtflags flags, int deep 16034 #define ARGS_ const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0 16035 #define VALS_ prefix, suffix, flags, deep 16036 #define ERRPTR_(p) { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; } 16037 16038 template <typename T, typename StreamT> const T& _txDumpVal (const T& value, StreamT& stream, ARGS_); 16039 16040 //----------------------------------------------------------------------------------------------------------------- 16041 16042 template <typename T> inline const T& _txDumpVar (const T& value, ARGS_) { _txDumpVal (value, std:: cerr, VALS_); return value; } 16043 template <typename T> inline T& _txDumpVar ( T& value, ARGS_) { _txDumpVal (value, std:: cerr, VALS_); return value; } 16044 16045 template <int N> inline const char (&_txDumpVar (const char (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; } 16046 template <int N> inline char (&_txDumpVar ( char (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; } 16047 16048 template <int N> inline const wchar_t (&_txDumpVar (const wchar_t (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; } 16049 template <int N> inline wchar_t (&_txDumpVar ( wchar_t (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; } 16050 16051 inline const wchar_t& _txDumpVar (const wchar_t& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16052 inline wchar_t& _txDumpVar ( wchar_t& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16053 16054 inline const wchar_t*& _txDumpVar (const wchar_t*& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16055 inline wchar_t*& _txDumpVar ( wchar_t*& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16056 16057 inline const std::wstring& _txDumpVar (const std::wstring& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16058 inline std::wstring& _txDumpVar ( std::wstring& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16059 16060 //----------------------------------------------------------------------------------------------------------------- 16061 16062 template <typename T, typename StreamT> inline void _txDumpVal (const T& value, StreamT& stream) { stream << value; } 16063 template <typename StreamT> inline void _txDumpVal (const char value, StreamT& stream) { stream << "'" << value << "'"; } 16064 template <typename StreamT> inline void _txDumpVal (const wchar_t value, StreamT& stream) { stream << L"'" << value << L"'"; } 16065 template <typename StreamT> inline void _txDumpVal (const std::string& value, StreamT& stream) { stream << '"' << value << '"'; } 16066 template <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; } 16067 16068 template <typename StreamT> inline void _txDumpVal (const char* value, StreamT& stream) 16069 { 16070 if (_TX_ARGUMENT_FAILED (&stream)) return; 16071 16072 if (!_txIsBadReadPtr (value)) stream << '"' << value << '"'; 16073 else if (!value) stream << "(null)"; 16074 else ERRPTR_ (value); 16075 } 16076 16077 template <typename StreamT> inline void _txDumpVal (const wchar_t* value, StreamT& stream) 16078 { 16079 if (_TX_ARGUMENT_FAILED (&stream)) return; 16080 16081 if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"'; 16082 else if (!value) stream << L"(null)"; 16083 else ERRPTR_ (value); 16084 } 16085 16086 //----------------------------------------------------------------------------------------------------------------- 16087 16088 template <typename T, typename StreamT> 16089 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__) 16090 { 16091 if (_TX_ARGUMENT_FAILED (&stream)) return value; //-V778 16092 if (_TX_ARGUMENT_FAILED ( prefix)) return value; 16093 if (_TX_ARGUMENT_FAILED ( suffix)) return value; 16094 16095 $sc; 16096 if (!deep) stream << prefix; 16097 16098 std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags()); 16099 16100 if (!_txIsBadReadPtr (&value)) 16101 { 16102 _txDumpVal (value, stream); 16103 } 16104 else 16105 ERRPTR_ (&value); 16106 16107 stream.flags (old); 16108 16109 if (!deep) stream << suffix; 16110 16111 return value; 16112 } 16113 16114 //----------------------------------------------------------------------------------------------------------------- 16115 16116 template <typename T, int N> 16117 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N] 16118 { 16119 if (_TX_ARGUMENT_FAILED ( prefix)) return value; 16120 if (_TX_ARGUMENT_FAILED ( suffix)) return value; 16121 16122 std::ostream& stream = std::cerr; 16123 16124 $sc; if (!deep) std::cerr << prefix; 16125 $C; std::cerr << ((deep)? " {" : "{"); 16126 16127 if (!_txIsBadReadPtr (value)) 16128 { 16129 for (int i = 0; ; i++) 16130 { 16131 { $sC; stream << "[" << i << "]="; } 16132 16133 _txDumpVar (value[i], prefix, suffix, flags, deep+1); 16134 16135 if (i >= N-1) break; 16136 16137 stream << ", "; 16138 } 16139 } 16140 else 16141 ERRPTR_ (&value); 16142 16143 $C; std::cerr << "}"; 16144 $c; if (!deep) std::cerr << suffix; 16145 16146 return value; 16147 } 16148 16149 //================================================================================================================= 16150 16151 inline std::ostream& operator << (std::ostream& stream, const POINT& point) 16152 { 16153 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16154 16155 if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }"; // NOLINT (clang-diagnostic-undefined-bool-conversion) 16156 else if (!&point) stream << "(null)"; 16157 else ERRPTR_ (&point); 16158 16159 return stream; 16160 } 16161 16162 inline std::ostream& operator << (std::ostream& stream, const SIZE& size) 16163 { 16164 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16165 16166 if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }"; // NOLINT (clang-diagnostic-undefined-bool-conversion) 16167 else stream << "(null)"; 16168 16169 return stream; 16170 } 16171 16172 inline std::ostream& operator << (std::ostream& stream, const RECT& rect) 16173 { 16174 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16175 16176 if (&rect) stream << "{ left: " << rect.left << ", top: " << rect.top << // NOLINT (clang-diagnostic-undefined-bool-conversion) 16177 ", right: " << rect.right << ", bottom: " << rect.bottom << " }"; 16178 16179 else stream << "(null)"; 16180 16181 return stream; 16182 } 16183 16184 //----------------------------------------------------------------------------------------------------------------- 16185 16186 #undef ARGS__ 16187 #undef ARGS_ 16188 #undef VALS_ 16189 #undef ERRPTR_ 16190 16191 //----------------------------------------------------------------------------------------------------------------- 16193 16194 #endif 16195 16196 //} 16197 //================================================================================================================= 16198 16200 16201 //================================================================================================================= 16202 //{ TXAPI calls tracing 16203 // Трассировка вызовов TXAPI 16204 //================================================================================================================= 16205 16206 #ifndef FOR_DOXYGEN_ONLY 16207 16208 #if defined (_MSC_VER) 16209 #undef _txLocCurSet 16210 #define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, NULL) 16211 #endif 16212 16213 #define txAlphaBlend(...) ( _txLocCurSet(), txAlphaBlend (__VA_ARGS__) ) 16214 #define txArc(...) ( _txLocCurSet(), txArc (__VA_ARGS__) ) 16215 #define txBegin(...) ( _txLocCurSet(), txBegin (__VA_ARGS__) ) 16216 #define txBitBlt(...) ( _txLocCurSet(), txBitBlt (__VA_ARGS__) ) 16217 #define txChord(...) ( _txLocCurSet(), txChord (__VA_ARGS__) ) 16218 #define txCircle(...) ( _txLocCurSet(), txCircle (__VA_ARGS__) ) 16219 #define txClear(...) ( _txLocCurSet(), txClear (__VA_ARGS__) ) 16220 #define txClearConsole(...) ( _txLocCurSet(), txClearConsole (__VA_ARGS__) ) 16221 #define txColor(...) ( _txLocCurSet(), txColor (__VA_ARGS__) ) 16222 #define txCreateCompatibleDC(...) ( _txLocCurSet(), txCreateCompatibleDC (__VA_ARGS__) ) 16223 #define txCreateDIBSection(...) ( _txLocCurSet(), txCreateDIBSection (__VA_ARGS__) ) 16224 #define txCreateExtraWindow(...) ( _txLocCurSet(), txCreateExtraWindow (__VA_ARGS__) ) 16225 #define txCreateWindow(...) ( _txLocCurSet(), txCreateWindow (__VA_ARGS__) ) 16226 #define txDC(...) ( _txLocCurSet(), txDC (__VA_ARGS__) ) 16227 #define txDeleteDC(...) ( _txLocCurSet(), txDeleteDC (__VA_ARGS__) ) 16228 #define txDemangle(...) ( _txLocCurSet(), txDemangle (__VA_ARGS__) ) 16229 #define txDestroyWindow(...) ( _txLocCurSet(), txDestroyWindow (__VA_ARGS__) ) 16230 #define txDisableAutoPause(...) ( _txLocCurSet(), txDisableAutoPause (__VA_ARGS__) ) 16231 #define txDrawText(...) ( _txLocCurSet(), txDrawText (__VA_ARGS__) ) 16232 #define txEllipse(...) ( _txLocCurSet(), txEllipse (__VA_ARGS__) ) 16233 #define txEnd(...) ( _txLocCurSet(), txEnd (__VA_ARGS__) ) 16234 #define txExtractColor(...) ( _txLocCurSet(), txExtractColor (__VA_ARGS__) ) 16235 #define txFillColor(...) ( _txLocCurSet(), txFillColor (__VA_ARGS__) ) 16236 #define txFloodFill(...) ( _txLocCurSet(), txFloodFill (__VA_ARGS__) ) 16237 #define txFontExist(...) ( _txLocCurSet(), txFontExist (__VA_ARGS__) ) 16238 #define txFormat(...) ( _txLocCurSet(), txFormat (__VA_ARGS__) ) 16239 #define txGetAsyncKeyState(...) ( _txLocCurSet(), txGetAsyncKeyState (__VA_ARGS__) ) 16240 #define txGetColor(...) ( _txLocCurSet(), txGetColor (__VA_ARGS__) ) 16241 #define txGetConsoleAttr(...) ( _txLocCurSet(), txGetConsoleAttr (__VA_ARGS__) ) 16242 #define txGetConsoleCursorPos(...) ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) ) 16243 #define txGetConsoleExtent(...) ( _txLocCurSet(), txGetConsoleExtent (__VA_ARGS__) ) 16244 #define txGetConsoleFontSize(...) ( _txLocCurSet(), txGetConsoleFontSize (__VA_ARGS__) ) 16245 #define txGetExtent(...) ( _txLocCurSet(), txGetExtent (__VA_ARGS__) ) 16246 #define txGetExtentX(...) ( _txLocCurSet(), txGetExtentX (__VA_ARGS__) ) 16247 #define txGetExtentY(...) ( _txLocCurSet(), txGetExtentY (__VA_ARGS__) ) 16248 #define txGetFillColor(...) ( _txLocCurSet(), txGetFillColor (__VA_ARGS__) ) 16249 #define txGetFPS(...) ( _txLocCurSet(), txGetFPS (__VA_ARGS__) ) 16250 #define txGetModuleFileName(...) ( _txLocCurSet(), txGetModuleFileName (__VA_ARGS__) ) 16251 #define txGetPixel(...) ( _txLocCurSet(), txGetPixel (__VA_ARGS__) ) 16252 #define txGetTextExtent(...) ( _txLocCurSet(), txGetTextExtent (__VA_ARGS__) ) 16253 #define txGetTextExtentX(...) ( _txLocCurSet(), txGetTextExtentX (__VA_ARGS__) ) 16254 #define txGetTextExtentY(...) ( _txLocCurSet(), txGetTextExtentY (__VA_ARGS__) ) 16255 #define txHSL2RGB(...) ( _txLocCurSet(), txHSL2RGB (__VA_ARGS__) ) 16256 #define txInputBox(...) ( _txLocCurSet(), txInputBox (__VA_ARGS__) ) 16257 #define txLine(...) ( _txLocCurSet(), txLine (__VA_ARGS__) ) 16258 #define txLoadImage(...) ( _txLocCurSet(), txLoadImage (__VA_ARGS__) ) 16259 #define txLock(...) ( _txLocCurSet(), txLock (__VA_ARGS__) ) 16260 #define txMessageBox(...) ( _txLocCurSet(), txMessageBox (__VA_ARGS__) ) 16261 #define txMouseButtons(...) ( _txLocCurSet(), txMouseButtons (__VA_ARGS__) ) 16262 #define txMousePos(...) ( _txLocCurSet(), txMousePos (__VA_ARGS__) ) 16263 #define txMouseX(...) ( _txLocCurSet(), txMouseX (__VA_ARGS__) ) 16264 #define txMouseY(...) ( _txLocCurSet(), txMouseY (__VA_ARGS__) ) 16265 #define txNotifyIcon(...) ( _txLocCurSet(), txNotifyIcon (__VA_ARGS__) ) 16266 #define txOK(...) ( _txLocCurSet(), txOK (__VA_ARGS__) ) 16267 #define txOutputDebugPrintf(...) ( _txLocCurSet(), txOutputDebugPrintf (__VA_ARGS__) ) 16268 #define txPause(...) ( _txLocCurSet(), txPause (__VA_ARGS__) ) 16269 #define txPie(...) ( _txLocCurSet(), txPie (__VA_ARGS__) ) 16270 #define txPixel(...) ( _txLocCurSet(), txPixel (__VA_ARGS__) ) 16271 #define txPlaySound(...) ( _txLocCurSet(), txPlaySound (__VA_ARGS__) ) 16272 #define txPlayVideo(...) ( _txLocCurSet(), txPlayVideo (__VA_ARGS__) ) 16273 #define txPolygon(...) ( _txLocCurSet(), txPolygon (__VA_ARGS__) ) 16274 #define txPrintf(...) ( _txLocCurSet(), txPrintf (__VA_ARGS__) ) 16275 #define txQueryPerformance(...) ( _txLocCurSet(), txQueryPerformance (__VA_ARGS__) ) 16276 #define txRectangle(...) ( _txLocCurSet(), txRectangle (__VA_ARGS__) ) 16277 #define txRedrawWindow(...) ( _txLocCurSet(), txRedrawWindow (__VA_ARGS__) ) 16278 #define txRegisterClass(...) ( _txLocCurSet(), txRegisterClass (__VA_ARGS__) ) 16279 #define txRegQuery(...) ( _txLocCurSet(), txRegQuery (__VA_ARGS__) ) 16280 #define txReopenStdio(...) ( _txLocCurSet(), txReopenStdio (__VA_ARGS__) ) 16281 #define txRGB2HSL(...) ( _txLocCurSet(), txRGB2HSL (__VA_ARGS__) ) 16282 #define txSaveImage(...) ( _txLocCurSet(), txSaveImage (__VA_ARGS__) ) 16283 #define txSelectFont(...) ( _txLocCurSet(), txSelectFont (__VA_ARGS__) ) 16284 #define txSelectObject(...) ( _txLocCurSet(), txSelectObject (__VA_ARGS__) ) 16285 #define txSetColor(...) ( _txLocCurSet(), txSetColor (__VA_ARGS__) ) 16286 #define txSetConsoleAttr(...) ( _txLocCurSet(), txSetConsoleAttr (__VA_ARGS__) ) 16287 #define txSetConsoleCursorPos(...) ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) ) 16288 #define txSetDefaults(...) ( _txLocCurSet(), txSetDefaults (__VA_ARGS__) ) 16289 #define txSetFillColor(...) ( _txLocCurSet(), txSetFillColor (__VA_ARGS__) ) 16290 #define txSetLocale(...) ( _txLocCurSet(), txSetLocale (__VA_ARGS__) ) 16291 #define txSetPixel(...) ( _txLocCurSet(), txSetPixel (__VA_ARGS__) ) 16292 #define txSetProgress(...) ( _txLocCurSet(), txSetProgress (__VA_ARGS__) ) 16293 #define txSetTextAlign(...) ( _txLocCurSet(), txSetTextAlign (__VA_ARGS__) ) 16294 #define txSetWindowsHook(...) ( _txLocCurSet(), txSetWindowsHook (__VA_ARGS__) ) 16295 #define txSleep(...) ( _txLocCurSet(), txSleep (__VA_ARGS__) ) 16296 #define txSpeak(...) ( _txLocCurSet(), txSpeak (__VA_ARGS__) ) 16297 #define txTextCursor(...) ( _txLocCurSet(), txTextCursor (__VA_ARGS__) ) 16298 #define txTextOut(...) ( _txLocCurSet(), txTextOut (__VA_ARGS__) ) 16299 #define txTransparentBlt(...) ( _txLocCurSet(), txTransparentBlt (__VA_ARGS__) ) 16300 #define txTriangle(...) ( _txLocCurSet(), txTriangle (__VA_ARGS__) ) 16301 #define txUnlock(...) ( _txLocCurSet(), txUnlock (__VA_ARGS__) ) 16302 #define txUpdateWindow(...) ( _txLocCurSet(), txUpdateWindow (__VA_ARGS__) ) 16303 #define txUseAlpha(...) ( _txLocCurSet(), txUseAlpha (__VA_ARGS__) ) 16304 #define txVersion(...) ( _txLocCurSet(), txVersion (__VA_ARGS__) ) 16305 #define txVersionNumber(...) ( _txLocCurSet(), txVersionNumber (__VA_ARGS__) ) 16306 #define txWindow(...) ( _txLocCurSet(), txWindow (__VA_ARGS__) ) 16307 #define tx_fpreset(...) ( _txLocCurSet(), tx_fpreset (__VA_ARGS__) ) 16308 #define tx_glGetError(...) ( _txLocCurSet(), tx_glGetError (__VA_ARGS__) ) 16309 #define _txDump(...) ( _txLocCurSet(), _txDump (__VA_ARGS__) ) 16310 #define _txStackBackTrace(...) ( _txLocCurSet(), _txStackBackTrace (__VA_ARGS__) ) 16311 16312 #endif 16313 16314 //} 16315 //================================================================================================================= 16316 16318 //} 16319 //================================================================================================================= 16320 16321 //----------------------------------------------------------------------------------------------------------------- 16322 //{ The namespaces 16323 //----------------------------------------------------------------------------------------------------------------- 16324 16327 _TX_END_NAMESPACE 16328 16331 using namespace TX; // Allow easy usage of TXLib functions 16332 16333 using ::std::cin; // Predefined usings to avoid "using namespace std" 16334 using ::std::cout; 16335 using ::std::cerr; 16336 using ::std::string; 16337 using ::std::wcin; 16338 using ::std::wcout; 16339 using ::std::wcerr; 16340 using ::std::wstring; 16341 16342 //} 16343 //----------------------------------------------------------------------------------------------------------------- 16344 16345 //----------------------------------------------------------------------------------------------------------------- 16346 //{ Compiler- and platform-specific 16347 // Адаптация к компиляторам и платформам 16348 //----------------------------------------------------------------------------------------------------------------- 16350 16351 #if defined (_GCC_VER) 16352 16353 #pragma GCC optimize "strict-aliasing" 16354 16355 #pragma GCC pop_options 16356 #pragma GCC diagnostic pop 16357 16358 #endif 16359 16360 #if defined (_CLANG_VER) 16361 16362 #pragma clang diagnostic pop 16363 16364 #endif 16365 16366 //----------------------------------------------------------------------------------------------------------------- 16367 16368 #if defined (_MSC_VER) 16369 16370 #pragma warning (pop) // Restoring maximum level 16371 16372 #endif 16373 16374 #if defined (__INTEL_COMPILER) 16375 16376 #pragma warning (default: 174) // Remark: expression has no effect 16377 #pragma warning (default: 304) // Remark: access control not specified ("public" by default) 16378 #pragma warning (default: 444) // Remark: destructor for base class "..." is not virtual 16379 #pragma warning (default: 522) // Remark: function redeclared "inline" after being called 16380 #pragma warning (default: 1684) // Conversion from pointer to same-sized integral type (potential portability problem) 16381 16382 #pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order 16383 16384 #endif 16385 16387 //} 16388 //----------------------------------------------------------------------------------------------------------------- 16389 16390 #endif // __TXLIB_H_INCLUDED 16391 16392 //================================================================================================================= 16393 // EOF 16394 //================================================================================================================= 16395 16396 16397 16398 16399