Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - BringToFront: MACHEN, nicht nur in Taskleiste blinken!


galagher - Mi 28.05.08 17:30
Titel: BringToFront: MACHEN, nicht nur in Taskleiste blinken!
Hallo!

Ich kriege folgenden Effekt nicht weg: Ich möchte aus einem Formular ein anderes, bereits geöffnetes, in den Vordergrund holen und verwende dazu BringToFront. Keines der Formulare ist StayOnTop oder wird Modal angezeigt. Einfach ganz normale Form's.

Aber der Aufruf BringToFront bewirkt nicht (immer) das Gewünschte, stattdessen blinkt der Button des Forms ein paar Mal in der Taskleiste auf und das aufrufende Fenster bleibt im Vordergrund. Ich möchte aber das aufgerufene Fenster in den Vordergrund bringen! StayOnTop möchte ich aber dafür nicht verwenden.

Was also tun?

//Edit: Das ist ein eigenes Hilfedatei-Format, mit dem ich das machen will. F1 holt also zunächst ganz wie gewünscht das Hilfefenster in den Vordergrund. Dann möchte der User zB. eine Datei öffnen. Er klickt im Öffnen-Dialog den Hilfebutton an (das Hilfefenster ist schon offen und im Hintergrund), und nun passiert's: Blinken statt BringToFront!
Oder man ruft es erstmalig auf, zB. mit F1 (oder mit dem Hilfemenü): Es erscheint wie gewünscht über dem aufrufenden Fenster. Man wechselt zum Programmfenster, das Hilfefenster bleibt offen. Ein nochmaliges F1 sollte es nun wieder in den Vordergrund bringen, aber -> es blinkt nur der Taskleisten-Eintrag!

Ich hoffe, das ist einigermassen verständlich...


jaenicke - Mi 28.05.08 17:58

Eine Lösung: StayOnTop setzen, Application.ProcessMessages, StayOnTop wieder weg


Silas - Mi 28.05.08 18:03

Moin,

du könntest es mit SetForegroundWindow(Handle) versuchen.


galagher - Mi 28.05.08 18:13

user profile iconjaenicke hat folgendes geschrieben:
Eine Lösung: StayOnTop setzen, Application.ProcessMessages, StayOnTop wieder weg

Gibt's nichts Direktes? Ich meine, liegt das nun an Windows, denn der Aufruf BringToFront wird ja angenommen und ausgeführt, halt nicht so, wie es gedacht ist!
Aber ich werde mal mit StayOnTop -> (evtl. BringToFront) Aufruf -> fsNormal experimentieren, mal sehen.

Noch ein Beispiel:
Der Benutzer klickt im Programmfenster auf ein Objekt - Button, Hyperlink, egal was - die Hilfe erscheint wie gewünscht. Das Hilfefenster überdeckt nun nicht ganz das Programmfenster, d.h., dieses kann man an den Seiten noch sehen, links und rechts hinter der Hife. Der Benutzer klickt nun auf ein anderes Objekt, und nun müsste doch folgendes passieren: 1. Durch das Klicken wird das Programmfenster das aktive und kommt nach vorne. 2. Das Klicken löst aber einen Aufruf aus, der an das Hilfefenster gesendet wird, und dieses müsste nun nach vorne kommen. Steht doch so im Quelltext! Das geht aber nur ein paar Mal, danach blinkt bloss der Taskleistenbutton. Der Aufruf wird anonsten korrekt ausgeführ, d.h., das Ganze ist korrekt programmiert und funktioniert. Ich habe daher stark den Verdacht, dass das eine Windows-Sache ist, und das ist öde!

Gibt's vielleicht was Ähnliches oder Besseres wie BringToFront, das aber funktioniert?


jaenicke - Mi 28.05.08 18:14

Also ich habe jedenfalls keine Lösung gefunden, die immer funktioniert hätte. Dies war dann die Notlösung als letzter Ausweg bei mir.


galagher - Mi 28.05.08 18:16

user profile iconSilas hat folgendes geschrieben:
du könntest es mit SetForegroundWindow(Handle) versuchen.

Danke, mal sehen! (Hab deinen Post zu spät bemerkt!)

Aber alles erst später, erst mal "Steckerlfisch" (= österreichisch -> gegrillter Fisch, Forelle oder so :mrgreen: ) essen gehen!

Danke erstmal!


galagher - Do 29.05.08 18:28

Hallo!

Danke, aber leider haben die Vorschläge alle nichts genützt, es blinkt immer noch!

Hier eine Lösung - es blinkt zwar immer noch in der Taskleiste, aber in den meisten Fällen (warum nicht immer, weiss ich nicht) wird das Fenster brav in den Vordergrund gebracht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
{Erzwingt die Anzeige eines nicht modalen Fensters als}
{modales Fenster und bringt es so in den Vordergrund}
function ForceTopMostWindow(hwnd: THandle): LongBool;
begin
 Result := SetWindowPos(hwnd, HWND_TOPMOST, 0000, SWP_NOMOVE or
                        SWP_NOSIZE or SWP_NOACTIVATE);
end;

{Setzt ein mit ForceTopMostWindow als modal im Vordergund}
{angezeigtes Fenster als nicht-modal zurück}
function ForceNoTopMostWindow(hwnd: THandle): LongBool;
begin
 Result := SetWindowPos(hwnd, HWND_NOTOPMOST, 0000, SWP_NOMOVE or
                        SWP_NOSIZE or SWP_NOACTIVATE);
end;

Wenn das jemand noch verbessern kann, nur keine Scheu!

//Edit: Fisch war super! :D