Das Forentreffen 2018 findet am 20./21. April in Dresden statt. Weitere Infos hier
Anmeldungen zum Forentreffen 2018 sind auf der Anmeldeseite möglich
Zur Homepage des Deutschsprachige Xbase-Entwickler e. V.
Xbase++-Wiki des Deutschsprachige Xbase-Entwickler e. V.

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: 10738
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Eigenes Programm inden Vordergrund holen

Beitrag von AUGE_OHR » Mi, 24. Feb 2016 8:50

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: 13907
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Eigenes Programm inden Vordergrund holen

Beitrag von brandelh » Mi, 24. Feb 2016 9:44

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) 42-mal heruntergeladen
Gruß
Hubert

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10738
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Eigenes Programm inden Vordergrund holen

Beitrag von AUGE_OHR » Mi, 24. Feb 2016 21:02

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: 10738
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Eigenes Programm inden Vordergrund holen

Beitrag von AUGE_OHR » Mi, 24. Feb 2016 23:10

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: 780
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Kontaktdaten:

Re: Eigenes Programm inden Vordergrund holen

Beitrag von satmax » Do, 25. Feb 2016 7:36

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