I use activex's double click event to define my own text editor function , but my code is work well only in no form state, once i use my own form , double click event will stop work.
the following is my code :
using System;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Publishing;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
//using CaiSoft.Cad.AcadUtilities;
using AcadArxApp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace CaiSoft.Cad.CaiCommands.General
{
public class DoubleClick
{
public static EventsWatcher ew;
[CommandMethod("Cai_StartDoubleClick", CommandFlags.Session)]
public static void StartDoubleClick()
{
if (ew == null)
{
ew = new EventsWatcher();
ew.StartEvent();
}
}
public static void DoubleClickEdit(Point3d pickPoint)
{
ObjectId id = GetEntityOnPickPoint(pickPoint);
AcadApplication app = (AcadApplication)AcadArxApp.AcadApplication;
bool loaded = false;
string dbclickArxName = "ACDBLCLKEDIT.ARX";
foreach (object obj in (string[])app.ListArx())
{
string name = (string)obj;
if (name.ToUpper() == dbclickArxName.ToUpper())
{
loaded = true;
break;
}
}
if (loaded)
{
app.UnloadArx(dbclickArxName);
}
if (id == ObjectId.Null)
{
AcadArxApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nPlease select a single entity!\n");
return;
}
else
{
AcadArxApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n" + id.ToString() + "\n");
}
Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction();
try
{
Entity ent = trans.GetObject(id, OpenMode.ForWrite, false) as Entity;
if (ent is DBText)
{
//((DBText)ent).TextString += "test "; // this line works fine.
EditText(id, trans); // this line only works some time.
}
else if (ent is MText)
{
EditText(id, trans);
}
trans.Commit();
}
catch (System.Exception e)
{
MessageBox.Show(e.Message);
}
finally { trans.Dispose(); }
}
private static ObjectId GetEntityOnPickPoint(Point3d pickPoint)
{
ObjectId id = ObjectId.Null;
PromptSelectionResult res = AcadArxApp.DocumentManager.MdiActiveDocument.Editor.SelectImplied();
if (res.Status == PromptStatus.OK)
{
if (res.Value.Count == 1)
{
id = res.Value[0].ObjectId;
}
}
return id;
}
public static void EditText(ObjectId objId, Transaction trans)
{
//TextEditorForm is my text editor form
string text = "";
Entity ent = trans.GetObject(objId, OpenMode.ForWrite, false) as Entity;
TextEditorForm f = null;
if (ent is DBText)
{
text = ((DBText)ent).TextString;
f = new TextEditorForm(text, false);
}
else if (ent is MText)
{
text = ((MText)ent).Contents;
f = new TextEditorForm(text, true);
}
DialogResult dr = AcadArxApp.ShowModalDialog(f);
if (dr != DialogResult.OK)
{
return;
}
if (ent is DBText)
{
((DBText)ent).TextString = "";
string[] temps = f.Res.text.Split('\n');
for (int i = 0; i < temps.Length; i++)
{
((DBText)ent).TextString += temps;
}
}
else if (ent is MText)
{
((MText)ent).Contents = f.Res.text;
}
}
}
// Helper class to workaround a Hashtable issue:
// Can't change values in a foreach loop or enumerator
class CBoolClass
{
public CBoolClass(bool val) { this.val = val; }
public bool val;
public override string ToString() { return (val.ToString()); }
}
///
/// DocManForUI.
///
public class DocManEvents
{
public DocManEvents()
{
Do();
}
public void Do()
{
try
{
DocumentCollection m_docMan = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
// Used to plant and remove Doc or DB events if applicable.
m_docMan.DocumentCreated += new DocumentCollectionEventHandler(callback_DocumentCreated);
m_docMan.DocumentToBeDestroyed += new DocumentCollectionEventHandler(callback_DocumentToBeDestroyed);
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
public void Undo()
{
try
{
DocumentCollection m_docMan = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
// Used to plant and remove Doc or DB events if applicable.
m_docMan.DocumentCreated -= new DocumentCollectionEventHandler(callback_DocumentCreated);
m_docMan.DocumentToBeDestroyed -= new DocumentCollectionEventHandler(callback_DocumentToBeDestroyed);
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
private void callback_DocumentCreated(Object sender, DocumentCollectionEventArgs e)
{
try
{
Document doc = e.Document;
EventsWatcher.documentCreated(ref doc);
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
private void callback_DocumentToBeDestroyed(Object sender, DocumentCollectionEventArgs e)
{
try
{
Document doc = e.Document;
EventsWatcher.documentToBeDestroyed(ref doc);
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
} // end of class DocManForUI
///
/// DocumentEvents.
///
public class DocumentEvents
{
public DocumentEvents()
{
m_bDone = false;
m_docsTable = new Hashtable();
collectAllDocs();
Do();
}
public void collectAllDocs()
{
try
{
DocumentCollection m_docCol = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
IEnumerator docEnum = m_docCol.GetEnumerator();
while (docEnum.MoveNext())
{
Document doc = (Document)docEnum.Current;
addDoc(ref doc);
}
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
public void addDoc(ref Document doc)
{
if (!m_docsTable.ContainsKey(doc))
m_docsTable.Add(doc, new CBoolClass(false));
}
public void removeDoc(ref Document doc)
{
if (m_docsTable.ContainsKey(doc))
{
UndoADoc(ref doc);
m_docsTable.Remove(doc);
}
}
private Document m_doc; // Used as a temporary var only.
private Hashtable m_docsTable; // Document(key)/bool(value) pair
private bool m_bDone; // A flag to indicate if events have been planted.
// A counterpart flag to the On option in the UI.
public void Do()
{
if (m_bDone == false)
m_bDone = true;
else // Don't return because we may need to address some new docs.
{ }
try
{
foreach (DictionaryEntry entry in m_docsTable)
{
CBoolClass boolClassVar = (CBoolClass)entry.Value;
// Continue if events have alrealy planted for the specific doc
if (boolClassVar.ToString().ToLower() == "true")
continue;
m_doc = (Document)entry.Key;
AcadDocument acadDoc = (AcadDocument)m_doc.AcadDocument;
acadDoc.BeginDoubleClick += new _DAcadDocumentEvents_BeginDoubleClickEventHandler(doc_BeginDoubleClick);
boolClassVar.val = true;
}
}
catch (System.Exception ex)
{
//Helper.ErrorMessage(ex);
}
}
public void Undo()
{
if (m_bDone == false)
return;
else
m_bDone = false;
try
{
IDictionaryEnumerator docsEnumerator = m_docsTable.GetEnumerator();
while (docsEnumerator.MoveNext())
{
DictionaryEntry entry = (DictionaryEntry)docsEnumerator.Current;
CBoolClass boolClassVar = (CBoolClass)entry.Value;
// Continue if events have alrealy been removed from the specific doc
if (boolClassVar.ToString().ToLower() == "false")
continue;
m_doc = (Document)entry.Key;
AcadDocument acadDoc = (AcadDocument)m_doc.AcadDocument;
acadDoc.BeginDoubleClick -= new _DAcadDocumentEvents_BeginDoubleClickEventHandler(doc_BeginDoubleClick);
boolClassVar.val = false;
}
}
catch (System.Exception ex)
{
//Helper.ErrorMessage(ex);
}
}
public void UndoADoc(ref Document doc)
{
try
{
if (!m_docsTable.Contains(doc))
return;
CBoolClass boolClassVar = (CBoolClass)m_docsTable[doc];
// Return if events have not been planted for it.
if (boolClassVar.ToString().ToLower() == "false")
return;
m_doc = doc;
AcadDocument acadDoc = (AcadDocument)m_doc.AcadDocument;
acadDoc.BeginDoubleClick -= new _DAcadDocumentEvents_BeginDoubleClickEventHandler(doc_BeginDoubleClick);
boolClassVar.val = false;
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
void doc_BeginDoubleClick(object PickPoint)
{
//Arx.Editor.WriteMessage("\ndouble click started!");
double[] pnt = (double[])PickPoint;
Point3d pickPoint = new Point3d(pnt[0], pnt[1], pnt[2]);
DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
DoubleClick.DoubleClickEdit(pickPoint);
docLock.Dispose();
}
} // end of class DocumentEvents
///
/// EventsWatcher.
///
public class EventsWatcher
{
public EventsWatcher()
{
}
// Static global event watchers
public static DocumentEvents m_docWatcher;
public static DocManEvents m_docManWatcher;
// Helper functions
public static void documentCreated(ref Autodesk.AutoCAD.ApplicationServices.Document doc)
{
if (m_docWatcher != null)
{
m_docWatcher.addDoc(ref doc);
m_docWatcher.Do();
}
}
public static void documentToBeDestroyed(ref Autodesk.AutoCAD.ApplicationServices.Document doc)
{
if (m_docWatcher != null)
{
m_docWatcher.removeDoc(ref doc);
}
}
public void StartEvent()
{
docManWatcherOnDuty();
docWatcherOnDuty();
}
private void docManWatcherOnDuty()
{
if (m_docManWatcher == null)
{
m_docManWatcher = new DocManEvents();
}
}
private void docWatcherOnDuty()
{
if (m_docWatcher == null)
{
m_docWatcher = new DocumentEvents();
}
}
}
///
/// Helper class including some static helper functions.
///
public class Helper
{
public static void StreamMessage(string str)
{
try
{
// Application.DocumentManager.Count should be used to check zero doc status
// MdiActiveDocument returns non null sometimes even if in zero doc status!
if ( AcadArxApp.DocumentManager.MdiActiveDocument != null
&& AcadArxApp.DocumentManager.Count != 0)
Helper.CmdLineMessage(str);
else
Helper.InfoMessageBox(str);
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
public static void ErrorMessage(System.Exception ex)
{
try
{
System.Windows.Forms.MessageBox.Show(
ex.ToString(),
"Error",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
catch
{
}
}
public static void InfoMessageBox(string str)
{
try
{
System.Windows.Forms.MessageBox.Show(
str,
"Events Watcher",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Information);
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
// Please check the valibility of Editor object before calling this.
public static void CmdLineMessage(string str)
{
try
{
if (AcadArxApp.DocumentManager.MdiActiveDocument != null
&& AcadArxApp.DocumentManager.Count != 0
&& AcadArxApp.DocumentManager.MdiActiveDocument.Editor != null)
{
AcadArxApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage(str);
}
else
return;
}
catch (System.Exception ex)
{
Helper.ErrorMessage(ex);
}
}
}
}