找回密码
 注册
查看: 4853|回复: 0

常用数据类型使用转换详解

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君8 m  L7 P7 o) r( `7 J8 Z8 f: |

% f: k6 N7 }! c# y1 o刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。$ n( z, ?  L2 N* q$ {7 T
/ R- A- y% ~  A1 P
我们先定义一些常见类型变量借以说明9 m* N! X, l8 ~' E" k4 t2 @* }8 Q

7 C" j/ {1 d! v+ ?  K. Dint i = 100;" {) i1 s' l0 T; g, @  O2 p
long l = 2001;" }- f; N) Z1 N+ x; R  ^
float f=300.2;
: [5 F6 x/ u! N0 `! {) q) [double d=12345.119;# h5 W3 U: m7 u  g9 L; v
char username[]="程佩君";
4 `2 L2 z9 u3 M! H( c, dchar temp[200];, t4 t5 x( S+ Z
char *buf;
. k4 C9 f4 [& |" ?# aCString str;
& B8 V7 X% C$ @  x, d% B_variant_t v1;
, |9 K7 ]/ I3 x/ B3 H& s* S_bstr_t v2;  `5 k; e8 M5 j+ B3 [
$ u- C- Y8 t1 ]0 z  b: H$ a
一、其它数据类型转换为字符串
8 H! `/ c+ H" b1 j" Q$ z; R! k" E8 {/ `8 `: X, _7 v

# \: N5 Y5 B3 {% V3 ~* o短整型(int)+ T' t/ J: p  \- b) z
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制/ O" W( i. H9 ?5 A/ d6 d
itoa(i,temp,2); ///按二进制方式转换 " v: v. ^0 F8 V0 @
长整型(long)
% d! P1 j. i6 v* t8 w2 Iltoa(l,temp,10); 4 Y/ q" X& T' `! K1 ~# H
浮点数(float,double)
* v* C5 O' F3 f8 B用fcvt可以完成转换,这是MSDN中的例子:( C1 N& I! L  k+ b! e
int decimal, sign; # ^" f: M; s4 H7 R9 H& C6 h
char *buffer;
* c: q% q/ W/ Q1 odouble source = 3.1415926535;   _8 }9 }) ~6 a" N3 a3 n
buffer = _fcvt( source, 7, &decimal, &sign );
' _& \3 n, A1 Y- G运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
" w5 n3 O( j% qdecimal表示小数点的位置,sign表示符号:0为正数,1为负数
% V+ E; m  x% v  S) u0 uCString变量
" T/ T+ ]& ]; F  ]* Bstr = "2008北京奥运";" P( v' W. {, Q& O7 T7 H* M5 J$ N
buf = (LPSTR)(LPCTSTR)str; . J+ w; Q! X2 X- K" P# A; i
BSTR变量9 Q# h, U( s0 K( T% i
BSTR bstrValue = ::SysAllocString(L"程序员"); ; |& u0 }9 C: v4 A7 p: K
char * buf = _com_util::ConvertBSTRToString(bstrValue);
3 ?/ G, l! {5 m2 {: h6 K* jSysFreeString(bstrValue); ' R! O1 t/ G4 a2 G
AfxMessageBox(buf);   M2 Y) [/ R2 r6 o( f) e0 O
delete(buf); , G9 {( n9 |" o. J6 A2 T+ r
CComBSTR变量! ]9 V* p! w$ \  d+ f; K
CComBSTR bstrVar("test"); 3 R8 N+ Y3 o5 d+ U; R# G
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
9 V0 Z" n  c, s. {  J+ ~AfxMessageBox(buf);
* p! I4 p/ @8 q9 B$ Q6 ndelete(buf);
/ ]# E5 O- t% o# A' W0 N, F9 v* W. O8 w) O; z
_bstr_t变量& x9 p! h/ B  _  _, _/ R! ~
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
% G. O- E/ g/ A_bstr_t bstrVar("test"); 8 e+ q) `1 I" I  y' s& S. o" P
const char *buf = bstrVar;///不要修改buf中的内容
( ]3 h2 v' T' y8 d+ H2 jAfxMessageBox(buf); . }& i6 W+ o& d+ p/ y  \" U: Y0 F

1 d  _2 D+ n/ E  h6 C% {" M& d+ {. I- Y' u9 \- \
通用方法(针对非COM数据类型)7 h5 T) d' W. i( e3 x
用sprintf完成转换
' }( J4 ?* ?6 Schar  buffer[200];
4 U- P; q+ R) j+ z8 i0 ]7 Bchar  c = '1';% j, x8 U& @# ?
int   i = 35;
- X5 q3 l% M1 j! A5 ~. j+ _! |long  j = 1000;( ^6 S# K+ A6 s- i) E; x
float f = 1.7320534f;
- K1 P2 s  e) U1 Rsprintf( buffer, "%c",c);
" d, y. [' A8 S+ usprintf( buffer, "%d",i);
6 L, {. o# Z4 msprintf( buffer, "%d",j);
6 L( M2 C9 H6 o) H' R( o* Gsprintf( buffer, "%f",f);4 f( N2 @# ]7 {% s$ {
4 D, n4 x: R8 d
二、字符串转换为其它数据类型$ u  b( m* u# F+ c% X. R2 L
strcpy(temp,"123");
' Z4 s. B+ }8 M. M  y2 ?7 G8 `& p7 C0 Z. t
短整型(int)
1 S/ d- y& Z6 z  x7 d$ v; B& {, r  ?i = atoi(temp);
/ b* W+ C( v# J: l7 S6 _长整型(long)+ g. S% I( H  V
l = atol(temp); # W  L2 L8 z8 C; @1 I
浮点(double)
, P9 Y! D( |. p/ i1 O9 Hd = atof(temp);
! N0 l  }# J9 ?CString变量1 p2 m  z7 X! s; D7 P9 S
CString name = temp;
9 U. u* n: d7 R+ _BSTR变量 % B* C& e8 C# Q! x; |
BSTR bstrValue = ::SysAllocString(L"程序员"); 8 V* r0 h4 e6 T) g
...///完成对bstrValue的使用, N) o5 h/ B5 Y# `; {; U
SysFreeString(bstrValue);
- {8 n" C* m; N  C# L- B8 v: i2 c+ T! ?' o6 r2 A
CComBSTR变量; A  }4 X# z+ P, ?1 K. w" @
CComBSTR类型变量可以直接赋值
+ i# E0 f- _! S' W9 H+ C: ~  zCComBSTR bstrVar1("test");) ^' V! V( Q: j5 o* s; Q5 }2 |( B
CComBSTR bstrVar2(temp);: e% W3 [6 X0 ]% @5 H8 E/ B4 x# r

& |: G" R  u" Y2 a_bstr_t变量& L- T: I" \  M2 D/ `+ k# H! y! l
_bstr_t类型的变量可以直接赋值/ F% G2 j7 v" [6 o" t$ S: E) I% }
_bstr_t bstrVar1("test");
0 `" w, G3 i7 ~_bstr_t bstrVar2(temp); , u5 S2 W4 H8 H9 u$ t
7 `8 w' E1 U3 O, B

( L7 P2 P3 O- W! y4 v三、其它数据类型转换到CString3 c" }/ \2 _9 U# H2 W/ }
使用CString的成员函数Format来转换,例如:
/ ?4 F& ~" x1 U+ a+ G6 V8 n5 J( f  w3 f" X

) R+ N; p, d+ E# T+ u整数(int)
0 Z' {$ B" |; Gstr.Format("%d",i); 0 o! N% a& K# Z
浮点数(float)( l9 @, a, @2 n5 T% A
str.Format("%f",i);
6 G' H2 H5 D+ P; U( B0 m5 X$ P4 }字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值3 G8 u' E+ I6 J# D# D( D% U
str = username; 3 M# s+ o  ~+ ~& o/ R
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。  a3 ?. V# E4 F9 @, a

" m6 f7 Z) L5 L( h  N2 i四、BSTR、_bstr_t与CComBSTR
6 u' w* [! L" W3 c6 D7 _# x' K' `6 a' B3 P" [) k  G
& ~+ c: b$ M2 O( ]* S: W
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
. G- S+ H8 c4 {0 I  d' zchar *转换到BSTR可以这样:
! b) e+ W3 I3 x% v" TBSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib' M, W( [0 g+ l: h/ m
SysFreeString(bstrValue);
  \5 U1 X& x# a$ F反之可以使用* c( ^- E; b9 [1 `" S* @1 h
char *p=_com_util::ConvertBSTRToString(b);0 |: G% y4 m) f4 t/ S  Q
delete p;
0 }( [' H) l7 E9 X) {具体可以参考一,二段落里的具体说明。) i9 S5 x1 j/ @- ~; F) o9 h
. c% j/ n% ^5 @, U, E  ]; ^- }
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。3 f0 _+ l* x$ i0 k9 M
特别是_bstr_t,建议大家使用它。( {2 s( L) N4 N6 n

7 e# G4 [7 X! g5 m/ f7 G+ y# w7 H" S$ N  q
五、VARIANT 、_variant_t 与 COleVariant
. P0 Y0 p; Z; u( L8 w7 y/ e$ I: i- h8 v; Y
  W, `* v+ f* F1 y7 I1 E
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
$ t4 Z9 e: P" z8 C对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:, F0 U2 k" ]( n) {2 [
VARIANT va;) @8 n) J8 y  ], S% x0 P1 D. h. M
int a=2001;
, E+ x* I7 m  [va.vt=VT_I4;///指明整型数据% ~3 u. k. I6 g0 c/ g# h  i) g7 Y
va.lVal=a; ///赋值
& D0 S% Y; }& [4 q, t6 V0 c/ `6 b
7 E" ^. X3 o4 m" p: M" P对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:. j/ G  C2 l) v& V6 N

% n. {3 ]5 [; k' d1 PByte bVal;  // VT_UI1. : l) i+ C' w) c
Short iVal;  // VT_I2. , T9 e( E( x, j
long lVal;  // VT_I4. $ ~. D4 s' C. w" y- W5 v% E
float fltVal;  // VT_R4.
2 ^2 _1 \1 n9 n+ _double dblVal;  // VT_R8.
8 {- h7 ]7 N6 NVARIANT_BOOL boolVal;  // VT_BOOL.
; k4 n* N) Y: F+ E+ oSCODE scode;  // VT_ERROR. * U$ A  y: D$ d  F4 j# A
CY cyVal;  // VT_CY. * H" Z% y- }1 W: W$ g7 R
DATE date;  // VT_DATE. 1 ?. L1 w& o8 s# G7 j
BSTR bstrVal;  // VT_BSTR.
: i& W3 N% c  c" E$ F& \1 ~DECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. ) w" X( W% u6 {2 b2 [, ?1 Y
IUnknown FAR* punkVal;  // VT_UNKNOWN. & V* }6 n' Y. w+ d* N' N
IDispatch FAR* pdispVal;  // VT_DISPATCH.
* j; T# O9 _6 P% D- K3 O/ V2 Y# ISAFEARRAY FAR* parray;  // VT_ARRAY|*. , J1 N! s- Y2 w0 K/ ]& ?0 }' _6 {' t
Byte FAR* pbVal;  // VT_BYREF|VT_UI1. / U% e- z/ S! F) C$ B4 v
short FAR* piVal;  // VT_BYREF|VT_I2.
' M8 A9 ?8 ^5 Y& l) I2 P! K4 Tlong FAR* plVal;  // VT_BYREF|VT_I4. ! i% G2 S! z, w( U/ M" R( ?
float FAR* pfltVal;  // VT_BYREF|VT_R4.
; E9 A7 I3 M. l8 R2 N( K) E% Jdouble FAR* pdblVal;  // VT_BYREF|VT_R8.
" c$ D3 M. J( g* n' cVARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL. 2 y0 ]' U$ X6 h! p7 }+ r, N
SCODE FAR* pscode;  // VT_BYREF|VT_ERROR. . K% |' Z- L% I+ ~1 t
CY FAR* pcyVal;  // VT_BYREF|VT_CY.
3 v" N8 w- Y1 w. KDATE FAR* pdate;  // VT_BYREF|VT_DATE. 9 _2 a; z+ f& k; T/ D5 w( q" O
BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR. " p" g- e) f4 _" Z/ p+ `! ?
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.   g9 E/ R$ I: K. S( i/ L/ X
IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH. * j* S5 C! N3 X5 {
SAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. 2 f$ D4 x' Z0 _  A" ]4 `* l4 v% ]
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT. " i) Z; u8 k- i1 k# l: C
void FAR* byref;  // Generic ByRef.
8 x/ D- }; s5 y. ?char cVal;  // VT_I1.
' ?( t& M% [, ^! Z% \9 K( W* munsigned short uiVal;  // VT_UI2.
8 G1 q7 `  n, B+ `unsigned long ulVal;  // VT_UI4.
; V  F9 w/ l$ n# U9 l8 Jint intVal;  // VT_INT. + \- g( c3 H. P2 z* U! i) K" z
unsigned int uintVal;  // VT_UINT.
( Q) p0 j& Q. qchar FAR * pcVal;  // VT_BYREF|VT_I1. & v! V+ e: M1 Z* m6 f- c& S% v3 I
unsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. + c+ Q$ D# F' S2 s8 O% o! h1 W
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4. ) s1 p3 A- R; i
int FAR * pintVal;  // VT_BYREF|VT_INT.
. Q6 m$ b/ R: V' punsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
- K# t$ g* L* A' A" F) |3 Q/ ?! U) h, P. I

" R* f. X5 F, C" J0 F: R_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。5 t; ?: d- R2 T3 F6 I) \8 K  V6 l
使用时需加上#include <comdef.h>, k" I9 R! w: _" ^$ ?7 b
例如:
, w5 U% u: i* f9 b/ q' v) Plong l=222;
; o2 s, W' m+ jing i=100;
- d0 k' A6 P0 m, R1 W; M& l* R_variant_t lVal(l);
2 V: Q9 X5 N2 D1 W# llVal = (long)i;
& H; L+ t! j. Q4 ]
) y1 q: ?: E0 {% `, [2 e8 L
  t! Z# S: M: q  s# MCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:$ z( j: X$ q- @( b$ q2 ~6 f( v
COleVariant v3 = "字符串", v4 = (long)1999;3 f: V; ~( M7 d& e
CString str =(BSTR)v3.pbstrVal;
6 ^, ^/ {9 Z/ O' @5 xlong i = v4.lVal;. Z! v7 V4 Z/ D

" i; b1 ?* C% ~
* c, a+ J5 I* V  W" R0 Z六、其它一些COM数据类型; ^1 D" v$ J$ m
9 n2 g* z1 u& A9 C8 v3 ]9 V; A
根据ProgID得到CLSID
) h1 c/ \( t' L( @HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);( n$ Q/ E+ n: }: x( P/ b4 u
CLSID clsid;( G% Z  n! f, ?3 t
CLSIDFromProgID( L"MAPI.Folder",&clsid);
  |9 }$ D2 U/ K9 S7 q9 y( J9 p/ t# H: Q2 G5 Z6 [
根据CLSID得到ProgID
. W6 r- x+ h- `WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); 7 ^. t$ P' H& _/ z, Z% c
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
( i% Z9 D2 E: b; d2 _; f; ^LPOLESTR pProgID = 0;
! D+ ^- D+ H0 z  |ProgIDFromCLSID( CLSID_IApplication,&pProgID);
4 y  G5 X- J& X. o...///可以使用pProgID
6 P4 y6 {/ w& @; H: D8 ECoTaskMemFree(pProgID);//不要忘记释放 $ D5 K  A  w/ \1 u' ~6 U# o1 q

3 r: s8 i$ r- y七、ANSI与Unicode
9 y  ^! y- [0 B$ u8 ~  L9 KUnicode称为宽字符型字串,COM里使用的都是Unicode字符串。
" J$ Z# {7 [5 T- N2 Z* [# c: q: K2 W' T
将ANSI转换到Unicode: N# T! O% n+ i6 ]0 C3 A# J
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
# ^2 @% q  \+ e. j' R4 x7 X( P(2)通过MultiByteToWideChar函数实现转换,例如:
/ t9 V  z% Y1 [+ E* D; \( ychar *szProgID = "MAPI.Folder";
) v! V, p( y! C3 r5 f* aWCHAR szWideProgID[128];- q5 }9 `3 b3 A# e+ @, z4 q* W
CLSID clsid;1 ~, m" a) P4 P3 n9 ~) q0 m3 F6 K
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
+ X' C! L- H+ V+ K7 B( D# o) b+ UszWideProgID[lLen] = '\0'; 7 f' C) T- C5 B  w
(3)通过A2W宏来实现,例如: * S0 M6 @5 F" Y" }7 n& l: a
USES_CONVERSION;
- `+ Z1 N) |! r7 OCLSIDFromProgID( A2W(szProgID),&clsid);
: G. k/ Y  f, X+ b7 Z# N将Unicode转换到ANSI
  u1 h4 U9 n2 w- I+ l(1)使用WideCharToMultiByte,例如:
& h1 H3 v2 L! ?$ j4 v6 h/ Z: b6 m// 假设已经有了一个Unicode 串 wszSomeString...
& ^' }9 S6 y8 r' T+ `5 P# Xchar szANSIString [MAX_PATH]; % d7 k3 F* O9 y+ @/ L# a- a7 N
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
* `/ ?. f# x  q7 @* |5 e/ M" B2 F* T(2)使用W2A宏来实现,例如:
3 K- ?  b3 j# {USES_CONVERSION;
2 @+ ^7 ^$ a+ N5 g; EpTemp=W2A(wszSomeString); $ q4 D6 j  G$ F; ~) ~9 k
八、其它
" U7 o% a& `/ n3 ], c7 A0 G: \4 b* M, k7 k) Z
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:. x0 M- @7 k" M) X. o4 V
LPARAM lParam;
' v7 }, Y, j# D2 z& w( _" CWORD loValue = LOWORD(lParam);///取低16位+ I; c' I' y! q
WORD hiValue = HIWORD(lParam);///取高16位% s- o: ~; ?& k/ q& {8 Z

5 t) w8 }( E" K+ ?1 \/ w2 H, R6 Y% y0 e; f( _
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
- A8 M, E: j' W& D6 PWORD wValue;+ ^$ {- A5 O/ W- e; S5 T6 p! O
BYTE loValue = LOBYTE(wValue);///取低8位
' b2 s0 ~! P# A$ aBYTE hiValue = HIBYTE(wValue);///取高8位
7 K" j* r5 ^; r; ~/ U8 M8 _
: }7 E1 ~! s$ [& @
0 k. B- {# s) x" |3 f两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)& g+ Q$ p7 P7 P2 Q) z( K& O
LONG MAKELONG( WORD wLow, WORD wHigh );
) r- ]  J) g- u  pWPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); % f2 r! X' Z+ I/ c5 C; t$ m3 |) K. }
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
; Q9 G$ U+ Z/ Q0 T% p$ rLRESULT MAKELRESULT( WORD wLow, WORD wHigh );
& T' F- Q% f1 Z7 H- ~+ e% A$ d  J7 I# G
3 U; q7 ~$ F0 f5 ?- K& f
两个8位的数据(BYTE)合成16位的数据(WORD)
  q) W0 O% D8 q# r5 HWORD MAKEWORD( BYTE bLow, BYTE bHigh );
; n" K2 O' `9 \0 U5 R* L3 R2 c# Q/ t7 E# z) _/ y* r/ r0 ^7 x

! ^7 v/ U# W7 u; q2 c- X. D, k* q从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
, l, k3 ]6 f; oCOLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
7 d6 V& u4 g: `& E例如COLORREF bkcolor = RGB(0x22,0x98,0x34);6 O: ]+ p+ ?! {; a& j1 G9 ^

5 ~3 v5 _- e2 U3 ?# ^% }- j, P' {4 k; O1 Y- r0 S; ]+ c
从COLORREF类型的颜色值得到RGB三个颜色值
, d; B5 l7 p+ M3 u3 ~- c6 H" N+ UBYTE Red = GetRValue(bkcolor); ///得到红颜色5 u% O  P# w6 `# U6 z$ s7 X0 k
BYTE Green = GetGValue(bkcolor); ///得到绿颜色) h  ^2 e9 h, u
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色" X3 V/ l& B: N' z9 H  \3 R- e
! }" I6 ?6 ?+ I7 _
九、注意事项$ I/ i# @) y# b! Q1 e" z) ^7 F0 ~6 E
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )5 [* A) I* _$ U4 t( @3 C) d
5 y2 v0 \( M1 z2 I1 k7 b
后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-10-1 23:15 , Processed in 0.017366 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表