Winform在PictureBox中显示另一个应用程序

时间:2015-07-16 22:13:11

标签: c# .net winforms picturebox

首先,我想说明我的问题与Running another application inside a picturebox类似,但我的应用程序运行.exe就好了,而不是总是将它嵌套在图片框中。

在我的c#winforms应用程序中,我试图在PictureBox中运行calc.exe,但是大约75%的时间我的应用程序只运行calc.exe作为它自己的窗口。

我的代码如下。

enter code hereprivate void Preview_Button_Click(object sender, EventArgs e)
    {
        if (ActiveWindows_ListBox.SelectedItem == null)
        {
            MessageBox.Show("There is no Window selected to take a picture of.", "Insufficient Data");
            return;
        }
        Process p = Process.Start("calc.exe");
        Thread.Sleep(500);
        p.WaitForInputIdle();
        SetParent(p.MainWindowHandle, ViewingScreen_PictureBox.Handle);
    }

根据我对我要做的事情的理解,我启动了Windows原生的calc.exe应用程序,然后告诉我的应用程序等待计算器初始化它自己,然后告诉计算器图片框是父的计算器。

这留下了我的问题,是否有一些我遗漏的东西使得我的应用程序不会在100%的时间内将计算器设置在图片框内?

提前感谢您的帮助。

P.S。我试图调整Thread.Sleep来给我的应用程序提供比现在更多更少的时间而不改变行为。

2 个答案:

答案 0 :(得分:1)

您的代码中有几个警告:

  1. 您对WaitForInputIdle的调用应该检查返回值。仅当调用返回true时才会达到空闲状态(请参阅MSDN)。

  2. 即使已达到空闲状态,p.MainWindowHandle也可能返回零。忙等待循环可以等待句柄变为非零。不好,但足以说明原则。诊断计数器ctr显示循环访问的频率。

  3. 下面的代码应该可靠地将计算器绑定到图片框,另外将picBox的大小调整为计算器大小,这样无论picBox的初始大小如何,总是可以看到整个计算器。

    [DllImport("user32.dll")]
    private static extern IntPtr SetParent(IntPtr hWndChild, IntPthWndNewParent);
    [DllImport("user32.dll")]
    private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);
    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    private struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
    
  4. static int ctr = 0;

    private void button2_Click(object sender, EventArgs e)
    {
        Process p = Process.Start("calc.exe");
        IntPtr h = IntPtr.Zero;
    
        //Wait for calc.exe to establish
        while ((h = p.MainWindowHandle) == IntPtr.Zero)
            ctr++;
    
        //Get size of calculator
        RECT r;
        GetWindowRect(h, out r);
    
        //width and height of the calculator
        int calcWidth = r.Right - r.Left;
        int calcHeight = r.Bottom - r.Top;
    
        //bind calculator to pictureBox
        SetParent(h, pictureBox1.Handle);
    
        //move calcusator to upper left corner of picturebox
        MoveWindow(h, 0, 0, calcWidth, calcHeight, true);
    
        //resize pictureBox to Calculator size
        Size newPicBoxSize = new Size(calcWidth, calcHeight);
        pictureBox1.Size = newPicBoxSize;
    }
    

答案 1 :(得分:0)

    public Process p = new Process();

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

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

    private void Preview_Button_Click(object sender, EventArgs e)
    {
        p = Process.Start("calc.exe");
        Thread.Sleep(500);
        p.WaitForInputIdle();
        SetParent(p.MainWindowHandle, ViewingScreen_PictureBox.Handle);
        MoveWindow(p.MainWindowHandle, 0, 0, 230, 320, true);
    }