欢迎光临
我们一直在努力

大飞跃!玄3.4!

// ============================================================
// 《玄》IDE v3.4 — 完整版
// v3.4 修复:编码一致性
// – .cpp 无论用 UTF-8 还是 GBK 保存,运行时所有中文 pattern
// 都经 to_ansi() 转为系统 ANSI(CP_ACP),与编辑框 GetWindowTextA
// 返回的编码匹配
// 历史修复(保留):
// – 标点类 pattern 前后边界豁免
// – "比…小/大" 编码无关 + 紧凑写法
// – 26 个头文件 + 14 个容器类型别名
// 链接库:-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 <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>

using namespace std;

#ifdef _WIN32
#define xuan_popen _popen
#define xuan_pclose _pclose
#else
#define xuan_popen popen
#define xuan_pclose pclose
#endif

#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="", g_currentFileName="未命名.玄";
bool g_isRunning=false, g_isCompiling=false;

struct CompileJob { string src; bool runAfter; };
CompileJob g_job;

// ============================================================
// 编码转换:把 .cpp 里的中文字面量(可能 UTF-8)转成系统 ANSI
// ============================================================
static string to_ansi(const char* s) {
if (!s || !*s) return string();
const char* p = s;
bool has_high = false;
while (*p) { if ((unsigned char)*p >= 0x80) { has_high = true; break; } ++p; }
if (!has_high) return string(s);

int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s, -1, NULL, 0);
if (wlen <= 0) return string(s); // 不是 UTF-8,假定已经是本地 ANSI

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 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; }
if (p == 0 && (unsigned char)s[0] < 0x80) return false;
return (unsigned char)s[p] >= 0x80;
}

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 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;
}

// ============================================================
// 用法大全
// ============================================================
const char* HELP_TEXT =
"================================================================\\n"
" 《玄》语言用法大全 v3.4\\n"
"================================================================\\n"
"\\n"
"【1 文件结构】\\n"
"头文件《标准IO》\\n"
"使用命名空间标准;\\n"
"主程序:\\n"
" 代码…\\n"
"。\\n"
"提示:\\n"
" – 关键字后建议跟空格或全角标点。\\n"
" – 标识符中如包含关键字,可用 \\\\ 转义:\\\\输出总数 -> 输出总数\\n"
" – 本版已处理 .cpp 编码(UTF-8/GBK 均可),无需担心保存格式。\\n"
"\\n"
"【2 头文件】(26 个)\\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"
"\\n"
"【5 容器类型别名】\\n"
"整数映射 std::map<int,int>\\n"
"文本映射 std::map<std::string,std::string>\\n"
"整数集合 std::set<int>\\n"
"文本集合 std::set<std::string>\\n"
"整数队列 std::queue<int>\\n"
"文本队列 std::queue<std::string>\\n"
"整数栈 std::stack<int>\\n"
"文本栈 std::stack<std::string>\\n"
"整数对 std::pair<int,int>\\n"
"文本对 std::pair<std::string,std::string>\\n"
"整数双端队列 std::deque<int>\\n"
"整数列表 std::vector<int>\\n"
"文本列表 std::vector<std::string>\\n"
"浮点列表 std::vector<float>\\n"
"\\n"
"【6 输入输出】\\n"
"输出:\\"你好\\":换行;\\n"
"输入:a;\\n"
"全角冒号(:)翻译为 <<\\n"
"\\n"
"【7 运算符】\\n"
"比较:小于 < 大于 > 不大于 <= 不小于 >=\\n"
" 等于 == 不等于 != 比…小 < 比…大 >\\n"
"说明:\\"比…小/大\\" 允许跨行、紧凑写法。\\n"
" 宽松: i 比 a 小\\n"
" 紧凑: i比a小\\n"
"识别规则(两步):\\n"
" 步骤 1:看 \\"比\\" 前一个字节\\n"
" – 不是 [a-zA-Z0-9_] → 进入匹配流程\\n"
" – 是 [a-zA-Z0-9_] → 转步骤 2\\n"
" 步骤 2:探测 \\"比\\" 后是否紧跟 空格/小/大\\n"
" – 是 → 拒绝(视为变量名后缀)\\n"
" – 否 → 接受(紧凑写法)\\n"
"逻辑:与/且 && 或/或者 || 非 !\\n"
"算术:加 + 减 – 乘 * 除 / 模 % 递增 ++ 递减 –\\n"
"\\n"
"【8 控制流】\\n"
"如果(条件)《…》 否则如果《…》 否则《…》\\n"
"对于(整数 i=0;i 小于 10;i 递增)《…》\\n"
"只要(条件)《…》 / 当(条件)《…》\\n"
"跳出 break / 继续 continue / 返回 return\\n"
"\\n"
"【9 函数】\\n"
"整数 求和(整数 x,整数 y)《\\n"
" 返回 x 加 y;\\n"
"》\\n"
"\\n"
"【10 类与结构】\\n"
"类 学生 《\\n"
"公开:\\n"
" 文本 姓名; 整数 年龄;\\n"
" 学生(文本 n,整数 a)《 姓名=n; 年龄=a; 》\\n"
" 无 介绍()《 输出:\\"我是\\":姓名:换行; 》\\n"
"》\\n"
"继承:类 大学生 继承 学生 《…》\\n"
"\\n"
"【11 指针】\\n"
"整数指针 p; int* p;\\n"
"取地址 a / 取址 a & a\\n"
"取内容 p / 解引用 p * p\\n"
"空指针 nullptr\\n"
"\\n"
"【12 动态内存】\\n"
"新建 整数(100) new int(100)\\n"
"新建数组 整数「10」 new int[10]\\n"
"释放 p / 释放数组 p delete / delete[]\\n"
"\\n"
"【13 容器初始化 / 索引】\\n"
"整数列表 v = 【1, 2, 3】; std::vector<int> v = {1, 2, 3};\\n"
"v「0」 / v.size() v[0] / v.size()\\n"
"\\n"
"【14 头文件对照表】\\n"
" 头文件《标准IO》 iostream + string + vector + memory\\n"
" 头文件《算法》 algorithm\\n"
" 头文件《数学》 cmath\\n"
" 头文件《数值》 numeric\\n"
" 头文件《随机数》《随机》 random\\n"
" 头文件《映射》《字典》 map\\n"
" 头文件《集合》 set\\n"
" 头文件《队列》 queue\\n"
" 头文件《栈》 stack\\n"
" 头文件《链表》 list\\n"
" 头文件《数组》 array\\n"
" 头文件《双端队列》 deque\\n"
" 头文件《元组》 tuple\\n"
" 头文件《对组》《工具》 utility\\n"
" 头文件《函数》 functional\\n"
" 头文件《时间》 chrono\\n"
" 头文件《线程》 thread\\n"
" 头文件《互斥》《互斥锁》 mutex\\n"
" 头文件《原子》 atomic\\n"
" 头文件《条件变量》 condition_variable\\n"
" 头文件《文件》《文件流》 fstream\\n"
" 头文件《字符串流》 sstream\\n"
" 头文件《流格式》 iomanip\\n"
" 头文件《异常》 stdexcept\\n"
" 头文件《迭代器》 iterator\\n"
" 头文件《位集》 bitset\\n"
" 头文件《复数》 complex\\n"
"\\n"
"【15 常见错误】\\n"
"1. 忘记写 头文件《标准IO》\\n"
"2. 忘记写 使用命名空间标准;\\n"
"3. 字符串用中文引号 “” —— 必须用英文引号 \\"\\"\\n"
"4. 缺少主程序结尾的句号 。\\n"
"5. 索引用 【】 会错 —— 索引用 「」,初始化用 【】\\n"
"6. 关键字与中文变量名粘连 —— 中间加空格或全角标点\\n"
"\\n"
" 《玄》IDE v3.4\\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());
f << content;
}

// ============================================================
// 转译核心
// ============================================================
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")));
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>")));

// 指针类型
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")));

// 长词优先
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();
const size_t XIAO_LEN = XIAO.size();
const size_t DA_LEN = DA.size();
const size_t ZUO_LEN = ZUO.size();
const size_t YOU_LEN = YOU.size();
const size_t KUO_L_LEN = KUO_L.size();
const size_t KUO_R_LEN = KUO_R.size();

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;

// "比" 结构
if (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;
}
}
}

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 (!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;
}

// ============================================================
// 后台任务
// ============================================================
void CompileAndRunTask(const string& src, bool runAfter) {
string cpp = translate_xuan(src);
write_file("output.cpp", cpp);

string buildLog;
char buffer[1024];
string cmd = "g++ \\"output.cpp\\" -o \\"output.exe\\" -std=c++11 2>&1";
FILE* pipe = xuan_popen(cmd.c_str(), "r");
if (pipe) {
while (fgets(buffer, sizeof(buffer), pipe)) buildLog += buffer;
xuan_pclose(pipe);
}

bool hasError = (buildLog.find("error") != string::npos ||
buildLog.find("Error") != string::npos);
if (hasError) {
string* pMsg = new string("❌ 编译失败:\\n" + buildLog);
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("✅ 编译成功!\\n" + buildLog);
if (g_hMainWnd) PostMessage(g_hMainWnd, WM_UPDATE_OUTPUT, 0, (LPARAM)pMsg);
else delete pMsg;

if (runAfter) {
string outputLog;
FILE* runPipe = xuan_popen("\\"output.exe\\"", "r");
if (runPipe) {
while (fgets(buffer, sizeof(buffer), runPipe)) outputLog += buffer;
xuan_pclose(runPipe);
}
string* pRun = new string("\\n▶ 程序输出:\\n——————–\\n" + outputLog + "\\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) {
(void)lpParam;
CompileAndRunTask(g_job.src, g_job.runAfter);
return 0;
}

// ============================================================
// 无声杀进程
// ============================================================
void KillOutputExe() {
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi = {};
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
char cmd[] = "taskkill /F /IM output.exe";
if (CreateProcessA(NULL, cmd, NULL, NULL, FALSE,
CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
WaitForSingleObject(pi.hProcess, 2000);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}

// ============================================================
// 帮助窗口
// ============================================================
LRESULT CALLBACK HelpWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: {
string helpText = to_ansi(HELP_TEXT);
g_hHelpEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", helpText.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, "新宋体");
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", "《玄》语言用法大全",
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());
}

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 = "玄源文件\\0*.玄\\0所有文件\\0*.*\\0";
ofn.lpstrFile = fileName;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = "玄";
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
if (!GetSaveFileNameA(&ofn)) return false;
g_currentFilePath = fileName;
}
write_file(g_currentFilePath, content);
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 = "玄源文件\\0*.玄\\0所有文件\\0*.*\\0";
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);
SetWindowTextA(g_hEdit, content.c_str());
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;
}

// ============================================================
// 主窗口过程
// ============================================================
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, "新建(&N)");
AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_OPEN, "打开(&O)…");
AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_SAVE, "保存(&S)");
AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_SAVEAS, "另存为(&A)…");
AppendMenuA(hFileMenu, MF_SEPARATOR, 0, NULL);
AppendMenuA(hFileMenu, MF_STRING, IDM_FILE_EXIT, "退出(&X)");
AppendMenuA(hEditMenu, MF_STRING, IDM_EDIT_CUT, "剪切(&T)");
AppendMenuA(hEditMenu, MF_STRING, IDM_EDIT_COPY, "复制(&C)");
AppendMenuA(hEditMenu, MF_STRING, IDM_EDIT_PASTE, "粘贴(&P)");
AppendMenuA(hRunMenu, MF_STRING, IDM_RUN_COMPILE, "编译(&B)");
AppendMenuA(hRunMenu, MF_STRING, IDM_RUN_RUN, "运行(&R)");
AppendMenuA(hRunMenu, MF_STRING, IDM_RUN_STOP, "停止(&S)");
AppendMenuA(hHelpMenu, MF_STRING, IDM_HELP_MANUAL, "用法大全(&H)");
AppendMenuA(hHelpMenu, MF_STRING, IDM_HELP_ABOUT, "关于(&A)");

AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, "文件(&F)");
AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hEditMenu, "编辑(&E)");
AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hRunMenu, "运行(&R)");
AppendMenuA(hMenuBar, MF_POPUP, (UINT_PTR)hHelpMenu, "帮助(&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","保存", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 5,5,70,28, hWnd,(HMENU)IDB_SAVE,g_hInst,NULL);
g_hBtnCompile = CreateWindowA("BUTTON","编译", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 80,5,70,28, hWnd,(HMENU)IDB_COMPILE,g_hInst,NULL);
g_hBtnRun = CreateWindowA("BUTTON","运行", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 155,5,70,28, hWnd,(HMENU)IDB_RUN,g_hInst,NULL);
g_hBtnStop = CreateWindowA("BUTTON","停止", 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","清空", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 305,5,70,28, hWnd,(HMENU)IDB_CLEAR,g_hInst,NULL);

g_hStatusBar = CreateWindowA(STATUSCLASSNAMEA, "未命名.玄",
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"
" 整数 a = 10;\\n"
" 整数 b = 0;\\n"
"\\n"
" // 宽松写法\\n"
" 对于(整数 i = 0; i 比 a 小; i 递增)《\\n"
" b = 求和(b,i);\\n"
" 》\\n"
" 输出:\\"总和=\\":b:换行;\\n"
"\\n"
" // 紧凑写法\\n"
" 整数 c = 0;\\n"
" 只要(c比3小)《\\n"
" 输出:\\"c=\\":c:换行;\\n"
" c 递增;\\n"
" 》\\n"
"\\n"
" 整数列表 v = 【10, 20, 30】;\\n"
" 对于(整数 i = 0; i 比 v.size() 小; i 递增)《\\n"
" 输出:v「i」:换行;\\n"
" 》\\n"
"\\n"
" // CJK 前边界:\\"比\\" 视为变量名的一部分\\n"
" 整数 总比 = 100;\\n"
" 输出:\\"总比=\\":总比:换行;\\n"
"\\n"
" 返回 0;\\n"
"。\\n";
string demoAnsi = to_ansi(demo);
SetWindowTextA(g_hEdit, demoAnsi.c_str());
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 (MessageBoxA(hWnd, "是否清空当前代码并新建?", "确认",
MB_YESNO|MB_ICONQUESTION) == IDYES) {
SetWindowTextA(g_hEdit, "");
g_currentFilePath = "";
g_currentFileName = "未命名.玄";
SetStatusText(g_currentFileName);
}
}
else if (id == IDM_FILE_OPEN) 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, "正在编译…\\n");
EnableWindow(g_hBtnCompile, FALSE);
EnableWindow(g_hBtnRun, FALSE);
g_isCompiling = true;
g_job.src = src; g_job.runAfter = false;
uintptr_t th = _beginthreadex(NULL, 0, CompileThreadProc, NULL, 0, NULL);
if (th) CloseHandle((HANDLE)th);
}
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, "正在编译并运行…\\n");
EnableWindow(g_hBtnCompile, FALSE);
EnableWindow(g_hBtnRun, FALSE);
EnableWindow(g_hBtnStop, TRUE);
g_isRunning = true;
g_job.src = src; g_job.runAfter = true;
uintptr_t th = _beginthreadex(NULL, 0, CompileThreadProc, NULL, 0, NULL);
if (th) CloseHandle((HANDLE)th);
}
else if (id == IDM_RUN_STOP || id == IDB_STOP) {
KillOutputExe();
g_isRunning = false;
g_isCompiling = false;
EnableWindow(g_hBtnStop, FALSE);
SetWindowTextA(g_hBtnCompile, "编译");
EnableWindow(g_hBtnCompile, TRUE);
SetWindowTextA(g_hBtnRun, "运行");
EnableWindow(g_hBtnRun, TRUE);
SetWindowTextA(g_hOutput, "已终止运行\\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,
"《玄》IDE v3.4\\n\\n一个用中文编写程序的 IDE\\n\\n"
"26 个头文件、14 个容器类型别名\\n"
"编码无关:.cpp 用 UTF-8 或 GBK 保存均可",
"关于", 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;
EnableWindow(g_hBtnCompile, TRUE);
EnableWindow(g_hBtnRun, TRUE);
EnableWindow(g_hBtnStop, FALSE);
SetWindowTextA(g_hBtnCompile, "编译");
SetWindowTextA(g_hBtnRun, "运行");
return 0;
}

case WM_CLOSE:
if (MessageBoxA(hWnd, "确定退出吗?", "确认", MB_YESNO|MB_ICONQUESTION) == IDYES)
DestroyWindow(hWnd);
return 0;

case WM_DESTROY:
g_hMainWnd = NULL;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

// ============================================================
// 入口
// ============================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
(void)hPrevInstance; (void)lpCmdLine;
g_hInst = hInstance;

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, "宋体");
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, "宋体");

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", "《玄》IDE v3.4",
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;
}

赞(0)
未经允许不得转载:171主机测评 » 大飞跃!玄3.4!
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址