在 C# 中使用 SetWindowPos 来移动窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1190423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using SetWindowPos in C# to move windows around
提问by Matt
I have the code below:
我有下面的代码:
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);
}
}
}
}
This is supposed to move every window on my desktop to 0,0 (x,y) and keep the same sizes. My problem is that only the calling app (built in C#) is getting moved.
这应该将我桌面上的每个窗口移动到 0,0 (x,y) 并保持相同的大小。我的问题是只有调用应用程序(内置在 C# 中)被移动。
Should I be using something else other than Control.FromHandle(IntPtr)? Will this only find dotnet controls? If so what should I use?
我应该使用 Control.FromHandle(IntPtr) 以外的其他东西吗?这只会找到 dotnet 控件吗?如果是这样,我应该使用什么?
Also, the second 0 in SetWindowPos was just a random int I stick in there, I'm not sure what to use for int hWndInsertAfter
此外,SetWindowPos 中的第二个 0 只是我坚持在那里的一个随机 int,我不确定用于 int hWndInsertAfter
What about processes with multiple windows like pidgin?
像 pidgin 这样具有多个窗口的进程呢?
采纳答案by Reed Copsey
Just take out your Control.FromHandle and the form == null check. You should be able to just do:
只需取出您的 Control.FromHandle 和 form == null 检查。你应该能够做到:
IntPtr handle = process.MainWindowHandle;
if (handle != IntPtr.Zero)
{
SetWindowPos(handle, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
}
If you add SWP_NOSIZE, it will not resize the window, but will still reposition it.
如果添加 SWP_NOSIZE,它不会调整窗口大小,但仍会重新定位它。
If you want to effect all windows, not just the main window, of each process, you might want to consider using P/Invoke withEnumWindowsinstead of iterating through the Process list and using MainWindowHandle.
如果您想影响每个进程的所有窗口,而不仅仅是主窗口,您可能需要考虑将P/Invoke 与EnumWindows一起使用,而不是遍历进程列表并使用 MainWindowHandle。
回答by Dagne
Played with this. See if it helps.
玩过这个。看看它是否有帮助。
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);
}
}
}
}