|
9 W- ]# x- @# k8 y" i. S西安交通大学流体机械研究所
7 V/ d: H0 h" z; W& ^张义云 - K, Y1 u, w9 T+ ^7 L+ P0 ?
- F* F% o) L/ a
---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重, 0 L7 M" ~7 _( ?; _! w; P
在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数 7 g- a, k I. e+ N
显示BMP位图,可以消除以上的缺点。 . Y. n& M; E: [5 Z3 B8 P0 ^
- o6 K3 ?/ o" z+ Q& k! A& E8 S---- 一、BMP文件结构
( i/ [5 y0 e$ Q& f1 B3 Z2 v
8 L+ q, b6 p; m: @/ G3 E( l, Q---- 1. BMP文件组成
. N- o% P! G8 X1 Y 0 w% j; j) `& H: D. e
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
5 c' R% g) i6 B! v& \, i 6 k0 h' i+ s( `" ]- S0 |
---- 2. BMP文件头
- q3 |* G! ?, ^0 i2 y
. O- s- I6 h5 W7 R---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息 " ^% i1 X8 V6 W) j" H( a$ s
。
7 ~: {4 k8 K- c/ N1 Q" _- [
: m6 v" W0 \) o R6 a5 P---- 其结构定义如下: * M( b' p/ m' ?0 a3 {/ H
$ p9 b) y7 h% Y1 @6 r
typedef struct tagBITMAPFILEHEADER ! e# g; A5 r$ y$ g0 U4 V. U' m
{
# y% r* G g+ J$ m8 N& @6 u) SWORDbfType; // 位图文件的类型,必须为BM ; ?1 T9 |1 |, N( A4 V- E& W- C
DWORD bfSize; // 位图文件的大小,以字节为单位 0 u X) [ K; L* v( `: e* I
WORDbfReserved1; // 位图文件保留字,必须为0 0 C* u. F n% ^! M7 a3 M7 o
WORDbfReserved2; // 位图文件保留字,必须为0
: g' u2 p( Z- ]' MDWORD bfOffBits; // 位图数据的起始位置,以相对于位图
' f' o# h4 N- b. w// 文件头的偏移量表示,以字节为单位
5 t7 `2 C, e' u% }3 j$ v. R} BITMAPFILEHEADER; 2 d9 Z5 [$ R) Y4 \, F9 ]2 E9 H
" R0 J( z* X K! {; v0 F3 D, M
& `+ }8 O- v. P$ D! Q: e- M& Q+ d" M---- 3. 位图信息头 ' e% h( S- I6 }8 |0 k& | T0 \
----
n: C R6 u: ^; D, t& b
- n( X8 w. J4 x2 r/ M+ U$ mBMP位图信息头数据用于说明位图的尺寸等信息。
6 d6 I# [( K+ R H+ b5 N- ?% z: A: N4 gtypedef struct tagBITMAPINFOHEADER{ 2 I/ ?' T X) ]1 b
DWORD biSize; // 本结构所占用字节数
" D w8 _4 [6 U( @3 f D% u- A) o LONGbiWidth; // 位图的宽度,以像素为单位
0 L. j6 t) |9 `: x- Y+ v LONGbiHeight; // 位图的高度,以像素为单位 6 G+ z( b; ?: M {: o% m
WORD biPlanes; // 目标设备的级别,必须为1
8 K& ]! G+ |! Q0 G; J- x) r WORD biBitCount// 每个像素所需的位数,必须是1(双色),
, V' K7 K s& N) k0 d5 z' u // 4(16色),8(256色)或24(真彩色)之一
5 p: m: `5 Q& M0 t( F2 O DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
`) n- P+ D, i9 u$ o5 V$ m" T1 b // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
2 \ Q) i. g! K t3 y- H9 R3 |+ B/ Z DWORD biSizeImage; // 位图的大小,以字节为单位 : ~( ?0 T3 q- A6 W) V9 {
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 * H) f/ g% v3 ^' L
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
; X" s/ y- x+ F( f DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
5 v# w! b* c) [' B4 F- {+ j( | DWORD biClrImportant;// 位图显示过程中重要的颜色数
u8 k0 G: [' Y/ |4 t: W; d} BITMAPINFOHEADER; 3 d6 t, D: U! p" G: @5 |
0 {) x* M* M2 [- J/ j 6 @3 O5 J% H# B, H( V3 E
---- 4. 颜色表 9 n" j- L; \# D! H& p
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 F: G3 g) ]% `6 j1 p
RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: * @) s3 ]) y, f( O6 x
% d' _ Y- C/ P6 I: `% v o. C6 btypedef struct tagRGBQUAD { ' `, M. c$ }1 e# B8 T
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
9 P% ^; L% L& LBYTErgbGreen; // 绿色的亮度(值范围为0-255)
# F" w5 V. b, Y0 e* W {5 c# eBYTErgbRed; // 红色的亮度(值范围为0-255) - \9 \( s+ {3 c: X
BYTErgbReserved;// 保留,必须为0
0 l% y" Z9 ^; y# o} RGBQUAD;
5 i4 E/ J5 P% J" \+ |" m. X+ S2 v颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
# E+ m9 w" U9 I1 J当biBitCount=1,4,8时,分别有2,16,256个表项; & K& M# |# G( |/ f; O
当biBitCount=24时,没有颜色表项。
8 e7 x4 ~9 q6 l2 y, f 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
% t; U F" T0 G5 l* y' m, c) Jtypedef struct tagBITMAPINFO { + j& G* O& {' u
BITMAPINFOHEADER bmiHeader; // 位图信息头
3 M4 E- \4 \# R/ \9 F5 s3 e RGBQUAD bmiColors[1]; // 颜色表
" e% c- A1 i x8 _9 b, s) z} BITMAPINFO; " n! [. J9 T ?
/ N' e. h5 v1 m! i% v' r/ @4 K5 X z 7 E5 ]9 l/ g1 }/ K1 E$ a8 l3 [
; |2 [; c @ ~5 E---- 5. 位图数据 ) B+ P8 E8 ]' b$ i
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右 . g3 u* }8 h) K1 u& d
,扫描行之间是从下到上。位图的一个像素值所占的字节数:
7 n/ J# D3 B0 i [
; o/ n- Y: b8 C- Y当biBitCount=1时,8个像素占1个字节;
3 G* \. R7 c p& Y" Y0 A当biBitCount=4时,2个像素占1个字节; ' z5 t) l4 B1 z( e- b5 @
当biBitCount=8时,1个像素占1个字节;
$ O: ~1 ?0 A1 g- m当biBitCount=24时,1个像素占3个字节;
$ }" ^$ Y! @ H, \) u+ u1 {Windows规定一个扫描行所占的字节数必须是
5 ^* h2 s! K7 Y- V g0 u9 |1 y4的倍数(即以long为单位),不足的以0填充, U. y- @' F; I/ `; N8 y: b
一个扫描行所占的字节数计算方法: ' Z) t5 z9 v# g3 ^
DataSizePerLine= (biWidth* biBitCount+31)/8; ! r% w& y( Q8 C4 E+ a$ E& S
// 一个扫描行所占的字节数
" J c) _5 a' s9 z5 fDataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 6 o1 N! H9 d' r% e1 H, j; }
位图数据的大小(不压缩情况下):
4 J' E0 q/ [1 l- h4 z/ K' lDataSize= DataSizePerLine* biHeight; % C4 S0 I: T- D$ R5 G# R! b5 B
5 Y6 @1 M; N& l q
6 O, y0 g: p$ M3 @
---- 二、BMP位图一般显示方法 ! h" O0 ?5 P9 B: ~; u7 u5 Y
---- 1. 申请内存空间用于存放位图文件 . ?( h# ~6 r# `" a6 B% W
" n+ H7 M0 o% f4 G& P) p---- GlobalAlloc(GHND,FileLength);
0 ?$ Q) R) `: v$ T$ C' p 0 ?6 U s6 ^) G1 S: L
---- 2. 位图文件读入所申请内存空间中
. d8 U c) t% @- I : D I5 o( f5 y0 H; X- }" R
---- LoadFileToMemory( mpBitsSrc,mFileName); ; O: g% c: F! b: p ?
+ V. m0 W8 g( X7 X3 a8 X---- 3. 在OnPaint等函数中用创建显示用位图
' k; O1 b. n: U) T+ R: N! z 2 P& n. `) C) p
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容
( P1 x. D: k" P' JDC,
& u$ |) |, X3 _' W; V) L" X5 ~
9 x: k& D$ a4 E8 M---- 用SelectBitmap()选择显示位图。
3 c6 N3 M1 k7 D( _6 K H2 }! j2 S6 x& b
---- 4. 用BitBlt或StretchBlt等函数显示位图
# l0 B( ^* U. k+ x ! G; r, j8 \' \
---- 5. 用DeleteObject()删除所创建的位图
. h- h! f/ m; c* e5 N2 w* {8 P" ] $ c% a3 E* ?: R) G7 F9 q( c2 @" m2 n' o
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示 & {: b* V" ^- }# H! Y- E
时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(
, X4 z/ z6 a0 I" C/ D如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
$ F$ P- a% M* h& {( S
( O" X+ Q( A: t! h6 l: n6 S- `---- 三、BMP位图缩放显示
" Q+ @& U( w# z' F
! o* [0 \" h/ _: K/ x$ Y---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形
& s: R( Y6 E1 q) P n* J进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比 ! A! B4 Z7 O& \/ X" c
图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: 2 k- t9 b( ~ u' s$ X6 N" k
1 s) Q! J/ S2 z6 T5 n
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
. H: K/ ^3 i9 l# N- R/ u& a # `' i/ p% Q* X
---- 2. 申请内存空间用于存放位图文件
: ~0 S& H `; D$ Y! T) n3 z Q0 Y + x2 {! b$ C3 u
---- GlobalAlloc(GHND,FileLength);
9 o, [ ~4 \, V
# U* _2 _+ X, q! A+ G0 S$ R: ?---- 3. 位图文件读入所申请内存空间中 8 r& ^- T( S2 z! t
6 C8 _7 m N5 N( U* {) c& P+ J---- LoadFileToMemory( mpBitsSrc,mFileName); ' I4 S1 M* r P2 M9 @ J
* H- n. J3 Z4 Q) K0 R( f7 D% N
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 : y+ M, F+ d+ L: f" B4 ^; A
$ X' z0 `0 i- o8 I( ~8 P: C6 I
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中 " V1 f- [# v9 @2 I. I6 W
3 y" j7 F# ^6 K. a& j% P1 Y2 M---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形
5 v8 ]. ]7 A5 b; l" u Z- w失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通
+ V) n+ n8 M `8 a过直接处理位图数据,可以制作简单动画。 : K8 J2 a1 I* T1 R7 F9 M
7 r" F( j. f6 ? R8 s4 y
---- 四、CViewBimap类编程要点
- K# V5 e- V% H1 u 4 _9 I, Z3 S- o. E( j ]2 `/ R
---- 1. 在CViewBimap类中添加视频函数等成员
8 W& T2 L4 E6 a" j- I' Q
8 G2 A' Y" T: H" nHDRAWDIB m_hDrawDib; // 视频函数
$ P& g) h# W" y3 ?HANDLEmhBitsSrc; // 位图文件句柄(内存) ; i$ [5 N: d% G' K4 O7 F/ c
LPSTR mpBitsSrc; // 位图文件地址(内存) ) k+ U: F; S( G
BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
& y; r3 R5 y8 `4 X! P3 e% V 0 D: ^6 h L0 U
7 p. R; M( P+ W
---- 2. 在CViewBimap类构造函数中添加打开视频函数
% p) Z$ F3 s9 i, G---- m_hDrawDib= DrawDibOpen(); - ]6 T% s6 D' q
, f l0 A4 X9 A+ i3 S1 N---- 3. 在CViewBimap类析构函数中添加关闭视频函数 9 X: j4 J g: h
6 r8 J% D. c! R' W# }1 Gif( m_hDrawDib != NULL) 5 r( U# H) O+ Y; i3 ~- I) e+ i
{ - p' e3 v/ V7 J' m; L1 ]% V
DrawDibClose( m_hDrawDib);
' X3 b* V* k7 O+ B( J* y @1 Y m_hDrawDib = NULL;
1 N `! b% t2 C0 i: b b }
/ A: S3 |# k9 G8 l . q0 B( {1 V Z; M# o6 k7 Q) H0 d, [: h
$ ~& I( ~3 I/ y* p7 i! `1 l---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw()
: ]+ R; d. I" p* f1 K! svoidCViewBitmap::OnPaint()
2 i- p. W/ a/ y" A, s% C' U5 z{ # ]3 i2 D. Z$ `) A; B* v
CPaintDC dc(this); // device context for painting
5 B% ]% ?, l1 p0 p! x1 J" F- HGraphicDraw( ); 4 y7 g# a1 o5 r: r5 w
} 8 D9 \/ X) U# ^& ?( D3 ~6 N
$ s4 `. t, H5 }; s% @& Z6 o+ k# V
voidCViewBitmap::GraphicDraw( void )
7 G' Z' [+ a+ J{
2 `6 N5 U% H" b! m) ]CClientDC dc(this); // device context for painting 3 y& G3 X8 F) P
BITMAPFILEHEADER *pBitmapFileHeader;
6 @5 q# D4 o, B8 B& S+ j3 A2 T+ {ULONG bfoffBits= 0;
/ x0 g/ Q9 P& u! L. ICPoint Wid;
: [- `( h$ X7 Q+ H& A+ _6 i 7 C2 X Y9 r2 O O. ?, q
// 图形文件名有效 (=0 BMP)
. L4 ]! Q, K; o5 p. z( v* D {- @if( mBitmapFileType < ID_BITMAP_BMP ) return; + Q0 n2 |" a: l/ h1 j
: Z2 n4 g0 p( a7 w* F
// 图形文件名有效 (=0 BMP) 1 ^! M9 y8 C* v9 h8 E; A. Q& }
// 准备显示真彩位图
5 A8 v' e0 |* {pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;
& c& f" o0 W3 x* J& obfoffBits= pBitmapFileHeader->bfOffBits;
/ O% C% W; c6 D! K2 l
# W- U) o. ^1 i! f' l; G* F: t// 使用普通函数显示位图 6 M) K* T1 g6 M! P3 {
* X* j h0 O5 B. Q: q% d
if( m_hDrawDib == NULL || mDispMethod == 0) % `3 S/ U5 p& v; S* C' y. a
{
, H: ?) ?" f% w, j HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC, * S% N# F" ~" D. X
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
4 T" l- `/ @3 g (LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);
4 k- _% y3 C$ i+ E" K$ P! D// 建立位图 / h! X" e( a5 D) r7 T" m# N7 h
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存 3 V+ m' i# K. a
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
! s7 E; U) @+ h* ^6 o+ p; r// 成员CRect mDispR用于指示图形显示区域的大小. , `' X! x* l( w
// 成员CPoint mPos用于指示图形显示起始位置坐标. " x1 A( R' L* |( M* r
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) , X& `" r; o; C6 S9 I) Z
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
5 m/ ^' u W# T' S i! D if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) o5 c: T& s4 X/ g. J$ h+ e
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
3 Q% s: C; a5 o if( mPos.x < 0 ) mPos.x= 0; 2 ?3 [! F/ ?' }/ F* O( f
if( mPos.y < 0 ) mPos.y= 0; - r: U; ?+ X1 O1 i; r' ]& O
5 ^8 `" H8 n: E+ X7 h5 w5 _# b& Y
if( mFullViewTog == 0)
: e- d2 z3 L0 b; r) u{ , e; d& y# K; J+ `4 B% I" C( q$ n
// 显示真彩位图 7 O" ?- r# x2 V o) N
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
9 B) i' z5 d& {1 L! S9 ^: e ?hMemDC,mPos.x,mPos.y, SRCCOPY); 5 c3 e; g& C5 O7 N6 {" u1 y
} else {
; Q7 [$ _. l- d::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
# G: h5 M1 \) }+ ?, H PhMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo- . b7 Z; W: Z3 e6 r- u
>biHeight, SRCCOPY);
8 ?) W' I6 H4 W' s7 Z}
& t( |# P0 N8 x, }3 F1 m // 结束显示真彩位图 ; B( Z5 w7 o, H* B, P
: eleteObject(SelectObject(hMemDC,hBitmapOld));
) r# @! H6 C1 G& R// 删 除 位 图 ' F$ H) t ~8 X' }" E
} else {
0 b5 b. P0 b: e# J1 I$ S $ u7 y: k4 k: b" y2 \
// 使用视频函数显示位图 7 d5 k2 t* A; {; a. ?8 d% g
4 _7 I8 q) u& `& {' o2 h4 s0 O' \ if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() )) * L/ N: I: w3 n) V1 Y
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
- G+ b6 u2 i# k l" w/ Q! T if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height())) * g; W8 ]( [& d% b- H: w h) |
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height(); 0 w! e9 F% k* \
if( mPos.x < 0 ) mPos.x= 0;
: q( c/ M" }/ C* E' y if( mPos.y < 0 ) mPos.y= 0;
3 T1 _' c- b: q3 {, G) w & b) R7 ~1 x$ M) i y
// 显示真彩位图 ; O' i/ R5 h) U9 \1 h
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);
- M) D% u* q; [$ j2 p
. @1 r" T& }+ O! C2 n' O7 S if( mFullViewTog == 0) * K( V. P9 S7 H8 h
{ 3 e3 ~9 V h3 o
Wid.x= mDispR.Width();
' U; s) i/ {( ?! G6 l3 ZWid.y= mDispR.Height();
. S- [( U. D4 W/ k6 F1 k( w// 1:1 显示时, 不能大于图形大小
* ~7 x! L1 d$ c Pif( Wid.x > mpBitmapInfo- >biWidth ) ' S+ r! U" M% L
Wid.x = mpBitmapInfo- >biWidth;
A$ ~/ E H2 y* ~$ k0 d" {, jif( Wid.y > mpBitmapInfo- >biHeight) % n$ |7 Q2 r8 K( k0 c
Wid.y = mpBitmapInfo- >biHeight;
2 ^$ V* B6 | C
% J5 `8 B3 h# q- UDrawDibDraw( m_hDrawDib, dc.GetSafeHdc() . K2 f8 X- }9 y' X- g. v# \
, 0, 0, Wid.x, Wid.y, 9 }' g) F, F$ R3 d2 A
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
0 K. ^4 ~: F+ p- r; x) d5 amPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL); 6 } h$ Z3 F% B, J
} else {
* `0 f+ v( Y6 s8 fDrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), 1 I0 R' U2 }; i# T- T+ m
0, 0, mDispR.Width(), mDispR.Height(), ' ]9 c; e1 k) U
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
# E: D! a j5 \/ E: m, f( l/ D; B0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
7 c0 w) V- E2 o8 B* n; nDDF_BACKGROUNDPAL); ' v! [+ E8 n4 u5 h
} `9 S9 g% V! Q" L9 B7 i' q
}
3 R# T- ?% w' m' U: jreturn;
* m/ F" B- d9 X& C} . A, C$ x: V7 S6 N0 w& |9 i# v" f
% \3 p/ u. F4 p0 D5 ~* m
: \) {* s: d% |! B6 |: A( u/ X---- 五、使用CViewBimap类显示BMP位图 8 Y- ^4 I! n2 x) g$ m( L
---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC
' V! a, Y0 x6 R0 [& tAppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点 - _$ v. v" I* w# q4 m( L
击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目
& w4 J$ b# G) k,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的 ( W9 d) r4 k+ t" O5 V
尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。
! r. y$ ~3 n* x6 ~/ ]: h
! A5 m# U$ f; s! @$ x! u0 i) d---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project- & E0 E( \; V, i" K' g& F
>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。 - D& Q( P2 | h3 G* Y, U
9 }: H+ N ~- X# {% i% p; N) c4 g6 ~---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为 ' b" x/ f; f1 g7 r& n& k9 |
CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add
, q! b4 f- B* H. y7 Y! b' J Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在 & c- T/ _4 \$ c! @) |
Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码
' u- ]* |' P N。代码如下: ' u1 C3 h# {; q9 d& C3 V0 B. b
0 F% F4 J7 b! R9 {" O0 e4 ~
void CMainFrame::OnViewBitmap()
" ?; M* T% W2 d1 J{
# O4 @" f1 a) `# [5 O// TOD Add your command handler code here # I% ^3 J" X' N
CViewBitmap *pViewBitmap= NULL;
. j6 l9 |$ G6 n) N# T / ^3 Z. E& T R: v* J
pViewBitmap= new CViewBitmap( "BITMAP.BMP", this); ( r6 l' @( H7 K4 P3 x" ^. J7 T- G- y
pViewBitmap- >ShowWindow( TRUE);
" P# `: x/ `% C( f3 C} 6 }9 H4 k* j, d5 B) O
S, k. e" ^4 T" l; n9 F, _
+ p7 [% p J' h; g# ~
---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 ; ~6 U F1 ` d2 p$ K
---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。 5 u$ J7 |& q- b; h7 N6 u' H% G) K* A K
4 ?) ], P) Y! d! C9 v% T---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >
6 ~- v# ^& o" c ViewBitmap)即可显示BITMAP.BMP位图。
5 L I+ L' s7 V8 o2 b$ a ' z. O6 E# G p' F
---- 六、CViewBimap类功能说明
7 A a9 _9 c! B! B+ n
9 Y+ a( R2 ~ d---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可 6 D% O& }9 w% Z, f
以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 1 R, h2 P# m5 Q
^2 @7 u4 | L, s---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为 0 S0 @* l+ i! d8 h% N
位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标
1 U$ p" y% c: ]& \" M5 M( H3 y,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在
8 O( o Z" f- e% s$ v第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区 $ ?# q% P' R; m1 o
小,则对位图放大; 如果位图比客户区大,则对位图缩小。
; O2 C( {, l$ T* r! s ' N1 N8 X2 X7 S W9 g1 f
---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,
/ i- A) p& T0 `- \' |就可以显示该位图。
* p/ o, ]" E0 A 0 P2 n: \& l$ C
---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小, " A/ I% n+ L+ O# p G
; k( m; G% J9 k$ g: Y
在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图 7 }* l' F; L/ Z5 i& @* {
放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失
* y+ F, b1 w- H真小,显示速度快。
! l- i* {; F, A$ Z0 u5 g) t1 q
6 g& {% N: e- y6 Q x---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模 # ~! L& z2 [8 m' p3 [+ y
式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可 ( d4 v+ @" C. I2 L$ E. `' S
以体会到使用视频函数的优越性了吧。 4 v0 h5 e" {9 V9 r7 d# {& U& R
; J: O, k: l7 z& v' L---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示 ( _( v6 C* b$ ?0 a( r! w# j; l
程序中加以适当调整即可,读者可自行完成。 |