找回密码
 注册
搜索
查看: 4747|回复: 0

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君. |7 I+ R. f6 Q( ]

3 w9 i' R- u/ ~. Z刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。
4 L# }5 V9 T0 M$ w0 }$ o$ ]# w/ s* ?3 P2 d' O# E
我们先定义一些常见类型变量借以说明
) ]  ?( u7 s, E1 Q, L* z7 N. h( Y
int i = 100;
- \0 o, j8 D% B% j+ Elong l = 2001;7 t: V9 ]% ^7 r+ h! i& L
float f=300.2;
- `* d8 I8 W; V& T, y* @double d=12345.119;" K* V" O/ L9 A& l# J; M7 P( k* N- f0 \
char username[]="程佩君";5 n7 o- G6 W* e  c$ N4 d
char temp[200];
; }7 {; _3 Z+ q1 Fchar *buf;1 j0 W3 }/ d3 B' @
CString str;+ b/ b( v6 v/ V
_variant_t v1;
& s. e  M! L7 H_bstr_t v2;
# P5 z$ g& J# ?& w. c2 t* [6 H4 V7 j6 x; B) U; g) U# u* D
一、其它数据类型转换为字符串" H+ Y( {6 A  f& k0 ~* f( l8 l
% W& `! y% l" l: i
) v+ h" P& a( `# h  S, t" ^
短整型(int)0 b6 F% f- G0 ^/ _6 L; G$ A
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制0 u* r# [% \: G* L
itoa(i,temp,2); ///按二进制方式转换 " y% @' E, D5 E, z( ~6 s* f! N' j  r7 F  T
长整型(long)' J( Z2 q$ ~% o% G0 t& n
ltoa(l,temp,10);
  u( G6 H, G8 u5 f浮点数(float,double)6 ], J5 F! G8 S4 Z- n1 g" O
用fcvt可以完成转换,这是MSDN中的例子:
- V6 |+ y% G% L* I3 g+ nint decimal, sign; . I; o. A% q1 n/ N  Q5 |& ]
char *buffer;
% Y! K  N% j) `% O7 f; ~( rdouble source = 3.1415926535; 9 [0 U5 i& y& ^- J, E: S9 ~
buffer = _fcvt( source, 7, &decimal, &sign ); ( ^# w; G! `" H. ?0 L
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
  P) F, `- {0 Z* I$ H6 idecimal表示小数点的位置,sign表示符号:0为正数,1为负数
- n; K  w% H3 \8 k1 FCString变量$ A% q$ V( U* @% X+ m4 d! F8 g, }
str = "2008北京奥运";
& u  H3 t+ W1 `0 D9 S- b2 [buf = (LPSTR)(LPCTSTR)str; 9 {9 P2 w* k6 W1 t$ c
BSTR变量+ r- W; P( {; V& l& o. b$ O
BSTR bstrValue = ::SysAllocString(L"程序员"); 6 J3 h& Z: y9 z; H% X' [7 u
char * buf = _com_util::ConvertBSTRToString(bstrValue);
, f& `# x8 Z* O0 I& hSysFreeString(bstrValue);
% ?- j' \; |5 N0 H1 D5 ZAfxMessageBox(buf); 3 u; |( u3 O6 ^
delete(buf);
1 O$ H2 S) ~; HCComBSTR变量$ f5 n% v+ v; B1 j& k9 l: ?  t
CComBSTR bstrVar("test");
; \% |9 k" k# ~8 bchar *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
% M1 U# h8 T$ O( d0 \3 Z- R: X: MAfxMessageBox(buf); / N9 b  t5 V7 r. C9 k: C
delete(buf);
0 {# ~2 J5 _) \5 x% P$ y
( j, Z# a; V' M# i# f4 J_bstr_t变量
" f; c7 @/ ?2 z" }0 v_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用: [! {5 {2 J: j* F
_bstr_t bstrVar("test"); 3 I4 p! S# y$ k4 x5 c# C6 m
const char *buf = bstrVar;///不要修改buf中的内容 # Q# E. L2 g: n% Q
AfxMessageBox(buf);
1 B+ ], ~: F/ |& _/ F, d1 U& q4 f  N0 F- D( g
& D* ^& h3 S  h. I
通用方法(针对非COM数据类型)
0 M2 o! |3 p5 T" J; i2 S% a用sprintf完成转换
5 D% h- X* W- C( r2 _char  buffer[200];
1 J1 _2 O7 u8 n0 `6 }7 Ichar  c = '1';( C9 `( w0 i0 g$ U# U) W3 d
int   i = 35;, o; U( k% v4 q3 z
long  j = 1000;$ i6 [0 K% x; m% w) \/ j
float f = 1.7320534f;* b6 h" W' D& J2 Q1 o
sprintf( buffer, "%c",c);* [0 U! _, W2 D# E8 x5 i8 b
sprintf( buffer, "%d",i);
9 [. h7 K" Z$ c5 H* X& {sprintf( buffer, "%d",j);
( a) S& J0 N& y* w, s' C1 hsprintf( buffer, "%f",f);; j. h! F4 d- t  T) P
" J1 B% `2 ~' ^- @* m! k7 P
二、字符串转换为其它数据类型
( P8 u- }# B8 `; S1 Dstrcpy(temp,"123");
# q4 j+ |4 d4 v3 v& l# @  ]5 c0 G8 R7 j: l
短整型(int)1 F4 ?% N- R; R
i = atoi(temp); 5 `3 e* s2 E  |  I5 o( J& e* T
长整型(long)% ], u/ U$ n0 R
l = atol(temp);
8 B, m7 k, [5 ?  f* c浮点(double)6 {1 f; J. w4 q3 S+ S2 t1 v+ u* w
d = atof(temp); & n0 B0 y4 q+ |" l2 S9 \" h
CString变量0 i5 T/ Z, {+ a' v" I1 o
CString name = temp;
: k: @+ o' F% o# p. `BSTR变量 ' Q2 D. b$ T! q) K; P: N2 I
BSTR bstrValue = ::SysAllocString(L"程序员");
( C. p4 w# ~% k# E3 U...///完成对bstrValue的使用
  E$ _& M/ ]! ?8 t- F1 d  rSysFreeString(bstrValue); 0 b8 S( G0 M$ u# r7 @& ^7 m6 m$ A

6 i7 F. [, a& X% r  W' OCComBSTR变量! i1 n5 |- o- S7 Q2 a
CComBSTR类型变量可以直接赋值
; S6 B1 c9 H6 T4 z+ u1 q! @CComBSTR bstrVar1("test");! q7 m/ }/ l& N# Z' f
CComBSTR bstrVar2(temp);
8 C9 \& y( \! A! c/ S; k  z$ d
5 M( i: ?" m! `+ C$ r_bstr_t变量) N- A6 {+ |. n# c! U$ Z, Z
_bstr_t类型的变量可以直接赋值
' L5 t+ j2 ?0 q3 i1 b5 W8 R  A' |_bstr_t bstrVar1("test");
6 A# p1 n& |' m* W7 K_bstr_t bstrVar2(temp);
  ~* L/ X9 f  k
0 ^- I: M  i5 I
0 [' j0 y& b" ^( G% N6 Z三、其它数据类型转换到CString
8 Y$ H7 o9 g1 {3 V使用CString的成员函数Format来转换,例如:
( R5 Q, Z4 g6 H
- ?( p( F# ^2 b# Z. d7 Q
; Q" s) w$ d! h" L整数(int)& f1 ]& z! G- P) ?( ]) J1 b& @
str.Format("%d",i);
0 T5 k( d9 _8 n浮点数(float)
; F; D6 z: B& ]! m+ a* m, Qstr.Format("%f",i); + S$ h" Y! h0 @7 D
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
! r- x! w8 X6 `, I! \4 |1 rstr = username; 5 A3 L* Q+ D8 u( t% p
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
0 L- b7 d: c! G- U' c% z6 y8 @# ]; M' {2 b
四、BSTR、_bstr_t与CComBSTR# N7 ]3 a5 p8 y" S

, M; a& `2 T& t; r( ^3 t7 Z
/ J" w8 k0 l: M# k# bCComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
3 t# f* V' t5 E/ x  \+ c& achar *转换到BSTR可以这样: $ G+ G4 l2 B3 r, [: z* j/ F
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib: q  l- ]" P; |4 ^& Y  E
SysFreeString(bstrValue); & m6 l6 K; l# o' w- U- I
反之可以使用  ?  ]! n5 ?4 J2 }! f
char *p=_com_util::ConvertBSTRToString(b);
+ ?& a& u. Y' s0 O. d5 E9 Xdelete p;
/ M6 \% a: y& P( v& C+ S具体可以参考一,二段落里的具体说明。
9 [3 ]+ d& l3 r: a* Z9 p, ^5 @. ?9 {' j5 C. g" b4 D7 S6 j
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
' \, b3 H8 `( B& p' f3 D$ i, \特别是_bstr_t,建议大家使用它。7 X  J, i. f5 p

. [2 r/ z& S. m/ b4 ~/ {6 e
% q; ?( w9 h" k% @  A( [五、VARIANT 、_variant_t 与 COleVariant5 m; p" ^( |# v8 I8 s! ?0 ?
+ x" L( ^2 k1 |: @9 M6 k

3 n$ u# E9 A; m: ~VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。4 R3 S: M7 D$ M+ c9 g! C% a! X
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
% Q' H8 c; L) z$ z0 g0 O, f1 dVARIANT va;
" P+ j  y  a# _: Iint a=2001;3 \! B, [/ N0 F: v! U" [/ ^
va.vt=VT_I4;///指明整型数据
8 P" g& h# u8 i7 F8 d9 kva.lVal=a; ///赋值
$ c- F: \# ]/ Y. u) \0 V/ r( `
9 Z% T8 ^, _& e2 l+ o对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:/ o  q' f# s& }

2 `; D+ _) k5 a6 u1 l" `, [) rByte bVal;  // VT_UI1.
0 j* X& c8 i; A% M8 e  d& G& VShort iVal;  // VT_I2. + K2 b; g5 c2 d% J' B! S2 r
long lVal;  // VT_I4.
3 {. \+ q# v9 X4 J( Bfloat fltVal;  // VT_R4. 5 |1 O0 u) L# _
double dblVal;  // VT_R8. + A+ H& C( _! H+ b( U/ z6 u, K9 B: r) A
VARIANT_BOOL boolVal;  // VT_BOOL. ) n! \$ R% q+ }( t) b# Z7 m
SCODE scode;  // VT_ERROR.
6 Q4 S' @( X" ^  ~, yCY cyVal;  // VT_CY.
; P1 K) a) t- Y( sDATE date;  // VT_DATE. . F# g0 c% c, B5 J' \0 L8 L) c
BSTR bstrVal;  // VT_BSTR.
6 |2 `. q6 a! t# ^6 |% H% ]" H  uDECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. 4 k+ ^" F8 W9 z" C
IUnknown FAR* punkVal;  // VT_UNKNOWN. 9 Q, z$ U5 {) ^# y& s
IDispatch FAR* pdispVal;  // VT_DISPATCH. 6 s5 O; }2 V  u( B6 X3 [  q8 Y( _$ }6 u
SAFEARRAY FAR* parray;  // VT_ARRAY|*.
* m( B& u. k9 NByte FAR* pbVal;  // VT_BYREF|VT_UI1. & W: j7 w/ b8 }. \" D' f
short FAR* piVal;  // VT_BYREF|VT_I2.
, h) X; s2 F  a. }/ ]long FAR* plVal;  // VT_BYREF|VT_I4.
9 p: N+ t2 t3 r! ?0 O% u; t5 [6 m3 `% Lfloat FAR* pfltVal;  // VT_BYREF|VT_R4.
+ q5 _) L8 ]' `6 a" {double FAR* pdblVal;  // VT_BYREF|VT_R8.
0 ]* N- g. l1 R) rVARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL.
$ h9 Q5 U) ^, S0 ^5 V4 ]2 }* MSCODE FAR* pscode;  // VT_BYREF|VT_ERROR.
( `5 t, |$ t. \0 aCY FAR* pcyVal;  // VT_BYREF|VT_CY. 2 S" a  Y& H+ ?+ u6 }. g% [& `
DATE FAR* pdate;  // VT_BYREF|VT_DATE.
5 j" n8 A5 ]2 N) D6 l: M% zBSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR. 5 R% `) ?( m1 e: o' K
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
5 s3 K! `( U' y5 y7 q9 H# k7 M" jIDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH. ; N( p- A' `6 c' H- L
SAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. " n3 T$ A% f' ]' W6 g
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT. 0 U6 n& C" z/ g. P8 j
void FAR* byref;  // Generic ByRef.
2 \  M6 f! _, w! D/ d& J' D5 o" lchar cVal;  // VT_I1.
. }# s* @0 ?; c9 h! z! i% `! runsigned short uiVal;  // VT_UI2.
1 y$ x" D" k5 J! b& J' R) vunsigned long ulVal;  // VT_UI4.
) j) k$ M) c4 C2 w+ E; }int intVal;  // VT_INT.
, S+ q) Z9 W" M, j7 m- j, Tunsigned int uintVal;  // VT_UINT. : R% ^9 u/ ~- q0 U; r6 Y( I7 E$ w
char FAR * pcVal;  // VT_BYREF|VT_I1. ) O2 u  V6 M3 d0 f# m, h& ]) u
unsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. ( M$ H# i- l) `* r4 G# q' O8 F
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4. 9 x+ W" S* Z) B
int FAR * pintVal;  // VT_BYREF|VT_INT. : G/ }* @) b, ^; e$ b
unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT. 2 g5 }0 U/ v0 @. R9 n3 j
3 p+ p  w! I; v8 X* H0 _- c+ b
) j& E( D1 R! ^+ E3 i1 g5 F6 V6 C
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。/ @6 G/ d+ E: h# W; Y
使用时需加上#include <comdef.h>( o5 E# H/ M# C3 T0 D/ z! E
例如:. U, S: ]4 [4 n- Z
long l=222;9 d/ C3 J- @+ P# _5 w/ y' N
ing i=100;, c4 d4 w, W: H
_variant_t lVal(l);5 W, w& b; c6 d6 e3 h9 o# b
lVal = (long)i;
) N2 }- Q0 Y0 K" V/ v! ?7 \0 v7 Z( x9 A

5 A8 Z7 a4 M4 |' Z$ t" s  [, CCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
3 X" \1 }. ~. }' nCOleVariant v3 = "字符串", v4 = (long)1999;
3 K. @+ G  M" g$ h$ }+ BCString str =(BSTR)v3.pbstrVal;- w# J* l% w$ E( T0 T5 H) p
long i = v4.lVal;
: w( o$ E# P# }7 Q. V5 F: {7 _- G4 X& u$ s- N/ z6 R) J, s

( z1 C& ^: o- i" X% C六、其它一些COM数据类型  [8 D% Y* a5 q
1 _$ u- {% |! D/ u/ K$ W( {
根据ProgID得到CLSID
+ m3 s9 ]9 m, s& AHRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
6 c: m7 g$ S" [4 U9 cCLSID clsid;9 W: X# A, A4 D- \, Z
CLSIDFromProgID( L"MAPI.Folder",&clsid);
( J! c/ P8 ?( q9 w" S5 v5 w  P( z8 @. |' \& |3 n2 Q" B
根据CLSID得到ProgID
; o- f& {" m0 A% S" E; OWINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
; ]7 V, v$ ^- \( R$ C例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID4 G0 A0 W  w1 _5 |6 ~$ d3 w
LPOLESTR pProgID = 0;6 W6 e9 T8 y3 [# c) O4 s/ u4 g" v8 b& ^
ProgIDFromCLSID( CLSID_IApplication,&pProgID);
% p$ w# ^. @/ a8 M) t! C* N% k, J...///可以使用pProgID
2 j2 K7 ?6 a6 z) p: O$ hCoTaskMemFree(pProgID);//不要忘记释放
3 ^- u8 ~: j! o6 H" R
, a, p8 Y2 B3 X9 F七、ANSI与Unicode
8 ^- r- A  J- |$ ]. bUnicode称为宽字符型字串,COM里使用的都是Unicode字符串。
4 ]. e# L: x3 y- f
5 D. `& d" u' R, g7 q将ANSI转换到Unicode! ^0 m& s8 [  a
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);! K: Y# \: n: R! H
(2)通过MultiByteToWideChar函数实现转换,例如:3 x- d" ?- n9 x
char *szProgID = "MAPI.Folder";
/ v: M- t/ T5 ]% KWCHAR szWideProgID[128];
+ V3 S! H+ ~" _8 b& C' \CLSID clsid;
  W; L0 l1 [. O% Hlong lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
, a2 Q+ j2 [$ c% XszWideProgID[lLen] = '\0'; " S5 ^% P8 n3 p& z% T, F3 l& B
(3)通过A2W宏来实现,例如:
! S/ s! f% E2 O% g/ h% jUSES_CONVERSION;
% [% C4 g1 f% ?CLSIDFromProgID( A2W(szProgID),&clsid);
9 G, V6 P  e7 O/ B将Unicode转换到ANSI
( s) l# ~! m# k* J, x! O(1)使用WideCharToMultiByte,例如:: X0 W$ u  F  r1 W4 f) `2 S
// 假设已经有了一个Unicode 串 wszSomeString...
4 S5 @/ j1 j3 S; bchar szANSIString [MAX_PATH];
6 {3 e4 V, x% C- D' E0 L; TWideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); + X( O8 y. T6 r
(2)使用W2A宏来实现,例如:
- a6 A5 i* H. |, aUSES_CONVERSION;
8 H  S, E4 Q4 e3 p/ I1 G$ wpTemp=W2A(wszSomeString);
3 X% }  x; ^4 [7 @" ^) T5 I八、其它
9 N4 g( X$ l4 x+ K/ R7 b" R1 J9 \$ Z5 w$ }. J2 y
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:: c8 Z6 A7 L4 h' }! g
LPARAM lParam;
. ]% @1 t; b( H" [, U( tWORD loValue = LOWORD(lParam);///取低16位) k/ D+ j* j/ l" q# ~' Q9 Q4 p, x
WORD hiValue = HIWORD(lParam);///取高16位
3 |' y4 c" h, a5 F; I+ F: m
% V  }- f3 x) v" h' V* T, B& g7 E: e
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:! b3 M4 u5 k3 F6 B6 `
WORD wValue;# f( Z) ?# z% y) y$ C+ h: n
BYTE loValue = LOBYTE(wValue);///取低8位& }4 }( Z' e% p
BYTE hiValue = HIBYTE(wValue);///取高8位
- @" t/ L5 l8 p& L: b# o; ^" K! M4 K2 F* d
2 }+ e- @2 c- d$ y/ J/ `
两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
' K7 W, D8 q7 Y/ J# n0 c" j+ OLONG MAKELONG( WORD wLow, WORD wHigh );1 q2 J* f# E8 g% {: ~& W' E5 s* w0 w
WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
- M' }5 H: R. h1 y" oLPARAM MAKELPARAM( WORD wLow, WORD wHigh );
: k7 Q9 ?3 V' A5 O9 ~- c6 T6 lLRESULT MAKELRESULT( WORD wLow, WORD wHigh );
+ \! `8 [. b) E) t6 o) z3 G1 J
+ t5 S6 V, g1 r* x
, k, ^4 Q& b& u5 K! n* C两个8位的数据(BYTE)合成16位的数据(WORD)
3 v- j8 f4 F" e9 `WORD MAKEWORD( BYTE bLow, BYTE bHigh );
* G* \( j' s2 i5 j  g* |1 g+ V% O+ Q5 n. E1 I8 N4 y% S* `* {( |1 k

  O% Z$ i3 _; a5 o1 x' H6 {3 t; b从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值  U: @' M1 F7 X
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
) ^% t9 l; q7 Q% A/ Z" u例如COLORREF bkcolor = RGB(0x22,0x98,0x34);6 L' _: v% @+ p

$ X' B' E, \9 |7 q! j# \6 ?$ `
( L/ _8 I/ N6 W  z" l0 e  i从COLORREF类型的颜色值得到RGB三个颜色值: }3 q9 H3 Q, u$ n
BYTE Red = GetRValue(bkcolor); ///得到红颜色
& d+ L6 O( K/ T4 u6 L1 pBYTE Green = GetGValue(bkcolor); ///得到绿颜色
7 w; x9 _! \! m5 a% RBYTE Blue = GetBValue(bkcolor); ///得到兰颜色
4 J2 [- z9 g4 D9 I, X2 Y
- j+ U; r  B$ }7 F+ H# Y* q4 Y九、注意事项
0 _7 ^8 j4 P0 X+ t: t. H. q假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )( C3 ]; A3 M, F. }6 k! n4 @
7 L) N) o" A/ G. L9 s
后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 08:46 , Processed in 0.018715 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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