|
来自: http://social.msdn.microsoft.com ... 9-a8c9-2e27eb9ec0584 ^8 E" l8 w. {( N6 F
By Mukta & ToxicDream- 7 D, S3 }$ c* H/ K
- //for delphi 5
0 e. F: x9 R* L+ [3 U) l! a0 N - unit MMDevApi_tlb;7 N4 c; p6 U1 A# G% R
- * l2 Z; _0 }% a) o9 ~
- interface
! n) l! q( ~: v) a& _8 ^1 }$ v - uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj;
0 K3 Y, p, y, T0 p - const
' U) A( J4 K" ~ w( q: R - // TypeLibrary Major and minor versions
3 Y& e/ k u; e4 T( s. m6 g; \
2 ?* O+ n6 h% W- w8 s- CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';6 F* }' V, |) ~1 q2 Z
- IID_IMMDeviceEnumerator: TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
% o a5 j$ \" Y8 _6 R& @ - IID_IMMDevice: TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
& u, a! d4 C5 @1 { - IID_IMMDeviceCollection: TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
- P0 T5 w5 H; C( c; d1 c3 l; p - IID_IAudioEndpointVolume: TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
. k; \# a( R+ | - IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
! |0 L, K0 @2 b% O; p+ R - IID_IAudioEndpointVolumeCallback: TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
- W$ ~# I0 n6 z - 5 F9 R/ l7 \7 X5 n, B$ z
- DEVICE_STATE_ACTIVE = $00000001;# {* U3 R- ?* G: f8 K7 ?: s
- DEVICE_STATE_UNPLUGGED = $00000002;; q+ w; ]0 j G) k. X
- DEVICE_STATE_NOTPRESENT = $00000004;
0 E3 e+ h8 B8 z5 r* _4 L+ z - DEVICE_STATEMASK_ALL = $00000007;( d/ w7 T; f7 V9 ?3 Y
- a, H' Z- i# S& k( F+ m$ W
- type- k8 a) q- G9 u- M
- EDataFlow = TOleEnum;
3 S1 N! Y/ D. Z. O& J$ s - const
( f2 C1 y6 W, U2 G. G# |: J - eRender = $00000000;
; I( [2 ]$ E6 K( ~+ v - eCapture = $00000001;
( m) }5 l: F& | - eAll = $00000002;. F$ V* l( [5 Y. A' W/ P
- EDataFlow_enum_count = $00000003;
1 d4 B t* d( ^0 X
7 b- y1 H) `" w0 T' K4 {- type
& h; @) B. a% U9 ^ - ERole = TOleEnum;: D7 Q" [/ k5 o2 w5 l* o4 N8 C: i
- const
% q& r. ~' ?8 a& J$ @ - eConsole = $00000000;
" ^2 G3 F% |8 z; p: Z/ l5 R - eMultimedia = $00000001;
; y$ L( c# W& |6 ~8 Z - eCommunications = $00000002;# J7 K2 n: z9 A! Z' E1 w
- ERole_enum_count = $00000003;
% C' p/ O% {( v$ e: C
* Q( Y1 M+ e; j5 o5 \- type
9 O4 N* d8 z" K1 C) W7 b - IAudioEndpointVolumeCallback = interface(IUnknown): `6 S6 I' G+ S( h% d
- ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
' \& P; J# h3 b) }7 U# z - end;
% S3 C0 A+ O1 k; P6 o0 U3 L) V
5 T' W' m$ D% R' c' {* m) Y- IMMAudioEndpointVolume = interface(IUnknown)- E: N3 B8 E$ ~3 J/ c
- ['{5CDF2C82-841E-4546-9722-0CF74078229A}']2 W( \0 X. C6 l9 \* w5 f
- Function RegisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
. w: d. Z9 F% I/ ~1 [. p0 J9 \ - Function UnregisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;1 T+ O& D8 u# ]
- Function GetChannelCount(out PInteger): Integer; stdcall;' p. V* G& R# q- a! v
- Function SetMasterVolumeLevel(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
9 X" n& F0 `3 g" D" [ - Function SetMasterVolumeLevelScalar(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
A: Y* B" U' G% F - Function GetMasterVolumeLevel(out fLevelDB: double):Integer; stdcall;
6 l2 [3 \2 H0 w' D0 |& F - Function GetMasterVolumeLevelScaler(out fLevel: double):Integer; stdcall;& r, B- p( y# e
- Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
+ h* |- `. w) h' g - Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
8 ]: l7 A6 ~. v, z! Y( J - Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double) : Integer; stdcall;) g& j& X4 L) |' J2 W
- Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double) : Integer; stdcall;
$ U/ O# a/ L# _& c7 K* M$ F - Function SetMute(bMute: Boolean ; pguidEventContext: TGUID) :Integer; stdcall;* s H/ x0 [. e [5 X5 b, u
- Function GetMute(out bMute: Boolean ) :Integer; stdcall;
6 v4 A+ _( ]+ C# P* B6 x - Function GetVolumeStepInfo( pnStep: Integer; out pnStepCount: Integer):Integer; stdcall;6 ^/ a1 {& ^% L4 @9 Y( N
- Function VolumeStepUp(pguidEventContext: TGUID) :Integer; stdcall;
! ]7 d- N! |6 U R* U - Function VolumeStepDown(pguidEventContext: TGUID) :Integer; stdcall;# N1 x7 `; I6 A3 a
- Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;5 S9 `3 |4 Z5 ^- |/ K
- Function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;4 N. E( M. B# o
- end;! e9 g- x0 {: j# | @& ^
- - @9 [3 Z7 w/ {; h4 j% h% ~) _
- { IAudioMeterInformation = interface(IUnknown)
+ m: W; q' V: C/ { - ['{C02216F6-8C67-4B5B-9D00-D008E73E0064']
" ~% i0 s$ R4 K. x( U - end;}# u/ E) V: ~7 u: t7 j8 |; @. { d
- 0 C/ k7 k; ^; v( @3 G2 s) B. R
- IPropertyStore = interface(IUnknown)% r" @% [% O6 E* U! v9 D) a" C
- end;" n! y4 P( M; y
9 z. v. n$ |4 D* b; U- M- Y- type5 I4 M8 Q) ~( ~+ n8 x
- IMMDevice = interface(IUnknown)
' I( w4 d) M* |- Q ~) n$ E - ['{D666063F-1587-4E43-81F1-B948E807363F}']8 J% G5 o: Q6 T: R' \- V) N; v
- Function Activate( refId :TGUID;
5 l2 M' D+ W* I+ [ - dwClsCtx: DWORD;
* t( ?7 b& T& n6 J O5 H1 i - pActivationParams: PInteger ;) t6 p3 d4 y( j+ C
- out pEndpointVolume: IMMAudioEndpointVolume): Hresult; stdCall; v& Q" ~6 f' Y" j% J
- Function OpenPropertyStore(stgmAccess: DWORD; out ppProperties :IPropertyStore): Hresult; stdcall;
7 z- v, \4 F3 X7 ^2 t% |7 a - Function GetId(out ppstrId: PLPWSTR ): Hresult; stdcall;
( [6 F5 v& G, A+ q2 T8 Y - Function GetState(out State :Integer): Hresult; stdcall;
+ t) k/ Y! C& ]* x7 \$ ?! {& ^
0 k$ x }1 B! K1 a; B- end;
. P0 c5 A7 [+ I2 x
$ t- m4 |& s8 Z- + x0 }) _& x8 {7 q6 b0 D) A, }
- IMMDeviceCollection = interface(IUnknown)
7 Q4 S* ?6 y1 M" i, t7 c - ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
$ ~! I( y( Q: H - end;. {9 B' j( Q) \: O# j
8 m* F) J. A4 [/ |$ {- IMMNotificationClient = interface (IUnknown)- }9 Y) v3 @: X
- ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
1 J8 L1 n3 i8 W - end;
" }# F) g7 C+ { - $ J3 k) @/ I+ G; p
- IMMDeviceEnumerator = interface(IUnknown)9 z- d7 L& F0 l5 g# \* [( P6 f
- ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']- b. y* _/ H1 a8 }; @ G0 {$ O
- Function EnumAudioEndpoints( dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection:IMMDeviceCollection ): Hresult ; stdcall;. Z# o8 Q2 _( K8 w. L
- Function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult ; stdcall;8 T: R9 O0 ~+ C, I
- Function GetDevice( pwstrId: pointer ; out Dev :IMMDevice) : HResult; stdcall;
& [5 }* S0 j4 ?$ @+ n - Function RegisterEndpointNotificationCallback(pClient :IMMNotificationClient) :Hresult; stdcall;& m% R9 q0 I; r" I* c& H/ k
- end;
3 U* I: K* o! q0 i - ; A& ~4 X" K$ T: A- M. z7 ^( J
- implementation
5 c5 n( y3 X# {" ]/ ]+ \* R - end.
& F" Q( a6 E/ P1 D) B( f - - C! ~. k' H) W; z1 Q8 Q9 M2 c
- Thanks & Reagrds,4 e: M. [# k: S
- Mukta ...
5 K+ i2 ^* v' F
复制代码
% D; s5 E- R9 P q- O' }- it's work in Delphi 7
, b$ w$ p B' i0 M* L$ S2 G7 S6 U - //////////////////////////
" | Y; V2 `0 G! L6 |, H$ j% J# Z9 [ - - K; P+ A: Z3 J( Y! H" C4 _
- unit MMDevApi;
! T8 c2 K2 [+ |/ ?; l - . F/ y. h, N$ G: }# L
- interface
, G3 B b0 ~0 X: t2 m5 r% g* a& O - + R+ v5 b ?7 `, H% f
- uses
3 f# B* W8 t/ x! p u - Windows, ActiveX, ComObj;5 H& Q( ?0 D/ h% A
; G2 E( l7 V, L% y- const
3 q' k' z0 [# z3 f - CLASS_IMMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';+ f) [; U6 X) w2 Z6 d
- IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';4 f0 b" M+ H7 J3 w; ]! `
- IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';% A) _7 p) q4 ^. Y4 T x- q" U
- IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';9 _" u5 N p2 e3 M( d4 o
- IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
! w& `- g+ l" {! R1 B1 U" _2 T - IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
& J( {5 o. S' y! k& [4 z1 ]3 ?9 x9 ] - IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';2 d& e; A! _5 }# l6 E/ f
- 0 C8 M# [% T6 x. ]7 E
- DEVICE_STATE_ACTIVE = $00000001;& O. d: B( F- T9 {. A
- DEVICE_STATE_UNPLUGGED = $00000002;# u5 A9 k! d( t5 j
- DEVICE_STATE_NOTPRESENT = $00000004;
, g- I( a+ S1 S! k6 T - DEVICE_STATEMASK_ALL = $00000007;* _0 j# ^9 G5 b3 E( u* t
( h- p- Q P0 |6 N* o- type
( w1 j7 R: C6 ^ - EDataFlow = TOleEnum;
* ?# J1 C9 y2 O0 X5 \9 v
% Q9 q% D! Q8 N( _7 ?" n- const! |9 n4 F% R7 ~, s; l( }1 S
- eRender = $00000000;
2 W/ G8 v) O7 R, ]1 s - eCapture = $00000001;
) j* E# t' p6 h3 L1 L% B - eAll = $00000002;
! @! ]- Z$ w& F1 \: N - EDataFlow_enum_count = $00000003;
4 ^( p# h, {8 p( i7 G3 U
: k3 U7 N7 s: V: E) E! q/ E$ b5 x- type
0 O4 ?3 N# p( Y8 r+ @2 Z - ERole = TOleEnum;
% ^0 x7 X6 e/ ^/ W$ q; T - 9 R2 D5 ~. [9 e
- const
6 K. `" H* w3 m - eConsole = $00000000;
6 f) D9 i* e1 H; t0 q9 j - eMultimedia = $00000001;) f. C; R( i- b5 h
- eCommunications = $00000002;
J# q0 E- y; M- q" N( a0 x5 s - ERole_enum_count = $00000003;1 e! s E5 J2 M9 G
! E, o' @; H! b' Z. E! f8 w- type8 I3 ` ?! m/ i! e9 z1 h7 Y9 ~ ?8 c
- IAudioEndpointVolumeCallback = interface(IUnknown) m: A6 Y5 g) a8 y' ]3 Y3 Q; B
- ['{657804FA-D6AD-4496-8A60-352752AF4F89}']) E+ x: x- i( C/ C
- end; j @7 W" Q% T& D
- 2 P% _. P: g. S! ~
- IAudioEndpointVolume = interface(IUnknown)/ Q+ e. _' N- o" D% ?* K
- ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
5 ^" Q1 i+ ]! `3 F6 ~ - function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall; q) j, P6 B7 r1 m( c& f
- function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
7 b! K* C: j" u4 f/ P E0 b( n- U - function GetChannelCount(out PInteger): Integer; stdcall;
/ l3 a+ \( x2 {, A! l5 u8 ?3 G - function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;# p5 Q( }8 k% _) ]# a. k3 O" ?" m
- function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
2 O" x4 _% i- u - function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;: C1 |% w" T4 h& x; f
- function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;
! z5 e) H9 h6 C' g0 e. i0 n, z* { - function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
* v, J, E% n; M7 u - function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
/ G' W6 Y0 ~, i" Q, U - function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;8 `6 S1 U# G$ ?
- function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall;, `6 t. Z1 l& l2 }) p
- function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;* i* E3 v6 j/ z( Z |2 U
- function GetMute(out bMute: Boolean): Integer; stdcall;3 K2 W3 I' ^1 M ?2 X
- function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;
) D |, s$ N/ Z/ L$ `2 m$ c - function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;) w1 \5 l1 T M0 s
- function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;4 ?/ C c6 T8 j+ U2 E1 a
- function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
1 k: i1 \( K, v. u6 L( { - function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;$ O9 N5 a8 C9 M8 A, G3 k. f4 P# n
- end;% D2 S9 o+ m4 b ^0 `: C/ _8 B
- % }; |/ R: ~8 k0 I- r% f
- IAudioMeterInformation = interface(IUnknown)
; N$ c* i: E! M2 e. J9 ] - ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
5 a) p) W7 c) R4 m - end;( e5 v/ x- A9 o% ?# S9 `7 r
: Q5 q# J! [1 C5 `$ W2 v+ I- IPropertyStore = interface(IUnknown)7 M7 V5 l# l& h% o$ ~3 q% S* B
- end;
" T* ~! X$ h* w' ?$ C4 N# c- c - , A: E/ r: p7 c T
- IMMDevice = interface(IUnknown)9 ?- n' x, Z; `, S5 P4 b( E
- ['{D666063F-1587-4E43-81F1-B948E807363F}']2 z+ c' ~# _5 U
- function Activate(const refId: TGUID;
; h) J+ ?" E( C! D1 w. S1 e - dwClsCtx: DWORD;, f) D1 B$ K5 t( T, y7 @
- pActivationParams: PInteger;: c3 I) F2 C/ l* L* w- |
- out pEndpointVolume: IAudioEndpointVolume): Hresult; stdCall;% S u y0 a* x% B1 O8 v( d, c" x
- function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): Hresult; stdcall;% _/ @, ^6 I* S5 w7 t
- function GetId(out ppstrId: PLPWSTR): Hresult; stdcall;( I0 H5 X" m. K, _. }* a5 T1 S4 a7 G
- function GetState(out State: Integer): Hresult; stdcall;
7 d5 g7 a5 P4 e6 C* x+ n: p - end;
' q) X: C6 n5 _" w" A
1 B; c( e" A& ] z; @2 X7 [
( j9 ^8 N) ?3 L+ L- IMMDeviceCollection = interface(IUnknown)
x; o$ v5 F7 ^4 X - ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
, F7 a" _; k- m' [3 Z: U - end;: X8 _5 r c; k$ Z
- , t8 ~8 A# [+ p5 ?2 l
- IMMNotificationClient = interface(IUnknown)( ~+ {6 x7 A+ [9 w2 ?2 m( b
- ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
6 W3 m9 T# b. m5 e- a' b& V - end;
4 u) S3 I6 `- j' @" H - 1 l: w5 W. @. W, D7 @6 U/ H
- IMMDeviceEnumerator = interface(IUnknown)
1 W) w0 _. w5 c - ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']: M& K1 \* R- Q0 v( M
- function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): Hresult; stdcall;
3 R% s1 l3 |( f9 Z - function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult; stdcall;( \/ O; T5 m1 M% V' @
- function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HResult; stdcall;" |6 }! j2 `3 R- o/ Q0 {( C, Q0 {6 o
- function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): Hresult; stdcall;% x; d4 o+ z7 M3 A8 m6 @% d7 L
- end;( Y! A4 J# O9 \' N" W) ^
4 p( e) ~5 W7 E+ m9 ]4 g- implementation
/ |" G1 R7 V4 [0 h, s- j- y - & |, c9 H# `) ?- M/ c6 t k O
- end.
* x* p \, @. A3 u! h1 `3 E3 _
9 u( F6 p. B* |$ } S' z5 ?- ///////////////////////; e& n. O6 h8 v! B, t
- simple sample :)
( V& G4 Y- b" p3 b - ///////////////////////
8 f6 @3 A3 Q4 G. ]7 [ - $ T1 L9 ]2 p! H) a5 c! e
- //...... other code
6 |/ m& D* ?; @ - I) c; F3 X) d/ S) K
- uses ... ActiveX, MMDevApi, ...;
" P0 t/ K$ e1 x F0 a! N/ d - ( L6 z' n7 Q r! a% Y2 i0 f+ v9 {
- //...... other code
: O! N$ A, V% G9 q& j) a$ b - ! j1 ~3 P4 Y ^' _4 g! ^& B* t
- var
1 x u8 y3 t. ` - endpointVolume: IAudioEndpointVolume = nil;7 N q {2 Q4 u4 B
- % m! P5 [/ [/ {
- procedure TForm1.FormCreate(Sender: TObject);
% v2 [2 o# b) U2 j1 Q2 K, m - var
9 x2 z7 Y e* M2 V# S3 h - deviceEnumerator: IMMDeviceEnumerator;1 F8 j8 C/ l- \! ^
- defaultDevice: IMMDevice;2 Y! A: u$ K a4 g, h
- begin
( Y7 t& w. e# m& o8 d) P - CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
+ x& J! V( E& s8 ^ - deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);8 M- D. K2 p$ c- s& A
- defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);& j% h' f3 e/ P2 ^5 l4 \; l5 z
- end;( G4 ^ q" y( w( o1 u
/ n1 |, V9 |$ m9 c- procedure TForm1.Button1Click(Sender: TObject);
" z( ]( d" M6 N' S* k - var
# c% b" W; w# x9 P7 |9 r& E# m - VolumeLevel: Single;
% E% |+ m, M* n; j- i1 x+ B - begin
( y( a. M, F; F; a; {' M4 P( F - if endpointVolume = nil then Exit;
% c) y# z# O n' N- |6 ^ - VolumeLevel := 0.50;
3 d, O' n+ |1 s" N - endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);" `6 \. e$ N, m
- Caption := Format('%1.8f', [VolumeLevel])9 y; \: B. V! M K, T. ?% D
- end;
% U$ a0 x. S" A( I( O) {. I
5 X7 X' Y, l1 Z# m: J/ Q4 w8 q- ////////////////////////////////////// U* d# B- W2 g0 F
- 0 b$ C0 S! s8 S5 t, W5 ^
- // with best regards ToxicDream t! i- q- b8 ?; B$ M4 S; w3 |1 n
复制代码 |
|