DIFICIL APRENDIZADO - Diálogos
Enviado: 13 Out 2004 11:36
Amiguinhos
Em busca da interface perfeita, fico tentando variações de controles e posicionamentos diversos para criar um padrão para meu sistema, e com isto vou aprimorando o uso dos mesmos.
Neste tópico, baseado em uma opção de meu sistema, apresento juntamente com os arquivos necessários como produzir um diálogo sofisticado usando os controles 5Win como, dialog, listbox, page e o conceito de recursos embutidos.
Neste tópico voce aprenderá a manusear .RC que são arquivos textos contendo os parâmetros necessários para criação de diálogos e posicionamento de controles. Eles funcionam identicamente às DLLs com a diferença de serem linkados diretamente ao executável no final produzindo um aquivo apenas.
O primeiro passo é baixar o arquivo contendo os recursos necessários para o teste. Descompacte-os em uma pasta qualquer.
http://www.5volution.com.br/downloads/forum/forum5.zip
Vamos aos arquivos principais
O primeiro deles é o arquivo de recursos, o FORUM5.RC.
Ele possui definidas alguns diálogos que são:
TestBMPLbx - Diálogo principal
dlgAUX - Diálogo de suporte ao controle PAGE
dlgTADocto - Diálogo de suporte a tabela DOCTO
dlgTASiglas - Diálogo de suporte a tabela SIGLAS
dlgTAMensal - Diálogo de suporte a tabela MENSAL
Para abrir este arquivo e analisá-lo, basta usar o WorkShop.
Já o arquivo FORUM5.PRG contém partes interessantes que acho melhor explicá-las:
A listbox principal necessita de um vetor contendo os itens que farão o disparo da mudança de página do controle PAGE.
Ao escolher um item dentro do listbox, o parâmetro ON CHANGE passa para o método oPags:SetOption() a posição numérica do item dentro do vetor usando a função ascan()
Logo no inicio do .PRG existe o comando SetHandleCount(150) que define a quantidade de arquivos que serão abertos na sessão do aplicativo e caso não seja definido obteremos erros de abertura de arquivo.
Não devemos esquecer de invocar a DLL padrão da Borland para que nossas diálogo sejam executadas, portanto no .PRG principal esta chamada deverá existir sempre.
Todas as tabelas utilizadas são abertas no modo SHARED e o parâmetro NEW ativa uma nova área de trabalho
Para que os controles tenham um apelo visual triidimensional ativamos o comando SET _3DLOOK ON
O diálogo principal é ativado e desenhado à partir da informações contidas no arquivo .RC e será chamado via parâmetro RESOURCE
O controle PAGE será redefinido com identificar 11 e ativará os diálogos de mesmo nome dlgAUX para todas as páginas definidas, já que as mesmas terão aparencia idêntica.
O passo principal de vinculo de cada listbox criada é redefini-la com a área da tabela já ativa, portanto, seleciono a tabela e redefino os controles não esquecendo de mudar as identificações dos controles para não obter erros, como oLbx1, oLbx2, aDialogs[1], aDialogs[3], etc.
A função TabDEL apenas força a mudança de área para que não ocorra deleção de registros em uma tabela à partir de ação executada em outra tabela. Para os programadores mais experientes esta função poderá ser descartada pelo uso de funções mais diretas.
A funcão TabRPT apresenta apenas um exemplo de obtenção de uma listagem à partir de uma tabela usando o comando REPORT, sendo de simples manuseio.
A função TabEDT irá acionar o diálogo de manutenção de registro da tabela escolhida pelo usuário.
Os seus parâmetros dependem do que for passado via botões no diálogo principal, sendo:
Ou seja:
_num_ - É o número de pesquisa no DO...CASE
_lbx_ - o objeto oLbx? deve ser passado para que os métodos UpStable() e Refresh() sejam executados ainda dentro da função.
lAppend - Define o conteúdo das variáveis que serão manipuladas dentro do diálogo.
A função tblMensal, que é a mais completa faço uso de diversos controles e a forma de seus conteúdos devem ser analisadas.
A saida do diálogo sem acréscimo de registros na tabela devem estar desligado pela variável lSave:
Dependendo do conteúdo de lAppend, as variáveis serão preenchidas de acordo
Aqui simulo um APPEND de TBrowse com registro em branco:
Aqui dou um numero sequencial para o registro usando um arquivo de controle numérico:
Aqui defino a variável usada pelo CHECKBOX como sendo lógica:
Aqui ativo o diálogo de manutenção de mensalidades
Aqui esta sendo redefinido um COMBOBOX com um vetor simples:
Aqui utilizo uma função modificada para abertura de COMBO com tabelas, pois a DBCOMBO não trabalha com tabelas muito grandes:
Sendo que:
ALIAS - Nome da tabela em que os dados serão pesquisados
ORDER - Ordem de indice nesta tabela em que o dado será pesquisado
FIELD - Campo que terá o conteúdo retornado dentro da variável em RESULT
HEADER - Colunas que serão apresentadas no listbox de pesquisa.
RESULT - Variável que contém o resultado da busca.
UDF - função do usuário que será executada após ter escolhido o resultado.
Notem que as funções de manutenção das tabelas seguem um padrão:
Por fim analisem o funcionamento da função psqControle, ela mantém em apenas um arquivo todos os numeros de controles de que necessitar.
Leiam também: viewtopic.php?t=874
@braços :?)
Em busca da interface perfeita, fico tentando variações de controles e posicionamentos diversos para criar um padrão para meu sistema, e com isto vou aprimorando o uso dos mesmos.
Neste tópico, baseado em uma opção de meu sistema, apresento juntamente com os arquivos necessários como produzir um diálogo sofisticado usando os controles 5Win como, dialog, listbox, page e o conceito de recursos embutidos.
Neste tópico voce aprenderá a manusear .RC que são arquivos textos contendo os parâmetros necessários para criação de diálogos e posicionamento de controles. Eles funcionam identicamente às DLLs com a diferença de serem linkados diretamente ao executável no final produzindo um aquivo apenas.
O primeiro passo é baixar o arquivo contendo os recursos necessários para o teste. Descompacte-os em uma pasta qualquer.
http://www.5volution.com.br/downloads/forum/forum5.zip
Vamos aos arquivos principais
O primeiro deles é o arquivo de recursos, o FORUM5.RC.
Ele possui definidas alguns diálogos que são:
TestBMPLbx - Diálogo principal
dlgAUX - Diálogo de suporte ao controle PAGE
dlgTADocto - Diálogo de suporte a tabela DOCTO
dlgTASiglas - Diálogo de suporte a tabela SIGLAS
dlgTAMensal - Diálogo de suporte a tabela MENSAL
Para abrir este arquivo e analisá-lo, basta usar o WorkShop.
Já o arquivo FORUM5.PRG contém partes interessantes que acho melhor explicá-las:
A listbox principal necessita de um vetor contendo os itens que farão o disparo da mudança de página do controle PAGE.
Código: Selecionar todos
local aMenuItens := { "Documentos",;
"Siglas",;
"Mensalidades" }
Código: Selecionar todos
REDEFINE LISTBOX cItem ;
ON CHANGE oPags:SetOption(ascan(aMenuItens,cItem));
ITEMS aMenuItens ;
Código: Selecionar todos
SetHandleCount(150)
Código: Selecionar todos
LoadLibrary("bwcc.dll")
Código: Selecionar todos
USE DOCTO SHARED NEW INDEX DOCTO001,DOCTO002
USE SIGLAS SHARED NEW INDEX SIGLA019
USE MENSAL SHARED NEW INDEX MENSA001
O diálogo principal é ativado e desenhado à partir da informações contidas no arquivo .RC e será chamado via parâmetro RESOURCE
Código: Selecionar todos
DEFINE DIALOG oDlg RESOURCE "TestBMPLbx"
Código: Selecionar todos
REDEFINE PAGES oPags ID 11 OF oDlg DIALOGS "dlgAUX", "dlgAUX", "dlgAUX"
Código: Selecionar todos
// **** Documentos ****
SELE DOCTO
REDEFINE LISTBOX oLbx1 FIELDS ID 600 OF oPags:aDialogs[1]
REDEFINE BTNBMP ID 601 OF oPags:aDialogs[1] RESOURCE "bmp_plus" TOOLTIP "Adiciona registro a tabela atual" ACTION TabEDT( 1, oLbx1, "NOVO" )
REDEFINE BTNBMP ID 602 OF oPags:aDialogs[1] RESOURCE "bmp_minus" TOOLTIP "Exclui o registro da tabela atual" ACTION TabDEL( 1, oLbx1)
REDEFINE BTNBMP ID 603 OF oPags:aDialogs[1] RESOURCE "bmp_editar" TOOLTIP "Altera dados do registro atual" ACTION TabEDT( 1, oLbx1, "MOSTRA" )
REDEFINE BTNBMP ID 604 OF oPags:aDialogs[1] RESOURCE "bmp_printer" TOOLTIP "Imprime o listagem da tabela atual" ACTION TabRPT( 1, oLbx1)
oLbx1:nClrPane := { || IIF( ( oLbx1:cAlias)->(OrdKeyNo()) %2 == 1, CLR_VERDINHO,CLR_CREME)}
oLbx1:lAdjLastCol := .F.
oLbx1:nStyle := 1
oLbx1:nHeaderHeight*= 2
// **** Siglas ****
SELE SIGLAS
REDEFINE LISTBOX oLbx2 FIELDS ID 600 OF oPags:aDialogs[2]
REDEFINE BTNBMP ID 601 OF oPags:aDialogs[2] RESOURCE "bmp_plus" TOOLTIP "Adiciona registro a tabela atual" ACTION TabEDT( 2, oLbx2, "NOVO" )
REDEFINE BTNBMP ID 602 OF oPags:aDialogs[2] RESOURCE "bmp_minus" TOOLTIP "Exclui o registro da tabela atual" ACTION TabDEL( 2, oLbx2)
REDEFINE BTNBMP ID 603 OF oPags:aDialogs[2] RESOURCE "bmp_editar" TOOLTIP "Altera dados do registro atual" ACTION TabEDT( 2, oLbx2, "MOSTRA" )
REDEFINE BTNBMP ID 604 OF oPags:aDialogs[2] RESOURCE "bmp_printer" TOOLTIP "Imprime o listagem da tabela atual" ACTION TabRPT( 2, oLbx2)
oLbx2:nClrPane := { || IIF( ( oLbx2:cAlias)->(OrdKeyNo()) %2 == 1, CLR_VERDINHO,CLR_CREME)}
oLbx2:lAdjLastCol := .F.
oLbx2:nStyle := 1
oLbx2:nHeaderHeight*= 2
Código: Selecionar todos
static function TabDEL( _num_, _lbx_ )
do case
case _num_ = 1
SELE DOCTO
case _num_ = 2
SELE SIGLAS
case _num_ = 3
SELE MENSAL
endcase
if MsgYesNo( "Tem certeza da exclusao deste registro?" )
RLOCK()
DELETE
COMMIT
_lbx_:UpStable()
_lbx_:Refresh()
endif
return .t.
Código: Selecionar todos
static function TabRPT( _num_, _lbx_ )
local oRpt
local n
local cAlias := If( _lbx_ != nil, _lbx_:cAlias, Alias() )
do case
case _num_ = 1
case _num_ = 2
REPORT oRpt TITLE "Relatorio: " + cAlias ;
HEADER "Data: " + DToC( Date() ) + ", Hora: " + Time() ;
FOOTER "Pagina: " + Str( oRpt:nPage, 3 ) ;
PREVIEW
if Empty( oRpt ) .or. oRpt:oDevice:hDC == 0
return nil
endif
COLUMN TITLE "UF" DATA SIGLAS->UF
COLUMN TITLE "ESTADO" DATA SIGLAS->ESTADO
COLUMN TITLE "ICMS" DATA SIGLAS->ICMS
COLUMN TITLE "IPI" DATA SIGLAS->IPI
COLUMN TITLE "REDUCAO" DATA SIGLAS->REDUCAO
ENDREPORT
ACTIVATE REPORT oRpt
GO TOP
case _num_ = 3
endcase
return .t.
Os seus parâmetros dependem do que for passado via botões no diálogo principal, sendo:
Código: Selecionar todos
REDEFINE BTNBMP ID 601 OF oPags:aDialogs[1] RESOURCE "bmp_plus" ... ACTION TabEDT( 1, oLbx1, "NOVO" )
REDEFINE BTNBMP ID 603 OF oPags:aDialogs[1] RESOURCE "bmp_editar" ... ACTION TabEDT( 1, oLbx1, "MOSTRA" )
_num_ - É o número de pesquisa no DO...CASE
_lbx_ - o objeto oLbx? deve ser passado para que os métodos UpStable() e Refresh() sejam executados ainda dentro da função.
lAppend - Define o conteúdo das variáveis que serão manipuladas dentro do diálogo.
Código: Selecionar todos
static function TabEDT( _num_, _lbx_, lAppend )
do case
case _num_ = 1
tblDocto( _num_, _lbx_, lAppend )
case _num_ = 2
tblSiglas( _num_, _lbx_, lAppend )
case _num_ = 3
tblMensal( _num_, _lbx_, lAppend )
endcase
return .t.
A saida do diálogo sem acréscimo de registros na tabela devem estar desligado pela variável lSave:
Código: Selecionar todos
local lSave := .f.
Aqui simulo um APPEND de TBrowse com registro em branco:
Código: Selecionar todos
if lAppend ="NOVO"
goto bottom
skip
endif
Código: Selecionar todos
if lAppend ="NOVO"
M->IDMENSAL := psqControle( dbf() )
endif
Código: Selecionar todos
M->FIXA := IIF(MENSAL->FIXA='S',.t.,.f.)
Código: Selecionar todos
DEFINE DIALOG oDlg RESOURCE "dlgTAMensal"
Código: Selecionar todos
REDEFINE COMBOBOX oCbx1 VAR M->TIPO ITEMS { "D-DESPESA", "R-RECEITA" } ...
Código: Selecionar todos
REDEFINE COMBO oCbx2 VAR M->IDCCUSTO ID 103 OF oDlg ;
RESOURCE "combo.bmp" ;
VALID .T. ;
ALIAS CENTROS ;
ORDER 1 ;
FIELD CENTROS->IDCCUSTO ;
HEADER STR(CENTROS->IDCCUSTO,3),CCUSTO ;
RESULT M->IDCCUSTO ;
UDF fun()
ALIAS - Nome da tabela em que os dados serão pesquisados
ORDER - Ordem de indice nesta tabela em que o dado será pesquisado
FIELD - Campo que terá o conteúdo retornado dentro da variável em RESULT
HEADER - Colunas que serão apresentadas no listbox de pesquisa.
RESULT - Variável que contém o resultado da busca.
UDF - função do usuário que será executada após ter escolhido o resultado.
Notem que as funções de manutenção das tabelas seguem um padrão:
Código: Selecionar todos
local lSave := .f.
//
// Aqui seleciono a tabela a ser manuseada
//
if lAppend ="NOVO"
goto bottom
skip
endif
//
// Aqui as variáveis serão preenchidas com dados ou zeradas
//
if lAppend ="NOVO"
//
// No caso de inclusão, se alguma variável necessitar de dado padrão.
//
endif
SET 3DLOOK ON
DEFINE DIALOG oDlg ...
//
// Aqui são colocados todos os REDEFINEs de controles para o diálogo
//
REDEFINE BUTTON ID 1 OF oDlg ACTION ( lSave := .t. , oDlg:End() )
REDEFINE BUTTON ID 2 OF oDlg ACTION ( lSave := .f. , oDlg:End() )
ACTIVATE DIALOG oDlg CENTERED
if lSave // Depende do resultado retornado pelo BUTTON acionado
//
// Aqui seleciono a tabela a ser manuseada
//
if lAppend ="NOVO"
APPEND BLANK
else
RLOCK()
endif
//
// Aqui salvo o conteúdo das variáveis em seus respectivos campos
//
COMMIT
_lbx_:UpStable() // Devem existir sempre
_lbx_:Refresh()
endif
return .t.
Leiam também: viewtopic.php?t=874
@braços :?)