1 // HwSMTP.cpp: implementation of the CHwSMTP class.
3 //////////////////////////////////////////////////////////////////////
9 #include "SpeedPostEmail.h"
15 static char THIS_FILE
[]=__FILE__
;
19 CPtrArray g_PtrAry_Threads
;
20 ::CCriticalSection m_CSFor__g_PtrAry_Threads
;
26 LPCTSTR lpszSmtpSrvHost
,
32 LPCTSTR lpszSenderName
,
33 LPCTSTR lpszReceiverName
,
37 CStringArray
*pStrAryAttach
,
38 CStringArray
*pStrAryCC
,
42 m_csSmtpSrvHost
= GET_SAFE_STRING(lpszSmtpSrvHost
);
43 m_csUserName
= GET_SAFE_STRING(lpszUserName
);
44 m_csPasswd
= GET_SAFE_STRING(lpszPasswd
);
45 m_bMustAuth
= bMustAuth
;
46 m_csAddrFrom
= GET_SAFE_STRING(lpszAddrFrom
);
47 m_csAddrTo
= GET_SAFE_STRING(lpszAddrTo
);
48 m_csSenderName
= GET_SAFE_STRING(lpszSenderName
);
49 m_csReceiverName
= GET_SAFE_STRING(lpszReceiverName
);
50 m_csSubject
= GET_SAFE_STRING(lpszSubject
);
51 m_csBody
= GET_SAFE_STRING(lpszBody
);
52 m_csCharSet
= GET_SAFE_STRING(lpszCharSet
);
54 m_StrAryAttach
.Append ( *pStrAryAttach
);
56 m_StrAryCC
.Append ( *pStrAryCC
);
57 m_nSmtpSrvPort
= nSmtpSrvPort
;
62 CString m_csSmtpSrvHost
;
68 CString m_csSenderName
;
69 CString m_csReceiverName
;
73 CStringArray m_StrAryAttach
;
74 CStringArray m_StrAryCC
;
80 //////////////////////////////////////////////////////////////////////
81 // Construction/Destruction
82 //////////////////////////////////////////////////////////////////////
85 m_bConnected ( FALSE
),
86 m_nSmtpSrvPort ( 25 ),
89 m_csMIMEContentType
= _T( "multipart/mixed");
90 m_csPartBoundary
= _T( "WC_MAIL_PaRt_BoUnDaRy_05151998" );
91 m_csNoMIMEText
= _T( "This is a multi-part message in MIME format." );
92 // m_csCharSet = _T("\r\n\tcharset=\"iso-8859-1\"\r\n");
99 BOOL
CHwSMTP::SendEmail (
100 LPCTSTR lpszSmtpSrvHost
,
101 LPCTSTR lpszUserName
,
104 LPCTSTR lpszAddrFrom
,
106 LPCTSTR lpszSenderName
,
107 LPCTSTR lpszReceiverName
,
110 LPCTSTR lpszCharSet
, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"
111 CStringArray
*pStrAryAttach
/*=NULL*/,
112 CStringArray
*pStrAryCC
/*=NULL*/,
113 UINT nSmtpSrvPort
/*=25*/
116 TRACE ( _T("·¢ËÍÓʼþ£º%s, %s, %s\n"), lpszAddrTo
, lpszReceiverName
, lpszBody
);
117 m_StrAryAttach
.RemoveAll();
118 m_StrAryCC
.RemoveAll();
119 m_csSmtpSrvHost
= GET_SAFE_STRING ( lpszSmtpSrvHost
);
120 if ( m_csSmtpSrvHost
.GetLength() <= 0 )
122 m_csLastError
.Format ( _T("Parameter Error!") );
125 m_csUserName
= GET_SAFE_STRING ( lpszUserName
);
126 m_csPasswd
= GET_SAFE_STRING ( lpszPasswd
);
127 m_bMustAuth
= bMustAuth
;
128 if ( m_bMustAuth
&& m_csUserName
.GetLength() <= 0 )
130 m_csLastError
.Format ( _T("Parameter Error!") );
134 m_csAddrFrom
= GET_SAFE_STRING ( lpszAddrFrom
);
135 m_csAddrTo
= GET_SAFE_STRING ( lpszAddrTo
);
136 m_csSenderName
= GET_SAFE_STRING ( lpszSenderName
);
137 m_csReceiverName
= GET_SAFE_STRING ( lpszReceiverName
);
138 m_csSubject
= GET_SAFE_STRING ( lpszSubject
);
139 m_csBody
= GET_SAFE_STRING ( lpszBody
);
140 m_nSmtpSrvPort
= nSmtpSrvPort
;
141 if ( lpszCharSet
&& lstrlen(lpszCharSet
) > 0 )
142 m_csCharSet
.Format ( _T("\r\n\tcharset=\"%s\"\r\n"), lpszCharSet
);
145 m_csAddrFrom
.GetLength() <= 0 || m_csAddrTo
.GetLength() <= 0 ||
146 m_csSenderName
.GetLength() <= 0 || m_csReceiverName
.GetLength() <= 0 ||
147 m_csSubject
.GetLength() <= 0 || m_csBody
.GetLength() <= 0
150 m_csLastError
.Format ( _T("Parameter Error!") );
156 m_StrAryAttach
.Append ( *pStrAryAttach
);
158 if ( m_StrAryAttach
.GetSize() < 1 )
159 m_csMIMEContentType
= _T( "text/plain");
163 m_StrAryCC
.Append ( *pStrAryCC
);
167 if ( !m_SendSock
.Create () )
169 m_csLastError
.Format ( _T("Create socket failed!") );
174 if ( !m_SendSock
.Connect ( m_csSmtpSrvHost
, m_nSmtpSrvPort
) )
176 m_csLastError
.Format ( _T("Connect to [ %s ] failed"), m_csSmtpSrvHost
);
177 TRACE ( _T("%d\n"), GetLastError() );
180 if ( !GetResponse( _T("220") ) ) return FALSE
;
188 BOOL
CHwSMTP::GetResponse ( LPCTSTR lpszVerifyCode
, int *pnCode
/*=NULL*/)
190 if ( !lpszVerifyCode
|| lstrlen(lpszVerifyCode
) < 1 )
193 char szRecvBuf
[1024] = {0};
195 char szStatusCode
[4] = {0};
196 nRet
= m_SendSock
.Receive ( szRecvBuf
, sizeof(szRecvBuf
) );
197 TRACE ( _T("Received : %s\r\n"), szRecvBuf
);
200 m_csLastError
.Format ( _T("Receive TCP data failed") );
203 // TRACE ( _T("ÊÕµ½·þÎñÆ÷»ØÓ¦£º%s\n"), szRecvBuf );
205 memcpy ( szStatusCode
, szRecvBuf
, 3 );
206 if ( pnCode
) (*pnCode
) = atoi ( szStatusCode
);
208 if ( strcmp ( szStatusCode
, CMultiByteString(lpszVerifyCode
).GetBuffer() ) != 0 )
210 m_csLastError
.Format ( _T("Received invalid response : %s"), GetCompatibleString(szRecvBuf
,FALSE
) );
217 // ÀûÓÃsocket·¢ËÍÊý¾Ý£¬Êý¾Ý³¤¶È²»Äܳ¬¹ý10M
218 BOOL
CHwSMTP::Send(LPCTSTR lpszData
, ... )
222 m_csLastError
.Format ( _T("Didn't connect") );
227 // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ
228 for ( int nBufCount
= 1024; nBufCount
<10*1024*1024; nBufCount
+= 1024 )
230 buf
= new TCHAR
[nBufCount
];
233 ::AfxThrowMemoryException ();
236 memset ( buf
, 0, nBufCount
*sizeof(TCHAR
) );
239 va_start (va
, lpszData
);
240 int nLen
= _vsnprintf_hw ((TCHAR
*)buf
, nBufCount
-sizeof(TCHAR
), lpszData
, va
);
242 if ( nLen
<= (int)(nBufCount
-sizeof(TCHAR
)) )
244 delete[] buf
; buf
= NULL
;
248 m_csLastError
.Format ( _T("Memory too small or data too big.") );
252 CMultiByteString
cbsData ( buf
);
253 delete[] buf
; buf
= NULL
;
254 TRACE ( _T("Send : %s\r\n"), cbsData
.GetBuffer() );
255 if ( m_SendSock
.Send ( cbsData
.GetBuffer(), cbsData
.GetLength() ) != cbsData
.GetLength() )
257 m_csLastError
.Format ( _T("Socket send data failed") );
264 BOOL
CHwSMTP::SendEmail()
267 char szLocalHostName
[64] = {0};
268 gethostname ( (char*)szLocalHostName
, sizeof(szLocalHostName
) );
271 if ( !Send ( _T("HELO %s\r\n"), GetCompatibleString(szLocalHostName
,FALSE
) ) )
275 if ( !GetResponse ( _T("250") ) )
280 if ( m_bMustAuth
&& !auth() )
290 if ( !SendSubject() )
305 if ( !Send ( _T(".\r\n") ) ) return FALSE
;
306 if ( !GetResponse ( _T("250") ) )
310 if ( HANDLE_IS_VALID(m_SendSock
.m_hSocket
) )
311 Send ( _T("QUIT\r\n") );
312 m_bConnected
= FALSE
;
319 int nResponseCode
= 0;
320 if ( !Send ( _T("auth login\r\n") ) ) return FALSE
;
321 if ( !GetResponse ( _T("334"), &nResponseCode
) ) return FALSE
;
322 if ( nResponseCode
!= 334 ) // ²»ÐèÒªÑéÖ¤Óû§ÃûºÍÃÜÂë
325 CBase64 Base64Encode
;
326 CMultiByteString
cbsUserName ( m_csUserName
), cbsPasswd ( m_csPasswd
);
327 CString csBase64_UserName
= GetCompatibleString ( Base64Encode
.Encode ( cbsUserName
.GetBuffer(), cbsUserName
.GetLength() ).GetBuffer(0), FALSE
);
328 CString csBase64_Passwd
= GetCompatibleString ( Base64Encode
.Encode ( cbsPasswd
.GetBuffer(), cbsPasswd
.GetLength() ).GetBuffer(0), FALSE
);
330 if ( !Send ( _T("%s\r\n"), csBase64_UserName
) ) return FALSE
;
331 if ( !GetResponse ( _T("334") ) )
333 m_csLastError
.Format ( _T("Authentication UserName failed") );
337 if ( !Send ( _T("%s\r\n"), csBase64_Passwd
) ) return FALSE
;
338 if ( !GetResponse ( _T("235") ) )
340 m_csLastError
.Format ( _T("Authentication Password failed") );
347 BOOL
CHwSMTP::SendHead()
349 if ( !Send ( _T("MAIL From: <%s>\r\n"), m_csAddrFrom
) ) return FALSE
;
350 if ( !GetResponse ( _T("250") ) ) return FALSE
;
351 if ( !Send ( _T("RCPT TO: <%s>\r\n"), m_csAddrTo
) ) return FALSE
;
352 if ( !GetResponse ( _T("250") ) ) return FALSE
;
354 for ( int i
=0; i
<m_StrAryCC
.GetSize(); i
++ )
356 if ( !Send ( _T("RCPT TO: <%s>\r\n"), m_StrAryCC
.GetAt(i
) ) ) return FALSE
;
357 if ( !GetResponse ( _T("250") ) ) return FALSE
;
359 if ( !Send ( _T("DATA\r\n") ) ) return FALSE
;
360 if ( !GetResponse ( _T("354") ) ) return FALSE
;
365 BOOL
CHwSMTP::SendSubject()
368 csSubject
+= _T("Date: ");
369 COleDateTime tNow
= COleDateTime::GetCurrentTime();
372 csSubject
+= GetCompatibleString(FormatDateTime (tNow
, _T("%a, %d %b %y %H:%M:%S %Z")).GetBuffer(0),FALSE
);
374 csSubject
+= _T("\r\n");
375 csSubject
+= FormatString ( _T("From: %s\r\nTo: %s\r\n"), m_csSenderName
, m_csReceiverName
);
376 csSubject
+= FormatString ( _T("Subject: %s\r\n"), m_csSubject
);
377 csSubject
+= FormatString ( _T("X-Mailer: chrys\r\nMIME-Version: 1.0\r\nContent-Type: %s; %s boundary=%s\r\n\r\n") ,
378 m_csMIMEContentType
, m_csCharSet
, m_csPartBoundary
);
380 return Send ( csSubject
);
383 BOOL
CHwSMTP::SendBody()
385 CString csBody
, csTemp
;
387 if ( m_StrAryAttach
.GetSize() > 0 )
389 csTemp
.Format ( _T("%s\r\n\r\n"), m_csNoMIMEText
);
392 csTemp
.Format ( _T("--%s\r\n"), m_csPartBoundary
);
395 csTemp
.Format ( _T("Content-Type: text/plain\r\n%sContent-Transfer-Encoding: 7Bit\r\n\r\n"),
400 csTemp
.Format ( _T("%s\r\n"), m_csBody
);
403 if ( m_StrAryAttach
.GetSize() > 0 )
405 csTemp
.Format ( _T("--%s\r\n"), m_csPartBoundary
);
409 return Send ( csBody
);
412 BOOL
CHwSMTP::SendAttach()
414 int nCountAttach
= (int)m_StrAryAttach
.GetSize();
415 if ( nCountAttach
< 1 ) return TRUE
;
417 for ( int i
=0; i
<nCountAttach
; i
++ )
419 if ( !SendOnAttach ( m_StrAryAttach
.GetAt(i
) ) )
426 BOOL
CHwSMTP::SendOnAttach(LPCTSTR lpszFileName
)
428 ASSERT ( lpszFileName
);
429 CString csAttach
, csTemp
;
431 csTemp
= lpszFileName
;
432 CString csShortFileName
= csTemp
.GetBuffer(0) + csTemp
.ReverseFind ( '\\' );
433 csShortFileName
.TrimLeft ( _T("\\") );
435 csTemp
.Format ( _T("Content-Type: application/octet-stream; file=%s\r\n"), csShortFileName
);
438 csTemp
.Format ( _T("Content-Transfer-Encoding: base64\r\n") );
441 csTemp
.Format ( _T("Content-Disposition: attachment; filename=%s\r\n\r\n"), csShortFileName
);
444 DWORD dwFileSize
= hwGetFileAttr(lpszFileName
);
445 if ( dwFileSize
> 5*1024*1024 )
447 m_csLastError
.Format ( _T("File [%s] too big. File size is : %s"), lpszFileName
, FormatBytes(dwFileSize
) );
450 char *pBuf
= new char[dwFileSize
+1];
453 ::AfxThrowMemoryException ();
460 if ( !file
.Open ( lpszFileName
, CFile::modeRead
) )
462 m_csLastError
.Format ( _T("Open file [%s] failed"), lpszFileName
);
465 UINT nFileLen
= file
.Read ( pBuf
, dwFileSize
);
466 CBase64 Base64Encode
;
467 csTemp
= Base64Encode
.Encode ( pBuf
, nFileLen
);
469 csAttach
+= _T("\r\n\r\n");
471 catch ( CFileException e
)
474 m_csLastError
.Format ( _T("Read file [%s] failed"), lpszFileName
);
479 csTemp
.Format ( _T("--%s\r\n"), m_csPartBoundary
);
484 return Send ( csAttach
);
487 CString
CHwSMTP::GetLastErrorText()
489 return m_csLastError
;
493 DWORD WINAPI
ThreadProc_SendEmail( LPVOID lpParameter
)
495 CEMailObject
*pEMailObject
= (CEMailObject
*)lpParameter
;
496 ASSERT ( pEMailObject
);
499 BOOL bRet
= HwSMTP
.SendEmail (
500 pEMailObject
->m_csSmtpSrvHost
,
501 pEMailObject
->m_csUserName
,
502 pEMailObject
->m_csPasswd
,
503 pEMailObject
->m_bMustAuth
,
504 pEMailObject
->m_csAddrFrom
,
505 pEMailObject
->m_csAddrTo
,
506 pEMailObject
->m_csSenderName
,
507 pEMailObject
->m_csReceiverName
,
508 pEMailObject
->m_csSubject
,
509 pEMailObject
->m_csBody
,
510 pEMailObject
->m_csCharSet
,
511 &pEMailObject
->m_StrAryAttach
,
512 &pEMailObject
->m_StrAryCC
,
513 pEMailObject
->m_nSmtpSrvPort
518 CString csError
= HwSMTP
.GetLastErrorText ();
519 csError
= FormatString ( _T("Send a email to [%s] failed."), pEMailObject
->m_csSmtpSrvHost
);
520 AfxMessageBox ( csError
);
524 m_CSFor__g_PtrAry_Threads
.Lock ();
525 int nFindPos
= FindFromArray ( g_PtrAry_Threads
, pEMailObject
->m_hThread
);
527 g_PtrAry_Threads
.RemoveAt ( nFindPos
);
528 m_CSFor__g_PtrAry_Threads
.Unlock ();
535 // Óà SMTP ·þÎñ·¢Ë͵ç×ÓÓʼþ£¬Èç¹ûÉèÖòÎÊý bViaThreadSend=TRUE£¬ÄÇÔÚ³ÌÐò½áÊøʱӦ¸ÃÔÚ ExitInstance() Öе÷Óà EndOfSMTP() º¯Êý
539 LPCTSTR lpszSmtpSrvHost
,
540 LPCTSTR lpszUserName
,
543 LPCTSTR lpszAddrFrom
,
545 LPCTSTR lpszSenderName
,
546 LPCTSTR lpszReceiverName
,
549 LPCTSTR lpszCharSet
/*=NULL*/,
550 CStringArray
*pStrAryAttach
/*=NULL*/,
551 CStringArray
*pStrAryCC
/*=NULL*/,
552 UINT nSmtpSrvPort
/*=25*/
555 if ( !lpszSmtpSrvHost
|| lstrlen(lpszSmtpSrvHost
) < 1 ||
556 !lpszSubject
|| lstrlen(lpszSubject
) < 1 ||
557 !lpszBody
|| lstrlen(lpszBody
) < 1 )
559 AfxMessageBox ( _T("Parameter error !") );
563 CEMailObject
*pEMailObject
= new CEMailObject (
579 if ( !pEMailObject
) return FALSE
;
582 if ( bViaThreadSend
)
584 DWORD dwThreadId
= 0;
585 pEMailObject
->m_hThread
= ::CreateThread ( NULL
, 0, ::ThreadProc_SendEmail
, pEMailObject
, CREATE_SUSPENDED
, &dwThreadId
);
586 bRet
= HANDLE_IS_VALID(pEMailObject
->m_hThread
);
587 m_CSFor__g_PtrAry_Threads
.Lock();
588 g_PtrAry_Threads
.Add ( pEMailObject
->m_hThread
);
589 m_CSFor__g_PtrAry_Threads
.Unlock();
590 ResumeThread ( pEMailObject
->m_hThread
);
594 bRet
= (BOOL
)ThreadProc_SendEmail ( pEMailObject
);
602 // µÈ´ýËùÓÐÏß³ÌÖ´ÐÐÍê±Ï
603 for ( int i
=0; i
<g_PtrAry_Threads
.GetSize(); i
++ )
605 HANDLE hThread
= (HANDLE
)g_PtrAry_Threads
.GetAt(i
);
606 if ( HANDLE_IS_VALID(hThread
) )
608 WaitForThreadEnd ( &hThread
, 30*1000 );
611 g_PtrAry_Threads
.RemoveAll ();
616 // ½«×Ö·û´® lpszOrg ת»»Îª¶à×Ö½ÚµÄ×Ö·û´®£¬Èç¹û»¹ÒªÊ¹Óöà×Ö·û´®µÄ³¤¶È£¬¿ÉÒÔÓÃÒÔÏ·½Ê½À´Ê¹ÓÃÕâ¸öÀࣺ
617 // CMultiByteString MultiByteString(_T("UNICODE×Ö·û´®"));
618 // printf ( "ANSI ×Ö·û´®Îª£º %s£¬ ×Ö·û¸öÊýΪ£º %d £¬ ³¤¶ÈΪ£º %d×Ö½Ú\n", MultiByteString.GetBuffer(), MultiByteString.GetLength(), MultiByteString.GetSize() );
620 CMultiByteString::CMultiByteString( LPCTSTR lpszOrg
, int nOrgStringEncodeType
/*=STRING_IS_SOFTCODE*/, OUT
char *pOutBuf
/*=NULL*/, int nOutBufSize
/*=0*/ )
622 m_bNewBuffer
= FALSE
;
625 m_nCharactersNumber
= 0;
626 if ( !lpszOrg
) return;
628 // ÅжÏÔʼ×Ö·û´®µÄ±àÂ뷽ʽ
629 BOOL bOrgIsUnicode
= FALSE
;
630 if ( nOrgStringEncodeType
== STRING_IS_MULTICHARS
) bOrgIsUnicode
= FALSE
;
631 else if ( nOrgStringEncodeType
== STRING_IS_UNICODE
) bOrgIsUnicode
= TRUE
;
635 bOrgIsUnicode
= TRUE
;
637 bOrgIsUnicode
= FALSE
;
641 // ¼ÆËã×Ö·û´®¸öÊýºÍÐèÒªµÄÄ¿±ê»º³å´óС
644 m_nCharactersNumber
= (int)wcslen((WCHAR
*)lpszOrg
);
645 m_nDataSize
= (m_nCharactersNumber
+ 1) * sizeof(WCHAR
);
649 m_nCharactersNumber
= (int)strlen((char*)lpszOrg
);
650 m_nDataSize
= (m_nCharactersNumber
+ 1) * sizeof(char);
653 // ʹÓõ÷ÓÃÕß´«ÈëµÄ»º³å
654 if ( pOutBuf
&& nOutBufSize
> 0 )
657 m_nDataSize
= nOutBufSize
;
662 m_pszData
= (char*)new BYTE
[m_nDataSize
];
665 ::AfxThrowMemoryException ();
670 memset ( m_pszData
, 0, m_nDataSize
);
674 m_nCharactersNumber
= WideCharToMultiByte ( CP_ACP
, 0, (LPCWSTR
)lpszOrg
, m_nCharactersNumber
, (LPSTR
)m_pszData
, m_nDataSize
/sizeof(char)-1, NULL
, NULL
);
675 if ( m_nCharactersNumber
< 1 ) m_nCharactersNumber
= (int)strlen ( m_pszData
);
679 m_nCharactersNumber
= __min ( m_nCharactersNumber
, (int)(m_nDataSize
/sizeof(char)-1) );
680 strncpy ( m_pszData
, (const char*)lpszOrg
, m_nCharactersNumber
);
681 m_nCharactersNumber
= (int)strlen ( m_pszData
);
683 m_nDataSize
= ( m_nCharactersNumber
+ 1 ) * sizeof(char);
686 CMultiByteString::~CMultiByteString ()
688 if ( m_bNewBuffer
&& m_pszData
)
695 // ½« lpszOrg ת»»Îª¸Ã³ÌÐòʹÓõıàÂë×Ö·û´®£¬Èç¹û¸Ã³ÌÐòÊÇ UNICODE ¾ÍתΪ UNICODE£¬Èç¹ûÊÇ ANSI ¾ÍתΪ ANSI µÄ
697 CString
GetCompatibleString ( LPVOID lpszOrg
, BOOL bOrgIsUnicode
, int nOrgLength
/*=-1*/ )
699 if ( !lpszOrg
) return _T("");
706 if ( nOrgLength
> 0 )
708 WCHAR
*szRet
= new WCHAR
[nOrgLength
+1];
709 if ( !szRet
) return _T("");
710 memset ( szRet
, 0, (nOrgLength
+1)*sizeof(WCHAR
) );
711 memcpy ( szRet
, lpszOrg
, nOrgLength
*sizeof(WCHAR
) );
712 CString csRet
= szRet
;
716 else if ( nOrgLength
== 0 )
719 return (LPCTSTR
)lpszOrg
;
722 if ( nOrgLength
< 0 )
723 nOrgLength
= (int)strlen((const char*)lpszOrg
);
724 int nWideCount
= nOrgLength
+ 1;
725 WCHAR
*wchar
= new WCHAR
[nWideCount
];
726 if ( !wchar
) return _T("");
727 memset ( wchar
, 0, nWideCount
*sizeof(WCHAR
) );
728 ::MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)lpszOrg
, nOrgLength
, wchar
, nWideCount
);
729 CString csRet
= wchar
;
733 if ( !bOrgIsUnicode
)
735 if ( nOrgLength
> 0 )
737 char *szRet
= new char[nOrgLength
+1];
738 if ( !szRet
) return _T("");
739 memset ( szRet
, 0, (nOrgLength
+1)*sizeof(char) );
740 memcpy ( szRet
, lpszOrg
, nOrgLength
*sizeof(char) );
741 CString csRet
= szRet
;
745 else if ( nOrgLength
== 0 )
748 return (LPCTSTR
)lpszOrg
;
751 if ( nOrgLength
< 0 )
752 nOrgLength
= (int)wcslen((WCHAR
*)lpszOrg
);
753 int nMultiByteCount
= nOrgLength
+ 1;
754 char *szMultiByte
= new char[nMultiByteCount
];
755 if ( !szMultiByte
) return _T("");
756 memset ( szMultiByte
, 0, nMultiByteCount
*sizeof(char) );
757 ::WideCharToMultiByte ( CP_ACP
, 0, (LPCWSTR
)lpszOrg
, nOrgLength
, (LPSTR
)szMultiByte
, nMultiByteCount
, NULL
, NULL
);
758 CString csRet
= szMultiByte
;
759 delete[] szMultiByte
;
772 CString
FormatDateTime ( COleDateTime
&DateTime
, LPCTSTR pFormat
)
774 // If null, return empty string
775 if ( DateTime
.GetStatus() == COleDateTime::null
|| DateTime
.GetStatus() == COleDateTime::invalid
)
779 if (S_OK
!= VarUdateFromDate(DateTime
.m_dt
, 0, &ud
))
785 tmTemp
.tm_sec
= ud
.st
.wSecond
;
786 tmTemp
.tm_min
= ud
.st
.wMinute
;
787 tmTemp
.tm_hour
= ud
.st
.wHour
;
788 tmTemp
.tm_mday
= ud
.st
.wDay
;
789 tmTemp
.tm_mon
= ud
.st
.wMonth
- 1;
790 tmTemp
.tm_year
= ud
.st
.wYear
- 1900;
791 tmTemp
.tm_wday
= ud
.st
.wDayOfWeek
;
792 tmTemp
.tm_yday
= ud
.wDayOfYear
- 1;
796 LPTSTR lpszTemp
= strDate
.GetBufferSetLength(256);
797 _tcsftime(lpszTemp
, strDate
.GetLength(), pFormat
, &tmTemp
);
798 strDate
.ReleaseBuffer();
803 CString
FormatString ( LPCTSTR lpszStr
, ... )
806 // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ
807 for ( int nBufCount
= 1024; nBufCount
<5*1024*1024; nBufCount
+= 1024 )
809 buf
= new TCHAR
[nBufCount
];
812 ::AfxThrowMemoryException ();
815 memset ( buf
, 0, nBufCount
*sizeof(TCHAR
) );
818 va_start (va
, lpszStr
);
819 int nLen
= _vsnprintf_hw ((TCHAR
*)buf
, nBufCount
-sizeof(TCHAR
), lpszStr
, va
);
821 if ( nLen
<= (int)(nBufCount
-sizeof(TCHAR
)) )
823 delete[] buf
; buf
= NULL
;
831 delete[] buf
; buf
= NULL
;
835 /********************************************************************************
836 * Function Type : Global
837 * Parameter : lpFileName - Îļþ·¾¶
838 * Return Value : -1 - ʧ°Ü
840 * Description : »ñÈ¡ÎļþÊôÐÔ ( Îļþ´óС¡¢´´½¨Ê±¼ä )
841 *********************************************************************************/
842 int hwGetFileAttr ( LPCTSTR lpFileName
, OUT CFileStatus
*pFileStatus
/*=NULL*/ )
844 if ( !lpFileName
|| lstrlen(lpFileName
) < 1 ) return -1;
846 CFileStatus fileStatus
;
847 fileStatus
.m_attribute
= 0;
848 fileStatus
.m_size
= 0;
849 memset ( fileStatus
.m_szFullName
, 0, sizeof(fileStatus
.m_szFullName
) );
853 if ( CFile::GetStatus(lpFileName
,fileStatus
) )
858 CATCH (CFileException
, e
)
872 pFileStatus
->m_ctime
= fileStatus
.m_ctime
;
873 pFileStatus
->m_mtime
= fileStatus
.m_mtime
;
874 pFileStatus
->m_atime
= fileStatus
.m_atime
;
875 pFileStatus
->m_size
= fileStatus
.m_size
;
876 pFileStatus
->m_attribute
= fileStatus
.m_attribute
;
877 pFileStatus
->_m_padding
= fileStatus
._m_padding
;
878 lstrcpy ( pFileStatus
->m_szFullName
, fileStatus
.m_szFullName
);
882 return (int)fileStatus
.m_size
;
886 // ½«Ò»¸ö±íʾ×Ö½ÚµÄÊýÓÿɶÁÐԺõÄ×Ö·û´®À´±íʾ£¬ÀýÈ罫 12345678 ×Ö½Úת»»Îª£º
888 // nFlag - 0 : ×Ô¶¯Æ¥Å䵥λ
893 CString
FormatBytes ( double fBytesNum
, BOOL bShowUnit
/*=TRUE*/, int nFlag
/*=0*/ )
898 if ( fBytesNum
>= 1024.0 && fBytesNum
< 1024.0*1024.0 )
899 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ 1024.0, bShowUnit
?_T(" K"):_T("") );
900 else if ( fBytesNum
>= 1024.0*1024.0 && fBytesNum
< 1024.0*1024.0*1024.0 )
901 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0), bShowUnit
?_T(" M"):_T("") );
902 else if ( fBytesNum
>= 1024.0*1024.0*1024.0 )
903 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0*1024.0), bShowUnit
?_T(" G"):_T("") );
905 csRes
.Format ( _T("%.2f%s"), fBytesNum
, bShowUnit
?_T(" B"):_T("") );
907 else if ( nFlag
== 1 )
909 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ 1024.0, bShowUnit
?_T(" K"):_T("") );
911 else if ( nFlag
== 2 )
913 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0), bShowUnit
?_T(" M"):_T("") );
915 else if ( nFlag
== 3 )
917 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0*1024.0), bShowUnit
?_T(" G"):_T("") );
926 BOOL
WaitForThreadEnd ( HANDLE
*phThread
, DWORD dwWaitTime
/*=10*1000*/ )
930 if ( !(*phThread
) ) return TRUE
;
931 if ( ::WaitForSingleObject ( *phThread
, dwWaitTime
) == WAIT_TIMEOUT
)
934 ::TerminateThread ( *phThread
, 0 );
936 ::CloseHandle ( *phThread
);