如何将DirectShow视频播放器嵌入已有的SDL_Window窗口
核心问题修复
你当前代码存在4个明确错误,按优先级依次修改即可:
- HWND获取逻辑完全错误
你写的HWND hwnd = GetWindow(info.info.win.window, GWL_WNDPROC);逻辑错误:GetWindow搭配GWL_WNDPROC参数返回的是目标窗口的窗口过程函数地址,并非窗口句柄,你把函数指针强制转换为HWND自然无法正常工作。
SDL已经把原生Windows窗口句柄存在SDL_SysWMinfo结构里,直接取值即可:
HWND hwnd = info.info.win.window;
- 多余的窗口类注册代码可直接删除
你不需要自己调用RegisterClass注册窗口类,SDL创建SDL_Window的时候已经完成了窗口类注册、窗口创建的全部流程,这部分代码完全冗余。 - 独立消息循环导致SDL窗口冻结
你在PlayVideo函数里跑了独立的GetMessage消息循环,直接阻塞了SDL本身的事件处理逻辑,所以会出现SDL窗口无响应的问题。DirectShow播放不需要独立跑消息循环,要么使用无窗口渲染模式,要么将视频帧抓取后更新到SDL纹理,不要在播放逻辑里单独跑消息循环。 - 不需要调用
ShowWindow
SDL创建窗口时已经处理过窗口显示逻辑,ShowWindow(hwnd, nCmdShow)这行可直接删除,重复调用反而可能导致窗口状态异常。
推荐实现思路
如果要避免窗口消息冲突,更稳定的方案是用DirectShow的Sample Grabber过滤器抓取每帧视频数据,直接更新到SDL_Texture上,再通过SDL_Renderer渲染,完全不需要绑定窗口句柄,兼容性更好,也不会和SDL的事件逻辑冲突。
你之前用原生创建HWND时视频在隐藏窗口播放、SDL窗口冻结,就是因为你新创建的窗口没有显示,同时独立消息循环阻塞了SDL的事件处理,修改后即可解决。
内容的提问来源于stack exchange,提问作者Strong FS - MUGEN Studio
相关产品推荐
相关产品推荐

