赞
踩
一个软件公司里面都有自己的通用库,它主要分为全产品通用和类似产品通用。
数据当然是项目或产品的重中之重,总体而言cad的数据中可分为外观、工程量。

自定义实体主要是为了数据安全、更为复杂的交互等而设计。通常我们都会以继承AcDbEntity而设计。在一个产品中,我们必须做个产品虚基类实体。比如DaveEntity,然后从该实体继承我们其他有意义的实体。它主要用来记录一些通用数据和方便我们做程序处理的。
OMF的设计上BricsCAD在sdk上提供了C++的类,而AutoCAD还是主要以COM的形式提供。有时感慨AutoDesk不思进取,估计力量都投到Revit或其他产品上面去了。从这里看一看出BricsCAD非常适合C++开发,从Ribbon、OMF都提供了接口。
这和具体业务相关,也较为简单,总之一切要以生成报表预算为准则去设计。
包括用户、工程量、权限、单价等各种数据的提供通常是数据库,由于这里不考虑直连,之前也分析过要离线设计,所以分为网络、和本地加密文件(或加密狗)两种方式。在设计框架的时候就要考虑数据提供的问题。
template<IProvider::ModelType type,typename TProvider = IProvider> class DataProviderBase { public: DataProviderBase() : type_(type), provider_(nullptr) { static_assert(std::is_base_of<IProvider, TProvider>::value, "provider type error"); } virtual ~DataProviderBase() = default; public: virtual IProvider::ModelType GetModelType() const { return type_; } virtual IProvider* GetProvider() { if (provider_== nullptr) { provider_= dynamic_cast<TProvider *>(CreateProvider()); if (provider_!= nullptr) provider_->SetPlugin(this); } return provider_; } protected: virtual CContainerUI* CreateProvider() = 0; protected: IProvider::ModelType type_; TProvider* provider_; };
数据提供者网络部分的实现,大概如下:
class UserCloudProvider : public IProvider
{
public:
UserCloudProvider() : type_(kDataFromCloud){
}
~UserCloudProvider() = default;
protected:
ModelType type_;
}
数据提供者本地部分的实现,大概如下:
class UserLocalProvider : public IProvider
{
public:
UserLocalProvider () : type_(kDataFromLocal){
}
~UserLocalProvider () = default;
protected:
ModelType type_;
}
这些源码只 进行思路分析。另外本地文件加密要慎之又慎,需要多重加密以确保安全。
“芙蓉不及美人妆,水殿风来珠翠香”。外观就是把各种数据展示给客户,精确且惊艳为最佳。

Ribbon的实现在AutoCAD例子中基本都是.Net源码,而在BricsCAD的官方例子中则是使用了C++接口。我们可以统一成.Net功能,但BricsCAD中可能加载较慢,影响体验,所以还是统一成C++。有关Ribbon的C#核心代码(网上例子超多,这里还是要充分考虑别用明确的AutoDesk.AutoCAD命名空间,因为我们还要支持其他CAD呢):
// 声明需要添加的Ribbon Tab页 _AcWnd1.RibbonControl ribbonControl = _AcWnd1.ComponentManager.Ribbon; _AcWnd1.RibbonTab Tab = new _AcWnd1.RibbonTab(); Tab.Title = "蚺城疯子软件"; Tab.Id = "RibbonTest_ID"; ribbonControl.Tabs.Add(Tab); // 创建新的Panel var panel1Panel = new _AcWnd1.RibbonPanelSource(); panel1Panel.Title = "图层管理"; var Panel1 = new _AcWnd1.RibbonPanel(); Panel1.Source = panel1Panel; Tab.Panels.Add(Panel1); // 添加按钮到Panel中 string ribbon_path = MyMgd.Utils.GetStartPath() + @"skin\image\ribbon\"; Bitmap img1_16 = new Bitmap(ribbon_path + "button1_16.png"), img1_32 = new Bitmap(ribbon_path + "button1_32.png"), img2_16 = new Bitmap(ribbon_path + "button2_16.png"), img2_32 = new Bitmap(ribbon_path + "button2_32.png"); var pan1btnAddLayers = NewRibbonButton("添加图层", "AddLayer ", img1_16, img1_32); var pan1btnEraseLayers = NewRibbonButton("允许导出", "Export ", img2_16, img2_32); var pan1row1 = new _AcWnd1.RibbonRowPanel(); pan1row1.Items.Add(pan1btnEraseLayers); pan1row1.Items.Add(new _AcWnd1.RibbonRowBreak()); panel1Panel.Items.Add(pan1btnAddLayers); panel1Panel.Items.Add(new _AcWnd1.RibbonSeparator()); panel1Panel.Items.Add(pan1row1);

一般是停靠在左侧,如天正系列的设计软件。在开发过程中还需要考虑高DPI的支持,由于我屏幕是2.5K,所以天正的字体在我这里会显得很小,或许客户的屏幕是4K,那估计就小得没法正常操作了。之后的交互UI同样要注意高分辨率屏幕的问题。
一个项目中,使用到的界面会非常的多,我们要事先考虑那些是共有的,提出来,我们事先做好UI的拆分。譬如列表格式、表格样式、属性界面等等。

预览控件其实也是交互UI的一种,但实现方式多种多样,可简可繁,下一章将会详细讨论。复杂功能应当有如下:
基础库或者基础框架总是要有人使用才会丰富、进化而变得更为实用,本章只提供大概思路。一个好的通用库可以大大的提升团队的开发 效率。
这些框架的东西没怎么细讲,否则每个环节都要花大篇幅的设计和源码,那就失去了重点。
之后就是每个具体功能的详细记录、分析、探讨——预览控件,从C++和C#、AutoCAD和BricsCAD多个方面来讨论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。