[SOLUCIONADO] Mover la selección en mi combobox
[SOLUCIONADO] Mover la selección en mi combobox
Buenos días,
He estado mirando la ayuda y varios foros pero no encuentro la instrucción para lo que quiero hacer, os explico. Tengo mi GUI y quisiera que una vez se inicia una función, modificara la opción seleccionada en el Combobox de mi GUI.
Gracias!!
He estado mirando la ayuda y varios foros pero no encuentro la instrucción para lo que quiero hacer, os explico. Tengo mi GUI y quisiera que una vez se inicia una función, modificara la opción seleccionada en el Combobox de mi GUI.
Gracias!!
Última edición por mitchito el 21 Mar 2012, 13:54, editado 1 vez en total.
- Ximorro
- Profesional del Autoit
- Mensajes: 1500
- Registrado: 10 Jul 2009, 12:35
- Ubicación: Castellón, España
Re: Mover la selección en mi combobox
No es por nada pero un poco de código siempre viene bien para tener algo con lo que empezar...
Bueno se me ocurren tres o cuatro maneras, dependiendo de lo que te interese.
Con las funciones básicas de AutoIt se puede establecer el valor por defecto del combo, que puedes cambiar cuando quieras. Desgraciadamente no sé cómo hacerlo sin redefinir el contenido de los items, así que no me gusta mucho, a menos que sean combos de pocos datos fijos.
Se haría:
En este caso cuando lo creo pongo por defecto "item3", más adelante en otro punto del programa lo cambio a "item1". Como ves el problema es que el segundo parámetro de GuiCtrlSetData es obligatorio, así que tengo que poner otra vez los items. Para simplificarlo los tengo en la variable $items, aún así no me gusta mucho esta solución. Si alguien sabe cómo utilizar GuiCtrlSetData en un combo para cambiar el valor por defecto sin redefinir los items que lo diga. En ese caso sí sería bastante interesante este método.
Las otras maneras se hacen mandando mensajes windows al combo. También es con las funciones básicas de AutoIt, pero es con la genérica GUICtrlSendMsg. Afortunadamente tenemos los valores de los mensajes ya definidos en la udf ComboConstants.au3.
Una manera es por posición, cambiando al índice correspondiente, empezando a contar desde cero. Es el mensaje CB_SETCURSEL, así que se hace así:
GUICtrlSendMsg($comb, $CB_SETCURSEL, $indice, 0)
$indice puede valer desde 0 hasta el número de items menos 1.
El último parámetro (lParam) no se usa en este mensaje, pero no es opcional para la función así que lo pongo a cero.
Con ese mensaje te colocas por posición, pero también puedes buscar por contenido, eso se hace con el mensaje CB_SELECTSTRING:
GUICtrlSendMsg($comb, $CB_SELECTSTRING, $indice, $cadena)
En este caso $indice indica desde qué posición se empieza a buscar, se usa -1 para buscar en todo el combo. En $cadena pones el texto a buscar (busca subcadenas pero sólo desde el principio del item.
Te pongo un ejemplo en el que uso estos dos métodos. También está comentado el equivalente a CB_SELECTSTRING con GUICtrlSetData.
Por último decir que hay una udf para trabajar con combos, GuiComboBox.au3, que tiene estas cosas y muchas más. Si vas a manejar el combo de maneras más complicadas te será muy útil. Si sólo vas a hacer lo de seleccionar el item yo no sobrecargaría el programa con esta udf tan completa, siendo que el problema se soluciona en una línea (el envío del mensaje). En cualquier caso aunque no uses la udf se puede aprender mucho de ella, por ejemplo veo que ellos hacen también esto con los mensajes, aunque curiosamente en vez de usar GUICtrlSendMsg hacen una llamada directamente a SendMessageW en user32.dll, complicación que se podrían haber ahorrado usando el soporte nativo en AutoIT, pero bueno, el resultado es el mismo.
Bueno se me ocurren tres o cuatro maneras, dependiendo de lo que te interese.
Con las funciones básicas de AutoIt se puede establecer el valor por defecto del combo, que puedes cambiar cuando quieras. Desgraciadamente no sé cómo hacerlo sin redefinir el contenido de los items, así que no me gusta mucho, a menos que sean combos de pocos datos fijos.
Se haría:
Código: Seleccionar todo
$items = "|item1|item2|item3"
$comb = GUICtrlCreateCombo("", 10, 10, 160)
GUICtrlSetData(-1, $items, "item3")
...
GUICtrlSetData($comb, $items, "item1")
Las otras maneras se hacen mandando mensajes windows al combo. También es con las funciones básicas de AutoIt, pero es con la genérica GUICtrlSendMsg. Afortunadamente tenemos los valores de los mensajes ya definidos en la udf ComboConstants.au3.
Una manera es por posición, cambiando al índice correspondiente, empezando a contar desde cero. Es el mensaje CB_SETCURSEL, así que se hace así:
GUICtrlSendMsg($comb, $CB_SETCURSEL, $indice, 0)
$indice puede valer desde 0 hasta el número de items menos 1.
El último parámetro (lParam) no se usa en este mensaje, pero no es opcional para la función así que lo pongo a cero.
Con ese mensaje te colocas por posición, pero también puedes buscar por contenido, eso se hace con el mensaje CB_SELECTSTRING:
GUICtrlSendMsg($comb, $CB_SELECTSTRING, $indice, $cadena)
En este caso $indice indica desde qué posición se empieza a buscar, se usa -1 para buscar en todo el combo. En $cadena pones el texto a buscar (busca subcadenas pero sólo desde el principio del item.
Te pongo un ejemplo en el que uso estos dos métodos. También está comentado el equivalente a CB_SELECTSTRING con GUICtrlSetData.
Código: Seleccionar todo
#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
Global $items, $msg, $comb, $bot1, $bot2
GUICreate("GUI combo", 180, 110)
$items = "|item1|item2|item3"
$comb = GUICtrlCreateCombo("", 10, 10, 160)
GUICtrlSetData(-1, $items, "item3")
$bot1 = GuiCtrlCreateButton('Selecciona "item1"', 10, 40)
$bot2 = GuiCtrlCreateButton("Selecciona segundo elemento", 10, 70)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
case $GUI_EVENT_CLOSE
ExitLoop
case $bot1
;GUICtrlSetData($comb, $items, "item1")
GUICtrlSendMsg($comb, $CB_SELECTSTRING, -1, "item1") ; Selecciona por texto
case $bot2
GUICtrlSendMsg($comb, $CB_SETCURSEL, 1, 0) ; Selecciona por posición (0 = primer elemento)
EndSwitch
WEnd
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Re: Mover la selección en mi combobox
Muchas gracias!! He utilizado la segunda opción y va perfecto!
GUICtrlSendMsg($combo, $CB_SETCURSEL, $indice, 0)
GUICtrlSendMsg($combo, $CB_SETCURSEL, $indice, 0)
- Ximorro
- Profesional del Autoit
- Mensajes: 1500
- Registrado: 10 Jul 2009, 12:35
- Ubicación: Castellón, España
Re: [SOLUCIONADO] Mover la selección en mi combobox
Vaya, vaya, veo que "has solucionado" el problema. Unos créditos habrían sido de agradecer, y más aún teniendo en cuenta que no has puesto absolutamente nada de código tuyo, aunque ahí también te lo pedían...
http://www.autoitscript.com/forum/topic ... _p__972848
Al menos les podías haber traducido los textos del programa a inglés...
http://www.autoitscript.com/forum/topic ... _p__972848
Al menos les podías haber traducido los textos del programa a inglés...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
- Chefito
- Profesional del Autoit
- Mensajes: 2035
- Registrado: 21 Feb 2008, 18:42
- Ubicación: Albacete/Cuenca (España)
Re: [SOLUCIONADO] Mover la selección en mi combobox
Mmmmm.....muy mal por parte de mitchito el no añadir créditos a los código que muestras, haciendo creer que lo has hecho tú .
Por culpa de estas cosas no dan ganas de ayudar a usuarios con comportamientos como estos .
Contestando a Ximorro:
Saludos.
Por culpa de estas cosas no dan ganas de ayudar a usuarios con comportamientos como estos .
Contestando a Ximorro:
Simplemente poniendo el texto del item como segundo parámetro. No se añade, se situa. Y no me preguntes por qué. Se comporta así y punto .Ximorro escribió: Si alguien sabe cómo utilizar GuiCtrlSetData en un combo para cambiar el valor por defecto sin redefinir los items que lo diga. En ese caso sí sería bastante interesante este método.
Código: Seleccionar todo
#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
Global $items, $msg, $comb, $bot1, $bot2
GUICreate("GUI combo", 180, 110)
$items = "|item1|item2|item3"
$comb = GUICtrlCreateCombo("", 10, 10, 160)
GUICtrlSetData(-1, $items, "item3")
$bot1 = GuiCtrlCreateButton('Selecciona "item1"', 10, 40)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
case $GUI_EVENT_CLOSE
ExitLoop
case $bot1
GUICtrlSetData($comb, "item1") ; Selecciona por texto
EndSwitch
WEnd
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 ;).
- Ximorro
- Profesional del Autoit
- Mensajes: 1500
- Registrado: 10 Jul 2009, 12:35
- Ubicación: Castellón, España
Re: [SOLUCIONADO] Mover la selección en mi combobox
Voy a intentar ser bien pensado y como no ha dicho expresamente que la solución es suya, sólo que "He solucionado mi problema" y "La solución que he usado".
En fin, habría sido mejor "Mi problema ha sido solucionado", pero bueno.
Verás mitchito, no es necesario dar créditos por cualquier cosa, si te hubiera contestado en una línea diciendo "Usa GUICtrlSendMsg con CB_SETCURSEL" pues vale, pero lo que me fastidia un poco es que como verás la respuesta era bastante extensa, aunque no lo creas me llevó mi tiempo escribirla, y encima me tocó hacer el código desde cero porque ni siquiera ofreciste un GUI sobre el que trabajar. Y no me molesté en dar la primera solución que se me ocurrió, sino que como no me satisfacía mucho busqué otras y te las puse. Creo que ese esfuerzo requiere algo de reconocimiento cuando en otro foro haces la misma consulta y dices "He solucionado el problema". Por cierto, allí también te han pedido algo de código... tuyo.
¡Chefito, lo encontraste! Pues hubiera imaginado que eso redefinía el combo con sólo ese item, pero no, hace lo que queremos ¡interesante!
Pues entonces creo que esta es la solución más natural. Para ir por índice sí será mejor el de mensajes pero por texto este es más "tipo AutoIt"
Nota, para redefinir el combo con un sólo elemento habrá que usar el separador:
GUICtrlSetData($comb, "|item2")
Por cierto, que hay otra solución (es lo que estaba buscando cuando me encontré el post de mitchito en el otro foro, que no es que lo estuviera siguiendo, es que estaba investigando lo de los combos porque casualmente después me hizo falta para otra cosa, aunque algo más compleja).
Mi caso es algo más complicado porque quiero controlar el combo de una aplicación externa, en realidad el diálogo de imprimir de windows, donde seleccionas impresora.
Al no tratarse de mi código AutoIt no funciona GUICtrlSetData ni directamente GUICtrlSendMsg.
Sí se pueden enviar mensajes usando directamente SendMessage en user32.dll, como hacen en la UDF, ¡pero no funciona bien!. Resulta que sí selecciona el elemento en el combo, pero falta alguna notificación porque el formulario no se entera, al dar al botón de aceptar no se cambia la impresora, y de hecho dentro del formulario cuando seleccionas una impresora cambian algunas etiquetas informativas, pues mandando el mensaje el item se selecciona pero ni cambian esas etiquetas ¿? ¿?
Así que he encontrado otra solución, hay una función un poco rara porque es un cajón de sastre, tiene algunas cosas genéricas y otras específicas para combos, listas, edits, tabs, etc.
Se trata de ControlCommand.
En concreto podemos seleccionar por texto en un combo con:
ControlCommand($VentConfig, "", $hcombo, "SelectString", $imprNombre)
siendo $VentConfig el handle de mi ventana de configuración de impresoras y $hcombo el handle del combo. $imprNombre es el texto con el nombre de la impresora que quiero seleccionar.
Eso debería ser totalmente equivalente a:
_SendMessage($hcombo, $CB_SELECTSTRING, -1, $imprNombre, 0, "wparam", "wstr")
La función _SendMessage está en SendMessage.au3 y usa la dll antes comentada.
Pero no van igual, porque con ControlCommand además de seleccionar el item lo notifica, y las etiquetas cambian como toca, y lo que es más importante: al aceptar el diálogo selecciona la impresora.
La diferencia es que con _SendMessage recojo el índice donde encuentra el item, y me da -1 si no lo encuentra. ControlCommand no retorna el índice, pero al menos con @error sabemos si ha encontrado el texto.
¿Por qué no irá el mensaje?... raro raro. Pero al menos con ControlCommand lo he solucionado, esta es otra solución para mitchito, pues también funciona en un GUI propio, de todas maneras ahora la mejor solución para GUI propio creo que es GUICtrlSetData.
Para combos externos a la aplicación podéis probar _SendMessage, aunque ojo que en mi viejo XP en ese diálogo ya veis que no va del todo bien. Así que también tenemos ControlCommand con el comando "SelectString" que tiene toda la pinta de estar enviando el mensaje CB_SELECTSTRING, pero bueno.
Con ControlCommand también podemos seleccionar por índice con el comando "SetCurrentSelection", que sospecho está enviando el mensaje
CB_SETCURSEL, así que no sé por qué no funcionará bien enviar directamente el mensaje, debe faltar algo que notifique al formulario...
En fin, habría sido mejor "Mi problema ha sido solucionado", pero bueno.
Verás mitchito, no es necesario dar créditos por cualquier cosa, si te hubiera contestado en una línea diciendo "Usa GUICtrlSendMsg con CB_SETCURSEL" pues vale, pero lo que me fastidia un poco es que como verás la respuesta era bastante extensa, aunque no lo creas me llevó mi tiempo escribirla, y encima me tocó hacer el código desde cero porque ni siquiera ofreciste un GUI sobre el que trabajar. Y no me molesté en dar la primera solución que se me ocurrió, sino que como no me satisfacía mucho busqué otras y te las puse. Creo que ese esfuerzo requiere algo de reconocimiento cuando en otro foro haces la misma consulta y dices "He solucionado el problema". Por cierto, allí también te han pedido algo de código... tuyo.
¡Chefito, lo encontraste! Pues hubiera imaginado que eso redefinía el combo con sólo ese item, pero no, hace lo que queremos ¡interesante!
Pues entonces creo que esta es la solución más natural. Para ir por índice sí será mejor el de mensajes pero por texto este es más "tipo AutoIt"
Nota, para redefinir el combo con un sólo elemento habrá que usar el separador:
GUICtrlSetData($comb, "|item2")
Por cierto, que hay otra solución (es lo que estaba buscando cuando me encontré el post de mitchito en el otro foro, que no es que lo estuviera siguiendo, es que estaba investigando lo de los combos porque casualmente después me hizo falta para otra cosa, aunque algo más compleja).
Mi caso es algo más complicado porque quiero controlar el combo de una aplicación externa, en realidad el diálogo de imprimir de windows, donde seleccionas impresora.
Al no tratarse de mi código AutoIt no funciona GUICtrlSetData ni directamente GUICtrlSendMsg.
Sí se pueden enviar mensajes usando directamente SendMessage en user32.dll, como hacen en la UDF, ¡pero no funciona bien!. Resulta que sí selecciona el elemento en el combo, pero falta alguna notificación porque el formulario no se entera, al dar al botón de aceptar no se cambia la impresora, y de hecho dentro del formulario cuando seleccionas una impresora cambian algunas etiquetas informativas, pues mandando el mensaje el item se selecciona pero ni cambian esas etiquetas ¿? ¿?
Así que he encontrado otra solución, hay una función un poco rara porque es un cajón de sastre, tiene algunas cosas genéricas y otras específicas para combos, listas, edits, tabs, etc.
Se trata de ControlCommand.
En concreto podemos seleccionar por texto en un combo con:
ControlCommand($VentConfig, "", $hcombo, "SelectString", $imprNombre)
siendo $VentConfig el handle de mi ventana de configuración de impresoras y $hcombo el handle del combo. $imprNombre es el texto con el nombre de la impresora que quiero seleccionar.
Eso debería ser totalmente equivalente a:
_SendMessage($hcombo, $CB_SELECTSTRING, -1, $imprNombre, 0, "wparam", "wstr")
La función _SendMessage está en SendMessage.au3 y usa la dll antes comentada.
Pero no van igual, porque con ControlCommand además de seleccionar el item lo notifica, y las etiquetas cambian como toca, y lo que es más importante: al aceptar el diálogo selecciona la impresora.
La diferencia es que con _SendMessage recojo el índice donde encuentra el item, y me da -1 si no lo encuentra. ControlCommand no retorna el índice, pero al menos con @error sabemos si ha encontrado el texto.
¿Por qué no irá el mensaje?... raro raro. Pero al menos con ControlCommand lo he solucionado, esta es otra solución para mitchito, pues también funciona en un GUI propio, de todas maneras ahora la mejor solución para GUI propio creo que es GUICtrlSetData.
Para combos externos a la aplicación podéis probar _SendMessage, aunque ojo que en mi viejo XP en ese diálogo ya veis que no va del todo bien. Así que también tenemos ControlCommand con el comando "SelectString" que tiene toda la pinta de estar enviando el mensaje CB_SELECTSTRING, pero bueno.
Con ControlCommand también podemos seleccionar por índice con el comando "SetCurrentSelection", que sospecho está enviando el mensaje
CB_SETCURSEL, así que no sé por qué no funcionará bien enviar directamente el mensaje, debe faltar algo que notifique al formulario...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)