multconv.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:12k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // convert.cpp : implementation file
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "wordpad.h"
  22. #include "multconv.h"
  23. #include "mswd6_32.h"
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char BASED_CODE THIS_FILE[] = __FILE__;
  27. #endif
  28. #ifdef CONVERTERS
  29. CConverter* CConverter::m_pThis = NULL;
  30. #endif
  31. #define BUFFSIZE 4096
  32. CTrackFile::CTrackFile(CFrameWnd* pWnd) : CFile()
  33. {
  34. m_nLastPercent = -1;
  35. m_dwLength = 0;
  36. m_pFrameWnd = pWnd;
  37. VERIFY(m_strComplete.LoadString(IDS_COMPLETE));
  38. VERIFY(m_strWait.LoadString(IDS_PLEASE_WAIT));
  39. VERIFY(m_strSaving.LoadString(IDS_SAVING));
  40. //  OutputPercent(0);
  41. }
  42. CTrackFile::~CTrackFile()
  43. {
  44. OutputPercent(100);
  45. if (m_pFrameWnd != NULL)
  46. m_pFrameWnd->SetMessageText(AFX_IDS_IDLEMESSAGE);
  47. }
  48. UINT CTrackFile::Read(void FAR* lpBuf, UINT nCount)
  49. {
  50. UINT n = CFile::Read(lpBuf, nCount);
  51. if (m_dwLength != 0)
  52. OutputPercent((int)((GetPosition()*100)/m_dwLength));
  53. return n;
  54. }
  55. void CTrackFile::Write(const void FAR* lpBuf, UINT nCount)
  56. {
  57. CFile::Write(lpBuf, nCount);
  58. OutputString(m_strSaving);
  59. //  if (m_dwLength != 0)
  60. //      OutputPercent((int)((GetPosition()*100)/m_dwLength));
  61. }
  62. void CTrackFile::OutputString(LPCTSTR lpsz)
  63. {
  64. if (m_pFrameWnd != NULL)
  65. {
  66. m_pFrameWnd->SetMessageText(lpsz);
  67. CWnd* pBarWnd = m_pFrameWnd->GetMessageBar();
  68. if (pBarWnd != NULL)
  69. pBarWnd->UpdateWindow();
  70. }
  71. }
  72. void CTrackFile::OutputPercent(int nPercentComplete)
  73. {
  74. if (m_pFrameWnd != NULL && m_nLastPercent != nPercentComplete)
  75. {
  76. m_nLastPercent = nPercentComplete;
  77. TCHAR buf[64];
  78. int n = nPercentComplete;
  79. wsprintf(buf, (n==100) ? m_strWait : m_strComplete, n);
  80. OutputString(buf);
  81. }
  82. }
  83. COEMFile::COEMFile(CFrameWnd* pWnd) : CTrackFile(pWnd)
  84. {
  85. }
  86. UINT COEMFile::Read(void FAR* lpBuf, UINT nCount)
  87. {
  88. UINT n = CTrackFile::Read(lpBuf, nCount);
  89. OemToCharBuffA((const char*)lpBuf, (char*)lpBuf, n);
  90. return n;
  91. }
  92. void COEMFile::Write(const void FAR* lpBuf, UINT nCount)
  93. {
  94. CharToOemBuffA((const char*)lpBuf, (char*)lpBuf, nCount);
  95. CTrackFile::Write(lpBuf, nCount);
  96. }
  97. #ifdef CONVERTERS
  98. HGLOBAL CConverter::StringToHGLOBAL(LPCSTR pstr)
  99. {
  100. HGLOBAL hMem = NULL;
  101. if (pstr != NULL)
  102. {
  103. hMem = GlobalAlloc(GHND, (lstrlenA(pstr)*2)+1);
  104. char* p = (char*) GlobalLock(hMem);
  105. ASSERT(p != NULL);
  106. if (p != NULL)
  107. lstrcpyA(p, pstr);
  108. GlobalUnlock(hMem);
  109. }
  110. return hMem;
  111. }
  112. CConverter::CConverter(LPCSTR pszLibName, CFrameWnd* pWnd) : CTrackFile(pWnd)
  113. {
  114. m_pInitConverter = NULL;
  115. m_pIsFormatCorrect = NULL;
  116. m_pForeignToRtf = NULL;
  117. m_pRtfToForeign = NULL;
  118. USES_CONVERSION;
  119. m_hBuff = NULL;
  120. m_pBuf = NULL;
  121. m_nBytesAvail = 0;
  122. m_nBytesWritten = 0;
  123. m_nPercent = 0;
  124. m_hEventFile = NULL;
  125. m_hEventConv = NULL;
  126. m_bDone = TRUE;
  127. m_bConvErr = FALSE;
  128. m_hFileName = NULL;
  129. OFSTRUCT ofs;
  130. if (OpenFile(pszLibName, &ofs, OF_EXIST) == HFILE_ERROR)
  131. {
  132. m_hLibCnv = NULL;
  133. return;
  134. }
  135. m_hLibCnv = LoadLibraryA(pszLibName);
  136. if (m_hLibCnv < (HINSTANCE)HINSTANCE_ERROR)
  137. m_hLibCnv = NULL;
  138. else
  139. {
  140. LoadFunctions();
  141. ASSERT(m_pInitConverter != NULL);
  142. if (m_pInitConverter != NULL)
  143. {
  144. CString str = AfxGetAppName();
  145. str.MakeUpper();
  146. VERIFY(m_pInitConverter(AfxGetMainWnd()->GetSafeHwnd(), T2CA(str)));
  147. }
  148. }
  149. }
  150. CConverter::CConverter(CFrameWnd* pWnd) : CTrackFile(pWnd)
  151. {
  152. m_pInitConverter = NULL;
  153. m_pIsFormatCorrect = NULL;
  154. m_pForeignToRtf = NULL;
  155. m_pRtfToForeign = NULL;
  156. m_bConvErr = FALSE;
  157. m_hFileName = NULL;
  158. }
  159. CConverter::~CConverter()
  160. {
  161. if (!m_bDone) // converter thread hasn't exited
  162. {
  163. WaitForConverter();
  164. m_nBytesAvail = 0;
  165. VERIFY(ResetEvent(m_hEventFile));
  166. m_nBytesAvail = 0;
  167. SetEvent(m_hEventConv);
  168. WaitForConverter();// wait for DoConversion exit
  169. VERIFY(ResetEvent(m_hEventFile));
  170. }
  171. if (m_hEventFile != NULL)
  172. VERIFY(CloseHandle(m_hEventFile));
  173. if (m_hEventConv != NULL)
  174. VERIFY(CloseHandle(m_hEventConv));
  175. if (m_hLibCnv != NULL)
  176. FreeLibrary(m_hLibCnv);
  177. if (m_hFileName != NULL)
  178. GlobalFree(m_hFileName);
  179. }
  180. void CConverter::WaitForConverter()
  181. {
  182. // while event not signalled -- process messages
  183. while (MsgWaitForMultipleObjects(1, &m_hEventFile, FALSE, INFINITE,
  184. QS_SENDMESSAGE) != WAIT_OBJECT_0)
  185. {
  186. MSG msg;
  187. PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
  188. }
  189. }
  190. void CConverter::WaitForBuffer()
  191. {
  192. // while event not signalled -- process messages
  193. while (MsgWaitForMultipleObjects(1, &m_hEventConv, FALSE, INFINITE,
  194. QS_SENDMESSAGE) != WAIT_OBJECT_0)
  195. {
  196. MSG msg;
  197. PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
  198. }
  199. }
  200. UINT AFX_CDECL CConverter::ConverterThread(LPVOID)
  201. {
  202. ASSERT(m_pThis != NULL);
  203. HRESULT hRes = OleInitialize(NULL);
  204. ASSERT(hRes == S_OK || hRes == S_FALSE);
  205. m_pThis->DoConversion();
  206. OleUninitialize();
  207. return 0;
  208. }
  209. BOOL CConverter::IsFormatCorrect(LPCTSTR pszFileName)
  210. {
  211. USES_CONVERSION;
  212. int nRet;
  213. if (m_hLibCnv == NULL || m_pIsFormatCorrect == NULL)
  214. return FALSE;
  215. char buf[_MAX_PATH];
  216. #if (_MSC_VER > 1310) // VS2005
  217. strcpy_s(buf, _MAX_PATH, T2CA(pszFileName));
  218. #else
  219. strcpy(buf, T2CA(pszFileName));
  220. #endif
  221. CharToOemA(buf, buf);
  222. HGLOBAL hFileName = StringToHGLOBAL(buf);
  223. HGLOBAL hDesc = GlobalAlloc(GHND, 256);
  224. ASSERT(hDesc != NULL);
  225. nRet = m_pIsFormatCorrect(hFileName, hDesc);
  226. GlobalFree(hDesc);
  227. GlobalFree(hFileName);
  228. return (nRet == 1) ? TRUE : FALSE;
  229. }
  230. // static callback function
  231. int CALLBACK CConverter::WriteOutStatic(int cch, int nPercentComplete)
  232. {
  233. ASSERT(m_pThis != NULL);
  234. return m_pThis->WriteOut(cch, nPercentComplete);
  235. }
  236. int CALLBACK CConverter::WriteOut(int cch, int nPercentComplete)
  237. {
  238. ASSERT(m_hBuff != NULL);
  239. m_nPercent = nPercentComplete;
  240. if (m_hBuff == NULL)
  241. return -9;
  242. if (cch != 0)
  243. {
  244. WaitForBuffer();
  245. VERIFY(ResetEvent(m_hEventConv));
  246. m_nBytesAvail = cch;
  247. SetEvent(m_hEventFile);
  248. WaitForBuffer();
  249. }
  250. return 0; //everything OK
  251. }
  252. int CALLBACK CConverter::ReadInStatic(int /*flags*/, int nPercentComplete)
  253. {
  254. ASSERT(m_pThis != NULL);
  255. return m_pThis->ReadIn(nPercentComplete);
  256. }
  257. int CALLBACK CConverter::ReadIn(int /*nPercentComplete*/)
  258. {
  259. ASSERT(m_hBuff != NULL);
  260. if (m_hBuff == NULL)
  261. return -8;
  262. SetEvent(m_hEventFile);
  263. WaitForBuffer();
  264. VERIFY(ResetEvent(m_hEventConv));
  265. return m_nBytesAvail;
  266. }
  267. BOOL CConverter::DoConversion()
  268. {
  269. USES_CONVERSION;
  270. m_nLastPercent = -1;
  271. //  m_dwLength = 0; // prevent Read/Write from displaying
  272. m_nPercent = 0;
  273. ASSERT(m_hBuff != NULL);
  274. ASSERT(m_pThis != NULL);
  275. HGLOBAL hDesc = StringToHGLOBAL("");
  276. HGLOBAL hSubset = StringToHGLOBAL("");
  277. int nRet = 0;
  278. if (m_bForeignToRtf)
  279. {
  280. ASSERT(m_pForeignToRtf != NULL);
  281. ASSERT(m_hFileName != NULL);
  282. nRet = m_pForeignToRtf(m_hFileName, NULL, m_hBuff, hDesc, hSubset,
  283. (LPFNOUT)WriteOutStatic);
  284. // wait for next CConverter::Read to come through
  285. WaitForBuffer();
  286. VERIFY(ResetEvent(m_hEventConv));
  287. }
  288. else if (!m_bForeignToRtf)
  289. {
  290. ASSERT(m_pRtfToForeign != NULL);
  291. ASSERT(m_hFileName != NULL);
  292. nRet = m_pRtfToForeign(m_hFileName, NULL, m_hBuff, hDesc,
  293. (LPFNIN)ReadInStatic);
  294. // don't need to wait for m_hEventConv
  295. }
  296. GlobalFree(hDesc);
  297. GlobalFree(hSubset);
  298. if (m_pBuf != NULL)
  299. GlobalUnlock(m_hBuff);
  300. GlobalFree(m_hBuff);
  301. if (nRet != 0)
  302. m_bConvErr = TRUE;
  303. m_bDone = TRUE;
  304. m_nPercent = 100;
  305. m_nLastPercent = -1;
  306. SetEvent(m_hEventFile);
  307. return (nRet == 0);
  308. }
  309. void CConverter::LoadFunctions()
  310. {
  311. m_pInitConverter = (PINITCONVERTER)GetProcAddress(m_hLibCnv, "InitConverter32");
  312. m_pIsFormatCorrect = (PISFORMATCORRECT)GetProcAddress(m_hLibCnv, "IsFormatCorrect32");
  313. m_pForeignToRtf = (PFOREIGNTORTF)GetProcAddress(m_hLibCnv, "ForeignToRtf32");
  314. m_pRtfToForeign = (PRTFTOFOREIGN)GetProcAddress(m_hLibCnv, "RtfToForeign32");
  315. }
  316. ///////////////////////////////////////////////////////////////////////////////
  317. BOOL CConverter::Open(LPCTSTR pszFileName, UINT nOpenFlags,
  318. CFileException* pException)
  319. {
  320. USES_CONVERSION;
  321. // we convert to oem and back because of the following case
  322. // test(c).txt becomes testc.txt in OEM and stays testc.txt to Ansi
  323. char buf[_MAX_PATH];
  324. #if (_MSC_VER > 1310) // VS2005
  325. strcpy_s(buf, _MAX_PATH, T2CA(pszFileName));
  326. #else
  327. strcpy(buf, T2CA(pszFileName));
  328. #endif
  329. CharToOemA(buf, buf);
  330. OemToCharA(buf, buf);
  331. LPTSTR lpszFileNameT = A2T(buf);
  332. // let's make sure we could do what is wanted directly even though we aren't
  333. m_bCloseOnDelete = FALSE;
  334. #if _MFC_VER < 0x700 // MFC 7.0
  335. m_hFile = (UINT)hFileNull;
  336. #else
  337. m_hFile = hFileNull;
  338. #endif
  339. BOOL bOpen = CFile::Open(lpszFileNameT, nOpenFlags, pException);
  340. CFile::Close();
  341. if (!bOpen)
  342. return FALSE;
  343. m_bForeignToRtf = !(nOpenFlags & (CFile::modeReadWrite | CFile::modeWrite));
  344. // check for reading empty file
  345. if (m_bForeignToRtf)
  346. {
  347. CFileStatus stat;
  348. if (CFile::GetStatus(lpszFileNameT, stat) && stat.m_size == 0)
  349. return TRUE;
  350. }
  351. //set security attributes to inherit handle
  352. SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
  353. //create the events
  354. m_hEventFile = CreateEvent(&sa, TRUE, FALSE, NULL);
  355. m_hEventConv = CreateEvent(&sa, TRUE, FALSE, NULL);
  356. //create the converter thread and create the events
  357. CharToOemA(buf, buf);
  358. ASSERT(m_hFileName == NULL);
  359. m_hFileName = StringToHGLOBAL(buf);
  360. m_pThis = this;
  361. m_bDone = FALSE;
  362. m_hBuff = GlobalAlloc(GHND, BUFFSIZE);
  363. ASSERT(m_hBuff != NULL);
  364. AfxBeginThread(ConverterThread, this, THREAD_PRIORITY_NORMAL, 0, 0, &sa);
  365. return TRUE;
  366. }
  367. // m_hEventConv -- the main thread signals this event when ready for more data
  368. // m_hEventFile -- the converter signals this event when data is ready
  369. UINT CConverter::Read(void FAR* lpBuf, UINT nCount)
  370. {
  371. ASSERT(m_bForeignToRtf);
  372. if (m_bDone)
  373. return 0;
  374. // if converter is done
  375. int cch = nCount;
  376. BYTE* pBuf = (BYTE*)lpBuf;
  377. while (cch != 0)
  378. {
  379. if (m_nBytesAvail == 0)
  380. {
  381. if (m_pBuf != NULL)
  382. GlobalUnlock(m_hBuff);
  383. m_pBuf = NULL;
  384. SetEvent(m_hEventConv);
  385. WaitForConverter();
  386. VERIFY(ResetEvent(m_hEventFile));
  387. if (m_bConvErr)
  388. AfxThrowFileException(CFileException::generic);
  389. if (m_bDone)
  390. return nCount - cch;
  391. m_pBuf = (BYTE*)GlobalLock(m_hBuff);
  392. ASSERT(m_pBuf != NULL);
  393. }
  394. int nBytes = min(cch, m_nBytesAvail);
  395. MEMCPY_S(pBuf, m_pBuf, nBytes);
  396. pBuf += nBytes;
  397. m_pBuf += nBytes;
  398. m_nBytesAvail -= nBytes;
  399. cch -= nBytes;
  400. OutputPercent(m_nPercent);
  401. }
  402. return nCount - cch;
  403. }
  404. void CConverter::Write(const void FAR* lpBuf, UINT nCount)
  405. {
  406. ASSERT(!m_bForeignToRtf);
  407. m_nBytesWritten += nCount;
  408. while (nCount != 0)
  409. {
  410. WaitForConverter();
  411. VERIFY(ResetEvent(m_hEventFile));
  412. if (m_bConvErr)
  413. AfxThrowFileException(CFileException::generic);
  414. m_nBytesAvail = min(nCount, BUFFSIZE);
  415. nCount -= m_nBytesAvail;
  416. BYTE* pBuf = (BYTE*)GlobalLock(m_hBuff);
  417. ASSERT(pBuf != NULL);
  418. MEMCPY_S(pBuf, lpBuf, m_nBytesAvail);
  419. GlobalUnlock(m_hBuff);
  420. SetEvent(m_hEventConv);
  421. }
  422. OutputString(m_strSaving);
  423. }
  424. LONG CConverter::Seek(LONG lOff, UINT nFrom)
  425. {
  426. if (lOff != 0 && nFrom != current)
  427. AfxThrowNotSupportedException();
  428. return 0;
  429. }
  430. ULONGLONG  CConverter::GetPosition() const
  431. {
  432. return 0;
  433. }
  434. void CConverter::Flush()
  435. {
  436. }
  437. void CConverter::Close()
  438. {
  439. }
  440. void CConverter::Abort()
  441. {
  442. }
  443. ULONGLONG  CConverter::GetLength() const
  444. {
  445. ASSERT_VALID(this);
  446. return 1;
  447. }
  448. CFile* CConverter::Duplicate() const
  449. {
  450. return NULL;
  451. }
  452. void CConverter::LockRange(DWORD, DWORD)
  453. {
  454. AfxThrowNotSupportedException();
  455. }
  456. void CConverter::UnlockRange(DWORD, DWORD)
  457. {
  458. AfxThrowNotSupportedException();
  459. }
  460. void CConverter::SetLength(DWORD)
  461. {
  462. AfxThrowNotSupportedException();
  463. }
  464. #endif