GARANTIR DESCONTO

Fórum Aplicação com ícones de atalhos #344725

20/08/2007

0

Pessoal estou desenvolvendo um aplicativo, onde preciso criar uma área de trabalho igual a área de trabalho do windows, colocando os ícones de atalhos para programas como word, excel, calculadora, etc. Só que a informação dos atalhos e caminhos do ícone ficaram guardadas no banco de dados, então preciso ler as informações do banco de dados e apresentar na tela em forma de ícones os programas que estão cadastrados.


Visualdesigner

Visualdesigner

Responder

Posts

20/08/2007

Emerson Nascimento

se não estou enganado, você pode fazer isso facilmente com ListView


Responder

Gostei + 0

20/08/2007

Visualdesigner

Mas como recuperar os dados do banco de dados?


Responder

Gostei + 0

21/08/2007

Vitor Alcantara

Cara você pode fazer utilizando um imagelist e um listview para retornar os icones dos programas na tela.

Um exemplo de como fazer isso:

No meu exemplo eu utilizo a procedure CriaLista para trazer os icones no listview.
procedure TFormMenu.CriaLista(Tipo:String);
var
  x:integer;
  ico:TIcon;
  tipo,SNome,sDiretorio,sExecutavel,sComando,sSensura:string;

begin
  //Limpo o ListView para inserir os dados
  ListView1.Clear;
  //Retorna os dados gravados no banco de dados com os programas
  With SqlProMaquina do
  begin
    Close;    
    ParamByName(´TIPO´).AsString := tipo;
    Open;   
  end;
  //Aqui eu crio a imagelist para guardar os icones dos programas
  imgList := TImageList.Create(self);
  imgList.Width := 32;
  imgList.Height := 32;
  ListView1.LargeImages := imgList;

  
  //Faço um laço no resultado dessa consulta que contem o nome do programa, executavel , icone e parametros
  if DmProgramas.ListaProgrMaquina(tipo ) then
  begin

    //Inicializo a váriavel Ico que irá receber o icone do prgrama
    Ico := TIcon.Create;
    ico.SetSize(32,32);

    //aqui eu inicializo o laço na query SqlProMaquina que contem os dados que eu preciso
    SQLProMaquina.First;
    while not DmProgramas.SQLProMaquina.Eof  do
    begin
      //Guardo nessas variaveis os dados do programa
      sNome := SQLProMaquinaDESCRICAO.AsString;
      sDiretorio := SQLProMaquinaDIRETORIO.AsString;
      sExecutavel := SQLProMaquinaEXECUTAVEL.AsString;
      sComando := SQLProMaquinaCOMANDO.AsString;
      sSensura := IntToStr(SQLProMaquinaSENSURA.Value);

      //Verifico se o arquivo exist , caso exista eu insiro ele no imagelist e no listview  
      if FileExists(sExecutavel) then     
      begin
        //Na minha tabela progr_maquina (que eu guardo os dados dos programas) eu tenho um campo do tipo Blob onde eu guardo icones personalizaveis para cada programa . Ou deixo esse campo vazio que dai eu utilizo o icone do programa mesmo
        if SQLProMaquinaICONE.Value <> ´´ then
        begin
          ICO.Assign(SQLProMaquinaICONE);
        end
        else
        Ico.Handle := ExtractIcon(Handle,PChar(sExecutavel),0);
        //Insiro o icone no imagelist
        imgList.AddIcon(Ico);

        //Insiro o item no ListView
        ListView1.AddItem(sNome,ListView1);
        ListView1.Items[ListView1.Items.Count -1].SubItems.Add(sExecutavel);
        ListView1.Items[ListView1.Items.Count -1].SubItems.Add(sDiretorio);
        ListView1.Items[ListView1.Items.Count -1].SubItems.Add(sComando);
        ListView1.Items[ListView1.Items.Count -1].SubItems.Add(sSensura);
        ListView1.Items[ListView1.Items.Count -1].ImageIndex := ListView1.Items.Count -1;
      end;
      SQLProMaquina.Next;
    end;
  end;
end;


PS: imgList é uma variavel do tipo TImageList que eu declarei na sessão private do meu form:
private
  imgList:TImageList;


Aqui segue o código que eu utilizo na minha Query SqlProMaquina:

select distinct CHAVE, COMANDO, DESCRICAO, DIRETORIO, EXECUTAVEL, LK_MAQUINA, SENSURA, TIPO , ICONE
from progr_maquina 
where ((:TIPO = ´T´) or
       (TIPO = :TIPO))


pra chamar eu coloco no evento do botão tipo
CriaLista(´G´);//Mostrar os icones referente a Games
CriaLista(´O´);//Mostrar os icones referente a Office
CriaLista(´I´);//Mostrar os icones referente a Internet
CriaLista(´T´);//Mostrar todos os programas

Dai no evento de duplo click do ListView eu utilizo esse código para executar o programa

procedure TFormMenu.ListView1DblClick(Sender: TObject);
var
  sNome,sExecutavel,sPasta,sComando:String;
begin

 // if ListView1.Focused  then
  //Verifico se existe algum item selecionado para não dar erro
  if ListView1.Selected <> nil then
  if ListView1.Selected.Index > -1 then
  begin
    //Gravos os dados dos programas para executar o comando  
    sNome := ListView1.Items[ListView1.Selected.Index ].Caption;
    sExecutavel := ListView1.Items[ListView1.Selected.Index ].SubItems[0];
    sPasta := ListView1.Items[ListView1.Selected.Index ].SubItems[1];
    sComando := ListView1.Items[ListView1.Selected.Index].SubItems[2];
    
    //Executo o procedimento para abrir o programa
    RunCommand(sExecutavel,sComando,False,SW_MAXIMIZE);
  end;
end;


Abaixo tem a procedure RunCommand que foi retirado da unit ACBRUtil que esta disponivel no projeto Acbr

{-----------------------------------------------------------------------------
 - Executa programa Externo descrito em "Command", adcionando os Parametros
   "Params" na linha de comando
 - Se "Wait" for true para a execução da aplicação para esperar a conclusao do
   programa externo executado por "Command"
 - WindowState apenas é utilizado na plataforma Windows
 ---------------------------------------------------------------------------- }
procedure RunCommand(Command: String; Params: String; Wait : Boolean;
   WindowState : Word);
var
  {$ifdef MSWINDOWS}
  SUInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  Executed : Boolean ;
  PCharStr : PChar ;
  {$endif}
  ConnectCommand : PChar;
begin
  {$ifdef LINUX}
     Command := Trim(Command + ´ ´ + Params) ;
     if not Wait then
        Command := Command + ´ &´ ;  { & = Rodar em BackGround }
     {$IFNDEF FPC}
       ConnectCommand := PChar(Command);
       Libc.system(ConnectCommand);
     {$ELSE}
       Shell(Command)
     {$ENDIF}
  {$endif}
  {$ifdef MSWINDOWS}
     Command  := Trim(Command) ;
     PCharStr := PChar(Trim(Params)) ;
     if Length(PCharStr) = 0 then
        PCharStr := nil ;

     if not Wait then
        ShellExecute(0,´open´,PChar(Command),PCharStr, nil, WindowState )
//        winexec(ConnectCommand, WindowState)
     else
      begin
        ConnectCommand := PChar(Trim(Command + ´ ´ + Params));
        PCharStr := PChar(ExtractFilePath(Command)) ;
        if Length(PCharStr) = 0 then
           PCharStr := nil ;
        FillChar(SUInfo, SizeOf(SUInfo), #0);
        with SUInfo do
        begin
           cb          := SizeOf(SUInfo);
           dwFlags     := STARTF_USESHOWWINDOW;
           wShowWindow := WindowState;
        end;

        Executed := CreateProcess(nil, ConnectCommand, nil, nil, false,
                    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                    PCharStr, SUInfo, ProcInfo);

        try
           { Aguarda até ser finalizado }
           if Executed then
              WaitForSingleObject(ProcInfo.hProcess, INFINITE);
        finally
           { Libera os Handles }
           CloseHandle(ProcInfo.hProcess);
           CloseHandle(ProcInfo.hThread);
        end;
      end;
  {$endif}
end;



Responder

Gostei + 0

21/08/2007

Visualdesigner

Boa Tarde Gladstone!


Cara você me ajudou bastante, pelo que percebi essas são rotinas de um programa para lan house né.


Estou também desenvolvendo um programa desse tipo. Não querendo abusar de sua boa vontade, mas será que você poderia me dar algumas dicas a respeito desse sistema.


Estou precisando das seguintes informações:

- Como configurar o preço por hora
- Como o sistema controla o tempo do cliente na estação, ou seja a como ele vai sendo atualizado para dar baixa nos créditos
- Quanto ao sistema de restrições da máquina, já sei como colocar todas as restrições na máquina, mas gostaria de informações de qual a melhor forma de aplicá-las, seria melhor gravar as informações no banco de dados, colocando as chaves que desejo alterar no regedit.


Sei que é muita coisa o que estou precisando, já tenho uma noção do que estou pretendendo fazer, mas preciso reunir idéias para confrontá-las com as minhas para montar uma estrutura segura e confiável, lembrando que caso precise de alguma coisa estarei a disposição

MSN: josimar_nil@hotmail.com


Responder

Gostei + 0

21/08/2007

Visualdesigner

desculpe acabe colocando o nome errado a mensagem era direcionada pra Vitor Araujo Alcantara


Responder

Gostei + 0

21/08/2007

Vitor Alcantara

Em relação ao atualização no banco da hora no sistema eu faço de dois modos:
uma localmente onde eu gravo no registro o tempo atual e o tempo restante a cada 5 segundos:
outra eu gravo no banco de dados a 30 segundos ou quando termina o tempo.

Aqui vai um exemplo de como funciona na minha aplicação (está incompleta);

As váriaveis que não estão sitadas no var da procedure são váriaveis que eu declarei na sessão Public do form/DataModule;
TmCalcTempoTimer é um componente TTimer;

procedure TDmMovimento.TmCalcTempoTimer(Sender: TObject);
var
  m,ms,s,h:word;
  Tm:TDateTime;
begin
  inc(iTEMPO_UTIL);
  iTEMPO_REST := iTEMPO_SOL - iTEMPO_UTIL;
  Tm := 0;
  tm := incSecond(tm,iTEMPO_UTIL);
  sTEMPO_ATUAL := TimeToStr(tm);

  tm := 0;
  Tm := incSecond(tm,iTEMPO_REST);
  sTEMPO_REST := TimeToStr(tm);

  //GRAVANDO OS DADOS NO BANCO E NO REGISTRO
  DecodeTime(now,h,m,s,ms);
  case s  of
    5,10,15,20,25,30,35,40,55,59:GravaTempoRegistro;
    1,31:GravaTempoBAnco;
  end;
   
  {Em caso de se acabar o tempo e não estiver no modo livre (sem limite de tempo) grava os dados no banco e chama o procedimento de finalizar 
o tempo aonde eu chamo a a tela que bloqueia a máquina }
  if (iTEMPO_UTIL >= iTEMPO_SOL)
     and (sTIPO <> ´Livre / Free ´) then
  begin
    GravaTempoBanco;
    FinalizaTempo;
  end;


end;


aqui segue um exemplo de como eu gravo o tempo no registro

procedure TDmMovimento.GravaTempoRegistro;
var
  key:TRegistry;
const
  chave:STRING = ´\SOFTWARE\SisLanHouse\TEMPO\´;
begin
  key := TRegistry.Create;
  key.RootKey := HKEY_LOCAL_MACHINE ;
  key.OpenKey(chave,true);

  //Grava os dados no registro
  key.WriteBool(´SESSAO ABERTA´,bSESSAO_ABERTA);
  key.WriteBool(´CARTAO´,bCARTAO );
  key.WriteBool(´COBBRAR´,bCOBRAR);
  key.WriteInteger(´CODCART´,iCODCART);
  key.WriteInteger(´CODUSER´,iCODUSER);
  key.WriteDateTime(´PERIODO INICIO´,dPERIODO_INICIO);
  key.WriteInteger(´TEMPO SOL´,iTEMPO_SOL );
  key.WriteInteger(´TEMPO UTIL´,iTEMPO_UTIL);
  key.WriteInteger(´TEMPO REST´,iTEMPO_REST);
  key.WriteString(´TIPO´,sTIPO);
  key.WriteFloat(´VALOR´,cVALOR );
  key.WriteString(´STR TEMPO REST´,sTEMPO_REST);
  key.WriteString(´STR TEMPO ATUAL´,sTEMPO_ATUAL);
  key.WriteString(´STR TEMPO SOL´,sTEMPO_SOL);
  Key.WriteInteger(´TEMPO TMP´,iTEMPO_TMP);
  key.CloseKey;
end;


O meu procedimento de gravar no banco:
procedure TDmMovimento.GravaTempoBanco;
var
  sStr:STring;
  e:Exception;
begin
  try
    //Inicio a transação
    DmPrincipal.IniciaTransacao;

    //Atualizando o Dados do banco
    sStr :=
    ´update mov_tmp ´ +
    ´set TEMPO_UTIL = ´+IntToSTr(iTEMPO_UTIL)+´,´ +
       ´VALOR = ´+StringReplace(FloatToSTrf(cVALOR ,ffFixed,10,2),´,´,´.´,[rfReplaceAll]) +´ ´ +
    ´where LK_ESTACAO = ´+IntToStr(DmMaquina.PegaCodMaquina);
    DmPrincipal.Conexao.ExecuteDirect(sStr);

    //Atualizando o dados no cliente ou cartão
    if bCARTAO  then
    begin
      if iTEMPO_UTIL < iTEMPO_SOL then      
      sStr :=
      ´update cartao ´ +
      ´set TEMPO_UTI = ´+ IntTostr(iTEMPO_UTIL)+´ ´ +
      ´where CHAVE = ´+IntToStr(iCODCART);
    end
    else
    //Atualiza os dados do cliente em caso de tipo por tempo
    //No caso do tempo livre só irá atualizar o tempo_acumulado do cliente
    //no final.
    begin
      if sTIPO = ´Tempo / Time ´ then
      sStr :=
      ´update usuario ´+
      ´set TEMPO_UTI = ´+ IntToStr(iTEMPO_TMP + iTEMPO_UTIL)+´, ´ +
      ´ TEMPO_RES = ´+ IntToStr(iTEMPO_REST)+´  ´ +
      //´ TEMPO_ACU = TEMPO_ACU + ´+IntToStr(iTEMPO_UTIL)+´ ´ +
      ´where CHAVE = ´+IntToStr(iCODUSER);
    end;

    DmPrincipal.Conexao.ExecuteDirect(sStr);
    //Em caso de suscesso dou um comit na transação
    DmPrincipal.FinalizaTransacao;
  except
    on e:Exception do
    begin
      //Em caso de erro desfaço a transação e crio um exception.
      DmPrincipal.DesfazTransacao;
      Raise Exception.Create(e.Message );
    end;

  end;

end;


Dai caso caia a energia o haja um desligamento indevido eu pego e verifico essas chaves e verifico no banco (onde eu tenho uma tabela que contem os registros das máquinas em sessão) e comparo se existe alguma máquina aberta pelo banco, e se tiver eu vejo qual está mais atual o do banco ou do registro e seto as váriaveis de tempo solicitado e tempo restante para os valores mais corretos. Evitando assim a perda de tempo quando a um desligamento indevido.

Toda vida que eu entro no sistema primeiro eu verifico se á máquina em que eu estou está com uma sessão aberta (sempre que eu finalizo a sessão eu insiro os dados em uma tabela de movimentação e apago da tabela que eu utilizo para as maquinas logadas) apenas vendo se existe um registro com o maquina que eu estou utilizando (eu também gravo todas as máquinas que se logam em uma tabela que tem: Número do IP, e Nome do Computador)

Em relação a verificar as restrições você pode simplismente comparar os valores do registro com os gravados no banco (No meu caso eu utilizo uma tabela onde eu gravo o código da máquina e valores Boolean para cada restrição) se forem diferente (Ex: no banco o campo RESTRINGIR_PAINEL está marcado como TRUE e a chave respectiva no registro estiver marcada como 0 (equivale a FALSE) você pode dar uma mensagem avisando que irá ser feito o logoff para que as restrições sejam feitas e alterar o valor no registro e fazer o logoff para fazer as restrições).
Outro modo de fazer isso por exemplo no meio de uma sessão utilizando os components da palheta INDY (da uma olhada no exemplo de chat) tipo: Eu envio para á máquina (pego o IP gravado no banco) uma mensagem tipo RESTRINGIR, e na minha aplicação cliente eu vou ter uma rotina que vai ler a mensagem RESTRINGIR e fazer o procedimento de restrições.

Em relação aos preços eu vou fazer de dois modos,
1º através de cartões aonde eu determino o tempo e o preço do cartão
2º através de um preço predefinido para a hora.

Se a hora por exemplo custar R$ 2,50 então para saber o valor do segundo eu pego 2,50 e divido por 3600 (que é a quantidade de segundos que tem em uma hora). Dai é só multiplicar o resultado pela quantidade de segundos que se está utilizando (eu gravo no banco em segundos (um valor inteiro) pois fica mais fácil de calcular as horas. Eu achei um pouco complicado utilizando-se de campos do tipo Time).

Para mostrar para o usuário o tempo que ele utilizou ou tempo restante você pode fazer do seguinte modo para transformar a quantidade de tempo em segundo no formato ´HH:MM:SS´:

Var
  Tm:TDateTime;
  sTEMPO_ATUAL : String;
begin
  Tm := 0;
  tm := incSecond(tm,iTEMPO_UTIL);
  sTEMPO_ATUAL := TimeToStr(tm);
  LbTempoRest.Caption := sTEMPO_ATUAL;

Ps: A função incSecond nescessita a unit DateUtils declarada na uses do form.

Cara esse é um exemplo do modo que eu estou utilizando na minha aplicação, obviamente que deve de haver outros modos de fazer a mesma coisa.
É apenas uma idéia.


Responder

Gostei + 0

22/08/2007

Visualdesigner

achei o seu código excelente, é realmente tudo que preciso, bate com as minhas idéias.

Só deu um erro na linha Ico.SetSize(32,32);

Gostaria de ver com você se você não vende o código fonte deu seu software para somente para eu desenvolver algumas idéias o mas rápido possível, pois tenho uma lan house e vc deve saber que os programas de lan house nem sempre tem aquilo que gente preciso, geralmente tem até mais do que precisamos, mas de vez em quando tempos a necessidade de uma coisa nova, então a gente fica na mão. Não precisa ser o programa totalmente montado, só preciso de algumas partes do fonte. Mas faz um esforço pra me ajudar cara, pois estou precisando muito.


Caso, você possa me fornecer ou vender me add: josimar_nil@hotmail.com


Responder

Gostei + 0

22/08/2007

Vitor Alcantara

Caro visualdesigner essa minha aplicação não está completa, pois não estou tendo muito tempo para me dedicar a ela, mais qualquer coisa podemos continuar trocando idéias por esse forum mesmo.
Recomendo a você dar uma ohada nesse forum http://forum.devmedia.com.br/viewforum.php?f=42 ele ta bastante destatualizado mais as idéias que contem nele são muito boas.

Quanto ao comando ´Ico.SetSize(32,32)´ tem que ter a unit Graphics declarada na uses do teu form.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar