将进程句柄窗口位置设置为屏幕中心时,它是否正常工作,但并非在所有情况下都是如此?

时间:2015-07-07 16:55:46

标签: c# .net winforms

如果进程尚未运行,则在form1中运行它,将其置于前面并将其置于屏幕中心。如果已经运行的流程只将它带到前面并使其居中:

if (AutoIt.AutoItX.WinExists(existingProcessName, "") == 0) // Window not found
            {
                int processId = AutoIt.AutoItX.Run(processFileName, "", AutoIt.AutoItX.SW_SHOW);
                SetProcessWindow.BringToFront(processId);
                SetProcessWindow.CenterProcessWindow(processId);
                Thread.Sleep(10000);
                AutoIt.AutoItX.MouseClick("LEFT", 358, 913, 1, -1);

            }
            else
            {
                Process[] processes = Process.GetProcessesByName(processName);
                SetProcessWindow. BringToFront(processes[0].Id);
                SetProcessWindow.CenterProcessWindow(processes[0].Id);
                Thread.Sleep(10000);
                AutoIt.AutoItX.MouseClick("LEFT", 358, 913, 1, -1);
            }

类SetProcessWindow:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing;

namespace UsingAutoIt
{
    class SetProcessWindow
    {
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        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
        }

        private const int SWP_NOSIZE = 0x0001;
        private const int SWP_NOZORDER = 0x0004;
        private const int SWP_SHOWWINDOW = 0x0040;

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

        public static void BringToFront(int processId)
        {
            Process process = Process.GetProcessById(processId);
            IntPtr handle = process.MainWindowHandle;

            if (handle == IntPtr.Zero)
                return;

            SetForegroundWindow(handle);
        }

        public static void CenterProcessWindow(int processId)
        {
            Process process = Process.GetProcessById(processId);
            IntPtr handle = process.MainWindowHandle;

            if (handle != IntPtr.Zero)
            {
                RECT rct;
                GetWindowRect(handle, out rct);
                Rectangle screen = Screen.FromHandle(handle).Bounds;
                Point pt = new Point(screen.Left + screen.Width / 2 - (rct.Right - rct.Left) / 2, screen.Top + screen.Height / 2 - (rct.Bottom - rct.Top) / 2);
                SetWindowPos(handle, IntPtr.Zero, pt.X, pt.Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
            }


        }
    }
}

问题是如果进程已经运行并且我将进程窗口拖动到屏幕角落之一,则单击空白在屏幕中,所以现在进程在后台然后运行我的程序它将带来进程句柄窗口到前面并居中。

但是如果我将进程窗口拖到屏幕中的某个位置而不是中心并退出进程然后运行我的程序并且它正在运行该进程它将把它带到前面但不会将它居中。

为什么当进程没有运行而我的程序正在运行它的中心时呢?

1 个答案:

答案 0 :(得分:1)

您的进程窗口会立即显示,但它没有完全设置,因此您甚至无法获得调试结果,因为如果您通过调试器,将会有足够的时间通过并创建句柄,因此一切都可以正常工作。您需要做的是等待设置MainWindowHandle。您可以像这样修改CenterProcessWindow方法:

public static void CenterProcessWindow(int processId)
{
    Process process = Process.GetProcessById(processId);

    while (process.MainWindowHandle == IntPtr.Zero)
        process.Refresh();

    IntPtr handle = process.MainWindowHandle;

    RECT rct;
    GetWindowRect(handle, out rct);
    Rectangle screen = Screen.FromHandle(handle).Bounds;
    Point pt = new Point(screen.Left + screen.Width / 2 - (rct.Right - rct.Left) / 2, screen.Top + screen.Height / 2 - (rct.Bottom - rct.Top) / 2);
    SetWindowPos(handle, IntPtr.Zero, pt.X, pt.Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
}