| 13652 | |
| 13653 | |
| 13654 | LPTSTR Script::ListKeyHistory(LPTSTR aBuf, int aBufSize) // aBufSize should be an int to preserve negatives from caller (caller relies on this). |
| 13655 | // aBufSize is an int so that any negative values passed in from caller are not lost. |
| 13656 | // Translates this key history into text equivalent, putting the result |
| 13657 | // into aBuf and returning the position in aBuf of its new string terminator. |
| 13658 | { |
| 13659 | LPTSTR aBuf_orig = aBuf; // Needed for the BUF_SPACE_REMAINING macro. |
| 13660 | // I was initially concerned that GetWindowText() can hang if the target window is |
| 13661 | // hung. But at least on newer OS's, this doesn't seem to be a problem: MSDN says |
| 13662 | // "If the window does not have a caption, the return value is a null string. This |
| 13663 | // behavior is by design. It allows applications to call GetWindowText without hanging |
| 13664 | // if the process that owns the target window is hung. However, if the target window |
| 13665 | // is hung and it belongs to the calling application, GetWindowText will hang the |
| 13666 | // calling application." |
| 13667 | HWND target_window = GetForegroundWindow(); |
| 13668 | TCHAR win_title[100]; |
| 13669 | if (target_window) |
| 13670 | GetWindowText(target_window, win_title, _countof(win_title)); |
| 13671 | else |
| 13672 | *win_title = '\0'; |
| 13673 | |
| 13674 | TCHAR timer_list[128]; |
| 13675 | *timer_list = '\0'; |
| 13676 | for (ScriptTimer *timer = mFirstTimer; timer != NULL; timer = timer->mNextTimer) |
| 13677 | if (timer->mEnabled) |
| 13678 | sntprintfcat(timer_list, _countof(timer_list) - 3, _T("%s "), timer->mCallback->Name()); // Allow room for "..." |
| 13679 | if (*timer_list) |
| 13680 | { |
| 13681 | size_t length = _tcslen(timer_list); |
| 13682 | if (length > (_countof(timer_list) - 5)) |
| 13683 | tcslcpy(timer_list + length, _T("..."), _countof(timer_list) - length); |
| 13684 | else if (timer_list[length - 1] == ' ') |
| 13685 | timer_list[--length] = '\0'; // Remove the last space if there was room enough for it to have been added. |
| 13686 | } |
| 13687 | |
| 13688 | TCHAR LRtext[256]; |
| 13689 | aBuf += sntprintf(aBuf, aBufSize, |
| 13690 | _T("Window: %s") |
| 13691 | //"\r\nBlocks: %u" |
| 13692 | _T("\r\nKeybd hook: %s") |
| 13693 | _T("\r\nMouse hook: %s") |
| 13694 | _T("\r\nEnabled Timers: %u of %u (%s)") |
| 13695 | //"\r\nInterruptible?: %s" |
| 13696 | _T("\r\nInterrupted threads: %d%s") |
| 13697 | _T("\r\nPaused threads: %d of %d (%d layers)") |
| 13698 | _T("\r\nModifiers (GetKeyState() now) = %s") |
| 13699 | _T("\r\n") |
| 13700 | , win_title |
| 13701 | //, SimpleHeap::GetBlockCount() |
| 13702 | , g_KeybdHook == NULL ? _T("no") : _T("yes") |
| 13703 | , g_MouseHook == NULL ? _T("no") : _T("yes") |
| 13704 | , mTimerEnabledCount, mTimerCount, timer_list |
| 13705 | //, INTERRUPTIBLE ? "yes" : "no" |
| 13706 | , g_nThreads > 1 ? g_nThreads - 1 : 0 |
| 13707 | , g_nThreads > 1 ? _T(" (preempted: they will resume when the current thread finishes)") : _T("") |
| 13708 | , g_nPausedThreads - (g_array[0].IsPaused && !mAutoExecSectionIsRunning) // Historically thread #0 isn't counted as a paused thread unless the auto-exec section is running but paused. |
| 13709 | , g_nThreads, g_nLayersNeedingTimer |
| 13710 | , ModifiersLRToText(GetModifierLRState(true), LRtext)); |
| 13711 | GetHookStatus(aBuf, BUF_SPACE_REMAINING); |
no test coverage detected