|
3 c. n( j) ~/ _- g9 ?& H1 ]
西安交通大学流体机械研究所 . Q9 o Y; M' F7 l7 h3 k i/ G
张义云 9 n" B+ l0 a8 ^
6 Z6 M' J" ]* ~---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
5 X9 ^, ^" s) k5 P在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数
& t; O' G ?& K* a; f: V V I8 w显示BMP位图,可以消除以上的缺点。
8 n2 |* j: C3 M" Q " ]+ z x9 G" B+ r: y
---- 一、BMP文件结构 2 v9 T9 l! z' G" D5 A
' C+ y0 l; y0 ^
---- 1. BMP文件组成
, k7 h9 f* b: } }. d ! m8 r9 D7 }7 i4 ?! w2 y
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 6 ~) Z* f; b) J" m, O. `! y
% Q' G! B( P+ J k9 _3 }5 T3 A2 d
---- 2. BMP文件头 $ L8 _1 F+ @! f9 E/ N s" h
! O K0 ?9 a1 v, K
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息 % M5 o; @6 W/ @
。 % L& H5 q! l2 R& t' { \7 W* x
A! T& ^ {$ u: J
---- 其结构定义如下: 3 q3 d& F' C8 w% }. M
8 l" q, Q3 G' x( D" Y5 v/ Jtypedef struct tagBITMAPFILEHEADER
6 C. p7 F* @7 i! r{ / C, a6 }% f5 w4 W7 ~
WORDbfType; // 位图文件的类型,必须为BM
0 I6 F' I% H5 c: D) oDWORD bfSize; // 位图文件的大小,以字节为单位
. w2 X7 ^, E; b+ _9 z2 ?WORDbfReserved1; // 位图文件保留字,必须为0 $ U; X+ O/ p# i/ O+ E8 e+ \
WORDbfReserved2; // 位图文件保留字,必须为0
1 M" K+ u+ v6 K# m1 CDWORD bfOffBits; // 位图数据的起始位置,以相对于位图 & ]+ |8 Y3 |# z, ?9 t/ s$ s
// 文件头的偏移量表示,以字节为单位
8 f0 N) q" v& u- f} BITMAPFILEHEADER;
% G q0 [/ @+ I! G$ X4 ~
! j) F% G; h; y. J: m1 j, M 4 @' r: M/ C2 n5 M k' H
---- 3. 位图信息头 % z [( k W2 O' G7 c5 Q1 C( P
---- 4 }# W6 @- N7 p* F
4 N* C/ `$ U1 B0 S
BMP位图信息头数据用于说明位图的尺寸等信息。 2 \7 B1 t0 t0 B% ]
typedef struct tagBITMAPINFOHEADER{ 1 O2 |" g; p9 E
DWORD biSize; // 本结构所占用字节数
! a6 Y3 W) `6 W' x LONGbiWidth; // 位图的宽度,以像素为单位 + L J% c4 h, K/ I D7 E
LONGbiHeight; // 位图的高度,以像素为单位 . ?' `! T! s% q4 ]: h" C
WORD biPlanes; // 目标设备的级别,必须为1
2 p& i t* _* G( h, u) W9 B( \; y WORD biBitCount// 每个像素所需的位数,必须是1(双色), . Q1 p9 [# p: x; B9 `: d( F
// 4(16色),8(256色)或24(真彩色)之一
( r" \3 ], U$ P8 c( L1 x DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
# Y* B2 o1 c6 H: W* ^ ]: ]8 U // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
9 X" P1 C6 N$ C) k6 k5 V DWORD biSizeImage; // 位图的大小,以字节为单位 , w5 Q) b4 `, `$ T. |# l, v6 ]; a
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 ; B6 a0 D0 v7 G3 k( g2 d5 K7 c
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
: E1 j: o% W/ X8 F DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
4 S( \( l8 Y- K9 ] DWORD biClrImportant;// 位图显示过程中重要的颜色数
# v+ f. L* e; ~2 f0 i5 `! |2 |} BITMAPINFOHEADER;
: ^4 y( S+ Z! ?0 d: P 3 x3 W: c- m* M
) h0 R1 F- r1 \! p
---- 4. 颜色表 , Z4 A9 A% q% [
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个
) w+ P% X$ f1 s4 R4 x8 x1 CRGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
7 G+ V7 X" \" A% K
: h, M- h: C3 i6 J1 N. h. [typedef struct tagRGBQUAD { 1 j4 x B- h# D5 Q
BYTErgbBlue;// 蓝色的亮度(值范围为0-255) , r# U& d6 ^. y& g: E5 {. T
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
9 M1 o# s0 H! @5 X5 v6 KBYTErgbRed; // 红色的亮度(值范围为0-255) ' ?; W( c. h" l, j- T
BYTErgbReserved;// 保留,必须为0
5 ]6 O1 j' M: U) L( O+ L& |4 g* N} RGBQUAD;
" z; @$ V7 E0 R, i, t- I颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
/ I) g, t8 g/ o1 z, r' s2 `当biBitCount=1,4,8时,分别有2,16,256个表项;
7 z; m7 I8 j& a8 h& Z, J当biBitCount=24时,没有颜色表项。 , S' C6 L" h2 Z6 D- E) [9 c
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: % T6 m9 c n/ o0 f* p5 _. F
typedef struct tagBITMAPINFO { ! m1 x2 J$ G' I; Q3 A: Y/ g
BITMAPINFOHEADER bmiHeader; // 位图信息头
P6 `0 y+ X# e+ w( ^6 g+ c RGBQUAD bmiColors[1]; // 颜色表 5 _# n/ P1 x" T) X0 S1 ]* h
} BITMAPINFO; 4 _! q, ?" F( B# m* B& @9 p
# ^( L! [7 A. ?/ _3 v
2 _. \" v" k7 u2 k4 _
E5 o' ^0 }" w& A4 o
---- 5. 位图数据 & R+ {. l- L* c# c- P# u* E' m1 E
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右
4 p; ?; ?5 I1 |: U+ g,扫描行之间是从下到上。位图的一个像素值所占的字节数: 1 P) z8 n5 y3 n$ h" L: B
O' O+ F9 h; P* X; Y当biBitCount=1时,8个像素占1个字节;
0 e$ m S/ ?# Q1 \8 M当biBitCount=4时,2个像素占1个字节;
" q8 K6 C5 U/ q: n# A% P/ @当biBitCount=8时,1个像素占1个字节; ( i8 e; v4 v4 }# v9 i5 }( R0 M
当biBitCount=24时,1个像素占3个字节;
9 {4 N" ]6 \1 H, h0 Y* z/ K |Windows规定一个扫描行所占的字节数必须是 ! T6 b3 n: {& f6 U
4的倍数(即以long为单位),不足的以0填充, - h* h$ j1 ?$ S0 t
一个扫描行所占的字节数计算方法: # I. D) w0 V9 j4 ~' B5 b4 E, D
DataSizePerLine= (biWidth* biBitCount+31)/8; 2 u* J$ F+ v. M8 v O
// 一个扫描行所占的字节数 ; i$ S8 W9 g6 [4 `- T; T" A
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 2 i g$ y/ G/ U7 M# T! A* @
位图数据的大小(不压缩情况下): % N( x8 t+ {! s! _7 Y' K
DataSize= DataSizePerLine* biHeight;
5 B' ?2 r" f* t
: ]! u: u3 d4 p1 z
/ @ t8 X c7 l% [8 u" z---- 二、BMP位图一般显示方法 + w7 e+ p, o& w7 w% a4 {, ~8 b
---- 1. 申请内存空间用于存放位图文件 ! y1 {2 T3 n2 m
+ S9 v5 C- N' c( U9 a1 y
---- GlobalAlloc(GHND,FileLength); 8 |, d% v/ P+ J# M. m, w) T( s
- L& ^# B# w; @7 f: {
---- 2. 位图文件读入所申请内存空间中
) f% A% k- K* Y& d9 P' g
7 H1 F5 j7 u L3 u# U---- LoadFileToMemory( mpBitsSrc,mFileName); ! B* P) o6 |1 T: {- u: u
% |1 j+ a' k* E7 X; L5 D2 W---- 3. 在OnPaint等函数中用创建显示用位图 ) H1 J7 |/ e; S' ^. n
2 V" h% J) S0 s1 E) q% x, G
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容
7 e K+ ]* ~" Y( J1 fDC, ( i& W% M& f! Z& [' n5 p$ K; P
$ x5 y" }( d3 {# u1 z3 J! B
---- 用SelectBitmap()选择显示位图。
0 s. @& o$ W6 k6 Z% w 6 Q* B6 H+ W6 r) m
---- 4. 用BitBlt或StretchBlt等函数显示位图
/ t9 `; [5 ?8 [4 w1 S) U, k% V
! E$ x3 r& a& _6 ^---- 5. 用DeleteObject()删除所创建的位图
" C8 U8 G8 {1 ^& `' F* R
1 L0 ]+ ^8 T8 K7 J$ n% c---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 * l' m% _; N. f1 o3 F
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(
( a/ r! J8 t3 F$ x& l如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
' _* B( e6 C" g$ v7 R( x
, ?0 y' d. q1 y---- 三、BMP位图缩放显示 ' O$ [! D7 Z6 c. u: d5 ~$ z
" `" Z& t: @" w! B, g! M1 \! l5 P
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形 # G, g2 Z, L- M4 L
进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 & ?# v$ p6 v- D, ?3 }' ?/ N
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: ' ]" V& p5 h: l) {8 ?
r: h4 W+ g4 l
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 / N7 D8 a2 b: B6 E% R4 }
# B$ _, m6 l& h) x. ^" G---- 2. 申请内存空间用于存放位图文件 & T) \( D" A$ O: L
$ M6 H: x4 q, t---- GlobalAlloc(GHND,FileLength);
- ~. N0 f8 \( m( f4 K
{) ?' E( V8 G. B5 ^$ s1 L+ X---- 3. 位图文件读入所申请内存空间中 . H2 h7 c' X- e6 C
3 p4 N# g1 i/ T/ F6 l---- LoadFileToMemory( mpBitsSrc,mFileName); 5 a4 E9 n1 p8 {9 ~) u
/ J* \* K$ F$ i% D
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 ' F7 H: u( y3 ^$ X3 i8 P
+ R5 [# W. B1 J$ ?( M# e1 J! d- O+ n
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
, ]1 p" M# Z3 _: Q 9 k7 E: ]8 \/ H r( N V( F
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形 + l" P/ ^" q! A( h
失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通 $ d& P% d* F8 F; `' A2 b1 V( ]
过直接处理位图数据,可以制作简单动画。
5 p4 k# p1 D6 \: W% P* |! m. X
$ ]; s! @$ C" p/ D) U# Q4 b4 [---- 四、CViewBimap类编程要点
7 h1 m+ p4 J) N
! S H A- x) X* P' P5 M' u---- 1. 在CViewBimap类中添加视频函数等成员
. f9 H# g. M1 ], m0 X
* E7 o$ C8 r7 X# S8 GHDRAWDIB m_hDrawDib; // 视频函数
/ {( I$ R5 Q1 S; NHANDLEmhBitsSrc; // 位图文件句柄(内存) : D6 L3 Q2 a0 K' y* {, t# h
LPSTR mpBitsSrc; // 位图文件地址(内存) " T( U" u* n$ k: P- ?
BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
' O. \; i |2 g% L5 H1 S' U/ `7 O
* ~- `6 f) @# i4 t9 e 3 h0 c' r2 W/ U
---- 2. 在CViewBimap类构造函数中添加打开视频函数
7 ]' K1 W8 G2 P! L1 V a---- m_hDrawDib= DrawDibOpen();
# z2 h9 \ K& Z" w4 ?1 @' N
8 F! }9 \+ X+ _+ e! K a4 ^* X `9 ]* k---- 3. 在CViewBimap类析构函数中添加关闭视频函数
. ^/ e( V p+ O" l4 t) V) y1 l 8 u0 v: D, C$ R
if( m_hDrawDib != NULL)
6 B, }$ K8 v5 ]$ k { 4 J- p1 [/ x8 v
DrawDibClose( m_hDrawDib);
4 C8 `& a& J- \! ~8 _ p m_hDrawDib = NULL;
( k6 R( b1 B% C8 j) {0 p# g% X }
( @& k. s( Q+ b- X5 W
Y3 g9 d/ P: k4 P; W+ _
& `0 T M" H/ E---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() " ]2 m1 N. o, \' P2 t3 S) q! E- G
voidCViewBitmap::OnPaint()
: R$ V0 @+ l5 `; s{ ) y0 ~& E# Y! @- [! G! N& ^
CPaintDC dc(this); // device context for painting + [0 Z0 `2 x9 \$ l2 F$ T7 l
GraphicDraw( ); 8 V( O$ r6 E$ A7 W5 d
} 5 {3 T7 {' h7 f" ^: c
3 n8 Z+ o% h( {* X# J. x
voidCViewBitmap::GraphicDraw( void ) / Z ~0 b( F% N e: _6 e; E
{
2 O' g2 A8 g2 g4 }6 t* u* yCClientDC dc(this); // device context for painting
& M* }3 `) H- V6 pBITMAPFILEHEADER *pBitmapFileHeader;
4 J; H" P+ G9 e. D+ ^% p1 ?. SULONG bfoffBits= 0;
# f8 I5 q2 V$ n/ E2 wCPoint Wid;
$ r; d9 j" i* a& m* ` % g1 [9 |/ N7 b# X# Z) ]
// 图形文件名有效 (=0 BMP)
. b& L- X" f3 {0 Y- m3 aif( mBitmapFileType < ID_BITMAP_BMP ) return; " S) W) Y+ A" m
8 A) G* H N1 N- H7 D& ?+ o! s
// 图形文件名有效 (=0 BMP)
$ _2 R/ N/ j8 S// 准备显示真彩位图
' P& c. p/ e! p0 y) [pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; % ]# w1 ]9 [, ^' i w7 A3 p
bfoffBits= pBitmapFileHeader->bfOffBits; ; _* T" y0 d% w( M/ I' L
0 O8 P$ j2 X* m: S: G8 J# m1 _' [// 使用普通函数显示位图 / ]3 n R" C! \: ^
# l! o' g+ P# ~# \5 J+ W$ a0 pif( m_hDrawDib == NULL || mDispMethod == 0) 6 {- ]5 Q$ l u- p
{
. G& m& t' I0 T' G# b! ~) c HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
. n$ [0 O2 z# l* t1 bmpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, 5 m/ O$ a: L. P, I: _0 w# g& G$ V4 T
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);
: K7 d9 U3 p: \% w% I// 建立位图 ]# R. Y6 U+ A% g! ^) S5 G% Q
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
2 U2 s$ z5 |8 b9 iHBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象 9 v" G+ ]: v, ?( ]' v
// 成员CRect mDispR用于指示图形显示区域的大小.
( l. F6 k5 D' C4 O// 成员CPoint mPos用于指示图形显示起始位置坐标. * s m/ r9 o4 b: s; t+ a' r
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) 3 N' @2 y$ l# i. _2 K0 P6 w( P- x
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ; - g4 s8 Y N8 I- \2 c+ W# E+ Q
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
' J+ t6 P/ C/ r6 _mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
! `2 d3 H+ b; u* @0 N if( mPos.x < 0 ) mPos.x= 0;
, R |" q3 o6 N' `! }6 O( l$ \ if( mPos.y < 0 ) mPos.y= 0; & [( f/ _* g7 O; ]
l" h5 t, X# H) K) Z9 P% O) k* H if( mFullViewTog == 0)
. |. C! n2 i, g7 |; J0 H{ 8 d% O3 d+ X( i7 I/ ~
// 显示真彩位图
3 `8 P: I7 H* l/ t% e; A::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
- _% U; g( M% R7 k) ThMemDC,mPos.x,mPos.y, SRCCOPY);
2 I) q# ~# Y; \& G: e* [- c7 x} else { 1 M8 D( h/ t g, D8 O
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
" @# d1 ]3 W9 t$ ThMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
' L9 X, a7 J1 D0 i- s. S>biHeight, SRCCOPY); . A- [" h3 p# H) t; d8 t v5 `" K
} # l+ V5 |" z0 ~. C* @; e
// 结束显示真彩位图 7 ]( E: d2 C8 t) [4 c
: eleteObject(SelectObject(hMemDC,hBitmapOld)); , Y2 j& M9 J6 n3 b4 E
// 删 除 位 图 " s3 |! o* Y# p; M0 E
} else { - G7 _3 U% S& d, ]" S% G. P
: }6 j f7 ~! \" X8 P$ T' p# v
// 使用视频函数显示位图 9 a/ E+ P8 k# {7 C6 M
& [7 t$ N. x9 w& g2 i$ I
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) 9 l5 H0 x6 F1 E* Z$ M
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
* M: W* G0 A: L5 s; } if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) ( v6 S- d1 x2 [4 `, n3 [) j
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); 6 }! g. l! Q/ |4 t8 {- v3 a2 K! w
if( mPos.x < 0 ) mPos.x= 0;
' k* f3 M* R1 J- ^9 A if( mPos.y < 0 ) mPos.y= 0;
; ~- l8 w8 \+ v* O- F* i* r % d V4 Q; @9 @7 h% f
// 显示真彩位图 + m: S/ r! B8 n4 x+ w; O: q* ^* b
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); % ^ [( R* b# X& W5 E# i
+ O$ P) a, o, C) w8 x! ]
if( mFullViewTog == 0) ; g' ]4 a4 O- Q; R
{ : u1 @ c% t* D6 ?8 P
Wid.x= mDispR.Width(); 9 |# `6 H# v' t; [
Wid.y= mDispR.Height(); . l' o) m3 ~2 i' a
// 1:1 显示时, 不能大于图形大小 1 s& D* q( Z+ m
if( Wid.x > mpBitmapInfo- >biWidth )
8 h2 }5 r0 p% ?6 m: T; m$ M" GWid.x = mpBitmapInfo- >biWidth;
" V- [. [- H k* d Sif( Wid.y > mpBitmapInfo- >biHeight) ( E6 Y5 f( ]5 ^
Wid.y = mpBitmapInfo- >biHeight; # f8 p0 } L, I( R
2 R" m/ B! j- c4 @( l) Y1 qDrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
& y9 N' i' w( l7 z1 [4 k1 B8 J, 0, 0, Wid.x, Wid.y,
' u2 v( w' [9 L& q1 |. MmpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
+ k! n% f3 G4 c0 I" e1 r9 }" FmPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); 7 O! D) }; b, O9 m
} else { 1 ?4 L6 s) } {/ T
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), $ a8 Q- X( D4 E6 Q. F
0, 0, mDispR.Width(), mDispR.Height(), . S9 W+ l2 `7 o* ]/ U9 v$ X
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
) U: h* q6 Q) g" J4 R0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight, 2 e, k6 R0 I) w, l# q/ |
DDF_BACKGROUNDPAL);
8 j9 Y. Q4 M8 G3 V3 V, |6 O. n} # c0 Q- a4 P' t: p
} 5 F4 X4 C3 G6 m2 q3 ^ C
return; ' z6 g; P' G2 v$ V$ V
} " S3 i! c7 \8 v% p- K1 P; H
7 y$ s' v/ }. U
* c( z7 W- ^8 v) m6 y+ T
---- 五、使用CViewBimap类显示BMP位图
9 t4 D: ]& j" ]* X4 c+ z! H---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC & R' Q' z6 X6 {9 K, |
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
" n5 s# K8 g) \$ j/ ?+ Q击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
; I& x) `* t- ] R,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
7 {' s' `: O9 v4 @) D H; U7 t尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 5 K" I/ }4 O8 E
3 M2 _' l, m; p' d% u) `---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
* i( U/ B8 l, G# a>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。 ( H* J" O- F* A( D5 a0 v: {8 w1 R
5 p6 L! g% [3 c! j---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
: j3 h* y% |( v7 X1 T7 H: |, k, VCMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
4 [; y* z! K. S$ `# K8 ` Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在
1 Q: m4 r0 `! G: o+ d5 t3 EMember functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 + X3 u ]0 L4 C% U% b8 g
。代码如下: 6 m, z+ t: Z! S' a8 L! u2 R
3 O# U" w: G9 X2 b1 x4 Dvoid CMainFrame::OnViewBitmap() 1 q& V% Y- S1 k$ C
{
1 G1 M; D/ p6 A; X! G; a// TOD Add your command handler code here ) w% E) m6 @+ g
CViewBitmap *pViewBitmap= NULL;
4 _7 p7 Q; Q3 i9 E8 k# G. _
+ U2 I% [( ?! q( ~pViewBitmap= new CViewBitmap( "BITMAP.BMP", this); . m8 A% {; y# [
pViewBitmap- >ShowWindow( TRUE); 9 _/ x/ C% M. K+ ?3 v. z
} ) K; y4 T$ r7 ~) A8 M) S$ }% q
( Z7 v6 n9 |0 B
! W% w" G, r0 L7 Q: a% w---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。
; [9 Q$ `7 Q0 ` u---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。 " H& R8 H$ S. T
4 }: ~+ f$ q% m# [+ [% d, r0 v/ ]7 M---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >
* c9 k9 R3 q( {$ x8 P2 e' i( R4 y ViewBitmap)即可显示BITMAP.BMP位图。 1 c8 k8 }) G) T1 W) p+ J! S
% O+ H" O0 r: }; P
---- 六、CViewBimap类功能说明
* U) X% K" P, m1 \' m' o
s1 A! e4 j* H8 t0 M---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可
3 l; E* t2 q$ u0 @2 P+ {以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 / ?- X% h4 G( g5 `4 g" Y4 F
5 a" P: x: U) f9 y0 t
---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 & F3 a7 {. M, O2 D$ e+ }
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标 : U C) n0 q/ n. b7 j, S
,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
0 v D* _7 R" F) F1 T# E. z) p第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
9 U% F9 w+ w* ]6 N! J, u小,则对位图放大; 如果位图比客户区大,则对位图缩小。
" s4 i+ Q1 q* s1 Z' P: Z / g1 R) N, U+ Q& j1 u+ t; F( j! [9 |
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, 7 A( s" A) G3 p u1 \% t% D9 D
就可以显示该位图。 + G3 f1 x8 G3 |! O- N6 ]" m! d
2 {+ E, M- d+ }3 |# J$ L1 A---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
& l- }2 C( O" d! I* U- g8 [' V7 l- |
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图
& V: G$ a) i, o5 C( I, ~4 Z4 p+ M放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失 , ^1 R4 L" M6 M; ]# \. u: {" N) t
真小,显示速度快。
* N f( R* M7 E, D# X; r3 D2 ^
, K' }, [8 P' P3 i---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 " h8 S' h% c- O' R
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可
, J% h# f4 ]7 `6 U- U( [ A以体会到使用视频函数的优越性了吧。 4 O C8 v. X) U$ m( s4 A
3 }) C5 c+ ^: D$ {/ m
---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
* w5 U. v+ Y2 i7 \程序中加以适当调整即可,读者可自行完成。 |