|
пауза в консольном окне
|
|
| Vitamin | Дата: Пятница, 14.08.2026, 12:08 | Сообщение # 1 |
|
Лейтенант
Группа: Пользователи
Сообщений: 73
Статус: Offline
| Если в окне консольной программы, например rar.exe или 7za.exe щелкнуть мышкой, то она останавливается. При нажатии на любую клавишу она снимается с паузы и продолжает выполняться. Как такое поведение реализовать в проге на FreeBasic?
Сообщение отредактировал Vitamin - Пятница, 14.08.2026, 12:10 |
| |
|
|
| haav | Дата: Пятница, 14.08.2026, 16:41 | Сообщение # 2 |
 Генералиссимус
Группа: Администраторы
Сообщений: 1480
Статус: Offline
| Так вроде ReadConsoleInput умеет ловить и мышь и клаву.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
| |
|
|
| Vitamin | Дата: Пятница, 14.08.2026, 18:10 | Сообщение # 3 |
|
Лейтенант
Группа: Пользователи
Сообщений: 73
Статус: Offline
| Вообще это не в проге зашито, а в работе Windows с консольным окном. Цитата Если консоль зависает или ставится на паузу при клике мыши, это происходит из-за включенного режима QuickEdit (Быстрое редактирование) в Windows. Когда вы кликаете внутри окна, терминал переходит в режим выделения текста, блокируя выполнение программы. Было предположение, что есть какой-нибудь ключ компилятора для включения этой функции, но ничего не нашел.
Добавлено (15.08.2026, 19:46) --------------------------------------------- Google ИИ выдал мне с пятой попытки примерно такой код:Код #include once "windows.bi" #include once "crt.bi" ' Подключаем CRT для прямого вывода без буферизации FreeBASIC
' Получаем дескриптор ввода консоли Dim As HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE) Dim As DWORD cmode
' Полностью очищаем режим ввода и принудительно выставляем флаги QuickEdit GetConsoleMode(hInput, @cmode) cmode = ENABLE_EXTENDED_FLAGS Or ENABLE_QUICK_EDIT_MODE SetConsoleMode(hInput, cmode)
Print "=== QuickEdit Тест на FreeBASIC ===" Print "Кликните ЛЕВОЙ кнопкой мыши прямо по тексту ниже." Print "Программа остановится (в заголовке окна появится 'Выбрать')." Print "Нажмите ENTER для продолжения работы." Print "-----------------------------------------------------------"
Do Printf(".") ' Прямой вывод через printf гарантирует, что Windows поймает блокировку Sleep(30) Loop
Он работает. Причем работает даже если режим консоли не переключать, а использовать только printf: Код #include once "windows.bi" #include once "crt.bi" ' Подключаем CRT для прямого вывода без буферизации FreeBASIC
Print "Кликните ЛЕВОЙ кнопкой мыши прямо по тексту ниже." Print "Программа остановится (в заголовке окна появится 'Выбрать')." Print "Нажмите ENTER для продолжения работы."
Do Printf(".") ' Прямой вывод через printf гарантирует, что Windows поймает блокировку Sleep(30) Loop
Цитата >работает даже без переключения режима консоли, достаточно Printf(".")
Вы абсолютно правы! Ваше наблюдение очень точное. На самом деле, в современных версиях Windows режим QuickEdit по умолчанию включен для всех окон командной строки. Поэтому, как только мы заменили встроенный Print из FreeBASIC на стандартный printf из библиотеки Си, всё сразу заработало «из коробки».
Сообщение отредактировал Vitamin - Суббота, 15.08.2026, 19:55 |
| |
|
|
| DarkDemon | Дата: Понедельник, 17.08.2026, 23:25 | Сообщение # 4 |
|
Генерал-майор
Группа: Друзья
Сообщений: 352
Статус: Offline
| Хотел тоже создать подобную тему. Пошерстить. Ну давайте вместе пошерстим. Думаю надо дать фокус на окно и отправить pause break.
Добавлено (18.08.2026, 18:02) ---------------------------------------------
Цитата Vitamin (  ) Он работает. А можно пример запуска 7za? Как оно должно работать? У меня 7za просто так не запускается, запускается только через командную строку винды, либо командой SHELL в FB. (При этом пути там в кавычках, т.е. CHR(34) ) И только с параметрами распаковки. Т.е. всё что таким образом выводится выводится в системную консоль, а у неё нету описанного поведения остановки по клику(ЛКМ?). Есть остановка по Pause Break и есть остановка по ПКМ -> Пометить. Это на 7-ке. На других не запускал.
Просто не очень понятна конечная цель, нужно именно для 7za сделать останов(управляя 7zip-ом в своей программе), или у себя в проге тормозить по клику на консольное окно, без привязки к 7za?
Я вот думал пошерстить заморозку любого консольного окна(да и не только консольного, а вообще любого процесса). Для этого есть две недокументированные функции винды:
NtSuspendProcess и NtResumeProcess.
Но код пока не пойму как наваять, как их подключить правильно, в хедерах их не видно. Если честно забыл уже как динамические эти штуки подключаются, там вроде тип для функции надо создать, но как в типе указать библиотеку (ntdll) ...
Сообщение отредактировал DarkDemon - Вторник, 18.08.2026, 18:03 |
| |
|
|
| Vitamin | Дата: Среда, 19.08.2026, 19:31 | Сообщение # 5 |
|
Лейтенант
Группа: Пользователи
Сообщений: 73
Статус: Offline
| DarkDemon, Цитата А можно пример запуска 7za? Обычный запуск в командной строке. Чтобы это работало на 7-ке нужно щелкнуть ПКМ в заголовке консольного окна -> Свойства -> поставить галку Выделение Мышью. На 10-ке этот режим включен по умолчанию и дополнительных манипуляций не требуется.
|
| |
|
|
| DarkDemon | Дата: Среда, 19.08.2026, 21:39 | Сообщение # 6 |
|
Генерал-майор
Группа: Друзья
Сообщений: 352
Статус: Offline
| Короче. Открыв свои старые исходники, вспомнил, разрулил. Пользуйтесь.
Осн код:
Код #DEFINE UNICODE
#INCLUDE ONCE "Windows.bi" #INCLUDE ONCE "Win\tlhelp32.bi"
TYPE NTSTATUS AS ULONG
DECLARE FUNCTION NtSuspendProcess LIB "ntdll" ALIAS "NtSuspendProcess" (BYVAL ProcessHandle as HANDLE) as NTSTATUS DECLARE FUNCTION NtResumeProcess LIB "ntdll" ALIAS "NtResumeProcess" (BYVAL ProcessHandle as HANDLE) as NTSTATUS DECLARE FUNCTION GetPIDByName (processName AS STRING) AS ULONG
DIM targetPid AS ULONG DIM hProcess AS HANDLE
SHELL "START TESTPRC.exe" ' Запустим в фоне процесс SLEEP 100
targetPid = GetPIDByName("TESTPRC.exe") PRINT targetPid
SLEEP 1000
' Откроем процесс с правами suspend/resume hProcess = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, targetPid)
IF hProcess <> NULL THEN DIM status AS NTSTATUS
' Заморозить! status = NtSuspendProcess(hProcess)
' Статус процесса IF status = 0 THEN PRINT "Process suspended successfully." ELSE PRINT "Failed to suspend process. NTSTATUS: "; HEX(status) END IF ' Удержим процесс замороженным 3 секунды SLEEP 3000 ' Продолжить status = NtResumeProcess(hProcess)
' Статус процесса IF status = 0 THEN PRINT "Process reactivated." ELSE PRINT "Failed to reactivate process. NTSTATUS: "; HEX(status) END IF
' Закрыть хендл CloseHandle(hProcess) ELSE PRINT "Could not open process. Check PID or privileges." END IF
SLEEP 4500 END
FUNCTION GetPIDByName(processName AS STRING) AS ULONG DIM pid AS ULONG = 0 DIM snapshot AS HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) IF (snapshot = INVALID_HANDLE_VALUE) THEN RETURN 0
DIM entry AS PROCESSENTRY32W entry.dwSize = SIZEOF(entry)
IF (Process32First(snapshot, @entry)) THEN DO IF entry.szExeFile = processName THEN pid = entry.th32ProcessID EXIT DO ' break END IF LOOP WHILE (Process32Next(snapshot, @entry)) END IF
CloseHandle(snapshot) RETURN pid END FUNCTION
[ TESTPRC.bas ] - процесс который останавливаем.
Код DIM Q AS INTEGER DO PRINT "*"; SLEEP 50 Q = Q + 1 LOOP UNTIL Q > 159 OR INKEY <> ""
При остановке самого себя последствия оного, думаю, понятны.
Добавлено (19.08.2026, 21:49) --------------------------------------------- Кстати экспериментально было выявлено что NTSTATUS не ULONG(как нам говорит гугл) a ULONGINT. (дал значение 64 бита и посмотрел сколько функция заполняет). Судя по всему с 32 битных исходников, лучше конечно переопределить платформозависимую размерность (UINTEGER). Просто не пишу под 32 бита сейчас, поэтому учитываем, кому важно.
Сообщение отредактировал DarkDemon - Пятница, 21.08.2026, 15:31 |
| |
|
|
| zamabuvaraeu | Дата: Четверг, 20.08.2026, 03:45 | Сообщение # 7 |
|
Полковник
Группа: Друзья
Сообщений: 220
Статус: Offline
| Нет, NTSTATUS это 32‐битное значение
Вот мои доказательства: https://learn.microsoft.com/en-us....c81e781
|
| |
|
|
| DarkDemon | Дата: Четверг, 20.08.2026, 14:42 | Сообщение # 8 |
|
Генерал-майор
Группа: Друзья
Сообщений: 352
Статус: Offline
| Цитата zamabuvaraeu (  ) Нет, NTSTATUS это 32‐битное значение На 64 бит ос. Проведи эксперимент, назначь его 64 битным, положи все биты единицы, посмотри сколько заполнит функция. Просто уже не в первый раз так опростоволошиваюсь, что потом другие места затирают эти оставшиеся 32 бита. Потому вынужден проверять. Последний бит в дополнительном коде - определяет знак. Если число зануляется полностью, это означает что старшие байты тоже перезаписались.Добавлено (20.08.2026, 14:52) --------------------------------------------- Я бы не парился если бы были прототипы этих функций в хедерах. Но найти их не удалось. Добавлено (20.08.2026, 21:16) --------------------------------------------- Короче zamabuvaraeu прав, я слишком большим кол-вом независимости деталей наделил компилятор. В данном случае заполнял байты именно компилятор, приводя тип под задекларированный. Поэтому можно оставлять ULONG.
Сообщение отредактировал DarkDemon - Четверг, 20.08.2026, 14:46 |
| |
|
|
|