Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Eleкtro

#3651
Cita de: Lekim en 16 Junio 2016, 01:13 AMen otro foro (en inglés) un usuario me ha puesto de los nervios porque no hacía más que decirme que era muy fácil, que usara MouseEnter, MouseLeave. Yo le dije que estos eventos no fucionan cuando arrastras el puntero con el bóton del ratón presionado, que no devuelven el índice del control donde se encuentra el puntero. De nuevo me contesta - ten encuenta el OOP, bla, bla, bla...-, jolines si es tan fácil teclea un poco y lo pones maldito hijo de la gran....   Igual se penseava que es sólo el clic.

Hola Lekim.

Si me equivoco en mis suposiciones, corrígeme, pero según leo en ese comentario das a entender que lo que realmente quieres hacer (ahora) es conseguir que se dispare el evento MouseDown en un control mientras mantienes presionado el botón izquierdo del mouse sobre el Form y arrastras el puntero hasta ese control. ¿es así?.




Cita de: Lekim en 16 Junio 2016, 01:13 AMAhora saldrá el listo que dirá, pero si es muy fácil no hace falta hacer tanta historia...

Es que es muy fácil, no hace falta hacer tanta historia  ...xD.

No, ahora en serio, si tu propósito es hacer lo que he mencionado, entonces solamente tienes que controlar e ignorar el mensaje de ventana que se procesa cuando presionas el botón izquierdo del mouse sobre el Form (o sobre la ventana Win32 que sea), es decir, el mensaje de ventana WM_LBUTTONDOWN (&H201).

Esto puede interferir o no en lo que realmente quieras hacer, pero de todas formas te lo explicaré. Para ello simpelmente tienes que declarar un sustituto del controlador base de mensajes de ventana, el método WndProc:

Código (vbnet) [Seleccionar]
Public NotInheritable Class Form1 : Inherits Form

   Private Sub TextBox1_MouseEnter(sender As Object, e As EventArgs) Handles TextBox1.MouseEnter
       MsgBox("Hello World!")
   End Sub

   Protected Overrides Sub WndProc(ByRef m As Message)

       Select Case m.Msg
           Case &H201 ' WM_LButtonDown
               m.Result = IntPtr.Zero

           Case Else
               ' Return message to base message handler.
               MyBase.WndProc(m)
       End Select

   End Sub

End Class


Nota: El valor de retorno "0" realmente no es necesario, con dejar el bloque del Case vacío es suficiente, pero en las indicaciones de MSDN especifica que si procesamos el mensaje debemos devolver Cero ...por alguna razón será.

También te puede venir bien hacer uso del mensaje WM_NCHITTEST (&H84) junto a la enumeración de test de posicionamientos (ej. HTNOWHERE) que está documentada aquí abajo, pero esto es ya según lo que pretendas hacer.

Y ya que estamos, hago un poco de publicidad para recordarte que todo lo necesario (con respecto a lo que he explicado) lo puedes encontrar ya implementado en mi API (por si quieres trastear con la WinAPI sin tener que ponerte a declarar cientos de cosas):

EDITO:
Si necesitas un ejemplo para controlar el mensaje WM_NCHITTEST, quizás te sirva esto:
(localiza el método WndProc)

Saludos.
#3652
Windows / Re: Crear windows desatendido
15 Junio 2016, 02:48 AM
Cita de: cristiansbd95 en 15 Junio 2016, 00:29 AMSi utilizáis otra herramienta para crear estos tipos de windows me gustaría que me pusierais vuestra opinión.

Antes de nada quiero hacerte saber que todas las herramientas existentes y por existir son solamente un wrapper de la API DismAPI de Microsoft (las aplicaciones más mediocres hacen uso de otro wrapper, la aplicación DISM de Microsoft), con funcionalidades extendidas (ej. como tu has dicho, poder seleccionar un programa y añadirlo de forma guiada y automatizada ...sin mayor interacción por tu parte.)

Dicho esto, considero que la aplicación más completa es WinToolkit (si, funciona para Windows 10).

Sin embargo, este tipo de aplicaciones tienen ciertas limitaciones, como por ejemplo poder añadir/instalar una aplicación que no está soportada, ya que los programas soportados o "predefinidos" por así decirlo están soportados por que para realizar el proceso de automatización el autor conoce que claves de registro ha de añadir, o todo lo demás que haya que hacer,
Ante este tipo de limitaciones, la solución más efectiva siempre es recurrir a la ya mencionada aplicación DISM de Microsoft (o bien a la DismAPI que ya mencioné, pero solo en caso de que tengas nociones de programación), aunque existen pasos adicionales que son necesarios.

A continuación te explicaré lo que debes hacer en caso de utilizar DISM, sin embargo, debo dividir las soluciones en dos soluciones diferentes, puesto que dependiendo del tipo de programa que quieras instalar, vas a necesitar una solución, o la otra.




En caso de que sea una aplicación "normalita", es decir, una aplicación portable que funcione con copiar y pegar, que no manipule el registro para añadir cientos de entradas, que no instale drivers, ni registre componentes ActiveX o librerías adicionales, o haga otras cosas raras.

1. Descarga la versión de DISM compatible con Windows 10. Para ello, debes descargar el kit Windows ADK:
(si tu sistema operativo actual es Windows 10, obviamente puedes saltarte este paso.)

2. Monta la imagen objetivo de Windows 10 en un directorio cualquiera. Con el siguiente comando:
Dism.exe /Mount-Image /ImageFile:"C:\Ruta de la imagen\Install.wim" /Index:"Índice de la imagen" /MountDir:"C:\Directorio de montado"
Lo más importante a destacar es que debes asegurarte de especificar el índice de la imagen correcto. En un DVD original, cada índice (1,2,3,etc) indica la edición de Windows (Home, Professional, Ultimate, etc).
Nota: Suele tardar en montar al rededor de 5-10 minutos.

3. Copia y pega el programa (junto a sus librerías y etc) en el directorio "C:\Directorio de montado\Program Files\Mi Programa" o bien "C:\Directorio de montado\Program Files (x86)\Mi Programa" dependiendo de la arquitectura de dicho programa.

4. Desmonta la imagen, aplicando los cambios efectuados. Con el siguiente comando:
Dism.exe /Unmount-WIM /Commit /MountDir:"C:\Directorio de montado"

En este punto, los cambios se habrán guardado en el archivo "Install.wim". Ya está todo listo.




En caso de que sea una aplicación no tan "normalita", o no estés seguro de que cambios realiza el programa en el sistema operativo durante el proceso de instalación:

Te advierto que es una tarea que lleva su tiempo, un par de horas. No es que sea una tarea compleja, simplemente requiere tiempo ...ya irás viendo el por qué.

1. Descarga un software de virtualización de sistemas operativos. Puedes utilizar VirtualBox, pero yo te recomiendo VMWare Player, ambos son gratuitos.

2. Crea un disco duro virtual de al menos 100 GB, e instala la ISO de Windows 10.
También puedes realizar la instalación desde un DVD o directorio que contenga los archivos del DVD de instalación (al menos con VMWare).

IMPORTANTE, al momento de instar Windows 10, en el menú de particiones, debes dividir el disco duro en dos particiones. Si no lo haces ahora, deberás hacerlo en cualquier otro momento desde el administrador de discos de Windows, o si lo prefieres, con el siguiente script:

Código (dos) [Seleccionar]
@Echo OFF

REM =================
REM Console Settings:
REM =================

Title Create Windows Capture Partition - By Elektro
Mode Con Cols=150 Lines=50
CHCP 1252 1>NUL & REM Windows-1252, Spanish-Latin.


REM ==============
REM User Settings:
REM ==============

Set "SourceLetter=C"
Set "TargetLetter=W"
Set "VolumeSize=50000" & REM Size in MegaBytes, 50 GB.
Set "VolumeName=Windows Capture"


REM =====
REM Info:
REM =====

Echo+
Echo  ------------------------------------------------------------------------------------
Echo  This script will create a seconday partition to capture another Windows OS partition
Echo  ------------------------------------------------------------------------------------
Echo+

(
Echo REM Select partition "%SourceLetter%:\".
Echo Select Volume "%SourceLetter%"
Echo+
Echo REM Reduce %VolumeSize% Bytes of partition size, in megabytes.
Echo Shrink Desired="%VolumeSize%"
Echo+
Echo REM Create a partition "%TargetLetter%:\".
Echo Create Partition Primary Size="%VolumeSize%"
Echo Assign Letter="%TargetLetter%"
Echo Format FS="NTFS" Label="%VolumeName%"
)>"%Temp%\Diskpart.ini"

Diskpart.exe /S "%Temp%\Diskpart.ini"

Pause&Exit /B 0


3. Al finalizar la instalación del Windows 10 virtualizado, cuando ya hayas entrado a tu sesión de usuario, instala las extensiones del software de virtualización para poder compartir carpetas.
En VMWare, esto se hace mediante el menú "VM -> Install VMWare Tools"
En VirtualBox, tienes que descargar manualmente el paquete de extensiones, desde su página web, y luego instalarlas haciendo doble click sobre el archivo descargado.

Acto seguido, establece una carpeta compartida. Esto será un directorio local al que el Windows 10 virtualizado podrá acceder, para ejecutar el instalador del programa en cuestión.

Nota: Si lo prefieres puedes compartirte a ti mismo el programa en cuestión enviándotelo a tu dirección de correo, y despues descargándolo desde el Windows 10 virtualizado. O usando OneDrive, etc.

4. Iinstala el programa en el Windows 10 virtualizado.

5. Reinicia el Windows 10 virtualizado (para que se apliquen correctamente cualquier posible cambio desconocido en el sistema.)

6. Apaga el Windows 10 virtualizado.

7. Ahora lo que debes hacer es volver a instalar Windows 10 en el disco duro virtual, pero seleccionando la otra partición.

Has oido bien. Nuestra intención es capturar los cambios realizados en el Windows 10 principal (el que instalaste en la primera partición), y para ello debemos crear una nueva imagen de instalación de Windows (Install.wim), esto es obligatorio hacerlo desde otra partición.

8. Inicia sesión en este último Windows que hemos instalado, y crea un archivo con extensión ".ini" con el siguiente contenido:

Archivo.ini
Código (ini) [Seleccionar]
[ExclusionList]
"System Volume Information"
"VirtualBox Guest Additions"
Program Files\VMWare\VMware Tools
$Recycle.Bin
*.bak
*.log
*.wim
BCD
appdb.dat
StaticCache.dat
DataStore.edb
ExplorerStartupLog.etl
ExplorerStartupLog_RunOnce.etl
FNTCACHE.DAT
FontCache-FontFace.dat
PackageRepository.edb
hiberfil.sys
iconcache_1024.db
iconcache_16.db
iconcache_1600.db
iconcache_256.db
iconcache_32.db
iconcache_48.db
iconcache_96.db
iconcache_exif.db
iconcache_idx.db
iconcache_sr.db
iconcache_wide.db
iconcache_wide_alternate.db
pagefile.sys
swapfile.sys
thumbcache_16.db
thumbcache_32.db
thumbcache_48.db
thumbcache_idx.db
ThumbCacheToDelete
TileCacheDefault-*_80.dat
TileCacheDefault-*_100.dat
TileCacheLogo-*_100.dat
TileCacheLogo-*_100.dat
TileCacheStartView-*_80.dat
TileCacheStartView-*_100.dat
TileCacheTickle-*_80.dat
TileCacheTickle-*_100.dat
WebCacheV01.dat
Windows.edb
Windows\CSC
WinPEpge.sys

(el contenido especifica las exclusiones de la captura, sirve para evitar que se incremente el tamaño del archivo Install.wim resultante.
El tamaño resultante debería ser practicamente igual o incluso menor que el archivo "Install.wim" que ya tienes.)

9.  Ahora procederemos con la captura del sistema operativo principal, desde el sistema operativo secundario. Con el siguiente comando:
DISM.exe /Capture-Image /ImageFile:".\Install.wim" /CaptureDir:"C:\" /ConfigFile:"Archivo.ini" /Name:"Windows 10" /Description:"Windows 10 Mod" /Compress:"Maximum" /CheckIntegrity /Verify /Bootable /NoRpFix

Nota: en el parámetro /Name debes especificar el nombre exacto de la imagen a capturar. En caso de que hayas instalado la edición "Home", entonces usa el nombre "Windows 10" como en el ejemplo. Para la versión profesional sinceramente desconozco el nombre, pero lo deberías poder averiguar mediante NTLite o WinToolkit.

Nota: Puede tardar más de 60 minutos.

10. Finálmente ya tenemos nuestro nuevo "Install.wim" que contiene el programa instalado. Solo tienes que transferir ese archivo a tu sistema operativo anfitrión o host, y ya estará todo listo.

Saludos.
#3653
¿VB6, o VB.NET?. No recuerdo ni por asomo el tema de los recursos en VB6.





Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Extracts a resource to disk.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' ExtractResourceToDisk(My.Resources.MyTextfile, "C:\File.txt")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="resource">
''' The resource to extract.
''' </param>
'''
''' <param name="targetFilepath">
''' The target filepath where to save the resource data.
''' </param>
'''
''' <param name="overwrite">
''' If set to <see langword="True"/>, overwites any existing file,
''' otherwise, if the file already exists, a <see cref="Global.System.IO.IOException"/> exception is thrown.
''' </param>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub ExtractResourceToDisk(ByVal resource As Byte(),
                                       ByVal targetFilepath As String,
                                       Optional ByVal overwrite As Boolean = False)

   Dim mode As FileMode
   If overwrite Then
       mode = FileMode.Create
   Else
       mode = FileMode.CreateNew
   End If

   Dim bufferSize As Integer = Streams.GetFileStreamBufferSize(resource.Length)

   Using fs As New FileStream(targetFilepath, mode, FileAccess.Write, FileShare.Read, bufferSize)
       fs.Write(resource, 0, resource.Length)
   End Using

End Sub


Ejemplo de uso:
Código (vbnet) [Seleccionar]
ExtractResourceToDisk(My.Resources.MyTextfile, "C:\File.txt")

Fuente:

Saludos.
#3654
En realidad no hay ningún error, estás describiendo el comportamiento normal del algoritmo de ordenamiento de texto, donde "2" es mayor que "1000".

El problema real es que estás añadiendo elementos de tipo String en el ListBox. Si añadieses elementos de tipo Integer, entonces la propiedad ListBox.Sorted cumpliría su cometido dando el resultado que esperas obtener, un ordenamiento numérico.

La solución más directa ya la he mencionado, pero de todas formas una solución simple al problema actual sería la siguiente:
Código (vbnet) [Seleccionar]
Dim integerSet As New SortedSet(Of Integer)
For Each item As Object In Me.ListBox1.Items
    integerSet.Add(CInt(item))
Next item

' Me.ListBox1.SuspendLayout()
Me.ListBox1.Items.Clear()
For Each value As Integer In integerSet
    Me.ListBox1.Items.Add(value)
Next value
' Me.ListBox1.ResumeLayout()


Nota: También puedes utilizar el tipo List para añadir los elementos numéricos de forma desordenada, y activar la propiedad ListBox.Sorted, el resultado será el mismo.

Saludos.
#3657
Cita de: DarK_FirefoX en 14 Junio 2016, 18:37 PMCreo que deberías usar:

%%r

en la línea:

for %%r in (*.zip) do (

Efectivamente ese es el error.

Es imposible que a su compañero le funcione como el OP mencionó, puesto que está obligado a dar error de sintaxis por el error que comentaste.

Las variables de FOR deben ser nombradas con dos símbolos de porcentaje para poder expandirla. Solo se debe hacer lo contrario, es decir, escribir un único símbolo de porcentaje, si colocamos y ejecutamos el código directamente en una instancia abierta de la CMD.

Saludos
#3658
Cita de: VladimirKux en 14 Junio 2016, 03:53 AMSolo quiero que ejecute la orden y cuando llege el tiempo que se cierre :)

Esto no va así, el comando TaskKill no expone ningún parámetro para poder especificar un tiempo de retraso o delay.

Debes hacer lo contrario, primero esperar, y cuando llegue el momento adecuado, ejecutar la orden. Puedes hacerlo con un búcle "infinito", de la siguiente manera:

Código (dos) [Seleccionar]
@Echo Off & SetLocal EnableDelayedExpansion
Title TaskKill with countdown

Set "ProcessName=Notepad"
Set "TargetTime=02:00" :: 2 AM.

For /L %%# In (0, 1, 99999999999) Do (
   Set /A "CurrentHour=!TIME:~0,2!"
   Set /A "CurrentMins=!TIME:~3,2!"
   Set /A "TargetHour=%TargetTime:~0,2%"
   Set /A "TargetMins=%TargetTime:~3,2%"

   If !CurrentHour! EQU !TargetHour! If !CurrentMins! EQU !TargetMins! (
       Call :KillProcess "%ProcessName%"
   )

   (TimeOut /T 10 /NoBreak)1>NUL
)

:KillProcess :: %1=ProcessName
(TakKill.exe /F /T /IM "%~1")2>NUL && (
   Echo Process "%~1" killed successfully.
) || (
    Echo Failed to kill process: "%~1".
)
GoTo :End

:End
Pause&Exit /B 0


Saludos.
#3659
.NET (C#, VB.NET, ASP) / Re: Bingo WEB
15 Junio 2016, 00:05 AM
    Hola.

CitarLa cosa es, como puedo hacer dicho sistema? Supongo que seria la parte servidor la que se encarga de decir el numero, pero, ¿como lo envió a los usuarios?¿Como implemento una nueva partida?¿Que debo de añadirle al proyecto?

Lo siento por la espera, y además lamentablemente no traigo buenas noticias para ti con respecto a lo citado.

Tenía la esperanza de poder ofrecerte ayudarte de forma superficial para que pudieras implementar la lógica del algoritmo, pero lo cierto es que no manejo ASP.NET hasta el punto necesario para poder ayudarte con el server y la "entrega"  de número y etc, lo siento.

De todas formas lo mejor que has posido hacer ha sido proporcionar todos los detalles necesarios que hacian falta, con eso alguien te podrá ayudar mucho mejor que yo.




Respecto a lo de iniciar una app WinForms desde ASP.NET, hace tiempo leí algo respecto a unas limitaciones, voy a ponerme a buscar mientras escribo esto...

Aquí tienes algo de información y posibles soluciones a ese último problema:
(El último enlace muestra lo que parece una solución definitiva.)[/list]

Fuente:

Saludos y suerte.
#3660
Hola.

Antes de nada: Gracias por compartir.

Con intención de que puedas mejorar el código que has compartido, te digo lo siguiente:

En el primer código cometiste una errata sin importancia, pero todo hay que mencionarlo, tienes declarado un método que se llama "ConstruyeTeclado",
eso lo descubrí observando las asociaciones de eventos (AddHandler ...), los cuales me he dado cuenta de que no las desasocias en ningún momento (RemoveHandler ...), lo cual en un principio no es un problema real, ya que solo los asocias una única vez durante el tiempo de vida de la aplicación, pero para prevenir futuros despistes que causen residuos sin liberar, convendría añadir las respectivas desasociaciones al inicio de los correspondientes métodos donde creas las asociaciones de eventos.

No he analizado mucho más el primer código, pero he visto que recurres a la función mouse_event de la WinAPI para sintetizar el botón izquierda y el del centro, ¿por qué motivo?, parece ser una metodología sustituible por código administrado, por ende optimizable, (o tal vez no) pero sin conocer el motivo no diré nada más por el momento.




Por último, me gustaría aconsejarte unas optimizaciones de diseño, solo son unos pequeños consejos que puedes aplicar u obviar (ya que no afectarán al funcionamiento del código):

1. Une las definiciones Win32 del módulo modEventMouse con la class ApiMidimessage (en la class, NO en el módulo).
De esta manera habrás separado el código administrado, del no administrado, compactándolo en un único lugar o class.

2. Asigna un nombre más convencional o estándar a la class modEventMouse, como por ejemplo SafeNativeMethods.
¿Por qué?, realmente no es por nada más que por seguir los estándares de nomenclatura de miembros y convenciones de uso.
Puedes leer más acerca de ello en la MSDN: https://msdn.microsoft.com/en-us/library/ms182161.aspx

3. Define un constructor por defecto y con visibilidad privada (Private Sub New() End Sub), para prevenir instanciar la class ApiMidimessage por error.

4. Asígnale el atributo SuppressUnmanagedCodeSecurity en esas funciones Win32 que has definido (o bien puedes asignarle el atributo a la class, y afectará a todos los miembros que contenga. ),
esto servirá para optimizar el rendimiento de las llamadas a esos métodos ...aunque para ser sinceros, en tu código practicamente no habrá diferencia al hacerlo (en el buen sentido).
Te recomiendo leer la sección 'Remarks' de este artículo de la MSDN: https://msdn.microsoft.com/en-us/library/system.security.suppressunmanagedcodesecurityattribute%28v=vs.110%29.aspx

5. Elimina el módulo.
Bueno, mejor dicho: Convierte el módulo en una clase no instanciable (leer el consejo nº3) dejando solo los wrappers EventoDown y EventoUp (el resto deberías haberlo movido a la class ApiMidimessage si aplicaste el consejo), y asígnale a esos wrappers una visibilidad global mediante el keyword Shared (Public Shared Sub EventoDown(...)).

6. No uses el keyword Call, ¡jamás!. No necesitas hacerlo, tampoco se recomiendo hacerlo, y aparte, está mal visto hacerlo, ya que es sinónimo de un acercamiento a las costumbres de VB6.
Cita de: MSDNYou can use the Call keyword when you call a procedure. For most procedure calls, you aren't required to use this keyword.

You typically use the Call keyword when the called expression doesn't start with an identifier. Use of the Call keyword for other uses isn't recommended.


If the procedure returns a value, the Call statement discards it.
( https://msdn.microsoft.com/en-us/library/sxz296wz.aspx )

Si lo que intentas es descartar/ignorar el valor de retorno de la función mouse_event, entonces en lugar de ignorarlo, contrólalo, y así mejoras la calidad de control de errores del código.

Saludos