Home>

Screenshot effect when dragging

The implementation code is as follows:

///<summary>
///drag and drop help class
///</summary>
public static class draghelper
{
  ///<summary>
  ///bandedgridview drag
  ///</summary>
  ///<param name="gvmain"></param>
  public static void draggridrow<t>(this bandedgridview gvmain)
  {
   //drag the mask control
   dragmaster dragmaster=new dragmaster ();
   //current drag line drawing area
   rectangle _dragrowrect=rectangle.empty;
   gridcontrol gcmain=gvmain.gridcontrol;
   gridhitinfo _downhitinfo=null;
   //Table property allows drag and drop
   gcmain.allowdrop=true;
   gvmain.optionsdetail.enablemasterviewmode=false;
   #region dragover when dragging an object to a boundary
   gcmain.dragover +=delegate (object sender, system.windows.forms.drageventargs e)
   {
    if (e.data.getdatapresent (typeof (t)))
     e.effect=dragdropeffects.move;
    else
     e.effect=dragdropeffects.none;
   };
   #endregion
   #region Processing data when the drag is complete dragdrop
   gcmain.dragdrop +=delegate (object sender, system.windows.forms.drageventargs e)
   {
    //new data dragged over
    t newrow=(t) e.data.getdata (typeof (t));
    //the original data at this coordinate
    //e's coordinates are relative to the screen
    var clientpoint=gcmain.pointtoclient (new point (e.x, e.y));
    gridhitinfo hitinfo=gvmain.calchitinfo (new point (clientpoint.x, clientpoint.y));
    var oldrow=(t) gvmain.getrow (hitinfo.rowhandle);
    //do not process if equal
    if (oldrow == null || newrow == null) return;
    //If the target position is not the last line, rearrange all the sequence numbers
    //original line number
    var oldindex=_downhitinfo.rowhandle;
    //new line number
    var newindex=hitinfo.rowhandle;
    bindingsource bs=(bindingsource) (gcmain.datasource);
    if (bs == null)
     return;
    bs.removeat (oldindex);
    bs.insert (oldindex, oldrow);
    bs.removeat (newindex);
    bs.insert (newindex, newrow);
    bs.resetbindings (false);
   };
   #endregion
   #region mouse down mousedown
   gcmain.mousedown +=delegate (object sender, mouseeventargs e)
   {
    _downhitinfo=null;
    gridhitinfo hitinfo=gvmain.calchitinfo (new point (e.x, e.y));
    if (control.modifierkeys!=keys.none) return;
    if (e.button == mousebuttons.left&&hitinfo.rowhandle>= 0)
    {
     //Disabled grid does not support dragging
     if (! gvmain.optionsbehavior.editable
      || gvmain.optionsbehavior.readonly)
      return;
     //can only be dragged by clicking on the front
     if (hitinfo.inrowcell)
      return;
     //cache
     _downhitinfo=hitinfo;
    }
   };
   #endregion
   #region mouse movement mousemove
   gcmain.mousemove +=delegate (object sender, mouseeventargs e)
   {
    if (e.button == mousebuttons.left)
    {
     if (_downhitinfo!=null)
     {
      size dragsize=systeminformation.dragsize;
      //deviation area
      rectangle dragrect=new rectangle (new point (_downhitinfo.hitpoint.x-dragsize.width/2, _downhitinfo.hitpoint.y-dragsize.height/2), dragsize);
      if (! dragrect.contains (new point (e.x, e.y)))
      {
       //screen coordinates
       var p=gcmain.pointtoscreen (e.location);
       //refresh is required
       gcmain.refresh ();
       //Get screenshot of current line
       var bmp=getdragrowimage (gcmain, _downhitinfo, _dragrowrect);
       point offsetpoint=new point (p.x + 1, p.y-dragmaster.dragsize.height/2);
       //start showing drag mask
       dragmaster.startdrag (bmp, offsetpoint, dragdropeffects.move);
       //Get the data to be dragged
       object row=gvmain.getrow (_downhitinfo.rowhandle);
       //start dragging
       gcmain.dodragdrop (row, dragdropeffects.move);
       //cancel event
       devexpress.utils.dxmouseeventargs.getmouseargs (e) .handled=true;
       //Empty the cache
       _downhitinfo=null;
      }
     }
    }
   };
   #endregion
   #region Occurs when dragging an item with the mouse.
Whether to allow drag and drop querycontinuedrag
   gcmain.querycontinuedrag +=delegate (object sender, querycontinuedrageventargs e)
   {
    switch (e.action)
    {
     case dragaction.continue:
      //move mask
      point offsetpoint=new point (cursor.position.x + 1, cursor.position.y-dragmaster.dragsize.height/2);
      dragmaster.dodrag (offsetpoint, dragdropeffects.move, false);
      break;
     default:
      //clear
      _dragrowrect=rectangle.empty;
      //stop dragging
      dragmaster.enddrag ();
      break;
    }
   };
   #endregion
   #region Click the row head to move the row
   gvmain.customdrawrowindicator +=delegate (object sender, rowindicatorcustomdraweventargs e)
   {
    if (_dragrowrect == rectangle.empty&&_downhitinfo!=null&&_downhitinfo.rowhandle == e.rowhandle)
    {
     _dragrowrect=e.bounds;
    }
   };
   #endregion
  }
  ///<summary>
  ///gridview drag
  ///</summary>
  ///<param name="gvmain"></param>
  public static void draggridrow<t>(this gridview gvmain)
  {
   //drag the mask control
   dragmaster dragmaster=new dragmaster ();
   //current drag line drawing area
   rectangle _dragrowrect=rectangle.empty;
   gridcontrol gcmain=gvmain.gridcontrol;
   gridhitinfo _downhitinfo=null;
   //Table property allows drag and drop
   gcmain.allowdrop=true;
   gvmain.optionsdetail.enablemasterviewmode=false;
   #region dragover when dragging an object to a boundary
   gcmain.dragover +=delegate (object sender, system.windows.forms.drageventargs e)
   {
    if (e.data.getdatapresent (typeof (t)))
     e.effect=dragdropeffects.move;
    else
     e.effect=dragdropeffects.none;
   };
   #endregion
   #region Processing data when the drag is complete dragdrop
   gcmain.dragdrop +=delegate (object sender, system.windows.forms.drageventargs e)
   {
    //new data dragged over
    t newrow=(t) e.data.getdata (typeof (t));
    //the original data at this coordinate
    //e's coordinates are relative to the screen
    var clientpoint=gcmain.pointtoclient (new point (e.x, e.y));
    gridhitinfo hitinfo=gvmain.calchitinfo (new point (clientpoint.x, clientpoint.y));
    var oldrow=(t) gvmain.getrow (hitinfo.rowhandle);
    //do not process if equal
    if (oldrow == null || newrow == null) return;
    //If the target position is not the last line, rearrange all the sequence numbers
    //original line number
    var oldindex=_downhitinfo.rowhandle;
    //new line number
    var newindex=hitinfo.rowhandle;
      bindingsource bs=(bindingsource) (gcmain.datasource);
    if (bs == null)
     return;
      bs.removeat (oldindex);
    bs.insert (oldindex, oldrow);
    bs.removeat (newindex);
    bs.insert (newindex, newrow);
    bs.resetbindings (false);
   };
   #endregion
   #region mouse down mousedown
   gcmain.mousedown +=delegate (object sender, mouseeventargs e)
   {
    _downhitinfo=null;
    gridhitinfo hitinfo=gvmain.calchitinfo (new point (e.x, e.y));
    if (control.modifierkeys!=keys.none) return;
    if (e.button == mousebuttons.left&&hitinfo.rowhandle>= 0)
    {
     //Disabled grid does not support dragging
     if (! gvmain.optionsbehavior.editable
      || gvmain.optionsbehavior.readonly)
      return;
     //can only be dragged by clicking on the front
     if (hitinfo.inrowcell)
      return;
     //cache
     _downhitinfo=hitinfo;
    }
   };
   #endregion
   #region mouse movement mousemove
   gcmain.mousemove +=delegate (object sender, mouseeventargs e)
   {
    if (e.button == mousebuttons.left)
    {
     if (_downhitinfo!=null)
     {
      size dragsize=systeminformation.dragsize;
      //deviation area
      rectangle dragrect=new rectangle (new point (_downhitinfo.hitpoint.x-dragsize.width/2, _downhitinfo.hitpoint.y-dragsize.height/2), dragsize);
        if (! dragrect.contains (new point (e.x, e.y)))
      {
       //screen coordinates
       var p=gcmain.pointtoscreen (e.location);
       //refresh is required
       gcmain.refresh ();
       //Get screenshot of current line
       var bmp=getdragrowimage (gcmain, _downhitinfo, _dragrowrect);
       point offsetpoint=new point (p.x + 1, p.y-dragmaster.dragsize.height/2);
       //start showing drag mask
       dragmaster.startdrag (bmp, offsetpoint, dragdropeffects.move);
       //Get the data to be dragged
       object row=gvmain.getrow (_downhitinfo.rowhandle);
       //start dragging
       gcmain.dodragdrop (row, dragdropeffects.move);
       //cancel event
       devexpress.utils.dxmouseeventargs.getmouseargs (e) .handled=true;
       //Empty the cache
       _downhitinfo=null;
      }
     }
    }
   };
   #endregion
   #region Occurs when dragging an item with the mouse.
Whether to allow drag and drop querycontinuedrag
   gcmain.querycontinuedrag +=delegate (object sender, querycontinuedrageventargs e)
   {
    switch (e.action)
    {
     case dragaction.continue:
      //move mask
      point offsetpoint=new point (cursor.position.x + 1, cursor.position.y-dragmaster.dragsize.height/2);
      dragmaster.dodrag (offsetpoint, dragdropeffects.move, false);
      break;
     default:
      //clear
      _dragrowrect=rectangle.empty;
      //stop dragging
      dragmaster.enddrag ();
      break;
    }
   };
   #endregion
   #region Click the row head to move the row
   gvmain.customdrawrowindicator +=delegate (object sender, rowindicatorcustomdraweventargs e)
   {
    if (_dragrowrect == rectangle.empty&&_downhitinfo!=null&&_downhitinfo.rowhandle == e.rowhandle)
    {
     _dragrowrect=e.bounds;
    }
   };
   #endregion
   }
  ///<summary>
  ///get drag screenshot
  ///</summary>
  ///<param name="hitinfo"></param>
  ///<param name="gcmain"></param>
  ///<param name="dragrowrect"<&//param>
  ///<returns></returns>
  private static bitmap getdragrowimage (gridcontrol gcmain, gridhitinfo hitinfo, rectangle dragrowrect)
  {
   //screenshot
   var bmp=devimagecapturer.getcontrolbitmap (gcmain, null
   , dragrowrect.width + 1, dragrowrect.top
   , gcmain.width-dragrowrect.width-4, dragrowrect.height-1);
     using (graphics g=graphics.fromimage (bmp))
   {
    var p1=new point (1, 1);
    var p2=new point (bmp.width-1, 1);
    var p3=new point (1, bmp.height-2);
    var p4=new point (bmp.width-1, bmp.height-2);
    using (pen pen=new pen (gcmain.forecolor))
    {
     g.drawline (pen, p1, p2);
     g.drawline (pen, p1, p3);
     g.drawline (pen, p2, p4);
     g.drawline (pen, p3, p4);
    }
   }
   return bmp;
  }
}
///<summary>
///drag window
///</summary>
public partial class dragwindow:devexpress.utils.win.topformbase
{
  private bitmap dragbitmap;
  private bool dragging;
  private point hotspot;
  public static readonly point invisiblepoint=new point (-100000, -100000);
  public dragwindow ()
  {
   hotspot=point.empty;
   dragging=false;
   setstyle (controlstyles.selectable, false);
   this.size=size.empty;
   this.showintaskbar=false;
   form prevactive=form.activeform;
   initializecomponent ();
  }
  void activateform (object sender, eventargs e)
  {
   form form=sender as form;
   if (form == null ||! form.ishandlecreated) return;
   form.activate ();
  }
  public void maketopmost ()
  {
   updatezorder ();
  }
  private void initializecomponent ()
  {
   this.startposition=formstartposition.manual;
   dragbitmap=null;
   this.enabled=false;
   this.minimumsize=size.empty;
   this.size=size.empty;
   this.location=invisiblepoint;
   this.visible=false;
   this.tabstop=false;
   //this.opacity=0.7;//devexpress.utils.dragdrop.dragwindow.defaultopacity;
  }
  protected void internalmovebitmap (point p)
  {
   //p.offset(-hotspot.x, -hotspot.y);
   this.suspendlayout ();
   this.location=p;
   this.resumelayout ();
  }
  protected override void onresize (system.eventargs e)
  {
   base.onresize (e);
  }
  public bool showdrag (point p)
  {
   if (this.backgroundimage == null) return false;
   dragging=true;
   visible=true;
   refresh ();
   internalmovebitmap (p);
   return true;
  }
  public bool movedrag (point p)
  {
   if (! dragging) return false;
   internalmovebitmap (p);
   return true;
  }
  public bool hidedrag ()
  {
   if (! dragging) return false;
   visible=false;
   backgroundimage=null;
   dragging=false;
   this.suspendlayout ();
   this.size=size.empty;
   this.location=invisiblepoint;
   this.resumelayout ();
   return true;
  }
  public point hotspot {get {return hotspot;} set {hotspot=value;}}
  public bitmap dragbitmap
  {
   get {return dragbitmap;}
   set
   {
    this.backgroundimage=value;
    if (value == null)
    {
     hidedrag ();
    }
    else
     hotspot=new point (value.size.width/2, value.size.height/2);
    dragbitmap=value;
    size=backgroundimage.size;
   }
  }
}
///<summary>
///screenshot
///</summary>
public class devimagecapturer
{
  [system.runtime.interopservices.dllimport ("user32.dll")]
  internal static extern intptr getdc (intptr dc);
  [system.runtime.interopservices.dllimport ("user32.dll")]
  internal static extern int releasedc (intptr hwnd, intptr hdc);
  [system.runtime.interopservices.dllimport ("user32.dll")]
  internal static extern intptr getdesktopwindow ();
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern bool bitblt (intptr hdcdest, int nxdest, int nydest, int nwidth, int nheight, intptr hdcsrc, int nxsrc, int nysrc, uint dwrop);
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern intptr createcompatibledc (intptr hdc);
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern intptr createcompatiblebitmap (intptr hdc, int nwidth, int nheight);
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern bool deleteobject (intptr hobject);
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern intptr selectobject (intptr hdc, intptr obj);
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern intptr createsolidbrush (int color);
  [system.runtime.interopservices.dllimport ("gdi32.dll")]
  internal static extern intptr createpatternbrush (intptr hbitmap);
  ///<summary>
  ///Get a screenshot of the control
  ///</summary>
  ///<param name="control">control</param>
  ///<param name="pattern">picture</param>
  ///<returns></returns>
  public static bitmap getcontrolbitmap (control control, bitmap pattern)
  {
   int width=control.width;
   int height=control.height;
   if (control is form)
   {
    width=control.clientrectangle.width;
    height=control.clientrectangle.height;
   }
   intptr hdc=getdc (control.handle);
   intptr compdc=createcompatibledc (hdc);
   intptr comphbmp=createcompatiblebitmap (hdc, width, height);
   intptr prev=selectobject (compdc, comphbmp);
   intptr brush=intptr.zero, prevbrush=intptr.zero;
   if (pattern!=null)
   {
    brush=createpatternbrush (pattern.gethbitmap ());
    prevbrush=selectobject (compdc, brush);
   }
   point pt=new point (0, 0);
   bitblt (compdc, 0, 0, width, height, hdc, pt.x, pt.y, 0x00c000ca);
   selectobject (compdc, prev);
   if (prevbrush!=intptr.zero)
    selectobject (compdc, prevbrush);
   releasedc (control.handle, hdc);
   nativemethods.deletedc (compdc);
   bitmap bmp=bitmap.fromhbitmap (comphbmp);
   deleteobject (comphbmp);
   if (brush!=intptr.zero)
    deleteobject (brush);
   return bmp;
  }
  ///<summary>
  ///Get a screenshot of the control
  ///</summary>
  ///<param name="control">control</param>
  ///<param name="pattern">picture</param>
  ///<param name="offsetx"&x;x</param>
  ///<param name="offsety">y</param>
  ///<param name="width">width</param>
  ///<param name="height">high</param>
  ///<returns></returns>
  public static bitmap getcontrolbitmap (control control, bitmap pattern, int offsetx=0, int offsety=0, int width=0, int height=0)
  {
   width=width == 0?control.width:width;
   height=height == 0?control.height:height;
   if (control is form)
   {
    width=control.clientrectangle.width;
    height=control.clientrectangle.height;
   }
   intptr hdc=getdc (control.handle);
   intptr compdc=createcompatibledc (hdc);
   intptr comphbmp=createcompatiblebitmap (hdc, width, height);
   intptr prev=selectobject (compdc, comphbmp);
   intptr brush=intptr.zero, prevbrush=intptr.zero;
   if (pattern!=null)
   {
    brush=createpatternbrush (pattern.gethbitmap ());
    prevbrush=selectobject (compdc, brush);
   }
   point pt=new point (offsetx, offsety);
   bitblt (compdc, 0, 0, width, height, hdc, pt.x, pt.y, 0x00c000ca);
   selectobject (compdc, prev);
   if (prevbrush!=intptr.zero)
    selectobject (compdc, prevbrush);
   releasedc (control.handle, hdc);
   nativemethods.deletedc (compdc);
   bitmap bmp=bitmap.fromhbitmap (comphbmp);
   deleteobject (comphbmp);
   if (brush!=intptr.zero)
    deleteobject (brush);
   return bmp;
  }
}
 public class dragmaster
 {
  [threadstatic]
  static dragwindow dragwindow;
  bool draginprogress;
  dragdropeffects effects;
  dragdropeffects lasteffect;
  static cursor customizationcursor=null;
  double _opacity=0.7;
    public double opacity
  {
   get {return _opacity;}
   set {_opacity=value;}
  }
  public dragmaster ()
  {
   draginprogress=false;
   lasteffect=effects=dragdropeffects.none;
  }
    dragwindow dragwindow
  {
   get
   {
    if (dragwindow == null) dragwindow=new dragwindow () {opacity=this.opacity};
    return dragwindow;
   }
  }
  public dragdropeffects lasteffect
  {
   get {return lasteffect;}
  }
  public bool draginprogress
  {
   get {return draginprogress;}
  }
    ///<summary>
  ///draw size
  ///</summary>
  public size dragsize
  {
   get
   {
    if (dragwindow.dragbitmap == null) return size.empty;
    return dragwindow.dragbitmap.size;
   }
  }
  ///<summary>
  ///start dragging
  ///</summary>
  ///<param name="bmp"></param>
  ///<param name="startpoint"></param>
  ///<param name="effects"></param>
  public void startdrag (bitmap bmp, point startpoint, dragdropeffects effects)
  {
   stopdrag ();
   draginprogress=true;
   this.effects=effects;
   lasteffect=effects;
   dragwindow.maketopmost ();
   dragwindow.dragbitmap=bmp;
   dragwindow.showdrag (startpoint);
   setdragcursor (effects);
  }
  ///<summary>
  ///stop dragging
  ///</summary>
  protected void stopdrag ()
  {
   draginprogress=false;
   lasteffect=effects=dragdropeffects.none;
   dragwindow.hidedrag ();
  }
  ///<summary>
  ///Set the type of drag mouse
  ///</summary>
  ///<param name="e"></param>
  public void setdragcursor (dragdropeffects e)
  {
   if (e == dragdropeffects.none)
    cursor.current=customizationcursor;
   else
    cursor.current=cursors.default;
  }
  ///<summary>
  ///drag
  ///</summary>
  ///<param name="p"></param>
  ///<param name="e"></param>
  ///¶m name="setcursor"
  public void dodrag (point p, dragdropeffects e, bool setcursor)
  {
   if (! draginprogress) return;
   lasteffect=e;
   if (setcursor) setdragcursor (e);
   dragwindow.movedrag (p);
  }
  ///<summary>
  ///cancel dragging
  ///</summary>
  public void canceldrag ()
  {
   if (! draginprogress) return;
   stopdrag ();
  }
  ///<summary>
  ///end the drag
  ///</summary>
  public void enddrag ()
  {
   if (! draginprogress) return;
   stopdrag ();
  }
  ///<summary>
  ///custom cursor
  ///</summary>
  static cursor customizationcursor
  {
   get
   {
    if (customizationcursor == null) customizationcursor=resourceimagehelper.createcursorfromresources ("devexpress.xtratreelist.images.customization.cur", typeof (dragmaster) .assembly);
    return customizationcursor;
   }
  }
}
c
  • Previous Ajax-based image upload based on firefox
  • Next Android Studio Tutorial (3): Common Shortcuts