22 Mai 2013 13:57
DEFINE WINDOW principal AT 30,1230 WIDTH 200 HEIGHT 80 ;
TITLE "JS600 - COM " + c_Port MAIN ;
ON INIT Dados_Iniciais( c_Form )
*
@ 12, 15 LABEL label_1 WIDTH 160 HEIGHT 16 ;
VALUE 'COM ' + c_Port + " => INATIVA" ;
FONT 'Times New Roman' SIZE 14
principal.label_1.fontcolor := RED
*
END WINDOW
ACTIVATE Window principal
WHILE ! EOF()
*
n_Soma += VALOR
DBSkip()
*
ENDDO
22 Mai 2013 21:08
22 Mai 2013 21:54
DEFINE WINDOW principal AT 30,1230 WIDTH 200 HEIGHT 80 ;
TITLE "JS600 - COM " + c_Port MAIN ;
ON INIT Dados_Iniciais( c_Form )
*
@ 12, 15 LABEL label_1 WIDTH 160 HEIGHT 16 ;
VALUE 'COM ' + c_Port + " => INATIVA" ;
FONT 'Times New Roman' SIZE 14
principal.label_1.fontcolor := RED
*
Leitura()
*
END WINDOW
ACTIVATE Window principal
FUNCTION Leitura()
...
...
Rotina de leitura da serial....
...
...
RETURN NIL
22 Mai 2013 22:08
23 Mai 2013 08:34
l_Read := .F.
DEFINE WINDOW principal AT 30,1230 WIDTH 200 HEIGHT 80 ;
TITLE "JS600 - COM " + c_Port MAIN ;
ON INIT Dados_Iniciais( c_Form )
*
@ 12, 15 LABEL label_1 WIDTH 160 HEIGHT 16 ;
VALUE 'COM ' + c_Port + " => INATIVA" ;
FONT 'Times New Roman' SIZE 14
principal.label_1.fontcolor := RED
*
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION Ctrl_Read()
*
END WINDOW
ACTIVATE Window principal
FUNCTION Ctrl_Read()
IF l_Read = .T.
RETURN( NIL )
ENDIF
l_Read := .T.
...
...
Leitura da Serial
...
...
l_Read := .T.
RETURN( .T. )
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION ( Ctrl_Read1() ; Ctrl_Read2() )
ou ainda
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION ( l_Read := .T. ; Ctrl_Read1() )
23 Mai 2013 09:19
Não deu pra entender direito o que você fez para contornar este caso. Acho que se você optou por fazer o TIMER com condicional, então acertou ! Para isso você disponibiliza uma variável private ou publica (acho que no seu caso você utilizou a variável l_Read), que deve ser do tipo lógica, começando sempre com valor verdadeiro, depois torna-se falso (enquanto está fazendo o processamento) e retorna a ser verdadeiro para que a condição do TIMER funcione na hora certa. Em código seria algo assim:Hasse escreveu:É que ela dispara a Função a cada intervalo de tempo programado, mesmo que o primeiro processamento ainda não tenha terminado
Function Main
Public l_Read:=.t.
..//..
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION (If(l_Read,Ctrl_Read(),Nil))
Function Ctrl_Read()
If l_Read
l_Read:=.f.
..//.. inicio de
// Leitura da Serial
..//.. fim da leitura (do processamento)
l_Read:=.t.
Endif
Return Nil
Não só a Minigui como em todo que é feito em Harbour ou qualquer outra linguagem. Quando é necessário fazer mais de uma ação, isto é: fazer executar mais de uma função... então você coloca as funções entre parenteses separadas de vírgula. Então como uma operação matemática, irá processar primeiro o que está dentro do parentese em sequência. O ponto e vírgula na linguagem de programação, é utilizada para quebra de linha. Mantendo tudo como se fosse uma linha só. Apenas quebra a linha para efeito visual (para compreensão do código apenas).Hasse escreveu:A MiniGui funciona com algo mais ou menos como abaixo ?
- Código:
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION ( Ctrl_Read1() ; Ctrl_Read2() )
ou ainda
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION ( l_Read := .T. ; Ctrl_Read1() )
23 Mai 2013 10:04
FUNCTION Liga_Timer(cEvento)
SWITCH cEvento
CASE "INICIAR"
IF !IsControlDefined(Timer_1,Form_1)
DEFINE TIMER Timer_1 ;
OF Form_1 ;
INTERVAL 500 ;
ACTION RotinaX()
ELSE
Form_1.Timer_1.Enabled:=.T.
ENDI
ENDIF
EXIT
CASE "PARAR"
IF IsControlDefined(Timer_1,Form_1)
//Form_1.Timer_1.Release
Form_1.Timer_1.Enabled:=.F.
ENDIF
EXIT
ENDSWITCH
RETURN Nil
23 Mai 2013 10:49
DEFINE TIMER Timer_1 INTERVAL 2000 ACTION (If(l_Read,Ctrl_Read(),Nil))
23 Mai 2013 12:00
Quê bom ! Mas além disso, você está formando novos conceitos para programação GUI. Essas lógicas que foram apresentadas servem para toda linguagem de programação gráfica é outra forma de programar como vínhamos programando em Clipper... (ou até mesmo em Harbour, console).Hasse escreveu:A minha percepção da MiniGUI está se expandindo...