ACTUALIZAR COMBO CON UNIDADES

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Responder
Avatar de Usuario
yasmany
Hacker del Foro
Mensajes: 249
Registrado: 06 Sep 2011, 21:30

ACTUALIZAR COMBO CON UNIDADES

Mensaje por yasmany »

Buenas tardes a todos,
He realizado una ventanita con un comboBox y un boton salir, en el combo se muestran todas las unidades extraibles disponibles
Pero no resulta que no se como hacer para que se auto actualice el combo, eliminando de la lista los dispositivos no disponibles y poniendo los nuevos dispositivos introducidos pero manteniendo el item actual seleccionado.

Código: Seleccionar todo

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=icono.ico
#AutoIt3Wrapper_Outfile=Avy.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Comment=Software gratuito [email protected]
#AutoIt3Wrapper_Res_Description=Avy
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Yasmany Curimilma
#AutoIt3Wrapper_Res_Language=1034
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#NoTrayIcon
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GuiConstantsEx.au3>
#include <EditConstants.au3>
#include <GuiButton.au3>
#include <Misc.au3>
#include <GUIListBox.au3>
#include <StaticConstants.au3>
#include <ListviewConstants.au3>

_Singleton("AVY1991") ; NO REPETIR INSTANCIA DE EJECUCION junto con  #include <Misc.au3>
Global $btnDesinfectar, $unidad, $ed

; GUI
$interfaz = GUICreate("Avy", 250, 140, -1, -1, -1, $ws_ex_acceptfiles)
;BOTONES
$btnSalir = GUICtrlCreateButton("&Salir", 95, 100, 60, 25)
GUICtrlSetTip(-1, "Cerrar programa")


$cbUnidades = GUICtrlCreateCombo("BUSCAR UNIDAD...", 25, 30, 193, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $CBS_UPPERCASE))
obtenerUnidades()
GUICtrlSetState($cbUnidades, $GUI_FOCUS)
;*******************************************************************************************
;ESTADO DE LA GUI
GUISetState(@SW_SHOW)

;CASOS
While 1
	$nMsg = GUIGetMsg()
	Actualizar(); lo llamo para que se me ejecute, pero me parpadea demaciado
	Switch $nMsg

		Case $GUI_EVENT_CLOSE

			If $nMsg = $GUI_EVENT_CLOSE Then
				Exit
			EndIf
		Case $btnSalir
			Exit

	EndSwitch

WEnd

Func Actualizar()
	$res = GUICtrlRead($cbUnidades)
	GUICtrlSetData($cbUnidades, $res)
	obtenerUnidades();
	GUICtrlSetData($cbUnidades, "BUSCAR UNIDAD...")
EndFunc   ;==>Actualizar

Func obtenerUnidades()
	$res = GUICtrlRead($cbUnidades)
	GUICtrlSetData($cbUnidades, $res)
	;esta función nos recorre todos los dispositivos conectados al pc
	$var = DriveGetDrive("removable"); se alamcenan en est variable
	If Not @error Then ; si no hay error continuamos
		For $i = 1 To $var[0]
;~ 			GUICtrlSetData($cbUnidades, DriveGetLabel($var[$i]) & "(" & $var[$i] & ")" & "Tipo: " & DriveGetType($var[$i])) ;lo he omitido
			;meto un for, es decir un bucle que irá desde el valor 0 hasta $var[0], que es el número max de dispositivos que hay
			;si suponemos que tenemos un total de 10 dispositivos, $var[0] valdrá 10
			If DriveStatus($var[$i]) <> "READY" Then ; soluciona  el error, si el dispositivo no está listo, no lo muestra, así se acelera todo
			Else
				GUICtrlSetData($cbUnidades, DriveGetLabel($var[$i]) & " (" & $var[$i] & ")")
			EndIf
		Next
	EndIf
EndFunc   ;==>obtenerUnidades

Func valordefinido()
	$contenidocombo1 = StringReplace(GUICtrlRead($cbUnidades), " (", "<unidad>")
	$contenidocombo = StringReplace($contenidocombo1, ")", "</unidad>")
	$unidad1 = StringRegExp($contenidocombo, "<(?i)unidad>(.*?)</(?i)unidad>", 1, 1)
	$unidad = $unidad1[0]

EndFunc   ;==>valordefinido
Espero su pronta respuesta
Obra de modo que merezcas a tu propio juicio y a juicio de los demás la eternidad, que te hagas insustituible que no merezcas morir.
https://www.facebook.com/yasmanycurimilma
Avatar de Usuario
yasmany
Hacker del Foro
Mensajes: 249
Registrado: 06 Sep 2011, 21:30

Re: ACTUALIZAR COMBO CON UNIDADES

Mensaje por yasmany »

AYUDAAAAAAAA!!! Por fa :smt022
Quisiera q alguien me ayude
Obra de modo que merezcas a tu propio juicio y a juicio de los demás la eternidad, que te hagas insustituible que no merezcas morir.
https://www.facebook.com/yasmanycurimilma
Avatar de Usuario
juantxo
Hacker del Foro
Mensajes: 78
Registrado: 02 Abr 2008, 13:36

Re: ACTUALIZAR COMBO CON UNIDADES

Mensaje por juantxo »

A ver si esto te sirve...

Es algo sencillo, y seguro que hay otras formas pero esta al menos funciona.
He intentado marcar todos los cambios que he realizado con una marca de comentario y varios 'asteristicos' :-)

Código: Seleccionar todo

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=icono.ico
#AutoIt3Wrapper_Outfile=Avy.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Comment=Software gratuito [email protected]
#AutoIt3Wrapper_Res_Description=Avy
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Yasmany Curimilma
#AutoIt3Wrapper_Res_Language=1034
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#NoTrayIcon
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GuiConstantsEx.au3>
#include <EditConstants.au3>
#include <GuiButton.au3>
#include <Misc.au3>
#include <GUIListBox.au3>
#include <StaticConstants.au3>
#include <ListviewConstants.au3>


_Singleton("AVY1991") ; NO REPETIR INSTANCIA DE EJECUCION junto con  #include <Misc.au3>
Global $btnDesinfectar, $unidad, $ed

; GUI
$interfaz = GUICreate("Avy", 250, 140, -1, -1, -1, $ws_ex_acceptfiles)
;BOTONES
$btnSalir = GUICtrlCreateButton("&Salir", 95, 100, 60, 25)
GUICtrlSetTip(-1, "Cerrar programa")


$cbUnidades = GUICtrlCreateCombo("BUSCAR UNIDAD...", 25, 30, 193, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $CBS_UPPERCASE))
obtenerUnidades()
GUICtrlSetState($cbUnidades, $GUI_FOCUS)
;*******************************************************************************************
;ESTADO DE LA GUI
GUISetState(@SW_SHOW)
AdlibRegister("Actualizar", 3000) ; *********************** Llamo a la funcion cada 3 sg. Ajustar tiempo pero no dejarlo demasiado bajo para evitar parpadeo.


;CASOS
While 1
	$nMsg = GUIGetMsg()
;~        Actualizar(); lo llamo para que se me ejecute, pero me parpadea demaciado ;************************ Lo inhablito aqui.
	Switch $nMsg

		Case $GUI_EVENT_CLOSE

			If $nMsg = $GUI_EVENT_CLOSE Then
				Exit
			EndIf
		Case $btnSalir
			Exit

	EndSwitch

WEnd
AdlibUnRegister("Actualizar"); *********************** Quito la llamada a la funcion de actualizacion.

Func Actualizar()
	$res = GUICtrlRead($cbUnidades)
	GUICtrlSetData($cbUnidades, $res)
	obtenerUnidades()
	; ********************************************** Quito de aqui la actualizacion del combo.
EndFunc   ;==>Actualizar

Func obtenerUnidades()
	$res = GUICtrlRead($cbUnidades)
;~ 	GUICtrlSetData($cbUnidades, $res)  ; ********************************************* No es necesario aqui.
	;esta función nos recorre todos los dispositivos conectados al pc
	$var = DriveGetDrive("removable"); se alamcenan en est variable
	$Existe = 0 ; ******************************************************************* Comprobamos que la unidad sigue existiendo....
	If Not @error Then ; si no hay error continuamos
;~ 		   GUICtrlSetData($cbUnidades, "BUSCAR UNIDAD...",$res)
		For $i = 1 To $var[0]
;~          GUICtrlSetData($cbUnidades, DriveGetLabel($var[$i]) & "(" & $var[$i] & ")" & "Tipo: " & DriveGetType($var[$i])) ;lo he omitido
			;meto un for, es decir un bucle que irá desde el valor 0 hasta $var[0], que es el número max de dispositivos que hay
			;si suponemos que tenemos un total de 10 dispositivos, $var[0] valdrá 10
			If DriveStatus($var[$i]) <> "READY" Then ; soluciona  el error, si el dispositivo no está listo, no lo muestra, así se acelera todo
			Else
				GUICtrlSetData($cbUnidades, DriveGetLabel($var[$i]) & " (" & StringUpper($var[$i]) & ")")
				If DriveGetLabel($var[$i]) & " (" & $var[$i] & ")" = $res Then $Existe = 1 ; **************************** Actualizamos la variable $Existe, si sigue activa la unidad.
			EndIf
		Next
		GUICtrlSetData($cbUnidades, "BUSCAR UNIDAD...")
		If $Existe = 1 Then GUICtrlSetData($cbUnidades, $res) ; ******************** Aqui indicamos el valor que tenia anteriormente, si existe.
	EndIf
EndFunc   ;==>obtenerUnidades

Func valordefinido()
	$contenidocombo1 = StringReplace(GUICtrlRead($cbUnidades), " (", "<unidad>")
	$contenidocombo = StringReplace($contenidocombo1, ")", "</unidad>")
	$unidad1 = StringRegExp($contenidocombo, "<(?i)unidad>(.*?)</(?i)unidad>", 1, 1)
	$unidad = $unidad1[0]

EndFunc   ;==>valordefinido
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: ACTUALIZAR COMBO CON UNIDADES

Mensaje por Chefito »

Hace tiempo estudié un poco los código para detectar los usbs. Por ejemplo, saqué este código del foro ingles que utiliza el evento OnDeviceChange. Te pongo el código de ejemplo que tengo por aquí.

Código: Seleccionar todo

Global Const $DBT_DEVICECOMPLETEREMOVAL = "0x00008004"
Dim $USB_ATTENTION = "0x00000007"

Global Const $DBT_DEVICEARRIVAL     = 0x00008000
Global Const $WM_DEVICECHANGE       = 0x0219
Global Const $tagDEV_BROADCAST_HDR  = "dword dbchsize;dword dbchdevicetype;dword dbchreserved"
Global Const $DBT_DEVTYP_VOLUME     = 0x00000002
Global Const $tagDEV_BROADCAST_VOLUME   = "dword dbcvsize;dword dbcvdevicetype;dword dbcvreserved;dword dbcvunitmask;short dbcvflags"
Global Const $DBTF_MEDIA            = 0x0001
Global Const $DBTF_NET              = 0x0002
;Setup The GUI to watch for the DeviceChange Event

GUICreate("Test")
GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange")

While 1
    Sleep (1000)
WEnd

Func DeviceChange($hWndGUI, $MsgID, $WParam, $LParam)
;~ 	ConsoleWrite($wparam)
    $iEvent = $WParam
    If $iEvent = $DBT_DEVICEARRIVAL Then
            $temp = DllStructCreate($tagDEV_BROADCAST_HDR, $LParam)
            $iDeviceType = DllStructGetData($temp, "dbchdevicetype")
            If $iDeviceType = $DBT_DEVTYP_VOLUME Then
                $struct = DllStructCreate($tagDEV_BROADCAST_VOLUME, $LParam)
                $iUnitMask = DllStructGetData($struct, "dbcvunitmask")
                $iFlags = DllStructGetData($struct, "dbcvflags")
                If Not BitAND($iFlags, $DBTF_MEDIA) And Not BitAND($iFlags, $DBTF_NET) Then
                    $sDrive = FirstDriveFromMask($iUnitMask)
                    ConsoleWrite($sDrive & ": was inserted!" & @CRLF)
                EndIf
            EndIf
    EndIf
EndFunc   ;==>DeviceChange

Func FirstDriveFromMask($unitmask)
    Local $i
    For $i = 0 To 25
        If BitAND($unitmask, 0x1) Then ExitLoop
        $unitmask = BitShift($unitmask, 1)
    Next
    Return Chr($i + Asc('A'))
EndFunc
Para entender algo mejor este código y todas las cosas que puedes hacer mira esta página: http://msdn.microsoft.com/es-es/library ... s.80).aspx

Recuerda de utilizar eventos es que no tienes que meterlo en un bucle e ir leyéndolo continuamente, detecta la acción cuando la haces.
Si quieres ver los códigos en hexadecimal que devuelve la función DeviceChange en cada acción que realizas, quita el comentario a la línea consolewrite.

Otro código utilizando WMI.

Código: Seleccionar todo

$DBT_DEVICEARRIVAL = "0x00008000"
$WM_DEVICECHANGE = 0x0219
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
 $colEvents = $objWMIService.ExecNotificationQuery _
    ("Select * From __InstanceOperationEvent Within 5 Where " _
        & "TargetInstance isa 'Win32_LogicalDisk'")

While 1
$objEvent = $colEvents.NextEvent
    If $objEvent.TargetInstance.DriveType = 2 Then
         Select
              Case $objEvent.Path_.Class()="__InstanceCreationEvent"
         Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been added." & @CR)
                     ;A Usb drive has been plugged in
              Case $objEvent.Path_.Class()="__InstanceDeletionEvent"
                     ConsoleWrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been removed."& @CR)
                     ;A usb drive has been removed
         EndSelect
     EndIf
Wend
Tengo algún ejemplo más, pero todos se basan en lo anterior.
A mi personalmente, la forma que más me gusta es la de por medio de eventos, ya que no necesitas depender del bucle.

Por cierto, paciencia con las respuesta, que estamos en verano y la gente está de vacaciones.

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
yasmany
Hacker del Foro
Mensajes: 249
Registrado: 06 Sep 2011, 21:30

Re: ACTUALIZAR COMBO CON UNIDADES

Mensaje por yasmany »

Gracias por vuestro tiempo Juantxo y Chefito
Lamentablemente :smt009 no me ha funcionado al 100% los codigos, pero intentaré :smt024 creando un boton
para actualizar el combo. :smt002, algo muy manual pero espero ESTAR conforme algun rato.
Zaludoz cordialez dezde Ecuador.
Obra de modo que merezcas a tu propio juicio y a juicio de los demás la eternidad, que te hagas insustituible que no merezcas morir.
https://www.facebook.com/yasmanycurimilma
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: ACTUALIZAR COMBO CON UNIDADES

Mensaje por Chefito »

Hombre, los códigos que yo te pasé había que depurarlos un poco, y más para hacer lo que tu querías.
Otra forma de hacerlo bastante buena es utilizando los eventos del control combobox. Mira la función _guictrlcombobox_create en la ayuda, y su ejemplo.
He utilizado este último código para que siempre que se despliege la lista se actualice las unidades.He metido el código de actualización de unidades en el evento $CBN_DROPDOWN. Puedes utilizar los demás eventos para realizar más cosas.

Código: Seleccionar todo

#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>

$Debug_CB = False ; Check ClassName being passed to ComboBox/ComboBoxEx functions, set to True and use a handle to another control to see it work

Global $hCombo

_Main()

Func _Main()
	Local $hGUI

	; Create GUI
	$hGUI = GUICreate("(UDF) ComboBox Create", 400, 296)
	$hCombo = _GUICtrlComboBox_Create($hGUI, "", 2, 2, 396, 296)
	GUISetState()

	; Add files
	_GUICtrlComboBox_BeginUpdate($hCombo)
	_GUICtrlComboBox_AddDir($hCombo, "", $DDL_DRIVES, False)
	_GUICtrlComboBox_EndUpdate($hCombo)

	GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

	; Loop until user exits
	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE
	GUIDelete()
EndFunc   ;==>_Main

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg
	Local $hWndFrom, $iIDFrom, $iCode
	$hWndFrom = $ilParam
	$iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
	$iCode = BitShift($iwParam, 16) ; Hi Word
	Switch $hWndFrom
		Case $hCombo
			Switch $iCode
				Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed
					_DebugPrint("$CBN_CLOSEUP" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box
					_DebugPrint("$CBN_DBLCLK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible
					_DebugPrint("$CBN_DROPDOWN" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
	; Add files
	_GUICtrlComboBox_ResetContent($hCombo)
	_GUICtrlComboBox_BeginUpdate($hCombo)
	_GUICtrlComboBox_AddDir($hCombo, "", $DDL_DRIVES, False)
	_GUICtrlComboBox_EndUpdate($hCombo)

					; no return value
				Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box
					_DebugPrint("$CBN_EDITCHANGE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text
					_DebugPrint("$CBN_EDITUPDATE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_ERRSPACE ; Sent when a combo box cannot allocate enough memory to meet a specific request
					_DebugPrint("$CBN_ERRSPACE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus
					_DebugPrint("$CBN_KILLFOCUS" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box
					_DebugPrint("$CBN_SELCHANGE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box
					_DebugPrint("$CBN_SELENDCANCEL" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list
					_DebugPrint("$CBN_SELENDOK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
				Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus
					_DebugPrint("$CBN_SETFOCUS" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
							"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
							"-->Code:" & @TAB & $iCode)
					; no return value
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func _DebugPrint($s_text, $line = @ScriptLineNumber)
	ConsoleWrite( _
			"!===========================================================" & @LF & _
			"+======================================================" & @LF & _
			"-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
			"+======================================================" & @LF)
EndFunc   ;==>_DebugPrint
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 ;).
Responder