在 aardio 中嵌入 Delphi 控制元件

這個例子我放到範例裡了:

在 aardio 中嵌入 Delphi 控制元件

執行這個範例,會自動檢測 Delphi 編寫的 DLL 是否存在,不存在會自動開啟 Delphi 工程,也就是這個檔案:

~\codes\範例程式\2) 呼叫其他語言\D) Delphi\Project1。dpr

注意上面路徑前面 ~ 符號,這在 aardio 裡表示當前 EXE 檔案所在目錄。

首先在 Delphi 的視窗原始碼( Unit1。pas 檔案) 新增一個建立視窗的函式如下:

function CreateForm(parentHandle: HWND): HWND; stdcall;var Form1 : TForm1;begin Form1 := TForm1。CreateParented(parentHandle); Form1。Show; Result := Form1。Handle;end;

這個函式接收一個外部視窗的控制代碼,並且將 TForm1 建立為外部視窗的子視窗,然後返回建立視窗的控制代碼,注意在 Delphi 工程的 exports 語句中匯出 CreateForm 函式 。

然後在 aardio 中呼叫該函式建立控制元件,這裡要注意幾個知識點:

1、在 win。ui。ctrl 名字空間下建立類,就可以在窗體上使用該控制元件類名,例如我們新建或匯入一個類 win。ui。ctrl。delphiForm, 然後我們就可以拖一個自定義控制元件到窗體上,並且將該控制元件的類名改為 delphiForm 就可以了。

2、自定義控制元件可以返回建立控制元件的引數或類名,也可以直接建立控制元件並將控制元件視窗的控制代碼包含到 hwnd 屬性中。

下面我們在 aardio 中編寫 win。ui。ctrl。delphiForm 控制元件:

var delphiDll = raw。loadDll($“\Project1。dll”);class win。ui。ctrl。delphiForm{ ctor(parent,tParam){ this。hwnd = delphiDll。CreateForm(parent。hwnd); }; @。。win。ui。ctrl。metaProperty()}

可以將上面的原始碼放到庫檔案中,再用

import

win。ui。ctrl。delphiForm 語句匯入,大家可以在標準庫中開啟 win。ui。ctrl 名字空間,可以看到非常多的控制元件類庫。

這裡要說明一下,為什麼 raw。loadDll($“\Project1。dll”); 這裡要加一個 $ 符號,這在 aardio 中用於將檔案編譯到程式碼中,然後執行時透過記憶體載入該 DLL檔案,也就是釋出後就不再需要該 DLL了,這非常方便。當然,不是必須要這樣做,也有一些 DLL 並不支援記憶體載入。

可以看到,在 aardio 中呼叫 Delphi 的匯出函式非常簡單,直接呼叫就可以了,不需要任何複雜的程式碼,實際上只要能編寫 DLL 的語言,我們都可以類似去呼叫他。

那麼在 Delphi 裡如何呼叫 aardio 函式呢?!其實很簡單,只要能呼叫 Delphi 函式,那麼就可以把 aardio 函式作為回撥函式傳給 Delphi ,這種方法很常用,在文件裡也有詳細說明,但這次我們不用這個方法。

今天我們換一個更簡單的方法,aardio 視窗物件支援一個神奇的 _WM_THREAD_CALLBACK 訊息,透過傳送這個訊息,就可以呼叫該視窗的成員函式,我們可以在 aardio 自帶的範例檢視這個訊息的用法:

~\codes\範例程式\1) aardio 語言\1) 多執行緒\12。threadCallback。aardio

有趣的是,這個方法也可以在 Delphi 裡使用,我在Delphi 工程範例裡提供了一個 aardio 。pas 檔案,匯入這個模組就可以使用這個訊息呼叫 aardio 視窗的成員函數了,例如:

aardio。sendCallback(self。ParentWindow,‘onTest( { int x;int y;} )’,@TestStruct);

@TestStruct 是 Delphi 的一個結構體指標,而上面的 self。ParentWindow 則是 aardio 視窗的控制代碼,‘onTest( { int x;int y;} )’ 是函式原型宣告,這句程式碼會呼叫 aardio 中的 winform。onTest 函式,並且引數會解析為 aardio 結構體 { int x;int y;}

aardio 中 winform。onTest 函式的原始碼如下:

winform。onTest = function(delphiStructParam){ winform。edit。print(“Delphi 呼叫了aardio 函式,引數如下:”); winform。edit。print(delphiStructParam); delphiStructParam。x = 90; //可選返回修改後的結構體 return delphiStructParam;}

從上面的程式碼可以看到,我們不但可以接收 Delphi 傳過來的結構體引數,還可以修改這個結構體( 也就是直接修改 Delphi 的結構體,Delphi 中結構體的值會被改變)

在與Delphi 互動要注意,Delphi 字串使用的是ANSI 編碼,而 aardio 使用的是 UTF-8 編碼。

看一下執行後的效果:

在 aardio 中嵌入 Delphi 控制元件

注意上面的結構體的值在第二次呼叫時已經被修改了。

使用這種方式嵌入 Delphi 控制元件,跟其他普通的自定義控制元件一樣,具有 aardio 控制元件的所有自適應佈局能力,支援固定邊距、自適應大小等屬性設定。