Versões: | Advanced Protheus 6.09 , Advanced Protheus 7.10 , Microsiga Protheus 8.11 , Protheus 10 |
Compatível Países: | Todos |
Sistemas Operacionais: | Todos |
Compatível às Bases de Dados: | Todos |
Nível de Acesso: | Nível 1 (Acesso Clientes) |
Idiomas: | Espanhol , Inglês |
Funções de dimensionamento de janelas
Objetivo:
Permitir que as janelas criadas pelo Protheus possam aproveitar a maior área da tela, levando em consideração a resolução adotada pelo sistema operacional.
Modo de funcionamento:
O conceito de MsAdvSize() e MsObjSize() é o de calcular o tamanho dos componentes (objetos) antes de sua criação. Para tanto, utilizam cálculos meramente matemáticos e são extremamente rápidas.
Modo de utilização:
Para que a janela e seus componentes possam ser ajustados à resolução, devem ser utilizadas duas funções: MsAdvSize() é a função básica, que devolve o tamanho da dialog (janela) a ser criada e o tamanho da área de trabalho a ser utilizada pelos componentes (objetos) contidos na janela. MsObjSize() retorna o tamanho e posição de cada componente (objeto) da janela, conforme definições recebidas via parâmetros. MsObjSize() recebe o tamanho da área de trabalho definida por MsAdvSize().
.PRW
MsObjSize - Dimensionamento de janelas ( ExpA2ExpA3 [ ExpL1 ] [ ExpL2 ] ) --> ExpA1
-
ExpA1(vetor)
- Array bidimensional contendo as posições de cada objeto
MsObjSize()
ExpA1 := MsObjSize( ExpA2, ExpA3, [ ExpL1 ], [ ExpL2 ] )
Parâmetros:
ExpA2 -> Área de trabalho (todos os dados em PIXEL)
1 -> Linha inicial
2 -> Coluna inicial
3 -> Linha final em
4 -> Coluna final em
5 –> Separação X – numérico.
6 –> Separação Y – numérico.
7 –> Separação X da borda. Opcional – numérico.
8 –> Separação Y da borda. Opcional – numérico.
Este array corresponde à área de trabalho a ser utilizada. É composto de seis ou oito elementos. Os quatro primeiros elementos normalmente correspondem aos 4 primeiros elementos retornados pela função MsAdvSize(). O elemento 5 indica a separação lateral ( X ) em pixels entre cada objeto, e o elemento 6 indica a separação vertical ( Y ) em pixels entre cada objeto. O elemento 7 indica a separação lateral ( X ) em pixel entre o objeto e o limite da área de trabalho, e o elemento 8 indica a separação vertical ( Y ) entre o objeto e o limite da área de trabalho. Os elementos 7 e 8 são opcionais, e caso o array seja passado com 6 elementos serão assumidos os conteúdos dos elementos 5 e 6 respectivamente.
Exemplo de janela com 4 objetos:
FATC010.PRX – Pipeline / Administração de vendas.
Local aObjects := {}
AAdd( aObjects, { 100, 10, .T., .F. } )
AAdd( aObjects, { 100, 100, .T., .T., .T. } )
AAdd( aObjects, { 100, 100, .T., .T., .T. } )
AAdd( aObjects, { 100, 35, .T., .F. } )
ExpA3 -> Definições de objetos
É um Array contendo as características de cada objeto a ser criado. É um array bidimensional, visto que podem ser criados vários objetos. A ordem de disposição lógica dos objetos na tela respeitará a ordem na definição de ExpA3. A segunda dimensão do array possui 5 elementos a saber:
1 - Tamanho X – numérico
Indica o tamanho do objeto na dimensão X (horizontal).
2 - Tamanho Y – numérico
Indica o tamanho do objeto na dimensão Y (vertical).
3 - Dimensiona X – booleano (lógico)
Indica se o tamanho do objeto deve ser modificado na dimensão X. Em alguns casos, não é desejável alterar a largura de um objeto. Exemplo: imagem.
4 - Dimensiona Y – booleano (lógico)
Indica se o tamanho do objeto deve ser modificado na dimensão Y. Em alguns casos, não é desejável alterar a altura de um objeto. Exemplo: linha contendo texto fixo ou objeto de altura fixa (folder de totalizadores da rotina MATA103 – documento de entrada – parte inferior)
5 - Retorna dimensões X e Y ao invés de linha / coluna final.
Algumas classes de objetos do Protheus recebem parâmetros de dimensões X e Y ao invés da linha / coluna inicial / final. Neste caso o parâmetro deve ser passado como .T. . Exemplo de classe que recebe X e Y -> mspanel
@ aPosObj2[1,1], aPosObj2[1,2] MSPANEL oScrPanel PROMPT "" SIZE aPosObj2[1,3],aPosObj2[1,4] OF oDlg CENTERED LOWERED
ExpL1 -> Booleano (lógico). Mantém a proporção dos objetos
Este parâmetro indica que os objetos que podem ser redimensionados terão sua proporção de tamanho respeitada. Exemplo: se um objeto foi passado como “dimensão Y – redimensionar” e tamanho 100, e outro como “dimensão Y – redimensionar” e tamanho 200, o segundo objeto terá sempre o dobro da altura do primeiro, não importa a altura da janela. É importante salientar que essa função atua apenas caso os parâmetros 3 ou 4 de ExpA3 sejam .T..
Exemplo de rotina que utiliza esta configuração: TECA120.PRX – Plano de manutenção preventiva. A altura do segundo objeto (getdados) é 50% maior que a do primeiro (enchoice), pois foram definidos tamanhos 60 e 40.
Local aObjects := {}
AAdd( aObjects, { 100, 40, .T., .T. } ) // enchoice
AAdd( aObjects, { 100, 60, .T., .T. } ) // getdados
O default é .F.
ExpL2 -> Booleano (lógico). Indica cálculo de objetos horizontais.
Este parâmetro indica que os objetos serão dispostos horizontalmente na janela, ou seja, um ao lado do outro. Exemplo de programa que utiliza esta configuração: TECC060 (Service Tracker – módulo FIELD SERVICE ).
O default é .F.
Retorno:
ExpA1 -> O array de retorno Exp1 é um array bidimensional contendo as posições de cada objeto. Cada linha do array é um subarray com a seguinte estrutura:
1 -> Linha inicial
2 -> Coluna inicial
3 -> Linha final
4 -> Coluna final
Ou:
Caso seja passado o elemento 5 de cada definição de
objetos como .t. o retorno será:
3 -> Tamanho da dimensão X
4 -> Tamanho da dimensão Y
Observação: algumas classes de objetos do Protheus recebem parâmetros de tamanho fora dos padrões citados acima. Nesses casos, é necessário manipular o array de retorno.
A ordem dos objetos em ExpA1 é a mesma na qual as definições dos objetos foram passadas em ExpA3. Ou seja, se na primeira linha de ExpA3 foram passados dados para uma enchoice, deve-se utilizar a primeira linha de ExpA1 como base para desenhar o objeto enchoice.
A rotina FATA180 (Regras de bonificação financeira – módulo faturamento) é um caso clássico. Possui um objeto enchoice na parte superior e um objeto getdados na parte inferior. Exemplo de código: Local aSize := {}Local oObjects := {} Loca aInfo := {} // Obtém a a área de trabalho e tamanho da dialogaSize := MsAdvSize()AAdd( aObjects, { 100, 100, .T., .T. } ) // Dados da Enchoice AAdd( aObjects, { 200, 200, .T., .T. } ) // Dados da getdados // Dados da área de trabalho e separaçãoaInfo := { aSize[ 1 ], aSize[ 2 ], aSize[ 3 ], aSize[ 4 ], 3, 3 } // Chama MsObjSize e recebe array e tamanhosaPosObj := MsObjSize( aInfo, aObjects,.T.) // Usa tamanhos da dialogDEFINE MSDIALOG oDlg TITLE cCadastro From aSize[7],0 To aSize[6],aSize[5] of oMainWnd PIXEL // Usar sempre PIXEL !!!// Usa linha 1 do array para enchoice. A enchoice já recebe um array pronto de dimensões EnChoice( "AI1", nReg, nOpc,,,,,aPosObj[1], , 3, , , , , ,.F. )// Usa linha 2 do array para getdados. A getdados recebe individualmenteoGetD :=MsGetDados():New(aPosObj[2,1],aPosObj[2,2],aPosObj[2,3],aPosObj[2,4],nOpc,"Ft180LOk()","Ft180TOk()","+AI2_ITEM",(nOper==3 .Or.nOper==4),,1,,MAXGETDAD)Casos mais sofisticadosEm algumas situações, uma chamada simples de MsObjSize() não é suficiente para se produzir janelas realmente sofisticadas. Tipicamente, isso ocorre quando desejamos exibir uma combinação de objetos dispostos vertical e horizontalmente. Nesse caso, pode ser necessário efetuar o disparo de duas ou mais funções MsObjSize(). Uma vez dominada esta técnica, pode-se produzir praticamente qualquer combinação de objetos. Um exemplo clássico desta técnica é a rotina FATA320.PRX ( representantes – módulo faturamento ). Nesse caso, temos dois objetos dispostos do lado esquerdo da tela (agenda do dia e tarefas da semana), um sobre o outro. Do lado direito, temos outros dois objetos (um calendário e um painel com vários botões), também dispostos de forma vertical. A forma mais fácil de solucionar esta janela é, primeiramente, considerar que existem dois objetos na tela dispostos lado a lado. Depois, resolveremos os objetos dispostos em cada metade da tela (direita e esquerda). Isso nos leva a três chamadas de MsObjSize().Exemplo de código:Local aSize := {}Local aInfo := {}Local aObjects := {} Local aPosObj1 := {}Local aPosObj2 := {}Local aPosObj3 := {}// Divide a tela lateralmente e resolve as dimensões de cada parte // Observe que o segundo objeto (calendário) não pode ser dimensionado // lateralmente, pois seu tamanho é fixoaSize := MsAdvSize(.F.)aObjects := {} AAdd( aObjects, { 100, 100, .T., .T. } ) // todo variável AAdd( aObjects, { 140, 66, .F., .T. } ) // tamanho ( X ) fixo aInfo := { aSize[ 1 ], aSize[ 2 ], aSize[ 3 ], aSize[ 4 ], 3, 3 } // Primeira chamada, dois objetos lateraisaPosObj1 := MsObjSize( aInfo, aObjects, , .T. ) // Resolve as dimensoes dos objetos da parte esquerda da tela// Temos 2 objetos que podem ser redimensionados.aObjects := {} AAdd( aObjects, { 100, 100, .T., .T., .T. } )AAdd( aObjects, { 100, 100, .T., .T., .T. } )// Agora, lançaremos mão de um artifício: usaremos o primeiro objeto retornado // pela primeira MsObjSize como área de trabalho da segunda MsObjSize aSize2 := aClone( aPosObj1[1] )// Para tanto, devemos inverter os parâmetros de tamanho. // A ordem passa a ser 2,1,4,3 e não mais 1,2,3,4// Isso ocorre, pois a área de trabalho funciona com coordenadas X,Y e não // Linha / coluna (Y, X) aInfo := { aSize2[ 2 ], aSize2[ 1 ], aSize2[ 4 ], aSize2[ 3 ], 3, 3, 0, 0 } // Segunda chamada (lado esquerdo), objetos dispostos verticalmente. aPosObj2 := MsObjSize( aInfo, aObjects ) // Resolve as dimensões dos objetos da parte direita da telaaObjects := {} AAdd( aObjects, { 140, 66, .T., .F. } ) // agora, a altura do calendário que nao pode mudar (Y) AAdd( aObjects, { 100, 100, .T., .T., .T. } ) // pode variar X e Y// O artifício de novo: usaremos o segundo objeto retornado // pela primeira MsobjSize como área de trabalho da terceira MsObjSizeaSize3 := aClone( aPosObj1[2] )// Para tanto, devemos inverter os parâmetros de tamanho. // A ordem passa a ser 2,1,4,3 e não mais 1,2,3,4 aInfo := { aSize3[ 2 ], aSize3[ 1 ], aSize3[ 4 ], aSize3[ 3 ], 3, 3, 0, 0 } aPosObj3 := MsObjSize( aInfo, aObjects )Basicamente, o que temos agora são dados de dimensões para 4 objetos, representados por aPosObj2, elementos 1 e 2, e aPosObj3, elementos 1 e 2. Abaixo representamos código resumido da aplicação dos dados de aPosObj2 e 3. // Browse da agenda oAgenda :=TSBrowse():New(aPosObj2[1,1],aPosObj2[1,2],aPosObj2[1,3],aPosObj2[1,4],oDlg,,35,,5 )// Browse das tarefas oTarefa :=TsBrowse():New( aPosObj2[2,1]aPosObj2[2,2],aPosObj2[2,3],aPosObj2[2,4], oDlg,,35,,5 )// Calendário oCalend:=MsCalend():New(aPosObj3[1,1],aPosObj3[1,2],oDlg)// Painel de botões @ aPosObj3[2,1],aPosObj3[2,2] MSPANEL oPanel3 PROMPT "" SIZEaPosObj3[2,3],aPosObj3[2,4] OF oDlg CENTERED RAISED //"Botoes"
Nome | Tipo | Descrição | Default | Obrigatório | Referência | ||||||||||||
ExpA2 | Vetor | Área de trabalho (todos os dados em PIXEL) | Não se aplica | X | |||||||||||||
ExpA3 | Vetor | Definições de objetos | Não se aplica | X | |||||||||||||
ExpL1 | Lógico | Mantém a proporção dos objetos | .F. | ||||||||||||||
ExpL2 | Lógico | Indica cálculo de objetos horizontais | .F. |