如何在 Rich Edit 控制件中使用 OLE
本節包含如何在豐富的編輯控件中使用對象連結和內嵌 (OLE) 的相關信息。
您需要知道的事項
技術
必要條件
- C/C++
- Windows 使用者介面程序設計
指示
使用 Rich Edit 介面
豐富的編輯控件會透過元件物件模型 (COM) 介面公開其部分功能。 藉由從控件取得介面,您就能夠與控件內的其他物件搭配使用。 您可以傳送EM_GETOLEINTERFACE訊息來取得此介面。 接著,您可以從 IRichEditOle 介面取得文字物件模型中所使用的介面。
另一個介面 IRichEditOleCallback 是由應用程式實作,以在控件與對象互動時定義其行為。
將物件插入 Rich Edit 控制件
下列程式代碼範例會將檔案物件插入豐富的編輯控件中。 如果程式與用戶電腦上的檔案類型相關聯(例如,.xls檔案的 Microsoft Excel),則檔案的內容會顯示在控件中:否則,會出現圖示。
取得 IRichEditOle 介面。
BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName) { HRESULT hr; LPRICHEDITOLE pRichEditOle; SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); ...
建立結構化記憶體。
LPLOCKBYTES pLockBytes = NULL; hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes); LPSTORAGE pStorage; hr = StgCreateDocfileOnILockBytes(pLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); ...
設定數據格式。
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); ...
建立 物件並擷取其 IUnknown 介面。
LPUNKNOWN pUnk; CLSID clsid = CLSID_NULL; hr = OleCreateFromFile(clsid, pszFileName, IID_IUnknown, OLERENDER_DRAW, &formatEtc, pClientSite, pStorage, (void**)&pUnk); pClientSite->Release(); ...
取得 物件的 IOleObject 介面。
LPOLEOBJECT pObject; hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject); pUnk->Release(); ...
若要確保正確計算參考,請通知物件包含該參考。
OleSetContainedObject(pObject, TRUE); ...
設定物件資訊。
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; ...
將插入號移至文字結尾,並新增歸位字元。
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(); return TRUE; }
使用 IRichEditOleCallback
應用程式會實作 IRichEditOleCallback 介面,以回應由豐富編輯控件執行的 OLE 相關查詢或動作。 您可以藉由傳送 EM_SETOLECALLBACK 訊息,將介面的實作與控件產生關聯。 然後控件會視需要呼叫 介面實作的方法。
例如,當用戶嘗試將物件拖曳或貼到 控件時,會呼叫 QueryAcceptData。 如果您的應用程式可以接受數據,則方法的實作會傳回S_OK;否則,它會傳回錯誤碼。 方法可能也會採取一些其他動作,例如警告使用者該類型的檔案無法放在控件中。
完成 InsertObject 範例函式
下列程式代碼範例示範前一個代碼段結合成包含錯誤處理的一個完整函式。
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;
}
相關主題