Toledo escreveu:microvolution escreveu:Pra fazer funcionar ou tentar, usei a HMG 3.0.46 e para que a matriz aListItens não ficasse em branco
Amigo, pelo código da função do Amparo a matriz aListItens (
aListItens[f][1]) é multi-dimensional
Bom, infelizmente - apesar do meu pouco conhecimento em harbour, já havia previsto que não funcionaria, pois como havia dito, o erro está sendo informado na CM_CAPTION entre as linhas 25 e 84.
Aliás, fui forçando a eliminação desses erros (colocando comentários a partir da chamada ao ACTION nas linhas com erros) e eles não param, vão só aparecendo outros, então, não dá pra ficar fazendo testes de um script/código em que o autor só passou parte. Tem que passar é tudo pra que todos juntos possamos crescer, mas, gostei muito de sua ideia Sr(a).
AMPARO. Se puder aqui contribuir e compartilhar mais, somos mui agradecidos!
Bom, mas, agora vou relatar ao caro professor e aos demais colegas e colaboradores em que pé está a minha migração que já está no passo de CONSOLE para GRÁFICO.
Antes de mais nada, quero muito agradecer a paciência de todos para comigo e agradecer a existência e manutenção deste fórum que muito enriquece não só a nós (pessoalmente) mas à nossa antiga e apaixonante linguagem CLIPPER que agora compete quase que igual por igual com as mais atuais e modernas linguagens do mercado e que estão no ranking das 10 mais usadas no mundo.
Apesar de não aparecermos em nenhum ranking, eles são obrigados a nos aceitar e saber que estamos aí mais vivos do que nunca.
Então vamos lá. Apesar de meu único aplicativo já estar migrado e rodando em plataformas de 32 e 64 bits infelizmente tá muito difícil de conseguir um espaço já lotado com modo CONSOLE.
Atualmente funciona assim o meu MENU PRINCIPAL e consequentemente as chamadas aos módulos, vou exemplificar com algumas partes que são padrão e comum a todos os módulos. Vamos ao .PRG principal que aqui chamo de PCI10000.PRG:
*PCI10000():
Código: Selecionar todos
if INTEGRIDADE_OK ()
*TELA_PADRAO (procname (),DESC_SIST,COR_DESKTOP,chr (176))
TELA_PADRAO (procname (),DESC_SIST,COR_DESKTOP,chr (250)) //ÿþýüûúù ¦
aadd (TECLAS,{'Esc','Retorna'})
aadd (TECLAS,{'F4','Consulta'})
TECLAS_FUNCAO (TECLAS)
if VERIFICOU_SENHA ()
TECLAS := {}
aadd (TECLAS,{'Esc','Retorna'})
aadd (TECLAS,{'F1','Help'})
aadd (TECLAS,{'F2','Utilit rios'})
aadd (TECLAS,{'F4','Consultas'})
TECLAS_FUNCAO (TECLAS)
setcolor (COR_NORMAL)
ABRE_ARQ_ACESSO ()
MCI10000 ()
else
setcolor (SALVA_COR)
@ 00,00 clear to maxrow (),maxcol ()
@ 00,00 say 'Acesso negado ...'
@ 01,00 say 'Verifique sua senha !'
endif
else
setcolor (SALVA_COR)
@ 00,00 clear to maxrow (),maxcol ()
@ 00,00 say 'Acesso negado ...'
@ 01,00 say 'Arquivo de Controle Alterado !'
endif
close all
Bom, aqui quero destacar apenas o que realmente faz o MENU funcionar, mas, pra não ficar com alguma dúvida, as funções que nesse momento não tem tanta importância são:
INTEGRIDADE_OK() - essa verifica se o arquivo de usuários está totalmente intacto, pois se ele for violado (todos sabemos que os .DBF/.NTX não possuem nada de segurança) o sistema não abre.
TELA_PADRAO() aqui abre uma tela CONSOLE com 25,80.
TECLAS_FUNCAO() adiciona recursos às teclas especiais de F1 à F12.
ABRE_ARQ_ACESSO() essa função abre os arquivos principais do sistema, antes do banco de dados propriamente dito
VERIFICOU_SENHA() aqui é a parte do LOGIN
MCI10000() - Agora sim, esse é que começa a montar o MENU e posto o conteúdo principal dessa função logo abaixo:
*MCI10000:
Código: Selecionar todos
aadd (LINHA,'~Cadastros')
aadd (BLOCO,{|LIN,COL| MCI10001 (LIN,COL)})
aadd (H_IND,'MCI10001')
aadd (LINHA,'C~onsultas')
aadd (BLOCO,{|LIN,COL| MCI10002 (LIN,COL)})
aadd (H_IND,'MCI10002')
aadd (LINHA,'~Relat¢rios')
aadd (BLOCO,{|LIN,COL| MCI10003 (LIN,COL)})
aadd (H_IND,'MCI10003')
MONTA_VETOR (LINHA,BLOCO,H_IND,'~Formatador-1',{|| EXECUTA_PROGRAMA ({|| PCI10998 ()})},'PCI10998')
MONTA_VETOR (LINHA,BLOCO,H_IND,'For~matador-2',{|| EXECUTA_PROGRAMA ({|| PCI10999 ()})},'PCI10999')
MONTA_VETOR (LINHA,BLOCO,H_IND,'Form~atador-3',{|| EXECUTA_PROGRAMA ({|| PCI10997 ()})},'PCI10997') // acrescentado em 03/10/11w para criar os arquivos DBF/NTX de DCI10031 À DCI10999.
if len (LINHA) > 0
do while lastkey () <> K_ESC
OPCAO := MENU_HORIZONTAL (LINHA,BLOCO,H_IND,OPCAO)
if CONFIRMA ('Retorna à tela de Acesso / Login') // modificado pois está em modo gráfico 1/6/15w
setcolor (COR_INICIO)
cls
clear typeahead
keyboard chr (K_ENTER)
exit
else
clear typeahead
keyboard chr (K_ENTER)
inkey ()
endif
enddo
endif
CLOSE ALL
return
Bom, agora coisa começa a complicar um pouco, pois, se todos os módulos e opções de MENUS fossem abertos aqui, ficaria atá menos difícil de se criar um MENU POPUP, mas, como esse MCI10000 é apenas 1 de uns 20, a coisa fica complexa. Tentarei explicar para facilitar a compreensão:
Observe que LINHA,BLOCO, H_IND são vetores (matrizes) que são passadas para a função MONTA_VETOR que É BEM PEQUENA e passo a seguir:
*MONTA_VETOR:
Código: Selecionar todos
static function MONTA_VETOR (LINHA,BLOCO,H_IND,PROMPT,ACAO,INDICE)
* BCMV1 Inicio
* BCMV1 Fim
if E_MASTER () .or. EXISTE_PROGRAMA (INDICE)
aadd (LINHA,PROMPT)
aadd (BLOCO,ACAO)
aadd (H_IND,INDICE)
endif
* BCMV2 Inicio
* BCMV2 Fim
return
Acho que não é necessário passar as outras funções que ela contém, explicando acredito que dá pra esclarecer:
E_MASTER() verifica se o usuário que efetuou o LOGIN tem senha do tipo mais importante: ADMINISTRADOR DO SISTEMA. Caso possua, todos os módulos, tabelas e MENUs serão montados e liberados para esse usuário, ou se a função EXISTE_PROGRAMA() verificar que está disponível o módulo/tabela para o usuário logado, através de um arquivo exclusivo pra isso. Então, após esse último teste será montado o MENU principal de acordo com o perfil desse usuário.
Voltando à função anterior MONTA_VETOR, o MENU PRINCIPAL é montado de acordo com 2 funções, uma, está nele MENU_HORIZONTAL e outra após o movimento das teclas do teclado (<▲▼>) serem pressionadas a outra função MENU_VERTICAL é acionada, pois aqui existe um INKEY() aguardando em loop essas teclas. Se for pressionado ENTER é acionado o MÓDULO correspondente. Se for pressionado ESC é retornado à TELA DE LOGIN.
Então, vou repassar as funções por completo MENU_HORIZONTAL e MENU_VERTICAL:
*MENU_HORIZONTAL
Código: Selecionar todos
function MENU_HORIZONTAL (ELEM,BLOCO,IND_HELP,INICIO)
memvar K_HELP,K_UTIL,K_CNS
local I := 1,;
J := 1,;
N_PROMPT := len (ELEM),;
PROMPT := aclone (ELEM),;
HOTKEY := array (len (ELEM)),;
POS := array (len (ELEM)),;
TECLA := 1,;
S_CURSOR := set (_SET_CURSOR)
private AT_MENU := .f.
set cursor off
setcancel (.f.)
* altd (0)
afill (HOTKEY,'')
@ 1,0 clear to 1,maxcol ()
POS [1] := 0
FORM_PROMPT (PROMPT)
ESCR_BAR_NORMAL (1,0,PROMPT [1])
if at ('~',PROMPT [I]) <> 0
HOTKEY [I] := upper (substr (PROMPT [I],at ('~',PROMPT [I]) + 1,1))
endif
for I := 2 to N_PROMPT
POS [I] := len (PROMPT [I - 1]) + POS [I - 1] + if (at ('~',PROMPT [I]) = 0,1,0) - 1
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
if at ('~',PROMPT [I]) <> 0
HOTKEY [I] := upper (substr (PROMPT [I],at ('~',PROMPT [I]) + 1,1))
endif
next I
I := if (INICIO <> nil,INICIO,1)
do while .t.
ESCR_BAR_DESTAQUE (1,POS [I],PROMPT [I])
TECLA := inkey (0)
do case
case TECLA = K_UP
* N„o faz nada
case TECLA = K_DOWN
eval (BLOCO [I],1,POS [I])
case TECLA = K_HOME
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
I := 1
case TECLA = K_END
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
I := N_PROMPT
case TECLA = K_RIGHT
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
I := if (set (_SET_WRAP),(I % N_PROMPT) + 1,if (I < N_PROMPT,I + 1,I))
if AT_MENU
if substr (IND_HELP [I],1,1) = 'M'
keyboard chr (K_ENTER)
AT_MENU := .f.
endif
endif
case TECLA = K_LEFT
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
I := if (set (_SET_WRAP),if (I > 1,I-1,N_PROMPT),if (I > 1,I - 1,I))
if AT_MENU
if substr (IND_HELP [I],1,1) = 'M'
keyboard chr (K_ENTER)
AT_MENU := .f.
endif
endif
case E_LETRA (TECLA)
J := ascan (HOTKEY,upper (chr (TECLA)))
if J <> 0
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
I := J
keyboard chr (K_ENTER)
endif
case E_ALT_LETRA (TECLA)
J := ascan (HOTKEY,chr (LETRA_ALT (TECLA)))
if J <> 0
ESCR_BAR_NORMAL (1,POS [I],PROMPT [I])
I := J
keyboard chr (K_ENTER)
endif
case E_TECLA_FUNCAO (TECLA)
do case
case TECLA = K_HELP
HELP (IND_HELP [I],strtran (strtran (ELEM [I],'~'),chr (16)))
case TECLA = K_UTIL
UTIL_MENU ()
case TECLA = K_CNS
ARQ_MENU ()
endcase
TECLA := I
case TECLA = K_ENTER
eval (BLOCO [I],1,POS [I])
case TECLA = K_ESC
TECLA := I
exit
otherwise
TECLA := I
endcase
enddo
setcancel (.t.)
* altd (1)
set (_SET_CURSOR,S_CURSOR)
return TECLA
*MENU_VERTICAL:
Código: Selecionar todos
function MENU_VERTICAL (LIN1,COL1,ELEM,BLOCO,IND_HELP,INICIO)
memvar K_HELP,K_UTIL,K_CNS
local I := 1,;
J := 1,;
N_PROMPT := len (ELEM),;
PROMPT := aclone (ELEM),;
HOTKEY := array (len (ELEM)),;
TECLA := 1,;
S_CURSOR := set (_SET_CURSOR),;
COMPL := 0
afill (HOTKEY,'')
set cursor off
if LIN1 = 1
LIN1++
endif
FORM_PROMPT (PROMPT)
COMPL := MAX_ELEM_VETOR (PROMPT)
COL1 := if (COL1 + COMPL + 1 < 80,COL1,COL1 - (COL1 + COMPL + 1 - 80) - 1)
MOLDURA (LIN1,COL1,LIN1 + N_PROMPT + 1,COL1 + COMPL + 1,.f.,'')
COL1++
for I := 1 to N_PROMPT
PROMPT [I] := if (at ('~',PROMPT [I]) = 0,padr (PROMPT [I],COMPL),padr (PROMPT [I],COMPL+1))
ESCR_BAR_NORMAL (LIN1 + I,COL1,PROMPT [I])
if at ('~',PROMPT [I]) <> 0
HOTKEY [I] := upper (substr (PROMPT [I],at ('~',PROMPT [I]) + 1,1))
endif
next I
I := if (INICIO <> nil,INICIO,1)
do while .t.
ESCR_BAR_DESTAQUE (LIN1 + I,COL1,PROMPT [I])
TECLA := inkey (0)
do case
case TECLA = K_UP
ESCR_BAR_NORMAL (LIN1 + I,COL1,PROMPT [I])
I := if (set (_SET_WRAP),if (I > 1,I-1,N_PROMPT),if (I > 1,I - 1,I))
case TECLA = K_DOWN
ESCR_BAR_NORMAL (LIN1 + I,COL1,PROMPT [I])
I := if (set (_SET_WRAP),(I % N_PROMPT) + 1,if (I < N_PROMPT,I + 1,I))
case TECLA = K_HOME
ESCR_BAR_NORMAL (LIN1 + I,COL1,PROMPT [I])
I := 1
case TECLA = K_END
ESCR_BAR_NORMAL (LIN1 + I,COL1,PROMPT [I])
I := N_PROMPT
case TECLA = K_RIGHT
keyboard chr (K_ESC) + chr (K_RIGHT)
AT_MENU := .t.
case TECLA = K_LEFT
keyboard chr (K_ESC) + chr (K_LEFT)
AT_MENU := .t.
case TECLA = K_ENTER
eval (BLOCO [I],LIN1 + I + 1,COL1 + 1)
case TECLA = K_ESC
TECLA := I
exit
case E_LETRA (TECLA)
J := ascan (HOTKEY,upper (chr (TECLA)))
if J <> 0
ESCR_BAR_NORMAL (LIN1 + I,COL1,PROMPT [I])
I := J
keyboard chr (K_ENTER)
endif
case E_ALT_LETRA (TECLA)
keyboard chr (K_ESC) + chr (LETRA_ALT (TECLA))
case E_TECLA_FUNCAO (TECLA)
do case
case TECLA = K_HELP
HELP (IND_HELP [I],strtran (strtran (ELEM [I],'~'),chr (16)))
case TECLA = K_UTIL
UTIL_MENU ()
case TECLA = K_CNS
ARQ_MENU ()
endcase
TECLA := I
otherwise
TECLA := I
endcase
enddo
set (_SET_CURSOR,S_CURSOR)
return TECLA
Bom, diante das funções acima, pode-se observar que o MENU PRINCIPAL começa apenas com 3 ou 6 opções HORIZONTAIS:
- CADASTROS, CONSULTAS, RELATÓRIOS e para senhas MASTERes os outros FORMATADOR1, FORMATADOR2 e FORMATADOR3.
O MENU VERTICAL vai sendo montado ou desmontado à medida em que o usuário movimenta as SETAS p/esq,dir,acima,abaixo ou com ESC, ENTER e a tecla HOTKEY (na cor destacada) ou com ALT mais uma tecla HOTKEY.
Então, para não ter que perder todo o meu código, estou tentando as seguintes alterações para que meu MENU PRINCIPAL POPUP seja apresentado de acordo o perfil do usuário.
Por isso que esse tópico me chamou a atenção..
E, pra isso, fiz as seguintes alterações em meu código para tentar um formulário principal com um menu gráficos que chamem as rotinas antigas em modo CONSOLE. A princípio tem dado certo e acho que estou no caminho certo, só que não estou conseguindo pensar numa forma em que o MENU seja montado de acordo com o perfil do usuário logado e aproveitando grande parte de meu código.
Então as mudanças que tentei foram as seguintes:
*MCI10000 ficou assim:
Código: Selecionar todos
aadd (LINHA,'~Cadastros')
aadd (BLOCO,{|LIN,COL| MCI10001 (LIN,COL)})
aadd (H_IND,'MCI10001')
aadd (LINHA,'C~onsultas')
aadd (BLOCO,{|LIN,COL| MCI10002 (LIN,COL)})
aadd (H_IND,'MCI10002')
aadd (LINHA,'~Relat¢rios')
aadd (BLOCO,{|LIN,COL| MCI10003 (LIN,COL)})
aadd (H_IND,'MCI10003')
MONTA_VETOR (LINHA,BLOCO,H_IND,'~Formatador-1',{|| EXECUTA_PROGRAMA ({|| PCI10998 ()})},'PCI10998')
MONTA_VETOR (LINHA,BLOCO,H_IND,'For~matador-2',{|| EXECUTA_PROGRAMA ({|| PCI10999 ()})},'PCI10999')
MONTA_VETOR (LINHA,BLOCO,H_IND,'Form~atador-3',{|| EXECUTA_PROGRAMA ({|| PCI10997 ()})},'PCI10997') // acrescentado em 03/10/11w para criar os arquivos DBF/NTX de DCI10031 À DCI10999.
MENU_HORIZONTAL (LINHA,BLOCO,H_IND,OPCAO)
MENU_VERTICAL (LINHA,BLOCO,H_IND,OPCAO)
return
*MENU_HORIZONTAL, ficou assim:
Código: Selecionar todos
function MENU_HORIZONTAL (ELEM,BLOCO,IND_HELP,INICIO) // MODIFICADO em 23/6/15w p/ poder ter MAIN MENU POPUP HARBOUR/HMG
memvar K_HELP,K_UTIL,K_CNS
local I := 1,;
J := 1,;
N_PROMPT := len (ELEM),;
PROMPT := aclone (ELEM),;
HOTKEY := array (len (ELEM)),;
POS := array (len (ELEM)),;
TECLA := 1,;
S_CURSOR := set (_SET_CURSOR)
private AT_MENU := .f.
public H_PROMPT := aclone (PROMPT),;
H_N_PROMPT := len (ELEM),;
H_I := I,;
H_J := J,;
H_BLOCO := BLOCO,;
H_POS := H_HOTKEY := POS
set cursor off
setcancel (.f.)
* altd (0)
afill (HOTKEY,'')
@ 1,0 clear to 1,maxcol ()
POS [1] := 0
FORM_PROMPT (PROMPT)
for I := 2 to N_PROMPT
POS [I] := len (PROMPT [I - 1]) + POS [I - 1] + if (at ('~',PROMPT [I]) = 0,1,0) - 1
if at ('~',PROMPT [I]) <> 0
HOTKEY [I] := upper (substr (PROMPT [I],at ('~',PROMPT [I]) + 1,1))
endif
// ? 'N_PROMPT[I]', N_PROMPT[I],'HOTKEY[I]',HOTKEY[I]
? 'H_PROMPT[I]', H_PROMPT[I],'H_POS[I]', H_POS[I]
WAIT
next I
I := if (INICIO <> nil,INICIO,1)
setcancel (.t.)
set (_SET_CURSOR,S_CURSOR)
return TECLA
Podem observar que além de ter excluído algumas linhas que pertencem ao INKEY() acrescentei as seguintes variáveis públicas:
Código: Selecionar todos
public H_PROMPT := aclone (PROMPT),;
H_N_PROMPT := len (ELEM),;
H_I := I,;
H_J := J,;
H_BLOCO := BLOCO,;
H_POS := H_HOTKEY := POS
E, por que delas? Fiz pensando no seguinte: que após a função MENU_HORIZONTAL() ser concluída e pela função anterior chamar a função MENU_VERTICAL() eu não perca esses valores que são públicos e comuns a tudo que eu usar daqui pra frente.
Veja(m) como ficou a minha função MENU_VERTICAL() a partir de agora:
*MENU_VERTICAL:
Código: Selecionar todos
function MENU_VERTICAL (LIN1,COL1,ELEM,BLOCO,IND_HELP,INICIO)
memvar K_HELP,K_UTIL,K_CNS
local I := 1,;
J := 1,;
N_PROMPT := len (ELEM),;
PROMPT := aclone (ELEM),;
HOTKEY := array (len (ELEM)),;
TECLA := 1,;
S_CURSOR := set (_SET_CURSOR),;
COMPL := 0
public V_PROMPT := aclone (PROMPT),;
V_N_PROMPT := len (ELEM),;
V_I := I,;
V_J := J,;
V_BLOCO := BLOCO
afill (HOTKEY,'')
set cursor off
if LIN1 = 1
LIN1++
endif
FORM_PROMPT (PROMPT)
COMPL := MAX_ELEM_VETOR (PROMPT)
for I := 1 to N_PROMPT
PROMPT [I] := if (at ('~',PROMPT [I]) = 0,padr (PROMPT [I],COMPL),padr (PROMPT [I],COMPL+1))
? 'PROMPT[I]', PROMPT[I],'HOTKEY[I]',HOTKEY[I]
? 'V_BLOCO [I],LIN1 + I + 1,COL1 + 1',V_BLOCO [I] // ,LIN1 + I + 1,COL1 + 1
WAIT
next I
I := if (INICIO <> nil,INICIO,1)
// SHOW WINDOW F1
// MAXIMIZE WINDOW F1
DEFINE WINDOW F2 ;
AT 0,0 ;
WIDTH 800 HEIGHT 600 ;
TITLE 'SiCCoSV - SISTEMA DE CONTROLE COMERCIAL DE ORDENS DE SERVIÇO VEICULAR' ;
FONT 'Arial' SIZE 10 ;
CHILD // ; // NÃO ACEITOU OUTRA TELA MAIN POIS NO pra funcionar CONSOLE e GRÁFICO juntos foi necessário criar primeiramente um F1 que é destruído em seguida através das funções HIDE WINDOW F1 e RELEASE WINDOW F1.
DEFINE MAIN MENU
for H_I := 1 to H_N_PROMPT
// POPUP H_POS [H_I] := len (H_PROMPT [H_I - 1]) + H_POS [H_I - 1] + if (at ('~',H_PROMPT [H_I]) = 0,1,0) - 1 // NÃO DEU CERTO, mudei pela linha abaixo
POPUP H_PROMPT [H_I]
for V_I := 1 to V_N_PROMPT
// MENUITEM V_PROMPT [V_I] := if (at ('~',V_PROMPT [V_I]) = 0,padr (V_PROMPT [V_I],COMPL),padr (V_PROMPT [V_I],COMPL+1)) ACTION eval (V_BLOCO [V_I],LIN1 + V_I + 1,COL1 + 1) // NÃO DEU CERTO, mudei pela linha abaixo
MENUITEM V_PROMPT [V_I] // ACTION eval (V_BLOCO [V_I],LIN1 + V_I + 1,COL1 + 1)
next V_I
END POPUP
next H_I
DEFINE TOOLBAR ToolBar_1 BUTTONSIZE 45,40 IMAGESIZE 22,22 FONT 'Arial' SIZE 8 FLAT
BUTTON Button_1 CAPTION 'Clientes' PICTURE 'button4.bmp' ACTION MsgInfo('Click! 1')
BUTTON Button_2 CAPTION 'OSV' PICTURE 'button5.bmp' WHOLEDROPDOWN
BUTTON Button_3 CAPTION 'Baixar' PICTURE 'button6.bmp' ACTION MsgInfo('Click! 3') DROPDOWN
BUTTON Button_4 CAPTION 'Extrato ' PICTURE 'button6.bmp' ACTION MsgInfo('Click! 3') DROPDOWN
END TOOLBAR
END MENU
DEFINE CONTEXT MENU
ITEM 'Item 1' ACTION MsgInfo ('Item 1')
ITEM 'Item 2' ACTION MsgInfo ('Item 2')
SEPARATOR
ITEM 'Item 3' ACTION MsgInfo ('Item 3')
END MENU
END WINDOW
CENTER WINDOW F2
ACTIVATE WINDOW F2
// MAXIMIZE WINDOW F2
set (_SET_CURSOR,S_CURSOR)
return TECLA
Podem observar como na função MENU_HORIZONTAL() que tirei algumas linhas do INKEY() e acrescentei as mesmas variáveis públicas só que com os diferenciais:
H_ pertencem ao MENU_HORIZONTAL
V_ pertencem ao MENU_VERTICAL
Então, essas duas funções não estão funcionando corretamente, apesar do MENU ser criado. Mas, como disse, que tudo parte da primeira função de criação do MENU que é a MCI10000. Aí, que mora o problema.
Se no meu atual código em MODO CONSOLE todo o MENU fosse montado de uma única vez acredito que seria mais fácil, mas, como para economizar memória e o aplicativo na época que comia muita memória RAM da pouca que existia (há 15 ou 20 anos atrás, MSDOS, win 9x/ME) então criei vários módulos MCI10000, MCI10001, MCI10002, MCI10030, que são divididos em 2 tipos:
1 - MCI10nnn para um conjunto de SUB-MENUs dentro de CADASTROS ou CONSULTAS ou RELATÓRIOS, ou seja, um MENU dentro de outro MENU. Nesse caso, para por exemplo:
MENU CADASTROS:
SUB-MENU CONTAS A PAGAR /A RECEBER:
SUB-MENU CONTAS A RECEBER:
2 - MCI10nnn para o MENU final propriamente dito e que executa por exemplo um cadastro de clientes ou uma VENDA. Exemplo:
MENU CADASTROS:
SUB-MENU CONTAS A PAGAR /A RECEBER:
SUB-MENU CONTAS A RECEBER:
VENDAS.
Bom, diante do exaustivamente exposto, preciso de um código fonte que permita que o MENU seja montado de acordo com o perfil do usuário, pois do jeito tradicional já consegui, só que o MENU fica liberado para todos os usuários e não é o meu caso, pois um exemplo desse MENU já fiz e não gostei, veja(m):
*MENU_POPUP:
Código: Selecionar todos
DEFINE WINDOW F2 ;
AT 0,0 ;
WIDTH 800 HEIGHT 600 ;
TITLE 'SiCCoSV - SISTEMA DE CONTROLE COMERCIAL DE ORDENS DE SERVIÇO VEICULAR' ;
FONT 'Arial' SIZE 10 ;
CHILD
DEFINE MAIN MENU
POPUP 'Cadastros'
POPUP 'Orçamentos'
ITEM 'Orçamentos' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Orçamento Simplificado' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Ordem de Serviço Veicular' ACTION PCI10043 ()
END POPUP
POPUP 'Contas a Pagar / a Receber'
POPUP 'Contas a Pagar'
ITEM 'Incluir' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Baixar' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Contas' ACTION MsgInfo ('Item 3.3.3')
END POPUP
POPUP 'Contas a Receber'
ITEM 'Prestações Antigas' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Cheques Pré Datados' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Baixar' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Condições de Pagamento' ACTION MsgInfo ('Item 3.3.3')
END POPUP
POPUP 'Caixa'
ITEM 'Movimentos' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Extrato do Dia' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Fechamento do Dia' ACTION MsgInfo ('Item 3.3.3')
END POPUP
END POPUP
POPUP '&Clientes'
ITEM '&Clientes' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Cl&assificações do Cliente' ACTION MsgInfo ('Item 3.3.2')
END POPUP
ITEM 'Fornecedores' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Produtos / Serviços'
POPUP 'Produtos'
ITEM 'Grupos' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Seções' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Produtos' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Compras para o Estoque' ACTION MsgInfo ('Item 3.3.3')
END POPUP
POPUP 'Serviços'
ITEM 'Serviços' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Veículos' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Dados do Veículo do Cliente' ACTION MsgInfo ('Item 3.3.3')
END POPUP
END POPUP
POPUP 'Configurações'
ITEM 'Empresas' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Mecânicos/Lanterneiros' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Operadores' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Senhas' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Parâmetros' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Excluir Informações Antigas' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Sobre o SiCCoSV v.4.01' ACTION MsgInfo ('Item 3.3.3')
END POPUP
END POPUP
POPUP 'Consultas'
POPUP 'Ordem de Serviço Veicular'
ITEM 'OSV em Aberto' ACTION MsgInfo ('Item 3.3.1')
ITEM 'OSV Conclusas' ACTION MsgInfo ('Item 3.3.2')
ITEM 'OSV Conclusas - Placa/Nome Cliente' ACTION MsgInfo ('Item 3.3.3')
END POPUP
ITEM 'Sobre o SiCCoSV v4.01' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Produtos'
ITEM 'Em Estoque' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Sugestão de Compras' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Contas' ACTION MsgInfo ('Item 3.3.3')
END POPUP
ITEM 'Fornecedores' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Clientes'
ITEM 'Clientes' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Informação Cadastral' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Contas a Pagar / a Receber'
POPUP 'Contas a Pagar'
POPUP 'Em Aberto'
ITEM 'Por Documento' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Fornecedor' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Conta' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Em Atraso' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Pagas'
ITEM 'Por Fornecedor' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Conta' ACTION MsgInfo ('Item 3.3.1')
END POPUP
END POPUP
POPUP 'Contas a Receber'
POPUP 'Em Aberto'
ITEM 'Por Documento' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Cliente' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Em Atraso' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Recebidas'
ITEM 'Por Cliente' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
END POPUP
END POPUP
POPUP 'Movimentos Bancários'
ITEM 'Por Conta' ACTION MsgInfo ('Item 3.3.1')
END POPUP
END POPUP
END POPUP
POPUP 'Relatórios'
ITEM 'Impressão de Cheques' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Produtos'
ITEM 'Produtos' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Grupo' ACTION MsgInfo ('Item 3.3.2')
ITEM 'Tabela de Preços' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Completo' ACTION MsgInfo ('Item 3.3.3')
ITEM 'Lista Preços' ACTION MsgInfo ('Item 3.3.3')
END POPUP
POPUP 'Fornecedores'
ITEM 'Fornecedores por Nome' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Fornecedores por Código' ACTION MsgInfo ('Item 3.3.1')
END POPUP
ITEM 'Clientes' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Contas a Pagar / a Receber'
POPUP 'Contas a Pagar'
POPUP 'Em Aberto'
ITEM 'Por Fornecedor' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Conta' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Em Atraso' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Pagas'
ITEM 'Por Fornecedor' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Conta' ACTION MsgInfo ('Item 3.3.1')
END POPUP
END POPUP
POPUP 'Contas a Receber'
ITEM 'Por Operador' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Em Aberto'
ITEM 'Por Cliente' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Em Atraso' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Recebidas'
ITEM 'Por Cliente' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Operador' ACTION MsgInfo ('Item 3.3.1')
END POPUP
END POPUP
ITEM 'E&xtrato' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Vendedor' ACTION MsgInfo ('Item 3.3.1')
POPUP 'Movimentos Bancários'
ITEM 'Por Conta' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Caixa'
ITEM 'Movimento Diário' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Caixa Por Operador' ACTION MsgInfo ('Item 3.3.1')
END POPUP
POPUP 'Vendas'
ITEM 'A Vista por Operador' ACTION MsgInfo ('Item 3.3.1')
ITEM 'A Prazo por Operador' ACTION MsgInfo ('Item 3.3.1')
ITEM 'A Vista no Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'A Prazo no Período' ACTION MsgInfo ('Item 3.3.1')
ITEM 'Por Vendedor' ACTION MsgInfo ('Item 3.3.1')
END POPUP
END POPUP
END POPUP
FINALMENTE, espero não ter complicado demais, tentando explicar minhas dúvidas e questionamentos.
Mas, que não seja apenas didático e, sim, ajuda a outros companheiros como eu que estão ingressando agora no mundo 32/64 bits e principalmente GUI/GRÁFICO.
Que, alguém como o PC, TOLEDO, HASSE, QUINTAS, EOLO, SEGYCOM, etc, sem esquecer dos demais que aqui não mencionei possam nos ajudar com esse quebra cabeças.
Se até lá, eu consegui pensar nalguma solução, postarei a todos aqui!