|
0 K8 U* l7 d& n$ a% A
西安交通大学流体机械研究所 5 U; z+ J# v* Y! q0 Q. B
张义云
# H6 q; ^- a2 Z! x1 R
$ t+ K6 z2 J" y$ g5 P# e' X, P---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重, 4 z6 `: E! n4 F
在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数 6 T. E" y' `8 j1 J# ?) h
显示BMP位图,可以消除以上的缺点。 ( Z1 c* n3 M3 J5 {# K
& M% c- _3 \, U# @1 v$ l" A
---- 一、BMP文件结构 6 V* V z) U4 F+ ?1 f$ w9 N
+ K0 _1 N; H( `) n% t
---- 1. BMP文件组成 ; U4 X0 i- V1 R1 X$ c* T
) c( w) D' |& Z! B0 z
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 % ], _6 g2 G; J
3 B$ n6 q- `2 q& {: c; w4 n
---- 2. BMP文件头
, r4 i) n& O1 a: q e
, [ s: X1 D, O k9 e+ ]---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息 ' I$ J! z l; e8 y$ }
。 ! N8 V5 t2 i; o5 g1 S
- v5 P" m/ T& d& [& d* T
---- 其结构定义如下:
: m+ j" \/ i5 o; r6 d; W . G J3 u! q+ |# T9 o
typedef struct tagBITMAPFILEHEADER
- p6 I9 R: w# s6 a: k8 H{ ( ]+ I4 x* Y M) j2 z' J
WORDbfType; // 位图文件的类型,必须为BM `, u3 ~7 Z) B7 w+ X
DWORD bfSize; // 位图文件的大小,以字节为单位 2 c0 A, V* z! c1 V9 `
WORDbfReserved1; // 位图文件保留字,必须为0 ' i+ z4 ?# _ y5 _; V0 ?5 j1 |
WORDbfReserved2; // 位图文件保留字,必须为0 9 V1 ]: V: E6 b0 `4 Y2 N2 s: G0 r
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图 5 ^) h+ ~: [- ~, @
// 文件头的偏移量表示,以字节为单位 & Z& M, p3 H% F' T" J
} BITMAPFILEHEADER; - M0 I5 N, N8 Y! X) J
0 Y$ d: g ^' a2 a1 s5 i5 f6 S
6 w, P: g S, d) B8 u. H: `/ i7 B---- 3. 位图信息头 $ g( n" m9 T9 J
---- 8 k( P' Z" U" O& p, `
2 t: `/ ?# [, J! z
BMP位图信息头数据用于说明位图的尺寸等信息。
% v. n) ^- H* T) b. ?: Q8 rtypedef struct tagBITMAPINFOHEADER{ ! `5 u! ]6 M* M- }6 A* S
DWORD biSize; // 本结构所占用字节数 ! N6 ~. F6 a( y' R8 S/ o7 t
LONGbiWidth; // 位图的宽度,以像素为单位
5 P! g) C: K7 B/ R LONGbiHeight; // 位图的高度,以像素为单位
% ^" f! [7 j: o2 L% w WORD biPlanes; // 目标设备的级别,必须为1 z \9 d+ _& ~+ q
WORD biBitCount// 每个像素所需的位数,必须是1(双色),
/ e- r& L# B/ N1 f // 4(16色),8(256色)或24(真彩色)之一 7 _$ ^& b% O+ t3 m' V
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), 2 q! m8 W! W7 z& q0 L, g
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 ' _' z" l7 z: H* M4 {$ G5 d
DWORD biSizeImage; // 位图的大小,以字节为单位 ( I: C$ B5 y u/ g3 r- r5 `
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 9 n" K7 m0 V3 m( o
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
' n4 Y* D1 o T3 M# W DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
5 x- v6 m- W4 c% ]3 x9 `9 h9 [ DWORD biClrImportant;// 位图显示过程中重要的颜色数 $ a; l- H( E8 O+ \8 w3 c. N( l4 _
} BITMAPINFOHEADER; , B$ B$ T7 P) p. _$ o
- s c; ] d5 W
' q3 f$ E ]2 f% |, Q% w
---- 4. 颜色表 - j2 I- Y! w( H0 t
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 0 y1 [; V0 F4 l" j( N; X0 \
RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: ) ~! ^: d/ C+ E) Q4 A
) t {) H4 z7 f( Y0 htypedef struct tagRGBQUAD { / |' O* H# M! g: q
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
% z: T0 {/ @% S+ SBYTErgbGreen; // 绿色的亮度(值范围为0-255)
) c3 r0 t4 n b) d0 qBYTErgbRed; // 红色的亮度(值范围为0-255) 2 o; w/ D3 S2 `; @9 `
BYTErgbReserved;// 保留,必须为0 ! d' S) B7 N5 `! {7 z& H
} RGBQUAD;
- Z. s: I4 c: p5 O颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
1 D* u$ T" c7 ]* U' C) C3 I当biBitCount=1,4,8时,分别有2,16,256个表项; & L: R5 C; G% v. X2 H# @
当biBitCount=24时,没有颜色表项。 9 o# n; {. u. R( }
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 3 ~. B7 b% Y, [
typedef struct tagBITMAPINFO { " A5 w' f9 B% w: |, h
BITMAPINFOHEADER bmiHeader; // 位图信息头
0 `7 ^( ^, d0 \4 [" C$ I& z RGBQUAD bmiColors[1]; // 颜色表 ! `, k0 v8 y. ^2 Z3 y/ ]) n* h
} BITMAPINFO; z' i1 W9 v2 S/ q7 G5 x% A
6 L8 M8 B9 M! X0 X. _
9 \6 [+ I$ y- Q: G5 _7 N
5 ~9 B, f4 H+ R6 O& x---- 5. 位图数据 1 e+ D4 c1 H0 E' D8 `! h, x1 y) g
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 + k; A8 f& f- l1 N6 B
,扫描行之间是从下到上。位图的一个像素值所占的字节数:
6 }3 ?" Y% U! Q3 w! G
( D4 G# l6 J- d" l# ?4 U当biBitCount=1时,8个像素占1个字节; & p* W9 \* p0 U5 K0 L5 w% J
当biBitCount=4时,2个像素占1个字节;
0 F" e, B! o" _3 _当biBitCount=8时,1个像素占1个字节; * a; a5 N: E. e, o! B) `) B9 W9 ~
当biBitCount=24时,1个像素占3个字节;
& k/ e7 g) t; a/ I! `Windows规定一个扫描行所占的字节数必须是
0 J) m3 g/ p: C( U4的倍数(即以long为单位),不足的以0填充,
4 @! A( \9 t- ~ i& d一个扫描行所占的字节数计算方法: ) A! N% P! C* ~2 L; A. M
DataSizePerLine= (biWidth* biBitCount+31)/8; ' c9 ? h6 [+ q+ ?4 i z' C1 i
// 一个扫描行所占的字节数
# }4 k" h+ @9 ~. J, K6 yDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
p. v3 B. B q& l, W8 \( _+ w, ^位图数据的大小(不压缩情况下): 4 ~+ |. P E$ y! }+ Q) ~) S
DataSize= DataSizePerLine* biHeight; , W$ O& Q4 @; R$ j$ U; e
4 e1 l. O/ u) X- E. w8 r6 T
) ^6 I! _( B/ Q& s: C( W& u! u---- 二、BMP位图一般显示方法 0 l; u9 D: J/ W7 r
---- 1. 申请内存空间用于存放位图文件 8 [4 ?0 j4 `# Z- ] |$ l1 n3 j* f
7 C1 E# O- O( l3 K+ g---- GlobalAlloc(GHND,FileLength); 5 t' y. x0 A( N! W0 ?# Q
C7 N/ D3 f3 m a---- 2. 位图文件读入所申请内存空间中 ! [- k& k* w/ I5 T: J& I* s; U3 G
% w- N' b* F. b' i
---- LoadFileToMemory( mpBitsSrc,mFileName);
) T, G- j( \9 G! H& w ]+ X1 M, Y0 { V0 L0 @1 l
---- 3. 在OnPaint等函数中用创建显示用位图 3 V( z; M- j* B5 P
& _# X" r! \$ r' J( {/ K---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 ; i G) c: T7 q" ]2 R
DC,
0 d8 Q/ B& ]. y# i, E2 y' ^7 f ! a2 Q7 P2 J& R$ d
---- 用SelectBitmap()选择显示位图。 " l7 [5 G2 `! m3 [
3 i$ p0 r, G7 b/ v/ X---- 4. 用BitBlt或StretchBlt等函数显示位图 * O9 o" I- R4 t- T' @" r
0 t* }( ]6 O9 b---- 5. 用DeleteObject()删除所创建的位图
1 E8 L3 _# J2 I7 C; a4 l/ H) J
9 P6 B! h3 T7 O, l/ z: [( h---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 - j$ o8 [7 W* F9 k/ o: C( H
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上( ) N) C1 j4 ]! e3 l2 l8 v) k3 f
如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
( \3 N$ t. c/ X9 v, L2 Y
; y: c! d2 m: [( O# ?! |, w/ L---- 三、BMP位图缩放显示
* T) A6 X3 o: X3 b2 u. }; B
4 ~4 j/ t: a# c2 T# `( ~) z( f4 T---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形 5 F' I" B8 C) \ G
进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 - X6 q1 e O4 }" j
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下:
, G8 h# ?+ Q5 G7 M" c( t
: _( A7 Z$ i1 _$ D7 b( u w---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 ' g2 [+ z& d8 E' T" G, U! h, ]
# H g" ^: ]$ }/ i- _, `---- 2. 申请内存空间用于存放位图文件 ' r: {6 \% k, \$ L B7 q
5 l' A0 ^0 L# |6 n3 m
---- GlobalAlloc(GHND,FileLength); & M9 F! i; X3 `) R! f2 {* |7 c
6 y9 ~' J$ N5 t& M$ ~, r2 Z2 Y: J! C7 L( C
---- 3. 位图文件读入所申请内存空间中 5 q2 P6 m. e! @/ x, C
9 @% \1 w; Q/ `* F& `
---- LoadFileToMemory( mpBitsSrc,mFileName);
+ s5 b+ t2 Q6 o4 @ . p0 Y9 N1 ^! `
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 , B' u* X( }0 w& }, M' \7 f
9 l+ a% ?$ C0 \! G
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
) f( \8 [7 _/ @! D" ~
3 E! X1 D7 a5 K& t( U+ A2 }---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形 . }7 y& m$ G( u) k% s3 P( ^
失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通 + Y* T* X1 J( z7 _+ S! s4 [" g* m/ C. j
过直接处理位图数据,可以制作简单动画。
; Y2 c5 W/ y6 R" c, U . v0 |9 ~* S/ g/ B4 v/ o3 q- x
---- 四、CViewBimap类编程要点 1 G2 f$ S' y9 f2 k) W
J2 Q' y7 |# s3 t0 Q---- 1. 在CViewBimap类中添加视频函数等成员
' |0 s0 V A+ @9 g! G
; v$ N% X/ |: Q5 n3 @# CHDRAWDIB m_hDrawDib; // 视频函数 + _% X# r9 ^9 m
HANDLEmhBitsSrc; // 位图文件句柄(内存)
) g6 o+ \- X$ i% T" _" MLPSTR mpBitsSrc; // 位图文件地址(内存) " [5 E8 b2 T3 |% `
BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头 / V* c) q9 n. M2 u$ a
+ l3 \" y, w. T' I( M7 d ! e) z% t8 v" _# Q# }. E, W
---- 2. 在CViewBimap类构造函数中添加打开视频函数 6 ^' M9 U1 F l4 Z6 p
---- m_hDrawDib= DrawDibOpen();
7 Q W/ }, T+ s# A $ q. j, D- q _! T' i$ b9 _! g5 `: x
---- 3. 在CViewBimap类析构函数中添加关闭视频函数
! I0 P' P# Q9 c # ?5 Z5 ~5 j1 A$ m$ Q* H
if( m_hDrawDib != NULL) 8 e! \- t* J! p% w
{ 8 [5 T. l: O9 k' J) j2 y% E
DrawDibClose( m_hDrawDib);
* b% T" M) C- ^2 }$ G( C. W/ l9 n m_hDrawDib = NULL;
: B: f; G1 ?! S! f7 S0 [# o } * {1 l# W" M" C1 p
0 b8 D/ v% ]+ T( p
! L$ G, T: m# a, z0 B
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() ( k& f- x, Y" Z# x& z
voidCViewBitmap::OnPaint()
5 x$ g" _1 v* N/ N0 @7 V{ . g, W/ i7 T m, c5 M5 @! ]3 ~8 i
CPaintDC dc(this); // device context for painting
6 s6 ]: w( V' _9 e" mGraphicDraw( );
) @8 v( u, s( m+ e; r} ( ?) |9 t5 B2 [# Z2 _5 J
- I4 ^( y# _: ~+ Q
voidCViewBitmap::GraphicDraw( void ) " _: _ m) I! u- Z+ Y( ?2 r
{
. y/ R9 q* L2 e: mCClientDC dc(this); // device context for painting
. u, t4 F6 l: z" P. b2 CBITMAPFILEHEADER *pBitmapFileHeader;
/ a+ P- _% j' oULONG bfoffBits= 0;
5 ^9 ?0 `6 _4 BCPoint Wid; 6 D, u# k2 S, }2 \ U7 r$ A
; @; H( W7 N ^6 _// 图形文件名有效 (=0 BMP)
0 G8 m3 @6 ^; G9 V- X. rif( mBitmapFileType < ID_BITMAP_BMP ) return;
* t' z3 I3 n) f; Y ! n8 v2 M# j4 f- L- u5 s3 S; {
// 图形文件名有效 (=0 BMP)
. c% A0 M1 d" G) x4 Y3 n- r// 准备显示真彩位图 , }5 }8 U$ ^0 z+ ]% S4 w3 D
pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; " j4 l- z' C! t N, X
bfoffBits= pBitmapFileHeader->bfOffBits;
( X2 z( n- f: G/ y 4 r% B1 L4 u2 Z* V4 w* j9 X
// 使用普通函数显示位图
+ U1 t8 F' b3 N : P- X2 j9 Q% _
if( m_hDrawDib == NULL || mDispMethod == 0)
1 {5 E+ `+ ^/ t0 D7 e% x5 A {
/ d6 o9 h; Q7 E/ S8 }( `9 h HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, 7 s a8 s/ \. W* s# L2 d
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
( J3 |) e& g- K0 }) _3 L (LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); ! M: Y- D) M# }
// 建立位图
- |: F/ P1 b5 k t/ SHDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
0 }2 b1 Q5 T& E! o8 D4 r$ BHBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
) f! O5 \# Z9 y4 E1 ~4 L# h// 成员CRect mDispR用于指示图形显示区域的大小. ( L. j4 o- e( ~* f5 m U
// 成员CPoint mPos用于指示图形显示起始位置坐标.
$ m0 X4 ^; H1 \( k! I7 \3 h5 Uif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
( |3 [: v( b9 `: bmPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
- h. O- N, [$ A. Q7 t; S3 v8 o: F if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) * N2 S/ c" g7 Y, n* c1 p4 s# Q
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
* ^1 E( H) w' j if( mPos.x < 0 ) mPos.x= 0; - P1 q1 T8 ?) q" [8 a5 H
if( mPos.y < 0 ) mPos.y= 0; 1 L" ?1 i9 N; n8 p* u; l
4 ~& Z3 `2 n1 p" q6 o if( mFullViewTog == 0)
. r+ R8 W, H" Q' U{
7 Z: d) d; W/ |! H) d3 P+ Q// 显示真彩位图
6 k5 C+ f2 M/ |6 [2 q::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
0 C) [" C6 K- j: h7 {# YhMemDC,mPos.x,mPos.y, SRCCOPY); 0 W6 c6 ~' u- L5 o* I
} else {
: J+ j0 C5 p- D: ?" Y9 x' y::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
) T! z" g5 d$ b! a0 ohMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
9 X0 F/ F6 J; w- u2 _1 Y>biHeight, SRCCOPY);
( P3 k, J$ S( e+ ~. q* o! l} 6 g! }6 a! _; ?+ M3 u' \
// 结束显示真彩位图
2 S. g9 I. G; z0 N6 U : eleteObject(SelectObject(hMemDC,hBitmapOld));
, O2 j. a- [4 a- x' p7 l// 删 除 位 图
/ _+ T* ^3 _# R$ { } else { + [: S) s. d5 f
. E- ~: D4 Q5 Q/ F- r // 使用视频函数显示位图 0 v! M+ ]5 E! }6 [5 s
! K% S3 j5 V, }# l
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
" |( `2 N2 J+ n6 p1 UmPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
$ w: h8 u B& g) c if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
P5 k; E" x2 p5 f" smPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
2 c' p- D, W% Q2 e if( mPos.x < 0 ) mPos.x= 0; 3 Z/ J7 m: ~0 _2 }/ t* d! J% [
if( mPos.y < 0 ) mPos.y= 0;
J! s# f. A" Q( [9 V 9 N" q9 |1 w' S2 k9 n5 N
// 显示真彩位图 " L. K7 U# a+ d* o
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);
# n/ J0 |, n! {& a! l % q% i+ u: [1 Y
if( mFullViewTog == 0) : y4 t5 b# I" |- R5 g( ^) g+ E# x% `
{ / k7 F' z$ s8 g |& R. ]
Wid.x= mDispR.Width();
& T( v; V8 [! G7 f% b; t" }; [Wid.y= mDispR.Height(); ) J2 Q, ~$ ^. e' |5 v; q
// 1:1 显示时, 不能大于图形大小
- \2 }/ o: ~4 c; {if( Wid.x > mpBitmapInfo- >biWidth )
3 t, R3 c- x+ U. A/ HWid.x = mpBitmapInfo- >biWidth; + r1 C4 a5 \. p9 ]' \. n8 g N' G
if( Wid.y > mpBitmapInfo- >biHeight) 9 T, m8 t! h; E/ w
Wid.y = mpBitmapInfo- >biHeight;
8 t1 d2 N3 I, p2 U0 y
) Z9 P. m/ B6 B s) iDrawDibDraw( m_hDrawDib, dc.GetSafeHdc() $ Y7 D% k# K$ o" Y- |; h
, 0, 0, Wid.x, Wid.y, * ^0 T, a/ S; ?% }
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), d. z. h7 O; j- b) S9 P
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); ' B! \. r& G2 }8 S6 N J
} else { ; m) b, ~8 x3 F7 x& f
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), 0 x9 H6 z3 R6 f. R- o! v0 T
0, 0, mDispR.Width(), mDispR.Height(), ( u- [2 x. |4 P. L3 d$ {9 P
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
+ ^% s3 {" \; w6 u3 T! s, o1 e5 E0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight, ! _4 A& `& j0 H
DDF_BACKGROUNDPAL); ) v7 M5 J9 O6 j1 ]/ d+ D
}
. I+ U7 E8 D- _) S; Z" w# o3 R* C } " M' W7 C! r1 y' h6 E& v8 q+ w, m
return; & o7 ^0 c) A& r+ T1 W8 i
} ! ^+ D# w: e) ~/ r7 b5 b" g
$ f, m' A# n$ ?3 v. z$ E
+ t$ B! e9 E% j I7 O---- 五、使用CViewBimap类显示BMP位图 ' _2 ^" N; ^; H4 n3 t
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC ( ]' a( y# W- r5 ~
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
% L2 i7 k' ~2 _- h5 _击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目 + |! N# O+ b! H+ E
,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
2 H4 P5 d1 n8 H- e尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。
& [4 ~& G$ ~5 e2 y/ V# e! ]% m$ k
- E | o$ }" s% z9 d---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
( Y' d& e$ b: ?" Y- I>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。
! T e. H& |6 n
4 h% g4 C: L- e( Y! A---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为 [& l, n) j4 s9 F# j a
CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add 0 P+ e7 M; e3 U" J q: K: q
Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 4 F9 q1 q8 z3 K8 }7 K4 g: J( ?
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码
( l* A7 H- ], _/ X8 N。代码如下: 2 d. ^: M4 n# X
5 P- E/ I1 N Q3 E+ _: t
void CMainFrame::OnViewBitmap() + A i: }& h: W
{
F+ B$ a; p0 D* O// TOD Add your command handler code here
( w# n' X4 r4 K1 ACViewBitmap *pViewBitmap= NULL; 4 s9 k6 S" u2 O g
4 C* A! ]! d, n; h) x, b0 KpViewBitmap= new CViewBitmap( "BITMAP.BMP", this); 6 w/ P, ?. g% z# ?! ?
pViewBitmap- >ShowWindow( TRUE);
4 \$ Y9 M# B" [9 V9 v}
3 N9 X. R/ H1 N 4 s( q* {' s3 [& ~& \ A& s& S
0 x. q1 L1 s* d, V0 ^8 a/ p---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。
( B4 b, D C9 |) p$ y) c1 e$ A2 B) a4 x---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
( x3 x. w. ^0 B( _. r2 x7 f( c) t, H + N1 r2 l M+ T6 k2 k, @
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >
# V) y a0 x# m* k, j! G+ h ViewBitmap)即可显示BITMAP.BMP位图。 # y7 A! ~3 |2 B) d! ]
( E" ?; Z2 Z+ D* M: |8 W5 z---- 六、CViewBimap类功能说明
9 A b% z" L+ i/ z- m) v- f & a7 c1 w+ g3 F$ v
---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可 $ y, M. O8 g/ w+ `! t5 v
以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。
A v! @: Q m& F. Q8 D
$ [" c8 H: U1 s2 h* J; N- J0 @. K6 V---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 + V$ Q" V& l" j; e" H+ m
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
% F3 K* e7 u. d+ j,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
) u1 y/ k# b! ]' { N$ C第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
* T1 ?7 N) Z5 |( `' d. v小,则对位图放大; 如果位图比客户区大,则对位图缩小。 % u) @$ J A }9 [
; z' v: w0 @# [$ s/ g
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, . j7 L; G; d8 ~8 \6 h3 k/ R; `
就可以显示该位图。 $ N" p/ q1 E* m: u$ o5 ~: `" e
- d5 \/ n, D: _$ O( y0 w/ Y0 x9 Y
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小, 6 F3 I* X! ]. E5 P6 O, |3 J3 c
/ U: }3 h: r2 s/ o6 V; _
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图 / _. r/ y; ?: z9 |1 |# O0 A( g( S A
放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失
) ?* Y+ k: T) G; g真小,显示速度快。
! h- C" x5 N) R8 O. _ [# O9 R 8 U3 }: E+ `5 M- _5 F
---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模
- P% U# \' u, _ m) M式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可 ) N( _& T+ T7 h6 Z9 e' R
以体会到使用视频函数的优越性了吧。
R/ P) W+ H: y# {* O# T
/ e* {' _. p. v8 O( n; m---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示 ! T4 K" V: n- _: i* \* @
程序中加以适当调整即可,读者可自行完成。 |