我的程序有一个错误让我困扰了好几天。我的程序设置窗口挂钩以听取键盘按下和鼠标单击,每当按下一个键或单击鼠标时,相关变量将添加一个数字。当程序启动时,这些变量将启动到从数据库读取的某些值。基本上如果我在程序启动时按下键盘或鼠标就会出现错误,那么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访问。