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

C# 整合 Google Earth COM API 開發實戰 (二):視窗嵌入與介面隱藏

     編輯:關於C#

承接第一篇 Hello World,本文解決核心整合需求:隱藏 Google Earth 原生視窗,將 3D 渲染畫面重定向嵌入自訂 WinForms 容器。使用 Windows API (SetParent, MoveWindow, SetWindowPos) 實現無縫嵌入,為後續互動功能奠基。

核心步驟

  1. 建立 ApplicationGEClass 實例,取得主視窗控制代碼 (GetMainHwnd) 與渲染視窗控制代碼 (GetRenderHwnd)
  2. 隱藏主視窗:SetWindowPos(HWND_BOTTOM, ..., SWP_HIDEWINDOW | SWP_NOSIZE)
  3. 取得渲染視窗父視窗 (GetParent),將其重新設定父視窗為自訂容器 (SetParent)
  4. 移動渲染視窗至容器客戶區原點並調整大小 (MoveWindow)
  5. 表單關閉時送出 WM_QUIT 正確關閉 GE 進程

完整程式碼

Form2.cs - 主視窗邏輯


using System;
using System.Windows.Forms;
using EARTHLib;
using System.Runtime.InteropServices;

namespace GEDemo
{
    public partial class Form2 : Form
    {
        private const int WM_QUIT = 0x0012;

        private IntPtr GEHWnd = IntPtr.Zero;
        private IntPtr GEHrender = IntPtr.Zero;
        private ApplicationGEClass GeApp;

        public Form2()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (DesignMode) return;

            // 1. 建立 GE 實例
            GeApp = new ApplicationGEClass();

            // 2. 取得主視窗並隱藏
            GEHWnd = (IntPtr)GeApp.GetMainHwnd();
            NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0,
                NativeMethods.SWP_NOSIZE | NativeMethods.SWP_HIDEWINDOW);

            // 3. 取得渲染視窗
            GEHrender = (IntPtr)GeApp.GetRenderHwnd();
            IntPtr oldParent = NativeMethods.GetParent(GEHrender);

            // 4. 先調整大小再重定向父視窗 (避免閃爍)
            NativeMethods.MoveWindow(GEHrender, 0, 0, this.Width, this.Height, true);
            NativeMethods.SetParent(GEHrender, this.Handle);
        }

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

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            if (GEHWnd != IntPtr.Zero)
                NativeMethods.PostMessage((int)GEHWnd, WM_QUIT, 0, 0);
        }
    }
}

NativeMethods.cs - Windows API 封裝


using System;
using System.Runtime.InteropServices;

namespace GEDemo
{
    public static class NativeMethods
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetParent(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        // 常數定義
        public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
        public static readonly IntPtr HWND_TOP = IntPtr.Zero;
        public const uint SWP_NOSIZE = 0x0001;
        public const uint SWP_HIDEWINDOW = 0x0080;
        public const uint SWP_FRAMECHANGED = 0x0020;
    }
}

關鍵 API 說明

API用途關鍵參數
SetWindowPos設定視窗位置、大小、Z-order、顯示狀態SWP_HIDEWINDOW 隱藏主視窗
GetRenderHwnd取得 GE 內部 OpenGL/Qt 渲染子視窗控制代碼此視窗為實際 3D 畫面載體
SetParent變更子視窗父視窗新父視窗 = 自訂 Form.Handle
MoveWindow移動並調整視窗大小座標相對新父視窗客戶區
PostMessage(WM_QUIT)通知 GE 進程正常退出避免殘留 googleearth.exe 進程

執行效果

Google Earth 3D 地球畫面嵌入自訂 WinForms 視窗,標題列顯示應用程式名稱,無 GE 原生選單與工具列

常見問題與解決

  1. 嵌入後畫面空白/黑屏:確保先 MoveWindow 再 SetParent,或在 OnResize 中重複 MoveWindow
  2. 關閉表單後 GE 進程殘留:必須在 OnClosing 送出 WM_QUIT,不可直接 Process.Kill
  3. 多螢幕 DPI 縮放導致座標偏移:設定專案 dpiAware 或使用 SetProcessDpiAwareness
  4. GE 版本不相容:需參考對應版本的 EARTHLib (Google Earth 1.0 Type Library),版本號需匹配

系列脈絡

  1. (一) Hello World:啟動 GE、截圖、基本 COM 呼叫
  2. (二) 視窗嵌入:隱藏原生視窗、渲染畫面重定向至自訂容器 ← 本文
  3. (三) 互動增強:自適應、滑鼠事件、彩色截圖
  4. (四) 進階控制:滾輪縮放、地標圖層樹狀管理

總結

透過 SetParent 重定向渲染視窗父視窗,配合 MoveWindow 同步大小,即可將 Google Earth 3D 引擎無縫整合進 WinForms 應用。此技術同樣適用於其他基於 Qt、OpenGL 或獨立渲染視窗的第三方元件嵌入場景。下一步將加入滑鼠互動、座標轉換與圖層管理,構建完整 GIS 應用框架。

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