天天看點

仿酷狗音樂播放器開發日志二十七 用ole為窗體增加檔案拖動功能(附源碼)

轉載請說明原出處,謝謝~~

       中秋到了,出去玩了幾天。今天把仿酷狗程式做了收尾,已經開發完成了,下一篇部落格把完結的情況說一下。在這篇部落格裡說一下使用OLE為窗體增加檔案拖拽的功能。使用播放器,我更喜歡直接拖動音樂檔案添加到軟體裡,是以做這個功能很重要。做OLE拖拽之前學習了兩篇文章:

<a target="_blank" href="http://www.codeproject.com/Articles/840/How-to-Implement-Drag-and-Drop-Between-Your-Progra%E3%80%91">http://www.codeproject.com/Articles/840/How-to-Implement-Drag-and-Drop-Between-Your-Progra%E3%80%91</a>

<a target="_blank" href="http://blog.csdn.net/liu4584945/article/details/6205341">http://blog.csdn.net/liu4584945/article/details/6205341</a>

<a target="_blank" href="http://blog.csdn.net/leehong2005/article/details/8609478">http://blog.csdn.net/leehong2005/article/details/8609478</a>

      先來看一下原酷狗裡的檔案拖動功能:

仿酷狗音樂播放器開發日志二十七 用ole為窗體增加檔案拖動功能(附源碼)
仿酷狗音樂播放器開發日志二十七 用ole為窗體增加檔案拖動功能(附源碼)

         可以看到,我拖動音樂檔案到軟體裡,進去音樂清單的範圍内就顯示可複制的圖示,不在範圍則顯示不可拖拽的圖示。

         讓軟體支援檔案拖拽有兩種方法:OLE拖放和檔案管理器拖放。第一種方法通過處理窗體的WM_DROPFILES消息,窗體就可以收到拖放進來的檔案名。OLE拖放允許你拖放可同時被儲存在剪貼闆上的任何資料,并且更加細緻的控制拖放過程。第一個是比較簡單的也是我之前一直使用的方法,下面相關函數的介紹:

       本函數用來取得拖放的檔案名。其中,hDrop是一個指向含有被拖放的檔案名的結構體的句柄;iFiles是要查詢的檔案序号,因為一次可能同時拖動很多個檔案;lpszFiles是出口緩沖區指針,儲存iFiles指定序号的檔案的路徑名,cch指定該緩沖區的大小。有兩點值得注意,第一,如果我們在調用該函數的時候,指定iFile為0xFFFFFFFF,則DragQueryFile将忽略lpszFile和cch參數,傳回本次拖放操作的檔案數目;第二,如果指定lpszFile為NULL,則函數将傳回實際所需的緩沖區長度。

         本函數用來擷取,當拖放操作正在進行時,滑鼠指針的位置。第二個參數lppt是一個指向POINT結構體的指針,用來儲存檔案放下時,滑鼠指針的位置。視窗可以調用該函數以查詢檔案是否落在自己的視窗矩形中。

         當拖放操作處理完畢後需調用該函數釋放系統配置設定來傳輸檔案名的記憶體。

         使用這個方法時,在窗體初始化完成後調用函數調用DragAcceptFiles(m_hWnd,TRUE),讓窗體可以接收WM_DROPFILES消息。然後在Duilib的窗體類中重寫HandleCustomMessage函數,去處理WM_DROPFILES消息,代碼如下:

        這樣就處理完了,處理WM_DROPFILES消息的方法簡單,但是效果比較差,無法動态擷取檔案在窗體上的坐标,樣式也難看一些,拖動時的圖示僅僅是一個加号而不是原檔案的圖示樣式。适用于做一些要求簡單的檔案拖動效果。

       接下來說一下OLE檔案拖動:

       OLE檔案拖動屬于Windows的外殼擴充程式設計。我在網上查了一些資料,都是關于MFC下OLE拖放的。最後找到了部落格開頭起到的檔案是介紹win32拖放的。我參考了兩篇文章的代碼,最終封裝為一個DropTargetEx類。但是這樣做了之後的确是可以達到拖放效果,但是發現拖放時的圖示還僅僅是一個加号,而不像我部落格開頭貼的原酷狗的圖檔,是對應的檔案的圖示。查閱資料後了解需要使用IDropTargetHelper接口,讓系統輔助來處理消息,就可以達到漂亮的拖拽效果,具體代碼我都寫在類裡面了。大家可以根據自己的需求來修改。

       這裡先看一下最終的效果:

仿酷狗音樂播放器開發日志二十七 用ole為窗體增加檔案拖動功能(附源碼)

       這個類可以用于win32工程和duilib工程裡,使用方法為,在duilib的窗體類中聲明一個拖放類的對象:

        然後在Notify函數的消息裡寫入下面的代碼來注冊拖放窗體:

          這裡需要寫一個回調函數,來通知主窗體檔案被拖動,回調函數的圓形如下,其中CFrameWnd為你的窗體類:

          回調函數的具體寫法和WM_DROPFILES消息處理的方法類似,需要把回調函數聲明為窗體類的友元。這樣就增加了拖動功能。CDropFileEx類的代碼如下:

總結:

        目前隻是根據我的需求編寫 CDropTargetEx類,實際上還可以擴充來完成更多功能。

    Redrain   2014.9.9