![]() |
"Echte" Sichtbarkeitsprüfung
Moin moin,
für mein aktuelles Projekt versuche ich herauszufinden, ob ein Fenster sich in einem bestimmten Bereich befindet. Allerdings ist das ganze ein wenig verzwickter, ich hab da nämlich noch ein boolean, das sagt "soll im bereich sein" bzw. sagt "soll nicht im bereich sein". Ich zeige mal ein wenig code...
Delphi-Quellcode:
ich rechne also zuerst das schnittrechteck zwischen dem zu überprüfenden bereich und dem fenster aus. dann den flächeninhalt dieses rechtecks. wenn der größer ist als ein bestimmter puffer, ist das fenster im bereich.
GetWindowRect(handle,r);
IntersectRect(ir,r,area); intersectspace := abs((ir.Right - ir.Left) * (ir.Bottom - ir.Top)); if ((intersectspace >= puffer) xor IsValidSpace) then begin machwas; end; Wenn das Boolean IsValidSpace wahr ist UND das fenter sich im bereich befindet, dann ist für mich alles ok, und es muss nichts gemacht werden. Am besten mach ich mal ne wahrheitstabelle...
Code:
Das ist doch eindeutig ein Fall für eine XOR-Verknüpfung, oder?
A = "fenster im bereich?"
B = "Bereich valide?" C = "Muss ich was tun?" 1 = wahr 0 = falsch A|B|C -+-+- 0|0|0 => fenster ist nicht im nicht validen bereich => alles ok 0|1|1 => fenster ist nicht im validen bereich => was tun! 1|0|1 => fenster ist im nicht-validen bereich => was tun! 1|1|0 => fenster ist im validen bereich => alles ok Warum funktioniert es dann nicht? Ich bekomme ziemlich unerklärliche (wenn auch reproduzierbare^^) Ergebnisse. Mach ich beim Schneiden irgendwas falsch? |
Re: "Echte" Sichtbarkeitsprüfung
Hallo Lukas,
GetWindowRect liefert Bildschirmkoordinaten. Befinden sich in der Variablen area vielleicht lokale Koordinaten, welche erst in Bildschirmkoordinaten umgerechnet werden müssen? Gruß Hawkeye |
Re: "Echte" Sichtbarkeitsprüfung
Hallo Lukas,
deine Flächenberechnung solltest du davon abhängig machen, ob das Rechteck ir leer ist:
Delphi-Quellcode:
Ostergrüße vom marabu
begin
// ... if not IsRectEmpty(ir) then if ((intersectspace >= puffer) xor IsValidSpace) then begin machwas; end; // ... end; |
Re: "Echte" Sichtbarkeitsprüfung
@hawkeye: nein. Kann ich ausschließen. area ist normalerweise der gesamte Bildschirm, also 0|0-1024|768 oder ähnlich.
@marabu: werd ich probieren... aber wenn es leer ist, heisst das doch nur, dass der erste teil false ergibt, also "nicht im bereich" -> as expected... EDIT: das muss sogar mit aufgenommen werden. denn wenn das rect leer ist und IsValidSpace true, also "nicht im validen Bereich", will ich ja was machen. |
Re: "Echte" Sichtbarkeitsprüfung
Zitat:
Delphi-Quellcode:
Durch deinen Einsatz von Abs() ignorierst du die Bedingung für ein leeres Rechteck.
function InterSectRect(var rect: TRect; const r1, r2: TRect): Boolean;
begin rect.Left := Max(r1.Left, r2.Left); rect.Top := Max(r1.Top, r2.Top); rect.Right := Min(r1.Right, r2.Right ); rect.Bottom := Min(r1.Bottom, r2.Bottom); Result := (rect.Left <= rect.Right) and (rect.Top <= rect.Bottom); end; Zitat:
Delphi-Quellcode:
marabu
begin
// ... if IsRectEmpty(ir) then intersectspace := 0 else intersectspace := abs((ir.Right - ir.Left) * (ir.Bottom - ir.Top)); if ((intersectspace >= puffer) xor IsValidSpace) then begin machwas; end; // ... end; |
Re: "Echte" Sichtbarkeitsprüfung
@marabu:
Jetzt hast Du ja doch noch Deinen InterSectRect-Algorithmus verraten! 3_of_8 wird sich freuen. :mrgreen: Falls Lukas aber die Routine aus Windows.pas nimmt, dann gilt das hier: Zitat:
Gruß Hawkeye |
Re: "Echte" Sichtbarkeitsprüfung
Zitat:
hab das jetzt so nachgebildet:
Delphi-Quellcode:
und dann folgerichtig meinen anfänglichen code wieder eingetragen:
if not IntersectRect(ir,r,area) then
begin ir.left := 0; ir.Top := 0; ir.Right := 0; ir.Bottom := 0; end;
Delphi-Quellcode:
Kurioserweise bekomme ich jetzt nur die Borland-IDE und die Anwendung selbst in machwas geliefert (das ist ein teil einer EnumWindowsProc)...
intersectspace := abs((ir.Right - ir.Left) * (ir.Bottom - ir.Top));
if ((intersectspace > 50) xor IsValidSpace) then begin machwas; end; //roter Kasten: Ja, genau.... |
Re: "Echte" Sichtbarkeitsprüfung
Zitat:
Im PSDK steht The IsRectEmpty function determines whether the specified rectangle is empty. A empty rectangle is one that has no area; that is, the coordinate of the right side is less than or equal to the coordinate of the left side, or the coordinate of the bottom side is less than or equal to the coordinate of the top side. Jetzt bin ich auch etwas ratlos. Werde mal drüber schlafen. Zitat:
marabu |
Re: "Echte" Sichtbarkeitsprüfung
OK, dann is das klar.
Ich werd jetzt meinen Code noch mal von anfang an aufziehen. Inzwischen hab ich auch die Abfrage geändert:
Delphi-Quellcode:
das sollte ja hoffentlich funktionieren... (oder schlägt da eh die compiler-optimierung zu? :mrgreen:)
if (inspace and (not spacevalid)) or ((not inspace) and spacevalid) then
machwas; |
Re: "Echte" Sichtbarkeitsprüfung
Sodele... hab das jetzt gelöst. Der relevante Code:
Delphi-Quellcode:
Hab den Puffer einfach rausgenommen.
GetWindowRect(handle,wr);
//wenn das fenster die Höhe/Breite 0 hat, ist es offensichtlich kein //relevantes fenster. if (wr.Right = wr.Left) or (wr.Bottom = wr.Top) or ((wr.Left = -32000) and Form1.CBSkipMaximized.Checked) then Exit; if (IntersectRect(ir,wr,Form1.area) xor Form1.RBValid.Checked) then Form1.ListBox1.AddItem(c,TObject(handle)); So einfach isses :gruebel: Tut wunderbar.. hab übrigens nicht deine Intersectrect hergenommen. Haben maximierte Fenster eigentlich immer das offset (-32000|-32000) ?! Den kompletten Code gibts hier: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz