FreeBasic
Главная
Вход
Регистрация
Пятница, 02.10.2026, 19:02Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
пауза в консольном окне
VitaminДата: Пятница, 14.08.2026, 12:08 | Сообщение # 1
Лейтенант
Группа: Пользователи
Сообщений: 73
Репутация: 4
Статус: Offline
Если в окне консольной программы, например rar.exe или 7za.exe щелкнуть мышкой, то она останавливается. При нажатии на любую клавишу она снимается с паузы и продолжает выполняться. Как такое поведение реализовать в проге на FreeBasic?

Сообщение отредактировал Vitamin - Пятница, 14.08.2026, 12:10
 
haavДата: Пятница, 14.08.2026, 16:41 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1480
Репутация: 50
Статус: Offline
Так вроде ReadConsoleInput умеет ловить и мышь и клаву.

Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
VitaminДата: Пятница, 14.08.2026, 18:10 | Сообщение # 3
Лейтенант
Группа: Пользователи
Сообщений: 73
Репутация: 4
Статус: 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
Репутация: -1
Статус: 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
Репутация: 4
Статус: Offline
DarkDemon, 
Цитата
А можно пример запуска 7za?
Обычный запуск в командной строке. Чтобы это работало на 7-ке нужно щелкнуть ПКМ в заголовке консольного окна -> Свойства -> поставить галку Выделение Мышью. На 10-ке этот режим включен по умолчанию и дополнительных манипуляций не требуется.
 
DarkDemonДата: Среда, 19.08.2026, 21:39 | Сообщение # 6
Генерал-майор
Группа: Друзья
Сообщений: 352
Репутация: -1
Статус: 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
Репутация: 5
Статус: Offline
Нет, NTSTATUS это 32‐битное значение

Вот мои доказательства:
https://learn.microsoft.com/en-us....c81e781
 
DarkDemonДата: Четверг, 20.08.2026, 14:42 | Сообщение # 8
Генерал-майор
Группа: Друзья
Сообщений: 352
Репутация: -1
Статус: 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
 
  • Страница 1 из 1
  • 1
Поиск: