Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将键盘输入发送到Windows98窗口模式下运行的dos应用程序_C++_Dos_Keyboard Input_Windows 98 - Fatal编程技术网

C++ 如何将键盘输入发送到Windows98窗口模式下运行的dos应用程序

C++ 如何将键盘输入发送到Windows98窗口模式下运行的dos应用程序,c++,dos,keyboard-input,windows-98,C++,Dos,Keyboard Input,Windows 98,我的问题是关于非常古老的技术。我有一项任务是在Windows 98中自动运行在Windows模式下的旧DOS软件(光谱仪)。我提出了两种不同的解决方案,但这两种解决方案在DOS应用程序中都不起作用: 第一种解决方案 使DOS应用程序处于活动状态 通过SendInput函数发送输入,如下所示: void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::sendKeysViaInput(const std::vector&keys,int

我的问题是关于非常古老的技术。我有一项任务是在Windows 98中自动运行在Windows模式下的旧DOS软件(光谱仪)。我提出了两种不同的解决方案,但这两种解决方案在DOS应用程序中都不起作用:

  • 第一种解决方案

    • 使DOS应用程序处于活动状态
    • 通过SendInput函数发送输入,如下所示:
  • void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::sendKeysViaInput(const std::vector&keys,int keyPause)
    {
    std::vector::const_迭代器it;
    输入键盘输入;
    keyBoardInput.type=输入\键盘;
    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;//按下键
    SendInput(1,&键盘输入,sizeof(输入));
    睡眠(按键暂停);
    keyBoardInput.ki.dwFlags=2;//向上键
    SendInput(1,&键盘输入,sizeof(输入));
    睡眠(按键暂停);
    }
    }
    
  • 通过i8042键盘控制器生成按键:使用D2命令写入键盘缓冲区命令,如下所示(keyboard_CMD_REG-0x64,keyboard_DATA_REG-0x60):
  • void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::SendKeyViaKeyboardController(const std::vector&scanCodes,int keyPause)
    {
    std::vector::const_迭代器it;
    for(it=scanCodes.begin();it!=scanCodes.end();it++)
    {
    //等待直到缓冲区为空
    int status=0;
    int结果=0;
    做
    {
    状态=_inp(0x64);
    
    //Windows 98中的MS-DOS应用程序运行在虚-实模式,而不是保护模式,这就是为什么无法使用保护模式驱动程序或系统调用与它们通信。您需要使用BIOS/DOS中断与键盘接口,Windows驱动程序将无法为您执行此操作

    因此,实现这一点的唯一方法是使用另一个DOS应用程序模拟按键,但我不确定BIOS键盘缓冲区是否虚拟化,但如果不是,那么您应该能够通过从应用程序启动虚拟实模式进程来实现(必须是一个单独的exe,但您应该能够在无窗口运行它)并将按键作为命令行参数传递给BIOS


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

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

    关于它是如何实现的:我已经创建了VXD驱动程序(它是我的专有驱动程序,我不能在这里发布它的代码,因为我计划在商业项目中使用它)。但此评论的主要目的是-是的,可以模拟Windows 98中运行的DOS应用程序在窗口模式下的键盘输入。。我可以发布的部分解决方案在github上:

    这里我使用的是vXd访问器类:()


    主要思想-使用W32_DEVICEIOCONTROL驱动程序消息处理程序和DEVICEIOCONTROL函数与驱动程序交互,并使用CTL(在我的驱动程序中定义)代码传递具有1字节对齐的结构:我没有使用CTL_代码宏。此Github项目几乎准备就绪~95%(目前,我只需手动选择要发送的窗口,方法是用鼠标点击激活窗口并检查是否有适当的内存可用)。

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


    我希望有人会觉得这很有用。

    您尝试的操作不会起作用,因为MS-DOS应用程序运行在与Windows运行的主虚拟机不同的虚拟机中。这两个虚拟机有两个不同的虚拟键盘控制器。除了编写VxD(32位驱动程序)之外我不确定是否有办法满足您的要求。也许有办法写信给MS-DOS Vx键盘驱动程序?罗斯,谢谢您的评论,我以前从未听说过VxD,我搜索了有关虚拟键盘驱动程序的内容,找到了有趣的链接:可能它可以帮我找到解决方案,这与您需要的解决方案类似。您已经找到了编写自己的来编写自己的VxD,就像您链接的“VSAMPLED”示例一样,但它不是键盘驱动程序。它将只使用Windows虚拟键盘驱动程序(VKD)公开的API,就像示例代码如何使用VKD_Force_键一样。
        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);
            }
        }
    
        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;
            }
        }