几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量  


返回   几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 » 仿射空间:CAX软件开发(三)二次开发与程序设计 » CAD二次开发 » AutoCAD二次开发 » ObjectARX(VB.NET/C#)
用户名
密码
注册 帮助 会员 日历 银行 搜索 今日新帖 标记论坛为已读


 
 
主题工具 搜索本主题 显示模式
旧 2009-04-29, 05:17 PM   #1
yang686526
高级会员
 
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
yang686526 向着好的方向发展
默认 【转帖】使用.net在在文档状态栏实现文档标签控件功能 - 精华帖集合

使用.net在在文档状态栏实现文档标签控件功能 - 精华帖集合
www.dimcax.com
使用.net在在文档状态栏实现文档标签控件功能
using autodesk.autocad.applicationservices;
using autodesk.autocad.databaseservices;
using system.collections.generic;
using system.windows.forms;
//支持程序后台关闭文档
namespace freefly.arx
{
public class docstatusbar
{
// 用于存储文档与按钮的对应关系
private class doclistnode
{
private int mindex; //按钮的顺序
private document mdoc; //对应的文档
public int index
{
get { return mindex; }
set { mindex = value; }
}
public document doc
{
get { return mdoc; }
set { mdoc = value; }
}
public doclistnode(int index, document doc)
{
mindex = index;
mdoc = doc;
}
}

// 用于存储文档集合的状态
private class doccollectionstatus
{
public static int doccount = 0; //已经打开的文档数目
public static int activedoc = 0; //当前活动的文档
}
private static bool isfirst = true; //记录该状态栏按钮是否第一次加载
//private static int maxcount = 7; //允许显示的最多细节数目,最后修改,增加锁定以保证稳定。
private static string firstpanename = "散步的木头"; //标志位显示的文本
private static int firstpanewidth = 30; //标志位的宽度
private static int panemaxwidth = 200; //按钮的最大宽度
private static int paneminwidth = 50; //按钮的最小宽度
private static int willdestroyeddoc = 0; //即将要关闭的文档
private static linkedlist<doclistnode> doclist = new linkedlist<doclistnode>();//将来修改为arraylist类型试试

// 增加每个文档的按钮
//应该在最前面那个标志按钮上加标志图像。
public static void mystatusbar()
{
if (isfirst)
{
autodesk.autocad.applicationservices.documentcollection doccollection = autodesk.autocad.applicationservices.application.documentmanager;
try
{
insertstatusbaritem(0, firstpanename, "", autodesk.autocad.windows.panestyles.noborders, firstpanewidth, firstpanewidth);//修改以使界面明朗
int i = 1;
foreach (document doc in doccollection)
{
autodesk.autocad.windows.panestyles mystyle;
if (doc.isactive == true)
{
mystyle = autodesk.autocad.windows.panestyles.normal;
doccollectionstatus.activedoc = i;
}
else
{
mystyle = autodesk.autocad.windows.panestyles.popout;
}
insertstatusbaritem(i, getfilename(doc.name), doc.name, mystyle, panemaxwidth, paneminwidth);
doclist.addlast(new doclistnode(i, doc));//doclist.addlast(curdoclistnode);//传递静态的变量会出错。
i += 1;
doccollectionstatus.doccount += 1;
doc.begindocumentclose += new documentbegincloseeventhandler(doc_begindocumentclose);
doc.database.savecomplete += new databaseioeventhandler(database_savecomplete);
}
doccollection.documentactivated += new documentcollectioneventhandler(doccollection_documentactivated);
doccollection.documentcreated += new documentcollectioneventhandler(doccollection_documentcreated);
doccollection.documentdestroyed += new documentdestroyedeventhandler(doccollection_documentdestroyed);
isfirst = false;
}
catch
{
messagebox.show("addstatusbartodoc方法中出错!");
}
}
}

// 在每个文档中增加一个按钮
private static void insertstatusbaritem(int index, string panetext, string panetooltiptext, autodesk.autocad.windows.panestyles mystyle, int maxwidth, int minwidth)
{
autodesk.autocad.applicationservices.documentcollection doccollection = autodesk.autocad.applicationservices.application.documentmanager;
try
{
foreach (document doc in doccollection)
{
autodesk.autocad.windows.statusbar mystatus = doc.statusbar;
autodesk.autocad.windows.panecollection docpanecolletion = mystatus.panes;
autodesk.autocad.windows.pane mypane = new autodesk.autocad.windows.pane();
mypane.style = mystyle;
mypane.maximumwidth = maxwidth;
mypane.minimumwidth = minwidth;
mypane.text = panetext;
mypane.tooltiptext = panetooltiptext;
mypane.mousedown += new autodesk.autocad.windows.statusbarmousedowneventhandler(statusbar_mousedown);
docpanecolletion.insert(index, mypane);
mystatus.update();
}
}
catch
{
messagebox.show("insertstatusbaritem方法中出错!");
}
}

// 新建打开文档
private static void doccollection_documentcreated(object sender, documentcollectioneventargs e)
{
autodesk.autocad.applicationservices.documentcollection doccollection = (autodesk.autocad.applicationservices.documentcollection)sender;
document curdoc = doccollection.mdiactivedocument;
try
{
#region 给新文档增加之前的按钮。
autodesk.autocad.windows.statusbar mystatus = curdoc.statusbar;
autodesk.autocad.windows.panecollection docpanecolletion = mystatus.panes;
autodesk.autocad.windows.pane mypane = new autodesk.autocad.windows.pane();
mypane.style = autodesk.autocad.windows.panestyles.noborders;
//先添加前面那个标志位按钮
mypane.maximumwidth = firstpanewidth;
mypane.minimumwidth = firstpanewidth;
mypane.text = firstpanename;
mypane.tooltiptext = "";
docpanecolletion.insert(0, mypane);
foreach (doclistnode mdoc in doclist)
{
//注意要重新初始变量,不能与前面共用一个变量,会引起引用同一个对象
mypane = new autodesk.autocad.windows.pane();
if (mdoc.index != doccollectionstatus.activedoc)
{
mypane.style = autodesk.autocad.windows.panestyles.popout;
}
else
{
mypane.style = autodesk.autocad.windows.panestyles.normal;
}
mypane.maximumwidth = panemaxwidth;
mypane.minimumwidth = paneminwidth;
mypane.text = getfilename(mdoc.doc.name);
mypane.tooltiptext = mdoc.doc.name;
mypane.mousedown += new autodesk.autocad.windows.statusbarmousedowneventhandler(statusbar_mousedown);
docpanecolletion.insert(mdoc.index, mypane);
}
mystatus.update();
#endregion
#region 在各文档增加新文档的按钮,并修改文档链表数据,设置新文档为当前文档。
doccollectionstatus.doccount += 1;
insertstatusbaritem(doccollectionstatus.doccount, getfilename(curdoc.name), curdoc.name, autodesk.autocad.windows.panestyles.popout, panemaxwidth, paneminwidth);
doclist.addlast(new doclistnode(doccollectionstatus.doccount, curdoc));
int lastdoc = doccollectionstatus.activedoc;
doccollectionstatus.activedoc = doccollectionstatus.doccount;
foreach (document doc in doccollection)
{
mystatus = doc.statusbar;
docpanecolletion = mystatus.panes;
docpanecolletion[lastdoc].style = autodesk.autocad.windows.panestyles.popout;
docpanecolletion[doccollectionstatus.activedoc].style = autodesk.autocad.windows.panestyles.normal;
mystatus.update();
}
curdoc.begindocumentclose += new documentbegincloseeventhandler(doc_begindocumentclose);
curdoc.database.savecomplete += new databaseioeventhandler(database_savecomplete);
#endregion
}
catch
{
messagebox.show("doccollection_documentcreated事件中出错!");
}
}

// 由选取菜单、打开、关闭文档而改变活动文档引起的事件处理,必须保证发生这个事件以前文档状态链表更新过。
private static void doccollection_documentactivated(object sender, documentcollectioneventargs e)
{
autodesk.autocad.applicationservices.documentcollection doccollection = autodesk.autocad.applicationservices.application.documentmanager;
document curdoc = autodesk.autocad.applicationservices.application.documentmanager.mdiactivedocument;
try
{
foreach (doclistnode mdoc in doclist)
{
if (mdoc.doc.equals(curdoc))
{
if (mdoc.index != doccollectionstatus.activedoc)
{
int lastdoc = doccollectionstatus.activedoc;
doccollectionstatus.activedoc = mdoc.index;
foreach (document doc1 in doccollection)
{
autodesk.autocad.windows.statusbar mystatus = doc1.statusbar;
autodesk.autocad.windows.panecollection docpanecolletion = mystatus.panes;
docpanecolletion[lastdoc].style = autodesk.autocad.windows.panestyles.popout;
docpanecolletion[doccollectionstatus.activedoc].style = autodesk.autocad.windows.panestyles.normal;
mystatus.update();
}
}
}
}
}
catch
{
messagebox.show("doccollection_documentactivated事件中出错!");
}
}

//包括正常关闭文档的事件,以及打开文档引起临时文档的关闭事件,注意在关闭最后一个文档时候的正确性。
//必须在这个事件中释放对要关闭的文档的引用,否则发生错误,另外注意索引的修改,防止地址越界。
private static void doc_begindocumentclose(object sender, documentbegincloseeventargs e)
{
autodesk.autocad.applicationservices.documentcollection doccollection = autodesk.autocad.applicationservices.application.documentmanager;
try
{
document curdoc = (document)sender;
doclistnode bedelnode = new doclistnode(0, null);
bool findit = false;
foreach (doclistnode mdoc in doclist)
{
if (mdoc.doc.equals(curdoc))
{
willdestroyeddoc = mdoc.index;
mdoc.doc = null;
bedelnode = mdoc;
findit = true;
}
else
{
if (findit)
{
mdoc.index -= 1;
}
}
}
doclist.remove(bedelnode);
autodesk.autocad.windows.statusbar mystatus;
foreach (document doc in doccollection)
{
mystatus = doc.statusbar;
autodesk.autocad.windows.panecollection docpanecolletion = mystatus.panes;
autodesk.autocad.windows.pane mypane = docpanecolletion[willdestroyeddoc];
mypane.mousedown -= new autodesk.autocad.windows.statusbarmousedowneventhandler(statusbar_mousedown);
mypane = null;
docpanecolletion.removeat(willdestroyeddoc);
mystatus.update();
}
doccollectionstatus.doccount -= 1;
mystatus = curdoc.statusbar;
for (int i = 0; i <= doccollectionstatus.doccount; i++)
{
mystatus.panes.removeat(0);
}
curdoc.database.savecomplete -= new databaseioeventhandler(database_savecomplete);
curdoc.begindocumentclose -= new documentbegincloseeventhandler(doc_begindocumentclose);
}
catch
{
messagebox.show("doc_begindocumentclose事件中出错!");
}
}

// 文档关闭已完成事件
private static void doccollection_documentdestroyed(object sender, documentdestroyedeventargs e)
{
autodesk.autocad.applicationservices.documentcollection doccollection = (documentcollection)sender;
autodesk.autocad.applicationservices.document curdoc = doccollection.mdiactivedocument;
try
{
foreach (doclistnode mdoc in doclist)
{
if (mdoc.doc.equals(curdoc))
{
doccollectionstatus.activedoc = mdoc.index;
foreach (document doc in doccollection)
{
doc.statusbar.panes[mdoc.index].style = autodesk.autocad.windows.panestyles.normal;
}
}
}
}
catch
{
messagebox.show("doccollection_documentdestroyed事件中出错!");
}
}

//鼠标命中状态栏文档的按钮引起的事件
private static void statusbar_mousedown(object sender, autodesk.autocad.windows.statusbarmousedowneventargs e)
{
autodesk.autocad.applicationservices.documentcollection doccollection = autodesk.autocad.applicationservices.application.documentmanager;
document curdoc = doccollection.mdiactivedocument;
autodesk.autocad.windows.pane willactivepane = (autodesk.autocad.windows.pane)sender;
autodesk.autocad.windows.panecollection mdipanecolletion = curdoc.statusbar.panes;
try
{
int lastdoc = 0;
for (int i = 1; i <= doccollectionstatus.doccount; i++)
if (mdipanecolletion.equals(willactivepane))
{
if (doccollectionstatus.activedoc != i)
{
lastdoc = doccollectionstatus.activedoc;
doccollectionstatus.activedoc = i;
}
}
if (lastdoc != 0)
{
foreach (doclistnode var in doclist)
{
if (var.index == doccollectionstatus.activedoc)
{
doccollection.mdiactivedocument = var.doc;//文档激活
}
}
foreach (document doc in doccollection)
{
autodesk.autocad.windows.statusbar mystatus = doc.statusbar;
autodesk.autocad.windows.panecollection docpanecolletion = mystatus.panes;
docpanecolletion[lastdoc].style = autodesk.autocad.windows.panestyles.popout;
docpanecolletion[doccollectionstatus.activedoc].style = autodesk.autocad.windows.panestyles.normal;
mystatus.update();
}
}
}
catch
{
messagebox.show("statusbar_mousedown事件中出错!");
}
}

//文档保存事件
private static void database_savecomplete(object sender, databaseioeventargs e)
{
try
{
autodesk.autocad.applicationservices.documentcollection doccollection = autodesk.autocad.applicationservices.application.documentmanager;
autodesk.autocad.databaseservices.database curdatabase = (autodesk.autocad.databaseservices.database)sender;
autodesk.autocad.windows.pane mypane;
foreach (doclistnode mdoc in doclist)
{
if (mdoc.doc.database.equals(curdatabase))
{
foreach (document doc in doccollection)
{
mypane = doc.statusbar.panes[mdoc.index];
mypane.text = getfilename(curdatabase.filename);
mypane.tooltiptext = curdatabase.filename;
doc.statusbar.update();
}
}
}
}
catch
{
messagebox.show("database_savecomplete事件中出错!");
}
}

// 提取文件名方法
private static string getfilename(string filename)
{
return filename.substring(filename.lastindexof("\\") + 1);
}
}
}
注意,只能使用于08以上版本。07的显示不出来!实现效果:
c#最适合开发autocad,因为它拥有vb容易的特点,却具有vc++的强大功能。
linkedlist是啥东东?编不过耶!
linkedlist是啥东东?编不过耶!
原帖由 azbd 于 2008-5-23 11:29 am 发表 linkedlist是啥东东?编不过耶!
是一个类似于list的类,有这个命名空间就可以了:system.collections.generic
c#最适合开发autocad,因为它拥有vb容易的特点,却具有vc++的强大功能。
不起作用
现在编译通过了,但是没有任何作用。我的cad为2009. 分析了一下程序,只定义了一个类。没有找到命令入口。
程序的入口是docstatusbar.mystatusbar();
这段程序在我的程序集里面是通过自动加载来运行的,入口需要你自己添加,你可以在初始化里面运行那个入口,或者自己在那个入口函数那儿定义命令。另外需要打开cad中的图形状态栏选项,请参考下图:
“散步的木头”的回答。在添加命令接口和打开图形状态栏后,能够显示,但不能用鼠标点击按钮来切换文档(没有任何动作),请指教。我是在cad2009中测试的。你说的自动加载是不是相当于netload命令。但还是要有地方调用mystatusbar()才行那!
我电脑上只有cad2008,不好意思,没有在2009上面测试过,应用到2009的话请确认那些事件在2009中能正常使用,不过按autodesk的版本发展计划,应该能通用,但可能两个版本的状态栏有一点微小的区别,也就是两个版本中缺省的状态栏里面的项目数量不一样,看懂我那个代码然后自己相应修改一下就行了,一般需要修改的可能只有一行代码。自动加载是给类定义iextensionapplication接口,然后initialize()方法中调用那个入口,再netload得时候就能自动运行。具体示例可以参考kean的有关文章。 [ ]
好多朋友反映入口的问题,我把完整的文件发上来,不过在2009下使用的问题我现在还解决不了,我电脑上只有2008,没法调试,希望大家见谅!~ 这个为修改以后的代码!
yang686526离线中   回复时引用此帖
GDT自动化论坛(仅游客可见)
 


主题工具 搜索本主题
搜索本主题:

高级搜索
显示模式

发帖规则
不可以发表新主题
不可以回复主题
不可以上传附件
不可以编辑您的帖子

vB 代码开启
[IMG]代码开启
HTML代码关闭



所有的时间均为北京时间。 现在的时间是 06:13 AM.


于2004年创办,几何尺寸与公差论坛"致力于产品几何量公差标准GD&T | GPS研究/CAD设计/CAM加工/CMM测量"。免责声明:论坛严禁发布色情反动言论及有关违反国家法律法规内容!情节严重者提供其IP,并配合相关部门进行严厉查处,若內容有涉及侵权,请立即联系我们QQ:44671734。注:此论坛须管理员验证方可发帖。
沪ICP备06057009号-2
更多