|
//用MCI命令来实现多媒体的播放功能% H$ C U0 M- e, ]; {( S
//下面的内容几乎有播放器软件的各种功能,你只是引用这些函数就能做出一个播放器来
/ F' e4 j4 [& _8 U- r3 R d3 R8 O* i# R& [- {
#include < MMSystem.h >
, r, K8 M/ \! [#include < Vfw.h >! i) q$ v8 v1 _ N A
#include < shlobj.H >8 w% u7 w$ E: t6 F! g E
s) C: i' i h
#pragma comment(lib, "winmm.lib"). Y l$ f6 i- b
#pragma comment(lib, "Vfw32.lib")
4 G! ?: a! r+ u& ?1 ^0 B
" Q; ] M2 }' e: b0 \+ d% O: P#define AudioStereo 0& `; e9 M# c+ l" V' u, L
#define AudioLeft 1' h( J( {3 h! ~1 `) t
#define AudioRight 2
7 E" F1 n- [/ h7 P
9 {' x" D) g# RWNDPROC OldProc;( A y z/ P- {, [
# Y. f [( t7 F4 s/ n( ALPSTR GetDriverID(LPSTR ff);
" b+ D2 `# }2 S9 I) T8 h
: E9 J" q7 B, abool OpenMusic(LPSTR FileName,HWND hWnd);( X" w/ W7 D: J; o) e! g& N8 P. j+ w9 O
bool PlayMusic();
+ A2 L6 T# u+ C: x) Olong GetMusicLength();: H4 ]+ m) u* g( P0 i4 k
bool PutToWindow(RECT rc);
6 F2 }/ C D) N# z5 _0 s+ Qlong GetMusicPos();
) T$ `/ K* Y7 U I& e; W1 u- u8 g5 Rbool SetMusicPos(long Position);% Z/ q* o* M+ `5 C, l" B5 K
bool PauseMusic();
: S1 L( A! J) Abool CloseMusic();) }# y+ v9 v1 P, J
bool SetAudioSource(int AudioSource);
1 Q9 v- \/ L, A2 F$ gbool PlayFullScreen();" V' |; g& Y, y
bool SetVolume(int Volume);* F" _1 | `" m+ {
bool SetSpeed(int Speed);
# ~" ^8 g" v5 _1 C& o* f, L- `1 l) lbool SetAudioOnOff(bool AudioOff);. u& L6 Z3 b6 F/ N; J
bool SetWindowShow(bool WindowOff);* ]$ q8 ~4 B8 D$ M: U
bool IsPlaying();
W; O6 z3 U. D: o7 v: BHWND GetWindowHandle();. O+ E" P4 k; E5 F+ X! K7 t2 W
MCIDEVICEID GetDeviceID();
- ^1 \1 W+ y/ ~( z4 l+ @+ [4 D- aLRESULT CALLBACK MCIWindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);9 A6 i. H5 a4 l" ~$ ]/ d1 h4 t
bool ShowOpenSave(LPSTR FileName,bool OpenOrSave,HWND hWnd);, _; v4 P' Q& H) e- H0 r& Y# w
bool SavePicture(LPSTR FileName,HWND hWnd);1 ]! h* i. h* ^6 o4 K
* a5 B' S4 o o* a' Y9 N3 R5 @: k6 `& O
/*'======================================================*\
6 Q6 n8 J, F, D+ W'根据文件名,确定设备
/ Q1 | O. k, v* U( Q W) [$ f* I\'=======================================================*/6 G/ ?$ P! _; ]6 [% b
LPSTR GetDriverID(LPSTR ff)6 D' Z( v: D2 c
{
) Z1 P I Z2 b p3 ?& ^' x char aa[3];
1 J; H: ] E2 y+ h* U5 x# f int i;
5 U7 D S: t' s# O- S6 `% o* z; ~ char bb[3];
: e8 U+ R% @2 O' w- r4 c. ^8 j6 C int lenff=strlen(ff);2 D' v% O3 J; x" s
for(i=0;i<3;i++)5 I8 }# `+ N J% V& z
{
4 v9 [ X2 A: y4 j aa[i]=ff[lenff-3+i];8 U# z' z5 n: k- J4 ~+ T
if(aa[i]>=97||aa[i]<=122)aa[i]-=32;
# ]( l, o- m3 }1 r5 [( X4 G( ~9 h }
4 _; i- S# Y2 j5 b% F' o aa[3]=0;% @3 k$ i; n6 n5 ?
strcpy(bb,"MID");
S' U' n, l1 Y* V if(strcmp(aa,bb)==0)return "Sequencer";1 p, H2 H: q( z7 T' G
strcpy(bb,"RMI");
; V9 O: C+ N. B6 V! O7 v if(strcmp(aa,bb)==0)return "Sequencer";4 q! U8 j& q k
strcpy(bb,"IDI");
9 Z' `/ W/ n: Y if(strcmp(aa,bb)==0)return "Sequencer";0 i* g1 p9 b9 ` S
strcpy(bb,"WAV");
; ^6 B$ R/ {" ^' Q5 ~! Q, o if(strcmp(aa,bb)==0)return "Waveaudio";8 c% X, n: g) x. p
return "MPEGVideo";
6 Z* C% Z, A$ `* s}1 @9 R/ ^3 E: u
8 r% y; e( H7 r$ i, {//=======================================================1 \, l! f3 P1 u0 o$ g1 O: n
//打开MCI设备,FILENAME为文件名,传值代表成功与否
% V p* S; t5 U# d//=======================================================% R4 S: y% f6 C0 H A
bool OpenMusic(LPSTR FileName,HWND hWnd=NULL)* `: E2 r3 X3 u+ w0 T
{9 ~( Z L8 h# P1 W0 f+ ~# L
CloseMusic();
; A- _! K4 x8 a* s CString ShortPathName;
5 J5 C4 O. s' T CString tmpStr=FileName;
0 r2 ?( h& ^4 y if(tmpStr.Left(7)=="http://")
; v5 Z* y+ l& @( Y ShortPathName=FileName;8 |# B2 z/ a5 O3 |) F4 I& `
else) k) T6 A' _5 {9 r8 b
GetShortPathName(FileName,
( n) R4 x5 K7 j& S ShortPathName.GetBuffer(0), 255);
& d8 ?2 m" p8 s; f9 u// MessageBox(NULL,ShortPathName.GetBuffer(0),"",MB_OK);
2 |& l/ \5 f% ^ Q" g5 p m- E- R char *DrvID=GetDriverID(ShortPathName.GetBuffer(0));' \# l' w* H) O6 R3 c/ ~* S
CString lpstrCommand;" e5 j7 B6 I1 D8 l+ E
lpstrCommand.Format("open %s type %s alias NOWMUSIC",
! U0 B! ?6 [) y! c. g7 W+ ]" K/ S ShortPathName.GetBuffer(0), DrvID);
2 F3 o/ L* |3 y4 y* x2 W1 P if(strcmp(DrvID,"MPEGVideo")>=0)
6 s$ Z p9 i) M, s6 q R {
" @/ r; {4 C* U, u' |* k C5 z# M: N if(hWnd!=NULL)* C+ W( K3 W x( c
lpstrCommand.Format("open %s type %s alias NOWMUSIC parent %d style child",+ {0 I" W* p @& |" {+ h6 v& \6 `
ShortPathName.GetBuffer(0), DrvID,(int)hWnd);
+ D- ^8 O0 b5 g2 x/ o1 q7 L else lpstrCommand+=" style overlapped ";
& c& a# S h6 X2 a }
, [/ `' k4 t7 L9 d; D if(mciSendString(lpstrCommand.GetBuffer(0),NULL,0,0)==0)
- U/ x, x3 [* _# x {
; E) T" L0 t' x3 m% ?. m OldProc=(WNDPROC)GetWindowLong(GetWindowHandle(),GWL_WNDPROC);/ v; j5 M$ u2 c& ~
SetWindowLong(GetWindowHandle(),GWL_WNDPROC,(long)MCIWindowProc);) ^$ n) {; B: v; w8 ?8 r+ v
return true;6 E: {# o$ _6 P0 ^3 D! B
} i; U$ Y h: S7 ^/ {* g
return false;4 l6 G5 _( |. k+ I/ R1 h4 e
}
; B3 f8 ~( y$ C9 ~1 h- _$ B4 X' D4 ]+ C' j% q+ i
//=======================================================& F+ I( a$ | p% E9 {8 o& `. k
//关闭MCI设备,FILENAME为文件名,传值代表成功与否$ n1 S- @2 B4 E& u! U
//=======================================================7 [1 J$ m3 F8 g4 P3 r
bool CloseMusic()+ P. {. B: J# K% y% v7 r( |
{' R' Y: |. N+ M) J1 @. G1 U4 F
if(mciSendString("close NOWMUSIC", NULL, 0, 0)==0)+ {; X+ L7 L$ `# P% V$ \
return true;
% ?0 {, a& P# G0 M- { else return false;, U2 }% e# l/ o- s2 @
}
% C3 B+ g( }+ X. d3 w//'======================================================
* I {- z5 t0 w- V' L, v. k//'播放文件
! f0 Q- q/ m" D3 b3 O8 X//'======================================================6 _. [- x7 R* \. Q
bool PlayMusic()
! [ |1 m# U0 f7 _{
3 D$ x0 v1 r) Q3 X if(mciSendString("play NOWMUSIC", NULL, 0, 0)==0)
- K7 L3 E" `+ r, y" B+ C return true;
% {3 P. f5 Y. i7 ?2 }2 R. N else return false;/ o$ g' E3 m" S3 b1 S% Q1 x: V
}
+ I2 X0 q% i& ? ^) M( ^! l3 n//'======================================================4 Z) K# Q0 Z6 |+ l8 r- K$ e
//'获取媒体的长度
9 O5 R/ M- M J0 t- X//'======================================================
# o& r3 N3 M4 A: ]long GetMusicLength()
0 z/ A( a' j; l5 W{$ {8 G, S m$ m! p9 D
char RefStr[80];4 n9 m E+ e' g
mciSendString("status NOWMUSIC length", RefStr, 80, 0);
$ g' R2 @5 c0 h/ y return atol(RefStr);
2 T1 x9 p# T' @! p% B} g* j+ X2 x" G3 K9 a2 \
//'====================================================== r) Y- Y8 g, q
//'添充画面
; p: e8 E) m; E; u: a; s$ J//'======================================================" m) ^$ q# V) @" u( a% D4 A( N
bool PutToWindow(RECT rc)
! S( ^$ f: {! K; S" w Y2 w8 @( }{ c2 B1 t. U4 B8 X# q; C% j+ F, f- `* V
CString lpstrCommand;5 C+ U$ {; H4 z" y" t
lpstrCommand.Format("put NOWMUSIC window at %d %d %d %d",8 P" `3 h `- k: q. n3 T
rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top); & q0 \! G8 V! l1 c) S
if(mciSendString(lpstrCommand.GetBuffer(0),NULL,0,0)==0)* J6 B' R4 F% U- l6 J, U3 _
return true;
2 y L3 A8 S. ?, C! ?6 \! K0 i2 T else return false;
% m' M/ C# m6 w. P1 L/ j- G}
, y s; S$ H# V& K) C+ b- K4 [4 ]: B4 b7 j6 B* i
//'======================================================8 [* o4 {0 Z1 `; y/ n$ y( F- V1 U
//'获取当前播放进度
5 G; R4 T2 g: g+ X' W, U( X8 x//'======================================================! a, b4 ?( H9 B: l, M7 m& l
long GetMusicPos()
" {3 X- N7 j9 Y [{! E9 H8 b( I4 v7 s& y+ A
char RefStr[80];' f5 P; g4 p" _& x. s! ]9 ^
mciSendString("status NOWMUSIC position", RefStr, 80, 0);
6 w4 J7 n. C1 J4 y+ d return atol(RefStr);* b% M: s% W) U9 c: I. R/ U: E
}
: F' G2 {$ D+ w! _# h W; f/ \9 D//'======================================================6 m! H3 _- z4 g
//'设置媒体的当前进度! V& @& J# P8 j) W8 Y
//'======================================================4 C' y3 y, w7 j6 w6 ]8 i
bool SetMusicPos(long Position)+ u! _2 H0 {$ x% f/ S
{
7 E. `! A* C( u D CString lpstrCommand;
" d6 R0 F% ^4 _. L8 a% } lpstrCommand.Format("seek NOWMUSIC to %d", Position); / M2 S; z- j' C8 o' D
if(mciSendString(lpstrCommand.GetBuffer(0),NULL,0,0)==0)
8 j4 _! E/ {6 M$ v' q5 w7 V9 r return true;
, J+ ?6 p2 V; H" G else return false;
# b4 }1 _) C, }, G( v: b}
% W& W/ B4 Q. F) R//'======================================================7 M0 m% V" e" S% ~9 ~: M
//'暂停播放
' y" Z- A/ R5 ?. u0 m//'======================================================
( F; [3 H; L) L9 s& jbool PauseMusic()5 o2 y# ]% j0 j
{6 g0 V# y5 [ `" w4 E n
if(mciSendString("pause NOWMUSIC", NULL, 0, 0)==0)5 N: R% D+ p6 y6 z! R- d, p# [& V
return true;: T+ I0 P6 f( W& ~0 t2 ~5 o
else return false;% v+ ~+ W O/ m D$ u c. F
}+ e3 g; B- c! D( @! c+ F
. J7 b9 K3 ? I0 A2 v/ l4 s& ]
//'======================================================
% d. f" q; S5 l9 C* H# M+ x" Y//'设置声道
8 I( |9 U+ n+ q% ^1 W//'======================================================
% i/ B o$ M! F! n: n9 b4 t% [7 Abool SetAudioSource(int AudioSource)4 q' t0 w& {" H1 A( x
{
# ?0 W; a: Z8 W7 E) \3 A CString lpstrCommand;
' w c. p& B* ^7 K% B3 Q lpstrCommand="setaudio NOWMUSIC source to ";
* j3 a. T/ j+ U7 p switch(AudioSource)
) ?" n7 b9 j/ V) J {: _) p, h, P! A: @$ J) t/ Q9 z! S7 O
case AudioStereo:3 r$ H$ L5 h' _- A& [6 ?/ N
lpstrCommand+="stereo";6 X6 [ A) C y" ^, Z7 m
break;
, K# v6 h `5 y" D0 R case AudioLeft:3 V( K( I5 T0 A! W {5 O
lpstrCommand+="left";
: M3 h6 \( C J. P0 U break;
2 J/ x$ z7 L3 }. E4 ]) x5 d case AudioRight:
* t; u+ l0 ]& o: r3 R( W% o lpstrCommand+="right";, G4 s6 e% G7 G4 o5 \) K! R) Z1 [: C$ e
break;
( r5 r. D2 W* z* `# {) Q; _: ^+ `* L }" Y( G) F# E2 _. G3 t5 n- [
if(mciSendString(lpstrCommand.GetBuffer(0),NULL,0,0)==0)! X `9 y5 |" U3 Q; [/ A
return true;
' n9 ^) {- R. I# P) J8 k+ A else return false;9 Q1 H0 T6 @0 b8 u
}+ Q0 r/ ~% t- T; e& K0 J
+ @6 ~# x, f- b. P" `( K
//'======================================================3 v& {* A8 v0 P
//'全屏播放: @$ t; \3 o# F0 u
//'======================================================5 u) e( P' K$ x$ N; Q4 n
bool PlayFullScreen()# k$ M0 H; n2 D# J3 ]0 ^
{
a3 `) Z5 \% Y4 d+ ^$ o5 ? if(mciSendString("play NOWMUSIC fullscreen", NULL, 0, 0)==0)
6 U+ K$ `, Q9 U/ Z) g return true;
: \5 a& h; R Q3 }9 A else return false;& ~% _8 N$ f; l7 A6 R
}
5 z+ l% N$ M2 D; }& c: C6 N$ ~! E$ K* r, @7 j
//'=====================================================
1 e7 y- k) ^( c4 Q( J//'设置声音大小1-1000$ N( V5 k2 z6 u! {% ~
//'=====================================================6 ~( p2 T( g0 Z# c
bool SetVolume(int Volume)
; f3 t! P3 |. w S1 s{/ b$ [$ }; W9 |) T; E# P1 W. t
CString lpstrCommand;$ t& q E# T% `# z
lpstrCommand.Format("setaudio NOWMUSIC volume to %d",
t) X' l4 [0 n) W3 q Volume); 5 X. V; N" N' a2 f
if(mciSendString(lpstrCommand.GetBuffer(0),NULL,0,0)==0)
; [ O8 N( f7 W; l, w1 _ return true;
# i/ z7 _& Y& _ else return false;& ]% o$ B( [# L1 Y+ x# Y& Z
}
' F! ]. G) D5 U
1 P& G4 C8 O+ s' t& u, v//'=====================================================
( H9 h) k; O) g* _//'设置播放速度1-20009 c2 R E0 n+ K# I% @' ]4 ]
//'=====================================================2 S! x9 X8 l! V! {4 r. n
bool SetSpeed(int Speed): J/ J4 {' g+ \7 `$ l7 D
{
5 O, d1 ?6 f9 M0 ^& o CString lpstrCommand;
6 i# x2 ~& P: s7 ]- [ lpstrCommand.Format("set NOWMUSIC speed %d",
8 r5 w$ _) \3 t9 u6 P Speed); / I4 D1 L+ C2 {" D: B2 V1 S7 G! O
if(mciSendString(lpstrCommand.GetBuffer(0),NULL,0,0)==0)
& f/ x) R* R. _0 u* {: B# R return true;
, K* {" l& J3 Z% s0 A( L else return false;' v. e, c. g" h$ ~
} B3 A; a1 N& N, `7 v; l, S, ?" X
//'====================================================2 T9 J A8 R9 A; q4 M/ {
//'静音True为静音,FALSE为取消静音
7 V: M4 E! D" j! R# R//'====================================================
8 Z6 I& ~ i8 k! g$ Zbool SetAudioOnOff(bool AudioOff)9 M+ _3 E, [ N$ H* z
{
, q) A* R+ J6 T) Q+ ~ if(AudioOff)' a# Q$ @; \1 }$ A( Q5 I2 }, q
{/ y4 v2 G3 o& ^! ?
if(mciSendString("setaudio NOWMUSIC off",NULL,0,0)==0)3 G. U! C! @( @$ `
return true;- {7 B/ D ~0 j' U+ X
}
: m. m; y0 X5 n0 U6 S3 K/ E else{
% n. [0 s+ K1 c4 x7 _$ k, B% W if(mciSendString("setaudio NOWMUSIC on",NULL,0,0)==0)# _4 s! k3 \9 E) v- t- M) n
return true;
. I* x$ J7 h6 \! p6 t }
( n: O* O! L3 J return false;% }# |& a7 [! j$ S
}
' p# y2 E( x7 S1 z/ n4 u( @) n7 W$ d/ o5 a8 n7 a5 [
//'====================================================- {7 w$ B6 M' E
//'是否有画面True为有,FALSE为取消1 N4 K+ Z7 v$ x* q) k' f
//'====================================================5 r d5 z" G' x% [% t
bool SetWindowShow(bool WindowOff)/ E7 }$ e4 e3 o8 E( ]. ]
{" v- P: b8 a9 j R% e
if(WindowOff)$ l/ m6 F! h/ r9 @& g
{
( L/ L$ t" s+ v if(mciSendString("window NOWMUSIC state show",NULL,0,0)==0)$ \3 j7 n; B( K5 y+ c' R1 [) P/ k
return true;7 r8 v! \. ~4 B; `3 @1 J! e
}
E# }( Y% C5 V7 ~9 D$ w else) ^0 C& X& m- |8 r+ u
{! _8 M5 D5 l( p
if(mciSendString("window NOWMUSIC state hide",NULL,0,0)==0)
0 @4 |: w2 T0 r, a+ K. v1 w' l return true;
9 s% |& ~8 K0 M5 ]2 @9 f7 x }
* x, o. j$ p( V' N& N return false;
7 |/ i( I7 o: k1 X6 m" `}0 f: F7 _' c# i3 V
0 m0 f& U9 C. P//'====================================================* K3 m* y7 z) M- Y
//'获得当前媒体的状态是不是在播放7 ?1 F* t. x8 x8 N( Q8 J
//'====================================================( ]3 p. b! \0 }9 j6 f# q% J" F
bool IsPlaying()3 i3 B% X3 {1 X. q' P$ y$ E
{' m/ H2 @3 v) i/ M' Z; u
// char RefStr[10]; P/ k. {% i; O) O
CString RefStr;
$ N% m1 {5 v9 E7 N [7 i/ ~ if(mciSendString("status NOWMUSIC mode", ( e; i) i7 v3 u$ o$ ]$ _! j
RefStr.GetBuffer(10), 10, 0)==0)
# K; f) ^; E' k1 i) Y6 Z$ o {
, s( M' k) m$ G if(RefStr.Find("playing")>=0||- Y. i9 s7 Z$ b
RefStr.Find("播放")>=0)
4 U* v7 r' o1 Y- t( e/ Q/ z return true;+ M" B9 [! ~: H7 i$ F2 ?2 Q
}5 P7 c' c" }$ e V5 D
return false;2 D4 T; I9 m( h8 {, _
}
; I( w/ `; |) O) H1 j2 x* u$ b, w) o D/ Q9 F
//'====================================================# M- d2 j1 g3 X$ y
//'获得播放窗口的handle' R* f/ e4 n3 u; N1 T
//'====================================================
5 C0 @4 {: v4 E1 {HWND GetWindowHandle()
( L+ \, M+ s* x: `. R1 X{
# N, m* I8 |5 ]0 b c5 F char RefStr[80];
1 u8 w1 @2 Z5 r- d4 C% l mciSendString("status NOWMUSIC window handle", RefStr, 80, 0);
|2 [0 V# w) P4 Q; u4 l; y- h. v$ A" s" F return (HWND)atol(RefStr);
+ ~8 m$ P, y* d2 s/ A9 k}
" R6 X4 F1 K7 L% p) x% F4 z, b5 T) _) }3 c2 ^
//'====================================================
, `% n) A* ~ v6 {5 \3 ^//'获取DeviceID
2 E- z8 g! {0 F, N5 }7 x! M) }, W4 Q//'====================================================
2 N0 w& l1 A& AMCIDEVICEID GetDeviceID()
0 z2 ` P4 s# o% W{ n6 Q$ K6 r6 u3 ~
return mciGetDeviceID("NOWMUSIC");0 T6 y3 x) O6 N: X
}. q7 K2 l2 X& z2 G( y# D0 y' Y: z
5 @8 L0 T f- A: \& O+ l
//'====================================================
& R; U; _3 `* N; f t$ a//'处理窗口事件 n ` ~8 }8 b/ X4 i" e( W/ F
//'====================================================; T+ B6 T1 S/ u3 A+ O
LRESULT CALLBACK MCIWindowProc(HWND hWnd,UINT message,
" o1 p5 a- g% ]( X, f0 | WPARAM wParam,LPARAM lParam): n; E' m/ q' p: J7 k
{. q o$ Q1 J: ]
// HDC hdc;
$ L' i0 l# ~6 n6 p8 w int wmId;8 ?: v- `% H, ^5 L! v9 T
switch (message)
& I7 j; X* I1 P& ]* d {, |* D, j5 K5 E: v
case WM_COMMAND:
* f+ w5 i4 d# W: W5 h, d wmId = LOWORD(wParam); % S- A: Q1 k8 p% I" K
//MessageBox(NULL,"OK","sd",MB_OK);2 f A% W6 j3 U7 W
/*switch(wmId)
% E9 _ ^' |' g( {! Q2 W% Y {
% @' K9 T6 a2 Y! d( S default:7 s2 n( b3 A* p2 Q
break;# K O* ]5 j4 h# t
}//*/
* E5 Z2 E" A4 P2 P break;
9 ?" `0 T1 P7 T3 K3 X' g$ i case WM_LBUTTONUP:
# `% o1 V- K! K: U# S, Q3 K4 p; v% P return 0;+ \3 p9 ]; q- F0 k
break;; P @+ R6 Z5 G! H ^4 R4 t
case WM_RBUTTONUP:
$ k7 Q' M( [9 M: n POINT pt; 4 J6 B0 o( V, N' x4 J7 [
GetCursorPos(&pt);4 |" B- J# Q7 |8 D3 Y
break;
0 Z. i& I3 f$ I5 k" x2 w case WM_PAINT:
i2 J4 W0 T+ m F( y. _ break;. [& w/ s u8 J8 ^+ T, h
default:" Z0 u( k4 [5 s2 I2 ^0 \
break;; ?& \8 R9 u* M/ V& n
}
2 Q" J I3 M3 |3 c! o# p return CallWindowProc(OldProc,hWnd,
8 z' l6 c+ D* W2 s5 O) K! A! Q message,wParam,lParam);
$ s& I9 v+ z% l) T: R# W- f} |
|