首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将键盘输入发送给Windows98中以窗口模式运行的dos应用程序

如何将键盘输入发送给Windows98中以窗口模式运行的dos应用程序
EN

Stack Overflow用户
提问于 2020-01-29 08:21:21
回答 3查看 817关注 0票数 3

我的问题是关于非常古老的技术。我有一个任务,自动化旧的DOS软件(光谱),是运行在Windows模式下Windows 98。我做了两种不同的解决方案,它们都不适用于DOS应用程序

  1. First解决方案

代码语言:javascript
复制
- Making DOS Application active
- Sending input via SendInput function, like this:

代码语言:javascript
复制
    void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::sendKeysViaInput(const std::vector<DWORD>& keys, int keyPause)
    {
        std::vector<DWORD>::const_iterator it;
        INPUT keyBoardInput;
        keyBoardInput.type = INPUT_KEYBOARD;
        keyBoardInput.ki.wScan = 0;
        keyBoardInput.ki.time = 0;
        keyBoardInput.ki.dwExtraInfo = 0;

        for(it = keys.begin(); it != keys.end(); it++)
        {
            keyBoardInput.ki.wVk = (*it);
            keyBoardInput.ki.dwFlags = 0;   // key down
            SendInput(1, &keyBoardInput, sizeof(INPUT));
            Sleep(keyPause);
            keyBoardInput.ki.dwFlags = 2;   // key up
            SendInput(1, &keyBoardInput, sizeof(INPUT));
            Sleep(keyPause);
        }
    }

  1. 通过i8042键盘控制器生成按键:使用D2命令写入键盘缓冲区命令,如(KEYBOARD_CMD_REG - 0x64,KEYBOARD_DATA_REG - 0x60):

代码语言:javascript
复制
    void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::sendKeysViaKeyboardController(const std::vector<BYTE>& scanCodes, int keyPause)
    {
        std::vector<BYTE>::const_iterator it;
        for(it = scanCodes.begin(); it != scanCodes.end(); it++)
        {
            // wait untill buffer is empty
            int status = 0;
            int result = 0;
            do
            {
                status = _inp(0x64);
                // std::cout <<"Keyboard status: "<< status << std::endl;
                Sleep(10);
            }
            while (status & 1);

            // send scan code for key down
            _outp(KEYBOARD_CMD_REG, 0xD2);
            _outp(KEYBOARD_DATA_REG, (*it));
            result = _inp(KEYBOARD_DATA_REG);
            std::cout <<"Keyboard command result for KEY DOWN: "<< result << std::endl;
            // send scan code for key up
            BYTE keyUpCode = (*it) | 128;
            Sleep(keyPause);
            _outp(KEYBOARD_CMD_REG, 0xD2);
            _outp(KEYBOARD_DATA_REG, keyUpCode);
            result = _inp(KEYBOARD_DATA_REG);
            std::cout <<"Keyboard command result for KEY UP: "<< result << std::endl;
        }
    }

我用标准记事本窗口( window,notepad.exe)测试了这两种解决方案,这两种解决方案都很好地使用了,但我无法让它在DOS应用程序中工作。

生成键盘输入(和整个项目)的代码:https://github.com/MossbauerLab/Sm2201Autosave/blob/master/MossbauerLab.Sm2201.ExtSaveUtility/src/saveManager/autoSaveManager.cpp

你能帮我解决这个问题吗。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-03-02 09:04:27

首先,我要感谢所有感兴趣这篇文章的人,你们都给了我一些有用的信息,我终于做出了我想要的。

关于它是如何实现的:我已经创建了VXD驱动程序(它是我的专有驱动程序,我不能在这里发布代码,因为我计划将它用于商业项目)。但本评论的主要目的是是的,它可以模拟键盘输入在Windows 98下运行的窗口模式的应用程序。我可以在github:https://github.com/MossbauerLab/Sm2201Autosave/blob/master/MossbauerLab.Sm2201.ExtSaveUtility/src/saveManager/autoSaveManager.cpp上发布的部分解决方案

这里我使用的是vXd访问器类:(https://github.com/MossbauerLab/Sm2201Autosave/blob/master/MossbauerLab.Sm2201.ExtSaveUtility/src/utils/windows/vxdAccessor.cpp)

主要思想-使用W32_DEVICEIOCONTROL驱动程序、消息处理程序和DeviceIoControl函数与驱动程序交互,并使用CTL (在驱动程序中定义)代码传递具有1字节对齐的结构:我没有使用CTL_CODE宏。这个Github项目几乎已经准备好了~95% (目前我只需要手动选择窗口发送,通过鼠标点击激活它,并检查适当的内存空闲)。

票数 1
EN

Stack Overflow用户

发布于 2021-02-11 16:42:33

16年前,我也遇到了同样的问题,我的解决方案(不太优雅,但可能更容易实现)是将我想要插入的文本放入剪贴板,获取前台窗口hWnd,然后使用SendMessage()将0xE 001作为数据的WM_SYSCOMMAND发送给它。IIRC从窗口的上下文菜单(我通过使用Spy++找到)触发了粘贴命令。

我希望有人发现这有用。:)

票数 0
EN

Stack Overflow用户

发布于 2020-02-10 15:58:45

Windows 98中的Mode应用程序在虚拟真实模式下运行,而不是在保护模式下运行,这就是为什么无法使用保护模式驱动程序或系统调用与它们进行通信的原因。您需要使用BIOS / DOS中断与键盘接口,Windows驱动程序将无法为您做到这一点。

因此,唯一的方法是使用另一个DOS应用程序模拟按键,但我不确定BIOS键盘缓冲区是否被虚拟化,但如果没有,那么您应该能够通过从应用程序中启动一个virtualised进程(必须是一个单独的exe,但您应该能够通过不带窗口地运行它)并将按键作为命令行参数传递到BIOS。

这是一个非常有趣的问题,希望这能帮你解决这个问题。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59963008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档