[MFC] Utiliser les SpinButtonCtrl [résolu, solution inside]

Utiliser les SpinButtonCtrl [résolu, solution inside] [MFC] - C++ - Programmation

Marsh Posté le 12-05-2003 à 10:35:49    

J'ai parcouru la msdn pour essayer de comprendre, mais je n'y arrive pas :(
Je sais seulement comment paramétrer l'echelle de valeurs du spinButton (SetRange).
Comment fait-on pour gérer les clicks sur les deux bouttons du spin Control ?
Est ce que ca fonctionne comme deux boutons séparés ? Est ce que c'est la fonction SetAccel ? C'est peut etre ca, mais je ne comprends pas pourquoi il y a un tableau à passer en parametre dans cette fonction...
 
Eclairez ma lanterne, répondez à toutes mes interrogations, pliiiiizzz


Message édité par backdafuckup le 12-05-2003 à 16:11:48
Reply

Marsh Posté le 12-05-2003 à 10:35:49   

Reply

Marsh Posté le 12-05-2003 à 10:45:46    

backdafuckup a écrit :

Comment fait-on pour gérer les clicks sur les deux bouttons du spin Control ?


 
Ce n'est pas à toi de gérer les clicks sur les boutons. C'est Windows qui s'en charge.
La principale utilisation (à mes yeux) des SpinButtonCtrls, c'est lié à un Edit. Lors de la création de ta boîte de dialogue, tu le colles à ton Edit (et tu vérifie que l'edit soit bien le contrôle précédant ton SpinButton dans l'ordre dee tabulation) et tu pourras alors constater que ton edit change de valeur tout seul.
Tu peux aussi définir le contrôle compagnon (buddy control) avec la fonction SetBuddy.
Enfin, si tu l'utilises sans contrôle compagnon, tu peux utiliser les fonctions SetPos et GetPos pour connaître sa valeur.


---------------
each day I don't die is cheating
Reply

Marsh Posté le 12-05-2003 à 10:50:05    

Qu'est ce que tu appelles "coller" le spin et l'edit...
Effectivement, c'est pour modifier des edits...
Et le problème et que j'avais déja fait tous les edits bien avant, et que je viens de placer tous les spin buttons, donc les tabulations ne sont surement pas respectées...
Et si jamais c'est ca qu'il faut corriger, comment change t on l'ordre des tabultations ?

Reply

Marsh Posté le 12-05-2003 à 10:57:18    

Pour rétablir l'ordre des tabulations, tu vas dans "Layout->Tab Order" et ensuite tu cliques sur tes contrôles les uns après les autres. Tu t'assures que sur tout tes SpinButtons, tu as bien coché "Auto Buddy" et "Set buddy integer" et que l'alignement est bien défini à "Right". Et normalement, même en mode test de la boîte de dialogue, ça doit fonctionner. Attention tout de même car par défaut, le Range est inversé ; ce qui fait qu'il faut appuyer sur la flèche du bas pour incrémenter (de mémoire, je crois que c'est fait exprès pour pas que l'on oublie de le définir).


---------------
each day I don't die is cheating
Reply

Marsh Posté le 12-05-2003 à 11:08:10    

Merci, ca marche très bien, mais..
Au risque de paraitre chiant, comment on fait pour faire varier le step et avoir des floats au lieu d'entiers (c'est pour faire varier des tensions, donc ca doit varier de 0.05 en 0.05...)


Message édité par backdafuckup le 12-05-2003 à 11:08:35
Reply

Marsh Posté le 12-05-2003 à 11:28:15    

Pour cela 2 choses :
 
- Ne pas cocher la propriete "Set Budy Integer" de ton spin
- Reecrire l'event "UDN_DELTAPOS"
 

Code :
  1. void CTestprojDlg::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult)
  2. {
  3. NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
  4. if (pNMUpDown->iDelta > 0)  m_fEditValue += INC_VALUE;
  5. else       m_fEditValue -= DEC_VALUE;
  6. UpdateData(FALSE);
  7. *pResult = 0;
  8. }


 
Attention en faisant ca ton set range n'est plus valide, donc a toi de rajouter un test aussi au moment d'incrementer/decrementer.

Reply

Marsh Posté le 12-05-2003 à 11:32:03    

merci visual, tu as toujours les solutions, c'est un plaisir...
Mais j'ai 38 spin buttons, je réécris 38 fois la fonction deltapos ou ya possibilité de faire de l'héritage ou truc du style (je suis pas très balaise en objet, mais tu as déja pu le constater je suppose) ?

Reply

Marsh Posté le 12-05-2003 à 11:44:57    

Ben la solution SI et je dit bien SI tout tes step sont equivalents (koike on peut le faire aussi mais faudrait faire un truc plus couillu) serait de faire une classe CSpinButtonCtrlet de l'utiliser a la place de CSpinButtonCtrl.
 
Faudrait voir comment recup le handle e l'edit qu'il est cense modifier.

Reply

Marsh Posté le 12-05-2003 à 11:50:24    

A mon avis, c'est pas possible de le faire simplement. La meilleure solution reste à mon avis de gérer le fonctionnement du contrôle manuellement (sans définir de contrôle compagnon) et de traîter la notification UDN_DELTAPOS afin de modifier manuellement l'edit quand la valeur du SpinButton change.
 
En gros tu définis un range du genre [-500,500] et quand tu reçois la notification, tu modifie l'edit correspondant (un truc du genre ::GetWindow( lpnmud->hdr.hwndFrom, GW_HWNDPREV ) devrait te permettre de retrouver le bon edit).
 

Code :
  1. ON_NOTIFY_RANGE( UDN_DELTAPOS, ID_FIRST_SPINBUTTON, ID_LAST_SPINBUTTON, OnSpinButtonsDeltaPos )
  2. void OnSpinButtonsDeltaPos( UINT id, NMHDR* pNotifyStruct, LRESULT * result )
  3. {
  4. LPNMUPDOWN lpnmud = reinterpret_cast<LPNMUPDOWN>(pNotifyStruct);
  5. CString strTemp;
  6. strTemp.Format( TEXT("%f" ), lpnmud->iPos / 100 );
  7. int cbNumber = ::GetNumberFormat( LOCALE_USER_DEFAULT, 0, strTemp, NULL, NULL, 0 );
  8. if( cbNumber > 0 )
  9. {
  10. LPTSTR szNumber = new TCHAR[cbNumber];
  11. cbNumber = ::GetNumberFormat( LOCALE_USER_DEFAULT, 0, strTemp, NULL, szNumber, cbNumber );
  12. if( cbNumber > 0 )
  13. {
  14. HWND hEdit = ::GetWindow( lpnmud->hdr.hwndFrom, GW_HWNDPREV );
  15. cbNumber = ::SetWindowText( hEdit, szNumber ) ? 1 : 0;
  16. }
  17. delete[] szNumber;
  18. }
  19. *result = ( cbNumber == 0 ? 1 : 0 );
  20. }


Message édité par gatorette le 12-05-2003 à 11:50:42

---------------
each day I don't die is cheating
Reply

Marsh Posté le 12-05-2003 à 11:50:48    

Ouais... ca commence à me dépasser, je pense que je vais rester sur le truc des 38 fonctions, ca fera un code lourd, et peu appliqué, mais personne n'est sensé le voir ici, je suis le seul à faire du C++ de toute facon...

Reply

Marsh Posté le 12-05-2003 à 11:50:48   

Reply

Marsh Posté le 12-05-2003 à 12:03:31    

Si tu te sens plus alaise avec 1 classe unique  
 
Creer une classe CMySpinButtonCtrl derive de CSpinButtonCtrl.
 
Remplacer ds tes header de Dialog, CSpinButtonCtrl par CMySpinButtonCtrl, et rajouter l'include qui va bien en haut.
 
Puis reecrire le NOTIFY_REFLECT de UDN_DELTAPOS ds ta nouvelle classe et y mettre ca.
 

Code :
  1. void CMySpinButtonCtrl::OnDeltapos(NMHDR* pNMHDR, LRESULT* pResult)
  2. {
  3. NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
  4. HWND pWnd = ::GetWindow(pNMUpDown->hdr.hwndFrom, GW_HWNDPREV);
  5. if (pWnd != NULL) {
  6.  char cText[20];
  7.  ::GetWindowText(pWnd, cText, 20);
  8.  double dNewValue = atof(cText);
  9.  if (pNMUpDown->iDelta > 0)  dNewValue += INC_VALUE;
  10.  else       dNewValue -= DEC_VALUE;
  11.  if (dNewValue > MAX_RANGE)  dNewValue = MAX_RANGE;
  12.  if (dNewValue < MIN_RANGE)  dNewValue = MIN_RANGE;
  13.  CString csNewText;
  14.  csNewText.Format("%0.2f", dNewValue);
  15.  ::SetWindowText(pWnd, csNewText);
  16. }
  17. *pResult = 0;
  18. }


 
Puis juste a remplecer les 3 constantes la suivant tes besoins.
 
 
 
Car bon se taper 20 fonctions pas propre et sources de bug.

Reply

Marsh Posté le 12-05-2003 à 15:07:46    

Allez remonte mon ptit topic...
J'ai encore besoin de vous...
Tout marche très bien (j'ai pas fait de classe unique, j'ai 38 fonctions, mais c'est pas grave..)
Le seul problème (et c'est important tout de même) c'est que les Edits ne m'affichent plus 0, mais une valeur proche de 0 (-7.5...e-0009). Et c'est embetant, voire meme impensable...
 
Quiqui a la solution ?? :jap:
 
 
Et merci à tous ceux qui m'ont aidé sur ce topic :jap:

Reply

Marsh Posté le 12-05-2003 à 15:14:06    

C un petit pb de conversion ca.
 
Avec les 2 code passe au dessus (enfin les 2 venant de moi) j ai pas le pb, ca de/incremente bien de 0.05 et pas de valeur en e-00 (j ai fait le test de 0.00 a 10.00 ds les 2 sens).
 
Comment tu convertis ton edit en nombre ?


Message édité par VisualC++ le 12-05-2003 à 15:14:52
Reply

Marsh Posté le 12-05-2003 à 15:19:24    

VisualC++ a écrit :

C un petit pb de conversion ca.
 
Avec les 2 code passe au dessus (enfin les 2 venant de moi) j ai pas le pb, ca de/incremente bien de 0.05 et pas de valeur en e-00 (j ai fait le test de 0.00 a 10.00 ds les 2 sens).
 
Comment tu convertis ton edit en nombre ?


j'ai fait des 'member variables' en float, mais je crois que ca convertis de double à float quelque part dans la fonction que tu m'as donné, c'est peut etre pour ca qu'il y a un problème...
 

Code :
  1. if (pNMUpDown->iDelta > 0)  m_ParamConsVdr2 += INC_VALUE;
  2.        else       m_ParamConsVdr2 -= DEC_VALUE;


 
dans le meme fichier, plus haut, il y a :
 

Code :
  1. //j'ai mis deux fois les memes au cas ou un jour on ait besoin  
  2. //de changer un des deux...
  3. #define INC_VALUE 0.05f
  4. #define INC_VALUE 0.05f


 
 
Voila... [:spamafote]

Reply

Marsh Posté le 12-05-2003 à 15:46:46    

Ouep a priori ca lui arrive de se planter j ai fait un chit projet pour tester, ca marche bien avec la classe car y a un %0.2f dedans, mais avec les const ca merdouille.
 
Tu peux contourner le pb en reformattant via une string

Code :
  1. UpdateData(TRUE);
  2. double dNewValue = (double)m_fEditValue;
  3. if (pNMUpDown->iDelta > 0)  dNewValue += INC_VALUE;
  4. else      dNewValue -= DEC_VALUE;
  5. if (dNewValue > MAX_RANGE)  dNewValue = MAX_RANGE;
  6. if (dNewValue < MIN_RANGE)  dNewValue = MIN_RANGE;
  7. CString csNewValue;
  8. csNewValue.Format("%0.2f", dNewValue);
  9. m_fEditValue = (float)atof(csNewValue);
  10. UpdateData(FALSE);

Reply

Marsh Posté le 12-05-2003 à 16:06:47    

C'est génial... Je te remercie, ca marche très bien...
 
J'ai juste de questions :  
- Quelle est la différence entre atoi() et atof()
- Quelle est la différence entre UpdateDate(TRUE) et UpdateDate(FALSE) ?
 
:jap:
 
Et merci à tous

Reply

Marsh Posté le 12-05-2003 à 16:10:09    

conversion entier ou double
TRUE > tu initialises les variable associees a tes control
FALSE > tu change la valeur du control en fonction de la valeur de la variable associee.

Reply

Marsh Posté le 12-05-2003 à 16:11:22    

Bien, encore merci à VC++, un grand homme du C++, et aussi gatorette (je crois que c'est ca)...
Topic terminé..

Reply

Sujets relatifs:

Leave a Replay

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