Aide - Recherche - Membres - Calendrier
Version complète : Assigner une variable à un champ (field) d'écran
Les Forums de PalmAttitude.org > GENERAL PalmOS > Développement sous PalmOS
naguttes
Je crois que je ne comprend vraiment rien à tout ces handle, pointeur et leur utilisation avec le Palm. 8O
Patrice il va falloir qu'on organise une autre session pour que tu nous (m')apprennes tout ça icon_question.gif , mais ça fera l'objet d'un autre post. Tout de suite j'aimerai bien qu'on m'explique comment assigner une variable à un champ. Je vous explique mon problème :
J'ai une structure qui contient un enregistrement que j'ai récupéré (ou initialisée à zéro en cas de création). Cette structure se présente un peu comme ceci
typedef struct {
UInt16 Number;
UInt16 Tome;
UInt16 Type;
UInt16 Status;
UInt16 Publisher;
UInt16 PurchaseDate;
Char Title[MaxLenTitre];
Char STitle[MaxLenTitre];
Char Note[MaxLenNote];
} LivreRec;

J'ai déclaré une variable "record" correspondant à cette structure et je voudrais maintenant savoir comment affecter chacune des zones de ce "record" à un champ de mon écran.
J'ai regardé dans la doc où l'on parle de changer le Handle sur lequel pointe le champ mais je ne sais pas comment créer un handle à partir de "record" (mais je n'ai peut être rien compris icon_bla.gif )
Patrice
Pas tout simple...

D'abord, tu récupères un "handle" sur le record comme suit (dbref est la référence reçue à l'ouverture de la base et index, le numéro de l'enregistrement que tu veux lire) :

MemHandle hRecord = DmGetRecord(dbref, index);
void * pRecord = MemHandleLock(hRecord);

Pour les champs numériques, il faut d'abord les "traduire" en texte. Tu as plusieurs moyens pour cela, dont en voici 1 (pour le champ number) :

MemHandle hNumber = MemHandleNew(6);
Char * pNumber = MemHandleLock(hNumber);
StrPrintF(pNumber, "%d", pRecord -> Number);
MemHandleUnlock(hNumber);

Et pour afficher le champ dans un "field" :

FldSetHandle(pField, hNumber);

Tu dois faire pareil pour tous les champs qu'il faut formater d'une façon ou d'une autre. N'oublie pas de "libérer" le record lorsque tu en as fini avec son contenu (et de supprimer hNumber quand tu termines tout) :

MemHandleUnlock(hRecord);

Pour les champs texte de ton enregistrement, tu peux utiliser directement le texte du record (mais lis les remarques qui suivent !), par exempel pour le titre :

FldSetText(pField, hRecord, 12, MaxLenTitre);

La différence entre ces deux méthodes est importante :
Dans le premier cas, tu fais une copie (formatée) du champ. Donc si tu modifies le champ texte, c'est le programme qui doit faire la modification dans le record.
Dans le second cas, c'est le record qui est associé au champ, il est donc modifié "sur place" (et attention aux débordements de taille dans ce cas !).
naguttes
Merci je vais étudier tout çà probablement ce we.

Tiens je t'offre un coup à boire en attendant les prochaines questions anim_pint.gif
naguttes
J'ai jeté un coup d'oeil à tes conseils et je dois mal m'y prendre car j'avais bien compris qu'il y avait un risque à affecter directement le record de la base au champ à cause des modifications éventuelles que l'utilisateur fait. J'avais donc décidé de stocker préalablement l'enregistrement dans des variables globales en faisant comme suit :
MemHandle RecordH;
LivreRec *Record;
LivreRec TempRecord;


RecordH=DmQueryRecord(LivreDB, recordNum);
Record=MemHandleLock(RecordH);
TempRecord=*Record;
MemHandleUnlock(RecordH);

Donc pour moi j'ai stocké mes données dans une structure temporaire (TempRecord) et libéré l'enregistrement. Après mon problème est d'affecter cette structure temporaire à mes champs.
Puis je faire quelque chose comme

MemHandle hChar = MemHandleNew(sizeof(MaxLenTitre));
Char * pChar = MemHandleLock(hChar);
Affectation de TempRecord.Titre à pChar ? Comment?
FldSetHandle(Field, pChar);

MemHandleUnlock(hChar); // une fois que je quitte l'écran ou tout de suite aprés l'affectation?
Patrice
Pas de solution "élégante" dans ce cas. Il faut que tu alloues dynamiquement ton "record" temporaire (un MemHandleNew) et tu repars comme indiqué ci-dessus. Et il te reste toujours à traiter les variables numériques...
Patrice
Accessoirement, il existe la fonction "FldSetTxtPtr' qui pourrait prendre en paramètre un "Char *". Mais dans ce cas, le champ ne doit pas être modifiable.
naguttes
D'abord Patrice, je suis un peu vexé que tu suggères que je programme de façon pas élégante icon_evil.gif (non je plaisante icon_lol2.gif )

Ceci dit, je suis désolé mais je n'y arrive pas.
J'ai initialisé mon ma structure en "dur" (je verrai après pour la remplir à partir d'un enreg)

gRecord.Number=1;
gRecord.Type=2;
gRecord.Status=NULL;
gRecord.Publisher=NULL;
gRecord.PurchaseDate=NULL;
gRecord.Titre[0]='a';
gRecord.Titre[1]='b';
gRecord.Titre[2]=0;
FrmCustomAlert(custAlrtID, "Init rec", "titre", gRecord.Titre);
gRecord.SousTitre[0]=0;
gRecord.Note[0]=0;

Et maintenant je veux assigner mes champs d'écran aux zones de cette structure. J'ai essayé de suivre tes explications en faisant ce qui suit :
static void AssignMainField()
{
MemHandle oldTextH, recordH;
LivreRec *recordP;
FieldPtr field;
FormPtr form;

recordH=MemHandleNew(12+MaxLenTitre+MaxLenTitre+MaxLenNote);
recordP=MemHandleLock(recordH);
recordP=&gRecord;
form = FrmGetActiveForm();
field = FrmGetObjectPtr(form, FrmGetObjectIndex(form, fldTitre));
FldSetText(field, recordH, 12, MaxLenTitre);
MemHandleUnlock(recordH);

}

mais ça donne n'importe quoi à l'execution. Peux tu m'aider encore.
Je ne sais opas si ça aide mais mes fonctions d'initialisation et d'assignation sont appelées à l'ouverture de la "form".
Patrice
CITATION(naguttes)
recordP=MemHandleLock(recordH);  
recordP=&gRecord;

Quand tu écris ces deux lignes : 1) tu demandes un pointeur sur le record 2) tu remplaces le pointeur par l'adresse de ton record, recordP contient simplement l'adresse de ton record "statique", sans aucun rapport avec le handle que tu as alloué. Pour faire ce que tu souhaites, il faut que tu copies ton record gRecord sur la zone allouée dynamiquement, pointée par recordP (code approximatif, je n'ai pas les API en mémoire) :
recordP=MemHandleLock(recordH);
MemCopy(recordP, gRecord, siaeof(RECORD));
naguttes
Je me sens un peu bête icon_bla.gif mais ça marche
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.