首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# WinForm 將外部應用程式視窗嵌入自身應用程式

     編輯:關於C#

前言

在專案開發中,常遇到需將現有獨立視窗應用程式嵌入自家開發的 WinForm 介面,使其外觀彷彿原生開發。然而,內嵌程式與宿主程式的視窗啟動狀態仍存有細微差異(例如內嵌視窗啟動時,宿主視窗卻處於非啟動狀態)。

解決方案演進

早期在 CodeProject 發現相關文章(Hosting EXE Applications in a WinForm project),雖可行但使用不便。因此重新設計封裝類庫,以單一控件完成嵌入功能。

實作示意圖

以下展示嵌入 Adobe Reader 等程式的實際畫面:

嵌入示例1 嵌入示例2 嵌入示例3 嵌入示例4

從 Adobe Reader 畫面可見「視窗啟動狀態問題」:內嵌程式視窗啟動時,包裹它的宿主視窗卻非啟動狀態。若欲隱藏此差異,可將宿主視窗 FormBorderStyle 設為 None,並自行繪製關閉、最大化、最小化按鈕。

核心實作步驟(原作者邏輯)

1. 啟動目標應用程式進程

Process p = null;
try {
    p = System.Diagnostics.Process.Start(this.exeName);
    p.WaitForInputIdle();
    appWin = p.MainWindowHandle;
} catch (Exception ex) {
    MessageBox.Show(this, ex.Message, "Error");
}

2. 呼叫 Windows API 將視窗嵌入自訂控件(如 Panel)

SetParent(appWin, this.Handle);
SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE);
MoveWindow(appWin, 0, 0, this.Width, this.Height, true);

3. 讓嵌入視窗隨宿主視窗縮放

protected override void OnResize(EventArgs e) {
    if (this.appWin != IntPtr.Zero) {
        MoveWindow(appWin, 0, 0, this.Width, this.Height, true);
    }
    base.OnResize(e);
}

4. 宿主關閉時同步關閉嵌入程式

protected override void OnHandleDestroyed(EventArgs e) {
    if (appWin != IntPtr.Zero) {
        PostMessage(appWin, WM_CLOSE, 0, 0);
        System.Threading.Thread.Sleep(1000);
        appWin = IntPtr.Zero;
    }
    base.OnHandleDestroyed(e);
}

改良版控件:AppContainer

原作者程式碼使用不便,故開發 AppContainer 控件,僅需三步即可完成嵌入:

  1. 專案引用 SmileWei.EmbeddedApp 類庫。
  2. 工具箱拖曳 AppContainer 控件至宿主視窗,調整位置(若未出現請先建置方案)。
  3. 設定嵌入目標 EXE 絕對路徑並啟動:
appContainer1.AppFilename = openEXE.FileName;
appContainer1.Start();

AppContainer 優勢

  • 自動處理視窗縮放與宿主關閉同步關閉。
  • 指定路徑與啟動分離,設計時期不會自動載入嵌入程式,避免干擾。
  • 內建防呆:禁止自我嵌入(死循環)、偵測 Console 應用程式無法嵌入、參數驗證等。
  • 採用 Application.Idle 事件而非 Thread.Sleep 確保嵌入時機,支援 Photoshop 等啟動緩慢程式。

進階:手動指定視窗控制代碼嵌入

部分程式啟動視窗與主視窗控制代碼不同,導致無法自動嵌入。解決方法:在宿主視窗狀態列提供「控制代碼嵌入」功能,輸入目標主視窗控制代碼即可嵌入。

控制代碼嵌入介面

如何取得目標視窗控制代碼?提供自製工具 WindowDetective (窗口偵探) 0.20:

WindowDetective 介面

啟動後自動偵測滑鼠所指視窗資訊,將滑鼠移至目標視窗標題列即可獲得控制代碼(如圖所示 Windows Live Writer 控制代碼)。QQ TM 版亦可嵌入,但正式版 QQ 可能因防護機制無法嵌入。

嵌入 QQ 對話框 嵌入 QQ 對話框效果

原始碼下載

原文出處:https://www.cnblogs.com/bitzhuwei/archive/2012/05/24/SmileWei_EmbeddedApp.html

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved