COleDropTarget類來支援任意視窗拖放

2021-04-13 02:54:43 字數 2676 閱讀 3226

一、拖放原理及mfc類庫對拖放的支援

拖放(drag and drop)是ole的一部分,是指對某一指定的物件,利用滑鼠拖動的方法,在不同應用的視窗之間、同一應用的不同視窗之間或同一應用的同一視窗內進行移動、複製(貼上)等操作的技術。

mfc為實現物件拖放提供了如下類:coledatasource、coledropsource、coledroptarget、coledataobject。對於上述幾個類的用法,讀者可參考有關資料。因拖放操作中的啟動拖放部分,實現較模式化,很多文獻都有詳細的實現,本文在此不再贅述。這裡著重說明mfc拖放操作中接收部分的實現原理,以使讀者了解為何要擴充套件mfc拖放類的功能。

mfc通過提供coledroptarget和cview類來支援拖放操作的接收。在cview及其繼承類中建立coledroptarget類物件,並在檢視視窗初始化時,呼叫其成員函式register(),以此在系統中註冊該檢視視窗為拖放接收視窗。當進行拖放操作的滑鼠指標處於檢視視窗範圍內時,coledroptarge類的ondragenter、ondragover、ondropex、ondrop等成員函式被依次呼叫,這些函式預設呼叫與其相對應的cview類成員函式ondragenter、ondragover、ondropex、ondrop等,在這些cview類成員函式中,使用者可對拖動的過程及結果進行控制。但mfc這種內在的對拖放的實現是很不夠的,乙個使用者介面友好的應用程式,很多時候要求不僅檢視視窗支援拖放,而且對話方塊以及編輯框等控制視窗也需要拖放的支援。雖然現在已經有一些拖放目標類的擴充套件類了,但通常都是需要按照cview類對拖放的實現模式來實現這些視窗類,再在coledroptarge繼承類的響應拖放函式中利用rtti(run-time type information)來呼叫這些特定的視窗類拖放響應函式。而利用rtti機制不可避免地會使拖放類只支援特定的視窗類,如果要增加新的可支援拖放的視窗類,則必須改寫已實現的coledroptarge繼承類,這種情況是我們所不願看到的。如果直接在coledroptarge繼承類中處理拖放呢?顯然,只會造就乙個針對性更強的類。針對這種情況,需要運用其它方式來支援無型別要求的視窗類拖放操作。

二、拖放擴充套件類執行原理

我們知道,使用訊息是可以傳遞資訊的。對於複雜的結構,可以通過在訊息引數中傳遞結構的指標來傳遞結構資訊。因此,在coledroptarge擴充套件類響應拖放成員函式中,將拖放資訊打包,存入拖放資訊類中,向註冊了拖放功能的控制視窗傳送使用者自定義訊息,並傳遞拖放資訊類位址。在視窗類中,對映該自定義訊息到訊息響應函式中,在該函式中,將訊息引數轉換回拖放資訊類指標,以此來獲得拖放資訊,進行相應操作後,返回對拖放操作的控制資訊。這樣,經過將mfc對拖放操作的函式呼叫轉化為型別無關的對視窗的訊息傳送,擴充套件的拖放目標類便具有了與拖放視窗類無關的特性,而且這種訊息機制符合程式編寫習慣。

三、例項實現

public:

virtual bool register();

// generated message map functions

protected:

coledroptargetex m_dropex;virtual bool ondrop(wparam pdropinfoclass, lparam lparm);

virtual dropeffect ondropex(wparam pdropinfoclass, lparam lparm);

virtual dropeffect ondragover(wparam pdropinfoclass,lparam lparm);在實現檔案中新增訊息對映如下:

begin_message_map(cdropedit, cedit)

//}afx_msg_map

on_message(dropm_dragover,ondragover)

on_message(dropm_dropex,ondropex)

on_message(dropm_drop,ondrop)

end_message_map()

在實現檔案中訊息響應函式定義如下:
/

// cdropedit message handlers

bool cdropedit::register()

dropeffect cdropedit::ondragover(wparam pdropinfoclass, lparam lparm)

dropeffect cdropedit::ondropex(wparam pdropinfoclass, lparam lparm)

bool cdropedit::ondrop(wparam pdropinfoclass, lparam lparm)

globalunlock( hmem );//unlock source

return true;

}else

return false;

}

現在,乙個支援拖放的編輯框就做好了。那麼把它放到對話方塊中測試一下。 新增乙個編輯控制m_dropedit到對話方塊模板中,使用classwizard宣告該編輯控制為cdropedit型別。在對話方塊類的oninitdialog()函式中註冊該編輯物件為拖放目標視窗。
bool cdropexdemodlg::oninitdialog()

最後,別忘了初始化ole。在應用程式類初始化函式中新增ole初始化**。

現在,編譯並執行程式。從vc ++ 6.0編輯視窗中選擇一詞,用滑鼠拖動其到編輯控制上並釋放滑鼠左鍵,編輯控制中內容變為拖動來的文字。至此,測試成功完成。  

類值類與類指標類

類值類 行為像值的 class a a const a a ps new string a.ps i a.i 每個類物件有自己的乙份資源拷貝 a operator const a rhs a private string ps int i 一種優化拷貝賦值運算子的方法 copy and swap c...

巢狀類 匿名類 密封類

巢狀類 在c 中可以將乙個類定義在另乙個類的內部,外部的叫外部類,內部的巢狀類 namespace 27 set public void hello 巢狀類 public class web webname,weburl class program 匿名類 如果某個類的例項物件只會使用到一次,可以使...

點類,圓類,圓柱類

print?copyright c 2012,煙台大學計算機學院 all rights reserved.檔名稱 text.cpp 作 者 胡穎 完成日期 2013年5月20日 版 本 號 v1.0 輸入描述 無 問題描述 1 先建立乙個point 點 類,包含資料成員x,y 座標點 2 以poin...