QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 907|回复: 0

[C/C++/Qt] qt实现在电脑端群发微信

[复制链接]

等级头衔

积分成就    金币 : 2851
   泡泡 : 1516
   精华 : 6
   在线时间 : 1305 小时
   最后登录 : 2024-12-7

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老活跃会员

联系方式
发表于 2023-2-6 09:41:43 | 显示全部楼层 |阅读模式
需要用到的知识点:6 E4 l, T1 Z: A8 A- ~
1.主要还是靠windows自带的api实现
2 N: a, W: k: p2 M" Y) Q2.用到了系统回调函数遍历窗口$ Y/ N) ^) X/ t/ M3 [. ?+ \
3.用到了剪贴板. {# _# P2 Z: P6 Y& R2 v1 V, Y! X* U
4.用到了窗口前后台链接、激活窗口及恢复窗口
2 h3 z. K% _( H 1.jpg ' `* P, j8 W& E
核心代码如下:
  g! L- ]) S& @- q
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <Windows.h>
#pragma comment  (lib, "User32.lib")
char m_Name[MAXBYTE];
char m_Title[MAXBYTE];
QList<HWND> gHwndLst;
WORD m_nNum=0;
BOOL CALLBACK enumAllWindow(HWND Hwnd, LPARAM IParm)//系统返还给你的窗口句柄,API调用进来的参数
{
    //每次Hwnd返回回来,都需要获取他的类名和标题
    GetClassNameA(Hwnd,m_Name,MAXBYTE);//获得指定窗口所属的类的类名
    GetWindowTextA(Hwnd,m_Title,MAXBYTE);//查找标题
    QString strName = QString::fromLocal8Bit(m_Name);
    QString strTitle = QString::fromLocal8Bit(m_Title);    
    if(strName.contains("ChatWnd"))//找到所有微信窗口
    {
        //动态数组
//        HWNDArray = (HWND*)realloc((HWND)HWNDArray,(m_nNum+1)*sizeof(DWORD_PTR));//动态给指针分配内存空间
//        HWNDArray[m_nNum] = Hwnd;
        gHwndLst.append(Hwnd);
        m_nNum++;
        qDebug()<<"ID:"<<m_nNum<<"窗口句柄:"<<Hwnd<<"窗口类名:"<<strName<<"窗口标题:"<<strTitle;
    }
//    return false;//枚举一次就不枚举了
    return true;//枚举到完毕
}

HGLOBAL sysTarget = 0;//系统对象
HLOCAL sysWCHAR = 0;//系统对象WCHAR
void SetClipboard(CONST CHAR* pData,DWORD dLength)
{
    GlobalUnlock(sysTarget);//释放锁定的内存
    GlobalFree(sysTarget);//释放内存对象
    if(dLength==0)
        dLength = strlen(pData);
    if(OpenClipboard(NULL))//打开粘贴板后不能再使用
    {
        EmptyClipboard();//清空粘贴板
        sysTarget = GlobalAlloc(GMEM_MOVEABLE,dLength+1);//在全局分配空间
        if(sysTarget)
        {
            LPSTR mem = (LPSTR)GlobalLock(sysTarget);//锁定系统对象且返回第一个字节的指针
            memcpy(mem,pData,dLength+1);//复制内容到对象指针
            mem[dLength] = (TCHAR)0;//字符结束符,只有CHAR可以使用
            SetClipboardData(CF_TEXT,sysTarget);//内存中的护具放入剪贴板用于CHAR
        }
        else
        {
            qDebug()<<"系统分配对象错误"<<GetLastError()<<endl;
        }
        CloseClipboard();//关闭粘贴板之后才能使用粘贴板
    }
    else
    {
        qDebug()<<"打开粘贴板错误!"<<endl;
    }
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButtonSendMes_released()
{
    m_nNum =0;
    gHwndLst.clear();
    QByteArray ba = ui->textEdit->toPlainText().toLocal8Bit();
    SetClipboard(ba.data(),ba.size());
    EnumWindows(enumAllWindow,(LPARAM)"");
    for(int i =0;i<m_nNum;i++)
    {
        //前景锁定超时值
        DWORD dwTimeOut = -1;
        SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT,0,(LPVOID)&dwTimeOut,0);//他表示再系统禁止应用程序强行自己进入前台期间的时间量
        if(dwTimeOut>=100)
        {
            SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);//更新系统设置,并且写入用户配置文件
        }
        HWND HwndCur = GetForegroundWindow();//获取当前窗口的句柄
        SetWindowPos(HwndCur,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);//窗口置顶,但不改变大小和坐标
        DWORD dOnlyFlag = GetCurrentThreadId();//获取系统中当前线程唯一标识
        DWORD dMainThreadID = GetWindowThreadProcessId(HwndCur,NULL);//当前窗口主线程ID
        AttachThreadInput(dOnlyFlag,dMainThreadID,TRUE);//当前窗口和后台窗口连接起来,连接线程
        ShowWindow(gHwndLst[i],SW_SHOWNORMAL);//窗口可能被最小化,那么恢复
        SetForegroundWindow(gHwndLst[i]);//激活
        AttachThreadInput(dOnlyFlag,dMainThreadID,FALSE);//释放连接
//        SendMessage(gHwndLst[i],WM_PASTE,0,0);//发送消息到窗口
        keybd_event(VK_CONTROL,MapVirtualKeyA(VK_CONTROL,0),0,0);//按下ctrl键
        Sleep(50);
        keybd_event(86,MapVirtualKeyA(86,0),0,0);//按下v键
        Sleep(50);
        keybd_event(VK_CONTROL,MapVirtualKeyA(VK_CONTROL,0),KEYEVENTF_KEYUP,0);//抬起ctrl键
        Sleep(50);
        keybd_event(86,MapVirtualKeyA(86,0),KEYEVENTF_KEYUP,0);//抬起v键
        Sleep(50);
        keybd_event(VK_RETURN,MapVirtualKeyA(VK_RETURN,0),0,0);//按下enter键
        Sleep(50);
        keybd_event(VK_RETURN,MapVirtualKeyA(VK_RETURN,0),KEYEVENTF_KEYUP,0);//抬起enter键
        SetForegroundWindow(HwndCur);//恢复当前窗口
        SetWindowPos(HwndCur,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
    }
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号|渝公网安备50010502503914号 )

GMT+8, 2024-12-7 03:31

Powered by paopaomj X3.5 © 2016-2025 sitemap

快速回复 返回顶部 返回列表