web-dev-qa-db-ja.com

C#でSetWindowPosを使用してウィンドウを移動する

私は以下のコードを持っています:

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);
            }
        }
    }
}

これは、デスクトップ上のすべてのウィンドウを0,0(x、y)に移動し、同じサイズを維持することになっています。私の問題は、(C#で構築された)呼び出しアプリのみが移動されることです。

Control.FromHandle(IntPtr)以外のものを使用する必要がありますか?これはdotnetコントロールのみを検出しますか?もしそうなら、私は何を使うべきですか?

また、SetWindowPosの2番目の0は、そこに固定されたランダムなintでした。inthWndInsertAfterに何を使用するかわかりません。

Pidginのような複数のウィンドウを持つプロセスはどうですか?

24
Matt

Control.FromHandleとフォーム== nullチェックを取り出すだけです。あなたはただ行うことができるはずです:

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

SWP_NOSIZEを追加すると、ウィンドウのサイズは変更されませんが、ウィンドウの位置は変更されます。

各プロセスのメインウィンドウだけでなく、すべてのウィンドウに影響を与える場合は、プロセスリストを反復処理する代わりに、 P/Invoke withEnumWindows の使用を検討してください。 MainWindowHandleを使用します。

26
Reed Copsey

これで遊んだ。それが役立つかどうかを確認します。


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); 
            }
        }
 }
}

2
Dagne