|
|
来自: http://social.msdn.microsoft.com ... 9-a8c9-2e27eb9ec058
M$ V% P: T, ]: M5 L4 n/ W$ DBy Mukta & ToxicDream
, v: c+ o* O* V/ k4 n4 Y9 x: q+ C- //for delphi 5, \/ g* D% P$ E. _8 O7 p6 f
- unit MMDevApi_tlb;
3 m# r/ X7 f$ c! s
* ?8 `% H1 ~, v# Y- interface) K2 e' x7 a Q$ R, q& Z
- uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj;
' l7 a( q8 n3 E2 _ - const
4 E k4 ^$ _. J! I: C4 b' `9 c. ` - // TypeLibrary Major and minor versions) x& E d" ~* y7 p' S" s5 `
- 8 x* X8 q( v$ W
- CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';1 Q/ j7 ?. |+ e7 p+ ^: Y
- IID_IMMDeviceEnumerator: TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';/ F' U4 P# P9 r+ t* V& F
- IID_IMMDevice: TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';) Z6 i. s: H" s
- IID_IMMDeviceCollection: TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
. x# b/ @* r, k - IID_IAudioEndpointVolume: TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
1 a: i" W0 Q) C0 X7 W& i4 \ - IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';: h G0 e3 g0 A5 _% m5 m! ~" u
- IID_IAudioEndpointVolumeCallback: TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
4 ~4 j$ k& i. _! d8 X - 1 H5 n2 Q: N: O
- DEVICE_STATE_ACTIVE = $00000001;
) [3 s7 b7 x) W$ `! V: t8 x - DEVICE_STATE_UNPLUGGED = $00000002;
. o7 W# G9 Q$ x3 O0 ~ - DEVICE_STATE_NOTPRESENT = $00000004;8 _" w; ^6 E8 |* R! ~
- DEVICE_STATEMASK_ALL = $00000007;7 k* h: U6 [: v5 U8 v8 y
. o3 x% V3 ]) X7 w2 @9 C Z- type
1 z7 D' @( N* I5 g - EDataFlow = TOleEnum;6 I. U- O( C$ @4 X- {" S; ?
- const
8 m) Z/ M# U! i/ y; E - eRender = $00000000;
5 t) c& V) Q1 P' p# o - eCapture = $00000001; i, Z2 _ F$ `" x- @2 ]3 d
- eAll = $00000002;4 y0 V+ N* { ~2 z+ l) A
- EDataFlow_enum_count = $00000003;
7 I+ k- U7 H6 ]8 @$ B
% B( ?& r% v2 B: f; J8 X" C- type7 p+ R1 J# C5 j3 w& E
- ERole = TOleEnum;! j9 _- w4 \' a$ a' L& j
- const2 O' @( \5 F- L- ?- U& Z% w
- eConsole = $00000000;
1 K! q3 S: a- o) b. q( O# C0 }3 j - eMultimedia = $00000001;
/ ?. C; _6 j- r% y# _; W - eCommunications = $00000002;
: k/ K( \! g6 T3 n! K2 { [" _ - ERole_enum_count = $00000003;& }. e# h- L& v+ b) G
- . ~# |* D5 R7 d g
- type
[1 M1 D4 }8 u; J4 z# c - IAudioEndpointVolumeCallback = interface(IUnknown)
7 M: Y/ { I# S( N; [" B - ['{657804FA-D6AD-4496-8A60-352752AF4F89}']2 R3 G( V2 O' _/ v
- end;1 u. q4 S6 G0 t# t6 ?
- # O, k$ O" d2 s
- IMMAudioEndpointVolume = interface(IUnknown)
: E6 {- b$ m) L5 t - ['{5CDF2C82-841E-4546-9722-0CF74078229A}']' P: c; X/ q! m# K6 z
- Function RegisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
! Y H; w3 ?# q. v - Function UnregisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;+ \# ^( Q' \- s6 ]% U
- Function GetChannelCount(out PInteger): Integer; stdcall;+ O2 f: u* S$ ~! E. Z9 |
- Function SetMasterVolumeLevel(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;8 F( v, l8 ~8 l& V
- Function SetMasterVolumeLevelScalar(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;0 C. f5 X* ^& `# `- h0 q
- Function GetMasterVolumeLevel(out fLevelDB: double):Integer; stdcall;
3 B2 j6 p2 k( A% Y - Function GetMasterVolumeLevelScaler(out fLevel: double):Integer; stdcall;3 e7 M, G+ n. z3 g$ F! r3 s
- Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
8 n V, s/ [7 S2 z+ U, d - Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;) T4 O) S5 l3 ]( N
- Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double) : Integer; stdcall;
" z4 k( R& V# S" Q8 d - Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double) : Integer; stdcall;. R& e; Y @: b0 M. m+ g) o4 `
- Function SetMute(bMute: Boolean ; pguidEventContext: TGUID) :Integer; stdcall;7 Z! x. d2 ~4 I+ E4 a, o& Y/ N
- Function GetMute(out bMute: Boolean ) :Integer; stdcall;
% Z) V w7 E6 L$ D - Function GetVolumeStepInfo( pnStep: Integer; out pnStepCount: Integer):Integer; stdcall;
6 @, T1 x8 k* ?5 J5 w1 a7 ?+ F - Function VolumeStepUp(pguidEventContext: TGUID) :Integer; stdcall;6 z3 X* M! J. W) }$ s) `( y
- Function VolumeStepDown(pguidEventContext: TGUID) :Integer; stdcall;: k1 M4 T+ r: {' _/ g
- Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;! o8 _) U) o: [6 J1 e
- Function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;; l' [% ]- |5 t+ R# L
- end;' H! s2 }+ k. C
- - G. N* o% l9 u4 T1 N$ l
- { IAudioMeterInformation = interface(IUnknown)
1 l6 [1 O: p7 I. u& G G - ['{C02216F6-8C67-4B5B-9D00-D008E73E0064']
# P( N% Q2 }1 B - end;}
1 l& L4 y. g8 |# Z
( ~% U# L Q" ]$ ]- IPropertyStore = interface(IUnknown)) \; U5 r. d/ D0 a9 m# M) T+ b
- end;2 A D2 {5 t, x& A8 ]; j
- ) l. \9 X: v5 {2 O' J
- type
J# s0 ~8 ]2 C7 a; F - IMMDevice = interface(IUnknown)3 K; ^% z9 q) V
- ['{D666063F-1587-4E43-81F1-B948E807363F}']- D' t8 }/ h6 m z l2 Y. S
- Function Activate( refId :TGUID;
1 H. x# Q5 d9 L5 O& J1 v7 ] - dwClsCtx: DWORD;: u8 H5 ~/ |4 K- \ a0 X. \5 t
- pActivationParams: PInteger ;
% ^# @" y+ |, v F7 n( E! m0 w - out pEndpointVolume: IMMAudioEndpointVolume): Hresult; stdCall;( w1 }% T/ q' o% M
- Function OpenPropertyStore(stgmAccess: DWORD; out ppProperties :IPropertyStore): Hresult; stdcall;
A2 c- \$ @/ P9 U/ T - Function GetId(out ppstrId: PLPWSTR ): Hresult; stdcall;3 `0 C& F0 \! H% q4 W9 ? ?
- Function GetState(out State :Integer): Hresult; stdcall;
: m* O( W" M8 | - 0 L8 h- Y& {; q. a" k! m
- end;! D! M/ J6 v4 q* w+ t3 ?1 d" Q# i7 W
/ E, R" ^ b a1 b- [2 |- - K6 @7 v b5 x& I9 G; V/ g
- IMMDeviceCollection = interface(IUnknown)
* f, \% N# a* N4 ^3 j. p( w) P - ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']2 W0 w% k9 z/ I% h$ y
- end;# a; u( w3 s/ m
- . \: y3 |! v) b! w- g
- IMMNotificationClient = interface (IUnknown)6 H" t) T% `. f1 X. h/ \
- ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']( k# J4 p6 ]+ D; G- v- @, {3 h
- end;1 _/ Y- J1 M6 ^8 J, k b; G
$ a2 e" ~, @( Y4 @8 S1 M- IMMDeviceEnumerator = interface(IUnknown)3 c7 V! t0 I6 M* q) f( b
- ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
5 ?0 }" C/ w5 ~! D" L. K5 _8 h. m - Function EnumAudioEndpoints( dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection:IMMDeviceCollection ): Hresult ; stdcall;' r- n9 I7 [( G) u: S
- Function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult ; stdcall;
U8 U2 L- W" A: l7 d - Function GetDevice( pwstrId: pointer ; out Dev :IMMDevice) : HResult; stdcall;2 I$ L( H' z l: D; k# X! k
- Function RegisterEndpointNotificationCallback(pClient :IMMNotificationClient) :Hresult; stdcall;, J( O$ F) w- n& [; ^
- end;
5 x# M. b& u3 G+ O3 I
) s# E, B7 s; x+ l/ M% O, a- implementation0 R0 o# P; t7 l* ]% C9 b
- end.5 B7 j; O" I4 n3 ^# k8 I! s
- & }. L0 p. J) O: h
- Thanks & Reagrds,
# B. f) H0 l( I, |. _/ O - Mukta ...! R+ ]" ]2 O3 i: _
复制代码
1 D7 Q2 ^8 ?" ?' a- it's work in Delphi 7; ~' W/ q d% o. O
- //////////////////////////0 X' R& f2 |0 L: T. O6 O* T9 D8 z
# Q5 ^% u0 |5 V- unit MMDevApi;: t h0 I9 @4 s0 [$ m
- * n6 o3 R0 s3 X- ]( K) h7 X
- interface
0 }/ t( x7 y( f6 y6 J' b" U. Z
8 R0 V$ W5 m8 A- uses1 n- o+ t( V: z1 J
- Windows, ActiveX, ComObj;" W# G$ Y! {6 @' i9 }- m" v
! z9 g# ]8 `0 t- const8 Z5 J" w- {* N6 i# H; o
- CLASS_IMMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
7 d5 t3 v4 `1 c; f1 r& W# w. t; U- C - IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
" T \. U. y2 m: K- M1 w - IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';8 {8 k/ |" N7 V' _+ \' _
- IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
\2 M" V4 }1 O, n - IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';) K+ p# o$ Y1 u [# c8 t8 J
- IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
. P% f9 O3 A, J9 Y4 w - IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
, \7 y* B- J$ ]% h - + e" s2 ]8 ?( e2 o4 s
- DEVICE_STATE_ACTIVE = $00000001;# G; c+ L1 y8 ?4 I# ]4 @8 V
- DEVICE_STATE_UNPLUGGED = $00000002;+ w+ O( u/ H( C/ P! j) s) w8 Y8 }
- DEVICE_STATE_NOTPRESENT = $00000004;
" b3 E {/ ?0 `# I# S( S1 H2 R - DEVICE_STATEMASK_ALL = $00000007;
. @+ ?* H3 g q( | F
& {( u! {0 O* t0 \- type
t# z& {+ y9 \ - EDataFlow = TOleEnum;& X9 z }9 Q- R9 | \" E9 ~; h- x
4 b3 y% g9 p- }' z# |- const
+ S% T9 d; E- Q* l* g) @5 Y - eRender = $00000000;
5 l5 k9 I' D" O+ q/ c* @0 T! r - eCapture = $00000001;% G0 V) Q0 F# K
- eAll = $00000002;2 a3 m: Q/ ~$ A' F: K) G
- EDataFlow_enum_count = $00000003;! r7 U$ \3 h( i5 m9 ~. Z0 ~# H. l- A$ c
- , c4 |* Z5 {5 W" Q* \. N8 ~
- type
5 j4 u6 b" D0 I9 E - ERole = TOleEnum;
* D6 W3 d: v/ Z: l2 N, K5 ~
w6 F9 e) [! z$ p! r. N- const4 o, a$ ?$ s, n0 M9 }/ J5 M. H0 R7 K% O
- eConsole = $00000000; T+ p2 E7 a9 [$ N
- eMultimedia = $00000001;
3 u; [( ] E& x+ o - eCommunications = $00000002;
5 r3 Z0 p) l) b; a - ERole_enum_count = $00000003;
" _( c( o% _ P4 R9 d# L - , n9 P" ` X) Z. G( V
- type0 K: b+ M& N6 Y# |7 F+ u9 K+ A9 }
- IAudioEndpointVolumeCallback = interface(IUnknown)% `& ^8 E: O \% [
- ['{657804FA-D6AD-4496-8A60-352752AF4F89}']! x$ E4 a8 T' I, Q
- end;
, a: C9 s4 J f- r - % S1 O, W4 U- t0 C4 p8 K
- IAudioEndpointVolume = interface(IUnknown)' U/ M6 [4 D" E- T
- ['{5CDF2C82-841E-4546-9722-0CF74078229A}']7 _' J6 I& V: c9 F7 j
- function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
3 `: P# g' w5 l- n6 } | - function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;3 C1 O. C# ]! |7 c! Z6 Q& n
- function GetChannelCount(out PInteger): Integer; stdcall;& L. L$ v6 M0 e/ i
- function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;- R) G/ s4 o, A# u) C4 X
- function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
- ~: q1 f/ J0 Z6 f$ q - function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;
. i/ M4 t$ V. g! Q9 i9 B - function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;
- h: g9 e& G$ |. r4 V - function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;- z; X& ?$ d- P
- function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;6 g" A4 h M& d! ?8 x5 h, O3 l
- function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;
* h! u/ V4 }; B - function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall; o& j$ J& H; V' ^
- function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;( ]; G2 c. ~6 u+ U1 r7 q7 ]
- function GetMute(out bMute: Boolean): Integer; stdcall;& L8 X3 A% m, \5 @3 i& \) s
- function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;
, h4 H! B% y4 L - function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;
7 X3 [1 n+ x: j( `, U- y - function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;
8 c8 m: w; ^5 ?" C - function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
, d9 {8 H6 m7 ~ - function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;
0 R7 B) r- I$ a' @, \* d - end;# N7 M: |, M9 V( @; W
- ! M/ M! ?* r5 A% `9 o% a+ p
- IAudioMeterInformation = interface(IUnknown)9 h! z* A$ ~1 j# c/ e0 o2 x
- ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']4 q9 C/ ?. X! _) T+ F+ l4 J
- end;) @0 B# c4 @ ^+ O' R$ ^+ L% G
& H5 ~; M7 r$ R) [4 a/ p- IPropertyStore = interface(IUnknown)5 s, m; _' T: K; o! y4 m4 B& h
- end;2 {- s2 ]' T, M6 p
: S$ w1 H. X1 ?( L. Z, u% D- IMMDevice = interface(IUnknown)
' w# |* m" p; F; Q& E* h0 W - ['{D666063F-1587-4E43-81F1-B948E807363F}']
: \! p5 V1 U) ~9 ` - function Activate(const refId: TGUID;
2 R4 V: I k+ ^ - dwClsCtx: DWORD;
5 {* Y1 G6 E5 b1 w, p2 {2 ] - pActivationParams: PInteger;
3 a( P# j/ h, j2 z3 ]8 ]( y - out pEndpointVolume: IAudioEndpointVolume): Hresult; stdCall;
4 t Z( _7 e+ g& R% s - function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): Hresult; stdcall;3 z- E4 d" B. q& @' E1 q2 R
- function GetId(out ppstrId: PLPWSTR): Hresult; stdcall;, B, I3 J1 F, ~" z* d
- function GetState(out State: Integer): Hresult; stdcall;* ~& g0 P3 F6 R& J- o& u& m
- end;: E$ g: l2 A9 b; R
- / ~3 V6 G' E% X3 D8 w8 }' c4 _4 V5 A3 B
7 F8 p# b7 k7 `$ a' S3 O( {/ ~- IMMDeviceCollection = interface(IUnknown)0 M2 _3 i" }/ i3 e
- ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
" \8 p9 _ ]1 d2 l - end;
8 A& R' f4 J5 H* M" x - 9 S5 s9 T: G% G4 ]1 S
- IMMNotificationClient = interface(IUnknown)
2 ]4 u1 S9 B* @0 W" H - ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']8 Y1 s1 a- q6 F
- end;9 k2 ^- e8 ]* B+ J' z' k
- , T h4 C0 y: ^5 u7 c
- IMMDeviceEnumerator = interface(IUnknown)/ }5 p1 ~: ~! @- _7 @
- ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
2 q5 G; `, O* n( {7 e - function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): Hresult; stdcall;
" I" f1 o, R$ }8 _ - function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult; stdcall;* A, ^, I7 j5 ~! G/ w1 T% X# m
- function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HResult; stdcall;$ S- @4 f4 o7 o; r
- function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): Hresult; stdcall;
3 n0 J! d% e, N/ t - end;3 w# X U4 C4 x) w
- , V" R3 Q3 q k$ q# G# o
- implementation9 {% V3 O+ ]% l* ~# t
, M! G( O4 o' q; F9 K- end.& c8 ^0 G/ b' N( Z* V+ k0 j. D
9 y" {% P6 l3 F7 K- ///////////////////////) }/ l( u! B) Y
- simple sample :)
( O- [ H9 l' J9 _3 k& O - ///////////////////////3 r3 ^ y5 ~0 r$ h i# E5 }
& |9 [8 ^. ~: ~* C$ K; O# {- //...... other code* T( R% ]7 G2 A5 r
! L9 V, f1 y y- uses ... ActiveX, MMDevApi, ...;
N% t$ a, A8 K3 H4 Z4 F+ O# v - . H2 u' L8 ~/ e4 Y
- //...... other code* J2 b. C8 N+ c/ Q
* |' J0 C2 o+ w( c. `; J R- var
: r5 Z. o2 B1 M, V - endpointVolume: IAudioEndpointVolume = nil;$ e8 k" }/ R3 c# ]6 G
' p5 J' E! _, b$ ^- p- procedure TForm1.FormCreate(Sender: TObject);
5 f9 @# p" N. `% j% a - var
' m$ n) A5 _' q - deviceEnumerator: IMMDeviceEnumerator;
# d- V. a& ]' U# y0 F* J - defaultDevice: IMMDevice;( F; U3 }5 U; d2 I
- begin
7 X/ x0 l8 B" s$ q# D' @ - CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
* O! u2 [1 M7 g/ K' { - deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);( ?, f. f; d# X" J5 e/ Z3 {; }
- defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);/ Q3 U9 C& ~& S2 L7 Q$ t
- end;
7 }) X1 P/ ]- o6 {* Y: Y2 C - & J9 |6 y- Z8 I4 E- V% [: ^3 E3 z
- procedure TForm1.Button1Click(Sender: TObject);
* t1 |! j! ]& C: f$ W8 ?/ E - var. {$ x1 o: n1 g( X( Z8 P
- VolumeLevel: Single;$ i+ P0 ?$ w# Z" g
- begin
" z& w. K2 D( u1 `0 ? - if endpointVolume = nil then Exit;% \; f8 g9 W* Q% S, x W
- VolumeLevel := 0.50;/ r' o3 a' ^& h. ~6 t# i% ~
- endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
& B9 }+ J# ^$ \# j0 M" b: [2 Y - Caption := Format('%1.8f', [VolumeLevel]); R& v3 o6 g6 M! q' r
- end;
5 ]! T5 {; j+ d9 d Y; q0 b - 4 J6 c5 a1 D0 M# \9 e
- /////////////////////////////////////: G" c: ~+ b0 f
q: H; B, n0 A- // with best regards ToxicDream
# E+ Y z; y- g; j6 u% {7 e* m
复制代码 |
|