|
|
来自: http://social.msdn.microsoft.com ... 9-a8c9-2e27eb9ec058
- s% n+ X: \ S9 `8 U; p1 I' HBy Mukta & ToxicDream- 4 ?& G8 L% M- z- q3 L* V/ `
- //for delphi 5
% j7 k* R0 }' W4 r, S5 G2 H" M: r - unit MMDevApi_tlb;
: j7 x3 T2 C1 V5 t0 l+ u - 4 d/ o& S) Z- a9 E
- interface
8 g( P- C, \& j4 m4 g+ [ - uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj;
( l0 f+ f& ^" J+ H$ G - const
7 e* k( m; A, m' ^1 M1 ?& _ - // TypeLibrary Major and minor versions9 v0 u0 W: {: j
" X0 Z8 h4 c8 }7 W; o j7 h- CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';" O2 o, F) H' h. ?, y
- IID_IMMDeviceEnumerator: TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
n& K) N5 R+ d% ~( P; A' V, Z - IID_IMMDevice: TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
; q& U: v1 A3 `, R: t8 C7 | - IID_IMMDeviceCollection: TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
' b1 I% N) n# A- m' H( [/ v* M - IID_IAudioEndpointVolume: TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
9 T3 M" |1 _( i& | - IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
2 J" r/ ?: e' r" H! N( T. Q! f - IID_IAudioEndpointVolumeCallback: TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
! f9 s; j. o0 w# S+ m6 \- q$ t
V- C U4 [( w- DEVICE_STATE_ACTIVE = $00000001;
0 l4 F) u) c. b/ Z - DEVICE_STATE_UNPLUGGED = $00000002;
+ f* k6 O6 ^9 \ - DEVICE_STATE_NOTPRESENT = $00000004;% p% [$ \: j7 X0 [; E
- DEVICE_STATEMASK_ALL = $00000007;! L4 b4 S" X! v" Q% x# g
. M* x$ b6 _' g# E- type) q$ T+ ~7 j+ f4 D3 K% p
- EDataFlow = TOleEnum;
. _6 c( i4 G1 |3 m1 k9 h* f( ?: f4 U - const
0 K! k) ~6 b* o7 q* t8 G' `7 u - eRender = $00000000;4 G" \$ ]) {5 `
- eCapture = $00000001;6 g! c+ q% }9 H" C: `
- eAll = $00000002;
4 q! x: ]- `0 X' ]+ u - EDataFlow_enum_count = $00000003; q+ e0 v" d: S9 C. I' X: Z
' c7 z' G. M1 _+ q) g5 ?/ c; M9 U- type
' |5 ]5 \% Q, N - ERole = TOleEnum;
$ R0 [! E6 w; b' J! J' X- M6 O - const
* l A$ ?+ V, N0 K6 P# g' H - eConsole = $00000000;! H9 K& X; j" d# V7 t" W
- eMultimedia = $00000001;* ]+ _# D5 J- e# j
- eCommunications = $00000002;6 F, U' y2 B9 o+ c! j/ c# N
- ERole_enum_count = $00000003;; ^3 f1 g8 p$ g! L
7 m! @7 z) s1 p9 T3 z* N, A5 ]- type6 S; F0 q4 v9 i U" U, T
- IAudioEndpointVolumeCallback = interface(IUnknown)
( F% q6 L4 C- y( a4 B+ f - ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
: \ Y6 M. ^3 \6 O( A" ? X - end;0 a" r0 x* E" e+ ?5 L! K( I
4 L- K9 W5 O' ]( J3 H* a6 {- IMMAudioEndpointVolume = interface(IUnknown)! w4 a1 J: \# J3 Z. `! d. M
- ['{5CDF2C82-841E-4546-9722-0CF74078229A}']5 S1 T# {: N/ ^% n2 H" o2 e
- Function RegisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
/ C/ P5 J2 {3 O1 {4 G5 H: Z3 P! K+ o - Function UnregisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;7 H2 z3 I, b8 \' _! F
- Function GetChannelCount(out PInteger): Integer; stdcall;, y! A: L/ w) J( W
- Function SetMasterVolumeLevel(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
5 u8 w4 v- ^% j3 e - Function SetMasterVolumeLevelScalar(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;3 h0 R/ T* u% y9 }# W3 B
- Function GetMasterVolumeLevel(out fLevelDB: double):Integer; stdcall;* R/ {4 A: c# }% d9 R
- Function GetMasterVolumeLevelScaler(out fLevel: double):Integer; stdcall;
, |( s: J e& ^1 l1 J+ y - Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;0 ]* Y% {/ `% m' q$ I6 d
- Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;% d3 _# M( q: u0 t2 r
- Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double) : Integer; stdcall;
9 V$ w& R( D$ S+ a2 R# `, E - Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double) : Integer; stdcall;7 n0 N+ ^* ?7 I1 I6 v6 _2 r; E
- Function SetMute(bMute: Boolean ; pguidEventContext: TGUID) :Integer; stdcall;8 j8 Z- I, J. f% x* s- N4 r
- Function GetMute(out bMute: Boolean ) :Integer; stdcall;
# X% ?7 P& @0 W - Function GetVolumeStepInfo( pnStep: Integer; out pnStepCount: Integer):Integer; stdcall;6 P2 B& R" h- h% L% h6 b
- Function VolumeStepUp(pguidEventContext: TGUID) :Integer; stdcall;
, o, F& W+ T6 q5 i1 ^ - Function VolumeStepDown(pguidEventContext: TGUID) :Integer; stdcall;' m7 ^; s# n5 \- \2 K, E
- Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
' ]4 ~* @; z3 K7 e& V - Function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;- D/ |- Q/ D% Y$ e
- end;, y/ n. Y! t1 z+ X; @% _$ G
- ; i% g. C/ |# Z; f: x+ `/ _
- { IAudioMeterInformation = interface(IUnknown)
7 m4 h: E/ O5 d3 n. h - ['{C02216F6-8C67-4B5B-9D00-D008E73E0064']
+ B2 z# u; z, v# H/ { - end;}$ X" v& _3 z; b
- ! l2 r+ Y ^" f. n6 C
- IPropertyStore = interface(IUnknown) w3 T! S# C6 X6 r* h
- end;! t0 H. S7 n; ~5 U
- , N2 z+ n: f" d6 m3 c. E
- type! s7 y: u g7 d7 X
- IMMDevice = interface(IUnknown)% u5 i/ r3 U/ i
- ['{D666063F-1587-4E43-81F1-B948E807363F}']
$ V* \+ s9 G# Z6 w% I - Function Activate( refId :TGUID;
% J+ |3 r7 T7 h" D; _$ ^ - dwClsCtx: DWORD;
) x, `7 D8 d! w' C3 G- }$ l - pActivationParams: PInteger ;
5 V8 t t# W( y4 f - out pEndpointVolume: IMMAudioEndpointVolume): Hresult; stdCall;* v2 d; h4 m& g+ V1 t5 F
- Function OpenPropertyStore(stgmAccess: DWORD; out ppProperties :IPropertyStore): Hresult; stdcall;
# R6 b2 I! p+ _# x1 s - Function GetId(out ppstrId: PLPWSTR ): Hresult; stdcall;
$ Y0 c4 p% j5 K: R - Function GetState(out State :Integer): Hresult; stdcall;
/ W2 Y2 V, L/ ^. d) Z) v
5 z7 { Z6 M* I. k3 R6 H) m- end;6 F% W( p4 z. h) [/ m
6 ~2 t4 \4 G* U% ^- 5 s& A$ d9 a. ?
- IMMDeviceCollection = interface(IUnknown)/ k9 K( @, \2 q) {2 T( O! F5 o
- ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']' ]. A* p V/ F
- end;& ?- L; g) O1 _7 g/ o) k, N$ G
- M7 j N+ M! j) K# p0 w- IMMNotificationClient = interface (IUnknown)
, F* Q! r# Y7 s) i - ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']* E6 S* q# N2 D" ~! a
- end;; J: Y; m( R" f' M
2 x' I9 j2 Y& {0 D: t7 K u- IMMDeviceEnumerator = interface(IUnknown)+ O" @$ C. r/ y5 D0 L
- ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
5 c/ C* S- K$ k6 w" z9 {6 z - Function EnumAudioEndpoints( dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection:IMMDeviceCollection ): Hresult ; stdcall;
. a5 B4 r) W& S8 h- j. v' l; h( Z8 a - Function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult ; stdcall;5 A0 Q6 Z) |; t8 b7 e
- Function GetDevice( pwstrId: pointer ; out Dev :IMMDevice) : HResult; stdcall;
" U; n+ A" a* n) B' f - Function RegisterEndpointNotificationCallback(pClient :IMMNotificationClient) :Hresult; stdcall;
' M" j2 k2 f+ B! [ - end;
2 Q; B( ~9 I) B: ?( a7 O1 w - 3 w1 \" v. b3 p( H) o3 j( j
- implementation7 E1 \* n7 }% D5 h ~" E+ j: p
- end.
+ B" j* d) Z- Z) o" Y - % A! N; L# g5 L; u/ B- A
- Thanks & Reagrds,
9 X: M* D: K- f. f: Y - Mukta ...
9 N7 a. s# [! ?0 E( r/ s3 q
复制代码- - L" b" O0 F- Z! a% I/ p
- it's work in Delphi 7! `$ i6 c/ D: D7 g' O7 J
- //////////////////////////
& W7 D X7 m3 o% z6 R8 p9 @4 Q
3 B+ ]: u+ _( m4 V$ Y- unit MMDevApi;% F. E# X7 N; \2 U, X
5 u6 g0 Q: N" O% x3 a- interface9 E! c- v' d! F9 ?0 F5 X: `' f! P
$ ~3 k0 Q. @, E( U( I- uses" z9 t$ a6 i" o' w
- Windows, ActiveX, ComObj; T( X8 v" E& |# B( f
- 6 j& k9 Y* q4 ~# @1 \0 E5 R
- const
9 S0 n8 w+ e# _% \6 Q - CLASS_IMMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';1 ]; M# }& d3 a( H
- IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
% u/ o' `' h) Z& q& a# f - IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
6 T# a1 X( Z$ C q1 S - IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
" J, T3 W# z6 } - IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';, Q% X3 l5 ]' B9 r( I
- IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
* C) m0 ^5 o$ m; l- C" K - IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';+ H/ ?; Z: c$ R
3 h" Z0 K) _3 C8 U- DEVICE_STATE_ACTIVE = $00000001;7 t) \( S# N) I+ Y
- DEVICE_STATE_UNPLUGGED = $00000002;
0 D: V% {2 o% ]) s4 R - DEVICE_STATE_NOTPRESENT = $00000004;* m; O! O4 q! _) ]2 f- x
- DEVICE_STATEMASK_ALL = $00000007;4 A+ y& I; J8 L, v; _/ P; Z
k: z k, z, B5 m4 X% ^7 ]- type
& R* ]5 P( L: k- L) n4 d - EDataFlow = TOleEnum;$ Z% E0 j$ J! W+ `7 R
+ E: o1 j$ N$ I4 Q+ d8 o- const! w/ ?9 p$ X" W v4 E. [
- eRender = $00000000;# }( @3 o" V- Y- J, {3 o
- eCapture = $00000001;
9 E& m& T/ G' A5 ~ - eAll = $00000002;6 {' X; Y+ q- a$ H4 z8 L
- EDataFlow_enum_count = $00000003;" R4 |# g; N( A! L0 P( q; {) P
- & O, F, V$ [) W, X# |. C( E
- type [$ N3 p! q' A- b
- ERole = TOleEnum;+ I6 b9 u/ |+ d& r6 N9 @; i
- , S0 I& \' E3 _. q
- const8 |3 k& I, B1 N# Z; X8 z4 g
- eConsole = $00000000;
1 ?4 ~# q+ [& O6 | - eMultimedia = $00000001;8 D9 _6 i' `% w4 s: J
- eCommunications = $00000002;
/ {' k' O0 n7 u2 \9 {1 @ - ERole_enum_count = $00000003;
; j$ e! Q+ P8 k9 ~4 u+ p5 W7 b7 U
# A$ D/ e1 }! Z$ W- type
" W9 l2 l0 ^. R- M: Y: | - IAudioEndpointVolumeCallback = interface(IUnknown)! Z: }6 X& \7 @* W1 H
- ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
& ?# \+ p1 S- E - end;
3 I, g3 P7 n$ Y" S5 d - ) w9 F5 P" T; ?3 v- a* O4 U. f$ O" ?
- IAudioEndpointVolume = interface(IUnknown)
0 q( x# N3 |% Q9 Y& d! w6 m/ I - ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
: {1 m! o# ]* P- _2 X5 ~: i - function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
% g$ @1 N) k) X, H( F - function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
! e4 P2 m* L6 C. j - function GetChannelCount(out PInteger): Integer; stdcall;; }: W* e: {$ Y% j! ^0 H
- function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
8 S r1 P7 x( D - function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall; H6 o, u5 f. h+ [- u
- function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;
1 ?$ s1 j, L# H - function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;# Y) x* q9 O9 B Q1 Y
- function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;7 v' y# d6 M* B8 U) Y
- function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
$ `/ s" z5 H' p* P$ K6 Y - function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;
; s' J% v) A& W% x+ r ~& Z/ [# F - function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall;
% {+ p. ^2 T" i2 H. z+ q4 Z - function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;
0 L' _" M. A. D+ w - function GetMute(out bMute: Boolean): Integer; stdcall;
; M/ ]8 {0 R" G( q7 j. h8 T - function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;0 Z/ N0 `: J3 G/ m
- function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;
$ d; u; w) p8 r& A7 v# W) [ - function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;
8 M) x j3 b+ `8 w B - function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;* V. X( ? F5 F) r, _" M
- function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;- U+ l# ?* X; Y4 o' T% `
- end;1 b7 `. a, S- b" h$ g$ K
4 R8 O- @4 o. Y- IAudioMeterInformation = interface(IUnknown). ?1 B- b# _% b9 k: ~# @
- ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']: p: v, @/ [* d7 ^4 @
- end;
& q& \& j3 U+ V1 e7 h - 7 c h9 y. G7 ]
- IPropertyStore = interface(IUnknown)
& f6 ~3 Q* n4 Z8 U9 n3 ] - end;& O* ?+ r7 V( R# x
- + f. E3 m2 \; z# j5 w* { g
- IMMDevice = interface(IUnknown)
5 K+ ]+ [. m2 g - ['{D666063F-1587-4E43-81F1-B948E807363F}']; J, u2 [5 C' q; T; h* r
- function Activate(const refId: TGUID;
0 P; z9 t% i( |4 f* | - dwClsCtx: DWORD;
% C ]4 @2 }% `6 j! l) l8 Y4 E - pActivationParams: PInteger;
7 h' M6 q; [( }! F) l - out pEndpointVolume: IAudioEndpointVolume): Hresult; stdCall;" r1 t+ E, k) E+ }% I$ k
- function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): Hresult; stdcall;2 s7 X( ~: v# S- d9 \+ m3 b& z! Q
- function GetId(out ppstrId: PLPWSTR): Hresult; stdcall;
C4 j4 Q8 Z/ w* M4 [ - function GetState(out State: Integer): Hresult; stdcall;+ \5 H% A! D- C
- end;
8 X+ T7 m& T4 f5 A, p4 @' u/ C
$ E `; s8 ~$ k3 B$ z8 N, n( |; j- j
* k# x' H$ p" M8 O- IMMDeviceCollection = interface(IUnknown)6 p# }3 r2 [5 g4 u5 v, j
- ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
/ z& H v& [# ~; C* y0 {; o. q - end;: R, ^ K4 P2 B" u! H9 u5 d
+ r5 J- Z* G- R; Y6 c; X- IMMNotificationClient = interface(IUnknown)
. m# _, G4 W5 [% c8 E$ b - ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
3 G$ F% Y7 z8 @' y1 X, } - end;
& D; V; q8 Q- d3 j4 s2 Z0 ?2 Y, B
1 k% `( t& s- \- IMMDeviceEnumerator = interface(IUnknown). F& G; r4 P" c* h& y9 `
- ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
C5 \$ D' v+ q+ M% T - function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): Hresult; stdcall;
7 _( n0 B! f; O0 s - function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult; stdcall;8 |4 F5 i' c/ W
- function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HResult; stdcall;
! ^* ^" G5 {: i0 S9 p - function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): Hresult; stdcall;
+ W0 R% `9 L. Q! A& Y* E - end;
{& y2 e9 R* b; `- n# Z# C
2 \9 N4 h" n) `3 z" g4 F- implementation0 B) W+ S& I/ E: M7 @: M9 h! t
% \2 R2 m5 R, f7 X- end.: I4 y; G4 d% q
+ F* c$ i! K/ ?3 T i- ///////////////////////
' J; ]5 c* n0 S" M" i- F& X+ H: T - simple sample :)
7 @$ Y! e4 \' U- r# t - ///////////////////////. @4 \3 S' t& B0 g3 j, j8 @' f
! w. l$ X* }! f8 _* x- //...... other code
5 S% _& \) n q! v% K8 ?- v
4 L' w: y" w& \7 v+ @- uses ... ActiveX, MMDevApi, ...;& ^9 o9 G/ Y* L9 |8 U3 y1 {
- 7 c. }" v9 Q2 b; R
- //...... other code
1 V% b+ S) g, U3 `4 }0 z - 8 c- f5 V5 a- G8 G
- var$ t6 v: V* H& g' N
- endpointVolume: IAudioEndpointVolume = nil;
# S, F7 q$ K5 a* ]# _% g4 Q - + A/ m j( \6 {
- procedure TForm1.FormCreate(Sender: TObject);
) k! ?; \& M h9 U2 ] - var( X; O% C# q( Q, g$ d
- deviceEnumerator: IMMDeviceEnumerator;, ]- N) R& B- K$ l% p
- defaultDevice: IMMDevice;
4 k9 ~- L/ W* M2 d - begin
" V& @0 [: m. b* s; G. \/ C - CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
$ Y! L) F) }2 N" ?. E8 V - deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);) H, Z1 L8 n# I; P! j" t
- defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
( J; C5 B! e& p4 N* t% r4 o - end;- ?9 |$ _5 H, l i
2 j7 ?2 \# B- Y0 R8 f& Z1 R- procedure TForm1.Button1Click(Sender: TObject);
1 Q* z$ E) e/ S2 H - var
2 x. }/ S5 T; l8 O% [/ ` B0 p - VolumeLevel: Single;
/ v- I6 ?: r% I& m ]; e7 O' i$ V+ r - begin' I# ^( e9 u7 v' m2 k/ N
- if endpointVolume = nil then Exit;* i% y7 \' s9 E; C9 n
- VolumeLevel := 0.50;3 p( C: a. B8 @) y3 m% g
- endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);7 R+ C& u2 K- ^. H0 z
- Caption := Format('%1.8f', [VolumeLevel])0 ~( y( n. V% c( g, E$ O& L
- end;
5 c2 t7 J- s, c4 i+ Y {" a
& X5 @; ?3 n" C. M7 o+ Q- D- /////////////////////////////////////
* _8 q+ S P2 n# j+ v7 o' |3 j
6 \! }5 K& g! @% G5 |4 q; E6 F* S- // with best regards ToxicDream7 h3 A( g. v3 |
复制代码 |
|