duda sobre hWnd

Iniciado por scod, 25 Enero 2006, 06:18 AM

0 Miembros y 1 Visitante están viendo este tema.

scod

sup,..

toy haciendo un proyecto en vb6 sin formularios, solo unos cuantos modulos, y entre el code creo timers con la api de windoze, pero la api directamente me pide el hwnd de la ventana con la que va asociada el tiemr, el problema es que comono tengo forms no tengo hwnd, si le mando algun valor nulo me crea el timer y todo bien, pero el prob es que yo quiero mas de un timer, y al momento de crear un segundo timer con el valor hwnd nulo o me marca error o el id del segundo timer me lo asocia con el primero, es decir, si queiro matar el primer timer, tambien mata al segundo.

alguien sabe alguna forma de pasar como parametro el hwnd sin que cree conflictos con los timers? supongo que por ser la misma instancia de una aplicaicon deberia tener hwnd pero como no lo puedo saber xD

antes lo hacia poniendo un for en blanco y nunca cargarlo, osea iniciaba con sub main en el modulo, pero me aumenta unos 30kb al exe final

salutes y grax
yeah,.. weeeell,...

not now,... u_u,... soon my webpage,... just dont know how soon xD

Angellore

Hola.
No hace falta utilizar ningún hWnd. En la función callback TimerProc hay un argumento idEvent, ese valor es el que hay que pasarle a la función KillTimer.

Al crear el timer utilizando la función SetTimer, no hay que especificar ningún argumento excepto el puntero de función a TimerProc y el intervalo del temporizador, así dejamos que el sistema elija el idEvent y nos ahorramos de tener que utilizar una variable para guardar esos valores.

El siguiente ejemplo muestra cómo crear varios temporizadores sin que haya conflictos entre ellos.


Sub Main()
  Call SetTimer(0&, 0&, 1000&, AddressOf Timer1)
  Call SetTimer(0&, 0&, 2000&, AddressOf Timer2)
  Call SetTimer(0&, 0&, 3000&, AddressOf Timer3)
End Sub

Sub Timer1(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long)
  Debug.Print "El idEvent de Timer1 es " & idEvent

  ' Elimina el temporizador.
  '
  Call KillTimer(0&, idEvent)
End Sub

Sub Timer2(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long)
  Debug.Print "El idEvent de Timer1 es " & idEvent

  ' Elimina el temporizador.
  '
  Call KillTimer(0&, idEvent)
End Sub

Sub Timer3(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long)
  Debug.Print "El idEvent de Timer1 es " & idEvent

  ' Elimina el temporizador.
  '
  Call KillTimer(0&, idEvent)
End Sub


Saludos.
Angellore.

scod

#2
ps me sale lo mismo, incluso se cierra el vb y no me deja ver el debug, lo que hago es crear un archivo y hago esto,..


Sub main()

Open "f:\timers.txt" For Output As #1
Print #1, vbCrLf & vbCrLf & "------------------------------" & Time & "-----------------------------------" & vbCrLf
Close #1

SetTimer 0&, 0&, 2000, AddressOf timer1
SetTimer 0&, 0&, 100, AddressOf timer2
End Sub

Private Sub timer1(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
i = i + 1
qwe "Timer1 = " & i & " - nIDEvent = " & nIDEvent

If i = 5 Then
    MsgBox "terminando,..."
    qwe "terminando,..." & vbCrLf & "killin' timer1,..."
    KillTimer 0&, nIDEvent
    qwe "ok" & vbCrLf & "endin,.."
    End
End If

End Sub
Private Sub timer2(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
qwe "     Timer2 = " & i & " - nIDEvent = " & nIDEvent

If i = 3 Then
    qwe "Killing timer2 ,..."
    qwe KillTimer(0&, nIDEvent)
End If
End Sub

Sub qwe(o As String)
Open "f:\timers.txt" For Append As #1
Print #1, o
Close #1
End Sub


------------edit-----------

ya lo solucione, modifique los parametros que tenia con los tuyos y ya jalo xD

ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long

saludos y grax
yeah,.. weeeell,...

not now,... u_u,... soon my webpage,... just dont know how soon xD

Angellore

Hola.
Eso pasa porque al utilizar como procedimiento de inicio Sub Main, el programa terminará cuando salga del procedimiento.

El problema está en que el código de los timers sigue ejecutandose y al haber terminado el procedimiento que los creó, se produce lo que se llama "condición de carrera" y los resultados son impredecibles.

Para solucionar esto, por ejemplo podrías declarar una variable global para que el procedimiento Sub Main monitoree en un bucle hasta que cambie a determinado valor, y recién ahí salir del procedimiento. Por ejemplo:


Public bTerminateApp As Boolean

Sub Main()
  Call SetTimer(0&, 0&, 1000&, AddressOf Timer1)
  Call SetTimer(0&, 0&, 2000&, AddressOf Timer2)
  Call SetTimer(0&, 0&, 3000&, AddressOf Timer3)

  Do While Not bTerminateApp
    DoEvents
  Loop
End Sub

Sub Timer1(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long)
  Debug.Print "El idEvent de Timer1 es " & idEvent

  ' Elimina el temporizador.
  '
  Call KillTimer(0&, idEvent)
End Sub

Sub Timer2(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long)
  Debug.Print "El idEvent de Timer1 es " & idEvent

  ' Elimina el temporizador.
  '
  Call KillTimer(0&, idEvent)
End Sub

Sub Timer3(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Integer, ByVal dwTime As Long)
  Debug.Print "El idEvent de Timer1 es " & idEvent

  ' Elimina el temporizador.
  '
  Call KillTimer(0&, idEvent)

  ' Cuando termina el tercer temporizador, establece
  ' la variable global a True y el procedimiento Sub Main
  ' sale del bucle de espera.
  '
  bTerminateApp = True
End Sub



En tu caso deberías saber cuando establecer la variable global a bTerminateApp, pero debes tener en cuenta que no tiene que estar ejecutándose ningún timer antes de salir de Sub Main.

Saludos.
Angellore.