Probe into Drag & DROP in Windows (2)

zhaozj2021-02-17  53

V. OLE drag and drop

The CView class of the MFC itself is supported by the drag and drop operation. By studying the source code of the CView class, it is generally known that its implementation principle is such that a CView class has a ColedropTarget class. When the view window is initialized, call the COLLDROPTARGET class member function. Register () to register this view window in the system to drag and drop the receiving window. When the mouse pointer of the drag and drop operation is in the view window range, the ColedropTarge class will respond, its member function such as OnDragenter, OnDragover, OnDropex, OnDrop is called by default, the CView class corresponds to it. Member Functions OnDragenter, OnDragover, OnDropex, OnDrop, etc., programmers only need to overload these CVIEW class member functions, which can be controlled to the process and results of the drag.

Because ColedropTarget is only available to CView by default, if you want to make other windows support drag and drop, we must derive the window classes to support drag and drop and the ColedropTarget class. Package the code for the drag and drop operation to encapsulate the member function of derived window classes, then reload the five virtual functions corresponding to the ColedropTarget, when it receives the drag and drop operation, call the window to derive the processing function. But there is a problem here, how do we know when to call the derived class handler? The answer is to use RTTI technology. If the window pointer type received by the COLLDROPTARGET is, we derived the window class, then call its handle function, otherwise the base class is called.

First become a dialog engineering, add two new classes.

The first class named CListCtrlex, the parent class is ClistCtrl. After adding, add Declare_Dynamic (CListCtrlex) in the definition header file of CListCtrlex, add import_dynamic (CListCtrlex, ClistCtrl) to its implementation file, which adds Run Time Type Information supporting the CListCtrlex class.

The second class name is ColedropTargetex, the parent class is a COLEDATATARGET.

Add the object of the COLLDROPTARGETEX class in CListCtrlex and add the following public virtual functions:

Virtual bool initialize ();

Virtual DROPEFFECT ONDRAGOVER (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DWORD DWKEYSTATE, CPOINT POINT);

Virtual DROPEFFECT OnDROPEX (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DROPEFFECT DROPEFFECT, DROPEFFECT DROPLIST, CPOINT POINT);

Virtual Bool OnDrop (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DROPEFFECT DROPEFFECT, CPOINT POINT);

Virtual Void OnDragleave (CWND * PWND);

The Initialize function is used to register CListCtrlex into drag and drop reception window;

OnDragover is called when dragging and dropping the mouse. The return value of this function determines the type of follow-up: If you return DROPEFFECT_MOVE, a cut action is generated; if you return DROPEFFECT_COPY, a copy action is generated. If DROPEFFECT_NONE is returned, it will not generate drag and drop motion because Ondropex, OnDrop The function will not be called (the onDragleave function will still be called). The onDropex function is called before the onDrop function. If the onDropex function does not process the drag and drop action, the application framework will then call the onDrop function for processing. So you must overload the onDropex function in the derived class - even if there is any action - Otherwise, our OnDrop function will not be executed, because there is no overload, will call the base class onDropex function, The base class's OnDropex function is processed to drag and drop - although not what we want. Of course, you can also put the action to drag and drop in OnDropex - then don't need to overload the onDrop.

The OnDragleave function is called when the mouse leaves the window, and some simple cleanup work can be made. For example, in the onDragenter or the onDragover function, we changed the shape of the cursor, then we should recover the cursor at this time.

The most important thing in these functions is the onDrop function, and the drag and drop action will be processed here. Its all the source code is as follows:

Bool ClistCtrlex :: Ondrop (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DROPEFFECT DROPEFFECT, CPOINT POINT)

{

UINT NFILECUNT = 0;

HDrop HDropfiles = NULL;

Hglobal HMEMDATA = NULL;

AfxMessageBox ("OnDrop");

IF (pDataObject-> isdataavailable (cf_hdrop))

{

HMEMDATA = PDataObject-> getGlobalData (cf_hdrop);

HDropfiles = (hdrop) Globalock (hglobal); // Lock memory block

IF (HDROPFILES! = NULL)

{

Char chtemp [_max_path 1] = {0};

NfileCount = DragQueryFile (HDropfiles, 0xfffffff, null, 0);

For (uint ncur = 0; ncur

{

ZeromeMory (chTEMP, _MAX_PATH 1);

Dragqueryfile (HDropfiles, NCur, (LPTSTR) ChTemp, _MAX_PATH 1);

AddAllFiles (chTEMP);

}

}

GlobalUnlock (HMEMDATA);

Return True;

}

Else

{

Return False;

}

}

Add a function of the following COLEDROPTARGET:

Virtual DROPEFFECT ONDRAGENTER (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DWORD DWKEYSTATE, CPOINT POINT);

virtual DROPEFFECT OnDragOver (CWnd * pWnd, COleDataObject * pDataObject, DWORD dwKeyState, CPoint point); virtual DROPEFFECT OnDropEx (CWnd * pWnd, COleDataObject * pDataObject, DROPEFFECT dropEffect, DROPEFFECT dropList, CPoint point);

Virtual Bool OnDrop (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DROPEFFECT DROPEFFECT, CPOINT POINT);

Virtual Void OnDragleave (CWND * PWND);

Their actions are similar: first use the RTTI to determine the type of window pointer PWnd, if it is CListCtrlex, call the corresponding processing function in CListCtrlex, otherwise the process function of the base class is called. Take OnDrop as an example:

Bool ColedropTargetex :: Ondrop (CWND * PWND, COLEDATAOBJECT * PDATAOBJECT, DROPEFFECT DROPEFFECT, CPOINT POINT)

{

Assert_Valid (this);

Assert (iswindow (pWnd-> m_hwnd);

ClistCtrlex * PListCtrlex = NULL;

IF (PWND-> iskindof (runtime_class (clistctrlex)))

{

PListCtrlex = (CListCtrlex *) PWND;

Return PListCtrlex-> OnDrop (PWND, PDataObject, DROPEFFECT, POINT);

}

Else

{

Return ColedropTarget :: Ondrop (PWND, PDataObject, DROPEFFECT, POINT);

}

}

To Be Continue ...

转载请注明原文地址:https://www.9cbs.com/read-29684.html

New Post(0)