using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System;
namespace DragAndDrop
{
public
enum
Msgs
{
WM_DRAWCLIPBOARD = 0x0308,
WM_CHANGECBCHAIN = 0x030D
}
public
class
ClipboardView : UserControl
{
[DllImport("user32.dll")]
public
static
extern
IntPtr SetClipboardViewer(
IntPtr hWndNewViewer
);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public
static
extern
IntPtr SendMessage(
IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam
);
private
IntPtr _nxtVwr;
private
PictureBox _img;
private
PaletteSet _ps;
public System.Drawing.Image Contents
{
get { return _img.Image; }
}
public ClipboardView(PaletteSet ps)
{
_img = new
PictureBox();
_img.Anchor =
(AnchorStyles)(AnchorStyles.Top |
AnchorStyles.Bottom |
AnchorStyles.Left |
AnchorStyles.Right);
_img.Location = new
Point(0, 0);
_img.Size = this.Size;
_img.SizeMode = PictureBoxSizeMode.StretchImage;
Controls.Add(_img);
// Add our event handler to launch a new drag event
// when someone clicks on the control
_img.MouseDown +=
delegate(object sender, MouseEventArgs e)
{
// Simply initiate the drag & drop in AutoCAD,
// specifying an instance of our custom "drop
// target" class
Autodesk.AutoCAD.ApplicationServices.
Application.DoDragDrop(
_img, this.Contents, DragDropEffects.Copy,
new
MyDropTarget()
);
};
_nxtVwr = SetClipboardViewer(this.Handle);
_ps = ps;
}
private
void ExtractImage()
{
IDataObject iData;
try
{
iData = Clipboard.GetDataObject();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
return;
}
if (iData.GetDataPresent("Bitmap"))
{
object o = iData.GetData("Bitmap");
Bitmap b = o as
Bitmap;
if (b != null)
{
_img.Image = b;
if (_ps != null)
{
_ps.Size =
new
Size(b.Size.Width / 3, b.Size.Height / 3);
}
}
}
}
protected
override
void WndProc(ref
Message m)
{
switch ((Msgs)m.Msg)
{
case
Msgs.WM_DRAWCLIPBOARD:
ExtractImage();
SendMessage(_nxtVwr, m.Msg, m.WParam, m.LParam);
break;
case
Msgs.WM_CHANGECBCHAIN:
if (m.WParam == _nxtVwr)
_nxtVwr = m.LParam;
else
SendMessage(_nxtVwr, m.Msg, m.WParam, m.LParam);
break;
default:
base.WndProc(ref m);
break;
}
}
}
// Our custom drop target class
public
class
MyDropTarget : Autodesk.AutoCAD.Windows.DropTarget
{
public
override
void OnDrop(DragEventArgs e)
{
Document doc =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument;
// If we have a valid bitmap, save it and send
// our custom command (RINS)
if (e.Data.GetDataPresent("Bitmap"))
{
object o = e.Data.GetData("Bitmap");
Bitmap b = o as
Bitmap;
if (b != null)
{
// We'll save the bitmap as a "temp" file
// (as its unique - a better approach
// would probably to create a unique file
// in the same folder as the drawing, but
// that's left to the reader)
string path = Path.GetTempFileName();
b.Save(path);
// Call our command
string cmd = "_RINS " + path + "\n";
doc.SendStringToExecute(
cmd, false, false, false
);
}
}
}
}
public
class
Commands
{
private
PaletteSet _ps = null;
private
ClipboardView _cv = null;
static
private
Point3d _pt = Point3d.Origin;
[CommandMethod("DRAGDROP")]
public
void DragAndDropClipboardRaster()
{
if (_ps == null)
{
_ps = new
PaletteSet(
"DRAGDROP",
new
Guid("5C8FC28C-45ED-4796-BD40-28D235B6D7DA")
);
if (_cv == null)
{
_cv = new
ClipboardView(_ps);
}
_ps.Text = "Clipboard";
_ps.DockEnabled =
DockSides.Left | DockSides.Right | DockSides.None;
_ps.Size = new System.Drawing.Size(300, 500);
_ps.Add("ClipboardView", _cv);
}
_ps.Visible = true;
}
// Our custom command to insert a raster image
[CommandMethod("RINS")]
public
void RasterInsert()
{
Document doc =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Pick up the location of the bitmap image
PromptStringOptions pso =
new
PromptStringOptions(
"\nPath of raster image: "
);
pso.AllowSpaces = true;
PromptResult pr = ed.GetString(pso);
if (pr.Status != PromptStatus.OK)
return;
if (!File.Exists(pr.StringResult))
{
ed.WriteMessage(
"\nFile does not exist."
);
return;
}
string path = pr.StringResult;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
// Get or create our raster image dictionary
ObjectId dictId =
RasterImageDef.GetImageDictionary(db);
if (dictId == ObjectId.Null)
dictId = RasterImageDef.CreateImageDictionary(db);
// And open it for write
DBDictionary dict =
(DBDictionary)tr.GetObject(
dictId, OpenMode.ForWrite
);
// Get a unique name for our definition object
string name = RasterImageDef.SuggestName(dict, path);
// Create the definition and add it to the dictionary
RasterImageDef rid = new
RasterImageDef();
rid.SourceFileName = path;
rid.Load();
ObjectId ridId = dict.SetAt(name, rid);
tr.AddNewlyCreatedDBObject(rid, true);
// Now we'll add our raster image reference
// to the current space
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForWrite
);
// Create and add the image reference
RasterImage ri = new
RasterImage();
ri.ImageDefId = ridId;
ri.SetClipBoundaryToWholeImage();
btr.AppendEntity(ri);
tr.AddNewlyCreatedDBObject(ri, true);
// Of course we commit
tr.Commit();
}
}
}
}