Terkadang komponen COM kami harus mengirim pemberitahuan kepada klien atau memanggil fungsi panggilan balik. Skema ini sederhana: komponen menerbitkan antarmuka, klien membuat objek yang diwarisi dari antarmuka dan meneruskannya ke komponen, komponen, pada gilirannya, memanggil fungsi antarmuka, sehingga memanggil fungsi di sisi klien.
Dalam kasus Visual Basic atau Visual Basic for Applicatons, kita dapat menulis kelas yang diwarisi dari antarmuka apa pun, tetapi ini tidak mungkin untuk file skrip VBScript.
Di sini antarmuka IDispatch
bergegas membantu kami. Menggunakan antarmuka ini, komponen kuat kami akan dengan rendah hati mengambil peran sederhana dari klien, dan skrip kecil akan berubah menjadi server otomatisasi nyata.
Kami akan mengembangkan komponen dalam bahasa pemrograman FreeBASIC.
Kelas dalam file skrip
Anda dapat mendeklarasikan dan menggunakan kelas dalam file skrip. Kelas-kelas semacam itu secara implisit diwarisi dari antarmuka IDispatch
dan merupakan kelas COM nyata.
Kami mendeklarasikan sebuah kelas, sebuah instance yang selanjutnya akan kami berikan ke komponen kami:
Class CallBack Function CallBack(Param)
Komponen kami akan menerima turunan dari kelas CallBack
, memanggil fungsi CallBack
dan meneruskannya string dengan teks dalam parameter.
IDispatch
Antarmuka ini adalah batu sandungan otomatisasi. Biasanya, implementasi IDispatch
didasarkan pada pustaka jenis melalui ITypeInfo->Invoke
atau CreateStdDispatch
, tetapi dalam hal ini server otomasi terletak dalam skrip dan tidak memiliki pustaka jenis, dan komponen kami bertindak sebagai klien. Untuk menyederhanakan, IDipatch
berfungsi seperti ini: mengambil nama fungsi dan mentransfer kontrol ke sana.
Definisi antarmuka terletak pada tajuk "oaidl.bi" (indentasi dan pemisah baris ditambahkan agar mudah dibaca):
Type IDispatch As IDispatch_ Type LPDISPATCH As IDispatch Ptr Type IDispatchVtbl
Fungsi GetIDsOfNames
dan Invoke
paling menarik di antarmuka ini.
GetIDsOfNames
Dibutuhkan nama fungsi dan mengembalikan pengenal pengirimannya DISPID
. DISPID
adalah alias untuk tipe LONG
.
Dari sudut pandang klien, DISPID
hanyalah alat pengoptimalan yang menghindari DISPID
baris. Untuk server, DISPID
adalah pengidentifikasi fungsi yang ingin dipanggil oleh klien.
Panggil
Dengan dispatch identifier melakukan fungsi yang sesuai.
DISPPARAM
Struktur ini berisi parameter dari fungsi yang dipanggil. Semua parameter dikemas dalam VARIANT
.
Type tagDISPPARAMS
Untuk menyederhanakan kode, kami tidak akan menggunakan argumen bernama, kami akan menetapkan NULL
sebagai gantinya.
Komponen
Untuk digunakan dalam skrip, komponen juga harus secara langsung atau tidak langsung mewarisi dari IDipatch
.
Antarmuka ITestCOMServer
ITestCOMServer
membangun antarmuka ITestCOMServer
dengan dua fungsi SetCallBack
dan InvokeCallBack
. Yang pertama akan menyimpan objek server otomatisasi, yang kedua akan memanggil fungsi objek.
Type ITestCOMServer As ITestCOMServer_ Type LPITESTCOMSERVER As ITestCOMServer Ptr Type ITestCOMServerVirtualTable
Kelas TestCOMServer
Sekarang Anda dapat mendeklarasikan kelas COM:
Type TestCOMServer
Fungsi setcallback
Implementasi fungsi SetCallBack
sederhana: kita menyimpan objek server otomatisasi yang dikirimkan oleh klien dan parameter panggilan fungsi.
Function TestCOMServerSetCallBack( _ ByVal pTestCOMServer As TestCOMServer Ptr, _ ByVal CallBack As IDispatch Ptr, _ ByVal UserName As BSTR _ )As HRESULT
Fungsi InvokeCallBack
Tetapi fungsi InvokeCallBack
bekerja keras. Pertama, Anda perlu mendapatkan pengidentifikasi operator fungsi CallBack
dari server otomatisasi.
Function TestCOMServerInvokeCallBack( _ ByVal pTestCOMServer As TestCOMServer Ptr _ )As HRESULT If pTestCOMServer->CallBack = NULL Then Return E_POINTER End If
Setelah DISPID
fungsi diterima, itu bisa disebut:
Kesimpulan
Seperti yang Anda lihat, bahkan dengan file skrip, komponen dapat memperoleh umpan balik. Ini berguna untuk memberi tahu klien operasi yang selesai oleh komponen.
Kelas-kelas dalam skrip dapat didaftarkan dalam registri, dalam hal ini mereka akan tersedia untuk seluruh sistem menggunakan ProgID
, tetapi ini adalah cerita yang sangat berbeda.
Referensi
Kode proyek di situs github: https://github.com/zamabuvaraeu/TestCOMServer
PS Entah bagaimana sorotan untuk sintaks BASIC menghilang, alih-alih menggunakan VBScript, dan beberapa operator tidak disorot dengan itu.