无法将winform控件大小传递给非托管代码

8
我使用非托管库从IP摄像机中获取视频流。 其中有一个函数:
[DllImport("client.dll", EntryPoint = "Network_ClientStartLive", SetLastError = true)]
protected static extern int Network_ClientStartLive(
        ref IntPtr pStream,
        IntPtr hDev,
        IntPtr pClientInfo,
        [MarshalAs(UnmanagedType.FunctionPtr)] ReadDatacbf lpfnCallbackFunc = null,
        UInt32 dwUserData = 0
    );

pClientInfo是指向以下结构类型的指针:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
protected struct LiveConnect
{
    public UInt32 dwChannel;
    public IntPtr hPlayWnd;
    public UInt32 dwConnectMode;
}

hPlayWnd 是视频流输出的窗口句柄。在调用 Network_ClientStartLive 函数时,库会通过该窗口的大小检测视频分辨率。我在一个使用了 C++ MFC 程序中进行了验证,输出窗口是 Picture control,通过调用方法 MoveWindow 来定义了输出视频的分辨率。

在 C# 版本的程序中,我使用了一个 PictureBox 控件来绘制视频流。视频可以正常显示,但是 PictureBox 的大小并不影响视频流的分辨率。我尝试了几种方法来改变 PictureBox 的大小:

  1. 设置 pictureBox.Size
  2. 使用 WinAPI 的 SetWindowPos
[DllImport("user32.dll")]
private static extern bool SetWindowPos(
    IntPtr hWnd, 
    IntPtr hWndInsertAfter,
    int x, 
    int y, 
    int width, 
    int height, 
    uint uFlags);

在这两种方法中,控件的大小都被改变了,但是摄像头库仍然以最大分辨率输出视频流。

我该如何解决这个问题呢?

谢谢!


我想不出任何故障模式,就非托管代码关心或看到的内容而言,.NET PictureBox 和非托管图片控件之间本质上没有什么区别。考虑您可能正在传递错误的窗口句柄,例如窗体或桌面(null)的句柄。请联系摄像头库供应商或作者获取支持,他们可以轻松调试此问题。 - Hans Passant
6
我怀疑句柄有误。将你传递给日志的句柄写下来,然后在应用程序运行时使用Spy++工具选择PictureBox。如果Spy++显示的句柄与你记录的不符,则说明出了问题。 - dazedandconfused
1个回答

1
每个Windows Forms控件都有一个SizeChanged事件(http://msdn.microsoft.com/en-us/library/system.windows.forms.control.sizechanged(v=vs.110).aspx)。也许可以在此事件处理程序中添加代码以手动更改视频分辨率?如果不行,您提供的PictureBox句柄可能没有发送WM_SIZE消息,这是未托管库正在寻找的内容。如评论中所述,Spy++(包含在Visual Studio中)将是一个有用的程序,可监视消息并确保句柄值和事件符合预期。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接