将窗口停靠在另一个窗口内

如何解决将窗口停靠在另一个窗口内

| 我有一个Winform应用程序(.NET 2.0 C#)。从这个应用程序,我想启动另一个进程(另一个winform应用程序)并将其停靠在我的窗口中(或至少使其看起来像是停靠了)。到目前为止,我只能找到有关停靠控件的信息,而不能找到单独进程中的窗口的信息。我的第一个想法是获取窗口的句柄并使用非托管系统调用将窗口的高度/宽度和位置设置到我的停靠区域。但是在开始之前,我想检查一下你们中有没有好人做过类似的事情。我可以访问要停靠的应用程序的源代码,但如果可以避免的话,不希望进行任何更改。我对什么是父应用程序具有完全的编程控制权。有什么建议吗?提前致谢!     

解决方法

我之前使用的解决方案是将应用程序窗口设置为要停靠在其中的控件的子窗口。
using System.Diagnostics;
using System.Runtime.InteropServices;

private Process pDocked;
private IntPtr hWndOriginalParent;
private IntPtr hWndDocked;

[DllImport(\"user32.dll\")]
public static extern IntPtr SetParent(IntPtr hWndChild,IntPtr hWndNewParent);

[DllImport(\"user32.dll\",SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd,int X,int Y,int nWidth,int nHeight,bool bRepaint);

private void dockIt()
{
    if (hWndDocked != IntPtr.Zero) //don\'t do anything if there\'s already a window docked.
        return;
    hWndParent = IntPtr.Zero;

    pDocked = Process.Start(@\"notepad\");
    while (hWndDocked == IntPtr.Zero)
    {
        pDocked.WaitForInputIdle(1000); //wait for the window to be ready for input;
        pDocked.Refresh();              //update process info
        if (pDocked.HasExited)
        {
            return; //abort if the process finished before we got a handle.
        }
        hWndDocked = pDocked.MainWindowHandle;  //cache the window handle
    }
    //Windows API call to change the parent of the target window.
    //It returns the hWnd of the window\'s parent prior to this call.
    hWndOriginalParent = SetParent(hWndDocked,Panel1.Handle);

    //Wire up the event to keep the window sized to match the control
    Panel1.SizeChanged += new EventHandler(Panel1_Resize);
    //Perform an initial call to set the size.
    Panel1_Resize(new Object(),new EventArgs());
}

private void undockIt()
{
    //Restores the application to it\'s original parent.
    SetParent(hWndDocked,hWndOriginalParent);
}

private void Panel1_Resize(object sender,EventArgs e)
{
    //Change the docked windows size to match its parent\'s size. 
    MoveWindow(hWndDocked,Panel1.Width,Panel1.Height,true);
}
    ,*在答案中添加一些解决方案.. ** 此代码帮助我将某些可执行文件停靠在Windows窗体中。像NotePad,Excel,Word,Acrobat Reader等等。 但是它不适用于某些应用程序。 有时,当您启动某个应用程序的处理时……等待空闲时间……并尝试获取其mainWindowHandle……直到主窗口句柄变为null为止。 所以我做了一个技巧来解决这个问题 如果您将主窗口句柄设置为null ...,然后在系统上搜索所有正在运行的进程并找到您的进程...,然后获取该进程的主haddle和将set面板作为其父级。
            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = \"xxxxxxxxxxxx.exe\";
            info.Arguments = \"yyyyyyyyyy\";
            info.UseShellExecute = true;
            info.CreateNoWindow = true;
            info.WindowStyle = ProcessWindowStyle.Maximized;
            info.RedirectStandardInput = false;
            info.RedirectStandardOutput = false;
            info.RedirectStandardError = false;

            System.Diagnostics.Process p = System.Diagnostics.Process.Start(info); 

            p.WaitForInputIdle();
            Thread.Sleep(3000);

            Process[] p1 ;
        if(p.MainWindowHandle == null)
        {
            List<String> arrString = new List<String>();
            foreach (Process p1 in Process.GetProcesses())
            {
                // Console.WriteLine(p1.MainWindowHandle);
                arrString.Add(Convert.ToString(p1.ProcessName));
            }
            p1 = Process.GetProcessesByName(\"xxxxxxxxxxxx\");
            //p.WaitForInputIdle();
            Thread.Sleep(5000);
           SetParent(p1[0].MainWindowHandle,this.panel2.Handle);
        }
         else
        {
           SetParent(p.MainWindowHandle,this.panel2.Handle);
        }
    ,这比我希望的要笨拙得多,但到目前为止已经可以了。我正在使用系统调用来强制子窗口位于反映停靠区域的位置。它还不能完美运行。我遇到了一些由ѭ2引起的奇怪情况,我仍然需要添加逻辑以防止用户直接移动子窗口。
    //This is my docking window
    private System.Diagnostics.Process notepad;
    private void windowDockTest()
    {
        /*
         * Docking notepad to panel2 of the splitcontainer
         */

        //if panel2 moves or is resized,call the docking function
        spcScript.Panel2.Move += new EventHandler(Panel2_Resize);
        spcScript.Panel2.SizeChanged += new EventHandler(Panel2_Resize);

        //Call the docking function if main form is moved
        this.LocationChanged += new EventHandler(Panel2_Resize);

        //Start the notepad process
        notepad = new System.Diagnostics.Process();
        notepad.StartInfo.FileName = \"notepad\";
        notepad.Start();

        //Wait a second for notpad to fully load
        notepad.WaitForInputIdle(1000);

        //Dock it
        Panel2_Resize(new Object(),new EventArgs());
    }

    void Panel2_Resize(object sender,EventArgs e)
    {
        //Get the screen location of panel2
        Rectangle r = spcScript.Panel2.RectangleToScreen(spcScript.Panel2.ClientRectangle);

        //Dock it
        redock(notepad.MainWindowHandle,r.X,r.Y,r.Width,r.Height);
    }

    [DllImport(\"user32.dll\")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd,IntPtr hWndInsertAfter,int x,int cx,int cy,int wFlags);
    public static void redock(IntPtr handle,int y,int width,int height)
    {
        IntPtr HWND_TOPMOST = new IntPtr(-1);
        const short SWP_NOACTIVATE = 0x0010;

        SetWindowPos(handle,HWND_TOPMOST,x,y,width,height,SWP_NOACTIVATE);
    }
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?