Capturador

Autoit Avanzado más complejo con funciones "geek" para cualificarse como "ESPECIALISTA EN AUTOIT". Originales de autor, no copiados. Mín. 100 lineas
Responder
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Capturador

Mensaje por Ximorro »

Este es un programa completo que además uso bastante en el trabajo.

Se trata del típico capturador de pantallas, que ha ido creciendo hasta tener una funcionalidad aceptable.
Surgió porque en el trabajo hacía muchas capturas de mapitas, copiaba con ImprPant de Windows, abría el Paint y pegaba, recortaba el trozo que quería... así que hice un script que automáticamente presionaba el ImprPant, abría el Paint y pegaba... y de esas cuatro líneas fui ampliando y ampliando y surgió esto.
CapturaCapturador.png
CapturaCapturador.png (14.73 KiB) Visto 19070 veces
Encontré por la web programas parecidos, en algunos casos bastante más complejos, pero quería algo compacto y con funcionalidad suficiente. AutoIt es ideal para hacer un programita distribuible en un único EXE, así que me hice mi versión.

La funcionalidad que ofrece es la siguiente:
5 métodos de captura: Toda la pantalla, Ventana activa, Cliente de la Ventana activa, Objeto (paneles, botones, etc) y Rectángulo marcado por el usuario.
En el modo Objeto se va recuadrando en tiempo real el objeto que será capturado.
En el modo Rectángulo sale una ventanita de zoom para ajustar exactamente la zona a capturar.

Como opciones de post-proceso está guardar la imagen como png u otros formatos registrados y/o pegarla en el portapapeles (para luego pegarla en un procesador de textos o en un programa de dibujo, por ejemplo). Si se pega en el portapapeles se da la posibilidad opcional de abrir la imagen en MSPaint.
Además se puede elegir si se captura el cursor (tanto de ratón como de texto).

En el funcionamiento típicamente se elige método de captura y opciones y se activa. En ese momento el programa captura el HotKey para ImprPantalla, de tal manera que lo procesará el programa en vez de Windows. Según el modo capturará una cosa u otra cuando se pulse dicha tecla.
Para el modo objeto enseguida se va recuadrando el objeto bajo el cursor, que será la zona capturada cuando se presione ImprPant.
En el modo rectángulo cuando se presiona ImprPant primero se espera a que el usuario marque un rectángulo arrastrando con el ratón, después este rectángulo se puede mover y redimensionar con CTRL y los cursores (pulsando en pantalla sale una mini-ayuda, de ahí el cursor con interrogante). Para finalizar se pulsa INTRO y se captura el rectángulo especificado.

Al activar un modo se muestra en una etiqueta las instrucciones a seguir, son sencillas pero al principio mejor leerlo por lo de los modos Objeto/Rectángulo, que son un poco más elaborados.

Después de cada captura el modo queda activado, para volver a la funcionalidad de Windows hay que desactivarlo (o cerrar el programa). Antes se desactivaban solos después de la captura, pero el uso habitual me mostró que era más cómodo mantenerlo. En el método de Objeto sí lo desactivo porque es un modo "molesto" al estar recuadrando objetos todo el rato.
Una vez activado un modo aún se pueden cambiar las opciones de captura (excepto el método mismo, para eso primero hay que desactivar). La única excepción es cuando se está dibujando el rectángulo, una vez activado Y presionado ImprPant. En ese caso capturo el ratón para que no "toquitee" las ventanas mientras se dibuja (lo que hago es poner un GUI transparente delante del escritorio, que es el que recibe los clics)

Aquí tenéis el enlace para la descarga (Nota: ver más abajo para versiones más actualizadas):
http://www.mediafire.com/file/fi2injwyy ... urador.rar

ACTUALIZACIÓN 17/03/2010:
Adjunto el programa con la versión mejorada del diálogo de guardar. Ahora usa la extensión que se pone al archivo, o el tipo que se selecciona si no hay extensión. Por defecto es PNG, la más adecuada para "pantallazos" de programas. Por ejemplo para fotos es mejor JPG.
Los tipos de imagen que salen dependen de cada Windows, hay unos básicos pero hay programas que instalan más formatos, por ejemplo a mí me sale GIF (como podéis ver en una captura que pongo abajo en un comentario) pero creo que no viene directamente con Windows.

Aquí tenéis la descarga:
Capturador20100317.rar
(263.06 KiB) Descargado 850 veces
En el código sólo cambia la función _GuardaBMPenPNG(), que ha crecido un poco, aquí la tenéis:

Código: Seleccionar todo

Func _GuardaBMPenPNG($HBitmap)
	; Averiguamos los coders de imágenes registrados en GDI+
	_GDIPlus_Startup()
	Local $coders = _GDIPlus_Encoders()
	Local $filtros = "", $indicePNG, $nom, $extens
	For $i = 1 To $coders[0][0]
		$nom = $coders[$i][5]
		$extens = $coders[$i][6]
		If StringInStr($nom, "PNG", 2) <> 0 Then $indicePNG = $i
		$filtros &= "Imagen " & $nom & "  [" & $extens & "]" & " (" & $extens & ")|"
	Next
	; Quitamos última barra
	$filtros = StringTrimRight($filtros,1)
	;ConsoleWrite('$filtros = ' & $filtros & @crlf)

	Local $flags = BitOr($OFN_DONTADDTORECENT, $OFN_OVERWRITEPROMPT, $OFN_PATHMUSTEXIST, $OFN_NOREADONLYRETURN)
	Local $fich = _WinAPI_GetSaveFileName("Guardar en...", $filtros, @WorkingDir, "Captura", "", $indicePNG, $flags)
	If $fich[0] = 0 Then
		Local $sError = _WinAPI_CommDlgExtendedError()
		If $sError = 0 Then
			MsgBox(48, "Capturador", "Proceso cancelado. Imagen descartada.")
		Else
			MsgBox(48, "Capturador", "Error (" & @error & "): " & $sError)
		EndIf
	Else
		Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($HBitmap)
		_GDIPlus_ImageSaveToFile($hImage, $fich[1] & "\" & $fich[2])
		If @error Then
			MsgBox(48, "Capturador", 'Imagen "' & $fich[2] & '" no guardada:' & @LF & 'Extensión "' & _
					_GDIPlus_ExtractFileExt($fich[2]) & '" reconocida por Windows pero no registrada como imagen.')
		EndIf
		_GDIPlus_ImageDispose($hImage)
	EndIf
	_GDIPlus_ShutDown ()
EndFunc
SALUDOS
Última edición por Ximorro el 09 Jul 2010, 09:34, editado 2 veces en total.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
XPyro
Profesional del Autoit
Mensajes: 542
Registrado: 04 Mar 2007, 10:12
Ubicación: México
Contactar:

Re: Capturador

Mensaje por XPyro »

Me quedo con este capturador, muy bueno, buen trabajo y gracias por compartirlo :smt003 :smt006

PD: Una imagen no estaría mal en el primer post :smt001
Imagen
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Capturador

Mensaje por Chefito »

Lo mismo que el anterior. Muy chulo y buen trabajo :smt023 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

¡Gracias! Que os guste a vosotros que sois unas máquinas es un honor.
La verdad es que lo uso bastante en el trabajo, así que no ha sido un simple entretenimiento de programación, tiene su utilidad.

XPyro, espero que el GUI no te parezca muy simple, los tuyos me dejan con la boca abierta. Lo mío no es la estética visual, pero es funcional y compacto, que era el objetivo.

En cualquier caso una vez activado se puede minimizar, con lo que se quita del medio para hacer la captura que se quiera. Por cierto, en modo Objeto aunque esté recuadrando se pueden manipular las ventanas, moverlas, cerrarlas, abrir, lo que sea. Se prepara lo que se quiere y cuando se tiene se pulsa el segundo ImprPant que es el que hace la captura.

Es así en todos los modos excepto en el de Recuadro que una vez se ha empezado a dibujar ya no se pueden tocar las ventanas de detrás. Al principio hice dos versiones que sí dejaban (¡hice 4 versiones diferentes!). Una con GDI dibujando directamente en pantalla, pero en Vista se refrescaba que daba pena, otra con layered windows y el recuadro era el borde de una etiqueta en un formulario transparente... Esta versión es la que mejor va en XP y Vista/Aero...

Ningún problema en poner imágenes, pero necesito un pequeño tutorial... ¿puedo adjuntar una imagen en el foro y hacer que se vea directamente en el post? ¿O tengo que subirla a otro sitio?
No sé si MediaFire (versión gratuita) dejará poner directamente la foto, creo que obliga a descargarla. Tenía una cuenta en Flicker que no uso mucho, podría utilizar eso pero me parece que las pasa obligatoriamente a jpg, y para pantallazos ese formato no es bueno...
¿Se pueden poner directamente en el foro?

talueeeec
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
XPyro
Profesional del Autoit
Mensajes: 542
Registrado: 04 Mar 2007, 10:12
Ubicación: México
Contactar:

Re: Capturador

Mensaje por XPyro »

Que va si esta muy bien el GUI, es entendible :smt033

Para subir la fotos yo uso:
http://www.overpic.net/

existen otros servicios gratuitos que puedes elegir pero recomiendo este :smt003
Imagen
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

Pero ahí dice que como mucho las imágenes desaparecen a los 6 meses...

Desenpolvaré la cuenta de Flicker a ver... ;-)

Pondré alguna pantallita, e intentaré hacer algo más vistoso el post del capturador, puede que sea un programa que interese a alguien. De todas maneras por ejemplo lo de dia-noche si no lo ves funcionando tampoco se entiende...

Gracias por las sugerencias, ya digo que la estética no es lo mío, soy más bien práctico ;-)

¡hasta luego!
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Nahuel
Hacker del Foro
Mensajes: 194
Registrado: 27 Jun 2007, 23:32
Ubicación: Argentina
Contactar:

Re: Capturador

Mensaje por Nahuel »

Amigo, excelente! Yo habìa hecho uno similar, pero el tuyo es muy superior. Buen manejo de gràficos y objetos! Una pequeña sugerencia: Intentà asignarle la extensiòn PNG automàticamente a los archivos que el usuario elige guardar, pues no todos toman ese cuidado.

:smt023
No soy un hombre de plegarias, pero si estás en el cielo sálvame por favor Superman!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

¡Gracias Nahuel!

¿Pues sabes por qué no pongo la extensión? (bueno, se la pongo al nombre por defecto) Pues porque si ves el código, para guardar uso GDI+, a través de _GDIPlus_ImageSaveToFile. Muy convenientemente esta función utiliza los encoders internos de Windows, esto quiere decir que si en vez de ".png" pones ".jpg" pues te guarda un JPEG, igualmente puedes guardar el bitmap sin comprimir con ".bmp".

Puse por defecto png porque es el formato más adecuado para capturar pantallas, jpg sería interesante para fotos, pero al perder calidad no es bueno por ejemplo para capturar letras.

Así que lo dejé abierto, aunque es un "feature oculto", para poder cambiar el formato cuando quisiera. Pero tienes razón que un usuario normal muchas veces no pone extensión, lo que haré es dejar que se ponga la extensión que se quiera, y si no se pone ninguna pondré el png. Básicamente lo que haré es que si no hay ningún punto en el nombre asumiré que no hay extensión.

De todas maneras ya puestos investigaré a ver cómo sacar una lista de encoders adecuados con sus extensiones para crear la lista para FileSaveDialog, normalmente no va a ser interesante guardar en un formato diferente a PNG pero ya que estamos... Si veo bien eso dejará de ser un "feature oculto", aunque es una opción que se usará raramente.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

He estado mirando lo de la extensión de la imagen, y en principio puedo ver los coders con _GDIPlus_Encoders(). Esa función da mucha información y gracias a ella he podido crear los filtros para FileSaveDialog, la verdad es que queda potito:
FiltrosCapturador.png
FiltrosCapturador.png (5.07 KiB) Visto 19430 veces
¡Pero no lo puedo controlar!
En realidad eso sólo sirve para que el usuario vea los archivos con esas extensiones, pero puede escribir lo que quiera, cualquier otra extensión ¡o ninguna!.
Y cuando sale de FileSaveDialog encima ni sé qué filtro estaba seleccionado, así que no sé qué extensión tengo que poner...
Si no se os ocurre alguna super idea creo que esa lista en vez de usarla para los filtros la usaré para analizar la extensión que me pone el usuario:
- Si es una de las registradas la uso
- Si no lo es o no ha puesto ninguna añado un png.

¿Cómo lo veis?

(Por cierto como veis ya sé insertar imágenes en el foro, cuando vuelva de vacaciones arreglaré un poco los posts de los programas con alguna pantallita)
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Capturador

Mensaje por Chefito »

Hombre, si te fijas en los programas, cuando le das a la opción de "guardar como", verás que si no pones ninguna extensión, te pone la extensión seleccionada de la lista, y si ponen cualquier extensión, se guarda el archivo con esa extensión sea cual sea.

Ideas? Varias :smt002 . Puedes hacer una lista de las extensiones como muestras, y poner al archivo la extensión seleccionada (o la 1º de ellas si son varias). También puedes separar totalmente todas las extensiones de la lista aunque pertenezcan a un mismo grupo.
Por otro lado, puedes ver si el nombre del archivo que te ha puesto tiene extensión o no. Esto se puede hacer viendo si tiene un punto el nombre dado. Tienes que tener en cuenta que un nombre de archivo puede tener varios puntos. Recuerda que el último punto indicará la extensión. Esto lo puedes solucionar con un stringsplit($nombrefichero,"."), y ver si tiene más de un vector. Si tiene más de un vector, coge el último que será la extensión.
Una vez que tienes la extensión, ya puedes comparala con las extensiones que tienes en la lista. Si coincide con alguna, pues la dejas como está, si no coincide pues le pones la extenxión que esté seleccionada en la lista o alguna por defecto.

También puedes obligar al usuario a tener que poner siempre la extensión seleccionada de la lista. Pero igualmente tendrías que comparar el nombre puesto por si acaso le ha puesto esta extensión. Si coincide con la seleccionada, pues no haces nada, y si no, pues se la añades.

Que rollo no? :smt005 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

A ver si la semana que viene miro el programilla y arreglo ese problema.
Sí, la idea es la que comentas, que si hay extensión la use si tengo un coder para ella, si no hay coder o no hay extensión seleccionar el coder (y poner extensión) según el filtro que había seleccionado en el diálogo de guardar.

Y ahí estaba el problema, lo miré un poco rápido pero hasta donde he visto el FileSaveDialog no devuelve el filtro seleccionado, sólo el nombre de archivo...

Así rápido vi una extensión en el foro inglés para un FileSaveDialog super-personalizable, muy interesante pero demasiado pesado para lo que quiero, va a ocupar más la extensión esa que mi capturador entero, así que quiero buscar alternativas.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Capturador

Mensaje por Chefito »

Mmmmm. Mira, te dejo unas funciones que cogí del foro ingles (no recuerdo la dirección) que da una alternativa a las funciones FileOpenDialog y FileSaveDialog. Son muy personalizables.
Lo interesante de estas funciones es que puedes recoger sus eventos en una función. Gracias a esto puedes capturar el texto del combobox antes de que se cierre la ventana :smt002 .
Te dejo un ejemplo adaptado a lo que tu quieres.
Adapté la función que recogía los eventos para ese programa al que no le meto mano para cortar archivos :smt005 :smt005 :smt005 :smt005 . Te he adaptado algo los eventos a lo que tu quieres. Espero que tu la utilices.....porque lo que es yo parece que va para largo :smt005 :smt005 :smt005 .

Código: Seleccionar todo

#include <String.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

;~ already declared in WinAPI.au3
;~ Global Const $OFN_ALLOWMULTISELECT = 0x200
;~ Global Const $OFN_CREATEPROMPT = 0x2000
;~ Global Const $OFN_DONTADDTORECENT = 0x2000000
;~ Global Const $OFN_ENABLEHOOK = 0x20
;~ Global Const $OFN_ENABLEINCLUDENOTIFY = 0x400000
;~ Global Const $OFN_ENABLESIZING = 0x800000
;~ Global Const $OFN_ENABLETEMPLATE = 0x40
;~ Global Const $OFN_ENABLETEMPLATEHANDLE = 0x80
;~ Global Const $OFN_EXPLORER = 0x80000
;~ Global Const $OFN_EXTENSIONDIFFERENT = 0x400
;~ Global Const $OFN_EX_NOPLACESBAR = 0x1
;~ Global Const $OFN_FILEMUSTEXIST = 0x1000
;~ Global Const $OFN_FORCESHOWHIDDEN = 0x10000000
;~ Global Const $OFN_HIDEREADONLY = 0x4
;~ Global Const $OFN_LONGNAMES = 0x200000
;~ Global Const $OFN_NOCHANGEDIR = 0x8
;~ Global Const $OFN_NODEREFERENCELINKS = 0x100000
;~ Global Const $OFN_NOLONGNAMES = 0x40000
;~ Global Const $OFN_NONETWORKBUTTON = 0x20000
;~ Global Const $OFN_NOREADONLYRETURN = 0x8000
;~ Global Const $OFN_NOTESTFILECREATE = 0x10000
;~ Global Const $OFN_NOVALIDATE = 0x100
;~ Global Const $OFN_OVERWRITEPROMPT = 0x2
;~ Global Const $OFN_PATHMUSTEXIST = 0x800
;~ Global Const $OFN_READONLY = 0x1
;~ Global Const $OFN_SHAREAWARE = 0x4000
;~ Global Const $OFN_SHOWHELP = 0x10
Global Const $OFN_SHAREFALLTHROUGH = 2
Global Const $OFN_SHARENOWARN = 1
Global Const $OFN_SHAREWARN = 0
Global Const $OFN_USEMONIKERS = 0x1000000
Global Const $OFS_MAXPATHNAME = 128


Global Const $CDM_FIRST = 1124
Global Const $CDM_GETFILEPATH = $CDM_FIRST + 0x1
Global Const $CDM_GETFOLDERIDLIST = $CDM_FIRST + 0x3
Global Const $CDM_GETFOLDERPATH = $CDM_FIRST + 0x2
Global Const $CDM_GETSPEC = $CDM_FIRST + 0x0
Global Const $CDM_HIDECONTROL = $CDM_FIRST + 0x5
Global Const $CDM_SETCONTROLTEXT = $CDM_FIRST + 0x4
Global Const $CDM_SETDEFEXT = $CDM_FIRST + 0x6
Global Const $CDM_LAST = 1224

Global Const $CDN_FIRST = -601
Global Const $CDN_INITDONE = $CDN_FIRST - 0x0
Global Const $CDN_INCLUDEITEM = $CDN_FIRST - 0x7
Global Const $CDN_FOLDERCHANGE = $CDN_FIRST - 0x2
Global Const $CDN_HELP = $CDN_FIRST - 0x4
Global Const $CDN_SELCHANGE = $CDN_FIRST - 0x1
Global Const $CDN_TYPECHANGE = $CDN_FIRST - 0x6
Global Const $CDN_SHAREVIOLATION = $CDN_FIRST - 0x3
Global Const $CDN_FILEOK = $CDN_FIRST - 0x5
Global Const $CDN_LAST = -699

;;explorer style dialog control indentifiers
Global Const $chx1 = 0x410;The read-only check box
Global Const $cmb1 = 0x470;Drop-down combo box that displays the list of file type filters
Global Const $stc2 = 0x441;Label for the cmb1 combo box
Global Const $cmb2 = 0x471;Drop-down combo box that displays the current drive or folder, and that allows the user to select a drive or folder to open
Global Const $stc4 = 0x443;Label for the cmb2 combo box
Global Const $edt1 = 0x480;Edit control that displays the name of the current file, or allows the user to type the name of the file to open. Compare with cmb13.
Global Const $stc3 = 0x442;Label for the cmb13 combo box and the edt1 edit control
Global Const $lst1 = 0x460;List box that displays the contents of the current drive or folder
Global Const $stc1 = 0x440;Label for the lst1 list box
;~ Global Const $IDOK = 1;The OK command button (push button)
;~ Global Const $IDCANCEL = 2;The Cancel command button (push button)
Global Const $pshHelp = 0x040e;The Help command button (push button)

;; reverse-engineered command codes for SHELLDLL_DefView (Paul DiLascia, MSDN Magazine  March 2004)
Global Const $ODM_VIEW_ICONS = 0x7029
Global Const $ODM_VIEW_LIST = 0x702b
Global Const $ODM_VIEW_DETAIL = 0x702c
Global Const $ODM_VIEW_THUMBS = 0x702d
Global Const $ODM_VIEW_TILES = 0x702e

Global $HaGuardado=1
$Form1 = GUICreate("Form1", 466, 400, 193, 115)
Local $NomArchivo = _GetOpenSaveFileName('GetSaveFileName', "_FileOpen_HookProc", 0, "", $Form1, "Guardar archivo", @MyDocumentsDir & "\", "All Files (*.*)|Imagen (*.jpg)", BitOR($OFN_PATHMUSTEXIST, $OFN_ENABLEHOOK), "Imagen.jpg")


;#
;   _FileOpenDialogEx()
;           Initiates a customizable Open File Dialog.
;   Parameters:
;           $sTitle - dialog title, see FileOpenDialog()
;           $sInitDir - initial folder, see FileOpenDialog()
;           $sFilter - file type filter, see FileOpenDialog()
;           $iOptions - can be one or combination of the following:
;                       $OFN_FILEMUSTEXIST
;                       $OFN_PATHMUSTEXIST
;                       $OFN_ALLOWMULTISELECT
;                       $OFN_CREATEPROMPT
;                       $OFN_ENABLESIZING
;                       $OFN_DONTADDTORECENT
;                       $OFN_FORCESHOWHIDDEN
;                       $OFN_NONETWORKBUTTON
;                       $OFN_EX_NOPLACESBAR
;
;           $sDefaultName - default filename, see FileOpenDialog()
;           $hParent - handle of dialog's parent window (0 if none)
;           $sHookName - name of user defined dialog hook procedure ("" if none). See examples.
;           $hTemplate - handle to a file or memory object containing custom dialog template (0 if none). See examples.
;           $sTemplateName - name of a dialog template resource in the module identified by the $hTemplate ("" if none or if $hTemplate is memory object handle). See examples.
;   Return values:
;           Success: string value of chosen filename(s), see FileOpenDialog()
;           Failure: Sets @error to 1
;   Remarks:
;           Using hook function you can customize dialog to greater extent - hide/show controls, change text of controls, and do other neat things.
;           Hook function should have 4 params ($hWnd, $Msg, $wParam, $lParam) and works similar to GuiRegisterMsg() functions. For more information refer http://msdn2.microsoft.com/en-us/library/ms646960(VS.85).aspx
;           Using custom templates you can add controls to a common dialog. To handle these custom controls, use hook function.
;#
Func _FileOpenDialogEx($sTitle = "", $sInitDir = "", $sFilter = "All Files (*.*)", $iOptions = 0, $sDefaultName = "", $hParent=0, $sHookName="", $hTemplate=0, $sTemplateName="")

    Local $sRet = _GetOpenSaveFileName('GetOpenFileName', $sHookName, $hTemplate, $sTemplateName, $hParent, $sTitle, $sInitDir, $sFilter, $iOptions, $sDefaultName)
    If @error Then SetError(@error)
    Return $sRet

EndFunc


;###################################
;#
;   _GetOpenSaveFileName()
;           Internal
;#
Func _GetOpenSaveFileName($sFunction, $sHookProc, $hTemplate, $sTemplateName, $hParent, $sTitle, $sInitDir, $sFilter, $iOptions, $sDefaultName)
    Local $taFilters, $tFile, $_OFN_HookProc = 0, $iFlagsEx = 0, $iFlagsForced = BitOR($OFN_EXPLORER,$OFN_HIDEREADONLY,$OFN_NODEREFERENCELINKS)
    $iOptions = BitOR($iFlagsForced, $iOptions)
    If BitAND($iOptions, $OFN_EX_NOPLACESBAR) Then
        $iOptions = BitXOR($iOptions, $OFN_EX_NOPLACESBAR)
        $iFlagsEx = $OFN_EX_NOPLACESBAR
    EndIf
;Local $iBufferSize = 4095
    Local $aFilters = StringSplit($sFilter, "|"), $saFilters = "", $aFiltSplit, $i
    For $i = 1 To $aFilters[0]
        $aFiltSplit = StringRegExp($aFilters[$i], "(?U)\A\h*(.+)\h*\((.*)\)", 1)
        $saFilters &= $aFilters[$i] & Chr(0) & $aFiltSplit[1] & Chr(0)
    Next
    $taFilters = DllStructCreate("wchar[" & StringLen($saFilters)+3 & "]")
    DllStructSetData($taFilters, 1, $saFilters)
    Local $tagFileBuffer = "wchar[32768]", $iFileBufferSize = 32767
    $tFile = DllStructCreate($tagFileBuffer);Win2000/XP: should be 32k for ansi, unlimited for unicode
    If $sDefaultName <> "" Then DllStructSetData($tFile, 1, $sDefaultName)
    Local $tOFN = DllStructCreate('dword lStructSize;hwnd hwndOwner;hwnd hInstance;' & _
                                    'ptr lpstrFilter;ptr lpstrCustomFilter;dword nMaxCustFilter;dword nFilterIndex;' & _
                                    'ptr lpstrFile;dword nMaxFile;ptr lpstrFileTitle;dword nMaxFileTitle;ptr lpstrInitialDir;ptr lpstrTitle;' & _
                                    'dword Flags;short nFileOffset;short nFileExtension;ptr lpstrDefExt;dword lCustData;ptr lpfnHook;ptr lpTemplateName;' & _
                                    'dword Reserved[2];dword FlagsEx')
    DllStructSetData($tOFN, 'lStructSize', DllStructGetSize($tOFN))
    If IsHWnd($hParent) Then DllStructSetData($tOFN, 'hwndOwner', $hParent)
    DllStructSetData($tOFN, 'lpstrFilter', DllStructGetPtr($taFilters))
    DllStructSetData($tOFN, 'nFilterIndex', 1)
    DllStructSetData($tOFN, 'lpstrFile', DllStructGetPtr($tFile))
    DllStructSetData($tOFN, 'nMaxFile', $iFileBufferSize)
    DllStructSetData($tOFN, 'FlagsEx', $iFlagsEx)
    If $hTemplate <> 0 Then
        If $sTemplateName <> "" Then
            $iOptions = BitOr($iOptions, $OFN_ENABLETEMPLATE)
            DllStructSetData($tOFN, 'hInstance', $hTemplate)
            Local $tTemplateName = DllStructCreate("wchar[4096]")
            DllStructSetData($tTemplateName, 1, $sTemplateName)
            DllStructSetData($tOFN, 'lpTemplateName', DllStructGetPtr($tTemplateName))
        Else
            $iOptions = BitOr($iOptions, $OFN_ENABLETEMPLATEHANDLE)
            DllStructSetData($tOFN, 'hInstance', $hTemplate)
        EndIf
    EndIf
    If $sHookProc <> "" Then
        $iOptions = BitOr($iOptions, $OFN_ENABLEHOOK, $OFN_ENABLEINCLUDENOTIFY)
        $_OFN_HookProc = DllCallbackRegister($sHookProc, "int", "hwnd;uint;wparam;lparam")
        DllStructSetData($tOFN, 'lpfnHook', DllCallbackGetPtr($_OFN_HookProc))
    EndIf
    If $sTitle <> "" Then
        Local $tTitle = DllStructCreate("wchar[4096]")
        DllStructSetData($tTitle, 1, String($sTitle))
        DllStructSetData($tOFN, "lpstrTitle", DllStructGetPtr($tTitle))
    EndIf
    If $sInitDir <> "" Then
        Local $tInitDir = DllStructCreate("wchar[4096]")
        DllStructSetData($tInitDir, 1, String($sInitDir))
        DllStructSetData($tOFN, "lpstrInitialDir", DllStructGetPtr($tInitDir))
    EndIf
    DllStructSetData($tOFN, 'Flags', $iOptions)
    $sFunction &= 'W'
    Local $aRet = DllCall('comdlg32.dll','int',$sFunction, 'ptr',DllStructGetPtr($tOFN)), $iError = @error
    If $_OFN_HookProc <> 0 Then DllCallbackFree($_OFN_HookProc)
    If $iError Then
        Return SetError(2,$iError,"")
    ElseIf $aRet[0] Then
        Local $iChar = 1
        While $iChar < $iFileBufferSize+1
            If DllStructGetData($tFile, 1, $iChar) = "" Then
                If DllStructGetData($tFile, 1, $iChar+1) = "" Then ExitLoop
                DllStructSetData($tFile, 1, "|", $iChar)
            EndIf
            $iChar += 1
        WEnd
        Return SetError(0,0,DllStructGetData($tFile, 1))
    Else
        Return SetError(1,0,"")
    EndIf
EndFunc

Func _FileOpen_HookProc($hWnd, $Msg, $wParam, $lParam)
    #forceref $wParam, $lParam
	Select
		Case $Msg=2 And $HaGuardado		;pulsa botón cancelar o cerrar.
			MsgBox(0,"Ha cancelado",ControlGetText("Guardar archivo","","ComboBox3"))
		Case $Msg=49265		;Se ha cerrado la ventana
			$HaGuardado=0
			MsgBox(0,"Ventana cerrada","Se va ha cerrar la ventana después de guardar")
		Case $Msg=31		;pulsa botón guardar.
			MsgBox(0,"Ha guardado el fichero",ControlGetText("Guardar archivo","","ComboBox3"))
	EndSelect
EndFunc
Puedes quitar código que no se utiliza.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

¡¡GRACIAS!!

Ya lo creo que va a ser útil, eso sí, el código es complicadillo, usando el diálogo interno de Windows, con hooks, acceso directo a los controles...

Tengo que analizarlo con cuidado para dejar justo lo que necesito, pero esto es justo lo que me hacía falta. Es como la udf aquélla pero yendo al grano.

De lo que tengo un poco de miedo es que al acceder tan directamente a las entrañas del diálogo original, se creen incompatibilidades. Por ejemplo al coger el combo de filtros pues muy bien, en ese diálogo de XP es ComboBox3 (o identificador 0x470). Pero si modifican aunque sea mínimamente el diálogo para Vista, Windows7, etc, probablemente esas referencias cambiarán.
Lo ideal sería que el propio diálogo tenga una API que devuelva esos valores, entonces aunque cambien el diálogo supongo que los de Windows mantendrían la API, ¿no existe algo así?

Necesito más información con _FileOpen_HookProc, que veo que es donde voy a meter más mano.
Parece como un gestor de eventos del diálogo ¿Cómo veo los mensajes y parámetros disponibles? ¿quizás por la MSDN?

Gracias otra vez... ¡ah, y ánimo con el Splitter, seguro que será una obra maestra!
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

Veo en la MSDN sobre GetOpenFileName,
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

"Note Starting with Windows Vista, the Common File Dialog has been superseded by the Common Item Dialog when used to open a file. We recommended that you use the Common Item Dialog API instead of the Common File Dialog API in this case. For more information, please see Common Item Dialog."

O sea...
Nota Comenzando con Windows Vista, el Common File Dialog ha sido reemplazado por Common Item Dialog cuando se usa para abrir un archivo. Recomendamos que use la API de Common Item Dialog en vez la de Common File Dialog en este caso. Para más información...

Bueno, aunque habla de open/abrir, el diálogo es el mismo para guardar, pues realmente es un selector de nombres de archivo, no abre ni guarda nada.

También dice que con un par de flags se utiliza el estilo antiguo, el del Common File Dialog, lo que ahí no queda claro si es que también lo tiene y lo usa tal cual (entonces no habrá problemas) o es el nuevo Common Item Dialog disfrazado del antiguo (con lo que sí puede haber problemas si se acceden a los controles internos directamente...)

He leído por el foro inglés (no he copiado la ruta y ahora resulta que están de mantenimiento...) que pedían que FileOpenDialog, FileSelectFolder y FileSaveDialog dieran más información al finalizar, como el tema del filtro seleccionado. Creo que era Valik el que contestaba y estaba de acuerdo en incluir en @extended información extra, pero claro, eso será para futuras versiones de AutoIt...

EDITADO:
Ya está activo el foro inglés. En esta entrada:
http://www.autoitscript.com/forum/index ... opic=43973
discuten el tema, dan una solución usando el modelo que nos ha pasado Chefito, y más abajo es cuando entra Valik en la discusión proponiendo un par de soluciones a implementar en el futuro... El caso es que el post está cerrado, el último comentario es de marzo de 2008, la última versión de AutoIT (no beta) es de diciembre de 2008... ¡y sigue igual!

¿Alguien trabaja con la versión beta de AutoIt? ¿hay cambios en estas funciones? lo que no sé es si las versiones beta vienen con la ayuda actualizada, si no es así a ver cómo averiguas si ha cambiado y cómo...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Capturador

Mensaje por Chefito »

De nada.
Es muy interesante el enlace que has puesto del foro de habla inglesa. Dan más o menos la solución que te dí yo pero aun más al grano.
La verdad, no investigé mucho esto, ya que como te dije lo tenía a mano. Lo único que hice es mirar los mensajes que enviaba esta ventana y los adapté a lo que tú querías. Los cogí directamente, en formato decimal. No investigé si se activaba algún bit determinado según la acción ni nada (si quieres hazlo tú). Miré muy muy por encima las estructuras de datos que tiene autoit a ver si alguna podía servir para este tipo de ventanas, pero en un principio no vi nada. Puede que haya alguna por ahí :smt017 .

Respecto a lo de la nueva ventana del vista, no tenía ni idea. Pero seguro que no funciona la de siempre? Es que no puedo probarlo porque solo tengo el xp. Muy interesante el enlace de ms sobre este tema.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

Pues en ese post Valik comenta algo muy interesante (que ya podía haber implementado en AutoIt): el caso es que si en el diálogo pones como extensión por defecto una cadena vacía, automáticamente éste pone la del filtro activo si el usuario no pone ninguna, justo lo que quiero.

Desgraciadamente ese parámetro de extensión por defecto no está en FileSaveDialog, que me pregunto, ¿qué diablos habrá puesto para que la extensión quede vacía? si pone una extensión pondría la extensión, si la pone vacía pondría la del filtro y no lo hace... quizás el famoso puntero nulo...

Afortunadamente no hace falta lidiar con la función de la dll, ¡resulta que en WinAPI.au3 tenemos _WinAPI_GetSaveFileName, que facilita mucho el acceso a GetSaveFileName en comdlg32.dll, y permite entre otras cosas poner esa extensión por defecto.

Así que eso será lo que voy a usar...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
tander
Mensajes: 7
Registrado: 12 Mar 2010, 04:05

Re: Capturador

Mensaje por tander »

Dios mio, me encantan tus aplicaciones. Son muy interesantes y útiles. Te felicito y te admiro! :smt038
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

¡Vaya gracias!

Hice una pequeña mejora en el diálogo de guardar, para que use PNG como extensión por defecto, y que además deje guardar en otros formatos registrados en Windows (BMP, JPG, etc.). Al final me ha tocado pasar del FileSaveDialog de AutoIt y usar directamente la API, junto con algo de ayuda de GDI+ para obtener info de los coders...

A ver si la pongo hoy o mañana.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Capturador

Mensaje por Ximorro »

Nueva versión disponible, más detalles en la entrada principal.

Saludos.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
rgracia
Mensajes: 18
Registrado: 28 Jun 2012, 09:06

Re: Capturador

Mensaje por rgracia »

Hola,

La App está dabuten!

Pero como has hecho para pasar la imagen al portapapeles?
Responder