要想 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. edge浏览器两个标签页localStorage不同步,解决办法

    今天遇到个奇怪的问题,edge两个标签页之间的localStorage值不同步,网上说ie和edge如果想让localStorage值同步,需要主动出发localStorage的change事件 wi ...

  2. require(): open_basedir restriction in effect. File(/www/wwwroot/xcx/zerg/thinkphp/start.php) is not within the allowed path(s): (/www/wwwroot/xcx/zerg/public/:/tmp/:/proc/) in /www/wwwroot/xcx/zerg/p

    解决方法: 在如下文件增加一项(如图所示) 在如下文件增加一项(如图所示): #php文件采用fastcgi解析并设置参数    location ~ \.php {        try_files ...

  3. 111-PHP类变量之间的赋值标识为同一个对象

    <?php class mao{ //定义猫类 public $age=0; //定义多个属性并初始化 public $weight=50; public $color='white'; } $ ...

  4. JNI操作二维数组

    之前的文章讲解了有关JNI使用方法,这篇文章进阶一点,介绍下JNI操作二维数组的方法.有了之前文章的操作JNI的方法,这里直接上代码了. Java代码部分 package com.testjni; p ...

  5. v2??? 替换协议

    输入 v2??? 命令,选择修改 v2??? 配置, 然后选择修改传输协议, 可以选择 mKcp_wechat-video .然后重新生成 vmess,放入客户端使用.

  6. metaspace 元空间

    为何移除持久代 它的大小是在启动时固定好的, 很难进行调优 -XX:MaxPermSize(默认64M) HotSpot 的内部类型也是Java对象: 它可能会在Full GC中被移动, 同时它对应用 ...

  7. Spark 广播变量 和 累加器

    1. 广播变量 理解图 使用示例 # word.txt hello scala hello python hello java hello go hello julia hello C++ hello ...

  8. Inception Score

    转载 https://www.jiqizhixin.com/articles/2019-01-10-18    全面解析Inception Score原理及其局限性 https://blog.csdn ...

  9. ROS2学习日志:QoS学习日志

    QoS学习日志 参考:ROS2API 及 https://index.ros.org/doc/ros2/Concepts/About-Quality-of-Service-Settings 1.概述 ...

  10. 电脑使用热键时是否需按住Fn键相关说明

    ThinkPad E系列机型 方法一: 在开机出现ThinkPad标志时,连续点F1(若无反应,请尝试Fn+F1)进入BIOS设置. 在BIOS中,依次选择Config---Keyboard/Mous ...