【正文】
rage::Release成員函數(shù)釋放。 數(shù)據(jù)對(duì)象 ? IDataObject接口 IDataObject接口的成員 (一 ) ? GetData( FORMATETC *, STGMEDIUM *) ? GetDataHere( FORMATETC *, STGMEDIUM *) ? QueryGetData( FORMATETC *) ? GetCanonicalFormatEtc(FORMATETC *pformatectIn, FORMATETC *pformatetcOut) IDataObject接口的成員 (二 ) ? SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease) ? EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC **) ? DAdvise(FORMATETC *, DWORD advf, IAdviseSink *, DWORD *) ? DUnadvise( DWORD ) ? EnumDAdvise( IEnumSTATDATA **) 通報(bào)連接 (advisory connection)機(jī)制 客戶通過 IData Ob jec t: :DA d v is e函數(shù)把接收器傳給對(duì)象客戶程序通報(bào)連接接收器對(duì)象數(shù)據(jù)對(duì)象事件發(fā)生時(shí)數(shù)據(jù)對(duì)象調(diào)用 On Data Ch a n g e 成員IA d v ise S in kIData Ob jec t剪貼板傳輸數(shù)據(jù)機(jī)理 (一 ) ? 常用的 7個(gè) Win32 API函數(shù) BOOL WINAPI OpenClipboard( HWND hWndNewOwner)。 BOOL WINAPI CloseClipboard( VOID)。 BOOL WINAPI EmptyClipboard(VOID)。 HANDLE WINAPI SetClipboardData( UINT uFormat, HANDLE hMem)。 HANDLE WINAPI GetClipboardData( UINT uFormat)。 BOOL WINAPI IsClipboardFormatAvailable( UINT format)。 UINT WINAPI EnumClipboardFormats( UINT format)。 ? 剪貼板是系統(tǒng)全局共享,進(jìn)程獨(dú)占方式 ? 存儲(chǔ)介質(zhì)僅限于全局內(nèi)存 剪貼板傳輸數(shù)據(jù)機(jī)理 (二 ) ? 剪貼板所有者為一個(gè) Windows窗口 – 調(diào)用 EmptyClipboard時(shí)被 OpenClipboard指定的窗口 ? 延遲供應(yīng) (delayed rendering): – (1)SetClipboardData的參數(shù) hMem可以是 NULL – (2) 客戶需要數(shù)據(jù)時(shí),所有者窗口處理WM_RENDERFORMAT消息 – (3)所有者窗口被刪除之前處理WM_RENDERALLFORMATS消息 OLE剪貼板 (一 ) ? OLE API函數(shù) WINOLEAPI OleSetClipboard(IDataObject *pDataObj)。 WINOLEAPI OleGetClipboard(IDataObject ** ppDataObj)。 WINOLEAPI OleFlushClipboard(void)。 WINOLEAPI OleIsCurrentClipboard(IDataObject *pDataObj)。 ? OleSetClipboard內(nèi)部把所有權(quán)交給 OLE內(nèi)部隱藏窗口 ? 針對(duì)以全局內(nèi)存作為存儲(chǔ)介質(zhì)的數(shù)據(jù)格式, OleSetClipboard使用 “ 延遲供應(yīng) ” 方式調(diào)用SetClipboardData放到剪貼板上 ? 清空剪貼板,可調(diào)用 OleSetClipboard(NULL) OLE剪貼板 (二 ) ? 客戶方調(diào)用 GetClipboardData只能訪問到以全局內(nèi)存作為存儲(chǔ)介質(zhì)的數(shù)據(jù)格式 ? 使用 OleGetClipboard函數(shù)可以訪問到源數(shù)據(jù)對(duì)象的所有格式 ? OleGetClipboard函數(shù)返回不同的數(shù)據(jù)對(duì)象 – (1)源數(shù)據(jù)對(duì)象仍在運(yùn)行,則直接返回 (有可能是代理對(duì)象 ) – (2)源程序調(diào)用了 OleFlushClipboard函數(shù), OLE創(chuàng)建一個(gè)缺省的數(shù)據(jù)對(duì)象,供客戶使用 – (3)剪貼板上的數(shù)據(jù)非數(shù)據(jù)對(duì)象,返回一個(gè)缺省數(shù)據(jù)對(duì)象,但數(shù)據(jù)格式受限制 MFC對(duì)剪貼板的支持示意圖 源程序COle D a ta S o u rc e對(duì)象 ID a ta O b je c t原始數(shù)據(jù)格式 1格式 2......調(diào)用 Ca c h e G lo b a lDa ta或 Ca c h e D a ta客戶程序COle D a ta O b je c t對(duì)象目標(biāo)數(shù)據(jù)m _ lp D a ta O b je c t剪貼板復(fù)制S e tCli p b o a rd粘帖A ttac h Clip b o a rd調(diào)用 G e tD a ta 或者G e t G lo b a lDa ta拖 放數(shù)據(jù)傳輸協(xié)議 O L E源程序數(shù)據(jù)對(duì)象IDa taO b jec t拖源對(duì)象I Dro p S o u rce源程序放目標(biāo)對(duì)象I Dro p T a r g e tD o Dra g Dro p Re g isterD ro p T a r g e t拖 放數(shù)據(jù)傳輸協(xié)議:源 ? 實(shí)現(xiàn)數(shù)據(jù)對(duì)象和 “ 拖源 ” 對(duì)象, “ 拖源 ” 對(duì)象實(shí)現(xiàn)了接口 IDropSource class IDropSource : public IUnknown { virtual HRESULT QueryContinueDrag( BOOL fEscapePressed, DWORD grfKeyState) = 0。 virtual HRESULT GiveFeedback( DWORD dwEffect) = 0。 }。 ? WM_LBUTTONDOWN消息控制函數(shù)中調(diào)用OLE函數(shù): DoDragDrop 拖 放數(shù)據(jù)傳輸協(xié)議:目標(biāo) ? 實(shí)現(xiàn) “ 放目標(biāo) ” 對(duì)象, “ 放目標(biāo) ” 對(duì)象實(shí)現(xiàn)了接口IDropTarget: class IDropTarget : public IUnknown { virtual HRESULT DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) = 0。 virtual HRESULT DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)。 virtual HRESULT DragLeave( void) = 0。 virtual HRESULT Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) = 0。 }。 ? 為了支持 “ 放 ” 特性,調(diào)用 OLE API函數(shù)RegisterDragDrop,把對(duì)象與窗口聯(lián)系起來 WINOLEAPI RegisterDragDrop(HWND hwnd, IDropTarget *pDropTarget)。 DoDragDrop函數(shù) ?原型 WINOLEAPI DoDragDrop(IDataObject *pDataObj, IDropSource *pDropSource, DWORD dwOKEffects, DWORD *pdwEffect)。 ? DoDragDrop函數(shù)內(nèi)部是一個(gè)循環(huán),它不斷檢查鼠標(biāo)和鍵盤的狀態(tài),以及詢問 “ 放 ”目標(biāo)窗口和 “ 源 ” 窗口,并作出反應(yīng) 支持剪貼板操作、拖 放操作的例子程序