Ver Mensaje Individual
  #4 (permalink)  
Antiguo 14/10/2013, 12:13
vosk
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Temporizadores con parámetros

No puedes hacerlo asi porque UnBan() es una llamada a la funcion, es decir que la ejecuta al momento de asignar el puntero a la funcion de callback.

Puedes resolver con una lista de datos:

Código C:
Ver original
  1. struct TIMERDATA {
  2.     unsigned int idTimer;
  3.     unsigned int hTimer;
  4.     int data;
  5. };

Ahora tienes dos opciones, o bien usas una lista estatica de structs o bien las generas de forma dinamica, en ambos casos es lo de menos. Una vez tengas decidido como declarar los structs solo has de rellenar cada uno con los datos que quieras.

Suponiendo que vas a hacer una lista estatica puedes quitar el campo idTimer del struct porque el propio id será el orden del struct al que asignas el manejador de timer dentro de la lista:

Código C:
Ver original
  1. //esto tiene que ser global, que no caduque al terminar la funcion de crear timers
  2. struct TIMERDATA timerList[3];
  3.  
  4. //dentro de la funcion de crear timers
  5. for(q = 0; q < 3; q++) {
  6.     timerList[q].data = q+10;//un dato que me invento
  7.     timerList[q].hTimer = SetTimer(hwndBans, q, 5000, UnBan);
  8. }

Fijate en el truco: en tu codigo todos los timers tienen un identificador 0, con lo que no puedes diferenciarlos a menos que llames a diferentes callbacks. En este caso asigno como identificador del timer el orden del struct que contiene su manejador.

Ahora declaras el callback, pero antes echa un vistazo a tu manual de referencia de las funciones TIMERPROC para ver los argumentos: en tu codigo solo tienes un argumento cuando esa funcion soporta 4 y cada uno tiene su utilidad.

Código C:
Ver original
  1. void CALLBACK UnBan(HWND hwnd, unsigned int msg, unsigned id, unsigned long st) {
  2.     ...
  3. }

Los argumentos son: el 'hwnd' será el hwnd con que creaste el timer, en este caso todos fueron hwndBans; el 'msg' siempre será WM_TIMER (en otros casos puede variar, pero en el callback de un SetTimer siempre es el mismo); el 'id' es el identificador con que creaste el timer, es decir que es el orden del struct dentro de la lista donde guardaste el manejador del handler; y 'st' es el retorno de GetTickCount al momento de llamar al callback (el nº de ms desde que arrancó windows).

Supongo que ya te has dado cuenta de como recuperar los datos: el identificador te sirve como indice de la lista de datos de timer; la unica comprovacion de error es que el identificador sea menor que el nº de elementos de la lista de structs:

Código C:
Ver original
  1. struct TIMERDATA *ptr;
  2.  
  3. if((ptr = (id < 3)? &timerList[id] : 0)) {
  4.     //ya lo tienes
  5. }

Una ultima cosa que seguramente ya sabes, pero te la comento igual (es lo que te comente al principio): ojo con los scope de los datos que se van a manejar desde los callbacks, y ojo tambien con trabajar desde un callback sobre una misma direccion de memoria. Para evitar perder los datos debes declararlos como globales o como memoria dinamica, y en caso necesario para evitar conflictos al trabajar sobre una misma variable puedes usar secciones criticas (todas las funciones para el manejo de variables y secciones criticas las tienes en el manual de referenacia o tambien en la msdn).

Saludos
vosk