TEdit ou TCombobox à l'interieur d'un TMemo

Messages postés
297
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
- - Dernière réponse :  Utilisateur anonyme - 22 janv. 2009 à 17:44
Bonjour,

Je suis actuellement en train de me faire un logiciel de test de langue anglaise (Bulats). Parmis les épreuves du test, il y en a une où il faut compléter un texte avec des trous.

J'ai donc utilisé un TMemo pour afficher le texte à trou (contenu dans un fichier), à l'intérieur de ce mémo, là ou il y a un trou à remplir, j'ai placé un texte fixe  : XXXXXXXXX, pour repérer les trous dans le memo. Ensuite, je parcoure le MEMO à la recherche de ce texte et dès que je le trouve, j'essaie de placer soit un combobox, soit un TEdit , soit un TCombobox par dessus pour permettre au candidat de remplir ou de sélectionner un mot.
Sauf que je ne parvient pas à placer correctement mon TEdit (ou TCombobox) sur le TMemo.

Le programme que j'ai essayé de faire est dépendant de la police, et de l'ordinateur sur lequel il fonctionne (j'ai essayé sur plusieurs PC). Voici le bout de code qui me pose probléme :

FMain.P_Audio.Visible:=true;//
         FMain.P_Text_Choice.Visible:=true;
         FMain.B_AudioScript.Visible:=False;
         FMain.B_Ecoute_Audio2.Visible:=False;
         FMain.B_Ecoute_Audio1.Visible:=False;
         hc:=FMain.B_AudioScript.Canvas.TextHeight('O')+1; // B_Audioscript est un TImage dont la proprièté TFont est la même que celle du Memo
         //tc:=FMain.B_AudioScript.Canvas.TextWidth('OOOOOOOOOO'); // Comme le Memo n'a pas de TCanvas, j'ai essayé de faire comme ca
         tc:=10*10+4; // mais ce n'est pas concluant

        // les combos à placer au dessus des différents trous

         FMain.ComboBox1.Width:=tc;
         FMain.ComboBox2.Width:=tc;
         FMain.ComboBox3.Width:=tc;
         FMain.ComboBox4.Width:=tc;
         FMain.ComboBox5.Width:=tc;
        
         FMain.ComboBox1.Height:=hc-8;
         FMain.ComboBox2.Height:=hc-8;
         FMain.ComboBox3.Height:=hc-8;
         FMain.ComboBox4.Height:=hc-8;
         FMain.ComboBox5.Height:=hc-8;

         FMain.ComboBox1.Visible:=True;
         FMain.ComboBox2.Visible:=True;
         FMain.ComboBox3.Visible:=True;
         FMain.ComboBox4.Visible:=True;
         FMain.ComboBox5.Visible:=True;
        
         FMain.ComboBox1.ItemIndex:=-1;
         FMain.ComboBox2.ItemIndex:=-1;
         FMain.ComboBox3.ItemIndex:=-1;
         FMain.ComboBox4.ItemIndex:=-1;
         FMain.ComboBox5.ItemIndex:=-1;

         FMain.Edit1.Visible:=False;
         FMain.Edit2.Visible:=False;
         FMain.Edit3.Visible:=False;
         FMain.Edit4.Visible:=False;
         FMain.Edit5.Visible:=False;
         k:=1;
         for i:=0 to FMain.M_Text_choice.Lines.Count-1 do // Je parcoure toutes les lignes du Memo
           begin
             texte:=FMain.M_Text_choice.Lines.Strings[i];
             j:=pos('XXXXXXXXXX',texte);                       // à la recherche de la chaine XXXXXXX
             while j>0 do
               begin
                 texte1:=copy(texte,1,j-1);
                 delete(texte,1,j+9);
                 texte:=texte1+'OOOOOOOOOO'+texte; // Cette chaine, je la change en OOOOOOO de manière à pouvoir refaire une détection sur la même ligne
                 FMain.M_Text_choice.Lines.Strings[i]:=texte;
                 //j:=trunc(FMain.B_AudioScript.Canvas.TextWidth(texte1)*1.2);
                 j:=length(texte1)*10;
                 case k of    // en fonction du numéro du trou actuel, on place soit Combobox1 sur le trou 1, combobox 2 sur le trou 2 etc...
                   1 : begin
                         FMain.ComboBox1.Left:=j;
                         FMain.ComboBox1.Top:=i*hc+4;
                   end;
                   2 : begin
                         FMain.ComboBox2.Left:=j;
                         FMain.ComboBox2.Top:=i*hc+4;
                   end;
                   3 : begin
                         FMain.ComboBox3.Left:=j;
                         FMain.ComboBox3.Top:=i*hc+4;
                   end;
                   4 : begin
                         FMain.ComboBox4.Left:=j;
                         FMain.ComboBox4.Top:=i*hc+4;
                   end;
                   5 : begin
                         FMain.ComboBox5.Left:=j;
                         FMain.ComboBox5.Top:=i*hc+4;
                   end;
                 end;
                 k:=k+1;
                 j:=pos('XXXXXXXXXX',texte);
               end;
           end;
         FMain.ComboBox1.Color:=clWhite;
         FMain.ComboBox2.Color:=clWhite;
         FMain.ComboBox3.Color:=clWhite;
         FMain.ComboBox4.Color:=clWhite;
         FMain.ComboBox5.Color:=clWhite;     

Merci à ceux qui pouront me dire comment faire pour connaitre la position en pixel d'un texte dans un TMemo

Oniria
Afficher la suite 

3 réponses

Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
26 juillet 2018
11
0
Merci
Salut Oniria,

«Comme le Memo n'a pas de TCanvas»
Il suffit de lui en assigner un.
Note que la méthode est valable pour tous les compos qui n'ont pas de Canvas!..

Il me semble qu'avec cet exemple tu devrais t'en tirer:



procedure TForm1.Button1Click(Sender: TObject);
  var
              DC    : HDC;
              Fonte: HFONT;
  begin
  DC := GetDC(Memo1.Handle); //Un Device Context pour le Memo
  SetBkMode(DC, TRANSPARENT); //Background remains untouched
  Fonte := CreateFont(
                      0, // logical height of font
                      0, // logical average character width
                      0, // angle of escapement
                      0, // base-line orientation angle
                      FW_NORMAL, // font weight
                      0, // italic attribute flag
                      0, // underline attribute flag
                      0, // strikeout attribute flag
                      DEFAULT_CHARSET, // character set identifier
                      0, // output precision
                      CLIP_DEFAULT_PRECIS, // clipping precision
                      DEFAULT_QUALITY, // output quality
                      DEFAULT_PITCH or FF_DONTCARE, // pitch and family
                      PChar('Arial') // pointer to typeface name string
                      );
  SelectObject(DC, Fonte);
  TextOut(DC, 10, 20, PChar('Mon texte...'), Length('Mon texte...'));



  DeleteObject(Fonte);
  ReleaseDC(Memo1.Handle, DC);
end
Commenter la réponse de Caribensila
Messages postés
297
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
2
0
Merci
Bonjour,

Merci pour la réponse.

Ce que je cherche à faire c'est dimentionner un TEdit avec la taille de la chaine 'XXXXXXX' en pixel et de le placer au dessus de cette chaine.
Le but est de cacher cette chaine de référence. Pour placer mon TEdit, j'utilise la propriété Left et Top du composant.
Ce que je n'arrive pas à faire c'est de convertir une position en X caractére et Y ligne du TMemo vers des pixels qui me permettront de placer mon TEdit dessus. De plus, ma méthode pour connaitre la taille de la chaine XXXXXXXXX en pixel n'est pas élégante et ne fonctionne pas bien non plus.

Ta méthode, je la place précieusement de coté car je vois d'autre utilisation sympa avec mais elle ne répond pas à mon probléme.

Merci encore.

Oniria
Commenter la réponse de Oniria
0
Merci
Mais non Cari a raison car ce dernier admet les propriétés TextWidth et TextHeight qui te renvoyent la largueur et la hauteur d'un string en pixel .

Par contre tu devrais revoir ton code : il y a de l'optimisation à faire
Commenter la réponse de Utilisateur anonyme