#ifndef __APPLICATION_HPP__ #define __APPLICATION_HPP__ #include #include #include #include #include "PaintUtil.hpp" #include "PlotView.hpp" #include "SignalPanel.hpp" #include "SignalSet.hpp" #include "Theme.hpp" #include "Toolbar.hpp" namespace jdi { /** * @brief 应用主框架:负责窗口、布局、消息分发、绘制合成与命令处理。 */ class Application { public: /** * @brief 获取全局唯一应用实例。 * @return 应用实例引用。 */ static Application& Instance(); /** * @brief 初始化环境、创建窗口并进入消息循环。 * @param [IN] instance 模块实例句柄。 * @param [IN] showCommand 窗口显示方式。 * @return 进程退出码。 */ int Run(HINSTANCE instance, int showCommand); /** * @brief 窗口过程中转处理函数。 * @param [IN] hwnd 窗口句柄。 * @param [IN] message 消息标识。 * @param [IN] wParam 消息参数。 * @param [IN] lParam 消息参数。 * @return 消息处理结果。 */ LRESULT HandleMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); private: /** * @brief 鼠标交互的作用目标。 */ enum class Target : int { NONE = 0, /**< 无目标。 */ TOOLBAR, /**< 工具栏。 */ PANEL, /**< 信号面板。 */ PLOT, /**< 波形绘图区。 */ SPLITTER /**< 面板分隔条。 */ }; Application() = default; ~Application() = default; Application(const Application&) = delete; Application& operator=(const Application&) = delete; /** * @brief 窗口过程静态回调。 * @param [IN] hwnd 窗口句柄。 * @param [IN] message 消息标识。 * @param [IN] wParam 消息参数。 * @param [IN] lParam 消息参数。 * @return 消息处理结果。 */ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /** * @brief 创建主窗口与相关资源。 * @param [IN] instance 模块实例句柄。 * @param [IN] showCommand 窗口显示方式。 * @return 创建成功返回 true。 */ bool Initialize(HINSTANCE instance, int showCommand); /** * @brief 释放窗口与绘图资源。 */ void Shutdown(); /** * @brief 依据 DPI 重建字体与布局。 * @param [IN] dpi 目标 DPI。 */ void ApplyDpi(UINT dpi); /** * @brief 重新计算各区域的布局。 */ void Relayout(); /** * @brief 创建或调整后备缓冲区尺寸。 * @param [IN] width 客户区宽度。 * @param [IN] height 客户区高度。 */ void EnsureBackBuffer(int width, int height); /** * @brief 释放后备缓冲区。 */ void ReleaseBackBuffer(); /** * @brief 完整重绘客户区并呈现到窗口。 */ void Render(); /** * @brief 绘制底部状态栏。 * @param [IN,OUT] g 绘图上下文。 */ void PaintStatusBar(gd::Graphics& g); /** * @brief 弹出文件选择对话框并加载所选文件。 */ void OpenFileDialog(); /** * @brief 加载指定 CSV 文件并刷新界面。 * @param [IN] path 文件完整路径。 * @return 加载成功返回 true。 */ bool LoadFile(const std::wstring& path); /** * @brief 执行工具栏动作。 * @param [IN] action 动作标识。 */ void ExecuteToolbarAction(ToolbarAction action); /** * @brief 处理键盘按键。 * @param [IN] key 虚拟键码。 * @return 已处理返回 true。 */ bool HandleKeyDown(WPARAM key); /** * @brief 设置状态栏提示信息。 * @param [IN] text 提示文本。 * @param [IN] isError 是否为错误提示。 */ void SetStatusMessage(const std::wstring& text, bool isError); /** * @brief 刷新窗口标题。 */ void UpdateWindowTitle(); /** * @brief 解析命令行中的文件参数并加载。 */ void LoadCommandLineFile(); /** * @brief 处理客户区鼠标移动。 * @param [IN] x 客户区横坐标。 * @param [IN] y 客户区纵坐标。 * @param [IN] buttonDown 是否有按键处于按下状态。 * @return 需要重绘返回 true。 */ bool HandleMouseMove(int x, int y, bool buttonDown); HINSTANCE m_instance = nullptr; /**< 模块实例句柄。 */ HWND m_hwnd = nullptr; /**< 主窗口句柄。 */ UINT m_dpi = 96; /**< 当前 DPI。 */ float m_scale = 1.0f; /**< DPI 缩放比例。 */ ULONG_PTR m_gdiplusToken = 0; /**< GDI+ 运行时令牌。 */ bool m_gdiplusReady = false; /**< GDI+ 是否初始化成功。 */ Theme m_theme; /**< 主题配色。 */ UiFonts m_fonts; /**< 界面字体。 */ SignalSet m_document; /**< 已加载的数据集。 */ Toolbar m_toolbar; /**< 顶部工具栏。 */ SignalPanel m_panel; /**< 左侧信号面板。 */ PlotView m_plot; /**< 波形绘图区。 */ gd::RectF m_toolbarRect; /**< 工具栏区域。 */ gd::RectF m_panelRect; /**< 信号面板区域。 */ gd::RectF m_splitterRect; /**< 面板分隔条区域。 */ gd::RectF m_plotRect; /**< 绘图区区域。 */ gd::RectF m_statusRect; /**< 状态栏区域。 */ float m_panelWidth = 292.0f; /**< 面板宽度(逻辑像素)。 */ bool m_draggingSplitter = false; /**< 是否正在拖动分隔条。 */ int m_splitterGrabOffset = 0; /**< 分隔条拖动的抓取偏移。 */ HDC m_backDc = nullptr; /**< 后备缓冲设备上下文。 */ HBITMAP m_backBitmap = nullptr; /**< 后备缓冲位图。 */ HGDIOBJ m_backOldBitmap = nullptr; /**< 后备缓冲原始位图。 */ int m_backWidth = 0; /**< 后备缓冲宽度。 */ int m_backHeight = 0; /**< 后备缓冲高度。 */ Target m_activeTarget = Target::NONE; /**< 当前鼠标作用目标。 */ bool m_trackingLeave = false; /**< 是否已注册鼠标离开通知。 */ std::size_t m_lastLaneCount = 0; /**< 上次渲染时的网格数量,用于检测布局失效。 */ std::wstring m_statusMessage; /**< 状态栏提示文本。 */ bool m_statusIsError = false; /**< 状态提示是否为错误。 */ }; } // namespace jdi #endif // __APPLICATION_HPP__