|
) P: Y) b6 N7 c5 n5 J7 b. V3 `
西安交通大学流体机械研究所 8 r, A# A' u! O2 ^- `9 S, g( Q4 w& u
张义云 # T4 E7 G0 P2 n2 p5 u# I! \5 A
4 Y. Q5 o& N1 M* ~0 u& W( l---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重, / K r" A; }& W, B, r
在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数 . A' j4 t6 m4 B+ Z1 c" N
显示BMP位图,可以消除以上的缺点。
+ u, j$ t+ n( D- ]6 r
. a3 p9 f% F1 ^' `6 R---- 一、BMP文件结构 ' ~6 ~" _0 I+ L0 }& c
T9 Q" O0 ~$ I5 Y) v% O+ C4 A---- 1. BMP文件组成
0 s- ?" @* B& ?& P5 j
/ l7 W% R3 w4 g! p) v---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 3 i0 A9 \# L( M( d
8 l; x! x% Z8 \5 U- Y: b
---- 2. BMP文件头
$ ]/ T s. S3 Z8 t' N U( j4 }, b $ j' P' L- V* ^( K. V3 N9 o
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息 / M7 n/ r( \+ \
。 8 p' d A+ k( D: u. f( J# O- O
4 B2 t( X3 U3 R8 h: F
---- 其结构定义如下: ! f4 j9 C* c/ J% Y4 e9 E' T
% |# T; _4 C L+ c5 P- ntypedef struct tagBITMAPFILEHEADER
" |, I7 T1 d( k- K9 k- W% } _4 n{ 8 v2 u: u& Z5 ?3 L9 W! H) |
WORDbfType; // 位图文件的类型,必须为BM 8 F6 Y; X9 s* [6 r8 H& l
DWORD bfSize; // 位图文件的大小,以字节为单位 ' U+ K: A4 w" ?- m/ H& f
WORDbfReserved1; // 位图文件保留字,必须为0
9 g; u: ?5 R* H7 BWORDbfReserved2; // 位图文件保留字,必须为0 , G$ ~# P+ m" [% x7 }8 K9 y* N
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
3 X5 z) p) d6 E0 I// 文件头的偏移量表示,以字节为单位 $ f6 s9 |$ S$ v+ \! G2 q
} BITMAPFILEHEADER;
& j/ s3 x# U& _5 j 0 D+ Q7 a; T1 @) i" D
2 B; ]4 V1 ]+ K. c$ a
---- 3. 位图信息头
' p. O1 ^) I( W5 M" ~1 f. ~7 r2 ~---- " U+ g/ E; Q) X/ H+ u
^' O( C( E1 Q3 G% q$ S, T! d
BMP位图信息头数据用于说明位图的尺寸等信息。 * c' s4 Z& u7 w
typedef struct tagBITMAPINFOHEADER{
3 B& v6 \0 x; Q DWORD biSize; // 本结构所占用字节数 2 ?/ O+ z0 H" v- C$ ]0 C
LONGbiWidth; // 位图的宽度,以像素为单位 8 N9 y( k3 u" b) b! L1 a# ?
LONGbiHeight; // 位图的高度,以像素为单位 ' s: N6 s. `! w6 w2 `
WORD biPlanes; // 目标设备的级别,必须为1 * j! c Z" f8 g% G
WORD biBitCount// 每个像素所需的位数,必须是1(双色),
5 P. D B: ^4 P; O/ {# G1 |! {# S // 4(16色),8(256色)或24(真彩色)之一 / s* A) l2 S$ F/ R9 O; p
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
2 j: K6 y8 V) T9 t) O // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 8 b" g2 |. W% l) Z4 ~. B
DWORD biSizeImage; // 位图的大小,以字节为单位 3 F) N. j% t8 l
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
- F, y' Y& h2 A: b: U0 j LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数 # K& |5 z% W7 h9 q; u- f
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 - u* l. o4 g3 {* r/ k# v) |
DWORD biClrImportant;// 位图显示过程中重要的颜色数
5 [- a0 }3 {' F0 ~% G5 R$ M7 \6 H} BITMAPINFOHEADER; $ h8 ]+ O! g" I! ?% Y/ }
, ~1 q+ \' B$ s' K" g+ p3 J
' D$ D4 J- ^, V. V
---- 4. 颜色表 * j: j; _. d- L& R. g
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 " E3 t; P4 Y! k9 _
RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
( s% u% g% i' q$ c 4 u8 b' c& x4 F8 }+ s
typedef struct tagRGBQUAD { # @3 o" S$ d! q: n2 j
BYTErgbBlue;// 蓝色的亮度(值范围为0-255) 5 q( p6 h+ ]4 B$ S* A# l: M. x, ~
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
7 m. p% ?7 Z" `+ o, KBYTErgbRed; // 红色的亮度(值范围为0-255)
: j! r9 V5 Z" p5 b3 Z! FBYTErgbReserved;// 保留,必须为0 / w+ r) k+ m2 ?! E) f, r4 O
} RGBQUAD;
3 B3 m' g: J, Z, z; d- @颜色表中RGBQUAD结构数据的个数有biBitCount来确定: : b! V/ Y* K1 i4 g m
当biBitCount=1,4,8时,分别有2,16,256个表项; ) ^# l5 _# ~ o7 f1 V6 F
当biBitCount=24时,没有颜色表项。 7 v) S2 b" _9 ^' Y0 V
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
, j, I9 S: g p c8 {typedef struct tagBITMAPINFO { . y! G2 H# U. F
BITMAPINFOHEADER bmiHeader; // 位图信息头 7 k3 p& T3 x; r b: P- N! Z* }+ ]
RGBQUAD bmiColors[1]; // 颜色表
, x. n% x, n9 r! g1 X7 f3 [} BITMAPINFO; 4 ~; C6 n/ M9 ~9 J* a% a. M; Y
* ~$ I! r0 h- T
8 L2 {, r: }0 U( M) _/ e) T
8 T) \" C5 X! h---- 5. 位图数据
4 ?8 L% W; V" M$ E---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 8 H6 C8 S7 O# V
,扫描行之间是从下到上。位图的一个像素值所占的字节数:
U: w0 r9 V L4 X6 k9 z/ Q7 ~
# R: N- d0 w; [/ H当biBitCount=1时,8个像素占1个字节; 8 }' N+ y+ @. i" Z+ _1 E6 J* z
当biBitCount=4时,2个像素占1个字节;
- O) y) K; r8 ~9 E当biBitCount=8时,1个像素占1个字节; 3 F% ^: j( F `# q
当biBitCount=24时,1个像素占3个字节;
8 g7 ~* l7 d/ F) ]; H" kWindows规定一个扫描行所占的字节数必须是
, J! U, S* D+ _; l, M9 ~4的倍数(即以long为单位),不足的以0填充, 9 ` {3 o" ^7 P2 @" p# d4 x H
一个扫描行所占的字节数计算方法:
! x: }, L2 y! S0 j) [DataSizePerLine= (biWidth* biBitCount+31)/8; , ?. l% [6 b) u! [
// 一个扫描行所占的字节数
2 w; A( C3 ?. r6 H5 j, q/ NDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 0 q# k4 {2 q0 C# P
位图数据的大小(不压缩情况下): 2 J: u: ]: `& M
DataSize= DataSizePerLine* biHeight;
( ]- ~! o; H! B- l/ J& W
& h4 _) f$ D+ o: U) \1 B+ E
5 Q) U0 Z m0 i& R; @) R- R' W---- 二、BMP位图一般显示方法 : l- L; G9 R+ X: F) p6 g9 d3 m( i
---- 1. 申请内存空间用于存放位图文件
: M/ d" E- t4 `* q U j' v' Q3 J
& U) R- N9 k/ _% y- B* |---- GlobalAlloc(GHND,FileLength);
' A1 N6 ?4 B7 @) ~( d
( C3 G! J9 l0 |( c3 K---- 2. 位图文件读入所申请内存空间中 ' C5 g7 w/ c; i, u/ s
% J0 T! _" y: M, y! B---- LoadFileToMemory( mpBitsSrc,mFileName); # i6 l- Z1 O2 Y+ j3 H9 v; ]* B
$ \1 M/ d1 [: I& D9 ]$ X2 r& o! U( E$ j---- 3. 在OnPaint等函数中用创建显示用位图
. W! q+ _4 I7 h& V. U - B7 }* Q x+ Y7 U! o, u
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 # _( l) }0 L. `5 h
DC, 9 Y& \0 |% t, |: j/ ?# K1 u
) T- j4 j1 ]- d0 }
---- 用SelectBitmap()选择显示位图。 ! T8 H( M0 A8 G* @2 h
+ K: H; C( ^ E& u5 z m
---- 4. 用BitBlt或StretchBlt等函数显示位图
+ W3 J& j! T/ @* c
R/ ]" {5 s' Q8 u: z# t---- 5. 用DeleteObject()删除所创建的位图
4 s* l, P' z9 k' S0 g6 p 0 G8 O- k% i/ T% J3 g) L
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 6 x4 Y5 r4 j, e+ V! d
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上( $ y7 ?$ t) o, f- ~* w" q
如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。 " K/ ^/ `$ w8 ^' v9 K0 k" x
( [* `" e3 b3 t3 `6 r% b
---- 三、BMP位图缩放显示 " q0 c: Y, a8 [ m! o
; p- d6 i6 c/ F' z3 p, i9 I1 G
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
" g! c/ f4 B( Y1 t, P进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 ! g+ N2 N! M' Q |: r
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: 7 c9 j% w' F! K
X, o0 i n1 Q2 t- W---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
: h* U: L; n1 U' C) M) i6 j6 R ! V1 G! z5 [& x' ]
---- 2. 申请内存空间用于存放位图文件 , M, k- V8 u" j, ~" s* ~$ ?
R( f: B0 Y$ Q( U( P4 b---- GlobalAlloc(GHND,FileLength); 0 x, ^3 @. R7 q W% q5 N
) l* X# h5 S) E
---- 3. 位图文件读入所申请内存空间中 * X4 v. s- E& D- q, w
% w/ H2 G9 Q! P3 q) S$ ?+ o
---- LoadFileToMemory( mpBitsSrc,mFileName); 5 o; a- \: n# q& v
. F+ X# k, w; d3 w
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图
# }, g+ C: {3 `. Z. I & q: I" h, O; ~; J
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
L! ]* y* c* v7 @ % U2 p, g7 A7 e" t
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形 3 l3 a0 n l" e6 I; ^6 a
失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通
* B; x; _' k2 T过直接处理位图数据,可以制作简单动画。
' o+ P" l' {" m
- Q7 R) n; L3 K( a, M& G---- 四、CViewBimap类编程要点
* O: s0 r/ M" D* L z7 Y8 D ' P) h1 ]& k( |% @' E; u: k
---- 1. 在CViewBimap类中添加视频函数等成员 ( X) z% V, k0 `% H) D
4 {1 N: P/ d5 N* J" sHDRAWDIB m_hDrawDib; // 视频函数
- X0 H3 w5 D b' k/ WHANDLEmhBitsSrc; // 位图文件句柄(内存) , r$ g- s) `/ M' p% a2 ]
LPSTR mpBitsSrc; // 位图文件地址(内存)
/ j. e6 g4 U( MBITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
( W2 P% N% S& U& U8 R7 G8 }
$ n& Q" m$ w# X/ c4 s- v/ i Y# O0 \" ?9 E( N" _ k6 |, r( ~
---- 2. 在CViewBimap类构造函数中添加打开视频函数 : r& K9 z8 d* u8 X6 H
---- m_hDrawDib= DrawDibOpen(); 5 Q% x. \. ?% q2 }0 K
3 {0 Q6 P1 H3 c# G" A2 H---- 3. 在CViewBimap类析构函数中添加关闭视频函数
8 \0 A ~! Y9 f; v$ B- I9 f8 A 1 g, B& C4 Y1 H/ t8 @0 R5 Y! p
if( m_hDrawDib != NULL)
/ t5 Y) B+ P/ }6 ]& E {
" t+ c1 k6 i* d$ | DrawDibClose( m_hDrawDib); ' C! d( I9 w( f7 E
m_hDrawDib = NULL;
' l" R7 h! w5 s7 E h3 b6 i1 ~, _ }
! G( n/ ^3 T B# c" d 2 ]% s' H- {6 r) b' p4 {& C7 M0 _
1 g# z P4 e- Z8 q, y
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw()
$ n& y4 y. h* }voidCViewBitmap::OnPaint()
- m8 o0 ` g R2 I6 b4 o( [{
7 d, v! X q! T9 d p- B. g$ Q& E4 tCPaintDC dc(this); // device context for painting
& T& H f! \( O( VGraphicDraw( ); * R0 w% G0 s8 L' }% e# c
}
( I5 S& A' e$ b5 v
E) {8 x x/ F& ~$ vvoidCViewBitmap::GraphicDraw( void ) 1 i8 p9 u5 h) Q4 k" W( I# X$ v
{
6 D6 h5 H$ ^' ?) }- mCClientDC dc(this); // device context for painting & f. e" X4 {3 @( w g8 q- J
BITMAPFILEHEADER *pBitmapFileHeader;
% O" h/ u6 J% H4 \- ~+ g$ yULONG bfoffBits= 0;
* M9 K$ q$ F1 ]0 }6 RCPoint Wid; . t$ U6 i/ v2 }8 s9 P$ l
; J$ R$ _. I( @. }
// 图形文件名有效 (=0 BMP)
% n. C" Z; \( c' ~if( mBitmapFileType < ID_BITMAP_BMP ) return;
: m) L) u& ` J3 y2 ? 4 Y5 E( s! m4 c, ]: ?. m2 K
// 图形文件名有效 (=0 BMP)
9 d7 c9 a3 `+ ^- ^, ]3 H0 Q5 Q// 准备显示真彩位图
. R9 ~" E7 M: v1 i: ~4 h6 I qpBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; % C4 X: ^/ J; C- t
bfoffBits= pBitmapFileHeader->bfOffBits; $ _( A! f, _# D- e7 @! r) Z- G
1 K6 z" l: D: P9 G' R3 p// 使用普通函数显示位图 / D' h& E% G. q1 G1 G5 d
0 Z3 v9 r1 ~4 _+ \
if( m_hDrawDib == NULL || mDispMethod == 0) " E' p- d8 c+ T) f, Q; v
{ 1 W' ]3 x: ^+ ?
HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, ( H2 }: G1 K2 a
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
+ n& G0 L+ ?, A) |/ L) X. M; x (LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);
) H8 P, M' z( r9 L+ \// 建立位图 $ u5 N- R) D- @7 j0 j
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
& A5 {5 r. A. }1 u4 Z5 W* C; O7 n7 sHBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象 & b+ N0 u" m* Z0 b4 b# j
// 成员CRect mDispR用于指示图形显示区域的大小.
0 g1 O( {% }- j" N// 成员CPoint mPos用于指示图形显示起始位置坐标.
) Z1 A3 K2 b, I. [, D+ Hif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) ; l* T9 w' w$ O% ?! F4 P3 q) e
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
8 {/ o+ m/ y# @; T5 }: J( H* T if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
+ N1 Q) v" K6 @3 O. UmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
/ H; k5 V& m2 `! x/ ] if( mPos.x < 0 ) mPos.x= 0;
9 e3 v" Q2 o8 f: Y% y if( mPos.y < 0 ) mPos.y= 0;
* l1 {& u* I; l3 w
% b( ?) @9 U: ^" z if( mFullViewTog == 0)
2 M6 g6 T( |& }0 ^" u3 Q0 O{
! C8 W/ t$ t) {8 ^# ~# q// 显示真彩位图
# F" M: N/ v+ G# G3 a::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), + s+ d) T, [/ R2 g1 a1 y3 [5 y$ B& b0 r
hMemDC,mPos.x,mPos.y, SRCCOPY); 6 f* M2 e! ~* @( n9 y% g: z
} else {
$ O7 c- B# N& D4 P::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), + v/ R* Y2 `0 Y8 i
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
: x9 z2 B$ `6 x* W. L. R>biHeight, SRCCOPY); ! |4 d; L0 j% }* B/ N
} + V6 p: @$ _- \! H. \
// 结束显示真彩位图
6 t* j6 `: ~" V/ D! j/ [ : eleteObject(SelectObject(hMemDC,hBitmapOld)); 8 c( C1 `6 s- z2 \5 ?9 E; P! g
// 删 除 位 图 1 k/ J9 K$ b: q- |% T# R2 l# z
} else { - I% a7 U" d; }4 k
+ b* t' T0 q2 A( T2 k" V8 |
// 使用视频函数显示位图
; l7 `( f, D& f* ?5 a3 ^- \
1 C; i8 f" P: Q s, J, ? r# f/ a) ~" H if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
3 E) u6 A# \0 t5 f% ~mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ; 2 b# k& O0 V: N! i" q0 i
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
( d6 q7 m- s+ c. F' P# \mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
, l: w- m! |7 z8 C if( mPos.x < 0 ) mPos.x= 0; # h4 D% a+ }' e, K) X5 E" V% M
if( mPos.y < 0 ) mPos.y= 0; 2 `9 P& E* n- @2 h
; }1 W0 M/ \: c* W
// 显示真彩位图
6 G- r9 K# `8 I1 x* H; ~0 m DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);
) E& G9 L$ Z4 b d& X& e% v* K
. c; Q" {4 }4 k+ T if( mFullViewTog == 0) & r/ E: G3 P6 n! _- f5 @
{ 8 a! m2 M% }6 i1 n1 p! [( _
Wid.x= mDispR.Width(); 0 Q* C; v5 v- S/ o% o4 q
Wid.y= mDispR.Height(); % \- T7 m; I3 f+ {! V+ I$ I
// 1:1 显示时, 不能大于图形大小
5 k4 f' r9 `; `* j% ?+ |if( Wid.x > mpBitmapInfo- >biWidth )
; O) E$ D! [ p. PWid.x = mpBitmapInfo- >biWidth; 0 a# L: t- B i$ N! q8 ^
if( Wid.y > mpBitmapInfo- >biHeight) + d; h' p: H ^. I- o
Wid.y = mpBitmapInfo- >biHeight; ) A$ b( t" R) v* T0 R
" g$ J* c/ h. P
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc() 3 X# V7 a! ^4 J
, 0, 0, Wid.x, Wid.y, # Y3 _% a( P, g5 v0 R# Z" E% Z
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
: m1 _* G) `+ C1 BmPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); 1 e2 p5 o% `) }9 N% `
} else { $ z n6 k" K& u1 c- l
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
6 d/ h4 C- u% y* u0, 0, mDispR.Width(), mDispR.Height(), 7 i, b; G t- {5 f* Y; p/ }
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), / t7 u3 u4 u; y( n2 e; I
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight, 6 p) R9 @; |& }; X! ]
DDF_BACKGROUNDPAL); # J; H2 D7 U' K4 M# z* n% u
} # Y3 i h" s s: X/ j$ Z; R
} 0 |2 |+ [( p4 t& i4 }/ U
return; 6 }( [. U) z1 ^8 O& m/ t$ r- ~4 }
} / B* Q& X1 R1 L. u& E
: a7 z7 z7 L2 ]. A: n/ z# a
7 _3 r1 @+ A) R/ c3 R7 w4 L---- 五、使用CViewBimap类显示BMP位图 $ f) s' J6 s, X4 P0 m" i( G' m
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC * g% w |% V+ k! b. e
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点 . j3 B6 D, n5 x0 d! X/ J( ^
击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
; k% r# g5 ]: ]# d$ S,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
% n' F$ k G; P0 o( d$ J% O' _尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。
" [. e. V I7 i6 X9 d
/ u( N1 e D/ D0 Q. ?( y3 s7 F---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
$ ]0 p z, C1 H y>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。
( I4 [( H* ~5 P; ?, |1 v 3 [# f/ U. s( v+ |* x" X
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
7 c( G' ?& k- d" K0 yCMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add * g4 U8 W6 w/ ^) o1 F9 Y# e3 b
Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 6 g5 W+ D# ^) x+ `) x
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码
4 f& m5 z1 Y4 d7 f8 E。代码如下: * H9 v2 w: \2 h2 U2 b# f" b8 ?
& I$ d* t& S% {" ^4 `' F; i
void CMainFrame::OnViewBitmap()
" Q. I/ h7 j: Z& L. C7 X{ : w% K! } W3 n) T7 L) Q7 M5 `/ ^
// TOD Add your command handler code here
+ G9 q% i+ M- e+ H6 NCViewBitmap *pViewBitmap= NULL; 9 {% G3 X! ~8 ?; L. R& z: _
! B9 m& P8 L2 f+ b2 N7 C
pViewBitmap= new CViewBitmap( "BITMAP.BMP", this);
5 n; }; j& r$ l R; s' t. P: rpViewBitmap- >ShowWindow( TRUE); % q# m d! b$ b1 y4 J* F0 s
}
0 K/ s" i2 _* R6 d3 z3 m1 j- I # h" J0 N# C+ A& I& J
! ^0 W6 z( o% t9 a o---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 ?: X4 ?& q& ]4 H0 p5 y- x! @
---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。 6 Y8 D/ ?2 d) _/ m- g
6 P& O. E( z+ W
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- > 2 O& c. J2 m5 `$ _% N4 d
ViewBitmap)即可显示BITMAP.BMP位图。
5 ]& ?& C" ]/ B, s% V2 f3 k5 ~' G ' f1 ~8 C. X: ?0 D
---- 六、CViewBimap类功能说明 $ A4 \5 ?$ C+ i- ]7 j
0 k0 t3 N/ D8 @, y, A" \8 y9 p2 U---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可
* h8 }! ]: i H9 Q) Y以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 W* U8 Q t8 y: o# o
8 S4 T9 v1 Y+ ?7 J& S---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 . |& B* { F( w. f3 o0 k5 I
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
; s9 R+ i! l8 },可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
: G) V4 ~; h! _' A8 U第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
: v+ f& F- @# H小,则对位图放大; 如果位图比客户区大,则对位图缩小。 ) |/ I4 R {# Y% F8 G
: U0 k7 Y8 v1 V+ m- b& X---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,
- n- s" y# K, d8 }6 |就可以显示该位图。 ! @0 J' E( s; r% k& i: o( `
+ L0 G# f$ j" z+ n8 x
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小, ' C& ]! ^& |; }' d+ E1 o
. F: F! b) ~3 A% p
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图
* e& c0 U; `) N5 K' r, I放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失
2 Q& I3 O( G8 y( t4 h: S% I真小,显示速度快。 " I8 `9 ?) b) }0 W$ N, W) b' P
2 v3 P9 _+ S, }/ D. e( t
---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模
: [* Z6 z$ t& [- I6 M式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可
0 @, E% F1 ]3 r' i以体会到使用视频函数的优越性了吧。
5 V. f7 ~7 B2 ?4 a
1 N0 l! ^1 p1 ~" s& p---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
9 R/ d5 E. A/ {2 b3 ~$ q程序中加以适当调整即可,读者可自行完成。 |