Aide - Recherche - Membres - Calendrier
Version complète : prob de listes
Les Forums de PalmAttitude.org > GENERAL PalmOS > Développement sous PalmOS
yogi
salut à tous !
ma question est la suivante :
je dois crééer pour un programme une liste que l'utilisateur pourra modifier (ajout et suppression d'éléments)
j'ai trouvé dans la doc une fonction qui s'appelle SetDrawFunction à laquelle on passe la liste des éléments ainsi qu'une fonction que l'on crééer soit meme et qui permet de dessiner un éléments de la liste (des chaines de caracteres), voici le prototype de la fonction :
CODE
void LstSetDrawFunction (ListType *listP,

ListDrawDataFuncPtr func)

j'ai crééer ma fonction mais je ne comprend pas l'erreur qui est génére (je parle pas du warning). dans la doc la fonction est donnee sans parametre..

j'ajoute que je travail avec CodeWarrior.

merci pour votre aide.. et A+
Caporal Kro
Déjà le premier paramètre de la callback function doit être un short, puis toi tu en as faite une qui prend un unsigned short.
La ligne est coupée sur la photo mais ton troisième paramètre doit être un char **, vérifie aussi.
Les types de paramètres de ton DrawAString doivent matcher exactement avec le type ListDrawDataFunc
yogi
oui tu as entièrement raison, merci ! c'est ca de suivre la doc a la lettre rolleyes.gif
par contre y'a un truk qui me chifonne, je comprend pas comment je dois modifier/crééer le contenu du
CODE
**Item text  
qui est le derniere parametre de la fonction
CODE
DrawOneString
.

d'après ce que j'ai vu l'accès direct aux champs d'une liste n'est pas possible
l'idée est qu'a chaque fois que le user donne une chaine de caractere dans un champs d'édition, je la récupère et l'ajoute a la liste.

j'y pense je vais aussi rester un peu sur ce forum histoire d'aider si je le peut les gens.
Caporal Kro
Ce dernier paramètre, j'ai fini par renoncer à y toucher. Ca me pétait à la face avec des insultes en anglais. En fait maintenant je l'ignore carrément et je m'en porte beaucoup mieux rolleyes.gif .
Mes lignes de texte sont stockées ailleurs, dans un tableau et suivant le numéro de la ligne je fais mon WinDrawChars en me servant du second paramètre pour la position, comme ceci:
CODE
procedure DessineTrace(ItemNum: Int16; Limites: RectanglePtr; var Contenu: PChar);

var

 pcTemp: PChar;

begin

 if ItemNum < StringList.Count(slTrace) then begin

   pcTemp := StringList.Strings(slTrace,ItemNum);

   WinDrawChars(pcTemp, StrLen(pcTemp), Limites.TopLeft.x, Limites.TopLeft.y);

 end;

end;

8O euh... comme tu vois c'est du pascal
Patrice
Le dernier paramètre de la fonction est un pointeur vers le texte de l'item à afficher si tu as défini au préalable le contenu de la liste (soit en ressources, soit avec la fonction LstSetListChoices()). Si tu n'as pas "rempli" la liste, le pointeur est indéfini et ça te pête à la tronche, normal icon_lol2.gif
yogi
CITATION(Patrice)
Le dernier paramètre de la fonction est un pointeur vers le texte de l'item à afficher si tu as défini au préalable le contenu de la liste (soit en ressources, soit avec la fonction LstSetListChoices()). Si tu n'as pas "rempli" la liste, le pointeur est indéfini et ça te pête à la tronche, normal icon_lol2.gif

ok patrice. tu défini ta fonction qui est ton dernier parametre. mais ce qui m'échappe c'est que vu qu'a l'appel, tu passe ta fonction sans parametre
CODE
LstSetDrawFunction(list,DrawOnesString);
la ou

DrawOnesString est ma fonction, comment je fais pour définir une liste de sting différents a chaque appel, c'est a dire que lorsque un bouton "ajout" est pressé, je dois récupérer le string fourni par le user et l'ajouter dans cette liste.
je sais pas si je suis clair.
yogi
CITATION(Patrice)
Le dernier paramètre de la fonction est un pointeur vers le texte de l'item à afficher si tu as défini au préalable le contenu de la liste (soit en ressources, soit avec la fonction LstSetListChoices()). Si tu n'as pas "rempli" la liste, le pointeur est indéfini et ça te pête à la tronche, normal icon_lol2.gif


bon je me suis remis sur le prob, ca avance mais je comprend toujours pas

je me suis défini ma fonction de call back. et voici le code que je met juste pour dessiner les éléments de ma liste
CODE
LstSetListChoices (list,NULL,2);

LstSetDrawFunction(list,DrawOneString);

LstDrawList(list);

ce code m'affiche effectivement mon string, mais a un detail près, il m'affiche le string n fois dans n ligne (selon la valeur du param de LstSetListChoices ici 2).
la question que je me pose donc, c'est comment je dois faire pour afficher des chaine différentes dans chaque lignes.
j'ai vu dans la doc qu'on peut récupréer une ressource de type chaine de caractere, seulement moi je peut pas, puisk'à la base la liste est censée etre vide et que c'est le user qui est sensé crééer sa propre liste.
Patrice
Dans ta fonction de dessin (DrawOneString), c'est à toi de dessiner la chaîne correspondant à la ligne à afficher (pour ça, l'OS te passe en paramètre l'indice de la rangée à afficher).
yogi
merci pour ton aide patrice !

j'arrive en effet maintenant à afficher ma list de chaine de caractère dans ma liste c'est cool.

mais y'a une dernière question que je me permet de te poser.
tu fait comment pour modifier la ressource StringTable que tu récupère pour afficher ta liste ? en effet j'utilise la ressource StringTable dans ma fonction SysStringByIndex comme suis :
CODE
void DrawOneString(Int16 itemNum, RectangleType *bounds, char **text)

{

     UInt16 no=1;

     #pragma unused(text)

     Char s[kMaxTableStringLength+1];

     SysStringByIndex(monStringTable, (UInt16)itemNum, s,

     sizeof(s));

     WinDrawChars(s, StrLen(s),bounds->topLeft.x, bounds->topLeft.y);

}

j'ai un peu de peine avec cette doc :?
Patrice
Je ne suis pas certain de comprendre ta question mais il est impossible (pas simplement, en tous cas) de modifier une ressource de ton exécutable dans ton code. Si tu veux modifier le contenu de la liste, tu dois utiliser une autre "source" pour tes strings (un pdb, les préférences ou autre...).
yogi
CITATION(Patrice)
Je ne suis pas certain de comprendre ta question mais il est impossible (pas simplement, en tous cas) de modifier une ressource de ton exécutable dans ton code. Si tu veux modifier le contenu de la liste, tu dois utiliser une autre "source" pour tes strings (un pdb, les préférences ou autre...).

ok c'est ce que je voulais savoir. les ressource (que je créée dans mon cas avec le Pilrc designer) ne sont pas modifiable depuis mon code (ou en tout cas pas simplement comme tu le dit).
donc ce que je dois faire c'est utiliser un pdb. en passant c'est quoi les préférence ?
merci bkp pour ton aide. tu m'as enlever une sacré épine du pied. anim_wink.gif
Patrice
Les "préférences", c'est une base de données spéciale du Palm qui te permet d'enregistrer facilement des ... préférences pour ton programme... Il y a un chapitre dans le Reference Guide PalmOS consacré à ce sujet anim_wink.gif
yogi
merci patrice pour ton aide ! je stocke dorénavant mes chaines dans une ressource pdb. et je peut ajouter mes string dans ma liste. seulement y'a un truc qui est bizarre, c'est que lorsque je sélectionne un élément de la liste, j'ai droit à un joli crash.
je récupère l'évenement de selection avec un lstSelectEvent. normalement c'est la bonne méthode nan ?
Patrice
CITATION(yogi)
merci patrice pour ton aide ! je stocke dorénavant mes chaines dans une ressource pdb. et je peut ajouter mes string dans ma liste. seulement y'a un truc qui est bizarre, c'est que lorsque je sélectionne un élément de la liste, j'ai droit à un joli crash.
je récupère l'évenement de selection avec un lstSelectEvent. normalement c'est la bonne méthode nan ?

Ca c'est la bonne méthode, mais tu dois faire quelque chose de pas catholique quand tu traites l'événement... anim_wink.gif
yogi
CITATION(Patrice)
CITATION(yogi)
merci patrice pour ton aide ! je stocke dorénavant mes chaines dans une ressource pdb. et je peut ajouter mes string dans ma liste. seulement y'a un truc qui est bizarre, c'est que lorsque je sélectionne un élément de la liste, j'ai droit à un joli crash.
je récupère l'évenement de selection avec un lstSelectEvent. normalement c'est la bonne méthode nan ?

Ca c'est la bonne méthode, mais tu dois faire quelque chose de pas catholique quand tu traites l'événement... anim_wink.gif

ouais... doit y avoir un problème avec mon pdb. parce que quand dans le lstSelectEvent je tente de dessiner des string prédéfini dans les ressource y'a pas de probleme. c'est lorsque je tente d'afficher des string provenant de la pdb que ca crashe... je fais pourtant bien attention a ouvrir la base et a la fermer a chaque accès aux données :? . je continue a chercher
yogi
vala a titre d'indication la belle erreur dans l'émulateur

Patrice
Le message t'indique juste que tu attaques une zone mémoire qui ne t'appartient pas. Si tu veux tu peux poster l'extrait de code pour mieux voir...
yogi
cet extrait de code se trouve dans le gestionnaire d'évenement de ma form. ce qui est étonnant c'est que la sélection du premier élément ne pose pas de problème.
CODE
case lstSelectEvent:

   error = OuvrireBase();    

   frmP= FrmGetActiveForm();

   list1=(ListPtr) FrmGetObjectPtr(frmP,FrmGetObjectIndex

                     ( frmP,lstProduitsClassesProduits));

   list2=(ListPtr) FrmGetObjectPtr(frmP, FrmGetObjectIndex

                     (frmP,lstProduitsProduits));

   no= LstGetSelection (list1);

   if (no==0){    Index=DmNumRecords (gDB2);

    LstSetDrawFunction(list2,DrawOneString);

    LstSetListChoices (list2,NULL,Index);

    LstDrawList(list2);

  }

  if (no==1){

               Index=DmNumRecords (gDB2);

    LstSetDrawFunction(list2,DrawOneString);

    LstSetListChoices (list2,NULL,Index);

               LstDrawList(list2);

  }

  if (no==2){

    Index=DmNumRecords (gDB2);

    LstSetDrawFunction(list2,DrawOneString);

    LstSetListChoices (list2,NULL,Index);

    LstDrawList(list2);

  }

  handled=true;

  error = DmCloseDatabase(gDB2);

  break;


voici ma fonction de dessin des éléments.
j'ouvre ma base avant de l'utiliser
CODE
void DrawOneString(Int16 itemNum, RectangleType *bounds, char **text)

{

       #pragma unused(text)

       MemHandle maresponse;

       StructType *produit1;

       Char* nom;

       maresponse=DmQueryRecord(gDB2,itemNum);

       produit1=MemHandleLock(maresponse);

       nom=produit1->NomProduit;

       WinDrawChars(nom, StrLen(nom),bounds->topLeft.x, bounds-  

       >topLeft.y);

       produit1=(StructType*)MemHandleUnlock(maresponse);

}
Patrice
Ton code a plusieurs problèmes mais je ne vois pas "immédiatement" ce qui cause ton erreur (corrige d'abord celles-là et on en rediscute) :

- L'événement "lstSelectEvent" va t'arriver pour tes deux listes, tu risques donc de traiter des événements de la liste 2 comme s'ils venaient de la 1

- Dans les 3 cas (que tu devrais plutôt programmer avec un "switch" qu'avec une série de "if"), tu fais le même traitement (mais ça te regarde)

- Tu ne gères pas les cas d'erreur (à l'ouverture de la base et sur le QueryRecord) : à mon avis tu dois en avoir une mais comme tu l'ignores, ça crashe (c'est la vie et il faut s'habituer à tester les codes retour, règle n°1 du développeur).

- Et tu devrais aussi tester dans DrawOneString() que gDB2 est valide avant de chercher un record...

- De toutes manières tu vas avoir un gros problème avec ton code : la liste peut être ré-affichée par l'OS sans que tu lui demandes quoi que ce soit (essaye avec une ROM debug, tu vas comprendre). Et l'OS va appeler ta fonction DrawOneString(). Mais malheureusement tu fermes la base dès que tu as fini de gérer l'événement icon_arrow.gif crash garanti 100%. Ta base doit être ouverte tout le temps pendant lequel la liste est affichée. Le plus simple est de l'ouvrir au démarrage ou à l'ouverture de la form et de la refermer en quittant ou à la fermeture de la form. C'est peut-être ça la cause de ton bug mais je ne me rappelle plus si LstDrawList() redessine tout de suite ou s'il poste un événement ultérieur (quand ta base est déjà fermée).
yogi
bonne nouvelle patrice.. j'ai résolu mon prob.
en fait c'etait effectivement du à la base de donnée, mais aussi au fait que la structure de mon code n'était pas très correct !

un grand merci ! je te mettrait dans les remerciement de mon rapport de travail
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2008 Invision Power Services, Inc.