I have a need to set the current viewport using C# but I could not find any method that would do so. I fired up google and came away with a couple of posts shown below.
https://www.theswamp.org/index.php?topic=35873.0http://forums.autodesk.com/t5/net/set-current-paperspace-viewport-autocad-2011-x64/td-p/2842674http://www.theswamp.org/index.php?topic=11973.msg148924#msg148924Unfortunately for whatever reason the solutions posted do not work for me. The most disappointing was the actual help file from autodesk. They show like the other posts using an entry point into acad.exe to access the c++ function. Now I will be the first to admit that I know absolutely nothing about unmanaged code and how to access it but I can copy and paste with the best of them. So i copied the code and it did not work. I suspect it was because of a 32/64 bit issue which Autodesk fails to point out when using unmanaged stuff in their help files.
So i downloaded and fired up dependency walker and got the following two entry points.
So I put them in my code and tried them and I still get an error. For the first call i get:
{"Unable to find an entry point named '?acedSetCurrentVPort@@YA?AW4ErrorStatus@Acad@@H@Z' in DLL 'acad.exe'.":""} as an error message.
For my second attemp i get this as an error message:
Unable to find an entry point named '?' in DLL 'acad.exe'.
Here is the full code that I am using.
public class RotatedDimensionAddStrategy : IDimensionAddStrategy
{
private readonly Viewport _viewport;
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acedSetCurrentVPort@@YA? AW4ErrorStatus@Acad@@PEBVAcDbViewport@@@Z")]
private static extern int acedSetCurrentVPort(IntPtr acDbVport);
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acedSetCurrentVPort@@YA?AW4ErrorStatus@Acad@@H@Z")]
private static extern int acedSetCurrentVPort(int acDbVportNumber);
/// <summary>
/// Initializes a new instance of the <see cref="RotatedDimensionAddStrategy"/> class.
/// </summary>
/// <param name="viewport">The viewport.</param>
public RotatedDimensionAddStrategy(Viewport viewport)
{
this._viewport = viewport;
}
/// <summary>
/// Adds the dimensions.
/// </summary>
/// <param name="dimensionLines">The dimension lines.</param>
public void AddDimensions(List<DimensionLine> dimensionLines)
{
if (dimensionLines == null || dimensionLines.Count == 0)
{
return;
}
using (Transaction transaction = Active.Database.TransactionManager.StartTransaction())
{
BlockTableRecord ms = Active.Database.ModelSpace(OpenMode.ForWrite);
List
<ObjectId
> dimensions
= new List
<ObjectId
>();
Matrix3d worldToView = this._viewport.GetModelToPaperTransform();
Vector3d viewDirection = this._viewport.ViewDirection.GetNormal();
RotatedDimensionBuilder dimensionBuilder
= new RotatedDimensionBuilder
(viewDirection,
25,
this._viewport
.CustomScale);
foreach (DimensionLine dimensionLine in dimensionLines)
{
dimensionBuilder.CreateDimensions(dimensionLine);
if (dimensionBuilder.Dimensions.Count > 0)
{
foreach (RotatedDimension dimension in dimensionBuilder.Dimensions)
{
dimensions.Add(ms.AppendEntity(dimension));
transaction.AddNewlyCreatedDBObject(dimension, true);
}
}
}
Viewport viewport = this._viewport.ObjectId.OpenAs<Viewport>();
if (dimensions.Count > 0)
{
SelectionSet selectionSet = SelectionSet.FromObjectIds(dimensions.ToArray());
ObjectId
[] viewPortSelection
= new ObjectId
[1]; viewPortSelection[0] = this._viewport.ObjectId;
SelectionSet viewportSelectionSet = SelectionSet.FromObjectIds(viewPortSelection);
Active.Editor.Command("MSPACE", viewportSelectionSet);
while (Active.Editor.CurrentViewportObjectId != viewport.ObjectId)
{
//acedSetCurrentVPort(viewport.Number);
acedSetCurrentVPort(viewport.UnmanagedObject);
}
Active.Editor.Command("CHSPACE", selectionSet, "");
}
transaction.Commit();
}
}
}
The code that is meaningful is on lines 63 and 64. I commented out the first call when trying the second as near as i can tell they both do the samething.
The code basically builds dimensions and them moves them to paperspace through a viewport using the mspace command to open a modelspace inside a viewport and then the chspace command to move the objects from modelspace to paperspace. I am using the chspace command to handle all of the scaling, rotating, etc automatically of the dimensions. Everything works great if there is only one viewport. However, when there are two viewports the mspace command opens up the current viewport instead of the currently selected one. So i need to change the current viewport and this is the only way i can find. Sending Ctrl-R to the autocad window using send keys did not work either. Ctrl-R will switch current viewports when using the mspace command.
Does anyone have any ideas or can see the error that I am making? I would rather not have to write the code to programmatically move the dimensions from modelspace to paperspace and instead just prefer to automate it with the command. Unless someone has created something or can point me in the right direction to achieve this. Thanks.