Reprendre un programme où il a été quitté ?

docdoc - 26 déc. 2012 à 23:29
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 - 31 déc. 2012 à 17:29
DOCDOC

voilà je suis en train de réaliser un programme pour "interroger" des techniciens (tout en amenant une formation ludique)
au départ on saisit son identité, puis on clique sur le premier item, on vpoit la question, on saisit sa réponse qui est enregistré en arr plan non visible dans un rich edit qui pourra être imprimé...mais il y 45 items ! à 4 minutes en moyenne par item !! ... donc ma question

comment je peux faire pour que l'on puisse arrêter le "jeu" et revenir le lendemain par exemple pour reprendre à la question quittée sans être obligé de reprendre depuis le début

je suppose qu'il faille passer par une base de données ? mais après ?

Par avance, merci

17 réponses

cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
27 déc. 2012 à 00:37
Bonsoir;

qu'il faille passer par une base de données

pas nécessairement, sauf, si tu as besoin de conserver des archives et faire des stats.
il faut néanmoins un stockage.

cantador
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
27 déc. 2012 à 12:22
Salut,


[quote=Cantador][quote=DocDoc]qu'il faille passer par une base de données/quote

pas nécessairement, sauf, si tu as besoin de conserver des archives et faire des stats.
il faut néanmoins un stockage.
/quote
en effet ... un simple fichier texte suffit déjà

[hr]@+Cirec
[hr]
0
DOCDOC

merci de vous intêresser à mon cas mais je suis perdu
- différence entre base de données et stockage ?
- un simple text suffit ?
pour enregistrer d'accord ... mais comment se repositionner à l'endroit où le programme a été quitté ?
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
27 déc. 2012 à 13:39
Salut DOCDOC
si je comprends bien c'est comme dans un jeu, tu fais une sauvegarde avant d'arrêter et tu veux pouvoir redémarrer à la même place
principe :
avant de quitter tu sauves toutes les variables du jeu (valeurs, positions ...) dans un fichier genre "type"

type
  StructFichier = record
   var1 : integer;
   var2 : string;
   ...
   end;

VAR : MonFIC : file of StructFichier;
      DATA : StructFichier;

Sauvegarde :

DATA.var1 := xxxx;
DATA.var2 := yyyy;

assignfile(monFIC,'SVG.bin'):
Rewrite(monFIC);
Write(monFIC,DATA);
CloseFile(monFIC);

puis pour récupérer, dans l'autre sens

AssignFile(MonFIC,'SVG.bin');
Reset(MonFIC);
Read(MonFIC,DATA);
CloseFile(MonFIC);

ensuite :
xxxx := DATA.var1;
yyyy := DATA.var1;
;;;



Bien sur c'est pas du code à récupérer tel quel, il faut l'adapter, voir les exemples etc ..
C'est juste un principe qui vaut ce qu'il vaut !


Dubois77
site perso
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
DOCDOC
merci Dubois77, je vais essayé de ce coté
0
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
27 déc. 2012 à 20:24
Salut,

Pourquoi pas la solution à dubois77, mais attention, il faut impérativement utiliser des chaînes courtes (ShortString, AnsiString, ...) à la place des "string" qui sont un pointeur sur un espace mémoire de taille non déterminable par avance pour le compilateur :

type
  StructFichier = record
    var1 : integer;
    var2 : string[255]; // <- par exemple
    ...
  end;
0
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
27 déc. 2012 à 20:26
J'utiliserais même plutôt un "packed record" par précaution...
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
28 déc. 2012 à 07:24
Exact Korgis
une autre solution consiste à utiliser un Tstringlist avec mon unité GestH (voir dernier source posté)


Dubois77
site perso
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
30 déc. 2012 à 20:49
Salut,

Pour info, il y a aussi la solution du fainéant-qui-veut-pas-s'prendre-la-tête-mais-qui-est-quand-même-partisan-des_trucs-bluffants qui consiste à utiliser des routines de mise en flux de composants (VOIR: WriteComponentResFile et ReadComponentResFile).

En supposant que l'interface du questionnaire soit entièrement contenu dans le TPanel MonPanel, ça donnerait quelque chose comme :

procedure SauverInterface;
  begin
  WriteComponentResFile(ChangeFileExt(Application.ExeName,'.dat'),MonPanel);
end;


procedure ChargerInterface;
begin
   if FileExists(ChangeFileExt(Application.ExeName,'.dat')) then begin
     ReadComponentResFile(ChangeFileExt(Application.ExeName,'.dat'),MonPanel);
     MonPanel.Parent:=self; //NB: ne se fait pas automatiquement après le chargement
   end;
end;
non testé cause fainéantise
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
31 déc. 2012 à 09:07
Salut Caribensila
J'ai testé, et à priori tel quel ça ne marche pas
Il y a bien un fichier .dat qui se crée du genre :

TPANEL 0S TPF0TPanelMonPanelLeftpTop8Width±Height CaptionMonPanelTabOrder

qui à priori ne sauvegarde que le setbounds, pas le contenu des objets
j'ai regardé la doc F1, cela ne m'aide pas trop (Ecrit des composants et leurs propriétés dans un fichier en utilisant un format de ressources)
(le "TEXT" du Tedit le le "LINES" du Tmemo sont pourtant des propriétés (je crois !)
Je pense toutefois qu'on peut surement faire quelque chose de ce coté là, reste à trouver ce qu'il faut ajouter pour que tout soit sauver



Dubois77
site perso
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
31 déc. 2012 à 10:18
Salut Dubois,

Te v'là pris en flagrant délit de fainéantise !

Je pense que ça ne marche pas parce que, si je me souviens bien, le compos sauvegardé doit être le Owner des compos enfants (en plus d'être le parent, bien sûr).
Et pour ça, le plus simple est de créer les compos enfants en RunTime je crois.
En tout cas ça marche très bien parce que je l'ai déjà utilisé.

Tiens-moi au courant.
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
31 déc. 2012 à 11:27
J'ai créé les objets dans le formcreate et j'ai fait la sauvegarde près avoir rempli un tedit et un tmemo :
impec le contenu est sauvé
mais j'arrive pas à le recharger correctement
je ne sais pas si je dois recréer les compos avant de recharger ?
j'ai essayé les 2 cas et les 2 plantent !
Quant au owner je ne sais pas comment l'utiliser
désolé je cale un peu !
Dubois77
site perso
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
31 déc. 2012 à 13:10
Le Parent est responsable de l'affichage alors que le Owner est responsable de la destruction de l'objet. En général on affecte le Owner dans le constructeur :

NewEdit := TEdit.Create(MonPanel);
NewEdit.Parent := MonPanel;
...

Mais il est aussi possible de changer le Owner en RunTime.
Voici une petite routine permettant de faire ça (non testée) :

procedure MoveOwner(AComp,AFrom,ATo : TComponent);
  begin
  if not (AComp is TControl) then begin
    AFrom.RemoveComponent(AComp);
    ATo.InsertComponent(AComp);
  end;
end;



Si tu n'arrives pas à recharger correctement, c'est sans doute parce que tu ne fais pas le ménage avant de recharger :

for i:=MonPanel.ComponentCount-1 Downto 0 do MonPanel.Components[i].Free;


Mais ce n'est pas obligatoire. En fait, tout dépend du comportement souhaité. Si tu ne fais pas le ménage avant de recharger, les compos chargés s'ajouteront à la suite de ceux déjà présents.

Le plus simple est de faire des tests pour comprendre le principe.
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
31 déc. 2012 à 14:56
J'ai cela dans le formecreate :
         ED1 := Tedit.Create(MonPanel);
         ED1.Parent := MonPanel;
         ED1.Left := 10;
         ED1.Top  := 10;
         MM1 := Tmemo.Create(MonPanel);
         MM1.Parent := MonPanel;
         MM1.Left := 10;
         MM1.Top  := 50;


tant que je touche à rien, le panel s'affiche correctement avec le tedit et le tmemo

j'ai 2 boutons : CHARGER SAUVER :
procedure TForm1.SAUVERClick(Sender: TObject);
begin
  WriteComponentResFile(ChangeFileExt(Application.ExeName,'.dat'),MonPanel);
end;

procedure TForm1.CHARGERClick(Sender: TObject);
var i:integer;
begin
for i:=MonPanel.ComponentCount-1 Downto 0 do MonPanel.Components[i].Free;
if FileExists('essais.dat') then
  begin
    ReadComponentResFile('essais.dat',MonPanel);
    MonPanel.Parent:=Form1; //NB: ne se fait pas automatiquement après le chargement
  end;
end;


Le sauver comme je l'ai dit plus haut marche bien

le Charger plante avec ce message d'erreur :
"Le projet à procoqué une classe d'exeption EClassNotFound, avec le message 'Class TEdit' non trouvé"

Faut-il insister ?

Dubois77
site perso
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
31 déc. 2012 à 16:55
Comme disait Rutebeuf :
« Tout ce qui pouvait t'advenir t'est advenu ! »
Et c'est un peu de ma faute car je dis tout en plusieurs fois.

Voici une petite démo :
- juste un TPanel sur une fiche !
- L'application sauvegardera et rechargera automatiquement l'interface-utilisateur à chaque utilisation de l'appli.
- L'interface-utilisateur consiste ici en un simple Memo.

UNIT Unit1;

INTERFACE

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  end;

var
  Form1   : TForm1;
  MonMemo : TMemo;

IMPLEMENTATION
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
  begin
  if FileExists(ChangeFileExt(Application.ExeName,'.dat')) then begin
    ReadComponentResFile(ChangeFileExt(Application.ExeName,'.dat') ,Panel1);
    Panel1.Parent:=self;
  end else begin
    MonMemo            := TMemo.Create(Panel1);
    MonMemo.BoundsRect := Rect(5,5,250,150);
    MonMemo.Parent     := Panel1;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
  WriteComponentResFile(ChangeFileExt(Application.ExeName,'.dat'), Panel1);
end;

INITIALIZATION
  RegisterClass(TMemo); // !!! Sinon message "Class TMemo non trouvé" !!!

END.
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
31 déc. 2012 à 17:05
... A première vue, ça n'a pas l'air compliqué, hein ?
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
31 déc. 2012 à 17:29
Pour DOCDOC
Tu peux reprendre la dernière réponse de Caribensila !
Elle fonctionne super
tu mets tout tes compos dans un panel, comme le disait d'ailleurs Caribensila dans son premier message "En supposant que l'interface du questionnaire soit entièrement contenu dans le TPanel MonPanel, "
Moi pour essayer j'ai rajouté un tedit pour voir : pas de problème çà marche impec (ne pas oublier dans ce cas de rajouter dans INITIALIZATION
RegisterClass(TEdit);

Pour Caribensila
Rien à dire, tu es le big !



Dubois77
site perso
0
Rejoignez-nous