Autor Beitrag
Jakob Schöttl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Mi 03.01.07 15:56 
Hi,
ich will grad ein Programm machen (ehrlich gesagt nachmachen), das das aktive Fenster Topmost bzw. nicht Topmost macht.

Dazu hab ich folgenden Quelltext zum auspobieren geschrieben. Leider funktioniert er nicht, und ich weiß nicht, wo der Fehler ist.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var wh: HWND; //Fenster Handle
    style: DWORD; //Fenster Style
begin
  wh := GetForegroundWindow;
  if wh > 0 then begin    
    style := GetWindowLong(wh,GWL_EXSTYLE);
    if (style and WS_EX_TOPMOST) = WS_EX_TOPMOST then begin
      ShowMessage('gerade noch topmost');
      style := style and not WS_EX_TOPMOST; //nach hinten setzen
    end else begin
      showMessage('gerade noch nicht topmost');
      style := style or WS_EX_TOPMOST; //nach vorne setzen
    end;
    SetWindowLong(wh,GWL_EXSTYLE,style);    
  end;
end;


Hoffentlich findet jemand meinen Fehler.
Reinhard Kern
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Mi 03.01.07 16:45 
user profile iconJakob Schöttl hat folgendes geschrieben:
Hi,
ich will grad ein Programm machen (ehrlich gesagt nachmachen), das das aktive Fenster Topmost bzw. nicht Topmost macht.

Dazu hab ich folgenden Quelltext zum auspobieren geschrieben. Leider funktioniert er nicht, und ich weiß nicht, wo der Fehler ist.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var wh: HWND; //Fenster Handle
    style: DWORD; //Fenster Style
begin
  wh := GetForegroundWindow;
  if wh > 0 then begin    
    style := GetWindowLong(wh,GWL_EXSTYLE);
    if (style and WS_EX_TOPMOST) = WS_EX_TOPMOST then begin
      ShowMessage('gerade noch topmost');
      style := style and not WS_EX_TOPMOST; //nach hinten setzen
    end else begin
      showMessage('gerade noch nicht topmost');
      style := style or WS_EX_TOPMOST; //nach vorne setzen
    end;
    SetWindowLong(wh,GWL_EXSTYLE,style);    
  end;
end;


Hoffentlich findet jemand meinen Fehler.


Hallo,

nach meinem jetzigen Kenntnisstand kann das so nicht funktionieren: GetForegroundWindow liefert das gewünschte Window, egal welches, aber SetWindowLong kann nur Werte setzen in Windows, die zum eigenen Prozess gehören. Das ist Folge der Abschottung zwischen Prozessen, dient also der Sicherheit. Unter 16bit-Anwendungen ging das und geht das auch heute noch.

Zu umgehen ist das etwa so (für SetForegroundWindow):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  FGThread := GetWindowThreadProcessID (GetForegroundWindow,nil);
  OtherThread := GetWindowThreadProcessID (FIWindow,nil);
  AttachThreadInput (FGThread,OtherThread,true);
  SetForegroundWindow (FIWindow);
  AttachThreadInput (FGThread,OtherThread,false);


Es kann sein, dass in zukünftigen Versionen die Schotten weiter dicht gemacht werden. In einem wirklich sicheren System siehst du nur deine eigene Anwendung, der Rest geht dich nichts an.

Gruss Reinhard
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 04.01.07 13:07 
ja, das kann sein.
Aber in diesem Fall muss der Fehler wo anders liegen, weil ich nähmlich das Ereignis OnClick meines Buttons verwende. Ich hab schon überprüft. Die Handles von Form1 (meinem eigenen) und GetForegroundWindow stimmen überein, weil mein Fenster auch im Vordergrund ist. Und trotzdem geht es nicht.

Das auslesen des attributes TopMost funktioniert richtig!

Es muss also meiner Meinung an ungefähr folgendem liegen (Auszüge von oben):

ausblenden Delphi-Quelltext
1:
style := style and not WS_EX_TOPMOST; //nach hinten setzen					


ausblenden Delphi-Quelltext
1:
style := style or WS_EX_TOPMOST; //nach vorne setzen					


ausblenden Delphi-Quelltext
1:
SetWindowLong(wh,GWL_EXSTYLE,style); //Werte setzen. wh ist ganz sicher das Handle von Form1					
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 04.01.07 14:05 
Also, obwohl ich glaube ich in der Logik keinen Fehler hatte, geht es so nicht.

Aber jetzt hab ich eine Möglichkeit gefunden, das problem anders zu lösen, nähmlich doch mit SetWindowPos:

ausblenden Delphi-Quelltext
1:
SetWindowPos(wh,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE + SWP_NOMOVE);					

bzw.
ausblenden Delphi-Quelltext
1:
SetWindowPos(wh,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE + SWP_NOMOVE);					


... und das geht übrigens auch (noch) mit externen Anwendungs-Fenstern.
Reinhard Kern
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Do 04.01.07 19:14 
user profile iconJakob Schöttl hat folgendes geschrieben:
Also, obwohl ich glaube ich in der Logik keinen Fehler hatte, geht es so nicht.

Aber jetzt hab ich eine Möglichkeit gefunden, das problem anders zu lösen, nähmlich doch mit SetWindowPos:

ausblenden Delphi-Quelltext
1:
SetWindowPos(wh,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE + SWP_NOMOVE);					

bzw.
ausblenden Delphi-Quelltext
1:
SetWindowPos(wh,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE + SWP_NOMOVE);					


... und das geht übrigens auch (noch) mit externen Anwendungs-Fenstern.


Hallo, zu deiner Beruhigung:

Microsoft selbst empfiehlt, Fenster mit SetWindowPos auf Top zu setzen (KB von 1993), allerdings mit einer anderen Begründung: MDI-Fenster können nicht den Stil WS_EX_TOPMOST haben. Wahrscheinlich ist SetWindowPos auch deshalb noch eine der wenigen Funktionen, denen der Zugriff auf fremde Fenster erlaubt ist.

Gruss Reinhard
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 04.01.07 20:13 
Gut, hier hab ich jetzt mein Programm zum Download reingestellt. Wenns das Forum hier nicht gäbe, würde ich noch lange nach der Lösung meines Problems suchen...