|
m4 O: D& B$ ^: V西安交通大学流体机械研究所 , l: `% a' o8 J
张义云 % V3 G* u" Z! y! x3 ^9 `$ p8 a/ ?$ y! D
8 b) ]: Y5 ^' r---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重, & Z4 g$ \) M/ Q& F7 C
在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数
; s) m# r5 c5 T) o( p& n/ x) W显示BMP位图,可以消除以上的缺点。
1 E0 g( `3 W) m* m: N+ R, z) B; [ % M+ M8 F1 X3 R
---- 一、BMP文件结构 5 @" I/ ^0 {% v( ]
( h& Q. T. \4 ]" J---- 1. BMP文件组成 ! m+ J: Q9 R1 Y& |# L
5 V' c$ {# U- p X. t2 I---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 + C0 N$ ?4 e/ s) H- V3 [, {" G
: Q: [5 @* t3 N
---- 2. BMP文件头
5 W3 w; q/ F: l5 F/ _' {: v
( |, t4 o; s: y2 P8 n+ x. l* o---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
/ m5 D: D& d/ E2 k' g。
1 `# F- V2 M1 [) n1 P
9 Y2 q1 N% W* p7 |, L. E---- 其结构定义如下: * I( ~ `% r! Y( T) b
% R- J! m; `; [+ _( ?typedef struct tagBITMAPFILEHEADER
- d; W6 _) ]( P. Y- L* m q- F{
8 T: Z" _# J# A8 l2 }* d0 x1 lWORDbfType; // 位图文件的类型,必须为BM 7 r2 ~* Z6 ~: Z
DWORD bfSize; // 位图文件的大小,以字节为单位 * ~8 M; c& g* s* y
WORDbfReserved1; // 位图文件保留字,必须为0
# q& j( G* k' OWORDbfReserved2; // 位图文件保留字,必须为0 % ?, Y8 c5 A5 A9 O1 I0 ] @' w
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
9 ^6 S4 y8 J2 p7 l1 a// 文件头的偏移量表示,以字节为单位
% w7 ^2 I0 C0 m' v* x! G# w} BITMAPFILEHEADER; * X5 F8 y" N9 L2 ^. l6 @& I6 ]
7 a1 l+ \5 b' G6 e- M- S2 u 1 [7 K" \# g! S. ?4 T# n& [
---- 3. 位图信息头
2 z: v9 x* ~& s& ?# a, A7 T2 c----
$ D, L# B/ V; \, o) ` ; x6 T7 {% q9 @# }6 u6 _; Y
BMP位图信息头数据用于说明位图的尺寸等信息。 # B9 Z6 F5 c8 ~- C
typedef struct tagBITMAPINFOHEADER{ 2 L8 A: R1 T! U
DWORD biSize; // 本结构所占用字节数
. E; i+ ~; F8 B7 q LONGbiWidth; // 位图的宽度,以像素为单位 9 ^, C8 g4 w( a# ^
LONGbiHeight; // 位图的高度,以像素为单位
1 P# J+ g O/ l' {5 K0 b, S6 ^ WORD biPlanes; // 目标设备的级别,必须为1 0 \+ r5 p; i7 c( I
WORD biBitCount// 每个像素所需的位数,必须是1(双色), ( e+ j" s! c6 |
// 4(16色),8(256色)或24(真彩色)之一 " A0 V' E# G2 O6 Y# t) H
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), , S p- i5 G% b7 ^! o
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
6 r- d* J4 a- c* @% S DWORD biSizeImage; // 位图的大小,以字节为单位
; }/ s/ Z9 b8 {5 N! f LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 " k, s, C4 O0 B1 @; \( f# f
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数 # e8 a* J: |0 N7 B0 X# O2 L, N
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
, c& y$ f3 n! Y DWORD biClrImportant;// 位图显示过程中重要的颜色数
3 ]) E) k8 M v} BITMAPINFOHEADER;
9 r6 f; k7 v z; Y3 T
" x: Z; P6 I5 s; s+ _
4 ?1 d8 c0 n7 f6 a4 j3 D---- 4. 颜色表 + B( Q$ ?& B1 }' E
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 # P9 R" {, L& j# O+ q/ G' x! V! @0 [
RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: ; ?! |: C/ A* s& [7 w3 {8 f
! k6 m/ V! j8 E) l9 }typedef struct tagRGBQUAD { / [: T" J n; I1 d5 t2 D8 [. ?, }
BYTErgbBlue;// 蓝色的亮度(值范围为0-255) 0 K& `. H# Y! k! [% I4 J% I
BYTErgbGreen; // 绿色的亮度(值范围为0-255) ) M* t% l* | G" S2 n6 I' C5 m
BYTErgbRed; // 红色的亮度(值范围为0-255)
$ a4 B7 ]" P; N1 S& b* v9 S4 XBYTErgbReserved;// 保留,必须为0
" `" |9 r' |) s" B} RGBQUAD;
& K4 i6 a: |3 e颜色表中RGBQUAD结构数据的个数有biBitCount来确定: / F9 j Y( m3 m# r B
当biBitCount=1,4,8时,分别有2,16,256个表项;
# T1 H; y$ v3 H7 m# _ Y当biBitCount=24时,没有颜色表项。
6 e4 b W' s7 |8 b5 U! b# }/ x, I. A0 E 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 3 V9 e$ z1 U5 @+ B0 h0 ~: e/ g
typedef struct tagBITMAPINFO {
6 ^( U1 k( c# l' Q K BITMAPINFOHEADER bmiHeader; // 位图信息头
7 a/ M- I7 Q; z2 m* P7 @. B( W RGBQUAD bmiColors[1]; // 颜色表
% h& r: L- `6 o/ X( [} BITMAPINFO;
8 ]3 ]) k( d4 J7 Z, D+ | ! ]' k7 j% j F
' R; {- b, D8 v: C
* i6 `6 j4 B6 Z9 D: c+ r5 w" I2 l6 }---- 5. 位图数据
0 `& E6 O$ X: h---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右
' `* l I3 |, O8 v,扫描行之间是从下到上。位图的一个像素值所占的字节数: ' }" i' J; w& o% m/ x. ^7 g2 b
# H" F' Y0 L0 l/ R" U& \当biBitCount=1时,8个像素占1个字节;
8 C2 p, B3 B" ?3 i3 m7 Y2 D当biBitCount=4时,2个像素占1个字节; 4 s" Y! @1 r& r+ M# {2 h
当biBitCount=8时,1个像素占1个字节;
% R: e5 S+ D2 n# W当biBitCount=24时,1个像素占3个字节;
( A2 F% v0 W, ]9 x" T& ]Windows规定一个扫描行所占的字节数必须是
, ?& n0 H/ q9 f/ s5 l3 F4的倍数(即以long为单位),不足的以0填充,
5 G4 }" r( m q+ ~0 J3 q一个扫描行所占的字节数计算方法: # G' f' y+ ` \1 r
DataSizePerLine= (biWidth* biBitCount+31)/8; , L" U% } m5 c. A
// 一个扫描行所占的字节数
8 h! I' O" r9 r5 WDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 / Y' m- B- \1 o9 C- ]
位图数据的大小(不压缩情况下):
) U% {: d! [9 ^2 ZDataSize= DataSizePerLine* biHeight;
/ J9 Y2 f/ D, s5 Q+ N
) b0 i- N5 h1 [! ]
9 }. b# E2 x1 B$ v* J---- 二、BMP位图一般显示方法 8 B& x& O! e6 |1 M1 |( D3 O' ?
---- 1. 申请内存空间用于存放位图文件
S; J" p X( i) \- v( [) X8 D 7 A1 `4 F9 x! P' N2 P2 W5 H
---- GlobalAlloc(GHND,FileLength); $ z$ \2 g8 b9 [
) l/ A- H8 R9 i
---- 2. 位图文件读入所申请内存空间中 9 i; r( T; d$ _. l
1 D+ w" b. J# z! e! |6 s! v
---- LoadFileToMemory( mpBitsSrc,mFileName);
) g+ d; ]+ M- i: x; w0 r9 r5 Z
0 m+ P2 _( ^/ @! w6 a---- 3. 在OnPaint等函数中用创建显示用位图
( |! X# t" h6 t3 H) x( I/ P$ B
u5 ~$ S7 L* T---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容 - v" w/ M$ e+ f6 y$ ^, N
DC,
6 a$ ^: Q' ~" `: ?3 R9 l
" Z) X; w; I# F4 r2 {0 G: d---- 用SelectBitmap()选择显示位图。 2 P( i8 \% l! z r
& Z( ?4 [3 r/ o. T0 H; Q: f/ F/ Z
---- 4. 用BitBlt或StretchBlt等函数显示位图 6 w2 c# X' Q. F+ \( t) Z. V
+ ~8 c" z. D$ s4 Z3 w---- 5. 用DeleteObject()删除所创建的位图
+ A4 ?0 K* N3 F+ |& \. l . {% q3 t7 E4 }' @+ o* f' p
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示
2 T7 B: N: O+ k8 [9 j: I时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(
) C- k! R4 {$ o- E2 z如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。 ) M% r& k2 t- e T, J6 } d
! w+ I2 l9 q' M; O, ?---- 三、BMP位图缩放显示 . d0 l c+ `; t7 e- S( l
, s9 n# W/ o) J5 @
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形 " e7 R* d; L0 s+ m# Z+ q
进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 5 A) t% S% H" P" C. V" o1 R
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: , z H( K* a# ]9 d: u
5 H$ ]/ |! o, b) N$ p
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 . T6 B: v0 f9 V' j# m% `
2 n( C) |& f0 \1 }---- 2. 申请内存空间用于存放位图文件
' O, j3 ]5 v# E r6 X / V& {+ E" W5 b
---- GlobalAlloc(GHND,FileLength); / h7 @5 e6 p3 O
$ |% P. t3 k, U, s* m/ L0 Y---- 3. 位图文件读入所申请内存空间中
' {: {" { U5 f2 t0 z; s5 c * Y; d# q2 O" f/ M- ~' { n
---- LoadFileToMemory( mpBitsSrc,mFileName);
: P5 R6 F$ v5 f/ J; j. P ; u# w: v/ H& y
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 7 p/ O; E2 V5 U' Y( J6 D+ T! Q
- i# F0 \6 K! ^5 b* M' s% r& `, g
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
8 U+ i; b% p9 G* ] , g* O- B/ J+ c" t3 p- k# _
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形
( Y8 F3 k7 j0 M% g3 K失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通
2 C, v2 N: Y8 u过直接处理位图数据,可以制作简单动画。 / ?- j3 L, p0 n+ e# [0 A" A
/ n) x! Z. H5 V( K8 z* c2 G6 v
---- 四、CViewBimap类编程要点 $ g$ C! ~8 K% H) w7 `
" J" R9 u9 S! b, a& }
---- 1. 在CViewBimap类中添加视频函数等成员
7 i7 L f( j- v. O 9 Q. R4 ~/ P3 ]. F' N/ s" a
HDRAWDIB m_hDrawDib; // 视频函数 Y4 Q9 S& z8 B& v% o% g8 } G
HANDLEmhBitsSrc; // 位图文件句柄(内存) 9 H5 e% w P% B1 F6 E
LPSTR mpBitsSrc; // 位图文件地址(内存)
0 P0 c- u1 W" B8 P7 w* X6 sBITMAPINFOHEADER *mpBitmapInfo; // 位图信息头 / ?/ o$ V+ W1 u
9 {1 J: A* t$ B8 Q' q" ^3 W; P
; |4 K% f8 \# M9 ?5 D# I* m+ _0 Z+ c---- 2. 在CViewBimap类构造函数中添加打开视频函数 ' f* C- Q8 A) a5 y6 G g# T" b
---- m_hDrawDib= DrawDibOpen();
3 }/ ?- t1 ?2 @' s0 `+ w 9 R* p& q$ L. \5 [. _: G
---- 3. 在CViewBimap类析构函数中添加关闭视频函数
, D2 _) f& k0 P P' ^& e2 r $ `- ^+ E' U& g9 \' w7 r
if( m_hDrawDib != NULL)
& y! O) P3 n, v1 z" w { : s6 k: S+ e2 g4 [& S' f6 g
DrawDibClose( m_hDrawDib);
3 f. E, p7 W' a, K& h m_hDrawDib = NULL; : [; }3 h& X' m n* x
}
& |' Y; l1 N; ` a3 B4 \
- Y4 Y K6 {+ b b ! Q1 A6 ?, j6 J* t- ~7 ]
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw()
1 Q. M8 Q- ~) e5 XvoidCViewBitmap::OnPaint() 4 d0 _/ ?$ X; q4 _7 q
{
$ O/ I" Z- o) v3 L8 L9 B, CCPaintDC dc(this); // device context for painting
/ D2 q$ l3 T* D' z: {0 cGraphicDraw( );
- {$ h* }; _, L# s: n; m}
$ b( z* e/ k6 o9 f, I0 s2 s3 ^! u, { . v8 ^: o: M* Q8 `7 e
voidCViewBitmap::GraphicDraw( void ) 1 D0 A5 L: X% d; ^$ c) R! x/ f
{
$ l* a# l" g8 b9 B/ cCClientDC dc(this); // device context for painting 4 F% C7 c0 L- Z) f7 u
BITMAPFILEHEADER *pBitmapFileHeader;
2 L6 l- I2 R1 l* BULONG bfoffBits= 0;
p. U7 r7 B J* hCPoint Wid;
; D' T# s" s, r- f! x( B) H 6 x2 K$ Z* f! |$ e0 E) e/ l
// 图形文件名有效 (=0 BMP)
' g' t9 m8 U) C$ Z& U/ \if( mBitmapFileType < ID_BITMAP_BMP ) return;
8 g( D8 b8 {& G, ^
9 N; Y+ E8 r( O1 \" v. y' C' E: a$ U// 图形文件名有效 (=0 BMP)
5 K, A! ~- v, d1 H// 准备显示真彩位图
% |; S9 t0 E) D) t# `pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; 5 @; D2 c* b# l. Q
bfoffBits= pBitmapFileHeader->bfOffBits;
l! W5 t# e u3 z) L* ^* \ ) b8 y) e2 S5 |# g
// 使用普通函数显示位图 & N" O$ U4 n9 S
5 I6 q, v2 I/ r5 s/ v
if( m_hDrawDib == NULL || mDispMethod == 0)
( b7 @6 P! t2 r m { : x. W7 q6 G6 b0 M+ s3 v
HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, / k$ H& j6 t# i2 H! E) T
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits, " i# ^- x+ k# x8 K, ^
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);
: b4 O/ _9 Q2 @& j// 建立位图 # A' A, n% W" z+ ~+ ^
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
: o3 z4 Q h6 XHBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象 ; L+ w9 G7 {& L! I% Q
// 成员CRect mDispR用于指示图形显示区域的大小. 8 [3 Y6 p. c6 f$ x: r3 x
// 成员CPoint mPos用于指示图形显示起始位置坐标. 5 W! Q) a- `7 r* q% T! O# h. g! S
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) 4 @# q) W: D1 j) _
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
6 L+ ]: r) _, W/ |) _* k& }% | if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) : j: p0 `5 g- |9 b- l
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); . v% i C# ]8 _- A* n9 O8 M0 f
if( mPos.x < 0 ) mPos.x= 0;
$ f7 R7 o9 d3 `2 G( Z% E* |5 o if( mPos.y < 0 ) mPos.y= 0;
7 H* F, M8 I j& v5 x Y7 e . s( R2 {' T5 o: A" j
if( mFullViewTog == 0) / m0 }; h+ l7 e& C: A
{
' }5 F* @$ [ i" ^$ T9 T- |// 显示真彩位图 . ]( M+ D' A3 j* s% [6 J
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
, o4 E, w8 v. O1 m9 U$ f9 X( k) X% yhMemDC,mPos.x,mPos.y, SRCCOPY); + j, f5 z }( u1 X, l/ n: a# g
} else {
8 b/ o: B! B# }/ @# L4 }::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), % s; v9 Q+ y8 w% ]9 G+ ]# z+ K
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
7 K) ~* r- @' }1 F* l# ~>biHeight, SRCCOPY);
$ l% M" f& ?8 `! [8 f}
) V/ `) Q# {7 l/ |& T1 I // 结束显示真彩位图 $ h7 a h, _% i; V
: eleteObject(SelectObject(hMemDC,hBitmapOld)); 0 H& g+ A, Z& h$ B9 U W K
// 删 除 位 图 / ^. r" `; x' e/ E! o# S: i- Z
} else {
, y/ F% g7 b' p& [' i: `
" \; R, f/ M. ?; t // 使用视频函数显示位图
H! S2 {5 a. |1 u7 D8 T3 h
9 [0 X; R+ m8 N if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) 6 g9 S+ H: \( Q! i; s5 W
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ; , K) h/ Q% r2 }3 N+ g
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
1 r( i+ l( {7 J8 w8 O7 P0 UmPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
$ S- w! }# r9 ~+ @. C" {4 |! h( l if( mPos.x < 0 ) mPos.x= 0;
' F7 k' K+ t+ H7 P( F! y3 R if( mPos.y < 0 ) mPos.y= 0; 4 m+ U7 G9 O, s6 d1 P2 ?6 p) T v
; I3 O! \! u0 H$ b& ^3 Z // 显示真彩位图 2 [, i6 H) S6 d* v( N8 d5 s
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE); * L$ [6 o/ {7 e" c' H
* L' s8 V* F0 Q& @6 Y3 f: y# c4 u
if( mFullViewTog == 0)
6 o/ n/ z, a7 a2 k! E2 G* n% [ T( S8 m{ 5 k# D2 ~2 c! F' B) J0 J; v, Y
Wid.x= mDispR.Width(); ( _4 Z7 Q/ p, K/ n' \0 S* t
Wid.y= mDispR.Height(); 7 p8 V* `9 b5 o$ S5 D3 D: O
// 1:1 显示时, 不能大于图形大小
7 J9 z7 s4 y& Nif( Wid.x > mpBitmapInfo- >biWidth )
% h* x2 D# q; K1 z% |Wid.x = mpBitmapInfo- >biWidth; + C/ X1 U- M" ]6 U }3 j
if( Wid.y > mpBitmapInfo- >biHeight) 0 I7 C4 E3 L8 t I$ g& z
Wid.y = mpBitmapInfo- >biHeight; 2 [1 D8 J- r- ~
( D3 g* F9 Q+ q. f6 vDrawDibDraw( m_hDrawDib, dc.GetSafeHdc() 2 j& S& t+ d% t$ C- ^" J
, 0, 0, Wid.x, Wid.y, I7 q* I' z3 a, I
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
[( a$ `2 P" I0 Q; i5 GmPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); & `: Y: M0 {* |0 W) X1 q: E) h
} else {
! I$ ?. `5 Q I" N3 w) v# uDrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), - ~( T8 `0 s* r2 j$ g8 R
0, 0, mDispR.Width(), mDispR.Height(),
0 D2 d4 f) _9 n6 I6 W* n7 MmpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
/ B0 a/ n) y# P6 `9 Z0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight, " [( _# w1 v% b) o) o4 e) h
DDF_BACKGROUNDPAL); & V; F/ p% F$ z2 i' ~" \
}
: l" e5 w$ M5 G) [. F }
: A" `+ _* }* X+ { C8 B2 Ereturn; ; h5 G+ J9 d2 C+ E6 C' A
}
8 |6 ]" C8 `, c q
5 N' [3 n" e/ m( R( `2 h/ M & \# K8 j& J7 E2 z
---- 五、使用CViewBimap类显示BMP位图
8 m5 t4 t8 W; S9 j---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC ! l% r( H1 c6 B' V5 L2 |6 s# D
AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点
/ l( g2 h$ Y: n& y0 h击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
; A, p7 M# `" g9 \, a. i. `" M,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的
+ Q K7 O! b. ]尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。
0 b: v8 y+ a3 ~. ^ ( ]. l0 d* o! n3 [, o
---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-
8 @3 k @9 }, s4 M# n) K>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。
' X8 @6 ]0 D/ l1 p/ U v 0 s5 j* N+ T$ N, S
---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为
- g$ a+ Q5 w+ z1 `5 FCMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
0 r) T r1 E: Z/ y7 X0 S Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 " }& |/ [/ O% c
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码 0 k# N0 E+ K6 j5 D% P7 O
。代码如下:
( K2 }/ y4 g+ r/ G( a1 L
& R4 j V+ p- x5 ~9 Qvoid CMainFrame::OnViewBitmap() & Y+ S" D5 R! }
{ 8 Y1 n# h& f1 u& o: S
// TOD Add your command handler code here 0 Z9 n+ ?+ I2 C# M# ?7 J
CViewBitmap *pViewBitmap= NULL;
0 V6 H* O1 s p% P) y( F& v5 ?, o
2 d; z; i# Q- x% L5 {pViewBitmap= new CViewBitmap( "BITMAP.BMP", this); & `$ @. n+ X! J* J' |
pViewBitmap- >ShowWindow( TRUE);
2 T9 t% I, e, {3 T% v% b} 6 \0 X0 J: ~, F. ?( \( h* F& j
W+ C- T2 G9 P- }; L
! Y6 _: p; X$ `& ^2 l---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。
. c \9 \% c; i4 \5 f---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。
( K4 J& V" }% ^8 \( @5 y o. a b6 \0 m; d4 t; }; l7 P
---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- > % h( ?8 |) J6 e1 E# }* t% p( ~
ViewBitmap)即可显示BITMAP.BMP位图。
7 `" c# w, C+ c4 H, n8 r * x8 K9 }% \+ ]; c8 @
---- 六、CViewBimap类功能说明 : x/ ?- E q& B4 B# j. N
! Q" k" J/ D+ I9 u% K! I---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可
- G- o5 S; J& s9 U; [% x以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 $ \: c1 W& I8 m( P5 ]
' c4 [! u. N k* h6 M# C
---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为
0 ^- N& ^# O/ e5 ?$ ~' F* Z, w位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
. W$ E! e; B! f! j4 {! c4 s, o,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在 ) R% u% a, w* U" Z1 L
第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区
( q1 k+ B2 }, H. D8 S小,则对位图放大; 如果位图比客户区大,则对位图缩小。 ! ~8 [ F* J9 T" P0 H, {3 k: l8 i
: T& ], X7 H; {7 E---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,
, \4 \# m8 L2 h2 K5 n5 N就可以显示该位图。
4 F% @; S X. m7 }5 I % g \( u o% B( G
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,
/ b& z! ~6 c7 H* b9 y( j ?; r3 Y& V) w4 B
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图
8 c) A3 z0 @8 ]% v( u! J* [1 x放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失 # `' H! M* p- P- Z% @- }" M
真小,显示速度快。 " T7 U8 `3 B$ m- G9 u& K
9 ?6 j) g2 Y) _9 f( t7 K* ?, u5 T. {---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 ' G: |) M! L1 {/ T
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可 " o V# T: u- m1 i3 u3 ]2 k4 k
以体会到使用视频函数的优越性了吧。 1 B8 @0 \% k E9 }
* Z4 [& _) I( {---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示 . ~& }) v) w8 v* P& Z
程序中加以适当调整即可,读者可自行完成。 |