Development log of the imitation codoy music player adds the file drag function (with source code) for the form with ole, codoy ole

Source: Internet
Author: User

Development log of the imitation codoy music player adds the file drag function (with source code) for the form with ole, codoy ole

Reprinted, please describe the original source. Thank you ~~

The Mid-Autumn Festival is approaching. I went out for a few days. Today, we have completed the development of the cool dog-like program. The next blog will talk about the situation. In this blog, we will introduce how to use OLE to add the file drag function for the form. When using a player, I prefer to drag music files directly to the software, so this function is very important. I learned two articles before performing OLE drag:

Http://www.codeproject.com/Articles/840/How-to-Implement-Drag-and-Drop-Between-Your-Progra%E3%80%91

Http://blog.csdn.net/liu4584945/article/details/6205341

Let's take a look at the file drag function in the original cool dog:


As you can see, I drag the music file to the software and display the replicable icon within the range of the music list. If it is not in the range, it is not possible to drag the icon.

There are two ways for the software to support drag and drop of Files: OLE drag and drop and file manager drag and drop. The first method is to process the WM_DROPFILES message of the form, and then the form receives the drag-and-drop file name. OLE drag-and-drop allows you to drag and drop any data that can be stored on the clipboard at the same time, and to control the drag-and-drop process in greater detail. The first one is relatively simple and the method I have been using. The following describes the related functions:

        UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch)

This function is used to obtain the drag-and-drop file name. Hddrop is a handle pointing to a struct containing the drag-and-drop file name; iFiles is the serial number of the file to be queried, because many files may be dragged at a time; lpszFiles is the egress buffer pointer, saves the path name of the file with the specified serial number iFiles, and cch specifies the size of the buffer. There are two points worth noting. First, if we specify iFile as 0 xFFFFFFFF when calling this function, DragQueryFile ignores the lpszFile and cch parameters and returns the number of files in this drag-and-drop operation; second, if the specified lpszFile is NULL, the function returns the actual buffer length required.

         BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt);


This function is used to obtain the cursor position when the drag-and-drop operation is in progress. The second parameter, lppt, is a pointer to the POINT struct, used to save the cursor position when the file is put down. The window can call this function to check whether the file falls into its own window rectangle.

         void DragFinish(HDROP hDrop);

After the drag-and-drop operation is complete, you need to call this function to release the memory allocated by the system to transfer file names.

When this method is used, call the function after the form Initialization is complete to call DragAcceptFiles (m_hWnd, TRUE) so that the form can receive WM_DROPFILES messages. Then, rewrite the HandleCustomMessage function in the Form class of Duilib to process the WM_DROPFILES message. The Code is as follows:

Else if (uMsg = WM_DROPFILES) {HDROP hDrop = (HDROP) wParam; TCHAR szFilePathName [_ MAX_PATH] = {0}; UINT nNumOfFiles = DragQueryFile (hDrop, 0 xFFFFFFFF, NULL, 0); // obtain the number of files for (UINT nIndex = 0; nIndex <nNumOfFiles; ++ nIndex) {DragQueryFile (hDrop, nIndex, szFilePathName, _ MAX_PATH ); // get the file name and start processing} DragFinish (hDrop );}


In this way, the WM_DROPFILES message processing method is simple, but the effect is poor. The coordinates of the file on the form cannot be dynamically obtained, and the style is ugly, when dragging, the icon is only a plus sign rather than the icon style of the original file. It is applicable to some simple file drag effects.


Next, let's move the OLE file:

OLE file dragging belongs to Windows Shell extension programming. I checked some information on the Internet about OLE drag-and-drop in MFC. Finally, the file starting with the blog is described as win32 drag-and-drop. I have referenced the code in two articles and finally encapsulated it into a DropTargetEx class. However, after doing so, the drag-and-drop effect can be achieved, but it is found that the icon during the drag-and-drop operation is only a plus sign, unlike the pictures of the original cool dog posted on my blog, is the icon of the corresponding file. After reading the information, you need to use the IDropTargetHelper interface to help the system process the message, so that you can achieve the beautiful drag-and-drop effect. The specific code is written in the class. You can modify it as needed.

Here, let's take a look at the final effect:


This class can be used in win32 and duilib projects. It is used to declare an object of the drag and drop class in the Form class of duilib:

CDropTargetExm_DropTarget; // enables drag-and-drop operations on the form

Then write the following code in the message of the Notify function to register the drag-and-drop form:

<span style="font-size:14px;">m_DropTarget.DragDropRegister(m_hWnd);m_DropTarget.SetHDropCallBack(OnDropFiles);</span>

Write a callback function to notify the main form file to be dragged. The circle of the callback function is as follows, where CFrameWnd is your form class:

      typedef void (*DROPCALLBACK)(CFrameWnd*, HDROP);
The method for writing callback functions is similar to that for processing WM_DROPFILES messages. You need to declare the callback function as a friend of the Form class. This adds the drag function. The code for the CDropFileEx class is as follows:

# Ifndef DROP_TARGET_EX_H # define DROP_TARGET_EX_H # include "OleIdl. h "# include" ShObjIdl. h "typedef struct _ DRAGDATA {int cfFormat; STGMEDIUM stgMedium;} DRAGDATA, * LPDRAGDATA; typedef void (* DROPCALLBACK) (CFrameWnd *, HDROP); class metadata: public IDropTarget {public: CDropTargetEx (CFrameWnd * pMainWnd); virtual ~ Revoke (); BOOL DragDropRegister (HWND hWnd, DWORD AcceptKeyState = MK_LBUTTON); hresult stdmethodcalltype QueryInterface (REFIID iid, void ** ppvObject); ULONG extends AddRef (void ); ULONG implements Release (void); hresult stdmethodcalltype DragOver (DWORD grfKeyState, POINTL pt, DWORD * pdwEffect); HRESULT implements DragEnter (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect); hresult stdmethodcalltype DragLeave (void); hresult stdmethodcalltype Drop (IDataObject * pDataObj, DWORD grfKeyState, POINTL pt, DWORD _ RPC_FAR * pdwEffect ); BOOL GetDragData (IDataObject * pDataObject, FORMATETC cFmt); void SetHDropCallBack (DROPCALLBACK pFun); void ProcessDrop (LPDRAGDATA pDropData/* HDROP */); // function for enumerating data formats, I have not used it here, but it may be used in the future. Currently, the function only enumerates the HDROP BOOL EnumDragData (IDataObject * pDataObject); private: CFrameWnd * m_pMainWnd; CDuiRectm_rcList; boolm_bUseDnDHelper; IDropTargetHelper * m_piDropHelper; DROPCALLBACKm_pDropCallBack; vector <LPDRAGDATA> m_Array ;}; # endif // DROP_TARGET_EX_H

# Include "duilib. h "CDropTargetEx: CDropTargetEx (CFrameWnd * pMainWnd): m_pMainWnd (pMainWnd), tb_RefCount (0), round (0), m_AcceptKeyState (0), round (NULL ), m_bUseDnDHelper (false), m_pDropCallBack (NULL) {// Create an instance of the shell DnD helper object. if (SUCCEEDED (CoCreateInstance (CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (void **) & m_piDropHelper) {m_bU SeDnDHelper = true ;}} CDropTargetEx ::~ CDropTargetEx () {if (NULL! = M_piDropHelper) m_piDropHelper-> Release ();} BOOL CDropTargetEx: DragDropRegister (HWND hWnd, DWORD AcceptKeyState) {if (! IsWindow (hWnd) return false; HRESULT s =: RegisterDragDrop (hWnd, this); if (SUCCEEDED (s) {m_hTargetWnd = hWnd; m_AcceptKeyState = AcceptKeyState; if (m_pMainWnd-> GetLeftListPos (m_rcList) return true; return false;} else {return false ;}} hresult stdmethodcalltype CDropTargetEx: QueryInterface (REFIID iid, void ** ppvObject) {* ppvObject = NULL; if (iid = IID_IDropTarget) * ppvObject = static_cast <IDropTarge T *> (this); if (* ppvObject! = NULL) AddRef (); return * ppvObject = NULL? E_NOINTERFACE: S_ OK;} ULONG STDMETHODCALLTYPE direction: AddRef (void) {InterlockedIncrement (& tb_RefCount); return tb_RefCount;} ULONG STDMETHODCALLTYPE direction: Release (void) {ULONG ulRefCount = InterlockedDecrement (& tb_RefCount); return ulRefCount;} HRESULT completion failed: DragOver (DWORD grfKeyState, POINTL pt, DWORD * pdwEffect) {ScreenToClient) & pt); if (GrfKeyState! = M_AcceptKeyState | pt. x <m_rcList.left | pt. x> m_rcList.right | pt. y <m_rcList.top | pt. y> latency) {* pdwEffect = DROPEFFECT_NONE;} else {* pdwEffect = DROPEFFECT_COPY;} if (m_bUseDnDHelper) {latency-> DragOver (LPPOINT) & pt, * pdwEffect );} return S_ OK;} HRESULT STDMETHODCALLTYPE CDropTargetEx: DragEnter (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect) {if (GrfKeyState! = M_AcceptKeyState) {* pdwEffect = DROPEFFECT_NONE; return S_ OK;} // I only care about the CE_HDROP type here. If necessary, call the EnumDragData function to enumerate all types of FORMATETC cFmt = {(CLIPFORMAT) CF_HDROP, NULL, DVASPECT_CONTENT,-1, TYMED_HGLOBAL}; GetDragData (pDataObject, cFmt); * pdwEffect = DROPEFFECT_COPY; if (plaintext) {plaintext-> DragEnter (m_hTargetWnd, pDataObject, (LPPOINT) & pt, * pdwEffect);} return S_ OK;} HRESULT STDMETHODCALLTYPE CDropTargetEx: DragLeave (void) {int temp = m_Array.size (); for (UINT I = 0; I <m_Array.size (); I ++) {LPDRAGDATA pData = m_Array [I];: ReleaseStgMedium (& pData-> stgMedium); delete pData; m_Array.clear ();} if (m_bUseDnDHelper) {success-> DragLeave ();} return S_ OK;} HRESULT STDMETHODCALLTYPE CDropTargetEx: Drop (IDataObject * pDataObj, DWORD grfKeyState, POINTL pt, DWORD _ RPC_FAR * pdwEffect) {int temp = m_Arr Ay. size (); for (UINT I = 0; I <m_Array.size (); I ++) {LPDRAGDATA pData = m_Array [I]; // I only obtain HDROP data here, So I directly start to process ProcessDrop (pData);: ReleaseStgMedium (& pData-> stgMedium); delete pData; m_Array.clear ();} if (m_bUseDnDHelper) {m_piDropHelper-> Drop (pDataObj, (LPPOINT) & pt, * pdwEffect);} return S_ OK;} BOOL CDropTargetEx: EnumDragData (IDataObject * pDataObject) {IEnumFORMATETC * pEnumFmt = NULL; // if the result is obtained successfully, you can use IE The Next method of the numFORMATETC interface to enumerate all data formats: HRESULT ret = pDataObject-> EnumFormatEtc (DATADIR_GET, & pEnumFmt); pEnumFmt-> Reset (); HRESULT Ret = S_ OK; FORMATETC cFmt = {0}; ULONG Fetched = 0; while (Ret! = S_ OK) {Ret = pEnumFmt-> Next (1, & cFmt, & Fetched); if (SUCCEEDED (ret) {if (cFmt. cfFormat = CF_HDROP) {if (GetDragData (pDataObject, cFmt) return TRUE ;}} else {return FALSE ;}} return TRUE ;} BOOL CDropTargetEx :: getDragData (IDataObject * pDataObject, FORMATETC cFmt) {HRESULT ret = S_ OK; STGMEDIUM stgMedium; ret = pDataObject-> GetData (& cFmt, & stgMedium); if (FAILED (ret )) return FALSE; if (stgMedium. pUnkForRelease! = NULL) return FALSE; switch (stgMedium. tymed) {// you can expand this code and use the EnumDragData function to save more types of data. case TYMED_HGLOBAL: {LPDRAGDATA pData = new DRAGDATA; pData-> cfFormat = cFmt. cfFormat; memcpy (& pData-> stgMedium, & stgMedium, sizeof (STGMEDIUM); m_Array.push_back (pData); return true; break;} default: // type not supported, so return error {: ReleaseStgMedium (& stgMedium) ;}break;} return false;} void CDropTargetEx: SetHDropCallBac K (DROPCALLBACK pFun) {if (pFun! = NULL) {m_pDropCallBack = pFun ;}} void CDropTargetEx: ProcessDrop (LPDRAGDATA pDropData/* HDROP hDrop */) {switch (pDropData-> cfFormat) {case CF_TEXT: {// m_pTextCallBack (HDROP) pDropData-> stgMedium. hGlobal); break;} case CF_HDROP: {m_pDropCallBack (m_pMainWnd, (HDROP) pDropData-> stgMedium. hGlobal); break;} default: break ;}}

Summary:

For the CDropTargetEx class, click the open link.

Currently, the CDropTargetEx class is compiled based on my needs. In fact, it can be expanded to complete more functions.


Redrain 2014.9.9


How to add the cool dog music player to the QQ space log

I wouldn't have said anything about the upstairs, but cool has a tutorial. The landlord can check it and understand it. How can I find the tutorial? First, upload a song to your music hard disk, then open your personal center, and click my music file in my music hard disk ], click the advanced settings of the song you uploaded. Then, [How do I post a song to a Blog or BBS?] Click "How to paste" to show you how to paste it. If you still cannot understand it, use Baidu hi to chat with me online.

How to add the cool dog music player to the QQ space log and add other players?

I also want to add music to the log. I wouldn't have said anything wrong, but cool has a tutorial. The landlord can check it and understand it. How can he find the tutorial? First
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.