|
. c2 S4 S6 k E- h$ k2 z+ { z. a3 J西安交通大学流体机械研究所
7 X% d, c0 _ J! [8 f9 F Z/ K张义云 9 A) g& n- @4 {1 [
; W/ I9 x- q# X, o8 d. B
---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
. d0 Y7 y( J* |在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数
& G" o- I) s+ g. c! o% U6 j% ~显示BMP位图,可以消除以上的缺点。 O4 E. u6 v$ P# Z
5 T2 I+ Q. |% s, I u& o6 c---- 一、BMP文件结构
% @0 \5 O' V& D1 O
?" _/ t3 w. y5 c---- 1. BMP文件组成 + Y q5 L9 \; z& [! Y4 I& R
& y3 a& L+ j: Q. O7 ]
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 9 c/ ? a: @$ F; ~+ @ V/ T
% Y e; }' ? y; ?, k r' {9 D---- 2. BMP文件头 . b) I' o/ |+ @
$ `+ ?( v4 L# b% q---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
, Z! D- Q: ]0 Y0 C9 C& ~) ~) b。
0 `# t" R! A3 M# x) z, n# p
, K) p+ `: Z1 M---- 其结构定义如下:
7 n" r) b( l9 x4 v' U3 [ 5 x6 ?0 d4 b7 _0 @3 p4 l
typedef struct tagBITMAPFILEHEADER
2 ~2 k1 p; j/ G- @# l{ 7 \9 B# ^( E, H
WORDbfType; // 位图文件的类型,必须为BM
0 P: S! `/ f) d6 `9 F, lDWORD bfSize; // 位图文件的大小,以字节为单位
! z& R( L6 N6 G3 x- JWORDbfReserved1; // 位图文件保留字,必须为0 ; u) m1 |3 n3 y' a
WORDbfReserved2; // 位图文件保留字,必须为0 2 n1 J% G( M+ ?7 A2 ]- u) |
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图 2 q8 ^& F2 `& f4 F i
// 文件头的偏移量表示,以字节为单位 4 d J) r. u+ r4 l- y w
} BITMAPFILEHEADER;
k7 b6 |( J8 s8 o' b s2 K( \. {
/ N: B' K! C% f
; `1 X5 z, G" V% a; D7 F1 [3 J---- 3. 位图信息头
9 |/ W# @, |; ? N6 U----
1 y. H( g9 I3 W
. L: Q9 @1 M( Y* |BMP位图信息头数据用于说明位图的尺寸等信息。
. H2 E4 ^1 \# R' u8 T7 h' Ftypedef struct tagBITMAPINFOHEADER{
! [% _: a( K) ]& | |, i2 S DWORD biSize; // 本结构所占用字节数 + d8 {, v0 A& C4 L: [
LONGbiWidth; // 位图的宽度,以像素为单位
2 y( V2 ?' ^; j* t6 {+ ] LONGbiHeight; // 位图的高度,以像素为单位 ; H8 k1 c( O$ ~: a
WORD biPlanes; // 目标设备的级别,必须为1 ! W0 G! B; N8 e3 X- @ K# S: s& r
WORD biBitCount// 每个像素所需的位数,必须是1(双色),
; l+ N$ g) Q& K% _ // 4(16色),8(256色)或24(真彩色)之一 6 D8 A* m6 r6 M
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), 3 f; r T( }9 l4 l, `! H @
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 * @$ }0 |) n* g! w9 H+ Z
DWORD biSizeImage; // 位图的大小,以字节为单位 2 R: a! `6 k1 a2 N# F" ~% G
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
9 N3 T8 P& h9 _: A$ {0 j LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数 6 T# q! K7 | g5 m" k
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 ~6 `# A. P" q$ q, b
DWORD biClrImportant;// 位图显示过程中重要的颜色数
, c+ R5 H1 w+ ^0 Y/ Z: S} BITMAPINFOHEADER;
1 C3 t4 Q, j4 Z& w- W " j. f$ R1 p8 Z/ E+ w1 j6 h
" x0 x1 T% \; O3 }" r
---- 4. 颜色表
$ r8 c7 F1 ~" o$ ]0 \. `& k---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个
) C# A; G9 B' Z7 x# yRGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: * O+ u6 {* e/ a3 ^+ W Y% Q4 w b
" h _, g/ R3 E$ S4 C4 b. \5 ttypedef struct tagRGBQUAD {
9 ]4 q6 u8 l/ n- J% jBYTErgbBlue;// 蓝色的亮度(值范围为0-255) & L4 D3 x$ f! ]9 _% A# b
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
$ g& g4 [* a1 C) LBYTErgbRed; // 红色的亮度(值范围为0-255)
. d+ N6 p. O( I4 G CBYTErgbReserved;// 保留,必须为0 6 [0 z2 W( C, s- D, a4 G: n
} RGBQUAD;
3 t$ j/ A" d$ \# ]* q5 p5 {颜色表中RGBQUAD结构数据的个数有biBitCount来确定: ; ^( V. f3 g) S) J0 A6 D
当biBitCount=1,4,8时,分别有2,16,256个表项;
) W. I/ W- a D& E) g1 d- B% J当biBitCount=24时,没有颜色表项。
/ q* F" o+ E8 O5 [0 L 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 9 U8 K$ @+ Q! n) |/ {
typedef struct tagBITMAPINFO { " _' I% l' q1 n
BITMAPINFOHEADER bmiHeader; // 位图信息头
1 n+ Q2 S) y. T2 n( Y3 k! I RGBQUAD bmiColors[1]; // 颜色表 [% h4 K1 L3 j7 k
} BITMAPINFO;
0 c5 u, w8 K1 D7 Q4 U( t& @, k% j7 U
: w- \1 O3 P4 Z7 r& @( X. E/ A! Z 1 h! h% r+ u% D- b! ?
4 C8 x& B5 u* Q8 [, n
---- 5. 位图数据 1 `" @+ \+ Y2 S3 u
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 4 [3 U7 W, L: y0 Z' @" ^4 O+ P
,扫描行之间是从下到上。位图的一个像素值所占的字节数:
6 o) H* z4 A, [* U6 b7 U( s/ O1 A
8 |- U) `- H: w( i( B当biBitCount=1时,8个像素占1个字节;
, U* |7 ?: ]3 G2 l6 n0 R. U! v% X; T当biBitCount=4时,2个像素占1个字节;
5 z. J/ V- K T3 A+ I当biBitCount=8时,1个像素占1个字节; ) K. n6 }. U7 x# D+ P# ]# o c8 v
当biBitCount=24时,1个像素占3个字节; ) o% _. f! {, M. p, g& a9 ?8 J
Windows规定一个扫描行所占的字节数必须是
# ]+ G$ [$ v% x+ E7 C2 u& v1 F4的倍数(即以long为单位),不足的以0填充, ; @# g+ E7 |& B8 W
一个扫描行所占的字节数计算方法: 4 g9 F+ m) z$ Y
DataSizePerLine= (biWidth* biBitCount+31)/8; 6 u8 c0 `9 I, t- n7 H( m. N$ ?
// 一个扫描行所占的字节数
8 c" x2 O: l' U+ f5 r2 CDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
; x+ s8 u7 @; T" u! D" c* u位图数据的大小(不压缩情况下): - ~. H% z" |8 X9 E; z0 X' t
DataSize= DataSizePerLine* biHeight; & N" t6 E X. m$ L- k8 m! x
3 Q4 f3 J4 r- T, B( |7 f
9 ^6 e0 y" ]+ R) \; w3 @% v) ?---- 二、BMP位图一般显示方法
@8 [+ J" D+ _---- 1. 申请内存空间用于存放位图文件
6 N/ |* l. E: o) z. l 1 _: V) _; ^; H5 H5 T& G
---- GlobalAlloc(GHND,FileLength); + r. M. O3 _$ P; ]* x
: B* d8 X4 j/ U8 V( z8 l, m---- 2. 位图文件读入所申请内存空间中 3 f* h" B" i$ J T8 t) W' H9 ]7 {$ n
% w0 V+ O; \' X; `- U$ }---- LoadFileToMemory( mpBitsSrc,mFileName); - A2 W* L! D& p8 \1 N8 g( K1 E( d
+ J% ] z! e) O" F/ @---- 3. 在OnPaint等函数中用创建显示用位图
5 u3 u, } q1 o* j. r) Z
$ `0 u; Y3 p4 w+ B$ L---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容
" u) l# N! Y7 d, v: `2 eDC,
" [/ [5 ?, [& L6 U w8 X* x8 t/ Z6 H' b- | C6 k
---- 用SelectBitmap()选择显示位图。 ' B. b* X! t6 P$ V5 X' u
" b4 `. d0 h1 }0 m) o# p% n& L
---- 4. 用BitBlt或StretchBlt等函数显示位图 " j; I' K" A' k) W" {
: M- T) l9 P2 `$ E% x
---- 5. 用DeleteObject()删除所创建的位图 ) i) d, V, Y% |8 K( w
- \- v' F: J# @, p I---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 7 {; t8 g& T. P
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(
& u9 ^' ]6 @. l+ p2 [, t4 I- Y2 A如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。 ( o. N. r1 Q) s2 k, k
; A T9 C0 G$ M: @---- 三、BMP位图缩放显示
) G) y* V/ n0 `% o- a* A- j+ A7 G / o# r6 h* x5 c" w- V" N
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形 9 z: D! H: _8 s9 U$ [* z
进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比
! ~, S! ]; k+ n图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: & {& v* m' L$ r; }3 b1 u0 [
: _& r) x; j K3 p+ E+ ~: a! M$ _---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
+ k0 o3 C, P1 ?3 l1 }0 ?% x
/ _8 A! ], Q7 C! y& U/ h---- 2. 申请内存空间用于存放位图文件 7 Z L) R; j- e9 W H. Q4 K/ Z5 m
, r. ^ [/ R1 c6 g
---- GlobalAlloc(GHND,FileLength); H/ X7 Y5 c ]5 d; U
# _4 G9 I- G, _9 ?. d9 x---- 3. 位图文件读入所申请内存空间中 ( p. `( j# R# {+ b5 K1 g
. B; R2 v6 d( b. q4 b' Q---- LoadFileToMemory( mpBitsSrc,mFileName); ( {, ` u7 m7 x: _ d/ v) K( T# c! U8 O
6 d# W; N9 y) x9 l$ W
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图
6 a5 W' j6 L& [& @3 O1 K/ X$ P
$ c& s7 E) \0 s! d% w/ A5 u- {3 X---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
' V {1 i2 n! ^. d
- `- j0 T$ T/ ?, B1 t5 I---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形 - {$ m/ c( Q9 @( X# C+ m( \. V
失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通 # y N$ [5 u; q, A+ _( p3 n
过直接处理位图数据,可以制作简单动画。
0 C) W, v) j& h! @* h8 r
: b; S1 z% l$ K- M2 m. e/ Q---- 四、CViewBimap类编程要点
8 T, w* f( y3 Y, j
8 M' v( W' B9 i9 B& S' l---- 1. 在CViewBimap类中添加视频函数等成员
! f- I: Y# _; F. Y d; W$ F1 T8 u: M: N
HDRAWDIB m_hDrawDib; // 视频函数
7 L; F' M( f/ L# ZHANDLEmhBitsSrc; // 位图文件句柄(内存) }1 N) P! X* D1 J- A/ ~' p+ I
LPSTR mpBitsSrc; // 位图文件地址(内存)
- Q& R ^0 o8 G- YBITMAPINFOHEADER *mpBitmapInfo; // 位图信息头 . i }) ~9 Q3 l- O
0 e# f/ y" e% `' F% a4 K
/ Y+ H2 C: \4 W---- 2. 在CViewBimap类构造函数中添加打开视频函数
3 \1 @/ W. K% K* Y5 i---- m_hDrawDib= DrawDibOpen(); ! j8 a2 S9 G/ {9 [
) {$ }3 o7 R+ ~$ w---- 3. 在CViewBimap类析构函数中添加关闭视频函数
1 a% b! A# w! L2 b
1 ~% g# w* k0 s. g% K5 yif( m_hDrawDib != NULL)
- k* C& ~9 ?: J& B: Y { 2 |& m+ y+ x7 E) Q
DrawDibClose( m_hDrawDib); # i6 Q% L, T$ r( |9 I
m_hDrawDib = NULL; 1 g1 f( o/ i& D; E! n9 c9 J
} + [8 W5 e+ W' j: [$ p! U
3 W) I/ \, q- | ] 6 @0 [" B! d* U `6 W4 @
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() 3 \0 {. ~5 B0 y" D4 I1 L
voidCViewBitmap::OnPaint() / o7 R: O$ j6 f+ p
{ - g. }2 R3 R, e* h2 i. {) H! u
CPaintDC dc(this); // device context for painting
9 _4 A) v" A/ w4 ^7 c( c% H! mGraphicDraw( );
2 N% B% i- e' }3 h/ h} 4 I z# d* L7 ]9 g) b0 q& N, J
, w# D9 C1 d( C0 _; A
voidCViewBitmap::GraphicDraw( void )
9 G3 {& T3 u% [" K: X8 {{ ( R0 d+ a( Y+ P/ z
CClientDC dc(this); // device context for painting
) ?& k+ B6 r. |2 M; w6 a4 uBITMAPFILEHEADER *pBitmapFileHeader;
( m2 A+ o1 ~" Q9 z& ?2 m. BULONG bfoffBits= 0;
8 ?( H0 B0 `2 _6 ]CPoint Wid; 4 C7 B' G- C& B; ?; P( }
7 X1 Q( D5 i9 w" d
// 图形文件名有效 (=0 BMP) % U7 |' B8 b/ B
if( mBitmapFileType < ID_BITMAP_BMP ) return; ) z C: F+ r) f
8 c( H5 K" b# X" b2 F: g) t6 A8 h// 图形文件名有效 (=0 BMP) 4 {- d- y/ N5 I
// 准备显示真彩位图
5 N. h3 _% b! l4 k, F$ }$ RpBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; - w2 g r' e( o7 Q
bfoffBits= pBitmapFileHeader->bfOffBits; # J+ A3 G2 l/ e$ j1 U" ?8 S0 t
9 L* D% y, ?3 {7 y// 使用普通函数显示位图 ( j/ n; R8 g8 o
0 T' F( j- _" y$ P% A6 Fif( m_hDrawDib == NULL || mDispMethod == 0)
8 I9 H2 Z* y. F$ p. M' m {
; S! n: ^* Q5 y& T- e" h. q HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, 8 c7 T7 X7 L/ u9 L. B
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, 7 C% l. c. K/ [& |5 l1 @5 U
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); + |* [2 z7 h( j- C/ [3 l
// 建立位图
5 G2 F" ?# O1 T7 l* Z. QHDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
7 d. e+ e2 v# ^+ v3 Q# h3 q4 JHBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
; J2 \, X% l/ s// 成员CRect mDispR用于指示图形显示区域的大小. 1 o) f" p, c# g8 p- `5 ~$ [% X7 N
// 成员CPoint mPos用于指示图形显示起始位置坐标.
1 `1 q" ]7 Y- fif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) ) ~, S3 R& Q4 Q2 O
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ; 0 p' R% b8 i4 {* N* d! x
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
) e& N; T0 Y# N- d- C" M$ xmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
: F1 t/ G" T2 _. ^6 F if( mPos.x < 0 ) mPos.x= 0; - X, G! h. y5 {4 q
if( mPos.y < 0 ) mPos.y= 0;
% S# R( k6 `3 q" @* q P0 Y6 ~! ?8 R* [
if( mFullViewTog == 0)
* @2 h8 s# [% H. H# j9 t{ - H0 O1 J/ T1 W$ v5 L- h& q
// 显示真彩位图 % A v' X& |; x- P3 K$ W
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
/ C2 e! A+ \6 \1 b! UhMemDC,mPos.x,mPos.y, SRCCOPY);
) d* G" b/ Z7 |0 p5 h} else {
! Y( @; c* t1 V::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
) D$ `7 V+ w" t4 o* s+ o7 ThMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
. j' }9 ~3 K0 o" K>biHeight, SRCCOPY); , C! J0 ?5 s/ E* N+ G4 {3 p
}
9 S8 J; x, s2 N5 a, R+ B // 结束显示真彩位图
: c7 t, h8 D7 P; s4 d9 z' @- E : eleteObject(SelectObject(hMemDC,hBitmapOld)); , p8 Q) Y- `8 p; ~
// 删 除 位 图
# L% {6 h/ M% I3 _ } else { 5 ? ^: I5 `: n. p- j
" X6 [! S) m7 l1 l
// 使用视频函数显示位图 + e+ Z; q- p& L9 K& X2 e( E) R# f( \
) q$ W% t- [3 { if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) 0 k* h, {$ n' s. D
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
5 f# G: \* u0 E# I# {: s% X7 J if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
" _/ ]5 C0 B( N! S5 d: X) k2 ^/ ?mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); + `+ I+ _" d% L9 z* K2 S2 C+ R$ n
if( mPos.x < 0 ) mPos.x= 0;
7 u3 u" }. C7 X if( mPos.y < 0 ) mPos.y= 0;
$ A9 H0 S7 z- P 1 @- o* W9 P4 G- J$ t/ S2 N2 w
// 显示真彩位图
( t! I' O, n% P5 m% w* s" W- S DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); " W7 h" j& t5 x9 H% \% K
4 P/ D* _$ `2 E8 y, S2 W. b; v if( mFullViewTog == 0)
! N( t7 k& l5 @6 z% I) M$ ?% J% k{ : I7 b+ ?0 I* Z' @' q
Wid.x= mDispR.Width();
: m @& M: x7 |1 ~8 N5 E: ZWid.y= mDispR.Height();
- ~2 W4 D* w( `- L. D// 1:1 显示时, 不能大于图形大小 % e# x5 G& w* A) {2 B
if( Wid.x > mpBitmapInfo- >biWidth ) 1 p3 `, P/ v- v; {; A
Wid.x = mpBitmapInfo- >biWidth;
/ {5 J3 V) O0 I& H& V& m$ y1 }' kif( Wid.y > mpBitmapInfo- >biHeight)
( _! _0 H0 p; t7 u" j& v* x0 w4 SWid.y = mpBitmapInfo- >biHeight;
& ]9 W; l% ]8 Y- S5 T4 T; x: \
6 ^0 d6 r) Q* b8 K+ W' xDrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
) P& ^& b* ]8 e; M8 q/ e. ]0 ], 0, 0, Wid.x, Wid.y,
6 Y" U: N7 {+ M* B8 ?0 s% qmpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), 9 J0 q6 }1 H p
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); 2 y S" w3 a8 H$ F2 h3 j. S
} else { 4 h j5 I8 N/ Z1 o; w
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
8 o3 U4 i2 {2 H% W) K) e0, 0, mDispR.Width(), mDispR.Height(), ) b" g; Q$ N' \' w% }/ @: {2 W
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), 8 Z! ^8 d. \% |3 z; U8 x# A. g. E
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
. }2 h- J- A) t! x2 w, ]; NDDF_BACKGROUNDPAL); & Y" O: Z4 e5 z$ d: ?9 E+ s
} 0 p9 p" Q! X+ v4 ~: O
} * L5 y9 d& @4 \4 l U
return; * T; u( n5 P% D' i# ~! A4 j3 i
} 0 g: N: {1 B& m3 R2 Y
4 h( l" R' y7 \- l
5 W9 q9 K9 G4 \---- 五、使用CViewBimap类显示BMP位图 ! P3 l; c( L1 |6 Q7 A8 K3 R2 E3 a
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC 1 }% ]3 h. q1 d$ g5 C( x) A
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
0 L; `, C8 I/ L% z0 b7 G/ x6 p" Q; A击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
# O+ f) ?5 T3 [ Z3 k% j,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的 1 I0 Q; }" N& G1 G: z% H; D
尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 0 a0 k& d1 b: ?; f
# s& Y, R- y& f2 O* Z---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
2 F! m' B- a& B>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。
! b/ T5 \. z% L
[( g3 i7 a2 z( Z5 l+ P1 a0 V---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
6 ]- x" y7 p3 m$ lCMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
% m6 a, q! a3 j Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在
- W) Y9 a! C* |- JMember functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 " Y% D1 X4 D E' e
。代码如下: - Q: [4 A0 A7 }
# H7 @* h+ {) e- ~% ^, K
void CMainFrame::OnViewBitmap()
" B- Q9 v0 c4 X{ 2 C- J f- K ?
// TOD Add your command handler code here " F4 ^) o: Z3 x
CViewBitmap *pViewBitmap= NULL;
' S& _, W3 y; d5 w0 Q3 m 2 P" e5 H+ Y# {% k0 [
pViewBitmap= new CViewBitmap( "BITMAP.BMP", this);
, A) D8 F; B# l% EpViewBitmap- >ShowWindow( TRUE); ! t1 c1 a7 m j) C s7 i6 k0 [
}
* i# y, ~8 K$ A9 B3 x" x: ]8 ?
5 W/ z6 `& _1 e8 F ) Z$ W# [' |3 \( ]
---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。
4 P/ ~8 j1 A8 y3 A7 H$ X! A, |---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
2 R4 t5 T* H/ m# [- [ # v$ t: z A& ^3 w5 |* h
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- > ) b. F: I6 ~. [# [
ViewBitmap)即可显示BITMAP.BMP位图。
2 ]) Q( [5 K( E- b) \ $ Q. }0 s; b- r Z! _& p b Q8 o6 Q
---- 六、CViewBimap类功能说明
" N4 W3 O* V! L, ]' T5 Q) \' A
B6 h3 W. i- g2 S5 x---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可
$ Y. N, C' N) m6 M以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。
I/ W* [ V) W6 q* X" r * Q3 V0 d" N$ q2 t- c9 J
---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为
P! P/ ~( C' K& L7 N" ?( f位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
; z( h1 W- h( j8 d; l7 d. {,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
+ `* ^; a5 L1 z) V) U第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
' l4 J4 w2 T! Z小,则对位图放大; 如果位图比客户区大,则对位图缩小。
2 s# V6 [+ k& r$ K, M
4 ?6 x) ?3 U. i, w1 J---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,
' F; H1 I6 p: U! P- f3 Z就可以显示该位图。 S0 f: S( D. N0 v4 T6 ]5 `5 z
) p5 D- z8 j* Q$ F---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小, " d" Z4 C; ^. \* y
7 \5 ]2 `3 t; ~3 U) ]
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图
) ?: y( w% j" l放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失 : B9 V& J1 P% s* F* p2 _9 O" H
真小,显示速度快。
3 Z% A. d% w" l% | 7 Z, g- {+ k" @- H
---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模
' F6 z! e- {5 F式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可
' R& I' `# w1 s9 \8 E _- e/ {以体会到使用视频函数的优越性了吧。 2 O2 @9 G; ]. G+ _' s# x, t3 B1 C) I
. d% Q" \3 [5 P4 k( R5 x
---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
7 A; y) A d" M) V q程序中加以适当调整即可,读者可自行完成。 |