Word中的WPF窗口只运行一次

时间:2017-08-29 13:44:50

标签: c# .net wpf ms-word

我有一个Word加载项,它有一个从功能区按钮启动的WPF窗口。 WPF窗口用于从网络摄像头捕获图片。它有两个窗口:Live和Snap。它还有三个按钮:Start(在Live中显示实时视频),Capture(将Live的当前帧复制到Snap中)和Close(关闭表单)。它还有一个用于选择正确相机的下拉列表。

我在这里有一个工作代码作为Windows窗体:

private void StartButton_Click(object sender, EventArgs e)
    {
        FinalFrame = new VideoCaptureDevice(CaptureDevice[cboDevices.SelectedIndex].MonikerString);
        FinalFrame.NewFrame += FinalFrame_NewFrame;
        FinalFrame.Start();
    }

        private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        pboLive.Image = (Bitmap)eventArgs.Frame.Clone();
    }

但是使用WPF我遇到了线程问题。现在在这里的人的帮助下:WPF Calling thread cannot access with eventargs 我得到它与WPF一起使用,但它只运行一次 - 如果我在关闭表单后尝试按下启动,则Live保持为空。

private FilterInfoCollection CaptureDevice;
private VideoCaptureDevice FinalFrame;
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
    capturedpictures.Clear();

    CaptureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);

    cboDevices.Items.Clear();
    foreach (FilterInfo Device in CaptureDevice)
    {
        cboDevices.Items.Add(Device.Name);
    }
    cboDevices.SelectedIndex = cboDevices.Items.Count - 1;
    FinalFrame = new VideoCaptureDevice();
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
    int capturedeviceindex = cboDevices.SelectedIndex;
    FilterInfo cd = CaptureDevice[cboDevices.SelectedIndex];
    string cdms = cd.MonikerString;
    FinalFrame = new VideoCaptureDevice(cdms);
    FinalFrame.NewFrame += FinalFrame_NewFrame;
    FinalFrame.Start();
}

这会处理新的框架:

private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    this.Dispatcher.Invoke(
            new Action<Bitmap>(
                (bitmap) =>
                {
                    pboLive.Source = ImageSourceForBitmap(bitmap);
                    return;
                }
            ),
            (Bitmap)eventArgs.Frame.Clone()
            );
}

public ImageSource ImageSourceForBitmap(Bitmap bmp)
{
    var handle = bmp.GetHbitmap();
    try
    {
        return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
    }
    finally { DeleteObject(handle); }
}

这样就关闭了表格:

private void CaptureWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
}

调试重新启动时,代码卡在FinalFrame_NewFrame中,并且在pboLive上没有显示任何内容。

2 个答案:

答案 0 :(得分:0)

这可能无法解答您的问题,但使用Excel时会出现一些警告(对于Word或其他任何使用COM的内容也是如此)

您在Word中使用的任何COM对象都需要小心处理。 COM确实引用计数,因此每次使用一个对象时,背景中的计数器基本上都是+1。 (是的,我知道它不仅仅是这个,但它是一个很好的设想方式)当你完成一个对象时,你需要告诉它-1,否则该对象永远不会被清除。要做到这一点:

Marshal.ReleaseComObject(o);

您必须确保为您使用的每个COM对象调用它,否则它将不会被释放并留在内存中。如果处理不当,可能会导致许多问题。

我会确保您使用上述内容减少参考,并查看问题是否仍然存在。我已经看到很多这样的问题,其中问题是以前的实例仍在内存中导致新实例正常工作的问题。

答案 1 :(得分:-1)

您是否可以像以前一样创建Bitmap,然后调用ImageSourceForBitmap方法?:

private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    this.Dispatcher.BeginInvoke(new Action(() =>
    {
        Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone()
        pboLive.Source = ImageSourceForBitmap(bitmap);
    }));
}