J'ai à maintenir un programme C++ qui simule la frappe clavier sur une
autre fenêtre. Par exemple, ayant détecté une fenêtre qui demande un nom
de login et un mot de passe, c'est le programme en question qui saisit
les informations à la place de l'utilisateur.
Mon problème, c'est que le programme est sensible à l'état de certaines
touches du vrai clavier (par exemple Shift ou Caps Lock), alors que
j'aimerais que ça ne soit pas le cas.
Le code actuel utilise les fonctions suivantes ;
VkKeyScan(...)
GetKeyboardState(...)
SetKeyboardState(...)
MapVirtualKey(...)
PostMessage(... WM_KEYDOWN...)
PostMessage(... WM_KEYUP...)
Je ne publie pas le code, à moins que ce ne soit vraiment nécessaire.
En fait, j'ai fait des recherches sur Internet, et vu quelqu'un
déconseiller les PostMessage(... WM_KEYDOWN...) et PostMessage(...
WM_KEYUP...) en faveur de keybd_event(), et du coup en lisant la
doc j'ai vu que SendInput() était conseillé à la place.
Bref, je n'y comprends rien, et j'aimerais savoir s'il existe quelque
part un exemple de code qui marche et que je pourrais repomper.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Christian ASTOR
On 21 fév, 16:23, Olivier Miakinen <om+ wrote:
En fait, j'ai fait des recherches sur Internet, et vu quelqu'un déconseiller les PostMessage(... WM_KEYDOWN...) et PostMessage(... WM_KEYUP...) en faveur de keybd_event(), et du coup en lisant la doc j'ai vu que SendInput() était conseillé à la place.
Bref, je n'y comprends rien, et j'aimerais savoir s'il existe quelque part un exemple de code qui marche et que je pourrais repomper.
Oui, il faut utiliser keybd_event() ou SendInput() (après avoir mis la fenêtre en foreground, avec SwitchToThisWindow() par ex)
On 21 fév, 16:23, Olivier Miakinen <om+n...@miakinen.net> wrote:
En fait, j'ai fait des recherches sur Internet, et vu quelqu'un
déconseiller les PostMessage(... WM_KEYDOWN...) et PostMessage(...
WM_KEYUP...) en faveur de keybd_event(), et du coup en lisant la
doc j'ai vu que SendInput() était conseillé à la place.
Bref, je n'y comprends rien, et j'aimerais savoir s'il existe quelque
part un exemple de code qui marche et que je pourrais repomper.
Oui, il faut utiliser keybd_event() ou SendInput()
(après avoir mis la fenêtre en foreground, avec SwitchToThisWindow()
par ex)
En fait, j'ai fait des recherches sur Internet, et vu quelqu'un déconseiller les PostMessage(... WM_KEYDOWN...) et PostMessage(... WM_KEYUP...) en faveur de keybd_event(), et du coup en lisant la doc j'ai vu que SendInput() était conseillé à la place.
Bref, je n'y comprends rien, et j'aimerais savoir s'il existe quelque part un exemple de code qui marche et que je pourrais repomper.
Oui, il faut utiliser keybd_event() ou SendInput() (après avoir mis la fenêtre en foreground, avec SwitchToThisWindow() par ex)
Oui, il faut utiliser keybd_event() ou SendInput() (après avoir mis la fenêtre en foreground, avec SwitchToThisWindow() par ex)
Je ne connaissais pas cette fonction, qui peut m'être très utile en effet. Malgré tout, la doc m'inquiète un peu : <cit. http://msdn2.microsoft.com/en-us/library/ms633553(VS.85).aspx> However, this function is deprecated and not intended for general use. It is recommended that you do not use it in new programs because it might be altered or unavailable in subsequent versions of Windows. </>
Est-ce que l'une des options de ShowWindow() ferait la même chose, par exemple SW_RESTORE ou SW_SHOW ?
Un vieil ex de fonction pour simuler du texte =>
void GenerateText(char* sText) { [...] }
Un grand merci pour cet exemple !
Le 21/02/2008 16:42, Christian ASTOR a écrit :
Oui, il faut utiliser keybd_event() ou SendInput()
(après avoir mis la fenêtre en foreground, avec SwitchToThisWindow()
par ex)
Je ne connaissais pas cette fonction, qui peut m'être très utile en
effet. Malgré tout, la doc m'inquiète un peu :
<cit. http://msdn2.microsoft.com/en-us/library/ms633553(VS.85).aspx>
However, this function is deprecated and not intended for general use.
It is recommended that you do not use it in new programs because it
might be altered or unavailable in subsequent versions of Windows.
</>
Est-ce que l'une des options de ShowWindow() ferait la même chose, par
exemple SW_RESTORE ou SW_SHOW ?
Oui, il faut utiliser keybd_event() ou SendInput() (après avoir mis la fenêtre en foreground, avec SwitchToThisWindow() par ex)
Je ne connaissais pas cette fonction, qui peut m'être très utile en effet. Malgré tout, la doc m'inquiète un peu : <cit. http://msdn2.microsoft.com/en-us/library/ms633553(VS.85).aspx> However, this function is deprecated and not intended for general use. It is recommended that you do not use it in new programs because it might be altered or unavailable in subsequent versions of Windows. </>
Est-ce que l'une des options de ShowWindow() ferait la même chose, par exemple SW_RESTORE ou SW_SHOW ?
Un vieil ex de fonction pour simuler du texte =>
void GenerateText(char* sText) { [...] }
Un grand merci pour cet exemple !
Christian ASTOR
On 21 fév, 17:00, Olivier Miakinen <om+ wrote:
However, this function is deprecated
MSDN met souvent ça, alors que les apis sont utilisées par Windows lui- même (taskmgr entre autres pour cette api) Mais si le prog a déjà, comme cité, "détecté une fenêtre qui dem ande un nom de login et un mot de passe", c'est peut-être inutile si le focus est déjà mis.
On 21 fév, 17:00, Olivier Miakinen <om+n...@miakinen.net> wrote:
However, this function is deprecated
MSDN met souvent ça, alors que les apis sont utilisées par Windows lui-
même (taskmgr entre autres pour cette api)
Mais si le prog a déjà, comme cité, "détecté une fenêtre qui dem ande
un nom de login et un mot de passe", c'est peut-être inutile si le
focus est déjà mis.
MSDN met souvent ça, alors que les apis sont utilisées par Windows lui- même (taskmgr entre autres pour cette api) Mais si le prog a déjà, comme cité, "détecté une fenêtre qui dem ande un nom de login et un mot de passe", c'est peut-être inutile si le focus est déjà mis.
Olivier Miakinen
Le 21/02/2008 17:40, Christian ASTOR a écrit :
However, this function is deprecated
MSDN met souvent ça, alors que les apis sont utilisées par Windows lui- même (taskmgr entre autres pour cette api)
:-D
Mais si le prog a déjà, comme cité, "détecté une fenêtre qui demande un nom de login et un mot de passe", c'est peut-être inutile si le focus est déjà mis.
Cela pourrait me servir dans un cas où l'envoi des caractères se fait très lentement, et qu'il est possible de perdre le focus avant la fin.
Le 21/02/2008 17:40, Christian ASTOR a écrit :
However, this function is deprecated
MSDN met souvent ça, alors que les apis sont utilisées par Windows lui-
même (taskmgr entre autres pour cette api)
:-D
Mais si le prog a déjà, comme cité, "détecté une fenêtre qui demande
un nom de login et un mot de passe", c'est peut-être inutile si le
focus est déjà mis.
Cela pourrait me servir dans un cas où l'envoi des caractères se fait
très lentement, et qu'il est possible de perdre le focus avant la fin.
MSDN met souvent ça, alors que les apis sont utilisées par Windows lui- même (taskmgr entre autres pour cette api)
:-D
Mais si le prog a déjà, comme cité, "détecté une fenêtre qui demande un nom de login et un mot de passe", c'est peut-être inutile si le focus est déjà mis.
Cela pourrait me servir dans un cas où l'envoi des caractères se fait très lentement, et qu'il est possible de perdre le focus avant la fin.
Olivier Miakinen
Le 21/02/2008 16:42, Christian ASTOR a écrit :
Un vieil ex de fonction pour simuler du texte =>
void GenerateText(char* sText) { [...] }
Ça ne marche pas. :-(
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas dans le cas contraire. Par exemple,
Voici le code que j'appelle pour essayer d'annuler ça, d'abord _SaveAndResetKeyboardState() avant d'appeler ta fonction, puis _RestoreKeyboardState() quand c'est terminé :
INPUT input[9]; int idx = 0; ZeroMemory(input, sizeof input); if (bKbState[VK_CAPITAL] & 0x80) { // Touche Caps lock enfoncée : on la relâche KEYRELEASE(input, idx, VK_CAPITAL); } if (bKbState[VK_CAPITAL] & 0x01) { // Voyant Caps lock allumé : on l'éteint KEYPRESS(input, idx, VK_CAPITAL); KEYRELEASE(input, idx, VK_CAPITAL); } if (bKbState[VK_LSHIFT] & 0x80) { // Touche Shift gauche enfoncée : on la relâche KEYRELEASE(input, idx, VK_LSHIFT); } if (bKbState[VK_RSHIFT] & 0x80) { // Touche Shift droit enfoncée : on la relâche KEYRELEASE(input, idx, VK_RSHIFT); } if (bKbState[VK_LCONTROL] & 0x80) { // Touche Ctrl gauche enfoncée : on la relâche KEYRELEASE(input, idx, VK_LCONTROL); } if (bKbState[VK_RCONTROL] & 0x80) { // Touche Ctrl droit enfoncée : on la relâche KEYRELEASE(input, idx, VK_RCONTROL); } if (bKbState[VK_LMENU] & 0x80) { // Touche Alt gauche enfoncée : on la relâche KEYRELEASE(input, idx, VK_LMENU); } if (bKbState[VK_RMENU] & 0x80) { // Touche Alt droit enfoncée : on la relâche KEYRELEASE(input, idx, VK_RMENU); } SendInput(idx, input, sizeof INPUT); return TRUE; } static BOOL _RestoreKeyboardState(BYTE *bKbState) { INPUT input[9]; int idx = 0; ZeroMemory(input, sizeof input); switch (bKbState[VK_CAPITAL] & 0x81) { case 0x81: // La touche était enfoncée, le voyant allumé KEYPRESS(input, idx, VK_CAPITAL); break; case 0x01: // La touche était relâchée, le voyant allumé KEYPRESS(input, idx, VK_CAPITAL); KEYRELEASE(input, idx, VK_CAPITAL); break; case 0x80: // La touche était enfoncée, le voyant éteint KEYPRESS(input, idx, VK_CAPITAL); KEYRELEASE(input, idx, VK_CAPITAL); KEYPRESS(input, idx, VK_CAPITAL); break; } if (bKbState[VK_LSHIFT] & 0x80) { // La touche Shift gauche était enfoncée KEYPRESS(input, idx, VK_LSHIFT); } if (bKbState[VK_RSHIFT] & 0x80) { // La touche Shift droit était enfoncée KEYPRESS(input, idx, VK_RSHIFT); } if (bKbState[VK_LCONTROL] & 0x80) { // La touche Ctrl gauche était enfoncée KEYPRESS(input, idx, VK_LCONTROL); } if (bKbState[VK_RCONTROL] & 0x80) { // La touche Ctrl droit était enfoncée KEYPRESS(input, idx, VK_RCONTROL); } if (bKbState[VK_LMENU] & 0x80) { // La touche Alt gauche était enfoncée KEYPRESS(input, idx, VK_LMENU); } if (bKbState[VK_RMENU] & 0x80) { // La touche Alt droit était enfoncée KEYPRESS(input, idx, VK_RMENU); } SendInput(idx, input, sizeof INPUT); return TRUE; }
Quand la touche Shift est enfoncée, aucun caractère n'est envoyé. Et quand le voyant Caps Lock est allumé, il y a quelques caractères qui sont échangés (M->m, m->M, 8->_, _->8).
Le 21/02/2008 16:42, Christian ASTOR a écrit :
Un vieil ex de fonction pour simuler du texte =>
void GenerateText(char* sText)
{
[...]
}
Ça ne marche pas. :-(
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune
touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas
dans le cas contraire. Par exemple,
Voici le code que j'appelle pour essayer d'annuler ça, d'abord
_SaveAndResetKeyboardState() avant d'appeler ta fonction, puis
_RestoreKeyboardState() quand c'est terminé :
INPUT input[9];
int idx = 0;
ZeroMemory(input, sizeof input);
if (bKbState[VK_CAPITAL] & 0x80) {
// Touche Caps lock enfoncée : on la relâche
KEYRELEASE(input, idx, VK_CAPITAL);
}
if (bKbState[VK_CAPITAL] & 0x01) {
// Voyant Caps lock allumé : on l'éteint
KEYPRESS(input, idx, VK_CAPITAL);
KEYRELEASE(input, idx, VK_CAPITAL);
}
if (bKbState[VK_LSHIFT] & 0x80) {
// Touche Shift gauche enfoncée : on la relâche
KEYRELEASE(input, idx, VK_LSHIFT);
}
if (bKbState[VK_RSHIFT] & 0x80) {
// Touche Shift droit enfoncée : on la relâche
KEYRELEASE(input, idx, VK_RSHIFT);
}
if (bKbState[VK_LCONTROL] & 0x80) {
// Touche Ctrl gauche enfoncée : on la relâche
KEYRELEASE(input, idx, VK_LCONTROL);
}
if (bKbState[VK_RCONTROL] & 0x80) {
// Touche Ctrl droit enfoncée : on la relâche
KEYRELEASE(input, idx, VK_RCONTROL);
}
if (bKbState[VK_LMENU] & 0x80) {
// Touche Alt gauche enfoncée : on la relâche
KEYRELEASE(input, idx, VK_LMENU);
}
if (bKbState[VK_RMENU] & 0x80) {
// Touche Alt droit enfoncée : on la relâche
KEYRELEASE(input, idx, VK_RMENU);
}
SendInput(idx, input, sizeof INPUT);
return TRUE;
}
static BOOL _RestoreKeyboardState(BYTE *bKbState)
{
INPUT input[9];
int idx = 0;
ZeroMemory(input, sizeof input);
switch (bKbState[VK_CAPITAL] & 0x81) {
case 0x81:
// La touche était enfoncée, le voyant allumé
KEYPRESS(input, idx, VK_CAPITAL);
break;
case 0x01:
// La touche était relâchée, le voyant allumé
KEYPRESS(input, idx, VK_CAPITAL);
KEYRELEASE(input, idx, VK_CAPITAL);
break;
case 0x80:
// La touche était enfoncée, le voyant éteint
KEYPRESS(input, idx, VK_CAPITAL);
KEYRELEASE(input, idx, VK_CAPITAL);
KEYPRESS(input, idx, VK_CAPITAL);
break;
}
if (bKbState[VK_LSHIFT] & 0x80) {
// La touche Shift gauche était enfoncée
KEYPRESS(input, idx, VK_LSHIFT);
}
if (bKbState[VK_RSHIFT] & 0x80) {
// La touche Shift droit était enfoncée
KEYPRESS(input, idx, VK_RSHIFT);
}
if (bKbState[VK_LCONTROL] & 0x80) {
// La touche Ctrl gauche était enfoncée
KEYPRESS(input, idx, VK_LCONTROL);
}
if (bKbState[VK_RCONTROL] & 0x80) {
// La touche Ctrl droit était enfoncée
KEYPRESS(input, idx, VK_RCONTROL);
}
if (bKbState[VK_LMENU] & 0x80) {
// La touche Alt gauche était enfoncée
KEYPRESS(input, idx, VK_LMENU);
}
if (bKbState[VK_RMENU] & 0x80) {
// La touche Alt droit était enfoncée
KEYPRESS(input, idx, VK_RMENU);
}
SendInput(idx, input, sizeof INPUT);
return TRUE;
}
Quand la touche Shift est enfoncée, aucun caractère n'est envoyé. Et
quand le voyant Caps Lock est allumé, il y a quelques caractères qui
sont échangés (M->m, m->M, 8->_, _->8).
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas dans le cas contraire. Par exemple,
Voici le code que j'appelle pour essayer d'annuler ça, d'abord _SaveAndResetKeyboardState() avant d'appeler ta fonction, puis _RestoreKeyboardState() quand c'est terminé :
INPUT input[9]; int idx = 0; ZeroMemory(input, sizeof input); if (bKbState[VK_CAPITAL] & 0x80) { // Touche Caps lock enfoncée : on la relâche KEYRELEASE(input, idx, VK_CAPITAL); } if (bKbState[VK_CAPITAL] & 0x01) { // Voyant Caps lock allumé : on l'éteint KEYPRESS(input, idx, VK_CAPITAL); KEYRELEASE(input, idx, VK_CAPITAL); } if (bKbState[VK_LSHIFT] & 0x80) { // Touche Shift gauche enfoncée : on la relâche KEYRELEASE(input, idx, VK_LSHIFT); } if (bKbState[VK_RSHIFT] & 0x80) { // Touche Shift droit enfoncée : on la relâche KEYRELEASE(input, idx, VK_RSHIFT); } if (bKbState[VK_LCONTROL] & 0x80) { // Touche Ctrl gauche enfoncée : on la relâche KEYRELEASE(input, idx, VK_LCONTROL); } if (bKbState[VK_RCONTROL] & 0x80) { // Touche Ctrl droit enfoncée : on la relâche KEYRELEASE(input, idx, VK_RCONTROL); } if (bKbState[VK_LMENU] & 0x80) { // Touche Alt gauche enfoncée : on la relâche KEYRELEASE(input, idx, VK_LMENU); } if (bKbState[VK_RMENU] & 0x80) { // Touche Alt droit enfoncée : on la relâche KEYRELEASE(input, idx, VK_RMENU); } SendInput(idx, input, sizeof INPUT); return TRUE; } static BOOL _RestoreKeyboardState(BYTE *bKbState) { INPUT input[9]; int idx = 0; ZeroMemory(input, sizeof input); switch (bKbState[VK_CAPITAL] & 0x81) { case 0x81: // La touche était enfoncée, le voyant allumé KEYPRESS(input, idx, VK_CAPITAL); break; case 0x01: // La touche était relâchée, le voyant allumé KEYPRESS(input, idx, VK_CAPITAL); KEYRELEASE(input, idx, VK_CAPITAL); break; case 0x80: // La touche était enfoncée, le voyant éteint KEYPRESS(input, idx, VK_CAPITAL); KEYRELEASE(input, idx, VK_CAPITAL); KEYPRESS(input, idx, VK_CAPITAL); break; } if (bKbState[VK_LSHIFT] & 0x80) { // La touche Shift gauche était enfoncée KEYPRESS(input, idx, VK_LSHIFT); } if (bKbState[VK_RSHIFT] & 0x80) { // La touche Shift droit était enfoncée KEYPRESS(input, idx, VK_RSHIFT); } if (bKbState[VK_LCONTROL] & 0x80) { // La touche Ctrl gauche était enfoncée KEYPRESS(input, idx, VK_LCONTROL); } if (bKbState[VK_RCONTROL] & 0x80) { // La touche Ctrl droit était enfoncée KEYPRESS(input, idx, VK_RCONTROL); } if (bKbState[VK_LMENU] & 0x80) { // La touche Alt gauche était enfoncée KEYPRESS(input, idx, VK_LMENU); } if (bKbState[VK_RMENU] & 0x80) { // La touche Alt droit était enfoncée KEYPRESS(input, idx, VK_RMENU); } SendInput(idx, input, sizeof INPUT); return TRUE; }
Quand la touche Shift est enfoncée, aucun caractère n'est envoyé. Et quand le voyant Caps Lock est allumé, il y a quelques caractères qui sont échangés (M->m, m->M, 8->_, _->8).
Olivier Miakinen
Le 22/02/2008 14:57, j'écrivais :
[...] Par exemple,
Saleté d'interface chaise-clavier ! ;-)
Bon, je crois que le message reste compréhensible malgré cette phrase non terminée.
Le 22/02/2008 14:57, j'écrivais :
[...] Par exemple,
Saleté d'interface chaise-clavier ! ;-)
Bon, je crois que le message reste compréhensible malgré cette phrase
non terminée.
Bon, je crois que le message reste compréhensible malgré cette phrase non terminée.
Christian ASTOR
On 22 fév, 14:57, Olivier Miakinen <om+ wrote:
Ça ne marche pas. :-(
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas dans le cas contraire.
Oui, il faut tester l'état du clavier avant, le modifier et le remettre à l'état initial Par ex, ceci marche chez moi (XP SP2) sur le Notepad et j'obtiens bien dans tous les cas : "Hello ! 12345&é'(~#{[" =>
On 22 fév, 14:57, Olivier Miakinen <om+n...@miakinen.net> wrote:
Ça ne marche pas. :-(
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune
touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas
dans le cas contraire.
Oui, il faut tester l'état du clavier avant, le modifier et le
remettre à l'état initial
Par ex, ceci marche chez moi (XP SP2) sur le Notepad et j'obtiens bien
dans tous les cas :
"Hello ! 12345&é'(~#{["
=>
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas dans le cas contraire.
Oui, il faut tester l'état du clavier avant, le modifier et le remettre à l'état initial Par ex, ceci marche chez moi (XP SP2) sur le Notepad et j'obtiens bien dans tous les cas : "Hello ! 12345&é'(~#{[" =>
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas dans le cas contraire.
Oui, il faut tester l'état du clavier avant, le modifier et le remettre à l'état initial
C'est bien ce que je croyais avoir fait avec GetKeyboardState() et SendInput() !
Par ex, ceci marche chez moi (XP SP2) sur le Notepad et j'obtiens bien dans tous les cas : "Hello ! 12345&é'(~#{[" =>
[...]
Encore merci, j'essaye ça tout de suite.
Le 22/02/2008 17:13, Christian ASTOR a écrit :
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune
touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas
dans le cas contraire.
Oui, il faut tester l'état du clavier avant, le modifier et le
remettre à l'état initial
C'est bien ce que je croyais avoir fait avec GetKeyboardState() et
SendInput() !
Par ex, ceci marche chez moi (XP SP2) sur le Notepad et j'obtiens bien
dans tous les cas :
"Hello ! 12345&é'(~#{["
=>
Plus exactement, cette fonction fait bien ce qu'il faut quand aucune touche n'est enfoncée et que le voyant Caps Lock est éteint, mais pas dans le cas contraire.
Oui, il faut tester l'état du clavier avant, le modifier et le remettre à l'état initial
C'est bien ce que je croyais avoir fait avec GetKeyboardState() et SendInput() !
Par ex, ceci marche chez moi (XP SP2) sur le Notepad et j'obtiens bien dans tous les cas : "Hello ! 12345&é'(~#{[" =>
[...]
Encore merci, j'essaye ça tout de suite.
Olivier Miakinen
Le 22/02/2008 17:20, je répondais à Christian ASTOR :
Encore merci, j'essaye ça tout de suite.
Malheureusement ça ne fonctionne toujours pas : aucun caractère n'est reçu par Notepad quand la touche Shift est enfoncée. :-(
Je soupçonne un effet de bord dû à un bout de code ailleurs que là où je suis en train de regarder... je vais essayer de mettre des traces un peu partout ! En tout cas merci encore pour ton aide.
Le 22/02/2008 17:20, je répondais à Christian ASTOR :
Encore merci, j'essaye ça tout de suite.
Malheureusement ça ne fonctionne toujours pas : aucun caractère n'est
reçu par Notepad quand la touche Shift est enfoncée. :-(
Je soupçonne un effet de bord dû à un bout de code ailleurs que là où je
suis en train de regarder... je vais essayer de mettre des traces un peu
partout ! En tout cas merci encore pour ton aide.
Le 22/02/2008 17:20, je répondais à Christian ASTOR :
Encore merci, j'essaye ça tout de suite.
Malheureusement ça ne fonctionne toujours pas : aucun caractère n'est reçu par Notepad quand la touche Shift est enfoncée. :-(
Je soupçonne un effet de bord dû à un bout de code ailleurs que là où je suis en train de regarder... je vais essayer de mettre des traces un peu partout ! En tout cas merci encore pour ton aide.