i have download the project from microsoft using WMEncoder to capture a desktop activities as video. Its working fine. But the problem is it capture a full screen but i need to capture the specific window. The main problem is video frame width and height is desktop screen resolution size. The video is playing very in computer but it is not playing in DVD player. I am new to VC++ thats y i dono how to change the coding for my purpose. Please help me to solve this issue....
Thanks in Advance
Code is:
#define WM_NOTIFYICON_MESSAGE WM_USER+1000
#define CONTENT_TYPE_VIDEO_ONLY 16 //Profile Supports Only Video
#define CONTENT_TYPE_AUDIO_VIDEO 17 //Profile Supports both audio and Video
#define PROFILE_CONTENT_TYPE CONTENT_TYPE_VIDEO_ONLY //Change this to Audio_Video for Audio support
#define PROFILE_AUDIENCE_BITRATE 400000 //Target for 400 Kbps
#define VIDEOCODEC MAKEFOURCC('M','S','S','2')
#define VIDEOFRAMERATE 30 //15 FPS(Frames Per Second)
#define IMAGEQUALITY 100 // 0 ~ 100: The higher the number the better the quality
#define CAPTURE_FULLSCREEN false //By Default We capture Full Screen - If false set the coordinates
#define WMSRCNCAP_CAPTUREWINDOW CComBSTR("CaptureWindow") //Property of Source Video - Fullscreen Mode
#define WMSCRNCAP_WINDOWLEFT CComBSTR("Left")
#define WMSCRNCAP_WINDOWTOP CComBSTR("Top")
#define WMSCRNCAP_WINDOWRIGHT CComBSTR("Right")
#define WMSCRNCAP_WINDOWBOTTOM CComBSTR("Bottom")
#define WMSCRNCAP_FLASHRECT CComBSTR("FlashRect")
#define WMSCRNCAP_ENTIRESCREEN CComBSTR("Screen")
#define WMSCRNCAP_WINDOWTITLE CComBSTR("WindowTitle")
#define ErrorMessage(x) MessageBox(NULL,x,"Error",MB_OK|MB_ICONERROR)
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
HMENU ghMenu=NULL;
IWMEncoder2* g_pEncoder=NULL;
IWMEncProfile2* g_pProfile=NULL;
HRESULT SetupScreenCaptureProfile(); void Cleanup(); HRESULT InitEncoder(LPCTSTR);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
CoInitialize(NULL);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WMENCSCRNCAP, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WMENCSCRNCAP);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CoUninitialize();
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW ;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WMENCSCRNCAP);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(BLACK_BRUSH);
wcex.lpszMenuName = (LPCTSTR)IDC_WMENCSCRNCAP;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 480, 320, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static NOTIFYICONDATA nid;
static bool bMinimized=false;
static RECT clientRect = {0,0,0,0};
DWORD wmId,wmEvent;
switch (message)
{
case WM_SYSCOMMAND:
{
if(g_pEncoder)
{
if(wParam==SC_CLOSE)
{
SendMessage(hWnd,WM_SYSCOMMAND,SC_MINIMIZE,0); return 0;
}
if(wParam==SC_MINIMIZE)
{
bMinimized=true;
LONG_PTR ret=DefWindowProc(hWnd,message,wParam,lParam); SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(ID_FILE_HIDEWINDOW,0),0); return ret;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
case WM_COMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case ID_FILE_STARTCAPTURE:
case ID_CAPTURE_START:
{
if(g_pEncoder==NULL)
{
OPENFILENAME ofn;
char szFileName[512];
strcpy(szFileName,"Output.wmv");
ZeroMemory(&ofn,sizeof(ofn));
ofn.lStructSize=sizeof(OPENFILENAME);
ofn.Flags=OFN_HIDEREADONLY|OFN_PATHMUSTEXIST;
ofn.lpstrFilter="Video Files (*.wmv)\0*.wmv\0 ";
ofn.lpstrDefExt="wmv";
ofn.lpstrFile=szFileName;
ofn.nMaxFile=512;
if(!GetSaveFileName(&ofn)) break;
SendMessage(hWnd,WM_SYSCOMMAND,SC_MINIMIZE,0);
ShowWindow(hWnd,SW_HIDE);
if(FAILED(InitEncoder(szFileName)))
{
DestroyWindow(hWnd);
break;
}
}
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; nid.uCallbackMessage=WM_NOTIFYICON_MESSAGE;
nid.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON_PAUSE));
strcpy(nid.szTip,"Capturing the Screen - Click to Pause");
if(!Shell_NotifyIcon(NIM_MODIFY,&nid)) MessageBox(NULL,"Unable to Set Notification Icon","Error",MB_ICONINFORMATION|MB_OK);
SendMessage(hWnd,WM_SYSCOMMAND,SC_MINIMIZE,0);
if(FAILED(g_pEncoder->Start()))
ErrorMessage("Unable to Start Encoding Process");
break;
}
case ID_FILE_PAUSECAPTURE:
case ID_CAPTURE_PAUSE:
{
nid.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON_START));
strcpy(nid.szTip,"Screen Capture Paused - Click to Resume");
if(!Shell_NotifyIcon(NIM_MODIFY,&nid)) MessageBox(NULL,"Unable to Set Notification Icon","Error",MB_ICONINFORMATION|MB_OK);
if(FAILED(g_pEncoder->Pause()))
{
ErrorMessage("Unable to Pause the Encoder");
}
InvalidateRect(hWnd,NULL,false);
break;
}
case ID_FILE_SHOWWINDOW:
{
if(bMinimized) ShowWindow(hWnd,SW_RESTORE);
else ShowWindow(hWnd,SW_SHOW);
SetForegroundWindow(hWnd);
bMinimized=false;
break;
}
case ID_FILE_HIDEWINDOW:
{
ShowWindow(hWnd,SW_HIDE);
break;
}
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
}
case WM_CREATE:
{
ZeroMemory(&nid,sizeof(nid));
nid.cbSize=sizeof(nid);
nid.uID=1000;
nid.uFlags=NIF_ICON|NIF_TIP;
nid.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_WMENCSCRNCAP));
nid.hWnd=hWnd;
strcpy(nid.szTip,"Screen Capture Application");
if(!Shell_NotifyIcon(NIM_ADD,&nid)) MessageBox(NULL,"Unable to Set Notification Icon","Error",MB_ICONINFORMATION|MB_OK);
ghMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDC_WMENCSCRNCAP));
break;
}
case WM_CHAR:
{
if(wParam==VK_ESCAPE)
DestroyWindow(hWnd); break;
}
case WM_INITMENU:
{
HMENU hMenu = (HMENU)wParam;
WMENC_ENCODER_STATE encState=WMENC_ENCODER_STOPPED ;
if(g_pEncoder) g_pEncoder->get_RunState(&encState);
bool bCapturing = (encState!=WMENC_ENCODER_PAUSED && encState!=WMENC_ENCODER_STOPPED);
EnableMenuItem(hMenu,ID_FILE_SHOWWINDOW,IsWindowVisible(hWnd)?MF_GRAYED:MF_ENABLED|MF_BYCOMMAND);
if(g_pEncoder) EnableMenuItem(hMenu,ID_FILE_HIDEWINDOW,IsWindowVisible(hWnd)?MF_ENABLED:MF_GRAYED|MF_BYCOMMAND);
EnableMenuItem(hMenu,ID_FILE_STARTCAPTURE,bCapturing?MF_GRAYED|MF_BYCOMMAND:MF_ENABLED);
EnableMenuItem(hMenu,ID_FILE_PAUSECAPTURE,bCapturing?MF_ENABLED:MF_GRAYED|MF_BYCOMMAND);
EnableMenuItem(hMenu,ID_CAPTURE_START,bCapturing?MF_GRAYED|MF_BYCOMMAND:MF_ENABLED);
EnableMenuItem(hMenu,ID_CAPTURE_PAUSE,bCapturing?MF_ENABLED:MF_GRAYED|MF_BYCOMMAND);
break;
}
case WM_INITMENUPOPUP:
{
WMENC_ENCODER_STATE encState=WMENC_ENCODER_STOPPED ;
if(g_pEncoder) g_pEncoder->get_RunState(&encState);
bool bCapturing = (encState!=WMENC_ENCODER_PAUSED && encState!=WMENC_ENCODER_STOPPED);
EnableMenuItem(ghMenu,ID_FILE_SHOWWINDOW,IsWindowVisible(hWnd)?MF_GRAYED:MF_ENABLED|MF_BYCOMMAND);
EnableMenuItem(ghMenu,ID_FILE_HIDEWINDOW,IsWindowVisible(hWnd)?MF_ENABLED:MF_GRAYED|MF_BYCOMMAND);
EnableMenuItem(ghMenu,ID_FILE_STARTCAPTURE,bCapturing?MF_GRAYED|MF_BYCOMMAND:MF_ENABLED);
EnableMenuItem(ghMenu,ID_FILE_PAUSECAPTURE,bCapturing?MF_ENABLED:MF_GRAYED|MF_BYCOMMAND);
EnableMenuItem(ghMenu,ID_CAPTURE_START,bCapturing?MF_GRAYED|MF_BYCOMMAND:MF_ENABLED);
EnableMenuItem(ghMenu,ID_CAPTURE_PAUSE,bCapturing?MF_ENABLED:MF_GRAYED|MF_BYCOMMAND);
break;
}
case WM_PAINT:
{
WMENC_ENCODER_STATE encState=WMENC_ENCODER_STOPPED ;
if(g_pEncoder) g_pEncoder->get_RunState(&encState);
bool bCapturing = (encState!=WMENC_ENCODER_PAUSED && encState!=WMENC_ENCODER_STOPPED);
const char* strMsg[]={"Click Start From Capture Menu to Start/Resume the Screen Capture","Click Pause From Capture Menu to Pause the Screen Capture"};
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hWnd,&ps);
DrawText(hdc,strMsg[bCapturing],(int)strlen(strMsg[bCapturing]),&clientRect,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
EndPaint(hWnd,&ps);
break;
}
case WM_SIZE:
{
clientRect.right = LOWORD(lParam);
clientRect.bottom= HIWORD(lParam);
break;
}
case WM_NOTIFYICON_MESSAGE:
{
switch(lParam)
{
case WM_MOUSEMOVE:break;
case WM_LBUTTONDOWN:
{
WMENC_ENCODER_STATE encState=WMENC_ENCODER_STOPPED; g_pEncoder->get_RunState(&encState);
if(encState == WMENC_ENCODER_RUNNING)
SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(ID_FILE_PAUSECAPTURE,0),0);
if(encState == WMENC_ENCODER_PAUSED || encState == WMENC_ENCODER_STOPPED)
SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(ID_FILE_STARTCAPTURE,0),0);
break;
}
case WM_RBUTTONDOWN:
{
POINT pt;GetCursorPos(&pt);
SetForegroundWindow(hWnd);
TrackPopupMenu(GetSubMenu(ghMenu,0),TPM_LEFTALIGN|TPM_BOTTOMALIGN,pt.x,pt.y,0,hWnd,NULL);
break;
}
}
break;
}
case WM_DESTROY:
{
Shell_NotifyIcon(NIM_DELETE,&nid);
DestroyMenu(ghMenu);
Cleanup();
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
HRESULT SetupScreenCaptureProfile() {
IWMEncAudienceObj* pAudience=NULL;
if(FAILED(CoCreateInstance(CLSID_WMEncProfile2,NULL,CLSCTX_INPROC_SERVER,IID_IWMEncProfile2,(void**)&g_pProfile)))
{
ErrorMessage("Unable to Create Profile Manager");
return E_FAIL;
}
if(FAILED(g_pProfile->put_ValidateMode(true))) {
ErrorMessage("Unable to Set Validate Mode");
return E_FAIL;
}
if(FAILED(g_pProfile->put_ProfileName(CComBSTR("Custom Screen Capture Profile"))))
{
ErrorMessage("Unable to Set Profile Name");
return E_FAIL;
}
if(FAILED(g_pProfile->put_ProfileDescription(CComBSTR("A Custom Video Profile For Screen Capture"))))
{
ErrorMessage("Unable to Set Profile Description");
return E_FAIL;
}
if(FAILED(g_pProfile->put_ContentType(PROFILE_CONTENT_TYPE))) {
ErrorMessage("Unable to Set Content Type for Profile");
return E_FAIL;
}
if(FAILED(g_pProfile->put_VBRMode(WMENC_VIDEO,0,WMENC_PVM_NONE))) {
ErrorMessage("Unable to Set BitRate Mode");
return E_FAIL;
}
if(FAILED(g_pProfile->AddAudience(PROFILE_AUDIENCE_BITRATE,&pAudience)))
{
ErrorMessage("Unable to Set Target Audience");
return E_FAIL;
}
do
{
long lCodecIndex=-1;
if(FAILED(g_pProfile->GetCodecIndexFromFourCC(WMENC_VIDEO,VIDEOCODEC,&lCodecIndex)))
{
ErrorMessage("Unable to Get Codec Index");
break;
}
if(FAILED(pAudience->put_VideoCodec(0,lCodecIndex))) {
ErrorMessage("Unable to Set Codec");
break;
}
if(FAILED(pAudience->put_VideoHeight(0,0))) {
ErrorMessage("Unable to Set Video Height");
break;
}
if(FAILED(pAudience->put_VideoWidth(0,0))) {
ErrorMessage("Unable to Set Video Width");
break;
}
if(FAILED(pAudience->put_VideoBufferSize(0,5000))) {
ErrorMessage("Unable to Set Buffer Size");
break;
}
if(FAILED(pAudience->put_VideoFPS(0,VIDEOFRAMERATE * 1000))) {
ErrorMessage("Unable to Set Video Frame Rate");
break;
}
if(FAILED(pAudience->put_VideoImageSharpness(0,IMAGEQUALITY))) {
ErrorMessage("Unable to Set Video Image Sharpness");
break;
}
if(FAILED(g_pProfile->Validate())) {
ErrorMessage("Unable to Validate the Profile Settings");
break;
}
if(pAudience)
{
pAudience->Release();
pAudience=NULL;
}
return S_OK;
}while(false);
if(pAudience) {
pAudience->Release();
pAudience=NULL;
}
return E_FAIL;
}
HRESULT InitEncoder(LPCTSTR szOutputFileName)
{
HRESULT hr = E_FAIL;
CComVariant varValue;
IWMEncSourceGroupCollection* pSrcGrpCollection=NULL;
IWMEncSourceGroup* pSrcGrp=NULL;
IWMEncSource* pSrc=NULL;
IPropertyBag* pPropertyBag=NULL;
IWMEncVideoSource2* pSrcVid=NULL;
IWMEncFile* pOutFile=NULL;
IWMEncProfile* pProfile=NULL;
if(FAILED(CoCreateInstance(CLSID_WMEncoder,NULL,CLSCTX_INPROC_SERVER,IID_IWMEncoder2,(void**)&g_pEncoder)))
{
ErrorMessage("Unable to Create Encoder Object");
return E_FAIL;
}
if(FAILED(g_pEncoder->get_SourceGroupCollection(&pSrcGrpCollection))) {
ErrorMessage("Unable to Get Source Group Collection");
return E_FAIL;
}
do
{
if(FAILED(hr=pSrcGrpCollection->Add(CComBSTR("SourceGroup1"),&pSrcGrp))) {
ErrorMessage("Unable to Add A Source Group to the Collection");
break;
}
if(FAILED(hr=pSrcGrp->AddSource(WMENC_VIDEO,&pSrc))) {
ErrorMessage("Unable to Add A Source to the Source Group");
break;
}
if(FAILED(hr=pSrc->QueryInterface(IID_IWMEncVideoSource2,(void**)&pSrcVid)))
{
ErrorMessage("Unable to Query interface for Video Source");
break;
}
if(FAILED(hr=pSrcVid->SetInput(CComBSTR("ScreenCap://ScreenCapture1")))) {
ErrorMessage("Unable to Set Video Input Source");
break;
}
if(FAILED(hr=pSrcVid->QueryInterface(IID_IPropertyBag,(void**)&pPropertyBag)))
{
ErrorMessage("Unable to Query Interface for Propery bag");
break;
}
varValue = CAPTURE_FULLSCREEN;
if(FAILED(hr=pPropertyBag->Write(WMSCRNCAP_ENTIRESCREEN,&varValue))) {
ErrorMessage("Unable to Set Capture Screen Property");
break;
}
if(FAILED(hr=SetupScreenCaptureProfile())) {
break;
}
if(FAILED(hr=g_pProfile->QueryInterface(IID_IWMEncProfile,(void**)&pProfile)))
{
ErrorMessage("Unable to Query Interface For Profile");
break;
}
if(FAILED(hr=pSrcGrp->put_Profile(variant_t(pProfile)))) {
ErrorMessage("Unable to Set Profile For Source Group");
break;
}
if(FAILED(hr=g_pEncoder->get_File(&pOutFile)))
{
ErrorMessage("Unable to Get Encoder Output File Object");
break;
}
if(FAILED(hr=pOutFile->put_LocalFileName(CComBSTR(szOutputFileName)))) {
ErrorMessage("Unable to Set Output File Name");
break;
}
if(FAILED(hr=g_pEncoder->PrepareToEncode(VARIANT_TRUE))) {
ErrorMessage("Unable to Prepare for Encoding");
break;
}
}while(false);
if(pProfile)
{
pProfile->Release();
pProfile=NULL;
}
if(pOutFile)
{
pOutFile->Release();
pOutFile = NULL;
}
if(pPropertyBag)
{
pPropertyBag->Release();
pPropertyBag = NULL;
}
if(pSrcVid)
{
pSrcVid->Release();
pSrcVid = NULL;
}
if(pSrc)
{
pSrc->Release();
pSrc = NULL;
}
if(pSrcGrp)
{
pSrcGrp->Release();
pSrcGrp = NULL;
}
if(pSrcGrpCollection)
{
pSrcGrpCollection->Release();
pSrcGrpCollection = NULL;
}
return hr;
}
void Cleanup()
{
if(g_pProfile)
{
g_pProfile->Release();
g_pProfile =NULL;
}
if(g_pEncoder)
{
g_pEncoder->PrepareToEncode(VARIANT_FALSE); g_pEncoder->Stop();
g_pEncoder->Release();
g_pEncoder=NULL;
}
}