Visual C# 作為微軟推出的新一代開發語言,其強大功能極大程度依賴 .NET Framework SDK 提供的豐富類庫。然而,現實開發中常會遇到這樣的情況:.NET 基礎類庫未提供的功能,卻在第三方 COM 組件中現成可用。此時如何讓 C# 呼叫這些 COM 組件?關鍵在於將「非受控代碼」轉換為「受控代碼」。
.NET 框架專門提供了 Aximp.exe 工具,能將 COM 組件轉換為 WinForm 可用的控制項。假設 SDK 安裝在 C 槽,該工具位於 C:\Program Files\Microsoft.NET\FrameworkSDK\Bin 目錄下。本文將以開發一個簡易瀏覽器為例,完整演示從 COM 組件轉換、控制項引用、核心功能實現到編譯運行的全過程。
Aximp.exe 將 shdocvw.dll(Microsoft Web Browser COM 組件)轉換為 WinForm 控制項AxSHDocVw.dll 與 SHDocVw.dllAxWebBrowser 控制項,實現導航、前進、後退、停止、重新整理、首頁等核心功能csc 命令列編譯生成獨立執行檔在 Windows 2000 系統中,shdocvw.dll 位於 c:\winnt\system32 目錄(Windows 98/Me 則在 c:\Windows\system)。打開命令提示字元,執行:
Aximp c:\winnt\system32\shdocvw.dll
命令執行完成後,當前目錄會生成兩個檔案:SHDocVw.dll(RCW 執行階段可呼叫包裝函式)與 AxSHDocVw.dll(ActiveX 控制項包裝函式),其中定義了 AxSHDocVw.AxWebBrowser 控制項,這是我們開發瀏覽器的核心。
首先匯入命名空間:
using AxSHDocVw;
然後在表單類別中宣告控制項實例:
private AxWebBrowser axWebBrowser1;
在「轉到」按鈕的 Click 事件中:
private void button1_Click(object sender, System.EventArgs e)
{
object nullObject = 0;
string str = "";
object nullObjStr = str;
Cursor.Current = Cursors.WaitCursor;
axWebBrowser1.Navigate(textBox1.Text, ref nullObject, ref nullObjStr, ref nullObjStr, ref nullObjStr);
Cursor.Current = Cursors.Default;
}
private void toolBar1_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
{
if (e.Button == tb1) axWebBrowser1.GoBack(); // 後退
if (e.Button == tb2) axWebBrowser1.GoForward(); // 前進
if (e.Button == tb3) axWebBrowser1.Stop(); // 停止
if (e.Button == tb4) axWebBrowser1.Refresh(); // 重新整理
if (e.Button == tb5) axWebBrowser1.GoHome(); // 首頁
}
// 「轉到」按鈕固定右上
button1.Anchor = AnchorStyles.Top | AnchorStyles.Right;
// 網址列固定上、左、右,隨寬度拉伸
textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
// 瀏覽器主體固定四邊,隨視窗縮放
axWebBrowser1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using AxSHDocVw;
public class Form1 : Form
{
private ToolBar toolBar1;
private ToolBarButton tb1, tb2, tb3, tb4, tb5;
private Label label1;
private TextBox textBox1;
private Button button1;
private AxWebBrowser axWebBrowser1;
private Container components = null;
public Form1() { InitializeComponent(); }
protected override void Dispose(bool disposing)
{
if (disposing && components != null) components.Dispose();
base.Dispose(disposing);
}
private void InitializeComponent()
{
// 工具列按鈕初始化
tb1 = new ToolBarButton(); tb1.Text = "後退";
tb2 = new ToolBarButton(); tb2.Text = "前進";
tb3 = new ToolBarButton(); tb3.Text = "停止";
tb4 = new ToolBarButton(); tb4.Text = "重新整理";
tb5 = new ToolBarButton(); tb5.Text = "首頁";
toolBar1 = new ToolBar();
toolBar1.Appearance = ToolBarAppearance.Flat;
toolBar1.BorderStyle = BorderStyle.FixedSingle;
toolBar1.Buttons.AddRange(new ToolBarButton[] { tb1, tb2, tb3, tb4, tb5 });
toolBar1.ShowToolTips = true;
toolBar1.Size = new Size(612, 39);
toolBar1.ButtonClick += new ToolBarButtonClickEventHandler(toolBar1_ButtonClick);
// 「轉到」按鈕
button1 = new Button();
button1.Anchor = AnchorStyles.Top | AnchorStyles.Right;
button1.Location = new Point(544, 45);
button1.Size = new Size(40, 23);
button1.Text = "轉到";
button1.Click += new EventHandler(button1_Click);
// 網址列
textBox1 = new TextBox();
textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
textBox1.Location = new Point(64, 47);
textBox1.Size = new Size(464, 21);
// 瀏覽器控制項
axWebBrowser1 = new AxWebBrowser();
((ISupportInitialize)axWebBrowser1).BeginInit();
axWebBrowser1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
axWebBrowser1.Location = new Point(0, 72);
axWebBrowser1.Size = new Size(608, 358);
((ISupportInitialize)axWebBrowser1).EndInit();
// 標籤
label1 = new Label();
label1.Location = new Point(16, 48);
label1.Size = new Size(48, 16);
label1.Text = "地址:";
// 表單設定
this.ClientSize = new Size(612, 433);
this.Controls.AddRange(new Control[] { toolBar1, label1, textBox1, button1, axWebBrowser1 });
this.Text = "Visual C# 瀏覽器";
this.ResumeLayout(false);
}
static void Main() { Application.Run(new Form1()); }
// 工具列按鈕事件
private void toolBar1_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
{
if (e.Button == tb1) axWebBrowser1.GoBack();
else if (e.Button == tb2) axWebBrowser1.GoForward();
else if (e.Button == tb3) axWebBrowser1.Stop();
else if (e.Button == tb4) axWebBrowser1.Refresh();
else if (e.Button == tb5) axWebBrowser1.GoHome();
}
// 導航事件
private void button1_Click(object sender, EventArgs e)
{
object nullObj = 0, nullStr = "";
Cursor.Current = Cursors.WaitCursor;
axWebBrowser1.Navigate(textBox1.Text, ref nullObj, ref nullStr, ref nullStr, ref nullStr);
Cursor.Current = Cursors.Default;
}
}
使用命令列編譯器 csc 生成 Windows 執行檔:
csc /t:winexe /r:AxSHDocVw.dll /r:SHDocVw.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll browser.cs
編譯成功後,執行 browser.exe 即可看到擁有工具列、網址列、導航功能的簡易瀏覽器介面。
本文完整示範了 Visual C# 透過 Aximp.exe 將 COM 組件轉換為受控控制項,並整合至 WinForm 應用程式的標準流程。掌握此技術後,開發者可進一步封裝更多 ActiveX 控制項(如 Media Player、Flash、Office 文件檢視器等),快速構建功能豐富的桌面應用。雖然現代 .NET 開發已轉向 WPF / WinUI,但 COM 互通機制在維護舊系統、整合協力廠商元件時仍具不可替代的價值。