将按钮添加到Media Foundation Interfaces视频屏幕的正确方法是什么

时间:2018-05-03 19:43:43

标签: c++ winapi ms-media-foundation

我目前正尝试使用Media Foundation Interfaces从头开始构建一个播放器。

我使用从这里取得的例子: https://msdn.microsoft.com/en-us/library/windows/desktop/dd979592(v=vs.85).aspx

作为玩家的基础。

我想在视频屏幕窗口中添加按钮(后退/前进按钮,进度条等),但对我来说并不是很清楚。

我不能简单地添加一个按钮作为主窗口的子窗口,因为它被播放器隐藏,我试图将按钮添加为视频窗口的子窗口,但它不起作用...

向视频窗口添加按钮的正确方法是什么?

这是您注册到播放器窗口的代码的一部分(完整代码请输入我附上的链接)。

// create the instance of the player hwnd = handle of main window
HRESULT hr = CPlayer::CreateInstance(hwnd, hwnd, &g_pPlayer);

// inner call to cplayer
CPlayer *pPlayer = new (std::nothrow) CPlayer(hVideo, hEvent);

// Create a partial topology. (m_hwndVideo == hVideo == hwnd)
hr = CreatePlaybackTopology(m_pSource, pSourcePD, m_hwndVideo, &pTopology);

我尝试使用此功能来更改视频画面,所以我会有一些 把它放在底部放在我的按钮上,这是我的功能:

VOID update_lower_window(HWND hwnd)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);

    RECT rc;
    GetClientRect(hwnd, &rc);

    //rc = father size
    RECT repaint;
    memcpy(&repaint, &rc, sizeof(RECT));
    repaint.top = repaint.bottom - DOWN_SPACE; // DOWN_SPACE == 50

    // paint back bottom to white
    FillRect(hdc, &repaint, (HBRUSH)COLOR_WINDOW);

    EndPaint(hwnd, &ps);
}

我在以下情况下调用此函数:

  1. WM_PAINT发生了
  2. WM_SIZE发生了
  3. WM_CREATE发生了
  4. 有了这个说我仍然无法实现我的目标:

    1. 当电影开始播放时,它开始全屏播放并且不会留下我想要的空间(我似乎无法找到播放电影时发送的信息,换句话说,当电影在屏幕上画出时它#39 ; s没有发送我插入我的函数的消息之一)
    2. 当我缩小屏幕时,前一个屏幕的残留仍然保持不变,我无法看到背景。
    3. 使用“最小化”按钮时,会出现与2中相同的现象。
    4. 另一个有趣的细节我在2中提到的现象只发生在我从下向上拖动来改变窗口大小时,如果我通过从一个角落拖动来改变窗口大小(同时放大或缩小高度和宽度),那么窗口会自行修正我一直在底部白色部分(背景)看到。

1 个答案:

答案 0 :(得分:0)

您可以重新定位视频区域,以便win32 GUI(按钮和进度)位于下方。请参阅该示例中的WM_SIZE处理程序以了解如何执行此操作,它们计算矩形以占据窗口,您可以调整以适应您的控件。

如果您想要半透明的重叠控件,您可以编写EVR Presenter。 https://msdn.microsoft.com/en-us/library/windows/desktop/bb530107(v=vs.85).aspx https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/multimedia/mediafoundation/evrpresenter

但这相当困难。

P.S。如果您只想要一个简单的解决方案,请使用更高级别的内容。与Windows Media Player control一样,注意它们有一个C ++示例,或者.NET中包含GUI和MediaElement。

更新:我认为在MFGetService(MR_VIDEO_RENDER_SERVICE)行之后,在该示例中设置初始视频位置的正确位置可能是CPlayer :: OnTopologyStatus。

无论如何,另一种可能更简单的方法是创建一个专门用于视频的子窗口。定位它使它占据应用程序主窗口的大部分,并且只留下底部50px未占用。不要忘记至少处理WM_SIZE以重新定位,理想情况下还要处理WM_DISPLAYCHANGED,WM_ENDSESSION,WM_GETMINMAXINFO。设置MF播放,使视频占据整个子视频窗口。 这将确保视频不会干扰您在底部50px面板上绘制的Win32内容。

BT,这就是MPC-HC正在做的事情,请参阅图片。 enter image description here 正如您在Spy ++截图中看到的那样,它们具有专用的视频窗口,以及用于播放器的Win32控件的其他子窗口。