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

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君% }. ~( F; Q0 K; v
+ J( t; ?4 [/ L7 T; C- `
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。
) |6 z4 L0 C4 Z" V5 w* ~
% N% P0 Z( P8 L; H  q5 N( Z我们先定义一些常见类型变量借以说明. o& X3 Z# e: z) o+ f

9 Y( y& g; {' Q% mint i = 100;
) z  [) U2 f( a1 y& b) k" Hlong l = 2001;
1 l' f6 L6 l: i5 vfloat f=300.2;
  s1 t8 C: a/ `4 I- Tdouble d=12345.119;
3 }7 H$ P$ q6 L& p; D1 fchar username[]="程佩君";5 Y0 E4 b- _/ F' e) B
char temp[200];6 O/ f" l8 J% b; ?) T' Y  r
char *buf;1 }; M# j2 M! F; d
CString str;
9 O& R/ I" e/ U) z9 Q) `_variant_t v1;2 B$ u. s: d7 r
_bstr_t v2;5 s- d3 a( Y4 e4 f( i! U1 ]

0 p4 r/ b# U% m( j  @# j- D; W$ d7 S一、其它数据类型转换为字符串
; U- h  ?! s  ~" z2 Q2 V! J9 e- h7 X2 o' N- |$ g
- b( X6 g5 n/ [
短整型(int)6 j8 v; M; {* p; ]
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制3 n- g' M) i) N7 F/ Y6 h
itoa(i,temp,2); ///按二进制方式转换 0 g: M/ ]( k' X2 p. \5 e
长整型(long)
2 p, c, h/ _/ W$ hltoa(l,temp,10); 5 I. v! E6 g4 m9 M* k. i% k
浮点数(float,double). x* k6 p9 U8 x8 X, c1 b* [
用fcvt可以完成转换,这是MSDN中的例子:& k. E) j+ n( ?" J# @
int decimal, sign; ( Z) s$ S$ L# \0 O6 K
char *buffer; " W4 {  A7 u; A9 @$ B: v# j
double source = 3.1415926535; " t: Q* j" @9 P
buffer = _fcvt( source, 7, &decimal, &sign );
7 T$ V! P) R: ?* n' f" V  j& S3 t运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0; N- Y- {6 I! i3 [, K* V( M' N
decimal表示小数点的位置,sign表示符号:0为正数,1为负数
4 P1 j9 V0 M0 w, i4 Q6 S& f7 P+ JCString变量9 [$ \2 M3 h/ J3 _
str = "2008北京奥运";
/ I& a. s' N- S1 Q; Abuf = (LPSTR)(LPCTSTR)str; - r  V9 E$ A- Q: R1 u
BSTR变量
. _; i; l' e" W4 M- N5 G# gBSTR bstrValue = ::SysAllocString(L"程序员"); 5 }; @. q7 i3 z+ J
char * buf = _com_util::ConvertBSTRToString(bstrValue);
. r0 r/ J$ Q$ x+ j2 W# iSysFreeString(bstrValue); 9 |8 T8 N3 [) h
AfxMessageBox(buf);
5 R) R+ G' P& L$ Q0 m5 f$ Bdelete(buf);
  w# r" L( i$ Q4 kCComBSTR变量
- r# G9 P4 P+ f9 o8 MCComBSTR bstrVar("test");
, W& k$ c/ h; m& t# d/ wchar *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
. O7 R) C+ @3 N% ^AfxMessageBox(buf);
3 h9 y* l4 k& R$ Odelete(buf);
' |& R2 ~% p+ X$ _+ K7 e/ [  A& x4 T5 C7 ^4 D& }, e4 T
_bstr_t变量6 b( }' m7 S7 a1 h0 U% a7 e/ q
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用7 R* t9 a) d+ W5 @  w/ W6 v
_bstr_t bstrVar("test"); . q5 K* Z, ?3 K1 x2 A. `' c
const char *buf = bstrVar;///不要修改buf中的内容 8 E! @6 O6 k2 W' b
AfxMessageBox(buf); $ y. `7 x1 }0 z! l% e7 l! w

$ T. \& ~) x; X1 {1 f9 t% y1 C' ?( v8 N6 D) ~$ o- [9 R
通用方法(针对非COM数据类型)
; O' B- P* S, M& T用sprintf完成转换
/ Q6 w8 M' B* ?, Ychar  buffer[200];
1 d' L  }* V- u! D, \char  c = '1';7 n) w: s% B( q% p
int   i = 35;
5 R1 K: T4 n8 b0 U' Elong  j = 1000;4 m9 i$ @1 q9 M+ X2 |+ E8 \; m1 F
float f = 1.7320534f;; Z$ U5 f/ a8 {
sprintf( buffer, "%c",c);
2 {) }. ^1 o* k' x9 M# [sprintf( buffer, "%d",i);
! |" t3 V1 _4 lsprintf( buffer, "%d",j);
6 G# |4 k. Y1 n; \2 j8 z" }sprintf( buffer, "%f",f);
/ z2 m+ e' a" n8 V) a
0 w; Z: N- q. i" h二、字符串转换为其它数据类型
* m% n0 U8 m; D2 i* [strcpy(temp,"123"); ) j5 H  ?& s' `. o

7 Z1 [6 j" Z' v0 _* G: L* j短整型(int)7 }) k; v* m8 V/ X' H  L3 ]9 z
i = atoi(temp);
; B) T/ i' T+ B# d% S0 r7 Y& J长整型(long)9 s& v/ x6 f$ R
l = atol(temp);
; `, {5 ^9 X  a/ i8 N$ K7 ?浮点(double)8 a# w4 f* n' n' ~- y" j7 E
d = atof(temp);
& ^0 W4 J2 y  F  B4 Y" JCString变量7 j0 Y! }. i+ t' D( ?
CString name = temp; . K1 T5 a& _/ ?! X( l5 e
BSTR变量
' D2 w# ?* O% l& QBSTR bstrValue = ::SysAllocString(L"程序员");
" Z2 B. H+ w( F* U0 x) e...///完成对bstrValue的使用
1 m6 i. c5 j  o# H5 u& ySysFreeString(bstrValue); 5 k7 \$ D1 J$ ^2 o# P
( d& |/ Y. W( P7 T7 ?6 _' k( @6 u
CComBSTR变量
1 z+ A4 L  c1 y' w! K4 ^+ M2 {8 fCComBSTR类型变量可以直接赋值% V5 |9 c$ U& q- Y9 X  \- B+ j
CComBSTR bstrVar1("test");
' O+ T4 v7 u  h- FCComBSTR bstrVar2(temp);
, K& k0 ?  X+ o1 Q7 j1 t. D; U$ R/ e! U+ G( x; B/ V
_bstr_t变量0 O) i0 Q7 e1 x& Q2 g& I
_bstr_t类型的变量可以直接赋值
! U7 ?7 }0 E6 ^4 L+ A9 m_bstr_t bstrVar1("test");
' ^' N8 x+ r5 k0 H2 ~$ f/ V9 A8 m_bstr_t bstrVar2(temp);
$ E, u9 b9 D3 L* a
( y/ F. h( [: D# p) F3 D4 w/ o. H5 F0 k
三、其它数据类型转换到CString$ h8 }& i' h" q' s; k" I
使用CString的成员函数Format来转换,例如:
, ~7 p6 G3 {1 t! G2 T
; y. M: d: Y, S4 a5 b4 V
5 L3 N6 ^; l( a2 p# D9 ]整数(int)
9 z2 v( |- L" }# U" |0 I/ f* K, \; Istr.Format("%d",i); / y' i. F% Q  _+ h( I! f% |4 `
浮点数(float)
5 d3 ?0 f+ H% y. M  Ostr.Format("%f",i); , _# `( V7 F( L2 [* B+ [: m, _* l
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值& x8 W3 x, \8 w- d% `- r
str = username;
7 E& W5 Q* F% O对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
. w( w+ Z4 f* V5 ?3 p: G, h/ O
, k  j' j1 X/ u' G2 g) w四、BSTR、_bstr_t与CComBSTR
6 ?, c& n2 L+ N5 B  {: l1 e* k
. Y; m3 f  ], ~: u; t( ?/ h: [6 q+ Z6 z$ G8 O
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
; E! c+ p6 ~  n0 _( c0 v/ [: |char *转换到BSTR可以这样: 4 Q% J: C7 w0 H  w
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib5 F: ~8 b- |. `6 W3 |
SysFreeString(bstrValue);
, V, E) E$ P( \5 f1 b4 ~. G反之可以使用
$ w6 k0 {( d0 F1 d8 h/ G( H% n; X% Nchar *p=_com_util::ConvertBSTRToString(b);
0 L$ [. h" R: ^delete p;
- i% j" @- e8 ?9 `# v. R2 e具体可以参考一,二段落里的具体说明。/ V; ^& u* P1 m: d' Y3 t' n! |

+ ^  E/ x" W0 }, J& n( JCComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
4 q1 z2 _. S8 h& m1 k0 h# R特别是_bstr_t,建议大家使用它。9 W, P+ f* q6 Z/ B& `8 q: T- l9 F

" T- {0 A; g; j7 ]8 n1 x' T. v' Y, t' X3 w( f- G% h- w4 }* p
五、VARIANT 、_variant_t 与 COleVariant
& m! d- e* b2 l; {5 I5 U2 Y' r
, @4 H! M1 {/ x+ n
+ @% V- q( E& k( _3 r6 `, hVARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。. r' [4 h7 \7 M" {
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:! h" G" C2 T* d5 h
VARIANT va;
+ @$ h: m3 Q& A- q, N# k* Cint a=2001;6 T# ]: h. i& q
va.vt=VT_I4;///指明整型数据% ^' v) e) q! K% N9 n
va.lVal=a; ///赋值
$ f4 V6 a' b0 r) ]  T  ^7 g6 p% F1 r% s
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:2 ^' U) _/ H# u8 R
. s4 O+ Z# U8 J
Byte bVal;  // VT_UI1. 3 @* ~% ~, h: ~% K# b& r# i
Short iVal;  // VT_I2.
" ~5 z# E' D  s, Elong lVal;  // VT_I4. ! {3 _9 p/ ~8 @/ O2 v5 C7 t0 J9 \+ y
float fltVal;  // VT_R4.
; n/ c$ f  V2 f( T: c0 Wdouble dblVal;  // VT_R8.
$ ]0 c0 W1 G, d4 a9 F1 c" ?VARIANT_BOOL boolVal;  // VT_BOOL. ! X" z4 z! t0 v- s' N1 r! L8 D
SCODE scode;  // VT_ERROR.
# D( e1 z6 {! T! T- u  @CY cyVal;  // VT_CY.
$ T5 k% n" f' t: {$ `# K9 eDATE date;  // VT_DATE.
& @' H% `! q  M* p/ }BSTR bstrVal;  // VT_BSTR.
0 G6 C3 I6 W  a8 E- a9 C2 IDECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. 3 L/ d/ ]+ x% l# G+ \( }0 Y
IUnknown FAR* punkVal;  // VT_UNKNOWN.
* r  F0 R! n6 U- k  b% E" VIDispatch FAR* pdispVal;  // VT_DISPATCH. ) A0 X2 c0 b8 M4 C+ T& b9 _
SAFEARRAY FAR* parray;  // VT_ARRAY|*. 8 [0 l( j* K7 S5 J5 v3 t' _
Byte FAR* pbVal;  // VT_BYREF|VT_UI1.
6 ]' b# K$ v+ S" i* I1 fshort FAR* piVal;  // VT_BYREF|VT_I2.
0 s7 z8 W$ b) T, Nlong FAR* plVal;  // VT_BYREF|VT_I4. ; ]9 u2 q) N9 d7 s- Z
float FAR* pfltVal;  // VT_BYREF|VT_R4. . t' u" g/ \8 Q
double FAR* pdblVal;  // VT_BYREF|VT_R8.
" l& H6 F/ x# |& O9 R  hVARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL.
' c- U6 D, Q" \' D6 dSCODE FAR* pscode;  // VT_BYREF|VT_ERROR. * J3 Q; A7 {4 j$ M9 r% b5 q
CY FAR* pcyVal;  // VT_BYREF|VT_CY.
0 \  ~) D& `& D: n& ^DATE FAR* pdate;  // VT_BYREF|VT_DATE. ; X/ \9 u, M  G8 [) }: y) R
BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR.
# Z- ~- G/ u' v) ~1 T0 NIUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
4 {+ F+ y: ~" H6 vIDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH. 7 y: v9 I+ X4 j1 I4 K
SAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. 6 ~! j: j, Z, ^# P
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT. , }6 c1 q; H1 r3 b3 ]  H1 v+ M: \
void FAR* byref;  // Generic ByRef. 1 v" Y7 }0 m6 i6 N' |
char cVal;  // VT_I1. ' u, y( j8 w* q/ w' S5 I# V
unsigned short uiVal;  // VT_UI2. ; X( [7 K# ^& G. Y7 @( H6 O5 k  n
unsigned long ulVal;  // VT_UI4.
7 M  }$ O8 o4 b9 ~int intVal;  // VT_INT.
: h, {" T& k9 funsigned int uintVal;  // VT_UINT.
( d: M0 b  N  \6 b/ zchar FAR * pcVal;  // VT_BYREF|VT_I1.
, d: H) R% q7 C0 g9 e  Q0 j2 h6 |unsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. ! ^6 Q1 E8 i6 M# x5 u
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4. * t" r, T8 S" P" S9 n' |, c
int FAR * pintVal;  // VT_BYREF|VT_INT. ! [' U9 j; c  `3 M
unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
; ~# T' M; C# ^7 N' C( n2 _/ G, i0 {" x: j3 p
, A- n, a4 Y: a' K
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。; T5 Y+ A" `4 ?% ^/ j& p* a
使用时需加上#include <comdef.h>
% l- I: p# n. z" Z例如:7 _+ |: `; }3 {  ^* i" Z; N& _, V9 d
long l=222;6 Z0 y; g' m' W
ing i=100;. E7 Z# n" Q4 _0 c
_variant_t lVal(l);
% _3 Z- T1 J# ^, r6 S% j% H) u: LlVal = (long)i;
0 D- F' v: Q# h3 z3 w& w& o9 |3 t' x) {+ e( U% D7 P/ Z- Q

4 f' y# L/ J5 K7 H1 {' M% z- e+ w9 B  bCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:& r7 w6 U: z4 [+ d( r4 n, E! g
COleVariant v3 = "字符串", v4 = (long)1999;! ?% p( g9 b" ~
CString str =(BSTR)v3.pbstrVal;+ Q7 l5 `2 S* W) O1 \5 U% U: e, `5 e
long i = v4.lVal;
7 q4 F; P  ?6 V- S5 D
4 y" E5 ]' N0 o# R- g
, G6 x: b2 |( ]6 Q5 ]六、其它一些COM数据类型
: y9 G, }! I  W/ @
  l. }) T- g/ e. E; v2 C根据ProgID得到CLSID
- i3 H& C# N$ d- J/ `HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);! j) u- E% b$ O- l% x/ W, `
CLSID clsid;
8 d+ l0 \" X) J4 z3 j; WCLSIDFromProgID( L"MAPI.Folder",&clsid);
- ]) y& o: R- r& ~1 K
) F/ j3 @4 z: A( Z, M3 B+ f$ t- Q+ G根据CLSID得到ProgID+ N  a* e$ ^* ?
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
% x1 v  L* ]7 H5 i例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID! P2 q; Q$ R3 J' @* U# \3 ?
LPOLESTR pProgID = 0;
$ Y6 o6 G/ B+ t0 s: A8 UProgIDFromCLSID( CLSID_IApplication,&pProgID);
* {: S2 C' Q% u5 ], ?...///可以使用pProgID ( K: {" y: G. b" p$ _9 I
CoTaskMemFree(pProgID);//不要忘记释放
$ B: @- @( m6 Q, x6 c! }7 s0 A# W
七、ANSI与Unicode
6 l+ ^" {* E. x. F4 iUnicode称为宽字符型字串,COM里使用的都是Unicode字符串。- A1 c# N% C. r# D

* J$ \9 m; a6 v# j; I& ?将ANSI转换到Unicode( c1 ~/ w. I% v
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
1 l' N% _8 u# |" c. c3 P8 t6 E% }( F(2)通过MultiByteToWideChar函数实现转换,例如:
, U/ C5 E5 E" `. k" i) ichar *szProgID = "MAPI.Folder";0 A: u* }: g. r/ i, P- }
WCHAR szWideProgID[128];
5 x5 i9 `* `0 r  e% a! A! ^CLSID clsid;
3 c7 {( @/ Z3 elong lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));! F+ L% J4 G. F
szWideProgID[lLen] = '\0';
0 o1 O8 H2 ^/ T6 |+ b$ _(3)通过A2W宏来实现,例如: 9 }  p+ m; t9 F8 `2 {+ m1 |( b; t
USES_CONVERSION;
8 }; {( A$ D9 v- Y# ^CLSIDFromProgID( A2W(szProgID),&clsid); 0 @2 d; C) e6 v7 ~$ L& K% W
将Unicode转换到ANSI" r, S) T# p2 k  l
(1)使用WideCharToMultiByte,例如:3 {" ^& g, f5 t( U& J0 b! l
// 假设已经有了一个Unicode 串 wszSomeString...
! ^1 R7 G5 z; Wchar szANSIString [MAX_PATH]; 2 V8 b5 B- ~1 ~) y0 Y
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
8 V  k9 h7 |! {2 K(2)使用W2A宏来实现,例如:( m% b2 w- g0 `) ~& t" D( q
USES_CONVERSION;
$ Y4 v! R0 _. B8 ]6 K0 KpTemp=W2A(wszSomeString); ; h: D1 ]" F- m8 B; J6 ?
八、其它0 L; ?0 u' z- C+ J) v, F/ t7 @( k
8 k& t' J7 [4 R# g, n
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:3 {2 g9 {8 k" O/ u! V
LPARAM lParam;6 q* H: T. w; G5 ~8 O2 e
WORD loValue = LOWORD(lParam);///取低16位9 ?! x: j4 V7 P* z6 M6 v: L
WORD hiValue = HIWORD(lParam);///取高16位
  v* p4 s5 j4 ~$ a0 q7 F
/ z. B; O; d& f# @9 I: u5 e7 w  ~+ r$ u
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:' Y; Y+ r: Y  g7 V8 J
WORD wValue;! g, r) M* N+ `& y6 G2 w, K
BYTE loValue = LOBYTE(wValue);///取低8位
/ k$ e; F+ F# g1 q4 d  y/ ]  m1 kBYTE hiValue = HIBYTE(wValue);///取高8位
" c; |- Q& e: l2 B  I8 m- |
( Z1 ?$ W- ~, o/ L
9 F" q2 v; r$ {! Z/ D2 C6 `两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
/ R* {3 ]$ m) j' \8 [LONG MAKELONG( WORD wLow, WORD wHigh );1 b! k& s2 i6 I) D/ l; O
WPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); 1 ^9 S% ?- _) Z0 H( }
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );& E, P( |0 d: `  V& |7 k4 f
LRESULT MAKELRESULT( WORD wLow, WORD wHigh );
: {  K+ L% _1 _3 c( x
9 z5 `4 W( K9 f  U" }: D) T
2 s: N8 N+ n# A& `; ]/ O5 G; v两个8位的数据(BYTE)合成16位的数据(WORD)# s( h5 I2 P6 {: U; n' p
WORD MAKEWORD( BYTE bLow, BYTE bHigh );
- d3 }- q1 V0 n* ~" n7 l- G' [
$ E1 s3 j( s: j( {4 I/ t- J6 \. U+ B* c1 e6 s
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值" i2 {% n  ~5 S2 N! r  {
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
6 b0 J. Z: O0 ~例如COLORREF bkcolor = RGB(0x22,0x98,0x34);
- M2 O+ E1 p' v# [6 O. g* b. V5 t- w( d
; ?9 B: k: p4 J4 I
从COLORREF类型的颜色值得到RGB三个颜色值
/ ~8 e" D" X: j9 K/ ?BYTE Red = GetRValue(bkcolor); ///得到红颜色! I# c3 Q/ ^* x" ?4 ?/ H
BYTE Green = GetGValue(bkcolor); ///得到绿颜色
. M1 E. f- t5 A4 l5 R; VBYTE Blue = GetBValue(bkcolor); ///得到兰颜色6 f. q: |3 f: R( C
+ M: O* ]0 N, k* t, ^( W2 N' r$ e
九、注意事项
9 T6 l$ U! d, y5 E3 V: \4 _# A假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )/ G. [1 V- M7 U5 F4 Z- J

! R6 F& ~* Y% w1 |" B后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-4 16:50 , Processed in 0.023447 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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