幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如HYPERSNAP等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用." C, h* |6 R( Y3 u$ T0 J
下面用VC来逐步介绍在Windows95下的实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.
) p Z* X: @& w) m/ l# O0 h2 K HBITMAP CopyScreenToBitmap(LPRECT lpRect)
5 I& `5 ]( @3 P5 N5 F | //lpRect 代表选定区域
$ Z2 B' ^3 U$ p/ X {9 c& `& K2 `% b2 \ d) v( R
HDC hScrDC, hMemDC;5 F3 t8 _, ?: S8 B: f" i6 u# a
// 屏幕和内存设备描述表
& k- K7 v0 @- G HBITMAP hBitmap, hOldBitmap;) J6 U6 V# y) Q+ y, A& \
// 位图句柄
% `' D6 E" j4 y int nX, nY, nX2, nY2;$ v# ?5 E- b6 ^2 K- j1 k
// 选定区域坐标
, Q+ W/ R' d. K% Z int nWidth, nHeight;
% r! w/ |) {, ?# E$ E6 G% i // 位图宽度和高度
2 X) X0 Y$ e; b2 @' O int xScrn, yScrn;+ {: R8 N4 [: C, g" H. S8 h
// 屏幕分辨率
5 L# o1 E/ Z. D* y // 确保选定区域不为空矩形
2 Y. f8 ^- D* G1 ^- ? if (IsRectEmpty(lpRect))
9 i& \( T5 P- ] return NULL;6 R7 h) ?; _8 O- K( c
//为屏幕创建设备描述表! ^7 y+ H) q" @! w) l2 r
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
~' V9 G1 l) j, J$ ^! ^3 k //为屏幕设备描述表创建兼容的内存设备描述表
: e& R7 W+ [) Z hMemDC = CreateCompatibleDC(hScrDC);9 o; y) Z8 h3 l' D
// 获得选定区域坐标+ T7 c2 K1 \! t+ E: K0 h* M% H/ V5 K
nX = lpRect->left;' f4 w6 H& `, N J" L
nY = lpRect->top;* l* A2 \- @2 E; U6 N/ O
nX2 = lpRect->right;
7 l8 ^: c5 ]4 B1 n nY2 = lpRect->bottom;2 U3 K3 l; n, ?
// 获得屏幕分辨率% c9 A1 r }2 r
xScrn = GetDeviceCaps(hScrDC, HORZRES);# D4 z, v' j- O5 V: R" _( ~, \
yScrn = GetDeviceCaps(hScrDC, VERTRES);6 p( r: V; K% ~' O5 x4 z
//确保选定区域是可见的8 Q, H, _6 @* U H
if (nX < 0)
3 o7 v; ~/ A' ~5 A nX = 0;
. x( r: v. d% f1 r- t; H8 b. b. B8 }6 i if (nY < 0)
( d! L; }; h" h5 A9 J$ Y8 z, s0 q nY = 0;
8 e7 K( b9 I2 D9 x7 J# j7 ^ if (nX2 > xScrn)
/ O+ L9 z# o; ?; o: |. ^# ] nX2 = xScrn;6 V1 ~6 w0 W; J
if (nY2 > yScrn)* q0 d: V _6 ]2 D! v
nY2 = yScrn;" H% Y% H( p" t" L$ N x* h
nWidth = nX2 - nX;
9 p# u- h/ \; [2 z1 k$ d1 b nHeight = nY2 - nY;
4 M) e6 o! B- @5 Q" j% i M; x$ @ // 创建一个与屏幕设备描述表兼容的位图
2 v; e1 ?7 N, A/ }+ ] hBitmap = CreateCompatibleBitmap
4 C% {/ V5 [; b3 u (hScrDC, nWidth, nHeight);
7 p* c/ @$ x4 K& L2 X. K! ]" i // 把新位图选到内存设备描述表中) c7 N1 x9 [1 r
hOldBitmap = SelectObject(hMemDC, hBitmap);
. E. T# p) G0 n# {5 ~ // 把屏幕设备描述表拷贝到内存设备描述表中
4 r) |/ P9 r. A- \5 V BitBlt(hMemDC, 0, 0, nWidth, nHeight,+ y8 w/ W! W/ q8 m- X) h5 K
hScrDC, nX, nY, SRCCOPY);+ W; U! @6 |. u) }0 R
//得到屏幕位图的句柄
m4 x2 n/ U9 P4 E5 x hBitmap = SelectObject(hMemDC, hOldBitmap);3 [" Y# A9 I& r/ ?, }+ I
//清除$ ?( S' ?0 b( E+ Z, Q- k
DeleteDC(hScrDC);+ _0 ]3 ~& q2 j
DeleteDC(hMemDC);
. x6 G- @/ _4 b0 R2 U // 返回位图句柄
2 S" u2 ^* @8 N, z3 k return hBitmap;: F$ v7 w/ L3 Q X9 ?
}
2 o2 ]8 X9 B. i
* a$ n& `7 l7 f- r# i, B 得到屏幕位图句柄以后,我们; ]( t( O; H7 \+ @& u# h
可以把屏幕内容粘贴到剪贴板上.
" Q: Q/ g* J, i2 u: g5 W if (OpenClipboard(hWnd))6 W* l! T% ]0 D" t, T
//hWnd为程序窗口句柄
8 W! D+ b1 L$ I) y5 W9 | {1 s/ ^! w" L) K8 B
//清空剪贴板
) `: d. ~: ^9 C" @7 T EmptyClipboard();9 p) o0 H+ |6 {% Q3 J/ ]
//把屏幕内容粘贴到剪贴板上,' T: n1 t# j& b# |" t# B1 `
hBitmap 为刚才的屏幕位图句柄7 T6 _" N& d% x* P! \2 Y4 ~6 n
SetClipboardData(CF_BITMAP, hBitmap);. E8 c3 C% B' w; @' J- N6 X
//关闭剪贴板, @$ O2 y( ]* k2 q/ s
CloseClipboard();
4 f5 p( g+ [! p% l/ K }0 T$ U+ ~0 {+ G |( B% G* e0 S* h
我们也可以把屏幕内容以位图格式存到磁盘文件上.
& H0 E' ^' X6 L2 n, [ int SaveBitmapToFile(HBITMAP hBitmap ,
O: j! M0 z( R5 e) d4 `" ]- ?9 I LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄
9 q$ H6 u8 ^% v b { //lpFileName 为位图文件名
" B9 I6 t V; i% @0 \1 i6 P HDC hDC;+ K1 y0 o6 a% \% L; x! r; t- s
//设备描述表* c5 a+ w4 m. P. Y. J
int iBits;6 t0 j# a6 R+ L2 w9 H
//当前显示分辨率下每个像素所占字节数. t& T( \* c3 z5 }0 |9 G5 t
WORD wBitCount;1 f# T6 b, v$ m9 Z; t
//位图中每个像素所占字节数# h/ ?/ [% z8 X/ Y9 k( a, X* J
//定义调色板大小, 位图中像素字节大小 ,( `+ D- Y5 |7 |2 r- J; h1 b, i
位图文件大小 , 写入文件字节数
8 t; _4 l) n$ y) B4 Y) p* I DWORD dwPaletteSize=0,% C% B% I" b, v$ |- w5 G
dwBmBitsSize,
* a- r: l3 V4 ? dwDIBSize, dwWritten;( r8 n X: `, y7 o" {& q s
BITMAP Bitmap;
# p, Z% p: ]# y0 ]# }, z //位图属性结构6 u, P& T$ s) q7 Y6 r
BITMAPFILEHEADER bmfHdr;
3 ~, ?8 Z( N. O _1 U) T% ? //位图文件头结构
2 R6 m- w8 P+ j; ] BITMAPINFOHEADER bi;
) [* S+ _* Q5 i, f$ A //位图信息头结构5 [4 [# j4 a6 G
LPBITMAPINFOHEADER lpbi;
* A. g5 e3 T. f$ b //指向位图信息头结构: b7 Z2 G5 K3 R, ~9 I& I
HANDLE fh, hDib, hPal,hOldPal=NULL* W$ s% q' Y. v$ L+ X: j( c* F
$ P8 R2 W- ?+ g+ H4 v- g% E7 v
//定义文件,分配内存句柄,调色板句柄
, n% J) n$ t+ ~5 h( ` //计算位图文件每个像素所占字节数5 p" `. W c# O7 s, U. _# f! D' I
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);+ v; z7 _+ p1 K$ ~% E$ c# e- `
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
: i# J" ~; |. _8 c0 P GetDeviceCaps(hDC, PLANES);
/ a3 k- U* U. d& F% R9 O DeleteDC(hDC);8 e; E4 c3 i2 O
if (iBits |