一、转换类
- 功能:显式转换不同数据类型
- 筛选器Other中添加(第(三)篇文件结构为基础)
- ConvertUtil.h
#pragma once class ConvertUtil { public: ConvertUtil(); ~ConvertUtil(); public: // 2d点转换为3d点 static AcGePoint3d ToPoint3d(const AcGePoint2d& pt, double z = 0); // 3d点转换为2d点 static AcGePoint2d ToPoint2d(const AcGePoint3d& pt); // 角度转弧度 static double AngleToRadian(double angle); // 弧度转角度 static double RadianToAngle(double rad); // 整型转字符串(需要支持MFC) static CString ToString(int val); // 点坐标系转换:世界坐标系wcs->显示坐标系dcs static AcGePoint3d WcsPointToDcsPoint(const AcGePoint3d &point); // 点坐标系转换:用户坐标系ucs->世界坐标系wcs static AcGePoint3d UcsPointToWcsPoint(const AcGePoint3d &point); // 点坐标系转换:世界坐标系wcs->用户坐标系ucs static AcGePoint3d WcsPointToUcsPoint(const AcGePoint3d &point); };
- ConvertUtil.cpp
#include "stdafx.h" #include "ConvertUtil.h" #include "MathUtil.h" ConvertUtil::ConvertUtil(){} ConvertUtil::~ConvertUtil(){} // 2d点转换为3d点 AcGePoint3d ConvertUtil::ToPoint3d(const AcGePoint2d& pt, double z) { return AcGePoint3d(pt.x, pt.y, z); } // 3d点转换为2d点 AcGePoint2d ConvertUtil::ToPoint2d(const AcGePoint3d& pt) { return AcGePoint2d(pt.x, pt.y); } // 角度转弧度 double ConvertUtil::AngleToRadion(double angle) { return angle * MathUtil::PI() / 180; } // 弧度转角度 double ConvertUtil::RadionToAngle(double rad) { return rad * 180 / MathUtil::PI(); } // 整型转字符串(需要支持MFC) CString ConvertUtil::ToString(int val) { CString str; str.Format(_T("%d"), val); return str; } // 点坐标系转换:世界坐标系wcs->显示坐标系dcs AcGePoint3d ConvertUtil::WcsPointToDcsPoint(const AcGePoint3d &point) { AcGePoint3d pt; struct resbuf rbFrom, rbTo; rbFrom.restype = RTSHORT; rbFrom.resval.rint = 0; rbTo.restype = RTSHORT; rbTo.resval.rint = 2; // 坐标系转换函数:wcs坐标、wcs标识符(0)、dcs标识符(2)、类型为点(0)、dcs坐标 acedTrans(asDblArray(point), &rbFrom, &rbTo, 0, asDblArray(pt)); return pt; } // 点坐标系转换:用户坐标系ucs->世界坐标系wcs AcGePoint3d ConvertUtil::UcsPointToWcsPoint(const AcGePoint3d &point) { AcGePoint3d pt; struct resbuf rbFrom, rbTo; rbFrom.restype = RTSHORT; rbFrom.resval.rint = 1; rbTo.restype = RTSHORT; rbTo.resval.rint = 0; // 坐标系转换函数:ucs坐标、ucs标识符(1)、wcs标识符(0)、类型为点(0)、wcs坐标 acedTrans(asDblArray(point), &rbFrom, &rbTo, 0, asDblArray(pt)); return pt; } // 点坐标系转换:世界坐标系wcs->用户坐标系ucs AcGePoint3d ConvertUtil::WcsPointToUcsPoint(const AcGePoint3d &point) { AcGePoint3d pt; struct resbuf rbFrom, rbTo; rbFrom.restype = RTSHORT; rbFrom.resval.rint = 0; rbTo.restype = RTSHORT; rbTo.resval.rint = 1; // 坐标系转换函数:wcs坐标、ucs标识符(1)、wcs标识符(0)、类型为点(0)、ucs坐标 acedTrans(asDblArray(point), &rbFrom, &rbTo, 0, asDblArray(pt)); return pt; }
二、数学计算类
- 功能:涉及到数学类的计算
- Other筛选器中添加(第(三)篇文件结构为基础)
- MathUtil.h
#pragma once class MathUtil { public: MathUtil(); ~MathUtil(); // 定义派值 static double PI(); // 判断两个双精度浮点数是否相等 static bool IsEqual(double a, double b, double tol = 1.0E-7); };
- MathUtil.cpp
#include "stdafx.h" #include "MathUtil.h" MathUtil::MathUtil(){} MathUtil::~MathUtil(){} // 定义派值 double MathUtil::PI() { // 数学求派的精确方法 return atan(1.0) * 4; } // 判断两个双精度浮点数是否相等,因为浮点数都是近似存储 bool MathUtil::IsEqual(double a, double b, double tol /* = 1.0E-7 */) { // 当两个浮点数的差小于10E-7,则判定两个浮点数相等 return (fabs(a - b) < tol); }
三、几何计算类
- Geometry筛选器中添加(第(三)篇文件结构为基础)
- Geometry.h
#pragma once class Geometry { public: Geometry(); ~Geometry(); public: // 算两点中点:下面是2d点和3d点重载 static AcGePoint2d GetMiddlePoint(const AcGePoint2d &startPt, const AcGePoint2d &endPt); static AcGePoint3d GetMiddlePoint(const AcGePoint3d &startPt, const AcGePoint3d &endPt); // 计算相对坐标:传入基准坐标pt、x偏移量、y偏移量 static AcGePoint3d RelativePoint(const AcGePoint3d &pt, double x, double y); };
- Geometry.cpp
#include "stdafx.h" #include "Geometry.h" Geometry::Geometry(){} Geometry::~Geometry(){} AcGePoint2d Geometry::GetMiddlePoint(const AcGePoint2d &startPt, const AcGePoint2d &endPt) { // 这是提取2d点的三个坐标值,为double类型 double x = (startPt.x + endPt.x) *0.5; double y = (startPt.y + endPt.y) *0.5; return AcGePoint2d(x, y); } AcGePoint3d Geometry::GetMiddlePoint(const AcGePoint3d &startPt, const AcGePoint3d &endPt) { // 这是提取3d点的三个坐标值,为double类型 double x = (startPt.x + endPt.x) *0.5; double y = (startPt.y + endPt.y) *0.5; double z = (startPt.z + endPt.z) *0.5; return AcGePoint3d(x, y, z); } AcGePoint3d Geometry::RelativePoint(const AcGePoint3d &pt, double x, double y) { AcGePoint3d ptReturn(pt.x + x, pt.y + y, pt.z); return ptReturn; }
四、字符串工具类
4.1 类定义
- Other筛选器中添加(第(三)篇文件结构为基础)
- StringUtil.h
#pragma once #include <vector> class StringUtil { public: StringUtil(); ~StringUtil(); // 分割字符串:传入字符串、分割符、接收分割后的字符串容器、分隔符间允许包含空字符(默认) static void Split(const CString &text, const ACHAR *separator, std::vector<CString>&result, bool bAddEmptyStr = true); // 合并字符串:传入字符串容器、分隔符,返回合并的字符串 static CString Join(const std::vector<CString> &items, const ACHAR *spearator); };
- StringUtil.cpp
#include "stdafx.h" #include "StringUtil.h" StringUtil::StringUtil(){} StringUtil::~StringUtil(){} // 分割字符串:传入字符串、分割符、接收分割后的字符串容器、是否允许包含空字符 void StringUtil::Split(const CString &text, const ACHAR *separator, std::vector<CString>&result, bool bAddEmptyStr ) { // 前一个索引号、当前索引号 int prev = 0, current = 0; // 将传入的字符串深拷贝一个副本 CString strCopyTxt = text; // 删除字符串右侧的空字符 strCopyTxt.TrimRight(_T(" ")); // 如果没找到分隔符:未找到返回-1,Find见下注释 if (strCopyTxt.Find(separator, 0) < 0) { // 如果传入的字符串有长度 if (strCopyTxt.GetLength() > 0) { // 整个字符串就是唯一的分割字符串,添加进字符串容器 result.push_back(strCopyTxt); } // 如果传入的字符串长度为0,啥也不添加 return; } // 以下为至少发现一个分隔符 // 获得字符串总长度 int length = strCopyTxt.GetLength(); bool bExit = false; // 开启无限循环:注意循环中的break语句 while (true) { // prev为起始索引值,迭代的关键,Find见下注释 current = strCopyTxt.Find(separator, prev); // 循环到最后一个待分割字符串,之后无分隔符 if (current == -1) { // 将整个字符串长度赋值current,标识退出变量为真 current = length; bExit = true; } // 取最后一个分隔符到结尾的字符串,Mid见下注释 CString item = strCopyTxt.Mid(prev, current - prev); // 添加进容器的条件:每个提取的子字符串是否过滤0长度 if (bAddEmptyStr || item.GetLength() > 0) result.push_back(item); // 判断退出条件 if (bExit) break; // 更新Find函数的起始索引值,要包含分隔符,否则如 1,,2 会成死循环 CString sep = separator; prev = current + sep.GetLength(); } } // 合并字符串:传入字符串容器、分隔符,返回合并的字符串 CString StringUtil::Join(const std::vector<CString> &items, const ACHAR *spearator) { CString strResult; // 逐个拼接容器中的字符串 for (int i = 0; i < items.size(); i++) { strResult += items.at(i) + spearator; } // 删除右侧的空字符 strResult.TrimRight(spearator); // 返回拼接好的字符串 return strResult; }
4.2 测试代码
- Commands.h
#include "StdAfx.h" void AddCommands(); void Seperate(); void Unit();
- Commands.cpp
#include "StdAfx.h" #include "Commands.h" #include "Editor.h" #include "StringUtil.h" void AddCommands() { // 分割字符串 Editor::AddCommand(L"Seperate", ACRX_CMD_MODAL, Seperate); // 合并字符串 Editor::AddCommand(L"unit", ACRX_CMD_MODAL, Unit); } void Seperate() { std::vector<CString> lines; ACHAR line[128]; ACHAR separator[10]; if (acedGetString(NULL, _T("\n请输入待分割内容:"), line) != RTNORM) { return; } if (acedGetString(NULL, _T("\n请输入分隔符:"), separator) == RTNORM) { CString str = line; StringUtil::Split(str, separator, lines); } for (int i = 0; i < lines.size(); i++) { acutPrintf(lines.at(i)); acutPrintf(_T("\n")); } acutPrintf(_T("%d"), lines.size()); } void Unit() { std::vector<CString> lines; ACHAR line[128]; while (acedGetString(NULL, _T("\n请输入待组合内容:"), line)== RTNORM) { CString temp = line; if (temp == _T("exit")) break; lines.push_back(line); } CString unitline = StringUtil::Join(lines, _T(",")); acutPrintf(unitline); }
五、文件操作类
5.1 类定义
- IO筛选器中添加(第(三)篇文件结构为基础)
- TextFileUtil.h
#pragma once #include <vector> class TextFileUtil { public: TextFileUtil(); ~TextFileUtil(); // 覆盖式存到文件:文件名(绝对路径)、接收CString字符串容器 static void ToFile(const ACHAR *fileName, const std::vector<CString>&lines); // 从文件读取:文件名(绝对路径)、输出CString字符串容器 static bool FromFile(const ACHAR *fileName, std::vector<CString>&lines); // 通过对话框选择获取文件绝对路径(多选) static bool SelectFilePath(CStringArray & fileNameArray); };
- TextFileUtil.cpp
#include "stdafx.h" #include "TextFileUtil.h" TextFileUtil::TextFileUtil(){} TextFileUtil::~TextFileUtil(){} // 覆盖式存到文件:文件名(绝对路径)、接收CString字符串容器 void TextFileUtil::ToFile(const ACHAR *fileName, const std::vector<CString>&lines) { // 以下是支持MFC才有的,相当于open函数功能 CStdioFile file(fileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText); // 逐个读取容器中的字符串,并在每个字符串后面加换行符 for (int i = 0; i < lines.size(); i++) { file.WriteString(lines.at(i)); file.WriteString(_T("\n")); } file.Close(); } // 从文件读取:文件名(绝对路径)、输出CString字符串容器 bool TextFileUtil::FromFile(const ACHAR *fileName, std::vector<CString>&lines) { // 纠错函数:如果文件不存在打印 if (PathFileExists(fileName) != TRUE) { acutPrintf(_T("\n文件不存在!")); return false; } else { // 首先格式化容器 lines.clear(); // 以读的方式打开文件 CStdioFile file(fileName, CFile::modeRead | CFile::typeText); CString strLine; // 只要读取成功,就循环读每一行 while (file.ReadString(strLine)) { // 将每一行添加到CString字符串容器 lines.push_back(strLine); } return true; } } // 通过对话框选择获取文件绝对路径(多选):一些MFC语句,了解即可,重点看注释语句 bool TextFileUtil::SelectFilePath(CStringArray & fileNameArray) { // 构建文件过滤器 CNavFilter *filter; // 过滤的注释 LPCTSTR filterDesc[] = { _T("可选文件格式"), NULL }; // 过滤的后缀名:可以在null前增加后缀 LPCTSTR filterDWG[] = { _T("*.dwg"),_T("*.dxf"), NULL }; LPCTSTR *filterSpec[] = { filterDWG, NULL }; CNavFilterArray gFilterArray; gFilterArray.RemoveAllData(); int i = 0, j; while (filterSpec[i] != NULL) { filter = gFilterArray.AddData(); if (filter != NULL) { filter->SetDescription(filterDesc[i]); j = 0; while (filterSpec[i][j] != NULL) { filter->Add(filterSpec[i][j]); j++; } } i++; } fileNameArray.RemoveAll(); CNavDataArray gDataArray; while (true) { // 获取autoCAD的窗口句柄 HWND acadhandle = adsw_acadMainWnd(); // 使句柄成为当前窗口 ::EnableWindow(acadhandle, true); // 设置焦点 ::SetFocus(acadhandle); // 获取MFC的主窗口 CWnd *pWnd = CWnd::FromHandle(acadhandle); CAcUiNavDialog dlg(gDataArray, gFilterArray, 0, pWnd); // 开启多选模式 dlg.SetMultiSelectAllowed(true); // 对话框标题 dlg.SetDialogCaption(_T("多选对话框")); // 设置当前点选的文件可见缩略图 dlg.SetPreviewPresent(true); dlg.SetPreviewVisible(true); // 如果点选了确认按钮 if (dlg.DoModal() == IDOK) { for (int i = 0; i < gDataArray.GetCount(); i++) { LPITEMIDLIST id = gDataArray.GetAt(i)->GetID(); // 获取并打印:每个选择到的 文件绝对路径 的 字符串 fileNameArray.Add(gDataArray.GetAt(i)->GetText()); } } // 跳出循环 break; } if (fileNameArray.GetCount() > 0) return true; else return false; }
5.2 测试代码
- Commands.h
#include "StdAfx.h" void AddCommands(); void ToFile(); void FromFile(); void SelectFile();
- Commands.cpp
#include "StdAfx.h" #include "Commands.h" #include "Editor.h" #include "TextFileUtil.h" void AddCommands() { // 输出到桌面文件 Editor::AddCommand(L"tofile", ACRX_CMD_MODAL, ToFile); // 从桌面文件输入 Editor::AddCommand(L"fromfile", ACRX_CMD_MODAL, FromFile); // 打印选择文件路径 Editor::AddCommand(L"showpath", ACRX_CMD_MODAL, SelectFile); } void ToFile() { std::vector<CString> lines; ACHAR line[128]; while (acedGetString(NULL, _T("\n请输入行内容:"), line) == RTNORM) { CString str = line; lines.push_back(str); } TextFileUtil::ToFile(_T("C:\\Users\\Administrator\\Desktop\\test.txt"), lines); } void FromFile() { std::vector<CString> lines; // 包含纠错函数:打开失败情况 TextFileUtil::FromFile(_T("C:\\Users\\Administrator\\Desktop\\test.txt"), lines); for (int i = 0; i < lines.size() ; i++) { acutPrintf(lines.at(i)); acutPrintf(_T("\n")); } } void SelectFile() { CStringArray fileNamePath; bool isseletct = TextFileUtil::SelectFilePath(fileNamePath); if (!isseletct) { return; } // 遍历cstringArray每一项 for (int i = 0; i < fileNamePath.GetCount(); i++) { // Cstring定位和打印方法 CString filepath = fileNamePath.GetAt(i); acutPrintf(_T("\n文件路径为:%s"), filepath); } }
- showpath命令效果