DirectX、Directshow介绍

1DirectX是什么

DirectX(简称:DX)是微软推出的一套基于Windows系统的多媒体应用程式接口APIs函式。在开发中,DX分为两个部分,一个是运行库,通过DX编译出来的程式必须要有运行库的支持,另外一个是开发库,也就是常说的SDK,这部分是在编译DX程序中是必需的。
DirectX是一种图形应用程序接口(API),简单的说它是一个辅助软件,一个提高系统性能的加速软件,微软创建开发的。他的意思不难理解,Direct是直接的意思,X是很多东西,加在一起就是一组具有共性的东西,这个共性就是直接。微软定义它为“硬件设备无关性”。
DirectX 是微软开发的图形及媒体加速接口,只有安装了它,系统中软件才能比较直接的利用硬件加速资源(高速访问硬件),目前该软件最高版本为9.0c
在Windows操作系统的体系构架中,在内核与硬件之间有一层抽象层,专门对硬件进行屏蔽抽象,所以用户不再被允许对硬件进行直接访问。这样做以后,大大地提高了操作系统的抗破坏性和抗干扰性,但这样以来,使硬件操作的效率大打折扣,许多新硬件的新特性无法直接使用,这对多媒体和游戏的发展显然是一种障碍。DirectX是微软公司提供的一套优秀的应用程序编程接口(APIs),用于联系应用程序和硬件自身,它对发展Windows平台下的多媒体应用程序和电脑游戏起到了关键的作用。
DirectX组件包括:DirectDraw、DirectSound、DirectPlay、Direct3D、DirectInput、DirectSetup、AutoPlay等

  总之,DirectX的主要好处有两个:为软件开发者提供与硬件的无关性;为硬件开发提供策略。
为得到最新的版本,应该从最新的Microsoft Platform SDK中将DirectX安装到系统中。 可以在http://www.microsoft.com/msdn站点或者MSDN光盘中找到platform SDK。缺省情况下,Microsoft Platform SDK被安装到缺省驱动器根目录下的MSSDK目录中。DirectX 的头文件安装在MSSDKINCLUDE目录中,Lib文件安装在MSSDKLIB目录中。
Platform SDK包含了一些非常好的DirectX例子和文档。早期发布的DirectX 文档非常粗略而且有些是错误的,现在的版本已经极大地改正了这一问题。最好要熟悉这些文档。
所幸的是,不必一次就处理DirectX的全部功能。DirectX是一套可以分别使用的组件。实际上,在编程概念中,DirectX的不同部分互相没有联系。它们仅仅是具有相同的设计风格和目标:使Windows的游戏编程变得容易。
使用DirectX组件的程序有什么特殊的地方吗?根本没有。使用DirectX组件的程序是基于Win32的程序,它们使用普通Win32 API集,并且可以访问所有可以获得的操作系统工具。实际上,DirectX既可以用于GUI程序,也可以用于控制台程序。可以直接用Petzold-style SDK编程开发程序,也可以用基本类库,如MFC。总的说,唯一的要求是大多数DirectX组件在程序中需要HWND,所以至少要有一个窗口。
2DirectX 9.0 家族的所有成员
DirectX Graphics:集成了以前的DirectDraw 和Direct3D技术。DirectDraw主要负责2D加速,以实现对显卡内存和系统内存的直接操作;Direct3D主要提供三维绘图硬件接口,它是开发三维DirectX游戏的基础。
DirectInput:主要支持输入服务(包括鼠标、键盘、游戏杆等),同时支持输出设备。
DirectPlay:主要提供多人网络游戏的通信、组织功能。
DirectSetup:主要提供自动安装DirectX组件的API功能。
DirectMusic:主要支持MIDI音乐合成和播放功能。
DirectSound:主要提供音频捕捉、回放、音效处理、硬件加速、直接设备访问等功能。
DirectShow:为Windows平台上处理各种格式的媒体文件的回放、音视频采集等高性能要求的多媒体应用,提供了完整的解决方案。
DirectX Media Objects:DirectShow Filter 的简化模型,提供更方便的流数据处理方案。
3DirectX的作用
DirectX软件开发包是微软公司提供的一套Windows操作平台上的开发高性能图形、声音、输入、输出和网络游戏的编程接口。它提供了硬件设备无关性。
4DirectShow的由来及介绍
DirectShow是从DirectX6.0中的DirectX Media 发展而来的,它集成了DirectX家族中其他成员(DirectDraw、DirectSound等)的技术。DirectX Media Objects是从DirectX8.1的DirectShow中分离出来的,成为了另一种高效率的流数据处理解决方案。
  Microsoft DirectShow是一个基于Microsoft Windows平台的媒体流结构。它支持各种格式,包括高级流模式(ASF)、运动图像专家组(MPEG)、音频视频交错(AVI)、音频动态压缩第三层(MP3)和WAV声音文件。它支持Windows驱动模式(WDM)设备的捕捉,以及早期Widows设备的视频。DirectShow结合了其它的DirectX技术。当视频和音频的硬件加速可用时,它能够自动检测并进行使用,同时也支持没有硬件加速的系统。
  DirectShow媒体重放、格式转换和捕捉的任务变得简单。同时,它为需要自定义的解决方案的应用程序提供了对底层流控制结构的访问。您也可以创建自己的DirectShow组件,来支持新的格式或自定义效果。
  使用DirectShow的应用程序类型包括DVD播放器、视频编辑应用程序、AVI到ASF的转换器、MP3播放器和数字视频捕捉应用程序。
  DirectShow是基于组件对象模型(COM)的。要做一个DirectShow的应用程序,您必须了解COM客户端编程。对于大多数应用程序,您不需要实现您自己的COM对象。DirectShow提供了您所需要的组件。(如果您想写自己的组件扩展DirectShow,则必须以COM对象的方式来实现。)
5、程序开发包的选择
请问在Mirosoft DirectX主页上的下载连接有如下:
它们有什么区别:
l         DirectX 9.0 SDK Update – (April 2005)
l         DirectX 9.0 SDK Update – (April 2005) Symbol Files
l         DirectX 9.0c Redistributable for Software Developers – (April 2005)
l         DirectX 9.0c End-User Runtime
——————————————————————————–
l         DirectX 9.0 SDK Update – (April 2005) – 就是通常说的DXSDK
l         DirectX 9.0 SDK Update – (April 2005) Symbol Files - 调试时用的符号文件
l         DirectX 9.0c Redistributable for Software Developers – (April 2005) - 能够随你的程序一起发行的部分
l         DirectX 9.0c End-User Runtime - 普通用户安装的DX
6、如何把DirectX关联到VC中?
我们要进行DirectX程序的编译就必须要有DirectX SDK库文件,此文件可以到微软或者本站获取,然后通过VC设置将其关联。下面说明了在VC6和VS.Net下的安装方法。
VC6(英文版):选择菜单Tools->Options,打开Options对话框,选择Directions标签页,选择Include files项,在里面添加DirectX头文件的文件夹路径目录,同样,在Library files项中添加DirectX头文件的文件夹路径目录。
VS.Net(中文版):选择菜单”工具->选项”,打开选项对话框,打开Projects标签页,分别选择”包含文件”和”库文件”进行相应的路径添加即可。
注:VC在进行编译时,会根据排列顺序来进行库文件选取,假设有两个相同名字的库,VC会优先使用排列在前面的库文件。
DirectShow应用程序至少连接库文件Strmiids.lib和Quartz.lib。前者定义了SirectShow标准的CLSID和IID,后者定义了导出函数AMGetErrorText(如果应用程序中没有使用到这个函数,也可以不连接这个库)。
        DirectShow应用程序都应该包含Dshow.h文件,但常常用Streams.h文件来代替它。如果包含了Streams.h,则一般库文件还要连接strmbasd.lib、uuid.lib和winmm.lib。
7DirectShow开发环境的配置
(1)使用VC向导生成一个具体项目,如Win32 Dynamic-Link;
(2)包含头文件streams.h;
(3)在VC的菜单中选择Project|Settings|C/C++,在弹出的对话框中的Category中选择Code generation,然后在Calling convention中选择_stdcall;
(4)使用多线程语言运行时库,即在VC的菜单中选择Project|Settings|C/C++,在弹出的对话框中的Category中选择Code generation,然后在Use run-time library中,Debug版选择Debug Multithreaded,Release版选择Multithreaded。
(5)配置必要的链接库文件,即在VC的菜单中选择Project|Settings|Link,在弹出的对话框中的Category中选择General,然后在Object/library modules中输入如下代码:
     Debug版本    strmbasd.lib, msvcrtd.lib, winmm.lib
     Release版本 strmbase.lib, msvcrt.lib, winmm.lib
并且选中Ignore all default libraries。
DirectShow SDK建议,DirectShow应用程序应该至少连接库文件strmiids.lib和quartz.lib。前者定义了DirectShow标准的CLSID和IID,后者定义了导出函数AMGetErrorText(如果应用程序中没有使用到这个函数,也可以不连接这个库)。如果程序里包含了头文件streams.h,则一般库文件还要连接strmbasd.lib、uuid.lib、winmm.lib。
(6)将DirectX SDK的Include和Lib目录配置到VC的系统目录中去,并且放在标准的VC目录之前,以保证编译器能够拿到最新版本的源文件。选择Tools|Options|Directories,在弹出的对话框中的Show directories for中选择Include files,配置如下(假设DirectX SDK安装在D:DXSDK目录下,VC安装在C:Program Files下):
     D:DXSDKInclude
     D:DXSDKSAMPLESC++DIRECTSHOWBASECLASSES
     D:DXSDKSAMPLESC++COMMONINCLUDE
     C:Program FilesMicrosoft Visual StudioVC98INCLUDE
     C:Program FilesMicrosoft Visual StudioVC98MFCINCLUDE
     C:Program FilesMicrosoft Visual StudioVC98ATLINCLUDE
再在Show directories for中选择Library files,配置如下:
     D:DXSDKLib
     D:DXSDKSAMPLESC++DIRECTSHOWBASECLASSESDEBUG
     D:DXSDKSAMPLESC++DIRECTSHOWBASECLASSESRELEASE
     C:PROGRAM FILESMICROSOFT SDKLIB
     C:Program FilesMicrosoft Visual StudioVC98LIB
     C:Program FilesMicrosoft Visual StudioVC98MFCLIB
(7)因为DirectShow应用程序是一种COM客户程序,因此在调用任何COM函数之前调用CoInitialize()(或CoInitializeEx)函数进行COM库的初始化(一般是在应用程序启动的时候调用一次),在结束COM库使用时调用CoUninitialize()函数进行反初始化(一般是在应用程序退出前调用一次)。
8VC编译DX程序出现无法解析的外部符号是怎么回事?
这个错误经常出现在初学者要进行编译DirectX程序的时候,主要是因为没有将DX的库文件引用到工程中,这里需要注意,我们将DX SDK的路径设置到VC后,并不代表我们已设置好了DX SDK,在我们的DX工程中,我们还需要进行相应的设置操作,把我们所需要的库文件(DirectX SDK Library)加入到我们的工程中,要设置这个库文件有两个方法,一个是在你工程的编译选项中进行添加,另外一种可以通过代码的方法来添加(推荐)。
命令行:#pragma comment( lib,”xxx.lib” )
这个是VC的编译预处理指令,将其加在代码中即可。
例如:#pragma comment( lib,”ddraw.lib” )  这句的意思是将ddraw.lib库加入到工程中进行编译。
注:此命令行不需要加分号(“;”)。
9DirectShow SDK基类库
       在DirectShow SDK基类库中,除了Filter和Pin类外,还有很多工具类。有了这些类的支持,我们开发Filter组件或者DirectShow应用程序会更加轻松。这些类主要包括:CPullPin、COutputQueue、CSourceSeeking、CEnumPins、CEnumMedieTypes、CMemAllocator、CMediaSample、CBaseReferenceClock、CMediaType、CBaseProperyPage等。
10DirectShowCOM编程基础
        DirectX采用了COM标准,而DirectShow是一套完全基于COM的应用系统。
        DirectShow应用程序实际上是一种COM组件的客户程序,只是COM组件的“使用”问题。这些问题包括如何创建COM组件、如何得到组件对象上的解风口以及调用接口方法、如何管理组件对象(即需要熟悉COM的引用计数机制)等。
       而对于Filter开发人员来说,需要掌握的COM知识就要多一点。因为Filter本身是一种COM组件,开发Filter牵涉到了COM组件的“实现”问题。
       COM本身只是一种规范,而不是实现。但是当使用C++来实现时,COM组件就是一个C++类,而接口都是纯虚类。COM规范规定,任何组件或接口都必须从IUnknown接口中继承而来,每个组件都必须实现一个与支相对应的类工厂(Class Factory),类工厂也是一个COM组件,他实现了IClassFactory接口。在IClassFactory的接口函数CreateInstance中,才能使用new操作生成一个与之对应的COM组件类对象实例。
       COM组件有3种类型:进程内组件、本地进程组件和远程组件。Filter一般是一种进程内组件,以DLL的形式提供服务。
       每个COM组件都使用一个GUID来唯一标识。当创建一个COM组件时,总是首先通过这个GUID调用CoGetClassObject来获得创建这个组件对象的类工厂。然后调用类工厂的接口方法IClassFactory::CreateInstance,就能真正地创建GUID标示的组件对象了。
       一个典型的自注册COM组件DLL所必需的5个函数如下:
l         DllMain:DLL的入口函数(DirectShow实现的是DllEntryPoint);
l         DllGetClassObject:用于获得类工厂指针;
l         DllCanUnloadNow:系统空闲时会调用这个函数,以确定是否可以卸载DLL;
l         DllRegisterServer:将COM组件注册到注册表中;
l         DllUnregisterServer:删除注册表中COM组件的注册信息。

折腾了一晚上了东东。。。

编程有时候挺好玩的。。有时候还让人挺郁闷的。。。气死人了。。

晚上本来心情很好。。想继续做一个FTP搜索引擎。。结果被一个PO东东搞得不高兴了。。哀。。

记一下吧。。省得以后再犯

VC中的CListCtrl这个控件的问题。。

一开始是这么写

while(m_mysql_row=mysql_fetch_row(m_mysql_res))

{

   m_listctrl.InsertItem(j,”hello”);

   for(i=0;i<mysql_num_fields(m_mysql_res);i++)

   {

    m_listctrl.SetItemText(j,i,m_mysql_row[i]);

   }

   j++;

   

}

然后换成这样写就对了。为什么要先插入再能调用SetItemText修改。。一边修改一边插入就不行。。。郁闷死。。为什么。。至今不明白。。

rowcount=mysql_num_fields(m_mysql_res);

for(j=1;j<rowcount;j++)

   m_listctrl.InsertItem(j,”hello”);

j=0;

while(m_mysql_row=mysql_fetch_row(m_mysql_res))

{

  

   for(i=0;i<mysql_num_fields(m_mysql_res);i++)

   {

    m_listctrl.SetItemText(j,i,m_mysql_row[i]);

   }

   j++;

   

}

不理解。。不理解。。弄了一晚上。。什么都没干。。一个半小时就这么过去了。。呵。。记一下。。以后不能再犯了。。

这几天搞的东东。。。。[转载]

本文讨论在Evc下遍历ftp站点的文件并下载,google了很多天,找到相关资料,但在evc下应用的很少,此文总结方法并应用到evc,以共享。

      ftp站点的访问有很多方法,本文使用InternetOpen,InternetConnect两函数来连接,因在evc环境下并不支持CFtpFileFind类,可用FtpFindFirstFile,InternetFindNextFile来遍历文件夹,用FtpGetFile下载文件,此方法是win API函数,在多种windows开发平台上都可以使用。

      这几个函数的结合在google上可以轻易搜索到,在此介绍下此次开发过程中遇到的问题:

1 关于evc下遍历文件夹的方法

    vc下遍历ftp文件夹的方法很简单,又专门的类CFtpFileFind,通过此类可直接查找文件,但是evc下不支持这个类的使用。在windows遍历文件夹使用FindFirstFile和FindNextFile,此方法可访问本地和局域网的文件夹,如访问:”\\192.168.1.230\Share“,注意此时的文件夹中的斜杠的数量,必须是这种格式的,但此方法无法访问远程的ftp站点,最终找到FtpFindFirstFile,InternetFindNextFile结合的方法,可以使用;

2 使用FtpFindFirstFile,InternetFindNextFile查找的文件夹类型

     ftp站点下的每个文件夹下都有两个文件夹”.”和”..”存在,”.”代表本目录路径,”..”代表上一级路径,所以在搜索到文件夹时需做判断排除此文件夹。

3 使用FtpFindFirstFile后无法用InternetFindNextFile继续查找下一个文件或文件夹

     在使用函数InternetOpen(_T(“ftp”),INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0)时注意参数设置,起初我最后一个参数使用了INTERNET_FLAG_ASYNC,MSDN上的解释是Makes only asynchronous requests on handles descended from the handle returned from this function. Only the InternetOpen function uses this flag. 我尚未弄清该参数的具体意义,起初使用是参考其他网友的版本,大家可研究下。还有注意的是第一个参数不能为NULL,否则open出错。

4 使用FtpFindFirstFile查询后,发现文件夹遍历进入后,再搜索时发现FtpFindFirstFile的返回值为0

      在这里要注意的是,在进入下一级文件夹后,必须先调用InternetCloseHandle(hFind)!!!否则结果就像上面描述的那样了,返回0。

      这样使用后,会存在递归调用下载的问题,因为程序逻辑是,如果发现文件夹即递归进入,之前的hFind已经被关闭,这样递归返回后,其余文件无法下载了,所以此处采用的方法是,在递归发现文件夹后把文件夹名保存,下载此目录下的其他文件,全部完毕后,再调用文件夹名递归进入下一级文件夹,这样之前的hFind被关闭后也不存在返回的问题了。