|
8 P1 }, O! m" `西安交通大学流体机械研究所 : I9 y5 P+ U" |* X
张义云 0 B. g$ m. m: z& C8 S) L4 {: ]
+ F+ Z; G8 @+ S" K/ D2 Q---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
" [8 h. z( s e6 w- R( e在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数
6 i# i6 ?! c& S/ b2 |, {: ]显示BMP位图,可以消除以上的缺点。 $ U* k7 q4 a: ~( b% _& b0 U' s
, [0 ^3 v$ D- v2 S
---- 一、BMP文件结构 * K! }9 N! H" `! W
" H8 ?. k, d: N, \" }( Z1 d$ P# S---- 1. BMP文件组成 % C$ x9 X6 ^ \9 H( o6 d. J
; E% T, ~& `$ r' ]* n _. N# B7 R) x$ ]
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
6 q- k8 ?9 f* ?+ P' V4 I . P# O/ Z/ n2 P
---- 2. BMP文件头
& L! B' ^1 a! k/ ~7 E * y% C# S* W% W/ S
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
4 L, g E; @9 h8 Z。 0 c" ~) }. m# v7 M5 N0 T* f
9 a q% k* F4 K+ M---- 其结构定义如下:
4 w5 m% @6 P7 `& E) a- m$ B , w u* V; x: O% k$ r |
typedef struct tagBITMAPFILEHEADER
! Y: _) Q; L' i# T' ?" i1 j{
) c8 ?5 U6 U- f1 E3 s5 m4 XWORDbfType; // 位图文件的类型,必须为BM 2 n$ Y# J* C8 o' S; Q( A
DWORD bfSize; // 位图文件的大小,以字节为单位 0 \( W, u! w- P& E* g/ Y1 N
WORDbfReserved1; // 位图文件保留字,必须为0
$ c2 X j! d& R3 `6 X+ nWORDbfReserved2; // 位图文件保留字,必须为0 / d% P9 o0 E. p# W% d) n8 l2 j# Q
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
5 I V8 M( x1 o// 文件头的偏移量表示,以字节为单位 1 O) ]) {- y# N5 K
} BITMAPFILEHEADER; " t, K- G- t: E! f$ ]
: s4 m7 d3 b2 i/ d; _0 ?6 s+ u" |
9 u+ R% D5 }, u7 p+ o0 ]2 i- H---- 3. 位图信息头
$ U- E) J1 A7 \/ E---- * I5 D3 T. Y: t) C# O& k1 Q
9 C, o5 E: U0 w' A9 B5 aBMP位图信息头数据用于说明位图的尺寸等信息。
& S+ M8 ~" U1 D5 |0 E" S& Jtypedef struct tagBITMAPINFOHEADER{
9 H4 i) R- ^& Y; g# w+ N3 L! [ DWORD biSize; // 本结构所占用字节数 d' `1 y) T; n/ O r- \
LONGbiWidth; // 位图的宽度,以像素为单位
) B- o% a+ Z* M N LONGbiHeight; // 位图的高度,以像素为单位 ' ?, k+ H0 S. x: c
WORD biPlanes; // 目标设备的级别,必须为1 9 r) B+ r' a- J$ ^, U6 Y3 m
WORD biBitCount// 每个像素所需的位数,必须是1(双色), 3 v! K% q s3 Y; x$ B
// 4(16色),8(256色)或24(真彩色)之一
9 a7 d, h" Q G9 Z- f1 @& Y+ h3 i6 @ DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
6 {( {- ~3 W% j; b2 D // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 - w) b/ W6 i3 G7 }$ I. [# F
DWORD biSizeImage; // 位图的大小,以字节为单位 E% |' q, D1 F. I' {
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
6 Z) q! T7 Y5 X6 S' F LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数 & i' _5 `4 s! G8 {; {# G
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 & F, Q; k. [: P8 g8 \. I ~- W
DWORD biClrImportant;// 位图显示过程中重要的颜色数 " ?( ^, X+ X. p s8 a
} BITMAPINFOHEADER; 3 ~/ g3 a7 f' N
8 i! U' y p C( e( W F 8 ?8 V" Z7 i9 q$ q7 e" {- `3 o* y
---- 4. 颜色表 * C {8 g4 K9 c5 @% g3 Y
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 9 h+ [4 z, v$ U7 F, A" \
RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
: H1 H" V1 ~ u( o
. m! w9 s! x0 qtypedef struct tagRGBQUAD {
c4 R5 V, a7 s4 v" r7 B/ `. {BYTErgbBlue;// 蓝色的亮度(值范围为0-255) P' s1 {$ _2 q8 s. C+ _
BYTErgbGreen; // 绿色的亮度(值范围为0-255) 9 V- B" M. K# b$ e& f5 `$ k
BYTErgbRed; // 红色的亮度(值范围为0-255) 5 o; v: R4 p# `% g
BYTErgbReserved;// 保留,必须为0
& H4 j$ Y4 }, }; |} RGBQUAD;
0 c1 N& k1 {0 f: J9 D9 l( I颜色表中RGBQUAD结构数据的个数有biBitCount来确定: ! ~/ c. e+ c0 W- C3 ]- H. q; T
当biBitCount=1,4,8时,分别有2,16,256个表项; 1 w$ m, D1 v' j( a' T/ K/ p8 p( w3 m
当biBitCount=24时,没有颜色表项。
) L; Q4 |' f0 Y7 m 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 9 s4 \0 H6 M- u1 K' V5 s+ @2 @
typedef struct tagBITMAPINFO { ' N$ v% ~1 v! s/ h( M' J# P2 L
BITMAPINFOHEADER bmiHeader; // 位图信息头 0 w. t1 j! G, T7 G
RGBQUAD bmiColors[1]; // 颜色表
2 a( [- u- H: y6 j% [ k2 P: V# g} BITMAPINFO; ) r* o9 ~! T& b5 ?& [+ F
+ o% x- P" G K- G5 A
, j2 |' A! H( Z/ S& r& d8 f
3 ~4 v- }% H; P: W. G- ~---- 5. 位图数据
) O F) @# A4 o---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 ' ~6 ^, X }& E" a
,扫描行之间是从下到上。位图的一个像素值所占的字节数:
% n' ~: r9 f$ G8 W# g
) J, t: m( N6 }5 s% o* d当biBitCount=1时,8个像素占1个字节; . R8 i( Y+ b. ~. T. j- N+ h
当biBitCount=4时,2个像素占1个字节;
- S3 n2 `" o( A7 {% _% w当biBitCount=8时,1个像素占1个字节; + V% j) ~% y4 }) u' ^) S3 l# E# |
当biBitCount=24时,1个像素占3个字节;
4 p9 a8 o( Y8 ~+ O* U) z. AWindows规定一个扫描行所占的字节数必须是 " x. D7 C' r$ e& L% _
4的倍数(即以long为单位),不足的以0填充,
3 s5 t( f1 G0 A; D% Q/ o一个扫描行所占的字节数计算方法: 2 E- V+ o2 ~* E4 ?
DataSizePerLine= (biWidth* biBitCount+31)/8; ) b3 x8 w( F; L' A6 H
// 一个扫描行所占的字节数
6 s# Z G. W% U- C' V3 BDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
& P/ A" w" H$ a' m* s位图数据的大小(不压缩情况下): 3 R# `# l/ |4 u) v# h5 C: p
DataSize= DataSizePerLine* biHeight; 2 p/ A+ |* }/ I/ i e
( W) D& f$ ^: k! {, @+ O' E. i. e
) I$ H0 |3 a* a2 Y/ i! i9 ]---- 二、BMP位图一般显示方法
( Q6 b$ N8 i9 g3 y0 ^# i1 a---- 1. 申请内存空间用于存放位图文件 . F6 q1 r( z/ i K: I" z% G g4 X
r- o, p9 f$ t* U @ Y
---- GlobalAlloc(GHND,FileLength);
" K2 x) ~! ^7 Y! I* _
- Q, I" S6 }, Y5 O. v---- 2. 位图文件读入所申请内存空间中 3 \% x( v( B% p1 o& l. \1 a
' ~* V" O/ G" W8 {% G6 ~' c
---- LoadFileToMemory( mpBitsSrc,mFileName);
0 u' J, M/ W1 O" {/ B" t
; n; O6 ^7 }" Q) x7 F' d, `---- 3. 在OnPaint等函数中用创建显示用位图
6 ]+ D4 e. @; d/ I6 U2 E $ I" C( s3 y: ~, q
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 " A& p* D/ Q J: a9 e
DC, % g- Q5 |/ v5 ^* l8 p1 S/ k5 g9 p7 l* ]
5 v* H1 {2 r$ Z( N x7 N- c
---- 用SelectBitmap()选择显示位图。
* W9 P d9 ]* P8 V$ q & N6 D7 R0 z0 z! C7 D. I' u. ] Y
---- 4. 用BitBlt或StretchBlt等函数显示位图
. C3 t2 H' F I5 d0 h& ~& c
7 u5 n! y, F' r+ K% k---- 5. 用DeleteObject()删除所创建的位图 , \9 e* N% _4 B: V* x. e8 w
6 B+ v9 `8 ^+ K, h% |1 f: h/ m
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 0 h" R; a: x: X* J* C/ o2 \
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(
[3 R+ Z2 ]) U5 I% `( A如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
* g2 @& ~4 T. Z q ( n9 U- R" d. q- V
---- 三、BMP位图缩放显示
2 n5 B- e/ \: P L5 s# r& p `& V: [, x/ E
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
+ q3 z" g/ }1 O/ |1 z( K" I0 U, i进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比
# Q# f/ ~% Z* L3 N7 d& }6 X) C图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: : ]* |5 @! _" F' e. N
: `9 t% U b6 D, r8 f' u& H% O---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
0 N9 S3 L/ x% T# L/ I
# ]. i+ o% _% h! z---- 2. 申请内存空间用于存放位图文件 5 `& Z' A: Y. r7 G3 k9 y* B4 {
& r @8 s) `" X" S4 r
---- GlobalAlloc(GHND,FileLength);
X1 C% R" s" o7 U: z $ P* s3 ]( F8 K M5 a
---- 3. 位图文件读入所申请内存空间中 + d2 ?# D& n: o3 p. F
! k& k" w1 u) V- R! N4 F% N" w3 P
---- LoadFileToMemory( mpBitsSrc,mFileName); 5 Y B# Z8 C: R. @- ^9 W! x0 N
) S; B8 J6 V( `# n. K$ i" j
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 6 `# ^' z3 k5 T1 Z6 k1 R3 f# G
- e0 {5 D! z& |, a% @! h
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
( y; y2 V; y- c) {9 H ' W- e7 R5 W1 e, a' P- ?5 v9 |4 M; u
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形
8 c# b/ D1 U& T9 z2 T失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通
2 ^0 i, h8 {7 c4 ]* |过直接处理位图数据,可以制作简单动画。 . p# C3 Z9 k, q8 k$ z# W. g1 V
4 y$ a+ P! R: p8 @% [---- 四、CViewBimap类编程要点
; Y7 K p/ m8 q/ o ) ~, w, q" f0 [, A
---- 1. 在CViewBimap类中添加视频函数等成员
- Z3 I- P. q# F' d( p" r* ^ * @! K# l1 R' d
HDRAWDIB m_hDrawDib; // 视频函数 6 ], t* s3 K5 o+ @( h. }
HANDLEmhBitsSrc; // 位图文件句柄(内存) 0 R9 B- P" S3 r) E- o
LPSTR mpBitsSrc; // 位图文件地址(内存) # y: O! x# k$ c/ u7 L, N' r7 i
BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
5 p2 A+ e; |0 T j ! _; b) n, Q& C7 l
" ^0 o% U8 j2 B5 j* @0 f
---- 2. 在CViewBimap类构造函数中添加打开视频函数 ' U' m% r. Y8 f; B2 ]5 o
---- m_hDrawDib= DrawDibOpen(); # e6 d- |- u3 H V
) X! n8 I: v4 w5 S* r4 z---- 3. 在CViewBimap类析构函数中添加关闭视频函数 + ~" U0 s. S1 P7 y+ @
8 h% W7 c+ J. u" W% w, zif( m_hDrawDib != NULL) 0 n$ p. j# w; n5 X) G
{ , _$ }. B1 V& J% N8 u1 E& u
DrawDibClose( m_hDrawDib);
, ~+ E# I* r, h; a m_hDrawDib = NULL;
# x# `# x3 s' D; p& ^2 e( n } ) L% o" j( j+ `6 }9 ?/ K' D/ }. H
+ h! B* N/ `! G, o7 H+ T 6 C5 U: [1 z1 ~ b& c9 h
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() 5 g7 @. [$ z" U
voidCViewBitmap::OnPaint() ! g' ~. }% |, F8 u
{ , r" j6 S. D- p
CPaintDC dc(this); // device context for painting : g7 D# i9 E7 H+ \ |
GraphicDraw( );
+ e# d s e* H} # [, {- k6 l! p' H# h
- ^9 }+ f, N% b! w5 rvoidCViewBitmap::GraphicDraw( void )
7 F2 J' K) b& X5 L$ C" w5 F8 e% R4 U{
3 _0 R! k0 D! ?+ L- LCClientDC dc(this); // device context for painting % M8 B# }" n2 v' r% X, |* S3 W
BITMAPFILEHEADER *pBitmapFileHeader; $ s- y0 g5 A8 `% l5 O4 i( a
ULONG bfoffBits= 0;
2 F0 A& U- W1 I: j- v4 uCPoint Wid;
; ~3 T4 H7 ]5 `8 p+ i$ g ; g8 }: h) A( H) D- a
// 图形文件名有效 (=0 BMP)
8 ]2 y: A2 g2 B- D. Eif( mBitmapFileType < ID_BITMAP_BMP ) return;
2 b# D# ~: H( G' _
8 j7 H( h; O4 _/ G0 ^) y# z! H; [0 {// 图形文件名有效 (=0 BMP) . j) o2 X$ \! F1 p7 M% P7 v) ~" C; P
// 准备显示真彩位图
/ L$ l* m1 D5 W9 c5 r7 o* bpBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; - k2 D/ t, ]% }" [$ o4 G
bfoffBits= pBitmapFileHeader->bfOffBits;
- A$ d2 _2 b0 {+ w; d
! ]) f/ K5 {6 u j8 i// 使用普通函数显示位图 ( o1 s2 Y& S' f- u- k6 y+ R
) ]2 a1 X; J4 l" c7 ^9 T
if( m_hDrawDib == NULL || mDispMethod == 0)
+ b6 D P, I' y& J) G, y3 ]! U {
A5 Y+ R; e/ @2 ]- S HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
4 M0 k U0 z* I/ b# m; HmpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
+ \6 d7 C7 q2 O1 S" h4 ` (LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); 9 a7 V. A. r/ l% b- v* k1 z, H
// 建立位图 5 r" w, g/ D3 s5 a) d
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
9 M @# p1 W* SHBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
; e G; k6 A W$ s1 P0 I% B& c// 成员CRect mDispR用于指示图形显示区域的大小. * n; I7 @4 I' x D* t# T
// 成员CPoint mPos用于指示图形显示起始位置坐标.
, V3 U/ X& S9 Y& jif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
. ]3 p3 U: s" r6 G) p, U$ SmPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
* i2 O- s( F" [+ j/ q! s7 V- ]9 `! ^9 L if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) 9 p' |& E' _' e* W
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); ! e+ A$ i$ Y# t; |7 q
if( mPos.x < 0 ) mPos.x= 0; - h/ b( r6 G, I& Z8 L2 R
if( mPos.y < 0 ) mPos.y= 0; $ w' m" f) q$ B/ ~
+ z0 G0 M1 f4 }4 |8 v& d6 I if( mFullViewTog == 0)
: @! m, |. \/ J2 t! B{
; j. D/ ]- J( w0 U" T6 \- a: {// 显示真彩位图
) @3 X$ C* {0 `1 r3 F::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), + m. U4 B' o! C3 d
hMemDC,mPos.x,mPos.y, SRCCOPY); * `% S$ \& J' B
} else { - X* E1 J! A4 L3 t- e7 y. j' s3 k" R
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
4 h2 S& r- C( I7 G' VhMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo- - P4 n; A7 J' O+ A7 m" z8 s O0 z
>biHeight, SRCCOPY);
% C# P5 a$ d9 c, w. k}
, P) ]1 F' m, d. A# t // 结束显示真彩位图
7 M! X+ D, t2 y1 N' R8 Y J : eleteObject(SelectObject(hMemDC,hBitmapOld)); ) f& p. r) T% C+ r
// 删 除 位 图
: ?$ E% w( t! p3 f6 s } else { % o& `& X) P2 i' g+ d( q9 a/ W
# Q9 }1 X E8 \1 G3 q
// 使用视频函数显示位图 + U( X7 t' Q7 B- V9 l" v8 G8 r
/ S9 \# L0 H! p( q, @ if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
5 ?: _; G1 Z+ S: gmPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ; 4 V! }8 V- A3 d2 b: e
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
; B" ~4 e0 ^$ V* z# u3 jmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
/ c4 [4 R* e7 A4 U% g: G+ q4 V if( mPos.x < 0 ) mPos.x= 0; 1 @; F! G) o0 k% z( m5 Z( l6 z
if( mPos.y < 0 ) mPos.y= 0; ) b; l; z9 n- c( j$ B! a- I
9 [) F* ^: ]$ z d // 显示真彩位图 4 l* C# D [! V( w* k5 |. G9 \& c
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); ! }* F/ x& p9 k) _* F
( e; S" a3 {0 n" W/ d7 ?' P if( mFullViewTog == 0)
3 c! P2 m( C5 @4 c. U1 Y{ + B* d8 z- I1 b5 l& @4 E) `" y
Wid.x= mDispR.Width(); : _# v: q; h* e9 U
Wid.y= mDispR.Height(); , ^1 H# f$ j! ]3 A: Y
// 1:1 显示时, 不能大于图形大小
2 h: z- K/ x( m* M& e1 yif( Wid.x > mpBitmapInfo- >biWidth )
3 V; {- t: ` d6 I8 S' p2 K/ d) fWid.x = mpBitmapInfo- >biWidth;
6 F/ q0 V( l% t5 Y/ d0 dif( Wid.y > mpBitmapInfo- >biHeight)
5 z/ q8 i$ E# l9 c! I" CWid.y = mpBitmapInfo- >biHeight; / s! F* h+ G6 T4 O0 q
9 w, A7 K9 F Z# j: fDrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
4 Q) q. {1 L. J, 0, 0, Wid.x, Wid.y, : }7 y9 t: V+ T* S6 Z
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
- \* B8 K1 ^7 P! a9 u" v$ t1 QmPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL);
) s* t3 _' f0 c0 Q+ D8 N! M. ?2 S} else { 5 |4 |2 S0 V7 H- Q+ X8 P- H
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), 5 g! z: Z5 H0 |" I3 o
0, 0, mDispR.Width(), mDispR.Height(),
3 t7 R" z* j% B: G/ FmpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
# I# q- v; F- ~9 V3 e" z5 `0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight, * G+ R- ]: f+ P
DDF_BACKGROUNDPAL); 2 y% A; E: F8 x/ g1 p K
} , i5 l" L* w, E# F+ p# Y
}
. m8 D2 [5 S2 j8 Rreturn; $ w; j; x1 ?/ Z. ?, W
}
7 ?8 I- j8 q! u C7 G' a; ~
, [6 j- o% ~; D / W7 k# ^7 {# p: Z- \
---- 五、使用CViewBimap类显示BMP位图
# M, M s5 P* `---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC . z. ?0 C# A- Z# x+ m
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点 ' ^2 P$ t2 p* f
击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目 % ~9 e& t+ \: \
,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
$ r0 y& N+ b+ D9 f1 A* B尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 2 f) D7 H& E6 Y2 I: w2 U
- I' L5 H. ?7 Y8 x7 ~* m% [: l8 L
---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
! Q7 K% e# ^6 h>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。
1 f& L1 X+ N# F- a/ F4 ` " R. h( U* R( n1 a8 ]) [# @3 u, }
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
5 h8 R/ R7 u9 E; a. m. z5 iCMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
* `8 y! f1 f% n/ I; y$ V, j- ~ Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 8 M8 B8 d. O. ~( H
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码
2 t% t9 A3 {" r1 ~。代码如下:
" R1 ?) n% f0 F! b : h4 ^8 r6 v& c! M' m
void CMainFrame::OnViewBitmap() ( z: v+ B8 b1 t* i `4 z1 E
{ ' Q: I) u2 F& V+ @
// TOD Add your command handler code here ( Y1 Q/ b& Z9 p. _* ?$ F6 |
CViewBitmap *pViewBitmap= NULL;
' N( d' a z4 d. O4 p* f, N$ i
( H" ^3 u$ _+ _: c F, VpViewBitmap= new CViewBitmap( "BITMAP.BMP", this);
6 c0 R) I: F4 Q* u6 i+ k0 z3 wpViewBitmap- >ShowWindow( TRUE);
. m( o- [! ]* Z9 R/ \# f} 7 R7 x$ Z4 w: p- t0 Q
" s# S' @, h4 y4 l: G% B* q9 M
8 R' d3 N" @" n6 g
---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 E- q$ b- S6 X* f, S; u
---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
" p7 x$ k- Q8 W( o. o) k& G
1 z2 w) K5 m0 \---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >
- g% {$ V6 ?8 I2 n5 {: y S7 Q ViewBitmap)即可显示BITMAP.BMP位图。
! K' L( q9 ]$ q7 _, p
- f5 v0 {# f9 s1 x5 `4 q---- 六、CViewBimap类功能说明 2 W: W( S3 ?0 j
/ x) X! K. g9 t5 g; S3 y---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可 3 `* M. U+ B) @5 F+ G/ D/ ]( A
以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 - c" d. U* ?6 z. `- `& }% O
$ n S5 e7 X$ H7 M6 i* p. G5 B* A---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为
1 y! v6 u! r4 G5 q2 A: ?位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
$ @2 K4 }8 Y4 G" G+ t# f,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在 7 O& T5 c) Q5 y) x% a
第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区 2 q' L6 C+ b5 p, k" y+ k
小,则对位图放大; 如果位图比客户区大,则对位图缩小。
# @7 S/ X( T5 ?1 y! ^+ q! {
7 ?8 i4 X6 {2 q% d- p---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, 7 q4 b# g0 [, @3 b
就可以显示该位图。 * X& X- G. l; _1 w
4 C4 d- K! p2 W9 z: g
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
3 @- u) [5 K w$ \
7 T, X4 z% B3 ?9 l2 J在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图
6 e v) D* f; v+ p放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失 ( c0 D. [1 w& V6 z3 `
真小,显示速度快。
' k2 B: k! `0 m6 I2 } _0 ?
: Q) b4 C R+ q---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 3 t: J1 a3 ^( x: j) v- Q
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可
4 |5 E" e+ D' X3 O" M以体会到使用视频函数的优越性了吧。
2 J, B( u' N+ L0 m- [; S
2 C8 Z0 S/ p7 S1 H1 n---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
1 A6 [& l4 d# x, x7 v8 h4 Q% B- s程序中加以适当调整即可,读者可自行完成。 |