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

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君
5 g- o6 Z; H% p& L: J, p: b! L
! y- y$ Q, `% [. W1 F! B0 M) n刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。
4 r$ m/ T6 T$ f7 I# z5 t' Y2 S" D0 H0 s2 g
我们先定义一些常见类型变量借以说明
) L3 a' `! @, s$ Z# ~0 R9 L) i8 l& R1 v
int i = 100;
9 P" ?/ M/ b! o, ?. `7 V. p$ ?: {long l = 2001;
% ~9 q" I9 P* \6 Rfloat f=300.2;
- @5 C3 G7 G& b  `! ydouble d=12345.119;% X  Q6 v$ f- r7 W; r# f6 |9 j" x
char username[]="程佩君";
2 V. l, R" G& y2 b' Y# d6 Z. Gchar temp[200];
, W7 J  }. n' s# T$ c9 @char *buf;4 Q; \5 }- y4 L8 u1 `6 F/ u
CString str;& Z7 L" w+ R! O$ }1 o5 ?# L
_variant_t v1;9 }, ]0 t( G% R
_bstr_t v2;
1 ^5 Q$ I$ h4 e
$ m: k# `  P6 ^! W一、其它数据类型转换为字符串4 J* O" b' l/ i2 f
2 E1 w% D* s; G& t' x, Q/ b

4 Z9 k6 i6 ?: @0 m! |7 g+ _短整型(int)
& l: h7 ^! D/ Eitoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制% k1 `- u* k" {" Y: H3 W4 L! l3 z
itoa(i,temp,2); ///按二进制方式转换
3 w. X6 E& W/ w1 @9 J/ L7 _$ L长整型(long)% f( |: u; F& P; R1 P8 M% M; e
ltoa(l,temp,10); ' T' x6 x7 e/ [$ M) w
浮点数(float,double)
' \$ I. M. V5 t1 X0 U1 f$ V+ b) o用fcvt可以完成转换,这是MSDN中的例子:( Z1 p2 a% x+ v% z6 G
int decimal, sign;   h0 ?  Y8 a! V1 ?0 z& I; k% U
char *buffer; , `) [# z2 H# s6 K/ ]8 c5 t
double source = 3.1415926535;   ~% ]# i+ K+ V% o0 s7 Z  C1 ?
buffer = _fcvt( source, 7, &decimal, &sign );
/ D  A8 B) y8 r1 {& J3 X运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
' G7 S$ s- y( R, \decimal表示小数点的位置,sign表示符号:0为正数,1为负数
! p% s9 o: F5 ?2 X1 x8 X1 NCString变量+ x: Y4 U% _. _
str = "2008北京奥运";" t$ Y& D( j  I8 E! V* n
buf = (LPSTR)(LPCTSTR)str; 9 K" n, |6 e2 C2 y! y3 O
BSTR变量
4 u0 f% ~" R' Y+ C) |: _1 w  SBSTR bstrValue = ::SysAllocString(L"程序员"); 9 [" `# t8 Y0 a+ b# `8 u
char * buf = _com_util::ConvertBSTRToString(bstrValue); 9 V5 w- J  @6 L% z5 j! n
SysFreeString(bstrValue); 6 t; N& Z. C& o; x
AfxMessageBox(buf); & V1 y. p  c' F1 j& U
delete(buf); 3 L! p, i0 k9 C) o8 h) M. s% k# _; w( |
CComBSTR变量
* S% v1 T+ o6 a2 iCComBSTR bstrVar("test");
0 T* T( ]- {- Nchar *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
* w% x* S2 p* r- aAfxMessageBox(buf); 8 ~1 J- \. }. N  \
delete(buf); * b; f. I$ j5 t/ R

( h  Z! O; m3 [7 |* ?_bstr_t变量
+ J2 {5 d7 O! }, p4 ?_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用- ^9 g7 i' i% ?: \% {$ U
_bstr_t bstrVar("test"); 9 S' n1 Q. t( f3 [6 j3 l/ H
const char *buf = bstrVar;///不要修改buf中的内容
% H5 y) Z4 J3 VAfxMessageBox(buf); 8 L# {) {% I2 P! _/ G6 P- H4 k: d" d

( ^/ N5 Z, G' G/ z, J( B
8 [  G  T0 Z$ [/ E  f通用方法(针对非COM数据类型)- I+ L/ R/ u6 v! r* o) L2 W( K) {
用sprintf完成转换/ p; C" T% N: X; }) u* V
char  buffer[200];% ]0 h3 `( E9 o. Q' A. S  n4 _5 F4 b; _
char  c = '1';
6 e, W. L: Z  M+ Rint   i = 35;
% r' ]# t: a" D. y4 _2 u  Zlong  j = 1000;
. M; b, p% H" ^( \float f = 1.7320534f;
+ T6 q1 F$ {  P, b5 r' Hsprintf( buffer, "%c",c);
! R6 d# G/ A! y) e5 {* usprintf( buffer, "%d",i);; c) ~) q: F' d: F, ^) M
sprintf( buffer, "%d",j);
! V( I$ Y1 t1 {% b# U" E# Gsprintf( buffer, "%f",f);
6 ^: y* n, R* L3 }$ o2 L& W8 L
1 k5 T' R2 Y7 `9 R$ E+ M& I7 y' B8 o二、字符串转换为其它数据类型
$ a$ p; z* f( r2 Hstrcpy(temp,"123"); 9 n) |# N+ F0 {0 Q7 ?
( h9 h# j3 J. q8 ^
短整型(int)
: O8 k0 h; u# |& `- S& [i = atoi(temp); / y) M2 l( f3 n6 ]# R( U
长整型(long)
6 z9 k+ I7 ~. b: s+ I: Q3 V  [l = atol(temp); ) H3 H+ \, e  Q
浮点(double)
' [7 n4 j6 T0 q$ e; s; |8 id = atof(temp);
' p* `4 b" {- v0 @' _0 tCString变量. y6 S# j1 u, t0 s
CString name = temp;
! B7 b( \# u2 DBSTR变量
& }1 ]1 Y& ^8 tBSTR bstrValue = ::SysAllocString(L"程序员"); . h7 W, O8 u% y% b# V7 G
...///完成对bstrValue的使用& o( o! X8 ~) \, [
SysFreeString(bstrValue);
) R- s7 h/ B" Z- A5 U/ z9 x' u1 A0 v; M" {6 y
CComBSTR变量) h* g, T6 m  b+ ^( p/ J
CComBSTR类型变量可以直接赋值
6 e5 A# l& X0 l3 w! |6 u; c: \CComBSTR bstrVar1("test");. s6 Z' P* `6 F9 }7 l
CComBSTR bstrVar2(temp);
6 |# \$ a! z& o. I& i7 u, n: K* {  w
_bstr_t变量
8 @2 m5 o5 T. l5 t$ X( r9 k_bstr_t类型的变量可以直接赋值
. s+ w5 r: [3 T, X' n_bstr_t bstrVar1("test");
' ^0 {0 p3 c! g8 I) W4 b# s5 ~# h_bstr_t bstrVar2(temp); 5 o! \9 x1 u9 |! q# ?/ d$ L4 X

- L) @3 m" R# h, ~/ a2 _6 D, [7 L, J9 o% ^
三、其它数据类型转换到CString# C9 Y% M" [: E/ O- S/ k* J
使用CString的成员函数Format来转换,例如:
. }" w" _$ m; T# {7 k
% c4 F! O# g0 `' Y# T  W! c+ Y% O. }9 T: s! g
整数(int)) A4 n4 D6 o9 c% @1 O' n4 ~, d
str.Format("%d",i);
8 U0 D& M" f0 V3 F浮点数(float)3 s+ O8 s$ q4 k- e2 m. U* L
str.Format("%f",i); " X& \$ e1 X8 n% R8 y, g% i+ p
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值7 k3 C2 v, r+ F: h; O1 R# d% V
str = username; # u! v) w2 {  O( n8 b: n( q
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
9 u( Y8 w) ?5 B2 k8 G7 Y6 L8 Y+ j: i3 R# n* h; Y0 ?
四、BSTR、_bstr_t与CComBSTR
. ]- O$ G4 M' z" Z. Y5 Q7 o0 ?% q8 R( B

5 Y0 [7 p( @# DCComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。- R& c. _* L: Z5 R9 `" Z
char *转换到BSTR可以这样: ( [/ o( V+ L) y* A( Q0 |" j) V' u
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
( f* D6 U) f5 G" T- FSysFreeString(bstrValue);
1 H- m9 {& u! }$ w反之可以使用4 V' v* T$ d7 L( ?( s  B9 n
char *p=_com_util::ConvertBSTRToString(b);/ o' h; ], ?1 k$ n0 V$ ?
delete p;
, ]! L2 n0 t$ ?; @具体可以参考一,二段落里的具体说明。
0 _  ~$ V0 g) p/ H
1 n1 _3 u3 f2 C8 m( Q' W, jCComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。6 Z3 e: d6 k7 P* }! i4 D- ]: e9 W9 I
特别是_bstr_t,建议大家使用它。# z: j. n! F$ ~5 B

, A5 ~! i) Q$ l5 _, x6 N6 i3 W2 X1 x
五、VARIANT 、_variant_t 与 COleVariant2 ^$ y9 W  ?) ]% o. ]
% j* ?7 X$ N" V4 _
. c( f/ n/ I; m0 ?
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
: V' x+ d- N  e) u对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:6 \( H: i8 ^8 ~' S  Y( j+ ]1 F0 N
VARIANT va;& P- w3 I, v' f4 i% s8 c
int a=2001;
6 z4 c/ }* t2 L( ]# Rva.vt=VT_I4;///指明整型数据
6 S( C* ?/ r  X+ G# {va.lVal=a; ///赋值
8 r! M# ]% G! K# X& W; v
! e" N1 w  }! ?# C7 q对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:7 G7 e' M" C2 W2 |- a9 y

2 q. D* K/ R3 h7 w, VByte bVal;  // VT_UI1.
+ O! F% {% E1 q" |, IShort iVal;  // VT_I2. 4 Q) b8 u0 H  X2 w4 W5 S
long lVal;  // VT_I4.
9 Z# J3 O1 H" k7 H" Z6 R3 xfloat fltVal;  // VT_R4.
9 S3 G0 P" b% a9 m: sdouble dblVal;  // VT_R8. + g# Z/ H( J9 L) d
VARIANT_BOOL boolVal;  // VT_BOOL.
5 J  C0 z0 {' RSCODE scode;  // VT_ERROR.
( H$ x) e1 W8 y! D4 BCY cyVal;  // VT_CY. & i5 ^1 [& L2 V: e" s
DATE date;  // VT_DATE. # ?& Z* H3 g+ ~1 E5 H+ v
BSTR bstrVal;  // VT_BSTR. % P& F3 J* H9 I% L& @* L
DECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. & q0 A- |' c+ i
IUnknown FAR* punkVal;  // VT_UNKNOWN. 6 g' D- }3 E# Y
IDispatch FAR* pdispVal;  // VT_DISPATCH.   v0 x; Q" |( C! r* Y
SAFEARRAY FAR* parray;  // VT_ARRAY|*.
; d/ Q9 T  U8 @6 MByte FAR* pbVal;  // VT_BYREF|VT_UI1. 8 w, p. J  u% m& x6 f% r+ d+ [
short FAR* piVal;  // VT_BYREF|VT_I2. 0 Q/ W8 Y- v1 I2 w' m. V
long FAR* plVal;  // VT_BYREF|VT_I4.
5 O- L! q) B' {$ Afloat FAR* pfltVal;  // VT_BYREF|VT_R4. ! z) ^4 V* z6 I6 D; C4 o
double FAR* pdblVal;  // VT_BYREF|VT_R8. : ?" j/ T) @" F- m7 L
VARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL. # K8 b# U& v. a# ~! U. M( }
SCODE FAR* pscode;  // VT_BYREF|VT_ERROR. * k1 x; \" M$ v+ m- G6 [
CY FAR* pcyVal;  // VT_BYREF|VT_CY. : |, L! `) g! o5 m. f" f/ ~
DATE FAR* pdate;  // VT_BYREF|VT_DATE. ' L! ]4 J) ^' z. c, |7 _+ }6 N
BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR.
$ |4 B5 L$ c0 n- z  PIUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
" ]' V/ d% J, E: U! AIDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
4 a- m- ^2 ?8 i1 f  a+ A2 xSAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*.
  O% L3 D4 J2 V% m9 S: qVARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT.
) x5 K, V0 I4 U0 s  n$ D3 dvoid FAR* byref;  // Generic ByRef.
+ j" p* o5 Z# B- ~5 p+ j. Echar cVal;  // VT_I1. 6 X! \4 K, Q: Z/ A. D
unsigned short uiVal;  // VT_UI2.
7 W7 q5 K  \! Gunsigned long ulVal;  // VT_UI4.
7 i9 r" c  t) u3 Y3 sint intVal;  // VT_INT.
& v  G; E$ G+ S/ L3 j3 Hunsigned int uintVal;  // VT_UINT.
4 A7 v% }! Y/ Z5 n$ Kchar FAR * pcVal;  // VT_BYREF|VT_I1.
: a  K; P" R, `6 X; ]# P' @! F5 wunsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. 1 n% k" [2 l* u
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4.
  z. e9 f& O1 k0 C  z9 f6 ?5 d) yint FAR * pintVal;  // VT_BYREF|VT_INT.
9 S3 H( _' k- m+ {; Y+ a) |unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
/ I% m4 x9 i3 j
# _% Y. h( E. N% Y4 C
- \5 y, Q' Y  M' D# G& j* `_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
( y& R0 s/ z* A8 p% q# F3 o! o' o使用时需加上#include <comdef.h>
1 O" m1 t+ t* z7 ~$ i% B例如:$ {. B5 I- W$ J' k' V0 [9 {4 V2 R9 C  _
long l=222;
) V# Y" C4 R) h# B0 sing i=100;5 N' C" c# w( W( l7 l( H/ ?2 l
_variant_t lVal(l);
2 ]# p  x# W: V; {$ HlVal = (long)i;  E. Y5 y8 b9 C2 b" K3 d+ T
: x9 k5 z6 Q8 I! C6 B7 G
1 s& m: {7 V' g( F  B
COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
2 t  E6 m* n1 F/ U  ^/ q  PCOleVariant v3 = "字符串", v4 = (long)1999;
5 d0 V' D2 e( V0 oCString str =(BSTR)v3.pbstrVal;/ j5 O0 O; Q+ c/ I" y9 _4 l
long i = v4.lVal;  `- Y* M, ]! F2 N( D& f

6 A) p( v, x' [6 h& ^- |
% R" K7 a/ b- \9 ?& J1 x& v六、其它一些COM数据类型6 a) R5 l) I* x- }7 ?
8 S# g( U! Z, Q, @$ a
根据ProgID得到CLSID. E8 |+ e/ n: B8 |/ C& n  m+ t
HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);$ u' q3 }8 L+ b1 W# h
CLSID clsid;
9 t6 n* k- U' Z- x. s3 \; }CLSIDFromProgID( L"MAPI.Folder",&clsid);
  @; ~  Q( L% O" ^" G; o( M
4 p) l" k# R, {: ]- o4 W# _+ y% A根据CLSID得到ProgID9 `' X4 f4 K: p" |& V7 H
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
1 h4 E* K/ {& J# d+ s例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
& F4 G7 ?% F' z- Y( eLPOLESTR pProgID = 0;7 Z) N* `& ^6 R$ z6 ^- g8 H3 [
ProgIDFromCLSID( CLSID_IApplication,&pProgID);
2 x* d7 o  u6 g% ~9 x2 X...///可以使用pProgID
  h& e% l7 G& ~9 m+ z8 sCoTaskMemFree(pProgID);//不要忘记释放 . {. c' l: k1 E2 g- Q

  j( g6 Q( |, W# d' r$ e: l七、ANSI与Unicode
& e/ M8 o  \0 U% Z5 `Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。
- x# _7 D& w& F- s/ a* b& M# O/ A  G
将ANSI转换到Unicode
/ _0 R+ o7 n3 Z) t9 w6 C8 ?6 t(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);3 c% a5 {  h! g& l* `! o3 x4 y$ T
(2)通过MultiByteToWideChar函数实现转换,例如:. M7 w5 L, a# R$ A
char *szProgID = "MAPI.Folder";' |( C) V; k/ ?' u; x- C
WCHAR szWideProgID[128];
+ ^) C: V; F  z+ c+ `; ?CLSID clsid;
; @, G; F. j; u8 v: _/ m# jlong lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));8 F0 [9 O, p, x
szWideProgID[lLen] = '\0';
; T* Z- _7 P$ m: L! Z7 L) O- F(3)通过A2W宏来实现,例如:
5 i  m8 E8 ^1 t, K& |USES_CONVERSION; : F0 S) V2 E* M  z! u, t9 }7 ~
CLSIDFromProgID( A2W(szProgID),&clsid); - E# n) |. ^; P3 C# e$ P! E/ R
将Unicode转换到ANSI
) A6 ^* l% P: A8 X(1)使用WideCharToMultiByte,例如:
! a2 w3 }  R" `% k, Z9 j// 假设已经有了一个Unicode 串 wszSomeString...
; T6 z. y0 i5 S* achar szANSIString [MAX_PATH]; ) ^+ X8 g0 ]6 K: R
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); 4 C3 {/ T  s, G& d1 [# p
(2)使用W2A宏来实现,例如:
1 F) Z9 G. K8 `# a+ L+ j0 ^" k# t+ yUSES_CONVERSION;- V3 @/ ^! w3 }0 K6 d) t
pTemp=W2A(wszSomeString); 9 @( d0 t: M6 {9 i  e2 C& U
八、其它2 I; i) L: J& Y* u9 Z* n
0 n* k$ C4 d  Q8 _* M
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:$ F; e1 M. `7 U! f9 V( H$ e; m
LPARAM lParam;- J9 J  Q) z' p3 F+ P$ l
WORD loValue = LOWORD(lParam);///取低16位
' [- ]* J. |* ^6 D6 }+ W% b9 A* dWORD hiValue = HIWORD(lParam);///取高16位
0 o. V' H0 K" \3 |' N$ g  m
# ^* Q0 f# I  y4 p6 E! ]* Y/ Y$ Y( i/ s
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
5 o- n$ `5 }5 J7 v& Q  sWORD wValue;
" ^$ A# K7 w2 F4 H. l3 O+ ?5 o" X! v% ~BYTE loValue = LOBYTE(wValue);///取低8位/ Y" _" F+ j; l+ R% x
BYTE hiValue = HIBYTE(wValue);///取高8位5 S# [& q! j0 W
' d* L! _6 K9 w8 P: }
' v  m7 T' s* }6 R# o3 l5 M
两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM): {  m- L: q& i! h
LONG MAKELONG( WORD wLow, WORD wHigh );7 y% S3 N0 `7 R2 S/ B' o+ q
WPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); % _! _( `2 m& v% h; N% n
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );6 E7 N+ {3 ~7 J; Y9 C+ |
LRESULT MAKELRESULT( WORD wLow, WORD wHigh ); 4 r; n; ^9 v- L" r' j# f

$ X3 u& R1 x  I  {1 P6 z, f* c' E$ W, I& i5 S" O9 o
两个8位的数据(BYTE)合成16位的数据(WORD)
8 o; D% v, E. e5 Z1 TWORD MAKEWORD( BYTE bLow, BYTE bHigh ); ) H$ k0 G, a: A8 y8 W

' w1 q& `" \$ H: e) p( l* ?0 b( f9 C5 C6 M) p" W; ^
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
: }7 W/ j. k. O% }COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
! ~8 T( y2 I8 T例如COLORREF bkcolor = RGB(0x22,0x98,0x34);
5 d- M+ ^: |) p* k
# w" |: {& d4 D) f& Z. n) ~- h+ F# D3 Y+ n. c& |! p" t. m
从COLORREF类型的颜色值得到RGB三个颜色值9 ?% Y( d$ B. Y$ p- }3 j9 S
BYTE Red = GetRValue(bkcolor); ///得到红颜色
2 m9 P- ?5 F# {7 }  TBYTE Green = GetGValue(bkcolor); ///得到绿颜色: J( H% Z+ j, |, p
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色( y9 e) [, R# m1 ^5 Z2 K
# Q1 e  @! e' S9 S$ @4 r8 z( ^
九、注意事项4 U& A0 j2 g* h; O; c
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )
. k* t2 k# w+ s1 A- D
/ j4 t7 ?( O6 R: r后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-29 20:01 , Processed in 0.023910 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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