StkReceiver.cpp
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:23k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "Stockdrv.h" // 通视卡数据结构定义
  3. #include "Tongshi.h" // 通视卡使用函数
  4. #include "STKDRVContainer.h"
  5. #include "StkReceiver.h"
  6. #include "SelectEngineDlg.h"
  7. static CNetSTKDRV gNetTSDLL;
  8. static CSTKDRVContainer gSTOCKDLL;
  9. CStkReceiver & AfxGetStkReceiver()
  10. {
  11. static CStkReceiver gStkReceiver;
  12. return gStkReceiver;
  13. }
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CStkReceiver
  16. HANDLE CStkReceiver::m_hEventKillProcessThread = NULL;
  17. HANDLE CStkReceiver::m_hEventProcessThreadKilled = NULL;
  18. CCriticalSection g_mutexCommPacket;
  19. CPtrArray g_aptrCommPacket;
  20. // 处理接收到的Report数据的线程
  21. UINT StkProcessReceiveReport(LPVOID pParam)
  22. {
  23. while(TRUE)
  24. {
  25. COMMPACKET * pCommPacket = NULL;
  26. {
  27. CSingleLock lock(&g_mutexCommPacket,TRUE);
  28. if(g_aptrCommPacket.GetSize() > 0)
  29. {
  30. pCommPacket = (COMMPACKET *)g_aptrCommPacket.ElementAt(0);
  31. g_aptrCommPacket.RemoveAt(0);
  32. }
  33. }
  34. if(NULL != pCommPacket && CStock::dataReport == pCommPacket->m_dwDataType)
  35. {
  36. // 修改AfxGetStockContainer()
  37. for(DWORD i=0; i<pCommPacket->m_dwCount; i++)
  38. AfxGetStkReceiver().OnReceiveReport(&(pCommPacket->m_pReport[i]));
  39. // 保存至本地文件
  40. AfxGetDB().StoreReport(pCommPacket->m_pReport, pCommPacket->m_dwCount, FALSE);
  41. // 通知各股票信息显示窗口,刷新行情数据
  42. AfxGetStkReceiver().NotifyWndRcvData(CStock::dataReport, (LPARAM)pCommPacket);
  43. // 释放备份数据存储空间
  44. FreeCommPacket(pCommPacket);
  45. }
  46. Sleep(1);
  47. // User wants to quit program
  48. if(WAIT_OBJECT_0 == WaitForSingleObject(CStkReceiver::m_hEventKillProcessThread,0))
  49. {
  50. {
  51. CSingleLock lock(&g_mutexCommPacket,TRUE);
  52. for(int i=0; i<g_aptrCommPacket.GetSize(); i++)
  53. {
  54. pCommPacket = (COMMPACKET *)g_aptrCommPacket.ElementAt(i);
  55. FreeCommPacket(pCommPacket);
  56. }
  57. g_aptrCommPacket.RemoveAll();
  58. }
  59. SetEvent(CStkReceiver::m_hEventProcessThreadKilled);
  60. AfxEndThread(0, TRUE);
  61. return 0;
  62. }
  63. }
  64. }
  65. CStkReceiver::CStkReceiver()
  66. {
  67. m_bTongshiRunning = FALSE;
  68. }
  69. CStkReceiver::~CStkReceiver()
  70. {
  71. }
  72. BOOL CStkReceiver::CreateReceiver(CWnd * pParentWnd)
  73. {
  74. return CreateEx(0, NULL,"",WS_OVERLAPPEDWINDOW | WS_CHILDWINDOW, CRect(0,0,0,0), pParentWnd, 0, NULL);
  75. }
  76. void CStkReceiver::OnReceiveReport(REPORT * pReport)
  77. {
  78. CStockContainer & container = AfxGetStockContainer();
  79. REPORT reportLast;
  80. if(!UpdateStockContainerByREPORT(container, pReport, TRUE, &reportLast))
  81. return;
  82. CStockInfo infoCur;
  83. // 主力大单
  84. if(container.GetStockInfo(pReport->m_szCode, &infoCur, NULL))
  85. {
  86. if(0 != reportLast.m_time && reportLast.m_time < pReport->m_time
  87. && pReport->m_fVolume - reportLast.m_fVolume >= 100000
  88. && !infoCur.IsIndex() && !infoCur.IsBond() && !infoCur.IsFund() && !infoCur.IsBondIndex())
  89. {
  90. REPORT report;
  91. memcpy(&report, pReport, sizeof(report));
  92. report.m_fVolume = pReport->m_fVolume - infoCur.m_reportLatest.m_fVolume;
  93. report.m_fAmount = pReport->m_fAmount - infoCur.m_reportLatest.m_fAmount;
  94. AfxGetDB().StoreReport(&report, 1, TRUE);
  95. }
  96. }
  97. // 指数发生变化
  98. if(0 == strncmp(pReport->m_szCode, STKLIB_CODE_MAIN, sizeof(pReport->m_szCode))
  99. || 0 == strncmp(pReport->m_szCode, STKLIB_CODE_MAINSZN, sizeof(pReport->m_szCode)))
  100. {
  101. NotifyWndRcvAlarm(STKRCV_ALARM_REFRESH, 0);
  102. }
  103. // 盘中预警在此处加入
  104. if(AfxGetAlarmContainer().OnReceiveReport(&infoCur, pReport, &reportLast))
  105. {
  106. NotifyWndRcvAlarm(STKRCV_ALARM_WARNING, 0);
  107. }
  108. }
  109. void CStkReceiver::AddRcvAlarmWnd(HWND hWnd)
  110. {
  111. m_awndRcvAlarm.Add(hWnd);
  112. }
  113. BOOL CStkReceiver::RemoveRcvAlarmWnd(HWND hWnd)
  114. {
  115. for(int i=0; i<m_awndRcvAlarm.GetSize(); i++)
  116. {
  117. if(m_awndRcvAlarm.ElementAt(i) == hWnd)
  118. {
  119. m_awndRcvAlarm.RemoveAt(i,1);
  120. return TRUE;
  121. }
  122. }
  123. return FALSE;
  124. }
  125. void CStkReceiver::NotifyWndRcvAlarm(WPARAM wParam, LPARAM lParam)
  126. {
  127. for(int i=0; i<m_awndRcvAlarm.GetSize(); i++)
  128. ::PostMessage(m_awndRcvAlarm[i], WM_APP_STKRECEIVER_ALARM, wParam, lParam);
  129. }
  130. void CStkReceiver::AddRcvDataWnd(HWND hWnd)
  131. {
  132. m_awndRcvData.Add(hWnd);
  133. }
  134. BOOL CStkReceiver::RemoveRcvDataWnd(HWND hWnd)
  135. {
  136. for(int i=0; i<m_awndRcvData.GetSize(); i++)
  137. {
  138. if(m_awndRcvData.ElementAt(i) == hWnd)
  139. {
  140. m_awndRcvData.RemoveAt(i,1);
  141. return TRUE;
  142. }
  143. }
  144. return FALSE;
  145. }
  146. void CStkReceiver::NotifyWndRcvData(WPARAM wParam, LPARAM lParam)
  147. {
  148. for(int i=0; i<m_awndRcvData.GetSize(); i++)
  149. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA , wParam, lParam);
  150. }
  151. BOOL CStkReceiver::NetEngineBeginWorking()
  152. {
  153. return SendMessage(WM_APP_STKRECEIVER_CONNECTSERVER);
  154. }
  155. BOOL CStkReceiver::NetEngineBeginWorking(LPCTSTR lpszAddress, UINT nPort, LPCTSTR lpszUser, LPCTSTR lpszPasswd)
  156. {
  157. if(gNetTSDLL.LoadDriver("NetTS.dll")
  158. && gNetTSDLL.Stock_Init_Nodialog(m_hWnd,WM_APP_STKRECEIVER_TSDATA,RCV_WORK_SENDMSG,
  159. lpszAddress,nPort,lpszUser,lpszPasswd) > 0)
  160. return TRUE;
  161. return FALSE;
  162. }
  163. BOOL CStkReceiver::NetEngineEndWorking()
  164. {
  165. return SendMessage(WM_APP_STKRECEIVER_DISCONNECTSERVER);
  166. }
  167. BOOL CStkReceiver::NetEngineIsWorking()
  168. {
  169. return gNetTSDLL.IsEngineWorking();
  170. }
  171. BOOL CStkReceiver::NetEngineSetAutoReport(int bAutoReport)
  172. {
  173. return gNetTSDLL.SetAutoReport(bAutoReport);
  174. }
  175. int CStkReceiver::RequestStockData(int nDataType/*CStock::DataType*/, CStockInfo * pStockInfo, int nSize, int nKType, int nDataCount)
  176. {
  177. int nDataTypeTS = DataType_to_TSDataType(nDataType);
  178. if(nSize < 0)
  179. return 0;
  180. STOCK_STRUCTEx * pStocks = new STOCK_STRUCTEx[nSize+1];
  181. memset(pStocks, 0, sizeof(STOCK_STRUCTEx)*(nSize+1));
  182. for(int i=0; i<nSize; i++)
  183. {
  184. pStocks[i].m_type = (BYTE)pStockInfo[i].GetType();
  185. strncpy(pStocks[i].m_code, pStockInfo[i].GetStockCode(), sizeof(pStocks[i].m_code));
  186. }
  187. int nRet = gNetTSDLL.RequestStockData(nDataTypeTS, pStocks, nSize, nKType, nDataCount);
  188. delete [] pStocks;
  189. return nRet;
  190. }
  191. int CStkReceiver::RequestKData(CStock *pstock, int period)
  192. {
  193. int nDataCount = 480;
  194. CStockInfo & info = pstock->GetStockInfo();
  195. CKData & kdata = pstock->GetKData(period);
  196. DWORD dateLatest = info.m_datebegin;
  197. if(kdata.GetSize() > 0)
  198. dateLatest = kdata.ElementAt(kdata.GetSize()-1).m_date;
  199. CSPTime tmLatest;
  200. tmLatest.FromStockTime(dateLatest, CKData::IsDayOrMin(period));
  201. CSPTime tmInitial = CStDatabase::GetTimeInitial();
  202. if(tmLatest < tmInitial)
  203. tmLatest = tmInitial;
  204. CSPTime tmNow = CSPTime::GetCurrentTime();
  205. CSPTimeSpan span = tmNow - tmLatest;
  206. switch(period)
  207. {
  208. case CKData::ktypeDay: nDataCount = span.GetDays()*5/7+1; break;
  209. case CKData::ktypeWeek: nDataCount = span.GetDays()/7+1; break;
  210. case CKData::ktypeMonth: nDataCount = span.GetDays()/30+1; break;
  211. default: ;
  212. }
  213. if(nDataCount < 100) nDataCount = 100;
  214. return RequestStockData(CStock::dataK, &info, 1, period, nDataCount);
  215. }
  216. BOOL CStkReceiver::EngineBeginWorking(BOOL bShowSelectEngineDialog)
  217. {
  218. return SendMessage(WM_APP_STKRECEIVER_INIT, !bShowSelectEngineDialog); // 启动通视接收系统
  219. }
  220. BOOL CStkReceiver::EngineSetup()
  221. {
  222. return SendMessage(WM_APP_STKRECEIVER_SETUP);
  223. }
  224. BOOL CStkReceiver::EngineEndWorking()
  225. {
  226. return SendMessage(WM_APP_STKRECEIVER_QUIT);
  227. }
  228. BOOL CStkReceiver::EngineIsWorking()
  229. {
  230. return m_bTongshiRunning;
  231. }
  232. int CStkReceiver::RefreshStockContainer(CStockContainer & container, BOOL bAddIfNotExist)
  233. {
  234. if(gNetTSDLL.IsEngineWorking() || gNetTSDLL.GetTotalNumber() > 0)
  235. {
  236. int nMaxNumber = gNetTSDLL.GetTotalNumber();
  237. ASSERT(nMaxNumber >= 0);
  238. if(nMaxNumber <= 0)
  239. return 0;
  240. int nNO = 0;
  241. while(TRUE)
  242. {
  243. RCV_REPORT_STRUCTEx tsreport;
  244. memset(&tsreport,0,sizeof(tsreport));
  245. int nRet = gNetTSDLL.GetStockByNoEx(nNO, &tsreport);
  246. if(nRet <= 0)
  247. break;
  248. REPORT report;
  249. if(convert_TSREPORT_to_REPORT(&tsreport, &report))
  250. UpdateStockContainerByREPORT(container, &report, bAddIfNotExist);
  251. nNO ++;
  252. }
  253. return nNO;
  254. }
  255. if(m_bTongshiRunning)
  256. {
  257. int nMaxNumber = gSTOCKDLL.GetTotalNumber();
  258. ASSERT(nMaxNumber >= 0);
  259. if(nMaxNumber <= 0)
  260. return 0;
  261. int nNO = 0;
  262. while(TRUE)
  263. {
  264. RCV_REPORT_STRUCTEx tsreport;
  265. memset(&tsreport,0,sizeof(tsreport));
  266. int nRet = gSTOCKDLL.GetStockByNoEx(nNO, &tsreport);
  267. if(nRet <= 0)
  268. break;
  269. REPORT report;
  270. if(convert_TSREPORT_to_REPORT(&tsreport, &report))
  271. UpdateStockContainerByREPORT(container, &report, bAddIfNotExist);
  272. nNO ++;
  273. }
  274. return nNO;
  275. }
  276. return 0;
  277. }
  278. int CStkReceiver::GetReport(CStockInfo &info, CReport &aReport)
  279. {
  280. if(m_bTongshiRunning)
  281. {
  282. int nMarket = SH_MARKET_EX;
  283. if(info.IsShangHai())
  284. nMarket = SH_MARKET_EX;
  285. else if(info.IsShenZhen())
  286. nMarket = SZ_MARKET_EX;
  287. RCV_REPORT_STRUCTEx tsreport;
  288. REPORT  report;
  289. int nRet = gSTOCKDLL.GetStockByCodeEx((char *)info.GetStockCode(), nMarket, &tsreport);
  290. if(nRet > 0 && 0 == strncmp(info.GetStockCode(),tsreport.m_szLabel,min(strlen(info.GetStockCode()),sizeof(tsreport.m_szLabel)))
  291. && convert_TSREPORT_to_REPORT(&tsreport, &report))
  292. {
  293. UpdateStockInfoByREPORT(info, &report);
  294. return 1;
  295. }
  296. }
  297. return 0;
  298. }
  299. BEGIN_MESSAGE_MAP(CStkReceiver, CWnd)
  300. ON_WM_CREATE()
  301. ON_WM_DESTROY()
  302. ON_MESSAGE(WM_APP_STKRECEIVER_CONNECTSERVER,OnStkReceiverConnectserver)
  303. ON_MESSAGE(WM_APP_STKRECEIVER_DISCONNECTSERVER,OnStkReceiverDisconnectserver)
  304. ON_MESSAGE(WM_APP_STKRECEIVER_INIT,OnStkReceiverInit)
  305. ON_MESSAGE(WM_APP_STKRECEIVER_SETUP,OnStkReceiverSetup)
  306. ON_MESSAGE(WM_APP_STKRECEIVER_QUIT,OnStkReceiverQuit)
  307. ON_MESSAGE(WM_APP_STKRECEIVER_TSDATA,OnStkReceiverTsdata)
  308. END_MESSAGE_MAP()
  309. /////////////////////////////////////////////////////////////////////////////
  310. // CStkReceiver message handlers
  311. int CStkReceiver::OnCreate(LPCREATESTRUCT lpCreateStruct)
  312. {
  313. if (CWnd::OnCreate(lpCreateStruct) == -1)
  314. return -1;
  315. CStkReceiver::m_hEventKillProcessThread = CreateEvent(NULL,FALSE,FALSE,NULL);
  316. CStkReceiver::m_hEventProcessThreadKilled = CreateEvent(NULL,FALSE,FALSE,NULL);
  317. AfxBeginThread(StkProcessReceiveReport, NULL, THREAD_PRIORITY_NORMAL);
  318. return 0;
  319. }
  320. void CStkReceiver::OnDestroy()
  321. {
  322. OnStkReceiverQuit(0, 0);
  323. OnStkReceiverDisconnectserver(0, 0);
  324. /*
  325. // These codes do not work well. system will terminate the thread auto, but cause some memory leaks
  326. if(CStkReceiver::m_hEventKillProcessThread)
  327. SetEvent(CStkReceiver::m_hEventKillProcessThread);
  328. if(WAIT_OBJECT_0 == WaitForSingleObject(CStkReceiver::m_hEventKillProcessThread,2000))
  329. {
  330. if(CStkReceiver::m_hEventKillProcessThread)
  331. CloseHandle(CStkReceiver::m_hEventKillProcessThread);
  332. if(CStkReceiver::m_hEventProcessThreadKilled)
  333. CloseHandle(CStkReceiver::m_hEventProcessThreadKilled);
  334. CStkReceiver::m_hEventKillProcessThread = NULL;
  335. CStkReceiver::m_hEventProcessThreadKilled = NULL;
  336. }
  337. */
  338. CWnd::OnDestroy();
  339. }
  340. LRESULT CStkReceiver::OnStkReceiverConnectserver(WPARAM wParam, LPARAM lParam)
  341. {
  342. if(gNetTSDLL.LoadDriver("NetTS.dll")
  343. && gNetTSDLL.Stock_Init(m_hWnd,WM_APP_STKRECEIVER_TSDATA,RCV_WORK_SENDMSG) > 0)
  344. return TRUE;
  345. return FALSE;
  346. }
  347. LRESULT CStkReceiver::OnStkReceiverDisconnectserver(WPARAM wParam, LPARAM lParam)
  348. {
  349. gNetTSDLL.Stock_Quit(m_hWnd);
  350. return TRUE;
  351. }
  352. LRESULT CStkReceiver::OnStkReceiverInit(WPARAM wParam, LPARAM lParam)
  353. {
  354. // 通视及兼容设备
  355. {
  356. CStringArray astrProvider, astrDriver;
  357. if(!wParam)
  358. {
  359. CSelectEngineDlg dlg;
  360. if(IDOK != dlg.DoModal())
  361. return -1L;
  362. dlg.GetSelectedDriver(astrProvider, astrDriver);
  363. }
  364. if(astrDriver.GetSize() <= 0)
  365. {
  366. CSPStringArray aProDefault, aDrvDefault;
  367. AfxGetProfile().GetRcvDriverDefault(aProDefault, aDrvDefault);
  368. for(int i=0; i<aProDefault.GetSize(); i++) astrProvider.Add(aProDefault[i]);
  369. for(i=0; i<aDrvDefault.GetSize(); i++) astrDriver.Add(aDrvDefault[i]);
  370. }
  371. if(astrDriver.GetSize() <= 0)
  372. {
  373. // AfxRegQueryString(HKEY_LOCAL_MACHINE, _T("Software"), _T("stockdrv"), _T("兼容设备"), astrProvider, astrDriver);
  374. astrProvider.InsertAt(0, AfxRegQueryString(HKEY_LOCAL_MACHINE, _T("Software"), _T("stockdrv"), "", "", _T("Provider"), "Tongshi"));
  375. astrDriver.InsertAt(0, AfxRegQueryString(HKEY_LOCAL_MACHINE, _T("Software"), _T("stockdrv"), "", "", _T("Driver"), "Stock.dll"));
  376. }
  377. // 数据共享引用
  378. gSTOCKDLL.Stock_Quit(m_hWnd);
  379. gSTOCKDLL.UnloadDriver();
  380. if(gSTOCKDLL.LoadDriver(astrDriver)
  381. && gSTOCKDLL.Stock_Init(m_hWnd,WM_APP_STKRECEIVER_TSDATA,RCV_WORK_SENDMSG) > 0)
  382. m_bTongshiRunning = TRUE;
  383. else if(!wParam)
  384. AfxMessageBox(AfxModuleLoadString(IDS_SELECTENGINE_ERRLOAD), MB_OK | MB_ICONINFORMATION);
  385. }
  386. return TRUE;
  387. }
  388. LRESULT CStkReceiver::OnStkReceiverSetup(WPARAM wParam, LPARAM lParam)
  389. {
  390. return gSTOCKDLL.SetupReceiver(TRUE);
  391. }
  392. LRESULT CStkReceiver::OnStkReceiverQuit(WPARAM wParam, LPARAM lParam)
  393. {
  394. gSTOCKDLL.Stock_Quit(m_hWnd);
  395. m_bTongshiRunning = FALSE;
  396. gSTOCKDLL.UnloadDriver();
  397. return TRUE;
  398. }
  399. // 通视处理数据
  400. LRESULT CStkReceiver::OnStkReceiverTsdata(
  401. UINT wFileType, // 文件类型, 参见 StockDrv.H
  402. LONG lPara)
  403. {
  404. int i = 0;
  405. PBYTE pFileBuf = NULL;
  406. PBYTE pBuffx = NULL;
  407. PGZLXBINDATA pGZLX = NULL;
  408. RCV_DATA * pHeader = (RCV_DATA *) lPara;
  409. // 检查参数
  410. ASSERT(pHeader && pHeader->m_pData);
  411. if(!pHeader || !pHeader->m_pData)
  412. return -1L;
  413. // ASSERT(pHeader->m_nPacketNum > 0 || pHeader->m_bDISK);
  414. if(pHeader->m_nPacketNum <= 0 && !pHeader->m_bDISK)
  415. return -1L;
  416. // 对于处理较慢的数据类型,建议将数据备份,另创建一线程处理
  417. switch(wFileType)
  418. {
  419. case RCV_REPORT:
  420. {
  421. // 检查参数
  422. ASSERT(pHeader->m_nPacketNum > 0 && !pHeader->m_bDISK);
  423. if(pHeader->m_nPacketNum <= 0 || pHeader->m_bDISK)
  424. return -1L;
  425. // 分配备份数据存储空间
  426. COMMPACKET * pCommPacket = AllocCommPacket(CStock::dataReport, pHeader->m_nPacketNum);
  427. if(NULL == pCommPacket)
  428. return -1L;
  429. // 修改AfxGetStockContainer()
  430. int nBufSize = pHeader->m_pReport[0].m_cbSize;
  431. PBYTE pBaseBuf = (PBYTE)&pHeader->m_pReport[0];
  432. for(i=0; i<pHeader->m_nPacketNum; i++)
  433. {
  434. PRCV_REPORT_STRUCTEx pReport = (PRCV_REPORT_STRUCTEx)(pBaseBuf + nBufSize*i);
  435. if(convert_TSREPORT_to_REPORT(pReport, &(pCommPacket->m_pReport[i])))
  436. {
  437. /* 以下代码转移到新建线程中执行 */
  438. // AfxGetStkReceiver().OnReceiveReport(&(pCommPacket->m_pReport[i]));
  439. }
  440. }
  441. {
  442. CSingleLock lock(&g_mutexCommPacket,TRUE);
  443. g_aptrCommPacket.Add(pCommPacket);
  444. }
  445. /* 以下代码转移到新建线程中执行
  446. // 保存至本地文件
  447. AfxGetDB().StoreReport(pCommPacket->m_pReport, pCommPacket->m_dwCount, FALSE);
  448. // 通知各股票信息显示窗口,刷新行情数据
  449. for(i=0; i<m_awndRcvData.GetSize(); i++)
  450. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataReport, (LPARAM)pCommPacket);
  451. // 释放备份数据存储空间
  452. FreeCommPacket(pCommPacket);
  453. */ 
  454. }
  455. break;
  456. case RCV_FILEDATA:
  457. switch(pHeader->m_wDataType)
  458. {
  459. case FILE_HISTORY_EX: // 补日线数据
  460. {
  461. RCV_HISTORY_STRUCTEx * pDay = pHeader->m_pDay;
  462. int nPacketNum = pHeader->m_nPacketNum;
  463. CKData kdata(CKData::ktypeDay);
  464. CString sCode;
  465. DWORD dwMarket = CStock::marketUnknown;
  466. // 读取文件
  467. if(pHeader->m_bDISK)
  468. {
  469. pDay = NULL;
  470. CFile file;
  471. if(file.Open(pHeader->m_File.m_szFileName,CFile::modeRead))
  472. {
  473. ASSERT(file.GetLength() == pHeader->m_File.m_dwLen);
  474. nPacketNum = (int)(file.GetLength()/sizeof(RCV_HISTORY_STRUCTEx));
  475. if(nPacketNum > 0)
  476. pDay = new RCV_HISTORY_STRUCTEx[nPacketNum];
  477. if(pDay)
  478. file.Read(pDay, sizeof(RCV_HISTORY_STRUCTEx)*nPacketNum);
  479. file.Close();
  480. }
  481. }
  482. // 分配备份数据存储空间
  483. COMMPACKET * pCommPacket = AllocCommPacket(CStock::dataK, nPacketNum);
  484. if(NULL == pCommPacket)
  485. return -1L;
  486. // 处理数据
  487. DWORD dwCount = 0;
  488. for(i=0; i<nPacketNum && pDay; i++)
  489. {
  490. if(pDay[i].m_head.m_dwHeadTag == EKE_HEAD_TAG)
  491. {
  492. if(kdata.GetSize() > 0)
  493. {
  494. kdata.AutoSetKType();
  495. UpdateStockContainerByKData(AfxGetStockContainer(), sCode, kdata);
  496. AfxGetDB().InstallKData(kdata);
  497. kdata.RemoveAll();
  498. }
  499. sCode = pDay[i].m_head.m_szLabel;
  500. dwMarket = TSMarket_to_Market(pDay[i].m_head.m_wMarket);
  501. continue;
  502. }
  503. convert_TSHISTORY_to_KDATA(dwMarket, sCode, &(pDay[i]), &(pCommPacket->m_pKdata[dwCount]));
  504. kdata.Add(pCommPacket->m_pKdata[dwCount]);
  505. dwCount ++;
  506. }
  507. pCommPacket->m_dwCount = dwCount;
  508. if(pHeader->m_bDISK && pDay)
  509. delete [] pDay;
  510. if(kdata.GetSize() > 0)
  511. {
  512. kdata.AutoSetKType();
  513. UpdateStockContainerByKData(AfxGetStockContainer(), sCode, kdata);
  514. AfxGetDB().InstallKData(kdata);
  515. }
  516. // 通知各股票信息显示窗口,刷新行情数据
  517. for(i=0; i<m_awndRcvData.GetSize(); i++)
  518. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataK, (LPARAM)pCommPacket);
  519. // 释放备份数据存储空间
  520. FreeCommPacket(pCommPacket);
  521. }
  522. break;
  523. case FILE_MINUTE_EX: // 补分钟线数据
  524. case 83: // 补分笔数据
  525. {
  526. RCV_MINUTE_STRUCTEx * pMin = pHeader->m_pMinute;
  527. ASSERT(pMin->m_head.m_dwHeadTag == EKE_HEAD_TAG);
  528. CMinute minute;
  529. BOOL bAutoSaveKDataMin = AfxGetProfile().GetAutoSaveKDataMin(); // 作为分钟K线保存
  530. CString sCode;
  531. DWORD dwMarket = CStock::marketUnknown;
  532. // 分配备份数据存储空间
  533. COMMPACKET * pCommPacket = AllocCommPacket(CStock::dataMinute, pHeader->m_nPacketNum);
  534. if(NULL == pCommPacket)
  535. return -1L;
  536. DWORD dwCount = 0;
  537. for(i=0; i<pHeader->m_nPacketNum; i++)
  538. {
  539. if(pMin[i].m_head.m_dwHeadTag == EKE_HEAD_TAG)
  540. {
  541. if(minute.GetSize() > 0)
  542. {
  543. CKData kdMin(CKData::ktypeMin5);
  544. if(minute.ToKData(kdMin))
  545. AfxGetDB().InstallKData(kdMin);
  546. minute.RemoveAll();
  547. }
  548. sCode = pMin[i].m_head.m_szLabel;
  549. dwMarket = TSMarket_to_Market(pMin[i].m_head.m_wMarket);
  550. continue;
  551. }
  552. convert_TSMINUTE_to_MINUTE(dwMarket, sCode, &(pMin[i]), &(pCommPacket->m_pMinute[dwCount]));
  553. if(bAutoSaveKDataMin)
  554. minute.Add(pCommPacket->m_pMinute[dwCount]);
  555. dwCount ++;
  556. }
  557. pCommPacket->m_dwCount = dwCount;
  558. if(minute.GetSize() > 0)
  559. {
  560. CKData kdMin(CKData::ktypeMin5);
  561. if(minute.ToKData(kdMin))
  562. AfxGetDB().InstallKData(kdMin);
  563. }
  564. // 保存至本地文件
  565. AfxGetDB().StoreMinute(pCommPacket->m_pMinute, pCommPacket->m_dwCount);
  566. // 通知各股票信息显示窗口,刷新行情数据
  567. for(i=0; i<m_awndRcvData.GetSize(); i++)
  568. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataMinute, (LPARAM)pCommPacket);
  569. // 释放备份数据存储空间
  570. FreeCommPacket(pCommPacket);
  571. }
  572. break;
  573. case FILE_POWER_EX: // 补充除权数据
  574. {
  575. RCV_POWER_STRUCTEx * pPower = pHeader->m_pPower;
  576. int nPacketNum = pHeader->m_nPacketNum;
  577. CDRData drdata;
  578. CString sCode;
  579. DWORD dwMarket = CStock::marketUnknown;
  580. if(pHeader->m_bDISK)
  581. {
  582. pPower = NULL;
  583. CFile file;
  584. if(file.Open(pHeader->m_File.m_szFileName,CFile::modeRead))
  585. {
  586. ASSERT(file.GetLength() == pHeader->m_File.m_dwLen);
  587. nPacketNum = (int)(file.GetLength()/sizeof(RCV_POWER_STRUCTEx));
  588. if(nPacketNum > 0)
  589. pPower = new RCV_POWER_STRUCTEx[nPacketNum];
  590. if(pPower)
  591. file.Read(pPower, sizeof(RCV_POWER_STRUCTEx)*nPacketNum);
  592. file.Close();
  593. }
  594. }
  595. // 分配备份数据存储空间
  596. COMMPACKET * pCommPacket = AllocCommPacket(CStock::dataDR, nPacketNum);
  597. if(NULL == pCommPacket)
  598. return -1L;
  599. DWORD dwCount = 0;
  600. for(i=0; i<nPacketNum && pPower; i++)
  601. {
  602. if(pPower[i].m_head.m_dwHeadTag == EKE_HEAD_TAG)
  603. {
  604. if(drdata.GetSize() > 0)
  605. AfxGetDB().InstallDRData(drdata);
  606. drdata.RemoveAll();
  607. sCode = pPower[i].m_head.m_szLabel;
  608. dwMarket = TSMarket_to_Market(pPower[i].m_head.m_wMarket);
  609. continue;
  610. }
  611. convert_TSPOWER_to_DRDATA(dwMarket, sCode, &(pPower[i]), &(pCommPacket->m_pDrdata[dwCount]));
  612. drdata.Add(pCommPacket->m_pDrdata[dwCount]);
  613. dwCount ++;
  614. }
  615. if(pHeader->m_bDISK && pPower)
  616. delete [] pPower;
  617. if(drdata.GetSize() > 0)
  618. AfxGetDB().InstallDRData(drdata);
  619. pCommPacket->m_dwCount = dwCount;
  620. // 通知各股票信息显示窗口,刷新行情数据
  621. for(i=0; i<m_awndRcvData.GetSize(); i++)
  622. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataDR, (LPARAM)pCommPacket);
  623. // 释放备份数据存储空间
  624. FreeCommPacket(pCommPacket);
  625. }
  626. break;
  627. case FILE_MULTISORT_EX: // 综合排名
  628. {
  629. RCV_MULTISORT_STRUCTEx * pMultisort = pHeader->m_pMultisort;
  630. // 分配备份数据存储空间
  631. COMMPACKET * pCommPacket = AllocCommPacket(CStock::dataMultisort, pHeader->m_nPacketNum);
  632. if(NULL == pCommPacket)
  633. return -1L;
  634. for(i=0; i<pHeader->m_nPacketNum; i++)
  635. {
  636. convert_TSMULTISORT_to_MULTISORT(&(pMultisort[i]), &(pCommPacket->m_pMultisort[i]));
  637. }
  638. pCommPacket->m_dwCount = pHeader->m_nPacketNum;
  639. // 通知各股票信息显示窗口,刷新行情数据
  640. for(i=0; i<m_awndRcvData.GetSize(); i++)
  641. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataMultisort, (LPARAM)pCommPacket);
  642. // 释放备份数据存储空间
  643. FreeCommPacket(pCommPacket);
  644. }
  645. break;
  646. case FILE_BASE_EX: // 钱龙兼容基本资料文件,m_szFileName仅包含文件名
  647. {
  648. if(pHeader->m_bDISK)
  649. {
  650. AfxGetDB().InstallBaseText(pHeader->m_File.m_szFileName, AfxGetFileTitle(pHeader->m_File.m_szFileName));
  651. }
  652. else
  653. {
  654. AfxGetDB().InstallBaseText(LPCTSTR(pHeader->m_pData), pHeader->m_File.m_dwLen, AfxGetFileTitle(pHeader->m_File.m_szFileName));
  655. }
  656. // 分配备份数据存储空间
  657. COMMPACKET * pCommPacket = AllocCommPacket(CStock::dataCode, 1);
  658. if(NULL == pCommPacket)
  659. return -1L;
  660. CString sTemp = AfxGetFileTitleNoExt(pHeader->m_File.m_szFileName);
  661. strncpy(pCommPacket->m_pStockcode[0].m_szCode, sTemp, min(sizeof(pCommPacket->m_pStockcode[0].m_szCode)-1,sTemp.GetLength()));
  662. pCommPacket->m_pStockcode[0].m_dwMarket = CStock::marketUnknown;
  663. // 通知各股票信息显示窗口,刷新行情数据
  664. for(i=0; i<m_awndRcvData.GetSize(); i++)
  665. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataBasetext, (LPARAM)pCommPacket);
  666. // 释放备份数据存储空间
  667. FreeCommPacket(pCommPacket);
  668. }
  669. break;
  670. case FILE_NEWS_EX: // 新闻类,其类型由m_szFileName中子目录名来定
  671. if(pHeader->m_bDISK)
  672. {
  673. AfxGetDB().InstallNewsText(pHeader->m_File.m_szFileName, AfxGetFileTitle(pHeader->m_File.m_szFileName));
  674. }
  675. else
  676. {
  677. AfxGetDB().InstallNewsText(LPCTSTR(pHeader->m_pData), pHeader->m_File.m_dwLen, AfxGetFileTitle(pHeader->m_File.m_szFileName));
  678. }
  679. // 通知各股票信息显示窗口,刷新行情数据
  680. for(i=0; i<m_awndRcvData.GetSize(); i++)
  681. ::SendMessage(m_awndRcvData[i], WM_APP_STKRECEIVER_DATA, CStock::dataNews, NULL);
  682. break;
  683. case FILE_HTML_EX: // HTML文件,m_szFileName为URL
  684. AfxGetProfile().AddHTMLURLToExplorer(pHeader->m_File.m_szFileName);
  685. break;
  686. case FILE_SOFTWARE_EX:
  687. TRACE("%sn",pHeader->m_File.m_szFileName);
  688. TRACE("%dn",pHeader->m_File.m_dwLen);
  689. pBuffx = (PBYTE)pHeader->m_pData;
  690. break;
  691. case FILE_SHAZQDATA_EX: //h上海国债净价交易
  692. break;
  693. case FILE_TYPE_RES:
  694. TRACE("MSG: CStkReceiver::OnStkDataOK, Replaced data n");
  695. break;
  696. default:
  697. TRACE("Msg: CStkReceiver::OnStkReceiverData,Unkonw data typen");
  698. }
  699. break;
  700. }
  701. return 0L;
  702. }