_GUICtrlListView varias dudas

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

_GUICtrlListView varias dudas

Mensaje por Spra »

Tengo varias dudas con _GUICtrlListView
a) Cuando añado una columna con

Código: Seleccionar todo

_GUICtrlListView_AddColumn ($lista, "Nombres", 480, 2)
centra el texto en la columna y todos los items de esa columna aparacen centrados.
¿Hay alguna manera de que aparezca el texto de la columna centrado y el texto de los items a la izqda?
He estado probando también _GUICtrlListView_SetView con los diferentes flags, pero no logro el efecto antes citado.

b)Como se puede aplicar diferentes estilos de letra (Verdana, Comic Sans, etc.) ó formato (negrita, italica, etc.) en _GUICtrlListView

Código: Seleccionar todo

GUICtrlSetFont(-1, 9, 400, 2, "Verdana")
esto no me funciona.

Me imagino que deben ser preguntas muy básicas, pero le llevo dando vueltas un tiempo y no logro dar con la solucción.

Saludos.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

De básicas nada, en realidad es complicadillo.
No he conseguido hacerlo con el ListView básico de AutoIt, parece que poner la fuente a las líneas de GUICtrlCreateListViewItem no funciona.

Con el ListView de GuiListView.au3, que es el que usas, no es tan fácil, hay que usar directamente la API y ésta no es tan sencilla, cuando tienes que hacer cosas fuera de lo común las llamadas ya no son muy directas (hay que crear estructuras, hacer llamadas a DLL, mensajes...)
En fin, directamente con GuiListView.au3 no veo que se pueda hacer, pero en el foro inglés he encontrado una udf para dar formato a los items, como mínimo fuente y color, no sé lo de la justificación. Está aquí, hay un extenso ejemplo también:
http://www.autoitscript.com/forum/topic ... ntry731575

Aquí pantallazos del ejemplo:
http://www.autoitscript.com/forum/topic ... -and-font/
"¿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: _GUICtrlListView varias dudas

Mensaje por Ximorro »

Hum, he seguido investigando y he conseguido algo parcial. Desgraciadamente sólo funciona si la lista es estática, para mostrar cosas. Si el usuario puede manipularla toca rehacer el estilo cada vez.
El caso es que si cambias la justificación DESPUÉS de mostrar el control, es decir, después de GUISetState(@SW_SHOW), sólo se cambia la cabecera, el contenido se queda igual.
Para cambiar también el contenido hay que redibujar las celdas con _GUICtrlListView_RedrawItems, es lo que he dejado comentado en el código.

En este ejemplo he justificado las columnas al crearlas a la derecha (son números y queda mejor así), lo hago con _GUICtrlListView_SetColumn porque así aprovecho y las hago más anchas para que se note más la justificación.

Después de mostrar el formulario, y por lo tanto la lista, rejustifico centrando con _GUICtrlListView_JustifyColumn, pero si no hago un redibujo de celdas éstas quedan a la derecha como estaban.

El problema como digo es que cualquier otra cosa que fuerce el redibujado de las celdas las pondrá centradas... :-( No sé si habrá manera de fijarlas.

Código: Seleccionar todo

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>

Global $LINS = 5, $COLS = 4, $Data[$LINS][$COLS]
For $l = 0 To $LINS-1
    For $c = 0 To $COLS - 1
        $Data[$l][$c] = $c + $l*$COLS
    Next
Next

Global $hGUI = GUICreate("Lista", 400, 200)
Global $hLista = GUICtrlCreateListView("1|2|3|4", 20, 20, 370, 105, $LVS_SINGLESEL)
_GUICtrlListView_SetExtendedListViewStyle($hLista, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
_GUICtrlListView_SetColumn($hLista, 0, "Columna1", 90, 1)
_GUICtrlListView_SetColumn($hLista, 1, "Columna2", 90, 1)
_GUICtrlListView_SetColumn($hLista, 2, "Columna3", 90, 1)
_GUICtrlListView_SetColumn($hLista, 3, "Columna4", 90, 1)
_GUICtrlListView_AddArray($hLista, $Data)

GUISetState()

;Si se cambia después de mostrado sólo cambia la cabecera, a menos que se redibujen los items
For $i = 0 To $COLS - 1
	_GUICtrlListView_JustifyColumn($hLista, $i, 2)
Next
;_GUICtrlListView_RedrawItems($hLista, 0, _GUICtrlListView_GetItemCount($hLista) - 1)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Lista.PNG
Lista.PNG (3.54 KiB) Visto 5263 veces
Si la lista es puramente de lectura he encontrado en el foro inglés una udf para hacer tablas de lectura a base de labels. Es una currada inmensa, y los resultados son impresionantes. Si no tienes que manipular la lista te puede servir:
http://www.autoitscript.com/forum/topic ... table-udf/

Ojo al ejemplo, es MUY personalizable:
TablaLabels.jpg
TablaLabels.jpg (42.99 KiB) Visto 5263 veces
"¿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: _GUICtrlListView varias dudas

Mensaje por Ximorro »

Ya estoy aquí otra vez :smt003

Lo de antes no mola mucho, es muy fácil que se redibujen los items, con lo que se pierde la justificación diferenciada (por ejemplo minimizando el formulario, o si se puede seleccionar filas...)

He encontrado un ejemplo cambiando la fuente con la API, que es como he imaginado al principio que se haría pero que no parecía nada fácil. Efectivamente no era tan fácil averiguarlo pero al menos con el ejemplo es fácil seguir investigando. Fíjate que la fuente hay que hacerla con _WinAPI_CreateFont().
rover ha hecho una función para cambiar la font de un ListView en la que puedes poner una segunda fuente específica para la cabecera.
El ejemplo más actualizado está en el último comentario de este post:
http://www.autoitscript.com/forum/topic ... ew-create/
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

Ufff si que es complicado el tema.
Mis conocimientos de AutoIT son menos que básicos, la verdad lo único que deseaba hacer era centrar y poner en negrita el título de la columna, he estado ojeando los dos enlaces que has puesto al foro en inglés y me parece demasiado complicado, otra alternativa que he estado mirando es con el comando

Código: Seleccionar todo

_GUICtrlListView_SetView($hListView, 4)
que oculta la columna y con el comando

Código: Seleccionar todo

_GUICtrlHeader_Create 
crearla, pero mi sorpresa es que al ejecutar el script de ejemplo de la Ayuda UDFs aparecen signos como en chino, he probado de varias maneras y siempre pasa igual.
¿Se sabe a que es debido?
Ximorro muchas gracias por el esfuerzo pero si ya me cuesta con los comandos básicos, cuando hablas de manejar API´s entonces abandono :smt003

Saludos.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

¿Podrías poner el código que saca los chinos para que lo probemos?

Con la función de rover será fácil poner la cabecera en negrita. Piensa que tú utilizas su función, ya se encarga él de acceder directamente a la API. De hecho ya lo estás haciendo, las funciones de GuiListView.au3 si ves el código son todo accesos a la API.
Lo difícil con lo de rover es crear la fuente si quieres hacer cosas raras, pero para una definición sencilla no es complicado.
Por ejemplo siguiendo su ejemplo para los items bastaría hacer esta fuente:
$hFontItems = _WinAPI_CreateFont(15, 0, 0, 0, $FW_NORMAL)

Y para la cabecera en negrita simplemente se cambia el cuarto parámetro:
$hFontCabecera = _WinAPI_CreateFont(15, 0, 0, 0, $FW_BOLD)

El primer parámetro es el tamaño, pero creo que está en píxeles, no en puntos.
Si quieres cambiar el tipo de fuente resulta que es el último parámetro, y la llamada ciertamente asusta, pero simplemente ponemos a partir del cuarto parámetro todos los valores por defecto y sólo cambiamos el último:

Código: Seleccionar todo

_WinAPI_CreateFont(15, 0, 0, 0, $FW_NORMAL, , False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, _ 
                        $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, "Tahoma"))
Ese "Tahoma" del final es lo que hay que cambiar al nombre de la fuente, lo demás aunque no se entienda pues se deja por defecto y ya está.
Así que con tres parámetros cambiamos tamaño, negrita y fuente.

Eso sí, al cerrar el programa hay que liberar los recursos de Windows que hemos creado, eso se hace con DeleteObject de WinAPI:
_WinAPI_DeleteObject($hFontItems)
_WinAPI_DeleteObject($hFontCabecera)


Ah, lo del centrado ni idea, no encuentro manera. Que por cierto, con lo que comentas hay otra posibilidad: no poner la cabecera de la lista, y hacerla "a mano" poniendo etiquetas encima con el formato que quieras. Naturalmente en ese caso mejor que no se pueda redimensionar o mover columnas, porque entonces tendrás que mover las etiquetas para que estén siempre encima de sus columnas.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

jejeje justo estaba investigando en los enlaces que me has facilitado del foro inglés cuando has respondido, tengo que probarlo y ahora mismo no tengo tiempo, tengo que irme, pero creo que se puede hacer.

Primero centrar el texto de la columna con

Código: Seleccionar todo

_GUICtrlListView_AddColumn($hListView, "Column 1", 100, 2)
Segundo setear el texto de los items del Listview con

Código: Seleccionar todo

_GUICtrlListView_SetView($hListView, 4)
Tercero justo lo que has respondido crear dos fuentes con _WinAPI_CreateFont una para el ListView y otra para el Header.

En cuanto a lo de los chinos :smt003 decir que uso Win 7 no vaya a ser por eso, pero cuando ejecuto cualquier script de ejemplo de _GUICtrlHeader de la Ayuda UDFs sale esto:

Imagen

Gracias otra vez y Saludos

PD. ya hasta esta noche no podré seguir investigando.

EDIT: Por cierto se me olvidaba, en cuanto a las columnas solo utilizo 1 columna que ocupa todo el ListView
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

¿Cuál es _GUICtrlHeader? Hay muchas funciones que empiezan así, pero no tengo ninguna con ese nombre exacto, ¿a cuál te refieres exactamente?
¿_GUICtrlHeader_Create?

Ah, pues sí, esa me sale "chino", yo estoy en un XP, en realidad no me sale chino, sino otros caracteres raros, parece problemas con Unicode/ANSI...

Vale, he comprobado que en el AutoIT anterior no pasa (v3.3.0), quizás la udf no está actualizada para la nueva (v3.3.6).
Al final me ha servido de algo no actualizar ;-)

No es solución pasarse a la versión anterior, claro, habrá que ver si sacan un parche o ver qué habrá cambiado...

Mira, te adjunto el GuiHeader.au3 de la versión anterior. Prueba a sustituir el que tienes con este (¡haz copia de seguridad!) y a ver si así funciona.
Hay que ponerlo en la carpeta Include en la instalación de AutoIt (o sea, por defecto está en C:\Archivos de programa\AutoIt3\Include)
Adjuntos
GuiHeader.rar
(7.74 KiB) Descargado 144 veces
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

Ximorro escribió:¿Cuál es _GUICtrlHeader? Hay muchas funciones que empiezan así, pero no tengo ninguna con ese nombre exacto, ¿a cuál te refieres exactamente?
¿_GUICtrlHeader_Create?

Ah, pues sí, esa me sale "chino", yo estoy en un XP, en realidad no me sale chino, sino otros caracteres raros, parece problemas con Unicode/ANSI...

Vale, he comprobado que en el AutoIT anterior no pasa (v3.3.0), quizás la udf no está actualizada para la nueva (v3.3.6).
Al final me ha servido de algo no actualizar ;-)

No es solución pasarse a la versión anterior, claro, habrá que ver si sacan un parche o ver qué habrá cambiado...

Mira, te adjunto el GuiHeader.au3 de la versión anterior. Prueba a sustituir el que tienes con este (¡haz copia de seguridad!) y a ver si así funciona.
Hay que ponerlo en la carpeta Include en la instalación de AutoIt (o sea, por defecto está en C:\Archivos de programa\AutoIt3\Include)
Gracias por el archivo, pero se ve que no sirve, da 5 Warnings en todos los scripts que ejecuto del GuiHeader, esperemos que saquen un parche ó una actualización.

Saludos.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

¿A pesar de los warnings sale bien o hace lo mismo?
Si el texto sale bien mientras esperamos parche se podría mirar a ver si se pueden solucionar.

Porque hablamos de warnings, no de errores, eso sería más grave...

También puede ser cosa de que realmente esa udf no funciona sola, habría que mirar de las que depende, pero la principal es WinAPI que esa no hay que cambiarla por la vieja porque ha sido muy ampliada...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

He probado cuatro scripts de la Ayuda UDFs y en todos sale 4 errores, 5 Warnings

Habrá que esperar a ver si lo soluccionan.

Saludos.
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

Te pego el código del script de ejemplo _GUICtrlHeader_GetItem y una captura de los errores y Warnings.

Código: Seleccionar todo

#include <GuiConstantsEx.au3>
#include <GuiHeader.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>

Opt('MustDeclareVars', 1)

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

Global $iMemo

_Main()

Func _Main()
    Local $hGUI, $hHeader, $hImage, $tItem

    ; Create GUI
    $hGUI = GUICreate("Header", 400, 300)
    $hHeader = _GUICtrlHeader_Create ($hGUI)
    $iMemo = GUICtrlCreateEdit("", 2, 24, 396, 274, 0)
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    GUISetState()

    ; Create an image list with images
    $hImage = _GUIImageList_Create (11, 11)
    _GUIImageList_Add ($hImage, _WinAPI_CreateSolidBitmap ($hGUI, 0xFF0000, 11, 11))
    _GUIImageList_Add ($hImage, _WinAPI_CreateSolidBitmap ($hGUI, 0x00FF00, 11, 11))
    _GUIImageList_Add ($hImage, _WinAPI_CreateSolidBitmap ($hGUI, 0x0000FF, 11, 11))
    _GUICtrlHeader_SetImageList ($hHeader, $hImage)

    ; Add columns
    _GUICtrlHeader_AddItem ($hHeader, "Column 1", 100, 0, 0)
    _GUICtrlHeader_AddItem ($hHeader, "Column 2", 100, 0, 1)
    _GUICtrlHeader_AddItem ($hHeader, "Column 3", 100, 0, 2)
    _GUICtrlHeader_AddItem ($hHeader, "Column 4", 100)

    ; Show column 3 image index
    $tItem = DllStructCreate($tagHDITEM)
    DllStructSetData($tItem, "Mask", $HDI_IMAGE)
    _GUICtrlHeader_GetItem ($hHeader, 2, $tItem)
    MemoWrite("Column 3 image index: " & DllStructGetData($tItem, "Image"))

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

; Write a line to the memo control
Func MemoWrite($sMessage)
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite
Imagen

Saludos.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

Vale, creo que ya está. Veo en el foro oficial de los desarrolladores que en las versiones beta ya está solucionado.

Si no quieres instalar una beta creo que funcionará sólo cambiando lo siguiente:
Ve al archivo GuiHeader.au3 y lo editas. El original, no el que te pasé yo de la versión anterior.
Creo que los include originales son de sólo lectura, tendrás que quitar la protección.

En la función _GUICtrlHeader_Create, al final, antes del Return, hay una línea que dice
_GUICtrlHeader_SetUnicodeFormat($hHeader, False)
COMENTA esa línea para que sí sea Unicode.

Graba el cambio y ya debería funcionar.
Si quieres vuelve a proteger el archivo contra escritura para dejarlo "como estaba" :smt003
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

Efectivamente esa es la solucción, ahora ya funcionan los scripts como toca :smt041

Gracias y Saludos
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

¡Genial!

Pues vaya fallo se les coló en la versión de producción porque parece fácil de detectar, quiero decir que es fácil ver que falla porque incluso usando caracteres básico salía chino, otra cosa es ver cómo solucionarlo, claro, eso ya no es tan fácil.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

Otra duda más con _GUICtrlListView pretendo que los items no se puedan seleccionar, tengo este código

Código: Seleccionar todo

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Misc.au3>


Opt('MustDeclareVars', 1)


_Main()

Func _Main()
	Local $hListView, $Form1

	; Create GUI
	$Form1 = GUICreate("Prueba", 515, 443, 192, 124)

	; Create ListView
	$hListView = _GUICtrlListView_Create($Form1, "", 12, 26, 490, 306)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES))
_GUICtrlListView_AddColumn($hListView, "Prueba", 490)

	GUISetState()

	; Add items
	_GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
	_GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
	_GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)

	; Loop until user exits
	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE
	GUIDelete()
EndFunc
hasta aqui normal, y ahora con $LVS_SHOWSELALWAYS entiendo que no se deberian seleccionar los items

Código: Seleccionar todo

$hListView = _GUICtrlListView_Create($Form1, "", 12, 26, 490, 306, Not($LVS_SHOWSELALWAYS))
pues bien, no solo se siguen seleccionando los items, si no que desaparece la columna y los items los ordena horizontalmente, vamos que lo cambia todo.

En realidad lo que pretendo hacer es que cada vez que se haga click en un item el checkbox se ponga marcado y al siguiente click desmarcado, vamos que para activar el checkbox con pinchar encima del texto sea suficiente, aunque el código para esto vendría despues, lo primero sería que no se pudieran seleccionar los items

A ver si me dais alguna idea, por que con la Ayuda he probado con varios parámetros y no consigo hacerlo.

Saludos.
jamaro
Hacker del Foro
Mensajes: 253
Registrado: 03 Nov 2010, 23:04

Re: _GUICtrlListView varias dudas

Mensaje por jamaro »

Maravillado me he quedado con este hilo. No lo había leído y ahora lo he hecho de principio a fin.

¡Muy interesante! Acabo de probar y aplicar alguna de las cosas que se comentan.

Sigo atento.... :smt024
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: _GUICtrlListView varias dudas

Mensaje por Ximorro »

No puedes quitar un estilo de esa manera. Piensa que los estilos son realmente bits en un número que los agrupa todos. El estilo es un entero que se interpreta en binario, cada bit (o grupo de bits concreto) corresponderá a un estilo
Realmente poner un estilo es por ejemplo "activar el bit 8".

Por eso se hace con BitOr para añadir los estilos, si por ejemplo tengo este valor de estilos (lo pongo ya en binario, supongamos que es un sólo byte, aunque realmente son más): 10001001
Ahora quiero añadir el estilo NoSel que vamos a inventarnos que es "activar el 5º bit", se cuentan desde la derecha, (el 5º bit sería en realidad el número 4, pues empieza a contar desde cero, pero no hace falta liar la cosa).
El caso es que eso significa que nuestro estilo NoSel es en binario 00010000 (un byte con el 5º bit a uno).
Para añadir ese estilo a nuestra máscara de estilos se hace un OR binario, así si ya había un uno se deja como está (ya estaba activado), pero si estaba a cero (estaba desactivado) lo activamos:
10001001 OR 00010000 = 10011001
Con lo que hemos añadido el estilo pues la máscara final tiene el 5º bit a 1, que es el estilo NoSel, y además NO HEMOS TOCADO LOS OTROS ESTILOS QUE YA ESTABAN PUESTOS.

¿Para quitarlo si ya está puesto?

Pues para empezar habría que combinarlo con el que haya en ese momento, cosa que no haces, pero es que fíjate lo que significa lo que has puesto. Supongamos que en nuestro caso inventado quiero quitar NoSel. Si hago Not(NoSel) obtengo el negativo, es decir BitNot(00010000)=11101111.
O sea, he quitado el flag, sí, ¡¡pero he activado todos los demás!!, por eso te hace cosas raras, en realidad has activado un montón de estilos.


Cuando entiendas lo que he puesto hasta ahora (puede que tengas que leerlo varias veces si nunca has manejado esas cosas) quizás encuentres una manera de quitar los bits de tu estilo, que poderse se puede haciendo operaciones booleanas, pero hay DOS problemas.

El primero es que hay estilos que comparten otros, y si quitas uno puedes dejar un estado inconsistente en la palabra de estilos, porque podrías dejar uno activado a medias.
Eso pasa por ejemplo mucho con los del GUI, por ejemplo WS_BORDER es 0x00800000, es decir en binario eso es:
00000000100000000000000000000000 (¿a que ahora agradeces que antes haya usado sólo un byte?) :smt003
y WS_CAPTION es 0x00C00000, en binario:
00000000110000000000000000000000

Si te fijas hay un bit compartido. Si tuviera puestos los dos estilos, si quito WS_CAPTION también estaría quitando WS_BORDER, o sea quiero tener un borde pero no título, ¡¡pero no hay manera!!, la selección de flags para los estilos me lo impide ¡gracias Microsoft!. Y si quiero quitar el borde porque quiero tener una ventana sin borde pero con título... ¡tampoco puedo!. Si quito su bit me quedaría:
00000000010000000000000000000000
Es decir 0x00400000 en hexadecimal, que corresponde a otro estilo (en este caso borde de tipo diálogo, que no es lo mismo que sin borde). Y en este caso igual nos sirve porque toca el borde y a lo mejor nos gusta, pero podría haber sido otro estilo diferente...
Poder quitar algunos flags o no depende del diseño que haya dado Microsoft a los mismos, hay que tener cuidado al quitar bits sueltos de la máscara de estilo.

El segundo problema
, ya particular de tu caso, es que el estilo que estás intentando quitar no sirve para eso. Resulta que ese flag es para que la selección se muestre siempre, eso quiere decir que si lo pones se mostrará también aunque el control no tenga foco. Ese estilo no hace nada mientras el control tiene foco, en ese caso la selección se mostrará da igual lo que valga LVS_SHOWSELALWAYS. Así que quitarlo no quita la selección, sólo cuando no hay foco.
Las malas noticias es que no veo que haya estilos que impidan selección, para mí que no se puede, aunque esto sólo lo digo por lo que veo en la documentación, si alguien sabe de algún estilo que falte ahí o si se puede hacer con otro comando (quizás mandando un mensaje al control) que lo diga.

De todas maneras dado lo que quieres hacer tienes una solución. Con eso de cambiar el check al pinchar tendrás que hacer una gestión de eventos más compleja, supongo que capturando WM_COMMAND. Pues entonces lo que tienes que hacer es que al pinchar no sólo cambias el estilo del check, de paso aprovechas y vuelves a quitar la selección :smt004 En realidad parpadeará porque se pondrá y enseguida la quitarás, pero tampoco pasa nada porque como visualmente la celda cambia, pues estás cambiando el check, queda como un efecto visual. :smt024

Uf, estoy cansado de escribir, espero que la megaexplicación haya servido para algo.
(Bueno jamaro me alegro que lo hayas aprovechado, si has llegado hasta aquí igual ya no piensas lo mismo ;-) )
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Spra
Mensajes: 27
Registrado: 04 May 2008, 20:32

Re: _GUICtrlListView varias dudas

Mensaje por Spra »

En primer lugar muchas gracias por la superexplicación.
En cuanto al tema binario que explicas lo he entendido mas ó menos, pero suficiente, me hago la idea
El tema de añadir o quitar estilos que afectan unos a otros, lo vi ayer en el foro inglés por lo que la selección de items lo dejo como está y en cuanto a lo de activar los checkbox pinchando en los items he copiado un codigo del foro inglés que funciona perfectamente, aunque hay varias instrucciones que no entiendo, funciona bien, ahora tengo que adaptarlo a mi script ya que en un primer intento no me funcionaba, no se porque, tengo que revisarlo.

Pongo aqui el codigo por si alguien le interesa:
Créditos a rover y laffo16 del foro inglés

Código: Seleccionar todo

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <GuiListView.au3>

Opt('MustDeclareVars', 1)

Local $msg
Local $search_gui = GUICreate("Product Scanner", 400, 300, -1, -1)
Local $listview = GUICtrlCreateListView("Product ID|Category|Last Update", 2, 2, 394, 250)
_GUICtrlListView_SetExtendedListViewStyle($listview, BitOR($LVS_EX_BORDERSELECT, $LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES, $LVS_EX_GRIDLINES))
GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUICtrlCreateListViewItem("1|2|3", $listview)
GUICtrlCreateListViewItem("4|5|6", $listview)
GUICtrlCreateListViewItem("7|8|9", $listview)

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
GUIDelete()

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    If $iIDFrom = $listview Then
        Switch $iCode
            Case $NM_CLICK
                Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                If @error Then Return $GUI_RUNDEFMSG
                Local $Item = DllStructGetData($tInfo, "Index")
                If @error Or $Item = -1 Then Return $GUI_RUNDEFMSG

                Local $tTest = DllStructCreate($tagLVHITTESTINFO)
                DllStructSetData($tTest, "X", DllStructGetData($tInfo, "X"))
                DllStructSetData($tTest, "Y", DllStructGetData($tInfo, "Y"))
                Local $iRet = GUICtrlSendMsg($iIDFrom, $LVM_HITTEST, 0, DllStructGetPtr($tTest))
                If @error Or $iRet = -1 Then Return $GUI_RUNDEFMSG
                Switch DllStructGetData($tTest, "Flags")
                    Case $LVHT_ONITEMICON, $LVHT_ONITEMLABEL, $LVHT_ONITEM
                        If _GUICtrlListView_GetItemChecked($listview, $Item) = False Then
                            _GUICtrlListView_SetItemChecked($listview, $Item, 1)
                        Else
                            _GUICtrlListView_SetItemChecked($listview, $Item, 0)
                        EndIf
                    Case $LVHT_ONITEMSTATEICON ;on checkbox
                EndSwitch
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc
lo que interesa verdaderamente es la Func WM_NOTIFY, aqui me pierdo al utilizar dll y varios estilos que no se que significan, pero funciona.

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

Re: _GUICtrlListView varias dudas

Mensaje por Chefito »

Personalmente, a mi me gusta más como dice Ximorro. Darle un efecto de selección/deselección rápido. Lo veo más bonito. Incluso si la velocidad de este efecto es muy rápida, la puedes controlar con un sleep con un valor pequeño (ejemplo sleep(50)) para hacer este efecto visual más vistoso. Yo ya he hecho esto en algunos scripts, como por ejemplo el último que hice de búsqueda de textos. Lo hice cuando pulsabas los labels que hacían funciones de botones :smt002 .

Pero bueno, si sigues queriendolo hacer así como dices, que no se vea la selección ni el foco (además de la marca de selección tendrías que quitar el recuadro con líneas discontinuas del foco) te pongo lo que tienes que hacer. Antes del GUISetState() pon esta línea:

Código: Seleccionar todo

_GUICtrlListView_SetCallBackMask($ListView, 12)
Mira esta función en la ayuda y leelo bien. Con la explicación tan buena que te ha hecho Ximorro seguramente lo entenderás :smt001 .
Solo decirte que esto da el valor de la máscara de devolución de llamada. Como ha explicado Ximorro, con una máscara se suele filtrar bits que proporcionan o quitan propiedades a un objeto (un poco mal explicado, pero bueno :smt005 . Busca en google). En este caso estoy enmascarando el 3º bit (en decimal el número 4) y el 4º bit (en decimal el número 8). Sumando los dos (4+8) hacen un total de 12, que es el valor que paso a la función.
Por que estos dos bits??? Porque enmascaro el 3º bit que como dice la ayuda es el que da el foco al item (número 4), y el 4º bit que es el que selecciona al item (número 8).

No me explicado muy bien (se le da mejor al compa Ximorro :smt002 ), pero espero que hayas comprendido algo. Para saber estas cosas bien, tienes que tener algo de base en programación y numeración binaria, algebra de boole, etc. Pero con estas pequeñas explicaciones supongo que te apañes :smt005 .

El método que utilizan nuestros compis de habla inglesa está bien. Creo que averiguan el item a partir de las coordenas del click en el listview. Yo, como soy más simple, seguramente esa parte la hubiese hecho así:

Código: Seleccionar todo

    If $iIDFrom = $listview Then
        Switch $iCode
			Case $NM_CLICK
                Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                If @error Then Return $GUI_RUNDEFMSG
                Local $Item = DllStructGetData($tInfo, "Index")
				If $Item<>-1 Then
					If _GUICtrlListView_GetItemChecked($listview, $Item) = False Then
						_GUICtrlListView_SetItemChecked($listview, $Item, 1)
					Else
						_GUICtrlListView_SetItemChecked($listview, $Item, 0)
					EndIf
				EndIf
		EndSwitch
    EndIf
Simplemente miro el index que se devuelve al cliquear en un item, y si no da -1 (no se ha cliqueado ningún item), pues revisa si lo chequea o no.

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