Sistema automático de menus

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

yugi386
Usuário Nível 2
Usuário Nível 2
Mensagens: 82
Registrado em: 24 Jul 2008 10:36
Localização: Minas Gerais

Sistema automático de menus

Mensagem por yugi386 »

Saudações!

Para chamar o sono resolvi criar esta função de criação de menu completo da aplicação.
É possível criar um menu completo com 5 níveis (1 horizontal e 4 verticais). Basta entrar com uma matriz para indicar as opções de menu e a função calcula o resto. É possível ainda corrigir a posição de qualquer menu vertical nos níveis 2, 3 ou 4 para fixa-los em uma posição melhor na tela.

Vejam:

Imagem

Imagem

Imagem

Imagem

Imagem

Imagem

O código completo encontra-se em anexo.

[]s

Yugi
Anexos
menu.zip
(8.88 KiB) Baixado 900 vezes
yugi386
Usuário Nível 2
Usuário Nível 2
Mensagens: 82
Registrado em: 24 Jul 2008 10:36
Localização: Minas Gerais

Sistema automático de menus

Mensagem por yugi386 »

Pequena adaptação na função ylib_mainMenu para aceitar voltar o menu com <ESC>. Para funcionar é necessário baixar o pacote anterior e substituir a referida função em ylib.prg. Foram corrigidos alguns pequenos bugs e também foram acrescentados recursos para navegação com menu aberto em nível 1 se não houverem menus horizontais desabilitados. Vejam:

Imagem

O Código:

Código: Selecionar todos

/** 
--------------------------------------------------------------------------------------------------------------------
Descrição:
[007] Cria um Menu Completo (Horizontal + Vertical Multinível)
Parâmetros:
1. l1...........: Linha inicial do Menu
2. c1...........: Coluna inicial do Menu
3. opcoes.......: Matriz com opções e mensagens de status do Menu, opção habilitado/desabilitado, deslocamento(linha e coluna do menu)
4. corMenu......: Cor do menu padrão e selecionado
5. espacamento..: Espaçamento entre os menus
6. lstatus......: linha de mensagem de status
7. cormenudesabilitado.: cor do menu que estiver desabilitado
8. tipoSombra...: pode ser 0, 1, 2, 3, 4, respectivamente, sem sombra, sombra na posição inferior esquerdo, inferior direito, superior esquerdo e superior direito
9. corsombra....: cor da sombra (padrao n+/n)
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_mainMenu(l1,c1,opcoes,corMenu,espacamento,lstatus,corMenuDesabilitado,tipoSombra,corSombra)
	local contador := 0, ct:=0, opc:= 0, mHorizontal:={}, mVertical:={}, ct2, tela, ret:="", telaTotal, maxMenu := 0,;
        tagSubmenu := " " + chr(226) + chr(150) + chr(182) + " ", escolhaOpcao:=array(5), tam, tamMenu:=array(4), nivel,;
        tela1, tela2, tela3, tela4
    private navega:=0

save screen to telaTotal
nivel := 0  //  variavel para controlar o retorno do menu via <ESC>

do while.t.
    if nivel <> 0   //  controla a posicao dos menus quando voltamos com esc
        marca := .t.
    else
        marca:=.f.
    endif
    navega:=0

    if nivel == 0   //  nivel inicial - Menu Horizontal

            restore screen from telaTotal

            // reiniciando os gerenciadores de retorno e os vetores temporários...
            ret:=""
            mHorizontal:={}
            mVertical:={}

            // Pegando os menus horizontais:
            for ct:= 1 to len(opcoes)
                if ylib_len(alltrim(opcoes[ct][1])) <> 0
                    aadd(mHorizontal,{opcoes[ct][1],opcoes[ct][2],opcoes[ct][3]})
                endif
            next

            opcoesHorizontais := len(mHorizontal)   //  total de opcoes do menu horizontal...

            opc := ylib_criaMenu(l1,c1,mHorizontal,corMenu,espacamento,lstatus,corMenuDesabilitado)

            escolhaopcao[1] = opc   //  guarda o menu escolhido
            ret := alltrim(str(opc))    //  gerencia o retorno da função

            if opc == 0
                exit
            endif

            nivel := 1  //  nivel é igual a um
    endif   //  fim do nivel = 0 - inicial menu horizontal

     // gerenciando o menu vertical de nível 1 =====================================================================
     // Pegando os menus verticais

    if nivel <= 1

        contador := 0
         for ct2:= 1 to len(opcoes)
            if ylib_len(alltrim(opcoes[ct2][1])) <> 0
                ++ contador
            endif

            // verificando a opção escolhida
            if contador == escolhaopcao[1]
                if ylib_len(alltrim(opcoes[ct2][1])) == 0
                    if ylib_len(alltrim(opcoes[ct2][2])) <> 0
                        aadd(mVertical,{opcoes[ct2][2],opcoes[ct2][3],opcoes[ct2][4]})
                    else
                        if !(tagSubmenu $ mVertical[len(mVertical)][1]) 
                            mVertical[len(mVertical)][1] += tagSubmenu  //  verificando submenus vinculados
                        endif
                    endif
                endif
            endif
       next

        // Verificando a posição do Menu Vertical
        xc1 = c1
        for ct:= 2 to escolhaopcao[1]
            xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
            if ct==escolhaopcao[1]
                exit
            endif
        next

        tamMenu[1] :=0  //  tamanho menu
        for ct:=1 to len(mVertical)
            tamMenu[1]:=max(tamMenu[1],ylib_len(mVertical[ct][1]))
        next
        tamMenu[1]:=tamMenu[1]+4

        save screen to tela1

        set key 4 to ylib_avancarMenuHorizontal()
        set key 19 to ylib_voltarMenuHorizontal()

            opc := ylib_criaMenuVertical(l1+1,xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
            escolhaopcao[2] = opc   //  guarda o menu escolhido

        set key 4 to
        set key 19 to

        if lastkey() == 27  .and. navega==1
            keyboard replicate(chr(4),escolhaopcao[1])+chr(13)
            nivel := 0
            loop
        endif

        if lastkey() == 27  .and. navega==2
            keyboard replicate(chr(4),escolhaopcao[1]-1)+replicate(chr(19),1)+chr(13)
            nivel := 0
            loop
        endif

        ret += "."+alltrim(str(opc))    //  gerencia o retorno da função

     // Verificando a opção escolhida (excluindo separadores de menu)
        contador := 0
        for ct:= 1 to len(mVertical)
            if (alltrim(mVertical[ct][1]) <> "-")
                ++contador
            endif
            if opc == contador
                verifica := mVertical[ct][1]
                exit
            endif
        next

        if opc == 0     //  tecla ESC
            restore screen from tela1
            nivel := 0  //  retorna para o nivel 0 inicial
            loop
        else
            if !(tagSubmenu $ verifica)    //  se não tem um submenu cai fora
                exit    
            endif
        endif

        nivel := 2

    endif   // fim nivel = 1

     // gerenciando o menu vertical de nível 2 =====================================================================
     // Pegando os menus verticais

    if nivel <= 2   //  nivel 2 do menu

            if marca =.f.
                mverticalOLD:= mVertical
            endif

            mVertical := {}
            contador := 0

             for ct2:= 1 to len(opcoes)
                if ylib_len(alltrim(opcoes[ct2][1])) <> 0
                    ++ contador
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[1]
                    ct:= ct2
                    exit
                endif
           next

            contador:=0
             for ct2:= (ct+1) to len(opcoes)
                if ylib_len(alltrim(opcoes[ct2][2])) <> 0 .and. alltrim(opcoes[ct2][2]) <> "-"
                    ++ contador
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[2]

                    if ct2 > len(opcoes)  //  Verifica o estouro da matriz
                        exit
                    endif

                    if ylib_len(alltrim(opcoes[ct2][2])) == 0
                        if upper(transform(opcoes[ct2][3],"L")) <> "T" .and. upper(transform(opcoes[ct2][3],"L")) <> "F"
                            if ylib_len(alltrim(opcoes[ct2][3])) <> 0
                                aadd(mVertical,{opcoes[ct2][3],opcoes[ct2][4],opcoes[ct2][5],opcoes[ct2][6]})
                            else
                                if !(tagSubmenu $ mVertical[len(mVertical)][1]) 
                                    mVertical[len(mVertical)][1] += tagSubmenu  //  verificando submenus vinculados
                                endif
                            endif
                        endif
                    endif
                endif
           next

            // Verificando a posição do Menu Vertical
            xc1 = c1
            for ct:= 2 to escolhaopcao[1]
                xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
            next

            // Verificando o tamanho do primeiro menu vertical
            tam:= 0
            tamvertical :=0
            contador:=0

            for ct:= 1 to len(mVerticalOLD)
                tam:= max(tam,ylib_len(mVerticalOLD[ct][1]))

               if ylib_len(alltrim(mVerticalOLD[ct][1])) <> 0 .and. alltrim(mVerticalOLD[ct][2]) <> "-"
                    ++ contador
                endif

                if contador <= escolhaopcao[2] .and. mVerticalOLD[ct][1] == "-"
                    ++tamvertical
                endif
            next

            deslocamento = mVertical[1][4]
            // xc1 += int(tam/2.5) + deslocamento[2] //  posicao do menu vertical 2
            xc1 += int(tamMenu[1]/4) + deslocamento[2]

            tamMenu[2] :=0  //  tamanho menu
            for ct:=1 to len(mVertical)
                tamMenu[2]:=max(tamMenu[2],ylib_len(mVertical[ct][1]))
            next
            tamMenu[2]:=tamMenu[2]+4

            save screen to tela2

                opc := ylib_criaMenuVertical(l1+1+escolhaopcao[2]+tamVertical+1+deslocamento[1],xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
                escolhaopcao[3] = opc   //  guarda o menu escolhido

            ret += "."+alltrim(str(opc))    //  gerencia o retorno da função

         // Verificando a opção escolhida (excluindo separadores de menu)
            contador := 0
            for ct:= 1 to len(mVertical)
                if (alltrim(mVertical[ct][1]) <> "-")
                    ++contador
                endif
                if opc == contador
                    verifica := mVertical[ct][1]
                    exit
                endif
            next

            if opc == 0     //  tecla ESC
                restore screen from tela2   
                // Rotina para voltar ao menu anterior usando ESC
                mVertical = {}
                nivel := 1
                for ct:= 1 to 2    
                    tmp := rat(".",ret)
                    ret := substr(ret,1,tmp-1)
                next
                restore screen from tela1
                loop
            else
                if !(tagSubmenu $ verifica)    //  se não tem um submenu cai fora
                    exit    
                endif
            endif

                nivel := 3
    endif   //  fim do nivel 2 do menu

     // gerenciando o menu vertical de nível 3 =====================================================================
     // Pegando os menus verticais

    if nivel <= 3       //  nivel 3 do menu

            if marca =.f.
                mverticalOLD:= mVertical
            endif

            mVertical := {}
            contador := 0

             for ct2:= 1 to len(opcoes)     // primeira opcao
                if ylib_len(alltrim(opcoes[ct2][1])) <> 0
                    ++ contador
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[1]
                    ct:= ct2
                    exit
                endif
             next

            contador:=0     //  segunda opcao
            for ct2:= (ct+1) to len(opcoes)
                if ylib_len(alltrim(opcoes[ct2][2])) <> 0 .and. alltrim(opcoes[ct2][2]) <> "-"
                    ++ contador
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[2]
                    ct:= ct2
                    exit
                endif
             next

            contador:=0
             for ct2:= (ct+1) to len(opcoes)    //  terceira opcao
                if upper(transform(opcoes[ct2][3],"L")) <> "T" .and. upper(transform(opcoes[ct2][3],"L")) <> "F"
                    if ylib_len(alltrim(opcoes[ct2][3])) <> 0 .and. alltrim(opcoes[ct2][3]) <> "-"
                        ++ contador
                    endif
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[3]

                    if ct2 > len(opcoes)  //  Verifica o estouro da matriz
                        exit
                    endif

                    if ylib_len(alltrim(opcoes[ct2][3])) == 0
                         if !isarray(opcoes[ct2][4])
                             if upper(transform(opcoes[ct2][4],"L")) <> "T" .and. upper(transform(opcoes[ct2][4],"L")) <> "F"
                                if ylib_len(alltrim(opcoes[ct2][4])) <> 0
                                    aadd(mVertical,{opcoes[ct2][4],opcoes[ct2][5],opcoes[ct2][6],opcoes[ct2][7]})
                                else
                                    if !(tagSubmenu $ mVertical[len(mVertical)][1]) 
                                        mVertical[len(mVertical)][1] += tagSubmenu  //  verificando submenus vinculados
                                    endif
                                endif
                            endif
                        endif
                    endif
                endif
           next

            // Verificando a posição do Menu Vertical
            xc1 = c1
            for ct:= 2 to escolhaopcao[1]
                xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
            next

            // Verificando o tamanho do primeiro menu vertical
            tam:= 0
            tamvertical :=0
            contador:=0

            for ct:= 1 to len(mVerticalOLD)
                tam:= max(tam,ylib_len(mVerticalOLD[ct][1]))

               if ylib_len(alltrim(mVerticalOLD[ct][1])) <> 0 .and. alltrim(mVerticalOLD[ct][2]) <> "-"
                    ++ contador
                endif

                if contador <= escolhaopcao[2] .and. mVerticalOLD[ct][1] == "-"
                    ++tamvertical
                endif
            next

            deslocamento = mVertical[1][4]
            // xc1 += (int(tam/2.5) * 2) +deslocamento[2] //+nTam //  posicao do menu vertical 2
            xc1 += int((tamMenu[1]/4)+(tamMenu[2]/4)) + deslocamento[2]

           tamMenu[3] :=0  //  tamanho menu
            for ct:=1 to len(mVertical)
                tamMenu[3]:=max(tamMenu[3],ylib_len(mVertical[ct][1]))
            next
            tamMenu[3]:=tamMenu[3]+4

            save screen to tela3

                opc := ylib_criaMenuVertical(l1+1+escolhaopcao[2]+escolhaopcao[3]+tamVertical+2+deslocamento[1],xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
                escolhaopcao[4] = opc   //  guarda o menu escolhido

            ret += "."+alltrim(str(opc))    //  gerencia o retorno da função

         // Verificando a opção escolhida (excluindo separadores de menu)
            contador := 0
            for ct:= 1 to len(mVertical)
                if (alltrim(mVertical[ct][1]) <> "-")
                    ++contador
                endif
                if opc == contador
                    verifica := mVertical[ct][1]
                    exit
                endif
            next

            if opc == 0     //  tecla ESC
                restore screen from tela3
                 mVertical = {}
                  nivel := 2
                  for ct:= 1 to 2    
                      tmp := rat(".",ret)
                      ret := substr(ret,1,tmp-1)
                  next
                   restore screen from tela2
                  loop
            else
                if !(tagSubmenu $ verifica)    //  se não tem um submenu cai fora
                    exit    
                endif
            endif

            menu := 4
    endif   //  fim do nivel 3 do menu

     // gerenciando o menu vertical de nível 4 =====================================================================
     // Pegando os menus verticais

    if nivel <= 4   //  nivel 4 do menu

            if marca =.f.
                mverticalOLD:= mVertical
            endif

            mVertical := {}
            contador := 0

             for ct2:= 1 to len(opcoes)     // primeira opcao
                if ylib_len(alltrim(opcoes[ct2][1])) <> 0
                    ++ contador
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[1]
                    ct:= ct2
                    exit
                endif
             next

            contador:=0     //  segunda opcao
            for ct2:= (ct+1) to len(opcoes)
                if ylib_len(alltrim(opcoes[ct2][2])) <> 0 .and. alltrim(opcoes[ct2][2]) <> "-"
                    ++ contador
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[2]
                    ct:= ct2
                    exit
                endif
             next

            contador:=0     //  terceira opcao
            for ct2:= (ct+1) to len(opcoes)
                if upper(transform(opcoes[ct2][3],"L")) <> "T" .and. upper(transform(opcoes[ct2][3],"L")) <> "F"
                    if ylib_len(alltrim(opcoes[ct2][3])) <> 0 .and. alltrim(opcoes[ct2][3]) <> "-"
                        ++ contador
                    endif
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[3]
                    ct:= ct2
                    exit
                endif
             next

            contador:=0
             for ct2:= (ct+1) to len(opcoes)    //  quarta opcao
                if !isarray(opcoes[ct2][4])
                    if upper(transform(opcoes[ct2][4],"L")) <> "T" .and. upper(transform(opcoes[ct2][4],"L")) <> "F"
                        if ylib_len(alltrim(opcoes[ct2][4])) <> 0 .and. alltrim(opcoes[ct2][4]) <> "-"
                            ++ contador
                        endif
                    endif
                endif

                // verificando a opção escolhida
                if contador == escolhaopcao[4]

                    if ct2 > len(opcoes)  //  Verifica o estouro da matriz
                        exit
                    endif

                    if ylib_len(alltrim(opcoes[ct2][4])) == 0
                         if !isarray(opcoes[ct2][4])
                             if upper(transform(opcoes[ct2][5],"L")) <> "T" .and. upper(transform(opcoes[ct2][5],"L")) <> "F"
                                if ylib_len(alltrim(opcoes[ct2][5])) <> 0
                                    aadd(mVertical,{opcoes[ct2][5],opcoes[ct2][6],opcoes[ct2][7],opcoes[ct2][8]})
                                else
                                    if !(tagSubmenu $ mVertical[len(mVertical)][1]) 
                                        mVertical[len(mVertical)][1] += tagSubmenu  //  verificando submenus vinculados
                                    endif
                                endif
                            endif
                        endif    
                    endif
                endif
           next

            // Verificando a posição do Menu Vertical
            xc1 = c1
            for ct:= 2 to escolhaopcao[1]
                xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
            next

            // Verificando o tamanho do primeiro menu vertical
            tam:= 0
            tamvertical :=0
            contador:=0

            for ct:= 1 to len(mVerticalOLD)
                tam:= max(tam,ylib_len(mVerticalOLD[ct][1]))

               if ylib_len(alltrim(mVerticalOLD[ct][1])) <> 0 .and. alltrim(mVerticalOLD[ct][2]) <> "-"
                    ++ contador
                endif

                if contador <= escolhaopcao[2] .and. mVerticalOLD[ct][1] == "-"
                    ++tamvertical
                endif
            next

            deslocamento = mVertical[1][4]
            // xc1 += (int(tam/2.5) * 4) + deslocamento[2] // +int(nTam/2) //  posicao do menu vertical 3
            xc1 += int((tamMenu[1]/4)+(tamMenu[2]/4)+(tamMenu[3]/4)) + deslocamento[2]

           tamMenu[4] :=0  //  tamanho menu
            for ct:=1 to len(mVertical)
                tamMenu[4]:=max(tamMenu[4],ylib_len(mVertical[ct][1]))
            next
            tamMenu[4]:=tamMenu[4]+4

            save screen to tela4

                opc := ylib_criaMenuVertical(l1+1+escolhaopcao[2]+escolhaopcao[3]+escolhaopcao[4]+tamVertical+3+deslocamento[1],xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
                escolhaopcao[5] = opc   //  guarda o menu escolhido

            ret += "."+alltrim(str(opc))    //  gerencia o retorno da função

         // Verificando a opção escolhida (excluindo separadores de menu)
            contador := 0
            for ct:= 1 to len(mVertical)
                if (alltrim(mVertical[ct][1]) <> "-")
                    ++contador
                endif
                if opc == contador
                    verifica := mVertical[ct][1]
                    exit
                endif
            next

            if opc == 0     //  tecla ESC
                restore screen from tela4
                mVertical = {}
                  nivel := 3
                  for ct:= 1 to 2    
                      tmp := rat(".",ret)
                      ret := substr(ret,1,tmp-1)
                  next
                    restore screen from tela3
                  loop
            else
                if !(tagSubmenu $ verifica)    //  se não tem um submenu cai fora
                    exit    
                endif
            endif

    endif   //  fim do nivel 4 do menu

    exit    //  retirar para mais níveis...
enddo

return ret

//==================================================================================
function isarray(vet)   //  verifica se a entrada e um vetor
local ret := .t., ct

    BEGIN SEQUENCE WITH {| oErr | Break( oErr ) }
        ct := vet[1]
    RECOVER
        ret:= .F.
    END SEQUENCE

return ret
//===================================================================================
func ylib_avancarMenuHorizontal()
    keyboard chr(27)
    navega:=1
return NIL
// ==================================================================================
func ylib_voltarMenuHorizontal()
    keyboard chr(27)
    navega:=2
return NIL
//===================================================================================
[]s

Yugi
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Sistema automático de menus

Mensagem por rochinha »

:{ :xau
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
yugi386
Usuário Nível 2
Usuário Nível 2
Mensagens: 82
Registrado em: 24 Jul 2008 10:36
Localização: Minas Gerais

Sistema automático de menus

Mensagem por yugi386 »

Saudações!

Mais alguns bugs encontrados e corrigidos.
Agora temos os seguintes recursos:

1. É possível criar um menu a partir de uma matriz [N][M].
2. O Menu pode ter até 5 níveis (1 horizontal e 4 verticais)
3. É possível desabilitar um ou mais menus horizontais ou verticais.
4. É possível o uso da tecla <ESC> para retornar ao menu anterior.
5. É possível o uso das setas esquerda e direita para navegar com o menu aberto no nível 2.
6. Mesmo que um ou mais menus horizontais estejam desabilitados o menu rotativo funciona normalmente.
7. Foi corrigido o problema da sombra quando se utiliza caracteres especiais em UTF-8.
8. Suporte para menus verticais (até 35 itens) com hotkeys automáticos.
9. Suporte a separadores de menu para menus verticais.
10. Supondo que exista uma opção de menu para cada procedimento é possível gerenciar 32.768 opções com 8 menus em cada nível.

Pode ser que ainda existam alguns bugs mas consegui eliminar todos os mais críticos, eu acho.....

Eis o novo pacote em anexo.

[]s

Yugi
Anexos
menu.zip
(9.71 KiB) Baixado 1094 vezes
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Sistema automático de menus

Mensagem por janio »

Showwwww!
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
lugab
Colaborador
Colaborador
Mensagens: 843
Registrado em: 19 Mai 2009 15:58

Sistema automático de menus

Mensagem por lugab »

Que menu show de bola !!!

Pena que não da pra aproveirar, ele é do tempo em q se podia usar libs de terceiros ..

Tem alguma alma generosa aqui no fórum pra compartilhar os fontes de um menu similar pra harbour ??

Eu uso hb 3.2, modo console
lugab
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Sistema automático de menus

Mensagem por JoséQuintas »

José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
lugab
Colaborador
Colaborador
Mensagens: 843
Registrado em: 19 Mai 2009 15:58

Sistema automático de menus

Mensagem por lugab »

Valeu, professor Quintas, esse também é 10 e aparenta ser mais fácil de implementar por leigos

Vou ver se consigo compilar e se possível adotar cores pasteis, tipo as do colega Yugi386 acima

Grato, mais uma vez
lugab
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Sistema automático de menus

Mensagem por alxsts »

Olá!

Outra opção é usar as classes de criação de menus do próprio Harbour, como exemplificado no tópico TopBarMenu().
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Sistema automático de menus

Mensagem por JoséQuintas »

lugab escreveu:Vou ver se consigo compilar e se possível adotar cores pasteis, tipo as do colega Yugi386 acima
Cada cor está em uma função, então é só alterar cada uma.

SetColorNormal() - área de texto
SetColorMensagem() - área de mensagem
SetColorTitulo() - titulo da janela
SetColorBox()
SetColorTituloBox()
SetColorBorda() - o contorno dos box
SetColorFocus() - cor em destaque/posição atual
SetColorTraco() - Traço separador
SetColorTBrowseFrame() - Traços do TBrowse (não disponível no TBrowse do Harbour)
SetColorTBrowse() - Cores usadas em tbrowse

https://github.com/JoseQuintas/JoseQuin ... tcolor.prg

E se juntar com a rotina de mensagem, completa uma tela padrão, só definir as cores nas funções anteriores.

https://github.com/JoseQuintas/JoseQuin ... nsagem.prg
mensagem2.png
mensagem2.png (7.71 KiB) Exibido 9379 vezes
mensagem1.png
mensagem1.png (11.63 KiB) Exibido 9379 vezes
Mensagem( "texto" )
Mensagem( "texto", " 27" )
IF Mensagem( "texto", "S,N, 27" ) != "S"
IF Mensagem( "texto", "S,N", 1, 1 ) != "S"

Opções sem resposta, com resposta, central, com beep, etc.

E pode criar mensagens intermediárias pra simplificar ainda mais.

IF ! MsgYesNo( "Confirma" )
RETURN
ENDIF

FUNCTION MsgYesNo( cTexto ); RETURN Mensagem( "texto", "S,N", 1, 1 ) == "S"


Nota:
Não importa o tamanho da tela, pode ser 25 x 80, 40 x 100, 100 x 200, ou qualquer outra
Funciona também com GTWVG e multithread.

Esqueci de dizer: o menu já deixa a tela pronta para o módulo chamado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Sistema automático de menus

Mensagem por JoséQuintas »

Esta seria a tela que o módulo recebe, pronta pra uso.
Vém preenchida de acordo com o texto do menu.
subtela.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
lugab
Colaborador
Colaborador
Mensagens: 843
Registrado em: 19 Mai 2009 15:58

Sistema automático de menus

Mensagem por lugab »

Valeu, pessoal....
Já estou trabalhando no código pra testar as dicas

Muito obrigado !!!!!
lugab
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Sistema automático de menus

Mensagem por JoséQuintas »

É um exemplo exagerado, mas o mesmo estilo de construção de menu em HMG, e multithread.
Usa o mesmo array do exemplo anterior.
menuhmge.png

Código: Selecionar todos


MEMVAR fonte_Menu

#include 'minigui.ch'
#include "i_hmgcompat.ch"

FUNCTION main()

   //MyInit()
   hb_ThreadStart( { || Main2() } )
   hb_ThreadStart( { || Main2() } )
   hb_ThreadStart( { || Main2() } )
   hb_ThreadStart( { || Main2() } )
   hb_ThreadStart( { || Main2() } )
   Main2()
   //Inkey(1)

   RETURN NIL

FUNCTION Main2()

   LOCAL oMenu, cForm // aColors, oMenu

   cForm := "Tela" + StrZero( NextWindowNumber(), 6 )

   MyInit()

   DEFINE FONT font_1 FONTNAME 'tahoma' SIZE 10
   fonte_menu := GetFontHandle( 'font_1' )

   DEFINE WINDOW &cForm ;
         ; // at 0, 0 ;
         WIDTH 1024 ;
         HEIGHT 768 ;
         TITLE cForm ;
         ; // icon 'icone';
         ; //windowtype main;
         ;// noshow;
         ;//nosize;
         BACKCOLOR {0,0,0}
      DEFINE IMAGE img_wallpaper
         ROW 000
         COL 000
         HEIGHT 768
         WIDTH 1024
         PICTURE hb_cwd() + 'wallpaper.jpg'
         STRETCH .T.
      END IMAGE
      DEFINE MAIN MENU OF &cForm
         OMenu := MenuCria()
         MyCreateMenu( oMenu, 1 )
      END MENU
      ON KEY ESCAPE ACTION thiswindow.release
   END WINDOW
   CENTER WINDOW &cForm

   //&cForm..activate
   ACTIVATE WINDOW &cForm // DoMethod( &cForm, "Activate" )

   RETURN NIL

FUNCTION MyCreateMenu( oMenu, nLevel )

   LOCAL oElement

   FOR EACH oElement IN oMenu
      IF oElement[ 4 ] == NIL
         oElement[ 4 ] := hb_cwd() + "jose.bmp"
      ENDIF
      IF Len( oElement[ 2 ] ) > 0
         IF nLevel == 1
            DEFINE POPUP oElement[ 1 ] FONT fonte_Menu
         ELSE
            DEFINE POPUP oElement[ 1 ] FONT fonte_Menu IMAGE oELement[ 4 ]
         ENDIF
         MyCreateMenu( oElement[ 2 ], nLevel + 1 )
         END POPUP
      ELSE
         IF nLevel == 1
            MENUITEM oElement[ 1 ] ACTION NIL FONT fonte_menu
         ELSE
            MENUITEM oElement[ 1 ] ACTION NIL FONT fonte_menu IMAGE oElement[ 4 ]
         ENDIF
      ENDIF
   NEXT

   RETURN NIL

FUNCTION MyInit()

   REQUEST HB_CODEPAGE_PTISO

   Set( _SET_CODEPAGE, "PTISO" )
   Init()
   SET AUTOADJUST ON
   SET BROWSESYNC ON
   //SET CODEPAGE TO portuguese
   SET CENTERWINDOW RELATIVE DESKTOP
   SET CENTURY ON
   SET DATE BRITISH
   SET DELETED ON
   SET EPOCH TO Year( Date() ) - 90
   SET NAVIGATION EXTENDED
   SET MENUCURSOR FULL
   SET MENUITEM BORDER 3D
   SET MENUSEPARATOR SINGLE RIGHTALIGN
   SET MENUSTYLE EXTENDED
   SET TOOLTIPBALLOON ON
   SET WINDOW MAIN OFF

   RETURN NIL

FUNCTION NextWindowNumber()

   STATIC nValue := 0, xMutex := hb_MutexCreate()

   hb_MutexLock( xMutex )
   nValue += 1
   hb_MutexUnlock( xMutex )

   RETURN nValue
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Sistema automático de menus

Mensagem por JoséQuintas »

O mesmo estilo de menus no VB...
A IDE do VB não deixa...
( parece o editor da HMG, mas é do VB6 )
vb2.png
Então...
Se a IDE não deixa...
É só não usar a IDE... kkkk
vb1.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Sistema automático de menus

Mensagem por JoséQuintas »

Na prática, é igual o Yugi386 também fez.
Você cria um menu, e vai expandindo recursos.
Ficando do jeito que você gosta, é só adaptar pra outras LIBs/linguagens.

A vantagem de usar um único array, é que se quiser criar senhas/acessos, basta modificar o array.
A partir das senhas/acessos, elimina elementos do array.
Como a rotina de menus cria a partir do array, pronto, vai ter um menu conforme o acesso de cada usuário.

E pode usar o mesmo array pra configurar senhas, ou criar um índice para o aplicativo ou para o manual, etc.

O array é relativamente simples:

{ "nome", {}, "modulo" }

Toda opção tem nome, um array que pode ser vazio, e o nome do módulo a executar.
Se tem subopções, esse array vazio passa a ser um novo array, com o mesmo formato, para as sub-opções, e assim por diante.

E se o menu já tem o nome do módulo e a descrição, nada impede do menu criar uma janela já com essa descrição, que seria a janela para o módulo.

Eu uso isso faz tempo, não consigo imaginar algo mais fácil e prático.

- fechar todos os arquivos no menu: nunca mais esquecer de fechar arquivos
- salvar tela antes do módulo, e depois restaurar: tela sempre limpa
- uma variável com o nome do módulo, já pode ser usada no rodapé dos relatórios, ou pra uma rotina de help
- acrescentar quanto tempo demora pra voltar ao menu, já serve pra controle de uso de cada módulo

É tudo coisa que a gente quebraria a cabeça, e basta colocar no menu.
Nem se trata do fonte pra fazer isso, mas da facilidade que trás.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder