static bool remove(const string& name) { lstring part = name.split("/"); HKEY rootKey = root(part.take(0)); string node = part.take(); string path = part.merge("\\"); if(node.empty()) return SHDeleteKeyW(rootKey, utf16_t(path)) == ERROR_SUCCESS; return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS; }
inline bool library::open(const string& name, const string& path) { if(handle) close(); if(path) { string filepath = {path, name, ".dll"}; handle = (uintptr_t)LoadLibraryW(utf16_t(filepath)); } if(!handle) { string filepath = {name, ".dll"}; handle = (uintptr_t)LoadLibraryW(utf16_t(filepath)); } return handle; }
static bool exists(const string &name) { lstring part = name.split("/"); HKEY handle, rootKey = root(part.take(0)); string node = part.take(); string path = part.concatenate("\\"); if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { wchar_t data[NWR_SIZE] = L""; DWORD size = NWR_SIZE * sizeof(wchar_t); LONG result = RegQueryValueExW(handle, utf16_t(node), NULL, NULL, (LPBYTE)&data, (LPDWORD)&size); RegCloseKey(handle); if(result == ERROR_SUCCESS) return true; } return false; }
static string read(const string& name) { lstring part = name.split("/"); HKEY handle, rootKey = root(part.take(0)); string node = part.take(); string path = part.merge("\\"); if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { wchar_t data[NWR_SIZE] = L""; DWORD size = NWR_SIZE * sizeof(wchar_t); LONG result = RegQueryValueExW(handle, utf16_t(node), nullptr, nullptr, (LPBYTE)&data, (LPDWORD)&size); RegCloseKey(handle); if(result == ERROR_SUCCESS) return (const char*)utf8_t(data); } return ""; }
static HFONT Font_createFont(const char *name, unsigned size, bool bold, bool italic) { return CreateFont( -(size * 96.0 / 72.0 + 0.5), 0, 0, 0, bold == false ? FW_NORMAL : FW_BOLD, italic, 0, 0, 0, 0, 0, 0, 0, utf16_t(name) ); }
void pComboButton::setText(unsigned selection, string text) { locked = true; SendMessage(hwnd, CB_DELETESTRING, selection, 0); SendMessage(hwnd, CB_INSERTSTRING, selection, (LPARAM)(wchar_t*)utf16_t(text)); setSelection(comboButton.state.selection); locked = false; }
inline bool directory::exists(const string &pathname) { string name = pathname; name.trim<1>("\""); DWORD result = GetFileAttributes(utf16_t(name)); if(result == INVALID_FILE_ATTRIBUTES) return false; return (result & FILE_ATTRIBUTE_DIRECTORY); }
static void write(const string& name, const string& data = "") { lstring part = name.split("/"); HKEY handle, rootKey = root(part.take(0)); string node = part.take(), path; DWORD disposition; for(unsigned n = 0; n < part.size(); n++) { path.append(part[n]); if(RegCreateKeyExW(rootKey, utf16_t(path), 0, nullptr, 0, NWR_FLAGS | KEY_ALL_ACCESS, nullptr, &handle, &disposition) == ERROR_SUCCESS) { if(n == part.size() - 1) { RegSetValueExW(handle, utf16_t(node), 0, REG_SZ, (BYTE*)(wchar_t*)utf16_t(data), (data.length() + 1) * sizeof(wchar_t)); } RegCloseKey(handle); } path.append("\\"); } }
inline lstring directory::files(const string &pathname, const string &pattern) { lstring list; string path = pathname; path.transform("/", "\\"); if(!strend(path, "\\")) path.append("\\"); path.append("*"); HANDLE handle; WIN32_FIND_DATA data; handle = FindFirstFile(utf16_t(path), &data); if(handle != INVALID_HANDLE_VALUE) { if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { string name = utf8_t(data.cFileName); if(wildcard(name, pattern)) list.append(name); } while(FindNextFile(handle, &data) != false) { if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { string name = utf8_t(data.cFileName); if(wildcard(name, pattern)) list.append(name); } } FindClose(handle); } if(list.size() > 0) sort(&list[0], list.size()); return list; }
void pButton::setText(string text) { if(text.empty()) { //bitmaps will not show up if text is empty SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | BS_BITMAP); } else { //text will not show up if BS_BITMAP is set SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~BS_BITMAP); } if(OsVersion() >= WindowsVista && button.state.image.empty() == false && text.empty() == false) { //Vista+ does not add spacing between the icon and text; causing them to run into each other SetWindowText(hwnd, utf16_t(string{" ", text})); } else { SetWindowText(hwnd, utf16_t(text)); } }
inline lstring directory::folders(const string &pathname, const string &pattern) { lstring list; string path = pathname; path.transform("/", "\\"); if(!strend(path, "\\")) path.append("\\"); path.append("*"); HANDLE handle; WIN32_FIND_DATA data; handle = FindFirstFile(utf16_t(path), &data); if(handle != INVALID_HANDLE_VALUE) { if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) { if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { string name = (const char*)utf8_t(data.cFileName); if(wildcard(name, pattern)) list.append(name); } } while(FindNextFile(handle, &data) != false) { if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) { if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { string name = (const char*)utf8_t(data.cFileName); if(wildcard(name, pattern)) list.append(name); } } } FindClose(handle); } if(list.size() > 0) list.sort(); for(auto &name : list) name.append("/"); //must append after sorting return list; }
void pTextEdit::setText(const string &text) { locked = true; string output = text; output.replace("\r", ""); output.replace("\n", "\r\n"); SetWindowText(hwnd, utf16_t(output)); locked = false; }
inline bool directory::remove(const string &pathname) { lstring list = directory::contents(pathname); for(auto &name : list) { if(name.endswith("/")) directory::remove({pathname, name}); else file::remove({pathname, name}); } return _wrmdir(utf16_t(pathname)) == 0; }
void pCheckButton::setText(string text) { if(text.empty()) { SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | BS_BITMAP); } else { SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~BS_BITMAP); } SetWindowText(hwnd, utf16_t(text)); }
static bool exists(const string &filename) { #if !defined(_WIN32) struct stat64 data; return stat64(filename, &data) == 0; #else struct __stat64 data; return _wstat64(utf16_t(filename), &data) == 0; #endif }
inline bool library::open(const char *name) { if(handle) close(); char *t = new char[strlen(name) + 8]; strcpy(t, name); strcat(t, ".dll"); handle = (uintptr_t)LoadLibraryW(utf16_t(t)); delete[] t; return handle; }
static uintmax_t size(const string &filename) { #if !defined(_WIN32) struct stat64 data; stat64(filename, &data); #else struct __stat64 data; _wstat64(utf16_t(filename), &data); #endif return S_ISREG(data.st_mode) ? data.st_size : 0u; }
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) { widget->window = CreateWindow( L"BUTTON", utf16_t(text), WS_CHILD | WS_TABSTOP | WS_VISIBLE, x, y, width, height, parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0 ); SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this); SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0); }
inline bool directory::create(const string &pathname, unsigned permissions) { string path; lstring list = string{pathname}.transform("\\", "/").rtrim<1>("/").split("/"); bool result = true; for(auto &part : list) { path.append(part, "/"); result &= (_wmkdir(utf16_t(path)) == 0); } return result; }
static bool exists(const string& filename) { #if !defined(_WIN32) struct stat64 data; if(stat64(filename, &data) != 0) return false; #else struct __stat64 data; if(_wstat64(utf16_t(filename), &data) != 0) return false; #endif //return true if this is a file, and false if this is a directory return !(data.st_mode & S_IFDIR); }
static int CALLBACK BrowserWindowCallbackProc(HWND hwnd, UINT msg, LPARAM lparam, LPARAM lpdata) { if(msg == BFFM_INITIALIZED) { if(lpdata) { auto state = (BrowserWindow::State*)lpdata; utf16_t wpath(string{state->path}.transform("/", "\\")); if(state->title) SetWindowText(hwnd, utf16_t(state->title)); SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)(wchar_t*)wpath); } } return 0; }
string realpath(const string &name) { string result; #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; if(_wfullpath(path, utf16_t(name), PATH_MAX)) result = (const char*)utf8_t(path); result.transform("\\", "/"); #else char path[PATH_MAX] = ""; if(::realpath(name, path)) result = path; #endif return result; }
string realpath(const string& name) { string result; #if defined(PLATFORM_WINDOWS) wchar_t path[PATH_MAX] = L""; if(_wfullpath(path, utf16_t(name), PATH_MAX)) result = (const char*)utf8_t(path); result.transform("\\", "/"); #else char path[PATH_MAX] = ""; if(::realpath(name, path)) result = path; #endif if(result.empty()) result = {activepath(), name}; return result; }
void pWindow::updateMenu() { if(hmenu) DestroyMenu(hmenu); hmenu = CreateMenu(); for(auto &menu : window.state.menu) { menu.p.update(window); if(menu.visible()) { AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT_PTR)menu.p.hmenu, utf16_t(menu.state.text)); } } SetMenu(hwnd, window.state.menuVisible ? hmenu : 0); }
static time_t timestamp(const string &filename, file::time mode = file::time::create) { #if !defined(_WIN32) struct stat64 data; stat64(filename, &data); #else struct __stat64 data; _wstat64(utf16_t(filename), &data); #endif switch(mode) { default: case file::time::create: return data.st_ctime; case file::time::modify: return data.st_mtime; case file::time::access: return data.st_atime; } }
bool open(const string &filename, mode mode_) { if(fp) return false; switch(file_mode = mode_) { #if !defined(_WIN32) case mode::read: fp = fopen(filename, "rb" ); break; case mode::write: fp = fopen(filename, "wb+"); break; //need read permission for buffering case mode::readwrite: fp = fopen(filename, "rb+"); break; case mode::writeread: fp = fopen(filename, "wb+"); break; #else case mode::read: fp = _wfopen(utf16_t(filename), L"rb" ); break; case mode::write: fp = _wfopen(utf16_t(filename), L"wb+"); break; case mode::readwrite: fp = _wfopen(utf16_t(filename), L"rb+"); break; case mode::writeread: fp = _wfopen(utf16_t(filename), L"wb+"); break; #endif } if(!fp) return false; buffer_offset = -1; //invalidate buffer file_offset = 0; fseek(fp, 0, SEEK_END); file_size = ftell(fp); fseek(fp, 0, SEEK_SET); return true; }
bool string::readfile(const string &filename) { assign(""); #if !defined(_WIN32) FILE *fp = fopen(filename, "rb"); #else FILE *fp = _wfopen(utf16_t(filename), L"rb"); #endif if(!fp) return false; fseek(fp, 0, SEEK_END); unsigned size = ftell(fp); rewind(fp); char *fdata = new char[size + 1]; unsigned unused = fread(fdata, 1, size, fp); fclose(fp); fdata[size] = 0; assign(fdata); delete[] fdata; return true; }
void set_shader(const char *source) { if(!caps.shader) return; if(effect) { effect->Release(); effect = NULL; } if(!source || !*source) { shader_source_markup = ""; return; } shader_source_markup = source; XML::Document document(shader_source_markup); bool is_hlsl = document["shader"]["language"].data == "HLSL"; string shader_source = document["shader"]["source"].data; if(shader_source == "") return; HMODULE d3dx; for(unsigned i = 0; i < 256; i++) { char t[256]; sprintf(t, "d3dx9_%u.dll", i); d3dx = LoadLibraryW(utf16_t(t)); if(d3dx) break; } if(!d3dx) d3dx = LoadLibraryW(L"d3dx9.dll"); if(!d3dx) return; EffectProc effectProc = (EffectProc)GetProcAddress(d3dx, "D3DXCreateEffect"); TextureProc textureProc = (TextureProc)GetProcAddress(d3dx, "D3DXCreateTextureFromFileA"); LPD3DXBUFFER pBufferErrors = NULL; effectProc(device, shader_source, lstrlenA(shader_source), NULL, NULL, 0, NULL, &effect, &pBufferErrors); D3DXHANDLE hTech; effect->FindNextValidTechnique(NULL, &hTech); effect->SetTechnique(hTech); }
static lstring contents(const string& name) { lstring part = name.split("/"), result; HKEY handle, rootKey = root(part.take(0)); part.remove(); string path = part.merge("\\"); if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { DWORD folders, nodes; RegQueryInfoKey(handle, nullptr, nullptr, nullptr, &folders, nullptr, nullptr, &nodes, nullptr, nullptr, nullptr, nullptr); for(unsigned n = 0; n < folders; n++) { wchar_t name[NWR_SIZE] = L""; DWORD size = NWR_SIZE * sizeof(wchar_t); RegEnumKeyEx(handle, n, (wchar_t*)&name, &size, nullptr, nullptr, nullptr, nullptr); result.append({(const char*)utf8_t(name), "/"}); } for(unsigned n = 0; n < nodes; n++) { wchar_t name[NWR_SIZE] = L""; DWORD size = NWR_SIZE * sizeof(wchar_t); RegEnumValueW(handle, n, (wchar_t*)&name, &size, nullptr, nullptr, nullptr, nullptr); result.append((const char*)utf8_t(name)); } RegCloseKey(handle); } return result; }
void pWindow::setTitle(const string &text) { SetWindowText(hwnd, utf16_t(text)); }