evitar parpadeo del cursor sin usar screenupdating

13/10/2006 - 18:40 por Ivan | Informe spam
Hola a todos

estoy haciendo una macro para simular la escritura en directo en un
cuadro de texto de la barra de dibujo. Parece funcionar bastante bien,
pero no logro evitar el parpadeo continuo del cursor mientras se
ejecuta. Explico un poco el funcionamiento (y expongo el codigo al
final).

Lo que hace el codigo es ir 'extrayendo' caracter tras caracter de un
texto depositado en una celda de una hoja (oculta) e irlo concatenando
en el cuadro de texto.

para conseguir un retardo de tiempo que permita ver la secuencia de
'escritura' utilizo una funcion de las APIs (facilitada por HM) que
'crea? retardos de x milisegundos en la ejecucion del codigo (no estoy
seguro de que sea esto lo que haga, pero supongo que sera algo asi).

el problema es que no puedo (o al menos no he podido) usar
App...Screenupdating porque entonces oculta el proceso y muestra solo
el resultado final (el texto completo), y no se si hay otra forma para
evitar el parpadeo del cursor, o al menos intentar atenuarlo al maximo.

el codigo es el siguiente (posiblemente haya formas mejores/mas
eficientes de lograr lo mismo ¿quizas con sendkeys?)

Private Declare Sub Retardo Lib "kernel32" _
Alias "Sleep" (ByVal Milisegundos As Long)

Sub EscribirEnVivoCuadroT()
Dim Pos As Byte, Fin As Byte, lt As String
Dim hj As Worksheet
QuitarTexto 'elimina el cuadro de texto si existe
CrearCuadroTexto 'crea un nuevo cuadro de texto
Set hj = ThisWorkbook.Worksheets("Hoja3")
With Worksheets("Hoja1").Range("a1")
Fin = Len(.Value)
hj.Shapes(1).TextFrame.Characters.Text = ""
For Pos = 1 To Fin
lt = .Characters(Pos, 1).Text
DoEvents
Retardo 130
With hj.Shapes(1)
With .TextFrame
.HorizontalAlignment = xlHAlignCenter
With .Characters
With .Font
.Name = "ZephyrScript"
.Size = 16
End With
.Text = .Text & lt
End With
End With
End With
Next
End With
Set hj = Nothing
End Sub

si podeis echarme una mano de nuevo os lo agradezco

un saludo y hasta pronto
Ivan

Preguntas similare

Leer las respuestas

#1 Ivan
13/10/2006 - 19:13 | Informe spam
hola de nuevo

parece haberse resuelto eliminando la instruccion 'DoEvents', pero me
han quedado un par de dudas:

la verdad es que no acabo de tener claro cuando usar DoEvents. aqui la
inclui porque en el codigo original la tenia incluida (tambien sin
acabar de comprender por que). Dicho codigo mostraba imagenes en una
hoja a modo de presentacion usando tambien la funcion de las APIs y de
alguna de las ayudas del foro deduje que debia incluirlo. ¿puede ser
necesario en este nuevo caso? y de ser asi ¿por que?

y por ultimo, aunque esto supongo que no debe ser dificil de encontrar
en la ayuda, ¿se puede ocultar el cursor durante la ejecucion?


En cualquier caso un saludo y muchas gracias
Ivan
Respuesta Responder a este mensaje
#2 Héctor Miguel
14/10/2006 - 05:39 | Informe spam
hola, Ivan !

1) el uso del 'DoEvents' [generalmente] es para que 'nuestra' aplicacion no 'acapare' los recursos del cpu
mientras se estan ejecutando 'otros procesos/programas/... [aunque] los 'gasta' revisando los mensajes de las otras aplicaciones :-(
no tiene 'sentido' su uso en un ambiente/sistema 'multitareas' [como windows]
a menos que... [como en el caso donde lo 'sugeria'] necesites la actualizacion de otra aplicacion [como un userform] ;)
-> si ya estas 'familiarizado' con la rutina del retardo/'sleep', el 'equivalente' del DoEvents pudiera ser -> Retardo 0& ;)

2) [hasta donde se]... lo mas que podrias 'adelgazar' el cursor [en excel] mientras se ejecuta un procedimiento...
es a la 'delgadez' de un cursor de tipo 'I' que aparece en los eventos de escritura y deberas restablecerlo al finalizar [p.e.]

Sub Cursores()
Application.Cursor = xlIBeam
Application.Wait Now + TimeSerial(0, 0, 5)
Application.Cursor = xlDefault
End Sub

si cualquier duda [o informacion adicional]... comentas ?
saludos,
hector.

__ la consulta original __
... resuelto eliminando la instruccion 'DoEvents', pero me han quedado un par de dudas:
... no acabo de tener claro cuando usar DoEvents... mostraba imagenes en una hoja a modo de presentacion
... usando tambien la funcion de las APIs y de alguna de las ayudas del foro deduje que debia incluirlo.
... puede ser necesario en este nuevo caso? y de ser asi por que?
... por ultimo, aunque... supongo que no debe ser dificil de encontrar en la ayuda, se puede ocultar el cursor durante la ejecucion?
Respuesta Responder a este mensaje
#3 Ivan
15/10/2006 - 00:50 | Informe spam
hola Hector Miguel, muchas gracias de nuevo y disculpa la tardanza


1) el uso del 'DoEvents' [generalmente]
no tiene 'sentido' su uso en un ambiente/sistema 'multitareas' [como windows]
a menos que... [como en el caso donde lo 'sugeria'] necesites la actualizacion de otra aplicacion [como un userform] ;)



efectivamente tu 'sugerencia' fue para el userform de la consulta
inicial, y, de hecho, en ese momento/contexto crei entender (+o-) el
'sentido de DoEvents.

mi 'descoloque' surjio cuando, al 'cargar' las imagenes directamente en
la hoja y prescindir del userform (y por tanto pensar que ya no se
interactuaba con otra aplicacion)

probe a suprimir el doevents en el codigo. El resultado fue que, las
imagenes, en vez de desplazarse mas o menos despacio hasta su ubicacion
final, se abalanzaban en cuestion de un suspiro hasta el. (ahora mismo
se me ha ocurrido que quizas seria cuestion de seguir
jugando con el 'retardo' hasta conseguir un efecto similar). Sin
embargo, esto no ocurre con el cuadro de texto.

es (muy) posible que no haya seguido/entendido bien tu ultimo consejo
de aquella consulta =>

-> si son pocas [probablemente] convendria mantenerlas en el archivo [obviamente usando la opcion >de vinculadas]
[es decir... incrustarlas por codigo una sola vez y proveerlas en la misma ubicacion si vas a >distribuir la aplicacion]
y dejar que el codigo solamente las vaya modificando en dimensiones y posicion -?-



Si puedes explicarme un poco mas a que te referias con => "incrustarlas
por codigo una sola vez y proveerlas en la misma ubicacion ", te lo
agradecere una vez mas.

lo que hago hasta ahora es cargar las imagenes (guardadas en la misma
carpeta) al abrir la presentacion poniendo LinkToFile a true y
SaveWithDocument a false, y al cerrar la presentacion elimino todas las
formas. Esta es la instruccion que las carga:->

MiHj.Shapes.AddPicture "C:\Documents...\...\ Foto" & nroFoto & ".jpg",
msoTrue, _
msoFalse, InIzq, InSup, 142.5, 142.5

supongo que el insertar archivos se considera 'interactuar con otra
aplicacion' ¿ y de ahi DoEvents?

y, para no alargarme mucho mas (me temo que mis lagunas son tan grandes
que cada consulta se acaba convirtiendo en un tomo), y seguir abusando
de tu generosidad ->

-> si ya estas 'familiarizado' con la rutina del retardo/'sleep', el 'equivalente' del DoEvents pudiera ser -> Retardo 0& ;)



me temo que, aunque poco a poco (creo que) le voy cogiendo el punto,
... familiarizarme, familiarizarme. ¿podrias explicarme un poco
como usar el 'eqivalente' -> Retardo 0&...?

Bueno, disculpa el rollo, y muchas gracias tambien por el 'cursor', y,
creo que aun mas, por agregar 'Wait' a la saca de mis desconciertos.

Un saludo y hasta pronto
Ivan

PD: tengo un par de consultas mas o menos relacionadas, pero creo que
las pondre en otro hilo para no saturar el post.
Respuesta Responder a este mensaje
#4 Héctor Miguel
15/10/2006 - 02:19 | Informe spam
hola, Ivan !

1) [hasta donde se]... algunas aplicaciones/eventos/instrucciones/objetos/... requieren +/- recursos 'compartidos' que otras :)
'actualizar' un userform [practicamente] es 'lo mismo' que actualizar un cuadro de texto [aun incrustado en hoja de calculo] ;)
'mover' o cambiar las dimensiones de una imagen [incrustada en hoja de calculo] no requiere del 'DoEvents' [lo anterior... SI] :-(
-> los siguientes codigos [en un modulo general] podrian demostrarlo
asumiendo un cuadro de texto -dibujo- que se llena con el contenido de 'A1' y una imagen [p.e. JPG] incrustada en la hoja

Private Declare Sub Retardo Lib "kernel32" Alias "Sleep" (ByVal Milisegundos As Long)
Sub Escribiendo_en_TextBox()
Dim Nuevo As Byte
With ActiveSheet.Shapes("cuadro de texto 1").TextFrame.Characters
.Text = ""
For Nuevo = 1 To Len([a1])
.Text = .Text & Mid([a1], Nuevo, 1)
DoEvents
Retardo 200
Next
End With
End Sub
Sub Mover_imagenes()
Dim Sig As Byte
With ActiveSheet.Pictures(1)
For Sig = 1 To 20
If .Left = 108 Then .Left = 432 Else .Left = 108
Retardo 200
Next
End With
End Sub

2) mi 'sugerencia' de agregar las imagenes [vinculadas] una sola vez [por codigo] y 'dejarlas' ahi [proveyendo las imagenes]...
se debe a que al insertarlas vinculadas... no conoces con anticipacion las dimensiones 'reales' de la imagen a insertar -?-
y como la instruccion -> Shapes.AddPicture REQUIERE que indiques la posicion y las dimensiones... [seguramente]
estaras 'adivinando/suponiendo/... su 'relacion de aspecto' y no te sera posible 'rescatar' sus dimensiones 'reales' -> al 100%
[a menos que las conozcas previamente, o las 'averigues' antes de insertarla, -quizas por medio de API's-] -?-

3) la -posible- sustitucion de un 'DoEvents' versus un 'Retardo'... seria mas notoria/aplicable/...
-> si necesitas interactuar con otras aplicaciones [como lanzar otra aplicacion desde una instruccion 'Shell' o similar] :))

si cualquier duda [o informacion adicional]... comentas ?
saludos,
hector.

__ la consulta original __
__ 1 __
1) el uso del 'DoEvents' [generalmente]
no tiene 'sentido' su uso en un ambiente/sistema 'multitareas' [como windows]
a menos que... [como en el caso donde lo 'sugeria'] necesites la actualizacion de otra aplicacion [como un userform] ;)



efectivamente tu 'sugerencia' fue para el userform... y... en ese momento/contexto crei entender (+o-) el 'sentido de DoEvents.
mi 'descoloque' surjio cuando, al 'cargar' las imagenes directamente en la hoja y prescindir del userform
(y por tanto pensar que ya no se interactuaba con otra aplicacion) probe a suprimir el doevents en el codigo.
El resultado fue que, las imagenes, en vez de desplazarse mas o menos despacio hasta su ubicacion final
se abalanzaban en cuestion de un suspiro hasta el.
(ahora mismo se me ha ocurrido que quizas seria cuestion de seguir jugando con el 'retardo' hasta conseguir un efecto similar).
Sin embargo, esto no ocurre con el cuadro de texto.


__ 2 __
es (muy) posible que no haya seguido/entendido bien tu ultimo consejo de aquella consulta =>
-> si son pocas [probablemente] convendria mantenerlas en el archivo [obviamente usando la opcion >de vinculadas]
[es decir... incrustarlas por codigo una sola vez y proveerlas en la misma ubicacion si vas a >distribuir la aplicacion]
y dejar que el codigo solamente las vaya modificando en dimensiones y posicion -?-



Si puedes explicarme un poco mas a que te referias con => "incrustarlas por codigo una sola vez y proveerlas en la misma ubicacion"...
lo que hago hasta ahora es cargar las imagenes (guardadas en la misma carpeta) al abrir la presentacion
poniendo LinkToFile a true y SaveWithDocument a false, y al cerrar la presentacion elimino todas las formas.
Esta es la instruccion que las carga:->
MiHj.Shapes.AddPicture "C:\Documents...\...\ Foto" & nroFoto & ".jpg", msoTrue, _
msoFalse, InIzq, InSup, 142.5, 142.5
supongo que el insertar archivos se considera 'interactuar con otra aplicacion' y de ahi DoEvents?


__ 3 __
y, para no alargarme mucho mas (me temo que mis lagunas son tan grandes que cada consulta se acaba convirtiendo en un tomo)...

-> si ya estas 'familiarizado' con la rutina del retardo/'sleep', el 'equivalente' del DoEvents pudiera ser -> Retardo 0& ;)



me temo que, aunque poco a poco (creo que) le voy cogiendo el punto, ... familiarizarme, familiarizarme
podrias explicarme un poco como usar el 'eqivalente' -> Retardo 0&...?
... gracias... por el 'cursor', y, creo que aun mas, por agregar 'Wait' a la saga de mis desconciertos...
Respuesta Responder a este mensaje
#5 Ivan
15/10/2006 - 04:22 | Informe spam
Hola Hector Miguel, muchas gracias de nuevo

por lo que se ve no habia dado pie con bola. Creo que tendre que
replantear bastante la presentacion.

Hay varias cosas que he estado viendo, comparando el funcionamiento
(sobre todo respecto a doevents) de tus codigos y los que yo estoy
usando. Pero prefiero estudiarlas un poco mas antes de comentartelas, y
creo que hoy ya tengo la neurona envuelta en un buen galimatias y
pidiendome un descanso. (por estos lares como que ya va siendo hora).

Si no te importa, mañana te comento lo que voy viendo, tambien
respecto a 'saltarse la presentacion' que ya he conseguido (supongo que
habras visto la otra consulta) pero que en la forma en que lo he hecho,
tambien tiene comportamientos 'curiosillos' cuando se cruza/descruza
con doevents.

un saludo y de nuevo muchas gracias por todo
Ivan
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida