当程序在qt中读取数据库时,Windows挂钩停止工作?

时间:2018-05-19 08:14:38

标签: c++ windows qt access setwindowshookex

我的程序有一个错误让我困扰了好几天。我的程序设置窗口挂钩以听取键盘按下和鼠标单击,每当按下一个键或单击鼠标时,相关变量将添加一个数字。当程序启动时,这些变量将启动到从数据库读取的某些值。基本上如果我在程序启动时按下键盘或鼠标就会出现错误,那么Windows挂钩就会停止工作。我尽力解决这个问题,我尽可能小地编写了许多最小的例子,但是bug仍然存在。我将在最简单的例子中展示我的代码的样子:

widget.cpp:中 我把钩子设置为:

HHOOK hHook = NULL;

LRESULT CALLBACK MyLowLevelKeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (wParam == WM_KEYUP) {
        Emitter::Instance()->keyPressed(); //emit this signal whenever a key is being pressed
        qDebug() << "Key Pressed"; //when hook stopped working, the debug message will not even show
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

并在widget的构造函数中:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);  //set hook here

    pressedTimes = database.returnTotalPressedTimes(); //get data from database and initiate pressedTimes
    ui->label->setText(QString::number(pressedTimes));

    connect(Emitter::Instance(), &SignalEmitter::keyPressed, [this](){ pressedTimes++; ui->label->setText(QString::number(pressedTimes)); }); //when key presses, ++pressedTimes;
}

Database class就像:

Database::Database()
{
    QString dbName = QString("Driver={Microsoft Access Driver (*.mdb)}; FIL={MS Access}; DBQ= C:/path/to/TestingDB.mdb");
    database = QSqlDatabase::addDatabase("QODBC");
    database.setDatabaseName(dbName);
}

//this function is used to initiate the pressedTimes variable when the program starts
int Database::returnTotalPressedTimes()
{
    int totalPressedTimes = 0;

    if(database.open()) {
        QSqlQuery sqlQuery;
        sqlQuery.exec("SELECT SUM(PressedTimes) FROM TestingTable"); //I trid my best to the testing database as simple as possible
        while(sqlQuery.next()) {
            totalPressedTimes = sqlQuery.value(0).toInt();
        }
        database.close();
    }
    else {
        qDebug() << database.lastError().text();
    }

    return totalPressedTimes;
}

所以你可以看到,基本上我展示了最小例子的所有代码。因此,当程序启动时,它会从数据库中读取数据并将数据发送到pressedTimes,而pressedTimes每次按下一个键时都会添加一个数字。

但是这个错误只是在你启动你的程序的那一刻发生的,同时你一直按下键盘。然后钩子停止工作。不知道那里到底发生了什么,以及如何解决这个奇怪的错误。希望我能清楚地解释我的问题,希望有人能帮助我解决这个问题。
感谢。

修改:
顺便说一句,我忘了说,据我测试它,如果我只是将pessedTimes发送到0或只是其他一些值而不是从读取数据库中获取值。这个bug不会发生。那么这是否意味着Windows钩子和读取数据库之间存在一些冲突?
我正在使用Windows 10,数据库是Windows访问。

0 个答案:

没有答案