久久―日本道色综合久久,亚洲欧美精品在线,狼狼色丁香久久婷婷综合五月,香蕉人人超,日本网站黄,国产在线观看不卡免费高清,无遮挡的毛片免费

2023信創(chuàng)獨角獸企業(yè)100強
全世界各行各業(yè)聯(lián)合起來,internet一定要實現(xiàn)!

利用MFC實現(xiàn)對象拖放

2004-02-15 eNet&Ciweek

  對象拖放是指對某一指定的對象,利用鼠標(biāo)拖動的方法,在不同應(yīng)用的窗口之間、同一應(yīng)用的不同窗口之間或同一應(yīng)用的同一窗口內(nèi)進行移動、復(fù)制(粘貼)等操作的技術(shù)。
  利用對象拖放,可以為用戶提供方便、直觀的操作界面。
  實現(xiàn)對象拖放技術(shù),需要了解、使用MFC的CView、COleDataSource和COleDropTarget等類,并利用這些類協(xié)同工作。
  本文討論了對象拖放技術(shù),并研究了如何利用MFC實現(xiàn)該技術(shù)。
  利用MFC實現(xiàn)對象拖放,編程比較容易,代碼可讀性好。
  修改稿
  利用MFC實現(xiàn)對象拖放
  本文討論了對象拖放技術(shù),并研究了如何利用MFC實現(xiàn)該技術(shù);利用MFC實現(xiàn)對象拖放,編程比較容
  易,代碼可讀性好。

  1.對象拖放概念
  對象拖放是指對某一指定的對象,利用鼠標(biāo)拖動的方法,在不同應(yīng)用的窗口之間、同一應(yīng)用的不同窗口之間或同一應(yīng)用的同一窗口內(nèi)進行移動、復(fù)制(粘貼)等操作的技術(shù)?! ?

  對象拖放是在操作系統(tǒng)的幫助下完成的。 要開始一次拖動, 首先需要指定或生成被拖動的對象,然后指定整個拖放操作過程所使用的數(shù)據(jù)格式,并按指定的數(shù)據(jù)格式提供數(shù)據(jù),最后啟動對象拖放操作;當(dāng)對象在某一窗口內(nèi)落下時,拖放過程結(jié)束,接收拖放對象的窗口按指定的數(shù)據(jù)格式提取有關(guān)數(shù)據(jù),并根據(jù)提取的數(shù)據(jù)生成對象。 

  2.MFC中用于對象拖放的類
  MFC(Microsoft Foundation ClassLibrary)為實現(xiàn)對象拖放提供了如下三個類。為便于后邊的討論我們先來熟悉一下這些類?!?

  2.1.COleDataSource。用于啟動一次拖放操作,并向系統(tǒng)提供拖放對象的數(shù)據(jù)。類中的成員函數(shù)有如下三種:  

  a.設(shè)定提供數(shù)據(jù)的方式和使用的數(shù)據(jù)格式。提供數(shù)據(jù)的方式有兩種,一種是即時方式,另一種是延遲方式;即時方式需要在拖動開始之前提供數(shù)據(jù);延遲方式不需要立即提供數(shù)據(jù),當(dāng)系
  統(tǒng)請求有關(guān)數(shù)據(jù)時,由OnRenderData()等虛函數(shù)提供所需的數(shù)據(jù)?! ?

  可以用CacheGlobalData()等函數(shù)指定使用即時方式提供數(shù)據(jù),也可以用DelayRenderData
  ()等函數(shù)指定使用延時方式提供數(shù)據(jù)。  

  b.響應(yīng)請求,提供數(shù)據(jù)。應(yīng)當(dāng)重載OnRenderFileData()或其他相應(yīng)的虛函數(shù),以提供有關(guān)數(shù)據(jù)(后邊將詳細(xì)討論)?!?

  c.實施拖放操作。調(diào)用函數(shù)DoDragDrop(),開始實施拖放操作。
  2.2.OleDataTarget。用于準(zhǔn)備接收拖放對象的目標(biāo)窗口;一個窗口要想能夠接收拖放對象,必須包含一個COleDataTarget對象,并注冊該對象。類中主要成員函數(shù):

  a.注冊。函數(shù)Register()注冊該對象,以便使窗口能夠接收拖放對象。
  b.響應(yīng)拖放過程中的動作(虛成員函數(shù)) 當(dāng)鼠標(biāo)首次進入窗口時系統(tǒng)將調(diào)用OnDragEnter(),當(dāng)鼠標(biāo)移出窗口時系統(tǒng)將調(diào)用OnDragLeave(), 當(dāng)鼠標(biāo)在窗口內(nèi)移動,系統(tǒng)將重復(fù)調(diào)用調(diào)用OnDragOver(),當(dāng)對象在窗口內(nèi)落下調(diào)用OnDrop()。  

  2.3.OleDataObject.用于接收拖放對象,類中主要成員函數(shù)有兩種:  

  a.確定可以使用的數(shù)據(jù)格式。IsDataAvailable()等函數(shù)確定指定數(shù)據(jù)格式是否可用;  

  b.獲取數(shù)據(jù)。GetData()、GetFileData()等函數(shù)用于按指定數(shù)據(jù)格式獲得數(shù)據(jù)?! ?

  3.利用MFC實現(xiàn)對象拖放  

  要實現(xiàn)一次對象拖放,需要做三方面的工作:對象所在的窗口準(zhǔn)備拖放對象并啟拖動操作,接受對象的窗口響應(yīng)有關(guān)拖放消息并接受落下的對象,以及拖放完成時的后期處理。以下分別予以介紹。  

  3.1. 拖動操作的啟動。拖放操作一般是從單擊鼠標(biāo)左鍵開始。在消息WM_LBUTTONDOWN的響應(yīng)

  函數(shù)OnLButtonDown(...)中,首先要判定是否選定了某一對象,如果未選定或選定多個,則不能進

  行拖放操作;如果選定了一個對象,則可以進行拖放操作。  

  要啟動一次拖放操作,需要先準(zhǔn)備一個COleDataSource對象。注意到類COleClientIten和類

  COleServerItem都是從類COleDataSource上派生的,如果選定的是COleClientItem對象或者是

  COleServerItem對象,則可以直接使用;否則,需要生成一個COleDataSource對象,值得注意的

  是:需要象上文中所說的,應(yīng)該指定使用的數(shù)據(jù)格式,并按指定格式提供對象的有關(guān)數(shù)據(jù)。
  

  下面給出準(zhǔn)備數(shù)據(jù)源的例子:

  class myDataSource: public COleDataSource
  {
  public:
  COLORREF color;
  CString str;
  protected:
  virtual BOOL OnRenderFileData(LPFORMATETC,CFile*);
  //......
  };  

  BOOL myDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc,CFile* pFile)
  {
  if(lpFormatEtc->cfFormat==CF_TEXT)
  {
  pFile.Write("Test DragDrop",13); //Magic String
  pFile.Write(&color,sizeof(COLORREF));
  int len= str.GetLength();
  pFile.Write(len,sizeof(int));
  pFile.Write(str,len);
  return TRUE;
  }  

  COleDataSource::OnRenderFileData(lpFormatEtc,pFile);
  return FALSE;
  }  

  有了以上數(shù)據(jù)源之后,就可以在消息WM_LBUTTON的響應(yīng)函數(shù)OnLButtonDown()中,按如下方式,指定使用的數(shù)據(jù)格式:  

  myDataSource* pItemDragDrop=new myDataSource;
  pItemDragDrop->str="This string will dragdrop to another place";
  pItemDragDrop->DelayRenderFileData(CF_TEXT,NULL);  

  指定好使用的數(shù)據(jù)格式之后,調(diào)用此對象的成員函數(shù)DoDragDrop(...),啟動對象拖放操作。需要注意的是,函數(shù)DoDragDrop(...)并不立即返回,而是要等到鼠標(biāo)按鈕彈起之后?! ?

  3.2. 拖放對象的接收。缺省情況下,一般的窗口是不能接收拖放對象的;要使窗口可以接收拖放對象,需要在窗口類定義中加入成員對象COleDropTarget,并在生成窗口時調(diào)用函數(shù)COleDataTarget::Register()。例如:

  Class myView : public CScrollView
  {
  private:
  COleDropTarget oleTarget;
  protected:
  virtual int OnCreate(LPCREATESTRUCT);
  //......
  }  

  int myView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
  //......
  dropTarget.Register(this);
  return 0;
  }

  為實現(xiàn)拖放對象的接收,還應(yīng)重載CView或COleDropTarget的虛函數(shù):COnDragMove()、OnDragEnter()和OnDrop()等。函數(shù)OnDragEnter()、OnDragMove()應(yīng)根據(jù)鼠標(biāo)在窗口中的位置,返回以下數(shù)值:

  DROPEFFECT_MOVE---表明可以把對象復(fù)制到現(xiàn)在的窗口、現(xiàn)在的位置;
  DROPEFFECT_COPY---表明可以把對象從原來的窗口、原來的位置移到現(xiàn)在的窗口、現(xiàn)在的位置;
  DROPEFFECT_NONE---表明不能在該窗口的該位置放下。
  下例只允許移動對象,而不允許復(fù)制對象:
  DROPEFFECT myView::OnDragEnter(......)
  {
  return DROPEFFECT_MOVE;
  }  

  DROPEFFECT myView::OnDragOver(......)
  {
  return DROPEFFECT_MOVE;
  }  

  函數(shù)OnDrop()應(yīng)處理拖動對象放下后的工作。該函數(shù)的參數(shù)pDataObjec指向一個COleDataObject對象,利用指針,可以獲取有關(guān)數(shù)據(jù)。該函數(shù)的一般實現(xiàn)是:

  a.檢查對象的數(shù)據(jù)格式: 利用函數(shù)COleDataObject::IsDataAvailable();
  b.按指定的格式獲取數(shù)據(jù):利用COleDataObject::GetFileData()等函數(shù);
  c.建立對象(可能與原對象相同,也可能不建立對象僅使用對象中的數(shù)據(jù)):利用以上步驟

  得到的數(shù)據(jù)建立對象。例如:

  char magic_string[13];
  COLORREF color;
  CString str;
  int len;
  myDataSource* pMyData;  

  if(IsDataAvailable(CF_TEXT))
  {
  CFile file=GetFileData(CF_TEXT);   

  file.Read(magic_string,13);
  if(strncmp(magic_string,"Test DragDrop",13)==0)
  {
  file.Read(&color,sizeof(COLORREF));
  file.Read(len,sizeof(int));
  file.Read(str,len);   

  CClientDC dc(this);
  dc.SetTextColor(color);
  dc.SetBkMode(TRANSPARENT);
  dc.TextOut(100,50,str,len);   

  pMyData=new myDataSource;
  pMyData->color=color;
  pMyData->str=str;
  }
  }  

  對于COleClientItem或COleServerItem對象,可以按以下方法很容易地重建對象:

  COleClient* pItem=GetDocument()->CreateNewItem();
  pItem->CreateFrom(pDataObject);  

  3.3. 拖放操作的結(jié)束函數(shù)DoDragDrop()返回時,拖放過程結(jié)束。函數(shù)DoDragDrop()的返回值,表明了對象的拖放結(jié)果。

  DROPEFFECT_MOVE:對象被放到他處,需刪除原對象
  DROPEFFECT_COPY:對象被復(fù)制到他處,不刪除原對象
  DROPEFFECT_NONE:未能實現(xiàn)拖放,無需刪除原對象 

  例如:

  int DragEffect=pItemTracking->DoDragDrop(......);
  switch(DragEffect)
  {
  case DROPEFFECT_MOVE:
  delete pItemTracking;
  GetDocument()->UpdateAllItems(NULL);
  GetDocument()->UpdateAllViews(NULL);
  break;
  case DROPEFFECT_COPY:
  case DROPEFFECT_NONE:
  default:
  break;
  }

相關(guān)頻道: eNews

您對本文或本站有任何意見,請在下方提交,謝謝!

投稿信箱:tougao@enet16.com