首先,我想说明我的问题与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来给我的应用程序提供比现在更多更少的时间而不改变行为。
答案 0 :(得分:1)
您的代码中有几个警告:
您对WaitForInputIdle的调用应该检查返回值。仅当调用返回true时才会达到空闲状态(请参阅MSDN)。
即使已达到空闲状态,p.MainWindowHandle也可能返回零。忙等待循环可以等待句柄变为非零。不好,但足以说明原则。诊断计数器ctr显示循环访问的频率。
下面的代码应该可靠地将计算器绑定到图片框,另外将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; }
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);
}