hr = ppostview->setviewsetting((dword) lcookie, sizeof(hwnd), (byte*)&hwnd);hr = pencoder->start();// start viewing the stream in a pop-up window.hr = ppostview->start(lcookie); //开始编码后,显示窗口。
上文只是说明了显示窗口的设置,没有文件输入和格式选择等操作,因此每次都要改源码来控制打开文件、存储路径、编码格式,改进了的程序运行界面如下:
其中的两个文件路径分别用cstring m_path, m_path1
浏览按钮的实现分别如下:
cfiledialog file(true);//true为打开一个文件,false为保存一个文件
file.domodal(); //响应点击事件
m_path=file.getpathname(); //得到文件的完整路径
this->updatedata(false); //更新数据
getdlgitem(idc_screen) //使屏幕捕获和视频设备的按钮无效,因为已经选择了文件编码。这样会使程序更健壮一些,否则无意中点了这两个按钮会出现意外的错误。
->enablewindow(false);
getdlgitem(idc_device)
->enablewindow(false);
cfiledialog file1(false,".wmv",null,ofn_hidereadonly, //保存一个文件,而且以.wmv为扩展名
"wmv files (*.wmv)|*.wmv|");
file1.domodal();
if(m_path1=file1.getpathname())
getdlgitem(idc_combo)
->enablewindow(true);
this->updatedata(false);
其中得到编码格式是通过在窗口初始化的时候加入的,通过cpreviewsdlg::choice();调用自定义的函数,choice()函数的具体实现如下:
void cpreviewsdlg::choice()
{
hresult hr;
iwmencoder* pencoder;
iwmencprofilecollection* pprocoll;
iwmencprofile* ppro;
long lcount;
int i;
// initialize the com library and retrieve a pointer
// to an iwmencoder interface.
hr = coinitialize(null);
hr = cocreateinstance(clsid_wmencoder,
null,
clsctx_inproc_server,
iid_iwmencoder,
(void**) &pencoder);
// retrieve a pointer to an iwmencprofilecollection interface.
hr = pencoder->get_profilecollection(&pprocoll);
// loop through the profile collection and retrieve a specific
// profile.
cstring str;
ccombstr bstrname(l"");
hr = pprocoll->get_count(&lcount);
for (i=0; i<lcount; i++)
{
hr = pprocoll->item(i, &ppro);
hr = ppro->get_name(&bstrname);
str=bstrname.copy();
m_choice.insertstring(i,str);
}
pencoder->release();
}
并使用ccombobox类的onselchangecombo()来得到选择编码的格式
void cpreviewsdlg::onselchangecombo()
{
j=m_choice.getcursel(); //把当前的选择赋值给j
if(j!=100) //j的初值为100,如果不等于100说明已经选择了格式
getdlgitem(idc_start) //使开始编码按钮有效
->enablewindow(true);
}
关于屏幕和设备的区别是通过全局变量h来标志的,h=1是屏幕捕获, h=2是从设备得到视频。程序如下:
void cpreviewsdlg::onscreen()
{
h=1;
getdlgitem(idc_device)
->enablewindow(false);
getdlgitem(idc_brower)
->enablewindow(false);
}
void cpreviewsdlg::ondevice()
{
h=2;
getdlgitem(idc_screen)
->enablewindow(false);
getdlgitem(idc_brower)
->enablewindow(false);
}
当配置好后,就可以开始编码了,程序如下:
void cpreviewsdlg::onstart()
{
hwnd=::getdlgitem(this->getsafehwnd(),idc_view); //得到预览编码前窗口的句柄
phwnd=::getdlgitem(this->getsafehwnd(),idc_postview); //得到预览编码后窗口的句柄
// g_mythread->setparentwnd(hwnd); //可以去掉
g_mythread->postthreadmessage(wm_start,0,0 ); //给线程发送消息,开始编码
getdlgitem(idc_watch)
->enablewindow(true);
getdlgitem(idc_stop)
->enablewindow(true);
getdlgitem(idc_start)
->enablewindow(false);
}
线程中的开始函数如下:
void cmythread::onstart( wparam wparam, lparam lparam)
{
iwmencsourcegroupcollection* psrcgrpcoll;
iwmencsourcegroup* psrcgrp;
iwmencsource* paudsrc1;
iwmencsource* psrc1;
iwmencvideosource* pvidsrc1;
// iwmencdataview* ppreview;
iwmencdataviewcollection* ppostviewcoll;
iwmencdataviewcollection* ppreviewcoll;
iwmencprofilecollection* pprocoll;
iwmencsourceplugininfomanager* psrcplugmgr;
iwmencplugininfo* ppluginfo;
iwmencprofile* ppro;
iwmencdisplayinfo* pdispinfo;
iwmencattributes* pattr;
iwmencbroadcast* pbrdcast;
iwmencfile* pfile;
wmenc_encoder_state enumencoderstate;
ccombstr bstrresource(l"");
long lcount;
short i;
hr = coinitialize(null);
hr = cocreateinstance(clsid_wmencoder, //初始化com库
null,
clsctx_inproc_server,
iid_iwmencoder,
(void**) &pencoder);
// retrieve a pointer to an iwmencsourcegroupcollection
// interface.
hr = pencoder->get_sourcegroupcollection(&psrcgrpcoll);
// add a source group to the collection. named "sg_1"
hr = psrcgrpcoll->add(l"sg_1", &psrcgrp);
&nbs