Perte de focus clavier inexpliqué, aide bienvenue !

Perte de focus clavier inexpliqué, aide bienvenue ! - API Win32 - Programmation

Marsh Posté le 19-10-2007 à 13:55:27    

Merci de lire ce sujet et de tester ce programme écrit avec Dev-cpp.
 
- lancez le programme
- appuyez sur quelques touches du clavier : le code de chaque touche s'affiche dans le STATIC
- cliquez sur le bouton
- appuyez sur une touche du clavier : PLUS D'AFFICHAGE DES CODES !
 
Une explication ?
 

Code :
  1. #include <windows.h>
  2. #include <stdio.h>
  3. HINSTANCE instance;
  4. #define ID_PUSHBUTTON_1     110
  5. HWND hVoir;
  6. HWND hBouton;
  7. VOID RemplieFenetrePrincipale(HWND fenetrePrincipale)
  8. {
  9.     hBouton=CreateWindow(
  10.         "BUTTON",
  11.         "Bouton",
  12.         WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
  13.         10,50,
  14.         100,20,
  15.         fenetrePrincipale,
  16.         (HMENU)ID_PUSHBUTTON_1,
  17.         instance,
  18.         NULL);
  19.     hVoir=CreateWindow(
  20.         "STATIC",
  21.         "texte du STATIC",
  22.         WS_CHILD|WS_VISIBLE,
  23.         10,10,
  24.         120,20,
  25.         fenetrePrincipale,
  26.         NULL,
  27.         instance,
  28.         NULL);
  29. }
  30. LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
  31. {
  32.     switch (message)
  33.     {
  34.         case WM_CREATE:
  35.             RemplieFenetrePrincipale(fenetrePrincipale);
  36.             return 0;
  37.         case WM_KEYDOWN:
  38. char chaine[5];
  39. sprintf(chaine, "%d", wParam);
  40. SendMessage(hVoir, WM_SETTEXT, 0, (LPARAM) chaine);
  41.             return 0;
  42.         case WM_COMMAND:
  43.             return 0;
  44.         case WM_DESTROY:
  45.             PostQuitMessage(0);
  46.             return 0;
  47.         default:
  48.             return DefWindowProc(fenetrePrincipale,message,wParam,lParam);
  49.     }
  50. }
  51. int WinMain (HINSTANCE cetteInstance, HINSTANCE precedenteInstance, LPSTR lignesDeCommande, int modeDAffichage)
  52. {
  53.     HWND fenetrePrincipale;
  54.     MSG message;
  55.     WNDCLASS classeFenetre;
  56.     instance = cetteInstance;
  57.     classeFenetre.style = 0;
  58.     classeFenetre.lpfnWndProc = procedureFenetrePrincipale;
  59.     classeFenetre.cbClsExtra = 0;
  60.     classeFenetre.cbWndExtra = 0;
  61.     classeFenetre.hInstance = NULL;
  62.     classeFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  63.     classeFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
  64.     classeFenetre.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
  65.     classeFenetre.lpszMenuName = NULL;
  66.     classeFenetre.lpszClassName = "classeF";
  67. // On prévoit quand même le cas où ça échoue
  68.     if(!RegisterClass(&classeFenetre))
  69.         return FALSE;
  70.     fenetrePrincipale=CreateWindow(
  71.         "classeF",
  72.         "Perte de focus clavier",
  73.         WS_OVERLAPPEDWINDOW,
  74.         CW_USEDEFAULT,
  75.         CW_USEDEFAULT,
  76.         270,
  77.         320,
  78.         NULL,
  79.         NULL,
  80.         cetteInstance,
  81.         NULL);
  82.     if (!fenetrePrincipale)
  83.         return FALSE;
  84.     ShowWindow(fenetrePrincipale,modeDAffichage);
  85.     UpdateWindow(fenetrePrincipale);
  86.     while(GetMessage(&message,NULL,0,0))
  87.     {
  88.         TranslateMessage(&message);
  89.         DispatchMessage(&message);
  90.     }
  91.     return message.wParam;
  92. }


Reply

Marsh Posté le 19-10-2007 à 13:55:27   

Reply

Marsh Posté le 19-10-2007 à 16:25:09    

Bah, ton focus est sur le bouton. Le bouton a aussi des raccourcis clavier : genre appuie sur espace pour l'activer.
 
Il doit y avoir un flag qui empèche un controle d'avoir le focus (on peut toujours les utiliser à la souris, mais le controle ne fera plus partie du cycle tab).

Reply

Marsh Posté le 19-10-2007 à 16:49:22    

tpierron a écrit :

Bah, ton focus est sur le bouton. Le bouton a aussi des raccourcis clavier : genre appuie sur espace pour l'activer.
 
Il doit y avoir un flag qui empèche un controle d'avoir le focus (on peut toujours les utiliser à la souris, mais le controle ne fera plus partie du cycle tab).


Merci de ta réponse !
Je pensais que c'était la touche 'entrée' qui actionnait le bouton ayant le focus.
Mais pourquoi le bouton ne rend pas le focus une fois qu'on a cliqué ?
Si je place 2 boutons dans le programme, comment passer le focus de l'un à l'autre avec la touche 'tab' ?
Où est le focus au tout début du programme ?

Reply

Marsh Posté le 19-10-2007 à 17:32:33    

Bon, ton problème, c'est que ton bouton "mange" les événements clavier qu'il ne connait pas au lieu de les passer à la fenêtre parente. Je ne me rappelle plus la technique qu'il fallait faire pour ça (je crains qu'il faille passer par du sous-classement de contrôle). Mais si tu débutes en Win32, ça être super gore et je n'ai pour l'instant pas de code sous les yeux pour me rappeler comment faire ça.

Reply

Marsh Posté le 19-10-2007 à 17:37:04    

tpierron a écrit :

Bon, ton problème, c'est que ton bouton "mange" les événements clavier qu'il ne connait pas au lieu de les passer à la fenêtre parente. Je ne me rappelle plus la technique qu'il fallait faire pour ça (je crains qu'il faille passer par du sous-classement de contrôle). Mais si tu débutes en Win32, ça être super gore et je n'ai pour l'instant pas de code sous les yeux pour me rappeler comment faire ça.


 
Merci quand même !!
En fait, je suis sur un programme plus gros (boutons, boutons radios, cases à cocher,  listes, timer, lecture de fichier) qui fonctionne parfaitement mais uniquement à la souris et je cherchais une amélioration en permettant aussi à l'utilisateur d'utiliser le clavier.

Reply

Marsh Posté le 19-10-2007 à 17:48:18    

Oula, il y a déjà tout ce qui faut dans l'api win32, ça s'apelle les mnemonic. Rajoute un & avant la lettre que tu veux qui soit utilisée pour le racourci du controle.

Reply

Marsh Posté le 23-10-2007 à 18:49:27    

Salut !
 
Mon problème est résolu !!!!
 
En fait, lorsqu'il a le focus, le bouton bloque l'appel à
 
LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
 
Pour forcer le traitement des appuis de touche clavier, je rajoute 1 ligne de test (numéro 3 et 4) dans la boucle de traitement des messages qui devient :

Code :
  1. while(GetMessage(&message,NULL,0,0))
  2.     {
  3.     if (message.message == WM_KEYDOWN)
  4.         message.hwnd=fenetrePrincipale;
  5.         TranslateMessage(&message);
  6.         C_quoi=DispatchMessage(&message);
  7.     }


Ainsi, c'est la fenêtre entière qui "récupère" l'évenement clavier et le traitement peut se faire dans procedureFenetrePrincipale.
Aucune garantie sur les conséquences de cette bidouille mais ça marche pour ce que je veux faire : récupérer TOUS les évenements clavier.
Si la fenêtre principale contient un EDIT ou autre, je pense qu'on peut tester le message WM_KEYDOWN ET AUSSI le hwnd ...
 
C'est tout !
Grand merci à tous !

Reply

Marsh Posté le 23-10-2007 à 20:32:32    

Correction sur la boucle de messages, désolé :

Code :
  1. 1. while(GetMessage(&message,NULL,0,0))
  2.    2.     {
  3.    3.     if (message.message == WM_KEYDOWN)
  4.    4.         message.hwnd=fenetrePrincipale;
  5.    5.         TranslateMessage(&message);
  6.    6.         DispatchMessage(&message);
  7.    7.     }

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed