Carregar menu Dinamico e jogar na tela conforme modelo
Boa noite
Sou iniciante em Delphi, porem tenho grande conhecimento em Firebird, ja com alguns anos de experiencia.
Eu assisti uma video aula no site da Devmedia, postada pelo Renato Matos, onde ele da um exemplo de carregar um Menu dinamico e tambêm estou seguindo uma video aula do mesmo autor com o assunto "Delphi OOP", dentro destes conceitos, eu gostatia de carregar um Menu de Forma dinamica (buscando de uma tabela no Firebird) baseado na empresa que o usuario irá logar.
Por exemplo:
Tenho 3 tipos de sistema, 1 basico, 1 intermediário e 1 completo, a diferença entre as 3 opções, é a quantida de menu disponivel no sistema.
Exemplificando:
Na opção 1 (Básico) o meu cliente terá apenas o Modúlo Contas a Receber que este contem o cadastro de Clientes, Lançamentos das parcelas e o Modulo Vendas que contem a Tela de Vendas e Cadastros de Produtos.
Na opção 2 (Intermediário) terá alem dos modulos contidos na opção 1, mais os modulos do Contas a Pagar com suas opções, o Modulo de Bancos, com suas opções e assim por diante na opção 3.
O tipo da opção do sistema contratado esta informado na tabela de Empresas no firebird.
Fiz um exemplo simbolico da Tela Inicial e abaixo a tela do Menu conforme eu gostaria de disponibilizar ao cliente.
No exemplo abaixo eu usei o ListView, não sei se é esta a melhor forma, mas pelo menos a disponização é importante para o produto que estou disponibilizando ao meu cliente.
Abaixo a tela do Menu:
Com esta configuração, ficará facil o acesso as opções, pois ele irá escolher o Modulo que se Encontra a Esquerda (Vendas, Caixa, etc) e do lado direito as opções do modulo (Cadastros, Relatórios, Movimentações, etc) que ele ira selecionar e escolher a opção que irá se abrir.
Sendo assim, ele irá escolher o modulo do lado esquerdo e do lado direito, ele irá mostrar a opção disponivel relacionada ao modulo.
Estes dados (Modulos e opções) eu gostaria de carregar conforme a opção informada no cadastro de empresa (tabela firebird), conforme o usuário logar e selecionar a empresa, ele irá trazer os modulos do menu e as opções do modulo.
Espero não ter abusado do meu primeiro chamado :D
Abraços,
Rogério.
Obs: Citei o listview, mas não precisa ser o mesmo, o importante para mim, é a flexibilidade do menu, ja que todas as opções estarão em apenas um banco de dados, disponibilizarei a opção conforme o cliente contratar (Basico, Intermediario e Completo) e a vizualização do mesmo para facilitar o manuseio do cliente, ja que eles reclamam muito dos MainMenus tradicionais.
Irei utilizar o Delphi 2009 e o Firebird 2.1.
Sou iniciante em Delphi, porem tenho grande conhecimento em Firebird, ja com alguns anos de experiencia.
Eu assisti uma video aula no site da Devmedia, postada pelo Renato Matos, onde ele da um exemplo de carregar um Menu dinamico e tambêm estou seguindo uma video aula do mesmo autor com o assunto "Delphi OOP", dentro destes conceitos, eu gostatia de carregar um Menu de Forma dinamica (buscando de uma tabela no Firebird) baseado na empresa que o usuario irá logar.
Por exemplo:
Tenho 3 tipos de sistema, 1 basico, 1 intermediário e 1 completo, a diferença entre as 3 opções, é a quantida de menu disponivel no sistema.
Exemplificando:
Na opção 1 (Básico) o meu cliente terá apenas o Modúlo Contas a Receber que este contem o cadastro de Clientes, Lançamentos das parcelas e o Modulo Vendas que contem a Tela de Vendas e Cadastros de Produtos.
Na opção 2 (Intermediário) terá alem dos modulos contidos na opção 1, mais os modulos do Contas a Pagar com suas opções, o Modulo de Bancos, com suas opções e assim por diante na opção 3.
O tipo da opção do sistema contratado esta informado na tabela de Empresas no firebird.
Fiz um exemplo simbolico da Tela Inicial e abaixo a tela do Menu conforme eu gostaria de disponibilizar ao cliente.
No exemplo abaixo eu usei o ListView, não sei se é esta a melhor forma, mas pelo menos a disponização é importante para o produto que estou disponibilizando ao meu cliente.
Abaixo a tela do Menu:
Com esta configuração, ficará facil o acesso as opções, pois ele irá escolher o Modulo que se Encontra a Esquerda (Vendas, Caixa, etc) e do lado direito as opções do modulo (Cadastros, Relatórios, Movimentações, etc) que ele ira selecionar e escolher a opção que irá se abrir.
Sendo assim, ele irá escolher o modulo do lado esquerdo e do lado direito, ele irá mostrar a opção disponivel relacionada ao modulo.
Estes dados (Modulos e opções) eu gostaria de carregar conforme a opção informada no cadastro de empresa (tabela firebird), conforme o usuário logar e selecionar a empresa, ele irá trazer os modulos do menu e as opções do modulo.
Espero não ter abusado do meu primeiro chamado :D
Abraços,
Rogério.
Obs: Citei o listview, mas não precisa ser o mesmo, o importante para mim, é a flexibilidade do menu, ja que todas as opções estarão em apenas um banco de dados, disponibilizarei a opção conforme o cliente contratar (Basico, Intermediario e Completo) e a vizualização do mesmo para facilitar o manuseio do cliente, ja que eles reclamam muito dos MainMenus tradicionais.
Irei utilizar o Delphi 2009 e o Firebird 2.1.
Rogério Nascimento
Curtidas 0
Respostas
Rodrigo Mourão
18/05/2009
Olá Rogério, fica tranquilo que não abusou não. Eu gosto de desafios. rsrsrsrs
Bem, não sei se você já assistiu alguma de minhas videos aulas. Eu sou bem prático, mas apesar disso não gosto de sair do padrão.
No seu caso temos duas opções: Ficar aqui durante dias desenvolvendo uma rotina que faça Exatamente o que você quer e com ListView. Digo dias pois a parte de montar os items do ListView e a parte mais simples, o mais complicado e linkar dinamicamente os eventos. O que também não é nada impossível de ser feito.
A segunda opção, e aí entra a praticidade, é criar manualmente todos os itens de menu conforme você quer na tela. E depois de criados apenas criamos uma rotina para exibir aqueles que o seu cliente tem acesso. Simples, prático, fácil e objetivo. O que acha ?
Isso irá lhe atender perfeitamente. Se estiver de acordo sinalize para que possamos dar início.
Abs!!!!!
P.S.: Gostei a ideia do ListView para trabalhar como menu. :-)
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Bem, não sei se você já assistiu alguma de minhas videos aulas. Eu sou bem prático, mas apesar disso não gosto de sair do padrão.
No seu caso temos duas opções: Ficar aqui durante dias desenvolvendo uma rotina que faça Exatamente o que você quer e com ListView. Digo dias pois a parte de montar os items do ListView e a parte mais simples, o mais complicado e linkar dinamicamente os eventos. O que também não é nada impossível de ser feito.
A segunda opção, e aí entra a praticidade, é criar manualmente todos os itens de menu conforme você quer na tela. E depois de criados apenas criamos uma rotina para exibir aqueles que o seu cliente tem acesso. Simples, prático, fácil e objetivo. O que acha ?
Isso irá lhe atender perfeitamente. Se estiver de acordo sinalize para que possamos dar início.
Abs!!!!!
P.S.: Gostei a ideia do ListView para trabalhar como menu. :-)
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Fala Rodrigo, tudo na paz?!!!
Rapaz, estou acompanhando a sua video aula sobre Delphi 2007 e estou ansioso para ver o final. A sua proposta didatica e conceituosa sobre o assunto é muito boa.
Podemos fazer da forma que vc sugeriu, vindo de você a sugestão, ta feito.
Vamos lá, pode fazer da forma que você achou melhor.
Rapaz, estou acompanhando a sua video aula sobre Delphi 2007 e estou ansioso para ver o final. A sua proposta didatica e conceituosa sobre o assunto é muito boa.
Podemos fazer da forma que vc sugeriu, vindo de você a sugestão, ta feito.
Vamos lá, pode fazer da forma que você achou melhor.
GOSTEI 0
Rodrigo Mourão
18/05/2009
Ok!
Começo a trabalhar nisto hoje mesmo. Em breve posto a solução.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Começo a trabalhar nisto hoje mesmo. Em breve posto a solução.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rodrigo Mourão
18/05/2009
Olá Rogério, segue solução:
Vá no seu Form Principal e crie a seguinte procedure: procedure CarregaMenu(Nivel: Byte);
A implementação deste metodo fica assim:
procedure TFrmPrincipal.CarregaMenu(Nivel: Byte);
var
i: Integer;
J: Integer;
begin
for I := 0 to Pred(ComponentCount) do
if Components[I] is TListView then
begin
J := Pred(TListView(Components[I]).Items.Count);
while J >= 0 do
begin
if TListView(Components[I]).Items[J].StateIndex > Nivel then
begin
TListView(Components[I]).Items.Delete(J);
end;
Dec(J);
end;
end;
end;
O que faço ai na verdade é o seguinte. Eu varro o form e procuro por componentes TListView, pois pode haver mais de um. Quando localizo um TListView então percorro todos seus items e comparo a propriedade StateIndex com o Nivel passado, ou seja, cada item que você criar nos ListView você terá que alterar a propriedade StateIndex e colocar ali o nivel necessario para ele ser mostrado. Exemplo: 1, 2, 3, 4 Etc.
Assim quando você passar CarregaMenu(2) ele vai mostrar so os Items com StateIndex 1 e 2. No link abaixo te envio um exemplo feito em Delphi. Claro que o nivel voce traz do banco de dados.
http://video.devmedia.com.br/RodrigoCarreiro/Consultoria/MenuDinamico.zip
Abs.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Vá no seu Form Principal e crie a seguinte procedure: procedure CarregaMenu(Nivel: Byte);
A implementação deste metodo fica assim:
procedure TFrmPrincipal.CarregaMenu(Nivel: Byte);
var
i: Integer;
J: Integer;
begin
for I := 0 to Pred(ComponentCount) do
if Components[I] is TListView then
begin
J := Pred(TListView(Components[I]).Items.Count);
while J >= 0 do
begin
if TListView(Components[I]).Items[J].StateIndex > Nivel then
begin
TListView(Components[I]).Items.Delete(J);
end;
Dec(J);
end;
end;
end;
O que faço ai na verdade é o seguinte. Eu varro o form e procuro por componentes TListView, pois pode haver mais de um. Quando localizo um TListView então percorro todos seus items e comparo a propriedade StateIndex com o Nivel passado, ou seja, cada item que você criar nos ListView você terá que alterar a propriedade StateIndex e colocar ali o nivel necessario para ele ser mostrado. Exemplo: 1, 2, 3, 4 Etc.
Assim quando você passar CarregaMenu(2) ele vai mostrar so os Items com StateIndex 1 e 2. No link abaixo te envio um exemplo feito em Delphi. Claro que o nivel voce traz do banco de dados.
http://video.devmedia.com.br/RodrigoCarreiro/Consultoria/MenuDinamico.zip
Abs.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rodrigo Mourão
18/05/2009
Olá Rogério !
Há mais alguma dúvida referente a este chamado?
Estamos aguardando para podermos encerrá-lo.
Abs.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Há mais alguma dúvida referente a este chamado?
Estamos aguardando para podermos encerrá-lo.
Abs.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Olá Rodrigo, tudo bem? Perfeito, é isto mesmo, porem vou precisar da sua ajuda um pouco mais.
Vejamos pela imagem anexada, temos dois Listview, o da Esquerda é o Menu na qual eu irei carregar pela procedure, eu preciso que vc me ajude a chamar e passar o resultado da procedure para o listView da Esquerda.
Eu irei chamar a procedure que carrega os Menus e as Opçoes do Menu, apos o usuario logar no sistema e em seguida escolher a empresa que vai conectar, pois o mesmo pode ter mais de uma empresa no banco.
Abaixo da imagem, eu mandei 3 tabelas e 1 procedure exemplificando como seria.
Fiz um pequeno exemplo de como seria as tabelas:
CREATE TABLE EMPRESA (
CODIGO INTEGER NOT NULL,
RAZAOSOCIAL VARCHAR(60),
PACOTESISTEMA INTEGER DEFAULT 0
);
/* Fields descriptions */
COMMENT ON COLUMN EMPRESA.PACOTESISTEMA IS
'1 = versao basica
2 = versao intermediaria
3 = versao completa';
INSERT INTO EMPRESA (CODIGO, RAZAOSOCIAL, PACOTESISTEMA) VALUES (1, 'BRUNI QUIMICA LTDA', 1);
INSERT INTO EMPRESA (CODIGO, RAZAOSOCIAL, PACOTESISTEMA) VALUES (20, 'BRUNI QUIMICA LTDA MATRIZ', 2);
INSERT INTO EMPRESA (CODIGO, RAZAOSOCIAL, PACOTESISTEMA) VALUES (50, 'PEQUIMIK SOLVENTES', 3);
COMMIT WORK;
=====================================================================
CREATE TABLE MENU (
MENU_ID INTEGER NOT NULL,
MENUOPCAO VARCHAR(20) NOT NULL,
IMAGE INTEGER DEFAULT 0
);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (1, 'Contas a Receber', 0);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (2, 'Contas a Pagar', 1);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (3, 'Vendas', 2);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (4, 'PCP', 3);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (5, 'Compras', 4);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (6, 'Cheques', 5);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (7, 'Faturamento', 6);
COMMIT WORK;
=====================================================================
CREATE TABLE MENU_ITENS (
MENU_ID INTEGER NOT NULL,
DESCRICAOITENSMENU VARCHAR(30) NOT NULL,
ABAOPCAO INTEGER NOT NULL,
IMAGEM INTEGER DEFAULT 0 ,
OPCAOCONTRATADA INTEGER DEFAULT 0
);
COMMENT ON COLUMN MENU_ITENS.ABAOPCAO IS
' SE PERTENCE A CADASTROS, RELATORIOS, MOVIMENTACOES, ETC
1 = CADASTROS
2 = MOVIMENTACOES
3 = RELATORIOS';
CREATE PROCEDURE SP_MENUS (
cod_empresa integer)
returns (
menu varchar(30),
menuindex integer,
item_menu varchar(30),
menu_imagem integer,
item_menu_imagem integer,
abacontrole integer)
as
begin
for select menu.menu_id, menu.menuopcao, menu.image,
menu_itens.abaopcao, menu_itens.descricaoitensmenu, menu_itens.imagem
from menu
left join menu_itens on menu.menu_id = menu_itens.menu_id
where menu_itens.opcaocontratada <= (select empresa.pacotesistema from Empresa Where Empresa.codigo = :cod_empresa)
into menuindex, menu, menu_imagem,
abacontrole, item_menu, item_menu_imagem do
suspend;
end
Vejamos pela imagem anexada, temos dois Listview, o da Esquerda é o Menu na qual eu irei carregar pela procedure, eu preciso que vc me ajude a chamar e passar o resultado da procedure para o listView da Esquerda.
Eu irei chamar a procedure que carrega os Menus e as Opçoes do Menu, apos o usuario logar no sistema e em seguida escolher a empresa que vai conectar, pois o mesmo pode ter mais de uma empresa no banco.
Abaixo da imagem, eu mandei 3 tabelas e 1 procedure exemplificando como seria.
Fiz um pequeno exemplo de como seria as tabelas:
CREATE TABLE EMPRESA (
CODIGO INTEGER NOT NULL,
RAZAOSOCIAL VARCHAR(60),
PACOTESISTEMA INTEGER DEFAULT 0
);
/* Fields descriptions */
COMMENT ON COLUMN EMPRESA.PACOTESISTEMA IS
'1 = versao basica
2 = versao intermediaria
3 = versao completa';
INSERT INTO EMPRESA (CODIGO, RAZAOSOCIAL, PACOTESISTEMA) VALUES (1, 'BRUNI QUIMICA LTDA', 1);
INSERT INTO EMPRESA (CODIGO, RAZAOSOCIAL, PACOTESISTEMA) VALUES (20, 'BRUNI QUIMICA LTDA MATRIZ', 2);
INSERT INTO EMPRESA (CODIGO, RAZAOSOCIAL, PACOTESISTEMA) VALUES (50, 'PEQUIMIK SOLVENTES', 3);
COMMIT WORK;
=====================================================================
CREATE TABLE MENU (
MENU_ID INTEGER NOT NULL,
MENUOPCAO VARCHAR(20) NOT NULL,
IMAGE INTEGER DEFAULT 0
);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (1, 'Contas a Receber', 0);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (2, 'Contas a Pagar', 1);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (3, 'Vendas', 2);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (4, 'PCP', 3);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (5, 'Compras', 4);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (6, 'Cheques', 5);
INSERT INTO MENU (MENU_ID, MENUOPCAO, IMAGE) VALUES (7, 'Faturamento', 6);
COMMIT WORK;
=====================================================================
CREATE TABLE MENU_ITENS (
MENU_ID INTEGER NOT NULL,
DESCRICAOITENSMENU VARCHAR(30) NOT NULL,
ABAOPCAO INTEGER NOT NULL,
IMAGEM INTEGER DEFAULT 0 ,
OPCAOCONTRATADA INTEGER DEFAULT 0
);
COMMENT ON COLUMN MENU_ITENS.ABAOPCAO IS
' SE PERTENCE A CADASTROS, RELATORIOS, MOVIMENTACOES, ETC
1 = CADASTROS
2 = MOVIMENTACOES
3 = RELATORIOS';
CREATE PROCEDURE SP_MENUS (
cod_empresa integer)
returns (
menu varchar(30),
menuindex integer,
item_menu varchar(30),
menu_imagem integer,
item_menu_imagem integer,
abacontrole integer)
as
begin
for select menu.menu_id, menu.menuopcao, menu.image,
menu_itens.abaopcao, menu_itens.descricaoitensmenu, menu_itens.imagem
from menu
left join menu_itens on menu.menu_id = menu_itens.menu_id
where menu_itens.opcaocontratada <= (select empresa.pacotesistema from Empresa Where Empresa.codigo = :cod_empresa)
into menuindex, menu, menu_imagem,
abacontrole, item_menu, item_menu_imagem do
suspend;
end
GOSTEI 0
Rodrigo Mourão
18/05/2009
Olá Rogério, é como eu lhe expliquei no início. O que você quer fazer e Montar todos os menus dinamicamente para isso ficar flexivel não é? Mas é uma false Flexibilidade. Repare que na tabela menu vc passa o Caption do Menu e o Index da imagem.
Mas onde está essa imagem?
- No imageList dentro do Delphi.
Então se você quiser alterar o nome de um menu altera no banco, mas trocar o ícone tem que abrir a aplicação e trocar a imagem no ImageList. Com isso você tem parte da rotina no banco e parte na aplicação. Isso é extremamente ruim.
Você chegou a rodar o código que lhe falei? Pois você pode ter 1,2,3 quantas listview quiser na aplicação com os itens que ele vai ocultar ou não.
Faça o seguinte em cada item que de cada ListView que você tem ai configura a propriedade StateIndex com 1, 2 ou 3 de acordo com o PACOTESISTEMA da empresa. Ex. menu Contas a Pagar coloca state Index 3 isso fara com que ele so aparceça na 3;
Agora como isso vai funcionar? Simples. Ao se logra você vai no banco e pega o PACOTESISTEMA da empresa e passar para a rotina CarregaMenu(Nivel: Byte); E mais.
Essa listView lateral tambem pode ter seus itens ocultados. Basta configurar a propriedade StateIndex dos itens também.
Rógerio esta é a melhor solução pois montar o menu e tranquilo mas se for feito dinamicamente como vai "injetar" o Onclick.
Por isso acho mais vantajoso deixar todos os itens criados em Design Time, com os onClick's ja programados e apenas ocultar os itens que a empresa não tenha acesso !!
Se quiser manda a sua aplicacao com o banco que implemento a rotina pra voce ver !!!
Abs !!!
Mas onde está essa imagem?
- No imageList dentro do Delphi.
Então se você quiser alterar o nome de um menu altera no banco, mas trocar o ícone tem que abrir a aplicação e trocar a imagem no ImageList. Com isso você tem parte da rotina no banco e parte na aplicação. Isso é extremamente ruim.
Você chegou a rodar o código que lhe falei? Pois você pode ter 1,2,3 quantas listview quiser na aplicação com os itens que ele vai ocultar ou não.
Faça o seguinte em cada item que de cada ListView que você tem ai configura a propriedade StateIndex com 1, 2 ou 3 de acordo com o PACOTESISTEMA da empresa. Ex. menu Contas a Pagar coloca state Index 3 isso fara com que ele so aparceça na 3;
Agora como isso vai funcionar? Simples. Ao se logra você vai no banco e pega o PACOTESISTEMA da empresa e passar para a rotina CarregaMenu(Nivel: Byte); E mais.
Essa listView lateral tambem pode ter seus itens ocultados. Basta configurar a propriedade StateIndex dos itens também.
Rógerio esta é a melhor solução pois montar o menu e tranquilo mas se for feito dinamicamente como vai "injetar" o Onclick.
Por isso acho mais vantajoso deixar todos os itens criados em Design Time, com os onClick's ja programados e apenas ocultar os itens que a empresa não tenha acesso !!
Se quiser manda a sua aplicacao com o banco que implemento a rotina pra voce ver !!!
Abs !!!
GOSTEI 0
Rogério Nascimento
18/05/2009
Olá Rodrigo, tdo bem?
Você tem razão !!!! Vamos fazer assim, eu vou testar conforme vc me orientou hoje a noite e caso eu tiver alguma duvida te passo ou encerro o chamado, combinado !!!?
Abraços.
GOSTEI 0
Rodrigo Mourão
18/05/2009
Olá Amigo !!
Por falta de retonro encerramos o seu chamado. Caso ainda possua alguma dúvida sobre esse assunto, por favor, post a mesma que o consultor voltará a lhe atender e o chamado será reaberto.
Abs !!
Por falta de retonro encerramos o seu chamado. Caso ainda possua alguma dúvida sobre esse assunto, por favor, post a mesma que o consultor voltará a lhe atender e o chamado será reaberto.
Abs !!
GOSTEI 0
Rogério Nascimento
18/05/2009
Olá Rodrigo, tudo bem? Olha eu aqui novamente !!!
Esbarrei com um problema não previsto na rotina implementada e preciso de sua ajuda.
Conforme a rotina que vc me passou, esta acontecendo o seguinte:
////////// Rotina implementada //////////////
procedure TfrmPrincipal.CarregaMenu(Nivel: Byte);
var
i: Integer;
J: Integer;
begin
// Filtra as opções do ListView conforme o Modulo Relacionado (Rodrigo Carreiro / DevMedia);
for I := 0 to Pred(ComponentCount) do
if Components[I] is TListView then
begin
J := Pred(TListView(Components[I]).Items.Count);
while J >= 0 do
begin
if TListView(Components[I]).Items[J].StateIndex > Nivel then
begin
TListView(Components[I]).Items.Delete(J);
end;
Dec(J);
end;
end;
end;
O Menu, tem vários modulos a esquerda e do lado direito tem o listview que aparece as opções do modulo selecionado, conforme vc tinha me orientado, adicionei todos os itens no listview e depois conforme clico no modulo, ele apaga os itens diferentes do modulo selecionado, porem acontece o seguinte:
Entrei no modulo Contas a Receber, beleza, os itens que estão no listview, são relacionados a ele, qdo vou para outro modulo, Vendas por exemplo, ja não aparece mais as opções no listview, ja que qdo eu entrei no Contas a Receber, ele apagou o que foi diferente dele, qdo entrei no vendas, ele tbm apagou o que foi diferente dele, porem não carregou as opções relacionadas a ele, assim o listview fica vazio.
Pensei na seguinte situação, como uso Tabsheet, adicionar uma Tab que não ficará visivel ao usuário e nesta adiciono um listView, com todas as opções do sistema ja inseridas nele e conforme eu clicar no menu na tela inicial, ele capta as opçoes relacionadas ao menu pelo State Index (conforme sugerido por você) e adiciona no listview principal. Se esta for a forma mais facil, gostaria que vc me ajudasse a implementar isto, ou, sugerir algo para isto.
Abaixo a tela principal de como esta.
Abraços,
Rogério Nascimento.
Esbarrei com um problema não previsto na rotina implementada e preciso de sua ajuda.
Conforme a rotina que vc me passou, esta acontecendo o seguinte:
////////// Rotina implementada //////////////
procedure TfrmPrincipal.CarregaMenu(Nivel: Byte);
var
i: Integer;
J: Integer;
begin
// Filtra as opções do ListView conforme o Modulo Relacionado (Rodrigo Carreiro / DevMedia);
for I := 0 to Pred(ComponentCount) do
if Components[I] is TListView then
begin
J := Pred(TListView(Components[I]).Items.Count);
while J >= 0 do
begin
if TListView(Components[I]).Items[J].StateIndex > Nivel then
begin
TListView(Components[I]).Items.Delete(J);
end;
Dec(J);
end;
end;
end;
O Menu, tem vários modulos a esquerda e do lado direito tem o listview que aparece as opções do modulo selecionado, conforme vc tinha me orientado, adicionei todos os itens no listview e depois conforme clico no modulo, ele apaga os itens diferentes do modulo selecionado, porem acontece o seguinte:
Entrei no modulo Contas a Receber, beleza, os itens que estão no listview, são relacionados a ele, qdo vou para outro modulo, Vendas por exemplo, ja não aparece mais as opções no listview, ja que qdo eu entrei no Contas a Receber, ele apagou o que foi diferente dele, qdo entrei no vendas, ele tbm apagou o que foi diferente dele, porem não carregou as opções relacionadas a ele, assim o listview fica vazio.
Pensei na seguinte situação, como uso Tabsheet, adicionar uma Tab que não ficará visivel ao usuário e nesta adiciono um listView, com todas as opções do sistema ja inseridas nele e conforme eu clicar no menu na tela inicial, ele capta as opçoes relacionadas ao menu pelo State Index (conforme sugerido por você) e adiciona no listview principal. Se esta for a forma mais facil, gostaria que vc me ajudasse a implementar isto, ou, sugerir algo para isto.
Abaixo a tela principal de como esta.
Abraços,
Rogério Nascimento.
GOSTEI 0
Rodrigo Mourão
18/05/2009
Olá Rogério,
Bem vamos lá, eu acredito que a melhor maneira de resolver o problema seja restaurar a condição inicial ao mudar o módulo. Por exemplo, quando vc entra no Contas a Pagar vc oculta alguns itens. Quando vc trocar de modulo faça um loop e coloque todos os itens visíveis. Assim volta ao estado original e ai vc poderá chamar a rotina para outro modulo.
Assim é mais simples de implementar.
Abs!!
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Bem vamos lá, eu acredito que a melhor maneira de resolver o problema seja restaurar a condição inicial ao mudar o módulo. Por exemplo, quando vc entra no Contas a Pagar vc oculta alguns itens. Quando vc trocar de modulo faça um loop e coloque todos os itens visíveis. Assim volta ao estado original e ai vc poderá chamar a rotina para outro modulo.
Assim é mais simples de implementar.
Abs!!
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Olá Rodrigo
Como eu faço para restaurar as opções que foram deletadas?
Como eu faço para restaurar as opções que foram deletadas?
GOSTEI 0
Rodrigo Mourão
18/05/2009
Rogério agora você me colocou em check rsrsrsrs!
Não me atentei ao detalhe que estavamos deletando o item. Mas deixar eu ver aqui. Se não tiver a opção visible no Item (E acho que não tem) então vamos tentar reconstruir o controle. Aqui no momento estou sem Delphi mas assim que chegar no cliente eu vou fazer os teste e te enviar.
Abs!!
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Não me atentei ao detalhe que estavamos deletando o item. Mas deixar eu ver aqui. Se não tiver a opção visible no Item (E acho que não tem) então vamos tentar reconstruir o controle. Aqui no momento estou sem Delphi mas assim que chegar no cliente eu vou fazer os teste e te enviar.
Abs!!
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Olá Rodrigo, sem problemas !!!
Você tem alguma sugestão para substituir-mos o listview por outro componente que seja mais facil a manutenção, mas que de a mesma aparencia, pois o meu foco é dar facilidade ao acesso ao menu, ficando bem visivel todas opções ao entrar no modulo, evitando o incoveniente de ficar navegando pelo menu até achar a outra opção.
Você tem alguma sugestão para substituir-mos o listview por outro componente que seja mais facil a manutenção, mas que de a mesma aparencia, pois o meu foco é dar facilidade ao acesso ao menu, ficando bem visivel todas opções ao entrar no modulo, evitando o incoveniente de ficar navegando pelo menu até achar a outra opção.
GOSTEI 0
Rodrigo Mourão
18/05/2009
Rogério, não se atreva rsrsrsrsrsrsrs
Este disposição e esta ideia do ListView foi uma grande sacada você está de parabéns.
Eu fiquei enrolado durante o dia mas ja estou fazendo o teste com o repaint e o CreateWND acho que vai nos ajudar.
Peço que aguardo mais um pouco !!
Abs!!
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Este disposição e esta ideia do ListView foi uma grande sacada você está de parabéns.
Eu fiquei enrolado durante o dia mas ja estou fazendo o teste com o repaint e o CreateWND acho que vai nos ajudar.
Peço que aguardo mais um pouco !!
Abs!!
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Sem problemas irmão, fique tranquilo.
GOSTEI 0
Rodrigo Mourão
18/05/2009
Rapaz a parada não é tão simples não. Bem pra ter noção tentei "repintar" o componente. Não rolou. Entao fui para o RecrateWND. também não rolou. Apelei para destruir e criar de novo e nada. Ai apelei para meu mestre em delphi rsrsrsrsr Adilson Junior, Master Trainning da Borland e meu Diretor. Ele sugeriu um Stream do Arquivo em Disco para fazer um Undo. Putz maior viagem.
Bem pra resumir, pensei numa coisa mais simples e mais obvia. Fazer com que o seu form principal hoje se torne o segundo form, ou seja, a aplicacao vai ter um form principal sem nada so para conter o segundo form com toda a infra. Assim quando quiser recarregar original destruimos e reciamos o form. Assim ele rele o DFM e coloca tudo como estava no inicio, 0 KM.
Eu ainda não implementei mas vou criar um exemplo aqui e te mando.
Abs.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Bem pra resumir, pensei numa coisa mais simples e mais obvia. Fazer com que o seu form principal hoje se torne o segundo form, ou seja, a aplicacao vai ter um form principal sem nada so para conter o segundo form com toda a infra. Assim quando quiser recarregar original destruimos e reciamos o form. Assim ele rele o DFM e coloca tudo como estava no inicio, 0 KM.
Eu ainda não implementei mas vou criar um exemplo aqui e te mando.
Abs.
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
hahahah, sem problemas, fique tranquilo, não tenho pressa, este projeto estou desenvolvendo paralelo aos meus estudos, e ainda virão mais chamados relacionados a ele :D.
Abraços,
Rogério
Abraços,
Rogério
GOSTEI 0
Rodrigo Mourão
18/05/2009
Olá Rogério, demorou mais saiu !!
Seguinte abaixo tem um link com os fontes de um exemplo que criei para te mostrar a ideia. O lance é o seguinte. Eu tenho um form principal que nunca será mostrado, ele servirá so para manter a aplicação rodando. Quando eu crio o form principal eu chamo um metodo AlteraMenu passando o maior nivel ( ai vc troca pro nivel do usuario).
Este metodo ALteraMenu cria um form chamado FrmMenu que tem os PageControls, ListView, etc. Depois ele configura os ListView de acordo com o nivel e por ultimo exibe o formulario.
Quando vc for alterar o nivel eu destruo o formulario FrmMenu e recrio ele. Assim ele volta ao normal, exibindo todos os itens e aplica o novo nivel.
Quando vc cria em sair eu uso o aplication.terminated para encerrar a aplicação.
O caminho é este.
Abs!!!
Segue Link : www.rmfactory.com.br/rmfontes/ListView.rar
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Seguinte abaixo tem um link com os fontes de um exemplo que criei para te mostrar a ideia. O lance é o seguinte. Eu tenho um form principal que nunca será mostrado, ele servirá so para manter a aplicação rodando. Quando eu crio o form principal eu chamo um metodo AlteraMenu passando o maior nivel ( ai vc troca pro nivel do usuario).
Este metodo ALteraMenu cria um form chamado FrmMenu que tem os PageControls, ListView, etc. Depois ele configura os ListView de acordo com o nivel e por ultimo exibe o formulario.
Quando vc for alterar o nivel eu destruo o formulario FrmMenu e recrio ele. Assim ele volta ao normal, exibindo todos os itens e aplica o novo nivel.
Quando vc cria em sair eu uso o aplication.terminated para encerrar a aplicação.
O caminho é este.
Abs!!!
Segue Link : www.rmfactory.com.br/rmfontes/ListView.rar
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Fala ae Rodrigo, tudo na paz !!!!
Bom, recebi aqui, executei, tudo beleza, entendi tudo o que vc me explicou certinho, mas na pratica não sei se conseguirei colocar isto em ação, vou dar uma estudada aqui e depois te falo.
Mas ja de antemão, agradeço sua gigantesca atenção.
Abraços.
Bom, recebi aqui, executei, tudo beleza, entendi tudo o que vc me explicou certinho, mas na pratica não sei se conseguirei colocar isto em ação, vou dar uma estudada aqui e depois te falo.
Mas ja de antemão, agradeço sua gigantesca atenção.
Abraços.
GOSTEI 0
Rodrigo Mourão
18/05/2009
Por nada Rogério !!
Vou colocar o chamado como encerrado, caso surja alguma outra dúvida é so reabrir.
Abs !
Vou colocar o chamado como encerrado, caso surja alguma outra dúvida é so reabrir.
Abs !
GOSTEI 0
Marcio Silva
18/05/2009
o arquivo deste link Segue Link : www.rmfactory.com.br/rmfontes/ListView.rar
voce teria ai para mandar.
Outro detalhe, o que deu o projeto, funcionou, tem como compartilhar.
Marcio
voce teria ai para mandar.
Outro detalhe, o que deu o projeto, funcionou, tem como compartilhar.
Marcio
Olá Rogério, demorou mais saiu !!
Seguinte abaixo tem um link com os fontes de um exemplo que criei para te mostrar a ideia. O lance é o seguinte. Eu tenho um form principal que nunca será mostrado, ele servirá so para manter a aplicação rodando. Quando eu crio o form principal eu chamo um metodo AlteraMenu passando o maior nivel ( ai vc troca pro nivel do usuario).
Este metodo ALteraMenu cria um form chamado FrmMenu que tem os PageControls, ListView, etc. Depois ele configura os ListView de acordo com o nivel e por ultimo exibe o formulario.
Quando vc for alterar o nivel eu destruo o formulario FrmMenu e recrio ele. Assim ele volta ao normal, exibindo todos os itens e aplica o novo nivel.
Quando vc cria em sair eu uso o aplication.terminated para encerrar a aplicação.
O caminho é este.
Abs!!!
Segue Link : www.rmfactory.com.br/rmfontes/ListView.rar
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
Seguinte abaixo tem um link com os fontes de um exemplo que criei para te mostrar a ideia. O lance é o seguinte. Eu tenho um form principal que nunca será mostrado, ele servirá so para manter a aplicação rodando. Quando eu crio o form principal eu chamo um metodo AlteraMenu passando o maior nivel ( ai vc troca pro nivel do usuario).
Este metodo ALteraMenu cria um form chamado FrmMenu que tem os PageControls, ListView, etc. Depois ele configura os ListView de acordo com o nivel e por ultimo exibe o formulario.
Quando vc for alterar o nivel eu destruo o formulario FrmMenu e recrio ele. Assim ele volta ao normal, exibindo todos os itens e aplica o novo nivel.
Quando vc cria em sair eu uso o aplication.terminated para encerrar a aplicação.
O caminho é este.
Abs!!!
Segue Link : www.rmfactory.com.br/rmfontes/ListView.rar
Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi
GOSTEI 0
Rogério Nascimento
18/05/2009
Olá Márcio, tudo bem?
Não tenho mais estes fontes, o processo que eu estava iniciando com o Rodrigo deu certo sim, porém esbarrei em outras limitações, pois queria utilizar o projeto como MDI e a estrutura de navegação seria um pouco diferente e queria também mostrar o menu desabilitado e não oculta-lo, da forma projetada inicial o menu seria ocultado ou quando o usuário clicasse no menu daria a mensagem que não tem permissão.
Relembrando aqui, não vejo dificuldades, você terá que ter uma tabela no banco com os nomes dos menus e os índices das imagens, na confirmação do login do usuário chamaria um método que carregaria todas as opções dos usuários em tempo de execução.
No onclick do listview você passaria o índice do listview para um método que chamaria a classe e criaria o objeto em tempo de execução.
Espero ter ajudado !
Não tenho mais estes fontes, o processo que eu estava iniciando com o Rodrigo deu certo sim, porém esbarrei em outras limitações, pois queria utilizar o projeto como MDI e a estrutura de navegação seria um pouco diferente e queria também mostrar o menu desabilitado e não oculta-lo, da forma projetada inicial o menu seria ocultado ou quando o usuário clicasse no menu daria a mensagem que não tem permissão.
Relembrando aqui, não vejo dificuldades, você terá que ter uma tabela no banco com os nomes dos menus e os índices das imagens, na confirmação do login do usuário chamaria um método que carregaria todas as opções dos usuários em tempo de execução.
No onclick do listview você passaria o índice do listview para um método que chamaria a classe e criaria o objeto em tempo de execução.
Espero ter ajudado !
GOSTEI 0
Marcio Silva
18/05/2009
Tudo bem Rogerio!!, obrigado pela resposta, vou testar suas indicações.
Olá Márcio, tudo bem?
Não tenho mais estes fontes, o processo que eu estava iniciando com o Rodrigo deu certo sim, porém esbarrei em outras limitações, pois queria utilizar o projeto como MDI e a estrutura de navegação seria um pouco diferente e queria também mostrar o menu desabilitado e não oculta-lo, da forma projetada inicial o menu seria ocultado ou quando o usuário clicasse no menu daria a mensagem que não tem permissão.
Relembrando aqui, não vejo dificuldades, você terá que ter uma tabela no banco com os nomes dos menus e os índices das imagens, na confirmação do login do usuário chamaria um método que carregaria todas as opções dos usuários em tempo de execução.
No onclick do listview você passaria o índice do listview para um método que chamaria a classe e criaria o objeto em tempo de execução.
Espero ter ajudado !
Não tenho mais estes fontes, o processo que eu estava iniciando com o Rodrigo deu certo sim, porém esbarrei em outras limitações, pois queria utilizar o projeto como MDI e a estrutura de navegação seria um pouco diferente e queria também mostrar o menu desabilitado e não oculta-lo, da forma projetada inicial o menu seria ocultado ou quando o usuário clicasse no menu daria a mensagem que não tem permissão.
Relembrando aqui, não vejo dificuldades, você terá que ter uma tabela no banco com os nomes dos menus e os índices das imagens, na confirmação do login do usuário chamaria um método que carregaria todas as opções dos usuários em tempo de execução.
No onclick do listview você passaria o índice do listview para um método que chamaria a classe e criaria o objeto em tempo de execução.
Espero ter ajudado !
GOSTEI 0