|
+ ^4 R4 H. Y- H* \! v
西安交通大学流体机械研究所
; I- x' ^' J+ [+ T) \- ~" H1 y张义云 7 g& k* I' R7 {5 s4 ?
6 b/ s, Y5 B' r: j---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,
9 l4 t+ ~3 s% O1 ]/ t在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数
4 v5 v7 X" \: E# H显示BMP位图,可以消除以上的缺点。
' V2 D+ C- Y* J 0 |) l3 Q7 I4 A
---- 一、BMP文件结构 . R6 b2 i$ D1 v4 S4 ^- l4 U
- z& E/ l4 e8 j5 L- W, a) A$ X9 A
---- 1. BMP文件组成
8 \$ e; K# h. k Q5 @4 Q
1 ~+ d. q, K, X0 t2 [7 Z---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 1 B! w9 b9 p" j3 I# R. l7 B
$ }1 y( g9 {7 U1 [+ N* p2 B9 Y; J" Z5 J---- 2. BMP文件头
$ [. z0 H! S0 P3 c4 S
1 u+ V; S+ n k$ e* `---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
2 g) R- q1 Z% X9 Y5 j。
. \ b% s2 K. u9 @4 I' t
8 v9 J( T& d0 U8 m2 p- j---- 其结构定义如下: 4 ?% ^6 ~" L$ O+ N$ t! k4 t/ Q
& N) S5 G* M8 f7 ^" u: h* O0 e( M$ Ktypedef struct tagBITMAPFILEHEADER 5 Y) b) U4 z+ j# N
{
0 Z! ~+ z! ]) }/ u' S( d9 @3 c( i PWORDbfType; // 位图文件的类型,必须为BM
* n+ c) p" i; O2 z( `& dDWORD bfSize; // 位图文件的大小,以字节为单位
' y7 o3 K! M4 j7 mWORDbfReserved1; // 位图文件保留字,必须为0 ) H6 I# ~8 Y. ~9 y
WORDbfReserved2; // 位图文件保留字,必须为0
+ e# r X; P- {- P# B( l# CDWORD bfOffBits; // 位图数据的起始位置,以相对于位图 . _! B- ]5 n c9 Q# ~
// 文件头的偏移量表示,以字节为单位 , w" s6 V, A D+ U+ k( L3 s
} BITMAPFILEHEADER; 5 u9 Z, C. g* G% S+ Y+ }7 q2 E5 R
8 {7 w* R3 J( t3 @0 w* j% D
5 i- b* P3 I& c; B---- 3. 位图信息头
# i: r6 A3 n S: @---- b( y4 O% f# e' ^& v2 I" r" b( a
0 @9 @# R% L- i5 {7 j* b/ f6 s: ]! UBMP位图信息头数据用于说明位图的尺寸等信息。
$ l% C( t0 r. |: V3 X) J2 gtypedef struct tagBITMAPINFOHEADER{
5 D, G. g' B1 z g( @ DWORD biSize; // 本结构所占用字节数 / P$ c, U4 U+ i; z8 P0 y
LONGbiWidth; // 位图的宽度,以像素为单位
- r% f6 E$ z: s& x* i, x LONGbiHeight; // 位图的高度,以像素为单位 1 f$ P; m3 X+ _4 m( J
WORD biPlanes; // 目标设备的级别,必须为1 ; X$ Z' e5 w- i r$ i7 I5 m
WORD biBitCount// 每个像素所需的位数,必须是1(双色), & m$ _1 S3 |, L! H' T s# G }3 F
// 4(16色),8(256色)或24(真彩色)之一
3 G, V4 k0 r6 X! g9 U+ e DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), 1 j, C; n5 d3 U$ k% ]
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 - ?9 S! r' `1 U# j M; k
DWORD biSizeImage; // 位图的大小,以字节为单位 & a$ Q( D( |: A* v- m
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
" J; H1 [& H7 t3 g" M7 z! l LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
. ~9 ~0 i6 g* h- r5 t DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
& i; Z. Q4 t. m$ e! p; g# H DWORD biClrImportant;// 位图显示过程中重要的颜色数 7 [8 Z: K7 @7 ? _& E: V+ e
} BITMAPINFOHEADER;
) I- l+ i! D0 K5 |5 w
5 x0 V2 ]0 P W0 i8 Z* M$ d" L 9 O. T$ u0 {" j5 Z/ ]( R/ C9 L8 @
---- 4. 颜色表
! h9 F, a4 t6 v3 E. T---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 . x: t A; N! v/ n' y" q1 d
RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
& r$ J( W) A* l6 y
8 d; q: x+ e3 X: a, ltypedef struct tagRGBQUAD {
* j. l) H2 c2 CBYTErgbBlue;// 蓝色的亮度(值范围为0-255) . G, h. G5 j% E4 z! u8 z
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
% W; I) @( n- Z" T& A( nBYTErgbRed; // 红色的亮度(值范围为0-255) / }2 X0 _! }& k" a# N% j
BYTErgbReserved;// 保留,必须为0 ! q) T; j& u& q
} RGBQUAD; 2 A, X/ K. `6 G) }) ~! Z6 a+ t
颜色表中RGBQUAD结构数据的个数有biBitCount来确定: . y) Y$ G, l. l: ~& ^$ s
当biBitCount=1,4,8时,分别有2,16,256个表项; * d9 J# P. O+ {! a2 s- r# W) u
当biBitCount=24时,没有颜色表项。
5 |) n& K" h, d* j f# A* n# Z1 b 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 7 R, h* [6 s& X
typedef struct tagBITMAPINFO {
2 s/ l4 ~. H* D% k1 V9 w' o8 Y' O BITMAPINFOHEADER bmiHeader; // 位图信息头 8 _# U( Z/ W2 ~! o5 R7 {9 I
RGBQUAD bmiColors[1]; // 颜色表
; z* y1 b+ Q* D2 R' [" m) {5 L& {+ d} BITMAPINFO; ' D+ f8 _6 L2 t: q% h
+ d4 Y* ~5 g; C" T! E ' o& y4 o4 o- D' y, ^# ?
; J: r8 E, ], l4 i$ R0 h+ O" A
---- 5. 位图数据
$ c" \( v2 l$ Q& x# c1 C---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 & C; W5 ^8 G- n$ V! E! X
,扫描行之间是从下到上。位图的一个像素值所占的字节数: 9 `& {) h r2 {4 a
2 ?! W1 {" f7 N当biBitCount=1时,8个像素占1个字节;
; q* e) i% J2 Q4 n+ W. [5 r当biBitCount=4时,2个像素占1个字节; & b; K" `' b1 V4 V+ W' x7 U7 K8 s/ X
当biBitCount=8时,1个像素占1个字节;
( H+ C0 k, R! {0 D当biBitCount=24时,1个像素占3个字节;
9 I0 s a V4 m2 g6 a: gWindows规定一个扫描行所占的字节数必须是
& P3 B, @- N4 X0 X+ L. @8 m4的倍数(即以long为单位),不足的以0填充,
+ D% q0 n5 B! C7 f- H! f+ n+ U一个扫描行所占的字节数计算方法: $ l9 c1 t$ H1 R Y, C& V4 i
DataSizePerLine= (biWidth* biBitCount+31)/8; + T* ~+ [# R2 x. ^
// 一个扫描行所占的字节数 8 O$ ]5 @0 t1 s' X0 O8 H3 b5 ~
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
4 y# N5 b- j& z6 Z位图数据的大小(不压缩情况下):
: h- d5 I" |9 c) ~6 v/ W$ b. @DataSize= DataSizePerLine* biHeight; / W; V+ e3 A G" G; o3 I1 N7 W: G7 Y
& X& L3 W9 u0 U) u
2 I) Q! h; @. N3 K$ K8 ]
---- 二、BMP位图一般显示方法
: F0 K, A* _4 Z1 N# _3 H9 w! f& q---- 1. 申请内存空间用于存放位图文件 ' }. e+ A m' l3 n z5 w) _
0 X/ n) {% B- N7 h
---- GlobalAlloc(GHND,FileLength);
# {' w6 {1 m7 o% P, ^/ N1 a
+ z$ E& ]7 M0 d1 ^, s---- 2. 位图文件读入所申请内存空间中
& T$ V! ~+ g1 @% X& ?& h 4 X' ^9 E6 D2 X' B( U: @9 N
---- LoadFileToMemory( mpBitsSrc,mFileName);
3 B7 H4 p1 o4 q% z8 ^7 c 3 U# ?( E' H4 P K, T8 `
---- 3. 在OnPaint等函数中用创建显示用位图
* T4 |3 x6 \/ b9 R 3 {1 [5 r `" |. m+ l8 K
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 # O& S9 ^: ?' D* b- U N: { Q0 f
DC,
7 O0 G$ B: b- }8 d' P
$ e9 t' a4 R* H! |) C! M. \1 x% _---- 用SelectBitmap()选择显示位图。
# s3 G; R6 N, y$ h5 m& f + V4 K, Q6 a, k4 Q
---- 4. 用BitBlt或StretchBlt等函数显示位图
* w* W& K; N, h5 [# S 0 w4 F# X) I& y( f( v% X
---- 5. 用DeleteObject()删除所创建的位图 # [. s1 v" X) K2 H% P$ J. B
* @3 s3 V% _' T& T7 M* o
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示
8 v- E1 g( r5 C* m2 w' k8 |时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上( ; R, n" I7 S3 `, }4 q, V7 r
如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。 % E; c; j3 x& k1 h
2 G, y% L* X& M. u" u$ q& p9 J5 Z---- 三、BMP位图缩放显示
9 G+ N& Z% m& @% t: q: I 9 P) m) Z9 e) i4 E/ r0 ~
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
- f c8 l5 K( b. r进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 0 S" b6 v' i* |$ ~$ X6 m5 ?
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: 0 w1 {9 G8 e6 ^: w7 z& }
* z* ^" l2 e8 P1 X# y; Y& l8 Q
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
" A- p, M- P( |% G6 t9 x- r* l: e ; U6 R5 q/ G( ^+ k9 ~
---- 2. 申请内存空间用于存放位图文件 + l1 r- W2 A* |) t# x" }
! u2 x$ E* ^! F* X0 B
---- GlobalAlloc(GHND,FileLength); : G, K% {% R! L& ]) \" v& N. c: z
8 o+ F& O( |5 |' r" u
---- 3. 位图文件读入所申请内存空间中 ( d" |( t( u( e6 j; V/ D
! N! q$ U; ~& M- B
---- LoadFileToMemory( mpBitsSrc,mFileName);
' }7 I/ G/ i3 X( R7 I
/ j7 K! [9 v* R% X% d% K) E---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图
8 P2 d6 `+ l( Y0 p+ R
! w5 J% H k/ w3 N) p4 R---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
% C. W9 Y+ F0 D" A1 e * y) f2 I- z2 d i
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形
+ z: F* O) X) E' A& L; {) Z失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通
. Y" g) G) T# |# ?0 J过直接处理位图数据,可以制作简单动画。 2 m T5 {9 t! z8 I: y' b
2 H& S3 C, A( `- \---- 四、CViewBimap类编程要点 % m# G, ~( d1 U! w: b, X D. |
8 \1 Q1 R! w* w
---- 1. 在CViewBimap类中添加视频函数等成员
}- s B2 h+ J8 Q- z
: T; q: E. L6 o0 V5 uHDRAWDIB m_hDrawDib; // 视频函数 % b8 C5 z8 Z; F/ e$ |
HANDLEmhBitsSrc; // 位图文件句柄(内存) & _5 B3 p7 r, }1 g' z
LPSTR mpBitsSrc; // 位图文件地址(内存)
# u6 T) g1 K2 EBITMAPINFOHEADER *mpBitmapInfo; // 位图信息头 ; z+ ?7 [. `7 `. [9 x
* G F6 |7 R/ Z" K- o; Z
! ^& ]+ ^. l n
---- 2. 在CViewBimap类构造函数中添加打开视频函数
; C) N1 `' [8 D! b6 i1 T---- m_hDrawDib= DrawDibOpen();
% V) \- X" K! h9 A8 T! N7 ~
. o H% X( b* S: f/ A( _" k---- 3. 在CViewBimap类析构函数中添加关闭视频函数
& I9 d/ W) W/ ^7 C - M* L8 u6 Z! Z) M
if( m_hDrawDib != NULL)
# i$ b. Y0 b4 P { ! I5 _& y- E4 l( h. v, E
DrawDibClose( m_hDrawDib);
: ?. B7 m0 |3 y& W m_hDrawDib = NULL; " k( K. O1 c. V* P
}
+ A9 N. ]6 `& d $ \ J; N7 f# F' d$ k# e
0 s2 |3 }8 O- l9 q9 ]% Y- g/ B: h---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() * K. _6 E$ ^" `( r2 J9 t
voidCViewBitmap::OnPaint() " F! n7 s, N; J6 y# v" O0 Z
{ ( H" `- l% C" Y, A* ]) G
CPaintDC dc(this); // device context for painting
% ^6 j2 n, W( V( uGraphicDraw( ); 9 M7 s) |3 X# s
} 3 ?( G" O! n# I) B% J( D7 r' w* c% t4 g
' A0 c; Y: a3 H9 ^! JvoidCViewBitmap::GraphicDraw( void )
0 b& a7 M. x% E; @& D{ 6 H; r: ~7 L( N$ M: V; N
CClientDC dc(this); // device context for painting
, w- y* F2 l. S: j( Z. cBITMAPFILEHEADER *pBitmapFileHeader;
; v |( j \! \( X ]ULONG bfoffBits= 0; # ` C6 ?1 {2 l L% J* I
CPoint Wid; 3 X: U w5 m& P ~, W
2 v. _' c1 p8 z' ^3 A
// 图形文件名有效 (=0 BMP) 6 V7 O0 j) s' Y
if( mBitmapFileType < ID_BITMAP_BMP ) return; # R, }) {- v& Y; n- M
& ^8 Q/ n6 C9 B3 ]% H) F0 x
// 图形文件名有效 (=0 BMP)
, X$ a* {$ W, ?0 n// 准备显示真彩位图 7 y/ U, `7 p, d, \4 K
pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; ' _0 W2 F& @4 B/ C4 u5 j" d, J
bfoffBits= pBitmapFileHeader->bfOffBits; , s3 r3 x3 b' H+ C* n
3 v4 Q3 I+ m+ t, I. X
// 使用普通函数显示位图
+ X" F8 D2 P' W7 {: t% d$ ^ 1 P. F& x. I3 j n5 E' `. {
if( m_hDrawDib == NULL || mDispMethod == 0)
, {, P& S# ^4 ?3 f$ n/ w$ O6 C D: _ {
2 L) h/ f r, {4 j, K( i HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
6 h/ ]$ \3 O; v& AmpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, & U- l, [: J) v) Q3 P6 P3 y
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); ' O6 H( ]; C" I d: {' \
// 建立位图
9 [( t% w9 Q Q/ M1 W1 G- y0 jHDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存 6 f! X4 v( V' L, P) h
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
" i8 a+ k. x+ p v" n// 成员CRect mDispR用于指示图形显示区域的大小.
. f0 M/ \4 I0 y5 M// 成员CPoint mPos用于指示图形显示起始位置坐标.
- V! C: i* A' A U2 a' h0 ~" jif( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) ! K h, M; S# [, m. N
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
4 E4 ?# `: X7 t8 V% \+ o N if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) 2 o1 g# I( P3 o0 M* ?
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
' Q; i- j' b/ ^5 E# P! }- S if( mPos.x < 0 ) mPos.x= 0;
r0 J1 ]2 @! q if( mPos.y < 0 ) mPos.y= 0; , B! \7 W: O$ ]4 r% u/ p9 c+ s
8 @9 Q% ^8 z7 E0 D7 p+ d+ p8 @1 c if( mFullViewTog == 0)
6 W( x1 U, D# ^" j{
# Q5 h" j p% Q& j5 \! U// 显示真彩位图
/ o. c& n; {/ {- j$ P/ O/ R::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
1 e9 G5 h# v8 x. d( z5 }hMemDC,mPos.x,mPos.y, SRCCOPY);
" a, r a/ `8 R3 c- H9 P} else {
& K( N+ \; d' _) N0 s. S::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), ; i: x, D( j$ R2 [& z
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo- ; ^! ?2 q$ @! o0 i# P8 j1 I; P
>biHeight, SRCCOPY);
! a1 t3 N/ b/ z3 M}
\. `# l3 H: }7 D4 M P // 结束显示真彩位图 # s; \1 t5 p$ Y1 f! y
: eleteObject(SelectObject(hMemDC,hBitmapOld)); ! R- Y/ u5 i( O+ {
// 删 除 位 图
, A4 ]8 |+ J# D7 F3 |/ x0 G } else { . E5 N( M$ W' z( n9 K5 h
! b2 T% y7 l0 a3 Z* `3 m- w // 使用视频函数显示位图 # {8 y7 \6 B5 q
/ p( a% a, d: J, I9 l if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
5 V, O" L% X$ FmPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ; # K6 R& o. L H8 \+ |
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) # {+ e) \) C9 g) o
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
0 O @, E" R% `/ y7 U& z D if( mPos.x < 0 ) mPos.x= 0; % k# z2 ` e7 s% [
if( mPos.y < 0 ) mPos.y= 0; $ l0 _/ T0 O3 @. o1 o& X, f
2 p# l( E9 c7 a; E6 f! B Z // 显示真彩位图 ' L. E3 m7 x6 `7 \6 G& T, o5 c
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); 2 ^6 s; `; B$ G
* a$ U8 \, M9 b) z% ?9 g
if( mFullViewTog == 0) * P$ L+ `. R/ ?+ h6 c% C
{ 9 K4 @. m, n9 o- t
Wid.x= mDispR.Width();
& f/ {; e' E: L8 O. ~( _; ]Wid.y= mDispR.Height();
% r5 @0 r& H% {1 N+ S4 j" T// 1:1 显示时, 不能大于图形大小 - K$ [: S9 ^1 C4 L; e5 F. C
if( Wid.x > mpBitmapInfo- >biWidth ) . {. ?& i# {: _& ?0 k3 d; E
Wid.x = mpBitmapInfo- >biWidth;
4 G' {: h+ r% X' l7 H( W* e/ jif( Wid.y > mpBitmapInfo- >biHeight) 0 j' \' b% b1 \ u
Wid.y = mpBitmapInfo- >biHeight;
8 E5 t8 J2 G. t& [
5 i5 c% b# z1 N% q" q, B! zDrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
# h d }* a0 E+ u" e, [, H: E, 0, 0, Wid.x, Wid.y, ! \5 u7 n9 I+ c V9 a
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), $ d* f( y* r G( ^ S- h
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); 5 }4 s1 z2 \" [/ x( P' M% X1 ?8 q
} else {
" l7 E9 b' X* S8 ^6 w5 G' v5 |DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
# T% \4 Z0 F0 M! f3 d0, 0, mDispR.Width(), mDispR.Height(), $ M+ S" D5 Y: F d$ e) F8 X1 R' ~
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits), ' e, p. g1 U7 ]% Q3 D6 j
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
0 [, G. v8 O6 BDDF_BACKGROUNDPAL);
) d' ^- L B" B* q: A/ h6 n D} 1 ? N1 x& k. y4 y2 @) `- Z
} / ?) w" C6 v* S/ _7 j, E+ N
return;
( q. y S) Q% {} 2 u2 k4 p1 a! i& \. p4 s6 N
3 f& D2 q$ X4 w- N
2 |; p( y5 @. P9 [& z5 e5 V---- 五、使用CViewBimap类显示BMP位图
9 n- R$ y0 E; ?---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC
% }0 D& L' c3 b b8 \) cAppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
) r- `( r7 k, y1 {- R3 Z击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
2 L. S9 _" T& F& }7 C,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
, W, {/ H( }0 @$ C1 D6 z$ I尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 + M# K8 d7 t* s9 Y* E
. l" o, `/ ]1 {* @1 L( L" A
---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
/ Q7 T6 D i, }>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。 3 [; k7 P" ?; u7 V' h1 s( H7 Z; @
* F- x3 S5 K3 g0 ]- s+ W
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为 8 S: ~4 K! I0 C, |3 p8 n
CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
8 S% R/ p9 D, W) X Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 / q0 r+ n/ i0 Q0 `. ?3 M
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 . n z( `6 k; p u5 p: Q
。代码如下: , T9 b. R& _1 Z; P
5 I7 b* N2 `; W2 N) mvoid CMainFrame::OnViewBitmap() 7 W0 D- `5 l' c' d! h5 H: G
{ . H9 j2 t( \5 t6 r' w
// TOD Add your command handler code here
. c, Q# k$ x. W( `$ F' tCViewBitmap *pViewBitmap= NULL;
4 l2 ] W7 g2 {7 S `3 I) E9 c! A$ w
pViewBitmap= new CViewBitmap( "BITMAP.BMP", this); $ j% E2 R2 g. B: J/ C5 m
pViewBitmap- >ShowWindow( TRUE); / r0 [9 r% r; @3 z
}
* x; `8 Q$ B5 ?5 |$ n& }4 }- L " R% m, e: y3 {- Z
% y" K9 N- c; l C6 i8 `---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 7 q7 D9 n) T; x' ^9 @; M/ D0 ~( [
---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
5 F) b4 g) K; ]- U+ b8 }
4 b/ f1 V8 }4 C---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >
1 x; B" q2 q1 ]. e) _8 H: J3 v& _ ViewBitmap)即可显示BITMAP.BMP位图。 # I6 p. W% W. u# j( k6 w
/ O1 a1 U+ x( Q i9 z# e
---- 六、CViewBimap类功能说明 8 E9 u' e$ Y* b. k3 E$ I
7 y1 C, _5 |% o) i6 w
---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可 3 M) B' c( Q0 c1 n0 F m0 g+ N
以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 , E9 N( [0 t1 r# y* S/ E
7 k- E; @/ x, R6 Q. @, C---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为
. g7 _' o) [4 G, D位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
: c4 y- ]! u* S( S* a' `,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在 " f5 h) @7 @0 u0 o" [" |( d- T
第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区 5 G1 |) V% b# W: T J% I
小,则对位图放大; 如果位图比客户区大,则对位图缩小。 + `6 e* n3 f7 w# u/ I& e2 f
$ l5 p, Z6 U) _
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区, # h8 A' P, g- S: r! t
就可以显示该位图。 " k) |1 X y' H8 k# c4 T" s
9 _, x8 _" A1 f) s$ C6 y8 \& w---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
; c% b5 Q* L& q4 L2 w3 V' [5 f7 c2 t3 e5 E" u( i7 _
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图 ' n* n5 h# `3 C% C& x. `( @
放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失
* P5 g1 b2 z$ i真小,显示速度快。 + H' f/ x$ R O* o# U
9 g0 h( _0 W, u/ P# z
---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 m! O; g, E: g; n8 k+ x
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可
9 J: @0 n9 i7 j+ W以体会到使用视频函数的优越性了吧。 4 r% o+ d+ T% @- `9 X" {$ s* x& q
: V" C, J8 V& l---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示
/ X8 s# V" l {% _+ ^# M- q3 q程序中加以适当调整即可,读者可自行完成。 |