.NET

Reply
Valued Contributor
netcai
Posts: 66
Registered: ‎07-22-2004
Message 1 of 16 (376 Views)

strange problem of double click event

376 Views, 15 Replies
06-27-2005 06:26 AM
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);
}
}

}

}
Valued Contributor
netcai
Posts: 66
Registered: ‎07-22-2004
Message 2 of 16 (376 Views)

Re: strange problem of double click event

06-30-2005 12:14 AM in reply to: netcai
no body help me?
*Albert Szilvasy
Message 3 of 16 (376 Views)

Re: strange problem of double click event

06-30-2005 02:33 PM in reply to: netcai
This seems to work fine form me:

public class TestDoubleClick
{
Autodesk.AutoCAD.Interop.AcadDocument m_doc;
[CommandMethod("testdblclick")]
public void DoIt()
{
if (m_doc == null)
{
m_doc =
(Autodesk.AutoCAD.Interop.AcadDocument)AcadApp.DocumentManager.MdiActiveDocument.AcadDocument;
m_doc.BeginDoubleClick+=new
_DAcadDocumentEvents_BeginDoubleClickEventHandler(m_doc_BeginDoubleClick);
AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Double
click event is now hooked.");
}
else
{

m_doc.BeginDoubleClick-=new
_DAcadDocumentEvents_BeginDoubleClickEventHandler(m_doc_BeginDoubleClick);
m_doc = null;
AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Double
click event is now unhooked.");
}
}
class MTextEditor : Form
{
TextBox m_textBox;
public MTextEditor()
{
m_textBox = new TextBox();
this.SuspendLayout();
m_textBox.Location = new System.Drawing.Point(0, 0);
m_textBox.Name = "textBox";
m_textBox.TabIndex = 0;
m_textBox.Multiline = true;
m_textBox.Dock = DockStyle.Fill;

ClientSize = new System.Drawing.Size(100, 100);
Controls.Add(this.m_textBox);
Name = "MTextEditor";
Text = "MText Editor";
this.ResumeLayout(false);
}
public string Contents
{
get {return m_textBox.Text;}
set {m_textBox.Text = value;}
}
}
private void m_doc_BeginDoubleClick(object PickPoint)
{
Document activeDoc = AcadApp.DocumentManager.MdiActiveDocument;
//get the object that the user has selected
PromptSelectionResult res = activeDoc.Editor.SelectImplied();
if (res.Status != PromptStatus.OK)
return;
if (res.Value.Count != 1)
return; //we don't handle multiple selected objects
ObjectId idSel = res.Value[0].ObjectId;
using (DocumentLock docLock = activeDoc.LockDocument())
{
using (Transaction trans =
activeDoc.TransactionManager.StartTransaction())
{
DBObject obj = trans.GetObject(idSel,OpenMode.ForWrite);
MText text = obj as MText;
if (text == null)
return; //not an mtext
using (MTextEditor form = new MTextEditor())
{
form.Contents = text.Contents;
AcadApp.ShowModalDialog(form);
text.Contents = form.Contents;
}
trans.Commit();
}
}
}
}
wrote in message news:4889347@discussion.autodesk.com...
no body help me?
Valued Contributor
netcai
Posts: 66
Registered: ‎07-22-2004
Message 4 of 16 (376 Views)

Re: strange problem of double click event

06-30-2005 06:14 PM in reply to: netcai
Albert, thanks very much.
your code works well, but I don't understanding why my code doesn't work. Our code's difference is : I use a static method,you use a instance method.
Valued Contributor
netcai
Posts: 66
Registered: ‎07-22-2004
Message 5 of 16 (376 Views)

Re: strange problem of double click event

06-30-2005 08:01 PM in reply to: netcai
one more question:
after I run my double click event, the dited object is highlighted, my question is how to make it unhighlighted,otherwise I must press twice esc key.
Valued Contributor
netcai
Posts: 66
Registered: ‎07-22-2004
Message 6 of 16 (376 Views)

Re: strange problem of double click event

06-30-2005 09:32 PM in reply to: netcai
Albert, when I run your code, it works fine ,but when autocad exit, a error messagebox appeare, it shows "Unhandled Exception E0434F4D(e0434f4dh)" at address 7C81EB33h
*Albert Szilvasy
Message 7 of 16 (376 Views)

Re: strange problem of double click event

07-01-2005 08:44 AM in reply to: netcai
Did you run unhooked the even before exiting (by running the command again)?

Albert
wrote in message news:4890685@discussion.autodesk.com...
Albert, when I run your code, it works fine ,but when autocad exit, a error
messagebox appeare, it shows "Unhandled Exception E0434F4D(e0434f4dh)" at
address 7C81EB33h
*Albert Szilvasy
Message 8 of 16 (376 Views)

Re: strange problem of double click event

07-01-2005 08:49 AM in reply to: netcai
Frankly, if you want to replace the mtext editor then I wouldn't approach
the problem this way: why don't you redefine the mtedit command like this?
[CommandMethod("mtedit")]

public void DoIt2()

{

AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("My mtedit
command.");

}

It would be much simpler and more reliable.

Albert

wrote in message news:4890663@discussion.autodesk.com...
one more question:
after I run my double click event, the dited object is highlighted, my
question is how to make it unhighlighted,otherwise I must press twice esc
key.
Valued Contributor
netcai
Posts: 66
Registered: ‎07-22-2004
Message 9 of 16 (376 Views)

Re: strange problem of double click event

07-01-2005 06:18 PM in reply to: netcai
1. If I redefine mtedit command , I can't get the object on pickpoint use SelectImplied() method. and more I can't redefine ddedit command, my aids is to hanle all the objects double click event.
2. yes, I run the command again, but the error still exit.
*Albert Szilvasy
Message 10 of 16 (376 Views)

Re: strange problem of double click event

07-01-2005 09:45 PM in reply to: netcai
1. You have to specify CommandFlags.UsePickSet like in:
[CommandFlags("mtedit", CommandFlags.Modal | CommandFlags.UsePickSet]
Why can't you redefine the ddedit command? You must undefine it first
because it is a built in command but you should be able to supply your own.

2. I can't reproduce this. I'm not sure what else you have going on in your
environment.

Albert

wrote in message news:4891655@discussion.autodesk.com...
1. If I redefine mtedit command , I can't get the object on pickpoint use
SelectImplied() method. and more I can't redefine ddedit command, my aids
is to hanle all the objects double click event.
2. yes, I run the command again, but the error still exit.
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.