将QT窗口嵌入到WinForm窗口
要想 windows下抓取Qt进程主界面,并嵌入到自己的程序中显示,需要首先设置qt窗口的windowTitle属性,然后就可以通过 windows api 中的 FindWindow 函数查找到窗口的hWnd了,最后通过SetParent将QT窗口装入即可。
抓取Qt界面窗口的时候,最好选用FindWindow的方式,因为通过进程查找主窗口的方式可能导致抓取到的窗口句柄不是主窗口(一个进程可能对应多个主窗口或者没有主窗口)
遇到抓取的Qt程序界面坐标响应异常,会导致菜单栏和工具栏无法正常鼠标事件,解决方案如下
1.考虑Qt界面有自己的坐标系机制,可以通过抓取QT程序界面开发接口所示方式解决坐标系不一致问题。
#include "doecwidget.h" #include <QApplication>
#include <QMouseEvent>
#include <QMessageBox> #include "mainwindow.h" class PosEventFilter : public QObject
{ public: PosEventFilter(QObject * parent = ); virtual ~PosEventFilter(); QWidget * m_curWindow; protected: bool eventFilter(QObject *obj, QEvent *event); }; PosEventFilter::PosEventFilter(QObject * parent)
: QObject(parent)
{
m_curWindow = NULL;
} PosEventFilter::~PosEventFilter()
{
} bool PosEventFilter::eventFilter(QObject *obj, QEvent *event)
{
QWidget * t_curWidget = qobject_cast<QWidget *>(obj);
///多重判断,以免导致winId函数引起事件无限循环
if ((event->type() == QEvent::MouseMove) && (NULL != t_curWidget) && (!t_curWidget->internalWinId()))
{
t_curWidget->winId();
} return QObject::eventFilter(obj, event); if ((event->type() == QEvent::MouseButtonRelease) && (m_curWindow == obj)) {
QMouseEvent * t_mouseEvent = static_cast<QMouseEvent *>(event);
QMessageBox::information(, "", QString("Mouse press %1,%2").arg(t_mouseEvent->pos().x()).arg(t_mouseEvent->pos().y()));
return true;
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}
} doecwidget::doecwidget()
{ } doecwidget::~doecwidget()
{ } void doecwidget::creatDockWidget(HWND _hwnd)
{
int t_argc = ;
char * t_argv = "";
QApplication t_app(t_argc, &t_argv);
PosEventFilter t_posEventFilter(&t_app);
t_app.installEventFilter(&t_posEventFilter); CMainWindow * t_mainWindow = new CMainWindow();
t_posEventFilter.m_curWindow = t_mainWindow;
t_mainWindow->show();
SetParent(t_mainWindow->winId(), _hwnd);
///ShowWindow(t_dockWidget->winId(), SW_SHOW);
t_app.exec();
} void doecwidget::creatDockWidget()
{
int t_argc = ;
char * t_argv = "";
QApplication t_app(t_argc, &t_argv);
PosEventFilter t_posEventFilter(&t_app);
t_app.installEventFilter(&t_posEventFilter); CMainWindow * t_mainWindow = new CMainWindow();
t_posEventFilter.m_curWindow = t_mainWindow;
t_mainWindow->show();
t_app.exec();
}
2.也可以在抓取程序端,通过SendMessage函数在位置移动或大小改变事件中发送消息的方式保证坐标系一致
HWND t_curHWND;
///t_curHWND = FindWindow(L"QWidget", L"编码分析");
t_curHWND = FindWindow(L"QWidget", L"CMainWindow");
LONG style = GetWindowLong(t_curHWND, GWL_STYLE);// 14CF 0000
// 1=WS_VISIBLE 4=WS_CLIPSIBLINGS C=WS_CAPTION F= 0000
style &=~WS_CAPTION;
//style &=~WS_CLIPSIBLINGS;
//style |=WS_CHILD;
SetWindowLong(t_curHWND,GWL_STYLE,style);
RECT t_rc;
GetClientRect(AfxGetMainWnd()->GetSafeHwnd(), &t_rc); MoveWindow(t_curHWND, , , t_rc.right - t_rc.left, t_rc.bottom - t_rc.top, TRUE);
SetParent(t_curHWND, AfxGetMainWnd()->GetSafeHwnd());
///SetWindowLong(t_curHWND, GWL_STYLE, WS_VISIBLE);
///SendMessage(t_curHWND, WM_SYSCOMMAND, SC_MAXIMIZE, 0); ShowWindow(t_curHWND, SW_MAXIMIZE); POINT t_point;
t_point.x = t_rc.left;
t_point.y = t_rc.top;
ClientToScreen(AfxGetMainWnd()->GetSafeHwnd(), &t_point); RECT t_curWinRc, t_curCliRc;
GetWindowRect(t_curHWND, &t_curWinRc);
GetClientRect(t_curHWND, &t_curCliRc);
ClientToScreen(t_curHWND, (LPPOINT)&t_curCliRc.left);
ClientToScreen(t_curHWND, (LPPOINT)&t_curCliRc.right);
///t_point.x = t_point.x + t_curCliRc.left - t_curWinRc.left;
///t_point.y = t_point.y + t_curCliRc.top - t_curWinRc.top;
SendMessage(t_curHWND, WM_MOVE, , MAKELPARAM(t_point.x, t_point.y));
///MAKELPARAM将xy转换为lParam
///MAKEPOINTS将lParam转换为POINTS
将QT窗口嵌入到WinForm窗口的更多相关文章
- Wpf窗口中打开WinForm窗口
获取wpf窗口对应的句柄窗口 using System; using System.Windows; using System.Windows.Interop; using IWin32Window ...
- 窗口嵌入到另一个窗口(VC和QT都有)
1.用vc新建一个dialog1工程.属性默认. 2.insert一个dialog2,改为child. 3.在dialog1中包含dialog2头文件,在一个按钮事件中显示dialog2: Cdial ...
- windows窗口分析,父窗口,子窗口,所有者窗口
(本文尝试通过一些简单的实验,来分析Windows的窗口机制,并对微软的设计理由进行一定的猜测,需要读者具备C++.Windows编程及MFC经验,还得有一定动手能力.文中可能出现一些术语不统一的现象 ...
- Qt实现嵌入桌面的半透明窗口 good
这儿用上了前面一文提到的函数findDesktopIconWnd().见: http://mypyg.blog.51cto.com/820446/263349 一.将Qt窗口嵌入到桌面中.声明一个最简 ...
- WPF中用于嵌入其他进程窗口的自定义控件(AppContainer)
原文:WPF中用于嵌入其他进程窗口的自定义控件(AppContainer) 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199 ...
- [WPF]建立自适应窗口大小布局的WinForm窗口
编写WinForm程序时,都会碰到一个问题.就是WinForm窗口在不同分辨率下的大小问题.举例说明,你编写的WinForm窗口在1024×768下是合适.匀称的.不过,如果用户的计算机的分辨率为14 ...
- qt如何实现一个渐隐窗口呢(开启的时候他是从上往下渐渐显示)
qt如何实现一个渐隐窗口呢?就是比如说开启的时候他是从上往下渐渐显示的,关闭的时候从下往上渐渐小时的http://stackoverflow.com/questions/19087822/how-to ...
- QT笔记之实现阴影窗口
方法一: 代码实现 在窗口构造函数中加入:setAttribute(Qt::WA_TranslucentBackground),保证不被绘制上的部分透明 重写void paintEvent(QPain ...
- Qt使用QStackedWidget实现堆栈窗口
Qt使用QStackedWidget实现堆栈窗口 分类: QT2012-07-25 21:59 6997人阅读 评论(0) 收藏 举报 qtlistsignal 堆栈窗口可以根据选择项的不同显示不同的 ...
随机推荐
- 对上一篇Logstash的补充
主要补充内容: 1.同步多表 2.配置的参数个别说明 3.elasticsearch的"_id"如果有相同的,那么会覆盖掉,相同"_id"的数据只会剩下最后一条 ...
- Java多线程之以7种方式让主线程等待子线程结束
记一次主线程等待子线程结束的多种方法的学习 在学习多线程时,最开始遇到的问题其实是"计算子线程运行时间",写到最后发现本文和标题更为符合,但是仍然基于问题:"在主线程中获 ...
- Golang函数-不定参函数
Golang函数-不定参函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- 使用Nginx搭建Tomcat9集群,Redis实现Session共享
使用Nginx搭建Tomcat9集群,Redis实现Session共享 1.tomcat准备 首先准备两个tomcat9 ,修改配置文件server.xml 如果在多个服务器上分别启动tomcat 则 ...
- 19 03 13 关于 scrapy 框架的 对环球网的整体爬取(存储于 mongodb 数据库里)
关于 spinder 在这个框架里面 和不用数据库 相同 # -*- coding: utf-8 -*- import scrapy from yang_guan.items import ...
- Linux学习43 CCNA网络知识-计算机网络基础
一.Linux网络配置属性 1.计算机网络 TCP/IP:协议簇,协议栈(使用的模型) ISO组织制定了OSI七层模型协议栈(学习的模型) 2.网卡 a.MAC:Media Access Contro ...
- Windows系统安装免费的开源虚拟机软件VirtualBox
https://www.qikegu.com/uncategorized/1179 VirtualBox是什么 VirtualBox是一个虚拟机平台软件,在VirtualBox平台上可以安装各种操作系 ...
- 2019山东ACM省赛L题题解(FLOYD传递闭包的变形)
本题地址 https://cn.vjudge.net/contest/302014#problem/L Median Time Limit: 1 Second Memory Limit: 6 ...
- java登录以及连接数据库的温习
学完一部分android相关知识点后,为了下周的java测试,我还是反回来重新的学习了上学期的知识点java,在今天打开eclipse之后,对于自己之前自己所写过的东西还有连接数据库的内容,已经有所忘 ...
- H5 - 本地数据存储 - localStorage.setItem