Página 1 de 2

Como saber se o aplicativo está Minimizado?

Enviado: 26 Jul 2014 17:57
por Jairo Maia
Olá Pessoal,

Tem como eu saber se o aplicativo em Harbour está minimizado ou maximizado?

Sei como pegar o Handle da janela ao iniciar o aplicativo, então estou por exemplo tentando usar a função GetForeGroundWindow(), e fazer a verificação, e então queria voltar a janela do aplicativo ao primeiro plano em determinada situação usando a função SetActiveWindow(), mas não sei qual lib linkar para essas funções, e a rigor, não sei se seria possível com elas o resultado que gostaria.

A situação que gostaria de resolver é a seguinte: Determinado usuário está usando outro aplicativo, ou está com o navegador da internet aberto. Determinado operador enviou alguma mensagem a este usuário usando o messenger do aplicativo em Harbour e precisa da resposta. Como eu fazer para quando meu aplicativo receber uma mensagem forçar aparecer em primeiro plano? Pode ser nativo em Harbour ou em alguma função em C para integrar a meu sistema.

Alguém conhece algo desse tipo, ou então, em qual lib estão as funções acima para que eu possa testar se consigo com elas?

Como saber se o aplicativo está Minimizado?

Enviado: 26 Jul 2014 20:30
por Pablo César
Oi Jairo,

Esta solução já foi apresentada aqui em algum lugar do fórum, talvez como sempre_visivel ou So_Roda2.

Mas espero que isto seja de ajuda:

Código: Selecionar todos

#include "minigui.ch"
#define APP_TITLE 'Meu Programa'

Function Main ()
Local hWnd

IF IsExeRunning( cFileNoPath( HB_ArgV( 0 ) ) )
	MsgStop( "O programa " + APP_TITLE + " já estava sendo executado!" )
	
	hWnd := FindWindow( APP_TITLE )

	IF hWnd > 0
		IF IsIconic( hWnd )
			Restore( hWnd )
		ELSE
			SetForeGroundWindow( hWnd )
		ENDIF
	ELSE
		MsgStop( "Não foi possível encontrar a aplicação !", "Erro", , .f. )
	ENDIF
ELSE

DEFINE WINDOW Form1 ;
   AT 0,0 ;
   WIDTH 320 ;
   HEIGHT 240 ;
   TITLE "Meu Programa" ;
   MAIN
END WINDOW
CENTER WINDOW Form1
ACTIVATE WINDOW Form1

ENDIF
Return Nil

#pragma BEGINDUMP

#define HB_OS_WIN_USED
#define _WIN32_WINNT 0x0400

#include <windows.h>
#include "hbapi.h"
#include "hbapiitm.h"

HB_FUNC( ISICONIC )
{
   hb_retl( IsIconic( ( HWND ) hb_parnl( 1 ) ) );
}

HB_FUNC ( FINDWINDOW )
{
   hb_retnl( ( LONG ) FindWindow( 0, hb_parc( 1 ) ) );
}

HB_FUNC( ISEXERUNNING ) // ( cExeNameCaseSensitive ) --> lResult
{
   HANDLE hMutex = CreateMutex( NULL, TRUE, ( LPTSTR ) hb_parc(1) );

   hb_retl( GetLastError() == ERROR_ALREADY_EXISTS );

   ReleaseMutex( hMutex );
}

#pragma ENDDUMP

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 00:08
por rochinha
Amiguinhos,

Vou roubar a função IsIconic().

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 11:04
por Jairo Maia
Olá Pablo,

Obrigado por sua resposta.

Pablo, compilei seu exemplo com HMG, e é exatamente isso que preciso, mas tem um porém: Preciso usar esse recurso num sistema em Harbour+WVG, e eu precisaria do fonte da função Restore(), ou saber que lib linkar. Você tem alguma dica?

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 12:37
por janio
Jairo,

Também estou em busca desta mesma solução.

No tópico abaixo, a função Focaliza_App parece ser a solução. Porém, não consegui compilar as funções em c.

viewtopic.php?f=4&t=8283&p=46482&hilit=pisca_exe#p46482

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 17:29
por rochinha
Amiguinhos,

Vendo a situação deste tópico e sabendo que existem soluções que se agregadas dão resultado resolvi sair a caça de um teste que havia feito a tempos atrás para um colega.

Neste teste agreguei as funções de uso nos tópicos conversados para vossos testes.

Ao amigo Jairo Maia tenho pra mim que ele deva acrescentar uma função que rode em background verificando a mensageria e percebendo que a mensagem foi enviada a certo usuário piscar o botão.

Para o caso daqueles usuários que usam a barra de tarefas escondida, use uma das funções expostas para mostrá-la antes de piscar o botão.

Código: Selecionar todos

#include "FiveWin.ch"
#include "dll.ch"

#Define SW_HIDE       0 // &H0
#Define SW_SHOWNA     8 // &H8
#Define SW_SHOW       5 // &H5
#Define SW_SHOWNORMAL 1

static oWnd

//----------------------------------------------------------------------------//
function Main()
   DEFINE WINDOW oWnd TITLE "Botao Iniciar"
          DEFINE BUTTONBAR oBar _3D OF oWnd
          DEFINE BUTTON OF oBar ACTION TaskBarInvisivel()
          DEFINE BUTTON OF oBar ACTION TaskBarVisivel()
          DEFINE BUTTON OF oBar ACTION StartButtonInvisivel()
          DEFINE BUTTON OF oBar ACTION StartButtonVisivel()
          DEFINE BUTTON OF oBar ACTION Tira_X()
          DEFINE BUTTON OF oBar ACTION Volta_X()
          DEFINE BUTTON OF oBar ACTION Pisca_EXE()
          SET MESSAGE OF oWnd TO "Botao Iniciar Windows XP/2K3/7" NOINSET CLOCK DATE KEYBOARD
   ACTIVATE WINDOW oWnd //;
   return nil

//----------------------------------------------------------------------------//

FUNCTION TaskBarInvisivel()
   ShowWindow( FindWindow( "Shell_TrayWnd", "" ), 0 ) // Taskbar
   RETURN NIL

//----------------------------------------------------------------------------//
FUNCTION TaskBarVisivel()
   ShowWindow( FindWindow( "Shell_TrayWnd", "" ), 1 ) // Taskbar
   RETURN NIL

//----------------------------------------------------------------------------//
FUNCTION StartButtonInvisivel()
   ShowWindow( FindWindowEx( FindWindow( "Shell_TrayWnd", "" ), 0, "Button", nil ), 0 ) // Taskbar
   ShowWindow( FindWindowEx( FindWindow( "Button", "Start" ), 0, "Button", nil ), 0 ) // Vista round button
   RETURN NIL

//----------------------------------------------------------------------------//
FUNCTION StartButtonVisivel()
   ShowWindow( FindWindowEx( FindWindow( "Shell_TrayWnd", "" ), 0, "Button", nil ), 1 ) // Taskbar
   ShowWindow( FindWindowEx( FindWindow( "Button", "Start" ), 0, "Button", nil ), 1 ) // Vista round button
   RETURN NIL

DLL32 FUNCTION FindWindowEx( hWndParent AS LONG, hWndChildAfter AS LONG, lpszClass AS STRING, lpszWindow AS STRING ) AS LONG PASCAL FROM "FindWindowExA" LIB "user32"
// Testei no Windows 2003 Server e no Windows Seven Ultimate.
//
// - Os dois primeiros botões manejam a barra em si, sendo que no W2K3 esconde tudo e mostra tudo. No W7 esconde/mostra somente a barra.
// - Os dois segundos botões manejam o botão Iniciar, sendo que no W2K3 esconde/mostra. No W7 voce terá de mesclar os comandos para esconder a barra e o botão junto já que ocorre algo estranho.
//

#pragma BEGINDUMP
#include "windows.h"
#include "shlobj.h"
#include "hbapi.h"
#include "math.h"
#include "hbvm.h"
#include "hbstack.h"
#include "hbapiitm.h"
#include "hbapigt.h"

HB_FUNC ( SHOWTASKBAR ) //Habilita o botao INICIAR
    {
    HWND hWnd = FindWindow( "Shell_TrayWnd", "" );
    ShowWindow( hWnd, SW_SHOW );
    }

HB_FUNC ( HIDETASKBAR ) //Desabilita o botao Iniciar
    {
    HWND hWnd = FindWindow( "Shell_TrayWnd", "" );
    ShowWindow( hWnd, SW_HIDE );
    }

HB_FUNC ( PISCA_EXE ) // VAI PISCAR O SEU EXE NA BARRA
    {
    HWND Handle = GetForegroundWindow();
    FlashWindow(Handle,TRUE); // VAI PISCAR O SEU EXE NA BARRA
    Sleep(300); // TEMPO DE ESPERA
    }

HB_FUNC ( TIRA_X ) // DESABILITA O X da janela
    {
    HMENU MenuH = GetSystemMenu(GetForegroundWindow(),FALSE);
    EnableMenuItem(MenuH,SC_CLOSE,MF_GRAYED);
    }

HB_FUNC ( VOLTA_X ) // HABILITA O X da janela
    {
    HMENU MenuH = GetSystemMenu(GetForegroundWindow(),FALSE);
    EnableMenuItem(MenuH,SC_CLOSE,MF_BYCOMMAND);
    }

HB_FUNC( ISICONIC )    
    {
    hb_retl( IsIconic( ( HWND ) hb_parnl( 1 ) ) );
    }

//HB_FUNC ( FINDWINDOW )
//    {
//    hb_retnl( ( LONG ) FindWindow( 0, hb_parc( 1 ) ) );
//    }

HB_FUNC( ISEXERUNNING ) // ( cExeNameCaseSensitive ) --> lResult
    {
    HANDLE hMutex = CreateMutex( NULL, TRUE, ( LPTSTR ) hb_parc(1) );
    hb_retl( GetLastError() == ERROR_ALREADY_EXISTS );
    ReleaseMutex( hMutex );
    }

#pragma ENDDUMP

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 19:43
por Jairo Maia
Jânio,
janio escreveu:No tópico abaixo, a função Focaliza_App parece ser a solução. Porém, não consegui compilar as funções em c.
Que tipo de problema você teve ao tentar compilar essas funções? Fiz o teste e compilou normal.

Rochinha, Obrigado por sua participação.
rochinha escreveu:Ao amigo Jairo Maia tenho pra mim que ele deva acrescentar uma função que rode em background verificando a mensageria
Já tenho esse controle, cada estação sabe quando recebeu uma mensagem e emite um sinal sonoro estando o aplicativo em Background ou Foreground. O problema é que precisei remover o sinal sonoro, e até concordo, embora ele seja bem suave, realmente cansa quando se recebe muita mensagem, enfim...
rochinha escreveu: percebendo que a mensagem foi enviada a certo usuário piscar o botão.
Ok. Boa idéia, e acho que resolveria também, porém, ao colocar a função Pisca_Exe(), ao receber a mensagem a estação pisca apenas o botão da janela ativa, e não a do meu aplicativo. Mas já é um começo...

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 21:41
por janio
Olá Jairo,

Eh que quando copiei, algumas funções tiveram quebra de linha. Mas vi aqui e consegui compilar.

Vc resolveu seu problema?? eu resolvi com essa função.

Janio

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 22:00
por janio
Jairo,

Vc pode voltar o foco para o sistema com a função do link acima, e depois restaurar a janela. Se o sistema estiver minimizado, ele restaura. Se o sistema ja estiver maximizado, nada acontece.

Código: Selecionar todos

HB_FUNC( RESTAURAJANELA )
{
    ShowWindow(( HWND) FindWindow( NULL, "Nome da Sua Janela" ), SW_RESTORE);
}

Como saber se o aplicativo está Minimizado?

Enviado: 27 Jul 2014 23:42
por rochinha
Amiguinhos,

Baseado na função do Janio deveria então ficar assim:

Código: Selecionar todos

HB_FUNC( PISCA_EXE )
{
    HWND hWnd = FindWindow( NULL, "Nome da Sua Janela" );
    FlashWindow( Handle, TRUE );
}
Depois teste com esta passando como parâmetro o nome da janela:

Código: Selecionar todos

HB_FUNC( PISCA_OUTRA_JANELA )
{
    HWND hWnd = FindWindow( NULL, (LPCSTR) hb_parc(1) );
    FlashWindow( Handle, TRUE );
}

Código: Selecionar todos

...
PISCA_OUTRA_JANELA ( "Nome da Sua Janela" )
...

Como saber se o aplicativo está Minimizado?

Enviado: 28 Jul 2014 08:23
por Pablo César
Jairo Maia escreveu:Olá Pablo,

..//..
e eu precisaria do fonte da função Restore(), ou saber que lib linkar. Você tem alguma dica?
A função RESTAURAJANELA que o Janio passou seria esa função Se não te serve, me diga que posto outra.

Como saber se o aplicativo está Minimizado?

Enviado: 28 Jul 2014 09:41
por Jairo Maia
Olá Pessoal,

Ideal seria realmente restaurar a tela, mas por enquanto ficou resolvido usando esta função:

Código: Selecionar todos

HB_FUNC ( PISCA_EXE ) // dica do Rochinha
    {
    HWND Handle = FindWindow( NULL, "Título da Janela" );
    FlashWindow(Handle,TRUE); // VAI PISCAR O SEU EXE NA BARRA
    }
Quanto a função RestauraJanela() do Jânio, também funciona, mas na seguinte condição: O aplicativo precisa ser no máximo o penúltimo a ter sido usado, quando não for ela não restaura a tela. Como será comum o usuário estar com o aplicativo, o Navegador e o OutLokk abertos, e alternando entre eles, preferi não usa-la para não gerar confusão.

Por exemplo: O usuário está no aplicativo, e clica no botão do navegador. Se neste intervalo chega uma mensagem a função RestauraJanela() funciona, e o aplicativo vem para o primeiro plano. Porém, se entre esse intervalo ele clica no navegador, e depois no outlook, então não consegue recuperar o foco, e o botão apenas pisca.

Legal, é que após piscar o botão ele continua em cor lranja escuro, chamando atenção, e como tenho como capturar o clique do mouse mesmo em BackGround, a cada clique faço a chamada novamente ao Pisca_Exe(). E ficou acordado que se após 30 segundos do último clique do mouse, a mensagem ainda estiver pendente então sim emite o sinal sonoro. Por enquanto em teste assim, vamos ver.

Por enquanto, muito obrigado a todos.

Como saber se o aplicativo está Minimizado?

Enviado: 28 Jul 2014 11:23
por janio
Jairo,

Aqui aconteceu algo interessante mas sem nada a ver com a ordem que as janelas perdem o foco. Nao consegui restaurar uma determinada janela quando ela não foi minimizada da "maneira oficial". Ou seja, o usuario clicou em outros botoes na barra de tarefas sem minimizar oficialmente o sistema. Nesse caso, realmente a janela do sistema nao foi restaurada. Mas quando o usuario minimiza o sistema clicando no botaozinho "_", ele pode mudar o foco pra quantas janelas for que e ainda assim a funçaõ "RestauraJanela" funciona.

Pra resolver esse problema em qualquer situação, antes de mandar restaurar a janela, deu o foco a ela:
- Focaliza_App( NomeAplic )
- RestauraJanela(NomeAplic)

Pronto, assim funciona (pelo menos pra mim) em qualquer situação, que o usuario tenha minizado o sistema "oficialmente", ou nao.

Outra coisa, esse sistema de troca de mensagens entre usuarios que vc usa eh aquele q foi postado pelo Jose Quintas??

Como saber se o aplicativo está Minimizado?

Enviado: 28 Jul 2014 11:37
por janio
Perae!

Na verdade quando vc da o foco para a janela do seu sistema, ele ja restaura mesmo que a aplicação esteja minimizada. Ou seja, nem precisa da função "RestauraJanela", mas apenas de dar o foco novamente ao sistema.

Todavia, no seu caso, acho q a melhor solução é mesmo apenas piscar o exe na barra de tarefas. Pode ser que o usuario esteja fazendo algo importante e mesmo vendo que tem alguem querendo conversar com ele, ele prefere terminar o que estava fazendo e depois abrir a janela de conversação.

Ja pensou estar respondendo a um e-mail e a cada vez que chega uma mensagem vem aquela janela e "toma a vez" daquilo que vc tava fazendo!?!?!? meio chato isso...

Janio

Como saber se o aplicativo está Minimizado?

Enviado: 28 Jul 2014 20:51
por Jairo Maia
Olá Jânio,
janio escreveu:Nao consegui restaurar uma determinada janela quando ela não foi minimizada da "maneira oficial".
Verdade. Constatei isso há pouco. Durante meus testes sempre eu minimizava, depois testava. Realmente ocorre esse problema.
janio escreveu:Pra resolver esse problema em qualquer situação, antes de mandar restaurar a janela, deu o foco a ela:
- Focaliza_App( NomeAplic )
- RestauraJanela(NomeAplic)
Pois é. Fiz esse teste e o comportamento não muda conforme a situação que citei antes. Apenas pisca o botão.
janio escreveu:Todavia, no seu caso, acho q a melhor solução é mesmo apenas piscar o exe na barra de tarefas.
Agora também concordo. Foi muito bem recebida essa ideia inicialmente proposta pelo Rochicha. Ficou bom sim.
janio escreveu:Ja pensou estar respondendo a um e-mail e a cada vez que chega uma mensagem vem aquela janela e "toma a vez" daquilo que vc tava fazendo!?!?!? meio chato isso...
É que neste caso Jânio, as mensagens são de caráter profissional, e elas têm prioridade Zero. São referentes a várias situações, mas a principal é solicitar ao escritório a liberação de um cadastro ou cheque do banco "X" CPF "Y". A operadora após a liberação recebe um protocolo que anota no verso do cheque, ou se for o caso, solicita ao cliente para dirigir-se ao escritório.
janio escreveu:Outra coisa, esse sistema de troca de mensagens entre usuarios que vc usa eh aquele q foi postado pelo Jose Quintas??
Não é. Esse sistema foi desenvolvido ainda em Clipper especificamente para esse sistema, e na migração para Harbour esse foi inclusive redesenhado. É um processo muito especifico. Cheguei a pensar em divulgar no fórum na época que o José estava postando a ideia dele, mas vi que não era tão simples. Em Clipper ele era monitorado pela minha função do Mouse, em Harbour via Idle.

Bom... a Boa notícia já dei acima, foi bem aceito, mas a má notícia é que pela manhã instalei compilado com a versão 3.4, e por volta de 12h00m recebi a reclamação que o sistema já havia Travado 2 vezes. Como isso já havia acontecido com a versão 3.2, então recompilei com a versão 3.0 e troquei. trabalhou normal durante o restante do dia. Preciso entender o que está ocorrwndo com esse aplicativo e as versões mais novas. Uma pena, até porque a velocidade de processamento do Harbour 3.4 em rede, cara, você vai até extranhar. É muito boa (DBF/CDX).