Newsgroup: it.comp.programmare.win32
Titolo: [API] Usare Unicode in Win98

Inizando a leggere Programmare Applicazione per Windows ho inizato ad
affrontare il capitolo relativo a Unicode. Gia' sapevo che sotto Win98
non e' facile (si', uso ancora il 98^^;;; ma a Luglio cambio ;-).
Potete confermarmi, pero', che le seguenti funzioni o scritture
effettivamente non funzionano sotto windows (o non completamente). 
Grazie
Il contenuto della libreria "ShlWApi.h" (ovvero le funzioni StrCat,
StrCpy, Str...)
static TCHAR * szAppName = _TEXT ("Unicode Test"); 
strcpy (szTextB, szTextA); //dove TextA e TextB sono TCHAR *
--
Scritto da Gordon
E-mail: 
tbe...@avpu.vg

 strcpy (szTextB, szTextA); //dove TextA e TextB sono TCHAR *
Immagino non sia corretto, a meno di quando non è definito _UNICODE (in 
quel caso il TCHAR dovrebbe equivalere al char).
L'help di Visual Studio, su strcpy(), specifica che quella generica è 
_tcscpy() -- con questa, trattando i TCHAR, non sbagli mai, si adeguerà 
a chiamare strcpy() o wcscpy() a seconda della definizione di _UNICODE
Lou

a chiamare strcpy() o wcscpy() a seconda della definizione di _UNICODE
ah, capito.


ah, capito.
comunque
_tcscpy (szText, _TEXT(" "));
mi da errore Windows all'esecuzione del programma


 mi da errore Windows all'esecuzione del programma
Molto probabile, a seconda che ne fai di quel szText, visto che 
definisci UNICODE su Windows 98, che *non supporta* Unicode, giusto 
qualche funzione essenziale, tipo la MessageBox().
(Se hai il Petzold č scritto proprio nel primo capitolo).
Peraltro non mi sembra una buona idea definire UNICODE nel sorgente, 
credo sarebbe da farsi a livello d'invocazione del compilatore -- faccio 
solo ipotesi, mai realizzato applicativi Unicode, ho sempre avuto 
necessitą che fossero compatibili con Windows 95/98.
Lou

mi da errore Windows all'esecuzione del programma
Se definisce UNICODE il tuo applicativo non girera mai sotto un
sistema win 9x in quanto NON E' SUPPORTATO.

credo sarebbe da farsi a livello d'invocazione del compilatore 
non saprei, nei libri c'e' scritto di definire UNICODE, non e' chiaro
se intendono a livello di compilatore o nel sorgente. Se intendono a
livello di compilatore, con il VC++ 6, dove devo inserirlo?


sistema win 9x in quanto NON E' SUPPORTATO.
ah, ho capito ^^;;;
pero' ho scritto questo programmino (che ho testato su WinXP, che
dovrebbe essere compatibile Unicode) ma da qualche problema. Si apre,
funziona, ma le stringhe danno parecchi problemi ^^;;;;
****
/*INCLUDE*/
#include "windows.h" //la libreria base per le API windows
#include "tchar.h" //la libreria per unicode
#include "resource.h" //file resource
/*DEFINE*/
#define _UNICODE //per utilizzare unicode
#define UNICODE //per utilizzare unicode
/*ENUM, STRUCT, CLASS*/
/*DICHIARAZIONE GLOBALI*/
static TCHAR * szAppName = _TEXT ("Unicode Test"); //il nome 
static TCHAR * szVersion = _TEXT ("1.0"); //la versione
static TCHAR * szProgrammer = _TEXT ("Gordon"); //il programmatore
static TCHAR * szInfo = _TEXT ("(c) 2003"); //altre informazioni
/*DICHIARAZIONE FUNZIONI*/
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); 
/*FUNZIONI*/
//WINMAIN
int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
		          PSTR szCmdLine, int iCmdShow)
{
	//imposta la finestra e le opzioni	
	HWND		hwnd;
	MSG		msg;
	WNDCLASS	wndclass;
	wndclass.style			= CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc		= WndProc;
	wndclass.cbClsExtra		= 0;
	wndclass.cbWndExtra		= DLGWINDOWEXTRA; //NOTA!!
	wndclass.hInstance		= hInstance;
	wndclass.hIcon			= LoadIcon (NULL,
						 IDI_APPLICATION);
	wndclass.hCursor		= LoadCursor (NULL,
						 IDC_ARROW);
	wndclass.hbrBackground	= (HBRUSH) (COLOR_BTNFACE + 1); 	
	wndclass.lpszMenuName	= NULL;
	wndclass.lpszClassName	= szAppName;
	if (!RegisterClass (&wndclass))
	{
		MessageBox (NULL, TEXT ("Questo programma richiede
			 Windows NT!"), szAppName, MB_ICONERROR);
		return 0;
	}
	//crea la dialog
	hwnd = CreateDialog (hInstance, TEXT ("MainDlg"), NULL,
				 (DLGPROC) WndProc);
 
	//mostra la finestra
	ShowWindow (hwnd, iCmdShow);
	// crea il ciclo dei messaggi
	while (GetMessage (&msg, NULL, 0, 0))
	{
		if (hwnd == 0 || !IsDialogMessage (hwnd, &msg))
		{
			TranslateMessage (&msg);
			DispatchMessage (&msg);
		}
	}
	return msg.wParam; //il return 
}
//WNDPROC
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
	//la Window Procedure
	//variabili e costanti
	static TCHAR * szTextA = _TEXT (" "), * szTextB = _TEXT (" ");
	static HWND hTestoA, hTestoB, hTotale, hRisultati, hDraw;
	TCHAR * szText = _TEXT (" ");
	HDC hdc;
	PAINTSTRUCT ps;
	//il ciclo dei messaggi
	switch (message)
	{
	case WM_INITDIALOG:
	case WM_CREATE:
		SetWindowText (hwnd, szAppName);
		_tcscpy (szText, _TEXT(" "));
 
		hTestoA = GetDlgItem (hwnd, ID_TESTOA);
		hTestoB = GetDlgItem (hwnd, ID_TESTOB);
		hTotale = GetDlgItem (hwnd, ID_TOTALE);
		hRisultati = GetDlgItem (hwnd, ID_RESULT);
		hDraw = GetDlgItem (hwnd, ID_DRAW);
		_tcscpy (szTextA, _TEXT ("Scrivimi"));
		_tcscpy (szTextB, szTextA);
		SetWindowText (hTestoA, szTextA);
		SetWindowText (hTestoB, szTextB);
		UpdateWindow (hwnd);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint (hwnd, &ps);
		//qui
		EndPaint (hwnd, &ps);
		return 0;
	case WM_COMMAND:
		switch (LOWORD (wParam))
		{
		case ID_CHIUDI:
			SendMessage (hwnd, WM_CLOSE, 0, 0);
			break;
		case ID_MORE:
			_tcscpy (szText, szVersion);
			_tcscat (szText, _TEXT ("\n"));
			_tcscat (szText, szProgrammer);
			_tcscat (szText, _TEXT ("\n"));
			_tcscat (szText, szInfo);
			MessageBox (hwnd, szText, szAppName, MB_OK |
					 MB_ICONQUESTION);
			break;
		case ID_RESET:
			_tcscpy (szTextA, _TEXT ("Scrivimi"));
			_tcscpy (szTextB, szTextA);
			SetWindowText (hTestoA, szTextA);
			SetWindowText (hTestoB, szTextB);
			UpdateWindow (hwnd);
			break;
		case ID_TESTOA:
			if (HIWORD (wParam) == EN_UPDATE) {
				GetWindowText (hTestoA, szTextA,
					 GetWindowTextLength (hTestoA)
					 + 1);
				_tcscpy (szText, szTextA);
				_tcscat (szText, szTextB);
				SetWindowText (hTotale, szText);
			}
			break;
		case ID_TESTOB:
			if (HIWORD (wParam) == EN_UPDATE) {
				GetWindowText (hTestoB, szTextB,
					 GetWindowTextLength (hTestoB)
					  + 1);
				_tcscpy (szText, szTextA);
				_tcscat (szText, szTextB);
				SetWindowText (hTotale, szText);
			}
			break;
		}
		return 0;
	case WM_CLOSE:
	case WM_DESTROY:
		PostQuitMessage (0);
		return 0;
	}
	return DefWindowProc (hwnd, message, wParam, lParam); 


#define UNICODE //per utilizzare unicode
#define _UNICODE va prima di ogni include
sbirish

 livello di compilatore, con il VC++ 6, dove devo inserirlo?
Suppongo a livello di progetto: Menų Project, Settings, C/C++, Category: 
Preprocessor, li aggiungi fra le le "Preprocessor definitions"
Sicuramente *non* dopo le #include, come in quel pezzo di codice che hai 
riportato in un'altra diramazione di questo post.
Viene da chiedermi: ma ti serve davvero? Il tuo applicativo deve avere 
messaggi in cinese, coreano o altre lingue "inusuali" e girare solo su 
NT/2000/XP?
Lou

NT/2000/XP?
effettivamente per ora era solo per pura curiosita e per imparare (in
caso servisse) Unicode... cmq studicchio giapponese ;P


#define _UNICODE va prima di ogni include
ok.
Grazie


 ma tecnicamente qual'e' la differenza?
Cambia anzitutto l'ordine di ricerca, nel path per i file da includere.
Le parentesi angolari iniziano solitamente la ricerca fra i percorsi 
predefiniti del compilatore (normalmente gli header di sistema), mentre 
le virgolette portano a ricercare prima nella directory corrente.
Per i file header di sistema/del compilatore si usano *sempre* le 
parentesi angolari, sia per il discorso del path, sia per rendere chiaro 
che sono file forniti con il sistema/compilatore; inoltre perché alcune 
utility di make/gestione progetto/compilatori possono dare un 
significato diverso alla ricerca delle dipendenze (di solito non è molto 
importante mettere nelle dipendenze i file di sistema, che difficilmente 
cambiano), mentre gli altri header possono cambiare molto facilmente 
durante la stesura del progetto.
Lou

CUT
grazie per l'esauriente risposta ^____^


ho avuto a suo tempo il tuo stesso problema dovendo sviluppare un 
applicativo che girasse sotto OS solo Unicode e windows 98 e l'ho 
risolto come dice il libro che tu hai citato:
1°) Vai sul setting del progetto e ti definisci (se non mi sbaglio 
nella scheda C++) /D "_UNICODE" /D "UNICODE"
se hai letto il libro sai la differenza tra le due define...
2°)Ogni file di implementazione deve intestare l'header tchar.h, quindi
#include <tchar.h>
3°)adesso devi solamente utilizzare le funzioni _tcscpy, _tcscmp...
Cosi' non avrai piu' problemi... ciao!!!
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG


-- 
  < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
      Don't stand, REACT!      version 0.1.1. C, C++ and ASM developers
                               and beta testers are welcome!


rimanendo in tema.. quindi ot visto che sono mezzo bresco..
che tu sappia č normale che alcune api che tornano struct che a dire
di msdn dovrebbero contenere stringhe unicode, saltino invece a pič
pari tale campo senza fillarlo, addirittura senza azzerarlo?
sto parlando in particolare per esperienza personale di questi giorni
di GetIfTable che dovrebbe fillare una MIB_IFTABLE e nelle MIB_IFROW
wszName non viene fillato affatto..
idem per NetShareInfo/SHARE_INFO_502 .hi502_netname e .shi502_path
sbirish che si gratta la testa confuso

 idem per NetShareInfo/SHARE_INFO_502 .hi502_netname e .shi502_path
non è necessario che una share abbia un path. IPC$ non ce l'ha, come ti 
confermerà il comando net share


confermerà il comando net share
no.. però mi sarei aspettato una stringa vuota piuttosto che
dell'immondizia..
di fatto con GetIfTable mi accontento di memsettare la struct prima di
farla fillare.. se il discorso vale per quell'api, con NetShareEnum il
buffer lo alloca e lo riempie la stessa api, senza darmi modo di
azzerare prima... risultato... un paio di LPWSTR che puntano
all'iperspazio, l'impossibilità di capire se punta ad una stringa, ed
in omaggio un bel segmentation fault quando dereferenzio..
mi chiedevo se non mi sfuggisse qualcosa.
sbirish

Cosi' non avrai piu' problemi... ciao!!!
provo, grazie.



Oh beh, Petzold diceva che non esistesse supporto; probabilmente la sua 
č un'affermazione piů datata ed il libro non č stato aggiornato.
Lou

 č un'affermazione piů datata ed il libro non č stato aggiornato.
Ah, evidente che non fosse citata dal Petzold: č una DLL aggiuntiva 
rilasciata meno di due mesi fa
   "It was first made available on April 24, 2003"
Non male per un sistema operativo di oltre cinque anni, meglio tardi che 
mai ;^)
Lou