Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi SetWindowPos Alternative (https://www.delphipraxis.net/174826-setwindowpos-alternative.html)

Ondeth 12. Mai 2013 14:28

Delphi-Version: XE2

SetWindowPos Alternative
 
Hallo :)

Ich würde gerne wissen, ob es noch eine andere Möglichkeit gibt, ein Fenster dauerhaft im Vordergrund anzuzeigen als :

Code:
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE + SWP_NOMOVE + SWP_NOSIZE);
Grund dafür :

Ich will mir ein kleines Programm für ein Spiel schreiben, welches nach Drücken zweier Tasten vor dem "Vollbild-Spielefenster" angezeigt werden soll. Soweit so gut...Das Programm ist fertig, nur scheint SetWindowPos nicht auszureichen , da sich mein Programm hinter dem Spielefenster öffnet ,und nicht davor... :?:

Hat einer von Euch zufällig eine Idee , wie ich das Problem lösen könnte ?

Schonmal Danke für die Antworten :)

EWeiss 12. Mai 2013 14:32

AW: SetWindowPos Alternative
 
In dem man SetWindowPos an der richtigen position im Code aufruft ;)

gruss

Ondeth 12. Mai 2013 14:34

AW: SetWindowPos Alternative
 
Ähm ... ja :D

Stehe ich echt so auf dem Schlauch ? :?

Da bleibt jetzt nur noch die Frage , was du mit richtiger Stelle meinst :cyclops:

Denn der Witz ist ja : mit anderen Programmen funktioniert es wunderbar

EWeiss 12. Mai 2013 14:38

AW: SetWindowPos Alternative
 
Zitat:

was du mit richtiger Stelle meinst
Prüfe doch einfach mal ob du dein Spielefenster wirklich geöffnet hast
bevor du SetWindowPos aufrufst.

Sollte sich die ZOrder ändern dann mußt du sie halt erneut setzen
und zwar nach jedem öffnen deines Programm Fensters.

Notfalls in einem Thread oder aber Timer(Was allerdings nicht so schön wäre)
Ein SpielFenster hat halt die Eigenschaft sich immer in den Vordergrund zu setzen.

gruss

Ondeth 12. Mai 2013 14:40

AW: SetWindowPos Alternative
 
Ok, werde ich mal ausprobieren

Fürs Erste mal Danke :thumb:

EWeiss 12. Mai 2013 14:53

AW: SetWindowPos Alternative
 
Zitat:

Zitat von Ondeth (Beitrag 1215123)
Ok, werde ich mal ausprobieren

Fürs Erste mal Danke :thumb:

Du könntest auch noch das SpielFenster deaktivieren in der zeit wo dein ProgrammFenster geöffnet ist.
Ob das sinnvoll ist kann ich nicht sagen da ich nicht weiß ob du gleichzeitig das Spielfenster noch bedienen willst.

Hier im Forum suchenEnableWindow

gruss

Ondeth 12. Mai 2013 14:57

AW: SetWindowPos Alternative
 
Hmm ...hast recht :)

Ich hatte eigentlich nicht vor das Fenster zu bedienen während das Programm geöffnet ist...

Hättest du noch eine Idee, wie sich das anstellen ließe ? :oops:

EWeiss 12. Mai 2013 15:10

AW: SetWindowPos Alternative
 
Wenn du das spiel gestartet hast deaktiviere es bevor du SetWindowPos verwendest
ansonsten wird sich das Window des Spiels wieder in den Vordergrund setzen.

Ich bin mir nicht sicher ob das überhaupt funktioniert denn bei DirektX ist das mit dem FensterHandle immer so eine sache
bin mir nicht sicher ob das im Vollbild noch gültig ist.

Prüfe also mal ob das Handle dann überhaupt noch existiert.

Delphi-Quellcode:
EnableWindow(SpielFensterHandle, False);

Beim beenden deines Programms wieder auf True setzen.

HWND_TOPMOST
Platziert das Fenster über allen nicht obersten Fenster.
Das Fenster behält seine oberste Stellung, auch wenn es deaktiviert ist.

gruss

Ondeth 12. Mai 2013 15:49

AW: SetWindowPos Alternative
 
Das Ergebnis meines "Ausprobierens" sieht folgendermaßen aus :

Code:
EnableWindow(game, False);
SetWindowPos(Handle,HWND_TOPMOST,Left,Top, Width,Height,SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
Mit dem Code wird dann ja das Spielefenster deaktiviert und das Programmfenster nach oben gebracht... (hoffe ich jetzt einfach mal ^^)

Habe das ganze mal ausprobiert , aber es klappt nicht wirklich ... Das Programmfenster erscheint immer mal wieder für Bruchteile von Sekunden im Spielefenster und verschwindet dann wieder...

Habe ich was falsch gemacht ? :?:

EWeiss 12. Mai 2013 15:52

AW: SetWindowPos Alternative
 
Delphi-Quellcode:
EnableWindow(game, False);


Was ist das game!
Hier solltest du dann das Handle des SpielFenster verwenden
Irgendwo in deinem Quelltext wirst du dieses doch ermitteln oder?
Über FindWindow und konsorten.

Irgendetwas dort hineinzuschreiben was keine gültigkeit hat wird dir nichts bringen.
Das Handle in EnableWindow und SetWindowPos müssen gültig sein.

Delphi-Quellcode:
SetWindowPos(Handle,HWND_TOPMOST,0, 0, 0, 0,SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);

Warum positionen des Fensters angeben wenn du dieses nur in der ZOrder verändern willst?
Zudem hast du flags addiert die den Resitz des Fensters grundsätzlich unterbinden..
Delphi-Quellcode:
SWP_NOMOVE + SWP_NOSIZE


gruss

Ondeth 12. Mai 2013 16:10

AW: SetWindowPos Alternative
 
Game bezeichnet bei mir das Handle des Spielefensters...
Ich hab es kurz vor dem "Codeschnipsel von eben" ermittelt.

Da werde ich doch noch einmal drüber schauen müssen :)

EWeiss 12. Mai 2013 16:14

AW: SetWindowPos Alternative
 
Zitat:

Zitat von Ondeth (Beitrag 1215138)
Game bezeichnet bei mir das Handle des Spielefensters...
Ich hab es kurz vor dem "Codeschnipsel von eben" ermittelt.

Da werde ich doch noch einmal drüber schauen müssen :)

oops.. OK ;)
Wenn das Handle von SetWindowPos das deines Programms ist dann sollte das so stimmen
vorrausgesetzt das Game Handle ist gültig.

gruss

Ondeth 12. Mai 2013 16:24

AW: SetWindowPos Alternative
 
Naja , es läuft so "halb" ...

Sobald das Spielfenster deaktiviert ist und das Fenster meines Programmes HWND_TOPMOST ist , "blitzt" mein Programmfenster immer mal wieder im Spiel auf , um Sekundebruchteile später wieder zu verschwinden :shock: Es wird eben nie "richtig" angezeigt....

Wenn ich dann durch Druck der Tastenkombination das ganze wieder rückgängig mache (also Spiel aktivieren und NOTOPMOST), ist nur das Spielefenster im Vordergrund (wie es auch sein soll :-D )

Ich glaub schon bald nicht mehr dran , dass das noch klappt :D

EWeiss 12. Mai 2013 16:33

AW: SetWindowPos Alternative
 
Zitat:

Es wird eben nie "richtig" angezeigt....
Da wäre die frage kannst du noch eingaben machen im Spiel nachdem es deaktiviert wurde?
Wenn Ja dann ist dein Handle nicht gültig für das Spielfenster.

Was du noch versuchen könntest

Delphi-Quellcode:
// Zeichnen zulassen
SendMessageW(WinHandle, WM_SETREDRAW, Integer(TRUE), 0);
// Zeichnen unterbinden
SendMessageW(WinHandle, WM_SETREDRAW, Integer(FALSE), 0);
Es wäre möglich das die Paint routine des SpieleFensters eine erneute ZOrder verursacht.

Mehr fällt mir jetzt auch nicht ein. :oops:

PS:
Wie schon gesagt DirectX Fenster haben nichts gemein mit normalen WindowFenster daher denke ich das
dein vorhaben im FullScreen nicht funktionieren wird ohne über DirectX zu gehen und eventuelle Hooks dafür
zu verwenden.

gruss

Ondeth 12. Mai 2013 16:49

AW: SetWindowPos Alternative
 
Zitat:

Da wäre die frage kannst du noch eingaben machen im Spiel nachdem es deaktiviert wurde?
Sobald ich die Maus bewege, fliege ich aus dem Spielefenster raus und mein Programmfenster wird angezeigt :)
Tastendrucke allerdings werden im Spiel übernommen :? -> Daraus schließe ich einfach mal,dass das Handle nicht gültig ist...

Jetzt werde ich aber erstmal deine Idee ausprobieren :lol:

EWeiss 12. Mai 2013 16:53

AW: SetWindowPos Alternative
 
Zitat:

Zitat von Ondeth (Beitrag 1215143)
Zitat:

Da wäre die frage kannst du noch eingaben machen im Spiel nachdem es deaktiviert wurde?
Sobald ich die Maus bewege, fliege ich aus dem Spielefenster raus und mein Programmfenster wird angezeigt :)
Tastendrucke allerdings werden im Spiel übernommen :?

Jetzt werde ich aber erstmal deine Idee ausprobieren :lol:

Viel Glück!

Einen ähnlichen Thread hatten wir schon mal..
http://www.delphipraxis.net/47398-os...mm-legen.html#

gruss

Ondeth 12. Mai 2013 17:01

AW: SetWindowPos Alternative
 
Hat sich nichts geändert , aber dein Link ist interessant(hab ich bei der Suche heute morgen wahrscheinlich übersehen)-den werde ich mir gleich mal anschauen :)

Vielen Dank für deine Hilfe & deine Zeit :thumb:

EWeiss 12. Mai 2013 19:10

AW: SetWindowPos Alternative
 
Zitat:

Vielen Dank für deine Hilfe & deine Zeit
Kein problem ;)
-------------------------------
Grundsätzlich kann man das verwirklichen was du vorhast
Dazu muss man nur die Form als Bitmap in den Speicher kopieren dann weiter auf den BackBuffer(Offscreen Surface) von DDraw.

Das Bitmap kann man mit CreateDIBSection erstellen.

Das problem dabei mal wieder wie kommt man an den BackBuffer einer DirectX Anwendung.
Solange ich das Fenster für DX selbst erstelle ist das kein problem dann geht es auch mit Fullscreen.

Hab es vorhin mal in VB auf die schnelle getestet da ich keine lust hatte die Header Dateien für Delphi zusammen zu suchen.
Da funktioniert das ohne flackern oder sonstige schwierigkeiten.

Na ja denke das hilft dir jetzt so auch nicht weiter.

gruss

BUG 12. Mai 2013 23:35

AW: SetWindowPos Alternative
 
Wenn du noch weiter suchen willst: Hier im Forum suchenoverlay ist ein gutes Stichwort.

Es scheint relativ gut möglich zu sein, ein Overlay für ein bestimmtes Spiel zu programmieren. Allgemeine Ansätze scheinen da schwieriger zu sein, vor allem weil verschieden Versionen von DirectX bzw. OpenGL gibt.

EWeiss 13. Mai 2013 09:33

AW: SetWindowPos Alternative
 
Hier ist mal ein DDraw Sample wie so etwas funktionieren könnte.
Beim beenden hab ich aber einen AV.. Und nein den find ich nicht ;)

Ein paar kleine sachen könnte auch noch verbessert werden.
Wie immer verwendung auf eigene gefahr!

Vielleicht könnte man die Zeichnen Routine der Form noch beschleunigen.
Wäre was für die DirectX Spezialisten hier.

gruss

Ondeth 13. Mai 2013 17:12

AW: SetWindowPos Alternative
 
Ok erst einmal danke für die nächsten Antworten :)

@EWeiss Ich werde das gleich mal mit dem DDraw ausprobieren

@BUG Ich werde mich mal später durch die Suchergebnisse durchackern

Werde mich dann später melden 8-)

Ondeth 15. Mai 2013 17:04

AW: SetWindowPos Alternative
 
@EWeiss So,habe noch eine Frage an dich ...

Was ist denn genau möglich mithilfe von DDraw..? Ich meine aus deiner Antwort rauszulesen , dass man die Form "nur" als Bild anzeigen lassen kann... Fällt somit jegliche Interaktion mit Knöpfen (TButton) weg,oder blick' ich hier gerade nicht durch ? :D

EWeiss 15. Mai 2013 18:12

AW: SetWindowPos Alternative
 
Zitat:

Zitat von Ondeth (Beitrag 1215445)
@EWeiss So,habe noch eine Frage an dich ...

Was ist denn genau möglich mithilfe von DDraw..? Ich meine aus deiner Antwort rauszulesen , dass man die Form "nur" als Bild anzeigen lassen kann... Fällt somit jegliche Interaktion mit Knöpfen (TButton) weg,oder blick' ich hier gerade nicht durch ? :D

Verstehe nicht was du meinst ;)
Hättest du das Projekt ausgeführt dann würde sich deine Frage erübrigen.
Klar hat man vollen zugriff auf alle Komponenten die sich auf der Form befinden.

Der Trick hierbei ist folgender.
Die Form befindet sich an X,y position auf den Desktop als Topmost wird aber von DirektX überzeichnet.
Da die Form sich nicht vor dem SpielFenster (bzw. wird überzeichnet) setzen läßt kopiere ich quasi nur das Bild der Form in den Speicher auf den "Offscreen Surface"
Durch diesen Trick kann man nun sehen wo sich die Form befindet.
Klickt man nun an der jeweiligen position Button oder was auch immer wird die Aktion auch angezeigt weil die Form zeitgleich neu in den Buffer gezeichnet wird.
Das clickevent ist natürlich genauso wie im normalen zustand und wird auch genauso ausgeführt.

Das problem ist nur wie willst du an den BackBuffer des jeweiligen Spiels kommen um deine Form dort einzublitten.
Ein Overlay "ohne hook" im VollBild ist da auch so gut wie ausgeschlossen es sei denn das Spiel wird im Fenstermodus ausgeführt.

nochmal leicht editiert :oops:

gruss

Ondeth 18. Mai 2013 15:31

AW: SetWindowPos Alternative
 
Entschuldige :oops:

Da stand ich vor ein paar tagen echt auf dem Schlauch :?

Naja ich hab mich jetzt doch mal eine Zeitlang mit deinem Projekt befasst und finde es echt toll :thumb:

Und den AV am Ende kann man ja sicherlich mal für's Erste ignorieren :P

EWeiss 18. Mai 2013 16:17

AW: SetWindowPos Alternative
 
Zitat:

Entschuldige
Kein problem ;)

Hätte dir ja gerne mehr geholfen aber das ist dann doch zuviel des guten was meine kenntnisse in DirectX angeht
dafür einen Systemweiten Hook für alle DXVersionen zu erstellen.

Machbar wäre es mit Viel Aufwand.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz