[R1] Utisation de methode/class static
class Test
{
public :
static int nbInstance;
Test() { nbInstance++; }
static int fonc() { return nbInstance; }
};
int Test::nbInstance = 0; // sinon la variable na pas d'instansiation
void main() {
// nbInstance =0;
Test test; // nbInstance =1;
Test::fonc(); // valide
test.nbInstance; // valide
test.fonc(); // valide
}
[R2] Appel de methode/class par un pointeur
class Test {
public:
void Methode1(int param1) { printf("Methode1(%d)\n",param1); }
void Methode2(int param1) { printf("Methode2(%d)\n",param1); }
};
void Function1(int param1) { printf("Function1(%d)\n",param1); }
void Function2(int param1) { printf("Function2(%d)\n",param1); }
void main () {
// appel par pointeur sur fonction
typedef void (*Function)(int);
Function function;
function=Function1;
function(10);
function=Function2;
function(20);
// appel par pointeur sur methode
typedef void (Test::*Methode)(int);
Methode methode;
Test test; // il faut fatalement un "this" pour appeler une methode
methode=Test::Methode1;
//test.methode(30); // dommage mais c'est impossible, "methode" ne fait pas partie de la class !!
(test.*methode)(30); // syntax tres laide
methode=Test::Methode2;
(test.*methode)(40);
}
Resultat:
Function1(10)
Function2(20)
Methode1(30)
Methode2(40) |
[R3] Gestion d'evenement par pointeur sur class
Cette article repond aussi a la question: comment faire un pointeur sur methode quelquonque.
class Class {
public:
typedef void (Class::*Methode)(); // type un pointeur sur methode
void *ptrThis; // pointeur sur le this de la class
Methode methode; // pointeur sur une methode generique
Class() { Set(NULL,NULL); }
void Set(void *_ptrThis,Methode _methode) {
ptrThis = _ptrThis; // affectation des nouvelles valeurs
methode = _methode;
}
#define SetIt(_ptrThis,_methode) Set(_ptrThis,(Class::Methode)_methode) // pour simplifier l'ecriture
};
#define Call0Param(ptrClass) \
{ typedef void (Class::*Methode)(); \
Methode methode = (Methode) (ptrClass)->methode; \
((Class *)((ptrClass)->ptrThis)->*methode)(); \
}
#define Call1Param(ptrClass,t1,p1) \
{ typedef void (Class::*Methode)(t1);\
Methode methode = (Methode) (ptrClass)->methode;\
((Class *)((ptrClass)->ptrThis)->*methode)(p1); \
}
#define Call2Param(ptrClass,t1,p1,t2,p2) \
{ \
typedef void (Class::*Methode)(t1,t2); \
Methode methode = (Methode) (ptrClass)->methode; \
((Class *)((ptrClass)->ptrThis)->*methode)(p1,p2); \
}
// Les differant call suivant le nombre de parametres (avec valeur de retour)
#define Call0ParamR(ptrClass,tr,pr) { typedef tr (Class::*Methode)(); Methode methode = (Methode) (ptrClass)->methode; pr = ((Class *)((ptrClass)->ptrThis)->*methode)(); }
#define Call1ParamR(ptrClass,tr,pr,t1,p1) { typedef tr (Class::*Methode)(t1); Methode methode = (Methode) (ptrClass)->methode; pr = ((Class *)((ptrClass)->ptrThis)->*methode)(p1); }
#define Call2ParamR(ptrClass,tr,pr,t1,p1,t2,p2) { typedef tr (Class::*Methode)(t1,t2); Methode methode = (Methode) (ptrClass)->methode; pr = ((Class *)((ptrClass)->ptrThis)->*methode)(p1,p2); }
class A {
public:
int valueA; // simplement pour montrer un element du this valide
A(int value) { valueA = value; }
int MethodeA1() {
printf("[valueA=%d] MethodeA1()\n",valueA);
return valueA;
}
void MethodeA2(int p1) {
printf("[valueA=%d] MethodeA2(%d)\n",valueA,p1);
}
};
class B {
public:
int valueB; // simplement pour montrer un element du this valide
B(int value) { valueB = value; }
void MethodeB1(int p1) {
printf("[valueB=%d] MethodeB1(%d)\n",valueB,p1);
}
void MethodeB2(int p1,float p2) {
printf("[valueB=%d] MethodeB2(%d,%f)\n",valueB,p1,p2);
}
};
void main()
{
A a(1);
B b(2);
Class class1,class2,class3;
class1.SetIt(&a,A::MethodeA1);
class2.SetIt(&b,B::MethodeB1);
class3.SetIt(&b,B::MethodeB2);
int result;
Call0ParamR(&class1,int,result); // <=> result = a.MethodeA1();
printf("Result:%d\n",result);
Call1Param(&class2,int,3); // <=> b.MethodeB1(3);
Call2Param(&class3,int,4,float,5.5f); // <=> b.MethodeB2(4,5.5f);
// clairement ce system d'appel de methode par CallxParamX() a un gros default:
// il ne verifie pas l'integrité des passages de parametres
// on peut tres bien faire un appel a un methode qui attend 2 argument alors
// que l'on en passe q'un seul, pas de pb a la compil, mais erreur a l'execution
// ex.: Call1Param(&class3,int,4); // <=> b.MethodeB2(4,???); alors deMethodeB2 a 2 param
}
Resultat:
[valueA=1] MethodeA1()
Result:1
[valueB=2] MethodeB1(3)
[valueB=2] MethodeB2(4,5.500000) |
[R4] Comment placer un timer en "pause" (fonction PauseTimer/ReleaseTimer)
Seul existent les API SetTimer et KillTimer.
Recherche fonction du type int GetTimer(HWND hWnd,int id) qui donnerai le elapsed time d'un timer déjà Initialisé par SetTimer().
Mon but est de pouvoir faire un pause/resume de timer quand un MessageBox est utilisér
(pour débuguer de l'OpenGL ça peut être très utile Mais les seuls API windows sur le sujet sont SetTimer / KillTimer() qui ne donnent pas les infos sur l'ement killer, sinon ça serait trop simple)
Reponces:
Pause: SetTimer ( hWnd , id , 0x7fffffff , NULL ) ;
Release: SetTimer ( hWnd , id , periodeOriginal , NULL );
|