![]() |
TX Library Help – Version: 00173a, Revision: 174
|
00001 //================================================================================================================= 00002 // TXLib.h - Библиотека Тупого Художника (The Dumb Artist Library, TX Library, TXLib) - (C) Ilya Dedinsky 00003 //================================================================================================================= 00004 // [These sections are for folding control in Code::Blocks] [$Date: 2025-05-31 01:13:58 +0400 $] 00005 // [Best viewed with "Fold all on file open" option enabled] [Best screen/page width = 120 chars] 00006 // 00007 // [If RUSSIAN CHARS below are UNREADABLE, check this file codepage. It should be CP1251, NOT UTF-8 etc.] 00008 //{ [Use RELOAD options in your IDE or editor (CLion / Visual Studio Code / ...), and do NOT use Convert.] 00009 //================================================================================================================= 00102 // $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $ 00103 //----------------------------------------------------------------------------------------------------------------- 00110 //} 00111 //================================================================================================================= 00112 00113 #if !defined (__TXLIB_H_INCLUDED) // <<< THE CODE IS HERE, UNFOLD IT <<< 00114 #define __TXLIB_H_INCLUDED 00115 00116 //----------------------------------------------------------------------------------------------------------------- 00117 //{ Version information and configuration 00118 //----------------------------------------------------------------------------------------------------------------- 00119 00120 //{---------------------------------------------------------------------------------------------------------------- 00142 //}---------------------------------------------------------------------------------------------------------------- 00144 00145 #define _TX_VER _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-05-31 01:13:58 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00146 #define _TX_VERSION _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-05-31 01:13:58 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00147 #define _TX_AUTHOR _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-05-31 01:13:58 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00148 00150 #define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2) ((0x##ver##u << 16) | 0x##rev##u) 00151 #define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2) "TXLib [Ver: " #ver ", Rev: " #rev ", Date: " #date "]" 00152 #define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2) "Copyright (C) " auth 00153 00154 00156 //{---------------------------------------------------------------------------------------------------------------- 00163 //}---------------------------------------------------------------------------------------------------------------- 00164 00165 #if !defined (_TX_MODULE) 00166 #define _TX_MODULE "TXLib" 00167 #endif 00168 00169 //{---------------------------------------------------------------------------------------------------------------- 00173 //}---------------------------------------------------------------------------------------------------------------- 00174 00175 #if defined (__GNUC__) 00176 00177 #define _GCC_VER ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ ) 00178 00179 #define __TX_COMPILER__ "GNU g++ " TX_QUOTE (__GNUC__) "." \ 00180 TX_QUOTE (__GNUC_MINOR__) "." \ 00181 TX_QUOTE (__GNUC_PATCHLEVEL__) \ 00182 ", std=" TX_QUOTE (__cplusplus) 00183 00184 #elif defined (__clang__) || defined (__clang_major__) 00185 00186 #define _CLANG_VER ( __clang_major__*100 + __clang_minor__*10 + __clang_patchlevel__ ) 00187 00188 #define __TX_COMPILER__ "Clang " TX_QUOTE (__clang_major__) "." \ 00189 TX_QUOTE (__clang_minor__) "." \ 00190 TX_QUOTE (__clang_patchlevel__) \ 00191 ", std=" TX_QUOTE (__cplusplus) 00192 #elif defined (_MSC_VER) 00193 00194 #define __TX_COMPILER__ "MSVS " TX_QUOTE (_MSC_VER) \ 00195 ", std=" TX_QUOTE (__cplusplus) 00196 00197 #elif defined (__INTEL_COMPILER) 00198 00199 #define __TX_COMPILER__ "Intel C++ " TX_QUOTE (__INTEL_COMPILER) \ 00200 ", std=" TX_QUOTE (__cplusplus) 00201 #else 00202 00203 #define __TX_COMPILER__ "Unknown C++, std=" TX_QUOTE (__cplusplus) 00204 #endif 00205 00207 00208 #define TX_QUOTE(sym) _TX_QUOTE (sym) 00209 #define _TX_QUOTE(sym) #sym 00210 00211 #define TX_JOIN(sym1, sym2) _TX_JOIN (sym1, sym2) 00212 #define _TX_JOIN(sym1, sym2) sym1 ## sym2 00213 00215 00216 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 00217 00218 #define _TX_CPP11 1 00219 #endif 00220 00221 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1900) // MSVC 2015 00222 00223 #define _TX_CPP11_MSVC15 1 00224 #endif 00225 00226 //{---------------------------------------------------------------------------------------------------------------- 00230 //}---------------------------------------------------------------------------------------------------------------- 00231 00232 #if !defined (NDEBUG) && defined (_DEBUG) 00233 #define _TX_BUILDMODE "DEBUG" 00234 00235 #elif !defined (NDEBUG) && !defined (_DEBUG) 00236 #define _TX_BUILDMODE "Debug" 00237 00238 #elif defined (NDEBUG) 00239 #define _TX_BUILDMODE "Release" 00240 #endif 00241 00242 //{---------------------------------------------------------------------------------------------------------------- 00246 //}---------------------------------------------------------------------------------------------------------------- 00247 00248 #define __TX_FILELINE__ __FILE__ ":" TX_QUOTE (__LINE__) 00249 00250 //{---------------------------------------------------------------------------------------------------------------- 00258 //}---------------------------------------------------------------------------------------------------------------- 00259 00260 #if defined (__GNUC__) || defined (__clang__) || defined (__clang_major__) 00261 #define __TX_FUNCTION__ __PRETTY_FUNCTION__ 00262 00263 #elif defined (__FUNCSIG__) 00264 #define __TX_FUNCTION__ __FUNCSIG__ 00265 00266 #elif defined (__FUNCTION__) 00267 #define __TX_FUNCTION__ __FUNCTION__ 00268 00269 #elif defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 600) 00270 #define __TX_FUNCTION__ __FUNCTION__ 00271 00272 #elif defined (__BORLANDC__) && (__BORLANDC__ >= 0x550) 00273 #define __TX_FUNCTION__ __FUNC__ 00274 00275 #elif defined (__cplusplus) && (__cplusplus >= 199711L) 00276 #define __TX_FUNCTION__ __func__ 00277 00278 #elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 00279 #define __TX_FUNCTION__ __func__ 00280 00281 #elif defined (__PYTHON__) 00282 #error No Python. No. Using parseltongue languages can lead you to Slytherin. 00283 00284 #else 00285 #define __TX_FUNCTION__ "(" __TX_FILELINE__ ")" 00286 00287 #endif 00288 00289 #if !defined (__func__) && defined (__FUNCTION__) 00290 #define __func__ __FUNCTION__ 00291 00292 #endif 00293 00294 //} 00295 //----------------------------------------------------------------------------------------------------------------- 00296 00297 //----------------------------------------------------------------------------------------------------------------- 00298 //{ Compiler- and platform-specific 00300 //----------------------------------------------------------------------------------------------------------------- 00302 00303 #if !defined (__cplusplus) 00304 00305 #ifdef __GNUC__ 00306 #error 00307 #error --------------------------------------------------------------------------------------- 00308 #endif 00309 #error TXLib.h: Must use C++ to compile TXLib.h. Now you are using C only. 00310 #error 00311 #error CHECK source file EXTENSION. Maybe it is ".C". It must be ".CPP". 00312 #error If your file is named, for example, "Untitled.C", go to menu [File], 00313 #error then [Save As] and rename it to "Untitled.CPP". Please do NOT use spaces. 00314 #error --------------------------------------------------------------------------------------- 00315 #error 00316 00317 #endif 00318 00319 //----------------------------------------------------------------------------------------------------------------- 00320 00321 #if !defined (WIN32) && !defined (__WIN32__) && !defined(_WIN32) && !defined(_WIN32_WINNT) && !defined (__CYGWIN__) 00322 00323 #ifdef __GNUC__ 00324 #error 00325 #error --------------------------------------------------------------------------------------- 00326 #endif 00327 #error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW or Cygwin) is the only supported OS, sorry. 00328 #error 00329 #error In Linux or MacOS, you should write your own TXLib and share it with your friends, or use wine. 00330 #error --------------------------------------------------------------------------------------- 00331 #error 00332 00333 #endif 00334 00335 //----------------------------------------------------------------------------------------------------------------- 00336 00337 #if defined (UNICODE) || defined (_UNICODE) 00338 00339 #ifdef __GNUC__ 00340 #warning TXLib.h: Disabling the UNICODE 00341 #endif 00342 00343 #undef UNICODE // Burn Unicode, burn 00344 #undef _UNICODE 00345 00346 #if defined (_WINDOWS_H) || defined (_INC_WINDOWS) || defined (_WINDOWS_) || defined (__WINDOWS__) 00347 00348 #ifdef __GNUC__ 00349 #error 00350 #error --------------------------------------------------------------------------------------- 00351 #endif 00352 #error TXLib.h: Should include "TXLib.h" BEFORE or INSTEAD of <Windows.h> in UNICODE mode. 00353 #error 00354 #error REARRANGE your #include directives, or DISABLE the UNICODE mode by #undef UNICODE/_UNICODE. 00355 #error --------------------------------------------------------------------------------------- 00356 #error 00357 00358 #endif 00359 00360 #endif 00361 00362 //----------------------------------------------------------------------------------------------------------------- 00363 00364 #if defined (__STRICT_ANSI__) && (_GCC_VER < 1120) // Try to extend strict ANSI rules 00365 00366 #undef __STRICT_ANSI__ 00367 #define __STRICT_ANSI__UNDEFINED 00368 00369 #if defined (_STRING_H_) || defined (_INC_STRING) || defined (_STDIO_H_) || defined (_INC_STDIO) 00370 00371 #ifdef __GNUC__ 00372 #error 00373 #error --------------------------------------------------------------------------------------- 00374 #endif 00375 #error TXLib.h: Should include "TXLib.h" BEFORE <string.h> or <stdio.h> in Strict ANSI mode. 00376 #error 00377 #error REARRANGE your #include directives, or DISABLE ANSI-compliancy by #undef __STRICT_ANSI__. 00378 #error --------------------------------------------------------------------------------------- 00379 #error 00380 00381 #endif 00382 00383 #endif 00384 00385 //----------------------------------------------------------------------------------------------------------------- 00386 00387 #if defined (__GNUC__) 00388 00389 #pragma GCC diagnostic ignored "-Wpragmas" 00390 00391 #pragma GCC diagnostic warning "-Wall" 00392 #pragma GCC diagnostic warning "-Weffc++" 00393 #pragma GCC diagnostic warning "-Wextra" 00394 00395 #pragma GCC diagnostic warning "-Waggressive-loop-optimizations" 00396 #pragma GCC diagnostic warning "-Walloc-zero" 00397 #pragma GCC diagnostic warning "-Walloca" 00398 #pragma GCC diagnostic warning "-Walloca-larger-than=8192" 00399 #pragma GCC diagnostic warning "-Warray-bounds" 00400 #pragma GCC diagnostic warning "-Wcast-align" 00401 #pragma GCC diagnostic warning "-Wcast-qual" 00402 #pragma GCC diagnostic warning "-Wchar-subscripts" 00403 #pragma GCC diagnostic warning "-Wconditionally-supported" 00404 #pragma GCC diagnostic warning "-Wconversion" 00405 #pragma GCC diagnostic warning "-Wctor-dtor-privacy" 00406 #pragma GCC diagnostic warning "-Wdangling-else" 00407 #pragma GCC diagnostic warning "-Wduplicated-branches" 00408 #pragma GCC diagnostic warning "-Wempty-body" 00409 #pragma GCC diagnostic warning "-Wfloat-equal" 00410 #pragma GCC diagnostic warning "-Wformat-nonliteral" 00411 #pragma GCC diagnostic warning "-Wformat-overflow=2" 00412 #pragma GCC diagnostic warning "-Wformat-security" 00413 #pragma GCC diagnostic warning "-Wformat-signedness" 00414 #pragma GCC diagnostic warning "-Wformat-truncation=2" 00415 #pragma GCC diagnostic warning "-Wformat=2" 00416 #pragma GCC diagnostic warning "-Wlarger-than=8192" 00417 #pragma GCC diagnostic warning "-Wlogical-op" 00418 #pragma GCC diagnostic warning "-Wmismatched-tags" 00419 #pragma GCC diagnostic warning "-Wmissing-declarations" 00420 #pragma GCC diagnostic warning "-Wnarrowing" 00421 #pragma GCC diagnostic warning "-Wnon-virtual-dtor" 00422 #pragma GCC diagnostic warning "-Wnonnull" 00423 #pragma GCC diagnostic warning "-Wopenmp-simd" 00424 #pragma GCC diagnostic warning "-Woverloaded-virtual" 00425 #pragma GCC diagnostic warning "-Wpacked" 00426 #pragma GCC diagnostic warning "-Wpointer-arith" 00427 #pragma GCC diagnostic warning "-Wredundant-decls" 00428 #pragma GCC diagnostic warning "-Wredundant-tags" 00429 #pragma GCC diagnostic warning "-Wrestrict" 00430 #pragma GCC diagnostic warning "-Wshadow" 00431 #pragma GCC diagnostic warning "-Wsign-promo" 00432 #pragma GCC diagnostic warning "-Wstack-usage=8192" 00433 #pragma GCC diagnostic warning "-Wstrict-aliasing" 00434 #pragma GCC diagnostic warning "-Wstrict-null-sentinel" 00435 #pragma GCC diagnostic warning "-Wstrict-overflow=2" 00436 #pragma GCC diagnostic warning "-Wstringop-overflow=4" 00437 #pragma GCC diagnostic warning "-Wsuggest-attribute=noreturn" 00438 #pragma GCC diagnostic warning "-Wsuggest-final-methods" 00439 #pragma GCC diagnostic warning "-Wsuggest-final-types" 00440 #pragma GCC diagnostic warning "-Wsuggest-override" 00441 #pragma GCC diagnostic warning "-Wswitch-default" 00442 #pragma GCC diagnostic warning "-Wswitch-enum" 00443 #pragma GCC diagnostic warning "-Wsync-nand" 00444 #pragma GCC diagnostic warning "-Wundef" 00445 #pragma GCC diagnostic warning "-Wunused" 00446 #pragma GCC diagnostic warning "-Wvarargs" 00447 #pragma GCC diagnostic warning "-Wvla-larger-than=8192" 00448 00449 #pragma GCC diagnostic error "-Wsizeof-array-argument" 00450 00451 #pragma GCC diagnostic ignored "-Waddress" 00452 #pragma GCC diagnostic ignored "-Winline" 00453 #pragma GCC diagnostic ignored "-Wliteral-suffix" 00454 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 00455 #pragma GCC diagnostic ignored "-Wnonnull-compare" 00456 #pragma GCC diagnostic ignored "-Wold-style-cast" 00457 #pragma GCC diagnostic ignored "-Wunreachable-code" 00458 #pragma GCC diagnostic ignored "-Wunused-const-variable" 00459 #pragma GCC diagnostic ignored "-Wunused-function" 00460 #pragma GCC diagnostic ignored "-Wvariadic-macros" 00461 00462 #pragma GCC diagnostic warning "-Wpragmas" 00463 00464 //{ These warning settings for TXLib.h only and will be re-enabled at end of file: 00465 00466 #pragma GCC push_options 00467 #pragma GCC diagnostic push 00468 00469 #pragma GCC diagnostic ignored "-Wpragmas" 00470 00471 #pragma GCC diagnostic ignored "-Wpedantic" 00472 #pragma GCC diagnostic ignored "-Waddress" 00473 #pragma GCC diagnostic ignored "-Warray-bounds" 00474 #pragma GCC diagnostic ignored "-Wclobbered" 00475 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00476 #pragma GCC diagnostic ignored "-Wfloat-equal" 00477 #pragma GCC diagnostic ignored "-Wformat-nonliteral" 00478 #pragma GCC diagnostic ignored "-Wlarger-than=" 00479 #pragma GCC diagnostic ignored "-Wmisleading-indentation" 00480 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 00481 #pragma GCC diagnostic ignored "-Wredundant-decls" 00482 #pragma GCC diagnostic ignored "-Wshadow" 00483 #pragma GCC diagnostic ignored "-Wsign-conversion" 00484 #pragma GCC diagnostic ignored "-Wstrict-aliasing" 00485 #pragma GCC diagnostic ignored "-Wsuggest-override" 00486 #pragma GCC diagnostic ignored "-Wunused-label" // Just for fun in _txCanvas_OnCmdAbout() 00487 #pragma GCC diagnostic ignored "-Wunused-value" 00488 #pragma GCC diagnostic ignored "-Wformat-zero-length" 00489 #pragma GCC diagnostic ignored "-Wpacked-not-aligned" 00490 #pragma GCC optimize "no-strict-aliasing" 00491 00492 #pragma GCC diagnostic warning "-Wpragmas" 00493 00494 #if defined (__CYGWIN__) && !defined (_TX_TESTING) 00495 #pragma GCC system_header // This is not a fair play, but this is the only way to deal with Cygwin :( 00496 #endif 00497 00498 //} 00499 00500 #define _tx_thread __thread 00501 #define _tx_decltype(value) __decltype (value) 00502 00503 #define _FORTIFY_SOURCE 2 00504 00505 #ifndef MINGW_HAS_SECURE_API 00506 #define MINGW_HAS_SECURE_API 1 00507 #endif 00508 00509 #if defined (TX_USE_SFML) 00510 #define _GLIBCXX_NDEBUG 00511 #endif 00512 00513 #ifndef _GLIBCXX_NDEBUG // TXLib enables _GLIBCXX_DEBUG by default. When using third-party libraries 00514 #define _GLIBCXX_DEBUG // compiled without _GLIBCXX_DEBUG (SFML, for example), #define _GLIBCXX_NDEBUG 00515 #define _GLIBCXX_DEBUG_PEDANTIC // *before* including TXLib.h. 00516 #endif 00517 00518 #if defined (_WIN64) // removed in x86 because printf ("%g", double) failure, this prints 0 always 00519 #ifndef __USE_MINGW_ANSI_STDIO 00520 #define __USE_MINGW_ANSI_STDIO 1 00521 #endif 00522 #endif 00523 00524 template <typename T> 00525 inline T _txNOP (T value) { return value; } // To suppress performance warnings in assert etc. 00526 00527 // From MinGW\include\float.h which is replaced by MinGW\lib\gcc\i686-pc-mingw32\x.x.x\include\float.h 00528 extern "C" __declspec (dllimport) unsigned __cdecl _controlfp (unsigned control, unsigned mask); 00529 extern "C" void __cdecl _fpreset (); 00530 00531 #else 00532 00533 #define __attribute__( attr ) 00534 #define _txNOP( value ) ( value ) 00535 00536 #endif 00537 00538 //----------------------------------------------------------------------------------------------------------------- 00539 00540 #if defined (__clang__) || defined (__clang_major__) 00541 00542 #pragma clang diagnostic ignored "-Wunknown-pragmas" 00543 00544 #pragma clang diagnostic warning "-Wall" 00545 #pragma clang diagnostic warning "-Weffc++" 00546 #pragma clang diagnostic warning "-Wextra" 00547 00548 #pragma clang diagnostic warning "-Wcast-qual" 00549 #pragma clang diagnostic warning "-Wchar-subscripts" 00550 #pragma clang diagnostic warning "-Wconversion" 00551 #pragma clang diagnostic warning "-Wctor-dtor-privacy" 00552 #pragma clang diagnostic warning "-Wempty-body" 00553 #pragma clang diagnostic warning "-Wfloat-equal" 00554 #pragma clang diagnostic warning "-Wformat" 00555 #pragma clang diagnostic warning "-Wformat-nonliteral" 00556 #pragma clang diagnostic warning "-Wformat-security" 00557 #pragma clang diagnostic warning "-Wmissing-declarations" 00558 #pragma clang diagnostic warning "-Wnon-virtual-dtor" 00559 #pragma clang diagnostic warning "-Woverloaded-virtual" 00560 #pragma clang diagnostic warning "-Wpacked" 00561 #pragma clang diagnostic warning "-Wpointer-arith" 00562 #pragma clang diagnostic warning "-Wredundant-decls" 00563 #pragma clang diagnostic warning "-Wshadow" 00564 #pragma clang diagnostic warning "-Wsign-promo" 00565 #pragma clang diagnostic warning "-Wstrict-aliasing" 00566 #pragma clang diagnostic warning "-Wstrict-overflow" 00567 #pragma clang diagnostic warning "-Wswitch-default" 00568 #pragma clang diagnostic warning "-Wswitch-enum" 00569 #pragma clang diagnostic warning "-Wunused" 00570 00571 #pragma clang diagnostic ignored "-Winvalid-source-encoding" 00572 #pragma clang diagnostic ignored "-Wunused-const-variable" 00573 #pragma clang diagnostic ignored "-Wunused-variable" 00574 00575 #pragma clang diagnostic warning "-Wunknown-pragmas" 00576 00577 //{ These warning settings for TXLib.h only and will be re-enabled at end of file: 00578 00579 #pragma clang diagnostic push 00580 00581 #pragma clang diagnostic ignored "-Wunknown-pragmas" 00582 00583 #pragma clang diagnostic ignored "-Wpedantic" 00584 #pragma clang diagnostic ignored "-Wcast-align" 00585 #pragma clang diagnostic ignored "-Wfloat-conversion" 00586 #pragma clang diagnostic ignored "-Wmicrosoft-cast" 00587 #pragma clang diagnostic ignored "-Wmisleading-indentation" 00588 #pragma clang diagnostic ignored "-Wmissing-braces" 00589 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 00590 #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 00591 #pragma clang diagnostic ignored "-Wsign-compare" 00592 #pragma clang diagnostic ignored "-Wsign-conversion" 00593 #pragma clang diagnostic ignored "-Wstring-plus-int" 00594 #pragma clang diagnostic ignored "-Wundef" 00595 #pragma clang diagnostic ignored "-Wundefined-bool-conversion" 00596 #pragma clang diagnostic ignored "-Wunused-function" 00597 #pragma clang diagnostic ignored "-Wunused-value" 00598 #pragma clang diagnostic ignored "-Wvariadic-macros" 00599 00600 #pragma clang diagnostic warning "-Wunknown-pragmas" 00601 00602 //{ CLang-Tidy options 00603 // 00604 // *,-cert-dcl50-cpp,-cert-dcl58-cpp,-cert-err52-cpp,-cert-err58-cpp,-cert-flp30-c,-cert-msc30-c,-cert-msc32-c, 00605 // -cert-msc50-cpp,-cert-msc51-cpp,-clang-analyzer-core.DivideZero,-cppcoreguidelines-avoid-c-arrays, 00606 // -cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage, 00607 // -cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-no-malloc, 00608 // -cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic, 00609 // -cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access, 00610 // -cppcoreguidelines-pro-type-vararg,-fuchsia-default-arguments-calls,-fuchsia-default-arguments-declarations, 00611 // -fuchsia-overloaded-operator,-google-build-using-namespace,-google-global-names-in-headers,-google-runtime-int, 00612 // -google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments, 00613 // -hicpp-avoid-c-arrays,-hicpp-avoid-goto,-hicpp-braces-around-statements,-hicpp-deprecated-headers,-hicpp-no-array-decay, 00614 // -hicpp-signed-bitwise,-hicpp-use-equals-delete,-hicpp-use-nullptr,-hicpp-vararg,-llvm-include-order,-hicpp-no-malloc, 00615 // -llvm-namespace-comment,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-use-auto, 00616 // -modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-use-default-member-init,-hicpp-use-auto, 00617 // -modernize-use-equals-delete,-modernize-use-nullptr,-modernize-use-trailing-return-type,-modernize-use-using, 00618 // -readability-braces-around-statements,-readability-else-after-return,-readability-implicit-bool-conversion, 00619 // -readability-isolate-declaration,-readability-magic-numbers,-readability-named-parameter,-modernize-loop-convert 00620 //} 00621 00622 //} 00623 00624 #endif 00625 00626 //----------------------------------------------------------------------------------------------------------------- 00627 00628 #if defined (_MSC_VER) 00629 00630 #pragma warning (push, 4) // Set maximum warning level. This 'push' is to set the level only. It will NOT be popped. 00631 00632 #pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning 00633 00634 #pragma warning (disable: 4514) // Unreferenced inline function has been removed 00635 #pragma warning (disable: 4710) // Function not inlined 00636 #pragma warning (disable: 4786) // Identifier was truncated to '255' characters in the debug information 00637 00638 #pragma warning (error: 4715) // Not all control paths return a value 00639 00640 #pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665 00641 00642 #pragma warning (disable: 26473) // Don't cast between pointer types where the source type and the target type are the same (type.1). 00643 #pragma warning (disable: 26475) // Do not use function style C-casts (es.49). 00644 #pragma warning (disable: 26477) // Use 'nullptr' rather than 0 or NULL (es.47). 00645 #pragma warning (disable: 26481) // Don't use pointer arithmetic. Use span instead (bounds.1). 00646 #pragma warning (disable: 26826) // Don't use C-style variable arguments (f.55). 00647 00648 // These warning settings for TXLib.h only and will be re-enabled at end of file: 00649 00650 #pragma warning (push) 00651 00652 #pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning 00653 00654 #pragma warning (disable: 4091) // 'typedef': ignored on left of '...' when no variable is declared 00655 #pragma warning (disable: 4124) // Using __fastcall with stack checking is ineffective 00656 #pragma warning (disable: 4127) // Conditional expression is constant 00657 #pragma warning (disable: 4200) // Nonstandard extension used: zero-sized array in struct/union 00658 #pragma warning (disable: 4201) // Nonstandard extension used: nameless struct/union 00659 #pragma warning (disable: 4351) // New behavior: elements of array will be default initialized 00660 #pragma warning (disable: 4480) // Nonstandard extension used: specifying underlying type for enum 'type' 00661 #pragma warning (disable: 4481) // Nonstandard extension used: override specifier 'override' 00662 #pragma warning (disable: 4555) // Result of expression not used 00663 #pragma warning (disable: 4611) // Interaction between '_setjmp' and C++ object destruction is non-portable 00664 #pragma warning (disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified 00665 #pragma warning (disable: 6269) // Possibly incorrect order of operations: dereference ignored 00666 #pragma warning (disable: 6285) // (<non-zero constant>) || (<non-zero constant>) is always a non-zero constant. Did you intend to use bitwize-and operator? 00667 #pragma warning (disable: 6319) // Use of the comma-operator in a tested expression causes the left argument to be ignored when it has no side-effects 00668 #pragma warning (disable: 6326) // Potential comparison of a constant with another constant 00669 #pragma warning (disable: 6553) // The annotation for function 'func' on _Param_(N) does not apply to a value type. 00670 #pragma warning (disable: 26135) // Missing locking annotation 00671 #pragma warning (disable: 26400) // Do not assign the result of an allocation or a function call with an owner<T> return value to a raw pointer, use owner<T> instead (i.11). 00672 #pragma warning (disable: 26401) // Do not delete a raw pointer that is not an owner<T> (i.11). 00673 #pragma warning (disable: 26403) // Reset or explicitly delete an owner<T> pointer 'name' (r.3). 00674 #pragma warning (disable: 26408) // Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10). 00675 #pragma warning (disable: 26409) // Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11). 00676 #pragma warning (disable: 26426) // Global initializer calls a non-constexpr function 'name' (i.22). 00677 #pragma warning (disable: 26429) // Symbol 'name' is never tested for nullness, it can be marked as not_null (f.23). 00678 #pragma warning (disable: 26430) // Symbol 'name' is not tested for nullness on all paths (f.23). 00679 #pragma warning (disable: 26432) // If you define or delete any default operation in the type 'struct 'name'', define or delete them all (c.21). 00680 #pragma warning (disable: 26435) // Function 'name' should specify exactly one of 'virtual', 'override', or 'final' (c.128). 00681 #pragma warning (disable: 26438) // Avoid 'goto' (es.76). 00682 #pragma warning (disable: 26440) // Function 'name' can be declared 'noexcept' (f.6). 00683 #pragma warning (disable: 26446) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4). 00684 #pragma warning (disable: 26447) // The function is declared 'noexcept' but calls function 'func' which may throw exceptions (f.6). 00685 #pragma warning (disable: 26448) // Consider using gsl::finally if final action is intended (gsl.util). 00686 #pragma warning (disable: 26451) // Arithmetic overflow: Using operator 'op' on a n-byte value and then casting the result to a m-byte value. Cast the value to the wider type before calling operator 'op' to avoid overflow (io.2). 00687 #pragma warning (disable: 26455) // Default constructor may not throw. Declare it 'noexcept' (f.6). 00688 #pragma warning (disable: 26457) // (void) should not be used to ignore return values, use 'std::ignore =' instead (es.48) 00689 #pragma warning (disable: 26460) // The reference argument 'stream' for function 'name' can be marked as const (con.3). 00690 #pragma warning (disable: 26461) // The pointer argument 'name' for function 'name' can be marked as a pointer to const (con.3). 00691 #pragma warning (disable: 26462) // The value pointed to by 'name' is assigned only once, mark it as a pointer to const (con.4). 00692 #pragma warning (disable: 26482) // Only index into arrays using constant expressions (bounds.2). 00693 #pragma warning (disable: 26483) // Value 'value' is outside the bounds (min, max) of variable 'name'. Only index into arrays using constant expressions that are within bounds of the array (bounds.2). 00694 #pragma warning (disable: 26485) // Expression 'expr': No array to pointer decay (bounds.3). 00695 #pragma warning (disable: 26486) // Don't pass a pointer that may be invalid to a function. Parameter 'n' 'name' in call to 'name' may be invalid (lifetime.3). 00696 #pragma warning (disable: 26487) // Don't return a pointer 'name' that may be invalid (lifetime.4). 00697 #pragma warning (disable: 26488) // Do not dereference a potentially null pointer: 'name'. 'name' was null at line 'n' (lifetime.1). 00698 #pragma warning (disable: 26489) // Don't dereference a pointer that may be invalid: 'name'. 'name' may have been invalidated at line 'n' (lifetime.1). 00699 #pragma warning (disable: 26490) // Don't use reinterpret_cast (type.1). 00700 #pragma warning (disable: 26492) // Don't use const_cast to cast away const or volatile (type.3). 00701 #pragma warning (disable: 26493) // Don't use C-style casts (type.4). 00702 #pragma warning (disable: 26496) // The variable 'name' is assigned only once, mark it as const (con.4). 00703 #pragma warning (disable: 26497) // The function 'name' could be marked constexpr if compile-time evaluation is desired (f.4). 00704 #pragma warning (disable: 26812) // The enum type 'type' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). 00705 #pragma warning (disable: 26814) // The const variable 'name' can be computed at compile-time. Consider using constexpr (con.5). 00706 #pragma warning (disable: 26822) // Dereferencing a possibly null pointer '...' (lifetime.1). 00707 #pragma warning (disable: 26823) // Dereferencing a possibly null pointer '...' (lifetime.1). 00708 #pragma warning (disable: 28125) // The function must be called from within a try/except block 00709 #pragma warning (disable: 28159) // Consider using another function instead 00710 00711 #pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665 00712 00713 #define _tx_thread __declspec (thread) 00714 #define _tx_decltype(value) decltype (value) 00715 00716 #if !defined (_CLANG_VER) 00717 00718 #pragma setlocale ("russian") // Set source file encoding, see also _TX_CODEPAGE 00719 00720 #if !defined (NDEBUG) 00721 #pragma check_stack ( on) // Turn on stack probes at runtime 00722 #pragma strict_gs_check (push, on) // Detects stack buffer overruns 00723 #endif 00724 00725 #endif 00726 00727 #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 00728 00729 #endif 00730 00731 //----------------------------------------------------------------------------------------------------------------- 00732 00733 #if defined (__INTEL_COMPILER) 00734 00735 #pragma warning (disable: 174) // Remark: expression has no effect 00736 #pragma warning (disable: 304) // Remark: access control not specified ("public" by default) 00737 #pragma warning (disable: 444) // Remark: destructor for base class "..." is not virtual 00738 #pragma warning (disable: 522) // Remark: function "..." redeclared "inline" after being called 00739 #pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order 00740 #pragma warning (disable: 1684) // Conversion from pointer to same-sized integral type (potential portability problem) 00741 00742 #endif 00743 00744 //----------------------------------------------------------------------------------------------------------------- 00745 00746 #if (defined (_GCC_VER) && (_GCC_VER < 472) || \ 00747 defined (_MSC_VER) && (_MSC_VER < 1600)) // Minimum requirements are now GCC 4.7.2 or MSVC 10.0 (2010) 00748 00749 #ifdef __GNUC__ 00750 #error 00751 #error --------------------------------------------------------------------------------------- 00752 #endif 00753 #error TXLib.h: This version will NOT work with GCC < 4.7.2 or MS Visual Studio < 2010, sorry. 00754 #error 00755 #error Please use TXLib.h previous stable version/revision OR upgrade your compiler. 00756 #error --------------------------------------------------------------------------------------- 00757 #error 00758 00759 #endif 00760 00761 //----------------------------------------------------------------------------------------------------------------- 00762 00763 #if defined (_GCC_VER) && (_GCC_VER >= 492) 00764 #if defined (TX_USE_SPEAK) && !__has_include (<SAPI.h>) 00765 00766 #ifdef __GNUC__ 00767 #error 00768 #error --------------------------------------------------------------------------------------- 00769 #endif 00770 #error You have defined TX_USE_SPEAK, but your compiler do NOT have the library <SAPI.h>. 00771 #error 00772 #error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API 00773 #error necessary for txSpeak() to work. 00774 #error --------------------------------------------------------------------------------------- 00775 #error 00776 00777 #endif 00778 #endif 00779 00780 //----------------------------------------------------------------------------------------------------------------- 00781 00782 #if !defined (WINVER) 00783 #define WINVER 0x0502 // Defaults to Windows XP 00784 #define WINDOWS_ENABLE_CPLUSPLUS // Allow use of type-limit macros in <basetsd.h>, 00785 #endif // they are allowed by default if WINVER >= 0x0600. 00786 00787 #if !defined (_WIN32_WINNT) 00788 #define _WIN32_WINNT WINVER // Defaults to the same as WINVER 00789 #endif 00790 00791 #if !defined (_WIN32_IE) 00792 #define _WIN32_IE WINVER // Defaults to the same as WINVER 00793 #endif 00794 00795 #define stristr( str1, str2 ) Win32::StrStrIA ((str1), (str2)) 00796 #define stristrw( str1, str2 ) Win32::StrStrIW ((str1), (str2)) 00797 00798 //----------------------------------------------------------------------------------------------------------------- 00799 00800 #define _USE_MATH_DEFINES 1 // Math.h's M_PI etc. 00801 #define __STDC_FORMAT_MACROS 1 // PRIu64 and other PR... macros 00802 #define __STDC_WANT_LIB_EXT1__ 1 // String and output *_s functions 00803 00804 #define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS // Wow, how long. Kudos, Clang 00805 00806 #define _ALLOW_RTCc_IN_STL 1 // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc. 00807 00808 #define NOMINMAX 1 // Preventing 'min' and 'max' defines in Windows.h 00809 00810 #if defined (_DEBUG) 00811 #define _SECURE_SCL 1 // Enable checked STL iterators to throw an exception on incorrect use 00812 #define _HAS_ITERATOR_DEBUGGING 1 00813 #define _LIBCPP_DEBUG 1 00814 #endif 00815 00816 #if defined (_MSC_VER) && defined (_DEBUG) 00817 00818 #define _CRTDBG_MAP_ALLOC // Enable MSVCRT debug heap 00819 #define _new_dbg new (_NORMAL_BLOCK, __FILE__, __LINE__) 00820 #define NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) 00821 00822 #else 00823 #define _new_dbg new 00824 #define NEW new 00825 00826 #endif 00827 00828 #if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015 00829 #define _SECURE_SCL_THROWS 1 00830 #endif 00831 00832 #define tx_noreturn __attribute__ (( noreturn )) 00833 #define tx_nodiscard __attribute__ (( warn_unused_result )) 00834 #define tx_deprecated __attribute__ (( deprecated )) 00835 #define tx_printfy( formatArgN ) __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) )) 00836 #define tx_scanfy( formatArgN ) __attribute__ (( format (scanf, (formatArgN), (formatArgN)+1) )) 00837 00838 00839 #if defined (_TX_CPP11) 00840 00841 #define _tx_delete = delete 00842 #define _tx_default = default 00843 #define _tx_override override 00844 #define _tx_final final 00845 00846 #else 00847 00848 #define _tx_delete 00849 #define _tx_default 00850 #define _tx_override 00851 #define _tx_final 00852 00853 #endif 00854 00855 namespace std { enum nomeow_t { nomeow }; } // Vital addition to the C++ standard. TODO: Should contact C++ std committee. 00856 00857 //----------------------------------------------------------------------------------------------------------------- 00858 00860 //} 00861 //----------------------------------------------------------------------------------------------------------------- 00862 00863 //----------------------------------------------------------------------------------------------------------------- 00864 //{ The Includes 00865 //----------------------------------------------------------------------------------------------------------------- 00866 00867 #if defined (_MSC_VER) 00868 #pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o 00869 00870 #pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch 00871 #pragma warning (disable: 4005) // 'name': macro redefinition 00872 #endif 00873 00874 //----------------------------------------------------------------------------------------------------------------- 00875 00876 #include <stdlib.h> 00877 #include <stdio.h> 00878 #include <string.h> 00879 #include <time.h> 00880 #include <math.h> 00881 #include <float.h> 00882 00883 #include <vector> 00884 #include <string> 00885 #include <iostream> 00886 #include <sstream> 00887 #include <iomanip> 00888 00889 #if !defined (__CYGWIN__) 00890 #include <conio.h> 00891 #include <direct.h> 00892 #endif 00893 00894 #if defined (TX_COMPILED) 00895 #define WIN32_LEAN_AND_MEAN 00896 #endif 00897 00898 #include <windows.h> 00899 #include <mmsystem.h> 00900 00901 //----------------------------------------------------------------------------------------------------------------- 00902 //{ Compiler- and platform-specific 00904 //----------------------------------------------------------------------------------------------------------------- 00905 00906 #if defined (_MSC_VER) 00907 #pragma warning (pop) // MSVC: Restore max level 00908 #endif 00909 00910 #if defined (__STRICT_ANSI__UNDEFINED) 00911 #define __STRICT_ANSI__ // Redefine back 00912 #endif 00913 00914 #if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED) 00915 00916 #define strncpy_s( dest, sizeof_dest, src, count ) ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) ) 00917 #define wcsncpy_s( dest, sizeof_dest, src, count ) ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) ) 00918 #define strncat_s( dest, sizeof_dest, src, count ) ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) ) 00919 #define strerror_s( buf, sizeof_buf, code ) ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) ) 00920 #define strtok_s( buf, delim, ctx ) ( (void)(ctx), strtok ((buf), (delim)) ) 00921 #define fopen_s( file, name, mode ) ( *(file) = fopen ((name), (mode)) ) 00922 #define _strlwr_s( str, sizeof_str ) ( _strlwr (str) ) 00923 00924 #define ctime_s( buf, sizeof_buf, time ) ( strncpy ((buf), ctime (time), (sizeof_buf)-1) ) 00925 #define _controlfp_s( oldCtl, newCtl, mask ) ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 ) 00926 00927 #define _snprintf_s snprintf 00928 #define _vsnprintf_s( str, sz, trunc, format, arg ) _vsnprintf (str, sz, format, arg) 00929 00930 #endif 00931 00932 #if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) ) 00933 00934 #define getenv_s( sz, buf, sizeof_buf, name ) ({ (void)(sz); const char* _env = getenv (name); \ 00935 strncpy ((buf), (_env)? _env : "", (sizeof_buf)-1); }) 00936 #endif 00937 00938 #if defined (__CYGWIN__) 00939 00940 #undef __STRICT_ANSI__ 00941 00942 typedef void _exception; 00943 00944 #define _O_TEXT O_TEXT 00945 #define _fdopen fdopen 00946 #define _flushall() fflush (NULL) 00947 #define _getcwd getcwd 00948 #define _getpid getpid 00949 #define _stricmp strcasecmp 00950 #define _strlwr strlwr 00951 #define _strnicmp strncasecmp 00952 #define _unlink unlink 00953 #define _vsnprintf vsnprintf 00954 #define _access access 00955 #define _strdup strdup 00956 00957 #define getch _getch 00958 #define putch _putch 00959 #define kbhit _kbhit 00960 00961 #endif 00962 00963 #if !defined (PRId64) || \ 00964 defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32 00965 00966 #undef PRId64 00967 #undef PRIi64 00968 #undef PRIo64 00969 #undef PRIu64 00970 #undef PRIx64 00971 #undef PRIX64 00972 00973 #define PRId64 "I64d" 00974 #define PRIi64 "I64i" 00975 #define PRIo64 "I64o" 00976 #define PRIu64 "I64u" 00977 #define PRIx64 "I64x" 00978 #define PRIX64 "I64X" 00979 00980 #endif 00981 00982 //} 00983 //----------------------------------------------------------------------------------------------------------------- 00984 00985 //} 00986 //----------------------------------------------------------------------------------------------------------------- 00987 00988 //----------------------------------------------------------------------------------------------------------------- 00989 //{ The namespaces 00990 //----------------------------------------------------------------------------------------------------------------- 00991 00992 //{---------------------------------------------------------------------------------------------------------------- 00995 //}---------------------------------------------------------------------------------------------------------------- 00996 00997 #ifdef FOR_DOXYGEN_ONLY 00998 namespace { namespace TX { }} 00999 #endif 01000 01003 //----------------------------------------------------------------------------------------------------------------- 01004 01005 #if defined (TX_COMPILED) && defined (TX_COMPILING) 01006 #undef TX_COMPILED 01007 #endif 01008 01009 #if !defined (TX_COMPILED) && !defined (TX_COMPILING) 01010 01011 #define _TX_BEGIN_NAMESPACE namespace { namespace TX { 01012 #define _TX_END_NAMESPACE } } 01013 01014 #else 01015 01016 #define _TX_BEGIN_NAMESPACE namespace TX { 01017 #define _TX_END_NAMESPACE } 01018 01019 #endif 01020 01021 //----------------------------------------------------------------------------------------------------------------- 01022 01023 _TX_BEGIN_NAMESPACE 01024 01027 //} 01028 //----------------------------------------------------------------------------------------------------------------- 01029 01030 //================================================================================================================= 01031 //{ TXLIB INTERFACE 01032 // Интерфейс библиотеки 01033 //================================================================================================================= 01034 01035 //================================================================================================================= 01036 //{ Initialization 01038 //================================================================================================================= 01040 //{---------------------------------------------------------------------------------------------------------------- 01084 //}---------------------------------------------------------------------------------------------------------------- 01085 01086 HWND txCreateWindow (double sizeX, double sizeY, bool centered = true); 01087 01088 //{---------------------------------------------------------------------------------------------------------------- 01115 //}---------------------------------------------------------------------------------------------------------------- 01116 01117 inline HDC& txDC() tx_nodiscard; 01118 01119 //{---------------------------------------------------------------------------------------------------------------- 01155 //}---------------------------------------------------------------------------------------------------------------- 01156 01157 inline RGBQUAD* txVideoMemory() tx_nodiscard; 01158 01159 //{---------------------------------------------------------------------------------------------------------------- 01178 //}---------------------------------------------------------------------------------------------------------------- 01179 01180 bool txSetDefaults (HDC dc = txDC()); 01181 01182 //{---------------------------------------------------------------------------------------------------------------- 01201 //}---------------------------------------------------------------------------------------------------------------- 01202 01203 inline bool txOK() tx_nodiscard; 01204 01205 //{---------------------------------------------------------------------------------------------------------------- 01237 //}---------------------------------------------------------------------------------------------------------------- 01238 01239 POINT txGetExtent (HDC dc = txDC()) tx_nodiscard; 01240 01241 //{---------------------------------------------------------------------------------------------------------------- 01258 //}---------------------------------------------------------------------------------------------------------------- 01259 01260 inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard; 01261 01262 //{---------------------------------------------------------------------------------------------------------------- 01280 //}---------------------------------------------------------------------------------------------------------------- 01281 01282 inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard; 01283 01284 //{---------------------------------------------------------------------------------------------------------------- 01296 //}---------------------------------------------------------------------------------------------------------------- 01297 01298 inline HWND txWindow() tx_nodiscard; 01299 01300 //{---------------------------------------------------------------------------------------------------------------- 01309 //}---------------------------------------------------------------------------------------------------------------- 01310 01311 inline const char* txVersion() tx_nodiscard; 01312 01313 //{---------------------------------------------------------------------------------------------------------------- 01322 //}---------------------------------------------------------------------------------------------------------------- 01323 01324 inline unsigned txVersionNumber() tx_nodiscard; 01325 01326 //{---------------------------------------------------------------------------------------------------------------- 01356 //}---------------------------------------------------------------------------------------------------------------- 01357 01358 const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard; 01359 01361 //{---------------------------------------------------------------------------------------------------------------- 01396 //}---------------------------------------------------------------------------------------------------------------- 01397 01398 int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает", 01399 unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL); 01400 01401 //{---------------------------------------------------------------------------------------------------------------- 01418 //}---------------------------------------------------------------------------------------------------------------- 01419 01420 HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL); 01421 01422 //} 01423 //================================================================================================================= 01424 01425 //================================================================================================================= 01426 //{ Setting the parameters 01428 //================================================================================================================= 01430 //{---------------------------------------------------------------------------------------------------------------- 01456 //}---------------------------------------------------------------------------------------------------------------- 01457 01458 const COLORREF 01459 #ifdef FOR_DOXYGEN_ONLY 01460 enum txColors { 01461 #endif 01462 01463 TX_BLACK = RGB ( 0, 0, 0), 01464 TX_BLUE = RGB ( 0, 0, 128), 01465 TX_GREEN = RGB ( 0, 128, 0), 01466 TX_CYAN = RGB ( 0, 128, 128), 01467 TX_RED = RGB (128, 0, 0), 01468 TX_MAGENTA = RGB (128, 0, 128), 01469 TX_BROWN = RGB (128, 128, 0), 01470 TX_ORANGE = RGB (255, 128, 0), 01471 TX_GRAY = RGB (160, 160, 160), 01472 TX_DARKGRAY = RGB (128, 128, 128), 01473 TX_LIGHTGRAY = RGB (192, 192, 192), 01474 TX_LIGHTBLUE = RGB ( 0, 0, 255), 01475 TX_LIGHTGREEN = RGB ( 0, 255, 128), 01476 TX_LIGHTCYAN = RGB ( 0, 255, 255), 01477 TX_LIGHTRED = RGB (255, 0, 128), 01478 TX_LIGHTMAGENTA = RGB (255, 0, 255), 01479 TX_PINK = RGB (255, 128, 255), 01480 TX_YELLOW = RGB (255, 255, 128), 01481 TX_WHITE = RGB (255, 255, 255), 01482 TX_TRANSPARENT = 0xFFFFFFFF, 01483 TX_NULL = TX_TRANSPARENT, 01484 TX_BLM = TX_BLACK, 01485 TX_white = TX_WHITE, 01486 01487 // Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB() 01488 01489 TX_HUE = 0x04000000, 01490 TX_SATURATION = 0x05000000, 01491 TX_LIGHTNESS = 0x06000000; 01492 01493 #ifdef FOR_DOXYGEN_ONLY 01494 }; 01495 #endif 01496 01498 #define TX_GREY TX_GRAY 01499 #define TX_DARKGREY TX_DARKGRAY 01500 #define TX_LIGHTGREY TX_LIGHTGRAY 01501 01502 01503 //{---------------------------------------------------------------------------------------------------------------- 01528 //}---------------------------------------------------------------------------------------------------------------- 01529 01530 #ifdef FOR_DOXYGEN_ONLY 01531 COLORREF RGB (int red, int green, int blue); 01532 #endif 01533 01534 //{---------------------------------------------------------------------------------------------------------------- 01553 //}---------------------------------------------------------------------------------------------------------------- 01554 01555 HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC()); 01556 01558 #define txSetColour txSetColor 01559 01560 01562 01563 //{---------------------------------------------------------------------------------------------------------------- 01574 //}---------------------------------------------------------------------------------------------------------------- 01575 01576 COLORREF txColor (double red, double green, double blue); 01577 01579 01580 //{---------------------------------------------------------------------------------------------------------------- 01593 //}---------------------------------------------------------------------------------------------------------------- 01594 01595 COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard; 01596 01597 //{---------------------------------------------------------------------------------------------------------------- 01612 //}---------------------------------------------------------------------------------------------------------------- 01613 01614 HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC()); 01615 01617 #define txSetFillColour txSetFillColor 01618 01619 01621 01622 //{---------------------------------------------------------------------------------------------------------------- 01633 //}---------------------------------------------------------------------------------------------------------------- 01634 01635 COLORREF txFillColor (double red, double green, double blue); 01636 01638 01639 //{---------------------------------------------------------------------------------------------------------------- 01652 //}---------------------------------------------------------------------------------------------------------------- 01653 01654 COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard; 01655 01656 //{---------------------------------------------------------------------------------------------------------------- 01674 //}---------------------------------------------------------------------------------------------------------------- 01675 01676 unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard; 01677 01678 //{---------------------------------------------------------------------------------------------------------------- 01706 //}---------------------------------------------------------------------------------------------------------------- 01707 01708 COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard; 01709 01710 //{---------------------------------------------------------------------------------------------------------------- 01740 //}---------------------------------------------------------------------------------------------------------------- 01741 01742 COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard; 01743 01745 //} 01746 //================================================================================================================= 01747 01748 //================================================================================================================= 01749 //{ Drawing 01751 //================================================================================================================= 01753 //{---------------------------------------------------------------------------------------------------------------- 01767 //}---------------------------------------------------------------------------------------------------------------- 01768 01769 bool txClear (HDC dc = txDC()); 01770 01771 //{---------------------------------------------------------------------------------------------------------------- 01789 //}---------------------------------------------------------------------------------------------------------------- 01790 01791 inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC()); 01792 01794 01795 //{---------------------------------------------------------------------------------------------------------------- 01813 //}---------------------------------------------------------------------------------------------------------------- 01814 01815 inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC()); 01816 01818 01819 //{---------------------------------------------------------------------------------------------------------------- 01837 //}---------------------------------------------------------------------------------------------------------------- 01838 01839 inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard; 01840 01841 //{---------------------------------------------------------------------------------------------------------------- 01861 //}---------------------------------------------------------------------------------------------------------------- 01862 01863 bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01864 01865 //{---------------------------------------------------------------------------------------------------------------- 01887 //}---------------------------------------------------------------------------------------------------------------- 01888 01889 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01890 01891 //{---------------------------------------------------------------------------------------------------------------- 01911 //}---------------------------------------------------------------------------------------------------------------- 01912 01913 bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC()); 01914 01915 //{---------------------------------------------------------------------------------------------------------------- 01935 //}---------------------------------------------------------------------------------------------------------------- 01936 01937 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01938 01939 //{---------------------------------------------------------------------------------------------------------------- 01957 //}---------------------------------------------------------------------------------------------------------------- 01958 01959 bool txCircle (double x, double y, double r); 01960 01961 //{---------------------------------------------------------------------------------------------------------------- 01984 //}---------------------------------------------------------------------------------------------------------------- 01985 01986 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 01987 01988 //{---------------------------------------------------------------------------------------------------------------- 02011 //}---------------------------------------------------------------------------------------------------------------- 02012 02013 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 02014 02015 //{---------------------------------------------------------------------------------------------------------------- 02038 //}---------------------------------------------------------------------------------------------------------------- 02039 02040 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 02041 02042 //{---------------------------------------------------------------------------------------------------------------- 02074 //}---------------------------------------------------------------------------------------------------------------- 02075 02076 bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC()); 02077 02078 //{---------------------------------------------------------------------------------------------------------------- 02096 //}---------------------------------------------------------------------------------------------------------------- 02097 02098 inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3) 02099 { 02100 (void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3; 02101 02102 txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n" 02103 "Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами " 02104 "как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". " 02105 "Ну или нарисовать тремя линиями. :)", "TXLib сообщает"); 02106 return false; 02107 } 02108 02109 //{---------------------------------------------------------------------------------------------------------------- 02111 02112 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3); 02113 02114 #define txRectandle Sleep (1000), txRectangle // Copy-protection for the function below 02115 #define txLine(...) txLine (__VA_ARGS__); { // 02116 #define txNotifyIcon }}}}}}}}}} txNotifyIcon // Не спрашивайте, зачем. Это дичь. 02117 #define txCircle ;txCircle // 02118 #define txSetColor ;txSetColor // 02119 #define C0L0RREF COLORREF // 02120 #define OxFFFFFF 0xFFFFFF // 02121 #define lO 10 // 02122 #define lOOO 1000 // 02123 #define oo // 02124 #define O // 02125 02127 //} 02128 02129 //{---------------------------------------------------------------------------------------------------------------- 02170 //}----------------------------------------------------------------------------------------------------------------////// 02171 // 02172 inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist, // 02173 double head, double eyes, double wink, double crazy, double smile, double hair, double wind) // 02174 { // 02175 const char __[] = "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/"; // 02176 // | | | | // 02177 // Не копипастите! _/ \_ Все равно не получится! :) _/ \_ Человечки защищают _/ \_ этот код! :) _/ \_ Муаххаха! // 02178 // // 02179 static int count = GetTickCount(), L = 0; 02180 02181 C0L0RREF lineColor = txGetColor(); 02182 C0L0RREF fillColor = txGetFillColor(); 02183 02184 txSetColor (color, 3); 02185 txSetFillColor (color); 02186 02187 txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY); 02188 02189 txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY); 02190 txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY); 02191 02192 txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y); 02193 txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y); 02194 02195 txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY); 02196 02197 txLine (x, y - (1 + head) * sizeY, x + wind/lO * sizeX, y - (1 + head + hair/lO) * sizeY); 02198 txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY); 02199 txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY); 02200 02201 txSetColor (~color & OxFFFFFF); // Inverse the color 02202 txSetFillColor (~color & OxFFFFFF); 02203 02204 txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY); 02205 txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY); 02206 oo 02207 txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]); //-V112 //-V542 02208 oo 02209 // See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow 02210 02211 txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY); 02212 txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY); 02213 Sleep (lOOO + count%2); 02214 02215 txSetColor ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT); 02216 txSetFillColor (TX_TRANSPARENT); 02217 02218 txCircle (x, y, 4); //-V112 02219 txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y); 02220 02221 txSetColor (lineColor); 02222 txSetFillColor (fillColor); 02223 } 02224 02226 //} 02227 //================================================================================================================= 02228 02229 //================================================================================================================= 02230 //{ Drawing text 02232 //================================================================================================================= 02234 //{---------------------------------------------------------------------------------------------------------------- 02253 //}---------------------------------------------------------------------------------------------------------------- 02254 02255 bool txTextOut (double x, double y, const char text[], HDC dc = txDC()); 02256 02257 //{---------------------------------------------------------------------------------------------------------------- 02259 02260 #undef txRectandle 02261 #undef txLine 02262 #undef txNotifyIcon 02263 #undef txCircle 02264 #undef txSetColor 02265 #undef C0L0RREF 02266 #undef OxFFFFFF 02267 #undef lO 02268 #undef lOOO 02269 #undef oo 02270 #undef O 02271 02273 //} 02274 02275 //{---------------------------------------------------------------------------------------------------------------- 02322 //}---------------------------------------------------------------------------------------------------------------- 02323 02324 bool txDrawText (double x0, double y0, double x1, double y1, const char text[], 02325 unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC()); 02326 02327 //{---------------------------------------------------------------------------------------------------------------- 02352 //}---------------------------------------------------------------------------------------------------------------- 02353 02354 HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1, 02355 int bold = FW_DONTCARE, bool italic = false, bool underline = false, 02356 bool strikeout = false, double angle = 0, 02357 HDC dc = txDC()); 02358 02359 //{---------------------------------------------------------------------------------------------------------------- 02374 //}---------------------------------------------------------------------------------------------------------------- 02375 02376 SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard; 02377 02378 //{---------------------------------------------------------------------------------------------------------------- 02392 //}---------------------------------------------------------------------------------------------------------------- 02393 02394 int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard; 02395 02396 //{---------------------------------------------------------------------------------------------------------------- 02410 //}---------------------------------------------------------------------------------------------------------------- 02411 02412 int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard; 02413 02414 //{---------------------------------------------------------------------------------------------------------------- 02441 //}---------------------------------------------------------------------------------------------------------------- 02442 02443 unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC()); 02444 02445 //{---------------------------------------------------------------------------------------------------------------- 02461 //}---------------------------------------------------------------------------------------------------------------- 02462 02463 LOGFONT* txFontExist (const char name[]) tx_nodiscard; 02464 02466 //} 02467 //================================================================================================================= 02468 02469 //================================================================================================================= 02470 //{ Drawing to memory DC and image loading 02472 //================================================================================================================= 02474 //{---------------------------------------------------------------------------------------------------------------- 02514 //}---------------------------------------------------------------------------------------------------------------- 02515 02516 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard; 02517 02518 //{---------------------------------------------------------------------------------------------------------------- 02621 //}---------------------------------------------------------------------------------------------------------------- 02622 02623 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels = NULL) tx_nodiscard; 02624 02626 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) tx_nodiscard; 02628 02629 //{---------------------------------------------------------------------------------------------------------------- 02705 //}---------------------------------------------------------------------------------------------------------------- 02706 02707 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0, 02708 unsigned imageFlags = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard; 02709 02710 //{---------------------------------------------------------------------------------------------------------------- 02742 //}---------------------------------------------------------------------------------------------------------------- 02743 02744 bool txDeleteDC (HDC dc); 02745 02747 bool txDeleteDC (HDC* dc); 02749 02750 //{---------------------------------------------------------------------------------------------------------------- 02790 //}---------------------------------------------------------------------------------------------------------------- 02791 02792 bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height, 02793 HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY); 02794 02795 //{---------------------------------------------------------------------------------------------------------------- 02810 //}---------------------------------------------------------------------------------------------------------------- 02811 02812 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0); 02813 02814 //{---------------------------------------------------------------------------------------------------------------- 02874 //}---------------------------------------------------------------------------------------------------------------- 02875 02876 bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height, 02877 HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK); 02878 02879 //{---------------------------------------------------------------------------------------------------------------- 02895 //}---------------------------------------------------------------------------------------------------------------- 02896 02897 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage, 02898 COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0); 02899 02900 //{---------------------------------------------------------------------------------------------------------------- 03005 //}---------------------------------------------------------------------------------------------------------------- 03006 03007 bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height, 03008 HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0); 03009 03010 //{---------------------------------------------------------------------------------------------------------------- 03027 //}---------------------------------------------------------------------------------------------------------------- 03028 03029 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage, 03030 double xSource = 0, double ySource = 0, double alpha = 1.0); 03031 03032 //{---------------------------------------------------------------------------------------------------------------- 03061 //}---------------------------------------------------------------------------------------------------------------- 03062 03063 HDC txUseAlpha (HDC image); 03064 03065 //{---------------------------------------------------------------------------------------------------------------- 03091 //}---------------------------------------------------------------------------------------------------------------- 03092 03093 bool txSaveImage (const char filename[], HDC dc = txDC()); 03094 03096 //} 03097 //================================================================================================================= 03098 03099 //================================================================================================================= 03100 //{ Utility functions 03102 //================================================================================================================= 03104 //{---------------------------------------------------------------------------------------------------------------- 03123 //}---------------------------------------------------------------------------------------------------------------- 03124 03125 double txSleep (double time = 0); 03126 03127 //{---------------------------------------------------------------------------------------------------------------- 03212 //}---------------------------------------------------------------------------------------------------------------- 03213 03214 inline int txBegin(); 03215 03216 //{---------------------------------------------------------------------------------------------------------------- 03239 //}---------------------------------------------------------------------------------------------------------------- 03240 03241 inline int txEnd(); 03242 03243 //{---------------------------------------------------------------------------------------------------------------- 03265 //}---------------------------------------------------------------------------------------------------------------- 03266 03267 inline void txRedrawWindow(); 03268 03269 //{---------------------------------------------------------------------------------------------------------------- 03293 //}---------------------------------------------------------------------------------------------------------------- 03294 03295 inline int txUpdateWindow (int update = true); 03296 03297 //{---------------------------------------------------------------------------------------------------------------- 03314 //}---------------------------------------------------------------------------------------------------------------- 03315 03316 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC()); 03317 03318 //{---------------------------------------------------------------------------------------------------------------- 03338 // 03339 // +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее" 03340 // | 03341 // v 03342 // txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture(); 03347 //}---------------------------------------------------------------------------------------------------------------- 03348 03349 // +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее" 03350 // | 03351 // v 03352 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture(); 03353 03354 //{---------------------------------------------------------------------------------------------------------------- 03370 //}---------------------------------------------------------------------------------------------------------------- 03371 03372 bool txDestroyWindow (HWND wnd = txWindow()); 03373 03374 //{---------------------------------------------------------------------------------------------------------------- 03385 //}---------------------------------------------------------------------------------------------------------------- 03386 03387 double txQueryPerformance() tx_nodiscard; 03388 03389 //{---------------------------------------------------------------------------------------------------------------- 03404 //}---------------------------------------------------------------------------------------------------------------- 03406 03407 #if defined (_TX_CPP11) 03408 template <int txFramesToAverage = 5> 03409 #else 03410 const int txFramesToAverage = 5; 03411 #endif 03412 03414 03415 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard; 03416 03418 //} 03419 03420 //================================================================================================================= 03421 //{ Mouse functions 03423 //================================================================================================================= 03425 //{---------------------------------------------------------------------------------------------------------------- 03449 //}---------------------------------------------------------------------------------------------------------------- 03450 03451 inline POINT txMousePos() tx_nodiscard; 03452 03453 //{---------------------------------------------------------------------------------------------------------------- 03473 //}---------------------------------------------------------------------------------------------------------------- 03474 03475 inline double txMouseX() tx_nodiscard; 03476 03477 //{---------------------------------------------------------------------------------------------------------------- 03497 //}---------------------------------------------------------------------------------------------------------------- 03498 03499 inline double txMouseY() tx_nodiscard; 03500 03501 //{---------------------------------------------------------------------------------------------------------------- 03533 //}---------------------------------------------------------------------------------------------------------------- 03534 03535 inline unsigned txMouseButtons() tx_nodiscard; 03536 03537 //{---------------------------------------------------------------------------------------------------------------- 03569 //}---------------------------------------------------------------------------------------------------------------- 03570 03571 #ifdef FOR_DOXYGEN_ONLY 03572 inline Mouse& txCatchMouse (bool shouldEat = true); 03573 #endif 03574 03576 //} 03577 //================================================================================================================= 03578 03579 //================================================================================================================= 03580 //{ Console functions 03582 //================================================================================================================= 03584 //{---------------------------------------------------------------------------------------------------------------- 03626 //}---------------------------------------------------------------------------------------------------------------- 03627 03628 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/); 03629 03630 //{---------------------------------------------------------------------------------------------------------------- 03642 //}---------------------------------------------------------------------------------------------------------------- 03643 03644 unsigned txGetConsoleAttr() tx_nodiscard; 03645 03646 //{---------------------------------------------------------------------------------------------------------------- 03660 //}---------------------------------------------------------------------------------------------------------------- 03661 03662 bool txClearConsole(); 03663 03664 //{---------------------------------------------------------------------------------------------------------------- 03684 //}---------------------------------------------------------------------------------------------------------------- 03685 03686 POINT txSetConsoleCursorPos (double x, double y); 03687 03688 //{---------------------------------------------------------------------------------------------------------------- 03701 //}---------------------------------------------------------------------------------------------------------------- 03702 03703 POINT txGetConsoleCursorPos(); 03704 03705 //{---------------------------------------------------------------------------------------------------------------- 03718 //}---------------------------------------------------------------------------------------------------------------- 03719 03720 POINT txGetConsoleExtent(); 03721 03722 //{---------------------------------------------------------------------------------------------------------------- 03736 //}---------------------------------------------------------------------------------------------------------------- 03737 03738 POINT txGetConsoleFontSize() tx_nodiscard; 03739 03740 //{---------------------------------------------------------------------------------------------------------------- 03756 //}---------------------------------------------------------------------------------------------------------------- 03757 03758 bool txTextCursor (bool blink = true); 03759 03761 //} 03762 //================================================================================================================= 03763 03764 //================================================================================================================= 03765 //{ Other staff not related to drawing 03767 //================================================================================================================= 03769 //{---------------------------------------------------------------------------------------------------------------- 03798 //}---------------------------------------------------------------------------------------------------------------- 03799 03800 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC); 03801 03802 //{---------------------------------------------------------------------------------------------------------------- 03860 //}---------------------------------------------------------------------------------------------------------------- 03861 03862 int txSpeak (const char* text, ...) tx_printfy (1); 03863 03864 //{---------------------------------------------------------------------------------------------------------------- 03981 //}---------------------------------------------------------------------------------------------------------------- 03982 03983 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[], 03984 double zoom = 0, double gain = 1, HWND wnd = txWindow()); 03985 03986 //{---------------------------------------------------------------------------------------------------------------- 04000 //}---------------------------------------------------------------------------------------------------------------- 04001 04002 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow()); 04003 04004 //{---------------------------------------------------------------------------------------------------------------- 04060 //}---------------------------------------------------------------------------------------------------------------- 04061 04062 bool txGetAsyncKeyState (int key); 04063 04064 //{---------------------------------------------------------------------------------------------------------------- 04101 //}---------------------------------------------------------------------------------------------------------------- 04102 04103 #ifdef FOR_DOXYGEN_ONLY 04104 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3); 04105 #endif 04106 04107 //{---------------------------------------------------------------------------------------------------------------- 04132 //}---------------------------------------------------------------------------------------------------------------- 04133 04134 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1); 04135 04136 //{---------------------------------------------------------------------------------------------------------------- 04212 //}---------------------------------------------------------------------------------------------------------------- 04213 04214 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04215 04216 template <typename T, typename... ArgsT> 04217 int txPrintf (const char* format, ArgsT... args); 04218 04219 #define TX_PRINTF(...) ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) ) 04220 04221 #endif 04222 04223 //----------------------------------------------------------------------------------------------------------------- 04224 04225 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY) 04226 04227 enum width_t : int {}; 04228 enum precision_t : int {}; 04229 04230 inline width_t width (int width) { return (width_t) width; } 04231 inline precision_t precision (int prec) { return (precision_t) prec; } 04232 04233 #endif 04234 04235 //{---------------------------------------------------------------------------------------------------------------- 04254 //}---------------------------------------------------------------------------------------------------------------- 04255 04256 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04257 04258 template <typename T, typename... ArgsT> 04259 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args); 04260 04261 #endif 04262 04263 //{---------------------------------------------------------------------------------------------------------------- 04283 //}---------------------------------------------------------------------------------------------------------------- 04284 04285 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04286 04287 template <typename T, typename... ArgsT> 04288 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args); 04289 04290 #endif 04291 04292 //{---------------------------------------------------------------------------------------------------------------- 04310 //}---------------------------------------------------------------------------------------------------------------- 04311 04312 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04313 04314 template <typename... ArgsT> 04315 std::string txFormat (const char* format, ArgsT... args); 04316 04317 #endif 04318 04319 //{---------------------------------------------------------------------------------------------------------------- 04391 //}---------------------------------------------------------------------------------------------------------------- 04393 04394 #define sizearr( arr ) ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) ) 04395 04397 // See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx 04398 04399 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N]; // ;=P 04400 04401 // Another approach 04402 04403 #if defined (_TX_CPP11_MSVC15) 04404 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; } 04405 #endif 04406 04408 04409 #define SIZEARR( arr ) ( sizeof (arr) / sizeof ((arr)[0]) ) 04410 04412 //{---------------------------------------------------------------------------------------------------------------- 04431 //}---------------------------------------------------------------------------------------------------------------- 04432 04433 inline int random (int range) tx_deprecated; 04434 04435 //{---------------------------------------------------------------------------------------------------------------- 04460 //}---------------------------------------------------------------------------------------------------------------- 04461 04462 inline double random (double left, double right) tx_nodiscard tx_deprecated; 04463 04464 inline double random (std::nomeow_t, double left, double right) tx_nodiscard; 04465 04466 //{---------------------------------------------------------------------------------------------------------------- 04496 //}---------------------------------------------------------------------------------------------------------------- 04497 04498 template <typename Tx, typename Ta, typename Tb> 04499 inline bool In (Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated; 04500 04501 template <typename Tx, typename Ta, typename Tb> 04502 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated; 04503 04504 //{---------------------------------------------------------------------------------------------------------------- 04550 //}---------------------------------------------------------------------------------------------------------------- 04552 04553 inline bool In (const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated; 04554 inline bool In (const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated; 04555 04557 04558 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated; 04559 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated; 04560 04561 //{---------------------------------------------------------------------------------------------------------------- 04580 //}---------------------------------------------------------------------------------------------------------------- 04581 04582 #define MAX( a, b ) ( ((a) > (b))? (a) : (b) ) 04583 04584 template <typename T> 04585 T max (const T& a, const T& b) { return (a > b)? a : b; } 04586 04587 //{---------------------------------------------------------------------------------------------------------------- 04606 //}---------------------------------------------------------------------------------------------------------------- 04607 04608 #define MIN( a, b ) ( ((a) < (b))? (a) : (b) ) 04609 04610 template <typename T> 04611 T min (const T& a, const T& b) { return (a < b)? a : b; } 04612 04613 //{---------------------------------------------------------------------------------------------------------------- 04627 //}---------------------------------------------------------------------------------------------------------------- 04628 04629 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // MSVC: C99 case 04630 04631 #define ROUND( x ) ( (long) round (x) ) 04632 04633 #else 04634 04635 #define ROUND( x ) ( (long) floor ((x) + 0.5) ) 04636 04637 #endif 04638 04639 //{---------------------------------------------------------------------------------------------------------------- 04658 //}---------------------------------------------------------------------------------------------------------------- 04659 04660 void tx_fpreset(); 04661 04662 //{---------------------------------------------------------------------------------------------------------------- 04671 //}---------------------------------------------------------------------------------------------------------------- 04672 04673 const double txPI = asin (1.0) * 2; 04674 04675 //{---------------------------------------------------------------------------------------------------------------- 04702 //}---------------------------------------------------------------------------------------------------------------- 04703 04704 inline double txSqr (double x) 04705 { 04706 double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0)); // Бурная вычислительная деятельность 04707 04708 char str[1024] = ""; 04709 _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr); 04710 txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL || 04711 ( 04712 txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION), 04713 txMessageBox ("Уйду я от вас", "Злые вы...", MB_ICONSTOP), 04714 exit (EXIT_FAILURE), 0 //-V2509 //-V2014 04715 ); 04716 04717 txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика! \0" // А как это работает, а? //-V111 04718 "С ума сойти... \0" // 04719 "а КЭП подтверждает \0" // и кто это будет 04720 "Главное - отчитаться\0" // поддерживать?.. 04721 "Невероятно, но факт \0" 04722 "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21); 04723 04724 return sqr; // Все же вернем значение. Мы же не звери 04725 } 04726 04727 //{---------------------------------------------------------------------------------------------------------------- 04749 //}---------------------------------------------------------------------------------------------------------------- 04750 04751 #ifdef FOR_DOXYGEN_ONLY 04752 #define _TX_DESTROY_3D 04753 #endif 04754 04755 #if defined (_TX_DESTROY_3D) 04756 04757 #define z 0 // Читайте "Флатландию" Эбботта! 04758 04759 #endif 04760 04761 //{---------------------------------------------------------------------------------------------------------------- 04778 //}---------------------------------------------------------------------------------------------------------------- 04780 04781 #define meow ; 04782 04783 #if defined (_MSC_VER) && !defined (_CLANG_VER) 04784 #define мяу meow 04785 #endif 04786 04787 #define please 04788 04790 04791 //{---------------------------------------------------------------------------------------------------------------- 04809 //}---------------------------------------------------------------------------------------------------------------- 04810 04811 #define ZERO( type ) zero <type> () 04812 04814 template <typename T> inline T zero() tx_nodiscard; 04816 04817 //{---------------------------------------------------------------------------------------------------------------- 04844 //}---------------------------------------------------------------------------------------------------------------- 04846 04847 #define tx_auto_func( func ) _tx_auto_fun1 ( __LINE__, func ) 04848 #define _tx_auto_fun1( n, func ) _tx_auto_fun2 ( n, func ) 04849 #define _tx_auto_fun2( n, func ) auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; }) 04850 04851 #define tx_finally(...) tx_auto_func (__VA_ARGS__) 04852 04853 template <typename T> 04854 struct _tx_auto_func_ 04855 { 04856 typedef _tx_auto_func_<T> this_t; 04857 T func_; 04858 04859 explicit _tx_auto_func_ (T func) : func_ (func) {} 04860 ~_tx_auto_func_ () { func_ (); } 04861 04862 private: _tx_auto_func_ () _tx_delete; 04863 _tx_auto_func_ (const this_t&) _tx_delete; 04864 this_t& operator = (const this_t&) _tx_delete; 04865 }; 04866 04867 template <typename T> 04868 _tx_auto_func_<T> _tx_auto_func (T func) 04869 { 04870 return _tx_auto_func_ <T> (func); 04871 } 04872 04874 04875 //{---------------------------------------------------------------------------------------------------------------- 04920 //}---------------------------------------------------------------------------------------------------------------- 04921 04922 #if !defined (NDEBUG) 04923 #undef TX_ASSERT 04924 #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \ 04925 "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 ) 04926 #else 04927 #undef TX_ASSERT 04928 #define TX_ASSERT( cond ) ((void) 1) 04929 04930 #endif 04931 04932 #ifdef assert 04933 #undef assert 04934 #endif 04935 04936 #define assert( cond ) TX_ASSERT (cond) 04937 04938 //{---------------------------------------------------------------------------------------------------------------- 04965 //}---------------------------------------------------------------------------------------------------------------- 04966 04967 #if !defined (NDEBUG) 04968 #define asserted || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.") 04969 04970 #else 04971 #define asserted || _txNOP (0) 04972 04973 #endif 04974 04975 #define verified asserted //!< For compatibility with assert macro 04976 04978 #define TX_NEEDED asserted //!< For compatibility with earlier releases 04979 04980 04981 //{---------------------------------------------------------------------------------------------------------------- 05009 //}---------------------------------------------------------------------------------------------------------------- 05010 05011 #if !defined (NDEBUG) 05012 #undef verify 05013 #define verify assert 05014 05015 #else 05016 #undef verify 05017 #define verify( expr ) ( expr ) 05018 05019 #endif 05020 05021 //{---------------------------------------------------------------------------------------------------------------- 05040 //}---------------------------------------------------------------------------------------------------------------- 05041 05042 #if !defined (FOR_DOXYGEN_ONLY) 05043 #define TX_ERROR( ... ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__) 05044 #else 05045 #define TX_ERROR( msg ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg) 05046 #endif 05047 05049 #define TX_THROW TX_ERROR //!< For compatibility with earlier TXLib releases 05050 05051 05052 //{---------------------------------------------------------------------------------------------------------------- 05068 //}---------------------------------------------------------------------------------------------------------------- 05069 05070 #if !defined (NDEBUG) 05071 #define TX_DEBUG_ERROR(...) TX_ERROR (__VA_ARGS__) 05072 05073 #else 05074 #define TX_DEBUG_ERROR(...) ((void) 0) 05075 05076 #endif 05077 05078 //{---------------------------------------------------------------------------------------------------------------- 05098 //}---------------------------------------------------------------------------------------------------------------- 05099 05100 #ifdef FOR_DOXYGEN_ONLY 05101 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true); 05102 #endif 05103 05105 05106 #ifdef _MSC_VER 05107 #define txDump( ... ) _txDump ((const void*)(uintptr_t) __VA_ARGS__) 05108 #else 05109 #define txDump( address, ... ) _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__) 05110 #endif 05111 05112 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true); 05113 05115 05116 //{---------------------------------------------------------------------------------------------------------------- 05142 //}---------------------------------------------------------------------------------------------------------------- 05143 05144 #define txStackBackTrace() _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true); 05145 05146 //{---------------------------------------------------------------------------------------------------------------- 05168 //}---------------------------------------------------------------------------------------------------------------- 05170 05171 std::string txDemangle (const char* mangledName); 05172 char* txDemangle (const char* mangledName, std::nomeow_t); 05173 05174 #define txTypename(value) txDemangle (typeid (value) .name()) .c_str() 05175 05177 //{---------------------------------------------------------------------------------------------------------------- 05204 //}---------------------------------------------------------------------------------------------------------------- 05205 05206 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue); 05207 05208 //{---------------------------------------------------------------------------------------------------------------- 05221 //}---------------------------------------------------------------------------------------------------------------- 05223 05224 #define _ , 05225 #define TX_COMMA , //!< Синоним макроса _ (@ref _ "символ подчеркивания") 05226 05228 05229 //{---------------------------------------------------------------------------------------------------------------- 05289 //}---------------------------------------------------------------------------------------------------------------- 05290 05291 #ifdef FOR_DOXYGEN_ONLY 05292 05293 #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType ) 05294 05295 #else 05296 05297 // Hand-made DLLIMPORT helper 05298 05299 #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... ) \ 05300 retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \ 05301 _txDllImport ((libName), #funcName, (required)) 05302 #endif 05303 05305 //} 05306 //================================================================================================================= 05307 05308 //================================================================================================================= 05309 //{ Back-hole (I hope, not an ass-hole:) of the library) 05311 //================================================================================================================= 05313 //{---------------------------------------------------------------------------------------------------------------- 05465 //}---------------------------------------------------------------------------------------------------------------- 05466 05467 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL); 05468 05469 //{---------------------------------------------------------------------------------------------------------------- 05494 //}---------------------------------------------------------------------------------------------------------------- 05495 05496 bool txLock (bool wait = true); 05497 05498 //{---------------------------------------------------------------------------------------------------------------- 05509 //}---------------------------------------------------------------------------------------------------------------- 05511 05512 bool txUnlock(); 05513 05515 template <typename T> inline T txUnlock (T value); 05517 05519 05520 //{---------------------------------------------------------------------------------------------------------------- 05543 //}---------------------------------------------------------------------------------------------------------------- 05544 05545 #define txGDI( command, dc ) ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) ) 05546 05547 //{---------------------------------------------------------------------------------------------------------------- 05570 //}---------------------------------------------------------------------------------------------------------------- 05571 05572 #ifndef FOR_DOXYGEN_ONLY 05573 05574 const int _TX_CODEPAGE = 1251; 05575 05576 #ifndef __CYGWIN__ 05577 const char _TX_LOCALE[] = "Russian"; 05578 #else 05579 const char _TX_LOCALE[] = "ru_RU.CP1251"; 05580 #endif 05581 05582 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP"; 05583 05584 #endif 05585 05586 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE); 05587 05588 //{---------------------------------------------------------------------------------------------------------------- 05603 //}---------------------------------------------------------------------------------------------------------------- 05604 05605 int txPause (const char* message, ...) tx_printfy (1); 05606 05608 //} 05609 //================================================================================================================= 05610 05611 //================================================================================================================= 05612 //{ Tune-up constants and variables 05614 //================================================================================================================= 05616 //{---------------------------------------------------------------------------------------------------------------- 05626 //}---------------------------------------------------------------------------------------------------------------- 05627 05628 #ifndef TX_COMPILED 05629 05630 char _txLogName[MAX_PATH] = ""; 05631 05632 #endif // TX_COMPILED 05633 05634 extern char _txLogName[]; 05635 05636 //{---------------------------------------------------------------------------------------------------------------- 05668 //}---------------------------------------------------------------------------------------------------------------- 05669 05670 #if defined (_TX_NOINIT) 05671 05672 #undef _TX_NOINIT 05673 #define _TX_NOINIT 1 05674 05675 #else 05676 05677 #define _TX_NOINIT 0 05678 05679 #endif 05680 05681 //{---------------------------------------------------------------------------------------------------------------- 05725 //}---------------------------------------------------------------------------------------------------------------- 05726 05727 #if !defined (TX_CONSOLE_MODE) 05728 05729 #define TX_CONSOLE_MODE SW_HIDE 05730 05731 #endif 05732 05733 //{---------------------------------------------------------------------------------------------------------------- 05737 //}---------------------------------------------------------------------------------------------------------------- 05738 05739 #if !defined (TX_CONSOLE_FONT) 05740 05741 #define TX_CONSOLE_FONT "Lucida Console" 05742 05743 #endif 05744 05745 //{---------------------------------------------------------------------------------------------------------------- 05756 //}---------------------------------------------------------------------------------------------------------------- 05757 05758 #ifndef TX_COMPILED 05759 05760 int _txWindowStyle = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU; 05761 05762 #endif // TX_COMPILED 05763 05764 extern int _txWindowStyle; 05765 05766 //{---------------------------------------------------------------------------------------------------------------- 05769 //}---------------------------------------------------------------------------------------------------------------- 05770 05771 #ifndef TX_COMPILED 05772 05773 unsigned _txCursorBlinkInterval = 500; 05774 05775 #endif // TX_COMPILED 05776 05777 extern unsigned _txCursorBlinkInterval; 05778 05779 //{---------------------------------------------------------------------------------------------------------------- 05783 //}---------------------------------------------------------------------------------------------------------------- 05784 05785 #ifndef TX_COMPILED 05786 05787 unsigned _txWindowUpdateInterval = 25; 05788 05789 #endif // TX_COMPILED 05790 05791 extern unsigned _txWindowUpdateInterval; 05792 05793 //{---------------------------------------------------------------------------------------------------------------- 05802 //}---------------------------------------------------------------------------------------------------------------- 05803 05804 #ifdef FOR_DOXYGEN_ONLY 05805 #define TX_USE_SFML 05806 #endif 05807 05808 //{---------------------------------------------------------------------------------------------------------------- 05811 //}---------------------------------------------------------------------------------------------------------------- 05812 05813 const int _TX_TIMEOUT = 1000 05814 05815 #if defined (_TX_ALLOW_TRACE) 05816 * 2 05817 #endif 05818 05819 #if defined (TX_TRACE) 05820 * 3 05821 #endif 05822 05823 #if defined (_TX_USE_DEVPARTNER) 05824 * 10 05825 #endif 05826 ; 05827 05828 //{---------------------------------------------------------------------------------------------------------------- 05869 //}---------------------------------------------------------------------------------------------------------------- 05870 05871 #ifndef TX_COMPILED 05872 05873 bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest, 05874 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp) = NULL; 05875 05876 #endif // TX_COMPILED 05877 05878 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest, 05879 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp); 05880 05881 //{---------------------------------------------------------------------------------------------------------------- 05884 //}---------------------------------------------------------------------------------------------------------------- 05885 05886 const unsigned _TX_BUFSIZE = 1024, 05887 _TX_BIGBUFSIZE = _TX_BUFSIZE * 2, 05888 _TX_HUGEBUFSIZE = _TX_BUFSIZE * 20, 05889 05890 _TX_STACKSIZE = 64 * 1024; 05891 05892 //{---------------------------------------------------------------------------------------------------------------- 05895 //}---------------------------------------------------------------------------------------------------------------- 05896 05897 #if !defined (_TX_EXCEPTIONS_LIMIT) 05898 #define _TX_EXCEPTIONS_LIMIT 16 05899 #endif 05900 05901 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT) 05902 #define _TX_FATAL_EXCEPTIONS_LIMIT 16 //!< Максимальное количество фатальных исключений. 05903 #endif 05904 05905 //{---------------------------------------------------------------------------------------------------------------- 05908 //}---------------------------------------------------------------------------------------------------------------- 05909 05910 #ifdef FOR_DOXYGEN_ONLY 05911 #define _TX_FULL_STACKTRACE 05912 #endif 05913 05914 //{---------------------------------------------------------------------------------------------------------------- 05917 //}---------------------------------------------------------------------------------------------------------------- 05918 05919 #ifndef TX_COMPILED 05920 05921 bool _txProcessSystemWarnings = true; 05922 05923 #endif // TX_COMPILED 05924 05925 extern bool _txProcessSystemWarnings; 05926 05927 //{---------------------------------------------------------------------------------------------------------------- 05941 //}---------------------------------------------------------------------------------------------------------------- 05942 05943 #if !defined (_TX_WAITABLE_PARENTS) 05944 #define _TX_WAITABLE_PARENTS "Winpty-agent.exe:Clion.exe, " /* 0: CLion32 */ \ 05945 "Winpty-agent.exe:Clion64.exe, " /* 1: CLion64 */ \ 05946 "starter.exe:eclipse.exe, " /* 2: Eclipse 4 */ \ 05947 "starter.exe:javaw.exe, " /* 3: Eclipse 3 */ \ 05948 "cmd.exe:devenv.exe, " /* 4: MSVS 2003+ */ \ 05949 "VSDebugConsole.exe:devenv.exe, " /* 5: MSVS 2019+ */ \ 05950 "VSDebugConsole.exe:msvsmon.exe, " /* 6: MSVS 2022 x86 */ \ 05951 "consolepauser.exe:devcpp.exe, " /* 7: Dev-Cpp */ \ 05952 "cb_console_runner.exe:codeblocks.exe" /* 8: CodeBlocks 8+ */ 05953 #endif 05954 05955 //{---------------------------------------------------------------------------------------------------------------- 05974 //}---------------------------------------------------------------------------------------------------------------- 05975 05976 #if !defined (_TX_ALLOW_KILL_PARENT) // DISCLAIMER: Я не призываю к убийству родителей. 05977 #define _TX_ALLOW_KILL_PARENT true // Это технический термин. 05978 #endif // г_дам юристам привет. 05979 05980 //{---------------------------------------------------------------------------------------------------------------- 05990 //}---------------------------------------------------------------------------------------------------------------- 05991 05992 #ifndef TX_COMPILED 05993 05994 int _txWatchdogTimeout = 10*_TX_TIMEOUT; 05995 05996 #endif // TX_COMPILED 05997 05998 extern int _txWatchdogTimeout; 05999 06000 //{---------------------------------------------------------------------------------------------------------------- 06069 //}---------------------------------------------------------------------------------------------------------------- 06071 06072 #ifdef FOR_DOXYGEN_ONLY 06073 06074 #define TX_COMPILED 06075 06076 #endif 06077 06079 06081 //} 06082 //================================================================================================================= 06083 06084 //================================================================================================================= 06085 //{ Internal diagnostics 06087 //================================================================================================================= 06089 //{---------------------------------------------------------------------------------------------------------------- 06129 //}---------------------------------------------------------------------------------------------------------------- 06130 06131 #ifdef FOR_DOXYGEN_ONLY 06132 #define _TX_ALLOW_TRACE 06133 #endif 06134 06135 //{---------------------------------------------------------------------------------------------------------------- 06165 //}---------------------------------------------------------------------------------------------------------------- 06166 06167 #ifdef FOR_DOXYGEN_ONLY 06168 #define TX_TRACE 06169 #endif 06170 06171 #if !defined (TX_TRACE) 06172 #define TX_TRACE { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); } 06173 #endif 06174 06176 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...); 06178 06179 //{---------------------------------------------------------------------------------------------------------------- 06182 06183 #ifndef FOR_DOXYGEN_ONLY 06184 06185 struct _txLoc 06186 { 06187 const char* func; 06188 const char* file; 06189 int line; 06190 06191 int inTX; // We are inside one of TXLib functions 06192 int trace; // Internal TX trace level, when enabled by _TX_ALLOW_TRACE 06193 06194 const _txLoc* prev; // Caller's location 06195 06196 static _txLoc _tx_thread Cur; 06197 }; 06198 06199 struct _txFuncEntry 06200 { 06201 typedef _txFuncEntry this_t; 06202 06203 _txLoc loc; 06204 06205 _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; } 06206 void restore() { _txLoc::Cur = loc; } 06207 ~_txFuncEntry() { restore(); } 06208 06209 private: 06210 _txFuncEntry (const this_t&) _tx_delete; 06211 this_t& operator = (const this_t&) _tx_delete; 06212 }; 06213 06214 #if defined (_GCC_VER) 06215 06216 inline const char* __txLocCurSet (const char* _file, int _line, const char* _func) 06217 { _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; } 06218 06219 #else 06220 06221 #define __txLocCurSet( _file, _line, _func ) \ 06222 ( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) ) 06223 06224 #endif 06225 06226 #define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__) 06227 06228 #define _txLocLvlSet(lvl) { _txLoc::Cur.trace = (lvl); } 06229 06230 //{---------------------------------------------------------------------------------------------------------------- 06231 06232 #if defined ($0) 06233 #undef $0 06234 #endif 06235 06236 #if defined ($1) 06237 #undef $1 06238 #endif 06239 06240 #if defined ($2) 06241 #undef $2 06242 #endif 06243 06244 #if defined ($3) 06245 #undef $3 06246 #endif 06247 06248 #if defined ($4) 06249 #undef $4 06250 #endif 06251 06252 #if defined ($5) 06253 #undef $5 06254 #endif 06255 06256 #if defined ($6) 06257 #undef $6 06258 #endif 06259 06260 #if defined ($7) 06261 #undef $7 06262 #endif 06263 06264 #if defined ($8) 06265 #undef $8 06266 #endif 06267 06268 #if defined ($9) 06269 #undef $9 06270 #endif 06271 06272 #if defined ($) 06273 #undef $ 06274 #endif 06275 06276 #if defined ($$) 06277 #undef $$ 06278 #endif 06279 06280 //} 06281 //----------------------------------------------------------------------------------------------------------------- 06282 06283 #if defined (_TX_ALLOW_TRACE) 06284 06285 #define _txEntry(lvl) _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl); $; } 06286 06287 #define $ { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } } 06288 06289 #define $$ { __txFuncEntry.restore(); } 06290 06291 #elif defined (_DEBUG) 06292 06293 #define _txEntry(lvl) _txFuncEntry __txFuncEntry; { $; } 06294 06295 #define $ { _txLocCurSet(); } 06296 06297 #define $$ { __txFuncEntry.restore(); } 06298 06299 #else 06300 06301 #define _txEntry(lvl) ; 06302 #define $ ; 06303 #define $$ ; 06304 06305 #endif 06306 06307 //{---------------------------------------------------------------------------------------------------------------- 06308 06309 #define $0 _txEntry (0) // (Log level unchanged) 06310 #define $1 _txEntry (1) // Regular functions 06311 #define $2 _txEntry (2) // Resvd 06312 #define $3 _txEntry (3) // Init/Cleanup 06313 #define $4 _txEntry (4) // Init/Cleanup, misc functions 06314 #define $5 _txEntry (5) // Error handling, entry points 06315 #define $6 _txEntry (6) // Error handling, main part 06316 #define $7 _txEntry (7) // Error handling, misc functions 06317 #define $8 _txEntry (8) // Canvas worker thread 06318 #define $9 _txEntry (9) // Resvd 06319 06320 //} 06321 //----------------------------------------------------------------------------------------------------------------- 06322 06323 #endif // FOR_DOXYGEN_ONLY 06324 06327 //}---------------------------------------------------------------------------------------------------------------- 06328 06330 //} 06331 //================================================================================================================= 06332 06333 //================================================================================================================= 06334 //{ Sweet critical section blocking: txAutoLock class 06335 //================================================================================================================= 06336 06337 //{---------------------------------------------------------------------------------------------------------------- 06353 //}---------------------------------------------------------------------------------------------------------------- 06354 06356 extern CRITICAL_SECTION _txCanvas_LockBackBuf; 06358 06359 class txAutoLock 06360 { 06361 typedef txAutoLock this_t; 06362 06363 public: 06364 06365 //{---------------------------------------------------------------------------------------------------------------- 06388 //}---------------------------------------------------------------------------------------------------------------- 06389 06390 explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) : 06391 cs_ (cs) 06392 { 06393 $1 if (!cs_) return; 06394 06395 if (mandatory) {$ EnterCriticalSection (cs_); } 06396 else {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); } 06397 } 06398 06399 //{---------------------------------------------------------------------------------------------------------------- 06412 //}---------------------------------------------------------------------------------------------------------------- 06413 06414 explicit txAutoLock (bool mandatory = true) : 06415 cs_ (NULL) 06416 { 06417 $1 new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory); 06418 } 06419 06420 //{---------------------------------------------------------------------------------------------------------------- 06422 //}---------------------------------------------------------------------------------------------------------------- 06423 06424 ~txAutoLock() 06425 { 06426 $1 if (!cs_) return; 06427 $ LeaveCriticalSection (cs_); cs_ = NULL; 06428 } 06429 06430 //{---------------------------------------------------------------------------------------------------------------- 06433 //}---------------------------------------------------------------------------------------------------------------- 06434 06435 operator bool () const 06436 { 06437 $1 return (cs_ != NULL); 06438 } 06439 06440 //{---------------------------------------------------------------------------------------------------------------- 06442 //}---------------------------------------------------------------------------------------------------------------- 06443 06444 // private: 06445 CRITICAL_SECTION* cs_; 06446 06447 //{---------------------------------------------------------------------------------------------------------------- 06449 //}---------------------------------------------------------------------------------------------------------------- 06451 06452 private: 06453 txAutoLock (const this_t&) _tx_delete; 06454 this_t& operator = (const this_t&) _tx_delete; 06455 06457 06458 }; 06459 06460 //} 06461 //================================================================================================================= 06462 06463 //================================================================================================================= 06464 //{ Dialogs: txDialog class 06466 //================================================================================================================= 06468 //{---------------------------------------------------------------------------------------------------------------- 06489 //}---------------------------------------------------------------------------------------------------------------- 06490 06491 struct txDialog 06492 { 06493 typedef txDialog this_t; 06494 06495 //{---------------------------------------------------------------------------------------------------------------- 06508 //}---------------------------------------------------------------------------------------------------------------- 06509 06510 public: 06511 enum CONTROL 06512 { 06513 DIALOG = (int) 0x00000000, 06514 BUTTON = (int) 0xFFFF0080, 06515 EDIT = (int) 0xFFFF0081, 06516 STATIC = (int) 0xFFFF0082, 06517 LISTBOX = (int) 0xFFFF0083, 06518 SCROLLBAR = (int) 0xFFFF0084, 06519 COMBOBOX = (int) 0xFFFF0085, 06520 END = (int) 0x00000000 06521 }; 06522 06523 //{---------------------------------------------------------------------------------------------------------------- 06540 //}---------------------------------------------------------------------------------------------------------------- 06541 06542 public: 06543 struct Layout 06544 { //-V802 06545 CONTROL wndclass; 06546 const char* caption; 06547 WORD id; 06548 short x; 06549 short y; 06550 short sx; 06551 short sy; 06552 DWORD style; 06553 06554 const char* font; 06555 WORD fontsize; 06556 }; 06557 06558 //{---------------------------------------------------------------------------------------------------------------- 06566 //}---------------------------------------------------------------------------------------------------------------- 06567 06568 public: 06569 txDialog(); 06570 06571 //{---------------------------------------------------------------------------------------------------------------- 06581 //}---------------------------------------------------------------------------------------------------------------- 06582 06583 explicit txDialog (const Layout* layout); 06584 06585 //{---------------------------------------------------------------------------------------------------------------- 06587 //}---------------------------------------------------------------------------------------------------------------- 06588 06589 virtual ~txDialog() {}; 06590 06591 //{---------------------------------------------------------------------------------------------------------------- 06603 //}---------------------------------------------------------------------------------------------------------------- 06604 06605 const Layout* setLayout (const Layout *layout); 06606 06607 //{---------------------------------------------------------------------------------------------------------------- 06625 //}---------------------------------------------------------------------------------------------------------------- 06626 06627 virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam); 06628 06629 //{---------------------------------------------------------------------------------------------------------------- 06645 //}---------------------------------------------------------------------------------------------------------------- 06646 06647 intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0); 06648 06649 //{---------------------------------------------------------------------------------------------------------------- 06662 //}---------------------------------------------------------------------------------------------------------------- 06663 06664 intptr_t dialogBox (WORD resource); 06665 06666 //{---------------------------------------------------------------------------------------------------------------- 06668 //}---------------------------------------------------------------------------------------------------------------- 06669 06670 private: 06671 txDialog (const this_t&) _tx_delete; 06672 this_t& operator = (const this_t&) _tx_delete; 06673 06674 //{---------------------------------------------------------------------------------------------------------------- 06676 //}---------------------------------------------------------------------------------------------------------------- 06677 06678 protected: 06679 static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam); 06680 06681 //{---------------------------------------------------------------------------------------------------------------- 06683 //}---------------------------------------------------------------------------------------------------------------- 06684 06685 private: 06686 const Layout* layout_; 06687 }; 06688 06690 //} 06691 //================================================================================================================= 06692 06693 //================================================================================================================= 06694 //{ Dialogs: Message Map macros 06696 //================================================================================================================= 06698 //{---------------------------------------------------------------------------------------------------------------- 06719 //}---------------------------------------------------------------------------------------------------------------- 06720 06721 #define TX_BEGIN_MESSAGE_MAP() \ 06722 virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \ 06723 { \ 06724 int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result; \ 06725 \ 06726 switch (_msg) \ 06727 { \ 06728 case WM_NULL: 06729 06730 //{---------------------------------------------------------------------------------------------------------------- 06749 //}---------------------------------------------------------------------------------------------------------------- 06750 06751 #define TX_HANDLE( id ) \ 06752 break; \ 06753 case (id): 06754 06755 //{---------------------------------------------------------------------------------------------------------------- 06775 //}---------------------------------------------------------------------------------------------------------------- 06776 06777 #define TX_COMMAND_MAP \ 06778 default: break; \ 06779 } \ 06780 \ 06781 if (_msg == WM_COMMAND) switch (LOWORD (_wParam)) \ 06782 { \ 06783 case 0: 06784 06785 //{---------------------------------------------------------------------------------------------------------------- 06804 //}---------------------------------------------------------------------------------------------------------------- 06805 06806 #define TX_END_MESSAGE_MAP \ 06807 default: break; \ 06808 } \ 06809 \ 06810 return FALSE; \ 06811 } 06812 06814 //} 06815 //================================================================================================================= 06816 06817 //================================================================================================================= 06818 //{ Dialogs: txDialog example: txInputBox() 06820 //================================================================================================================= 06822 //{---------------------------------------------------------------------------------------------------------------- 06842 //}---------------------------------------------------------------------------------------------------------------- 06843 06844 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard; 06845 06846 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 06847 06848 const char* txInputBox (const char* text, const char* caption, const char* input) 06849 { 06850 //------------------------------------------------------------------------------------------------------------- 06851 // Если не указаны параметры, приходится использовать хоть какие-то надписи. 06852 // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название. 06853 //------------------------------------------------------------------------------------------------------------- 06854 06855 if (!text) text = "Введите строку:"; 06856 if (!caption) caption = txGetModuleFileName (false); 06857 if (!input) input = ""; 06858 06859 //------------------------------------------------------------------------------------------------------------- 06860 // Идентификаторы элементов диалога. Они требуются в GetDlgItemText(). 06861 // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически. 06862 // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы 06863 // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения, 06864 // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о 06865 //------------------------------------------------------------------------------------------------------------- 06866 06867 #define ID_TEXT_ 101 06868 #define ID_INPUT_ 102 06869 06870 //------------------------------------------------------------------------------------------------------------- 06871 // Задание макета (вида) диалога в виде массива структур. 06872 // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив 06873 // становится похож на описание ресурса диалога в .rc-файле. 06874 // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com). 06875 //------------------------------------------------------------------------------------------------------------- 06876 06877 txDialog::Layout layout[] = 06878 06879 //----------------------+----------+-----------+-----------------+--------------------------------------------- 06880 // Тип элемента | Имя | Иденти- | Координаты | Флаги элементов 06881 // диалога | элемента | фикатор |-----------------| (см. описание элементов 06882 // | | элемента | X | Y |Шир.|Выс.| окон диалога в MSDN) 06883 //----------------------+----------+-----------+---+---+----+----+--------------------------------------------- 06884 // | | | | | | | 06885 {{ txDialog::DIALOG, caption, 0, 0, 0, 240, 85 }, 06886 { txDialog::STATIC, text, ID_TEXT_, 10, 10, 150, 40, SS_LEFT }, 06887 { txDialog::EDIT, input, ID_INPUT_, 10, 60, 220, 15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP }, 06888 { txDialog::BUTTON, "&OK", IDOK, 180, 10, 50, 15, BS_DEFPUSHBUTTON | WS_TABSTOP }, 06889 { txDialog::BUTTON, "&Cancel", IDCANCEL, 180, 30, 50, 15, BS_PUSHBUTTON | WS_TABSTOP }, 06890 { txDialog::END }}; 06891 06892 //------------------------------------------------------------------------------------------------------------- 06893 // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним. 06894 // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она 06895 // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную 06896 // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее 06897 // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG). 06898 //------------------------------------------------------------------------------------------------------------- 06899 struct inputDlg : txDialog 06900 { 06901 char str [1024]; 06902 06903 //--------------------------------------------------------------------------------------------------------- 06904 06905 inputDlg() : 06906 str() 06907 {} 06908 06909 //--------------------------------------------------------------------------------------------------------- 06910 06911 TX_BEGIN_MESSAGE_MAP() // Карта сообщений (на самом деле это начало оконной функции). //-V2525 06912 06913 TX_COMMAND_MAP // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch). 06914 06915 //------------------------------------------------------------------------------------------------- 06916 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия 06917 // диалога строка ввода умрет и текст уже из нее получить. 06918 // Этот макрос на самом деле превращается в case из оператора switch. 06919 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP(). 06920 //------------------------------------------------------------------------------------------------- 06921 06922 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1); 06923 06924 TX_END_MESSAGE_MAP //-V2522 06925 06926 //--------------------------------------------------------------------------------------------------------- 06927 // Конец внутреннего класса диалога 06928 //--------------------------------------------------------------------------------------------------------- 06929 }; 06930 06931 //------------------------------------------------------------------------------------------------------------- 06932 // Убираем дефайны, чтобы потом не мешали. 06933 // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом 06934 // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _. 06935 // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны. 06936 //------------------------------------------------------------------------------------------------------------- 06937 06938 #undef ID_TEXT_ 06939 #undef ID_INPUT_ 06940 06941 //------------------------------------------------------------------------------------------------------------- 06942 // Это статический объект, потому что строка в нем должна жить после завершения функции. 06943 //------------------------------------------------------------------------------------------------------------- 06944 06945 static inputDlg dlg; 06946 06947 //------------------------------------------------------------------------------------------------------------- 06948 // Передаем layout и запускаем окно диалога 06949 //------------------------------------------------------------------------------------------------------------- 06950 06951 dlg.dialogBox (layout); 06952 06953 //------------------------------------------------------------------------------------------------------------- 06954 // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет 06955 // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать 06956 // синтаксически можно, но ведет к серьезным ошибкам. 06957 //------------------------------------------------------------------------------------------------------------- 06958 06959 return dlg.str; 06960 } 06961 06962 #endif // TX_COMPILED 06963 06965 //} 06966 //================================================================================================================= 06967 06968 //} 06969 //================================================================================================================= 06970 06971 //================================================================================================================= 06972 //{ TXLIB IMPLEMENTATION 06973 // Реализация функций библиотеки 06974 //================================================================================================================= 06976 06977 //----------------------------------------------------------------------------------------------------------------- 06978 //{ The Includes 06979 //----------------------------------------------------------------------------------------------------------------- 06980 06981 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 06982 06983 _TX_END_NAMESPACE 06984 06985 //----------------------------------------------------------------------------------------------------------------- 06986 06987 #if defined (_MSC_VER) 06988 #pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o 06989 06990 #pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch 06991 #pragma warning (disable: 4005) // 'name': macro redefinition 06992 #endif 06993 06994 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED) 06995 #undef __STRICT_ANSI__ 06996 #endif 06997 06998 //----------------------------------------------------------------------------------------------------------------- 06999 07000 #include <stdarg.h> 07001 #include <io.h> 07002 #include <fcntl.h> 07003 #include <process.h> 07004 #include <signal.h> 07005 #include <setjmp.h> 07006 #include <locale.h> 07007 #include <limits.h> 07008 #include <stdint.h> 07009 07010 #include <map> 07011 #include <numeric> 07012 #include <exception> 07013 #include <stdexcept> 07014 07015 #include <tlhelp32.h> 07016 #include <shellapi.h> 07017 07018 #if defined (_GCC_VER) 07019 07020 #include <shlobj.h> 07021 07022 #include <cxxabi.h> 07023 #include <unwind.h> 07024 07025 #endif 07026 07027 #if defined (__CYGWIN__) 07028 07029 #include <stdarg.h> 07030 #include <unistd.h> 07031 #include <termios.h> 07032 07033 #endif 07034 07035 #if defined (_MSC_VER) 07036 07037 #include <new.h> 07038 07039 #include <shlobj.h> 07040 #include <ntstatus.h> 07041 #include <crtdbg.h> 07042 #include <rtcapi.h> 07043 #include <dbghelp.h> 07044 07045 #endif 07046 07047 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 07048 #include <inttypes.h> 07049 #endif 07050 07051 //----------------------------------------------------------------------------------------------------------------- 07052 07053 #if defined (TX_USE_SPEAK) //-------------------------------------------------------------------------------------- 07054 #include <SAPI.h> // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :( 07055 #endif //-------------------------------------------------------------------------------------- 07056 07057 //----------------------------------------------------------------------------------------------------------------- 07058 07059 #if defined (_MSC_VER) 07060 #pragma warning (pop) // MSVC: Restore max level 07061 #endif 07062 07063 #if defined (__STRICT_ANSI__UNDEFINED) 07064 #define __STRICT_ANSI__ // Redefine back 07065 #endif 07066 07067 //----------------------------------------------------------------------------------------------------------------- 07068 07069 _TX_BEGIN_NAMESPACE 07070 07071 #endif // TX_COMPILED 07072 07073 //} 07074 //----------------------------------------------------------------------------------------------------------------- 07075 07076 //================================================================================================================= 07077 //{ DLL functions import, missing types definitions 07079 //================================================================================================================= 07081 07082 //----------------------------------------------------------------------------------------------------------------- 07083 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers. 07084 // Copied from Windows SDK 7.0a. 07085 //----------------------------------------------------------------------------------------------------------------- 07086 07087 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07088 07089 namespace Win32 { 07090 07091 #ifndef AC_SRC_ALPHA 07092 #define AC_SRC_ALPHA 0x01 07093 #endif 07094 07095 #ifndef SMTO_ERRORONEXIT 07096 #define SMTO_ERRORONEXIT 0x0020 07097 #endif 07098 07099 #ifndef NT_CONSOLE_PROPS_SIG 07100 #define NT_CONSOLE_PROPS_SIG 0xA0000002 07101 #endif 07102 07103 #ifndef NIIF_INFO 07104 #define NIIF_INFO 0x00000001 07105 #define NIIF_WARNING 0x00000002 07106 #define NIIF_ERROR 0x00000003 07107 #endif 07108 07109 #ifndef NIF_INFO 07110 #define NIF_STATE 0x00000008 07111 #define NIF_INFO 0x00000010 07112 #endif 07113 07114 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 07115 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x00000004 07116 #endif 07117 07118 #ifndef SYMOPT_CASE_INSENSITIVE 07119 #define SYMOPT_CASE_INSENSITIVE 0x00000001 07120 #define SYMOPT_UNDNAME 0x00000002 07121 #define SYMOPT_DEFERRED_LOADS 0x00000004 07122 #define SYMOPT_NO_CPP 0x00000008 07123 #define SYMOPT_LOAD_LINES 0x00000010 07124 #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 07125 #define SYMOPT_LOAD_ANYTHING 0x00000040 07126 #define SYMOPT_IGNORE_CVREC 0x00000080 07127 #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 07128 #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 07129 #define SYMOPT_EXACT_SYMBOLS 0x00000400 07130 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 07131 #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 07132 #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 07133 #define SYMOPT_PUBLICS_ONLY 0x00004000 07134 #define SYMOPT_NO_PUBLICS 0x00008000 07135 #define SYMOPT_AUTO_PUBLICS 0x00010000 07136 #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 07137 #define SYMOPT_SECURE 0x00040000 07138 #define SYMOPT_NO_PROMPTS 0x00080000 07139 #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 07140 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 07141 #define SYMOPT_FAVOR_COMPRESSED 0x00800000 07142 #define SYMOPT_FLAT_DIRECTORY 0x00400000 07143 #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 07144 #define SYMOPT_OVERWRITE 0x00100000 07145 #define SYMOPT_DEBUG 0x80000000 07146 #endif 07147 07148 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66. 07149 07150 #ifndef STATUS_POSSIBLE_DEADLOCK 07151 #define STATUS_POSSIBLE_DEADLOCK 0xC0000194 07152 #endif 07153 07154 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS 07155 #define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4 07156 #endif 07157 07158 #ifndef STATUS_STACK_BUFFER_OVERRUN 07159 #define STATUS_STACK_BUFFER_OVERRUN 0xC0000409 07160 #endif 07161 07162 #ifndef STATUS_ASSERTION_FAILURE 07163 #define STATUS_ASSERTION_FAILURE 0xC0000420 07164 #endif 07165 07166 #ifndef STATUS_WX86_BREAKPOINT 07167 #define STATUS_WX86_BREAKPOINT 0x4000001F 07168 #endif 07169 07170 #ifndef DBG_PRINTEXCEPTION_C 07171 #define DBG_PRINTEXCEPTION_C 0x40010006 // OutputDebugStringA() call 07172 #endif 07173 07174 #ifndef DBG_PRINTEXCEPTION_WIDE_C 07175 #define DBG_PRINTEXCEPTION_WIDE_C 0x4001000A // OutputDebugStringW() call 07176 #endif 07177 07178 #ifndef DBG_THREAD_NAME 07179 #define DBG_THREAD_NAME 0x406D1388 07180 #endif 07181 07182 #define EXCEPTION_CPP_MSC 0xE06D7363 // '?msc' 07183 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 0x19930520 // '?msc' version magic, see ehdata.h 07184 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 0x19930521 // '?msc' version magic 07185 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 0x19930522 // '?msc' version magic 07186 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1 0x01994000 // '?msc' version magic 07187 07188 #define EXCEPTION_CPP_GCC 0x20474343 // ' GCC' 07189 #define EXCEPTION_CPP_GCC_UNWIND 0x21474343 // '!GCC' 07190 #define EXCEPTION_CPP_GCC_FORCED 0x22474343 // '"GCC' 07191 07192 #define EXCEPTION_CLR_FAILURE 0xE0434f4D // 'аCOM' 07193 07194 #define EXCEPTION_CPP_BORLAND_BUILDER 0x0EEDFAE6 // Should never occur here 07195 #define EXCEPTION_CPP_BORLAND_DELPHI 0x0EEDFADE // Should never occur here 07196 07197 #pragma pack (push, 1) 07198 07199 struct CONSOLE_CURSOR_INFO 07200 { 07201 DWORD dwSize; 07202 BOOL bVisible; 07203 }; 07204 07205 struct CONSOLE_FONT_INFO 07206 { 07207 DWORD nFont; 07208 COORD dwFontSize; 07209 }; 07210 07211 struct CONSOLE_FONT_INFOEX 07212 { 07213 ULONG cbSize; 07214 DWORD nFont; 07215 COORD dwFontSize; 07216 UINT FontFamily; 07217 UINT FontWeight; 07218 WCHAR FaceName[LF_FACESIZE]; 07219 }; 07220 07221 struct DATABLOCK_HEADER 07222 { 07223 DWORD cbSize; 07224 DWORD dwSignature; 07225 }; 07226 07227 struct NT_CONSOLE_PROPS 07228 { 07229 DATABLOCK_HEADER dbh; 07230 07231 WORD wFillAttribute; 07232 WORD wPopupFillAttribute; 07233 COORD dwScreenBufferSize; 07234 COORD dwWindowSize; 07235 COORD dwWindowOrigin; 07236 DWORD nFont; 07237 DWORD nInputBufferSize; 07238 COORD dwFontSize; 07239 UINT uFontFamily; 07240 UINT uFontWeight; 07241 WCHAR FaceName[LF_FACESIZE]; 07242 UINT uCursorSize; 07243 BOOL bFullScreen; 07244 BOOL bQuickEdit; 07245 BOOL bInsertMode; 07246 BOOL bAutoPosition; 07247 UINT uHistoryBufferSize; 07248 UINT uNumberOfHistoryBuffers; 07249 BOOL bHistoryNoDup; 07250 07251 COLORREF ColorTable[16]; 07252 }; 07253 07254 struct FLASHWINFO 07255 { 07256 UINT cbSize; 07257 HWND hwnd; 07258 DWORD dwFlags; 07259 UINT uCount; 07260 DWORD dwTimeout; 07261 }; 07262 07263 enum TBPFLAG 07264 { 07265 TBPF_NOPROGRESS = 0x0, 07266 TBPF_INDETERMINATE = 0x1, 07267 TBPF_NORMAL = 0x2, 07268 TBPF_ERROR = 0x4, 07269 TBPF_PAUSED = 0x8 07270 }; 07271 07272 #pragma pack (pop) 07273 07274 const GUID IID_IShellLink = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 07275 const GUID IID_IShellLinkDataList = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}}; 07276 const GUID IID_IPersistFile = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 07277 07278 const GUID IID_ITaskbarList3 = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}}; 07279 const GUID CLSID_TaskbarList = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}}; 07280 07281 const GUID CLSID_SpVoice = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}}; 07282 const GUID IID_ISpVoice = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}}; 07283 07284 typedef DWORD NTSTATUS; 07285 typedef ULONG_PTR KAFFINITY; 07286 typedef LONG KPRIORITY; 07287 07288 struct UNICODE_STRING 07289 { 07290 USHORT Length; 07291 USHORT MaximumLength; 07292 wchar_t* Buffer; 07293 }; 07294 07295 struct RTL_DRIVE_LETTER_CURDIR 07296 { 07297 USHORT Flags; 07298 USHORT Length; 07299 ULONG TimeStamp; 07300 UNICODE_STRING DosPath; 07301 }; 07302 07303 struct CURDIR 07304 { 07305 UNICODE_STRING DosPath; 07306 void* Handle; 07307 }; 07308 07309 struct RTL_USER_PROCESS_PARAMETERS 07310 { 07311 ULONG AllocationSize; 07312 ULONG Size; 07313 ULONG Flags; 07314 ULONG DebugFlags; 07315 HANDLE ConsoleHandle; 07316 ULONG ConsoleFlags; 07317 HANDLE hStdInput; 07318 HANDLE hStdOutput; 07319 HANDLE hStdError; 07320 CURDIR CurrentDirectory; 07321 UNICODE_STRING DllPath; 07322 UNICODE_STRING ImagePathName; 07323 UNICODE_STRING CommandLine; 07324 wchar_t* Environment; 07325 ULONG dwX; 07326 ULONG dwY; 07327 ULONG dwXSize; 07328 ULONG dwYSize; 07329 ULONG dwXCountChars; 07330 ULONG dwYCountChars; 07331 ULONG dwFillAttribute; 07332 ULONG dwFlags; 07333 ULONG wShowWindow; 07334 UNICODE_STRING WindowTitle; 07335 UNICODE_STRING Desktop; 07336 UNICODE_STRING ShellInfo; 07337 UNICODE_STRING RuntimeInfo; 07338 RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; 07339 }; 07340 07341 struct PEB 07342 { 07343 BYTE Reserved1[2]; 07344 BYTE BeingDebugged; 07345 BYTE Reserved2[1]; 07346 void* Reserved3[2]; 07347 void* Ldr; 07348 RTL_USER_PROCESS_PARAMETERS* ProcessParameters; 07349 void* Reserved4[3]; 07350 void* AtlThunkSListPtr; 07351 void* Reserved5; 07352 ULONG Reserved6; 07353 void* Reserved7; 07354 ULONG Reserved8; 07355 ULONG AtlThunkSListPtr32; 07356 void* Reserved9[45]; 07357 BYTE Reserved10[96]; 07358 void* PostProcessInitRoutine; 07359 BYTE Reserved11[128]; 07360 void* Reserved12[1]; 07361 ULONG SessionId; 07362 }; 07363 07364 struct TEB 07365 { 07366 void* Reserved1[12]; 07367 PEB* ProcessEnvironmentBlock; 07368 void* Reserved2[399]; 07369 BYTE Reserved3[1952]; 07370 void* TlsSlots[64]; 07371 BYTE Reserved4[8]; 07372 void* Reserved5[26]; 07373 void* ReservedForOle; 07374 void* Reserved6[4]; 07375 void* TlsExpansionSlots; 07376 }; 07377 07378 struct PROCESS_BASIC_INFORMATION 07379 { 07380 NTSTATUS ExitStatus; 07381 PEB* PebBaseAddress; 07382 KAFFINITY AffinityMask; 07383 KPRIORITY BasePriority; 07384 ULONG_PTR UniqueProcessId; 07385 ULONG_PTR InheritedFromUniqueProcessId; 07386 }; 07387 07388 enum ADDRESS_MODE 07389 { 07390 AddrMode1616, 07391 AddrMode1632, 07392 AddrModeReal, 07393 AddrModeFlat 07394 }; 07395 07396 struct ADDRESS64 07397 { 07398 DWORD64 Offset; 07399 WORD Segment; 07400 ADDRESS_MODE Mode; 07401 }; 07402 07403 struct KDHELP64 07404 { 07405 DWORD64 Thread; 07406 DWORD ThCallbackStack; 07407 DWORD ThCallbackBStore; 07408 DWORD NextCallback; 07409 DWORD FramePointer; 07410 DWORD64 KiCallUserMode; 07411 DWORD64 KeUserCallbackDispatcher; 07412 DWORD64 SystemRangeStart; 07413 DWORD64 KiUserExceptionDispatcher; 07414 DWORD64 StackBase; 07415 DWORD64 StackLimit; 07416 DWORD64 Reserved[5]; 07417 }; 07418 07419 struct STACKFRAME64 07420 { 07421 ADDRESS64 AddrPC; 07422 ADDRESS64 AddrReturn; 07423 ADDRESS64 AddrFrame; 07424 ADDRESS64 AddrStack; 07425 ADDRESS64 AddrBStore; 07426 void* FuncTableEntry; 07427 DWORD64 Params[4]; 07428 BOOL Far; 07429 BOOL Virtual; 07430 DWORD64 Reserved[3]; 07431 KDHELP64 KdHelp; 07432 }; 07433 07434 struct WOW64_FLOATING_SAVE_AREA 07435 { 07436 DWORD ControlWord; 07437 DWORD StatusWord; 07438 DWORD TagWord; 07439 DWORD ErrorOffset; 07440 DWORD ErrorSelector; 07441 DWORD DataOffset; 07442 DWORD DataSelector; 07443 BYTE RegisterArea[80]; 07444 DWORD Cr0NpxState; 07445 }; 07446 07447 #pragma pack (push, 4) 07448 07449 struct WOW64_CONTEXT 07450 { 07451 DWORD ContextFlags; 07452 07453 DWORD Dr0; 07454 DWORD Dr1; 07455 DWORD Dr2; 07456 DWORD Dr3; 07457 DWORD Dr6; 07458 DWORD Dr7; 07459 07460 WOW64_FLOATING_SAVE_AREA FloatSave; 07461 07462 DWORD SegGs; 07463 DWORD SegFs; 07464 DWORD SegEs; 07465 DWORD SegDs; 07466 07467 DWORD Edi; 07468 DWORD Esi; 07469 DWORD Ebx; 07470 DWORD Edx; 07471 DWORD Ecx; 07472 DWORD Eax; 07473 07474 DWORD Ebp; 07475 DWORD Eip; 07476 DWORD SegCs; 07477 DWORD EFlags; 07478 DWORD Esp; 07479 DWORD SegSs; 07480 07481 BYTE ExtendedRegisters[512]; 07482 }; 07483 07484 #pragma pack (pop) 07485 07486 struct SYMBOL_INFO 07487 { 07488 ULONG SizeOfStruct; 07489 ULONG TypeIndex; 07490 ULONG64 Reserved[2]; 07491 ULONG info; 07492 ULONG Size; 07493 ULONG64 ModBase; 07494 ULONG Flags; 07495 ULONG64 Value; 07496 ULONG64 Address; 07497 ULONG Register; 07498 ULONG Scope; 07499 ULONG Tag; 07500 ULONG NameLen; 07501 ULONG MaxNameLen; 07502 char Name[1]; 07503 }; 07504 07505 struct IMAGEHLP_LINE64 07506 { 07507 DWORD SizeOfStruct; 07508 void* Key; 07509 DWORD LineNumber; 07510 char* FileName; 07511 DWORD64 Address; 07512 }; 07513 07514 typedef bool (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64) (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead); 07515 typedef void* (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress); 07516 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64) (HANDLE process, DWORD64 address); 07517 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64) (HANDLE process, HANDLE thread, ADDRESS64* address); 07518 07519 typedef void (*unexpected_handler)(); 07520 07521 #pragma pack (push, 4) 07522 07523 struct MINIDUMP_THREAD_CALLBACK 07524 { 07525 ULONG ThreadId; 07526 HANDLE ThreadHandle; 07527 CONTEXT Context; 07528 ULONG SizeOfContext; 07529 ULONG64 StackBase; 07530 ULONG64 StackEnd; 07531 }; 07532 07533 struct MINIDUMP_THREAD_EX_CALLBACK 07534 { 07535 ULONG ThreadId; 07536 HANDLE ThreadHandle; 07537 CONTEXT Context; 07538 ULONG SizeOfContext; 07539 ULONG64 StackBase; 07540 ULONG64 StackEnd; 07541 ULONG64 BackingStoreBase; 07542 ULONG64 BackingStoreEnd; 07543 }; 07544 07545 struct MINIDUMP_MODULE_CALLBACK 07546 { 07547 wchar_t* FullPath; 07548 ULONG64 BaseOfImage; 07549 ULONG SizeOfImage; 07550 ULONG CheckSum; 07551 ULONG TimeDateStamp; 07552 VS_FIXEDFILEINFO VersionInfo; 07553 void* CvRecord; 07554 ULONG SizeOfCvRecord; 07555 void* MiscRecord; 07556 ULONG SizeOfMiscRecord; 07557 }; 07558 07559 struct MINIDUMP_INCLUDE_THREAD_CALLBACK 07560 { 07561 ULONG ThreadId; 07562 }; 07563 07564 struct MINIDUMP_INCLUDE_MODULE_CALLBACK 07565 { 07566 ULONG64 BaseOfImage; 07567 }; 07568 07569 struct MINIDUMP_MEMORY_INFO 07570 { 07571 ULONG64 BaseAddress; 07572 ULONG64 AllocationBase; 07573 ULONG32 AllocationProtect; 07574 ULONG32 __alignment1; 07575 ULONG64 RegionSize; 07576 ULONG32 State; 07577 ULONG32 Protect; 07578 ULONG32 Type; 07579 ULONG32 __alignment2; 07580 }; 07581 07582 struct MINIDUMP_USER_STREAM 07583 { 07584 ULONG32 Type; 07585 ULONG BufferSize; 07586 void* Buffer; 07587 }; 07588 07589 struct MINIDUMP_USER_STREAM_INFORMATION 07590 { 07591 ULONG UserStreamCount; 07592 MINIDUMP_USER_STREAM* UserStreamArray; 07593 }; 07594 07595 struct MINIDUMP_CALLBACK_INPUT 07596 { 07597 ULONG ProcessId; 07598 HANDLE ProcessHandle; 07599 ULONG CallbackType; 07600 07601 union //-V2514 07602 { 07603 MINIDUMP_THREAD_CALLBACK Thread; 07604 MINIDUMP_THREAD_EX_CALLBACK ThreadEx; 07605 MINIDUMP_MODULE_CALLBACK Module; 07606 MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; 07607 MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; 07608 }; 07609 }; 07610 07611 struct MINIDUMP_CALLBACK_OUTPUT 07612 { 07613 union //-V2514 07614 { 07615 ULONG ModuleWriteFlags; 07616 ULONG ThreadWriteFlags; 07617 ULONG SecondaryFlags; 07618 07619 struct 07620 { 07621 ULONG64 MemoryBase; 07622 ULONG MemorySize; 07623 }; 07624 07625 struct 07626 { 07627 unsigned CheckCancel; 07628 unsigned Cancel; 07629 }; 07630 07631 HANDLE Handle; //-V117 07632 }; 07633 07634 struct 07635 { 07636 MINIDUMP_MEMORY_INFO VmRegion; 07637 unsigned Continue; 07638 }; 07639 07640 HRESULT Status; 07641 }; 07642 07643 struct MINIDUMP_EXCEPTION_INFORMATION 07644 { 07645 DWORD ThreadId; 07646 EXCEPTION_POINTERS* ExceptionPointers; 07647 unsigned ClientPointers; 07648 }; 07649 07650 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output); 07651 07652 struct MINIDUMP_CALLBACK_INFORMATION 07653 { 07654 MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; 07655 void* CallbackParam; 07656 }; 07657 07658 enum MINIDUMP_TYPE 07659 { 07660 MiniDumpNormal = 0x00000000, 07661 MiniDumpWithDataSegs = 0x00000001, 07662 MiniDumpWithFullMemory = 0x00000002, 07663 MiniDumpWithHandleData = 0x00000004, 07664 MiniDumpFilterMemory = 0x00000008, 07665 MiniDumpScanMemory = 0x00000010, 07666 MiniDumpWithUnloadedModules = 0x00000020, 07667 MiniDumpWithIndirectlyReferencedMemory = 0x00000040, 07668 MiniDumpFilterModulePaths = 0x00000080, 07669 MiniDumpWithProcessThreadData = 0x00000100, 07670 MiniDumpWithPrivateReadWriteMemory = 0x00000200, 07671 MiniDumpWithoutOptionalData = 0x00000400, 07672 MiniDumpWithFullMemoryInfo = 0x00000800, 07673 MiniDumpWithThreadInfo = 0x00001000, 07674 MiniDumpWithCodeSegs = 0x00002000, 07675 MiniDumpWithoutAuxiliaryState = 0x00004000, 07676 MiniDumpWithFullAuxiliaryState = 0x00008000, 07677 MiniDumpWithPrivateWriteCopyMemory = 0x00010000, 07678 MiniDumpIgnoreInaccessibleMemory = 0x00020000, 07679 MiniDumpWithTokenInformation = 0x00040000 07680 }; 07681 07682 #ifndef CONTEXT_ALL 07683 #define CONTEXT_ALL ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS ) 07684 #endif 07685 07686 #pragma pack (pop) 07687 07688 } // namespace Win32 07689 07690 #endif // TX_COMPILED 07691 07692 #define FOREGROUND_BLACK ( 0 ) 07693 #define FOREGROUND_CYAN ( FOREGROUND_BLUE | FOREGROUND_GREEN ) 07694 #define FOREGROUND_MAGENTA ( FOREGROUND_BLUE | FOREGROUND_RED ) 07695 #define FOREGROUND_DARKYELLOW ( FOREGROUND_GREEN | FOREGROUND_RED ) 07696 #define FOREGROUND_LIGHTGRAY ( FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ) 07697 #define FOREGROUND_DARKGRAY ( FOREGROUND_INTENSITY ) 07698 #define FOREGROUND_LIGHTBLUE ( FOREGROUND_BLUE | FOREGROUND_INTENSITY ) 07699 #define FOREGROUND_LIGHTGREEN ( FOREGROUND_GREEN | FOREGROUND_INTENSITY ) 07700 #define FOREGROUND_LIGHTCYAN ( FOREGROUND_CYAN | FOREGROUND_INTENSITY ) 07701 #define FOREGROUND_LIGHTRED ( FOREGROUND_RED | FOREGROUND_INTENSITY ) 07702 #define FOREGROUND_LIGHTMAGENTA ( FOREGROUND_MAGENTA | FOREGROUND_INTENSITY ) 07703 #define FOREGROUND_YELLOW ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY ) 07704 #define FOREGROUND_WHITE ( FOREGROUND_LIGHTGRAY | FOREGROUND_INTENSITY ) 07705 07706 #define BACKGROUND_BLACK ( 0 ) 07707 #define BACKGROUND_CYAN ( BACKGROUND_BLUE | BACKGROUND_GREEN ) 07708 #define BACKGROUND_MAGENTA ( BACKGROUND_BLUE | BACKGROUND_RED ) 07709 #define BACKGROUND_DARKYELLOW ( BACKGROUND_GREEN | BACKGROUND_RED ) 07710 #define BACKGROUND_GRAY ( BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED ) 07711 #define BACKGROUND_DARKGRAY ( BACKGROUND_INTENSITY ) 07712 #define BACKGROUND_LIGHTBLUE ( BACKGROUND_BLUE | BACKGROUND_INTENSITY ) 07713 #define BACKGROUND_LIGHTGREEN ( BACKGROUND_GREEN | BACKGROUND_INTENSITY ) 07714 #define BACKGROUND_LIGHTCYAN ( BACKGROUND_CYAN | BACKGROUND_INTENSITY ) 07715 #define BACKGROUND_LIGHTRED ( BACKGROUND_RED | BACKGROUND_INTENSITY ) 07716 #define BACKGROUND_LIGHTMAGENTA ( BACKGROUND_MAGENTA | BACKGROUND_INTENSITY ) 07717 #define BACKGROUND_LIGHTYELLOW ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY ) 07718 #define BACKGROUND_WHITE ( BACKGROUND_DARKGRAY | BACKGROUND_INTENSITY ) 07719 07720 //} 07721 //----------------------------------------------------------------------------------------------------------------- 07722 07723 //----------------------------------------------------------------------------------------------------------------- 07724 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode. 07725 // So we have to override them. See: http://stackoverflow.com/questions/39113168 07726 //----------------------------------------------------------------------------------------------------------------- 07727 07728 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07729 07730 #if defined (_MSC_VER) 07731 // MS ABI C++ Exception Layout 07732 namespace Win32 { // --------------------------- 07733 // 07734 #pragma pack (push, 4) // EXCEPTION_RECORD: 07735 // +==================================================+ 07736 struct ThrowInfo // |... | 07737 { // |NumberParameters: 3, 4 or more | 07738 __int32 attributes; // |ExceptionInformation[0]: MS signature 0x19930520 | 07739 __int32 pmfnUnwind; // |ExceptionInformation[1]: object* thrown | 07740 __int32 pForwardCompat; // |ExceptionInformation[2]: ThrowInfo* --------------+---+ 07741 __int32 pCatchableTypeArray; // |ExceptionInformation[3]: ImageBase (if params > 3)| | 07742 }; // +==================================================+ | 07743 // | 07744 struct CatchableTypeArray // ThrowInfo: | 07745 { // +======================================+ <-------+ 07746 __int32 nCatchableTypes; // | ... | 07747 __int32 arrayOfCatchableTypes[]; // +-----+-- pCatchableTypeArray (ptr/RVA) | 07748 }; // | +======================================+ 07749 // | 07750 struct CatchableType // | CatchableTypeArray: 07751 { // +---> +======================================+ 07752 __int32 properties; // | ... | 07753 __int32 pType; // +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) | 07754 __int32 thisDisplacement[3]; // struct _PMD // | +======================================+ 07755 __int32 sizeOrOffset; // | 07756 __int32 copyFunction; // | CatchableType: 07757 }; // +---> +====================+ 07758 // | ... | std::type_info: 07759 #pragma pack (pop) // | pType (ptr/RVA) ---+------> +==================+ 07760 // | ... | |type_info data | 07761 } // namespace Win32 // +====================+ |... | 07762 // +==================+ 07763 #endif 07764 07765 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp: 07766 07767 #define _TX_MSC__CXX_DETECT_RETHROW( exc ) \ 07768 ( \ 07769 (exc) && \ 07770 (exc) -> ExceptionCode == EXCEPTION_CPP_MSC && \ 07771 (exc) -> NumberParameters >= 3 && \ 07772 \ 07773 ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 || \ 07774 (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 || \ 07775 (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \ 07776 \ 07777 (exc) -> ExceptionInformation[2] == 0 \ 07778 ) 07779 07780 #endif // TX_COMPILED 07781 07782 //} 07783 //----------------------------------------------------------------------------------------------------------------- 07784 07785 //----------------------------------------------------------------------------------------------------------------- 07786 //{ The corresponding structures for GCC 07787 // 07788 // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h 07789 // See: http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi 07790 //----------------------------------------------------------------------------------------------------------------- 07791 07792 #if defined (_GCC_VER) 07793 07794 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07795 07796 // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0]. 07797 namespace ABI { // -------------------------------------------------------------- 07798 // 07799 struct __cxa_exception // Case A: "_Unwind_Exception* A" is independent exception: 07800 { // -------------------------------------------------------- 07801 union { // 07802 struct // __cxa_exception: std::type_info: 07803 { // -*--+====================+ +==================+ 07804 ::std::type_info* exceptionType; // ^ |exceptionType* -----+---->|type_info data | 07805 void (*exceptionDestructor)(void*); // | |... | |... | 07806 }; // -1 | | +==================+ 07807 struct // | | | 07808 { // A >----|--+--------------------+ 07809 __cxa_exception* primaryException; // | | |unwindHeader | 07810 void (*padding)(); // +1 | | | 07811 }; // | | | | 07812 }; // V | | | 07813 // -*--- +====================+ 07814 void (*unexpected_handler)(); // |object | 07815 std::terminate_handler terminateHandler; // +--------------------+ 07816 // 07817 __cxa_exception* nextException; // Case B: "_Unwind_Exception* B" is dependent exception 07818 int handlerCount; // (unwindHeader.exception_class & 1 != 0): 07819 int handlerSwitchValue; // ----------------------------------------------------- 07820 const unsigned char* actionRecord; // 07821 const unsigned char* languageSpecificData; // __cxa_exception: __cxa_exception: 07822 void* catchTemp; // -*--+====================+ -*--+=================+ 07823 void* adjustedPtr; // ^ |primaryException* --+-- ^ |exceptionType* | 07824 // | |... | \ | |... | 07825 _Unwind_Exception unwindHeader; // -1 | | | | | | 07826 }; // | | | | | | | 07827 // B >----|--+--------------------+ | -1 +-----------------+ 07828 struct __cxa_eh_globals // | | |unwindHeader | | | |unwindHeader | 07829 { // +1 | | | | | | | 07830 __cxa_exception* caughtExceptions; // | | | | | | | | 07831 unsigned int uncaughtExceptions; // V | | | \ | | | 07832 }; // -*--- +====================+ -->*--+=================+ 07833 // |... | |object | 07834 } // namespace ABI // . . | | 07835 // +-----------------+ 07836 07837 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals(); 07838 07839 #endif // TX_COMPILED 07840 07841 #endif 07842 07843 //} 07844 //----------------------------------------------------------------------------------------------------------------- 07845 07846 //----------------------------------------------------------------------------------------------------------------- 07847 //{ Hand-made IAT. 07848 // Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :( 07849 //----------------------------------------------------------------------------------------------------------------- 07850 07851 // Hand-made DLLIMPORT helpers 07852 07853 #define _TX_DLLIMPORT( lib, retval, name, params ) TX_DLLIMPORT (true, lib ".dll", retval, name, params, WINAPI) 07854 #define _TX_DLLIMPORT_OPT( lib, retval, name, params ) TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI) 07855 #define _TX_DLLIMPORT_CRT( lib, retval, name, params ) TX_DLLIMPORT (false, lib ".dll", retval, name, params, please) 07856 07857 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) (); 07858 07859 //----------------------------------------------------------------------------------------------------------------- 07860 07861 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07862 07863 namespace Win32 { 07864 07865 _TX_DLLIMPORT ("GDI32", HDC, CreateCompatibleDC, (HDC dc)); 07866 _TX_DLLIMPORT ("GDI32", HBITMAP, CreateCompatibleBitmap, (HDC dc, int width, int height)); 07867 _TX_DLLIMPORT ("GDI32", HGDIOBJ, GetStockObject, (int object)); 07868 _TX_DLLIMPORT ("GDI32", HGDIOBJ, SelectObject, (HDC dc, HGDIOBJ object)); 07869 _TX_DLLIMPORT ("GDI32", HGDIOBJ, GetCurrentObject, (HDC dc, unsigned objectType)); 07870 _TX_DLLIMPORT ("GDI32", int, GetObjectA, (HGDIOBJ obj, int bufsize, void* buffer)); 07871 _TX_DLLIMPORT ("GDI32", DWORD, GetObjectType, (HGDIOBJ object)); 07872 _TX_DLLIMPORT ("GDI32", bool, DeleteDC, (HDC dc)); 07873 _TX_DLLIMPORT ("GDI32", bool, DeleteObject, (HGDIOBJ object)); 07874 _TX_DLLIMPORT ("GDI32", COLORREF, SetTextColor, (HDC dc, COLORREF color)); 07875 _TX_DLLIMPORT ("GDI32", COLORREF, SetBkColor, (HDC dc, COLORREF color)); 07876 _TX_DLLIMPORT ("GDI32", int, SetBkMode, (HDC dc, int bkMode)); 07877 _TX_DLLIMPORT ("GDI32", HFONT, CreateFontA, (int height, int width, int escapement, int orientation, 07878 int weight, DWORD italic, DWORD underline, DWORD strikeout, 07879 DWORD charSet, DWORD outputPrec, DWORD clipPrec, 07880 DWORD quality, DWORD pitchAndFamily, const char face[])); 07881 _TX_DLLIMPORT ("GDI32", int, EnumFontFamiliesExA, (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc, 07882 LPARAM lParam, DWORD reserved)); 07883 _TX_DLLIMPORT ("GDI32", COLORREF, SetPixel, (HDC dc, int x, int y, COLORREF color)); 07884 _TX_DLLIMPORT ("GDI32", COLORREF, GetPixel, (HDC dc, int x, int y)); 07885 _TX_DLLIMPORT ("GDI32", HPEN, CreatePen, (int penStyle, int width, COLORREF color)); 07886 _TX_DLLIMPORT ("GDI32", HBRUSH, CreateSolidBrush, (COLORREF color)); 07887 _TX_DLLIMPORT ("GDI32", bool, MoveToEx, (HDC dc, int x, int y, POINT* point)); 07888 _TX_DLLIMPORT ("GDI32", bool, LineTo, (HDC dc, int x, int y)); 07889 _TX_DLLIMPORT ("GDI32", bool, Polygon, (HDC dc, const POINT points[], int count)); 07890 _TX_DLLIMPORT ("GDI32", bool, Polyline, (HDC dc, const POINT points[], int count)); 07891 _TX_DLLIMPORT ("GDI32", bool, PolyBezier, (HDC dc, const POINT points[], int count)); 07892 _TX_DLLIMPORT ("GDI32", bool, Rectangle, (HDC dc, int x0, int y0, int x1, int y1)); 07893 _TX_DLLIMPORT ("GDI32", bool, RoundRect, (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY)); 07894 _TX_DLLIMPORT ("GDI32", bool, Ellipse, (HDC dc, int x0, int y0, int x1, int y1)); 07895 _TX_DLLIMPORT ("GDI32", bool, Arc, (HDC dc, int x0, int y0, int x1, int y1, 07896 int xStart, int yStart, int xEnd, int yEnd)); 07897 _TX_DLLIMPORT ("GDI32", bool, Pie, (HDC dc, int x0, int y0, int x1, int y1, 07898 int xStart, int yStart, int xEnd, int yEnd)); 07899 _TX_DLLIMPORT ("GDI32", bool, Chord, (HDC dc, int x0, int y0, int x1, int y1, 07900 int xStart, int yStart, int xEnd, int yEnd)); 07901 _TX_DLLIMPORT ("GDI32", bool, TextOutA, (HDC dc, int x, int y, const char string[], int length)); 07902 _TX_DLLIMPORT ("GDI32", UINT, SetTextAlign, (HDC dc, unsigned mode)); 07903 _TX_DLLIMPORT ("GDI32", bool, GetTextExtentPoint32A, (HDC dc, const char string[], int length, SIZE* size)); 07904 _TX_DLLIMPORT ("GDI32", bool, ExtFloodFill, (HDC dc, int x, int y, COLORREF color, unsigned type)); 07905 _TX_DLLIMPORT ("GDI32", bool, BitBlt, (HDC dest, int xDest, int yDest, int width, int height, 07906 HDC src, int xSrc, int ySrc, DWORD rOp)); 07907 _TX_DLLIMPORT ("GDI32", bool, StretchBlt, (HDC dest, int xDest, int yDest, int width, int height, 07908 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp)); 07909 _TX_DLLIMPORT ("GDI32", bool, PlgBlt, (HDC dest, const POINT* parallelogram, 07910 HDC src, int xSrc, int ySrc, int width, int height, 07911 HBITMAP mask, int xMask, int yMask)); 07912 _TX_DLLIMPORT ("GDI32", int, SetDIBitsToDevice, (HDC dc, int xDest, int yDest, DWORD width, DWORD height, 07913 int xSrc, int ySrc, unsigned startLine, unsigned numLines, 07914 const void* data, const BITMAPINFO* info, unsigned colorUse)); 07915 _TX_DLLIMPORT ("GDI32", int, GetDIBits, (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines, 07916 void* lpvBits, BITMAPINFO* lpbi, unsigned usage)); 07917 _TX_DLLIMPORT ("GDI32", bool, PatBlt, (HDC dc, int x0, int y0, int width, int height, DWORD rOp)); 07918 _TX_DLLIMPORT ("GDI32", int, SetROP2, (HDC dc, int mode)); 07919 _TX_DLLIMPORT ("GDI32", int, SetStretchBltMode, (HDC dc, int mode)); 07920 _TX_DLLIMPORT ("GDI32", DWORD, GdiSetBatchLimit, (DWORD limit)); 07921 _TX_DLLIMPORT ("GDI32", HBITMAP, CreateDIBSection, (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits, 07922 HANDLE section, DWORD offset)); 07923 07924 _TX_DLLIMPORT ("User32", int, DrawTextA, (HDC dc, const char text[], int length, RECT* rect, unsigned format)); 07925 _TX_DLLIMPORT ("User32", HANDLE, LoadImageA, (HINSTANCE inst, const char name[], unsigned type, 07926 int sizex, int sizey, unsigned mode)); 07927 _TX_DLLIMPORT_OPT ("User32", bool, IsHungAppWindow, (HWND wnd)); 07928 _TX_DLLIMPORT_OPT ("User32", HWND, GhostWindowFromHungWindow, (HWND wnd)); 07929 _TX_DLLIMPORT_OPT ("User32", bool, FlashWindowEx, (const FLASHWINFO* flash)); 07930 07931 _TX_DLLIMPORT ("WinMM", bool, PlaySound, (const char sound[], HMODULE mod, DWORD mode)); 07932 07933 _TX_DLLIMPORT_OPT ("MSImg32", bool, TransparentBlt, (HDC dest, int destX, int destY, int destWidth, int destHeight, 07934 HDC src, int srcX, int srcY, int srcWidth, int srcHeight, 07935 unsigned transparentColor)); 07936 _TX_DLLIMPORT_OPT ("MSImg32", bool, AlphaBlend, (HDC dest, int destX, int destY, int destWidth, int destHeight, 07937 HDC src, int srcX, int srcY, int srcWidth, int srcHeight, 07938 BLENDFUNCTION blending)); 07939 07940 _TX_DLLIMPORT ("Kernel32", void, ExitProcess, (unsigned retcode)); 07941 _TX_DLLIMPORT ("Kernel32", bool, TerminateProcess, (HANDLE process, unsigned retcode)); 07942 _TX_DLLIMPORT_OPT ("Kernel32", void, FatalExit, (int retcode)); 07943 _TX_DLLIMPORT_OPT ("Kernel32", void, FatalAppExitA, (unsigned action, const char message[])); 07944 _TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetThreadId, (HANDLE thread)); 07945 _TX_DLLIMPORT ("Kernel32", HWND, GetConsoleWindow, (void)); 07946 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetConsoleFont, (HANDLE con, DWORD fontIndex)); 07947 _TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetNumberOfConsoleFonts, (void)); 07948 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetCurrentConsoleFont, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO* curFont)); 07949 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont)); 07950 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont)); 07951 _TX_DLLIMPORT_OPT ("Kernel32", void, RtlCaptureContext, (CONTEXT* contextRecord)); 07952 _TX_DLLIMPORT_OPT ("Kernel32", USHORT, RtlCaptureStackBackTrace, (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash)); 07953 _TX_DLLIMPORT_OPT ("Kernel32", void*, AddVectoredExceptionHandler, (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler)); 07954 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler)); 07955 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetModuleHandleEx, (DWORD flags, const char moduleName[], HMODULE* module)); 07956 _TX_DLLIMPORT_OPT ("Kernel32", bool, IsWow64Process, (HANDLE process, int* isWow64Process)); 07957 _TX_DLLIMPORT_OPT ("Kernel32", bool, Wow64GetThreadContext, (HANDLE thread, WOW64_CONTEXT* context)); 07958 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetThreadStackGuarantee, (unsigned long* stackSize)); 07959 07960 _TX_DLLIMPORT ("OLE32", HRESULT, CoInitialize, (void*)); 07961 _TX_DLLIMPORT ("OLE32", HRESULT, CoCreateInstance, (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value)); 07962 _TX_DLLIMPORT ("OLE32", void, CoUninitialize, (void)); 07963 07964 _TX_DLLIMPORT ("Shell32", HINSTANCE,ShellExecuteA, (HWND wnd, const char operation[], const char file[], 07965 const char parameters[], const char directory[], int showCmd)); 07966 07967 _TX_DLLIMPORT ("ShlWAPI", char*, StrStrIA, (const char string[], const char search[])); 07968 _TX_DLLIMPORT ("ShlWAPI", char*, StrStrIW, (const wchar_t string[], const wchar_t search[])); 07969 07970 _TX_DLLIMPORT_OPT ("NTDLL", char*, wine_get_version, (void)); 07971 _TX_DLLIMPORT ("NTDLL", NTSTATUS, NtQueryInformationProcess, (HANDLE process, int infoClass, 07972 void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo)); 07973 07974 _TX_DLLIMPORT_CRT ("MSVCRT", void, exit, (int retcode)); 07975 _TX_DLLIMPORT_CRT ("MSVCRT", void, _cexit, (void)); 07976 _TX_DLLIMPORT_CRT ("MSVCRT", unsigned, _fpreset, (void)); 07977 _TX_DLLIMPORT_CRT ("MSVCRT", unsigned, _controlfp, (unsigned control, unsigned mask)); 07978 _TX_DLLIMPORT_CRT ("MSVCRT", uintptr_t,_beginthread, (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist)); 07979 _TX_DLLIMPORT_CRT ("MSVCRT", uintptr_t,_beginthreadex, (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*), 07980 void *arglist, unsigned init_flag, unsigned* thread_addr)); 07981 _TX_DLLIMPORT_CRT ("MSVCRT", char*, __unDName, (char* outStr, const char* mangledName, int outStrLen, 07982 void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer), 07983 unsigned short flags)); 07984 _TX_DLLIMPORT_CRT ("MSVCRT", unexpected_handler, set_unexpected, (unexpected_handler handler)); 07985 07986 _TX_DLLIMPORT_OPT ("OpenGL32", HDC, wglGetCurrentDC, (void)); 07987 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned, glGetError, (void)); 07988 _TX_DLLIMPORT_OPT ("Glu32", const char*, gluErrorString, (unsigned error)); 07989 07990 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD, CommDlgExtendedError, (void)); 07991 07992 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, MiniDumpWriteDump, (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType, 07993 MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, 07994 MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, 07995 MINIDUMP_CALLBACK_INFORMATION* callbackParam)); 07996 07997 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD, SymSetOptions, (DWORD options)); 07998 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymInitialize, (HANDLE process, const char userSearchPath[], bool invadeProcess)); 07999 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymFromAddr, (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO* symbol)); 08000 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymGetLineFromAddr64, (HANDLE process, DWORD64 addr, DWORD* offset, IMAGEHLP_LINE64* line)); 08001 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64, SymGetModuleBase64, (HANDLE process, DWORD64 addr)); 08002 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymCleanup, (HANDLE process)); 08003 _TX_DLLIMPORT_OPT ("DbgHelp*", void*, SymFunctionTableAccess64, (HANDLE process, DWORD64 addrBase)); 08004 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, StackWalk64, (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord, 08005 PREAD_PROCESS_MEMORY_ROUTINE64 readMemoryFunc, 08006 PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc, 08007 PGET_MODULE_BASE_ROUTINE64 getModuleBaseFunc, 08008 PTRANSLATE_ADDRESS_ROUTINE64 translateAddressFunc)); 08009 namespace MinGW { 08010 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD, SymSetOptions, (DWORD options)); 08011 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymInitialize, (HANDLE process, const char userSearchPath[], bool invadeProcess)); 08012 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymFromAddr, (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO* symbol)); 08013 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymGetLineFromAddr64, (HANDLE process, DWORD64 addr, DWORD* offset, IMAGEHLP_LINE64* line)); 08014 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64, SymGetModuleBase64, (HANDLE process, DWORD64 addr)); 08015 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymCleanup, (HANDLE process)); 08016 _TX_DLLIMPORT_OPT ("MgwHelp*", void*, SymFunctionTableAccess64, (HANDLE process, DWORD64 addrBase)); 08017 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, StackWalk64, (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord, 08018 PREAD_PROCESS_MEMORY_ROUTINE64 readMemoryFunc, 08019 PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc, 08020 PGET_MODULE_BASE_ROUTINE64 getModuleBaseFunc, 08021 PTRANSLATE_ADDRESS_ROUTINE64 translateAddressFunc)); 08022 } // namespace MinGW 08023 } // namespace Win32 08024 08025 #endif // TX_COMPILED 08026 08027 //} 08028 //----------------------------------------------------------------------------------------------------------------- 08029 08031 //} 08032 //================================================================================================================= 08033 08034 //================================================================================================================= 08035 //{ Internal function prototypes, macros and constants 08036 // @name Прототипы внутренних функций, макросы и константы 08037 //================================================================================================================= 08039 08040 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08041 08042 int _txInitialize(); 08043 void _txCleanup(); 08044 08045 HWND _txCanvas_CreateWindow (const SIZE* size); 08046 08047 bool _txCanvas_OnCREATE (HWND wnd); 08048 bool _txCanvas_OnDESTROY (HWND wnd); 08049 bool _txCanvas_OnCLOSE (HWND); 08050 bool _txCanvas_OnPAINT (HWND wnd); 08051 bool _txCanvas_OnKEY (HWND wnd, WPARAM vk, LPARAM info, bool down); 08052 bool _txCanvas_OnCHAR (HWND wnd, WPARAM ch, LPARAM info); 08053 bool _txCanvas_OnTIMER (HWND wnd, WPARAM id); 08054 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords); 08055 bool _txCanvas_OnMOUSELEAVE (HWND wnd); 08056 bool _txCanvas_OnCREATEWND (HWND wnd, WPARAM, LPARAM lpar); 08057 bool _txCanvas_OnDESTROYWND (HWND wnd, WPARAM, LPARAM lpar); 08058 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd); 08059 bool _txCanvas_OnCmdABOUT (HWND wnd, WPARAM cmd); 08060 08061 unsigned WINAPI _txCanvas_ThreadProc (void* data); 08062 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar); 08063 08064 HDC _txBuffer_Create (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL, 08065 RGBQUAD** pixels = NULL) tx_nodiscard; 08066 bool _txBuffer_Delete (HDC* dc); 08067 bool _txBuffer_Select (HGDIOBJ obj, HDC dc = txDC()); 08068 08069 HWND _txConsole_Attach(); 08070 bool _txConsole_OK() tx_nodiscard; 08071 bool _txConsole_Detach (bool activate); 08072 bool _txConsole_Draw (HDC dc); 08073 bool _txConsole_SetUnicodeFont(); 08074 08075 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra); 08076 HWND txCreateExtraWindow (CREATESTRUCT createData); 08077 HICON _txCreateTXIcon (int size) tx_nodiscard; 08078 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng = NULL, 08079 int checkOfs = 0, const wchar_t checkLetters[2] = NULL); 08080 int _txPauseBeforeTermination (HWND canvas); 08081 int _txIsParentWaitable (DWORD* parentPID = NULL) tx_nodiscard; 08082 void _txActivateWindow (HWND wnd, unsigned mode); 08083 int _txGetInput(); 08084 08085 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar); 08086 const char* _txPlayVideo_FindVLC() tx_nodiscard; 08087 08088 bool _txCreateShortcut (const char shortcutName[], 08089 const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL, 08090 const char description[] = NULL, int cmdShow = SW_SHOWNORMAL, 08091 const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0, 08092 COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD)); 08093 08094 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle, 08095 WORD controls, short x, short y, short cx, short cy, 08096 const char caption[], const char font[], WORD fontsize, 08097 const char menu[]) tx_nodiscard; 08098 08099 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle, 08100 short x, short y, short cx, short cy, 08101 WORD id, const char wclass[], const char caption[]); 08102 08103 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, 08104 const char msg[], va_list args); 08105 void _txOnTerminate(); 08106 void _txOnUnexpected(); 08107 void _txOnPureCall(); 08108 void _txOnNewHandlerAnsi(); 08109 int _txOnNewHandler (size_t size); 08110 void _txOnSignal (int signal = 0, int fpe = 0); 08111 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type); 08112 void _txOnSecurityError (int code, void*); 08113 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code); 08114 int _txOnMatherr (_exception* except); 08115 void _txOnInvalidParam (const wchar_t* expr, const wchar_t* func, const wchar_t* file, 08116 unsigned line, uintptr_t); 08117 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, 08118 const unsigned char* file, int line); 08119 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5); 08120 int _txOnErrorReport (int type, const char* text, int* ret); 08121 int tx_glGetError (int setError = INT_MIN); 08122 08123 void _txOnCExit(); 08124 void _txOnExit (int retcode); 08125 void _txOnFatalExit (int retcode); 08126 void _txOnExitProcess (unsigned retcode); 08127 void _txOnFatalAppExitA (unsigned action, const char message[]); 08128 bool _txOnTerminateProcess (HANDLE process, unsigned retcode); 08129 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI 08130 _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter); 08131 void _txWatchdogTerminator (void* timeout); // Only Arnold-type series are supported, not T1000 08132 08133 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc); 08134 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc); 08135 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[]); 08136 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]); 08137 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type); 08138 intptr_t _txDumpExceptionCPP (char what[], intptr_t size, unsigned code = 0, 08139 unsigned params = 0, const ULONG_PTR info[] = NULL); 08140 08141 void _txStackBackTrace (const char file[] = "?", int line = 0, const char func[] = "?", 08142 bool readSource = true); 08143 const char* _txCaptureStackBackTrace (int framesToSkip = 0, bool readSource = true, 08144 CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread()); 08145 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL, 08146 HANDLE thread = GetCurrentThread()); 08147 const char* _txCaptureStackBackTraceTX (int framesToSkip = 0, bool readSource = false); 08148 08149 const char* _txSymPrintFromAddr (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2); 08150 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol = NULL, 08151 Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL, 08152 const char** source = NULL, int context = 2); 08153 intptr_t _txReadSource (char buf[], intptr_t size, const char file[], 08154 int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN); 08155 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc = NULL); 08156 08157 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL, 08158 int useHotPatching = false, HMODULE module = NULL, bool debug = false); 08159 bool _txInDll() tx_nodiscard; 08160 PROCESSENTRY32* _txFindProcess (unsigned pid = GetCurrentProcessId()) tx_nodiscard; 08161 bool _txKillProcess (DWORD pid); 08162 int _txTaskKill (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/); 08163 bool _txCheckSourceCP (int needCP = _TX_CODEPAGE, bool verbose = true); 08164 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid()); 08165 IMAGE_NT_HEADERS*_txGetNtHeaders (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard; 08166 bool _txIsConsoleSubsystem(); 08167 const char* _txAppInfo() tx_nodiscard; 08168 08169 #if defined (_CLANG_VER) && !defined (_MSC_VER) 08170 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info); 08171 #endif 08172 08173 #endif // TX_COMPILED 08174 08175 inline bool _txCanvas_OK () tx_nodiscard; 08176 int _txCanvas_SetRefreshLock (int count); 08177 08178 const char* _txError (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0, 08179 const char msg[] = NULL, ...) tx_printfy (5); 08180 08181 bool _txIsBadReadPtr (const void* address); 08182 08183 intptr_t _tx_snprintf_s (char stream[], intptr_t size, const char format[], ...) tx_printfy (3); 08184 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg); 08185 bool _txIsTTY (int fd); 08186 void txReopenStdio(); 08187 08188 #if defined (__CYGWIN__) 08189 08190 int _getch(); 08191 int _putch (int ch); 08192 int _kbhit() tx_nodiscard; 08193 08194 #endif 08195 08196 //----------------------------------------------------------------------------------------------------------------- 08197 // There are macros for __FILE__ and __LINE__ to work properly. 08198 08199 #if !defined (NDEBUG) 08200 08201 #define _TX_ARGUMENT_FAILED( cond ) ( !(cond) && \ 08202 (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1) && \ 08203 (assert (cond), true) ) 08204 08205 #define _TX_TXWINDOW_FAILED() ( !txOK() && \ 08206 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08207 (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) ) 08208 08209 #define _TX_HDC_FAILED( dc ) ( !Win32::GetObjectType (dc) && \ 08210 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08211 (TX_ERROR ("\a" "Параметр \"%s\" неверен." \ 08212 " Возможно, этот холст не создан, или уже уничтожен, " \ 08213 "или не загрузилась картинка.", #dc), 1) ) 08214 #define _TX_DEFAULT_HDC_FAILED( dc ) ( !(dc) && \ 08215 (TX_ERROR ("\a" "%s" \ 08216 "Если вы указали параметр \"%s\", то он неверен.%s", \ 08217 (!txWindow()? "Окно рисования не создано или не в порядке.\n" : ""), \ 08218 #dc, \ 08219 ( txWindow()? " Возможно, этот холст не создан, или уже уничтожен, " \ 08220 "или не загрузилась картинка." : "")), 1) ) 08221 #else 08222 08223 #define _TX_ARGUMENT_FAILED( cond ) ( !(cond) && \ 08224 (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1) ) 08225 08226 #define _TX_TXWINDOW_FAILED() ( !txOK() && \ 08227 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08228 08229 #define _TX_HDC_FAILED( dc ) ( !Win32::GetObjectType (dc) && \ 08230 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08231 08232 #define _TX_DEFAULT_HDC_FAILED( dc ) ( !(dc) && \ 08233 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08234 #endif 08235 08236 //----------------------------------------------------------------------------------------------------------------- 08237 // Take action in debug configuration only. 08238 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'( 08239 08240 #if !defined (NDEBUG) 08241 #define _TX_ON_DEBUG( code ) { code; } 08242 #else 08243 #define _TX_ON_DEBUG( code ) ; 08244 #endif 08245 08246 //----------------------------------------------------------------------------------------------------------------- 08247 // Invokes an error without location information. "$$" restores TX-related call location context 08248 08249 #define _TX_UNEXPECTED( ... ) $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__) 08250 08251 //----------------------------------------------------------------------------------------------------------------- 08252 // Safe call of a function via its pointer 08253 08254 #define _TX_CALL( func, param ) ( (func)? ((func) param) : 0 ) 08255 #define _TX_CALLv( func, param ) ( (func)? ((func) param) : (void)0 ) 08256 08257 //----------------------------------------------------------------------------------------------------------------- 08258 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x. 08259 08260 #define _txWaitFor( cond, time ) { for (DWORD _t = GetTickCount() + (time); \ 08261 !(cond) && GetTickCount() < _t; \ 08262 Sleep (_txWindowUpdateInterval)) \ 08263 ; \ 08264 \ 08265 if (!(cond)) \ 08266 _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); } 08267 08268 //----------------------------------------------------------------------------------------------------------------- 08269 // Detouring in case of SEH mechanism 08270 08271 #define _txSetJmp() ( setjmp (_txDumpExceptionObjJmp) == 0 ) 08272 08273 #define _txClearJmp() { *(unsigned long long*) _txDumpExceptionObjJmp = 0; } 08274 08275 //----------------------------------------------------------------------------------------------------------------- 08276 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code. 08277 08278 #if defined (IN) 08279 // #undef IN 08280 #endif 08281 08282 #if defined (OUT) 08283 // #undef OUT 08284 #endif 08285 08287 //} 08288 //================================================================================================================= 08289 08290 //================================================================================================================= 08291 //{ Internal global data 08293 // 08294 // Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :) 08295 // 08296 // Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же. 08297 // Здесь это сделано только в образовательных целях. 08298 // 08299 // Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс. 08300 //================================================================================================================= 08302 08303 #ifndef TX_COMPILED // <<<<<<< THE CODE IS HERE, UNFOLD IT <<< 08304 08305 const int _TX_IDM_ABOUT = 40000, // Идентификаторы системного меню окна 08306 _TX_IDM_CONSOLE = 40001, 08307 _TX_WM_CREATEWND = 0x7FF0, // Сообщения для создания/уничтожения 08308 _TX_WM_DESTROYWND = 0x7FF1; // окон в потоке Canvas 08309 08310 //----------------------------------------------------------------------------------------------------------------- 08311 08312 volatile unsigned _txCanaryFirst = 0x776F656D; // A very system value 08313 08314 int _txInitialized = (_TX_NOINIT +0)? 0 : _txInitialize(); 08315 08316 volatile unsigned _txMainThreadId = 0; // ID потока, где выполняется main() 08317 volatile HANDLE _txMainThread = NULL; // Дексриптор этого потока 08318 08319 volatile unsigned _txCanvas_ThreadId = 0; // ID потока, владеющего окном холста TXLib 08320 volatile HANDLE _txCanvas_Thread = NULL; // Дексриптор этого потока 08321 volatile HWND _txCanvas_Window = NULL; // Дескриптор окна холста TXLib 08322 08323 HDC _txCanvas_BackBuf[2] = {NULL, // [0] Main TXLib in-memory DC, where user's pictures lies 08324 NULL}; // [1] Image ready for auto-refresh, see txCanvas_OnPAINT() 08325 08326 RGBQUAD* _txCanvas_Pixels = NULL; // Memory buffer of _txCanvas_BackBuf[0] 08327 08328 HBITMAP _txStockBitmap = NULL; // Equivalent of GetStockObject (BITMAP), 08329 // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313 08330 08331 CRITICAL_SECTION _txCanvas_LockBackBuf = {0,-1}; // Prevent simultaneous access to back buffer, see txLock() 08332 08333 UINT_PTR _txCanvas_RefreshTimer = 1; // Timer ID to redraw TXLib window 08334 volatile int _txCanvas_RefreshLock = 0; // Blocks auto on-timer canvas update, see txBegin/txEnd 08335 08336 ::std::vector<HDC>* _txCanvas_UserDCs = NULL; // List of DCs allocated, for auto-free 08337 08338 volatile bool _txConsole_IsBlinking = true; // To blink or not to blink, that is the question. 08339 08340 int _txConsole = false; // Only first TXLib module in app can own the console 08341 bool _txMain = false; // First TXLib wnd opened (closing it terminates program) 08342 bool _txIsDll = false; // TXLib module is in DLL 08343 volatile bool _txRunning = false; // main() is still running 08344 volatile bool _txExit = false; // exit() is active 08345 08346 volatile POINT _txMousePos = {-1,-1}; // Ask Captn Obviouos about it. See txCanvas_OnMOUSE() 08347 volatile unsigned _txMouseButtons = 0; 08348 08349 volatile WNDPROC _txAltWndProc = NULL; // Альтернативная оконная функция. См. txSetWindowsHook(). 08350 08351 _tx_thread _txLoc _txLoc::Cur = {}; // Execution point tracking and trace state, see "$" macro 08352 08353 volatile int _txErrors = 0; // TX_ERROR calls sequential number 08354 volatile int _txOGLError = 0; // Last OpenGL error when using tx_glGetError() 08355 volatile long _txSENumber = 0; // SEH exceptions sequential number 08356 volatile long _txSEFatalNumber = 0; // SEH fatal exceptions sequential number 08357 char _txDumpSE [_TX_BUFSIZE] = ""; // SEH dump data area 08358 char _txTraceSE[_TX_HUGEBUFSIZE] = ""; // Stack trace data area 08359 08360 LPTOP_LEVEL_EXCEPTION_FILTER _txPrevUEFilter = NULL; // Previous UnhandledExceptionFilter 08361 08362 jmp_buf _txDumpExceptionObjJmp = {}; // Hook for _txDumpExceptionObj 08363 08364 const volatile uintptr_t _txForceImport[] = { (uintptr_t) ::TerminateProcess, (uintptr_t) ::ExitProcess, 08365 (uintptr_t) ::FatalExit, (uintptr_t) ::FatalAppExitA, 08366 (uintptr_t) ::exit, (uintptr_t) Win32::_controlfp, 08367 (uintptr_t) Win32::Polyline, (uintptr_t) Win32::PolyBezier, 08368 (uintptr_t) Win32::RoundRect, (uintptr_t) Win32::RemoveVectoredExceptionHandler, 08369 (uintptr_t) Win32::PlgBlt, (uintptr_t) Win32::RtlCaptureStackBackTrace, 08370 (uintptr_t) Win32::SymInitialize, (uintptr_t) Win32::MinGW::SymInitialize, 08371 (uintptr_t) Win32::SymSetOptions, (uintptr_t) Win32::MinGW::SymSetOptions, 08372 (uintptr_t) Win32::SymGetLineFromAddr64, (uintptr_t) Win32::MinGW::SymGetLineFromAddr64, 08373 (uintptr_t) Win32::SymFromAddr, (uintptr_t) Win32::MinGW::SymFromAddr, 08374 (uintptr_t) Win32::SymCleanup, (uintptr_t) Win32::MinGW::SymCleanup, 08375 (uintptr_t) Win32::SymGetModuleBase64, (uintptr_t) Win32::MinGW::SymGetModuleBase64, 08376 (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64, 08377 (uintptr_t) Win32::StackWalk64, (uintptr_t) Win32::MinGW::StackWalk64, 08378 (uintptr_t) Win32::StrStrIA, (uintptr_t) Win32::Wow64GetThreadContext }; 08379 08380 volatile unsigned _txCanaryLast = 0x5E2E2E5E; // Another very system value 08381 08382 #endif // TX_COMPILED 08383 08384 //----------------------------------------------------------------------------------------------------------------- 08385 08386 extern volatile unsigned _txCanaryFirst; 08387 extern volatile unsigned _txCanaryLast; 08388 extern volatile HWND _txCanvas_Window; 08389 extern volatile unsigned _txCanvas_ThreadId; 08390 extern HDC _txCanvas_BackBuf[2]; 08391 extern RGBQUAD* _txCanvas_Pixels; 08392 extern volatile int _txCanvas_RefreshLock; 08393 extern volatile WNDPROC _txAltWndProc; 08394 extern volatile bool _txExit; 08395 extern volatile int _txOGLError; 08396 08398 //} 08399 //================================================================================================================= 08400 08401 //================================================================================================================= 08402 //{ TXLib engine init/check/cleanup 08404 //================================================================================================================= 08406 08407 //----------------------------------------------------------------------------------------------------------------- 08408 //{ Early initialization 08409 //----------------------------------------------------------------------------------------------------------------- 08410 08411 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08412 08413 int _txInitialize() 08414 { 08415 if (_txInitialized) return 1; 08416 _txInitialized = 1; 08417 08418 #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER) // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx 08419 _CrtSetBreakAlloc (_TX_ALLOC_BREAK); // and http://support.microsoft.com/ru-ru/kb/151585 08420 #endif 08421 08422 #if defined (_TX_ALLOW_TRACE) 08423 _txLocLvlSet (1); 08424 #endif 08425 08426 _TX_ON_DEBUG (OutputDebugString ("\n"); 08427 OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" " 08428 "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n"); 08429 OutputDebugString ("\n")); 08430 08431 _txMainThreadId = GetCurrentThreadId(); 08432 _txMainThread = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId); 08433 08434 $3 _txIsDll = _txInDll(); 08435 08436 $ if (!_txIsDll) 08437 { 08438 $ _txConsole = ! FindAtom ("_txConsole"); 08439 $ (void) AddAtom ("_txConsole"); //-V530 08440 } 08441 08442 $ if (_txConsole) 08443 { 08444 $ _txCheckSourceCP (_TX_CODEPAGE, true); 08445 08446 $ unsigned long stackSize = _TX_STACKSIZE; 08447 $ _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize)); 08448 08449 $ _txOnSignal(); 08450 08451 $ if (!*_txLogName) 08452 {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); } 08453 08454 $ if (!_txIsDll) 08455 { 08456 $ _TX_CALL (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER) _txVectoredExceptionHandler)); 08457 $ _txPrevUEFilter = SetUnhandledExceptionFilter ( (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter); 08458 } 08459 08460 $ ::std::set_terminate (_txOnTerminate); 08461 $ ::std::set_new_handler (_txOnNewHandlerAnsi); 08462 $ _TX_CALL (Win32::set_unexpected, (_txOnUnexpected)); 08463 08464 #if defined (_CLANG_VER) && !defined (_MSC_VER) 08465 $ ::std::__libcpp_debug_function = _txLibCppDebugFunction; 08466 #endif 08467 08468 $ SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true); 08469 08470 $ SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); 08471 08472 #if defined (_MSC_VER) 08473 08474 $ _set_printf_count_output (1); 08475 08476 $ _set_new_handler (_txOnNewHandler); 08477 $ _set_new_mode (1); 08478 08479 #if !defined (_CLANG_VER) 08480 08481 $ _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF); 08482 $ _CrtSetAllocHook (_txOnAllocHook); 08483 08484 $ unsigned mode = _CRTDBG_MODE_FILE; 08485 $ if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0; 08486 08487 $ _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_DEBUG | mode); 08488 $ _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW); 08489 $ _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW); 08490 $ _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR); 08491 $ _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR); 08492 $ _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR); 08493 08494 #endif 08495 08496 $ _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG); 08497 $ _set_abort_behavior (0, _CALL_REPORTFAULT); 08498 08499 $ _RTC_SetErrorFunc (_txOnRTCFailure); 08500 $ _set_purecall_handler (_txOnPureCall); 08501 $ _set_invalid_parameter_handler (_txOnInvalidParam); 08502 08503 #endif 08504 08505 #if defined (__STDC_LIB_EXT1__) 08506 $ ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi); 08507 #endif 08508 08509 #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386) 08510 $ __setusermatherr (_txOnMatherr); 08511 #endif 08512 08513 #if !defined (__CYGWIN__) 08514 $ _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR); 08515 #endif 08516 08517 $ HWND console = _txConsole_Attach(); 08518 $ SetWindowTextA (console, txGetModuleFileName (false)); 08519 } 08520 08521 $ _txSetProcAddress ("ExitProcess", (uintptr_t) _txOnExitProcess, "KERNEL32.DLL"); 08522 $ _txSetProcAddress ("TerminateProcess", (uintptr_t) _txOnTerminateProcess, "KERNEL32.DLL"); 08523 $ _txSetProcAddress ("FatalExit", (uintptr_t) _txOnFatalExit, "KERNEL32.DLL"); 08524 $ _txSetProcAddress ("FatalAppExitA", (uintptr_t) _txOnFatalAppExitA, "KERNEL32.DLL"); 08525 $ _txSetProcAddress ("UnhandledExceptionFilter", (uintptr_t) _txUnhandledExceptionFilter, "KERNEL32.DLL", true); //-V601 08526 $ _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL"); 08527 $ _txSetProcAddress ("exit", (uintptr_t) _txOnExit); 08528 $ _txSetProcAddress ("_cexit", (uintptr_t) _txOnCExit); 08529 08530 $ InitializeCriticalSection (&_txCanvas_LockBackBuf); 08531 08532 $ HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted; 08533 $ _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted; 08534 $ Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted; 08535 $ Win32::DeleteDC (dc) asserted; 08536 08537 $ atexit (_txCleanup); 08538 08539 $ if (_txConsole) 08540 { 08541 $ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 08542 08543 $ tx_fpreset(); 08544 08545 $ srand ((unsigned) time (NULL)); //-V202 08546 08547 $ SetLastError (0); 08548 $ errno = 0; 08549 08550 #if !defined (__CYGWIN__) 08551 $ _doserrno = 0; 08552 #endif 08553 } 08554 08555 $ Win32::CoCreateInstance = Win32::CoCreateInstance; // g++ 5.1.0 bug, false warning "defined but not used" 08556 08557 $ return 1; 08558 } 08559 08560 //----------------------------------------------------------------------------------------------------------------- 08561 08562 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/) 08563 { 08564 $3 const char* sCodePage = NULL; 08565 $ int codePage = 0; 08566 08567 $ switch (((unsigned const char*) "А") [0]) 08568 { 08569 case 192: {$ codePage = 1251; sCodePage = "1251."; break; } 08570 case 208: {$ codePage = 65001; sCodePage = "UTF-8."; break; } 08571 case 128: {$ codePage = 866; sCodePage = "866."; break; } 08572 case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; } 08573 default: {$ codePage = -1; sCodePage = "(Unknown)"; break; } 08574 } 08575 08576 $ if (codePage != needCP && verbose) 08577 { 08578 $ *_txTraceSE = ' '; // No stack trace please 08579 08580 $ _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n" 08581 "This is NOT an error of TXLib itself. Please note:\n\n" 08582 "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your " 08583 "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO " 08584 "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. " 08585 "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n" 08586 "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n" 08587 "You can continue, but Russian messages and symbols may appear unreadable.", 08588 sCodePage, needCP, needCP); 08589 } 08590 08591 $ return (codePage == needCP); 08592 } 08593 08594 //----------------------------------------------------------------------------------------------------------------- 08595 08596 #ifdef _TX_DEBUG_LOAD 08597 08598 HMODULE _txLoadLibrary_ (const char* dll, int line); 08599 HMODULE _txLoadLibrary_ (const char* dll, int line) 08600 { 08601 txOutputDebugPrintf (_TX_DEBUG_LOAD "[" __FILE__ ":%04d] Loading \"%s\"... ", line, dll); 08602 08603 SetLastError (0); 08604 HMODULE lib = LoadLibrary (dll); 08605 08606 if (lib) txOutputDebugPrintf (_TX_DEBUG_LOAD "SUCSESS [%p]\n", (void*) lib); 08607 else txOutputDebugPrintf (_TX_DEBUG_LOAD "error %lu\n", GetLastError()); 08608 08609 return lib; 08610 } 08611 08612 #define LoadLibraryA(dll) _txLoadLibrary_ (dll, __LINE__) 08613 08614 #endif 08615 08616 //----------------------------------------------------------------------------------------------------------------- 08617 08618 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) () 08619 { 08620 if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL; 08621 if (_TX_ARGUMENT_FAILED (funcName && *funcName)) return NULL; 08622 08623 static char dllPaths [4][MAX_PATH] = {}; 08624 08625 if (!*dllPaths[0]) 08626 { 08627 const char dllDir[] = "\\Windows\\"; 08628 char* path = NULL; 08629 size_t sz = 0; 08630 08631 // The dllPaths[0] is a directory where executable file is located 08632 08633 path = dllPaths[0]; 08634 08635 sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0; 08636 if (char* dir = strrchr (path, '\\')) dir[1] = 0; 08637 08638 // The dllPaths[1] is relative to directory where executable file is located 08639 08640 path = dllPaths[1]; 08641 08642 sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0; 08643 if (char* dir = strrchr (path, '\\')) dir[0] = 0; 08644 08645 if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08646 08647 // The dllPaths[2] is relative to TXib.h file used in compilation 08648 08649 path = dllPaths[2]; 08650 08651 if (strchr (__FILE__, ':')) 08652 { 08653 strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1); 08654 } 08655 else 08656 { 08657 // No way to get include path at compile time using simple call "gcc file.cpp" 08658 08659 sz = GetCurrentDirectory (MAX_PATH, path); path[sz] = 0; 08660 if (*path) strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1); 08661 } 08662 08663 if (char* dir = strrchr (path, '\\')) *dir = 0; 08664 08665 if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08666 08667 // The dllPaths[3] is relative to the TX Setup directory stored in the Registry 08668 08669 path = dllPaths[3]; 08670 08671 txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH); 08672 if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08673 } 08674 08675 char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = ""; 08676 const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL); //-V547 08677 08678 if (arch) 08679 { 08680 assert (arch >= dllFileName); //-V547 08681 08682 strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName)); 08683 strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName)); 08684 08685 strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName)); 08686 strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3); 08687 strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch)); 08688 } 08689 else if (dllFileName) //-V547 //-V2516 08690 { 08691 strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1); 08692 } 08693 08694 HMODULE dll = GetModuleHandle (dllFileName); 08695 08696 if (!dll) dll = GetModuleHandle (dllArch); 08697 if (!dll) dll = GetModuleHandle (dllName); 08698 08699 for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++) 08700 { 08701 if (!dllPaths[i]) continue; 08702 08703 char path [MAX_PATH] = ""; 08704 strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i])); 08705 size_t len = strlen (path); 08706 08707 SetDllDirectory (path); 08708 08709 strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch)); 08710 if (!dll && *dllArch) dll = LoadLibrary (path); //-V547 08711 08712 strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName)); 08713 if (!dll) dll = LoadLibrary (path); 08714 } 08715 08716 SetDllDirectory (NULL); 08717 08718 if (!dll && *dllArch) dll = LoadLibrary (dllArch); 08719 if (!dll) dll = LoadLibrary (dllName); 08720 08721 if (!dll && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".", 08722 dllName, (arch? "\" / \"" : ""), dllArch); 08723 if (!dll) return NULL; 08724 08725 void (*addr)() = (void(*)()) GetProcAddress (dll, funcName); 08726 08727 if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".", 08728 funcName, dllName, (arch? "\" / \"" : ""), dllArch); 08729 return addr; 08730 } 08731 08732 //----------------------------------------------------------------------------------------------------------------- 08733 08734 #ifdef _TX_DEBUG_LOAD 08735 #undef LoadLibraryA 08736 #endif 08737 08738 //----------------------------------------------------------------------------------------------------------------- 08739 08740 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013 08741 #pragma warning (push) 08742 #pragma warning (disable: 6102) // Использование 'name' из завершившегося ошибкой вызова функции 08743 #endif 08744 08745 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue) 08746 { 08747 if (_TX_ARGUMENT_FAILED (keyName)) return 0; 08748 08749 HKEY hive = NULL; 08750 08751 #define EQU_(name1, name2) ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \ 08752 _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 ) 08753 08754 if (EQU_("HKLM", "HKEY_LOCAL_MACHINE")) hive = HKEY_LOCAL_MACHINE; 08755 else if (EQU_("HKCU", "HKEY_CURRENT_USER")) hive = HKEY_CURRENT_USER; 08756 else if (EQU_("HKCR", "HKEY_CLASSES_ROOT")) hive = HKEY_CLASSES_ROOT; 08757 else if (EQU_("HKU", "HKEY_USERS")) hive = HKEY_USERS; 08758 else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG; 08759 08760 else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; } 08761 08762 #undef EQU_ 08763 08764 keyName = strchr (keyName, '\\') + 1; //-V769 08765 assert (keyName > (const char*) 1); 08766 08767 HKEY key = NULL; 08768 DWORD size = 0; 08769 08770 bool ok = (RegOpenKeyEx (hive, keyName, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS); 08771 if (ok) ok &= (RegQueryValueEx (key, valueName, NULL, NULL, NULL, &size) == ERROR_SUCCESS); 08772 if (ok && value && size < szValue) ok &= (RegQueryValueEx (key, valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS); //-V104 08773 if (key) ok &= (RegCloseKey (key) == ERROR_SUCCESS); 08774 08775 return size; 08776 } 08777 08778 #if defined (_MSC_VER) && (_MSC_VER == 1800) 08779 #pragma warning (pop) 08780 #endif 08781 08782 #endif // TX_COMPILED 08783 08784 //} 08785 //----------------------------------------------------------------------------------------------------------------- 08786 08787 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08788 08789 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/) 08790 { 08791 $1 if (!_txInitialized) _txInitialized = _txInitialize(); 08792 08793 $ if (HWND wnd = txWindow()) 08794 { 08795 $ SetLastErrorEx (ERROR_INVALID_DATA, 0); 08796 $ _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!")); 08797 $ return wnd; 08798 } 08799 08800 $ if (!_txIsDll) 08801 { 08802 $ _txMain = ! FindAtom ("_txMain"); // Not a thread-safe 08803 $ (void) AddAtom ("_txMain"); //-V530 08804 } 08805 08806 $ if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; } //-V1048 08807 08808 $ _txRunning = false; 08809 08810 // Store the size 08811 08812 $ static SIZE size = { ROUND (sizeX), ROUND (sizeY) }; 08813 $ if (centered) { size.cx *= -1; size.cy *= -1; } 08814 08815 // In Thread, where REAL creation lies... 08816 08817 $ unsigned id = 0; 08818 $ _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id); 08819 08820 $ if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."), (HWND) NULL; 08821 08822 $ _txWaitFor (_txRunning, 10*_TX_TIMEOUT); 08823 08824 $ if (!_txRunning) return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL; 08825 $ if (!txOK()) return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."), (HWND) NULL; 08826 08827 $ HWND console = Win32::GetConsoleWindow(); 08828 08829 $ DWORD proc = 0; 08830 $ GetWindowThreadProcessId (console, &proc); 08831 08832 $ if (console && (proc == GetCurrentProcessId() || _txIsParentWaitable())) 08833 {$ ShowWindow (console, TX_CONSOLE_MODE); } 08834 08835 $ HMENU menu = GetSystemMenu (txWindow(), false); 08836 if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); } 08837 08838 $ Win32::GdiSetBatchLimit (1); 08839 08840 $ SetLastError (0); 08841 08842 $ errno = 0; 08843 08844 #if !defined (__CYGWIN__) 08845 $ _doserrno = 0; 08846 #endif 08847 08848 $ return txWindow(); 08849 } 08850 08851 //----------------------------------------------------------------------------------------------------------------- 08852 08853 HWND txCreateExtraWindow (CREATESTRUCT createData) 08854 { 08855 $1 if (_TX_TXWINDOW_FAILED()) return NULL; 08856 08857 $ volatile HWND wnd = NULL; 08858 $ createData.hInstance = (HINSTANCE)(uintptr_t) &wnd; 08859 08860 $ PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted; 08861 08862 $ _txWaitFor (wnd, 5*_TX_TIMEOUT); 08863 08864 $ return wnd; 08865 } 08866 08867 //----------------------------------------------------------------------------------------------------------------- 08868 08869 bool txSetDefaults (HDC dc /*= txDC()*/) 08870 { 08871 $1 if (dc == txDC()) txUpdateWindow (false); //-V601 08872 $ txAutoLock _lock; 08873 08874 $ RECT r = {}; 08875 $ GetClientRect (Win32::GetConsoleWindow(), &r); 08876 $ SIZE szCon = { r.right - r.left, r.bottom - r.top }; 08877 08878 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 08879 08880 $ CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}}; 08881 $ GetConsoleScreenBufferInfo (out, &con); 08882 08883 $ SIZE szTxt = { (short) (con.srWindow.Right - con.srWindow.Left + 1), 08884 (short) (con.srWindow.Bottom - con.srWindow.Top + 1) }; 08885 08886 //{ Set defaults for graphics layer 08887 08888 $ _txBuffer_Select (Win32::GetStockObject (WHITE_PEN), dc) asserted; 08889 $ _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted; 08890 08891 $ _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx, 08892 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 08893 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 08894 DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT), 08895 dc) asserted; 08896 08897 $ (Win32::SetTextColor (dc, TX_WHITE) != CLR_INVALID) asserted; 08898 $ Win32::SetBkMode (dc, TRANSPARENT) asserted; 08899 08900 $ Win32::SetROP2 (dc, R2_COPYPEN) asserted; 08901 $ Win32::SetStretchBltMode (dc, HALFTONE) asserted; 08902 08903 //} 08904 08905 $ if (dc != txDC()) 08906 {$ return true; } 08907 08908 //{ Set defaults for console layer 08909 08910 $ POINT szCanvas = txGetExtent (dc); 08911 08912 $ HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)? 08913 Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx, 08914 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 08915 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 08916 DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT) 08917 : 08918 Win32::GetStockObject (SYSTEM_FIXED_FONT); 08919 08920 $ _txBuffer_Select (font, _txCanvas_BackBuf[1]); 08921 //} 08922 08923 //{ Scroll the console for text to go above top of window and don't mix with graphics 08924 08925 $ if (con.dwCursorPosition.X) _putch ('\n'); 08926 08927 $ short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top); 08928 08929 $ con.srWindow.Top = (short) (con.srWindow.Top + delta); 08930 $ con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta); 08931 08932 $ SMALL_RECT src = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) }; 08933 $ CHAR_INFO fill = { {' '}, FOREGROUND_LIGHTGRAY }; 08934 $ COORD dest = { 0, (short) -delta }; // New UL-corner of src, scroll up 08935 08936 $ con.dwCursorPosition.X = 0; 08937 $ con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta); 08938 08939 $ (con.srWindow.Bottom < con.dwSize.Y && // Move the "window" 08940 SetConsoleWindowInfo (out, true, &con.srWindow)) 08941 || 08942 (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill), // Or scroll the buffer 08943 SetConsoleCursorPosition (out, con.dwCursorPosition)); 08944 //} 08945 08946 $ txUpdateWindow (true); //-V601 08947 08948 return true; 08949 } 08950 08951 #endif // TX_COMPILED 08952 08953 //----------------------------------------------------------------------------------------------------------------- 08954 08955 inline bool txOK() 08956 { 08957 return (_txCanaryFirst == 0x776F656D && // Too well-known values to use constants. You know these values, don't you? 08958 _txCanaryLast == 0x5E2E2E5E && 08959 _txCanvas_OK() 08960 08961 #if defined (_MSC_VER) 08962 && _CrtCheckMemory() 08963 #endif 08964 ); 08965 } 08966 08967 //----------------------------------------------------------------------------------------------------------------- 08968 //{ Cleanup 08969 //----------------------------------------------------------------------------------------------------------------- 08970 08971 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08972 08973 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain. 08974 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols 08975 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize(). 08976 08977 void _txOnCExit() 08978 { 08979 OutputDebugString ("\n"); 08980 08981 $5 _txCleanup(); 08982 08983 _TX_CALLv (Win32::_cexit, ()); 08984 } 08985 08986 //----------------------------------------------------------------------------------------------------------------- 08987 08988 void _txOnExit (int retcode) 08989 { 08990 if (retcode != 0) 08991 { 08992 OutputDebugString ("\n"); 08993 txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode); 08994 } 08995 08996 $5 _txCleanup(); 08997 08998 if (retcode != 0) 08999 txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode); 09000 09001 Win32::exit (retcode); 09002 } 09003 09004 //----------------------------------------------------------------------------------------------------------------- 09005 09006 void _txOnExitProcess (unsigned retcode) 09007 { 09008 if (retcode != 0) 09009 { 09010 OutputDebugString ("\n"); 09011 txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode); 09012 } 09013 09014 $5 _txCleanup(); 09015 09016 if (retcode != 0) 09017 txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode); 09018 09019 Win32::ExitProcess (retcode); 09020 } 09021 09022 //----------------------------------------------------------------------------------------------------------------- 09023 09024 bool _txOnTerminateProcess (HANDLE process, unsigned retcode) 09025 { 09026 if (retcode != 0) 09027 { 09028 OutputDebugString ("\n"); 09029 txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode); 09030 } 09031 09032 $5 _txCleanup(); 09033 09034 if (retcode != 0) 09035 txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode); 09036 09037 return Win32::TerminateProcess (process, retcode); 09038 } 09039 09040 //----------------------------------------------------------------------------------------------------------------- 09041 09042 void _txOnFatalExit (int retcode) 09043 { 09044 OutputDebugString ("\n"); 09045 txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode); 09046 09047 $5 _txCleanup(); 09048 09049 txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode); 09050 _TX_CALLv (Win32::FatalExit, (retcode)); 09051 09052 txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode); 09053 Win32::TerminateProcess (GetCurrentProcess(), retcode); 09054 } 09055 09056 //----------------------------------------------------------------------------------------------------------------- 09057 09058 void _txOnFatalAppExitA (unsigned action, const char message[]) 09059 { 09060 OutputDebugString ("\n"); 09061 txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message); 09062 09063 $5 _txCleanup(); 09064 09065 txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message); 09066 _TX_CALLv (Win32::FatalAppExitA, (action, message)); 09067 09068 txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION); 09069 Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 09070 } 09071 09072 //----------------------------------------------------------------------------------------------------------------- 09073 09074 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type) 09075 { 09076 OutputDebugString ("\n"); 09077 txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type); 09078 09079 $5 switch (type) 09080 { 09081 case CTRL_LOGOFF_EVENT: 09082 case CTRL_SHUTDOWN_EVENT: $ _txExit = true; 09083 $ _txCleanup(); 09084 case CTRL_C_EVENT: 09085 case CTRL_CLOSE_EVENT: 09086 case CTRL_BREAK_EVENT: 09087 09088 default: break; //-V2522 09089 } 09090 09091 $ return false; 09092 } 09093 09094 //----------------------------------------------------------------------------------------------------------------- 09095 09096 void _txCleanup() 09097 { 09098 if (!_txInitialized) return; 09099 else _txInitialized = false; //-V601 09100 09101 $3 _txRunning = false; 09102 $ _txConsole_IsBlinking = false; 09103 09104 $ txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR); 09105 09106 $ txSetWindowsHook (NULL); 09107 09108 $ HWND canvas = txWindow(); 09109 $ HWND console = Win32::GetConsoleWindow(); 09110 $ unsigned thread = GetCurrentThreadId(); 09111 09112 $ HWND wnd = (canvas)? canvas : console; 09113 09114 $ bool externTerm = (thread != _txMainThreadId && 09115 thread != _txCanvas_ThreadId); 09116 09117 $ DWORD list[1] = {}; 09118 $ DWORD ownsConsole = (GetConsoleProcessList (list, 1) <= 1); 09119 09120 $ int envPause = -1; 09121 $ char envPause_s[10] = ""; 09122 $ size_t envPause_sz = 0; 09123 $ getenv_s (&envPause_sz, envPause_s, sizeof (envPause_s) - 1, "TX_PAUSE"); 09124 09125 if (strcmp (envPause_s, "1") == 0 || _stricmp (envPause_s, "ON") == 0) {$ envPause = 1; } 09126 if (strcmp (envPause_s, "0") == 0 || _stricmp (envPause_s, "OFF") == 0) {$ envPause = 0; } 09127 09128 $ DWORD parent = 0; 09129 $ int isParentWaitable = _txIsParentWaitable (&parent); 09130 09131 $ if (canvas) 09132 {$ txSleep (5*_txWindowUpdateInterval); } 09133 09134 $ if (_txConsole) 09135 { 09136 $ if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 09137 09138 $ if (console) 09139 { 09140 $ EnableWindow (console, true); 09141 $ _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); 09142 } 09143 } 09144 09145 $ if (_txMain && !externTerm && canvas) 09146 {$ _txSetWindowText (canvas, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); } 09147 09148 $ std::cout.flush(); 09149 $ std::cerr.flush(); 09150 $ std::clog.flush(); 09151 $ _flushall(); 09152 09153 $ bool paused = false; 09154 $ if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId)) 09155 { 09156 $ if (wnd) 09157 { 09158 $ if (isParentWaitable >= 0) 09159 {$ _txActivateWindow (wnd, 0x08); } 09160 09161 $ EnableWindow (wnd, true); 09162 } 09163 09164 $ if ((console && (ownsConsole || canvas || _txErrors || envPause == 1)) && isParentWaitable >= 0 && !(envPause == 0)) 09165 { 09166 $ txPause ((_txErrors)? "\f\n" "[Press F to Pay Respects...]" : 09167 (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f"); 09168 09169 $ paused = true; 09170 } 09171 } 09172 09173 $ if (_txConsole && _txWatchdogTimeout >= 0) 09174 {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); } 09175 09176 $ if (txWindow()) 09177 {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); } 09178 09179 $ _txWaitFor (!txWindow(), 5*_TX_TIMEOUT); 09180 09181 $ txSpeak (NULL); 09182 $ txPlayVideo (NULL); 09183 09184 $ delete _txCanvas_UserDCs; 09185 $ _txCanvas_UserDCs = NULL; 09186 09187 $ if (GetCurrentThreadId() != _txMainThreadId) 09188 {$ SuspendThread (_txMainThread); } //-V720 09189 $ if (GetCurrentThreadId() != _txCanvas_ThreadId) 09190 {$ SuspendThread (_txCanvas_Thread); } //-V720 09191 09192 $ if (_txMainThread) 09193 {$ CloseHandle (_txMainThread) asserted; _txMainThread = NULL; } 09194 $ if (_txCanvas_Thread) 09195 {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; } 09196 09197 $ if (!txWindow()) 09198 {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; } 09199 09200 $ bool parentKilled = false; 09201 $ if (isParentWaitable && !externTerm && paused && _txNOP (_TX_ALLOW_KILL_PARENT)) 09202 { 09203 $ console = Win32::GetConsoleWindow(); 09204 09205 $ if (parent) 09206 {$ parentKilled = _txKillProcess (parent); } 09207 09208 $ if (parent && !parentKilled) 09209 { 09210 $ PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001); // Scancode = 0x1C, Count = 1 09211 $ PostMessage (console, WM_KEYUP, VK_RETURN, 0xC01C0001); // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1 09212 } 09213 } 09214 09215 $ if (_txConsole) 09216 {$ _txSetWindowText (console, NULL); } 09217 09218 $ if (_txMain && _txConsole) 09219 {$ _txConsole_Detach (isParentWaitable && !externTerm && !parentKilled); } //-V560 09220 09221 $ std::cout.flush(); 09222 $ std::cerr.flush(); 09223 $ std::clog.flush(); 09224 $ _flushall(); 09225 09226 $ _txSymGetFromAddr (NULL); 09227 09228 // That's all, folks 09229 09230 _TX_ON_DEBUG (OutputDebugString ("\n"); 09231 OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n"); 09232 OutputDebugString ("\n")); 09233 } 09234 09235 //----------------------------------------------------------------------------------------------------------------- 09236 09237 int txPause (const char* message /*= NULL*/, ...) 09238 { 09239 $3 bool wine = !!Win32::wine_get_version; 09240 09241 $ HWND canvas = txWindow(); 09242 $ HWND console = Win32::GetConsoleWindow(); 09243 $ HWND wnd = (canvas)? canvas : console; 09244 $ bool istty0 = _txIsTTY (0); 09245 09246 $ int attr = txGetConsoleAttr(); 09247 09248 $ int oldCP = GetConsoleOutputCP(); 09249 $ SetConsoleOutputCP (_TX_CODEPAGE); 09250 09251 if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; } 09252 09253 if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); } 09254 else {$ message++; } 09255 09256 if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); } 09257 else {$ message++; } 09258 09259 $ _txActivateWindow (wnd, 0x08); 09260 09261 $ va_list args; 09262 $ va_start (args, message); 09263 $ vfprintf (stderr, message, args); 09264 $ txOutputDebugPrintf (message, args); 09265 $ va_end (args); 09266 09267 $ fflush (stderr); 09268 $ txSleep(); 09269 09270 $ Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF }; 09271 $ _TX_CALL (Win32::FlashWindowEx, (&flash)); 09272 09273 $ int ch = EOF; 09274 if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); } 09275 09276 $ for (int i = 1; ; i++) //-V2530 09277 { 09278 $ Sleep (_txWindowUpdateInterval); 09279 09280 if (!istty0 && !canvas) {$ break; } // No need to run and hide 09281 09282 if (!wine && (ch = _txGetInput()) != EOF) {$ break; } // Somebody hit something. 09283 09284 if (canvas && !_txCanvas_ThreadId) {$ break; } // There was a window, and now there is not. 09285 09286 if (!Win32::GetConsoleWindow()) {$ break; } // Console was destroyed 09287 09288 if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas))) 09289 {$ TX_ERROR ("Похоже, программа зависла :("); break; } 09290 09291 if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas))) 09292 {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; } 09293 09294 if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL)) 09295 {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает"); break; } 09296 09297 if (!wine && !(i % 100500)) 09298 {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...] \b\b"); } 09299 } 09300 09301 if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); } 09302 09303 $ _txSetWindowText (wnd, NULL); 09304 09305 $ fprintf (stderr, "\n"); 09306 09307 if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); } 09308 09309 $ SetConsoleOutputCP (oldCP); 09310 $ txSetConsoleAttr (attr); 09311 09312 $ return ch; 09313 } 09314 09315 //----------------------------------------------------------------------------------------------------------------- 09316 09317 int _txGetInput() 09318 { 09319 $4 HANDLE con = GetStdHandle (STD_INPUT_HANDLE); 09320 $ int ch = EOF; 09321 09322 $ DWORD nChars = 0; 09323 $ if (GetConsoleMode (con, &nChars) == 0 && 09324 PeekNamedPipe (con, NULL, 0, NULL, &nChars, NULL)) 09325 { 09326 $ ch = (nChars)? fgetc (stdin) : EOF; 09327 } 09328 09329 else if (_kbhit()) 09330 { 09331 $ ch = _getch(); 09332 } 09333 09334 #if defined (_MSC_VER) && (_MSC_VER < 1700) 09335 09336 else if (fseek (stdin, 1, SEEK_CUR) != EOF) 09337 { 09338 $ (void) fseek (stdin, -1, SEEK_CUR); 09339 $ ch = fgetc (stdin); // This causes blocking in MSVC 2011 beta 09340 } 09341 09342 #endif 09343 09344 if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); } 09345 09346 $ return ch; 09347 } 09348 09349 //----------------------------------------------------------------------------------------------------------------- 09350 09351 bool _txIsTTY (int fd) 09352 { 09353 $4 return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR; 09354 } 09355 09356 //----------------------------------------------------------------------------------------------------------------- 09357 09358 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/, 09359 int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/) 09360 { 09361 struct tools 09362 { 09363 static LRESULT getWindowText (HWND window, wchar_t text[], size_t size) 09364 { 09365 $3 memset (text, 0, size * sizeof (*text)); 09366 09367 $ return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL); 09368 } 09369 09370 static LRESULT setWindowText (HWND window, wchar_t text[]) 09371 { 09372 $1 return SendMessageTimeoutW (window, WM_SETTEXT, 0, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL); 09373 } 09374 }; 09375 09376 $1 static wchar_t _tx_thread title [_TX_BUFSIZE+15] = L"TXLib"; 09377 $ static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib"; 09378 09379 $ if (!textRus) 09380 { 09381 $ tools::setWindowText (wnd, oldTitle); 09382 $ return -1; 09383 } 09384 09385 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09386 $ int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1; 09387 $ memcpy (oldTitle, title, sizeof (oldTitle)); 09388 09389 $ if (textRus) 09390 { 09391 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len); 09392 09393 $ tools::setWindowText (wnd, title); 09394 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09395 if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; } 09396 if (!checkLetters) {$ return -2; } 09397 } 09398 09399 $ if (textEng) 09400 { 09401 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len); 09402 09403 $ tools::setWindowText (wnd, title); 09404 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09405 if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; } 09406 if (!checkLetters) {$ return -2; } 09407 } 09408 09409 $ return -3; 09410 } 09411 09412 //----------------------------------------------------------------------------------------------------------------- 09413 09414 int _txIsParentWaitable (DWORD* parentPID /*= NULL*/) 09415 { 09416 $4 PROCESSENTRY32* info = _txFindProcess(); 09417 $ if (!info) return 0; 09418 09419 $ info = _txFindProcess (info->th32ParentProcessID); 09420 $ if (!info) return 0; 09421 09422 $ char parent [MAX_PATH] = ""; 09423 $ strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1); 09424 $ if (parentPID) *parentPID = info->th32ProcessID; 09425 09426 $ info = _txFindProcess (info->th32ParentProcessID); // info: grandparent 09427 09428 $ char list[_TX_BUFSIZE] = _TX_WAITABLE_PARENTS; 09429 $ char* ctx = NULL; 09430 09431 $ for (char* p = strtok_s (list, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx)) 09432 { 09433 $ char* gp = strchr (p, ':'); 09434 09435 $ if (gp) 09436 { 09437 $ *gp++ = 0; 09438 09439 $ if (_stricmp (p, parent) != 0) { continue; } 09440 09441 $ if (info) if (_stricmp (gp, info->szExeFile) == 0) // Was &&, but MSVC /analyze is so paranoid 09442 {$ return islower ((unsigned char) *gp)? +1 : -1; } 09443 } 09444 else 09445 { 09446 $ if (_stricmp (p, parent) == 0) 09447 {$ return islower ((unsigned char) *p)? +1 : -1; } 09448 } 09449 } 09450 09451 $ return 0; 09452 } 09453 09454 //----------------------------------------------------------------------------------------------------------------- 09455 09456 void _txWatchdogTerminator (void* timeout) // Or Watchcat? Possibly will change in future versions 09457 { 09458 $3 if (_TX_ARGUMENT_FAILED (timeout)) return; 09459 09460 $ Sleep (*(int*) timeout); //-V206 09461 09462 $ OutputDebugString ("\n"); 09463 txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n", // Kinda static reflection... 09464 _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow")); //-V206 09465 $ DWORD parent = 0; 09466 $ if (_txIsParentWaitable (&parent)) 09467 { 09468 txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n", 09469 _TX_VERSION, __func__, (unsigned long) parent); 09470 09471 $ _txKillProcess (parent); 09472 09473 $ HWND console = GetConsoleWindow(); 09474 $ PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001); // Scancode = 0x1C, Count = 1 09475 $ PostMessage (console, WM_KEYUP, VK_RETURN, 0xC01C0001); // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1 09476 } 09477 09478 txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__); 09479 $ Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 09480 } 09481 09482 #endif // TX_COMPILED 09483 09484 //} 09485 //----------------------------------------------------------------------------------------------------------------- 09486 09487 //----------------------------------------------------------------------------------------------------------------- 09488 //{ Tools 09489 //----------------------------------------------------------------------------------------------------------------- 09490 09491 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 09492 09493 // You are here, little hacker? 09494 09495 int _txTaskKill (const char i[] /*= NULL*/, 09496 const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/, 09497 unsigned x /*= 0*/) 09498 { 09499 // ...so tired of it already... 09500 09501 #define name i // Great name! 09502 #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine 09503 #define pid x // Another great name, isn't it? 09504 09505 $3 if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false; //-V560 //-V601 09506 09507 $ wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L""; 09508 if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); } 09509 09510 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 09511 $ assert (sshot); if (!sshot) return 0; //-V547 09512 09513 $ int killed = 0; 09514 09515 $ PROCESSENTRY32 info = { sizeof (info) }; 09516 $ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info)) 09517 { 09518 bool kill = false; 09519 09520 if (!kill && pid && info.th32ParentProcessID == pid) {$ kill = true; } //-V560 09521 09522 if (!kill && name && _stricmp (info.szExeFile, name) == 0) {$ kill = true; } 09523 09524 if (!kill) 09525 { 09526 wchar_t cmdLineW[_TX_BUFSIZE] = L""; 09527 if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; } 09528 09529 if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW)) {$ kill = true; } 09530 } 09531 09532 if (kill) 09533 { 09534 $ if (_txKillProcess (info.th32ProcessID)) 09535 {$ killed++; } 09536 } 09537 } 09538 09539 $ CloseHandle (sshot); 09540 09541 $ return killed; 09542 09543 #undef name 09544 #undef cmdLine 09545 #undef pid 09546 } 09547 09548 //----------------------------------------------------------------------------------------------------------------- 09549 09550 bool _txKillProcess (DWORD pid) 09551 { 09552 $3 if (_TX_ARGUMENT_FAILED (pid)) return false; 09553 09554 $ HANDLE token = INVALID_HANDLE_VALUE; 09555 $ OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted; 09556 09557 $ LUID luid = {}; 09558 $ LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted; 09559 09560 $ TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}}; 09561 $ TOKEN_PRIVILEGES old = {}; 09562 09563 $ DWORD oldSz = 0; 09564 $ AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted; 09565 09566 $ HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid); 09567 $ if (!proc) return false; 09568 09569 $ bool ok = !!Win32::TerminateProcess (proc, 0); 09570 $ CloseHandle (proc); 09571 09572 $ return ok; 09573 } 09574 09575 //----------------------------------------------------------------------------------------------------------------- 09576 09577 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/) 09578 { 09579 $4 static PROCESSENTRY32 info = { sizeof (info) }; 09580 $ if (!pid) return &info; 09581 09582 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 09583 $ assert (sshot); if (!sshot) return NULL; //-V547 09584 09585 $ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info)) 09586 if (info.th32ProcessID == pid) break; 09587 09588 $ CloseHandle (sshot); 09589 09590 $ return &info; 09591 } 09592 09593 //----------------------------------------------------------------------------------------------------------------- 09594 09595 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/) 09596 { 09597 $6 if (_TX_ARGUMENT_FAILED (cmdLine)) return false; 09598 $ if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false; //-V547 09599 09600 $ if (pid == (unsigned) _getpid()) 09601 { 09602 $ wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1); 09603 $ return true; 09604 } 09605 09606 $ HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid); 09607 if (!proc) {$ return false; } 09608 09609 $ Win32::PROCESS_BASIC_INFORMATION pbi = {}; 09610 $ bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0); 09611 09612 // Should use ReadProcessMemory() because the info is actually in another address space 09613 09614 $ Win32::PEB peb = {}; 09615 if (ok && pbi.PebBaseAddress) {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress, &peb, sizeof (peb), NULL); } 09616 09617 $ Win32::RTL_USER_PROCESS_PARAMETERS params = {}; 09618 if (ok && peb.ProcessParameters) {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters, ¶ms, sizeof (params), NULL); } 09619 09620 $ *cmdLine = 0; 09621 if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine, //-V106 09622 MIN (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2), //-V202 09623 NULL); } 09624 $ CloseHandle (proc) asserted; 09625 09626 $ return ok; 09627 } 09628 09629 //----------------------------------------------------------------------------------------------------------------- 09630 09631 #define RVA_(type, module, addr) ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) ) 09632 09633 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/) 09634 { 09635 $4 assert (module); 09636 09637 $ IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0); 09638 $ IMAGE_NT_HEADERS* ntHdr = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew); 09639 09640 $ return (dosHdr->e_magic == IMAGE_DOS_SIGNATURE && 09641 ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL; 09642 } 09643 09644 //----------------------------------------------------------------------------------------------------------------- 09645 09646 // TXLib continues to hack the reality to make your life better, sweeter and easier 09647 09648 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/, 09649 HMODULE module /*= NULL*/, bool debug /*= false*/) 09650 { 09651 $4 if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module); 09652 09653 $ if (_TX_ARGUMENT_FAILED (funcName)) return 0; 09654 $ if (_TX_ARGUMENT_FAILED (newFunc)) return 0; 09655 09656 $ if (!module) module = GetModuleHandle (NULL); 09657 $ if (!module) return 0; 09658 09659 $ HMODULE dll = (dllName)? GetModuleHandle (dllName) : NULL; 09660 $ PROC oldFunc = (dll)? GetProcAddress (dll, funcName) : NULL; 09661 09662 $ if (useHotPatching && oldFunc) 09663 { 09664 $ const size_t jmpSz = 1 + sizeof (DWORD); // sizeof (JMP rel instruction) 09665 09666 $ DWORD oldRights = 0; 09667 $ if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0; 09668 09669 // Overwrite oldFunc prolog with JMP trampoline to newFunc. 09670 // Calling oldFunc from any location will lead to newFunc call anyway. 09671 09672 $ *(BYTE*) ((char*)(uintptr_t) oldFunc + 0) = 0xE9; // JMP rel 09673 $ *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF; //-V206 //-V112 //-V2007 //-V104 //-V103 09674 09675 $ FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz); 09676 09677 $ VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights); 09678 09679 $ return (uintptr_t) oldFunc; 09680 } 09681 09682 // For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255 09683 // and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html. 09684 09685 $ IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module); 09686 if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; } 09687 09688 $ DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 09689 $ IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset); 09690 09691 $ if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0; //-V1027 09692 09693 $ IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL; 09694 $ char* impDll = NULL; 09695 $ char* impName = NULL; 09696 $ void** impPtr = NULL; 09697 $ bool found = false; 09698 09699 for (; desc->Name; desc++) 09700 { 09701 $ impDll = RVA_ (char*, module, desc->Name); 09702 $ if (dllName && _stricmp (impDll, dllName) != 0) continue; 09703 09704 $ for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk), 09705 thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk); 09706 09707 thunk0 && thunk1 && thunk1->u1.Function; 09708 09709 thunk0++, 09710 thunk1++) 09711 { 09712 impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name; 09713 impPtr = (void**)(uintptr_t) &thunk1->u1.Function; // Should change it, so this is ptr 09714 09715 if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL; 09716 09717 if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName); 09718 09719 if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) || 09720 (impName && _stricmp (funcName, impName) == 0)) //-V560 09721 { 09722 found = true; 09723 break; 09724 } 09725 } 09726 09727 $ if (found) break; 09728 } 09729 09730 if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n", 09731 funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found")); 09732 $ if (!found) return 0; 09733 09734 $ DWORD rights = PAGE_READWRITE; 09735 $ if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0; 09736 09737 $ *(uintptr_t*) impPtr = newFunc; 09738 09739 $ VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights); 09740 09741 $ return (uintptr_t) oldFunc; 09742 } 09743 09744 #undef RVA_ 09745 09746 //----------------------------------------------------------------------------------------------------------------- 09747 09748 bool _txInDll() 09749 { 09750 $4 MODULEENTRY32 mod = { sizeof (mod) }; 09751 09752 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); 09753 $ assert (sshot); if (!sshot) return false; //-V547 09754 09755 $ bool inDll = false; 09756 09757 $ for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod)) 09758 { 09759 $ if (!mod.modBaseAddr) continue; 09760 09761 $ IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr); 09762 09763 $ inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0); 09764 09765 $ if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize)) //-V104 09766 {$ break; } 09767 } 09768 09769 $ CloseHandle (sshot); 09770 $ return inDll; 09771 } 09772 09773 //----------------------------------------------------------------------------------------------------------------- 09774 09775 bool _txIsConsoleSubsystem() 09776 { 09777 $4 IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders(); 09778 09779 $ return ntHdr && 09780 ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC && 09781 09782 (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI || 09783 ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI); 09784 } 09785 09786 //----------------------------------------------------------------------------------------------------------------- 09787 09788 bool _txIsBadReadPtr (const void* address) 09789 { 09790 MEMORY_BASIC_INFORMATION mbi = {}; 09791 if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true; 09792 09793 if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) return true; // Guard page -> bad ptr 09794 09795 DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY; 09796 09797 return !(mbi.Protect & readRights); 09798 } 09799 09800 //----------------------------------------------------------------------------------------------------------------- 09801 09802 void _txActivateWindow (HWND wnd, unsigned mode) 09803 { 09804 $1 EnableWindow (wnd, true); 09805 09806 $ if (mode & 0x10) 09807 { 09808 $ ShowWindow (wnd, SW_MINIMIZE); 09809 $ ShowWindow (wnd, SW_RESTORE); 09810 } 09811 09812 $ if (mode & 0x08) 09813 { 09814 $ int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0); 09815 09816 $ AttachThreadInput (GetCurrentThreadId(), focus, true); 09817 $ SetForegroundWindow (wnd); 09818 $ AttachThreadInput (GetCurrentThreadId(), focus, false); 09819 } 09820 09821 $ if (mode & 0x04) 09822 { 09823 $ SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); 09824 } 09825 09826 $ if (mode & 0x02) 09827 { 09828 $ SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS); 09829 } 09830 09831 $ if (mode & 0x01) 09832 { 09833 $ UpdateWindow (wnd); 09834 } 09835 } 09836 09837 #endif // TX_COMPILED 09838 09839 //} 09840 //----------------------------------------------------------------------------------------------------------------- 09841 09843 //} 09844 //================================================================================================================= 09845 09846 //================================================================================================================= 09847 //{ Internal TXLib window functions (_txCanvas...) 09849 //================================================================================================================= 09850 09851 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 09852 09853 unsigned WINAPI _txCanvas_ThreadProc (void* data) 09854 { 09855 #define SetClassLong_ SetClassLongPtr 09856 #define GCL_HICON_ GCLP_HICON 09857 #define GCL_HICONSM_ GCLP_HICONSM 09858 #define GCL_HCURSOR_ GCLP_HCURSOR 09859 09860 $8 _txCanvas_ThreadId = GetCurrentThreadId(); 09861 09862 $ if (_TX_ARGUMENT_FAILED (data)) return false; //-V601 09863 09864 $ unsigned long stackSize = _TX_STACKSIZE; 09865 $ _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize)); 09866 09867 $ HWND wnd = _txCanvas_CreateWindow ((SIZE*) data); 09868 $ if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0; 09869 09870 $ HICON icon32 = LoadIcon (NULL, "_TX_ICON"); 09871 $ HICON icon16 = LoadIcon (NULL, "_TX_ICONSM"); 09872 $ HCURSOR cursor = LoadCursor (NULL, "_TX_CURSOR"); 09873 $ HMENU menu = LoadMenu (NULL, "_TX_MENU"); 09874 $ HACCEL accel = LoadAccelerators (NULL, "_TX_ACCELERATORS"); 09875 09876 $ SetClassLong_ (wnd, GCL_HICON_, (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32))); //-V107 //-V112 09877 $ SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16))); //-V107 09878 $ SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW))); //-V107 09879 09880 if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); } 09881 09882 $ Win32::GdiSetBatchLimit (1); 09883 09884 _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n")); 09885 09886 $ _txActivateWindow (wnd, 0x10); 09887 09888 $ ShowWindow (wnd, SW_SHOW); 09889 $ UpdateWindow (wnd); 09890 09891 $ _txRunning = true; 09892 09893 $ MSG msg = {}; 09894 $ while (GetMessage (&msg, NULL, 0, 0)) 09895 { 09896 if (!msg.hwnd) {$ continue; } 09897 09898 if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; } 09899 09900 $ TranslateMessage (&msg); 09901 $ DispatchMessage (&msg); 09902 09903 $ Sleep (0); 09904 } 09905 09906 $ if (icon16) DestroyIcon (icon16); // If Explorer is displaying Tray Notification, these 09907 $ if (icon32) DestroyIcon (icon32); // calls will possibly fail, and we'll get resource leak. 09908 09909 $ LeaveCriticalSection (&_txCanvas_LockBackBuf); 09910 09911 _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n")); 09912 09913 $ if (_txWatchdogTimeout >= 0) 09914 {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); } 09915 09916 $ if (_txRunning && _txMain) // Main window is destroyed but main() is still running. 09917 { // No chances for good termination, so use exit(). 09918 $ _txCleanup(); 09919 $ ::exit ((int) msg.wParam); //-V202 //-V2509 //-V2014 09920 } 09921 09922 $ _txCanvas_ThreadId = 0; 09923 $ return true; //-V601 09924 09925 #undef SetClassLong 09926 #undef GCL_HICON_ 09927 #undef GCL_HICONSM_ 09928 #undef GCL_HCURSOR_ 09929 } 09930 09931 //----------------------------------------------------------------------------------------------------------------- 09932 09933 HWND _txCanvas_CreateWindow (const SIZE* sizePtr) 09934 { 09935 $8 if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL; 09936 09937 $ bool centered = false; 09938 if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; } 09939 09940 $ SIZE screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; 09941 $ RECT rect = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false); 09942 $ SIZE size = { rect.right - rect.left, rect.bottom - rect.top }; 09943 $ RECT conPos = {}; 09944 09945 $ HWND console = _TX_CALL (Win32::GetConsoleWindow, ()); 09946 if (console) {$ GetWindowRect (console, &conPos); } 09947 09948 $ const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0); 09949 $ if (!wndClass) return (HWND) NULL; 09950 09951 $ HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN, 09952 (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT, 09953 (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top : CW_USEDEFAULT, 09954 size.cx, size.cy, NULL, NULL, NULL, NULL); 09955 $ if (!wnd || !txWindow()) 09956 {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; } 09957 09958 $ HMENU menu = GetSystemMenu (txWindow(), false); 09959 if (!menu) {$ return txWindow(); } 09960 09961 $ AppendMenu (menu, MF_SEPARATOR, 0, NULL) asserted; 09962 $ AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted; 09963 $ AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT, "&About...") asserted; 09964 09965 $ return txWindow(); 09966 } 09967 09968 //----------------------------------------------------------------------------------------------------------------- 09969 09970 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra) 09971 { 09972 $8 assert (classId); 09973 $ assert (wndProc); 09974 09975 $ static char name[_TX_BUFSIZE] = ""; 09976 $ _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ " 09977 _TX_VERSION " " __FILE__ " WndClass %08lX " 09978 "-------------[%s]-[TXLib]---*/", 09979 classId, (unsigned long) GetTickCount(), classId); 09980 $ WNDCLASS wc = { sizeof (wc) }; 09981 09982 $ wc.lpszClassName = name; 09983 $ wc.lpfnWndProc = wndProc; 09984 $ wc.style = style; 09985 $ wc.cbWndExtra = (wndExtra + 1) * (int) sizeof (long); 09986 09987 $ wc.hCursor = LoadCursor (NULL, IDC_ARROW); 09988 $ wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush); 09989 09990 $ ATOM atom = RegisterClass (&wc); 09991 if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; } 09992 09993 $ return (const char*)(uintptr_t) atom; 09994 } 09995 09996 //----------------------------------------------------------------------------------------------------------------- 09997 09998 int _txCanvas_SetRefreshLock (int count) 09999 { 10000 $8 int oldCount = _txCanvas_RefreshLock; 10001 10002 $ _txCanvas_RefreshLock = count; 10003 10004 $ HWND wnd = txWindow(); 10005 10006 $ if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd) 10007 {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); } 10008 10009 $ return oldCount; 10010 } 10011 10012 //----------------------------------------------------------------------------------------------------------------- 10013 10014 HICON _txCreateTXIcon (int size) 10015 { 10016 $8 if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL; //-V112 //-V560 10017 10018 $ const unsigned char image32 [32*32+1] = 10019 "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0" 10020 "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0" 10021 "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0" 10022 "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0" 10023 "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0" 10024 "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0" 10025 "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0" 10026 "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000"; 10027 10028 $ const unsigned char image16 [16*16+1] = 10029 "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990" 10030 "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000"; 10031 10032 $ const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0, 10033 0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff }; 10034 10035 $ const unsigned char* image = (size == 32)? image32 : image16; //-V112 10036 10037 $ POINT sz = { size, size }; 10038 $ HDC dcMask = _txBuffer_Create (txWindow(), &sz); assert (dcMask); 10039 $ HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor); 10040 10041 $ for (int i = 0; i < size*size; i++) 10042 { 10043 assert (In (std::nomeow, image[i], '0', '9') || 10044 In (std::nomeow, image[i], 'A', 'F')); 10045 10046 Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']); 10047 } 10048 10049 $ ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask, OBJ_BITMAP), 10050 (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) }; 10051 10052 $ HICON icon = CreateIconIndirect (&info); 10053 $ assert (icon); 10054 10055 $ _txBuffer_Delete (&dcMask) asserted; 10056 $ _txBuffer_Delete (&dcColor) asserted; 10057 10058 $ return icon; 10059 } 10060 10061 #endif // TX_COMPILED 10062 10063 //----------------------------------------------------------------------------------------------------------------- 10064 10065 inline bool _txCanvas_OK() 10066 { 10067 return _txCanvas_ThreadId && 10068 _txCanvas_Window && 10069 _txCanvas_BackBuf[0] && 10070 _txCanvas_BackBuf[1] && 10071 _txCanvas_Pixels; 10072 } 10073 10074 //} 10075 //================================================================================================================= 10076 10077 //================================================================================================================= 10078 //{ Main window event handlers (_txCanvas_On...) 10080 //================================================================================================================= 10082 10083 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10084 10085 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) 10086 { 10087 #if defined (_TX_ALLOW_TRACE) 10088 10089 int inTX = _txLoc::Cur.inTX++; 10090 10091 if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)", 10092 2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar); 10093 _txLoc::Cur.inTX = inTX; 10094 10095 #endif 10096 10097 $8 if (msg == WM_KEYDOWN && wpar == VK_F12 && 10098 GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU)) 10099 { 10100 $ _txCanvas_OnCmdABOUT (wnd, wpar); 10101 $ return DefWindowProc (wnd, msg, wpar, lpar); 10102 } 10103 10104 WNDPROC altWndProc = _txAltWndProc; // Cache to prevent change from main thread 10105 if (altWndProc) 10106 { 10107 $ LRESULT res = altWndProc (wnd, msg, wpar, lpar); 10108 $ if (res) return res; 10109 } 10110 10111 static bool bkErased = false; 10112 10113 switch (msg) 10114 { 10115 case WM_CREATE: {$ _txCanvas_OnCREATE (wnd); return 0; } 10116 10117 case WM_CLOSE: {$ if (_txCanvas_OnCLOSE (wnd)) break; else return 0; } 10118 case WM_DESTROY: {$ _txCanvas_OnDESTROY (wnd); return 0; } 10119 10120 case WM_ERASEBKGND: {$ if (!bkErased) { bkErased = true; break; } else return 1; } 10121 case WM_SIZE: {$ bkErased = false; break; } 10122 10123 case WM_PAINT: {$ _txCanvas_OnPAINT (wnd); return 0; } 10124 10125 case WM_TIMER: {$ _txCanvas_OnTIMER (wnd, wpar); return 0; } 10126 10127 case WM_KEYUP: {$ if (_txCanvas_OnKEY (wnd, wpar, lpar, false)) return 0; else break; } 10128 case WM_KEYDOWN: {$ if (_txCanvas_OnKEY (wnd, wpar, lpar, true)) return 0; else break; } 10129 case WM_CHAR: {$ if (_txCanvas_OnCHAR (wnd, wpar, lpar)) return 0; else break; } 10130 10131 case WM_LBUTTONUP: 10132 case WM_LBUTTONDOWN: 10133 case WM_RBUTTONUP: 10134 case WM_RBUTTONDOWN: 10135 case WM_MBUTTONUP: 10136 case WM_MBUTTONDOWN: 10137 case WM_MOUSEMOVE: {$ _txCanvas_OnMOUSEMOVE (wnd, wpar, lpar); return 0; } 10138 10139 case WM_MOUSELEAVE: {$ _txCanvas_OnMOUSELEAVE (wnd); return 0; } 10140 10141 case _TX_WM_CREATEWND: {$ _txCanvas_OnCREATEWND (wnd, wpar, lpar); return 0; } 10142 case _TX_WM_DESTROYWND: {$ _txCanvas_OnDESTROYWND (wnd, wpar, lpar); return 0; } 10143 10144 case WM_NULL: {$ return 0; } 10145 10146 default: break; //-V2522 10147 } 10148 10149 if (msg == WM_SYSCOMMAND) switch (wpar) 10150 { 10151 case _TX_IDM_ABOUT: {$ _txCanvas_OnCmdABOUT (wnd, wpar); return 0; } 10152 case _TX_IDM_CONSOLE: {$ _txCanvas_OnCmdCONSOLE (wnd, wpar); return 0; } 10153 10154 default: break; //-V2522 10155 } 10156 10157 $ return DefWindowProc (wnd, msg, wpar, lpar); 10158 } 10159 10160 //----------------------------------------------------------------------------------------------------------------- 10161 10162 bool _txCanvas_OnCREATE (HWND wnd) 10163 { 10164 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10165 10166 $ _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]); 10167 $ _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL); assert (_txCanvas_BackBuf[1]); 10168 10169 $ if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0; 10170 $ assert (_txCanvas_RefreshTimer); 10171 10172 $ _txCanvas_UserDCs = new ::std::vector <HDC>; 10173 10174 $ _txCanvas_Window = wnd; 10175 10176 $ txSetDefaults(); 10177 10178 $ return true; 10179 } 10180 10181 //----------------------------------------------------------------------------------------------------------------- 10182 10183 bool _txCanvas_OnDESTROY (HWND wnd) 10184 { 10185 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10186 10187 // Инициируем остановку цикла сообщений 10188 10189 $ PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS); 10190 10191 $ if (!_txCanvas_Window) return false; 10192 10193 // Indicate that we are about to manually terminate 10194 10195 $ _txExit = true; 10196 10197 // Lock GDI resources 10198 10199 $ bool locked = false; 10200 $ _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT); 10201 $ if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources"); 10202 10203 // Освобождаем пользовательские ресурсы 10204 10205 $ if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty()) 10206 { 10207 $ txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size()); //-V202 10208 $ Sleep (_TX_TIMEOUT); 10209 10210 $ for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i)); 10211 $ _txCanvas_UserDCs->clear(); 10212 } 10213 10214 // Освобождаем ресурсы, связанные с окном 10215 10216 $ if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted; 10217 10218 $ if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1]) asserted; 10219 $ if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0]) asserted; 10220 $ _txCanvas_Pixels = NULL; 10221 10222 $ txUnlock(); 10223 10224 // Indicate that we are destroyed 10225 10226 $ _txCanvas_Window = NULL; 10227 10228 $ return true; 10229 } 10230 10231 //----------------------------------------------------------------------------------------------------------------- 10232 10233 bool _txCanvas_OnCLOSE (HWND wnd) //-V2009 //-V2558 10234 { 10235 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10236 $ if (!_txCanvas_OK()) return false; 10237 10238 $ if (_txMain && _txRunning && 10239 txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n" 10240 "Лучше подождать, когда main() завершится - это отображается в заголовке окна.", 10241 txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false; 10242 $ return true; 10243 } 10244 10245 //----------------------------------------------------------------------------------------------------------------- 10246 10247 bool _txCanvas_OnTIMER (HWND wnd, WPARAM) 10248 { 10249 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10250 10251 $ if (_txCanvas_RefreshLock > 0 || !_txRunning) return false; 10252 10253 $ InvalidateRect (wnd, NULL, false) asserted; 10254 $ UpdateWindow (wnd) asserted; 10255 10256 $ return true; 10257 } 10258 10259 //----------------------------------------------------------------------------------------------------------------- 10260 10261 bool _txCanvas_OnPAINT (HWND wnd) 10262 { 10263 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10264 $ if (!_txCanvas_OK()) return false; 10265 10266 $ bool forceRedraw = GetAsyncKeyState (VK_MENU) && GetAsyncKeyState (VK_CONTROL) && 10267 GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT); 10268 10269 $ PAINTSTRUCT ps = {}; 10270 $ HDC wndDc = BeginPaint (wnd, &ps); 10271 $ if (!wndDc) return false; 10272 10273 $ HDC dc0 = _txCanvas_BackBuf[0], 10274 dc1 = _txCanvas_BackBuf[1]; 10275 10276 $ RECT r = {}; 10277 $ GetClientRect (wnd, &r) asserted; 10278 $ POINT wndSize = { r.right - r.left, r.bottom - r.top }; 10279 10280 $ POINT dcSize = txGetExtent (dc1); 10281 10282 $ if ((_txCanvas_RefreshLock <= 0 || forceRedraw) && 10283 txLock (false)) 10284 { 10285 $ Win32::BitBlt (dc1, 0, 0, dcSize.x, dcSize.y, dc0, 0, 0, SRCCOPY); 10286 10287 $ if (_txConsole >= 0) 10288 {$ _txConsole_Draw (dc1); } 10289 10290 $ txUnlock(); 10291 } 10292 10293 // Magic 100500 value is used to completely block screen refresh. 10294 // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL. 10295 // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers 10296 // themselves. 10297 // Yes guys, with all your software installed. :( 10298 10299 $ if (_txCanvas_RefreshLock != 100500) 10300 { 10301 if (_txSwapBuffers) 10302 { 10303 $ _txSwapBuffers (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY); 10304 } 10305 else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y) 10306 { 10307 $ Win32::BitBlt (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, SRCCOPY); 10308 } 10309 else 10310 { 10311 $ Win32::SetStretchBltMode (wndDc, HALFTONE); 10312 $ Win32::StretchBlt (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY); 10313 } 10314 } 10315 10316 $ EndPaint (wnd, &ps) asserted; 10317 10318 $ return true; 10319 } 10320 10321 //----------------------------------------------------------------------------------------------------------------- 10322 10323 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info) 10324 { 10325 $8 INPUT_RECORD evt[2] = {}; 10326 10327 $ evt[0].EventType = KEY_EVENT; 10328 $ evt[0].Event.KeyEvent.bKeyDown = true; 10329 $ evt[0].Event.KeyEvent.wRepeatCount = 1; 10330 $ evt[0].Event.KeyEvent.uChar.AsciiChar = (char) (ch); 10331 $ evt[0].Event.KeyEvent.wVirtualScanCode = (WORD) (info >> 16); 10332 $ evt[0].Event.KeyEvent.wVirtualKeyCode = (WORD) MapVirtualKey ((WORD) (info >> 16), 3); // 3 == MAPVK_VSC_TO_VK_EX 10333 $ evt[0].Event.KeyEvent.dwControlKeyState = 0; 10334 10335 $ evt[1] = evt[0]; 10336 $ evt[1].Event.KeyEvent.bKeyDown = false; 10337 10338 $ DWORD written = 0; 10339 $ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), evt, 2, &written); 10340 10341 $ return true; 10342 } 10343 10344 //----------------------------------------------------------------------------------------------------------------- 10345 10346 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down) 10347 { 10348 $8 INPUT_RECORD evt = {}; 10349 10350 $ evt.EventType = KEY_EVENT; 10351 $ evt.Event.KeyEvent.bKeyDown = down; 10352 $ evt.Event.KeyEvent.wRepeatCount = 1; 10353 $ evt.Event.KeyEvent.uChar.AsciiChar = (char) MapVirtualKey ((WORD) vk, 2); // 2 == MAPVK_VK_TO_CHAR 10354 $ evt.Event.KeyEvent.wVirtualScanCode = (WORD) (info >> 16); 10355 $ evt.Event.KeyEvent.wVirtualKeyCode = (WORD) vk; 10356 $ evt.Event.KeyEvent.dwControlKeyState = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0; 10357 10358 $ if (evt.Event.KeyEvent.uChar.AsciiChar) return false; // Let TranslateMessage() and WM_CHAR do the job 10359 10360 $ DWORD written = 0; 10361 $ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written); 10362 10363 $ return true; 10364 } 10365 10366 //----------------------------------------------------------------------------------------------------------------- 10367 10368 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords) 10369 { 10370 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10371 $ if (!_txCanvas_OK()) return false; 10372 10373 $ if (_txMousePos.x == -1 && _txMousePos.y == -1) 10374 { 10375 $ TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT }; 10376 $ TrackMouseEvent (&track); 10377 } 10378 10379 $ _txMousePos.x = LOWORD (coords); 10380 $ _txMousePos.y = HIWORD (coords); 10381 $ _txMouseButtons = (unsigned) buttons; //-V202 10382 10383 $ return true; 10384 } 10385 10386 //----------------------------------------------------------------------------------------------------------------- 10387 10388 bool _txCanvas_OnMOUSELEAVE (HWND) 10389 { 10390 $8 _txMousePos.x = -1; 10391 $ _txMousePos.y = -1; 10392 $ _txMouseButtons = 0; 10393 10394 $ return true; 10395 } 10396 10397 //----------------------------------------------------------------------------------------------------------------- 10398 10399 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar) 10400 { 10401 $8 if (_TX_ARGUMENT_FAILED (lpar)) return false; 10402 10403 $ const CREATESTRUCT* create = (CREATESTRUCT*) lpar; 10404 10405 $ HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style, 10406 create->x, create->y, create->cx, create->cy, 10407 create->hwndParent, create->hMenu, NULL, create->lpCreateParams); 10408 10409 $ *(HWND*) create->hInstance = wnd; 10410 10411 $ return true; 10412 } 10413 10414 //----------------------------------------------------------------------------------------------------------------- 10415 10416 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar) 10417 { 10418 $8 if (_TX_ARGUMENT_FAILED (lpar)) return false; 10419 10420 $ DestroyWindow ((HWND) lpar); 10421 10422 $ return false; 10423 } 10424 10425 //----------------------------------------------------------------------------------------------------------------- 10426 10427 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd) 10428 { 10429 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10430 10431 $ HWND console = Win32::GetConsoleWindow(); 10432 $ if (!console) return false; 10433 10434 $ bool visible = !!IsWindowVisible (console); 10435 10436 $ ShowWindow (console, visible? SW_HIDE : SW_RESTORE); 10437 10438 $ visible = !!IsWindowVisible (console); 10439 $ CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED); //-V202 10440 10441 $ return true; 10442 } 10443 10444 //----------------------------------------------------------------------------------------------------------------- 10445 10446 bool _txCanvas_OnCmdABOUT (HWND, WPARAM) 10447 { 10448 $8 //{ Overriding the missing names, if the set is incomplete 10449 10450 #if defined (__MODULE) 10451 #define ABOUT_NAME_ __MODULE 10452 #else 10453 #define ABOUT_NAME_ "TXLib" 10454 #endif 10455 10456 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR) 10457 10458 #ifndef __MODULE 10459 #define __MODULE "TXLib" "\n" "#define __MODULE to set the name.\n" 10460 #endif 10461 10462 #ifndef __VERSION 10463 #define __VERSION "(0.000000000)." "\n" "#define __VERSION to set the string value.\n" 10464 #endif 10465 10466 #ifndef __DESCRIPTION 10467 #define __DESCRIPTION "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n" 10468 #endif 10469 10470 #ifndef __AUTHOR 10471 #define __AUTHOR "(Непонятно кто)." "\n" "#define __AUTHOR to override this name." 10472 #endif 10473 10474 #endif 10475 //} 10476 10477 $ static char text[_TX_BUFSIZE] = ""; 10478 10479 $ _tx_snprintf_s (text, sizeof (text) - 1, 10480 10481 "Application:\n\n" 10482 10483 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR) 10484 __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n" 10485 #else 10486 "Здесь могла бы быть Ваша реклама :)\n" 10487 "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n" 10488 #endif 10489 10490 "\n" "%s", _txAppInfo()); 10491 10492 $ txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION); 10493 10494 // And a bit of HTTP-code in C++ function: 10495 10496 goto http; 10497 http://sizeof.livejournal.com 10498 10499 $ return true; 10500 10501 #undef ABOUT_NAME_ 10502 } 10503 10504 #endif // TX_COMPILED 10505 10507 //} 10508 //================================================================================================================= 10509 10510 //================================================================================================================= 10511 //{ Console-support functions (_txConsole...) 10513 //================================================================================================================= 10515 10516 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10517 10518 HWND _txConsole_Attach() 10519 { 10520 $1 HWND console = Win32::GetConsoleWindow(); 10521 10522 $ if (!console) 10523 { 10524 $ bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem()); 10525 10526 $ Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb(); 10527 $ assert (teb); 10528 $ assert (teb->ProcessEnvironmentBlock); 10529 10530 $ Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters; 10531 $ assert (params); 10532 10533 $ if (minimizeConsole) // The fact that ShowWindow parameter of the program's console is taken from calling 10534 // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo() 10535 // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :( 10536 // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke!.. 10537 { 10538 $ params->dwFlags |= STARTF_USESHOWWINDOW; 10539 $ params->wShowWindow = SW_MINIMIZE; 10540 } 10541 10542 $ AllocConsole(); 10543 $ console = Win32::GetConsoleWindow(); 10544 } 10545 10546 $ if (!console) return NULL; 10547 10548 $ txSetLocale(); // Устанавливаем русскую кодовую страницу для консоли Windows 10549 10550 $ _txConsole_SetUnicodeFont(); // Впечатлительным лучше сюда не смотреть. 10551 10552 $ if (!_txIsConsoleSubsystem()) 10553 {$ txReopenStdio(); } // Переоткрываем потоки ввода-вывода, если subsystem != console 10554 10555 $ return console; 10556 } 10557 10558 //----------------------------------------------------------------------------------------------------------------- 10559 10560 int txSetLocale (int codepage /*= _TX_CODEPAGE*/, 10561 const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/) 10562 { 10563 $1 int oldPage = GetConsoleOutputCP(); 10564 10565 // Устанавливаем нужную кодовую страницу для консоли Windows 10566 10567 $ if (codepage) 10568 { 10569 $ SetConsoleCP (codepage); 10570 $ SetConsoleOutputCP (codepage); 10571 } 10572 10573 // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии 10574 // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным 10575 // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN - 10576 // обозначение кодовой страницы (например, для русского языка - CP1251). 10577 10578 $ if (locale) 10579 { 10580 $ setlocale (LC_ALL, locale); 10581 $ setlocale (LC_NUMERIC, "C"); // Return to decimal point (3.14) instead of comma (3,14) in floating numbers 10582 } 10583 10584 #ifndef __CYGWIN__ 10585 10586 $ const bool wine = !!Win32::wine_get_version; // Linux::Wine v1.2.2+ compatibility. 10587 10588 $ if (wLocale && !wine) 10589 { 10590 $ _wsetlocale (LC_ALL, wLocale); 10591 $ _wsetlocale (LC_NUMERIC, L"C"); // L"C" (see above) 10592 } 10593 10594 #endif 10595 10596 (void) wLocale; 10597 10598 $ return oldPage; 10599 } 10600 10601 //----------------------------------------------------------------------------------------------------------------- 10602 10603 void txReopenStdio() 10604 { 10605 $1 // Переоткрываем заново <s>Америку</s> потоки ввода-вывода 10606 10607 $ fflush (stdout); 10608 $ fflush (stderr); 10609 10610 $ FILE* f = NULL; 10611 10612 #ifndef __CYGWIN__ 10613 10614 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE), _O_TEXT), "r"); assert (f); *stdin = *f; 10615 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f; 10616 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE), _O_TEXT), "w"); assert (f); *stderr = *f; 10617 10618 #else 10619 10620 $ f = _fdopen (STDIN_FILENO, "r"); assert (f); *stdin = *f; 10621 $ f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f; 10622 $ f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f; 10623 10624 #endif 10625 10626 $ setvbuf (stdin, NULL, _IONBF, 0); 10627 $ setvbuf (stdout, NULL, _IONBF, 0); 10628 $ setvbuf (stderr, NULL, _IONBF, 0); 10629 10630 $ ::std::ios::sync_with_stdio(); 10631 } 10632 10633 //----------------------------------------------------------------------------------------------------------------- 10634 10635 inline bool _txConsole_OK() 10636 { 10637 return Win32::GetConsoleWindow() != NULL; 10638 } 10639 10640 //----------------------------------------------------------------------------------------------------------------- 10641 10642 bool _txConsole_Detach (bool activate) 10643 { 10644 $1 HWND console = Win32::GetConsoleWindow(); 10645 $ if (!console) return false; 10646 10647 $ EnableWindow (console, true); 10648 10649 $ if (activate) 10650 { 10651 $ if (!IsWindowVisible (console)) 10652 {$ ShowWindow (console, SW_MINIMIZE); } 10653 10654 $ _txActivateWindow (console, 0xFF); 10655 $ return true; 10656 } 10657 else 10658 { 10659 $ return !!FreeConsole(); 10660 } 10661 } 10662 10663 //----------------------------------------------------------------------------------------------------------------- 10664 10665 bool _txConsole_Draw (HDC dc) 10666 { 10667 $8 if (_TX_HDC_FAILED (dc)) return false; 10668 10669 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10670 10671 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 10672 $ BOOL ok = GetConsoleScreenBufferInfo (out, &con); 10673 $ if (!ok) return false; 10674 10675 $ POINT size = { con.srWindow.Right - con.srWindow.Left + 1, 10676 con.srWindow.Bottom - con.srWindow.Top + 1 }; 10677 10678 $ SIZE fontSz = { 12, 16 }; 10679 $ Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted; 10680 10681 $ COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, 10682 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF }; 10683 10684 $ for (short y = 0; y < size.y; y++) 10685 { 10686 static char chr [_TX_BUFSIZE + 1] = ""; // [con.dwSize.X + 1]; maybe will be truncated 10687 static WORD atr [_TX_BUFSIZE + 1] = {}; // [con.dwSize.X + 1]; maybe will be truncated 10688 COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) }; 10689 DWORD read = 0; 10690 10691 if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue; 10692 if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue; 10693 10694 for (int x = 0, xEnd = size.x; x < size.x; x = xEnd) 10695 { 10696 Win32::SetTextColor (dc, pal [ atr[x] & 0x0F]); 10697 Win32::SetBkColor (dc, pal [(atr[x] >> 4) & 0x0F]); 10698 Win32::SetBkMode (dc, (atr[x] & 0xF0)? OPAQUE : TRANSPARENT); 10699 10700 for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;} 10701 10702 Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)), 10703 ROUND (fontSz.cy * y), chr + x, xEnd - x) asserted; 10704 } 10705 } 10706 10707 $ Win32::SetTextColor (dc, pal [ con.wAttributes & 0x0F]); 10708 $ Win32::SetBkColor (dc, pal [(con.wAttributes >> 4) & 0x0F]); 10709 $ Win32::SetBkMode (dc, TRANSPARENT); 10710 10711 $ if (_txConsole_IsBlinking && 10712 In (std::nomeow, con.dwCursorPosition, con.srWindow) && 10713 GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval && 10714 GetForegroundWindow() == txWindow()) 10715 { 10716 $ Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)), 10717 ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1, 10718 "_", 1) asserted; 10719 } 10720 10721 $ return true; 10722 } 10723 10724 #endif // TX_COMPILED 10725 10726 //----------------------------------------------------------------------------------------------------------------- 10727 //{ Welcome to the Duck Side! Together we will rule the Bathroom! 10728 //----------------------------------------------------------------------------------------------------------------- 10729 10730 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10731 10732 bool _txConsole_SetUnicodeFont() 10733 { 10734 $ const bool wine = !!Win32::wine_get_version; // Linux::Wine v1.2.2+ compatibility. 10735 // Beer compatibility may be added in future versions... 10736 $ if (wine) // Минздрав РФ предупреждает: чрезмерное употребление wine 10737 { // вредит Вашему здоровью. 10738 $ Win32::GetNumberOfConsoleFonts = NULL; 10739 $ Win32::GetCurrentConsoleFont = NULL; 10740 $ Win32::SetConsoleFont = NULL; 10741 10742 $ return false; 10743 } 10744 10745 // Начиная с Висты все хорошо... 10746 10747 $1 if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx) 10748 { 10749 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10750 10751 $ Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) }; 10752 $ if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false; 10753 10754 $ info.FontFamily = 0x36; // Unicode fixed-pitch 10755 $ if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2); // Terminal font is too small 10756 10757 $ if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0) // Consolas is allowed too 10758 {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); } 10759 10760 $ return !!Win32::SetCurrentConsoleFontEx (out, false, &info); 10761 } 10762 10763 // ...а до этого все не так сладко 10764 10765 $ const unsigned uniFont = 10; // The Internet and W2K sources know this magic number 10766 $ const unsigned uniSize = 20; // Size of the font desired, should be > max # of Raster Fonts //-V2551 10767 $ bool ok = true; 10768 10769 // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font. 10770 10771 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10772 10773 $ unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ()); 10774 $ if (fonts && fonts <= uniFont) 10775 { 10776 $ HRESULT init = Win32::CoInitialize (NULL); 10777 $ size_t sz = 0; 10778 10779 $ char link [MAX_PATH] = ""; 10780 $ getenv_s (&sz, link, sizeof (link) - 1, "TEMP"); 10781 $ strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1); 10782 10783 $ char comspec [MAX_PATH] = ""; 10784 $ getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC"); 10785 10786 $ (void) _unlink (link); 10787 10788 $ _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted; 10789 10790 $ ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32); // Sic! //-V112 //-V566 10791 if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); } 10792 10793 $ (void) _unlink (link); 10794 10795 $ if (init == S_OK) Win32::CoUninitialize(); 10796 } 10797 10798 // If Unicode font is not already set, do set it. 10799 10800 $ Win32::CONSOLE_FONT_INFO cur = {}; 10801 $ _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur)); 10802 10803 $ ok &= (cur.nFont >= uniFont); 10804 if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); } 10805 10806 $ HWND console = Win32::GetConsoleWindow(); 10807 $ InvalidateRect (console, NULL, false); 10808 $ UpdateWindow (console); 10809 10810 $ return ok; 10811 } 10812 10813 #endif // TX_COMPILED 10814 10815 //----------------------------------------------------------------------------------------------------------------- 10816 //{ The assistants to the nightmare. You can use it freely to make your own nightmare sweet. 10817 10818 #define _TX_TRY { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error; 10819 #define _TX_CHECKED( cmd ) { if (FAILED (__tx_error = (cmd))) goto __tx_catch; } 10820 #define _TX_FAIL { __tx_error = E_FAIL; goto __tx_catch; } 10821 #define _TX_RETRY { __tx_error = S_OK; goto __tx_try; } 10822 #define _TX_OK ( SUCCEEDED (__tx_error) ) 10823 #define _TX_CATCH goto __tx_finally; __tx_catch: 10824 #define _TX_RETURN goto __tx_finally; 10825 #define _TX_FINALLY __tx_finally: 10826 #define _TX_ENDTRY } 10827 10828 //} 10829 //----------------------------------------------------------------------------------------------------------------- 10830 10831 // Мало не покажется 10832 10833 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10834 10835 bool _txCreateShortcut (const char shortcutName[], 10836 const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/, 10837 const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/, 10838 int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/) 10839 { 10840 $1 if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false; 10841 $ if (_TX_ARGUMENT_FAILED (fileToLink && *fileToLink)) return false; 10842 10843 #if defined (__IShellLinkDataList_INTERFACE_DEFINED__) 10844 10845 $ IShellLink* shellLink = NULL; 10846 $ IShellLinkDataList* dataList = NULL; 10847 $ IPersistFile* file = NULL; 10848 10849 $ HRESULT init = Win32::CoInitialize (NULL); 10850 10851 _TX_TRY 10852 { 10853 $ _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink)); 10854 $ if (!shellLink) _TX_FAIL; 10855 10856 $ shellLink->SetPath (fileToLink); 10857 $ shellLink->SetArguments (args); 10858 $ shellLink->SetWorkingDirectory (workDir); 10859 $ shellLink->SetDescription (description); 10860 $ shellLink->SetShowCmd (cmdShow); 10861 $ shellLink->SetIconLocation (iconFile, iconIndex); 10862 10863 $ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList)); 10864 $ if (!dataList) _TX_FAIL; 10865 10866 $ Win32::NT_CONSOLE_PROPS props = 10867 {{sizeof (props), NT_CONSOLE_PROPS_SIG}, 10868 10869 FOREGROUND_LIGHTGRAY, // wFillAttribute 10870 FOREGROUND_MAGENTA | BACKGROUND_WHITE, // wPopupFillAttribute 10871 {bufSize.X, bufSize.Y}, // dwScreenBufferSize 10872 {wndSize.X, wndSize.Y}, // dwWindowSize 10873 {wndOrg.X, wndOrg.Y}, // dwWindowOrigin 10874 0, // nFont 10875 0, // nInputBufferSize 10876 {0, (short) fontSize}, // dwFontSize 10877 0x36, 400, L"Lucida Console", // uFontFamily, uFontWeight, FaceName. We're dancing for this! 10878 15, // uCursorSize 10879 0, 1, 1, 0, // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition 10880 50, 4, 0, // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup 10881 10882 {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, // Palette 10883 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF} 10884 }; 10885 10886 $ _TX_CHECKED (dataList->AddDataBlock (&props)); 10887 10888 $ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file)); 10889 $ if (!file) _TX_FAIL; 10890 10891 $ wchar_t wName[MAX_PATH] = L""; 10892 $ MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName)); 10893 10894 $ _TX_CHECKED (file->Save (wName, true)); 10895 } 10896 10897 $ _TX_CATCH 10898 $ _TX_FINALLY 10899 10900 if (file) {$ file ->Release(); } 10901 if (dataList) {$ dataList ->Release(); } 10902 if (shellLink) {$ shellLink->Release(); } 10903 10904 if (init == S_OK) {$ Win32::CoUninitialize(); } 10905 10906 $ return _TX_OK; 10907 _TX_ENDTRY 10908 10909 #else 10910 10911 (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex; 10912 (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg; 10913 10914 $ return false; 10915 10916 #endif 10917 } 10918 10919 #endif // TX_COMPILED 10920 10921 //} 10922 //----------------------------------------------------------------------------------------------------------------- 10923 10925 //} 10926 //================================================================================================================= 10927 10928 //================================================================================================================= 10929 //{ Memory DC functions (_txBuffer...) 10931 //================================================================================================================= 10933 10934 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10935 10936 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/) 10937 { 10938 $1 txAutoLock _lock; 10939 10940 $ HDC wndDC = GetDC (wnd); 10941 $ if (!wndDC) return NULL; 10942 10943 $ POINT sz = { 1, 1 }; 10944 $ if (size) sz = *size; 10945 10946 $ if (!size && wnd) 10947 { 10948 $ RECT r = {}; 10949 $ GetClientRect (wnd, &r) asserted; 10950 10951 $ sz.x = r.right - r.left; 10952 $ sz.y = r.bottom - r.top; 10953 } 10954 10955 $ if (bitmap) 10956 { 10957 $ BITMAP bmap = {}; 10958 $ Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted; 10959 10960 $ sz.x = bmap.bmWidth; 10961 $ sz.y = bmap.bmHeight; 10962 } 10963 10964 $ RGBQUAD* buf = NULL; 10965 $ if (!pixels) pixels = &buf; 10966 10967 $ HDC dc = Win32::CreateCompatibleDC (wndDC); 10968 $ if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed"); 10969 10970 #ifndef _TX_DIB_FIX 10971 #define _TX_DIB_FIX 10972 #endif 10973 10974 $ BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }}; 10975 10976 $ HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0); 10977 $ if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed"); 10978 10979 $ Win32::SelectObject (dc, bmap) asserted; 10980 10981 $ if (!bitmap) 10982 { 10983 $ if (*pixels) 10984 { 10985 $ RGBQUAD black = { 0, 0, 0, 255 }; 10986 $ for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black; //-V108 10987 } 10988 else 10989 {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; } 10990 } 10991 10992 $ ReleaseDC (wnd, wndDC) asserted; 10993 10994 $ return dc; 10995 } 10996 10997 //----------------------------------------------------------------------------------------------------------------- 10998 10999 bool _txBuffer_Delete (HDC* dc) 11000 { 11001 $1 if (_TX_ARGUMENT_FAILED (dc)) return false; 11002 $ if ( !*dc) return false; 11003 $ if (_TX_HDC_FAILED (*dc)) return false; 11004 11005 $ if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false; 11006 11007 $ txAutoLock _lock; 11008 11009 $ _txBuffer_Select (Win32::GetStockObject (NULL_PEN), *dc) asserted; 11010 $ _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH), *dc) asserted; 11011 $ _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted; 11012 $ _txBuffer_Select (_txStockBitmap, *dc); 11013 11014 $ Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted; 11015 11016 $ Win32::DeleteDC (*dc) asserted; 11017 11018 $ *dc = NULL; 11019 11020 $ return true; 11021 } 11022 11023 //----------------------------------------------------------------------------------------------------------------- 11024 11025 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/) 11026 { 11027 $1 if (!obj) return false; 11028 $ if (_TX_HDC_FAILED (dc)) return false; 11029 11030 $ if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type"); 11031 11032 $ txAutoLock _lock; 11033 11034 $ obj = Win32::SelectObject (dc, obj); 11035 $ if (obj) Win32::DeleteObject (obj); 11036 11037 $ return obj != NULL; 11038 } 11039 11040 #endif // TX_COMPILED 11041 11043 //} 11044 //================================================================================================================= 11045 11046 //================================================================================================================= 11047 //{ Diagnostics 11049 //================================================================================================================= 11051 11052 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11053 11054 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/, 11055 const char* msg /*= NULL*/, ...) 11056 { //---/\---/\-------Это ASCII KOT!--// 11057 $1 va_list arg; va_start (arg, msg); // { '-' } // 11058 $$ const char* what = _txProcessError (file, line, func, color, msg, arg); // { 0 0 } Добавь его себе // 11059 va_end (arg); // --> V <-- в исходник, и тебе // 11060 // \ \|/ / будет, наверно, // 11061 if (!(msg && msg[0] == '\a')) return what; // \___/ приятно отлаживаться // 11062 //---------------долгими ночами:)--// 11063 // vvvvvvvvvvvvvvvvvv 11064 DebugBreak(); // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться. 11065 // ^^^^^^^^^^^^^^^^^^ 11066 11067 return what; // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7). 11068 } 11069 11070 #endif // TX_COMPILED 11071 11072 //----------------------------------------------------------------------------------------------------------------- 11073 //{ General runtime check hooks 11074 //----------------------------------------------------------------------------------------------------------------- 11075 11076 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11077 11078 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/) 11079 { 11080 $1 if (!sig && !fpe) 11081 { 11082 $ signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11083 $ signal (SIGFPE, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11084 $ signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11085 $ signal (SIGILL, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11086 $ signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11087 $ return; 11088 } 11089 11090 txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe); 11091 11092 #define GET_DESCR_(str, code, descr) case (code): {$ (str) = " " #code ": " descr; break; } 11093 11094 $ const char* sSig = "Неизвестный тип сигнала"; 11095 11096 $ switch (sig) 11097 { 11098 GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!") 11099 GET_DESCR_ (sSig, SIGILL, "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.") 11100 GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().") 11101 GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.") 11102 GET_DESCR_ (sSig, SIGFPE, "Грубая ошибка в вычислениях.") 11103 default: break; //-V2522 11104 } 11105 11106 $ const char* sFPE = ""; 11107 11108 #if defined (_MSC_VER) 11109 11110 // MSVC provides the FPE code as a MS extension. 11111 // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx 11112 11113 $ if (sig == SIGFPE) switch (fpe) 11114 { 11115 GET_DESCR_ (sFPE, _FPE_INVALID, "Результат неверен.") 11116 GET_DESCR_ (sFPE, _FPE_DENORMAL, "Денормализация.") 11117 GET_DESCR_ (sFPE, _FPE_ZERODIVIDE, "Деление на ноль.") 11118 GET_DESCR_ (sFPE, _FPE_OVERFLOW, "Результат слишком большой.") 11119 GET_DESCR_ (sFPE, _FPE_UNDERFLOW, "Результат слишком маленький.") 11120 GET_DESCR_ (sFPE, _FPE_INEXACT, "Результат неточен.") 11121 GET_DESCR_ (sFPE, _FPE_UNEMULATED, "Операция не поддерживается.") 11122 GET_DESCR_ (sFPE, _FPE_SQRTNEG, "Квадратный корень из отрицательного числа.") 11123 GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW, "Переполнение стека сопроцессора.") 11124 GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.") 11125 GET_DESCR_ (sFPE, _FPE_EXPLICITGEN, "Явный вызов исключения.") 11126 default: break; //-V2522 11127 } 11128 11129 #else 11130 $ fpe = 0; 11131 #endif 11132 11133 #undef GET_DESCR_ 11134 11135 $ signal (sig, (void(*)(int))(uintptr_t)_txOnSignal); 11136 11137 $ Win32::_fpreset(); 11138 11139 $ _TX_UNEXPECTED ("\a\t" 11140 "signal (%d, 0x%02X):%s%s " 11141 "%s%s" 11142 "С помощью функции signal() вы можете сами обработать эту ошибку.", 11143 sig, (unsigned) fpe, sSig, sFPE, 11144 ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1); 11145 } 11146 11147 //----------------------------------------------------------------------------------------------------------------- 11148 11149 void _txOnTerminate() 11150 { 11151 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11152 11153 // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc 11154 11155 $1 static int terminating = 0; 11156 if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; } 11157 11158 $ if (!*_txDumpSE) 11159 {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); } 11160 11161 $ _TX_UNEXPECTED ("\t\a" 11162 "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, " 11163 "или другая фатальная ошибка C++. " 11164 "%s" 11165 "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, " 11166 "разбирайтесь, в чем дело.\n\n" 11167 "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE, 11168 _txDumpSE + 1); 11169 } 11170 11171 //----------------------------------------------------------------------------------------------------------------- 11172 11173 void _txOnUnexpected() 11174 { 11175 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11176 11177 $1 if (!*_txDumpSE) 11178 {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); } 11179 11180 $ _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n" 11181 "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете " 11182 "спецификацию исключений для функций, проверьте, не нарушена ли она." 11183 "%s" 11184 "С помощью catch (...) в main() вы можете сами обработать эту ошибку.", 11185 _txDumpSE + 1); 11186 } 11187 11188 //----------------------------------------------------------------------------------------------------------------- 11189 11190 int _txOnMatherr (_exception* exc) 11191 { 11192 txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc); 11193 11194 $1 assert (exc); 11195 11196 const char* sType = "Неизвестный тип исключения"; 11197 11198 #if !defined (__CYGWIN__) 11199 11200 #define GET_DESCR_(code, descr) case (code): {$ sType = "(" #code "): " descr; break; } 11201 11202 $ switch (exc->type) 11203 { 11204 GET_DESCR_ (_DOMAIN, "Нарушение области определения"); 11205 GET_DESCR_ (_SING, "Сингулярность аргумента"); 11206 GET_DESCR_ (_PLOSS, "Частичная потеря значимости"); 11207 GET_DESCR_ (_TLOSS, "Полная потеря значимости"); 11208 GET_DESCR_ (_OVERFLOW, "Результат слишком большой"); 11209 GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький"); 11210 default: break; //-V2522 11211 } 11212 11213 #undef GET_DESCR_ 11214 11215 $ _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n" 11216 "С помощью __setusermatherr() вы можете сами обработать эту ошибку.", 11217 exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval); 11218 #else 11219 11220 $ _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType); 11221 11222 #endif 11223 11224 return 0; 11225 } 11226 11227 //----------------------------------------------------------------------------------------------------------------- 11228 11229 tx_noreturn void _txOnNewHandlerAnsi() 11230 { 11231 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11232 $1 11233 $ _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n" 11234 "С помощью std::set_new_handler() вы можете сами обработать эту ошибку " 11235 "и где-нибудь найти недостающую память."); 11236 11237 $ throw std::bad_alloc(); 11238 } 11239 11240 //----------------------------------------------------------------------------------------------------------------- 11241 11242 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code) 11243 { 11244 txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code); 11245 11246 $1 if (code) 11247 {$ errno = code; } 11248 11249 $ _TX_UNEXPECTED ("\a" 11250 "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n" 11251 "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку " 11252 "и постараться не выходить за границы массивов.", 11253 code, msg, (char*) ptr, ptr); 11254 } 11255 11256 //----------------------------------------------------------------------------------------------------------------- 11257 11258 int tx_glGetError (int setError /*= INT_MIN*/) 11259 { 11260 $1 _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError; 11261 $ return _txOGLError; 11262 } 11263 11264 #endif // TX_COMPILED 11265 11266 //} 11267 //----------------------------------------------------------------------------------------------------------------- 11268 11269 //----------------------------------------------------------------------------------------------------------------- 11270 //{ MSC Runtime check hooks 11271 //----------------------------------------------------------------------------------------------------------------- 11272 11273 #if defined (_MSC_VER) 11274 11275 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11276 11277 //----------------------------------------------------------------------------------------------------------------- 11278 11279 int _txOnNewHandler (size_t size) 11280 { 11281 txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size); 11282 $5 11283 $ _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n" 11284 "С помощью _set_new_handler() вы можете сами обработать эту ошибку " 11285 "и где-нибудь найти недостающую память.", (unsigned long long) size); 11286 11287 $ throw std::bad_alloc(); 11288 } 11289 11290 //----------------------------------------------------------------------------------------------------------------- 11291 11292 void _txOnSecurityError (int code, void* addr) 11293 { 11294 txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr); 11295 $5 11296 $ _TX_UNEXPECTED ("\a" 11297 "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n" 11298 "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку " 11299 "и более торжественно завершить программу. Ставьте же ассерты.", code); 11300 } 11301 11302 //----------------------------------------------------------------------------------------------------------------- 11303 11304 void _txOnPureCall() 11305 { 11306 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11307 $5 11308 $ _TX_UNEXPECTED ("\a" 11309 "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах " 11310 "или деструкторах базовых классов - не вызывайте там таких функций.\n\n" 11311 "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку " 11312 "и проверить свое знание С++ :)"); 11313 } 11314 11315 //----------------------------------------------------------------------------------------------------------------- 11316 11317 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr) 11318 { 11319 txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr); 11320 11321 $5 assert (wExpr); 11322 assert (wFunc); 11323 assert (wFile); 11324 11325 char expr [_TX_BUFSIZE/2] = "[Unknowm expr]", 11326 func [_TX_BUFSIZE/2] = "[Unknowm func]", 11327 file [MAX_PATH] = "[Unknowm file]"; 11328 11329 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL); 11330 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL); 11331 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL); 11332 11333 $$ _txError (file, (int) line, func, 0, "\a" 11334 "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n" 11335 "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr); 11336 } 11337 11338 //----------------------------------------------------------------------------------------------------------------- 11339 11340 #if defined (_CLANG_VER) && !defined (_MSC_VER) 11341 11342 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info) 11343 { 11344 $5 assert (&info); 11345 11346 $$ _txError (info.__file_, info.__line_, NULL, 0, "\a" 11347 "Оказалось неверно, что %s (%s). Не надо так.\n\n" 11348 "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_); 11349 } 11350 11351 #endif 11352 11353 //----------------------------------------------------------------------------------------------------------------- 11354 11355 #pragma runtime_checks ("", off) 11356 11357 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...) 11358 { 11359 txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format); 11360 11361 $5 static long running = 0; 11362 $ while (InterlockedExchange (&running, 1)) Sleep (0); 11363 11364 $ assert (format); 11365 11366 // Disable all RTC failures 11367 11368 $ int nErrors = _RTC_NumErrors(); 11369 $ int* errors = NULL; 11370 $ try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;} //-V104 11371 11372 $ int err = 0; 11373 $ for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE); //-V108 11374 11375 $ char text [_TX_BUFSIZE] = ""; 11376 11377 $ va_list arg; va_start (arg, format); 11378 $ _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg); // Get message from the vararg list 11379 $ auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/); // Get the RTC error number 11380 $ va_end (arg); 11381 11382 $ const char* sType = "type"; 11383 11384 $ switch (type) 11385 { 11386 case _CRT_ERROR: $ sType = "ошибка"; break; 11387 case _CRT_ASSERT: $ sType = "логическая ошибка"; break; 11388 case _CRT_WARN: $ sType = "возможная ошибка"; break; 11389 default: $ break; 11390 } 11391 11392 $ const char* sError = _RTC_GetErrDesc (error); 11393 11394 $$ _txError (file, line, NULL, 0, "\a" 11395 "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module); 11396 11397 // The code below will be never executed until the error above will stay fatal: 11398 11399 // Restore the RTC error types 11400 11401 #if defined (_MSC_VER) 11402 #pragma warning (push) 11403 #pragma warning (disable: 6385) // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read. 11404 #endif 11405 11406 $ for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR)); //-V108 11407 11408 #if defined (_MSC_VER) 11409 #pragma warning (pop) // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read. 11410 #endif 11411 11412 $ InterlockedExchange (&running, 0); 11413 $ return 1; 11414 } 11415 11416 #pragma runtime_checks ("", restore) 11417 11418 //----------------------------------------------------------------------------------------------------------------- 11419 11420 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line) 11421 { 11422 #if (_TX_ALLOW_TRACE +0 >= 4) 11423 11424 static _tx_thread int recursive = 0; 11425 if (recursive) return true; 11426 recursive++; 11427 11428 #if (_TX_ALLOW_TRACE +0 <= 10) 11429 if (!size) return true; 11430 #endif 11431 11432 #define GET_DESCR_(str, type) case (type): { str = #type; break; } 11433 11434 const char* sType = "Unknown type"; 11435 const char* sUse = "Unknown use"; 11436 11437 switch (_BLOCK_TYPE (type)) 11438 { 11439 GET_DESCR_ (sType, _HOOK_ALLOC); 11440 GET_DESCR_ (sType, _HOOK_REALLOC); 11441 GET_DESCR_ (sType, _HOOK_FREE); 11442 default: break; 11443 } 11444 11445 switch (use) 11446 { 11447 GET_DESCR_ (sUse, _NORMAL_BLOCK); 11448 GET_DESCR_ (sUse, _CRT_BLOCK); 11449 GET_DESCR_ (sUse, _CLIENT_BLOCK); 11450 GET_DESCR_ (sUse, _FREE_BLOCK); 11451 GET_DESCR_ (sUse, _IGNORE_BLOCK); 11452 default: break; 11453 } 11454 11455 #undef GET_DESCR_ 11456 11457 _txTrace ((const char*) file, line, NULL, "%*s" 11458 "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)", 11459 2 * _txLoc::Cur.inTX, "", 11460 type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request); 11461 11462 recursive--; 11463 11464 #else 11465 11466 UNREFERENCED_PARAMETER (type); 11467 UNREFERENCED_PARAMETER (data); 11468 UNREFERENCED_PARAMETER (size); 11469 UNREFERENCED_PARAMETER (use); 11470 UNREFERENCED_PARAMETER (request); 11471 UNREFERENCED_PARAMETER (file); 11472 UNREFERENCED_PARAMETER (line); 11473 11474 #endif 11475 11476 return true; //-V601 11477 } 11478 11479 //----------------------------------------------------------------------------------------------------------------- 11480 11481 #endif // TX_COMPILED 11482 11483 #endif 11484 11485 //} 11486 //----------------------------------------------------------------------------------------------------------------- 11487 11488 //----------------------------------------------------------------------------------------------------------------- 11489 //{ SEH staff 11490 //----------------------------------------------------------------------------------------------------------------- 11491 11492 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11493 11494 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc) 11495 { 11496 if (!_txProcessSystemWarnings) 11497 { 11498 DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode : 0; //-V560 11499 void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL; //-V560 11500 11501 if (code != DBG_PRINTEXCEPTION_C && 11502 code != DBG_PRINTEXCEPTION_WIDE_C) 11503 { 11504 txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n", 11505 _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings); 11506 } 11507 11508 return EXCEPTION_CONTINUE_SEARCH; 11509 } 11510 else 11511 { 11512 int inTX = _txLoc::Cur.inTX++; 11513 11514 long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler"); 11515 11516 _txLoc::Cur.inTX = inTX; 11517 return ret; 11518 } 11519 } 11520 11521 //----------------------------------------------------------------------------------------------------------------- 11522 11523 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc) 11524 { 11525 int inTX = _txLoc::Cur.inTX++; 11526 11527 long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter"); 11528 11529 if (_txPrevUEFilter) 11530 { 11531 if (_txSetJmp()) 11532 { 11533 int inTX2 = _txLoc::Cur.inTX++; 11534 11535 ret = _txPrevUEFilter (exc); 11536 11537 _txLoc::Cur.inTX = inTX2; 11538 } 11539 else 11540 { 11541 $6 _txClearJmp(); 11542 11543 _TX_UNEXPECTED ("\t\a" "%s" 11544 "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n" 11545 "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE, 11546 _txDumpSE + 1); 11547 } 11548 } 11549 11550 _txLoc::Cur.inTX = inTX; 11551 return ret; 11552 } 11553 11554 //----------------------------------------------------------------------------------------------------------------- 11555 11556 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter) 11557 { 11558 $6 _txPrevUEFilter = filter; 11559 11560 return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter; 11561 } 11562 11563 //----------------------------------------------------------------------------------------------------------------- 11564 11565 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[]) 11566 { 11567 assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; } //-V547 11568 11569 assert (exc->ExceptionRecord); 11570 11571 assert (func); 11572 assert (func[3] == 'V' || func[3] == 'U'); 11573 11574 bool unhExc = (func[3] == 'U'); 11575 DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode : 0; //-V560 11576 void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL; //-V560 11577 11578 if (code == DBG_PRINTEXCEPTION_C || 11579 code == DBG_PRINTEXCEPTION_WIDE_C || 11580 code == DBG_THREAD_NAME || 11581 (code == RPC_S_SERVER_UNAVAILABLE && !unhExc) || 11582 (code == RPC_S_CALL_CANCELLED && !unhExc) || 11583 (code == EXCEPTION_BREAKPOINT && IsDebuggerPresent())) 11584 return EXCEPTION_CONTINUE_SEARCH; 11585 11586 ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr; 11587 if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; } 11588 11589 dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr; 11590 if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; } 11591 11592 _txSENumber = _txSENumber + 1; 11593 if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1; 11594 11595 OutputDebugString ("\n"); 11596 txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n", 11597 _TX_VERSION, _txSENumber, func, (unsigned long) code, addr); 11598 11599 $6 if (*(unsigned long long*) _txDumpExceptionObjJmp) 11600 { 11601 $ longjmp (_txDumpExceptionObjJmp, 1); //-V2512 11602 } 11603 11604 tx_fpreset(); 11605 11606 #if defined (_MSC_VER) 11607 if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); } 11608 #endif 11609 11610 $ bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord)); //-V560 11611 11612 $ if (primaryException && exc) //-V560 11613 { 11614 $ unsigned err = GetLastError(); 11615 11616 $ const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc); 11617 11618 $ _txDumpExceptionSEH (_txDumpSE, (intptr_t) sizeof (_txDumpSE) - 1, exc->ExceptionRecord, func); 11619 $ _tx_snprintf_s (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace); 11620 11621 $ static _tx_thread DWORD prevCode = 0; 11622 $ static _tx_thread void* prevAddr = NULL; 11623 11624 $ if (code != prevCode && addr != prevAddr && 11625 !strstr (_txDumpSE, "Объект исключения C++:")) 11626 { 11627 $ SetLastError (err); 11628 $ _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1); 11629 11630 $ prevCode = code; 11631 $ prevAddr = addr; 11632 } 11633 11634 $ SetLastError (err); 11635 } 11636 11637 $ if (_txDumpSE[0] == '\a' || 11638 _txSENumber >= _TX_EXCEPTIONS_LIMIT+0 || 11639 _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0) 11640 { 11641 $ _TX_UNEXPECTED ("\a\t" "%s" 11642 "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.", 11643 _txDumpSE + 1); 11644 } 11645 11646 $ return EXCEPTION_CONTINUE_SEARCH; 11647 } 11648 11649 //----------------------------------------------------------------------------------------------------------------- 11650 11651 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]) //-V2008 11652 { 11653 $6 assert (what); 11654 $ assert (size >= 0); //-V547 11655 assert (exc); if (!exc) {$ return 0; } //-V547 11656 $ assert (func); 11657 11658 $ unsigned code = exc->ExceptionCode; 11659 $ void* addr = exc->ExceptionAddress; 11660 $ unsigned params = exc->NumberParameters; 11661 $ const ULONG_PTR* info = exc->ExceptionInformation; 11662 $ void* object = (params >= 2)? (void*) info[1] : NULL; 11663 11664 $ char* s = what; 11665 11666 #define PRINT_(...) s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__) 11667 11668 $ const char* sCode = NULL; 11669 $ const char* sDescr = NULL; 11670 11671 #define GET_DESCR_(code, descr) case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; } 11672 11673 $ switch (code) 11674 { 11675 GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION, " " "Нарушение доступа к памяти.") 11676 GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION, " " "Недопустимая операция.") 11677 GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION, " " "Привилегированная операция.") 11678 GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "\a" "Выход за границы массива. Ставьте ассерты!") 11679 GET_DESCR_ (EXCEPTION_BREAKPOINT, "\a" "Достигнута точка останова. Удачи в отладке!") 11680 GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT, "\a" "Нарушение выравнивания данных.") 11681 GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION, "\a" "Обработчик исключения возвратил неверное значение.") 11682 GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR, "\a" "Невозможно загрузить нужную страницу памяти.") 11683 GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.") 11684 GET_DESCR_ (EXCEPTION_SINGLE_STEP, "\a" "Выполнена инструкция машинного кода. Одна штука.") 11685 GET_DESCR_ (EXCEPTION_STACK_OVERFLOW, "\a" "Ю-ху! Переполнение стека!") 11686 GET_DESCR_ (EXCEPTION_GUARD_PAGE, "\a" "Попытка доступа к защищенной странице памяти.") 11687 GET_DESCR_ (EXCEPTION_INVALID_HANDLE, "\a" "Неверный или уже закрытый дескриптор.") 11688 GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK, "\a" "Возможно, взаимная блокировка ресурсов.") 11689 11690 GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK, "\a" "Ошибка стека при операции с плавающей точкой.") 11691 GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND, " " "Денормализация числа с плавающей точкой.") 11692 GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO, " " "Деление на ноль при операции с плавающей точкой.") 11693 GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT, " " "Неточный результат при операции с плавающей точкой.") 11694 GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION, " " "Недопустимая операция с плавающей точкой.") 11695 GET_DESCR_ (EXCEPTION_FLT_OVERFLOW, " " "Переполнение при операции с плавающей точкой.") 11696 GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW, " " "Потеря значимости при операции с плавающей точкой.") 11697 GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS, " " "Множественные ошибки с плавающей точкой.") 11698 11699 GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO, "\a" "Целочисленное деление на ноль.") 11700 GET_DESCR_ (EXCEPTION_INT_OVERFLOW, "\a" "Переполнение при целочисленной операции.") 11701 11702 GET_DESCR_ (EXCEPTION_CLR_FAILURE, "\a" "Сбой среды исполнения (CLR).") 11703 GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN, "\a" "Переполнение стекового буфера!") 11704 GET_DESCR_ (STATUS_ASSERTION_FAILURE, "\a" "Сработал assert. На этот раз из ядра.") 11705 GET_DESCR_ (STATUS_WX86_BREAKPOINT, "\a" "Точка останова подсистемы эмуляции x86.") 11706 GET_DESCR_ (RPC_S_UNKNOWN_IF, "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).") 11707 GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE, "\a" "Сервер удаленного вызова процедур (RPC) недоступен.") 11708 GET_DESCR_ (DBG_TERMINATE_THREAD, "\a" "Отладчик завершил поток сознания.") 11709 GET_DESCR_ (DBG_TERMINATE_PROCESS, "\a" "Отладчик завершил процесс.") 11710 GET_DESCR_ (DBG_CONTROL_C, "\a" "Отладчик получил сигнал прерывания Control+C.") 11711 GET_DESCR_ (DBG_CONTROL_BREAK, "\a" "Отладчик получил сигнал прерывания Control+Break.") 11712 GET_DESCR_ (DBG_THREAD_NAME, " " "Отладчик получил указание дать потоку имя.") 11713 GET_DESCR_ (DBG_PRINTEXCEPTION_C, " " "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).") 11714 GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C, " " "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).") 11715 11716 GET_DESCR_ (EXCEPTION_CPP_MSC, " " "Исключение С++, вызванное оператором throw.") 11717 GET_DESCR_ (EXCEPTION_CPP_GCC, " " "Исключение С++, вызванное оператором throw.") 11718 GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND, " " "Исключение С++, вызванное во время раскрутки стека (rethrow?).") 11719 GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED, " " "Исключение С++, вызванное нарушением магии.") 11720 GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER, "\a" "Это скомпилилось под Билдер? O_O") 11721 GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI, "\a" "Это же С++. Как это вышло?") 11722 11723 default: $ break; 11724 } 11725 11726 #undef GET_DESCR_ 11727 11728 $ if (sDescr) 11729 { 11730 $ PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode); 11731 } 11732 else 11733 { 11734 $ PRINT_ ("\a#%ld: ", _txSENumber); 11735 $ s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 11736 GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 11737 s, (DWORD) (size - (s-what)), NULL) - 2; //-V202 11738 $ PRINT_ ("\r\r"); 11739 } 11740 11741 $ PRINT_ (" (0x%X) при выполнении кода по адресу", code); 11742 $ PRINT_ ((addr? " 0x%p" : " NULL"), addr); 11743 11744 $ Win32::SYMBOL_INFO* sym = NULL; 11745 $ Win32::IMAGEHLP_LINE64* line = NULL; 11746 11747 if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); } 11748 11749 $ if (sym && *sym->Name) PRINT_ (" в функции %s()", sym->Name); 11750 $ if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber); 11751 11752 $ if (code == EXCEPTION_ACCESS_VIOLATION || 11753 code == EXCEPTION_IN_PAGE_ERROR) 11754 { 11755 $ PRINT_ (". Попытка "); 11756 11757 $ unsigned long op = 0xBADC0DE; 11758 $ const char* sOp = "(действие не указано)"; 11759 11760 $ if (params >= 1) 11761 { 11762 $ switch (op = (unsigned long) info[0]) //-V202 11763 { 11764 case 0: $ sOp = "прочесть данные"; break; 11765 case 1: $ sOp = "записать данные"; break; 11766 case 8: $ sOp = "исполнить код"; break; 11767 default: $ sOp = "совершить операцию 0x%lX"; break; 11768 } 11769 } 11770 11771 $ PRINT_ (sOp, op); 11772 11773 $ if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); } //-V1048 11774 else {$ PRINT_ (" (адрес не указан)"); } 11775 11776 $ if (code == EXCEPTION_IN_PAGE_ERROR) 11777 { 11778 $ PRINT_ (", ошибка ввода-вывода:"); 11779 11780 $ if (params >= 3) 11781 { 11782 $ unsigned long ntstatus = (unsigned long) info[2]; //-V202 11783 11784 $ PRINT_ (" 0x%lX (", ntstatus); 11785 11786 $ s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 11787 GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 11788 s, (DWORD) (size - (s-what)), NULL) - 2; //-V202 11789 $ PRINT_ (")"); 11790 } 11791 else 11792 {$ PRINT_ (" (не указана)"); } 11793 } 11794 } 11795 11796 $ HMODULE module = NULL; 11797 $ _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module)); 11798 11799 $ if (module) 11800 { 11801 $ static char sModule [MAX_PATH] = ""; 11802 $ int ok = GetModuleFileName (module, sModule, sizeof (sModule)); 11803 11804 $ char* ext = (ok? strrchr (sModule, '.') : NULL); 11805 $ if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule)); 11806 11807 if (ok) {$ PRINT_ (" в модуле %s", sModule); } 11808 else {$ PRINT_ (" в модуле 0x%p", (void*) module); } 11809 } 11810 11811 $ PRINT_ ("."); 11812 11813 $ if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0) 11814 {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).", _TX_EXCEPTIONS_LIMIT+0); } 11815 11816 $ if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0) 11817 {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); } 11818 11819 $ PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func); 11820 11821 $ if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE) 11822 {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); } 11823 11824 $ if (exc->ExceptionRecord) 11825 { 11826 $ PRINT_ ("\n\n" "Причина:" "\n\n"); 11827 $ s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func); 11828 } 11829 11830 $ if (code == EXCEPTION_CPP_GCC || 11831 code == EXCEPTION_CPP_GCC_UNWIND || 11832 code == EXCEPTION_CPP_GCC_FORCED || 11833 code == EXCEPTION_CPP_MSC) 11834 { 11835 $ s += _txDumpExceptionCPP (s, size - (s-what), code, params, info); 11836 } 11837 11838 #undef PRINT_ 11839 11840 $ while (s > what && s[-1] == '\n') s--; 11841 $ if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n"); 11842 11843 $ return s - what; 11844 } 11845 11846 //----------------------------------------------------------------------------------------------------------------- 11847 11848 intptr_t _txDumpExceptionCPP (char what[], intptr_t size, 11849 unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/) 11850 { 11851 $6 assert (what); 11852 $ assert (size >= 0); //-V547 11853 11854 $ char* s = what; 11855 11856 $ switch (code) 11857 { 11858 #if defined (_GCC_VER) 11859 11860 case EXCEPTION_CPP_GCC: 11861 case EXCEPTION_CPP_GCC_UNWIND: 11862 case EXCEPTION_CPP_GCC_FORCED: 11863 { 11864 // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp 11865 // [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below 11866 // [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below 11867 // [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below 11868 // and figure above near ABI::__cxa_exception definition in this file 11869 11870 $ const std::type_info* type = NULL; 11871 $ void* object = NULL; 11872 11873 $ if (params >= 1) 11874 { 11875 $ _Unwind_Exception* unwind_exception = (_Unwind_Exception*) info[0]; 11876 $ ABI::__cxa_exception* cxa_exception = (ABI::__cxa_exception*) (unwind_exception + 1) - 1; 11877 11878 $ type = cxa_exception->exceptionType; 11879 $ object = cxa_exception + 1; 11880 } 11881 11882 $ s += _txDumpExceptionObj (s, size - (s-what), object, 0, type); 11883 } 11884 $ break; 11885 11886 case 0: // Not called within SEH chain 11887 { 11888 // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc 11889 // [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc 11890 11891 using namespace abi; 11892 11893 $ ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions; 11894 11895 $ if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1)) // Dependent exception, case B, see pic above 11896 { 11897 $ cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1; 11898 } 11899 11900 $ if (cxa_exception) 11901 { 11902 $ verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type()); 11903 11904 $ s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType); 11905 } 11906 } 11907 $ break; 11908 11909 #elif defined (_MSC_VER) 11910 11911 case EXCEPTION_CPP_MSC: 11912 { 11913 // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273 11914 // [2] http://www.openrce.org/articles/full_view/21 11915 // [3] http://www.openrce.org/articles/full_view/23 11916 // [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf 11917 11918 $ const std::type_info* type = NULL; 11919 $ void* object = (params >= 2)? (void*) info[1] : NULL; 11920 $ size_t szObj = 0; 11921 11922 $ if (params >= 3 && 11923 (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 || 11924 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 || 11925 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 || 11926 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1)) 11927 { 11928 $ auto throwInfo = (const Win32::ThrowInfo*) info[2]; 11929 11930 $ if (throwInfo && throwInfo->pCatchableTypeArray) 11931 { 11932 $ HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL; //-V112 11933 11934 #define RVA_(type, addr) ( (type) ((uintptr_t) module + (uintptr_t) (addr)) ) 11935 11936 $ const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray); 11937 $ const Win32::CatchableType* cType = RVA_(const Win32::CatchableType*, cArray->arrayOfCatchableTypes[0]); 11938 11939 $ type = RVA_(const std::type_info*, cType->pType); 11940 $ szObj = cType->sizeOrOffset; //-V101 11941 11942 #undef RVA_ 11943 } 11944 } 11945 11946 $ s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type); 11947 } 11948 break; 11949 11950 case 0: // Not called within SEH chain 11951 11952 // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC: 11953 // 11954 // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception. 11955 // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp 11956 // 11957 // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception. 11958 // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp 11959 // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp 11960 // and http://msdn.microsoft.com/en-us/library/ff730818.aspx. 11961 // 11962 // So _txDumpSE information should have been recorded during previous call. Now do nothing. 11963 11964 $ break; 11965 11966 #endif 11967 11968 default: 11969 $ txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code); 11970 $ break; 11971 } 11972 11973 $ while (s > what && s[-1] == '\n') s--; 11974 $ if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n"); 11975 11976 $ return (s - what); 11977 } 11978 11979 //----------------------------------------------------------------------------------------------------------------- 11980 11981 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type) //-V2008 11982 { 11983 $6 assert (what); 11984 $ assert (size > 0); //-V547 11985 11986 $ static char* s = NULL; s = what; 11987 $ static size_t szObj = 0; szObj = sizeObj; 11988 11989 #define PRINT_(...) s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__) 11990 11991 $ PRINT_ ("\n\n" "Объект исключения C++:"); 11992 11993 $ const char* mangledName = (type)? type->name() : NULL; 11994 11995 $ char* typeName = NULL; 11996 $ int err = 1; 11997 11998 #if defined (_GCC_VER) 11999 $ typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); 12000 #endif 12001 12002 $ const char* name = (!err && typeName)? typeName : mangledName; //-V560 12003 12004 $ if (name && 12005 (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >") == 0 || 12006 strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >") == 0)) 12007 {$ name = "std::string"; } 12008 12009 $ if (name && 12010 (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *") == 0 || 12011 strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 || 12012 strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*") == 0)) 12013 {$ name = "std::string*"; } 12014 12015 if (name) {$ PRINT_ (" %s", name); } 12016 12017 #if defined (_GCC_VER) 12018 $ free (typeName); 12019 #endif 12020 12021 $ err = 0; 12022 $ if (mangledName) 12023 { 12024 if (_txSetJmp()) 12025 { 12026 #define PRINT_VAL_(fmt, typ, ...) \ 12027 else if (*type == typeid ( typ )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \ 12028 else if (*type == typeid (const typ )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \ 12029 else if (*type == typeid ( typ* )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 12030 else if (*type == typeid (const typ* )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 12031 else if (*type == typeid ( typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 12032 else if (*type == typeid (const typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } 12033 #define NO_ 12034 12035 if (false) ; 12036 PRINT_VAL_ ("%s", char*, NO_) PRINT_VAL_ ('%c', unsigned char, NO_) PRINT_VAL_ (%s, bool, ? "true" : "false") //-V206 //-V517 12037 PRINT_VAL_ ( %d, int, NO_) PRINT_VAL_ ( %u, unsigned int, NO_) PRINT_VAL_ (%g, float, NO_) //-V206 12038 PRINT_VAL_ ( %hd, short, NO_) PRINT_VAL_ ( %hu, unsigned short, NO_) PRINT_VAL_ (%g, double, NO_) //-V206 12039 PRINT_VAL_ ( %ld, long, NO_) PRINT_VAL_ ( %lu, unsigned long, NO_) PRINT_VAL_ ('%c', char, NO_) //-V206 12040 PRINT_VAL_ ("%s", std::string, .c_str()) //-V206 12041 12042 else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object)) 12043 { 12044 $ PRINT_ (", what(): \"%s\"", e->what()); 12045 } 12046 else 12047 {$ err = 1; } 12048 } 12049 else 12050 {$ err = 2; } 12051 } 12052 12053 $ _txClearJmp(); 12054 12055 $ if (err && object && szObj) 12056 { 12057 $ const unsigned char* buf = (const unsigned char*) object; 12058 12059 $ if (szObj >= 64) szObj = 64; 12060 12061 $ PRINT_ (", дамп: ["); 12062 $ for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' ); 12063 12064 $ PRINT_ ("]"); 12065 $ for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]); 12066 12067 $ err = 0; 12068 } 12069 12070 $ if (err) 12071 {$ PRINT_ (" = ??"); } 12072 12073 $ PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object); //-V560 12074 12075 #undef PRINT_VAL_ 12076 #undef PRINT_ 12077 #undef NO_ 12078 12079 $ return s - what; 12080 } 12081 12082 #endif // TX_COMPILED 12083 12084 //} 12085 //----------------------------------------------------------------------------------------------------------------- 12086 12087 //----------------------------------------------------------------------------------------------------------------- 12088 //{ Stack trace and debug info access 12089 //----------------------------------------------------------------------------------------------------------------- 12090 12091 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 12092 12093 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/, 12094 CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/, 12095 HANDLE thread /*= GetCurrentThread()*/) 12096 { 12097 $6 const int maxFrames = 62; // MS says: < 63 12098 $ static char trace [(MAX_PATH + 1024+1) * maxFrames] = ""; 12099 12100 if (framesToSkip == -1) {$ return trace; } 12101 12102 $ static void* capture [maxFrames] = {}; 12103 $ int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread); 12104 12105 $ memset (trace, 0, sizeof (trace)); 12106 $ char* s = trace; 12107 12108 $ bool haveSrcInfo = false; 12109 12110 #define PRINT_(...) s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__) 12111 12112 $ for (int i = 0, n = 0; i < frames; i++) //-V2530 12113 { 12114 $ void* addr = capture[i]; 12115 12116 $ Win32::SYMBOL_INFO* sym = NULL; 12117 $ Win32::IMAGEHLP_LINE64* line = NULL; 12118 $ const char* module = NULL; 12119 $ const char* source = NULL; 12120 $ bool inTX = false; 12121 12122 if (addr) {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module); } 12123 if (readSource && !inTX) {$ _txSymGetFromAddr ((void*) 1, NULL, NULL, NULL, &source, 2); } //-V566 12124 12125 $ int nl = 0; 12126 $ while (s > trace && s[-1] == '\n') { s--; nl++; } 12127 12128 #if !defined (_TX_FULL_STACKTRACE) 12129 12130 $ if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber)))) 12131 {$ continue; } 12132 12133 #endif 12134 12135 $ PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr); 12136 $ n++; 12137 12138 if (addr == 0) {$ PRINT_ (" [Неверный фрейм]"); break; } 12139 if (addr == (void*) -1) {$ PRINT_ (" [Странный фрейм]"); break; } 12140 if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; } //-V566 12141 12142 if (module) {$ PRINT_ (" in %s%s", module, ((sym && *sym->Name)? ": " : "")); } 12143 if (sym && *sym->Name) {$ PRINT_ ("%s()", sym->Name); } 12144 if (line && line->FileName) {$ PRINT_ (" at %s", line->FileName); haveSrcInfo = true; } 12145 if (line && line->LineNumber) {$ PRINT_ (":%d", (int) line->LineNumber); haveSrcInfo = true; } 12146 if (source) {$ PRINT_ (":\n\n" "%s\n", source); } 12147 12148 if (sym && strcmp (sym->Name , "main") == 0) {$ break; } 12149 } 12150 12151 $ while (s > trace && s[-1] == '\n') s--; 12152 $ *s = 0; 12153 12154 $ int bits = sizeof (void*) * CHAR_BIT; 12155 if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ ("TXLib отмечает: Не загрузилась библиотека "); } 12156 if (!Win32::SymSetOptions) {$ PRINT_ ("DbgHelp%d.dll или DbgHelp.dll", bits); } 12157 if ( !Win32::MinGW::SymSetOptions) {$ PRINT_ ("MgwHelp%d.dll или MgwHelp.dll", bits); } 12158 if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ (". Отладочная информация недоступна :(\n"); } 12159 12160 $ while (s > trace && s[-1] == '\n') s--; 12161 $ *s = 0; 12162 12163 $ if (!haveSrcInfo) 12164 {$ PRINT_ ("\n\n" "TXLib печалится: Нет информации об исходных файлах. Вы не забыли опцию -g при компиляции?"); } 12165 12166 #if defined (_MSC_VER) 12167 #pragma warning (push) 12168 #pragma warning (disable: 28199) // Using possibly uninitialized memory '*s' 12169 #endif 12170 12171 $ while (s > trace && s[-1] == '\n') s--; 12172 $ *s = 0; 12173 12174 #if defined (_MSC_VER) 12175 #pragma warning (pop) // Using possibly uninitialized memory '*s' 12176 #endif 12177 12178 #undef PRINT_ 12179 12180 $ s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), ""); 12181 12182 #if !defined (_TX_NO_MINIDUMP) 12183 $ _txCreateMiniDump (exc); 12184 #endif 12185 12186 $ return trace; 12187 } 12188 12189 //----------------------------------------------------------------------------------------------------------------- 12190 12191 // Stack WALKING if the program is DEAD. Dead, Carl! 12192 12193 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/, 12194 HANDLE thread /* = GetCurrentThread()*/) 12195 { 12196 $6 namespace MinGW = Win32::MinGW; 12197 12198 $ assert (capture); 12199 12200 $ HANDLE process = GetCurrentProcess(); 12201 $ bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId()); 12202 12203 $ CONTEXT ctx = {}; 12204 $ ctx.ContextFlags |= CONTEXT_FULL; 12205 12206 $ int isWow64 = 0; 12207 $ if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64); 12208 else {$ return -1; } 12209 12210 $ if (context) 12211 { 12212 $ ctx = *context; 12213 } 12214 else 12215 { 12216 $ if (thisThread) 12217 { 12218 $ _TX_CALLv (Win32::RtlCaptureContext, (&ctx)); 12219 } 12220 else 12221 { 12222 $ SuspendThread (thread); //-V720 12223 12224 $ ctx.ContextFlags = CONTEXT_ALL; 12225 $ bool ok = !!GetThreadContext (thread, &ctx); 12226 12227 $ if (!ok) 12228 { 12229 $ ResumeThread (thread); 12230 $ return -1; 12231 } 12232 } 12233 } 12234 12235 $ Win32::STACKFRAME64 frame = {}; 12236 $ frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat; 12237 12238 $ int cpu = 0; 12239 12240 #if defined (_WIN64) 12241 12242 $ if (isWow64) 12243 { 12244 $ Win32::WOW64_CONTEXT wow64ctx = {}; 12245 $ wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL; 12246 12247 $ if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx))) // This call fails in WINE, 12248 { // while EXIT_PROCESS_DEBUG_EVENT 12249 if (!thisThread) {$ ResumeThread (thread); } 12250 $ return 0; 12251 } 12252 12253 $ cpu = IMAGE_FILE_MACHINE_I386; 12254 12255 $ frame.AddrPC .Offset = wow64ctx.Eip; 12256 $ frame.AddrStack.Offset = wow64ctx.Esp; 12257 $ frame.AddrFrame.Offset = wow64ctx.Ebp; 12258 } 12259 else 12260 { 12261 $ cpu = IMAGE_FILE_MACHINE_AMD64; 12262 12263 $ frame.AddrPC .Offset = ctx.Rip; 12264 $ frame.AddrStack.Offset = ctx.Rbp; 12265 $ frame.AddrFrame.Offset = ctx.Rsp; 12266 } 12267 12268 #else 12269 12270 { 12271 $ cpu = IMAGE_FILE_MACHINE_I386; 12272 12273 $ frame.AddrPC .Offset = ctx.Eip; 12274 $ frame.AddrStack.Offset = ctx.Ebp; 12275 $ frame.AddrFrame.Offset = ctx.Esp; 12276 } 12277 12278 #endif 12279 12280 $ assert (cpu); 12281 12282 if (_txSetJmp()) 12283 { 12284 $ _txSymGetFromAddr ((void*) 1); //-V566 12285 } 12286 $ _txClearJmp(); 12287 12288 $ int frames = -1; 12289 12290 $ for (frames = -framesToSkip; frames < (int) szCapture; frames++) //-V202 //-V2530 12291 { 12292 $ DWORD64 prev = frame.AddrStack.Offset; 12293 12294 // Я злой и страшный серый walk. Я в поросятах знаю talk. 12295 12296 if (!_txSetJmp()) {$ break; } 12297 12298 #if defined (_GCC_VER) 12299 12300 if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL, 12301 MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; } 12302 #elif defined (_MSC_VER) 12303 12304 $ if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL, 12305 Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; } 12306 #else 12307 #error _GCC_VER / _MSC_VER not defined 12308 #endif 12309 if (frames < 0) {$ continue; } 12310 12311 $ void* addr = (void*) frame.AddrPC.Offset; 12312 12313 if (frame.AddrFrame.Offset == 0) {$ addr = 0; } // Bad frame 12314 if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; } // Strange frame 12315 12316 $ assert (0 <= frames && frames < (int) szCapture); //-V202 12317 12318 $ capture[frames] = addr; //-V108 12319 } 12320 12321 $ _txClearJmp(); 12322 12323 if (!thisThread) {$ ResumeThread (thread); } 12324 12325 $ return frames; 12326 } 12327 12328 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl 12329 12330 //----------------------------------------------------------------------------------------------------------------- 12331 12332 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/, 12333 Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/, 12334 const char** source /*= NULL*/, int context /*= 2*/) 12335 { 12336 $7 static HANDLE process = NULL; 12337 12338 #if defined (_GCC_VER) 12339 #define LIB_ Win32::MinGW 12340 12341 #elif defined (_MSC_VER) 12342 #define LIB_ Win32 12343 12344 #else 12345 #error _GCC_VER / _MSC_VER not defined 12346 #endif 12347 12348 $ if (!process && addr) 12349 { 12350 $ process = GetCurrentProcess(); 12351 12352 $ DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES | 12353 SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS; 12354 12355 $ _TX_CALL (LIB_::SymSetOptions, (options)); 12356 $ _TX_CALL (LIB_::SymInitialize, (process, NULL, true)); 12357 } 12358 12359 $ static DWORD64 mod = 0; 12360 12361 $ if (module) 12362 { 12363 $ static char sMod [MAX_PATH] = ""; 12364 $ memset (sMod, 0, sizeof (sMod)); 12365 12366 $ mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr)); 12367 12368 $ GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH); 12369 12370 $ char* ext = strrchr (sMod, '.'); 12371 if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); } 12372 12373 $ *module = sMod; 12374 } 12375 12376 $ static char buffer [_TX_BUFSIZE] = ""; 12377 $ static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer; //-V1032 12378 12379 $ if (symbol) 12380 { 12381 $ memset (buffer, 0, sizeof (buffer)); 12382 12383 $ sym->MaxNameLen = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1; 12384 $ sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO); 12385 $ unsigned long long ofs = 0; 12386 12387 $ _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym)); 12388 12389 if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; } 12390 12391 $ *symbol = sym; 12392 } 12393 12394 $ static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line64) }; 12395 12396 $ if (line) 12397 { 12398 $ memset (&line64, 0, sizeof (line64)); 12399 12400 $ DWORD ofs = 0; 12401 $ _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64)); 12402 12403 $ *line = &line64; 12404 } 12405 12406 $ if (source) 12407 { 12408 $ static char buf [_TX_BUFSIZE] = ""; 12409 $ memset (buf, 0, sizeof (buf)); 12410 12411 $ if (line64.FileName && line64.LineNumber) 12412 { 12413 $ _txReadSource (buf, sizeof (buf) - 1, line64.FileName, 12414 (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber); 12415 12416 $ *source = buf; 12417 } 12418 12419 if (!*source || !**source) {$ *source = NULL; } 12420 } 12421 12422 $ if (!addr && process) 12423 { 12424 $ _TX_CALL (LIB_::SymCleanup, (process)); 12425 12426 $ process = NULL; 12427 } 12428 12429 #if (_GCC_VER == 481) 12430 #pragma GCC diagnostic push 12431 #pragma GCC system_header 12432 #endif 12433 12434 $ if (symbol) 12435 { 12436 $ if (strstr (sym->Name, "::TX::") || 12437 (strncmp (sym->Name, "_tx", 3) == 0 && isupper ((unsigned char) sym->Name[3])) || 12438 (strncmp (sym->Name, "tx", 2) == 0 && isupper ((unsigned char) sym->Name[2])) || 12439 strncmp (sym->Name, "_tx_", 4) == 0 || //-V112 12440 strncmp (sym->Name, "tx_", 3) == 0) 12441 { 12442 $ return true; 12443 } 12444 12445 #if (_GCC_VER == 481) 12446 #pragma GCC diagnostic pop 12447 #endif 12448 12449 $ if (!line || !line64.FileName) return false; 12450 12451 $ intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1); 12452 12453 $ return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) && 12454 (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\'); 12455 } 12456 12457 #undef LIB_ 12458 12459 $ return false; 12460 } 12461 12462 //----------------------------------------------------------------------------------------------------------------- 12463 12464 intptr_t _txReadSource (char buf[], intptr_t size, const char file[], 12465 int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/) 12466 { 12467 $7 assert (buf); 12468 12469 if (!file || !*file) {$ return 0; } 12470 12471 if (linStart < 1) {$ linStart = 1; } 12472 if (linEnd == -1) {$ linEnd = INT_MAX; } 12473 12474 $ FILE* f = NULL; 12475 $ fopen_s (&f, file, "r"); 12476 if (!f) {$ return 0; } 12477 12478 $ int n = 1; 12479 while (!feof (f)) 12480 { 12481 if (n >= linStart) {$ break; } 12482 while (!feof (f) && fgetc (f) != '\n') 12483 ; 12484 n++; 12485 } 12486 12487 $ char* s = buf; 12488 12489 #define SZ_ ( size - 3 - (s - buf) ) 12490 12491 $ while (!feof (f) && SZ_ > 0) 12492 { 12493 if (n > linEnd || _txNOP (SZ_) < 0) {$ break; } 12494 12495 if (linMark != INT_MIN) 12496 {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : " "), n); } 12497 12498 $ int c = 0; 12499 $ while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c; 12500 if (c == EOF) {$ s--; } 12501 12502 if (SZ_ > 0) {$ *s++ = '\n'; } 12503 $ n++; 12504 } 12505 12506 if (n <= linEnd && SZ_ <= 0) 12507 {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); } 12508 12509 #undef SZ_ 12510 12511 $ fclose (f); 12512 12513 if (s > buf && s[-1] == '\n') {$ s--; } 12514 $ *s = 0; 12515 12516 $ return (s - buf); 12517 } 12518 12519 //----------------------------------------------------------------------------------------------------------------- 12520 12521 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/) 12522 { 12523 $6 const int maxFrames = 62; // TX says too: < 63 12524 $ static char trace [(MAX_PATH + 1024+1) * maxFrames] = ""; 12525 12526 if (framesToSkip == -1) {$ return trace; } 12527 12528 $ memset (trace, 0, sizeof (trace)); 12529 $ char* s = trace; 12530 12531 #define SZ_ ( sizeof (trace) - 1 - 3 - (s-trace) ) 12532 12533 $ const _txLoc* loc = &_txLoc::Cur; 12534 12535 for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; } 12536 12537 $ for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev) 12538 { 12539 if (i < 0) {$ continue; } 12540 12541 if (loc->func || loc->file || loc->line) 12542 { 12543 $ s += _tx_snprintf_s (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""), 12544 i, loc->func, loc->file, loc->line); 12545 12546 $ if (readSource) 12547 { 12548 $ s += _tx_snprintf_s (s, SZ_, ":\n\n"); 12549 $ s += _txReadSource (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line); 12550 } 12551 } 12552 } 12553 12554 #undef SZ_ 12555 12556 $ s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), ""); 12557 12558 $ return trace; 12559 } 12560 12561 //----------------------------------------------------------------------------------------------------------------- 12562 12563 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/) 12564 { 12565 $6 static char dumpName[MAX_PATH] = ""; 12566 if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); } 12567 12568 $ HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 12569 12570 if (!file || file == INVALID_HANDLE_VALUE) {$ return false; } 12571 12572 $ Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false }; 12573 $ Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory); 12574 12575 $ bool ok = _TX_CALL (Win32::MiniDumpWriteDump, (GetCurrentProcess(), GetCurrentProcessId(), file, type, 12576 ((exc)? &excInfo : NULL), NULL, NULL)); 12577 $ CloseHandle (file); 12578 12579 if (ok) {$ return true; } 12580 else {$ return false; } 12581 } 12582 12583 #endif // TX_COMPILED 12584 12585 //} 12586 //----------------------------------------------------------------------------------------------------------------- 12587 12588 //----------------------------------------------------------------------------------------------------------------- 12589 //{ Errors reporting 12590 //----------------------------------------------------------------------------------------------------------------- 12591 12592 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 12593 12594 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args) //-V2008 12595 { 12596 _txErrors = _txErrors + 1; 12597 12598 DWORD winErr = GetLastError(); 12599 12600 int crtErr = errno; 12601 12602 #if !defined (__CYGWIN__) 12603 unsigned long dosErr = _doserrno; 12604 #else 12605 unsigned long dosErr = 0; 12606 #endif 12607 12608 unsigned dlgErr = _TX_CALL (Win32::CommDlgExtendedError, ()); 12609 12610 unsigned oglErr = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError; 12611 12612 unsigned threadId = GetCurrentThreadId(); 12613 12614 enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 }; 12615 unsigned options = 0; 12616 12617 for (; msg && *msg; msg++) 12618 { 12619 if (*msg == '\a') options |= isFatal; 12620 else if (*msg == '\v') options |= isWarning; 12621 else if (*msg == '\b') options |= noMsgBox; 12622 else if (*msg == '\f') options |= fmtOnly; 12623 else if (*msg == '\t') options |= traceSE; 12624 else break; 12625 } 12626 12627 const char* stkTrace = NULL; 12628 const char* txTrace = NULL; (void) txTrace; 12629 12630 if (!(options & fmtOnly)) 12631 { 12632 stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace (2, true); 12633 txTrace = _txCaptureStackBackTraceTX (0, true); 12634 } 12635 12636 static char what[_TX_BIGBUFSIZE*10] = ""; 12637 static char str [_TX_BIGBUFSIZE] = ""; 12638 char *s = what; 12639 12640 #define PRINT_(...) s += _tx_snprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__) 12641 #define VPRINT_(...) s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__) 12642 12643 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" : 12644 (options & isFatal)? "соболезнует..." : 12645 "сообщает:")); 12646 PRINT_ ("Программа: %s", txGetModuleFileName()); 12647 if (file) PRINT_ (", файл: %s", file); 12648 if (line) PRINT_ (", строка: %d", line); 12649 if (func) PRINT_ (", функция: %s", func); 12650 PRINT_ (",\n\n"); 12651 12652 if (msg) PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"), 12653 VPRINT_ (msg, args); 12654 12655 while (s > what && s[-1] == '\n') s--; 12656 12657 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s", 12658 12659 _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64, 12660 12661 "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace, 12662 12663 threadId, (threadId == _txMainThreadId)? " (Main)" : 12664 (threadId == _txCanvas_ThreadId)? " (Canvas)" : ""); 12665 12666 if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr), 12667 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 12668 NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 12669 s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2, //-V202 12670 s -= (s[-1] == '.')? 1 : 0, 12671 PRINT_ (")"); 12672 12673 if (crtErr) PRINT_ (", errno: %d (%s)", crtErr, (strerror_s (str, sizeof (str), crtErr), str)); 12674 if (dosErr) PRINT_ (", _doserrno: %lu (%s)", dosErr, (strerror_s (str, sizeof (str), dosErr), str)); 12675 if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)", oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr))); 12676 if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr); 12677 12678 #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L) 12679 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : ""); 12680 #else 12681 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true." : ""); 12682 #endif 12683 12684 if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) && 12685 (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func)) 12686 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func); 12687 12688 txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what); 12689 12690 if (options & fmtOnly) 12691 { 12692 SetLastError (winErr); 12693 12694 errno = crtErr; 12695 12696 #if !defined (__CYGWIN__) 12697 _doserrno = dosErr; 12698 #endif 12699 12700 return what; 12701 } 12702 12703 txSetProgress (-1, Win32::TBPF_ERROR); 12704 12705 unsigned restore = txGetConsoleAttr(); 12706 txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED); 12707 if (color) {$ txSetConsoleAttr (color); } 12708 12709 int oldCodePage = txSetLocale(); 12710 12711 fprintf (stderr, "\n" "--------------------------------------------------\n" 12712 "%s\n" 12713 "--------------------------------------------------\n", 12714 what); 12715 12716 if (stkTrace && strstr (stkTrace, ".exe: ")) 12717 {$ fprintf (stderr, "Стек вызовов:\n\n" 12718 "%s\n\n" 12719 "--------------------------------------------------\n", 12720 stkTrace); } 12721 12722 SetConsoleOutputCP (oldCodePage); 12723 txSetConsoleAttr (restore); 12724 12725 if (*_txLogName) do //-V2530 12726 { 12727 FILE* log = NULL; fopen_s (&log, _txLogName, "a"); 12728 if (!log) {$ break; } 12729 12730 fprintf (log, "\n" "--------------------------------------------------\n" 12731 "%s\n" 12732 "--------------------------------------------------\n", 12733 what); 12734 12735 fprintf (log, "Стек вызовов:\n\n" //-V576 12736 "%s\n", 12737 (*_txTraceSE)? _txTraceSE : stkTrace); 12738 12739 #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG) 12740 12741 if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace) 12742 { 12743 fprintf (log, "\n" "--------------------------------------------------\n" 12744 "Стек вызовов TX:\n\n" 12745 "%s\n", 12746 txTrace); 12747 } 12748 12749 #endif 12750 12751 fprintf (log, "\n" "--------------------------------------------------\n" 12752 "%s\n\n" 12753 "--------------------------------------------------\n", 12754 _txAppInfo()); 12755 fclose (log); 12756 break; 12757 } 12758 while (false); 12759 12760 txSleep(); 12761 12762 int ret = 0; 12763 12764 if (!(options & noMsgBox)) 12765 { 12766 txSleep (_txWindowUpdateInterval); 12767 12768 PRINT_ ("\n" "Прервать программу?"); 12769 12770 ret = txMessageBox (what, ((options & isWarning)? "Предупреждение" : 12771 (options & isFatal)? "Фатальная ошибка" : 12772 "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL); 12773 } 12774 12775 SetLastError (winErr); 12776 12777 errno = crtErr; 12778 12779 #if !defined (__CYGWIN__) 12780 _doserrno = dosErr; 12781 #endif 12782 12783 if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES) 12784 { 12785 txUnlock(); 12786 _txCleanup(); 12787 Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 12788 } 12789 12790 #undef PRINT_ 12791 #undef VPRINT_ 12792 12793 return what; 12794 } 12795 12796 //----------------------------------------------------------------------------------------------------------------- 12797 12798 #if defined (_MSC_VER) 12799 12800 int _txOnErrorReport (int type, const char* text, int* ret) 12801 { 12802 assert (text); 12803 assert (ret); 12804 12805 _txErrors = _txErrors + 1; 12806 12807 unsigned restore = txGetConsoleAttr(); 12808 12809 switch (type) 12810 { 12811 case _CRT_WARN: txSetConsoleAttr (FOREGROUND_LIGHTRED); break; 12812 case _CRT_ERROR: txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break; 12813 case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW); break; 12814 default: break; //-V2522 12815 } 12816 12817 const char startReport[] = "Detected memory leaks!\n", 12818 endReport[] = "Object dump complete.\n"; 12819 12820 if (strcmp (text, startReport) == 0) // Dirty, dirty hack. А что делать? 12821 { 12822 _txOnErrorReport (type, "\n", NULL); 12823 _txOnErrorReport (type, _TX_VERSION " - ERROR: ", NULL); 12824 _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL); 12825 _txOnErrorReport (type, "\n", NULL); 12826 } 12827 12828 size_t len = strlen (text); 12829 if (text [len-1] != '\n') txOutputDebugPrintf ("%s", text); 12830 else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION); 12831 else txOutputDebugPrintf ("%s\n", text); 12832 12833 DWORD n = 0; 12834 HANDLE err = GetStdHandle (STD_ERROR_HANDLE); 12835 WriteFile (err, text, (DWORD) strlen (text), &n, NULL); //-V202 12836 12837 txSetConsoleAttr (restore); 12838 12839 if (*_txLogName) do //-V2530 12840 { 12841 HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 12842 if (log == INVALID_HANDLE_VALUE) break; 12843 12844 SetFilePointer (log, 0, NULL, FILE_END); 12845 WriteFile (log, text, (DWORD) strlen (text), &n, NULL); //-V202 12846 12847 CloseHandle (log); 12848 break; 12849 } 12850 while (false); 12851 12852 if (ret) *ret = 0; 12853 12854 return (type == _CRT_WARN); 12855 } 12856 12857 #endif 12858 12859 //----------------------------------------------------------------------------------------------------------------- 12860 12861 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/) 12862 { 12863 $5 static wchar_t textW [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]"; 12864 $ static wchar_t headerW [_TX_BUFSIZE * sizeof (wchar_t)] = L"[NULL header]"; 12865 12866 if (text) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text, -1, textW, sizearr (textW)) || memset (textW, 0, sizeof (textW)); } 12867 if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); } 12868 12869 $ txSleep(); 12870 12871 $ HWND wnd = _txCanvas_Window; 12872 $ int ret = MessageBoxW ((wnd && IsWindowVisible (wnd))? wnd : _TX_CALL (Win32::GetConsoleWindow,()), 12873 textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST); 12874 12875 $ GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU); 12876 12877 $ if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU)) 12878 { 12879 $ SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0); 12880 $ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT); 12881 } 12882 12883 $ return ret; 12884 } 12885 12886 //----------------------------------------------------------------------------------------------------------------- 12887 12888 bool txGetAsyncKeyState (int key) 12889 { 12890 $1 HWND wnd = GetForegroundWindow(); 12891 12892 return (GetAsyncKeyState (key) & 0x8000) && 12893 (wnd == txWindow() || wnd == Win32::GetConsoleWindow()); 12894 } 12895 12896 //----------------------------------------------------------------------------------------------------------------- 12897 12898 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...) 12899 { 12900 $5 if (_TX_ARGUMENT_FAILED (format)) return false; 12901 12902 $ va_list arg; va_start (arg, format); 12903 $ bool ok = true; 12904 12905 #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500) 12906 12907 $ NOTIFYICONDATA nid = { sizeof (nid) }; 12908 12909 $ nid.uFlags = NIF_ICON | NIF_TIP | NIF_INFO; 12910 $ nid.hWnd = NULL; 12911 $ nid.uID = 1; 12912 $ nid.hIcon = _txCreateTXIcon (16); assert (nid.hIcon); 12913 $ strncpy_s (nid.szTip, sizeof (nid.szTip), "TXLib Information", sizeof (nid.szTip)); 12914 $ strncpy_s (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1); 12915 $ _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg); 12916 $ nid.dwInfoFlags = flags; 12917 12918 $ txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo); 12919 12920 $ ok &= !!Shell_NotifyIcon (NIM_ADD, (::NOTIFYICONDATA*) &nid); 12921 $ ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid); 12922 12923 $ if (nid.hIcon) DestroyIcon (nid.hIcon) asserted; 12924 12925 #else 12926 12927 $ char nid_szInfo[_TX_BUFSIZE] = ""; 12928 $ _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg); 12929 $ txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo); 12930 $ ok = false; 12931 12932 $ (void)flags; (void)title; 12933 12934 #endif 12935 12936 $ va_end (arg); 12937 return ok; 12938 } 12939 12940 //----------------------------------------------------------------------------------------------------------------- 12941 12942 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...) 12943 { 12944 unsigned id = GetCurrentThreadId(); 12945 12946 const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}}; 12947 12948 char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)]; 12949 12950 char msgStr[_TX_BUFSIZE] = ""; 12951 if (msg) 12952 { 12953 va_list arg; va_start (arg, msg); 12954 _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg); 12955 va_end (arg); 12956 } 12957 12958 txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d) " "|%*s%s" "%s%s\n", 12959 12960 _TX_VERSION, (void*) &_txInitialized, 12961 12962 "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], 12963 _txLoc::Cur.trace, mark, 12964 12965 (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line, 12966 2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""), 12967 12968 ((*msgStr && func)? ": " : ""), msgStr); 12969 } 12970 12971 //----------------------------------------------------------------------------------------------------------------- 12972 12973 int txOutputDebugPrintf (const char* format, ...) 12974 { 12975 if (!format) return 0; 12976 12977 enum { msgbox = 1, print = 2, compr = 4 }; 12978 int options = 0; 12979 12980 for (; format && *format; format++) 12981 { 12982 if (*format == '\a') options |= msgbox; 12983 else if (*format == '\f') options |= print; 12984 else if (*format == '\r') options |= compr; 12985 else break; 12986 } 12987 12988 char text[_TX_BIGBUFSIZE] = ""; 12989 12990 va_list arg; va_start (arg, format); 12991 int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg); //-V202 12992 va_end (arg); 12993 12994 struct __ { static int trimSpaces (char str[]) 12995 { 12996 char *dst = str, *src = str; 12997 12998 for (char d = ' '; d; src++) 12999 if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; } 13000 else *dst++ = d = *src; 13001 13002 return (int) (dst - str - 1); //-V202 13003 }}; 13004 13005 if (options & compr) n = __::trimSpaces (text); 13006 13007 OutputDebugString (text); 13008 13009 if (options & print) fprintf (stderr, "%s", text); 13010 13011 if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION); 13012 13013 return n; 13014 } 13015 13016 //----------------------------------------------------------------------------------------------------------------- 13017 13018 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...) 13019 { 13020 if (!format) return 0; 13021 13022 va_list arg; va_start (arg, format); 13023 intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg); 13024 va_end (arg); 13025 13026 return ret; 13027 } 13028 13029 //----------------------------------------------------------------------------------------------------------------- 13030 13031 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg) 13032 { 13033 if (!stream || !format) return 0; 13034 13035 #if defined (_TRUNCATE) 13036 intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg); 13037 #else 13038 intptr_t ret = _vsnprintf (stream, size, format, arg); 13039 #endif 13040 13041 if (ret < 0 && size >= 4) //-V112 13042 { 13043 const char ellipsis[] = "..."; 13044 size_t szEllipsis = sizeof (ellipsis) - 1; 13045 13046 strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis); 13047 } 13048 13049 return (ret >= 0)? ret : size; 13050 } 13051 13052 //----------------------------------------------------------------------------------------------------------------- 13053 13054 #if defined (__CYGWIN__) 13055 13056 int _getch() 13057 { 13058 termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr); 13059 13060 termios newattr = oldattr; 13061 newattr.c_lflag &= ~(ICANON | ECHO); 13062 tcsetattr (STDIN_FILENO, TCSANOW, &newattr); 13063 13064 int ch = getchar(); 13065 13066 tcsetattr (STDIN_FILENO, TCSANOW, &oldattr); 13067 13068 return ch; 13069 } 13070 13071 //----------------------------------------------------------------------------------------------------------------- 13072 13073 int _putch (int ch) 13074 { 13075 termios old = {}; tcgetattr (STDOUT_FILENO, &old); 13076 13077 termios cur = old; 13078 cur.c_lflag &= ~ICANON; 13079 cur.c_lflag |= ECHO; 13080 tcsetattr (STDOUT_FILENO, TCSANOW, &cur); 13081 13082 putchar (ch); 13083 13084 tcsetattr (STDOUT_FILENO, TCSANOW, &old); 13085 13086 return ch; 13087 } 13088 13089 //----------------------------------------------------------------------------------------------------------------- 13090 13091 int _kbhit() 13092 { 13093 termios old = {}; tcgetattr (STDIN_FILENO, &old); 13094 13095 termios cur = old; 13096 cur.c_lflag &= ~(ICANON | ECHO); 13097 cur.c_cc[VMIN] = 1; 13098 cur.c_cc[VTIME] = 0; 13099 13100 tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur); 13101 13102 fd_set fd = {}; FD_SET (STDIN_FILENO, &fd); 13103 timeval tv = {}; 13104 13105 int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd); 13106 13107 tcsetattr (STDIN_FILENO, TCSAFLUSH, &old); 13108 13109 return res; 13110 } 13111 13112 #endif 13113 13114 #endif // TX_COMPILED 13115 13116 //} 13117 //----------------------------------------------------------------------------------------------------------------- 13118 13119 //----------------------------------------------------------------------------------------------------------------- 13120 //{ Information 13121 //----------------------------------------------------------------------------------------------------------------- 13122 13123 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 13124 13125 const char* txGetModuleFileName (bool fileNameOnly /*= true*/) 13126 { 13127 static char name[MAX_PATH] = ""; 13128 13129 if (!*name) 13130 { 13131 if (!GetModuleFileName (NULL, name, sizeof (name) - 1)) *name = 0; 13132 13133 char* ext = strrchr (name, '.'); 13134 if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name)); 13135 } 13136 13137 assert (*name); 13138 13139 if (fileNameOnly) return name; 13140 13141 static char fullName[MAX_PATH] = ""; 13142 strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1); 13143 13144 char* title = strrchr (fullName, '\\'); if (!title) title = fullName; 13145 char* ext = strrchr (fullName, '.'); if (!ext) ext = fullName + strlen (fullName); 13146 13147 size_t sz = sizeof (fullName) - (ext - fullName); 13148 strncpy_s (ext, sz-1, " - TXLib", sz); 13149 13150 return title + 1; 13151 } 13152 13153 #endif // TX_COMPILED 13154 13155 //----------------------------------------------------------------------------------------------------------------- 13156 13157 inline const char* _txAppInfo() 13158 { 13159 $1 time_t timeT = time (NULL) - clock()/CLOCKS_PER_SEC; //-V104 13160 char timeS[32] = ""; 13161 ctime_s (timeS, sizeof (timeS), &timeT); 13162 13163 static char text[_TX_BUFSIZE] = ""; 13164 char cwd [MAX_PATH] = ""; 13165 13166 _tx_snprintf_s (text, sizeof (text) - 1, 13167 13168 "Developed with:\n\n" 13169 "The Dumb Artist Library (TX Library)\n" 13170 _TX_VERSION "\n" _TX_AUTHOR "\n" 13171 "See license on: http://txlib.ru\n\n" 13172 13173 "TXLib file:" "\t" __FILE__ "\n" 13174 "Compiled:" "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n" 13175 "Started:" "\t" "%.6s %.4s %.8s\n\n" 13176 13177 "Run file:" "\t" "%s\n" 13178 "Directory:" "\t" "%s", 13179 13180 #if defined (_MSC_VER) 13181 "MSVC Runtime", 13182 #elif defined (__CYGWIN__) 13183 "Cygwin Runtime", 13184 #elif defined (_GCC_VER) && defined (_WIN64) 13185 __mingw_get_crt_info(), 13186 #else 13187 "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION), 13188 #endif 13189 (sizeof (void*) == sizeof (DWORD))? 32 : 64, //-V112 13190 13191 timeS + 4, timeS + 20, timeS + 11, //-V112 These offsets are ANSI standardized 13192 txGetModuleFileName(), 13193 _getcwd (cwd, sizeof (cwd) - 1)); 13194 13195 return text; 13196 } 13197 13198 //} 13199 //----------------------------------------------------------------------------------------------------------------- 13200 13202 //} 13203 //================================================================================================================= 13204 13205 //================================================================================================================= 13206 //{ TXLib API implementation 13207 // Реализация TXLib API 13208 //================================================================================================================= 13209 13210 inline const char* txVersion() 13211 { 13212 return _TX_VERSION; 13213 } 13214 13215 //----------------------------------------------------------------------------------------------------------------- 13216 13217 inline unsigned txVersionNumber() 13218 { 13219 return _TX_VER; //-V2517 13220 } 13221 13222 //----------------------------------------------------------------------------------------------------------------- 13223 13224 inline HWND txWindow() 13225 { 13226 $9 return _txCanvas_Window; 13227 } 13228 13229 //----------------------------------------------------------------------------------------------------------------- 13230 13231 inline HDC& txDC() 13232 { 13233 return _txCanvas_BackBuf[0]; 13234 } 13235 13236 //----------------------------------------------------------------------------------------------------------------- 13237 13238 inline RGBQUAD* txVideoMemory() 13239 { 13240 return _txCanvas_Pixels; 13241 } 13242 13243 //----------------------------------------------------------------------------------------------------------------- 13244 13245 inline int txGetExtentX (HDC dc /*= txDC()*/) 13246 { 13247 return txGetExtent (dc) .x; 13248 } 13249 13250 //----------------------------------------------------------------------------------------------------------------- 13251 13252 inline int txGetExtentY (HDC dc /*= txDC()*/) 13253 { 13254 return txGetExtent (dc) .y; 13255 } 13256 13257 //----------------------------------------------------------------------------------------------------------------- 13258 13259 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 13260 13261 POINT txGetExtent (HDC dc /*= txDC()*/) 13262 { 13263 $0 static POINT err = {-1, -1}; 13264 13265 if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; }; 13266 13267 if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; } 13268 13269 $ BITMAP bmap = {}; 13270 $ txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted; 13271 13272 $ POINT size = { bmap.bmWidth, bmap.bmHeight }; 13273 $ return size; 13274 } 13275 13276 //----------------------------------------------------------------------------------------------------------------- 13277 13278 bool txDestroyWindow (HWND wnd /*= txWindow()*/) 13279 { 13280 $1 if (!wnd || !txWindow()) return false; 13281 13282 $ if (wnd != txWindow()) 13283 { 13284 $ return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd); 13285 } 13286 13287 $ if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false; 13288 13289 $ if (_txMain) 13290 { 13291 $ txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n" 13292 "Возвращайтесь через main(), там вам будут рады.\n"); 13293 $ Sleep (_TX_TIMEOUT); 13294 } 13295 13296 $ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT); 13297 13298 $ return _txCanvas_Window == NULL; 13299 } 13300 13301 //----------------------------------------------------------------------------------------------------------------- 13302 13303 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/) 13304 { 13305 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13306 13307 $ HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color); 13308 13309 $ if (!pen) return (HPEN) NULL; 13310 13311 $ if (!_txBuffer_Select (pen, dc)) 13312 { 13313 $ Win32::DeleteObject (pen); 13314 $ return (HPEN) NULL; 13315 } 13316 13317 $ if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID) 13318 {$ return (HPEN) NULL; } 13319 13320 $ return pen; 13321 } 13322 13323 //----------------------------------------------------------------------------------------------------------------- 13324 13325 COLORREF txColor (double red, double green, double blue) 13326 { 13327 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13328 $ if (green > 1) green = 1; if (green < 0) green = 0; 13329 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13330 13331 $ COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)); 13332 13333 $ return txSetColor (color)? color : CLR_INVALID; 13334 } 13335 13336 //----------------------------------------------------------------------------------------------------------------- 13337 13338 COLORREF txGetColor (HDC dc /*= txDC()*/) 13339 { 13340 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13341 13342 $ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc); 13343 $ assert (obj); if (!obj) return CLR_INVALID; //-V547 13344 13345 $ union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {}; //-V2514 13346 13347 $ int size = Win32::GetObject (obj, 0, NULL); 13348 $ Win32::GetObject (obj, sizeof (buf), &buf) asserted; 13349 13350 $ return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor; 13351 } 13352 13353 //----------------------------------------------------------------------------------------------------------------- 13354 13355 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/) 13356 { 13357 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13358 13359 $ HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color); 13360 13361 $ return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL); 13362 } 13363 13364 //----------------------------------------------------------------------------------------------------------------- 13365 13366 COLORREF txFillColor (double red, double green, double blue) 13367 { 13368 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13369 $ if (green > 1) green = 1; if (green < 0) green = 0; 13370 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13371 13372 $ COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)); 13373 13374 $ return txSetFillColor (color)? color : CLR_INVALID; 13375 } 13376 13377 //----------------------------------------------------------------------------------------------------------------- 13378 13379 COLORREF txGetFillColor (HDC dc /*= txDC()*/) 13380 { 13381 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13382 13383 $ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc); 13384 $ assert (obj); if (!obj) return CLR_INVALID; //-V547 13385 13386 $ LOGBRUSH buf = {}; 13387 $ txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted; 13388 13389 $ return buf.lbColor; 13390 } 13391 13392 //----------------------------------------------------------------------------------------------------------------- 13393 13394 bool txClear (HDC dc /*= txDC()*/) 13395 { 13396 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13397 13398 $ POINT size = txGetExtent (dc); 13399 $ return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc); 13400 } 13401 13402 //----------------------------------------------------------------------------------------------------------------- 13403 13404 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/) 13405 { 13406 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13407 13408 $ txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc); 13409 13410 $ return true; 13411 } 13412 13413 //----------------------------------------------------------------------------------------------------------------- 13414 13415 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/) 13416 { 13417 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13418 $ if (green > 1) green = 1; if (green < 0) green = 0; 13419 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13420 13421 $ return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc); 13422 } 13423 13424 //----------------------------------------------------------------------------------------------------------------- 13425 13426 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/) 13427 { 13428 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13429 13430 $ return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc); 13431 } 13432 13433 //----------------------------------------------------------------------------------------------------------------- 13434 13435 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13436 { 13437 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13438 13439 $ bool ok = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc); 13440 $ ok &= txGDI ((Win32::LineTo (dc, ROUND (x1), ROUND (y1) )), dc); 13441 13442 $ return ok; 13443 } 13444 13445 //----------------------------------------------------------------------------------------------------------------- 13446 13447 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13448 { 13449 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13450 13451 $ return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc); 13452 } 13453 13454 //----------------------------------------------------------------------------------------------------------------- 13455 13456 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/) 13457 { 13458 $1 if (_TX_ARGUMENT_FAILED (points)) return false; 13459 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13460 13461 $ return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc); 13462 } 13463 13464 //----------------------------------------------------------------------------------------------------------------- 13465 13466 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13467 { 13468 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13469 13470 $ return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc); 13471 } 13472 13473 //----------------------------------------------------------------------------------------------------------------- 13474 13475 bool txCircle (double x, double y, double r) 13476 { 13477 $1 return txEllipse (x-r, y-r, x+r, y+r); 13478 } 13479 13480 //----------------------------------------------------------------------------------------------------------------- 13481 13482 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13483 { 13484 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13485 13486 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13487 13488 $ double start = startAngle * txPI/180, 13489 end = (startAngle + totalAngle) * txPI/180; 13490 13491 $ return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13492 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13493 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13494 } 13495 13496 //----------------------------------------------------------------------------------------------------------------- 13497 13498 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13499 { 13500 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13501 13502 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13503 13504 $ double start = startAngle * txPI/180, 13505 end = (startAngle + totalAngle) * txPI/180; 13506 13507 $ return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13508 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13509 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13510 } 13511 13512 //----------------------------------------------------------------------------------------------------------------- 13513 13514 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13515 { 13516 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13517 13518 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13519 13520 $ double start = startAngle * txPI/180, 13521 end = (startAngle + totalAngle) * txPI/180; 13522 13523 $ return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13524 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13525 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13526 } 13527 13528 //----------------------------------------------------------------------------------------------------------------- 13529 13530 bool txFloodFill (double x, double y, 13531 COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/) 13532 { 13533 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13534 13535 $ if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc); 13536 13537 $ return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc); 13538 } 13539 13540 //----------------------------------------------------------------------------------------------------------------- 13541 13542 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/) 13543 { 13544 $1 if (_TX_ARGUMENT_FAILED (text)) return false; 13545 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13546 13547 $ int len = (int) strlen (text); //-V202 13548 $ bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc); 13549 13550 $ return ok; 13551 } 13552 13553 //----------------------------------------------------------------------------------------------------------------- 13554 13555 bool txDrawText (double x0, double y0, double x1, double y1, const char text[], 13556 unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/, 13557 HDC dc /*= txDC()*/) 13558 { 13559 $1 if (_TX_ARGUMENT_FAILED (text)) return false; 13560 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13561 13562 #if !defined (NDEBUG) 13563 13564 $ if (x0 > x1) 13565 { 13566 $ SetLastError (ERROR_INVALID_DATA); 13567 $ TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1); 13568 } 13569 13570 $ if (y0 > y1) 13571 { 13572 $ SetLastError (ERROR_INVALID_DATA); 13573 $ TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1); 13574 } 13575 13576 #endif 13577 13578 $ RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) }; 13579 13580 $ if (!strchr (text, '\n')) format |= DT_SINGLELINE; 13581 13582 $ unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc); 13583 13584 $ bool ok = false; 13585 13586 $ if (Win32::DrawText) 13587 { 13588 $ ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc); 13589 $ Win32::GetPixel (dc, 0, 0); 13590 $ ok = true; //-V519 13591 } 13592 else 13593 { 13594 $ txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text); 13595 $ ok = false; 13596 } 13597 13598 $ txSetTextAlign (prev, dc); 13599 13600 $ return ok; 13601 } 13602 13603 //----------------------------------------------------------------------------------------------------------------- 13604 13605 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/, 13606 int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/, 13607 bool strikeout /*= false*/, double angle /*= 0*/, 13608 HDC dc /*= txDC()*/) 13609 { 13610 $1 if (_TX_ARGUMENT_FAILED (name)) return NULL; 13611 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13612 13613 $ HFONT font = txFontExist (name)? 13614 Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3), 13615 ROUND (angle*10), 0, bold, italic, underline, strikeout, 13616 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 13617 DEFAULT_QUALITY, DEFAULT_PITCH, name) 13618 : 13619 (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT); 13620 13621 $ _txBuffer_Select (font, dc); 13622 13623 $ return font; 13624 } 13625 13626 //----------------------------------------------------------------------------------------------------------------- 13627 13628 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/) 13629 { 13630 $1 SIZE size = {-1, -1}; 13631 13632 $ if (_TX_ARGUMENT_FAILED (text)) return size; 13633 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return size; 13634 13635 $ size_t len = strlen (text); 13636 $ txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted; //-V202 13637 13638 $ return size; 13639 } 13640 13641 //----------------------------------------------------------------------------------------------------------------- 13642 13643 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/) 13644 { 13645 $1 return txGetTextExtent (text, dc) .cx; 13646 } 13647 13648 //----------------------------------------------------------------------------------------------------------------- 13649 13650 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/) 13651 { 13652 $1 return txGetTextExtent (text, dc) .cy; 13653 } 13654 13655 //----------------------------------------------------------------------------------------------------------------- 13656 13657 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/) 13658 { 13659 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; //-V601 13660 13661 $ return txGDI ((Win32::SetTextAlign (dc, align)), dc); 13662 } 13663 13664 //----------------------------------------------------------------------------------------------------------------- 13665 13666 LOGFONT* txFontExist (const char name[]) 13667 { 13668 $1 if (_TX_ARGUMENT_FAILED (name)) return NULL; 13669 13670 $ static LOGFONT font = {}; 13671 $ font.lfCharSet = DEFAULT_CHARSET; 13672 $ strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1); 13673 13674 $ struct tools 13675 { 13676 static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data) 13677 { 13678 $ if (_TX_ARGUMENT_FAILED (fnt)) return 0; 13679 $ if (_TX_ARGUMENT_FAILED (data)) return 0; 13680 13681 #ifndef __STRICT_ANSI__ 13682 $ return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE); 13683 13684 #else 13685 $ return strncmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE); 13686 13687 #endif 13688 } 13689 }; 13690 13691 $ return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL; 13692 } 13693 13694 //----------------------------------------------------------------------------------------------------------------- 13695 13696 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/) 13697 { 13698 $1 if (_TX_ARGUMENT_FAILED (obj)) return false; 13699 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13700 13701 $ return _txBuffer_Select (obj, dc); 13702 } 13703 13704 //----------------------------------------------------------------------------------------------------------------- 13705 13706 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/) 13707 { 13708 $1 POINT size = { ROUND (sizeX), ROUND (sizeY) }; 13709 13710 $ HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels); 13711 $ assert (dc); if (!dc) return NULL; //-V547 13712 13713 $ txSetDefaults (dc); 13714 13715 $ if (!_txCanvas_UserDCs) return dc; 13716 13717 $ txAutoLock _lock; 13718 $ _txCanvas_UserDCs->push_back (dc); 13719 13720 $ if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE) 13721 {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); } //-V202 13722 13723 $ return dc; 13724 } 13725 13726 //----------------------------------------------------------------------------------------------------------------- 13727 13728 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/) 13729 { 13730 $1 return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels); 13731 } 13732 13733 //----------------------------------------------------------------------------------------------------------------- 13734 13735 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) 13736 { 13737 $1 return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels); 13738 } 13739 13740 //----------------------------------------------------------------------------------------------------------------- 13741 13742 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/, 13743 unsigned imageFlags /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/) 13744 { 13745 $1 if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL; 13746 13747 $ HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL), 13748 filename, imageFlags, sizeX, sizeY, loadFlags); 13749 $ if (!image) return NULL; 13750 13751 $ HDC dc = txCreateCompatibleDC (sizeX, sizeY, image); 13752 13753 $ if (!(loadFlags & LR_LOADFROMFILE)) return dc; 13754 13755 $ static std::map <std::string, unsigned> loadTimes; 13756 $ std::string file = filename; 13757 $ unsigned time = GetTickCount(); 13758 13759 $ if ((long) (time - loadTimes [file]) < _TX_TIMEOUT) 13760 {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); } 13761 13762 $ loadTimes [file] = time; 13763 13764 $ return dc; 13765 } 13766 13767 //----------------------------------------------------------------------------------------------------------------- 13768 13769 bool txDeleteDC (HDC* pdc) 13770 { 13771 $1 if (_TX_ARGUMENT_FAILED (pdc)) return false; 13772 13773 $ HDC dc = *pdc; 13774 $ bool ok = _txBuffer_Delete (pdc); 13775 $ if (!ok) return false; 13776 13777 $ if (!_txCanvas_UserDCs) return ok; 13778 13779 $ txAutoLock _lock; 13780 13781 $ for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it) 13782 if (*it == dc) 13783 { 13784 $ std::swap (*it, _txCanvas_UserDCs->back()); 13785 $ _txCanvas_UserDCs->pop_back(); 13786 $ break; 13787 } 13788 13789 $ return ok; 13790 } 13791 13792 //----------------------------------------------------------------------------------------------------------------- 13793 13794 bool txDeleteDC (HDC dc) 13795 { 13796 $1 return txDeleteDC (&dc); 13797 } 13798 13799 //----------------------------------------------------------------------------------------------------------------- 13800 13801 bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height, 13802 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/) 13803 { 13804 $1 if (_TX_HDC_FAILED (destImage)) return false; 13805 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13806 13807 $ POINT size = txGetExtent (sourceImage); 13808 $ if (!width) width = size.x; //-V550 13809 $ if (!height) height = size.y; //-V550 13810 13811 $ return txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13812 sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage); 13813 } 13814 13815 //----------------------------------------------------------------------------------------------------------------- 13816 13817 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/) 13818 { 13819 $1 if (_TX_TXWINDOW_FAILED()) return false; 13820 13821 $ return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource); 13822 } 13823 13824 //----------------------------------------------------------------------------------------------------------------- 13825 13826 bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height, 13827 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/) 13828 { 13829 // Это проверки того, правильные ли HDC вы передали в функцию. 13830 // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а. 13831 // При первом чтении это можно пропустить. 13832 13833 $1 if (_TX_HDC_FAILED (destImage)) return false; 13834 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13835 13836 // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent(). 13837 // При первом чтении это можно пропустить. 13838 13839 $ POINT size = txGetExtent (sourceImage); 13840 $ if (!width) width = size.x; //-V550 13841 $ if (!height) height = size.y; //-V550 13842 13843 // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest). 13844 // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только 13845 // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки). 13846 // При первом чтении это можно пропустить. 13847 13848 #if !defined (NDEBUG) 13849 13850 $ if (!(0 <= xSource && xSource + width <= size.x && 13851 0 <= ySource && ySource + height <= size.y)) 13852 { 13853 $ SetLastError (ERROR_INVALID_DATA); 13854 $ TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, " 13855 "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y); 13856 } 13857 13858 #endif 13859 13860 $ bool ok = true; 13861 13862 $ if (Win32::TransparentBlt) 13863 { 13864 // А вот теперь уже надо начать читать. 13865 // 13866 // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function" 13867 // и почитайте про ее параметры. 13868 // 13869 // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не 13870 // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что 13871 // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s> 13872 // это сделано для упрощения вызова функции TransparentBlt(). 13873 13874 // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки! // <<-- 13875 // // <<-- 13876 // ||||| |||||| // <<-- 13877 // vvvvv vvvvvv // <<-- 13878 // <<-- 13879 $ ok &= txGDI (!!(Win32::TransparentBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), // <<<< 13880 sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<< 13881 destImage); // <<-- 13882 // ^^^^^ ^^^^^^ // <<-- 13883 // ||||| |||||| // <<-- 13884 // // <<-- 13885 } // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте! // <<-- 13886 else 13887 { 13888 $ ok &= txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13889 sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)), 13890 destImage); 13891 } 13892 13893 // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что 13894 // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s> 13895 // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL 13896 // или DirectX, будет круто. Хотя это и сложнее.</s> 13897 13898 // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами, 13899 // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :(( 13900 13901 $ return ok; 13902 } 13903 13904 //----------------------------------------------------------------------------------------------------------------- 13905 13906 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage, 13907 COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/) 13908 { 13909 $1 if (_TX_TXWINDOW_FAILED()) return false; 13910 13911 $ return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor); 13912 } 13913 13914 //----------------------------------------------------------------------------------------------------------------- 13915 13916 bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height, 13917 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/) 13918 { 13919 $1 if (_TX_HDC_FAILED (destImage)) return false; 13920 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13921 13922 $ POINT size = txGetExtent (sourceImage); 13923 $ if (!width) width = size.x; //-V550 13924 $ if (!height) height = size.y; //-V550 13925 13926 #if !defined (NDEBUG) 13927 13928 $ if (!(0 <= xSource && xSource + width <= size.x && 13929 0 <= ySource && ySource + height <= size.y)) 13930 { 13931 $ SetLastError (ERROR_INVALID_DATA); 13932 $ TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, " 13933 "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y); 13934 } 13935 13936 #endif 13937 13938 $ if (alpha < 0) alpha = 0; 13939 $ if (alpha > 1) alpha = 1; 13940 13941 $ BITMAP bmap = { 0, 0, 0, 0, 0, 24 }; 13942 $ bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap); 13943 13944 $ BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) }; //-V112 //-V821 //-V2551 13945 13946 $ if (Win32::AlphaBlend) 13947 { 13948 $ ok &= txGDI (!!(Win32::AlphaBlend (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13949 sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)), 13950 destImage); 13951 } 13952 else 13953 { 13954 $ ok &= txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13955 sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)), 13956 destImage); 13957 $ ok = false; //-V519 13958 } 13959 13960 $ return ok; 13961 } 13962 13963 //----------------------------------------------------------------------------------------------------------------- 13964 13965 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage, 13966 double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/) 13967 { 13968 $1 if (_TX_TXWINDOW_FAILED()) return false; 13969 13970 $ return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha); 13971 } 13972 13973 //----------------------------------------------------------------------------------------------------------------- 13974 13975 HDC txUseAlpha (HDC image) 13976 { 13977 $1 if (_TX_HDC_FAILED (image)) return NULL; 13978 13979 $ HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP); 13980 $ if (!bitmap) return NULL; 13981 13982 $ DIBSECTION dib = {}; 13983 $ Win32::GetObject (bitmap, sizeof (dib), &dib) asserted; 13984 13985 $ POINT size = { dib.dsBm.bmWidth, dib.dsBm.bmHeight }; 13986 $ BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }}; 13987 $ RGBQUAD* buf = NULL; 13988 13989 $ bool isDIB = (dib.dsBm.bmPlanes == 1 && 13990 dib.dsBm.bmBitsPixel == sizeof (RGBQUAD) * 8 && 13991 dib.dsBmih.biCompression == DIB_RGB_COLORS && 13992 dib.dsBm.bmBits); 13993 $ if (!isDIB) 13994 { 13995 $ buf = new (std::nothrow) RGBQUAD [size.x * size.y]; //-V121 13996 $ if (!buf) return NULL; 13997 13998 $ Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted; 13999 } 14000 else 14001 { 14002 $ buf = (RGBQUAD*) dib.dsBm.bmBits; 14003 } 14004 14005 $ for (int y = 0; y < size.y; y++) 14006 for (int x = 0; x < size.x; x++) 14007 { 14008 RGBQUAD* color = &buf [x + y * size.x]; // Get color at (x, y) within image buffer //-V108 14009 14010 color->rgbRed = (BYTE) ROUND (color->rgbRed * color->rgbReserved / 255.0); 14011 color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0); 14012 color->rgbBlue = (BYTE) ROUND (color->rgbBlue * color->rgbReserved / 255.0); 14013 } 14014 14015 $ if (!isDIB) 14016 { 14017 $ Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted; 14018 14019 $ delete[] buf; 14020 } 14021 14022 $ return image; 14023 } 14024 14025 //----------------------------------------------------------------------------------------------------------------- 14026 14027 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/) 14028 { 14029 $1 if (_TX_ARGUMENT_FAILED (filename)) return false; 14030 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 14031 14032 $ POINT size = txGetExtent (dc); 14033 14034 $ size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), //-V119 14035 szImg = (size.x * size.y) * sizeof (RGBQUAD); //-V104 14036 14037 $ BITMAP bmap = {}; 14038 $ BITMAPFILEHEADER hdr = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs }; //-V202 14039 $ BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }; 14040 14041 $ RGBQUAD* buf = NULL; 14042 $ bool ok = true; 14043 14044 $ ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap); 14045 14046 if (!ok) {$ return false; } 14047 14048 $ if (!bmap.bmBits) 14049 { 14050 $ buf = new (std::nothrow) RGBQUAD [size.x * size.y]; //-V121 14051 $ ok &= (buf != NULL); 14052 14053 $ int res = Win32::GetDIBits (dc, (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y, 14054 buf, (BITMAPINFO*) &info, DIB_RGB_COLORS); 14055 14056 if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); } 14057 14058 $ ok &= !!res; 14059 } 14060 else 14061 { 14062 $ buf = (RGBQUAD*) bmap.bmBits; 14063 } 14064 14065 $ FILE* f = NULL; 14066 $ if (ok) fopen_s (&f, filename, "wb"); 14067 $ ok &= (f != NULL); 14068 14069 $ if (ok) ok &= (fwrite (&hdr, sizeof (hdr), 1, f) == 1); //-V575 //-V595 14070 $ if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1); 14071 $ if (ok) ok &= (fwrite (buf, szImg, 1, f) == 1); //-V575 14072 14073 $ ok &= (f && fclose (f) == 0); 14074 14075 $ if (!bmap.bmBits) 14076 { 14077 $ delete[] buf; 14078 $ buf = NULL; 14079 } 14080 14081 $ return ok; 14082 } 14083 14084 //----------------------------------------------------------------------------------------------------------------- 14085 14086 double txSleep (double time) 14087 { 14088 $1 LARGE_INTEGER start = {}; 14089 $ QueryPerformanceCounter (&start) asserted; 14090 14091 $ LARGE_INTEGER freq = {}; 14092 $ QueryPerformanceFrequency (&freq) asserted; 14093 14094 $ int lock = _txCanvas_RefreshLock; 14095 $ _txCanvas_RefreshLock = 0; 14096 14097 $ HWND wnd = txWindow(); 14098 if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); } 14099 14100 $ Sleep (ROUND ((time >= 0)? time : 0)); 14101 14102 $ _txCanvas_RefreshLock = lock; 14103 14104 $ LARGE_INTEGER stop = {}; 14105 $ QueryPerformanceCounter (&stop) asserted; 14106 14107 $ return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart; 14108 } 14109 14110 //----------------------------------------------------------------------------------------------------------------- 14111 14112 bool txLock (bool wait /*= true*/) 14113 { 14114 $0 if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0); 14115 14116 $ if (wait) {$ return EnterCriticalSection (&_txCanvas_LockBackBuf), true; } //-V1048 14117 else {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf); } 14118 } 14119 14120 //----------------------------------------------------------------------------------------------------------------- 14121 14122 bool txUnlock() 14123 { 14124 $0 LeaveCriticalSection (&_txCanvas_LockBackBuf); 14125 14126 $ if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0); 14127 $ return false; 14128 } 14129 14130 #endif // TX_COMPILED 14131 14132 //----------------------------------------------------------------------------------------------------------------- 14133 14134 template <typename T> 14135 inline T txUnlock (T value) 14136 { 14137 $1 txUnlock(); 14138 $ return value; 14139 } 14140 14141 //----------------------------------------------------------------------------------------------------------------- 14142 14143 inline void txRedrawWindow() 14144 { 14145 $1 txSleep (0); 14146 } 14147 14148 //----------------------------------------------------------------------------------------------------------------- 14149 14150 inline int txUpdateWindow (int update /*= true*/) 14151 { 14152 $1 return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update); 14153 } 14154 14155 //----------------------------------------------------------------------------------------------------------------- 14156 14157 inline int txBegin() 14158 { 14159 $1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1); 14160 14161 $ return _txCanvas_RefreshLock; 14162 } 14163 14164 //----------------------------------------------------------------------------------------------------------------- 14165 14166 inline int txEnd() 14167 { 14168 $1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1); 14169 14170 $ return _txCanvas_RefreshLock; 14171 } 14172 14173 //----------------------------------------------------------------------------------------------------------------- 14174 14175 inline POINT txMousePos() 14176 { 14177 $1 POINT pos = {}; 14178 $ GetCursorPos (&pos); 14179 14180 $ if (txWindow()) 14181 {$ ScreenToClient (txWindow(), &pos); } 14182 14183 $ return pos; 14184 } 14185 14186 //----------------------------------------------------------------------------------------------------------------- 14187 14188 inline double txMouseX() 14189 { 14190 return (double) txMousePos() .x; 14191 } 14192 14193 //----------------------------------------------------------------------------------------------------------------- 14194 14195 inline double txMouseY() 14196 { 14197 return (double) txMousePos() .y; 14198 } 14199 14200 //----------------------------------------------------------------------------------------------------------------- 14201 14202 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 14203 14204 unsigned txMouseButtons() 14205 { 14206 $1 HWND txWnd = txWindow(); 14207 $ HWND foreground = GetForegroundWindow(); 14208 14209 $ if ((txWnd && (foreground == txWnd)) || 14210 (!txWnd && (foreground == Win32::GetConsoleWindow()))) 14211 { 14212 $ return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) | // MSB to bit 0 14213 ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) | // MSB to bit 1 14214 ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13); // MSB to bit 2 14215 } 14216 else 14217 {$ return 0; } 14218 } 14219 14220 //----------------------------------------------------------------------------------------------------------------- 14221 14222 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/) 14223 { 14224 unsigned oldAttr = txGetConsoleAttr(); 14225 14226 SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color); 14227 SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE), (WORD) color); 14228 14229 return oldAttr; 14230 } 14231 14232 //----------------------------------------------------------------------------------------------------------------- 14233 14234 unsigned txGetConsoleAttr() 14235 { 14236 CONSOLE_SCREEN_BUFFER_INFO con = {}; 14237 con.wAttributes = FOREGROUND_LIGHTGRAY; 14238 14239 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) || 14240 GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE), &con); 14241 14242 return con.wAttributes; 14243 } 14244 14245 //----------------------------------------------------------------------------------------------------------------- 14246 14247 POINT txSetConsoleCursorPos (double x, double y) 14248 { 14249 $1 POINT fontSz = txGetConsoleFontSize(); 14250 14251 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14252 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14253 14254 $ COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left), 14255 (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) }; 14256 14257 $ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted; 14258 14259 $ POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x), 14260 ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) }; 14261 $ return prev; 14262 } 14263 14264 //----------------------------------------------------------------------------------------------------------------- 14265 14266 POINT txGetConsoleCursorPos() 14267 { 14268 $1 POINT fontSz = txGetConsoleFontSize(); 14269 14270 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14271 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14272 14273 $ POINT pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x), 14274 ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) }; 14275 $ return pos; 14276 } 14277 14278 //----------------------------------------------------------------------------------------------------------------- 14279 14280 POINT txGetConsoleExtent() 14281 { 14282 $1 CONSOLE_SCREEN_BUFFER_INFO con = {}; 14283 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14284 14285 $ POINT size = { con.srWindow.Right - con.srWindow.Left + 1, 14286 con.srWindow.Bottom - con.srWindow.Top + 1 }; 14287 $ return size; 14288 } 14289 14290 //----------------------------------------------------------------------------------------------------------------- 14291 14292 bool txClearConsole() 14293 { 14294 $1 HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 14295 14296 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14297 $ GetConsoleScreenBufferInfo (out, &con) asserted; 14298 14299 $ COORD start = {con.srWindow.Left, con.srWindow.Top}; 14300 14301 $ DWORD len = (con.srWindow.Right - con.srWindow.Left + 1) * 14302 (con.srWindow.Bottom - con.srWindow.Top + 1); 14303 14304 $ DWORD written = 0; 14305 $ FillConsoleOutputCharacter (out, 0x20 /*' '*/, len, start, &written) asserted; //-V112 14306 $ FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted; 14307 14308 $ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted; 14309 14310 $ return written == len; 14311 } 14312 14313 //----------------------------------------------------------------------------------------------------------------- 14314 14315 POINT txGetConsoleFontSize() 14316 { 14317 $1 Win32::CONSOLE_FONT_INFO font = {0, {8, 16}}; 14318 14319 $ _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font)); 14320 14321 $ SIZE size = { font.dwFontSize.X, font.dwFontSize.Y }; 14322 if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); } //-V501 14323 14324 if (size.cx == 0) {$ size.cx = 1; } 14325 if (size.cy == 0) {$ size.cy = 1; } 14326 14327 $ POINT sizeFont = { size.cx, size.cy }; 14328 $ return sizeFont; 14329 } 14330 14331 //----------------------------------------------------------------------------------------------------------------- 14332 14333 bool txTextCursor (bool blink /*= true*/) 14334 { 14335 $1 bool old = _txConsole_IsBlinking; 14336 14337 $ _txConsole_IsBlinking = blink; 14338 14339 $ return old; 14340 } 14341 14342 //----------------------------------------------------------------------------------------------------------------- 14343 14344 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/) 14345 { 14346 $1 mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT; 14347 $ if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC; 14348 14349 $ if (!filename) mode = SND_PURGE; 14350 14351 $ return !!Win32::PlaySound (filename, NULL, mode); 14352 } 14353 14354 //----------------------------------------------------------------------------------------------------------------- 14355 14356 int txSpeak (const char* text, ...) 14357 { 14358 $1 bool verbose = false; (void) verbose; 14359 $ bool async = false; (void) async; 14360 14361 $ for (; text && *text; text++) 14362 { 14363 if (*text == '\a') {$ async = true; } 14364 else if (*text == '\v') {$ verbose = true; } 14365 else break; 14366 } 14367 14368 $ char textA [_TX_BUFSIZE] = "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!"; 14369 14370 $ va_list arg; va_start (arg, text); 14371 if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); } 14372 $ va_end (arg); 14373 14374 if (text && verbose) {$ printf ("%s", textA); } 14375 14376 #ifdef TX_USE_SPEAK 14377 14378 $ int time = GetTickCount(); 14379 14380 $ static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L""; 14381 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW)); 14382 14383 $ static ISpVoice* voice = NULL; 14384 14385 $ if (text && !voice) 14386 { 14387 $ HRESULT res = Win32::CoInitialize (NULL); 14388 if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); } 14389 } 14390 14391 $ if (text && voice) 14392 { 14393 $ Win32::_fpreset(); 14394 $ voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL); 14395 $ tx_fpreset(); 14396 } 14397 14398 $ if (!text && voice) 14399 { 14400 $ voice->Release(); 14401 $ voice = NULL; 14402 14403 $ Win32::CoUninitialize(); 14404 } 14405 14406 $ return (voice)? GetTickCount() - time : -1; 14407 14408 #else 14409 14410 $ if (text) 14411 { 14412 $ unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK); 14413 14414 $ txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA); 14415 14416 $ txSetConsoleAttr (oldAttr); 14417 } 14418 14419 $ return -1; 14420 14421 #endif 14422 } 14423 14424 //----------------------------------------------------------------------------------------------------------------- 14425 14426 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[], 14427 double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/) 14428 { 14429 $1 if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1; 14430 14431 $ int time = GetTickCount(); //-V2551 14432 14433 $ static char processUID [64] = ""; 14434 if (!*processUID) 14435 { 14436 $ FILETIME startTime = {}, null = {}; 14437 $ GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted; 14438 $ _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo", 14439 (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted; 14440 } 14441 14442 $ if (!fileName) 14443 { 14444 $ _txTaskKill ("vlc.exe", processUID, 0); // Kill'em all, by command line pattern 14445 $ return 0; 14446 } 14447 14448 $ static const char* vlcPath = _txPlayVideo_FindVLC(); 14449 14450 $ if (!vlcPath || _access (vlcPath, 0) != 0) 14451 { 14452 $ static int once = false; //-V601 14453 14454 $ if (*fileName && !once++) 14455 {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org " 14456 "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n" 14457 "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n" 14458 "P.S. См. мое описание в TXLib Help."); } 14459 $ return INT_MIN; //-V109 14460 } 14461 14462 $ bool async = false; 14463 if (*fileName == '\a') {$ async = true; fileName++; } 14464 14465 $ RECT rect = {}; 14466 if (wnd) {$ GetClientRect (wnd, &rect); } 14467 14468 if (!width) {$ width = rect.right; } 14469 if (!height) {$ height = rect.bottom; } 14470 14471 // Create a child window to hold the video stream 14472 14473 $ const char* errPos = "ВНЕЗАПНО"; 14474 14475 $ volatile HWND child = NULL; 14476 $ if (wnd && (wnd == txWindow())) 14477 { 14478 $ const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1); 14479 14480 $ static int number = 1; 14481 $ CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x, 14482 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass }; 14483 $ child = txCreateExtraWindow (createData); 14484 $ if (!child) 14485 { 14486 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s", 14487 strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos)); 14488 $ return INT_MIN+3; //-V109 14489 } 14490 14491 $ BringWindowToTop (child); 14492 14493 $ wnd = child; 14494 } 14495 14496 // Build the command line 14497 14498 if (!zoom && !wnd) {$ zoom = 1; } 14499 14500 $ char sZoom [64] = "--autoscale"; 14501 if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; } //-V550 14502 14503 $ static char cmd [MAX_PATH*2 + 1024] = ""; 14504 14505 $ _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit" 14506 14507 " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s" 14508 14509 " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging" 14510 14511 " --ignore-config --reset-config --no-one-instance --play-and-exit" 14512 " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file" 14513 " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events", 14514 14515 vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted; 14516 14517 $ txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n", 14518 x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd); 14519 $ if (!*fileName) 14520 { 14521 if (child) {$ txDestroyWindow (child); } 14522 $ return (intptr_t) cmd; 14523 } 14524 14525 $ if (!strstr (fileName, "://") && _access (fileName, 0) != 0) 14526 { 14527 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s", 14528 strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos)); 14529 14530 if (child) {$ txDestroyWindow (child); } 14531 $ return INT_MIN+1; //-V109 14532 } 14533 14534 // Run VLC, run 14535 14536 $ PROCESS_INFORMATION vlc = {}; 14537 $ STARTUPINFO start = { sizeof (start) }; 14538 $ DWORD ret = 0; 14539 14540 $ if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) && 14541 vlc.hProcess && vlc.hThread) 14542 { 14543 $ if (child) 14544 { 14545 $ assert (wnd == child); //-V547 14546 $ SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess); //-V107 14547 } 14548 14549 $ if (!async) 14550 { 14551 $ WaitForSingleObject (vlc.hProcess, INFINITE); 14552 $ GetExitCodeProcess (vlc.hProcess, &ret) asserted; 14553 } 14554 14555 $ if (!child) 14556 { 14557 $ CloseHandle (vlc.hProcess) asserted; 14558 } 14559 14560 $ CloseHandle (vlc.hThread) asserted; 14561 14562 $ return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret); //-V105 14563 } 14564 else 14565 { 14566 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s", 14567 strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos)); 14568 $ if (child) 14569 {$ txDestroyWindow (child); } 14570 14571 $ return INT_MIN+4; //-V112 //-V109 14572 } 14573 14574 #undef PROCESS_UID_ 14575 } 14576 14577 //----------------------------------------------------------------------------------------------------------------- 14578 14579 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/) 14580 { 14581 $1 return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd); 14582 } 14583 14584 //----------------------------------------------------------------------------------------------------------------- 14585 14586 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) 14587 { 14588 const UINT_PTR checkTimer = 1; 14589 14590 switch (msg) 14591 { 14592 case WM_CREATE: 14593 { 14594 $1 SetTimer (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted; 14595 } 14596 break; 14597 14598 case WM_DESTROY: 14599 { 14600 $1 KillTimer (wnd, checkTimer) asserted; 14601 14602 $ HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA); 14603 14604 $ if (vlc) 14605 { 14606 $ Win32::TerminateProcess (vlc, 0); 14607 14608 $ CloseHandle (vlc) asserted; 14609 14610 $ SetWindowLongPtr (wnd, GWLP_USERDATA, 0); 14611 } 14612 } 14613 break; 14614 14615 case WM_TIMER: 14616 { 14617 HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA); 14618 14619 if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT) 14620 { 14621 $1 DestroyWindow (wnd) asserted; 14622 } 14623 } 14624 break; 14625 14626 default: //-V2522 14627 break; 14628 } 14629 14630 return DefWindowProc (wnd, msg, wpar, lpar); 14631 } 14632 14633 //----------------------------------------------------------------------------------------------------------------- 14634 14635 const char* _txPlayVideo_FindVLC() 14636 { 14637 $1 static char vlcPath [MAX_PATH] = ""; 14638 14639 $ if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL)) 14640 { 14641 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14642 } 14643 14644 $ if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL)) 14645 { 14646 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14647 } 14648 14649 $ if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath))) 14650 { 14651 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14652 } 14653 14654 $ if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath))) 14655 { 14656 $ strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX); 14657 14658 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14659 } 14660 14661 $ strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files" "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX); //-V106 14662 { 14663 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14664 } 14665 14666 $ strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX); //-V106 14667 { 14668 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14669 } 14670 14671 $ return NULL; 14672 } 14673 14674 //----------------------------------------------------------------------------------------------------------------- 14675 14676 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/) 14677 { 14678 $1 static double oldPercent = 100; 14679 14680 if (percent < 0) {$ percent = MIN (oldPercent, 100); } 14681 else {$ oldPercent = percent; } 14682 14683 $ HRESULT res = S_FALSE; 14684 14685 #if defined (__ITaskbarList3_INTERFACE_DEFINED__) 14686 14687 $ HRESULT init = Win32::CoInitialize (NULL); 14688 14689 $ bool ok = true; 14690 $ res = S_OK; 14691 14692 $ ITaskbarList3* taskbar = NULL; 14693 if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); } 14694 $ ok &= !!taskbar && (res == S_OK); 14695 14696 if (!wnd) {$ wnd = txWindow(); } 14697 if (ok && taskbar) {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); } 14698 if (ok && taskbar) {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type); ok &= (res == S_OK); } 14699 14700 if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); } 14701 if (ok && taskbar) {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); } 14702 if (ok && taskbar) {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type); ok &= (res == S_OK); } 14703 14704 if (taskbar) {$ taskbar->Release(); } 14705 14706 if (init == S_OK) {$ Win32::CoUninitialize(); } 14707 14708 #endif 14709 14710 (void) type; (void) wnd; 14711 14712 $ return res; 14713 } 14714 14715 #endif // TX_COMPILED 14716 14717 //----------------------------------------------------------------------------------------------------------------- 14718 14719 // +--<<< Это не те символы, что вы ищете :) 14720 // V Полезно смотреть не только вверх, но и вниз 14721 14722 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/) 14723 { 14724 $1 WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc; 14725 $ return old; 14726 } 14727 14728 //----------------------------------------------------------------------------------------------------------------- 14729 14730 // +--<<< А это, наконец, искомое определение этой функции. 14731 // | Смотрите по сторонам! Нужная вам функция где-то рядом. 14732 // | 14733 // v 14734 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture() 14735 { 14736 txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n" 14737 14738 "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n" 14739 14740 "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. " 14741 "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n" 14742 14743 "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом " 14744 "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n" 14745 14746 "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы " 14747 "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n", 14748 14749 "Не получилось", MB_ICONSTOP); 14750 14751 // The truth is out there... (C++files) 14752 14753 return false; 14754 } 14755 14756 //----------------------------------------------------------------------------------------------------------------- 14757 14758 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you. 14759 14760 inline bool txDisableAutoPause() 14761 { 14762 _txExit = true; 14763 return true; 14764 } 14765 14766 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword. 14767 14768 //----------------------------------------------------------------------------------------------------------------- 14769 14770 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 14771 14772 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/) 14773 { 14774 $1 assert (!_txIsBadReadPtr (address)); 14775 14776 $ const unsigned char* addr = (const unsigned char*) address; 14777 14778 $ const int stdout_fileno = 1; // Not all g++ packages contain STDOUT_FILENO 14779 $ const int _o_u16text = 0x00020000; // and _O_U16TEXT 14780 14781 $ bool istty = _txIsTTY (1); 14782 14783 $ int mode = _O_TEXT; 14784 $ int oldMode = _setmode (stdout_fileno, mode); 14785 14786 $ unsigned oldCP = GetConsoleOutputCP(); 14787 $ unsigned cp = 1251; SetConsoleOutputCP (cp); //-V581 14788 14789 $ unsigned attr = txGetConsoleAttr(); 14790 14791 $ txSetConsoleAttr (FOREGROUND_WHITE); 14792 $ printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : "")); 14793 14794 $ txSetConsoleAttr (FOREGROUND_YELLOW); 14795 $ for (unsigned x = 0; x < 16; x++) printf ("%02X ", x); 14796 $ for (unsigned x = 0; x < 16; x++) printf ("%X", x); 14797 14798 $ const wchar_t* xlat[33] = {L"\xB7" /* 00 - NUL - NULL */, L"\x263A" /* 01 - SOH - Start of header */, 14799 L"\x263B" /* 02 - STX - Start of text */, L"\x2665" /* 03 - ETX - End of text */, 14800 L"\x2666" /* 04 - EOT - End of transm. */, L"\x2663" /* 05 - ENQ - Enquiry */, 14801 L"\x2660" /* 06 - ACK - Acknowledgment */, L"\x2022" /* 07 - BEL - Bell */, 14802 L"\x25D8" /* 08 - BS - Backspace */, L"\x25CB" /* 09 - HT - Horizontal tab */, 14803 L"\x25D9" /* 10 - LF - Line feed */, L"\x2642" /* 11 - VT - Vertical tab */, 14804 L"\x2640" /* 12 - FF - Form feed */, L"\x266A" /* 13 - CR - Carriage return */, 14805 L"\x266B" /* 14 - SO - Shift out */, L"\x263C" /* 15 - SI - Shift in */, 14806 L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1 */, 14807 L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3 */, 14808 L"\xB6" /* 20 - DC4 - Device control 4 */, L"\xA7" /* 21 - NAK - Negative ACK */, 14809 L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */, 14810 L"\x2191" /* 24 - CAN - Cancel */, L"\x2193" /* 25 - EM - End of medium */, 14811 L"\x2192" /* 26 - SUB - Substitute */, L"\x2190" /* 27 - ESC - Escape */, 14812 L"\x221F" /* 28 - FS - File separator */, L"\x2194" /* 29 - GS - Group separator */, 14813 L"\x25B2" /* 30 - RS - Record separator */, L"\x25BC" /* 31 - US - Unit separator */, 14814 L"\x20" /* 32 - Space */}; 14815 14816 $ for (int y = 0; y < 16; y++, addr += 16) 14817 { 14818 if (cp != 1251) SetConsoleOutputCP (cp = 1251); //-V581 14819 (void)_setmode (stdout_fileno, mode = oldMode); 14820 14821 txSetConsoleAttr (FOREGROUND_YELLOW); 14822 14823 printf ("\n" "%*p ", (int) sizeof (address) * 2, addr); 14824 14825 int color = FOREGROUND_LIGHTGREEN; 14826 14827 for (unsigned x = 0; x < 16; x++) 14828 { 14829 txSetConsoleAttr (color + x/4%2); //-V112 14830 printf ("%02X ", addr[x]); 14831 } 14832 14833 for (unsigned x = 0; x < 16; x++) 14834 { 14835 txSetConsoleAttr (color + x/4%2); //-V112 14836 14837 unsigned char ch = addr[x]; 14838 14839 if (ch >= sizearr (xlat) || !istty) 14840 { 14841 if (cp != oldCP) SetConsoleOutputCP (cp = oldCP); //-V581 14842 if (mode != oldMode) (void)_setmode (stdout_fileno, mode = oldMode); 14843 14844 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' '); 14845 } 14846 else 14847 { 14848 if (cp != 1251) SetConsoleOutputCP (cp = 1251); //-V581 14849 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text); 14850 14851 wprintf (L"%lls", xlat[ch]); 14852 } 14853 } 14854 } 14855 14856 $ (void)_setmode (stdout_fileno, oldMode); 14857 $ printf ("\n"); 14858 14859 $ if (pause && istty) 14860 { 14861 $ txSetConsoleAttr (FOREGROUND_DARKGRAY); 14862 $ txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP); 14863 } 14864 14865 $ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 14866 $ printf ("\n"); 14867 14868 $ txSetConsoleAttr (attr); 14869 $ SetConsoleOutputCP (oldCP); 14870 } 14871 14872 //----------------------------------------------------------------------------------------------------------------- 14873 14874 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/, 14875 bool readSource /*= true*/) 14876 { 14877 $1 unsigned attr = txGetConsoleAttr(); 14878 $ txSetConsoleAttr (FOREGROUND_LIGHTCYAN); 14879 14880 $ fprintf (stderr, "\n" "--------------------------------------------------\n" 14881 "Трассировка стека из \"%s\" at %s:%d:\n\n" 14882 "%s\n\n" 14883 "--------------------------------------------------\n\n", 14884 func, file, line, _txCaptureStackBackTrace (1, readSource)); 14885 14886 $ txSetConsoleAttr (attr); 14887 } 14888 14889 //----------------------------------------------------------------------------------------------------------------- 14890 14891 char* txDemangle (const char* mangledName, std::nomeow_t) 14892 { 14893 $1 if (!mangledName) return NULL; 14894 14895 $ char* typeName = NULL; 14896 14897 #if defined (_GCC_VER) 14898 14899 $ int err = 1; 14900 $ typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err; 14901 if (typeName) {$ return typeName; } 14902 14903 #endif 14904 14905 $ unsigned short flags = 0; 14906 14907 $ if (mangledName[0] == '.') 14908 { 14909 $ mangledName++; 14910 $ flags = 0x2800; // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY 14911 } 14912 14913 $ typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags)); 14914 if (typeName) {$ return typeName; } 14915 14916 $ return _strdup (mangledName); 14917 } 14918 14919 //----------------------------------------------------------------------------------------------------------------- 14920 14921 std::string txDemangle (const char* mangledName) 14922 { 14923 $1 char* typeName = txDemangle (mangledName, std::nomeow); 14924 $ std::string name (typeName? typeName : ""); 14925 $ free (typeName); 14926 14927 $ return name; 14928 } 14929 14930 //----------------------------------------------------------------------------------------------------------------- 14931 14932 double txQueryPerformance() 14933 { 14934 $1 int maxTime = 500; 14935 $ int maxSamples = 100; 14936 $ POINT size = {100, 100}; 14937 14938 $ HDC dc = _txBuffer_Create (txWindow(), &size, NULL); 14939 $ assert (dc); if (!dc) return -1; //-V547 14940 14941 $ DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1); //-V202 14942 $ assert (mask); 14943 14944 $ LARGE_INTEGER freq = {}; 14945 $ QueryPerformanceFrequency (&freq) asserted; 14946 14947 $ LARGE_INTEGER start = {}; 14948 $ QueryPerformanceCounter (&start) asserted; 14949 14950 $ int samples = 0; 14951 $ while (samples++ < maxSamples) 14952 { 14953 $ LARGE_INTEGER cur = {}; 14954 $ QueryPerformanceCounter (&cur) asserted; 14955 14956 $ double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart; 14957 $ if (t > maxTime) break; 14958 14959 // Draw test scene 14960 14961 $ for (int y = 0; y < size.y; y++) 14962 for (int x = 0; x < size.x; x++) txSetPixel (x, y, TX_BLACK, dc); 14963 14964 $ for (int y = 0; y < size.y; y += 10) 14965 for (int x = 0; x < size.x; x += 50) txTextOut (x, y, "*", dc); 14966 14967 $ txEllipse (0, 0, size.x, size.y, dc); 14968 $ txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc); 14969 14970 $ txBitBlt (dc, size.x/2.0, 0, size.x/2.0, size.y/2.0, dc, 0, 0) asserted; 14971 $ txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, 0, size.y/2.0) asserted; 14972 $ txBitBlt (dc, 0, size.y/2.0, size.x/2.0, size.y/2.0, dc, 0, 0) asserted; 14973 $ txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, size.x/2.0, 0) asserted; 14974 } 14975 14976 $ mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask); //-V106 //-V202 14977 $ assert (mask); 14978 14979 $ _txBuffer_Delete (&dc); 14980 14981 $ return 3.0 * samples / sqrt (1.0 * size.x * size.y); 14982 } 14983 14984 //----------------------------------------------------------------------------------------------------------------- 14985 14986 unsigned txExtractColor (COLORREF color, COLORREF component) 14987 { 14988 $1 switch (component) 14989 { 14990 case TX_RED: 14991 case TX_HUE: $ return (color >> 0) & 0xFF; 14992 14993 case TX_GREEN: 14994 case TX_SATURATION: $ return (color >> 8) & 0xFF; 14995 14996 case TX_BLUE: 14997 case TX_LIGHTNESS: $ return (color >> 16) & 0xFF; 14998 14999 default: $ return CLR_INVALID; 15000 } 15001 } 15002 15003 //----------------------------------------------------------------------------------------------------------------- 15004 15005 COLORREF txRGB2HSL (COLORREF rgbColor) 15006 { 15007 $1 struct xRGB 15008 { 15009 static bool zero (double val) 15010 { 15011 const double prec = 0.001; 15012 15013 return (fabs (val) < prec); 15014 } 15015 }; 15016 15017 $ double r = txExtractColor (rgbColor, TX_RED) / 255.0, //-V2551 15018 g = txExtractColor (rgbColor, TX_GREEN) / 255.0, //-V2551 15019 b = txExtractColor (rgbColor, TX_BLUE) / 255.0, //-V2551 15020 15021 m1 = MAX (MAX (r, g), b), 15022 m2 = MIN (MIN (r, g), b), 15023 dm = m1 - m2, 15024 sm = m1 + m2, 15025 15026 h = 0, 15027 s = 0, 15028 l = sm / 2; 15029 15030 $ if (!xRGB::zero (dm)) 15031 { 15032 $ sm = (sm <= 1)? sm : (2-sm); 15033 $ s = (!xRGB::zero (sm))? dm/sm : 0; 15034 15035 $ double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0, 15036 cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0, 15037 cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0; 15038 15039 $ if (xRGB::zero (r - m1)) h = cb - cg; 15040 $ if (xRGB::zero (g - m1)) h = 2 + cr - cb; 15041 $ if (xRGB::zero (b - m1)) h = 4 + cg - cr; 15042 } 15043 15044 $ h = (h >= 0)? h*60 : h*60 + 360; 15045 15046 $ return RGB (ROUND (h / 360.0 * 256), ROUND (s * 255), ROUND (l * 255)); 15047 } 15048 15049 //----------------------------------------------------------------------------------------------------------------- 15050 15051 COLORREF txHSL2RGB (COLORREF hslColor) 15052 { 15053 $1 struct xRGB 15054 { 15055 static double calc (double h, double m1, double m2) 15056 { 15057 $2 while (h < 0) h += 360; 15058 $ while (h > 360) h -= 360; 15059 15060 $ return (h < 60)? m1 + (m2-m1) * h / 60 : 15061 (h < 180)? m2 : 15062 (h < 240)? m1 + (m2-m1) * (240-h) / 60 : 15063 m1; 15064 } 15065 }; 15066 15067 $ int si = txExtractColor (hslColor, TX_SATURATION); 15068 15069 $ double h = txExtractColor (hslColor, TX_HUE) / 256.0 * 360, 15070 s = txExtractColor (hslColor, TX_SATURATION) / 255.0, 15071 l = txExtractColor (hslColor, TX_LIGHTNESS) / 255.0, 15072 15073 m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s, 15074 m1 = 2 * l - m2, 15075 15076 r = (si)? xRGB::calc (h + 120, m1, m2) : l, 15077 g = (si)? xRGB::calc (h, m1, m2) : l, 15078 b = (si)? xRGB::calc (h - 120, m1, m2) : l; 15079 15080 $ return RGB (ROUND (r * 255), ROUND (g * 255), ROUND (b * 255)); 15081 } 15082 15083 //----------------------------------------------------------------------------------------------------------------- 15084 15085 void tx_fpreset() 15086 { 15087 $1 txAutoLock _lock; 15088 15089 $ Win32::_fpreset(); 15090 15091 $ unsigned new87 = 0x0008001C; // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW 15092 15093 #if !defined (__CYGWIN__) 15094 15095 $ unsigned old87 = 0; 15096 $ if (_controlfp_s (&old87, 0, 0) == 0) 15097 {$ (void) _controlfp_s (&old87, old87 & ~new87, 0x0008001F); } // _MCW_EM 15098 15099 #else 15100 15101 $ Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F); // _MCW_EM 15102 15103 #endif 15104 } 15105 15106 #endif // TX_COMPILED 15107 15108 //----------------------------------------------------------------------------------------------------------------- 15109 15110 #if defined (_TX_CPP11) 15111 template <int txFramesToAverage> 15112 #endif 15113 15114 double txGetFPS (int minFrames) 15115 { 15116 $1 static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0); 15117 $ LARGE_INTEGER time = {}; QueryPerformanceCounter (&time); 15118 15119 $ if (time.QuadPart - time0.QuadPart == 0) 15120 {$ return 0; } 15121 15122 $ LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq); 15123 15124 $ double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart); 15125 $ time0 = time; 15126 15127 $ if (txFramesToAverage == 0) return fps; 15128 15129 $ static _tx_thread double average [txFramesToAverage] = {}; 15130 $ static _tx_thread unsigned n = 0; 15131 15132 $ average [n++ % txFramesToAverage] = fps; 15133 15134 $ unsigned nn = MIN (n, (unsigned) sizearr (average)); 15135 15136 $ fps = 0; 15137 $ for (unsigned i = 0; i < nn; i++) fps += average[i]; 15138 $ fps /= nn; 15139 15140 $ return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0; 15141 } 15142 15143 //----------------------------------------------------------------------------------------------------------------- 15144 15145 template <typename T> 15146 inline T zero() { T __zero = {}; return __zero; } 15147 15148 //----------------------------------------------------------------------------------------------------------------- 15149 15150 inline double random (std::nomeow_t, double left, double right) 15151 { 15152 return left + (right - left) * ((double) rand() / RAND_MAX); 15153 } 15154 15155 //----------------------------------------------------------------------------------------------------------------- 15156 15157 template <typename Tx, typename Ta, typename Tb> 15158 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) 15159 { 15160 return a <= x && x <= b; 15161 } 15162 15163 //----------------------------------------------------------------------------------------------------------------- 15164 15165 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) 15166 { 15167 if (_TX_ARGUMENT_FAILED (&pt)) return false; 15168 if (_TX_ARGUMENT_FAILED (&rect)) return false; 15169 15170 return In (std::nomeow, pt.x, rect.left, rect.right) && 15171 In (std::nomeow, pt.y, rect.top, rect.bottom); 15172 } 15173 15174 //----------------------------------------------------------------------------------------------------------------- 15175 15176 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) 15177 { 15178 if (_TX_ARGUMENT_FAILED (&pt)) return false; 15179 if (_TX_ARGUMENT_FAILED (&rect)) return false; 15180 15181 return In (std::nomeow, pt.X, rect.Left, rect.Right) && 15182 In (std::nomeow, pt.Y, rect.Top, rect.Bottom); 15183 } 15184 15185 //----------------------------------------------------------------------------------------------------------------- 15186 15187 inline int random (int range) 15188 { 15189 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15190 15191 return rand() % range; 15192 } 15193 15194 //----------------------------------------------------------------------------------------------------------------- 15195 15196 inline double random (double left, double right) 15197 { 15198 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15199 15200 return random (std::nomeow, left, right); 15201 } 15202 15203 //----------------------------------------------------------------------------------------------------------------- 15204 15205 template <typename Tx, typename Ta, typename Tb> 15206 inline bool In (Tx x, Ta a, Tb b) 15207 { 15208 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15209 15210 return In (std::nomeow, x, a, b); 15211 } 15212 15213 //----------------------------------------------------------------------------------------------------------------- 15214 15215 inline bool In (const POINT& pt, const RECT& rect) 15216 { 15217 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15218 15219 return In (std::nomeow, pt, rect); 15220 } 15221 15222 //----------------------------------------------------------------------------------------------------------------- 15223 15224 inline bool In (const COORD& pt, const SMALL_RECT& rect) 15225 { 15226 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15227 15228 return In (std::nomeow, pt, rect); 15229 } 15230 15231 //} 15232 //================================================================================================================= 15233 15234 //================================================================================================================= 15235 //{ txPrintf() implementation 15236 // Реализация txPrintf() 15237 //================================================================================================================= 15238 15239 #if defined (_TX_CPP11) 15240 15241 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args); 15242 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args); 15243 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args); 15244 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args); 15245 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt); 15246 15247 template <typename T> void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg); 15248 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg); 15249 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt); 15250 15251 //----------------------------------------------------------------------------------------------------------------- 15252 15253 template <typename T, typename... ArgsT> 15254 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args) 15255 { 15256 $1 assert (fmt); 15257 15258 $ _txPrintV (stream, format, n, fmt); 15259 15260 if (fmt[0] == '%') {$} 15261 else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); } 15262 15263 $ _txPrintV (stream, format, n, fmt, arg); 15264 15265 $ _txPrintF (stream, format, n+1, fmt, args...); 15266 } 15267 15268 //----------------------------------------------------------------------------------------------------------------- 15269 15270 template <typename T, typename... ArgsT> 15271 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args) 15272 { 15273 $1 assert (&stream); 15274 $ assert (fmt); 15275 15276 $ _txPrintV (stream, format, n, fmt); 15277 15278 if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); } //-V2006 15279 else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); } 15280 15281 $ _txPrintV (stream, format, n, fmt, arg); 15282 15283 $ _txPrintF (stream, format, n+1, fmt, args...); 15284 } 15285 15286 //----------------------------------------------------------------------------------------------------------------- 15287 15288 template <typename T, typename... ArgsT> 15289 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args) 15290 { 15291 $1 assert (&stream); 15292 $ assert (fmt); 15293 15294 $ _txPrintV (stream, format, n, fmt); 15295 15296 if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((std::streamsize) (prec + 1)); } //-V2006 //-V1028 15297 else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); } 15298 15299 $ _txPrintV (stream, format, n, fmt, arg); 15300 15301 $ _txPrintF (stream, format, n+1, fmt, args...); 15302 } 15303 15304 //----------------------------------------------------------------------------------------------------------------- 15305 15306 template <typename T, typename... ArgsT> 15307 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args) 15308 { 15309 $1 assert (&stream); 15310 $ assert (fmt); 15311 15312 $ _txPrintV (stream, format, n, fmt); 15313 15314 if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((std::streamsize) (prec + 1)); } //-V2006 //-V1028 15315 else {$ TX_ERROR ("\"%%*.*\" required to setwidth (%d) and setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, prec, fmt, txTypename (arg), n, format); } 15316 15317 $ _txPrintV (stream, format, n, fmt, arg); 15318 15319 $ _txPrintF (stream, format, n+1, fmt, args...); 15320 } 15321 15322 //----------------------------------------------------------------------------------------------------------------- 15323 15324 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt) 15325 { 15326 $1 assert (fmt); 15327 15328 $ _txPrintV (stream, format, n, fmt); 15329 15330 if (!fmt[0]) {$} 15331 else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); } 15332 } 15333 15334 //----------------------------------------------------------------------------------------------------------------- 15335 15336 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt) 15337 { 15338 $1 assert (&stream); 15339 $ assert (fmt); 15340 15341 $ while (*fmt) 15342 { 15343 if (fmt[0] == '%') 15344 { 15345 if (fmt[1] == '%') fmt++; 15346 else break; 15347 } 15348 15349 stream << *fmt++; 15350 } 15351 $ } 15352 15353 //----------------------------------------------------------------------------------------------------------------- 15354 15355 template <typename T> 15356 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg) 15357 { 15358 $1 assert (&stream); 15359 $ assert (fmt); 15360 15361 $ if (_TX_ARGUMENT_FAILED (&arg)) return; 15362 15363 if (fmt[0] == '%') {$} 15364 else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); } 15365 15366 $ fmt++; 15367 15368 $ char oldFill = stream.fill (' '); 15369 $ std::ios_base::fmtflags oldFlags = stream.flags(); 15370 15371 $ for (;;) switch (*fmt) 15372 { 15373 case '-': $ stream << std::left; fmt++; break; 15374 case '+': $ stream << std::showpos; fmt++; break; 15375 case ' ': $ stream.fill (' '); fmt++; break; 15376 case '#': $ stream << std::showbase; fmt++; break; 15377 case '0': $ stream.fill ('0'); fmt++; break; 15378 15379 default: $ goto end; 15380 } 15381 end: 15382 15383 $ int width = (*fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0); 15384 $ int prec = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0; 15385 15386 if (width) {$ stream << std::setw (width); } 15387 if (prec) {$ stream << std::setprecision (prec); } 15388 15389 $ fmt += strspn (fmt, "hljztL"); 15390 15391 $ switch (*fmt) 15392 { 15393 case '$': 15394 case '?': $ break; 15395 15396 case 'd': 15397 case 'i': 15398 case 'u': $ stream << std::dec; break; 15399 15400 case 'o': $ stream << std::oct; break; 15401 15402 case 'x': $ stream << std::hex; break; 15403 case 'X': $ stream << std::hex << std::uppercase; break; 15404 15405 case 'f': $ stream << std::fixed; break; 15406 case 'F': $ stream << std::fixed << std::uppercase; break; 15407 15408 case 'e': $ stream << std::scientific; break; 15409 case 'E': $ stream << std::scientific << std::uppercase; break; 15410 15411 case 'g': $ break; 15412 case 'G': $ stream << std::uppercase; break; 15413 15414 case 'a': $ break; 15415 case 'A': $ stream << std::uppercase; break; 15416 15417 case 'c': 15418 case 's': 15419 case 'p': $ break; 15420 15421 default: $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break; 15422 } 15423 15424 $ fmt++; 15425 15426 if (&arg) {$ stream << arg; } 15427 else {$ stream << "(null)"; } 15428 15429 $ stream.fill (oldFill); 15430 $ stream.flags (oldFlags); 15431 } 15432 15433 //----------------------------------------------------------------------------------------------------------------- 15434 15435 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg) //-V2009 15436 { 15437 $1 assert (fmt); 15438 15439 if (_TX_ARGUMENT_FAILED (arg)) return; 15440 15441 if (fmt[0] == '%' && fmt[1] == 'n') {$} 15442 else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); } 15443 15444 $ *arg = (int) stream.str().length(); //-V202 15445 15446 $ fmt += 2; 15447 } 15448 15449 //----------------------------------------------------------------------------------------------------------------- 15450 15451 template <typename T> inline const T& _txPrintfNormalizeArg (const T& arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;} return arg; } 15452 inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); } 15453 15454 //----------------------------------------------------------------------------------------------------------------- 15455 15456 template <typename... ArgsT> 15457 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args) 15458 { 15459 $1 if (_TX_ARGUMENT_FAILED (&stream)) return 0; 15460 $ if (_TX_ARGUMENT_FAILED (&format)) return 0; 15461 15462 $ const char* fmt = format; 15463 $ _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...); 15464 15465 $ return (int) stream.str().length(); //-V202 15466 } 15467 15468 //----------------------------------------------------------------------------------------------------------------- 15469 15470 template <typename... ArgsT> 15471 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args) 15472 { 15473 $1 if (_TX_ARGUMENT_FAILED (&buffer)) return 0; 15474 $ if (_TX_ARGUMENT_FAILED (&format)) return 0; 15475 15476 $ if (size > 0) size--; 15477 $ buffer[size] = 0; 15478 15479 $ if (!size) return 0; 15480 15481 $ std::ostringstream stream; 15482 $ stream.rdbuf() -> pubsetbuf (buffer, size); 15483 15484 $ txPrintf (stream, format, args...); 15485 15486 $ return (int) stream.str().length(); //-V202 15487 } 15488 15489 //----------------------------------------------------------------------------------------------------------------- 15490 15491 template <typename... ArgsT> 15492 inline std::string txFormat (const char* format, ArgsT... args) 15493 { 15494 $1 if (_TX_ARGUMENT_FAILED (&format)) return ""; 15495 15496 $ std::ostringstream stream; 15497 15498 $ txPrintf (stream, format, args...); 15499 15500 $ return stream.str(); 15501 } 15502 15503 //----------------------------------------------------------------------------------------------------------------- 15504 15505 template <typename... ArgsT> 15506 inline int txPrintf (const char* format, ArgsT... args) 15507 { 15508 $1 if (_TX_ARGUMENT_FAILED (&format)) return 0; 15509 15510 $ return printf ("%s", txFormat (format, args...) .c_str()); 15511 } 15512 15513 #endif 15514 15515 //----------------------------------------------------------------------------------------------------------------- 15516 15517 int _txPrintfCheck (const char* format, ...) tx_printfy (1); 15518 inline int _txPrintfCheck (const char*, ...) { return 0; } 15519 15520 //} 15521 //================================================================================================================= 15522 15523 //================================================================================================================= 15524 //{ txDialog methods implementation 15525 // Реализация методов класса txDialog 15526 // 15527 // See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx 15528 // [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743 15529 // [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753 15530 //================================================================================================================= 15531 15532 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 15533 15534 txDialog::txDialog () : 15535 layout_ (NULL) 15536 {$1} 15537 15538 //----------------------------------------------------------------------------------------------------------------- 15539 15540 txDialog::txDialog (const Layout* layout) : 15541 layout_ (layout) 15542 {$1} 15543 15544 //----------------------------------------------------------------------------------------------------------------- 15545 15546 const txDialog::Layout* txDialog::setLayout (const Layout* layout) 15547 { 15548 $1 assert (layout); 15549 15550 $ return ::std::swap (layout_, layout), layout; 15551 } 15552 15553 //----------------------------------------------------------------------------------------------------------------- 15554 15555 intptr_t txDialog::dialogBox (WORD resourceID) 15556 { 15557 $1 const char* resName = (char*)(uintptr_t) resourceID; 15558 15559 $ if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0; 15560 15561 $ return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this); 15562 } 15563 15564 //----------------------------------------------------------------------------------------------------------------- 15565 15566 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/) 15567 { 15568 $1 if (!layout) layout = layout_; 15569 $ if (!layout) return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0; 15570 15571 $ if (!bufsize) bufsize = 1024; 15572 15573 $ DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize); 15574 $ if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0; 15575 15576 $ const Layout* dlg = &layout[0]; 15577 $ const Layout def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 }; 15578 15579 $ void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize, 15580 (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0, 15581 dlg->x, dlg->y, dlg->sx, dlg->sy, 15582 dlg->caption? dlg->caption : def.caption, 15583 dlg->font? dlg->font : def.font, 15584 dlg->fontsize? dlg->fontsize : def.fontsize, NULL); 15585 $ WORD i = 0; 15586 $ for (i = 1; layout[i].wndclass != END; ++i) 15587 { 15588 $ const Layout* item = &layout[i]; 15589 15590 $ ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl), 15591 item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy, 15592 item->id, (const char*)(uintptr_t) item->wndclass, item->caption); 15593 } 15594 15595 $ tmpl->cdit = (unsigned short) (i-1); 15596 15597 $ intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this); 15598 15599 $ GlobalFree (tmpl); 15600 15601 $ return res; 15602 } 15603 15604 //----------------------------------------------------------------------------------------------------------------- 15605 15606 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM) 15607 { 15608 $1 switch (msg) 15609 { 15610 case WM_INITDIALOG: $ SetForegroundWindow (wnd); 15611 $ break; 15612 15613 case WM_COMMAND: $ switch (LOWORD (wParam)) 15614 { 15615 case IDOK: 15616 case IDCANCEL: $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow()); 15617 $ EndDialog (wnd, (uintptr_t) this); 15618 $ break; 15619 15620 default: $ break; 15621 } 15622 $ break; 15623 default: $ break; 15624 } 15625 15626 $ return FALSE; 15627 } 15628 15629 //----------------------------------------------------------------------------------------------------------------- 15630 15631 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) 15632 { 15633 $1 static txDialog* this__ = NULL; 15634 $ if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam; 15635 $ if (!this__) return FALSE; 15636 15637 $ return this__-> dialogProc (wnd, msg, wParam, lParam); //-V109 15638 } 15639 15640 //----------------------------------------------------------------------------------------------------------------- 15641 15642 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle, 15643 WORD controls, short x, short y, short cx, short cy, 15644 const char caption[], const char font[], WORD fontsize, const char menu[]) 15645 { 15646 $1 if (_TX_ARGUMENT_FAILED (globalMem)) return NULL; 15647 15648 $ WORD* pw = (WORD*) globalMem; 15649 15650 $ DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++; 15651 15652 $ tmpl->style = style; 15653 $ tmpl->dwExtendedStyle = exStyle; 15654 $ tmpl->cdit = controls; 15655 $ tmpl->x = x; 15656 $ tmpl->y = y; 15657 $ tmpl->cx = cx; 15658 $ tmpl->cy = cy; 15659 15660 $ if (menu > (const char*) 0xFFFF) 15661 { 15662 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (menu? menu : ""), -1, (wchar_t*) pw, //-V547 15663 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15664 } 15665 else 15666 { 15667 $ *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0); 15668 $ *pw++ = (WORD)(uintptr_t) menu; 15669 } 15670 15671 $ if (caption) 15672 { 15673 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw, //-V547 15674 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15675 } 15676 15677 $ if (style & DS_SETFONT) 15678 { 15679 $ *pw++ = fontsize; 15680 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (font? font : ""), -1, (wchar_t*) pw, 15681 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15682 } 15683 15684 $ return pw; 15685 } 15686 15687 //----------------------------------------------------------------------------------------------------------------- 15688 15689 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle, 15690 short x, short y, short cx, short cy, 15691 WORD id, const char wclass[], const char caption[]) 15692 { 15693 $1 if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL; 15694 15695 $ WORD* pw = (LPWORD) dlgTemplatePtr; // Force align at word boundary 15696 $ ((ULONG&) pw) += 3; //-V205 15697 $ ((ULONG&) pw) >>= 2; //-V205 15698 $ ((ULONG&) pw) <<= 2; //-V205 15699 15700 $ DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++; 15701 15702 $ tmpl->style = style; 15703 $ tmpl->dwExtendedStyle = exStyle; 15704 $ tmpl->x = x; 15705 $ tmpl->y = y; 15706 $ tmpl->cx = cx; 15707 $ tmpl->cy = cy; 15708 $ tmpl->id = id; 15709 15710 $ if (HIWORD (wclass) == 0xFFFF) 15711 { 15712 $ *pw++ = (WORD) (HIWORD ((uintptr_t) wclass)); 15713 $ *pw++ = (WORD) (LOWORD ((uintptr_t) wclass)); 15714 } 15715 else if (wclass) 15716 { 15717 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw, 15718 (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF)); //-V202 15719 } 15720 else 15721 { 15722 $ *pw++ = 0; 15723 } 15724 15725 $ if (caption) 15726 { 15727 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw, 15728 (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF)); //-V202 15729 } 15730 else 15731 { 15732 $ *pw++ = 0; 15733 } 15734 15735 $ *pw++ = 0; 15736 15737 $ return pw; 15738 } 15739 15740 #endif // TX_COMPILED 15741 15742 //} 15743 //================================================================================================================= 15744 15745 //================================================================================================================= 15746 //{ Cleaning up the utility macros 15747 // Очистка служебных макросов 15748 //================================================================================================================= 15749 15750 #undef $ 15751 #undef $0 15752 #undef $1 15753 #undef $2 15754 #undef $3 15755 #undef $4 15756 #undef $5 15757 #undef $6 15758 #undef $7 15759 #undef $8 15760 #undef $9 15761 #undef $$ 15762 15763 //} 15764 //================================================================================================================= 15765 15767 15768 //================================================================================================================= 15769 //{ Experimental Debugging macros 15771 //================================================================================================================= 15772 15773 //{---------------------------------------------------------------------------------------------------------------- 15893 //}---------------------------------------------------------------------------------------------------------------- 15894 15895 #ifndef __TX_DEBUG_MACROS 15896 #define __TX_DEBUG_MACROS ("Группа отладочных $-макросов") 15897 15899 //----------------------------------------------------------------------------------------------------------------- 15900 15901 #define $H txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_BLACK); 15902 #define $B txSetConsoleAttr (FOREGROUND_BLUE | BACKGROUND_BLACK); 15903 #define $G txSetConsoleAttr (FOREGROUND_GREEN | BACKGROUND_BLACK); 15904 #define $C txSetConsoleAttr (FOREGROUND_CYAN | BACKGROUND_BLACK); 15905 #define $R txSetConsoleAttr (FOREGROUND_RED | BACKGROUND_BLACK); 15906 #define $M txSetConsoleAttr (FOREGROUND_MAGENTA | BACKGROUND_BLACK); 15907 #define $Y txSetConsoleAttr (FOREGROUND_DARKYELLOW | BACKGROUND_BLACK); 15908 #define $d txSetConsoleAttr (FOREGROUND_LIGHTGRAY | BACKGROUND_BLACK); 15909 #define $D txSetConsoleAttr (FOREGROUND_DARKGRAY | BACKGROUND_BLACK); 15910 #define $b txSetConsoleAttr (FOREGROUND_LIGHTBLUE | BACKGROUND_BLACK); 15911 #define $g txSetConsoleAttr (FOREGROUND_LIGHTGREEN | BACKGROUND_BLACK); 15912 #define $c txSetConsoleAttr (FOREGROUND_LIGHTCYAN | BACKGROUND_BLACK); 15913 #define $r txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK); 15914 #define $m txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK); 15915 #define $y txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLACK); 15916 #define $h txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_BLACK); 15917 15918 #define $i txSetConsoleAttr (FOREGROUND_LIGHTCYAN | BACKGROUND_BLUE); 15919 #define $I txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLUE); 15920 #define $o txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_GREEN); 15921 #define $O txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_GREEN); 15922 #define $e txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_RED); 15923 #define $E txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_RED); 15924 #define $w txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA); 15925 #define $W txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_MAGENTA); 15926 #define $f txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_LIGHTRED); 15927 #define $F txSetConsoleAttr (FOREGROUND_MAGENTA | BACKGROUND_LIGHTRED); 15928 #define $l txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_DARKGRAY); 15929 #define $L txSetConsoleAttr (FOREGROUND_LIGHTGRAY | BACKGROUND_DARKGRAY); 15930 15931 #define $T( cond ) txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED ); 15932 15933 #define $s _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__); 15934 15935 #define $sH $s $H 15936 #define $sB $s $B 15937 #define $sG $s $G 15938 #define $sC $s $C 15939 #define $sR $s $R 15940 #define $sM $s $M 15941 #define $sY $s $Y 15942 #define $sd $s $d 15943 #define $sD $s $D 15944 #define $sb $s $b 15945 #define $sg $s $g 15946 #define $sc $s $c 15947 #define $sr $s $r 15948 #define $sm $s $m 15949 #define $sy $s $y 15950 #define $sh $s $h 15951 15952 #define $si $s $i 15953 #define $sI $s $I 15954 #define $so $s $o 15955 #define $sO $s $O 15956 #define $se $s $e 15957 #define $sE $s $E 15958 #define $sw $s $w 15959 #define $sW $s $W 15960 #define $sf $s $f 15961 #define $sF $s $F 15962 #define $sl $s $l 15963 #define $sL $s $L 15964 15965 #define $sT( cond ) $s $T (cond) 15966 15967 #define $test(cond) { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \ 15968 else { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; } 15969 15970 #define $status(cond) $test (cond) 15971 15972 #define $unittest( code, expected ) \ 15973 { \ 15974 const _tx_decltype (code) & _result = (code); /* Should use auto, but g++ 4.7.2 default std is < 2011 */ \ 15975 const _tx_decltype (expected) & _expected = (expected); \ 15976 \ 15977 if (_result == _expected) \ 15978 { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; } \ 15979 else \ 15980 { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \ 15981 \ 15982 $n; \ 15983 (_result == _expected); \ 15984 } 15985 15986 //================================================================================================================= 15987 15988 #define $V( var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "]\n") ) 15989 #define $V_( var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "] " ) ) 15990 #define $V__(var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "]" ) ) 15991 15992 #define $( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]\n") ) 15993 #define $_( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "] " ) ) 15994 #define $__( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ) ) 15995 15996 #define $x( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) ) 15997 #define $x_( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "] ", ::std::ios_base::showbase | ::std::ios_base::hex) ) 15998 15999 #define $v( var, cond, ...) { { $st (cond); _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ); } $n; } 16000 #define $v_( var, cond, ...) { $st (cond); _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ); } 16001 16002 #define $$ { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__); } txOutputDebugPrintf ("\f\n"); } 16003 #define $$_ { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]", __LINE__, __func__); } txOutputDebugPrintf ("\f\n"); } 16004 #define $meow(...) { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); } 16005 16006 #define $$$( ... ) ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") ) 16007 #define $$$_( ... ) ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__), "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") ) 16008 16009 #define $$$$( ... ) { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__ " DONE]\n\n"); { __VA_ARGS__; } } 16010 #define $$$$_( ... ) { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix ( "[" __TX_FILELINE__ ": " #__VA_ARGS__ " DONE]\n\n"); { __VA_ARGS__; } } 16011 #define $do( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; __VA_ARGS__ 16012 #define $DO( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p; __VA_ARGS__ 16013 #define $Do( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; \ 16014 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__); __VA_ARGS__ 16015 16016 #define $n { ::std::cerr << "\n"; } 16017 #define $nn { ::std::cerr << "\n\n"; } 16018 #define $t { ::std::cerr << "\t"; } 16019 16020 #define _tx$PrefixV( ...) ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " ) : ("[" ) ) 16021 #define _tx$Prefix(var, ...) ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") ) 16022 16023 //----------------------------------------------------------------------------------------------------------------- 16024 16025 // This will never be documented, he-he. Read the source, Luke. 16026 16027 #if defined (_DEBUG) 16028 #define $dbg if (1) 16029 #define $DBG if (1) 16030 #define $debug if (1) 16031 #define $DEBUG if (1) 16032 #define $printf(fmt, ...) if (1) printf ( fmt, ##__VA_ARGS__) 16033 #define $PRINTF(fmt, ...) if (1) fprintf (stderr, fmt, ##__VA_ARGS__) 16034 #else 16035 #define $dbg if (0) 16036 #define $DBG if (0) 16037 #define $debug if (0) 16038 #define $DEBUG if (0) 16039 #define $printf(...) if (0) printf ( fmt, ##__VA_ARGS__) 16040 #define $PRINTF(...) if (0) fprintf (stderr, fmt, ##__VA_ARGS__) 16041 #endif 16042 16043 #define $$d $debug 16044 #define $$w $$$$ 16045 #define $$s __TX_FILELINE__ 16046 #define $$b { txSleep(); DebugBreak(); } 16047 #define $$p { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \ 16048 __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); } 16049 #define $$P ( txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) ) 16050 #define $ppp { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); } 16051 #define $pp { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__, __TX_FUNCTION__); } 16052 #define $p { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__); } 16053 #define $ppp_ { $sy; txPause ("\v[%s ""%s]...", __TX_FILELINE__, __TX_FUNCTION__); } 16054 #define $pp_ { $sy; txPause ("\v[%04d %s]...", __LINE__, __TX_FUNCTION__); } 16055 #define $p_ { $sy; txPause ("\v[%s ""%s()]...", __TX_FILELINE__, __func__); } 16056 #define $P ( txPause ("") ) 16057 16058 //----------------------------------------------------------------------------------------------------------------- 16059 16060 struct _txSaveConsoleAttr 16061 { 16062 unsigned attr_; 16063 16064 _txSaveConsoleAttr() : attr_ (txGetConsoleAttr ()) {} 16065 explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr); } 16066 ~_txSaveConsoleAttr() { txSetConsoleAttr (attr_); } 16067 }; 16068 16069 //----------------------------------------------------------------------------------------------------------------- 16070 16071 struct _txDumpVarSuffix 16072 { 16073 typedef _txDumpVarSuffix this_t; 16074 16075 const char* suffix_; 16076 16077 explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); } 16078 ~_txDumpVarSuffix() { ::std::cerr << suffix_; } 16079 16080 _txDumpVarSuffix (const this_t&) _tx_delete; 16081 this_t& operator = (const this_t&) _tx_delete; 16082 }; 16083 16084 //----------------------------------------------------------------------------------------------------------------- 16085 16086 #define ARGS__ const char* prefix, const char* suffix, std::ios_base::fmtflags flags, int deep 16087 #define ARGS_ const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0 16088 #define VALS_ prefix, suffix, flags, deep 16089 #define ERRPTR_(p) { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; } 16090 16091 template <typename T, typename StreamT> const T& _txDumpVal (const T& value, StreamT& stream, ARGS_); 16092 16093 //----------------------------------------------------------------------------------------------------------------- 16094 16095 template <typename T> inline const T& _txDumpVar (const T& value, ARGS_) { _txDumpVal (value, std:: cerr, VALS_); return value; } 16096 template <typename T> inline T& _txDumpVar ( T& value, ARGS_) { _txDumpVal (value, std:: cerr, VALS_); return value; } 16097 16098 template <int N> inline const char (&_txDumpVar (const char (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; } 16099 template <int N> inline char (&_txDumpVar ( char (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; } 16100 16101 template <int N> inline const wchar_t (&_txDumpVar (const wchar_t (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; } 16102 template <int N> inline wchar_t (&_txDumpVar ( wchar_t (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; } 16103 16104 inline const wchar_t& _txDumpVar (const wchar_t& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16105 inline wchar_t& _txDumpVar ( wchar_t& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16106 16107 inline const wchar_t*& _txDumpVar (const wchar_t*& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16108 inline wchar_t*& _txDumpVar ( wchar_t*& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16109 16110 inline const std::wstring& _txDumpVar (const std::wstring& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16111 inline std::wstring& _txDumpVar ( std::wstring& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16112 16113 //----------------------------------------------------------------------------------------------------------------- 16114 16115 template <typename T, typename StreamT> inline void _txDumpVal (const T& value, StreamT& stream) { stream << value; } 16116 template <typename StreamT> inline void _txDumpVal (const char value, StreamT& stream) { stream << "'" << value << "'"; } 16117 template <typename StreamT> inline void _txDumpVal (const wchar_t value, StreamT& stream) { stream << L"'" << value << L"'"; } 16118 template <typename StreamT> inline void _txDumpVal (const std::string& value, StreamT& stream) { stream << '"' << value << '"'; } 16119 template <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; } 16120 16121 template <typename StreamT> inline void _txDumpVal (const char* value, StreamT& stream) 16122 { 16123 if (_TX_ARGUMENT_FAILED (&stream)) return; 16124 16125 if (!_txIsBadReadPtr (value)) stream << '"' << value << '"'; 16126 else if (!value) stream << "(null)"; 16127 else ERRPTR_ (value); 16128 } 16129 16130 template <typename StreamT> inline void _txDumpVal (const wchar_t* value, StreamT& stream) 16131 { 16132 if (_TX_ARGUMENT_FAILED (&stream)) return; 16133 16134 if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"'; 16135 else if (!value) stream << L"(null)"; 16136 else ERRPTR_ (value); 16137 } 16138 16139 //----------------------------------------------------------------------------------------------------------------- 16140 16141 template <typename T, typename StreamT> 16142 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__) 16143 { 16144 if (_TX_ARGUMENT_FAILED (&stream)) return value; //-V778 16145 if (_TX_ARGUMENT_FAILED ( prefix)) return value; 16146 if (_TX_ARGUMENT_FAILED ( suffix)) return value; 16147 16148 $sc; 16149 if (!deep) stream << prefix; 16150 16151 std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags()); 16152 16153 if (!_txIsBadReadPtr (&value)) 16154 { 16155 _txDumpVal (value, stream); 16156 } 16157 else 16158 ERRPTR_ (&value); 16159 16160 stream.flags (old); 16161 16162 if (!deep) stream << suffix; 16163 16164 return value; 16165 } 16166 16167 //----------------------------------------------------------------------------------------------------------------- 16168 16169 template <typename T, int N> 16170 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N] 16171 { 16172 if (_TX_ARGUMENT_FAILED ( prefix)) return value; 16173 if (_TX_ARGUMENT_FAILED ( suffix)) return value; 16174 16175 std::ostream& stream = std::cerr; 16176 16177 $sc; if (!deep) std::cerr << prefix; 16178 $C; std::cerr << ((deep)? " {" : "{"); 16179 16180 if (!_txIsBadReadPtr (value)) 16181 { 16182 for (int i = 0; ; i++) 16183 { 16184 { $sC; stream << "[" << i << "]="; } 16185 16186 _txDumpVar (value[i], prefix, suffix, flags, deep+1); 16187 16188 if (i >= N-1) break; 16189 16190 stream << ", "; 16191 } 16192 } 16193 else 16194 ERRPTR_ (&value); 16195 16196 $C; std::cerr << "}"; 16197 $c; if (!deep) std::cerr << suffix; 16198 16199 return value; 16200 } 16201 16202 //================================================================================================================= 16203 16204 inline std::ostream& operator << (std::ostream& stream, const POINT& point) 16205 { 16206 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16207 16208 if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }"; // NOLINT (clang-diagnostic-undefined-bool-conversion) 16209 else if (!&point) stream << "(null)"; 16210 else ERRPTR_ (&point); 16211 16212 return stream; 16213 } 16214 16215 inline std::ostream& operator << (std::ostream& stream, const SIZE& size) 16216 { 16217 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16218 16219 if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }"; // NOLINT (clang-diagnostic-undefined-bool-conversion) 16220 else stream << "(null)"; 16221 16222 return stream; 16223 } 16224 16225 inline std::ostream& operator << (std::ostream& stream, const RECT& rect) 16226 { 16227 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16228 16229 if (&rect) stream << "{ left: " << rect.left << ", top: " << rect.top << // NOLINT (clang-diagnostic-undefined-bool-conversion) 16230 ", right: " << rect.right << ", bottom: " << rect.bottom << " }"; 16231 16232 else stream << "(null)"; 16233 16234 return stream; 16235 } 16236 16237 //----------------------------------------------------------------------------------------------------------------- 16238 16239 #undef ARGS__ 16240 #undef ARGS_ 16241 #undef VALS_ 16242 #undef ERRPTR_ 16243 16244 //----------------------------------------------------------------------------------------------------------------- 16246 16247 #endif 16248 16249 //} 16250 //================================================================================================================= 16251 16253 16254 //================================================================================================================= 16255 //{ TXAPI calls tracing 16256 // Трассировка вызовов TXAPI 16257 //================================================================================================================= 16258 16259 #ifndef FOR_DOXYGEN_ONLY 16260 16261 #if defined (_MSC_VER) 16262 #undef _txLocCurSet 16263 #define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, NULL) 16264 #endif 16265 16266 #define txAlphaBlend(...) ( _txLocCurSet(), txAlphaBlend (__VA_ARGS__) ) 16267 #define txArc(...) ( _txLocCurSet(), txArc (__VA_ARGS__) ) 16268 #define txBegin(...) ( _txLocCurSet(), txBegin (__VA_ARGS__) ) 16269 #define txBitBlt(...) ( _txLocCurSet(), txBitBlt (__VA_ARGS__) ) 16270 #define txChord(...) ( _txLocCurSet(), txChord (__VA_ARGS__) ) 16271 #define txCircle(...) ( _txLocCurSet(), txCircle (__VA_ARGS__) ) 16272 #define txClear(...) ( _txLocCurSet(), txClear (__VA_ARGS__) ) 16273 #define txClearConsole(...) ( _txLocCurSet(), txClearConsole (__VA_ARGS__) ) 16274 #define txColor(...) ( _txLocCurSet(), txColor (__VA_ARGS__) ) 16275 #define txCreateCompatibleDC(...) ( _txLocCurSet(), txCreateCompatibleDC (__VA_ARGS__) ) 16276 #define txCreateDIBSection(...) ( _txLocCurSet(), txCreateDIBSection (__VA_ARGS__) ) 16277 #define txCreateExtraWindow(...) ( _txLocCurSet(), txCreateExtraWindow (__VA_ARGS__) ) 16278 #define txCreateWindow(...) ( _txLocCurSet(), txCreateWindow (__VA_ARGS__) ) 16279 #define txDC(...) ( _txLocCurSet(), txDC (__VA_ARGS__) ) 16280 #define txDeleteDC(...) ( _txLocCurSet(), txDeleteDC (__VA_ARGS__) ) 16281 #define txDemangle(...) ( _txLocCurSet(), txDemangle (__VA_ARGS__) ) 16282 #define txDestroyWindow(...) ( _txLocCurSet(), txDestroyWindow (__VA_ARGS__) ) 16283 #define txDisableAutoPause(...) ( _txLocCurSet(), txDisableAutoPause (__VA_ARGS__) ) 16284 #define txDrawText(...) ( _txLocCurSet(), txDrawText (__VA_ARGS__) ) 16285 #define txEllipse(...) ( _txLocCurSet(), txEllipse (__VA_ARGS__) ) 16286 #define txEnd(...) ( _txLocCurSet(), txEnd (__VA_ARGS__) ) 16287 #define txExtractColor(...) ( _txLocCurSet(), txExtractColor (__VA_ARGS__) ) 16288 #define txFillColor(...) ( _txLocCurSet(), txFillColor (__VA_ARGS__) ) 16289 #define txFloodFill(...) ( _txLocCurSet(), txFloodFill (__VA_ARGS__) ) 16290 #define txFontExist(...) ( _txLocCurSet(), txFontExist (__VA_ARGS__) ) 16291 #define txFormat(...) ( _txLocCurSet(), txFormat (__VA_ARGS__) ) 16292 #define txGetAsyncKeyState(...) ( _txLocCurSet(), txGetAsyncKeyState (__VA_ARGS__) ) 16293 #define txGetColor(...) ( _txLocCurSet(), txGetColor (__VA_ARGS__) ) 16294 #define txGetConsoleAttr(...) ( _txLocCurSet(), txGetConsoleAttr (__VA_ARGS__) ) 16295 #define txGetConsoleCursorPos(...) ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) ) 16296 #define txGetConsoleExtent(...) ( _txLocCurSet(), txGetConsoleExtent (__VA_ARGS__) ) 16297 #define txGetConsoleFontSize(...) ( _txLocCurSet(), txGetConsoleFontSize (__VA_ARGS__) ) 16298 #define txGetExtent(...) ( _txLocCurSet(), txGetExtent (__VA_ARGS__) ) 16299 #define txGetExtentX(...) ( _txLocCurSet(), txGetExtentX (__VA_ARGS__) ) 16300 #define txGetExtentY(...) ( _txLocCurSet(), txGetExtentY (__VA_ARGS__) ) 16301 #define txGetFillColor(...) ( _txLocCurSet(), txGetFillColor (__VA_ARGS__) ) 16302 #define txGetFPS(...) ( _txLocCurSet(), txGetFPS (__VA_ARGS__) ) 16303 #define txGetModuleFileName(...) ( _txLocCurSet(), txGetModuleFileName (__VA_ARGS__) ) 16304 #define txGetPixel(...) ( _txLocCurSet(), txGetPixel (__VA_ARGS__) ) 16305 #define txGetTextExtent(...) ( _txLocCurSet(), txGetTextExtent (__VA_ARGS__) ) 16306 #define txGetTextExtentX(...) ( _txLocCurSet(), txGetTextExtentX (__VA_ARGS__) ) 16307 #define txGetTextExtentY(...) ( _txLocCurSet(), txGetTextExtentY (__VA_ARGS__) ) 16308 #define txHSL2RGB(...) ( _txLocCurSet(), txHSL2RGB (__VA_ARGS__) ) 16309 #define txInputBox(...) ( _txLocCurSet(), txInputBox (__VA_ARGS__) ) 16310 #define txLine(...) ( _txLocCurSet(), txLine (__VA_ARGS__) ) 16311 #define txLoadImage(...) ( _txLocCurSet(), txLoadImage (__VA_ARGS__) ) 16312 #define txLock(...) ( _txLocCurSet(), txLock (__VA_ARGS__) ) 16313 #define txMessageBox(...) ( _txLocCurSet(), txMessageBox (__VA_ARGS__) ) 16314 #define txMouseButtons(...) ( _txLocCurSet(), txMouseButtons (__VA_ARGS__) ) 16315 #define txMousePos(...) ( _txLocCurSet(), txMousePos (__VA_ARGS__) ) 16316 #define txMouseX(...) ( _txLocCurSet(), txMouseX (__VA_ARGS__) ) 16317 #define txMouseY(...) ( _txLocCurSet(), txMouseY (__VA_ARGS__) ) 16318 #define txNotifyIcon(...) ( _txLocCurSet(), txNotifyIcon (__VA_ARGS__) ) 16319 #define txOK(...) ( _txLocCurSet(), txOK (__VA_ARGS__) ) 16320 #define txOutputDebugPrintf(...) ( _txLocCurSet(), txOutputDebugPrintf (__VA_ARGS__) ) 16321 #define txPause(...) ( _txLocCurSet(), txPause (__VA_ARGS__) ) 16322 #define txPie(...) ( _txLocCurSet(), txPie (__VA_ARGS__) ) 16323 #define txPixel(...) ( _txLocCurSet(), txPixel (__VA_ARGS__) ) 16324 #define txPlaySound(...) ( _txLocCurSet(), txPlaySound (__VA_ARGS__) ) 16325 #define txPlayVideo(...) ( _txLocCurSet(), txPlayVideo (__VA_ARGS__) ) 16326 #define txPolygon(...) ( _txLocCurSet(), txPolygon (__VA_ARGS__) ) 16327 #define txPrintf(...) ( _txLocCurSet(), txPrintf (__VA_ARGS__) ) 16328 #define txQueryPerformance(...) ( _txLocCurSet(), txQueryPerformance (__VA_ARGS__) ) 16329 #define txRectangle(...) ( _txLocCurSet(), txRectangle (__VA_ARGS__) ) 16330 #define txRedrawWindow(...) ( _txLocCurSet(), txRedrawWindow (__VA_ARGS__) ) 16331 #define txRegisterClass(...) ( _txLocCurSet(), txRegisterClass (__VA_ARGS__) ) 16332 #define txRegQuery(...) ( _txLocCurSet(), txRegQuery (__VA_ARGS__) ) 16333 #define txReopenStdio(...) ( _txLocCurSet(), txReopenStdio (__VA_ARGS__) ) 16334 #define txRGB2HSL(...) ( _txLocCurSet(), txRGB2HSL (__VA_ARGS__) ) 16335 #define txSaveImage(...) ( _txLocCurSet(), txSaveImage (__VA_ARGS__) ) 16336 #define txSelectFont(...) ( _txLocCurSet(), txSelectFont (__VA_ARGS__) ) 16337 #define txSelectObject(...) ( _txLocCurSet(), txSelectObject (__VA_ARGS__) ) 16338 #define txSetColor(...) ( _txLocCurSet(), txSetColor (__VA_ARGS__) ) 16339 #define txSetConsoleAttr(...) ( _txLocCurSet(), txSetConsoleAttr (__VA_ARGS__) ) 16340 #define txSetConsoleCursorPos(...) ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) ) 16341 #define txSetDefaults(...) ( _txLocCurSet(), txSetDefaults (__VA_ARGS__) ) 16342 #define txSetFillColor(...) ( _txLocCurSet(), txSetFillColor (__VA_ARGS__) ) 16343 #define txSetLocale(...) ( _txLocCurSet(), txSetLocale (__VA_ARGS__) ) 16344 #define txSetPixel(...) ( _txLocCurSet(), txSetPixel (__VA_ARGS__) ) 16345 #define txSetProgress(...) ( _txLocCurSet(), txSetProgress (__VA_ARGS__) ) 16346 #define txSetTextAlign(...) ( _txLocCurSet(), txSetTextAlign (__VA_ARGS__) ) 16347 #define txSetWindowsHook(...) ( _txLocCurSet(), txSetWindowsHook (__VA_ARGS__) ) 16348 #define txSleep(...) ( _txLocCurSet(), txSleep (__VA_ARGS__) ) 16349 #define txSpeak(...) ( _txLocCurSet(), txSpeak (__VA_ARGS__) ) 16350 #define txTextCursor(...) ( _txLocCurSet(), txTextCursor (__VA_ARGS__) ) 16351 #define txTextOut(...) ( _txLocCurSet(), txTextOut (__VA_ARGS__) ) 16352 #define txTransparentBlt(...) ( _txLocCurSet(), txTransparentBlt (__VA_ARGS__) ) 16353 #define txTriangle(...) ( _txLocCurSet(), txTriangle (__VA_ARGS__) ) 16354 #define txUnlock(...) ( _txLocCurSet(), txUnlock (__VA_ARGS__) ) 16355 #define txUpdateWindow(...) ( _txLocCurSet(), txUpdateWindow (__VA_ARGS__) ) 16356 #define txUseAlpha(...) ( _txLocCurSet(), txUseAlpha (__VA_ARGS__) ) 16357 #define txVersion(...) ( _txLocCurSet(), txVersion (__VA_ARGS__) ) 16358 #define txVersionNumber(...) ( _txLocCurSet(), txVersionNumber (__VA_ARGS__) ) 16359 #define txWindow(...) ( _txLocCurSet(), txWindow (__VA_ARGS__) ) 16360 #define tx_fpreset(...) ( _txLocCurSet(), tx_fpreset (__VA_ARGS__) ) 16361 #define tx_glGetError(...) ( _txLocCurSet(), tx_glGetError (__VA_ARGS__) ) 16362 #define _txDump(...) ( _txLocCurSet(), _txDump (__VA_ARGS__) ) 16363 #define _txStackBackTrace(...) ( _txLocCurSet(), _txStackBackTrace (__VA_ARGS__) ) 16364 16365 #endif 16366 16367 //} 16368 //================================================================================================================= 16369 16371 //} 16372 //================================================================================================================= 16373 16374 //----------------------------------------------------------------------------------------------------------------- 16375 //{ The namespaces 16376 //----------------------------------------------------------------------------------------------------------------- 16377 16380 _TX_END_NAMESPACE 16381 16384 using namespace TX; // Allow easy usage of TXLib functions 16385 16386 using ::std::cin; // Predefined usings to avoid "using namespace std" 16387 using ::std::cout; 16388 using ::std::cerr; 16389 using ::std::string; 16390 using ::std::wcin; 16391 using ::std::wcout; 16392 using ::std::wcerr; 16393 using ::std::wstring; 16394 16395 //} 16396 //----------------------------------------------------------------------------------------------------------------- 16397 16398 //----------------------------------------------------------------------------------------------------------------- 16399 //{ Compiler- and platform-specific 16400 // Адаптация к компиляторам и платформам 16401 //----------------------------------------------------------------------------------------------------------------- 16403 16404 #if defined (_GCC_VER) 16405 16406 #pragma GCC optimize "strict-aliasing" 16407 16408 #pragma GCC pop_options 16409 #pragma GCC diagnostic pop 16410 16411 #endif 16412 16413 #if defined (_CLANG_VER) 16414 16415 #pragma clang diagnostic pop 16416 16417 #endif 16418 16419 //----------------------------------------------------------------------------------------------------------------- 16420 16421 #if defined (_MSC_VER) 16422 16423 #pragma warning (pop) // Restoring maximum level 16424 16425 #endif 16426 16427 #if defined (__INTEL_COMPILER) 16428 16429 #pragma warning (default: 174) // Remark: expression has no effect 16430 #pragma warning (default: 304) // Remark: access control not specified ("public" by default) 16431 #pragma warning (default: 444) // Remark: destructor for base class "..." is not virtual 16432 #pragma warning (default: 522) // Remark: function redeclared "inline" after being called 16433 #pragma warning (default: 1684) // Conversion from pointer to same-sized integral type (potential portability problem) 16434 16435 #pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order 16436 16437 #endif 16438 16440 //} 16441 //----------------------------------------------------------------------------------------------------------------- 16442 16443 #endif // __TXLIB_H_INCLUDED 16444 16445 //================================================================================================================= 16446 // EOF 16447 //================================================================================================================= 16448 16449 16450 16451 16452 16453 16454 16455 16456 16457 16458 16459 16460 16461 16462 16463 16464 16465 16466 16467 16468 16469 16470 16471 16472 16473 16474 16475 16476 16477 16478 16479 16480 16481 16482 16483 16484 16485 16486 16487 16488 16489 16490 16491 16492 16493 16494 16495 16496 16497 16498 16499