Peut on créer des caracteres spéciaux personnalisé

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Mais nadine boudin, t'a rien compris ça fait depuis ce matin que je t'explique que je comprend rien à l'unicode :lol:
Alors comment tu veux que je leur parle une langue UNICODE que je connais pas :lol:

Quoi qu'il en soit je crois que quand je parle anglais, c'est déjà codé :lol:
J'aurais fait des malheurs pendant la guerre :lol:
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Message par case »

unicode c'est simple pourtant :) il faut juste regarder les codes ascii en binaire pour comprendre un peu mieux

http://fr.wikipedia.org/wiki/UTF-8

la c'est assé bien expliqué perso je comprenais pas non plus au début mais en fait c'est pas trop compliqué :)

je vais tenter de t'expliquer un peu plus simplement :)

un caractère peut être codé en utilisant jusqu'à 4 octets mais comme c'est variable il faut savoir sur combien d'octet est codé le prochain caractere de ta phrase ...

pour cela ils on réfléchis au système suivant tu prend la représentation binaire de ton caractère codé sur 8 bit donc ascii

et tu regarde les bits de poids forts

un bit de poids fort c'est pas un bit qui aurais mangé trop de cassoulet étant jeune mais c'est un bit qui si tu le met a 1 augmente considérablement la valeur de ton octet

en l'ocurence les bits a gauche de la representation binaire de l'octet

00000000 = 0
00000001 = 1
10000000 = 128

donc si tu remarque bien si on met le bit a gauche sur 1 ta valeur fait un bond de 128 ce qui est quand meme enorme sur un nombre pouvant atteindre au maximum 255 c'est donc ce qu'on apelle un bit de poids fort.

l'utf 8 concidere que si le bit de poids fort est a zero le caractere correspond a son code ascii

bit de poids fort = 128 donc tout ce qui est inferieur a 128 n'est pas codé en utf8 mais en ascii

si le bit de poids fort est a 1 alors le caractere est encodé selon la norme utf8 et necessite plusieurs octets pour son encodage

le premier octet lu donne donc le nombre d'octets utilises pour encoder le caractere. pour cela on compte le nombre d'octets de poids forts a 1 ils sont toujours suivis d'un bit a 0 comme separateur avec le code du caractere proprement dit.

11000011

en gras on a deux bits de poids forts a 1 ce qui fais donc un caractere sur deux octets

les octets suivant le premier octet ont leur premier bit de poids fort a 1 suivis d'un zero puis 6 bits contenant une partie du code du caractere

reprenons l'exemple

11000011 10101001

donc le caractere est ici encodé sur deux octets (deux bits de poids fort a un sur le premier) la valeur du caractere est egal a

premier octet second octet
00011 101001

ce qui une fois rassemblé donne

00011101001 = 233 soit le caracter é

avec utf8 tu peux ainsi utiliser une valeur allant de

0 a 2097151 a cause de la limite de 4 octets maximum utilises pour encoder un caractere et de 6 bit maximum par octets utilisable pour l'encodage

pour l'encodage c'est simple

tu veux encoder le caractère dont le code utf8 serais 45812

en binaire cela donne :

1011001011110100

on le decoupe en partant de la droite en tronçons de 6 bits

1011 001011 110100

ce qui donne 3 octets pour l'encoder

si le premier groupe de bits est plus grand que 4 bits il faut rajouter un octet pour l'encodage la ce n'est pas le cas

on ajoute les bits de poids forts
3 octets
11101011 10001011 10110100

pour le nombre suivant c'est presque pareil

111348

11011001011110100

11011 001011 110100

la premiere sequence est plus grande que 4 bits on ne peux pas encoder le nombre sur 3 octets car cela donnerais un chiffre sur 9 bits pour le premier troncon a cause des 3 bits de poids fort et du 0 de separation

111011011

donc on l'encode sur 4 octets

ce qui donne

11110000 10011011 10001011 10110100

voila j'espère que tu as compris comment l'utf8 fonctionne.

cela ne sert pas a réduire la place que prend un texte mais a pourvoir afficher un nombre conséquent de caractères dans un texte bien au dela des 255 caractères de la norme ASCII
ImageImage
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Tout d'abord mille merci de ton TUTO. 8)
J'ai compris jusqu'a la moitié et apres je suis allé prendre un aspirine :D

Mais je vais relire ton tuto, comme la bible jusqu'a ce que ce qui me sert de cerveau veuille bien entrevoir l'ombre d'une lumiere. :?
Je doit comprendre c'est une question de vie ou de vie :D

T'as l'air d'en connaitre un rayon sur l'UNICODE, parce que je galere depuis ce matin sur les deux forums pour essayer de comprendre comment je pourrais par exemple ecrire un caractere chinois.

Faut dire aussi que c'est du chinois l'unicode pour moi :lol:

Donc c'est exactement ce que je cherche, à dépasser cette sacro-sainte barriere des 255 caracteres.

Mais comment faire avec PB, pourquoi le code de NICO retourne un chiffre et pas un caractere 8O
Parce qu'il a peur que windows ne puisse l'interprété si il n'a pas la police adéquate ????
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Message par case »

le chiffre retourné est le code utf8 du caractere

chaque caractere a un nombre unique le definissant

voici les tables de caracteres correspondantes

http://www.unicode.org/charts/

le site http://www.unicode.org regorge d'informations a ce sujet :) en anglais malheureusement...

ceci dit PB peut compiler en utilisant l'unicode comme norme :)
ImageImage
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Tu es une maman pour moi CASE 8)

ça commence à s'éclaircir dans ma tete comme quand la gonzesse elle a bu son ricoré du matin :D

Mais dit moi quand je fais ce code :

Code : Tout sélectionner

OpenFile(1,"c:\chr.txt")

For i = 1 To 10000 ;2097151
 WriteStringN(1, "Ligne " + Str(i) + " = " + Chr(i))
Next

CloseFile(1)
C'est la meme serie de lettres qui reviennent :?
Pourquoi ?
C'est parce que les langues ne sont pas chargées dans mon PC ?
Et si je voulais ecrire un caractere chinois, par exemple, il faut evidemment aller dans le panneau de config charger le chinois ....
Y'a pas d'autres moyens ????
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Mon pauvre KCC je pense que tu es mal barré, si tu veux pouvoir utiliser des caractères sur 32 bits, peux tu m'expliquer comment tu vas les tapper au clavier qui lui ne gère lui que du 8 bits voir 16 bits en ansi ?????

Si tu as 32 bits il te faudra imperativement 4 octets pour le définir alors ??? Je te vois mal dans ce brouillard qui semble te cerner ici !

Je pense qu'une partie du brouillard d'ailleurs, vient de là !

Bonne soirée ! :lol:
Denis

Bonne Jounée à tous
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Mon riche BROSSDEN

Je te remercie de me remonter le moral.
ça fait toujour plaisir le soutiens des copains :D

Et si je met 2 claviers de 2 octets, ça fait bien 4 octets, hein !!!!
Aaah ça te la coupe, hein, celle la :lol:

Bon t'aurais mieux fait de me dire pourquoi la serie se répete pour que comprenne quelque chose :?
Et comment je peux ecrire du chinois, c'est joli le chinois, non... :D

Comme tout ce que je lis depuis ce matin c'est du chinois (Hormis le POST de mon amis CASE qui lui me soutiens, si tu vois ce que je veux dire :? ) , KCC y voudrais aussi ecrire chinois :?
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Je viens de trouver un code VB qui sait lire chinois 8O
Et ça marche sur ma machine, donc j'en deduis que le chinois est deja dans windows :roll:

Le bleme c'est pour le convertir en pure .......:cry:

Code : Tout sélectionner

'Pour le support des caractères UNICODE, il faut utiliser les API qui finissent
'par W (on peut souvent remplacer le A a la fin d'un API par W)
'Ici on remplace FindFirstFileA par FindFirstFileW... et ça marche.
'Ainsi , ces api supporteront le format string UNICODE, ils renveronts des valeurs sous forme UNICODE et recevront des paramètres en UNICODE egalement.
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesW" (ByVal lpFileName As String) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long

'Declaration des constantes...
Const MAX_PATH = 260
Const MAXDWORD = &HFFFF
Const INVALID_HANDLE_VALUE = -1
Const FILE_ATTRIBUTE_ARCHIVE = &H20
Const FILE_ATTRIBUTE_DIRECTORY = &H10
Const FILE_ATTRIBUTE_HIDDEN = &H2
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_ATTRIBUTE_READONLY = &H1
Const FILE_ATTRIBUTE_SYSTEM = &H4
Const FILE_ATTRIBUTE_TEMPORARY = &H100

'Declaration des Types
Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type

Function StripNulls(OriginalStr As String) As String
    If (InStr(OriginalStr, Chr(0) & Chr(0)) > 1) Then
        OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0) & Chr(0)))
    End If
    StripNulls = OriginalStr
End Function

'Fonction de recherche.
Function FindFilesUNICODE(ByVal path As String, ByVal SearchStr As String, FileCount As Integer, DirCount As Integer)
    Dim FileName As String
    Dim DirName As String
    Dim dirNames() As String
    Dim nDir As Integer
    Dim i As Integer
    Dim hSearch As Long
    Dim WFD As WIN32_FIND_DATA
    Dim Cont As Integer
    
    If Right(StrConv(path, vbFromUnicode), 1) <> "\" Then path = path & StrConv("\", vbUnicode)
    
    nDir = 0
    ReDim dirNames(nDir)
    Cont = True
    hSearch = FindFirstFile(path & StrConv("*", vbUnicode), WFD)
    If hSearch <> INVALID_HANDLE_VALUE Then
        Do While Cont
        DirName = StripNulls(WFD.cFileName)
        If (StrConv(DirName, vbFromUnicode) <> ".") And (StrConv(DirName, vbFromUnicode) <> "..") Then
            If GetFileAttributes(path & DirName) And FILE_ATTRIBUTE_DIRECTORY Then
                dirNames(nDir) = DirName
                DirCount = DirCount + 1
                nDir = nDir + 1
                ReDim Preserve dirNames(nDir)
            End If
        End If
        Cont = FindNextFile(hSearch, WFD)
        Loop
        Cont = FindClose(hSearch)
    End If
    
    hSearch = FindFirstFile(path & SearchStr, WFD)
    Cont = True
    If hSearch <> INVALID_HANDLE_VALUE Then
        While Cont
            FileName = StripNulls(WFD.cFileName)
            If (StripNulls(StrConv(FileName, vbFromUnicode)) <> ".") And (StripNulls(StrConv(FileName, vbFromUnicode)) <> "..") Then
                FindFilesAPI = FindFilesAPI + (WFD.nFileSizeHigh * MAXDWORD) + WFD.nFileSizeLow
                FileCount = FileCount + 1
                List1.AddItem StrConv(path & FileName, vbFromUnicode)
                ListBox1.AddItem StrConv(path & FileName, vbFromUnicode)
                DoEvents
            End If
            Cont = FindNextFile(hSearch, WFD)
        Wend
        Cont = FindClose(hSearch)
    End If
    
    If nDir > 0 Then
        For i = 0 To nDir - 1
            FindFilesUNICODE = FindFilesUNICODE + FindFilesUNICODE(path & dirNames(i), SearchStr, FileCount, DirCount)
        Next i
    End If
End Function

Sub Command1_Click()
    Dim SearchPath As String, FindStr As String
    Dim FileSize As Long
    Dim NumFiles As Integer, NumDirs As Integer
    Screen.MousePointer = vbHourglass
    List1.Clear
    ListBox1.Clear
    SearchPath = Text1.Text
    FindStr = Text2.Text
    FileSize = FindFilesUNICODE(StrConv(SearchPath, vbUnicode), StrConv(FindStr, vbUnicode), NumFiles, NumDirs)
    Text3.Text = NumFiles & " Files found in " & NumDirs + 1 & " Directories"
    Text4.Text = "Size of files found under " & SearchPath & " = " & Format(FileSize, "#,###,###,##0") & " Bytes"
    Screen.MousePointer = vbDefault
End Sub

Private Sub Form_Load()
    Text1.Text = App.path
End Sub
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

Facile ton truc il n'y a environ que 55 000 caratères chinois dont 3000 courants :lol:

Oui pour le chinois le japonais et autres orientaleries il existe des polices systèmes que l'on peut charger :roll:
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Je suis en train d'essayer de tirer les 2/3 fonctions qui servent à lire un fichier qui est ecrit en chinois.
Voici les fichiers avec un nom chinois dans un fichier winrar, car il parait que winzip ne gere pas l'unicode. :?

http://purebasic.myftp.org/files/413/Recherche.rar

J'en suis la, j'ai pas beaucoup avancé car je connais pas grand chose à ces déclarations structurées et ces api :cry:
MAis je vais essayer de continuer, y'a surement que quelques lignes qui servent à lire le nom des fichiers

Code : Tout sélectionner

;Pour le support des caractères UNICODE, il faut utiliser les API qui finissent
;par W (on peut souvent remplacer le A a la fin d'un API par W)
;Ici on remplace FindFirstFileA par FindFirstFileW... et ça marche.
;Ainsi , ces api supporteront le format string UNICODE, ils renveronts des valeurs sous forme UNICODE et recevront des paramètres en UNICODE egalement.
;Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
;Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
;Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesW" (ByVal lpFileName As String) As Long
;Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long

;Declaration des constantes...

#MAX_PATH = 260
#MAXDWORD = &HFFFF
#INVALID_HANDLE_VALUE = -1
#FILE_ATTRIBUTE_ARCHIVE = &H20
#FILE_ATTRIBUTE_DIRECTORY = &H10
#FILE_ATTRIBUTE_HIDDEN = &H2
#FILE_ATTRIBUTE_NORMAL = &H80
#FILE_ATTRIBUTE_READONLY = &H1
#FILE_ATTRIBUTE_SYSTEM = &H4
#FILE_ATTRIBUTE_TEMPORARY = &H100

;Declaration des Types
Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type

Procedure StripNulls(OriginalStr As String) As String
    If (InStr(OriginalStr, Chr(0) & Chr(0)) > 1) Then
        OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0) & Chr(0)))
    End If
    StripNulls = OriginalStr
EndProcedure

;Fonction de recherche.

Procedure FindFilesUNICODE(ByVal path As String, ByVal SearchStr As String, FileCount As Integer, DirCount As Integer)
    FileName.s
    DirName.s
    Dim dirNames.s() 
    nDir.l
    i.l
    hSearch.l
    Dim WFD As WIN32_FIND_DATA
    Cont.l
    
    If Right(StrConv(path, vbFromUnicode), 1) <> "\" Then path = path & StrConv("\", vbUnicode)
    
    nDir = 0
    ReDim dirNames(nDir)
    Cont = True
    hSearch = FindFirstFile(path & StrConv("*", vbUnicode), WFD)
    If hSearch <> INVALID_HANDLE_VALUE Then
        Do While Cont
        DirName = StripNulls(WFD.cFileName)
        If (StrConv(DirName, vbFromUnicode) <> ".") And (StrConv(DirName, vbFromUnicode) <> "..") Then
            If GetFileAttributes(path & DirName) And FILE_ATTRIBUTE_DIRECTORY Then
                dirNames(nDir) = DirName
                DirCount = DirCount + 1
                nDir = nDir + 1
                ReDim Preserve dirNames(nDir)
            End If
        End If
        Cont = FindNextFile(hSearch, WFD)
        Loop
        Cont = FindClose(hSearch)
    End If
    
    hSearch = FindFirstFile(path & SearchStr, WFD)
    Cont = True
    If hSearch <> INVALID_HANDLE_VALUE Then
        While Cont
            FileName = StripNulls(WFD.cFileName)
            If (StripNulls(StrConv(FileName, vbFromUnicode)) <> ".") And (StripNulls(StrConv(FileName, vbFromUnicode)) <> "..") Then
                FindFilesAPI = FindFilesAPI + (WFD.nFileSizeHigh * MAXDWORD) + WFD.nFileSizeLow
                FileCount = FileCount + 1
                List1.AddItem StrConv(path & FileName, vbFromUnicode)
                ListBox1.AddItem StrConv(path & FileName, vbFromUnicode)
                DoEvents
            End If
            Cont = FindNextFile(hSearch, WFD)
        Wend
        Cont = FindClose(hSearch)
    End If
    
    If nDir > 0 Then
        For i = 0 To nDir - 1
            FindFilesUNICODE = FindFilesUNICODE + FindFilesUNICODE(path & dirNames(i), SearchStr, FileCount, DirCount)
        Next i
    End If
EndProcedure



SearchPath.s
FindStr.s
FileSize.l
NumFiles.l
NumDirs.l

SearchPath = "c:\"
FindStr = Text2.Text
FileSize = FindFilesUNICODE_(StrConv(SearchPath, vbUnicode), StrConv(FindStr, vbUnicode), NumFiles, NumDirs)
Text3.Text = NumFiles & " Files found in " & NumDirs + 1 & " Directories"
Text4.Text = "Size of files found under " & SearchPath & " = " & Format(FileSize, "#,###,###,##0") & " Bytes"
Répondre