After more 2 000 000 (two million) views on forum for 1.5.0.x development versions... and 1.6.1.0, 1.6.3.0-dev versions
A new stable version, UltraVNC 1.6.4.0 and UltraVNC SC 1.6.4.0 have been released: https://forum.uvnc.com/viewtopic.php?t=38095
Feedback is always welcome

2026-04-01: After 1.7.x, 1.8.0.X release builds need tests and feedback: https://forum.uvnc.com/viewtopic.php?t=38158

2026-03-11: CVE-2026-3787 Clarification: https://forum.uvnc.com/viewtopic.php?t=38155

2025-12-02: We need help: English Wikipedia UltraVNC page has been requested to deletion: https://forum.uvnc.com/viewtopic.php?t=38127
Any help is welcome to improve the UltraVNC page and/or to comment on the Wikipedia Talk page

2025-05-06: Forum password change request: https://forum.uvnc.com/viewtopic.php?t=38078

2023-09-21: Important: Please update to latest version before to create a reply, a topic or an issue: https://forum.uvnc.com/viewtopic.php?t=37864

Development: UltraVNC development is always here... Any help is welcome
Feedback is welcome

Unicode support for UI

Single Click discussions / bugs
Post Reply
badaa
Posts: 1
Joined: 2016-08-26 10:27

Unicode support for UI

Post by badaa »

Hi,
I just wanted to have SC in my native language (Mongolian) also UTF-8 encoded charset. PChelpware has same issue. See below.
Image
Then I have downloaded SC source, the latest public available version "SC update 2015(Feb)" and checked up.
The project was configured with "Multi-Byte Character Set" which leads the problem. If I have to do things right way, I need to configure it as use Unicode. In this case I got huge number of errors that I have to correct. I fixed until Socket functions and gave up, because I don't want to change low level socket function, which may affect performance. And I had limited time also only one day to do this task!
Then I have done some small hack which converts only UI string into Unicode. The patch:

Code: Select all

Left file: \Z_SC_2015(Feb)\Z_SC\winvnc\winvnc\vncmenu.h
Right file: \Z_SC\winvnc\winvnc\vncmenu.h
51a52,54
> //const wchar_t *toUnicode(const char *str);
> int toUnicode(wchar_t *buffer, const char *str);
> 
89c92
< 	NOTIFYICONDATA	m_nid;
---
> 	NOTIFYICONDATAW	m_nid;

Code: Select all

Left file: \Z_SC_2015(Feb)\Z_SC\winvnc\winvnc\vncmenu.cpp
Right file: \Z_SC\winvnc\winvnc\vncmenu.cpp
62,69c62,69
< extern char		Balloon1Title[150];
< extern char		Balloon2Title[150];
< extern char		Balloon1A[150];
< extern char		Balloon1B[150];
< extern char		Balloon1C[150];
< extern char		Balloon2A[150];
< extern char		Balloon2B[150];
< extern char		Balloon2C[150];
---
> extern wchar_t		Balloon1Title[150];
> extern wchar_t		Balloon2Title[150];
> extern wchar_t		Balloon1A[150];
> extern wchar_t		Balloon1B[150];
> extern wchar_t		Balloon1C[150];
> extern wchar_t		Balloon2A[150];
> extern wchar_t		Balloon2B[150];
> extern wchar_t		Balloon2C[150];
370a371,378
> int toUnicode(wchar_t *buffer, const char *str) {
> 	int lenW =  MultiByteToWideChar(CP_UTF8 , 0 , str , -1, NULL , 0 );
> 	//wchar_t *wstr = SysAllocStringLen(0, lenW);
> 	//wchar_t* wstr = new wchar_t[lenW];
> 	MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer, lenW);
> 	return lenW;
> }
> 
590c598
< 	if (LoadString(hAppInstance, ID_WINVNC, m_nid.szTip, sizeof(m_nid.szTip)))
---
> 	if (LoadStringW(hAppInstance, ID_WINVNC, m_nid.szTip, sizeof(m_nid.szTip)))
598c606
< 	    strncat(m_nid.szTip, " - ", (sizeof(m_nid.szTip)-1)-strlen(m_nid.szTip));
---
> 	    wcsncat(m_nid.szTip, L" - ", (sizeof(m_nid.szTip)-1)-wcslen(m_nid.szTip));
602c610
< 		unsigned long tiplen = strlen(m_nid.szTip);
---
> 		unsigned long tiplen = wcslen(m_nid.szTip);
609c617
< 		strncat(m_nid.szTip, " connecting", (sizeof(m_nid.szTip)-1)-strlen(m_nid.szTip));
---
> 		wcsncat(m_nid.szTip, L" connecting", (sizeof(m_nid.szTip)-1)-wcslen(m_nid.szTip));
612c620
< 	if (strcmp(Balloon1Title,"")!=NULL)if (nport!=0 && (connect_counter%5==0 || connect_counter==1))
---
> 	if (wcscmp(Balloon1Title,L"")!=NULL)if (nport!=0 && (connect_counter%5==0 || connect_counter==1))
614,619c622,627
< 	char all[450];
< 	strcpy(all,Balloon1A);
< 	strcat(all,"\n");
< 	strcat(all,Balloon1B);
< 	strcat(all,"\n");
< 	strcat(all,Balloon1C);
---
> 	wchar_t all[450];
> 	wcscpy(all,Balloon1A);
> 	wcscat(all,L"\n");
> 	wcscat(all,Balloon1B);
> 	wcscat(all,L"\n");
> 	wcscat(all,Balloon1C);
621,622c629,630
< 	strncpy(m_nid.szInfo,all, 256);
< 	strncpy(m_nid.szInfoTitle,Balloon1Title,64);
---
> 	wcsncpy(m_nid.szInfo,all, 256);
> 	wcsncpy(m_nid.szInfoTitle,Balloon1Title,64);
626c634
< 	if (strcmp(Balloon2Title,"")!=NULL)if (connected==1 && connect_counter%10==0)
---
> 	if (wcscmp(Balloon2Title,L"")!=NULL)if (connected==1 && connect_counter%10==0)
629,634c637,642
< 	char all[450];
< 	strcpy(all,Balloon2A);
< 	strcat(all,"\n");
< 	strcat(all,Balloon2B);
< 	strcat(all,"\n");
< 	strcat(all,Balloon2C);
---
> 	wchar_t all[450];
> 	wcscpy(all,Balloon2A);
> 	wcscat(all,L"\n");
> 	wcscat(all,Balloon2B);
> 	wcscat(all,L"\n");
> 	wcscat(all,Balloon2C);
636,637c644,645
< 	strncpy(m_nid.szInfo,all, 256);
< 	strncpy(m_nid.szInfoTitle,Balloon2Title,64);
---
> 	wcsncpy(m_nid.szInfo,all, 256);
> 	wcsncpy(m_nid.szInfoTitle,Balloon2Title,64);
643c651
< 	if (Shell_NotifyIcon(msg, &m_nid))
---
> 	if (Shell_NotifyIconW(msg, &m_nid))

Code: Select all

Left file: \Z_SC_2015(Feb)\Z_SC\winvnc\winvnc\winvnc.cpp
Right file: \Z_SC\winvnc\winvnc\winvnc.cpp
73c73
< char		g_var_20[25][50];
---
> wchar_t		g_var_20[25][50];
76,84c76,84
< char		TextTop[150]="";
< char		TextMiddle[150]="";
< char		TextBottom[150]="";
< char		TextRTop[150]="";
< char		TextRBottom[150]="";
< char		TextButton[150]="";
< char		TextCButton[150]="";
< char		TextRMiddle[150]="";
< char		TextTitle[150]="";
---
> wchar_t		TextTop[150]=L"";
> wchar_t		TextMiddle[150]=L"";
> wchar_t		TextBottom[150]=L"";
> wchar_t		TextRTop[150]=L"";
> wchar_t		TextRBottom[150]=L"";
> wchar_t		TextButton[150]=L"";
> wchar_t		TextCButton[150]=L"";
> wchar_t		TextRMiddle[150]=L"";
> wchar_t		TextTitle[150]=L"";
87,94c87,94
< char		Balloon1Title[150]="";
< char		Balloon2Title[150]="";
< char		Balloon1A[150]="";
< char		Balloon1B[150]="";
< char		Balloon1C[150]="";
< char		Balloon2A[150]="";
< char		Balloon2B[150]="";
< char		Balloon2C[150]="";
---
> wchar_t		Balloon1Title[150]=L"";
> wchar_t		Balloon2Title[150]=L"";
> wchar_t		Balloon1A[150]=L"";
> wchar_t		Balloon1B[150]=L"";
> wchar_t		Balloon1C[150]=L"";
> wchar_t		Balloon2A[150]=L"";
> wchar_t		Balloon2B[150]=L"";
> wchar_t		Balloon2C[150]=L"";
108c108
< LVITEM LvItem;  // ListView Item struct
---
> LVITEMW LvItem;  // ListView Item struct
173c173
< 				  LvItem.pszText=Text;
---
> 				  LvItem.pszText=(LPWSTR)Text;
218c218
<                     LvItem.pszText=text;
---
>                     LvItem.pszText=(LPWSTR)text;
269c269
< 				LvItem.pszText="Item 0"; // Text to display (can be from a char variable) (Items)
---
> 				LvItem.pszText=L"Item 0"; // Text to display (can be from a char variable) (Items)
306d305
< 
309,311c308,312
< 								strcpy(g_var_20[i],"");
< 								strncpy(g_var_20[i],myline,strlen(myline)-1);
< 								iItem=SendMessage(hList,LVM_GETITEMCOUNT,0,0);
---
> 								/*strcpy(g_var_20[i],"");
> 								strncpy(g_var_20[i],myline,strlen(myline)-1);*/
> 								toUnicode(g_var_20[i], myline);
> 
> 								iItem=SendMessageW(hList,LVM_GETITEMCOUNT,0,0);
315c316
< 								SendMessage(hList,LVM_INSERTITEM,0,(LPARAM)&LvItem);
---
> 								SendMessageW(hList,LVM_INSERTITEMW,0,(LPARAM)&LvItem);
324,325c325,327
< 								strncpy(TextTop,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_TEXTTOP, WM_SETTEXT, 0, (LONG)TextTop);
---
> 								toUnicode(TextTop, myline);
> 								//strncpy(TextTop,myline,strlen(myline)-1);
> 								SendDlgItemMessageW(hWnd,IDC_TEXTTOP, WM_SETTEXT, 0, (LONG)TextTop);
330,331c332,334
< 								strncpy(TextMiddle,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_TEXTMIDDLE, WM_SETTEXT, 0, (LONG)TextMiddle);
---
> 								//strncpy(TextMiddle,myline,strlen(myline)-1);
> 								toUnicode(TextMiddle, myline);
> 								SendDlgItemMessageW(hWnd,IDC_TEXTMIDDLE, WM_SETTEXT, 0, (LONG)TextMiddle);
336,337c339,341
< 								strncpy(TextBottom,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_TEXTBOTTOM, WM_SETTEXT, 0, (LONG)TextBottom);
---
> 								//strncpy(TextBottom,myline,strlen(myline)-1);
> 								toUnicode(TextBottom, myline);
> 								SendDlgItemMessageW(hWnd,IDC_TEXTBOTTOM, WM_SETTEXT, 0, (LONG)TextBottom);
342,343c346,348
< 								strncpy(TextRTop,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_TEXTRICHTTOP, WM_SETTEXT, 0, (LONG)TextRTop);
---
> 								//strncpy(TextRTop,myline,strlen(myline)-1);
> 								toUnicode(TextRTop, myline);
> 								SendDlgItemMessageW(hWnd,IDC_TEXTRICHTTOP, WM_SETTEXT, 0, (LONG)TextRTop);
348,349c353,355
< 								strncpy(TextRBottom,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_TEXTRIGHTBOTTOM, WM_SETTEXT, 0, (LONG)TextRBottom);
---
> 								//strncpy(TextRBottom,myline,strlen(myline)-1);
> 								toUnicode(TextRBottom, myline);
> 								SendDlgItemMessageW(hWnd,IDC_TEXTRIGHTBOTTOM, WM_SETTEXT, 0, (LONG)TextRBottom);
354,355c360,362
< 								strncpy(TextRMiddle,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_TEXTRIGHTMIDDLE, WM_SETTEXT, 0, (LONG)TextRMiddle);
---
> 								//strncpy(TextRMiddle,myline,strlen(myline)-1);
> 								toUnicode(TextRMiddle, myline);
> 								SendDlgItemMessageW(hWnd,IDC_TEXTRIGHTMIDDLE, WM_SETTEXT, 0, (LONG)TextRMiddle);
360c367,368
< 								strncpy(TextButton,myline,strlen(myline)-1);
---
> 								//strncpy(TextButton,myline,strlen(myline)-1);
> 								toUnicode(TextButton, myline);
363c371
< 								SendDlgItemMessage(hWnd,IDC_HELPWEB, WM_SETTEXT, 0, (LONG)TextButton);
---
> 								SendDlgItemMessageW(hWnd,IDC_HELPWEB, WM_SETTEXT, 0, (LONG)TextButton);
368,370c376,377
< 								strcpy(TextCButton,"");
< 								strncpy(TextCButton,myline,strlen(myline)-1);
< 								SendDlgItemMessage(hWnd,IDC_CLOSE, WM_SETTEXT, 0, (LONG)TextCButton);
---
> 								toUnicode(TextCButton, myline);
> 								SendDlgItemMessageW(hWnd,IDC_CLOSE, WM_SETTEXT, 0, (LONG)TextCButton);
375,377c382,385
< 								strcpy(TextTitle,myline);
< 								TextTitle[strlen(myline)-1]='\0';
< 								SetWindowText(hWnd,TextTitle);
---
> 								//strcpy(TextTitle,myline);
> 								//TextTitle[strlen(myline)-1]='\0';
> 								toUnicode(TextTitle, myline);
> 								SetWindowTextW(hWnd,TextTitle);
388,389c396,398
< 								strcpy(Balloon1Title,myline);
< 								Balloon1Title[strlen(myline)-1]='\0';
---
> 								//strcpy(Balloon1Title,myline);
> 								int len = toUnicode(Balloon1Title, myline);
> 								Balloon1Title[len-1]='\0';
393,394c402,404
< 								strcpy(Balloon1A,myline);
< 								Balloon1A[strlen(myline)-1]='\0';
---
> 								//strcpy(Balloon1A,myline);
> 								//Balloon1A[strlen(myline)-1]='\0';
> 								toUnicode(Balloon1A, myline);
398,399c408,410
< 								strcpy(Balloon1B,myline);
< 								Balloon1B[strlen(myline)-1]='\0';
---
> 								/*strcpy(Balloon1B,myline);
> 								Balloon1B[strlen(myline)-1]='\0';*/
> 								toUnicode(Balloon1B, myline);
403,404c414,416
< 								strcpy(Balloon1C,myline);
< 								Balloon1C[strlen(myline)-1]='\0';
---
> 								/*strcpy(Balloon1C,myline);
> 								Balloon1C[strlen(myline)-1]='\0';*/
> 								toUnicode(Balloon1C, myline);
409,410c421,423
< 								strcpy(Balloon2Title,myline);
< 								Balloon2Title[strlen(myline)-1]='\0';
---
> 								/*strcpy(Balloon2Title,myline);
> 								Balloon2Title[strlen(myline)-1]='\0';*/
> 								toUnicode(Balloon2Title, myline);
414,415c427,429
< 								strcpy(Balloon2A,myline);
< 								Balloon2A[strlen(myline)-1]='\0';
---
> 								/*strcpy(Balloon2A,myline);
> 								Balloon2A[strlen(myline)-1]='\0';*/
> 								toUnicode(Balloon2A, myline);
419,420c433,435
< 								strcpy(Balloon2B,myline);
< 								Balloon2B[strlen(myline)-1]='\0';
---
> 								/*strcpy(Balloon2B,myline);
> 								Balloon2B[strlen(myline)-1]='\0';*/
> 								toUnicode(Balloon2B, myline);
424,425c439,441
< 								strcpy(Balloon2C,myline);
< 								Balloon2C[strlen(myline)-1]='\0';
---
> 								/*strcpy(Balloon2C,myline);
> 								Balloon2C[strlen(myline)-1]='\0';*/
> 								toUnicode(Balloon2C, myline);
619c635
< 			DialogBoxParam(hInstance, MAKEINTRESOURCE(IDC_DIALOG), NULL, (DLGPROC)DialogProc,0);
---
> 			DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDC_DIALOG), NULL, (DLGPROC)DialogProc,0);
The result:
Image

PS: Where can I download latest version of SC source? The source https://sourceforge.net/p/ultravnc/code ... /UltraVNC/ seems very different. I want to check up some performance issues like mouse pointer etc.
lwc
40
40
Posts: 100
Joined: 2006-08-08 11:00

Re: Unicode support for UI

Post by lwc »

Did you ever find a solution for this? It's really unfortunate that in 2018 SC still doesn't support any language other than English.
User avatar
Rudi De Vos
Admin & Developer
Admin & Developer
Posts: 7010
Joined: 2004-04-23 10:21
Contact:

Re: Unicode support for UI

Post by Rudi De Vos »

Will do when time.
Uvnc is a hobby, i still have a daytime job.
UltraVNC links (join us on social networks):
- Website: https://uvnc.com/
- Forum: https://forum.uvnc.com/
- GitHub sourcecode: https://github.com/ultravnc/UltraVNC
- Mastodon: https://mastodon.social/@ultravnc
- Bluesky/AT Protocol: https://bsky.app/profile/ultravnc.bsky.social
- Facebook: https://www.facebook.com/ultravnc1
- X/Twitter: https://x.com/ultravnc1
- Reddit community: https://www.reddit.com/r/ultravnc
- OpenHub: https://openhub.net/p/ultravnc
- uvnc2me: https://uvnc2me.com/
Neustradamus
20
20
Posts: 55
Joined: 2011-03-26 20:22

Re: Unicode support for UI

Post by Neustradamus »

@badaa: UltraVNC is now on GitHub:
- https://github.com/ultravnc

Please look on it and create a PR :)
Last edited by Neustradamus on 2026-04-21 13:07, edited 1 time in total.
lwc
40
40
Posts: 100
Joined: 2006-08-08 11:00

Re: Unicode support for UI

Post by lwc »

Neustradamus wrote: 2020-09-26 01:50 @badaa: UltraVNC is now on GitHub:
Please look on it and create a PR :)
Sure, https://github.com/ultravnc/SC/issues/1

Just updating it was eventually fixed by integrating SC in the main UltraVNC in the v1.4 branch (first seen in 1.3.9-dev1).
Thanks!
Last edited by lwc on 2026-04-24 08:01, edited 1 time in total.
Neustradamus
20
20
Posts: 55
Joined: 2011-03-26 20:22

Re: Unicode support for UI

Post by Neustradamus »

@Rudi De Vos has done recent changes about Unicode into 1.8.x versions.
User avatar
Rudi De Vos
Admin & Developer
Admin & Developer
Posts: 7010
Joined: 2004-04-23 10:21
Contact:

Re: Unicode support for UI

Post by Rudi De Vos »

UI vncviewer is unicode, not winvnc.
SC is winvnc -> no unicode changes for UI
UltraVNC links (join us on social networks):
- Website: https://uvnc.com/
- Forum: https://forum.uvnc.com/
- GitHub sourcecode: https://github.com/ultravnc/UltraVNC
- Mastodon: https://mastodon.social/@ultravnc
- Bluesky/AT Protocol: https://bsky.app/profile/ultravnc.bsky.social
- Facebook: https://www.facebook.com/ultravnc1
- X/Twitter: https://x.com/ultravnc1
- Reddit community: https://www.reddit.com/r/ultravnc
- OpenHub: https://openhub.net/p/ultravnc
- uvnc2me: https://uvnc2me.com/
lwc
40
40
Posts: 100
Joined: 2006-08-08 11:00

Re: Unicode support for UI

Post by lwc »

Rudi De Vos wrote: 2026-04-22 21:14 UI vncviewer is unicode, not winvnc.
SC is winvnc -> no unicode changes for UI
Not sure what you mean. SC used to have Gibberish (like in the OP's screenshot), but since 2023 (stable) or even 2022 (dev) it was fixed to support Unicode.
Post Reply