急求救一个win32下directshow刷新问题
急求救一个win32下directshow刷新问题
我用win32写了一个dll, 然后在用CreateWindow建立了一个主窗体和一个static控件, 把static控件传给了IID_IVideoWindow用来浏缆视频, 但视频浏缆一直刷不出来
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
m_hInst = (HINSTANCE)hModule;
m_bCallState = FALSE;
m_bSpeech = FALSE;
m_bVideoState = FALSE;
GetDirectory();
return TRUE;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
// 定义窗口类
WNDCLASS wndcls;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
HBITMAP hbmp = GetBitmap(PNG_BK);
wndcls.hbrBackground = CreatePatternBrush(hbmp);
// wndcls.hbrBackground = 0;
// wndcls.hCursor=LoadCursor(NULL,IDC_ARROW);
// wndcls.hIcon=LoadIcon(NULL,IDI_WINLOGO);
wndcls.hCursor = NULL;
wndcls.hIcon = NULL;
wndcls.hInstance = m_hInst;
wndcls.lpfnWndProc = WindowProc;
wndcls.lpszClassName = L"DLL";
wndcls.lpszMenuName = NULL;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
// 注册初始化的窗口类
return RegisterClass(&wndcls);
}
LRESULT WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hWnd);
return FALSE;
break;
case WM_DESTROY:
PostQuitMessage(0);
return FALSE;
case WM_PAINT:
{
if (hWnd == m_hWndDLG)
{
OnPaint(hWnd, m_hBitmapBK);
return TRUE;
}
}
break;
case WM_COMMAND:
{
switch (wmId)
{
case IDC_BUTTON_LINK:
{
OnButtonCall();
}
break;
case IDC_BUTTON_VIDEO:
{
OnButtonVedio();
}
break;
case IDC_BUTTON_BACK:
{
OnButtonBack();
}
break;
case IDC_BUTTON_SPEECH:
{
OnButtonSpeech();
}
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// return TRUE;
}
break;
case WM_NOTIFY:
{
if(NM_CLICK == ((LPNMHDR)lParam)->code)
{
OnClickTree(hWnd);
// return TRUE;
}
}
break;
case WM_ACTIVATE:
{
if (hWnd == m_hWndDLG)
{
// 隐藏命令栏
HWND hWnd = SHFindMenuBar(m_hWndDLG);
::CommandBar_Show(hWnd, FALSE);
//如果对话框不在最前面,那么SHFullScreen()函数会失败
SetForegroundWindow(m_hWndDLG);
// 隐藏任务栏,任务栏是屏幕最上边的一条
SHFullScreen(m_hWndDLG, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
return TRUE;
}
}
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
};
return DefWindowProc(hWnd, uMsg, wParam, lParam);
// return FALSE; // 返回FALSE给缺省对话框函数DefDlgProc(),表示没有处理本消息
}
// 建立主窗体
BOOL CreatVCIPWnd()
{
BOOL bRet = FALSE;
// 垂直显示
DEVMODE devmode = {0};
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDisplayOrientation = DMDO_0; //垂直模式
devmode.dmFields = DM_DISPLAYORIENTATION;
ChangeDisplaySettingsEx(NULL, &devmode, NULL, 0, NULL);
int nWidth = GetSystemMetrics(SM_CXSCREEN);
int nHeight = GetSystemMetrics(SM_CYSCREEN);
MyRegisterClass(m_hInst);
if (!m_hInst)
{
return FALSE;
}
// 获取背景图
m_hBitmapBK = GetBitmap(PNG_BK);
m_hWndDLG = CreateWindow(L"DLL", NULL, WS_BORDER,
0, 0, nWidth, nHeight, NULL, NULL, m_hInst, (DLGPROC)WindowProc);
if (!m_hWndDLG)
{
return FALSE;
}
MoveWindow(m_hWndDLG, 0, 0, nWidth, nHeight, TRUE);
ShowWindow(m_hWndDLG, SW_SHOW);
// 隐藏命令栏
HWND hWnd = SHFindMenuBar(m_hWndDLG);
::CommandBar_Show(hWnd, FALSE);
//如果对话框不在最前面,那么SHFullScreen()函数会失败
SetForegroundWindow(m_hWndDLG);
// 隐藏任务栏,任务栏是屏幕最上边的一条
SHFullScreen(m_hWndDLG, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
SetControl(nWidth, nHeight);
UpdateWindow(m_hWndDLG);
return TRUE ;
}
// 建立浏览窗体
void NewVideoScreen(RECT rect)
{
BOOL bRet = FALSE;
if ( NULL == m_hWVideoScreen)
{
int nWidth = rect.right - rect.left;
int nHeight = rect.bottom - rect.top;
m_hWVideoScreen = CreateWindow(TEXT("STATIC"), NULL ,WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_BITMAP | SS_NOTIFY,
rect.left, rect.top, nWidth, nHeight, m_hWndDLG, (HMENU)IDC_STATIC_VIDEO, m_hInst, 0);
if (NULL == m_hWVideoScreen)
{
return;
}
}
ShowWindow(m_hWVideoScreen, SW_SHOW);
}
BOOL CEricCamera::PreviewCamera(HWND hVideoWnd)
{
HRESULT hResult = S_FALSE;
// 摄像头设备名称
WCHAR wzDeviceName[MAX_PATH + 1];
// 定义摄像头设备名称
// VARIANT varCamName;
CComVariant varCamName;
//摄像头属性页
CPropertyBag PropBag;
// 视频窗口尺寸
RECT rectVideo;
//--定义录像用到的编码、写文件等FILTER
IBaseFilter *pVideoEncoder = NULL;
IBaseFilter *pASFMultiplexer = NULL;
//默认先释放DSHOW接口
FreeDShow();
// 创建ICaptureGraphBuilder2接口,用于管理媒体捕捉对象
CHK(CoCreateInstance(CLSID_CaptureGraphBuilder, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCaptureGraphBuilder));
// 创建IGraphBuilder接口
CHK(CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGraphBuilder));
// 设置FilgerGraph接口
CHK(m_pCaptureGraphBuilder->SetFiltergraph(m_pGraphBuilder));
// 得到IMediaControl接口,用于控制流播放
CHK(m_pGraphBuilder->QueryInterface(&m_pMediaControl));
// 得到IMediaSeeking接口,用于设置播放位置
CHK(m_pGraphBuilder->QueryInterface(&m_pMediaSeeking));
// 得到m_pMediaEvent接口,用于获取媒体事件
CHK(m_pGraphBuilder->QueryInterface(&m_pMediaEvent));
// 创建视频捕捉Filter
CHK(CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_pVideoCaptureFilter));
// 得到视频捕捉属性页接口
CHK(m_pVideoCaptureFilter->QueryInterface(&m_pPropertyBag));
// 选择视频捕捉设备
// 得到第1个视频捕捉设备名。
if (!GetFirstCameraDriver(wzDeviceName))
{
goto Cleanup;
}
varCamName = wzDeviceName;
if(( varCamName.vt == VT_BSTR ) == NULL ) {
return FALSE;
}
//设置视频捕捉为第1个捕捉设备
PropBag.Write( L"VCapName", &varCamName );
CHK(m_pPropertyBag->Load( &PropBag, NULL ));
// 将视频捕捉FILTER添加到FILTER图中。
CHK(m_pGraphBuilder->AddFilter( m_pVideoCaptureFilter, L"Video capture source" ));
// 设置视频预览窗口
// CHK(m_pGraphBuilder->QueryInterface(&m_pVideoWindow));
CHK(m_pGraphBuilder->QueryInterface(IID_IVideoWindow,(void**)&m_pVideoWindow));
// 设置视频播放的WINDOWS窗口
m_pVideoWindow->put_Owner((OAHWND)hVideoWnd);
m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
//设置视频尺寸
GetClientRect(hVideoWnd, &rectVideo);
int nWidth = rectVideo.right - rectVideo.left;
int nHeight = rectVideo.bottom - rectVideo.top;
m_pVideoWindow->SetWindowPosition(rectVideo.left, rectVideo.top, nWidth, nHeight);
m_pVideoWindow->put_Visible(OATRUE);
// 渲染捕捉PIN, 用于录像
CHK(m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pVideoCaptureFilter, pVideoEncoder, pASFMultiplexer ));
// 预览视频
CHK(m_pMediaControl->Run());
Cleanup:
// 释放接口
if (pVideoEncoder != NULL)
{
pVideoEncoder->Release();
pVideoEncoder = NULL;
}
if (pASFMultiplexer != NULL)
{
pASFMultiplexer->Release();
pASFMultiplexer = NULL;
}
// if (pFileSinkFilter != NULL)
// {
// pFileSinkFilter.Release();
// pFileSinkFilter = NULL;
// }
//
// if (pWrapperFilter != NULL)
// {
// pWrapperFilter.Release();
// pWrapperFilter = NULL;
// }
if( FAILED( hResult ))
{
return FALSE;
}
else
{
return TRUE;
}
}
最后用下面的代码启动浏览
if( NULL == m_hWVideoScreen)
{
RECT rect;
rect.left = VIDEO_SRCCEN_LEFT;
rect.top = VIDEO_SRCCEN_TOP;
rect.right = VIDEO_SRCCEN_LEFT + VIDEO_SRCCEN_WIDTH;
rect.bottom = VIDEO_SRCCEN_TOP + VIDEO_SRCCEN_HEIGHT;
NewVideoScreen(rect);
}
if (m_hWVideoScreen)
{
ShowWindow(m_hWVideoScreen, SW_SHOW);
if ( NULL == m_Camera)
{
m_Camera = new CEricCamera();
}
m_Camera->PreviewCamera(m_hWVideoScreen);
m_bVideoRun = TRUE;
}
但是图象一直刷不出来
我在mfc上直接加了一个static控件, 一样的调用PreviewCamera把它传给CEricCamera是可以显示出视频的, 急求教一下我要怎么样才能在win32上刷新显示出来