0

我目前正在编写一个简单的程序来使用 Firefox 的内置更新服务(从菜单 -> 帮助 -> 关于访问)自动更新 Firefox。我正在使用 ShellExecute 打开 Firefox,并使用 sendInput 将击键“Alt + h”和“a”发送到打开的 Firefox 窗口。我的代码目前在打开更新菜单时工作,但我正在使用系统睡眠方法调用来给 Firefox 在调用 sendInput 之前打开足够的时间。有什么方法可以让我检查 Firefox 是否已打开并准备好接收键盘输入(例如,较慢的机器需要 10 秒,而我的机器需要 1 秒)?我不确定 sendInput 是否有任何可以提供此功能的关联方法,而且我还无法在 MSDN 上找到有关此主题的任何信息。谢谢,

#include <Windows.h>
#include <exception>

const int ERROR_VALUE_RANGE = 32;

using namespace std;

//Method Declarations
void openProgram(char filePath[]);
void openUpdateMenu();


/**
 * exception class for throwing ShellExecute Exceptions
 * throws char* "Error opening program" if any issues arise
 */
class runException: public exception {

    virtual const char* what() const throw() {
        return "Error opening program";
    }

} runEx;

int main (void) {



    // Path to Mozilla Firefox
    char filePath[] = "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"; 

    // Start Firefox using openProgram Method
    try {
        openProgram(filePath);
    }
    catch (exception& e) {
        //Insert code to open dialog box displaying error message;
    }

    Sleep(5000); //sleep for one second while we wait for Windows Update to open

    openUpdateMenu();

    return 0;
}


/**
 * method openProgram opens a file using the ShellExecute method
 * @param filePath - a char array of the complete filepath
 */
void openProgram(char filePath[])  { // throws (runEx)

    HINSTANCE exReturn = ShellExecute(
        HWND_DESKTOP, // Parent is desktop
        "open",       // Opens file (explorer double click behavior)
        filePath,     // Path to Windows Update program
        NULL,         // Parameters
        NULL,         // Default Directory
        SW_SHOW);     // Show the program once it opens

    //if there are any issues opening the file the return value will be less than 32
    if ((int)exReturn <=  ERROR_VALUE_RANGE) { 
        throw runEx; //throws runException
    }

    return;
}

/**
 * method openUpdateMenu sends key commands to Firefox to open the about menu with the         update service
 */
void openUpdateMenu() {

    //set up keyboard emulation
    INPUT Input; //declare input object
    Input.type = INPUT_KEYBOARD;
    Input.ki.time = 0; //let system provide timestamp
    Input.ki.dwExtraInfo = 0;

    //simulate pressing alt down
    Input.ki.wVk = VK_LMENU;
    Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
    SendInput(1, &Input, sizeof(INPUT));

    //simulate pressing 'h' down
    Input.ki.wVk = 0x48;
    Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
    SendInput(1, &Input, sizeof(INPUT));

    //release alt key
    Input.ki.wVk = VK_LMENU;
    Input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1, &Input, sizeof(INPUT));

    //release 'h' key
    Input.ki.wVk = 0x48;
    Input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1, &Input, sizeof(INPUT));

    Sleep(500); // wait for menu to open

    //simulate pressing 'a' down
    Input.ki.wVk = 0x41 ;
    Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
    SendInput(1, &Input, sizeof(INPUT));

    //release 'a' key
    Input.ki.wVk = 0x41 ;
    Input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1, &Input, sizeof(INPUT));

    //wait a second so user can see the program work
    Sleep(1000);
}
4

0 回答 0