Problème de récupération des lignes d'un Edit Multiline

Signaler
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
-
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
-
Bonjour, j'ai un petit problème car je ne parviens pas à récupérer de façon intacte chacune des lignes rentrées dans un controle Edit en Multiline.

Voici ma partie de code :
HWND EditTexte;
.............
long LigneCourante = 0; //Compteur de position courante
long MaxLine =0; //Nb de ligne de mon edit box
LPSTR SLigne = (LPSTR) malloc (100); // Chaine chargée de
contenir le numéro de la ligne pour inscription dans un
fichier.
long Taille = 0; //Taille de la ligne courante
TCHAR BufferLigne [1000]; //C'est le buffer qui va contenir
chaque ligne lue

MaxLine = SendMessage(FREInstructionTexte,
EM_GETLINECOUNT, 0, 0);

for (Ligne = 0; Ligne < MaxLine; Ligne ++)
{
Taille = SendMessage(FREInstructionTexte,
EM_LINELENGTH, (WPARAM) Ligne, 0);

SendMessage(FREInstructionTexte, EM_GETLINE,
(WPARAM) Ligne, (LPARAM) BufferLigne);

BufferLigne[Taille+1] = '\0';
ltoa(Ligne,SLigne, 10);
WritePrivateProfileString("INSTRUCTION", SLigne,
BufferLigne, "Fichier.txt");
}

Dans cet exemple, logiquement, on cherche le nombre maxi de lignes contenues dans l'Edit, puis, on boucle de façon à déterminer pour chacune des lignes sa taille, on lit chaque ligne et on place son contenu dans BufferLigne de type TCHAR, puis, on ajoute '\0' à la fin de chaque ligne, enfin, on écrit BufferLigne dans un fichier à la position numérotée de chaque ligne.
Et bien mon prog plante,le fichier texte généré contient pour chaque ligne un nombre toujours identique de caractères. Si la première ligne fait 10 Caractères, toutes les autres sont écrites avec 10 Caractères, et si elles sont plus petites, des caractères parasite sont rajoutés. Si je m'emploie à 'nettoyer' BufferLigne' en remplissant chaque élément par le caractère NULL au moyen d'une boucle, j'ai beau réaffecter à BufferLigne les autres ligne de mon edit, rien ne s'écrit dans mon fichier.
Pour avoir l'intégralité des lignes de mon edit dans mon fichier, il faut que j'enlève l'ajout de \0 à la fin de mes lignes, mais cela laisse d'inombrables caractères parasites.
De plus, si mon Edit comporte des sauts de ligne, il sont remplacés entièrement par les mêmes caractères que la ligne précédente.
Comment faire pour avoir une restitution exacte dans mon fichier des lignes de mon editbox ?
Merci d'avance
LaPatoshe

14 réponses

Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Rectificatif : mon edit box se nomme HWND FREInstructionTexte et non EditTexte.
LaPatoshe
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
Je vois pas pkoi tu t'embetes, tu fais un coup de GetDLgItemText, puis tu parses le buffer avec un pointeur pour trouver '\r\n' ki delimiteront les lignes, voila un exemple de GetDlgItemText :

#include <windows.h>
#include "resource.h"

BOOL CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
char buf[520];

switch (message) {
case WM_COMMAND:
if (IDOK == wparam) {
GetDlgItemText(hwnd, IDC_EDIT1, buf, 520);
MessageBox(hwnd, buf, 0, 0);
}else if (IDCANCEL == wparam)
EndDialog(hwnd, 0);
return 0;
default:
return 0;
}
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE p, LPSTR q, int r)
{
DialogBoxParam(hInst, (LPCTSTR)IDD_DIALOG1, 0, DlgProc, 0);
return 0;
}

Si tu n'as pas compris, je repasse ce soir.

++ bonne chance
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
astuce pour EM_LINELENGTH :

EM_LINELENGTH
An application sends an EM_LINELENGTH message to retrieve the length of a line, in characters, in an edit control.

EM_LINELENGTH
wParam = (WPARAM) ich; // character index
lParam = 0; // not used; must be zero

!!!! wParam n'est pas le numéro de ligne mais l'indice du premier caractère de la ligne depuis le début du texte !!!

cet indice peut être obtenu à partir du numéro de ligne par
EM_LINEINDEX
wParam = (WPARAM) line; // line number
lParam = 0; // not used; must be zero

ensuite, pour EM_GETLINE, li faut cette fois donner le numéro de ligne et un buffer. Ce buffer doit faire au moins 2 octets (1 WORD) car lors de l'appel, il faut mettre sa taille dans le premier WORD
Messages postés
933
Date d'inscription
dimanche 1 avril 2001
Statut
Modérateur
Dernière intervention
9 janvier 2012
2
Bonjour,

Une source de mon ami Brunews : http://www.cppfrance.com/code.aspx?id=21272

@+
Arnotic,
Admin CS, MVP Visual C++
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
Ok, il ne faut donc pas utiliser GetDlgItemText ? Mais pourquoi alors ? parce que ca marche, nan ?

Merci
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Salut AlexMan, j'ai essayé ta méthode, mais elle ne fonctionne pas. Pour info, mon prog est constitué de feuilles et de contrôles (pas de DialogBox). J'ai quand même tenté l'opération GetDlgItemText(hEdit, 0, Buffer, 2000), mais lors de l'écriture de Buffer dans mon fichier, rien n'apparait.
Vu la définition des paramètres demandés dans cette fonction, j'ai usé de SetWindowLong (hEdit, GWL_ID, 1234); pour donner l'identifieur de mon contrôle comme étant 1234, et ensuite j'ai inscrit GetDlgItemText(hFeuille, 1234, Buffer, 2000); Dans mon fichier on retrouve d'enregistrer tout ce que je tape dans l'edit Box. cependant voilà, lorsque je lis ce même fichier, et que je code StDlgItemText(hFeuille, 1234, buffer), il n'apparait dans ma zone de texte que la première ligne, les autres ne s'affichent pas. Cela donne le même résultat que lorsque j'utilisait WM_GETTEXT et WM_SETTEXT.
LaPatoshe
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Je viens de tenter de comprendre l'exemple cité par Arnotic, mais je le trouve un peu complexe, et utilise beaucoup les dialogBox (Y en a pas dans mon prog), quelqu'un aurait il un exemple le plus simple soit il montrant comment récupérer un edit box ligne par ligne ? Merci
LaPatoshe
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
LE crois que je viens de trouver un début de solution à mon problème.

LPSTR Ligne =(LPSTR) malloc (10);
long Pl=0;
long nbLigne = SendMessage(FREInstructionTexte,EM_GETLINECOUNT,0, 0);
for (Pl = 0; Pl < nbLigne; Pl ++)
{
char LigneTexte[2000];
*((WORD*) LigneTexte) = 2000;
ltoa(Pl,Ligne,10);
long cpt=0;
for (cpt=0; cpt<2000; cpt++)
{
szbuff[cpt]= ' ';
}

SendMessage(FREInstructionTexte, EM_GETLINE, (WPARAM) Pl, (LPARAM) LigneTexte);
WritePrivateProfileString("INSTRUCTION", Ligne, szbuff, DCh);
}

*((WORD*) LigneTexte d'après ce que j'ai compris en regardant certaines sources permettrait d'écrire la taille de LigneTexte dans la partie basse de cette variable (comme si LigneTexte pouvait contenir deux choses telle une structure).
Grace à cela, mon prog marche, mes lignes s'inscrivent entièrement dans mon fichier, et les caractères parasites sont remplacés par le caractère d'espacement. C'est un bon début, maintenant, je cherche comment calculer à peu près la place à réserver pour chacune des lignes pour ne pas à avoir à écrire les caractères d'espacement qui sont de beaucoup trop.
Encore Merci pour votre aide.
LaPatoshe
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
Ok dsl si ca marche po, j'avais testé chez moi et ca fonctionnait, dsl encore.
Je viens de regarder la source de Brunews, pour connaitre la 'taille d'une ligne', il te faut envoyer un msg EM_LINELENGTH ki te renverra la taille (size = SendMessage(h, EM_LINELENGHT, ..)).
Voila, encore dsl pour le truc ke je t'avais proposé, et pis bonne chance.

ymca & Arnotic > J'aimerais que vous me disiez pourkoi ca ne fonctionne pas GetDlgItemText ? Merci d'avance a vous deux.

++
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
GetDlgItemText marche seulement si l'Edit est dans un Dialogue, ce qui n'est pas le cas du code de LaPastoche.

LigneTexte est un tableau de caractères et donc un pointeur sur le premier octet de ce tableau. A partir de la, on peut y écrire n'importe quoi si on fai un cast appoprié. pour EM_GETLINE, il faut mettre dans le premier WORD la taille. On caste donc le pointeur en un pointeur sur un WORD et on affecte la valeur de ce pointeur comme si on avait affaire à un WORD. Il ne faut pas perdre de vue que le tablea de caractères est une simple réservation d'octets à la suite en mémoire, on peut donc y mettre ce que l'on veut masi le compilo veut qu'on lui spécifie les types ( d'ou le cast)
*((WORD*) LigneTexte) = 2000;

pour connaître la taille d'une ligne, il faut suivre ma réponse précédente et faire :
hEdt : handle de l'Edit
nLine : numéro de la ligne

nIndex = SendMessage(hEdt, EM_LINEINDEX, nLine, 0);
nLineLength = SendMessage(hEdt, EM_LINELENGTH, nIndex, 0);
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Salut, et merci, pour toutes vos précisions, qui m'ont permis d'élaborer mon prog un peu à ma sauce.
J'ai réussi à enregistrer dans mon fichier les lignes de mon texte de deux façon : La première ligne par ligne chacune terminée par un \n. Seulement, je n'ai pas trouvé de fonction permettant de restituer dans un edit Multiline chaque ligne une par une (EM_SETLINE n'existe pas apparement). Vu qu'il existe WM_SETTEXT, j'ai donc créé une nouvelle chaine dans laquelle j'ai placé côte à côte toutes les chaines terminées par \n de mon contrôle Edit (en Somme, j'enregistre le texte entier en le faisant entrer dans une chaine sur une seule ligne).
Seulement voilà, pour la restitution avec WM_SETTEXT, ça ne fonctionne pas, il n'y a que la premièreligne qui apparait. Dès que la lecture arrive au premier \n, l'affichage du reste ne se fait pas.

Pour résumer, comment restituer des chaines de caractère (LPSTR) à leur place dans un contrôle Edit en Multiline.
Merci
La Patoshe
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
pour faire un saut de ligne il faut mettre \r\n et pas seulement \n

sinon pour rajouter du texte à la fin de l'Edit, il faut faire WM_GETTEXTELENGTH pour connaître la taille totale nTextLength, EM_SETSEL pour mettre une sélection nulle à la fin (nTextLength pour nStart et nEnd) puis faire EM_REPLACESEL avec le texte à rajouter
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Salut, et merci de vos contributions. En fait, dans mon prog, j'arrive sans difficulté à récupérer les lignes de mon edit multiline. Une fois récupérées, j'enregistre ces lignes dans un fichier avec ou sans caractère de retour de ligne.
Le problème, c'est que je ne trouve pas la commande permettant de restituer ces lignes à leur place dans l'Edit. Lorsque 'utilise la commande WM_SETTEXT, uniquement la première ligne se remplit. Si j'utilise EM_REPLACESEL, tout le texte se place dans le controle Edit, mais sans les sauts de ligne, que j'en mette ou non en ajoutant "\n\r" à mes chaines enregistrées. J'ai essayé également de placer dans une seule chaine tout le texte en y isérant aux endroits nécessaires des sauts de ligne, puis j'essais de faire afficher mon texte dans une EditBox avec WM_SETTEXT, mais seule la première ligne s'affiche. JE cherhe en fait une fonction qui: soit permette d'envoyer des sauts de ligne dans un Edit Multiline pour ainsi placer le curseur sur la ligne suivante et envoyer la l'enregistrement correspondant,
soit permettent de placer chaque ligne à un numéro de ligne précis (un peu comme cela se fait pour les listbox). J'ai fouillé toutes les fonctions WM_ et EM_, je n'ai rien trouvé qui puisse aller.
Merci pour votre aide
LaPatoshe
Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Je viens de trouver une solution intermédiaire. Au lieu d'inclure le saut de ligne dans la chaine de caractère, je fais ce saut de ligne d'office dès que la ligne est chargée et affichée. En effet, un saut de ligne dans la chaine de caractère ne fonctionne pas , mais SendMessage(Edit, EM_REPLACESEL, 0, (LPARAM) "\r\n") fonctionne.
LaPatoshe