Drop down list com imagens

Tire suas dúvidas sobre programação em AutoHotkey

Moderator: Gio

leodapaz
Posts: 3
Joined: 01 Oct 2020, 22:11

Drop down list com imagens

06 Oct 2020, 09:53

Tem alguns dias que tento procurar um dropdownlist customizado que eu possa usar imagens ao inves de palavras.
Não sei se procurei errado ou se não existe de fato.

Se alguém puder me ajudar nisso fico grato, grande abraço!
User avatar
Gio
Posts: 1067
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Drop down list com imagens

06 Oct 2020, 12:11

Bom dia Leodapaz.

Seja bem-vindo ao fórum da comunidade do AutoHotkey.

Existe sim, mas como se trata de um estilo de controle de janela pouco utilizado,ele não possui uma implementação simplificada pelo AutoHotkey. Por isso, você teria que basicamente usar programação Windows para fazer isso.

:arrow: O usuário Coco postou um exemplo de como fazer isso com ícones de uma DLL padrão do Windows em 2013. Mesmo sendo um código antigo, ele ainda funciona na maior parte:

Code: Select all

Gui, Add, Custom, classComboBoxEx32 HwndhCBoxEx 0x0002 ; CBS_DROPDOWN = 0x0002

hIL := IL_Create()
Loop, 12
	IL_Add(hIL, "imageres.dll" , A_Index+4)

SetImageList(hCBoxEx, hIL)
for a, b in ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
	InsertItem(hCBoxEx, b, a, a, a)
SetCurSel(hCBoxEx, "Verde", false)

Gui, Show
return

GuiClose:
ExitApp

SetImageList(hwnd, hIL) {
	static CBEM_SETIMAGELIST := 0x0402

	SendMessage, % CBEM_SETIMAGELIST, 0, hIL,, % "ahk_id " hwnd
	return ErrorLevel
}

InsertItem(hwnd, text, pos:="", IconNormal:="", IconSel:="") {
	static CBEM_INSERTITEMW := 0x040B , CBEM_INSERTITEMA := 0x0401
	
	pos :=  pos ? pos-1 : GetCount(hwnd) ; Append to last if pos is not specified | Zero-based index
	, IconNormal := IconNormal <> "" ? IconNormal-1 : IconNormal
	, IconSel := IconSel <> "" ? IconSel-1 : IconSel
	, cchTextMax := false ; If text information is being set, this member is ignored.
	, iOverlay := 1
	
	; SET STRUCTURE
	CBEI_STRUCT(COMBOBOXEXITEM, text, cchTextMax, pos, IconNormal, IconSel, iOverlay)
	
	SendMessage, % A_IsUnicode ? CBEM_INSERTITEMW : CBEM_INSERTITEMA, 0, &COMBOBOXEXITEM,, % "ahk_id " hwnd
}

SetCurSel(hwnd, PosOrText:=1, ByIndex:=true) {
	static CB_SETCURSEL := 0x014E , CB_FINDSTRINGEXACT := 0x0158 ;, CB_SELECTSTRING := 0x014D ; Doesn't work
	
	if ByIndex {
		SendMessage, % CB_SETCURSEL, % PosOrText-1, 0,, % "ahk_id " hwnd
		idx := ErrorLevel
	} else {
		SendMessage, % CB_FINDSTRINGEXACT, -1, &PosOrText,, % "ahk_id " hwnd
		SendMessage, % CB_SETCURSEL, % ErrorLevel, 0,, % "ahk_id " hwnd
		idx := ErrorLevel
	}
	return (idx == "FAIL" ? false : idx+1)
}

GetCount(hwnd) {
	static CB_GETCOUNT := 0x0146
	
	SendMessage, % CB_GETCOUNT, 0, 0,, % "ahk_id " hwnd
	return (ErrorLevel == "FAIL" ? false : ErrorLevel)
}

CBEI_STRUCT(ByRef COMBOBOXEXITEM, ByRef pszText, ByRef cchTextMax, ByRef iItem, ByRef iImage, ByRef iSelectedImage, ByRef iOverlay, ByRef iIndent:=0) {
	static CBEIF_TEXT := 0x00000001 , CBEIF_IMAGE := 0x00000002 , CBEIF_SELECTEDIMAGE := 0x00000004 , CBEIF_OVERLAY := 0x00000008 
			, CBEIF_INDENT := 0x00000010 , CBEIF_LPARAM := 0x00000020 , CBEIF_DI_SETITEM := 0x10000000
	
	; SET MASK
	mask := CBEIF_TEXT | (iImage <> "" ? CBEIF_IMAGE : 0) | (iSelectedImage <> "" ? CBEIF_SELECTEDIMAGE : 0)
	
	;~ CREATE STRUCTURE
	VarSetCapacity(COMBOBOXEXITEM, 36, 0)
	, NumPut(mask , COMBOBOXEXITEM , 0) ; mask
	, Numput(iItem, COMBOBOXEXITEM , 4) ; iItem
	, Numput(&pszText, COMBOBOXEXITEM , 8) ; pszText
	, Numput(cchTextMax, COMBOBOXEXITEM , 12) ; cchTextMax - If text information is being set, this member is ignored.
	, NumPut(iImage, COMBOBOXEXITEM , 16) ; iImage
	, NumPut(iSelectedImage, COMBOBOXEXITEM , 20) ; iSelectedImage
	, Numput(iOverlay, COMBOBOXEXITEM , 24) ; iOverlay
	, Numput(iIndent, COMBOBOXEXITEM , 28) ; iIndent
	;~ , NumPut(CBEIF_LPARAM , COMBOBOXEXITEM , 32) ; lParam
	
}

Referências e créditos: https://autohotkey.com/board/topic/90877-autohotkey-v1110-alpha-release/#entry573723


:arrow: Naturalmente, também é possível fazer o mesmo com imagens customizadas por você e que estejam em arquivos. Aqui vai um exemplo modificado do código acima utilizando imagens em arquivos que estiverem na pasta do script (salve as imagens verde, vermelho e amarelo, todas em anexo abaixo, na pasta do script antes de rodar o script abaixo).

Code: Select all

Gui, Add, Custom, classComboBoxEx32 HwndhCBoxEx 0x0002 ; CBS_DROPDOWN = 0x0002

hIL := IL_Create(3) ; O 3 se refer ao número de imagens que você vai utilizar. Se forem 4, 5, ou qualquer outro número de imagens, ajuste aqui.
IL_Add(hIL, A_ScriptDir . "\Verde.png") ; Para cada imagem, também é necessário adicioná-las individualmente na lista (mas você pode usar um loop se estiverem indexadas).
IL_Add(hIL, A_ScriptDir . "\Amarelo.png")
IL_Add(hIL, A_ScriptDir . "\Vermelho.png")


SetImageList(hCBoxEx, hIL)
for a, b in ["Verde", "Amarelo", "Vermelho"]
	InsertItem(hCBoxEx, b, a, a, a)
SetCurSel(hCBoxEx, "Verde", false)

Gui, Show
return


GuiClose:
ExitApp

SetImageList(hwnd, hIL) {
	static CBEM_SETIMAGELIST := 0x0402

	SendMessage, % CBEM_SETIMAGELIST, 0, hIL,, % "ahk_id " hwnd
	return ErrorLevel
}

InsertItem(hwnd, text, pos:="", IconNormal:="", IconSel:="") {
	static CBEM_INSERTITEMW := 0x040B , CBEM_INSERTITEMA := 0x0401
	
	pos :=  pos ? pos-1 : GetCount(hwnd) ; Append to last if pos is not specified | Zero-based index
	, IconNormal := IconNormal <> "" ? IconNormal-1 : IconNormal
	, IconSel := IconSel <> "" ? IconSel-1 : IconSel
	, cchTextMax := false ; If text information is being set, this member is ignored.
	, iOverlay := 1
	
	; SET STRUCTURE
	CBEI_STRUCT(COMBOBOXEXITEM, text, cchTextMax, pos, IconNormal, IconSel, iOverlay)
	
	SendMessage, % A_IsUnicode ? CBEM_INSERTITEMW : CBEM_INSERTITEMA, 0, &COMBOBOXEXITEM,, % "ahk_id " hwnd
}

SetCurSel(hwnd, PosOrText:=1, ByIndex:=true) {
	static CB_SETCURSEL := 0x014E , CB_FINDSTRINGEXACT := 0x0158 ;, CB_SELECTSTRING := 0x014D ; Doesn't work
	
	if ByIndex {
		SendMessage, % CB_SETCURSEL, % PosOrText-1, 0,, % "ahk_id " hwnd
		idx := ErrorLevel
	} else {
		SendMessage, % CB_FINDSTRINGEXACT, -1, &PosOrText,, % "ahk_id " hwnd
		SendMessage, % CB_SETCURSEL, % ErrorLevel, 0,, % "ahk_id " hwnd
		idx := ErrorLevel
	}
	return (idx == "FAIL" ? false : idx+1)
}

GetCount(hwnd) {
	static CB_GETCOUNT := 0x0146
	
	SendMessage, % CB_GETCOUNT, 0, 0,, % "ahk_id " hwnd
	return (ErrorLevel == "FAIL" ? false : ErrorLevel)
}

CBEI_STRUCT(ByRef COMBOBOXEXITEM, ByRef pszText, ByRef cchTextMax, ByRef iItem, ByRef iImage, ByRef iSelectedImage, ByRef iOverlay, ByRef iIndent:=0) {
	static CBEIF_TEXT := 0x00000001 , CBEIF_IMAGE := 0x00000002 , CBEIF_SELECTEDIMAGE := 0x00000004 , CBEIF_OVERLAY := 0x00000008 
			, CBEIF_INDENT := 0x00000010 , CBEIF_LPARAM := 0x00000020 , CBEIF_DI_SETITEM := 0x10000000
	
	; SET MASK
	mask := CBEIF_TEXT | (iImage <> "" ? CBEIF_IMAGE : 0) | (iSelectedImage <> "" ? CBEIF_SELECTEDIMAGE : 0)
	
	;~ CREATE STRUCTURE
	VarSetCapacity(COMBOBOXEXITEM, 36, 0)
	, NumPut(mask , COMBOBOXEXITEM , 0) ; mask
	, Numput(iItem, COMBOBOXEXITEM , 4) ; iItem
	, Numput(&pszText, COMBOBOXEXITEM , 8) ; pszText
	, Numput(cchTextMax, COMBOBOXEXITEM , 12) ; cchTextMax - If text information is being set, this member is ignored.
	, NumPut(iImage, COMBOBOXEXITEM , 16) ; iImage
	, NumPut(iSelectedImage, COMBOBOXEXITEM , 20) ; iSelectedImage
	, Numput(iOverlay, COMBOBOXEXITEM , 24) ; iOverlay
	, Numput(iIndent, COMBOBOXEXITEM , 28) ; iIndent
	;~ , NumPut(CBEIF_LPARAM , COMBOBOXEXITEM , 32) ; lParam
	
}
Verde.png
Verde.png (165 Bytes) Viewed 232 times
Amarelo.png
Amarelo.png (150 Bytes) Viewed 232 times
Vermelho.png
Vermelho.png (135 Bytes) Viewed 232 times
leodapaz
Posts: 3
Joined: 01 Oct 2020, 22:11

Re: Drop down list com imagens

07 Oct 2020, 00:47

Usando este código (salvando as imagens das 3 cores), abriria algum GUI? aqui não deu nada, pode ser que sou leigo demais pra entender isso kkkk Obrigado de qualquer modo
User avatar
Gio
Posts: 1067
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Drop down list com imagens

07 Oct 2020, 10:11

Bom dia.

Fiz alguns testes aqui e parece que o código acima (original de 2013) só funciona em versões 32 bits do AutoHotkey (ANSI e Unicode, mas somente 32 bits).

:arrow: Fiz algumas alterações para o código funcionar também em versões 64 bits do AutoHotkey (portanto, agora ele funciona em qualquer versão):

Code: Select all

Gui, Add, Custom, classComboBoxEx32 HwndhCBoxEx 0x0002 ; CBS_DROPDOWN = 0x0002

hIL := IL_Create(3) ; O 3 se refer ao número de imagens que você vai utilizar. Se forem 4, 5, ou qualquer outro número de imagens, ajuste aqui.
IL_Add(hIL, A_ScriptDir . "\Verde.png") ; Para cada imagem, também é necessário adicioná-las individualmente na lista (mas você pode usar um loop se estiverem indexadas).
IL_Add(hIL, A_ScriptDir . "\Amarelo.png")
IL_Add(hIL, A_ScriptDir . "\Vermelho.png")


SetImageList(hCBoxEx, hIL)
for a, b in ["Verde", "Amarelo", "Vermelho"]
	InsertItem(hCBoxEx, b, a, a, a)
SetCurSel(hCBoxEx, "Verde", false)

Gui, Show
return


GuiClose:
ExitApp

SetImageList(hwnd, hIL) {
	static CBEM_SETIMAGELIST := 0x0402

	SendMessage, % CBEM_SETIMAGELIST, 0, hIL,, % "ahk_id " hwnd
	return ErrorLevel
}

InsertItem(hwnd, text, pos:="", IconNormal:="", IconSel:="") {
	static CBEM_INSERTITEMW := 0x040B , CBEM_INSERTITEMA := 0x0401
	
	pos :=  pos ? pos-1 : GetCount(hwnd) ; Append to last if pos is not specified | Zero-based index
	, IconNormal := IconNormal <> "" ? IconNormal-1 : IconNormal
	, IconSel := IconSel <> "" ? IconSel-1 : IconSel
	, cchTextMax := false ; If text information is being set, this member is ignored.
	, iOverlay := 1
	
	; SET STRUCTURE
	CBEI_STRUCT(COMBOBOXEXITEM, text, cchTextMax, pos, IconNormal, IconSel, iOverlay)
	
	SendMessage, % A_IsUnicode ? CBEM_INSERTITEMW : CBEM_INSERTITEMA, 0, &COMBOBOXEXITEM,, % "ahk_id " hwnd
}

SetCurSel(hwnd, PosOrText:=1, ByIndex:=true) {
	static CB_SETCURSEL := 0x014E , CB_FINDSTRINGEXACT := 0x0158 ;, CB_SELECTSTRING := 0x014D ; Doesn't work
	
	if ByIndex {
		SendMessage, % CB_SETCURSEL, % PosOrText-1, 0,, % "ahk_id " hwnd
		idx := ErrorLevel
	} else {
		SendMessage, % CB_FINDSTRINGEXACT, -1, &PosOrText,, % "ahk_id " hwnd
		SendMessage, % CB_SETCURSEL, % ErrorLevel, 0,, % "ahk_id " hwnd
		idx := ErrorLevel
	}
	return (idx == "FAIL" ? false : idx+1)
}

GetCount(hwnd) {
	static CB_GETCOUNT := 0x0146
	
	SendMessage, % CB_GETCOUNT, 0, 0,, % "ahk_id " hwnd
	return (ErrorLevel == "FAIL" ? false : ErrorLevel)
}

CBEI_STRUCT(ByRef COMBOBOXEXITEM, ByRef pszText, ByRef cchTextMax, ByRef iItem, ByRef iImage, ByRef iSelectedImage, ByRef iOverlay, ByRef iIndent:=0) {
	static CBEIF_TEXT := 0x00000001 , CBEIF_IMAGE := 0x00000002 , CBEIF_SELECTEDIMAGE := 0x00000004 , CBEIF_OVERLAY := 0x00000008 
			, CBEIF_INDENT := 0x00000010 , CBEIF_LPARAM := 0x00000020 , CBEIF_DI_SETITEM := 0x10000000
	
	; SET MASK
	mask := CBEIF_TEXT | (iImage <> "" ? CBEIF_IMAGE : 0) | (iSelectedImage <> "" ? CBEIF_SELECTEDIMAGE : 0)
	
	;~ CREATE STRUCTURE
	
	If (A_PtrSize = 4) ; Se essa condicional for verdadeira, esta é uma versão 32 bit do AutoHotkey (independente de quantos bits é a versão do Windows ou a máquina).
	{
		VarSetCapacity(COMBOBOXEXITEM, 36, 0)
		, NumPut(mask , COMBOBOXEXITEM , 0) ; mask
		, Numput(iItem, COMBOBOXEXITEM , 4) ; iItem
		, Numput(&pszText, COMBOBOXEXITEM , 8) ; pszText
		, Numput(cchTextMax, COMBOBOXEXITEM , 12) ; cchTextMax - If text information is being set, this member is ignored.
		, NumPut(iImage, COMBOBOXEXITEM , 16) ; iImage
		, NumPut(iSelectedImage, COMBOBOXEXITEM , 20) ; iSelectedImage
		, Numput(iOverlay, COMBOBOXEXITEM , 24) ; iOverlay
		, Numput(iIndent, COMBOBOXEXITEM , 28) ; iIndent
		;~ , NumPut(CBEIF_LPARAM , COMBOBOXEXITEM , 32) ; lParam
	}
	else ; Portanto, se não for, esta é uma versão 64 bits do AutoHotkey. Teremos de usar uma estrutura 64bits.
	{
		VarSetCapacity(COMBOBOXEXITEM, 72, 0)
		, NumPut(mask , COMBOBOXEXITEM , 0) ; mask
		, Numput(iItem, COMBOBOXEXITEM , 8) ; iItem
		, Numput(&pszText, COMBOBOXEXITEM , 16) ; pszText
		, Numput(cchTextMax, COMBOBOXEXITEM , 24) ; cchTextMax - If text information is being set, this member is ignored.
		, NumPut(iImage, COMBOBOXEXITEM , 28) ; iImage ; COLOCAR 32 AQUI FEZ COM QUE TODAS AS IMAGENS APAREÇAM VERDES ANTES DA SELEÇÃO.
		, NumPut(iSelectedImage, COMBOBOXEXITEM , 32) ; iSelectedImage ; COLOCAR 40 AQUI FAZ COM QUE TODAS AS IMAGENS APAREÇAM VERDES DEPOIS DA SELEÇÃO.
		, Numput(iOverlay, COMBOBOXEXITEM , 48) ; iOverlay
		, Numput(iIndent, COMBOBOXEXITEM , 56) ; iIndent
	}
	
}

:arrow: Para fazer funcionar o script exemplo, tudo que você tem que fazer é salvar aquelas 3 imagens (verde, amarelo e vermelho) na mesma pasta do script acima, e depois executar o script acima.

Abaixo, uma imagem do resultado:

IMAGEM SCRIPT ABERTO.png
IMAGEM SCRIPT ABERTO.png (36.15 KiB) Viewed 179 times
leodapaz
Posts: 3
Joined: 01 Oct 2020, 22:11

Re: Drop down list com imagens

07 Oct 2020, 10:32

Show de bola, agora funcionou, valeu pela atenção

Return to “Ajuda e Suporte Geral”

Who is online

Users browsing this forum: No registered users and 4 guests