|
|
来自: http://social.msdn.microsoft.com ... 9-a8c9-2e27eb9ec058
4 U+ d' _1 C: x0 Y# S, B$ q+ M7 RBy Mukta & ToxicDream
: _- T' W. p% Z9 C0 o3 i5 E5 a- //for delphi 5& r" s* S% y8 u* C* I
- unit MMDevApi_tlb;
5 |% |7 v6 G L5 U
. }2 e( h( F9 m8 n. b- interface, }9 h) C5 Y- U
- uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj;
9 i/ d& U, r# V% s/ N2 U - const: Q0 {. e9 N3 m1 P% v
- // TypeLibrary Major and minor versions; V$ \: x! d+ y4 R1 v9 A8 ]4 ?
- 5 S* x5 [$ H7 V2 c; g
- CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';3 B7 ]- \- a0 L
- IID_IMMDeviceEnumerator: TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';3 ` m& B, G! S/ @ r. s
- IID_IMMDevice: TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
9 A$ `% O- ~# s- C - IID_IMMDeviceCollection: TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}'; Y7 J# }0 J. E' B1 x1 @4 k7 \
- IID_IAudioEndpointVolume: TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
& c! z& w* T; W% d P% l$ V - IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
0 ^7 T2 F! U% k - IID_IAudioEndpointVolumeCallback: TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';: @ k6 J$ O/ l: U q9 A+ C9 a0 [
- # N" I- Z' P2 x) V$ a9 f
- DEVICE_STATE_ACTIVE = $00000001;
8 \5 c- c$ L2 v9 |% `! \6 O - DEVICE_STATE_UNPLUGGED = $00000002;
A# h! `% U A0 w& T - DEVICE_STATE_NOTPRESENT = $00000004;4 Q' _ c: B# J; R
- DEVICE_STATEMASK_ALL = $00000007;
* N R; e/ l+ X# d
, n& |/ i% K) _ g) d; L- type
0 l: C: `, Z- @) E0 f - EDataFlow = TOleEnum;9 @! b6 V; w! l1 m6 N
- const1 F% I! ]) @- W" d
- eRender = $00000000;
8 K1 k( l8 Q) c' @ O2 w7 b+ s - eCapture = $00000001;
* S6 i, M9 k) e - eAll = $00000002;$ B; ~: n" r( Q! \ N6 _* Y0 \( p3 o
- EDataFlow_enum_count = $00000003;
3 Q) R) M! U' T6 R/ a# b: V | - ; i" R+ ?& U. I3 f5 S
- type
9 @ }8 `! D7 R& }- ?3 D {- K - ERole = TOleEnum;; M4 H8 D" g2 J& m; S( i5 U
- const
4 K9 s$ R' G5 a; ^ - eConsole = $00000000;- J5 Y8 ]8 A$ l$ |2 ^
- eMultimedia = $00000001;( u% N5 |' R2 y9 n) J
- eCommunications = $00000002;
, @- [/ A) l' R; \. h! [ - ERole_enum_count = $00000003;
" ~, W. e1 _( B: ]! F4 q& c- a - . w6 U2 Z8 F" T" b
- type
+ x% t' F+ o! m# p - IAudioEndpointVolumeCallback = interface(IUnknown)
7 [0 L3 ?7 X) a3 m; h! ?, J - ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
1 `; D9 a8 q# l- ?3 U - end;" g) ? l b1 n* y) [( H
, E9 I* R, B }- IMMAudioEndpointVolume = interface(IUnknown)' \! \- c2 _: i3 W# V! Q, n
- ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
* E5 M2 i Q# k - Function RegisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;4 ?9 u3 h( v# I5 U; Y, V
- Function UnregisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;! D) a" N Q! i" [! i
- Function GetChannelCount(out PInteger): Integer; stdcall;
( J. I2 u3 g$ a! a U! s( b - Function SetMasterVolumeLevel(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;0 E; ?7 `5 ]& C, o+ Y+ t2 L7 H8 T& t
- Function SetMasterVolumeLevelScalar(fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;0 v; P8 Y9 V, y, G: `
- Function GetMasterVolumeLevel(out fLevelDB: double):Integer; stdcall;' ~: B% G2 b, E2 s/ D
- Function GetMasterVolumeLevelScaler(out fLevel: double):Integer; stdcall;
4 x% w7 v3 p4 [3 ~4 w$ n0 g8 r8 H% x* _ - Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;4 J* e- U/ z( L# _1 P' K J
- Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall;
. e# u$ C5 k7 R/ E5 I) a - Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double) : Integer; stdcall;
! B1 f, Y0 R t& \# y& D3 G$ @ _ - Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double) : Integer; stdcall;; ?' B+ v( h4 m: o$ o: b+ C
- Function SetMute(bMute: Boolean ; pguidEventContext: TGUID) :Integer; stdcall;
" J1 J7 `# {/ f4 L4 N - Function GetMute(out bMute: Boolean ) :Integer; stdcall;* D0 q& z7 |- W2 i7 E
- Function GetVolumeStepInfo( pnStep: Integer; out pnStepCount: Integer):Integer; stdcall;
# Y3 x- q: o" X2 d$ [* A! V - Function VolumeStepUp(pguidEventContext: TGUID) :Integer; stdcall;
4 A. ?7 D, \$ y& E' H U - Function VolumeStepDown(pguidEventContext: TGUID) :Integer; stdcall;
6 m! y" L# N& A6 t! R9 B$ e1 S - Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;* k9 {; q+ m: R( i1 s0 N$ U
- Function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;* s; ]' y n: w4 h, G2 g' P7 `
- end;8 S2 i! w. |5 X
- % Y- Z/ h* P2 S
- { IAudioMeterInformation = interface(IUnknown)
: e& P2 ]9 [4 B - ['{C02216F6-8C67-4B5B-9D00-D008E73E0064']
% }) Y0 H; g2 X, |: h2 |/ ~7 V - end;}$ V! H0 h A5 ]5 ^
- + U8 N9 s" U- j( b* i' s7 f
- IPropertyStore = interface(IUnknown); _8 v. U1 v+ L
- end;
" G- Y6 F8 i$ v. P6 a/ N - # v0 X) o2 B( ?' B) ^2 D3 R2 l
- type, L7 O- g3 V4 P
- IMMDevice = interface(IUnknown)
- x. H* }8 F2 H: Q - ['{D666063F-1587-4E43-81F1-B948E807363F}']1 k( p' i3 ?7 | m" P
- Function Activate( refId :TGUID;
; y/ P5 @- P3 g - dwClsCtx: DWORD;
# a6 w# r' p" D+ N# ^' g: U7 D - pActivationParams: PInteger ;
" Y$ r& \, w, T, A+ g& B5 [ - out pEndpointVolume: IMMAudioEndpointVolume): Hresult; stdCall;0 F5 b! x, w: t, ]: b& m8 W
- Function OpenPropertyStore(stgmAccess: DWORD; out ppProperties :IPropertyStore): Hresult; stdcall;. a+ z- }/ y# b7 m3 `" v/ @- W3 T
- Function GetId(out ppstrId: PLPWSTR ): Hresult; stdcall; ]3 l# ?6 I6 B. r
- Function GetState(out State :Integer): Hresult; stdcall; k" l! S2 p8 K' k/ x
- 5 @0 V" X/ `9 X- m8 ~0 J0 d" i
- end;
$ C2 D6 s" y, v8 E5 G7 n8 T! h
5 f6 _. t: f% f+ y- 3 y2 B! _4 I# f+ a
- IMMDeviceCollection = interface(IUnknown); v% o$ Q) Y/ i: t9 n, n5 c0 E
- ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']4 J+ m6 Y9 I0 D' r V2 b( Q
- end;
3 D6 o4 ]. o4 G+ d0 {& h - ( \+ g4 s+ d' l
- IMMNotificationClient = interface (IUnknown)
! Z0 ^8 W) \! L - ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
& ?8 ~) j% N( J, |0 J2 }0 a& R - end;5 l+ r( n0 Q& c5 [2 X; w S5 ~5 D
- ]+ `8 I9 w9 `- a) s) G1 I- IMMDeviceEnumerator = interface(IUnknown)
) q; z3 |- N9 T; L7 @ - ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']# o+ y/ i4 ^5 D' u1 w% {3 x9 g5 ~9 O
- Function EnumAudioEndpoints( dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection:IMMDeviceCollection ): Hresult ; stdcall; Q1 t% S. f. t
- Function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult ; stdcall;
" y4 h% {- y5 D9 O4 C - Function GetDevice( pwstrId: pointer ; out Dev :IMMDevice) : HResult; stdcall;( y Y# e+ n, p% U5 ~7 M+ t
- Function RegisterEndpointNotificationCallback(pClient :IMMNotificationClient) :Hresult; stdcall;
6 J: p2 f( l4 ^( ^% Q# b% }) V8 S( w - end;
( d& e, G$ t, I3 T5 A Q9 n - 8 }5 n1 x4 }# |$ M: T( N7 ?
- implementation/ l2 |/ D5 F# f Z# R( I5 H
- end.- n, B! U% E' G. X0 K; H/ O" y
- # F* S H& e2 A" E: G
- Thanks & Reagrds,6 S* Z$ z, x6 Q# U* V7 b# Z
- Mukta ...
2 ?4 x+ z0 A0 h; S# a1 A
复制代码
3 E8 c2 s7 T5 y- it's work in Delphi 7
; X: k5 G- K* f* Y% U3 t& q( p - //////////////////////////. W- L7 W- q( O1 h+ M+ A; I
- * M, D+ }+ D( `2 F
- unit MMDevApi;* t2 q" k) l; _. e$ B
- - G( d2 r- g/ J1 g* X6 k/ f
- interface7 C0 v8 N. ]) k+ U
- 6 I: Z4 e* U1 X; L
- uses4 G9 p, q6 V9 F" l
- Windows, ActiveX, ComObj;
3 \; x+ G. q" j6 }2 [2 Q' Z
6 \0 w0 S8 d/ g- const
* j- c, }8 @8 c" u J$ g9 h4 [ - CLASS_IMMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';5 n$ k5 B' |' F2 J4 K
- IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
: A8 i7 Y* T3 ` - IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';. x6 \/ e4 [ D; F$ i* J
- IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';# N2 F5 I' |7 ~, B
- IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';) z: s# F0 ^) }6 i a
- IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
' V5 h, w" D5 i# n7 n - IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
, w' F8 t! p. a" Q( Y [ - + m' Y4 M) |0 \
- DEVICE_STATE_ACTIVE = $00000001;# v% c% b2 L$ ^
- DEVICE_STATE_UNPLUGGED = $00000002;# K7 _5 i' }( f/ |
- DEVICE_STATE_NOTPRESENT = $00000004;
1 G) q% z" D8 p% `5 h1 ~ - DEVICE_STATEMASK_ALL = $00000007; N* _/ ^ z/ F, X
- ( _8 ^/ A& [; K0 J# ~% U$ h r
- type
: o2 G9 i2 o* G( j1 E8 n) j1 V - EDataFlow = TOleEnum;
/ P+ J1 `3 t$ n( p" M
" I% _+ m* j& z6 U7 f' m- const: U5 M* r) c9 c" h! y! A
- eRender = $00000000;
3 C' |/ m+ d5 X - eCapture = $00000001;
/ X; I) z4 p& ^* [" q ^ - eAll = $00000002;1 o& F& L) D* M5 i' v, n) o% {
- EDataFlow_enum_count = $00000003;' s7 y2 t$ i2 f6 h' P5 w
- 4 S1 E& V9 g8 Z4 ?, u
- type$ K* L; r2 K6 x2 t: J
- ERole = TOleEnum;$ q7 @3 i: K) q# m7 f8 M- ]+ O" N
- 1 O: n/ i% A0 C A
- const
/ l* H- L e- b# z( X - eConsole = $00000000;
1 ?8 a6 M4 ?- W9 o - eMultimedia = $00000001;* C6 d! z& f$ L5 B% i
- eCommunications = $00000002;
: L, ~7 F2 W2 u1 s! U - ERole_enum_count = $00000003;
: c: ], w( H# E
$ l& w8 `' |. T7 V: V) }- type
2 b! J3 q: q# p) A1 H% |4 Q - IAudioEndpointVolumeCallback = interface(IUnknown)3 q! w: k( D: h
- ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
3 u% o% B7 k+ s - end;
" f4 z/ ~% E1 p. a4 _
$ G6 U' ]" S7 k" e! R3 H- IAudioEndpointVolume = interface(IUnknown)
8 q- F+ J8 i, E# p& W' H# P' E6 F - ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
% H+ t7 @' g2 N+ {3 ` - function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
4 ?5 a/ M( T9 ] - function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;, k4 V8 }/ P) W/ S9 x( M% v
- function GetChannelCount(out PInteger): Integer; stdcall;
, {$ O- f- k1 @, B) g! B6 V - function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
4 S3 n! J: w. f5 {+ o; c0 H - function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
7 B5 {; D; F( Z* ] - function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;
, B( }6 [8 W( @3 X6 n - function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;" D% N$ P* f& y. }% Z- [+ [
- function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
0 q3 `& T7 N2 q) b - function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
$ H" E* O y: i1 n) y8 s - function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;
$ Z% Y. K8 R+ p# V - function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall;3 \& ~7 I/ s- T7 q
- function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;
- ] F2 D: j P9 l) i, u. H5 b& O - function GetMute(out bMute: Boolean): Integer; stdcall;
. O* H3 N! `$ t - function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;1 x8 f4 j" \4 U2 a
- function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;
) B( C6 n' s9 N6 B - function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;
+ H9 \8 Q" }* Y* b! ~ - function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;0 T. E8 Z; `; X# @' G/ w
- function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;& |8 W* G& K5 l# M) d; S% Y
- end;
2 |! e$ x$ |/ f! E* \ - 9 }/ I# b- _/ B/ `4 C
- IAudioMeterInformation = interface(IUnknown)) ?% N, @+ r! v" r$ V
- ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']( B) I3 q a/ T% M8 d
- end;
6 L0 _1 E) [3 B# i9 K: X
. `1 e0 k9 }5 S. E* ~' W6 m- IPropertyStore = interface(IUnknown)
% y5 E0 ~) M: a* k9 G - end;8 }- U- P3 D- L4 I& a7 _
- % X8 s: O4 @) P2 k3 \; q% K3 `
- IMMDevice = interface(IUnknown)
7 w k: E9 |! x8 C5 e - ['{D666063F-1587-4E43-81F1-B948E807363F}']
. {- _# D, G1 x6 o8 f - function Activate(const refId: TGUID;
9 u# q7 r( H) z7 H5 O: `. U6 n - dwClsCtx: DWORD;
/ p$ g' l- U# A8 I+ ^8 j5 q: H% n - pActivationParams: PInteger;
V$ O" D0 L, K8 d: g/ c0 }( N! O - out pEndpointVolume: IAudioEndpointVolume): Hresult; stdCall;
! |% r3 b- [% [% `( `) y - function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): Hresult; stdcall;# K" @3 D' t1 D+ e L- W
- function GetId(out ppstrId: PLPWSTR): Hresult; stdcall;- ]# V8 J! J7 E; ?
- function GetState(out State: Integer): Hresult; stdcall;& S) a5 u) w6 i6 a1 ~- W, S, y% d* p
- end;: t# S, P& P/ C. ^
- . l( g! ^# ]3 G
3 T* }' ~, l8 w, ]3 W: T- IMMDeviceCollection = interface(IUnknown)
& J; i& Q0 o9 [1 {& k. d0 D - ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
- D* [, T# j* M( ` - end;
7 l$ g& C' W1 I
) |, y( I5 \5 D- IMMNotificationClient = interface(IUnknown)
; c/ Q* M5 _( w8 g- @: e - ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']! _& V- m5 b5 ?+ p
- end;5 w7 a. h I4 e$ @7 g+ O' h( d
- % e9 J/ A' `/ f" _4 d+ f! \( I; f5 E
- IMMDeviceEnumerator = interface(IUnknown)
8 h, i; i( N; P0 H" q( `. c; P/ Y - ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']7 K$ k6 S" C+ P* K; d# F( V
- function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): Hresult; stdcall;; ]/ V9 b; V" e; K" K% ~
- function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult; stdcall;
3 u2 a1 }3 N9 X9 @ - function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HResult; stdcall;1 a8 |# f( d) ]
- function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): Hresult; stdcall;
" Y* ?* j h2 U - end;. |. w: }* I5 y& h( |
2 W& l+ v _4 R" V! L+ O- implementation5 Z! D# L3 E6 s I2 H
! y+ ]' F0 [( ?$ `8 {- end.4 t" r- B) V6 ?- R3 }8 h) o
- & @ N h) J+ M' H! k; @; I8 G
- ///////////////////////) a+ t' [1 r* Q
- simple sample :)4 K& `; p) z/ V3 }5 \( W
- ///////////////////////5 N5 H; ?6 e1 P$ E* W2 Z7 R
- V6 A, v8 G4 S- o+ Q
- //...... other code6 E: A# T0 y% o: B
& S5 I T7 y/ W7 ]3 S- uses ... ActiveX, MMDevApi, ...;2 ]6 {7 _& p# i
- 7 m! `, l5 s' Z2 X) a# {: u
- //...... other code. ?- i0 C" e; U( x, w; N/ S; {
; O2 u9 J" z1 h) T- l1 I- var; t! f* c) l ?+ z: Y
- endpointVolume: IAudioEndpointVolume = nil;) A, c) e6 r- _; e
" D: X" n9 M3 N- I' Z+ R- procedure TForm1.FormCreate(Sender: TObject); ? k4 F' [% K% |4 D: R
- var6 g4 p0 l& ~0 \7 l; P
- deviceEnumerator: IMMDeviceEnumerator;. C4 R, {: k- u- d
- defaultDevice: IMMDevice;) X! s5 p4 k2 s+ w( I1 W: u
- begin
8 [4 @4 q# G; K, e& D3 g& f - CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);* [: S) k7 b! |$ O z ^; \8 R
- deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
% I6 Z: @+ l6 o4 F1 z* U' | - defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
1 z" T- W \! K% J; N - end;
# a- ?! _+ S0 y$ g* g - - f; e/ y& I8 U8 c4 i' C; X) u
- procedure TForm1.Button1Click(Sender: TObject);6 J* d, k7 C- P: B3 r5 h* z& U- y/ f
- var( p6 u2 B3 Q7 t8 `$ j( t; q
- VolumeLevel: Single;: E( H6 \3 o9 ^: Z* a% D
- begin6 v) `! b. R$ Z4 y; m
- if endpointVolume = nil then Exit;
0 d# w8 h D# B! F7 j- \ - VolumeLevel := 0.50;, K% \# b' `3 g
- endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
: u& f9 l( c( `8 z9 [/ r - Caption := Format('%1.8f', [VolumeLevel])1 ?* ^1 \! `, y
- end;
4 M: X; |* s& N$ q5 z% r; B4 f
[8 X' Q6 h9 |6 {, q. t' \- /////////////////////////////////////1 f0 e( R4 X* t0 B ~
- 2 f0 U- U) r$ u$ t
- // with best regards ToxicDream
, ~2 I- R; L0 G
复制代码 |
|