fix: .gitignore + add 44 language JSON files
This commit is contained in:
1 parent
e8fd68e27b
commit
8de545dd2c
227 files changed
+22603
No files matched your search
+348
@@ -0,0 +1,348 @@
|
||||
// lity_editor.c - Lity3D Editor (Win32 Unicode + JSON i18n)
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <shellapi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define IDC_TREE 1001
|
||||
#define IDC_EDIT 1002
|
||||
#define IDC_CONSOLE 1003
|
||||
#define IDM_NEW 2001
|
||||
#define IDM_OPEN 2002
|
||||
#define IDM_SAVE 2003
|
||||
#define IDM_RUN 2004
|
||||
#define IDM_BUILD 2005
|
||||
#define IDM_PACKAGE 2006
|
||||
#define IDM_ABOUT 2007
|
||||
#define IDM_LANG_BASE 3000
|
||||
|
||||
static HWND g_hwnd, g_tree, g_edit, g_console;
|
||||
static WCHAR g_current_file[MAX_PATH] = L"";
|
||||
static WCHAR g_engine_dir[MAX_PATH] = L"";
|
||||
static int g_lang_count = 0;
|
||||
static WCHAR g_lang_codes[128][32];
|
||||
static WCHAR g_lang_names[128][128];
|
||||
static WCHAR g_cur_lang[32] = L"en";
|
||||
// Translation keys
|
||||
static WCHAR g_t[256][256]; // up to 256 keys
|
||||
static int g_t_count = 0;
|
||||
static WCHAR g_t_keys[256][64];
|
||||
|
||||
static WCHAR* T(const char* key) {
|
||||
for (int i = 0; i < g_t_count; i++) {
|
||||
char kbuf[64];
|
||||
WideCharToMultiByte(CP_UTF8, 0, g_t_keys[i], -1, kbuf, sizeof(kbuf), NULL, NULL);
|
||||
if (strcmp(kbuf, key) == 0) return g_t[i];
|
||||
}
|
||||
// fallback to English defaults
|
||||
static const WCHAR* defs[][2] = {
|
||||
{L"app_title",L"Lity3D Editor"},{L"file",L"File"},{L"build",L"Build"},
|
||||
{L"scene",L"Scene"},{L"help",L"Help"},{L"lang",L"Language"},
|
||||
{L"new",L"New"},{L"open",L"Open"},{L"save",L"Save"},{L"exit",L"Exit"},
|
||||
{L"run",L"Run"},{L"compile",L"Build Engine"},{L"package",L"Package"},
|
||||
{L"explorer",L"Explorer"},{L"output",L"Output"},{L"ready",L"Ready"},
|
||||
{L"about",L"About Lity3D"},
|
||||
};
|
||||
for (int i = 0; i < 17; i++) {
|
||||
char kbuf2[64];
|
||||
WideCharToMultiByte(CP_UTF8, 0, defs[i][0], -1, kbuf2, sizeof(kbuf2), NULL, NULL);
|
||||
if (strcmp(kbuf2, key) == 0) return defs[i][1];
|
||||
}
|
||||
static WCHAR fb[128];
|
||||
MultiByteToWideChar(CP_UTF8, 0, key, -1, fb, 128);
|
||||
return fb;
|
||||
}
|
||||
|
||||
static void parse_json_value(const char* json, const char* key, WCHAR* out, int max) {
|
||||
char pattern[128];
|
||||
sprintf(pattern, "\"%s\"", key);
|
||||
const char* p = strstr(json, pattern);
|
||||
if (!p) { out[0] = 0; return; }
|
||||
p = strchr(p + strlen(pattern), ':');
|
||||
if (!p) { out[0] = 0; return; }
|
||||
p++; while (*p == ' ') p++;
|
||||
if (*p == '"') {
|
||||
p++; const char* end = strchr(p, '"'); if (!end) end = p + strlen(p);
|
||||
int len = (int)(end - p);
|
||||
char tmp[512] = {0}; if (len > 511) len = 511;
|
||||
memcpy(tmp, p, len);
|
||||
MultiByteToWideChar(CP_UTF8, 0, tmp, -1, out, max);
|
||||
}
|
||||
}
|
||||
|
||||
static void load_lang(const WCHAR* code) {
|
||||
WCHAR path[MAX_PATH];
|
||||
wsprintfW(path, L"%s\\languages\\%s.json", g_engine_dir, code);
|
||||
HANDLE hf = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hf == INVALID_HANDLE_VALUE) {
|
||||
// try English fallback
|
||||
wsprintfW(path, L"%s\\languages\\en.json", g_engine_dir);
|
||||
hf = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hf == INVALID_HANDLE_VALUE) return;
|
||||
}
|
||||
DWORD sz = GetFileSize(hf, NULL);
|
||||
char* buf = malloc(sz + 1); DWORD rd; ReadFile(hf, buf, sz, &rd, NULL); buf[sz] = '\0'; CloseHandle(hf);
|
||||
g_t_count = 0;
|
||||
const char* keys[] = {"app_title","file","build","scene","help","lang","new","open","save","exit",
|
||||
"run","compile","package","explorer","output","ready","running","saved","opened",
|
||||
"build_first","kill","packaged","about"};
|
||||
for (int i = 0; i < 23; i++) {
|
||||
MultiByteToWideChar(CP_UTF8, 0, keys[i], -1, g_t_keys[g_t_count], 64);
|
||||
parse_json_value(buf, keys[i], g_t[g_t_count], 256);
|
||||
g_t_count++;
|
||||
}
|
||||
free(buf);
|
||||
wcscpy(g_cur_lang, code);
|
||||
}
|
||||
|
||||
static void discover_languages(void) {
|
||||
g_lang_count = 0;
|
||||
WCHAR pattern[MAX_PATH];
|
||||
wsprintfW(pattern, L"%s\\languages\\*.json", g_engine_dir);
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE h = FindFirstFileW(pattern, &fd);
|
||||
if (h == INVALID_HANDLE_VALUE) return;
|
||||
do {
|
||||
WCHAR name[MAX_PATH]; wcscpy(name, fd.cFileName);
|
||||
WCHAR* dot = wcsrchr(name, L'.'); if (dot) *dot = 0;
|
||||
wcscpy(g_lang_codes[g_lang_count], name);
|
||||
// Read language name from JSON
|
||||
WCHAR path[MAX_PATH]; wsprintfW(path, L"%s\\languages\\%s", g_engine_dir, fd.cFileName);
|
||||
HANDLE hf = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hf != INVALID_HANDLE_VALUE) {
|
||||
DWORD sz = GetFileSize(hf, NULL); char* buf = malloc(sz + 1); DWORD rd;
|
||||
ReadFile(hf, buf, sz, &rd, NULL); buf[sz] = '\0'; CloseHandle(hf);
|
||||
WCHAR title[256]; parse_json_value(buf, "app_title", title, 256);
|
||||
wsprintfW(g_lang_names[g_lang_count], L"%s (%s)", title, name);
|
||||
free(buf);
|
||||
}
|
||||
g_lang_count++;
|
||||
} while (FindNextFileW(h, &fd));
|
||||
FindClose(h);
|
||||
}
|
||||
|
||||
static void console_msg(const char* msg) {
|
||||
int len = GetWindowTextLengthA(g_console);
|
||||
SendMessageA(g_console, EM_SETSEL, len, len);
|
||||
SendMessageA(g_console, EM_REPLACESEL, FALSE, (LPARAM)msg);
|
||||
}
|
||||
|
||||
static void populate_tree(void) {
|
||||
TreeView_DeleteAllItems(g_tree);
|
||||
TVINSERTSTRUCTW tvi = {0};
|
||||
tvi.hParent = TVI_ROOT; tvi.hInsertAfter = TVI_LAST;
|
||||
tvi.item.mask = TVIF_TEXT;
|
||||
tvi.item.pszText = (WCHAR*)L"lity3d";
|
||||
HTREEITEM root = TreeView_InsertItem(g_tree, &tvi);
|
||||
WIN32_FIND_DATAW fd; WCHAR pat[MAX_PATH];
|
||||
wsprintfW(pat, L"%s\\*", g_engine_dir);
|
||||
HANDLE hFind = FindFirstFileW(pat, &fd);
|
||||
if (hFind == INVALID_HANDLE_VALUE) return;
|
||||
do {
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
if (!wcscmp(fd.cFileName,L".")||!wcscmp(fd.cFileName,L"..")) continue;
|
||||
if (!wcscmp(fd.cFileName,L".git")||!wcscmp(fd.cFileName,L"build")||!wcscmp(fd.cFileName,L"target")) continue;
|
||||
tvi.hParent = root; tvi.item.pszText = fd.cFileName;
|
||||
HTREEITEM d = TreeView_InsertItem(g_tree, &tvi);
|
||||
WCHAR sub[MAX_PATH]; wsprintfW(sub, L"%s\\%s\\*", g_engine_dir, fd.cFileName);
|
||||
WIN32_FIND_DATAW fd2; HANDLE h2 = FindFirstFileW(sub, &fd2);
|
||||
if (h2 != INVALID_HANDLE_VALUE) {
|
||||
do { if (fd2.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
|
||||
tvi.hParent = d; tvi.item.pszText = fd2.cFileName;
|
||||
TreeView_InsertItem(g_tree, &tvi);
|
||||
} while (FindNextFileW(h2, &fd2));
|
||||
FindClose(h2);
|
||||
}
|
||||
} else {
|
||||
if (wcsstr(fd.cFileName,L".py")||wcsstr(fd.cFileName,L".c")||wcsstr(fd.cFileName,L".h")||
|
||||
wcsstr(fd.cFileName,L".asm")||wcsstr(fd.cFileName,L".md")||wcsstr(fd.cFileName,L".txt")||
|
||||
wcsstr(fd.cFileName,L".json")||wcsstr(fd.cFileName,L".toml")||wcsstr(fd.cFileName,L".bat")) {
|
||||
tvi.hParent = root; tvi.item.pszText = fd.cFileName;
|
||||
TreeView_InsertItem(g_tree, &tvi);
|
||||
}
|
||||
}
|
||||
} while (FindNextFileW(hFind, &fd));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
static void open_file_at(WCHAR* path) {
|
||||
HANDLE hf = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hf == INVALID_HANDLE_VALUE) return;
|
||||
DWORD sz = GetFileSize(hf, NULL); char* buf = malloc(sz + 1);
|
||||
DWORD rd; ReadFile(hf, buf, sz, &rd, NULL); buf[sz] = '\0'; CloseHandle(hf);
|
||||
SetWindowTextA(g_edit, buf); free(buf);
|
||||
wcscpy(g_current_file, path);
|
||||
WCHAR title[MAX_PATH]; wsprintfW(title, L"%s - %s", T("app_title"), path);
|
||||
SetWindowTextW(g_hwnd, title);
|
||||
}
|
||||
|
||||
static void open_file_dialog(void) {
|
||||
WCHAR file[MAX_PATH] = L""; OPENFILENAMEW of = {sizeof(of)};
|
||||
of.lpstrFilter = L"All\0*.*\0Python\0*.py\0C\0*.c;*.h\0";
|
||||
of.lpstrFile = file; of.nMaxFile = MAX_PATH; of.Flags = OFN_FILEMUSTEXIST;
|
||||
if (GetOpenFileNameW(&of)) open_file_at(file);
|
||||
}
|
||||
|
||||
static void save_file(void) {
|
||||
if (!g_current_file[0]) { open_file_dialog(); return; }
|
||||
int len = GetWindowTextLengthA(g_edit); char* buf = malloc(len + 1);
|
||||
GetWindowTextA(g_edit, buf, len + 1);
|
||||
HANDLE hf = CreateFileW(g_current_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
if (hf != INVALID_HANDLE_VALUE) { DWORD wr; WriteFile(hf, buf, len, &wr, NULL); CloseHandle(hf); }
|
||||
free(buf); console_msg("[OK] Saved.\n");
|
||||
}
|
||||
|
||||
static void run_game(void) {
|
||||
WCHAR p[MAX_PATH]; wsprintfW(p, L"%s\\build\\lity.exe", g_engine_dir);
|
||||
if (GetFileAttributesW(p) == INVALID_FILE_ATTRIBUTES) { console_msg("[!] Build engine first\n"); return; }
|
||||
ShellExecuteW(NULL, L"open", p, NULL, g_engine_dir, SW_SHOWNORMAL);
|
||||
console_msg("[>] Run game\n");
|
||||
}
|
||||
|
||||
static void build_engine(void) {
|
||||
WCHAR cmd[MAX_PATH*2];
|
||||
wsprintfW(cmd, L"/c set PATH=C:\\mingw64\\bin;%%PATH%%&& cd /d %s\\build && cmake --build . -j4", g_engine_dir);
|
||||
ShellExecuteW(NULL, L"open", L"cmd.exe", cmd, NULL, SW_SHOWNORMAL);
|
||||
console_msg("[>] Build engine...\n");
|
||||
}
|
||||
|
||||
static void package_exe(void) {
|
||||
WCHAR src[MAX_PATH], dst[MAX_PATH] = L"";
|
||||
wsprintfW(src, L"%s\\build\\lity.exe", g_engine_dir);
|
||||
OPENFILENAMEW of = {sizeof(of)}; of.lpstrFilter = L"EXE\0*.exe\0";
|
||||
of.lpstrFile = dst; of.nMaxFile = MAX_PATH; of.lpstrTitle = L"Package"; of.Flags = OFN_OVERWRITEPROMPT;
|
||||
if (GetSaveFileNameW(&of)) { CopyFileW(src, dst, FALSE); console_msg("[OK] Packaged.\n"); }
|
||||
}
|
||||
|
||||
static void rebuild_lang_menu(void) {
|
||||
HMENU hBar = GetMenu(g_hwnd);
|
||||
HMENU hLang = CreatePopupMenu();
|
||||
for (int i = 0; i < g_lang_count; i++) {
|
||||
UINT flags = (!wcscmp(g_lang_codes[i], g_cur_lang)) ? (MF_STRING|MF_CHECKED) : MF_STRING;
|
||||
AppendMenuW(hLang, flags, IDM_LANG_BASE + i, g_lang_names[i]);
|
||||
}
|
||||
// Replace old Language menu
|
||||
HMENU hOld = GetSubMenu(hBar, 3); // Language is 4th menu
|
||||
if (hOld) { RemoveMenu(hBar, 3, MF_BYPOSITION); DestroyMenu(hOld); }
|
||||
// Insert before Help
|
||||
InsertMenuW(hBar, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hLang, T("lang"));
|
||||
DrawMenuBar(g_hwnd);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WP(HWND h, UINT m, WPARAM w, LPARAM l) {
|
||||
switch (m) {
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(w) == IDM_NEW) { SetWindowTextA(g_edit, ""); g_current_file[0] = 0; }
|
||||
else if (LOWORD(w) == IDM_OPEN) open_file_dialog();
|
||||
else if (LOWORD(w) == IDM_SAVE) save_file();
|
||||
else if (LOWORD(w) == IDM_RUN) run_game();
|
||||
else if (LOWORD(w) == IDM_BUILD) build_engine();
|
||||
else if (LOWORD(w) == IDM_PACKAGE) package_exe();
|
||||
else if (LOWORD(w) == IDM_ABOUT) MessageBoxW(h, L"Lity3D Engine v1.0\nC + MASM x64\nD3D11 + Python Scripting\n\nhttps://gitee.com/shuiyu1123/lity3d", T("about"), MB_OK|MB_ICONINFORMATION);
|
||||
else if (LOWORD(w) >= IDM_LANG_BASE && LOWORD(w) < IDM_LANG_BASE + g_lang_count) {
|
||||
int idx = LOWORD(w) - IDM_LANG_BASE;
|
||||
load_lang(g_lang_codes[idx]);
|
||||
rebuild_lang_menu();
|
||||
SetWindowTextW(g_hwnd, T("app_title"));
|
||||
populate_tree();
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY: {
|
||||
NMHDR* nm = (NMHDR*)l;
|
||||
if (nm->idFrom == IDC_TREE && nm->code == TVN_SELCHANGED) {
|
||||
TVITEMW ti = {0}; ti.mask = TVIF_TEXT|TVIF_HANDLE;
|
||||
ti.hItem = TreeView_GetSelection(g_tree);
|
||||
WCHAR name[MAX_PATH]; ti.pszText = name; ti.cchTextMax = MAX_PATH;
|
||||
TreeView_GetItem(g_tree, &ti);
|
||||
if (!ti.hItem) break;
|
||||
HTREEITEM par = TreeView_GetParent(g_tree, ti.hItem);
|
||||
WCHAR full[MAX_PATH];
|
||||
if (par) { WCHAR parent[MAX_PATH]={0}; TVITEMW pti={0};
|
||||
pti.mask=TVIF_TEXT; pti.hItem=par; pti.pszText=parent; pti.cchTextMax=MAX_PATH;
|
||||
TreeView_GetItem(g_tree, &pti);
|
||||
wsprintfW(full, L"%s\\%s\\%s", g_engine_dir, parent, name);
|
||||
} else wsprintfW(full, L"%s\\%s", g_engine_dir, name);
|
||||
DWORD attr = GetFileAttributesW(full);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
open_file_at(full);
|
||||
}
|
||||
break; }
|
||||
case WM_SIZE: {
|
||||
int w2 = LOWORD(l), h2 = HIWORD(l);
|
||||
if (w2<100||h2<100) break;
|
||||
int tw=220, ch=160;
|
||||
MoveWindow(g_tree,0,0,tw,h2-ch,TRUE);
|
||||
MoveWindow(g_edit,tw+4,0,w2-tw-4,h2-ch,TRUE);
|
||||
MoveWindow(g_console,0,h2-ch,w2,ch-24,TRUE);
|
||||
break; }
|
||||
case WM_DESTROY: PostQuitMessage(0); return 0;
|
||||
}
|
||||
return DefWindowProcW(h, m, w, l);
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hI, HINSTANCE hP, LPWSTR nC, int nS) {
|
||||
(void)hP; (void)nC; (void)nS;
|
||||
GetModuleFileNameW(NULL, g_engine_dir, MAX_PATH);
|
||||
WCHAR* sl = wcsrchr(g_engine_dir, L'\\'); if (sl) *sl = 0;
|
||||
// Editor.exe is in lity3d/Editor/, engine root is one level up
|
||||
sl = wcsrchr(g_engine_dir, L'\\'); if (sl) *sl = 0;
|
||||
INITCOMMONCONTROLSEX icc = {sizeof(icc), ICC_TREEVIEW_CLASSES}; InitCommonControlsEx(&icc);
|
||||
WNDCLASSEXW wc = {sizeof(wc)}; wc.style=CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc=WP;
|
||||
wc.hInstance=hI; wc.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1); wc.lpszClassName=L"LityEditor";
|
||||
wc.hCursor=LoadCursor(NULL,IDC_ARROW); wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
|
||||
RegisterClassExW(&wc);
|
||||
// Discover and load languages
|
||||
discover_languages();
|
||||
// Auto-detect system language
|
||||
WCHAR sysLang[10]; int n = GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, sysLang, 10);
|
||||
if (n > 0) {
|
||||
for (int i = 0; i < g_lang_count; i++) {
|
||||
if (!_wcsicmp(g_lang_codes[i], sysLang)) { load_lang(g_lang_codes[i]); goto lang_done; }
|
||||
}
|
||||
}
|
||||
load_lang(L"en");
|
||||
lang_done:
|
||||
g_hwnd = CreateWindowExW(0, L"LityEditor", T("app_title"),
|
||||
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, 100,100,1400,900, NULL, NULL, hI, NULL);
|
||||
g_tree = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, L"",
|
||||
WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,
|
||||
0,0,220,600, g_hwnd, (HMENU)IDC_TREE, hI, NULL);
|
||||
g_edit = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
|
||||
WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE|ES_AUTOVSCROLL,
|
||||
224,0,1176,600, g_hwnd, (HMENU)IDC_EDIT, hI, NULL);
|
||||
SendMessageW(g_edit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
|
||||
g_console = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
|
||||
WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE|ES_READONLY,
|
||||
0,600,1400,136, g_hwnd, (HMENU)IDC_CONSOLE, hI, NULL);
|
||||
HFONT hf = CreateFontW(14,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,0,0,0,FIXED_PITCH,L"Consolas");
|
||||
SendMessageW(g_console, WM_SETFONT, (WPARAM)hf, TRUE);
|
||||
// Build menu
|
||||
HMENU hBar = CreateMenu();
|
||||
HMENU hFile = CreatePopupMenu();
|
||||
AppendMenuW(hFile,MF_STRING,IDM_NEW,T("new")); AppendMenuW(hFile,MF_STRING,IDM_OPEN,T("open"));
|
||||
AppendMenuW(hFile,MF_STRING,IDM_SAVE,T("save")); AppendMenuW(hFile,MF_SEPARATOR,0,NULL);
|
||||
AppendMenuW(hFile,MF_STRING,IDM_ABOUT,T("about"));
|
||||
AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hFile,T("file"));
|
||||
HMENU hBuild = CreatePopupMenu();
|
||||
AppendMenuW(hBuild,MF_STRING,IDM_RUN,T("run")); AppendMenuW(hBuild,MF_SEPARATOR,0,NULL);
|
||||
AppendMenuW(hBuild,MF_STRING,IDM_BUILD,T("compile")); AppendMenuW(hBuild,MF_STRING,IDM_PACKAGE,T("package"));
|
||||
AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hBuild,T("build"));
|
||||
HMENU hLang = CreatePopupMenu();
|
||||
for (int i=0;i<g_lang_count;i++) {
|
||||
UINT flags=(!wcscmp(g_lang_codes[i],g_cur_lang))?(MF_STRING|MF_CHECKED):MF_STRING;
|
||||
AppendMenuW(hLang,flags,IDM_LANG_BASE+i,g_lang_names[i]);
|
||||
}
|
||||
AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hLang,T("lang"));
|
||||
HMENU hHelp=CreatePopupMenu(); AppendMenuW(hHelp,MF_STRING,IDM_ABOUT,T("about"));
|
||||
AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hHelp,T("help"));
|
||||
SetMenu(g_hwnd,hBar);
|
||||
populate_tree();
|
||||
console_msg("Lity3D Editor ready.\n");
|
||||
ShowWindow(g_hwnd,SW_SHOW);
|
||||
MSG msg;
|
||||
while(GetMessageW(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessageW(&msg);}
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
Reference in new issue
Block a user