《玄》IDE v3.6.3重磅发布:全功能修复与性能飞跃

cpp 复制代码
// ============================================================
// 《玄》IDE v3.6.3 --- 完整版
//   v3.6.3 新增/修复:
//     - pattern 补:无符号短整数/整数/长整数,超长/长/短整数及指针/列表
//     - 修复嵌套 "重复" 生成同名计数器 _i_rep_0(改用独立递增 id)
//   v3.6.2 修复:
//     - BUG-1: 则/则␣ 前边界保护(不误伤 原则/规则/法则)
//     - BUG-2: 检测到 卦 时自动注入 srand((unsigned)time(0))
//   v3.6.1 修复:
//     - P0: 卦 A/B 扫描、对于X从A到B B 扫描加全角标点终止
// 链接库:-lgdi32 -lcomctl32 -lcomdlg32 -static-libstdc++ -static-libgcc
// ============================================================

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <process.h>
#include <atomic>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cctype>

using namespace std;

#define IDM_FILE_NEW     1001
#define IDM_FILE_OPEN    1002
#define IDM_FILE_SAVE    1003
#define IDM_FILE_SAVEAS  1004
#define IDM_FILE_EXIT    1005
#define IDM_EDIT_CUT     1011
#define IDM_EDIT_COPY    1012
#define IDM_EDIT_PASTE   1013
#define IDM_RUN_COMPILE  1021
#define IDM_RUN_RUN      1022
#define IDM_RUN_STOP     1023
#define IDM_HELP_MANUAL  1031
#define IDM_HELP_ABOUT   1032
#define IDB_SAVE    201
#define IDB_COMPILE 202
#define IDB_RUN     203
#define IDB_STOP    204
#define IDB_CLEAR   205

#define WM_UPDATE_OUTPUT    (WM_USER + 100)
#define WM_COMPILE_FINISHED (WM_USER + 101)

HWND g_hMainWnd=NULL, g_hEdit=NULL, g_hOutput=NULL, g_hStatusBar=NULL;
HWND g_hBtnSave=NULL, g_hBtnCompile=NULL, g_hBtnRun=NULL, g_hBtnStop=NULL, g_hBtnClear=NULL;
HWND g_hHelpWnd=NULL, g_hHelpEdit=NULL;
HFONT g_hFont=NULL, g_hOutFont=NULL, g_hHelpFont=NULL;
HINSTANCE g_hInst=NULL;
string g_currentFilePath = "";
string g_currentFileName;
string g_tempDir = ".";
bool g_isRunning=false, g_isCompiling=false;

static std::atomic<HANDLE> g_hGppProcess{NULL};
static std::atomic<HANDLE> g_hOutputProcess{NULL};
static std::atomic<bool>   g_stopRequested{false};

// ============================================================
// 编码转换
// ============================================================
static bool cpp_is_utf8() {
    static const int flag = (sizeof("中") == 4) ? 1 : 0;
    return flag == 1;
}

static string to_ansi(const char* s) {
    if (!s || !*s) return string();
    if (!cpp_is_utf8()) return string(s);
    int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s, -1, NULL, 0);
    if (wlen <= 0) return string(s);
    vector<wchar_t> wbuf(wlen);
    MultiByteToWideChar(CP_UTF8, 0, s, -1, &wbuf[0], wlen);
    int alen = WideCharToMultiByte(CP_ACP, 0, &wbuf[0], -1, NULL, 0, NULL, NULL);
    if (alen <= 0) return string(s);
    vector<char> abuf(alen);
    WideCharToMultiByte(CP_ACP, 0, &wbuf[0], -1, &abuf[0], alen, NULL, NULL);
    return string(&abuf[0], alen - 1);
}

static string to_ansi_n(const char* s, size_t len) {
    if (!s || len == 0) return string();
    if (!cpp_is_utf8()) return string(s, len);
    int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s, (int)len, NULL, 0);
    if (wlen <= 0) return string(s, len);
    vector<wchar_t> wbuf(wlen);
    MultiByteToWideChar(CP_UTF8, 0, s, (int)len, &wbuf[0], wlen);
    int alen = WideCharToMultiByte(CP_ACP, 0, &wbuf[0], wlen, NULL, 0, NULL, NULL);
    if (alen <= 0) return string(s, len);
    vector<char> abuf(alen);
    WideCharToMultiByte(CP_ACP, 0, &wbuf[0], wlen, &abuf[0], alen, NULL, NULL);
    return string(&abuf[0], alen);
}

static bool looks_like_utf8(const string& s) {
    if (s.size() >= 3 &&
        (unsigned char)s[0] == 0xEF &&
        (unsigned char)s[1] == 0xBB &&
        (unsigned char)s[2] == 0xBF) return true;
    size_t cjk3 = 0;
    for (size_t k = 0; k + 2 < s.size(); ++k) {
        unsigned char c0 = (unsigned char)s[k];
        unsigned char c1 = (unsigned char)s[k+1];
        unsigned char c2 = (unsigned char)s[k+2];
        if (c0 >= 0xE4 && c0 <= 0xE9 &&
            (c1 & 0xC0) == 0x80 && (c2 & 0xC0) == 0x80) {
            if (++cjk3 >= 3) return true;
        }
    }
    return false;
}

static string utf8_to_ansi(const string& s) {
    size_t start = 0;
    if (s.size() >= 3 &&
        (unsigned char)s[0] == 0xEF &&
        (unsigned char)s[1] == 0xBB &&
        (unsigned char)s[2] == 0xBF) start = 3;
    if (start >= s.size()) return string();
    int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
                                   s.c_str() + start, (int)(s.size() - start), NULL, 0);
    if (wlen <= 0) return s;
    vector<wchar_t> wbuf(wlen);
    MultiByteToWideChar(CP_UTF8, 0, s.c_str() + start,
                        (int)(s.size() - start), &wbuf[0], wlen);
    int alen = WideCharToMultiByte(CP_ACP, 0, &wbuf[0], wlen, NULL, 0, NULL, NULL);
    if (alen <= 0) return s;
    vector<char> abuf(alen);
    WideCharToMultiByte(CP_ACP, 0, &wbuf[0], wlen, &abuf[0], alen, NULL, NULL);
    return string(&abuf[0], alen);
}

#define XA(s) (to_ansi(s).c_str())

// ============================================================
// 辅助
// ============================================================
static bool is_ascii_ident(unsigned char c) {
    return (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') || c=='_';
}

static size_t advance_one_char(const string& s, size_t pos) {
    if (pos >= s.size()) return 1;
    unsigned char c = (unsigned char)s[pos];
    if (c < 0x80) return 1;
    if ((c & 0xF8) == 0xF0 && pos + 3 < s.size() &&
        ((unsigned char)s[pos+1] & 0xC0) == 0x80 &&
        ((unsigned char)s[pos+2] & 0xC0) == 0x80 &&
        ((unsigned char)s[pos+3] & 0xC0) == 0x80) return 4;
    if ((c & 0xF0) == 0xE0 && pos + 2 < s.size() &&
        ((unsigned char)s[pos+1] & 0xC0) == 0x80 &&
        ((unsigned char)s[pos+2] & 0xC0) == 0x80) return 3;
    if ((c & 0xE0) == 0xC0 && pos + 1 < s.size() &&
        ((unsigned char)s[pos+1] & 0xC0) == 0x80) return 2;
    return 2;
}

static bool ends_with_cjk_hanzi(const string& s) {
    if (s.size() < 2) return false;
    size_t p = s.size();
    while (p > 0) { p--; if (((unsigned char)s[p] & 0xC0) != 0x80) break; }
    unsigned char last = (unsigned char)s[p];
    if (last >= 0x80) return true;
    if (p > 0 && last >= 0x40 && last <= 0x7E) {
        unsigned char lead = (unsigned char)s[p-1];
        if (lead >= 0x81 && lead <= 0xFE) return true;
    }
    return false;
}

static bool is_fullwidth_punct_at(const string& s, size_t pos) {
    if (pos >= s.size()) return false;
    unsigned char c = (unsigned char)s[pos];
    if (c < 0x80) return false;
    if (c >= 0xA1 && c <= 0xA3) return true;
    if (c == 0xEF) return true;
    if (c == 0xE3 && pos + 1 < s.size() &&
        (unsigned char)s[pos+1] == 0x80) return true;
    return false;
}

// ============================================================
// 标点表
// ============================================================
static const vector<pair<string,string> >& get_punct_pairs() {
    static vector<pair<string,string> > list;
    static bool ready = false;
    if (!ready) {
        struct { const char* f; const char* t; } raw[] = {
            {"(","("},{")",")"},{"「","["},{"」","]"},
            {"【","{"},{"】","}"},{"《","{"},{"》","}"},
            {",",","},{"、",","},{";",";"},{":"," << "}
        };
        for (size_t i = 0; i < sizeof(raw)/sizeof(raw[0]); ++i)
            list.push_back(make_pair(to_ansi(raw[i].f), string(raw[i].t)));
        ready = true;
    }
    return list;
}

static const vector<string>& get_punct_list() {
    static vector<string> list;
    static bool ready = false;
    if (!ready) {
        const char* raw[] = {";",":",",","。","、","!","?",
            "(",")","【","】","「","」","《","》"," "};
        for (size_t i = 0; i < sizeof(raw)/sizeof(raw[0]); ++i)
            list.push_back(to_ansi(raw[i]));
        ready = true;
    }
    return list;
}

static bool is_punct_pattern(const string& from) {
    const vector<string>& L = get_punct_list();
    for (size_t k = 0; k < L.size(); ++k) if (from == L[k]) return true;
    return false;
}

static bool ends_with_any_punct(const string& s) {
    const vector<string>& L = get_punct_list();
    for (size_t k = 0; k < L.size(); ++k) {
        size_t n = L[k].size();
        if (s.size() >= n && s.compare(s.size()-n, n, L[k]) == 0) return true;
    }
    return false;
}

static bool is_cjk_terminator_at(const string& s, size_t pos) {
    const vector<string>& L = get_punct_list();
    for (size_t k = 0; k < L.size(); ++k) {
        size_t n = L[k].size();
        if (pos + n <= s.size() && s.compare(pos, n, L[k]) == 0)
            return true;
    }
    return false;
}

static string translate_punct_only(const string& s) {
    const vector<pair<string,string> >& subs = get_punct_pairs();
    string r = s;
    for (size_t k = 0; k < subs.size(); ++k) {
        const string& from = subs[k].first;
        const string& to   = subs[k].second;
        if (from.empty()) continue;
        size_t flen = from.size(), tlen = to.size(), pos = 0;
        while ((pos = r.find(from, pos)) != string::npos) {
            r.replace(pos, flen, to);
            pos += tlen;
        }
    }
    return r;
}

static const char* GetFilterAnsi() {
    static const char RAW[] = "玄源文件\0*.玄\0所有文件\0*.*\0";
    static const string ANSI = to_ansi_n(RAW, sizeof(RAW) - 1);
    return ANSI.c_str();
}

static const char* GetDefExtAnsi() {
    static const string s = to_ansi("玄");
    return s.c_str();
}

// ============================================================
// 用法大全
// ============================================================
const char* HELP_TEXT =
"================================================================\n"
"                《玄》语言用法大全 v3.6.3\n"
"================================================================\n"
"\n"
"【1 文件结构】\n"
"头文件《标准IO》\n"
"使用命名空间标准;\n"
"主程序:\n"
"    代码...\n"
"。\n"
"提示:关键字后建议跟空格或全角标点。\n"
"      标识符中如包含关键字,可用 \\ 转义。\n"
"\n"
"【2 头文件】(35 个)\n"
"  基础:标准IO / 字符串 / 向量 / 内存\n"
"  算法:算法 / 数学 / 数值 / 随机数 / 随机\n"
"  容器:映射 / 字典 / 集合 / 队列 / 栈 / 链表 / 数组 / 双端队列\n"
"  工具:元组 / 对组 / 工具 / 函数 / 时间\n"
"  并发:线程 / 互斥 / 互斥锁 / 原子 / 条件变量\n"
"  输入:文件 / 文件流 / 字符串流 / 流格式 / 异常 / 迭代器\n"
"  其他:位集 / 复数\n"
"\n"
"【3 命名空间】\n"
"使用命名空间标准;       -> using namespace std;\n"
"使用命名空间 我的库;     -> using namespace 我的库;\n"
"\n"
"【4 基本类型】\n"
"整数 int / 浮点 float / 双精度 double / 字符 char\n"
"布尔 bool / 文本 std::string / 字符串 std::string / 无 void\n"
"真 true / 假 false / 定义 int\n"
"短整数 short / 长整数 long long / 超长整数 long long\n"
"无符号整数 unsigned int / 无符号短整数 unsigned short\n"
"无符号长整数 unsigned long long\n"
"\n"
"【5 容器类型别名】\n"
"整数映射 / 文本映射 / 整数集合 / 文本集合\n"
"整数队列 / 文本队列 / 整数栈 / 文本栈\n"
"整数对 / 文本对 / 整数双端队列\n"
"整数列表 / 文本列表 / 浮点列表\n"
"短整数列表 / 长整数列表 / 超长整数列表\n"
"\n"
"【6 输入输出】\n"
"输出:\"你好\":换行;\n"
"输入:a;\n"
"全角冒号(:)翻译为 <<\n"
"\n"
"【7 运算符】\n"
"比较:小于 <  大于 >  不大于 <=  不小于 >=\n"
"      等于 ==  不等于 !=  比...小 <  比...大 >\n"
"      比...小 允许跨行、紧凑写法(i比a小)\n"
"逻辑:与/且 &&  或/或者 ||  非 !\n"
"算术:加 +  减 -  乘 *  除 /  模 %  递增 ++  递减 --\n"
"大小:大小(T) / 字节数(T)   -> sizeof(T)\n"
"\n"
"【8 控制流】\n"
"如果(条件)《...》 否则如果《...》 否则《...》\n"
"对于(整数 i=0;i 小于 10;i 递增)《...》\n"
"只要(条件)《...》 / 当(条件)《...》\n"
"跳出 break / 继续 continue / 返回 return\n"
"\n"
"【9 玄独有语法】\n"
"  ● 重复 N 次\n"
"      重复 3 次 《 输出:\"你好\":换行; 》\n"
"\n"
"  ● 对于 X 从 A 到 B(闭区间)\n"
"      对于 i 从 1 到 5 《 输出:i:换行; 》\n"
"      对于 i 从 3 到 1 递减 《 ... 》\n"
"\n"
"  ● 若 C 则 S;否则若 C 则 S;否则 S;\n"
"      若 分数 大于 90 则 输出:\"优\":换行;\n"
"      否则若 分数 大于 60 则 输出:\"及格\":换行;\n"
"      否则 输出:\"不及格\":换行;\n"
"      注意:\"若\"/\"则\"前后要有空格。\n"
"\n"
"  ● 环 《...》        无限循环\n"
"\n"
"  ● 卦 N / 卦 A 到 B  随机数(自动 srand)\n"
"      卦 6          -> 范围 0..5\n"
"      卦 1 到 6     -> 范围 1..6\n"
"\n"
"  ● 承                继承\n"
"  ● 此 的 / 的         成员访问\n"
"\n"
"【10 类与结构】\n"
"类 学生 《 公开: ... 继承:类 大学生 承 学生 《 ... 》\n"
"\n"
"【11 指针】\n"
"整数指针 / 短整数指针 / 长整数指针 / 超长整数指针\n"
"取地址 / 取内容 / 空指针 / 新建 / 释放\n"
"\n"
"【12 动态内存】\n"
"新建 整数(100) / 新建数组 整数「10」 / 释放 p\n"
"\n"
"【13 容器初始化 / 索引】\n"
"整数列表 v = 【1, 2, 3】; v「0」 -> v[0]\n"
"\n"
"【14 头文件对照表】\n"
"  标准IO -> iostream + string + vector + memory + cstdlib\n"
"  其余 34 个见源码\n"
"\n"
"【15 常见错误】\n"
"1. 忘记写 头文件《标准IO》\n"
"2. 忘记写 使用命名空间标准;\n"
"3. 字符串用中文引号 "" ------ 必须用英文引号 \"\"\n"
"4. 缺少主程序结尾的句号 。\n"
"5. 索引用 【】 会错 ------ 索引用 「」,初始化用 【】\n"
"6. 关键字与中文变量名粘连 ------ 中间加空格或全角标点\n"
"7. \"若\" / \"则\" / \"否则若\" / \"此 的\" / \" 的 \" 前后要空格\n"
"\n"
"                       《玄》IDE v3.6.3\n"
"================================================================\n";

// ============================================================
// 文件工具
// ============================================================
string read_file(const string& path) {
    ifstream f(path.c_str(), ios::binary);
    if (!f) return "";
    stringstream ss; ss << f.rdbuf();
    return ss.str();
}
void write_file(const string& path, const string& content) {
    ofstream f(path.c_str(), ios::binary);
    f << content;
}

// ============================================================
// 构建 pattern
// ============================================================
static void build_patterns(vector<pair<string,string> >& patterns) {
    patterns.push_back(make_pair(to_ansi("头文件《标准IO》"), string("#include <iostream>\n#include <string>\n#include <vector>\n#include <memory>\n#include <cstdlib>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《字符串》"), string("#include <string>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《向量》"),   string("#include <vector>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《内存》"),   string("#include <memory>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《算法》"),   string("#include <algorithm>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《数学》"),   string("#include <cmath>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《数值》"),   string("#include <numeric>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《随机数》"), string("#include <random>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《随机》"),   string("#include <random>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《映射》"),   string("#include <map>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《字典》"),   string("#include <map>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《集合》"),   string("#include <set>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《队列》"),   string("#include <queue>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《栈》"),     string("#include <stack>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《链表》"),   string("#include <list>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《数组》"),   string("#include <array>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《双端队列》"),string("#include <deque>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《元组》"),   string("#include <tuple>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《对组》"),   string("#include <utility>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《工具》"),   string("#include <utility>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《函数》"),   string("#include <functional>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《时间》"),   string("#include <chrono>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《线程》"),   string("#include <thread>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《互斥锁》"), string("#include <mutex>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《互斥》"),   string("#include <mutex>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《原子》"),   string("#include <atomic>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《条件变量》"),string("#include <condition_variable>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《文件流》"), string("#include <fstream>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《文件》"),   string("#include <fstream>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《字符串流》"),string("#include <sstream>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《流格式》"), string("#include <iomanip>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《异常》"),   string("#include <stdexcept>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《迭代器》"), string("#include <iterator>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《位集》"),   string("#include <bitset>\n")));
    patterns.push_back(make_pair(to_ansi("头文件《复数》"),   string("#include <complex>\n")));

    patterns.push_back(make_pair(to_ansi("使用命名空间标准;"), string("using namespace std;")));
    patterns.push_back(make_pair(to_ansi("使用命名空间标准"),   string("using namespace std")));
    patterns.push_back(make_pair(to_ansi("使用命名空间"),       string("using namespace ")));
    patterns.push_back(make_pair(to_ansi("命名空间"),           string("namespace ")));
    patterns.push_back(make_pair(to_ansi("主程序:"), string("int main() {")));

    patterns.push_back(make_pair(to_ansi("输出:"), string("std::cout << ")));
    patterns.push_back(make_pair(to_ansi("输出"),   string("std::cout << ")));
    patterns.push_back(make_pair(to_ansi("输入:"), string("std::cin >> ")));
    patterns.push_back(make_pair(to_ansi("输入"),   string("std::cin >> ")));
    patterns.push_back(make_pair(to_ansi("换行"),   string("std::endl")));

    patterns.push_back(make_pair(to_ansi("整数双端队列"), string("std::deque<int>")));
    patterns.push_back(make_pair(to_ansi("整数映射"),     string("std::map<int,int>")));
    patterns.push_back(make_pair(to_ansi("文本映射"),     string("std::map<std::string,std::string>")));
    patterns.push_back(make_pair(to_ansi("整数集合"),     string("std::set<int>")));
    patterns.push_back(make_pair(to_ansi("文本集合"),     string("std::set<std::string>")));
    patterns.push_back(make_pair(to_ansi("整数队列"),     string("std::queue<int>")));
    patterns.push_back(make_pair(to_ansi("文本队列"),     string("std::queue<std::string>")));
    patterns.push_back(make_pair(to_ansi("整数栈"),       string("std::stack<int>")));
    patterns.push_back(make_pair(to_ansi("文本栈"),       string("std::stack<std::string>")));
    patterns.push_back(make_pair(to_ansi("整数对"),       string("std::pair<int,int>")));
    patterns.push_back(make_pair(to_ansi("文本对"),       string("std::pair<std::string,std::string>")));
    patterns.push_back(make_pair(to_ansi("整数列表"),     string("std::vector<int>")));
    patterns.push_back(make_pair(to_ansi("文本列表"),     string("std::vector<std::string>")));
    patterns.push_back(make_pair(to_ansi("浮点列表"),     string("std::vector<float>")));

    // ---- v3.6.3 补:长短整数、无符号 ----
    patterns.push_back(make_pair(to_ansi("无符号长整数"),   string("unsigned long long")));
    patterns.push_back(make_pair(to_ansi("无符号短整数"),   string("unsigned short")));
    patterns.push_back(make_pair(to_ansi("无符号整数"),     string("unsigned int")));
    patterns.push_back(make_pair(to_ansi("超长整数指针"),   string("long long*")));
    patterns.push_back(make_pair(to_ansi("长整数指针"),     string("long long*")));
    patterns.push_back(make_pair(to_ansi("短整数指针"),     string("short*")));
    patterns.push_back(make_pair(to_ansi("超长整数列表"),   string("std::vector<long long>")));
    patterns.push_back(make_pair(to_ansi("长整数列表"),     string("std::vector<long long>")));
    patterns.push_back(make_pair(to_ansi("短整数列表"),     string("std::vector<short>")));
    patterns.push_back(make_pair(to_ansi("超长整数"),       string("long long")));
    patterns.push_back(make_pair(to_ansi("长整数"),         string("long long")));
    patterns.push_back(make_pair(to_ansi("短整数"),         string("short")));

    patterns.push_back(make_pair(to_ansi("整数指针"),   string("int*")));
    patterns.push_back(make_pair(to_ansi("文本指针"),   string("std::string*")));
    patterns.push_back(make_pair(to_ansi("浮点指针"),   string("float*")));
    patterns.push_back(make_pair(to_ansi("双精度指针"), string("double*")));
    patterns.push_back(make_pair(to_ansi("字符指针"),   string("char*")));
    patterns.push_back(make_pair(to_ansi("布尔指针"),   string("bool*")));

    patterns.push_back(make_pair(to_ansi("整数"),   string("int")));
    patterns.push_back(make_pair(to_ansi("浮点"),   string("float")));
    patterns.push_back(make_pair(to_ansi("双精度"), string("double")));
    patterns.push_back(make_pair(to_ansi("字符"),   string("char")));
    patterns.push_back(make_pair(to_ansi("布尔"),   string("bool")));
    patterns.push_back(make_pair(to_ansi("文本"),   string("std::string")));
    patterns.push_back(make_pair(to_ansi("字符串"), string("std::string")));
    patterns.push_back(make_pair(to_ansi("无"),     string("void")));
    patterns.push_back(make_pair(to_ansi("定义"),   string("int")));

    patterns.push_back(make_pair(to_ansi("取地址"),   string("&")));
    patterns.push_back(make_pair(to_ansi("取址"),     string("&")));
    patterns.push_back(make_pair(to_ansi("取内容"),   string("*")));
    patterns.push_back(make_pair(to_ansi("解引用"),   string("*")));
    patterns.push_back(make_pair(to_ansi("空指针"),   string("nullptr")));
    patterns.push_back(make_pair(to_ansi("新建数组"), string("new ")));
    patterns.push_back(make_pair(to_ansi("新建"),     string("new ")));
    patterns.push_back(make_pair(to_ansi("释放数组"), string("delete[] ")));
    patterns.push_back(make_pair(to_ansi("释放"),     string("delete ")));
    patterns.push_back(make_pair(to_ansi("常量"),     string("const ")));
    patterns.push_back(make_pair(to_ansi("静态"),     string("static ")));

    patterns.push_back(make_pair(to_ansi("不大于"), string("<=")));
    patterns.push_back(make_pair(to_ansi("不小于"), string(">=")));
    patterns.push_back(make_pair(to_ansi("小于"),   string("<")));
    patterns.push_back(make_pair(to_ansi("大于"),   string(">")));
    patterns.push_back(make_pair(to_ansi("等于"),   string("==")));
    patterns.push_back(make_pair(to_ansi("不等于"), string("!=")));
    patterns.push_back(make_pair(to_ansi("与"),     string("&&")));
    patterns.push_back(make_pair(to_ansi("且"),     string("&&")));
    patterns.push_back(make_pair(to_ansi("或者"),   string("||")));
    patterns.push_back(make_pair(to_ansi("或"),     string("||")));
    patterns.push_back(make_pair(to_ansi("非"),     string("!")));

    patterns.push_back(make_pair(to_ansi("递增"), string("++")));
    patterns.push_back(make_pair(to_ansi("递减"), string("--")));
    patterns.push_back(make_pair(to_ansi("加"),   string("+")));
    patterns.push_back(make_pair(to_ansi("减"),   string("-")));
    patterns.push_back(make_pair(to_ansi("乘"),   string("*")));
    patterns.push_back(make_pair(to_ansi("除"),   string("/")));
    patterns.push_back(make_pair(to_ansi("模"),   string("%")));

    patterns.push_back(make_pair(to_ansi("《"), string("{")));
    patterns.push_back(make_pair(to_ansi("》"), string("}")));
    patterns.push_back(make_pair(to_ansi("【"), string("{")));
    patterns.push_back(make_pair(to_ansi("】"), string("}")));
    patterns.push_back(make_pair(to_ansi("「"), string("[")));
    patterns.push_back(make_pair(to_ansi("」"), string("]")));
    patterns.push_back(make_pair(to_ansi("("), string("(")));
    patterns.push_back(make_pair(to_ansi(")"), string(")")));
    patterns.push_back(make_pair(to_ansi(";"), string(";")));
    patterns.push_back(make_pair(to_ansi(":"), string(" << ")));
    patterns.push_back(make_pair(to_ansi("。"), string("}")));
    patterns.push_back(make_pair(to_ansi(","), string(",")));
    patterns.push_back(make_pair(to_ansi("、"), string(",")));
    patterns.push_back(make_pair(to_ansi("!"), string("!")));
    patterns.push_back(make_pair(to_ansi("?"), string("?")));
    patterns.push_back(make_pair(to_ansi(" "), string(" ")));

    patterns.push_back(make_pair(to_ansi("否则如果"), string("else if ")));
    patterns.push_back(make_pair(to_ansi("否则"),     string("else ")));
    patterns.push_back(make_pair(to_ansi("如果"),     string("if ")));
    patterns.push_back(make_pair(to_ansi("对于"),     string("for ")));
    patterns.push_back(make_pair(to_ansi("只要"),     string("while ")));
    patterns.push_back(make_pair(to_ansi("当"),       string("while ")));
    patterns.push_back(make_pair(to_ansi("跳出"),     string("break")));
    patterns.push_back(make_pair(to_ansi("继续"),     string("continue")));
    patterns.push_back(make_pair(to_ansi("返回"),     string("return ")));

    patterns.push_back(make_pair(to_ansi("类"),     string("class ")));
    patterns.push_back(make_pair(to_ansi("结构"),   string("struct ")));
    patterns.push_back(make_pair(to_ansi("枚举"),   string("enum ")));
    patterns.push_back(make_pair(to_ansi("继承"),   string(": public ")));
    patterns.push_back(make_pair(to_ansi("公开"),   string("public:")));
    patterns.push_back(make_pair(to_ansi("公有"),   string("public:")));
    patterns.push_back(make_pair(to_ansi("私有"),   string("private:")));
    patterns.push_back(make_pair(to_ansi("保护"),   string("protected:")));
    patterns.push_back(make_pair(to_ansi("虚函数"), string("virtual ")));

    patterns.push_back(make_pair(to_ansi("真"), string("true")));
    patterns.push_back(make_pair(to_ansi("假"), string("false")));

    patterns.push_back(make_pair(to_ansi("否则若 "), string("else if (")));
    patterns.push_back(make_pair(to_ansi("若 "),     string("if (")));
    patterns.push_back(make_pair(to_ansi("则 "),     string(") ")));
    patterns.push_back(make_pair(to_ansi("则"),      string(")")));
    patterns.push_back(make_pair(to_ansi("承"),      string(": public ")));
    patterns.push_back(make_pair(to_ansi("此 的 "),  string("this->")));
    patterns.push_back(make_pair(to_ansi(" 的 "),    string(". ")));
    patterns.push_back(make_pair(to_ansi("字节数("), string("sizeof(")));
    patterns.push_back(make_pair(to_ansi("大小("),   string("sizeof(")));

    sort(patterns.begin(), patterns.end(),
         [](const pair<string, string>& a, const pair<string, string>& b) {
             return a.first.size() > b.first.size();
         });
}

// ============================================================
// 转译核心
// ============================================================
string translate_xuan(const string& src) {
    static vector<pair<string,string> > patterns;
    static bool patterns_ready = false;
    if (!patterns_ready) { build_patterns(patterns); patterns_ready = true; }

    static string BI, XIAO, DA, ZUO, YOU, KUO_L, KUO_R;
    static bool kw_ready = false;
    if (!kw_ready) {
        BI = to_ansi("比"); XIAO = to_ansi("小"); DA = to_ansi("大");
        ZUO = to_ansi("("); YOU = to_ansi(")");
        KUO_L = to_ansi("《"); KUO_R = to_ansi("》");
        kw_ready = true;
    }
    const size_t BI_LEN = BI.size(), XIAO_LEN = XIAO.size(), DA_LEN = DA.size();
    const size_t ZUO_LEN = ZUO.size(), YOU_LEN = YOU.size();
    const size_t KUO_L_LEN = KUO_L.size(), KUO_R_LEN = KUO_R.size();

    static string REPEAT_KW, TIMES_KW, FOR_KW, CONG_KW, DAO_KW, DEC_KW, GUA_KW, HUAN_KW;
    static bool new_kw_ready = false;
    if (!new_kw_ready) {
        REPEAT_KW = to_ansi("重复");
        TIMES_KW  = to_ansi("次");
        FOR_KW    = to_ansi("对于");
        CONG_KW   = to_ansi("从");
        DAO_KW    = to_ansi("到");
        DEC_KW    = to_ansi("递减");
        GUA_KW    = to_ansi("卦");
        HUAN_KW   = to_ansi("环");
        new_kw_ready = true;
    }
    const size_t REPEAT_LEN = REPEAT_KW.size(), TIMES_LEN = TIMES_KW.size();
    const size_t FOR_KW_LEN = FOR_KW.size(), CONG_LEN = CONG_KW.size();
    const size_t DAO_LEN = DAO_KW.size(), DEC_LEN = DEC_KW.size();
    const size_t GUA_LEN = GUA_KW.size(), HUAN_LEN = HUAN_KW.size();

    static string ZE_SPACE_KW, ZE_KW;
    static bool ze_ready = false;
    if (!ze_ready) {
        ZE_SPACE_KW = to_ansi("则 ");
        ZE_KW       = to_ansi("则");
        ze_ready = true;
    }

    vector<int> repeat_stack;
    int next_rep_id = 0;   // v3.6.3:独立递增计数器,避免嵌套同名

    string out;
    size_t i = 0;
    const size_t N = src.size();
    while (i < N) {
        if (src[i] == '"') {
            out += src[i++];
            while (i < N) {
                if (src[i] == '\\' && i+1 < N) { out += src[i++]; out += src[i++]; continue; }
                if (src[i] == '"') break;
                out += src[i++];
            }
            if (i < N) out += src[i++];
            continue;
        }
        if (src[i] == '\\' && i + 1 < N) {
            size_t clen = advance_one_char(src, i + 1);
            if (i + 1 + clen <= N) { out += src.substr(i + 1, clen); i += 1 + clen; continue; }
        }
        if (src[i] == '/' && i+1 < N && src[i+1] == '/') {
            while (i < N && src[i] != '\n') out += src[i++];
            continue;
        }
        if (src[i] == '/' && i+1 < N && src[i+1] == '*') {
            out += src[i++]; out += src[i++];
            while (i < N && !(src[i-1] == '*' && src[i] == '/')) out += src[i++];
            if (i < N) out += src[i++];
            continue;
        }

        bool matched = false;

        // ---- 重复 N 次 ----
        if (!matched && REPEAT_LEN > 0 && i + REPEAT_LEN <= N &&
            src.compare(i, REPEAT_LEN, REPEAT_KW) == 0) {
            if (i == 0 || !is_ascii_ident((unsigned char)src[i-1])) {
                int id = next_rep_id++;   // v3.6.3:独立递增
                repeat_stack.push_back(id);
                out += "for (int _i_rep_" + to_string(id) + " = 0; _i_rep_"
                       + to_string(id) + " < (";
                i += REPEAT_LEN;
                matched = true;
            }
        }
        // ---- 次 ----
        if (!matched && !repeat_stack.empty() && TIMES_LEN > 0 &&
            i + TIMES_LEN <= N && src.compare(i, TIMES_LEN, TIMES_KW) == 0) {
            if (i == 0 || !is_ascii_ident((unsigned char)src[i-1])) {
                size_t aft = i + TIMES_LEN;
                unsigned char nx = (aft < N) ? (unsigned char)src[aft] : (unsigned char)0;
                if (nx == 0 || isspace(nx) ||
                    (aft + KUO_L_LEN <= N &&
                     src.compare(aft, KUO_L_LEN, KUO_L) == 0)) {
                    int id = repeat_stack.back();
                    repeat_stack.pop_back();
                    out += "); _i_rep_" + to_string(id) + "++) ";
                    i = aft;
                    matched = true;
                }
            }
        }
        // ---- 对于 X 从 A 到 B [递减] ----
        if (!matched && FOR_KW_LEN > 0 && i + FOR_KW_LEN <= N &&
            src.compare(i, FOR_KW_LEN, FOR_KW) == 0) {
            if (i == 0 || !is_ascii_ident((unsigned char)src[i-1])) {
                size_t j = i + FOR_KW_LEN;
                while (j < N && isspace((unsigned char)src[j])) j++;
                size_t vs = j;
                while (j < N && !isspace((unsigned char)src[j]) &&
                       !(j + CONG_LEN <= N &&
                         src.compare(j, CONG_LEN, CONG_KW) == 0))
                    j += advance_one_char(src, j);
                size_t ve = j;
                while (j < N && isspace((unsigned char)src[j])) j++;
                if (ve > vs && j + CONG_LEN <= N &&
                    src.compare(j, CONG_LEN, CONG_KW) == 0) {
                    string var = src.substr(vs, ve - vs);
                    j += CONG_LEN;
                    while (j < N && isspace((unsigned char)src[j])) j++;
                    size_t as = j;
                    while (j < N && !isspace((unsigned char)src[j]) &&
                           !(j + DAO_LEN <= N &&
                             src.compare(j, DAO_LEN, DAO_KW) == 0))
                        j += advance_one_char(src, j);
                    size_t ae = j;
                    while (j < N && isspace((unsigned char)src[j])) j++;
                    if (ae > as && j + DAO_LEN <= N &&
                        src.compare(j, DAO_LEN, DAO_KW) == 0) {
                        string A = src.substr(as, ae - as);
                        j += DAO_LEN;
                        while (j < N && isspace((unsigned char)src[j])) j++;
                        size_t bs = j;
                        while (j < N && !isspace((unsigned char)src[j]) &&
                               !(j + DEC_LEN <= N &&
                                 src.compare(j, DEC_LEN, DEC_KW) == 0) &&
                               !(j + KUO_L_LEN <= N &&
                                 src.compare(j, KUO_L_LEN, KUO_L) == 0)) {
                            if (is_cjk_terminator_at(src, j)) break;
                            j += advance_one_char(src, j);
                        }
                        size_t be = j;
                        if (be > bs) {
                            string B = src.substr(bs, be - bs);
                            while (j < N && isspace((unsigned char)src[j])) j++;
                            bool desc = false;
                            if (j + DEC_LEN <= N &&
                                src.compare(j, DEC_LEN, DEC_KW) == 0) {
                                desc = true; j += DEC_LEN;
                            }
                            out += "for (int " + var + " = " + A + "; " + var;
                            out += desc ? " >= " : " <= ";
                            out += B + "; " + var;
                            out += desc ? "--" : "++";
                            out += ") ";
                            i = j;
                            matched = true;
                        }
                    }
                }
            }
        }
        // ---- 环 《 ----
        if (!matched && HUAN_LEN > 0 && i + HUAN_LEN <= N &&
            src.compare(i, HUAN_LEN, HUAN_KW) == 0) {
            if (i == 0 || !is_ascii_ident((unsigned char)src[i-1])) {
                size_t j = i + HUAN_LEN;
                while (j < N && isspace((unsigned char)src[j])) j++;
                if (j + KUO_L_LEN <= N &&
                    src.compare(j, KUO_L_LEN, KUO_L) == 0) {
                    out += "while (true) {";
                    i = j + KUO_L_LEN;
                    matched = true;
                }
            }
        }
        // ---- 卦 N / 卦 A 到 B ----
        if (!matched && GUA_LEN > 0 && i + GUA_LEN <= N &&
            src.compare(i, GUA_LEN, GUA_KW) == 0) {
            if (i == 0 || !is_ascii_ident((unsigned char)src[i-1])) {
                size_t j = i + GUA_LEN;
                while (j < N && isspace((unsigned char)src[j])) j++;
                size_t as = j;
                while (j < N && !isspace((unsigned char)src[j]) &&
                       src[j] != ';' && src[j] != ')' &&
                       src[j] != ',' && src[j] != '(' &&
                       src[j] != '{' && src[j] != '}') {
                    if (j + DAO_LEN <= N &&
                        src.compare(j, DAO_LEN, DAO_KW) == 0) break;
                    if (is_cjk_terminator_at(src, j)) break;
                    j += advance_one_char(src, j);
                }
                size_t ae = j;
                if (ae > as) {
                    while (j < N && isspace((unsigned char)src[j])) j++;
                    if (j + DAO_LEN <= N &&
                        src.compare(j, DAO_LEN, DAO_KW) == 0) {
                        j += DAO_LEN;
                        while (j < N && isspace((unsigned char)src[j])) j++;
                        size_t bs = j;
                        while (j < N && !isspace((unsigned char)src[j]) &&
                               src[j] != ';' && src[j] != ')' &&
                               src[j] != ',' && src[j] != '(' &&
                               src[j] != '{' && src[j] != '}') {
                            if (is_cjk_terminator_at(src, j)) break;
                            j += advance_one_char(src, j);
                        }
                        size_t be = j;
                        if (be > bs) {
                            string A = src.substr(as, ae - as);
                            string B = src.substr(bs, be - bs);
                            out += "((rand() % ((" + B + ") - (" + A
                                 + ") + 1)) + (" + A + "))";
                            i = j;
                            matched = true;
                        }
                    } else {
                        string N_ = src.substr(as, ae - as);
                        out += "(rand() % (" + N_ + "))";
                        i = ae;
                        matched = true;
                    }
                }
            }
        }

        // ---- "比" 结构 ----
        if (!matched && BI_LEN > 0 && i + BI_LEN <= N && src.compare(i, BI_LEN, BI) == 0) {
            bool boundary_ok = (i == 0) || !is_ascii_ident((unsigned char)src[i-1]);
            if (!boundary_ok) {
                size_t probe = i + BI_LEN;
                if (probe < N) {
                    unsigned char p = (unsigned char)src[probe];
                    bool sp = isspace(p) != 0;
                    bool xa = (probe + XIAO_LEN <= N && src.compare(probe, XIAO_LEN, XIAO) == 0);
                    bool da = (probe + DA_LEN   <= N && src.compare(probe, DA_LEN,   DA)   == 0);
                    boundary_ok = !sp && !xa && !da;
                }
            }
            if (boundary_ok) {
                size_t v1_end = i;
                while (v1_end > 0 && isspace((unsigned char)src[v1_end-1])) v1_end--;
                size_t v1_start = v1_end;
                while (v1_start > 0 &&
                       !isspace((unsigned char)src[v1_start-1]) &&
                       src[v1_start-1] != '(' &&
                       !(v1_start >= ZUO_LEN && src.compare(v1_start - ZUO_LEN, ZUO_LEN, ZUO) == 0))
                    v1_start--;
                size_t j = i + BI_LEN;
                while (j < N && isspace((unsigned char)src[j])) j++;
                size_t v2_start = j, v2_end = j;
                int depth = 0;
                const size_t MAX_SCAN = 4096;
                while (v2_end < N && (v2_end - v2_start) < MAX_SCAN) {
                    unsigned char c = (unsigned char)src[v2_end];
                    if (c == '(') { depth++; v2_end++; continue; }
                    if (c == ')') { if (depth == 0) break; depth--; v2_end++; continue; }
                    if (v2_end + ZUO_LEN <= N && src.compare(v2_end, ZUO_LEN, ZUO) == 0) { depth++; v2_end += ZUO_LEN; continue; }
                    if (v2_end + YOU_LEN <= N && src.compare(v2_end, YOU_LEN, YOU) == 0) { if (depth == 0) break; depth--; v2_end += YOU_LEN; continue; }
                    if (depth == 0) {
                        if (isspace(c) || c == ';' || c == '{' || c == '}') break;
                        if (v2_end + KUO_L_LEN <= N && src.compare(v2_end, KUO_L_LEN, KUO_L) == 0) break;
                        if (v2_end + KUO_R_LEN <= N && src.compare(v2_end, KUO_R_LEN, KUO_R) == 0) break;
                        if (v2_end + XIAO_LEN <= N && src.compare(v2_end, XIAO_LEN, XIAO) == 0) break;
                        if (v2_end + DA_LEN   <= N && src.compare(v2_end, DA_LEN,   DA)   == 0) break;
                    }
                    v2_end += advance_one_char(src, v2_end);
                }
                size_t after = v2_end;
                while (after < N && isspace((unsigned char)src[after])) after++;
                bool is_xiao = (after + XIAO_LEN <= N && src.compare(after, XIAO_LEN, XIAO) == 0);
                bool is_da   = (after + DA_LEN   <= N && src.compare(after, DA_LEN,   DA)   == 0);
                if (v1_end > v1_start && v2_end > v2_start && (is_xiao || is_da)) {
                    char op = is_xiao ? '<' : '>';
                    string var2 = src.substr(v2_start, v2_end - v2_start);
                    var2 = translate_punct_only(var2);
                    while (!out.empty() && isspace((unsigned char)out.back())) out.pop_back();
                    out += " "; out += op; out += " "; out += var2;
                    i = after + (is_xiao ? XIAO_LEN : DA_LEN);
                    matched = true;
                }
            }
        }

        // ---- 常规 pattern ----
        if (!matched) {
            for (size_t k = 0; k < patterns.size(); ++k) {
                const string& from = patterns[k].first;
                const string& to   = patterns[k].second;
                if (from.empty() || i + from.size() > N) continue;
                if (src.compare(i, from.size(), from) != 0) continue;

                // 则 / 则␣ 前边界保护
                if ((from == ZE_SPACE_KW || from == ZE_KW) &&
                    i > 0 && (unsigned char)src[i-1] >= 0x80)
                    continue;

                if (!is_punct_pattern(from) &&
                    i > 0 && is_ascii_ident((unsigned char)src[i-1])) continue;
                if (ends_with_cjk_hanzi(from) && !ends_with_any_punct(from)) {
                    size_t end = i + from.size();
                    if (end < N) {
                        unsigned char next = (unsigned char)src[end];
                        if (is_ascii_ident(next)) continue;
                        if (next >= 0x80 && !is_fullwidth_punct_at(src, end)) continue;
                    }
                }
                out += to;
                i += from.size();
                matched = true;
                break;
            }
        }

        if (!matched) out += src[i++];
    }
    return out;
}

// ============================================================
// 后台任务
// ============================================================
struct CompileJob { string src; bool runAfter; };

static void FinishByStop() {
    g_stopRequested.store(false);
    if (g_hMainWnd) PostMessage(g_hMainWnd, WM_COMPILE_FINISHED, 0, 0);
}

static bool RunAndCapture(const string& cmdline,
                          std::atomic<HANDLE>* pSlot,
                          string& output) {
    SECURITY_ATTRIBUTES sa = {};
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;

    HANDLE hRead = NULL, hWrite = NULL;
    if (!CreatePipe(&hRead, &hWrite, &sa, 0)) return false;
    SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0);

    HANDLE hNul = CreateFileA("NUL", GENERIC_READ,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL, OPEN_EXISTING, 0, NULL);
    if (hNul == INVALID_HANDLE_VALUE) hNul = NULL;

    STARTUPINFOA si = { sizeof(si) };
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = hWrite;
    si.hStdError  = hWrite;
    si.hStdInput  = hNul;

    PROCESS_INFORMATION pi = {};
    vector<char> cmdbuf(cmdline.begin(), cmdline.end());
    cmdbuf.push_back('\0');

    BOOL ok = CreateProcessA(NULL, &cmdbuf[0], NULL, NULL, TRUE,
                             CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
    CloseHandle(hWrite);
    if (hNul) CloseHandle(hNul);
    if (!ok) { CloseHandle(hRead); return false; }

    if (pSlot) pSlot->store(pi.hProcess);
    CloseHandle(pi.hThread);

    char buf[1024];
    DWORD rd = 0;
    while (ReadFile(hRead, buf, sizeof(buf) - 1, &rd, NULL) && rd > 0)
        output.append(buf, rd);
    CloseHandle(hRead);

    WaitForSingleObject(pi.hProcess, INFINITE);
    DWORD ec = 1;
    GetExitCodeProcess(pi.hProcess, &ec);

    if (pSlot) pSlot->store(NULL);
    CloseHandle(pi.hProcess);
    return (ec == 0);
}

void CompileAndRunTask(const string& src, bool runAfter) {
    if (g_stopRequested.load()) { FinishByStop(); return; }

    string cppPath = g_tempDir + "\\output.cpp";
    string exePath = g_tempDir + "\\output.exe";

    string cpp = translate_xuan(src);

    {
        static const string GUA_NEEDLE = to_ansi("卦");
        if (cpp.find(GUA_NEEDLE) != string::npos ||
            src.find(GUA_NEEDLE) != string::npos) {
            string inject =
                "// 玄 v3.6.3:检测到 卦,自动注入随机种子\n"
                "#include <cstdlib>\n"
                "#include <ctime>\n"
                "namespace { struct _xuan_srand_init {"
                " _xuan_srand_init(){ srand((unsigned)time(0)); }"
                " } _xuan_srand_instance; }\n";
            cpp = inject + cpp;
        }
    }

    write_file(cppPath, cpp);

    string buildLog;
    string gppCmd = "g++ \"" + cppPath + "\" -o \"" + exePath + "\" "
                    "-std=c++11 -finput-charset=GBK -fexec-charset=GBK";
    bool compileOK = RunAndCapture(gppCmd, &g_hGppProcess, buildLog);

    if (g_stopRequested.load()) { FinishByStop(); return; }

    if (!compileOK) {
        string* pMsg = new string(
            to_ansi("❌ 编译失败:\n") + buildLog
            + to_ansi("\n提示:转译后的 C++ 源码在 ") + cppPath + "\n");
        if (g_hMainWnd) PostMessage(g_hMainWnd, WM_UPDATE_OUTPUT, 0, (LPARAM)pMsg);
        else delete pMsg;
        if (g_hMainWnd) PostMessage(g_hMainWnd, WM_COMPILE_FINISHED, 0, 0);
        return;
    }

    string* pMsg = new string(to_ansi("✅ 编译成功!\n") + buildLog);
    if (g_hMainWnd) PostMessage(g_hMainWnd, WM_UPDATE_OUTPUT, 0, (LPARAM)pMsg);
    else delete pMsg;

    if (runAfter) {
        if (g_stopRequested.load()) { FinishByStop(); return; }

        string outputLog;
        string runCmd = "\"" + exePath + "\"";
        RunAndCapture(runCmd, &g_hOutputProcess, outputLog);

        if (g_stopRequested.load()) { FinishByStop(); return; }

        if (looks_like_utf8(outputLog)) outputLog = utf8_to_ansi(outputLog);

        string* pRun = new string(to_ansi("\n▶ 程序输出:\n--------------------\n")
                                  + outputLog
                                  + to_ansi("\n--------------------\n"));
        if (g_hMainWnd) PostMessage(g_hMainWnd, WM_UPDATE_OUTPUT, 1, (LPARAM)pRun);
        else delete pRun;
    }

    if (g_hMainWnd) PostMessage(g_hMainWnd, WM_COMPILE_FINISHED, 0, 0);
}

unsigned __stdcall CompileThreadProc(void* lpParam) {
    CompileJob* pJob = (CompileJob*)lpParam;
    if (!pJob) return 0;
    CompileAndRunTask(pJob->src, pJob->runAfter);
    delete pJob;
    return 0;
}

// ============================================================
// 停止
// ============================================================
void KillOutputExe() {
    HANDLE hGpp = g_hGppProcess.load();
    if (hGpp) TerminateProcess(hGpp, 1);

    HANDLE hOut = g_hOutputProcess.load();
    if (hOut) TerminateProcess(hOut, 1);
}

// ============================================================
// 帮助窗口
// ============================================================
static const string& GetHelpAnsi() {
    static const string s = to_ansi(HELP_TEXT);
    return s;
}

LRESULT CALLBACK HelpWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE: {
            g_hHelpEdit = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT",
                GetHelpAnsi().c_str(),
                WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY |
                ES_AUTOVSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | WS_HSCROLL,
                10, 10, 100, 100, hWnd, NULL, g_hInst, NULL);
            g_hHelpFont = CreateFont(16, 0, 0, 0, FW_NORMAL, 0, 0, 0,
                DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, XA("新宋体"));
            SendMessage(g_hHelpEdit, WM_SETFONT, (WPARAM)g_hHelpFont, TRUE);
            return 0;
        }
        case WM_SIZE: {
            if (g_hHelpEdit)
                SetWindowPos(g_hHelpEdit, NULL, 10, 10,
                    LOWORD(lParam) - 20, HIWORD(lParam) - 20, SWP_NOZORDER);
            return 0;
        }
        case WM_CLOSE: DestroyWindow(hWnd); return 0;
        case WM_DESTROY:
            if (g_hHelpFont) { DeleteObject(g_hHelpFont); g_hHelpFont = NULL; }
            g_hHelpWnd = NULL; g_hHelpEdit = NULL;
            return 0;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
}

void ShowHelp() {
    if (g_hHelpWnd && IsWindow(g_hHelpWnd)) {
        SetForegroundWindow(g_hHelpWnd);
        return;
    }
    WNDCLASSA wcCheck = {};
    if (!GetClassInfoA(g_hInst, "XuanHelpWnd", &wcCheck)) {
        WNDCLASSA wc = {};
        wc.lpfnWndProc = HelpWndProc;
        wc.hInstance = g_hInst;
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wc.lpszClassName = "XuanHelpWnd";
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hIcon = LoadIcon(NULL, IDI_INFORMATION);
        RegisterClassA(&wc);
    }
    g_hHelpWnd = CreateWindowExA(0, "XuanHelpWnd", XA("《玄》语言用法大全"),
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 700,
        g_hMainWnd, NULL, g_hInst, NULL);
    if (!g_hHelpWnd) return;
    ShowWindow(g_hHelpWnd, SW_SHOW);
    UpdateWindow(g_hHelpWnd);
    EnableWindow(g_hMainWnd, FALSE);
    MSG msg;
    while (g_hHelpWnd && IsWindow(g_hHelpWnd) && GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    EnableWindow(g_hMainWnd, TRUE);
    SetForegroundWindow(g_hMainWnd);
}

// ============================================================
// 文件操作
// ============================================================
void SetStatusText(const string& text) {
    SendMessageA(g_hStatusBar, SB_SETTEXTA, 0, (LPARAM)text.c_str());
}

static bool IsDirty() {
    if (!g_hEdit) return false;
    return SendMessage(g_hEdit, EM_GETMODIFY, 0, 0) != 0;
}
static void ClearDirty() {
    if (g_hEdit) SendMessage(g_hEdit, EM_SETMODIFY, FALSE, 0);
}

bool SaveFile(const string& content, bool saveAs=false) {
    if (saveAs || g_currentFilePath.empty()) {
        OPENFILENAMEA ofn = {};
        char fileName[MAX_PATH] = "";
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = g_hMainWnd;
        ofn.lpstrFilter = GetFilterAnsi();
        ofn.lpstrFile = fileName;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrDefExt = GetDefExtAnsi();
        ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
        if (!GetSaveFileNameA(&ofn)) return false;
        g_currentFilePath = fileName;
    }
    write_file(g_currentFilePath, content);
    ClearDirty();
    size_t pos = g_currentFilePath.find_last_of("/\\");
    g_currentFileName = (pos == string::npos) ? g_currentFilePath : g_currentFilePath.substr(pos+1);
    SetStatusText(g_currentFileName);
    return true;
}

bool OpenFile() {
    OPENFILENAMEA ofn = {};
    char fileName[MAX_PATH] = "";
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = g_hMainWnd;
    ofn.lpstrFilter = GetFilterAnsi();
    ofn.lpstrFile = fileName;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
    if (!GetOpenFileNameA(&ofn)) return false;
    g_currentFilePath = fileName;
    string content = read_file(g_currentFilePath);
    if (looks_like_utf8(content)) content = utf8_to_ansi(content);
    SetWindowTextA(g_hEdit, content.c_str());
    ClearDirty();
    size_t pos = g_currentFilePath.find_last_of("/\\");
    g_currentFileName = (pos == string::npos) ? g_currentFilePath : g_currentFilePath.substr(pos+1);
    SetStatusText(g_currentFileName);
    return true;
}

string GetEditContent() {
    int len = GetWindowTextLength(g_hEdit) + 1;
    if (len <= 1) return "";
    char* buf = new char[len];
    GetWindowTextA(g_hEdit, buf, len);
    string s = buf;
    delete[] buf;
    return s;
}

static bool ConfirmDiscardOrSave(HWND hWnd, const char* prompt) {
    if (!IsDirty()) return true;
    int r = MessageBoxA(hWnd, XA(prompt), XA("确认"),
                        MB_YESNOCANCEL | MB_ICONQUESTION);
    if (r == IDCANCEL) return false;
    if (r == IDNO) return true;
    if (!SaveFile(GetEditContent(), false)) return false;
    return true;
}

// ============================================================
// 主窗口过程
// ============================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE: {
            HMENU hMenuBar  = CreateMenu();
            HMENU hFileMenu = CreatePopupMenu();
            HMENU hEditMenu = CreatePopupMenu();
            HMENU hRunMenu  = CreatePopupMenu();
            HMENU hHelpMenu = CreatePopupMenu();

            AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_NEW,    XA("新建(&N)"));
            AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_OPEN,   XA("打开(&O)..."));
            AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_SAVE,   XA("保存(&S)"));
            AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_SAVEAS, XA("另存为(&A)..."));
            AppendMenuA(hFileMenu, MF_SEPARATOR, 0, NULL);
            AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_EXIT,   XA("退出(&X)"));
            AppendMenuA(hEditMenu, MF_STRING, IDM_EDIT_CUT,   XA("剪切(&T)"));
            AppendMenuA(hEditMenu, MF_STRING, IDM_EDIT_COPY,  XA("复制(&C)"));
            AppendMenuA(hEditMenu, MF_STRING, IDM_EDIT_PASTE, XA("粘贴(&P)"));
            AppendMenuA(hRunMenu, MF_STRING, IDM_RUN_COMPILE, XA("编译(&B)"));
            AppendMenuA(hRunMenu, MF_STRING, IDM_RUN_RUN,     XA("运行(&R)"));
            AppendMenuA(hRunMenu, MF_STRING, IDM_RUN_STOP,    XA("停止(&S)"));
            AppendMenuA(hHelpMenu, MF_STRING, IDM_HELP_MANUAL, XA("用法大全(&H)"));
            AppendMenuA(hHelpMenu, MF_STRING, IDM_HELP_ABOUT,  XA("关于(&A)"));

            AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, XA("文件(&F)"));
            AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hEditMenu, XA("编辑(&E)"));
            AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hRunMenu,  XA("运行(&R)"));
            AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hHelpMenu, XA("帮助(&H)"));
            SetMenu(hWnd, hMenuBar);

            g_hEdit = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
                WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL |
                ES_AUTOHSCROLL | WS_HSCROLL,
                0, 0, 0, 0, hWnd, (HMENU)101, g_hInst, NULL);
            SendMessage(g_hEdit, WM_SETFONT, (WPARAM)g_hFont, TRUE);

            g_hOutput = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
                WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL |
                ES_AUTOHSCROLL | WS_HSCROLL | ES_READONLY,
                0, 0, 0, 0, hWnd, (HMENU)102, g_hInst, NULL);
            SendMessage(g_hOutput, WM_SETFONT, (WPARAM)g_hOutFont, TRUE);

            g_hBtnSave    = CreateWindowA("BUTTON", XA("保存"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 5,5,70,28,   hWnd,(HMENU)IDB_SAVE,g_hInst,NULL);
            g_hBtnCompile = CreateWindowA("BUTTON", XA("编译"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 80,5,70,28,  hWnd,(HMENU)IDB_COMPILE,g_hInst,NULL);
            g_hBtnRun     = CreateWindowA("BUTTON", XA("运行"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 155,5,70,28, hWnd,(HMENU)IDB_RUN,g_hInst,NULL);
            g_hBtnStop    = CreateWindowA("BUTTON", XA("停止"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 230,5,70,28, hWnd,(HMENU)IDB_STOP,g_hInst,NULL);
            EnableWindow(g_hBtnStop, FALSE);
            g_hBtnClear   = CreateWindowA("BUTTON", XA("清空"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 305,5,70,28, hWnd,(HMENU)IDB_CLEAR,g_hInst,NULL);

            g_hStatusBar = CreateWindowA(STATUSCLASSNAMEA, XA("未命名.玄"),
                WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)301, g_hInst, NULL);

            const char* demo =
                "头文件《标准IO》\n"
                "使用命名空间标准;\n"
                "\n"
                "整数 求和(整数 x,整数 y)《\n"
                "    返回 x 加 y;\n"
                "》\n"
                "\n"
                "主程序:\n"
                "    重复 3 次 《\n"
                "        输出:\"你好\":换行;\n"
                "    》\n"
                "\n"
                "    对于 i 从 1 到 5 《\n"
                "        输出:\"i=\":i:换行;\n"
                "    》\n"
                "\n"
                "    对于 k 从 3 到 1 递减 《\n"
                "        输出:\"k=\":k:换行;\n"
                "    》\n"
                "\n"
                "    整数 分数 = 85;\n"
                "    若 分数 大于 90 则 输出:\"优\":换行;\n"
                "    否则若 分数 大于 60 则 输出:\"及格\":换行;\n"
                "    否则 输出:\"不及格\":换行;\n"
                "\n"
                "    输出:\"骰子=\":卦 1 到 6:换行;\n"
                "    输出:\"sizeof(int)=\":大小(整数):换行;\n"
                "    输出:\"sizeof(short)=\":大小(短整数):换行;\n"
                "    输出:\"sizeof(long long)=\":大小(长整数):换行;\n"
                "\n"
                "    整数 n = 0;\n"
                "    环 《\n"
                "        n 递增;\n"
                "        若 n 大于 3 则 跳出;\n"
                "    》\n"
                "    输出:\"n=\":n:换行;\n"
                "\n"
                "    整数 a = 10;\n"
                "    整数 b = 0;\n"
                "    对于(整数 i = 0; i 比 a 小; i 递增)《\n"
                "        b = 求和(b,i);\n"
                "    》\n"
                "    输出:\"总和=\":b:换行;\n"
                "\n"
                "    整数列表 v = 【10, 20, 30】;\n"
                "    对于(整数 i = 0; i 比 v.size() 小; i 递增)《\n"
                "        输出:v「i」:换行;\n"
                "    》\n"
                "\n"
                "    整数 总比 = 100;\n"
                "    输出:\"总比=\":总比:换行;\n"
                "\n"
                "    整数 原则 = 7;\n"
                "    输出:\"原则=\":原则:换行;\n"
                "\n"
                "    返回 0;\n"
                "。\n";
            SetWindowTextA(g_hEdit, to_ansi(demo).c_str());
            ClearDirty();
            return 0;
        }

        case WM_SIZE: {
            RECT rc; GetClientRect(hWnd, &rc);
            int w = rc.right - rc.left, h = rc.bottom - rc.top;
            int toolbarH = 40, outH = 140, statusH = 25;
            int editH = h - toolbarH - outH - statusH - 15;
            if (editH < 50) editH = 50;
            SetWindowPos(g_hEdit, NULL, 5, toolbarH+5, w-10, editH, SWP_NOZORDER);
            SetWindowPos(g_hOutput, NULL, 5, toolbarH+10+editH, w-10, outH-5, SWP_NOZORDER);
            SendMessage(g_hStatusBar, WM_SIZE, 0, 0);
            return 0;
        }

        case WM_COMMAND: {
            int id = LOWORD(wParam);
            if (id == IDM_FILE_NEW) {
                if (!ConfirmDiscardOrSave(hWnd, "当前代码已修改,是否保存?")) break;
                SetWindowTextA(g_hEdit, "");
                g_currentFilePath = "";
                g_currentFileName = to_ansi("未命名.玄");
                SetStatusText(g_currentFileName);
                ClearDirty();
            }
            else if (id == IDM_FILE_OPEN) {
                if (!ConfirmDiscardOrSave(hWnd, "当前代码已修改,是否保存?")) break;
                OpenFile();
            }
            else if (id == IDM_FILE_SAVE) SaveFile(GetEditContent(), false);
            else if (id == IDM_FILE_SAVEAS) SaveFile(GetEditContent(), true);
            else if (id == IDM_FILE_EXIT) PostMessage(hWnd, WM_CLOSE, 0, 0);
            else if (id == IDM_EDIT_CUT) SendMessage(g_hEdit, WM_CUT, 0, 0);
            else if (id == IDM_EDIT_COPY) SendMessage(g_hEdit, WM_COPY, 0, 0);
            else if (id == IDM_EDIT_PASTE) SendMessage(g_hEdit, WM_PASTE, 0, 0);
            else if (id == IDM_RUN_COMPILE || id == IDB_COMPILE) {
                if (g_isCompiling || g_isRunning) break;
                string src = GetEditContent();
                if (!g_currentFilePath.empty()) write_file(g_currentFilePath, src);
                SetWindowTextA(g_hOutput, XA("正在编译...\n"));
                EnableWindow(g_hBtnCompile, FALSE);
                EnableWindow(g_hBtnRun, FALSE);
                g_isCompiling = true;
                g_stopRequested.store(false);
                CompileJob* pJob = new CompileJob();
                pJob->src = src; pJob->runAfter = false;
                uintptr_t th = _beginthreadex(NULL, 0, CompileThreadProc, pJob, 0, NULL);
                if (th) {
                    CloseHandle((HANDLE)(intptr_t)th);
                } else {
                    delete pJob;
                    g_isCompiling = false;
                    EnableWindow(g_hBtnCompile, TRUE);
                    EnableWindow(g_hBtnRun, TRUE);
                    SetWindowTextA(g_hOutput, XA("线程创建失败\n"));
                }
            }
            else if (id == IDM_RUN_RUN || id == IDB_RUN) {
                if (g_isCompiling || g_isRunning) break;
                string src = GetEditContent();
                if (!g_currentFilePath.empty()) write_file(g_currentFilePath, src);
                SetWindowTextA(g_hOutput, XA("正在编译并运行...\n"));
                EnableWindow(g_hBtnCompile, FALSE);
                EnableWindow(g_hBtnRun, FALSE);
                EnableWindow(g_hBtnStop, TRUE);
                g_isRunning = true;
                g_stopRequested.store(false);
                CompileJob* pJob = new CompileJob();
                pJob->src = src; pJob->runAfter = true;
                uintptr_t th = _beginthreadex(NULL, 0, CompileThreadProc, pJob, 0, NULL);
                if (th) {
                    CloseHandle((HANDLE)(intptr_t)th);
                } else {
                    delete pJob;
                    g_isRunning = false;
                    EnableWindow(g_hBtnCompile, TRUE);
                    EnableWindow(g_hBtnRun, TRUE);
                    EnableWindow(g_hBtnStop, FALSE);
                    SetWindowTextA(g_hOutput, XA("线程创建失败\n"));
                }
            }
            else if (id == IDM_RUN_STOP || id == IDB_STOP) {
                g_stopRequested.store(true);
                KillOutputExe();
                EnableWindow(g_hBtnStop, FALSE);
                EnableWindow(g_hBtnCompile, FALSE);
                EnableWindow(g_hBtnRun, FALSE);
                SetWindowTextA(g_hOutput, XA("正在停止...\n"));
            }
            else if (id == IDB_SAVE) SaveFile(GetEditContent(), false);
            else if (id == IDB_CLEAR) SetWindowTextA(g_hOutput, "");
            else if (id == IDM_HELP_MANUAL) ShowHelp();
            else if (id == IDM_HELP_ABOUT) {
                MessageBoxA(hWnd,
                    XA("《玄》IDE v3.6.3\n\n一个用中文编写程序的 IDE\n\n"
                       "新增:无符号/短/长/超长整数及指针/列表\n"
                       "修复:嵌套 重复 计数器同名遮蔽"),
                    XA("关于"), MB_OK|MB_ICONINFORMATION);
            }
            return 0;
        }

        case WM_UPDATE_OUTPUT: {
            string* pMsg = (string*)lParam;
            if (pMsg) {
                if (wParam == 0) SetWindowTextA(g_hOutput, pMsg->c_str());
                else {
                    int len = GetWindowTextLengthA(g_hOutput);
                    char* cur = new char[len+1];
                    GetWindowTextA(g_hOutput, cur, len+1);
                    string nt = string(cur) + *pMsg;
                    delete[] cur;
                    SetWindowTextA(g_hOutput, nt.c_str());
                }
                delete pMsg;
            }
            return 0;
        }

        case WM_COMPILE_FINISHED: {
            g_isCompiling = false;
            g_isRunning = false;
            g_stopRequested.store(false);
            EnableWindow(g_hBtnCompile, TRUE);
            EnableWindow(g_hBtnRun, TRUE);
            EnableWindow(g_hBtnStop, FALSE);
            return 0;
        }

        case WM_CLOSE:
            if (!ConfirmDiscardOrSave(hWnd, "退出前是否保存修改?")) return 0;
            DestroyWindow(hWnd);
            return 0;

        case WM_DESTROY: {
            g_hMainWnd = NULL;

            KillOutputExe();

            if (g_tempDir != ".") {
                string cppPath = g_tempDir + "\\output.cpp";
                string exePath = g_tempDir + "\\output.exe";
                DeleteFileA(cppPath.c_str());
                DeleteFileA(exePath.c_str());
                RemoveDirectoryA(g_tempDir.c_str());
            }

            PostQuitMessage(0);
            return 0;
        }
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

// ============================================================
// 入口
// ============================================================
static void InitTempDir() {
    char tempPath[MAX_PATH];
    DWORD len = GetTempPathA(MAX_PATH, tempPath);
    if (len > 0 && len < MAX_PATH) {
        char pidStr[32];
        snprintf(pidStr, sizeof(pidStr), "xuan_ide_%lu",
                 (unsigned long)GetCurrentProcessId());
        string dir = string(tempPath) + pidStr;
        CreateDirectoryA(dir.c_str(), NULL);
        DWORD attr = GetFileAttributesA(dir.c_str());
        if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
            g_tempDir = dir;
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    (void)hPrevInstance; (void)lpCmdLine;

    {
        typedef BOOL (WINAPI *PFN_DPIAWARE)();
        HMODULE hU = GetModuleHandleA("user32.dll");
        if (hU) {
            PFN_DPIAWARE pFn = (PFN_DPIAWARE)GetProcAddress(hU, "SetProcessDPIAware");
            if (pFn) pFn();
        }
    }

    g_hInst = hInstance;
    g_currentFileName = to_ansi("未命名.玄");
    InitTempDir();

    INITCOMMONCONTROLSEX icex = {sizeof(icex), ICC_WIN95_CLASSES};
    InitCommonControlsEx(&icex);

    g_hFont = CreateFontA(18,0,0,0,FW_NORMAL,0,0,0, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
        DEFAULT_PITCH|FF_DONTCARE, XA("宋体"));
    g_hOutFont = CreateFontA(16,0,0,0,FW_NORMAL,0,0,0, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
        DEFAULT_PITCH|FF_DONTCARE, XA("宋体"));

    WNDCLASSA wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszClassName = "XuanIDE";
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    if (!RegisterClassA(&wc)) return 1;

    g_hMainWnd = CreateWindowExA(0, "XuanIDE", XA("《玄》IDE v3.6.3"),
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1000, 720,
        NULL, NULL, hInstance, NULL);
    if (!g_hMainWnd) return 1;

    ShowWindow(g_hMainWnd, nCmdShow);
    UpdateWindow(g_hMainWnd);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    if (g_hFont) DeleteObject(g_hFont);
    if (g_hOutFont) DeleteObject(g_hOutFont);
    return 0;
}

哈哈哈!《玄》,果然玄!这才是给中国人用的语言!


相关推荐
Jasmine_llq1 小时前
《P10263 [GESP202403 八级] 公倍数问题》
算法·数论·快速 io 优化·埃氏筛(倍数枚举)·线性遍历求和
2402_882893861 小时前
C++异常:从概念到实践的一篇博客
c++·异常
橘子汽水1681 小时前
Leetcode 322 279 零钱兑换,完全平方数
算法·leetcode
奔跑吧树袋熊1 小时前
多租户隔离该做到哪一层:从连接池到 ORM 的取舍
开发语言·数据库·oracle·系统架构
大江东去浪淘尽千古风流人物1 小时前
【LoMa】局部特征匹配重访:从LoMa-B到旋转不变LoMa-R的架构与工程实践
开发语言·深度学习·计算机视觉·r语言·视觉定位·sfm·局部特征匹配
菜鸟~noob2331 小时前
【电子战】测向精度极限——克拉美-罗下限(CRLB)与误差分析【含matlab代码】
开发语言·matlab
kevin_kang1 小时前
第01章 VoiceAgent 的总体架构与完整流程
算法
m0_734571761 小时前
深入理解C++ 析构函数<二>析构顺序
开发语言·c++
Lintongzg1 小时前
KV-Cache 的显存账本:长上下文、并发与量化剪枝的取舍
算法·机器学习·剪枝