|
+ x" n/ f+ m' K
西安交通大学流体机械研究所
' L' _- X8 B) J4 U张义云 1 z3 D! N/ w$ |' X
& }! x5 X+ ?& N0 G; n---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
7 @, \% @0 D+ D6 Y在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数 + y1 N! Z/ z7 y8 t! n: }
显示BMP位图,可以消除以上的缺点。
$ ~4 A3 P8 R/ X6 z6 |
8 e1 w' J% z/ X& M---- 一、BMP文件结构 $ q: y8 M; d! n$ R5 ^
8 O K2 e7 W6 H7 l( E9 R
---- 1. BMP文件组成
6 T$ k6 V. U4 c+ ]
# P* T& ^' K# u; J---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 3 G2 P9 G6 f2 S" r3 \. I7 V
: i f7 t' S8 c7 }6 ?; t3 y
---- 2. BMP文件头 + u9 z' Y, G' M- Z! O0 Z5 O$ y1 O
/ K8 a- G. A, f0 r
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
* _9 ?5 _3 `9 ~- e) D。 7 l: v7 ]- D6 D' H- L+ ?
" F& b+ ~. ?" E- O. u# p, ^---- 其结构定义如下: / ]* `6 `3 h# F" W6 x5 u+ X7 B
0 [4 i* b4 h5 {typedef struct tagBITMAPFILEHEADER . k2 W; ^0 J) ^
{ + Y: }7 ]* M) ]; S2 [2 L. ?$ {- V
WORDbfType; // 位图文件的类型,必须为BM - _/ {" J, }, |4 d/ u
DWORD bfSize; // 位图文件的大小,以字节为单位
E3 |) U& A5 g E5 r+ T: s1 |# Z2 g( X. aWORDbfReserved1; // 位图文件保留字,必须为0 " q, Y( q% c3 B- p1 D# M
WORDbfReserved2; // 位图文件保留字,必须为0
/ G7 H) A0 p( aDWORD bfOffBits; // 位图数据的起始位置,以相对于位图 ' s1 [3 s7 W7 B; o! i# p* `- }. K
// 文件头的偏移量表示,以字节为单位 1 Q- P: I- v9 l, C- `. O
} BITMAPFILEHEADER; / N4 E M7 o6 j
5 h, R1 M7 H1 a! x
+ W; i9 {. u Y# L, y---- 3. 位图信息头 # F4 q0 @, W2 X- v `! b% @
---- ( d% B0 b( s3 B2 t C. v( i
1 q* N- O8 v, R' c4 U0 f
BMP位图信息头数据用于说明位图的尺寸等信息。
. B7 d+ A6 I4 O: z* m& Y. ptypedef struct tagBITMAPINFOHEADER{ ! H$ k# V3 F* g' a
DWORD biSize; // 本结构所占用字节数
2 z4 k' J9 `( l# T9 z4 R LONGbiWidth; // 位图的宽度,以像素为单位 4 A" g5 o! W% A5 p3 i% R
LONGbiHeight; // 位图的高度,以像素为单位
. X8 ^5 v' q0 R/ u- K z7 @0 g+ ~ WORD biPlanes; // 目标设备的级别,必须为1
( I- l3 {& i0 Y7 M9 \ WORD biBitCount// 每个像素所需的位数,必须是1(双色), * S) c1 s p8 I4 S. J4 e
// 4(16色),8(256色)或24(真彩色)之一 ) ], y) H; N3 v4 i- C; x* U
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
8 n, [+ Q, F; E8 ?: ^# b+ A // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
% H5 t3 B% }- N3 K; q# D DWORD biSizeImage; // 位图的大小,以字节为单位 4 t; o4 X* U$ M I( L! H
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
8 w+ E) a( W. F" ^& _ LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
n X# Z7 B ]: x0 U) D DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
6 O+ z& B C( m& b& r DWORD biClrImportant;// 位图显示过程中重要的颜色数
- t4 x$ L+ L+ A- \} BITMAPINFOHEADER; * K" k4 l, D! D* d' G3 w+ S! \
. ]* j( M3 R+ p. p3 N+ L
: f: R# r5 @0 z3 X$ I' v
---- 4. 颜色表 5 k7 k+ J/ g* J3 E- r$ W
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个
' Q( W" ]; r* o, k, u. kRGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: 8 R3 ?) J$ L+ y& F' _
4 h0 X2 Y: G2 E$ r- B
typedef struct tagRGBQUAD {
2 r( W, E7 T$ ?$ {1 T4 Q3 f" H7 YBYTErgbBlue;// 蓝色的亮度(值范围为0-255) ) v- \1 K8 _; i e
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
5 i# \6 K8 M" A3 @- _, z: nBYTErgbRed; // 红色的亮度(值范围为0-255)
8 a5 A" X% g5 L8 `3 VBYTErgbReserved;// 保留,必须为0 . _+ O& h6 n2 E
} RGBQUAD; $ Q& ^$ j: ?% {$ ^7 i% x
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
2 ?- x/ b1 y t5 c: Q- `! j0 f当biBitCount=1,4,8时,分别有2,16,256个表项;
8 S1 M/ ^7 W' g6 S, ~. J' b( b当biBitCount=24时,没有颜色表项。
8 B7 f5 m1 z- h7 z6 |- G 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 5 {: @. B+ B# d$ K- X; @1 h
typedef struct tagBITMAPINFO { * a8 l& C5 ]9 L: J5 h' s
BITMAPINFOHEADER bmiHeader; // 位图信息头 1 [0 u2 R8 n5 s4 B
RGBQUAD bmiColors[1]; // 颜色表 Y4 s1 n( Q2 F$ Q V/ O' O
} BITMAPINFO; % T: N3 S$ Q; y X
2 ^5 s+ q% r7 M5 Y2 c
6 n- u9 l( B7 O& b
3 d2 z+ t8 c: c( m+ O---- 5. 位图数据 @& H3 Q- o5 o/ r: p) {6 Q% m; d
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 # }0 ?/ D. g$ ^/ F. u# \
,扫描行之间是从下到上。位图的一个像素值所占的字节数:
% Y& |% M1 r6 h" H: M0 i' z8 g " Y! G/ i! ]# R( ]- d
当biBitCount=1时,8个像素占1个字节;
6 P" ~( g- {( @% a7 M' P% z当biBitCount=4时,2个像素占1个字节;
( V# D# p' S/ t/ J9 h( ^当biBitCount=8时,1个像素占1个字节; ( a! j& M$ q3 S9 ]$ x* E; W
当biBitCount=24时,1个像素占3个字节; 1 c6 t2 \( X+ y+ g
Windows规定一个扫描行所占的字节数必须是
+ H! Y6 i. O& K; h- e: q8 ?: I4的倍数(即以long为单位),不足的以0填充, , f5 F* U i, x( s. H9 E7 Z
一个扫描行所占的字节数计算方法:
+ [' l: @: V |! h2 {DataSizePerLine= (biWidth* biBitCount+31)/8; ( o6 }5 f4 H; t: r/ c, W( M
// 一个扫描行所占的字节数
4 p$ C# Q8 Q9 QDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
. v" y' j7 e" j& K- L0 R4 Q位图数据的大小(不压缩情况下): ) c% @! u; X2 }% J! R: ]
DataSize= DataSizePerLine* biHeight; ' W/ b8 g1 z. V2 q# o) \ V
2 L* g# }- f0 u' U ^
a% d; k; q8 G7 B* @( Y---- 二、BMP位图一般显示方法 ; Y) H/ J2 e+ m) E. P2 @
---- 1. 申请内存空间用于存放位图文件 9 U: j5 D( ^3 G' b' T5 K0 n& O: F4 j
, v9 M2 r- |& U/ y! A0 [3 ?6 q
---- GlobalAlloc(GHND,FileLength); - X: w4 _4 O" g. R/ V
+ Z0 q8 J- j2 i8 C# n---- 2. 位图文件读入所申请内存空间中
0 V% X5 v, s6 W4 s2 \+ y
" H: |7 X2 L |% Z* x8 {---- LoadFileToMemory( mpBitsSrc,mFileName);
0 z! p- Z3 y+ H! V
- B2 |2 y! C( ^& {6 N9 d, @---- 3. 在OnPaint等函数中用创建显示用位图
$ V0 W3 i- \8 r& I+ S8 c: g4 D + G( ?4 B* e; J0 l* i
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 # I& q" a" r5 X; o) \
DC, 7 f- Z8 B. d; z6 K& L
. c* O( @- p' ~4 f" ?) N
---- 用SelectBitmap()选择显示位图。 ; H) V2 U# @/ N2 b
$ {1 K5 T3 n$ f) W
---- 4. 用BitBlt或StretchBlt等函数显示位图 " Z; ?6 `# _* H- u
3 t- j2 s0 K+ E; p+ h---- 5. 用DeleteObject()删除所创建的位图
2 r6 Y' S' l/ O5 S
; N1 V/ h6 [# S* `( M6 s! U+ X/ z---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 7 K' R- Y: }2 q
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(
& i; J; B: C# O( D) K如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
0 }. S! s$ h x9 Q $ n/ O8 G5 \+ R
---- 三、BMP位图缩放显示
8 I* J3 T4 H, i( ^! x
! [- Z: z+ D* A/ g$ V---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
' j$ k) V& C% Q c6 O2 Z进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 2 z- }2 V9 b/ b, v3 Q; b
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: 0 @# V$ `5 o+ F# y1 i
$ M% T3 u. r; y2 T5 v& d+ \ S---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 ( E& T+ d: P0 |% b$ N1 Y7 d
# H0 z/ W: W; f8 W1 k7 {+ c" h8 r Y---- 2. 申请内存空间用于存放位图文件 5 _( ?2 I8 Z* O7 e4 G3 E4 ~
; Q$ B' Y+ q: c- C" t4 ]* l$ Q0 O
---- GlobalAlloc(GHND,FileLength); - }0 r' u. _5 V4 y
# d7 h, B$ c/ U8 B
---- 3. 位图文件读入所申请内存空间中 / ~6 X" c& E3 A6 b2 D
, J$ U8 }! n% T---- LoadFileToMemory( mpBitsSrc,mFileName); & K0 _4 j7 U& J6 m
+ `3 X: c; n/ f8 N; p6 m; |$ L6 q# t
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 - W5 f4 e2 Q/ _; p2 p" K
8 B% p& @7 B- M8 ?5 f! g
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中 $ ^5 b% G2 V4 y" e/ k, O
' d+ E) _8 ?% x' Q, I
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形 0 r# I" h% V) J4 w0 Q6 Z3 o
失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通 _+ M6 Z+ P2 F
过直接处理位图数据,可以制作简单动画。 2 B. i% O3 V% [2 J$ R5 r5 p; v
: I- [, S3 Z: z
---- 四、CViewBimap类编程要点 ( G) x' L3 F2 \: T) m; D
! B1 N& F5 @0 z' o) |
---- 1. 在CViewBimap类中添加视频函数等成员
* N& |5 a! e) C' j8 ~
2 w9 B; V8 n. y8 C, L# _HDRAWDIB m_hDrawDib; // 视频函数
; }. Q, E2 G4 V: X( X) QHANDLEmhBitsSrc; // 位图文件句柄(内存)
! S S: R% ~4 {3 [LPSTR mpBitsSrc; // 位图文件地址(内存)
1 |* S/ F# N) X5 yBITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
" ^3 Z" w8 Y* e9 K) Q! M) o& q
$ p' C% X5 q' u4 G
! ]2 W; R9 n' z---- 2. 在CViewBimap类构造函数中添加打开视频函数
2 [/ H% Z" ]4 {$ k; g3 N---- m_hDrawDib= DrawDibOpen(); 0 X4 s7 a' i4 h
W5 v# M4 z( s6 \5 q) i---- 3. 在CViewBimap类析构函数中添加关闭视频函数
3 G; g) n# y2 U5 X+ ^$ M8 h
3 R& l- T ?" \& z4 p% S* C; Uif( m_hDrawDib != NULL) ; e+ g2 ~: s8 a% E" R9 G
{
' i d" }9 D" V' }; D# v" u DrawDibClose( m_hDrawDib); ; l' a0 @3 q/ Q! {8 t
m_hDrawDib = NULL; + I8 W( o5 e5 s+ I6 {# y
}
. o3 X; [& [! Y q; S4 s
. X; N1 K3 t* s1 |$ b, P . N/ z. y e1 x/ \( P
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() 5 g4 w+ W' V0 J/ i; O; ^
voidCViewBitmap::OnPaint()
2 |/ y( w8 c, A6 p% J% V+ i2 c{
5 t: _1 w8 n1 z& f0 KCPaintDC dc(this); // device context for painting
' p+ q) B. o D2 U# v: D% ~GraphicDraw( );
. W, {& b2 C8 F" I% B2 V8 k# x' w& e}
! W$ J, P3 p! o& M. C4 H( f, D
0 a( ?" a, h# o% P( f. tvoidCViewBitmap::GraphicDraw( void ) 0 X3 V0 U- P6 z
{
Z i6 x5 s. f% W. Z# [. OCClientDC dc(this); // device context for painting
. O0 }3 N8 k1 w+ iBITMAPFILEHEADER *pBitmapFileHeader;
% u- w6 m1 s& |+ z2 g8 H O8 {ULONG bfoffBits= 0; 8 H( d6 Z' C n: E0 D! c
CPoint Wid;
! U" r/ v3 k" q2 W. U
+ f5 L: a, n- s// 图形文件名有效 (=0 BMP) 8 r9 n+ Z7 g5 U/ t y- u
if( mBitmapFileType < ID_BITMAP_BMP ) return;
9 ?& m. H+ ^$ ? z) j6 A4 J% l , Q/ f* t0 H, z1 D6 z
// 图形文件名有效 (=0 BMP)
0 n% O( d+ x. ~1 p/ d) B! M! J// 准备显示真彩位图
, p8 S u2 c) P) u, Y6 @, T1 `9 _& ?pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;
) x2 s4 y* ~4 p; ?; E6 DbfoffBits= pBitmapFileHeader->bfOffBits; 3 z. | t( D* S6 f5 H
+ g$ _6 h8 P5 d" Y% q2 r0 O// 使用普通函数显示位图 * P# p7 ^/ e, P8 G4 Q, I
: I3 f, c: q! r$ O/ y7 j8 A
if( m_hDrawDib == NULL || mDispMethod == 0) . C. V- z* O5 u/ A' X! I
{
% \6 i+ e% m4 b0 W2 ~2 v HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, 9 Z. b1 S- X3 Y4 a* [ E
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, 5 R& d& p* J1 N9 t4 g6 N
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);
: d% z; t+ U# ^) Y. B// 建立位图
8 s3 H. c% K2 J0 F: L& Z, e9 WHDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存 3 u5 m2 k3 i( s/ o4 `; n3 E
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象 0 H) J3 Z% B/ f* |: m4 `
// 成员CRect mDispR用于指示图形显示区域的大小.
/ n& u! C) }. C/ x4 u x! y// 成员CPoint mPos用于指示图形显示起始位置坐标.
" S! p8 \+ }7 V4 k% X! Xif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) H# {, v9 K/ q/ Y
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ; * E( Y0 Z- R; r( d( }
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
+ _, ?7 e/ N/ g- u" W |/ CmPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); r! r7 d1 `/ a
if( mPos.x < 0 ) mPos.x= 0; . j- E q( j4 p( @$ ~; x2 |/ l
if( mPos.y < 0 ) mPos.y= 0; , Y$ l# |4 H: G8 ~
5 h8 y+ a& l8 B) H( y if( mFullViewTog == 0)
, R# K H2 f& {8 E+ i) c{ / \2 W F' |4 {! @9 P! J
// 显示真彩位图
9 Z4 M0 Y& q2 B) p: {: A9 y::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
% j8 [! X, s0 u" VhMemDC,mPos.x,mPos.y, SRCCOPY); 0 P5 a, B1 A$ o
} else { ~7 ~8 o" F' P% [ ~4 W
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
6 r/ e( a; X+ ^( b+ thMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo- ( X% k5 s' S( W6 x% ?% b5 a* r
>biHeight, SRCCOPY); $ C* d* E( s& u
}
8 W/ g- q4 D% ?" k) c // 结束显示真彩位图
7 j8 }, r: b' j4 |) A# O: e; \ : eleteObject(SelectObject(hMemDC,hBitmapOld)); 6 z2 q# }4 v$ r' ^" ^# D& I
// 删 除 位 图
1 j' v d" i% _5 v. M7 h } else { 9 \9 j' B. [& ?# F8 \; s# j
: C# K& e6 b$ w2 [3 `! k // 使用视频函数显示位图 ) j. I0 {2 p2 A3 [
$ I/ a5 i& z* f" |) { if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) 6 h+ {. d- M, h
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
( ^. F4 b# V( R" }# n& ] O if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
& T2 O& f2 U$ ^% o& QmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
# |" x+ p6 Q9 @8 p if( mPos.x < 0 ) mPos.x= 0; & x# d% h+ T$ V
if( mPos.y < 0 ) mPos.y= 0;
+ f2 S7 @8 V( _
: z9 S$ E- r' B, Q' e. t$ h // 显示真彩位图
! r, l9 `/ c8 a DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); ! |( g6 ?! e) u) t
8 C D6 q ^& t
if( mFullViewTog == 0) ( x% I! B% k# l5 J. g
{ # N: D# b* ^% Y+ e
Wid.x= mDispR.Width();
, ]5 X. K8 z; m& W: |4 \Wid.y= mDispR.Height(); # q8 N( e. x" N
// 1:1 显示时, 不能大于图形大小
1 r! x/ A8 m' ]1 g. sif( Wid.x > mpBitmapInfo- >biWidth )
+ P) S9 I3 k+ g0 ^Wid.x = mpBitmapInfo- >biWidth;
( f- u! e) H# G# q* _7 Lif( Wid.y > mpBitmapInfo- >biHeight)
3 o) N; N- K" n5 I1 \5 V% rWid.y = mpBitmapInfo- >biHeight;
# i D4 g8 p6 |6 [0 w 4 m) e2 o. I3 G
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc() " Q. N M0 o, A/ E) j& E3 J7 u
, 0, 0, Wid.x, Wid.y, ! ^! x" @% Z6 R( U3 I0 M* M5 W- c
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), ( k' v1 r; G/ ~( k5 z% G( m- s
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); ; s. P' n2 _3 I( h0 `
} else {
i1 y) b& x. z9 l- u: uDrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
2 R0 T# T* \: ^0, 0, mDispR.Width(), mDispR.Height(),
! ?' U% x: ~! z8 S% V( ]% G6 U' smpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), - ^ }* I0 q5 @2 K& L# R
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
/ l9 |2 S6 D- {! ]# Z; U; u7 qDDF_BACKGROUNDPAL); 4 @: {; L, A B* Q: r8 z3 P
}
- m/ i; a* m) ]9 g: L# n } 3 e3 }5 U6 l' M
return;
0 J; f, j8 c6 w% \* Z) X} 0 h7 K! B' B% B
( I) y: }5 Z1 a+ v" p9 s5 o" W+ c7 f- x$ c & h3 J3 s2 t9 |6 Y7 k& o9 N$ G/ c/ T
---- 五、使用CViewBimap类显示BMP位图
2 G# u) K# d5 J0 c& l---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC
0 U0 r1 ~+ I6 l+ ~$ l; |# j. aAppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点 9 n6 R' ?0 V6 u g8 ?: }% L
击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目 5 s; W) W- h6 i
,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
( O; D" D3 x4 n; ]. V1 w" J尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 " |; f: m, Y- c/ i$ l% f2 g
: S3 _. x: E5 u! ?
---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
2 ?4 j+ F, U3 `, P- o$ t( }; ] H>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。 7 }! j( ~) j: P: s
/ b) e- M+ } g. h) K
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为 $ N! M \, v; V+ {. a
CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
6 O' z. H- q* f1 f) @. k1 ?/ W Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 # i4 z# C. G7 J
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码
t- i9 g X! H; J) N. ^. l。代码如下:
# r( X" q+ l; {1 F
' h$ X# x7 V( H' evoid CMainFrame::OnViewBitmap()
" u7 ^/ c5 o" G; S{ ; E% D! z1 a: _0 [& h1 f# @ _
// TOD Add your command handler code here # s5 U i* k0 l& _# ~
CViewBitmap *pViewBitmap= NULL;
: q; z, o5 e9 Z& Y
\/ y6 v/ d5 G- gpViewBitmap= new CViewBitmap( "BITMAP.BMP", this); % G4 m$ Q( R7 j# L5 H4 R& A
pViewBitmap- >ShowWindow( TRUE);
6 F3 k: l! Z' h1 u+ ^" J} 8 c+ S% r7 Z E, `, p
7 w8 Z& O( h% `
! p, l/ p& J# L---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 7 U* h' n# H- S$ f# l
---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
~, C `1 c$ z7 O, m 6 j% [% f: t6 x; `- p7 B# x) o
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- > $ G$ @3 v0 Y( q& x& Q
ViewBitmap)即可显示BITMAP.BMP位图。 ; x; W% o* W# D1 V. E8 J
# N" b8 r9 `* H
---- 六、CViewBimap类功能说明
0 H$ \6 [) \3 e2 q 6 } u% Q O( J' ?
---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可
. D! \ w% l: m: A以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 3 t! Q) U+ Y2 |* C1 P
* \6 ?2 g5 n9 K---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 5 K: \- t2 ^6 w* e
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标 " B8 a4 B4 S3 F# }. P1 \1 c
,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
9 P8 e& {& Y+ i# R d+ B; j7 E# l第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
, \1 b4 O0 i! W* k b小,则对位图放大; 如果位图比客户区大,则对位图缩小。 * @; r. ^* E: @# d& }4 M( Z1 y* k- ^& H
; a9 }4 m; x Z5 |" Z- a
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, - k2 g( `5 z- X9 t3 d5 E
就可以显示该位图。 ( q2 w7 k; D2 }) R( O7 |, v
' [; N! w! q+ I9 E" U
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
& s. W5 J+ s5 d; N5 X
: D+ t$ h! z$ C# Y. C0 V) ~* j在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图 " ]' a0 s0 }" B& `* j' {
放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失 9 ~ _2 `1 q. p' I' T, H
真小,显示速度快。 % S, p& ]/ A" N6 v% Q
1 @- i5 P* y H$ r
---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 1 W$ w/ _' v L7 D3 d0 ]7 J
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可
6 l, W8 f# L8 e/ p以体会到使用视频函数的优越性了吧。 ' e( b! O. f5 l0 s: ?" Z5 A& e1 A+ @
" C; l/ ?; {, G" f
---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
9 c- `1 n; @* j( H/ ?程序中加以适当调整即可,读者可自行完成。 |