# 专用功能界面 **本文档引用的文件** - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp) - [CCrossHoleConfig3DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig3DMainDlg.cpp) - [COption2DGeometryDlg.cpp](file://cpp/crossHole/COption2DGeometryDlg.cpp) - [COption3DGeometryDlg.cpp](file://cpp/crossHole/COption3DGeometryDlg.cpp) - [CDialogLoggingWnd.cpp](file://cpp/logging/CDialogLoggingWnd.cpp) - [CDialogLoggingParameterSetting.cpp](file://cpp/logging/CDialogLoggingParameterSetting.cpp) - [CDialogLoggingLithologicWnd.cpp](file://cpp/logging/CDialogLoggingLithologicWnd.cpp) - [CDragListCtrl.cpp](file://cpp/ctrl/CDragListCtrl.cpp) - [CListTextColorCtrl.cpp](file://cpp/ctrl/CListTextColorCtrl.cpp) - [CCrosshole2dDrawingBoardDlg.cpp](file://cpp/crossHole/CCrosshole2dDrawingBoardDlg.cpp) ## 目录 1. [引言](#引言) 2. [跨孔测量配置对话框设计](#跨孔测量配置对话框设计) 3. [几何参数设置逻辑](#几何参数设置逻辑) 4. [测井功能用户界面实现](#测井功能用户界面实现) 5. [自定义控件绘制与交互机制](#自定义控件绘制与交互机制) 6. [专用UI与后台算法协同工作](#专用ui与后台算法协同工作) 7. [自定义控件消息处理与重绘逻辑](#自定义控件消息处理与重绘逻辑) 8. [复杂参数配置验证与默认值管理](#复杂参数配置验证与默认值管理) 9. [跨孔测量与测井功能操作流程](#跨孔测量与测井功能操作流程) 10. [自定义控件扩展最佳实践](#自定义控件扩展最佳实践) ## 引言 本项目Geomative Studio是一款专业的地质勘探软件,专注于跨孔测量和测井功能的实现。系统通过专用的UI组件为用户提供直观、高效的操作界面,支持2D和3D跨孔测量配置、测井参数设置、数据可视化等功能。核心功能模块包括跨孔测量配置对话框、几何参数设置、测井功能界面以及自定义控件等。这些组件通过精心设计的架构和交互逻辑,实现了从用户输入到数据处理再到结果展示的完整工作流。系统采用MFC框架开发,利用对话框、列表控件等标准UI元素,并结合自定义绘制和消息处理机制,提供了高度可定制的用户界面体验。 **Section sources** - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp#L1-L50) - [CDialogLoggingWnd.cpp](file://cpp/logging/CDialogLoggingWnd.cpp#L1-L50) ## 跨孔测量配置对话框设计 跨孔测量配置对话框是系统的核心功能之一,提供2D和3D两种模式的测量配置。`CCrossHoleConfig2DMainDlg`和`CCrossHoleConfig3DMainDlg`两个类分别实现了2D和3D模式的对话框功能。对话框采用标签页(Tab)设计,包含"电极坐标"、"井下"、"地面"和"参数"四个主要页面。用户可以通过标签页切换不同的配置视图。对话框初始化时,会创建并管理多个子对话框,如`CCrosshole2dDrawingBoardDlg`用于2D绘图,`C2DSimulationDlg`用于模拟显示,以及`COption2DGeometryDlg`、`COption2DBoreholeDlg`等用于具体参数设置。这种设计实现了功能的模块化和界面的层次化,提高了代码的可维护性和用户体验。 ```mermaid classDiagram class CCrossHoleConfig2DMainDlg { +m_tabChange CTabCtrl +m_pConnection _ConnectionPtr +m_vecAllBoreholeABMNInfo vector +m_mapDatabaseABMNInfo map>> +GetInstance() CCrossHoleConfig2DMainDlg* +OnInitDialog() BOOL +OnBnClickedBtnCreate() void +OnBnClickedBtnLoadGeometry() void +SaveTestPointToDB() BOOL } class CCrossHoleConfig3DMainDlg { +m_tabChange CTabCtrl +m_pConnection _ConnectionPtr +m_vecAllBoreholeABMNInfo vector +m_mapDatabaseABMNInfo map>> +GetInstance() CCrossHoleConfig3DMainDlg* +OnInitDialog() BOOL +OnBnClickedBtnCreate() void +OnBnClickedBtnLoadGeometry() void +SaveTestPointToDB() BOOL } class COption2DGeometryDlg { +m_geometryList CListCtrl +m_vecNoSortAllPoints vector +m_mapBoreholeCoordinates map> +m_vecSurfaceCoordinates vector +GetInstance() COption2DGeometryDlg* +AddCoordinatesPoints() void +DeleteCoordinatesPoint() void +ShowCoordinatesPoints() void } class COption3DGeometryDlg { +m_geometryList CListCtrl +m_vecNoSortAllPoints vector +m_mapBoreholeCoordinates map> +m_mapSurfaceXCoordinates map> +m_mapSurfaceYCoordinates map> +GetInstance() COption3DGeometryDlg* +AddCoordinatesPoints() void +DeleteCoordinatesPoint() void +ShowCoordinatesPoints() void } CCrossHoleConfig2DMainDlg --> COption2DGeometryDlg : "包含" CCrossHoleConfig3DMainDlg --> COption3DGeometryDlg : "包含" CCrossHoleConfig2DMainDlg --> CCrosshole2dDrawingBoardDlg : "包含" CCrossHoleConfig3DMainDlg --> CCrosshole3dDrawingBoardDlg : "包含" ``` **Diagram sources ** - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp#L15-L20) - [CCrossHoleConfig3DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig3DMainDlg.cpp#L15-L20) - [COption2DGeometryDlg.cpp](file://cpp/crossHole/COption2DGeometryDlg.cpp#L19-L20) - [COption3DGeometryDlg.cpp](file://cpp/crossHole/COption3DGeometryDlg.cpp#L19-L20) **Section sources** - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp#L11-L800) - [CCrossHoleConfig3DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig3DMainDlg.cpp#L11-L800) ## 几何参数设置逻辑 几何参数设置是跨孔测量配置的核心环节,主要由`COption2DGeometryDlg`和`COption3DGeometryDlg`两个类实现。这两个类负责管理电极的坐标信息,包括井下电极和地表电极。`COption2DGeometryDlg`使用`CListCtrl`控件`m_geometryList`以列表形式展示所有电极的ID、地址、X、Y、Z坐标。用户可以通过"加载坐标"按钮从`.geomative`文件中导入坐标数据,系统会解析CSV格式的文件内容,将电极信息存储在`m_vecNoSortAllPoints`向量中,并同步更新列表显示。对于3D模式,`COption3DGeometryDlg`还支持X方向和Y方向的电缆测线,使用`m_mapSurfaceXCoordinates`和`m_mapSurfaceYCoordinates`两个映射来分别管理不同方向的测线数据。当用户添加或删除坐标点时,系统会自动调用`AddCoordinatesPoints`和`DeleteCoordinatesPoint`方法更新内部数据结构,并通知绘图板进行重绘。 ```mermaid flowchart TD Start([开始]) --> LoadGeometry["加载坐标文件"] LoadGeometry --> ParseFile["解析.geomative文件"] ParseFile --> ExtractPoints["提取电极坐标点"] ExtractPoints --> ClassifyPoints{"分类坐标点"} ClassifyPoints --> |地表| AddToSurface["添加到地表集合"] ClassifyPoints --> |井下| AddToBorehole["添加到井下集合"] AddToSurface --> UpdateList["更新列表显示"] AddToBorehole --> UpdateList UpdateList --> NotifyDrawingBoard["通知绘图板更新"] NotifyDrawingBoard --> End([结束]) ``` **Diagram sources ** - [COption2DGeometryDlg.cpp](file://cpp/crossHole/COption2DGeometryDlg.cpp#L78-L103) - [COption3DGeometryDlg.cpp](file://cpp/crossHole/COption3DGeometryDlg.cpp#L78-L108) **Section sources** - [COption2DGeometryDlg.cpp](file://cpp/crossHole/COption2DGeometryDlg.cpp#L1-L309) - [COption3DGeometryDlg.cpp](file://cpp/crossHole/COption3DGeometryDlg.cpp#L1-L396) ## 测井功能用户界面实现 测井功能的用户界面由`CDialogLoggingWnd`、`CDialogLoggingParameterSetting`和`CDialogLoggingLithologicWnd`三个主要对话框构成。`CDialogLoggingWnd`是主窗口,负责展示测井数据的完整报告,包括公司名称、钻孔编号、井深、测井方向等基本信息,以及自电、长电位、短电位和梯度电阻率的曲线图。`CDialogLoggingParameterSetting`用于设置测井参数,如任务名、测试地点、测井类型、采样间隔、初始深度、结束深度等。`CDialogLoggingLithologicWnd`则用于编辑和管理岩性剖面,用户可以添加、删除和修改不同深度范围的岩性信息。这些对话框通过消息映射(`BEGIN_MESSAGE_MAP`)处理用户的交互操作,如按钮点击、下拉框选择等,并通过`CMarkup`类解析和加载XML格式的参数文件和DAT格式的数据文件。 ```mermaid sequenceDiagram participant User as "用户" participant ParamDlg as "CDialogLoggingParameterSetting" participant MainWnd as "CDialogLoggingWnd" participant DataOper as "CLoggingDataOper" User->>ParamDlg : 打开参数设置对话框 ParamDlg->>DataOper : 查询任务列表 DataOper-->>ParamDlg : 返回任务信息 ParamDlg->>ParamDlg : 填充下拉框 User->>ParamDlg : 选择任务并修改参数 ParamDlg->>DataOper : 更新任务信息到数据库 DataOper-->>ParamDlg : 返回操作结果 ParamDlg->>MainWnd : 传递测井参数 User->>MainWnd : 打开测井文件 MainWnd->>MainWnd : 加载XML参数文件 MainWnd->>MainWnd : 加载DAT数据文件 MainWnd->>MainWnd : 解析并绘制曲线图 MainWnd-->>User : 显示测井报告 ``` **Diagram sources ** - [CDialogLoggingParameterSetting.cpp](file://cpp/logging/CDialogLoggingParameterSetting.cpp#L34-L37) - [CDialogLoggingWnd.cpp](file://cpp/logging/CDialogLoggingWnd.cpp#L45-L51) - [CDialogLoggingLithologicWnd.cpp](file://cpp/logging/CDialogLoggingLithologicWnd.cpp#L50-L59) **Section sources** - [CDialogLoggingWnd.cpp](file://cpp/logging/CDialogLoggingWnd.cpp#L1-L1222) - [CDialogLoggingParameterSetting.cpp](file://cpp/logging/CDialogLoggingParameterSetting.cpp#L1-L356) - [CDialogLoggingLithologicWnd.cpp](file://cpp/logging/CDialogLoggingLithologicWnd.cpp#L1-L304) ## 自定义控件绘制与交互机制 系统实现了两个重要的自定义控件:`CDragListCtrl`和`CListTextColorCtrl`。`CDragListCtrl`继承自`CListCtrl`,支持列表项的拖拽操作。它通过重写`OnLvnBegindrag`、`OnMouseMove`和`OnLButtonUp`消息处理函数,实现了拖拽的开始、移动和结束逻辑。当用户开始拖拽时,系统创建一个`CImageList`作为拖拽图像,并调用`DragEnter`方法显示拖拽效果。在鼠标移动过程中,`DragMove`方法会实时更新拖拽图像的位置。`CListTextColorCtrl`则是一个支持自定义文本颜色和背景颜色的列表控件。它通过将控件设置为`LVS_OWNERDRAWFIXED`风格,并重写`DrawItem`方法,实现了对每个列表项的自定义绘制。控件内部维护了`m_colTextColor`和`m_ItemTextColor`等链表,用于存储列和单元格的文本颜色,从而实现灵活的样式控制。 ```mermaid classDiagram class CDragListCtrl { +m_nSelItem int +m_pDragImageList CImageList* +m_bDragging BOOL +OnLvnBegindrag() void +OnMouseMove() void +OnLButtonUp() void } class CListTextColorCtrl { +m_nRowHeight int +m_fontHeight int +m_fontWith int +m_color COLORREF +m_ptrListCol CPtrList +m_ptrListItem CPtrList +m_colTextColor CPtrList +m_ItemTextColor CPtrList +DrawItem() void +MeasureItem() void +SetColTextColor() void +SetItemTextColor() void } CDragListCtrl --|> CListCtrl : "继承" CListTextColorCtrl --|> CListCtrl : "继承" ``` **Diagram sources ** - [CDragListCtrl.cpp](file://cpp/ctrl/CDragListCtrl.cpp#L9-L17) - [CListTextColorCtrl.cpp](file://cpp/ctrl/CListTextColorCtrl.cpp#L16-L21) **Section sources** - [CDragListCtrl.cpp](file://cpp/ctrl/CDragListCtrl.cpp#L1-L260) - [CListTextColorCtrl.cpp](file://cpp/ctrl/CListTextColorCtrl.cpp#L1-L399) ## 专用UI与后台算法协同工作 专用UI组件与后台算法模块通过数据结构和函数调用紧密协同工作。以跨孔测量配置为例,用户在`COption2DGeometryDlg`中设置的电极坐标,会通过`AddCoordinatesPoints`方法传递给`CCrossHoleConfig2DMainDlg`。当用户点击"创建"按钮时,`CCrossHoleConfig2DMainDlg`会调用`TwoBoreholeGenerateScript`等算法函数,根据电极的相对位置和间距,计算出测点的ABMN参数和几何因子K值。这些计算结果被存储在`m_vecAllBoreholeABMNInfo`向量中,最终通过`SaveTestPointToDB`方法写入数据库。对于测井功能,`CDialogLoggingParameterSetting`收集的参数被封装成`STLoggingParamSettingReq`结构体,传递给数据采集模块。采集到的数据则由`CDialogLoggingWnd`负责解析和可视化,实现了从用户配置到数据采集再到结果展示的完整闭环。 **Section sources** - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp#L734-L736) - [CDialogLoggingParameterSetting.cpp](file://cpp/logging/CDialogLoggingParameterSetting.cpp#L353-L356) ## 自定义控件消息处理与重绘逻辑 自定义控件的消息处理和重绘逻辑是其核心功能的实现基础。`CListTextColorCtrl`通过`PreSubclassWindow`方法将控件风格修改为`LVS_OWNERDRAWFIXED`,这表示控件将自行负责绘制其内容。当需要重绘时,系统会调用`DrawItem`方法。该方法首先获取要绘制的列表项信息,然后根据项的状态(选中或未选中)设置不同的背景色。接着,它会遍历所有列,计算每列的显示位置,并从`m_colTextColor`和`m_ItemTextColor`链表中查找对应的文本颜色,最后使用`DrawText`函数将文本绘制到指定位置。为了支持行高设置,控件重写了`MeasureItem`方法,根据`m_nRowHeight`成员变量的值来确定每一行的高度。这种机制使得控件能够灵活地适应不同的显示需求。 **Section sources** - [CListTextColorCtrl.cpp](file://cpp/ctrl/CListTextColorCtrl.cpp#L62-L69) - [CListTextColorCtrl.cpp](file://cpp/ctrl/CListTextColorCtrl.cpp#L71-L234) ## 复杂参数配置验证与默认值管理 系统对复杂参数配置进行了严格的验证和默认值管理。在`CDialogLoggingParameterSetting`中,当用户点击"确定"按钮时,`OnBnClickedOk`方法会执行一系列验证检查。例如,它会检查任务名、采样间隔、初始深度等必填字段是否为空,以及测井类型是否已选择。如果验证失败,会弹出相应的错误提示。对于数值型参数,系统会使用`atof`函数将其从字符串转换为浮点数,并进行范围检查。此外,系统还实现了默认值管理,例如在`OnInitDialog`方法中,会将"迭代次数"的默认值设置为0,并将"发射波形"的默认选项设置为"0+0-"。对于跨孔测量配置,系统会根据电极的Z坐标自动计算L值的取值范围,并确保生成的测点符合物理规律。 **Section sources** - [CDialogLoggingParameterSetting.cpp](file://cpp/logging/CDialogLoggingParameterSetting.cpp#L174-L351) - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp#L302-L349) ## 跨孔测量与测井功能操作流程 对于初学者,跨孔测量和测井功能的操作流程如下: 1. **跨孔测量配置**: * 打开"跨孔测量配置"对话框。 * 切换到"井下"或"地面"标签页,通过"加载坐标"按钮导入电极坐标。 * 切换到"参数"标签页,输入脚本名称、时间间隔等信息。 * 点击"创建"按钮生成测点脚本。 * 点击"开始模拟"按钮进行模拟运行。 2. **测井功能使用**: * 在主界面选择"测井"功能。 * 点击"参数设置"按钮,配置任务名、测井类型、深度范围等参数。 * 开始数据采集。 * 采集完成后,点击"打开文件"按钮加载测井数据。 * 在主窗口查看自电、电阻率等曲线图,并通过"岩性编辑"功能添加岩性剖面。 **Section sources** - [CCrossHoleConfig2DMainDlg.cpp](file://cpp/crossHole/CCrossHoleConfig2DMainDlg.cpp#L734-L736) - [CDialogLoggingParameterSetting.cpp](file://cpp/logging/CDialogLoggingParameterSetting.cpp#L174-L351) ## 自定义控件扩展最佳实践 对于高级开发者,扩展自定义控件的最佳实践包括: 1. **继承与重写**:从标准MFC控件(如`CListCtrl`)继承,并重写关键的虚函数,如`DrawItem`、`PreSubclassWindow`等。 2. **消息映射**:使用`BEGIN_MESSAGE_MAP`宏将Windows消息(如`WM_PAINT`、`WM_LBUTTONDOWN`)映射到自定义的消息处理函数。 3. **状态管理**:在控件类中定义私有成员变量来管理控件的内部状态,如选中的项、拖拽状态、自定义颜色等。 4. **资源管理**:注意GDI对象(如`CPen`、`CBrush`、`CFont`)的创建和销毁,避免资源泄漏。通常在`OnPaint`等函数中创建,并在函数结束前通过`SelectObject`恢复旧对象。 5. **性能优化**:对于复杂的绘制操作,考虑使用双缓冲技术(Double Buffering)来减少屏幕闪烁。可以通过在内存DC上先绘制,再一次性拷贝到屏幕DC上来实现。 **Section sources** - [CListTextColorCtrl.cpp](file://cpp/ctrl/CListTextColorCtrl.cpp#L1-L399) - [CDragListCtrl.cpp](file://cpp/ctrl/CDragListCtrl.cpp#L1-L260)