feat: move temp files to userspace folder
This commit is contained in:
parent
1d349d6692
commit
40602121ea
10
dialog.jai
10
dialog.jai
@ -55,7 +55,7 @@ dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
|
|||||||
SendMessageW(state.edit_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);
|
SendMessageW(state.edit_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);
|
||||||
|
|
||||||
// Populate with existing URL if present
|
// Populate with existing URL if present
|
||||||
config_filename := ifx state.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if read_ok {
|
if read_ok {
|
||||||
existing_url := get_json_string_field(config_data, "\"_url\"");
|
existing_url := get_json_string_field(config_data, "\"_url\"");
|
||||||
@ -112,7 +112,7 @@ dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
|
|||||||
mode: string;
|
mode: string;
|
||||||
port := ifx state.is_test_mode then 10899 else 10801;
|
port := ifx state.is_test_mode then 10899 else 10801;
|
||||||
update_interval := 3600;
|
update_interval := 3600;
|
||||||
config_filename := ifx state.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if read_ok {
|
if read_ok {
|
||||||
extracted_mode := get_json_string_field(config_data, "\"_mode\"");
|
extracted_mode := get_json_string_field(config_data, "\"_mode\"");
|
||||||
@ -142,7 +142,7 @@ dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
|
|||||||
state.url_saved = true;
|
state.url_saved = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
config_filename := ifx state.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
DeleteFileW(utf8_to_wide(config_filename));
|
DeleteFileW(utf8_to_wide(config_filename));
|
||||||
state.url_saved = true;
|
state.url_saved = true;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ show_config_port_dialog :: (parent_hwnd: HWND, is_test_mode := false) -> bool {
|
|||||||
SendMessageW(state.edit_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);
|
SendMessageW(state.edit_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);
|
||||||
|
|
||||||
// Populate with existing port if present
|
// Populate with existing port if present
|
||||||
config_filename := ifx state.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
port := ifx state.is_test_mode then 10899 else 10801;
|
port := ifx state.is_test_mode then 10899 else 10801;
|
||||||
if !state.is_test_mode && read_ok {
|
if !state.is_test_mode && read_ok {
|
||||||
@ -350,7 +350,7 @@ show_config_port_dialog :: (parent_hwnd: HWND, is_test_mode := false) -> bool {
|
|||||||
if ok && val > 0 && val <= 65535 {
|
if ok && val > 0 && val <= 65535 {
|
||||||
port := xx val;
|
port := xx val;
|
||||||
|
|
||||||
config_filename := ifx state.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
url := "";
|
url := "";
|
||||||
mode := "system_proxy";
|
mode := "system_proxy";
|
||||||
|
|||||||
110
main.jai
110
main.jai
@ -8,6 +8,67 @@
|
|||||||
#load "dialog.jai";
|
#load "dialog.jai";
|
||||||
#load "updater.jai";
|
#load "updater.jai";
|
||||||
|
|
||||||
|
global_userspace_dir: string;
|
||||||
|
global_config_path: string;
|
||||||
|
global_config_run_path: string;
|
||||||
|
global_log_path: string;
|
||||||
|
|
||||||
|
init_userspace_paths :: (is_test: bool) {
|
||||||
|
name_wide := utf8_to_wide("LOCALAPPDATA");
|
||||||
|
len := GetEnvironmentVariableW(name_wide, null, 0);
|
||||||
|
if len > 0 {
|
||||||
|
buf := alloc(cast(s64) (len * 2));
|
||||||
|
defer free(buf);
|
||||||
|
GetEnvironmentVariableW(name_wide, cast(*u16) buf, len);
|
||||||
|
local_app_data := wide_to_utf8(cast(*u16) buf);
|
||||||
|
defer free(local_app_data);
|
||||||
|
|
||||||
|
global_userspace_dir = sprint("%\\singbox-tray", local_app_data);
|
||||||
|
} else {
|
||||||
|
global_userspace_dir = copy_string(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure directory exists
|
||||||
|
dir_wide := utf8_to_wide(global_userspace_dir);
|
||||||
|
CreateDirectoryW(dir_wide, null);
|
||||||
|
|
||||||
|
config_name := ifx is_test then "config_test.json" else "config.json";
|
||||||
|
config_run_name := ifx is_test then "config_run_test.json" else "config_run.json";
|
||||||
|
log_name := ifx is_test then "singbox_tray_test.log" else "singbox_tray.log";
|
||||||
|
|
||||||
|
global_config_path = sprint("%\\%", global_userspace_dir, config_name);
|
||||||
|
global_config_run_path = sprint("%\\%", global_userspace_dir, config_run_name);
|
||||||
|
global_log_path = sprint("%\\%", global_userspace_dir, log_name);
|
||||||
|
|
||||||
|
// Migrate existing configuration if it exists in the executable's directory
|
||||||
|
// but not in the userspace directory yet.
|
||||||
|
if file_exists(config_name) {
|
||||||
|
if !file_exists(global_config_path) {
|
||||||
|
data, ok := read_entire_file(config_name);
|
||||||
|
if ok {
|
||||||
|
write_entire_file(global_config_path, data);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !is_test {
|
||||||
|
test_config := sprint("%\\config_test.json", global_userspace_dir);
|
||||||
|
defer free(test_config);
|
||||||
|
test_config_run := sprint("%\\config_run_test.json", global_userspace_dir);
|
||||||
|
defer free(test_config_run);
|
||||||
|
test_log := sprint("%\\singbox_tray_test.log", global_userspace_dir);
|
||||||
|
defer free(test_log);
|
||||||
|
test_singbox_log := sprint("%\\sing-box_test.log", global_userspace_dir);
|
||||||
|
defer free(test_singbox_log);
|
||||||
|
|
||||||
|
DeleteFileW(utf8_to_wide(test_config));
|
||||||
|
DeleteFileW(utf8_to_wide(test_config_run));
|
||||||
|
DeleteFileW(utf8_to_wide(test_log));
|
||||||
|
DeleteFileW(utf8_to_wide(test_singbox_log));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Custom constants
|
// Custom constants
|
||||||
TIMER_PROCESS_CHECK :: 1;
|
TIMER_PROCESS_CHECK :: 1;
|
||||||
TIMER_ANIMATION :: 2;
|
TIMER_ANIMATION :: 2;
|
||||||
@ -58,7 +119,7 @@ append_to_log_file :: (text: string) {
|
|||||||
OPEN_ALWAYS :: 4;
|
OPEN_ALWAYS :: 4;
|
||||||
FILE_END :: 2;
|
FILE_END :: 2;
|
||||||
|
|
||||||
filename := ifx global_is_test_mode then "singbox_tray_test.log" else "singbox_tray.log";
|
filename := ifx global_log_path.count > 0 then global_log_path else (ifx global_is_test_mode then "singbox_tray_test.log" else "singbox_tray.log");
|
||||||
wide_path := utf8_to_wide(filename);
|
wide_path := utf8_to_wide(filename);
|
||||||
|
|
||||||
hFile := CreateFileW(
|
hFile := CreateFileW(
|
||||||
@ -147,7 +208,7 @@ log_singbox :: (message: string, is_test_mode: bool) {
|
|||||||
OutputDebugStringW(utf8_to_wide(colored_log));
|
OutputDebugStringW(utf8_to_wide(colored_log));
|
||||||
|
|
||||||
// Append to the correct log file
|
// Append to the correct log file
|
||||||
filename := ifx is_test_mode then "singbox_tray_test.log" else "singbox_tray.log";
|
filename := ifx global_log_path.count > 0 then global_log_path else (ifx is_test_mode then "singbox_tray_test.log" else "singbox_tray.log");
|
||||||
wide_path := utf8_to_wide(filename);
|
wide_path := utf8_to_wide(filename);
|
||||||
|
|
||||||
hFile := CreateFileW(
|
hFile := CreateFileW(
|
||||||
@ -267,7 +328,7 @@ set_autostart :: (enable: bool) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hidden Process Spawning with Job Object configuration and stdout/stderr redirection
|
// Hidden Process Spawning with Job Object configuration and stdout/stderr redirection
|
||||||
create_process_hidden :: (cmd: string, stdout_handle: HANDLE = INVALID_HANDLE_VALUE) -> HANDLE, PROCESS_INFORMATION, bool {
|
create_process_hidden :: (cmd: string, stdout_handle: HANDLE = INVALID_HANDLE_VALUE, working_dir: string = "") -> HANDLE, PROCESS_INFORMATION, bool {
|
||||||
startup_info: STARTUPINFOW;
|
startup_info: STARTUPINFOW;
|
||||||
startup_info.cb = size_of(STARTUPINFOW);
|
startup_info.cb = size_of(STARTUPINFOW);
|
||||||
startup_info.dwFlags = STARTF_USESHOWWINDOW;
|
startup_info.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
@ -294,6 +355,11 @@ create_process_hidden :: (cmd: string, stdout_handle: HANDLE = INVALID_HANDLE_VA
|
|||||||
|
|
||||||
inherit_handles := ifx stdout_handle != INVALID_HANDLE_VALUE then cast(BOOL) 1 else cast(BOOL) 0;
|
inherit_handles := ifx stdout_handle != INVALID_HANDLE_VALUE then cast(BOOL) 1 else cast(BOOL) 0;
|
||||||
|
|
||||||
|
working_dir_wide: *u16 = null;
|
||||||
|
if working_dir.count > 0 {
|
||||||
|
working_dir_wide = utf8_to_wide(working_dir);
|
||||||
|
}
|
||||||
|
|
||||||
success := CreateProcessW(
|
success := CreateProcessW(
|
||||||
null,
|
null,
|
||||||
cmd_wide,
|
cmd_wide,
|
||||||
@ -302,7 +368,7 @@ create_process_hidden :: (cmd: string, stdout_handle: HANDLE = INVALID_HANDLE_VA
|
|||||||
inherit_handles,
|
inherit_handles,
|
||||||
CREATE_NO_WINDOW,
|
CREATE_NO_WINDOW,
|
||||||
null,
|
null,
|
||||||
null,
|
working_dir_wide,
|
||||||
*startup_info,
|
*startup_info,
|
||||||
*process_info
|
*process_info
|
||||||
);
|
);
|
||||||
@ -351,9 +417,8 @@ update_tray :: (app: *App_State) {
|
|||||||
start_singbox :: (app: *App_State) -> bool {
|
start_singbox :: (app: *App_State) -> bool {
|
||||||
if app.singbox_running return true;
|
if app.singbox_running return true;
|
||||||
|
|
||||||
config_filename := ifx app.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_run_filename := ifx app.is_test_mode then "config_run_test.json" else "config_run.json";
|
config_run_filename := global_config_run_path;
|
||||||
singbox_log_filename := ifx app.is_test_mode then "sing-box_test.log" else "sing-box.log";
|
|
||||||
|
|
||||||
has_config := file_exists(config_filename);
|
has_config := file_exists(config_filename);
|
||||||
url_present := false;
|
url_present := false;
|
||||||
@ -431,13 +496,14 @@ start_singbox :: (app: *App_State) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exe_path := "sing-box.exe";
|
relative_exe_path := "sing-box.exe";
|
||||||
// Check if sing-box.exe is not in current folder, check in the sing-box subfolder
|
// Check if sing-box.exe is not in current folder, check in the sing-box subfolder
|
||||||
if !file_exists("sing-box.exe") {
|
if !file_exists("sing-box.exe") {
|
||||||
if file_exists("sing-box/sing-box.exe") {
|
if file_exists("sing-box/sing-box.exe") {
|
||||||
exe_path = "sing-box\\sing-box.exe";
|
relative_exe_path = "sing-box\\sing-box.exe";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
exe_path := get_absolute_path(relative_exe_path);
|
||||||
|
|
||||||
hReadPipe, hWritePipe: HANDLE;
|
hReadPipe, hWritePipe: HANDLE;
|
||||||
sa: SECURITY_ATTRIBUTES;
|
sa: SECURITY_ATTRIBUTES;
|
||||||
@ -454,7 +520,7 @@ start_singbox :: (app: *App_State) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd := tprint("% run -c %", exe_path, config_run_filename);
|
cmd := tprint("% run -c %", exe_path, config_run_filename);
|
||||||
job, pi, ok := create_process_hidden(cmd, hWritePipe);
|
job, pi, ok := create_process_hidden(cmd, hWritePipe, global_userspace_dir);
|
||||||
|
|
||||||
if hWritePipe != INVALID_HANDLE_VALUE {
|
if hWritePipe != INVALID_HANDLE_VALUE {
|
||||||
CloseHandle(hWritePipe);
|
CloseHandle(hWritePipe);
|
||||||
@ -528,9 +594,7 @@ stop_singbox :: (app: *App_State) {
|
|||||||
log_info("Test Mode: System proxy bypass kept on stop.\n");
|
log_info("Test Mode: System proxy bypass kept on stop.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up temporary run config
|
DeleteFileW(utf8_to_wide(global_config_run_path));
|
||||||
config_run_filename := ifx app.is_test_mode then "config_run_test.json" else "config_run.json";
|
|
||||||
DeleteFileW(utf8_to_wide(config_run_filename));
|
|
||||||
|
|
||||||
update_tray(app);
|
update_tray(app);
|
||||||
log_print("Sing-box stopped.\n");
|
log_print("Sing-box stopped.\n");
|
||||||
@ -567,8 +631,7 @@ check_process_status :: (app: *App_State) {
|
|||||||
log_info("Test Mode: System proxy bypass kept on unexpected exit.\n");
|
log_info("Test Mode: System proxy bypass kept on unexpected exit.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
config_run_filename := ifx app.is_test_mode then "config_run_test.json" else "config_run.json";
|
DeleteFileW(utf8_to_wide(global_config_run_path));
|
||||||
DeleteFileW(utf8_to_wide(config_run_filename));
|
|
||||||
|
|
||||||
update_tray(app);
|
update_tray(app);
|
||||||
}
|
}
|
||||||
@ -644,6 +707,8 @@ show_context_menu :: (app: *App_State) {
|
|||||||
AppendMenuW(hUpdateMenu, MF_STRING | (ifx current_interval == 259200 then MF_CHECKED else 0), CMD_UPDATE_3D, utf8_to_wide("3 days"));
|
AppendMenuW(hUpdateMenu, MF_STRING | (ifx current_interval == 259200 then MF_CHECKED else 0), CMD_UPDATE_3D, utf8_to_wide("3 days"));
|
||||||
AppendMenuW(hUpdateMenu, MF_STRING | (ifx current_interval == 604800 then MF_CHECKED else 0), CMD_UPDATE_WEEKLY, utf8_to_wide("weekly"));
|
AppendMenuW(hUpdateMenu, MF_STRING | (ifx current_interval == 604800 then MF_CHECKED else 0), CMD_UPDATE_WEEKLY, utf8_to_wide("weekly"));
|
||||||
AppendMenuW(hConfigureMenu, MF_POPUP, cast(s64) hUpdateMenu, utf8_to_wide("Auto-update"));
|
AppendMenuW(hConfigureMenu, MF_POPUP, cast(s64) hUpdateMenu, utf8_to_wide("Auto-update"));
|
||||||
|
AppendMenuW(hConfigureMenu, MF_SEPARATOR, 0, null);
|
||||||
|
AppendMenuW(hConfigureMenu, MF_STRING, CMD_CONFIG_DIR, utf8_to_wide("Config directory..."));
|
||||||
|
|
||||||
AppendMenuW(hMenu, MF_POPUP, cast(s64) hConfigureMenu, utf8_to_wide("Configure"));
|
AppendMenuW(hMenu, MF_POPUP, cast(s64) hConfigureMenu, utf8_to_wide("Configure"));
|
||||||
|
|
||||||
@ -691,7 +756,7 @@ show_context_menu :: (app: *App_State) {
|
|||||||
if changed {
|
if changed {
|
||||||
log_print("Port configured, updating state...\n");
|
log_print("Port configured, updating state...\n");
|
||||||
|
|
||||||
config_filename := ifx app.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if read_ok {
|
if read_ok {
|
||||||
port_str := get_json_val_field(config_data, "\"_port\"");
|
port_str := get_json_val_field(config_data, "\"_port\"");
|
||||||
@ -718,7 +783,7 @@ show_context_menu :: (app: *App_State) {
|
|||||||
if app.use_system_proxy {
|
if app.use_system_proxy {
|
||||||
app.use_system_proxy = false;
|
app.use_system_proxy = false;
|
||||||
|
|
||||||
config_filename := ifx app.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if read_ok {
|
if read_ok {
|
||||||
url := get_json_string_field(config_data, "\"_url\"");
|
url := get_json_string_field(config_data, "\"_url\"");
|
||||||
@ -743,7 +808,7 @@ show_context_menu :: (app: *App_State) {
|
|||||||
if !app.use_system_proxy {
|
if !app.use_system_proxy {
|
||||||
app.use_system_proxy = true;
|
app.use_system_proxy = true;
|
||||||
|
|
||||||
config_filename := ifx app.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if read_ok {
|
if read_ok {
|
||||||
url := get_json_string_field(config_data, "\"_url\"");
|
url := get_json_string_field(config_data, "\"_url\"");
|
||||||
@ -775,6 +840,9 @@ show_context_menu :: (app: *App_State) {
|
|||||||
MessageBoxW(app.hwnd, utf8_to_wide("Failed to update Windows registry autostart configuration."), utf8_to_wide("Sing-box Tray"), MB_ICONERROR);
|
MessageBoxW(app.hwnd, utf8_to_wide("Failed to update Windows registry autostart configuration."), utf8_to_wide("Sing-box Tray"), MB_ICONERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case CMD_CONFIG_DIR; {
|
||||||
|
ShellExecuteW(null, utf8_to_wide("open"), utf8_to_wide(global_userspace_dir), null, null, 1);
|
||||||
|
}
|
||||||
case CMD_UPDATE_NEVER; {
|
case CMD_UPDATE_NEVER; {
|
||||||
save_update_interval(app, 0);
|
save_update_interval(app, 0);
|
||||||
log_print("Auto-update interval set to: Never\n");
|
log_print("Auto-update interval set to: Never\n");
|
||||||
@ -971,7 +1039,7 @@ global_is_test_mode: bool = false;
|
|||||||
save_update_interval :: (app: *App_State, interval: s32) {
|
save_update_interval :: (app: *App_State, interval: s32) {
|
||||||
app.updater_data.update_interval_seconds = interval;
|
app.updater_data.update_interval_seconds = interval;
|
||||||
|
|
||||||
config_filename := ifx app.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if read_ok {
|
if read_ok {
|
||||||
url := get_json_string_field(config_data, "\"_url\"");
|
url := get_json_string_field(config_data, "\"_url\"");
|
||||||
@ -1017,6 +1085,8 @@ main :: () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_userspace_paths(is_test);
|
||||||
|
|
||||||
hInstance := GetModuleHandleW(null);
|
hInstance := GetModuleHandleW(null);
|
||||||
class_name_str := ifx is_test then "SingboxTrayControllerClassTest" else "SingboxTrayControllerClass";
|
class_name_str := ifx is_test then "SingboxTrayControllerClassTest" else "SingboxTrayControllerClass";
|
||||||
class_name := utf8_to_wide(class_name_str);
|
class_name := utf8_to_wide(class_name_str);
|
||||||
@ -1060,7 +1130,7 @@ main :: () {
|
|||||||
|
|
||||||
app_state.hwnd = hwnd;
|
app_state.hwnd = hwnd;
|
||||||
|
|
||||||
config_filename := ifx app_state.is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
|
|
||||||
app_state.updater_data.update_interval_seconds = 3600; // default
|
app_state.updater_data.update_interval_seconds = 3600; // default
|
||||||
|
|
||||||
|
|||||||
@ -81,7 +81,7 @@ download_url :: (url: string) -> string, bool, string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
perform_update :: (is_test_mode := false) -> changed: bool, success: bool, error_msg: string {
|
perform_update :: (is_test_mode := false) -> changed: bool, success: bool, error_msg: string {
|
||||||
config_filename := ifx is_test_mode then "config_test.json" else "config.json";
|
config_filename := global_config_path;
|
||||||
|
|
||||||
config_data, read_ok := read_entire_file(config_filename);
|
config_data, read_ok := read_entire_file(config_filename);
|
||||||
if !read_ok {
|
if !read_ok {
|
||||||
|
|||||||
12
win32.jai
12
win32.jai
@ -164,6 +164,7 @@ CMD_UPDATE_12H :: 1014;
|
|||||||
CMD_UPDATE_DAILY :: 1015;
|
CMD_UPDATE_DAILY :: 1015;
|
||||||
CMD_UPDATE_3D :: 1016;
|
CMD_UPDATE_3D :: 1016;
|
||||||
CMD_UPDATE_WEEKLY :: 1017;
|
CMD_UPDATE_WEEKLY :: 1017;
|
||||||
|
CMD_CONFIG_DIR :: 1018;
|
||||||
|
|
||||||
// Boolean constants
|
// Boolean constants
|
||||||
FALSE :: 0;
|
FALSE :: 0;
|
||||||
@ -204,6 +205,8 @@ GetWindowTextLengthW :: (hWnd: HWND) -> s32 #foreign user32;
|
|||||||
|
|
||||||
SendMessageW :: (hWnd: HWND, Msg: u32, wParam: WPARAM, lParam: LPARAM) -> LRESULT #foreign user32;
|
SendMessageW :: (hWnd: HWND, Msg: u32, wParam: WPARAM, lParam: LPARAM) -> LRESULT #foreign user32;
|
||||||
SetEvent :: (hEvent: HANDLE) -> BOOL #foreign kernel32;
|
SetEvent :: (hEvent: HANDLE) -> BOOL #foreign kernel32;
|
||||||
|
GetEnvironmentVariableW :: (lpName: *u16, lpBuffer: *u16, nSize: u32) -> u32 #foreign kernel32;
|
||||||
|
CreateDirectoryW :: (lpPathName: *u16, lpSecurityAttributes: *void) -> BOOL #foreign kernel32;
|
||||||
SetFocus :: (hWnd: HWND) -> HWND #foreign user32;
|
SetFocus :: (hWnd: HWND) -> HWND #foreign user32;
|
||||||
|
|
||||||
LOWORD :: (val: WPARAM) -> u16 {
|
LOWORD :: (val: WPARAM) -> u16 {
|
||||||
@ -314,6 +317,15 @@ SHGetStockIconInfo :: (
|
|||||||
psii: *SHSTOCKICONINFO
|
psii: *SHSTOCKICONINFO
|
||||||
) -> s32 #foreign shell32;
|
) -> s32 #foreign shell32;
|
||||||
|
|
||||||
|
ShellExecuteW :: (
|
||||||
|
hwnd: HWND,
|
||||||
|
lpOperation: LPCWSTR,
|
||||||
|
lpFile: LPCWSTR,
|
||||||
|
lpParameters: LPCWSTR,
|
||||||
|
lpDirectory: LPCWSTR,
|
||||||
|
nShowCmd: s32
|
||||||
|
) -> HANDLE #foreign shell32;
|
||||||
|
|
||||||
DestroyIcon :: (hIcon: HICON) -> BOOL #foreign user32;
|
DestroyIcon :: (hIcon: HICON) -> BOOL #foreign user32;
|
||||||
|
|
||||||
wcslen :: (str: *u16) -> int {
|
wcslen :: (str: *u16) -> int {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user