幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如HYPERSNAP等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用.
4 U1 D! X4 S. O) b- u8 R5 Z& m% q 下面用VC来逐步介绍在Windows95下的实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.2 E/ e. v* `( ]3 _1 ?
HBITMAP CopyScreenToBitmap(LPRECT lpRect)/ s, S: {- D! e& t$ {) j& {
//lpRect 代表选定区域7 v4 n$ N1 m2 p+ j1 i
{4 B8 J: s2 j* Z2 d1 |+ P# ^
HDC hScrDC, hMemDC;6 d r* ^: m3 J5 D& \, y5 ]8 D/ T
// 屏幕和内存设备描述表
7 y! N: n" A" C HBITMAP hBitmap, hOldBitmap;
' s4 S1 P5 @6 N // 位图句柄( Z8 J5 v" `' l( Q
int nX, nY, nX2, nY2;
# ]& P8 x v. E8 k/ H% j3 l0 D // 选定区域坐标
' S% x5 `' ]3 ?2 I/ Q2 f int nWidth, nHeight;8 s$ h+ N) w* Q7 C$ y
// 位图宽度和高度
# |8 I) b4 z4 v; ~9 H7 j: L n5 U int xScrn, yScrn;) B+ P3 e- R* x/ `
// 屏幕分辨率 ^; M- B: C. O3 {
// 确保选定区域不为空矩形' C9 s. Z9 W% s1 l, u
if (IsRectEmpty(lpRect))& Z) N9 i+ a: |; }
return NULL;8 x# Y; o9 g+ R2 v2 G
//为屏幕创建设备描述表8 x: }; B5 g- ]3 f
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
9 i G- }5 {$ N0 r7 t //为屏幕设备描述表创建兼容的内存设备描述表6 h6 R2 V6 \. u8 @6 k8 U
hMemDC = CreateCompatibleDC(hScrDC);
; V% Z7 L( @1 d; { // 获得选定区域坐标
0 ?' v; V0 V' h nX = lpRect->left;
E3 n; G: l5 ^8 w; {8 M nY = lpRect->top;6 `; B* I( C- B
nX2 = lpRect->right;
: @- ?" }9 g4 c7 M nY2 = lpRect->bottom;
' t4 U6 A' C" n // 获得屏幕分辨率 u: x7 Y, z; J
xScrn = GetDeviceCaps(hScrDC, HORZRES);% [* l' t U& m3 _4 n3 @
yScrn = GetDeviceCaps(hScrDC, VERTRES);2 C1 g* N4 g2 ?
//确保选定区域是可见的
( e0 |& c6 L& @+ C; e if (nX < 0)- T$ O$ p" \" V
nX = 0;
- v* y& |& R; p0 d if (nY < 0)
2 K9 H! T9 F9 q nY = 0;3 q. x" D: n: m; P w' ~8 b: A, S
if (nX2 > xScrn)
, \5 e9 p+ @/ y9 b nX2 = xScrn;% j1 S& M; E3 u" s( @1 @- R
if (nY2 > yScrn)( l8 g f* ^# F' }* N* G& j( \7 \
nY2 = yScrn;
$ c3 ]% z# w# ^) e6 M) z2 ]4 E3 z nWidth = nX2 - nX;
1 o/ v2 E o) L nHeight = nY2 - nY;% I0 r- F5 M' e5 u; m* Y e- S/ u
// 创建一个与屏幕设备描述表兼容的位图3 ` ^% G+ ]9 y$ Z) r% p
hBitmap = CreateCompatibleBitmap
5 H2 @6 o: _0 R5 x! J (hScrDC, nWidth, nHeight);
# u1 e t( j% P/ c$ t' b/ @% D3 W; v& h // 把新位图选到内存设备描述表中
) z/ ~0 o) |5 @% v, @' ^5 [ C) O3 Z' u hOldBitmap = SelectObject(hMemDC, hBitmap);
& n( Z2 |/ c) q // 把屏幕设备描述表拷贝到内存设备描述表中
8 ]7 \+ d$ a2 q) k0 ? BitBlt(hMemDC, 0, 0, nWidth, nHeight,* C9 {. o) D! w% p8 O
hScrDC, nX, nY, SRCCOPY);1 k- L* S( x' k J' }
//得到屏幕位图的句柄
; U# |0 Z+ N8 e/ q5 h* ?1 X' ?9 U hBitmap = SelectObject(hMemDC, hOldBitmap);3 m1 |% R4 i7 U# e r' g7 w
//清除
( B. m" ], j0 r7 U) q6 u2 y DeleteDC(hScrDC);* b* ]* l/ Z2 F Q" M7 _' k7 x
DeleteDC(hMemDC);% S3 j: M& t8 n: J
// 返回位图句柄
3 B# D6 T! @& g, } return hBitmap;" g0 c0 G; Y. D% S
}
# |$ b1 p! K1 k+ L# v9 {) ^
$ u6 r- h* v+ p" @3 o 得到屏幕位图句柄以后,我们
5 A5 `6 A( M2 R% Y- b 可以把屏幕内容粘贴到剪贴板上.3 H c1 R3 Z! v& G
if (OpenClipboard(hWnd))# J/ K3 \% j$ I, T w( I9 p4 v
//hWnd为程序窗口句柄% n: ~7 |8 D2 F: I( ~
{
5 c( r0 T& X0 T2 ^2 G //清空剪贴板
1 y/ M% S- ?' H EmptyClipboard();
( A( _& e0 f& c! k: v) u //把屏幕内容粘贴到剪贴板上,
/ K: ]/ j" r e- W' ?4 L- e hBitmap 为刚才的屏幕位图句柄
' W1 w% d4 f4 O3 r$ g) y SetClipboardData(CF_BITMAP, hBitmap);9 I) z0 ~6 w- i( |
//关闭剪贴板3 I" L! s F a9 @+ d' j' T) H, L
CloseClipboard();* n) C+ U) \- S$ g4 u& B& g. A
}5 o/ a9 K& f' M \
我们也可以把屏幕内容以位图格式存到磁盘文件上.
$ Y6 \* s" m1 z# ~7 _9 ]+ J( e+ D int SaveBitmapToFile(HBITMAP hBitmap ,
1 r2 v$ Y1 }9 d LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄/ J4 y0 w R: v
{ //lpFileName 为位图文件名
7 j. V" z8 I8 n HDC hDC;
2 C, I; Q: B6 u& M% j //设备描述表
1 @6 a6 e9 E% \( E int iBits;
* |" q( f, R, r1 C //当前显示分辨率下每个像素所占字节数4 u3 x4 {8 }. M' e6 P3 q0 H
WORD wBitCount;
. n; r$ ^' }# l+ w$ `1 k* X //位图中每个像素所占字节数
2 w0 x* Y4 S/ L' P; ? @ //定义调色板大小, 位图中像素字节大小 ,: T& J5 b! z+ [, k% i" \# p
位图文件大小 , 写入文件字节数8 E' J# _: M* { F: H" F( e5 P
DWORD dwPaletteSize=0,
+ f3 M5 p( d- i# Z dwBmBitsSize,
6 W1 Y7 u" }/ @2 r% \ dwDIBSize, dwWritten;
8 z3 i: p& W2 ]6 S BITMAP Bitmap;' ^/ H& w0 S% a$ P) E3 X
//位图属性结构8 x: C2 N \/ d! q
BITMAPFILEHEADER bmfHdr;
* ~% X* ~9 Y0 A* m3 p, g //位图文件头结构
: j g' e' e- p BITMAPINFOHEADER bi;4 ?5 s% x, L. L* M \
//位图信息头结构- G9 W, l0 w7 D% R0 R% Z) b1 U
LPBITMAPINFOHEADER lpbi;! w8 d9 P/ _5 C0 U# A4 N
//指向位图信息头结构8 \; u" J/ `% W$ Q" N. r5 Q
HANDLE fh, hDib, hPal,hOldPal=NULL" z1 J$ v4 u p* h( F8 y8 V5 S1 w
c: n7 Z; p Z& t* ? u! p' p
//定义文件,分配内存句柄,调色板句柄! x8 {2 J7 I. J7 W- `
//计算位图文件每个像素所占字节数. A( M) J$ @, }' [6 P' H: ~1 o
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
0 t |2 H) f4 k& R2 b0 | iBits = GetDeviceCaps(hDC, BITSPIXEL) *$ ~' p2 }! ?* ]" }
GetDeviceCaps(hDC, PLANES);
# u* z/ M: {: ~& H( i( z* ~ DeleteDC(hDC);
, g9 D8 J A; p* C. { if (iBits |