QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 898|回复: 0

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

[复制链接]

等级头衔

积分成就    金币 : 2841
   泡泡 : 1516
   精华 : 6
   在线时间 : 1294 小时
   最后登录 : 2024-11-21

丰功伟绩

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

联系方式
发表于 2023-2-6 09:41:43 | 显示全部楼层 |阅读模式
需要用到的知识点:7 C9 N' \' b/ |! ?: t8 i
1.主要还是靠windows自带的api实现
& D! J( @9 R+ v/ f2.用到了系统回调函数遍历窗口  }* b( E3 f* G3 ~
3.用到了剪贴板
8 o$ X+ |  J2 W4.用到了窗口前后台链接、激活窗口及恢复窗口
  {4 V) L! F! Z  X% z 1.jpg
3 C" g& y7 c6 [, ~' S$ E& X核心代码如下:
! p3 W5 d3 B$ W5 H: |9 R+ _
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QDebug>
  4. #include <Windows.h>
  5. #pragma comment  (lib, "User32.lib")
  6. char m_Name[MAXBYTE];
  7. char m_Title[MAXBYTE];
  8. QList<HWND> gHwndLst;
  9. WORD m_nNum=0;
  10. BOOL CALLBACK enumAllWindow(HWND Hwnd, LPARAM IParm)//系统返还给你的窗口句柄,API调用进来的参数
  11. {
  12.     //每次Hwnd返回回来,都需要获取他的类名和标题
  13.     GetClassNameA(Hwnd,m_Name,MAXBYTE);//获得指定窗口所属的类的类名
  14.     GetWindowTextA(Hwnd,m_Title,MAXBYTE);//查找标题
  15.     QString strName = QString::fromLocal8Bit(m_Name);
  16.     QString strTitle = QString::fromLocal8Bit(m_Title);   
  17.     if(strName.contains("ChatWnd"))//找到所有微信窗口
  18.     {
  19.         //动态数组
  20. //        HWNDArray = (HWND*)realloc((HWND)HWNDArray,(m_nNum+1)*sizeof(DWORD_PTR));//动态给指针分配内存空间
  21. //        HWNDArray[m_nNum] = Hwnd;
  22.         gHwndLst.append(Hwnd);
  23.         m_nNum++;
  24.         qDebug()<<"ID:"<<m_nNum<<"窗口句柄:"<<Hwnd<<"窗口类名:"<<strName<<"窗口标题:"<<strTitle;
  25.     }
  26. //    return false;//枚举一次就不枚举了
  27.     return true;//枚举到完毕
  28. }
  29. HGLOBAL sysTarget = 0;//系统对象
  30. HLOCAL sysWCHAR = 0;//系统对象WCHAR
  31. void SetClipboard(CONST CHAR* pData,DWORD dLength)
  32. {
  33.     GlobalUnlock(sysTarget);//释放锁定的内存
  34.     GlobalFree(sysTarget);//释放内存对象
  35.     if(dLength==0)
  36.         dLength = strlen(pData);
  37.     if(OpenClipboard(NULL))//打开粘贴板后不能再使用
  38.     {
  39.         EmptyClipboard();//清空粘贴板
  40.         sysTarget = GlobalAlloc(GMEM_MOVEABLE,dLength+1);//在全局分配空间
  41.         if(sysTarget)
  42.         {
  43.             LPSTR mem = (LPSTR)GlobalLock(sysTarget);//锁定系统对象且返回第一个字节的指针
  44.             memcpy(mem,pData,dLength+1);//复制内容到对象指针
  45.             mem[dLength] = (TCHAR)0;//字符结束符,只有CHAR可以使用
  46.             SetClipboardData(CF_TEXT,sysTarget);//内存中的护具放入剪贴板用于CHAR
  47.         }
  48.         else
  49.         {
  50.             qDebug()<<"系统分配对象错误"<<GetLastError()<<endl;
  51.         }
  52.         CloseClipboard();//关闭粘贴板之后才能使用粘贴板
  53.     }
  54.     else
  55.     {
  56.         qDebug()<<"打开粘贴板错误!"<<endl;
  57.     }
  58. }
  59. MainWindow::MainWindow(QWidget *parent)
  60.     : QMainWindow(parent)
  61.     , ui(new Ui::MainWindow)
  62. {
  63.     ui->setupUi(this);
  64. }
  65. MainWindow::~MainWindow()
  66. {
  67.     delete ui;
  68. }
  69. void MainWindow::on_pushButtonSendMes_released()
  70. {
  71.     m_nNum =0;
  72.     gHwndLst.clear();
  73.     QByteArray ba = ui->textEdit->toPlainText().toLocal8Bit();
  74.     SetClipboard(ba.data(),ba.size());
  75.     EnumWindows(enumAllWindow,(LPARAM)"");
  76.     for(int i =0;i<m_nNum;i++)
  77.     {
  78.         //前景锁定超时值
  79.         DWORD dwTimeOut = -1;
  80.         SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT,0,(LPVOID)&dwTimeOut,0);//他表示再系统禁止应用程序强行自己进入前台期间的时间量
  81.         if(dwTimeOut>=100)
  82.         {
  83.             SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);//更新系统设置,并且写入用户配置文件
  84.         }
  85.         HWND HwndCur = GetForegroundWindow();//获取当前窗口的句柄
  86.         SetWindowPos(HwndCur,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);//窗口置顶,但不改变大小和坐标
  87.         DWORD dOnlyFlag = GetCurrentThreadId();//获取系统中当前线程唯一标识
  88.         DWORD dMainThreadID = GetWindowThreadProcessId(HwndCur,NULL);//当前窗口主线程ID
  89.         AttachThreadInput(dOnlyFlag,dMainThreadID,TRUE);//当前窗口和后台窗口连接起来,连接线程
  90.         ShowWindow(gHwndLst[i],SW_SHOWNORMAL);//窗口可能被最小化,那么恢复
  91.         SetForegroundWindow(gHwndLst[i]);//激活
  92.         AttachThreadInput(dOnlyFlag,dMainThreadID,FALSE);//释放连接
  93. //        SendMessage(gHwndLst[i],WM_PASTE,0,0);//发送消息到窗口
  94.         keybd_event(VK_CONTROL,MapVirtualKeyA(VK_CONTROL,0),0,0);//按下ctrl键
  95.         Sleep(50);
  96.         keybd_event(86,MapVirtualKeyA(86,0),0,0);//按下v键
  97.         Sleep(50);
  98.         keybd_event(VK_CONTROL,MapVirtualKeyA(VK_CONTROL,0),KEYEVENTF_KEYUP,0);//抬起ctrl键
  99.         Sleep(50);
  100.         keybd_event(86,MapVirtualKeyA(86,0),KEYEVENTF_KEYUP,0);//抬起v键
  101.         Sleep(50);
  102.         keybd_event(VK_RETURN,MapVirtualKeyA(VK_RETURN,0),0,0);//按下enter键
  103.         Sleep(50);
  104.         keybd_event(VK_RETURN,MapVirtualKeyA(VK_RETURN,0),KEYEVENTF_KEYUP,0);//抬起enter键
  105.         SetForegroundWindow(HwndCur);//恢复当前窗口
  106.         SetWindowPos(HwndCur,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
  107.     }
  108. }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-21 19:42

Powered by paopaomj X3.5 © 2016-2025 sitemap

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