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

2025年度未來銀行科技服務(wù)商TOP100
全世界各行各業(yè)聯(lián)合起來,internet一定要實(shí)現(xiàn)!

利用MFC實(shí)現(xiàn)對(duì)象拖放

2004-02-15 eNet&Ciweek

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  行拖放操作;如果選定了一個(gè)對(duì)象,則可以進(jìn)行拖放操作?! ?

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

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

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

  是:需要象上文中所說的,應(yīng)該指定使用的數(shù)據(jù)格式,并按指定格式提供對(duì)象的有關(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)用此對(duì)象的成員函數(shù)DoDragDrop(...),啟動(dòng)對(duì)象拖放操作。需要注意的是,函數(shù)DoDragDrop(...)并不立即返回,而是要等到鼠標(biāo)按鈕彈起之后。  

  3.2. 拖放對(duì)象的接收。缺省情況下,一般的窗口是不能接收拖放對(duì)象的;要使窗口可以接收拖放對(duì)象,需要在窗口類定義中加入成員對(duì)象COleDropTarget,并在生成窗口時(shí)調(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;
  }

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

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

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

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

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

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

  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;
  }
  }  

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

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

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

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

  例如:

  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

您對(duì)本文或本站有任何意見,請(qǐng)?jiān)谙路教峤?,謝謝!

投稿信箱:tougao@enet16.com