-
2019-03-07 21:55:54
不务正业的c++程序员(QT窗口嵌套)
Qt窗口嵌套
为实现一体化平台集成现有项目特研究实现了Qt窗口嵌套,这里特说明一下qt的一些小东西以便以后自己查看方便做些小的记录
Qt相同程序的嵌套我就不细说了
同程序嵌套窗口只需要设置父类就ok了。(根据不同地方不同写法)
(1)setparent()
(2)new 的时候设置父类就可以了
详细的说下Qt不同程序和不同版本程序的嵌套
一、首先说一下Qt5以上版本的窗口嵌套WId id = static_cast<WId>(myid);//myid为通信传进来的Wid QWindow *myQWindow = QWindow::fromWinId(id);//Qt5以上版本 Qwidget *mywidget = QWidget::find(id);//Qt4版本但是不知为什么返回的窗口为空 QWidget *m = QWidget::createWindowContainer(myQWindow,nullptr);//参数意义请见文档
得到窗口句柄
MainWindow w; w.winId();
另外之间通信需要进程间通信
还有一种是拿到当前程序句柄设置他的父亲,但是时隔太久了忘了咋写了,目前代码在公司电脑里带不出来,所以只写点片段。希望对后来者有些帮助。更多相关内容 -
多进程窗口嵌套
2014-01-21 11:19:30一个可以跨进程嵌套窗口的demo,主调进程嵌套子进程中的窗口 -
VC实现A进程窗口嵌入到B进程窗口中显示的方法
2020-12-26 08:30:04本文通过一个Demo示例讲述把A应用程序嵌入到B应用程序中显示的方法。 主要代码如下: //在B应用启动时创建A进程 CreateProcess(_T("A.exe"),NULL,NULL,NULL,FALSE,CREATE_NEW_...//移动A进程窗口位置 MoveWindow -
Qt 实现进程间窗口嵌套(一)
2017-10-09 20:18:52环境:Qt 5.9.1_msvc2015_64bit,Window 10. ...方法:获取外部程序的窗口句柄,调用 [static] QWindow *QWindow::fromWinId(WId id) 函数创建QWindow,然后调用 [static] QWidget *QWidget::createWi环境:Qt 5.9.1_msvc2015_64bit,Window 10.
为了实现在qt程序中打开Window上其他应用程序,并将其嵌入到qt程序中。
方法:获取外部程序的窗口句柄,调用
[static]QWindow *QWindow::fromWinId(WIdid)
函数创建QWindow,然后调用
[static]QWidget *QWidget::createWindowContainer(QWindow *window,QWidget *parent = Q_NULLPTR,Qt::WindowFlagsflags = Qt::WindowFlags())
创建一个QWidget即可。
关键之处在于如何获取窗口句柄。
我们都知道Windows编程中,可以通过FindWindow系列的函数获取HWND类型的窗口句柄(需要include windows.h头文件),HWND类型和Qt中的WId类型可以转换,所以通过FindWindow我们可以找到想要嵌入的窗口,不论是子窗口还是主窗口,即使是整个桌面也未尝不可。
下面贴一下效果图:
原程序:
这是嵌入之后的Qt程序:
可以看到,在这里标题栏和边框都消失了。很有意思的方法,好奇Qt是如何做到这种进程间的嵌套,这篇只是简单介绍,待我研究透彻再来给大家分享。
如果不需要嵌套窗口的话,Qt也提供了其他的方法,不需要如此复杂。像QDesktopServices类,可以打开本地应用程序(打开文件或网页时,自动选择默认的应用程序)。
一开始的目的,是想将office窗口显示到qt程序里面,采用的是activexQt模块,但activex的开发需要一定时间的积累,微软的东西比较难用,加上activex只能打开微软自家的东西(有待验证),而且如果以后不仅仅是显示office呢?所以干脆直接嵌套进程窗口,一劳永逸。
参考链接:http://blog.csdn.net/dazhong159/article/details/7903382 -如何获取window窗口句柄
-
c++窗口嵌入第三方进程窗口
2020-06-15 18:57:34现在的大型软件启动之后,很可能存在多个进程。如浏览器,每打开一个新的页面,就会启动一个新的进程。...1. 打开第三方进程窗口 主要通过CreateProcess函数来打开第三方进程,并获取进程ID。 HWND CNestWndDlg::Open现在的大型软件启动之后,很可能存在多个进程。如浏览器,每打开一个新的页面,就会启动一个新的进程。为什么会使用多进程,而不是全部使用多线程呢?因为多进程,可以做到完全的隔离,这样的好处是:如果一个页面卡死了,不会干扰到其他页面;在代码层,也少了多页面之间线程变量安全考虑的顾忌了,不用考虑同步异步等操作。
我们在MainUI中嵌入ThirdUI窗口,主要有以下步骤:1. 打开第三方进程窗口
主要通过CreateProcess函数来打开第三方进程,并获取进程ID。
HWND CNestWndDlg::OpenProcess() { // 进程启动信息 STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOW; // 进程信息 PROCESS_INFORMATION pi = {0}; // 创建进程 if (CreateProcess("C:\\WINDOWS\\system32\\notepad.exe", NULL, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) { PROCESS_INFO procwin; procwin.dwProcessId = pi.dwProcessId; procwin.hWnd = NULL; // 等待新进程初始化完毕 WaitForInputIdle(pi.hProcess, 5000); EnumWindows(EnumWindowCallBack, (LPARAM)&procwin); if (NULL == procwin.hWnd) { Sleep(200); EnumWindows(EnumWindowCallBack, (LPARAM)&procwin); } return procwin.hWnd; } return NULL; }
2. 通过进程ID找到对应窗口句柄
主要通过EnumWindows来枚举所有窗口,并通过GetWindowThreadProcessId来获取窗口的进程ID,并与1中打开的进程ID作比较来获取对应窗口的句柄。
// 查找进程主窗口的回调函数 BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam) { PROCESS_INFO *pProcessWindow = (PROCESS_INFO *)lParam; DWORD dwProcessId; GetWindowThreadProcessId(hWnd, &dwProcessId); if (pProcessWindow->dwProcessId == dwProcessId && IsWindowEnabled(hWnd) && GetParent(hWnd) == NULL) { pProcessWindow->hWnd = hWnd; return FALSE; } return TRUE; }
3. 设置第三方窗口相关属性
为了让thirdUI内嵌入MainUI中,需要以下设置:
- 修改thirdUI的属性,通过SetWindowLong清除WS_POPUP风格。
- 修改thirdUI的属性,通过SetWindowLong添加WS_CHILD风格。
- 通过SetParent来将MainUI设置为thirdUI的父窗口,设置完之后,thirdUI的消息循环就进入到了MainUI的消息队列,这样thirdUI就和MainUI的一个子窗口类似。
- 通过GetClientRect来获取MainUI的客户区大小,通过MoveWindow将thirdUI移到MainUI的客户区。
- 调用InvalidateRect将thirdUI设置为整个区域无效区域。
- UpdateWindow强制刷新thirdUI,因为InvalidateRect只是将消息放入消息队列并不定立即响应,所以可能导致thirdUI更新不正常,此时需要UpdateWindow来强制刷新无效区域。
4. 切换窗口之后的更新设置
当窗口最小化或者切换到主进程的其他页面后,再切换回来,此时也需要刷新设置。否则会更新错误。重点,必须再次设置SetParent,否则无法正确传递消息。(具体原因未知)
- 通过SetParent来将MainUI设置为thirdUI的父窗口,设置完之后,thirdUI的消息循环就进入到了MainUI的消息队列,这样thirdUI就和MainUI的一个子窗口类似。
- 调用InvalidateRect将thirdUI设置为整个区域无效区域。
- UpdateWindow强制刷新thirdUI,因为InvalidateRect只是将消息放入消息队列并不定立即响应,所以可能导致thirdUI更新不正常,此时需要UpdateWindow来强制刷新无效区域。
5. 示例
示例是一个多tab窗口,调用记事本(notepad),显示如下:
Demo -
Qt-窗口嵌套exe
2019-02-22 14:51:35某些特殊场景,我们要在主程序中嵌套第三方程序。这样臃肿的设计好比,在乡村小楼里面建设一个商业... winApi通过进程ID获取窗口句柄 QWindow::fromWinId(WId id)创建window window代理的widget,即我们常见的Q...某些特殊场景,我们要在主程序中嵌套第三方程序。这样臃肿的设计好比,在乡村小楼里面建设一个商业广场,本人不是很喜欢。Qt的QProcess和QWindow可以为我们完成这样的任务,核心思路即
- QProcess启动第三方exe,获取进程ID
- winApi通过进程ID获取窗口句柄
- QWindow::fromWinId(WId id)创建window
- window代理的widget,即我们常见的QWidget
最好的是,第三方exe也是Qt开发的app。下面就是这样的情况
第三方exe
int main(int argc, char *argv[]) { QApplication a(argc, argv); // OtherWidget inherit from QWidget OtherWidget w; w.setWindowFlags(w.windowFlags() | Qt::FramelessWindowHint); w.show(); return a.exec(); }
如上,OtherWidget继承于QWidget ,如果继承QMainWindow,在嵌入后更改主窗口size时出现丢失。
嵌套
// 枚举窗口参数 typedef struct { HWND hwndWindow; // 窗口句柄 DWORD dwProcessID; // 进程ID }EnumWindowsArg; // 枚举窗口回调函数 BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { EnumWindowsArg *pArg = (EnumWindowsArg *)lParam; DWORD dwProcessID = 0; // 通过窗口句柄取得进程ID ::GetWindowThreadProcessId(hwnd, &dwProcessID); if (dwProcessID == pArg->dwProcessID) { pArg->hwndWindow = hwnd; // 找到了 return FALSE; } // 没找到 return TRUE; } // 通过进程ID获取窗口句柄 HWND GetWindowHwndByPID(DWORD dwProcessID) { HWND hwndRet = NULL; EnumWindowsArg ewa; ewa.dwProcessID = dwProcessID; ewa.hwndWindow = NULL; EnumWindows(EnumWindowsProc, (LPARAM)&ewa); if (ewa.hwndWindow) { hwndRet = ewa.hwndWindow; } return hwndRet; }
QString cusExePath = "D:/VSpro/mainpro/x64/Debug/mainpro.exe"; QString otherPath = "D:/QtProject/build-ModelDemo-Desktop_Qt_5_10_0_MSVC2015_64bit-Debug/debug/ModelDemo.exe"; QStringList exePathList; exePathList << cusExePath << otherPath; for(int i = 0; i < exePathList.length(); i++){ QProcess *process = new QProcess; QString path = exePathList.at(i); // 启动 第三方 exe, exepath 含有空格时,再次填充path即可 if(path.contains(" ")){ process->start(path, QStringList() << path); } else{ process->start(path); } m_listProcess << process; qint64 proID = process->processId(); HWND wid = NULL; do{ wid = GetWindowHwndByPID(proID); if(wid){ break; } }while(1); // window QWindow *window; window = QWindow::fromWinId((WId)wid); // proxyWidget QWidget *widget; widget = QWidget::createWindowContainer(window,this); ui->tabWidget->addTab(widget,QString::number(ui->tabWidget->count())); }
如上,我们开启了2个Qt APP exe,对于exePath含有空格的进行处理,结合winApi实现窗口句柄的获取,剩下的就很好办了。
退出
开启的第三方程序与主程序的依附问题,进程杀死等。对此的方法也很多
void MainWindow::closeEvent(QCloseEvent *event) { for(auto &one : m_listProcess){ one->close(); } }
当然,如果时其他开发的App,嵌套中会出现问题,所以还是说,小楼里面开商场,搞笑。
-
用Tkinter打造GUI开发工具(41)Tkinter窗口中嵌套其他应用程序窗口
2020-06-06 20:53:17用Tkinter打造GUI开发工具(41)Tkinter窗口中嵌套其他应用程序窗口 上一篇我们介绍了Tkinter中的真多子窗口设计,如果我们想增加外部的一个Toplevel子窗口,能够套入主窗口中吗?用HP_mtk2当然可以的。 我们甚至能... -
blockbar:一个不同的进度条,将嵌套循环中的计算状态可视化为块,而不是 %completed。-matlab开发
2021-05-29 07:40:02这个函数提供了一种不同的等待栏。 它是为重复执行相同任务的缓慢嵌套循环而编写的。 每个任务/进程都拥有它的“块”,完成后会改变颜色。 此功能非常适合监控 parfeval 计算。 它允许有选择地取消“卡住”的期货。... -
QT在当前进程界面中嵌入其他进程的界面
2019-11-08 16:07:05最近接触到外协厂家的一套系统,这套系统的主界面由几个功能界面组成的,他的实现方式并不是将所有的功能界面设计在这一个主界面程序上,而是将各个功能界面做成单独的界面程序(单独的进程),每个程序都可以独立... -
解决 WPF 嵌套的子窗口在改变窗口大小的时候闪烁的问题
2019-10-28 08:56:13因为 Win32 的窗口句柄是可以跨进程传递的,所以可以用来实现跨进程 UI。不过,本文不会谈论跨进程 UI 的具体实现,只会提及其实现中的一个重要缓解,使用子窗口的方式。 你有可能在使用子窗口之后,发现拖拽改变... -
使用 SetParent 制作父子窗口的时候,如何设置子窗口的窗口样式以避免抢走父窗口的焦点
2019-11-27 07:49:47制作传统 Win32 程序以及 Windows Forms 程序的时候,一个用户看起来独立的窗口本就是通过各种父子窗口嵌套完成的,有大量窗口句柄,窗口之间形成父子关系。不过,对于 WPF 程序来说,一个独立的窗口实际上只有一个... -
在Qt中将QWindow或者QWidget嵌入到别的进程中的窗口中(windows)
2018-02-08 10:58:30前提:必须知道另外一个进程的窗口句柄 示例(这里用QWidget举例,QWindow也一样的): 1、首先创建一个进程,创建一个顶级窗口“Proc 1 Window”并运行 #include "mainwindow.h" #include <QApplication... -
c++多进程编程
2020-04-16 10:12:52c++多进程编程 介绍 进程:进程是一个正在执行的程序,是向CPU申请资源的,进程之间数据相互独立,一个进程至少有一个线程。 线程:线程是进程中的单一的顺序控制流程也可以叫做最小控制单元,线程是进程中执行单元... -
说说Windows嵌套窗口数量限制
2020-08-31 21:05:53嵌套窗口不能太多 在古老的年代,Windows系统并不会限制应用程序的嵌套...但是到了Windows NT的时候,窗口管理器从应用程序的栈中移除(首先是被移动到了单独的进程,后来被移到了内核空间中)。这个时候,操作系统就 -
MultiProcessUion.7z
2020-03-30 19:24:26演示通过每个标签页运行一个进程,让每个进程的窗口成为主进程的一个子窗口,各进程间相互不干扰,可通过主进程进行中转消息进行通信 -
C# 根据窗口句柄设置父窗口并在父窗口中显示子窗口
2020-03-25 15:41:01已经知道了一个窗口的句柄,如何将这个窗口设置为父窗口并显示一个子窗口进去? 主要使用了WIN API函数SetParent; [DllImport("user32.dll", EntryPoint = "SetParent")] public static extern int SetParent... -
Qt源码解析2---外部程序嵌入到Qt进程界面
2022-02-25 17:11:14Qt源码解析 索引 Qt程序开发时经常需要启动外部程序,这个通常使用QProcess挺好解决的...可以将calc嵌入到您自己的应用程序中,但它仍然可以在它自己的进程空间中运行. UAC可能还会施加一些限制,但这取决于计算方法的推 -
E语言(外部程序嵌入运行在窗口)
2008-08-26 20:01:55E语言(外部程序嵌入运行在窗口) 将指定运行的程序运行在编译的窗口中,使其成为该窗口的子窗口而存在 -
System.InvalidOperationException:“寄宿 HWND 必须是子窗口。”
2019-10-19 08:56:11当试图在 WPF 窗口中嵌套显示 Win32 子窗口的时候,你有可能出现错误:“System.InvalidOperationException:“寄宿 HWND 必须是子窗口。””。 这是很典型的 Win32 错误,本文介绍如何修复此错误。 本文内容一个最... -
外部进程嵌入到Qt进程界面
2017-11-14 20:49:19有时候需要做框架集成的东西,需要把其他客户端像组件一样集成到一个客户端中,类似于一个软件集成的平台客户端,统一用一个中心管理的...一、首先是获取计算机程序的窗口类名称,只要利用的是VS中的Spy++工具,在vs菜 -
winform把exe程序嵌套在窗体中
2010-05-23 09:30:39winform把将外部exe程序作为窗体的一部分,嵌套在自己定义的窗体中。 -
qt界面嵌入外部进程界面
2018-02-06 11:42:33有时候需要做框架集成的东西,需要把其他客户端像组件一样集成到一个客户端中,类似于一个软件集成的平台客户端,统一用一个中心管理的...一、首先是获取计算机程序的窗口类名称,只要利用的是VS中的Spy++工具,在v -
VB将外部程序加载到自己程序窗体中显示
2021-05-07 11:17:47内容索引:VB源码,系统相关,窗体嵌套 VB将外部程序加载到自己程序窗体中显示,虽然这个示例很小,但可能很实用这个功能,在本例中,将计算器、记事本、翻牌游戏显示在自己所指定的窗体中,而且不会超出窗体范围,就... -
java--进程和线程
2018-11-25 22:55:49进程和线程的概述 ...进程就是正在运行的程序,它是系统资源调度的独立单位,各个进程之间不会相互影响,因为系统给它们分配了不同的空间和资源,它分为单进程和多进程。 单进程与多进程的概述 ... -
将GLFW窗口嵌入Win32 SDK窗口及其多线程渲染方法
2020-04-14 19:30:08这篇文章提到了glfw嵌入mfc的办法,采用的查找进程PID再嵌入的方法,进程间通信采用UDP,略微繁琐。 MFC单文档视图中嵌入GLFW窗口 其实不必如此麻烦,SetParent直接就可以办到。 第1步 创建标准Win32 SDK窗口 #... -
System.InvalidOperationException:“BuildWindowCore 无法返回寄宿的子窗口句柄。”
2019-10-19 09:06:07当试图在 WPF 窗口中嵌套显示 Win32 子窗口的时候,你有可能出现错误:“BuildWindowCore 无法返回寄宿的子窗口句柄。”。 这是很典型的 Win32 错误,本文介绍如何修复此错误。 本文内容问题原因和解决办法 我们在 ... -
十种进程注入技术介绍
2019-02-28 15:01:46尽管目前有许多进程注入技术,但在这篇文章中,我将会介绍十种在野发现的,在另一个程序的地址空间执行恶意代码的进程注入技术,并提供这些技术应用的截图,以便于逆向工程和恶意软件分析,然后协助检测并防御这些... -
electron BrowserView组件嵌套网页(六)
2020-09-21 17:43:59文章目录例子如何让一个网页充满整个窗口 例子 const { app, BrowserWindow, BrowserView, globalShortcut } = require('electron') const path = require('path') var mainWindow = null // 声明要打开的主窗口 ...