16 KiB
主界面
**本文档中引用的文件** - [MainFrm.cpp](file://cpp/Views/MainFrm.cpp) - [ChildFrm.cpp](file://cpp/Views/ChildFrm.cpp) - [ChildView.cpp](file://cpp/Views/ChildView.cpp) - [Splash.cpp](file://cpp/Views/Splash.cpp) - [MainFrm.h](file://h/MainFrm.h) - [ChildFrm.h](file://h/ChildFrm.h) - [ChildView.h](file://h/ChildView.h) - [Splash.h](file://h/Splash.h) - [GeoMative.rc2](file://res/GeoMative.rc2) - [GeoMative.cpp](file://cpp/Main/GeoMative.cpp)目录
- 主界面架构概述
- 主窗口初始化流程
- 菜单栏、工具栏与状态栏构建
- 多文档界面(MDI)组织方式
- 子窗口创建与管理逻辑
- 启动画面显示控制
- UI元素资源定义与消息映射
- 用户操作路由机制
- 主界面与其他管理模块的数据交互
- MFC框架下的窗口生命周期管理
- 性能优化建议
主界面架构概述
Geomative Studio主界面采用MFC(Microsoft Foundation Classes)框架实现,基于多文档界面(MDI)架构。系统通过CMainFrame类作为主框架窗口,继承自CMDIFrameWnd,负责管理整个应用程序的主窗口、菜单栏、工具栏和状态栏。主界面通过消息映射机制处理用户交互,并与设备管理、项目管理和数据管理器等模块进行数据交互。
主界面架构采用分层设计,包括:
- 主框架层:
CMainFrame负责整体布局和核心功能调度 - 子框架层:
CChildFrame用于管理多文档界面中的子窗口 - 视图层:
CChildView提供客户端区域的显示功能 - 辅助组件层:如启动画面
CSplashWnd等提供辅助功能
该架构支持模块化扩展,通过消息驱动机制实现各组件间的松耦合通信。
Section sources
主窗口初始化流程
主窗口的初始化流程始于CGeoMativeApp::InitInstance()方法,在GeoMative.cpp中创建CMainFrame实例并加载框架。初始化过程包含以下关键步骤:
- 主框架创建:通过
new CMainFrame实例化主窗口对象 - 框架加载:调用
LoadFrame(IDR_MAINFRAME)加载资源定义的框架结构 - 窗口显示:设置为最大化显示并通过
ShowWindow和UpdateWindow呈现 - 数据库连接:初始化ADO连接,打开GeoMativeDB.accdb数据库
- 系统初始化:创建系统时间获取线程,初始化诊断信息等
在CMainFrame::OnCreate方法中,进一步完成工具栏、状态栏的创建和初始化,并显示启动画面。整个初始化流程确保了应用程序在启动时能够正确配置所有必要的UI组件和系统资源。
sequenceDiagram
participant App as CGeoMativeApp
participant MainFrame as CMainFrame
participant Splash as CSplashWnd
App->>MainFrame : new CMainFrame()
App->>MainFrame : LoadFrame(IDR_MAINFRAME)
App->>MainFrame : ShowWindow(SW_SHOWMAXIMIZED)
App->>MainFrame : UpdateWindow()
MainFrame->>MainFrame : OnCreate()
MainFrame->>Splash : CSplashWnd : : ShowSplashScreen()
MainFrame->>MainFrame : 创建工具栏和状态栏
MainFrame->>MainFrame : 初始化设备检测
Diagram sources
Section sources
菜单栏、工具栏与状态栏构建
主界面的菜单栏、工具栏和状态栏通过MFC的标准机制构建。在MainFrm.cpp中,BEGIN_MESSAGE_MAP宏定义了这些控件的创建和管理。
工具栏通过CToolBar::CreateEx方法创建,使用TBSTYLE_FLAT|TBSTYLE_TOOLTIPS样式实现扁平化外观和工具提示功能。工具栏加载IDR_MAINFRAME资源中的工具栏定义,并通过EnableDocking(CBRS_ALIGN_ANY)启用任意方向停靠。
状态栏通过CStatusBar::Create方法创建,使用预定义的指示器数组indicators来显示状态信息。该数组包含分隔符、大写锁定、数字锁定和滚动锁定等标准状态指示器。
classDiagram
class CMainFrame {
+CStatusBar m_wndStatusBar
+CToolBar m_wndToolBar
+LoadFrame()
+OnCreate()
+PreCreateWindow()
}
class CToolBar {
+CreateEx()
+LoadToolBar()
+EnableDocking()
+DockControlBar()
}
class CStatusBar {
+Create()
+SetIndicators()
}
CMainFrame --> CToolBar : 包含
CMainFrame --> CStatusBar : 包含
Diagram sources
Section sources
多文档界面(MDI)组织方式
Geomative Studio采用标准的MFC多文档界面(MDI)架构,通过CMDIFrameWnd和CMDIChildWnd类实现。主框架CMainFrame继承自CMDIFrameWnd,负责管理多个子窗口。
MDI架构的核心组件包括:
- 主框架窗口:
CMainFrame,作为所有子窗口的容器 - 子框架窗口:
CChildFrame,继承自CMDIChildWnd,每个子窗口的容器 - 视图窗口:
CChildView,继承自CWnd,提供实际内容显示区域
子窗口的创建通过CreateNewChild方法实现,该方法使用运行时类信息创建指定类型的子框架。例如,在OnMngDataWin方法中,通过CreateNewChild(RUNTIME_CLASS(CDataMngFrame), IDR_MAINFRAME)创建数据管理框架。
graph TD
A[CMainFrame] --> B[CChildFrame]
A --> C[CChildFrame]
A --> D[CChildFrame]
B --> E[CChildView]
C --> F[CChildView]
D --> G[CChildView]
style A fill:#f9f,stroke:#333
style B fill:#bbf,stroke:#333
style C fill:#bbf,stroke:#333
style D fill:#bbf,stroke:#333
Diagram sources
Section sources
子窗口创建与管理逻辑
子窗口的创建与管理由CChildFrame和CChildView类共同实现。CChildFrame作为子框架窗口,负责管理子窗口的生命周期和布局,而CChildView则负责客户端区域的内容显示。
在CChildFrame::OnCreate方法中,通过m_wndView.Create()创建CChildView实例,并将其作为子窗口的视图组件。OnCmdMsg方法实现了命令消息的传递机制,确保视图能够优先处理命令消息。
子窗口的关闭通过OnFileClose方法实现,该方法发送WM_CLOSE消息来关闭窗口。OnSetFocus方法确保当子窗口获得焦点时,其内部的视图组件也能获得焦点。
flowchart TD
Start([子窗口创建]) --> PreCreateWindow["CChildFrame::PreCreateWindow"]
PreCreateWindow --> OnCreate["CChildFrame::OnCreate"]
OnCreate --> CreateView["创建CChildView"]
CreateView --> SetStyle["设置窗口样式"]
SetStyle --> Complete([子窗口创建完成])
CloseStart([子窗口关闭]) --> OnFileClose["CChildFrame::OnFileClose"]
OnFileClose --> SendClose["发送WM_CLOSE消息"]
SendClose --> CompleteClose([窗口关闭])
Diagram sources
Section sources
启动画面显示控制
启动画面由CSplashWnd类实现,遵循MFC向导添加的典型启动画面模式。该类继承自CWnd,通过静态方法ShowSplashScreen控制启动画面的显示。
启动画面的显示控制流程如下:
- 调用
CSplashWnd::ShowSplashScreen(this)显示启动画面 Create方法加载IDB_SPLASH位图资源并创建弹出式窗口OnCreate方法调用CenterWindow居中显示,并设置2秒定时器OnPaint方法使用BitBlt绘制启动画面位图OnTimer方法触发HideSplashScreen隐藏并销毁窗口
启动画面具有用户交互感知能力,通过PreTranslateAppMessage方法检测键盘或鼠标消息,一旦用户交互即立即隐藏启动画面,提升用户体验。
stateDiagram-v2
[*] --> Hidden
Hidden --> Creating : ShowSplashScreen()
Creating --> Displayed : Create()
Displayed --> Hiding : OnTimer() or 用户交互
Hiding --> Hidden : DestroyWindow()
note right of Displayed
定时器设置为2秒
或等待用户交互
end note
Diagram sources
Section sources
UI元素资源定义与消息映射
UI元素的资源定义主要通过.rc资源文件实现,尽管GeoMative.rc2文件当前为空,但系统使用IDR_MAINFRAME等资源ID引用主框架资源。菜单、工具栏和对话框等UI元素在资源编辑器中定义,并通过资源ID在代码中引用。
消息映射机制是MFC的核心特性,通过BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏定义消息处理函数。在MainFrm.cpp中,消息映射表将WM_CREATE、菜单命令ID和自定义消息映射到相应的处理方法。
例如,菜单命令IDM_MNG_DATA_WIN映射到OnMngDataWin方法,自定义消息WM_SCHEDULE映射到OnSchedule方法。这种声明式的消息映射机制使得UI事件处理清晰且易于维护。
erDiagram
RESOURCE : "资源定义" {
string 资源类型
string 资源ID
string 资源数据
}
MESSAGE_MAP : "消息映射" {
string 消息ID
string 处理函数
string 消息类型
}
HANDLER : "处理函数" {
string 函数名
string 参数
string 返回值
}
RESOURCE ||--o{ MESSAGE_MAP : "通过ID关联"
MESSAGE_MAP }o--|| HANDLER : "映射到"
Diagram sources
Section sources
用户操作路由机制
用户操作路由机制基于MFC的消息映射系统实现。ON_COMMAND宏将菜单项和工具栏按钮的命令ID映射到特定的处理函数。当用户点击菜单项或工具栏按钮时,MFC框架自动调用相应的处理方法。
例如,ON_COMMAND(IDM_MNG_DATA_WIN, OnMngDataWin)将数据管理窗口命令映射到OnMngDataWin方法。该方法检查m_pDataMngFrm是否已创建,若未创建则通过CreateNewChild创建新的子框架,否则激活现有窗口。
自定义消息通过ON_MESSAGE宏处理,如ON_MESSAGE(WM_SCHEDULE, OnSchedule)处理调度消息。这种机制支持应用程序内部组件间的通信,实现了松耦合的设计。
sequenceDiagram
participant User as 用户
participant Frame as CMainFrame
participant Handler as 处理函数
User->>Frame : 点击菜单项IDM_MNG_DATA_WIN
Frame->>Frame : 查找消息映射表
Frame->>Handler : 调用OnMngDataWin()
Handler->>Handler : 检查m_pDataMngFrm
alt 窗口未创建
Handler->>Handler : CreateNewChild()
Handler->>Handler : ShowWindow(SW_SHOWMAXIMIZED)
else 窗口已存在
Handler->>Handler : ActivateFrame()
end
Handler-->>Frame : 返回
Diagram sources
Section sources
主界面与其他管理模块的数据交互
主界面通过成员变量和消息机制与设备管理、项目管理和数据管理器等模块进行数据交互。CMainFrame类定义了指向这些管理框架的指针,如m_pDevMngFrm、m_pDataMngFrm和m_pSptMngFrm。
数据交互主要通过以下方式实现:
- 直接方法调用:通过管理框架指针调用其公开方法
- 消息传递:使用
SendMessage发送WM_REFRESH等自定义消息 - 共享数据对象:通过应用程序对象
theApp访问全局管理器
例如,在设备连接时,主框架通过m_pDevMngFrm->SendMessage(WM_REFRESH_NAV_DEVICE)通知设备管理框架刷新设备列表。文件导入导出操作通过theApp.m_pIOManager执行,并在完成后发送刷新消息。
classDiagram
class CMainFrame {
+CDevMngFrame* m_pDevMngFrm
+CDataMngFrame* m_pDataMngFrm
+CSptMngFrame* m_pSptMngFrm
+OnRefresh()
+OnFileExp()
+OnFileImp()
}
class CDevMngFrame {
+OnRefreshNavDevice()
}
class CDataMngFrame {
+OnRefresh()
}
class CIOManager {
+Export()
+Import()
}
CMainFrame --> CDevMngFrame : 持有引用
CMainFrame --> CDataMngFrame : 持有引用
CMainFrame --> CIOManager : 通过theApp访问
CMainFrame ..> CDevMngFrame : 发送WM_REFRESH_NAV_DEVICE
CMainFrame ..> CDataMngFrame : 发送WM_REFRESH
Diagram sources
Section sources
MFC框架下的窗口生命周期管理
MFC框架通过一系列虚拟方法和消息处理机制管理窗口生命周期。窗口的创建、销毁和消息处理遵循特定的顺序和模式。
创建过程:
- 构造函数:
CMainFrame()进行成员变量初始化 PreCreateWindow:修改窗口样式和类属性OnCreate:创建子控件(工具栏、状态栏)LoadFrame:加载框架资源并显示窗口
销毁过程:
WM_CLOSE消息:触发窗口关闭- 析构函数:
~CMainFrame()清理资源 PostNcDestroy:删除C++对象(在CSplashWnd中实现)
子窗口通过OnCmdMsg方法实现命令消息的传递,确保视图能够优先处理命令。这种分层的消息处理机制是MFC框架的核心特性之一。
flowchart TB
subgraph 创建流程
A[构造函数] --> B[PreCreateWindow]
B --> C[OnCreate]
C --> D[LoadFrame]
D --> E[ShowWindow]
end
subgraph 销毁流程
F[WM_CLOSE] --> G[析构函数]
G --> H[PostNcDestroy]
H --> I[对象删除]
end
Diagram sources
Section sources
性能优化建议
针对Geomative Studio主界面的性能优化,建议从以下几个方面着手:
减少重绘开销:
- 使用双缓冲技术减少闪烁
- 仅重绘无效区域而非整个窗口
- 延迟更新,批量处理UI变更
减少消息处理延迟:
- 避免在消息处理函数中执行耗时操作
- 将长时间运行的任务移至工作线程
- 使用定时器分批处理大量数据更新
内存管理优化:
- 及时释放不再使用的子窗口
- 使用智能指针管理动态创建的对象
- 缓存频繁访问的资源
启动性能优化:
- 延迟加载非关键模块
- 优化数据库连接和初始化流程
- 减少启动时的同步操作
通过实施这些优化措施,可以显著提升主界面的响应速度和用户体验。
Section sources