feat: add a new awesome feature
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* @文件: StellarX.h
|
||||
* @摘要: 星垣(StellarX) GUI框架 - 主包含头文件
|
||||
* @版本: v2.3.2
|
||||
* @版本: v3.0.0
|
||||
* @描述:
|
||||
* 一个为Windows平台打造的轻量级、模块化C++ GUI框架。
|
||||
* 基于EasyX图形库,提供简洁易用的API和丰富的控件。
|
||||
@@ -31,6 +31,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "SxLog.h"
|
||||
#include "Control.h"
|
||||
#include"Canvas.h"
|
||||
#include"Window.h"
|
||||
@@ -41,3 +42,5 @@
|
||||
#include"Dialog.h"
|
||||
#include"MessageBox.h"
|
||||
#include"TabControl.h"
|
||||
|
||||
|
||||
|
||||
416
include/StellarX/SxLog.h
Normal file
416
include/StellarX/SxLog.h
Normal file
@@ -0,0 +1,416 @@
|
||||
#pragma once
|
||||
|
||||
/********************************************************************************
|
||||
* @文件: SxLog.h
|
||||
* @摘要: StellarX 日志系统对外接口定义(控制台/文件输出 + 级别过滤 + Tag过滤 + 中英文选择)
|
||||
* @描述:
|
||||
* 该日志系统采用“宏 + RAII(析构提交)”的方式实现:
|
||||
* - 调用端通过 SX_LOGD/SX_LOGI... 写日志
|
||||
* - 宏内部先 shouldLog 短路过滤,未命中时不构造对象、不拼接字符串
|
||||
* - 命中时构造 SxLogLine,使用 operator<< 拼接内容
|
||||
* - 语句结束时 SxLogLine 析构,统一提交到 SxLogger::logLine 输出
|
||||
*
|
||||
* 输出通道(Sink)目前提供:
|
||||
* - ConsoleSink: 写入 std::cout(不走 WinAPI 调试输出通道)
|
||||
* - FileSink: 写入文件,支持按字节阈值滚动
|
||||
*
|
||||
* @特性:
|
||||
* - 日志级别:Trace/Debug/Info/Warn/Error/Fatal/Off
|
||||
* - Tag 过滤:None/Whitelist/Blacklist
|
||||
* - 可选前缀:时间戳/级别/Tag/线程ID/源码位置
|
||||
* - 中英文选择:SX_T(zh, en) / setLanguage
|
||||
* - 文件滚动:rotateBytes > 0 时按阈值滚动
|
||||
*
|
||||
* @使用场景:
|
||||
* - 排查重绘链路、脏标记传播、Tab 切换、Table 数据刷新等时序问题
|
||||
* - 输出可复现日志,配合回归验证
|
||||
*
|
||||
* @注意:
|
||||
* - SX_T 仅做“字符串选择”,不做编码转换
|
||||
* - 控制台显示是否乱码由“终端 codepage/字体/环境”决定
|
||||
* - 该头文件只声明接口,实现位于 SxLog.cpp
|
||||
*
|
||||
* @所属框架: 星垣(StellarX) GUI框架
|
||||
* @作者: 我在人间做废物
|
||||
********************************************************************************/
|
||||
|
||||
// SxLog.h - header-only interface (implementation in SxLog.cpp)
|
||||
// Pure standard library: std::cout and optional file sink.
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#ifndef SX_LOG_ENABLE
|
||||
#define SX_LOG_ENABLE 1
|
||||
#endif
|
||||
|
||||
namespace StellarX
|
||||
{
|
||||
/* ========================= 日志级别 ========================= */
|
||||
// 说明:
|
||||
// - minLevel 表示最低输出级别,小于 minLevel 的日志会被 shouldLog 直接过滤
|
||||
// - Off 表示全局关闭
|
||||
enum class SxLogLevel : int
|
||||
{
|
||||
Trace = 0, // 最细粒度:高频路径追踪(谨慎开启)
|
||||
Debug = 1, // 调试信息:状态变化/关键分支
|
||||
Info = 2, // 业务信息:关键流程节点
|
||||
Warn = 3, // 警告:非致命但异常的情况
|
||||
Error = 4, // 错误:功能失败、需要关注
|
||||
Fatal = 5, // 致命:通常意味着无法继续运行
|
||||
Off = 6 // 关闭全部日志
|
||||
};
|
||||
|
||||
/* ========================= 语言选择 ========================= */
|
||||
// 说明:仅用于 SX_T 选择输出哪一段文本,不做编码转换
|
||||
enum class SxLogLanguage : int
|
||||
{
|
||||
ZhCN = 0, // 中文
|
||||
EnUS = 1 // 英文
|
||||
};
|
||||
|
||||
/* ========================= Tag 过滤模式 ========================= */
|
||||
// None : 不过滤,全部输出
|
||||
// Whitelist : 只输出 tagList 中包含的 tag
|
||||
// Blacklist : 输出除 tagList 以外的 tag
|
||||
enum class SxTagFilterMode : int
|
||||
{
|
||||
None = 0,
|
||||
Whitelist = 1,
|
||||
Blacklist = 2
|
||||
};
|
||||
|
||||
/* ========================= 日志配置 ========================= */
|
||||
// 说明:SxLogger 内部持有该配置,shouldLog 与 logLine 都依赖它
|
||||
struct SxLogConfig
|
||||
{
|
||||
SxLogLevel minLevel = SxLogLevel::Info; // 最低输出级别
|
||||
|
||||
bool showTimestamp = true; // 是否输出时间戳前缀
|
||||
bool showLevel = true; // 是否输出级别前缀
|
||||
bool showTag = true; // 是否输出 tag 前缀
|
||||
bool showThreadId = false; // 是否输出线程ID(排查并发时开启)
|
||||
bool showSource = false; // 是否输出源码位置(file:line func)
|
||||
bool autoFlush = true; // 每行写完是否 flush(排查问题更稳,性能略差)
|
||||
|
||||
SxTagFilterMode tagFilterMode = SxTagFilterMode::None; // Tag 过滤模式
|
||||
std::vector<std::string> tagList; // Tag 列表(白名单/黑名单)
|
||||
|
||||
bool fileEnabled = false; // 文件输出是否启用(enableFile 成功才为 true)
|
||||
std::string filePath; // 文件路径
|
||||
bool fileAppend = true; // 是否追加写入
|
||||
std::size_t rotateBytes = 0; // 滚动阈值(0 表示不滚动)
|
||||
};
|
||||
|
||||
/* ========================= Sink 接口 ========================= */
|
||||
// 说明:
|
||||
// - Sink 负责“把完整的一行日志写到某个地方”
|
||||
// - SxLogger 负责过滤/格式化/分发
|
||||
class ILogSink
|
||||
{
|
||||
public:
|
||||
virtual ~ILogSink() = default;
|
||||
|
||||
// 返回 Sink 名称,用于调试识别(例如 "console"/"file")
|
||||
virtual const char* name() const = 0;
|
||||
|
||||
// 写入一整行(调用方保证 line 已包含换行或按约定追加换行)
|
||||
virtual void writeLine(const std::string& line) = 0;
|
||||
|
||||
// 刷新缓冲(可选实现)
|
||||
virtual void flush() {}
|
||||
};
|
||||
|
||||
/* ========================= 控制台输出 Sink ========================= */
|
||||
// 作用:把日志写入指定输出流(默认用 std::cout)
|
||||
class ConsoleSink : public ILogSink
|
||||
{
|
||||
public:
|
||||
// 绑定一个输出流引用(常见用法:std::cout)
|
||||
explicit ConsoleSink(std::ostream& os) : out(os) {}
|
||||
|
||||
const char* name() const override { return "console"; }
|
||||
|
||||
// 写入一行(不自动追加换行,换行由上层统一拼接)
|
||||
void writeLine(const std::string& line) override { out << line; }
|
||||
|
||||
// 立即 flush(当 autoFlush=true 时由 SxLogger 调用)
|
||||
void flush() override { out.flush(); }
|
||||
|
||||
private:
|
||||
std::ostream& out; // 输出流引用(不负责生命周期)
|
||||
};
|
||||
|
||||
/* ========================= 文件输出 Sink ========================= */
|
||||
// 作用:把日志写入文件,支持按字节阈值滚动
|
||||
class FileSink : public ILogSink
|
||||
{
|
||||
public:
|
||||
FileSink() = default;
|
||||
|
||||
const char* name() const override { return "file"; }
|
||||
|
||||
// 打开文件
|
||||
// path : 文件路径
|
||||
// append : true 追加写;false 清空重写
|
||||
bool open(const std::string& path, bool append);
|
||||
|
||||
// 关闭文件(安全可重复调用)
|
||||
void close();
|
||||
|
||||
// 查询文件是否处于打开状态
|
||||
bool isOpen() const;
|
||||
|
||||
// 设置滚动阈值(字节)
|
||||
// bytes = 0 表示不滚动
|
||||
void setRotateBytes(std::size_t bytes) { rotateBytes = bytes; }
|
||||
|
||||
// 写入一行,并在需要时触发滚动
|
||||
void writeLine(const std::string& line) override;
|
||||
|
||||
// flush 文件缓冲
|
||||
void flush() override;
|
||||
|
||||
private:
|
||||
// 检查并执行滚动
|
||||
// 返回值:是否发生滚动(或是否重新打开)
|
||||
bool rotateIfNeeded();
|
||||
|
||||
std::ofstream ofs; // 文件输出流
|
||||
std::string filePath; // 当前文件路径
|
||||
bool appendMode = true; // 是否追加模式(用于 reopen)
|
||||
std::size_t rotateBytes = 0; // 滚动阈值
|
||||
};
|
||||
|
||||
/* ========================= 日志中心 SxLogger ========================= */
|
||||
// 作用:
|
||||
// - 保存配置(SxLogConfig)
|
||||
// - 过滤(level/tag/sink enabled)
|
||||
// - 格式化前缀(时间/级别/tag/线程/源码位置)
|
||||
// - 分发到 console/file 等 sink
|
||||
class SxLogger
|
||||
{
|
||||
public:
|
||||
// 仅用于 Windows 控制台:把 codepage 切到 GBK,解决中文乱码。
|
||||
// 不使用 WinAPI:内部通过 system("chcp 936") 实现
|
||||
// 注意:这只影响终端解释输出字节的方式,不影响源码文件编码
|
||||
static void setGBK();
|
||||
|
||||
// 获取全局单例
|
||||
// 说明:函数内静态对象,C++11 起保证线程安全初始化
|
||||
static SxLogger& Get();
|
||||
|
||||
// 设置最低输出级别
|
||||
void setMinLevel(SxLogLevel level);
|
||||
|
||||
// 获取最低输出级别
|
||||
SxLogLevel getMinLevel() const;
|
||||
|
||||
// 设置语言(用于 SX_T 选择)
|
||||
void setLanguage(SxLogLanguage lang);
|
||||
|
||||
// 获取当前语言
|
||||
SxLogLanguage getLanguage() const;
|
||||
|
||||
// 设置 Tag 过滤
|
||||
// mode: None/Whitelist/Blacklist
|
||||
// tags: 过滤列表(精确匹配)
|
||||
void setTagFilter(SxTagFilterMode mode, const std::vector<std::string>& tags);
|
||||
|
||||
// 清空 Tag 过滤(恢复 None)
|
||||
void clearTagFilter();
|
||||
|
||||
// 开关控制台输出
|
||||
void enableConsole(bool enable);
|
||||
|
||||
// 开启文件输出
|
||||
// path : 文件路径
|
||||
// append : 追加写/清空写
|
||||
// rotateBytes: 滚动阈值(0 不滚动)
|
||||
// 返回值:是否打开成功
|
||||
bool enableFile(const std::string& path, bool append = true, std::size_t rotateBytes = 0);
|
||||
|
||||
// 关闭文件输出(不影响控制台输出)
|
||||
void disableFile();
|
||||
|
||||
// 快速判定是否需要输出(宏层面的短路依赖它)
|
||||
// 说明:
|
||||
// - shouldLog 一定要“副作用为 0”
|
||||
// - 若返回 false,调用端不会创建 SxLogLine,也不会拼接字符串
|
||||
bool shouldLog(SxLogLevel level, const char* tag) const;
|
||||
|
||||
// 输出一条完整日志
|
||||
// 说明:这是统一出口,SxLogLine 析构最终会走到这里
|
||||
void logLine(
|
||||
SxLogLevel level,
|
||||
const char* tag,
|
||||
const char* file,
|
||||
int line,
|
||||
const char* func,
|
||||
const std::string& msg);
|
||||
|
||||
// 获取配置副本(避免外部直接改内部 cfg)
|
||||
SxLogConfig getConfigCopy() const;
|
||||
|
||||
// 批量设置配置(整体替换)
|
||||
void setConfig(const SxLogConfig& cfg);
|
||||
|
||||
// 工具:把级别转为字符串(用于前缀)
|
||||
static const char* levelToString(SxLogLevel level);
|
||||
|
||||
// 工具:生成本地时间戳字符串(用于前缀与文件滚动名)
|
||||
static std::string makeTimestampLocal();
|
||||
|
||||
private:
|
||||
SxLogger();
|
||||
|
||||
// 判断 tag 是否允许输出(根据 Tag 过滤模式与 tagList)
|
||||
static bool tagAllowed(const SxLogConfig& cfg, const char* tag);
|
||||
|
||||
// 生成前缀(调用方需已持有锁)
|
||||
std::string formatPrefixUnlocked(
|
||||
const SxLogConfig& cfg,
|
||||
SxLogLevel level,
|
||||
const char* tag,
|
||||
const char* file,
|
||||
int line,
|
||||
const char* func) const;
|
||||
|
||||
mutable std::mutex mtx; // 保护 cfg 与 sink 写入,确保多线程行级一致性
|
||||
SxLogConfig cfg; // 当前配置
|
||||
std::atomic<SxLogLanguage> lang; // 语言开关(仅影响 SX_T 选择)
|
||||
|
||||
std::unique_ptr<ConsoleSink> consoleSink; // 控制台 sink(enableConsole 控制)
|
||||
std::unique_ptr<FileSink> fileSink; // 文件 sink(enableFile 控制)
|
||||
};
|
||||
|
||||
/* ========================= 双语选择辅助 ========================= */
|
||||
// 说明:
|
||||
// - 只做“选择 zhCN 或 enUS”,不做编码转换
|
||||
// - 输出显示是否正常由终端环境决定
|
||||
inline const char* SxT(const char* zhCN, const char* enUS)
|
||||
{
|
||||
return (SxLogger::Get().getLanguage() == SxLogLanguage::ZhCN) ? zhCN : enUS;
|
||||
}
|
||||
|
||||
#if defined(__cpp_char8_t) && (__cpp_char8_t >= 201811L)
|
||||
// 说明:
|
||||
// - C++20 的 u8"xxx" 是 char8_t*,为了兼容调用端,这里提供重载
|
||||
// - reinterpret_cast 只是改指针类型,不做 UTF-8 -> GBK 转码
|
||||
inline const char* SxT(const char8_t* zhCN, const char* enUS)
|
||||
{
|
||||
return (SxLogger::Get().getLanguage() == SxLogLanguage::ZhCN)
|
||||
? reinterpret_cast<const char*>(zhCN)
|
||||
: enUS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================= RAII 日志行对象 ========================= */
|
||||
// 作用:
|
||||
// - 构造时记录 level/tag/源码位置
|
||||
// - operator<< 拼接内容
|
||||
// - 析构时统一提交给 SxLogger::logLine 输出
|
||||
//
|
||||
// 设计意义:
|
||||
// - 避免调用端忘记写换行
|
||||
// - 保证一行日志作为整体写出
|
||||
class SxLogLine
|
||||
{
|
||||
public:
|
||||
// 构造:记录元信息(不输出)
|
||||
SxLogLine(SxLogLevel level, const char* tag, const char* file, int line, const char* func);
|
||||
|
||||
// 析构:提交输出(真正写出发生在这里)
|
||||
~SxLogLine();
|
||||
|
||||
// 拼接内容(流式写法)
|
||||
template<typename T>
|
||||
SxLogLine& operator<<(const T& v)
|
||||
{
|
||||
ss << v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
SxLogLevel lvl; // 日志级别
|
||||
const char* tg; // Tag(不拥有内存)
|
||||
const char* srcFile; // 源文件名(来自 __FILE__)
|
||||
int srcLine; // 行号(来自 __LINE__)
|
||||
const char* srcFunc; // 函数名(来自 __func__)
|
||||
std::ostringstream ss; // 内容拼接缓冲
|
||||
};
|
||||
|
||||
/* ========================= RAII 作用域计时对象 ========================= */
|
||||
// 作用:
|
||||
// - 仅在 shouldLog(Trace, tag) 为 true 时启用计时
|
||||
// - 析构时输出耗时(微秒)
|
||||
//
|
||||
// 使用建议:
|
||||
// - 只在需要定位性能瓶颈时开启 Trace
|
||||
// - name 建议传入常量字符串,便于检索
|
||||
class SxLogScope
|
||||
{
|
||||
public:
|
||||
// 构造:根据 shouldLog 决定是否启用计时
|
||||
SxLogScope(SxLogLevel level, const char* tag, const char* file, int line, const char* func, const char* name);
|
||||
|
||||
// 析构:若启用则输出耗时
|
||||
~SxLogScope();
|
||||
|
||||
private:
|
||||
bool enabled = false; // 是否启用(未启用则析构无输出)
|
||||
SxLogLevel lvl = SxLogLevel::Trace; // 级别(通常用 Trace)
|
||||
const char* tg = nullptr; // Tag
|
||||
const char* srcFile = nullptr; // 源文件
|
||||
int srcLine = 0; // 行号
|
||||
const char* srcFunc = nullptr; // 函数
|
||||
const char* scopeName = nullptr; // 作用域名
|
||||
std::chrono::steady_clock::time_point t0; // 起始时间点
|
||||
};
|
||||
|
||||
} // namespace StellarX
|
||||
|
||||
#if SX_LOG_ENABLE
|
||||
|
||||
// SX_T:双语选择宏,调用 SxT 根据当前语言选择输出
|
||||
#define SX_T(zh, en) ::StellarX::SxT(zh, en)
|
||||
|
||||
// 日志宏说明:
|
||||
// 1) 先 shouldLog 短路过滤,未命中则不会构造 SxLogLine,也不会执行 else 分支的表达式
|
||||
// 2) 命中则构造临时 SxLogLine,并允许继续使用 operator<< 拼接
|
||||
// 3) 语句结束时临时对象析构,触发真正输出
|
||||
#define SX_LOG_TRACE(tag) if(!::StellarX::SxLogger::Get().shouldLog(::StellarX::SxLogLevel::Trace, tag)) ; else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Trace, tag, __FILE__, __LINE__, __func__)
|
||||
#define SX_LOGD(tag) if(!::StellarX::SxLogger::Get().shouldLog(::StellarX::SxLogLevel::Debug, tag)) ; else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Debug, tag, __FILE__, __LINE__, __func__)
|
||||
#define SX_LOGI(tag) if(!::StellarX::SxLogger::Get().shouldLog(::StellarX::SxLogLevel::Info, tag)) ; else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Info, tag, __FILE__, __LINE__, __func__)
|
||||
#define SX_LOGW(tag) if(!::StellarX::SxLogger::Get().shouldLog(::StellarX::SxLogLevel::Warn, tag)) ; else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Warn, tag, __FILE__, __LINE__, __func__)
|
||||
#define SX_LOGE(tag) if(!::StellarX::SxLogger::Get().shouldLog(::StellarX::SxLogLevel::Error, tag)) ; else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Error, tag, __FILE__, __LINE__, __func__)
|
||||
#define SX_LOGF(tag) if(!::StellarX::SxLogger::Get().shouldLog(::StellarX::SxLogLevel::Fatal, tag)) ; else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Fatal, tag, __FILE__, __LINE__, __func__)
|
||||
|
||||
// 作用域耗时统计宏:默认用 Trace 级别
|
||||
#define SX_TRACE_SCOPE(tag, nameLiteral) ::StellarX::SxLogScope sx_scope_##__LINE__(::StellarX::SxLogLevel::Trace, tag, __FILE__, __LINE__, __func__, nameLiteral)
|
||||
|
||||
#else
|
||||
|
||||
// 关闭日志时的兼容宏:保证调用端代码不需要改动
|
||||
#define SX_T(zh, en) (en)
|
||||
#define SX_LOG_TRACE(tag) if(true) {} else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Off, tag, "", 0, "")
|
||||
#define SX_LOGD(tag) if(true) {} else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Off, tag, "", 0, "")
|
||||
#define SX_LOGI(tag) if(true) {} else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Off, tag, "", 0, "")
|
||||
#define SX_LOGW(tag) if(true) {} else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Off, tag, "", 0, "")
|
||||
#define SX_LOGE(tag) if(true) {} else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Off, tag, "", 0, "")
|
||||
#define SX_LOGF(tag) if(true) {} else ::StellarX::SxLogLine(::StellarX::SxLogLevel::Off, tag, "", 0, "")
|
||||
#define SX_TRACE_SCOPE(tag, nameLiteral) do {} while(0)
|
||||
|
||||
#endif
|
||||
@@ -66,7 +66,7 @@ private:
|
||||
int totalPages = 1; // 总页数
|
||||
|
||||
bool isShowPageButton = true; // 是否显示翻页按钮
|
||||
bool isNeedDrawHeaders = true; // 是否需要绘制表头
|
||||
bool isNeedDrawHeaders = true; // 是否需要绘制表头(暂时废弃,单做保留,后期优化可能用到)
|
||||
bool isNeedCellSize = true; // 是否需要计算单元格尺寸
|
||||
bool isNeedButtonAndPageNum = true; // 是否需要计算翻页按钮和页码信息
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
* - WM_GETMINMAXINFO:按最小“客户区”换算到“窗口矩形”,提供系统层最小轨迹值。
|
||||
* - runEventLoop:只记录 WM_SIZE 的新尺寸;真正绘制放在 needResizeDirty 时集中处理。
|
||||
*/
|
||||
//fuck windows fuck win32
|
||||
#pragma once
|
||||
|
||||
#include "Control.h"
|
||||
@@ -53,7 +54,7 @@ class Window
|
||||
std::vector<std::unique_ptr<Control>> dialogs;
|
||||
|
||||
public:
|
||||
bool dialogClose = false; // 项目内使用的状态位
|
||||
bool dialogClose = false; // 项目内使用的状态位,对话框关闭标志
|
||||
|
||||
// —— 构造/析构 ——(仅初始化成员;实际样式与子类化在 draw() 中完成)
|
||||
Window(int width, int height, int mode);
|
||||
@@ -86,21 +87,7 @@ public:
|
||||
std::string getBkImageFile() const;
|
||||
std::vector<std::unique_ptr<Control>>& getControls();
|
||||
|
||||
// —— 配置开关 ——(动态调整最小客户区、合成双缓冲)
|
||||
inline void setMinClientSize(int w, int h)
|
||||
{
|
||||
// 仅更新阈值;实际约束在 WM_GETMINMAXINFO/WM_SIZING 中生效
|
||||
minClientW = w;
|
||||
minClientH = h;
|
||||
}
|
||||
|
||||
inline void setComposited(bool on)
|
||||
{
|
||||
// 更新标志;真正应用在 draw()/样式 SetWindowLongEx + SWP_FRAMECHANGED
|
||||
useComposited = on;
|
||||
}
|
||||
|
||||
void processWindowMessage(const ExMessage& msg); // 处理 EX_WINDOW 中的 WM_SIZE 等
|
||||
// —— 尺寸调整 ——(供内部与外部调用的尺寸变化处理)
|
||||
void pumpResizeIfNeeded(); // 执行一次统一收口重绘
|
||||
void scheduleResizeFromModal(int w, int h);
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user