Partage
  • Partager sur Facebook
  • Partager sur Twitter

[WinAPI] Problème avec le contrôleur EDIT

Sujet résolu
    15 avril 2019 à 14:51:26

    Bonjour à tous,

    Depuis peu j'ai voulu commencer à apprendre à utiliser la WinAPI. Oui je sais : Pourquoi ? C'est bête il y a des bibliothèques tellement mieux ! Elles rajoutent une couche d'abstraction qui te fait moins galérer... Et j'en passe. Mais moi j'ai envie, alors je me lance :)

    Pour commencer j'ai voulu faire un simple bloc-note. Quand on ouvre un fichier, ça affiche l'EDIT et c'est censé le remplir.
    edit = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, MAIN_WIN_W, MAIN_WIN_H, win, NULL, instance, NULL);

    Donc pour se faire j'ouvre le fichier avec CreateFile et je récupère un handle sur mon fichier. Jusque là aucun soucis.
    file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    Je lis mon fichier avec la fonction ReadFile. Là encore aucun problème, j'arrive à récupérer la totalité du contenu de mon fichier et à le stocker dans un buffer grâce à une boucle. Je suis passé par les malloc et realloc pour ne pas avoir de contrainte sur sa taille.
    do {
        if ( (str = realloc(str, i*BUFFERSIZE*sizeof(TCHAR))) == NULL) {
            stdoutErrorMsg(win);    // Fonction définie dans mon projet
            exit(-1);
        }
    
        if ( ReadFile(file, buf, BUFFERSIZE, &len, NULL) == FALSE ) {
            stdoutErrorMsg(win);
            return FALSE;
        }
    
        strconcat(str, buf, pos);    // Fonction définie dans mon projet
          pos += len;
        i++;
    
    } while( !(len < BUFFERSIZE) );
    str[pos] = '\0';

    Maintenant, il faut que j'affiche le contenu de ce buffer dans le contrôleur. Là j'ai un problème. J'ai voulu passé par les messages et plus particulièrement WM_SETTEXT en envoyant mon buffer comme paramètre. Et ça marche plutôt bien. Mais dès lors que j'ouvre un autre fichier, le comportement de l'EDIT est pour le moins étrange.
    SendMessage(edit, WM_SETTEXT, 0, (LPARAM)str);

    Il affiche le contenu de ce fichier que je viens d'ouvrir, mais conserve au niveau de son utilisation ma première ouverture. Par exemple, si j'ouvre mon fichier, j'efface tout, et j'en ouvre un autre. Le contenu de mon second fichier s'affiche dans le contrôleur, mais je ne peux rien faire car pour lui j'ai tout est effacé (de mon premier fichier ouvert). Je peux évidemment écrire par dessus, dans quel cas le texte s'efface au fur et à mesure de mon écriture...

    J'ai pas trop de piste sur ce coup là... Quelqu'un pourrait m'aider ? Merci mille fois :)
    • Partager sur Facebook
    • Partager sur Twitter
      16 avril 2019 à 17:45:41

      Bonjour,

      Je profite d'un petit up pour porter un éclaircissement. Quand je cherche à récupérer le contenu du buffer ainsi :
      handle = (HLOCAL)SendMessage(edit, EM_GETHANDLE, 0, 0);
      str = (PTCHAR)LocalLock(handle);
      printf("buffer : %s\n", str);

      Il est bien "mis à jour". Si j'ouvre un autre fichier, son contenu est bien celui du nouveau fichier. Au début je pensais que genre un buffer gardait en mémoire le contenu de mon premier fichier, et quand j'en ouvrais un nouveau celui-ci ne se mettait pas à jour. Et du coup le programme, lui, traitait avec ce buffer au lieu de traiter le contenu du EDIT.

      Mais apparemment ce n'est pas ça. Alors si quelqu'un a une idée ?
      • Partager sur Facebook
      • Partager sur Twitter
        17 avril 2019 à 19:37:33

        Bonjour à tous,

        J'ai apporté quelques modifications. Je passe plus par des malloc et autres, j'utilise LocalAlloc de la WinAPI. Pour faire des tests je suis parti sur un buffer fixe de taille BUFFERSIZE. Voici ma fonction "ouvrir" :

        BOOL open_file(HWND win, LPCSTR path)
        {
        	HANDLE file;
        	DWORD pos;
        	PTCHAR buf;
        
        	printf("===Ouverture===\n");
        
        	if ( (buf = (PTCHAR)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, BUFFERSIZE)) == NULL ) {
        		fprintf(stderr,
        				"Impossible d'allouer de la memoire : %s (WinAPI : %ld)\n",
        				strerror(errno), GetLastError());
        		MessageBox(win, "Impossible d'ouvrir le fichier.", "Erreur",
        					MB_OK | MB_ICONERROR);
        
        		return FALSE;
        	}
        
        	#ifdef DEBUG
        		printf("Allocation de la memoire :\
        				\n Adresse du buffer : %p \
        				\n Contenu du buffer : %s\n", &buf, buf);
        	#endif // DEBUG
        
        	if ( (file = CreateFile(path,
        							GENERIC_READ,
        							FILE_SHARE_READ,
        							NULL,
        							OPEN_EXISTING,
        							FILE_ATTRIBUTE_NORMAL,
        							NULL)
        	) == INVALID_HANDLE_VALUE ) {
        		fprintf(stderr,
        				"Impossible d'ouvrir le fichier (%s) : %s (WinAPI : %ld)\n",
        				path, strerror(errno), GetLastError());
        		MessageBox(win, "Impossible d'ouvrir le fichier.", "Erreur",
        					MB_OK | MB_ICONERROR);
        
        		return FALSE;
        	}
        
        	printf("Ouverture du fichier : %s\n", path);
        
        	if(ReadFile(file, buf, BUFFERSIZE-1, &pos, NULL) == FALSE) {
        		fprintf(stderr,
        				"Impossible de lire le fichier (%s) : %s (WinAPI : %ld)\n",
        				path, strerror(errno), GetLastError());
        		MessageBox(win, "Impossible d'ouvrir le fichier.", "Erreur",
        					MB_OK | MB_ICONERROR);
        
        		return FALSE;
        	}
        	buf[BUFFERSIZE] = '\0';
        
        	edit = CreateWindow("EDIT", "",
        						WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL |
        						ES_AUTOVSCROLL,
        						0, 0, MAIN_WIN_W, MAIN_WIN_H, win, NULL, instance,
        						NULL);
        
        	SendMessage(edit, WM_SETTEXT, 0, (LPARAM)buf);
        
        	CloseHandle(file);
        	LocalFree(buf);
        
        	return TRUE;
        }
        

        Seulement aucun changement de comportement. J'ouvre un 1er fichier. Tout est OK. Quand je veux en ouvrir un autre, dans un premier temps il m'affiche bien son contenu. Mais dés que je veux prendre la main sur le texte, PAF, c'est mon 1er fichier ouvert qui réapparaît.

        J'avance vraiment pas, personne n'a de pistes ?

        Merci :)

        • Partager sur Facebook
        • Partager sur Twitter
          18 avril 2019 à 10:17:22

          Salut,

          Il faut dissocier ouverture de fichier et création de contrôle Edit.

          Avec ta façon de faire, à chaque ouverture de fichier tu crées un nouveau contrôle Edit.

          Tu n'as besoin que d'un seul contrôle Edit, que tu crées au début de ton programme et que tu remplis à ta convenance.

          • Partager sur Facebook
          • Partager sur Twitter
            18 avril 2019 à 19:42:13

            Ah d'accord !

            Merci magma :)

            Juste une question tu aurais des pistes pour l'UTF-8 ? Parce que le but c'est quand même d'ouvrir les fichiers textes. Or, si j'ai des caractères spéciaux ça marche plus. Du coup je me suis dis je vais passer par l'UTF-8.

            Alors j'ajoute les macro UNICODE et _UNICODE. Les chaînes de caractères je les passe par TEXT(). Mais pour mes buffers je trouve pas la fonction qui permette de convertir les caractères de mon fichier texte en caractère UTF-8...

            Voilà,

            Sinon encore merci :)

            • Partager sur Facebook
            • Partager sur Twitter

            [WinAPI] Problème avec le contrôleur EDIT

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            • Editeur
            • Markdown