Ir para conteúdo


Manimal

Cadastrado: 06 Jun 2012
Offline Última atividade: Ontem, 07:48
-----

#13050 Script silencioso c++

Postado por Manimal em 22 maio 2017 - 05:35

Olá Leandro.

 

O que vc chama de script silencioso?

 

E aqui é um fórum de AutoIt, seria mais fácil se vc for num fórum de C++




#13018 Remapear teclas

Postado por Manimal em 11 maio 2017 - 09:13

Olá Belini.

 

Entenda que o ScanCode é permanente, ou seja, não é apenas uma questão de mudar e pronto, fica mudado até nova ordem.

 

É o contrário, a cada boot o SO lê o ScanCode e remapeia as teclas ali contidas, portanto para mudar 2 ou mais teclas, só colocá-las na lista do ScanCode ampliando ou modificando a lista.

 

Usando o mesmo exemplo de antes (P pelo A):
 
00 00 00 00 -> sempre zeros
00 00 00 00 -> sempre zeros
02 00 00 00 -> 2 definições (1 tecla e 1 NULL)
1E 00 18 00 -> troca letra P pela letra A (observe que é primeiro a tecla final depois a inicial)
00 00 00 00 -> sempre zeros (NULL)
 
Agora modificando para incluir mais teclas:
 
00 00 00 00 -> sempre zeros
00 00 00 00 -> sempre zeros
02 00 00 00 -> 5 definições (4 teclas e 1 NULL)
1E 00 18 00 -> troca letra P pela letra A
YY 00 XX 00 -> troca X pela Y
++ 00 11 00 -> troca 1 pelo +
GG 00 00 00 -> desativa o G
00 00 00 00 -> sempre zeros (NULL)
 

Não esqueça de modificar a 3a linha que contém a quantidade de definições no ScanCode inteiro.

 

A parte chata da brincadeira é que para remover uma tecla, por exemplo, tem que remover a linha dela MAS preservar o resto do ScanCode e ajustar a 3a linha.

 

Ok?




#12955 Contar Palavras de um arquivo de texto

Postado por Manimal em 05 maio 2017 - 01:50

Olá Pedro.

 

Entendi agora seu uso dos INI.

 

Teoricamente sobre se haveria uma possível sobrecarga ao ler o INI repetidas vezes, a resposta é não!

 

Se este procedimento deixa o teu programa rápido como vc quer (ou precisa), vai nessa!  :600866:

 

Toda e qualquer função pode ser desenvolvida (ou redesenhada) do zero para satisfazer suas necessidades específicas. As funções que temos hoje, são apenas os blocos básicos com os quais desenvolvemos melhor nossas lógicas.

 

Claro que seria um saco ter que desenvolver uma rotina como StringRight ou FileOpen ou qualquer outra. Mas o princípio é de que TUDO pode ser recriado como função!

 

Se vc não gosta de uma função, recrie-a como vc gosta. Não gosta dos argumentos? Escreva outra com os argumentos que vc precisa!

 

Um belo exemplo seria a função MSgBox Plus que está aqui no fórum.

 

Por consequência, reescrever a INIREAD seria totalmente possível!

 

Na verdade, se vc pegar uma linguagem e montar um subsistema que facilite pra outras pessoas programarem, vc simplesmente estará criando um Framework. Dependendo do seu sucesso neste Framework, ele será mais conhecido (ou utiizado) do que a linguagem original  ;)




#12907 Problema com Logica

Postado por Manimal em 01 maio 2017 - 08:16

Olá Denis de Araújo Ferreira.

 

Na maioria das linguagens ditas "tipadas" esse tipo de comparação que vc está tentando fazer não seria possível.

 

Em linguagens como C, Pascal ou Java seria impossível comparar um número com uma string.

 

Felizmente (ou infelizmente) o AutoIt tem uma liberdade muito grande neste ponto. E por isto mesmo que devemos ter um cuidado extra ao fazermos este tipo de comparações.

 

Quando fazemos um IF, estamos basicamente comparando 2 variáveis do MESMO TIPO, ou seja, ambas numéricas, ambas string ou ambas lógicas. Ao efetuar comparações entre TIPOS DIFERENTES de variáveis, devemos ter em mente como que esta comparação será feita.

 

No AutoIt, ao compararmos TIPOS DISTINTOS, elas serão basicamente convertidas para números e daí feita a comparação. Neste caso todas as variáveis string são avaliadas como 0 (zero), pois não possuem um "valor" específico pois começam com letras, portanto o valor delas é zero!

 

Por isso teu programa deu resultado 5 e não 3 como vc gostaria.

 

Mas é interessante notar que o AutoIt ao converter as variáveis tipo string para números, leva em consideração o conteúdo das mesmas. Assim mesmo strings que contenham números serão convertidas para números, o que pode levar a conclusões e lógicas de programação incorretas. Por exemplo:

  1.  
  2. $variavel = "AutoIt"
  3. If $Variavel = 0 then ... ; isto vai ser VERDADEIRO porque ao converter a string, a primeira letra não tem representação numérica, portanto valor 0 (zero)
  4.  

mas se alterarmos o conteúdo da variável

  1.  
  2. $variavel = "5AutoIt"
  3. If $Variavel = 0 then ... ; isto vai ser FALSO porque ao converter a string, a primeira letra TEM representação numérica, nesse caso 5 (cinco)
Muito cuidado com isto!

 

A partir daqui temos 2 caminhos que vc deve seguir:

  1. Ou converte todas as variáveis para o mesmo tipo usando as funções string() ou number()
  2. Ou modifica seu programa pra refletir o que vc realmente quer

Eu acho que no seu exemplo, se a intenção era verificar se havia conteúdo dentro das variáveis string, então o operador correto a ser usado na comparação seria ==

Porque daí vc força a comparação do tipo (númerica/string) e do conteúdo da variável!

 

Outra possibilidade (e a mais correta no meu entendimento): Ao saber que as variáveis $x1, $x2 e $x3 são string, trate-as como tal da seguinte forma:

  1.  
  2. If $x1 = "" then ...



#12899 Como criar variáveis dinâmicamente

Postado por Manimal em 28 abril 2017 - 06:24

Olá Experito.

 

Para resolver seu problema, use os comandos Assign e Eval

  • Assign para atribuir conteúdos a variáveis dinâmicas
  • Eval para ler o conteúdo das variáveis dinâmicas

 

Modifiquei a linha 20 para a sintaxe correta de criação e as linhas 37 a 40 para a leitura correta das variáveis também.

  1.  
  2. #include <ButtonConstants.au3>
  3. #include <GUIConstantsEx.au3>
  4. #include <MsgBoxConstants.au3>
  5. #include <StaticConstants.au3>
  6. #include <WindowsConstants.au3>
  7.  
  8. FormuDinamico(3)
  9.  
  10. Func FormuDinamico($NumCan)
  11. #Region ### START Koda GUI section ### Form=
  12. $Form1 = GUICreate("Lista de pessoas", 1361, 700, 2, 2)
  13. $Group1 = GUICtrlCreateGroup("Escolhas", 8, 56, 1185, 601)
  14. GUICtrlSetFont(-1, 14, 400, 0, "MS Sans Serif")
  15. $Button1 = GUICtrlCreateButton("Pronto", 312, 608, 129, 41)
  16. $Button2 = GUICtrlCreateButton("Voltar", 704, 608, 129, 41)
  17. Local $esp = 480 / $NumCan
  18.  
  19. For $i = 1 To $NumCan
  20. Assign("Checkbox" & $i, GUICtrlCreateCheckbox("Pessoa " & $i, 104, 60 + $i * $esp, 1009, 33))
  21.  
  22. GUICtrlCreateGroup("", -99, -99, 1, 1)
  23. $Label1 = GUICtrlCreateLabel("Você pode escolher até cinco pessoas.", 8, 8, 1181, 29)
  24. GUICtrlSetFont(-1, 15, 400, 0, "MS Sans Serif")
  25. GUISetState(@SW_SHOW)
  26. #EndRegion ### END Koda GUI section ###
  27.  
  28. While 1
  29. $nMsg = GUIGetMsg()
  30. Switch $nMsg
  31. Case $GUI_EVENT_CLOSE
  32. Case $Button1
  33. ;----------- O meu problema está aqui! Não consigo descobrir qual checkbos foi marcado.
  34.  
  35. For $i = 1 To $NumCan
  36. $saida = GUICtrlRead(Eval("Checkbox" & $i))
  37. If $saida = $GUI_CHECKED Then MsgBox(1, "leu", $i)
  38.  
  39. ;----------- Esperava que os nomes das variáveis fossem Checkbox1, Checkbox2,...
  40.  
  41. EndSwitch
  42. WEnd
  43.  
  44. EndFunc ;==>FormuDinamico
  45.  
  46.  
  47.  

Dessa forma, apenas a CheckBox marcada será sinalizada!




#12888 Remapear teclas

Postado por Manimal em 28 abril 2017 - 11:01

Bom dia.
Desculpe o atraso...
 
Para remapear as teclas em Windows através do REGISTRO, a opção é usar a chave
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
através do valor
Scancode Map
 
Observações:
  1. Obrigatório reboot para efetivar as mudanças
  2. As mudanças são permanentes até apagar a chave do registro e reboot novamente
  3. As mudanças ocorrem para TODOS os usuários e/ou teclados (lay-outs)
 
Até o Windows XP era possível remapear as teclas "por usuário" usando a chave
HKEY_CURRENT_USER\Keyboard Layout
porém do Windows 7 pra frente não funciona mais
 
A "sintaxe" do Scancode Map é a seguinte:
  • 4 bytes indicando a versão (deixar sempre zeros)
  • 4 bytes indicando os flags (deixar sempre zeros)
  • 4 bytes informando a quantidade de teclas que estão sendo remapeadas (nro de teclas + 1 que é o terminador NULL da string)
  • 4 bytes para cada tecla remapeada sendo:
  •    2 bytes para a tecla desejada (deixar 00 00 para desativar a tecla)
  •    2 bytes da tecla original
  • 4 bytes indicando terminador NULL (deixar sempre zeros)
 
A maneira mais simples de pegar os Scancodes é utilizando o Sharpkeys que mostra os Scancodes
 
Senão os Scancodes podem ser procurados na net mas recomendo (para melhor entendimento):
 
 
Como exemplo usando a sugestão do teu post (trocando o P pelo A)
 
Precisamos saber
00 18 = scancode tecla P
00 1E - scancode tecla A
 
Resultando na string
00 00 00 00 -> sempre zeros
00 00 00 00 -> sempre zeros
02 00 00 00 -> 2 definições (1 tecla e 1 NULL)
1E 00 18 00 -> troca letra P pela letra A (observe que é primeiro a tecla final depois a inicial)
00 00 00 00 -> sempre zeros (NULL)
 
Ficando em AutoIt
  1.  
  2. RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout", "Scancode Map", REG_BINARY, "0x00000000000000000200000018001E0000000000")
  3.  
Depois só reiniciar  :lol:



#12844 Pressionar tecla após o resultado do _imageSearch (Violação de Regras do Fórum)

Postado por Manimal em 04 abril 2017 - 10:21

Olá SSuperComboo.

 

Além da excelente dica do Joelson0007 e do vídeo do Alexandre, eu acho que vc está usando a função errada!

 

No seu caso, que quer procurar uma imagem em uma determinada área e não no desktop inteiro, use a função _ImageSearchArea

 

Uma boa fonte de referência é este post aqui: ImageSearch Usage Explanation




#12829 Sons do windows ao digitar em um GUI

Postado por Manimal em 30 março 2017 - 08:20

Boa galera.

 

Parabéns pela solução Pedro.  :600866:

 

Fábio, muito bom seu exemplo, demorei para responder porque enroscou o trabalho aqui e quando fui testar seus exemplos não dava o som. :mad2:

 

Entre achar uma máquina que aparecesse o som que vcs falavam e fazer alguns testes, não tinha mais olhado nada.

 

E hoje, O Pedro aparece com a resposta! Uhu!!!  :like_icon:




#12811 Sons do windows ao digitar em um GUI

Postado por Manimal em 28 março 2017 - 03:42

Olá.

 

A pedidos, vim dar uma conferida no que está rolando aqui neste tópico.  ;)

Só não entendi muito bem o que está acontecendo. Não estou conseguindo imaginar que "barulho" seria esse ou onde e quando acontece.

Pelo que peguei no papo de vcs, ocorre um ruído de fundo em determinadas telas ou GUIs?

 

Já que vcs estão falando nelas, naturalmente vcs sabem a diferença entre HotKeySet e _IsPressed, mas vamos repassar para ter certeza que estamos todos no mesmo barco  :lol:

 

A diferença básica é que HotKeySet define uma tecla e quando esta tecla é pressionada, a função é chamada.

INVERSAMENTE, no caso do _IsPressed, há uma verificação em tempo real se uma tecla está sendo pressionada E se é a tecla desejada E se a tecla foi solta, neste caso a partir daí se faz algo (pode até chamar uma função se quiser).

 

Agora vamos definir o que é "pressionar uma tecla" pois digitação seria a prática de "pressionar" e "soltar" (ou bater) uma sequência qualquer de teclas. Atentem para a questão do "soltar" a tecla.

 

Na maioria das teclas normais, quando vc bate ou mantém pressionado, a tecla retorna como se fosse batido várias vezes. Argh!!! Vamos de novo, não ficou legal!

 

Quando eu teclo (bato e solto) a tecla ESC, por exemplo, gera um retorno do SO, informando que a tecla ESC foi pressionada (e solta), caracterizando uma batida.

Se eu mantenho a tecla ESC pressionada, a cada 500 ms gera um pressionamento da mesma tecla, como se eu tivesse batido repetidas vezes.

 

No caso do HotSetKey, a chamada à função se faz quando vc SOLTA a tecla, ou "completa a digitação" - quando o SO entende que a tecla foi solta ou a cada 500 ms.

 

Nas teclas modificadoras, isto não é possível de se fazer porque não foram projetadas para isso. Teclas modificadoras são as SHIFTs, as CTRLs e as ALTs, entre outras.

Neste caso, teclar (ou pressionar e soltar) não tem efeito e nem geram retorno no teclado, por isso não podem ser usadas em HotKeySet.

São necessárias que permaneçam "apertadas" porque a combinação destas com as teclas normais é que geram o retorno do SO.

 

Fácil de verificar isso em AutoIt:

  1.  
  2. HotKeySet("^a", "TECLA") ; pressione "CTRL A" 3x para fechar o programa
  3. While True
  4. Sleep(100)
  5. WEnd
  6.  
  7. Func TECLA()
  8. Static Local $Qtde = 0
  9. $Qtde += 1
  10. If $Qtde >= 3 Then Exit
  11. ConsoleWrite("tecla pressionada" & @CRLF)
  12. EndFunc
  13.  

No exemplo acima tem uma tecla modificadora (CTRL) e uma normal (A).

 

Mas se removermos a tecla normal e deixarmos apenas a modificadora, o script não acaba (sendo que precisamos encerrar manualmente o mesmo):

  1.  
  2. HotKeySet("^", "TECLA") ; pressione "CTRL" 3x para fechar o programa
  3. While True
  4. Sleep(100)
  5. WEnd
  6.  
  7. Func TECLA()
  8. Static Local $Qtde = 0
  9. $Qtde += 1
  10. If $Qtde >= 3 Then Exit
  11. ConsoleWrite("tecla pressionada" & @CRLF)
  12. EndFunc
  13.  

Portanto para que estas teclas modificadoras pudessem ser verificadas e/ou testadas, existe a _IsPressed, que por sua vez funciona com qualquer tecla MAS exige um trabalho maior de programação porque é necessário fazer a verificação se a tecla foi "solta" e não apenas pressionada.

Vide Help da _IsPressed que diz:

  1.  
  2. ...the script should wait until _IsPressed() returns 0 before continuing. => ...o script deve aguardar até _IsPressed retornar 0 (zero) antes de continuar. 

sinalizando a "soltura" da tecla.

 

Mencionei em tempo real, porque por mais leve que vc bata numa tecla, a HotKeySet vai gerar apenas 1 (uma) chamada, mas na _IsPressed pode gerar várias chamadas!

 

O teclado possui um processador próprio, que interpreta as teclas e manda de volta para o SO. Existe inclusive um buffer interno que armazena até 15 (quinze) teclas.

É possível verificar isso quando se está digitando algo e o computador "trava" ocupado com outra coisa e depois quando volta, ele processa (ou mostra) as teclas que vc pressionou durante o "travamento".

 

O interessante nisso tudo é que quando o buffer "enche", o teclado faz barulho!  Talvez seja aí o barulho de vcs...  :o

 

Mas fora essa explanação de "fatos inúteis e irrelevantes" (como diria a minha filha), ainda continuo sem entender os sons nas GUI de vcs.

 

Só de curioso, tem certeza que não tem algum keylogger instalado?




#12801 Movendo texto na label

Postado por Manimal em 27 março 2017 - 09:30

Olá Fábio.

 

Pelo que entendi, então não pode usar os limites da GUI, mas "caminhar" no meio da GUI, isso?

 

Bom, neste caso acho que usar o GUICtrlSetPos não seria a melhor estratégia, pois estaríamos movendo o LABEL inteiro.

 

Acho mais válido criar um LABEL fixo dentro das coordenadas que vc precisa e modificar o TEXTO dentro dele para fazer o mesmo efeito. Estou imaginando...

 

Segue novo exemplo (ainda sem janela filha) e usando Timer simples:

  1.  
  2. #include <String.au3>
  3. #include <Timers.au3>
  4. #include <FontConstants.au3>
  5. #include <ColorConstantS.au3>
  6. #include <GUIConstantsEx.au3>
  7. #include <AutoItConstants.au3>
  8. #include <StaticConstants.au3>
  9. #include <WindowsConstants.au3>
  10.  
  11. Global $Margem = 30, $Altura = 30, $Tam_Janela = 350
  12. Global $Label, $Qual, $Posicao, $Texto, $Playing = True
  13. Global $Tamanho = Floor(($Tam_Janela - ($Margem * 2)) / 7) - 1
  14. Global $Musicas = [ "TOCANDO: Detonautas >> Retorno de saturno", _
  15. "PRÓXIMA MÚSICA: Legião Urbana Disco 4 >> Pais e Filhos", _
  16. "PRÓXIMA MÚSICA: Engenheiros do Hawaii Disco 7 >> Era um garoto que como eu amava os Beatles" ]
  17. PRINCIPAL()
  18.  
  19. Func PRINCIPAL()
  20. ; GUI PRINCIPAL
  21. GUICreate("By: Fábio iGames / Pedro Pinheiro / Manimal", $Tam_Janela, 80, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_COMPOSITED, $WS_EX_TOPMOST))
  22.  
  23. ; Label da mensagem
  24. $Label = GUICtrlCreateLabel("", $Margem, $Altura, $Tam_Janela - ($Margem * 2), 20, $SS_RIGHT)
  25. GUICtrlSetColor($Label, $COLOR_WHITE) ; ajusta a cor da letra
  26. GUICtrlSetBkColor($Label, $GUI_BKCOLOR_TRANSPARENT)
  27. GUICtrlSetFont($Label, 9, $FW_SEMIBOLD, Default, "Arial")
  28.  
  29. ; Fundo (para mostrar o efeito de transparência)
  30. GUICtrlCreatePic(StringRegExpReplace(@AutoItExe, "autoit3(_x64)?\.exe", "") & "Examples\GUI\msoobe.jpg", 0, 0, 500, 600, Default, $GUI_WS_EX_PARENTDRAG) ; put up the panel graphic
  31.  
  32. ; Mostra janela principal
  33. GUISetState(@SW_SHOW)
  34. SplashTextOn("Info", "", 400, 220, Default, 100, $DLG_TEXTLEFT, "")
  35.  
  36. ; Configura teclas
  37. HotKeySet("{ESC}", "_Fechar")
  38. HotKeySet("z", "_trocar_reserva")
  39. HotKeySet("a", "_trocar")
  40.  
  41. AJUSTA_LABEL()
  42. Local $Tempo = _Timer_Init()
  43. Do
  44. If _Timer_Diff($Tempo) > 100 Then
  45. ROLA_TEXTO()
  46. $Tempo = _Timer_Init()
  47. EndIf
  48. Until GUIGetMsg() = $GUI_EVENT_CLOSE
  49. EndFunc ;==>PRINCIPAL
  50.  
  51. Func ROLA_TEXTO()
  52. If $Playing Then
  53. $Posicao += 1
  54. Local $Mostra = StringLeft($Texto, $Posicao)
  55. If $Posicao <= $Tamanho Then
  56. GUICtrlSetStyle($Label, $SS_RIGHT)
  57. If $Posicao > StringLen($Mostra) Then $Mostra &= _StringRepeat(" ", $Posicao - StringLen($Mostra))
  58. GUICtrlSetData($Label, $Mostra)
  59. Else
  60. $Mostra = StringTrimLeft($Mostra, $Posicao - $Tamanho)
  61. GUICtrlSetStyle($Label, $SS_LEFT)
  62. GUICtrlSetData($Label, $Mostra)
  63. If StringLen($Mostra) = 0 Then AJUSTA_LABEL()
  64. EndIf
  65. ControlSetText("Info", "", "Static1", _
  66. "Aperte 'Z' para trocar de mensagem na proxima volta" & @CRLF & _
  67. "Aperte 'A' para iniciar ou parar o texto" & @CRLF & @CRLF & _
  68. "Mostrando: " & $Playing & @CRLF & @CRLF & _
  69. "Mensagem: " & $Musicas[$Qual])
  70. EndIf
  71. EndFunc ;==>ROLA_TEXTO
  72.  
  73. Func AJUSTA_LABEL()
  74. $Posicao = 0
  75. $Texto = $Musicas[$Qual]
  76. EndFunc ;==>AJUSTA_LABEL
  77.  
  78. Func _TROCAR_RESERVA()
  79. $Qual += 1
  80. If $Qual >= UBound($Musicas) Then $Qual = 0
  81. EndFunc ;==>_TROCAR_RESERVA
  82.  
  83. Func _TROCAR()
  84. $Playing = not $Playing
  85. EndFunc ;==>_TROCAR
  86.  
  87. Func _FECHAR()
  88. EndFunc ;==>_FECHAR
  89.  
  90.  

Neste caso, mudando as variáveis:

  • $Margem = diz quanto afastado das margens laterais vc quer
  • $Altura = diz quanto de altura em relação à janela
  • $Tam_Janela = nem precisa explicar...  ;)

 

Coloquei um fundo padrão apenas para reforçar a transparência...

 

É por aí?




#12793 Movendo texto na label

Postado por Manimal em 26 março 2017 - 03:39

Alternativa sem a janela filha...

  1.  
  2. #include <FontConstants.au3>
  3. #include <ColorConstantS.au3>
  4. #include <GUIConstantsEx.au3>
  5. #include <AutoItConstants.au3>
  6. #include <WindowsConstants.au3>
  7.  
  8. Global $Tam_Janela = 650
  9. Global $Limite = 0, $Posicao = -1
  10. Global $Label, $Playing = True, $Qual = 0
  11. Global $Musicas = [ "TOCANDO: Detonautas >> Retorno de saturno", _
  12. "PRÓXIMA MÚSICA: Legião Urbana >> Pais e Filhos", _
  13. "PRÓXIMA MÚSICA: Engenheiros do Hawaii >> Era um garoto que como eu amava os Beatles" ]
  14. PRINCIPAL()
  15.  
  16. Func PRINCIPAL()
  17. ; GUI PRINCIPAL
  18. GUICreate("By: Fábio iGames / Pedro Pinheiro / Manimal", $Tam_Janela, 80, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_COMPOSITED, $WS_EX_TOPMOST))
  19. GUISetBkColor($COLOR_BLACK)
  20.  
  21. ; Label da mensagem
  22. $Label = GUICtrlCreateLabel("", $Tam_Janela, 30, 300, 20)
  23. GUICtrlSetColor($Label, $COLOR_WHITE)
  24. GUICtrlSetBkColor($Label, $COLOR_BLUE)
  25. GUICtrlSetFont($Label, 9, $FW_SEMIBOLD, Default, "Arial")
  26.  
  27. ; Fundo da mensagem
  28. Local $Fundo = GUICtrlCreateLabel("", 0, 30, $Tam_Janela, 20) ; fundo justo
  29. ;~ Local $Fundo = GUICtrlCreateLabel("", 0, 25, $Tam_Janela, 30) ; fundo com borda
  30. GUICtrlSetBkColor($Fundo, $COLOR_GREEN)
  31.  
  32. ; Mostra janela principal
  33. GUISetState(@SW_SHOW)
  34. SplashTextOn("Info", "", 400, 220, Default, 100, $DLG_TEXTLEFT, "")
  35.  
  36. ; Registra função
  37. AdlibRegister("_Marquee", 100)
  38.  
  39. ; Configura teclas
  40. HotKeySet("{ESC}", "_Fechar")
  41. HotKeySet("z", "_trocar_reserva")
  42. HotKeySet("a", "_trocar")
  43.  
  44. Do
  45. Until GUIGetMsg() = $GUI_EVENT_CLOSE
  46. EndFunc ;==>PRINCIPAL
  47.  
  48. Func _Marquee()
  49. If $Playing Then
  50. If $Posicao < $Limite Then AJUSTA_LABEL()
  51. GUICtrlSetPos($Label, $Posicao)
  52. $Posicao -= 8
  53. ControlSetText("Info", "", "Static1", "Limite: " & $Limite & " / Posição: " & $Posicao & @CRLF & @CRLF & _
  54. "Aperte 'Z' para trocar de mensagem na proxima volta" & @CRLF & _
  55. "Aperte 'A' para iniciar ou parar o texto" & @CRLF & @CRLF & _
  56. "Mostrando: " & $Playing & @CRLF & _
  57. "Mensagem: " & $Musicas[$Qual])
  58. EndIf
  59. EndFunc ;==>_Marquee
  60.  
  61. Func AJUSTA_LABEL()
  62. Local $Texto = $Musicas[$Qual]
  63. Local $Largura = StringLen($Texto)
  64. GUICtrlSetData($Label, $Texto)
  65. GUICtrlSetPos($Label, $Tam_Janela, 30, 8 * $Largura, 20)
  66. $Limite = -8 * $Largura
  67. $Posicao = $Tam_Janela
  68. EndFunc ;==>AJUSTA_LABEL
  69.  
  70. Func _trocar_reserva()
  71. $Qual += 1
  72. If $Qual >= UBound($Musicas) Then $Qual = 0
  73. EndFunc ;==>_trocar_reserva
  74.  
  75. Func _trocar()
  76. $Playing = not $Playing
  77. EndFunc ;==>_trocar
  78.  
  79. Func _Fechar()
  80. AdlibUnRegister("_Marquee")
  81. Exit (0)
  82. EndFunc ;==>_Fechar
  83.  



#12784 Duvida com array

Postado por Manimal em 24 março 2017 - 10:42

Olá Fábio.

 

Não querendo me meter, mas já metendo (no bom sentido...)

 

Não conheço as especificações do projeto, mas em alguns pontos fiquei curioso sobre o script que vc postou:

 

1) o arquivo .Pastas_Encontradas.ini tem um PONTO no começo do nome, por quê?

Em Linux/Android seria uma maneira de deixar o arquivo "escondido", equivalente ao atributo HIDDEN no Windows. É essa a idéia ou seria apenas para deixá-lo no início da lista?

 

2) Percebi que em todos os arquivos, há necessidade de ter a QUANTIDADE de arquivos lidos ou a QUANTIDADE de pastas encontradas.

Imagino que o motivo disso seria poder utilizar este resultado para o limite do FOR/NEXT?

 

3) Perceba que ao gerar arqs (INIs, TXT ou o que for) vc "congela" a lista de arquivos, tendo que recriar os arquivos com frequência. Não teria problema se não forem mais inseridos ou removidos nenhum arquivo.

 

4) Sua função parte do pressuposto que há somente 1 (UM) nível de subpastas dentro da pasta "musicas", assim se houver mais pastas dentro de pastas, a lista de arquivos não ficaria completa, isso?

Não tem problemas se o design do projeto for assim, mas ma minha opinião, independente do projeto, sempre deveria ler todas as pastas e arquivos possíveis a partir de uma pasta, até porque se necessário portar o projeto para outro "local", ele não pare de funcionar, exigindo a manutenção e/ou correção do programa

 

5) Vc gera o arquivo .Pastas_Encontradas.ini com as "pastas" viáveis, ou seja, que contém os arquivos que vc quer e removendo as pastas que não tem "nada", inclusive marcando as pastas como HIDDEN para que na "limpeza" do arquivo essas pastas não sejam reconhecidas.

No meu entendimento não seria nem necessário a geração desse arquivo, pois envolve 3 operações:

a) geração do arquivo (leitura de todas as pastas)

b ) marcar as pastas "vazias" como HIDDEN - não concordo com isto, porque posteriormente estas pastas pode conter arquivos e sua função não iria reconhecer estes novos arquivos porque as pastas estão escondidas (ver item 3) e também porque envolve "esconder" pastas o que pode chamar a atenção de algum programa de segurança vindo a impedir seu programa de funcionar.

c) reescrever o arquivo para "apagar" as referências, eliminando as pastas vazias

Então, não seria mais fácil ver o número de pastas pela quantidade de arquivo .INI dentro da pasta "Dados Musicais"? Tipo tem 3 arquivos INI então são 3 pastas "cheias". Eliminaria tudo isso!

 

6) Dentro dos arquivos INI, vc armazena apenas o nome dos arquivos, sendo que para poder utilizá-los, precisa montar o nome completo, utilizando como referência a pasta raiz "musicas", o nome do arquivo INI como nome da pasta e finalmente o nome do arquivo.

E se alterasse apenas o último parâmetro do _FileLIstToArrayRec para $FLTAR_FULLPATH? Dessa forma, retornaria o nome completo dos arquivos, independente de onde estão, sem precisar montar o mesmo.

 

Finalmente, fica minha versão para o seu script:

  1.  
  2. #include <File.au3> ; necessário para o _FileListToArrayRec
  3. #include <AutoItConstants.au3> ; necessário para o DirRemove
  4. #include <StringConstants.au3> ; necessário para o StringRegExp
  5.  
  6. Global Const $BASE = @ScriptDir & "\Dados_Musicais"
  7. Global Const $FILTRO = "*.mp3*;*.wav*;*.wma*;*.avi*;*.mp4*;*.mpg*;*.wmv*;*.bmp*;*.jpg*;*.png*"
  8.  
  9. DirRemove($BASE, $DIR_REMOVE) ; Deleta o Diretório (Pasta) Todo Para Criar um Novo.
  10. DirCreate($BASE) ; Cria o Diretório(Pasta).
  11.  
  12. Find_Folders(@ScriptDir & "\musicas")
  13.  
  14. Func Find_Folders($Inicio)
  15. Local $Arquivos = _FileListToArrayRec($Inicio, $FILTRO, $FLTAR_FILES, $FLTAR_NORECUR, $FLTAR_SORT, $FLTAR_FULLPATH)
  16. If @extended <> 9 Then ; @extended = 9 significa que não havia arquivos na pasta que obedecessem aos critérios do filtro
  17. IniWrite($BASE & "\" & StringRegExp($Inicio, '\\([^<>:"\/\\|?*]+)$', $STR_REGEXPARRAYMATCH)[0] & ".ini", "Arquivos", "Total", $Arquivos[0])
  18. For $Ind = 1 To $Arquivos[0]
  19. IniWrite($BASE & "\" & StringRegExp($Inicio, '\\([^<>:"\/\\|?*]+)$', $STR_REGEXPARRAYMATCH)[0] & ".ini", "Arquivos", $Ind, $Arquivos[$Ind])
  20. Next
  21. EndIf
  22. Local $Pastas = _FileListToArrayRec($Inicio, Default, $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH)
  23. If Not @error Then
  24. For $Nro = 1 To $Pastas[0]
  25. LE_PASTAS($Pastas[$Nro])
  26. Next
  27. EndIf
  28. EndFunc ;==>Find_Folders 

Obs. Eu gravei o nome completo no arquivo .INI conforme comentei no item 6. Para reverter ao seu padrão basta alterar a linha 16 de

  1.  
  2. Local $Arquivos = _FileListToArrayRec($Inicio, $FILTRO, $FLTAR_FILES, $FLTAR_NORECUR, $FLTAR_SORT, $FLTAR_FULLPATH)

para

  1.  
  2. Local $Arquivos = _FileListToArrayRec($Inicio, $FILTRO, $FLTAR_FILES, $FLTAR_NORECUR, $FLTAR_SORT, $FLTAR_NOPATH)

;)




#12759 Arquivo em Memoria

Postado por Manimal em 22 março 2017 - 08:36

Verdade Pedro.

 

Se o programa terminasse de forma normal haveria um comando para "desligar" o disco em RAM, mas no caso de encerramento abrupto existe a possibilidade do Disco ficar!

 

Nesse caso prevendo isso:

  1. Se o programa for chamado novamente, verificar se já existe o RamDisk antes de criar novamente
  2. Ao montar o RamDisk, tentar montar com o menor tamanho possível para impactar menos os demais programas e o próprio SO

Pelo menos quando reiniciar a máquina, vai apagar o RamDisk sozinho (não é uma modificação permanente)




#12752 Arquivo em Memoria

Postado por Manimal em 21 março 2017 - 10:14

Olá Carlos Henrique Cerqueira.

 

Vamos definir o que é "arquivo em memória"?

 

No momento que vc "abre" o arquivo utilizando alguma função do AutoIt, ele será/estará automaticamente na memória RAM.

Salvo arquivos muito grandes ou bancos de dados, que são especificamente projetados para não serem carregados em memória pois demandam atualizações constantes, no momento da leitura do arquivo, seu conteúdo é copiado para a memória RAM e permanece lá até:

  1. seu programa ou sua função fechar (vai depender do escopo da sua variável se Local ou Global)
  2. vc "libera a memória" referente aquela variável reatribuindo outro conteúdo a ela pois o AutoIt não tem um comando para "apagar" uma variável (até onde eu sei)

 

Como exemplo para melhor entender vamos observar o comando FileRead, cuja definição é a seguinte:

  1.  
  2. FileRead ( "filehandle/filename" [, count] )

Dentro de um loop um comando FileRead utilizando um NOME DE ARQUIVO, faz com que cada vez que função é chamada, ele force a abertura do arquivo, leitura do mesmo e fechamento.

  1.  
  2. While True
  3. bla bla bla
  4. $Conteudo = FileRead("C:\Pasta\Arquivo.ext")
  5. bla bla bla
  6. WEnd
  7.  

Ao ler o arquivo, seu conteúdo já vai para a memória, mas dessa forma, estamos pedindo ao SO que releia o arquivo toda vez, forçando um acesso a disco (procedimento mais lento) e recarregar para a memória o conteúdo a cada passagem.

 

Uma variante desse procedimento seria utilizar a forma alternativa do FileRead, através do handle:

  1.  
  2. $Handle = FileOpen("C:\Pasta\Arquivo.ext")
  3. While True
  4. bla bla bla
  5. $Conteudo = FileRead($Handle)
  6. bla bla bla
  7. WEnd
  8.  

Assim quando efetuamos a 1a leitura, o AutoIt copia o conteúdo do arquivo a memória e mantém lá para as próximas passagens, não exigindo que o SO "releia" o arquivo cada vez, por causa do parâmetro $Handle.

 

São 2 comportamentos que, dependendo da situação, podem ser aplicados: Ler uma vez só ou forçar a leitura toda vez.

Porém este comportamento só pode ser escolhido porque a função FileRead permite. Observe que nos parâmetros é aceito tanto um nome de arquivo como um handle, certo?

 

No seu caso, ao usar o GUICtrlSetImage não existe essa opção. Vamos analisar a sintaxe dele:

  1.  
  2. GUICtrlSetImage ( controlID, filename [, iconname [, icontype]] )
  3.  

O 2o parâmetro é um NOME  DE ARQUIVO, não permitindo um handle ou uma outra variável. Assim a opção de ler ou aproveitar o fato do arquivo estar em memória não existe! Portanto cada vez que for executado, o GUICtrlSetImage vai "reler" o arquivo do disco.

 

Outro detalhe interessante é que vc mesmo mencionou que o arquivo é modificado constantemente, sendo substituído por outras imagens.

Assim a cada vez que o arquivo for trocado, teoricamente vc deveria "reler" o arquivo para ter a última versão, para não correr o risco de mostrar a imagem antiga.

Montar um controle desses é trabalhoso e lento, pois ficaria mais difícil fazer esse controle do que simplesmente reler o arquivo a cada vez.

 

Não vamos entrar aqui no mérito do chamado CACHE do SO, que independente do programam ou da linguagem, acelera a manipulação dos arquivos.

 

Finalmente chegamos a conclusão de que em AutoIt, não seria possível acelerar o acesso pelo menos no seu caso em específico.

Mas sempre existe uma luz no fim do túnel... (Nem que seja o trem chegando!)  :3408emo-messbrasil:

Uma alternativa possível no seu caso, ao entender como funciona os acessos à arquivos, seria como vc mesmo disse "colocar o arquivo na memória". Então por quê não colocar todos os arquivos que precisamos na memória?

 

É possível fazer isso utilizando um Disco em RAM, ou seja, reservando parte da memória RAM e dizer ao SO que trate esse espaço como se fosse um HD.

Para o SO, onde estão fisicamente os arquivos (local, RAM, rede, internet...) não faz diferença, pois ele aplica os mesmo comandos internamente.

 

Sabendo disso, vc pode usar o RamDisk para fazer isso acontecer.

Criando um disco na RAM e armazenando seus arquivos lá, basicamente faz o que vc queria originalmente. O comportamento de um RAM Disk é exatamente igual ao de um disco comum, só que ele está na mémória. Vc pode copiar arquivos para lá, deletá-los, modificá-los etc...

 

Estou sugerindo o produto acima, apesar de ser um produto PAGO, pela funcionalidade de poder criar RAMDisks on-the-fly através de opções em linha de comando, que por sua vez, podem ser colocadas dentro do seu script em AutoIt. Exemplo:

  1.  
  2. Run(@ComSpec & " /c " & 'C:\Pasta\RamDisk.exe /add:"letter=R, fs=NTFS, size=100M"', "", @SW_HIDE) 

Esse comando cria um disco de letra R de 100 Mb no padrão NTFS na máquina que está sendo executado seu script.

Mais exemplos podem ser encontrados no help do RamDisk e nos parâmetros da linha de comando.

 
Se logo depois da criação do disco, copiar seus arquivos para lá, através das excelentes sugestões do Pedro Pinheiro, a partir daí, literalmente todos os acessos serão em memória  :P
 
Só não esqueça de desativar o RamDisk ao sair do programa!



#12744 Duvida com array

Postado por Manimal em 20 março 2017 - 12:09

Olá Fábio.

 

Em relação ao meu exemplo, minha intenção foi apenas mostrar que é possível montar quaisquer tipos de estruturas com arrays.

Tem aquela opção que mostrei, tem outra que envolvia cada pasta num sub-array fazendo um array 2D (esse eu achei mais complexo pro Pedro), mas a idéia era mostrar que tudo é possível!

 

Obs.: Pedro, quando me referi a muito complexo, não é que vc não possa usar ou entender, mas as vezes um exemplo muito complexo mais desanima do que ajuda! Desculpa qualquer coisa aí...

 

 

        hwnd = CreateWindowEx(          // Criação da Janela.
               WS_EX_TOPMOST ,          // 1º Parâmetro Opções Extras de Estilos para dar a Janela. 
               "Classe da Janela",      // 2º Parâmetro é o identificador da Class da Janela ==> O legal é que você que cria o nome da Classe.. FANTÁSTICO.
               ''Título da Janela" ,    // 3º Parametro como já diz ai é o Título da Janela.
               WS_VISIBLE | WS_POPUP ,  // 4º Estilo da Janela , aqui tem dois ==> Visível e sem Borda , só colocar esse separador ai.
               100,                     // 5º Posição X da Janela.
               100,                     // 6º Posição Y da Janela.
               640,                     // 7º Tamanho X da Janela.
               480,                     // 8º Tamanho Y da Janela.
               HWND_DESKTOP,            // 9º   (OPCIONAL) Um identificador para a janela pai ou proprietário da janela sendo criada...
               NULL,                    //  10º (OPCIONAL) Um identificador para um menu ou especifica um identificador de janela filho, dependendo do estilo da janela...
               hInstance,               //  11º (OPCIONAL) Um identificador para a instância do módulo a ser associado com a janela..
               NULL);                   //  12º (OPCIONAL) Ponteiro para um valor a ser passado para a janela através da estrutura CREATESTRUCT ...

 

Boa Fábio, agora use a mesma técnica no AutoIt, só colocando o ; (ponto e vírgula para os comentários) e o _ (underline) para continuar o comando na próxima linha).

Adaptado do exemplo do Help:

  1.  
  2. Local $hChild = GUICreate("", _ ; título da janela
  3. 169, _ ; largura
  4. 68, _ ; altura
  5. 20, _ ; posição à esquerda
  6. 20, _ ; posição ao topo
  7. $WS_POPUP, _ ; estilo a ser aplicado
  8. BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), _ ; estilo estendido
  9. $hGUI) ; handle da janela pai
  10.  
  11.  

Realmente o AutoIt é muito divertido, simples e eficiente.  :lol:

Uma das melhores linguagens que já trabalhei.  :600866: