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 :?)
