Introduction
This is a simple application that will explain how to host or embed an .exe application into a dialog. The same application is available in C# here. But if we want to do this in Visual C++ 6.0, it is something different. I have searched for this on different sites and did not get it in Visual C++ 6.0, so I decided to do it myself.
Procedure
The basic procedure for this is:
- Declare the two required variables.
- Start the application using '
CreateProcess
'. - Write a call-back function to get the
HWND
of the process window. - Set the parent of the .exe application.
- Set the position of the window.
Technical Details
This program is an MFC Dialog-based application. The steps are outlined below.
Step 1: Declare Two Variables
You must first declare the following variables:
HWND apphwnd;
HANDLE handle;
Step 2: Start the Application using 'CreateProcess'
Here is the function that will do this task and return the handle of the process:
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);
::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);
hProcess = processInfo.hProcess;
}
return hProcess;
}
Here, we are starting the process using CreateProces
. The WaitForInputIdle
function enables a thread to suspend its execution until the specified process has finished its initialization. The EnumWindows
function enumerates all top-level windows on the screen by passing the handle to each window and, in turn, to an application-defined callback function. EnumWindows
continues until the last top-level window is enumerated or the callback function returns FALSE
.
Our callback function will get the HWND
of new the process window. The returned handle hprocess
can then be used to terminate the process:
TerminateProcess(handle,0);
Step 3: Write a Call-back Function to Get the HWND of the Process Window
This step is needed to find the HWND
of our .exe application's window. We can use this window handle in different functions such as SetParent
, MoveWindow
, etc.
int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
{
DWORD pID;
DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);
if (TpID == (DWORD)param)
{
apphwnd=hwnd;
return false;
}
return true;
}
The GetWindowThreadProcessId
function retrieves the identifier of the thread that created the specified window. apphwnd
is the window handle of the newly created window.
Step 4: Set the Parent of the .exe Application
Here, we are setting the parent window of the .exe application's window. The parent should be our application.
::SetParent(apphwnd,m_hWnd);
If we need to, we can remove the title bar of the window by using the following:
::SetWindowLong(apphwnd, GWL_STYLE, WS_VISIBLE);
Step 5: Set the Position of the Window
This can be done with the code below:
CRect rect;
GetClientRect(&rect);
::MoveWindow(apphwnd, rect.left, rect.top,rect.right, rect.bottom, true);
GetClientRect
will get the window size of our dialog. MoveWindow
will position the .exe application's window inside our dialog.
Remarks
Note that after calling StartNewProcess
, we should only do Steps 4 and 5, and these should be inside a function handler of our dialog-based program.
History
- 9th May, 2007 - Original version posted