.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

strange problem of double click event

15 REPLIES 15
Reply
Message 1 of 16
netcai
718 Views, 15 Replies

strange problem of double click event

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);
}
}

}

}
15 REPLIES 15
Message 2 of 16
netcai
in reply to: netcai

no body help me?
Message 3 of 16
Anonymous
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?
Message 4 of 16
netcai
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.
Message 5 of 16
netcai
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.
Message 6 of 16
netcai
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
Message 7 of 16
Anonymous
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
Message 8 of 16
Anonymous
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.
Message 9 of 16
netcai
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.
Message 10 of 16
Anonymous
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.
Message 11 of 16
netcai
in reply to: netcai

Maybe I don't state clearly, I means I can't change autocad default double click command (ddedit,eattedit,refedit..) )with my command, because
1. autocad alway use .ddedit to response double click event, so my ddedit doesn't work.
2. I can redefine eattedit and refedit, I also use CommandFlags.UsePickSet flag as you say , but again SelectImplied() get nothing object.
Message 12 of 16
netcai
in reply to: netcai

I think the best way to realize custom double click command is to use double click event , but as I say befor, the problem is after finish my own command , the object edited is still highlighted and selected , and I must press "esc" key twice to continue my next work.
Message 13 of 16
Anonymous
in reply to: netcai

To use the current selection set in a command, you need
to include CommandFlags.UsePickSet in your command
handler's CommandMethod attribute:

[CommandMethod("YOURCOMMAND", CommandFlags.UsePickSet)]

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006
http://www.acadxtabs.com

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.
Message 14 of 16
netcai
in reply to: netcai

tony , I can redefine eattedit and refedit, I also use CommandFlags.UsePickSet flag as you say , but SelectImplied() get nothing object.
Message 15 of 16
Anonymous
in reply to: netcai

I'm not sure what you are doing. This seems to work fine for me.

Albert

wrote in message news:4891851@discussion.autodesk.com...
tony , I can redefine eattedit and refedit, I also use
CommandFlags.UsePickSet flag as you say , but SelectImplied() get nothing
object.
Message 16 of 16
netcai
in reply to: netcai

thanks, Albert. you are really a good man, with your help , I learn many useful things.
I have solved my problem of double click event. through calling a command(my own unhighlight method ) with SendStringToExecute method after my own double click event, I can unhighlight the object edited sucessfully.

but as you suggest , I can call my own double click command through redefine all commands related to double click , I trid ,but only mtext works, others command doesn't work.

when I undefine ddedit command in my lisp,autocad default ddedit command doesn't work in autocad if I directly run ddedit in command line, instead my own ddedit run , but when I double click a text, autocad will run its internal command .ddedit, not run ddedit,so my own ddedit command doesn't work in double click event through this method.

I can redefine eattedit and refedit, I also use CommandFlags.UsePickSet flag as you say , but again SelectImplied() get nothing object.

thanks again .

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost