2009-07-27 9 views
19

ich den Code unten habe:Mit SetWindowPos in C# Fenster zu bewegen

namespace WindowMover 
{ 
    using System.Windows.Forms; 

    static class Logic 
    { 
     [DllImport("user32.dll", EntryPoint = "SetWindowPos")] 
     public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags); 

     public static void Move() 
     { 
      const short SWP_NOMOVE = 0X2; 
      const short SWP_NOSIZE = 1; 
      const short SWP_NOZORDER = 0X4; 
      const int SWP_SHOWWINDOW = 0x0040; 

      Process[] processes = Process.GetProcesses("."); 
      foreach (var process in processes) 
      { 
       var handle = process.MainWindowHandle; 
       var form = Control.FromHandle(handle); 

       if (form == null) continue; 

       SetWindowPos(handle, 0, 0, 0, form.Bounds.Width, form.Bounds.Height, SWP_NOZORDER | SWP_SHOWWINDOW); 
      } 
     } 
    } 
} 

Dies soll jedes Fenster auf meinem Desktop auf 0,0 (x, y) und immer wieder die gleichen Größen bewegen. Mein Problem ist, dass nur die aufrufende App (eingebaut in C#) verschoben wird.

Sollte ich etwas anderes als Control.FromHandle (IntPtr) verwenden? Findet das nur dotnet controls? Wenn ja, was soll ich verwenden?

Auch die zweite 0 in SetWindowPos war nur eine zufällige int ich dort bleiben, ich bin nicht sicher, was für int verwenden hWndInsertAfter

Was Prozesse mit mehreren Fenstern wie Pidgin?

Antwort

23

Nehmen Sie einfach Ihre Control.FromHandle und die Form == Null-Check. Sie sollten in der Lage sein, nur tun:

IntPtr handle = process.MainWindowHandle; 
if (handle != IntPtr.Zero) 
{ 
    SetWindowPos(handle, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); 
} 

Wenn Sie SWP_NOSIZE hinzufügen, es wird das Fenster nicht die Größe, sondern es wird immer noch neu zu positionieren.

Wenn Sie alle Fenster und nicht nur das Hauptfenster jedes Prozesses bearbeiten möchten, sollten Sie die Verwendung von P/Invoke withEnumWindows in Betracht ziehen, anstatt die Prozessliste zu durchlaufen und MainWindowHandle zu verwenden.

+0

Es gibt immer, aber einige Fenster (scheint wie jene Prozesse, die mehrere Fenster haben) bewegen sich nicht alle. BTW, du antwortest so viele meiner Fragen, ich hoffe, ich habe eines Tages so viel Programmier-Know-how .... – Matt

+0

Matt: Ich habe die Lösung dafür hinzugefügt - ich habe diese Antwort erst am Ende gesehen. EnumWindows durchläuft alle Top-Level-Fenster (nicht nur MainWindowHandle-Fenster), was Ihnen das geben soll, was Sie wollen. –

2

Gespielt mit diesem. Sehen Sie, ob es hilft.


using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 


namespace ConsoleTestApp 
{ 
class Program 
{ 
    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 

    static void Main(string[] args) 
    { 

     Process[] processes = Process.GetProcesses(); 

     foreach (var process in processes) 
     { 
      Console.WriteLine("Process Name: {0} ", process.ProcessName); 

      if (process.ProcessName == "WINWORD") 
      { 
       IntPtr handle = process.MainWindowHandle; 

       bool topMost = SetForegroundWindow(handle); 
      } 
     } 
} 
} 

Verwandte Themen