# H2 S" J. n2 g+ q: L9 n% u7 Y; r: u
9 F7 Z7 J. s/ R! m3 V
我们还可以使用IDirect3DSurface9的 GetDC()方法取得DirectX surface的GDI兼容DC,然后复制它的内容到我们的兼容DC。如果你用的是DirectX9,试试吧。 3 o1 ^1 ]6 a" B- `( d" f% p 5 q: @" s. Q. Z8 {) T 2 t; K/ y/ H k1 N3 l r9 u m) q6 q* I6 q( a Z
最后,需要注意的一点,文档提到:FrontBuffer是一个比较慢的操作,设计就是如此,所以在效率很关键的程序中应避免使用。已经警告你了!本文附带的源代码用这种技术定时捕捉屏幕,并保存为动画。 % b2 i+ U: m' |: ?' h
# s# c# w" G2 L1 i 用Windows Media API抓屏 ; i) b5 c* }% F! F* ~; Y2 _+ z8 V9 m
Windows Media 9.0 支持用Windows Media Encoder 9 API来抓屏。它有一个编码器叫Windows Media Video 9 Screen codec,特别为抓屏优化过。Windows Media Encoder API提供了一个IWMEncoder2接口可以用来高效地捕捉屏幕图像。 9 a1 n# j6 V: M/ E3 g , y* W: t5 s4 m$ r6 j8 {$ N4 N; N: j
5 S9 h5 t, _; f7 T+ _3 X( D
用这种技术进行抓屏也很简单,首先我们用CoCreateInstance()创建一个IWMEncoder2对象: - h& s: J/ D C0 ]4 O7 I! |$ i ! p; v" y4 A7 C6 o6 D- |% i6 \5 ^: zIWMEncoder2* g_pEncoder=NULL; ' F4 U& Y% O5 P& K, ]) Y) w b1 P! a
$ C# N) p3 l1 h( c: h
CoCreateInstance(CLSID_WMEncoder,NULL,CLSCTX_INPROC_SERVER, 4 y* @! r$ `3 F, H$ `3 I ' P( Y- B S" G+ {( BIID_IWMEncoder2,(void**)&g_pEncoder); * w+ }/ |& u* ]& W - ~" m* g( T0 Q3 g7 @这个Encoder对象包含了捕捉屏幕的所需的全部操作,然而为了正确地工作,编码器对象的行为取决于被称作profile的设置。一个profile只是一个包含了所有控制编码操作设置的文件,我们可以根据被捕捉的数据的特性在运行时创建包含自定义设置的profile。为了在你的抓屏程序中使用profile,我们基于Windows Media Video 9 Screen codec来创建自定义的profile。自定义的profile对象从IWMEncProfile2开始就被支持了。我们可以用CoCreateInstance来创建自定义profile # c6 t1 o0 p$ A% R% V. c" E. j9 i9 T& X: f 9 ~9 _. K1 E1 O7 vIWMEncProfile2* g_pProfile=NULL; h$ G9 j0 N6 M4 ]7 m! L/ s/ I, K8 y9 |0 w. Z9 I
CoCreateInstance(CLSID_WMEncProfile2,NULL,CLSCTX_INPROC_SERVER, " z5 k5 n7 d5 s0 B
+ X5 W1 B# N. r1 W5 [
IID_IWMEncProfile2,(void**)&g_pProfile); ! i" ^. w* a# J ( ?+ f& S+ G& D0 y$ n4 q1 B我需要在profile里指定编码器的听众(audience)。每个profile可以包含多个听众配置,它们是IWMEncAudienceObj接口对象。这里我们为profile使用一个听众。我们可以通过IWMEncProfile::AddAudience()为我们的profile创建听众,这个函数返回一个IWMEncAudienceObj指针,可以用来配置视频编码器(IWMEncAudienceObj::put_VideoCodec()),视频帧对象(IWMEncAudienceObj::put_VideoHeight() 和IWMEncAudienceObj::put_VideoWidth())我们用下面的代码来配置视频编码器: 1 B% Y/ j# x e. i8 N9 l, F9 P; c, S, F- R% C4 }
extern IWMEncAudienceObj* pAudience; ! N! I" m/ D% w& \
; _, ?$ Y: }$ ?) ~1 K6 |, J% z1 D
#define VIDEOCODEC MAKEFOURCC('M','S','S','2') 4 w2 K+ l2 O) A; \9 p) [! m
- J+ B- ~* u; G" k' u$ \
//MSS2 is the fourcc for the screen codec , ]3 f2 Y f" ?; T2 G$ E& U3 |0 \/ |1 H' c1 X {
1 ~# d, `' S. T U
- x2 E) I& @' Y# dlong lCodecIndex=-1; 2 m; t2 N% j/ ~6 C # ?9 @4 u" _: Y A4 l. Wg_pProfile->GetCodecIndexFromFourCC(WMENC_VIDEO,VIDEOCODEC, 5 H( U8 I$ K- P( ?
, K& U5 p8 a1 X G
&lCodecIndex); //Get the Index of the Codec 8 X) q) N) D! g6 G7 `
/ B. Y3 j p m
pAudience->put_VideoCodec(0,lCodecIndex); " n5 Y1 p. r0 Y0 b, l' p+ x/ u
& ]5 g4 C/ M2 C" N; P2 t( K% \0 d& b0 k9 h8 X
6 q: \8 }( [2 X- m }. T6 e% Mfourcc是针对每个编码器的唯一的标识,Windows Media Video 9 Screen codec的fourcc为MSS2。IWMEncAudienceObj::put_VideoCodec()接受profile索引来组织一个profile,索引可以用IWMEncProfile::GetCodecIndexFromFourCC()取得。 $ C( ?. o8 r- G" s* E6 W5 Q( e$ ?! W: W& v$ |- O4 l