1 #if defined(_WIN32) && !defined(WDL_WIN32_UTF8_NO_UI_IMPL)
6 #include "win32_utf8.h"
12 #if !defined(WDL_NO_SUPPORT_UTF8)
19 #ifndef WDL_UTF8_MAXFNLEN
20 #define WDL_UTF8_MAXFNLEN 2048
23 #define MBTOWIDE(symbase, src) \
25 WCHAR symbase##_buf[1024]; \
26 WCHAR *symbase = (symbase##_size=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,NULL,0)) >= 1000 ? (WCHAR *)malloc(symbase##_size * sizeof(WCHAR) + 10) : symbase##_buf; \
27 int symbase##_ok = symbase ? (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,symbase,symbase##_size < 1 ? 1024 : symbase##_size)) : 0
29 #define MBTOWIDE_FREE(symbase) if (symbase != symbase##_buf) free(symbase)
32 #define WIDETOMB_ALLOC(symbase, length) \
33 WCHAR symbase##_buf[1024]; \
34 size_t symbase##_size = sizeof(symbase##_buf); \
35 WCHAR *symbase = (length) > 1000 ? (WCHAR *)malloc(symbase##_size = (sizeof(WCHAR)*(length) + 10)) : symbase##_buf
37 #define WIDETOMB_FREE(symbase) if (symbase != symbase##_buf) free(symbase)
39 BOOL
WDL_HasUTF8(const char *_str
)
41 return WDL_DetectUTF8(_str
) > 0;
44 #ifdef AND_IS_NOT_WIN9X
45 #undef AND_IS_NOT_WIN9X
47 #ifdef IS_NOT_WIN9X_AND
48 #undef IS_NOT_WIN9X_AND
51 #ifdef WDL_SUPPORT_WIN9X
52 #define IS_NOT_WIN9X_AND (GetVersion() < 0x80000000) &&
53 #define AND_IS_NOT_WIN9X && (GetVersion() < 0x80000000)
55 #define AND_IS_NOT_WIN9X
56 #define IS_NOT_WIN9X_AND
59 static ATOM s_combobox_atom
;
60 #define WDL_UTF8_OLDPROCPROP "WDLUTF8OldProc"
62 int GetWindowTextUTF8(HWND hWnd
, LPTSTR lpString
, int nMaxCount
)
64 if (!lpString
) return 0;
65 if (nMaxCount
>0 AND_IS_NOT_WIN9X
)
67 int alloc_size
=nMaxCount
;
69 // if a hooked combo box, and has an edit child, ask it directly
70 if (s_combobox_atom
&& s_combobox_atom
== GetClassWord(hWnd
,GCW_ATOM
) && GetProp(hWnd
,WDL_UTF8_OLDPROCPROP
))
72 HWND h2
=FindWindowEx(hWnd
,NULL
,"Edit",NULL
);
77 int sel
= (int) SendMessage(hWnd
,CB_GETCURSEL
,0,0);
80 int len
= (int) SendMessage(hWnd
,CB_GETLBTEXTLEN
,sel
,0);
82 if (len
> nMaxCount
-1)
84 p
= (char*)calloc(len
+1,1);
90 SendMessage(hWnd
,CB_GETLBTEXT
,sel
,(LPARAM
)p
);
93 memcpy(lpString
,p
,len
);
103 // prevent large values of nMaxCount from allocating memory unless the underlying text is big too
104 if (alloc_size
> 512)
106 int l
=GetWindowTextLengthW(hWnd
);
107 if (l
>=0 && l
< 512) alloc_size
=1000;
111 WIDETOMB_ALLOC(wbuf
, alloc_size
);
115 if (GetWindowTextW(hWnd
,wbuf
,(int) (wbuf_size
/sizeof(WCHAR
))))
117 if (!WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,lpString
,nMaxCount
,NULL
,NULL
))
118 lpString
[nMaxCount
-1]=0;
123 return (int)strlen(lpString
);
127 return GetWindowTextA(hWnd
,lpString
,nMaxCount
);
130 UINT
GetDlgItemTextUTF8(HWND hDlg
, int nIDDlgItem
, LPTSTR lpString
, int nMaxCount
)
132 HWND h
= GetDlgItem(hDlg
,nIDDlgItem
);
133 if (h
) return GetWindowTextUTF8(h
,lpString
,nMaxCount
);
138 BOOL
SetDlgItemTextUTF8(HWND hDlg
, int nIDDlgItem
, LPCTSTR lpString
)
140 HWND h
= GetDlgItem(hDlg
,nIDDlgItem
);
141 if (!h
) return FALSE
;
143 if (WDL_HasUTF8(lpString
) AND_IS_NOT_WIN9X
)
145 MBTOWIDE(wbuf
,lpString
);
148 BOOL rv
= SetWindowTextW(h
, wbuf
);
156 return SetWindowTextA(h
, lpString
);
160 static LRESULT WINAPI
__forceUnicodeWndProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
162 if (uMsg
== WM_SETTEXT
&& lParam
)
164 MBTOWIDE(wbuf
,(const char *)lParam
);
167 LRESULT rv
= DefWindowProcW(hwnd
, uMsg
, wParam
, (LPARAM
)wbuf
);
173 return DefWindowProc(hwnd
, uMsg
, wParam
, lParam
);
176 BOOL
SetWindowTextUTF8(HWND hwnd
, LPCTSTR str
)
178 if (WDL_HasUTF8(str
) AND_IS_NOT_WIN9X
)
181 if (GetWindowThreadProcessId(hwnd
,&pid
) == GetCurrentThreadId() &&
182 pid
== GetCurrentProcessId() &&
183 !(GetWindowLong(hwnd
,GWL_STYLE
)&WS_CHILD
))
185 LPARAM tmp
= SetWindowLongPtr(hwnd
, GWLP_WNDPROC
, (LPARAM
)__forceUnicodeWndProc
);
186 BOOL rv
= SetWindowTextA(hwnd
, str
);
187 SetWindowLongPtr(hwnd
, GWLP_WNDPROC
, tmp
);
195 BOOL rv
= SetWindowTextW(hwnd
, wbuf
);
204 return SetWindowTextA(hwnd
,str
);
207 int MessageBoxUTF8(HWND hwnd
, LPCTSTR lpText
, LPCTSTR lpCaption
, UINT fl
)
209 if ((WDL_HasUTF8(lpText
)||WDL_HasUTF8(lpCaption
)) AND_IS_NOT_WIN9X
)
211 MBTOWIDE(wbuf
,lpText
);
214 MBTOWIDE(wcap
,lpCaption
?lpCaption
:"");
217 int ret
=MessageBoxW(hwnd
,wbuf
,lpCaption
?wcap
:NULL
,fl
);
225 return MessageBoxA(hwnd
,lpText
,lpCaption
,fl
);
228 UINT
DragQueryFileUTF8(HDROP hDrop
, UINT idx
, char *buf
, UINT bufsz
)
230 if (buf
&& bufsz
&& idx
!=-1 AND_IS_NOT_WIN9X
)
232 const UINT reqsz
= DragQueryFileW(hDrop
,idx
,NULL
,0);
233 WIDETOMB_ALLOC(wbuf
, reqsz
+32);
236 UINT rv
=DragQueryFileW(hDrop
,idx
,wbuf
,(int)(wbuf_size
/sizeof(WCHAR
)));
239 if (!WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,buf
,bufsz
,NULL
,NULL
))
246 return DragQueryFileA(hDrop
,idx
,buf
,bufsz
);
250 WCHAR
*WDL_UTF8ToWC(const char *buf
, BOOL doublenull
, int minsize
, DWORD
*sizeout
)
255 const char *p
= (const char *)buf
;
260 int a
=MultiByteToWideChar(CP_UTF8
,MB_ERR_INVALID_CHARS
,p
,-1,NULL
,0);
261 int sp
=(int)strlen(p
)+1;
262 if (a
< sp
)a
=sp
; // in case it needs to be ansi mapped
266 if (sz
< minsize
) sz
=minsize
;
268 pout
= (WCHAR
*) malloc(sizeof(WCHAR
)*(sz
+4));
269 if (!pout
) return NULL
;
272 p
= (const char *)buf
;
277 a
= MultiByteToWideChar(CP_UTF8
,MB_ERR_INVALID_CHARS
,p
,-1,pout
,(int) (sz
-(pout
-ret
)));
281 a
=MultiByteToWideChar(CP_ACP
,MB_ERR_INVALID_CHARS
,p
,-1,pout
,(int) (sz
-(pout
-ret
)));
288 if (sizeout
) *sizeout
=sz
;
293 int srclen
= (int)strlen(buf
)+1;
294 int size
=MultiByteToWideChar(CP_UTF8
,MB_ERR_INVALID_CHARS
,buf
,srclen
,NULL
,0);
295 if (size
< srclen
)size
=srclen
; // for ansi code page
296 if (size
<minsize
)size
=minsize
;
299 WCHAR
*outbuf
= (WCHAR
*)malloc(sizeof(WCHAR
)*(size
+128));
300 if (!outbuf
) return NULL
;
305 int a
=MultiByteToWideChar(CP_UTF8
,MB_ERR_INVALID_CHARS
,buf
,srclen
,outbuf
, size
);
309 a
=MultiByteToWideChar(CP_ACP
,MB_ERR_INVALID_CHARS
,buf
,srclen
,outbuf
,size
);
312 if (sizeout
) *sizeout
= size
;
318 #ifndef WDL_WIN32_UTF8_NO_UI_IMPL
319 static BOOL
GetOpenSaveFileNameUTF8(LPOPENFILENAME lpofn
, BOOL save
)
322 OPENFILENAMEW tmp
={sizeof(tmp
),lpofn
->hwndOwner
,lpofn
->hInstance
,};
325 // allocate, convert input
326 if (lpofn
->lpstrFilter
) tmp
.lpstrFilter
= WDL_UTF8ToWC(lpofn
->lpstrFilter
,TRUE
,0,0);
327 tmp
.nFilterIndex
= lpofn
->nFilterIndex
;
329 if (lpofn
->lpstrFile
) tmp
.lpstrFile
= WDL_UTF8ToWC(lpofn
->lpstrFile
,FALSE
,lpofn
->nMaxFile
,&tmp
.nMaxFile
);
330 if (lpofn
->lpstrFileTitle
) tmp
.lpstrFileTitle
= WDL_UTF8ToWC(lpofn
->lpstrFileTitle
,FALSE
,lpofn
->nMaxFileTitle
,&tmp
.nMaxFileTitle
);
331 if (lpofn
->lpstrInitialDir
) tmp
.lpstrInitialDir
= WDL_UTF8ToWC(lpofn
->lpstrInitialDir
,0,0,0);
332 if (lpofn
->lpstrTitle
) tmp
.lpstrTitle
= WDL_UTF8ToWC(lpofn
->lpstrTitle
,0,0,0);
333 if (lpofn
->lpstrDefExt
) tmp
.lpstrDefExt
= WDL_UTF8ToWC(lpofn
->lpstrDefExt
,0,0,0);
334 tmp
.Flags
= lpofn
->Flags
;
335 tmp
.lCustData
= lpofn
->lCustData
;
336 tmp
.lpfnHook
= lpofn
->lpfnHook
;
337 tmp
.lpTemplateName
= (const WCHAR
*)lpofn
->lpTemplateName
;
339 ret
=save
? GetSaveFileNameW(&tmp
) : GetOpenFileNameW(&tmp
);
341 // free, convert output
342 if (ret
&& lpofn
->lpstrFile
&& tmp
.lpstrFile
)
344 if ((tmp
.Flags
& OFN_ALLOWMULTISELECT
) && tmp
.lpstrFile
[wcslen(tmp
.lpstrFile
)+1])
346 char *op
= lpofn
->lpstrFile
;
347 WCHAR
*ip
= tmp
.lpstrFile
;
350 const int bcount
= WideCharToMultiByte(CP_UTF8
,0,ip
,-1,NULL
,0,NULL
,NULL
);
352 const int maxout
=lpofn
->nMaxFile
- 2 - (int)(op
- lpofn
->lpstrFile
);
353 if (maxout
< 2+bcount
) break;
354 op
+= WideCharToMultiByte(CP_UTF8
,0,ip
,-1,op
,maxout
,NULL
,NULL
);
361 int len
= WideCharToMultiByte(CP_UTF8
,0,tmp
.lpstrFile
,-1,lpofn
->lpstrFile
,lpofn
->nMaxFile
-1,NULL
,NULL
);
362 if (len
== 0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER
) len
= lpofn
->nMaxFile
-2;
363 lpofn
->lpstrFile
[len
]=0;
366 lpofn
->lpstrFile
[len
+1]=0;
373 lpofn
->nFileOffset
= tmp
.nFileOffset
;
374 lpofn
->nFileExtension
= tmp
.nFileExtension
;
375 lpofn
->lCustData
= tmp
.lCustData
;
377 free((WCHAR
*)tmp
.lpstrFilter
);
378 free((WCHAR
*)tmp
.lpstrFile
);
379 free((WCHAR
*)tmp
.lpstrFileTitle
);
380 free((WCHAR
*)tmp
.lpstrInitialDir
);
381 free((WCHAR
*)tmp
.lpstrTitle
);
382 free((WCHAR
*)tmp
.lpstrDefExt
);
384 lpofn
->nFilterIndex
= tmp
.nFilterIndex
;
388 BOOL
GetOpenFileNameUTF8(LPOPENFILENAME lpofn
)
390 #ifdef WDL_SUPPORT_WIN9X
391 if (GetVersion()&0x80000000) return GetOpenFileNameA(lpofn
);
393 return GetOpenSaveFileNameUTF8(lpofn
,FALSE
);
396 BOOL
GetSaveFileNameUTF8(LPOPENFILENAME lpofn
)
398 #ifdef WDL_SUPPORT_WIN9X
399 if (GetVersion()&0x80000000) return GetSaveFileNameA(lpofn
);
401 return GetOpenSaveFileNameUTF8(lpofn
,TRUE
);
404 BOOL
SHGetSpecialFolderPathUTF8(HWND hwndOwner
, LPTSTR lpszPath
, int pszPathLen
, int csidl
, BOOL create
)
406 if (lpszPath AND_IS_NOT_WIN9X
)
409 if (SHGetSpecialFolderPathW(hwndOwner
,tmp
,csidl
,create
))
411 return WideCharToMultiByte(CP_UTF8
,0,tmp
,-1,lpszPath
,pszPathLen
,NULL
,NULL
) > 0;
414 return SHGetSpecialFolderPathA(hwndOwner
,lpszPath
,csidl
,create
);
418 #if _MSC_VER > 1700 && defined(_WIN64)
419 BOOL
SHGetPathFromIDListUTF8(const struct _ITEMIDLIST __unaligned
*pidl
, LPSTR pszPath
, int pszPathLen
)
421 BOOL
SHGetPathFromIDListUTF8(const struct _ITEMIDLIST
*pidl
, LPSTR pszPath
, int pszPathLen
)
424 if (pszPath AND_IS_NOT_WIN9X
)
426 const int alloc_sz
= pszPathLen
< 4096 ? 4096 : pszPathLen
;
427 WIDETOMB_ALLOC(wfn
,alloc_sz
);
431 if (SHGetPathFromIDListW(pidl
,wfn
))
433 b
= WideCharToMultiByte(CP_UTF8
,0,wfn
,-1,pszPath
,pszPathLen
,NULL
,NULL
) > 0;
439 return SHGetPathFromIDListA(pidl
,pszPath
);
442 struct _ITEMIDLIST
*SHBrowseForFolderUTF8(struct _browseinfoA
*bi
)
444 if (bi
&& (WDL_HasUTF8(bi
->pszDisplayName
) || WDL_HasUTF8(bi
->lpszTitle
)) AND_IS_NOT_WIN9X
)
446 MBTOWIDE(wfn
,bi
->pszDisplayName
);
449 MBTOWIDE(wtxt
,bi
->lpszTitle
);
452 BROWSEINFOW biw
={ bi
->hwndOwner
,bi
->pidlRoot
,wfn
,wtxt
,bi
->ulFlags
,bi
->lpfn
,(LPARAM
)bi
->lParam
,bi
->iImage
};
453 LPITEMIDLIST idlist
= SHBrowseForFolderW(&biw
);
456 return (struct _ITEMIDLIST
*) idlist
;
462 return (struct _ITEMIDLIST
*)SHBrowseForFolderA(bi
);
465 int WDL_UTF8_SendBFFM_SETSEL(HWND hwnd
, const char *str
)
467 if (IS_NOT_WIN9X_AND
WDL_HasUTF8(str
))
472 int r
=(int)SendMessage(hwnd
, BFFM_SETSELECTIONW
, 1, (LPARAM
)wc
);
478 return (int) SendMessage(hwnd
, BFFM_SETSELECTIONA
, 1, (LPARAM
)str
);
483 BOOL
SetCurrentDirectoryUTF8(LPCTSTR path
)
485 if (WDL_HasUTF8(path
) AND_IS_NOT_WIN9X
)
490 BOOL rv
=SetCurrentDirectoryW(wbuf
);
496 return SetCurrentDirectoryA(path
);
499 BOOL
RemoveDirectoryUTF8(LPCTSTR path
)
501 if (WDL_HasUTF8(path
) AND_IS_NOT_WIN9X
)
506 BOOL rv
=RemoveDirectoryW(wbuf
);
512 return RemoveDirectoryA(path
);
515 HINSTANCE
LoadLibraryUTF8(LPCTSTR path
)
517 if (WDL_HasUTF8(path
) AND_IS_NOT_WIN9X
)
522 HINSTANCE rv
=LoadLibraryW(wbuf
);
531 return LoadLibraryA(path
);
534 BOOL
CreateDirectoryUTF8(LPCTSTR path
, LPSECURITY_ATTRIBUTES attr
)
536 if (WDL_HasUTF8(path
) AND_IS_NOT_WIN9X
)
541 BOOL rv
=CreateDirectoryW(wbuf
,attr
);
547 return CreateDirectoryA(path
,attr
);
550 BOOL
DeleteFileUTF8(LPCTSTR path
)
552 if (WDL_HasUTF8(path
) AND_IS_NOT_WIN9X
)
557 BOOL rv
=DeleteFileW(wbuf
);
563 return DeleteFileA(path
);
566 BOOL
MoveFileUTF8(LPCTSTR existfn
, LPCTSTR newfn
)
568 if ((WDL_HasUTF8(existfn
)||WDL_HasUTF8(newfn
)) AND_IS_NOT_WIN9X
)
570 MBTOWIDE(wbuf
,existfn
);
573 MBTOWIDE(wbuf2
,newfn
);
576 int rv
=MoveFileW(wbuf
,wbuf2
);
577 MBTOWIDE_FREE(wbuf2
);
581 MBTOWIDE_FREE(wbuf2
);
585 return MoveFileA(existfn
,newfn
);
588 BOOL
CopyFileUTF8(LPCTSTR existfn
, LPCTSTR newfn
, BOOL fie
)
590 if ((WDL_HasUTF8(existfn
)||WDL_HasUTF8(newfn
)) AND_IS_NOT_WIN9X
)
592 MBTOWIDE(wbuf
,existfn
);
595 MBTOWIDE(wbuf2
,newfn
);
598 int rv
=CopyFileW(wbuf
,wbuf2
,fie
);
599 MBTOWIDE_FREE(wbuf2
);
603 MBTOWIDE_FREE(wbuf2
);
607 return CopyFileA(existfn
,newfn
,fie
);
611 DWORD
GetModuleFileNameUTF8(HMODULE hModule
, LPTSTR lpBuffer
, DWORD nBufferLength
)
613 if (lpBuffer
&& nBufferLength
> 1 AND_IS_NOT_WIN9X
)
616 WCHAR wbuf
[WDL_UTF8_MAXFNLEN
];
618 if (GetModuleFileNameW(hModule
,wbuf
,WDL_UTF8_MAXFNLEN
) && wbuf
[0])
620 int rv
=WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,lpBuffer
,nBufferLength
,NULL
,NULL
);
624 return GetModuleFileNameA(hModule
,lpBuffer
,nBufferLength
);
628 DWORD
GetCurrentDirectoryUTF8(DWORD nBufferLength
, LPTSTR lpBuffer
)
630 if (lpBuffer
&& nBufferLength
> 1 AND_IS_NOT_WIN9X
)
633 WCHAR wbuf
[WDL_UTF8_MAXFNLEN
];
635 if (GetCurrentDirectoryW(WDL_UTF8_MAXFNLEN
,wbuf
) && wbuf
[0])
637 int rv
=WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,lpBuffer
,nBufferLength
,NULL
,NULL
);
641 return GetCurrentDirectoryA(nBufferLength
,lpBuffer
);
644 HANDLE
CreateFileUTF8(LPCTSTR lpFileName
,DWORD dwDesiredAccess
,DWORD dwShareMode
,LPSECURITY_ATTRIBUTES lpSecurityAttributes
,DWORD dwCreationDisposition
,DWORD dwFlagsAndAttributes
,HANDLE hTemplateFile
)
646 if (WDL_HasUTF8(lpFileName
) AND_IS_NOT_WIN9X
)
648 HANDLE h
= INVALID_HANDLE_VALUE
;
650 MBTOWIDE(wstr
, lpFileName
);
651 if (wstr_ok
) h
= CreateFileW(wstr
,dwDesiredAccess
,dwShareMode
,lpSecurityAttributes
,dwCreationDisposition
,dwFlagsAndAttributes
,hTemplateFile
);
654 if (h
!= INVALID_HANDLE_VALUE
) return h
;
656 return CreateFileA(lpFileName
,dwDesiredAccess
,dwShareMode
,lpSecurityAttributes
,dwCreationDisposition
,dwFlagsAndAttributes
,hTemplateFile
);
660 int DrawTextUTF8(HDC hdc
, LPCTSTR str
, int nc
, LPRECT lpRect
, UINT format
)
662 if (WDL_HasUTF8(str
) AND_IS_NOT_WIN9X
)
664 if (nc
<0) nc
=(int)strlen(str
);
670 int rv
=DrawTextW(hdc
,wstr
,-1,lpRect
,format
);;
678 return DrawTextA(hdc
,str
,nc
,lpRect
,format
);
682 BOOL
InsertMenuUTF8(HMENU hMenu
, UINT uPosition
, UINT uFlags
, UINT_PTR uIDNewItem
, LPCTSTR str
)
684 if (!(uFlags
&(MF_BITMAP
|MF_SEPARATOR
)) && str
&& WDL_HasUTF8(str
) AND_IS_NOT_WIN9X
)
689 BOOL rv
=InsertMenuW(hMenu
,uPosition
,uFlags
,uIDNewItem
,wbuf
);
694 return InsertMenuA(hMenu
,uPosition
,uFlags
,uIDNewItem
,str
);
697 BOOL
InsertMenuItemUTF8( HMENU hMenu
,UINT uItem
, BOOL fByPosition
, LPMENUITEMINFO lpmii
)
699 if (!lpmii
) return FALSE
;
700 if ((lpmii
->fMask
& MIIM_TYPE
) && (lpmii
->fType
&(MFT_SEPARATOR
|MFT_STRING
|MFT_BITMAP
)) == MFT_STRING
&& lpmii
->dwTypeData
&& WDL_HasUTF8(lpmii
->dwTypeData
) AND_IS_NOT_WIN9X
)
703 MENUITEMINFOW tmp
= *(MENUITEMINFOW
*)lpmii
;
704 MBTOWIDE(wbuf
,lpmii
->dwTypeData
);
708 tmp
.cbSize
=sizeof(tmp
);
709 tmp
.dwTypeData
= wbuf
;
710 rv
=InsertMenuItemW(hMenu
,uItem
,fByPosition
,&tmp
);
717 return InsertMenuItemA(hMenu
,uItem
,fByPosition
,lpmii
);
719 BOOL
SetMenuItemInfoUTF8( HMENU hMenu
,UINT uItem
, BOOL fByPosition
, LPMENUITEMINFO lpmii
)
721 if (!lpmii
) return FALSE
;
722 if ((lpmii
->fMask
& MIIM_TYPE
) && (lpmii
->fType
&(MFT_SEPARATOR
|MFT_STRING
|MFT_BITMAP
)) == MFT_STRING
&& lpmii
->dwTypeData
&& WDL_HasUTF8(lpmii
->dwTypeData
) AND_IS_NOT_WIN9X
)
725 MENUITEMINFOW tmp
= *(MENUITEMINFOW
*)lpmii
;
726 MBTOWIDE(wbuf
,lpmii
->dwTypeData
);
729 tmp
.cbSize
=sizeof(tmp
);
730 tmp
.dwTypeData
= wbuf
;
731 rv
=SetMenuItemInfoW(hMenu
,uItem
,fByPosition
,&tmp
);
738 return SetMenuItemInfoA(hMenu
,uItem
,fByPosition
,lpmii
);
741 BOOL
GetMenuItemInfoUTF8( HMENU hMenu
,UINT uItem
, BOOL fByPosition
, LPMENUITEMINFO lpmii
)
743 if (!lpmii
) return FALSE
;
744 if ((lpmii
->fMask
& MIIM_TYPE
) && lpmii
->dwTypeData
&& lpmii
->cch AND_IS_NOT_WIN9X
)
746 MENUITEMINFOW tmp
= *(MENUITEMINFOW
*)lpmii
;
747 WIDETOMB_ALLOC(wbuf
,lpmii
->cch
);
752 char *otd
=lpmii
->dwTypeData
;
753 int osz
=lpmii
->cbSize
;
754 tmp
.cbSize
=sizeof(tmp
);
755 tmp
.dwTypeData
= wbuf
;
756 tmp
.cch
= (UINT
)(wbuf_size
/sizeof(WCHAR
));
757 rv
=GetMenuItemInfoW(hMenu
,uItem
,fByPosition
,&tmp
);
759 if (rv
&& (tmp
.fType
&(MFT_SEPARATOR
|MFT_STRING
|MFT_BITMAP
)) == MFT_STRING
)
761 if (!WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,lpmii
->dwTypeData
,lpmii
->cch
,NULL
,NULL
))
763 lpmii
->dwTypeData
[lpmii
->cch
-1]=0;
766 *lpmii
= *(MENUITEMINFO
*)&tmp
; // copy results
767 lpmii
->cbSize
=osz
; // restore old stuff
768 lpmii
->dwTypeData
= otd
;
776 return GetMenuItemInfoA(hMenu
,uItem
,fByPosition
,lpmii
);
780 FILE *fopenUTF8(const char *filename
, const char *mode
)
782 if (WDL_HasUTF8(filename
) AND_IS_NOT_WIN9X
)
784 MBTOWIDE(wbuf
,filename
);
790 MultiByteToWideChar(CP_UTF8
,0,mode
,-1,tb
,32);
791 rv
=tb
[0] ? _wfopen(wbuf
,tb
) : NULL
;
796 return fopen(filename
,mode
);
799 int statUTF8(const char *filename
, struct stat
*buffer
)
801 if (WDL_HasUTF8(filename
) AND_IS_NOT_WIN9X
)
803 MBTOWIDE(wbuf
,filename
);
806 int rv
=_wstat(wbuf
,(struct _stat
*)buffer
);
815 return stat(filename
,buffer
);
818 LPSTR
GetCommandParametersUTF8()
822 LPWSTR w
=GetCommandLineW();
824 szneeded
= WideCharToMultiByte(CP_UTF8
,0,w
,-1,NULL
,0,NULL
,NULL
);
825 if (szneeded
<1) return NULL
;
826 buf
= (char *)malloc(szneeded
+10);
827 if (!buf
) return NULL
;
828 if (WideCharToMultiByte(CP_UTF8
,0,w
,-1,buf
,szneeded
+9,NULL
,NULL
)<1) return NULL
;
829 while (*buf
== ' ') buf
++;
833 while (*buf
&& *buf
!= '\"') buf
++;
837 while (*buf
&& *buf
!= ' ') buf
++;
840 while (*buf
== ' ') buf
++;
841 if (*buf
) return buf
;
846 int GetKeyNameTextUTF8(LONG lParam
, LPTSTR lpString
, int nMaxCount
)
848 if (!lpString
) return 0;
849 if (nMaxCount
>0 AND_IS_NOT_WIN9X
)
851 WIDETOMB_ALLOC(wbuf
, nMaxCount
);
854 const int v
= GetKeyNameTextW(lParam
,wbuf
,(int) (wbuf_size
/sizeof(WCHAR
)));
859 if (!WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,lpString
,nMaxCount
,NULL
,NULL
))
860 lpString
[nMaxCount
-1]=0;
864 return v
? (int)strlen(lpString
) : 0;
867 return GetKeyNameTextA(lParam
,lpString
,nMaxCount
);
870 HINSTANCE
ShellExecuteUTF8(HWND hwnd
, LPCTSTR lpOp
, LPCTSTR lpFile
, LPCTSTR lpParm
, LPCTSTR lpDir
, INT nShowCmd
)
872 if (IS_NOT_WIN9X_AND (WDL_HasUTF8(lpOp
)||WDL_HasUTF8(lpFile
)||WDL_HasUTF8(lpParm
)||WDL_HasUTF8(lpDir
)))
875 WCHAR
*p1
=lpOp
? WDL_UTF8ToWC(lpOp
,0,0,&sz
) : NULL
;
876 WCHAR
*p2
=lpFile
? WDL_UTF8ToWC(lpFile
,0,0,&sz
) : NULL
;
877 WCHAR
*p3
=lpParm
? WDL_UTF8ToWC(lpParm
,0,0,&sz
) : NULL
;
878 WCHAR
*p4
=lpDir
? WDL_UTF8ToWC(lpDir
,0,0,&sz
) : NULL
;
879 HINSTANCE rv
= p2
? ShellExecuteW(hwnd
,p1
,p2
,p3
,p4
,nShowCmd
) : NULL
;
886 return ShellExecuteA(hwnd
,lpOp
,lpFile
,lpParm
,lpDir
,nShowCmd
);
889 BOOL
GetUserNameUTF8(LPTSTR lpString
, LPDWORD nMaxCount
)
891 if (IS_NOT_WIN9X_AND lpString
&& nMaxCount
)
893 WIDETOMB_ALLOC(wtmp
,*nMaxCount
);
896 DWORD sz
=(DWORD
)(wtmp_size
/sizeof(WCHAR
));
897 BOOL r
= GetUserNameW(wtmp
, &sz
);
898 if (r
&& (!*nMaxCount
|| (!WideCharToMultiByte(CP_UTF8
,0,wtmp
,-1,lpString
,*nMaxCount
,NULL
,NULL
) && GetLastError()==ERROR_INSUFFICIENT_BUFFER
)))
900 if (*nMaxCount
>0) lpString
[*nMaxCount
-1]=0;
901 *nMaxCount
=(int)wcslen(wtmp
)+1;
912 return GetUserNameA(lpString
, nMaxCount
);
915 BOOL
GetComputerNameUTF8(LPTSTR lpString
, LPDWORD nMaxCount
)
917 if (IS_NOT_WIN9X_AND lpString
&& nMaxCount
)
919 WIDETOMB_ALLOC(wtmp
,*nMaxCount
);
922 DWORD sz
=(DWORD
)(wtmp_size
/sizeof(WCHAR
));
923 BOOL r
= GetComputerNameW(wtmp
, &sz
);
924 if (r
&& (!*nMaxCount
|| (!WideCharToMultiByte(CP_UTF8
,0,wtmp
,-1,lpString
,*nMaxCount
,NULL
,NULL
) && GetLastError()==ERROR_INSUFFICIENT_BUFFER
)))
926 if (*nMaxCount
>0) lpString
[*nMaxCount
-1]=0;
927 *nMaxCount
=(int)wcslen(wtmp
)+1;
938 return GetComputerNameA(lpString
, nMaxCount
);
941 #define MBTOWIDE_NULLOK(symbase, src) \
942 int symbase##_size; \
943 WCHAR symbase##_buf[256]; \
944 WCHAR *symbase = (src)==NULL ? NULL : ((symbase##_size=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,NULL,0)) >= 248 ? (WCHAR *)malloc(symbase##_size * sizeof(WCHAR) + 10) : symbase##_buf); \
945 int symbase##_ok = symbase ? (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,symbase,symbase##_size < 1 ? 256 : symbase##_size)) : (src)==NULL
948 // these only bother using Wide versions if the filename has wide chars
950 #define PROFILESTR_COMMON \
951 if (IS_NOT_WIN9X_AND fnStr && WDL_HasUTF8(fnStr)) \
953 MBTOWIDE(wfn,fnStr); \
954 MBTOWIDE_NULLOK(wapp,appStr); \
955 MBTOWIDE_NULLOK(wkey,keyStr); \
956 if (wfn_ok && wapp_ok && wkey_ok) {
958 #define PROFILESTR_COMMON_END \
959 MBTOWIDE_FREE(wfn); \
960 MBTOWIDE_FREE(wapp); \
961 MBTOWIDE_FREE(wkey); \
965 UINT
GetPrivateProfileIntUTF8(LPCTSTR appStr
, LPCTSTR keyStr
, INT def
, LPCTSTR fnStr
)
969 const UINT rv
= GetPrivateProfileIntW(wapp
,wkey
,def
,wfn
);
971 PROFILESTR_COMMON_END
972 return GetPrivateProfileIntA(appStr
,keyStr
,def
,fnStr
);
975 DWORD
GetPrivateProfileStringUTF8(LPCTSTR appStr
, LPCTSTR keyStr
, LPCTSTR defStr
, LPTSTR retStr
, DWORD nSize
, LPCTSTR fnStr
)
978 MBTOWIDE_NULLOK(wdef
, defStr
);
980 WIDETOMB_ALLOC(buf
, nSize
);
982 DWORD rv
= GetPrivateProfileStringW(wapp
,wkey
,wdef
,buf
,(DWORD
) (buf_size
/ sizeof(WCHAR
)),wfn
);
984 const DWORD nullsz
= (!wapp
|| !wkey
) ? 2 : 1;
987 memset(retStr
,0,nSize
);
992 // rv does not include null character(s)
993 if (rv
>0) rv
= WideCharToMultiByte(CP_UTF8
,0,buf
,rv
,retStr
,nSize
-nullsz
,NULL
,NULL
);
994 if (rv
> nSize
-nullsz
) rv
=nSize
-nullsz
;
995 memset(retStr
+ rv
,0,nullsz
);
999 PROFILESTR_COMMON_END
1000 return GetPrivateProfileStringA(appStr
,keyStr
,defStr
,retStr
,nSize
,fnStr
);
1003 BOOL
WritePrivateProfileStringUTF8(LPCTSTR appStr
, LPCTSTR keyStr
, LPCTSTR str
, LPCTSTR fnStr
)
1006 MBTOWIDE_NULLOK(wval
, str
);
1008 const BOOL rv
= WritePrivateProfileStringW(wapp
,wkey
,wval
,wfn
);
1010 MBTOWIDE_FREE(wval
);
1012 PROFILESTR_COMMON_END
1013 return WritePrivateProfileStringA(appStr
,keyStr
,str
,fnStr
);
1016 BOOL
GetPrivateProfileStructUTF8(LPCTSTR appStr
, LPCTSTR keyStr
, LPVOID pStruct
, UINT uSize
, LPCTSTR fnStr
)
1020 const BOOL rv
= GetPrivateProfileStructW(wapp
,wkey
,pStruct
,uSize
,wfn
);
1022 PROFILESTR_COMMON_END
1023 return GetPrivateProfileStructA(appStr
,keyStr
,pStruct
,uSize
,fnStr
);
1026 BOOL
WritePrivateProfileStructUTF8(LPCTSTR appStr
, LPCTSTR keyStr
, LPVOID pStruct
, UINT uSize
, LPCTSTR fnStr
)
1030 const BOOL rv
= WritePrivateProfileStructW(wapp
,wkey
,pStruct
,uSize
,wfn
);
1032 PROFILESTR_COMMON_END
1033 return WritePrivateProfileStructA(appStr
,keyStr
,pStruct
,uSize
,fnStr
);
1037 #undef PROFILESTR_COMMON
1038 #undef PROFILESTR_COMMON_END
1041 BOOL
CreateProcessUTF8(LPCTSTR lpApplicationName
,
1042 LPTSTR lpCommandLine
,
1043 LPSECURITY_ATTRIBUTES lpProcessAttributes
, LPSECURITY_ATTRIBUTES lpThreadAttributes
,
1044 BOOL bInheritHandles
,
1045 DWORD dwCreationFlags
, LPVOID lpEnvironment
, // pointer to new environment block
1046 LPCTSTR lpCurrentDirectory
,
1047 LPSTARTUPINFO lpStartupInfo
,
1048 LPPROCESS_INFORMATION lpProcessInformation
)
1051 if (IS_NOT_WIN9X_AND (
1052 WDL_HasUTF8(lpApplicationName
) ||
1053 WDL_HasUTF8(lpCommandLine
) ||
1054 WDL_HasUTF8(lpCurrentDirectory
)
1058 MBTOWIDE_NULLOK(appn
, lpApplicationName
);
1059 MBTOWIDE_NULLOK(cmdl
, lpCommandLine
);
1060 MBTOWIDE_NULLOK(curd
, lpCurrentDirectory
);
1062 if (appn_ok
&& cmdl_ok
&& curd_ok
)
1065 WCHAR
*free1
=NULL
, *free2
=NULL
;
1066 char *save1
=NULL
, *save2
=NULL
;
1068 if (lpStartupInfo
&& lpStartupInfo
->cb
>= sizeof(STARTUPINFO
))
1070 if (lpStartupInfo
->lpDesktop
)
1071 lpStartupInfo
->lpDesktop
= (char *) (free1
= WDL_UTF8ToWC(save1
= lpStartupInfo
->lpDesktop
,FALSE
,0,NULL
));
1072 if (lpStartupInfo
->lpTitle
)
1073 lpStartupInfo
->lpTitle
= (char*) (free2
= WDL_UTF8ToWC(save2
= lpStartupInfo
->lpTitle
,FALSE
,0,NULL
));
1076 rv
=CreateProcessW(appn
,cmdl
,lpProcessAttributes
,lpThreadAttributes
,bInheritHandles
,dwCreationFlags
,
1077 lpEnvironment
,curd
,(STARTUPINFOW
*)lpStartupInfo
,lpProcessInformation
);
1079 if (lpStartupInfo
&& lpStartupInfo
->cb
>= sizeof(STARTUPINFO
))
1081 lpStartupInfo
->lpDesktop
= save1
;
1082 lpStartupInfo
->lpTitle
= save2
;
1087 MBTOWIDE_FREE(appn
);
1088 MBTOWIDE_FREE(cmdl
);
1089 MBTOWIDE_FREE(curd
);
1092 MBTOWIDE_FREE(appn
);
1093 MBTOWIDE_FREE(cmdl
);
1094 MBTOWIDE_FREE(curd
);
1097 return CreateProcessA(lpApplicationName
,lpCommandLine
,lpProcessAttributes
,lpThreadAttributes
,bInheritHandles
,dwCreationFlags
,lpEnvironment
,lpCurrentDirectory
,lpStartupInfo
,lpProcessInformation
);
1101 #if (defined(WDL_WIN32_UTF8_IMPL_NOTSTATIC) || defined(WDL_WIN32_UTF8_IMPL_STATICHOOKS)) && !defined(WDL_WIN32_UTF8_NO_UI_IMPL)
1103 static LRESULT WINAPI
cb_newProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1105 WNDPROC oldproc
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1106 if (!oldproc
) return 0;
1108 if (msg
==WM_NCDESTROY
)
1110 SetWindowLongPtr(hwnd
, GWLP_WNDPROC
,(INT_PTR
)oldproc
);
1111 RemoveProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1112 RemoveProp(hwnd
,WDL_UTF8_OLDPROCPROP
"W");
1114 else if (msg
== CB_ADDSTRING
|| msg
== CB_INSERTSTRING
|| msg
== LB_ADDSTRING
|| msg
== LB_INSERTSTRING
)
1116 char *str
=(char*)lParam
;
1117 if (lParam
&& WDL_HasUTF8(str
))
1122 WNDPROC oldprocW
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
"W");
1123 LRESULT rv
=CallWindowProcW(oldprocW
? oldprocW
: oldproc
,hwnd
,msg
,wParam
,(LPARAM
)wbuf
);
1124 MBTOWIDE_FREE(wbuf
);
1128 MBTOWIDE_FREE(wbuf
);
1131 else if ((msg
== CB_GETLBTEXT
|| msg
== LB_GETTEXT
) && lParam
)
1133 WNDPROC oldprocW
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
"W");
1134 LRESULT l
= CallWindowProcW(oldprocW
? oldprocW
: oldproc
,hwnd
,msg
== CB_GETLBTEXT
? CB_GETLBTEXTLEN
: LB_GETTEXTLEN
,wParam
,0);
1138 WIDETOMB_ALLOC(tmp
,l
+1);
1141 LRESULT rv
=CallWindowProcW(oldprocW
? oldprocW
: oldproc
,hwnd
,msg
,wParam
,(LPARAM
)tmp
);
1145 rv
=WideCharToMultiByte(CP_UTF8
,0,tmp
,-1,(char *)lParam
,((int)l
)*4 + 32,NULL
,NULL
);
1154 else if (msg
== CB_GETLBTEXTLEN
|| msg
== LB_GETTEXTLEN
)
1156 WNDPROC oldprocW
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
"W");
1157 return CallWindowProcW(oldprocW
? oldprocW
: oldproc
,hwnd
,msg
,wParam
,lParam
) * 4 + 32; // make sure caller allocates a lot extra
1160 return CallWindowProc(oldproc
,hwnd
,msg
,wParam
,lParam
);
1163 void WDL_UTF8_HookComboBox(HWND h
)
1166 #ifdef WDL_SUPPORT_WIN9X
1167 GetVersion()>=0x80000000||
1169 GetProp(h
,WDL_UTF8_OLDPROCPROP
)) return;
1170 SetProp(h
,WDL_UTF8_OLDPROCPROP
"W",(HANDLE
)GetWindowLongPtrW(h
,GWLP_WNDPROC
));
1171 SetProp(h
,WDL_UTF8_OLDPROCPROP
,(HANDLE
)SetWindowLongPtr(h
,GWLP_WNDPROC
,(INT_PTR
)cb_newProc
));
1173 if (!s_combobox_atom
) s_combobox_atom
= (ATOM
)GetClassWord(h
,GCW_ATOM
);
1176 void WDL_UTF8_HookListBox(HWND h
)
1178 WDL_UTF8_HookComboBox(h
);
1181 static LRESULT WINAPI
tc_newProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1183 WNDPROC oldproc
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1184 if (!oldproc
) return 0;
1186 if (msg
==WM_NCDESTROY
)
1188 SetWindowLongPtr(hwnd
, GWLP_WNDPROC
,(INT_PTR
)oldproc
);
1189 RemoveProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1191 else if (msg
== TCM_INSERTITEMA
)
1193 LPTCITEM pItem
= (LPTCITEM
) lParam
;
1195 if (pItem
&& (str
=pItem
->pszText
) && (pItem
->mask
&TCIF_TEXT
) && WDL_HasUTF8(str
))
1201 pItem
->pszText
=(char*)wbuf
; // set new buffer
1202 rv
=CallWindowProc(oldproc
,hwnd
,TCM_INSERTITEMW
,wParam
,lParam
);
1203 pItem
->pszText
= str
; // restore old pointer
1204 MBTOWIDE_FREE(wbuf
);
1208 MBTOWIDE_FREE(wbuf
);
1213 return CallWindowProc(oldproc
,hwnd
,msg
,wParam
,lParam
);
1217 static LRESULT WINAPI
tv_newProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1219 WNDPROC oldproc
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1220 if (!oldproc
) return 0;
1222 if (msg
==WM_NCDESTROY
)
1224 SetWindowLongPtr(hwnd
, GWLP_WNDPROC
,(INT_PTR
)oldproc
);
1225 RemoveProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1227 else if (msg
== TVM_INSERTITEMA
|| msg
== TVM_SETITEMA
)
1229 LPTVITEM pItem
= msg
== TVM_INSERTITEMA
? &((LPTVINSERTSTRUCT
)lParam
)->item
: (LPTVITEM
) lParam
;
1231 if (pItem
&& (str
=pItem
->pszText
) && (pItem
->mask
&TVIF_TEXT
) && WDL_HasUTF8(str
))
1237 pItem
->pszText
=(char*)wbuf
; // set new buffer
1238 rv
=CallWindowProc(oldproc
,hwnd
,msg
== TVM_INSERTITEMA
? TVM_INSERTITEMW
: TVM_SETITEMW
,wParam
,lParam
);
1239 pItem
->pszText
= str
; // restore old pointer
1240 MBTOWIDE_FREE(wbuf
);
1244 MBTOWIDE_FREE(wbuf
);
1247 else if (msg
==TVM_GETITEMA
)
1249 LPTVITEM pItem
= (LPTVITEM
) lParam
;
1251 if (pItem
&& (pItem
->mask
& TVIF_TEXT
) && (obuf
=pItem
->pszText
) && pItem
->cchTextMax
> 3)
1253 WIDETOMB_ALLOC(wbuf
,pItem
->cchTextMax
);
1257 int oldsz
=pItem
->cchTextMax
;
1260 pItem
->cchTextMax
=(int) (wbuf_size
/sizeof(WCHAR
));
1261 pItem
->pszText
= (char *)wbuf
;
1262 rv
=CallWindowProc(oldproc
,hwnd
,TVM_GETITEMW
,wParam
,lParam
);
1264 if (!WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,obuf
,oldsz
,NULL
,NULL
))
1267 pItem
->cchTextMax
=oldsz
;
1268 pItem
->pszText
=obuf
;
1269 WIDETOMB_FREE(wbuf
);
1271 if (obuf
[0]) return rv
;
1276 return CallWindowProc(oldproc
,hwnd
,msg
,wParam
,lParam
);
1279 static LRESULT WINAPI
lv_newProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1281 WNDPROC oldproc
= (WNDPROC
)GetProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1282 if (!oldproc
) return 0;
1284 if (msg
==WM_NCDESTROY
)
1286 SetWindowLongPtr(hwnd
, GWLP_WNDPROC
,(INT_PTR
)oldproc
);
1287 RemoveProp(hwnd
,WDL_UTF8_OLDPROCPROP
);
1289 else if (msg
== LVM_INSERTCOLUMNA
|| msg
==LVM_SETCOLUMNA
)
1291 LPLVCOLUMNA pCol
= (LPLVCOLUMNA
) lParam
;
1293 if (pCol
&& (str
=pCol
->pszText
) && (pCol
->mask
& LVCF_TEXT
) && WDL_HasUTF8(str
))
1299 pCol
->pszText
=(char*)wbuf
; // set new buffer
1300 rv
=CallWindowProc(oldproc
,hwnd
,msg
==LVM_INSERTCOLUMNA
?LVM_INSERTCOLUMNW
:LVM_SETCOLUMNW
,wParam
,lParam
);
1301 pCol
->pszText
= str
; // restore old pointer
1302 MBTOWIDE_FREE(wbuf
);
1308 else if (msg
== LVM_INSERTITEMA
|| msg
== LVM_SETITEMA
|| msg
== LVM_SETITEMTEXTA
)
1310 LPLVITEMA pItem
= (LPLVITEMA
) lParam
;
1312 if (pItem
&& (str
=pItem
->pszText
) && (msg
==LVM_SETITEMTEXTA
|| (pItem
->mask
&LVIF_TEXT
)) && WDL_HasUTF8(str
))
1318 pItem
->pszText
=(char*)wbuf
; // set new buffer
1319 rv
=CallWindowProc(oldproc
,hwnd
,msg
== LVM_INSERTITEMA
? LVM_INSERTITEMW
: msg
== LVM_SETITEMA
? LVM_SETITEMW
: LVM_SETITEMTEXTW
,wParam
,lParam
);
1320 pItem
->pszText
= str
; // restore old pointer
1321 MBTOWIDE_FREE(wbuf
);
1325 MBTOWIDE_FREE(wbuf
);
1328 else if (msg
==LVM_GETITEMA
||msg
==LVM_GETITEMTEXTA
)
1330 LPLVITEMA pItem
= (LPLVITEMA
) lParam
;
1332 if (pItem
&& (msg
== LVM_GETITEMTEXTA
|| (pItem
->mask
& LVIF_TEXT
)) && (obuf
=pItem
->pszText
) && pItem
->cchTextMax
> 3)
1334 WIDETOMB_ALLOC(wbuf
,pItem
->cchTextMax
);
1338 int oldsz
=pItem
->cchTextMax
;
1341 pItem
->cchTextMax
=(int) (wbuf_size
/sizeof(WCHAR
));
1342 pItem
->pszText
= (char *)wbuf
;
1343 rv
=CallWindowProc(oldproc
,hwnd
,msg
==LVM_GETITEMTEXTA
? LVM_GETITEMTEXTW
: LVM_GETITEMW
,wParam
,lParam
);
1345 if (!WideCharToMultiByte(CP_UTF8
,0,wbuf
,-1,obuf
,oldsz
,NULL
,NULL
))
1348 pItem
->cchTextMax
=oldsz
;
1349 pItem
->pszText
=obuf
;
1350 WIDETOMB_FREE(wbuf
);
1352 if (obuf
[0]) return rv
;
1357 return CallWindowProc(oldproc
,hwnd
,msg
,wParam
,lParam
);
1360 void WDL_UTF8_HookListView(HWND h
)
1363 #ifdef WDL_SUPPORT_WIN9X
1364 GetVersion()>=0x80000000||
1366 GetProp(h
,WDL_UTF8_OLDPROCPROP
)) return;
1367 SetProp(h
,WDL_UTF8_OLDPROCPROP
,(HANDLE
)SetWindowLongPtr(h
,GWLP_WNDPROC
,(INT_PTR
)lv_newProc
));
1370 void WDL_UTF8_HookTreeView(HWND h
)
1373 #ifdef WDL_SUPPORT_WIN9X
1374 GetVersion()>=0x80000000||
1376 GetProp(h
,WDL_UTF8_OLDPROCPROP
)) return;
1378 SetProp(h
,WDL_UTF8_OLDPROCPROP
,(HANDLE
)SetWindowLongPtr(h
,GWLP_WNDPROC
,(INT_PTR
)tv_newProc
));
1381 void WDL_UTF8_HookTabCtrl(HWND h
)
1384 #ifdef WDL_SUPPORT_WIN9X
1385 GetVersion()>=0x80000000||
1387 GetProp(h
,WDL_UTF8_OLDPROCPROP
)) return;
1389 SetProp(h
,WDL_UTF8_OLDPROCPROP
,(HANDLE
)SetWindowLongPtr(h
,GWLP_WNDPROC
,(INT_PTR
)tc_newProc
));
1392 void WDL_UTF8_ListViewConvertDispInfoToW(void *_di
)
1394 NMLVDISPINFO
*di
= (NMLVDISPINFO
*)_di
;
1395 if (di
&& (di
->item
.mask
& LVIF_TEXT
) && di
->item
.pszText
&& di
->item
.cchTextMax
>0)
1397 char tmp_buf
[1024], *tmp
=tmp_buf
;
1398 char *src
= di
->item
.pszText
;
1400 if (strlen(src
) < 1024) strcpy(tmp
,src
);
1401 else tmp
= strdup(src
);
1403 if (!MultiByteToWideChar(CP_UTF8
,MB_ERR_INVALID_CHARS
,tmp
,-1,(LPWSTR
)di
->item
.pszText
,di
->item
.cchTextMax
))
1405 if (GetLastError()==ERROR_INSUFFICIENT_BUFFER
)
1407 ((WCHAR
*)di
->item
.pszText
)[di
->item
.cchTextMax
-1] = 0;
1411 if (!MultiByteToWideChar(CP_ACP
,MB_ERR_INVALID_CHARS
,tmp
,-1,(LPWSTR
)di
->item
.pszText
,di
->item
.cchTextMax
))
1412 ((WCHAR
*)di
->item
.pszText
)[di
->item
.cchTextMax
-1] = 0;
1416 if (tmp
!=tmp_buf
) free(tmp
);