IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Visual C++ Discussion :

[Win32] editbox et touche "entrée"


Sujet :

Visual C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut [Win32] editbox et touche "entrée"
    Bonjour à tous,

    Je dois débugguer et améliorer un soft que je n'ai pas conçu.

    Je récupère des données et dois pouvoir en modifier certaines. Aujourd'hui, j'affiche donc, par un thread, une succession de lignes constituées de divers boutons et editbox.
    Je souhaite, à la fin de la modification d'une des editbox, pouvoir, à l'aide de la touche "Entrée", lancer une action spécifique. D'ailleurs, aucune touche autre qu'alphanumérique n'est prise en compte.
    Aujourd'hui, il faut cliquer sur un autre bouton à l'aide de la souris pour envoyer la valeur de l'editbox ce qui n'est pas acceptable en production.

    Or, je n'ai pas l'impression que le moindre évènement soit généré lors de l'appui sur la touche "Entrée", lorsque l'editbox a le focus.

    J'ai regardé du coté des hooks (notamment une discussion de NicoPyright-c de 2004), mais le nombre d'editbox varie en fonction du nombre de paramètres récupérés...

    Avez-vous une idée ?

    PS : En plus, il faudrait aussi que cela soit portable sous WinCE...

    Merci pour vos réponses

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 467
    Par défaut
    Or, je n'ai pas l'impression que le moindre évènement soit généré lors de l'appui sur la touche "Entrée", lorsque l'editbox a le focus.
    Je pense que vous avez une vue un peu trop simpliste de votre programme.

    Utilisez Spy++ pour voir les messages circulés.


    Une editBox qui n'est pas multi-ligne n'a pas à prendre en compte la touche Return, il la propage donc à sa fenêtre parente, à moins que sa fonction de fenêtre n'ait été sur ou sous-classé. Et si ont fait abstraction de tous les mécanismes cracra de bas niveau telle que le hooking.

    Donc le comportement est fonction du type de la classe parente.
    Si c'est une boite de dialogue, cela devrait déclencher le bouton sélectionné ou celui noté par défaut.
    Si c'est un autre type de fenêtre, il devrait faire la même chose que le contrôle Edit, envoi à son parent.

    etc...

    Vérifiez vos assertions svp.

    Aujourd'hui, il faut cliquer sur un autre bouton à l'aide de la souris pour envoyer la valeur de l'editbox ce qui n'est pas acceptable en production
    Plutôt que de faire une fixette sur la touche "Entrée", je gérerais l'évènement de notification de perte de focus envoyé pas le contrôle Edit à sa fenêtre parente dans la fonction de fenêtre de la fenêtre parente.

  3. #3
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut
    Merci pour ces précisions.
    Ce que je ne comprend pas bien, c'est qu'à l'utilisation, l'appui sur la touche Entrée ne fait pas quitter l'editbox.

    Voici, pour plus de clarté, un extrait du code. Nous ne nous intéressons qu'au paramètres (Parameters dans le code)
    Le main appelle, lors de la création de la fenêtre, la fonction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DiagDisplay_Init(hInst, hParameterBox, hEventBox, hScrollBarParam, hScrollBarEvent);
    hInst est l'instance globale, hParameterBox est une box contenant nos futures lignes, et hScrollBarParam est une scrollbar.
    Cette fonction appelle notamment la fonction d'enregistrement de la fenêtre, avant d'afficher le header.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    RegisterParameterWnd();
    DiagDisplay_ParamHeader();
    La fonction d'enregistrement lie la fonction myProc définie après.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void RegisterParameterWnd(void)
    {
    	WNDCLASS wc;
    	wc.lpszClassName  = PARAMWND_CLASSNAME;
    	wc.hInstance      = GetModuleHandle(0);
    	wc.lpfnWndProc    = ParameterWnd::myProc;
    	wc.hCursor        = LoadCursor (NULL, IDC_ARROW);
    	wc.hIcon          = 0;
    	wc.lpszMenuName   = 0;
    	wc.hbrBackground  = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
    	wc.style          = 0;
    	wc.cbClsExtra     = 0;
    	wc.cbWndExtra     = sizeof( ParameterWnd * );
     
    	RegisterClass(&wc);
     
    }
    La fonction myProc gère la création de tous les boutons, dont la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    LRESULT CALLBACK ParameterWnd::myProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	int						wmId, wmEvent;
    	ParameterWnd*			my_data;
    	WCHAR					wcTemp[STRING_MAXIMAL_SIZE];
    	RECT					windowRect;
     
    	std::string TempString;
    	my_data = (ParameterWnd*)GetWindowLong(hwnd,0);
     
    	switch(msg)
    	{
    		// Allocate a new CustCtrl class for this window.
    		case WM_CREATE:
    			{
    				CREATESTRUCT* stCreate = (CREATESTRUCT*)lParam;
    				stParameterDiagKv*		receivedParam;
    				WCHAR buttonClass[50] = {0};
    				WCHAR editClass[50] = {0};
    				unsigned long buttonStyle = 0L;
    				unsigned long editStyle = 0L;
    				int numberWidth = 30;
    				//affects the datas to myself
    				my_data = new ParameterWnd(hwnd);
    				SetWindowLong(hwnd,0,(LONG)my_data);
     
    				//Get parameter datas
    				receivedParam = (stParameterDiagKv*)stCreate->lpCreateParams;
    				my_data->my_parameter.id			= receivedParam->id;
    				my_data->my_parameter.ecuValue		= receivedParam->ecuValue;
    				my_data->my_parameter.wishedValue	= receivedParam->wishedValue;
     
    				if(my_data->my_parameter.id != -1)
    				{
    					swprintf_s(buttonClass, STRING_MAXIMAL_SIZE, L"%s", INFOBUTTON_CLASSNAME);
    					buttonStyle = WS_CHILD | WS_VISIBLE;
    					swprintf_s(editClass, STRING_MAXIMAL_SIZE, L"%s",  L"EDIT");
    //					editStyle = WS_CHILD |WS_VISIBLE|WS_BORDER|ES_NUMBER;
    					editStyle = WS_CHILD |WS_VISIBLE|WS_BORDER;
    				}
    				else
    				{
    					swprintf_s(buttonClass, STRING_MAXIMAL_SIZE, L"%s", L"BUTTON");
    					buttonStyle = WS_CHILD | WS_VISIBLE; 
    					swprintf_s(editClass, STRING_MAXIMAL_SIZE, L"%s",  L"BUTTON");
    					editStyle = WS_CHILD | WS_VISIBLE;
    				}
     
    				//create all buttons that will show the parameter datas
    				GetClientRect(hwnd, &windowRect);
     
    // Ici, on crée les autres boutons...
    // Le code est supprimé
    // Là, on crée le bouton sous la forme d'une editbox
    				if(my_data->my_parameter.id != -1)
    				{
    					_ultow(my_data->my_parameter.wishedValue,wcTemp,10);
    				}
    				else
    				{
    					swprintf_s(wcTemp, STRING_MAXIMAL_SIZE, L"%s",  L"Value");
    				}
     
    				//Calculate edit box size depending on systeme we are on
    				int editboxPosX;
    				int editboxWidthX;
     
    				editboxPosX = windowRect.left + 6*(windowRect.right - windowRect.left)/8+ numberWidth;
    				editboxWidthX = (windowRect.right - windowRect.left)/8;
     
    				my_data->hValue = CreateWindow(	editClass, wcTemp,
    						editStyle,
    						editboxPosX,
    						windowRect.top,
    						editboxWidthX,
    						windowRect.bottom - windowRect.top,
    						hwnd,
    						(HMENU)ID_EDIT_BOX, // C'est ici que le menu de l'edit box est créé....
    						stCreate->hInstance,
    						NULL);
     
    			}
    			return (my_data != NULL);
    		case WM_KEYDOWN:
    			switch(wParam)
    			{
    			case VK_RETURN:
    				MessageBox(NULL, L"Return pressed",L"Info", MB_OK);
    				break;
    			case VK_NEXT:
    				MessageBox(NULL, L"Page down pressed",L"Info", MB_OK);
    				break;
    			case VK_PRIOR:
    				MessageBox(NULL, L"Page up pressed",L"Info", MB_OK);
    				break;
    			}
    			break;
     
    		case WM_COMMAND:
    			{
    				wmId    = LOWORD(wParam);
    				wmEvent = HIWORD(wParam);
     
    				switch(wmId)
    				{
    					case ID_EDIT_BOX:
    						if((my_data->my_parameter.id != -1) &&
    								((wmEvent == EN_UPDATE) || (wmEvent == EN_CHANGE) || (wmEvent > EN_SETFOCUS) ))
    						{
     
    							wcTemp[0] = 50;
    							if(SendMessage(my_data->hValue, EM_GETLINE, 0, (LPARAM)wcTemp) == 0)
    							{
    								// The string is empty
    								return 0;
    							}
    							//convert received string into integer and send it over CAN
    							my_data->my_parameter.wishedValue = _wtoi(wcTemp);
     
    							//analyse entered value
    							//							my_data->my_parameter.wishedValue = my_data->my_parameter.wishedValue - (my_data->my_parameter.wishedValue%my_data->my_parameter.step);
    							//							my_data->my_parameter.wishedValue = max(my_data->my_parameter.wishedValue, my_data->my_parameter.minValue);
    							//							my_data->my_parameter.wishedValue = min(my_data->my_parameter.wishedValue, my_data->my_parameter.maxValue);
    							my_data->my_parameter.wishedValue = CheckValue(my_data->my_parameter.wishedValue, my_data->my_parameter.type, my_data->my_parameter.step);
     
    							DiagKv_ChangeWishedValue(&my_data->my_parameter);
     
    							if(my_data->my_parameter.ecuValue != my_data->my_parameter.wishedValue)
    							{
    								//Change button with "set" message
    								swprintf_s(wcTemp, L"%s",  L"SET");
    								SendMessage(my_data->hValidate, WM_SETTEXT, 0, (LPARAM)wcTemp);
    							}
    							else
    							{
    								//Change button with "set" message
    								swprintf_s(wcTemp, L"%s",  L"OK");
    								SendMessage(my_data->hValidate, WM_SETTEXT, 0, (LPARAM)wcTemp);
    							}
    						}
     
    						break;
    				}
    			}
    			break;
    		case WM_QUIT:
    						UnhookWindowsHookEx(hookClavier);
    			MessageBox(0, L"Fin", L"",0x10);
    			PostQuitMessage(0);
    break;
    	}	
    	return DefWindowProc(hwnd, msg, wParam, lParam);
     
    }
    Cette fonction est appelée à chaque paramètre différent ou supplémentaire.
    Ce que je ne comprend pas, c'est que rien n'est remonté à la fenêtre hWnd qui me semble être la parente : j'ai en effet dedans un appel à WM_KEYDOWN qui n'est jamais déclenché.

    Du coup, je me demande si la fenêtre hwnd d'appel de la fonction myProc est bien celle
    Pourquoi cela ne marche-t-il pas ?

    Merci

  4. #4
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut Spy++
    J'ai utilisé Spy++.
    L'évènement d'appui sur la touche est bien compris, mais seulement dans l'éditbox. Il n'est ni remonté à ParameterBox, ni à hWnd.
    Par contre, l'évènement "WM_MOUSEMOVE" est bien remonté, même si c'est l'éditbox qui a le focus.
    Voici en pièce jointe un extrait de Spy++, ainsi que l'aspect qu'à le programme.

    Je suis prêt à faire tout plein de tests
    Images attachées Images attachées   

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 467
    Par défaut
    Ce que je ne comprend pas bien, c'est qu'à l'utilisation, l'appui sur la touche Entrée ne fait pas quitter l'editbox.
    Heu, pourquoi ?

    http://support.microsoft.com/kb/102589

  6. #6
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut
    Merci Bacelar, justement, c'est bien le problème, il doit être écrit quelque chose de tellement gros dans le code que je ne comprend pas.
    Il me semble que la fenêtre parente (la ligne) n'est qu'un rectangle, sans réelle signification ? Nulle part cette ligne n'est définie comme une DialogBox...
    Je n'ai pas défini de retour par défaut...

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 467
    Par défaut
    fenêtre parente (la ligne) n'est qu'un rectangle, sans réelle signification
    Faux, elle est la cible du message (hwnd associé) quand la fenêtre fille ne gère pas le message est utilise DefWinProc pour propager le message.


    P.S.: Une dialogueBox crée les ses contrôles et sous-classes leur fenêtre pour pouvoir faire des choses comme l'implémentation de la touche "Tab".

  8. #8
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut
    Avec beaucoup de retard, pour mieux amener un nouveau post, j'ai résolu mon problème en interceptant tous les messages dans une fonction dans la boucle du TranslateMessage, DispatchMessage.
    En effet, j'ai utilisé plein de raccourcis claviers dans mon programme, indépendamment des fenêtres qui possèdent le focus.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problemes de quotes entre 2 versions
    Par Batmat01 dans le forum Requêtes
    Réponses: 4
    Dernier message: 14/06/2006, 15h03
  2. sql dynamic : passage de parametre entre quotes
    Par de LANFRANCHI dans le forum SQL
    Réponses: 12
    Dernier message: 26/05/2004, 15h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo