Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

GetAsyncKeyState et MessageBox en bisbille

6 réponses
Avatar
Gloops
Bonjour tout le monde,

J'affiche des informations dans un formulaire Windows, en les=20
temporisant =E0 l'aide de l'API Sleep (jusqu'=E0 ce que quelqu'un me sign=
ale=20
une m=E9thode C# int=E9gr=E9e pour le faire).

A l'issue de ce d=E9lai, je veux laisser =E0 l'utilisateur la possibilit=E9=
=20
d'annuler un traitement en ayant press=E9 la touche d'=E9chappement.=20
J'utilise donc l'API GetAsyncKeyState((int) 27), et le traitement n'est=20
r=E9alis=E9 que si elle me retourne 0.

=E7a, =E7a marche bien, mais alors maintenant si la valeur de retour est =
non=20
nulle, je voudrais accuser r=E9ception par

MessageBox.Show("Annulation demand=E9e par l'utilisateur");

Mais voil=E0, =E7a, =E7a ne marche pas.

Le programme passe bien sur cette instruction, ce que je peux constater=20
en mettant une pause dessus (breakpoint), mais le message ne s'affiche pa=
s.

Quelqu'un aurait-il d=E9j=E0 remarqu=E9 une incompatibilit=E9 entre Messa=
geBox=20
et les API utilis=E9es ? Et, par la m=EAme occasion, une solution=20
aurait-elle =E9t=E9 trouv=E9e ? Il y aurait bien cr=E9er un autre formula=
ire,=20
enfin si il y avait une solution =E9l=E9gante ...

6 réponses

Avatar
Jérémy Jeanson
Bonjour Gloops,

Ton soucis semble venir de l'utilisation que tu fais de la méthode
GetAsyncKeyState et non d'une incompatibilité.

Pourquoi est ce que je dis cela ?... en fait quand tu utilises une
méthode provenant de Win32 ou autre tu ne fais qu'inclure une
déclaration de méthodes, structure, callback... etc...
Cela n'a pas d'influence sur le comportement de ton code, c'est lui qui
utilises ces méthodes et qui éventuellement s'abonne à un évènement. il
faudrait donc que tu nous montres un peu le code que tu utilises pour
que l'on puisse t'aider et trouver ce qui cloche.

J'ai récemment utilisé ce genre d'inclusions dans mes codes pour
intercepter la souris et le clavier et je n'ai pas rencontré de soucis
(hors mis dans une solution pour Média center qui n'aime pas vraiment).
Donc à plusieurs on devrait pouvoir faire quelque chose pour toi
--
Jérémy JEANSON
MCP
http://www.jjeanson.fr
Avatar
Gloops
[MessageBox qui ne s'affiche pas après GetAsyncKeyState : voir le code
car il n'y a pas d'incompatibilité de principe, la réponse risque d e
se trouver dans le code]
_____________________________________________________

Bonjour Jérémy,

Ah, d'accord, le code. Mais c'est que ça fait un morceau, hein. Au poin t
que je viens d'y définir des #region sinon je m'y perdais. Faute d'avoi r
eu à temps l'idée de passer par une impression PDF (avec dans les
options "Hide collapsed regions") pour récupérer en format texte le c ode
avec les noms de régions, et corriger l'indentation après (sauf si
quelqu'un sait obtenir automatiquement le résultat avec l'indentation
correcte), j'ai été bon pour recopier ça moi-même au clavier, com me on
fait à l'école quand on n'a pas été sage. Je mets ça ici à la fin.

Je suis en train d'écrire un programme pour purger les répertoires
temporaires, parce que répéter la commande d'effacement après chaqu e
fichier verrouillé qu'on rencontre, ça va un moment, et après ça finit
par lasser. Dans l'explorateur il faut répéter la commande dix fois p our
vider un répertoire temporaire (selon le nombre de fichiers ou
sous-répertoires verrouillés), il me semble plus raisonnable de pouvo ir
vider dix répertoires en une commande (on se doute que ça va plus vit e,
mais après avoir essayé, au début quand je ne mettais rien à
l'affichage, j'ai vérifié trois fois tellement c'était impressionna nt).

Il doit probablement exister déjà des programmes de purge en
téléchargement, mais ça m'apprendra sûrement plus de faire le mie n que
de découvrir ceux qui existent et finalement y passer peut-être autan t
de temps.

Pour le moment, comme on pouvait s'y attendre, j'ai contourné ce
problème de message qui n'apparaissait pas en créant un formulaire, a vec
une jolie image de touche d'échappement, j'espère ne pas avoir d'ennu is
avec ça pour piratage ...
La question reste donc posée par curiosité.

Ci-dessous c'est le code du bouton de purge (promis, le bouton suivant
ne s'appelle pas button2 :) ). En dehors de ça (donc en dehors du sujet
du fil), hier soir j'ai traité l'ajout de répertoire sélectionné par
FolderBrowserDialog et la suppression, il restera à traiter l'ajout d'u n
répertoire spécial, le fonctionnement silencieux, et pour finir la
globalisation car contrairement à mon habitude cette fois j'ai attaqué
directement en Français. C'est vrai que si je fais tout ça je diminue la
probabilité que ça aille plus vite que d'en télécharger un :)

Je finirai peut-être bien par proposer la source quelque part.

Le formulaire comprend une checkedListbox avec la liste des répertoires
temporaires à purger (stockés dans un fichier texte, objet d'un autre
fil pas loin), un Label (oui bon une étiquette) pour afficher le nom du
répertoire en cours de traitement (en plus de sa sélection automatiqu e
dans la checkedListbox), et un ListView pour afficher le contenu du
répertoire en cours de traitement (plus bien entendu quelques boutons).

Alors voici le plan, après le détail de la région temporiserAfficha ge.
Le MessageBox.Show("Abandon demandé par l'utilisateur") qui m'a posé
problème constituait la région abandon, qui donc maintenant comporte
l'affichage d'un formulaire en mode dialogue.


#region temporiserAffichage
this.Refresh();
Sleep(5000);
int intKey = GetAsyncKeyState((int) 27);
#endregion

private void button1_Click(object sender, EventArgs e)
{

initialiserListviewEtFso

foreach (int indexChecked in checkedListBox1.CheckedIndices)
{
listView1.Items.Clear();

SelectionItemListBox

decompteFichiersSousRepertoires

if (c > 0 || nr > 0)
{

remplirListView

temporiserAffichage

if (intKey == 0)
{

SuppressionFichiers

SuppressionSousRepertoires

}
else
{
abandon
}
listView1.Items.Clear();

}
else
{
afficherCheminNonTraite

}
}
this.lblCheminRep.Text = "";
this.checkedListBox1.SelectedIndex = -1;
}

_____________________________________________
Jérémy Jeanson a écrit, le 13/05/2009 12:20 :
Bonjour Gloops,

Ton soucis semble venir de l'utilisation que tu fais de la méthode
GetAsyncKeyState et non d'une incompatibilité.

Pourquoi est ce que je dis cela ?... en fait quand tu utilises une
méthode provenant de Win32 ou autre tu ne fais qu'inclure une
déclaration de méthodes, structure, callback... etc...
Cela n'a pas d'influence sur le comportement de ton code, c'est lui qui
utilises ces méthodes et qui éventuellement s'abonne à un évè nement. il
faudrait donc que tu nous montres un peu le code que tu utilises pour
que l'on puisse t'aider et trouver ce qui cloche.

J'ai récemment utilisé ce genre d'inclusions dans mes codes pour
intercepter la souris et le clavier et je n'ai pas rencontré de souci s
(hors mis dans une solution pour Média center qui n'aime pas vraiment ).
Donc à plusieurs on devrait pouvoir faire quelque chose pour toi


Avatar
Jérémy Jeanson
Bonjour Gloops,

Je crois avoir saisi ton souci. En fait tu utilises une boucle dans
laquelle tu attends un certain temps et ensuite tu regarde si
l'utilisateur a voulu annulé l'opération.

On est un peu loin de ce que tu voudrais où l'aspect "asynchrone"
serrait de mise. Tu es dans un dispositif séquentiel et rien d'autre
dans lequel le dernier état entre deux opérations est testé et
uniquement cela et malheureusement entre deux opérations et donc deux
périodes d'attente un test peu raté car ton thread était en pause (ou
sommeil si on veut traduire littéralement le sleep) et donc ne pas
t'afficher ta boite de dialogue. Donc l'approche d'un formulaire affiché
et d'une méthode (thread managé ou job de backgroundworker) qui serrait
interrompue de manière asynchrone est plus avisé (abort du thread ou
cancel du job du backgroundworker).
--
Jérémy JEANSON
MCP
http://www.jjeanson.fr
Avatar
Gloops
Bon, effectivement le BackgroundWorker peut être une piste.
Ce qui m'intrigue dans ton explication, c'est que pourtant la touche
d'échappement a bien été détectée, puisque le formulaire de mes sage
s'affiche proprement, c'est juste MessageBox qui ne fonctionne pas à la
place (ou seulement une fois sur dix).

Ou le fait d'ouvrir un autre formulaire ouvre un autre thread, même en
dialogue ?
_____________________________________________
Jérémy Jeanson a écrit, le 14/05/2009 08:20 :
Bonjour Gloops,

Je crois avoir saisi ton souci. En fait tu utilises une boucle dans
laquelle tu attends un certain temps et ensuite tu regarde si
l'utilisateur a voulu annulé l'opération.

On est un peu loin de ce que tu voudrais où l'aspect "asynchrone"
serrait de mise. Tu es dans un dispositif séquentiel et rien d'autre
dans lequel le dernier état entre deux opérations est testé et
uniquement cela et malheureusement entre deux opérations et donc deux
périodes d'attente un test peu raté car ton thread était en pause (ou
sommeil si on veut traduire littéralement le sleep) et donc ne pas
t'afficher ta boite de dialogue. Donc l'approche d'un formulaire affich é
et d'une méthode (thread managé ou job de backgroundworker) qui ser rait
interrompue de manière asynchrone est plus avisé (abort du thread o u
cancel du job du backgroundworker).


Avatar
Jérémy Jeanson
Bonjour Gloops,

Oui la fameuse fois sur dix où le test est fait mais qu'une autre
opération a peut être eu lieu en parallèle mais qu'elle n'est pas dans
mise dans une quelconque fille d'attente vu qu'il n'y as pas de
traitement asynchrone... et donc quelle fini dans le vide... plouf dans
l'eau.

Et puis il y a le fameux Sleep... je commence de plus en plus à
comprendre pourquoi on le déconseille dans les applications (hors mis un
context de tes unitaires)
--
Jérémy JEANSON
MCP
http://www.jjeanson.fr
Avatar
Gloops
Jérémy Jeanson a écrit, le 14/05/2009 10:06 :
Et puis il y a le fameux Sleep... je commence de plus en plus à
comprendre pourquoi on le déconseille dans les applications (hors mis un
context de tes unitaires)



Oui, d'accord ; toutefois ça n'explique toujours pas qu'avec le
formulaire de message en mode dialogue ça fonctionne très bien.