Celebrating the 22th anniversary of the UltraVNC: https://forum.uvnc.com/viewtopic.php?t=38031
Update: UltraVNC 1.4.3.6 and UltraVNC SC 1.4.3.6: https://forum.uvnc.com/viewtopic.php?t=37885
Important: Please update to latest version before to create a reply, a topic or an issue: https://forum.uvnc.com/viewtopic.php?t=37864

Join us on social networks and share our announcements:
- Website: https://uvnc.com/
- GitHub: https://github.com/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

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: 90
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.
Neustradamus
20
20
Posts: 54
Joined: 2011-03-26 20:22

Re: Unicode support for UI

Post by Neustradamus »

@Rudi De Vos: Can you look?
User avatar
Rudi De Vos
Admin & Developer
Admin & Developer
Posts: 6867
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.
Neustradamus
20
20
Posts: 54
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 :)
Post Reply