Erreur Windows EOSError 1400 : Error_Invalid_Window_Handle

cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011 - 14 nov. 2003 à 15:11
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011 - 27 juil. 2006 à 18:30
bonjour,

Je ne suis pas passé sur le Forum depuis longtemps, je développe en Windev 5.5 en ce moment et mon patron ne gueule dessus des qu'il voit qu'on est sur Internet (je cherche ailleurs sur Paris mais c'est pas la joie en ce moment)

Sur un projet (En delphi sous Windows 2000 Pro) en production depuis quelques mois on a eu le droit à un message "Erreur Windows 1400" qui fait planter TOUTES les Applications et massacrent nos Données (Index Out of Date que l'on arrive à récupérer mais avec 1 à 5% de pertes).

Actuellement on est sur Paradox (très très rapide pour petit volume mais très fragile) avant de changer de BD pour DB2 ou SQLServer on cherche a éliminé ce problème d'erreur 1400

L'erreur ne génère pas d'exception mais fait tout planter direct donc les threads qui calcule avec la BD Paradox en pseudo temps réel le dispatching des articles se plantent laissant des morceaux à moitié validé en DB

Stef Shai Han

10 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
14 nov. 2003 à 17:31
Erreur 1400 : ERROR_INVALID_WINDOW_HANDLE

A défaut de trouver l'origine du problème (pas évident), pourquoi ne travailles-tu pas en mode transactionnel ?
0
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011
14 nov. 2003 à 17:52
je ne connais pas très le transactionnel (Commit-RollBack) sur du Paradox ! je ne savais pas qu'il était capable de le gérer !

Comme je l'ai dit avant c'était du windev 5.5 (Beurk !) et on a eu qu'un seul petit mois pour TOUT refaire en DELPHI !
Donc j'ai eu trop le temps d'étudier ce genre de mécanisme !

Notre application est pseudo temps réel, elle communique avec une application d'interface avec une Trieuse de Vêtement et les temps de traitements DOIVENT être TRES COURT (1 messages toutes les 50 ms en moyenne pour le thread de pilotage plus d'autre thread d'importation et d'exportation de fichier en FTP vers un AS400)

J'ai réussi à reproduire le bug !

j'ai obtenu l'erreur 1400, lors de la fermeture du programme après qu'un thread est fait un appel à ShowMessage !

j'ai essayé ceci

FMessageForm := TForm.Create(Application); -> déclenche une Exception EOSError 1400 à la fermeture du Programme

FMessageForm := TForm.Create(nil); -> le programme se ferme normalement

Je n'ai ni ShowMessage, ni MessageDlg, ni Fenêtre, ni Etat dans mes Threads donc c'est une fontion (API, Composant TTable, TNMFTP, ...?) que j'utilise qui doit afficher un Message et qui fait tout planté, lorsque je n'aurais rien à faire sous Windev, je continuerais des recherches de mon côté ! Si quelqu'un s'interresse à se problème, qu'il n'hésite pas à m'aider !

Stef Shai Han
0
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011
19 nov. 2003 à 10:51
j'ai trouvé dans le forum est topic nommé :
"Soit le Thread, soit l'UDP", je ne sais pas quelle est son groupe

les participants à ce sujet sont : Stailer et Bestiol

Je voudrais savoir si ils ont réussi à solutionné leur problème d'erreur 1400 !

Stef Shai Han
0
lio33 Messages postés 3 Date d'inscription vendredi 5 décembre 2003 Statut Membre Dernière intervention 1 septembre 2014
5 déc. 2003 à 17:06
Bonjour.

j'ai le même type de problème avec une application Delphi.
Cette application utilise des threads dont certains exécutent des showmessage().

Problème : dans l'environnement Delphi l'appli tourne bien et je vois mes showmessage() auquels je réponds par OK et l'appli se termine sans problème.

En autonome, les showmessage() ne sont pas vus ( je ne peux donc pas répondre OK ) et l'appli se termine par un message d'erreur EOSErreur .. Erreur système 1400. handle de fenêtre non valide.

Je pense que cela est du au fait que je ne vois pas mon showmessage() et qu'il doit trainer quelque part en mémoire...
Mais je n'ai pas trouvé la solution. Si vous voyez quelque chose censé m'aider, merci d'avance.
0

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

Posez votre question
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011
8 déc. 2003 à 10:10
Salut,

en fait lorsque tu fais un ShowMessage, Delphi crée une fenêtre avec comme parent

TForm.Create(Application);

donc le seul moyen que j'ai trouvé c'est de reprendre le source de ShowMessage (tu trouverais une fontion MessageDlgPosHelp dans laquelle il y aura CreateMessageDialog)

Ici ce pose DEUX solutions tu refais TOUTES Les fonctions entre ShowMessage et CreateMessageDialog (ce qui fait une demi-douzaine de fonctions), c'est par dur c'est du copier coller et tu modifie

Result := TMessageForm.CreateNew(Application);
en
Result := TMessageForm.CreateNew(nil); // ligne 1702 Dialogs

tu te retrouveras avec une unité du genre ThreadDialogs avec des fonctions ThreadShowMessage et ThreadCreateMessageDialog ...

AUTRE solution BEAUCOUP plus simple fais toi une fenêtre MessageForm sous le RAD de Delphi et utilise cette fenêtre pour tes showmessages !
et lorsque tu crérera ta fenêtre utilise le nil comme paramètre de Create

Moi dans mon problème, j'ai pas de fenêtre dans mes threads donc je sais pas d'où ça vient !

Stef Shai Han
0
DCA_BIGBOSS Messages postés 5 Date d'inscription jeudi 9 octobre 2003 Statut Membre Dernière intervention 28 mai 2006
27 juil. 2006 à 14:12
J'ai aussi cette erreur 1400.

Merci à vous de m'avoir fait réaliser que ça pouvait être dù aux ShowMessage, c'était le cas pour moi.
J'utilise GLScene pour mon application, je vais donc remplacer mes ShowMessage par un TGLForm avec un bouton ;-)

Merci quand même pour tes deux solutions proposées ;-)
0
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011
27 juil. 2006 à 17:40
Bonjour,


Je ne suis plus sur ce projet depuis un bout de temps, il fonctionne tout seul depuis trois ans, on a juste imposé un redémarrage de l'ordinateur toutes les 24h et les jours où ils n'ont l'on pas fait, ils ont du trimer pour remettre en stock tous les articles en cours de dispatch

2 causes possibles :
- la fenêtre pouvait être la TDBEngineErrorDlg, qui devait nous signaler d'un plantage du BDE (il n'aime pas on dirait bosser autant, environ 3 lectures, 3 modification, 1 insertion, 1 suppression en moyenne en l'espace de 50 ms, et cela en permanence pendant 8heures ... les plantages survenaient au bout de 3 jours sans rédémarrer, ce qui correspond à 3 * 8h ... lorsqu'ils sont passé à 2 équipes (2 fois 6h), ça ne tenait plus que 2 jours, ...

- l'erreur pouvait provenir de la fenêtre principal, les threads étaient mal développé en terme de gestion de la VCL, manipulation de Label, de progressBar, sans passer par un Synchronize, ... avec peu de chance, on tombe sur un cycle où windows dispatch ses messages au composant visuel au moment, où notre thread écrit dedans, et pouf erreur 1400 ...

Donc oui, à bannir les ShowMessage; pour le moment, j'ai réussi à créer des forms depuis un thread, mais ça bloque on dirait celle du thread zéro, pas top donc ...

Stef Shai Han
0
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011
27 juil. 2006 à 17:51
En fait, j'ai retrouvé, un programme de test, voici le code

   TThreadMessage = class(TThread)
   private
      procedure PumpMessages();
   public
      procedure Execute(); override;
   end;

---

procedure TThreadMessage.Execute();
var
   ThreadForm: TForm;
   TrayRect: TRect;
   Delay, StartTime: Cardinal;
begin
     ThreadForm := TForm.Create(nil);
     try



        // Noms trouvés avec KillApplic.exe, et l'arborescence que j'ai développé en Juillet 2006
        GetWindowRect(FindWindowEx(FindWindow('Shell_TrayWnd', nil), 0, 'TrayNotifyWnd', nil), TrayRect);



        ThreadForm.Height := 50;
        ThreadForm.Width := 400;
        ThreadForm.Top := (Screen.Height - ThreadForm.Height) - (TrayRect.Bottom - TrayRect.Top + 2);
        ThreadForm.Left := 0;



        ThreadForm.Parent := nil;
        ThreadForm.Show();



        while not Terminated do
        begin
           ThreadForm.Caption := FormatDateTime('dddd dd mmmm yyyy hh:nn:ss', Now());
           ThreadForm.Show();
           ThreadForm.Refresh();



           StartTime := GetTickCount();
           Delay := 0;
           while Delay < 1000 do
           begin
              Sleep(1);
              PumpMessages();
              Delay := GetTickCount() - StartTime;
           end;
        end;



        ThreadForm.Hide();



     finally
        ThreadForm.Free();
     end;



     FreeOnTerminate := True;
end;


// Cette fonction remplace l'Application ProcessMessages, et cela fait des miracles, on peut avoir sa fenêtre principal et plein de fenêtre indépendant qui se débrouille toute seule en Thread ...
procedure TThreadMessage.PumpMessages();
var
   Msg: TMsg;
begin
   while PeekMessage(Msg, 0, 0, 0, pm_Remove) do begin
         TranslateMessage(Msg);
         DispatchMessage(Msg);
   end;   
end;

Stef Shai Han
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
27 juil. 2006 à 17:57
J'ai eut cette erreur cette semaine !

C'était du a du code creant des fenetre depuis un thread. J'avais beau syncroniser la procedure, ma nouvelle form avait un composant avec un faux handle (cause de mon 1400).

la seul "solution" que j'ai trouvé, c'est de ne pas créer cette form depuis un thread.

pour le message, essaie de syncroniser les methodes qui appel des showmessage et autres avec le thread principal.
0
cs_Shai Messages postés 50 Date d'inscription mardi 8 octobre 2002 Statut Membre Dernière intervention 21 décembre 2011
27 juil. 2006 à 18:30
Le Synchronize lance les méthodes de le thread vcl, pour les modifications d'une fenêtre appartenant au thread vcl depuis un autre thread, cela fonctione, dans d'autres cas, il ne faut surtout pas l'utiliser.

le synchronize fait perdre l'intérêt du thread, depuis, je préfère manipuler les fenêtres entre thread d'une façon plus lourde mais non bloquante (un peu moins, car tu veux mettre à jour la progress bar, mais dans le thread vcl tu as un traitement en cours qui ne concerne en rien ton thread, et bien le synchronize te fera attendre, ... pas bon donc ...), en fait le thread contient une structure (faut se la palucher à la main) qui réplique toutes les propriétés utiles (caption, enabled, coleur, position des progressbar, ... le strict minium vital)  des controls à manipuler, et un timer se charge de lire la structure, je pose des sections critique que dans le cas de modification de chaine (opération lente pouvant être interrompu), tous ce qui est scalaire, ne pose pas de problème (ben oui, c'est MOV registre, adresse, puis MOV adresse2, registre mais ma paranoïa veut que je mette des locks partout on ne sait jamais, imaginez que le thread passe à la main entre deux MOV ...) ...

et donc comme je le disais, le code ci-dessous, créer une fenêtre qui fonctionne très bien ... pour la fermer, je fais Thread.Terminate depuis le thread VCL ...

Stef Shai Han
0
Rejoignez-nous