在现代的编程环境中,将一个独立的.exe应用程序嵌入到另一个应用程序的对话框中是一个常见的需求。虽然在C#中实现这个功能相对简单,但在Visual C++6.0中则需要一些额外的步骤。本文将介绍如何在Visual C++ 6.0中实现这一功能。
要在Visual C++6.0中嵌入一个.exe应用程序到对话框,需要遵循以下基本步骤:
首先,必须声明以下变量:
    HWND apphwnd;
    HANDLE handle;
    
以下是执行此任务并返回进程句柄的函数:
    HANDLE StartNewProcess(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, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
        {
            Sleep(5000); // 等待exe应用程序窗口创建
            ::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);
            hProcess = processInfo.hProcess;
        }
        return hProcess; // 返回进程句柄
    }
    
在这里,使用CreateProcess启动进程。WaitForInputIdle函数使线程暂停执行,直到指定的进程完成初始化。EnumWindows函数通过将句柄传递给每个窗口,以及应用程序定义的回调函数,枚举屏幕上所有顶级窗口。EnumWindows继续进行,直到枚举完最后一个顶级窗口或回调函数返回FALSE。
回调函数将获取新进程窗口的HWND。返回的句柄hProcess随后可用于终止进程:
    TerminateProcess(handle, 0);
    
这一步需要找到.exe应用程序窗口的HWND。可以使用这个窗口句柄在不同的函数中,如SetParent、MoveWindow等。
    int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
    {
        DWORD pID;
        DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);
        if (TpID == (DWORD)param)
        {
            apphwnd = hwnd;
            return false;
        }
        return true;
    }
    
GetWindowThreadProcessId函数检索创建指定窗口的线程的标识符。apphwnd是新创建窗口的窗口句柄。
在这里,设置.exe应用程序窗口的父窗口。父窗口应该是应用程序。
    ::SetParent(apphwnd, m_hWnd);
    
如果需要,可以使用以下代码移除窗口的标题栏:
    ::SetWindowLong(apphwnd, GWL_STYLE, WS_VISIBLE);
    
可以使用以下代码完成:
    CRect rect;
    GetClientRect(▭);
    ::MoveWindow(apphwnd, rect.left, rect.top, rect.right, rect.bottom, true);
    
GetClientRect将获取对话框的窗口大小。MoveWindow将定位.exe应用程序的窗口在对话框内。