要想 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窗口的更多相关文章

  1. Wpf窗口中打开WinForm窗口

    获取wpf窗口对应的句柄窗口 using System; using System.Windows; using System.Windows.Interop; using IWin32Window ...

  2. 窗口嵌入到另一个窗口(VC和QT都有)

    1.用vc新建一个dialog1工程.属性默认. 2.insert一个dialog2,改为child. 3.在dialog1中包含dialog2头文件,在一个按钮事件中显示dialog2: Cdial ...

  3. windows窗口分析,父窗口,子窗口,所有者窗口

    (本文尝试通过一些简单的实验,来分析Windows的窗口机制,并对微软的设计理由进行一定的猜测,需要读者具备C++.Windows编程及MFC经验,还得有一定动手能力.文中可能出现一些术语不统一的现象 ...

  4. Qt实现嵌入桌面的半透明窗口 good

    这儿用上了前面一文提到的函数findDesktopIconWnd().见: http://mypyg.blog.51cto.com/820446/263349 一.将Qt窗口嵌入到桌面中.声明一个最简 ...

  5. WPF中用于嵌入其他进程窗口的自定义控件(AppContainer)

    原文:WPF中用于嵌入其他进程窗口的自定义控件(AppContainer) 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199 ...

  6. [WPF]建立自适应窗口大小布局的WinForm窗口

    编写WinForm程序时,都会碰到一个问题.就是WinForm窗口在不同分辨率下的大小问题.举例说明,你编写的WinForm窗口在1024×768下是合适.匀称的.不过,如果用户的计算机的分辨率为14 ...

  7. qt如何实现一个渐隐窗口呢(开启的时候他是从上往下渐渐显示)

    qt如何实现一个渐隐窗口呢?就是比如说开启的时候他是从上往下渐渐显示的,关闭的时候从下往上渐渐小时的http://stackoverflow.com/questions/19087822/how-to ...

  8. QT笔记之实现阴影窗口

    方法一: 代码实现 在窗口构造函数中加入:setAttribute(Qt::WA_TranslucentBackground),保证不被绘制上的部分透明 重写void paintEvent(QPain ...

  9. Qt使用QStackedWidget实现堆栈窗口

    Qt使用QStackedWidget实现堆栈窗口 分类: QT2012-07-25 21:59 6997人阅读 评论(0) 收藏 举报 qtlistsignal 堆栈窗口可以根据选择项的不同显示不同的 ...

随机推荐

  1. 【转帖】影响超 10 亿设备,博通和 Cypress 芯片曝惊天漏洞,苹果、华为、三星等中招

    影响超 10 亿设备,博通和 Cypress 芯片曝惊天漏洞,苹果.华为.三星等中招   https://www.infoq.cn/article/lpNEQGrxZL22gHDPBE2z   26 ...

  2. Golang的循环结构-for语句

    Golang的循环结构-for语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.for循环语法 循环结构在生活中的场景也非常的多,比如: ()上班族们每天朝九晚五的生活; ( ...

  3. IOCTL_DISK_GET_DRIVE_GEOMETRY

    IOCTL_DISK_GET_DRIVE_GEOMETRY: 获取磁盘参数 c++实现: #include <Windows.h> #include <winioctl.h> ...

  4. oracle 开发注意事项

    新建表或字段时,不能使用char,统一使用varcha,防止判断null时有遗漏 新建表,索引,序列,新增删除或修改字段的时候,要先判断操作的对象是否存在,否则SLQ会报错 插入或者修改特殊字符,解决 ...

  5. 二十三、SAP中内表的修改

    一.通过MODIFY关键字来修改内表的内容,it相当于全部内容,wa相当于一条内容 二.效果如下

  6. 051-PHP求余运算

    <?php $x=10%5; //进行求余运算 $y=10%3; //进行求余运算 $z=10%6; //进行求余运算 echo $x; //输出变量x的值 echo $y; //输出变量y的值 ...

  7. POJ 3615 Cow Hurdles(最短路径flyod)

    Cow Hurdles Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9337   Accepted: 4058 Descr ...

  8. Spring的数据源配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. 阿里巴巴技术总监全解中台架构19页ppt

    //初创时,快速上线 单体架构至少撑了3年 //分布式,中间件基座 //平台化,内部是简单服务,对于业务侧就是快速上线 //平台化之后由于多平台协作问题,再次出现问题: 效率仍然不能匹配业务发展之需要 ...

  10. 高次同余方程 $BSGS$

    第一篇\(Blog\)... 还是决定把\(luogu\)上的那篇搬过来了. BSGS,又名北上广深 它可以用来求\(a^x \equiv b (mod \ n)\)这个同余方程的一个解,其中\(a, ...