|
* H/ ~: ?. }: ?. @
西安交通大学流体机械研究所 0 E$ `# l0 H% c# |/ ~' \3 T
张义云
1 |7 n* U: e- l5 G! b' }
9 y. x9 B% d, p4 b9 ?1 k---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
_& u7 Z; d5 m/ Q6 V, e" l( ]在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数
5 q! W0 a0 b( u) ^, r* E显示BMP位图,可以消除以上的缺点。 $ l/ Q' I2 S' A. \$ C. M
1 g8 \0 Q; \: Q$ }8 z---- 一、BMP文件结构
' l, w$ P) g7 i8 L6 y5 ~
0 _5 _4 T- ]/ ]$ c3 p---- 1. BMP文件组成 + ^5 @( m+ n7 T/ e0 B* ?; f
) W- C: I/ E7 g$ W+ D
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 : x4 B% V D: m/ l
5 V' S* |* o+ Y7 G( w+ @---- 2. BMP文件头 + ? x; ~( N! k, g* a. Z* s6 ?- K
, s9 u5 d9 H& E5 K- s2 V
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
. X/ i9 t( V! p1 G( T; \0 U。
% ]' P8 v+ |, T& T0 ~& U' Q+ x7 M + d/ D: R- ^ g) g( b6 S
---- 其结构定义如下: / ~8 t6 G6 Q5 G+ D; T
2 y0 E* ^8 C e5 ttypedef struct tagBITMAPFILEHEADER w7 F2 J% X/ {7 _
{
4 k6 b2 e9 f" BWORDbfType; // 位图文件的类型,必须为BM " Q3 z; [! ]. K& [/ ]1 r
DWORD bfSize; // 位图文件的大小,以字节为单位
1 L$ Q8 J2 G" G7 ~WORDbfReserved1; // 位图文件保留字,必须为0 - J" c: U8 P( g- D
WORDbfReserved2; // 位图文件保留字,必须为0 & ] }0 G' ]# T3 h* L3 ~5 ]
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图 9 u( f' a2 \+ L
// 文件头的偏移量表示,以字节为单位
$ `! S# l+ L( K} BITMAPFILEHEADER;
& G9 {) T, i u' `+ r" y4 I
( c$ _% b# `& R. b+ J8 W A 5 U! G; x; ?' V% m' I$ J
---- 3. 位图信息头 ' o; W+ _" J7 k: d; E( A
---- " l& {: j& _1 g* i
! Q7 x( a: q7 X C4 k
BMP位图信息头数据用于说明位图的尺寸等信息。
a; Q w q& _6 N7 ftypedef struct tagBITMAPINFOHEADER{ . t5 k" t1 h, v. d' R
DWORD biSize; // 本结构所占用字节数 ) ~9 [0 O9 p+ R1 s# l. c
LONGbiWidth; // 位图的宽度,以像素为单位 8 y* D. E" v% n& B0 b
LONGbiHeight; // 位图的高度,以像素为单位
* R- k+ \+ V& ]# Q- C. I WORD biPlanes; // 目标设备的级别,必须为1 9 w; P0 r, t( B9 v7 {9 ~
WORD biBitCount// 每个像素所需的位数,必须是1(双色), 7 Y, ~: b0 Z$ t% Q1 g8 O7 Z. G
// 4(16色),8(256色)或24(真彩色)之一 : _9 M1 |$ r# }" K) z+ K8 D: q9 @7 L
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
& G1 \3 V. P/ B1 g! s // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 " {& G" j9 @$ q: a4 b
DWORD biSizeImage; // 位图的大小,以字节为单位
2 b# e5 @, u1 u. Z/ n" P! e LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 0 t4 a/ ?: `% i4 T5 P5 _
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
9 c5 n3 P0 o$ K$ b+ L& ~ DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 0 P5 d1 v( h; ^$ m9 R% D- W& I
DWORD biClrImportant;// 位图显示过程中重要的颜色数 5 _/ i1 i4 o7 N& q
} BITMAPINFOHEADER; / E8 {0 o; @. O8 G U/ n
4 D) j4 k0 T5 \+ {0 y1 M8 B 5 E0 ?' Q8 X0 r! C# [
---- 4. 颜色表
* b! m; Q/ l8 Q3 ~+ Q8 z8 l4 Q---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个
: e" Z" t: g7 F, Z4 r5 [RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
' |! J# ?% }9 N! a
0 R5 w. e- y! k( F/ Ttypedef struct tagRGBQUAD {
1 l2 |6 F+ E' T& y1 wBYTErgbBlue;// 蓝色的亮度(值范围为0-255)
8 w$ o. a: s! MBYTErgbGreen; // 绿色的亮度(值范围为0-255) % K' z) k5 p" e% Y2 O
BYTErgbRed; // 红色的亮度(值范围为0-255) $ b5 j `" ]2 A0 U3 w6 `
BYTErgbReserved;// 保留,必须为0 ) c: W/ }$ b- l( d
} RGBQUAD; 9 l* g& e8 L6 j' \- W
颜色表中RGBQUAD结构数据的个数有biBitCount来确定: " d* N; A. O" P7 f7 @
当biBitCount=1,4,8时,分别有2,16,256个表项; 5 E: L" `! B0 m X
当biBitCount=24时,没有颜色表项。
9 Y+ N" ?# g1 w4 C$ B3 g 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: ( ?4 Y# R( z( o$ K6 `
typedef struct tagBITMAPINFO { % Q+ U) G* x7 J, S0 f3 ~1 l2 n
BITMAPINFOHEADER bmiHeader; // 位图信息头 + d1 b z1 v4 `+ \; O2 o2 Z
RGBQUAD bmiColors[1]; // 颜色表
$ Y. ^7 C1 `/ g} BITMAPINFO; ! w, w6 Y# O' b
" B- {1 Z/ [" Z. f8 M
4 h) |; `7 O4 L 1 p9 w/ f6 h. k7 t5 I. l: j
---- 5. 位图数据
$ S& H- l% O* N5 e5 O---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右
' u( i m- G9 x4 e,扫描行之间是从下到上。位图的一个像素值所占的字节数:
/ V0 F/ ]: ^. d$ l ; g8 k' Q+ [6 r* P$ w9 |! u8 Z j
当biBitCount=1时,8个像素占1个字节; 6 G0 M4 H. y- C; {5 U2 `6 n+ e
当biBitCount=4时,2个像素占1个字节; # b, ?* F! I; V7 @4 W) K
当biBitCount=8时,1个像素占1个字节;
& x0 N X2 r. O当biBitCount=24时,1个像素占3个字节;
/ T! `2 B) m# ^Windows规定一个扫描行所占的字节数必须是
3 B* }) V, Y0 L; n. a- L4的倍数(即以long为单位),不足的以0填充,
4 R2 F' M& m5 A# B& u$ b一个扫描行所占的字节数计算方法: ) [2 I# }( e$ _5 X5 }0 F
DataSizePerLine= (biWidth* biBitCount+31)/8;
. h+ q0 h8 D4 } // 一个扫描行所占的字节数 $ S9 N/ j1 M+ r' L
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
0 P; E$ {* n& u3 d& E位图数据的大小(不压缩情况下):
0 g- r) Q" a$ L9 Y, R7 u* v5 u8 wDataSize= DataSizePerLine* biHeight; 6 R$ f+ `( G2 Q! ^
4 j2 d6 D4 `) G/ ]! n7 @
/ H3 s, v9 Q1 S4 G( }---- 二、BMP位图一般显示方法 0 M- V& O% s, I: r
---- 1. 申请内存空间用于存放位图文件 , ?6 l% o7 ]; n# }
+ E2 o% I" j& |7 e U---- GlobalAlloc(GHND,FileLength);
3 ?$ [: [% Y: m2 a+ h i 3 }+ i% l$ r; J) q
---- 2. 位图文件读入所申请内存空间中
9 p; l1 g, Y' }, ]! ~8 N 2 D- ?. E: {2 R' x. A; u4 X1 T
---- LoadFileToMemory( mpBitsSrc,mFileName); 8 e3 P8 P% R" e" K! ^
! l% Z1 e9 f2 X) Q' K
---- 3. 在OnPaint等函数中用创建显示用位图
9 \3 d# g( B k; ?( y2 h
' u' Z$ o8 L1 X! L, y( @2 O---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 + A) |2 ?( E l+ J# [
DC,
, ~7 p! y' f# O7 f" h& d/ r
) o/ ~; e! c9 _6 K) K r# p---- 用SelectBitmap()选择显示位图。 ! k4 ~/ [( j1 S! o
6 D5 T1 l/ B. Y
---- 4. 用BitBlt或StretchBlt等函数显示位图 7 M' O0 R( V' q& ?) w$ Y/ U; N
8 e7 H: b5 E7 M- x: f. v4 X1 s5 r---- 5. 用DeleteObject()删除所创建的位图
/ w( O% |; D5 O4 G" A
& }9 l% s" j7 P---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 " A4 F! ~7 s9 R
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上( " o2 f4 }3 }: U% z$ H. J9 o
如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。 * y& i0 v1 b4 K, q1 J% w
4 @' G$ W, T" j6 _, v* b) S---- 三、BMP位图缩放显示
. u7 F3 U# @2 [4 P) Y
! v6 B- A" A* |6 W8 v---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
1 L' q! v; }3 F! m进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比
! p7 x4 k; L5 H3 f图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下:
( e- ~ {, a8 o, I" W- W3 O- O& a x 5 d: [# `" u6 W5 f, y S- e, M
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 & o$ B- Z) ~' Y, n4 x$ H3 p, M
; y+ k J5 Q. z4 N---- 2. 申请内存空间用于存放位图文件
; `8 _. w& h& k$ H+ A8 B) m
2 `, [! q' u& L3 \9 Q1 ]9 s---- GlobalAlloc(GHND,FileLength); + S3 ~8 P) e- `
1 d; u) z: V5 @7 i1 p
---- 3. 位图文件读入所申请内存空间中
) k! F* e1 P7 C" ?4 e5 u ( ~+ [3 @+ Y2 B5 w9 C- o
---- LoadFileToMemory( mpBitsSrc,mFileName);
9 l! x. `3 o( m# `& n
( J, X8 S( `( j8 P: Y---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 . _1 J( d+ m* K8 C% {1 |
9 D- l. \5 ?9 ^: y% Q' R1 c& C
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中 # [9 ^3 I: w4 x' m9 q' c+ ` i
0 G1 h1 L6 d) ~ \9 Y* r* G
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形
4 o1 c$ H: A: ?& Q8 N" x* m$ S失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通 ! ~! _# {* V& z7 F8 }9 q/ B
过直接处理位图数据,可以制作简单动画。
- _6 T4 o/ T$ K/ t; Y4 l
$ @1 k) ~. }7 O# P---- 四、CViewBimap类编程要点 - B; F+ S0 |2 S! W
% w2 x0 q6 a. r& |
---- 1. 在CViewBimap类中添加视频函数等成员 / g* m9 g Y2 I& n6 p
# _) C* [" e* M# c: PHDRAWDIB m_hDrawDib; // 视频函数 ! t5 { K$ ?5 X7 Y- s3 V
HANDLEmhBitsSrc; // 位图文件句柄(内存) 2 S& F B' ~" Y0 M: r7 u
LPSTR mpBitsSrc; // 位图文件地址(内存)
; S: m0 i" s+ i l/ ?0 {BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
4 Z% x1 I8 x4 S# A7 T8 T# ]) n, {
; t: d _- I, u7 ]: l4 t
8 {6 B1 `& @% |/ }6 q) P$ C: D7 e---- 2. 在CViewBimap类构造函数中添加打开视频函数
7 ~, b/ L% _! a, u5 D. O& [---- m_hDrawDib= DrawDibOpen();
3 v6 ]* C, [$ { " T/ n! R& R& y! E" _" I
---- 3. 在CViewBimap类析构函数中添加关闭视频函数
$ g2 v- ~" e9 R; l! F : O/ A/ j' t' f3 D+ J0 b- V( [% \
if( m_hDrawDib != NULL)
4 S$ I/ x& X, `4 O" T- Q- k { 8 k/ r6 @/ W3 R& C* l/ S5 a( {) Z6 D
DrawDibClose( m_hDrawDib); 4 W8 V6 l( N6 P. e/ n8 c
m_hDrawDib = NULL;
; j9 m* S5 ]7 c# D/ P } 8 y1 l% p2 N( B9 E$ t% M1 G
8 n5 K! P) D' j$ O6 v" W & r6 N' N( @, J: k) W E4 s
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw()
, u9 T/ G1 Q2 V E' l. E* l( dvoidCViewBitmap::OnPaint()
" H! h" M6 B+ W3 y{ - o/ N5 @( D' v9 z
CPaintDC dc(this); // device context for painting
7 @/ A+ U% o) J% B& u7 v7 E! wGraphicDraw( );
/ `, d2 h* K$ W}
~ Q) P0 e; s X, a1 d' L
: u3 W8 x: S" P) CvoidCViewBitmap::GraphicDraw( void )
& E9 C. A4 |# g% Q/ k7 f2 `{
" V8 O, l! ?: o$ j$ f E# D! K9 ^CClientDC dc(this); // device context for painting
5 X/ C' d( x3 Q) B! `& T' `BITMAPFILEHEADER *pBitmapFileHeader; ( d# n" f0 J5 Q: ?. b4 E4 ]; W G4 ]
ULONG bfoffBits= 0;
s- U+ D' T t1 UCPoint Wid; 6 o0 x8 X* O2 b' r$ i# H$ n
0 P; a! j" u$ p: I) v0 T9 g// 图形文件名有效 (=0 BMP) 9 F9 u# k7 v2 \3 d
if( mBitmapFileType < ID_BITMAP_BMP ) return;
; O" j- B4 s/ g, ^! _
$ ]6 R6 R" L7 }$ W0 D// 图形文件名有效 (=0 BMP)
" k5 t/ s3 n/ a2 f5 R! x) U5 d// 准备显示真彩位图
1 [6 u. l! Z5 ^7 o* B; I7 IpBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;
$ g' s3 S }, |: @3 ?4 J4 H/ b8 k8 EbfoffBits= pBitmapFileHeader->bfOffBits; 8 N) t y3 f, s7 v6 ]! d
4 ~5 V! G' |' {1 Z
// 使用普通函数显示位图 $ H' R: R% \5 e
# \% \3 _# Q3 v' y7 |: q0 `
if( m_hDrawDib == NULL || mDispMethod == 0) " L- ?- c) r7 a* I2 q; l' D
{
+ u1 S+ ~3 Y% E- G) K HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, 0 R" ~3 p" |. b$ W
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, 0 F6 w; r7 g3 g2 f! F5 A
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);
! O% t% t/ D/ T( N3 y// 建立位图
6 A* `! D+ y+ R" E, ?; WHDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存 9 D e1 Q M" D1 Q* w
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象 3 v- }1 ?3 p5 X" h* C% G: I
// 成员CRect mDispR用于指示图形显示区域的大小. / [ C: ~6 W" y/ u! w
// 成员CPoint mPos用于指示图形显示起始位置坐标.
9 l, ^, K/ K, zif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
/ a: w: V4 U/ h5 G! OmPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
5 @- b$ N' R) Q6 U1 k if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
* r5 |/ x$ S9 m; s* t VmPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); & a' S) h+ m( k% }9 U, L
if( mPos.x < 0 ) mPos.x= 0;
) S4 M- i! h( K1 I! t) Z6 S# o if( mPos.y < 0 ) mPos.y= 0; ; w' W: E5 c* C. o5 p. j& P2 ] Z
+ L$ w8 n2 u' G) ~7 z+ ~1 I if( mFullViewTog == 0)
" ]0 r4 D0 R* Y) z{
2 I+ Y( G; w m9 F: S// 显示真彩位图 + ?0 A3 [; B5 ~& w: P9 ?8 K. W' j
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
' u+ n5 V7 b) F# l% ?0 `! z9 |3 vhMemDC,mPos.x,mPos.y, SRCCOPY); 6 s, g- V5 q, R. B: s
} else { : S7 M x6 W, Q- G6 j: O
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), 4 T; k( z! N% M, V! v# U$ A
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
1 y! T# L; i% W$ R/ ~* w>biHeight, SRCCOPY);
" r% ?) ]) `' \$ @: W}
, @+ a& F6 f+ b9 E5 s // 结束显示真彩位图 % w) w) S* j* T j! A5 g* B$ H2 I
: eleteObject(SelectObject(hMemDC,hBitmapOld)); ; X7 Z2 p# { Q( W
// 删 除 位 图 . H9 h% t) P( v
} else { 5 E+ h- T7 i3 c) r7 d9 D' o, B% i9 Q) B
0 c7 ~ U' ~' e" r0 [( k // 使用视频函数显示位图
6 o4 N& s# Z$ F5 o
) I) T, F; u0 z+ Q6 | if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
$ ~* r4 Z5 r9 b5 v" Z, r3 C3 @mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ; 1 y T- B' M/ V+ d1 {# }
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
2 _; N( @4 o, wmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
% ~: B- Z& j; M$ r3 ^ if( mPos.x < 0 ) mPos.x= 0;
. G" ?, v/ ]% G: k, h9 b if( mPos.y < 0 ) mPos.y= 0; # T0 Q6 D$ r# W
1 P6 J1 ~7 a j
// 显示真彩位图 , k7 _; p0 a9 G" E2 W
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); + S( y8 ?+ K9 {/ m3 m
' d% I, g8 ^1 m; O# u6 I/ Y
if( mFullViewTog == 0) ' \) x5 t6 O& C' F x- f) a
{
& i' m' p6 b7 D% QWid.x= mDispR.Width(); 7 q9 d9 B9 ?+ j! T, _0 @( O
Wid.y= mDispR.Height(); $ M4 E5 d! i" h3 X
// 1:1 显示时, 不能大于图形大小
- `6 M1 v% ?: S' Kif( Wid.x > mpBitmapInfo- >biWidth )
4 C1 E( e; Z" x8 C7 }9 ]* CWid.x = mpBitmapInfo- >biWidth; ) |3 Q. o% R# |- y7 Z. s4 Z' }
if( Wid.y > mpBitmapInfo- >biHeight)
& V& S5 n1 [- w+ [, p) p: ?Wid.y = mpBitmapInfo- >biHeight;
" K; F j9 j3 ]4 N( `: j # Q# b3 K. g% _: q! U: ~. r! U
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc() . Y# ^% n* d+ i7 X8 Q; e
, 0, 0, Wid.x, Wid.y, + C, d5 G" I' g) t* E/ c
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), 6 v" r4 B5 Y) k" X6 X7 \9 Q
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL);
: ^# \2 K5 H$ T& O" y3 Z5 Y1 l7 I} else {
& F ^1 _- I: Q! X, O8 \DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), 4 @. X' W8 Q' M: `# v
0, 0, mDispR.Width(), mDispR.Height(), : t3 ^$ \6 `- L
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), 1 H% @; a; T+ b
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
8 m1 |* \' G4 ], z; I# [DDF_BACKGROUNDPAL); . m; [( U; H+ {
}
: z" |# J, P M: b5 [5 } } F! S: J% s3 [" n) v6 S
return; " d! U/ A1 Q8 U, j& m9 X
}
" p* U5 w) ?2 N+ w 3 S. _$ k# E% a, X0 n& s
' D0 P3 r4 i" [; S---- 五、使用CViewBimap类显示BMP位图 , c8 a! \/ @' S7 X3 t, E/ O8 z
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC / e2 ~6 E1 s& O* p, i4 S# |8 g
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
* h7 w+ l) f+ l$ n4 a1 m% A击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
! L& {- D' r3 \3 y4 V2 J,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
' D/ X3 p' @. H4 k$ u2 M+ C. J K尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 , a) A4 M2 M5 P" x$ ]3 G# _: ?
' f! x' @" ^, L/ W# d---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
8 J3 q1 o/ F3 `>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。 % y6 i8 A6 ?4 L4 _. d9 l! j
" P& C' O) L% J0 T9 m I! b4 B% b3 Q
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
4 L& r2 }3 b7 }CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
9 T; r. g! V1 E9 s; ]( Y$ K* S% v Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 , D) k& }: H C T9 ]- U0 ?
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 ( Z2 w) e8 A9 }. J
。代码如下:
5 ~8 ~" ^5 X; V+ f* ]& @. E! z
! z W1 m! ~: [, bvoid CMainFrame::OnViewBitmap() 2 i* a/ E8 N' K3 M: J2 x3 `( o
{ ' V4 G: Y. _" M( k! p D
// TOD Add your command handler code here 0 K8 l" C4 w/ E
CViewBitmap *pViewBitmap= NULL;
: ~8 J( y! g, y/ w+ y5 x- n
$ {5 K4 P7 H& h V8 F& K! C6 NpViewBitmap= new CViewBitmap( "BITMAP.BMP", this);
# ?9 o. S2 K- g" Z: M2 ^pViewBitmap- >ShowWindow( TRUE);
0 f/ t" q; o' b5 i}
1 c$ |8 o8 R, Q/ J
% ^. G1 M8 @! Q1 s/ T: ]
& I6 q! W% L- c---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 % W& k" }0 b9 M( g
---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
2 M& Z2 {% q$ s: p, q2 t * a2 Q% r& N$ B1 z. u8 Q
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- > & t6 M% O8 p7 z& l9 |& e0 q
ViewBitmap)即可显示BITMAP.BMP位图。
+ H* o' ]0 e& ^! D/ h% |$ i ( I9 B6 i& c, y( w! P J4 a
---- 六、CViewBimap类功能说明 + H/ W4 f; F6 {; P+ Q
' j c" |0 v+ E. u/ U1 H K
---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可
5 @8 `" p8 E% d6 Y' S8 a$ @1 E以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。
7 N+ a0 ]. I. I# |3 @! M2 v
& l& h6 J& ]5 F" T---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 0 J( G3 K, b$ S& o1 q: f
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
7 l7 p7 p* W4 _8 k6 p,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在 - ^$ c% g7 B4 n# v# K8 u8 p
第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
0 q' a8 ]2 N0 ^小,则对位图放大; 如果位图比客户区大,则对位图缩小。
& R* R2 ~4 D! P0 T
) d8 f N# X% j/ f' s% y---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,
5 p* v+ b# _0 i, Z. H就可以显示该位图。
8 Y' ]1 u: f/ I
3 Z5 @/ Q# r( l8 P K9 w$ y* n---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
- p* i2 W p2 `' {
* G$ }4 G4 [7 ^- D& Y% z在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图 % Q6 r H7 j3 |# T! d" ], u. \; L5 y
放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失
+ O5 p/ f# [9 S9 s* O. [; d# h3 t: A真小,显示速度快。 ) w1 x5 [1 d. ~4 o, @1 w9 J
7 d# Z! Y+ z! ]4 X# f; j; t---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 2 D* t' s6 {9 ~ O0 U8 S. Y/ a
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可 8 X' u f$ I2 h% M& _
以体会到使用视频函数的优越性了吧。
z1 D* Z3 Q. v0 U" U: z, h: k
7 a$ ^2 }$ z0 z) r/ Y% w) H; I+ m---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
: R/ g0 l8 v! {$ R程序中加以适当调整即可,读者可自行完成。 |