|
$ ]3 T- u3 _, j1 w
西安交通大学流体机械研究所
7 B7 L C6 i9 M3 W; }4 I- R张义云 1 J8 v* f/ m( Q, i
9 I* H- G9 K( a1 [; F9 m [/ k! ?
---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重, . t, i/ G: z% P* P. q
在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数 T" `8 J* D! m: u9 }4 T% u* l
显示BMP位图,可以消除以上的缺点。
: b G; {5 N4 `9 ?+ W* L 5 U$ q2 _. R6 s C; H* R4 }+ D
---- 一、BMP文件结构 ( L1 y8 F5 m# c
0 I8 q1 u% S3 m
---- 1. BMP文件组成 / S: f& i# o* d8 P/ H
) t) |2 H( `# f0 _( X# Z. O7 W
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
* k& l/ ^ K* p+ l- q$ { ? ) ?$ r4 @ o( l
---- 2. BMP文件头 " D# v7 b( z/ `3 V# v" V4 p+ Z
0 }: \6 {! b7 Q; M6 d
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息 + O- s0 c$ s2 N" Y9 d
。
0 v) x+ z, @' u3 n G3 N6 `2 b; h5 R" p 8 w- A( W/ E- i
---- 其结构定义如下:
7 z5 C0 F& ]) q" Q5 m $ e& ~) w! ~$ s( f' T7 C: V8 E
typedef struct tagBITMAPFILEHEADER
7 {' H9 g$ g& M{ , n% v3 R- @2 {2 a* |9 e
WORDbfType; // 位图文件的类型,必须为BM
2 K7 k7 l$ d/ c; {DWORD bfSize; // 位图文件的大小,以字节为单位 3 U& d0 q, z/ G. L
WORDbfReserved1; // 位图文件保留字,必须为0 M" C5 L4 O( Q
WORDbfReserved2; // 位图文件保留字,必须为0 7 `7 y: ?% O/ k$ ?
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图 5 `2 V4 m, k3 I. K j* A- Y- g
// 文件头的偏移量表示,以字节为单位 5 h, D( L) G8 n) ^
} BITMAPFILEHEADER; ( y1 l4 D" ~" G, `
% W, ~4 ]: g4 G! j- _0 X0 D
7 `( C, o1 `$ c& `% e2 S
---- 3. 位图信息头 8 a: Y C# h9 B4 a7 [8 A& \/ b
----
$ I1 g8 \* g6 ?5 ?+ _6 n8 _6 S) m1 ?
+ u; w0 Q' S% W6 k' q1 tBMP位图信息头数据用于说明位图的尺寸等信息。 8 z& N& |8 u# Z' p8 ?
typedef struct tagBITMAPINFOHEADER{ s2 @9 [: R3 L# @
DWORD biSize; // 本结构所占用字节数
. h4 j1 N: i% x+ n' ~! M) v% P& p LONGbiWidth; // 位图的宽度,以像素为单位 & @/ t0 d+ j) o
LONGbiHeight; // 位图的高度,以像素为单位 ; r- P+ k" q# k) Z, N7 `; i X
WORD biPlanes; // 目标设备的级别,必须为1
' B1 \* ?% I) x WORD biBitCount// 每个像素所需的位数,必须是1(双色),
. |- X# X9 w! \% ^8 F // 4(16色),8(256色)或24(真彩色)之一 . A; F7 M l4 T* v' t
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), ! z2 t3 O0 e" o; s5 a) h$ W; }
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 : s" N! [, ? f4 ]
DWORD biSizeImage; // 位图的大小,以字节为单位
( o' V E$ B+ N8 X! @' a' w4 T i LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
+ j7 P1 d4 f) S& e2 Y8 i& y+ q LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
7 L6 p4 R3 W9 {5 z2 p DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 - s2 H% F; C) W2 Q y2 ?
DWORD biClrImportant;// 位图显示过程中重要的颜色数 ! G/ g7 Y% l, [) I4 k. R' N6 |
} BITMAPINFOHEADER;
1 l3 I3 Y: [& X5 A$ A' f% S3 c5 \) f
' `6 N- J+ O& }9 O
4 L. d" B0 P& y6 q---- 4. 颜色表 , l" |$ M9 }! |/ v+ Z$ [
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个
! C% z% Z m% M2 ]" URGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
. n. A' l, }$ ?& y8 ? 3 a3 i% N$ R0 r
typedef struct tagRGBQUAD { 9 j0 i3 V2 ^4 }7 V) j
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
4 g r" |7 } P6 [1 ?BYTErgbGreen; // 绿色的亮度(值范围为0-255) 9 W0 d- p/ X# t9 f6 E
BYTErgbRed; // 红色的亮度(值范围为0-255)
( @" {- C# p3 \3 k# qBYTErgbReserved;// 保留,必须为0 # }" @. l0 V1 O% M& {
} RGBQUAD; 7 M }' J9 I2 s! S% Q4 J
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
8 x( y1 e' s' }! c, s当biBitCount=1,4,8时,分别有2,16,256个表项;
% v! I+ h# ?. C/ c: d" x# {当biBitCount=24时,没有颜色表项。 4 ]$ v6 o( F, c& N2 h
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
D R2 I. x, b5 C. Vtypedef struct tagBITMAPINFO { 0 t( n+ @$ ]/ [$ \4 d( l
BITMAPINFOHEADER bmiHeader; // 位图信息头
/ ]+ n' ?0 H+ d( V* H6 _ RGBQUAD bmiColors[1]; // 颜色表 8 `1 d5 o K5 x
} BITMAPINFO;
; T+ T+ ~$ `8 X" N# h2 w4 G
, Z4 l) q Z# ?* C ' T( z/ j$ h9 Y
3 i8 y# S1 s' ?+ A---- 5. 位图数据 ! D2 F7 m$ j9 {& c- m" e
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右
# ]+ }5 d3 d4 J2 d7 C* L,扫描行之间是从下到上。位图的一个像素值所占的字节数:
3 h4 X; @& a7 Q0 q5 ~; X/ I9 `% n
! T$ N1 E' |( k# b/ p. j当biBitCount=1时,8个像素占1个字节;
: h/ F$ ?- Q% M- X9 A4 `当biBitCount=4时,2个像素占1个字节; . A! ^. z* q. T. i$ k$ V2 ^
当biBitCount=8时,1个像素占1个字节;
, @, q0 l! r" \当biBitCount=24时,1个像素占3个字节;
: { M- M3 M# V) q: J$ n0 L! }; h2 PWindows规定一个扫描行所占的字节数必须是 3 H4 v( x8 a6 d0 I* H. ]6 _* ]& O
4的倍数(即以long为单位),不足的以0填充,
, U3 x0 d0 O! y5 m一个扫描行所占的字节数计算方法: ( o6 l# a h; ~& Q2 t" y
DataSizePerLine= (biWidth* biBitCount+31)/8;
4 O; H2 I7 }! [2 A. E, Y // 一个扫描行所占的字节数
4 l2 ?9 x+ `8 i3 c! c/ x/ R7 I2 yDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 ( A5 i: ~* \5 W" a+ O
位图数据的大小(不压缩情况下):
* J0 Z4 @( X) g! J# XDataSize= DataSizePerLine* biHeight;
, G2 j5 l: P1 ^( W! |
`, V3 g) @$ t4 |6 V
' H6 [1 @6 f X+ T8 f---- 二、BMP位图一般显示方法
r; R0 J# X$ T: m3 b8 H+ W9 W---- 1. 申请内存空间用于存放位图文件
# d, V% F; v5 {0 Y. C6 W , t T% `* N8 E
---- GlobalAlloc(GHND,FileLength);
. U' l$ L- ~8 T7 ^; ?8 d3 C, F
4 V' E& V( B6 v( p---- 2. 位图文件读入所申请内存空间中 8 ]: \% t% t+ d* t, R& y) V/ K
1 d& r D" a4 A \" A! U$ v
---- LoadFileToMemory( mpBitsSrc,mFileName);
% D/ _+ q% R' R( v! Q
: X( \( t( `' | l, w, ^2 D---- 3. 在OnPaint等函数中用创建显示用位图 6 A, N V* x; V
! Y0 i5 r! V( d---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 " C: [8 D( ~2 ^& k/ l6 |
DC,
; w6 Z5 M/ w! D9 u * k0 `: p1 |9 {# k
---- 用SelectBitmap()选择显示位图。
: C5 X+ }" ]; w% p; f9 g ! V* T p1 r! J" c1 g' W6 L% v( z
---- 4. 用BitBlt或StretchBlt等函数显示位图 ( W; m$ d$ T6 D
/ W9 b: n/ b$ T1 F6 ?8 _0 D& \
---- 5. 用DeleteObject()删除所创建的位图 ; Q( Z: k% K2 l* a
m3 T5 Q# o0 t; i1 W---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示
1 M( m4 l q9 o, p时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上( 0 e4 q/ m. Z5 v9 j$ z; A
如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
% g, r5 A3 j- L) y9 B
n' P3 ?' H8 c K---- 三、BMP位图缩放显示
% v! f1 J: A% A3 y/ a g . A! Y. e q& }3 i" A# h2 g* h: y
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
5 A$ Y7 e* ?: ?3 I" }( D$ x进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比
& V# G4 q6 H3 E4 f( f. r! Z图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下:
+ u, e0 N4 m+ b W
/ n U& p. o& z' ?+ g( Z4 e---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
0 }" [. {/ I. p* L1 W- { . S& V; _' K4 @7 A! g$ e1 N( {
---- 2. 申请内存空间用于存放位图文件
% `5 L. p8 t4 H& G7 ^* W+ q e1 a/ C& ?3 |* x4 `+ a2 ]
---- GlobalAlloc(GHND,FileLength); + y/ w' m- [3 _' | Z- B( R+ A+ }7 z' E- _
/ _ c/ F E, j9 V1 ~! u# t---- 3. 位图文件读入所申请内存空间中 6 j2 S3 u" w5 P/ b1 |9 O6 H
( k! d8 p# m$ P( E+ {* Z/ p m---- LoadFileToMemory( mpBitsSrc,mFileName); , q4 d& w& s S! |/ J$ g- a
& s) a, |; E$ b3 O" A" P* a---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图
. j1 a) q. o# M, p$ U) P
6 Y; N( n0 T. ]. \---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中 5 W* d2 G+ n& Z2 S& `; w0 X8 P, O2 T
* H! k# z4 } z1 B8 I' [---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形
. A. j, T! N3 q4 {失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通
( H1 ~, J6 R H1 J' V过直接处理位图数据,可以制作简单动画。
, I2 l ^. c& |4 R- x+ e: H * }- U$ S" X3 \6 m$ w
---- 四、CViewBimap类编程要点 & Q1 P* z8 J6 x1 ?. _
. b1 P% N9 B( r/ E: q; X9 {---- 1. 在CViewBimap类中添加视频函数等成员
: e& r9 i+ R/ F8 z* M
* X; z1 ~- G" Q+ G/ P: x9 u; HHDRAWDIB m_hDrawDib; // 视频函数
* l: L- ]& ]+ WHANDLEmhBitsSrc; // 位图文件句柄(内存)
% \. C1 ^0 j5 E" o: `LPSTR mpBitsSrc; // 位图文件地址(内存)
& z6 m' P& L' U4 JBITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
8 R. `1 N5 o) W# G5 | * ]% D/ ]: `, D9 {$ f9 ~
c$ E+ K q! ?" _2 V
---- 2. 在CViewBimap类构造函数中添加打开视频函数 ! h( }+ @( D$ o( ^7 J/ w
---- m_hDrawDib= DrawDibOpen();
. J. Z+ J+ g: U7 R" w
( R6 |# p4 }! K---- 3. 在CViewBimap类析构函数中添加关闭视频函数
; d" i9 |% s2 |: _+ w " f6 U/ G3 Q' M. F8 R. L/ X: n, l
if( m_hDrawDib != NULL) 7 z: s# |! P6 U! S
{
. E# |% B$ r Z. n* e& s# ` DrawDibClose( m_hDrawDib);
/ o$ k7 C* w. l+ R5 Q; Q: W, Z m_hDrawDib = NULL;
/ l) Y5 v3 ?' n) S" z; [ } 9 b3 O) \1 n# f
+ r( K( p0 l* I
! y/ h. X. P! s2 G6 [: b [# {3 C$ @
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() 2 U, f$ Y. a9 c) m/ a
voidCViewBitmap::OnPaint()
- ^/ ]! B- w4 b{ % ~: W' B3 ]0 _7 _/ m1 l9 l
CPaintDC dc(this); // device context for painting ' ?. V+ H2 L& R9 X7 M: d
GraphicDraw( ); 0 z2 }& F$ _) K/ O, N3 o
}
* T7 s/ S# ~1 D6 O9 }3 m/ r( c ; k" L0 m) i- m1 {. X+ s
voidCViewBitmap::GraphicDraw( void )
9 R$ j- ~4 _' g4 k{ ; y0 g/ C7 ]1 {/ K9 w8 G+ y
CClientDC dc(this); // device context for painting
( p0 k; d0 b1 U9 e& J* m/ L3 UBITMAPFILEHEADER *pBitmapFileHeader;
+ r5 Y8 m) O, o4 AULONG bfoffBits= 0;
0 L% |# n" I" e" N8 F0 D; qCPoint Wid;
5 s! N! ?+ e3 S' H. ?2 M! S ' T7 f: y1 Q4 d- S: [' t( \
// 图形文件名有效 (=0 BMP) + f, A' V8 E( u5 f1 W% x" y
if( mBitmapFileType < ID_BITMAP_BMP ) return;
: c" U9 X9 c' G8 r 9 G5 s) z8 a, Q& d5 [# |
// 图形文件名有效 (=0 BMP)
@# ^$ o+ f. C1 D( ^/ @! Y// 准备显示真彩位图
( h7 q- G) g( w9 v0 @# ]4 WpBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;
, B4 [ E6 ^) u( t& y2 A MbfoffBits= pBitmapFileHeader->bfOffBits;
! Q l0 r) E' K. P) T$ f
/ A: q; L. a1 Q// 使用普通函数显示位图 ( B3 B- H: f. S
% N% Y# V" y$ m2 h) M) T6 k0 O
if( m_hDrawDib == NULL || mDispMethod == 0)
5 k0 d5 s- y+ j/ d5 b5 ` {
2 @, Q1 w" ~7 C+ L9 e8 _- M, q HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
8 d% O, j& p/ l3 L, CmpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, $ W' F* [. l) m' p, r# \
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); - }) ^0 b2 d" g U6 t
// 建立位图 8 h5 w+ [6 l2 B9 t k5 j* r
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存 ! H. H0 L9 a& J" o+ ~$ n+ G
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
9 F6 O9 I7 F9 z% B* B// 成员CRect mDispR用于指示图形显示区域的大小.
$ G- z( q4 I8 v4 t2 g6 G( A// 成员CPoint mPos用于指示图形显示起始位置坐标. 1 K' W7 V" h: b9 ?1 K# D" m5 i, [
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) . n. B9 ]5 u! A5 \! X+ U
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
2 J" x: i" q: T if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) , E/ S [' V: S+ R. r) J4 Z# O
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); $ l6 n; w% p% R! \) r% t
if( mPos.x < 0 ) mPos.x= 0;
' |# |1 [/ @1 z& E' o9 a8 ]4 j' a if( mPos.y < 0 ) mPos.y= 0; + h' o# d, c0 w8 ?# E+ j# r5 K
5 H0 K9 _: k/ y, H7 ^' r4 v, D if( mFullViewTog == 0)
' m3 Q1 l2 A( z- |% ^8 u7 C* F; [{
0 d$ p% n* c) e3 i& {// 显示真彩位图 4 ]& w n3 d+ y, Q2 Y1 K h
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
( Q2 G# ^ w! A& B7 ThMemDC,mPos.x,mPos.y, SRCCOPY);
1 W/ v( h, |: q# M$ n} else {
! g/ }2 z3 D! c- \ v. ~% i4 s::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), " Y. i& }. i- {" W0 e6 C
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
. i7 d0 ~" ^$ f; z+ D( z" |>biHeight, SRCCOPY); ) F3 @# P o( \% d
} & Y6 G" o% ?9 t2 @! O, k
// 结束显示真彩位图
0 K. t s4 r/ e& k7 V8 r : eleteObject(SelectObject(hMemDC,hBitmapOld));
" {" _( K/ E2 C( M6 r- U// 删 除 位 图
7 f# }' b0 l( ?# ^2 J1 H } else { 9 l) D( a. i" p# m% [' z
8 q( \; r1 ^0 d2 q! b; n: Z
// 使用视频函数显示位图 & ]7 m' i" [% ~$ o' _# |
+ k/ D O/ J" h7 B7 P if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
- Q' D4 |! @8 y/ U! E" i8 W2 emPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ; 3 B& @+ }4 j- z( s3 h* E
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
. \$ k0 g& t( n# D5 HmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
) E" t' D! A0 F6 N if( mPos.x < 0 ) mPos.x= 0; " d0 r6 B! D2 G4 i
if( mPos.y < 0 ) mPos.y= 0;
" u& n$ Z' C$ Y; X* @
0 ~6 O! `# v' G) v2 L% n: X4 Q // 显示真彩位图
* W* \: k! W; T: V, k' V DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);
7 @3 I+ y' W" ]+ s% ]) F' T& Z
( B* G& o. m, D4 r if( mFullViewTog == 0) 5 E0 C; ]' u& w, n
{ $ l0 _6 E% ` W* \, E/ A
Wid.x= mDispR.Width();
# z) t/ Z! W! X* e& k* T: x& EWid.y= mDispR.Height();
1 Z) p9 U- j9 I9 T// 1:1 显示时, 不能大于图形大小
9 v/ @& [* B- Xif( Wid.x > mpBitmapInfo- >biWidth )
. i& q+ g) J% z0 qWid.x = mpBitmapInfo- >biWidth;
( a% D( H, L& m( j ? Zif( Wid.y > mpBitmapInfo- >biHeight) 8 Z: t4 T7 H' c: R0 x
Wid.y = mpBitmapInfo- >biHeight;
# B) `6 P0 ]& }; u- B- q$ E1 g. I $ e7 w6 |& Q) b( \' j" U: R
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
$ k5 J1 b: Z J8 v' w$ H) R; e, 0, 0, Wid.x, Wid.y,
, x9 l7 |, c% tmpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), % S( `' o, }, D* T0 n' ?7 |7 S
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); 2 r7 C5 ?4 Y4 w; R0 [
} else { . o1 ~" j; B+ n+ S: p, S2 F: j
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), - D) r- T0 P" U% ~# C& F" J
0, 0, mDispR.Width(), mDispR.Height(), . @# @1 a" b6 V1 X5 D* K: J4 X$ Q9 x
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), ( [( M* H( z7 z+ E$ ~" G% B
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
8 i0 _. t0 V6 I/ Y* p' lDDF_BACKGROUNDPAL);
. }6 |& D1 z- {4 [}
- A0 @1 ]7 c% e1 ~. o) o1 U6 v. D } 1 ~ f# d& X7 B. o$ B! r
return; " W; y" V( o- t! n& r) _
}
4 G& U! Q) d- ^$ q
6 F: E9 O# D8 n+ v5 H2 |
& P7 X( f0 f9 Q: d: {8 s---- 五、使用CViewBimap类显示BMP位图 ! ~6 l U1 R0 ]9 p) v
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC & F4 q/ M8 y) O
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点 8 S2 t; E9 W B" Y
击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目 ) } _6 W$ q1 Q' s0 }
,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
3 \$ ]- G3 y! ^, K+ e2 X' F尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 0 u+ _! s; j0 i3 B+ L
. \2 }/ h% N7 ~3 ?) `6 ~---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project- - r9 S4 S0 R. R" K: B9 f! Q8 j
>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。 " l9 t8 ~2 C0 y
' w+ {5 R6 X5 c+ C1 B
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
3 \) s+ `$ G% ?& a# |) |! W1 LCMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
* ]. G/ y2 Y b. M( M% K1 O- O Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 4 @- y" c" ]- g4 d1 m- u
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 ; ]# p: r4 T! G& f" A1 D8 \
。代码如下:
7 d5 ]1 {* w8 S; K3 D
( b ?' r0 ~2 }void CMainFrame::OnViewBitmap()
& j; u6 e5 j2 \{ ' q+ O3 f1 r9 R7 R, n8 q7 j) |7 V8 c! u
// TOD Add your command handler code here
1 L% @: p, o/ }, M! ?7 j$ a7 wCViewBitmap *pViewBitmap= NULL; 5 _) R i- J9 ~ D1 M
! n% A! |" X. d, R* Y
pViewBitmap= new CViewBitmap( "BITMAP.BMP", this); 4 u, e: u+ W$ W# |& ?9 n
pViewBitmap- >ShowWindow( TRUE); 9 W7 L: N" Z2 Y$ Y5 w- r0 N, A+ `
} " {# z" G |; p; h$ b
; b( Z$ n+ ^. X1 S3 `: _7 L
, l' |9 `% n) v0 g3 g---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。
( q, Z6 Y8 T. C: Q& t" L6 M---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。 7 p3 J9 X' L" f6 n1 {
2 U4 V5 s9 `+ c, c8 o2 k: }
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- > # S, v+ j4 U. Z' b( S7 E
ViewBitmap)即可显示BITMAP.BMP位图。
6 V' S1 V; z' R. [- U
[2 U0 n. ~$ f* u4 X' H+ W---- 六、CViewBimap类功能说明 % v* `, ^' t! I4 j
3 y& z. Z7 X8 [+ L' B* R. n% l
---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可 9 q: s& j, R4 W+ V
以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 0 Q" [1 [4 K5 [6 c% V! m3 q
6 r1 M2 `% `1 t2 Z$ E' v' m---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 2 D3 x, i# p1 M' i# u& b: L9 G
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标 6 T! G1 ?, q! d3 E, d+ e
,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在 4 J9 K/ L3 D( g" }" ?
第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区 : C2 n3 r, m2 W2 g0 ~8 ]% F
小,则对位图放大; 如果位图比客户区大,则对位图缩小。
+ u* A: J( h" D% T$ y) h) d6 w) `9 D P3 C! i+ t* X1 h2 u$ A) @! N
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, 4 H* k' x# r& s
就可以显示该位图。
6 C* ]4 j4 N' Q6 L! F4 O + Z) I6 f! R4 O8 j: h/ {; b6 v
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小, $ |, \, ~$ n/ P8 F
1 F3 F; L) [6 I! |: w5 Y0 R在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图
( }3 S* z7 q+ Z+ L; _放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失 8 P; K* N% B! ?& ~
真小,显示速度快。
3 m a( H& V3 |8 H# x! c " f2 o. S3 P4 ~0 D
---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模
& `! J _! V" F; i式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可 - v& Q6 Z* L- _# w: ^9 j
以体会到使用视频函数的优越性了吧。
9 m& `' F: D8 ~7 _( I/ O" C7 L3 w
4 V8 G( Y7 z6 K& T---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
5 g; w. z) C4 m) f! i: u% b程序中加以适当调整即可,读者可自行完成。 |