|
3 W* y6 R" J0 N* ^西安交通大学流体机械研究所
" k) t* E% d7 g张义云
' _4 H, X$ s: n
' s3 y# ?( `- o. }2 D1 Q2 K---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
8 Z; b. W) K0 E$ y( ^在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数 $ Q6 ~5 C$ T' b! ^
显示BMP位图,可以消除以上的缺点。 7 ^$ X5 M" }+ I2 y1 g
0 |7 M( k( }2 h2 Y8 u2 S---- 一、BMP文件结构 ; ]& @7 b3 `2 ~0 D& Z
4 @! m1 y& S2 Q2 Q3 k' y. l4 q# X---- 1. BMP文件组成
4 s7 C: c7 C* W
- X9 G/ E2 R) ~3 l---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
+ ^1 b, `7 O& P7 V$ G; p * B. h( H3 V# a8 s* W* y
---- 2. BMP文件头 ! F! H8 f$ n$ Y/ `! j* z
; J- J* x: w X7 A& e---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
! l$ H3 r; C( f% M。 4 k1 \# ~' W, E
2 ~5 a; c# [7 b6 W$ Y5 Z---- 其结构定义如下: # x8 h& y! b' X, R
( L% l7 b% V, t5 w. ]( s; z. R% u
typedef struct tagBITMAPFILEHEADER
+ G% I! P# H- c( l{ - y4 _3 R' f9 ^" w: ?2 p
WORDbfType; // 位图文件的类型,必须为BM ( Z% z+ h3 I( H* u6 m& a
DWORD bfSize; // 位图文件的大小,以字节为单位
2 A+ h- V4 d0 B$ K+ ]( [- l- c7 }; D3 r, CWORDbfReserved1; // 位图文件保留字,必须为0 h: q, t& N+ ]
WORDbfReserved2; // 位图文件保留字,必须为0
' u4 w" @: p3 c+ qDWORD bfOffBits; // 位图数据的起始位置,以相对于位图 3 j4 Q9 z; y _* x" b
// 文件头的偏移量表示,以字节为单位
: V6 J1 _5 E7 X9 \: G6 V( Q. I4 G} BITMAPFILEHEADER; ' O- [: _1 q" P3 ^4 I
5 j/ F2 I$ Q8 S# k# |' j 9 Q8 W+ S8 @5 K$ e. b6 U& v% o
---- 3. 位图信息头 2 X/ @; w/ _* k: p+ ]& p7 X. K
----
1 h ]8 l' ~ l, c. ?& d* d% O / N0 a) o# U4 ]5 }" E. x
BMP位图信息头数据用于说明位图的尺寸等信息。
" V! y3 O/ @, x( _typedef struct tagBITMAPINFOHEADER{
1 s' e9 |7 n! A: P DWORD biSize; // 本结构所占用字节数 1 S! \) p- g# X2 r. _, s* G
LONGbiWidth; // 位图的宽度,以像素为单位
! y9 U2 w U- v LONGbiHeight; // 位图的高度,以像素为单位 5 Y8 {4 W0 s# G
WORD biPlanes; // 目标设备的级别,必须为1 ! ]- z6 ]9 Y5 j, ~, y
WORD biBitCount// 每个像素所需的位数,必须是1(双色), % M2 f, {9 b. k P
// 4(16色),8(256色)或24(真彩色)之一 9 W: l' j! G. [- C
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
( g! ?( ~! U5 k4 l // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
! l K( ~: Q, q+ R4 U# L V DWORD biSizeImage; // 位图的大小,以字节为单位 1 o v0 |6 Z1 T5 i8 L
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 6 v* L& L) S @( c/ M, Y7 L2 k
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
/ C# ~: X& o/ I5 \0 I: g DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 6 |7 t) X) |: n
DWORD biClrImportant;// 位图显示过程中重要的颜色数
! T- }0 }0 L3 d* L2 V' ~} BITMAPINFOHEADER;
8 o9 O+ z c; |/ D& M& } 8 n( e( I' i: ^
( E# ~ ]( x% S+ z) \) p---- 4. 颜色表 3 g! S. `, G- \8 Q9 H! D1 ?
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个
. _# \8 n+ n3 }, w* w, vRGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
5 Z/ C9 | n ? " E+ B& ]' E2 ^+ M
typedef struct tagRGBQUAD {
: n+ e0 @; R6 b2 M7 L; yBYTErgbBlue;// 蓝色的亮度(值范围为0-255)
( @3 g1 O9 }. D; o9 l: ~* tBYTErgbGreen; // 绿色的亮度(值范围为0-255)
" F+ \+ y% ~5 D# S& t" QBYTErgbRed; // 红色的亮度(值范围为0-255)
* \# b3 k+ s' \8 O3 j- XBYTErgbReserved;// 保留,必须为0
0 g" I' f9 V2 j. w' I* G" k} RGBQUAD; ]3 E, S: K% Y
颜色表中RGBQUAD结构数据的个数有biBitCount来确定: : k7 O7 M! \" V
当biBitCount=1,4,8时,分别有2,16,256个表项;
3 l6 ^2 B+ r2 ~6 ]当biBitCount=24时,没有颜色表项。 - k% U' C* @- g
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 9 Q" U+ h1 ~+ L" `- S- z; x
typedef struct tagBITMAPINFO { + w9 ], |& J( s! I9 L) a' B
BITMAPINFOHEADER bmiHeader; // 位图信息头 % ~3 ]* o2 k% a2 L e2 M8 {# c' P
RGBQUAD bmiColors[1]; // 颜色表
9 w: h, I: P6 M$ P! d} BITMAPINFO;
- c1 T. a u; g' J- @; E- ^* N f * G- _& P" j& O$ Z1 I
% C" L ^$ }( F! f- Q2 k% F
5 i* @1 h4 y* \3 b0 M4 y2 C---- 5. 位图数据
; |3 P" H$ S9 k7 j2 h4 P4 O---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右
4 p; O1 O4 `, `,扫描行之间是从下到上。位图的一个像素值所占的字节数: 7 c0 a% A, a. E: E2 D% S
2 h5 y& `# B* ?6 i& w# k& |7 W v9 a当biBitCount=1时,8个像素占1个字节;
% ~4 S3 f$ i7 c m! O1 N5 Y当biBitCount=4时,2个像素占1个字节;
% s( e$ y# w% t. k" ]& R- F当biBitCount=8时,1个像素占1个字节;
) }8 N) [7 |% o* s( `当biBitCount=24时,1个像素占3个字节;
, B; j$ R4 V v* t' R5 ]Windows规定一个扫描行所占的字节数必须是 $ q9 H7 o2 \. R% Q& P9 H" h( u( Z
4的倍数(即以long为单位),不足的以0填充, [5 a2 V! V) I0 e$ n6 X) `
一个扫描行所占的字节数计算方法: 1 R* y0 |& N* [. l+ `: p5 u1 J6 `
DataSizePerLine= (biWidth* biBitCount+31)/8; . H8 O/ {; r T7 K2 r9 W
// 一个扫描行所占的字节数 ) r2 c7 i& u+ W/ ]4 b& x
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
/ s( Q8 J# h2 e& ]. w" B: B6 `位图数据的大小(不压缩情况下): ; `) a6 Q r& M# ?
DataSize= DataSizePerLine* biHeight; . e9 B% W# W/ D: T4 V7 z( R4 \
, }* v {, R8 |+ C 1 v. O4 e5 e' ]. N: Y( b
---- 二、BMP位图一般显示方法
5 ]3 N' Y7 y/ e- Y% I---- 1. 申请内存空间用于存放位图文件 % l& J3 D b4 t! K5 e
' X4 `8 L( N& S! o---- GlobalAlloc(GHND,FileLength);
7 q4 k2 h; b h2 z/ N
7 |7 [8 S0 ^# J2 I: X---- 2. 位图文件读入所申请内存空间中
6 V( }/ L! u1 v# P/ G
6 g9 O8 j; G' l9 a---- LoadFileToMemory( mpBitsSrc,mFileName); e# \: g/ a, S4 D3 v+ w
$ k2 W- n& A8 }6 @6 ]0 c! g
---- 3. 在OnPaint等函数中用创建显示用位图
+ P+ D: F; S1 z2 c: d* c - P L) W' H8 w, ~! y4 o
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容
6 n8 _0 j1 a z eDC,
4 n8 v7 n$ {# r1 S" v! z; G ) o. C4 t% `% c) [
---- 用SelectBitmap()选择显示位图。
7 h0 l5 e2 r* M' }1 G! |! P8 }
( ~8 a# h7 n' V# D& J `---- 4. 用BitBlt或StretchBlt等函数显示位图 9 d# ?' r/ z* {* Y$ t" `+ \3 F
* Y6 D9 K. W2 A8 d$ g0 y---- 5. 用DeleteObject()删除所创建的位图
! ]# o3 f+ u, t' A1 E5 H 6 y; T+ \6 f( G2 ?- {( S
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示
9 u' |& i; A, V& O时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上( - M' o9 @5 v+ _1 E7 r }
如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
: P6 D& w& b$ U( q
6 p0 d. g- T* W---- 三、BMP位图缩放显示 % H% I( S5 Z# ?7 U8 d3 O' T
( S$ ]! S1 a* f0 y, w---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
- z: L0 r1 M) W }/ Z( K0 Z进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 6 w8 a9 H" Q+ ?6 ~6 t
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: * j! q+ Y, q- W
$ Y( B% K% M- l7 ^( E3 _' }* v
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 * E% {' \' H6 z0 u2 P7 S
9 E/ ]5 b* [" s# M---- 2. 申请内存空间用于存放位图文件
3 l+ @6 p6 s2 q, z
7 f% U: w) U1 z% w---- GlobalAlloc(GHND,FileLength); " ]* }/ Q0 g6 `! {$ L
1 T# N6 `0 z ]# I3 ~5 N
---- 3. 位图文件读入所申请内存空间中 8 O' E1 D4 C; ~
- \0 [8 d# b" b; H---- LoadFileToMemory( mpBitsSrc,mFileName);
( {6 B, f* ~# ], g7 R6 p' `' O
: S1 Q# e. M) G; m" J- B---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图
, \0 n3 |" ^) y
6 f- r5 q7 V% U0 S( T) `4 r$ }# l---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
0 ?* l* O9 L' L- F ( F a! I$ {9 p
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形 # e" Z9 m* A/ ^1 J! w# D0 j. p
失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通 5 j; D: I R9 J/ z& f7 ]$ |- n
过直接处理位图数据,可以制作简单动画。 ! b$ ]; z2 G6 q6 P/ N! L1 w8 p6 Q: ^4 L
* X% I( H V8 d9 W: F3 i# a---- 四、CViewBimap类编程要点
$ C* l/ v# a& k. T6 |, d2 s; d0 @. ^ 1 P; T* u. x5 ]- q* d" S$ n9 g- l
---- 1. 在CViewBimap类中添加视频函数等成员
) z. ^. I" g3 s 0 ]# S# D/ S" C7 G5 _
HDRAWDIB m_hDrawDib; // 视频函数
4 W3 j f0 u3 ~1 |: W7 q% T0 ]HANDLEmhBitsSrc; // 位图文件句柄(内存) ) T5 B+ `5 g( s# G" `
LPSTR mpBitsSrc; // 位图文件地址(内存) . Q5 c e5 d* Q F+ v$ ]. j; ~
BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
0 v- u; }8 h* j/ d4 Y6 Y 5 \; S5 f) K! V) q
4 z v; S0 k; X$ f
---- 2. 在CViewBimap类构造函数中添加打开视频函数
; q& s* T* s2 ~- n' t- N---- m_hDrawDib= DrawDibOpen(); : w8 _& q8 I9 v
Z% A9 f: n3 j) o---- 3. 在CViewBimap类析构函数中添加关闭视频函数 6 k. s* H! K, H [* n9 ?
# J' a$ T# ]4 |; r, Y9 i4 Dif( m_hDrawDib != NULL) x5 n9 v- b- M; [
{
/ A7 ^- i, [' a* k! Q% K DrawDibClose( m_hDrawDib);
- e. c, K/ z% [5 B$ [, g' n3 _ m_hDrawDib = NULL;
, v8 w( d2 L: [1 V5 }! s }
- E O. E2 A5 m% Q) Z
: n% @9 Q g2 @5 F $ x9 }8 g$ C! a; L! O, E
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() ( w8 e' F' m% R" C/ e3 o
voidCViewBitmap::OnPaint()
# S( M3 |: s$ D. e1 O9 K. k{
2 ?8 T- f, I" O0 }CPaintDC dc(this); // device context for painting
# E2 m5 C4 y7 A2 z" tGraphicDraw( ); . U0 q3 V) y; a8 k! V# X3 ~) w
} ! _0 f/ T Y/ |& T/ Z& j
% G8 m8 v6 E+ g1 ^( t" c$ k
voidCViewBitmap::GraphicDraw( void ) ( K$ Q2 b' `4 r9 Y% r
{ ! M4 n9 x. Q; U0 a5 M
CClientDC dc(this); // device context for painting 9 ]" _* H, M) }. l/ X& M4 e" ~
BITMAPFILEHEADER *pBitmapFileHeader; 8 [' {) h6 g. e2 n- q/ A
ULONG bfoffBits= 0; # e/ O: c2 H- C5 s3 N
CPoint Wid; $ |0 u5 U7 g9 u
' P( p1 I/ H' ~' D; ~+ W
// 图形文件名有效 (=0 BMP)
" B4 h! t/ ~) D/ cif( mBitmapFileType < ID_BITMAP_BMP ) return;
8 M* u3 A% _! u* i0 z6 x
: \: f- c% @) D0 G* b: l// 图形文件名有效 (=0 BMP)
5 c. L# y/ ^; P8 o8 L8 L# p! T, f// 准备显示真彩位图
5 h+ ~, x8 r4 w- L0 ]6 }' O q) KpBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; ( \' S) ]. _% t
bfoffBits= pBitmapFileHeader->bfOffBits; $ ~& y, g# W- [8 `( k1 a- \# i
$ r8 k8 D# k4 J: U( K1 Q2 [7 f
// 使用普通函数显示位图 6 @3 f# M$ W0 a; ~" f) }# ]
4 p1 ^3 w% P! K2 H' L) v5 V) |# q; j
if( m_hDrawDib == NULL || mDispMethod == 0)
& ]- w& \, A/ B { ) S @ l6 e2 p) k9 @1 U: r
HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, ) M+ i9 |$ R/ H
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
% g, S" T2 g! L (LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); ) |; A1 G$ y( ^8 ]6 t
// 建立位图 # L' g. Z6 y$ n+ M5 w5 ~
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存 ' L, S- c0 W9 c+ g& E8 Q+ F" }3 F
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象 6 j$ F& Z3 H' S' a; g
// 成员CRect mDispR用于指示图形显示区域的大小.
( {# j3 V( x: j9 x4 l0 W, N// 成员CPoint mPos用于指示图形显示起始位置坐标.
6 I. i% w2 i/ r4 A$ [1 ]if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
( E, X+ Q% D" C3 R8 j$ t$ OmPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
3 ?; P9 T0 j7 b' I if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) ) q5 W/ p! h& P5 S! c* c. }
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
- v4 T: ^+ t6 y if( mPos.x < 0 ) mPos.x= 0; 3 V4 E$ f8 s9 l% a% w: h
if( mPos.y < 0 ) mPos.y= 0; 5 S2 \- c; e. i# ^2 I
8 P/ P4 K1 \5 ~4 F9 m
if( mFullViewTog == 0)
p" e% b! e, X4 b: {{
! Z* Y# t4 o, F0 z1 a// 显示真彩位图
. A0 ^* ^4 q3 }' G! h9 H: \0 x; `::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
' W4 Q; J+ h# v+ vhMemDC,mPos.x,mPos.y, SRCCOPY);
3 ~# m- e. g5 W9 u} else { " n* t1 y7 h& n2 a
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
; G9 ]' m& J8 i* J! t/ phMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
- [! U- Q5 _) H1 I0 U. K+ d- j. u7 s>biHeight, SRCCOPY); 5 \/ x. w% O- J# g& M) u
} 9 q9 ~/ s( P$ ^/ L0 z- z; O+ @" Y+ c
// 结束显示真彩位图
7 k% z* j s7 R* V: O : eleteObject(SelectObject(hMemDC,hBitmapOld)); 7 |% w# y7 I3 L* ~6 \
// 删 除 位 图
" w: t i+ e) s } else { # e$ b* ^/ r# ^( K: ` v+ |
. @- t, w# A E
// 使用视频函数显示位图
$ j) t Z" E# k6 r: E/ o& r% ^* {
- M* ~' Q4 n' M) M; x$ \& k if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) ) [0 B; W# P, `0 T
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
Q& e$ N, u! S) c) }! u6 G if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) k" f8 d4 w5 P" w6 j3 ^
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); $ l* R5 U! B; j0 E
if( mPos.x < 0 ) mPos.x= 0;
6 I$ |4 J; w# |8 t% r3 x, s- A if( mPos.y < 0 ) mPos.y= 0; / K; s$ |* d# |! B' y/ I& j7 B
5 q k2 x# u. g$ P; i3 G# {& x
// 显示真彩位图 3 ?: _( A% b' `, {- s. q2 _
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);
9 d; d* Y0 h+ j1 \* f . `6 j' F2 @1 P' m( e% r
if( mFullViewTog == 0)
' t" ?6 v. V+ ^0 K7 \{ p3 r f5 v1 A
Wid.x= mDispR.Width(); + Z& s( y8 j5 v' r/ M
Wid.y= mDispR.Height();
# ^4 E- [. I9 K1 n! m9 S// 1:1 显示时, 不能大于图形大小 8 m! n& o. R, E4 ~- J4 w
if( Wid.x > mpBitmapInfo- >biWidth )
. z( U& y7 q" i4 \3 ^Wid.x = mpBitmapInfo- >biWidth;
3 D- M1 |! Q* r$ \& _) I# _" Cif( Wid.y > mpBitmapInfo- >biHeight)
6 J" G0 n4 k9 x' ?% b3 S; p- M5 z6 BWid.y = mpBitmapInfo- >biHeight;
/ ?7 q8 m/ S% `% L+ M( ^ : U, o9 M; r! L+ V$ q; Q
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
$ M4 V) }' {4 I& M% [, 0, 0, Wid.x, Wid.y,
) \, ]; g1 g( Y D. e. C" {mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), G0 K9 u y9 l' b' t3 D
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); : ]5 Q( e4 R% k7 D' m; c/ n- u
} else {
2 d! ?% R* I' d& U$ gDrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
* X' D8 \+ m" h, P6 Y U0, 0, mDispR.Width(), mDispR.Height(), - H# _8 u' Y! D+ a) e
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), 9 }; g! _- r0 v( k8 b' j
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
! I2 N; y* C; H) oDDF_BACKGROUNDPAL);
+ o9 W9 Z5 c! l$ r6 o) ?} - {7 g& [% x+ a. G8 g4 M& }5 w
}
+ U& }. g5 s- i" m/ }return;
1 r L8 s. A( L4 ~' I} 2 s2 O1 @- j7 }2 i+ Z- m
8 e3 K# V! F4 ^( W, U. s
9 y. T% Y# H0 A---- 五、使用CViewBimap类显示BMP位图 5 d3 F* ~( F: L$ x2 k3 b
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC & P% H, _0 s8 o8 {7 a3 N5 s
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
+ L0 v: M( \. ?击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
* H7 y! W8 A( L( c, t: a,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的 * q D* k- L T4 s+ k
尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 ( j* P. U, G1 Z o! f5 S1 q
+ R' C: u3 O! V
---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project- 1 P9 w8 v. V4 O' m
>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。
7 o' h8 t+ o3 z. c6 ?: f ! G& E& G% m' T# Y
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为 . v+ |9 p) C. V9 l
CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
8 K$ H7 U7 ^% U7 B/ y, d Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 6 J! `9 v1 X' q& V9 n, g
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 ( w! n$ m F# N
。代码如下:
8 H4 O: M; v9 a; A; |! N9 Y
0 R4 L6 {# G2 y% U; }! P6 h B( pvoid CMainFrame::OnViewBitmap()
' p, {; I0 a+ Z! I{ 9 l5 V" g7 Q* D; ? b: D6 {
// TOD Add your command handler code here ) K$ @8 J# ^1 x6 A% u
CViewBitmap *pViewBitmap= NULL;
; j# H' P) t" ^8 q' W 3 d, Z1 s; `' X& r
pViewBitmap= new CViewBitmap( "BITMAP.BMP", this);
* d8 d K0 y( U; e% V/ fpViewBitmap- >ShowWindow( TRUE);
4 \3 w9 Q- C2 K} . j( B* o* @" h
. y8 P9 R5 H& W' W( h" D/ R 9 ?( [- L5 {4 ~7 ?- u. ]& w
---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。
1 ]) Z% \2 q" [0 B: v---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
1 C3 r7 s. v* w! E5 M4 }% E
( z+ d8 O+ K; w! a* k, V) G---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >
! @" q: l1 l1 |, \- k! m1 ~ ViewBitmap)即可显示BITMAP.BMP位图。 0 q5 {8 H/ A7 z/ V7 T. h2 p6 _$ |
/ k5 l( E# {& G* ]- q---- 六、CViewBimap类功能说明 $ r& [- k0 Z" U/ W
% J: p; `4 I3 z" ?+ _: i: p2 E
---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可 ( m; G+ n0 u7 F4 y
以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 8 O8 I4 L' r. ~9 s7 B6 L6 k7 {' @
3 j: W& q3 Z$ p2 V
---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为
$ f' h% R/ }& A) M6 ~, g, f/ R位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
4 P3 t0 j' [9 l4 O" Y% ^# l,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
$ F! S3 W5 Q' H第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
5 ^# v% `( W1 q4 Y0 j) t小,则对位图放大; 如果位图比客户区大,则对位图缩小。
! q3 `0 A: x- M8 v) |) r! I- r1 N . S6 y Z$ Q: N2 e
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, - t' C {% S2 S G ?; M
就可以显示该位图。
6 ~( O3 A$ z6 j% `
; y& T6 N; ~3 O9 t. d6 f# {$ I---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
# _0 K; w# D" I) ?
7 B6 o) C" S* H+ x1 \在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图 $ C* }) h1 [; R+ X. R& B3 ?
放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失
3 k1 x5 ]9 A; g u* Q% [真小,显示速度快。 & e1 a8 O. ?& z
. |; m& W/ U/ @( m---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 ' N. Z' ~/ x/ M3 a: r3 l& n
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可 F1 u4 d4 h7 Z, D7 m
以体会到使用视频函数的优越性了吧。
: z( X; h% A; I) M R
# B) L+ n9 |3 I# v/ k---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示 " b1 D0 {- h( H
程序中加以适当调整即可,读者可自行完成。 |