我有以下代码:
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中的第二个0只是一个随机的int我坚持在那里,我不知道什么用于int hWndInsertAfter
像pidgin这样的多个窗口的进程呢?
答案 0 :(得分:25)
只需取出Control.FromHandle和form == null check。你应该能够做到:
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 with EnumWindows而不是迭代进程列表并使用MainWindowHandle。
答案 1 :(得分:2)
玩这个。看看它是否有帮助。
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);
}
}
}
}