![]() |
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-08-17 06:00:49 +0400 $] 00005 // [Best viewed with "Fold all on file open" option enabled] [Best screen/page width = 120 chars] 00006 // 00007 // [If RUSSIAN CHARS below are UNREADABLE, check this file codepage. It should be CP1251, NOT UTF-8 etc.] 00008 //{ [Use RELOAD options in your IDE or editor (CLion / Visual Studio Code / ...), and do NOT use Convert.] 00009 //================================================================================================================= 00102 // $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $ 00103 //----------------------------------------------------------------------------------------------------------------- 00110 //} 00111 //================================================================================================================= 00112 00113 #if !defined (__TXLIB_H_INCLUDED) // <<< THE CODE IS HERE, UNFOLD IT <<< 00114 #define __TXLIB_H_INCLUDED 00115 00116 //----------------------------------------------------------------------------------------------------------------- 00117 //{ Version information and configuration 00118 //----------------------------------------------------------------------------------------------------------------- 00119 00120 //{---------------------------------------------------------------------------------------------------------------- 00142 //}---------------------------------------------------------------------------------------------------------------- 00144 00145 #define _TX_VER _TX_v_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-08-17 06:00:49 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00146 #define _TX_VERSION _TX_V_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-08-17 06:00:49 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00147 #define _TX_AUTHOR _TX_A_FROM_CVS ($VersionInfo: , TXLib.h, 00173a, 174, 2025-08-17 06:00:49 +0400, "Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru>", $) 00148 00150 #define _TX_v_FROM_CVS(_1,file,ver,rev,date,auth,_2) ((0x##ver##u << 16) | 0x##rev##u) 00151 #define _TX_V_FROM_CVS(_1,file,ver,rev,date,auth,_2) "TXLib [Ver: " #ver ", Rev: " #rev ", Date: " #date "]" 00152 #define _TX_A_FROM_CVS(_1,file,ver,rev,date,auth,_2) "Copyright (C) " auth 00153 00154 00156 //{---------------------------------------------------------------------------------------------------------------- 00163 //}---------------------------------------------------------------------------------------------------------------- 00164 00165 #if !defined (_TX_MODULE) 00166 #define _TX_MODULE "TXLib" 00167 #endif 00168 00169 //{---------------------------------------------------------------------------------------------------------------- 00173 //}---------------------------------------------------------------------------------------------------------------- 00174 00175 #if defined (__GNUC__) 00176 00177 #define _GCC_VER ( __GNUC__*100 + __GNUC_MINOR__*10 + __GNUC_PATCHLEVEL__ ) 00178 00179 #define __TX_COMPILER__ "GNU g++ " TX_QUOTE (__GNUC__) "." \ 00180 TX_QUOTE (__GNUC_MINOR__) "." \ 00181 TX_QUOTE (__GNUC_PATCHLEVEL__) \ 00182 ", std=" TX_QUOTE (__cplusplus) 00183 00184 #elif defined (__clang__) || defined (__clang_major__) 00185 00186 #define _CLANG_VER ( __clang_major__*100 + __clang_minor__*10 + __clang_patchlevel__ ) 00187 00188 #define __TX_COMPILER__ "Clang " TX_QUOTE (__clang_major__) "." \ 00189 TX_QUOTE (__clang_minor__) "." \ 00190 TX_QUOTE (__clang_patchlevel__) \ 00191 ", std=" TX_QUOTE (__cplusplus) 00192 #elif defined (_MSC_VER) 00193 00194 #define __TX_COMPILER__ "MSVS " TX_QUOTE (_MSC_VER) \ 00195 ", std=" TX_QUOTE (__cplusplus) 00196 00197 #elif defined (__INTEL_COMPILER) 00198 00199 #define __TX_COMPILER__ "Intel C++ " TX_QUOTE (__INTEL_COMPILER) \ 00200 ", std=" TX_QUOTE (__cplusplus) 00201 #else 00202 00203 #define __TX_COMPILER__ "Unknown C++, std=" TX_QUOTE (__cplusplus) 00204 #endif 00205 00207 00208 #define TX_QUOTE(sym) _TX_QUOTE (sym) 00209 #define _TX_QUOTE(sym) #sym 00210 00211 #define TX_JOIN(sym1, sym2) _TX_JOIN (sym1, sym2) 00212 #define _TX_JOIN(sym1, sym2) sym1 ## sym2 00213 00215 00216 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 00217 00218 #define _TX_CPP11 1 00219 #endif 00220 00221 #if (__cplusplus >= 201103L) || defined (_MSC_VER) && (_MSC_VER >= 1900) // MSVC 2015 00222 00223 #define _TX_CPP11_MSVC15 1 00224 #endif 00225 00226 //{---------------------------------------------------------------------------------------------------------------- 00230 //}---------------------------------------------------------------------------------------------------------------- 00231 00232 #if !defined (NDEBUG) && defined (_DEBUG) 00233 #define _TX_BUILDMODE "DEBUG" 00234 00235 #elif !defined (NDEBUG) && !defined (_DEBUG) 00236 #define _TX_BUILDMODE "Debug" 00237 00238 #elif defined (NDEBUG) 00239 #define _TX_BUILDMODE "Release" 00240 #endif 00241 00242 //{---------------------------------------------------------------------------------------------------------------- 00246 //}---------------------------------------------------------------------------------------------------------------- 00247 00248 #define __TX_FILELINE__ __FILE__ ":" TX_QUOTE (__LINE__) 00249 00250 //{---------------------------------------------------------------------------------------------------------------- 00258 //}---------------------------------------------------------------------------------------------------------------- 00259 00260 #if defined (__GNUC__) || defined (__clang__) || defined (__clang_major__) 00261 #define __TX_FUNCTION__ __PRETTY_FUNCTION__ 00262 00263 #elif defined (__FUNCSIG__) 00264 #define __TX_FUNCTION__ __FUNCSIG__ 00265 00266 #elif defined (__FUNCTION__) 00267 #define __TX_FUNCTION__ __FUNCTION__ 00268 00269 #elif defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 600) 00270 #define __TX_FUNCTION__ __FUNCTION__ 00271 00272 #elif defined (__BORLANDC__) && (__BORLANDC__ >= 0x550) 00273 #define __TX_FUNCTION__ __FUNC__ 00274 00275 #elif defined (__cplusplus) && (__cplusplus >= 199711L) 00276 #define __TX_FUNCTION__ __func__ 00277 00278 #elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 00279 #define __TX_FUNCTION__ __func__ 00280 00281 #elif defined (__PYTHON__) 00282 #error No Python. No. Using parseltongue languages can lead you to Slytherin. 00283 00284 #else 00285 #define __TX_FUNCTION__ "(" __TX_FILELINE__ ")" 00286 00287 #endif 00288 00289 #if !defined (__func__) && defined (__FUNCTION__) 00290 #define __func__ __FUNCTION__ 00291 00292 #endif 00293 00294 //} 00295 //----------------------------------------------------------------------------------------------------------------- 00296 00297 //----------------------------------------------------------------------------------------------------------------- 00298 //{ Compiler- and platform-specific 00300 //----------------------------------------------------------------------------------------------------------------- 00302 00303 #if !defined (__cplusplus) 00304 00305 #ifdef __GNUC__ 00306 #error 00307 #error --------------------------------------------------------------------------------------- 00308 #endif 00309 #error TXLib.h: Must use C++ to compile TXLib.h. Now you are using C only. 00310 #error 00311 #error CHECK source file EXTENSION. Maybe it is ".C". It must be ".CPP". 00312 #error If your file is named, for example, "Untitled.C", go to menu [File], 00313 #error then [Save As] and rename it to "Untitled.CPP". Please do NOT use spaces. 00314 #error --------------------------------------------------------------------------------------- 00315 #error 00316 00317 #endif 00318 00319 //----------------------------------------------------------------------------------------------------------------- 00320 00321 #if !defined (WIN32) && !defined (__WIN32__) && !defined(_WIN32) && !defined(_WIN32_WINNT) && !defined (__CYGWIN__) 00322 00323 #ifdef __GNUC__ 00324 #error 00325 #error --------------------------------------------------------------------------------------- 00326 #endif 00327 #error TXLib.h: Windows (MSVC/Win32 or GCC/MinGW or Cygwin) is the only supported OS, sorry. 00328 #error 00329 #error In Linux or MacOS, you should write your own TXLib and share it with your friends, or use wine. 00330 #error --------------------------------------------------------------------------------------- 00331 #error 00332 00333 #endif 00334 00335 //----------------------------------------------------------------------------------------------------------------- 00336 00337 #if defined (UNICODE) || defined (_UNICODE) 00338 00339 #ifdef __GNUC__ 00340 #warning TXLib.h: Disabling the UNICODE 00341 #endif 00342 00343 #undef UNICODE // Burn Unicode, burn 00344 #undef _UNICODE 00345 00346 #if defined (_WINDOWS_H) || defined (_INC_WINDOWS) || defined (_WINDOWS_) || defined (__WINDOWS__) 00347 00348 #ifdef __GNUC__ 00349 #error 00350 #error --------------------------------------------------------------------------------------- 00351 #endif 00352 #error TXLib.h: Should include "TXLib.h" BEFORE or INSTEAD of <Windows.h> in UNICODE mode. 00353 #error 00354 #error REARRANGE your #include directives, or DISABLE the UNICODE mode by #undef UNICODE/_UNICODE. 00355 #error --------------------------------------------------------------------------------------- 00356 #error 00357 00358 #endif 00359 00360 #endif 00361 00362 //----------------------------------------------------------------------------------------------------------------- 00363 00364 #if defined (__STRICT_ANSI__) && (_GCC_VER < 1120) // Try to extend strict ANSI rules 00365 00366 #undef __STRICT_ANSI__ 00367 #define __STRICT_ANSI__UNDEFINED 00368 00369 #if defined (_STRING_H_) || defined (_INC_STRING) || defined (_STDIO_H_) || defined (_INC_STDIO) 00370 00371 #ifdef __GNUC__ 00372 #error 00373 #error --------------------------------------------------------------------------------------- 00374 #endif 00375 #error TXLib.h: Should include "TXLib.h" BEFORE <string.h> or <stdio.h> in Strict ANSI mode. 00376 #error 00377 #error REARRANGE your #include directives, or DISABLE ANSI-compliancy by #undef __STRICT_ANSI__. 00378 #error --------------------------------------------------------------------------------------- 00379 #error 00380 00381 #endif 00382 00383 #endif 00384 00385 //----------------------------------------------------------------------------------------------------------------- 00386 00387 #if defined (__GNUC__) && !defined (__clang__) 00388 00389 #pragma GCC diagnostic ignored "-Wpragmas" 00390 00391 #pragma GCC diagnostic warning "-Wall" 00392 #pragma GCC diagnostic warning "-Weffc++" 00393 #pragma GCC diagnostic warning "-Wextra" 00394 00395 #pragma GCC diagnostic warning "-Waggressive-loop-optimizations" 00396 #pragma GCC diagnostic warning "-Walloc-zero" 00397 #pragma GCC diagnostic warning "-Walloca" 00398 #pragma GCC diagnostic warning "-Walloca-larger-than=8192" 00399 #pragma GCC diagnostic warning "-Warray-bounds" 00400 #pragma GCC diagnostic warning "-Wcast-align" 00401 #pragma GCC diagnostic warning "-Wcast-qual" 00402 #pragma GCC diagnostic warning "-Wchar-subscripts" 00403 #pragma GCC diagnostic warning "-Wconditionally-supported" 00404 #pragma GCC diagnostic warning "-Wconversion" 00405 #pragma GCC diagnostic warning "-Wctor-dtor-privacy" 00406 #pragma GCC diagnostic warning "-Wdangling-else" 00407 #pragma GCC diagnostic warning "-Wduplicated-branches" 00408 #pragma GCC diagnostic warning "-Wempty-body" 00409 #pragma GCC diagnostic warning "-Wfloat-equal" 00410 #pragma GCC diagnostic warning "-Wformat-nonliteral" 00411 #pragma GCC diagnostic warning "-Wformat-overflow=2" 00412 #pragma GCC diagnostic warning "-Wformat-security" 00413 #pragma GCC diagnostic warning "-Wformat-signedness" 00414 #pragma GCC diagnostic warning "-Wformat-truncation=2" 00415 #pragma GCC diagnostic warning "-Wformat=2" 00416 #pragma GCC diagnostic warning "-Wlarger-than=8192" 00417 #pragma GCC diagnostic warning "-Wlogical-op" 00418 #pragma GCC diagnostic warning "-Wmismatched-tags" 00419 #pragma GCC diagnostic warning "-Wmissing-declarations" 00420 #pragma GCC diagnostic warning "-Wnarrowing" 00421 #pragma GCC diagnostic warning "-Wnon-virtual-dtor" 00422 #pragma GCC diagnostic warning "-Wnonnull" 00423 #pragma GCC diagnostic warning "-Wopenmp-simd" 00424 #pragma GCC diagnostic warning "-Woverloaded-virtual" 00425 #pragma GCC diagnostic warning "-Wpacked" 00426 #pragma GCC diagnostic warning "-Wpointer-arith" 00427 #pragma GCC diagnostic warning "-Wredundant-decls" 00428 #pragma GCC diagnostic warning "-Wredundant-tags" 00429 #pragma GCC diagnostic warning "-Wrestrict" 00430 #pragma GCC diagnostic warning "-Wshadow" 00431 #pragma GCC diagnostic warning "-Wsign-promo" 00432 #pragma GCC diagnostic warning "-Wstack-usage=8192" 00433 #pragma GCC diagnostic warning "-Wstrict-aliasing" 00434 #pragma GCC diagnostic warning "-Wstrict-null-sentinel" 00435 #pragma GCC diagnostic warning "-Wstrict-overflow=2" 00436 #pragma GCC diagnostic warning "-Wstringop-overflow=4" 00437 #pragma GCC diagnostic warning "-Wsuggest-attribute=noreturn" 00438 #pragma GCC diagnostic warning "-Wsuggest-final-methods" 00439 #pragma GCC diagnostic warning "-Wsuggest-final-types" 00440 #pragma GCC diagnostic warning "-Wsuggest-override" 00441 #pragma GCC diagnostic warning "-Wswitch-default" 00442 #pragma GCC diagnostic warning "-Wswitch-enum" 00443 #pragma GCC diagnostic warning "-Wsync-nand" 00444 #pragma GCC diagnostic warning "-Wundef" 00445 #pragma GCC diagnostic warning "-Wunused" 00446 #pragma GCC diagnostic warning "-Wvarargs" 00447 #pragma GCC diagnostic warning "-Wvla-larger-than=8192" 00448 00449 #pragma GCC diagnostic error "-Wsizeof-array-argument" 00450 00451 #pragma GCC diagnostic ignored "-Waddress" 00452 #pragma GCC diagnostic ignored "-Winline" 00453 #pragma GCC diagnostic ignored "-Wliteral-suffix" 00454 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 00455 #pragma GCC diagnostic ignored "-Wnonnull-compare" 00456 #pragma GCC diagnostic ignored "-Wold-style-cast" 00457 #pragma GCC diagnostic ignored "-Wunreachable-code" 00458 #pragma GCC diagnostic ignored "-Wunused-const-variable" 00459 #pragma GCC diagnostic ignored "-Wunused-function" 00460 #pragma GCC diagnostic ignored "-Wvariadic-macros" 00461 00462 #pragma GCC diagnostic warning "-Wpragmas" 00463 00464 //{ These warning settings for TXLib.h only and will be re-enabled at end of file: 00465 00466 #pragma GCC push_options 00467 #pragma GCC diagnostic push 00468 00469 #pragma GCC diagnostic ignored "-Wpragmas" 00470 00471 #pragma GCC diagnostic ignored "-Wpedantic" 00472 #pragma GCC diagnostic ignored "-Waddress" 00473 #pragma GCC diagnostic ignored "-Warray-bounds" 00474 #pragma GCC diagnostic ignored "-Wclobbered" 00475 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00476 #pragma GCC diagnostic ignored "-Wfloat-equal" 00477 #pragma GCC diagnostic ignored "-Wformat-nonliteral" 00478 #pragma GCC diagnostic ignored "-Wlarger-than=" 00479 #pragma GCC diagnostic ignored "-Wmisleading-indentation" 00480 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 00481 #pragma GCC diagnostic ignored "-Wredundant-decls" 00482 #pragma GCC diagnostic ignored "-Wshadow" 00483 #pragma GCC diagnostic ignored "-Wsign-conversion" 00484 #pragma GCC diagnostic ignored "-Wstrict-aliasing" 00485 #pragma GCC diagnostic ignored "-Wsuggest-override" 00486 #pragma GCC diagnostic ignored "-Wunused-label" // Just for fun in _txCanvas_OnCmdAbout() 00487 #pragma GCC diagnostic ignored "-Wunused-value" 00488 #pragma GCC diagnostic ignored "-Wformat-zero-length" 00489 #pragma GCC diagnostic ignored "-Wpacked-not-aligned" 00490 #pragma GCC optimize "no-strict-aliasing" 00491 00492 #pragma GCC diagnostic warning "-Wpragmas" 00493 00494 #if defined (__CYGWIN__) && !defined (_TX_TESTING) 00495 #pragma GCC system_header // This is not a fair play, but this is the only way to deal with Cygwin :( 00496 #endif 00497 00498 //} 00499 00500 #define _tx_thread __thread 00501 #define _tx_decltype(value) __decltype (value) 00502 00503 #define _FORTIFY_SOURCE 2 00504 00505 #ifndef MINGW_HAS_SECURE_API 00506 #define MINGW_HAS_SECURE_API 1 00507 #endif 00508 00509 #if defined (TX_USE_SFML) 00510 #define _GLIBCXX_NDEBUG 00511 #endif 00512 00513 #ifndef _GLIBCXX_NDEBUG // TXLib enables _GLIBCXX_DEBUG by default. When using third-party libraries 00514 #define _GLIBCXX_DEBUG // compiled without _GLIBCXX_DEBUG (SFML, for example), #define _GLIBCXX_NDEBUG 00515 #define _GLIBCXX_DEBUG_PEDANTIC // *before* including TXLib.h. 00516 #endif 00517 00518 #if defined (_WIN64) // removed in x86 because printf ("%g", double) failure, this prints 0 always 00519 #ifndef __USE_MINGW_ANSI_STDIO 00520 #define __USE_MINGW_ANSI_STDIO 1 00521 #endif 00522 #endif 00523 00524 template <typename T> 00525 inline T _txNOP (T value) { return value; } // To suppress performance warnings in assert etc. 00526 00527 // From MinGW\include\float.h which is replaced by MinGW\lib\gcc\i686-pc-mingw32\x.x.x\include\float.h 00528 extern "C" __declspec (dllimport) unsigned __cdecl _controlfp (unsigned control, unsigned mask); 00529 extern "C" void __cdecl _fpreset (); 00530 00531 #else 00532 00533 #define __attribute__( attr ) 00534 #define _txNOP( value ) ( value ) 00535 00536 #endif 00537 00538 //----------------------------------------------------------------------------------------------------------------- 00539 00540 #if defined (__clang__) || defined (__clang_major__) 00541 00542 #pragma clang diagnostic ignored "-Wunknown-pragmas" 00543 00544 #pragma clang diagnostic warning "-Wall" 00545 #pragma clang diagnostic warning "-Weffc++" 00546 #pragma clang diagnostic warning "-Wextra" 00547 00548 #pragma clang diagnostic warning "-Wcast-qual" 00549 #pragma clang diagnostic warning "-Wchar-subscripts" 00550 #pragma clang diagnostic warning "-Wconversion" 00551 #pragma clang diagnostic warning "-Wctor-dtor-privacy" 00552 #pragma clang diagnostic warning "-Wempty-body" 00553 #pragma clang diagnostic warning "-Wfloat-equal" 00554 #pragma clang diagnostic warning "-Wformat" 00555 #pragma clang diagnostic warning "-Wformat-nonliteral" 00556 #pragma clang diagnostic warning "-Wformat-security" 00557 #pragma clang diagnostic warning "-Wmissing-declarations" 00558 #pragma clang diagnostic warning "-Wnon-virtual-dtor" 00559 #pragma clang diagnostic warning "-Woverloaded-virtual" 00560 #pragma clang diagnostic warning "-Wpacked" 00561 #pragma clang diagnostic warning "-Wpointer-arith" 00562 #pragma clang diagnostic warning "-Wredundant-decls" 00563 #pragma clang diagnostic warning "-Wshadow" 00564 #pragma clang diagnostic warning "-Wsign-promo" 00565 #pragma clang diagnostic warning "-Wstrict-aliasing" 00566 #pragma clang diagnostic warning "-Wstrict-overflow" 00567 #pragma clang diagnostic warning "-Wswitch-default" 00568 #pragma clang diagnostic warning "-Wswitch-enum" 00569 #pragma clang diagnostic warning "-Wunused" 00570 00571 #pragma clang diagnostic ignored "-Winvalid-source-encoding" 00572 #pragma clang diagnostic ignored "-Wunused-const-variable" 00573 #pragma clang diagnostic ignored "-Wunused-variable" 00574 00575 #pragma clang diagnostic warning "-Wunknown-pragmas" 00576 00577 //{ These warning settings for TXLib.h only and will be re-enabled at end of file: 00578 00579 #pragma clang diagnostic push 00580 00581 #pragma clang diagnostic ignored "-Wunknown-pragmas" 00582 00583 #pragma clang diagnostic ignored "-Wpedantic" 00584 #pragma clang diagnostic ignored "-Wcast-align" 00585 #pragma clang diagnostic ignored "-Wfloat-conversion" 00586 #pragma clang diagnostic ignored "-Wmicrosoft-cast" 00587 #pragma clang diagnostic ignored "-Wmisleading-indentation" 00588 #pragma clang diagnostic ignored "-Wmissing-braces" 00589 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 00590 #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 00591 #pragma clang diagnostic ignored "-Wsign-compare" 00592 #pragma clang diagnostic ignored "-Wsign-conversion" 00593 #pragma clang diagnostic ignored "-Wstring-plus-int" 00594 #pragma clang diagnostic ignored "-Wundef" 00595 #pragma clang diagnostic ignored "-Wundefined-bool-conversion" 00596 #pragma clang diagnostic ignored "-Wunused-function" 00597 #pragma clang diagnostic ignored "-Wunused-value" 00598 #pragma clang diagnostic ignored "-Wvariadic-macros" 00599 00600 #pragma clang diagnostic warning "-Wunknown-pragmas" 00601 00602 //{ CLang-Tidy options 00603 // 00604 // *,-cert-dcl50-cpp,-cert-dcl58-cpp,-cert-err52-cpp,-cert-err58-cpp,-cert-flp30-c,-cert-msc30-c,-cert-msc32-c, 00605 // -cert-msc50-cpp,-cert-msc51-cpp,-clang-analyzer-core.DivideZero,-cppcoreguidelines-avoid-c-arrays, 00606 // -cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage, 00607 // -cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-no-malloc, 00608 // -cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic, 00609 // -cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access, 00610 // -cppcoreguidelines-pro-type-vararg,-fuchsia-default-arguments-calls,-fuchsia-default-arguments-declarations, 00611 // -fuchsia-overloaded-operator,-google-build-using-namespace,-google-global-names-in-headers,-google-runtime-int, 00612 // -google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments, 00613 // -hicpp-avoid-c-arrays,-hicpp-avoid-goto,-hicpp-braces-around-statements,-hicpp-deprecated-headers,-hicpp-no-array-decay, 00614 // -hicpp-signed-bitwise,-hicpp-use-equals-delete,-hicpp-use-nullptr,-hicpp-vararg,-llvm-include-order,-hicpp-no-malloc, 00615 // -llvm-namespace-comment,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-use-auto, 00616 // -modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-use-default-member-init,-hicpp-use-auto, 00617 // -modernize-use-equals-delete,-modernize-use-nullptr,-modernize-use-trailing-return-type,-modernize-use-using, 00618 // -readability-braces-around-statements,-readability-else-after-return,-readability-implicit-bool-conversion, 00619 // -readability-isolate-declaration,-readability-magic-numbers,-readability-named-parameter,-modernize-loop-convert 00620 //} 00621 00622 //} 00623 00624 #endif 00625 00626 //----------------------------------------------------------------------------------------------------------------- 00627 00628 #if defined (_MSC_VER) 00629 00630 #pragma warning (push, 4) // Set maximum warning level. This 'push' is to set the level only. It will NOT be popped. 00631 00632 #pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning 00633 00634 #pragma warning (disable: 4514) // Unreferenced inline function has been removed 00635 #pragma warning (disable: 4710) // Function not inlined 00636 #pragma warning (disable: 4786) // Identifier was truncated to '255' characters in the debug information 00637 00638 #pragma warning (error: 4715) // Not all control paths return a value 00639 00640 #pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665 00641 00642 #pragma warning (disable: 26473) // Don't cast between pointer types where the source type and the target type are the same (type.1). 00643 #pragma warning (disable: 26475) // Do not use function style C-casts (es.49). 00644 #pragma warning (disable: 26477) // Use 'nullptr' rather than 0 or NULL (es.47). 00645 #pragma warning (disable: 26481) // Don't use pointer arithmetic. Use span instead (bounds.1). 00646 #pragma warning (disable: 26826) // Don't use C-style variable arguments (f.55). 00647 00648 // These warning settings for TXLib.h only and will be re-enabled at end of file: 00649 00650 #pragma warning (push) 00651 00652 #pragma warning (disable: 4616) // #pragma warning: warning number 'n' not a valid compiler warning 00653 00654 #pragma warning (disable: 4091) // 'typedef': ignored on left of '...' when no variable is declared 00655 #pragma warning (disable: 4124) // Using __fastcall with stack checking is ineffective 00656 #pragma warning (disable: 4127) // Conditional expression is constant 00657 #pragma warning (disable: 4200) // Nonstandard extension used: zero-sized array in struct/union 00658 #pragma warning (disable: 4201) // Nonstandard extension used: nameless struct/union 00659 #pragma warning (disable: 4351) // New behavior: elements of array will be default initialized 00660 #pragma warning (disable: 4480) // Nonstandard extension used: specifying underlying type for enum 'type' 00661 #pragma warning (disable: 4481) // Nonstandard extension used: override specifier 'override' 00662 #pragma warning (disable: 4555) // Result of expression not used 00663 #pragma warning (disable: 4611) // Interaction between '_setjmp' and C++ object destruction is non-portable 00664 #pragma warning (disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified 00665 #pragma warning (disable: 6269) // Possibly incorrect order of operations: dereference ignored 00666 #pragma warning (disable: 6285) // (<non-zero constant>) || (<non-zero constant>) is always a non-zero constant. Did you intend to use bitwize-and operator? 00667 #pragma warning (disable: 6319) // Use of the comma-operator in a tested expression causes the left argument to be ignored when it has no side-effects 00668 #pragma warning (disable: 6326) // Potential comparison of a constant with another constant 00669 #pragma warning (disable: 6553) // The annotation for function 'func' on _Param_(N) does not apply to a value type. 00670 #pragma warning (disable: 26135) // Missing locking annotation 00671 #pragma warning (disable: 26400) // Do not assign the result of an allocation or a function call with an owner<T> return value to a raw pointer, use owner<T> instead (i.11). 00672 #pragma warning (disable: 26401) // Do not delete a raw pointer that is not an owner<T> (i.11). 00673 #pragma warning (disable: 26403) // Reset or explicitly delete an owner<T> pointer 'name' (r.3). 00674 #pragma warning (disable: 26408) // Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10). 00675 #pragma warning (disable: 26409) // Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11). 00676 #pragma warning (disable: 26426) // Global initializer calls a non-constexpr function 'name' (i.22). 00677 #pragma warning (disable: 26429) // Symbol 'name' is never tested for nullness, it can be marked as not_null (f.23). 00678 #pragma warning (disable: 26430) // Symbol 'name' is not tested for nullness on all paths (f.23). 00679 #pragma warning (disable: 26432) // If you define or delete any default operation in the type 'struct 'name'', define or delete them all (c.21). 00680 #pragma warning (disable: 26435) // Function 'name' should specify exactly one of 'virtual', 'override', or 'final' (c.128). 00681 #pragma warning (disable: 26438) // Avoid 'goto' (es.76). 00682 #pragma warning (disable: 26440) // Function 'name' can be declared 'noexcept' (f.6). 00683 #pragma warning (disable: 26446) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4). 00684 #pragma warning (disable: 26447) // The function is declared 'noexcept' but calls function 'func' which may throw exceptions (f.6). 00685 #pragma warning (disable: 26448) // Consider using gsl::finally if final action is intended (gsl.util). 00686 #pragma warning (disable: 26451) // Arithmetic overflow: Using operator 'op' on a n-byte value and then casting the result to a m-byte value. Cast the value to the wider type before calling operator 'op' to avoid overflow (io.2). 00687 #pragma warning (disable: 26455) // Default constructor may not throw. Declare it 'noexcept' (f.6). 00688 #pragma warning (disable: 26457) // (void) should not be used to ignore return values, use 'std::ignore =' instead (es.48) 00689 #pragma warning (disable: 26460) // The reference argument 'stream' for function 'name' can be marked as const (con.3). 00690 #pragma warning (disable: 26461) // The pointer argument 'name' for function 'name' can be marked as a pointer to const (con.3). 00691 #pragma warning (disable: 26462) // The value pointed to by 'name' is assigned only once, mark it as a pointer to const (con.4). 00692 #pragma warning (disable: 26482) // Only index into arrays using constant expressions (bounds.2). 00693 #pragma warning (disable: 26483) // Value 'value' is outside the bounds (min, max) of variable 'name'. Only index into arrays using constant expressions that are within bounds of the array (bounds.2). 00694 #pragma warning (disable: 26485) // Expression 'expr': No array to pointer decay (bounds.3). 00695 #pragma warning (disable: 26486) // Don't pass a pointer that may be invalid to a function. Parameter 'n' 'name' in call to 'name' may be invalid (lifetime.3). 00696 #pragma warning (disable: 26487) // Don't return a pointer 'name' that may be invalid (lifetime.4). 00697 #pragma warning (disable: 26488) // Do not dereference a potentially null pointer: 'name'. 'name' was null at line 'n' (lifetime.1). 00698 #pragma warning (disable: 26489) // Don't dereference a pointer that may be invalid: 'name'. 'name' may have been invalidated at line 'n' (lifetime.1). 00699 #pragma warning (disable: 26490) // Don't use reinterpret_cast (type.1). 00700 #pragma warning (disable: 26492) // Don't use const_cast to cast away const or volatile (type.3). 00701 #pragma warning (disable: 26493) // Don't use C-style casts (type.4). 00702 #pragma warning (disable: 26496) // The variable 'name' is assigned only once, mark it as const (con.4). 00703 #pragma warning (disable: 26497) // The function 'name' could be marked constexpr if compile-time evaluation is desired (f.4). 00704 #pragma warning (disable: 26812) // The enum type 'type' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). 00705 #pragma warning (disable: 26814) // The const variable 'name' can be computed at compile-time. Consider using constexpr (con.5). 00706 #pragma warning (disable: 26822) // Dereferencing a possibly null pointer '...' (lifetime.1). 00707 #pragma warning (disable: 26823) // Dereferencing a possibly null pointer '...' (lifetime.1). 00708 #pragma warning (disable: 28125) // The function must be called from within a try/except block 00709 #pragma warning (disable: 28159) // Consider using another function instead 00710 00711 #pragma warning (default: 4616) // #pragma warning: warning number 'n' not a valid compiler warning //-V665 00712 00713 #define _tx_thread __declspec (thread) 00714 #define _tx_decltype(value) decltype (value) 00715 00716 #if !defined (_CLANG_VER) 00717 00718 #pragma setlocale ("russian") // Set source file encoding, see also _TX_CODEPAGE 00719 00720 #if !defined (NDEBUG) 00721 #pragma check_stack ( on) // Turn on stack probes at runtime 00722 #pragma strict_gs_check (push, on) // Detects stack buffer overruns 00723 #endif 00724 00725 #endif 00726 00727 #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 00728 00729 #endif 00730 00731 //----------------------------------------------------------------------------------------------------------------- 00732 00733 #if defined (__INTEL_COMPILER) 00734 00735 #pragma warning (disable: 174) // Remark: expression has no effect 00736 #pragma warning (disable: 304) // Remark: access control not specified ("public" by default) 00737 #pragma warning (disable: 444) // Remark: destructor for base class "..." is not virtual 00738 #pragma warning (disable: 522) // Remark: function "..." redeclared "inline" after being called 00739 #pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order 00740 #pragma warning (disable: 1684) // Conversion from pointer to same-sized integral type (potential portability problem) 00741 00742 #endif 00743 00744 //----------------------------------------------------------------------------------------------------------------- 00745 00746 #if (defined (_GCC_VER) && (_GCC_VER < 472) || \ 00747 defined (_MSC_VER) && (_MSC_VER < 1600)) // Minimum requirements are now GCC 4.7.2 or MSVC 10.0 (2010) 00748 00749 #ifdef __GNUC__ 00750 #error 00751 #error --------------------------------------------------------------------------------------- 00752 #endif 00753 #error TXLib.h: This version works only with GCC >= 4.7.2 or MS Visual Studio >= 2010, sorry. 00754 #error 00755 #error Please use TXLib.h previous stable version/revision OR upgrade/install proper compiler. 00756 #error --------------------------------------------------------------------------------------- 00757 #error 00758 00759 #endif 00760 00761 //----------------------------------------------------------------------------------------------------------------- 00762 00763 #if defined (_GCC_VER) && (_GCC_VER >= 492) 00764 #if defined (TX_USE_SPEAK) && !__has_include (<SAPI.h>) 00765 00766 #ifdef __GNUC__ 00767 #error 00768 #error --------------------------------------------------------------------------------------- 00769 #endif 00770 #error You have defined TX_USE_SPEAK, but your compiler do NOT have the library <SAPI.h>. 00771 #error 00772 #error Please use compiler library set with SAPI.h included. SAPI is Microsoft Speech API 00773 #error necessary for txSpeak() to work. 00774 #error --------------------------------------------------------------------------------------- 00775 #error 00776 00777 #endif 00778 #endif 00779 00780 //----------------------------------------------------------------------------------------------------------------- 00781 00782 #if !defined (WINVER) 00783 #define WINVER 0x0502 // Defaults to Windows XP 00784 #define WINDOWS_ENABLE_CPLUSPLUS // Allow use of type-limit macros in <basetsd.h>, 00785 #endif // they are allowed by default if WINVER >= 0x0600. 00786 00787 #if !defined (_WIN32_WINNT) 00788 #define _WIN32_WINNT WINVER // Defaults to the same as WINVER 00789 #endif 00790 00791 #if !defined (_WIN32_IE) 00792 #define _WIN32_IE WINVER // Defaults to the same as WINVER 00793 #endif 00794 00795 #define stristr( str1, str2 ) Win32::StrStrIA ((str1), (str2)) 00796 #define stristrw( str1, str2 ) Win32::StrStrIW ((str1), (str2)) 00797 00798 //----------------------------------------------------------------------------------------------------------------- 00799 00800 #define _USE_MATH_DEFINES 1 // Math.h's M_PI etc. 00801 #define __STDC_FORMAT_MACROS 1 // PRIu64 and other PR... macros 00802 #define __STDC_WANT_LIB_EXT1__ 1 // String and output *_s functions 00803 00804 #define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS // Wow, how long. Kudos, Clang 00805 00806 #define _ALLOW_RTCc_IN_STL 1 // MSVC C2338: /RTCc rejects conformant code, so it isn't supported by libc. 00807 00808 #define NOMINMAX 1 // Preventing 'min' and 'max' defines in Windows.h 00809 00810 #if defined (_DEBUG) 00811 #define _SECURE_SCL 1 // Enable checked STL iterators to throw an exception on incorrect use 00812 #define _HAS_ITERATOR_DEBUGGING 1 00813 #define _LIBCPP_DEBUG 1 00814 #endif 00815 00816 #if defined (_MSC_VER) && defined (_DEBUG) 00817 00818 #define _CRTDBG_MAP_ALLOC // Enable MSVCRT debug heap 00819 #define _new_dbg new (_NORMAL_BLOCK, __FILE__, __LINE__) 00820 #define NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) 00821 00822 #else 00823 #define _new_dbg new 00824 #define NEW new 00825 00826 #endif 00827 00828 #if !( defined (_MSC_VER) && (_MSC_VER < 1900) ) // MSVC 2015 00829 #define _SECURE_SCL_THROWS 1 00830 #endif 00831 00832 #define tx_noreturn __attribute__ (( noreturn )) 00833 #define tx_nodiscard __attribute__ (( warn_unused_result )) 00834 #define tx_deprecated __attribute__ (( deprecated )) 00835 #define tx_printfy( formatArgN ) __attribute__ (( format (printf, (formatArgN), (formatArgN)+1) )) 00836 #define tx_scanfy( formatArgN ) __attribute__ (( format (scanf, (formatArgN), (formatArgN)+1) )) 00837 00838 00839 #if defined (_TX_CPP11) 00840 00841 #define _tx_delete = delete 00842 #define _tx_default = default 00843 #define _tx_override override 00844 #define _tx_final final 00845 00846 #else 00847 00848 #define _tx_delete 00849 #define _tx_default 00850 #define _tx_override 00851 #define _tx_final 00852 00853 #endif 00854 00855 namespace std { enum nomeow_t { nomeow }; } // Vital addition to the C++ standard. TODO: Should contact C++ std committee. 00856 00857 //----------------------------------------------------------------------------------------------------------------- 00858 00860 //} 00861 //----------------------------------------------------------------------------------------------------------------- 00862 00863 //----------------------------------------------------------------------------------------------------------------- 00864 //{ The Includes 00865 //----------------------------------------------------------------------------------------------------------------- 00866 00867 #if defined (_MSC_VER) 00868 #pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o 00869 00870 #pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch 00871 #pragma warning (disable: 4005) // 'name': macro redefinition 00872 #endif 00873 00874 //----------------------------------------------------------------------------------------------------------------- 00875 00876 #include <stdlib.h> 00877 #include <stdio.h> 00878 #include <string.h> 00879 #include <time.h> 00880 #include <math.h> 00881 #include <float.h> 00882 00883 #include <vector> 00884 #include <string> 00885 #include <iostream> 00886 #include <sstream> 00887 #include <iomanip> 00888 00889 #if !defined (__CYGWIN__) 00890 #include <conio.h> 00891 #include <direct.h> 00892 #endif 00893 00894 #if defined (TX_COMPILED) 00895 #define WIN32_LEAN_AND_MEAN 00896 #endif 00897 00898 #include <windows.h> 00899 #include <mmsystem.h> 00900 00901 //----------------------------------------------------------------------------------------------------------------- 00902 //{ Compiler- and platform-specific 00904 //----------------------------------------------------------------------------------------------------------------- 00905 00906 #if defined (_MSC_VER) 00907 #pragma warning (pop) // MSVC: Restore max level 00908 #endif 00909 00910 #if defined (__STRICT_ANSI__UNDEFINED) 00911 #define __STRICT_ANSI__ // Redefine back 00912 #endif 00913 00914 #if !defined (_TRUNCATE) || defined (__CYGWIN__) || defined (_MEMORY_S_DEFINED) 00915 00916 #define strncpy_s( dest, sizeof_dest, src, count ) ( strncpy ((dest), (src), MIN ((count), (sizeof_dest))) ) 00917 #define wcsncpy_s( dest, sizeof_dest, src, count ) ( wcsncpy ((dest), (src), MIN ((count), (sizeof_dest))) ) 00918 #define strncat_s( dest, sizeof_dest, src, count ) ( strncat ((dest), (src), MIN ((count), (sizeof_dest))) ) 00919 #define strerror_s( buf, sizeof_buf, code ) ( strncpy ((buf), strerror ((int)(code)), (sizeof_buf)-1) ) 00920 #define strtok_s( buf, delim, ctx ) ( (void)(ctx), strtok ((buf), (delim)) ) 00921 #define fopen_s( file, name, mode ) ( *(file) = fopen ((name), (mode)) ) 00922 #define _strlwr_s( str, sizeof_str ) ( _strlwr (str) ) 00923 00924 #define ctime_s( buf, sizeof_buf, time ) ( strncpy ((buf), ctime (time), (sizeof_buf)-1) ) 00925 #define _controlfp_s( oldCtl, newCtl, mask ) ( assert (oldCtl), *(oldCtl) = _controlfp (newCtl, mask), 0 ) 00926 00927 #define _snprintf_s snprintf 00928 #define _vsnprintf_s( str, sz, trunc, format, arg ) _vsnprintf (str, sz, format, arg) 00929 00930 #endif 00931 00932 #if !( defined (_MSC_VER) || defined (__STDC_LIB_EXT1__) ) 00933 00934 #define getenv_s( sz, buf, sizeof_buf, name ) ({ (void)(sz); const char* _env = getenv (name); \ 00935 strncpy ((buf), (_env)? _env : "", (sizeof_buf)-1); }) 00936 #endif 00937 00938 #if defined (__CYGWIN__) 00939 00940 #undef __STRICT_ANSI__ 00941 00942 typedef void _exception; 00943 00944 #define _O_TEXT O_TEXT 00945 #define _fdopen fdopen 00946 #define _flushall() fflush (NULL) 00947 #define _getcwd getcwd 00948 #define _getpid getpid 00949 #define _stricmp strcasecmp 00950 #define _strlwr strlwr 00951 #define _strnicmp strncasecmp 00952 #define _unlink unlink 00953 #define _vsnprintf vsnprintf 00954 #define _access access 00955 #define _strdup strdup 00956 00957 #define getch _getch 00958 #define putch _putch 00959 #define kbhit _kbhit 00960 00961 #endif 00962 00963 #if !defined (PRId64) || \ 00964 defined (_GCC_VER) && (_GCC_VER == 492) && !defined (_WIN64) // Dev-CPP 5.11: TDM-GCC 4.9.2 MinGW64 with -m32 00965 00966 #undef PRId64 00967 #undef PRIi64 00968 #undef PRIo64 00969 #undef PRIu64 00970 #undef PRIx64 00971 #undef PRIX64 00972 00973 #define PRId64 "I64d" 00974 #define PRIi64 "I64i" 00975 #define PRIo64 "I64o" 00976 #define PRIu64 "I64u" 00977 #define PRIx64 "I64x" 00978 #define PRIX64 "I64X" 00979 00980 #endif 00981 00982 //} 00983 //----------------------------------------------------------------------------------------------------------------- 00984 00985 //} 00986 //----------------------------------------------------------------------------------------------------------------- 00987 00988 //----------------------------------------------------------------------------------------------------------------- 00989 //{ The namespaces 00990 //----------------------------------------------------------------------------------------------------------------- 00991 00992 //{---------------------------------------------------------------------------------------------------------------- 00995 //}---------------------------------------------------------------------------------------------------------------- 00996 00997 #ifdef FOR_DOXYGEN_ONLY 00998 namespace { namespace TX { }} 00999 #endif 01000 01003 //----------------------------------------------------------------------------------------------------------------- 01004 01005 #if defined (TX_COMPILED) && defined (TX_COMPILING) 01006 #undef TX_COMPILED 01007 #endif 01008 01009 #if !defined (TX_COMPILED) && !defined (TX_COMPILING) 01010 01011 #define _TX_BEGIN_NAMESPACE namespace { namespace TX { 01012 #define _TX_END_NAMESPACE } } 01013 01014 #else 01015 01016 #define _TX_BEGIN_NAMESPACE namespace TX { 01017 #define _TX_END_NAMESPACE } 01018 01019 #endif 01020 01021 //----------------------------------------------------------------------------------------------------------------- 01022 01023 _TX_BEGIN_NAMESPACE 01024 01027 //} 01028 //----------------------------------------------------------------------------------------------------------------- 01029 01030 //================================================================================================================= 01031 //{ TXLIB INTERFACE 01032 // Интерфейс библиотеки 01033 //================================================================================================================= 01034 01035 //================================================================================================================= 01036 //{ Initialization 01038 //================================================================================================================= 01040 //{---------------------------------------------------------------------------------------------------------------- 01084 //}---------------------------------------------------------------------------------------------------------------- 01085 01086 HWND txCreateWindow (double sizeX, double sizeY, bool centered = true); 01087 01088 //{---------------------------------------------------------------------------------------------------------------- 01115 //}---------------------------------------------------------------------------------------------------------------- 01116 01117 inline HDC& txDC() tx_nodiscard; 01118 01119 //{---------------------------------------------------------------------------------------------------------------- 01155 //}---------------------------------------------------------------------------------------------------------------- 01156 01157 inline RGBQUAD* txVideoMemory() tx_nodiscard; 01158 01159 //{---------------------------------------------------------------------------------------------------------------- 01178 //}---------------------------------------------------------------------------------------------------------------- 01179 01180 bool txSetDefaults (HDC dc = txDC()); 01181 01182 //{---------------------------------------------------------------------------------------------------------------- 01201 //}---------------------------------------------------------------------------------------------------------------- 01202 01203 inline bool txOK() tx_nodiscard; 01204 01205 //{---------------------------------------------------------------------------------------------------------------- 01237 //}---------------------------------------------------------------------------------------------------------------- 01238 01239 POINT txGetExtent (HDC dc = txDC()) tx_nodiscard; 01240 01241 //{---------------------------------------------------------------------------------------------------------------- 01258 //}---------------------------------------------------------------------------------------------------------------- 01259 01260 inline int txGetExtentX (HDC dc = txDC()) tx_nodiscard; 01261 01262 //{---------------------------------------------------------------------------------------------------------------- 01280 //}---------------------------------------------------------------------------------------------------------------- 01281 01282 inline int txGetExtentY (HDC dc = txDC()) tx_nodiscard; 01283 01284 //{---------------------------------------------------------------------------------------------------------------- 01296 //}---------------------------------------------------------------------------------------------------------------- 01297 01298 inline HWND txWindow() tx_nodiscard; 01299 01300 //{---------------------------------------------------------------------------------------------------------------- 01309 //}---------------------------------------------------------------------------------------------------------------- 01310 01311 inline const char* txVersion() tx_nodiscard; 01312 01313 //{---------------------------------------------------------------------------------------------------------------- 01322 //}---------------------------------------------------------------------------------------------------------------- 01323 01324 inline unsigned txVersionNumber() tx_nodiscard; 01325 01326 //{---------------------------------------------------------------------------------------------------------------- 01356 //}---------------------------------------------------------------------------------------------------------------- 01357 01358 const char* txGetModuleFileName (bool fileNameOnly = true) tx_nodiscard; 01359 01361 //{---------------------------------------------------------------------------------------------------------------- 01396 //}---------------------------------------------------------------------------------------------------------------- 01397 01398 int txMessageBox (const char text[] = "Муаххаха! :)", const char header[] = "TXLib сообщает", 01399 unsigned flags = MB_ICONINFORMATION | MB_OKCANCEL); 01400 01401 //{---------------------------------------------------------------------------------------------------------------- 01418 //}---------------------------------------------------------------------------------------------------------------- 01419 01420 HRESULT txSetProgress (double percent, unsigned type = 2 /*TBPF_NORMAL*/, HWND wnd = NULL); 01421 01422 //} 01423 //================================================================================================================= 01424 01425 //================================================================================================================= 01426 //{ Setting the parameters 01428 //================================================================================================================= 01430 //{---------------------------------------------------------------------------------------------------------------- 01456 //}---------------------------------------------------------------------------------------------------------------- 01457 01458 const COLORREF 01459 #ifdef FOR_DOXYGEN_ONLY 01460 enum txColors { 01461 #endif 01462 01463 TX_BLACK = RGB ( 0, 0, 0), 01464 TX_BLUE = RGB ( 0, 0, 128), 01465 TX_GREEN = RGB ( 0, 128, 0), 01466 TX_CYAN = RGB ( 0, 128, 128), 01467 TX_RED = RGB (128, 0, 0), 01468 TX_MAGENTA = RGB (128, 0, 128), 01469 TX_BROWN = RGB (128, 128, 0), 01470 TX_ORANGE = RGB (255, 128, 0), 01471 TX_GRAY = RGB (160, 160, 160), 01472 TX_DARKGRAY = RGB (128, 128, 128), 01473 TX_LIGHTGRAY = RGB (192, 192, 192), 01474 TX_LIGHTBLUE = RGB ( 0, 0, 255), 01475 TX_LIGHTGREEN = RGB ( 0, 255, 128), 01476 TX_LIGHTCYAN = RGB ( 0, 255, 255), 01477 TX_LIGHTRED = RGB (255, 0, 128), 01478 TX_LIGHTMAGENTA = RGB (255, 0, 255), 01479 TX_PINK = RGB (255, 128, 255), 01480 TX_YELLOW = RGB (255, 255, 128), 01481 TX_WHITE = RGB (255, 255, 255), 01482 TX_TRANSPARENT = 0xFFFFFFFF, 01483 TX_NULL = TX_TRANSPARENT, 01484 TX_BLM = TX_BLACK, 01485 TX_white = TX_WHITE, 01486 01487 // Цветовые каналы (компоненты) -- см. txExtractColor(), txRGB2HSL(), txHSL2RGB() 01488 01489 TX_HUE = 0x04000000, 01490 TX_SATURATION = 0x05000000, 01491 TX_LIGHTNESS = 0x06000000; 01492 01493 #ifdef FOR_DOXYGEN_ONLY 01494 }; 01495 #endif 01496 01498 #define TX_GREY TX_GRAY 01499 #define TX_DARKGREY TX_DARKGRAY 01500 #define TX_LIGHTGREY TX_LIGHTGRAY 01501 01502 01503 //{---------------------------------------------------------------------------------------------------------------- 01528 //}---------------------------------------------------------------------------------------------------------------- 01529 01530 #ifdef FOR_DOXYGEN_ONLY 01531 COLORREF RGB (int red, int green, int blue); 01532 #endif 01533 01534 //{---------------------------------------------------------------------------------------------------------------- 01553 //}---------------------------------------------------------------------------------------------------------------- 01554 01555 HPEN txSetColor (COLORREF color, double thickness = 1, HDC dc = txDC()); 01556 01558 #define txSetColour txSetColor 01559 01560 01562 01563 //{---------------------------------------------------------------------------------------------------------------- 01574 //}---------------------------------------------------------------------------------------------------------------- 01575 01576 COLORREF txColor (double red, double green, double blue); 01577 01579 01580 //{---------------------------------------------------------------------------------------------------------------- 01593 //}---------------------------------------------------------------------------------------------------------------- 01594 01595 COLORREF txGetColor (HDC dc = txDC()) tx_nodiscard; 01596 01597 //{---------------------------------------------------------------------------------------------------------------- 01612 //}---------------------------------------------------------------------------------------------------------------- 01613 01614 HBRUSH txSetFillColor (COLORREF color, HDC dc = txDC()); 01615 01617 #define txSetFillColour txSetFillColor 01618 01619 01621 01622 //{---------------------------------------------------------------------------------------------------------------- 01633 //}---------------------------------------------------------------------------------------------------------------- 01634 01635 COLORREF txFillColor (double red, double green, double blue); 01636 01638 01639 //{---------------------------------------------------------------------------------------------------------------- 01652 //}---------------------------------------------------------------------------------------------------------------- 01653 01654 COLORREF txGetFillColor (HDC dc = txDC()) tx_nodiscard; 01655 01656 //{---------------------------------------------------------------------------------------------------------------- 01674 //}---------------------------------------------------------------------------------------------------------------- 01675 01676 unsigned txExtractColor (COLORREF color, COLORREF component) tx_nodiscard; 01677 01678 //{---------------------------------------------------------------------------------------------------------------- 01706 //}---------------------------------------------------------------------------------------------------------------- 01707 01708 COLORREF txRGB2HSL (COLORREF rgbColor) tx_nodiscard; 01709 01710 //{---------------------------------------------------------------------------------------------------------------- 01740 //}---------------------------------------------------------------------------------------------------------------- 01741 01742 COLORREF txHSL2RGB (COLORREF hslColor) tx_nodiscard; 01743 01745 //} 01746 //================================================================================================================= 01747 01748 //================================================================================================================= 01749 //{ Drawing 01751 //================================================================================================================= 01753 //{---------------------------------------------------------------------------------------------------------------- 01767 //}---------------------------------------------------------------------------------------------------------------- 01768 01769 bool txClear (HDC dc = txDC()); 01770 01771 //{---------------------------------------------------------------------------------------------------------------- 01789 //}---------------------------------------------------------------------------------------------------------------- 01790 01791 inline bool txSetPixel (double x, double y, COLORREF color, HDC dc = txDC()); 01792 01794 01795 //{---------------------------------------------------------------------------------------------------------------- 01813 //}---------------------------------------------------------------------------------------------------------------- 01814 01815 inline bool txPixel (double x, double y, double red, double green, double blue, HDC dc = txDC()); 01816 01818 01819 //{---------------------------------------------------------------------------------------------------------------- 01837 //}---------------------------------------------------------------------------------------------------------------- 01838 01839 inline COLORREF txGetPixel (double x, double y, HDC dc = txDC()) tx_nodiscard; 01840 01841 //{---------------------------------------------------------------------------------------------------------------- 01861 //}---------------------------------------------------------------------------------------------------------------- 01862 01863 bool txLine (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01864 01865 //{---------------------------------------------------------------------------------------------------------------- 01887 //}---------------------------------------------------------------------------------------------------------------- 01888 01889 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01890 01891 //{---------------------------------------------------------------------------------------------------------------- 01911 //}---------------------------------------------------------------------------------------------------------------- 01912 01913 bool txPolygon (const POINT points[], int numPoints, HDC dc = txDC()); 01914 01915 //{---------------------------------------------------------------------------------------------------------------- 01935 //}---------------------------------------------------------------------------------------------------------------- 01936 01937 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc = txDC()); 01938 01939 //{---------------------------------------------------------------------------------------------------------------- 01957 //}---------------------------------------------------------------------------------------------------------------- 01958 01959 bool txCircle (double x, double y, double r); 01960 01961 //{---------------------------------------------------------------------------------------------------------------- 01984 //}---------------------------------------------------------------------------------------------------------------- 01985 01986 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 01987 01988 //{---------------------------------------------------------------------------------------------------------------- 02011 //}---------------------------------------------------------------------------------------------------------------- 02012 02013 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 02014 02015 //{---------------------------------------------------------------------------------------------------------------- 02038 //}---------------------------------------------------------------------------------------------------------------- 02039 02040 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc = txDC()); 02041 02042 //{---------------------------------------------------------------------------------------------------------------- 02074 //}---------------------------------------------------------------------------------------------------------------- 02075 02076 bool txFloodFill (double x, double y, COLORREF color = TX_TRANSPARENT, DWORD mode = FLOODFILLSURFACE, HDC dc = txDC()); 02077 02078 //{---------------------------------------------------------------------------------------------------------------- 02096 //}---------------------------------------------------------------------------------------------------------------- 02097 02098 inline bool txTriangle (double x1, double y1, double x2, double y2, double x3, double y3) 02099 { 02100 (void)x1; (void)y1; (void)x2; (void)y2; (void)x3; (void)y3; 02101 02102 txMessageBox ("txTriangle (double x1, double y1, double x2, double y2, double x3, double y3)\n\n" 02103 "Эта функция не реализована в библиотеке, потому что вы легко можете реализовать ее сами " 02104 "как функцию с параметрами, используя txPolygon(). См. \"Пример с функциями с параметрами\". " 02105 "Ну или нарисовать тремя линиями. :)", "TXLib сообщает"); 02106 return false; 02107 } 02108 02109 //{---------------------------------------------------------------------------------------------------------------- 02111 02112 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3); 02113 02114 #define txRectandle Sleep (1000), txRectangle // Copy-protection for the function below 02115 #define txLine(...) txLine (__VA_ARGS__); { // 02116 #define txNotifyIcon }}}}}}}}}} txNotifyIcon // Не спрашивайте, зачем. Это дичь. 02117 #define txCircle ;txCircle // 02118 #define txSetColor ;txSetColor // 02119 #define C0L0RREF COLORREF // 02120 #define OxFFFFFF 0xFFFFFF // 02121 #define lO 10 // 02122 #define lOOO 1000 // 02123 #define oo // 02124 #define O // 02125 02127 //} 02128 02129 //{---------------------------------------------------------------------------------------------------------------- 02170 //}----------------------------------------------------------------------------------------------------------------////// 02171 // 02172 inline void txDrawMan (int x, int y, int sizeX, int sizeY, COLORREF color, double handL, double handR, double twist, // 02173 double head, double eyes, double wink, double crazy, double smile, double hair, double wind) // 02174 { // 02175 const char __[] = "\0/А я - человечек из библиотеки!\0/Меня объясняли на уроке!\0/Напиши меня сам!\0/"; // 02176 // | | | | // 02177 // Не копипастите! _/ \_ Все равно не получится! :) _/ \_ Человечки защищают _/ \_ этот код! :) _/ \_ Муаххаха! // 02178 // // 02179 static int count = GetTickCount(), L = 0; 02180 02181 C0L0RREF lineColor = txGetColor(); 02182 C0L0RREF fillColor = txGetFillColor(); 02183 02184 txSetColor (color, 3); 02185 txSetFillColor (color); 02186 02187 txLine (x + twist * sizeX, y - O.35 * sizeY, x, y - O.7 * sizeY); 02188 02189 txLine (x, y - O.7 * sizeY, x - sizeX/2.0, y - (O.7 + handL) * sizeY); 02190 txLine (x, y - O.7 * sizeY, x + sizeX/2.0, y - (O.7 + handR) * sizeY); 02191 02192 txLine (x + twist * sizeX, y - O.35 * sizeY, x - sizeX/2.0, y); 02193 txLine (x + twist * sizeX, y - O.35 * sizeY, x + sizeX/2.0, y); 02194 02195 txCircle (x, y - (O.85 + head) * sizeY, O.15 * sizeY); 02196 02197 txLine (x, y - (1 + head) * sizeY, x + wind/lO * sizeX, y - (1 + head + hair/lO) * sizeY); 02198 txLine (x, y - (1 + head) * sizeY, x + (wind/lO - O.1) * sizeX, y - (1 + head + hair/lO) * sizeY); 02199 txLine (x, y - (1 + head) * sizeY, x + (wind/lO + O.1) * sizeX, y - (1 + head + hair/lO) * sizeY); 02200 02201 txSetColor (~color & OxFFFFFF); // Inverse the color 02202 txSetFillColor (~color & OxFFFFFF); 02203 02204 txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x - O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY); 02205 txLine (x, y - (O.8 + head - O.05 * smile/2) * sizeY, x + O.05 * sizeY, y - (O.8 + head + O.05 * smile/2) * sizeY); 02206 oo 02207 txNotifyIcon (4, (const char*)!! (L+'L')[(__)], "\n%s\n", __ + ((unsigned) (((count -=- 1) ^=! 1) ^=~ ((0)^(0)) +1) % 3)["\x02\"<"]); //-V112 //-V542 02208 oo 02209 // See above: Frog construct [(__)], Mouth operator -=-, Cat operator ^=!, Mouse operator ^=~ and Owl constant ((0)^(0)). Use it freely, meow 02210 02211 txCircle (x - O.05 * sizeY, y - (O.9 + head - O.02 * crazy) * sizeY, eyes * (1 + O.5*wink) * O.02 * sizeY); 02212 txCircle (x + O.05 * sizeY, y - (O.9 + head + O.02 * crazy) * sizeY, eyes * (1 - O.5*wink) * O.02 * sizeY); 02213 Sleep (lOOO + count%2); 02214 02215 txSetColor ((color == 0xDEADFACE)? TX_DARKGRAY : TX_TRANSPARENT); 02216 txSetFillColor (TX_TRANSPARENT); 02217 02218 txCircle (x, y, 4); //-V112 02219 txRectandle (x - sizeX/2.0, y - sizeY, x + sizeX/2.0, y); 02220 02221 txSetColor (lineColor); 02222 txSetFillColor (fillColor); 02223 } 02224 02226 //} 02227 //================================================================================================================= 02228 02229 //================================================================================================================= 02230 //{ Drawing text 02232 //================================================================================================================= 02234 //{---------------------------------------------------------------------------------------------------------------- 02253 //}---------------------------------------------------------------------------------------------------------------- 02254 02255 bool txTextOut (double x, double y, const char text[], HDC dc = txDC()); 02256 02257 //{---------------------------------------------------------------------------------------------------------------- 02259 02260 #undef txRectandle 02261 #undef txLine 02262 #undef txNotifyIcon 02263 #undef txCircle 02264 #undef txSetColor 02265 #undef C0L0RREF 02266 #undef OxFFFFFF 02267 #undef lO 02268 #undef lOOO 02269 #undef oo 02270 #undef O 02271 02273 //} 02274 02275 //{---------------------------------------------------------------------------------------------------------------- 02322 //}---------------------------------------------------------------------------------------------------------------- 02323 02324 bool txDrawText (double x0, double y0, double x1, double y1, const char text[], 02325 unsigned format = DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS, HDC dc = txDC()); 02326 02327 //{---------------------------------------------------------------------------------------------------------------- 02352 //}---------------------------------------------------------------------------------------------------------------- 02353 02354 HFONT txSelectFont (const char name[], double sizeY, double sizeX = -1, 02355 int bold = FW_DONTCARE, bool italic = false, bool underline = false, 02356 bool strikeout = false, double angle = 0, 02357 HDC dc = txDC()); 02358 02359 //{---------------------------------------------------------------------------------------------------------------- 02374 //}---------------------------------------------------------------------------------------------------------------- 02375 02376 SIZE txGetTextExtent (const char text[], HDC dc = txDC()) tx_nodiscard; 02377 02378 //{---------------------------------------------------------------------------------------------------------------- 02392 //}---------------------------------------------------------------------------------------------------------------- 02393 02394 int txGetTextExtentX (const char text[], HDC dc = txDC()) tx_nodiscard; 02395 02396 //{---------------------------------------------------------------------------------------------------------------- 02410 //}---------------------------------------------------------------------------------------------------------------- 02411 02412 int txGetTextExtentY (const char text[], HDC dc = txDC()) tx_nodiscard; 02413 02414 //{---------------------------------------------------------------------------------------------------------------- 02441 //}---------------------------------------------------------------------------------------------------------------- 02442 02443 unsigned txSetTextAlign (unsigned align = TA_CENTER | TA_BASELINE, HDC dc = txDC()); 02444 02445 //{---------------------------------------------------------------------------------------------------------------- 02461 //}---------------------------------------------------------------------------------------------------------------- 02462 02463 LOGFONT* txFontExist (const char name[]) tx_nodiscard; 02464 02466 //} 02467 //================================================================================================================= 02468 02469 //================================================================================================================= 02470 //{ Drawing to memory DC and image loading 02472 //================================================================================================================= 02474 //{---------------------------------------------------------------------------------------------------------------- 02514 //}---------------------------------------------------------------------------------------------------------------- 02515 02516 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap = NULL, RGBQUAD** pixels = NULL) tx_nodiscard; 02517 02518 //{---------------------------------------------------------------------------------------------------------------- 02621 //}---------------------------------------------------------------------------------------------------------------- 02622 02623 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels = NULL) tx_nodiscard; 02624 02626 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) tx_nodiscard; 02628 02629 //{---------------------------------------------------------------------------------------------------------------- 02705 //}---------------------------------------------------------------------------------------------------------------- 02706 02707 HDC txLoadImage (const char filename[], int sizeX = 0, int sizeY = 0, 02708 unsigned imageFlags = IMAGE_BITMAP, unsigned loadFlags = LR_LOADFROMFILE) tx_nodiscard; 02709 02710 //{---------------------------------------------------------------------------------------------------------------- 02742 //}---------------------------------------------------------------------------------------------------------------- 02743 02744 bool txDeleteDC (HDC dc); 02745 02747 bool txDeleteDC (HDC* dc); 02749 02750 //{---------------------------------------------------------------------------------------------------------------- 02790 //}---------------------------------------------------------------------------------------------------------------- 02791 02792 bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height, 02793 HDC sourceImage, double xSource = 0, double ySource = 0, unsigned operation = SRCCOPY); 02794 02795 //{---------------------------------------------------------------------------------------------------------------- 02810 //}---------------------------------------------------------------------------------------------------------------- 02811 02812 inline bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource = 0, double ySource = 0); 02813 02814 //{---------------------------------------------------------------------------------------------------------------- 02874 //}---------------------------------------------------------------------------------------------------------------- 02875 02876 bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height, 02877 HDC sourceImage, double xSource = 0, double ySource = 0, COLORREF transColor = TX_BLACK); 02878 02879 //{---------------------------------------------------------------------------------------------------------------- 02895 //}---------------------------------------------------------------------------------------------------------------- 02896 02897 inline bool txTransparentBlt (double xDest, double yDest, HDC sourceImage, 02898 COLORREF transColor = TX_BLACK, double xSource = 0, double ySource = 0); 02899 02900 //{---------------------------------------------------------------------------------------------------------------- 03005 //}---------------------------------------------------------------------------------------------------------------- 03006 03007 bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height, 03008 HDC sourceImage, double xSource = 0, double ySource = 0, double alpha = 1.0); 03009 03010 //{---------------------------------------------------------------------------------------------------------------- 03027 //}---------------------------------------------------------------------------------------------------------------- 03028 03029 inline bool txAlphaBlend (double xDest, double yDest, HDC sourceImage, 03030 double xSource = 0, double ySource = 0, double alpha = 1.0); 03031 03032 //{---------------------------------------------------------------------------------------------------------------- 03061 //}---------------------------------------------------------------------------------------------------------------- 03062 03063 HDC txUseAlpha (HDC image); 03064 03065 //{---------------------------------------------------------------------------------------------------------------- 03091 //}---------------------------------------------------------------------------------------------------------------- 03092 03093 bool txSaveImage (const char filename[], HDC dc = txDC()); 03094 03096 //} 03097 //================================================================================================================= 03098 03099 //================================================================================================================= 03100 //{ Utility functions 03102 //================================================================================================================= 03104 //{---------------------------------------------------------------------------------------------------------------- 03123 //}---------------------------------------------------------------------------------------------------------------- 03124 03125 double txSleep (double time = 0); 03126 03127 //{---------------------------------------------------------------------------------------------------------------- 03212 //}---------------------------------------------------------------------------------------------------------------- 03213 03214 inline int txBegin(); 03215 03216 //{---------------------------------------------------------------------------------------------------------------- 03239 //}---------------------------------------------------------------------------------------------------------------- 03240 03241 inline int txEnd(); 03242 03243 //{---------------------------------------------------------------------------------------------------------------- 03265 //}---------------------------------------------------------------------------------------------------------------- 03266 03267 inline void txRedrawWindow(); 03268 03269 //{---------------------------------------------------------------------------------------------------------------- 03293 //}---------------------------------------------------------------------------------------------------------------- 03294 03295 inline int txUpdateWindow (int update = true); 03296 03297 //{---------------------------------------------------------------------------------------------------------------- 03314 //}---------------------------------------------------------------------------------------------------------------- 03315 03316 bool txSelectObject (HGDIOBJ obj, HDC dc = txDC()); 03317 03318 //{---------------------------------------------------------------------------------------------------------------- 03338 // 03339 // +--<<< Это текст помощи, который вы уже читали. Ищите дальше! Жмите [F3] или "Найти далее" 03340 // | 03341 // v 03342 // txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture(); 03347 //}---------------------------------------------------------------------------------------------------------------- 03348 03349 // +--<<< Это _прототип_ функции, а надо найти ее _определение_. Ищите дальше! Жмите [F3] или "Найти далее" 03350 // | 03351 // v 03352 bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture(); 03353 03354 //{---------------------------------------------------------------------------------------------------------------- 03370 //}---------------------------------------------------------------------------------------------------------------- 03371 03372 bool txDestroyWindow (HWND wnd = txWindow()); 03373 03374 //{---------------------------------------------------------------------------------------------------------------- 03385 //}---------------------------------------------------------------------------------------------------------------- 03386 03387 double txQueryPerformance() tx_nodiscard; 03388 03389 //{---------------------------------------------------------------------------------------------------------------- 03404 //}---------------------------------------------------------------------------------------------------------------- 03406 03407 #if defined (_TX_CPP11) 03408 template <int txFramesToAverage = 5> 03409 #else 03410 const int txFramesToAverage = 5; 03411 #endif 03412 03414 03415 double txGetFPS (int minFrames = txFramesToAverage) tx_nodiscard; 03416 03418 //} 03419 03420 //================================================================================================================= 03421 //{ Mouse functions 03423 //================================================================================================================= 03425 //{---------------------------------------------------------------------------------------------------------------- 03449 //}---------------------------------------------------------------------------------------------------------------- 03450 03451 inline POINT txMousePos() tx_nodiscard; 03452 03453 //{---------------------------------------------------------------------------------------------------------------- 03473 //}---------------------------------------------------------------------------------------------------------------- 03474 03475 inline double txMouseX() tx_nodiscard; 03476 03477 //{---------------------------------------------------------------------------------------------------------------- 03497 //}---------------------------------------------------------------------------------------------------------------- 03498 03499 inline double txMouseY() tx_nodiscard; 03500 03501 //{---------------------------------------------------------------------------------------------------------------- 03533 //}---------------------------------------------------------------------------------------------------------------- 03534 03535 inline unsigned txMouseButtons() tx_nodiscard; 03536 03537 //{---------------------------------------------------------------------------------------------------------------- 03569 //}---------------------------------------------------------------------------------------------------------------- 03570 03571 #ifdef FOR_DOXYGEN_ONLY 03572 inline Mouse& txCatchMouse (bool shouldEat = true); 03573 #endif 03574 03576 //} 03577 //================================================================================================================= 03578 03579 //================================================================================================================= 03580 //{ Console functions 03582 //================================================================================================================= 03584 //{---------------------------------------------------------------------------------------------------------------- 03626 //}---------------------------------------------------------------------------------------------------------------- 03627 03628 unsigned txSetConsoleAttr (unsigned colors = 0x07 /*FOREGROUND_LIGHTGRAY*/); 03629 03630 //{---------------------------------------------------------------------------------------------------------------- 03642 //}---------------------------------------------------------------------------------------------------------------- 03643 03644 unsigned txGetConsoleAttr() tx_nodiscard; 03645 03646 //{---------------------------------------------------------------------------------------------------------------- 03660 //}---------------------------------------------------------------------------------------------------------------- 03661 03662 bool txClearConsole(); 03663 03664 //{---------------------------------------------------------------------------------------------------------------- 03684 //}---------------------------------------------------------------------------------------------------------------- 03685 03686 POINT txSetConsoleCursorPos (double x, double y); 03687 03688 //{---------------------------------------------------------------------------------------------------------------- 03701 //}---------------------------------------------------------------------------------------------------------------- 03702 03703 POINT txGetConsoleCursorPos(); 03704 03705 //{---------------------------------------------------------------------------------------------------------------- 03718 //}---------------------------------------------------------------------------------------------------------------- 03719 03720 POINT txGetConsoleExtent(); 03721 03722 //{---------------------------------------------------------------------------------------------------------------- 03736 //}---------------------------------------------------------------------------------------------------------------- 03737 03738 POINT txGetConsoleFontSize() tx_nodiscard; 03739 03740 //{---------------------------------------------------------------------------------------------------------------- 03756 //}---------------------------------------------------------------------------------------------------------------- 03757 03758 bool txTextCursor (bool blink = true); 03759 03761 //} 03762 //================================================================================================================= 03763 03764 //================================================================================================================= 03765 //{ Other staff not related to drawing 03767 //================================================================================================================= 03769 //{---------------------------------------------------------------------------------------------------------------- 03798 //}---------------------------------------------------------------------------------------------------------------- 03799 03800 bool txPlaySound (const char filename[] = NULL, DWORD mode = SND_ASYNC); 03801 03802 //{---------------------------------------------------------------------------------------------------------------- 03860 //}---------------------------------------------------------------------------------------------------------------- 03861 03862 int txSpeak (const char* text, ...) tx_printfy (1); 03863 03864 //{---------------------------------------------------------------------------------------------------------------- 03981 //}---------------------------------------------------------------------------------------------------------------- 03982 03983 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[], 03984 double zoom = 0, double gain = 1, HWND wnd = txWindow()); 03985 03986 //{---------------------------------------------------------------------------------------------------------------- 04000 //}---------------------------------------------------------------------------------------------------------------- 04001 04002 intptr_t txPlayVideo (const char fileName[], double zoom = 0, double gain = 1, HWND wnd = txWindow()); 04003 04004 //{---------------------------------------------------------------------------------------------------------------- 04060 //}---------------------------------------------------------------------------------------------------------------- 04061 04062 bool txGetAsyncKeyState (int key); 04063 04064 //{---------------------------------------------------------------------------------------------------------------- 04101 //}---------------------------------------------------------------------------------------------------------------- 04102 04103 #ifdef FOR_DOXYGEN_ONLY 04104 bool txNotifyIcon (unsigned flags, const char title[], const char format[], ...) tx_printfy (3); 04105 #endif 04106 04107 //{---------------------------------------------------------------------------------------------------------------- 04132 //}---------------------------------------------------------------------------------------------------------------- 04133 04134 int txOutputDebugPrintf (const char format[], ...) tx_printfy (1); 04135 04136 //{---------------------------------------------------------------------------------------------------------------- 04212 //}---------------------------------------------------------------------------------------------------------------- 04213 04214 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04215 04216 template <typename T, typename... ArgsT> 04217 int txPrintf (const char* format, ArgsT... args); 04218 04219 #define TX_PRINTF(...) ( _txPrintfCheck (__VA_ARGS__), txPrintf (__VA_ARGS__) ) 04220 04221 #endif 04222 04223 //----------------------------------------------------------------------------------------------------------------- 04224 04225 #if defined (_TX_CPP11) && !defined (FOR_DOXYGEN_ONLY) 04226 04227 enum width_t : int {}; 04228 enum precision_t : int {}; 04229 04230 inline width_t width (int width) { return (width_t) width; } 04231 inline precision_t precision (int prec) { return (precision_t) prec; } 04232 04233 #endif 04234 04235 //{---------------------------------------------------------------------------------------------------------------- 04254 //}---------------------------------------------------------------------------------------------------------------- 04255 04256 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04257 04258 template <typename T, typename... ArgsT> 04259 int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args); 04260 04261 #endif 04262 04263 //{---------------------------------------------------------------------------------------------------------------- 04283 //}---------------------------------------------------------------------------------------------------------------- 04284 04285 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04286 04287 template <typename T, typename... ArgsT> 04288 int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args); 04289 04290 #endif 04291 04292 //{---------------------------------------------------------------------------------------------------------------- 04310 //}---------------------------------------------------------------------------------------------------------------- 04311 04312 #if defined (_TX_CPP11) || defined (FOR_DOXYGEN_ONLY) 04313 04314 template <typename... ArgsT> 04315 std::string txFormat (const char* format, ArgsT... args); 04316 04317 #endif 04318 04319 //{---------------------------------------------------------------------------------------------------------------- 04391 //}---------------------------------------------------------------------------------------------------------------- 04393 04394 #define sizearr( arr ) ( sizeof (get_size_of_an_array_with_unknown_or_nonconst_size_ (arr)) ) 04395 04397 // See explanation here: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx 04398 04399 template <typename T, size_t N> char (&get_size_of_an_array_with_unknown_or_nonconst_size_ (T (&) [N])) [N]; // ;=P 04400 04401 // Another approach 04402 04403 #if defined (_TX_CPP11_MSVC15) 04404 template <typename T, size_t N> constexpr size_t countof (const T (&) [N] ) { return N; } 04405 #endif 04406 04408 04409 #define SIZEARR( arr ) ( sizeof (arr) / sizeof ((arr)[0]) ) 04410 04412 //{---------------------------------------------------------------------------------------------------------------- 04431 //}---------------------------------------------------------------------------------------------------------------- 04432 04433 inline int random (int range) tx_deprecated; 04434 04435 //{---------------------------------------------------------------------------------------------------------------- 04460 //}---------------------------------------------------------------------------------------------------------------- 04461 04462 inline double random (double left, double right) tx_nodiscard tx_deprecated; 04463 04464 inline double random (std::nomeow_t, double left, double right) tx_nodiscard; 04465 04466 //{---------------------------------------------------------------------------------------------------------------- 04496 //}---------------------------------------------------------------------------------------------------------------- 04497 04498 template <typename Tx, typename Ta, typename Tb> 04499 inline bool In (Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated; 04500 04501 template <typename Tx, typename Ta, typename Tb> 04502 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) tx_nodiscard tx_deprecated; 04503 04504 //{---------------------------------------------------------------------------------------------------------------- 04550 //}---------------------------------------------------------------------------------------------------------------- 04552 04553 inline bool In (const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated; 04554 inline bool In (const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated; 04555 04557 04558 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) tx_nodiscard tx_deprecated; 04559 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) tx_nodiscard tx_deprecated; 04560 04561 //{---------------------------------------------------------------------------------------------------------------- 04580 //}---------------------------------------------------------------------------------------------------------------- 04581 04582 #define MAX( a, b ) ( ((a) > (b))? (a) : (b) ) 04583 04584 template <typename T> 04585 T max (const T& a, const T& b) { return (a > b)? a : b; } 04586 04587 //{---------------------------------------------------------------------------------------------------------------- 04606 //}---------------------------------------------------------------------------------------------------------------- 04607 04608 #define MIN( a, b ) ( ((a) < (b))? (a) : (b) ) 04609 04610 template <typename T> 04611 T min (const T& a, const T& b) { return (a < b)? a : b; } 04612 04613 //{---------------------------------------------------------------------------------------------------------------- 04627 //}---------------------------------------------------------------------------------------------------------------- 04628 04629 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // MSVC: C99 case 04630 04631 #define ROUND( x ) ( (long) round (x) ) 04632 04633 #else 04634 04635 #define ROUND( x ) ( (long) floor ((x) + 0.5) ) 04636 04637 #endif 04638 04639 //{---------------------------------------------------------------------------------------------------------------- 04658 //}---------------------------------------------------------------------------------------------------------------- 04659 04660 void tx_fpreset(); 04661 04662 //{---------------------------------------------------------------------------------------------------------------- 04671 //}---------------------------------------------------------------------------------------------------------------- 04672 04673 const double txPI = asin (1.0) * 2; 04674 04675 //{---------------------------------------------------------------------------------------------------------------- 04702 //}---------------------------------------------------------------------------------------------------------------- 04703 04704 inline double txSqr (double x) 04705 { 04706 double sqr = pow (sqrt (x) * sqrt (x), sqrt (4.0)); // Бурная вычислительная деятельность 04707 04708 char str[1024] = ""; 04709 _snprintf_s (str, sizeof (str), "Возведение дало %g!" "!!" "!!" " Вы рады??1!!", sqr); 04710 txMessageBox (str, "Получен ОТВЕТ!" "!!", MB_ICONEXCLAMATION | MB_YESNO) != IDCANCEL || 04711 ( 04712 txMessageBox ("Жаль...", "А я так старалась", MB_ICONINFORMATION), 04713 txMessageBox ("Уйду я от вас", "Злые вы...", MB_ICONSTOP), 04714 exit (EXIT_FAILURE), 0 //-V2509 //-V2014 04715 ); 04716 04717 txNotifyIcon (1, NULL, "\n%s\n", "Высшая математика! \0" // А как это работает, а? //-V111 04718 "С ума сойти... \0" // 04719 "а КЭП подтверждает \0" // и кто это будет 04720 "Главное - отчитаться\0" // поддерживать?.. 04721 "Невероятно, но факт \0" 04722 "Кто бы мог подумать?\0" + GetTickCount() % 6 * 21); 04723 04724 return sqr; // Все же вернем значение. Мы же не звери 04725 } 04726 04727 //{---------------------------------------------------------------------------------------------------------------- 04749 //}---------------------------------------------------------------------------------------------------------------- 04750 04751 #ifdef FOR_DOXYGEN_ONLY 04752 #define _TX_DESTROY_3D 04753 #endif 04754 04755 #if defined (_TX_DESTROY_3D) 04756 04757 #define z 0 // Читайте "Флатландию" Эбботта! 04758 04759 #endif 04760 04761 //{---------------------------------------------------------------------------------------------------------------- 04778 //}---------------------------------------------------------------------------------------------------------------- 04780 04781 #define meow ; 04782 04783 #if defined (_MSC_VER) && !defined (_CLANG_VER) 04784 #define мяу meow 04785 #endif 04786 04787 #define please 04788 04790 04791 //{---------------------------------------------------------------------------------------------------------------- 04809 //}---------------------------------------------------------------------------------------------------------------- 04810 04811 #define ZERO( type ) zero <type> () 04812 04814 template <typename T> inline T zero() tx_nodiscard; 04816 04817 //{---------------------------------------------------------------------------------------------------------------- 04844 //}---------------------------------------------------------------------------------------------------------------- 04846 04847 #define tx_auto_func( func ) _tx_auto_fun1 ( __LINE__, func ) 04848 #define _tx_auto_fun1( n, func ) _tx_auto_fun2 ( n, func ) 04849 #define _tx_auto_fun2( n, func ) auto _tx_auto_func_##n = _tx_auto_func ([&]() { func; }) 04850 04851 #define tx_finally(...) tx_auto_func (__VA_ARGS__) 04852 04853 template <typename T> 04854 struct _tx_auto_func_ 04855 { 04856 typedef _tx_auto_func_<T> this_t; 04857 T func_; 04858 04859 explicit _tx_auto_func_ (T func) : func_ (func) {} 04860 ~_tx_auto_func_ () { func_ (); } 04861 04862 private: _tx_auto_func_ () _tx_delete; 04863 _tx_auto_func_ (const this_t&) _tx_delete; 04864 this_t& operator = (const this_t&) _tx_delete; 04865 }; 04866 04867 template <typename T> 04868 _tx_auto_func_<T> _tx_auto_func (T func) 04869 { 04870 return _tx_auto_func_ <T> (func); 04871 } 04872 04874 04875 //{---------------------------------------------------------------------------------------------------------------- 04920 //}---------------------------------------------------------------------------------------------------------------- 04921 04922 #if !defined (NDEBUG) 04923 #undef TX_ASSERT 04924 #define TX_ASSERT( cond ) _txNOP ( !(cond)? (TX_ERROR ("\a" "ВНЕЗАПНО: Логическая ошибка: " \ 04925 "Неверно, что \"%s\"." TX_COMMA #cond), 1/(int)!!(cond)) : 1 ) 04926 #else 04927 #undef TX_ASSERT 04928 #define TX_ASSERT( cond ) ((void) 1) 04929 04930 #endif 04931 04932 #ifdef assert 04933 #undef assert 04934 #endif 04935 04936 #define assert( cond ) TX_ASSERT (cond) 04937 04938 //{---------------------------------------------------------------------------------------------------------------- 04965 //}---------------------------------------------------------------------------------------------------------------- 04966 04967 #if !defined (NDEBUG) 04968 #define asserted || TX_ERROR ("\a" "Обнаружен нулевой или ложный результат.") 04969 04970 #else 04971 #define asserted || _txNOP (0) 04972 04973 #endif 04974 04975 #define verified asserted //!< For compatibility with assert macro 04976 04978 #define TX_NEEDED asserted //!< For compatibility with earlier releases 04979 04980 04981 //{---------------------------------------------------------------------------------------------------------------- 05009 //}---------------------------------------------------------------------------------------------------------------- 05010 05011 #if !defined (NDEBUG) 05012 #undef verify 05013 #define verify assert 05014 05015 #else 05016 #undef verify 05017 #define verify( expr ) ( expr ) 05018 05019 #endif 05020 05021 //{---------------------------------------------------------------------------------------------------------------- 05040 //}---------------------------------------------------------------------------------------------------------------- 05041 05042 #if !defined (FOR_DOXYGEN_ONLY) 05043 #define TX_ERROR( ... ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, ##__VA_ARGS__) 05044 #else 05045 #define TX_ERROR( msg ) ::TX::_txError (__FILE__, __LINE__, __TX_FUNCTION__, 0, msg) 05046 #endif 05047 05049 #define TX_THROW TX_ERROR //!< For compatibility with earlier TXLib releases 05050 05051 05052 //{---------------------------------------------------------------------------------------------------------------- 05068 //}---------------------------------------------------------------------------------------------------------------- 05069 05070 #if !defined (NDEBUG) 05071 #define TX_DEBUG_ERROR(...) TX_ERROR (__VA_ARGS__) 05072 05073 #else 05074 #define TX_DEBUG_ERROR(...) ((void) 0) 05075 05076 #endif 05077 05078 //{---------------------------------------------------------------------------------------------------------------- 05098 //}---------------------------------------------------------------------------------------------------------------- 05099 05100 #ifdef FOR_DOXYGEN_ONLY 05101 void txDump (const void* address, const char name[] = "_txDump()", bool pause = true); 05102 #endif 05103 05105 05106 #ifdef _MSC_VER 05107 #define txDump( ... ) _txDump ((const void*)(uintptr_t) __VA_ARGS__) 05108 #else 05109 #define txDump( address, ... ) _txDump ((const void*)(uintptr_t) (address), #address, ##__VA_ARGS__) 05110 #endif 05111 05112 void _txDump (const void* address, const char name[] = "_txDump()", bool pause = true); 05113 05115 05116 //{---------------------------------------------------------------------------------------------------------------- 05142 //}---------------------------------------------------------------------------------------------------------------- 05143 05144 #define txStackBackTrace() _txStackBackTrace (__FILE__, __LINE__, __TX_FUNCTION__, true); 05145 05146 //{---------------------------------------------------------------------------------------------------------------- 05168 //}---------------------------------------------------------------------------------------------------------------- 05170 05171 std::string txDemangle (const char* mangledName); 05172 char* txDemangle (const char* mangledName, std::nomeow_t); 05173 05174 #define txTypename(value) txDemangle (typeid (value) .name()) .c_str() 05175 05177 //{---------------------------------------------------------------------------------------------------------------- 05204 //}---------------------------------------------------------------------------------------------------------------- 05205 05206 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue); 05207 05208 //{---------------------------------------------------------------------------------------------------------------- 05221 //}---------------------------------------------------------------------------------------------------------------- 05223 05224 #define _ , 05225 #define TX_COMMA , //!< Синоним макроса _ (@ref _ "символ подчеркивания") 05226 05228 05229 //{---------------------------------------------------------------------------------------------------------------- 05289 //}---------------------------------------------------------------------------------------------------------------- 05290 05291 #ifdef FOR_DOXYGEN_ONLY 05292 05293 #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, callType ) 05294 05295 #else 05296 05297 // Hand-made DLLIMPORT helper 05298 05299 #define TX_DLLIMPORT( required, libName, retValType, funcName, funcParams, ... ) \ 05300 retValType (__VA_ARGS__* funcName) funcParams = (retValType (__VA_ARGS__*) funcParams) \ 05301 _txDllImport ((libName), #funcName, (required)) 05302 #endif 05303 05305 //} 05306 //================================================================================================================= 05307 05308 //================================================================================================================= 05309 //{ Back-hole (I hope, not an ass-hole:) of the library) 05311 //================================================================================================================= 05313 //{---------------------------------------------------------------------------------------------------------------- 05465 //}---------------------------------------------------------------------------------------------------------------- 05466 05467 WNDPROC txSetWindowsHook (WNDPROC wndProc = NULL); 05468 05469 //{---------------------------------------------------------------------------------------------------------------- 05494 //}---------------------------------------------------------------------------------------------------------------- 05495 05496 bool txLock (bool wait = true); 05497 05498 //{---------------------------------------------------------------------------------------------------------------- 05509 //}---------------------------------------------------------------------------------------------------------------- 05511 05512 bool txUnlock(); 05513 05515 template <typename T> inline T txUnlock (T value); 05517 05519 05520 //{---------------------------------------------------------------------------------------------------------------- 05543 //}---------------------------------------------------------------------------------------------------------------- 05544 05545 #define txGDI( command, dc ) ( ((dc) == txDC())? txUnlock ( (txLock(), (command)) ) : (command) ) 05546 05547 //{---------------------------------------------------------------------------------------------------------------- 05570 //}---------------------------------------------------------------------------------------------------------------- 05571 05572 #ifndef FOR_DOXYGEN_ONLY 05573 05574 const int _TX_CODEPAGE = 1251; 05575 05576 #ifndef __CYGWIN__ 05577 const char _TX_LOCALE[] = "Russian"; 05578 #else 05579 const char _TX_LOCALE[] = "ru_RU.CP1251"; 05580 #endif 05581 05582 const wchar_t _TX_WLOCALE[] = L"Russian_Russia.ACP"; 05583 05584 #endif 05585 05586 int txSetLocale (int codepage = _TX_CODEPAGE, const char locale[] = _TX_LOCALE, const wchar_t wLocale[] = _TX_WLOCALE); 05587 05588 //{---------------------------------------------------------------------------------------------------------------- 05603 //}---------------------------------------------------------------------------------------------------------------- 05604 05605 int txPause (const char* message, ...) tx_printfy (1); 05606 05608 //} 05609 //================================================================================================================= 05610 05611 //================================================================================================================= 05612 //{ Tune-up constants and variables 05614 //================================================================================================================= 05616 //{---------------------------------------------------------------------------------------------------------------- 05626 //}---------------------------------------------------------------------------------------------------------------- 05627 05628 #ifndef TX_COMPILED 05629 05630 char _txLogName[MAX_PATH] = "~TXLog.log"; 05631 05632 #endif // TX_COMPILED 05633 05634 extern char _txLogName[]; 05635 05636 //{---------------------------------------------------------------------------------------------------------------- 05668 //}---------------------------------------------------------------------------------------------------------------- 05669 05670 #if defined (_TX_NOINIT) 05671 05672 #undef _TX_NOINIT 05673 #define _TX_NOINIT 1 05674 05675 #else 05676 05677 #define _TX_NOINIT 0 05678 05679 #endif 05680 05681 //{---------------------------------------------------------------------------------------------------------------- 05725 //}---------------------------------------------------------------------------------------------------------------- 05726 05727 #if !defined (TX_CONSOLE_MODE) 05728 05729 #define TX_CONSOLE_MODE SW_HIDE 05730 05731 #endif 05732 05733 //{---------------------------------------------------------------------------------------------------------------- 05737 //}---------------------------------------------------------------------------------------------------------------- 05738 05739 #if !defined (TX_CONSOLE_FONT) 05740 05741 #define TX_CONSOLE_FONT "Lucida Console" 05742 05743 #endif 05744 05745 //{---------------------------------------------------------------------------------------------------------------- 05756 //}---------------------------------------------------------------------------------------------------------------- 05757 05758 #ifndef TX_COMPILED 05759 05760 int _txWindowStyle = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU; 05761 05762 #endif // TX_COMPILED 05763 05764 extern int _txWindowStyle; 05765 05766 //{---------------------------------------------------------------------------------------------------------------- 05769 //}---------------------------------------------------------------------------------------------------------------- 05770 05771 #ifndef TX_COMPILED 05772 05773 unsigned _txCursorBlinkInterval = 500; 05774 05775 #endif // TX_COMPILED 05776 05777 extern unsigned _txCursorBlinkInterval; 05778 05779 //{---------------------------------------------------------------------------------------------------------------- 05783 //}---------------------------------------------------------------------------------------------------------------- 05784 05785 #ifndef TX_COMPILED 05786 05787 unsigned _txWindowUpdateInterval = 25; 05788 05789 #endif // TX_COMPILED 05790 05791 extern unsigned _txWindowUpdateInterval; 05792 05793 //{---------------------------------------------------------------------------------------------------------------- 05802 //}---------------------------------------------------------------------------------------------------------------- 05803 05804 #ifdef FOR_DOXYGEN_ONLY 05805 #define TX_USE_SFML 05806 #endif 05807 05808 //{---------------------------------------------------------------------------------------------------------------- 05811 //}---------------------------------------------------------------------------------------------------------------- 05812 05813 const int _TX_TIMEOUT = 1000 05814 05815 #if defined (_TX_ALLOW_TRACE) 05816 * 2 05817 #endif 05818 05819 #if defined (TX_TRACE) 05820 * 3 05821 #endif 05822 05823 #if defined (_TX_USE_DEVPARTNER) 05824 * 10 05825 #endif 05826 ; 05827 05828 //{---------------------------------------------------------------------------------------------------------------- 05869 //}---------------------------------------------------------------------------------------------------------------- 05870 05871 #ifndef TX_COMPILED 05872 05873 bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest, 05874 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp) = NULL; 05875 05876 #endif // TX_COMPILED 05877 05878 extern bool (*_txSwapBuffers) (HDC dest, int xDest, int yDest, int wDest, int hDest, 05879 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp); 05880 05881 //{---------------------------------------------------------------------------------------------------------------- 05884 //}---------------------------------------------------------------------------------------------------------------- 05885 05886 const unsigned _TX_BUFSIZE = 1024, 05887 _TX_BIGBUFSIZE = _TX_BUFSIZE * 2, 05888 _TX_HUGEBUFSIZE = _TX_BUFSIZE * 20, 05889 05890 _TX_STACKSIZE = 64 * 1024; 05891 05892 //{---------------------------------------------------------------------------------------------------------------- 05895 //}---------------------------------------------------------------------------------------------------------------- 05896 05897 #if !defined (_TX_EXCEPTIONS_LIMIT) 05898 #define _TX_EXCEPTIONS_LIMIT 16 05899 #endif 05900 05901 #if !defined (_TX_FATAL_EXCEPTIONS_LIMIT) 05902 #define _TX_FATAL_EXCEPTIONS_LIMIT 16 //!< Максимальное количество фатальных исключений. 05903 #endif 05904 05905 //{---------------------------------------------------------------------------------------------------------------- 05908 //}---------------------------------------------------------------------------------------------------------------- 05909 05910 #ifdef FOR_DOXYGEN_ONLY 05911 #define _TX_FULL_STACKTRACE 05912 #endif 05913 05914 //{---------------------------------------------------------------------------------------------------------------- 05917 //}---------------------------------------------------------------------------------------------------------------- 05918 05919 #ifndef TX_COMPILED 05920 05921 bool _txProcessSystemWarnings = true; 05922 05923 #endif // TX_COMPILED 05924 05925 extern bool _txProcessSystemWarnings; 05926 05927 //{---------------------------------------------------------------------------------------------------------------- 05941 //}---------------------------------------------------------------------------------------------------------------- 05942 05943 #if !defined (_TX_WAITABLE_PARENTS) 05944 #define _TX_WAITABLE_PARENTS "Winpty-agent.exe:Clion.exe, " /* 0: CLion32 */ \ 05945 "Winpty-agent.exe:Clion64.exe, " /* 1: CLion64 */ \ 05946 "starter.exe:eclipse.exe, " /* 2: Eclipse 4 */ \ 05947 "starter.exe:javaw.exe, " /* 3: Eclipse 3 */ \ 05948 "cmd.exe:devenv.exe, " /* 4: MSVS 2003+ */ \ 05949 "VSDebugConsole.exe:devenv.exe, " /* 5: MSVS 2019+ */ \ 05950 "VSDebugConsole.exe:msvsmon.exe, " /* 6: MSVS 2022 x86 */ \ 05951 "consolepauser.exe:devcpp.exe, " /* 7: Dev-Cpp */ \ 05952 "cb_console_runner.exe:codeblocks.exe" /* 8: CodeBlocks 8+ */ 05953 #endif 05954 05955 //{---------------------------------------------------------------------------------------------------------------- 05974 //}---------------------------------------------------------------------------------------------------------------- 05975 05976 #if !defined (_TX_ALLOW_KILL_PARENT) // DISCLAIMER: Я не призываю к убийству родителей. 05977 #define _TX_ALLOW_KILL_PARENT true // Это технический термин. 05978 #endif // г_дам юристам привет. 05979 05980 //{---------------------------------------------------------------------------------------------------------------- 05990 //}---------------------------------------------------------------------------------------------------------------- 05991 05992 #ifndef TX_COMPILED 05993 05994 int _txWatchdogTimeout = 10*_TX_TIMEOUT; 05995 05996 #endif // TX_COMPILED 05997 05998 extern int _txWatchdogTimeout; 05999 06000 //{---------------------------------------------------------------------------------------------------------------- 06069 //}---------------------------------------------------------------------------------------------------------------- 06071 06072 #ifdef FOR_DOXYGEN_ONLY 06073 06074 #define TX_COMPILED 06075 06076 #endif 06077 06079 06081 //} 06082 //================================================================================================================= 06083 06084 //================================================================================================================= 06085 //{ Internal diagnostics 06087 //================================================================================================================= 06089 //{---------------------------------------------------------------------------------------------------------------- 06129 //}---------------------------------------------------------------------------------------------------------------- 06130 06131 #ifdef FOR_DOXYGEN_ONLY 06132 #define _TX_ALLOW_TRACE 06133 #endif 06134 06135 //{---------------------------------------------------------------------------------------------------------------- 06165 //}---------------------------------------------------------------------------------------------------------------- 06166 06167 #ifdef FOR_DOXYGEN_ONLY 06168 #define TX_TRACE 06169 #endif 06170 06171 #if !defined (TX_TRACE) 06172 #define TX_TRACE { if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__); } 06173 #endif 06174 06176 void _txTrace (const char file[], int line, const char func[], const char msg[] = NULL, ...); 06178 06179 //{---------------------------------------------------------------------------------------------------------------- 06182 06183 #ifndef FOR_DOXYGEN_ONLY 06184 06185 struct _txLoc 06186 { 06187 const char* func; 06188 const char* file; 06189 int line; 06190 06191 int inTX; // We are inside one of TXLib functions 06192 int trace; // Internal TX trace level, when enabled by _TX_ALLOW_TRACE 06193 06194 const _txLoc* prev; // Caller's location 06195 06196 static _txLoc _tx_thread Cur; 06197 }; 06198 06199 struct _txFuncEntry 06200 { 06201 typedef _txFuncEntry this_t; 06202 06203 _txLoc loc; 06204 06205 _txFuncEntry() : loc (_txLoc::Cur) { _txLoc::Cur.inTX++; _txLoc::Cur.prev = &loc; } 06206 void restore() { _txLoc::Cur = loc; } 06207 ~_txFuncEntry() { restore(); } 06208 06209 private: 06210 _txFuncEntry (const this_t&) _tx_delete; 06211 this_t& operator = (const this_t&) _tx_delete; 06212 }; 06213 06214 #if defined (_GCC_VER) 06215 06216 inline const char* __txLocCurSet (const char* _file, int _line, const char* _func) 06217 { _txLoc::Cur.file = _file; _txLoc::Cur.line = _line; _txLoc::Cur.func = _func; return _func; } 06218 06219 #else 06220 06221 #define __txLocCurSet( _file, _line, _func ) \ 06222 ( _txLoc::Cur.file = (_file), _txLoc::Cur.line = (_line), _txLoc::Cur.func = (_func) ) 06223 06224 #endif 06225 06226 #define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, __TX_FUNCTION__) 06227 06228 #define _txLocLvlSet(lvl) { _txLoc::Cur.trace = (lvl); } 06229 06230 //{---------------------------------------------------------------------------------------------------------------- 06231 06232 #if defined ($0) 06233 #undef $0 06234 #endif 06235 06236 #if defined ($1) 06237 #undef $1 06238 #endif 06239 06240 #if defined ($2) 06241 #undef $2 06242 #endif 06243 06244 #if defined ($3) 06245 #undef $3 06246 #endif 06247 06248 #if defined ($4) 06249 #undef $4 06250 #endif 06251 06252 #if defined ($5) 06253 #undef $5 06254 #endif 06255 06256 #if defined ($6) 06257 #undef $6 06258 #endif 06259 06260 #if defined ($7) 06261 #undef $7 06262 #endif 06263 06264 #if defined ($8) 06265 #undef $8 06266 #endif 06267 06268 #if defined ($9) 06269 #undef $9 06270 #endif 06271 06272 #if defined ($) 06273 #undef $ 06274 #endif 06275 06276 #if defined ($$) 06277 #undef $$ 06278 #endif 06279 06280 //} 06281 //----------------------------------------------------------------------------------------------------------------- 06282 06283 #if defined (_TX_ALLOW_TRACE) 06284 06285 #define _txEntry(lvl) _txFuncEntry __txFuncEntry; { if (lvl) _txLocLvlSet (lvl); $; } 06286 06287 #define $ { _txLocCurSet(); if (_txLoc::Cur.trace <= _TX_ALLOW_TRACE+0) { TX_TRACE; } } 06288 06289 #define $$ { __txFuncEntry.restore(); } 06290 06291 #elif defined (_DEBUG) 06292 06293 #define _txEntry(lvl) _txFuncEntry __txFuncEntry; { $; } 06294 06295 #define $ { _txLocCurSet(); } 06296 06297 #define $$ { __txFuncEntry.restore(); } 06298 06299 #else 06300 06301 #define _txEntry(lvl) ; 06302 #define $ ; 06303 #define $$ ; 06304 06305 #endif 06306 06307 //{---------------------------------------------------------------------------------------------------------------- 06308 06309 #define $0 _txEntry (0) // (Log level unchanged) 06310 #define $1 _txEntry (1) // Regular functions 06311 #define $2 _txEntry (2) // Resvd 06312 #define $3 _txEntry (3) // Init/Cleanup 06313 #define $4 _txEntry (4) // Init/Cleanup, misc functions 06314 #define $5 _txEntry (5) // Error handling, entry points 06315 #define $6 _txEntry (6) // Error handling, main part 06316 #define $7 _txEntry (7) // Error handling, misc functions 06317 #define $8 _txEntry (8) // Canvas worker thread 06318 #define $9 _txEntry (9) // Resvd 06319 06320 //} 06321 //----------------------------------------------------------------------------------------------------------------- 06322 06323 #endif // FOR_DOXYGEN_ONLY 06324 06327 //}---------------------------------------------------------------------------------------------------------------- 06328 06330 //} 06331 //================================================================================================================= 06332 06333 //================================================================================================================= 06334 //{ Sweet critical section blocking: txAutoLock class 06335 //================================================================================================================= 06336 06337 //{---------------------------------------------------------------------------------------------------------------- 06353 //}---------------------------------------------------------------------------------------------------------------- 06354 06356 extern CRITICAL_SECTION _txCanvas_LockBackBuf; 06358 06359 class txAutoLock 06360 { 06361 typedef txAutoLock this_t; 06362 06363 public: 06364 06365 //{---------------------------------------------------------------------------------------------------------------- 06388 //}---------------------------------------------------------------------------------------------------------------- 06389 06390 explicit txAutoLock (CRITICAL_SECTION* cs, bool mandatory = true) : 06391 cs_ (cs) 06392 { 06393 $1 if (!cs_) return; 06394 06395 if (mandatory) {$ EnterCriticalSection (cs_); } 06396 else {$ TryEnterCriticalSection (cs_)? 0 : (cs_ = NULL); } 06397 } 06398 06399 //{---------------------------------------------------------------------------------------------------------------- 06412 //}---------------------------------------------------------------------------------------------------------------- 06413 06414 explicit txAutoLock (bool mandatory = true) : 06415 cs_ (NULL) 06416 { 06417 $1 new (this) txAutoLock (&_txCanvas_LockBackBuf, mandatory); 06418 } 06419 06420 //{---------------------------------------------------------------------------------------------------------------- 06422 //}---------------------------------------------------------------------------------------------------------------- 06423 06424 ~txAutoLock() 06425 { 06426 $1 if (!cs_) return; 06427 $ LeaveCriticalSection (cs_); cs_ = NULL; 06428 } 06429 06430 //{---------------------------------------------------------------------------------------------------------------- 06433 //}---------------------------------------------------------------------------------------------------------------- 06434 06435 operator bool () const 06436 { 06437 $1 return (cs_ != NULL); 06438 } 06439 06440 //{---------------------------------------------------------------------------------------------------------------- 06442 //}---------------------------------------------------------------------------------------------------------------- 06443 06444 // private: 06445 CRITICAL_SECTION* cs_; 06446 06447 //{---------------------------------------------------------------------------------------------------------------- 06449 //}---------------------------------------------------------------------------------------------------------------- 06451 06452 private: 06453 txAutoLock (const this_t&) _tx_delete; 06454 this_t& operator = (const this_t&) _tx_delete; 06455 06457 06458 }; 06459 06460 //} 06461 //================================================================================================================= 06462 06463 //================================================================================================================= 06464 //{ Dialogs: txDialog class 06466 //================================================================================================================= 06468 //{---------------------------------------------------------------------------------------------------------------- 06489 //}---------------------------------------------------------------------------------------------------------------- 06490 06491 struct txDialog 06492 { 06493 typedef txDialog this_t; 06494 06495 //{---------------------------------------------------------------------------------------------------------------- 06508 //}---------------------------------------------------------------------------------------------------------------- 06509 06510 public: 06511 enum CONTROL 06512 { 06513 DIALOG = (int) 0x00000000, 06514 BUTTON = (int) 0xFFFF0080, 06515 EDIT = (int) 0xFFFF0081, 06516 STATIC = (int) 0xFFFF0082, 06517 LISTBOX = (int) 0xFFFF0083, 06518 SCROLLBAR = (int) 0xFFFF0084, 06519 COMBOBOX = (int) 0xFFFF0085, 06520 END = (int) 0x00000000 06521 }; 06522 06523 //{---------------------------------------------------------------------------------------------------------------- 06540 //}---------------------------------------------------------------------------------------------------------------- 06541 06542 public: 06543 struct Layout 06544 { //-V802 06545 CONTROL wndclass; 06546 const char* caption; 06547 WORD id; 06548 short x; 06549 short y; 06550 short sx; 06551 short sy; 06552 DWORD style; 06553 06554 const char* font; 06555 WORD fontsize; 06556 }; 06557 06558 //{---------------------------------------------------------------------------------------------------------------- 06566 //}---------------------------------------------------------------------------------------------------------------- 06567 06568 public: 06569 txDialog(); 06570 06571 //{---------------------------------------------------------------------------------------------------------------- 06581 //}---------------------------------------------------------------------------------------------------------------- 06582 06583 explicit txDialog (const Layout* layout); 06584 06585 //{---------------------------------------------------------------------------------------------------------------- 06587 //}---------------------------------------------------------------------------------------------------------------- 06588 06589 virtual ~txDialog() {}; 06590 06591 //{---------------------------------------------------------------------------------------------------------------- 06603 //}---------------------------------------------------------------------------------------------------------------- 06604 06605 const Layout* setLayout (const Layout *layout); 06606 06607 //{---------------------------------------------------------------------------------------------------------------- 06625 //}---------------------------------------------------------------------------------------------------------------- 06626 06627 virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam); 06628 06629 //{---------------------------------------------------------------------------------------------------------------- 06645 //}---------------------------------------------------------------------------------------------------------------- 06646 06647 intptr_t dialogBox (const Layout* layout = NULL, size_t bufsize = 0); 06648 06649 //{---------------------------------------------------------------------------------------------------------------- 06662 //}---------------------------------------------------------------------------------------------------------------- 06663 06664 intptr_t dialogBox (WORD resource); 06665 06666 //{---------------------------------------------------------------------------------------------------------------- 06668 //}---------------------------------------------------------------------------------------------------------------- 06669 06670 private: 06671 txDialog (const this_t&) _tx_delete; 06672 this_t& operator = (const this_t&) _tx_delete; 06673 06674 //{---------------------------------------------------------------------------------------------------------------- 06676 //}---------------------------------------------------------------------------------------------------------------- 06677 06678 protected: 06679 static intptr_t CALLBACK DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam); 06680 06681 //{---------------------------------------------------------------------------------------------------------------- 06683 //}---------------------------------------------------------------------------------------------------------------- 06684 06685 private: 06686 const Layout* layout_; 06687 }; 06688 06690 //} 06691 //================================================================================================================= 06692 06693 //================================================================================================================= 06694 //{ Dialogs: Message Map macros 06696 //================================================================================================================= 06698 //{---------------------------------------------------------------------------------------------------------------- 06719 //}---------------------------------------------------------------------------------------------------------------- 06720 06721 #define TX_BEGIN_MESSAGE_MAP() \ 06722 virtual int dialogProc (HWND _wnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) _tx_override \ 06723 { \ 06724 int _result = txDialog::dialogProc (_wnd, _msg, _wParam, _lParam); (void) _result; \ 06725 \ 06726 switch (_msg) \ 06727 { \ 06728 case WM_NULL: 06729 06730 //{---------------------------------------------------------------------------------------------------------------- 06749 //}---------------------------------------------------------------------------------------------------------------- 06750 06751 #define TX_HANDLE( id ) \ 06752 break; \ 06753 case (id): 06754 06755 //{---------------------------------------------------------------------------------------------------------------- 06775 //}---------------------------------------------------------------------------------------------------------------- 06776 06777 #define TX_COMMAND_MAP \ 06778 default: break; \ 06779 } \ 06780 \ 06781 if (_msg == WM_COMMAND) switch (LOWORD (_wParam)) \ 06782 { \ 06783 case 0: 06784 06785 //{---------------------------------------------------------------------------------------------------------------- 06804 //}---------------------------------------------------------------------------------------------------------------- 06805 06806 #define TX_END_MESSAGE_MAP \ 06807 default: break; \ 06808 } \ 06809 \ 06810 return FALSE; \ 06811 } 06812 06814 //} 06815 //================================================================================================================= 06816 06817 //================================================================================================================= 06818 //{ Dialogs: txDialog example: txInputBox() 06820 //================================================================================================================= 06822 //{---------------------------------------------------------------------------------------------------------------- 06842 //}---------------------------------------------------------------------------------------------------------------- 06843 06844 const char* txInputBox (const char* text = NULL, const char* caption = NULL, const char* input = NULL) tx_nodiscard; 06845 06846 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 06847 06848 const char* txInputBox (const char* text, const char* caption, const char* input) 06849 { 06850 //------------------------------------------------------------------------------------------------------------- 06851 // Если не указаны параметры, приходится использовать хоть какие-то надписи. 06852 // txGetModuleFileName() -- имя EXE-файла, на случай, если кое-кто поленился задать название. 06853 //------------------------------------------------------------------------------------------------------------- 06854 06855 if (!text) text = "Введите строку:"; 06856 if (!caption) caption = txGetModuleFileName (false); 06857 if (!input) input = ""; 06858 06859 //------------------------------------------------------------------------------------------------------------- 06860 // Идентификаторы элементов диалога. Они требуются в GetDlgItemText(). 06861 // Если диалог строится не вручную, а редактором ресурсов, то они задаются в нем автоматически. 06862 // У нас же тут -- хардкор стайл, к сожалению. Причина в том, что у разных сред программирования разные редакторы 06863 // ресурсов и системы сборки. Поэтому для независимости от них все будет строиться на этапе выполнения, 06864 // динамически. Вы еще гляньте, как это реализовано в txDialog::dialogBox() и функциях _tx_DLGTEMPLATE_()... О_о 06865 //------------------------------------------------------------------------------------------------------------- 06866 06867 #define ID_TEXT_ 101 06868 #define ID_INPUT_ 102 06869 06870 //------------------------------------------------------------------------------------------------------------- 06871 // Задание макета (вида) диалога в виде массива структур. 06872 // С помощью особого порядка полей в структуре txDialog::Layout и констант из класса txDialog этот массив 06873 // становится похож на описание ресурса диалога в .rc-файле. 06874 // См. описание синтаксиса rc-файла в документации по Win32 (MSDN, http://msdn.com). 06875 //------------------------------------------------------------------------------------------------------------- 06876 06877 txDialog::Layout layout[] = 06878 06879 //----------------------+----------+-----------+-----------------+--------------------------------------------- 06880 // Тип элемента | Имя | Иденти- | Координаты | Флаги элементов 06881 // диалога | элемента | фикатор |-----------------| (см. описание элементов 06882 // | | элемента | X | Y |Шир.|Выс.| окон диалога в MSDN) 06883 //----------------------+----------+-----------+---+---+----+----+--------------------------------------------- 06884 // | | | | | | | 06885 {{ txDialog::DIALOG, caption, 0, 0, 0, 240, 85 }, 06886 { txDialog::STATIC, text, ID_TEXT_, 10, 10, 150, 40, SS_LEFT }, 06887 { txDialog::EDIT, input, ID_INPUT_, 10, 60, 220, 15, ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP }, 06888 { txDialog::BUTTON, "&OK", IDOK, 180, 10, 50, 15, BS_DEFPUSHBUTTON | WS_TABSTOP }, 06889 { txDialog::BUTTON, "&Cancel", IDCANCEL, 180, 30, 50, 15, BS_PUSHBUTTON | WS_TABSTOP }, 06890 { txDialog::END }}; 06891 06892 //------------------------------------------------------------------------------------------------------------- 06893 // Класс диалога для InputBox. Внутренний, т.к. зачем ему быть внешним. 06894 // Нужен в основном для задания строки ввода (str) и оконной функции диалогового окна, требуемой Win32 (она 06895 // построена макросами TX_BEGIN_MESSAGE_MAP и другими). Можно не делать внутреннего класса, но тогда оконную 06896 // функцию придется писать в глобальной области видимости, и str объявлять глобально тоже (или передавать ее 06897 // адрес через DialogBoxParam и записывать его в класс во время обработки WM_INITDIALOG). 06898 //------------------------------------------------------------------------------------------------------------- 06899 struct inputDlg : txDialog 06900 { 06901 char str [1024]; 06902 06903 //--------------------------------------------------------------------------------------------------------- 06904 06905 inputDlg() : 06906 str() 06907 {} 06908 06909 //--------------------------------------------------------------------------------------------------------- 06910 06911 TX_BEGIN_MESSAGE_MAP() // Карта сообщений (на самом деле это начало оконной функции). //-V2525 06912 06913 TX_COMMAND_MAP // Здесь обрабатываются WM_COMMAND (на самом деле это оператор switch). 06914 06915 //------------------------------------------------------------------------------------------------- 06916 // При нажатии кнопки OK копируем строку из поля ввода в нашу переменную str, т.к. после закрытия 06917 // диалога строка ввода умрет и текст уже из нее получить. 06918 // Этот макрос на самом деле превращается в case из оператора switch. 06919 // _wnd -- это параметр оконной функции, см. определение макроса TX_BEGIN_MESSAGE_MAP(). 06920 //------------------------------------------------------------------------------------------------- 06921 06922 TX_HANDLE (IDOK) GetDlgItemText (_wnd, ID_INPUT_, str, sizeof (str) - 1); 06923 06924 TX_END_MESSAGE_MAP //-V2522 06925 06926 //--------------------------------------------------------------------------------------------------------- 06927 // Конец внутреннего класса диалога 06928 //--------------------------------------------------------------------------------------------------------- 06929 }; 06930 06931 //------------------------------------------------------------------------------------------------------------- 06932 // Убираем дефайны, чтобы потом не мешали. 06933 // От этого они получаются "локального действия", как будто у них была бы область видимости -- функция. На самом 06934 // деле это сделано вручную через #undef. Чтобы подчеркнуть их локальную природу, у них имена заканчиваются на _. 06935 // Такие дефайны потом не перекосячат весь код после того как, фактически, стали уже не нужны. 06936 //------------------------------------------------------------------------------------------------------------- 06937 06938 #undef ID_TEXT_ 06939 #undef ID_INPUT_ 06940 06941 //------------------------------------------------------------------------------------------------------------- 06942 // Это статический объект, потому что строка в нем должна жить после завершения функции. 06943 //------------------------------------------------------------------------------------------------------------- 06944 06945 static inputDlg dlg; 06946 06947 //------------------------------------------------------------------------------------------------------------- 06948 // Передаем layout и запускаем окно диалога 06949 //------------------------------------------------------------------------------------------------------------- 06950 06951 dlg.dialogBox (layout); 06952 06953 //------------------------------------------------------------------------------------------------------------- 06954 // Возвращаем адрес строки из статического объекта. Так можно делать, потому что статический объект не умрет 06955 // при выходе из функции и строка в нем, соответственно, тоже. Адрес нестатических переменных передавать 06956 // синтаксически можно, но ведет к серьезным ошибкам. 06957 //------------------------------------------------------------------------------------------------------------- 06958 06959 return dlg.str; 06960 } 06961 06962 #endif // TX_COMPILED 06963 06965 //} 06966 //================================================================================================================= 06967 06968 //} 06969 //================================================================================================================= 06970 06971 //================================================================================================================= 06972 //{ TXLIB IMPLEMENTATION 06973 // Реализация функций библиотеки 06974 //================================================================================================================= 06976 06977 //----------------------------------------------------------------------------------------------------------------- 06978 //{ The Includes 06979 //----------------------------------------------------------------------------------------------------------------- 06980 06981 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 06982 06983 _TX_END_NAMESPACE 06984 06985 //----------------------------------------------------------------------------------------------------------------- 06986 06987 #if defined (_MSC_VER) 06988 #pragma warning (push, 3) // MSVC: At level /Wall, some std headers emit warnings... O_o 06989 06990 #pragma warning (disable: 4365) // 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch 06991 #pragma warning (disable: 4005) // 'name': macro redefinition 06992 #endif 06993 06994 #if defined (__STRICT_ANSI__) && defined (__STRICT_ANSI__UNDEFINED) 06995 #undef __STRICT_ANSI__ 06996 #endif 06997 06998 //----------------------------------------------------------------------------------------------------------------- 06999 07000 #include <stdarg.h> 07001 #include <io.h> 07002 #include <fcntl.h> 07003 #include <process.h> 07004 #include <signal.h> 07005 #include <setjmp.h> 07006 #include <locale.h> 07007 #include <limits.h> 07008 #include <stdint.h> 07009 07010 #include <map> 07011 #include <numeric> 07012 #include <exception> 07013 #include <stdexcept> 07014 07015 #include <tlhelp32.h> 07016 #include <shellapi.h> 07017 07018 #if defined (_GCC_VER) 07019 07020 #include <shlobj.h> 07021 07022 #include <cxxabi.h> 07023 #include <unwind.h> 07024 07025 #endif 07026 07027 #if defined (__CYGWIN__) 07028 07029 #include <stdarg.h> 07030 #include <unistd.h> 07031 #include <termios.h> 07032 07033 #endif 07034 07035 #if defined (_MSC_VER) 07036 07037 #include <new.h> 07038 07039 #include <shlobj.h> 07040 #include <ntstatus.h> 07041 #include <crtdbg.h> 07042 #include <rtcapi.h> 07043 #include <dbghelp.h> 07044 07045 #endif 07046 07047 #if defined (_GCC_VER) || defined (_MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 07048 #include <inttypes.h> 07049 #endif 07050 07051 //----------------------------------------------------------------------------------------------------------------- 07052 07053 #if defined (TX_USE_SPEAK) //-------------------------------------------------------------------------------------- 07054 #include <SAPI.h> // <== ЕСЛИ ЗДЕСЬ ОШИБКА, ТО У ВАС НЕТ ФАЙЛА SAPI.h. No SAPI.h file, TXLib isn't guilty :( 07055 #endif //-------------------------------------------------------------------------------------- 07056 07057 //----------------------------------------------------------------------------------------------------------------- 07058 07059 #if defined (_MSC_VER) 07060 #pragma warning (pop) // MSVC: Restore max level 07061 #endif 07062 07063 #if defined (__STRICT_ANSI__UNDEFINED) 07064 #define __STRICT_ANSI__ // Redefine back 07065 #endif 07066 07067 //----------------------------------------------------------------------------------------------------------------- 07068 07069 _TX_BEGIN_NAMESPACE 07070 07071 #endif // TX_COMPILED 07072 07073 //} 07074 //----------------------------------------------------------------------------------------------------------------- 07075 07076 //================================================================================================================= 07077 //{ DLL functions import, missing types definitions 07079 //================================================================================================================= 07081 07082 //----------------------------------------------------------------------------------------------------------------- 07083 //{ Some of structs, consts and interfaces aren't defined in MinGW some early headers. 07084 // Copied from Windows SDK 7.0a. 07085 //----------------------------------------------------------------------------------------------------------------- 07086 07087 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07088 07089 namespace Win32 { 07090 07091 #ifndef AC_SRC_ALPHA 07092 #define AC_SRC_ALPHA 0x01 07093 #endif 07094 07095 #ifndef SMTO_ERRORONEXIT 07096 #define SMTO_ERRORONEXIT 0x0020 07097 #endif 07098 07099 #ifndef NT_CONSOLE_PROPS_SIG 07100 #define NT_CONSOLE_PROPS_SIG 0xA0000002 07101 #endif 07102 07103 #ifndef NIIF_INFO 07104 #define NIIF_INFO 0x00000001 07105 #define NIIF_WARNING 0x00000002 07106 #define NIIF_ERROR 0x00000003 07107 #endif 07108 07109 #ifndef NIF_INFO 07110 #define NIF_STATE 0x00000008 07111 #define NIF_INFO 0x00000010 07112 #endif 07113 07114 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 07115 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x00000004 07116 #endif 07117 07118 #ifndef SYMOPT_CASE_INSENSITIVE 07119 #define SYMOPT_CASE_INSENSITIVE 0x00000001 07120 #define SYMOPT_UNDNAME 0x00000002 07121 #define SYMOPT_DEFERRED_LOADS 0x00000004 07122 #define SYMOPT_NO_CPP 0x00000008 07123 #define SYMOPT_LOAD_LINES 0x00000010 07124 #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 07125 #define SYMOPT_LOAD_ANYTHING 0x00000040 07126 #define SYMOPT_IGNORE_CVREC 0x00000080 07127 #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 07128 #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 07129 #define SYMOPT_EXACT_SYMBOLS 0x00000400 07130 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 07131 #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 07132 #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 07133 #define SYMOPT_PUBLICS_ONLY 0x00004000 07134 #define SYMOPT_NO_PUBLICS 0x00008000 07135 #define SYMOPT_AUTO_PUBLICS 0x00010000 07136 #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 07137 #define SYMOPT_SECURE 0x00040000 07138 #define SYMOPT_NO_PROMPTS 0x00080000 07139 #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 07140 #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 07141 #define SYMOPT_FAVOR_COMPRESSED 0x00800000 07142 #define SYMOPT_FLAT_DIRECTORY 0x00400000 07143 #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 07144 #define SYMOPT_OVERWRITE 0x00100000 07145 #define SYMOPT_DEBUG 0x80000000 07146 #endif 07147 07148 // SEH exception codes. For GCC, see http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 64-66. 07149 07150 #ifndef STATUS_POSSIBLE_DEADLOCK 07151 #define STATUS_POSSIBLE_DEADLOCK 0xC0000194 07152 #endif 07153 07154 #ifndef STATUS_FLOAT_MULTIPLE_FAULTS 07155 #define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4 07156 #endif 07157 07158 #ifndef STATUS_STACK_BUFFER_OVERRUN 07159 #define STATUS_STACK_BUFFER_OVERRUN 0xC0000409 07160 #endif 07161 07162 #ifndef STATUS_ASSERTION_FAILURE 07163 #define STATUS_ASSERTION_FAILURE 0xC0000420 07164 #endif 07165 07166 #ifndef STATUS_WX86_BREAKPOINT 07167 #define STATUS_WX86_BREAKPOINT 0x4000001F 07168 #endif 07169 07170 #ifndef DBG_PRINTEXCEPTION_C 07171 #define DBG_PRINTEXCEPTION_C 0x40010006 // OutputDebugStringA() call 07172 #endif 07173 07174 #ifndef DBG_PRINTEXCEPTION_WIDE_C 07175 #define DBG_PRINTEXCEPTION_WIDE_C 0x4001000A // OutputDebugStringW() call 07176 #endif 07177 07178 #ifndef DBG_THREAD_NAME 07179 #define DBG_THREAD_NAME 0x406D1388 07180 #endif 07181 07182 #define EXCEPTION_CPP_MSC 0xE06D7363 // '?msc' 07183 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 0x19930520 // '?msc' version magic, see ehdata.h 07184 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 0x19930521 // '?msc' version magic 07185 #define EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 0x19930522 // '?msc' version magic 07186 #define EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1 0x01994000 // '?msc' version magic 07187 07188 #define EXCEPTION_CPP_GCC 0x20474343 // ' GCC' 07189 #define EXCEPTION_CPP_GCC_UNWIND 0x21474343 // '!GCC' 07190 #define EXCEPTION_CPP_GCC_FORCED 0x22474343 // '"GCC' 07191 07192 #define EXCEPTION_CLR_FAILURE 0xE0434f4D // 'аCOM' 07193 07194 #define EXCEPTION_CPP_BORLAND_BUILDER 0x0EEDFAE6 // Should never occur here 07195 #define EXCEPTION_CPP_BORLAND_DELPHI 0x0EEDFADE // Should never occur here 07196 07197 #pragma pack (push, 1) 07198 07199 struct CONSOLE_CURSOR_INFO 07200 { 07201 DWORD dwSize; 07202 BOOL bVisible; 07203 }; 07204 07205 struct CONSOLE_FONT_INFO 07206 { 07207 DWORD nFont; 07208 COORD dwFontSize; 07209 }; 07210 07211 struct CONSOLE_FONT_INFOEX 07212 { 07213 ULONG cbSize; 07214 DWORD nFont; 07215 COORD dwFontSize; 07216 UINT FontFamily; 07217 UINT FontWeight; 07218 WCHAR FaceName[LF_FACESIZE]; 07219 }; 07220 07221 struct DATABLOCK_HEADER 07222 { 07223 DWORD cbSize; 07224 DWORD dwSignature; 07225 }; 07226 07227 struct NT_CONSOLE_PROPS 07228 { 07229 DATABLOCK_HEADER dbh; 07230 07231 WORD wFillAttribute; 07232 WORD wPopupFillAttribute; 07233 COORD dwScreenBufferSize; 07234 COORD dwWindowSize; 07235 COORD dwWindowOrigin; 07236 DWORD nFont; 07237 DWORD nInputBufferSize; 07238 COORD dwFontSize; 07239 UINT uFontFamily; 07240 UINT uFontWeight; 07241 WCHAR FaceName[LF_FACESIZE]; 07242 UINT uCursorSize; 07243 BOOL bFullScreen; 07244 BOOL bQuickEdit; 07245 BOOL bInsertMode; 07246 BOOL bAutoPosition; 07247 UINT uHistoryBufferSize; 07248 UINT uNumberOfHistoryBuffers; 07249 BOOL bHistoryNoDup; 07250 07251 COLORREF ColorTable[16]; 07252 }; 07253 07254 struct FLASHWINFO 07255 { 07256 UINT cbSize; 07257 HWND hwnd; 07258 DWORD dwFlags; 07259 UINT uCount; 07260 DWORD dwTimeout; 07261 }; 07262 07263 enum TBPFLAG 07264 { 07265 TBPF_NOPROGRESS = 0x0, 07266 TBPF_INDETERMINATE = 0x1, 07267 TBPF_NORMAL = 0x2, 07268 TBPF_ERROR = 0x4, 07269 TBPF_PAUSED = 0x8 07270 }; 07271 07272 #pragma pack (pop) 07273 07274 const GUID IID_IShellLink = {0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 07275 const GUID IID_IShellLinkDataList = {0x45e2b4ae, 0xb1c3, 0x11d0, {0xb9,0x2f,0x00,0xa0,0xc9,0x03,0x12,0xe1}}; 07276 const GUID IID_IPersistFile = {0x0000010b, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 07277 07278 const GUID IID_ITaskbarList3 = {0xea1afb91, 0x9e28, 0x4b86, {0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf}}; 07279 const GUID CLSID_TaskbarList = {0x56fdf344, 0xfd6d, 0x11d0, {0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90}}; 07280 07281 const GUID CLSID_SpVoice = {0x96749377, 0x3391, 0x11d2, {0x9e,0xe3,0x00,0xc0,0x4f,0x79,0x73,0x96}}; 07282 const GUID IID_ISpVoice = {0x6c44df74, 0x72b9, 0x4992, {0xa1,0xec,0xef,0x99,0x6e,0x04,0x22,0xd4}}; 07283 07284 typedef DWORD NTSTATUS; 07285 typedef ULONG_PTR KAFFINITY; 07286 typedef LONG KPRIORITY; 07287 07288 struct UNICODE_STRING 07289 { 07290 USHORT Length; 07291 USHORT MaximumLength; 07292 wchar_t* Buffer; 07293 }; 07294 07295 struct RTL_DRIVE_LETTER_CURDIR 07296 { 07297 USHORT Flags; 07298 USHORT Length; 07299 ULONG TimeStamp; 07300 UNICODE_STRING DosPath; 07301 }; 07302 07303 struct CURDIR 07304 { 07305 UNICODE_STRING DosPath; 07306 void* Handle; 07307 }; 07308 07309 struct RTL_USER_PROCESS_PARAMETERS 07310 { 07311 ULONG AllocationSize; 07312 ULONG Size; 07313 ULONG Flags; 07314 ULONG DebugFlags; 07315 HANDLE ConsoleHandle; 07316 ULONG ConsoleFlags; 07317 HANDLE hStdInput; 07318 HANDLE hStdOutput; 07319 HANDLE hStdError; 07320 CURDIR CurrentDirectory; 07321 UNICODE_STRING DllPath; 07322 UNICODE_STRING ImagePathName; 07323 UNICODE_STRING CommandLine; 07324 wchar_t* Environment; 07325 ULONG dwX; 07326 ULONG dwY; 07327 ULONG dwXSize; 07328 ULONG dwYSize; 07329 ULONG dwXCountChars; 07330 ULONG dwYCountChars; 07331 ULONG dwFillAttribute; 07332 ULONG dwFlags; 07333 ULONG wShowWindow; 07334 UNICODE_STRING WindowTitle; 07335 UNICODE_STRING Desktop; 07336 UNICODE_STRING ShellInfo; 07337 UNICODE_STRING RuntimeInfo; 07338 RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; 07339 }; 07340 07341 struct PEB 07342 { 07343 BYTE Reserved1[2]; 07344 BYTE BeingDebugged; 07345 BYTE Reserved2[1]; 07346 void* Reserved3[2]; 07347 void* Ldr; 07348 RTL_USER_PROCESS_PARAMETERS* ProcessParameters; 07349 void* Reserved4[3]; 07350 void* AtlThunkSListPtr; 07351 void* Reserved5; 07352 ULONG Reserved6; 07353 void* Reserved7; 07354 ULONG Reserved8; 07355 ULONG AtlThunkSListPtr32; 07356 void* Reserved9[45]; 07357 BYTE Reserved10[96]; 07358 void* PostProcessInitRoutine; 07359 BYTE Reserved11[128]; 07360 void* Reserved12[1]; 07361 ULONG SessionId; 07362 }; 07363 07364 struct TEB 07365 { 07366 void* Reserved1[12]; 07367 PEB* ProcessEnvironmentBlock; 07368 void* Reserved2[399]; 07369 BYTE Reserved3[1952]; 07370 void* TlsSlots[64]; 07371 BYTE Reserved4[8]; 07372 void* Reserved5[26]; 07373 void* ReservedForOle; 07374 void* Reserved6[4]; 07375 void* TlsExpansionSlots; 07376 }; 07377 07378 struct PROCESS_BASIC_INFORMATION 07379 { 07380 NTSTATUS ExitStatus; 07381 PEB* PebBaseAddress; 07382 KAFFINITY AffinityMask; 07383 KPRIORITY BasePriority; 07384 ULONG_PTR UniqueProcessId; 07385 ULONG_PTR InheritedFromUniqueProcessId; 07386 }; 07387 07388 enum ADDRESS_MODE 07389 { 07390 AddrMode1616, 07391 AddrMode1632, 07392 AddrModeReal, 07393 AddrModeFlat 07394 }; 07395 07396 struct ADDRESS64 07397 { 07398 DWORD64 Offset; 07399 WORD Segment; 07400 ADDRESS_MODE Mode; 07401 }; 07402 07403 struct KDHELP64 07404 { 07405 DWORD64 Thread; 07406 DWORD ThCallbackStack; 07407 DWORD ThCallbackBStore; 07408 DWORD NextCallback; 07409 DWORD FramePointer; 07410 DWORD64 KiCallUserMode; 07411 DWORD64 KeUserCallbackDispatcher; 07412 DWORD64 SystemRangeStart; 07413 DWORD64 KiUserExceptionDispatcher; 07414 DWORD64 StackBase; 07415 DWORD64 StackLimit; 07416 DWORD64 Reserved[5]; 07417 }; 07418 07419 struct STACKFRAME64 07420 { 07421 ADDRESS64 AddrPC; 07422 ADDRESS64 AddrReturn; 07423 ADDRESS64 AddrFrame; 07424 ADDRESS64 AddrStack; 07425 ADDRESS64 AddrBStore; 07426 void* FuncTableEntry; 07427 DWORD64 Params[4]; 07428 BOOL Far; 07429 BOOL Virtual; 07430 DWORD64 Reserved[3]; 07431 KDHELP64 KdHelp; 07432 }; 07433 07434 struct WOW64_FLOATING_SAVE_AREA 07435 { 07436 DWORD ControlWord; 07437 DWORD StatusWord; 07438 DWORD TagWord; 07439 DWORD ErrorOffset; 07440 DWORD ErrorSelector; 07441 DWORD DataOffset; 07442 DWORD DataSelector; 07443 BYTE RegisterArea[80]; 07444 DWORD Cr0NpxState; 07445 }; 07446 07447 #pragma pack (push, 4) 07448 07449 struct WOW64_CONTEXT 07450 { 07451 DWORD ContextFlags; 07452 07453 DWORD Dr0; 07454 DWORD Dr1; 07455 DWORD Dr2; 07456 DWORD Dr3; 07457 DWORD Dr6; 07458 DWORD Dr7; 07459 07460 WOW64_FLOATING_SAVE_AREA FloatSave; 07461 07462 DWORD SegGs; 07463 DWORD SegFs; 07464 DWORD SegEs; 07465 DWORD SegDs; 07466 07467 DWORD Edi; 07468 DWORD Esi; 07469 DWORD Ebx; 07470 DWORD Edx; 07471 DWORD Ecx; 07472 DWORD Eax; 07473 07474 DWORD Ebp; 07475 DWORD Eip; 07476 DWORD SegCs; 07477 DWORD EFlags; 07478 DWORD Esp; 07479 DWORD SegSs; 07480 07481 BYTE ExtendedRegisters[512]; 07482 }; 07483 07484 #pragma pack (pop) 07485 07486 struct SYMBOL_INFO 07487 { 07488 ULONG SizeOfStruct; 07489 ULONG TypeIndex; 07490 ULONG64 Reserved[2]; 07491 ULONG info; 07492 ULONG Size; 07493 ULONG64 ModBase; 07494 ULONG Flags; 07495 ULONG64 Value; 07496 ULONG64 Address; 07497 ULONG Register; 07498 ULONG Scope; 07499 ULONG Tag; 07500 ULONG NameLen; 07501 ULONG MaxNameLen; 07502 char Name[1]; 07503 }; 07504 07505 struct IMAGEHLP_LINE64 07506 { 07507 DWORD SizeOfStruct; 07508 void* Key; 07509 DWORD LineNumber; 07510 char* FileName; 07511 DWORD64 Address; 07512 }; 07513 07514 typedef bool (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64) (HANDLE process, DWORD64 baseAddress, void* buffer, DWORD size, DWORD* bytesRead); 07515 typedef void* (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64) (HANDLE process, DWORD64 baseAddress); 07516 typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64) (HANDLE process, DWORD64 address); 07517 typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64) (HANDLE process, HANDLE thread, ADDRESS64* address); 07518 07519 typedef void (*unexpected_handler)(); 07520 07521 #pragma pack (push, 4) 07522 07523 struct MINIDUMP_THREAD_CALLBACK 07524 { 07525 ULONG ThreadId; 07526 HANDLE ThreadHandle; 07527 CONTEXT Context; 07528 ULONG SizeOfContext; 07529 ULONG64 StackBase; 07530 ULONG64 StackEnd; 07531 }; 07532 07533 struct MINIDUMP_THREAD_EX_CALLBACK 07534 { 07535 ULONG ThreadId; 07536 HANDLE ThreadHandle; 07537 CONTEXT Context; 07538 ULONG SizeOfContext; 07539 ULONG64 StackBase; 07540 ULONG64 StackEnd; 07541 ULONG64 BackingStoreBase; 07542 ULONG64 BackingStoreEnd; 07543 }; 07544 07545 struct MINIDUMP_MODULE_CALLBACK 07546 { 07547 wchar_t* FullPath; 07548 ULONG64 BaseOfImage; 07549 ULONG SizeOfImage; 07550 ULONG CheckSum; 07551 ULONG TimeDateStamp; 07552 VS_FIXEDFILEINFO VersionInfo; 07553 void* CvRecord; 07554 ULONG SizeOfCvRecord; 07555 void* MiscRecord; 07556 ULONG SizeOfMiscRecord; 07557 }; 07558 07559 struct MINIDUMP_INCLUDE_THREAD_CALLBACK 07560 { 07561 ULONG ThreadId; 07562 }; 07563 07564 struct MINIDUMP_INCLUDE_MODULE_CALLBACK 07565 { 07566 ULONG64 BaseOfImage; 07567 }; 07568 07569 struct MINIDUMP_MEMORY_INFO 07570 { 07571 ULONG64 BaseAddress; 07572 ULONG64 AllocationBase; 07573 ULONG32 AllocationProtect; 07574 ULONG32 __alignment1; 07575 ULONG64 RegionSize; 07576 ULONG32 State; 07577 ULONG32 Protect; 07578 ULONG32 Type; 07579 ULONG32 __alignment2; 07580 }; 07581 07582 struct MINIDUMP_USER_STREAM 07583 { 07584 ULONG32 Type; 07585 ULONG BufferSize; 07586 void* Buffer; 07587 }; 07588 07589 struct MINIDUMP_USER_STREAM_INFORMATION 07590 { 07591 ULONG UserStreamCount; 07592 MINIDUMP_USER_STREAM* UserStreamArray; 07593 }; 07594 07595 struct MINIDUMP_CALLBACK_INPUT 07596 { 07597 ULONG ProcessId; 07598 HANDLE ProcessHandle; 07599 ULONG CallbackType; 07600 07601 union //-V2514 07602 { 07603 MINIDUMP_THREAD_CALLBACK Thread; 07604 MINIDUMP_THREAD_EX_CALLBACK ThreadEx; 07605 MINIDUMP_MODULE_CALLBACK Module; 07606 MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; 07607 MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; 07608 }; 07609 }; 07610 07611 struct MINIDUMP_CALLBACK_OUTPUT 07612 { 07613 union //-V2514 07614 { 07615 ULONG ModuleWriteFlags; 07616 ULONG ThreadWriteFlags; 07617 ULONG SecondaryFlags; 07618 07619 struct 07620 { 07621 ULONG64 MemoryBase; 07622 ULONG MemorySize; 07623 }; 07624 07625 struct 07626 { 07627 unsigned CheckCancel; 07628 unsigned Cancel; 07629 }; 07630 07631 HANDLE Handle; //-V117 07632 }; 07633 07634 struct 07635 { 07636 MINIDUMP_MEMORY_INFO VmRegion; 07637 unsigned Continue; 07638 }; 07639 07640 HRESULT Status; 07641 }; 07642 07643 struct MINIDUMP_EXCEPTION_INFORMATION 07644 { 07645 DWORD ThreadId; 07646 EXCEPTION_POINTERS* ExceptionPointers; 07647 unsigned ClientPointers; 07648 }; 07649 07650 typedef int (WINAPI* MINIDUMP_CALLBACK_ROUTINE) (void* param, MINIDUMP_CALLBACK_INPUT* input, MINIDUMP_CALLBACK_OUTPUT* output); 07651 07652 struct MINIDUMP_CALLBACK_INFORMATION 07653 { 07654 MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; 07655 void* CallbackParam; 07656 }; 07657 07658 enum MINIDUMP_TYPE 07659 { 07660 MiniDumpNormal = 0x00000000, 07661 MiniDumpWithDataSegs = 0x00000001, 07662 MiniDumpWithFullMemory = 0x00000002, 07663 MiniDumpWithHandleData = 0x00000004, 07664 MiniDumpFilterMemory = 0x00000008, 07665 MiniDumpScanMemory = 0x00000010, 07666 MiniDumpWithUnloadedModules = 0x00000020, 07667 MiniDumpWithIndirectlyReferencedMemory = 0x00000040, 07668 MiniDumpFilterModulePaths = 0x00000080, 07669 MiniDumpWithProcessThreadData = 0x00000100, 07670 MiniDumpWithPrivateReadWriteMemory = 0x00000200, 07671 MiniDumpWithoutOptionalData = 0x00000400, 07672 MiniDumpWithFullMemoryInfo = 0x00000800, 07673 MiniDumpWithThreadInfo = 0x00001000, 07674 MiniDumpWithCodeSegs = 0x00002000, 07675 MiniDumpWithoutAuxiliaryState = 0x00004000, 07676 MiniDumpWithFullAuxiliaryState = 0x00008000, 07677 MiniDumpWithPrivateWriteCopyMemory = 0x00010000, 07678 MiniDumpIgnoreInaccessibleMemory = 0x00020000, 07679 MiniDumpWithTokenInformation = 0x00040000 07680 }; 07681 07682 #ifndef CONTEXT_ALL 07683 #define CONTEXT_ALL ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS ) 07684 #endif 07685 07686 #pragma pack (pop) 07687 07688 } // namespace Win32 07689 07690 #endif // TX_COMPILED 07691 07692 #define FOREGROUND_BLACK ( 0 ) 07693 #define FOREGROUND_CYAN ( FOREGROUND_BLUE | FOREGROUND_GREEN ) 07694 #define FOREGROUND_MAGENTA ( FOREGROUND_BLUE | FOREGROUND_RED ) 07695 #define FOREGROUND_DARKYELLOW ( FOREGROUND_GREEN | FOREGROUND_RED ) 07696 #define FOREGROUND_LIGHTGRAY ( FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ) 07697 #define FOREGROUND_DARKGRAY ( FOREGROUND_INTENSITY ) 07698 #define FOREGROUND_LIGHTBLUE ( FOREGROUND_BLUE | FOREGROUND_INTENSITY ) 07699 #define FOREGROUND_LIGHTGREEN ( FOREGROUND_GREEN | FOREGROUND_INTENSITY ) 07700 #define FOREGROUND_LIGHTCYAN ( FOREGROUND_CYAN | FOREGROUND_INTENSITY ) 07701 #define FOREGROUND_LIGHTRED ( FOREGROUND_RED | FOREGROUND_INTENSITY ) 07702 #define FOREGROUND_LIGHTMAGENTA ( FOREGROUND_MAGENTA | FOREGROUND_INTENSITY ) 07703 #define FOREGROUND_YELLOW ( FOREGROUND_DARKYELLOW | FOREGROUND_INTENSITY ) 07704 #define FOREGROUND_WHITE ( FOREGROUND_LIGHTGRAY | FOREGROUND_INTENSITY ) 07705 07706 #define BACKGROUND_BLACK ( 0 ) 07707 #define BACKGROUND_CYAN ( BACKGROUND_BLUE | BACKGROUND_GREEN ) 07708 #define BACKGROUND_MAGENTA ( BACKGROUND_BLUE | BACKGROUND_RED ) 07709 #define BACKGROUND_DARKYELLOW ( BACKGROUND_GREEN | BACKGROUND_RED ) 07710 #define BACKGROUND_GRAY ( BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED ) 07711 #define BACKGROUND_DARKGRAY ( BACKGROUND_INTENSITY ) 07712 #define BACKGROUND_LIGHTBLUE ( BACKGROUND_BLUE | BACKGROUND_INTENSITY ) 07713 #define BACKGROUND_LIGHTGREEN ( BACKGROUND_GREEN | BACKGROUND_INTENSITY ) 07714 #define BACKGROUND_LIGHTCYAN ( BACKGROUND_CYAN | BACKGROUND_INTENSITY ) 07715 #define BACKGROUND_LIGHTRED ( BACKGROUND_RED | BACKGROUND_INTENSITY ) 07716 #define BACKGROUND_LIGHTMAGENTA ( BACKGROUND_MAGENTA | BACKGROUND_INTENSITY ) 07717 #define BACKGROUND_LIGHTYELLOW ( BACKGROUND_DARKYELLOW | BACKGROUND_INTENSITY ) 07718 #define BACKGROUND_WHITE ( BACKGROUND_DARKGRAY | BACKGROUND_INTENSITY ) 07719 07720 //} 07721 //----------------------------------------------------------------------------------------------------------------- 07722 07723 //----------------------------------------------------------------------------------------------------------------- 07724 //{ There are copies of MSVC compiler built-in predefined definitions, which are wrong in 64-bit mode. 07725 // So we have to override them. See: http://stackoverflow.com/questions/39113168 07726 //----------------------------------------------------------------------------------------------------------------- 07727 07728 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07729 07730 #if defined (_MSC_VER) 07731 // MS ABI C++ Exception Layout 07732 namespace Win32 { // --------------------------- 07733 // 07734 #pragma pack (push, 4) // EXCEPTION_RECORD: 07735 // +==================================================+ 07736 struct ThrowInfo // |... | 07737 { // |NumberParameters: 3, 4 or more | 07738 __int32 attributes; // |ExceptionInformation[0]: MS signature 0x19930520 | 07739 __int32 pmfnUnwind; // |ExceptionInformation[1]: object* thrown | 07740 __int32 pForwardCompat; // |ExceptionInformation[2]: ThrowInfo* --------------+---+ 07741 __int32 pCatchableTypeArray; // |ExceptionInformation[3]: ImageBase (if params > 3)| | 07742 }; // +==================================================+ | 07743 // | 07744 struct CatchableTypeArray // ThrowInfo: | 07745 { // +======================================+ <-------+ 07746 __int32 nCatchableTypes; // | ... | 07747 __int32 arrayOfCatchableTypes[]; // +-----+-- pCatchableTypeArray (ptr/RVA) | 07748 }; // | +======================================+ 07749 // | 07750 struct CatchableType // | CatchableTypeArray: 07751 { // +---> +======================================+ 07752 __int32 properties; // | ... | 07753 __int32 pType; // +-----+-- arrayOfCatchableTypes[0] (ptr/RVA) | 07754 __int32 thisDisplacement[3]; // struct _PMD // | +======================================+ 07755 __int32 sizeOrOffset; // | 07756 __int32 copyFunction; // | CatchableType: 07757 }; // +---> +====================+ 07758 // | ... | std::type_info: 07759 #pragma pack (pop) // | pType (ptr/RVA) ---+------> +==================+ 07760 // | ... | |type_info data | 07761 } // namespace Win32 // +====================+ |... | 07762 // +==================+ 07763 #endif 07764 07765 // Similar to __CxxDetectRethrow(), see C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\crtsrc\vcruntime\frame.cpp: 07766 07767 #define _TX_MSC__CXX_DETECT_RETHROW( exc ) \ 07768 ( \ 07769 (exc) && \ 07770 (exc) -> ExceptionCode == EXCEPTION_CPP_MSC && \ 07771 (exc) -> NumberParameters >= 3 && \ 07772 \ 07773 ((exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 || \ 07774 (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 || \ 07775 (exc)-> ExceptionInformation[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3) && \ 07776 \ 07777 (exc) -> ExceptionInformation[2] == 0 \ 07778 ) 07779 07780 #endif // TX_COMPILED 07781 07782 //} 07783 //----------------------------------------------------------------------------------------------------------------- 07784 07785 //----------------------------------------------------------------------------------------------------------------- 07786 //{ The corresponding structures for GCC 07787 // 07788 // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h 07789 // See: http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-abi 07790 //----------------------------------------------------------------------------------------------------------------- 07791 07792 #if defined (_GCC_VER) 07793 07794 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07795 07796 // GCC ABI C++ Exception layout. A/B are ExceptionInformation[0]. 07797 namespace ABI { // -------------------------------------------------------------- 07798 // 07799 struct __cxa_exception // Case A: "_Unwind_Exception* A" is independent exception: 07800 { // -------------------------------------------------------- 07801 union { // 07802 struct // __cxa_exception: std::type_info: 07803 { // -*--+====================+ +==================+ 07804 ::std::type_info* exceptionType; // ^ |exceptionType* -----+---->|type_info data | 07805 void (*exceptionDestructor)(void*); // | |... | |... | 07806 }; // -1 | | +==================+ 07807 struct // | | | 07808 { // A >----|--+--------------------+ 07809 __cxa_exception* primaryException; // | | |unwindHeader | 07810 void (*padding)(); // +1 | | | 07811 }; // | | | | 07812 }; // V | | | 07813 // -*--- +====================+ 07814 void (*unexpected_handler)(); // |object | 07815 std::terminate_handler terminateHandler; // +--------------------+ 07816 // 07817 __cxa_exception* nextException; // Case B: "_Unwind_Exception* B" is dependent exception 07818 int handlerCount; // (unwindHeader.exception_class & 1 != 0): 07819 int handlerSwitchValue; // ----------------------------------------------------- 07820 const unsigned char* actionRecord; // 07821 const unsigned char* languageSpecificData; // __cxa_exception: __cxa_exception: 07822 void* catchTemp; // -*--+====================+ -*--+=================+ 07823 void* adjustedPtr; // ^ |primaryException* --+-- ^ |exceptionType* | 07824 // | |... | \ | |... | 07825 _Unwind_Exception unwindHeader; // -1 | | | | | | 07826 }; // | | | | | | | 07827 // B >----|--+--------------------+ | -1 +-----------------+ 07828 struct __cxa_eh_globals // | | |unwindHeader | | | |unwindHeader | 07829 { // +1 | | | | | | | 07830 __cxa_exception* caughtExceptions; // | | | | | | | | 07831 unsigned int uncaughtExceptions; // V | | | \ | | | 07832 }; // -*--- +====================+ -->*--+=================+ 07833 // |... | |object | 07834 } // namespace ABI // . . | | 07835 // +-----------------+ 07836 07837 extern "C" ABI::__cxa_eh_globals* __cxa_get_globals(); 07838 07839 #endif // TX_COMPILED 07840 07841 #endif 07842 07843 //} 07844 //----------------------------------------------------------------------------------------------------------------- 07845 07846 //----------------------------------------------------------------------------------------------------------------- 07847 //{ Hand-made IAT. 07848 // Some IDEs don't link with these libs by default in console projects, so do sunrise by hand. :( 07849 //----------------------------------------------------------------------------------------------------------------- 07850 07851 // Hand-made DLLIMPORT helpers 07852 07853 #define _TX_DLLIMPORT( lib, retval, name, params ) TX_DLLIMPORT (true, lib ".dll", retval, name, params, WINAPI) 07854 #define _TX_DLLIMPORT_OPT( lib, retval, name, params ) TX_DLLIMPORT (false, lib ".dll", retval, name, params, WINAPI) 07855 #define _TX_DLLIMPORT_CRT( lib, retval, name, params ) TX_DLLIMPORT (false, lib ".dll", retval, name, params, please) 07856 07857 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required = true)) (); 07858 07859 //----------------------------------------------------------------------------------------------------------------- 07860 07861 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 07862 07863 namespace Win32 { 07864 07865 _TX_DLLIMPORT ("GDI32", HDC, CreateCompatibleDC, (HDC dc)); 07866 _TX_DLLIMPORT ("GDI32", HBITMAP, CreateCompatibleBitmap, (HDC dc, int width, int height)); 07867 _TX_DLLIMPORT ("GDI32", HGDIOBJ, GetStockObject, (int object)); 07868 _TX_DLLIMPORT ("GDI32", HGDIOBJ, SelectObject, (HDC dc, HGDIOBJ object)); 07869 _TX_DLLIMPORT ("GDI32", HGDIOBJ, GetCurrentObject, (HDC dc, unsigned objectType)); 07870 _TX_DLLIMPORT ("GDI32", int, GetObjectA, (HGDIOBJ obj, int bufsize, void* buffer)); 07871 _TX_DLLIMPORT ("GDI32", DWORD, GetObjectType, (HGDIOBJ object)); 07872 _TX_DLLIMPORT ("GDI32", bool, DeleteDC, (HDC dc)); 07873 _TX_DLLIMPORT ("GDI32", bool, DeleteObject, (HGDIOBJ object)); 07874 _TX_DLLIMPORT ("GDI32", COLORREF, SetTextColor, (HDC dc, COLORREF color)); 07875 _TX_DLLIMPORT ("GDI32", COLORREF, SetBkColor, (HDC dc, COLORREF color)); 07876 _TX_DLLIMPORT ("GDI32", int, SetBkMode, (HDC dc, int bkMode)); 07877 _TX_DLLIMPORT ("GDI32", HFONT, CreateFontA, (int height, int width, int escapement, int orientation, 07878 int weight, DWORD italic, DWORD underline, DWORD strikeout, 07879 DWORD charSet, DWORD outputPrec, DWORD clipPrec, 07880 DWORD quality, DWORD pitchAndFamily, const char face[])); 07881 _TX_DLLIMPORT ("GDI32", int, EnumFontFamiliesExA, (HDC dc, LPLOGFONT logFont, FONTENUMPROC enumProc, 07882 LPARAM lParam, DWORD reserved)); 07883 _TX_DLLIMPORT ("GDI32", COLORREF, SetPixel, (HDC dc, int x, int y, COLORREF color)); 07884 _TX_DLLIMPORT ("GDI32", COLORREF, GetPixel, (HDC dc, int x, int y)); 07885 _TX_DLLIMPORT ("GDI32", HPEN, CreatePen, (int penStyle, int width, COLORREF color)); 07886 _TX_DLLIMPORT ("GDI32", HBRUSH, CreateSolidBrush, (COLORREF color)); 07887 _TX_DLLIMPORT ("GDI32", bool, MoveToEx, (HDC dc, int x, int y, POINT* point)); 07888 _TX_DLLIMPORT ("GDI32", bool, LineTo, (HDC dc, int x, int y)); 07889 _TX_DLLIMPORT ("GDI32", bool, Polygon, (HDC dc, const POINT points[], int count)); 07890 _TX_DLLIMPORT ("GDI32", bool, Polyline, (HDC dc, const POINT points[], int count)); 07891 _TX_DLLIMPORT ("GDI32", bool, PolyBezier, (HDC dc, const POINT points[], int count)); 07892 _TX_DLLIMPORT ("GDI32", bool, Rectangle, (HDC dc, int x0, int y0, int x1, int y1)); 07893 _TX_DLLIMPORT ("GDI32", bool, RoundRect, (HDC dc, int x0, int y0, int x1, int y1, int sizeX, int sizeY)); 07894 _TX_DLLIMPORT ("GDI32", bool, Ellipse, (HDC dc, int x0, int y0, int x1, int y1)); 07895 _TX_DLLIMPORT ("GDI32", bool, Arc, (HDC dc, int x0, int y0, int x1, int y1, 07896 int xStart, int yStart, int xEnd, int yEnd)); 07897 _TX_DLLIMPORT ("GDI32", bool, Pie, (HDC dc, int x0, int y0, int x1, int y1, 07898 int xStart, int yStart, int xEnd, int yEnd)); 07899 _TX_DLLIMPORT ("GDI32", bool, Chord, (HDC dc, int x0, int y0, int x1, int y1, 07900 int xStart, int yStart, int xEnd, int yEnd)); 07901 _TX_DLLIMPORT ("GDI32", bool, TextOutA, (HDC dc, int x, int y, const char string[], int length)); 07902 _TX_DLLIMPORT ("GDI32", UINT, SetTextAlign, (HDC dc, unsigned mode)); 07903 _TX_DLLIMPORT ("GDI32", bool, GetTextExtentPoint32A, (HDC dc, const char string[], int length, SIZE* size)); 07904 _TX_DLLIMPORT ("GDI32", bool, ExtFloodFill, (HDC dc, int x, int y, COLORREF color, unsigned type)); 07905 _TX_DLLIMPORT ("GDI32", bool, BitBlt, (HDC dest, int xDest, int yDest, int width, int height, 07906 HDC src, int xSrc, int ySrc, DWORD rOp)); 07907 _TX_DLLIMPORT ("GDI32", bool, StretchBlt, (HDC dest, int xDest, int yDest, int width, int height, 07908 HDC src, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rOp)); 07909 _TX_DLLIMPORT ("GDI32", bool, PlgBlt, (HDC dest, const POINT* parallelogram, 07910 HDC src, int xSrc, int ySrc, int width, int height, 07911 HBITMAP mask, int xMask, int yMask)); 07912 _TX_DLLIMPORT ("GDI32", int, SetDIBitsToDevice, (HDC dc, int xDest, int yDest, DWORD width, DWORD height, 07913 int xSrc, int ySrc, unsigned startLine, unsigned numLines, 07914 const void* data, const BITMAPINFO* info, unsigned colorUse)); 07915 _TX_DLLIMPORT ("GDI32", int, GetDIBits, (HDC hdc, HBITMAP hbmp, unsigned uStartScan, unsigned cScanLines, 07916 void* lpvBits, BITMAPINFO* lpbi, unsigned usage)); 07917 _TX_DLLIMPORT ("GDI32", bool, PatBlt, (HDC dc, int x0, int y0, int width, int height, DWORD rOp)); 07918 _TX_DLLIMPORT ("GDI32", int, SetROP2, (HDC dc, int mode)); 07919 _TX_DLLIMPORT ("GDI32", int, SetStretchBltMode, (HDC dc, int mode)); 07920 _TX_DLLIMPORT ("GDI32", DWORD, GdiSetBatchLimit, (DWORD limit)); 07921 _TX_DLLIMPORT ("GDI32", HBITMAP, CreateDIBSection, (HDC dc, const BITMAPINFO* bmInfo, unsigned colorUsage, void **vBits, 07922 HANDLE section, DWORD offset)); 07923 07924 _TX_DLLIMPORT ("User32", int, DrawTextA, (HDC dc, const char text[], int length, RECT* rect, unsigned format)); 07925 _TX_DLLIMPORT ("User32", HANDLE, LoadImageA, (HINSTANCE inst, const char name[], unsigned type, 07926 int sizex, int sizey, unsigned mode)); 07927 _TX_DLLIMPORT_OPT ("User32", bool, IsHungAppWindow, (HWND wnd)); 07928 _TX_DLLIMPORT_OPT ("User32", HWND, GhostWindowFromHungWindow, (HWND wnd)); 07929 _TX_DLLIMPORT_OPT ("User32", bool, FlashWindowEx, (const FLASHWINFO* flash)); 07930 07931 _TX_DLLIMPORT ("WinMM", bool, PlaySound, (const char sound[], HMODULE mod, DWORD mode)); 07932 07933 _TX_DLLIMPORT_OPT ("MSImg32", bool, TransparentBlt, (HDC dest, int destX, int destY, int destWidth, int destHeight, 07934 HDC src, int srcX, int srcY, int srcWidth, int srcHeight, 07935 unsigned transparentColor)); 07936 _TX_DLLIMPORT_OPT ("MSImg32", bool, AlphaBlend, (HDC dest, int destX, int destY, int destWidth, int destHeight, 07937 HDC src, int srcX, int srcY, int srcWidth, int srcHeight, 07938 BLENDFUNCTION blending)); 07939 07940 _TX_DLLIMPORT ("Kernel32", void, ExitProcess, (unsigned retcode)); 07941 _TX_DLLIMPORT ("Kernel32", bool, TerminateProcess, (HANDLE process, unsigned retcode)); 07942 _TX_DLLIMPORT_OPT ("Kernel32", void, FatalExit, (int retcode)); 07943 _TX_DLLIMPORT_OPT ("Kernel32", void, FatalAppExitA, (unsigned action, const char message[])); 07944 _TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetThreadId, (HANDLE thread)); 07945 _TX_DLLIMPORT ("Kernel32", HWND, GetConsoleWindow, (void)); 07946 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetConsoleFont, (HANDLE con, DWORD fontIndex)); 07947 _TX_DLLIMPORT_OPT ("Kernel32", DWORD, GetNumberOfConsoleFonts, (void)); 07948 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetCurrentConsoleFont, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFO* curFont)); 07949 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont)); 07950 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetCurrentConsoleFontEx, (HANDLE con, bool maxWnd, CONSOLE_FONT_INFOEX* curFont)); 07951 _TX_DLLIMPORT_OPT ("Kernel32", void, RtlCaptureContext, (CONTEXT* contextRecord)); 07952 _TX_DLLIMPORT_OPT ("Kernel32", USHORT, RtlCaptureStackBackTrace, (DWORD framesToSkip, DWORD framesToCapture, void** backTrace, DWORD* hash)); 07953 _TX_DLLIMPORT_OPT ("Kernel32", void*, AddVectoredExceptionHandler, (unsigned long firstHandler, PVECTORED_EXCEPTION_HANDLER handler)); 07954 _TX_DLLIMPORT_OPT ("Kernel32", unsigned, RemoveVectoredExceptionHandler,(void* handler)); 07955 _TX_DLLIMPORT_OPT ("Kernel32", bool, GetModuleHandleEx, (DWORD flags, const char moduleName[], HMODULE* module)); 07956 _TX_DLLIMPORT_OPT ("Kernel32", bool, IsWow64Process, (HANDLE process, int* isWow64Process)); 07957 _TX_DLLIMPORT_OPT ("Kernel32", bool, Wow64GetThreadContext, (HANDLE thread, WOW64_CONTEXT* context)); 07958 _TX_DLLIMPORT_OPT ("Kernel32", bool, SetThreadStackGuarantee, (unsigned long* stackSize)); 07959 07960 _TX_DLLIMPORT ("OLE32", HRESULT, CoInitialize, (void*)); 07961 _TX_DLLIMPORT ("OLE32", HRESULT, CoCreateInstance, (REFCLSID clsId, IUnknown*, DWORD, REFIID iId, void** value)); 07962 _TX_DLLIMPORT ("OLE32", void, CoUninitialize, (void)); 07963 07964 _TX_DLLIMPORT ("Shell32", HINSTANCE,ShellExecuteA, (HWND wnd, const char operation[], const char file[], 07965 const char parameters[], const char directory[], int showCmd)); 07966 07967 _TX_DLLIMPORT ("ShlWAPI", char*, StrStrIA, (const char string[], const char search[])); 07968 _TX_DLLIMPORT ("ShlWAPI", char*, StrStrIW, (const wchar_t string[], const wchar_t search[])); 07969 07970 _TX_DLLIMPORT_OPT ("NTDLL", char*, wine_get_version, (void)); 07971 _TX_DLLIMPORT ("NTDLL", NTSTATUS, NtQueryInformationProcess, (HANDLE process, int infoClass, 07972 void* processInfo, unsigned long szProcessInfo, unsigned long* szReturnInfo)); 07973 07974 _TX_DLLIMPORT_CRT ("MSVCRT", void, exit, (int retcode)); 07975 _TX_DLLIMPORT_CRT ("MSVCRT", void, _cexit, (void)); 07976 _TX_DLLIMPORT_CRT ("MSVCRT", unsigned, _fpreset, (void)); 07977 _TX_DLLIMPORT_CRT ("MSVCRT", unsigned, _controlfp, (unsigned control, unsigned mask)); 07978 _TX_DLLIMPORT_CRT ("MSVCRT", uintptr_t,_beginthread, (void (__cdecl* start_address) (void*), unsigned stack_size, void* arglist)); 07979 _TX_DLLIMPORT_CRT ("MSVCRT", uintptr_t,_beginthreadex, (void* security, unsigned stack_size, unsigned (__stdcall* start_address) (void*), 07980 void *arglist, unsigned init_flag, unsigned* thread_addr)); 07981 _TX_DLLIMPORT_CRT ("MSVCRT", char*, __unDName, (char* outStr, const char* mangledName, int outStrLen, 07982 void* (*mallocFunc) (size_t size), void (*freeFunc) (void *pointer), 07983 unsigned short flags)); 07984 _TX_DLLIMPORT_CRT ("MSVCRT", unexpected_handler, set_unexpected, (unexpected_handler handler)); 07985 07986 _TX_DLLIMPORT_OPT ("OpenGL32", HDC, wglGetCurrentDC, (void)); 07987 _TX_DLLIMPORT_OPT ("OpenGL32", unsigned, glGetError, (void)); 07988 _TX_DLLIMPORT_OPT ("Glu32", const char*, gluErrorString, (unsigned error)); 07989 07990 _TX_DLLIMPORT_OPT ("ComDlg32", DWORD, CommDlgExtendedError, (void)); 07991 07992 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, MiniDumpWriteDump, (HANDLE process, DWORD processId, HANDLE file, MINIDUMP_TYPE dumpType, 07993 MINIDUMP_EXCEPTION_INFORMATION* exceptionParam, 07994 MINIDUMP_USER_STREAM_INFORMATION* userStreamParam, 07995 MINIDUMP_CALLBACK_INFORMATION* callbackParam)); 07996 07997 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD, SymSetOptions, (DWORD options)); 07998 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymInitialize, (HANDLE process, const char userSearchPath[], bool invadeProcess)); 07999 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymFromAddr, (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO* symbol)); 08000 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymGetLineFromAddr64, (HANDLE process, DWORD64 addr, DWORD* offset, IMAGEHLP_LINE64* line)); 08001 _TX_DLLIMPORT_OPT ("DbgHelp*", DWORD64, SymGetModuleBase64, (HANDLE process, DWORD64 addr)); 08002 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, SymCleanup, (HANDLE process)); 08003 _TX_DLLIMPORT_OPT ("DbgHelp*", void*, SymFunctionTableAccess64, (HANDLE process, DWORD64 addrBase)); 08004 _TX_DLLIMPORT_OPT ("DbgHelp*", bool, StackWalk64, (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord, 08005 PREAD_PROCESS_MEMORY_ROUTINE64 readMemoryFunc, 08006 PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc, 08007 PGET_MODULE_BASE_ROUTINE64 getModuleBaseFunc, 08008 PTRANSLATE_ADDRESS_ROUTINE64 translateAddressFunc)); 08009 namespace MinGW { 08010 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD, SymSetOptions, (DWORD options)); 08011 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymInitialize, (HANDLE process, const char userSearchPath[], bool invadeProcess)); 08012 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymFromAddr, (HANDLE process, DWORD64 addr, DWORD64* offset, SYMBOL_INFO* symbol)); 08013 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymGetLineFromAddr64, (HANDLE process, DWORD64 addr, DWORD* offset, IMAGEHLP_LINE64* line)); 08014 _TX_DLLIMPORT_OPT ("MgwHelp*", DWORD64, SymGetModuleBase64, (HANDLE process, DWORD64 addr)); 08015 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, SymCleanup, (HANDLE process)); 08016 _TX_DLLIMPORT_OPT ("MgwHelp*", void*, SymFunctionTableAccess64, (HANDLE process, DWORD64 addrBase)); 08017 _TX_DLLIMPORT_OPT ("MgwHelp*", bool, StackWalk64, (DWORD arch, HANDLE process, HANDLE thread, STACKFRAME64* frame, void* ctxRecord, 08018 PREAD_PROCESS_MEMORY_ROUTINE64 readMemoryFunc, 08019 PFUNCTION_TABLE_ACCESS_ROUTINE64 tableAccessFunc, 08020 PGET_MODULE_BASE_ROUTINE64 getModuleBaseFunc, 08021 PTRANSLATE_ADDRESS_ROUTINE64 translateAddressFunc)); 08022 } // namespace MinGW 08023 } // namespace Win32 08024 08025 #endif // TX_COMPILED 08026 08027 //} 08028 //----------------------------------------------------------------------------------------------------------------- 08029 08031 //} 08032 //================================================================================================================= 08033 08034 //================================================================================================================= 08035 //{ Internal function prototypes, macros and constants 08036 // @name Прототипы внутренних функций, макросы и константы 08037 //================================================================================================================= 08039 08040 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08041 08042 int _txInitialize(); 08043 void _txCleanup(); 08044 08045 HWND _txCanvas_CreateWindow (const SIZE* size); 08046 08047 bool _txCanvas_OnCREATE (HWND wnd); 08048 bool _txCanvas_OnDESTROY (HWND wnd); 08049 bool _txCanvas_OnCLOSE (HWND); 08050 bool _txCanvas_OnPAINT (HWND wnd); 08051 bool _txCanvas_OnKEY (HWND wnd, WPARAM vk, LPARAM info, bool down); 08052 bool _txCanvas_OnCHAR (HWND wnd, WPARAM ch, LPARAM info); 08053 bool _txCanvas_OnTIMER (HWND wnd, WPARAM id); 08054 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords); 08055 bool _txCanvas_OnMOUSELEAVE (HWND wnd); 08056 bool _txCanvas_OnCREATEWND (HWND wnd, WPARAM, LPARAM lpar); 08057 bool _txCanvas_OnDESTROYWND (HWND wnd, WPARAM, LPARAM lpar); 08058 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd); 08059 bool _txCanvas_OnCmdABOUT (HWND wnd, WPARAM cmd); 08060 08061 unsigned WINAPI _txCanvas_ThreadProc (void* data); 08062 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar); 08063 08064 HDC _txBuffer_Create (HWND wnd = NULL, const POINT* size = NULL, HBITMAP bitmap = NULL, 08065 RGBQUAD** pixels = NULL) tx_nodiscard; 08066 bool _txBuffer_Delete (HDC* dc); 08067 bool _txBuffer_Select (HGDIOBJ obj, HDC dc = txDC()); 08068 08069 HWND _txConsole_Attach(); 08070 bool _txConsole_OK() tx_nodiscard; 08071 bool _txConsole_Detach (bool activate); 08072 bool _txConsole_Draw (HDC dc); 08073 bool _txConsole_SetUnicodeFont(); 08074 08075 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra); 08076 HWND txCreateExtraWindow (CREATESTRUCT createData); 08077 HICON _txCreateTXIcon (int size) tx_nodiscard; 08078 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng = NULL, 08079 int checkOfs = 0, const wchar_t checkLetters[2] = NULL); 08080 int _txPauseBeforeTermination (HWND canvas); 08081 int _txIsParentListed (const char* list, DWORD* parentPID = NULL) tx_nodiscard; 08082 void _txActivateWindow (HWND wnd, unsigned mode); 08083 int _txGetInput(); 08084 08085 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar); 08086 const char* _txPlayVideo_FindVLC() tx_nodiscard; 08087 08088 bool _txCreateShortcut (const char shortcutName[], 08089 const char fileToLink[], const char args[] = NULL, const char workDir[] = NULL, 08090 const char description[] = NULL, int cmdShow = SW_SHOWNORMAL, 08091 const char iconFile[] = NULL, int iconIndex = 0, int fontSize = 0, 08092 COORD bufSize = ZERO (COORD), COORD wndSize = ZERO (COORD), COORD wndOrg = ZERO (COORD)); 08093 08094 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle, 08095 WORD controls, short x, short y, short cx, short cy, 08096 const char caption[], const char font[], WORD fontsize, 08097 const char menu[]) tx_nodiscard; 08098 08099 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle, 08100 short x, short y, short cx, short cy, 08101 WORD id, const char wclass[], const char caption[]); 08102 08103 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, 08104 const char msg[], va_list args); 08105 void _txOnTerminate(); 08106 void _txOnUnexpected(); 08107 void _txOnPureCall(); 08108 void _txOnNewHandlerAnsi(); 08109 int _txOnNewHandler (size_t size); 08110 void _txOnSignal (int signal = 0, int fpe = 0); 08111 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type); 08112 void _txOnSecurityError (int code, void*); 08113 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code); 08114 int _txOnMatherr (_exception* except); 08115 void _txOnInvalidParam (const wchar_t* expr, const wchar_t* func, const wchar_t* file, 08116 unsigned line, uintptr_t); 08117 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, 08118 const unsigned char* file, int line); 08119 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...) tx_printfy (5); 08120 int _txOnErrorReport (int type, const char* text, int* ret); 08121 int tx_glGetError (int setError = INT_MIN); 08122 08123 void _txOnCExit(); 08124 void _txOnExit (int retcode); 08125 void _txOnFatalExit (int retcode); 08126 void _txOnExitProcess (unsigned retcode); 08127 void _txOnFatalAppExitA (unsigned action, const char message[]); 08128 bool _txOnTerminateProcess (HANDLE process, unsigned retcode); 08129 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI 08130 _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter); 08131 void _txWatchdogTerminator (void* timeout); // Only Arnold-type series are supported, not T1000 08132 08133 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc); 08134 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc); 08135 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[]); 08136 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]); 08137 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type); 08138 intptr_t _txDumpExceptionCPP (char what[], intptr_t size, unsigned code = 0, 08139 unsigned params = 0, const ULONG_PTR info[] = NULL); 08140 08141 void _txStackBackTrace (const char file[] = "?", int line = 0, const char func[] = "?", 08142 bool readSource = true); 08143 const char* _txCaptureStackBackTrace (int framesToSkip = 0, bool readSource = true, 08144 CONTEXT* context = NULL, EXCEPTION_POINTERS* exc = NULL, HANDLE thread = GetCurrentThread()); 08145 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context = NULL, 08146 HANDLE thread = GetCurrentThread()); 08147 const char* _txCaptureStackBackTraceTX (int framesToSkip = 0, bool readSource = false); 08148 08149 const char* _txSymPrintFromAddr (void* addr = NULL, const char format[] = NULL, ...) tx_printfy (2); 08150 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol = NULL, 08151 Win32::IMAGEHLP_LINE64** line = NULL, const char** module = NULL, 08152 const char** source = NULL, int context = 2); 08153 intptr_t _txReadSource (char buf[], intptr_t size, const char file[], 08154 int linStart = 0, int linEnd = INT_MIN, int linMark = INT_MIN); 08155 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc = NULL); 08156 08157 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] = NULL, 08158 int useHotPatching = false, HMODULE module = NULL, bool debug = false); 08159 bool _txInDll() tx_nodiscard; 08160 PROCESSENTRY32* _txFindProcess (unsigned pid = GetCurrentProcessId()) tx_nodiscard; 08161 bool _txKillProcess (DWORD pid); 08162 int _txTaskKill (const char name[] /*= NULL*/, const char cmdLineSubstr[] /*= NULL*/, unsigned pid /*= 0*/); 08163 bool _txCheckSourceCP (int needCP = _TX_CODEPAGE, bool verbose = true); 08164 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid = _getpid()); 08165 IMAGE_NT_HEADERS*_txGetNtHeaders (HMODULE module = GetModuleHandle (NULL)) tx_nodiscard; 08166 bool _txIsConsoleSubsystem(); 08167 const char* _txAppInfo() tx_nodiscard; 08168 08169 #if defined (_CLANG_VER) && !defined (_MSC_VER) 08170 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info); 08171 #endif 08172 08173 #endif // TX_COMPILED 08174 08175 inline bool _txCanvas_OK () tx_nodiscard; 08176 int _txCanvas_SetRefreshLock (int count); 08177 08178 const char* _txError (const char file[] = NULL, int line = 0, const char func[] = NULL, unsigned color = 0, 08179 const char msg[] = NULL, ...) tx_printfy (5); 08180 08181 bool _txIsBadReadPtr (const void* address); 08182 08183 intptr_t _tx_snprintf_s (char stream[], intptr_t size, const char format[], ...) tx_printfy (3); 08184 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg); 08185 bool _txIsTTY (int fd); 08186 void txReopenStdio(); 08187 08188 #if defined (__CYGWIN__) 08189 08190 int _getch(); 08191 int _putch (int ch); 08192 int _kbhit() tx_nodiscard; 08193 08194 #endif 08195 08196 //----------------------------------------------------------------------------------------------------------------- 08197 // There are macros for __FILE__ and __LINE__ to work properly. 08198 08199 #if !defined (NDEBUG) 08200 08201 #define _TX_ARGUMENT_FAILED( cond ) ( !(cond) && \ 08202 (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1) && \ 08203 (assert (cond), true) ) 08204 08205 #define _TX_TXWINDOW_FAILED() ( !txOK() && \ 08206 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08207 (TX_ERROR ("\a" "Возможно, окно рисования не создано или не в порядке."), 1) ) 08208 08209 #define _TX_HDC_FAILED( dc ) ( !Win32::GetObjectType (dc) && \ 08210 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08211 (TX_ERROR ("\a" "Параметр \"%s\" неверен." \ 08212 " Возможно, этот холст не создан, или уже уничтожен," \ 08213 " или не загрузилась картинка.", #dc), 1) ) 08214 #define _TX_DEFAULT_HDC_FAILED( dc ) ( (!(dc) && \ 08215 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) && \ 08216 (TX_ERROR ("\a" "%s" "Если вы указали параметр \"%s\", то он неверен.%s", \ 08217 !txWindow()? "Окно рисования не создано или не в порядке.\n" : "", \ 08218 #dc, \ 08219 txWindow()? " Возможно, этот холст не создан, или уже уничтожен," \ 08220 " или не загрузилась картинка." : ""), 1)) \ 08221 || \ 08222 _TX_HDC_FAILED (dc) ) 08223 #else 08224 08225 #define _TX_ARGUMENT_FAILED( cond ) ( !(cond) && \ 08226 (SetLastErrorEx (ERROR_BAD_ARGUMENTS, 0), 1) ) 08227 08228 #define _TX_TXWINDOW_FAILED() ( !txOK() && \ 08229 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08230 08231 #define _TX_HDC_FAILED( dc ) ( !Win32::GetObjectType (dc) && \ 08232 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08233 08234 #define _TX_DEFAULT_HDC_FAILED( dc ) ( !(dc) && \ 08235 (SetLastErrorEx (ERROR_INVALID_DATA, 0), 1) ) 08236 #endif 08237 08238 //----------------------------------------------------------------------------------------------------------------- 08239 // Take action in debug configuration only. 08240 // Definition ({ expr; }) would be better, but MSVC rejects it. So sad. :'( 08241 08242 #if !defined (NDEBUG) 08243 #define _TX_ON_DEBUG( code ) { code; } 08244 #else 08245 #define _TX_ON_DEBUG( code ) ; 08246 #endif 08247 08248 //----------------------------------------------------------------------------------------------------------------- 08249 // Invokes an error without location information. "$$" restores TX-related call location context 08250 08251 #define _TX_UNEXPECTED( ... ) $$ _txError (NULL, 0, NULL, 0, ##__VA_ARGS__) 08252 08253 //----------------------------------------------------------------------------------------------------------------- 08254 // Safe call of a function via its pointer 08255 08256 #define _TX_CALL( func, param ) ( (func)? ((func) param) : 0 ) 08257 #define _TX_CALLv( func, param ) ( (func)? ((func) param) : (void)0 ) 08258 08259 //----------------------------------------------------------------------------------------------------------------- 08260 // This is a macro because cond is an expression and is not always a function. Lack of lambdas in pre-C++0x. 08261 08262 #define _txWaitFor( cond, time ) { for (DWORD _t = GetTickCount() + (time); \ 08263 !(cond) && GetTickCount() < _t; \ 08264 Sleep (_txWindowUpdateInterval)) \ 08265 ; \ 08266 \ 08267 if (!(cond)) \ 08268 _txTrace (__FILE__, __LINE__, NULL, "WARNING: Timeout: " #cond "."); } 08269 08270 //----------------------------------------------------------------------------------------------------------------- 08271 // Detouring in case of SEH mechanism 08272 08273 #define _txSetJmp() ( setjmp (_txDumpExceptionObjJmp) == 0 ) 08274 08275 #define _txClearJmp() { *(unsigned long long*) _txDumpExceptionObjJmp = 0; } 08276 08277 //----------------------------------------------------------------------------------------------------------------- 08278 // IN and OUT are defined in WinDef.h to support Microsoft SAL. Remove them because they are often confused with user's code. 08279 08280 #if defined (IN) 08281 // #undef IN 08282 #endif 08283 08284 #if defined (OUT) 08285 // #undef OUT 08286 #endif 08287 08289 //} 08290 //================================================================================================================= 08291 08292 //================================================================================================================= 08293 //{ Internal global data 08295 // 08296 // Данные не упакованы в структуру или класс, для того, чтобы это сделали Вы сами :) 08297 // 08298 // Если вы пишете свою библиотеку и используете TXLib.h как пример, не следуйте ему и не делайте так же. 08299 // Здесь это сделано только в образовательных целях. 08300 // 08301 // Будьте практичнее, сделайте структуру и глобальную функцию для доступа к ней, или класс. 08302 //================================================================================================================= 08304 08305 #ifndef TX_COMPILED // <<<<<<< THE CODE IS HERE, UNFOLD IT <<< 08306 08307 const int _TX_IDM_ABOUT = 40000, // Идентификаторы системного меню окна 08308 _TX_IDM_CONSOLE = 40001, 08309 _TX_WM_CREATEWND = 0x7FF0, // Сообщения для создания/уничтожения 08310 _TX_WM_DESTROYWND = 0x7FF1; // окон в потоке Canvas 08311 08312 const char _TX_VSCODE_PARENTS[] = "cmd.exe:code.exe, powershell.exe:code.exe"; 08313 08314 //----------------------------------------------------------------------------------------------------------------- 08315 08316 volatile unsigned _txCanaryFirst = 0x776F656D; // A very system value 08317 08318 int _txInitialized = (_TX_NOINIT +0)? 0 : _txInitialize(); 08319 08320 volatile unsigned _txMainThreadId = 0; // ID потока, где выполняется main() 08321 volatile HANDLE _txMainThread = NULL; // Дексриптор этого потока 08322 08323 volatile unsigned _txCanvas_ThreadId = 0; // ID потока, владеющего окном холста TXLib 08324 volatile HANDLE _txCanvas_Thread = NULL; // Дексриптор этого потока 08325 volatile HWND _txCanvas_Window = NULL; // Дескриптор окна холста TXLib 08326 08327 HDC _txCanvas_BackBuf[2] = {NULL, // [0] Main TXLib in-memory DC, where user's pictures lies 08328 NULL}; // [1] Image ready for auto-refresh, see txCanvas_OnPAINT() 08329 08330 RGBQUAD* _txCanvas_Pixels = NULL; // Memory buffer of _txCanvas_BackBuf[0] 08331 08332 HBITMAP _txStockBitmap = NULL; // Equivalent of GetStockObject (BITMAP), 08333 // see https://devblogs.microsoft.com/oldnewthing/20100416-00/?p=14313 08334 08335 CRITICAL_SECTION _txCanvas_LockBackBuf = {0,-1}; // Prevent simultaneous access to back buffer, see txLock() 08336 08337 UINT_PTR _txCanvas_RefreshTimer = 1; // Timer ID to redraw TXLib window 08338 volatile int _txCanvas_RefreshLock = 0; // Blocks auto on-timer canvas update, see txBegin/txEnd 08339 08340 ::std::vector<HDC>* _txCanvas_UserDCs = NULL; // List of DCs allocated, for auto-free 08341 08342 volatile bool _txConsole_IsBlinking = true; // To blink or not to blink, that is the question. 08343 08344 int _txConsole = false; // Only first TXLib module in app can own the console 08345 bool _txMain = false; // First TXLib wnd opened (closing it terminates program) 08346 bool _txIsDll = false; // TXLib module is in DLL 08347 volatile bool _txRunning = false; // main() is still running 08348 volatile bool _txExit = false; // exit() is active 08349 08350 volatile POINT _txMousePos = {-1,-1}; // Ask Captn Obviouos about it. See txCanvas_OnMOUSE() 08351 volatile unsigned _txMouseButtons = 0; 08352 08353 volatile WNDPROC _txAltWndProc = NULL; // Альтернативная оконная функция. См. txSetWindowsHook(). 08354 08355 _tx_thread _txLoc _txLoc::Cur = {}; // Execution point tracking and trace state, see "$" macro 08356 08357 volatile int _txErrors = 0; // TX_ERROR calls sequential number 08358 volatile int _txOGLError = 0; // Last OpenGL error when using tx_glGetError() 08359 volatile long _txSENumber = 0; // SEH exceptions sequential number 08360 volatile long _txSEFatalNumber = 0; // SEH fatal exceptions sequential number 08361 char _txDumpSE [_TX_BUFSIZE] = ""; // SEH dump data area 08362 char _txTraceSE[_TX_HUGEBUFSIZE] = ""; // Stack trace data area 08363 08364 LPTOP_LEVEL_EXCEPTION_FILTER _txPrevUEFilter = NULL; // Previous UnhandledExceptionFilter 08365 08366 jmp_buf _txDumpExceptionObjJmp = {}; // Hook for _txDumpExceptionObj 08367 08368 const volatile uintptr_t _txForceImport[] = { (uintptr_t) ::TerminateProcess, (uintptr_t) ::ExitProcess, 08369 (uintptr_t) ::FatalExit, (uintptr_t) ::FatalAppExitA, 08370 (uintptr_t) ::exit, (uintptr_t) Win32::_controlfp, 08371 (uintptr_t) Win32::Polyline, (uintptr_t) Win32::PolyBezier, 08372 (uintptr_t) Win32::RoundRect, (uintptr_t) Win32::RemoveVectoredExceptionHandler, 08373 (uintptr_t) Win32::PlgBlt, (uintptr_t) Win32::RtlCaptureStackBackTrace, 08374 (uintptr_t) Win32::SymInitialize, (uintptr_t) Win32::MinGW::SymInitialize, 08375 (uintptr_t) Win32::SymSetOptions, (uintptr_t) Win32::MinGW::SymSetOptions, 08376 (uintptr_t) Win32::SymGetLineFromAddr64, (uintptr_t) Win32::MinGW::SymGetLineFromAddr64, 08377 (uintptr_t) Win32::SymFromAddr, (uintptr_t) Win32::MinGW::SymFromAddr, 08378 (uintptr_t) Win32::SymCleanup, (uintptr_t) Win32::MinGW::SymCleanup, 08379 (uintptr_t) Win32::SymGetModuleBase64, (uintptr_t) Win32::MinGW::SymGetModuleBase64, 08380 (uintptr_t) Win32::SymFunctionTableAccess64, (uintptr_t) Win32::MinGW::SymFunctionTableAccess64, 08381 (uintptr_t) Win32::StackWalk64, (uintptr_t) Win32::MinGW::StackWalk64, 08382 (uintptr_t) Win32::StrStrIA, (uintptr_t) Win32::Wow64GetThreadContext }; 08383 08384 volatile unsigned _txCanaryLast = 0x5E2E2E5E; // Another very system value 08385 08386 #endif // TX_COMPILED 08387 08388 //----------------------------------------------------------------------------------------------------------------- 08389 08390 extern volatile unsigned _txCanaryFirst; 08391 extern volatile unsigned _txCanaryLast; 08392 extern volatile HWND _txCanvas_Window; 08393 extern volatile unsigned _txCanvas_ThreadId; 08394 extern HDC _txCanvas_BackBuf[2]; 08395 extern RGBQUAD* _txCanvas_Pixels; 08396 extern volatile int _txCanvas_RefreshLock; 08397 extern volatile WNDPROC _txAltWndProc; 08398 extern volatile bool _txExit; 08399 extern volatile int _txOGLError; 08400 08402 //} 08403 //================================================================================================================= 08404 08405 //================================================================================================================= 08406 //{ TXLib engine init/check/cleanup 08408 //================================================================================================================= 08410 08411 //----------------------------------------------------------------------------------------------------------------- 08412 //{ Early initialization 08413 //----------------------------------------------------------------------------------------------------------------- 08414 08415 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08416 08417 int _txInitialize() 08418 { 08419 if (_txInitialized) return 1; 08420 _txInitialized = 1; 08421 08422 #if defined (_TX_ALLOC_BREAK) && defined (_MSC_VER) // See http://msdn.microsoft.com/en-us/library/w2fhc9a3%28v=vs.90%29.aspx 08423 _CrtSetBreakAlloc (_TX_ALLOC_BREAK); // and http://support.microsoft.com/ru-ru/kb/151585 08424 #endif 08425 08426 #if defined (_TX_ALLOW_TRACE) 08427 _txLocLvlSet (1); 08428 #endif 08429 08430 _TX_ON_DEBUG (OutputDebugString ("\n"); 08431 OutputDebugString (_TX_VERSION " - The Dumb Artist Library, " _TX_AUTHOR ": \"" __FILE__ "\" " 08432 "compiled " __DATE__ " " __TIME__ ", " _TX_BUILDMODE " mode, module: " _TX_MODULE "\n"); 08433 OutputDebugString ("\n")); 08434 08435 _txMainThreadId = GetCurrentThreadId(); 08436 _txMainThread = OpenThread (THREAD_ALL_ACCESS, false, _txMainThreadId); 08437 08438 $3 _txIsDll = _txInDll(); 08439 08440 $ if (!_txIsDll) 08441 { 08442 $ _txConsole = ! FindAtom ("_txConsole"); 08443 $ (void) AddAtom ("_txConsole"); //-V530 08444 } 08445 08446 $ if (_txConsole) 08447 { 08448 $ _txCheckSourceCP (_TX_CODEPAGE, true); 08449 08450 $ unsigned long stackSize = _TX_STACKSIZE; 08451 $ _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize)); 08452 08453 $ _txOnSignal(); 08454 08455 $ if (_txLogName[0] == '~') 08456 {$ _tx_snprintf_s (_txLogName, sizeof (_txLogName) - 1, "%s.log", txGetModuleFileName()); } 08457 08458 $ if (!_txIsDll) 08459 { 08460 $ _TX_CALL (Win32::AddVectoredExceptionHandler, (1, (PVECTORED_EXCEPTION_HANDLER) _txVectoredExceptionHandler)); 08461 $ _txPrevUEFilter = SetUnhandledExceptionFilter ( (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter); 08462 } 08463 08464 $ ::std::set_terminate (_txOnTerminate); 08465 $ ::std::set_new_handler (_txOnNewHandlerAnsi); 08466 $ _TX_CALL (Win32::set_unexpected, (_txOnUnexpected)); 08467 08468 #if defined (_CLANG_VER) && !defined (_MSC_VER) 08469 $ ::std::__libcpp_debug_function = _txLibCppDebugFunction; 08470 #endif 08471 08472 $ SetConsoleCtrlHandler (_txOnConsoleCtrlEvent, true); 08473 08474 $ SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); 08475 08476 #if defined (_MSC_VER) 08477 08478 $ _set_printf_count_output (1); 08479 08480 $ _set_new_handler (_txOnNewHandler); 08481 $ _set_new_mode (1); 08482 08483 #if !defined (_CLANG_VER) 08484 08485 $ _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF); 08486 $ _CrtSetAllocHook (_txOnAllocHook); 08487 08488 $ unsigned mode = _CRTDBG_MODE_FILE; 08489 $ if (_CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, (_CRT_REPORT_HOOK) _txOnErrorReport) > 0) mode = 0; 08490 08491 $ _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_DEBUG | mode); 08492 $ _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW); 08493 $ _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG | mode | _CRTDBG_MODE_WNDW); 08494 $ _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR); 08495 $ _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR); 08496 $ _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR); 08497 08498 #endif 08499 08500 $ _set_abort_behavior (_WRITE_ABORT_MSG, _WRITE_ABORT_MSG); 08501 $ _set_abort_behavior (0, _CALL_REPORTFAULT); 08502 08503 $ _RTC_SetErrorFunc (_txOnRTCFailure); 08504 $ _set_purecall_handler (_txOnPureCall); 08505 $ _set_invalid_parameter_handler (_txOnInvalidParam); 08506 08507 #endif 08508 08509 #if defined (__STDC_LIB_EXT1__) 08510 $ ::std::set_constraint_handler_s (_txOnSecurityErrorAnsi); 08511 #endif 08512 08513 #if !defined (__CYGWIN__) && defined (_GCC_VER) && (_GCC_VER >= 530) && !defined (i386) 08514 $ __setusermatherr (_txOnMatherr); 08515 #endif 08516 08517 #if !defined (__CYGWIN__) 08518 $ _set_error_mode (_OUT_TO_MSGBOX | _OUT_TO_STDERR); 08519 #endif 08520 08521 $ HWND console = _txConsole_Attach(); 08522 $ SetWindowTextA (console, txGetModuleFileName (false)); 08523 } 08524 08525 $ _txSetProcAddress ("ExitProcess", (uintptr_t) _txOnExitProcess, "KERNEL32.DLL"); 08526 $ _txSetProcAddress ("TerminateProcess", (uintptr_t) _txOnTerminateProcess, "KERNEL32.DLL"); 08527 $ _txSetProcAddress ("FatalExit", (uintptr_t) _txOnFatalExit, "KERNEL32.DLL"); 08528 $ _txSetProcAddress ("FatalAppExitA", (uintptr_t) _txOnFatalAppExitA, "KERNEL32.DLL"); 08529 $ _txSetProcAddress ("UnhandledExceptionFilter", (uintptr_t) _txUnhandledExceptionFilter, "KERNEL32.DLL", true); //-V601 08530 $ _txSetProcAddress ("SetUnhandledExceptionFilter", (uintptr_t) _txOnSetUnhandledExceptionFilter, "KERNEL32.DLL"); 08531 $ _txSetProcAddress ("exit", (uintptr_t) _txOnExit); 08532 $ _txSetProcAddress ("_cexit", (uintptr_t) _txOnCExit); 08533 08534 $ InitializeCriticalSection (&_txCanvas_LockBackBuf); 08535 08536 $ HDC dc = Win32::CreateCompatibleDC (NULL); dc asserted; 08537 $ _txStockBitmap = (HBITMAP) Win32::SelectObject (dc, Win32::CreateCompatibleBitmap (dc, 1, 1)); _txStockBitmap asserted; 08538 $ Win32::DeleteObject (Win32::SelectObject (dc, _txStockBitmap)) asserted; 08539 $ Win32::DeleteDC (dc) asserted; 08540 08541 $ atexit (_txCleanup); 08542 08543 $ if (_txConsole) 08544 { 08545 $ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 08546 08547 $ tx_fpreset(); 08548 08549 $ srand ((unsigned) time (NULL)); //-V202 08550 08551 $ SetLastError (0); 08552 $ errno = 0; 08553 08554 #if !defined (__CYGWIN__) 08555 $ _doserrno = 0; 08556 #endif 08557 } 08558 08559 $ Win32::CoCreateInstance = Win32::CoCreateInstance; // g++ 5.1.0 bug, false warning "defined but not used" 08560 08561 $ return 1; 08562 } 08563 08564 //----------------------------------------------------------------------------------------------------------------- 08565 08566 bool _txCheckSourceCP (int needCP /*= _TX_CODEPAGE*/, bool verbose /*= true*/) 08567 { 08568 $3 const char* sCodePage = NULL; 08569 $ int codePage = 0; 08570 08571 $ switch (((unsigned const char*) "А") [0]) 08572 { 08573 case 192: {$ codePage = 1251; sCodePage = "1251."; break; } 08574 case 208: {$ codePage = 65001; sCodePage = "UTF-8."; break; } 08575 case 128: {$ codePage = 866; sCodePage = "866."; break; } 08576 case 225: {$ codePage = 20866; sCodePage = "KOI-8, waaat?!"; break; } 08577 default: {$ codePage = -1; sCodePage = "(Unknown)"; break; } 08578 } 08579 08580 $ if (codePage != needCP && verbose) 08581 { 08582 $ *_txTraceSE = ' '; // No stack trace please 08583 08584 $ _TX_UNEXPECTED ("\v\t" "\n\n" "WARNING: CHECK TXLib.h file CODEPAGE. Maybe it is %s It should be %d.\n\n" 08585 "This is NOT an error of TXLib itself. Please note:\n\n" 08586 "Do NOT copy-and-paste TXLib.h file contents into a new file and them save it inside your " 08587 "IDE or editor. This can change original TXLib codepage (%d) to another one. Instead, DO " 08588 "use copy / move / cut-and-paste operations in Windows Explorer (Far Manager etc) only. " 08589 "Or, when you see TXLib.h being opened in browser, use 'Save as...' (Ctrl+S) command.\n\n" 08590 "Now you should re-download TXLib.h file from the http://txlib.ru site.\n\n" 08591 "You can continue, but Russian messages and symbols may appear unreadable.", 08592 sCodePage, needCP, needCP); 08593 } 08594 08595 $ return (codePage == needCP); 08596 } 08597 08598 //----------------------------------------------------------------------------------------------------------------- 08599 08600 #ifdef _TX_DEBUG_LOAD 08601 08602 HMODULE _txLoadLibrary_ (const char* dll, int line); 08603 HMODULE _txLoadLibrary_ (const char* dll, int line) 08604 { 08605 txOutputDebugPrintf (_TX_DEBUG_LOAD "[" __FILE__ ":%04d] Loading \"%s\"... ", line, dll); 08606 08607 SetLastError (0); 08608 HMODULE lib = LoadLibrary (dll); 08609 08610 if (lib) txOutputDebugPrintf (_TX_DEBUG_LOAD "SUCSESS [%p]\n", (void*) lib); 08611 else txOutputDebugPrintf (_TX_DEBUG_LOAD "error %lu\n", GetLastError()); 08612 08613 return lib; 08614 } 08615 08616 #define LoadLibraryA(dll) _txLoadLibrary_ (dll, __LINE__) 08617 08618 #endif 08619 08620 //----------------------------------------------------------------------------------------------------------------- 08621 08622 void (*_txDllImport (const char dllFileName[], const char funcName[], bool required /*= true*/)) () 08623 { 08624 if (_TX_ARGUMENT_FAILED (dllFileName && *dllFileName)) return NULL; 08625 if (_TX_ARGUMENT_FAILED (funcName && *funcName)) return NULL; 08626 08627 static char dllPaths [4][MAX_PATH] = {}; 08628 08629 if (!*dllPaths[0]) 08630 { 08631 const char dllDir[] = "\\Windows\\"; 08632 char* path = NULL; 08633 size_t sz = 0; 08634 08635 // The dllPaths[0] is a directory where executable file is located 08636 08637 path = dllPaths[0]; 08638 08639 sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0; 08640 if (char* dir = strrchr (path, '\\')) dir[1] = 0; 08641 08642 // The dllPaths[1] is relative to directory where executable file is located 08643 08644 path = dllPaths[1]; 08645 08646 sz = GetModuleFileName (NULL, path, MAX_PATH); path[sz] = 0; 08647 if (char* dir = strrchr (path, '\\')) dir[0] = 0; 08648 08649 if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08650 08651 // The dllPaths[2] is relative to TXib.h file used in compilation 08652 08653 path = dllPaths[2]; 08654 08655 if (strchr (__FILE__, ':')) 08656 { 08657 strncpy_s (path, MAX_PATH, __FILE__, sizeof (__FILE__) - 1); 08658 } 08659 else 08660 { 08661 // No way to get include path at compile time using simple call "gcc file.cpp" 08662 08663 sz = GetCurrentDirectory (MAX_PATH, path); path[sz] = 0; 08664 if (*path) strncat_s (path, MAX_PATH, "\\" __FILE__, sizeof ("\\" __FILE__) - 1); 08665 } 08666 08667 if (char* dir = strrchr (path, '\\')) *dir = 0; 08668 08669 if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08670 08671 // The dllPaths[3] is relative to the TX Setup directory stored in the Registry 08672 08673 path = dllPaths[3]; 08674 08675 txRegQuery ("HKCU\\Software\\TX Library", "ProductDir", path, MAX_PATH); 08676 if (*path) strncat_s (path, MAX_PATH, dllDir, sizeof (dllDir) - 1); 08677 } 08678 08679 char dllName[MAX_PATH] = "", dllArch[MAX_PATH] = ""; 08680 const char* arch = (dllFileName? strchr (dllFileName, '*') : NULL); //-V547 08681 08682 if (arch) 08683 { 08684 assert (arch >= dllFileName); //-V547 08685 08686 strncpy_s (dllName, sizeof (dllName), dllFileName, (size_t) (arch - dllFileName)); 08687 strncat_s (dllName, sizeof (dllName), arch+1, sizeof (dllName) - 1 - strlen (dllName)); 08688 08689 strncpy_s (dllArch, sizeof (dllArch), dllFileName, (size_t) (arch - dllFileName)); 08690 strncat_s (dllArch, sizeof (dllArch), sizeof (void*) == 8? "64" : "32", 3); 08691 strncat_s (dllArch, sizeof (dllArch), arch+1, sizeof (dllArch) - 1 - strlen (dllArch)); 08692 } 08693 else if (dllFileName) //-V547 //-V2516 08694 { 08695 strncat_s (dllName, sizeof (dllName), dllFileName, sizeof (dllName) - 1); 08696 } 08697 08698 HMODULE dll = GetModuleHandle (dllFileName); 08699 08700 if (!dll) dll = GetModuleHandle (dllArch); 08701 if (!dll) dll = GetModuleHandle (dllName); 08702 08703 for (int i = 0; !dll && i < (int) sizearr (dllPaths); i++) 08704 { 08705 if (!dllPaths[i]) continue; 08706 08707 char path [MAX_PATH] = ""; 08708 strncpy_s (path, sizeof (path), dllPaths[i], sizeof (dllPaths[i])); 08709 size_t len = strlen (path); 08710 08711 SetDllDirectory (path); 08712 08713 strncpy_s (path + len, sizeof (path) - len, dllArch, sizeof (dllArch)); 08714 if (!dll && *dllArch) dll = LoadLibrary (path); //-V547 08715 08716 strncpy_s (path + len, sizeof (path) - len, dllName, sizeof (dllName)); 08717 if (!dll) dll = LoadLibrary (path); 08718 } 08719 08720 SetDllDirectory (NULL); 08721 08722 if (!dll && *dllArch) dll = LoadLibrary (dllArch); 08723 if (!dll) dll = LoadLibrary (dllName); 08724 08725 if (!dll && required) TX_ERROR ("\a" "Cannot load library \"%s%s%s\".", 08726 dllName, (arch? "\" / \"" : ""), dllArch); 08727 if (!dll) return NULL; 08728 08729 void (*addr)() = (void(*)()) GetProcAddress (dll, funcName); 08730 08731 if (!addr && required) TX_ERROR ("\a" "Cannot import \"%s\" from library \"%s%s%s\".", 08732 funcName, dllName, (arch? "\" / \"" : ""), dllArch); 08733 return addr; 08734 } 08735 08736 //----------------------------------------------------------------------------------------------------------------- 08737 08738 #ifdef _TX_DEBUG_LOAD 08739 #undef LoadLibraryA 08740 #endif 08741 08742 //----------------------------------------------------------------------------------------------------------------- 08743 08744 #if defined (_MSC_VER) && (_MSC_VER == 1800) // MSVC 2013 08745 #pragma warning (push) 08746 #pragma warning (disable: 6102) // Использование 'name' из завершившегося ошибкой вызова функции 08747 #endif 08748 08749 int txRegQuery (const char* keyName, const char* valueName, void* value, size_t szValue) 08750 { 08751 if (_TX_ARGUMENT_FAILED (keyName)) return 0; 08752 08753 HKEY hive = NULL; 08754 08755 #define EQU_(name1, name2) ( _strnicmp (keyName, name1 "\\", sizeof (name1)) == 0 || \ 08756 _strnicmp (keyName, name2 "\\", sizeof (name2)) == 0 ) 08757 08758 if (EQU_("HKLM", "HKEY_LOCAL_MACHINE")) hive = HKEY_LOCAL_MACHINE; 08759 else if (EQU_("HKCU", "HKEY_CURRENT_USER")) hive = HKEY_CURRENT_USER; 08760 else if (EQU_("HKCR", "HKEY_CLASSES_ROOT")) hive = HKEY_CLASSES_ROOT; 08761 else if (EQU_("HKU", "HKEY_USERS")) hive = HKEY_USERS; 08762 else if (EQU_("HKCC", "HKEY_CURRENT_CONFIG")) hive = HKEY_CURRENT_CONFIG; 08763 08764 else { _TX_ARGUMENT_FAILED (("keyName должно начинаться с HKLM\\, HKCU\\, HKCR\\, HKU\\ или HKCC\\ ", hive)); return 0; } 08765 08766 #undef EQU_ 08767 08768 keyName = strchr (keyName, '\\') + 1; //-V769 08769 assert (keyName > (const char*) 1); 08770 08771 HKEY key = NULL; 08772 DWORD size = 0; 08773 08774 bool ok = (RegOpenKeyEx (hive, keyName, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS); 08775 if (ok) ok &= (RegQueryValueEx (key, valueName, NULL, NULL, NULL, &size) == ERROR_SUCCESS); 08776 if (ok && value && size < szValue) ok &= (RegQueryValueEx (key, valueName, NULL, NULL, (BYTE*) value, &size) == ERROR_SUCCESS); //-V104 08777 if (key) ok &= (RegCloseKey (key) == ERROR_SUCCESS); 08778 08779 return size; 08780 } 08781 08782 #if defined (_MSC_VER) && (_MSC_VER == 1800) 08783 #pragma warning (pop) 08784 #endif 08785 08786 #endif // TX_COMPILED 08787 08788 //} 08789 //----------------------------------------------------------------------------------------------------------------- 08790 08791 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08792 08793 HWND txCreateWindow (double sizeX, double sizeY, bool centered /*= true*/) 08794 { 08795 $1 if (!_txInitialized) _txInitialized = _txInitialize(); 08796 08797 $ if (HWND wnd = txWindow()) 08798 { 08799 $ SetLastErrorEx (ERROR_INVALID_DATA, 0); 08800 $ _TX_ON_DEBUG (TX_ERROR ("\a" "Окно рисования уже создано!")); 08801 $ return wnd; 08802 } 08803 08804 $ if (!_txIsDll) 08805 { 08806 $ _txMain = ! FindAtom ("_txMain"); // Not a thread-safe 08807 $ (void) AddAtom ("_txMain"); //-V530 08808 } 08809 08810 $ if (_txWindowUpdateInterval < 10) {$ _txWindowUpdateInterval = 10; } //-V1048 08811 08812 $ _txRunning = false; 08813 08814 // Store the size 08815 08816 $ static SIZE size = { ROUND (sizeX), ROUND (sizeY) }; 08817 $ if (centered) { size.cx *= -1; size.cy *= -1; } 08818 08819 // In Thread, where REAL creation lies... 08820 08821 $ unsigned id = 0; 08822 $ _txCanvas_Thread = (HANDLE) Win32::_beginthreadex (NULL, 0, _txCanvas_ThreadProc, &size, 0, &id); 08823 08824 $ if (!_txCanvas_Thread) return TX_DEBUG_ERROR ("\a" "Cannot start canvas thread."), (HWND) NULL; 08825 08826 $ _txWaitFor (_txRunning, 10*_TX_TIMEOUT); 08827 08828 $ if (!_txRunning) return TX_DEBUG_ERROR ("\a" "Cannot create canvas window."), (HWND) NULL; 08829 $ if (!txOK()) return TX_DEBUG_ERROR ("\a" "Canvas window is not OK."), (HWND) NULL; 08830 08831 $ HWND console = Win32::GetConsoleWindow(); 08832 08833 $ DWORD proc = 0; 08834 $ GetWindowThreadProcessId (console, &proc); 08835 08836 $ if (console && (proc == GetCurrentProcessId() || _txIsParentListed (_TX_WAITABLE_PARENTS))) 08837 {$ ShowWindow (console, TX_CONSOLE_MODE); } 08838 08839 $ HMENU menu = GetSystemMenu (txWindow(), false); 08840 if (menu) {$ CheckMenuItem (menu, _TX_IDM_CONSOLE, (console? (IsWindowVisible (console)? MF_CHECKED : 0) : MF_DISABLED)); } 08841 08842 $ Win32::GdiSetBatchLimit (1); 08843 08844 $ SetLastError (0); 08845 08846 $ errno = 0; 08847 08848 #if !defined (__CYGWIN__) 08849 $ _doserrno = 0; 08850 #endif 08851 08852 $ return txWindow(); 08853 } 08854 08855 //----------------------------------------------------------------------------------------------------------------- 08856 08857 HWND txCreateExtraWindow (CREATESTRUCT createData) 08858 { 08859 $1 if (_TX_TXWINDOW_FAILED()) return NULL; 08860 08861 $ volatile HWND wnd = NULL; 08862 $ createData.hInstance = (HINSTANCE)(uintptr_t) &wnd; 08863 08864 $ PostMessage (txWindow(), _TX_WM_CREATEWND, 0, (LPARAM) &createData) asserted; 08865 08866 $ _txWaitFor (wnd, 5*_TX_TIMEOUT); 08867 08868 $ return wnd; 08869 } 08870 08871 //----------------------------------------------------------------------------------------------------------------- 08872 08873 bool txSetDefaults (HDC dc /*= txDC()*/) 08874 { 08875 $1 if (dc == txDC()) txUpdateWindow (false); //-V601 08876 $ txAutoLock _lock; 08877 08878 $ RECT r = {}; 08879 $ GetClientRect (Win32::GetConsoleWindow(), &r); 08880 $ SIZE szCon = { r.right - r.left, r.bottom - r.top }; 08881 08882 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 08883 08884 $ CONSOLE_SCREEN_BUFFER_INFO con = {{80, 25}, {}, 0, {0, 0, 80-1, 25-1}, {80, 25}}; 08885 $ GetConsoleScreenBufferInfo (out, &con); 08886 08887 $ SIZE szTxt = { (short) (con.srWindow.Right - con.srWindow.Left + 1), 08888 (short) (con.srWindow.Bottom - con.srWindow.Top + 1) }; 08889 08890 //{ Set defaults for graphics layer 08891 08892 $ _txBuffer_Select (Win32::GetStockObject (WHITE_PEN), dc) asserted; 08893 $ _txBuffer_Select (Win32::GetStockObject (WHITE_BRUSH), dc) asserted; 08894 08895 $ _txBuffer_Select (Win32::CreateFont (szCon.cy/szTxt.cy, szCon.cx/szTxt.cx, 08896 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 08897 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 08898 DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT), 08899 dc) asserted; 08900 08901 $ (Win32::SetTextColor (dc, TX_WHITE) != CLR_INVALID) asserted; 08902 $ Win32::SetBkMode (dc, TRANSPARENT) asserted; 08903 08904 $ Win32::SetROP2 (dc, R2_COPYPEN) asserted; 08905 $ Win32::SetStretchBltMode (dc, HALFTONE) asserted; 08906 08907 //} 08908 08909 $ if (dc != txDC()) 08910 {$ return true; } 08911 08912 //{ Set defaults for console layer 08913 08914 $ POINT szCanvas = txGetExtent (dc); 08915 08916 $ HGDIOBJ font = txFontExist (TX_CONSOLE_FONT)? 08917 Win32::CreateFont (szCanvas.y/szTxt.cy, szCanvas.x/szTxt.cx, 08918 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 08919 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 08920 DEFAULT_QUALITY, FIXED_PITCH, TX_CONSOLE_FONT) 08921 : 08922 Win32::GetStockObject (SYSTEM_FIXED_FONT); 08923 08924 $ _txBuffer_Select (font, _txCanvas_BackBuf[1]); 08925 //} 08926 08927 //{ Scroll the console for text to go above top of window and don't mix with graphics 08928 08929 $ if (con.dwCursorPosition.X) _putch ('\n'); 08930 08931 $ short delta = (short) (con.dwCursorPosition.Y - con.srWindow.Top); 08932 08933 $ con.srWindow.Top = (short) (con.srWindow.Top + delta); 08934 $ con.srWindow.Bottom = (short) (con.srWindow.Bottom + delta); 08935 08936 $ SMALL_RECT src = { 0, 0, (short) (con.dwSize.X - 1), (short) (con.dwSize.Y - 1) }; 08937 $ CHAR_INFO fill = { {' '}, FOREGROUND_LIGHTGRAY }; 08938 $ COORD dest = { 0, (short) -delta }; // New UL-corner of src, scroll up 08939 08940 $ con.dwCursorPosition.X = 0; 08941 $ con.dwCursorPosition.Y = (short) (con.dwCursorPosition.Y - delta); 08942 08943 $ (con.srWindow.Bottom < con.dwSize.Y && // Move the "window" 08944 SetConsoleWindowInfo (out, true, &con.srWindow)) 08945 || 08946 (ScrollConsoleScreenBuffer (out, &src, NULL, dest, &fill), // Or scroll the buffer 08947 SetConsoleCursorPosition (out, con.dwCursorPosition)); 08948 //} 08949 08950 $ txUpdateWindow (true); //-V601 08951 08952 return true; 08953 } 08954 08955 #endif // TX_COMPILED 08956 08957 //----------------------------------------------------------------------------------------------------------------- 08958 08959 inline bool txOK() 08960 { 08961 return (_txCanaryFirst == 0x776F656D && // Too well-known values to use constants. You know these values, don't you? 08962 _txCanaryLast == 0x5E2E2E5E && 08963 _txCanvas_OK() 08964 08965 #if defined (_MSC_VER) 08966 && _CrtCheckMemory() 08967 #endif 08968 ); 08969 } 08970 08971 //----------------------------------------------------------------------------------------------------------------- 08972 //{ Cleanup 08973 //----------------------------------------------------------------------------------------------------------------- 08974 08975 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 08976 08977 // Implicit std(MSVCRT.dll)::_cexit() call before _txCleanup can lead to hangs in _cexit handlers chain. 08978 // So redefining ::std::_cexit(). Do it dynamically via PE Import Table hook to avoid duplicate symbols 08979 // if several modules linked together include TXLib.h. See _txSetProcAddress() call in _txInitialize(). 08980 08981 void _txOnCExit() 08982 { 08983 OutputDebugString ("\n"); 08984 08985 $5 _txCleanup(); 08986 08987 _TX_CALLv (Win32::_cexit, ()); 08988 } 08989 08990 //----------------------------------------------------------------------------------------------------------------- 08991 08992 void _txOnExit (int retcode) 08993 { 08994 if (retcode != 0) 08995 { 08996 OutputDebugString ("\n"); 08997 txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode); 08998 } 08999 09000 $5 _txCleanup(); 09001 09002 if (retcode != 0) 09003 txOutputDebugPrintf ("%s - WARNING: calling Win32::exit (%d)\n", _TX_VERSION, retcode); 09004 09005 Win32::exit (retcode); 09006 } 09007 09008 //----------------------------------------------------------------------------------------------------------------- 09009 09010 void _txOnExitProcess (unsigned retcode) 09011 { 09012 if (retcode != 0) 09013 { 09014 OutputDebugString ("\n"); 09015 txOutputDebugPrintf ("%s - WARNING: %s (%u) called\n", _TX_VERSION, __func__, retcode); 09016 } 09017 09018 $5 _txCleanup(); 09019 09020 if (retcode != 0) 09021 txOutputDebugPrintf ("%s - WARNING: calling Win32::ExitProcess (%u)\n", _TX_VERSION, retcode); 09022 09023 Win32::ExitProcess (retcode); 09024 } 09025 09026 //----------------------------------------------------------------------------------------------------------------- 09027 09028 bool _txOnTerminateProcess (HANDLE process, unsigned retcode) 09029 { 09030 if (retcode != 0) 09031 { 09032 OutputDebugString ("\n"); 09033 txOutputDebugPrintf ("%s - WARNING: %s (0x%p, %u) called\n", _TX_VERSION, __func__, process, retcode); 09034 } 09035 09036 $5 _txCleanup(); 09037 09038 if (retcode != 0) 09039 txOutputDebugPrintf ("%s - WARNING: calling Win32::TerminateProcess (0x%p, %u)\n", _TX_VERSION, process, retcode); 09040 09041 return Win32::TerminateProcess (process, retcode); 09042 } 09043 09044 //----------------------------------------------------------------------------------------------------------------- 09045 09046 void _txOnFatalExit (int retcode) 09047 { 09048 OutputDebugString ("\n"); 09049 txOutputDebugPrintf ("%s - WARNING: %s:%d called\n", _TX_VERSION, __func__, retcode); 09050 09051 $5 _txCleanup(); 09052 09053 txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalExit (%d)\n", _TX_VERSION, retcode); 09054 _TX_CALLv (Win32::FatalExit, (retcode)); 09055 09056 txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (%d)\n", _TX_VERSION, retcode); 09057 Win32::TerminateProcess (GetCurrentProcess(), retcode); 09058 } 09059 09060 //----------------------------------------------------------------------------------------------------------------- 09061 09062 void _txOnFatalAppExitA (unsigned action, const char message[]) 09063 { 09064 OutputDebugString ("\n"); 09065 txOutputDebugPrintf ("%s - WARNING: %s (%u, \"%s\") called\n", _TX_VERSION, __func__, action, message); 09066 09067 $5 _txCleanup(); 09068 09069 txOutputDebugPrintf ("%s - WARNING: calling Win32::FatalAppExitA (%u, %s)\n", _TX_VERSION, action, message); 09070 _TX_CALLv (Win32::FatalAppExitA, (action, message)); 09071 09072 txOutputDebugPrintf ("%s - WARNING: Win32::FatalExit() failure, calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION); 09073 Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 09074 } 09075 09076 //----------------------------------------------------------------------------------------------------------------- 09077 09078 BOOL WINAPI _txOnConsoleCtrlEvent (DWORD type) 09079 { 09080 OutputDebugString ("\n"); 09081 txOutputDebugPrintf ("%s - WARNING: %s (0x%04lX) called\n", _TX_VERSION, __func__, (unsigned long) type); 09082 09083 $5 switch (type) 09084 { 09085 case CTRL_LOGOFF_EVENT: 09086 case CTRL_SHUTDOWN_EVENT: $ _txExit = true; 09087 $ _txCleanup(); 09088 case CTRL_C_EVENT: 09089 case CTRL_CLOSE_EVENT: 09090 case CTRL_BREAK_EVENT: 09091 09092 default: break; //-V2522 09093 } 09094 09095 $ return false; 09096 } 09097 09098 //----------------------------------------------------------------------------------------------------------------- 09099 09100 void _txCleanup() 09101 { 09102 if (!_txInitialized) return; 09103 else _txInitialized = false; //-V601 09104 09105 $3 _txRunning = false; 09106 $ _txConsole_IsBlinking = false; 09107 09108 $ txSetProgress (100, (!_txErrors)? Win32::TBPF_PAUSED : Win32::TBPF_ERROR); 09109 09110 $ txSetWindowsHook (NULL); 09111 09112 $ HWND canvas = txWindow(); 09113 $ HWND console = Win32::GetConsoleWindow(); 09114 $ unsigned thread = GetCurrentThreadId(); 09115 09116 $ HWND wnd = (canvas)? canvas : console; 09117 09118 $ bool externTerm = (thread != _txMainThreadId && 09119 thread != _txCanvas_ThreadId); 09120 09121 $ DWORD list[1] = {}; 09122 $ DWORD ownsConsole = (GetConsoleProcessList (list, 1) <= 1); 09123 09124 $ int envPause = -1; 09125 $ char envPause_s[10] = ""; 09126 $ size_t envPause_sz = 0; 09127 $ getenv_s (&envPause_sz, envPause_s, sizeof (envPause_s) - 1, "TX_PAUSE"); 09128 09129 if (strcmp (envPause_s, "1") == 0 || _stricmp (envPause_s, "ON") == 0) {$ envPause = 1; } 09130 if (strcmp (envPause_s, "0") == 0 || _stricmp (envPause_s, "OFF") == 0) {$ envPause = 0; } 09131 09132 $ DWORD parent = 0; 09133 $ int isParentWaitable = _txIsParentListed (_TX_WAITABLE_PARENTS, &parent); 09134 09135 $ if (canvas) 09136 {$ txSleep (5*_txWindowUpdateInterval); } 09137 09138 $ if (_txConsole) 09139 { 09140 $ if (_txMain) txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 09141 09142 $ if (console) 09143 { 09144 $ EnableWindow (console, true); 09145 $ _txSetWindowText (console, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); 09146 } 09147 } 09148 09149 $ if (_txMain && !externTerm && canvas) 09150 {$ _txSetWindowText (canvas, " [ЗАВЕРШЕНО]", " [FINISHED]", 2, L"\x0417" /* 'З' */ L"\x0046" /* 'F' */); } 09151 09152 $ std::cout.flush(); 09153 $ std::cerr.flush(); 09154 $ std::clog.flush(); 09155 $ _flushall(); 09156 09157 $ bool paused = false; 09158 $ if (((canvas? _txMain : _txConsole) && !_txExit) || (_txErrors && thread == _txMainThreadId)) 09159 { 09160 $ if (wnd) 09161 { 09162 $ int isVSCode = _txIsParentListed (_TX_VSCODE_PARENTS); 09163 09164 $ if (isParentWaitable >= 0 && !isVSCode) 09165 {$ _txActivateWindow (wnd, 0x10); } 09166 09167 $ EnableWindow (wnd, true); 09168 } 09169 09170 $ if ((console && (ownsConsole || canvas || _txErrors || envPause == 1)) && isParentWaitable >= 0 && !(envPause == 0)) 09171 { 09172 $ txPause ((_txErrors)? "\f\n" "[Press F to Pay Respects...]" : 09173 (!canvas && _txIsTTY (0))? "\f\n" "[Нажмите любую клавишу для завершения]" : "\f"); 09174 09175 $ paused = true; 09176 } 09177 } 09178 09179 $ if (_txConsole && _txWatchdogTimeout >= 0) 09180 {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); } 09181 09182 $ if (txWindow()) 09183 {$ SendNotifyMessage (txWindow(), WM_DESTROY, 0, 0); } 09184 09185 $ _txWaitFor (!txWindow(), 5*_TX_TIMEOUT); 09186 09187 $ txSpeak (NULL); 09188 $ txPlayVideo (NULL); 09189 09190 $ delete _txCanvas_UserDCs; 09191 $ _txCanvas_UserDCs = NULL; 09192 09193 $ if (GetCurrentThreadId() != _txMainThreadId) 09194 {$ SuspendThread (_txMainThread); } //-V720 09195 $ if (GetCurrentThreadId() != _txCanvas_ThreadId) 09196 {$ SuspendThread (_txCanvas_Thread); } //-V720 09197 09198 $ if (_txMainThread) 09199 {$ CloseHandle (_txMainThread) asserted; _txMainThread = NULL; } 09200 $ if (_txCanvas_Thread) 09201 {$ CloseHandle (_txCanvas_Thread) asserted; _txCanvas_Thread = NULL; } 09202 09203 $ if (!txWindow()) 09204 {$ DeleteCriticalSection (&_txCanvas_LockBackBuf); CRITICAL_SECTION zero = {0, -1}; _txCanvas_LockBackBuf = zero; } 09205 09206 $ bool parentKilled = false; 09207 $ if (isParentWaitable && !externTerm && paused && _txNOP (_TX_ALLOW_KILL_PARENT)) 09208 { 09209 $ console = Win32::GetConsoleWindow(); 09210 09211 $ if (parent) 09212 {$ parentKilled = _txKillProcess (parent); } 09213 09214 $ if (parent && !parentKilled) 09215 { 09216 $ PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001); // Scancode = 0x1C, Count = 1 09217 $ PostMessage (console, WM_KEYUP, VK_RETURN, 0xC01C0001); // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1 09218 } 09219 } 09220 09221 $ if (_txConsole) 09222 {$ _txSetWindowText (console, NULL); } 09223 09224 $ if (_txMain && _txConsole) 09225 {$ _txConsole_Detach (isParentWaitable && !externTerm && !parentKilled); } //-V560 09226 09227 $ std::cout.flush(); 09228 $ std::cerr.flush(); 09229 $ std::clog.flush(); 09230 $ _flushall(); 09231 09232 $ _txSymGetFromAddr (NULL); 09233 09234 // That's all, folks 09235 09236 _TX_ON_DEBUG (OutputDebugString ("\n"); 09237 OutputDebugString (_TX_VERSION " - FINISHED: " _TX_MODULE "\n"); 09238 OutputDebugString ("\n")); 09239 } 09240 09241 //----------------------------------------------------------------------------------------------------------------- 09242 09243 int txPause (const char* message /*= NULL*/, ...) 09244 { 09245 $3 bool wine = !!Win32::wine_get_version; 09246 09247 $ HWND canvas = txWindow(); 09248 $ HWND console = Win32::GetConsoleWindow(); 09249 $ HWND wnd = (canvas)? canvas : console; 09250 $ bool istty0 = _txIsTTY (0); 09251 09252 $ int attr = txGetConsoleAttr(); 09253 09254 $ int oldCP = GetConsoleOutputCP(); 09255 $ SetConsoleOutputCP (_TX_CODEPAGE); 09256 09257 if (!message) {$ message = "[Нажмите любую клавишу для продолжения]"; } 09258 09259 if (*message != '\f') {$ _txSetWindowText (wnd, " [Нажмите клавишу...]", " [Press a key...]"); } 09260 else {$ message++; } 09261 09262 if (*message != '\v') {$ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); } 09263 else {$ message++; } 09264 09265 $ int isVSCode = _txIsParentListed (_TX_VSCODE_PARENTS); 09266 09267 $ if (!isVSCode) 09268 {$ _txActivateWindow (wnd, 0x10); } 09269 09270 $ va_list args; 09271 $ va_start (args, message); 09272 $ vfprintf (stderr, message, args); 09273 $ va_end (args); 09274 09275 $ va_start (args, message); 09276 $ txOutputDebugPrintf ("txPause(): message, args"); // !!! 0xC0000005 reading [-1] 09277 $ va_end (args); 09278 09279 $ fflush (stderr); 09280 $ txSleep(); 09281 09282 $ Win32::FLASHWINFO flash = { sizeof (flash), wnd, FLASHW_ALL | FLASHW_TIMERNOFG, 0xFFFFFFFF }; 09283 $ _TX_CALL (Win32::FlashWindowEx, (&flash)); 09284 09285 $ int ch = EOF; 09286 if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); } 09287 09288 $ for (int i = 1; ; i++) //-V2530 09289 { 09290 $ Sleep (_txWindowUpdateInterval); 09291 09292 if (!istty0 && !canvas) {$ break; } // No need to run and hide 09293 09294 if (!wine && (ch = _txGetInput()) != EOF) {$ break; } // Somebody hit something. 09295 09296 if (canvas && !_txCanvas_ThreadId) {$ break; } // There was a window, and now there is not. 09297 09298 if (!Win32::GetConsoleWindow()) {$ break; } // Console was destroyed 09299 09300 if (_TX_CALL (Win32::GhostWindowFromHungWindow, (canvas))) 09301 {$ TX_ERROR ("Похоже, программа зависла :("); break; } 09302 09303 if (canvas && _TX_CALL (Win32::IsHungAppWindow, (canvas))) 09304 {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа-таки зависла"); break; } 09305 09306 if (canvas && !SendMessageTimeout (canvas, WM_NULL, 0,0, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL)) 09307 {$ _txTrace (__FILE__, __LINE__, NULL, "WARNING: Программа не отвечает"); break; } 09308 09309 if (!wine && !(i % 100500)) 09310 {$ fprintf (stderr, "\r" "[Так нажмите же какую-нибудь клавишу...] \b\b"); } 09311 } 09312 09313 if (istty0) {$ while (!wine && _kbhit()) ch = _getch(); } 09314 09315 $ _txSetWindowText (wnd, NULL); 09316 09317 $ fprintf (stderr, "\n"); 09318 09319 if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); } 09320 09321 $ SetConsoleOutputCP (oldCP); 09322 $ txSetConsoleAttr (attr); 09323 09324 $ return ch; 09325 } 09326 09327 //----------------------------------------------------------------------------------------------------------------- 09328 09329 int _txGetInput() 09330 { 09331 $4 HANDLE con = GetStdHandle (STD_INPUT_HANDLE); 09332 $ int ch = EOF; 09333 09334 $ DWORD nChars = 0; 09335 $ if (GetConsoleMode (con, &nChars) == 0 && 09336 PeekNamedPipe (con, NULL, 0, NULL, &nChars, NULL)) 09337 { 09338 $ ch = (nChars)? fgetc (stdin) : EOF; 09339 } 09340 09341 else if (_kbhit()) 09342 { 09343 $ ch = _getch(); 09344 } 09345 09346 #if defined (_MSC_VER) && (_MSC_VER < 1700) 09347 09348 else if (fseek (stdin, 1, SEEK_CUR) != EOF) 09349 { 09350 $ (void) fseek (stdin, -1, SEEK_CUR); 09351 $ ch = fgetc (stdin); // This causes blocking in MSVC 2011 beta 09352 } 09353 09354 #endif 09355 09356 if (ch == 3 /* Ctrl+C */) {$ raise (SIGABRT); } 09357 09358 $ return ch; 09359 } 09360 09361 //----------------------------------------------------------------------------------------------------------------- 09362 09363 bool _txIsTTY (int fd) 09364 { 09365 $4 return GetFileType ((HANDLE)_get_osfhandle (fd)) == FILE_TYPE_CHAR; 09366 } 09367 09368 //----------------------------------------------------------------------------------------------------------------- 09369 09370 int _txSetWindowText (HWND wnd, const char* textRus, const char* textEng /*= NULL*/, 09371 int checkOfs /*= 0*/, const wchar_t checkLetters[2] /*= NULL*/) 09372 { 09373 struct tools 09374 { 09375 static LRESULT getWindowText (HWND window, wchar_t text[], size_t size) 09376 { 09377 $3 memset (text, 0, size * sizeof (*text)); 09378 09379 $ return SendMessageTimeoutW (window, WM_GETTEXT, (WPARAM) size, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL); 09380 } 09381 09382 static LRESULT setWindowText (HWND window, wchar_t text[]) 09383 { 09384 $1 return SendMessageTimeoutW (window, WM_SETTEXT, 0, (LPARAM) text, SMTO_BLOCK | SMTO_ABORTIFHUNG, _TX_TIMEOUT, NULL); 09385 } 09386 }; 09387 09388 $1 static wchar_t _tx_thread title [_TX_BUFSIZE+15] = L"TXLib"; 09389 $ static wchar_t _tx_thread oldTitle [_TX_BUFSIZE+15] = L"TXLib"; 09390 09391 $ if (!textRus) 09392 { 09393 $ tools::setWindowText (wnd, oldTitle); 09394 $ return -1; 09395 } 09396 09397 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09398 $ int len = (int) wcslen (title); if (len >= (int)_TX_BUFSIZE) len = _TX_BUFSIZE-1; 09399 $ memcpy (oldTitle, title, sizeof (oldTitle)); 09400 09401 $ if (textRus) 09402 { 09403 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textRus, -1, title + len, (int)_TX_BUFSIZE - len); 09404 09405 $ tools::setWindowText (wnd, title); 09406 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09407 if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[0]) {$ return 0; } 09408 if (!checkLetters) {$ return -2; } 09409 } 09410 09411 $ if (textEng) 09412 { 09413 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textEng, -1, title + len, (int)_TX_BUFSIZE - len); 09414 09415 $ tools::setWindowText (wnd, title); 09416 $ tools::getWindowText (wnd, title, _TX_BUFSIZE-1); 09417 if (checkLetters && len <= (int)_TX_BUFSIZE-1-2 && title [len + checkOfs] == checkLetters[1]) {$ return 1; } 09418 if (!checkLetters) {$ return -2; } 09419 } 09420 09421 $ return -3; 09422 } 09423 09424 //----------------------------------------------------------------------------------------------------------------- 09425 09426 int _txIsParentListed (const char* list, DWORD* parentPID /*= NULL*/) 09427 { 09428 $4 PROCESSENTRY32* info = _txFindProcess(); 09429 $ if (!info) return 0; 09430 09431 $ info = _txFindProcess (info->th32ParentProcessID); 09432 $ if (!info) return 0; 09433 09434 $ char parent [MAX_PATH] = ""; 09435 $ strncpy_s (parent, sizeof (parent), info->szExeFile, sizeof (parent) - 1); 09436 $ if (parentPID) *parentPID = info->th32ProcessID; 09437 09438 $ info = _txFindProcess (info->th32ParentProcessID); // info: grandparent 09439 09440 $ char lst[_TX_BUFSIZE] = ""; 09441 $ strncpy_s (lst, sizeof (lst), list, strlen (list)); 09442 09443 $ char* ctx = NULL; 09444 $ for (char* p = strtok_s (lst, ", ", &ctx); p; p = strtok_s (NULL, ", ", &ctx)) 09445 { 09446 $ char* gp = strchr (p, ':'); 09447 09448 $ if (gp) 09449 { 09450 $ *gp++ = 0; 09451 09452 $ if (_stricmp (p, parent) != 0) { continue; } 09453 09454 $ if (info) if (_stricmp (gp, info->szExeFile) == 0) // Was &&, but MSVC /analyze is so paranoid 09455 {$ return islower ((unsigned char) *gp)? +1 : -1; } 09456 } 09457 else 09458 { 09459 $ if (_stricmp (p, parent) == 0) 09460 {$ return islower ((unsigned char) *p)? +1 : -1; } 09461 } 09462 } 09463 09464 $ return 0; 09465 } 09466 09467 //----------------------------------------------------------------------------------------------------------------- 09468 09469 void _txWatchdogTerminator (void* timeout) // Or Watchcat? Possibly will change in future versions 09470 { 09471 $3 if (_TX_ARGUMENT_FAILED (timeout)) return; 09472 09473 $ Sleep (*(int*) timeout); //-V206 09474 09475 $ OutputDebugString ("\n"); 09476 txOutputDebugPrintf ("%s - WARNING: %s(): Timeout (%d) expired, activating. %s\n", // Kinda static reflection... 09477 _TX_VERSION, __func__, *(int*) timeout, ((__func__[8] == 'd')? "Bark, bark" : "Meow, meow")); //-V206 09478 $ DWORD parent = 0; 09479 $ if (_txIsParentListed (_TX_WAITABLE_PARENTS, &parent)) 09480 { 09481 txOutputDebugPrintf ("%s - WARNING: %s(): Calling _txKillProcess (0x%04lu)\n", 09482 _TX_VERSION, __func__, (unsigned long) parent); 09483 09484 $ _txKillProcess (parent); 09485 09486 $ HWND console = GetConsoleWindow(); 09487 $ PostMessage (console, WM_KEYDOWN, VK_RETURN, 0x001C0001); // Scancode = 0x1C, Count = 1 09488 $ PostMessage (console, WM_KEYUP, VK_RETURN, 0xC01C0001); // Scancode = 0x1C, Count = 1, Prev = 1, Trans = 1 09489 } 09490 09491 txOutputDebugPrintf ("%s - WARNING: %s(): Calling Win32::TerminateProcess (EXIT_FAILURE)\n", _TX_VERSION, __func__); 09492 $ Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 09493 } 09494 09495 #endif // TX_COMPILED 09496 09497 //} 09498 //----------------------------------------------------------------------------------------------------------------- 09499 09500 //----------------------------------------------------------------------------------------------------------------- 09501 //{ Tools 09502 //----------------------------------------------------------------------------------------------------------------- 09503 09504 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 09505 09506 // You are here, little hacker? 09507 09508 int _txTaskKill (const char i[] /*= NULL*/, 09509 const char doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine[] /*= NULL*/, 09510 unsigned x /*= 0*/) 09511 { 09512 // ...so tired of it already... 09513 09514 #define name i // Great name! 09515 #define cmdLineSubstr doYouWantToFindSomethingInTheCommandLineIDidSomethingForYouToFindSomethingInTheCommandLineMaybeYouWillFindSomeInterestingInTheCommandLineSoIDidSomethingForYouInTheCommandLine 09516 #define pid x // Another great name, isn't it? 09517 09518 $3 if (_TX_ARGUMENT_FAILED ((name || cmdLineSubstr || pid) && "Вот такие тут интересные имена встречаются...")) return false; //-V560 //-V601 09519 09520 $ wchar_t cmdLineSubstrW[_TX_BUFSIZE] = L""; 09521 if (cmdLineSubstr) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, cmdLineSubstr, -1, cmdLineSubstrW, sizearr (cmdLineSubstrW)); } 09522 09523 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 09524 $ assert (sshot); if (!sshot) return 0; //-V547 09525 09526 $ int killed = 0; 09527 09528 $ PROCESSENTRY32 info = { sizeof (info) }; 09529 $ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info)) 09530 { 09531 bool kill = false; 09532 09533 if (!kill && pid && info.th32ParentProcessID == pid) {$ kill = true; } //-V560 09534 09535 if (!kill && name && _stricmp (info.szExeFile, name) == 0) {$ kill = true; } 09536 09537 if (!kill) 09538 { 09539 wchar_t cmdLineW[_TX_BUFSIZE] = L""; 09540 if (!_txGetCommandLine (cmdLineW, sizearr (cmdLineW), info.th32ProcessID)) { continue; } 09541 09542 if (*cmdLineW && stristrw (cmdLineW, cmdLineSubstrW)) {$ kill = true; } 09543 } 09544 09545 if (kill) 09546 { 09547 $ if (_txKillProcess (info.th32ProcessID)) 09548 {$ killed++; } 09549 } 09550 } 09551 09552 $ CloseHandle (sshot); 09553 09554 $ return killed; 09555 09556 #undef name 09557 #undef cmdLine 09558 #undef pid 09559 } 09560 09561 //----------------------------------------------------------------------------------------------------------------- 09562 09563 bool _txKillProcess (DWORD pid) 09564 { 09565 $3 if (_TX_ARGUMENT_FAILED (pid)) return false; 09566 09567 $ HANDLE token = INVALID_HANDLE_VALUE; 09568 $ OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) asserted; 09569 09570 $ LUID luid = {}; 09571 $ LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid) asserted; 09572 09573 $ TOKEN_PRIVILEGES priv = { 1, {{{ luid.LowPart, luid.HighPart}, SE_PRIVILEGE_ENABLED }}}; 09574 $ TOKEN_PRIVILEGES old = {}; 09575 09576 $ DWORD oldSz = 0; 09577 $ AdjustTokenPrivileges (token, false, &priv, sizeof (priv), &old, &oldSz) asserted; 09578 09579 $ HANDLE proc = OpenProcess (PROCESS_ALL_ACCESS, 0, pid); 09580 $ if (!proc) return false; 09581 09582 $ bool ok = !!Win32::TerminateProcess (proc, 0); 09583 $ CloseHandle (proc); 09584 09585 $ return ok; 09586 } 09587 09588 //----------------------------------------------------------------------------------------------------------------- 09589 09590 PROCESSENTRY32* _txFindProcess (unsigned pid /*= GetCurrentProcessId()*/) 09591 { 09592 $4 static PROCESSENTRY32 info = { sizeof (info) }; 09593 $ if (!pid) return &info; 09594 09595 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 09596 $ assert (sshot); if (!sshot) return NULL; //-V547 09597 09598 $ for (bool ok = !!Process32First (sshot, &info); ok; ok = !!Process32Next (sshot, &info)) 09599 if (info.th32ProcessID == pid) break; 09600 09601 $ CloseHandle (sshot); 09602 09603 $ return &info; 09604 } 09605 09606 //----------------------------------------------------------------------------------------------------------------- 09607 09608 bool _txGetCommandLine (wchar_t cmdLine[], size_t szCmdLine, unsigned pid /*= _getpid()*/) 09609 { 09610 $6 if (_TX_ARGUMENT_FAILED (cmdLine)) return false; 09611 $ if (_TX_ARGUMENT_FAILED (szCmdLine >= 2)) return false; //-V547 09612 09613 $ if (pid == (unsigned) _getpid()) 09614 { 09615 $ wcsncpy_s (cmdLine, szCmdLine, GetCommandLineW(), szCmdLine-1); 09616 $ return true; 09617 } 09618 09619 $ HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid); 09620 if (!proc) {$ return false; } 09621 09622 $ Win32::PROCESS_BASIC_INFORMATION pbi = {}; 09623 $ bool ok = (Win32::NtQueryInformationProcess (proc, 0 /*ProcessBasicInformation*/, &pbi, sizeof (pbi), NULL) == 0); 09624 09625 // Should use ReadProcessMemory() because the info is actually in another address space 09626 09627 $ Win32::PEB peb = {}; 09628 if (ok && pbi.PebBaseAddress) {$ ok &= !!ReadProcessMemory (proc, pbi.PebBaseAddress, &peb, sizeof (peb), NULL); } 09629 09630 $ Win32::RTL_USER_PROCESS_PARAMETERS params = {}; 09631 if (ok && peb.ProcessParameters) {$ ok &= !!ReadProcessMemory (proc, peb.ProcessParameters, ¶ms, sizeof (params), NULL); } 09632 09633 $ *cmdLine = 0; 09634 if (ok && params.CommandLine.Buffer) {$ ok &= !!ReadProcessMemory (proc, params.CommandLine.Buffer, cmdLine, //-V106 09635 MIN (params.CommandLine.Length + 2, (int) (szCmdLine * sizeof (*cmdLine)) - 2), //-V202 09636 NULL); } 09637 $ CloseHandle (proc) asserted; 09638 09639 $ return ok; 09640 } 09641 09642 //----------------------------------------------------------------------------------------------------------------- 09643 09644 #define RVA_(type, module, addr) ( (type) ((uintptr_t) (module) + (uintptr_t) (addr)) ) 09645 09646 IMAGE_NT_HEADERS* _txGetNtHeaders (HMODULE module /*= GetModuleHandle (NULL)*/) 09647 { 09648 $4 assert (module); 09649 09650 $ IMAGE_DOS_HEADER* dosHdr = RVA_ (IMAGE_DOS_HEADER*, module, 0); 09651 $ IMAGE_NT_HEADERS* ntHdr = RVA_ (IMAGE_NT_HEADERS*, module, dosHdr->e_lfanew); 09652 09653 $ return (dosHdr->e_magic == IMAGE_DOS_SIGNATURE && 09654 ntHdr->Signature == IMAGE_NT_SIGNATURE)? ntHdr : NULL; 09655 } 09656 09657 //----------------------------------------------------------------------------------------------------------------- 09658 09659 // TXLib continues to hack the reality to make your life better, sweeter and easier 09660 09661 uintptr_t _txSetProcAddress (const char funcName[], uintptr_t newFunc, const char dllName[] /*= NULL*/, int useHotPatching /*= false*/, 09662 HMODULE module /*= NULL*/, bool debug /*= false*/) 09663 { 09664 $4 if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p):\n", funcName, (void*) newFunc, dllName, (void*) module); 09665 09666 $ if (_TX_ARGUMENT_FAILED (funcName)) return 0; 09667 $ if (_TX_ARGUMENT_FAILED (newFunc)) return 0; 09668 09669 $ if (!module) module = GetModuleHandle (NULL); 09670 $ if (!module) return 0; 09671 09672 $ HMODULE dll = (dllName)? GetModuleHandle (dllName) : NULL; 09673 $ PROC oldFunc = (dll)? GetProcAddress (dll, funcName) : NULL; 09674 09675 $ if (useHotPatching && oldFunc) 09676 { 09677 $ const size_t jmpSz = 1 + sizeof (DWORD); // sizeof (JMP rel instruction) 09678 09679 $ DWORD oldRights = 0; 09680 $ if (!VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, PAGE_EXECUTE_READWRITE, &oldRights)) return 0; 09681 09682 // Overwrite oldFunc prolog with JMP trampoline to newFunc. 09683 // Calling oldFunc from any location will lead to newFunc call anyway. 09684 09685 $ *(BYTE*) ((char*)(uintptr_t) oldFunc + 0) = 0xE9; // JMP rel 09686 $ *(DWORD*) ((char*)(uintptr_t) oldFunc + 1) = ((char*)(uintptr_t) newFunc - (char*)(uintptr_t) oldFunc - jmpSz) & 0xFFFFFFFF; //-V206 //-V112 //-V2007 //-V104 //-V103 09687 09688 $ FlushInstructionCache (GetCurrentProcess(), (void*)(uintptr_t) oldFunc, jmpSz); 09689 09690 $ VirtualProtect ((void*)(uintptr_t) oldFunc, jmpSz, oldRights, &oldRights); 09691 09692 $ return (uintptr_t) oldFunc; 09693 } 09694 09695 // For PE structure and Import Table format, e.g. see https://books.google.ru/books?id=ifQPC86G66sC&pg=PA255 09696 // and below through Figure 5-5, and/or http://www.brokenthorn.com/Resources/OSDevPE.html. 09697 09698 $ IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders (module); 09699 if (!ntHdr || (ntHdr ->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)) {$ return 0; } 09700 09701 $ DWORD impOffset = ntHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 09702 $ IMAGE_IMPORT_DESCRIPTOR* desc = RVA_ (IMAGE_IMPORT_DESCRIPTOR*, module, impOffset); 09703 09704 $ if (desc == (IMAGE_IMPORT_DESCRIPTOR*) ntHdr) return 0; //-V1027 09705 09706 $ IMAGE_THUNK_DATA* thunk0 = NULL, * thunk1 = NULL; 09707 $ char* impDll = NULL; 09708 $ char* impName = NULL; 09709 $ void** impPtr = NULL; 09710 $ bool found = false; 09711 09712 for (; desc->Name; desc++) 09713 { 09714 $ impDll = RVA_ (char*, module, desc->Name); 09715 $ if (dllName && _stricmp (impDll, dllName) != 0) continue; 09716 09717 $ for (thunk0 = RVA_ (IMAGE_THUNK_DATA*, module, desc->OriginalFirstThunk), 09718 thunk1 = RVA_ (IMAGE_THUNK_DATA*, module, desc->FirstThunk); 09719 09720 thunk0 && thunk1 && thunk1->u1.Function; 09721 09722 thunk0++, 09723 thunk1++) 09724 { 09725 impName = (char*) RVA_ (IMAGE_IMPORT_BY_NAME*, module, thunk0->u1.AddressOfData) -> Name; 09726 impPtr = (void**)(uintptr_t) &thunk1->u1.Function; // Should change it, so this is ptr 09727 09728 if (IsBadReadPtr (impName, sizeof (impName))) impName = NULL; 09729 09730 if (debug) txOutputDebugPrintf ("[0x%p] %s!%s\n", *impPtr, impDll, impName); 09731 09732 if ((oldFunc && (uintptr_t) oldFunc == (uintptr_t) *impPtr) || 09733 (impName && _stricmp (funcName, impName) == 0)) //-V560 09734 { 09735 found = true; 09736 break; 09737 } 09738 } 09739 09740 $ if (found) break; 09741 } 09742 09743 if (debug) txOutputDebugPrintf ("_txSetProcAddress (%s, 0x%p, %s, 0x%p): %s\n\n", 09744 funcName, (void*) newFunc, dllName, (void*) module, (found? "FOUND" : "NOT found")); 09745 $ if (!found) return 0; 09746 09747 $ DWORD rights = PAGE_READWRITE; 09748 $ if (!VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights)) return 0; 09749 09750 $ *(uintptr_t*) impPtr = newFunc; 09751 09752 $ VirtualProtect (impPtr, sizeof (*impPtr), rights, &rights); 09753 09754 $ return (uintptr_t) oldFunc; 09755 } 09756 09757 #undef RVA_ 09758 09759 //----------------------------------------------------------------------------------------------------------------- 09760 09761 bool _txInDll() 09762 { 09763 $4 MODULEENTRY32 mod = { sizeof (mod) }; 09764 09765 $ HANDLE sshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); 09766 $ assert (sshot); if (!sshot) return false; //-V547 09767 09768 $ bool inDll = false; 09769 09770 $ for (bool ok = !!Module32First (sshot, &mod); ok; ok = !!Module32Next (sshot, &mod)) 09771 { 09772 $ if (!mod.modBaseAddr) continue; 09773 09774 $ IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders ((HMODULE) mod.modBaseAddr); 09775 09776 $ inDll = ntHdr && ((ntHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0); 09777 09778 $ if (In (std::nomeow, (BYTE*)(uintptr_t)_txInDll, mod.modBaseAddr, mod.modBaseAddr + mod.modBaseSize)) //-V104 09779 {$ break; } 09780 } 09781 09782 $ CloseHandle (sshot); 09783 $ return inDll; 09784 } 09785 09786 //----------------------------------------------------------------------------------------------------------------- 09787 09788 bool _txIsConsoleSubsystem() 09789 { 09790 $4 IMAGE_NT_HEADERS* ntHdr = _txGetNtHeaders(); 09791 09792 $ return ntHdr && 09793 ntHdr ->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC && 09794 09795 (ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI || 09796 ntHdr ->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_POSIX_CUI); 09797 } 09798 09799 //----------------------------------------------------------------------------------------------------------------- 09800 09801 bool _txIsBadReadPtr (const void* address) 09802 { 09803 MEMORY_BASIC_INFORMATION mbi = {}; 09804 if (!VirtualQuery (address, &mbi, sizeof (mbi))) return true; 09805 09806 if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) return true; // Guard page -> bad ptr 09807 09808 DWORD readRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY; 09809 09810 return !(mbi.Protect & readRights); 09811 } 09812 09813 //----------------------------------------------------------------------------------------------------------------- 09814 09815 void _txActivateWindow (HWND wnd, unsigned mode) 09816 { 09817 $1 EnableWindow (wnd, true); 09818 09819 $ if (mode & 0x20) 09820 { 09821 $ ShowWindow (wnd, SW_MINIMIZE); 09822 $ ShowWindow (wnd, SW_RESTORE); 09823 } 09824 09825 $ if (mode & 0x10) 09826 { 09827 $ int focus = GetWindowThreadProcessId (GetForegroundWindow(), 0); 09828 09829 $ AttachThreadInput (GetCurrentThreadId(), focus, true); 09830 09831 $ ShowWindow (wnd, SW_SHOW); 09832 09833 $ AllowSetForegroundWindow (ASFW_ANY); 09834 $ LockSetForegroundWindow (LSFW_UNLOCK); 09835 $ keybd_event ((byte) VK_LMENU, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); // https://stackoverflow.com/questions/10740346 09836 $ SetForegroundWindow (wnd); 09837 09838 $ _txWaitFor (GetForegroundWindow() == wnd, 10*_TX_TIMEOUT); 09839 09840 $ AttachThreadInput (GetCurrentThreadId(), focus, false); 09841 } 09842 09843 $ if (mode & 0x08) 09844 { 09845 $ SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); 09846 } 09847 09848 $ if (mode & 0x04) 09849 { 09850 $ SetWindowPos (wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS); 09851 } 09852 09853 $ if (mode & 0x02) 09854 { 09855 $ UpdateWindow (wnd); 09856 } 09857 09858 $ if (mode & 0x01) 09859 { 09860 $ RECT r = {}; 09861 $ GetWindowRect (wnd, &r); 09862 $ mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, r.left, r.top, 0, 0); 09863 $ Sleep (100); 09864 $ mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP, r.left, r.top, 0, 0); 09865 $ Sleep (100); 09866 } 09867 } 09868 09869 #endif // TX_COMPILED 09870 09871 //} 09872 //----------------------------------------------------------------------------------------------------------------- 09873 09875 //} 09876 //================================================================================================================= 09877 09878 //================================================================================================================= 09879 //{ Internal TXLib window functions (_txCanvas...) 09881 //================================================================================================================= 09882 09883 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 09884 09885 unsigned WINAPI _txCanvas_ThreadProc (void* data) 09886 { 09887 #define SetClassLong_ SetClassLongPtr 09888 #define GCL_HICON_ GCLP_HICON 09889 #define GCL_HICONSM_ GCLP_HICONSM 09890 #define GCL_HCURSOR_ GCLP_HCURSOR 09891 09892 $8 _txCanvas_ThreadId = GetCurrentThreadId(); 09893 09894 $ if (_TX_ARGUMENT_FAILED (data)) return false; //-V601 09895 09896 $ unsigned long stackSize = _TX_STACKSIZE; 09897 $ _TX_CALL (Win32::SetThreadStackGuarantee, (&stackSize)); 09898 09899 $ HWND wnd = _txCanvas_CreateWindow ((SIZE*) data); 09900 $ if (!txWindow()) return TX_DEBUG_ERROR ("\a" "Cannot create canvas!"), 0; 09901 09902 $ HICON icon32 = LoadIcon (NULL, "_TX_ICON"); 09903 $ HICON icon16 = LoadIcon (NULL, "_TX_ICONSM"); 09904 $ HCURSOR cursor = LoadCursor (NULL, "_TX_CURSOR"); 09905 $ HMENU menu = LoadMenu (NULL, "_TX_MENU"); 09906 $ HACCEL accel = LoadAccelerators (NULL, "_TX_ACCELERATORS"); 09907 09908 $ SetClassLong_ (wnd, GCL_HICON_, (LONG_PTR) (icon32? icon32 : _txCreateTXIcon (32))); //-V107 //-V112 09909 $ SetClassLong_ (wnd, GCL_HICONSM_, (LONG_PTR) (icon16? icon16 : _txCreateTXIcon (16))); //-V107 09910 $ SetClassLong_ (wnd, GCL_HCURSOR_, (LONG_PTR) (cursor? cursor : LoadCursor (NULL, IDC_ARROW))); //-V107 09911 09912 if (menu) {$ SetMenu (wnd, menu); DrawMenuBar (wnd); } 09913 09914 $ Win32::GdiSetBatchLimit (1); 09915 09916 _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STARTED: " _TX_MODULE "\n")); 09917 09918 $ _txActivateWindow (wnd, 0x20); 09919 09920 $ ShowWindow (wnd, SW_SHOW); 09921 $ UpdateWindow (wnd); 09922 09923 $ _txRunning = true; 09924 09925 $ MSG msg = {}; 09926 $ while (GetMessage (&msg, NULL, 0, 0)) 09927 { 09928 if (!msg.hwnd) {$ continue; } 09929 09930 if (accel && TranslateAccelerator (wnd, accel, &msg)) {$ continue; } 09931 09932 $ TranslateMessage (&msg); 09933 $ DispatchMessage (&msg); 09934 09935 $ Sleep (0); 09936 } 09937 09938 $ if (icon16) DestroyIcon (icon16); // If Explorer is displaying Tray Notification, these 09939 $ if (icon32) DestroyIcon (icon32); // calls will possibly fail, and we'll get resource leak. 09940 09941 $ LeaveCriticalSection (&_txCanvas_LockBackBuf); 09942 09943 _TX_ON_DEBUG (OutputDebugString (_TX_VERSION " - STOPPED: " _TX_MODULE "\n")); 09944 09945 $ if (_txWatchdogTimeout >= 0) 09946 {$ Win32::_beginthread (_txWatchdogTerminator, 0, &_txWatchdogTimeout); } 09947 09948 $ if (_txRunning && _txMain) // Main window is destroyed but main() is still running. 09949 { // No chances for good termination, so use exit(). 09950 $ _txCleanup(); 09951 $ ::exit ((int) msg.wParam); //-V202 //-V2509 //-V2014 09952 } 09953 09954 $ _txCanvas_ThreadId = 0; 09955 $ return true; //-V601 09956 09957 #undef SetClassLong 09958 #undef GCL_HICON_ 09959 #undef GCL_HICONSM_ 09960 #undef GCL_HCURSOR_ 09961 } 09962 09963 //----------------------------------------------------------------------------------------------------------------- 09964 09965 HWND _txCanvas_CreateWindow (const SIZE* sizePtr) 09966 { 09967 $8 if (_TX_ARGUMENT_FAILED (sizePtr)) return NULL; 09968 09969 $ bool centered = false; 09970 if (sizePtr->cx < 0 && sizePtr->cy < 0) {$ centered = true; } 09971 09972 $ SIZE screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; 09973 $ RECT rect = { 0, 0, abs (sizePtr->cx), abs (sizePtr->cy) }; AdjustWindowRect (&rect, _txWindowStyle, false); 09974 $ SIZE size = { rect.right - rect.left, rect.bottom - rect.top }; 09975 $ RECT conPos = {}; 09976 09977 $ HWND console = _TX_CALL (Win32::GetConsoleWindow, ()); 09978 if (console) {$ GetWindowRect (console, &conPos); } 09979 09980 $ const char* wndClass = txRegisterClass ("MAIN", _txCanvas_WndProc, CS_HREDRAW | CS_VREDRAW | CS_OWNDC, BLACK_BRUSH, 0); 09981 $ if (!wndClass) return (HWND) NULL; 09982 09983 $ HWND wnd = CreateWindowEx (WS_EX_APPWINDOW, wndClass, txGetModuleFileName (false), _txWindowStyle | WS_CLIPCHILDREN, 09984 (centered)? screen.cx/2 - size.cx/2 : (console)? conPos.left : CW_USEDEFAULT, 09985 (centered)? screen.cy/2 - size.cy/2 : (console)? conPos.top : CW_USEDEFAULT, 09986 size.cx, size.cy, NULL, NULL, NULL, NULL); 09987 $ if (!wnd || !txWindow()) 09988 {$ return TX_DEBUG_ERROR ("Cannot create canvas: CreateWindowEx() failed"), (HWND) NULL; } 09989 09990 $ HMENU menu = GetSystemMenu (txWindow(), false); 09991 if (!menu) {$ return txWindow(); } 09992 09993 $ AppendMenu (menu, MF_SEPARATOR, 0, NULL) asserted; 09994 $ AppendMenu (menu, MF_STRING, _TX_IDM_CONSOLE, "Show &Console") asserted; 09995 $ AppendMenu (menu, MF_STRING, _TX_IDM_ABOUT, "&About...") asserted; 09996 09997 $ return txWindow(); 09998 } 09999 10000 //----------------------------------------------------------------------------------------------------------------- 10001 10002 const char* txRegisterClass (const char classId[], WNDPROC wndProc, unsigned style, int backBrush, int wndExtra) 10003 { 10004 $8 assert (classId); 10005 $ assert (wndProc); 10006 10007 $ static char name[_TX_BUFSIZE] = ""; 10008 $ _tx_snprintf_s (name, sizeof (name) - 1, "/*---[TXLib]-[%s]------------ " 10009 _TX_VERSION " " __FILE__ " WndClass %08lX " 10010 "-------------[%s]-[TXLib]---*/", 10011 classId, (unsigned long) GetTickCount(), classId); 10012 $ WNDCLASS wc = { sizeof (wc) }; 10013 10014 $ wc.lpszClassName = name; 10015 $ wc.lpfnWndProc = wndProc; 10016 $ wc.style = style; 10017 $ wc.cbWndExtra = (wndExtra + 1) * (int) sizeof (long); 10018 10019 $ wc.hCursor = LoadCursor (NULL, IDC_ARROW); 10020 $ wc.hbrBackground = (HBRUSH) Win32::GetStockObject (backBrush); 10021 10022 $ ATOM atom = RegisterClass (&wc); 10023 if (!atom) {$ TX_DEBUG_ERROR ("RegisterClass (\"%s\") failed", name); return 0; } 10024 10025 $ return (const char*)(uintptr_t) atom; 10026 } 10027 10028 //----------------------------------------------------------------------------------------------------------------- 10029 10030 int _txCanvas_SetRefreshLock (int count) 10031 { 10032 $8 int oldCount = _txCanvas_RefreshLock; 10033 10034 $ _txCanvas_RefreshLock = count; 10035 10036 $ HWND wnd = txWindow(); 10037 10038 $ if ((_txCanvas_RefreshLock <= 0 || oldCount <= 0) && wnd) 10039 {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); } 10040 10041 $ return oldCount; 10042 } 10043 10044 //----------------------------------------------------------------------------------------------------------------- 10045 10046 HICON _txCreateTXIcon (int size) 10047 { 10048 $8 if (_TX_ARGUMENT_FAILED (size == 32 || size == 16)) return NULL; //-V112 //-V560 10049 10050 $ const unsigned char image32 [32*32+1] = 10051 "00000000000000000000000000000000""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""0F0000000000000000000000000000F0""0F0000000000000000000000000000F0" 10052 "0F0000000000000099999999999900F0""0F0000000000000090300333330900F0""0F0000000990000090000000000900F0""0F00000099990000900BB000000900F0" 10053 "0F0000039999000090B00090900900F0""0F0000009999000090B00999990900F0""0F00000009903799900BB090900900F0""0F000000009BB70090000010000900F0" 10054 "0F0000000B90000090000000000900F0""0F000000B0B0000099999999999900F0""0F00007B30B0000090000000000000F0""0F00007300B0000090000000000000F0" 10055 "0F00000000B3000090000000000000F0""0F0000000B0B000090000000000000F0""0F000000B303B00090000000000000F0""0F000003B000B00090000000000000F0" 10056 "0F00003B00003B0090000000000000F0""0F0000300000030090000000000000F0""0F0000000448888888888844000000F0""0F00004886E6E6E60E66E6EEEE4400F0" 10057 "0F4488866E0E60E00660E06E66EEE4F0""0F868806E06E06E666E66E00E06EE6F0""0F08606E66E0066000E006E66E00E6F0""0F8666E006600E00006600E006E00EF0" 10058 "0F000E066888888888888888606660F0""0F66EEE6EE000E00000E00086EEEE6F0""0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0""00000000000000000000000000000000"; 10059 10060 $ const unsigned char image16 [16*16+1] = 10061 "0000000000000000""0000000999999990""0009000900000090""0099900909973090""0059700909009390""0009799909973090""0099000900000090""0959330999999990" 10062 "0709500900000000""0095930900000000""0090393900000000""0790073900000000""0900000900000000""000EE6E6E6E6E000""0EE6E6E6E6E6EEE0""0000000000000000"; 10063 10064 $ const COLORREF pal['F'-'0'+1] = { 0x000000, 0x002b2b, 0x555500, 0x005555, 0x808000, 0x008080, 0xaaaa00, 0x00aaaa, 0xd5d500, 0x00d5d5, 0,0,0,0,0,0,0, 10065 0xffff00, 0x00ffff, 0xffffaa, 0xaaffff, 0xd5d500, 0xffffff }; 10066 10067 $ const unsigned char* image = (size == 32)? image32 : image16; //-V112 10068 10069 $ POINT sz = { size, size }; 10070 $ HDC dcMask = _txBuffer_Create (txWindow(), &sz); assert (dcMask); 10071 $ HDC dcColor = _txBuffer_Create (txWindow(), &sz); assert (dcColor); 10072 10073 $ for (int i = 0; i < size*size; i++) 10074 { 10075 assert (In (std::nomeow, image[i], '0', '9') || 10076 In (std::nomeow, image[i], 'A', 'F')); 10077 10078 Win32::SetPixel (dcColor, i % size, i / size, pal [image[i] - '0']); 10079 } 10080 10081 $ ICONINFO info = { true, 0, 0, (HBITMAP) Win32::GetCurrentObject (dcMask, OBJ_BITMAP), 10082 (HBITMAP) Win32::GetCurrentObject (dcColor, OBJ_BITMAP) }; 10083 10084 $ HICON icon = CreateIconIndirect (&info); 10085 $ assert (icon); 10086 10087 $ _txBuffer_Delete (&dcMask) asserted; 10088 $ _txBuffer_Delete (&dcColor) asserted; 10089 10090 $ return icon; 10091 } 10092 10093 #endif // TX_COMPILED 10094 10095 //----------------------------------------------------------------------------------------------------------------- 10096 10097 inline bool _txCanvas_OK() 10098 { 10099 return _txCanvas_ThreadId && 10100 _txCanvas_Window && 10101 _txCanvas_BackBuf[0] && 10102 _txCanvas_BackBuf[1] && 10103 _txCanvas_Pixels; 10104 } 10105 10106 //} 10107 //================================================================================================================= 10108 10109 //================================================================================================================= 10110 //{ Main window event handlers (_txCanvas_On...) 10112 //================================================================================================================= 10114 10115 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10116 10117 LRESULT CALLBACK _txCanvas_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) 10118 { 10119 #if defined (_TX_ALLOW_TRACE) 10120 10121 int inTX = _txLoc::Cur.inTX++; 10122 10123 if (_txLoc::Cur.trace) _txTrace (__FILE__, __LINE__, __TX_FUNCTION__, "%*s" "0x%X <- 0x%04X (0x%08X, 0x%08lX)", 10124 2 * (_txLoc::Cur.inTX - 1), "", wnd, msg, wpar, lpar); 10125 _txLoc::Cur.inTX = inTX; 10126 10127 #endif 10128 10129 $8 if (msg == WM_KEYDOWN && wpar == VK_F12 && 10130 GetKeyState (VK_SHIFT) && GetKeyState (VK_CONTROL) && GetKeyState (VK_MENU)) 10131 { 10132 $ _txCanvas_OnCmdABOUT (wnd, wpar); 10133 $ return DefWindowProc (wnd, msg, wpar, lpar); 10134 } 10135 10136 WNDPROC altWndProc = _txAltWndProc; // Cache to prevent change from main thread 10137 if (altWndProc) 10138 { 10139 $ LRESULT res = altWndProc (wnd, msg, wpar, lpar); 10140 $ if (res) return res; 10141 } 10142 10143 static bool bkErased = false; 10144 10145 switch (msg) 10146 { 10147 case WM_CREATE: {$ _txCanvas_OnCREATE (wnd); return 0; } 10148 10149 case WM_CLOSE: {$ if (_txCanvas_OnCLOSE (wnd)) break; else return 0; } 10150 case WM_DESTROY: {$ _txCanvas_OnDESTROY (wnd); return 0; } 10151 10152 case WM_ERASEBKGND: {$ if (!bkErased) { bkErased = true; break; } else return 1; } 10153 case WM_SIZE: {$ bkErased = false; break; } 10154 10155 case WM_PAINT: {$ _txCanvas_OnPAINT (wnd); return 0; } 10156 10157 case WM_TIMER: {$ _txCanvas_OnTIMER (wnd, wpar); return 0; } 10158 10159 case WM_KEYUP: {$ if (_txCanvas_OnKEY (wnd, wpar, lpar, false)) return 0; else break; } 10160 case WM_KEYDOWN: {$ if (_txCanvas_OnKEY (wnd, wpar, lpar, true)) return 0; else break; } 10161 case WM_CHAR: {$ if (_txCanvas_OnCHAR (wnd, wpar, lpar)) return 0; else break; } 10162 10163 case WM_LBUTTONUP: 10164 case WM_LBUTTONDOWN: 10165 case WM_RBUTTONUP: 10166 case WM_RBUTTONDOWN: 10167 case WM_MBUTTONUP: 10168 case WM_MBUTTONDOWN: 10169 case WM_MOUSEMOVE: {$ _txCanvas_OnMOUSEMOVE (wnd, wpar, lpar); return 0; } 10170 10171 case WM_MOUSELEAVE: {$ _txCanvas_OnMOUSELEAVE (wnd); return 0; } 10172 10173 case _TX_WM_CREATEWND: {$ _txCanvas_OnCREATEWND (wnd, wpar, lpar); return 0; } 10174 case _TX_WM_DESTROYWND: {$ _txCanvas_OnDESTROYWND (wnd, wpar, lpar); return 0; } 10175 10176 case WM_NULL: {$ return 0; } 10177 10178 default: break; //-V2522 10179 } 10180 10181 if (msg == WM_SYSCOMMAND) switch (wpar) 10182 { 10183 case _TX_IDM_ABOUT: {$ _txCanvas_OnCmdABOUT (wnd, wpar); return 0; } 10184 case _TX_IDM_CONSOLE: {$ _txCanvas_OnCmdCONSOLE (wnd, wpar); return 0; } 10185 10186 default: break; //-V2522 10187 } 10188 10189 $ return DefWindowProc (wnd, msg, wpar, lpar); 10190 } 10191 10192 //----------------------------------------------------------------------------------------------------------------- 10193 10194 bool _txCanvas_OnCREATE (HWND wnd) 10195 { 10196 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10197 10198 $ _txCanvas_BackBuf[0] = _txBuffer_Create (wnd, NULL, NULL, &_txCanvas_Pixels); assert (_txCanvas_BackBuf[0]); 10199 $ _txCanvas_BackBuf[1] = _txBuffer_Create (wnd, NULL, NULL, NULL); assert (_txCanvas_BackBuf[1]); 10200 10201 $ if (!SetTimer (wnd, _txCanvas_RefreshTimer, _txWindowUpdateInterval, NULL)) _txCanvas_RefreshTimer = 0; 10202 $ assert (_txCanvas_RefreshTimer); 10203 10204 $ _txCanvas_UserDCs = new ::std::vector <HDC>; 10205 10206 $ _txCanvas_Window = wnd; 10207 10208 $ txSetDefaults(); 10209 10210 $ return true; 10211 } 10212 10213 //----------------------------------------------------------------------------------------------------------------- 10214 10215 bool _txCanvas_OnDESTROY (HWND wnd) 10216 { 10217 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10218 10219 // Инициируем остановку цикла сообщений 10220 10221 $ PostQuitMessage (_txRunning? WM_DESTROY : EXIT_SUCCESS); 10222 10223 $ if (!_txCanvas_Window) return false; 10224 10225 // Indicate that we are about to manually terminate 10226 10227 $ _txExit = true; 10228 10229 // Lock GDI resources 10230 10231 $ bool locked = false; 10232 $ _txWaitFor ((locked = txLock (false), locked), _TX_TIMEOUT); 10233 $ if (!locked) TX_DEBUG_ERROR ("Cannot lock GDI to free resources"); 10234 10235 // Освобождаем пользовательские ресурсы 10236 10237 $ if (_txCanvas_UserDCs && !_txCanvas_UserDCs->empty()) 10238 { 10239 $ txNotifyIcon (NIIF_ERROR, NULL, "Вы забыли освободить %d HDC.", (int) _txCanvas_UserDCs->size()); //-V202 10240 $ Sleep (_TX_TIMEOUT); 10241 10242 $ for (size_t i = 0; i < _txCanvas_UserDCs->size(); i++) _txBuffer_Delete (&_txCanvas_UserDCs->at (i)); 10243 $ _txCanvas_UserDCs->clear(); 10244 } 10245 10246 // Освобождаем ресурсы, связанные с окном 10247 10248 $ if (_txCanvas_RefreshTimer) KillTimer (wnd, _txCanvas_RefreshTimer) asserted; 10249 10250 $ if (_txCanvas_BackBuf[1]) _txBuffer_Delete (&_txCanvas_BackBuf[1]) asserted; 10251 $ if (_txCanvas_BackBuf[0]) _txBuffer_Delete (&_txCanvas_BackBuf[0]) asserted; 10252 $ _txCanvas_Pixels = NULL; 10253 10254 $ txUnlock(); 10255 10256 // Indicate that we are destroyed 10257 10258 $ _txCanvas_Window = NULL; 10259 10260 $ return true; 10261 } 10262 10263 //----------------------------------------------------------------------------------------------------------------- 10264 10265 bool _txCanvas_OnCLOSE (HWND wnd) //-V2009 //-V2558 10266 { 10267 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10268 $ if (!_txCanvas_OK()) return false; 10269 10270 $ if (_txMain && _txRunning && 10271 txMessageBox ("Функция main() не завершена. Программа все еще работает. Прервать аварийно?\n\n" 10272 "Лучше подождать, когда main() завершится - это отображается в заголовке окна.", 10273 txGetModuleFileName (false), MB_YESNOCANCEL | MB_ICONSTOP) != IDYES) return false; 10274 $ return true; 10275 } 10276 10277 //----------------------------------------------------------------------------------------------------------------- 10278 10279 bool _txCanvas_OnTIMER (HWND wnd, WPARAM) 10280 { 10281 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10282 10283 $ if (_txCanvas_RefreshLock > 0 || !_txRunning) return false; 10284 10285 $ InvalidateRect (wnd, NULL, false) asserted; 10286 $ UpdateWindow (wnd) asserted; 10287 10288 $ return true; 10289 } 10290 10291 //----------------------------------------------------------------------------------------------------------------- 10292 10293 bool _txCanvas_OnPAINT (HWND wnd) 10294 { 10295 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10296 $ if (!_txCanvas_OK()) return false; 10297 10298 $ bool forceRedraw = GetAsyncKeyState (VK_MENU) && GetAsyncKeyState (VK_CONTROL) && 10299 GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_SNAPSHOT); 10300 10301 $ PAINTSTRUCT ps = {}; 10302 $ HDC wndDc = BeginPaint (wnd, &ps); 10303 $ if (!wndDc) return false; 10304 10305 $ HDC dc0 = _txCanvas_BackBuf[0], 10306 dc1 = _txCanvas_BackBuf[1]; 10307 10308 $ RECT r = {}; 10309 $ GetClientRect (wnd, &r) asserted; 10310 $ POINT wndSize = { r.right - r.left, r.bottom - r.top }; 10311 10312 $ POINT dcSize = txGetExtent (dc1); 10313 10314 $ if ((_txCanvas_RefreshLock <= 0 || forceRedraw) && 10315 txLock (false)) 10316 { 10317 $ Win32::BitBlt (dc1, 0, 0, dcSize.x, dcSize.y, dc0, 0, 0, SRCCOPY); 10318 10319 $ if (_txConsole >= 0) 10320 {$ _txConsole_Draw (dc1); } 10321 10322 $ txUnlock(); 10323 } 10324 10325 // Magic 100500 value is used to completely block screen refresh. 10326 // Since no value can be 100500 or above, this condition is always true and the refresh cannot be blocked IRL. 10327 // Do not use 100501 because it may lead to errors on some compilers and possible may crash the compilers 10328 // themselves. 10329 // Yes guys, with all your software installed. :( 10330 10331 $ if (_txCanvas_RefreshLock != 100500) 10332 { 10333 if (_txSwapBuffers) 10334 { 10335 $ _txSwapBuffers (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY); 10336 } 10337 else if (dcSize.x == wndSize.x && dcSize.y == wndSize.y) 10338 { 10339 $ Win32::BitBlt (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, SRCCOPY); 10340 } 10341 else 10342 { 10343 $ Win32::SetStretchBltMode (wndDc, HALFTONE); 10344 $ Win32::StretchBlt (wndDc, 0, 0, wndSize.x, wndSize.y, dc1, 0, 0, dcSize.x, dcSize.y, SRCCOPY); 10345 } 10346 } 10347 10348 $ EndPaint (wnd, &ps) asserted; 10349 10350 $ return true; 10351 } 10352 10353 //----------------------------------------------------------------------------------------------------------------- 10354 10355 bool _txCanvas_OnCHAR (HWND, WPARAM ch, LPARAM info) 10356 { 10357 $8 INPUT_RECORD evt[2] = {}; 10358 10359 $ evt[0].EventType = KEY_EVENT; 10360 $ evt[0].Event.KeyEvent.bKeyDown = true; 10361 $ evt[0].Event.KeyEvent.wRepeatCount = 1; 10362 $ evt[0].Event.KeyEvent.uChar.AsciiChar = (char) (ch); 10363 $ evt[0].Event.KeyEvent.wVirtualScanCode = (WORD) (info >> 16); 10364 $ evt[0].Event.KeyEvent.wVirtualKeyCode = (WORD) MapVirtualKey ((WORD) (info >> 16), 3); // 3 == MAPVK_VSC_TO_VK_EX 10365 $ evt[0].Event.KeyEvent.dwControlKeyState = 0; 10366 10367 $ evt[1] = evt[0]; 10368 $ evt[1].Event.KeyEvent.bKeyDown = false; 10369 10370 $ DWORD written = 0; 10371 $ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), evt, 2, &written); 10372 10373 $ return true; 10374 } 10375 10376 //----------------------------------------------------------------------------------------------------------------- 10377 10378 bool _txCanvas_OnKEY (HWND, WPARAM vk, LPARAM info, bool down) 10379 { 10380 $8 INPUT_RECORD evt = {}; 10381 10382 $ evt.EventType = KEY_EVENT; 10383 $ evt.Event.KeyEvent.bKeyDown = down; 10384 $ evt.Event.KeyEvent.wRepeatCount = 1; 10385 $ evt.Event.KeyEvent.uChar.AsciiChar = (char) MapVirtualKey ((WORD) vk, 2); // 2 == MAPVK_VK_TO_CHAR 10386 $ evt.Event.KeyEvent.wVirtualScanCode = (WORD) (info >> 16); 10387 $ evt.Event.KeyEvent.wVirtualKeyCode = (WORD) vk; 10388 $ evt.Event.KeyEvent.dwControlKeyState = (DWORD) (info & (1 << (24-1)))? ENHANCED_KEY : 0; 10389 10390 $ if (evt.Event.KeyEvent.uChar.AsciiChar) return false; // Let TranslateMessage() and WM_CHAR do the job 10391 10392 $ DWORD written = 0; 10393 $ WriteConsoleInput (GetStdHandle (STD_INPUT_HANDLE), &evt, 1, &written); 10394 10395 $ return true; 10396 } 10397 10398 //----------------------------------------------------------------------------------------------------------------- 10399 10400 bool _txCanvas_OnMOUSEMOVE (HWND wnd, WPARAM buttons, LPARAM coords) 10401 { 10402 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10403 $ if (!_txCanvas_OK()) return false; 10404 10405 $ if (_txMousePos.x == -1 && _txMousePos.y == -1) 10406 { 10407 $ TRACKMOUSEEVENT track = { sizeof (track), TME_HOVER | TME_LEAVE, wnd, HOVER_DEFAULT }; 10408 $ TrackMouseEvent (&track); 10409 } 10410 10411 $ _txMousePos.x = LOWORD (coords); 10412 $ _txMousePos.y = HIWORD (coords); 10413 $ _txMouseButtons = (unsigned) buttons; //-V202 10414 10415 $ return true; 10416 } 10417 10418 //----------------------------------------------------------------------------------------------------------------- 10419 10420 bool _txCanvas_OnMOUSELEAVE (HWND) 10421 { 10422 $8 _txMousePos.x = -1; 10423 $ _txMousePos.y = -1; 10424 $ _txMouseButtons = 0; 10425 10426 $ return true; 10427 } 10428 10429 //----------------------------------------------------------------------------------------------------------------- 10430 10431 bool _txCanvas_OnCREATEWND (HWND, WPARAM, LPARAM lpar) 10432 { 10433 $8 if (_TX_ARGUMENT_FAILED (lpar)) return false; 10434 10435 $ const CREATESTRUCT* create = (CREATESTRUCT*) lpar; 10436 10437 $ HWND wnd = CreateWindowEx (create->dwExStyle, create->lpszClass, create->lpszName, create->style, 10438 create->x, create->y, create->cx, create->cy, 10439 create->hwndParent, create->hMenu, NULL, create->lpCreateParams); 10440 10441 $ *(HWND*) create->hInstance = wnd; 10442 10443 $ return true; 10444 } 10445 10446 //----------------------------------------------------------------------------------------------------------------- 10447 10448 bool _txCanvas_OnDESTROYWND (HWND, WPARAM, LPARAM lpar) 10449 { 10450 $8 if (_TX_ARGUMENT_FAILED (lpar)) return false; 10451 10452 $ DestroyWindow ((HWND) lpar); 10453 10454 $ return false; 10455 } 10456 10457 //----------------------------------------------------------------------------------------------------------------- 10458 10459 bool _txCanvas_OnCmdCONSOLE (HWND wnd, WPARAM cmd) 10460 { 10461 $8 if (_TX_ARGUMENT_FAILED (wnd)) return false; 10462 10463 $ HWND console = Win32::GetConsoleWindow(); 10464 $ if (!console) return false; 10465 10466 $ bool visible = !!IsWindowVisible (console); 10467 10468 $ ShowWindow (console, visible? SW_HIDE : SW_RESTORE); 10469 10470 $ visible = !!IsWindowVisible (console); 10471 $ CheckMenuItem (GetSystemMenu (wnd, false), (int) cmd, visible? MF_CHECKED : MF_UNCHECKED); //-V202 10472 10473 $ return true; 10474 } 10475 10476 //----------------------------------------------------------------------------------------------------------------- 10477 10478 bool _txCanvas_OnCmdABOUT (HWND, WPARAM) 10479 { 10480 $8 //{ Overriding the missing names, if the set is incomplete 10481 10482 #if defined (__MODULE) 10483 #define ABOUT_NAME_ __MODULE 10484 #else 10485 #define ABOUT_NAME_ "TXLib" 10486 #endif 10487 10488 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR) 10489 10490 #ifndef __MODULE 10491 #define __MODULE "TXLib" "\n" "#define __MODULE to set the name.\n" 10492 #endif 10493 10494 #ifndef __VERSION 10495 #define __VERSION "(0.000000000)." "\n" "#define __VERSION to set the string value.\n" 10496 #endif 10497 10498 #ifndef __DESCRIPTION 10499 #define __DESCRIPTION "(Да, мне лень задать описание)." "\n" "#define __DESCRIPTION to override project role.\n" 10500 #endif 10501 10502 #ifndef __AUTHOR 10503 #define __AUTHOR "(Непонятно кто)." "\n" "#define __AUTHOR to override this name." 10504 #endif 10505 10506 #endif 10507 //} 10508 10509 $ static char text[_TX_BUFSIZE] = ""; 10510 10511 $ _tx_snprintf_s (text, sizeof (text) - 1, 10512 10513 "Application:\n\n" 10514 10515 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR) 10516 __MODULE " version " __VERSION "\n" __DESCRIPTION "\n" "Copyright (c) " __AUTHOR "\n" 10517 #else 10518 "Здесь могла бы быть Ваша реклама :)\n" 10519 "#define __MODULE to \"your program name\" before including TXLib.h to use this billboard...\n" 10520 #endif 10521 10522 "\n" "%s", _txAppInfo()); 10523 10524 $ txMessageBox (text, "About " ABOUT_NAME_, MB_ICONINFORMATION); 10525 10526 // And a bit of HTTP-code in C++ function: 10527 10528 goto http; 10529 http://sizeof.livejournal.com 10530 10531 $ return true; 10532 10533 #undef ABOUT_NAME_ 10534 } 10535 10536 #endif // TX_COMPILED 10537 10539 //} 10540 //================================================================================================================= 10541 10542 //================================================================================================================= 10543 //{ Console-support functions (_txConsole...) 10545 //================================================================================================================= 10547 10548 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10549 10550 HWND _txConsole_Attach() 10551 { 10552 $1 HWND console = Win32::GetConsoleWindow(); 10553 10554 $ if (!console) 10555 { 10556 $ bool minimizeConsole = ((TX_CONSOLE_MODE) == SW_HIDE && !_txIsConsoleSubsystem()); 10557 10558 $ Win32::TEB* teb = (Win32::TEB*) NtCurrentTeb(); 10559 $ assert (teb); 10560 $ assert (teb->ProcessEnvironmentBlock); 10561 10562 $ Win32::RTL_USER_PROCESS_PARAMETERS* params = teb->ProcessEnvironmentBlock->ProcessParameters; 10563 $ assert (params); 10564 10565 $ if (minimizeConsole) // The fact that ShowWindow parameter of the program's console is taken from calling 10566 // process' STARTUPINFO, was researched from Windows XP sources. See SetUpConsoleInfo() 10567 // in windows\core\ntcon\client\dllinit.c. No one can miss stealing Windows sources. :( 10568 // Thank you Matt Pietrek, the author of "Undocumented Windows". Use the Source, Luke! 10569 { 10570 $ params->dwFlags |= STARTF_USESHOWWINDOW; 10571 $ params->wShowWindow = SW_MINIMIZE; 10572 } 10573 10574 $ AllocConsole(); 10575 $ console = Win32::GetConsoleWindow(); 10576 } 10577 10578 $ if (!console) return NULL; 10579 10580 $ txSetLocale(); // Устанавливаем русскую кодовую страницу для консоли Windows 10581 10582 $ _txConsole_SetUnicodeFont(); // Впечатлительным лучше сюда не смотреть. 10583 10584 $ if (!_txIsConsoleSubsystem()) 10585 {$ txReopenStdio(); } // Переоткрываем потоки ввода-вывода, если subsystem != console 10586 10587 $ return console; 10588 } 10589 10590 //----------------------------------------------------------------------------------------------------------------- 10591 10592 int txSetLocale (int codepage /*= _TX_CODEPAGE*/, 10593 const char locale[] /*= _TX_LOCALE*/, const wchar_t wLocale[] /*= _TX_WLOCALE*/) 10594 { 10595 $1 int oldPage = GetConsoleOutputCP(); 10596 10597 // Устанавливаем нужную кодовую страницу для консоли Windows 10598 10599 $ if (codepage) 10600 { 10601 $ SetConsoleCP (codepage); 10602 $ SetConsoleOutputCP (codepage); 10603 } 10604 10605 // Устанавливаем нужную кодовую страницу для стандартной библиотеки, иначе не будут работать Unicode-версии 10606 // функций (wprintf, ...). Если компилите с помощью gcc и собираетесь использовать L"unicode-строки" с определенным 10607 // языком, укажите опции в командной строке компилятора g++: -finput-charset=NNNN -fexec-charset=NNNN, где NNNN - 10608 // обозначение кодовой страницы (например, для русского языка - CP1251). 10609 10610 $ if (locale) 10611 { 10612 $ setlocale (LC_ALL, locale); 10613 $ setlocale (LC_NUMERIC, "C"); // Return to decimal point (3.14) instead of comma (3,14) in floating numbers 10614 } 10615 10616 #ifndef __CYGWIN__ 10617 10618 $ const bool wine = !!Win32::wine_get_version; // Linux::Wine v1.2.2+ compatibility. 10619 10620 $ if (wLocale && !wine) 10621 { 10622 $ _wsetlocale (LC_ALL, wLocale); 10623 $ _wsetlocale (LC_NUMERIC, L"C"); // L"C" (see above) 10624 } 10625 10626 #endif 10627 10628 (void) wLocale; 10629 10630 $ return oldPage; 10631 } 10632 10633 //----------------------------------------------------------------------------------------------------------------- 10634 10635 void txReopenStdio() 10636 { 10637 $1 // Переоткрываем заново <s>Америку</s> потоки ввода-вывода 10638 10639 $ fflush (stdout); 10640 $ fflush (stderr); 10641 10642 $ FILE* f = NULL; 10643 10644 #ifndef __CYGWIN__ 10645 10646 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_INPUT_HANDLE), _O_TEXT), "r"); assert (f); *stdin = *f; 10647 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_OUTPUT_HANDLE), _O_TEXT), "w"); assert (f); *stdout = *f; 10648 $ f = _fdopen (_open_osfhandle ((intptr_t) GetStdHandle (STD_ERROR_HANDLE), _O_TEXT), "w"); assert (f); *stderr = *f; 10649 10650 #else 10651 10652 $ f = _fdopen (STDIN_FILENO, "r"); assert (f); *stdin = *f; 10653 $ f = _fdopen (STDOUT_FILENO, "w"); assert (f); *stdout = *f; 10654 $ f = _fdopen (STDERR_FILENO, "w"); assert (f); *stderr = *f; 10655 10656 #endif 10657 10658 $ setvbuf (stdin, NULL, _IONBF, 0); 10659 $ setvbuf (stdout, NULL, _IONBF, 0); 10660 $ setvbuf (stderr, NULL, _IONBF, 0); 10661 10662 $ ::std::ios::sync_with_stdio(); 10663 } 10664 10665 //----------------------------------------------------------------------------------------------------------------- 10666 10667 inline bool _txConsole_OK() 10668 { 10669 return Win32::GetConsoleWindow() != NULL; 10670 } 10671 10672 //----------------------------------------------------------------------------------------------------------------- 10673 10674 bool _txConsole_Detach (bool activate) 10675 { 10676 $1 HWND console = Win32::GetConsoleWindow(); 10677 $ if (!console) return false; 10678 10679 $ EnableWindow (console, true); 10680 10681 $ if (activate) 10682 { 10683 $ if (!IsWindowVisible (console)) 10684 {$ ShowWindow (console, SW_MINIMIZE); } 10685 10686 $ _txActivateWindow (console, 0xFF); 10687 $ return true; 10688 } 10689 else 10690 { 10691 $ return !!FreeConsole(); 10692 } 10693 } 10694 10695 //----------------------------------------------------------------------------------------------------------------- 10696 10697 bool _txConsole_Draw (HDC dc) 10698 { 10699 $8 if (_TX_HDC_FAILED (dc)) return false; 10700 10701 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10702 10703 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 10704 $ BOOL ok = GetConsoleScreenBufferInfo (out, &con); 10705 $ if (!ok) return false; 10706 10707 $ POINT size = { con.srWindow.Right - con.srWindow.Left + 1, 10708 con.srWindow.Bottom - con.srWindow.Top + 1 }; 10709 10710 $ SIZE fontSz = { 12, 16 }; 10711 $ Win32::GetTextExtentPoint32 (dc, "W", 1, &fontSz) asserted; 10712 10713 $ COLORREF pal [16] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, 10714 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF }; 10715 10716 $ for (short y = 0; y < size.y; y++) 10717 { 10718 static char chr [_TX_BUFSIZE + 1] = ""; // [con.dwSize.X + 1]; maybe will be truncated 10719 static WORD atr [_TX_BUFSIZE + 1] = {}; // [con.dwSize.X + 1]; maybe will be truncated 10720 COORD coord = { (short) (con.srWindow.Left), (short) (y + con.srWindow.Top) }; 10721 DWORD read = 0; 10722 10723 if (!ReadConsoleOutputCharacter (out, chr, sizearr (chr) - 1, coord, &read)) continue; 10724 if (!ReadConsoleOutputAttribute (out, atr, sizearr (atr) - 1, coord, &read)) continue; 10725 10726 for (int x = 0, xEnd = size.x; x < size.x; x = xEnd) 10727 { 10728 Win32::SetTextColor (dc, pal [ atr[x] & 0x0F]); 10729 Win32::SetBkColor (dc, pal [(atr[x] >> 4) & 0x0F]); 10730 Win32::SetBkMode (dc, (atr[x] & 0xF0)? OPAQUE : TRANSPARENT); 10731 10732 for (xEnd = x+1; xEnd < size.x && atr[xEnd] == atr[x]; xEnd++) {;} 10733 10734 Win32::TextOut (dc, ROUND (fontSz.cx * (x + con.srWindow.Left)), 10735 ROUND (fontSz.cy * y), chr + x, xEnd - x) asserted; 10736 } 10737 } 10738 10739 $ Win32::SetTextColor (dc, pal [ con.wAttributes & 0x0F]); 10740 $ Win32::SetBkColor (dc, pal [(con.wAttributes >> 4) & 0x0F]); 10741 $ Win32::SetBkMode (dc, TRANSPARENT); 10742 10743 $ if (_txConsole_IsBlinking && 10744 In (std::nomeow, con.dwCursorPosition, con.srWindow) && 10745 GetTickCount() % _txCursorBlinkInterval*2 > _txCursorBlinkInterval && 10746 GetForegroundWindow() == txWindow()) 10747 { 10748 $ Win32::TextOut (dc, ROUND (fontSz.cx * (con.dwCursorPosition.X - con.srWindow.Left)), 10749 ROUND (fontSz.cy * (con.dwCursorPosition.Y - con.srWindow.Top)) + 1, 10750 "_", 1) asserted; 10751 } 10752 10753 $ return true; 10754 } 10755 10756 #endif // TX_COMPILED 10757 10758 //----------------------------------------------------------------------------------------------------------------- 10759 //{ Welcome to the Duck Side! Together we will rule the Bathroom! 10760 //----------------------------------------------------------------------------------------------------------------- 10761 10762 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10763 10764 bool _txConsole_SetUnicodeFont() 10765 { 10766 $ const bool wine = !!Win32::wine_get_version; // Linux::Wine v1.2.2+ compatibility. 10767 // Beer compatibility may be added in future versions... 10768 $ if (wine) // Минздрав РФ предупреждает: чрезмерное употребление wine 10769 { // вредит Вашему здоровью. 10770 $ Win32::GetNumberOfConsoleFonts = NULL; 10771 $ Win32::GetCurrentConsoleFont = NULL; 10772 $ Win32::SetConsoleFont = NULL; 10773 10774 $ return false; 10775 } 10776 10777 // Начиная с Висты все хорошо... 10778 10779 $1 if (Win32::GetCurrentConsoleFontEx && Win32::SetCurrentConsoleFontEx) 10780 { 10781 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10782 10783 $ Win32::CONSOLE_FONT_INFOEX info = { sizeof (info) }; 10784 $ if (!Win32::GetCurrentConsoleFontEx (out, false, &info)) return false; 10785 10786 $ info.FontFamily = 0x36; // Unicode fixed-pitch 10787 $ if (!*info.FaceName) info.dwFontSize.Y = (SHORT) (info.dwFontSize.Y + 2); // Terminal font is too small 10788 10789 $ if (wcsncmp (info.FaceName, L"Consolas", sizearr (info.FaceName)) != 0) // Consolas is allowed too 10790 {$ wcsncpy_s (info.FaceName, sizearr (info.FaceName), L"Lucida Console", sizearr (info.FaceName)); } 10791 10792 $ return !!Win32::SetCurrentConsoleFontEx (out, false, &info); 10793 } 10794 10795 // ...а до этого все не так сладко 10796 10797 $ const unsigned uniFont = 10; // The Internet and W2K sources know this magic number 10798 $ const unsigned uniSize = 20; // Size of the font desired, should be > max # of Raster Fonts //-V2551 10799 $ bool ok = true; 10800 10801 // Force Windows to use Unicode font by creating and run the console shortcut tuned to use that font. 10802 10803 $ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 10804 10805 $ unsigned fonts = _TX_CALL (Win32::GetNumberOfConsoleFonts, ()); 10806 $ if (fonts && fonts <= uniFont) 10807 { 10808 $ HRESULT init = Win32::CoInitialize (NULL); 10809 $ size_t sz = 0; 10810 10811 $ char link [MAX_PATH] = ""; 10812 $ getenv_s (&sz, link, sizeof (link) - 1, "TEMP"); 10813 $ strncat_s (link, sizeof (link), "\\~txLink.lnk", sizeof (link) - 1); 10814 10815 $ char comspec [MAX_PATH] = ""; 10816 $ getenv_s (&sz, comspec, sizeof (comspec), "COMSPEC"); 10817 10818 $ (void) _unlink (link); 10819 10820 $ _txCreateShortcut (link, comspec, "/c exit", NULL, NULL, SW_SHOWMINNOACTIVE, NULL, 0, uniSize) asserted; 10821 10822 $ ok = (Win32::ShellExecuteA (NULL, NULL, link, NULL, NULL, SW_SHOWMINNOACTIVE) > (void*)32); // Sic! //-V112 //-V566 10823 if (ok) {$ _txWaitFor (FindWindow (NULL, "~txLink"), _TX_TIMEOUT); } 10824 10825 $ (void) _unlink (link); 10826 10827 $ if (init == S_OK) Win32::CoUninitialize(); 10828 } 10829 10830 // If Unicode font is not already set, do set it. 10831 10832 $ Win32::CONSOLE_FONT_INFO cur = {}; 10833 $ _TX_CALL (Win32::GetCurrentConsoleFont, (out, false, &cur)); 10834 10835 $ ok &= (cur.nFont >= uniFont); 10836 if (!ok) {$ ok &= _TX_CALL (Win32::SetConsoleFont, (out, uniFont)); } 10837 10838 $ HWND console = Win32::GetConsoleWindow(); 10839 $ InvalidateRect (console, NULL, false); 10840 $ UpdateWindow (console); 10841 10842 $ return ok; 10843 } 10844 10845 #endif // TX_COMPILED 10846 10847 //----------------------------------------------------------------------------------------------------------------- 10848 //{ The assistants to the nightmare. You can use it freely to make your own nightmare sweet. 10849 10850 #define _TX_TRY { goto __tx_try; } __tx_try: { int __tx_error = S_OK; (void)__tx_error; 10851 #define _TX_CHECKED( cmd ) { if (FAILED (__tx_error = (cmd))) goto __tx_catch; } 10852 #define _TX_FAIL { __tx_error = E_FAIL; goto __tx_catch; } 10853 #define _TX_RETRY { __tx_error = S_OK; goto __tx_try; } 10854 #define _TX_OK ( SUCCEEDED (__tx_error) ) 10855 #define _TX_CATCH goto __tx_finally; __tx_catch: 10856 #define _TX_RETURN goto __tx_finally; 10857 #define _TX_FINALLY __tx_finally: 10858 #define _TX_ENDTRY } 10859 10860 //} 10861 //----------------------------------------------------------------------------------------------------------------- 10862 10863 // Мало не покажется 10864 10865 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10866 10867 bool _txCreateShortcut (const char shortcutName[], 10868 const char fileToLink[], const char args[] /*= NULL*/, const char workDir[] /*= NULL*/, 10869 const char description[] /*= NULL*/, int cmdShow /*= SW_SHOWNORMAL*/, const char iconFile[] /*= NULL*/, int iconIndex /*= 0*/, 10870 int fontSize /*= 0*/, COORD bufSize /*= ZERO (COORD)*/, COORD wndSize /*= ZERO (COORD)*/, COORD wndOrg /*=ZERO (COORD)*/) 10871 { 10872 $1 if (_TX_ARGUMENT_FAILED (shortcutName && *shortcutName)) return false; 10873 $ if (_TX_ARGUMENT_FAILED (fileToLink && *fileToLink)) return false; 10874 10875 #if defined (__IShellLinkDataList_INTERFACE_DEFINED__) 10876 10877 $ IShellLink* shellLink = NULL; 10878 $ IShellLinkDataList* dataList = NULL; 10879 $ IPersistFile* file = NULL; 10880 10881 $ HRESULT init = Win32::CoInitialize (NULL); 10882 10883 _TX_TRY 10884 { 10885 $ _TX_CHECKED (Win32::CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, Win32::IID_IShellLink, (void**) &shellLink)); 10886 $ if (!shellLink) _TX_FAIL; 10887 10888 $ shellLink->SetPath (fileToLink); 10889 $ shellLink->SetArguments (args); 10890 $ shellLink->SetWorkingDirectory (workDir); 10891 $ shellLink->SetDescription (description); 10892 $ shellLink->SetShowCmd (cmdShow); 10893 $ shellLink->SetIconLocation (iconFile, iconIndex); 10894 10895 $ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IShellLinkDataList, (void**) &dataList)); 10896 $ if (!dataList) _TX_FAIL; 10897 10898 $ Win32::NT_CONSOLE_PROPS props = 10899 {{sizeof (props), NT_CONSOLE_PROPS_SIG}, 10900 10901 FOREGROUND_LIGHTGRAY, // wFillAttribute 10902 FOREGROUND_MAGENTA | BACKGROUND_WHITE, // wPopupFillAttribute 10903 {bufSize.X, bufSize.Y}, // dwScreenBufferSize 10904 {wndSize.X, wndSize.Y}, // dwWindowSize 10905 {wndOrg.X, wndOrg.Y}, // dwWindowOrigin 10906 0, // nFont 10907 0, // nInputBufferSize 10908 {0, (short) fontSize}, // dwFontSize 10909 0x36, 400, L"Lucida Console", // uFontFamily, uFontWeight, FaceName. We're dancing for this! 10910 15, // uCursorSize 10911 0, 1, 1, 0, // bFullScreen, bQuickEdit, bInsertMode, bAutoPosition 10912 50, 4, 0, // uHistoryBufferSize, uNumberOfHistoryBuffers, bHistoryNoDup 10913 10914 {0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, // Palette 10915 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF} 10916 }; 10917 10918 $ _TX_CHECKED (dataList->AddDataBlock (&props)); 10919 10920 $ _TX_CHECKED (shellLink->QueryInterface (Win32::IID_IPersistFile, (void**) &file)); 10921 $ if (!file) _TX_FAIL; 10922 10923 $ wchar_t wName[MAX_PATH] = L""; 10924 $ MultiByteToWideChar (_TX_CODEPAGE, 0, shortcutName, -1, wName, MAX_PATH) || ZeroMemory (wName, sizeof (wName)); 10925 10926 $ _TX_CHECKED (file->Save (wName, true)); 10927 } 10928 10929 $ _TX_CATCH 10930 $ _TX_FINALLY 10931 10932 if (file) {$ file ->Release(); } 10933 if (dataList) {$ dataList ->Release(); } 10934 if (shellLink) {$ shellLink->Release(); } 10935 10936 if (init == S_OK) {$ Win32::CoUninitialize(); } 10937 10938 $ return _TX_OK; 10939 _TX_ENDTRY 10940 10941 #else 10942 10943 (void) args; (void) workDir, (void) description; (void) cmdShow; (void) iconFile; (void) iconIndex; 10944 (void) fontSize; (void) bufSize; (void) wndSize; (void) wndOrg; 10945 10946 $ return false; 10947 10948 #endif 10949 } 10950 10951 #endif // TX_COMPILED 10952 10953 //} 10954 //----------------------------------------------------------------------------------------------------------------- 10955 10957 //} 10958 //================================================================================================================= 10959 10960 //================================================================================================================= 10961 //{ Memory DC functions (_txBuffer...) 10963 //================================================================================================================= 10965 10966 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 10967 10968 HDC _txBuffer_Create (HWND wnd, const POINT* size /*= NULL*/, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/) 10969 { 10970 $1 txAutoLock _lock; 10971 10972 $ HDC wndDC = GetDC (wnd); 10973 $ if (!wndDC) return NULL; 10974 10975 $ POINT sz = { 1, 1 }; 10976 $ if (size) sz = *size; 10977 10978 $ if (!size && wnd) 10979 { 10980 $ RECT r = {}; 10981 $ GetClientRect (wnd, &r) asserted; 10982 10983 $ sz.x = r.right - r.left; 10984 $ sz.y = r.bottom - r.top; 10985 } 10986 10987 $ if (bitmap) 10988 { 10989 $ BITMAP bmap = {}; 10990 $ Win32::GetObject (bitmap, sizeof (bmap), &bmap) asserted; 10991 10992 $ sz.x = bmap.bmWidth; 10993 $ sz.y = bmap.bmHeight; 10994 } 10995 10996 $ RGBQUAD* buf = NULL; 10997 $ if (!pixels) pixels = &buf; 10998 10999 $ HDC dc = Win32::CreateCompatibleDC (wndDC); 11000 $ if (!dc) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleDC() failed"); 11001 11002 #ifndef _TX_DIB_FIX 11003 #define _TX_DIB_FIX 11004 #endif 11005 11006 $ BITMAPINFO info = {{ sizeof (info), sz.x, _TX_DIB_FIX sz.y, 1, WORD (sizeof (RGBQUAD) * 8), BI_RGB }}; 11007 11008 $ HBITMAP bmap = bitmap? bitmap : Win32::CreateDIBSection (NULL, &info, DIB_RGB_COLORS, (void**) pixels, NULL, 0); 11009 $ if (!bmap) TX_DEBUG_ERROR ("Cannot create buffer: CreateCompatibleBitmap() failed"); 11010 11011 $ Win32::SelectObject (dc, bmap) asserted; 11012 11013 $ if (!bitmap) 11014 { 11015 $ if (*pixels) 11016 { 11017 $ RGBQUAD black = { 0, 0, 0, 255 }; 11018 $ for (int i = 0; i < sz.x * sz.y; i++) (*pixels)[i] = black; //-V108 11019 } 11020 else 11021 {$ Win32::PatBlt (dc, 0, 0, sz.x, sz.y, BLACKNESS) asserted; } 11022 } 11023 11024 $ ReleaseDC (wnd, wndDC) asserted; 11025 11026 $ return dc; 11027 } 11028 11029 //----------------------------------------------------------------------------------------------------------------- 11030 11031 bool _txBuffer_Delete (HDC* dc) 11032 { 11033 $1 if (_TX_ARGUMENT_FAILED (dc)) return false; 11034 $ if ( !*dc) return false; 11035 $ if (_TX_HDC_FAILED (*dc)) return false; 11036 11037 $ if (!Win32::GetObjectType (Win32::GetCurrentObject (*dc, OBJ_BITMAP))) return false; 11038 11039 $ txAutoLock _lock; 11040 11041 $ _txBuffer_Select (Win32::GetStockObject (NULL_PEN), *dc) asserted; 11042 $ _txBuffer_Select (Win32::GetStockObject (NULL_BRUSH), *dc) asserted; 11043 $ _txBuffer_Select (Win32::GetStockObject (SYSTEM_FONT), *dc) asserted; 11044 $ _txBuffer_Select (_txStockBitmap, *dc); 11045 11046 $ Win32::DeleteObject (Win32::GetCurrentObject (*dc, OBJ_BITMAP)) asserted; 11047 11048 $ Win32::DeleteDC (*dc) asserted; 11049 11050 $ *dc = NULL; 11051 11052 $ return true; 11053 } 11054 11055 //----------------------------------------------------------------------------------------------------------------- 11056 11057 bool _txBuffer_Select (HGDIOBJ obj, HDC dc /*= txDC()*/) 11058 { 11059 $1 if (!obj) return false; 11060 $ if (_TX_HDC_FAILED (dc)) return false; 11061 11062 $ if (!Win32::GetObjectType (obj)) TX_DEBUG_ERROR ("Invalid GDI object type"); 11063 11064 $ txAutoLock _lock; 11065 11066 $ obj = Win32::SelectObject (dc, obj); 11067 $ if (obj) Win32::DeleteObject (obj); 11068 11069 $ return obj != NULL; 11070 } 11071 11072 #endif // TX_COMPILED 11073 11075 //} 11076 //================================================================================================================= 11077 11078 //================================================================================================================= 11079 //{ Diagnostics 11081 //================================================================================================================= 11083 11084 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11085 11086 const char* _txError (const char* file /*= NULL*/, int line /*= 0*/, const char* func /*= NULL*/, unsigned color /*= 0*/, 11087 const char* msg /*= NULL*/, ...) 11088 { //---/\---/\-------Это ASCII KOT!--// 11089 $1 va_list arg; va_start (arg, msg); // { '-' } // 11090 $$ const char* what = _txProcessError (file, line, func, color, msg, arg); // { 0 0 } Добавь его себе // 11091 va_end (arg); // --> V <-- в исходник, и тебе // 11092 // \ \|/ / будет, наверно, // 11093 if (!(msg && msg[0] == '\a')) return what; // \___/ приятно отлаживаться // 11094 //---------------долгими ночами:)--// 11095 // vvvvvvvvvvvvvvvvvv 11096 DebugBreak(); // >>> Котики, вы в отладчике. Не пугайтесь. Есть шанс посмотреть переменные и разобраться. 11097 // ^^^^^^^^^^^^^^^^^^ 11098 11099 return what; // >>> Уходите из функции пошаговой отладкой (F10/F11). Следите за стеком вызовов (Alt+7). 11100 } 11101 11102 #endif // TX_COMPILED 11103 11104 //----------------------------------------------------------------------------------------------------------------- 11105 //{ General runtime check hooks 11106 //----------------------------------------------------------------------------------------------------------------- 11107 11108 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11109 11110 void _txOnSignal (int sig /*= 0*/, int fpe /*= 0*/) 11111 { 11112 $1 if (!sig && !fpe) 11113 { 11114 $ signal (SIGSEGV, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11115 $ signal (SIGFPE, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11116 $ signal (SIGABRT, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11117 $ signal (SIGILL, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11118 $ signal (SIGTERM, (void(*)(int))(uintptr_t)_txOnSignal) != SIG_ERR asserted; 11119 $ return; 11120 } 11121 11122 txOutputDebugPrintf ("%s - WARNING: %s (%d, %d) called\n", _TX_VERSION, __func__, sig, fpe); 11123 11124 #define GET_DESCR_(str, code, descr) case (code): {$ (str) = " " #code ": " descr; break; } 11125 11126 $ const char* sSig = "Неизвестный тип сигнала"; 11127 11128 $ switch (sig) 11129 { 11130 GET_DESCR_ (sSig, SIGSEGV, "Доступ по неверному указателю. Ставьте ассерты!") 11131 GET_DESCR_ (sSig, SIGILL, "Попытка выполнить недопустимую операцию. Проверьте указатели на функции.") 11132 GET_DESCR_ (sSig, SIGABRT, "Аварийное завершение программы, вызвана функция abort().") 11133 GET_DESCR_ (sSig, SIGTERM, "Получен сигнал принудительного завершения программы.") 11134 GET_DESCR_ (sSig, SIGFPE, "Грубая ошибка в вычислениях.") 11135 default: break; //-V2522 11136 } 11137 11138 $ const char* sFPE = ""; 11139 11140 #if defined (_MSC_VER) 11141 11142 // MSVC provides the FPE code as a MS extension. 11143 // See: https://msdn.microsoft.com/ru-ru/library/xdkz3x12.aspx 11144 11145 $ if (sig == SIGFPE) switch (fpe) 11146 { 11147 GET_DESCR_ (sFPE, _FPE_INVALID, "Результат неверен.") 11148 GET_DESCR_ (sFPE, _FPE_DENORMAL, "Денормализация.") 11149 GET_DESCR_ (sFPE, _FPE_ZERODIVIDE, "Деление на ноль.") 11150 GET_DESCR_ (sFPE, _FPE_OVERFLOW, "Результат слишком большой.") 11151 GET_DESCR_ (sFPE, _FPE_UNDERFLOW, "Результат слишком маленький.") 11152 GET_DESCR_ (sFPE, _FPE_INEXACT, "Результат неточен.") 11153 GET_DESCR_ (sFPE, _FPE_UNEMULATED, "Операция не поддерживается.") 11154 GET_DESCR_ (sFPE, _FPE_SQRTNEG, "Квадратный корень из отрицательного числа.") 11155 GET_DESCR_ (sFPE, _FPE_STACKOVERFLOW, "Переполнение стека сопроцессора.") 11156 GET_DESCR_ (sFPE, _FPE_STACKUNDERFLOW, "В стеке сопроцессора не хватает данных.") 11157 GET_DESCR_ (sFPE, _FPE_EXPLICITGEN, "Явный вызов исключения.") 11158 default: break; //-V2522 11159 } 11160 11161 #else 11162 $ fpe = 0; 11163 #endif 11164 11165 #undef GET_DESCR_ 11166 11167 $ signal (sig, (void(*)(int))(uintptr_t)_txOnSignal); 11168 11169 $ Win32::_fpreset(); 11170 11171 $ _TX_UNEXPECTED ("\a\t" 11172 "signal (%d, 0x%02X):%s%s " 11173 "%s%s" 11174 "С помощью функции signal() вы можете сами обработать эту ошибку.", 11175 sig, (unsigned) fpe, sSig, sFPE, 11176 ((_txDumpSE[1] == '\n')? "" : "\n\n"), _txDumpSE + 1); 11177 } 11178 11179 //----------------------------------------------------------------------------------------------------------------- 11180 11181 void _txOnTerminate() 11182 { 11183 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11184 11185 // From: http://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc 11186 11187 $1 static int terminating = 0; 11188 if (terminating++) {$ _TX_UNEXPECTED ("\a" "std::terminate() вызвана рекурсивно."); return; } 11189 11190 $ if (!*_txDumpSE) 11191 {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); } 11192 11193 $ _TX_UNEXPECTED ("\t\a" 11194 "std::terminate(): Неперехваченное исключение в функции main() или в деструкторе, " 11195 "или другая фатальная ошибка C++. " 11196 "%s" 11197 "Используйте try/catch блоки, перехватывайте catch (...), проверяйте вызовы виртуальных функций, " 11198 "разбирайтесь, в чем дело.\n\n" 11199 "С помощью std::set_terminate() вы можете сами обработать эту ошибку." + !*_txDumpSE, 11200 _txDumpSE + 1); 11201 } 11202 11203 //----------------------------------------------------------------------------------------------------------------- 11204 11205 void _txOnUnexpected() 11206 { 11207 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11208 11209 $1 if (!*_txDumpSE) 11210 {$ _txDumpExceptionCPP (_txDumpSE + 1, sizeof (_txDumpSE) - 2); } 11211 11212 $ _TX_UNEXPECTED ("std::unexpected(): Необработанное исключение.\n\n" 11213 "Проверьте свои catch-блоки. Перехватите catch (...). Если вы (зря) используете " 11214 "спецификацию исключений для функций, проверьте, не нарушена ли она." 11215 "%s" 11216 "С помощью catch (...) в main() вы можете сами обработать эту ошибку.", 11217 _txDumpSE + 1); 11218 } 11219 11220 //----------------------------------------------------------------------------------------------------------------- 11221 11222 int _txOnMatherr (_exception* exc) 11223 { 11224 txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*) exc); 11225 11226 $1 assert (exc); 11227 11228 const char* sType = "Неизвестный тип исключения"; 11229 11230 #if !defined (__CYGWIN__) 11231 11232 #define GET_DESCR_(code, descr) case (code): {$ sType = "(" #code "): " descr; break; } 11233 11234 $ switch (exc->type) 11235 { 11236 GET_DESCR_ (_DOMAIN, "Нарушение области определения"); 11237 GET_DESCR_ (_SING, "Сингулярность аргумента"); 11238 GET_DESCR_ (_PLOSS, "Частичная потеря значимости"); 11239 GET_DESCR_ (_TLOSS, "Полная потеря значимости"); 11240 GET_DESCR_ (_OVERFLOW, "Результат слишком большой"); 11241 GET_DESCR_ (_UNDERFLOW, "Результат слишком маленький"); 11242 default: break; //-V2522 11243 } 11244 11245 #undef GET_DESCR_ 11246 11247 $ _TX_UNEXPECTED ("_matherr(): Математическая ошибка %d %s в функции %s (%g, [%g]). Она вернет значение %g.\n\n" 11248 "С помощью __setusermatherr() вы можете сами обработать эту ошибку.", 11249 exc->type, sType, exc->name, exc->arg1, exc->arg2, exc->retval); 11250 #else 11251 11252 $ _TX_UNEXPECTED ("_matherr(): Математическая ошибка: %s.", sType); 11253 11254 #endif 11255 11256 return 0; 11257 } 11258 11259 //----------------------------------------------------------------------------------------------------------------- 11260 11261 tx_noreturn void _txOnNewHandlerAnsi() 11262 { 11263 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11264 $1 11265 $ _TX_UNEXPECTED ("operator new: Ошибка выделения памяти.\n\n" 11266 "С помощью std::set_new_handler() вы можете сами обработать эту ошибку " 11267 "и где-нибудь найти недостающую память."); 11268 11269 $ throw std::bad_alloc(); 11270 } 11271 11272 //----------------------------------------------------------------------------------------------------------------- 11273 11274 void _txOnSecurityErrorAnsi (const char* msg, void* ptr, int code) 11275 { 11276 txOutputDebugPrintf ("%s - WARNING: %s (%s, 0x%p, %d) called\n", _TX_VERSION, __func__, msg, ptr, code); 11277 11278 $1 if (code) 11279 {$ errno = code; } 11280 11281 $ _TX_UNEXPECTED ("\a" 11282 "Ошибка переполнения буфера %d: %s в %.20s (0x%p). Ставьте ассерты!\n\n" 11283 "С помощью std::set_constraint_handler_s() вы можете сами обработать эту ошибку " 11284 "и постараться не выходить за границы массивов.", 11285 code, msg, (char*) ptr, ptr); 11286 } 11287 11288 //----------------------------------------------------------------------------------------------------------------- 11289 11290 int tx_glGetError (int setError /*= INT_MIN*/) 11291 { 11292 $1 _txOGLError = (setError == INT_MIN)? _TX_CALL (Win32::glGetError, ()) : setError; 11293 $ return _txOGLError; 11294 } 11295 11296 #endif // TX_COMPILED 11297 11298 //} 11299 //----------------------------------------------------------------------------------------------------------------- 11300 11301 //----------------------------------------------------------------------------------------------------------------- 11302 //{ MSC Runtime check hooks 11303 //----------------------------------------------------------------------------------------------------------------- 11304 11305 #if defined (_MSC_VER) 11306 11307 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11308 11309 //----------------------------------------------------------------------------------------------------------------- 11310 11311 int _txOnNewHandler (size_t size) 11312 { 11313 txOutputDebugPrintf ("%s - WARNING: %s (0x%p) called\n", _TX_VERSION, __func__, (void*)(uintptr_t) size); 11314 $5 11315 $ _TX_UNEXPECTED ("operator new: Ошибка выделения %llu байт памяти.\n\n" 11316 "С помощью _set_new_handler() вы можете сами обработать эту ошибку " 11317 "и где-нибудь найти недостающую память.", (unsigned long long) size); 11318 11319 $ throw std::bad_alloc(); 11320 } 11321 11322 //----------------------------------------------------------------------------------------------------------------- 11323 11324 void _txOnSecurityError (int code, void* addr) 11325 { 11326 txOutputDebugPrintf ("%s - WARNING: %s (%d, 0x%p) called\n", _TX_VERSION, __func__, code, addr); 11327 $5 11328 $ _TX_UNEXPECTED ("\a" 11329 "Ошибка переполнения буфера %d (_SECERR_BUFFER_OVERRUN). Ставьте ассерты!\n\n" 11330 "С помощью _set_security_error_handler() вы можете сами обработать эту ошибку " 11331 "и более торжественно завершить программу. Ставьте же ассерты.", code); 11332 } 11333 11334 //----------------------------------------------------------------------------------------------------------------- 11335 11336 void _txOnPureCall() 11337 { 11338 txOutputDebugPrintf ("%s - WARNING: %s() called\n", _TX_VERSION, __func__); 11339 $5 11340 $ _TX_UNEXPECTED ("\a" 11341 "Вызвана чисто виртуальная функция. Такое бывает, например, в конструкторах " 11342 "или деструкторах базовых классов - не вызывайте там таких функций.\n\n" 11343 "С помощью _set_purecall_handler() вы можете сами обработать эту ошибку " 11344 "и проверить свое знание С++ :)"); 11345 } 11346 11347 //----------------------------------------------------------------------------------------------------------------- 11348 11349 void _txOnInvalidParam (const wchar_t* wExpr, const wchar_t* wFunc, const wchar_t* wFile, unsigned int line, uintptr_t addr) 11350 { 11351 txOutputDebugPrintf ("%s - WARNING: %s (%S, %S, %S, %d, 0x%p) called\n", _TX_VERSION, __func__, wExpr, wFunc, wFile, line, addr); 11352 11353 $5 assert (wExpr); 11354 assert (wFunc); 11355 assert (wFile); 11356 11357 char expr [_TX_BUFSIZE/2] = "[Unknowm expr]", 11358 func [_TX_BUFSIZE/2] = "[Unknowm func]", 11359 file [MAX_PATH] = "[Unknowm file]"; 11360 11361 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wExpr, -1, expr, sizeof (expr) - 1, NULL, NULL); 11362 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wFunc, -1, func, sizeof (func) - 1, NULL, NULL); 11363 $ WideCharToMultiByte (_TX_CODEPAGE, 0, wFile, -1, file, sizeof (file) - 1, NULL, NULL); 11364 11365 $$ _txError (file, (int) line, func, 0, "\a" 11366 "В функцию %s передан неверный параметр: неверно, что %s. Не надо так.\n\n" 11367 "С помощью _set_invalid_parameter_handler() вы можете сами обработать эту ошибку.", func, expr); 11368 } 11369 11370 //----------------------------------------------------------------------------------------------------------------- 11371 11372 #if defined (_CLANG_VER) && !defined (_MSC_VER) 11373 11374 void _txLibCppDebugFunction (std::__libcpp_debug_info const& info) 11375 { 11376 $5 assert (&info); 11377 11378 $$ _txError (info.__file_, info.__line_, NULL, 0, "\a" 11379 "Оказалось неверно, что %s (%s). Не надо так.\n\n" 11380 "С помощью std::__libcpp_debug_function вы можете сами обработать эту ошибку.", info.__pred_, info.__msg_); 11381 } 11382 11383 #endif 11384 11385 //----------------------------------------------------------------------------------------------------------------- 11386 11387 #pragma runtime_checks ("", off) 11388 11389 int _txOnRTCFailure (int type, const char* file, int line, const char* module, const char* format, ...) 11390 { 11391 txOutputDebugPrintf ("%s - WARNING: %s (%d, %s, %d, %s, %s) called\n", _TX_VERSION, __func__, type, file, line, module, format); 11392 11393 $5 static long running = 0; 11394 $ while (InterlockedExchange (&running, 1)) Sleep (0); 11395 11396 $ assert (format); 11397 11398 // Disable all RTC failures 11399 11400 $ int nErrors = _RTC_NumErrors(); 11401 $ int* errors = NULL; 11402 $ try { errors = (int*) _alloca (nErrors * sizeof (*errors)); } catch (...) {;} //-V104 11403 11404 $ int err = 0; 11405 $ for (int i = 0; i < nErrors; i++) *(errors? &errors[i] : &err) = _RTC_SetErrorType ((_RTC_ErrorNumber) i, _RTC_ERRTYPE_IGNORE); //-V108 11406 11407 $ char text [_TX_BUFSIZE] = ""; 11408 11409 $ va_list arg; va_start (arg, format); 11410 $ _tx_vsnprintf_s (text, sizeof (text) - 1, format, arg); // Get message from the vararg list 11411 $ auto error = (_RTC_ErrorNumber) va_arg (arg, int /*_RTC_ErrorNumber*/); // Get the RTC error number 11412 $ va_end (arg); 11413 11414 $ const char* sType = "type"; 11415 11416 $ switch (type) 11417 { 11418 case _CRT_ERROR: $ sType = "ошибка"; break; 11419 case _CRT_ASSERT: $ sType = "логическая ошибка"; break; 11420 case _CRT_WARN: $ sType = "возможная ошибка"; break; 11421 default: $ break; 11422 } 11423 11424 $ const char* sError = _RTC_GetErrDesc (error); 11425 11426 $$ _txError (file, line, NULL, 0, "\a" 11427 "Сбой проверки выполнения машинного кода: %s %d (%s): %s в модуле %s.", sType, error, sError, text, module); 11428 11429 // The code below will be never executed until the error above will stay fatal: 11430 11431 // Restore the RTC error types 11432 11433 #if defined (_MSC_VER) 11434 #pragma warning (push) 11435 #pragma warning (disable: 6385) // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read. 11436 #endif 11437 11438 $ for (int i = 0; i < nErrors; i++) _RTC_SetErrorType ((_RTC_ErrorNumber) i, (errors? errors[i] : _CRT_ERROR)); //-V108 11439 11440 #if defined (_MSC_VER) 11441 #pragma warning (pop) // Reading invalid data from 'errors': the readable size is 'n' bytes, but 'm' bytes may be read. 11442 #endif 11443 11444 $ InterlockedExchange (&running, 0); 11445 $ return 1; 11446 } 11447 11448 #pragma runtime_checks ("", restore) 11449 11450 //----------------------------------------------------------------------------------------------------------------- 11451 11452 int _txOnAllocHook (int type, void* data, size_t size, int use, long request, const unsigned char* file, int line) 11453 { 11454 #if (_TX_ALLOW_TRACE +0 >= 4) 11455 11456 static _tx_thread int recursive = 0; 11457 if (recursive) return true; 11458 recursive++; 11459 11460 #if (_TX_ALLOW_TRACE +0 <= 10) 11461 if (!size) return true; 11462 #endif 11463 11464 #define GET_DESCR_(str, type) case (type): { str = #type; break; } 11465 11466 const char* sType = "Unknown type"; 11467 const char* sUse = "Unknown use"; 11468 11469 switch (_BLOCK_TYPE (type)) 11470 { 11471 GET_DESCR_ (sType, _HOOK_ALLOC); 11472 GET_DESCR_ (sType, _HOOK_REALLOC); 11473 GET_DESCR_ (sType, _HOOK_FREE); 11474 default: break; 11475 } 11476 11477 switch (use) 11478 { 11479 GET_DESCR_ (sUse, _NORMAL_BLOCK); 11480 GET_DESCR_ (sUse, _CRT_BLOCK); 11481 GET_DESCR_ (sUse, _CLIENT_BLOCK); 11482 GET_DESCR_ (sUse, _FREE_BLOCK); 11483 GET_DESCR_ (sUse, _IGNORE_BLOCK); 11484 default: break; 11485 } 11486 11487 #undef GET_DESCR_ 11488 11489 _txTrace ((const char*) file, line, NULL, "%*s" 11490 "_txOnAllocHook (type = 0x%02X (%-*s), subtype =0x%X, data = 0x%p, size = 0x%p, use = 0x%02X (%-*s), request = %ld)", 11491 2 * _txLoc::Cur.inTX, "", 11492 type, 13, sType, _BLOCK_SUBTYPE (type), data, (void*) size, use, 13, sUse, request); 11493 11494 recursive--; 11495 11496 #else 11497 11498 UNREFERENCED_PARAMETER (type); 11499 UNREFERENCED_PARAMETER (data); 11500 UNREFERENCED_PARAMETER (size); 11501 UNREFERENCED_PARAMETER (use); 11502 UNREFERENCED_PARAMETER (request); 11503 UNREFERENCED_PARAMETER (file); 11504 UNREFERENCED_PARAMETER (line); 11505 11506 #endif 11507 11508 return true; //-V601 11509 } 11510 11511 //----------------------------------------------------------------------------------------------------------------- 11512 11513 #endif // TX_COMPILED 11514 11515 #endif 11516 11517 //} 11518 //----------------------------------------------------------------------------------------------------------------- 11519 11520 //----------------------------------------------------------------------------------------------------------------- 11521 //{ SEH staff 11522 //----------------------------------------------------------------------------------------------------------------- 11523 11524 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 11525 11526 long WINAPI _txVectoredExceptionHandler (EXCEPTION_POINTERS* exc) 11527 { 11528 if (!_txProcessSystemWarnings) 11529 { 11530 DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode : 0; //-V560 11531 void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL; //-V560 11532 11533 if (code != DBG_PRINTEXCEPTION_C && 11534 code != DBG_PRINTEXCEPTION_WIDE_C) 11535 { 11536 txOutputDebugPrintf ("%s - WARNING: %s (code 0x%08lX, addr 0x%p) called and SKIPPED! (_txProcessSystemWarnings == %d)\n", 11537 _TX_VERSION, "_txVectoredExceptionHandler", (unsigned long) code, addr, _txProcessSystemWarnings); 11538 } 11539 11540 return EXCEPTION_CONTINUE_SEARCH; 11541 } 11542 else 11543 { 11544 int inTX = _txLoc::Cur.inTX++; 11545 11546 long ret = _txOnExceptionSEH (exc, "_txVectoredExceptionHandler"); 11547 11548 _txLoc::Cur.inTX = inTX; 11549 return ret; 11550 } 11551 } 11552 11553 //----------------------------------------------------------------------------------------------------------------- 11554 11555 long WINAPI _txUnhandledExceptionFilter (EXCEPTION_POINTERS* exc) 11556 { 11557 int inTX = _txLoc::Cur.inTX++; 11558 11559 long ret = _txOnExceptionSEH (exc, "_txUnhandledExceptionFilter"); 11560 11561 if (_txPrevUEFilter) 11562 { 11563 if (_txSetJmp()) 11564 { 11565 int inTX2 = _txLoc::Cur.inTX++; 11566 11567 ret = _txPrevUEFilter (exc); 11568 11569 _txLoc::Cur.inTX = inTX2; 11570 } 11571 else 11572 { 11573 $6 _txClearJmp(); 11574 11575 _TX_UNEXPECTED ("\t\a" "%s" 11576 "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.\n\n" 11577 "Дополнительно: Сбой вызова стандартного обработчика неперехваченнных исключений SEH." + !*_txDumpSE, 11578 _txDumpSE + 1); 11579 } 11580 } 11581 11582 _txLoc::Cur.inTX = inTX; 11583 return ret; 11584 } 11585 11586 //----------------------------------------------------------------------------------------------------------------- 11587 11588 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI _txOnSetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER filter) 11589 { 11590 $6 _txPrevUEFilter = filter; 11591 11592 return (LPTOP_LEVEL_EXCEPTION_FILTER) _txUnhandledExceptionFilter; 11593 } 11594 11595 //----------------------------------------------------------------------------------------------------------------- 11596 11597 long _txOnExceptionSEH (EXCEPTION_POINTERS* exc, const char func[]) 11598 { 11599 assert (exc); if (!exc) {$ return EXCEPTION_CONTINUE_SEARCH; } //-V547 11600 11601 assert (exc->ExceptionRecord); 11602 11603 assert (func); 11604 assert (func[3] == 'V' || func[3] == 'U'); 11605 11606 bool unhExc = (func[3] == 'U'); 11607 DWORD code = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionCode : 0; //-V560 11608 void* addr = (exc && exc->ExceptionRecord)? exc->ExceptionRecord->ExceptionAddress : NULL; //-V560 11609 11610 if (code == DBG_PRINTEXCEPTION_C || 11611 code == DBG_PRINTEXCEPTION_WIDE_C || 11612 code == DBG_THREAD_NAME || 11613 (code == RPC_S_SERVER_UNAVAILABLE && !unhExc) || 11614 (code == RPC_S_CALL_CANCELLED && !unhExc) || 11615 (code == EXCEPTION_BREAKPOINT && IsDebuggerPresent())) 11616 return EXCEPTION_CONTINUE_SEARCH; 11617 11618 ptrdiff_t dist = (uintptr_t) addr - (uintptr_t) IsBadReadPtr; 11619 if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; } 11620 11621 dist = (uintptr_t) addr - (uintptr_t) IsBadWritePtr; 11622 if (0 <= dist && dist <= 256) {$6 return EXCEPTION_CONTINUE_SEARCH; } 11623 11624 _txSENumber = _txSENumber + 1; 11625 if (HIBYTE (HIWORD (code)) == 0xC0) _txSEFatalNumber = _txSEFatalNumber + 1; 11626 11627 OutputDebugString ("\n"); 11628 txOutputDebugPrintf ("%s - WARNING: #%ld: %s (code 0x%08lX, addr 0x%p) called\n", 11629 _TX_VERSION, _txSENumber, func, (unsigned long) code, addr); 11630 11631 $6 if (*(unsigned long long*) _txDumpExceptionObjJmp) 11632 { 11633 $ longjmp (_txDumpExceptionObjJmp, 1); //-V2512 11634 } 11635 11636 tx_fpreset(); 11637 11638 #if defined (_MSC_VER) 11639 if (code == EXCEPTION_STACK_OVERFLOW) {$ _resetstkoflw(); } 11640 #endif 11641 11642 $ bool primaryException = !(func && exc) || !((unhExc && *_txDumpSE) || _TX_MSC__CXX_DETECT_RETHROW (exc->ExceptionRecord)); //-V560 11643 11644 $ if (primaryException && exc) //-V560 11645 { 11646 $ unsigned err = GetLastError(); 11647 11648 $ const char* stackTrace = _txCaptureStackBackTrace (0, true, exc->ContextRecord, exc); 11649 11650 $ _txDumpExceptionSEH (_txDumpSE, (intptr_t) sizeof (_txDumpSE) - 1, exc->ExceptionRecord, func); 11651 $ _tx_snprintf_s (_txTraceSE, (intptr_t) sizeof (_txTraceSE) - 1, "%s", stackTrace); 11652 11653 $ static _tx_thread DWORD prevCode = 0; 11654 $ static _tx_thread void* prevAddr = NULL; 11655 11656 $ if (code != prevCode && addr != prevAddr && 11657 !strstr (_txDumpSE, "Объект исключения C++:")) 11658 { 11659 $ SetLastError (err); 11660 $ _TX_UNEXPECTED ("\v\b\t" "%s", _txDumpSE + 1); 11661 11662 $ prevCode = code; 11663 $ prevAddr = addr; 11664 } 11665 11666 $ SetLastError (err); 11667 } 11668 11669 $ if (_txDumpSE[0] == '\a' || 11670 _txSENumber >= _TX_EXCEPTIONS_LIMIT+0 || 11671 _txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0) 11672 { 11673 $ _TX_UNEXPECTED ("\a\t" "%s" 11674 "С помощью функции _set_se_translator() вы можете сами обработать эту ошибку.", 11675 _txDumpSE + 1); 11676 } 11677 11678 $ return EXCEPTION_CONTINUE_SEARCH; 11679 } 11680 11681 //----------------------------------------------------------------------------------------------------------------- 11682 11683 intptr_t _txDumpExceptionSEH (char what[], intptr_t size, const EXCEPTION_RECORD* exc, const char func[]) //-V2008 11684 { 11685 $6 assert (what); 11686 $ assert (size >= 0); //-V547 11687 assert (exc); if (!exc) {$ return 0; } //-V547 11688 $ assert (func); 11689 11690 $ unsigned code = exc->ExceptionCode; 11691 $ void* addr = exc->ExceptionAddress; 11692 $ unsigned params = exc->NumberParameters; 11693 $ const ULONG_PTR* info = exc->ExceptionInformation; 11694 $ void* object = (params >= 2)? (void*) info[1] : NULL; 11695 11696 $ char* s = what; 11697 11698 #define PRINT_(...) s += _tx_snprintf_s (s, size-2 - (s-what), ##__VA_ARGS__) 11699 11700 $ const char* sCode = NULL; 11701 $ const char* sDescr = NULL; 11702 11703 #define GET_DESCR_(code, descr) case ((unsigned long) (code)): {$ sCode = #code; sDescr = descr; break; } 11704 11705 $ switch (code) 11706 { 11707 GET_DESCR_ (EXCEPTION_ACCESS_VIOLATION, " " "Нарушение доступа к памяти.") 11708 GET_DESCR_ (EXCEPTION_ILLEGAL_INSTRUCTION, " " "Недопустимая операция.") 11709 GET_DESCR_ (EXCEPTION_PRIV_INSTRUCTION, " " "Привилегированная операция.") 11710 GET_DESCR_ (EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "\a" "Выход за границы массива. Ставьте ассерты!") 11711 GET_DESCR_ (EXCEPTION_BREAKPOINT, "\a" "Достигнута точка останова. Удачи в отладке!") 11712 GET_DESCR_ (EXCEPTION_DATATYPE_MISALIGNMENT, "\a" "Нарушение выравнивания данных.") 11713 GET_DESCR_ (EXCEPTION_INVALID_DISPOSITION, "\a" "Обработчик исключения возвратил неверное значение.") 11714 GET_DESCR_ (EXCEPTION_IN_PAGE_ERROR, "\a" "Невозможно загрузить нужную страницу памяти.") 11715 GET_DESCR_ (EXCEPTION_NONCONTINUABLE_EXCEPTION, "\a" "Продолжение выполнения невозможно.") 11716 GET_DESCR_ (EXCEPTION_SINGLE_STEP, "\a" "Выполнена инструкция машинного кода. Одна штука.") 11717 GET_DESCR_ (EXCEPTION_STACK_OVERFLOW, "\a" "Ю-ху! Переполнение стека!") 11718 GET_DESCR_ (EXCEPTION_GUARD_PAGE, "\a" "Попытка доступа к защищенной странице памяти.") 11719 GET_DESCR_ (EXCEPTION_INVALID_HANDLE, "\a" "Неверный или уже закрытый дескриптор.") 11720 GET_DESCR_ (STATUS_POSSIBLE_DEADLOCK, "\a" "Возможно, взаимная блокировка ресурсов.") 11721 11722 GET_DESCR_ (EXCEPTION_FLT_STACK_CHECK, "\a" "Ошибка стека при операции с плавающей точкой.") 11723 GET_DESCR_ (EXCEPTION_FLT_DENORMAL_OPERAND, " " "Денормализация числа с плавающей точкой.") 11724 GET_DESCR_ (EXCEPTION_FLT_DIVIDE_BY_ZERO, " " "Деление на ноль при операции с плавающей точкой.") 11725 GET_DESCR_ (EXCEPTION_FLT_INEXACT_RESULT, " " "Неточный результат при операции с плавающей точкой.") 11726 GET_DESCR_ (EXCEPTION_FLT_INVALID_OPERATION, " " "Недопустимая операция с плавающей точкой.") 11727 GET_DESCR_ (EXCEPTION_FLT_OVERFLOW, " " "Переполнение при операции с плавающей точкой.") 11728 GET_DESCR_ (EXCEPTION_FLT_UNDERFLOW, " " "Потеря значимости при операции с плавающей точкой.") 11729 GET_DESCR_ (STATUS_FLOAT_MULTIPLE_FAULTS, " " "Множественные ошибки с плавающей точкой.") 11730 11731 GET_DESCR_ (EXCEPTION_INT_DIVIDE_BY_ZERO, "\a" "Целочисленное деление на ноль.") 11732 GET_DESCR_ (EXCEPTION_INT_OVERFLOW, "\a" "Переполнение при целочисленной операции.") 11733 11734 GET_DESCR_ (EXCEPTION_CLR_FAILURE, "\a" "Сбой среды исполнения (CLR).") 11735 GET_DESCR_ (STATUS_STACK_BUFFER_OVERRUN, "\a" "Переполнение стекового буфера!") 11736 GET_DESCR_ (STATUS_ASSERTION_FAILURE, "\a" "Сработал assert. На этот раз из ядра.") 11737 GET_DESCR_ (STATUS_WX86_BREAKPOINT, "\a" "Точка останова подсистемы эмуляции x86.") 11738 GET_DESCR_ (RPC_S_UNKNOWN_IF, "\a" "Неизвестный интерфейс удаленного вызова процедур (RPC).") 11739 GET_DESCR_ (RPC_S_SERVER_UNAVAILABLE, "\a" "Сервер удаленного вызова процедур (RPC) недоступен.") 11740 GET_DESCR_ (DBG_TERMINATE_THREAD, "\a" "Отладчик завершил поток сознания.") 11741 GET_DESCR_ (DBG_TERMINATE_PROCESS, "\a" "Отладчик завершил процесс.") 11742 GET_DESCR_ (DBG_CONTROL_C, "\a" "Отладчик получил сигнал прерывания Control+C.") 11743 GET_DESCR_ (DBG_CONTROL_BREAK, "\a" "Отладчик получил сигнал прерывания Control+Break.") 11744 GET_DESCR_ (DBG_THREAD_NAME, " " "Отладчик получил указание дать потоку имя.") 11745 GET_DESCR_ (DBG_PRINTEXCEPTION_C, " " "Отладчик вывел исключение по CTRL+C (OutputDebugStringA).") 11746 GET_DESCR_ (DBG_PRINTEXCEPTION_WIDE_C, " " "Отладчик вывел исключение по CTRL+C (OutputDebugStringW).") 11747 11748 GET_DESCR_ (EXCEPTION_CPP_MSC, " " "Исключение С++, вызванное оператором throw.") 11749 GET_DESCR_ (EXCEPTION_CPP_GCC, " " "Исключение С++, вызванное оператором throw.") 11750 GET_DESCR_ (EXCEPTION_CPP_GCC_UNWIND, " " "Исключение С++, вызванное во время раскрутки стека (rethrow?).") 11751 GET_DESCR_ (EXCEPTION_CPP_GCC_FORCED, " " "Исключение С++, вызванное нарушением магии.") 11752 GET_DESCR_ (EXCEPTION_CPP_BORLAND_BUILDER, "\a" "Это скомпилилось под Билдер? O_O") 11753 GET_DESCR_ (EXCEPTION_CPP_BORLAND_DELPHI, "\a" "Это же С++. Как это вышло?") 11754 11755 default: $ break; 11756 } 11757 11758 #undef GET_DESCR_ 11759 11760 $ if (sDescr) 11761 { 11762 $ PRINT_ ("%s\n\n" "#%ld: Исключение %s", sDescr, _txSENumber, sCode); 11763 } 11764 else 11765 { 11766 $ PRINT_ ("\a#%ld: ", _txSENumber); 11767 $ s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 11768 GetModuleHandle ("NTDLL.DLL"), code, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 11769 s, (DWORD) (size - (s-what)), NULL) - 2; //-V202 11770 $ PRINT_ ("\r\r"); 11771 } 11772 11773 $ PRINT_ (" (0x%X) при выполнении кода по адресу", code); 11774 $ PRINT_ ((addr? " 0x%p" : " NULL"), addr); 11775 11776 $ Win32::SYMBOL_INFO* sym = NULL; 11777 $ Win32::IMAGEHLP_LINE64* line = NULL; 11778 11779 if (addr) {$ _txSymGetFromAddr (addr, &sym, &line); } 11780 11781 $ if (sym && *sym->Name) PRINT_ (" в функции %s()", sym->Name); 11782 $ if (line && line->FileName && *line->FileName) PRINT_ (" в файле %s на строке %u", line->FileName, (unsigned) line->LineNumber); 11783 11784 $ if (code == EXCEPTION_ACCESS_VIOLATION || 11785 code == EXCEPTION_IN_PAGE_ERROR) 11786 { 11787 $ PRINT_ (". Попытка "); 11788 11789 $ unsigned long op = 0xBADC0DE; 11790 $ const char* sOp = "(действие не указано)"; 11791 11792 $ if (params >= 1) 11793 { 11794 $ switch (op = (unsigned long) info[0]) //-V202 11795 { 11796 case 0: $ sOp = "прочесть данные"; break; 11797 case 1: $ sOp = "записать данные"; break; 11798 case 8: $ sOp = "исполнить код"; break; 11799 default: $ sOp = "совершить операцию 0x%lX"; break; 11800 } 11801 } 11802 11803 $ PRINT_ (sOp, op); 11804 11805 $ if (params >= 2) {$ PRINT_ ((object? " по адресу 0x%p" : " по адресу NULL"), object); } //-V1048 11806 else {$ PRINT_ (" (адрес не указан)"); } 11807 11808 $ if (code == EXCEPTION_IN_PAGE_ERROR) 11809 { 11810 $ PRINT_ (", ошибка ввода-вывода:"); 11811 11812 $ if (params >= 3) 11813 { 11814 $ unsigned long ntstatus = (unsigned long) info[2]; //-V202 11815 11816 $ PRINT_ (" 0x%lX (", ntstatus); 11817 11818 $ s += FormatMessage (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 11819 GetModuleHandle ("NTDLL.DLL"), ntstatus, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 11820 s, (DWORD) (size - (s-what)), NULL) - 2; //-V202 11821 $ PRINT_ (")"); 11822 } 11823 else 11824 {$ PRINT_ (" (не указана)"); } 11825 } 11826 } 11827 11828 $ HMODULE module = NULL; 11829 $ _TX_CALL (Win32::GetModuleHandleEx, (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char*) addr, &module)); 11830 11831 $ if (module) 11832 { 11833 $ static char sModule [MAX_PATH] = ""; 11834 $ int ok = GetModuleFileName (module, sModule, sizeof (sModule)); 11835 11836 $ char* ext = (ok? strrchr (sModule, '.') : NULL); 11837 $ if (ext) _strlwr_s (ext, sizeof (sModule) - 1 - (ext - sModule)); 11838 11839 if (ok) {$ PRINT_ (" в модуле %s", sModule); } 11840 else {$ PRINT_ (" в модуле 0x%p", (void*) module); } 11841 } 11842 11843 $ PRINT_ ("."); 11844 11845 $ if (_txSENumber >= _TX_EXCEPTIONS_LIMIT+0) 11846 {$ PRINT_ (" Дополнительно, превышен лимит исключений _TX_EXCEPTIONS_LIMIT (%d).", _TX_EXCEPTIONS_LIMIT+0); } 11847 11848 $ if (_txSEFatalNumber >= _TX_FATAL_EXCEPTIONS_LIMIT+0) 11849 {$ PRINT_ (" Также превышен лимит фатальных исключений _TX_FATAL_EXCEPTIONS_LIMIT (%d).", _TX_FATAL_EXCEPTIONS_LIMIT+0); } 11850 11851 $ PRINT_ (" Спасибо %s(), что сообщил. Люблю его <3", func); 11852 11853 $ if (exc->ExceptionFlags & EXCEPTION_NONCONTINUABLE) 11854 {$ PRINT_ ("\n\n" "Ой, всё (EXCEPTION_NONCONTINUABLE)."); } 11855 11856 $ if (exc->ExceptionRecord) 11857 { 11858 $ PRINT_ ("\n\n" "Причина:" "\n\n"); 11859 $ s += _txDumpExceptionSEH (s, size - (s-what), exc->ExceptionRecord, func); 11860 } 11861 11862 $ if (code == EXCEPTION_CPP_GCC || 11863 code == EXCEPTION_CPP_GCC_UNWIND || 11864 code == EXCEPTION_CPP_GCC_FORCED || 11865 code == EXCEPTION_CPP_MSC) 11866 { 11867 $ s += _txDumpExceptionCPP (s, size - (s-what), code, params, info); 11868 } 11869 11870 #undef PRINT_ 11871 11872 $ while (s > what && s[-1] == '\n') s--; 11873 $ if (s > what) s += _tx_snprintf_s (s, size - (s-what), "\n\n"); 11874 11875 $ return s - what; 11876 } 11877 11878 //----------------------------------------------------------------------------------------------------------------- 11879 11880 intptr_t _txDumpExceptionCPP (char what[], intptr_t size, 11881 unsigned code /*= 0*/, unsigned params /*= 0*/, const ULONG_PTR info[] /*= NULL*/) 11882 { 11883 $6 assert (what); 11884 $ assert (size >= 0); //-V547 11885 11886 $ char* s = what; 11887 11888 $ switch (code) 11889 { 11890 #if defined (_GCC_VER) 11891 11892 case EXCEPTION_CPP_GCC: 11893 case EXCEPTION_CPP_GCC_UNWIND: 11894 case EXCEPTION_CPP_GCC_FORCED: 11895 { 11896 // See: [1] http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp 11897 // [2] http://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-seh.c, lines 51-55 and below 11898 // [3] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_throw.cc, __cxa_throw, line 59 and below 11899 // [4] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/unwind-cxx.h, __cxa_exception, line 58 and below 11900 // and figure above near ABI::__cxa_exception definition in this file 11901 11902 $ const std::type_info* type = NULL; 11903 $ void* object = NULL; 11904 11905 $ if (params >= 1) 11906 { 11907 $ _Unwind_Exception* unwind_exception = (_Unwind_Exception*) info[0]; 11908 $ ABI::__cxa_exception* cxa_exception = (ABI::__cxa_exception*) (unwind_exception + 1) - 1; 11909 11910 $ type = cxa_exception->exceptionType; 11911 $ object = cxa_exception + 1; 11912 } 11913 11914 $ s += _txDumpExceptionObj (s, size - (s-what), object, 0, type); 11915 } 11916 $ break; 11917 11918 case 0: // Not called within SEH chain 11919 { 11920 // From: [1] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_type.cc 11921 // [2] http://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/vterminate.cc 11922 11923 using namespace abi; 11924 using namespace ABI; 11925 11926 $ ABI::__cxa_exception* cxa_exception = __cxa_get_globals() -> caughtExceptions; 11927 11928 $ if (cxa_exception && (cxa_exception->unwindHeader.exception_class & 1)) // Dependent exception, case B, see pic above 11929 { 11930 $ cxa_exception = (((ABI::__cxa_exception*) (&cxa_exception->unwindHeader + 1) - 1) -> primaryException) - 1; 11931 } 11932 11933 $ if (cxa_exception) 11934 { 11935 $ verify (cxa_exception->exceptionType == abi::__cxa_current_exception_type()); 11936 11937 $ s += _txDumpExceptionObj (s, size, cxa_exception + 1, 0, cxa_exception->exceptionType); 11938 } 11939 } 11940 $ break; 11941 11942 #elif defined (_MSC_VER) 11943 11944 case EXCEPTION_CPP_MSC: 11945 { 11946 // See [1] http://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273 11947 // [2] http://www.openrce.org/articles/full_view/21 11948 // [3] http://www.openrce.org/articles/full_view/23 11949 // [4] http://yurichev.com/mirrors/RE/Recon-2012-Skochinsky-Compiler-Internals.pdf 11950 11951 $ const std::type_info* type = NULL; 11952 $ void* object = (params >= 2)? (void*) info[1] : NULL; 11953 $ size_t szObj = 0; 11954 11955 $ if (params >= 3 && 11956 (info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER1 || 11957 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER2 || 11958 info[0] == EXCEPTION_CPP_MSC_EH_MAGIC_NUMBER3 || 11959 info[0] == EXCEPTION_CPP_MSC_EH_PURE_MAGIC_NUMBER1)) 11960 { 11961 $ auto throwInfo = (const Win32::ThrowInfo*) info[2]; 11962 11963 $ if (throwInfo && throwInfo->pCatchableTypeArray) 11964 { 11965 $ HMODULE module = (params >= 4)? (HMODULE) info[3] : NULL; //-V112 11966 11967 #define RVA_(type, addr) ( (type) ((uintptr_t) module + (uintptr_t) (addr)) ) 11968 11969 $ const Win32::CatchableTypeArray* cArray = RVA_(const Win32::CatchableTypeArray*, throwInfo->pCatchableTypeArray); 11970 $ const Win32::CatchableType* cType = RVA_(const Win32::CatchableType*, cArray->arrayOfCatchableTypes[0]); 11971 11972 $ type = RVA_(const std::type_info*, cType->pType); 11973 $ szObj = cType->sizeOrOffset; //-V101 11974 11975 #undef RVA_ 11976 } 11977 } 11978 11979 $ s += _txDumpExceptionObj (s, size - (s-what), object, szObj, type); 11980 } 11981 break; 11982 11983 case 0: // Not called within SEH chain 11984 11985 // signal() handlers or unexpected()/terminate() are called after Vectored Exception in MSC: 11986 // 11987 // terminate() is called by __scrt_unhandled_exception_filter() in case of MSC exception. 11988 // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\utility_desktop.cpp 11989 // 11990 // signal() handlers are called by _seh_filter_exe(), which is called by _mainCRTStartup() in case of exception. 11991 // See C:\Bin\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\mcrtexe.cpp 11992 // and C:\Bin\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\exception_filter.cpp 11993 // and http://msdn.microsoft.com/en-us/library/ff730818.aspx. 11994 // 11995 // So _txDumpSE information should have been recorded during previous call. Now do nothing. 11996 11997 $ break; 11998 11999 #endif 12000 12001 default: 12002 $ txOutputDebugPrintf ("ERROR: Wrong call to %s: Unknown exception code 0x%08X\n", __TX_FUNCTION__, code); 12003 $ break; 12004 } 12005 12006 $ while (s > what && s[-1] == '\n') s--; 12007 $ if (s > what) s += _tx_snprintf_s (s, size - (s - what), "\n\n"); 12008 12009 $ return (s - what); 12010 } 12011 12012 //----------------------------------------------------------------------------------------------------------------- 12013 12014 intptr_t _txDumpExceptionObj (char what[], intptr_t size, void* object, size_t sizeObj, const std::type_info* type) //-V2008 12015 { 12016 $6 assert (what); 12017 $ assert (size > 0); //-V547 12018 12019 $ static char* s = NULL; s = what; 12020 $ static size_t szObj = 0; szObj = sizeObj; 12021 12022 #define PRINT_(...) s += _tx_snprintf_s (s, size - (s - what), ##__VA_ARGS__) 12023 12024 $ PRINT_ ("\n\n" "Объект исключения C++:"); 12025 12026 $ const char* mangledName = (type)? type->name() : NULL; 12027 12028 $ char* typeName = NULL; 12029 $ int err = 1; 12030 12031 #if defined (_GCC_VER) 12032 $ typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); 12033 #endif 12034 12035 $ const char* name = (!err && typeName)? typeName : mangledName; //-V560 12036 12037 $ if (name && 12038 (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >") == 0 || 12039 strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >") == 0)) 12040 {$ name = "std::string"; } 12041 12042 $ if (name && 12043 (strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *") == 0 || 12044 strcmp (name, "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __ptr64") == 0 || 12045 strcmp (name, "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*") == 0)) 12046 {$ name = "std::string*"; } 12047 12048 if (name) {$ PRINT_ (" %s", name); } 12049 12050 #if defined (_GCC_VER) 12051 $ free (typeName); 12052 #endif 12053 12054 $ err = 0; 12055 $ if (mangledName) 12056 { 12057 if (_txSetJmp()) 12058 { 12059 #define PRINT_VAL_(fmt, typ, ...) \ 12060 else if (*type == typeid ( typ )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \ 12061 else if (*type == typeid (const typ )) {$ PRINT_ (" = " #fmt, (* (typ* ) object) __VA_ARGS__); } \ 12062 else if (*type == typeid ( typ* )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 12063 else if (*type == typeid (const typ* )) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 12064 else if (*type == typeid ( typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } \ 12065 else if (*type == typeid (const typ* const)) {$ PRINT_ (" = " #fmt, (**(typ**) object) __VA_ARGS__); } 12066 #define NO_ 12067 12068 if (false) ; 12069 PRINT_VAL_ ("%s", char*, NO_) PRINT_VAL_ ('%c', unsigned char, NO_) PRINT_VAL_ (%s, bool, ? "true" : "false") //-V206 //-V517 12070 PRINT_VAL_ ( %d, int, NO_) PRINT_VAL_ ( %u, unsigned int, NO_) PRINT_VAL_ (%g, float, NO_) //-V206 12071 PRINT_VAL_ ( %hd, short, NO_) PRINT_VAL_ ( %hu, unsigned short, NO_) PRINT_VAL_ (%g, double, NO_) //-V206 12072 PRINT_VAL_ ( %ld, long, NO_) PRINT_VAL_ ( %lu, unsigned long, NO_) PRINT_VAL_ ('%c', char, NO_) //-V206 12073 PRINT_VAL_ ("%s", std::string, .c_str()) //-V206 12074 12075 else if (std::exception* e = dynamic_cast <std::exception*> ( (std::exception* ) object)) 12076 { 12077 $ PRINT_ (", what(): \"%s\"", e->what()); 12078 } 12079 else 12080 {$ err = 1; } 12081 } 12082 else 12083 {$ err = 2; } 12084 } 12085 12086 $ _txClearJmp(); 12087 12088 $ if (err && object && szObj) 12089 { 12090 $ const unsigned char* buf = (const unsigned char*) object; 12091 12092 $ if (szObj >= 64) szObj = 64; 12093 12094 $ PRINT_ (", дамп: ["); 12095 $ for (size_t i = 0; i < szObj; i++) PRINT_ ("%c", (isprint (buf[i]) && !iscntrl (buf[i]))? buf[i] : '.' ); 12096 12097 $ PRINT_ ("]"); 12098 $ for (size_t i = 0; i < szObj; i++) PRINT_ (" %02X", buf[i]); 12099 12100 $ err = 0; 12101 } 12102 12103 $ if (err) 12104 {$ PRINT_ (" = ??"); } 12105 12106 $ PRINT_ ((object? "%sего адрес 0x%p." : "%sего адрес NULL."), ((typeName || mangledName)? ", " : ""), object); //-V560 12107 12108 #undef PRINT_VAL_ 12109 #undef PRINT_ 12110 #undef NO_ 12111 12112 $ return s - what; 12113 } 12114 12115 #endif // TX_COMPILED 12116 12117 //} 12118 //----------------------------------------------------------------------------------------------------------------- 12119 12120 //----------------------------------------------------------------------------------------------------------------- 12121 //{ Stack trace and debug info access 12122 //----------------------------------------------------------------------------------------------------------------- 12123 12124 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 12125 12126 const char* _txCaptureStackBackTrace (int framesToSkip /*= 0*/, bool readSource /*= true*/, 12127 CONTEXT* context /*= NULL*/, EXCEPTION_POINTERS* exc /*= NULL*/, 12128 HANDLE thread /*= GetCurrentThread()*/) 12129 { 12130 $6 const int maxFrames = 62; // MS says: < 63 12131 $ static char trace [(MAX_PATH + 1024+1) * maxFrames] = ""; 12132 12133 if (framesToSkip == -1) {$ return trace; } 12134 12135 $ static void* capture [maxFrames] = {}; 12136 $ int frames = _txStackWalk (framesToSkip + !context, sizearr (capture), capture, context, thread); 12137 12138 $ memset (trace, 0, sizeof (trace)); 12139 $ char* s = trace; 12140 12141 $ bool haveSrcInfo = false; 12142 12143 #define PRINT_(...) s += _tx_snprintf_s (s, sizeof (trace) - 1 - 3 - (s-trace), ##__VA_ARGS__) 12144 12145 $ for (int i = 0, n = 0; i < frames; i++) //-V2530 12146 { 12147 $ void* addr = capture[i]; 12148 12149 $ Win32::SYMBOL_INFO* sym = NULL; 12150 $ Win32::IMAGEHLP_LINE64* line = NULL; 12151 $ const char* module = NULL; 12152 $ const char* source = NULL; 12153 $ bool inTX = false; 12154 12155 if (addr) {$ inTX = _txSymGetFromAddr ((char*) addr - 1, &sym, &line, &module); } 12156 if (readSource && !inTX) {$ _txSymGetFromAddr ((void*) 1, NULL, NULL, NULL, &source, 2); } //-V566 12157 12158 $ int nl = 0; 12159 $ while (s > trace && s[-1] == '\n') { s--; nl++; } 12160 12161 #if !defined (_TX_FULL_STACKTRACE) 12162 12163 $ if (! ((sym && *sym->Name) || (line && ((line->FileName && *line->FileName) || line->LineNumber)))) 12164 {$ continue; } 12165 12166 #endif 12167 12168 $ PRINT_ ("%s#%2d 0x%p", ((n)? ((source || nl)? "\n\n" : "\n") : ""), i, addr); 12169 $ n++; 12170 12171 if (addr == 0) {$ PRINT_ (" [Неверный фрейм]"); break; } 12172 if (addr == (void*) -1) {$ PRINT_ (" [Странный фрейм]"); break; } 12173 if (addr == (void*)(uintptr_t) 0xBAADF00D) {$ PRINT_ (" [Мусор от LocalAlloc()]"); break; } //-V566 12174 12175 if (module) {$ PRINT_ (" in %s%s", module, ((sym && *sym->Name)? ": " : "")); } 12176 if (sym && *sym->Name) {$ PRINT_ ("%s()", sym->Name); } 12177 if (line && line->FileName) {$ PRINT_ (" at %s", line->FileName); haveSrcInfo = true; } 12178 if (line && line->LineNumber) {$ PRINT_ (":%d", (int) line->LineNumber); haveSrcInfo = true; } 12179 if (source) {$ PRINT_ (":\n\n" "%s\n", source); } 12180 12181 if (sym && strcmp (sym->Name , "main") == 0) {$ break; } 12182 } 12183 12184 $ while (s > trace && s[-1] == '\n') s--; 12185 $ *s = 0; 12186 12187 $ int bits = sizeof (void*) * CHAR_BIT; 12188 if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ ("TXLib бедствует: Не загрузилась библиотека"); } 12189 if (!Win32::SymSetOptions) {$ PRINT_ (" DbgHelp%d.dll или DbgHelp.dll,", bits); } 12190 if ( !Win32::MinGW::SymSetOptions) {$ PRINT_ (" MgwHelp%d.dll или MgwHelp.dll,", bits); } 12191 if (!Win32::SymSetOptions || !Win32::MinGW::SymSetOptions) {$ PRINT_ (" отладочная информация недоступна :(\n"); } 12192 12193 $ while (s > trace && s[-1] == '\n') s--; 12194 $ *s = 0; 12195 12196 $ if (!haveSrcInfo) 12197 {$ PRINT_ ("\n\n" "TXLib печалится: Нет информации об исходных файлах. Вы не забыли опцию -g при компиляции?"); } 12198 12199 #if defined (_MSC_VER) 12200 #pragma warning (push) 12201 #pragma warning (disable: 28199) // Using possibly uninitialized memory '*s' 12202 #endif 12203 12204 $ while (s > trace && s[-1] == '\n') s--; 12205 $ *s = 0; 12206 12207 #if defined (_MSC_VER) 12208 #pragma warning (pop) // Using possibly uninitialized memory '*s' 12209 #endif 12210 12211 #undef PRINT_ 12212 12213 $ s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), ""); 12214 12215 #if !defined (_TX_NO_MINIDUMP) 12216 $ _txCreateMiniDump (exc); 12217 #endif 12218 12219 $ return trace; 12220 } 12221 12222 //----------------------------------------------------------------------------------------------------------------- 12223 12224 // Stack WALKING if the program is DEAD. Dead, Carl! 12225 12226 int _txStackWalk (int framesToSkip, size_t szCapture, void* capture[], CONTEXT* context /*= NULL*/, 12227 HANDLE thread /* = GetCurrentThread()*/) 12228 { 12229 $6 namespace MinGW = Win32::MinGW; 12230 12231 $ assert (capture); 12232 12233 $ HANDLE process = GetCurrentProcess(); 12234 $ bool thisThread = !Win32::GetThreadId || (Win32::GetThreadId (thread) == GetCurrentThreadId()); 12235 12236 $ CONTEXT ctx = {}; 12237 $ ctx.ContextFlags |= CONTEXT_FULL; 12238 12239 $ int isWow64 = 0; 12240 $ if (Win32::IsWow64Process) Win32::IsWow64Process (process, &isWow64); 12241 else {$ return -1; } 12242 12243 $ if (context) 12244 { 12245 $ ctx = *context; 12246 } 12247 else 12248 { 12249 $ if (thisThread) 12250 { 12251 $ _TX_CALLv (Win32::RtlCaptureContext, (&ctx)); 12252 } 12253 else 12254 { 12255 $ SuspendThread (thread); //-V720 12256 12257 $ ctx.ContextFlags = CONTEXT_ALL; 12258 $ bool ok = !!GetThreadContext (thread, &ctx); 12259 12260 $ if (!ok) 12261 { 12262 $ ResumeThread (thread); 12263 $ return -1; 12264 } 12265 } 12266 } 12267 12268 $ Win32::STACKFRAME64 frame = {}; 12269 $ frame.AddrPC.Mode = frame.AddrStack.Mode = frame.AddrFrame.Mode = Win32::AddrModeFlat; 12270 12271 $ int cpu = 0; 12272 12273 #if defined (_WIN64) 12274 12275 $ if (isWow64) 12276 { 12277 $ Win32::WOW64_CONTEXT wow64ctx = {}; 12278 $ wow64ctx.ContextFlags |= WOW64_CONTEXT_FULL; 12279 12280 $ if (!_TX_CALL (Win32::Wow64GetThreadContext, (thread, &wow64ctx))) // This call fails in WINE, 12281 { // while EXIT_PROCESS_DEBUG_EVENT 12282 if (!thisThread) {$ ResumeThread (thread); } 12283 $ return 0; 12284 } 12285 12286 $ cpu = IMAGE_FILE_MACHINE_I386; 12287 12288 $ frame.AddrPC .Offset = wow64ctx.Eip; 12289 $ frame.AddrStack.Offset = wow64ctx.Esp; 12290 $ frame.AddrFrame.Offset = wow64ctx.Ebp; 12291 } 12292 else 12293 { 12294 $ cpu = IMAGE_FILE_MACHINE_AMD64; 12295 12296 $ frame.AddrPC .Offset = ctx.Rip; 12297 $ frame.AddrStack.Offset = ctx.Rbp; 12298 $ frame.AddrFrame.Offset = ctx.Rsp; 12299 } 12300 12301 #else 12302 12303 { 12304 $ cpu = IMAGE_FILE_MACHINE_I386; 12305 12306 $ frame.AddrPC .Offset = ctx.Eip; 12307 $ frame.AddrStack.Offset = ctx.Ebp; 12308 $ frame.AddrFrame.Offset = ctx.Esp; 12309 } 12310 12311 #endif 12312 12313 $ assert (cpu); 12314 12315 if (_txSetJmp()) 12316 { 12317 $ _txSymGetFromAddr ((void*) 1); //-V566 12318 } 12319 $ _txClearJmp(); 12320 12321 $ int frames = -1; 12322 12323 $ for (frames = -framesToSkip; frames < (int) szCapture; frames++) //-V202 //-V2530 12324 { 12325 $ DWORD64 prev = frame.AddrStack.Offset; 12326 12327 // Я злой и страшный серый walk. Я в поросятах знаю talk. 12328 12329 if (!_txSetJmp()) {$ break; } 12330 12331 #if defined (_GCC_VER) 12332 12333 if (!_TX_CALL (MinGW::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL, 12334 MinGW::SymFunctionTableAccess64, MinGW::SymGetModuleBase64, NULL))) {$ break; } 12335 #elif defined (_MSC_VER) 12336 12337 $ if (!_TX_CALL (Win32::StackWalk64, (cpu, process, thread, &frame, &ctx, NULL, 12338 Win32::SymFunctionTableAccess64, Win32::SymGetModuleBase64, NULL))) {$ break; } 12339 #else 12340 #error _GCC_VER / _MSC_VER not defined 12341 #endif 12342 if (frames < 0) {$ continue; } 12343 12344 $ void* addr = (void*) frame.AddrPC.Offset; 12345 12346 if (frame.AddrFrame.Offset == 0) {$ addr = 0; } // Bad frame 12347 if (frame.AddrStack.Offset < prev) {$ addr = (void*) -1; } // Strange frame 12348 12349 $ assert (0 <= frames && frames < (int) szCapture); //-V202 12350 12351 $ capture[frames] = addr; //-V108 12352 } 12353 12354 $ _txClearJmp(); 12355 12356 if (!thisThread) {$ ResumeThread (thread); } 12357 12358 $ return frames; 12359 } 12360 12361 // Note that Rick and Carl are speaking near the C language block. "C block", Carl. See: http://knowyourmeme.com/memes/carl 12362 12363 //----------------------------------------------------------------------------------------------------------------- 12364 12365 bool _txSymGetFromAddr (void* addr, Win32::SYMBOL_INFO** symbol /*= NULL*/, 12366 Win32::IMAGEHLP_LINE64** line /*= NULL*/, const char** module /*= NULL*/, 12367 const char** source /*= NULL*/, int context /*= 2*/) 12368 { 12369 $7 static HANDLE process = NULL; 12370 12371 #if defined (_GCC_VER) 12372 #define LIB_ Win32::MinGW 12373 12374 #elif defined (_MSC_VER) 12375 #define LIB_ Win32 12376 12377 #else 12378 #error _GCC_VER / _MSC_VER not defined 12379 #endif 12380 12381 $ if (!process && addr) 12382 { 12383 $ process = GetCurrentProcess(); 12384 12385 $ DWORD options = SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_LOAD_ANYTHING | SYMOPT_INCLUDE_32BIT_MODULES | 12386 SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS; 12387 12388 $ _TX_CALL (LIB_::SymSetOptions, (options)); 12389 $ _TX_CALL (LIB_::SymInitialize, (process, NULL, true)); 12390 } 12391 12392 $ static DWORD64 mod = 0; 12393 12394 $ if (module) 12395 { 12396 $ static char sMod [MAX_PATH] = ""; 12397 $ memset (sMod, 0, sizeof (sMod)); 12398 12399 $ mod = _TX_CALL (LIB_::SymGetModuleBase64, (process, (uintptr_t) addr)); 12400 12401 $ GetModuleFileName ((HMODULE)(intptr_t) mod, sMod, MAX_PATH); 12402 12403 $ char* ext = strrchr (sMod, '.'); 12404 if (ext) {$ _strlwr_s (ext, sizeof (sMod) - (ext-sMod)); } 12405 12406 $ *module = sMod; 12407 } 12408 12409 $ static char buffer [_TX_BUFSIZE] = ""; 12410 $ static Win32::SYMBOL_INFO* sym = (Win32::SYMBOL_INFO*) buffer; //-V1032 12411 12412 $ if (symbol) 12413 { 12414 $ memset (buffer, 0, sizeof (buffer)); 12415 12416 $ sym->MaxNameLen = sizeof (buffer) - sizeof (Win32::SYMBOL_INFO) - 1; 12417 $ sym->SizeOfStruct = sizeof (Win32::SYMBOL_INFO); 12418 $ unsigned long long ofs = 0; 12419 12420 $ _TX_CALL (LIB_::SymFromAddr, (process, (uintptr_t) addr, &ofs, sym)); 12421 12422 if (strcmp (sym->Name, "??") == 0) {$ *sym->Name = 0; } 12423 12424 $ *symbol = sym; 12425 } 12426 12427 $ static Win32::IMAGEHLP_LINE64 line64 = { sizeof (line64) }; 12428 12429 $ if (line) 12430 { 12431 $ memset (&line64, 0, sizeof (line64)); 12432 12433 $ DWORD ofs = 0; 12434 $ _TX_CALL (LIB_::SymGetLineFromAddr64, (process, (uintptr_t) addr, &ofs, &line64)); 12435 12436 $ *line = &line64; 12437 } 12438 12439 $ if (source) 12440 { 12441 $ static char buf [_TX_BUFSIZE] = ""; 12442 $ memset (buf, 0, sizeof (buf)); 12443 12444 $ if (line64.FileName && line64.LineNumber) 12445 { 12446 $ _txReadSource (buf, sizeof (buf) - 1, line64.FileName, 12447 (int) line64.LineNumber - context, (int) line64.LineNumber + context, (int) line64.LineNumber); 12448 12449 $ *source = buf; 12450 } 12451 12452 if (!*source || !**source) {$ *source = NULL; } 12453 } 12454 12455 $ if (!addr && process) 12456 { 12457 $ _TX_CALL (LIB_::SymCleanup, (process)); 12458 12459 $ process = NULL; 12460 } 12461 12462 #if (_GCC_VER == 481) 12463 #pragma GCC diagnostic push 12464 #pragma GCC system_header 12465 #endif 12466 12467 $ if (symbol) 12468 { 12469 $ if (strstr (sym->Name, "::TX::") || 12470 (strncmp (sym->Name, "_tx", 3) == 0 && isupper ((unsigned char) sym->Name[3])) || 12471 (strncmp (sym->Name, "tx", 2) == 0 && isupper ((unsigned char) sym->Name[2])) || 12472 strncmp (sym->Name, "_tx_", 4) == 0 || //-V112 12473 strncmp (sym->Name, "tx_", 3) == 0) 12474 { 12475 $ return true; 12476 } 12477 12478 #if (_GCC_VER == 481) 12479 #pragma GCC diagnostic pop 12480 #endif 12481 12482 $ if (!line || !line64.FileName) return false; 12483 12484 $ intptr_t len = strlen (line64.FileName) - (sizeof (__FILE__) - 1); 12485 12486 $ return (len >= 0 && _stricmp (line64.FileName + len, __FILE__) == 0) && 12487 (len == 0 || line64.FileName[len-1] == '/' || line64.FileName[len-1] == '\\'); 12488 } 12489 12490 #undef LIB_ 12491 12492 $ return false; 12493 } 12494 12495 //----------------------------------------------------------------------------------------------------------------- 12496 12497 intptr_t _txReadSource (char buf[], intptr_t size, const char file[], 12498 int linStart /*= 0*/, int linEnd /*= INT_MIN*/, int linMark /*= INT_MIN*/) 12499 { 12500 $7 assert (buf); 12501 12502 if (!file || !*file) {$ return 0; } 12503 12504 if (linStart < 1) {$ linStart = 1; } 12505 if (linEnd == -1) {$ linEnd = INT_MAX; } 12506 12507 $ FILE* f = NULL; 12508 $ fopen_s (&f, file, "r"); 12509 if (!f) {$ return 0; } 12510 12511 $ int n = 1; 12512 while (!feof (f)) 12513 { 12514 if (n >= linStart) {$ break; } 12515 while (!feof (f) && fgetc (f) != '\n') 12516 ; 12517 n++; 12518 } 12519 12520 $ char* s = buf; 12521 12522 #define SZ_ ( size - 3 - (s - buf) ) 12523 12524 $ while (!feof (f) && SZ_ > 0) 12525 { 12526 if (n > linEnd || _txNOP (SZ_) < 0) {$ break; } 12527 12528 if (linMark != INT_MIN) 12529 {$ s += _tx_snprintf_s (s, SZ_, "%s%5d: ", ((n == linMark)? "=>" : " "), n); } 12530 12531 $ int c = 0; 12532 $ while (!feof (f) && SZ_ > 0 && (c = fgetc (f)) != '\n') *s++ = (char) c; 12533 if (c == EOF) {$ s--; } 12534 12535 if (SZ_ > 0) {$ *s++ = '\n'; } 12536 $ n++; 12537 } 12538 12539 if (n <= linEnd && SZ_ <= 0) 12540 {$ s += _tx_snprintf_s (s, size - (s - buf), "..."); } 12541 12542 #undef SZ_ 12543 12544 $ fclose (f); 12545 12546 if (s > buf && s[-1] == '\n') {$ s--; } 12547 $ *s = 0; 12548 12549 $ return (s - buf); 12550 } 12551 12552 //----------------------------------------------------------------------------------------------------------------- 12553 12554 const char* _txCaptureStackBackTraceTX (int framesToSkip /*= 0*/, bool readSource /*= false*/) 12555 { 12556 $6 const int maxFrames = 62; // TX says too: < 63 12557 $ static char trace [(MAX_PATH + 1024+1) * maxFrames] = ""; 12558 12559 if (framesToSkip == -1) {$ return trace; } 12560 12561 $ memset (trace, 0, sizeof (trace)); 12562 $ char* s = trace; 12563 12564 #define SZ_ ( sizeof (trace) - 1 - 3 - (s-trace) ) 12565 12566 $ const _txLoc* loc = &_txLoc::Cur; 12567 12568 for (int i = 0; loc && i < framesToSkip + 1; i++, loc = loc->prev) { $; } 12569 12570 $ for (int i = -framesToSkip; loc && i < maxFrames; i++, loc = loc->prev) 12571 { 12572 if (i < 0) {$ continue; } 12573 12574 if (loc->func || loc->file || loc->line) 12575 { 12576 $ s += _tx_snprintf_s (s, SZ_, "%s#%2d in %s at %s:%d", (i? readSource? "\n\n" : "\n" : ""), 12577 i, loc->func, loc->file, loc->line); 12578 12579 $ if (readSource) 12580 { 12581 $ s += _tx_snprintf_s (s, SZ_, ":\n\n"); 12582 $ s += _txReadSource (s, SZ_, loc->file, loc->line - 2, loc->line + 2, loc->line); 12583 } 12584 } 12585 } 12586 12587 #undef SZ_ 12588 12589 $ s += _tx_snprintf_s (s, sizeof (trace) - 1 - (s-trace), ""); 12590 12591 $ return trace; 12592 } 12593 12594 //----------------------------------------------------------------------------------------------------------------- 12595 12596 bool _txCreateMiniDump (EXCEPTION_POINTERS* exc /*= NULL*/) 12597 { 12598 $6 static char dumpName[MAX_PATH] = ""; 12599 if (!*dumpName) {$ _tx_snprintf_s (dumpName, sizeof (dumpName) - 1, "%s.dmp", _txLogName); } 12600 12601 $ HANDLE file = CreateFile (dumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 12602 12603 if (!file || file == INVALID_HANDLE_VALUE) {$ return false; } 12604 12605 $ Win32::MINIDUMP_EXCEPTION_INFORMATION excInfo = { GetCurrentThreadId(), exc, false }; 12606 $ Win32::MINIDUMP_TYPE type = (Win32::MINIDUMP_TYPE) (Win32::MiniDumpWithIndirectlyReferencedMemory | Win32::MiniDumpScanMemory); 12607 12608 $ bool ok = _TX_CALL (Win32::MiniDumpWriteDump, (GetCurrentProcess(), GetCurrentProcessId(), file, type, 12609 ((exc)? &excInfo : NULL), NULL, NULL)); 12610 $ CloseHandle (file); 12611 12612 if (ok) {$ return true; } 12613 else {$ return false; } 12614 } 12615 12616 #endif // TX_COMPILED 12617 12618 //} 12619 //----------------------------------------------------------------------------------------------------------------- 12620 12621 //----------------------------------------------------------------------------------------------------------------- 12622 //{ Errors reporting 12623 //----------------------------------------------------------------------------------------------------------------- 12624 12625 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 12626 12627 const char* _txProcessError (const char file[], int line, const char func[], unsigned color, const char msg[], va_list args) //-V2008 12628 { 12629 _txErrors = _txErrors + 1; 12630 12631 DWORD winErr = GetLastError(); 12632 12633 int crtErr = errno; 12634 12635 #if !defined (__CYGWIN__) 12636 unsigned long dosErr = _doserrno; 12637 #else 12638 unsigned long dosErr = 0; 12639 #endif 12640 12641 unsigned dlgErr = _TX_CALL (Win32::CommDlgExtendedError, ()); 12642 12643 unsigned oglErr = _TX_CALL (Win32::wglGetCurrentDC, ())? _TX_CALL (Win32::glGetError, ()) : _txOGLError; 12644 12645 unsigned threadId = GetCurrentThreadId(); 12646 12647 enum { isFatal = 0x01, isWarning = 0x02, noMsgBox = 0x04, fmtOnly = 0x08, traceSE = 0x10 }; 12648 unsigned options = 0; 12649 12650 for (; msg && *msg; msg++) 12651 { 12652 if (*msg == '\a') options |= isFatal; 12653 else if (*msg == '\v') options |= isWarning; 12654 else if (*msg == '\b') options |= noMsgBox; 12655 else if (*msg == '\f') options |= fmtOnly; 12656 else if (*msg == '\t') options |= traceSE; 12657 else break; 12658 } 12659 12660 const char* stkTrace = NULL; 12661 const char* txTrace = NULL; (void) txTrace; 12662 12663 if (!(options & fmtOnly)) 12664 { 12665 stkTrace = ((options & traceSE) && *_txTraceSE)? _txTraceSE : _txCaptureStackBackTrace (2, true); 12666 txTrace = _txCaptureStackBackTraceTX (0, true); 12667 } 12668 12669 static char what[_TX_BIGBUFSIZE*10] = ""; 12670 static char str [_TX_BIGBUFSIZE] = ""; 12671 char *s = what; 12672 12673 #define PRINT_(...) s += _tx_snprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__) 12674 #define VPRINT_(...) s += _tx_vsnprintf_s (s, sizeof (what) - 1 - (s - what), ##__VA_ARGS__) 12675 12676 PRINT_ ("TXLib %s\n\n", ((options & isWarning)? "предупреждает:" : 12677 (options & isFatal)? "соболезнует..." : 12678 "сообщает:")); 12679 PRINT_ ("Программа: %s", txGetModuleFileName()); 12680 if (file) PRINT_ (", файл: %s", file); 12681 if (line) PRINT_ (", строка: %d", line); 12682 if (func) PRINT_ (", функция: %s", func); 12683 PRINT_ (",\n\n"); 12684 12685 if (msg) PRINT_ ("%s: ", (file || line || func)? "Сообщение" : "ВНЕЗАПНО"), 12686 VPRINT_ (msg, args); 12687 12688 while (s > what && s[-1] == '\n') s--; 12689 12690 PRINT_ ("\n\n" "#%d: %s, Instance: 0x%p (%d-bit), Flags: %c%c%c%c%c%d, Thread: 0x%X%s", 12691 12692 _txErrors, _TX_VERSION, (void*) &_txInitialized, (sizeof (void*) == 4)? 32 : 64, 12693 12694 "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], _txLoc::Cur.trace, 12695 12696 threadId, (threadId == _txMainThreadId)? " (Main)" : 12697 (threadId == _txCanvas_ThreadId)? " (Canvas)" : ""); 12698 12699 if (winErr) PRINT_ (", GetLastError(): %lu (", (unsigned long) winErr), 12700 s += FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, //-V102 12701 NULL, winErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 12702 s, (DWORD) (sizeof (what) - (s-what)), NULL) - 2, //-V202 12703 s -= (s[-1] == '.')? 1 : 0, 12704 PRINT_ (")"); 12705 12706 if (crtErr) PRINT_ (", errno: %d (%s)", crtErr, (strerror_s (str, sizeof (str), crtErr), str)); 12707 if (dosErr) PRINT_ (", _doserrno: %lu (%s)", dosErr, (strerror_s (str, sizeof (str), dosErr), str)); 12708 if (oglErr) PRINT_ (", glGetError(): %u (0x%04X, %s)", oglErr, oglErr, _TX_CALL (Win32::gluErrorString, (oglErr))); 12709 if (dlgErr) PRINT_ (", CommDlgExtendedError(): %u (0x%04X)", dlgErr, dlgErr); 12710 12711 #if (__cplusplus >= 201703L) || (defined (_MSVC_LANG) && _MSVC_LANG >= 201703L) 12712 PRINT_ (". %s\n", ::std::uncaught_exceptions()? "std::uncaught_exceptions(): true." : ""); 12713 #else 12714 PRINT_ (". %s\n", ::std::uncaught_exception ()? "std::uncaught_exception(): true." : ""); 12715 #endif 12716 12717 if (_txLoc::Cur.inTX > 0 && file && !(_txLoc::Cur.line == line && _stricmp (_txLoc::Cur.file, file) == 0) && 12718 (_txLoc::Cur.file || _txLoc::Cur.line || _txLoc::Cur.func)) 12719 PRINT_ ("From: %s:%d %s.\n", _txLoc::Cur.file, _txLoc::Cur.line, _txLoc::Cur.func); 12720 12721 txOutputDebugPrintf ("\r" "%s - ERROR: %s\n", _TX_VERSION, what); 12722 12723 if (options & fmtOnly) 12724 { 12725 SetLastError (winErr); 12726 12727 errno = crtErr; 12728 12729 #if !defined (__CYGWIN__) 12730 _doserrno = dosErr; 12731 #endif 12732 12733 return what; 12734 } 12735 12736 txSetProgress (-1, Win32::TBPF_ERROR); 12737 12738 unsigned restore = txGetConsoleAttr(); 12739 txSetConsoleAttr ((options & isFatal)? FOREGROUND_LIGHTMAGENTA : FOREGROUND_LIGHTRED); 12740 if (color) {$ txSetConsoleAttr (color); } 12741 12742 int oldCodePage = txSetLocale(); 12743 12744 fprintf (stderr, "\n" "--------------------------------------------------\n" 12745 "%s", 12746 what); 12747 if (stkTrace) 12748 {$ fprintf (stderr, "\n" "--------------------------------------------------\n" 12749 "Стек вызовов:\n\n" 12750 "%s\n\n" 12751 "--------------------------------------------------\n", 12752 stkTrace); } 12753 errno = 0; 12754 char sErrno[256] = ""; 12755 FILE* log = NULL; 12756 if (*_txLogName) fopen_s (&log, _txLogName, "a"); 12757 strerror_s (sErrno, sizeof (sErrno), errno); 12758 12759 if (!log) 12760 {$ fprintf (stderr, "\n" "TXLib шокирован: Не открывается лог-файл \"%s\" для записи: Ошибка %d (%s)!\n", 12761 _txLogName, errno, sErrno); } 12762 12763 SetConsoleOutputCP (oldCodePage); 12764 txSetConsoleAttr (restore); 12765 12766 if (log) 12767 { 12768 fprintf (log, "\n" "--------------------------------------------------\n" 12769 "%s\n" 12770 "--------------------------------------------------\n", 12771 what); 12772 12773 fprintf (log, "Стек вызовов:\n\n" //-V576 12774 "%s\n", 12775 (*_txTraceSE)? _txTraceSE : stkTrace); 12776 12777 #if defined (_TX_ALLOW_TRACE) || defined (_DEBUG) 12778 12779 if (_txLoc::Cur.inTX > 0 && txTrace && *txTrace) 12780 { 12781 fprintf (log, "\n" "--------------------------------------------------\n" 12782 "Стек вызовов TX:\n\n" 12783 "%s\n", 12784 txTrace); 12785 } 12786 12787 #endif 12788 12789 fprintf (log, "\n" "--------------------------------------------------\n" 12790 "%s\n\n" 12791 "--------------------------------------------------\n", 12792 _txAppInfo()); 12793 } 12794 12795 if (log) fclose (log); 12796 12797 txSleep(); 12798 12799 int ret = 0; 12800 12801 if (!(options & noMsgBox)) 12802 { 12803 txSleep (_txWindowUpdateInterval); 12804 12805 HWND wnd = GetForegroundWindow(); 12806 12807 PRINT_ ("\n" "Прервать программу?"); 12808 12809 ret = txMessageBox (what, ((options & isWarning)? "Предупреждение" : 12810 (options & isFatal)? "Фатальная ошибка" : 12811 "Ошибка в программе"), MB_ICONSTOP | MB_SYSTEMMODAL | MB_YESNOCANCEL); 12812 _txActivateWindow (wnd, 0x10); 12813 } 12814 12815 SetLastError (winErr); 12816 12817 errno = crtErr; 12818 12819 #if !defined (__CYGWIN__) 12820 _doserrno = dosErr; 12821 #endif 12822 12823 if (((options & isFatal) && !IsDebuggerPresent()) || ret == IDYES) 12824 { 12825 txUnlock(); 12826 _txCleanup(); 12827 Win32::TerminateProcess (GetCurrentProcess(), EXIT_FAILURE); 12828 } 12829 12830 #undef PRINT_ 12831 #undef VPRINT_ 12832 12833 return what; 12834 } 12835 12836 //----------------------------------------------------------------------------------------------------------------- 12837 12838 #if defined (_MSC_VER) 12839 12840 int _txOnErrorReport (int type, const char* text, int* ret) 12841 { 12842 assert (text); 12843 assert (ret); 12844 12845 _txErrors = _txErrors + 1; 12846 12847 unsigned restore = txGetConsoleAttr(); 12848 12849 switch (type) 12850 { 12851 case _CRT_WARN: txSetConsoleAttr (FOREGROUND_LIGHTRED); break; 12852 case _CRT_ERROR: txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA); break; 12853 case _CRT_ASSERT: txSetConsoleAttr (FOREGROUND_YELLOW); break; 12854 default: break; //-V2522 12855 } 12856 12857 const char startReport[] = "Detected memory leaks!\n", 12858 endReport[] = "Object dump complete.\n"; 12859 12860 if (strcmp (text, startReport) == 0) // Dirty, dirty hack. А что делать? 12861 { 12862 _txOnErrorReport (type, "\n", NULL); 12863 _txOnErrorReport (type, _TX_VERSION " - ERROR: ", NULL); 12864 _txOnErrorReport (type, "Внимание: Обнаружены утечки памяти! (Для поиска используйте _TX_ALLOC_BREAK.)\n", NULL); 12865 _txOnErrorReport (type, "\n", NULL); 12866 } 12867 12868 size_t len = strlen (text); 12869 if (text [len-1] != '\n') txOutputDebugPrintf ("%s", text); 12870 else if (strcmp (text, endReport) != 0) txOutputDebugPrintf ("%s" "%s - ERROR: ", text, _TX_VERSION); 12871 else txOutputDebugPrintf ("%s\n", text); 12872 12873 DWORD n = 0; 12874 HANDLE err = GetStdHandle (STD_ERROR_HANDLE); 12875 WriteFile (err, text, (DWORD) strlen (text), &n, NULL); //-V202 12876 12877 txSetConsoleAttr (restore); 12878 12879 if (*_txLogName) do //-V2530 12880 { 12881 HANDLE log = CreateFile (_txLogName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 12882 if (log == INVALID_HANDLE_VALUE) break; 12883 12884 SetFilePointer (log, 0, NULL, FILE_END); 12885 WriteFile (log, text, (DWORD) strlen (text), &n, NULL); //-V202 12886 12887 CloseHandle (log); 12888 break; 12889 } 12890 while (false); 12891 12892 if (ret) *ret = 0; 12893 12894 return (type == _CRT_WARN); 12895 } 12896 12897 #endif 12898 12899 //----------------------------------------------------------------------------------------------------------------- 12900 12901 int txMessageBox (const char text[], const char header[], unsigned flags /*= MB_ICONINFORMATION | MB_OKCANCEL*/) 12902 { 12903 $5 static wchar_t textW [_TX_BIGBUFSIZE * sizeof (wchar_t)] = L"[NULL text]"; 12904 $ static wchar_t headerW [_TX_BUFSIZE * sizeof (wchar_t)] = L"[NULL header]"; 12905 12906 if (text) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, text, -1, textW, sizearr (textW)) || memset (textW, 0, sizeof (textW)); } 12907 if (header) {$ MultiByteToWideChar (_TX_CODEPAGE, 0, header, -1, headerW, sizearr (headerW)) || memset (headerW, 0, sizeof (headerW)); } 12908 12909 $ txSleep(); 12910 12911 $ HWND wnd = _txCanvas_Window; 12912 $ int ret = MessageBoxW ((wnd && IsWindowVisible (wnd))? wnd : _TX_CALL (Win32::GetConsoleWindow,()), 12913 textW, headerW, flags | MB_SETFOREGROUND | MB_TOPMOST); 12914 12915 $ GetAsyncKeyState (VK_SHIFT); GetAsyncKeyState (VK_CONTROL); GetAsyncKeyState (VK_MENU); 12916 12917 $ if (ret == IDCANCEL && GetAsyncKeyState (VK_SHIFT) && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_MENU)) 12918 { 12919 $ SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0); 12920 $ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT); 12921 } 12922 12923 $ return ret; 12924 } 12925 12926 //----------------------------------------------------------------------------------------------------------------- 12927 12928 bool txGetAsyncKeyState (int key) 12929 { 12930 $1 HWND wnd = GetForegroundWindow(); 12931 12932 return (GetAsyncKeyState (key) & 0x8000) && 12933 (wnd == txWindow() || wnd == Win32::GetConsoleWindow()); 12934 } 12935 12936 //----------------------------------------------------------------------------------------------------------------- 12937 12938 bool txNotifyIcon (unsigned flags, const char* title, const char* format, ...) 12939 { 12940 $5 if (_TX_ARGUMENT_FAILED (format)) return false; 12941 12942 $ va_list arg; va_start (arg, format); 12943 $ bool ok = true; 12944 12945 #if defined (_WIN32_IE) && (_WIN32_IE >= 0x0500) 12946 12947 $ NOTIFYICONDATA nid = { sizeof (nid) }; 12948 12949 $ nid.uFlags = NIF_ICON | NIF_TIP | NIF_INFO; 12950 $ nid.hWnd = NULL; 12951 $ nid.uID = 1; 12952 $ nid.hIcon = _txCreateTXIcon (16); assert (nid.hIcon); 12953 $ strncpy_s (nid.szTip, sizeof (nid.szTip), "TXLib Information", sizeof (nid.szTip)); 12954 $ strncpy_s (nid.szInfoTitle, sizeof (nid.szInfoTitle), (title? title : "TXLib сообщает"), sizeof (nid.szInfoTitle) - 1); 12955 $ _tx_vsnprintf_s (nid.szInfo, sizeof (nid.szInfo), format, arg); 12956 $ nid.dwInfoFlags = flags; 12957 12958 $ txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification)\n", nid.szInfoTitle, nid.szInfo); 12959 12960 $ ok &= !!Shell_NotifyIcon (NIM_ADD, (::NOTIFYICONDATA*) &nid); 12961 $ ok &= !!Shell_NotifyIcon (NIM_MODIFY, (::NOTIFYICONDATA*) &nid); 12962 12963 $ if (nid.hIcon) DestroyIcon (nid.hIcon) asserted; 12964 12965 #else 12966 12967 $ char nid_szInfo[_TX_BUFSIZE] = ""; 12968 $ _tx_vsnprintf_s (nid_szInfo, sizeof (nid_szInfo), format, arg); 12969 $ txOutputDebugPrintf ("\r" _TX_VERSION " - %s: %s (Icon notification - NOT displayed)\n", title, nid_szInfo); 12970 $ ok = false; 12971 12972 $ (void)flags; (void)title; 12973 12974 #endif 12975 12976 $ va_end (arg); 12977 return ok; 12978 } 12979 12980 //----------------------------------------------------------------------------------------------------------------- 12981 12982 void _txTrace (const char* file, int line, const char* func, const char* msg /*= NULL*/, ...) 12983 { 12984 unsigned id = GetCurrentThreadId(); 12985 12986 const char marks[2][2][3] = {{"uU", "cC"}, {"mM", "??"}}; 12987 12988 char mark = marks [id == _txMainThreadId] [id == _txCanvas_ThreadId] [(_txLoc::Cur.inTX > 0)]; 12989 12990 char msgStr[_TX_BUFSIZE] = ""; 12991 if (msg) 12992 { 12993 va_list arg; va_start (arg, msg); 12994 _tx_vsnprintf_s (msgStr, sizeof (msgStr) - 1, msg, arg); 12995 va_end (arg); 12996 } 12997 12998 txOutputDebugPrintf ("%s - 0x%p %c%c%c%c%c%d [%c] - %-*s (%5d) " "|%*s%s" "%s%s\n", 12999 13000 _TX_VERSION, (void*) &_txInitialized, 13001 13002 "cC"[!!_txConsole], "mM"[_txMain], "dD"[_txIsDll], "rR"[_txRunning], "eE"[_txExit], 13003 _txLoc::Cur.trace, mark, 13004 13005 (int) sizeof (__FILE__) - 1, (file? file : "(NULL file)"), line, 13006 2 * (_txLoc::Cur.inTX - 1) * !!func, "", (func? func : ""), 13007 13008 ((*msgStr && func)? ": " : ""), msgStr); 13009 } 13010 13011 //----------------------------------------------------------------------------------------------------------------- 13012 13013 int txOutputDebugPrintf (const char* format, ...) 13014 { 13015 if (!format) return 0; 13016 13017 enum { msgbox = 1, print = 2, compr = 4 }; 13018 int options = 0; 13019 13020 for (; format && *format; format++) 13021 { 13022 if (*format == '\a') options |= msgbox; 13023 else if (*format == '\f') options |= print; 13024 else if (*format == '\r') options |= compr; 13025 else break; 13026 } 13027 13028 char text[_TX_BIGBUFSIZE] = ""; 13029 13030 va_list arg; va_start (arg, format); 13031 int n = (int) _tx_vsnprintf_s (text, sizeof (text) - 1-1, format, arg); //-V202 13032 va_end (arg); 13033 13034 struct __ { static int trimSpaces (char str[]) 13035 { 13036 char *dst = str, *src = str; 13037 13038 for (char d = ' '; d; src++) 13039 if (isspace ((unsigned char)(*src))) { if (d != ' ') *dst++ = d = ' '; } 13040 else *dst++ = d = *src; 13041 13042 return (int) (dst - str - 1); //-V202 13043 }}; 13044 13045 if (options & compr) n = __::trimSpaces (text); 13046 13047 OutputDebugString (text); 13048 13049 if (options & print) fprintf (stderr, "%s", text); 13050 13051 if (options & msgbox) txMessageBox (text, "Оказывается, что", MB_ICONEXCLAMATION); 13052 13053 return n; 13054 } 13055 13056 //----------------------------------------------------------------------------------------------------------------- 13057 13058 intptr_t _tx_snprintf_s (char* stream, intptr_t size, const char* format, ...) 13059 { 13060 if (!format) return 0; 13061 13062 va_list arg; va_start (arg, format); 13063 intptr_t ret = _tx_vsnprintf_s (stream, size, format, arg); 13064 va_end (arg); 13065 13066 return ret; 13067 } 13068 13069 //----------------------------------------------------------------------------------------------------------------- 13070 13071 intptr_t _tx_vsnprintf_s (char stream[], intptr_t size, const char format[], va_list arg) 13072 { 13073 if (!stream || !format) return 0; 13074 13075 #if defined (_TRUNCATE) 13076 intptr_t ret = _vsnprintf_s (stream, size, _TRUNCATE, format, arg); 13077 #else 13078 intptr_t ret = _vsnprintf (stream, size, format, arg); 13079 #endif 13080 13081 if (ret < 0 && size >= 4) //-V112 13082 { 13083 const char ellipsis[] = "..."; 13084 size_t szEllipsis = sizeof (ellipsis) - 1; 13085 13086 strncpy_s (stream + size - szEllipsis, szEllipsis+1, ellipsis, szEllipsis); 13087 } 13088 13089 return (ret >= 0)? ret : size; 13090 } 13091 13092 //----------------------------------------------------------------------------------------------------------------- 13093 13094 #if defined (__CYGWIN__) 13095 13096 int _getch() 13097 { 13098 termios oldattr = {}; tcgetattr (STDIN_FILENO, &oldattr); 13099 13100 termios newattr = oldattr; 13101 newattr.c_lflag &= ~(ICANON | ECHO); 13102 tcsetattr (STDIN_FILENO, TCSANOW, &newattr); 13103 13104 int ch = getchar(); 13105 13106 tcsetattr (STDIN_FILENO, TCSANOW, &oldattr); 13107 13108 return ch; 13109 } 13110 13111 //----------------------------------------------------------------------------------------------------------------- 13112 13113 int _putch (int ch) 13114 { 13115 termios old = {}; tcgetattr (STDOUT_FILENO, &old); 13116 13117 termios cur = old; 13118 cur.c_lflag &= ~ICANON; 13119 cur.c_lflag |= ECHO; 13120 tcsetattr (STDOUT_FILENO, TCSANOW, &cur); 13121 13122 putchar (ch); 13123 13124 tcsetattr (STDOUT_FILENO, TCSANOW, &old); 13125 13126 return ch; 13127 } 13128 13129 //----------------------------------------------------------------------------------------------------------------- 13130 13131 int _kbhit() 13132 { 13133 termios old = {}; tcgetattr (STDIN_FILENO, &old); 13134 13135 termios cur = old; 13136 cur.c_lflag &= ~(ICANON | ECHO); 13137 cur.c_cc[VMIN] = 1; 13138 cur.c_cc[VTIME] = 0; 13139 13140 tcsetattr (STDIN_FILENO, TCSAFLUSH, &cur); 13141 13142 fd_set fd = {}; FD_SET (STDIN_FILENO, &fd); 13143 timeval tv = {}; 13144 13145 int res = select (STDIN_FILENO + 1, &fd, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &fd); 13146 13147 tcsetattr (STDIN_FILENO, TCSAFLUSH, &old); 13148 13149 return res; 13150 } 13151 13152 #endif 13153 13154 #endif // TX_COMPILED 13155 13156 //} 13157 //----------------------------------------------------------------------------------------------------------------- 13158 13159 //----------------------------------------------------------------------------------------------------------------- 13160 //{ Information 13161 //----------------------------------------------------------------------------------------------------------------- 13162 13163 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 13164 13165 const char* txGetModuleFileName (bool fileNameOnly /*= true*/) 13166 { 13167 static char name[MAX_PATH] = ""; 13168 13169 if (!*name) 13170 { 13171 if (!GetModuleFileName (NULL, name, sizeof (name) - 1)) strncpy_s (name, sizeof (name), "~TXApp", 6); 13172 13173 char* ext = strrchr (name, '.'); 13174 if (ext) _strlwr_s (ext, sizeof (name) - 1 - (ext - name)); 13175 } 13176 13177 assert (*name); 13178 13179 if (fileNameOnly) return name; 13180 13181 static char fullName[MAX_PATH] = ""; 13182 static char* title = fullName; 13183 13184 if (!*fullName || !*title) 13185 { 13186 strncpy_s (fullName, sizeof (fullName), name, sizeof (fullName) - 1); 13187 13188 title = strrchr (fullName, '\\'); if (!title) title = fullName; 13189 char* ext = strrchr (fullName, '.'); if (!ext) ext = fullName + strlen (fullName); 13190 13191 size_t sz = sizeof (fullName) - (ext - fullName); 13192 strncpy_s (ext, sz-1, " - TXLib", sz); 13193 13194 title++; 13195 } 13196 13197 assert (*title); 13198 13199 return title; 13200 } 13201 13202 #endif // TX_COMPILED 13203 13204 //----------------------------------------------------------------------------------------------------------------- 13205 13206 inline const char* _txAppInfo() 13207 { 13208 $1 time_t timeT = time (NULL) - clock()/CLOCKS_PER_SEC; //-V104 13209 char timeS[32] = ""; 13210 ctime_s (timeS, sizeof (timeS), &timeT); 13211 13212 static char text[_TX_BUFSIZE] = ""; 13213 char cwd [MAX_PATH] = ""; 13214 13215 _tx_snprintf_s (text, sizeof (text) - 1, 13216 13217 "Developed with:\n\n" 13218 "The Dumb Artist Library (TX Library)\n" 13219 _TX_VERSION "\n" _TX_AUTHOR "\n" 13220 "See license on: http://txlib.ru\n\n" 13221 13222 "TXLib file:" "\t" __FILE__ "\n" 13223 "Compiled:" "\t" __DATE__ " " __TIME__ ", " __TX_COMPILER__ ", %s, %d-bit, " _TX_BUILDMODE "\n" 13224 "Started:" "\t" "%.6s %.4s %.8s\n\n" 13225 13226 "Run file:" "\t" "%s\n" 13227 "Directory:" "\t" "%s", 13228 13229 #if defined (_MSC_VER) 13230 "MSVC Runtime", 13231 #elif defined (__CYGWIN__) 13232 "Cygwin Runtime", 13233 #elif defined (_GCC_VER) && defined (_WIN64) 13234 __mingw_get_crt_info(), 13235 #else 13236 "MinGW Runtime " TX_QUOTE (__MINGW32_MAJOR_VERSION) "." TX_QUOTE (__MINGW32_MINOR_VERSION), 13237 #endif 13238 (sizeof (void*) == sizeof (DWORD))? 32 : 64, //-V112 13239 13240 timeS + 4, timeS + 20, timeS + 11, //-V112 These offsets are ANSI standardized 13241 txGetModuleFileName(), 13242 _getcwd (cwd, sizeof (cwd) - 1)); 13243 13244 return text; 13245 } 13246 13247 //} 13248 //----------------------------------------------------------------------------------------------------------------- 13249 13251 //} 13252 //================================================================================================================= 13253 13254 //================================================================================================================= 13255 //{ TXLib API implementation 13256 // Реализация TXLib API 13257 //================================================================================================================= 13258 13259 inline const char* txVersion() 13260 { 13261 return _TX_VERSION; 13262 } 13263 13264 //----------------------------------------------------------------------------------------------------------------- 13265 13266 inline unsigned txVersionNumber() 13267 { 13268 return _TX_VER; //-V2517 13269 } 13270 13271 //----------------------------------------------------------------------------------------------------------------- 13272 13273 inline HWND txWindow() 13274 { 13275 $9 return _txCanvas_Window; 13276 } 13277 13278 //----------------------------------------------------------------------------------------------------------------- 13279 13280 inline HDC& txDC() 13281 { 13282 return _txCanvas_BackBuf[0]; 13283 } 13284 13285 //----------------------------------------------------------------------------------------------------------------- 13286 13287 inline RGBQUAD* txVideoMemory() 13288 { 13289 return _txCanvas_Pixels; 13290 } 13291 13292 //----------------------------------------------------------------------------------------------------------------- 13293 13294 inline int txGetExtentX (HDC dc /*= txDC()*/) 13295 { 13296 return txGetExtent (dc) .x; 13297 } 13298 13299 //----------------------------------------------------------------------------------------------------------------- 13300 13301 inline int txGetExtentY (HDC dc /*= txDC()*/) 13302 { 13303 return txGetExtent (dc) .y; 13304 } 13305 13306 //----------------------------------------------------------------------------------------------------------------- 13307 13308 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 13309 13310 POINT txGetExtent (HDC dc /*= txDC()*/) 13311 { 13312 $0 static POINT err = {-1, -1}; 13313 13314 if (!dc) {$ POINT screen = { GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN) }; return screen; }; 13315 13316 if (_TX_DEFAULT_HDC_FAILED (dc)) {$ return err; } 13317 13318 $ BITMAP bmap = {}; 13319 $ txGDI (Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap), dc) asserted; 13320 13321 $ POINT size = { bmap.bmWidth, bmap.bmHeight }; 13322 $ return size; 13323 } 13324 13325 //----------------------------------------------------------------------------------------------------------------- 13326 13327 bool txDestroyWindow (HWND wnd /*= txWindow()*/) 13328 { 13329 $1 if (!wnd || !txWindow()) return false; 13330 13331 $ if (wnd != txWindow()) 13332 { 13333 $ return !!SendNotifyMessage (txWindow(), _TX_WM_DESTROYWND, 0, (LPARAM) wnd); 13334 } 13335 13336 $ if (SendNotifyMessage (txWindow(), (_txMain? WM_CLOSE : WM_DESTROY), 0, 0) == 0) return false; 13337 13338 $ if (_txMain) 13339 { 13340 $ txNotifyIcon (NIIF_WARNING, NULL, "\n" "Очень, очень плохо завершать программу через txDestroyWindow().\n\n" 13341 "Возвращайтесь через main(), там вам будут рады.\n"); 13342 $ Sleep (_TX_TIMEOUT); 13343 } 13344 13345 $ _txWaitFor (!_txCanvas_Window, _TX_TIMEOUT); 13346 13347 $ return _txCanvas_Window == NULL; 13348 } 13349 13350 //----------------------------------------------------------------------------------------------------------------- 13351 13352 HPEN txSetColor (COLORREF color, double thickness /*= 1*/, HDC dc /*= txDC()*/) 13353 { 13354 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13355 13356 $ HPEN pen = Win32::CreatePen ((color == TX_TRANSPARENT? PS_NULL : PS_SOLID), ROUND (thickness), color); 13357 13358 $ if (!pen) return (HPEN) NULL; 13359 13360 $ if (!_txBuffer_Select (pen, dc)) 13361 { 13362 $ Win32::DeleteObject (pen); 13363 $ return (HPEN) NULL; 13364 } 13365 13366 $ if (txGDI (Win32::SetTextColor (dc, color), dc) == CLR_INVALID) 13367 {$ return (HPEN) NULL; } 13368 13369 $ return pen; 13370 } 13371 13372 //----------------------------------------------------------------------------------------------------------------- 13373 13374 COLORREF txColor (double red, double green, double blue) 13375 { 13376 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13377 $ if (green > 1) green = 1; if (green < 0) green = 0; 13378 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13379 13380 $ COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)); 13381 13382 $ return txSetColor (color)? color : CLR_INVALID; 13383 } 13384 13385 //----------------------------------------------------------------------------------------------------------------- 13386 13387 COLORREF txGetColor (HDC dc /*= txDC()*/) 13388 { 13389 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13390 13391 $ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_PEN)), dc); 13392 $ assert (obj); if (!obj) return CLR_INVALID; //-V547 13393 13394 $ union { EXTLOGPEN extLogPen; LOGPEN LogPen; } buf = {}; //-V2514 13395 13396 $ int size = Win32::GetObject (obj, 0, NULL); 13397 $ Win32::GetObject (obj, sizeof (buf), &buf) asserted; 13398 13399 $ return (size == sizeof (LOGPEN))? buf.LogPen.lopnColor : buf.extLogPen.elpColor; 13400 } 13401 13402 //----------------------------------------------------------------------------------------------------------------- 13403 13404 HBRUSH txSetFillColor (COLORREF color, HDC dc /*= txDC()*/) 13405 { 13406 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13407 13408 $ HBRUSH brush = (color == TX_TRANSPARENT)? (HBRUSH) Win32::GetStockObject (HOLLOW_BRUSH) : Win32::CreateSolidBrush (color); 13409 13410 $ return (_txBuffer_Select (brush, dc))? brush : (Win32::DeleteObject (brush), (HBRUSH) NULL); 13411 } 13412 13413 //----------------------------------------------------------------------------------------------------------------- 13414 13415 COLORREF txFillColor (double red, double green, double blue) 13416 { 13417 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13418 $ if (green > 1) green = 1; if (green < 0) green = 0; 13419 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13420 13421 $ COLORREF color = RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)); 13422 13423 $ return txSetFillColor (color)? color : CLR_INVALID; 13424 } 13425 13426 //----------------------------------------------------------------------------------------------------------------- 13427 13428 COLORREF txGetFillColor (HDC dc /*= txDC()*/) 13429 { 13430 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13431 13432 $ HGDIOBJ obj = txGDI ((Win32::GetCurrentObject (dc, OBJ_BRUSH)), dc); 13433 $ assert (obj); if (!obj) return CLR_INVALID; //-V547 13434 13435 $ LOGBRUSH buf = {}; 13436 $ txGDI ((Win32::GetObject (obj, sizeof (buf), &buf)), dc) asserted; 13437 13438 $ return buf.lbColor; 13439 } 13440 13441 //----------------------------------------------------------------------------------------------------------------- 13442 13443 bool txClear (HDC dc /*= txDC()*/) 13444 { 13445 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13446 13447 $ POINT size = txGetExtent (dc); 13448 $ return txGDI (!!(Win32::PatBlt (dc, 0, 0, size.x, size.y, PATCOPY)), dc); 13449 } 13450 13451 //----------------------------------------------------------------------------------------------------------------- 13452 13453 bool txSetPixel (double x, double y, COLORREF color, HDC dc /*= txDC()*/) 13454 { 13455 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13456 13457 $ txGDI ((Win32::SetPixel (dc, ROUND (x), ROUND (y), color)), dc); 13458 13459 $ return true; 13460 } 13461 13462 //----------------------------------------------------------------------------------------------------------------- 13463 13464 bool txPixel (double x, double y, double red, double green, double blue, HDC dc /*= txDC()*/) 13465 { 13466 $1 if (red > 1) red = 1; if (red < 0) red = 0; 13467 $ if (green > 1) green = 1; if (green < 0) green = 0; 13468 $ if (blue > 1) blue = 1; if (blue < 0) blue = 0; 13469 13470 $ return txSetPixel (x, y, RGB (ROUND (red * 255), ROUND (green * 255), ROUND (blue * 255)), dc); 13471 } 13472 13473 //----------------------------------------------------------------------------------------------------------------- 13474 13475 COLORREF txGetPixel (double x, double y, HDC dc /*= txDC()*/) 13476 { 13477 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return CLR_INVALID; 13478 13479 $ return txGDI ((Win32::GetPixel (dc, ROUND (x), ROUND (y))), dc); 13480 } 13481 13482 //----------------------------------------------------------------------------------------------------------------- 13483 13484 bool txLine (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13485 { 13486 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13487 13488 $ bool ok = txGDI ((Win32::MoveToEx (dc, ROUND (x0), ROUND (y0), NULL)), dc); 13489 $ ok &= txGDI ((Win32::LineTo (dc, ROUND (x1), ROUND (y1) )), dc); 13490 13491 $ return ok; 13492 } 13493 13494 //----------------------------------------------------------------------------------------------------------------- 13495 13496 bool txRectangle (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13497 { 13498 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13499 13500 $ return txGDI ((Win32::Rectangle (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc); 13501 } 13502 13503 //----------------------------------------------------------------------------------------------------------------- 13504 13505 bool txPolygon (const POINT points[], int numPoints, HDC dc /*= txDC()*/) 13506 { 13507 $1 if (_TX_ARGUMENT_FAILED (points)) return false; 13508 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13509 13510 $ return txGDI (!!(Win32::Polygon (dc, points, numPoints)), dc); 13511 } 13512 13513 //----------------------------------------------------------------------------------------------------------------- 13514 13515 bool txEllipse (double x0, double y0, double x1, double y1, HDC dc /*= txDC()*/) 13516 { 13517 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13518 13519 $ return txGDI ((Win32::Ellipse (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1))), dc); 13520 } 13521 13522 //----------------------------------------------------------------------------------------------------------------- 13523 13524 bool txCircle (double x, double y, double r) 13525 { 13526 $1 return txEllipse (x-r, y-r, x+r, y+r); 13527 } 13528 13529 //----------------------------------------------------------------------------------------------------------------- 13530 13531 bool txArc (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13532 { 13533 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13534 13535 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13536 13537 $ double start = startAngle * txPI/180, 13538 end = (startAngle + totalAngle) * txPI/180; 13539 13540 $ return txGDI (!!(Win32::Arc (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13541 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13542 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13543 } 13544 13545 //----------------------------------------------------------------------------------------------------------------- 13546 13547 bool txPie (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13548 { 13549 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13550 13551 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13552 13553 $ double start = startAngle * txPI/180, 13554 end = (startAngle + totalAngle) * txPI/180; 13555 13556 $ return txGDI (!!(Win32::Pie (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13557 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13558 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13559 } 13560 13561 //----------------------------------------------------------------------------------------------------------------- 13562 13563 bool txChord (double x0, double y0, double x1, double y1, double startAngle, double totalAngle, HDC dc /*= txDC()*/) 13564 { 13565 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13566 13567 $ POINT center = { ROUND ((x0 + x1) /2), ROUND ((y0 + y1) /2) }; 13568 13569 $ double start = startAngle * txPI/180, 13570 end = (startAngle + totalAngle) * txPI/180; 13571 13572 $ return txGDI (!!(Win32::Chord (dc, ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1), 13573 ROUND (center.x + 1E3*cos (start)), ROUND (center.y - 1E3*sin (start)), 13574 ROUND (center.x + 1E3*cos (end)), ROUND (center.y - 1E3*sin (end)))), dc); 13575 } 13576 13577 //----------------------------------------------------------------------------------------------------------------- 13578 13579 bool txFloodFill (double x, double y, 13580 COLORREF color /*= TX_TRANSPARENT*/, DWORD mode /*= FLOODFILLSURFACE*/, HDC dc /*= txDC()*/) 13581 { 13582 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13583 13584 $ if (color == TX_TRANSPARENT) color = txGetPixel (x, y, dc); 13585 13586 $ return txGDI (!!(Win32::ExtFloodFill (dc, ROUND (x), ROUND (y), color, mode)), dc); 13587 } 13588 13589 //----------------------------------------------------------------------------------------------------------------- 13590 13591 bool txTextOut (double x, double y, const char text[], HDC dc /*= txDC()*/) 13592 { 13593 $1 if (_TX_ARGUMENT_FAILED (text)) return false; 13594 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13595 13596 $ int len = (int) strlen (text); //-V202 13597 $ bool ok = txGDI (!!(Win32::TextOut (dc, ROUND (x), ROUND (y), text, len)), dc); 13598 13599 $ return ok; 13600 } 13601 13602 //----------------------------------------------------------------------------------------------------------------- 13603 13604 bool txDrawText (double x0, double y0, double x1, double y1, const char text[], 13605 unsigned format /*= DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS*/, 13606 HDC dc /*= txDC()*/) 13607 { 13608 $1 if (_TX_ARGUMENT_FAILED (text)) return false; 13609 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13610 13611 #if !defined (NDEBUG) 13612 13613 $ if (x0 > x1) 13614 { 13615 $ SetLastError (ERROR_INVALID_DATA); 13616 $ TX_ERROR ("Параметр x0 = %g больше, чем x1 = %g. Текст выводиться не будет.", x0, x1); 13617 } 13618 13619 $ if (y0 > y1) 13620 { 13621 $ SetLastError (ERROR_INVALID_DATA); 13622 $ TX_ERROR ("Параметр y0 = %g больше, чем y1 = %g. Текст выводиться не будет.", y0, y1); 13623 } 13624 13625 #endif 13626 13627 $ RECT r = { ROUND (x0), ROUND (y0), ROUND (x1), ROUND (y1) }; 13628 13629 $ if (!strchr (text, '\n')) format |= DT_SINGLELINE; 13630 13631 $ unsigned prev = txSetTextAlign (TA_LEFT | TA_TOP | TA_NOUPDATECP, dc); 13632 13633 $ bool ok = false; 13634 13635 $ if (Win32::DrawText) 13636 { 13637 $ ok = !!txGDI ((Win32::DrawText (dc, text, -1, &r, format)), dc); 13638 $ Win32::GetPixel (dc, 0, 0); 13639 $ ok = true; //-V519 13640 } 13641 else 13642 { 13643 $ txTextOut ((x0 + x1) / 2, (y0 + y1) / 2, text); 13644 $ ok = false; 13645 } 13646 13647 $ txSetTextAlign (prev, dc); 13648 13649 $ return ok; 13650 } 13651 13652 //----------------------------------------------------------------------------------------------------------------- 13653 13654 HFONT txSelectFont (const char name[], double sizeY, double sizeX /*= -1*/, 13655 int bold /*= FW_DONTCARE*/, bool italic /*= false*/, bool underline /*= false*/, 13656 bool strikeout /*= false*/, double angle /*= 0*/, 13657 HDC dc /*= txDC()*/) 13658 { 13659 $1 if (_TX_ARGUMENT_FAILED (name)) return NULL; 13660 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return NULL; 13661 13662 $ HFONT font = txFontExist (name)? 13663 Win32::CreateFont (ROUND (sizeY), ROUND ((sizeX >= 0)? sizeX : sizeY/3), 13664 ROUND (angle*10), 0, bold, italic, underline, strikeout, 13665 RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 13666 DEFAULT_QUALITY, DEFAULT_PITCH, name) 13667 : 13668 (HFONT) Win32::GetStockObject (SYSTEM_FIXED_FONT); 13669 13670 $ _txBuffer_Select (font, dc); 13671 13672 $ return font; 13673 } 13674 13675 //----------------------------------------------------------------------------------------------------------------- 13676 13677 SIZE txGetTextExtent (const char text[], HDC dc /*= txDC()*/) 13678 { 13679 $1 SIZE size = {-1, -1}; 13680 13681 $ if (_TX_ARGUMENT_FAILED (text)) return size; 13682 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return size; 13683 13684 $ size_t len = strlen (text); 13685 $ txGDI ((Win32::GetTextExtentPoint32 (dc, text, (int) len, &size)), dc) asserted; //-V202 13686 13687 $ return size; 13688 } 13689 13690 //----------------------------------------------------------------------------------------------------------------- 13691 13692 int txGetTextExtentX (const char text[], HDC dc /*= txDC()*/) 13693 { 13694 $1 return txGetTextExtent (text, dc) .cx; 13695 } 13696 13697 //----------------------------------------------------------------------------------------------------------------- 13698 13699 int txGetTextExtentY (const char text[], HDC dc /*= txDC()*/) 13700 { 13701 $1 return txGetTextExtent (text, dc) .cy; 13702 } 13703 13704 //----------------------------------------------------------------------------------------------------------------- 13705 13706 unsigned txSetTextAlign (unsigned align /*= TA_CENTER | TA_BASELINE*/, HDC dc /*= txDC()*/) 13707 { 13708 $1 if (_TX_DEFAULT_HDC_FAILED (dc)) return false; //-V601 13709 13710 $ return txGDI ((Win32::SetTextAlign (dc, align)), dc); 13711 } 13712 13713 //----------------------------------------------------------------------------------------------------------------- 13714 13715 LOGFONT* txFontExist (const char name[]) 13716 { 13717 $1 if (_TX_ARGUMENT_FAILED (name)) return NULL; 13718 13719 $ static LOGFONT font = {}; 13720 $ font.lfCharSet = DEFAULT_CHARSET; 13721 $ strncpy_s (font.lfFaceName, sizeof (font.lfFaceName), name, sizeof (font.lfFaceName) - 1); 13722 13723 $ struct tools 13724 { 13725 static int CALLBACK enumFonts (const LOGFONT* fnt, const TEXTMETRIC*, DWORD, LPARAM data) 13726 { 13727 $ if (_TX_ARGUMENT_FAILED (fnt)) return 0; 13728 $ if (_TX_ARGUMENT_FAILED (data)) return 0; 13729 13730 #ifndef __STRICT_ANSI__ 13731 $ return _strnicmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE); 13732 13733 #else 13734 $ return strncmp (fnt->lfFaceName, ((LOGFONT*)data)->lfFaceName, LF_FACESIZE); 13735 13736 #endif 13737 } 13738 }; 13739 13740 $ return txGDI ((Win32::EnumFontFamiliesEx (NULL, &font, tools::enumFonts, (LPARAM) &font, 0)), NULL) == 0? &font : NULL; 13741 } 13742 13743 //----------------------------------------------------------------------------------------------------------------- 13744 13745 bool txSelectObject (HGDIOBJ obj, HDC dc /*= txDC()*/) 13746 { 13747 $1 if (_TX_ARGUMENT_FAILED (obj)) return false; 13748 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 13749 13750 $ return _txBuffer_Select (obj, dc); 13751 } 13752 13753 //----------------------------------------------------------------------------------------------------------------- 13754 13755 HDC txCreateCompatibleDC (double sizeX, double sizeY, HBITMAP bitmap /*= NULL*/, RGBQUAD** pixels /*= NULL*/) 13756 { 13757 $1 POINT size = { ROUND (sizeX), ROUND (sizeY) }; 13758 13759 $ HDC dc = _txBuffer_Create (NULL, &size, bitmap, pixels); 13760 $ assert (dc); if (!dc) return NULL; //-V547 13761 13762 $ txSetDefaults (dc); 13763 13764 $ if (!_txCanvas_UserDCs) return dc; 13765 13766 $ txAutoLock _lock; 13767 $ _txCanvas_UserDCs->push_back (dc); 13768 13769 $ if (_txCanvas_UserDCs->size() >= _TX_BUFSIZE) 13770 {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загрузили уже %d HDC, системе может стать плохо.", (int) _txCanvas_UserDCs->size()); } //-V202 13771 13772 $ return dc; 13773 } 13774 13775 //----------------------------------------------------------------------------------------------------------------- 13776 13777 HDC txCreateDIBSection (double sizeX, double sizeY, RGBQUAD** pixels /*= NULL*/) 13778 { 13779 $1 return txCreateCompatibleDC (sizeX, sizeY, NULL, pixels); 13780 } 13781 13782 //----------------------------------------------------------------------------------------------------------------- 13783 13784 HDC txCreateDIBSection (double sizeX, double sizeY, COLORREF** pixels) 13785 { 13786 $1 return txCreateDIBSection (sizeX, sizeY, (RGBQUAD**) pixels); 13787 } 13788 13789 //----------------------------------------------------------------------------------------------------------------- 13790 13791 HDC txLoadImage (const char filename[], int sizeX /*= 0*/, int sizeY /*= 0*/, 13792 unsigned imageFlags /*= IMAGE_BITMAP*/, unsigned loadFlags /*= LR_LOADFROMFILE*/) 13793 { 13794 $1 if (_TX_ARGUMENT_FAILED (filename && *filename)) return NULL; 13795 13796 $ HBITMAP image = (HBITMAP) Win32::LoadImage ((loadFlags & LR_LOADFROMFILE)? NULL : GetModuleHandle (NULL), 13797 filename, imageFlags, sizeX, sizeY, loadFlags); 13798 $ if (!image) return NULL; 13799 13800 $ HDC dc = txCreateCompatibleDC (sizeX, sizeY, image); 13801 13802 $ if (!(loadFlags & LR_LOADFROMFILE)) return dc; 13803 13804 $ static std::map <std::string, unsigned> loadTimes; 13805 $ std::string file = filename; 13806 $ unsigned time = GetTickCount(); 13807 13808 $ if ((long) (time - loadTimes [file]) < _TX_TIMEOUT) 13809 {$ txNotifyIcon (NIIF_WARNING, NULL, "Вы загружаете \"%s\" слишком часто, программа будет тормозить.", filename); } 13810 13811 $ loadTimes [file] = time; 13812 13813 $ return dc; 13814 } 13815 13816 //----------------------------------------------------------------------------------------------------------------- 13817 13818 bool txDeleteDC (HDC* pdc) 13819 { 13820 $1 if (_TX_ARGUMENT_FAILED (pdc)) return false; 13821 13822 $ HDC dc = *pdc; 13823 $ bool ok = _txBuffer_Delete (pdc); 13824 $ if (!ok) return false; 13825 13826 $ if (!_txCanvas_UserDCs) return ok; 13827 13828 $ txAutoLock _lock; 13829 13830 $ for (std::vector <HDC> ::iterator it = _txCanvas_UserDCs->begin(); it != _txCanvas_UserDCs->end(); ++it) 13831 if (*it == dc) 13832 { 13833 $ std::swap (*it, _txCanvas_UserDCs->back()); 13834 $ _txCanvas_UserDCs->pop_back(); 13835 $ break; 13836 } 13837 13838 $ return ok; 13839 } 13840 13841 //----------------------------------------------------------------------------------------------------------------- 13842 13843 bool txDeleteDC (HDC dc) 13844 { 13845 $1 return txDeleteDC (&dc); 13846 } 13847 13848 //----------------------------------------------------------------------------------------------------------------- 13849 13850 bool txBitBlt (HDC destImage, double xDest, double yDest, double width, double height, 13851 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, unsigned operation /*= SRCCOPY*/) 13852 { 13853 $1 if (_TX_HDC_FAILED (destImage)) return false; 13854 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13855 13856 $ POINT size = txGetExtent (sourceImage); 13857 $ if (!width) width = size.x; //-V550 13858 $ if (!height) height = size.y; //-V550 13859 13860 $ return txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13861 sourceImage, ROUND (xSource), ROUND (ySource), operation)), destImage); 13862 } 13863 13864 //----------------------------------------------------------------------------------------------------------------- 13865 13866 bool txBitBlt (double xDest, double yDest, HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/) 13867 { 13868 $1 if (_TX_TXWINDOW_FAILED()) return false; 13869 13870 $ return txBitBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource); 13871 } 13872 13873 //----------------------------------------------------------------------------------------------------------------- 13874 13875 bool txTransparentBlt (HDC destImage, double xDest, double yDest, double width, double height, 13876 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, COLORREF transColor /*= TX_BLACK*/) 13877 { 13878 // Это проверки того, правильные ли HDC вы передали в функцию. 13879 // Не бойтесь долларов - <s>это не запрещенная валюта</s> это макросы для отладки TXLib'а. 13880 // При первом чтении это можно пропустить. 13881 13882 $1 if (_TX_HDC_FAILED (destImage)) return false; 13883 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13884 13885 // Это автоматическое определение размеров картинки (точнее, HDC источника - source) с помощью txGetExtent(). 13886 // При первом чтении это можно пропустить. 13887 13888 $ POINT size = txGetExtent (sourceImage); 13889 $ if (!width) width = size.x; //-V550 13890 $ if (!height) height = size.y; //-V550 13891 13892 // Это проверка того, что картинка (или ее часть) правильно попадает в окно (точнее, HDC приемника - destination, dest). 13893 // Если она "вылезает" из окна в любую сторону, то Win32::TransparentBlt() не будет работать. Эта проверка происходит только 13894 // в режиме отладки (когда не задан макрос NDEBUG - No Debugging, без отладки). 13895 // При первом чтении это можно пропустить. 13896 13897 #if !defined (NDEBUG) 13898 13899 $ if (!(0 <= xSource && xSource + width <= size.x && 13900 0 <= ySource && ySource + height <= size.y)) 13901 { 13902 $ SetLastError (ERROR_INVALID_DATA); 13903 $ TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, " 13904 "функция txTransparentBlt() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y); 13905 } 13906 13907 #endif 13908 13909 $ bool ok = true; 13910 13911 $ if (Win32::TransparentBlt) 13912 { 13913 // А вот теперь уже надо начать читать. 13914 // 13915 // Ниже - это вызов стандартной Win32::TransparentBlt() из ядра Windows. Погуглите "Windows TransparentBlt function" 13916 // и почитайте про ее параметры. 13917 // 13918 // Как видите, оригинальная функция из Win32 принимает размеры не только исходной, но и итоговой картинки, и если они не 13919 // совпадают, то картинка будет уменьшена или увеличена. TXlib'овская <s>паленая</s> функция TransparentBlt предполагает, что 13920 // эти размеры всегда совпадают, и поэтому при работе с TransparentBlt() масштаб будет всегда 1:1. <s>Так себе решение, но</s> 13921 // это сделано для упрощения вызова функции TransparentBlt(). 13922 13923 // Только то, что эти параметры передаются одинаковыми, не дает возможность менять масштаб картинки! // <<-- 13924 // // <<-- 13925 // ||||| |||||| // <<-- 13926 // vvvvv vvvvvv // <<-- 13927 // <<-- 13928 $ ok &= txGDI (!!(Win32::TransparentBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), // <<<< 13929 sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), transColor)), // <<<< 13930 destImage); // <<-- 13931 // ^^^^^ ^^^^^^ // <<-- 13932 // ||||| |||||| // <<-- 13933 // // <<-- 13934 } // См. "TransparentBlt function" в Google, ищите смысл параметров wSrc и wDest (hSrc и hDest). Думайте! // <<-- 13935 else 13936 { 13937 $ ok &= txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13938 sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)), 13939 destImage); 13940 } 13941 13942 // В TXLib-овской функции txTransparentBlt() проверок и комментариев больше, чем рабочего кода, и это как бы намекает, что 13943 // нетрудно сделать свою аналогичную функцию без ограничений масштаба отображения. <s>Если ты дочитал до этого места,</s> 13944 // пересядь с иглы TXLib'а на поверхность GDI Win32, <s>хотя GDI тоже так себе, так что лучше заюзай GDI+, SFML, OpenGL 13945 // или DirectX, будет круто. Хотя это и сложнее.</s> 13946 13947 // Пожалуйста, не надо бездумно копировать себе в программу код из TXLib'а. Осмыслите его и напишите свою функцию сами, 13948 // иначе вы породите невнятный паленый код и безнадежно испортите себе карму. :(( 13949 13950 $ return ok; 13951 } 13952 13953 //----------------------------------------------------------------------------------------------------------------- 13954 13955 bool txTransparentBlt (double xDest, double yDest, HDC sourceImage, 13956 COLORREF transColor /*= TX_BLACK*/, double xSource /*= 0*/, double ySource /*= 0*/) 13957 { 13958 $1 if (_TX_TXWINDOW_FAILED()) return false; 13959 13960 $ return txTransparentBlt (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, transColor); 13961 } 13962 13963 //----------------------------------------------------------------------------------------------------------------- 13964 13965 bool txAlphaBlend (HDC destImage, double xDest, double yDest, double width, double height, 13966 HDC sourceImage, double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/) 13967 { 13968 $1 if (_TX_HDC_FAILED (destImage)) return false; 13969 $ if (_TX_HDC_FAILED (sourceImage)) return false; 13970 13971 $ POINT size = txGetExtent (sourceImage); 13972 $ if (!width) width = size.x; //-V550 13973 $ if (!height) height = size.y; //-V550 13974 13975 #if !defined (NDEBUG) 13976 13977 $ if (!(0 <= xSource && xSource + width <= size.x && 13978 0 <= ySource && ySource + height <= size.y)) 13979 { 13980 $ SetLastError (ERROR_INVALID_DATA); 13981 $ TX_ERROR ("Прямоугольник копируемой области {%g, %g, %g, %g} не полностью лежит внутри изображения-источника {%d, %d, %d, %d}, " 13982 "функция txAlphaBlend() работать не будет.", xSource, ySource, xSource + width, ySource + height, 0, 0, (int) size.x, (int) size.y); 13983 } 13984 13985 #endif 13986 13987 $ if (alpha < 0) alpha = 0; 13988 $ if (alpha > 1) alpha = 1; 13989 13990 $ BITMAP bmap = { 0, 0, 0, 0, 0, 24 }; 13991 $ bool ok = !!Win32::GetObject (txGDI ((Win32::GetCurrentObject (sourceImage, OBJ_BITMAP)), sourceImage), sizeof (bmap), &bmap); 13992 13993 $ BLENDFUNCTION blend = { AC_SRC_OVER, 0, (BYTE) ROUND (alpha * 255), (BYTE) ((bmap.bmBitsPixel == 32)? AC_SRC_ALPHA : 0) }; //-V112 //-V821 //-V2551 13994 13995 $ if (Win32::AlphaBlend) 13996 { 13997 $ ok &= txGDI (!!(Win32::AlphaBlend (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 13998 sourceImage, ROUND (xSource), ROUND (ySource), ROUND (width), ROUND (height), blend)), 13999 destImage); 14000 } 14001 else 14002 { 14003 $ ok &= txGDI (!!(Win32::BitBlt (destImage, ROUND (xDest), ROUND (yDest), ROUND (width), ROUND (height), 14004 sourceImage, ROUND (xSource), ROUND (ySource), SRCCOPY)), 14005 destImage); 14006 $ ok = false; //-V519 14007 } 14008 14009 $ return ok; 14010 } 14011 14012 //----------------------------------------------------------------------------------------------------------------- 14013 14014 bool txAlphaBlend (double xDest, double yDest, HDC sourceImage, 14015 double xSource /*= 0*/, double ySource /*= 0*/, double alpha /*= 1.0*/) 14016 { 14017 $1 if (_TX_TXWINDOW_FAILED()) return false; 14018 14019 $ return txAlphaBlend (txDC(), xDest, yDest, 0, 0, sourceImage, xSource, ySource, alpha); 14020 } 14021 14022 //----------------------------------------------------------------------------------------------------------------- 14023 14024 HDC txUseAlpha (HDC image) 14025 { 14026 $1 if (_TX_HDC_FAILED (image)) return NULL; 14027 14028 $ HBITMAP bitmap = (HBITMAP) Win32::GetCurrentObject (image, OBJ_BITMAP); 14029 $ if (!bitmap) return NULL; 14030 14031 $ DIBSECTION dib = {}; 14032 $ Win32::GetObject (bitmap, sizeof (dib), &dib) asserted; 14033 14034 $ POINT size = { dib.dsBm.bmWidth, dib.dsBm.bmHeight }; 14035 $ BITMAPINFO info = {{ sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }}; 14036 $ RGBQUAD* buf = NULL; 14037 14038 $ bool isDIB = (dib.dsBm.bmPlanes == 1 && 14039 dib.dsBm.bmBitsPixel == sizeof (RGBQUAD) * 8 && 14040 dib.dsBmih.biCompression == DIB_RGB_COLORS && 14041 dib.dsBm.bmBits); 14042 $ if (!isDIB) 14043 { 14044 $ buf = new (std::nothrow) RGBQUAD [size.x * size.y]; //-V121 14045 $ if (!buf) return NULL; 14046 14047 $ Win32::GetDIBits (image, bitmap, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted; 14048 } 14049 else 14050 { 14051 $ buf = (RGBQUAD*) dib.dsBm.bmBits; 14052 } 14053 14054 $ for (int y = 0; y < size.y; y++) 14055 for (int x = 0; x < size.x; x++) 14056 { 14057 RGBQUAD* color = &buf [x + y * size.x]; // Get color at (x, y) within image buffer //-V108 14058 14059 color->rgbRed = (BYTE) ROUND (color->rgbRed * color->rgbReserved / 255.0); 14060 color->rgbGreen = (BYTE) ROUND (color->rgbGreen * color->rgbReserved / 255.0); 14061 color->rgbBlue = (BYTE) ROUND (color->rgbBlue * color->rgbReserved / 255.0); 14062 } 14063 14064 $ if (!isDIB) 14065 { 14066 $ Win32::SetDIBitsToDevice (image, 0, 0, size.x, size.y, 0, 0, 0, size.y, buf, &info, DIB_RGB_COLORS) asserted; 14067 14068 $ delete[] buf; 14069 } 14070 14071 $ return image; 14072 } 14073 14074 //----------------------------------------------------------------------------------------------------------------- 14075 14076 bool txSaveImage (const char filename[], HDC dc /*= txDC()*/) 14077 { 14078 $1 if (_TX_ARGUMENT_FAILED (filename)) return false; 14079 $ if (_TX_DEFAULT_HDC_FAILED (dc)) return false; 14080 14081 $ POINT size = txGetExtent (dc); 14082 14083 $ size_t szHdrs = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), //-V119 14084 szImg = (size.x * size.y) * sizeof (RGBQUAD); //-V104 14085 14086 $ BITMAP bmap = {}; 14087 $ BITMAPFILEHEADER hdr = { 0x4D42 /* 'MB' */, (DWORD) (szHdrs + szImg), 0, 0, (DWORD) szHdrs }; //-V202 14088 $ BITMAPINFOHEADER info = { sizeof (info), size.x, size.y, 1, (WORD) (sizeof (RGBQUAD) * 8), BI_RGB }; 14089 14090 $ RGBQUAD* buf = NULL; 14091 $ bool ok = true; 14092 14093 $ ok &= !!Win32::GetObject (Win32::GetCurrentObject (dc, OBJ_BITMAP), sizeof (bmap), &bmap); 14094 14095 if (!ok) {$ return false; } 14096 14097 $ if (!bmap.bmBits) 14098 { 14099 $ buf = new (std::nothrow) RGBQUAD [size.x * size.y]; //-V121 14100 $ ok &= (buf != NULL); 14101 14102 $ int res = Win32::GetDIBits (dc, (HBITMAP) Win32::GetCurrentObject (dc, OBJ_BITMAP), 0, size.y, 14103 buf, (BITMAPINFO*) &info, DIB_RGB_COLORS); 14104 14105 if (res == ERROR_INVALID_PARAMETER) {$ SetLastError (res); } 14106 14107 $ ok &= !!res; 14108 } 14109 else 14110 { 14111 $ buf = (RGBQUAD*) bmap.bmBits; 14112 } 14113 14114 $ FILE* f = NULL; 14115 $ if (ok) fopen_s (&f, filename, "wb"); 14116 $ ok &= (f != NULL); 14117 14118 $ if (ok) ok &= (fwrite (&hdr, sizeof (hdr), 1, f) == 1); //-V575 //-V595 14119 $ if (ok) ok &= (fwrite (&info, sizeof (info), 1, f) == 1); 14120 $ if (ok) ok &= (fwrite (buf, szImg, 1, f) == 1); //-V575 14121 14122 $ ok &= (f && fclose (f) == 0); 14123 14124 $ if (!bmap.bmBits) 14125 { 14126 $ delete[] buf; 14127 $ buf = NULL; 14128 } 14129 14130 $ return ok; 14131 } 14132 14133 //----------------------------------------------------------------------------------------------------------------- 14134 14135 double txSleep (double time) 14136 { 14137 $1 LARGE_INTEGER start = {}; 14138 $ QueryPerformanceCounter (&start) asserted; 14139 14140 $ LARGE_INTEGER freq = {}; 14141 $ QueryPerformanceFrequency (&freq) asserted; 14142 14143 $ int lock = _txCanvas_RefreshLock; 14144 $ _txCanvas_RefreshLock = 0; 14145 14146 $ HWND wnd = txWindow(); 14147 if (wnd) {$ RedrawWindow (wnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW); } 14148 14149 $ Sleep (ROUND ((time >= 0)? time : 0)); 14150 14151 $ _txCanvas_RefreshLock = lock; 14152 14153 $ LARGE_INTEGER stop = {}; 14154 $ QueryPerformanceCounter (&stop) asserted; 14155 14156 $ return 1000.0 * (double) (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart; 14157 } 14158 14159 //----------------------------------------------------------------------------------------------------------------- 14160 14161 bool txLock (bool wait /*= true*/) 14162 { 14163 $0 if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0); 14164 14165 $ if (wait) {$ return EnterCriticalSection (&_txCanvas_LockBackBuf), true; } //-V1048 14166 else {$ return !!TryEnterCriticalSection (&_txCanvas_LockBackBuf); } 14167 } 14168 14169 //----------------------------------------------------------------------------------------------------------------- 14170 14171 bool txUnlock() 14172 { 14173 $0 LeaveCriticalSection (&_txCanvas_LockBackBuf); 14174 14175 $ if (_txCanvas_RefreshLock <= 0 || _txExit) Sleep (0); 14176 $ return false; 14177 } 14178 14179 #endif // TX_COMPILED 14180 14181 //----------------------------------------------------------------------------------------------------------------- 14182 14183 template <typename T> 14184 inline T txUnlock (T value) 14185 { 14186 $1 txUnlock(); 14187 $ return value; 14188 } 14189 14190 //----------------------------------------------------------------------------------------------------------------- 14191 14192 inline void txRedrawWindow() 14193 { 14194 $1 txSleep (0); 14195 } 14196 14197 //----------------------------------------------------------------------------------------------------------------- 14198 14199 inline int txUpdateWindow (int update /*= true*/) 14200 { 14201 $1 return _txCanvas_SetRefreshLock (update >= 0? (int) !update : -update); 14202 } 14203 14204 //----------------------------------------------------------------------------------------------------------------- 14205 14206 inline int txBegin() 14207 { 14208 $1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock + 1); 14209 14210 $ return _txCanvas_RefreshLock; 14211 } 14212 14213 //----------------------------------------------------------------------------------------------------------------- 14214 14215 inline int txEnd() 14216 { 14217 $1 _txCanvas_SetRefreshLock (_txCanvas_RefreshLock - 1); 14218 14219 $ return _txCanvas_RefreshLock; 14220 } 14221 14222 //----------------------------------------------------------------------------------------------------------------- 14223 14224 inline POINT txMousePos() 14225 { 14226 $1 POINT pos = {}; 14227 $ GetCursorPos (&pos); 14228 14229 $ if (txWindow()) 14230 {$ ScreenToClient (txWindow(), &pos); } 14231 14232 $ return pos; 14233 } 14234 14235 //----------------------------------------------------------------------------------------------------------------- 14236 14237 inline double txMouseX() 14238 { 14239 return (double) txMousePos() .x; 14240 } 14241 14242 //----------------------------------------------------------------------------------------------------------------- 14243 14244 inline double txMouseY() 14245 { 14246 return (double) txMousePos() .y; 14247 } 14248 14249 //----------------------------------------------------------------------------------------------------------------- 14250 14251 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 14252 14253 unsigned txMouseButtons() 14254 { 14255 $1 HWND txWnd = txWindow(); 14256 $ HWND foreground = GetForegroundWindow(); 14257 14258 $ if ((txWnd && (foreground == txWnd)) || 14259 (!txWnd && (foreground == Win32::GetConsoleWindow()))) 14260 { 14261 $ return ((GetAsyncKeyState (VK_LBUTTON) & 0x8000) >> 15) | // MSB to bit 0 14262 ((GetAsyncKeyState (VK_RBUTTON) & 0x8000) >> 14) | // MSB to bit 1 14263 ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) >> 13); // MSB to bit 2 14264 } 14265 else 14266 {$ return 0; } 14267 } 14268 14269 //----------------------------------------------------------------------------------------------------------------- 14270 14271 unsigned txSetConsoleAttr (unsigned color /*= FOREGROUND_LIGHTGRAY*/) 14272 { 14273 unsigned oldAttr = txGetConsoleAttr(); 14274 14275 SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) color); 14276 SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE), (WORD) color); 14277 14278 return oldAttr; 14279 } 14280 14281 //----------------------------------------------------------------------------------------------------------------- 14282 14283 unsigned txGetConsoleAttr() 14284 { 14285 CONSOLE_SCREEN_BUFFER_INFO con = {}; 14286 con.wAttributes = FOREGROUND_LIGHTGRAY; 14287 14288 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) || 14289 GetConsoleScreenBufferInfo (GetStdHandle (STD_ERROR_HANDLE), &con); 14290 14291 return con.wAttributes; 14292 } 14293 14294 //----------------------------------------------------------------------------------------------------------------- 14295 14296 POINT txSetConsoleCursorPos (double x, double y) 14297 { 14298 $1 POINT fontSz = txGetConsoleFontSize(); 14299 14300 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14301 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14302 14303 $ COORD pos = { (short) ROUND (1.0 * x / fontSz.x + con.srWindow.Left), 14304 (short) ROUND (1.0 * y / fontSz.y + con.srWindow.Top ) }; 14305 14306 $ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos) asserted; 14307 14308 $ POINT prev = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x), 14309 ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) }; 14310 $ return prev; 14311 } 14312 14313 //----------------------------------------------------------------------------------------------------------------- 14314 14315 POINT txGetConsoleCursorPos() 14316 { 14317 $1 POINT fontSz = txGetConsoleFontSize(); 14318 14319 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14320 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14321 14322 $ POINT pos = { ROUND ((con.dwCursorPosition.X - con.srWindow.Left) * fontSz.x), 14323 ROUND ((con.dwCursorPosition.Y - con.srWindow.Top ) * fontSz.y) }; 14324 $ return pos; 14325 } 14326 14327 //----------------------------------------------------------------------------------------------------------------- 14328 14329 POINT txGetConsoleExtent() 14330 { 14331 $1 CONSOLE_SCREEN_BUFFER_INFO con = {}; 14332 $ GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &con) asserted; 14333 14334 $ POINT size = { con.srWindow.Right - con.srWindow.Left + 1, 14335 con.srWindow.Bottom - con.srWindow.Top + 1 }; 14336 $ return size; 14337 } 14338 14339 //----------------------------------------------------------------------------------------------------------------- 14340 14341 bool txClearConsole() 14342 { 14343 $1 HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE); 14344 14345 $ CONSOLE_SCREEN_BUFFER_INFO con = {}; 14346 $ GetConsoleScreenBufferInfo (out, &con) asserted; 14347 14348 $ COORD start = {con.srWindow.Left, con.srWindow.Top}; 14349 14350 $ DWORD len = (con.srWindow.Right - con.srWindow.Left + 1) * 14351 (con.srWindow.Bottom - con.srWindow.Top + 1); 14352 14353 $ DWORD written = 0; 14354 $ FillConsoleOutputCharacter (out, 0x20 /*' '*/, len, start, &written) asserted; //-V112 14355 $ FillConsoleOutputAttribute (out, con.wAttributes, len, start, &written) asserted; 14356 14357 $ SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), start) asserted; 14358 14359 $ return written == len; 14360 } 14361 14362 //----------------------------------------------------------------------------------------------------------------- 14363 14364 POINT txGetConsoleFontSize() 14365 { 14366 $1 Win32::CONSOLE_FONT_INFO font = {0, {8, 16}}; 14367 14368 $ _TX_CALL (Win32::GetCurrentConsoleFont, (GetStdHandle (STD_OUTPUT_HANDLE), false, &font)); 14369 14370 $ SIZE size = { font.dwFontSize.X, font.dwFontSize.Y }; 14371 if (_txCanvas_BackBuf[1]) {$ txGDI (Win32::GetTextExtentPoint32 (_txCanvas_BackBuf[1], "W", 1, &size), txDC()); } //-V501 14372 14373 if (size.cx == 0) {$ size.cx = 1; } 14374 if (size.cy == 0) {$ size.cy = 1; } 14375 14376 $ POINT sizeFont = { size.cx, size.cy }; 14377 $ return sizeFont; 14378 } 14379 14380 //----------------------------------------------------------------------------------------------------------------- 14381 14382 bool txTextCursor (bool blink /*= true*/) 14383 { 14384 $1 bool old = _txConsole_IsBlinking; 14385 14386 $ _txConsole_IsBlinking = blink; 14387 14388 $ return old; 14389 } 14390 14391 //----------------------------------------------------------------------------------------------------------------- 14392 14393 bool txPlaySound (const char filename[] /*= NULL*/, DWORD mode /*= SND_ASYNC*/) 14394 { 14395 $1 mode |= SND_FILENAME | SND_NODEFAULT | SND_NOWAIT; 14396 $ if (mode & SND_LOOP) mode = (mode & ~SND_SYNC) | SND_ASYNC; 14397 14398 $ if (!filename) mode = SND_PURGE; 14399 14400 $ return !!Win32::PlaySound (filename, NULL, mode); 14401 } 14402 14403 //----------------------------------------------------------------------------------------------------------------- 14404 14405 int txSpeak (const char* text, ...) 14406 { 14407 $1 bool verbose = false; (void) verbose; 14408 $ bool async = false; (void) async; 14409 14410 $ for (; text && *text; text++) 14411 { 14412 if (*text == '\a') {$ async = true; } 14413 else if (*text == '\v') {$ verbose = true; } 14414 else break; 14415 } 14416 14417 $ char textA [_TX_BUFSIZE] = "You asked to speak empty text. I would rather say that TX Library is cool! Cats rules!"; 14418 14419 $ va_list arg; va_start (arg, text); 14420 if (text && *text) {$ _tx_vsnprintf_s (textA, sizeof (textA) - 1, text, arg); } 14421 $ va_end (arg); 14422 14423 if (text && verbose) {$ printf ("%s", textA); } 14424 14425 #ifdef TX_USE_SPEAK 14426 14427 $ int time = GetTickCount(); 14428 14429 $ static wchar_t textW [_TX_BUFSIZE * sizeof (wchar_t)] = L""; 14430 $ MultiByteToWideChar (_TX_CODEPAGE, 0, textA, -1, textW, sizearr (textW)); 14431 14432 $ static ISpVoice* voice = NULL; 14433 14434 $ if (text && !voice) 14435 { 14436 $ HRESULT res = Win32::CoInitialize (NULL); 14437 if (res == S_OK) {$ Win32::CoCreateInstance (Win32::CLSID_SpVoice, NULL, CLSCTX_ALL, Win32::IID_ISpVoice, (void**) &voice); } 14438 } 14439 14440 $ if (text && voice) 14441 { 14442 $ Win32::_fpreset(); 14443 $ voice->Speak (textW, SPF_PERSIST_XML | SPF_PURGEBEFORESPEAK | ((*textW == '<')? SPF_IS_XML : 0) | (async? SPF_ASYNC : 0), NULL); 14444 $ tx_fpreset(); 14445 } 14446 14447 $ if (!text && voice) 14448 { 14449 $ voice->Release(); 14450 $ voice = NULL; 14451 14452 $ Win32::CoUninitialize(); 14453 } 14454 14455 $ return (voice)? GetTickCount() - time : -1; 14456 14457 #else 14458 14459 $ if (text) 14460 { 14461 $ unsigned oldAttr = txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK); 14462 14463 $ txNotifyIcon (NIIF_ERROR, "txSpeak(): Не могу произнести (нужен TX_USE_SPEAK, см. TXLib Help)", "\n" "%s", textA); 14464 14465 $ txSetConsoleAttr (oldAttr); 14466 } 14467 14468 $ return -1; 14469 14470 #endif 14471 } 14472 14473 //----------------------------------------------------------------------------------------------------------------- 14474 14475 intptr_t txPlayVideo (int x, int y, int width, int height, const char fileName[], 14476 double zoom /*= 0*/, double gain /*= 1*/, HWND wnd /*= txWindow()*/) 14477 { 14478 $1 if (wnd && wnd == txWindow() && _TX_TXWINDOW_FAILED()) return -1; 14479 14480 $ int time = GetTickCount(); //-V2551 14481 14482 $ static char processUID [64] = ""; 14483 if (!*processUID) 14484 { 14485 $ FILETIME startTime = {}, null = {}; 14486 $ GetProcessTimes (GetCurrentProcess(), &startTime, &null, &null, &null) asserted; 14487 $ _snprintf_s (processUID, sizeof (processUID) - 1, "TXLib[%08X%08X]::txPlayVideo", 14488 (unsigned) startTime.dwHighDateTime, (unsigned) startTime.dwLowDateTime) < (int) sizeof (processUID) asserted; 14489 } 14490 14491 $ if (!fileName) 14492 { 14493 $ _txTaskKill ("vlc.exe", processUID, 0); // Kill'em all, by command line pattern 14494 $ return 0; 14495 } 14496 14497 $ static const char* vlcPath = _txPlayVideo_FindVLC(); 14498 14499 $ if (!vlcPath || _access (vlcPath, 0) != 0) 14500 { 14501 $ static int once = false; //-V601 14502 14503 $ if (*fileName && !once++) 14504 {$ txOutputDebugPrintf ("\a" "Не найден видеопроигрыватель VideoLAN (vlc.exe). Cкачайте его с сайта VideoLAN.org " 14505 "и установите. Без установки VideoLAN видео воспроизводиться не будет :(\n\n" 14506 "--\n" "Всегда Ваша, функция " /* как бы */ "txPlayVideo()...\n" 14507 "P.S. См. мое описание в TXLib Help."); } 14508 $ return INT_MIN; //-V109 14509 } 14510 14511 $ bool async = false; 14512 if (*fileName == '\a') {$ async = true; fileName++; } 14513 14514 $ RECT rect = {}; 14515 if (wnd) {$ GetClientRect (wnd, &rect); } 14516 14517 if (!width) {$ width = rect.right; } 14518 if (!height) {$ height = rect.bottom; } 14519 14520 // Create a child window to hold the video stream 14521 14522 $ const char* errPos = "ВНЕЗАПНО"; 14523 14524 $ volatile HWND child = NULL; 14525 $ if (wnd && (wnd == txWindow())) 14526 { 14527 $ const char* wndClass = txRegisterClass ("txPlayVideo", _txPlayVideo_WndProc, 0, NULL_BRUSH, 1); 14528 14529 $ static int number = 1; 14530 $ CREATESTRUCT createData = { NULL, NULL, (HMENU) (size_t) number++, txWindow(), height, width, y, x, 14531 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, __func__, wndClass }; 14532 $ child = txCreateExtraWindow (createData); 14533 $ if (!child) 14534 { 14535 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s", 14536 strstr (_txError (NULL, 0, NULL, 0, "\f" "Не могу создать окно для видео :("), errPos)); 14537 $ return INT_MIN+3; //-V109 14538 } 14539 14540 $ BringWindowToTop (child); 14541 14542 $ wnd = child; 14543 } 14544 14545 // Build the command line 14546 14547 if (!zoom && !wnd) {$ zoom = 1; } 14548 14549 $ char sZoom [64] = "--autoscale"; 14550 if (zoom) {$ _snprintf_s (sZoom, sizeof (sZoom) - 1, "--no-autoscale --zoom=%.10g", zoom) < (int) sizeof (sZoom) asserted; } //-V550 14551 14552 $ static char cmd [MAX_PATH*2 + 1024] = ""; 14553 14554 $ _snprintf_s (cmd, sizeof (cmd) - 1, "\"%s\" \"%s\" vlc://quit" 14555 14556 " %s --gain=%.10g --drawable-hwnd=%p --video-title=\"%s\" --logfile=%s" 14557 14558 " --live-caching=500 --network-caching=500 --quiet-synchro --no-embedded-video --file-logging" 14559 14560 " --ignore-config --reset-config --no-one-instance --play-and-exit" 14561 " --intf=dummy --dummy-quiet --quiet --no-video-deco --no-video-title-show --no-stats --no-sub-autodetect-file" 14562 " --no-disable-screensaver --no-snapshot-preview --no-auto-preparse --no-mouse-events --no-keyboard-events", 14563 14564 vlcPath, (*fileName? fileName : "fileName"), sZoom, gain, (void*) wnd, processUID, _txLogName) < (int) sizeof (cmd) asserted; 14565 14566 $ txOutputDebugPrintf ("txPlayVideo (%d, %d, %d, %d, \"%s\", %g, %g, %p): [%s]\n\n", 14567 x, y, width, height, fileName, zoom, gain, (void*) wnd, cmd); 14568 $ if (!*fileName) 14569 { 14570 if (child) {$ txDestroyWindow (child); } 14571 $ return (intptr_t) cmd; 14572 } 14573 14574 $ if (!strstr (fileName, "://") && _access (fileName, 0) != 0) 14575 { 14576 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "\n" "%s", 14577 strstr (_txError (NULL, 0, NULL, 0, "\f" "Не найден файл \"%s\"", fileName), errPos)); 14578 14579 if (child) {$ txDestroyWindow (child); } 14580 $ return INT_MIN+1; //-V109 14581 } 14582 14583 // Run VLC, run 14584 14585 $ PROCESS_INFORMATION vlc = {}; 14586 $ STARTUPINFO start = { sizeof (start) }; 14587 $ DWORD ret = 0; 14588 14589 $ if (CreateProcess (NULL, cmd, NULL, NULL, true, 0, NULL, NULL, &start, &vlc) && 14590 vlc.hProcess && vlc.hThread) 14591 { 14592 $ if (child) 14593 { 14594 $ assert (wnd == child); //-V547 14595 $ SetWindowLongPtr (wnd, GWLP_USERDATA, (LONG_PTR) vlc.hProcess); //-V107 14596 } 14597 14598 $ if (!async) 14599 { 14600 $ WaitForSingleObject (vlc.hProcess, INFINITE); 14601 $ GetExitCodeProcess (vlc.hProcess, &ret) asserted; 14602 } 14603 14604 $ if (!child) 14605 { 14606 $ CloseHandle (vlc.hProcess) asserted; 14607 } 14608 14609 $ CloseHandle (vlc.hThread) asserted; 14610 14611 $ return (async? (intptr_t) wnd : (ret == 0)? time - GetTickCount() : - (int) ret); //-V105 14612 } 14613 else 14614 { 14615 $ txNotifyIcon (NIIF_ERROR, "txPlayVideo() сообщает", "%s", 14616 strstr (_txError (NULL, 0, NULL, 0, "\f" "Ошибка запуска VideoLAN (%s)", cmd), errPos)); 14617 $ if (child) 14618 {$ txDestroyWindow (child); } 14619 14620 $ return INT_MIN+4; //-V112 //-V109 14621 } 14622 14623 #undef PROCESS_UID_ 14624 } 14625 14626 //----------------------------------------------------------------------------------------------------------------- 14627 14628 intptr_t txPlayVideo (const char fileName[], double zoom /*= 0*/, double gain /*= 0*/, HWND wnd /*= txWindow()*/) 14629 { 14630 $1 return txPlayVideo (0, 0, 0, 0, fileName, zoom, gain, wnd); 14631 } 14632 14633 //----------------------------------------------------------------------------------------------------------------- 14634 14635 LRESULT CALLBACK _txPlayVideo_WndProc (HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) 14636 { 14637 const UINT_PTR checkTimer = 1; 14638 14639 switch (msg) 14640 { 14641 case WM_CREATE: 14642 { 14643 $1 SetTimer (wnd, checkTimer, 5*_txWindowUpdateInterval, NULL) asserted; 14644 } 14645 break; 14646 14647 case WM_DESTROY: 14648 { 14649 $1 KillTimer (wnd, checkTimer) asserted; 14650 14651 $ HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA); 14652 14653 $ if (vlc) 14654 { 14655 $ Win32::TerminateProcess (vlc, 0); 14656 14657 $ CloseHandle (vlc) asserted; 14658 14659 $ SetWindowLongPtr (wnd, GWLP_USERDATA, 0); 14660 } 14661 } 14662 break; 14663 14664 case WM_TIMER: 14665 { 14666 HANDLE vlc = (HANDLE)(uintptr_t) GetWindowLongPtr (wnd, GWLP_USERDATA); 14667 14668 if (vlc && WaitForSingleObject (vlc, 0) != WAIT_TIMEOUT) 14669 { 14670 $1 DestroyWindow (wnd) asserted; 14671 } 14672 } 14673 break; 14674 14675 default: //-V2522 14676 break; 14677 } 14678 14679 return DefWindowProc (wnd, msg, wpar, lpar); 14680 } 14681 14682 //----------------------------------------------------------------------------------------------------------------- 14683 14684 const char* _txPlayVideo_FindVLC() 14685 { 14686 $1 static char vlcPath [MAX_PATH] = ""; 14687 14688 $ if (SearchPath (NULL, "vlc.bat", NULL, sizeof (vlcPath), vlcPath, NULL)) 14689 { 14690 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14691 } 14692 14693 $ if (SearchPath (NULL, "vlc.exe", NULL, sizeof (vlcPath), vlcPath, NULL)) 14694 { 14695 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14696 } 14697 14698 $ if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", NULL, vlcPath, sizeof (vlcPath))) 14699 { 14700 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14701 } 14702 14703 $ if (txRegQuery ("HKLM\\Software\\VideoLAN\\VLC", "InstallDir", vlcPath, sizeof (vlcPath))) 14704 { 14705 $ strncat_s (vlcPath, sizeof (vlcPath) - 1, "\\vlc.exe", INT_MAX); 14706 14707 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14708 } 14709 14710 $ strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files" "\\VideoLAN\\VLC\\vlc.exe", UINT_MAX); //-V106 14711 { 14712 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14713 } 14714 14715 $ strncpy_s (vlcPath, sizeof (vlcPath), "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe", UINT_MAX); //-V106 14716 { 14717 if (_access (vlcPath, 0) == 0) {$ return vlcPath; } 14718 } 14719 14720 $ return NULL; 14721 } 14722 14723 //----------------------------------------------------------------------------------------------------------------- 14724 14725 HRESULT txSetProgress (double percent, unsigned type /*= TBPF_NORMAL*/, HWND wnd /*= NULL*/) 14726 { 14727 $1 static double oldPercent = 100; 14728 14729 if (percent < 0) {$ percent = MIN (oldPercent, 100); } 14730 else {$ oldPercent = percent; } 14731 14732 $ HRESULT res = S_FALSE; 14733 14734 #if defined (__ITaskbarList3_INTERFACE_DEFINED__) 14735 14736 $ HRESULT init = Win32::CoInitialize (NULL); 14737 14738 $ bool ok = true; 14739 $ res = S_OK; 14740 14741 $ ITaskbarList3* taskbar = NULL; 14742 if (ok) {$ res = Win32::CoCreateInstance (Win32::CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, Win32::IID_ITaskbarList3, (void**) &taskbar); } 14743 $ ok &= !!taskbar && (res == S_OK); 14744 14745 if (!wnd) {$ wnd = txWindow(); } 14746 if (ok && taskbar) {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); } 14747 if (ok && taskbar) {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type); ok &= (res == S_OK); } 14748 14749 if (wnd == txWindow()) {$ wnd = Win32::GetConsoleWindow(); } 14750 if (ok && taskbar) {$ res = taskbar->SetProgressValue (wnd, ROUND (percent), 100); ok &= (res == S_OK); } 14751 if (ok && taskbar) {$ res = taskbar->SetProgressState (wnd, (TBPFLAG) type); ok &= (res == S_OK); } 14752 14753 if (taskbar) {$ taskbar->Release(); } 14754 14755 if (init == S_OK) {$ Win32::CoUninitialize(); } 14756 14757 #endif 14758 14759 (void) type; (void) wnd; 14760 14761 $ return res; 14762 } 14763 14764 #endif // TX_COMPILED 14765 14766 //----------------------------------------------------------------------------------------------------------------- 14767 14768 // +--<<< Это не те символы, что вы ищете :) 14769 // V Полезно смотреть не только вверх, но и вниз 14770 14771 inline WNDPROC txSetWindowsHook (WNDPROC wndProc /*= NULL*/) 14772 { 14773 $1 WNDPROC old = _txAltWndProc; _txAltWndProc = wndProc; 14774 $ return old; 14775 } 14776 14777 //----------------------------------------------------------------------------------------------------------------- 14778 14779 // +--<<< А это, наконец, искомое определение этой функции. 14780 // | Смотрите по сторонам! Нужная вам функция где-то рядом. 14781 // | 14782 // v 14783 inline bool txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture() 14784 { 14785 txMessageBox ("Это запланированная ошибка. Такое бывает. Вы хотели вызвать:\n\n" 14786 14787 "txIDontWantToHaveAPauseAfterMyProgramBeforeTheWindowWillClose_AndIWillNotBeAskingWhereIsMyPicture()\n\n" 14788 14789 "Хоть вы долго [копировали]набирали это имя, на самом деле эта функция не реализована. " 14790 "Есть другая функция, которая убирает авто-паузу в конце программы, но в хелпе про нее не написано.\n\n" 14791 14792 "Но не все так плохо. Определение нужной функции есть в исходных текстах TXLib.h, оно лежит рядом " 14793 "с определением той функции с длинным названием, которую вы сейчас вызвали.\n\n" 14794 14795 "Нажмите в редакторе Ctrl+O, найдите и откройте файл TXLib.h (он лежит в папке, куда вы " 14796 "установили TXLib), затем нажмите Ctrl+F и ищите \"txIDontWant\". Удачи!\n\n", 14797 14798 "Не получилось", MB_ICONSTOP); 14799 14800 // The truth is out there... (C++files) 14801 14802 return false; 14803 } 14804 14805 //----------------------------------------------------------------------------------------------------------------- 14806 14807 // Bingo! Now you are learned to use the Source, Luke. And may the Source be with you. 14808 14809 inline bool txDisableAutoPause() 14810 { 14811 _txExit = true; 14812 return true; 14813 } 14814 14815 // P.S. This library contains more undocumented functions. Search them via "Luke" keyword. 14816 14817 //----------------------------------------------------------------------------------------------------------------- 14818 14819 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 14820 14821 void _txDump (const void* address, const char name[] /*= "_txDump()"*/, bool pause /*= true*/) 14822 { 14823 $1 assert (!_txIsBadReadPtr (address)); 14824 14825 $ const unsigned char* addr = (const unsigned char*) address; 14826 14827 $ const int stdout_fileno = 1; // Not all g++ packages contain STDOUT_FILENO 14828 $ const int _o_u16text = 0x00020000; // and _O_U16TEXT 14829 14830 $ bool istty = _txIsTTY (1); 14831 14832 $ int mode = _O_TEXT; 14833 $ int oldMode = _setmode (stdout_fileno, mode); 14834 14835 $ unsigned oldCP = GetConsoleOutputCP(); 14836 $ unsigned cp = 1251; SetConsoleOutputCP (cp); //-V581 14837 14838 $ unsigned attr = txGetConsoleAttr(); 14839 14840 $ txSetConsoleAttr (FOREGROUND_WHITE); 14841 $ printf ("\n%*.*s ", (int) sizeof (address) * 2, (int) sizeof (address) * 2, ((name)? name : "")); 14842 14843 $ txSetConsoleAttr (FOREGROUND_YELLOW); 14844 $ for (unsigned x = 0; x < 16; x++) printf ("%02X ", x); 14845 $ for (unsigned x = 0; x < 16; x++) printf ("%X", x); 14846 14847 $ const wchar_t* xlat[33] = {L"\xB7" /* 00 - NUL - NULL */, L"\x263A" /* 01 - SOH - Start of header */, 14848 L"\x263B" /* 02 - STX - Start of text */, L"\x2665" /* 03 - ETX - End of text */, 14849 L"\x2666" /* 04 - EOT - End of transm. */, L"\x2663" /* 05 - ENQ - Enquiry */, 14850 L"\x2660" /* 06 - ACK - Acknowledgment */, L"\x2022" /* 07 - BEL - Bell */, 14851 L"\x25D8" /* 08 - BS - Backspace */, L"\x25CB" /* 09 - HT - Horizontal tab */, 14852 L"\x25D9" /* 10 - LF - Line feed */, L"\x2642" /* 11 - VT - Vertical tab */, 14853 L"\x2640" /* 12 - FF - Form feed */, L"\x266A" /* 13 - CR - Carriage return */, 14854 L"\x266B" /* 14 - SO - Shift out */, L"\x263C" /* 15 - SI - Shift in */, 14855 L"\x25BA" /* 16 - DLE - Data link escape */, L"\x25C4" /* 17 - DC1 - Device control 1 */, 14856 L"\x2195" /* 18 - DC2 - Device control 2 */, L"\x203C" /* 19 - DC3 - Device control 3 */, 14857 L"\xB6" /* 20 - DC4 - Device control 4 */, L"\xA7" /* 21 - NAK - Negative ACK */, 14858 L"\x25AC" /* 22 - SYN - Synchronous idle */, L"\x21A8" /* 23 - ETB - End of transm. block */, 14859 L"\x2191" /* 24 - CAN - Cancel */, L"\x2193" /* 25 - EM - End of medium */, 14860 L"\x2192" /* 26 - SUB - Substitute */, L"\x2190" /* 27 - ESC - Escape */, 14861 L"\x221F" /* 28 - FS - File separator */, L"\x2194" /* 29 - GS - Group separator */, 14862 L"\x25B2" /* 30 - RS - Record separator */, L"\x25BC" /* 31 - US - Unit separator */, 14863 L"\x20" /* 32 - Space */}; 14864 14865 $ for (int y = 0; y < 16; y++, addr += 16) 14866 { 14867 if (cp != 1251) SetConsoleOutputCP (cp = 1251); //-V581 14868 (void)_setmode (stdout_fileno, mode = oldMode); 14869 14870 txSetConsoleAttr (FOREGROUND_YELLOW); 14871 14872 printf ("\n" "%*p ", (int) sizeof (address) * 2, addr); 14873 14874 int color = FOREGROUND_LIGHTGREEN; 14875 14876 for (unsigned x = 0; x < 16; x++) 14877 { 14878 txSetConsoleAttr (color + x/4%2); //-V112 14879 printf ("%02X ", addr[x]); 14880 } 14881 14882 for (unsigned x = 0; x < 16; x++) 14883 { 14884 txSetConsoleAttr (color + x/4%2); //-V112 14885 14886 unsigned char ch = addr[x]; 14887 14888 if (ch >= sizearr (xlat) || !istty) 14889 { 14890 if (cp != oldCP) SetConsoleOutputCP (cp = oldCP); //-V581 14891 if (mode != oldMode) (void)_setmode (stdout_fileno, mode = oldMode); 14892 14893 printf ("%c", !strchr ("\t\r\n", ch)? ch : ' '); 14894 } 14895 else 14896 { 14897 if (cp != 1251) SetConsoleOutputCP (cp = 1251); //-V581 14898 if (mode != _o_u16text) (void)_setmode (stdout_fileno, mode = _o_u16text); 14899 14900 wprintf (L"%lls", xlat[ch]); 14901 } 14902 } 14903 } 14904 14905 $ (void)_setmode (stdout_fileno, oldMode); 14906 $ printf ("\n"); 14907 14908 $ if (pause && istty) 14909 { 14910 $ txSetConsoleAttr (FOREGROUND_DARKGRAY); 14911 $ txPause ("\v%-*s CodePage = %5u", (int) sizeof (void*) * 2 + 16*3, "[Нажмите любую клавишу для продолжения]", oldCP); 14912 } 14913 14914 $ txSetConsoleAttr (FOREGROUND_LIGHTGRAY); 14915 $ printf ("\n"); 14916 14917 $ txSetConsoleAttr (attr); 14918 $ SetConsoleOutputCP (oldCP); 14919 } 14920 14921 //----------------------------------------------------------------------------------------------------------------- 14922 14923 void _txStackBackTrace (const char file[] /*= "?"*/, int line /*= 0*/, const char func[] /*= "?"*/, 14924 bool readSource /*= true*/) 14925 { 14926 $1 unsigned attr = txGetConsoleAttr(); 14927 $ txSetConsoleAttr (FOREGROUND_LIGHTCYAN); 14928 14929 $ fprintf (stderr, "\n" "--------------------------------------------------\n" 14930 "Трассировка стека из \"%s\" at %s:%d:\n\n" 14931 "%s\n\n" 14932 "--------------------------------------------------\n\n", 14933 func, file, line, _txCaptureStackBackTrace (1, readSource)); 14934 14935 $ txSetConsoleAttr (attr); 14936 } 14937 14938 //----------------------------------------------------------------------------------------------------------------- 14939 14940 char* txDemangle (const char* mangledName, std::nomeow_t) 14941 { 14942 $1 if (!mangledName) return NULL; 14943 14944 $ char* typeName = NULL; 14945 14946 #if defined (_GCC_VER) 14947 14948 $ int err = 1; 14949 $ typeName = ::abi::__cxa_demangle (mangledName, 0, 0, &err); (void) err; 14950 if (typeName) {$ return typeName; } 14951 14952 #endif 14953 14954 $ unsigned short flags = 0; 14955 14956 $ if (mangledName[0] == '.') 14957 { 14958 $ mangledName++; 14959 $ flags = 0x2800; // UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY 14960 } 14961 14962 $ typeName = _TX_CALL (Win32::__unDName, (NULL, mangledName, 0, malloc, free, flags)); 14963 if (typeName) {$ return typeName; } 14964 14965 $ return _strdup (mangledName); 14966 } 14967 14968 //----------------------------------------------------------------------------------------------------------------- 14969 14970 std::string txDemangle (const char* mangledName) 14971 { 14972 $1 char* typeName = txDemangle (mangledName, std::nomeow); 14973 $ std::string name (typeName? typeName : ""); 14974 $ free (typeName); 14975 14976 $ return name; 14977 } 14978 14979 //----------------------------------------------------------------------------------------------------------------- 14980 14981 double txQueryPerformance() 14982 { 14983 $1 int maxTime = 500; 14984 $ int maxSamples = 100; 14985 $ POINT size = {100, 100}; 14986 14987 $ HDC dc = _txBuffer_Create (txWindow(), &size, NULL); 14988 $ assert (dc); if (!dc) return -1; //-V547 14989 14990 $ DWORD mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), 1); //-V202 14991 $ assert (mask); 14992 14993 $ LARGE_INTEGER freq = {}; 14994 $ QueryPerformanceFrequency (&freq) asserted; 14995 14996 $ LARGE_INTEGER start = {}; 14997 $ QueryPerformanceCounter (&start) asserted; 14998 14999 $ int samples = 0; 15000 $ while (samples++ < maxSamples) 15001 { 15002 $ LARGE_INTEGER cur = {}; 15003 $ QueryPerformanceCounter (&cur) asserted; 15004 15005 $ double t = 1000.0 * (double) (cur.QuadPart - start.QuadPart) / (double) freq.QuadPart; 15006 $ if (t > maxTime) break; 15007 15008 // Draw test scene 15009 15010 $ for (int y = 0; y < size.y; y++) 15011 for (int x = 0; x < size.x; x++) txSetPixel (x, y, TX_BLACK, dc); 15012 15013 $ for (int y = 0; y < size.y; y += 10) 15014 for (int x = 0; x < size.x; x += 50) txTextOut (x, y, "*", dc); 15015 15016 $ txEllipse (0, 0, size.x, size.y, dc); 15017 $ txFloodFill (size.x/2.0, size.y/2.0, TX_TRANSPARENT, FLOODFILLSURFACE, dc); 15018 15019 $ txBitBlt (dc, size.x/2.0, 0, size.x/2.0, size.y/2.0, dc, 0, 0) asserted; 15020 $ txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, 0, size.y/2.0) asserted; 15021 $ txBitBlt (dc, 0, size.y/2.0, size.x/2.0, size.y/2.0, dc, 0, 0) asserted; 15022 $ txBitBlt (dc, size.x/2.0, size.y/2.0, size.x/2.0, size.y/2.0, dc, size.x/2.0, 0) asserted; 15023 } 15024 15025 $ mask = (DWORD) SetThreadAffinityMask (GetCurrentThread(), mask); //-V106 //-V202 15026 $ assert (mask); 15027 15028 $ _txBuffer_Delete (&dc); 15029 15030 $ return 3.0 * samples / sqrt (1.0 * size.x * size.y); 15031 } 15032 15033 //----------------------------------------------------------------------------------------------------------------- 15034 15035 unsigned txExtractColor (COLORREF color, COLORREF component) 15036 { 15037 $1 switch (component) 15038 { 15039 case TX_RED: 15040 case TX_HUE: $ return (color >> 0) & 0xFF; 15041 15042 case TX_GREEN: 15043 case TX_SATURATION: $ return (color >> 8) & 0xFF; 15044 15045 case TX_BLUE: 15046 case TX_LIGHTNESS: $ return (color >> 16) & 0xFF; 15047 15048 default: $ return CLR_INVALID; 15049 } 15050 } 15051 15052 //----------------------------------------------------------------------------------------------------------------- 15053 15054 COLORREF txRGB2HSL (COLORREF rgbColor) 15055 { 15056 $1 struct xRGB 15057 { 15058 static bool zero (double val) 15059 { 15060 const double prec = 0.001; 15061 15062 return (fabs (val) < prec); 15063 } 15064 }; 15065 15066 $ double r = txExtractColor (rgbColor, TX_RED) / 255.0, //-V2551 15067 g = txExtractColor (rgbColor, TX_GREEN) / 255.0, //-V2551 15068 b = txExtractColor (rgbColor, TX_BLUE) / 255.0, //-V2551 15069 15070 m1 = MAX (MAX (r, g), b), 15071 m2 = MIN (MIN (r, g), b), 15072 dm = m1 - m2, 15073 sm = m1 + m2, 15074 15075 h = 0, 15076 s = 0, 15077 l = sm / 2; 15078 15079 $ if (!xRGB::zero (dm)) 15080 { 15081 $ sm = (sm <= 1)? sm : (2-sm); 15082 $ s = (!xRGB::zero (sm))? dm/sm : 0; 15083 15084 $ double cr = (!xRGB::zero (dm))? (m1 - r) / dm : 0, 15085 cg = (!xRGB::zero (dm))? (m1 - g) / dm : 0, 15086 cb = (!xRGB::zero (dm))? (m1 - b) / dm : 0; 15087 15088 $ if (xRGB::zero (r - m1)) h = cb - cg; 15089 $ if (xRGB::zero (g - m1)) h = 2 + cr - cb; 15090 $ if (xRGB::zero (b - m1)) h = 4 + cg - cr; 15091 } 15092 15093 $ h = (h >= 0)? h*60 : h*60 + 360; 15094 15095 $ return RGB (ROUND (h / 360.0 * 256), ROUND (s * 255), ROUND (l * 255)); 15096 } 15097 15098 //----------------------------------------------------------------------------------------------------------------- 15099 15100 COLORREF txHSL2RGB (COLORREF hslColor) 15101 { 15102 $1 struct xRGB 15103 { 15104 static double calc (double h, double m1, double m2) 15105 { 15106 $2 while (h < 0) h += 360; 15107 $ while (h > 360) h -= 360; 15108 15109 $ return (h < 60)? m1 + (m2-m1) * h / 60 : 15110 (h < 180)? m2 : 15111 (h < 240)? m1 + (m2-m1) * (240-h) / 60 : 15112 m1; 15113 } 15114 }; 15115 15116 $ int si = txExtractColor (hslColor, TX_SATURATION); 15117 15118 $ double h = txExtractColor (hslColor, TX_HUE) / 256.0 * 360, 15119 s = txExtractColor (hslColor, TX_SATURATION) / 255.0, 15120 l = txExtractColor (hslColor, TX_LIGHTNESS) / 255.0, 15121 15122 m2 = (l <= 0.5)? l * (1 + s) : l + s - l * s, 15123 m1 = 2 * l - m2, 15124 15125 r = (si)? xRGB::calc (h + 120, m1, m2) : l, 15126 g = (si)? xRGB::calc (h, m1, m2) : l, 15127 b = (si)? xRGB::calc (h - 120, m1, m2) : l; 15128 15129 $ return RGB (ROUND (r * 255), ROUND (g * 255), ROUND (b * 255)); 15130 } 15131 15132 //----------------------------------------------------------------------------------------------------------------- 15133 15134 void tx_fpreset() 15135 { 15136 $1 txAutoLock _lock; 15137 15138 $ Win32::_fpreset(); 15139 15140 $ unsigned new87 = 0x0008001C; // _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW 15141 15142 #if !defined (__CYGWIN__) 15143 15144 $ unsigned old87 = 0; 15145 $ if (_controlfp_s (&old87, 0, 0) == 0) 15146 {$ (void) _controlfp_s (&old87, old87 & ~new87, 0x0008001F); } // _MCW_EM 15147 15148 #else 15149 15150 $ Win32::_controlfp (Win32::_controlfp (0, 0) & ~new87, 0x0008001F); // _MCW_EM 15151 15152 #endif 15153 } 15154 15155 #endif // TX_COMPILED 15156 15157 //----------------------------------------------------------------------------------------------------------------- 15158 15159 #if defined (_TX_CPP11) 15160 template <int txFramesToAverage> 15161 #endif 15162 15163 double txGetFPS (int minFrames) 15164 { 15165 $1 static _tx_thread LARGE_INTEGER time0 = {}; if (!time0.QuadPart) QueryPerformanceCounter (&time0); 15166 $ LARGE_INTEGER time = {}; QueryPerformanceCounter (&time); 15167 15168 $ if (time.QuadPart - time0.QuadPart == 0) 15169 {$ return 0; } 15170 15171 $ LARGE_INTEGER freq = {}; QueryPerformanceFrequency (&freq); 15172 15173 $ double fps = (double) freq.QuadPart / (double) (time.QuadPart - time0.QuadPart); 15174 $ time0 = time; 15175 15176 $ if (txFramesToAverage == 0) return fps; 15177 15178 $ static _tx_thread double average [txFramesToAverage] = {}; 15179 $ static _tx_thread unsigned n = 0; 15180 15181 $ average [n++ % txFramesToAverage] = fps; 15182 15183 $ unsigned nn = MIN (n, (unsigned) sizearr (average)); 15184 15185 $ fps = 0; 15186 $ for (unsigned i = 0; i < nn; i++) fps += average[i]; 15187 $ fps /= nn; 15188 15189 $ return ((int)n >= MIN (minFrames, txFramesToAverage))? fps : 0; 15190 } 15191 15192 //----------------------------------------------------------------------------------------------------------------- 15193 15194 template <typename T> 15195 inline T zero() { T __zero = {}; return __zero; } 15196 15197 //----------------------------------------------------------------------------------------------------------------- 15198 15199 inline double random (std::nomeow_t, double left, double right) 15200 { 15201 return left + (right - left) * ((double) rand() / RAND_MAX); 15202 } 15203 15204 //----------------------------------------------------------------------------------------------------------------- 15205 15206 template <typename Tx, typename Ta, typename Tb> 15207 inline bool In (std::nomeow_t, Tx x, Ta a, Tb b) 15208 { 15209 return a <= x && x <= b; 15210 } 15211 15212 //----------------------------------------------------------------------------------------------------------------- 15213 15214 inline bool In (std::nomeow_t, const POINT& pt, const RECT& rect) 15215 { 15216 if (_TX_ARGUMENT_FAILED (&pt)) return false; 15217 if (_TX_ARGUMENT_FAILED (&rect)) return false; 15218 15219 return In (std::nomeow, pt.x, rect.left, rect.right) && 15220 In (std::nomeow, pt.y, rect.top, rect.bottom); 15221 } 15222 15223 //----------------------------------------------------------------------------------------------------------------- 15224 15225 inline bool In (std::nomeow_t, const COORD& pt, const SMALL_RECT& rect) 15226 { 15227 if (_TX_ARGUMENT_FAILED (&pt)) return false; 15228 if (_TX_ARGUMENT_FAILED (&rect)) return false; 15229 15230 return In (std::nomeow, pt.X, rect.Left, rect.Right) && 15231 In (std::nomeow, pt.Y, rect.Top, rect.Bottom); 15232 } 15233 15234 //----------------------------------------------------------------------------------------------------------------- 15235 15236 inline int random (int range) 15237 { 15238 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15239 15240 return rand() % range; 15241 } 15242 15243 //----------------------------------------------------------------------------------------------------------------- 15244 15245 inline double random (double left, double right) 15246 { 15247 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15248 15249 return random (std::nomeow, left, right); 15250 } 15251 15252 //----------------------------------------------------------------------------------------------------------------- 15253 15254 template <typename Tx, typename Ta, typename Tb> 15255 inline bool In (Tx x, Ta a, Tb b) 15256 { 15257 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15258 15259 return In (std::nomeow, x, a, b); 15260 } 15261 15262 //----------------------------------------------------------------------------------------------------------------- 15263 15264 inline bool In (const POINT& pt, const RECT& rect) 15265 { 15266 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15267 15268 return In (std::nomeow, pt, rect); 15269 } 15270 15271 //----------------------------------------------------------------------------------------------------------------- 15272 15273 inline bool In (const COORD& pt, const SMALL_RECT& rect) 15274 { 15275 if (rand() % 100 == 0) fprintf (stderr, "%.4s ", (const volatile char*) ((rand() & 0x0F)? &_txCanaryFirst : &_txCanaryLast)); //-V206 15276 15277 return In (std::nomeow, pt, rect); 15278 } 15279 15280 //} 15281 //================================================================================================================= 15282 15283 //================================================================================================================= 15284 //{ txPrintf() implementation 15285 // Реализация txPrintf() 15286 //================================================================================================================= 15287 15288 #if defined (_TX_CPP11) 15289 15290 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args); 15291 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args); 15292 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args); 15293 template <typename T, typename... ArgsT> void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args); 15294 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt); 15295 15296 template <typename T> void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg); 15297 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg); 15298 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt); 15299 15300 //----------------------------------------------------------------------------------------------------------------- 15301 15302 template <typename T, typename... ArgsT> 15303 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg, ArgsT... args) 15304 { 15305 $1 assert (fmt); 15306 15307 $ _txPrintV (stream, format, n, fmt); 15308 15309 if (fmt[0] == '%') {$} 15310 else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); } 15311 15312 $ _txPrintV (stream, format, n, fmt, arg); 15313 15314 $ _txPrintF (stream, format, n+1, fmt, args...); 15315 } 15316 15317 //----------------------------------------------------------------------------------------------------------------- 15318 15319 template <typename T, typename... ArgsT> 15320 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, const T& arg, ArgsT... args) 15321 { 15322 $1 assert (&stream); 15323 $ assert (fmt); 15324 15325 $ _txPrintV (stream, format, n, fmt); 15326 15327 if (fmt[0] == '%' && fmt[1] == '*') {$ stream << std::setw (width); } //-V2006 15328 else {$ TX_ERROR ("\"%%*\" required to setwidth (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, fmt, txTypename (arg), n, format); } 15329 15330 $ _txPrintV (stream, format, n, fmt, arg); 15331 15332 $ _txPrintF (stream, format, n+1, fmt, args...); 15333 } 15334 15335 //----------------------------------------------------------------------------------------------------------------- 15336 15337 template <typename T, typename... ArgsT> 15338 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, precision_t prec, const T& arg, ArgsT... args) 15339 { 15340 $1 assert (&stream); 15341 $ assert (fmt); 15342 15343 $ _txPrintV (stream, format, n, fmt); 15344 15345 if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*') {$ stream << std::setprecision ((std::streamsize) (prec + 1)); } //-V2006 //-V1028 15346 else {$ TX_ERROR ("\"%%.*\" required to setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", prec, fmt, txTypename (arg), n, format); } 15347 15348 $ _txPrintV (stream, format, n, fmt, arg); 15349 15350 $ _txPrintF (stream, format, n+1, fmt, args...); 15351 } 15352 15353 //----------------------------------------------------------------------------------------------------------------- 15354 15355 template <typename T, typename... ArgsT> 15356 void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt, width_t width, precision_t prec, const T& arg, ArgsT... args) 15357 { 15358 $1 assert (&stream); 15359 $ assert (fmt); 15360 15361 $ _txPrintV (stream, format, n, fmt); 15362 15363 if (fmt[0] == '%' && fmt[1] == '*' && fmt[2] == '.' && fmt[3] == '*') {$ stream << std::setw (width) << std::setprecision ((std::streamsize) (prec + 1)); } //-V2006 //-V1028 15364 else {$ TX_ERROR ("\"%%*.*\" required to setwidth (%d) and setprecision (%d) in ...\"%s\" while printing %s argument %d in \"%s\"", width, prec, fmt, txTypename (arg), n, format); } 15365 15366 $ _txPrintV (stream, format, n, fmt, arg); 15367 15368 $ _txPrintF (stream, format, n+1, fmt, args...); 15369 } 15370 15371 //----------------------------------------------------------------------------------------------------------------- 15372 15373 inline void _txPrintF (std::ostringstream& stream, const char* format, int n, const char*& fmt) 15374 { 15375 $1 assert (fmt); 15376 15377 $ _txPrintV (stream, format, n, fmt); 15378 15379 if (!fmt[0]) {$} 15380 else {$ TX_ERROR ("No argument provided for %% in \"%s\" while printing \"%s\"", fmt, format); } 15381 } 15382 15383 //----------------------------------------------------------------------------------------------------------------- 15384 15385 inline void _txPrintV (std::ostringstream& stream, const char*, int, const char*& fmt) 15386 { 15387 $1 assert (&stream); 15388 $ assert (fmt); 15389 15390 $ while (*fmt) 15391 { 15392 if (fmt[0] == '%') 15393 { 15394 if (fmt[1] == '%') fmt++; 15395 else break; 15396 } 15397 15398 stream << *fmt++; 15399 } 15400 $ } 15401 15402 //----------------------------------------------------------------------------------------------------------------- 15403 15404 template <typename T> 15405 void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, const T& arg) 15406 { 15407 $1 assert (&stream); 15408 $ assert (fmt); 15409 15410 $ if (_TX_ARGUMENT_FAILED (&arg)) return; 15411 15412 if (fmt[0] == '%') {$} 15413 else {$ TX_ERROR ("\"%%$\" required to print an argument in ...\"%s\" while printing %s argument %d in \"%s\"", fmt, txTypename (arg), n, format); } 15414 15415 $ fmt++; 15416 15417 $ char oldFill = stream.fill (' '); 15418 $ std::ios_base::fmtflags oldFlags = stream.flags(); 15419 15420 $ for (;;) switch (*fmt) 15421 { 15422 case '-': $ stream << std::left; fmt++; break; 15423 case '+': $ stream << std::showpos; fmt++; break; 15424 case ' ': $ stream.fill (' '); fmt++; break; 15425 case '#': $ stream << std::showbase; fmt++; break; 15426 case '0': $ stream.fill ('0'); fmt++; break; 15427 15428 default: $ goto end; 15429 } 15430 end: 15431 15432 $ int width = (*fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0); 15433 $ int prec = (*fmt == '.')? (*++fmt != '*')? (int) strtoul (fmt, const_cast <char**> (&fmt), 10) : (fmt++, 0) : 0; 15434 15435 if (width) {$ stream << std::setw (width); } 15436 if (prec) {$ stream << std::setprecision (prec); } 15437 15438 $ fmt += strspn (fmt, "hljztL"); 15439 15440 $ switch (*fmt) 15441 { 15442 case '$': 15443 case '?': $ break; 15444 15445 case 'd': 15446 case 'i': 15447 case 'u': $ stream << std::dec; break; 15448 15449 case 'o': $ stream << std::oct; break; 15450 15451 case 'x': $ stream << std::hex; break; 15452 case 'X': $ stream << std::hex << std::uppercase; break; 15453 15454 case 'f': $ stream << std::fixed; break; 15455 case 'F': $ stream << std::fixed << std::uppercase; break; 15456 15457 case 'e': $ stream << std::scientific; break; 15458 case 'E': $ stream << std::scientific << std::uppercase; break; 15459 15460 case 'g': $ break; 15461 case 'G': $ stream << std::uppercase; break; 15462 15463 case 'a': $ break; 15464 case 'A': $ stream << std::uppercase; break; 15465 15466 case 'c': 15467 case 's': 15468 case 'p': $ break; 15469 15470 default: $ TX_ERROR ("Invalid format '%.1s' at \"%s\" while printing %s argument %d in \"%s\"", fmt, fmt, txTypename (arg), n, format); break; 15471 } 15472 15473 $ fmt++; 15474 15475 if (&arg) {$ stream << arg; } 15476 else {$ stream << "(null)"; } 15477 15478 $ stream.fill (oldFill); 15479 $ stream.flags (oldFlags); 15480 } 15481 15482 //----------------------------------------------------------------------------------------------------------------- 15483 15484 inline void _txPrintV (std::ostringstream& stream, const char* format, int n, const char*& fmt, int* arg) //-V2009 15485 { 15486 $1 assert (fmt); 15487 15488 if (_TX_ARGUMENT_FAILED (arg)) return; 15489 15490 if (fmt[0] == '%' && fmt[1] == 'n') {$} 15491 else {$ TX_ERROR ("\"%%n\" required to store print length in int* argument %d in \"%s\"", n, format); } 15492 15493 $ *arg = (int) stream.str().length(); //-V202 15494 15495 $ fmt += 2; 15496 } 15497 15498 //----------------------------------------------------------------------------------------------------------------- 15499 15500 template <typename T> inline const T& _txPrintfNormalizeArg (const T& arg) { if (_TX_ARGUMENT_FAILED (&arg)) {;} return arg; } 15501 inline const char* _txPrintfNormalizeArg (const std::string& arg) { if (_TX_ARGUMENT_FAILED (&arg)) return NULL; return arg.c_str(); } 15502 15503 //----------------------------------------------------------------------------------------------------------------- 15504 15505 template <typename... ArgsT> 15506 inline int txPrintf (std::ostringstream& stream, const char* format, ArgsT... args) 15507 { 15508 $1 if (_TX_ARGUMENT_FAILED (&stream)) return 0; 15509 $ if (_TX_ARGUMENT_FAILED (&format)) return 0; 15510 15511 $ const char* fmt = format; 15512 $ _txPrintF (stream, format, 2, fmt, _txPrintfNormalizeArg (args)...); 15513 15514 $ return (int) stream.str().length(); //-V202 15515 } 15516 15517 //----------------------------------------------------------------------------------------------------------------- 15518 15519 template <typename... ArgsT> 15520 inline int txPrintf (char buffer[], size_t size, const char* format, ArgsT... args) 15521 { 15522 $1 if (_TX_ARGUMENT_FAILED (&buffer)) return 0; 15523 $ if (_TX_ARGUMENT_FAILED (&format)) return 0; 15524 15525 $ if (size > 0) size--; 15526 $ buffer[size] = 0; 15527 15528 $ if (!size) return 0; 15529 15530 $ std::ostringstream stream; 15531 $ stream.rdbuf() -> pubsetbuf (buffer, size); 15532 15533 $ txPrintf (stream, format, args...); 15534 15535 $ return (int) stream.str().length(); //-V202 15536 } 15537 15538 //----------------------------------------------------------------------------------------------------------------- 15539 15540 template <typename... ArgsT> 15541 inline std::string txFormat (const char* format, ArgsT... args) 15542 { 15543 $1 if (_TX_ARGUMENT_FAILED (&format)) return ""; 15544 15545 $ std::ostringstream stream; 15546 15547 $ txPrintf (stream, format, args...); 15548 15549 $ return stream.str(); 15550 } 15551 15552 //----------------------------------------------------------------------------------------------------------------- 15553 15554 template <typename... ArgsT> 15555 inline int txPrintf (const char* format, ArgsT... args) 15556 { 15557 $1 if (_TX_ARGUMENT_FAILED (&format)) return 0; 15558 15559 $ return printf ("%s", txFormat (format, args...) .c_str()); 15560 } 15561 15562 #endif 15563 15564 //----------------------------------------------------------------------------------------------------------------- 15565 15566 int _txPrintfCheck (const char* format, ...) tx_printfy (1); 15567 inline int _txPrintfCheck (const char*, ...) { return 0; } 15568 15569 //} 15570 //================================================================================================================= 15571 15572 //================================================================================================================= 15573 //{ txDialog methods implementation 15574 // Реализация методов класса txDialog 15575 // 15576 // See [1] http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms645389%28v=vs.85%29.aspx 15577 // [2] http://blogs.msdn.microsoft.com/oldnewthing/20050429-00/?p=35743 15578 // [3] http://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753 15579 //================================================================================================================= 15580 15581 #ifndef TX_COMPILED // <<< THE CODE IS HERE, UNFOLD IT <<< 15582 15583 txDialog::txDialog () : 15584 layout_ (NULL) 15585 {$1} 15586 15587 //----------------------------------------------------------------------------------------------------------------- 15588 15589 txDialog::txDialog (const Layout* layout) : 15590 layout_ (layout) 15591 {$1} 15592 15593 //----------------------------------------------------------------------------------------------------------------- 15594 15595 const txDialog::Layout* txDialog::setLayout (const Layout* layout) 15596 { 15597 $1 assert (layout); 15598 15599 $ return ::std::swap (layout_, layout), layout; 15600 } 15601 15602 //----------------------------------------------------------------------------------------------------------------- 15603 15604 intptr_t txDialog::dialogBox (WORD resourceID) 15605 { 15606 $1 const char* resName = (char*)(uintptr_t) resourceID; 15607 15608 $ if (!FindResource (NULL, resName, RT_DIALOG)) return TX_DEBUG_ERROR ("Не найден ресурс диалога %d", resourceID), 0; 15609 15610 $ return DialogBoxParam (NULL, resName, NULL, (DLGPROC) DialogProc_, (LPARAM) this); 15611 } 15612 15613 //----------------------------------------------------------------------------------------------------------------- 15614 15615 intptr_t txDialog::dialogBox (const txDialog::Layout* layout /*= NULL*/, size_t bufsize /*= 0*/) 15616 { 15617 $1 if (!layout) layout = layout_; 15618 $ if (!layout) return TX_DEBUG_ERROR ("Не установлен динамический шаблон диалога"), 0; 15619 15620 $ if (!bufsize) bufsize = 1024; 15621 15622 $ DLGTEMPLATE* tmpl = (DLGTEMPLATE*) GlobalAlloc (GPTR, bufsize); 15623 $ if (!tmpl) return TX_DEBUG_ERROR ("GlobalAlloc(): Нет памяти для шаблона диалога"), 0; 15624 15625 $ const Layout* dlg = &layout[0]; 15626 $ const Layout def = { DIALOG, NULL, 0, 0,0,0,0, WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER, "MS Shell Dlg", 8 }; 15627 15628 $ void* ptr = _tx_DLGTEMPLATE_Create (tmpl, bufsize, 15629 (dlg->style? dlg->style : def.style) | DS_SETFONT, 0, 0, 15630 dlg->x, dlg->y, dlg->sx, dlg->sy, 15631 dlg->caption? dlg->caption : def.caption, 15632 dlg->font? dlg->font : def.font, 15633 dlg->fontsize? dlg->fontsize : def.fontsize, NULL); 15634 $ WORD i = 0; 15635 $ for (i = 1; layout[i].wndclass != END; ++i) 15636 { 15637 $ const Layout* item = &layout[i]; 15638 15639 $ ptr = _tx_DLGTEMPLATE_Add (ptr, bufsize - ((char*)ptr - (char*)tmpl), 15640 item->style | WS_VISIBLE, 0, item->x, item->y, item->sx, item->sy, 15641 item->id, (const char*)(uintptr_t) item->wndclass, item->caption); 15642 } 15643 15644 $ tmpl->cdit = (unsigned short) (i-1); 15645 15646 $ intptr_t res = DialogBoxIndirectParam (NULL, tmpl, NULL, (DLGPROC) DialogProc_, (LPARAM) this); 15647 15648 $ GlobalFree (tmpl); 15649 15650 $ return res; 15651 } 15652 15653 //----------------------------------------------------------------------------------------------------------------- 15654 15655 int txDialog::dialogProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM) 15656 { 15657 $1 switch (msg) 15658 { 15659 case WM_INITDIALOG: $ SetForegroundWindow (wnd); 15660 $ break; 15661 15662 case WM_COMMAND: $ switch (LOWORD (wParam)) 15663 { 15664 case IDOK: 15665 case IDCANCEL: $ SetForegroundWindow (txWindow()? txWindow() : Win32::GetConsoleWindow()); 15666 $ EndDialog (wnd, (uintptr_t) this); 15667 $ break; 15668 15669 default: $ break; 15670 } 15671 $ break; 15672 default: $ break; 15673 } 15674 15675 $ return FALSE; 15676 } 15677 15678 //----------------------------------------------------------------------------------------------------------------- 15679 15680 intptr_t CALLBACK txDialog::DialogProc_ (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) 15681 { 15682 $1 static txDialog* this__ = NULL; 15683 $ if (msg == WM_INITDIALOG) this__ = (txDialog*) lParam; 15684 $ if (!this__) return FALSE; 15685 15686 $ return this__-> dialogProc (wnd, msg, wParam, lParam); //-V109 15687 } 15688 15689 //----------------------------------------------------------------------------------------------------------------- 15690 15691 void* _tx_DLGTEMPLATE_Create (void* globalMem, size_t bufsize, DWORD style, DWORD exStyle, 15692 WORD controls, short x, short y, short cx, short cy, 15693 const char caption[], const char font[], WORD fontsize, const char menu[]) 15694 { 15695 $1 if (_TX_ARGUMENT_FAILED (globalMem)) return NULL; 15696 15697 $ WORD* pw = (WORD*) globalMem; 15698 15699 $ DLGTEMPLATE* tmpl = ((DLGTEMPLATE*&) pw)++; 15700 15701 $ tmpl->style = style; 15702 $ tmpl->dwExtendedStyle = exStyle; 15703 $ tmpl->cdit = controls; 15704 $ tmpl->x = x; 15705 $ tmpl->y = y; 15706 $ tmpl->cx = cx; 15707 $ tmpl->cy = cy; 15708 15709 $ if (menu > (const char*) 0xFFFF) 15710 { 15711 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (menu? menu : ""), -1, (wchar_t*) pw, //-V547 15712 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15713 } 15714 else 15715 { 15716 $ *pw++ = (WORD)(uintptr_t) (menu? 0xFFFF : 0); 15717 $ *pw++ = (WORD)(uintptr_t) menu; 15718 } 15719 15720 $ if (caption) 15721 { 15722 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (caption? caption : ""), -1, (wchar_t*) pw, //-V547 15723 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15724 } 15725 15726 $ if (style & DS_SETFONT) 15727 { 15728 $ *pw++ = fontsize; 15729 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, (font? font : ""), -1, (wchar_t*) pw, 15730 (int) (bufsize? bufsize - ((char*) pw - (char*) globalMem) : 0xFFFF)); //-V202 15731 } 15732 15733 $ return pw; 15734 } 15735 15736 //----------------------------------------------------------------------------------------------------------------- 15737 15738 void* _tx_DLGTEMPLATE_Add (void* dlgTemplatePtr, size_t bufsize, DWORD style, DWORD exStyle, 15739 short x, short y, short cx, short cy, 15740 WORD id, const char wclass[], const char caption[]) 15741 { 15742 $1 if (_TX_ARGUMENT_FAILED (dlgTemplatePtr)) return NULL; 15743 15744 $ WORD* pw = (LPWORD) dlgTemplatePtr; // Force align at word boundary 15745 $ ((ULONG&) pw) += 3; //-V205 15746 $ ((ULONG&) pw) >>= 2; //-V205 15747 $ ((ULONG&) pw) <<= 2; //-V205 15748 15749 $ DLGITEMTEMPLATE* tmpl = ((DLGITEMTEMPLATE*&) pw)++; 15750 15751 $ tmpl->style = style; 15752 $ tmpl->dwExtendedStyle = exStyle; 15753 $ tmpl->x = x; 15754 $ tmpl->y = y; 15755 $ tmpl->cx = cx; 15756 $ tmpl->cy = cy; 15757 $ tmpl->id = id; 15758 15759 $ if (HIWORD (wclass) == 0xFFFF) 15760 { 15761 $ *pw++ = (WORD) (HIWORD ((uintptr_t) wclass)); 15762 $ *pw++ = (WORD) (LOWORD ((uintptr_t) wclass)); 15763 } 15764 else if (wclass) 15765 { 15766 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, const_cast <char*> (wclass), -1, (wchar_t*) pw, 15767 (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF)); //-V202 15768 } 15769 else 15770 { 15771 $ *pw++ = 0; 15772 } 15773 15774 $ if (caption) 15775 { 15776 $ pw += MultiByteToWideChar (_TX_CODEPAGE, 0, caption, -1, (wchar_t*) pw, 15777 (int) (bufsize? bufsize - ((char*) pw - (char*) dlgTemplatePtr) : 0xFFFF)); //-V202 15778 } 15779 else 15780 { 15781 $ *pw++ = 0; 15782 } 15783 15784 $ *pw++ = 0; 15785 15786 $ return pw; 15787 } 15788 15789 #endif // TX_COMPILED 15790 15791 //} 15792 //================================================================================================================= 15793 15794 //================================================================================================================= 15795 //{ Cleaning up the utility macros 15796 // Очистка служебных макросов 15797 //================================================================================================================= 15798 15799 #undef $ 15800 #undef $0 15801 #undef $1 15802 #undef $2 15803 #undef $3 15804 #undef $4 15805 #undef $5 15806 #undef $6 15807 #undef $7 15808 #undef $8 15809 #undef $9 15810 #undef $$ 15811 15812 //} 15813 //================================================================================================================= 15814 15816 15817 //================================================================================================================= 15818 //{ Experimental Debugging macros 15820 //================================================================================================================= 15821 15822 //{---------------------------------------------------------------------------------------------------------------- 15942 //}---------------------------------------------------------------------------------------------------------------- 15943 15944 #ifndef __TX_DEBUG_MACROS 15945 #define __TX_DEBUG_MACROS ("Группа отладочных $-макросов") 15946 15948 //----------------------------------------------------------------------------------------------------------------- 15949 15950 #define $H txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_BLACK); 15951 #define $B txSetConsoleAttr (FOREGROUND_BLUE | BACKGROUND_BLACK); 15952 #define $G txSetConsoleAttr (FOREGROUND_GREEN | BACKGROUND_BLACK); 15953 #define $C txSetConsoleAttr (FOREGROUND_CYAN | BACKGROUND_BLACK); 15954 #define $R txSetConsoleAttr (FOREGROUND_RED | BACKGROUND_BLACK); 15955 #define $M txSetConsoleAttr (FOREGROUND_MAGENTA | BACKGROUND_BLACK); 15956 #define $Y txSetConsoleAttr (FOREGROUND_DARKYELLOW | BACKGROUND_BLACK); 15957 #define $d txSetConsoleAttr (FOREGROUND_LIGHTGRAY | BACKGROUND_BLACK); 15958 #define $D txSetConsoleAttr (FOREGROUND_DARKGRAY | BACKGROUND_BLACK); 15959 #define $b txSetConsoleAttr (FOREGROUND_LIGHTBLUE | BACKGROUND_BLACK); 15960 #define $g txSetConsoleAttr (FOREGROUND_LIGHTGREEN | BACKGROUND_BLACK); 15961 #define $c txSetConsoleAttr (FOREGROUND_LIGHTCYAN | BACKGROUND_BLACK); 15962 #define $r txSetConsoleAttr (FOREGROUND_LIGHTRED | BACKGROUND_BLACK); 15963 #define $m txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_BLACK); 15964 #define $y txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLACK); 15965 #define $h txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_BLACK); 15966 15967 #define $i txSetConsoleAttr (FOREGROUND_LIGHTCYAN | BACKGROUND_BLUE); 15968 #define $I txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_BLUE); 15969 #define $o txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_GREEN); 15970 #define $O txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_GREEN); 15971 #define $e txSetConsoleAttr (FOREGROUND_WHITE | BACKGROUND_RED); 15972 #define $E txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_RED); 15973 #define $w txSetConsoleAttr (FOREGROUND_LIGHTMAGENTA | BACKGROUND_MAGENTA); 15974 #define $W txSetConsoleAttr (FOREGROUND_YELLOW | BACKGROUND_MAGENTA); 15975 #define $f txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_LIGHTRED); 15976 #define $F txSetConsoleAttr (FOREGROUND_MAGENTA | BACKGROUND_LIGHTRED); 15977 #define $l txSetConsoleAttr (FOREGROUND_BLACK | BACKGROUND_DARKGRAY); 15978 #define $L txSetConsoleAttr (FOREGROUND_LIGHTGRAY | BACKGROUND_DARKGRAY); 15979 15980 #define $T( cond ) txSetConsoleAttr ((cond)? FOREGROUND_LIGHTGREEN : FOREGROUND_LIGHTRED ); 15981 15982 #define $s _txSaveConsoleAttr TX_JOIN (__txSavedConsoleAttrs, __LINE__); 15983 15984 #define $sH $s $H 15985 #define $sB $s $B 15986 #define $sG $s $G 15987 #define $sC $s $C 15988 #define $sR $s $R 15989 #define $sM $s $M 15990 #define $sY $s $Y 15991 #define $sd $s $d 15992 #define $sD $s $D 15993 #define $sb $s $b 15994 #define $sg $s $g 15995 #define $sc $s $c 15996 #define $sr $s $r 15997 #define $sm $s $m 15998 #define $sy $s $y 15999 #define $sh $s $h 16000 16001 #define $si $s $i 16002 #define $sI $s $I 16003 #define $so $s $o 16004 #define $sO $s $O 16005 #define $se $s $e 16006 #define $sE $s $E 16007 #define $sw $s $w 16008 #define $sW $s $W 16009 #define $sf $s $f 16010 #define $sF $s $F 16011 #define $sl $s $l 16012 #define $sL $s $L 16013 16014 #define $sT( cond ) $s $T (cond) 16015 16016 #define $test(cond) { if (!!(cond)) { $o std::cerr << "[PASSED] " __TX_FILELINE__ ": " #cond; } \ 16017 else { $e std::cerr << "[FAILED] " __TX_FILELINE__ ": " #cond; } $d; } 16018 16019 #define $status(cond) $test (cond) 16020 16021 #define $unittest( code, expected ) \ 16022 { \ 16023 const _tx_decltype (code) & _result = (code); /* Should use auto, but g++ 4.7.2 default std is < 2011 */ \ 16024 const _tx_decltype (expected) & _expected = (expected); \ 16025 \ 16026 if (_result == _expected) \ 16027 { $so std::cerr << "[PASSED] " __TX_FILELINE__ ": " #code; } \ 16028 else \ 16029 { $se std::cerr << "[FAILED] " __TX_FILELINE__ ": " #code " == (" << _result << "), should be (" << _expected << ")"; } \ 16030 \ 16031 $n; \ 16032 (_result == _expected); \ 16033 } 16034 16035 //================================================================================================================= 16036 16037 #define $V( var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "]\n") ) 16038 #define $V_( var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "] " ) ) 16039 #define $V__(var, ...) ( _txDumpVar ((var), _tx$PrefixV ( __VA_ARGS__), "]" ) ) 16040 16041 #define $( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]\n") ) 16042 #define $_( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "] " ) ) 16043 #define $__( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ) ) 16044 16045 #define $x( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]\n", ::std::ios_base::showbase | ::std::ios_base::hex) ) 16046 #define $x_( var, ...) ( _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "] ", ::std::ios_base::showbase | ::std::ios_base::hex) ) 16047 16048 #define $v( var, cond, ...) { { $st (cond); _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ); } $n; } 16049 #define $v_( var, cond, ...) { $st (cond); _txDumpVar ((var), _tx$Prefix (#var, __VA_ARGS__), "]" ); } 16050 16051 #define $$ { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __TX_FUNCTION__); } txOutputDebugPrintf ("\f\n"); } 16052 #define $$_ { txOutputDebugPrintf ("\f\n"); { $sC txOutputDebugPrintf ("\f" "[" "%d %s]", __LINE__, __func__); } txOutputDebugPrintf ("\f\n"); } 16053 #define $meow(...) { txOutputDebugPrintf ("\f\n"); { $sc txOutputDebugPrintf ("\f" "[%s:%d %s]", __FILE__, __LINE__, __func__); txOutputDebugPrintf ("\f " __VA_ARGS__); } txOutputDebugPrintf ("\f\n"); } 16054 16055 #define $$$( ... ) ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__),"\n[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") ) 16056 #define $$$_( ... ) ( ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n", _txDumpVar ((__VA_ARGS__), "[" __TX_FILELINE__ ": " #__VA_ARGS__ ": ", ", DONE]\n\n") ) 16057 16058 #define $$$$( ... ) { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix ("\n[" __TX_FILELINE__ ": " #__VA_ARGS__ " DONE]\n\n"); { __VA_ARGS__; } } 16059 #define $$$$_( ... ) { ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; _txDumpVarSuffix ( "[" __TX_FILELINE__ ": " #__VA_ARGS__ " DONE]\n\n"); { __VA_ARGS__; } } 16060 #define $do( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]\n"; __VA_ARGS__ 16061 #define $DO( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; $p; __VA_ARGS__ 16062 #define $Do( ... ) ::std::cerr << "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n"; \ 16063 txMessageBox ( "\n[" __TX_FILELINE__ ": " #__VA_ARGS__ "]...\n", __TX_FUNCTION__); __VA_ARGS__ 16064 16065 #define $n { ::std::cerr << "\n"; } 16066 #define $nn { ::std::cerr << "\n\n"; } 16067 #define $t { ::std::cerr << "\t"; } 16068 16069 #define _tx$PrefixV( ...) ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " ) : ("[" ) ) 16070 #define _tx$Prefix(var, ...) ( *(__VA_ARGS__ "")? ("[" __VA_ARGS__ ": " var " = ") : ("[" var " = ") ) 16071 16072 //----------------------------------------------------------------------------------------------------------------- 16073 16074 // This will never be documented, he-he. Read the source, Luke. 16075 16076 #if defined (_DEBUG) 16077 #define $dbg if (1) 16078 #define $DBG if (1) 16079 #define $debug if (1) 16080 #define $DEBUG if (1) 16081 #define $printf(fmt, ...) if (1) printf ( fmt, ##__VA_ARGS__) 16082 #define $PRINTF(fmt, ...) if (1) fprintf (stderr, fmt, ##__VA_ARGS__) 16083 #else 16084 #define $dbg if (0) 16085 #define $DBG if (0) 16086 #define $debug if (0) 16087 #define $DEBUG if (0) 16088 #define $printf(...) if (0) printf ( fmt, ##__VA_ARGS__) 16089 #define $PRINTF(...) if (0) fprintf (stderr, fmt, ##__VA_ARGS__) 16090 #endif 16091 16092 #define $$d $debug 16093 #define $$w $$$$ 16094 #define $$s __TX_FILELINE__ 16095 #define $$b { txSleep(); DebugBreak(); } 16096 #define $$p { if (txMessageBox (__TX_FILELINE__ "\n\n" "[Повтор] - продолжение программы,\n" "[Отмена] - остановка", \ 16097 __TX_FUNCTION__, MB_ICONINFORMATION | MB_RETRYCANCEL) == IDCANCEL) ::exit (2); } 16098 #define $$P ( txMessageBox (__TX_FILELINE__, __TX_FUNCTION__, MB_ICONINFORMATION | MB_YESNOCANCEL) ) 16099 #define $ppp { $sy; txPause ("\v[%s ""%s: ""Нажмите клавишу]...", __TX_FILELINE__, __TX_FUNCTION__); } 16100 #define $pp { $sy; txPause ("\v[%04d %s: ""Нажмите клавишу]...", __LINE__, __TX_FUNCTION__); } 16101 #define $p { $sy; txPause ("\v[%s ""%s(): Нажмите клавишу]...", __TX_FILELINE__, __func__); } 16102 #define $ppp_ { $sy; txPause ("\v[%s ""%s]...", __TX_FILELINE__, __TX_FUNCTION__); } 16103 #define $pp_ { $sy; txPause ("\v[%04d %s]...", __LINE__, __TX_FUNCTION__); } 16104 #define $p_ { $sy; txPause ("\v[%s ""%s()]...", __TX_FILELINE__, __func__); } 16105 #define $P ( txPause ("") ) 16106 16107 //----------------------------------------------------------------------------------------------------------------- 16108 16109 struct _txSaveConsoleAttr 16110 { 16111 unsigned attr_; 16112 16113 _txSaveConsoleAttr() : attr_ (txGetConsoleAttr ()) {} 16114 explicit _txSaveConsoleAttr (WORD attr) : attr_ (txGetConsoleAttr ()) { txSetConsoleAttr (attr); } 16115 ~_txSaveConsoleAttr() { txSetConsoleAttr (attr_); } 16116 }; 16117 16118 //----------------------------------------------------------------------------------------------------------------- 16119 16120 struct _txDumpVarSuffix 16121 { 16122 typedef _txDumpVarSuffix this_t; 16123 16124 const char* suffix_; 16125 16126 explicit _txDumpVarSuffix (const char suffix[] = "") : suffix_ (suffix) { assert (suffix); } 16127 ~_txDumpVarSuffix() { ::std::cerr << suffix_; } 16128 16129 _txDumpVarSuffix (const this_t&) _tx_delete; 16130 this_t& operator = (const this_t&) _tx_delete; 16131 }; 16132 16133 //----------------------------------------------------------------------------------------------------------------- 16134 16135 #define ARGS__ const char* prefix, const char* suffix, std::ios_base::fmtflags flags, int deep 16136 #define ARGS_ const char* prefix, const char* suffix, std::ios_base::fmtflags flags = std::ios_base::fmtflags(), int deep = 0 16137 #define VALS_ prefix, suffix, flags, deep 16138 #define ERRPTR_(p) { $sE; stream << "<НЕВЕРНЫЙ АДРЕС " << (const void*) (p) << ">"; } 16139 16140 template <typename T, typename StreamT> const T& _txDumpVal (const T& value, StreamT& stream, ARGS_); 16141 16142 //----------------------------------------------------------------------------------------------------------------- 16143 16144 template <typename T> inline const T& _txDumpVar (const T& value, ARGS_) { _txDumpVal (value, std:: cerr, VALS_); return value; } 16145 template <typename T> inline T& _txDumpVar ( T& value, ARGS_) { _txDumpVal (value, std:: cerr, VALS_); return value; } 16146 16147 template <int N> inline const char (&_txDumpVar (const char (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; } 16148 template <int N> inline char (&_txDumpVar ( char (&value) [N], ARGS_)) [N] { _txDumpVal (value, std:: cerr, VALS_); return value; } 16149 16150 template <int N> inline const wchar_t (&_txDumpVar (const wchar_t (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; } 16151 template <int N> inline wchar_t (&_txDumpVar ( wchar_t (&value) [N], ARGS_)) [N] { _txDumpVal (value, std::wcerr, VALS_); return value; } 16152 16153 inline const wchar_t& _txDumpVar (const wchar_t& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16154 inline wchar_t& _txDumpVar ( wchar_t& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16155 16156 inline const wchar_t*& _txDumpVar (const wchar_t*& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16157 inline wchar_t*& _txDumpVar ( wchar_t*& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16158 16159 inline const std::wstring& _txDumpVar (const std::wstring& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16160 inline std::wstring& _txDumpVar ( std::wstring& value, ARGS_) { _txDumpVal (value, std::wcerr, VALS_); return value; } 16161 16162 //----------------------------------------------------------------------------------------------------------------- 16163 16164 template <typename T, typename StreamT> inline void _txDumpVal (const T& value, StreamT& stream) { stream << value; } 16165 template <typename StreamT> inline void _txDumpVal (const char value, StreamT& stream) { stream << "'" << value << "'"; } 16166 template <typename StreamT> inline void _txDumpVal (const wchar_t value, StreamT& stream) { stream << L"'" << value << L"'"; } 16167 template <typename StreamT> inline void _txDumpVal (const std::string& value, StreamT& stream) { stream << '"' << value << '"'; } 16168 template <typename StreamT> inline void _txDumpVal (const std::wstring& value, StreamT& stream) { stream << L'"' << value << L'"'; } 16169 16170 template <typename StreamT> inline void _txDumpVal (const char* value, StreamT& stream) 16171 { 16172 if (_TX_ARGUMENT_FAILED (&stream)) return; 16173 16174 if (!_txIsBadReadPtr (value)) stream << '"' << value << '"'; 16175 else if (!value) stream << "(null)"; 16176 else ERRPTR_ (value); 16177 } 16178 16179 template <typename StreamT> inline void _txDumpVal (const wchar_t* value, StreamT& stream) 16180 { 16181 if (_TX_ARGUMENT_FAILED (&stream)) return; 16182 16183 if (!_txIsBadReadPtr (value)) stream << L'"' << value << L'"'; 16184 else if (!value) stream << L"(null)"; 16185 else ERRPTR_ (value); 16186 } 16187 16188 //----------------------------------------------------------------------------------------------------------------- 16189 16190 template <typename T, typename StreamT> 16191 inline const T& _txDumpVal (const T& value, StreamT& stream, ARGS__) 16192 { 16193 if (_TX_ARGUMENT_FAILED (&stream)) return value; //-V778 16194 if (_TX_ARGUMENT_FAILED ( prefix)) return value; 16195 if (_TX_ARGUMENT_FAILED ( suffix)) return value; 16196 16197 $sc; 16198 if (!deep) stream << prefix; 16199 16200 std::ios_base::fmtflags old = stream.flags ((flags)? flags : stream.flags()); 16201 16202 if (!_txIsBadReadPtr (&value)) 16203 { 16204 _txDumpVal (value, stream); 16205 } 16206 else 16207 ERRPTR_ (&value); 16208 16209 stream.flags (old); 16210 16211 if (!deep) stream << suffix; 16212 16213 return value; 16214 } 16215 16216 //----------------------------------------------------------------------------------------------------------------- 16217 16218 template <typename T, int N> 16219 inline T (&_txDumpVar (T (&value) [N], ARGS_)) [N] 16220 { 16221 if (_TX_ARGUMENT_FAILED ( prefix)) return value; 16222 if (_TX_ARGUMENT_FAILED ( suffix)) return value; 16223 16224 std::ostream& stream = std::cerr; 16225 16226 $sc; if (!deep) std::cerr << prefix; 16227 $C; std::cerr << ((deep)? " {" : "{"); 16228 16229 if (!_txIsBadReadPtr (value)) 16230 { 16231 for (int i = 0; ; i++) 16232 { 16233 { $sC; stream << "[" << i << "]="; } 16234 16235 _txDumpVar (value[i], prefix, suffix, flags, deep+1); 16236 16237 if (i >= N-1) break; 16238 16239 stream << ", "; 16240 } 16241 } 16242 else 16243 ERRPTR_ (&value); 16244 16245 $C; std::cerr << "}"; 16246 $c; if (!deep) std::cerr << suffix; 16247 16248 return value; 16249 } 16250 16251 //================================================================================================================= 16252 16253 inline std::ostream& operator << (std::ostream& stream, const POINT& point) 16254 { 16255 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16256 16257 if (!_txIsBadReadPtr (&point)) stream << "{ x: " << point.x << ", y: " << point.y << " }"; // NOLINT (clang-diagnostic-undefined-bool-conversion) 16258 else if (!&point) stream << "(null)"; 16259 else ERRPTR_ (&point); 16260 16261 return stream; 16262 } 16263 16264 inline std::ostream& operator << (std::ostream& stream, const SIZE& size) 16265 { 16266 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16267 16268 if (&size) stream << "{ cx: " << size.cx << ", cy: " << size.cy << " }"; // NOLINT (clang-diagnostic-undefined-bool-conversion) 16269 else stream << "(null)"; 16270 16271 return stream; 16272 } 16273 16274 inline std::ostream& operator << (std::ostream& stream, const RECT& rect) 16275 { 16276 if (_TX_ARGUMENT_FAILED (&stream)) return stream; 16277 16278 if (&rect) stream << "{ left: " << rect.left << ", top: " << rect.top << // NOLINT (clang-diagnostic-undefined-bool-conversion) 16279 ", right: " << rect.right << ", bottom: " << rect.bottom << " }"; 16280 16281 else stream << "(null)"; 16282 16283 return stream; 16284 } 16285 16286 //----------------------------------------------------------------------------------------------------------------- 16287 16288 #undef ARGS__ 16289 #undef ARGS_ 16290 #undef VALS_ 16291 #undef ERRPTR_ 16292 16293 //----------------------------------------------------------------------------------------------------------------- 16295 16296 #endif 16297 16298 //} 16299 //================================================================================================================= 16300 16302 16303 //================================================================================================================= 16304 //{ TXAPI calls tracing 16305 // Трассировка вызовов TXAPI 16306 //================================================================================================================= 16307 16308 #ifndef FOR_DOXYGEN_ONLY 16309 16310 #if defined (_MSC_VER) 16311 #undef _txLocCurSet 16312 #define _txLocCurSet() __txLocCurSet (__FILE__, __LINE__, NULL) 16313 #endif 16314 16315 #define txAlphaBlend(...) ( _txLocCurSet(), txAlphaBlend (__VA_ARGS__) ) 16316 #define txArc(...) ( _txLocCurSet(), txArc (__VA_ARGS__) ) 16317 #define txBegin(...) ( _txLocCurSet(), txBegin (__VA_ARGS__) ) 16318 #define txBitBlt(...) ( _txLocCurSet(), txBitBlt (__VA_ARGS__) ) 16319 #define txChord(...) ( _txLocCurSet(), txChord (__VA_ARGS__) ) 16320 #define txCircle(...) ( _txLocCurSet(), txCircle (__VA_ARGS__) ) 16321 #define txClear(...) ( _txLocCurSet(), txClear (__VA_ARGS__) ) 16322 #define txClearConsole(...) ( _txLocCurSet(), txClearConsole (__VA_ARGS__) ) 16323 #define txColor(...) ( _txLocCurSet(), txColor (__VA_ARGS__) ) 16324 #define txCreateCompatibleDC(...) ( _txLocCurSet(), txCreateCompatibleDC (__VA_ARGS__) ) 16325 #define txCreateDIBSection(...) ( _txLocCurSet(), txCreateDIBSection (__VA_ARGS__) ) 16326 #define txCreateExtraWindow(...) ( _txLocCurSet(), txCreateExtraWindow (__VA_ARGS__) ) 16327 #define txCreateWindow(...) ( _txLocCurSet(), txCreateWindow (__VA_ARGS__) ) 16328 #define txDC(...) ( _txLocCurSet(), txDC (__VA_ARGS__) ) 16329 #define txDeleteDC(...) ( _txLocCurSet(), txDeleteDC (__VA_ARGS__) ) 16330 #define txDemangle(...) ( _txLocCurSet(), txDemangle (__VA_ARGS__) ) 16331 #define txDestroyWindow(...) ( _txLocCurSet(), txDestroyWindow (__VA_ARGS__) ) 16332 #define txDisableAutoPause(...) ( _txLocCurSet(), txDisableAutoPause (__VA_ARGS__) ) 16333 #define txDrawText(...) ( _txLocCurSet(), txDrawText (__VA_ARGS__) ) 16334 #define txEllipse(...) ( _txLocCurSet(), txEllipse (__VA_ARGS__) ) 16335 #define txEnd(...) ( _txLocCurSet(), txEnd (__VA_ARGS__) ) 16336 #define txExtractColor(...) ( _txLocCurSet(), txExtractColor (__VA_ARGS__) ) 16337 #define txFillColor(...) ( _txLocCurSet(), txFillColor (__VA_ARGS__) ) 16338 #define txFloodFill(...) ( _txLocCurSet(), txFloodFill (__VA_ARGS__) ) 16339 #define txFontExist(...) ( _txLocCurSet(), txFontExist (__VA_ARGS__) ) 16340 #define txFormat(...) ( _txLocCurSet(), txFormat (__VA_ARGS__) ) 16341 #define txGetAsyncKeyState(...) ( _txLocCurSet(), txGetAsyncKeyState (__VA_ARGS__) ) 16342 #define txGetColor(...) ( _txLocCurSet(), txGetColor (__VA_ARGS__) ) 16343 #define txGetConsoleAttr(...) ( _txLocCurSet(), txGetConsoleAttr (__VA_ARGS__) ) 16344 #define txGetConsoleCursorPos(...) ( _txLocCurSet(), txGetConsoleCursorPos (__VA_ARGS__) ) 16345 #define txGetConsoleExtent(...) ( _txLocCurSet(), txGetConsoleExtent (__VA_ARGS__) ) 16346 #define txGetConsoleFontSize(...) ( _txLocCurSet(), txGetConsoleFontSize (__VA_ARGS__) ) 16347 #define txGetExtent(...) ( _txLocCurSet(), txGetExtent (__VA_ARGS__) ) 16348 #define txGetExtentX(...) ( _txLocCurSet(), txGetExtentX (__VA_ARGS__) ) 16349 #define txGetExtentY(...) ( _txLocCurSet(), txGetExtentY (__VA_ARGS__) ) 16350 #define txGetFillColor(...) ( _txLocCurSet(), txGetFillColor (__VA_ARGS__) ) 16351 #define txGetFPS(...) ( _txLocCurSet(), txGetFPS (__VA_ARGS__) ) 16352 #define txGetModuleFileName(...) ( _txLocCurSet(), txGetModuleFileName (__VA_ARGS__) ) 16353 #define txGetPixel(...) ( _txLocCurSet(), txGetPixel (__VA_ARGS__) ) 16354 #define txGetTextExtent(...) ( _txLocCurSet(), txGetTextExtent (__VA_ARGS__) ) 16355 #define txGetTextExtentX(...) ( _txLocCurSet(), txGetTextExtentX (__VA_ARGS__) ) 16356 #define txGetTextExtentY(...) ( _txLocCurSet(), txGetTextExtentY (__VA_ARGS__) ) 16357 #define txHSL2RGB(...) ( _txLocCurSet(), txHSL2RGB (__VA_ARGS__) ) 16358 #define txInputBox(...) ( _txLocCurSet(), txInputBox (__VA_ARGS__) ) 16359 #define txLine(...) ( _txLocCurSet(), txLine (__VA_ARGS__) ) 16360 #define txLoadImage(...) ( _txLocCurSet(), txLoadImage (__VA_ARGS__) ) 16361 #define txLock(...) ( _txLocCurSet(), txLock (__VA_ARGS__) ) 16362 #define txMessageBox(...) ( _txLocCurSet(), txMessageBox (__VA_ARGS__) ) 16363 #define txMouseButtons(...) ( _txLocCurSet(), txMouseButtons (__VA_ARGS__) ) 16364 #define txMousePos(...) ( _txLocCurSet(), txMousePos (__VA_ARGS__) ) 16365 #define txMouseX(...) ( _txLocCurSet(), txMouseX (__VA_ARGS__) ) 16366 #define txMouseY(...) ( _txLocCurSet(), txMouseY (__VA_ARGS__) ) 16367 #define txNotifyIcon(...) ( _txLocCurSet(), txNotifyIcon (__VA_ARGS__) ) 16368 #define txOK(...) ( _txLocCurSet(), txOK (__VA_ARGS__) ) 16369 #define txOutputDebugPrintf(...) ( _txLocCurSet(), txOutputDebugPrintf (__VA_ARGS__) ) 16370 #define txPause(...) ( _txLocCurSet(), txPause (__VA_ARGS__) ) 16371 #define txPie(...) ( _txLocCurSet(), txPie (__VA_ARGS__) ) 16372 #define txPixel(...) ( _txLocCurSet(), txPixel (__VA_ARGS__) ) 16373 #define txPlaySound(...) ( _txLocCurSet(), txPlaySound (__VA_ARGS__) ) 16374 #define txPlayVideo(...) ( _txLocCurSet(), txPlayVideo (__VA_ARGS__) ) 16375 #define txPolygon(...) ( _txLocCurSet(), txPolygon (__VA_ARGS__) ) 16376 #define txPrintf(...) ( _txLocCurSet(), txPrintf (__VA_ARGS__) ) 16377 #define txQueryPerformance(...) ( _txLocCurSet(), txQueryPerformance (__VA_ARGS__) ) 16378 #define txRectangle(...) ( _txLocCurSet(), txRectangle (__VA_ARGS__) ) 16379 #define txRedrawWindow(...) ( _txLocCurSet(), txRedrawWindow (__VA_ARGS__) ) 16380 #define txRegisterClass(...) ( _txLocCurSet(), txRegisterClass (__VA_ARGS__) ) 16381 #define txRegQuery(...) ( _txLocCurSet(), txRegQuery (__VA_ARGS__) ) 16382 #define txReopenStdio(...) ( _txLocCurSet(), txReopenStdio (__VA_ARGS__) ) 16383 #define txRGB2HSL(...) ( _txLocCurSet(), txRGB2HSL (__VA_ARGS__) ) 16384 #define txSaveImage(...) ( _txLocCurSet(), txSaveImage (__VA_ARGS__) ) 16385 #define txSelectFont(...) ( _txLocCurSet(), txSelectFont (__VA_ARGS__) ) 16386 #define txSelectObject(...) ( _txLocCurSet(), txSelectObject (__VA_ARGS__) ) 16387 #define txSetColor(...) ( _txLocCurSet(), txSetColor (__VA_ARGS__) ) 16388 #define txSetConsoleAttr(...) ( _txLocCurSet(), txSetConsoleAttr (__VA_ARGS__) ) 16389 #define txSetConsoleCursorPos(...) ( _txLocCurSet(), txSetConsoleCursorPos (__VA_ARGS__) ) 16390 #define txSetDefaults(...) ( _txLocCurSet(), txSetDefaults (__VA_ARGS__) ) 16391 #define txSetFillColor(...) ( _txLocCurSet(), txSetFillColor (__VA_ARGS__) ) 16392 #define txSetLocale(...) ( _txLocCurSet(), txSetLocale (__VA_ARGS__) ) 16393 #define txSetPixel(...) ( _txLocCurSet(), txSetPixel (__VA_ARGS__) ) 16394 #define txSetProgress(...) ( _txLocCurSet(), txSetProgress (__VA_ARGS__) ) 16395 #define txSetTextAlign(...) ( _txLocCurSet(), txSetTextAlign (__VA_ARGS__) ) 16396 #define txSetWindowsHook(...) ( _txLocCurSet(), txSetWindowsHook (__VA_ARGS__) ) 16397 #define txSleep(...) ( _txLocCurSet(), txSleep (__VA_ARGS__) ) 16398 #define txSpeak(...) ( _txLocCurSet(), txSpeak (__VA_ARGS__) ) 16399 #define txTextCursor(...) ( _txLocCurSet(), txTextCursor (__VA_ARGS__) ) 16400 #define txTextOut(...) ( _txLocCurSet(), txTextOut (__VA_ARGS__) ) 16401 #define txTransparentBlt(...) ( _txLocCurSet(), txTransparentBlt (__VA_ARGS__) ) 16402 #define txTriangle(...) ( _txLocCurSet(), txTriangle (__VA_ARGS__) ) 16403 #define txUnlock(...) ( _txLocCurSet(), txUnlock (__VA_ARGS__) ) 16404 #define txUpdateWindow(...) ( _txLocCurSet(), txUpdateWindow (__VA_ARGS__) ) 16405 #define txUseAlpha(...) ( _txLocCurSet(), txUseAlpha (__VA_ARGS__) ) 16406 #define txVersion(...) ( _txLocCurSet(), txVersion (__VA_ARGS__) ) 16407 #define txVersionNumber(...) ( _txLocCurSet(), txVersionNumber (__VA_ARGS__) ) 16408 #define txWindow(...) ( _txLocCurSet(), txWindow (__VA_ARGS__) ) 16409 #define tx_fpreset(...) ( _txLocCurSet(), tx_fpreset (__VA_ARGS__) ) 16410 #define tx_glGetError(...) ( _txLocCurSet(), tx_glGetError (__VA_ARGS__) ) 16411 #define _txDump(...) ( _txLocCurSet(), _txDump (__VA_ARGS__) ) 16412 #define _txStackBackTrace(...) ( _txLocCurSet(), _txStackBackTrace (__VA_ARGS__) ) 16413 16414 #endif 16415 16416 //} 16417 //================================================================================================================= 16418 16420 //} 16421 //================================================================================================================= 16422 16423 //----------------------------------------------------------------------------------------------------------------- 16424 //{ The namespaces 16425 //----------------------------------------------------------------------------------------------------------------- 16426 16429 _TX_END_NAMESPACE 16430 16433 using namespace TX; // Allow easy usage of TXLib functions 16434 16435 using ::std::cin; // Predefined usings to avoid "using namespace std" 16436 using ::std::cout; 16437 using ::std::cerr; 16438 using ::std::string; 16439 using ::std::wcin; 16440 using ::std::wcout; 16441 using ::std::wcerr; 16442 using ::std::wstring; 16443 16444 //} 16445 //----------------------------------------------------------------------------------------------------------------- 16446 16447 //----------------------------------------------------------------------------------------------------------------- 16448 //{ Compiler- and platform-specific 16449 // Адаптация к компиляторам и платформам 16450 //----------------------------------------------------------------------------------------------------------------- 16452 16453 #if defined (_GCC_VER) 16454 16455 #pragma GCC optimize "strict-aliasing" 16456 16457 #pragma GCC pop_options 16458 #pragma GCC diagnostic pop 16459 16460 #endif 16461 16462 #if defined (_CLANG_VER) 16463 16464 #pragma clang diagnostic pop 16465 16466 #endif 16467 16468 //----------------------------------------------------------------------------------------------------------------- 16469 16470 #if defined (_MSC_VER) 16471 16472 #pragma warning (pop) // Restoring maximum level 16473 16474 #endif 16475 16476 #if defined (__INTEL_COMPILER) 16477 16478 #pragma warning (default: 174) // Remark: expression has no effect 16479 #pragma warning (default: 304) // Remark: access control not specified ("public" by default) 16480 #pragma warning (default: 444) // Remark: destructor for base class "..." is not virtual 16481 #pragma warning (default: 522) // Remark: function redeclared "inline" after being called 16482 #pragma warning (default: 1684) // Conversion from pointer to same-sized integral type (potential portability problem) 16483 16484 #pragma warning (disable: 981) // Remark: operands are evaluated in unspecified order 16485 16486 #endif 16487 16489 //} 16490 //----------------------------------------------------------------------------------------------------------------- 16491 16492 #endif // __TXLIB_H_INCLUDED 16493 16494 //================================================================================================================= 16495 // EOF 16496 //================================================================================================================= 16497 16498 16499