GARANTIR DESCONTO

Fórum Posicionamento da Calculadora #357047

13/04/2008

0

Saudações delphianas!!


Eu desenvolvi uma pequena aplicação onde a tela possui 2 divisões: na 1ª, o usuário escolhe qual o tipo de cálculo ele quer fazer (por. ex. IMC - índice de massa corpórea). na 2ª, aparecem os campos referentes ao tipo de cálculo escolhido. O problema é que há uma opção para que o usuário utilize a calculadora do windows para efetuar um outro cálculo. Eu gostaria que a calculadora fosse executada e centralizada dentro do panel, que fica na 2ª divisão. Eu até encontrei alguma coisa (tópico ´Execultar programa externo´), mas só funciona se a calculadora já estiver aberta.

Aí eu tentei fazer isso:

procedure TForm6.Button1Click(Sender: TObject);
var
Handle: THandle;
begin
Handle := FindWindow(nil, ´Calculadora´);
if Handle > 0 then
Windows.SetParent(Handle, Panel1.Handle)
else
begin
WinExec(´calc.exe´, SW_SHOWDEFAULT);
Windows.SetParent(Handle, Panel1.Handle);
end;
end;

O problema é que a calculadora é executada fora do panel, se eu clicar novamente no botão, aí a calculadora é executada dentro do panel.

Existe alguma forma de executar direto no panel, e de preferência centralizada?

[]s


Roger1976

Roger1976

Responder

Posts

14/04/2008

Rodc

Acho que o seu código estava errado. Não testei, mas testa este código abaixo:
procedure TForm6.Button1Click(Sender: TObject); 
var 
Handle: THandle; 
begin 
  Handle := FindWindow(nil, ´Calculadora´); 
  if Handle > 0 then 
    Windows.SetParent(Handle, Panel1.Handle) 
  else 
  begin 
    WinExec(´calc.exe´, SW_SHOWDEFAULT); 
    Handle := FindWindow(nil, ´Calculadora´);
    if Handle > 0 then 
        Windows.SetParent(Handle, Panel1.Handle); 
  end; 
end; 



Responder

Gostei + 0

14/04/2008

Martins

Acho que o seu código estava errado. Não testei, mas testa este código abaixo:
procedure TForm6.Button1Click(Sender: TObject); 
var 
Handle: THandle; 
begin 
  Handle := FindWindow(nil, ´Calculadora´); 
  if Handle > 0 then 
    Windows.SetParent(Handle, Panel1.Handle) 
  else 
  begin 
    WinExec(´calc.exe´, SW_SHOWDEFAULT); 
    Handle := FindWindow(nil, ´Calculadora´);
    if Handle > 0 then 
        Windows.SetParent(Handle, Panel1.Handle); 
  end; 
end; 


Esse código aqui deve realmente funcionar, pq verifica se já existe um Handle para a calculadora para poder colocá-la dentro do Panel, caso contrário executa a calculadora e verifica novamente.

Vale testá-lo.

Boa sorte.


Responder

Gostei + 0

14/04/2008

Roger1976

rodc e martins, funcionou, mas ainda preciso fazer 2 ajustes: colocar a calculadora no centro do panel e fazer com que execute a calculadora apenas uma vez, pq senão vcs sabem como é usuário, ele vai abrir várias calculadoras.

Muito obrigado pela força de vcs, e se tiverem algumas sugestão, agradeço.

[]s


Responder

Gostei + 0

15/04/2008

Rodc

O código abaixo move a calculadora para o canto superior do Panel, é só fazer o cálculo para centralizar. Eu testei em C++, por isso não sei como exatamente é no Delphi, tenta aí...
procedure TForm6.Button1Click(Sender: TObject); 
var 
Handle: THandle; 
rect: TRect;
begin 
  Handle := FindWindow(nil, ´Calculadora´); 
  if Handle > 0 then 
    Windows.SetParent(Handle, Panel1.Handle) 
  else 
  begin 
    WinExec(´calc.exe´, SW_SHOWDEFAULT); 
    Handle := FindWindow(nil, ´Calculadora´); 
    if Handle > 0 then 
        Windows.SetParent(Handle, Panel1.Handle); 
  end; 

  if Handle > 0 then
  begin
    Windows.GetWindowRect(Handle, rect);     // Pega a posição da calculadora
    Windows.MoveWindow(Handle, 0, 0, rect.right-rect.left, rect.bottom-rect.top, true);   // Move a posição da calculadora
  end;
end;

Uma coisa que percebi é que a calculadora fica em memória depois, por isto, sugiro antes de fechar o programa fazer a calculadora sair do panel ou guardar o Handle da calculadora para fechá-la usando a função
PostMessage(Handle, WM_CLOSE, 0, 0);



Responder

Gostei + 0

15/04/2008

Roger1976

Caro rodc, agora ficou bom. A tela do sistema fica centralizada, e qdo o usuário executaVA a calculadora, ela aparecia numa outra posição. Graças a sua dica, ficou melhor.

Muito obrigado!

[]s


Responder

Gostei + 0

15/04/2008

Marco Salles

Caro rodc, agora ficou bom. A tela do sistema fica centralizada, e qdo o usuário executaVA a calculadora, ela aparecia numa outra posição. Graças a sua dica, ficou melhor.


[b:c66db98d8d]´mas acho´[/b:c66db98d8d] que voce pode melhorar ainda mais o seu codigo ..
aproveitando um pouco do que foi falado aqui e utilizando refectoring
no codigo , alem do que [b:c66db98d8d]´eu acho´[/b:c66db98d8d] que o codigo postado tem erro de logica pois o WinExec(´calc.exe´, SW_SHOWDEFAULT); sempre será executado , por isso que voce observou deste do inicio :

citação de rogger
[b:c66db98d8d]
e fazer com que execute a calculadora apenas uma vez,
[/b:c66db98d8d]

então sugiro que se tente o codigo abaixo :

//guardar o Handle da calculadora para fechá-la
 private
    { Private declarations }
    hCalc:THandle;

procedure TForm1.Button1Click(Sender: TObject);
var
Hjanela,hmemo: THandle;
rect: TRect;
begin
hJanela := FindWindow( ´TForm1´, nil );
hMemo := FindWindowEx( hJanela, 0, ´TPanel´, nil );
hCalc := FindWindowEx( hmemo, 0,´scicalc´,nil );
if hcalc <= 0 Then
  begin
     WinExec(´calc.exe´, SW_SHOWDEFAULT);
     hcalc := FindWindow(nil, ´Calculadora´);
     Windows.SetParent(hcalc, Panel1.Handle);
     Windows.GetWindowRect(hCalc, rect);     // Pega a posição da calculadora
     Windows.MoveWindow(hCalc, 0, 0, rect.right-rect.left, rect.bottom-rect.top, true);   // Move a posição da calculadora
  end
else
 Windows.SetParent(hcalc, Panel1.Handle);
end;


[b:c66db98d8d]citação de rodc...[/b:c66db98d8d]
Uma coisa que percebi é que a calculadora fica em memória depois, por isto, sugiro antes de fechar o programa fazer a calculadora sair do panel ou guardar o Handle da calculadora para fechá-la usando a função
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if hCalc > 0 Then
PostMessage(Hcalc, WM_CLOSE, 0, 0);
end;


espero ter sido util


Responder

Gostei + 0

15/04/2008

Roger1976

Caro Marco Salles, boas observações, porém há 2 questões que eu gostaria de colocar em debate:

1ª- não acho interessante para o usuário q veja a calculadora se movimentando para dentro do panel, sei q é muito rápido, mas fica estranho;

2ª- não estou conseguindo fazer com que a calculadora seja executada apenas uma vez, ou seja, tem que haver uma condição que verifique se a calculadora está sendo executada, se estiver, não poderá carregá-la novamente.

Muito obrigado a você e ao rodc pelas dicas, e espero por uma resposta para saber se o que foi questionado é possível de se fazer ou não (principalmente a 1ª questão).

[]´s


Responder

Gostei + 0

15/04/2008

Dopi

Acho que seria muito melhor usar um componente de Calculadora...
Criar uma dependencia de um programa externo não é uma boa... E se a calculadora não estiver instalada ? E se estiver sendo exibida no modo científico ?

Na Jedi existe uma calculadora... No ACBr temos o [b:c058d37a81]ACBrCalculadora [/b:c058d37a81]que contempla apenas as operações básicas, mas permite vc posiciona-la onde quiser... além de uma bobina (memo) com as operações efetuadas

Vc pode usar uma função que chame o programa externo e aguarde pelo seu termino... seria parecido com um ShowModal...

{-----------------------------------------------------------------------------
 - 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

15/04/2008

Marco Salles

Caro Marco Salles, boas observações, porém há 2 questões que eu gostaria de colocar em debate: 1ª- não acho interessante para o usuário q veja a calculadora se movimentando para dentro do panel, sei q é muito rápido, mas fica estranho; 2ª- não estou conseguindo fazer com que a calculadora seja executada apenas uma vez, ou seja, tem que haver uma condição que verifique se a calculadora está sendo executada, se estiver, não poderá carregá-la novamente.


Voce esta [b:b8bacd91bc]fazendo confusão[/b:b8bacd91bc] .... o codigo que lhe enviei é exatamente para que a calculadora não seja chamada mais de uma Vez ..

Por acso voce colocou o método e executou :?: :?: :?: :?:
... Perceba que o
WinExec(´calc.exe´, SW_SHOWDEFAULT); 

[b:b8bacd91bc]é executado somente uma vez[/b:b8bacd91bc]

Agora quanto a sua primeira obervação ,
1ª- não acho interessante para o usuário q veja a calculadora se movimentando para dentro do panel, sei q é muito rápido, mas fica estranho;

Ai já é outra história

Primeiro vamos resolver a Segunda pendência , pq ela é bem mais antiga
A primeira pendencia é novissima , voce esta levantando agora .


Responder

Gostei + 0

16/04/2008

Roger1976

Marcos Salles, eu fiz um teste e realmente a calculadora é executada + de uma vez, eu percebi isso qdo cliquei no botão umas 3 vezes. Ao mover a calculadora, percebi q tinha outra por trás. Por via das dúvidas, eu copiei o código que você postou e colei no projeto, e mesmo assim não resolveu. Agora uma pergunta sobre a condição, se hcalc > 0, a calculadora não será executada mais de uma vez?

Dopi, infelizmente não poderei utilizar o componente que você citou no projeto, por uma questão de regra. No entanto, para estudo, vou testá-lo em casa sim, pois poderá ser útil em um projeto futuro onde eu tenha uma liberdade maior de utilizar o componente que eu quiser.


Responder

Gostei + 0

16/04/2008

Marco Salles

Marcos Salles, eu fiz um teste e realmente a calculadora é executada + de uma vez, eu percebi isso qdo cliquei no botão umas 3 vezes. Ao mover a calculadora, percebi q tinha outra por trás. Por via das dúvidas, eu copiei o código que você postou e colei no projeto,[b:850aba4600] e mesmo assim não resolveu[/b:850aba4600]. Agora uma pergunta sobre a condição, se hcalc > 0, a calculadora não será executada mais de uma vez?


Voce tem certeza que o codigo que lhe passei abre mais de uma calculadora ????? Aqui comigo posso de garantir que so so Abre uma .

Agora uma pergunta sobre a condição, se hcalc > 0, a calculadora não será executada mais de uma vez?

Observe que hcalc é uma variavel declarada na secção Private e não é uma variavel Local .. Se voce estiver declarando no esboço da procedure
ai sim , não irá resolver

De Qualque modo vou repetir o codigo :

 private
    { Private declarations }
     hCalc:THandle;


 procedure TForm1.Button1Click(Sender: TObject);
var 
Hjanela,hmemo: THandle;
rect: TRect;
begin
hJanela := FindWindow( ´TForm1´, nil );
hMemo := FindWindowEx( hJanela, 0, ´TPanel´, nil );
hCalc := FindWindowEx( hmemo, 0,´scicalc´,nil );
if hcalc <= 0 Then
  begin
     WinExec(´calc.exe´, SW_SHOWDEFAULT);
     ShowWindow(FindWindow(nil,´calc.exe´),SW_HIDE);
     hcalc := FindWindow(nil, ´Calculadora´); 
     Windows.SetParent(hcalc, Panel1.Handle); 
     Windows.GetWindowRect(hCalc, rect);     // Pega a posição da calculadora
     Windows.MoveWindow(hCalc, 0, 0, rect.right-rect.left, rect.bottom-rect.top, true);   // Move a posição da calculadora 
  end 
else
 Windows.SetParent(hcalc, Panel1.Handle);

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if hCalc > 0 Then
  PostMessage(Hcalc, WM_CLOSE, 0, 0);
end;



Responder

Gostei + 0

16/04/2008

Rodc

Vale lembrar que o exemplo do MarcosSalles vai funcionar se o seu formulário se chama Form1. No exemplo do Roger o formulário se chamava Form6. É preciso mudar o nome do formulário no primeiro FindWindow().


Responder

Gostei + 0

16/04/2008

Roger1976

Marcos Salles, agora sim, está funcionando perfeitamente. A diferença é que no primeiro código que vc postou não tinha a linha abaixo:

[b:b897d35501]ShowWindow(FindWindow(nil,´calc.exe´),SW_HIDE);[/b:b897d35501]

Sobre a 1ª questão que eu levantei, de ficar visível para o usuário o movimento, mesmo que rápido, da calculadora para o panel, de repente estou querendo algo que não seja possível, mas fica aí uma questão interessante, pois se tiver como, aí ficará perfeito.

rodc, bem observado, vc sabe como é, às vezes algum processo no sistema não funciona por causa de um mísero detalhe.

Obrigado a vcs pela ajuda, foi um grande aprendizado.

[]s


Responder

Gostei + 0

16/04/2008

Marco Salles

Marcos Salles, agora sim, está funcionando perfeitamente. A diferença é que no primeiro código que vc postou não tinha a linha abaixo: ShowWindow(FindWindow(nil,´calc.exe´),SW_HIDE);


[b:40efd567f8]vai entender [/b:40efd567f8]:?: :?: :?: ... Acho que o primeiro codigo funciona .. Na verdade esta linha apareceu no segundo post , porque estava tentando que a calculadora ficasse invisível e aparecer finalmente no panel . Mas não ocorreu conforme eu esperava ... Não seu pq o codigo do promeiro post não deu certo para voce :?: :?: :?: :?:

Bem enfim sobre a primeira questão :

Sobre a 1ª questão que eu levantei, de ficar visível para o usuário o movimento, mesmo que rápido, da calculadora para o panel, de repente estou querendo algo que não seja possível, mas fica aí uma questão interessante, pois se tiver como, aí ficará perfeito.


tem que perder um pouquinho de tempo na net .

a minha simples duvida é , não sei o porque mas a instrução

[b:40efd567f8]WinExec(´calc.exe´, SW_Hide); [/b:40efd567f8]

Abre a calculadora , mas ela não fica invisivel ????? To sem entender

Algume sabe o Porque ?????


Responder

Gostei + 0

17/04/2008

Roger1976

Marcos Salles, tenho uma pergunta a fazer que acabei me esquecendo: o que significa o parâmetro ´scicalc´? Ah, vou seguir sua sugestão e vasculhar na net para encontrar a resposta da 1ª questão, se é que existe a possibilidade.

Valeu pela força!

[]s


Responder

Gostei + 0

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

Aceitar