powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Эмуляция нажатия клавиши для досовской программы
14 сообщений из 14, страница 1 из 1
Эмуляция нажатия клавиши для досовской программы
    #39990506
1man
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нуждаюсь в помощи профессионалов.
Имеется древняя досовская прога, сделанная в модном тогда «интерактивном режиме». Чтобы обернуть её в современный интерфейс, необходимо эмулировать нажатие кнопок клавиатуры для досовской проги.
Тренировка на стандартном калькуляторе прошла успешно (в приведенном ниже коде закомментированные строки). handle и handleW (закомментированно) совпадают с тем, что пишется в Spy++ , т.е. досовской окно вроде как найдено правильно и сделано активным. Но оно никак не реагирует на SendKeys.SendWait. Даже не представляю куда копать.


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
        // Get a handle to an application window.
        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(string lpClassName,
            string lpWindowName);

        // Activate an application window.
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
...............

            Process process = new Process();

            //process.StartInfo.FileName = @"CALC.EXE";
            process.StartInfo.WorkingDirectory = @"D:\ED_13";
            process.StartInfo.FileName = @"HELIX.EXE";

            process.Start();

            MessageBox.Show("Continue?");
            IntPtr handle = process.MainWindowHandle;
            //IntPtr handleW = FindWindow("ConsoleWindowClass", @"D:\ED_13\HELIX.EXE");
            //IntPtr handleW = FindWindow("CalcFrame", @"Калькулятор");
            bool h;
            if (handle == IntPtr.Zero)
            {
                MessageBox.Show("Calculator from process is not running.");
                return;
            }
            else
                h = SetForegroundWindow(handle);

            SendKeys.SendWait("777");

Модератор: Учимся использовать тэги оформления кода - FAQ
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990523
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чет не совсем понятно, SendKeys ни как не настроен на полученный Handle, сообщения отправляются не в окно, которое вы нашли, а в окно в котором искали.
на счет ввода в консоль, то у консоли есть 2 потока (условно) для ввода и вывода, возможно стоит получить поток ввода и передавать туда нужные данные.
Либо через WM_KEYDOWN передавать события нажатия на кнопку в окно которое вы нашли по средствам API PostMessage, но делать это надо для найденного окна, а не для окна в котором вы икали
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990535
1man
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes,

Насколько я понял пример из
https://docs.microsoft.com/ru-ru/dotnet/framework/winforms/how-to-simulate-mouse-and-keyboard-events-in-code
«настройка» SendKeys не требуется, так как команда посылается в активное окно (SetForegroundWindow(handle)), которое и определяется найденным handle-ом, что подтвержается успешной работой со стандартным калькулятором (см. закомментированные строки).
А вот с потоками ввода и вывода можно подробнее как их получить?
И пример с WM_KEYDOWN?
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990541
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1man,

в активное окно вашего приложения, а не чужого, активное окно, не равно текущему
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990551
1man
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes, Не понял, что такое текущее окно, но как явствует из примера по ссылке и это работает с калькулятором, (если раскомментировать строки), окно, в которое посылается SendKeys.SendWait определяется SetForegroundWindow. Разве не так?
В моё приложение SendKeys.SendWait посылается, если не срабатывает SetForegroundWindow и активным остается моё окно, это я видел. Но сейчас активно досовское окно, как и в примере с калькулятором.
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990582
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes

на счет ввода в консоль, то у консоли есть 2 потока (условно) для ввода и вывода, возможно стоит получить поток ввода и передавать туда нужные данные.


Может не работать: некоторые дос-программы (особенно "интерактивные", написанные на TurboVision, например), читают данные прямо с клавиатуры (через прерывания BIOS), а не из stdin
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990584
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1man
Нуждаюсь в помощи профессионалов.
Имеется древняя досовская прога, сделанная в модном тогда «интерактивном режиме».


Это точно дос-программа, а не консольная? А то было когда-то обсуждение: 7071846
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990657
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1man
Нуждаюсь в помощи профессионалов.

Я не профессионал, только учусь, попробовал разобраться в Вашей проблеме (кроме этого, я не спец в дотнет, совсем):
1. Нужно найти правильное окно: мне кажется, Process.Start, для получения MainWindowHandle, может использовать WaitForInputIdle, который не работает для консольных (и дос) приложений. Для проверки, самый простой способ - ввести небольшую задержку между созданием процесса и получением его окна.
2. Для поиска нужного окна я использовал EnumWindows, в процедуре обратного вызова через GetWindowThreadProcessId получал Id процесса для окна и сравнивал его с id созданного процесса - так я получал окно созданного процесса, ему уже можно слать wm_key* - и это работает! (для консольных и дос- приложений)

Существенной проблемой я бы назвал определение момента, когда новый процесс создал окно ( я не заморачивался, просто ждал секунду).

Удачи!
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990663
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x1ca4064
Существенной проблемой я бы назвал

Существенной проблемой я бы назвал то, что консольные окна не работают с оконными сообщениями (WM_KEYUP/WM_KEYDOWN etc), т.к. у консоли отсутствует message pump, а SendKeys именно посылают оконные сообщения. В таких случаях в input buffer консоли пишут ( WriteConsoleInput ) нужным образом сформированный INPUT_RECORD . Например, вот так: https://stackoverflow.com/questions/14510350/postmessage-not-working-with-console-window-whose-output-is-redirected-and-read
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990665
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1man
Даже не представляю куда копать.

Засунуть дос в virtualbox у них было какое-то sdk для таких вещей.
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990694
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
x1ca4064
Существенной проблемой я бы назвал

Существенной проблемой я бы назвал то, что консольные окна не работают с оконными сообщениями (WM_KEYUP/WM_KEYDOWN etc),


Проверяли?
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990702
1man
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x1ca4064, Благодарю за помощь!
Полагаю, это таки DOS-приложение, виндов тогда еще никаких не было. Язык – фортран.
Задержка между созданием процесса и получением его окна обеспечивается MessageBox.Show("Continue?"). Иначе, да, Вы правы – не работает, срабатывает условие
if (handle == IntPtr.Zero).
В том, что окно найдено правильно, я почти не сомневаюсь, т.к. handle = handleW = [тому, что пишет Spy++].
C wm_key – спасибо, буду разбираться. А нет ли примера под рукой?
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39990713
1man
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1man,
Пожалуй, следовало бы отметить, что при запуске из моей проги, досовская прога не выводит в своё окно никаких надписей (инструкций для интерактивного ввода числового материала). Но адекватно реагирует на нажатие кнопок реальной клавиатуры (запускает расчеты, записывает рез в файл), но всё вслепую, без отображения чего-либо в окне.
...
Рейтинг: 0 / 0
Эмуляция нажатия клавиши для досовской программы
    #39991119
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1man
А нет ли примера под рукой?


На C# нет, но их много на просторах сети.

PostMessage(handle,WM_KEYDOWN,keycode,param);
PostMessage(handle,WM_KEYUP,keycode,param or $C0000000);

Для использования SetKeyboardState нужно будет сделать AttachThreadInput, может быть проблема с установкой SHIFT/CTRL, нужно проверять.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Эмуляция нажатия клавиши для досовской программы
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]