Foro de elhacker.net

Programación => Programación Visual Basic => Mensaje iniciado por: DarkMatrix en 21 Diciembre 2010, 08:09 am



Título: API SetCursor
Publicado por: DarkMatrix en 21 Diciembre 2010, 08:09 am
Buenas, tengo un pequeño problema con una aplicacion que no me carga un cursor, debido a esto me vi obligado a usar varias APIs para cargar el cursor. En si la aplicacion si cargo el cursor correctamente pero solo hasta que se mueve el mouse luego de eso regresa al anterior :S.

La idea es cargar el cursor en la aplicacion y cuando esta cierre que el cursor quede como estaba.

Aca les dejo el code que encontre pero es el que cambia al mover el cursor:

Código
  1.  
  2.    Private Declare Function LoadCursorFromFile Lib "user32.dll" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As Long
  3.    Private Declare Function SetCursor Lib "user32.dll" (ByVal hCursor As Long) As Long
  4.  
  5.    ' Display the application starting (arrow and hourglass) Windows
  6.    ' cursor for three seconds. The cursor resource is loaded from Windows. Then
  7.    ' restore the old cursor (whatever it happens to be).
  8.  
  9.    Dim hcursor    As Long ' receives handle to application starting cursor
  10.    Dim holdcursor As Long ' receives handle to previously used cursor
  11.    Dim retval     As Long ' throw-away return value
  12.  
  13.    hcursor = LoadCursor(0, IDC_APPSTARTING) ' load Windows's application starting cursor
  14.    holdcursor = SetCursor(hcursor) ' set it to the new cursor
  15.  
  16.    Sleep 3000 ' wait for 3 seconds
  17.  
  18.    retval = SetCursor(holdcursor) ' set it to the previous cursor
  19.  
  20.  

NOTA: Intente cambiando el cursor actual con SetSystemCursor pero no creo que eso sea buena idea ya que despues hay que restaurar el cursor de forma manual :S.


Título: Re: API SetCursor
Publicado por: raul338 en 21 Diciembre 2010, 14:33 pm
No uses Sleep, usa doevents, BlackZeroX tiene una funcion que te puede ayudar


Título: Re: API SetCursor
Publicado por: DarkMatrix en 21 Diciembre 2010, 18:04 pm
Si lo intente con DoEvents pero inmediatamente despues de cambiar el cursor vuelve al anterior :S


Título: Re: API SetCursor
Publicado por: 79137913 en 21 Diciembre 2010, 18:07 pm
HOLA!!!

Intentaste no usar el cursor, usa un shape o form o picturebox o lo que sea que persiga al mouse, entonces tenes un mouse "visible".

GRACIAS POR LEER!!!


Título: Re: API SetCursor
Publicado por: raul338 en 21 Diciembre 2010, 18:24 pm
Si lo intente con DoEvents pero inmediatamente despues de cambiar el cursor vuelve al anterior :S

Esporque tenes que hacer doevents mediante 3 segundos, con algun bucle o algo :P


Título: Re: API SetCursor
Publicado por: Karcrack en 21 Diciembre 2010, 21:07 pm
Esporque tenes que hacer doevents mediante 3 segundos, con algun bucle o algo :P
:¬¬ Entonces porque no usar Sleep() :huh:

Aun asi, la cosa seria como esto:
Código:
Sub Wait(lMs as long)
dim lTimer as long
lTimer = Timer()
do
 DoEvents
loop while (Timer() - lTimer < lMs)
end sub


Título: Re: API SetCursor
Publicado por: raul338 en 21 Diciembre 2010, 21:35 pm
Karcrack, porque el sleep congela todo :xD


Título: Re: API SetCursor
Publicado por: DarkMatrix en 21 Diciembre 2010, 23:17 pm
Creo que no me entendieron mucho de que se trata :S, bueno aqui subi un projecto de ejemplo: http://www.megaupload.com/?d=T0HXO5OF

Ok el codigo es este:

Código
  1. Option Explicit
  2.  
  3. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  4. Private Declare Function LoadCursorFromFile Lib "user32.dll" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As Long
  5. Private Declare Function SetCursor Lib "user32.dll" (ByVal hCursor As Long) As Long
  6.  
  7. Private Sub Form_Load()
  8.  
  9.    Dim hCursor    As Long
  10.    Dim holdcursor As Long
  11.    Dim retval     As Long
  12.  
  13.    hCursor = LoadCursorFromFile(App.Path & "\AB1.cur")
  14.  
  15.    If hCursor = 0 Then End
  16.  
  17.    holdcursor = SetCursor(hCursor)
  18.  
  19.    Sleep 3000 ' Mientras la aplicacion se encuentra pausada el cursor se mantiene
  20.  
  21.    retval = SetCursor(holdcursor) ' si se anula esta linea para no restaurar el cursor anterior, igual vuelve a como estaba antes :S.
  22.  
  23. End Sub
  24.  
  25.  

Lo que quiero lograr es que el cursor se mantenga hasta finalizar la aplicacion o llamar a la funcion para restaurarlo. Alguna idea del porque el cursor vuelve a como estaba?


Título: Re: API SetCursor
Publicado por: raul338 en 21 Diciembre 2010, 23:44 pm
Código
  1. Option Explicit
  2.  
  3. Private Declare Function SetCursor Lib "user32.dll" (ByVal hcursor As Long) As Long
  4. Private Declare Function GetTickCount Lib "kernel32" () As Long
  5. Private Const IDC_APPSTARTING As Long = 32650
  6. Private Const IDC_ARROW As Long = 32512&
  7. Private Declare Function LoadCursor Lib "user32.dll" Alias "LoadCursorA" (ByVal hInstance As Long, ByVal lpCursorName As Any) As Long
  8. Dim normal As Long, wait As Long
  9.  
  10. Private Sub Form_Load()
  11.    wait = LoadCursor(0&, IDC_APPSTARTING)
  12.    normal = LoadCursor(0&, IDC_ARROW)
  13.    Esperar 3000
  14.    Call SetCursor(normal) ' set it to the previous cursor
  15. End Sub
  16.  
  17. Public Sub Esperar(Miliseconds As Long)
  18.    Dim retraso As Long
  19.    'GetTickCount devuelve un valor inicial, y se lo sumamos al de retraso
  20.    retraso = Miliseconds + GetTickCount
  21.    While retraso >= GetTickCount
  22.        DoEvents
  23.        Call SetCursor(wait)
  24.    Wend
  25. End Sub
  26.  

El problema fue que apenas se ponia el cursor, se cambiaba el cursor a otro segun el evento de una ventana  :P por eso en ese bucle, forzamos a mostrar nuestro cursor :P


Título: Re: API SetCursor
Publicado por: Psyke1 en 21 Diciembre 2010, 23:56 pm
¿Lo que buscas no es esto? :huh:

Código
  1. Option Explicit
  2.  
  3. Private Declare Function LoadCursorFromFile Lib "user32.dll" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As Long
  4. Private Declare Function SetCursor Lib "user32.dll" (ByVal hCursor As Long) As Long
  5.  
  6. Private hOldCursor              As Long
  7. Private bStop                   As Boolean
  8.  
  9. Private Sub Form_Load()
  10. Dim hCursor                     As Long
  11.  
  12.    hCursor = LoadCursorFromFile("c:\bullseye.cur")
  13.  
  14.    If hCursor = 0 Then End
  15.  
  16.    Me.Show: DoEvents
  17.  
  18.    Do While bStop = False
  19.        hOldCursor = SetCursor(hCursor)
  20.        DoEvents
  21.    Loop
  22. End Sub
  23.  
  24. Private Sub Form_Unload(Cancel As Integer)
  25.    bStop = True
  26.    Call SetCursor(hOldCursor)
  27. End Sub

DoEvents! :P


Título: Re: API SetCursor
Publicado por: DarkMatrix en 22 Diciembre 2010, 01:03 am
Mr. Frog © estas en lo correcto algo asi es lo que necesito, pero hay un problema, ya habia intentado algo asi y resulta que en la aplicacion en la que quiero implementar la funcion para cambiar el mouse ya tiene un sub que entra en un bucle y por lo tanto uno de los dos bucles no se ejecutara :S, Alguna otra idea?


Título: Re: API SetCursor
Publicado por: raul338 en 22 Diciembre 2010, 01:34 am
Mezcla los 2 eventos :P Que tipo de bucle es ?


Título: Re: API SetCursor
Publicado por: DarkMatrix en 22 Diciembre 2010, 01:56 am
Lo haria pero pasa que si se mezclan entonces el mouse no se redibuja con la frecuencia suficiente como para simular que el cursor no cambia :S, Es un bucle encargado de pintar en un picturebox el cual siempre se esta ejecutando.


Título: Re: API SetCursor
Publicado por: raul338 en 22 Diciembre 2010, 13:38 pm
Entonces tienes un problema de repintado, tienes que optimizar el bucle ._.


Título: Re: API SetCursor
Publicado por: BlackZeroX en 23 Diciembre 2010, 21:36 pm
.
@DarkMatrix

si es para el juego de YuGioh que traes mejor resignate a pasarlo a un motor grafico como DirectX u OpenGL asi no tendras que gastar el procesador en vano.

Funcion Wait (No consume procesador) (http://infrangelux.hostei.com/index.php?option=com_content&view=article&id=6:artwait&catid=2:catprocmanager&Itemid=8)

Tome el ejemplo de la API Guide, saque todas las variable por que no queria estar revisando cuales eran las que se requerian asi que aqui tienes, no se come el proesador, y no para el hilo de tu programa.

Código
  1. '
  2. '   /////////////////////////////////////////////////////////////
  3. '   // Autor:   BlackZeroX ( Ortega Avila Miguel Angel )       //
  4. '   //                                                         //
  5. '   // Web:     http://InfrAngeluX.Sytes.Net/                  //
  6. '   //                                                         //
  7. '   //    |-> Pueden Distribuir Este codigo siempre y cuando   //
  8. '   // no se eliminen los creditos originales de este codigo   //
  9. '   // No importando que sea modificado/editado o engrandecido //
  10. '   // o achicado, si es en base a este codigo                 //
  11. '   /////////////////////////////////////////////////////////////
  12. '   // http://infrangelux.sytes.net/Blog/index.php?option=com_content&view=article&id=6:artwait&catid=2:catprocmanager&Itemid=8
  13. '   /////////////////////////////////////////////////////////////
  14. Option Explicit
  15. Private Declare Function WaitMessage Lib "user32" () As Long
  16. Enum eTime
  17.    Horas = 3600
  18.    Minutos = 60
  19.    Segundos = 1
  20. End Enum
  21.  
  22. Private Declare Function CreateCursor Lib "user32" (ByVal hInstance As Long, ByVal nXhotspot As Long, ByVal nYhotspot As Long, ByVal nWidth As Long, ByVal nHeight As Long, lpANDbitPlane As Any, lpXORbitPlane As Any) As Long
  23. Private Declare Function DestroyCursor Lib "user32" (ByVal hCursor As Long) As Long
  24. Private Declare Function SetCursor Lib "user32" (ByVal hCursor As Long) As Long
  25. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  26.    Dim hnewcursor As Long  ' newly created cursor
  27.    Dim holdcursor As Long  ' receives handle of default cursor
  28. Private Sub Form_Load()
  29.    'KPD-Team 1999
  30.    'URL: http://www.allapi.net/
  31.    'E-Mail: KPDTeam@Allapi.net
  32.  
  33.    ' Create a 32x32 color cursor shaped somewhat like a yin-yang symbol.
  34.    ' (The bit masks come from Microsoft's documentation on the API cursors function, just to
  35.    ' give them their due credit.)  Note how the masks are loaded into the arrays.  The new
  36.    ' cursor is then set to be the cursor for 10 seconds.
  37.    Dim andbuffer As String, xorbuffer As String  ' buffers for masks
  38.    Dim andbits(0 To 127) As Byte  ' stores the AND mask
  39.    Dim xorbits(0 To 127) As Byte  ' stores the XOR mask
  40.    Dim c As Integer, retval As Long  ' counter and return value
  41.  
  42.    ' Unfortunately, VB does not provide a nice way to load lots of information into an array.
  43.    ' To load the AND and XOR masks, we put the raw hex values into the string buffers
  44.    ' and use a loop to convert the hex values into numeric values and load them into
  45.    ' the elements of the array.  Yes, it's ugly, but there's no better way.  Note the
  46.    ' use of the line-continuation character here.  Each sequence of eight hex
  47.    ' characters represents one line in the 32x32 cursor.
  48.    andbuffer = "FFFC3FFF" & "FFC01FFF" & "FF003FFF" & "FE00FFFF" & _
  49.            "F701FFFF" & "F003FFFF" & "F003FFFF" & "E007FFFF" & _
  50.            "C007FFFF" & "C00FFFFF" & "800FFFFF" & "800FFFFF" & _
  51.            "8007FFFF" & "8007FFFF" & "0003FFFF" & "0000FFFF" & _
  52.            "00007FFF" & "00001FFF" & "00000FFF" & "80000FFF" & _
  53.            "800007FF" & "800007FF" & "C00007FF" & "C0000FFF" & _
  54.            "E0000FFF" & "F0001FFF" & "F0001FFF" & "F8003FFF" & _
  55.            "FE007FFF" & "FF00FFFF" & "FFC3FFFF" & "FFFFFFFF"
  56.    xorbuffer = "00000000" & "0003C000" & "003F0000" & "00FE0000" & _
  57.            "0EFC0000" & "07F80000" & "07F80000" & "0FF00000" & _
  58.            "1FF00000" & "1FE00000" & "3FE00000" & "3FE00000" & _
  59.            "3FF00000" & "7FF00000" & "7FF80000" & "7FFC0000" & _
  60.            "7FFF0000" & "7FFF8000" & "7FFFE000" & "3FFFE000" & _
  61.            "3FC7F000" & "3F83F000" & "1F83F000" & "1F83E000" & _
  62.            "0FC7E000" & "07FFC000" & "07FFC000" & "01FF8000" & _
  63.            "00FF0000" & "003C0000" & "00000000" & "00000000"
  64.    ' Now load these hex values into the proper arrays.
  65.    For c = 0 To 127
  66.        andbits(c) = Val("&H" & Mid(andbuffer, 2 * c + 1, 2))
  67.        xorbits(c) = Val("&H" & Mid(xorbuffer, 2 * c + 1, 2))
  68.    Next c
  69.    ' Finally, create this cursor!  The hotspot is at (19,2) on the cursor.
  70.    hnewcursor = CreateCursor(App.hInstance, 19, 2, 32, 32, andbits(0), xorbits(0))
  71.    ' Set the new cursor as the current cursor for 10 seconds and then switch back.
  72.   wait 10000, Horas   'Wait 10000 horas jeje haber que pc aguanta esto encendida...
  73.    retval = SetCursor(holdcursor)  ' change cursor back
  74.    ' Destroy the new cursor.
  75.    retval = DestroyCursor(hnewcursor)
  76. End Sub
  77. Public Sub wait(ByVal vToWait&, Optional ByVal ThisWait As eTime = Segundos, Optional ByVal UseAllProc As Boolean = False)
  78. Dim vDateE      As Date
  79.    vDateE = DateAdd("s", vToWait& * (ThisWait + 0), Time)
  80.    Do While vDateE > Time
  81.        holdcursor = SetCursor(hnewcursor)  ' change cursor
  82.        Call WaitMessage
  83.        If Not UseAllProc Then DoEvents
  84.    Loop
  85. End Sub
  86.  
  87.  

P.D.: Adapta el codigo y metelo a un modulo de clase y donde puse holdcursor = SetCursor(hnewcursor)  ' change cursor puedes meter un RaiseEvent... solo para notificar por mensajes entrantes asi se puede malear el proceso Wait()...

Temibles Lunas!¡.