MFC中嵌入外部独立EXE程序

文章目录
目录

前言

一、简单窗口嵌套方案

二、复杂窗口嵌套方案

总结



前言

在股票期货量化交易过程中,交易工具、策略部分可能只会完成自身所关注逻辑部分,而不是一整套完整的图表系统。,若都需要自己去完成工作量太大了。但是某些场景下我有需要展示图表比如k线等数据。本文介绍一种基于MFC嵌套外部EXE方案实现。

一、简单窗口嵌套方案

所谓简单窗口嵌套是指:外部exe嵌套过程中不涉及到窗口句柄的变化。比如说记事本、计算器这种。针对这类型的窗口嵌套可以使用下面方案.

变量定义

cpp 复制代码
HANDLE hProcess;
HWND apphWnd = NULL;

代码

cpp 复制代码
int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
{
    DWORD pID;
    DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);//get process id
    if (TpID == (DWORD)param)
    {
        apphWnd=hwnd;
        return false;
    }
    return true;
}


HANDLE StartProcess(LPCTSTR program, LPCTSTR args)
{

    HANDLE hProcess = NULL;
    PROCESS_INFORMATION processInfo;
    STARTUPINFO startupInfo;
    ::ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
    if(::CreateProcess(program, (LPTSTR)args, 
        NULL,  // process security
        NULL,  // thread security
        FALSE, // no inheritance
        0,     // no startup flags
        NULL,  // no special environment
        NULL,  // default startup directory
        &startupInfo,
        &processInfo))
    { 
        Sleep(1000);
        ::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);//Iterate all windows
        hProcess = processInfo.hProcess;
    } 
    return hProcess;
}

嵌套调用代码

cpp 复制代码
CRect rect;
GetClientRect(&rect);//get our dialog size into rect
hProcess=StartProcess("xxx","");//xxx为完整的路径
if(apphWnd!=NULL)//check for window handle
{
   ::SetParent(apphWnd,m_hWnd);//set parent of ms paint to our dialog.
   SetWindowLong(apphWnd, GWL_STYLE, WS_VISIBLE);//eraze title of ms paint window.
   ::MoveWindow(apphWnd, rect.left, rect.top+10,rect.right, rect.bottom, true);
}

注意:xxx为你需要嵌套的完整的exe路径

关闭子进程代码

cpp 复制代码
    TerminateProcess(hProcess,0);
    apphWnd = NULL;

运行效果

二、复杂窗口嵌套方案

这里所谓的复杂窗口嵌套指的是启动exe后会弹出一个或者多个界面,最终到我们需要嵌套的主界面上,此时使用简单窗口嵌套方案就无效了。失效的根本原因是:方案一中获取的句柄不是最终句柄。

代码

cpp 复制代码
HWND apphWnd = ::FindWindow(NULL, "快期交易终端");

CRect rect;
GetClientRect(&rect);//get our dialog size into rect
::SetParent(apphWnd,m_hWnd);//set parent of ms paint to our dialog.
SetWindowLong(apphWnd, GWL_STYLE, WS_VISIBLE);//eraze title of ms paint window.
::MoveWindow(apphWnd, rect.left, rect.top+10,rect.right, rect.bottom, true);

运行效果


总结

上面2个方案各有优缺点,方案一只需要指定被嵌套的exe路径就可以完成嵌套操作,但是不能对于多窗口切换导致句柄变化方案一却不能满足,方案二只需要指定主要嵌套exe的名称,但是这个需要我们手工的启动程序。当然我们可以结合方案1和方案二优缺点进行改造。笔者实际项目中就是结合方案1、方案2进行改造的。在这里就当给大家留一份作业有需要的可自行改造.。

相关推荐
笨鸟起飞5 分钟前
CODEFORCES----1999A - A+B Again?
数据结构·c++·算法
1白天的黑夜11 小时前
动态规划-931.下降路径最小和-力扣(LeetCode)
c++·算法·leetcode·动态规划
h汉堡1 小时前
Codeforces Round 1027 (Div. 3)
数据结构·c++·算法
小葡萄20251 小时前
黑马程序员C++核心编程笔记--4 类和对象--封装
java·c++·笔记
一条叫做nemo的鱼2 小时前
从汇编的角度揭秘C++函数重载,原来这么简单
汇编·c++·函数重载·原理解密
唐装鼠2 小时前
C++ 模板参数包展开方式
开发语言·c++
feiyangqingyun7 小时前
Qt/C++开发监控GB28181系统/sip协议/同时支持udp和tcp模式/底层协议解析
c++·qt·gb28181
我是李武涯10 小时前
C++ 条件变量虚假唤醒问题的解决
开发语言·c++·算法
岁忧11 小时前
(nice!!!)(LeetCode 每日一题) 3372. 连接两棵树后最大目标节点数目 I (贪心+深度优先搜索dfs)
java·c++·算法·leetcode·go·深度优先