admin
2024-07-05 3ef188e6075649f4c72e3e7588d8966e1071f2ff
DelegateQueue/MainFrame.cpp
@@ -31,6 +31,10 @@
   CLICK_TYPE_QUEUE,
};
struct ViewDetailData {
   string code;
};
// 委托信息数据
class DelegateInfoRenderer : public wxDataViewCustomRenderer
@@ -44,7 +48,7 @@
   map<wxString, wxRect> cancelBtnRectMap;
   map<wxString, wxRect> queueRectMap;
   map<wxString, wxRect> gridPostionMap;
public:
   /*static void addDelegateInfo(DelegateInfo info) {
      delegateMap[info.id] = info;
@@ -55,8 +59,8 @@
   wxString floatToString(float value) {
      std::ostringstream ss;
       ss << std::fixed << std::setprecision(2) << std::round(value * 100) / 100;
       return ss.str();
      ss << std::fixed << std::setprecision(2) << std::round(value * 100) / 100;
      return ss.str();
   }
   void loadContent() {
@@ -72,8 +76,8 @@
         colorInfo0.color = *wxRED;
         delegateColors.push_back(colorInfo0);
      }
      delegateInfoStr.Append("笔 ");
      ColorIndexInfo colorInfo1;
@@ -85,10 +89,18 @@
         delegateColors.push_back(colorInfo1);
      }
      delegateInfoStr.Append("/").Append("封单").Append(delegateInfo.buy1_money);
      delegateInfoStr.Append(" 【比例: ").Append(floatToString(delegateInfo.trade_progress_percent)).Append("%").Append("】,");
      delegateInfoStr.Append(" 【比例: ");
      ColorIndexInfo colorInfo2;
      colorInfo2.start_index = delegateInfoStr.Length();
      delegateInfoStr.Append(floatToString(delegateInfo.trade_progress_percent)).Append("%");
      colorInfo2.end_index = delegateInfoStr.Length() - 1;
      colorInfo2.color = wxColor(206, 14, 95);
      delegateColors.push_back(colorInfo2);
      delegateInfoStr.Append("】,");
      delegateInfoStr.Append("已成大单").Append(to_string(delegateInfo.big_num_count)).Append("笔").Append(delegateInfo.big_num_money).Append("  ");
@@ -108,13 +120,25 @@
      delegateInfoStr.Append("笔").Append(delegateInfo.not_deal_big_num_money_after).Append(",");
      delegateInfoStr.Append("涨停价:").Append(floatToString(delegateInfo.limit_up_price)).Append("元").Append(",");
      delegateInfoStr.Append(delegateInfo.block);
      delegateInfoStr.Append("涨停价:");
      ColorIndexInfo colorInfo3;
      colorInfo3.start_index = delegateInfoStr.Length();
      delegateInfoStr.Append(floatToString(delegateInfo.limit_up_price)).Append("Ԫ");
      colorInfo3.end_index = delegateInfoStr.Length();
      if (delegateInfo.limit_up_price < 3) {
         colorInfo3.color = *wxRED;
         delegateColors.push_back(colorInfo3);
      }
      delegateInfoStr.Append(",");
      delegateInfoStr.Append(delegateInfo.block).Append(",");
      delegateInfoStr.Append(" 涨停时间:").Append(delegateInfo.limit_up_time);
   }
   float parseMoneyAsW(wxString st) {
      wxString money= st;
      if (st.Find("万")>=0) {
      wxString money = st;
      if (st.Find("万") >= 0) {
         money = st.Mid(0, st.Find("万"));
         double d;
         money.ToDouble(&d);
@@ -124,7 +148,7 @@
         money = st.Mid(0, st.Find("亿"));
         double d;
         money.ToDouble(&d);
         return d*10000;
         return d * 10000;
      }
      else {
         double d;
@@ -136,35 +160,39 @@
   void drawOperateLine(wxDC* dc, int startx, int starty, int line_width) {
      //绘制红点
      /*  wxFont font(dc->GetFont().GetPixelSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT), wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);*/
      // 绘制名字
      wxString codeName = "";
      codeName.Append(delegateInfo.code).Append("(").Append(delegateInfo.codeName).Append(")");
      wxString codeInfo = "";
      codeInfo.Append(delegateInfo.code).Append("(").Append(delegateInfo.codeName).Append(")");
      WidgetsRenderUtil::drawText(dc, codeName, wxPoint(startx, starty + 3),line_width, TEXT_LINE_HEIGHT);
      codeInfo.Append("  ").Append(delegateInfo.zyltgb);
      if (delegateInfo.pay_attention) {
         wxSize textSize = dc->GetTextExtent(codeName);
         WidgetsRenderUtil::drawText(dc, "****", wxPoint(startx + textSize.GetWidth() + 5*DPI/100, starty + 5*DPI/100), line_width, TEXT_LINE_HEIGHT, std::list<ColorIndexInfo>(), *wxRED);
         WidgetsRenderUtil::drawText(dc, codeInfo, wxPoint(startx, starty + 3), line_width, TEXT_LINE_HEIGHT, std::list<ColorIndexInfo>(), *wxRED);
         wxSize textSize = dc->GetTextExtent(codeInfo);
         WidgetsRenderUtil::drawText(dc, "****", wxPoint(startx + textSize.GetWidth() + 5 * DPI / 100, starty + 5 * DPI / 100), line_width, TEXT_LINE_HEIGHT, std::list<ColorIndexInfo>(), *wxRED);
      }
      else {
         WidgetsRenderUtil::drawText(dc, codeInfo, wxPoint(startx, starty + 3), line_width, TEXT_LINE_HEIGHT);
      }
      // 绘制按钮
      dc->SetPen(wxColour(225, 225, 225));
      dc->SetBrush(wxColour(225, 225, 225));
      int btnWidth = 50*DPI/100;
      int btnHeight = 25*DPI/100;
      int padding = 10*DPI/100;
      int btnWidth = 50 * DPI / 100;
      int btnHeight = 25 * DPI / 100;
      int padding = 10 * DPI / 100;
      viewBtnRectMap[delegateInfo.id] = wxRect({ startx + line_width - btnWidth, starty, btnWidth, btnHeight });
      WidgetsRenderUtil::drawBtn(dc, "查看", viewBtnRectMap[delegateInfo.id], *wxWHITE, wxColour(0, 150, 136));
      // 相邻的撤单错位显示
      cancelBtnRectMap[delegateInfo.id] = wxRect({ startx + line_width - viewBtnRectMap[delegateInfo.id].GetWidth() - btnWidth - padding - (delegateInfo.index%2==0?0: btnWidth + 5*DPI/100), starty, btnWidth, btnHeight });
      cout << "撤单位置渲染:"<< delegateInfo.index << " - "<< cancelBtnRectMap[delegateInfo.id].x << ":" << cancelBtnRectMap[delegateInfo.id].y <<endl;
      cancelBtnRectMap[delegateInfo.id] = wxRect({ startx + line_width - viewBtnRectMap[delegateInfo.id].GetWidth() - btnWidth - padding - (delegateInfo.index % 2 == 0 ? 0 : btnWidth + 5 * DPI / 100), starty, btnWidth, btnHeight });
      cout << "撤单位置渲染:" << delegateInfo.index << " - " << cancelBtnRectMap[delegateInfo.id].x << ":" << cancelBtnRectMap[delegateInfo.id].y << endl;
      WidgetsRenderUtil::drawBtn(dc, "撤单", cancelBtnRectMap[delegateInfo.id], *wxWHITE, wxColour(255, 87, 34));
   }
@@ -179,7 +207,7 @@
      //gc->SetFont(font,*wxRED);
      wxSize queueSize(43*DPI/100, 22*DPI/100);
      wxSize queueSize(43 * DPI / 100, 22 * DPI / 100);
      // 绘制背景颜色
      wxRect queueRect = wxRect(start, wxSize(line_width, queueSize.y));
@@ -190,7 +218,7 @@
      queueRectMap[delegateInfo.id] = queueRect;
      int padding = 5*DPI/100;
      int padding = 5 * DPI / 100;
      int countPerLine = (line_width - padding) / (queueSize.x + padding);
@@ -275,12 +303,12 @@
   virtual bool Render(wxRect cell, wxDC* dc, int state)
   {
      cout <<"内存地址:"<< this << endl;
      cout << "内存地址:" << this << endl;
      dc->Clear();
      dc->SetUserScale(1,1);
      dc->SetUserScale(1, 1);
      gridPostionMap[delegateInfo.id] = wxRect(cell.GetPosition(), cell.GetSize());
      //// 设置绘制按钮的位置和大小
@@ -292,14 +320,14 @@
      loadContent();
      int start_y = cell.GetPosition().y + 3*DPI/100;
      int start_y = cell.GetPosition().y + 3 * DPI / 100;
      int start_x = cell.GetPosition().x;
      // 绘制操作区域
      drawOperateLine(dc, start_x, start_y, cell.GetSize().GetWidth());
      // 绘制简介区
      int infoWidth = cell.GetSize().GetWidth();
      int infoHeight = WidgetsRenderUtil::drawText(dc, delegateInfoStr, wxPoint(start_x, start_y + 25*DPI/100), infoWidth, TEXT_LINE_HEIGHT, delegateColors);
      int infoHeight = WidgetsRenderUtil::drawText(dc, delegateInfoStr, wxPoint(start_x, start_y + 25 * DPI / 100), infoWidth, TEXT_LINE_HEIGHT, delegateColors);
      // 绘制队列,给文字信息留3排左右的位置
      drawDelegateQueue(dc, wxPoint(start_x, TEXT_LINE_HEIGHT * 3 + start_y + 30 * DPI / 100), infoWidth);
@@ -309,25 +337,25 @@
   }
   void cancelOrder(string code) {
    string results =   MyNetworkApi::cancel_order(code);
    auto doc = JsonUtil::parseUTF16(results);
    if (doc.IsObject()) {
       if (doc[L"code"].GetInt() == 0) {
          showMsg(wxString(delegateInfo.codeName).Append(":撤单提交成功").ToStdString(), MSG_TYPE_INFO);
          MainFrame* mainFrame = getWindowFrame();
          if (mainFrame) {
             mainFrame->requestDelegatedInfoList();
          }
       }
       else {
          showMsg(wxString(doc[L"msg"].GetString()).ToStdString(), MSG_TYPE_WARNING);
       }
    }
    else {
       showMsg("网络请求失败", MSG_TYPE_ERROR);
    }
      string results = MyNetworkApi::cancel_order(code);
      auto doc = JsonUtil::parseUTF16(results);
      if (doc.IsObject()) {
         if (doc[L"code"].GetInt() == 0) {
            showMsg(wxString(delegateInfo.codeName).Append(":撤单提交成功").ToStdString(), MSG_TYPE_INFO);
            MainFrame* mainFrame = getWindowFrame();
            if (mainFrame) {
               mainFrame->requestDelegatedInfoList();
            }
         }
         else {
            showMsg(wxString(doc[L"msg"].GetString()).ToStdString(), MSG_TYPE_WARNING);
         }
      }
      else {
         showMsg("网络请求失败", MSG_TYPE_ERROR);
      }
   }
@@ -345,11 +373,32 @@
      }
   }
   void showMsg(string msg,MsgTypeEnum type) {
   void showMsg(string msg, MsgTypeEnum type) {
      MainFrame* mainFrame = getWindowFrame();
      if (mainFrame)
      {
         mainFrame->showMsg(msg, type);
      }
   }
   /// <summary>
   /// 查看详情
   /// </summary>
   /// <param name="code"></param>
   static void viewDetail(wxString code) {
      try {
         Win32Util::addToTHS(code.ToStdString());
         list<HWND> hwnds = Win32Util::searchWindow("看盘副屏");
         if (hwnds.size() > 0) {
            for (list<HWND>::iterator e = hwnds.begin(); e != hwnds.end(); ++e) {
               HWND hwnd = *e;
               ViewDetailData* data = new ViewDetailData();
               data->code = code.ToStdString();
               SendMessage(hwnd, WM_USER + 1024, 0, reinterpret_cast<LPARAM>(&data));
            }
         }
      }
      catch (...) {
      }
   }
@@ -362,13 +411,13 @@
         switch (clickType)
         {
         case CLICK_TYPE_CANCEL_BUY:
            cancelOrder(delegateInfo.code.ToStdString());
            break;
         case CLICK_TYPE_VIEW_DETAIL:
            try {
               Win32Util::addToTHS(delegateInfo.code.ToStdString());
               thread t(viewDetail, delegateInfo.code);
               t.detach();
            }
            catch (string msg) {
               wxMessageBox(msg.c_str());
@@ -377,12 +426,12 @@
         default:
            break;
         }
      }
      }
      if (mouseEvent->LeftDClick()) {
         BtnClickType clickType = getClickType(mouseEvent->GetX(), mouseEvent->GetY());
         if (clickType == CLICK_TYPE_QUEUE)
         {
            WindowPosSize r = MyConfigUtil::getTradeQueueWindowPos();
            if (r.x == -1 && r.y == -1 && r.width == -1 && r.height == -1) {
               // 默认的尺寸与位置
@@ -390,11 +439,11 @@
               RECT rect;
               Win32Util::getWindowRect(framePos, &rect);
               TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(rect.left, rect.top), wxSize(350,400));
               TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(rect.left, rect.top), wxSize(350, 400));
               tradeQueueFrame->Show(true);
            }
            else {
               TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(r.x,r.y), wxSize(r.width, r.height));
               TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(r.x, r.y), wxSize(r.width, r.height));
               tradeQueueFrame->Show(true);
            }
            // 默认查看
@@ -406,7 +455,7 @@
            }
         }
      }
@@ -435,7 +484,8 @@
MainFrame::MainFrame(const wxString& title, wxPoint position, wxSize size) :wxFrame(NULL, wxID_ANY, title, position, size) {
   // 置顶
   SetWindowStyle(GetWindowStyle() | wxSTAY_ON_TOP);
   // 初始化
   killed = false;
   Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnClose, this);
@@ -445,20 +495,19 @@
   SetTransparent(225);
   SetWindowStyle(GetWindowStyle() | wxSTAY_ON_TOP);
   wxPanel* panel = new wxPanel(this, wxID_ANY);
   // 创建 wxDataViewListCtrl 控件
    m_listCtrl = new wxDataViewListCtrl(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize,  wxDV_SINGLE| wxDV_NO_HEADER);
    m_listCtrl->SetBackgroundColour(wxColor(242, 242, 242));
    // 绑定没行的选中事件
    m_listCtrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MainFrame::OnSelectionChanged, this);
   m_listCtrl = new wxDataViewListCtrl(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_SINGLE | wxDV_NO_HEADER);
   m_listCtrl->SetBackgroundColour(wxColor(242, 242, 242));
   // 绑定没行的选中事件
   m_listCtrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MainFrame::OnSelectionChanged, this);
   // 添加列
   auto bc = new DelegateInfoRenderer();
   wxDataViewColumn *delegateColumn =  new wxDataViewColumn("委托信息", bc, 0, ROW_WIDTH_DELEGATE_INFO, wxALIGN_LEFT);
   wxDataViewColumn* delegateColumn = new wxDataViewColumn("委托信息", bc, 0, ROW_WIDTH_DELEGATE_INFO, wxALIGN_LEFT);
   m_listCtrl->AppendColumn(delegateColumn);
@@ -468,22 +517,26 @@
   wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
   // 提示信息
   msgCtrl = new wxStaticText(panel,wxID_ANY,"");
   msgCtrl = new wxStaticText(panel, wxID_ANY, "");
   wxButton *openTradeQueueBtn =new wxButton(panel, wxID_ANY,"查看全部");
   wxButton* openTradeQueueBtn = new wxButton(panel, wxID_ANY, "查看全部");
   wxBoxSizer *topSizer=new wxBoxSizer(wxHORIZONTAL);
   avaiableMoneyLabel = new wxStaticText(panel, wxID_ANY, "0.00", wxDefaultPosition, wxSize(80 * DPI / 100, -1));
   wxBoxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
   topSizer->Add(msgCtrl, 1, wxEXPAND);
   topSizer->Add(avaiableMoneyLabel, 0, wxEXPAND | wxALL, 3);
   topSizer->Add(openTradeQueueBtn, 0);
   sizer->Add(topSizer, 0, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 5);
   sizer->Add(topSizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 5);
   sizer->Add(m_listCtrl, 1, wxEXPAND | wxALL, 5);
   panel->SetSizerAndFit(sizer);
   openTradeQueueBtn->Bind(wxEVT_BUTTON, &MainFrame::OnButtonOpenTradeQueueClick,this);
   openTradeQueueBtn->Bind(wxEVT_BUTTON, &MainFrame::OnButtonOpenTradeQueueClick, this);
   std::thread t1(startRequestDelegatedInfoListTask, this);
@@ -515,9 +568,9 @@
}
void MainFrame::clearMsg( MainFrame* context)
void MainFrame::clearMsg(MainFrame* context)
{
   Sleep(15* 1000);
   Sleep(15 * 1000);
   if (TimeUtil::getNowTimeStamp() > context->msgExpireTime) {
      context->msgCtrl->SetLabelText("");
   }
@@ -533,6 +586,7 @@
void MainFrame::refresh()
{
   cout << "刷新时间:" << TimeUtil::getNowTimeStamp() << " 数量:" << delegateList.size() << endl;
   m_listCtrl->DeleteAllItems();
   for (list<DelegateInfo>::iterator e = delegateList.begin(); e != delegateList.end(); ++e) {
      DelegateInfo info = *e;
@@ -541,17 +595,19 @@
      data.push_back(info.id);
      m_listCtrl->AppendItem(data);
   }
   m_listCtrl->Refresh();
}
list<DelegateInfo> MainFrame::parseDelegates(string result)
DelegateResult MainFrame::parseDelegates(string result)
{
   list<DelegateInfo> fresults;
   wxString available_money = "";
   auto doc = JsonUtil::parseUTF16(result);
   if (doc.IsObject() && doc[L"code"].GetInt() == 0) {
      auto root = doc[L"data"].GetObject();
      auto delegates = root[L"delegates"].GetArray();
      auto money = root[L"account_available_money"].GetString();
      double money = root[L"account_available_money"].GetDouble();
      available_money = StringUtil::to_string(money);
      for (int i = 0; i < delegates.Size(); i++) {
         auto doc = delegates[i].GetObject();
@@ -582,15 +638,21 @@
         delegateInfo.limit_up_price = doc[L"limit_up_price"].GetFloat();
         delegateInfo.is_near_big_order = doc[L"is_near_big_order"].GetString();
         delegateInfo.block = doc[L"block"].GetString();
         if (doc.HasMember(L"limit_up_time")) {
            delegateInfo.limit_up_time = doc[L"limit_up_time"].GetString();
         }
         array=doc[L"trade_queue"].GetArray();
         array = doc[L"trade_queue"].GetArray();
         list<TradeQueue> queueList;
         for (int j = 0; j < array.Size(); j++) {
            int num = array[j].GetArray()[0].GetInt();
            int type = array[j].GetArray()[1].GetInt();
            queueList.push_back(TradeQueue({to_string(num),type}));
            queueList.push_back(TradeQueue({ to_string(num),type }));
         }
         delegateInfo.tradeQueueList = queueList;
         if (doc.HasMember(L"zyltgb"))
            delegateInfo.zyltgb = doc[L"zyltgb"].GetString();
         fresults.push_back(delegateInfo);
      }
@@ -598,45 +660,56 @@
   else {
      throw string("网络请求出错");
   }
   return fresults;
   return DelegateResult({ fresults ,available_money });
}
void MainFrame::startRequestDelegatedInfoListTask(MainFrame* context)
{
   while (TRUE) {
      if (context->killed) {
         break;
      }
      try {
         context->requestDelegatedInfoList();
      }
      catch (string st) {
         while (TRUE) {
            if (context->killed) {
               break;
            }
            try {
               context->requestDelegatedInfoList();
            }
            catch (string st) {
            }
            catch (...) {
            }
            Sleep(2000);
         }
      }
      catch (...) {
      }
      Sleep(2000);
   }
}
void MainFrame::requestDelegatedInfoList()
{
   try {
      cout <<"请求委托列表"<< endl;
      auto start_time = TimeUtil::getNowTimeStamp();
      string result = MyNetworkApi::get_delegated_buy_code_infos();
      if (killed) {
         return;
      }
      cout << "请求委托列表耗时:" << TimeUtil::getNowTimeStamp() - start_time << endl;
      start_time = TimeUtil::getNowTimeStamp();
      auto doc = JsonUtil::parseUTF8(result);
      auto delegateList = parseDelegates(result);
      auto delegateResult = parseDelegates(result);
      cout << "解析数据耗时:" << TimeUtil::getNowTimeStamp() - start_time << endl;
      start_time = TimeUtil::getNowTimeStamp();
      // 根据ID
      if (this != nullptr) {
         this->delegateList = delegateList;
         this->delegateList = delegateResult.delegates;
         this->avaiableMoneyLabel->SetLabelText(delegateResult.money);
         this->refresh();
         cout << "刷新UI耗时:" << TimeUtil::getNowTimeStamp() - start_time << endl;
      }
   }
   catch (string st) {
@@ -653,8 +726,7 @@
void MainFrame::OnButtonOpenTradeQueueClick(wxCommandEvent& event)
{
   if (delegateList.size()>0) {
   if (delegateList.size() > 0) {
      WindowPosSize r = MyConfigUtil::getTradeQueueWindowPos();
      if (r.x == -1 && r.y == -1) {
         r.x = 0;