comparison 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
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 #include "shared.h"
2
3
4 #include <lmcons.h>
5
6 #ifndef BIF_NEWDIALOGSTYLE
7 #define BIF_NEWDIALOGSTYLE 0x0040
8 #endif
9
10 using namespace pfc;
11
12 class param_os_from_utf8
13 {
14 bool m_is_null;
15 WORD m_low_word;
16 stringcvt::string_os_from_utf8 m_cvt;
17 public:
18 param_os_from_utf8(const char * p) :
19 m_is_null(p==NULL),
20 m_low_word( ((t_size)p & ~0xFFFF) == 0 ? (WORD)((t_size)p & 0xFFFF) : 0),
21 m_cvt( p != NULL && ((t_size)p & ~0xFFFF) != 0 ? p : "")
22 {}
23 operator const TCHAR *()
24 {
25 return get_ptr();
26 }
27 const TCHAR * get_ptr()
28 {
29 return m_low_word ? (const TCHAR*)(t_size)m_low_word : m_is_null ? 0 : m_cvt.get_ptr();
30 }
31
32 };
33
34
35
36 extern "C" {
37
38 LRESULT SHARED_EXPORT uSendMessageText(HWND wnd,UINT msg,WPARAM wp,const char * p_text)
39 {
40 if (p_text == NULL)
41 return SendMessage(wnd,msg,wp,0);
42 else {
43 stringcvt::string_os_from_utf8 temp;
44 temp.convert(p_text);
45 return SendMessage(wnd,msg,wp,(LPARAM)temp.get_ptr());
46 }
47 }
48
49 LRESULT SHARED_EXPORT uSendDlgItemMessageText(HWND wnd,UINT id,UINT msg,WPARAM wp,const char * text)
50 {
51 return uSendMessageText(uGetDlgItem(wnd,id),msg,wp,text);//SendDlgItemMessage(wnd,id,msg,wp,(long)(const TCHAR*)string_os_from_utf8(text));
52 }
53
54 BOOL SHARED_EXPORT uGetWindowText(HWND wnd,string_base & out)
55 {
56 PFC_ASSERT( wnd != NULL );
57 int len = GetWindowTextLength(wnd);
58 if (len>0)
59 {
60 len++;
61 pfc::array_t<TCHAR> temp;
62 temp.set_size(len);
63 temp[0]=0;
64 if (GetWindowText(wnd,temp.get_ptr(),len)>0)
65 {
66 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
67 return TRUE;
68 }
69 else return FALSE;
70 }
71 else
72 {
73 out.reset();
74 return TRUE;
75 }
76 }
77
78 BOOL SHARED_EXPORT uSetWindowTextEx(HWND wnd,const char * p_text,size_t p_text_length)
79 {
80 return SetWindowText(wnd,stringcvt::string_os_from_utf8(p_text, p_text_length));
81 }
82
83
84 BOOL SHARED_EXPORT uGetDlgItemText(HWND wnd,UINT id,string_base & out)
85 {
86 return uGetWindowText(GetDlgItem(wnd,id),out);
87 }
88
89 BOOL SHARED_EXPORT uSetDlgItemTextEx(HWND wnd,UINT id,const char * p_text,size_t p_text_length)
90 {
91 return SetDlgItemText(wnd,id,stringcvt::string_os_from_utf8(p_text,p_text_length));
92 }
93
94 int SHARED_EXPORT uMessageBox(HWND wnd,const char * text,const char * caption,UINT type)
95 {
96 modal_dialog_scope scope(wnd);
97 return MessageBox(wnd,param_os_from_utf8(text),param_os_from_utf8(caption),type);
98 }
99
100 void SHARED_EXPORT uOutputDebugString(const char * msg) {OutputDebugString(stringcvt::string_os_from_utf8(msg));}
101
102 BOOL SHARED_EXPORT uAppendMenu(HMENU menu,UINT flags,UINT_PTR id,const char * content)
103 {
104 return AppendMenu(menu,flags,id,param_os_from_utf8(content));
105 }
106
107 BOOL SHARED_EXPORT uInsertMenu(HMENU menu,UINT position,UINT flags,UINT_PTR id,const char * content)
108 {
109 return InsertMenu(menu,position,flags,id,param_os_from_utf8(content));
110 }
111
112 int SHARED_EXPORT uCharCompare(t_uint32 p_char1,t_uint32 p_char2) {
113 #ifdef UNICODE
114 wchar_t temp1[4],temp2[4];
115 temp1[utf16_encode_char(p_char1,temp1)]=0;
116 temp2[utf16_encode_char(p_char2,temp2)]=0;
117 return lstrcmpiW(temp1,temp2);
118 #else
119 wchar_t temp1[4],temp2[4];
120 char ctemp1[20],ctemp2[20];
121 temp1[utf16_encode_char(p_char1,temp1)]=0;
122 temp2[utf16_encode_char(p_char2,temp2)]=0;
123 WideCharToMultiByte(CP_ACP,0,temp1,-1,ctemp1,_countof(ctemp1),0,0);
124 WideCharToMultiByte(CP_ACP,0,temp2,-1,ctemp2,_countof(ctemp2),0,0);
125 return lstrcmpiA(ctemp1,ctemp2);
126 #endif
127 }
128
129 int SHARED_EXPORT uStringCompare(const char * elem1, const char * elem2) {
130 for(;;) {
131 unsigned c1,c2; t_size l1,l2;
132 l1 = utf8_decode_char(elem1,c1);
133 l2 = utf8_decode_char(elem2,c2);
134 if (l1==0 && l2==0) return 0;
135 if (c1!=c2) {
136 int test = uCharCompare(c1,c2);
137 if (test) return test;
138 }
139 elem1 += l1;
140 elem2 += l2;
141 }
142 }
143
144 int SHARED_EXPORT uStringCompare_ConvertNumbers(const char * elem1,const char * elem2) {
145 for(;;) {
146 if (pfc::char_is_numeric(*elem1) && pfc::char_is_numeric(*elem2)) {
147 t_size delta1 = 1, delta2 = 1;
148 while(pfc::char_is_numeric(elem1[delta1])) delta1++;
149 while(pfc::char_is_numeric(elem2[delta2])) delta2++;
150 int test = pfc::compare_t(pfc::atoui64_ex(elem1,delta1),pfc::atoui64_ex(elem2,delta2));
151 if (test != 0) return test;
152 elem1 += delta1;
153 elem2 += delta2;
154 } else {
155 unsigned c1,c2; t_size l1,l2;
156 l1 = utf8_decode_char(elem1,c1);
157 l2 = utf8_decode_char(elem2,c2);
158 if (l1==0 && l2==0) return 0;
159 if (c1!=c2) {
160 int test = uCharCompare(c1,c2);
161 if (test) return test;
162 }
163 elem1 += l1;
164 elem2 += l2;
165 }
166 }
167 }
168
169 HINSTANCE SHARED_EXPORT uLoadLibrary(const char * name)
170 {
171 return LoadLibrary(param_os_from_utf8(name));
172 }
173
174 HANDLE SHARED_EXPORT uCreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState, const char * lpName)
175 {
176 return CreateEvent(lpEventAttributes,bManualReset,bInitialState, param_os_from_utf8(lpName));
177 }
178
179 DWORD SHARED_EXPORT uGetModuleFileName(HMODULE hMod,string_base & out)
180 {
181 try {
182 pfc::array_t<TCHAR> buffer; buffer.set_size(256);
183 for(;;) {
184 DWORD ret = GetModuleFileName(hMod,buffer.get_ptr(), (DWORD)buffer.get_size());
185 if (ret == 0) return 0;
186 if (ret < buffer.get_size()) break;
187 buffer.set_size(buffer.get_size() * 2);
188 }
189 out = stringcvt::string_utf8_from_os(buffer.get_ptr(),buffer.get_size());
190 return (DWORD) out.length();
191 } catch(...) {
192 return 0;
193 }
194 }
195
196 BOOL SHARED_EXPORT uSetClipboardRawData(UINT format,const void * ptr,t_size size) {
197 try {
198 HANDLE buffer = GlobalAlloc(GMEM_DDESHARE,size);
199 if (buffer == NULL) throw std::bad_alloc();
200 try {
201 CGlobalLockScope lock(buffer);
202 PFC_ASSERT(lock.GetSize() == size);
203 memcpy(lock.GetPtr(),ptr,size);
204 } catch(...) {
205 GlobalFree(buffer); throw;
206 }
207
208 if (SetClipboardData(format,buffer) == NULL) throw pfc::exception_bug_check();
209 return TRUE;
210 } catch(...) {
211 return FALSE;
212 }
213 }
214 BOOL SHARED_EXPORT uSetClipboardString(const char * ptr)
215 {
216 try {
217 CClipboardOpenScope scope;
218 if (!scope.Open(NULL)) return FALSE;
219 EmptyClipboard();
220 stringcvt::string_os_from_utf8 temp(ptr);
221 return uSetClipboardRawData(
222 #ifdef UNICODE
223 CF_UNICODETEXT
224 #else
225 CF_TEXT
226 #endif
227 ,temp.get_ptr(), (temp.length() + 1) * sizeof(TCHAR));
228 } catch(...) {
229 return FALSE;
230 }
231 }
232
233 BOOL SHARED_EXPORT uGetClipboardString(pfc::string_base & p_out) {
234 try {
235 CClipboardOpenScope scope;
236 if (!scope.Open(NULL)) return FALSE;
237 HANDLE data = GetClipboardData(
238 #ifdef UNICODE
239 CF_UNICODETEXT
240 #else
241 CF_TEXT
242 #endif
243 );
244 if (data == NULL) return FALSE;
245
246 CGlobalLockScope lock(data);
247 p_out = pfc::stringcvt::string_utf8_from_os( (const TCHAR*) lock.GetPtr(), lock.GetSize() / sizeof(TCHAR) );
248 return TRUE;
249 } catch(...) {
250 return FALSE;
251 }
252 }
253
254
255 BOOL SHARED_EXPORT uGetClassName(HWND wnd,string_base & out)
256 {
257 TCHAR temp[512];
258 temp[0]=0;
259 if (GetClassName(wnd,temp,_countof(temp))>0)
260 {
261 out = stringcvt::string_utf8_from_os(temp,_countof(temp));
262 return TRUE;
263 }
264 else return FALSE;
265 }
266
267 t_size SHARED_EXPORT uCharLength(const char * src) {return utf8_char_len(src);}
268
269 BOOL SHARED_EXPORT uDragQueryFile(HDROP hDrop,UINT idx,string_base & out)
270 {
271 UINT len = DragQueryFile(hDrop,idx,0,0);
272 if (len>0 && len!=(UINT)(~0))
273 {
274 len++;
275 array_t<TCHAR> temp;
276 temp.set_size(len);
277 temp[0] =0 ;
278 if (DragQueryFile(hDrop,idx,temp.get_ptr(),len)>0)
279 {
280 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
281 return TRUE;
282 }
283 }
284 return FALSE;
285 }
286
287 UINT SHARED_EXPORT uDragQueryFileCount(HDROP hDrop)
288 {
289 return DragQueryFile(hDrop,-1,0,0);
290 }
291
292
293
294 BOOL SHARED_EXPORT uGetTextExtentPoint32(HDC dc,const char * text,UINT cb,LPSIZE size)
295 {
296 stringcvt::string_os_from_utf8 temp(text,cb);
297 return GetTextExtentPoint32(dc,temp,pfc::downcast_guarded<int>(temp.length()),size);
298 }
299
300 BOOL SHARED_EXPORT uExtTextOut(HDC dc,int x,int y,UINT flags,const RECT * rect,const char * text,UINT cb,const int * lpdx)
301 {
302 stringcvt::string_os_from_utf8 temp(text,cb);
303 return ExtTextOut(dc,x,y,flags,rect,temp,pfc::downcast_guarded<int>(_tcslen(temp)),lpdx);
304 }
305
306 static UINT_PTR CALLBACK choose_color_hook(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
307 {
308 switch(msg)
309 {
310 case WM_INITDIALOG:
311 {
312 CHOOSECOLOR * cc = reinterpret_cast<CHOOSECOLOR*>(lp);
313 reinterpret_cast<modal_dialog_scope*>(cc->lCustData)->initialize(FindOwningPopup(wnd));
314 }
315 return 0;
316 default:
317 return 0;
318 }
319 }
320
321 BOOL SHARED_EXPORT uChooseColor(DWORD * p_color,HWND parent,DWORD * p_custom_colors)
322 {
323 modal_dialog_scope scope;
324
325 CHOOSECOLOR cc = {};
326 cc.lStructSize = sizeof(cc);
327 cc.hwndOwner = parent;
328 cc.rgbResult = *p_color;
329 cc.lpCustColors = p_custom_colors;
330 cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT|CC_ENABLEHOOK;
331 cc.lpfnHook = choose_color_hook;
332 cc.lCustData = reinterpret_cast<LPARAM>(&scope);
333 BOOL rv = ChooseColor(&cc);
334 if (rv)
335 {
336 *p_color = cc.rgbResult;
337 return TRUE;
338 }
339 else return FALSE;
340 }
341
342 HCURSOR SHARED_EXPORT uLoadCursor(HINSTANCE hIns,const char * name)
343 {
344 return LoadCursor(hIns,param_os_from_utf8(name));
345 }
346
347 HICON SHARED_EXPORT uLoadIcon(HINSTANCE hIns,const char * name)
348 {
349 return LoadIcon(hIns,param_os_from_utf8(name));
350 }
351
352 HMENU SHARED_EXPORT uLoadMenu(HINSTANCE hIns,const char * name)
353 {
354 return LoadMenu(hIns,param_os_from_utf8(name));
355 }
356
357
358
359 BOOL SHARED_EXPORT uGetEnvironmentVariable(const char * name,string_base & out)
360 {
361 stringcvt::string_os_from_utf8 name_t(name);
362 DWORD size = GetEnvironmentVariable(name_t,0,0);
363 if (size>0)
364 {
365 size++;
366 array_t<TCHAR> temp;
367 temp.set_size(size);
368 temp[0]=0;
369 if (GetEnvironmentVariable(name_t,temp.get_ptr(),size)>0)
370 {
371 out = stringcvt::string_utf8_from_os(temp.get_ptr(),size);
372 return TRUE;
373 }
374 }
375 return FALSE;
376 }
377
378 HMODULE SHARED_EXPORT uGetModuleHandle(const char * name)
379 {
380 return GetModuleHandle(param_os_from_utf8(name));
381 }
382
383 UINT SHARED_EXPORT uRegisterWindowMessage(const char * name)
384 {
385 return RegisterWindowMessage(stringcvt::string_os_from_utf8(name));
386 }
387
388 BOOL SHARED_EXPORT uMoveFile(const char * src,const char * dst)
389 {
390 return MoveFile(stringcvt::string_os_from_utf8(src),stringcvt::string_os_from_utf8(dst));
391 }
392
393 BOOL SHARED_EXPORT uDeleteFile(const char * fn)
394 {
395 return DeleteFile(stringcvt::string_os_from_utf8(fn));
396 }
397
398 DWORD SHARED_EXPORT uGetFileAttributes(const char * fn)
399 {
400 PFC_ASSERT( ! pfc::string_has_prefix_i( fn, "file://" ) );
401 return GetFileAttributes(stringcvt::string_os_from_utf8(fn));
402 }
403
404 BOOL SHARED_EXPORT uRemoveDirectory(const char * fn)
405 {
406 return RemoveDirectory(stringcvt::string_os_from_utf8(fn));
407 }
408
409 HANDLE SHARED_EXPORT uCreateFile(const char * fn,DWORD access,DWORD share,LPSECURITY_ATTRIBUTES blah,DWORD creat,DWORD flags,HANDLE tmpl)
410 {
411 return CreateFile(stringcvt::string_os_from_utf8(fn),access,share,blah,creat,flags,tmpl);
412 }
413
414 BOOL SHARED_EXPORT uCreateDirectory(const char * fn,LPSECURITY_ATTRIBUTES blah)
415 {
416 return CreateDirectory(stringcvt::string_os_from_utf8(fn),blah);
417 }
418
419 HANDLE SHARED_EXPORT uCreateMutex(LPSECURITY_ATTRIBUTES blah,BOOL bInitialOwner,const char * name)
420 {
421 return name ? CreateMutex(blah,bInitialOwner,stringcvt::string_os_from_utf8(name)) : CreateMutex(blah,bInitialOwner,0);
422 }
423
424 BOOL SHARED_EXPORT uGetFullPathName(const char * name,string_base & out)
425 {
426 stringcvt::string_os_from_utf8 name_os(name);
427 unsigned len = GetFullPathName(name_os,0,0,0);
428 if (len==0) return FALSE;
429 array_t<TCHAR> temp;
430 temp.set_size(len+1);
431 TCHAR * blah;
432 if (GetFullPathName(name_os,len+1,temp.get_ptr(),&blah)==0) return FALSE;
433 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
434 return TRUE;
435 }
436
437 BOOL SHARED_EXPORT uGetLongPathName(const char * name,string_base & out)
438 {
439 TCHAR temp[4096];
440 temp[0]=0;
441 BOOL state = GetLongPathName(stringcvt::string_os_from_utf8(name),temp,_countof(temp));
442 if (state) out = stringcvt::string_utf8_from_os(temp,_countof(temp));
443 return state;
444 }
445
446 void SHARED_EXPORT uGetCommandLine(string_base & out)
447 {
448 out = stringcvt::string_utf8_from_os(GetCommandLine());
449 }
450
451 BOOL SHARED_EXPORT uGetTempPath(string_base & out)
452 {
453 TCHAR temp[MAX_PATH+1];
454 temp[0]=0;
455 if (GetTempPath(_countof(temp),temp))
456 {
457 out = stringcvt::string_utf8_from_os(temp,_countof(temp));
458 return TRUE;
459 }
460 return FALSE;
461
462 }
463 BOOL SHARED_EXPORT uGetTempFileName(const char * path_name,const char * prefix,UINT unique,string_base & out)
464 {
465 if (path_name==0 || prefix==0) return FALSE;
466 TCHAR temp[MAX_PATH+1];
467 temp[0]=0;
468 if (GetTempFileName(stringcvt::string_os_from_utf8(path_name),stringcvt::string_os_from_utf8(prefix),unique,temp))
469 {
470 out = stringcvt::string_utf8_from_os(temp,_countof(temp));
471 return TRUE;
472 }
473 return FALSE;
474 }
475
476 class uFindFile_i : public uFindFile
477 {
478 string8 fn;
479 WIN32_FIND_DATA fd;
480 HANDLE hFF;
481 public:
482 uFindFile_i() {hFF = INVALID_HANDLE_VALUE;}
483 bool FindFirst(const char * path)
484 {
485 hFF = FindFirstFile(stringcvt::string_os_from_utf8(path),&fd);
486 if (hFF==INVALID_HANDLE_VALUE) return false;
487 fn = stringcvt::string_utf8_from_os(fd.cFileName,_countof(fd.cFileName));
488 return true;
489 }
490 virtual BOOL FindNext()
491 {
492 if (hFF==INVALID_HANDLE_VALUE) return FALSE;
493 BOOL rv = FindNextFile(hFF,&fd);
494 if (rv) fn = stringcvt::string_utf8_from_os(fd.cFileName,_countof(fd.cFileName));
495 return rv;
496 }
497
498 virtual const char * GetFileName()
499 {
500 return fn;
501 }
502
503 virtual t_uint64 GetFileSize()
504 {
505 union
506 {
507 t_uint64 val64;
508 struct
509 {
510 DWORD lo,hi;
511 };
512 } ret;
513
514 ret.hi = fd.nFileSizeHigh;
515 ret.lo = fd.nFileSizeLow;
516 return ret.val64;
517
518 }
519 virtual DWORD GetAttributes()
520 {
521 return fd.dwFileAttributes;
522 }
523
524 virtual FILETIME GetCreationTime()
525 {
526 return fd.ftCreationTime;
527 }
528 virtual FILETIME GetLastAccessTime()
529 {
530 return fd.ftLastAccessTime;
531 }
532 virtual FILETIME GetLastWriteTime()
533 {
534 return fd.ftLastWriteTime;
535 }
536 virtual ~uFindFile_i()
537 {
538 if (hFF!=INVALID_HANDLE_VALUE) FindClose(hFF);
539 }
540 };
541
542 puFindFile SHARED_EXPORT uFindFirstFile(const char * path)
543 {
544 pfc::ptrholder_t<uFindFile_i> ptr = new uFindFile_i;
545 if (!ptr->FindFirst(path)) {
546 ptr.release();
547 return NULL;
548 } else {
549 return ptr.detach();
550 }
551 }
552
553 HINSTANCE SHARED_EXPORT uShellExecute(HWND wnd,const char * oper,const char * file,const char * params,const char * dir,int cmd)
554 {
555 modal_dialog_scope modal; // IDIOCY - ShellExecute may spawn a modal dialog
556 if (wnd) modal.initialize(wnd);
557 return ShellExecute(wnd,param_os_from_utf8(oper),param_os_from_utf8(file),param_os_from_utf8(params),param_os_from_utf8(dir),cmd);
558 }
559
560 HWND SHARED_EXPORT uCreateStatusWindow(LONG style,const char * text,HWND parent,UINT id)
561 {
562 return CreateStatusWindow(style,param_os_from_utf8(text),parent,id);
563 }
564
565 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)
566 {
567 return CreateWindowEx(dwExStyle,param_os_from_utf8(lpClassName),param_os_from_utf8(lpWindowName),dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
568 }
569
570 HANDLE SHARED_EXPORT uLoadImage(HINSTANCE hIns,const char * name,UINT type,int x,int y,UINT flags)
571 {
572 return LoadImage(hIns,param_os_from_utf8(name),type,x,y,flags);
573 }
574
575 BOOL SHARED_EXPORT uGetSystemDirectory(string_base & out)
576 {
577 UINT len = GetSystemDirectory(0,0);
578 if (len==0) len = MAX_PATH;
579 len++;
580 array_t<TCHAR> temp;
581 temp.set_size(len);
582 if (GetSystemDirectory(temp.get_ptr(),len)==0) return FALSE;
583 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
584 return TRUE;
585 }
586
587 BOOL SHARED_EXPORT uGetWindowsDirectory(string_base & out)
588 {
589 UINT len = GetWindowsDirectory(0,0);
590 if (len==0) len = MAX_PATH;
591 len++;
592 array_t<TCHAR> temp;
593 temp.set_size(len);
594 if (GetWindowsDirectory(temp.get_ptr(),len)==0) return FALSE;
595 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
596 return TRUE;
597 }
598
599 BOOL SHARED_EXPORT uSetCurrentDirectory(const char * path)
600 {
601 return SetCurrentDirectory(stringcvt::string_os_from_utf8(path));
602 }
603
604 BOOL SHARED_EXPORT uGetCurrentDirectory(string_base & out)
605 {
606 UINT len = GetCurrentDirectory(0,0);
607 if (len==0) len = MAX_PATH;
608 len++;
609 array_t<TCHAR> temp;
610 temp.set_size(len);
611 if (GetCurrentDirectory(len,temp.get_ptr())==0) return FALSE;
612 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
613 return TRUE;
614 }
615
616 BOOL SHARED_EXPORT uExpandEnvironmentStrings(const char * src,string_base & out)
617 {
618 stringcvt::string_os_from_utf8 src_os(src);
619 UINT len = ExpandEnvironmentStrings(src_os,0,0);
620 if (len==0) len = 256;
621 len++;
622 array_t<TCHAR> temp;
623 temp.set_size(len);
624 if (ExpandEnvironmentStrings(src_os,temp.get_ptr(),len)==0) return FALSE;
625 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
626 return TRUE;
627 }
628
629 BOOL SHARED_EXPORT uGetUserName(string_base & out)
630 {
631 TCHAR temp[UNLEN+1];
632 DWORD len = _countof(temp);
633 if (GetUserName(temp,&len))
634 {
635 out = stringcvt::string_utf8_from_os(temp,_countof(temp));
636 return TRUE;
637 }
638 else return FALSE;
639 }
640
641 BOOL SHARED_EXPORT uGetShortPathName(const char * src,string_base & out)
642 {
643 stringcvt::string_os_from_utf8 src_os(src);
644 UINT len = GetShortPathName(src_os,0,0);
645 if (len==0) len = MAX_PATH;
646 len++;
647 array_t<TCHAR> temp; temp.set_size(len);
648 if (GetShortPathName(src_os,temp.get_ptr(),len))
649 {
650 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
651 return TRUE;
652 }
653 else return FALSE;
654 }
655
656
657 #ifdef UNICODE
658 #define DDE_CODEPAGE CP_WINUNICODE
659 #else
660 #define DDE_CODEPAGE CP_WINANSI
661 #endif
662
663
664 HSZ SHARED_EXPORT uDdeCreateStringHandle(DWORD ins,const char * src)
665 {
666 return DdeCreateStringHandle(ins,stringcvt::string_os_from_utf8(src),DDE_CODEPAGE);
667 }
668
669 BOOL SHARED_EXPORT uDdeQueryString(DWORD ins,HSZ hsz,string_base & out)
670 {
671 array_t<TCHAR> temp;
672 UINT len = DdeQueryString(ins,hsz,0,0,DDE_CODEPAGE);
673 if (len==0) len = MAX_PATH;
674 len++;
675 temp.set_size(len);
676 if (DdeQueryString(ins,hsz,temp.get_ptr(),len,DDE_CODEPAGE))
677 {
678 out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
679 return TRUE;
680 }
681 else return FALSE;
682 }
683
684 UINT SHARED_EXPORT uDdeInitialize(LPDWORD pidInst,PFNCALLBACK pfnCallback,DWORD afCmd,DWORD ulRes)
685 {
686 return DdeInitialize(pidInst,pfnCallback,afCmd,ulRes);
687 }
688
689 BOOL SHARED_EXPORT uDdeAccessData_Text(HDDEDATA data,string_base & out)
690 {
691 const TCHAR * ptr = (const TCHAR*) DdeAccessData(data,0);
692 if (ptr)
693 {
694 out = stringcvt::string_utf8_from_os(ptr);
695 return TRUE;
696 }
697 else return FALSE;
698 }
699
700 uSortString_t SHARED_EXPORT uSortStringCreate(const char * src) {
701 t_size lenEst = pfc::stringcvt::estimate_utf8_to_wide(src,SIZE_MAX);
702 TCHAR * ret = pfc::__raw_malloc_t<TCHAR>(lenEst);
703 pfc::stringcvt::convert_utf8_to_wide(ret,lenEst,src,SIZE_MAX);
704 return reinterpret_cast<uSortString_t>( ret );
705 }
706
707 int SHARED_EXPORT uSortStringCompareEx(uSortString_t string1, uSortString_t string2,uint32_t flags) {
708 return CompareString(LOCALE_USER_DEFAULT,flags,reinterpret_cast<const TCHAR*>(string1),-1,reinterpret_cast<const TCHAR*>(string2),-1);
709 }
710
711 int SHARED_EXPORT uSortStringCompare(uSortString_t string1, uSortString_t string2) {
712 return lstrcmpi(reinterpret_cast<const TCHAR*>(string1),reinterpret_cast<const TCHAR*>(string2));
713 }
714
715 void SHARED_EXPORT uSortStringFree(uSortString_t string) {
716 pfc::__raw_free_t(reinterpret_cast<TCHAR*>(string));
717 }
718
719 HTREEITEM SHARED_EXPORT uTreeView_InsertItem(HWND wnd,const uTVINSERTSTRUCT * param)
720 {
721 stringcvt::string_os_from_utf8 temp;
722 temp.convert(param->item.pszText);
723
724
725 TVINSERTSTRUCT l_param = {};
726 l_param.hParent = param->hParent;
727 l_param.hInsertAfter = param->hInsertAfter;
728 l_param.item.mask = param->item.mask;
729 l_param.item.hItem = param->item.hItem;
730 l_param.item.state = param->item.state;
731 l_param.item.stateMask = param->item.stateMask;
732 l_param.item.pszText = const_cast<TCHAR*>(temp.get_ptr());
733 l_param.item.cchTextMax = 0;
734 l_param.item.iImage = param->item.iImage;
735 l_param.item.iSelectedImage = param->item.iImage;
736 l_param.item.cChildren = param->item.cChildren;
737 l_param.item.lParam = param->item.lParam;
738 if (param->item.mask & TVIF_INTEGRAL)
739 {
740 l_param.itemex.iIntegral = param->itemex.iIntegral;
741 }
742
743 return (HTREEITEM) uSendMessage(wnd,TVM_INSERTITEM,0,(LPARAM)&l_param);
744 }
745
746 UINT SHARED_EXPORT uGetFontHeight(HFONT font)
747 {
748 UINT ret;
749 HDC dc = CreateCompatibleDC(0);
750 SelectObject(dc,font);
751 ret = uGetTextHeight(dc);
752 DeleteDC(dc);
753 return ret;
754 }
755
756
757 HIMAGELIST SHARED_EXPORT uImageList_LoadImage(HINSTANCE hi, const char * lpbmp, int cx, int cGrow, COLORREF crMask, UINT uType, UINT uFlags)
758 {
759 return ImageList_LoadImage(hi,param_os_from_utf8(lpbmp),cx,cGrow,crMask,uType,uFlags);
760 }
761
762 int SHARED_EXPORT uTabCtrl_InsertItem(HWND wnd,t_size idx,const uTCITEM * item)
763 {
764 param_os_from_utf8 text((item->mask & TCIF_TEXT) ? item->pszText : 0);
765 TCITEM l_item;
766 assert(sizeof(l_item)==sizeof(*item));//meh lazy
767 memcpy(&l_item,item,sizeof(l_item));
768 l_item.pszText = const_cast<TCHAR*>(text.get_ptr());
769 l_item.cchTextMax = 0;
770 return TabCtrl_InsertItem(wnd,idx,&l_item);
771 }
772
773 int SHARED_EXPORT uTabCtrl_SetItem(HWND wnd,t_size idx,const uTCITEM * item)
774 {
775 param_os_from_utf8 text((item->mask & TCIF_TEXT) ? item->pszText : 0);
776 TCITEM l_item;
777 PFC_STATIC_ASSERT(sizeof(l_item)==sizeof(*item));//meh lazy
778 memcpy(&l_item,item,sizeof(l_item));
779 l_item.pszText = const_cast<TCHAR*>(text.get_ptr());
780 l_item.cchTextMax = 0;
781 return TabCtrl_SetItem(wnd,idx,&l_item);
782 }
783
784 int SHARED_EXPORT uGetKeyNameText(LONG lparam,string_base & out)
785 {
786 TCHAR temp[256];
787 temp[0]=0;
788 if (!GetKeyNameText(lparam,temp,_countof(temp))) return 0;
789 out = stringcvt::string_utf8_from_os(temp,_countof(temp));
790 return 1;
791 }
792
793 HANDLE SHARED_EXPORT uCreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,const char * lpName)
794 {
795 return CreateFileMapping(hFile,lpFileMappingAttributes,flProtect,dwMaximumSizeHigh,dwMaximumSizeLow,param_os_from_utf8(lpName));
796 }
797
798 BOOL SHARED_EXPORT uListBox_GetText(HWND listbox,UINT index,string_base & out)
799 {
800 t_size len = uSendMessage(listbox,LB_GETTEXTLEN,index,0);
801 if (len==LB_ERR || len>16*1024*1024) return FALSE;
802 if (len==0) {out.reset();return TRUE;}
803
804 array_t<TCHAR> temp; temp.set_size(len+1);
805 pfc::memset_t(temp,(TCHAR)0);
806 len = uSendMessage(listbox,LB_GETTEXT,index,(LPARAM)temp.get_ptr());
807 if (len==LB_ERR) return false;
808 out = stringcvt::string_utf8_from_os(temp.get_ptr());
809 return TRUE;
810 }
811 /*
812 void SHARED_EXPORT uPrintf(string_base & out,const char * fmt,...)
813 {
814 va_list list;
815 va_start(list,fmt);
816 uPrintfV(out,fmt,list);
817 va_end(list);
818 }
819 */
820 void SHARED_EXPORT uPrintfV(string_base & out,const char * fmt,va_list arglist)
821 {
822 pfc::string_printf_here_va(out, fmt, arglist);
823 }
824
825 int SHARED_EXPORT uCompareString(DWORD flags,const char * str1,size_t len1,const char * str2,size_t len2)
826 {
827 return CompareString(LOCALE_USER_DEFAULT,flags,stringcvt::string_os_from_utf8(str1,len1),-1,stringcvt::string_os_from_utf8(str2,len2),-1);
828 }
829
830 class uResource_i : public uResource
831 {
832 unsigned size;
833 const void * ptr;
834 public:
835 inline uResource_i(const void * p_ptr,unsigned p_size) : ptr(p_ptr), size(p_size)
836 {
837 }
838 virtual const void * GetPointer()
839 {
840 return ptr;
841 }
842 virtual unsigned GetSize()
843 {
844 return size;
845 }
846 virtual ~uResource_i()
847 {
848 }
849 };
850
851 puResource SHARED_EXPORT uLoadResource(HMODULE hMod,const char * name,const char * type,WORD wLang)
852 {
853 HRSRC res = uFindResource(hMod,name,type,wLang);
854 if (res==0) return 0;
855 HGLOBAL hglob = LoadResource(hMod,res);
856 if (hglob)
857 {
858 void * ptr = LockResource(hglob);
859 if (ptr)
860 {
861 return new uResource_i(ptr,SizeofResource(hMod,res));
862 }
863 else return 0;
864 }
865 else return 0;
866 }
867
868 puResource SHARED_EXPORT LoadResourceEx(HMODULE hMod,const TCHAR * name,const TCHAR * type,WORD wLang)
869 {
870 HRSRC res = wLang ? FindResourceEx(hMod,type,name,wLang) : FindResource(hMod,name,type);
871 if (res==0) return 0;
872 HGLOBAL hglob = LoadResource(hMod,res);
873 if (hglob)
874 {
875 void * ptr = LockResource(hglob);
876 if (ptr)
877 {
878 return new uResource_i(ptr,SizeofResource(hMod,res));
879 }
880 else return 0;
881 }
882 else return 0;
883 }
884
885 HRSRC SHARED_EXPORT uFindResource(HMODULE hMod,const char * name,const char * type,WORD wLang)
886 {
887 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));
888 }
889
890 BOOL SHARED_EXPORT uLoadString(HINSTANCE ins,UINT id,string_base & out)
891 {
892 BOOL rv = FALSE;
893 uResource * res = uLoadResource(ins,uMAKEINTRESOURCE(id),(const char*)(RT_STRING));
894 if (res)
895 {
896 unsigned size = res->GetSize();
897 const WCHAR * ptr = (const WCHAR*)res->GetPointer();
898 if (size>=4)
899 {
900 unsigned len = *(const WORD*)(ptr+1);
901 if (len * 2 + 4 <= size)
902 {
903 out = stringcvt::string_utf8_from_wide(ptr+2,len);
904 }
905 }
906
907 delete res;
908 rv = TRUE;
909 }
910 return rv;
911 }
912
913 BOOL SHARED_EXPORT uGetMenuString(HMENU menu,UINT id,string_base & out,UINT flag)
914 {
915 unsigned len = GetMenuString(menu,id,0,0,flag);
916 if (len==0)
917 {
918 out.reset();
919 return FALSE;
920 }
921 array_t<TCHAR> temp;
922 temp.set_size(len+1);
923 if (GetMenuString(menu,id,temp.get_ptr(),len+1,flag)==0) {
924 out.reset();
925 return FALSE;
926 }
927 out = stringcvt::string_utf8_from_os(temp.get_ptr());
928 return TRUE;
929 }
930
931 BOOL SHARED_EXPORT uModifyMenu(HMENU menu,UINT id,UINT flags,UINT newitem,const char * data)
932 {
933 return ModifyMenu(menu,id,flags,newitem,param_os_from_utf8(data));
934 }
935
936 UINT SHARED_EXPORT uGetMenuItemType(HMENU menu,UINT position)
937 {
938 MENUITEMINFO info = {};
939 info.cbSize = sizeof(info);
940 info.fMask = MIIM_TYPE;
941 if (!GetMenuItemInfo(menu,position,TRUE,&info))
942 return 0;
943 return info.fType;
944 }
945
946 static inline bool i_is_path_separator(unsigned c)
947 {
948 return c=='\\' || c=='/' || c=='|' || c==':';
949 }
950
951 int SHARED_EXPORT uSortPathCompare(HANDLE string1,HANDLE string2)
952 {
953 const TCHAR * s1 = reinterpret_cast<const TCHAR*>(string1);
954 const TCHAR * s2 = reinterpret_cast<const TCHAR*>(string2);
955 const TCHAR * p1, * p2;
956
957 while (*s1 || *s2)
958 {
959 if (*s1 == *s2)
960 {
961 s1++;
962 s2++;
963 continue;
964 }
965
966 p1 = s1; while (*p1 && !i_is_path_separator(*p1)) p1++;
967 p2 = s2; while (*p2 && !i_is_path_separator(*p2)) p2++;
968
969 if ((!*p1 && !*p2) || (*p1 && *p2))
970 {
971 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));
972 if (test && test != 2) return test - 2;
973 if (!*p1) return 0;
974 }
975 else
976 {
977 if (*p1) return -1;
978 else return 1;
979 }
980
981 s1 = p1 + 1;
982 s2 = p2 + 1;
983 }
984
985 return 0;
986 }
987
988 UINT SHARED_EXPORT uRegisterClipboardFormat(const char * name)
989 {
990 return RegisterClipboardFormat(stringcvt::string_os_from_utf8(name));
991 }
992
993 BOOL SHARED_EXPORT uGetClipboardFormatName(UINT format,string_base & out)
994 {
995 TCHAR temp[1024];
996 if (!GetClipboardFormatName(format,temp,_countof(temp))) return FALSE;
997 out = stringcvt::string_utf8_from_os(temp,_countof(temp));
998 return TRUE;
999 }
1000
1001 }//extern "C"
1002
1003 BOOL SHARED_EXPORT uSearchPath(const char * path, const char * filename, const char * extension, string_base & p_out)
1004 {
1005 enum {temp_size = 1024};
1006 param_os_from_utf8 path_os(path), filename_os(filename), extension_os(extension);
1007 array_t<TCHAR> temp; temp.set_size(temp_size);
1008 LPTSTR dummy;
1009 unsigned len;
1010
1011 len = SearchPath(path_os,filename_os,extension_os,temp_size,temp.get_ptr(),&dummy);
1012 if (len == 0) return FALSE;
1013 if (len >= temp_size)
1014 {
1015 unsigned len2;
1016 temp.set_size(len + 1);
1017 len2 = SearchPath(path_os,filename_os,extension_os,len+1,temp.get_ptr(),&dummy);
1018 if (len2 == 0 || len2 > len) return FALSE;
1019 len = len2;
1020 }
1021
1022 p_out = stringcvt::string_utf8_from_os(temp.get_ptr(),len);
1023
1024 return TRUE;
1025
1026 }
1027
1028 static bool is_ascii_alpha(char c)
1029 {
1030 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
1031 }
1032
1033 static char ascii_upper(char c)
1034 {
1035 if (c >= 'a' && c <= 'z') c += 'A' - 'a';
1036 return c;
1037 }
1038
1039 static BOOL uFixPathCaps_Internal(const char * path,string_base & p_out, bool bQuick) {
1040 pfc::string8_fastalloc temp, prependbuffer;
1041 if (path[0] == '\\' && path[1] == '\\')
1042 {
1043 unsigned index = 2;
1044 while(path[index] != '\\')
1045 {
1046 if (path[index] == 0) return FALSE;
1047 index++;
1048 }
1049 index++;
1050 if (path[index] == '\\' || path[index] == 0) return FALSE;
1051 while(path[index] != '\\')
1052 {
1053 if (path[index] == 0) {
1054 // \\host\share
1055 uStringLower(p_out,path);
1056 return TRUE;
1057 }
1058 index++;
1059 }
1060 index++;
1061 if (path[index] == '\\') return FALSE;
1062 uAddStringLower(temp,path,index);
1063 path += index;
1064 }
1065 else if (is_ascii_alpha(path[0]) && path[1] == ':' && path[2] == '\\')
1066 {
1067 temp.add_char(ascii_upper(path[0]));
1068 temp.add_string(":\\");
1069 path += 3;
1070 }
1071 else return FALSE;
1072
1073 for(;;)
1074 {
1075 t_size truncat = temp.length();
1076 t_size delta = 0;
1077 while(path[delta]!=0 && path[delta]!='\\') delta++;
1078 if (delta == 0) break;
1079 temp.add_string_nc(path,delta);
1080
1081 bool found = false;
1082 if (!bQuick) {
1083 #ifdef UNICODE
1084 pfc::winPrefixPath( prependbuffer, temp );
1085 pfc::ptrholder_t<uFindFile> ff = uFindFirstFile(prependbuffer);
1086 #else
1087 pfc::ptrholder_t<uFindFile> ff = uFindFirstFile(temp);
1088 #endif
1089 if (ff.is_valid()) {
1090 do {
1091 const char * fn = ff->GetFileName();
1092 if (!stricmp_utf8_ex(path,delta,fn,strlen(fn)))
1093 {
1094 found = true;
1095 temp.truncate(truncat);
1096 temp.add_string(fn);
1097 break;
1098 }
1099 } while(ff->FindNext());
1100 }
1101 }
1102 if (!found)
1103 {
1104 temp.add_string(path + delta);
1105 break;
1106 }
1107 path += delta;
1108 if (*path == 0) break;
1109 path ++;
1110 temp.add_char('\\');
1111 }
1112
1113
1114 p_out = temp;
1115
1116 return TRUE;
1117 }
1118 /*BOOL SHARED_EXPORT uFixPathCapsQuick(const char * path,string_base & p_out) {
1119 return uFixPathCaps_Internal(path, p_out, true);
1120 }*/
1121 BOOL SHARED_EXPORT uFixPathCaps(const char * path,string_base & p_out) {
1122 return uFixPathCaps_Internal(path, p_out, false);
1123 }
1124
1125 LPARAM SHARED_EXPORT uTreeView_GetUserData(HWND p_tree,HTREEITEM p_item)
1126 {
1127 TVITEM item = {};
1128 item.mask = TVIF_PARAM;
1129 item.hItem = p_item;
1130 if (uSendMessage(p_tree,TVM_GETITEM,0,(LPARAM)&item))
1131 return item.lParam;
1132 return 0;
1133 }
1134
1135 bool SHARED_EXPORT uTreeView_GetText(HWND p_tree,HTREEITEM p_item,string_base & p_out)
1136 {
1137 TCHAR temp[1024];//changeme ?
1138 TVITEM item = {};
1139 item.mask = TVIF_TEXT;
1140 item.hItem = p_item;
1141 item.pszText = temp;
1142 item.cchTextMax = _countof(temp);
1143 if (uSendMessage(p_tree,TVM_GETITEM,0,(LPARAM)&item))
1144 {
1145 p_out = stringcvt::string_utf8_from_os(temp,_countof(temp));
1146 return true;
1147 }
1148 else return false;
1149 }
1150
1151 BOOL SHARED_EXPORT uSetWindowText(HWND wnd,const char * p_text)
1152 {
1153 PFC_ASSERT( wnd != NULL );
1154 return SetWindowText(wnd,stringcvt::string_os_from_utf8(p_text));
1155 }
1156
1157 BOOL SHARED_EXPORT uSetDlgItemText(HWND wnd,UINT id,const char * p_text)
1158 {
1159 PFC_ASSERT( wnd != NULL );
1160 return SetDlgItemText(wnd, id, stringcvt::string_os_from_utf8(p_text));
1161 }
1162
1163 BOOL SHARED_EXPORT uFileExists(const char * fn)
1164 {
1165 DWORD attrib = uGetFileAttributes(fn);
1166 if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY)) return FALSE;
1167 return TRUE;
1168 }
1169
1170 BOOL SHARED_EXPORT uFormatSystemErrorMessage(string_base & p_out,DWORD p_code) {
1171 return pfc::winFormatSystemErrorMessage(p_out, p_code);
1172 }
1173
1174 HMODULE SHARED_EXPORT LoadSystemLibrary(const TCHAR * name) {
1175 pfc::array_t<TCHAR> buffer; buffer.set_size( MAX_PATH + _tcslen(name) + 2 );
1176 TCHAR * bufptr = buffer.get_ptr();
1177 if (GetSystemDirectory(bufptr, MAX_PATH) == 0) return NULL;
1178 bufptr[MAX_PATH] = 0;
1179
1180 size_t idx = _tcslen(bufptr);
1181 if (idx > 0 && bufptr[idx-1] != '\\') bufptr[idx++] = '\\';
1182
1183 pfc::strcpy_t(bufptr+idx, name);
1184
1185 return LoadLibrary(bufptr);
1186 }