Jump to content
Fivewin Brasil

Como saber se a janela do sistema está minimizada ou em foco?


emotta

Recommended Posts

A minha idéia é a seguinte:

Imagina que o usuário mande gerar um relatório que demore uns 5minutos para aparecer o preview. Então ele vai digitar por exemplo o periodo, selecionar a impressora e confirmar. Neste momento o sistema começa a processar as informações para gerar o preview do relatorio. O usuário não vai ficar parado esperando, ele pode por exemplo, abrir o Outlook para ver os emails. Então o sistema, quando gerar o preview eu quero apresentar uma mensagem de notificação na Tray informando "Relatório gerado e disponível para visualização". E então o usuário volta a dar o foco na janela do sistema, com ALT+TAB ou então clicando na janela do sistema na task bar.

O detalhe é que somente quero exibir esse balão de notificação na Tray se o sistema não estiver em foco, ou seja, se ele mandar processar o relatorio e ficar esperando olhando pra tela o sistema não exibe o balão de notificação na tray.

Para ficar simples de implementar fiz uma função para ser usada no final de cada relatório chamada: EMTNOTIFY e então sempre ao final dos relatorios eu coloco:

EmtNotify("Relatório gerado")

O fonte deste minha função é:

Function EmtNotify(cMsg,cTitulo)
Local c
Default cTitulo := "Atenção"

c = GetNotifyIconData( oWndMain:hWnd, 1, 0, nil, cMsg, cTitulo )

lSuccess = Shell_NotifyIcon( NIM_ADD, @c )

return NIL

Mas quero colocar um IF para somente mostrar quando o usuário não estiver "visualizando" o sistema, por exemplo, vendo os emais no outloook. Eu tentei assim e não funcionou:

Function EmtNotify(cMsg,cTitulo)
Local c
Default cTitulo := "Atenção"

If !oWndMain:lFocused
c = GetNotifyIconData( oWndMain:hWnd, 1, 0, nil, cMsg, cTitulo )

lSuccess = Shell_NotifyIcon( NIM_ADD, @c )
EndIf

return NIL

Eduardo.

Eu uso IF( oBjeto:lFocused) dentro de dialogs mas sempre tem uma função validando.

No seu caso, não captei exatamente como e porque ?

Link to comment
Share on other sites

É isso mesmo que desejo porem eis a questão, como identificar que o usuário não está com a janela do sistema em foco...

Ja tentei o oWndMain:lFocused e nao da certo....

abraços

ola

nao consegue controlar isso atravez de uma variavel boleana ?? alternando ela pra .T. e/ou .F. conforme situacao...

att

Gilberto

Link to comment
Share on other sites

isso não resolve para minha necessidade... nao é saber se um objeto especifico está em foco e sim se o sistema está aberto no plano principal... Por exemplo, no código preciso saber se o usuário está com a janela do sistema aberto em primeiro plano ou se por exemplo ele está vendo o Outlook naquele exato momento.

IF(oObj:lFocused)
    RETURN(.T.)
ENDIF

IF(!oObj:lFocused)
    RETURN(.T.)
ENDIF

Eduardo, estou sem tempo. mas veja de ajuda.

Link to comment
Share on other sites

STATIC FUNCTION teste()
? "Teste"
SysWait(20)
IF(!oDlg:lFocused)
    ? "To lendo na internet."
ENDIF
RETURN(.T.)

Coloquei um botão na dialog só para testar.

chamei a função Teste() e fui para o IE

Apesar de ser só uma mensagem, da para ver o resultado.

Ai se vc vai trazer o sistema para o focu ou vai mandar uma mensagem no tray, é contigo.

Link to comment
Share on other sites

Sergio, ja tinha feito um teste semelhante e não funcionou. No caso de um sistema ele tem a Window principal e ai chama as DIALOGS, GETS, etc... Então o oWndMain:lFocused fica .F. porque o foco está em um GET por exemplo.

Só pra vc fazer o teste mais real coloque no seu sistema este PRG que compilou mas na hora da verificação faça com o objeto da window principal do sistema. Pode reparar que mesmo tendo o foco no seu sistema o oWndMain:lFocused fica com .F. pois o foco está em outro objeto do seu sistema...

Ta dificil...

mas obrigado pela tentativa

STATIC FUNCTION teste()
? "Teste"
SysWait(20)
IF(!oDlg:lFocused)
    ? "To lendo na internet."
ENDIF
RETURN(.T.)

Coloquei um botão na dialog só para testar.

chamei a função Teste() e fui para o IE

Apesar de ser só uma mensagem, da para ver o resultado.

Ai se vc vai trazer o sistema para o focu ou vai mandar uma mensagem no tray, é contigo.

Link to comment
Share on other sites

Algo assim Eduardo?




#include "FiveWin.ch"

FUNCTION Main()

LOCAL oDlg
LOCAL oGet
LOCAL cGet := "test"
LOCAL oCheck2

SetCancel( .T. )

DEFINE DIALOG oDlg size 400, 400 TITLE "A Dialog Box"

@ 2, 2 GET oGet VAR cGet OF oDlg

oGet:bLostFocus := { || Show_Focus( oDlg, oGet, cGet ) }

@ 3, 2 CHECKBOX oCheck2 PROMPT "This is a second CHECKBOX" OF oDlg

@ 5, 4 BUTTON "&Ok" OF oDlg SIZE 40, 12 ACTION oDlg:End()

@ 5, 15 BUTTON "&Cancel" OF oDlg SIZE 40, 12 ACTION oDlg:End()

ACTIVATE DIALOG oDlg

RETURN NIL

FUNCTION Show_Focus( oDlg, oGet, cGet )

LOCAL i
LOCAL lReturn := .F.

i := AScan( oDlg:aControls, { | o | o:hWnd == GetFocus() } )

IF i > 0

nMsgBox( "Dialog element '" + oDlg:aControls[ i ] :cCaption + "' has the focus" )

ELSE

nMsgBox( "Can't determin focus!" )

ENDIF

RETURN lReturn

/*
nAt = AScan( oDlg:aControls, { | o | o:lFocused } )

if nAt != 0
MsgInfo( oDlg:aControls[ nAt ]:ClassName() )
// MsgInfo( oDlg:aControls[ nAt ]:nId )
endif

oControlConFoco = oDlg:aControls[ AScan( oDlg:aControls, { | o | o:lFocused } ) ]
*/

Link to comment
Share on other sites

mais ou menos por ai... vc me deu uma idéia... vou testar e ja posto o codigo...

vlwww

Algo assim Eduardo?
#include "FiveWin.ch"
 
FUNCTION Main()
   
   LOCAL oDlg
   LOCAL oGet
   LOCAL cGet := "test"
   LOCAL oCheck2
   
   SetCancel( .T. )
   
   DEFINE DIALOG oDlg size 400, 400 TITLE "A Dialog Box"
 
   @  2,  2 GET oGet VAR cGet OF oDlg
 
   oGet:bLostFocus := { || Show_Focus( oDlg, oGet, cGet ) }
   
   @  3,  2 CHECKBOX oCheck2 PROMPT "This is  a second CHECKBOX" OF oDlg
 
   @  5,  4 BUTTON "&Ok" OF oDlg SIZE 40, 12 ACTION oDlg:End()
 
   @  5, 15 BUTTON "&Cancel" OF oDlg SIZE 40, 12 ACTION oDlg:End()
 
   ACTIVATE DIALOG oDlg
   
RETURN NIL
 
FUNCTION Show_Focus( oDlg, oGet, cGet )
 
   LOCAL i
   LOCAL lReturn := .F.
 
   i := AScan( oDlg:aControls, { | o | o:hWnd == GetFocus() } )
 
   IF i > 0
 
     nMsgBox( "Dialog element '" + oDlg:aControls[ i ] :cCaption + "' has the focus"  )
 
   ELSE
 
      nMsgBox( "Can't determin focus!" )
 
   ENDIF
 
RETURN lReturn
 
/*
nAt = AScan( oDlg:aControls, { | o | o:lFocused } )
 
if nAt != 0
   MsgInfo( oDlg:aControls[ nAt ]:ClassName() )
   // MsgInfo( oDlg:aControls[ nAt ]:nId )
endif

oControlConFoco = oDlg:aControls[ AScan( oDlg:aControls, { | o | o:lFocused } ) ]
*/
Link to comment
Share on other sites

Fiz esse codigo e não funcionou. Ele sempre acusa que está em foco, mesmo quando dou alt+tab e vou para outra aplicação. Segue o codigo, caso alguem possa ajudar...

#include "fivewin.ch"

Static aTipos := {}

Function Teste2()
ThreadSleep(1000*5)
If IsAplFocus(oWndMain)
MsgStop("está em foco")
Else
MsgStop("não está em foco")
EndIf

Return


Static Function IsAplFocus(oWnd)
Local nI,nJ
Local lRet := .f.
Local nPos

cClass := oWnd:ClassName()
For nI := 1 to Len(oWnd:aControls)
nPos := aScan(aTipos,{|x|x==oWnd:aControls[nI]:ClassName() })
If nPos == 0
aadd(aTipos,oWnd:aControls[nI]:ClassName())
EndIf

If AllTrim(Upper(oWnd:aControls[nI]:ClassName())) in "TFOLDER"
For nJ := 1 to Len(oWnd:aControls[nI]:aDialogs)
lRet := IsAplFocus(oWnd:aControls[nI]:aDialogs[nJ])
If lRet
Return lRet
EndIf
Next
EndIf
If oWnd:aControls[nI]:hWnd == GetFocus()
lRet := .t.
Exit
EndIf
Next

Return lRet

Link to comment
Share on other sites

Veja bem.

Apenas fiz um teste rápido simulando uma situação.

- Sistema aberto

- Janela aberta (com um botão para simular um processamento longo)

- Clique no botão, desviando para a função Teste()

Ao executar a função, fui para o IE.

Veja bem, testei a dialog, e não a window.

Processamento concluído (syswat(20))

Retorna a mensagem "To lendo a internet".

Acho que se tratar o retorno chega ao que vc quer.

Link to comment
Share on other sites

Sergio, faça o mesmo teste mas nao saia do seu sistema... Fique nele sem fazer nada apos apertar o botao... Eu fiz esse teste aqui e no meu, mesmo estando com meu sistema em foco, ele informou que está fora... Provavelmente vai acontecer o mesmo se voce fizer esse teste...

Veja bem.

Apenas fiz um teste rápido simulando uma situação.

- Sistema aberto

- Janela aberta (com um botão para simular um processamento longo)

- Clique no botão, desviando para a função Teste()

Ao executar a função, fui para o IE.

Veja bem, testei a dialog, e não a window.

Processamento concluído (syswat(20))

Retorna a mensagem "To lendo a internet".

Acho que se tratar o retorno chega ao que vc quer.

Link to comment
Share on other sites

Kapiaba, resolveu. Só que a função do jeito que está ela vai piscar a janeja do aplicativo que está em foco e não a do sistema. Por exemplo, se o foco estiver no Outlook ele vai piscar o do outlook. Então mudei para que na chamada eu passe o handle da window principal do sistema e mudei o codigo dela. entao ficou assim:

HB_FUNC ( PISCA_EXE ) // VAI PISCAR O SEU EXE NA BARRA
{

FlashWindow(hb_parnl( 1 ),TRUE); // VAI PISCAR O SEU EXE NA BARRA

Sleep(300); // TEMPO DE ESPERA
}

Na chamada é só fazer

Pisca_Exe(oWndMain:hWnd)

Não era exatamente o que eu queria mas isso ja ajudou.... Obrigado a todos !

Link to comment
Share on other sites

Sambo, leia na 1a pagina logo no inicio eu explico meus motivos....

Quanto a forçar o foco voce imagina que o usuario mandou gerar um relatorio e enquanto gera está lendo um email, no meio da leitura o relatorio fca pronto e ai mando o foco pra aplicação... Eu não gostaria dessa situação. Quero apenas apresentar a notificação que o relatorio ficou pronto e ai quando ele quiser ele da o foco na aplicação. Porem não fica legal dar a notificação quando ele está na aplicação.

Resolvi por enqanto fazendo o icone do sistema na task_bar piscar. Ficou show de bola, porque se está em foco ele só pisca e ja era e quando não esta em foco ele pisca e dps fica em destaque, da mesma forma que o MSN ficava quando alguem mandava mensagem e voce nao abria a janela. Mas gostaria de alem disso implementar com a notificação.

Não deveria simplesmente forçar o foco na sua aplicação sempre?
Se já tiver na sua aplicação não vai fazer diferença, se tiver em outra vai forçar a ir pra sua...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...