Created
January 31, 2018 13:10
-
-
Save Polaringu/499c1ff6e72fe8a8c87aecbacca0c97b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Drop target that will contain the custom drag and drop implementation for the given object | |
public MyDropTarget myDropTarget = null; //PS: Do not forget to dispose of it (we do it in Form1_FormClosed) | |
//Method where the myDropTarget is initialized | |
void InitializePagesViewAsDropTarget() | |
{ | |
PDFXEdit.IUIX_Obj obj = pdfCtl.Doc.ActiveView.PagesView.Obj; | |
//Setting style of the object so it will accept dropping | |
obj.SetStyleEx((int)PDFXEdit.UIX_ObjStyleExFlags.UIX_ObjStyleEx_DropTarget, (int)PDFXEdit.UIX_ObjStyleExFlags.UIX_ObjStyleEx_DropTarget); | |
//Creating the drop target and filling it's supported formats | |
myDropTarget = new MyDropTarget(obj, this); | |
myDropTarget.AddSuppTextDrop(false); | |
myDropTarget.AddSuppTextDrop(true); | |
} | |
//Class that implements the drop target functionality for the needed object | |
//In this example the PagesView was used as the "needed object" | |
public partial class MyDropTarget : | |
PDFXEdit.IUIX_ObjImpl, | |
PDFXEdit.IDropTarget, | |
IDisposable | |
{ | |
//Here we push implementation of drag and drop functions of the PagesView | |
public MyDropTarget(PDFXEdit.IUIX_Obj obj, MainFrm parentForm) | |
{ | |
Obj_ = obj; | |
if (Obj_ != null) | |
Obj_.PushImpl(this); | |
Parent = parentForm; | |
} | |
~MyDropTarget() | |
{ | |
Dispose(); | |
} | |
//Disposing of all of the links we made with objects and parent | |
public void Dispose() | |
{ | |
Parent = null; | |
if (Disposed_) | |
return; | |
Disposed_ = true; | |
if (Obj_ != null) | |
{ | |
Obj_.PopImpl(this); | |
System.Runtime.InteropServices.Marshal.ReleaseComObject(Obj_); | |
Obj_ = null; | |
} | |
} | |
//Main form - a parent that in our case holds the PDFXEdit control | |
public MainFrm Parent = null; | |
//Object for which we are implementing drag and drop | |
public PDFXEdit.IUIX_Obj Obj_; | |
//Used for single dispose control | |
private bool Disposed_ = false; | |
//Used for checking whether the DragEnter function gave successful results (formats check) - used in DragOver function | |
private bool SuccessEnter = false; | |
//List of supported formats that will be dragged onto our object | |
List<System.Runtime.InteropServices.ComTypes.FORMATETC> m_SuppFmtEtc = new List<System.Runtime.InteropServices.ComTypes.FORMATETC>(); | |
// IUIX_ObjImpl | |
public PDFXEdit.IUIX_Obj Obj | |
{ | |
get { return this.Obj_; } | |
} | |
//Event listener that listens for e_QueryDropTarget | |
public void OnEvent(PDFXEdit.IUIX_Obj pSender, PDFXEdit.IUIX_Event pEvent) | |
{ | |
pEvent.Handled = false; | |
if (pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_QueryDropTarget) | |
{ | |
pEvent.Handled = true; | |
IntPtr res = IntPtr.Zero; | |
try | |
{ | |
//We need to return com interface for PDFXEdit.IDropTarget from the current class as a pEvent.Result | |
res = System.Runtime.InteropServices.Marshal.GetComInterfaceForObject(this, typeof(PDFXEdit.IDropTarget)); | |
} | |
catch (Exception e) | |
{ | |
Debug.WriteLine("pdfCtl.OnEvent: e.nEventID=={0}", e.Message); | |
} | |
if (res != IntPtr.Zero) | |
pEvent.Result = (uint)res; // = (long)res for x64 | |
} | |
else if (pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_BeforeDestroy) | |
{ | |
Dispose(); | |
} | |
else if (pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_Last) | |
{ | |
Dispose(); | |
} | |
} | |
//Method that adds text support formats into the m_SuppFmtEtc | |
public bool AddSuppTextDrop(bool bUnicode) | |
{ | |
System.Runtime.InteropServices.ComTypes.FORMATETC FmtEtc = new System.Runtime.InteropServices.ComTypes.FORMATETC(); | |
if (bUnicode == false) | |
FmtEtc.cfFormat = 1; //CF_TEXT | |
else | |
FmtEtc.cfFormat = 13; //CF_UNICODETEXT | |
FmtEtc.dwAspect = System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT; | |
FmtEtc.lindex = -1; | |
FmtEtc.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL; | |
return AddSuppFmt(FmtEtc); | |
} | |
//Method that adds a new format into the m_SuppFmtEtc | |
public bool AddSuppFmt(System.Runtime.InteropServices.ComTypes.FORMATETC FmtEtc) | |
{ | |
if (FmtEtc.cfFormat == 0) | |
return false; | |
for (int i = 0; i < m_SuppFmtEtc.Count(); i++) | |
{ | |
if (FmtEtc.cfFormat == m_SuppFmtEtc[i].cfFormat) | |
{ | |
m_SuppFmtEtc[i] = FmtEtc; | |
return true; | |
} | |
} | |
m_SuppFmtEtc.Add(FmtEtc); | |
return true; | |
} | |
//Method that gets FORMATETC and STGMEDIUM from the IDataObject | |
public bool GetFormatAndStgMedium(PDFXEdit.IDataObject pDataObj, ref System.Runtime.InteropServices.ComTypes.FORMATETC fmt, ref System.Runtime.InteropServices.ComTypes.STGMEDIUM med) | |
{ | |
//Running through the m_SuppFmtEtc and checking whether the dragged IDataObject is correct for one of them | |
System.Runtime.InteropServices.ComTypes.IDataObject obj = (System.Runtime.InteropServices.ComTypes.IDataObject)pDataObj; | |
for (int i = 0; i < m_SuppFmtEtc.Count(); i++) | |
{ | |
try | |
{ | |
//Getting STGMEDIUM data from IDataObject with the FORMATETC from the current iteration | |
obj.GetData(m_SuppFmtEtc[i], out med); | |
if (med.tymed != System.Runtime.InteropServices.ComTypes.TYMED.TYMED_NULL) | |
{ | |
fmt = m_SuppFmtEtc[i]; | |
return true; | |
} | |
} | |
catch (Exception e) | |
{ | |
Debug.WriteLine("pdfCtl.OnEvent: e.nEventID=={0}", e.Message); | |
} | |
} | |
return false; | |
} | |
public void OnPostEvent(PDFXEdit.IUIX_Obj pSender, PDFXEdit.IUIX_Event pEvent) | |
{ | |
} | |
public void OnPreEvent(PDFXEdit.IUIX_Obj pSender, PDFXEdit.IUIX_Event pEvent) | |
{ | |
} | |
/// <summary> | |
/// Provides access to Win32-level constants, structures, and functions. | |
/// </summary> | |
[DllImport("Kernel32.dll", SetLastError = true)] | |
private static extern IntPtr GlobalLock(IntPtr hMem); | |
[DllImport("Kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool GlobalUnlock(IntPtr hMem); | |
[DllImport("Kernel32.dll", SetLastError = true)] | |
private static extern int GlobalSize(IntPtr hMem); | |
// | |
public void DragEnter(PDFXEdit.IDataObject pDataObj, uint grfKeyState, PDFXEdit._POINTL pt, ref uint pdwEffect) | |
{ | |
pdwEffect = (uint)DragDropEffects.None; | |
SuccessEnter = false; | |
System.Runtime.InteropServices.ComTypes.FORMATETC fmtEtc = new System.Runtime.InteropServices.ComTypes.FORMATETC(); | |
System.Runtime.InteropServices.ComTypes.STGMEDIUM medium = new System.Runtime.InteropServices.ComTypes.STGMEDIUM(); | |
//Getting FORMATETC and STGMEDIUM from the IDataObject | |
if (GetFormatAndStgMedium(pDataObj, ref fmtEtc, ref medium) == true) | |
{ | |
//If we succeeded then doing the page hit test | |
//PDFXEdit.PXC_Point ptn = new PDFXEdit.PXC_Point(); | |
//if (Parent.HitTestPage(pt, out ptn) >= 0) | |
pdwEffect = (uint)DragDropEffects.Copy; //If we are on a page then changing the cursor | |
SuccessEnter = true; | |
} | |
} | |
public void DragLeave() | |
{ | |
SuccessEnter = false; | |
} | |
public void DragOver(uint grfKeyState, PDFXEdit._POINTL pt, ref uint pdwEffect) | |
{ | |
pdwEffect = (uint)DragDropEffects.None; | |
//If we got valid FORMATETC and STGMEDIUM in the DragEnter method then we can do the page hit test | |
if (SuccessEnter != false) | |
{ | |
//PDFXEdit.PXC_Point ptn = new PDFXEdit.PXC_Point(); | |
//if (Parent.HitTestPage(pt, out ptn) >= 0) | |
pdwEffect = (uint)DragDropEffects.Copy; | |
} | |
} | |
public void Drop(PDFXEdit.IDataObject pDataObj, uint grfKeyState, PDFXEdit._POINTL pt, ref uint pdwEffect) | |
{ | |
SuccessEnter = false; | |
System.Runtime.InteropServices.ComTypes.FORMATETC fmtEtc = new System.Runtime.InteropServices.ComTypes.FORMATETC(); | |
System.Runtime.InteropServices.ComTypes.STGMEDIUM medium = new System.Runtime.InteropServices.ComTypes.STGMEDIUM(); | |
//Getting FORMATETC and STGMEDIUM from the IDataObject | |
if (GetFormatAndStgMedium(pDataObj, ref fmtEtc, ref medium) == true) | |
{ | |
//If it's a global drag and drop and we've got the correct data | |
if (medium.tymed == System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL) | |
{ | |
//Getting data from the STGMEDIUM | |
var ptr = GlobalLock(medium.unionmember); | |
if (ptr != IntPtr.Zero) | |
{ | |
try | |
{ | |
var length = (Int32)GlobalSize(ptr); | |
var data = new byte[length]; | |
Marshal.Copy(ptr, data, 0, length); | |
//Now we have a result string that has our dragged text | |
string result = System.Text.Encoding.UTF8.GetString(data).TrimEnd('\0'); | |
//Adding Text annotation that contains that text | |
Parent.AddAnnotFromText(pt, result); | |
} | |
finally | |
{ | |
GlobalUnlock(medium.unionmember); | |
} | |
} | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment