none
怎么设置外部程序的窗口大小和位置 RRS feed

  • 问题

  • 我在按钮里用Process.Start("C:\\Users\\Administrator\\Desktop\\Internet Explorer");打开浏览器  然后我想设置这个浏览器窗口的大小和位置要怎么做?打开其他程序一样可用
    2014年2月28日 8:50

答案

  • 现在关键问题是,我的p.MainWindowHandle等于0

    http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx

    请具体的看一下解释。

    TopLevel 窗体)。</sentencetext>  Refresh 方法刷新 Process 对象获取当前主窗口句柄。</sentencetext> 

    MainWindowHandle 属性。</sentencetext>  MainWindowHandle   属性是一个唯一标识与进程关联的窗口的值。</sentencetext> 

    <sentencetext xmlns="http://www.w3.org/1999/xhtml">仅当进程有图形界面时,该进程才具有与其关联的主窗口。</sentencetext>  MainWindowHandle 值为零。</sentencetext>  <sentencetext xmlns="http://www.w3.org/1999/xhtml">对于已隐藏的进程,也就是任务栏里不可见的进程,该值也为零。</sentencetext>  <sentencetext xmlns="http://www.w3.org/1999/xhtml">这可以是任务栏最右端通知区域中显示为图标的进程的事例。</sentencetext> 

    WaitForInputIdle 方法让该进程完成启动,从而确保创建了主窗口句柄。</sentencetext>  <sentencetext xmlns="http://www.w3.org/1999/xhtml">否则,将引发异常。</sentencetext> 

    平台说明:.UseShellExecute set to true. " id="mt17" xml:space="preserve"><sentencetext xmlns="http://www.w3.org/1999/xhtml">如果在启动进程时 ProcessStartInfo.UseShellExecute 设置为 true,则此属性在此平台上不可用。</sentencetext>

    2014年3月5日 3:01

全部回复

  • Process.Start会返回一个Process对象,该Process对象的MainWindowHandle属性是显示的窗口的句柄,利用SetWindowPos函数可以根据窗口句柄设置窗口的大小,有关SetWindowPos函数可以参考以下链接:

    http://baike.baidu.com/link?url=WYf2VMjb-2Js5S_Osaf0mDNW5m-diuF3ED7bIqKwyFqDWoZxE9ET5b1Tv_xbrqbbmXFL3fnmOZSrq9CUNp9eEK

    2014年2月28日 9:05
  • IE不可,它會從上次關閉的IE的視窗大小,來打開下一個的大小。

    如果個別程式接受 SIZE的input parameter,那才可以呼叫時定下它打開的大小


    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for VB.NET since 2003
    My MSMVP Blog

    2014年2月28日 9:24
  • 噢!原來可以用Win32 API的,在這裡真的學習學習的好地方。

    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for VB.NET since 2003
    My MSMVP Blog

    2014年2月28日 9:29
  • 哦   原来是这样   我去试试  谢谢先。。。。。
    2014年3月3日 3:56
  • 我用Start返回的Process对象试了,但是设置不成功啊,开始以为是属性用错了,就把MainWindowHandle改成了Handle,但是还是不行,我又直接用this.Handle试了下,可以设置窗体的位置,但是大小还是没有改变。我打印出SetWindowPos的返回值,是true,为什么就是设置不成功呢?
    2014年3月3日 8:12
  • 你好:

    我使用MoveWindow这个函数是可以实现这个功能的。参考一下这个代码:

    [DllImport("user32.dll", SetLastError = true)]
            internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    
    
            static void Main(string[] args)
            {
                Process p = Process.Start("NotePad.exe");
                MoveWindow(p.MainWindowHandle, 200, 200, 50, 50, true);
                Console.Read();
            }


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年3月5日 2:01
    版主
  • 现在关键问题是,我的p.MainWindowHandle等于0
    2014年3月5日 2:57
  • 现在关键问题是,我的p.MainWindowHandle等于0

    http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx

    请具体的看一下解释。

    TopLevel 窗体)。</sentencetext>  Refresh 方法刷新 Process 对象获取当前主窗口句柄。</sentencetext> 

    MainWindowHandle 属性。</sentencetext>  MainWindowHandle   属性是一个唯一标识与进程关联的窗口的值。</sentencetext> 

    <sentencetext xmlns="http://www.w3.org/1999/xhtml">仅当进程有图形界面时,该进程才具有与其关联的主窗口。</sentencetext>  MainWindowHandle 值为零。</sentencetext>  <sentencetext xmlns="http://www.w3.org/1999/xhtml">对于已隐藏的进程,也就是任务栏里不可见的进程,该值也为零。</sentencetext>  <sentencetext xmlns="http://www.w3.org/1999/xhtml">这可以是任务栏最右端通知区域中显示为图标的进程的事例。</sentencetext> 

    WaitForInputIdle 方法让该进程完成启动,从而确保创建了主窗口句柄。</sentencetext>  <sentencetext xmlns="http://www.w3.org/1999/xhtml">否则,将引发异常。</sentencetext> 

    平台说明:.UseShellExecute set to true. " id="mt17" xml:space="preserve"><sentencetext xmlns="http://www.w3.org/1999/xhtml">如果在启动进程时 ProcessStartInfo.UseShellExecute 设置为 true,则此属性在此平台上不可用。</sentencetext>

    2014年3月5日 3:01
  • 恩,应该是我没有用WaitForInputIdle这个方法,现在能直接获取到主窗体的句柄了,但是不管用API SetWindowPos还是MoveWindow都是下面的这个结果,窗体上面的控件没有移动,而且原来的窗体还在,还在找原因
    2014年3月10日 9:18
  • 你需要知道你移动的这个窗体是不是你的主窗体,那些“控件”的父窗口是不是你移动的床体?

    2014年3月10日 9:29
  • 我刚才试了下,估计应该还是句柄的问题,我用以下代码打开并获取句柄,然后移动窗口位置。

                Process Now_Process = Process.Start("C:\\Users\\Zhou\\Desktop\\SSCOM32.exe");
                Now_Process.WaitForInputIdle();
                IntPtr ssHandle = Now_Process.MainWindowHandle;
                MessageBox.Show(ssHandle.ToString());
                bool result1 = SetWindowPos(ssHandle, HWND_TOP, 0, 0, 800, 300, 2);

    这样获取的窗口句柄虽然不为0了,但是SetWindowPos或者MoveWindow之后就是窗体移动了但是窗体控件没有移动。而且与我单独在timer里用下列方法获取的窗口句柄的值不一样。

                int x = Cursor.Position.X;
                int y = Cursor.Position.Y;
                Point p= new Point(x, y);
                IntPtr ssHandle = WindowFromPoint(p);

    我这样获取句柄之后,再利用这个句柄去移动就能得到一个正确的结果。

    怎么才能得到用Process.Start()方法打开的那个程序界面的正确句柄呢?

    2014年3月10日 9:33
  • 你用 Spy++ 看下,你移动出来的那个窗体,还有留在原位置的窗体两者有什么联系。

    2014年3月10日 9:47
  • 那个程序对有点exe程序就可以(比如windows的画板程序),以前没有用过Spy++,刚才看了下,但是不知道这两个窗体什么关系,但关掉原来那个窗体,移动后的那个窗体也被关闭了。Spy++显示如下图:
    2014年3月11日 1:52
  • 那个程序对有点exe程序就可以(比如windows的画板程序),以前没有用过Spy++,刚才看了下,但是不知道这两个窗体什么关系,但关掉原来那个窗体,移动后的那个窗体也被关闭了。Spy++显示如下图:

    注意看你的图,窗口 000A04A6 应该就是你那个背景镂空的窗体,而实际上你要移动的窗体是 000504B8,你可以把窗口 000504B8 展开看看。
    2014年3月11日 2:18