Cara Menggunakan OLE di Kontrol Pengeditan Kaya
Bagian ini berisi informasi tentang menggunakan penautan dan penyematan objek (OLE) dalam kontrol pengeditan kaya.
Apa yang perlu Anda ketahui
Teknologi
Prasyarat
- C/C++
- Pemrograman Antarmuka Pengguna Windows
Peraturan
Menggunakan Antarmuka Edit Kaya
Kontrol edit kaya mengekspos beberapa fungsionalitasnya melalui antarmuka Model Objek Komponen (COM). Dengan mendapatkan antarmuka dari kontrol, Anda mendapatkan kemampuan untuk bekerja dengan objek lain dalam kontrol. Anda dapat memperoleh antarmuka ini dengan mengirim pesan EM_GETOLEINTERFACE. Dari antarmukaIRichEditOle, Anda kemudian dapat memperoleh antarmuka yang digunakan dalam Text Object Model.
Antarmuka lain, IRichEditOleCallback, diimplementasikan oleh aplikasi untuk menentukan perilaku kontrol ketika berinteraksi dengan objek.
Sisipkan Objek ke dalam Kontrol Edit Kaya
Contoh kode berikut menyisipkan objek file ke dalam kontrol edit yang kaya. Jika program dikaitkan dengan tipe file pada komputer pengguna (misalnya, Microsoft Excel untuk file .xls), konten file ditampilkan dalam kontrol; jika tidak, ikon akan muncul.
Dapatkan antarmuka IRichEditOle .
BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName) { HRESULT hr; LPRICHEDITOLE pRichEditOle; SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); ...
Buat penyimpanan terstruktur.
LPLOCKBYTES pLockBytes = NULL; hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes); LPSTORAGE pStorage; hr = StgCreateDocfileOnILockBytes(pLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); ...
Siapkan format data.
FORMATETC formatEtc; formatEtc.cfFormat = 0; formatEtc.ptd = NULL; formatEtc.dwAspect = DVASPECT_CONTENT; formatEtc.lindex = -1; formatEtc.tymed = TYMED_NULL; ...
Dapatkan penunjuk ke situs tampilan.
LPOLECLIENTSITE pClientSite; hr = pRichEditOle->GetClientSite(&pClientSite); ...
Buat objek dan ambil antarmuka IUnknown .
LPUNKNOWN pUnk; CLSID clsid = CLSID_NULL; hr = OleCreateFromFile(clsid, pszFileName, IID_IUnknown, OLERENDER_DRAW, &formatEtc, pClientSite, pStorage, (void**)&pUnk); pClientSite->Release(); ...
Dapatkan antarmuka IOleObject ke objek.
LPOLEOBJECT pObject; hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject); pUnk->Release(); ...
Untuk memastikan bahwa referensi dihitung dengan benar, beri tahu objek bahwa referensi tersebut terkandung.
OleSetContainedObject(pObject, TRUE); ...
Siapkan info objek.
REOBJECT reobject = { sizeof(REOBJECT)}; hr = pObject->GetUserClassID(&clsid); reobject.clsid = clsid; reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT; reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE; reobject.dwUser = 0; reobject.poleobj = pObject; reobject.polesite = pClientSite; reobject.pstg = pStorage; SIZEL sizel = { 0 }; reobject.sizel = sizel; ...
Pindahkan tanda sisipan ke akhir teks dan tambahkan pengembalian pengangkutan.
SendMessage(hRichEdit, EM_SETSEL, 0, -1); DWORD dwStart, dwEnd; SendMessage(hRichEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd); SendMessage(hRichEdit, EM_SETSEL, dwEnd+1, dwEnd+1); SendMessage(hRichEdit, EM_REPLACESEL, TRUE, (WPARAM)L"\n"); ...
Sisipkan objek.
hr = pRichEditOle->InsertObject(&reobject); ...
Bersihkan.
pObject->Release(); pRichEditOle->Release(); return TRUE; }
Menggunakan IRichEditOleCallback
Aplikasi menerapkan antarmukaIRichEditOleCallbackuntuk merespons kueri atau tindakan terkait OLE yang dilakukan oleh kontrol edit yang kaya. Anda mengaitkan implementasi antarmuka dengan kontrol dengan mengirim pesan EM_SETOLECALLBACK. Kemudian, kontrol akan memanggil metode pada implementasi antarmuka Anda yang sesuai.
Misalnya, QueryAcceptData dipanggil saat pengguna mencoba menyeret atau menempelkan objek ke dalam kontrol. Jika aplikasi Anda dapat menerima data, implementasi metode Anda akan mengembalikan S_OK; jika tidak, kode kesalahan akan dikembalikan. Metode ini mungkin juga mengambil beberapa tindakan lain, seperti memperingatkan pengguna bahwa file jenis tersebut tidak dapat ditempatkan dalam kontrol.
Fungsi Contoh InsertObject Lengkap
Contoh kode berikut menunjukkan cuplikan kode sebelumnya yang digabungkan menjadi satu fungsi lengkap yang mencakup penanganan kesalahan.
BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName)
{
HRESULT hr;
LPRICHEDITOLE pRichEditOle;
SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
if (pRichEditOle == NULL)
{
return FALSE;
}
LPLOCKBYTES pLockBytes = NULL;
hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes);
if (FAILED(hr))
{
return FALSE;
}
LPSTORAGE pStorage;
hr = StgCreateDocfileOnILockBytes(pLockBytes,
STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
0, &pStorage);
if (FAILED(hr))
{
return FALSE;
}
FORMATETC formatEtc;
formatEtc.cfFormat = 0;
formatEtc.ptd = NULL;
formatEtc.dwAspect = DVASPECT_CONTENT;
formatEtc.lindex = -1;
formatEtc.tymed = TYMED_NULL;
LPOLECLIENTSITE pClientSite;
hr = pRichEditOle->GetClientSite(&pClientSite);
if (FAILED(hr))
{
return FALSE;
}
LPUNKNOWN pUnk;
CLSID clsid = CLSID_NULL;
hr = OleCreateFromFile(clsid, pszFileName, IID_IUnknown, OLERENDER_DRAW,
&formatEtc, pClientSite, pStorage, (void**)&pUnk);
pClientSite->Release();
if (FAILED(hr))
{
return FALSE;
}
LPOLEOBJECT pObject;
hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject);
pUnk->Release();
if (FAILED(hr))
{
return FALSE;
}
OleSetContainedObject(pObject, TRUE);
REOBJECT reobject = { sizeof(REOBJECT)};
hr = pObject->GetUserClassID(&clsid);
if (FAILED(hr))
{
pObject->Release();
return FALSE;
}
reobject.clsid = clsid;
reobject.cp = REO_CP_SELECTION;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE;
reobject.dwUser = 0;
reobject.poleobj = pObject;
reobject.polesite = pClientSite;
reobject.pstg = pStorage;
SIZEL sizel = { 0 };
reobject.sizel = sizel;
SendMessage(hRichEdit, EM_SETSEL, 0, -1);
DWORD dwStart, dwEnd;
SendMessage(hRichEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
SendMessage(hRichEdit, EM_SETSEL, dwEnd+1, dwEnd+1);
SendMessage(hRichEdit, EM_REPLACESEL, TRUE, (WPARAM)L"\n");
hr = pRichEditOle->InsertObject(&reobject);
pObject->Release();
pRichEditOle->Release();
if (FAILED(hr))
{
return FALSE;
}
return TRUE;
}
Topik terkait