admin
2022-08-25 14db1514fec89db599766d4996b4bb1fead0eff0
app/appDlg.cpp
@@ -12,8 +12,10 @@
#ifndef _TOOL_H
#define _TOOL_H 1
#include "tool.h"
#include "TaskChecker.h"
#endif 
#include "JsonUtil.h"
#include <exception>
#ifdef _DEBUG
@@ -26,6 +28,8 @@
#endif
#include <Win32Util.h>
#include "loginDlg.h"
#include <psapi.h>
#pragma comment(lib,"psapi.lib")
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
@@ -98,6 +102,8 @@
   tradeListCapture = new TradeListCapture();
   industryCapture = new IndustryCapture();
   gpDataCapture = new THSGPDataCapture();
   currentPriceCapture = new CurrentPriceCapture();
   thsL2RepairTool = new THSL2RepairTool();
}
void CappDlg::DoDataExchange(CDataExchange* pDX)
@@ -114,6 +120,8 @@
   DDX_Control(pDX, IDC_BUTTON22, refreshHWNDBtn);
   DDX_Control(pDX, IDC_BUTTON21, resetTHSBtn);
   DDX_Control(pDX, IDC_CHECK6, autoL2Check);
   DDX_Control(pDX, IDC_CURRENT_PRICE, currentPriceBtn);
   DDX_Control(pDX, IDC_STATIC_AUTO_MSG, autoMsgStatic);
}
BEGIN_MESSAGE_MAP(CappDlg, CDialogEx)
@@ -138,6 +146,7 @@
   ON_BN_CLICKED(IDC_BUTTON22, &CappDlg::OnBnClickedButton22)
   ON_BN_CLICKED(IDC_LOGOUT_BTN, &CappDlg::OnBnClickedLogoutBtn)
   ON_BN_CLICKED(IDC_CHECK6, &CappDlg::OnBnClickedCheck6)
   ON_BN_CLICKED(IDC_CURRENT_PRICE, &CappDlg::OnBnClickedCurrentPrice)
END_MESSAGE_MAP()
@@ -187,15 +196,17 @@
      btnL2.EnableWindow(TRUE);
      resetTHSBtn.EnableWindow(TRUE);
      refreshHWNDBtn.EnableWindow(TRUE);
      list<string> settings=   Tool::getSettings("setting.txt");
      list<string> settings = Tool::getSettings("setting.txt");
      if (settings.size() > 0) {
         string c= *(settings.begin());
         string c = *(settings.begin());
         if (c == "1") {
            autoMsgStatic.SetWindowTextW(_T("正在自动启动中..."));
            autoL2Check.SetCheck(TRUE);
            thread rt(&(CappDlg::autoStartL2),this);
            thread rt(&(CappDlg::autoStartL2), this);
            rt.detach();
         }
         else {
            autoMsgStatic.SetWindowTextW(_T(""));
            autoL2Check.SetCheck(FALSE);
         }
      }
@@ -223,9 +234,11 @@
   if (authoritySet.count(AUTHORITY_TRADE_DELEGATE) > 0) {
      delegateBtn.EnableWindow(TRUE);
      currentPriceBtn.EnableWindow(TRUE);
   }
   else {
      delegateBtn.EnableWindow(FALSE);
      currentPriceBtn.EnableWindow(FALSE);
   }
@@ -465,9 +478,27 @@
   _list.clear();
}
void CappDlg::OnCurrentPriceCallback(list<CurrentPriceData> dataList, void* context)
{
   //转为json
   CappDlg* app = (CappDlg*)context;
bool  CappDlg::OnActionCallback(string data, void* context) {
   string data = JsonUtil::loadGPPriceData(dataList);
   try {
      app->socketManager->sendMsg(8, data.c_str());
      //AfxMessageBox(_T("上传成功"));
   }
   catch (string st) {
      //重新连接服务器
      app->socketManager->resetClient(8);
      app->socketManager->Connect(8);
   }
   dataList.clear();
}
string CappDlg::OnActionProcess(string data, void* context)
{
   //转为json
   CappDlg* app = (CappDlg*)context;
   cout << "action回调:" << std::this_thread::get_id() << ":" << data << endl;
@@ -488,7 +519,7 @@
      try {
         if (!app->capture->isInited()) {
            throw string("采集器尚未初始化");
            app->initCapture(false);
         }
         //暂停采集
@@ -498,8 +529,10 @@
         if (!result) {
            throw string("设置版块监控的GP失败");
         }
         //刷新句柄
         THSActionUtil::setListenL2GP(index, code, recognitionManager);
         //打开Level2监控屏幕
         THSActionUtil::openL2Screen();
         map<int, string> results = THSActionUtil::getListenL2GPCodes(recognitionManager);
         //设置代码
         for (map<int, string>::iterator ele = results.begin();ele != results.end();ele++) {
@@ -509,21 +542,20 @@
         }
      }
      catch (string e) {
         //CString msg(e.c_str());
         //AfxMessageBox(msg);
         throw e;
      }
      catch (...) {
         throw string("未知错误");
         throw string("未知错误(unknown error)");
      }
      //恢复采集
      app->capture->start(index);
   }
   else if (action == "repairL2Data") {
      //修正代码与L2行情代码不对应 或者 L2行情无数据的情况
      cout << "修复L2数据" << endl;
      if (!app->capture->isInited()) {
         throw string("采集器尚未初始化");
         app->initCapture(false);
      }
      try {
         //修正L2的数据
@@ -531,43 +563,144 @@
         string code = root["data"]["code"].asString();
         double min_price = root["data"]["min_price"].asDouble();
         double max_price = root["data"]["max_price"].asDouble();
         list<TradeData> dataList = app->capture->captureLevel2TradeData(CaptureUtil::capture(index, CAPTURE_TYPE_L2), index);
         cout << index << ":" << code << ":" << min_price << ":" << max_price << endl;
         app->thsL2RepairTool->repairL2Data(recognitionManager, index, code, min_price, max_price);
      }catch (string st) {
         throw st;
      }
   }
   else if (action == "getEnvState") {
         bool success = false;
         int retryCount = 0;
         while (!success)
         {
            if (retryCount > 3) {
               break;
            }
            //点击代码
            retryCount++;
            THSActionUtil::setListenL2GP(index, code, recognitionManager);
            Sleep(1);
            bool normal = true;
      app->initCapture(false);
            for (list<TradeData>::iterator ele = dataList.begin();ele != dataList.end();++ele) {
               double price = stod((*ele).price);
               if (price >= max_price + 0.0001) {
                  normal = false;
                  break;
               }
               else if (price <= min_price - 0.0001) {
                  normal = false;
                  break;
               }
            }
            cout << code << "-repairL2Data是否修复成功:" << normal << endl;
      ClientEnvState state;
            success = normal;
      //获取同花顺的环境
      HWND l2 = THSActionUtil::getL2Win();
      HWND second = THSActionUtil::getSecondWindow();
      HWND third = THSActionUtil::getThirdWindow();
      HWND trade_success = THSActionUtil::getTradeSuccessWindow();
      if (l2 > 0 && Win32Util::isWindowShow(l2)) {
         state.ths_l2_win = TRUE;
      }
      else {
         state.ths_l2_win = FALSE;
      }
      if (second > 0 && Win32Util::isWindowShow(second)) {
         state.ths_fp_1 = TRUE;
      }
      else {
         state.ths_fp_1 = FALSE;
      }
      if (third > 0 && Win32Util::isWindowShow(third)) {
         state.ths_fp_2 = TRUE;
      }
      else {
         state.ths_fp_2 = FALSE;
      }
      if (trade_success > 0 && Win32Util::isWindowShow(trade_success)) {
         state.ths_trade_success = TRUE;
      }
      else {
         state.ths_trade_success = FALSE;
      }
      //获取环境状态
      int l2_valid_count = 0;
      int l2_invalid_count = 0;
      for (int i = 0;i < THS_FRAME_COUNT;i++)
      {
         clock_t latestTime = TaskChecker::clientLiveTime.l2[i];
         if (clock() - latestTime > 5000) {
            //5s内不再活跃
            l2_invalid_count++;
         }
         else {
            l2_valid_count++;
         }
      }
      catch (...) {
         throw string("未知错误");
      state.l2_channel_valid_count = l2_valid_count;
      state.l2_channel_invalid_count = l2_invalid_count;
      if (clock() - TaskChecker::clientLiveTime.limitUp > 5000) {
         state.limitUp = false;
      }
      else {
         state.limitUp = true;
      }
      if (clock() - TaskChecker::clientLiveTime.tradeSuccess > 5000) {
         state.tradeSuccess = false;
      }
      else {
         state.tradeSuccess = true;
      }
      return JsonUtil::toJson(state);
   }
   return true;
   else if (action == "repairEnv") {
      app->initCapture(false);
      //同花顺环境修复
      app->OnBnClickedButton21();
      //l2采集环境修复
      for (int i = 0;i < THS_FRAME_COUNT;i++)
      {
         clock_t latestTime = TaskChecker::clientLiveTime.l2[i];
         if (clock() - latestTime > 5000) {
            //5s内不再活跃
            app->capture->reCreateChannelRunner(i);
         }
      }
      if (clock() - TaskChecker::clientLiveTime.tradeSuccess > 5000) {
         app->tradeListCapture->captureTradeSuccessInfo();
      }
      if (clock() - TaskChecker::clientLiveTime.limitUp > 5000) {
         app->limitUpCapture->reCreateRunning();
      }
   }
   else if (action == "syncTargetCodes") {
      Json::Value data = root["data"];
      list<string> codeList;
      for (int i = 0;i < data.size();i++) {
         string code = data[i].asString();
         codeList.push_back(code);
      }
      THSActionUtil::addTargetCodes(codeList, app->recognitionManager);
   }
   return "";
}
string  CappDlg::OnActionCallback(string data, void* context) {
   Json::Value root;
   try {
      string result = OnActionProcess(data, context);
      root["code"] = 0;
      root["data"] = result;
   }
   catch (string st) {
      root["code"] = 1;
      root["msg"] = st;
   }
   catch (...) {
      root["code"] = 2;
      root["msg"] = "未知错误";
   }
   return  JsonUtil::jsonValue2String(root);
}
//心跳信号
@@ -575,24 +708,36 @@
   //5s一次心跳
   while (true)
   {
      MEMORYSTATUS ms;
      ::GlobalMemoryStatus(&ms);
      DWORD mer = ms.dwMemoryLoad;
      cout << "内存使用率:" << mer << endl;
      if (clientNum >= 0)
      {
         //用户已经登录
         MEMORYSTATUS ms;
         ::GlobalMemoryStatus(&ms);
         DWORD mer = ms.dwMemoryLoad;
         cout << "内存使用率:" << mer << endl;
      try {
         string msg = JsonUtil::loadHeartbeatData(clientNum,to_string(mer));
         SocketManager::sendMsg(msg.c_str());
         //cout << "心跳信号" << endl;
      }
      catch (...) {
         cout << "心跳信号异常" << endl;
         //获取当前进程的内存使用情况
         HANDLE handle = GetCurrentProcess();
         PROCESS_MEMORY_COUNTERS pmc;
         GetProcessMemoryInfo(handle, &pmc, sizeof(pmc));
         float memoryUsage_M = pmc.WorkingSetSize / (1024.0 * 1024.0);
         string ownMemory = to_string(memoryUsage_M);
         ownMemory.append("MB");
         try {
            string msg = JsonUtil::loadHeartbeatData(clientNum, to_string(mer), ownMemory);
            SocketManager::sendMsg(msg.c_str());
            //cout << "心跳信号" << endl;
         }
         catch (...) {
            cout << "心跳信号异常" << endl;
         }
      }
      Sleep(5000);
   }
}
void CappDlg::initCapture()
void CappDlg::initCapture(bool notify)
{
   if (!capture->isInited())
   {
@@ -600,21 +745,141 @@
         capture->init(OnL2DataCallback, OnTradeQueueDataCallback, this);
      }
      catch (string st) {
         CString msg(st.c_str());
         AfxMessageBox(msg);
         if (notify)
         {
            CString msg(st.c_str());
            AfxMessageBox(msg);
         }
      }
   }
   if (!limitUpCapture->isInited())
   {
      try {
         limitUpCapture->init(OnLimitUpDataCallback, this);
      }
      catch (string st) {
         if (notify)
         {
            CString msg(st.c_str());
            AfxMessageBox(msg);
         }
      }
   }
   if (!tradeListCapture->isInited())
   {
      try {
         tradeListCapture->init(OnTradeSuccessDataCallback, OnTradeDelegateDataCallback, this);
      }
      catch (string st) {
         if (notify)
         {
            CString msg(st.c_str());
            AfxMessageBox(msg);
         }
      }
   }
   if (!currentPriceCapture->isInited())
   {
      try {
         currentPriceCapture->init(OnCurrentPriceCallback, this);
      }
      catch (string st) {
         if (notify)
         {
            CString msg(st.c_str());
            AfxMessageBox(msg);
         }
      }
   }
}
void CappDlg::checkTHSEnv(CappDlg *app)
{
   try {
      THSActionUtil::checkEnv();
   }
   catch (string e) {
      //打开同花顺的所有屏幕
      try {
         THSActionUtil::openL2Screen();
         THSActionUtil::openSecondScreen();
         Sleep(1000);
         THSActionUtil::openThirdScreen();
         Sleep(1000);
      }
      catch (...) {
      }
   }
      HWND l2 = THSActionUtil::getL2Win();
      if (l2 > 0)
      {
         Win32Util::showWindow(l2);
         //初始化l2的各个窗口句柄
         app->capture->refreshHWND();
      }
      HWND  second = THSActionUtil::getSecondWindow();
      if (second <= 0) {
         throw string("同花顺副屏1未打开");
      }
      Win32Util::showWindow(second);
      HWND  third = THSActionUtil::getThirdWindow();
      if (third <= 0) {
         throw string("同花顺副屏2未打开");
      }
      Win32Util::showWindow(third);
      //设置
      DEVMODE device = Win32Util::getL2ScreenInfo();
      int device_width = device.dmPelsWidth;
      int device_height = device.dmPelsHeight;
      POINTL device_pos = device.dmPosition;
      //最大化L2
      Win32Util::moveWin(l2, device_pos.x, device_pos.y, device_width, device_height);
      //将副屏1与副屏2缩小为屏幕的一半
      Win32Util::moveWin(second, device_pos.x, device_pos.y + device_height / 2, device_width / 2 - 50, device_height / 2);
      Win32Util::moveWin(third, device_pos.x + device_width / 2 + 30, device_pos.y + device_height / 2, device_width / 2 - 50, device_height / 2);
}
void CappDlg::autoStartL2(void* context)
{
   Sleep(1500);
   CappDlg* app =(CappDlg*) context;
   CappDlg* app = (CappDlg*)context;
   app->autoMsgStatic.SetWindowTextW(_T("开始检测同花顺环境..."));
   //点击检查同花顺
   app->OnBnClickedButton21();
   for (int i = 0;i < 10;i++)
   {
      try {
         checkTHSEnv(app);
         app->autoMsgStatic.SetWindowTextW(_T("同花顺环境检测通过..."));
         break;
      }
      catch (string st) {
         Sleep(2000);
         CString msg(st.c_str());
         app->autoMsgStatic.SetWindowTextW(msg);
      }
   }
   Sleep(1000);
   app->autoMsgStatic.SetWindowTextW(_T("开始启动L2行情识别..."));
   //启动L2行情识别
   app->OnBnClickedButton5();
   app->autoMsgStatic.SetWindowTextW(_T("L2行情识别启动完成..."));
   //启动交易成功识别
   app->OnBnClickedButtonTrade();
   //启动涨停识别
@@ -1184,19 +1449,7 @@
   catch (string e) {
      //打开同花顺的所有屏幕
      try {
         HWND l2 = THSActionUtil::getL2Win();
         if (l2 <= 0) {
            //尝试打开主屏
            HWND main = THSActionUtil::getMainWin();
            if (main > 0)
            {
               Win32Util::focus(main);
               Win32Util::keyboardNum(".00", 200);
               Win32Util::keyboard(13, 10);
               Sleep(1000);
            }
         }
         THSActionUtil::openL2Screen();
         THSActionUtil::openSecondScreen();
         Sleep(1000);
         THSActionUtil::openThirdScreen();
@@ -1214,6 +1467,8 @@
      if (l2 > 0)
      {
         Win32Util::showWindow(l2);
         //初始化l2的各个窗口句柄
         capture->refreshHWND();
      }
      HWND  second = THSActionUtil::getSecondWindow();
@@ -1259,7 +1514,17 @@
   try {
      //刷新L2窗口句柄
      capture->refreshHWND();
      //刷新涨停句柄
   }
   catch (string e) {
      CString msg(e.c_str());
      AfxMessageBox(msg);
   }
   catch (...) {
      AfxMessageBox(_T("未知错误"));
   }
   try {
      //刷新L2窗口句柄
      limitUpCapture->refreshHWND();
   }
   catch (string e) {
@@ -1275,10 +1540,12 @@
//退出登录
void CappDlg::OnBnClickedLogoutBtn()
{
   clientNum = -1;
   SendMessage(WM_CLOSE);
   loginDlg dlg(this);
   dlg.setReLogin(true);
   dlg.DoModal();
   dlg.DoModal();
}
@@ -1294,3 +1561,35 @@
   }
   Tool::saveSettings("setting.txt", settings);
}
//线价识别
void CappDlg::OnBnClickedCurrentPrice()
{
   if (!currentPriceCapture->isInited()) {
      try {
         currentPriceCapture->init(OnCurrentPriceCallback, this);
      }
      catch (string e) {
         CString msg(e.c_str());
         AfxMessageBox(msg);
      }
   }
   if (currentPriceCapture->isRunning()) {
      currentPriceCapture->stop();
      currentPriceBtn.SetWindowTextW(_T("启动现价识别"));
   }
   else {
      try {
         currentPriceCapture->refreshHWND();
      }
      catch (string e) {
         CString msg(e.c_str());
         AfxMessageBox(msg);
      }
      currentPriceCapture->start();
      currentPriceBtn.SetWindowTextW(_T("暂停现价识别"));
   }
}