Слияние кода завершено, страница обновится автоматически
#include "widget.h"
#include "ui_widget.h"
#include "encode.cpp"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 实例化托盘图标
tray = new QSystemTrayIcon(this);
tray->setToolTip("OprtCtrl-受控端");
tray->setIcon(QIcon(":/res/tray.png"));
connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(show()));
QString conn = getIP();
if(conn.isEmpty()) {
QMessageBox box;
box.setText(tr("请插入网络设备!"));
box.exec();
exit(-1);
}
// 创建UDP对象
udpSocket=new QUdpSocket(this);
localAddr = new QHostAddress(conn);
for(udpLocalPort = 6666; udpLocalPort < 6688; udpLocalPort++)
{
if(udpSocket->bind(*localAddr,udpLocalPort)) {
break;
}
}
if(udpLocalPort >= 6688)
{
QMessageBox box;
box.setText(tr("网络监听失败!"));
box.exec();
exit(-1);
}
else
{
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));
if(encode((conn + "," + QString::number(udpLocalPort)).toStdString().c_str()))
{
showQR();
}
else
{
QMessageBox box;
box.setText(tr("网络连接失败!"));
box.exec();
exit(-1);
}
}
}
void Widget::showQR()
{
QImage *qr = new QImage("test.bmp");
ui->label->setPixmap(QPixmap::fromImage(*qr, Qt::AutoColor));
}
void Widget::receive()
{
while(udpSocket->hasPendingDatagrams()){ //是否读到数据
QByteArray data;
// udpSocket->pendingDatagramSize 获取报文长度
// data.resize 给 data 数组设置长度
data.resize(udpSocket->pendingDatagramSize());
// 读入数据
udpSocket->readDatagram(data.data(),data.size());
// 显示数据内容
QString str=data.data();
int a[] = {-1};
if(str.at(0) == '0') //鼠标位移指令
{
bool ok = true;
int xAcc = str.mid(2).split(",").at(0).toInt(&ok,10);
int yAcc = str.mid(2).split(",").at(1).toInt(&ok,10);
if(ok)
{
QCursor *cur = new QCursor;
moveCursor(cur, xAcc, -yAcc);
}
}
else if(str.at(0) == '1')
{
// 具体操作含义,请参考mouseCtrl函数
mouseCtrl(str.at(2).unicode() - '0');
}
else if(str.at(0) == '2') //幻灯片操作指令 如 2,F
{
switch (str.at(2).unicode())
{
case 'F': // 幻灯片开始播放
a[0] = VK_F5;
sendKey(a, 1);
break;
case 'P': // 上一张幻灯片
a[0] = VK_UP;
sendKey(a, 1);
break;
case 'N': // 下一张幻灯片
a[0] = VK_DOWN;
sendKey(a, 1);
break;
case 'W': // 进入/退出白屏
a[0] = 0x57;
sendKey(a, 1);
break;
case 'B': // 进入/退出黑屏
a[0] = 0x42;
sendKey(a, 1);
break;
case 'Q': // 退出演示
a[0] = VK_ESCAPE;
sendKey(a, 1);
break;
case 'H': // 切到第一张
a[0] = VK_HOME;
sendKey(a, 1);
break;
case 'E': // 切到最后一张
a[0] = VK_END;
sendKey(a, 1);
break;
}
}
else if(str.at(0) == '3') //其他指令 如 3,B
{
switch (str.at(2).unicode())
{
case 'B': // 受控开始,自动隐藏窗体到托盘
tray->show();
hide();
break;
case 'S': // 打开网页浏览器……可以进一步自行扩展
a[0] = 0xAC;
sendKey(a, 1);
break;
}
}
}
}
/*
* 控制光标在单位时间内移动
* cur: 光标实例
* xAcc: 水平方向加速度
* yAcc: 垂直方向加速度
*/
void Widget::moveCursor(QCursor *cur, int xAcc, int yAcc)
{
int x,y;
x = cur->pos().x() - xAcc;
y = cur->pos().y() - yAcc;
if(x > W)
x = W;
if(y > H)
y = H;
cur->setPos(x,y);
}
/*
* 利用 Windows API 向系统送模拟按键
* keys: 有序的组合键数组
* n: 数组长度
* 键码对应关系: msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx
*/
void Widget::sendKey(int keys[], int n)
{
int i;
INPUT *ip = new INPUT[n];
for(i = 0; i < n; ++i)
{
ip[i].type = INPUT_KEYBOARD;
ip[i].ki.wScan = 0;
ip[i].ki.time = 0;
ip[i].ki.dwExtraInfo = 0;
ip[i].ki.dwFlags = 0; // 按下
ip[i].ki.wVk = keys[i];
SendInput(1, &ip[i], sizeof(INPUT));
}
for(i = n-1; i >= 0; --i)
{
ip[i].ki.dwFlags = KEYEVENTF_KEYUP; // 释放
SendInput(1, &ip[i], sizeof(INPUT));
}
delete [] ip;
}
/*
* 利用 Windows API 向系统送鼠标操作
* type: 操作类型
* 键码对应关系: msdn.microsoft.com/en-us/library/windows/desktop/ms646273(v=vs.85).aspx
*/
void Widget::mouseCtrl(int type)
{
INPUT ip;
ip.type = INPUT_MOUSE;
if(type == 6 || type == 9) //向下(上)滚动6(9)
{
ip.mi.dwFlags = MOUSEEVENTF_WHEEL;
ip.mi.mouseData = (type==6) ? WHEEL_DELTA : -WHEEL_DELTA;
SendInput(1, &ip, sizeof(INPUT));
return;
}
else
{
switch (type)
{
case 2: // 右键单击
ip.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
SendInput(1, &ip, sizeof(INPUT));
ip.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
SendInput(1, &ip, sizeof(INPUT));
break;
case 3: // 中键单击
ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
SendInput(1, &ip, sizeof(INPUT));
ip.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
SendInput(1, &ip, sizeof(INPUT));
break;
case 1: // 左键按下
ip.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &ip, sizeof(INPUT));
break;
case 0: // 左键释放
ip.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &ip, sizeof(INPUT));
break;
default: // 左键单击8
ip.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &ip, sizeof(INPUT));
ip.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &ip, sizeof(INPUT));
break;
}
}
}
QString Widget::getIP()
{
QList<QHostAddress> list = QNetworkInterface::allAddresses();
foreach(QHostAddress address, list)
{
// 遍历IP地址并编码WiFi热点信息为二维码
if(address.protocol() == QAbstractSocket::IPv4Protocol && address.toString().contains("172.27.35"))
{
return address.toString();
}
}
return "";
}
Widget::~Widget()
{
delete ui;
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )