Eigenes Programm in den Vordergrund holen [erledigt]

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Eigenes Programm inden Vordergrund holen

Beitrag von AUGE_OHR »

grummel ... nun hab ich auch das Problem :(

der Witz : ich habe es auch in der AppSys und da funktioniert es d.h. das Programm wird in den Vordergrund geholt.
so bekommt man es vom "blinken" tatsächlich in den Vordergrund ... nicht schön aber so geht es (wieder)

Code: Alles auswählen

#define SW_HIDE            0
#define SW_SHOWNORMAL      1
#define SW_NORMAL          1
#define SW_SHOWMINIMIZED   2
#define SW_SHOWMAXIMIZED   3
#define SW_MAXIMIZE        3
#define SW_SHOWNOACTIVATE  4
#define SW_SHOW            5
#define SW_MINIMIZE        6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA          8
#define SW_RESTORE         9
#define SW_SHOWDEFAULT     10
#define SW_FORCEMINIMIZE   11
#define SW_MAX             11
#define SW_PARENTCLOSING   1
#define SW_OTHERZOOM       2
#define SW_PARENTOPENING   3
#define SW_OTHERUNZOOM     4

METHOD EditForm:SwitchFocus()

   IF ::lHaveFocus = .F.
      SetForegroundWindow(::nHwnd)
      BringWindowToTop(::nHwnd)
      // minimieren
      ShowWindow(::nHwnd, SW_MINIMIZE )
      // wiederherstellen
      ShowWindow(::nHwnd, SW_RESTORE )

      // Xbase++ Dialog
      SetAppWindow(::_EditForm)
      // XbPart
      SetAppFocus( ::oValues )
   ENDIF
RETURN NIL
gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Eigenes Programm inden Vordergrund holen

Beitrag von brandelh »

Im beiliegenden Testprogramm habe ich die Optionen durchprobiert.

1. SetAppWindow() => :toBack(), oDlg:toFront() - in dem Falle das CMD Fenster, der Dialog bleibt wo er ist, also nicht genau

2. oDlg => :toBack(), oDlg:toFront() - in dem Falle wird das Fenster genau definiert und es funktioniert "im Prinzip" ;-)

Beide Möglichkeiten beziehen sich jedoch auf SetAppWindow() selbst, d.h. man kann nur innerhalb seiner Anwendung damit "to Front" kommen ...

Code: Alles auswählen

      oDlg:alwaysOnTop := .t.
      oDlg:configure()
holt das Fenster auf jeden Fall ganz nach vorne, egal welches normale Fenster grad aktiv ist (wenn das auch "alwaysOnTop" ist, weiß ich nicht was passiert).
aber

Code: Alles auswählen

      oDlg:alwaysOnTop := .f.
      oDlg:configure()
bringt es nicht nach hinten, dafür muss man beides kombinieren:

Code: Alles auswählen

      oDlg:alwaysOnTop := .f.
      oDlg:configure()
      oDlg:toBack()
...
      oDlg:alwaysOnTop := .t.
      oDlg:configure()
      oDlg:toFront()
Ich habe das beiliegende Programm mit 1.90.355 auf Win 7 getestet, mal sehen ob es unter Win10 auch noch geht ;-)
Dateianhänge
WindowOnTop.zip
(5.04 KiB) 282-mal heruntergeladen
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Eigenes Programm inden Vordergrund holen

Beitrag von AUGE_OHR »

hi,

es gibt noch eine einfachere Möglichkeit. wie ich schon sagte funktioniert der Code in der AppSys ohne Probleme.

wenn man also das Programm nach vorne holen will startet man es einfach nochmals ;)

Code: Alles auswählen

METHOD EditForm:SwitchFocus()
   IF ::lHaveFocus = .F.
      RunShell( "","test.exe",.T.,.F.)
   ENDIF
RETURN NIL
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Eigenes Programm inden Vordergrund holen

Beitrag von AUGE_OHR »

Antwort von Pablo.
> try

Code: Alles auswählen

@ot4xb:ForceForegroundWindow( hWnd )
das ist keine "normale" API Function sondern eine ot4xb Function. deshalb nützt ein Suche bei Google nichts.
---
hier der Auszug aus dem Source WndTool.CPP

Code: Alles auswählen

DWORD OT4XB_API ot4xb_call_in_gui_thread_(ULONG np, DWORD dwfp , ... )
{
   DWORD dwResult = 0;
   if( _hWndDelegate_ )
   {
      DWORD * pStack = (DWORD*) _xgrab( (np + 2) * sizeof(DWORD) );
      ULONG n = np;
      va_list pva;
      pStack[n] = dwfp;
      va_start(pva,dwfp);
      while(n){n--;pStack[n] = va_arg(pva,DWORD);}
      dwResult = (DWORD) SendMessage(_hWndDelegate_,_nMsgCall32_,(WPARAM)np,(LPARAM)pStack);
   }
   return dwResult;
}


void OT4XB_API  ot4xb_ForceForegroundWindow(HWND hWnd)
{
   if(!IsWindow(hWnd)) return;
   DWORD nTimeOut       = 0;
   HWND  hPrevFWnd      = GetForegroundWindow();
   DWORD nNewThreadId   = GetCurrentThreadId();
   DWORD nOldThreadId   = GetWindowThreadProcessId(hPrevFWnd,0);
   if(nNewThreadId != nOldThreadId)
   {
      AttachThreadInput(nNewThreadId, nOldThreadId, TRUE);
      SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,0,&nTimeOut,0);
      SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
      if(AllowSetForegroundWindow_fp){ (*AllowSetForegroundWindow_fp)(-1);}
      SetForegroundWindow(hWnd);
      SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,(void*)nTimeOut,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
      AttachThreadInput(nNewThreadId, nOldThreadId, FALSE);
      return;
   }
   SetForegroundWindow(hWnd);
}
//----------------------------------------------------------------------------------------------------------------------
void OT4XB_API ForceForegroundWindow(HWND hWnd)
{
   _ot4xb_gen_hwnd_delegate_(hWnd);
   ot4xb_call_in_gui_thread_(  1 , (DWORD) ot4xb_ForceForegroundWindow , hWnd );
}
gruss by OHR
Jimmy
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Eigenes Programm inden Vordergrund holen

Beitrag von satmax »

Danke Jimmy und Pablo!

All you need is

Code: Alles auswählen

RestoreWindow(hWndToTop)
@ot4xb:ForceForegroundWindow( hWndToTop )
Damit funktionieren alle Variationen die ich getestet habe.
Gruß
Markus
Antworten