如何?菜單的拖拽

來源:互聯網
上載者:User
 

為了讓菜單支援拖拽,需要做:1、為菜單添加 MNS_DRAGDROP風格MENUINFO Info ;Info.cbSize = sizeof(MENUINFO) ;Info.fMask = MIM_STYLE ;Info.dwStyle= MNS_DRAGDROP ;SetMenuInfo( hMenu , &Info ) ;  註:當 WINVER>=0x500 ,才能找到 NMS_DRAGDROP 和下面相關常數的定義 2、處理 WM_MENUDRAG訊息其中, wParam 指定被拖拽功能表項目的位置,lParam為菜單的控制代碼。傳回值如果是MND_CONTINUE,則菜單仍然啟用,如果滑鼠被釋放,它將被忽略!
就是說不實現拖拽功能,使用預設的處理方式!如果是MND_ENDMENU,則菜單將關閉。要實現拖拽,要返回該值! 重點在於,在WM_MENUDRAG內要啟動拖操作,這裡我使用了OLE拖-放傳輸協議,即調用 DoDragDrop : -          分配記憶體,大小是256位元組。空間的大小要根據實際情況來定!
HGLOBAL hGlobal = ::GlobalAlloc( GMEM_SHARE | GMEM_ZEROINIT , 256 ) ;

-          將需的資料儲存到分配的記憶體中,這裡我將儲存菜單的文本
LPVOID pvoid = ::GlobalLock( hGlobal ) ;LPTSTR lpstr = (LPTSTR)pvoid ;::GetMenuString( hMenu , pos , lpstr , MAX_PATH - 1 , MF_BYPOSITION ) ;::GlobalUnlock( hGlobal ) ;
註:hMenu 來自 lParam , pos 來自 wParam  -          準備IDataObject、IDropSource對象
STGMEDIUM stgMedium ;memset( &stgMedium , 0 , sizeof(STGMEDIUM) ) ;stgMedium.tymed = TYMED_HGLOBAL ;stgMedium.hGlobal = hGlobal ;stgMedium.pUnkForRelease = NULL ; CMenuDataObject *pDataObj = new CMenuDataObject (&stgMedium,m_uClipboardFormat);              CMenuDropSource *pDropSource = new CMenuDropSource ;              pDropSource->AddRef() ;pDataObj->AddRef() ;               註: CMenuDataObject 派生自 IDataObject ; CMenuDropSource 派生自 IDropSource m_uClipboardFormat 是自訂的資料格式,為了能區分出自已的資料。 m_uClipboardFormat= RegisterClipboardFormat( “MyFormat” ) ; 這裡比較麻煩的是 CMenuDataObject CmenuDropSource 實現,其不 在本文的討論範圍,請參考相關資料, MSDN 的例子等。 http://www.cppblog.com/windcsn/category/995.html drag&drop 也要比較
詳細的描述。
  
  -          調用DoDragDrop 啟動拖操作         DWORD dwEffect = 0 ;HRESULT ret = ::DoDragDrop( pDataObj , pDropSource , DROPEFFECT_MOVE , &dwEffect );                     pDropSource->Release() ;pDataObj->Release() ;                 - 檢查傳回值,釋放資源                     if( ret == DROPEFFECT_MOVE ){::GlobalFree( hGlobal ) ;return MND_ENDMENU ;}   註:如果你用 MFC ,這一切將變得很簡單 ,IDataObject IDataSource 都由 MFC 實現: COleDataSource *pSource = new COleDataSource ; pSource->CacheData( (CLIPFORMAT)m_uClipboardFormat , &stgMedium ) ;     DROPEFFECT ret = DROPEFFECT_NONE ; ret = pSource->DoDragDrop( DROPEFFECT_MOVE ) ;   3、實現接收功能為了接收資料對象即支援“放”特性,它必須提供一個“放目標”對象。“放目標”
對象實現了介面IDropTarget,並且目標程式還必須把“放目標”對象與一個視窗聯絡在一起。因此,應用程式為了支援“放”特性,要調用OLE提供的API函數:RegisterDragDrop,當程式不再支援“放”特性,則可以調用RevokeDrapDrop函數取消。 OnCreate{… 視窗初始化RegisterDragDrop( m_hWnd , &m_DropTarget ) ;
} class CMyDropTarget : public IDropTarget ;CMyDropTarget m_DropTarget ; 因此,工作重點,就是實現 IDropTarget 。如果用MFC,可以讓CMyDropTarget派生自COleDropTarget 。CMyDropTarget實現不在本文討論範圍,請參考相關資料。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.