gpt4 book ai didi

c# - 将所有打开的窗口从任何进程移动到主屏幕的中心

转载 作者:行者123 更新时间:2023-11-30 13:45:51 25 4
gpt4 key购买 nike

我正在尝试制作一个 winforms 程序,它允许我将所有打开的窗口从任何进程移动到我的主监视器的中心。我平均打开 15 个以上的窗口,在我晚上离开之前,大约需要一分钟的时间才能将所有内容移到我的主显示器上。我需要将它们移到我的主显示器上,这样如果我远程处理客户的问题,我就不必处理将它们从屏幕上移开的问题。我在看一个链接 here但这只显示窗口名称文本和长度。我相信我需要使用 EnumWindows api 来执行此操作,但我不知道最好的方法。我也在查看 GetWindow 函数 here ,但不确定如何使用它。另外,我知道如何将我的 winforms 移动到屏幕中央,所以这不是问题。对此有任何见解表示赞赏。

最佳答案

如果您想要移动所有窗口,而不仅仅是打开应用程序拥有的窗体,您可以使用 EnumWindows

[DllImport("USER32.DLL")]
public static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

然后,在您的代码中,您可以遍历打开的(和可见的)Windows:

IntPtr lShellWindow = NativeMethods.GetShellWindow();
List<IntPtr> listWindows = new List<IntPtr>();

NativeMethods.EnumWindows(delegate(IntPtr hWnd, int lParam)
{
if (hWnd == lShellWindow) return true;
if (!NativeMethods.IsWindowVisible(hWnd)) return true;

// may be some other checks

lWindows.Add(hWnd);
return true;
}, 0);

如您所见,我还使用了 IsWindowVisibleGetShellWindow

[DllImport("USER32.DLL")]
public static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("USER32.DLL")]
public static extern IntPtr GetShellWindow();

然后,使用句柄列表,您可以使用 SetWindowPos

移动窗口
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

[Flags()]
public enum SetWindowPosFlags : uint
{
/// <summary>If the calling thread and the thread that owns the window are attached to different input queues,
/// the system posts the request to the thread that owns the window. This prevents the calling thread from
/// blocking its execution while other threads process the request.</summary>
/// <remarks>SWP_ASYNCWINDOWPOS</remarks>
AsynchronousWindowPosition = 0x4000,
/// <summary>Prevents generation of the WM_SYNCPAINT message.</summary>
/// <remarks>SWP_DEFERERASE</remarks>
DeferErase = 0x2000,
/// <summary>Draws a frame (defined in the window's class description) around the window.</summary>
/// <remarks>SWP_DRAWFRAME</remarks>
DrawFrame = 0x0020,
/// <summary>Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to
/// the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE
/// is sent only when the window's size is being changed.</summary>
/// <remarks>SWP_FRAMECHANGED</remarks>
FrameChanged = 0x0020,
/// <summary>Hides the window.</summary>
/// <remarks>SWP_HIDEWINDOW</remarks>
HideWindow = 0x0080,
/// <summary>Does not activate the window. If this flag is not set, the window is activated and moved to the
/// top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter
/// parameter).</summary>
/// <remarks>SWP_NOACTIVATE</remarks>
DoNotActivate = 0x0010,
/// <summary>Discards the entire contents of the client area. If this flag is not specified, the valid
/// contents of the client area are saved and copied back into the client area after the window is sized or
/// repositioned.</summary>
/// <remarks>SWP_NOCOPYBITS</remarks>
DoNotCopyBits = 0x0100,
/// <summary>Retains the current position (ignores X and Y parameters).</summary>
/// <remarks>SWP_NOMOVE</remarks>
IgnoreMove = 0x0002,
/// <summary>Does not change the owner window's position in the Z order.</summary>
/// <remarks>SWP_NOOWNERZORDER</remarks>
DoNotChangeOwnerZOrder = 0x0200,
/// <summary>Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to
/// the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent
/// window uncovered as a result of the window being moved. When this flag is set, the application must
/// explicitly invalidate or redraw any parts of the window and parent window that need redrawing.</summary>
/// <remarks>SWP_NOREDRAW</remarks>
DoNotRedraw = 0x0008,
/// <summary>Same as the SWP_NOOWNERZORDER flag.</summary>
/// <remarks>SWP_NOREPOSITION</remarks>
DoNotReposition = 0x0200,
/// <summary>Prevents the window from receiving the WM_WINDOWPOSCHANGING message.</summary>
/// <remarks>SWP_NOSENDCHANGING</remarks>
DoNotSendChangingEvent = 0x0400,
/// <summary>Retains the current size (ignores the cx and cy parameters).</summary>
/// <remarks>SWP_NOSIZE</remarks>
IgnoreResize = 0x0001,
/// <summary>Retains the current Z order (ignores the hWndInsertAfter parameter).</summary>
/// <remarks>SWP_NOZORDER</remarks>
IgnoreZOrder = 0x0004,
/// <summary>Displays the window.</summary>
/// <remarks>SWP_SHOWWINDOW</remarks>
ShowWindow = 0x0040,
}

在你的代码中:

internal static void MoveWindow(IntPtr intPtr, int X, int Y)
{
NativeMethods.SetWindowPos(intPtr, IntPtr.Zero, X, Y, 0 , 0, NativeMethods.SetWindowPosFlags.DoNotChangeOwnerZOrder | NativeMethods.SetWindowPosFlags.IgnoreResize);
}

如果你想让所有的窗口都居中,你可以改进这个,但这是一个好的开始;)

编辑:为了改进,您可以在 EnumWindows

中获取每个窗口的大小
List<AppWindow> listWindows = new List<AppWindow>();

NativeMethods.EnumWindows(delegate(IntPtr hWnd, int lParam)
{
if (hWnd == lShellWindow) return true;
if (!NativeMethods.IsWindowVisible(hWnd)) return true;

// may be some other checks

NativeMethods.RECT rct;

if (NativeMethods.GetWindowRect(hWnd, out rct))
{
listWindows.Add(new AppWindow()
{
Handle = hWnd,
Width = rct.Right - rct.Left,
Height = rct.Bottom - rct.Top,
});
}
return true;
}, 0);

使用 GetWindowRectRECT :

[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr 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
}

和一个名为 AppWindow 的类:

internal class AppWindow
{
private IntPtr handle ;
private Int32 height;
private Int32 width;

public IntPtr Handle
{
get { return this.handle; }
set { this.handle = value; }
}

public Int32 Height
{
get { return this.height; }
set { this.height= value; }
}

public Int32 Width
{
get { return this.width; }
set { this.width= value; }
}
}

现在,您可以计算移动窗口的位置

编辑:如何获得主屏幕的中心?轻松使用 WinForms:

int width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
int height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;

现在,屏幕的中心是width/2height/2

编辑:(总结)

foreach (AppWindow app in listWindows)
{
this.MoveWindow(app.Handle, (this.width / 2) - (app.Width/2), (this.height / 2) - (app.Height/2));
}

而且我认为这很好......(我还没有尝试过这个解决方案,但它非常接近我的一个项目)

关于c# - 将所有打开的窗口从任何进程移动到主屏幕的中心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26144757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com