SendKeys не работает с предопределенным LPSTR.
Вопрос
у меня есть QTimer
подключен к TimerHandler
функция.А TimerHandler
должен сделать мой SendKeys
функцию, которую я объявил в общедоступном разделе моего заголовка.Если я вручную введу текст для SendKeys
функция, она дает правильный вывод.Но если я передам текст из заранее определенного LPSTR
он выводит мусор.Вот мой код:
МойПроект.h
#ifndef MYPROJECT_H
#define MYPROJECT_H
#include <QtGui/QMainWindow>
#include "ui_myproject.h"
#include <qtimer.h>
#include <qmessagebox.h>
#include <Windows.h>
class MyProject : public QMainWindow
{
Q_OBJECT
public:
MyClass(QWidget *parent = 0, Qt::WFlags flags = 0);
Ui::MyProjectClass ui;
QTimer* SpamTimer;
void SendText(char* message, int size)
{
int lc=0;
do{
keybd_event(VkKeyScan(message[lc]),0,KEYEVENTF_EXTENDEDKEY,0);
keybd_event(VkKeyScan(message[lc]),0,KEYEVENTF_KEYUP,0);
lc=lc+1;
}while(lc<size);
keybd_event(VK_RETURN,0,KEYEVENTF_EXTENDEDKEY,0);
keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
}
public slots:
void StartBTNClick();
void StopBTNClick();
void TimerHandler();
};
#endif // MYPROJECT_H
МойПроект.cpp
#include "MyProject.h"
LPSTR txtMessage; // Message for SendKeys function.
int buffer;
bool TimerEnabled = 0;
MyClass::MainWindow(QWidget *parent, Qt::WFlags flags) // Intializing MainWindow
: QMainWindow(parent, flags)
{
ui.setupUi(this);
statusBar()->showMessage("Status: Idle.");
connect(ui.StartBTN, SIGNAL(clicked()), this, SLOT(StartBTNClick()));
connect(ui.StopBTN, SIGNAL(clicked()), this, SLOT(StopBTNClick()));
}
void MyClass::StartBTNClick() // Starts the timer.
{
int delay; // delay for QTimer
bool ok;
std::string convertme;
QString TextMSG = ui.TextBox->text(); // Get text from 'line edit' for txtMessage.
QString TimeMSG = ui.TimeBox->text(); // Get text from 2nd 'line edit' for delay.
convertme = TextMSG.toStdString();
txtMessage = const_cast<char*> (convertme.c_str()); // converted QString to LPSTR.
buffer = strlen(txtMessage);
delay = TimeMSG.toInt(&ok, 10); // converted QString to int.
if (delay > 0)
{
QtTimer = new QTimer(this);
connect(QtTimer, SIGNAL(timeout()), this, SLOT(TimerHandler()));
TimerEnabled = 1;
QtTimer->start(delay);
statusBar()->showMessage("Status: Running.");
}
else if (delay < 0)
{
QMessageBox::warning(this, "Warning!", "Delay can't be \"0\" or lower than \"0\"!");
}
else
{
QMessageBox::warning(this, "Warning!", "Delay was not specified properly.");
}
}
void MyClass::StopBTNClick() // Stops the timer.
{
if (TimerEnabled == 1)
{
QtTimer->stop();
disconnect(QtTimer, SIGNAL(timeout()), this, SLOT(TimerHandler()));
TimerEnabled = 0;
statusBar()->showMessage("Status: Idle.");
}
}
void MyClass::TimerHandler() // Timer handles the SendKeys function
{
SendText(txtMessage, buffer);
}
Это заставляет мой таймер выводить мусор вместо текста внутри txtMessage
.Если я использую
SendText("test message", strlen("test message"));
вместо этого он выводит сообщение правильно.Что-то не так с моим кодом?
Я попробовал объявить LPSTR txtMessage
внутри моего класса в общедоступном разделе на MyProject.h
но это тоже не сработало.
Решение
Делать txtMessage
а string
объект (std::string
или QString
, поскольку вы используете Qt), а не указатель.Получите указатель от этого объекта прямо перед вызовом SendText
или, еще проще, просто сделайте SendText
возьмите строковый объект вместо указателя.
void SendText(const QString& str)
{
const char* message = str.c_str();
// whatever else you want to do
}
Проблема в том, что вы сохраняете указатель на данные во временном объекте (convertme
).Этот объект выходит за пределы области видимости и уничтожается, а память перезаписывается.Причина, по которой это работает с «тестовым сообщением», заключается в том, что строковые литералы хранятся по-другому.Вам нужно постоянно держать в памяти сообщение, которое вы пытаетесь сохранить.