Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/shared/utf8api.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/shared/utf8api.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,1186 @@ +#include "shared.h" + + +#include <lmcons.h> + +#ifndef BIF_NEWDIALOGSTYLE +#define BIF_NEWDIALOGSTYLE 0x0040 +#endif + +using namespace pfc; + +class param_os_from_utf8 +{ + bool m_is_null; + WORD m_low_word; + stringcvt::string_os_from_utf8 m_cvt; +public: + param_os_from_utf8(const char * p) : + m_is_null(p==NULL), + m_low_word( ((t_size)p & ~0xFFFF) == 0 ? (WORD)((t_size)p & 0xFFFF) : 0), + m_cvt( p != NULL && ((t_size)p & ~0xFFFF) != 0 ? p : "") + {} + operator const TCHAR *() + { + return get_ptr(); + } + const TCHAR * get_ptr() + { + return m_low_word ? (const TCHAR*)(t_size)m_low_word : m_is_null ? 0 : m_cvt.get_ptr(); + } + +}; + + + +extern "C" { + +LRESULT SHARED_EXPORT uSendMessageText(HWND wnd,UINT msg,WPARAM wp,const char * p_text) +{ + if (p_text == NULL) + return SendMessage(wnd,msg,wp,0); + else { + stringcvt::string_os_from_utf8 temp; + temp.convert(p_text); + return SendMessage(wnd,msg,wp,(LPARAM)temp.get_ptr()); + } +} + +LRESULT SHARED_EXPORT uSendDlgItemMessageText(HWND wnd,UINT id,UINT msg,WPARAM wp,const char * text) +{ + return uSendMessageText(uGetDlgItem(wnd,id),msg,wp,text);//SendDlgItemMessage(wnd,id,msg,wp,(long)(const TCHAR*)string_os_from_utf8(text)); +} + +BOOL SHARED_EXPORT uGetWindowText(HWND wnd,string_base & out) +{ + PFC_ASSERT( wnd != NULL ); + int len = GetWindowTextLength(wnd); + if (len>0) + { + len++; + pfc::array_t<TCHAR> temp; + temp.set_size(len); + temp[0]=0; + if (GetWindowText(wnd,temp.get_ptr(),len)>0) + { + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; + } + else return FALSE; + } + else + { + out.reset(); + return TRUE; + } +} + +BOOL SHARED_EXPORT uSetWindowTextEx(HWND wnd,const char * p_text,size_t p_text_length) +{ + return SetWindowText(wnd,stringcvt::string_os_from_utf8(p_text, p_text_length)); +} + + +BOOL SHARED_EXPORT uGetDlgItemText(HWND wnd,UINT id,string_base & out) +{ + return uGetWindowText(GetDlgItem(wnd,id),out); +} + +BOOL SHARED_EXPORT uSetDlgItemTextEx(HWND wnd,UINT id,const char * p_text,size_t p_text_length) +{ + return SetDlgItemText(wnd,id,stringcvt::string_os_from_utf8(p_text,p_text_length)); +} + +int SHARED_EXPORT uMessageBox(HWND wnd,const char * text,const char * caption,UINT type) +{ + modal_dialog_scope scope(wnd); + return MessageBox(wnd,param_os_from_utf8(text),param_os_from_utf8(caption),type); +} + +void SHARED_EXPORT uOutputDebugString(const char * msg) {OutputDebugString(stringcvt::string_os_from_utf8(msg));} + +BOOL SHARED_EXPORT uAppendMenu(HMENU menu,UINT flags,UINT_PTR id,const char * content) +{ + return AppendMenu(menu,flags,id,param_os_from_utf8(content)); +} + +BOOL SHARED_EXPORT uInsertMenu(HMENU menu,UINT position,UINT flags,UINT_PTR id,const char * content) +{ + return InsertMenu(menu,position,flags,id,param_os_from_utf8(content)); +} + +int SHARED_EXPORT uCharCompare(t_uint32 p_char1,t_uint32 p_char2) { +#ifdef UNICODE + wchar_t temp1[4],temp2[4]; + temp1[utf16_encode_char(p_char1,temp1)]=0; + temp2[utf16_encode_char(p_char2,temp2)]=0; + return lstrcmpiW(temp1,temp2); +#else + wchar_t temp1[4],temp2[4]; + char ctemp1[20],ctemp2[20]; + temp1[utf16_encode_char(p_char1,temp1)]=0; + temp2[utf16_encode_char(p_char2,temp2)]=0; + WideCharToMultiByte(CP_ACP,0,temp1,-1,ctemp1,_countof(ctemp1),0,0); + WideCharToMultiByte(CP_ACP,0,temp2,-1,ctemp2,_countof(ctemp2),0,0); + return lstrcmpiA(ctemp1,ctemp2); +#endif +} + +int SHARED_EXPORT uStringCompare(const char * elem1, const char * elem2) { + for(;;) { + unsigned c1,c2; t_size l1,l2; + l1 = utf8_decode_char(elem1,c1); + l2 = utf8_decode_char(elem2,c2); + if (l1==0 && l2==0) return 0; + if (c1!=c2) { + int test = uCharCompare(c1,c2); + if (test) return test; + } + elem1 += l1; + elem2 += l2; + } +} + +int SHARED_EXPORT uStringCompare_ConvertNumbers(const char * elem1,const char * elem2) { + for(;;) { + if (pfc::char_is_numeric(*elem1) && pfc::char_is_numeric(*elem2)) { + t_size delta1 = 1, delta2 = 1; + while(pfc::char_is_numeric(elem1[delta1])) delta1++; + while(pfc::char_is_numeric(elem2[delta2])) delta2++; + int test = pfc::compare_t(pfc::atoui64_ex(elem1,delta1),pfc::atoui64_ex(elem2,delta2)); + if (test != 0) return test; + elem1 += delta1; + elem2 += delta2; + } else { + unsigned c1,c2; t_size l1,l2; + l1 = utf8_decode_char(elem1,c1); + l2 = utf8_decode_char(elem2,c2); + if (l1==0 && l2==0) return 0; + if (c1!=c2) { + int test = uCharCompare(c1,c2); + if (test) return test; + } + elem1 += l1; + elem2 += l2; + } + } +} + +HINSTANCE SHARED_EXPORT uLoadLibrary(const char * name) +{ + return LoadLibrary(param_os_from_utf8(name)); +} + +HANDLE SHARED_EXPORT uCreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState, const char * lpName) +{ + return CreateEvent(lpEventAttributes,bManualReset,bInitialState, param_os_from_utf8(lpName)); +} + +DWORD SHARED_EXPORT uGetModuleFileName(HMODULE hMod,string_base & out) +{ + try { + pfc::array_t<TCHAR> buffer; buffer.set_size(256); + for(;;) { + DWORD ret = GetModuleFileName(hMod,buffer.get_ptr(), (DWORD)buffer.get_size()); + if (ret == 0) return 0; + if (ret < buffer.get_size()) break; + buffer.set_size(buffer.get_size() * 2); + } + out = stringcvt::string_utf8_from_os(buffer.get_ptr(),buffer.get_size()); + return (DWORD) out.length(); + } catch(...) { + return 0; + } +} + +BOOL SHARED_EXPORT uSetClipboardRawData(UINT format,const void * ptr,t_size size) { + try { + HANDLE buffer = GlobalAlloc(GMEM_DDESHARE,size); + if (buffer == NULL) throw std::bad_alloc(); + try { + CGlobalLockScope lock(buffer); + PFC_ASSERT(lock.GetSize() == size); + memcpy(lock.GetPtr(),ptr,size); + } catch(...) { + GlobalFree(buffer); throw; + } + + if (SetClipboardData(format,buffer) == NULL) throw pfc::exception_bug_check(); + return TRUE; + } catch(...) { + return FALSE; + } +} +BOOL SHARED_EXPORT uSetClipboardString(const char * ptr) +{ + try { + CClipboardOpenScope scope; + if (!scope.Open(NULL)) return FALSE; + EmptyClipboard(); + stringcvt::string_os_from_utf8 temp(ptr); + return uSetClipboardRawData( + #ifdef UNICODE + CF_UNICODETEXT + #else + CF_TEXT + #endif + ,temp.get_ptr(), (temp.length() + 1) * sizeof(TCHAR)); + } catch(...) { + return FALSE; + } +} + +BOOL SHARED_EXPORT uGetClipboardString(pfc::string_base & p_out) { + try { + CClipboardOpenScope scope; + if (!scope.Open(NULL)) return FALSE; + HANDLE data = GetClipboardData( + #ifdef UNICODE + CF_UNICODETEXT + #else + CF_TEXT + #endif + ); + if (data == NULL) return FALSE; + + CGlobalLockScope lock(data); + p_out = pfc::stringcvt::string_utf8_from_os( (const TCHAR*) lock.GetPtr(), lock.GetSize() / sizeof(TCHAR) ); + return TRUE; + } catch(...) { + return FALSE; + } +} + + +BOOL SHARED_EXPORT uGetClassName(HWND wnd,string_base & out) +{ + TCHAR temp[512]; + temp[0]=0; + if (GetClassName(wnd,temp,_countof(temp))>0) + { + out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return TRUE; + } + else return FALSE; +} + +t_size SHARED_EXPORT uCharLength(const char * src) {return utf8_char_len(src);} + +BOOL SHARED_EXPORT uDragQueryFile(HDROP hDrop,UINT idx,string_base & out) +{ + UINT len = DragQueryFile(hDrop,idx,0,0); + if (len>0 && len!=(UINT)(~0)) + { + len++; + array_t<TCHAR> temp; + temp.set_size(len); + temp[0] =0 ; + if (DragQueryFile(hDrop,idx,temp.get_ptr(),len)>0) + { + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; + } + } + return FALSE; +} + +UINT SHARED_EXPORT uDragQueryFileCount(HDROP hDrop) +{ + return DragQueryFile(hDrop,-1,0,0); +} + + + +BOOL SHARED_EXPORT uGetTextExtentPoint32(HDC dc,const char * text,UINT cb,LPSIZE size) +{ + stringcvt::string_os_from_utf8 temp(text,cb); + return GetTextExtentPoint32(dc,temp,pfc::downcast_guarded<int>(temp.length()),size); +} + +BOOL SHARED_EXPORT uExtTextOut(HDC dc,int x,int y,UINT flags,const RECT * rect,const char * text,UINT cb,const int * lpdx) +{ + stringcvt::string_os_from_utf8 temp(text,cb); + return ExtTextOut(dc,x,y,flags,rect,temp,pfc::downcast_guarded<int>(_tcslen(temp)),lpdx); +} + +static UINT_PTR CALLBACK choose_color_hook(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) +{ + switch(msg) + { + case WM_INITDIALOG: + { + CHOOSECOLOR * cc = reinterpret_cast<CHOOSECOLOR*>(lp); + reinterpret_cast<modal_dialog_scope*>(cc->lCustData)->initialize(FindOwningPopup(wnd)); + } + return 0; + default: + return 0; + } +} + +BOOL SHARED_EXPORT uChooseColor(DWORD * p_color,HWND parent,DWORD * p_custom_colors) +{ + modal_dialog_scope scope; + + CHOOSECOLOR cc = {}; + cc.lStructSize = sizeof(cc); + cc.hwndOwner = parent; + cc.rgbResult = *p_color; + cc.lpCustColors = p_custom_colors; + cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT|CC_ENABLEHOOK; + cc.lpfnHook = choose_color_hook; + cc.lCustData = reinterpret_cast<LPARAM>(&scope); + BOOL rv = ChooseColor(&cc); + if (rv) + { + *p_color = cc.rgbResult; + return TRUE; + } + else return FALSE; +} + +HCURSOR SHARED_EXPORT uLoadCursor(HINSTANCE hIns,const char * name) +{ + return LoadCursor(hIns,param_os_from_utf8(name)); +} + +HICON SHARED_EXPORT uLoadIcon(HINSTANCE hIns,const char * name) +{ + return LoadIcon(hIns,param_os_from_utf8(name)); +} + +HMENU SHARED_EXPORT uLoadMenu(HINSTANCE hIns,const char * name) +{ + return LoadMenu(hIns,param_os_from_utf8(name)); +} + + + +BOOL SHARED_EXPORT uGetEnvironmentVariable(const char * name,string_base & out) +{ + stringcvt::string_os_from_utf8 name_t(name); + DWORD size = GetEnvironmentVariable(name_t,0,0); + if (size>0) + { + size++; + array_t<TCHAR> temp; + temp.set_size(size); + temp[0]=0; + if (GetEnvironmentVariable(name_t,temp.get_ptr(),size)>0) + { + out = stringcvt::string_utf8_from_os(temp.get_ptr(),size); + return TRUE; + } + } + return FALSE; +} + +HMODULE SHARED_EXPORT uGetModuleHandle(const char * name) +{ + return GetModuleHandle(param_os_from_utf8(name)); +} + +UINT SHARED_EXPORT uRegisterWindowMessage(const char * name) +{ + return RegisterWindowMessage(stringcvt::string_os_from_utf8(name)); +} + +BOOL SHARED_EXPORT uMoveFile(const char * src,const char * dst) +{ + return MoveFile(stringcvt::string_os_from_utf8(src),stringcvt::string_os_from_utf8(dst)); +} + +BOOL SHARED_EXPORT uDeleteFile(const char * fn) +{ + return DeleteFile(stringcvt::string_os_from_utf8(fn)); +} + +DWORD SHARED_EXPORT uGetFileAttributes(const char * fn) +{ + PFC_ASSERT( ! pfc::string_has_prefix_i( fn, "file://" ) ); + return GetFileAttributes(stringcvt::string_os_from_utf8(fn)); +} + +BOOL SHARED_EXPORT uRemoveDirectory(const char * fn) +{ + return RemoveDirectory(stringcvt::string_os_from_utf8(fn)); +} + +HANDLE SHARED_EXPORT uCreateFile(const char * fn,DWORD access,DWORD share,LPSECURITY_ATTRIBUTES blah,DWORD creat,DWORD flags,HANDLE tmpl) +{ + return CreateFile(stringcvt::string_os_from_utf8(fn),access,share,blah,creat,flags,tmpl); +} + +BOOL SHARED_EXPORT uCreateDirectory(const char * fn,LPSECURITY_ATTRIBUTES blah) +{ + return CreateDirectory(stringcvt::string_os_from_utf8(fn),blah); +} + +HANDLE SHARED_EXPORT uCreateMutex(LPSECURITY_ATTRIBUTES blah,BOOL bInitialOwner,const char * name) +{ + return name ? CreateMutex(blah,bInitialOwner,stringcvt::string_os_from_utf8(name)) : CreateMutex(blah,bInitialOwner,0); +} + +BOOL SHARED_EXPORT uGetFullPathName(const char * name,string_base & out) +{ + stringcvt::string_os_from_utf8 name_os(name); + unsigned len = GetFullPathName(name_os,0,0,0); + if (len==0) return FALSE; + array_t<TCHAR> temp; + temp.set_size(len+1); + TCHAR * blah; + if (GetFullPathName(name_os,len+1,temp.get_ptr(),&blah)==0) return FALSE; + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; +} + +BOOL SHARED_EXPORT uGetLongPathName(const char * name,string_base & out) +{ + TCHAR temp[4096]; + temp[0]=0; + BOOL state = GetLongPathName(stringcvt::string_os_from_utf8(name),temp,_countof(temp)); + if (state) out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return state; +} + +void SHARED_EXPORT uGetCommandLine(string_base & out) +{ + out = stringcvt::string_utf8_from_os(GetCommandLine()); +} + +BOOL SHARED_EXPORT uGetTempPath(string_base & out) +{ + TCHAR temp[MAX_PATH+1]; + temp[0]=0; + if (GetTempPath(_countof(temp),temp)) + { + out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return TRUE; + } + return FALSE; + +} +BOOL SHARED_EXPORT uGetTempFileName(const char * path_name,const char * prefix,UINT unique,string_base & out) +{ + if (path_name==0 || prefix==0) return FALSE; + TCHAR temp[MAX_PATH+1]; + temp[0]=0; + if (GetTempFileName(stringcvt::string_os_from_utf8(path_name),stringcvt::string_os_from_utf8(prefix),unique,temp)) + { + out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return TRUE; + } + return FALSE; +} + +class uFindFile_i : public uFindFile +{ + string8 fn; + WIN32_FIND_DATA fd; + HANDLE hFF; +public: + uFindFile_i() {hFF = INVALID_HANDLE_VALUE;} + bool FindFirst(const char * path) + { + hFF = FindFirstFile(stringcvt::string_os_from_utf8(path),&fd); + if (hFF==INVALID_HANDLE_VALUE) return false; + fn = stringcvt::string_utf8_from_os(fd.cFileName,_countof(fd.cFileName)); + return true; + } + virtual BOOL FindNext() + { + if (hFF==INVALID_HANDLE_VALUE) return FALSE; + BOOL rv = FindNextFile(hFF,&fd); + if (rv) fn = stringcvt::string_utf8_from_os(fd.cFileName,_countof(fd.cFileName)); + return rv; + } + + virtual const char * GetFileName() + { + return fn; + } + + virtual t_uint64 GetFileSize() + { + union + { + t_uint64 val64; + struct + { + DWORD lo,hi; + }; + } ret; + + ret.hi = fd.nFileSizeHigh; + ret.lo = fd.nFileSizeLow; + return ret.val64; + + } + virtual DWORD GetAttributes() + { + return fd.dwFileAttributes; + } + + virtual FILETIME GetCreationTime() + { + return fd.ftCreationTime; + } + virtual FILETIME GetLastAccessTime() + { + return fd.ftLastAccessTime; + } + virtual FILETIME GetLastWriteTime() + { + return fd.ftLastWriteTime; + } + virtual ~uFindFile_i() + { + if (hFF!=INVALID_HANDLE_VALUE) FindClose(hFF); + } +}; + +puFindFile SHARED_EXPORT uFindFirstFile(const char * path) +{ + pfc::ptrholder_t<uFindFile_i> ptr = new uFindFile_i; + if (!ptr->FindFirst(path)) { + ptr.release(); + return NULL; + } else { + return ptr.detach(); + } +} + +HINSTANCE SHARED_EXPORT uShellExecute(HWND wnd,const char * oper,const char * file,const char * params,const char * dir,int cmd) +{ + modal_dialog_scope modal; // IDIOCY - ShellExecute may spawn a modal dialog + if (wnd) modal.initialize(wnd); + return ShellExecute(wnd,param_os_from_utf8(oper),param_os_from_utf8(file),param_os_from_utf8(params),param_os_from_utf8(dir),cmd); +} + +HWND SHARED_EXPORT uCreateStatusWindow(LONG style,const char * text,HWND parent,UINT id) +{ + return CreateStatusWindow(style,param_os_from_utf8(text),parent,id); +} + +HWND SHARED_EXPORT uCreateWindowEx(DWORD dwExStyle,const char * lpClassName,const char * lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) +{ + return CreateWindowEx(dwExStyle,param_os_from_utf8(lpClassName),param_os_from_utf8(lpWindowName),dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); +} + +HANDLE SHARED_EXPORT uLoadImage(HINSTANCE hIns,const char * name,UINT type,int x,int y,UINT flags) +{ + return LoadImage(hIns,param_os_from_utf8(name),type,x,y,flags); +} + +BOOL SHARED_EXPORT uGetSystemDirectory(string_base & out) +{ + UINT len = GetSystemDirectory(0,0); + if (len==0) len = MAX_PATH; + len++; + array_t<TCHAR> temp; + temp.set_size(len); + if (GetSystemDirectory(temp.get_ptr(),len)==0) return FALSE; + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; +} + +BOOL SHARED_EXPORT uGetWindowsDirectory(string_base & out) +{ + UINT len = GetWindowsDirectory(0,0); + if (len==0) len = MAX_PATH; + len++; + array_t<TCHAR> temp; + temp.set_size(len); + if (GetWindowsDirectory(temp.get_ptr(),len)==0) return FALSE; + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; +} + +BOOL SHARED_EXPORT uSetCurrentDirectory(const char * path) +{ + return SetCurrentDirectory(stringcvt::string_os_from_utf8(path)); +} + +BOOL SHARED_EXPORT uGetCurrentDirectory(string_base & out) +{ + UINT len = GetCurrentDirectory(0,0); + if (len==0) len = MAX_PATH; + len++; + array_t<TCHAR> temp; + temp.set_size(len); + if (GetCurrentDirectory(len,temp.get_ptr())==0) return FALSE; + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; +} + +BOOL SHARED_EXPORT uExpandEnvironmentStrings(const char * src,string_base & out) +{ + stringcvt::string_os_from_utf8 src_os(src); + UINT len = ExpandEnvironmentStrings(src_os,0,0); + if (len==0) len = 256; + len++; + array_t<TCHAR> temp; + temp.set_size(len); + if (ExpandEnvironmentStrings(src_os,temp.get_ptr(),len)==0) return FALSE; + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; +} + +BOOL SHARED_EXPORT uGetUserName(string_base & out) +{ + TCHAR temp[UNLEN+1]; + DWORD len = _countof(temp); + if (GetUserName(temp,&len)) + { + out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return TRUE; + } + else return FALSE; +} + +BOOL SHARED_EXPORT uGetShortPathName(const char * src,string_base & out) +{ + stringcvt::string_os_from_utf8 src_os(src); + UINT len = GetShortPathName(src_os,0,0); + if (len==0) len = MAX_PATH; + len++; + array_t<TCHAR> temp; temp.set_size(len); + if (GetShortPathName(src_os,temp.get_ptr(),len)) + { + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; + } + else return FALSE; +} + + +#ifdef UNICODE +#define DDE_CODEPAGE CP_WINUNICODE +#else +#define DDE_CODEPAGE CP_WINANSI +#endif + + +HSZ SHARED_EXPORT uDdeCreateStringHandle(DWORD ins,const char * src) +{ + return DdeCreateStringHandle(ins,stringcvt::string_os_from_utf8(src),DDE_CODEPAGE); +} + +BOOL SHARED_EXPORT uDdeQueryString(DWORD ins,HSZ hsz,string_base & out) +{ + array_t<TCHAR> temp; + UINT len = DdeQueryString(ins,hsz,0,0,DDE_CODEPAGE); + if (len==0) len = MAX_PATH; + len++; + temp.set_size(len); + if (DdeQueryString(ins,hsz,temp.get_ptr(),len,DDE_CODEPAGE)) + { + out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + return TRUE; + } + else return FALSE; +} + +UINT SHARED_EXPORT uDdeInitialize(LPDWORD pidInst,PFNCALLBACK pfnCallback,DWORD afCmd,DWORD ulRes) +{ + return DdeInitialize(pidInst,pfnCallback,afCmd,ulRes); +} + +BOOL SHARED_EXPORT uDdeAccessData_Text(HDDEDATA data,string_base & out) +{ + const TCHAR * ptr = (const TCHAR*) DdeAccessData(data,0); + if (ptr) + { + out = stringcvt::string_utf8_from_os(ptr); + return TRUE; + } + else return FALSE; +} + +uSortString_t SHARED_EXPORT uSortStringCreate(const char * src) { + t_size lenEst = pfc::stringcvt::estimate_utf8_to_wide(src,SIZE_MAX); + TCHAR * ret = pfc::__raw_malloc_t<TCHAR>(lenEst); + pfc::stringcvt::convert_utf8_to_wide(ret,lenEst,src,SIZE_MAX); + return reinterpret_cast<uSortString_t>( ret ); +} + +int SHARED_EXPORT uSortStringCompareEx(uSortString_t string1, uSortString_t string2,uint32_t flags) { + return CompareString(LOCALE_USER_DEFAULT,flags,reinterpret_cast<const TCHAR*>(string1),-1,reinterpret_cast<const TCHAR*>(string2),-1); +} + +int SHARED_EXPORT uSortStringCompare(uSortString_t string1, uSortString_t string2) { + return lstrcmpi(reinterpret_cast<const TCHAR*>(string1),reinterpret_cast<const TCHAR*>(string2)); +} + +void SHARED_EXPORT uSortStringFree(uSortString_t string) { + pfc::__raw_free_t(reinterpret_cast<TCHAR*>(string)); +} + +HTREEITEM SHARED_EXPORT uTreeView_InsertItem(HWND wnd,const uTVINSERTSTRUCT * param) +{ + stringcvt::string_os_from_utf8 temp; + temp.convert(param->item.pszText); + + + TVINSERTSTRUCT l_param = {}; + l_param.hParent = param->hParent; + l_param.hInsertAfter = param->hInsertAfter; + l_param.item.mask = param->item.mask; + l_param.item.hItem = param->item.hItem; + l_param.item.state = param->item.state; + l_param.item.stateMask = param->item.stateMask; + l_param.item.pszText = const_cast<TCHAR*>(temp.get_ptr()); + l_param.item.cchTextMax = 0; + l_param.item.iImage = param->item.iImage; + l_param.item.iSelectedImage = param->item.iImage; + l_param.item.cChildren = param->item.cChildren; + l_param.item.lParam = param->item.lParam; + if (param->item.mask & TVIF_INTEGRAL) + { + l_param.itemex.iIntegral = param->itemex.iIntegral; + } + + return (HTREEITEM) uSendMessage(wnd,TVM_INSERTITEM,0,(LPARAM)&l_param); +} + +UINT SHARED_EXPORT uGetFontHeight(HFONT font) +{ + UINT ret; + HDC dc = CreateCompatibleDC(0); + SelectObject(dc,font); + ret = uGetTextHeight(dc); + DeleteDC(dc); + return ret; +} + + +HIMAGELIST SHARED_EXPORT uImageList_LoadImage(HINSTANCE hi, const char * lpbmp, int cx, int cGrow, COLORREF crMask, UINT uType, UINT uFlags) +{ + return ImageList_LoadImage(hi,param_os_from_utf8(lpbmp),cx,cGrow,crMask,uType,uFlags); +} + +int SHARED_EXPORT uTabCtrl_InsertItem(HWND wnd,t_size idx,const uTCITEM * item) +{ + param_os_from_utf8 text((item->mask & TCIF_TEXT) ? item->pszText : 0); + TCITEM l_item; + assert(sizeof(l_item)==sizeof(*item));//meh lazy + memcpy(&l_item,item,sizeof(l_item)); + l_item.pszText = const_cast<TCHAR*>(text.get_ptr()); + l_item.cchTextMax = 0; + return TabCtrl_InsertItem(wnd,idx,&l_item); +} + +int SHARED_EXPORT uTabCtrl_SetItem(HWND wnd,t_size idx,const uTCITEM * item) +{ + param_os_from_utf8 text((item->mask & TCIF_TEXT) ? item->pszText : 0); + TCITEM l_item; + PFC_STATIC_ASSERT(sizeof(l_item)==sizeof(*item));//meh lazy + memcpy(&l_item,item,sizeof(l_item)); + l_item.pszText = const_cast<TCHAR*>(text.get_ptr()); + l_item.cchTextMax = 0; + return TabCtrl_SetItem(wnd,idx,&l_item); +} + +int SHARED_EXPORT uGetKeyNameText(LONG lparam,string_base & out) +{ + TCHAR temp[256]; + temp[0]=0; + if (!GetKeyNameText(lparam,temp,_countof(temp))) return 0; + out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return 1; +} + +HANDLE SHARED_EXPORT uCreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,const char * lpName) +{ + return CreateFileMapping(hFile,lpFileMappingAttributes,flProtect,dwMaximumSizeHigh,dwMaximumSizeLow,param_os_from_utf8(lpName)); +} + +BOOL SHARED_EXPORT uListBox_GetText(HWND listbox,UINT index,string_base & out) +{ + t_size len = uSendMessage(listbox,LB_GETTEXTLEN,index,0); + if (len==LB_ERR || len>16*1024*1024) return FALSE; + if (len==0) {out.reset();return TRUE;} + + array_t<TCHAR> temp; temp.set_size(len+1); + pfc::memset_t(temp,(TCHAR)0); + len = uSendMessage(listbox,LB_GETTEXT,index,(LPARAM)temp.get_ptr()); + if (len==LB_ERR) return false; + out = stringcvt::string_utf8_from_os(temp.get_ptr()); + return TRUE; +} +/* +void SHARED_EXPORT uPrintf(string_base & out,const char * fmt,...) +{ + va_list list; + va_start(list,fmt); + uPrintfV(out,fmt,list); + va_end(list); +} +*/ +void SHARED_EXPORT uPrintfV(string_base & out,const char * fmt,va_list arglist) +{ + pfc::string_printf_here_va(out, fmt, arglist); +} + +int SHARED_EXPORT uCompareString(DWORD flags,const char * str1,size_t len1,const char * str2,size_t len2) +{ + return CompareString(LOCALE_USER_DEFAULT,flags,stringcvt::string_os_from_utf8(str1,len1),-1,stringcvt::string_os_from_utf8(str2,len2),-1); +} + +class uResource_i : public uResource +{ + unsigned size; + const void * ptr; +public: + inline uResource_i(const void * p_ptr,unsigned p_size) : ptr(p_ptr), size(p_size) + { + } + virtual const void * GetPointer() + { + return ptr; + } + virtual unsigned GetSize() + { + return size; + } + virtual ~uResource_i() + { + } +}; + +puResource SHARED_EXPORT uLoadResource(HMODULE hMod,const char * name,const char * type,WORD wLang) +{ + HRSRC res = uFindResource(hMod,name,type,wLang); + if (res==0) return 0; + HGLOBAL hglob = LoadResource(hMod,res); + if (hglob) + { + void * ptr = LockResource(hglob); + if (ptr) + { + return new uResource_i(ptr,SizeofResource(hMod,res)); + } + else return 0; + } + else return 0; +} + +puResource SHARED_EXPORT LoadResourceEx(HMODULE hMod,const TCHAR * name,const TCHAR * type,WORD wLang) +{ + HRSRC res = wLang ? FindResourceEx(hMod,type,name,wLang) : FindResource(hMod,name,type); + if (res==0) return 0; + HGLOBAL hglob = LoadResource(hMod,res); + if (hglob) + { + void * ptr = LockResource(hglob); + if (ptr) + { + return new uResource_i(ptr,SizeofResource(hMod,res)); + } + else return 0; + } + else return 0; +} + +HRSRC SHARED_EXPORT uFindResource(HMODULE hMod,const char * name,const char * type,WORD wLang) +{ + return wLang ? FindResourceEx(hMod,param_os_from_utf8(type),param_os_from_utf8(name),wLang) : FindResource(hMod,param_os_from_utf8(name),param_os_from_utf8(type)); +} + +BOOL SHARED_EXPORT uLoadString(HINSTANCE ins,UINT id,string_base & out) +{ + BOOL rv = FALSE; + uResource * res = uLoadResource(ins,uMAKEINTRESOURCE(id),(const char*)(RT_STRING)); + if (res) + { + unsigned size = res->GetSize(); + const WCHAR * ptr = (const WCHAR*)res->GetPointer(); + if (size>=4) + { + unsigned len = *(const WORD*)(ptr+1); + if (len * 2 + 4 <= size) + { + out = stringcvt::string_utf8_from_wide(ptr+2,len); + } + } + + delete res; + rv = TRUE; + } + return rv; +} + +BOOL SHARED_EXPORT uGetMenuString(HMENU menu,UINT id,string_base & out,UINT flag) +{ + unsigned len = GetMenuString(menu,id,0,0,flag); + if (len==0) + { + out.reset(); + return FALSE; + } + array_t<TCHAR> temp; + temp.set_size(len+1); + if (GetMenuString(menu,id,temp.get_ptr(),len+1,flag)==0) { + out.reset(); + return FALSE; + } + out = stringcvt::string_utf8_from_os(temp.get_ptr()); + return TRUE; +} + +BOOL SHARED_EXPORT uModifyMenu(HMENU menu,UINT id,UINT flags,UINT newitem,const char * data) +{ + return ModifyMenu(menu,id,flags,newitem,param_os_from_utf8(data)); +} + +UINT SHARED_EXPORT uGetMenuItemType(HMENU menu,UINT position) +{ + MENUITEMINFO info = {}; + info.cbSize = sizeof(info); + info.fMask = MIIM_TYPE; + if (!GetMenuItemInfo(menu,position,TRUE,&info)) + return 0; + return info.fType; +} + +static inline bool i_is_path_separator(unsigned c) +{ + return c=='\\' || c=='/' || c=='|' || c==':'; +} + +int SHARED_EXPORT uSortPathCompare(HANDLE string1,HANDLE string2) +{ + const TCHAR * s1 = reinterpret_cast<const TCHAR*>(string1); + const TCHAR * s2 = reinterpret_cast<const TCHAR*>(string2); + const TCHAR * p1, * p2; + + while (*s1 || *s2) + { + if (*s1 == *s2) + { + s1++; + s2++; + continue; + } + + p1 = s1; while (*p1 && !i_is_path_separator(*p1)) p1++; + p2 = s2; while (*p2 && !i_is_path_separator(*p2)) p2++; + + if ((!*p1 && !*p2) || (*p1 && *p2)) + { + int test = CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_IGNOREKANATYPE | NORM_IGNOREWIDTH, s1, pfc::downcast_guarded<int>(p1 - s1), s2, pfc::downcast_guarded<int>(p2 - s2)); + if (test && test != 2) return test - 2; + if (!*p1) return 0; + } + else + { + if (*p1) return -1; + else return 1; + } + + s1 = p1 + 1; + s2 = p2 + 1; + } + + return 0; +} + +UINT SHARED_EXPORT uRegisterClipboardFormat(const char * name) +{ + return RegisterClipboardFormat(stringcvt::string_os_from_utf8(name)); +} + +BOOL SHARED_EXPORT uGetClipboardFormatName(UINT format,string_base & out) +{ + TCHAR temp[1024]; + if (!GetClipboardFormatName(format,temp,_countof(temp))) return FALSE; + out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return TRUE; +} + +}//extern "C" + +BOOL SHARED_EXPORT uSearchPath(const char * path, const char * filename, const char * extension, string_base & p_out) +{ + enum {temp_size = 1024}; + param_os_from_utf8 path_os(path), filename_os(filename), extension_os(extension); + array_t<TCHAR> temp; temp.set_size(temp_size); + LPTSTR dummy; + unsigned len; + + len = SearchPath(path_os,filename_os,extension_os,temp_size,temp.get_ptr(),&dummy); + if (len == 0) return FALSE; + if (len >= temp_size) + { + unsigned len2; + temp.set_size(len + 1); + len2 = SearchPath(path_os,filename_os,extension_os,len+1,temp.get_ptr(),&dummy); + if (len2 == 0 || len2 > len) return FALSE; + len = len2; + } + + p_out = stringcvt::string_utf8_from_os(temp.get_ptr(),len); + + return TRUE; + +} + +static bool is_ascii_alpha(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +static char ascii_upper(char c) +{ + if (c >= 'a' && c <= 'z') c += 'A' - 'a'; + return c; +} + +static BOOL uFixPathCaps_Internal(const char * path,string_base & p_out, bool bQuick) { + pfc::string8_fastalloc temp, prependbuffer; + if (path[0] == '\\' && path[1] == '\\') + { + unsigned index = 2; + while(path[index] != '\\') + { + if (path[index] == 0) return FALSE; + index++; + } + index++; + if (path[index] == '\\' || path[index] == 0) return FALSE; + while(path[index] != '\\') + { + if (path[index] == 0) { + // \\host\share + uStringLower(p_out,path); + return TRUE; + } + index++; + } + index++; + if (path[index] == '\\') return FALSE; + uAddStringLower(temp,path,index); + path += index; + } + else if (is_ascii_alpha(path[0]) && path[1] == ':' && path[2] == '\\') + { + temp.add_char(ascii_upper(path[0])); + temp.add_string(":\\"); + path += 3; + } + else return FALSE; + + for(;;) + { + t_size truncat = temp.length(); + t_size delta = 0; + while(path[delta]!=0 && path[delta]!='\\') delta++; + if (delta == 0) break; + temp.add_string_nc(path,delta); + + bool found = false; + if (!bQuick) { +#ifdef UNICODE + pfc::winPrefixPath( prependbuffer, temp ); + pfc::ptrholder_t<uFindFile> ff = uFindFirstFile(prependbuffer); +#else + pfc::ptrholder_t<uFindFile> ff = uFindFirstFile(temp); +#endif + if (ff.is_valid()) { + do { + const char * fn = ff->GetFileName(); + if (!stricmp_utf8_ex(path,delta,fn,strlen(fn))) + { + found = true; + temp.truncate(truncat); + temp.add_string(fn); + break; + } + } while(ff->FindNext()); + } + } + if (!found) + { + temp.add_string(path + delta); + break; + } + path += delta; + if (*path == 0) break; + path ++; + temp.add_char('\\'); + } + + + p_out = temp; + + return TRUE; +} +/*BOOL SHARED_EXPORT uFixPathCapsQuick(const char * path,string_base & p_out) { + return uFixPathCaps_Internal(path, p_out, true); +}*/ +BOOL SHARED_EXPORT uFixPathCaps(const char * path,string_base & p_out) { + return uFixPathCaps_Internal(path, p_out, false); +} + +LPARAM SHARED_EXPORT uTreeView_GetUserData(HWND p_tree,HTREEITEM p_item) +{ + TVITEM item = {}; + item.mask = TVIF_PARAM; + item.hItem = p_item; + if (uSendMessage(p_tree,TVM_GETITEM,0,(LPARAM)&item)) + return item.lParam; + return 0; +} + +bool SHARED_EXPORT uTreeView_GetText(HWND p_tree,HTREEITEM p_item,string_base & p_out) +{ + TCHAR temp[1024];//changeme ? + TVITEM item = {}; + item.mask = TVIF_TEXT; + item.hItem = p_item; + item.pszText = temp; + item.cchTextMax = _countof(temp); + if (uSendMessage(p_tree,TVM_GETITEM,0,(LPARAM)&item)) + { + p_out = stringcvt::string_utf8_from_os(temp,_countof(temp)); + return true; + } + else return false; +} + +BOOL SHARED_EXPORT uSetWindowText(HWND wnd,const char * p_text) +{ + PFC_ASSERT( wnd != NULL ); + return SetWindowText(wnd,stringcvt::string_os_from_utf8(p_text)); +} + +BOOL SHARED_EXPORT uSetDlgItemText(HWND wnd,UINT id,const char * p_text) +{ + PFC_ASSERT( wnd != NULL ); + return SetDlgItemText(wnd, id, stringcvt::string_os_from_utf8(p_text)); +} + +BOOL SHARED_EXPORT uFileExists(const char * fn) +{ + DWORD attrib = uGetFileAttributes(fn); + if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY)) return FALSE; + return TRUE; +} + +BOOL SHARED_EXPORT uFormatSystemErrorMessage(string_base & p_out,DWORD p_code) { + return pfc::winFormatSystemErrorMessage(p_out, p_code); +} + +HMODULE SHARED_EXPORT LoadSystemLibrary(const TCHAR * name) { + pfc::array_t<TCHAR> buffer; buffer.set_size( MAX_PATH + _tcslen(name) + 2 ); + TCHAR * bufptr = buffer.get_ptr(); + if (GetSystemDirectory(bufptr, MAX_PATH) == 0) return NULL; + bufptr[MAX_PATH] = 0; + + size_t idx = _tcslen(bufptr); + if (idx > 0 && bufptr[idx-1] != '\\') bufptr[idx++] = '\\'; + + pfc::strcpy_t(bufptr+idx, name); + + return LoadLibrary(bufptr); +} \ No newline at end of file
