Faire perdre le focus d'une editbox

Résolu
Mastersam Messages postés 116 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2008 - 15 sept. 2005 à 21:35
Mastersam Messages postés 116 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2008 - 19 sept. 2005 à 20:40
Bonjour, j'ai un léger soucis, je voudrais faire perdre le focus d'une edit box pour récuperer sa valeur après l'appui sur la touche entrer.

J'ai essayé d'intercepter le message WM_KEYDOWN ou WM_CHAR dans ma fenetre mère, mais dès que mon curseur est dans l'edit alors ces messages ne sont plus détectés.

Que faire ? Merci d'avance pour m'indiquer une piste de réflexion.

http://www.rc-bot.com/

10 réponses

racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
18 sept. 2005 à 15:50
Le principe du sous-classement est très simple:

Chaque contrôle (Edit, Bouton, Static etc...) a une procédure par
défaut qui le gère. Cette procédure est invisible car elle est gérée
par le système. SetWindowLong() nous
permet de récupérer l'adresse de cette procédure et puis la remplacer
par l'adresse de notre procédure de sous-classement. Ainsi tous
les messages destinés à la procédure originale sont interceptés dans la
procédure de sous-classement. Si on fait return 0
dans le traitement d'un message, celui-ci ne sera pas envoyé à la
procédure originale. C'est justement le but recherché. Pour laisser
passer les autres messages on utilise CallWindowProc() comme dans l'exemple.
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
15 sept. 2005 à 22:57
Quel besoin de s'occuper du focus pour cela ??? Mets un bouton IDOK en defpush et sa procédure sera lancée à l'appui de ENTER.

ciao...
BruNews, MVP VC++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
16 sept. 2005 à 11:55
salut,

tu peux aussi "subclass(er)" la fonction:
SetWindowLong(hwEdit,GWL_WNDPROC,&myWndProc);
dans ta wndproc, tu utilise:
LRESULT CallWindowProc(

WNDPROC lpPrevWndFunc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
pour appeler l'ancien handler.

@++
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
16 sept. 2005 à 16:43
Salut,

Moi aussi, comme patatalo, je préfère le sous-classement. Voici un exemple:
// Variable déclarée en global:


WNDPROC OldEditProc;

// Procédure de sous-classement de l'Edit:


LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)


{


switch (message)


{


case WM_CHAR:


// Empêcher le beep après appui sur ENTREE:


if (wParam == VK_RETURN) return 0;


break;




case WM_KEYDOWN:


// Si la touche tapée est "ENTREE":


if (wParam == VK_RETURN)


{


// Faire ce qu'on veut ici:

// ..........


return 0;


}


break;




default:


break;


}


// Appeler la procédure originale:


return CallWindowProc(OldEditProc, hwnd, message, wParam, lParam);


}


Dans le traitement du message WM_CREATE ou WM_INITDIALOG, tu fais ceci:

OldEditProc= (WNDPROC) SetWindowLong(hEdit, GWL_WNDPROC, (LPARAM)EditProc);

Il faut que l'Edit soit déjà crée avant d'appeler SetWindowLong().

Pour plus de détails tu peux regarder ma source:

http://www.cppfrance.com/codes/NAVIGATEUR-WEB-API-/29247.aspx
0

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

Posez votre question
Mastersam Messages postés 116 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2008
16 sept. 2005 à 23:12
Bon j'ai un peu plus de mal avec le sousclassement des proc car en plus je n'ai pas qu'une seule editbox pour laquelle ceci doit fonctionner mais 32 alors ça me fait bcp de procédures ...

Parcontre j'ai essayé avec ce qu'a dit Brunews mais j'ai pas du tout comprendre car ça ne veut pas marcher. Voilà ce que j'ai ajouté à mon code:

Après la création de ma fenetre "dmxwindow" où se trouvent mes edits j'envoie:

SendMessage(dmxwindow,DM_SETDEFID,ID_DEFAULTBUTTON,0);

Pour préciser l'handle virtuel du bouton par defaut. J'ai une première question à ce sujet : doit il réellement exister ce bouton ?

Puis logiquement l'appuie sur "entrée" quand mon curseur de texte est dans un edit box çà envoie le message WM_COMMAND comme si j'avais appuyé sur le defpush : ID_DEFAULTBUTTON

Donc j'intercepte son handle dans le case WM_COMMAND de ma procedure de gestion de ma "dmxwindow"

if(LOWORD(wParam)==ID_DEFAULTBUTTON){
SetFocus(hwnd);
}

Et je remet mon focus sur ma fenetre entière ce qui va envoyer un EN_KILLFOCUS et déclencher la prise en compte de la valeur de mon edit box (bout de code qui existe déjà).

Mais hélas rien ne se passe quand j'appuie sur entrée, parcontre le fait d'appeler SetFocus(hwnd); déclenche bien l'effet escompté. J'utilise d'ailleurs cette méthode pour prendre ma valeur de l'edit lorsqu'un clic de souris survient.

Je suis en C (pas++) sous dev-cpp ... si ça a une importance ...

Merci

http://www.rc-bot.com/
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 sept. 2005 à 23:43
Mets direct le style BS_DEFPUSHBUTTON à la création de ton bouton.

Je n'avais quasi rien compris à ta question mais le sous classement est de loin la meilleure manière de procéder pour controler les entrées utilisateur. Ce n'est pas parce qu'on a X edit qu'il faudra X editProc, la même editProc peut servir à tous les rdit pour lesquels tu veux un traitement ressemblant.

ciao...
BruNews, MVP VC++
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
17 sept. 2005 à 18:36
Oui c'est vrai tu peux utiliser une seule procédure de sous-classement
pour tes 32 Edits. J'ai déjà fait un programme utilisant ce principe.
J'ai déclaré les HWND de mes 20 Edits dans un tableau en global. Pareil
pour les WNDPROC pour les procédure originales:

HWND hEdit[20];

WNDPROC oldproc[20];

Une autre variable globale sert à préciser l'Edit courant:

int courant;

"courant" est récupéré apès clic dans l'un des 20 Edits grâce à une boucle:

case WM_COMMAND:

for (int j=0;j<20;j++)

{

if( (HWND)lParam == hEdit[j]) break;

}

courant =j;

break;



SetWindowLong est utilisée dans une autre boucle:

for (int i=0;i<20;i++)

{

oldproc[i]= (WNDPROC) SetWindowLong(hEdit[i], GWL_WNDPROC, (LPARAM)EditProc);

}



Dans la procédure de sous-classement j'ai fait:

case WM_KEYDOWN:
if (wParam == VK_RETURN)
{
// Appeler la fonction de récupération du contenu de l'Edit
SetFocus(hEdit[courant+1]; // Passer le focus à l'Edit suivant
return 0;
}
break;

//............

return CallWindowProc(oldproc[courant], hwnd, message, wParam, lParam);

J'espère que ça aidera.
0
Mastersam Messages postés 116 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2008
17 sept. 2005 à 19:16
Bon je dois être un peu mal doué j'ai fait :

HWND boutondefaultdmx;
boutondefaultdmx = CreateWindowEx(0,
"BUTTON",
"",
WS_CHILD|BS_DEFPUSHBUTTON,
nbcanauxparpage*31-44,
244,
50,
20,
hwnd,
(HMENU)ID_DEFAULTBUTTON,
g_hInst,
NULL);

puis j'intercepte toujours :

if(LOWORD(wParam)==ID_DEFAULTBUTTON){
SetFocus(hwnd);
}

http://www.rc-bot.com/
0
Mastersam Messages postés 116 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2008
18 sept. 2005 à 00:39
... suite du message (ça a merdé chef)

Mais rien ne se passe. Je vais tenter le subclassement même si j'ai un peu de mal à le comprendre. Mais j'aimerais savoir pourquoi je n'arrive pas à faire fonctionner la méthode de Brunews qui me conviendrais mieux je pense.

http://www.rc-bot.com/
0
Mastersam Messages postés 116 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2008
19 sept. 2005 à 20:40
Bon merci beaucoup, j'ai maintenant compris la philosophie du subclassement et j'ai appliqué la méthode avec succés dans mon projet.

http://www.rc-bot.com/
0
Rejoignez-nous