Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
WinApi GetWindowRect auf Multimonitorsystem
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

WinApi GetWindowRect auf Multimonitorsystem

beantworten | zitieren | melden

allo,



mein programm soll sich über ein anderes Programm "legen"

Dazu habe ich folgende Funktion :


if (process.ProcessName == "CtiClient")
  {
   RECT windowPos = new RECT();
   GetWindowRect(new HandleRef(this,process.Handle), out windowPos);
   this.StartPosition = FormStartPosition.Manual;
   this.SetDesktopLocation(windowPos.Left,windowPos.Top);
  }
[DllImport("user32.dll")]
 [return: MarshalAs(UnmanagedType.Bool)]
 static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);

[StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;        // x position of upper-left corner
            public int Top;         // y position of upper-left corner
            public int Right;       // x position of lower-right corner
            public int Bottom;      // y position of lower-right corner
        }


Da ich es zur Zeit nur an einer Maschine mit 3 Monitoren testen kann, habe ich den verdacht das es damit nicht so klappt.

Er zeigt mir Koordinaten an aber wenn ich darauf die Position setzte landet das Ding im Nirvana.

Mache ich was falsch ?



Grüße
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Ahrimaan am .
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

1. das wrappen in HandleRef kannst Du Dir an dieser Stelle vermutlich sparen und stattdessen IntPtr verwenden um das Handle direkt zu übergeben, es funktioniert aber auch mit HandleRef.

2. Du benutzt das falsche Handle. Versuch mal mit process.MainWindowHandle

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi MarsStein,

ich habe es auch mal mit dem MainWindowHandle probiert (Auch mal mit Outlook etc.)
Irgendwie will es aber trotzdem nicht.
Das Ding landet immer auf dem hauptscreen oben links
Ich habe auch schon nachgeschaut ob ich das irgendwo setzte aber Pustekuchen....

Ich suche einfach mal weiter vll fällt mir ja was auf.

Grüße
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

startest Du den Prozess selbst? Dann solltest Du noch process.WaitForInputIdle() aufrufen, vorher sind alle Werte 0 weil das Fenster noch nicht erstellt ist.

Hier mal ein Beispiel mit HandleRef...

  static class Program
  {
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
      public int Left;
      public int Top;
      public int Right;
      public int Bottom;
    }

    [STAThread()]
    static void Main(string[] args)
    {
      Process proc = Process.Start("notepad.exe");
      proc.WaitForInputIdle();
      RECT r;
      GetWindowRect(new HandleRef(new Object(),proc.MainWindowHandle), out r);
      Console.WriteLine("{0} {1} {2} {3}", r.Left, r.Top, r.Bottom, r.Right);
      Console.Read();
    }
  }

und eins mit IntPtr

  static class Program
  {
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
      public int Left;
      public int Top;
      public int Right;
      public int Bottom;
    }

    [STAThread()]
    static void Main(string[] args)
    {
      Process proc = Process.Start("notepad.exe");
      proc.WaitForInputIdle();
      RECT r;
      GetWindowRect(proc.MainWindowHandle, out r);
      Console.WriteLine("{0} {1} {2} {3}", r.Left, r.Top, r.Bottom, r.Right);
      Console.Read();
    }
  }

Beide Varianten funktionieren bei mir problemlos.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi MarsStein,

der Prozess ist bereits vorhanden, ich starte diesen also nicht selbst.
Das Struct wird auch mit Leben gefüllt bzw. die Funktion liefert True zurück.

Zwar mit Werten wie :

Bottom : 1305
Left : 3352
Right : 4418
Top : -329

Ich fürchte fast es liegt an den Drei Monitoren : Ich muss also die Position umrechnen evtl.

Grüße

EDIT : Multiple Monitor System Metrics

Siehe da , aus Kompatibilitätsgründen wird nur der Primary Monitor angesprochen.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Ahrimaan am .
private Nachricht | Beiträge des Benutzers