Qt实战之开发软件数据获取助手(eventFilter处理鼠标按下,event处理鼠标松开)

前段时间,受朋友委托,需要做一个能够获取别人软件文本框中内容的助手。当然这需要调用win api来解决问题。一开始,我想都没想,就用getWindowText()。。。。居然没用,好郁闷。于是查msdn。。发现关于返回值,是这样写的

Return Values

The length, in characters, of the copied string, not including the terminating null character, indicates success. Zero indicates that the window has no title bar or text, if the title bar is empty, or if the window or control handle is invalid. To get extended error information, call GetLastError.

This function cannot retrieve the text of an edit control in another application.

原来是不能跨线程获取数据。。。。。。好吧。。那没办法。接着用SendMessage发送WM_GETTEXT。。。测试记事本是完全没有问题的。。。但是对那个软件却不起作用。。。。。于是各种百度。。无果。。好吧。。暂时搁一搁。。后来,同学在用vb弄文本框时发现了EM_GETLINECOUNT和  EM_GETLINE  。至此,这个问题算是解决了。

啰嗦了那么多,进入主题吧。接下来,我们先实现这个助手。spy++这个大同小异。无非就是多了几个api的调用和线程处理问题。好了。先看下这个助手的最终效果图。。

按住那个放大镜后  鼠标的样式会自动改变  然后获取鼠标所在位置的窗口句柄。。选择模式 尝试获取数据。  如果有填写发送数据的目的地信息。。还可以直接发送数据。

好了。我们来重点说说以下几点 :

1) 获取窗口句柄      所用API函数为:  HWNDWindowFromPoint( POINTPoint);  只有获取句柄后我们才能调用SendMessage来获取信息

2)Qt修改鼠标样式  首先,要修改鼠标样式,我们就应该对存放图片的便签进行事件处理 鼠标按下,切换切换label背景图片。同时修改鼠标样式。。代码如下

[cpp] view plaincopy

  1. bool MainWindow::eventFilter(QObject *obj, QEvent *event)
  2. {
  3. if (event->type() == QEvent::MouseButtonPress) {
  4. if (obj == ui->lab_MouseStyle) {
  5. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
  6. if (mouseEvent->button() == Qt::LeftButton) {
  7. ui->lab_MouseStyle->setPixmap(QPixmap("://image/wait.png"));
  8. // 设置鼠标样式
  9. QCursor cursor ;
  10. QPixmap pixmap("://image/searchMouse.png") ;
  11. cursor = QCursor(pixmap,-1,-1);
  12. setCursor(cursor) ;
  13. // 修改标志
  14. m_IsMouseStyleChanged = true;
  15. // 开启计时器 300 毫秒刷新一次
  16. m_pTimer->start(300);
  17. return true;
  18. }
  19. }
  20. }
  21. return QWidget::eventFilter(obj, event);
  22. }

其中lab_MouseStyle就是软件截图中,存放放大镜的label。。。

同时,当用户松开鼠标时。我们需要还原鼠标样式,并且切换label背景.   这个时候,就要对整个程序进行事件拦截了。而不是对label处理事件了。具体代码如下

[cpp] view plaincopy

  1. bool MainWindow::event(QEvent *event)
  2. {
  3. if (event->type() == QEvent::MouseButtonRelease) {
  4. if (m_IsMouseStyleChanged == true) {
  5. // 当用户松开鼠标时, 恢复鼠标样式并且重新给鼠标样式标签设置图标
  6. setCursor(Qt::ArrowCursor);
  7. ui->lab_MouseStyle->setPixmap(QPixmap("://image/searchMouse.png").scaled(QSize(48,48), Qt::KeepAspectRatio));
  8. m_IsMouseStyleChanged = false;
  9. // 停止计时器
  10. m_pTimer->stop();
  11. return true;
  12. }
  13. }
  14. return QWidget::event(event);
  15. }

计时器的做用时通知绘图  绘制窗口的黑色边框。。具体的可以看源码部分。。(绘图部分参考于网络,并非原创。。太久不用gdi了。。有点生疏哈)

3) 通过句柄获取数据   这里只是谈谈消息的使用   同时有个新问题。怎么处理字符编码问题。。 代码如下(  部分 )

[cpp] view plaincopy

  1. // 模式一 : 通过直接发送WM_GETTEXT
  2. TCHAR lpRes[20000] = L"";
  3. int len = ::SendMessage(m_DesHwnd,  WM_GETTEXT  , (WPARAM)10000, (LPARAM)lpRes);
  4. char str[40240] = "";
  5. int iLength = <span style="color:#ff0000;">WideCharToMultiByte</span>(CP_ACP, 0, lpRes, -1, NULL, 0, NULL, NULL);
  6. <span style="color:#ff0000;">WideCharToMultiByte</span>(CP_ACP, 0, lpRes, -1,str , iLength, NULL, NULL);
  7. ui->textEdit_Handle->setText(QString::fromAscii(str));

利用WideCharToMultiByte函数再结合QString::fromAscii我们可以很轻松的转换编码。。。 那么问题来了? QString又该怎么便捷的转换为TCHAR呢??

[cpp] view plaincopy

  1. // 此函数实现通过句柄获取富文本数据
  2. QString MainWindow::getDataFromHwnd(HWND hWnd)
  3. {
  4. // 先获取总行数  然后读取数据
  5. int lineCount= ::SendMessage(hWnd, EM_GETLINECOUNT, 0, 0);
  6. if (lineCount >0) {
  7. TCHAR strRes[102400] = L""; // 使用宽字符
  8. int  count = 0; // 用来记录总共获取了多少字符
  9. for (int i = 0; i< lineCount;++i) {
  10. TCHAR szBuffer[200] = L"";
  11. ((WORD*) szBuffer)[0] = 200;
  12. int len = ::SendMessage(hWnd,  EM_GETLINE  ,(WPARAM)i, (LPARAM)szBuffer);
  13. ((WORD*) szBuffer)[len] = ‘\0‘;
  14. for  (int j= 0; j< len;++j)
  15. strRes[count++] = szBuffer[j];
  16. strRes[count++] = ‘\n‘;
  17. }
  18. // 将宽字符转换为ASCII码字符
  19. char str[30240] = "";
  20. int iLength = WideCharToMultiByte(CP_ACP, 0, strRes, -1, NULL, 0, NULL, NULL);
  21. WideCharToMultiByte(CP_ACP, 0, strRes, -1,str , iLength, NULL, NULL);
  22. return QString::fromAscii(str);
  23. }
  24. return QString("");
  25. }

这个主要是针对文本框的处理!思路很简单: 先获取文本框中的行数,然后循环获取每一行数据。。不过此代码中没有采用动态开辟数组。。这个如有需要,自行修改。

4)到此基本的就实现了。我们讲讲题外话。。怎么实现开机启动的功能。   代码如下

[cpp] view plaincopy

  1. //设置为开机启动
  2. static void AutoRunWithSystem(bool IsAutoRun) {
  3. QSettings *reg = new QSettings(
  4. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
  5. QSettings::NativeFormat);
  6. QString AppPath = QApplication::applicationFilePath();
  7. QString AppName = QApplication::applicationName();
  8. if (IsAutoRun) {
  9. reg->setValue(AppName, AppPath.replace("/","\\"));
  10. } else {
  11. reg->setValue(AppName, "");
  12. }
  13. }

此代码并非原创。参考与游龙大神的代码。有修改。源代码测试有问题。问题出在windows系统注册表的‘\’符号问题。。必须先修改相应的符号。。

好了。最后附上已打包的软件和源码。。。仅供学习与交流。,不用于商业用途。 有不足之处,欢迎指出。谢谢。

可执行文件下载地址: http://download.csdn.net/detail/wu5151/8939661

源码文件下载地址:   http://download.csdn.net/detail/wu5151/8939673

本博客地址: http://blog.csdn.net/wu5151

http://blog.csdn.net/wu5151/article/details/47101201

时间: 2024-10-15 18:31:49

Qt实战之开发软件数据获取助手(eventFilter处理鼠标按下,event处理鼠标松开)的相关文章

Qt实战之开发CSDN下载助手 (3)(结束篇)

再次申明下,开发这款助手,主要是用来学习交流,并不是用来开发什么刷积分的软件. 好了,言归正传,这次,主要的分析下CSDN的下载,评论,验证码获取机制等等. 好,回到第二篇,当我们成功登陆时,CSDN会给我们返还一段“Set-Cookie"的内容.而这些,就是我们行走在CSDN的通行证. 接下来我们看下下载协议: 好,以我们上一篇写的登陆源码的文件为例:   http://download.csdn.net/download/wu5151/8945881    我们点击电信下载....好吧.由于

Qt实战之开发CSDN下载助手 (1)

这次实战,我们须要开发一款CSDN下载助手.它具备下面功能: 1) . 可以正常登录CSDN账户 2) . 可以依据用户提供的资源下载页面地址解析出真实地址 ( 当然啦. 你的账号积分要足够下载所须要积分) 3) . 可以在完成下载后评价资源 ,然后获得返还积分. 4) . 相信你已经猜到了隐含的功能了. 当然.本文捧着学习的宗旨,重在学习和运用Qt的各种点滴.慢慢积累开发经验. 好了,说下开发完这款助手我们会学到什么? 1) .  掌握主要的http抓包协议分析 2) . 掌握Qt的http的

WPF学习开发客户端软件-任务助手(下)

时光如梭,距离第一次写的 WPF学习开发客户端软件-任务助手(已上传源码)  已有三个多月,期间我断断续续地对该项目做了优化.完善等等工作,现在重新向大家介绍一下,希望各位可以使用,本软件以实用性为主,采用MVVM模式(有小部分没有修改过来),小巧.使用方便. 具体功能与更新如下: 计划助手:本软件由[email protected]开发与维护,免费使用,如有好的意见或建议,可发送邮件到[email protected],谢谢使用!注(功能与特色):1.本软件使用方便.操作简便:2.本软件可设置

WPF学习开发客户端软件-任务助手

本人纯属WPF新手,布局和WPF的开发水平相当欠缺,从个人来说,还是比较喜欢WPF的,有人说WPF是界面加上WINFORM,我不这样认为,WPF与WINFORM主要的不同在于数据绑定. 这个软件虽然功能比较简单,没有做分层设计,也没有使用MVVM的开发模式,但也确实花了我不少的时间,算是这段时间学习WPF的结果吧,在此给大家展示一下,也给同行的新手门一个参考的例子(喜欢不会是误导). 软件具体功能如下: 1.本软件可以设置计划任务运行的周期:一次.每月.每天.每小时.间隔分钟等不种不同的运行模式

Qt for Android 开发大坑

Qt for Android 开发大坑 作者: qyvlik Qt 5.5.1 这里说一说比较常见的 Qt 开发安卓的大坑.希望同学们不要做无谓的挣扎,跳过这些坑. 输入框 首当其冲的是输入框,Qt 的输入在安卓上表现不佳. 无法支持安卓原生的输入法访问 Qt 的输入框,就是安卓输入法无法复制,粘贴,剪切 Qt 输入框中的文本. 无法支持使用触摸的方式选中 Qt 输入框中的文字. 如果输入框的位置处于应用底部,类似于 IM 那种聊天工具,应当注意. a. 如果应用 Activity 设置为 an

嵌入式开发板 迅为4412开发板 搭建Qt应用程序开发环境

集成开发软件qtcreator-3.2.2下载 官网下载 选择GPL/LGPL协议 选择离线下载 选择Linux Host 这里需要注意的是,如果只下载"Qt Creator",是不带运行环境的. 迅为电子网盘下载 "iTOP-4412开发板搭建编译环境所需要的工具包以及补丁包" "07-Qt_Creator" "QtE_IDE3.2.2" "qt-opensource-linux-x64-android-5.3.2

【Qt编程】基于Qt的词典开发系列&lt;七&gt;--调用网络API

前面文章中我们实现了本地的词库设计,可以完成本地的查词功能,那么这篇文章主要讲一讲如何通过调用网络的api来实现词典的网络查词功能. 词典API的选择 基本上市面上做词典软件的公司都有对应的api,比如说有道.金山等等,不过一般都需要api key,有点麻烦,于是乎,我就找了个简单好用的扇贝网API:http://www.shanbay.com/help/developer/api/ 奇怪的是,该api说要停用了,可以从我去年暑假完成该软件制作,到如今为止,还能正常使用. 扇贝词典api的使用

【Qt编程】基于Qt的词典开发系列&lt;二&gt;--本地词典的设计

我设计的词典不仅可以实现在线查单词,而且一个重大特色就是具有丰富的本地词典库:我默认加入了八个类型的词典,如下所示: 由于是本人是通信专业,因此加入了华为通信词典.电子工程词典,又由于我喜爱编程,也加入了c语言基本函数词典.下面介绍如何设计本地词典: 词典类型的选择 当然是txt格式的最好了,因为我们可以用程序直接进行读取.可是网上词典一般都是用mdx格式.ld2格式的,我无法用Qt来直接读取.最终,经过不断摸索,网上查找,发现我们可以将mdx格式的词典通过软件转化为txt格式的! mdx词典的

【Qt编程】基于Qt的词典开发系列--后序

从去年八月份到现在,总算完成了词典的编写以及相关技术文档的编辑工作.从整个过程来说,文档的编写比程序的实现耗费的时间更多.基于Qt的词典开发系列文章,大致包含了在编写词典软件过程中遇到的技术重点与难点.每篇文章都完成了一个小的功能,所给的代码都基本上是可以独立运行的.本系列文章对于想要自己动手完成词典软件的程序员来说具有很好的参考价值,对于想要编写其它软件的人来说也具有参考意义. 词典软件制作的初衷 在2013的年终总结中,我提过想要学习一门界面编程语言,后来就选中了Qt.于是在2014年上半年