在對話框應用中嵌入一個.exe應用

注:本文系由外文翻譯而來,原文請見Hosting .exe applications into a dialog


一篇關於在基於對話框應用中啓動和嵌入.exe應用的文章
例程下載-27.0KB
這裏寫圖片描述

介紹

這是個講述如何嵌入一個.exe應用到對話框中去的簡單應用。相同的應用可以在C#中使用,點擊這裏。但是如果我們想在VC++ 6.0實現這個目的,就有一點點的不一樣。我試圖在不同網站中找到VC++ 6.0下相關的例子,但卻沒有找到,最終我決定自己來完成這項工作。

過程

基本的步驟如下:
1. 聲明兩個需要的變量
2. 用CreateProcess啓動需要打開的.exe應用
3. 寫一個回調函數來獲得處理窗口的句柄HWND
4. 給.exe應用設置父窗口
5. 設置.exe應用窗口的位置

具體實現

步驟1:聲明兩個變量

你必須先聲明以下變量:

HWND apphwnd;
HANDLE handle;

步驟2:用CreateProcess函數啓動.exe應用

下面這個函數將會完成這個任務,並返回進程的句柄

 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,  // process security
                                    NULL,  // thread security
                                    FALSE, // no inheritance
                                    0,     // no startup flags
                                    NULL,  // no special environment
                                    NULL,  // default startup directory
                                    &startupInfo,
                                    &processInfo))
                    { /* success */
                Sleep(5000);//wait for the window of exe application created
                ::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);
                     hProcess = processInfo.hProcess;
                    } /* success */
         return hProcess;//Return HANDLE of process.
        }

這裏我們用CreateProcess啓動進程。

函數WaitForInputIdle將暫停一個線程的執行,直到相應的進程完成初始化工作。通過把句柄傳遞給每個窗口,並反過來給到一個用戶定義的回調函數中去,函數EnumWindows枚舉屏幕上所有頂層窗口。EnumWindows函數一直運行直到最後一個頂層窗口被列舉出來,或者回調函數返回FALSE。

我們的回調函數將會獲取新進程窗口的句柄HWND。返回的句柄hprocess能被用來終止進程。
TerminateProcess(handle,0);

步驟3:寫一個回調函數來獲取進程窗口的句柄HWND

爲了找到我們的.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檢索創建了特定窗口線程的id。apphwnd變量保存了新建窗口的句柄。

步驟4:爲.exe應用設置父窗口

此時我們設置.exe應用窗口的父窗口。父窗口是我們的對話框應用窗口。
::SetParent(apphwnd,m_hWnd);

如果有必要,我們可以利用下面這個函數移除.exe窗口的標題欄。
::SetWindowLong(apphwnd, GWL_STYLE, WS_VISIBLE);

步驟5:設置.exe窗口位置

這個可以用下面的代碼實現:

CRect rect;
GetClientRect(&rect);
::MoveWindow(apphwnd, rect.left, rect.top,rect.right, rect.bottom, true);

GetClientRect函數將會獲得我們對話框窗口的大小尺寸。MoveWindow函數將會把.exe應用窗口移到我們的對話框中去。

備註

注意到調用函數StarNewProcess後,我們只能進行步驟4和5操作,並且應該在對話框項目中完成。

歷史

2007年5月9日——原始版本發佈

許可聲明

這篇文章及相關源碼和文件在協議CPOL許可之下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章