Kontrol ActiveX MFC: Topik Tingkat Lanjut
Artikel ini membahas topik lanjutan yang terkait dengan pengembangan kontrol ActiveX. Ini termasuk:
Penting
ActiveX adalah teknologi warisan yang tidak boleh digunakan untuk pengembangan baru. Untuk informasi selengkapnya tentang teknologi modern yang menggantikan ActiveX, lihat Kontrol ActiveX.
Menggunakan Kelas Database di Kontrol ActiveX
Karena kelas kontrol ActiveX adalah bagian dari pustaka kelas, Anda dapat menerapkan prosedur dan aturan yang sama untuk menggunakan kelas database dalam aplikasi MFC standar untuk mengembangkan kontrol ActiveX yang menggunakan kelas database MFC.
Untuk gambaran umum kelas database MFC, lihat Kelas Database MFC (DAO dan ODBC). Artikel ini memperkenalkan kelas MFC ODBC dan kelas MFC DAO dan mengarahkan Anda ke detail lebih lanjut.
Catatan
DAO didukung melalui Office 2013. DAO 3.6 adalah versi akhir, dan dianggap usang. Lingkungan dan wizard Visual C++ tidak mendukung DAO (meskipun kelas DAO disertakan dan Anda masih dapat menggunakannya). Microsoft menyarankan agar Anda menggunakan Templat OLE DB atau ODBC dan MFC untuk proyek baru. Anda hanya boleh menggunakan DAO dalam mempertahankan aplikasi yang ada.
Menerapkan Properti Berparameter
Properti berparameter (terkadang disebut array properti) adalah metode untuk mengekspos kumpulan nilai yang homogen sebagai properti tunggal kontrol. Misalnya, Anda dapat menggunakan properti berparameter untuk mengekspos array atau kamus sebagai properti. Di Visual Basic, properti seperti itu diakses menggunakan notasi array:
x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array
Gunakan Wizard Tambahkan Properti untuk mengimplementasikan properti berparameter. Wizard Tambahkan Properti mengimplementasikan properti dengan menambahkan sepasang fungsi Get/Set yang memungkinkan pengguna kontrol mengakses properti menggunakan notasi di atas atau dengan cara standar.
Mirip dengan metode dan properti, properti berparameter juga memiliki batas jumlah parameter yang diizinkan. Dalam kasus properti berparameter, batasnya adalah 15 parameter (dengan satu parameter yang dicadangkan untuk menyimpan nilai properti).
Prosedur berikut menambahkan properti berparameter, yang disebut Array, yang dapat diakses sebagai array bilangan bulat dua dimensi.
Untuk menambahkan properti berparameter menggunakan Wizard Tambahkan Properti
Muat proyek kontrol Anda.
Di Tampilan Kelas, perluas node pustaka kontrol Anda.
Klik kanan node antarmuka untuk kontrol Anda (node kedua dari node pustaka) untuk membuka menu pintasan.
Dari menu pintasan, klik Tambahkan lalu klik Tambahkan Properti.
Dalam kotak Nama Properti, ketik
Array
.Dalam kotak Jenis Properti, pilih
short
.Untuk Jenis Implementasi , klik Dapatkan/Atur Metode.
Dalam kotak Dapatkan Fungsi dan Atur Fungsi , ketik nama unik untuk Dapatkan dan Atur Fungsi Anda atau terima nama default.
Tambahkan parameter, yang disebut baris (ketik pendek), menggunakan kontrol Nama Parameter dan Jenis Parameter.
Tambahkan parameter kedua yang disebut kolom (ketik pendek).
Klik Selesai.
Perubahan yang Dibuat oleh Wizard Tambahkan Properti
Saat Anda menambahkan properti kustom, Wizard Tambahkan Properti membuat perubahan pada header kelas kontrol (. H) dan implementasinya (. File CPP).
Baris berikut ditambahkan ke kelas kontrol . File H:
SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);
Kode ini mendeklarasikan dua fungsi yang dipanggil GetArray
dan SetArray
yang memungkinkan pengguna untuk meminta baris dan kolom tertentu saat mengakses properti.
Selain itu, Wizard Tambahkan Properti menambahkan baris berikut ke peta pengiriman kontrol, yang terletak di implementasi kelas kontrol (. CPP) file:
DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)
Akhirnya, implementasi GetArray
fungsi dan SetArray
ditambahkan ke akhir . File CPP. Dalam kebanyakan kasus, Anda akan memodifikasi fungsi Get untuk mengembalikan nilai properti. Fungsi Set biasanya akan berisi kode yang harus dijalankan, baik sebelum atau sesudah properti berubah.
Agar properti ini berguna, Anda dapat mendeklarasikan variabel anggota array dua dimensi di kelas kontrol, jenis short
, untuk menyimpan nilai untuk properti berparameter. Anda kemudian dapat mengubah fungsi Dapatkan untuk mengembalikan nilai yang disimpan pada baris dan kolom yang tepat, seperti yang ditunjukkan oleh parameter, dan mengubah fungsi Set untuk memperbarui nilai yang dirujuk oleh parameter baris dan kolom.
Menangani Kesalahan di Kontrol ActiveX Anda
Jika kondisi kesalahan terjadi dalam kontrol, Anda mungkin perlu melaporkan kesalahan ke kontainer kontrol. Ada dua metode untuk melaporkan kesalahan, tergantung pada situasi di mana kesalahan terjadi. Jika kesalahan terjadi dalam fungsi Get atau Set properti, atau dalam implementasi metode OLE Automation, kontrol harus memanggil COleControl::ThrowError, yang memberi sinyal kepada pengguna kontrol bahwa terjadi kesalahan. Jika kesalahan terjadi di lain waktu, kontrol harus memanggil COleControl::FireError, yang mengaktifkan peristiwa Kesalahan stok.
Untuk menunjukkan jenis kesalahan yang telah terjadi, kontrol harus meneruskan kode kesalahan ke ThrowError
atau FireError
. Kode kesalahan adalah kode status OLE, yang memiliki nilai 32-bit. Jika memungkinkan, pilih kode kesalahan dari kumpulan kode standar yang ditentukan dalam OLECTL. File header H. Tabel berikut ini meringkas kode-kode ini.
Kode Kesalahan Kontrol ActiveX
Kesalahan | Deskripsi |
---|---|
CTL_E_ILLEGALFUNCTIONCALL | Panggilan fungsi ilegal |
CTL_E_OVERFLOW | Luapan |
CTL_E_OUTOFMEMORY | Kehabisan memori |
CTL_E_DIVISIONBYZERO | Pembagian dengan nol |
CTL_E_OUTOFSTRINGSPACE | Kehabisan string space |
CTL_E_OUTOFSTACKSPACE | Kehabisan stack space (ruang tumpukan) |
CTL_E_BADFILENAMEORNUMBER | Nama atau nomor file yang buruk |
CTL_E_FILENOTFOUND | File tidak ditemukan |
CTL_E_BADFILEMODE | Mode file yang buruk |
CTL_E_FILEALREADYOPEN | File sudah terbuka |
CTL_E_DEVICEIOERROR | Kesalahan I/O perangkat |
CTL_E_FILEALREADYEXISTS | File sudah ada |
CTL_E_BADRECORDLENGTH | Panjang rekaman yang buruk |
CTL_E_DISKFULL | Disk penuh |
CTL_E_BADRECORDNUMBER | Nomor rekaman yang buruk |
CTL_E_BADFILENAME | Nama file buruk |
CTL_E_TOOMANYFILES | Terlalu banyak file |
CTL_E_DEVICEUNAVAILABLE | Perangkat tidak tersedia |
CTL_E_PERMISSIONDENIED | Izin ditolak |
CTL_E_DISKNOTREADY | Disk belum siap |
CTL_E_PATHFILEACCESSERROR | Kesalahan akses jalur/file |
CTL_E_PATHNOTFOUND | Jalur tidak ditemukan |
CTL_E_INVALIDPATTERNSTRING | String pola tidak valid |
CTL_E_INVALIDUSEOFNULL | Penggunaan NULL tidak valid |
CTL_E_INVALIDFILEFORMAT | Format file tidak valid |
CTL_E_INVALIDPROPERTYVALUE | Nilai properti tidak valid |
CTL_E_INVALIDPROPERTYARRAYINDEX | Indeks array properti tidak valid |
CTL_E_SETNOTSUPPORTEDATRUNTIME | Pengaturan tidak didukung pada run time |
CTL_E_SETNOTSUPPORTED | Pengaturan tidak didukung (properti baca-saja) |
CTL_E_NEEDPROPERTYARRAYINDEX | Butuh indeks array properti |
CTL_E_SETNOTPERMITTED | Pengaturan tidak diizinkan |
CTL_E_GETNOTSUPPORTEDATRUNTIME | Dapatkan tidak didukung pada run time |
CTL_E_GETNOTSUPPORTED | Dapatkan tidak didukung (properti tulis-saja) |
CTL_E_PROPERTYNOTFOUND | Properti tidak ditemukan |
CTL_E_INVALIDCLIPBOARDFORMAT | Format papan klip tidak valid |
CTL_E_INVALIDPICTURE | Gambar tidak valid |
CTL_E_PRINTERERROR | Kesalahan printer |
CTL_E_CANTSAVEFILETOTEMP | Tidak dapat menyimpan file ke TEMP |
CTL_E_SEARCHTEXTNOTFOUND | Teks pencarian tidak ditemukan |
CTL_E_REPLACEMENTSTOOLONG | Penggantian terlalu panjang |
Jika perlu, gunakan makro CUSTOM_CTL_SCODE untuk menentukan kode kesalahan kustom untuk kondisi yang tidak dicakup oleh salah satu kode standar. Parameter untuk makro ini harus berupa bilangan bulat antara 1000 dan 32767, inklusif. Contohnya:
#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)
Jika Anda membuat kontrol ActiveX untuk mengganti kontrol VBX yang ada, tentukan kode kesalahan kontrol ActiveX Anda dengan nilai numerik yang sama yang digunakan kontrol VBX untuk memastikan bahwa kode kesalahan kompatibel.
Menangani Kunci Khusus di Kontrol
Dalam beberapa kasus, Anda mungkin ingin menangani kombinasi penekanan kunci tertentu dengan cara khusus; misalnya, sisipkan baris baru saat tombol ENTER ditekan dalam kontrol kotak teks multibaris atau berpindah di antara grup kontrol edit saat ID tombol arah ditekan.
Jika kelas dasar kontrol ActiveX Anda adalah COleControl
, Anda dapat mengambil alih CWnd::P reTranslateMessage untuk menangani pesan sebelum kontainer memprosesnya. Saat menggunakan teknik ini, selalu kembaliKAN TRUE jika Anda menangani pesan dalam penimpaan Anda .PreTranslateMessage
Contoh kode berikut menunjukkan cara yang mungkin untuk menangani pesan apa pun yang terkait dengan kunci arah.
BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)
{
BOOL bHandleNow = FALSE;
switch (pMsg->message)
{
case WM_KEYDOWN:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
bHandleNow = TRUE;
break;
}
if (bHandleNow)
{
OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
}
break;
}
return bHandleNow;
}
Untuk informasi selengkapnya tentang menangani antarmuka keyboard untuk kontrol ActiveX, lihat dokumentasi ActiveX SDK.
Mengakses Kontrol Dialog yang Tidak Terlihat pada Run Time
Anda dapat membuat kontrol dialog yang tidak memiliki antarmuka pengguna dan tidak terlihat pada waktu proses. Jika Anda menambahkan kontrol ActiveX yang tidak terlihat pada waktu proses ke kotak dialog dan menggunakan CWnd::GetDlgItem untuk mengakses kontrol, kontrol tidak akan berfungsi dengan benar. Sebagai gantinya, Anda harus menggunakan salah satu teknik berikut untuk mendapatkan objek yang mewakili kontrol:
Menggunakan Wizard Tambahkan Variabel Anggota, pilih Variabel Kontrol lalu pilih ID kontrol. Masukkan nama variabel anggota dan pilih kelas pembungkus kontrol sebagai Jenis Kontrol.
-atau-
Deklarasikan variabel dan subkelas lokal sebagai item dialog. Sisipkan kode yang menyerupan berikut (
CMyCtrl
adalah kelas pembungkus, IDC_MYCTRL1 adalah ID kontrol):CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();