admin
2024-10-18 8ea6d363df77de2dca288397da8d4f9c3d3a5c4d
'项目完善'
61个文件已修改
18个文件已添加
4066 ■■■■ 已修改文件
AndroidChannelPackage/AndroidChannelPackage.cpp 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
AndroidChannelPackage/AndroidChannelPackage.vcxproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
AndroidChannelPackage/AndroidChannelPackage.vcxproj.filters 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
AndroidChannelPackage/main.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/CBTrade.vcxproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/CBTrade.vcxproj.filters 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/DataParseUtil.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/DataStruct.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/JueJinDataUtil.cpp 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/JueJinDataUtil.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MainFrame.cpp 324 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MainFrame.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MyConfigUtil.cpp 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MyConfigUtil.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MyDataViewListCtrl.h 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MyNetworkApi.cpp 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/MyNetworkApi.h 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/TickChart.cpp 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/TickChart.h 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/ViewManager.cpp 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/ViewManager.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CBTrade/config.cfg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/DataStruct.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/DelegateQueue.vcxproj 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/MainFrame.cpp 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/MainFrame.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/MyNetworkApi.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/MyNetworkApi.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DelegateQueue/config.cfg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CBuyDlg.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CCBBuyDlg.cpp 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CCBBuyDlg.h 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CCodeNameDlg.cpp 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CCodeNameDlg.h 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CSettingDlg.cpp 418 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/CSettingDlg.h 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/ConfigUtil.cpp 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/ConfigUtil.h 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/Constant.cpp 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/Constant.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/DataStruct.h 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTrade.aps 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTrade.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTrade.rc 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTrade.vcxproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTrade.vcxproj.filters 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTradeDlg.cpp 708 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/FloatTradeDlg.h 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/MyApi.h 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/SellRuleDlg.cpp 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/SellRuleDlg.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/SellStruct.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/ThsUtil.cpp 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/ThsUtil.h 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/config.cfg 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/packages.config 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FloatTrade/resource.h 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Monitor/Monitor.aps 补丁 | 查看 | 原始文档 | blame | 历史
Monitor/Monitor.rc 补丁 | 查看 | 原始文档 | blame | 历史
Monitor/MonitorDlg.cpp 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Monitor/MonitorDlg.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Monitor/resource.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Setup/Setup.vdproj 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SetupCBTrade/SetupCBTrade.vdproj 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
TradeDesk.sln 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
TradeRecord/ConfigUtil.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/NetworkApi.cpp 207 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/NetworkApi.h 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/StringUtil.h 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common_nopch/NetworkApi.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
common_nopch/TimeUtil.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/.signature.p7s 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/build/configurations.autopkg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/build/native/default-propertiesui.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/build/native/include/iconv.h 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/build/native/libiconv.lib-propertiesui-8226f8b4-4a12-413f-938e-c8190803e882.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/build/native/libiconv.lib.targets 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/build/publisher-info.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/libiconv.lib.1.16.0.6/libiconv.lib.1.16.0.6.nupkg 补丁 | 查看 | 原始文档 | blame | 历史
AndroidChannelPackage/AndroidChannelPackage.cpp
@@ -160,7 +160,7 @@
}
int main(int argc, char* argv[])
int main1(int argc, char* argv[])
{
    //apk文件地址 渠道英文逗号分隔 签名文件地址 密码 别名 别名密码
    //
@@ -173,7 +173,16 @@
    }
    else {
    //测试
        package("E:\\WXWork\\1688855861247320\\Cache\\File\\2024-06\\影视大全_3.10.27_release_64_32.apk", "qq,huawei", "D:\\项目\\影音\\签名\\doudouvideo.jks", "weikou2015", "豆豆", "weikou2015");
      /*  package("E:\\WXWork\\1688855861247320\\Cache\\File\\2024-06\\影视大全_3.10.27_release_64_32.apk", "qq,huawei", "D:\\项目\\影音\\签名\\doudouvideo.jks", "weikou2015", "豆豆", "weikou2015");*/
        int a[8] = { 12,15,20,8,5,9,16,10 };
        int i, j, x = a[0] + a[1];
        for (i = 0; i < 8; i++)
            for (j = i + 1; j < 8; j++)
                if (a[i] + a[j] > x) x = a[i] + a[j];
        printf("%d ", x);
    }
    return 0;
}
AndroidChannelPackage/AndroidChannelPackage.vcxproj
@@ -141,6 +141,7 @@
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="AndroidChannelPackage.cpp" />
    <ClCompile Include="main.cpp" />
    <ClCompile Include="tinyxml2.cpp" />
  </ItemGroup>
  <ItemGroup>
AndroidChannelPackage/AndroidChannelPackage.vcxproj.filters
@@ -21,6 +21,9 @@
    <ClCompile Include="tinyxml2.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="main.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="packages.config" />
AndroidChannelPackage/main.cpp
New file
@@ -0,0 +1,14 @@
#include<stdio.h>
#include <wtypes.h>
#include <iostream>
#define N 4
using namespace std;
int main(int argc, char* argv[]) {
    HWND hwmd = HWND(0x00041504);
    const int bufferSize = 6;
    WCHAR buffer[bufferSize];
    LRESULT result =  SendMessage(hwmd, WM_GETTEXT, bufferSize, (LPARAM)buffer);
    wstring st = std::wstring(buffer).c_str();
    std::wcout<<L"读取到的内容:" << st << std::endl;
}
CBTrade/CBTrade.vcxproj
@@ -191,6 +191,7 @@
    <ClInclude Include="JueJInSettingFrame.h" />
    <ClInclude Include="MainFrame.h" />
    <ClInclude Include="MyConfigUtil.h" />
    <ClInclude Include="MyDataViewListCtrl.h" />
    <ClInclude Include="MyNetworkApi.h" />
    <ClInclude Include="TickChart.h" />
    <ClInclude Include="TickDataRequestStrategy.h" />
CBTrade/CBTrade.vcxproj.filters
@@ -140,6 +140,9 @@
    <ClInclude Include="BlinkingMessageDialog.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="MyDataViewListCtrl.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <None Include="packages.config" />
CBTrade/DataParseUtil.h
@@ -105,6 +105,13 @@
                            dealInfo.price = item[L"price"].GetString();
                            dealInfo.tradeTime = item[L"tradeTime"].GetString();
                            dealInfo.volume = item[L"volume"].GetInt();
                            if (item.HasMember(L"type")) {
                                dealInfo.type = item[L"type"].GetInt();
                            }
                            else {
                                // 默认为1
                                dealInfo.type = 1;
                            }
                            buyList.push_back(dealInfo);
                        }
                        position.buyList = buyList;
CBTrade/DataStruct.h
@@ -30,6 +30,7 @@
    wxString tradeTime;// 成交时间
    wxString price;// 成交价
    int volume;//成交量
    int type;
};
CBTrade/JueJinDataUtil.cpp
@@ -25,7 +25,14 @@
}
DataArray<Bar>* JueJinDataUtil::getBarDatas(std::string symbol, std::string startTime, std::string endTime, std::string frequency) {
    DataArray<Bar>* bars = history_bars(symbol.c_str(), frequency.c_str(), startTime.c_str(), endTime.c_str(), 1);
    return bars;
}
}
Tick JueJinDataUtil::currentTick(std::string symbol)
{
    DataArray<Tick>* ticks =    current(symbol.c_str());
    return ticks->at(0);
}
CBTrade/JueJinDataUtil.h
@@ -14,4 +14,6 @@
    static DataArray<Tick>* getTickDatas(std::string symbol, std::string startTime,std::string endTime);
    static DataArray<Bar>* getBarDatas(std::string symbol, std::string startTime, std::string endTime, std::string frequency="60s");
    static Tick currentTick(std::string symbol);
};
CBTrade/MainFrame.cpp
@@ -34,7 +34,7 @@
    SetIcon(icon);
    //SetTransparent(225);
    viewManager = new ViewManager();
    viewManager->initView(this);
@@ -44,7 +44,7 @@
    initTask();
    Bind(wxEVT_SHOW, [this](wxShowEvent& event) {
        this->SetWindowStyleFlag(GetWindowStyleFlag() | wxSTAY_ON_TOP);
    });
        });
    this->SetWindowStyleFlag(GetWindowStyleFlag() | wxSTAY_ON_TOP);
}
@@ -83,8 +83,7 @@
            wxMessageBox("输入格式错误");
            return;
        }
        MyConfigUtil::setSellMoney(stoi(value.c_str()));
        wxMessageBox("锁定卖出金额成功");
        lockSellVolume();
    }
@@ -105,8 +104,141 @@
        sellBtn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
            wxButton* btn = (wxButton*)event.GetEventObject();
            this->viewManager->sellWidgets->sellMoney->SetLabelText(btn->GetLabelText());
            // 锁定量
            if (this->viewManager->sellWidgets->sellLock->IsChecked()) {
                lockSellVolume();
            }
            });
    }
    viewManager->sellWidgets->openTrade->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        try {
            string result = MyNetworkApi::set_trade_state(1);
            auto doc = JsonUtil::parseUTF16(result);
            if (doc.IsObject()) {
                if (doc[L"code"] == 0) {
                    this->setTradeStateView(1);
                }
                else {
                    throw wstring(doc[L"msg"].GetString());
                }
            }
            else {
                throw wstring(L"网络请求失败");
            }
        }
        catch (wstring st) {
            wxMessageBox(st);
        }
    });
    viewManager->sellWidgets->closeTrade->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        try {
            string result = MyNetworkApi::set_trade_state(0);
            auto doc = JsonUtil::parseUTF16(result);
            if (doc.IsObject()) {
                if (doc[L"code"] == 0) {
                    this->setTradeStateView(0);
                }
                else {
                    throw wstring(doc[L"msg"].GetString());
                }
            }
            else {
                throw wstring(L"网络请求失败");
            }
        }
        catch (wstring st) {
            wxMessageBox(st);
        }
        });
    viewManager->sellWidgets->addWantBuy->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        try {
            wxString code = this->viewManager->topWidgets->codeEdit->GetValue();
            if (code.Length() != 6) {
                throw wstring(L"代码格式错误");
            }
            string result = MyNetworkApi::add_want_buy_code(code.ToStdString());
            auto doc = JsonUtil::parseUTF16(result);
            if (doc.IsObject()) {
                if (doc[L"code"] == 0) {
                    wxMessageBox("添加成功");
                }
                else {
                    throw wstring(doc[L"msg"].GetString());
                }
            }
            else {
                throw wstring(L"网络请求失败");
            }
        }
        catch (wstring st) {
            wxMessageBox(st);
        }
        });
    viewManager->sellWidgets->removeWantBuy->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        try {
            wxString code = this->viewManager->topWidgets->codeEdit->GetValue();
            if (code.Length() != 6) {
                throw wstring(L"代码格式错误");
            }
            string result = MyNetworkApi::remove_want_buy_code(code.ToStdString());
            auto doc = JsonUtil::parseUTF16(result);
            if (doc.IsObject()) {
                if (doc[L"code"] == 0) {
                    wxMessageBox("移除成功");
                }
                else {
                    throw wstring(doc[L"msg"].GetString());
                }
            }
            else {
                throw wstring(L"网络请求失败");
            }
        }
        catch (wstring st) {
            wxMessageBox(st);
        }
        });
    viewManager->sellWidgets->wantBuyList->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        try {
            string result = MyNetworkApi::list_want_buy_codes();
            auto doc = JsonUtil::parseUTF16(result);
            if (doc.IsObject()) {
                if (doc[L"code"] == 0) {
                    wxString st = "";
                    auto array = doc[L"data"].GetArray();
                    for (int i = 0; i < array.Size(); i++) {
                        st.Append(array[i].GetArray()[0].GetString());
                        st.Append("(");
                        st.Append(array[i].GetArray()[1].GetString());
                        st.Append(")");
                        if (i % 2 == 1) {
                            st.Append("\n");
                        }
                    }
                    wxMessageBox(st, "想买单");
                }
                else {
                    throw wstring(doc[L"msg"].GetString());
                }
            }
            else {
                throw wstring(L"网络请求失败");
            }
        }
        catch (wstring st) {
            wxMessageBox(st);
        }
        });
}
@@ -129,32 +261,46 @@
         wxAcceleratorEntry(wxACCEL_SHIFT, WXK_F10, 901),
         wxAcceleratorEntry(wxACCEL_CTRL, 'H', 902)
    };
    auto acceleratorTable = wxAcceleratorTable(2, entries);
    this->SetAcceleratorTable(acceleratorTable);
    this->Bind(wxEVT_MENU, [this](wxCommandEvent& event) {
        this->OnBtnSellClick(event);
    }, 901);
        }, 901);
    this->Bind(wxEVT_MENU, [this](wxCommandEvent& event) {
        for (std::list<PositionInfo>::iterator e = this->positionList.begin(); e != this->positionList.end(); e++) {
        PositionInfo info = *e;
        if (this->selectPositionId == info.id) {
            try {
                Sleep(200);
                CallAfter([info]() {
                    thread t(Win32Util::addToTHS, info.underlyingMarketInfo.code.ToStdString());
                    t.detach();
                });
            }
            catch (...) {
            PositionInfo info = *e;
            if (this->selectPositionId == info.id) {
                try {
                    Sleep(200);
                    CallAfter([info]() {
                        thread t(Win32Util::addToTHS, info.underlyingMarketInfo.code.ToStdString());
                        t.detach();
                        });
                }
                catch (...) {
                }
                break;
            }
            break;
        }
        }, 902);
    //-----------------------获取当前交易状态--------------------------
    try {
        string result = MyNetworkApi::get_trade_state();
        auto doc = JsonUtil::parseUTF8(result);
        if (doc.IsObject() && doc["code"].GetInt() == 0) {
            tradeState = doc["data"]["state"].GetInt();
            setTradeStateView(tradeState);
        }
    }
    }, 902);
    catch (...) {
    }
    // -----------------------卖出参数初始化--------------------------
@@ -191,26 +337,38 @@
    }
    requestCount += 1;
    std::list < PositionInfo> plist = DataParseUtil::parsePositionList(result);
    std::list<PositionInfo> plist = DataParseUtil::parsePositionList(result);
    if (plist.size() == 0) {
        string nowTime = TimeUtil::format(TimeUtil::getNowTimeStamp(), "%H%M%S");
        if (stoi(nowTime) < stoi("093000")) {
            MyConfigUtil::clearCodesSellMoney();
        }
    }
    //根据持仓排序,
    plist.sort([](PositionInfo p1, PositionInfo p2) {
        return p1.availablePosition == p2.availablePosition? p1.createTime > p2.createTime:  p1.availablePosition > p2.availablePosition;
    });
        int p1Int = p1.currentPosition > 0 ? 1 : 0;
        int p2Int = p2.currentPosition > 0 ? 1 : 0;
    if (requestCount>1&&this->orginPositionList.size() != plist.size()) {
        CallAfter([this]() {
                this->blinkingMessageDialog = new BlinkingMessageDialog(this, "可转债有新下单");
                this->blinkingMessageDialog->show();
        return p1Int == p2Int ? p1.createTime > p2.createTime:  p1Int > p2Int;
        });
    if (requestCount > 1 && this->orginPositionList.size() != plist.size()) {
        CallAfter([this]() {
            this->blinkingMessageDialog = new BlinkingMessageDialog(this, "可转债有新下单");
            this->blinkingMessageDialog->show();
            });
    }
    this->orginPositionList = plist;
    viewManager->positionWidgets->listCtrlReport->DeleteAllItems();
    // 按条件过滤
    std::list < PositionInfo> temList;
    for (std::list<PositionInfo>::iterator e = plist.begin(); e != plist.end(); ++e) {
@@ -232,12 +390,14 @@
        PositionInfo p = *e;
        //{ "名称", "涨幅", "现价", "L1现手", "剩余持仓", "持仓金额", "盈亏", "盈亏比", "正股名称", "更多" };
        wxVector<wxVariant> data;
        bool hasPosition = p.availablePosition > 0;
        wxColor color = !hasPosition ? COLOR_INVALID: COLOR_VALID;
        data.push_back(wxVariant(MyColorText(p.securityName, color)));
        bool hasPosition = p.currentPosition > 0;
        wxColor color = !hasPosition ? COLOR_INVALID : COLOR_VALID;
        map<int, wxVariant> dataMap;
        dataMap[0] = wxVariant(MyColorText(p.securityName, color));
        if (!hasPosition)
        {
            data.push_back(wxVariant(MyColorText(p.marketInfo.rate,color)));
            dataMap[1] = wxVariant(wxVariant(MyColorText(p.marketInfo.rate, color)));
        }
        else {
            wxString rateText = p.marketInfo.rate;
@@ -258,17 +418,19 @@
            else {
                tempColor = wxColor(64, 64, 64);
            }
            data.push_back(wxVariant(MyColorText(p.marketInfo.rate, tempColor)));
            dataMap[1] = (wxVariant(MyColorText(p.marketInfo.rate, tempColor)));
        }
        data.push_back(wxVariant(MyColorText(wxString(p.marketInfo.price),color)));
        data.push_back(wxVariant(MyColorText(p.marketInfo.lastVolume, color)));
        data.push_back(wxVariant(MyColorText(p.underlyingMarketInfo.rate, color)));
        dataMap[7] = (wxVariant(MyColorText(wxString(p.marketInfo.price), color)));
        // 获取卖额
        int sellMoney = MyConfigUtil::getSellMoney(p.securityID.ToStdString());
        dataMap[6] = (wxVariant(MyColorText(to_string(sellMoney), color)));
        dataMap[2] = wxVariant(MyColorText(p.underlyingMarketInfo.rate, color));
        if (!hasPosition)
        {
            data.push_back(wxVariant(MyColorText(p.underlyingMarketInfo.buy1Money, color)));
        }
        else {
            data.push_back(wxVariant(MyColorText(p.underlyingMarketInfo.buy1Money, wxColor(204, 78, 232))));
            dataMap[3]=wxVariant(MyColorText(p.underlyingMarketInfo.buy1Money, color));
        } else {
            dataMap[3] = wxVariant(MyColorText(p.underlyingMarketInfo.buy1Money, wxColor(204, 78, 232)));
        }
@@ -280,10 +442,10 @@
            positionMoney = price * p.currentPosition;
        }
        if (!hasPosition) {
            data.push_back(wxVariant(MyColorText(StringUtil::to_string(positionMoney, 2),color)));
            dataMap[4]=wxVariant(MyColorText(StringUtil::to_string(positionMoney, 2), color));
        }
        else {
            data.push_back(wxVariant(MyColorText(StringUtil::to_string(positionMoney, 2), *wxRED)));
            dataMap[4]=wxVariant(MyColorText(StringUtil::to_string(positionMoney, 2), *wxRED));
        }
@@ -301,7 +463,7 @@
        p.todayCommission.ToDouble(&todayCommission);
        totalPosCost += todayCommission;
        wxString cost_price = StringUtil::to_string(totalPosCost / totalVolume, 3);
        data.push_back(wxVariant(MyColorText(cost_price, color)));
        dataMap[8] = (wxVariant(MyColorText(cost_price, color)));
        // 今日盈亏计算: 总卖出金额 + 持仓*现价 -  买入金额 - 手续费
        double totalSellMoney = 0;
        for (std::list<DealInfo>::iterator e = p.sellList.begin(); e != p.sellList.end(); e++) {
@@ -315,18 +477,22 @@
        double profit_rate = profit_money / totalPosCost;
        wxString profit_rate_str = "";
        profit_rate_str.Append(StringUtil::to_string(profit_rate * 100)).Append("%");
        data.push_back(wxVariant(MyColorText(profit_rate_str, color)));
        dataMap[5] = (wxVariant(MyColorText(profit_rate_str, color)));
        // 正股数据设置
        if (hasPosition) {
            data.push_back(wxVariant(MyButton( p.underlyingMarketInfo.code,"查看",wxColor(64,64,64), wxColor(225,225,225))));
            dataMap[9] = (wxVariant(MyButton(p.underlyingMarketInfo.code, "查看", wxColor(64, 64, 64), wxColor(225, 225, 225))));
        }
        else {
            data.push_back(wxVariant(MyButton(p.underlyingMarketInfo.code, "查看", color, wxColor(255,255,255))));
            dataMap[9] = (wxVariant(MyButton(p.underlyingMarketInfo.code, "查看", color, wxColor(255, 255, 255))));
        }
        data.push_back(wxVariant(MyColorText(wxString(to_string(p.currentPosition).c_str()),color)));
        data.push_back(wxVariant(MyColorText(StringUtil::to_string(profit_money, 2), color)));
        data.push_back(wxVariant(MyColorText(p.underlyingMarketInfo.name, color)));
        dataMap[10] = (wxVariant(MyColorText(wxString(to_string(p.currentPosition).c_str()), color)));
        dataMap[11] = (wxVariant(MyColorText(StringUtil::to_string(profit_money, 2), color)));
        dataMap[12] = (wxVariant(MyColorText(p.underlyingMarketInfo.name, color)));
        for (const auto& pair : dataMap) {
            data.push_back(pair.second);
        }
        viewManager->positionWidgets->listCtrlReport->AppendItem(data);
        if (selectPositionId == p.id) {
@@ -337,7 +503,7 @@
                DealInfo info = *e;
                double price = stod(info.price.ToStdString().c_str());
                double rate = (price - p.marketInfo.preClosePrice) * 100 / p.marketInfo.preClosePrice;
                tradePoints.push_back(TickTradeData({ info.tradeTime, (float)rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())) }));
                tradePoints.push_back(TickTradeData({ info.tradeTime, (float)rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())), info.type }));
            }
            viewManager->tickWidgets->tickChart->SetBuyPoint(tradePoints);
            tradePoints.clear();
@@ -351,7 +517,7 @@
        }
        index += 1;
    }
    viewManager->positionWidgets->listCtrlReport->Refresh();
    viewManager->positionWidgets->listCtrlReport->HandleDataUpdate();
}
void MainFrame::requestMoney()
@@ -426,11 +592,11 @@
LRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
    cout <<"MSWWindowProc:"<< nMsg << endl;
    cout << "MSWWindowProc:" << nMsg << endl;
    if (nMsg == WM_COPYDATA) {
        COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
        if (pcds != NULL) {
            int action_code =    pcds->dwData;
            int action_code = pcds->dwData;
            if (action_code == 100) {
                // 卖
                BYTE* pBuf = (BYTE*)(pcds->lpData);
@@ -461,6 +627,24 @@
    MyConfigUtil::setPositionColumnWidth(positionWidthList);
    event.Skip();
    exit(0);
}
void MainFrame::lockSellVolume()
{
    string value = viewManager->sellWidgets->sellMoney->GetValue().ToStdString();
    if (selectPositionId.IsEmpty()) {
        MyConfigUtil::setSellMoney(stoi(value.c_str()));
        //wxMessageBox("锁定卖出金额成功");
    }
    else {
        for (std::list<PositionInfo>::iterator e = orginPositionList.begin(); e != orginPositionList.end(); ++e) {
            if ((*e).id == selectPositionId) {
                MyConfigUtil::setSellMoney((*e).securityID.ToStdString(), stoi(value.c_str()));
                //wxMessageBox("锁定卖出金额成功");
                break;
            }
        }
    }
}
void MainFrame::OnBtnRefreshClick(wxCommandEvent& event)
@@ -577,7 +761,11 @@
                that->viewManager->tickWidgets->tickChart->AddTickData(TimeUtil::format((long)tick->created_at, "%H:%M:%S"), 100 * (tick->price - info.marketInfo.preClosePrice) / info.marketInfo.preClosePrice, to_string(tick->price));
            }
            else if (info.underlyingMarketInfo.code == symbol) {
                that->viewManager->tickWidgets->tickChart->AddUnderlyingTickData(TimeUtil::format((long)tick->created_at, "%H:%M:%S"), 100 * (tick->price - info.underlyingMarketInfo.preClosePrice) / info.underlyingMarketInfo.preClosePrice);
                list<Quote> quotes;
                for (int i = 0; i < 5; i++) {
                    quotes.push_back(tick->quotes[i]);
                }
                that->viewManager->tickWidgets->tickChart->AddUnderlyingTickData(TimeUtil::format((long)tick->created_at, "%H:%M:%S"), 100 * (tick->price - info.underlyingMarketInfo.preClosePrice) / info.underlyingMarketInfo.preClosePrice, quotes);
            }
            break;
        }
@@ -592,6 +780,19 @@
            return info;
        }
    }
}
void MainFrame::setTradeStateView(int state)
{
    if (state > 0) {
        viewManager->sellWidgets->openTrade->SetForegroundColour(*wxRED);
        viewManager->sellWidgets->closeTrade->SetForegroundColour(*wxBLACK);
    }
    else {
        viewManager->sellWidgets->openTrade->SetForegroundColour(*wxBLACK);
        viewManager->sellWidgets->closeTrade->SetForegroundColour(*wxRED);
    }
}
@@ -668,7 +869,7 @@
            DealInfo info = *e;
            double price = stod(info.price.ToStdString().c_str());
            double rate = (price - p.marketInfo.preClosePrice) * 100 / p.marketInfo.preClosePrice;
            this->viewManager->tickWidgets->tickChart->AddBuyPoint(info.tradeTime, rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())));
            this->viewManager->tickWidgets->tickChart->AddBuyPoint(info.tradeTime, rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())), info.type);
        }
        for (std::list<DealInfo>::iterator e = p.sellList.begin(); e != p.sellList.end(); ++e) {
            DealInfo info = *e;
@@ -679,7 +880,7 @@
        wxRichTextAttr style;
        wxRichTextCtrl *richText =    this->viewManager->tickWidgets->codeInfoLabel;
        wxRichTextCtrl* richText = this->viewManager->topWidgets->codeInfoLabel;
        richText->GetBuffer().Clear();
        richText->Clear();
@@ -715,8 +916,8 @@
        codeInfoStr = "";
        codeInfoStr.Append(",板块:");
        auto blocks = p.underlyingDetailInfo.blocks;
        i = 0;
        for (std::list<wxString>::iterator e = blocks.begin(); e != blocks.end(); ++e) {
@@ -742,7 +943,7 @@
        }
        codeInfoStr.Append(",");
        codeInfoStr.Append("市值:").Append(p.underlyingDetailInfo.zyltgb).Append(",");
        codeInfoStr.Append("股价:").Append(p.underlyingDetailInfo.price).Append(",");
@@ -751,6 +952,9 @@
        richText->WriteText(codeInfoStr);
        tickDataRequestStrategy->subscribeSymbol(JueJinDataUtil::getSymbol(p.securityID.ToStdString()), JueJinDataUtil::getSymbol(p.underlyingMarketInfo.code.ToStdString()));
        // 获取设置的卖出金额
        int sellMoney = MyConfigUtil::getSellMoney(p.securityID.ToStdString());
        viewManager->sellWidgets->sellMoney->SetLabelText(to_wstring(sellMoney));
    }
    else {
        selectPositionId = "";
CBTrade/MainFrame.h
@@ -23,6 +23,8 @@
    bool killed;
    BlinkingMessageDialog* blinkingMessageDialog;
    int requestCount;
    // 交易状态
    int tradeState;
public:
    // Constructor
@@ -108,6 +110,13 @@
    /// <summary>
    /// 设置交易状态相关的视图
    /// </summary>
    /// <param name="state"></param>
    void setTradeStateView(int state);
    /// <summary>
    /// Tick 回调
    /// </summary>
    /// <param name="info"></param>
@@ -152,5 +161,11 @@
    void OnClose(wxCloseEvent& event);
    /// <summary>
    /// 卖量锁定
    /// </summary>
    void lockSellVolume();
};
CBTrade/MyConfigUtil.cpp
@@ -1,6 +1,7 @@
#include "MyConfigUtil.h"
#include "../common_nopch/JsonUtil.h"
#include <wx/wx.h>
#include <map>
JueJinParams MyConfigUtil::getJueJinParams()
{
@@ -61,6 +62,29 @@
    }
}
int MyConfigUtil::getSellMoney(string code)
{
    try {
        string value = readStringConfig("sell_codes_money");
        std::map<string, int> codeMoneyMap;
        if (!value.empty()) {
            auto doc = JsonUtil::parseUTF8(value);
            for (auto itr = doc.MemberBegin(); itr != doc.MemberEnd(); ++itr) {
                // itr->name is the key, itr->value is the value corresponding to the key
                codeMoneyMap[itr->name.GetString()] = itr->value.GetInt();
            }
        }
        if (codeMoneyMap.find(code) != codeMoneyMap.end()) {
            return codeMoneyMap[code];
        }
    }
    catch (...) {
    }
    return getSellMoney();
}
void MyConfigUtil::setSellMoney(int money)
{
    setIntConfig("sell_money", money);
@@ -68,6 +92,42 @@
}
void MyConfigUtil::setSellMoney(string code, int money)
{
    string value = "";
    try {
        value = readStringConfig("sell_codes_money");
    }
    catch (...) {
    }
    std::map<string, int> codeMoneyMap;
    if (!value.empty()) {
        auto doc = JsonUtil::parseUTF8(value);
        for (auto itr = doc.MemberBegin(); itr != doc.MemberEnd(); ++itr) {
            // itr->name is the key, itr->value is the value corresponding to the key
            codeMoneyMap[itr->name.GetString()] = itr->value.GetInt();
        }
    }
    codeMoneyMap[code] = money;
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    for (std::map<string, int>::iterator e = codeMoneyMap.begin(); e != codeMoneyMap.end(); ++e) {
        writer.Key((*e).first.c_str());
        writer.Int((*e).second);
    }
    writer.EndObject();
    const char* json_content = buf.GetString();
    setStringConfig("sell_codes_money", json_content);
}
void MyConfigUtil::clearCodesSellMoney()
{
    setStringConfig("sell_codes_money", "");
}
void MyConfigUtil::setMainWindowPos(wxPoint point, wxSize size)
{
    rapidjson::StringBuffer buf;
CBTrade/MyConfigUtil.h
@@ -44,11 +44,20 @@
    /// <param name="money"></param>
    static void setBuyMoney(int money);
    /// <summary>
    /// 获取卖出金额
    /// </summary>
    /// <returns></returns>
    static int getSellMoney();
    /// <summary>
    /// 获取单个票的卖出金额
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    static int getSellMoney(string code);
    /// <summary>
    /// 设置卖出金额
@@ -56,6 +65,17 @@
    static void setSellMoney(int money);
    /// <summary>
    /// 设置单个票的卖出金额
    /// </summary>
    /// <param name="code"></param>
    /// <param name="money"></param>
    static void setSellMoney(string code, int money);
    /// <summary>
    /// 清除代码的卖出金额
    /// </summary>
    static void clearCodesSellMoney();
    // 设置主窗口的位置与大小
CBTrade/MyDataViewListCtrl.h
New file
@@ -0,0 +1,55 @@
#pragma once
#include <wx/wx.h>
#include <wx/listctrl.h>
#include <wx/dataview.h>
class MyDataViewListCtrl:public wxDataViewListCtrl{
private:
    wxBitmap m_buffer;
public:
    MyDataViewListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style = wxDV_ROW_LINES)
        : wxDataViewListCtrl(parent, id, pos, size, style) {
        // Initialize buffer with the size of the control
        m_buffer.Create(size.GetWidth(), size.GetHeight());
    }
    void OnPaint(wxPaintEvent& event) {
        wxPaintDC dc(this);
        wxMemoryDC memDC;
        memDC.SelectObject(m_buffer);
        // Draw your items onto memDC instead of dc
        // Example: DrawItems(memDC);
        dc.Blit(0, 0, m_buffer.GetWidth(), m_buffer.GetHeight(), &memDC, 0, 0);
    }
    void UpdateBuffer() {
        wxClientDC dc(this);
        wxMemoryDC memDC;
        memDC.SelectObject(m_buffer);
        // Clear the buffer if needed
        memDC.SetBackground(wxBrush(GetBackgroundColour()));
        memDC.Clear();
        // Redraw items onto memDC
        // Example: RedrawItems(memDC);
        // Ensure all drawing is complete
        memDC.SelectObject(wxNullBitmap);
        // Refresh the screen
        Refresh();
    }
    void HandleDataUpdate() {
        // Update internal data structures as needed
        // Example: UpdateInternalData();
        // Update the buffer
        UpdateBuffer();
    }
};
CBTrade/MyNetworkApi.cpp
@@ -155,3 +155,109 @@
    string result = base_trade_request(std::string(json_content));
    return result; return string();
}
string MyNetworkApi::get_trade_state()
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("trade_state");
    writer.Key("operate");
    writer.Int(3);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    return result; return string();
}
string MyNetworkApi::set_trade_state(int state)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("trade_state");
    writer.Key("operate");
    writer.Int(1);
    writer.Key("state");
    writer.Int(state);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    return result; return string();
}
string MyNetworkApi::list_want_buy_codes()
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("want_buy_codes");
    writer.Key("operate");
    writer.Int(3);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    return result; return string();
}
string MyNetworkApi::add_want_buy_code(string code)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("want_buy_codes");
    writer.Key("operate");
    writer.Int(4);
    writer.Key("code");
    writer.String(code.c_str());
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    return result; return string();
}
string MyNetworkApi::remove_want_buy_code(string code)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("want_buy_codes");
    writer.Key("operate");
    writer.Int(2);
    writer.Key("code");
    writer.String(code.c_str());
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    return result; return string();
}
CBTrade/MyNetworkApi.h
@@ -77,5 +77,43 @@
    /// </summary>
    /// <returns></returns>
    static string get_backtest_mode();
    /// <summary>
    /// 获取交易状态
    /// </summary>
    /// <returns></returns>
    static string get_trade_state();
    /// <summary>
    /// 设置交易状态
    /// </summary>
    /// <param name="state"></param>
    /// <returns></returns>
    static string set_trade_state(int state);
    /// <summary>
    /// 获取想买单
    /// </summary>
    /// <returns></returns>
    static string list_want_buy_codes();
    /// <summary>
    /// 添加想买单
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    static string add_want_buy_code(string code);
    /// <summary>
    /// 移除想买单
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    static string remove_want_buy_code(string code);
};
CBTrade/TickChart.cpp
@@ -300,8 +300,6 @@
void TickChart::drawBuyPoint(wxDC& dc, wxPoint point)
{
    dc.SetPen(wxColor(232, 62, 37));
    dc.SetBrush(wxColor(232, 62, 37));
    dc.DrawCircle(point, POINT_REDIUS);
}
@@ -327,7 +325,7 @@
            // 计算位置
            wxString text = wxString("成交时间:").Append(tickData.time).Append("\n");
            text.Append("涨幅:").Append(StringUtil::to_string(tickData.rate)).Append("%").Append("\n");
            text.Append("成交价:").Append(tickData.price).Append("元\n");
            text.Append("成交价:").Append(StringUtil::to_string( stod( tickData.price.ToStdString().c_str()),3)).Append("元\n");
            text.Append("成交量:").Append(to_string(tickData.volume)).Append("\n");
            text.Append("成交额:").Append(tickData.money).Append("元");
            drawInfo(paint, wxPoint(point.x + POINT_REDIUS, point.y + POINT_REDIUS), text, {});
@@ -341,7 +339,7 @@
        if (abs(mousePoint.x - point.x) < POINT_REDIUS * 2 && abs(mousePoint.y - point.y) < POINT_REDIUS * 2) {
            wxString text = wxString("成交时间:").Append(tickData.time).Append("\n");
            text.Append("涨幅:").Append(StringUtil::to_string(tickData.rate)).Append("%").Append("\n");
            text.Append("成交价:").Append(tickData.price).Append("元\n");
            text.Append("成交价:").Append(StringUtil::to_string(stod(tickData.price.ToStdString().c_str()), 3)).Append("元\n");
            text.Append("成交量:").Append(to_string(tickData.volume)).Append("\n");
            text.Append("成交额:").Append(tickData.money).Append("元");
            drawInfo(paint, wxPoint(point.x + POINT_REDIUS, point.y + POINT_REDIUS), text, {});
@@ -389,6 +387,9 @@
void TickChart::drawUnderlyingLatestRate(wxDC& paint, wxRect area)
{
    if (1 > 0) {
        return;
    }
    if (underlyingTickDatas.size() > 0) {
        // 绘制Tick线最新的点
        TickData lastTickData = underlyingTickDatas.back();
@@ -415,6 +416,89 @@
        paint.DrawText(rateText, wxPoint(x,y));
    }
}
void TickChart::drawUnderlyingQuotes(wxDC& paint, wxRect area)
{
    if (underlyingTickDatas.size() <= 0) {
        return;
    }
    TickData tick =    underlyingTickDatas.back();
    if (tick.quotes.size() <= 0) {
        return;
    }
    wxSize size = paint.GetTextExtent("万");
    int lineHeight = (int)(size.GetHeight() * 1.1);
    int contentHeight = size.GetHeight();
    int contentWidth = contentHeight * 3;
    int height = lineHeight*10;
    int width = contentWidth * 2;
     // 绘制买卖档口
    wxPoint middlePoint = wxPoint(area.GetLeft()+ GRID_MARGIN.left, area.GetBottom() - GRID_MARGIN.bottom - height/2);
    if (stoi(TimeUtil::format(TimeUtil::getNowTimeStamp(), "%H%M%S").c_str())<120000) {
        middlePoint.x = area.GetRight() - GRID_MARGIN.right - width;
    }
    wxColour textColor = wxColor(100, 100, 100);
    paint.SetBrush(wxColor(255,255,255,128));
    paint.SetPen(*wxTRANSPARENT_PEN);
    paint.SetTextForeground(textColor);
    //paint.DrawRoundedRectangle(wxRect(wxPoint(middlePoint.x, middlePoint.y - height/2), wxSize(width, height)),5);
    int index = 0;
    for (std::list<Quote>::iterator e = tick.quotes.begin(); e != tick.quotes.end(); ++e) {
        Quote qu = *e;
        // 绘制买
        wxString price;
        wxString money;
        if (qu.bid_volume > 0) {
            // 有买1
            price = wxString(StringUtil::to_string(qu.bid_price).c_str());
            money =  StringUtil::to_string( qu.bid_price * qu.bid_volume/10000,1);
            money.Append("万");
        }
        else {
            price = "-";
            money = "-";
        }
        paint.DrawLabel(price, wxRect(wxPoint(middlePoint.x, middlePoint.y + lineHeight * index), wxSize(contentWidth, contentHeight)), wxALIGN_LEFT);
        paint.DrawLabel(money, wxRect(wxPoint(middlePoint.x + contentWidth, middlePoint.y + lineHeight * index), wxSize(contentWidth, contentHeight)), wxALIGN_RIGHT);
        // 绘制卖
        if (qu.ask_price > 0) {
            // 有买1
            price = wxString(StringUtil::to_string(qu.ask_price).c_str());
            money = StringUtil::to_string(qu.ask_price * qu.ask_volume / 10000, 1);
            money.Append("万");
        }
        else {
            price = "-";
            money = "-";
        }
        paint.DrawLabel(price, wxRect(wxPoint(middlePoint.x, middlePoint.y - lineHeight * (index+1)), wxSize(contentWidth, contentHeight)), wxALIGN_LEFT);
        paint.DrawLabel(money, wxRect(wxPoint(middlePoint.x + contentWidth, middlePoint.y - lineHeight * (index+1)), wxSize(contentWidth, contentHeight)), wxALIGN_RIGHT);
        if (index == 0) {
            paint.SetBrush(textColor);
            paint.SetPen(textColor);
            paint.DrawLine(wxPoint(middlePoint.x, middlePoint.y - (lineHeight-contentHeight)/2), wxPoint(middlePoint.x + width, middlePoint.y- (lineHeight - contentHeight) /2));
        }
        index += 1;
    }
}
TickChart::TickChart(wxWindow* parent, wxWindowID id, int timeSpace, TIME_SPACE_TYPE timeSpaceType, wxString xStartTime, wxString xEndTime, const wxPoint& pos, const wxSize& size) : wxControl(parent, id, pos, size, wxBORDER_NONE), timeSpace(timeSpace), timeSpaceType(timeSpaceType), xStartTime(xStartTime), xEndTime(xEndTime), maxYRate(20), limitUpRate(20), preClosePrice(10.00)
@@ -491,7 +575,24 @@
            if (TickDataUtil::tradTimeSub((*e).time, xEndTime) > 0) {
                continue;
            }
            TickTradeData info = *e;
            wxPoint point = convertTickDataToPoint(*e, rect);
            wxColour color;
            switch (info.colorType)
            {
            case 1:
                color = wxColor(232, 62, 37);
                break;
            case 3:
                color = wxColor(106, 254, 193);
                break;
            default:
                color = wxColor(232, 62, 37);
                break;
            }
            dc.SetPen(color);
            dc.SetBrush(color);
            drawBuyPoint(dc, point);
        }
@@ -510,6 +611,8 @@
        drawBuyAndSellPointInfo(dc, rect, mousePos);
        drawUnderlyingLatestRate(dc, rect);
        drawUnderlyingQuotes(dc, rect);
        //pdc.Clear();
        // 采用双缓存绘制
@@ -682,7 +785,7 @@
                        }
                        wxString time_str = TimeUtil::format((long)datas.bob, "%H:%M:%S");
                        float price = datas.open;
                        AddUnderlyingTickData(time_str, 100 * (price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice, FALSE);
                        AddUnderlyingTickData(time_str, 100 * (price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice,std::list<Quote>(), FALSE);
                        if (i == tempUDatas->count() - 1) {
                            // 加载Bar线无法覆盖的时间段数据
@@ -698,10 +801,23 @@
                                if (datas.price < 0.0001) {
                                    continue;
                                }
                                AddUnderlyingTickData(TimeUtil::format((long)datas.created_at, "%H:%M:%S"), 100 * (datas.price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice, FALSE);
                                std::list<Quote> quotes;
                                for (int n = 0; n < 5; n++) {
                                    quotes.push_back(datas.quotes[n]);
                                }
                                AddUnderlyingTickData(TimeUtil::format((long)datas.created_at, "%H:%M:%S"), 100 * (datas.price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice, quotes, FALSE);
                            }
                        }
                    }
                    Tick tick = JueJinDataUtil::currentTick(JueJinDataUtil::getSymbol(underlyingCodeInfo.code.ToStdString()));
                    std::list<Quote> quotes;
                    for (int n = 0; n < 5; n++) {
                        quotes.push_back(tick.quotes[n]);
                    }
                    AddUnderlyingTickData(TimeUtil::format((long)tick.created_at, "%H:%M:%S"), 100 * (tick.price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice, quotes, FALSE);
                }
                if (cbCodeInfo.code.Length() > 0) {
@@ -763,7 +879,7 @@
                        if (datas.price < 0.0001) {
                            continue;
                        }
                        AddUnderlyingTickData(TimeUtil::format((long)datas.created_at, "%H:%M:%S"), 100 * (datas.price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice, FALSE);
                        AddUnderlyingTickData(TimeUtil::format((long)datas.created_at, "%H:%M:%S"), 100 * (datas.price - underlyingCodeInfo.preClosePrice) / underlyingCodeInfo.preClosePrice, std::list<Quote>(), FALSE);
                    }
                }
@@ -818,9 +934,9 @@
    }
}
void TickChart::AddUnderlyingTickData(wxString time, float rate, bool refresh)
void TickChart::AddUnderlyingTickData(wxString time, float rate, list<Quote> quotes, bool refresh)
{
    if (TickDataUtil::tradTimeSub(time, xEndTime) > 0) {
    if (TickDataUtil::tradTimeSub(time, xEndTime) > 120) {
        return;
    }
@@ -832,12 +948,13 @@
            return;
        }
        if (seconds / this->timeSpace != last.time / this->timeSpace) {
            underlyingTickDatas.push_back(TickData({ seconds , rate, "" }));
            underlyingTickDatas.push_back(TickData({ seconds , rate, "", quotes }));
        }
        else {
            underlyingTickDatas.back().price = "";
            underlyingTickDatas.back().time = seconds;
            underlyingTickDatas.back().rate = rate;
            underlyingTickDatas.back().quotes = quotes;
            cout << "最后一条数据:" << underlyingTickDatas.back().time << "-" << underlyingTickDatas.back().price << endl;
        }
@@ -847,7 +964,7 @@
        }
    }
    else {
        underlyingTickDatas.push_back(TickData({ seconds , rate, "" }));
        underlyingTickDatas.push_back(TickData({ seconds , rate, "",  quotes }));
    }
    // 正股不浮动
    float newMaxYRate = abs(rate);
@@ -861,9 +978,11 @@
}
void TickChart::AddBuyPoint(wxString time, float rate, wxString price, int volume, wxString money)
void TickChart::AddBuyPoint(wxString time, float rate, wxString price, int volume, wxString money, int type)
{
    AddBuyPoint(TickTradeData({ time , rate, price,volume, money }));
    AddBuyPoint(TickTradeData({ time , rate, price,volume, money, type }));
}
void TickChart::AddBuyPoint(TickTradeData data)
CBTrade/TickChart.h
@@ -6,6 +6,7 @@
#include<list>
#include <map>
#include "../common_nopch/WidgetsRenderUtil.h"
#include "JueJinDataUtil.h"
struct  CodeBasicInfo
{
@@ -40,6 +41,11 @@
    wxString rightLabel;
};
struct QuotesInfo {
    float price;
    int volume;
};
/// <summary>
/// K线分时数据
/// </summary>
@@ -47,6 +53,7 @@
    int time;// 距离9点25的s数
    float rate;//涨幅
    wxString price;// 价格
    std::list<Quote> quotes; // 买5档
};
/// <summary>
/// tick交易信息
@@ -57,6 +64,7 @@
    wxString price;// 价格
    int volume;// 成交量
    wxString money;// 成交金额
    int colorType;// 颜色类型
};
@@ -205,6 +213,13 @@
    /// <param name="area"></param>
    void drawUnderlyingLatestRate(wxDC& paint, wxRect area);
    /// <summary>
    /// 绘制买卖5档
    /// </summary>
    /// <param name="paint"></param>
    /// <param name="area"></param>
    void drawUnderlyingQuotes(wxDC& paint, wxRect area);
public:
@@ -241,7 +256,7 @@
    /// <param name="time"></param>
    /// <param name="rate"></param>
    /// <param name="refresh"></param>
    void AddUnderlyingTickData(wxString time, float rate, bool refresh = TRUE);
    void AddUnderlyingTickData(wxString time, float rate, std::list<Quote> quotes, bool refresh = TRUE);
    /// <summary>
    /// 添加买点
@@ -249,7 +264,7 @@
    /// <param name="time"></param>
    /// <param name="rate"></param>
    /// <param name="price"></param>
    void AddBuyPoint(wxString time, float rate, wxString price, int volume, wxString money);
    void AddBuyPoint(wxString time, float rate, wxString price, int volume, wxString money, int type);
    /// <summary>
CBTrade/ViewManager.cpp
@@ -31,14 +31,14 @@
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    wxSize size = window->GetSize();
    cout << "size:"<< size.GetWidth() << endl;
    cout << "size:" << size.GetWidth() << endl;
    wxPanel* topPanel = new wxPanel(window, wxID_ANY, wxDefaultPosition, wxSize(-1, PANNEL_TOP_HEIGHT));
    wxPanel* tickPanel = new wxPanel(window, wxID_ANY, wxDefaultPosition, wxSize(-1,size.GetWidth()<100? PANNEL_TICK_HEIGHT: size.GetWidth()*2/3));
    wxPanel* tickPanel = new wxPanel(window, wxID_ANY, wxDefaultPosition, wxSize(-1, size.GetWidth() < 100 ? PANNEL_TICK_HEIGHT : size.GetWidth() * 2 / 3));
    wxPanel* moneyPanel = new wxPanel(window, wxID_ANY, wxDefaultPosition, wxSize(-1, PANNEL_MONEY_HEIGHT));
@@ -51,15 +51,15 @@
    initMenu((wxFrame*)window);
    sizer->Add(topPanel, 0, wxEXPAND|wxLEFT | wxRIGHT, 2);
    sizer->Add(topPanel, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
    sizer->Add(createSplitLine(window), 0, wxEXPAND);
    sizer->Add(tickPanel, 0, wxEXPAND|wxLEFT | wxRIGHT, 2);
    sizer->Add(tickPanel, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
    sizer->Add(createSplitLine(window), 0, wxEXPAND);
    sizer->Add(moneyPanel, 0, wxEXPAND|wxLEFT | wxRIGHT, 2);
    sizer->Add(moneyPanel, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
    sizer->Add(createSplitLine(window), 0, wxEXPAND);
    sizer->Add(positionPanel, 1, wxEXPAND |wxLEFT | wxRIGHT, 2);
    sizer->Add(positionPanel, 1, wxEXPAND | wxLEFT | wxRIGHT, 2);
    sizer->Add(createSplitLine(window), 0, wxEXPAND);
    sizer->Add(sellPanel, 0, wxEXPAND|wxLEFT | wxRIGHT, 2);
    sizer->Add(sellPanel, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
    sizer->Add(createSplitLine(window), 0, wxEXPAND);
    window->SetSizer(sizer);
    this->initTopView(topPanel);
@@ -72,7 +72,7 @@
void ViewManager::ShowJueJinSetting(wxCommandEvent& event)
{
    JueJInSettingFrame *jueJinFrame = new JueJInSettingFrame("掘金参数设置");
    JueJInSettingFrame* jueJinFrame = new JueJInSettingFrame("掘金参数设置");
    jueJinFrame->ShowModal();
}
@@ -107,7 +107,19 @@
    this->topWidgets->backTestDate = new wxTextCtrl(pancel, wxID_ANY);
    this->topWidgets->btnBackTest = new wxButton(pancel, wxID_ANY, "开始回测");
    topWidgets->codeInfoLabel = new wxRichTextCtrl(pancel, wxID_ANY, "", wxDefaultPosition, wxSize(-1, 90), wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE);
    wxFont font = topWidgets->codeInfoLabel->GetFont();
    font.SetPointSize(10);
    topWidgets->codeInfoLabel->SetFont(font);
    wxBoxSizer* infoSizer = new wxBoxSizer(wxHORIZONTAL);
    infoSizer->Add(topWidgets->codeInfoLabel, 1, wxEXPAND);
    
    // 绑定事件
    this->topWidgets->refreshBtn->Bind(wxEVT_BUTTON, &ViewManager::OnRefresh, this);
@@ -115,9 +127,12 @@
    sizer->Add(this->topWidgets->btnAddZX, 0, wxALL, 2);
    sizer->Add(this->topWidgets->msgLabel, 1, wxALIGN_CENTER_VERTICAL);
    sizer->Add(topWidgets->backTestDate, 0, wxALIGN_CENTER_VERTICAL);
    sizer->Add(topWidgets->btnBackTest, 0, wxLEFT| wxALIGN_CENTER_VERTICAL, 2);
    sizer->Add(topWidgets->btnBackTest, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 2);
    sizer->Add(this->topWidgets->refreshBtn, 0, wxALL, 2);
    pancel->SetSizer(sizer);
    wxBoxSizer* rootSizer = new wxBoxSizer(wxVERTICAL);
    rootSizer->Add(infoSizer, 0, wxEXPAND, 2);
    rootSizer->Add(sizer, 0, wxEXPAND, 2);
    pancel->SetSizer(rootSizer);
}
@@ -137,18 +152,8 @@
void ViewManager::initTickView(wxPanel* panel)
{
    wxString st = "";
    tickWidgets->tickChart = new TickChart(panel, wxID_ANY,60,TIME_SPACE_BAR,"09:25:00","15:00:00");
    tickWidgets->codeInfoLabel = new wxRichTextCtrl(panel, wxID_ANY, st, wxDefaultPosition,wxSize(-1,90), wxTE_MULTILINE| wxTE_READONLY| wxBORDER_NONE);
    wxFont font = tickWidgets->codeInfoLabel->GetFont();
    font.SetPointSize(10);
    tickWidgets->codeInfoLabel->SetFont(font);
    tickWidgets->tickChart = new TickChart(panel, wxID_ANY, 60, TIME_SPACE_BAR, "09:25:00", "15:00:00");
    wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
    sizer->Add(tickWidgets->codeInfoLabel,1, wxEXPAND);
    panelSizer->Add(sizer, 0, wxEXPAND, 2);
    panelSizer->Add(tickWidgets->tickChart, 1, wxEXPAND);
    panel->SetSizer(panelSizer);
}
@@ -254,7 +259,7 @@
                t.detach();
            }
            catch (...) {
            }
        }
        return false; // 返回 true 表示已经处理了点击事件
@@ -287,7 +292,7 @@
    ColorTextRenderer(const wxString& varianttype = wxS("wxObject"))
        : wxDataViewCustomRenderer(varianttype, wxDATAVIEW_CELL_ACTIVATABLE)
    {
    }
    virtual bool Render(wxRect cell, wxDC* dc, int state)
@@ -329,61 +334,39 @@
void ViewManager::initPositionView(wxPanel* panel)
{
    wxDataViewListCtrl* listCtrl = new wxDataViewListCtrl(
    MyDataViewListCtrl* listCtrl = new MyDataViewListCtrl(
        panel, wxID_ANY, wxDefaultPosition, wxSize(-1, -1),
        wxLC_REPORT | wxBORDER_NONE);
    // 设置整体的字体大小  
    wxFont font  = listCtrl->GetFont();
    wxFont font = listCtrl->GetFont();
    font.SetPointSize(10);
    listCtrl->SetFont(font);
    const int COL_COUNT = 13;
    std::string headers[COL_COUNT] = { "名称","涨幅","现价","现手","正股涨幅","正股买一","持仓金额","成本价","盈亏比","更多","持仓","盈亏","正股名称" };
    list<int> widths= MyConfigUtil::getPositionColumnWidth();
    std::string headers[COL_COUNT] = { "名称","涨幅","正股涨幅","正股买一","持仓金额","盈亏比","单笔卖额","现价","成本价","更多","持仓","盈亏","正股名称" };
    list<int> widths = MyConfigUtil::getPositionColumnWidth();
    for (int i = 0; i < COL_COUNT; i++) {
        int width = -1;
        if (widths.size() > i) {
            list<int>::iterator e =    widths.begin();
            std::advance(e,i);
            list<int>::iterator e = widths.begin();
            std::advance(e, i);
            width = *e;
        }
        cout << "持仓列宽度:" << i << "-" << width << endl;
        if (i != 9) {
            auto ctr = new ColorTextRenderer();
            listCtrl->AppendColumn(new wxDataViewColumn(headers[i], ctr, i, width < 0 ? 50 : width, i == 0 ? wxALIGN_LEFT : wxALIGN_RIGHT, wxDATAVIEW_COL_RESIZABLE));
        }
        else {
            auto bc = new ButtonRenderer();
            listCtrl->AppendColumn(new wxDataViewColumn(headers[i], bc,i, width < 0? 50:width, i == 0 ? wxALIGN_LEFT : wxALIGN_RIGHT, wxDATAVIEW_COL_RESIZABLE));
            listCtrl->AppendColumn(new wxDataViewColumn(headers[i], bc, i, width < 0 ? 50 : width, i == 0 ? wxALIGN_LEFT : wxALIGN_RIGHT, wxDATAVIEW_COL_RESIZABLE));
        }
    }
    for (int i = 0; i < 1; i++) {
        wxVector<wxVariant> data;
        data.push_back(wxVariant("美的转债"));
        data.push_back(wxVariant("10.20%"));
        data.push_back(wxVariant("123.123"));
        data.push_back(wxVariant("452"));
        data.push_back(wxVariant("10.02%"));
        data.push_back(wxVariant("12312万"));
        data.push_back(wxVariant("100000.00"));
        data.push_back(wxVariant("123.123"));
        data.push_back(wxVariant("1.01%"));
        data.push_back(wxVariant("美的集团"));
        data.push_back("");
        data.push_back(wxVariant("1000"));
        data.push_back(wxVariant("+20000.10"));
        listCtrl->AppendItem(data);
    }
    listCtrl->Refresh();
    listCtrl->HandleDataUpdate();
    positionWidgets->listCtrlReport = listCtrl;
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(positionWidgets->listCtrlReport, 1, wxEXPAND);
@@ -392,7 +375,7 @@
void ViewManager::initSellView(wxPanel* panel)
{
    const int moneys[] = { 50000,40000,30000,20000,10000,5000,3000,2000,1000 };
    const int moneys[] = { 80000,60000,40000,20000,15000,10000,8000,5000,3000,2000 };
    //-------按钮操作区域 
    const int COLUMN_SPACE = 8;
@@ -481,7 +464,7 @@
    sellWidgets->showAllPosition = new wxCheckBox(btnPannel, wxID_ANY, "显示无持仓");
    sellWidgets->showAllPosition->SetValue(TRUE);
    btnSizer->Add(sellWidgets->showAllPosition, 0,  wxLEFT, COLUMN_SPACE);
    btnSizer->Add(sellWidgets->showAllPosition, 0, wxLEFT, COLUMN_SPACE);
@@ -502,8 +485,10 @@
    auto sellNumsSizer = new wxBoxSizer(wxHORIZONTAL);
    for (std::list<wxButton*>::iterator e = sellWidgets->sellNums.begin(); e != sellWidgets->sellNums.end(); e++) {
        sellNumsSizer->Add(*e, 1, wxEXPAND | wxLEFT | wxRIGHT, 2);
        (*e)->SetMinSize(wxSize(40,50));
        sellNumsSizer->Add(*e, 1, wxEXPAND | wxALL, 2);
    }
    auto rootSizer = new wxBoxSizer(wxVERTICAL);
    rootSizer->Add(btnPannel, 0, wxEXPAND | wxTOP, 5);
    rootSizer->Add(sellNumsSizer, 1, wxEXPAND | wxTOP, 5);
CBTrade/ViewManager.h
@@ -5,10 +5,11 @@
#include <list>
#include "TickChart.h"
#include <wx/richtext/richtextctrl.h>
#include "MyDataViewListCtrl.h"
#define DPI 1
#define MAIN_WINDOW_WIDTH (int)(720*DPI)
#define PANNEL_TOP_HEIGHT (int)(30*DPI)
#define PANNEL_TICK_HEIGHT (int)(500*DPI)
#define PANNEL_TOP_HEIGHT (int)(120*DPI)
#define PANNEL_TICK_HEIGHT (int)(410*DPI)
#define PANNEL_MONEY_HEIGHT (int)(60*DPI)
#define PANNEL_POSITION_HEIGHT (int)(310*DPI)
#define PANNEL_SELL_HEIGHT (int)(120*DPI)
@@ -135,6 +136,7 @@
struct TopWidgets
{
    wxRichTextCtrl* codeInfoLabel;// 代码信息
    wxButton* refreshBtn;
    wxTextCtrl* codeEdit;
    wxStaticText* msgLabel;
@@ -147,7 +149,7 @@
{
    
    TickChart* tickChart;
    wxRichTextCtrl* codeInfoLabel;// 代码信息
};
struct MoneyWidgets
@@ -164,7 +166,7 @@
struct PositionWidgets
{
    wxDataViewListCtrl* listCtrlReport;
    MyDataViewListCtrl* listCtrlReport;
};
struct SellWidgets
CBTrade/config.cfg
@@ -1,6 +1,7 @@
juejin_params = "[\n    \"77fa387b37e9bc1586ae1135827e2ccb3e7cd4e4\",\n    \"95a982ce-fc2d-11ec-8ff3-0a0027000010\"\n]";
buy_money = 2000;
sell_money = 60000;
main_window_info = "[\n    -1292,\n    25,\n    963,\n    1037\n]";
tick_window_info = "[\n    -932,\n    366,\n    555,\n    428\n]";
position_view_column_width = "80,71,74,52,88,92,80,127,78,80,69,181,225";
main_window_info = "[\n    -1287,\n    73,\n    681,\n    1028\n]";
tick_window_info = "[\n    -1575,\n    251,\n    719,\n    428\n]";
position_view_column_width = "80,71,73,78,88,92,80,81,83,80,69,181,860";
sell_codes_money = "";
DelegateQueue/DataStruct.h
@@ -38,4 +38,5 @@
    wxString limit_up_time; // 
    std::list<TradeQueue> tradeQueueList;
    wxString zyltgb;
    int mode;// 下单模式, 3-扫入下单
};
DelegateQueue/DelegateQueue.vcxproj
@@ -22,8 +22,9 @@
    <VCProjectVersion>16.0</VCProjectVersion>
    <Keyword>Win32Proj</Keyword>
    <ProjectGuid>{e145394e-ff3e-4c4a-b76e-19c4e70153af}</ProjectGuid>
    <RootNamespace>DelegateQueue</RootNamespace>
    <RootNamespace>加贝控制中心</RootNamespace>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
    <ProjectName>加贝控制中心</ProjectName>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
DelegateQueue/MainFrame.cpp
@@ -8,6 +8,7 @@
#include "../common_nopch/TimeUtil.h"
#include "MyConfigUtil.h"
#include <wx/graphics.h>
#include <atlstr.h>
#define ROW_WIDTH_DELEGATE_INFO (FRAME_WIDTH  - 30)*DPI/100
@@ -29,6 +30,7 @@
    CLICK_TYPE_CANCEL_BUY,
    CLICK_TYPE_VIEW_DETAIL,
    CLICK_TYPE_QUEUE,
    CLICK_TYPE_NOT_BUY,
};
struct ViewDetailData {
@@ -44,6 +46,7 @@
    DelegateInfo delegateInfo;
    wxString delegateInfoStr;
    list<ColorIndexInfo> delegateColors;
    map<wxString, wxRect>  notBuyBtnRectMap;
    map<wxString, wxRect>  viewBtnRectMap;
    map<wxString, wxRect> cancelBtnRectMap;
    map<wxString, wxRect> queueRectMap;
@@ -170,6 +173,10 @@
        codeInfo.Append("  ").Append(delegateInfo.zyltgb);
        if (delegateInfo.mode == 3) {
            codeInfo.Append("(扫入)");
        }
        if (delegateInfo.pay_attention) {
            WidgetsRenderUtil::drawText(dc, codeInfo, wxPoint(startx, starty + 3), line_width, TEXT_LINE_HEIGHT, std::list<ColorIndexInfo>(), *wxRED);
@@ -179,6 +186,9 @@
        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));
@@ -194,6 +204,14 @@
        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));
        notBuyBtnRectMap[delegateInfo.id] = wxRect({ cancelBtnRectMap[delegateInfo.id].GetLeft() -btnWidth - padding, cancelBtnRectMap[delegateInfo.id].GetTop(), btnWidth, btnHeight});
        WidgetsRenderUtil::drawBtn(dc, "不买", notBuyBtnRectMap[delegateInfo.id], *wxWHITE, wxColour(133, 202, 255));
    }
    void drawDelegateQueue(wxDC* dc, wxPoint start, int line_width) {
@@ -266,6 +284,7 @@
        wxRect gridPostion = gridPostionMap[delegateInfo.id];
        wxRect queueRect = queueRectMap[delegateInfo.id];
        wxRect    cancelBtnRect = cancelBtnRectMap[delegateInfo.id];
        wxRect    notBuyBtnRect = notBuyBtnRectMap[delegateInfo.id];
        wxRect viewBtnRect = viewBtnRectMap[delegateInfo.id];
        cout << "单元位置:" << gridPostion.x << "-" << gridPostion.y << endl;
@@ -285,6 +304,10 @@
        else if (x >= cancelBtnRect.x && x <= cancelBtnRect.x + cancelBtnRect.GetWidth() && y > cancelBtnRect.y && y <= cancelBtnRect.y + cancelBtnRect.GetHeight()) {
            return CLICK_TYPE_CANCEL_BUY;
        }
        else if (x >= notBuyBtnRect.x && x <= notBuyBtnRect.x + notBuyBtnRect.GetWidth() && y > notBuyBtnRect.y && y <= notBuyBtnRect.y + notBuyBtnRect.GetHeight()) {
            return CLICK_TYPE_NOT_BUY;
        }
        else if (x >= queueRect.x && x <= queueRect.x + queueRect.GetWidth() && y > queueRect.y && y <= queueRect.y + queueRect.GetHeight()) {
@@ -358,6 +381,30 @@
    }
    // 加入黑名单
    void forbiddenBuy(string code) {
        try {
            string results = MyNetworkApi::add_black(code);
            auto doc = JsonUtil::parseUTF16(results);
            if (doc.IsObject()) {
                if (doc[L"code"].GetInt() == 0) {
                    showMsg(wxString(delegateInfo.codeName).Append(":加入黑名单成功").ToStdString(), MSG_TYPE_INFO);
                }
                else {
                    showMsg(wxString(doc[L"msg"].GetString()).ToStdString(), MSG_TYPE_WARNING);
                }
            }
            else {
                showMsg("网络请求失败", MSG_TYPE_ERROR);
            }
        }
        catch (wstring st) {
            showMsg(wxString( st.c_str()).ToStdString(), MSG_TYPE_ERROR);
        }
    }
    MainFrame* getWindowFrame() {
        wxWindow* window = this->GetOwner()->GetOwner()->GetParent();
@@ -413,6 +460,10 @@
            case CLICK_TYPE_CANCEL_BUY:
                cancelOrder(delegateInfo.code.ToStdString());
                break;
            case CLICK_TYPE_NOT_BUY:
                cancelOrder(delegateInfo.code.ToStdString());
                forbiddenBuy(delegateInfo.code.ToStdString());
                break;
            case CLICK_TYPE_VIEW_DETAIL:
                try {
@@ -522,13 +573,51 @@
    wxButton* openTradeQueueBtn = new wxButton(panel, wxID_ANY, "查看全部");
    avaiableMoneyLabel = new wxStaticText(panel, wxID_ANY, "0.00", wxDefaultPosition, wxSize(80 * DPI / 100, -1));
    avaiableMoneyLabel = new wxStaticText(panel, wxID_ANY, "0.00", wxDefaultPosition, wxSize(-1, -1));
    wxBoxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
    topSizer->Add(msgCtrl, 1, wxEXPAND);
    topSizer->Add(avaiableMoneyLabel, 0, wxEXPAND | wxALL, 3);
    topSizer->Add(openTradeQueueBtn, 0);
    currentTime = new wxStaticText(panel, wxID_ANY, "00:00:00", wxDefaultPosition, wxSize(-1, -1));
    wxButton* repaireBtn = new wxButton(panel, wxID_ANY, "刷新");
    wxBoxSizer* sizer1 = new wxBoxSizer(wxVERTICAL);
    sizer1->Add(currentTime, 0, wxALL, 1);
    sizer1->Add(repaireBtn, 0);
    topSizer->Add(sizer1, 0, wxRIGHT, 2);
    sizer1= new wxBoxSizer(wxVERTICAL);
    sizer1->Add(avaiableMoneyLabel, 0, wxALL, 1);
    sizer1->Add(openTradeQueueBtn, 0);
    topSizer->Add(sizer1);
    wxButton*  openTradeQueue = new wxButton(panel, wxID_ANY, "打开队列");
    openTradeQueue->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        wxTextEntryDialog dialog(this, "股票代码", "请输入股票代码", "");
        if (dialog.ShowModal() == wxID_OK) {
            wxString input = dialog.GetValue();
            if (input.Length() != 6) {
                wxMessageBox("代码输入错误");
                return;
            }
            WindowPosSize r = MyConfigUtil::getTradeQueueWindowPos();
            if (r.x == -1 && r.y == -1) {
                r.x = 0;
                r.y = 0;
                r.width = 400;
                r.height = 400;
            }
            TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(input.ToStdString(), input.ToStdString(), wxPoint(r.x, r.y), wxSize(r.width, r.height));
            tradeQueueFrame->Show(true);
        }
    });
    topSizer->Add(openTradeQueue, 0, wxALIGN_BOTTOM|wxLEFT, 2);
    sizer->Add(topSizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 5);
@@ -537,6 +626,16 @@
    openTradeQueueBtn->Bind(wxEVT_BUTTON, &MainFrame::OnButtonOpenTradeQueueClick, this);
    repaireBtn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
        string nowTime = TimeUtil::format(TimeUtil::getNowTimeStamp(),"%H:%M:%S");
        wxString updateTime = currentTime->GetLabelText().ToStdString();
        // 将时间转为s
        if (TimeUtil::timeStr2Seconds(nowTime) - TimeUtil::timeStr2Seconds(updateTime.ToStdString()) > 10||true) {
            // 大于10s
            std::thread t1(startRequestDelegatedInfoListTask, this);
            t1.detach();
        }
    });
    std::thread t1(startRequestDelegatedInfoListTask, this);
@@ -586,7 +685,7 @@
void MainFrame::refresh()
{
    cout << "刷新时间:" << TimeUtil::getNowTimeStamp() << " 数量:" << delegateList.size() << endl;
    //cout << "刷新时间:" << TimeUtil::getNowTimeStamp() << " 数量:" << delegateList.size() << endl;
    m_listCtrl->DeleteAllItems();
    for (list<DelegateInfo>::iterator e = delegateList.begin(); e != delegateList.end(); ++e) {
        DelegateInfo info = *e;
@@ -654,6 +753,9 @@
            if (doc.HasMember(L"zyltgb"))
                delegateInfo.zyltgb = doc[L"zyltgb"].GetString();
            if (doc.HasMember(L"mode"))
                delegateInfo.mode = doc[L"mode"].GetInt();
            fresults.push_back(delegateInfo);
        }
    }
@@ -706,10 +808,11 @@
        start_time = TimeUtil::getNowTimeStamp();
        // 根据ID
        if (this != nullptr) {
            this->currentTime->SetLabelText(TimeUtil::format(TimeUtil::getNowTimeStamp(),"%H:%M:%S"));
            this->delegateList = delegateResult.delegates;
            this->avaiableMoneyLabel->SetLabelText(delegateResult.money);
            this->refresh();
            cout << "刷新UI耗时:" << TimeUtil::getNowTimeStamp() - start_time << endl;
            //cout << "刷新UI耗时:" << TimeUtil::getNowTimeStamp() - start_time << endl;
        }
    }
    catch (string st) {
DelegateQueue/MainFrame.h
@@ -28,6 +28,7 @@
    wxDataViewListCtrl* m_listCtrl;
    wxStaticText* msgCtrl;
    wxStaticText* avaiableMoneyLabel;
    wxStaticText* currentTime;
    list<DelegateInfo> delegateList;
    bool killed;
    long msgExpireTime;
DelegateQueue/MyNetworkApi.cpp
@@ -16,7 +16,7 @@
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    //return result;
    /*string result = "{\"code\": 0, \"data\": {\"account_available_money\": 142688.82, \"delegates\": [{\"id\": \"110010190002045\", \"code_info\": [\"603332\", \"\\u82cf\\u5dde\\u9f99\\u67701\"], \"total_num\": 21234, \"finish_num\": 9999, \"buy1_money\": \"2541.76\\u4e07\", \"big_num_count\": 3, \"big_num_money\": \"1475.14\\u4e07\", \"not_deal_big_num_count\": [1, 1], \"not_deal_big_num_money\": [\"984.9\\u4e07\", \"502.35\\u4e07\"], \"left_count\": 0, \"volume_rate\": 0.78, \"left_money\": \"693.34\\u4e07\", \"pay_attention\": true, \"trade_progress_percent\": 27.28, \"limit_up_price\": 9.85, \"is_near_big_order\": true, \"block\": \"\\u5316\\u5de5-1\", \"trade_queue\": [[7039, 2], [20, 1], [1754, 0], [1663, 0], [5100, 2]]},{\"id\": \"110010190002046\", \"code_info\": [\"001696\", \"\\u82cf\\u5dde\\u9f99\\u67702\"], \"total_num\": 21234, \"finish_num\": 9999, \"buy1_money\": \"2541.76\\u4e07\", \"big_num_count\": 3, \"big_num_money\": \"1475.14\\u4e07\", \"not_deal_big_num_count\": [1, 1], \"not_deal_big_num_money\": [\"984.9\\u4e07\", \"502.35\\u4e07\"], \"left_count\": 0, \"volume_rate\": 0.78, \"left_money\": \"693.34\\u4e07\", \"pay_attention\": true, \"trade_progress_percent\": 27.28, \"limit_up_price\": 9.85, \"is_near_big_order\": true, \"block\": \"\\u5316\\u5de5-1\", \"trade_queue\": [[7039, 2], [20, 1], [1754, 0], [1663, 0], [5100, 2]]},{\"id\": \"110010190002047\", \"code_info\": [\"600383\", \"\\u82cf\\u5dde\\u9f99\\u67703\"], \"total_num\": 21234, \"finish_num\": 9999, \"buy1_money\": \"2541.76\\u4e07\", \"big_num_count\": 3, \"big_num_money\": \"1475.14\\u4e07\", \"not_deal_big_num_count\": [1, 1], \"not_deal_big_num_money\": [\"984.9\\u4e07\", \"502.35\\u4e07\"], \"left_count\": 0, \"volume_rate\": 0.78, \"left_money\": \"693.34\\u4e07\", \"pay_attention\": true, \"trade_progress_percent\": 27.28, \"limit_up_price\": 9.85, \"is_near_big_order\": true, \"block\": \"\\u5316\\u5de5-1\", \"trade_queue\": [[7039, 2], [20, 1], [1754, 0], [1663, 0], [5100, 2]]}]}}";*/
    //string result = "{\"code\": 0, \"data\": {\"account_available_money\": 142688.82, \"delegates\": [{\"id\": \"110010190002045\", \"code_info\": [\"603332\", \"\\u82cf\\u5dde\\u9f99\\u67701\"], \"total_num\": 21234, \"finish_num\": 9999, \"buy1_money\": \"2541.76\\u4e07\", \"big_num_count\": 3, \"big_num_money\": \"1475.14\\u4e07\", \"not_deal_big_num_count\": [1, 1], \"not_deal_big_num_money\": [\"984.9\\u4e07\", \"502.35\\u4e07\"], \"left_count\": 0, \"volume_rate\": 0.78, \"left_money\": \"693.34\\u4e07\", \"pay_attention\": true, \"trade_progress_percent\": 27.28, \"limit_up_price\": 9.85, \"is_near_big_order\": true, \"block\": \"\\u5316\\u5de5-1\", \"trade_queue\": [[7039, 2], [20, 1], [1754, 0], [1663, 0], [5100, 2]]},{\"id\": \"110010190002046\", \"code_info\": [\"001696\", \"\\u82cf\\u5dde\\u9f99\\u67702\"], \"total_num\": 21234, \"finish_num\": 9999, \"buy1_money\": \"2541.76\\u4e07\", \"big_num_count\": 3, \"big_num_money\": \"1475.14\\u4e07\", \"not_deal_big_num_count\": [1, 1], \"not_deal_big_num_money\": [\"984.9\\u4e07\", \"502.35\\u4e07\"], \"left_count\": 0, \"volume_rate\": 0.78, \"left_money\": \"693.34\\u4e07\", \"pay_attention\": true, \"trade_progress_percent\": 27.28, \"limit_up_price\": 9.85, \"is_near_big_order\": true, \"block\": \"\\u5316\\u5de5-1\", \"trade_queue\": [[7039, 2], [20, 1], [1754, 0], [1663, 0], [5100, 2]]},{\"id\": \"110010190002047\", \"code_info\": [\"600383\", \"\\u82cf\\u5dde\\u9f99\\u67703\"], \"total_num\": 21234, \"finish_num\": 9999, \"buy1_money\": \"2541.76\\u4e07\", \"big_num_count\": 3, \"big_num_money\": \"1475.14\\u4e07\", \"not_deal_big_num_count\": [1, 1], \"not_deal_big_num_money\": [\"984.9\\u4e07\", \"502.35\\u4e07\"], \"left_count\": 0, \"volume_rate\": 0.78, \"left_money\": \"693.34\\u4e07\", \"pay_attention\": true, \"trade_progress_percent\": 27.28, \"limit_up_price\": 9.85, \"is_near_big_order\": true, \"block\": \"\\u5316\\u5de5-1\", \"trade_queue\": [[7039, 2], [20, 1], [1754, 0], [1663, 0], [5100, 2]]}]}}";
    return result;
}
@@ -80,3 +80,23 @@
    string result = base_trade_request(std::string(json_content));
    return result;
}
string MyNetworkApi::add_black(string code)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.Int(201);
    writer.Key("data");
    writer.StartObject();
    writer.Key("codes");
    writer.StartArray();
    writer.String(code.c_str());
    writer.EndArray();
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    return result;
}
DelegateQueue/MyNetworkApi.h
@@ -14,5 +14,12 @@
    /// <param name="code"></param>
    /// <returns></returns>
    static string get_deal_big_money_list(string code);
    /// <summary>
    /// 加入黑名单
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    static string add_black(string code);
};
DelegateQueue/config.cfg
@@ -1,2 +1,2 @@
trade_queue_window = "[\n    -998,\n    123,\n    500,\n    466\n]";
main_window = "[\n    773,\n    205,\n    600,\n    660\n]";
trade_queue_window = "[\n    -1160,\n    329,\n    522,\n    466\n]";
main_window = "[\n    266,\n    251,\n    600,\n    660\n]";
FloatTrade/CBuyDlg.cpp
@@ -81,7 +81,7 @@
    }
    try {
        NetworkApi::buy(code, volume, price);
        NetworkApi::buy(code, volume, 0);
        MessageBox(_T("下单成功"), _T("下单结果"), MB_TASKMODAL);
    }
    catch (CString st) {
FloatTrade/CCBBuyDlg.cpp
New file
@@ -0,0 +1,159 @@
// CCBBuyDlg.cpp: 实现文件
//
#include "common/pch.h"
#include "FloatTrade.h"
#include "CCBBuyDlg.h"
#include "afxdialogex.h"
#include "../common/NetworkApi.h"
#include "../common/StringUtil.h"
#include "../common/JsonUtil.h"
// CCBBuyDlg 对话框
IMPLEMENT_DYNAMIC(CCBBuyDlg, CDialogEx)
CCBBuyDlg::CCBBuyDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_DIALOG_CB_TRADE, pParent)
{
}
CCBBuyDlg::~CCBBuyDlg()
{
}
void CCBBuyDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_CODE, editCode);
    DDX_Control(pDX, IDC_EDIT_VOLUME, editVolume);
}
BEGIN_MESSAGE_MAP(CCBBuyDlg, CDialogEx)
    ON_BN_CLICKED(IDC_BUTTON_BUY, &CCBBuyDlg::OnBnClickedButtonBuy)
    ON_BN_CLICKED(IDC_BUTTON_SELL, &CCBBuyDlg::OnBnClickedButtonSell)
END_MESSAGE_MAP()
// CCBBuyDlg 消息处理程序
void CCBBuyDlg::OnBnClickedButtonBuy()
{
    CString code;
    editCode.GetWindowTextW(code);
    CString volume;
    editVolume.GetWindowTextW(volume);
    try {
        if (code.GetLength() != 6) {
            throw CString("可转债代码输入不正确");
        }
        if (code.Find(L"11") != 0 && code.Find(L"12") != 0) {
            throw CString("不为可转债代码");
        }
        if (volume.GetLength() < 1) {
            throw CString("请输入买入量");
        }
        string result = NetworkApi::buy_cb(StringUtil::cstring2String(code), stoi(StringUtil::cstring2String(volume)));
        auto doc = JsonUtil::parseUTF16(result);
        if (doc.IsObject()) {
            if (doc[L"code"].GetInt() != 0) {
                throw doc[L"msg"].GetString();
            }
            else {
                if (doc[L"data"].HasMember(L"statusMsg")) {
                    CString statusMsg = doc[L"data"][L"statusMsg"].GetString();
                    if (statusMsg.IsEmpty()) {
                        MessageBox(L"下单成功");
                    }
                    else {
                        AfxMessageBox(statusMsg);
                    }
                }
                else if (doc[L"data"].HasMember(L"orderStatusMsg")) {
                    CString statusMsg = doc[L"data"][L"orderStatusMsg"].GetString();
                    if (statusMsg.IsEmpty()) {
                        MessageBox(L"下单成功");
                    }
                    else {
                        AfxMessageBox(statusMsg);
                    }
                }
            }
        }
    }
    catch (CString msg) {
        AfxMessageBox(msg);
    }
    catch (wstring msg) {
        AfxMessageBox(msg.c_str());
    }
}
BOOL CCBBuyDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    editVolume.SetWindowTextW(L"10");
    return TRUE;
}
void CCBBuyDlg::OnBnClickedButtonSell()
{
    CString code;
    editCode.GetWindowTextW(code);
    CString volume;
    editVolume.GetWindowTextW(volume);
    try {
        if (code.GetLength() != 6) {
            throw CString("可转债代码输入不正确");
        }
        if (code.Find(L"11") != 0 && code.Find(L"12") != 0) {
            throw CString("不为可转债代码");
        }
        if (volume.GetLength() < 1) {
            throw CString("请输入买入量");
        }
        string result = NetworkApi::sell_cb(StringUtil::cstring2String(code), stoi(StringUtil::cstring2String(volume)));
        auto doc = JsonUtil::parseUTF16(result);
        if (doc.IsObject()) {
            if (doc[L"code"].GetInt() != 0) {
                throw doc[L"msg"].GetString();
            }
            else {
                if (doc[L"data"].HasMember(L"statusMsg")) {
                    CString statusMsg = doc[L"data"][L"statusMsg"].GetString();
                    if (statusMsg.IsEmpty()) {
                        MessageBox(L"卖出委托成功");
                    }
                    else {
                        AfxMessageBox(statusMsg);
                    }
                }
                else if (doc[L"data"].HasMember(L"orderStatusMsg")) {
                    CString statusMsg = doc[L"data"][L"orderStatusMsg"].GetString();
                    if (statusMsg.IsEmpty()) {
                        MessageBox(L"卖出委托成功");
                    }
                    else {
                        AfxMessageBox(statusMsg);
                    }
                }
            }
        }
    }
    catch (CString msg) {
        AfxMessageBox(msg);
    }
    catch (wstring msg) {
        AfxMessageBox(msg.c_str());
    }
}
FloatTrade/CCBBuyDlg.h
New file
@@ -0,0 +1,29 @@
#pragma once
// CCBBuyDlg 对话框
class CCBBuyDlg : public CDialogEx
{
    DECLARE_DYNAMIC(CCBBuyDlg)
public:
    CCBBuyDlg(CWnd* pParent = nullptr);   // 标准构造函数
    virtual ~CCBBuyDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_DIALOG_CB_TRADE };
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedButtonBuy();
    CEdit editCode;
    CEdit editVolume;
    virtual BOOL OnInitDialog();
    afx_msg void OnBnClickedButtonSell();
};
FloatTrade/CCodeNameDlg.cpp
New file
@@ -0,0 +1,108 @@
// CCodeNameDlg.cpp: 实现文件
//
#include "common/pch.h"
#include "FloatTrade.h"
#include "CCodeNameDlg.h"
#include "afxdialogex.h"
#include "../common/NetworkApi.h"
#include "../common/JsonUtil.h"
#include "Constant.h"
#include "ConfigUtil.h"
#define CODE_NUM 10
// CCodeNameDlg 对话框
IMPLEMENT_DYNAMIC(CCodeNameDlg, CDialogEx)
CCodeNameDlg::CCodeNameDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_DIALOG_CODE_NAME, pParent)
{
}
CCodeNameDlg::~CCodeNameDlg()
{
}
void CCodeNameDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CCodeNameDlg, CDialogEx)
    ON_BN_CLICKED(IDOK, &CCodeNameDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// CCodeNameDlg 消息处理程序
void CCodeNameDlg::OnBnClickedOk()
{
    // 保存代码名称
    int codeCtrls[CODE_NUM] = { IDC_STATIC_CODE_1, IDC_STATIC_CODE_2, IDC_STATIC_CODE_3 , IDC_STATIC_CODE_4 , IDC_STATIC_CODE_5 , IDC_STATIC_CODE_6 , IDC_STATIC_CODE_7 , IDC_STATIC_CODE_8 , IDC_STATIC_CODE_9 , IDC_STATIC_CODE_10 };
    int nameCtrls[CODE_NUM] = { IDC_EDIT_NAME_1, IDC_EDIT_NAME_2, IDC_EDIT_NAME_3 , IDC_EDIT_NAME_4 , IDC_EDIT_NAME_5 , IDC_EDIT_NAME_6 , IDC_EDIT_NAME_7 , IDC_EDIT_NAME_8 , IDC_EDIT_NAME_9 , IDC_EDIT_NAME_10 };
    for (int i = 0; i < CODE_NUM; i++) {
        CString code;
        ((CStatic*)GetDlgItem(codeCtrls[i]))->GetWindowTextW(code);
        CString name;
        ((CEdit*)GetDlgItem(nameCtrls[i]))->GetWindowTextW(name);
        if (code.GetLength() != 6) {
            continue;
        }
        Constant::codeNameMap[StringUtil::cstring2String(code)] = name;
    }
    ConfigUtil::setCodeNames(Constant::codeNameMap);
    CDialogEx::OnOK();
}
BOOL CCodeNameDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    if (Constant::codeNameMap.empty()) {
        requestPositions();
    }
    int codeCtrls[CODE_NUM] ={IDC_STATIC_CODE_1, IDC_STATIC_CODE_2, IDC_STATIC_CODE_3 , IDC_STATIC_CODE_4 , IDC_STATIC_CODE_5 , IDC_STATIC_CODE_6 , IDC_STATIC_CODE_7 , IDC_STATIC_CODE_8 , IDC_STATIC_CODE_9 , IDC_STATIC_CODE_10};
    int nameCtrls[CODE_NUM] = { IDC_EDIT_NAME_1, IDC_EDIT_NAME_2, IDC_EDIT_NAME_3 , IDC_EDIT_NAME_4 , IDC_EDIT_NAME_5 , IDC_EDIT_NAME_6 , IDC_EDIT_NAME_7 , IDC_EDIT_NAME_8 , IDC_EDIT_NAME_9 , IDC_EDIT_NAME_10 };
    int index = 0;
    for (std::map<std::string, CString>::iterator e = Constant::codeNameMap.begin(); e != Constant::codeNameMap.end(); e++) {
        string code = (*e).first;
        CString name = (*e).second;
        ((CStatic*)GetDlgItem(codeCtrls[index]))->SetWindowTextW(CString(code.c_str()));
        ((CEdit*)GetDlgItem(nameCtrls[index]))->SetWindowTextW(name);
        index++;
    }
    return TRUE;
}
void CCodeNameDlg::requestPositions()
{
    string result = NetworkApi::get_all_positions();
    auto doc = JsonUtil::parseUTF16(result);
    if (doc.IsObject() && doc[L"code"] == 0) {
        auto array = doc[L"data"].GetArray();
        for (int i = 0; i < array.Size(); i++) {
            auto  data = array[i].GetObjectW();
            CString codew = data[L"code"].GetString();
            string code = StringUtil::cstring2String(codew);
            CString codeName = data[L"code_name"].GetString();
            Constant::codeNameMap[code] = codeName;
        }
    }
    cout << result << endl;
}
FloatTrade/CCodeNameDlg.h
New file
@@ -0,0 +1,29 @@
#pragma once
// CCodeNameDlg 对话框
class CCodeNameDlg : public CDialogEx
{
    DECLARE_DYNAMIC(CCodeNameDlg)
public:
    CCodeNameDlg(CWnd* pParent = nullptr);   // 标准构造函数
    virtual ~CCodeNameDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_DIALOG_CODE_NAME };
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedOk();
    virtual BOOL OnInitDialog();
private:
    void requestPositions();
};
FloatTrade/CSettingDlg.cpp
@@ -7,12 +7,14 @@
#include "afxdialogex.h"
#include "../common/StringUtil.h"
#include "../common/NetworkApi.h"
#include "../common/JsonUtil.h"
#include "ConfigUtil.h"
#include <iostream>
#include <string>
#include <sstream>
#include <regex>
#include <iconv.h>
using namespace std;
// CSettingDlg 对话框
@@ -32,15 +34,15 @@
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, edit_trade_refresh_space_time, editRefreshSpaceTime);
    DDX_Control(pDX, edit_trade_group_space_time, editGroupSpaceTime);
    DDX_Control(pDX, edit_group_pos, editGroupPos);
    DDX_Control(pDX, edit_per_code_buy_money, editPerCodeBuyMoney);
    DDX_Control(pDX, edit_normal_buy_count, editNormalBuyCount);
    DDX_Control(pDX, edit_radical_buy_count, editRadicalBuyCount);
}
BEGIN_MESSAGE_MAP(CSettingDlg, CDialogEx)
    ON_BN_CLICKED(btn_sure, &CSettingDlg::OnBnClickedsure)
    ON_BN_CLICKED(btn_sure_network, &CSettingDlg::OnBnClickedsurenetwork)
    ON_BN_CLICKED(btn_radical_buy_block_count_sure, &CSettingDlg::OnBnClickedradicalbuyblockcountsure)
END_MESSAGE_MAP()
@@ -52,43 +54,31 @@
    CString refreshSpace;
    editRefreshSpaceTime.GetWindowTextW(refreshSpace);
    CString groupSpace;
    editGroupSpaceTime.GetWindowTextW(groupSpace);
    CString pos;
    editGroupPos.GetWindowTextW(pos);
    if (refreshSpace.GetLength() < 0) {
        AfxMessageBox(L"请填写交易刷新频率");
        return;
    }
    if (groupSpace.GetLength() < 0) {
        AfxMessageBox(L"请填写分组刷新频率");
        return;
    }
    int volume_ids[] = {
        IDC_EDIT_VOLUME_1,IDC_EDIT_VOLUME_2,IDC_EDIT_VOLUME_3,IDC_EDIT_VOLUME_4,IDC_EDIT_VOLUME_5,IDC_EDIT_VOLUME_6,IDC_EDIT_VOLUME_7,
        IDC_EDIT_VOLUME_8,IDC_EDIT_VOLUME_9,IDC_EDIT_VOLUME_10,IDC_EDIT_VOLUME_11,IDC_EDIT_VOLUME_12
    };
    list<POINT> posList;
    if (pos.GetLength() > 0) {
        string result = StringUtil::cstring2String(pos);
        istringstream iss(result);    // 输入流
        string token;            // 接收缓冲区
        while (getline(iss, token, '\n'))    // 以split为分隔符
        {
            cout << token.find(",") << endl; // 输出
            if (token.find(",")>0) {
                int x = stoi(token.substr(0, token.find(",")));
                int y = stoi(token.substr(token.find(",") + 1));
                posList.push_back(POINT({ x,y }));
            }
    list<int> volumeList;
    for (int i = 0; i < 12; i++) {
        CEdit* edit = (CEdit*)GetDlgItem(volume_ids[i]);
        CString volumeC;
        edit->GetWindowTextW(volumeC);
        if (!StringUtil::isNumber(StringUtil::cstring2String(volumeC))) {
            AfxMessageBox(L"金额必须为数字");
            return;
        }
        volumeList.push_back(stoi(StringUtil::cstring2String(volumeC).c_str()));
    }
    ConfigUtil::setThsAutoClickTimeSpace(stoi(StringUtil::cstring2String(groupSpace)));
    ConfigUtil::setVolumesSetting(volumeList);
    ConfigUtil::setThsAutoRefreshTimeSpace(stoi(StringUtil::cstring2String(refreshSpace)));
    ConfigUtil::setThsAutoClickPositions(posList);
    AfxMessageBox(L"保存成功", MB_ICONINFORMATION);
}
@@ -96,34 +86,82 @@
BOOL CSettingDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // TODO:  在此添加额外的初始化
    list<POINT> posList = ConfigUtil::getThsAutoClickPositions();
    string st;
    for (list<POINT>::iterator ele = posList.begin(); ele != posList.end(); ++ele) {
        POINT p = *ele;
        st.append(std::to_string(p.x));
        st.append(",");
        st.append(std::to_string(p.y));
        st.append("\r\n");
    }
    editGroupPos.SetWindowTextW(CString( st.c_str()));
    int ct = ConfigUtil::getThsAutoClickTimeSpace();
    editGroupSpaceTime.SetWindowTextW(CString(std::to_string(ct).c_str()));
    int rt = ConfigUtil::getThsAutoRefreshTimeSpace();
    editRefreshSpaceTime.SetWindowTextW(CString(std::to_string(rt).c_str()));
    try {
        int money = NetworkApi::get_per_code_buy_money();
        editPerCodeBuyMoney.SetWindowTextW(to_wstring(money).c_str());
        string result = NetworkApi::get_buy_money_and_count();
        auto doc = JsonUtil::parseUTF8(result);
        if (doc.IsObject()) {
            if (doc["code"].GetInt() == 0) {
                BuyDataSettings settings;
                auto data = doc["data"].GetObject();
                auto normal = data["normal"].GetArray();;
                auto radical = data["radical"].GetArray();
                auto moneys_enum = data["moneys"].GetArray();
                settings.normalCount = normal[0].GetInt();
                settings.radicalCount = radical[0].GetInt();
                auto money_list = normal[1].GetArray();
                for (int i = 0; i < money_list.Size(); i++) {
                    auto item = money_list[i].GetArray();
                    settings.normalMoneyList.push_back(TimeMoney({ CString(item[0].GetString()),item[1].GetInt(), item[2].GetInt() }));
                }
                money_list = radical[1].GetArray();
                for (int i = 0; i < money_list.Size(); i++) {
                    auto item = money_list[i].GetArray();
                    settings.radicalMoneyList.push_back(TimeMoney({ CString(item[0].GetString()),item[1].GetInt(), item[2].GetInt() }));
                }
                int moneys[] = { combo_normal_buy_money_1 ,combo_normal_buy_money_2 ,combo_normal_buy_money_3,combo_radical_buy_money_1 ,combo_radical_buy_money_2 ,combo_radical_buy_money_3 };
                for (int i = 0; i < 6; i++) {
                    CComboBox* box = (CComboBox*)GetDlgItem(moneys[i]);
                    for (int i = 0; i < moneys_enum.Size(); i++) {
                        box->AddString(to_wstring(moneys_enum[i].GetInt()).c_str());
                    }
                }
                setBuyDataSetting(settings);
            }
        }
    }
    catch (... ) {
    catch (...) {
    }
    // 初始化下拉框内容
    try {
        int volume_ids[] = {
            IDC_EDIT_VOLUME_1,IDC_EDIT_VOLUME_2,IDC_EDIT_VOLUME_3,IDC_EDIT_VOLUME_4,IDC_EDIT_VOLUME_5,IDC_EDIT_VOLUME_6,IDC_EDIT_VOLUME_7,
            IDC_EDIT_VOLUME_8,IDC_EDIT_VOLUME_9,IDC_EDIT_VOLUME_10,IDC_EDIT_VOLUME_11,IDC_EDIT_VOLUME_12
        };
        list<int> volumeList = ConfigUtil::getVolumesSetting();
        int index = 0;
        for (list<int>::iterator e = volumeList.begin(); e != volumeList.end(); ++e) {
            int volume = *e;
            CEdit* edit = (CEdit*)GetDlgItem(volume_ids[index]);
            edit->SetWindowTextW(to_wstring(volume).c_str());
            index++;
        }
    }
    catch (...) {
    }
    try {
        requestRadicalBuyBlockCount();
    }
    catch (...) {
    
    }
    return TRUE;  // return TRUE unless you set the focus to a control
                  // 异常: OCX 属性页应返回 FALSE
@@ -132,18 +170,278 @@
void CSettingDlg::OnBnClickedsurenetwork()
{
    CString cmoney;
    editPerCodeBuyMoney.GetWindowTextW(cmoney);
    string money = StringUtil::cstring2String(cmoney);
    if (!StringUtil::isNumber(money)) {
        AfxMessageBox(L"输入内容格式错误");
        return;
    }
    try {
         NetworkApi::set_per_code_buy_money(stoi(money.c_str()));
         MessageBox(L"设置成功",L"提示");
        BuyDataSettings settings = getBuyDataSetting();
        rapidjson::StringBuffer buf;
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
        writer.StartArray();
        for (list<TimeMoney>::iterator e = settings.normalMoneyList.begin(); e != settings.normalMoneyList.end(); e++) {
            TimeMoney timeMoney = *e;
            writer.StartArray();
            writer.String(StringUtil::cstring2String(timeMoney.time).c_str());
            writer.Int(timeMoney.money);
            writer.Int(timeMoney.count);
            writer.EndArray();
        }
        writer.EndArray();
        const char* normalMoneyJson = buf.GetString();
        rapidjson::StringBuffer buf1;
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer1(buf1);
        writer1.StartArray();
        for (list<TimeMoney>::iterator e = settings.radicalMoneyList.begin(); e != settings.radicalMoneyList.end(); e++) {
            TimeMoney timeMoney = *e;
            writer1.StartArray();
            writer1.String(StringUtil::cstring2String(timeMoney.time).c_str());
            writer1.Int(timeMoney.money);
            writer1.Int(timeMoney.count);
            writer1.EndArray();
        }
        writer1.EndArray();
        const char* radicalMoneyJson = buf1.GetString();
        NetworkApi::set_buy_money_and_count(settings.normalCount, string(normalMoneyJson), settings.radicalCount, string(radicalMoneyJson));
        MessageBox(L"设置成功", L"提示");
    }
    catch (CString st) {
        AfxMessageBox(st);
    }
    catch (wstring st) {
        AfxMessageBox(st.c_str());
    }
}
BuyDataSettings CSettingDlg::getBuyDataSetting()
{
    int normal_times[] = { edit_normal_buy_money_time_1 ,edit_normal_buy_money_time_2 ,edit_normal_buy_money_time_3 };
    int normal_moneys[] = { combo_normal_buy_money_1 ,combo_normal_buy_money_2 ,combo_normal_buy_money_3 };
    int normal_counts[] = { edit_normal_buy_count_1 ,edit_normal_buy_count_2 ,edit_normal_buy_count_3 };
    int radical_times[] = { edit_radical_buy_money_time_1 ,edit_radical_buy_money_time_2 ,edit_radical_buy_money_time_3 };
    int radical_moneys[] = { combo_radical_buy_money_1 ,combo_radical_buy_money_2 ,combo_radical_buy_money_3 };
    int radical_counts[] = { edit_radical_buy_count_1 ,edit_radical_buy_count_2 ,edit_radical_buy_count_3 };
    CString normalCount;
    ((CEdit*)GetDlgItem(edit_normal_buy_count))->GetWindowTextW(normalCount);
    CString radicalCount;
    ((CEdit*)GetDlgItem(edit_radical_buy_count))->GetWindowTextW(radicalCount);
    if (normalCount.IsEmpty() || !StringUtil::isNumber(StringUtil::cstring2String(normalCount))) {
        throw CString(L"正常买入最大数量填写错误");
    }
    if (radicalCount.IsEmpty() || !StringUtil::isNumber(StringUtil::cstring2String(radicalCount))) {
        throw CString(L"扫入买入最大数量填写错误");
    }
    BuyDataSettings settings;
    settings.normalCount = stoi(StringUtil::cstring2String(normalCount).c_str());
    settings.radicalCount = stoi(StringUtil::cstring2String(radicalCount).c_str());
    for (int i = 0; i < 3; i++) {
        CString time;
        CString money;
        CString count;
        ((CEdit*)GetDlgItem(normal_times[i]))->GetWindowTextW(time);
        CComboBox* moneyCombo = ((CComboBox*)GetDlgItem(normal_moneys[i]));
        if (moneyCombo->GetCurSel() >= 0) {
            moneyCombo->GetLBText(moneyCombo->GetCurSel(), money);
        }
        ((CEdit*)GetDlgItem(normal_counts[i]))->GetWindowTextW(count);
        if (!time.IsEmpty() && !money.IsEmpty() && !count.IsEmpty()) {
            if (!validTime(time)) {
                throw CString(L"时间格式错误");
            }
            if (!StringUtil::isNumber(StringUtil::cstring2String(money))) {
                throw CString(L"金额格式错误(必须为正整数)");
            }
            if (!StringUtil::isNumber(StringUtil::cstring2String(count))) {
                throw CString(L"最大买入数量格式错误(必须为正整数)");
            }
            settings.normalMoneyList.push_back(TimeMoney({ time,stoi(StringUtil::cstring2String(money).c_str()),stoi(StringUtil::cstring2String(count).c_str()) }));
        }
    }
    for (int i = 0; i < 3; i++) {
        CString time;
        CString money;
        CString count;
        ((CEdit*)GetDlgItem(radical_times[i]))->GetWindowTextW(time);
        CComboBox* moneyCombo = ((CComboBox*)GetDlgItem(radical_moneys[i]));
        if (moneyCombo->GetCurSel() >= 0) {
            moneyCombo->GetLBText(moneyCombo->GetCurSel(), money);
        }
        ((CEdit*)GetDlgItem(radical_counts[i]))->GetWindowTextW(count);
        if (!time.IsEmpty() && !money.IsEmpty() && !count.IsEmpty()) {
            if (!validTime(time)) {
                throw CString(L"时间格式错误");
            }
            if (!StringUtil::isNumber(StringUtil::cstring2String(money))) {
                throw CString(L"金额格式错误(必须为正整数)");
            }
            if (!StringUtil::isNumber(StringUtil::cstring2String(count))) {
                throw CString(L"最大买入数量格式错误(必须为正整数)");
            }
            settings.radicalMoneyList.push_back(TimeMoney({ time,stoi(StringUtil::cstring2String(money).c_str()),stoi(StringUtil::cstring2String(count).c_str()) }));
        }
    }
    return settings;
}
void CSettingDlg::requestRadicalBuyBlockCount()
{
    list<RadicalBuyBlockInfo> mList;
    string result = NetworkApi::get_radical_buy_block_count();
    auto doc = JsonUtil::parseUTF16(result);
    if (doc.IsObject()) {
        if (doc[L"code"].GetInt() == 0) {
         auto array =    doc[L"data"].GetArray();
         for (int i = 0; i < array.Size(); i++) {
            auto item =  array[i].GetArray();
            mList.push_back(RadicalBuyBlockInfo({ item[0].GetString(),item[1].GetInt()}));
         }
        }
    }
    int block_ids[] = { IDC_EDIT_RADICAL_BUY_BLOCK_1, IDC_EDIT_RADICAL_BUY_BLOCK_2, IDC_EDIT_RADICAL_BUY_BLOCK_3, IDC_EDIT_RADICAL_BUY_BLOCK_4 };
    int count_ids[] = { IDC_EDIT_RADICAL_BUY_COUNT_1, IDC_EDIT_RADICAL_BUY_COUNT_2, IDC_EDIT_RADICAL_BUY_COUNT_3, IDC_EDIT_RADICAL_BUY_COUNT_4 };
    int index = 0;
    for (list<RadicalBuyBlockInfo>::iterator e = mList.begin(); e != mList.end(); e++) {
        RadicalBuyBlockInfo info = *e;
        ((CEdit*)GetDlgItem(block_ids[index]))->SetWindowTextW(info.blockName);
        ((CEdit*)GetDlgItem(count_ids[index]))->SetWindowTextW(to_wstring(info.count).c_str());
        index++;
        if (index >= 4) {
            break;
        }
    }
}
void CSettingDlg::setBuyDataSetting(BuyDataSettings setting)
{
    int normal_times[] = { edit_normal_buy_money_time_1 ,edit_normal_buy_money_time_2 ,edit_normal_buy_money_time_3 };
    int normal_moneys[] = { combo_normal_buy_money_1 ,combo_normal_buy_money_2 ,combo_normal_buy_money_3 };
    int normal_counts[] = { edit_normal_buy_count_1 ,edit_normal_buy_count_2 ,edit_normal_buy_count_3 };
    int radical_times[] = { edit_radical_buy_money_time_1 ,edit_radical_buy_money_time_2 ,edit_radical_buy_money_time_3 };
    int radical_moneys[] = { combo_radical_buy_money_1 ,combo_radical_buy_money_2 ,combo_radical_buy_money_3 };
    int radical_counts[] = { edit_radical_buy_count_1 ,edit_radical_buy_count_2 ,edit_radical_buy_count_3 };
    editNormalBuyCount.SetWindowTextW(to_wstring(setting.normalCount).c_str());
    editRadicalBuyCount.SetWindowTextW(to_wstring(setting.radicalCount).c_str());
    int index = 0;
    for (list<TimeMoney>::iterator e = setting.normalMoneyList.begin(); e != setting.normalMoneyList.end(); e++) {
        TimeMoney timeMoney = *e;
        ((CEdit*)GetDlgItem(normal_times[index]))->SetWindowTextW(timeMoney.time);
        CComboBox* box = (CComboBox*)GetDlgItem(normal_moneys[index]);
        int nCount = box->GetCount();
        for (int i = 0; i < nCount; i++)
        {
            CString strItem;
            box->GetLBText(i, strItem);
            if (stoi(StringUtil::cstring2String(strItem).c_str()) == timeMoney.money) {
                box->SetCurSel(i);
                break;
            }
        }
        ((CEdit*)GetDlgItem(normal_counts[index]))->SetWindowTextW(to_wstring(timeMoney.count).c_str());
        index++;
    }
    index = 0;
    for (list<TimeMoney>::iterator e = setting.radicalMoneyList.begin(); e != setting.radicalMoneyList.end(); e++) {
        TimeMoney timeMoney = *e;
        ((CEdit*)GetDlgItem(radical_times[index]))->SetWindowTextW(timeMoney.time);
        CComboBox* box = (CComboBox*)GetDlgItem(radical_moneys[index]);
        int nCount = box->GetCount();
        for (int i = 0; i < nCount; i++)
        {
            CString strItem;
            box->GetLBText(i, strItem);
            if (stoi(StringUtil::cstring2String(strItem).c_str()) == timeMoney.money) {
                box->SetCurSel(i);
                break;
            }
        }
        ((CEdit*)GetDlgItem(radical_counts[index]))->SetWindowTextW(to_wstring(timeMoney.count).c_str());
        index++;
    }
}
bool CSettingDlg::validTime(CString st)
{
    // 正则表达式:匹配 HH:MM:SS 格式
    std::regex timePattern(R"((([01]\d|2[0-3]):([0-5]\d):([0-5]\d))?)");
    return std::regex_match(StringUtil::cstring2String(st), timePattern);
}
void CSettingDlg::OnBnClickedradicalbuyblockcountsure()
{
    int block_ids[] = { IDC_EDIT_RADICAL_BUY_BLOCK_1, IDC_EDIT_RADICAL_BUY_BLOCK_2, IDC_EDIT_RADICAL_BUY_BLOCK_3, IDC_EDIT_RADICAL_BUY_BLOCK_4 };
    int count_ids[] = { IDC_EDIT_RADICAL_BUY_COUNT_1, IDC_EDIT_RADICAL_BUY_COUNT_2, IDC_EDIT_RADICAL_BUY_COUNT_3, IDC_EDIT_RADICAL_BUY_COUNT_4 };
    try {
        list<RadicalBuyBlockInfo> mList;
        // 获取数据
        for (int i = 0; i < 4; i++) {
            CString block;
            CString count;
            ((CEdit*)GetDlgItem(block_ids[i]))->GetWindowTextW(block);
            ((CEdit*)GetDlgItem(count_ids[i]))->GetWindowTextW(count);
            if (!block.IsEmpty() && !count.IsEmpty()) {
                if (!StringUtil::isNumber(StringUtil::cstring2String(count))) {
                    throw CString(L"输入格式错误");
                }
                mList.push_back(RadicalBuyBlockInfo({ block , stoi(StringUtil::cstring2String(count)) }));
            }
        }
        rapidjson::StringBuffer buf;
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
        writer.StartArray();
        for (list<RadicalBuyBlockInfo>::iterator e = mList.begin(); e != mList.end(); e++) {
            RadicalBuyBlockInfo info = *e;
            writer.StartArray();
            writer.String(StringUtil::cstring2StringV2(info.blockName).c_str());
            writer.Int(info.count);
            writer.EndArray();
        }
        writer.EndArray();
        const char* json = buf.GetString();
        // 设置数据
        NetworkApi::set_radical_buy_block_count(StringUtil::base64_encode(json));
        MessageBox(L"设置成功",L"提示");
    }
    catch (CString msg) {
        AfxMessageBox(msg);
    }
    catch (wstring msg) {
        AfxMessageBox(msg.c_str());
    }
}
FloatTrade/CSettingDlg.h
@@ -1,5 +1,6 @@
#pragma once
#include "DataStruct.h"
// CSettingDlg 对话框
@@ -24,9 +25,20 @@
public:
    afx_msg void OnBnClickedsure();
    CEdit editRefreshSpaceTime;
    CEdit editGroupSpaceTime;
    CEdit editGroupPos;
    virtual BOOL OnInitDialog();
    CEdit editPerCodeBuyMoney;
    afx_msg void OnBnClickedsurenetwork();
    CEdit editNormalBuyCount;
    CEdit editRadicalBuyCount;
private:
    BuyDataSettings getBuyDataSetting();
    void requestRadicalBuyBlockCount();
    void setBuyDataSetting(BuyDataSettings setting);
    static bool validTime(CString st);
public:
    afx_msg void OnBnClickedradicalbuyblockcountsure();
};
FloatTrade/ConfigUtil.cpp
@@ -4,6 +4,8 @@
#include <iostream>
#include <fstream>
#include "../common/JsonUtil.h"
#include "../common/TimeUtil.h"
bool fileExists(const std::string& filename) {
    std::ifstream file(filename);
@@ -109,7 +111,8 @@
    libconfig::Config mConfig;
    readConfig(mConfig);
    libconfig::Setting& root = mConfig.getRoot();
    root.remove(key);
    root.remove(key.c_str());
    writeConfig(mConfig);
}
bool ConfigUtil::isTradeRefresh()
@@ -203,19 +206,19 @@
    setStringConfig("sell_rule_show_pos", pos);
}
POINT ConfigUtil::getWindowPos()
MyPoint ConfigUtil::getWindowPos()
{
    
    // 页码位置
    try {
         string data =    readStringConfig("window_pos");
         rapidjson::Document root = JsonUtil::parseUTF8(data);
         return     POINT({ root[0].GetInt(), root[1].GetInt()});
         return     MyPoint({ root[0].GetInt(), root[1].GetInt()});
    }
    catch (...) {
    }
    return POINT({ 0,0 });
    return MyPoint({ 0,0 });
@@ -244,57 +247,102 @@
    setIntConfig("ths_auto_refresh_time_space", ms);
}
std::list<POINT> ConfigUtil::getThsAutoClickPositions()
list<int> ConfigUtil::getVolumesSetting()
{
    std::list<POINT> posList;
    try {
        string result =    readStringConfig("ths_auto_click_positions");
        rapidjson::Document root = JsonUtil::parseUTF8(result);
        for (rapidjson::SizeType i = 0; i < root.GetArray().Size(); i++) {
            posList.push_back(POINT({ root.GetArray()[i].GetArray()[0].GetInt(),root.GetArray()[i].GetArray()[1].GetInt() }));
        list<int> volumeList;
        string result = readStringConfig("volume_settings");
        auto doc = JsonUtil::parseUTF8(result);
        auto array = doc.GetArray();
        for (int i = 0; i < array.Size(); i++) {
            volumeList.push_back(array[i].GetInt());
        }
        return volumeList;
    }
    catch (...) {
    }
    return list<int>();
}
void ConfigUtil::setVolumesSetting(list<int> volumes)
{
    string st = "[";
    int index = 0;
    for (list<int>::iterator e = volumes.begin(); e != volumes.end(); ++e) {
        index++;
        st.append(to_string(*e));
        if (index != volumes.size()) {
            st.append(",");
        }
    }
    st.append("]");
    setStringConfig("volume_settings", st);
}
void ConfigUtil::setCodeNames(map<string, CString> codeNameMap)
{
    // 将map转为json
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    for (map<string, CString>::iterator el = codeNameMap.begin(); el != codeNameMap.end(); el++) {
        string code = (*el).first;
        CString name = (*el).second;
        writer.Key(code.c_str());
        writer.String(StringUtil::cstring2String( name).c_str());
    }
    writer.EndObject();
    const char* json_content = buf.GetString();
    string key = "code_name_map-";
    key.append(TimeUtil::getNowTime("%Y%m%d"));
    setStringConfig(key.c_str(), json_content);
    // 删除过期的代码数据
    list<string> kyes = getKeys();
    for (auto e = kyes.begin(); e != kyes.end(); ++e) {
        string k = *e;
        if (!k._Equal(key) && k.find("code_name_map-") == 0) {
            delKey(k);
        }
    }
}
map<string, CString> ConfigUtil::getCodeNames()
{
    map<string, CString> m;
    try {
        string key = "code_name_map-";
        key.append(TimeUtil::getNowTime("%Y%m%d"));
        string result = readStringConfig(key.c_str());
        if (!result.empty()) {
            auto doc = JsonUtil::parseUTF8(result);
            auto root = doc.GetObjectW();
            for (auto e = root.MemberBegin(); e != root.MemberEnd(); ++e) {
                string code = (*e).name.GetString();
                string name = (*e).value.GetString();
                m[code] = CString(name.c_str());
            }
        }
    }
    catch (...) {
    }
    return posList;
    return m;
}
void ConfigUtil::setThsAutoClickPositions(std::list<POINT> posList)
void ConfigUtil::setBuyMoney(int money)
{
    string st = "[";
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartArray();
    for (std::list<POINT>::iterator el = posList.begin(); el != posList.end(); el++) {
        POINT p = *el;
        writer.StartArray();
        writer.Int(p.x);
        writer.Int(p.y);
        writer.EndArray();
    }
    writer.EndArray();
    const char* json_content = buf.GetString();
    setStringConfig("ths_auto_click_positions",string(json_content));
    setIntConfig("buy_money", money);
}
int ConfigUtil::getThsAutoClickTimeSpace()
int ConfigUtil::getBuyMoney()
{
    try {
        return    readIntConfig("ths_auto_click_time_space");
        return readIntConfig("buy_money");
    }
    catch (...) {
        // 默认2w
        return 20000;
    }
    return 0;
}
void ConfigUtil::setThsAutoClickTimeSpace(int ms)
{
    setIntConfig("ths_auto_click_time_space", ms);
}
FloatTrade/ConfigUtil.h
@@ -1,7 +1,16 @@
#pragma once
#include<string>
#include <libconfig.h++>
#include<map>
#include<list>
struct MyPoint {
    long x;
    long y;
};
using namespace std;
class ConfigUtil
{
@@ -36,18 +45,33 @@
    static void setTradeQuickKey(bool enable);
    static void setSellRuleDialogShowPos(int x, int y);
    // 窗口位置
    static POINT getWindowPos();
    static void setWindowPos(int x,int y);
    //交易刷新频率
    static int getThsAutoRefreshTimeSpace();
    static void setThsAutoRefreshTimeSpace(int ms);
    //分组刷新坐标
    static std::list<POINT> getThsAutoClickPositions();
    static void setThsAutoClickPositions(std::list<POINT> posList);
    //分组刷新频率
    static int getThsAutoClickTimeSpace();
    static void setThsAutoClickTimeSpace(int ms);
    // 量设置
    static list<int> getVolumesSetting();
    static void setVolumesSetting(list<int> volumes);
    // 窗口位置
    static MyPoint getWindowPos();
    // 保存代码名字映射
    static void setCodeNames(std::map<string, CString> codeNameMap);
    // 获取代码名字映射
    static map<string, CString> getCodeNames();
    // 买入金额设置
    static void setBuyMoney(int money);
    // 买入金额获取
    static int getBuyMoney();
FloatTrade/Constant.cpp
New file
@@ -0,0 +1,8 @@
#include "common/pch.h"
#include "Constant.h"
#include "ConfigUtil.h"
std::map<std::string, CString> Constant::codeNameMap;
void Constant::loadCodeNames() {
    codeNameMap = ConfigUtil::getCodeNames();
}
FloatTrade/Constant.h
New file
@@ -0,0 +1,10 @@
#pragma once
#include <string>
#include <map>
class Constant {
public:
    static std::map<std::string, CString> codeNameMap;
    static void loadCodeNames();
};
FloatTrade/DataStruct.h
New file
@@ -0,0 +1,48 @@
#pragma once
#include <afxstr.h>
#include<list>
using namespace std;
struct SellRule
{
    CString id_;
    CString code;
    int buy1_volume;
    //买1价格
    CString buy1_price;
    //卖量
    int sell_volume;
    //卖价格类型
    int sell_price_type;
    CString create_time;
    int excuted;
    CString day;
    CString end_time;
    // 0-买 1-买撤 2-卖 3-卖撤
    int type;
};
struct Buy1Info {
    int volume;
    double price;
};
struct TimeMoney {
    CString time;
    int money;
    int count;
};
struct BuyDataSettings
{
    int normalCount;
    list<TimeMoney> normalMoneyList;
    int radicalCount;
    list<TimeMoney> radicalMoneyList;
};
struct RadicalBuyBlockInfo {
    CString blockName;
    int count;
};
FloatTrade/FloatTrade.aps
Binary files differ
FloatTrade/FloatTrade.cpp
@@ -8,7 +8,8 @@
#include "SellRuleDlg.h"
#include "TipDlg.h"
#include "SellDlg.h"
#include "CCodeNameDlg.h"
#include "CCBBuyDlg.h"
#ifdef _DEBUG
FloatTrade/FloatTrade.rc
Binary files differ
FloatTrade/FloatTrade.vcxproj
@@ -22,8 +22,9 @@
    <VCProjectVersion>16.0</VCProjectVersion>
    <ProjectGuid>{2A6CD50F-70A5-4BBA-84E1-759FC9DABE21}</ProjectGuid>
    <Keyword>MFCProj</Keyword>
    <RootNamespace>FloatTrade</RootNamespace>
    <RootNamespace>悬浮盯盘</RootNamespace>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
    <ProjectName>悬浮盯盘</ProjectName>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -224,13 +225,18 @@
    <ClInclude Include="..\common\TimeUtil.h" />
    <ClInclude Include="..\common\Win32Util.h" />
    <ClInclude Include="CBuyDlg.h" />
    <ClInclude Include="CCBBuyDlg.h" />
    <ClInclude Include="CCodeNameDlg.h" />
    <ClInclude Include="CColorStatic.h" />
    <ClInclude Include="CImgButton.h" />
    <ClInclude Include="CAutoFocusButton.h" />
    <ClInclude Include="ConfigUtil.h" />
    <ClInclude Include="Constant.h" />
    <ClInclude Include="CSettingDlg.h" />
    <ClInclude Include="DataStruct.h" />
    <ClInclude Include="FloatTrade.h" />
    <ClInclude Include="FloatTradeDlg.h" />
    <ClInclude Include="MyApi.h" />
    <ClInclude Include="MyButton.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="SellDlg.h" />
@@ -249,10 +255,13 @@
    <ClCompile Include="..\common\Win32Util.cpp" />
    <ClCompile Include="base64.cpp" />
    <ClCompile Include="CBuyDlg.cpp" />
    <ClCompile Include="CCBBuyDlg.cpp" />
    <ClCompile Include="CCodeNameDlg.cpp" />
    <ClCompile Include="CColorStatic.cpp" />
    <ClCompile Include="CImgButton.cpp" />
    <ClCompile Include="CAutoFocusButton.cpp" />
    <ClCompile Include="ConfigUtil.cpp" />
    <ClCompile Include="Constant.cpp" />
    <ClCompile Include="CSettingDlg.cpp" />
    <ClCompile Include="FloatTrade.cpp" />
    <ClCompile Include="FloatTradeDlg.cpp" />
@@ -283,11 +292,13 @@
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
    <Import Project="..\packages\tencent.rapidjson.1.1.1\build\tencent.rapidjson.targets" Condition="Exists('..\packages\tencent.rapidjson.1.1.1\build\tencent.rapidjson.targets')" />
    <Import Project="..\packages\libiconv.lib.1.16.0.6\build\native\libiconv.lib.targets" Condition="Exists('..\packages\libiconv.lib.1.16.0.6\build\native\libiconv.lib.targets')" />
  </ImportGroup>
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\tencent.rapidjson.1.1.1\build\tencent.rapidjson.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\tencent.rapidjson.1.1.1\build\tencent.rapidjson.targets'))" />
    <Error Condition="!Exists('..\packages\libiconv.lib.1.16.0.6\build\native\libiconv.lib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libiconv.lib.1.16.0.6\build\native\libiconv.lib.targets'))" />
  </Target>
</Project>
FloatTrade/FloatTrade.vcxproj.filters
@@ -105,6 +105,21 @@
    <ClInclude Include="SellManager.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="MyApi.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="DataStruct.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="CCodeNameDlg.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Constant.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="CCBBuyDlg.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="FloatTrade.cpp">
@@ -179,6 +194,15 @@
    <ClCompile Include="SellManager.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="CCodeNameDlg.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="Constant.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="CCBBuyDlg.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="FloatTrade.rc">
FloatTrade/FloatTradeDlg.cpp
@@ -25,6 +25,9 @@
#include "CSettingDlg.h"
#include "CBuyDlg.h"
#include "SellRuleDlg.h"
#include "MyApi.h"
#include "CCBBuyDlg.h"
#include "Constant.h"
// CFloatTradeDlg 对话框
@@ -139,22 +142,6 @@
    }
}
void CFloatTradeDlg::getMarketSituation(CFloatTradeDlg* context)
{
    try {
        int situation = NetworkApi::get_market_situation();
        if (situation == 2) {
            context->checkMarketSituation.SetCheck(TRUE);
        }
        else {
            context->checkMarketSituation.SetCheck(FALSE);
        }
    }
    catch (...) {
    }
}
void CFloatTradeDlg::getTradeMode(CFloatTradeDlg* context)
{
@@ -198,22 +185,24 @@
    try {
        wstring result = NetworkApi::getCodeDesc(code);
        CString resultC(result.c_str());
        context->setMsg(resultC, MSG_TYPE_INFO, FALSE);
        //context->setMsg(resultC, MSG_TYPE_INFO, FALSE);
        context->labelCodeInfo.SetWindowTextW(resultC);
    }
    catch (wstring st) {
        CString msgc;
        /*CString msgc;
        msgc.Append(CString(code.c_str()));
        msgc.Append(L":");
        msgc.Append(st.c_str());
        context->setMsg(msgc, MSG_TYPE_FAIL);
        context->setMsg(msgc, MSG_TYPE_FAIL);*/
    }
    catch (CString st) {
        CString msgc;
        msgc.Append(CString(code.c_str()));
        msgc.Append(L":");
        msgc.Append(st);
        context->setMsg(msgc, MSG_TYPE_FAIL);
        /*    CString msgc;
            msgc.Append(CString(code.c_str()));
            msgc.Append(L":");
            msgc.Append(st);
            context->setMsg(msgc, MSG_TYPE_FAIL);*/
    }
}
void CFloatTradeDlg::requestCodePosition(string code, CFloatTradeDlg* context, bool showCodeDesc, int delayMs)
@@ -223,80 +212,95 @@
    }
    context->sellManager->init(code);
    try {
        string result = NetworkApi::get_code_position_info(code);
        auto doc = JsonUtil::parseUTF16(result);
        if (doc.IsObject()) {
        CodePosition newCodePosition;
        // 如果是持仓代码就不更新代码信息
        if (context->positionMap.find(code) != context->positionMap.end()) {
            newCodePosition = context->positionMap[code];
            CString resultC;
            resultC.Append(CString(newCodePosition.code.c_str()));
            resultC.Append(L" ");
            resultC.Append(newCodePosition.name);
            context->setMsg(resultC, MSG_TYPE_INFO, FALSE);
            std::thread t1(updateCodePosition, code, context);
            t1.detach();
            if (doc[_T("data")].HasMember(L"code_info"))
            {
                auto data = doc[_T("data")].GetObjectW();
                CString c = data[_T("code_info")].GetArray()[0].GetString();
                wstring name = L"";
                // 获取输入框的内容
                if (context != nullptr) {
                    CString realCode;
                    context->editCode.GetWindowTextW(realCode);
                    if (c != realCode) {
                        return;
        }
        else {
            string result = NetworkApi::get_code_position_info(code);
            auto doc = JsonUtil::parseUTF16(result);
            if (doc.IsObject()) {
                if (doc[_T("data")].HasMember(L"code_info"))
                {
                    auto data = doc[_T("data")].GetObjectW();
                    CString c = data[_T("code_info")].GetArray()[0].GetString();
                    wstring name = L"";
                    // 获取输入框的内容
                    if (context != nullptr) {
                        CString realCode;
                        context->editCode.GetWindowTextW(realCode);
                        if (c != realCode) {
                            return;
                        }
                    }
                }
            }
                newCodePosition.total = doc[L"data"][L"total"].GetInt();
                newCodePosition.available = doc[L"data"][L"available"].GetInt();
                newCodePosition.costPrice = doc[L"data"][L"cost_price"].GetFloat();
                newCodePosition.sell_rules_count = doc[L"data"][L"sell_rules_count"].GetInt();
                list<int> sellVolumes;
                if (doc[L"data"].HasMember(L"sell_orders")) {
                    auto sell_orders_array = doc[L"data"][L"sell_orders"].GetArray();
            int total = doc[L"data"][L"total"].GetInt();
            int available = doc[L"data"][L"available"].GetInt();
            CodePosition* codePosition = context->sellManager->getCodePosition(code);
            codePosition->total = total;
            codePosition->available = available;
            codePosition->sell_rules_count = doc[L"data"][L"sell_rules_count"].GetInt();
            codePosition->costPrice = doc[L"data"][L"cost_price"].GetFloat();
            list<int> sellVolumes;
            if (doc[L"data"].HasMember(L"sell_orders")) {
                auto sell_orders_array = doc[L"data"][L"sell_orders"].GetArray();
                for (int i = 0; i < sell_orders_array.Size(); i++) {
                    sellVolumes.push_back(sell_orders_array[i].GetInt());
                    for (int i = 0; i < sell_orders_array.Size(); i++) {
                        sellVolumes.push_back(sell_orders_array[i].GetInt());
                    }
                }
            }
            codePosition->sell_orders = sellVolumes;
                newCodePosition.sell_orders = sellVolumes;
            // TODO 测试
            //codePosition->sell_orders.clear();
            //codePosition->sell_orders.push_back(900);
            //codePosition->available = 900;
            // 设置卖框显示的内容
            if (context->sellDlgMap.find(code) != context->sellDlgMap.end()) {
                context->sellDlgMap[code]->SetPositionInfo(total, available);
            }
            //设置内容
            context->showCodePositionInfo();
            context->initSellSettingView();
            if (showCodeDesc && doc[_T("data")].HasMember(L"code_info"))
            {
                auto data = doc[_T("data")].GetObjectW();
                CString c = data[_T("code_info")].GetArray()[0].GetString();
                wstring name = L"";
                if (!data[_T("code_info")].GetArray()[1].IsNull()) {
                    name = data[_T("code_info")].GetArray()[1].GetString();
                if (showCodeDesc && doc[_T("data")].HasMember(L"code_info"))
                {
                    auto data = doc[_T("data")].GetObjectW();
                    CString c = data[_T("code_info")].GetArray()[0].GetString();
                    wstring name = L"";
                    if (!data[_T("code_info")].GetArray()[1].IsNull()) {
                        name = data[_T("code_info")].GetArray()[1].GetString();
                    }
                    if (data.HasMember(L"desc")) {
                        wstring desc = data[_T("desc")].GetString();
                        wstring fresult;
                        fresult.append(c).append(L" ").append(name).append(L"  ").append(desc);
                        CString resultC(fresult.c_str());
                        context->setMsg(resultC, MSG_TYPE_INFO, FALSE);
                    }
                }
                if (data.HasMember(L"desc")) {
                    wstring desc = data[_T("desc")].GetString();
                    wstring fresult;
                    fresult.append(c).append(L" ").append(name).append(L"  ").append(desc);
                    CString resultC(fresult.c_str());
                    context->setMsg(resultC, MSG_TYPE_INFO, FALSE);
                }
            }
        }
        CodePosition* codePosition = context->sellManager->getCodePosition(code);
        /*codePosition->total = newCodePosition.total;
        codePosition->available = newCodePosition.available;
        codePosition->sell_rules_count = newCodePosition.sell_rules_count;
        codePosition->costPrice = newCodePosition.costPrice;*/
        // TODO 测试
        //codePosition->sell_orders.clear();
        //codePosition->sell_orders.push_back(900);
        //codePosition->available = 900;
        // 设置卖框显示的内容
        if (context->sellDlgMap.find(code) != context->sellDlgMap.end()) {
            context->sellDlgMap[code]->SetPositionInfo(newCodePosition.total, newCodePosition.available);
        }
        //设置内容
        context->showCodePositionInfo();
        context->initSellSettingView();
    }
    catch (wstring st) {
        context->setMsg(CString(st.c_str()), MSG_TYPE_FAIL);
@@ -317,12 +321,12 @@
    SellSetting* sellSetting = context->sellManager->getSellSetting(code);
    if (sellSetting->lockBuyMoney > 0) {
        context->editBuyMoney.SetWindowTextW(to_wstring(sellSetting->lockBuyMoney).c_str());
    }
    else {
    //if (sellSetting->lockBuyMoney > 0) {
    context->editBuyMoney.SetWindowTextW(to_wstring(ConfigUtil::getBuyMoney()).c_str());
    //}
    /*else {
        context->editBuyMoney.SetWindowTextW(L"");
    }
    }*/
    if (sellSetting->lock) {
        context->checkLockVolume.SetCheck(TRUE);
@@ -334,6 +338,31 @@
    int money = context->sellManager->computeCurrentMoney(code);
    context->editSellMoney.SetWindowTextW(to_wstring(money).c_str());
}
void CFloatTradeDlg::updateCodePosition(string code, CFloatTradeDlg* context)
{
    try {
        string result = NetworkApi::get_code_position_info(code);
        auto doc = JsonUtil::parseUTF16(result);
        if (doc.IsObject()) {
            if (context->positionMap.find(code) != context->positionMap.end()) {
                CodePosition codePosition = context->positionMap[code];
                codePosition.total = doc[L"data"][L"total"].GetInt();
                codePosition.available = doc[L"data"][L"available"].GetInt();
                codePosition.costPrice = doc[L"data"][L"cost_price"].GetFloat();
            }
            CodePosition* codePosition = context->sellManager->getCodePosition(code);
            if (codePosition != nullptr) {
                codePosition->total = doc[L"data"][L"total"].GetInt();
                codePosition->available = doc[L"data"][L"available"].GetInt();
                codePosition->costPrice = doc[L"data"][L"cost_price"].GetFloat();
            }
        }
    }
    catch (...) {
        cout << "出错" << endl;
    }
}
void CFloatTradeDlg::requestSellResult(int order_ref, CFloatTradeDlg* context, int delayMs)
@@ -376,6 +405,9 @@
    catch (wstring st) {
        showFloatMsg(context, st.c_str(), MSG_TYPE_FAIL);
    }
    // 更新持仓
    requestAllPositions(context);
}
void CFloatTradeDlg::regularUpdatePositionInfo(CFloatTradeDlg* context)
@@ -550,21 +582,22 @@
    fillSellMoney(code, codePosition->available);
    checkLockBuyVolume.SetCheck(sellSetting->lockBuy);
    if (sellSetting->lockBuy) {
        if (sellSetting->lockBuyMoney > 0) {
            editBuyMoney.SetWindowTextW(to_wstring(sellSetting->lockBuyMoney).c_str());
        }
    }
    else {
        string nowTime = TimeUtil::getNowTime("%H%M%S");
        // 09:25:00之前都是跌停价卖
        if (stoi(nowTime) < stoi("093000")) {
            editBuyMoney.SetWindowTextW(std::to_wstring((int)(codePosition->total * codePosition->costPrice * 100) / 100).c_str());
        }
        else {
            editBuyMoney.SetWindowTextW(L"");
        }
    }
    //if (sellSetting->lockBuy) {
    //    if (sellSetting->lockBuyMoney > 0) {
    //        editBuyMoney.SetWindowTextW(to_wstring(sellSetting->lockBuyMoney).c_str());
    //    }
    //}
    //else {
    //    string nowTime = TimeUtil::getNowTime("%H%M%S");
    //    // 09:25:00之前都是跌停价卖
    //    if (stoi(nowTime) < stoi("093000")) {
    //        editBuyMoney.SetWindowTextW(std::to_wstring((int)(codePosition->total * codePosition->costPrice * 100) / 100).c_str());
    //    }
    //    else {
    //        editBuyMoney.SetWindowTextW(L"");
    //    }
    //}
}
list<UINT> CFloatTradeDlg::distributeVolume(UINT total, UINT percent)
@@ -627,10 +660,12 @@
    DDX_Control(pDX, IDC_COMBO_SELL_PRICE, comboSellPriceType);
    DDX_Control(pDX, btn_code_trade_info, btnSellRule);
    DDX_Control(pDX, IDC_CHECK_LOCK_SELL_VOLUME, checkLockVolume);
    DDX_Control(pDX, IDC_CHECK_MARKET_SITUATION, checkMarketSituation);
    DDX_Control(pDX, IDC_MFCBUTTON_FLASH_INFO, mfcBtnFlashInfo);
    DDX_Control(pDX, IDC_CHECK_LOCK_BUY_VOLUME, checkLockBuyVolume);
    DDX_Control(pDX, IDC_EDIT_BUY_VOLUME, editBuyMoney);
    DDX_Control(pDX, label_code_info, labelCodeInfo);
    DDX_Control(pDX, btn_buy, btnBuy);
    DDX_Control(pDX, IDC_COMBO_BUY_PRICE, comboBuyPriceType);
}
BEGIN_MESSAGE_MAP(CFloatTradeDlg, CDialogEx)
@@ -682,7 +717,6 @@
    ON_BN_CLICKED(IDC_BUTTON_REMOVE_MUST, &CFloatTradeDlg::OnBnClickedremovefrommust)
    ON_MESSAGE(WM_FLOAT_MSG, &CFloatTradeDlg::OnFloatMsg)
    ON_BN_CLICKED(IDC_CHECK_LOCK_SELL_VOLUME, &CFloatTradeDlg::OnBnClickedCheckLockSellVolume)
    ON_BN_CLICKED(IDC_CHECK_MARKET_SITUATION, &CFloatTradeDlg::OnBnClickedCheckMarketSituation)
    ON_BN_CLICKED(IDC_BUTTON_ADD_WANT, &CFloatTradeDlg::OnBnClickedButtonAddWant)
    ON_BN_CLICKED(IDC_BUTTON_REMOVE_WANT, &CFloatTradeDlg::OnBnClickedButtonRemoveWant)
    ON_BN_CLICKED(IDC_BUTTON_WANT_LIST, &CFloatTradeDlg::OnBnClickedButtonWantList)
@@ -690,6 +724,12 @@
    ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VOLUME, &CFloatTradeDlg::OnDeltaposSpinVolume)
    ON_BN_CLICKED(IDC_CHECK_LOCK_BUY_VOLUME, &CFloatTradeDlg::OnBnClickedCheckLockBuyVolume)
    ON_WM_KEYDOWN()
    ON_BN_CLICKED(btn_code_trade_update_watch_buy1, &CFloatTradeDlg::OnBnClickedcodetradeupdatewatchbuy1)
    ON_BN_CLICKED(IDC_BUTTON_BUY_CB, &CFloatTradeDlg::OnBnClickedButtonBuyCb)
    ON_BN_CLICKED(IDC_BUTTON_ADD_GREEN, &CFloatTradeDlg::OnBnClickedButtonAddGreen)
    ON_BN_CLICKED(IDC_BUTTON_REMOVE_GREEN, &CFloatTradeDlg::OnBnClickedButtonRemoveGreen)
    ON_BN_CLICKED(IDC_BUTTON_GREEN_LIST, &CFloatTradeDlg::OnBnClickedButtonGreenList)
    ON_BN_CLICKED(btn_add_watch_limit_up_for_sell, &CFloatTradeDlg::OnBnClickedaddwatchlimitupforsell)
END_MESSAGE_MAP()
// CFloatTradeDlg 消息处理程序
@@ -705,12 +745,11 @@
    SetLayeredWindowAttributes(RGB(0, 0, 0), opacity, LWA_ALPHA);
    //设置字体
    labelAtrribute.SetFont(&middleFont, FALSE);
    labelCodeInfo.SetFont(&middleFont, FALSE);
    btnCancelBuy.SetFont(&bigFont, FALSE);
    btnSell.SetFont(&bigFont, FALSE);
    //btnBuy.SetFont(&bigFont, FALSE);
    btnBuy.SetFont(&bigFont, FALSE);
    mfcBtnFlashInfo.SetTextColor(RGB(255, 0, 0));
@@ -760,17 +799,9 @@
    std::thread t3(ThsUtil::run_trade_refresh);
    t3.detach();
    //启动分组刷新
    std::thread t4(ThsUtil::run_group_refresh);
    t4.detach();
    // 获取市场行情
    std::thread t5(getMarketSituation, this);
    t5.detach();
    // 设置位置
    POINT p = ConfigUtil::getWindowPos();
    MyPoint p = ConfigUtil::getWindowPos();
    RECT rect;
    Win32Util::getWindowRect(GetSafeHwnd(), &rect);
    Win32Util::moveWin(GetSafeHwnd(), p.x, p.y, (rect.right - rect.left + 1), (rect.bottom - rect.top + 1));
@@ -781,12 +812,48 @@
    comboSellPriceType.AddString(_T("买5价"));
    comboSellPriceType.SetCurSel(0);
    comboBuyPriceType.AddString(_T("价格笼子"));
    comboBuyPriceType.AddString(_T("跌停价"));
    comboBuyPriceType.AddString(_T("涨停价"));
    comboBuyPriceType.AddString(_T("现价"));
    comboBuyPriceType.AddString(_T("买5价"));
    comboBuyPriceType.SetCurSel(0);
    std::thread thread_ru(regularUpdatePositionInfo, this);
    thread_ru.detach();
    std::thread thread_push_msg_receive(runPushMsgReceiver, this);
    thread_push_msg_receive.detach();
    // 获取持仓
    std::thread thread_request_all_position(requestAllPositions, this);
    thread_request_all_position.detach();
    // 加载代码名称
    Constant::loadCodeNames();
    // 按下组合键
    list<HWND> hwndList = Win32Util::searchWindow("同花顺");
    if (hwndList.size() > 0) {
        UINT hwnd = (UINT) * (hwndList.begin());
        Win32Util::focus((HWND)hwnd);
        //SendMessage(hwnd, WM_KEYDOWN, VK_SHIFT);
        //SendMessage(hwnd, WM_KEYDOWN, VK_F12);
        //// 发送 SHIFT 键释放事件
        //PostMessage(hwnd, WM_KEYUP, VK_F12);
        //PostMessage(hwnd, WM_KEYUP, VK_SHIFT);
        keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY, 0); // 按下按键
        keybd_event(VK_F12, 0, KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); // 释放按键
        keybd_event(VK_F12, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); // 释放按键
    }
    editBuyMoney.SetWindowTextW(to_wstring(ConfigUtil::getBuyMoney()).c_str());
    fillMoneys();
}
@@ -813,6 +880,8 @@
    // TODO: 在此添加额外的初始化代码
    //初始化配置文件
    initData();
    return TRUE;
}
@@ -827,7 +896,7 @@
    if (nHotKeyId == HOT_KEY_SELL_ALL) {
        list<HWND> hwnds =    Win32Util::searchWindow("可转债交易");
        list<HWND> hwnds = Win32Util::searchWindow("可转债交易");
        HWND cbHwnd = 0;
        if (hwnds.size() > 0) {
            for (list<HWND>::iterator e = hwnds.begin(); e != hwnds.end(); ++e) {
@@ -842,7 +911,7 @@
            }
        }
        if (cbHwnd>0) {
        if (cbHwnd > 0) {
            string data = "你是不是傻";
            COPYDATASTRUCT cds;
            cds.dwData = 100; // 可以自定义标识数据
@@ -933,16 +1002,13 @@
void CFloatTradeDlg::OnBnClickedbuy()
{
    /*
    CString codew;
    editCode.GetWindowTextW(codew);
    CBuyDlg dlg(codew);
    //dlg.Create(IDD_BUY,this);
    //dlg.ShowWindow(SW_SHOW);
    //return;
    INT_PTR nResponse = dlg.DoModal();
    //dlg.ShowWindow(SW_SHOW);
    */
    buy();
}
@@ -1102,27 +1168,36 @@
void CFloatTradeDlg::OnClickedBtnSell()
{
    if (requestingCode.size() >= 6) {
        showTips(L"持仓请求未结束(150ms以后才能卖)", MSG_TYPE_FAIL, 1000);
        return;
    }
    CString sell_money;
    editSellMoney.GetWindowTextW(sell_money);
    if (!StringUtil::isNumber(StringUtil::cstring2String(sell_money))) {
        showTips(L"卖金额输入错误", MSG_TYPE_FAIL, 1000);
        return;
    }
    int sell_money_int = stoi(StringUtil::cstring2String(sell_money));
    if (sell_money_int <= 0) {
        showTips(L"卖金额不能为0", MSG_TYPE_FAIL, 1000);
        return;
    }
    // 卖
    bool showMsg = true;
    try {
        string code = getCode();
        string code = "";
        try {
            code = getCode();
        }
        catch (...) {
        }
        //if (requestingCode.size() >= 6) {
        //    showTips(L"持仓请求未结束(150ms以后才能卖)", MSG_TYPE_FAIL, 1000);
        //    return;
        //}
        CString sell_money;
        editSellMoney.GetWindowTextW(sell_money);
        if (!StringUtil::isNumber(StringUtil::cstring2String(sell_money))) {
            showTips(L"卖金额输入错误", MSG_TYPE_FAIL, 1000);
            return;
        }
        int sell_money_int = stoi(StringUtil::cstring2String(sell_money));
        if (sell_money_int <= 0) {
            showTips(L"卖金额不能为0", MSG_TYPE_FAIL, 1000);
            return;
        }
        // 卖
        int sell_volume_int = sellMoneyToVolume(code, sell_money_int);
        if (sell_volume_int == 0) {
            sell_volume_int = 100;
@@ -1142,6 +1217,7 @@
        //setMsg(msg, MSG_TYPE_FAIL);
        showTips(msg, MSG_TYPE_FAIL, 1000);
    }
}
@@ -1379,6 +1455,11 @@
        int orderRef = context->sellManager->sell(code, volume, sellPriceType);
        std::thread t1(context->requestSellResult, orderRef, context, 2000);
        t1.detach();
        std::thread t2(context->requestAllPositions, context);
        t2.detach();
        context->showTips(L"卖提交成功", MSG_TYPE_SUCCESS, 1000);
    }
    catch (wstring st) {
@@ -1443,22 +1524,22 @@
            throw wstring(L"请输入买入金额");
        }
        CodePosition* pos = sellManager->getCodePosition(code);
        /*CodePosition* pos = sellManager->getCodePosition(code);
        if (pos == nullptr) {
            throw wstring(L"没有获取到现价");
        }
        }*/
        int buyMoney = stoi(StringUtil::cstring2String(buyMoneyw));
        if (round(pos->costPrice) <= 0) {
        /*if (round(pos->costPrice) <= 0) {
            throw wstring(L"未获取到现价");
        }
        int volume = SellManager::sellMoneyToVolume(buyMoney, pos->costPrice);
        }*/
        /*int volume = SellManager::sellMoneyToVolume(buyMoney, pos->costPrice);
        if (volume <= 0) {
            CString msg = L"买入量不能小于100(单价:";
            msg.Append(to_wstring(pos->costPrice).c_str());
            msg.Append(L")");
            throw wstring(msg);
        }
        NetworkApi::buy(code, volume, "");
        }*/
        NetworkApi::buy(code, buyMoney, comboBuyPriceType.GetCurSel());
        showTips(L"买入提交成功", MSG_TYPE_SUCCESS, 1000);
    }
    catch (wstring st) {
@@ -1475,6 +1556,61 @@
    params.position = position;
    LPARAM lm = (LPARAM)&params;
    ::SendMessage(context->GetSafeHwnd(), WM_FLOAT_MSG, 0, lm);
}
void CFloatTradeDlg::requestAllPositions(CFloatTradeDlg* context)
{
    try {
        string result = NetworkApi::get_all_positions();
        auto doc = JsonUtil::parseUTF16(result);
        if (doc[L"code"].GetInt() == 0) {
            auto data = doc[L"data"].GetArray();
            for (int i = 0; i < data.Size(); i++) {
                auto item = data[i].GetObjectW();
                string code = StringUtil::cstring2String(item[L"code"].GetString());
                context->sellManager->init(code);
                CodePosition codePosition;
                codePosition.total = item[L"total"].GetInt();
                codePosition.available = item[L"available"].GetInt();
                codePosition.code = code;
                codePosition.name = item[L"code_name"].GetString();
                codePosition.costPrice = item[L"cost_price"].GetFloat();
                codePosition.sell_rules_count = 0;
                context->positionMap[codePosition.code] = codePosition;
                CodePosition* positionForSell = context->sellManager->getCodePosition(code);
                if (positionForSell != nullptr) {
                    positionForSell->total = item[L"total"].GetInt();
                    positionForSell->available = item[L"available"].GetInt();
                    positionForSell->code = code;
                    positionForSell->name = item[L"code_name"].GetString();
                    positionForSell->costPrice = item[L"cost_price"].GetFloat();
                    positionForSell->sell_rules_count = 0;
                }
            }
        }
    }
    catch (...) {
    }
}
void CFloatTradeDlg::fillMoneys()
{
    list<int> volumeList = ConfigUtil::getVolumesSetting();
    int ids[] = {
    IDC_BUTTON_SELL_VOLUME_13,IDC_BUTTON_SELL_VOLUME_11,IDC_BUTTON_SELL_VOLUME_10,IDC_BUTTON_SELL_VOLUME_9,IDC_BUTTON_SELL_VOLUME_8,IDC_BUTTON_SELL_VOLUME_7,IDC_BUTTON_SELL_VOLUME_6,IDC_BUTTON_SELL_VOLUME_5, IDC_BUTTON_SELL_VOLUME_4, IDC_BUTTON_SELL_VOLUME_3, IDC_BUTTON_SELL_VOLUME_2, IDC_BUTTON_SELL_VOLUME_1
    };
    if (volumeList.size() == 12) {
        int index = 0;
        for (list<int>::iterator e = volumeList.begin(); e != volumeList.end(); ++e) {
            int volume = *e;
            CButton* edit = (CButton*)GetDlgItem(ids[index]);
            edit->SetWindowTextW(to_wstring(volume).c_str());
            index++;
        }
    }
}
@@ -1547,7 +1683,6 @@
BOOL CFloatTradeDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    //this->labelAtrribute.Set
    //将当前页面显示在最前面并获取焦点
@@ -1573,11 +1708,12 @@
            requestingCode = code;
            //请求网络获取消息
            //std::thread t1(getCodeDesc, code, this);
            //t1.detach();
            std::thread t1(getCodeDesc, code, this);
            t1.detach();
            std::thread t2(requestCodePosition, code, this, TRUE, 0);
            t2.detach();
            // 判断是否有下单窗口
            /*if (!buyWin || !Win32Util::isWindowShow(buyWin)) {
@@ -1625,6 +1761,7 @@
    CSettingDlg dlg;
    INT_PTR nResponse = dlg.DoModal();
    fillMoneys();
}
@@ -1724,24 +1861,6 @@
}
void CFloatTradeDlg::OnBnClickedCheckMarketSituation()
{
    try {
        if (checkMarketSituation.GetCheck()) {
            NetworkApi::set_market_situation(2);
        }
        else {
            NetworkApi::set_market_situation(0);
        }
    }
    catch (wstring msg) {
        checkMarketSituation.SetCheck(!checkMarketSituation.GetCheck());
        AfxMessageBox(msg.c_str());
    }
}
void CFloatTradeDlg::OnBnClickedButtonAddWant()
{
    try {
@@ -1792,32 +1911,8 @@
void CFloatTradeDlg::OnBnClickedButtonGetPositions()
{
    string result = NetworkApi::get_all_positions();
    auto doc = JsonUtil::parseUTF16(result);
    if (doc.IsObject() && doc[L"code"] == 0) {
        auto array = doc[L"data"].GetArray();
        for (int i = 0; i < array.Size(); i++) {
            auto  data = array[i].GetObjectW();
            CString codew = data[L"code"].GetString();
            string code = StringUtil::cstring2String(codew);
            CString codeName = data[L"code_name"].GetString();
            CodePosition position;
            position.total = data[L"total"].GetInt();
            position.available = data[L"available"].GetInt();
            if (sellDlgMap.find(code) == sellDlgMap.end())
            {
                SellDlg* dlg = new SellDlg(code, codeName, position, OnSellCallback, OnSellCloseCallback, this);
                dlg->Create(IDD_DIALOG_SELL, this);
                dlg->ShowWindow(SW_SHOW);
                sellDlgMap[code] = dlg;
            }
            else {
                sellDlgMap[code]->ShowWindow(SW_SHOW);
            }
        }
    }
    cout << result << endl;
    requestAllPositions(this);
    MessageBox(L"拉取成功");
}
@@ -1915,7 +2010,6 @@
        {
            // 保存锁定的金额
            try {
                string code = getInputCode();
                CString buyMoneyw;
                editBuyMoney.GetWindowTextW(buyMoneyw);
                string buyMoney = StringUtil::cstring2String(buyMoneyw);
@@ -1923,11 +2017,7 @@
                    throw wstring(L"请输入正确的金额");
                }
                int buyMoney_int = stoi(buyMoney);
                SellSetting* sellSetting = sellManager->getSellSetting(code);
                sellSetting->lockBuyMoney = buyMoney_int;
                sellSetting->lockBuy = true;
                checkLockBuyVolume.SetCheck(true);
                sellManager->syncSettingToFile(code);
                ConfigUtil::setBuyMoney(buyMoney_int);
            }
            catch (wstring msg) {
                AfxMessageBox(msg.c_str());
@@ -1939,3 +2029,201 @@
    return CDialogEx::PreTranslateMessage(pMsg);
}
void CFloatTradeDlg::OnBnClickedcodetradeupdatewatchbuy1()
{
    // 批量更新填充数据
    try {
        list<SellRule> rules = MyApi::listSellRules();
        if (rules.size() > 0)
        {
            for (list<SellRule>::iterator e = rules.begin(); e != rules.end(); ++e) {
                SellRule rule = *e;
                if (rule.type == 2) {
                    if (rule.buy1_volume > 0) {
                        // 获取买1
                        Buy1Info info = MyApi::getBuy1Info(StringUtil::cstring2String(rule.code));
                        int volume = (info.volume / 100) * 2 / 5;
                        int buy1Volume_int = volume;
                        rapidjson::StringBuffer buf;
                        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
                        writer.StartObject();
                        writer.Key("id");
                        writer.String(StringUtil::cstring2String(rule.id_).c_str());
                        writer.Key("code");
                        writer.String(StringUtil::cstring2String(rule.code).c_str());
                        writer.Key("buy1_volume");
                        writer.Int(buy1Volume_int * 100);
                        writer.Key("buy1_price");
                        writer.String(StringUtil::to_string(info.price).c_str());
                        writer.Key("sell_volume");
                        writer.Int(rule.sell_volume);
                        writer.Key("sell_price_type");
                        writer.Int(rule.sell_price_type);
                        writer.Key("end_time");
                        writer.String(StringUtil::cstring2String(rule.end_time).c_str());
                        writer.EndObject();
                        const char* json_content = buf.GetString();
                        string result = NetworkApi::update_sell_rule(JsonUtil::parseUTF8(json_content));
                        rapidjson::GenericDocument<rapidjson::UTF16<>> doc = JsonUtil::parseUTF16(result);
                        if (doc[L"code"].GetInt() != 0) {
                            throw doc[L"msg"].GetString();
                        }
                    }
                }
            }
            MessageBox(L"更新完成", L"提示");
        }
        else {
            throw CString(L"没有板上盯数据");
        }
    }
    catch (CString st) {
        AfxMessageBox(st);
    }
    catch (wstring st) {
        AfxMessageBox(CString(st.c_str()));
    }
}
void CFloatTradeDlg::OnBnClickedButtonBuyCb()
{
    // 打开可转债买入
    CCBBuyDlg dlg;
    INT_PTR nResponse = dlg.DoModal();
}
void CFloatTradeDlg::OnBnClickedButtonAddGreen()
{
    try {
        string code = getCode();
        NetworkApi::add_green_buy(code);
        CString msg(code.c_str());
        msg.Append(_T("加入绿名单成功"));
        setMsg(msg, MSG_TYPE_SUCCESS);
    }
    catch (wstring st) {
        CString msg(st.c_str());
        setMsg(msg, MSG_TYPE_FAIL);
    }
}
void CFloatTradeDlg::OnBnClickedButtonRemoveGreen()
{
    // 移除绿名单
    try {
        string code = getCode();
        NetworkApi::remove_green_buy(code);
        CString msg(code.c_str());
        msg.Append(_T("移除绿名单成功"));
        setMsg(msg, MSG_TYPE_SUCCESS);
    }
    catch (wstring st) {
        CString msg(st.c_str());
        setMsg(msg, MSG_TYPE_FAIL);
    }
}
void CFloatTradeDlg::OnBnClickedButtonGreenList()
{
    try {
        std::list<wstring> wlist = NetworkApi::list_green_buy();
        MessageBox(formatListResult(wlist), TEXT("绿名单"), MB_TASKMODAL);
    }
    catch (wstring st) {
        CString cs(st.c_str());
        AfxMessageBox(cs);
    }
}
void CFloatTradeDlg::OnBnClickedaddwatchlimitupforsell()
{
    try {
        string code = getCode();
        // 获取板上盯列表
        // 批量更新填充数据
        CodePosition* codePosition = sellManager->getCodePosition(code);
        if (codePosition == nullptr) {
            throw CString(L"当前代码无持仓");
        }
        if (codePosition->available <= 0) {
            throw CString(L"当前代码无剩余持仓");
        }
        list<SellRule> rules = MyApi::listSellRules();
        if (rules.size() > 0)
        {
            for (list<SellRule>::iterator e = rules.begin(); e != rules.end(); ++e) {
                SellRule rule = *e;
                if (rule.excuted) {
                    continue;
                }
                if (rule.type == 2) {
                    if (rule.buy1_volume > 0) {
                        if (code._Equal(StringUtil::cstring2String(rule.code))) {
                            throw CString(L"已存在板上盯");
                            return;
                        }
                    }
                }
            }
        }
        // 获取买1
        Buy1Info info = MyApi::getBuy1Info(code);
        int volume = (info.volume / 100) * 2 / 5;
        int buy1Volume_int = volume;
        rapidjson::StringBuffer buf;
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
        writer.StartObject();
        writer.Key("code");
        writer.String(code.c_str());
        writer.Key("buy1_volume");
        writer.Int(buy1Volume_int * 100);
        writer.Key("buy1_price");
        writer.String(StringUtil::to_string(info.price).c_str());
        writer.Key("sell_volume");
        writer.Int(codePosition->available);
        writer.Key("sell_price_type");
        writer.Int(0);
        writer.Key("end_time");
        writer.String("14:56:56");
        writer.Key("type");
        writer.Int(2);
        writer.EndObject();
        const char* json_content = buf.GetString();
        string result = NetworkApi::add_sell_rule(JsonUtil::parseUTF8(json_content));
        rapidjson::GenericDocument<rapidjson::UTF16<>> doc = JsonUtil::parseUTF16(result);
        if (doc[L"code"].GetInt() != 0) {
            throw doc[L"msg"].GetString();
        }
        MessageBox(L"添加板上盯完成", L"提示");
    }
    catch (CString msg) {
        setMsg(msg, MSG_TYPE_FAIL);
    }
    catch (wstring msg) {
        setMsg(msg.c_str(), MSG_TYPE_FAIL);
    }
}
FloatTrade/FloatTradeDlg.h
@@ -56,6 +56,8 @@
    string requestingCode;
    // 下单窗口
    HWND buyWin;
    // 持仓map
    map<string, CodePosition> positionMap;
    SellManager* sellManager;
@@ -77,9 +79,6 @@
    static void getAutoCancelSellMode(CFloatTradeDlg* context);
    // 获取市场行情
    static void getMarketSituation(CFloatTradeDlg* context);
    //获取交易模式
    static void getTradeMode(CFloatTradeDlg* context);
    //清除消息
@@ -90,6 +89,9 @@
    // 获取代码持仓状态 
    static void requestCodePosition(string code, CFloatTradeDlg* context,bool showCodeDesc, int delayMs=0);
    // 更新持仓
    static void updateCodePosition(string code, CFloatTradeDlg* context);
    // 获取卖结果 
    static void requestSellResult(int order_ref, CFloatTradeDlg* context, int delayMs = 0);
@@ -139,6 +141,11 @@
    void buy();
    static void showFloatMsg(CFloatTradeDlg *context, CString msg,MSG_TYPE msgType,int showMS=2000, int position=TipDlg::POSITION_NORMAL);
    static void requestAllPositions(CFloatTradeDlg *context);
    // 填充预设金额
    void fillMoneys();
// 构造
@@ -221,7 +228,6 @@
    afx_msg void OnBnClickedremovefrommust();
    CButton checkLockVolume;
    afx_msg void OnBnClickedCheckLockSellVolume();
    CButton checkMarketSituation;
    afx_msg void OnBnClickedCheckMarketSituation();
    CMFCButton mfcBtnFlashInfo;
    afx_msg void OnBnClickedButtonAddWant();
@@ -233,4 +239,13 @@
    CEdit editBuyMoney;
    afx_msg void OnBnClickedCheckLockBuyVolume();
    virtual BOOL PreTranslateMessage(MSG* pMsg);
    afx_msg void OnBnClickedcodetradeupdatewatchbuy1();
    afx_msg void OnBnClickedButtonBuyCb();
    afx_msg void OnBnClickedButtonAddGreen();
    afx_msg void OnBnClickedButtonRemoveGreen();
    afx_msg void OnBnClickedButtonGreenList();
    CStatic labelCodeInfo;
    CButton btnBuy;
    CComboBox comboBuyPriceType;
    afx_msg void OnBnClickedaddwatchlimitupforsell();
};
FloatTrade/MyApi.h
New file
@@ -0,0 +1,62 @@
#pragma once
#include <string>
#include "../common/NetworkApi.h"
#include "../common/JsonUtil.h"
#include "DataStruct.h"
class MyApi {
public:
    static list<SellRule> listSellRules() {
        string result = NetworkApi::list_sell_rules();
        auto doc = JsonUtil::parseUTF16(result);
        if (doc.IsObject()) {
            if (doc[L"code"].GetInt() == 0) {
                auto array = doc[L"data"].GetArray();
                list<SellRule> rules;
                for (int i = 0; i < array.Size(); i++) {
                    SellRule rule;
                    rule.code = array[i][L"code"].GetString();
                    rule.id_ = array[i][L"id_"].GetString();
                    rule.buy1_volume = array[i][L"buy1_volume"].GetInt() / 100;
                    rule.buy1_price = array[i][L"buy1_price"].GetString();
                    rule.sell_volume = array[i][L"sell_volume"].GetInt();
                    rule.sell_price_type = array[i][L"sell_price_type"].GetInt();
                    rule.create_time = array[i][L"create_time"].GetString();
                    rule.excuted = array[i][L"excuted"].GetInt();
                    rule.end_time = array[i][L"end_time"].GetString();
                    rule.type = array[i][L"type"].GetInt();
                    rules.push_back(rule);
                }
                return rules;
            }
            else {
                throw CString(doc[L"msg"].GetString());
            }
        }
        else {
            throw CString("网络请求出错");
        }
    }
    static Buy1Info getBuy1Info(string code) {
        string result = NetworkApi::get_buy1_info(code);
        auto doc = JsonUtil::parseUTF16(result);
        if (doc.IsObject()) {
            if (doc[L"code"].GetInt() == 0) {
                    int volume = doc[L"data"][L"volume"].GetInt();
                    double price = doc[L"data"][L"price"].GetDouble();
                    return Buy1Info({volume, price});
            }
            else {
                throw CString(doc[L"msg"].GetString());
            }
        }
        else {
            throw CString("网络请求出错");
        }
    }
};
FloatTrade/SellRuleDlg.cpp
@@ -13,6 +13,7 @@
#include <ctime>
#include <cstring>
#include "../common/TimeUtil.h"
#include "MyApi.h"
// SellRuleDlg 对话框
@@ -198,80 +199,64 @@
void SellRuleDlg::requestListRules(SellRuleDlg* app)
{
    string result = NetworkApi::list_sell_rules();
    auto doc = JsonUtil::parseUTF16(result);
    if (doc.IsObject()) {
        if (doc[L"code"].GetInt() == 0) {
            auto array = doc[L"data"].GetArray();
            list<SellRule> rules;
            for (int i = 0; i < array.Size(); i++) {
                SellRule rule;
                rule.code = array[i][L"code"].GetString();
                rule.id_ = array[i][L"id_"].GetString();
                rule.buy1_volume = array[i][L"buy1_volume"].GetInt() / 100;
                rule.buy1_price = array[i][L"buy1_price"].GetString();
                rule.sell_volume = array[i][L"sell_volume"].GetInt();
                rule.sell_price_type = array[i][L"sell_price_type"].GetInt();
                rule.create_time = array[i][L"create_time"].GetString();
                rule.excuted = array[i][L"excuted"].GetInt();
                rule.end_time = array[i][L"end_time"].GetString();
                rule.type = array[i][L"type"].GetInt();
                rules.push_back(rule);
            }
            app->listRules.SetRedraw(false);
            app->listRules.DeleteAllItems();
            app->ruleList = rules;
            int index = 0;
            list<string> TYPES = get_price_types();
            for (list<SellRule>::iterator ele = app->ruleList.begin(); ele != app->ruleList.end(); ++ele) {
                SellRule rule = *ele;
    try {
        list<SellRule> rules = MyApi::listSellRules();
                app->listRules.InsertItem(index, rule.id_);
        app->listRules.SetRedraw(false);
        app->listRules.DeleteAllItems();
        app->ruleList = rules;
        int index = 0;
        list<string> TYPES = get_price_types();
        for (list<SellRule>::iterator ele = app->ruleList.begin(); ele != app->ruleList.end(); ++ele) {
            SellRule rule = *ele;
                app->listRules.SetItemText(index, 0, rule.code);
                list<string>::iterator its = TYPES.begin();
                std::advance(its, rule.sell_price_type);
                string price_type = *its;
                CString conditionDesc = L"";
                //通过量来卖
                if (rule.type == 2) {
                    if (rule.buy1_volume > 0) {
                        conditionDesc.Append(L"当【买1】低于【");
                        conditionDesc.Append(to_wstring(rule.buy1_volume).c_str());
                        conditionDesc.Append(L"】手,以【");
                        conditionDesc.Append(CString(price_type.c_str()));
                        conditionDesc.Append(L"】卖");
                    }
                    else {
                        conditionDesc.Append(L"当【最新价】低于【");
                        conditionDesc.Append(rule.buy1_price);
                        conditionDesc.Append(L"】,以【");
                        conditionDesc.Append(CString(price_type.c_str()));
                        conditionDesc.Append(L"】卖");
                    }
                }
                else if (rule.type == 1) {
            app->listRules.InsertItem(index, rule.id_);
            app->listRules.SetItemText(index, 0, rule.code);
            list<string>::iterator its = TYPES.begin();
            std::advance(its, rule.sell_price_type);
            string price_type = *its;
            CString conditionDesc = L"";
            //通过量来卖
            if (rule.type == 2) {
                if (rule.buy1_volume > 0) {
                    conditionDesc.Append(L"当【买1】低于【");
                    conditionDesc.Append(to_wstring(rule.buy1_volume).c_str());
                    conditionDesc.Append(L"】手,撤买");
                    conditionDesc.Append(L"】手,以【");
                    conditionDesc.Append(CString(price_type.c_str()));
                    conditionDesc.Append(L"】卖");
                }
                app->listRules.SetItemText(index, 1, conditionDesc);
                app->listRules.SetItemText(index, 2, std::to_wstring(rule.sell_volume).c_str());
                app->listRules.SetItemText(index, 3, rule.end_time);
                app->listRules.SetItemText(index, 4, rule.excuted ? L"已执行" : L"未执行");
                //app->listRules.SetItemText(index, 7, rule.id_);
                //app->listRules.SetItemText(index, 8, rule.create_time);
                if (rule.excuted) {
                    app->listRules.SetItemData(index, COLOR_RED);
                else {
                    conditionDesc.Append(L"当【最新价】低于【");
                    conditionDesc.Append(rule.buy1_price);
                    conditionDesc.Append(L"】,以【");
                    conditionDesc.Append(CString(price_type.c_str()));
                    conditionDesc.Append(L"】卖");
                }
                index++;
            }
            else if (rule.type == 1) {
                conditionDesc.Append(L"当【买1】低于【");
                conditionDesc.Append(to_wstring(rule.buy1_volume).c_str());
                conditionDesc.Append(L"】手,撤买");
            }
            app->listRules.SetItemText(index, 1, conditionDesc);
            app->listRules.SetItemText(index, 2, std::to_wstring(rule.sell_volume).c_str());
            app->listRules.SetItemText(index, 3, rule.end_time);
            app->listRules.SetItemText(index, 4, rule.excuted ? L"已执行" : L"未执行");
            //app->listRules.SetItemText(index, 7, rule.id_);
            //app->listRules.SetItemText(index, 8, rule.create_time);
            if (rule.excuted) {
                app->listRules.SetItemData(index, COLOR_RED);
            }
            index++;
        }
        app->listRules.SetRedraw(true);
    }
    else {
        AfxMessageBox(doc[L"msg"].GetString());
    catch (CString st) {
        AfxMessageBox(st);
    }
    catch (wstring st) {
        AfxMessageBox(CString(st.c_str()));
    }
}
@@ -794,27 +779,19 @@
{
    CString code;
    this->editCode.GetWindowTextW(code);
    string result = NetworkApi::get_buy1_info(StringUtil::cstring2String(code));
    auto doc = JsonUtil::parseUTF16(result);
    if (doc.IsObject()) {
        if (doc[L"code"].GetInt() == 0) {
            if (doc.HasMember(L"data")) {
                int volume = doc[L"data"][L"volume"].GetInt();
                double price = doc[L"data"][L"price"].GetDouble();
                codePriceMap[StringUtil::cstring2String(code)] = StringUtil::toString(price, 2);
                volume = volume / 100 / 3;
                this->editBuy1Volume.SetWindowTextW(to_wstring(volume).c_str());
                showBuy1Money(StringUtil::cstring2String(code));
            }
        }
        else {
            AfxMessageBox(doc[L"msg"].GetString());
        }
    try {
        Buy1Info info = MyApi::getBuy1Info(StringUtil::cstring2String(code));
        codePriceMap[StringUtil::cstring2String(code)] = StringUtil::toString(info.price, 2);
        int volume = (info.volume / 100 ) * 2 / 5;
        this->editBuy1Volume.SetWindowTextW(to_wstring(volume).c_str());
        showBuy1Money(StringUtil::cstring2String(code));
    }
    catch (CString msg) {
        AfxMessageBox(msg);
    }
    catch (wstring msg) {
        AfxMessageBox(CString(msg.c_str()));
    }
}
BOOL SellRuleDlg::PreTranslateMessage(MSG* pMsg)
@@ -828,7 +805,7 @@
            this->editCode.GetWindowTextW(code);
            showBuy1Money(StringUtil::cstring2String(code));
        }
        return TRUE;
    }
FloatTrade/SellRuleDlg.h
@@ -3,28 +3,11 @@
#include <list>
#include <string>
#include "SellManager.h"
#include "DataStruct.h"
using namespace std;
#define COLOR_RED 2
#define COLOR_DEFAULT 0
struct SellRule
{
    CString id_;
    CString code;
    int buy1_volume;
    //买1价格
    CString buy1_price;
    //卖量
    int sell_volume;
    //卖价格类型
    int sell_price_type;
    CString create_time;
    int excuted;
    CString day;
    CString end_time;
    // 0-买 1-买撤 2-卖 3-卖撤
    int type;
};
// SellRuleDlg 对话框
FloatTrade/SellStruct.h
@@ -1,5 +1,6 @@
#pragma once
#include <list>
#include <string>
using namespace std;
enum SELL_SETTING_MODE {
@@ -30,6 +31,8 @@
};
struct CodePosition {
    string code; // 代码
    CString name;// 名称
    int total;//总持仓
    int available;//可用持仓
    int sell_rules_count;//卖出规则数量
FloatTrade/ThsUtil.cpp
@@ -104,45 +104,40 @@
    }
}
void ThsUtil::run_group_refresh()
HWND ThsUtil::get_ths_flash_sell_win()
{
    HWND hwnd = get_ths_second_screen_menu_hwnd();
        while (TRUE) {
            try {
                if (hwnd <= 0 || !Win32Util::isWindowShow(hwnd))
                    // print("未找到同花顺副屏句柄")
                    hwnd = get_ths_second_screen_menu_hwnd();
                if (hwnd <= 0) {
                    Sleep(20);
                    continue;
                }
                if (!ConfigUtil::isGroupRefresh()) {
                    Sleep(20);
                    continue;
                }
                list<POINT> posList = ConfigUtil::getThsAutoClickPositions();
                if (posList.size() < 1) {
                    Sleep(20);
                    continue;
                }
                int space = ConfigUtil::getThsAutoClickTimeSpace();
                if (space <= 0)
                    space = 500;
                for (list<POINT>::iterator el = posList.begin(); el != posList.end(); el++) {
                    POINT p= *el;
                    Win32Util::visualClick(hwnd, MAKELONG(p.x,p.y));
                    Sleep(space);
                }
    auto hwnd = GetDesktopWindow();
    HWND mainPage = HWND();
    //获取桌面子窗口句柄
    hwnd = GetWindow(hwnd, GW_CHILD);
    list<HWND> list;
    while (hwnd != NULL)
    {
        const int bufferSize = 256;
        TCHAR className[bufferSize];
        GetClassName(hwnd, className, bufferSize);
        if (CString(className).Find( L"#32770")==0) {
            if (FindWindowEx(hwnd, NULL, NULL, L"一键卖出[S]") >0) {
                return hwnd;
            }
            catch (...) {
            }
            Sleep(20);
        }
        hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
    }
    return HWND();
}
std::wstring ThsUtil::get_ths_flash_sell_name()
{
    HWND hwnd = get_ths_flash_sell_win();
    if (hwnd <= 0) {
        return L"";
    }
    HWND nameHWND = GetDlgItem(hwnd, 0x0000040C);
    std::wstring name =    Win32Util::getText(nameHWND);
    return name;
}
FloatTrade/ThsUtil.h
@@ -1,5 +1,6 @@
#pragma once
//同花顺工具
#include<string>
class ThsUtil
{
@@ -10,7 +11,11 @@
public:
    //交易刷新
    static void run_trade_refresh();
    //分组刷新
    static void run_group_refresh();
    // 获取同花顺闪电卖出弹框
    static HWND get_ths_flash_sell_win();
    // 获取同花顺闪电卖出代码名称
    static std::wstring get_ths_flash_sell_name();
};
FloatTrade/config.cfg
@@ -1,6 +1,6 @@
window_pos = "[-1249,215]";
window_pos = "[-1147,270]";
trade_quick_key = 1;
sell_rule_show_pos = "-733,208";
sell_rule_show_pos = "-968,225";
ths_auto_click_time_space = 2000;
ths_auto_refresh_time_space = 2000;
ths_auto_click_positions = "[]";
@@ -62,3 +62,8 @@
sell_setting-20240304-603912 = "{\n    \"setting_mode\": 0,\n    \"lock\": true,\n    \"lockMoney\": 5000,\n    \"lockBuy\": true,\n    \"lockBuyMoney\": 8000,\n    \"mode1_rate_index\": 4,\n    \"mode2_first_index\": 0,\n    \"mode2_left_index\": 0\n}";
sell_setting-20240304-603380 = "{\n    \"setting_mode\": 0,\n    \"lock\": true,\n    \"lockMoney\": 5000,\n    \"lockBuy\": true,\n    \"lockBuyMoney\": 1000,\n    \"mode1_rate_index\": 4,\n    \"mode2_first_index\": 0,\n    \"mode2_left_index\": 0\n}";
sell_setting-20240305-603380 = "{\n    \"setting_mode\": 0,\n    \"lock\": true,\n    \"lockMoney\": 40000,\n    \"lockBuy\": true,\n    \"lockBuyMoney\": 0,\n    \"mode1_rate_index\": 4,\n    \"mode2_first_index\": 0,\n    \"mode2_left_index\": 0\n}";
code_name_map-20240823 = "{\n    \"000546\": \"金圆股份\",\n    \"002354\": \"天娱数科\"\n}";
sell_setting-20240906-600207 = "{\n    \"setting_mode\": 0,\n    \"lock\": true,\n    \"lockMoney\": 8000,\n    \"lockBuy\": true,\n    \"lockBuyMoney\": 0,\n    \"mode1_rate_index\": 4,\n    \"mode2_first_index\": 0,\n    \"mode2_left_index\": 0\n}";
sell_setting-20240906-600791 = "{\n    \"setting_mode\": 0,\n    \"lock\": true,\n    \"lockMoney\": 7000,\n    \"lockBuy\": true,\n    \"lockBuyMoney\": 0,\n    \"mode1_rate_index\": 4,\n    \"mode2_first_index\": 0,\n    \"mode2_left_index\": 0\n}";
buy_money = 20000;
volume_settings = "[100000,45000,40000,30000,25000,20000,15000,10000,5000,4000,3000,2000]";
FloatTrade/packages.config
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="libiconv.lib" version="1.16.0.6" targetFramework="native" />
  <package id="tencent.rapidjson" version="1.1.1" targetFramework="native" />
</packages>
FloatTrade/resource.h
@@ -13,6 +13,8 @@
#define IDB_BITMAP_BG                   152
#define IDB_PNG1                        153
#define IDB_PNG_CLOSE                   153
#define IDD_DIALOG_CODE_NAME            156
#define IDD_DIALOG_CB_TRADE             158
#define btn_already_canceled            1000
#define btn_sell                        1001
#define btn_white                       1002
@@ -22,6 +24,7 @@
#define btn_remove_black                1007
#define btn_white_list                  1008
#define btn_black_list                  1009
#define label_code_info                 1010
#define btn_want_list                   1012
#define btn_want_buy                    1013
#define btn_want_buy_remove             1014
@@ -41,10 +44,29 @@
#define btn_code_trade_info             1028
#define edit_per_code_buy_money         1028
#define btn_sure                        1029
#define btn_code_trade_update_watch_buy1 1029
#define btn_sure2                       1030
#define btn_sure_network                1030
#define btn_code_trade_info2            1030
#define btn_add_watch_limit_up_for_sell 1030
#define edit_price                      1031
#define edit_normal_buy_count           1031
#define edit_money                      1032
#define edit_normal_buy_money_time_1    1032
#define edit_normal_buy_count_1         1033
#define edit_normal_buy_money_time_2    1034
#define edit_normal_buy_count_2         1035
#define edit_normal_buy_money_time_3    1036
#define edit_normal_buy_count_3         1037
#define edit_radical_buy_count          1038
#define edit_radical_buy_money_time_1   1039
#define edit_radical_buy_count_1        1040
#define edit_radical_buy_money_time_2   1041
#define edit_radical_buy_count_2        1042
#define edit_radical_buy_money_time_3   1043
#define edit_radical_buy_count_3        1044
#define btn_sure3                       1045
#define btn_radical_buy_block_count_sure 1045
#define IDC_EDIT_CODE                   1048
#define IDC_EDIT_BUY1_VOLUME            1049
#define IDC_EDIT_SELL_VOLUME            1050
@@ -63,6 +85,7 @@
#define IDC_BUTTON_SELL_VOLUME_1        1060
#define IDC_BUTTON_CLEAR2               1060
#define IDC_EDIT_SELL_VOLUME2           1061
#define IDC_COMBO_BUY_PRICE             1061
#define IDC_EDIT_END_TIME2              1062
#define IDC_BUTTON_SELL_VOLUME_3        1063
#define IDC_EDIT_BUY1_PRICE2            1063
@@ -100,17 +123,20 @@
#define IDC_RADIO1                      1080
#define IDC_BUTTON_SELL_VOLUME_10       1080
#define IDC_RADIO2                      1081
#define IDC_BUTTON_ADD_GREEN            1081
#define IDC_COMBO_SELL_FIRST            1082
#define IDC_BUTTON_SELL_VOLUME_12       1082
#define IDC_BUTTON_SELL_VOLUME_11       1082
#define IDC_COMBO2                      1083
#define IDC_BUTTON_ADD_WANT             1083
#define IDC_CHECK_MARKET_SITUATION      1084
#define IDC_BUTTON_REMOVE_GREEN         1084
#define IDC_COMBO_SELL_LEFT             1085
#define IDC_BUTTON_SELL_VOLUME_13       1085
#define IDC_BUTTON_REMOVE_WANT          1086
#define IDC_BUTTON_WANT_LIST            1087
#define IDC_MFCBUTTON1                  1088
#define IDC_BUTTON_GREEN_LIST           1088
#define IDC_MFCBUTTON2                  1089
#define IDC_CHECK_LOCK_BUY_VOLUME       1089
#define IDC_MFCBUTTON_FLASH_INFO        1090
@@ -120,20 +146,71 @@
#define IDC_SPIN1                       1093
#define IDC_SPIN_VOLUME                 1093
#define IDC_BUTTON_GET_POSITION         1094
#define IDC_BUTTON_BUY_CB               1094
#define IDC_STATIC_POSITION             1095
#define IDC_BUTTON_GET_POSITION2        1096
#define IDC_STATIC_RATE                 1096
#define IDC_STATIC_POSITION2            1097
#define IDC_EDIT_NAME_1                 1097
#define IDC_STATIC_POSITION3            1098
#define IDC_STATIC_BUY1_MONEY           1098
#define IDC_STATIC_CODE_1               1098
#define IDC_STATIC_CODE_2               1099
#define IDC_BUTTON_BUY                  1099
#define IDC_EDIT_NAME_2                 1100
#define IDC_BUTTON_BUY2                 1100
#define IDC_BUTTON_SELL                 1100
#define IDC_STATIC_CODE_3               1101
#define IDC_EDIT_VOLUME                 1101
#define IDC_EDIT_NAME_3                 1102
#define combo_normal_buy_money_1        1102
#define IDC_STATIC_CODE_4               1103
#define combo_normal_buy_money_2        1103
#define IDC_EDIT_NAME_4                 1104
#define combo_normal_buy_money_3        1104
#define IDC_STATIC_CODE_5               1105
#define combo_radical_buy_money_1       1105
#define IDC_EDIT_NAME_5                 1106
#define combo_radical_buy_money_2       1106
#define IDC_STATIC_CODE_6               1107
#define combo_radical_buy_money_3       1107
#define IDC_EDIT_NAME_6                 1108
#define IDC_EDIT_VOLUME_1               1108
#define IDC_STATIC_CODE_7               1109
#define IDC_EDIT_VOLUME_2               1109
#define IDC_EDIT_NAME_7                 1110
#define IDC_EDIT_VOLUME_3               1110
#define IDC_STATIC_CODE_8               1111
#define IDC_EDIT_VOLUME_4               1111
#define IDC_EDIT_NAME_8                 1112
#define IDC_STATIC_CODE_9               1113
#define IDC_EDIT_NAME_9                 1114
#define IDC_STATIC_CODE_10              1115
#define IDC_EDIT_NAME_10                1116
#define IDC_EDIT_VOLUME_5               1120
#define IDC_EDIT_VOLUME_6               1121
#define IDC_EDIT_VOLUME_7               1122
#define IDC_EDIT_VOLUME_8               1123
#define IDC_EDIT_VOLUME_9               1124
#define IDC_EDIT_VOLUME_10              1125
#define IDC_EDIT_VOLUME_11              1126
#define IDC_EDIT_VOLUME_12              1127
#define IDC_EDIT_RADICAL_BUY_BLOCK_1    1128
#define IDC_EDIT_RADICAL_BUY_COUNT_1    1129
#define IDC_EDIT_RADICAL_BUY_BLOCK_2    1130
#define IDC_EDIT_RADICAL_BUY_COUNT_2    1131
#define IDC_EDIT_RADICAL_BUY_BLOCK_3    1132
#define IDC_EDIT_RADICAL_BUY_COUNT_3    1133
#define IDC_EDIT_RADICAL_BUY_BLOCK_4    1134
#define IDC_EDIT_RADICAL_BUY_COUNT_4    1135
// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        156
#define _APS_NEXT_RESOURCE_VALUE        160
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1097
#define _APS_NEXT_CONTROL_VALUE         1109
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
Monitor/Monitor.aps
Binary files differ
Monitor/Monitor.rc
Binary files differ
Monitor/MonitorDlg.cpp
@@ -112,6 +112,8 @@
                    desc.Append(L"(");
                    desc.Append(r.name);
                    desc.Append(L")");
                    desc.Append(L" ");
                    desc.Append(CString(StringUtil::to_string(r.rate).c_str()));
                    dlg->listL2Codes.SetItemText(index, 0, desc);
                }
@@ -609,6 +611,21 @@
                        int count = data[L"today_history_k_bar_count"].GetInt();
                        dlg->labelTodayKBarsCount.SetWindowTextW(to_wstring(count).c_str());
                    }
                    if (data.HasMember(L"data_server_open")) {
                        int state = data[L"data_server_open"].GetInt();
                        if (state > 0) {
                            dlg->labelColors[IDC_STATIC_DATA_SERVER_STATE] = RGB(0, 0, 0);
                            dlg->labelDataServerState.SetWindowTextW(L"已开启");
                        }
                        else {
                            dlg->labelColors[IDC_STATIC_DATA_SERVER_STATE] = RGB(255, 0, 0);
                            dlg->labelDataServerState.SetWindowTextW(L"未开启");
                        }
                    }
                    else {
                        dlg->labelDataServerState.SetWindowTextW(L"未知");
                    }
                    
@@ -631,12 +648,6 @@
        if (kill) {
            break;
        }
        Sleep(2000);
    }
@@ -835,6 +846,7 @@
    DDX_Control(pDX, IDC_EDIT_CODE_FOR_SEARCH, editSearchCode);
    DDX_Control(pDX, IDC_BUTTON_SEARCH, btnSearch);
    DDX_Control(pDX, IDC_STATIC_TODAY_K_BARS_COUNT, labelTodayKBarsCount);
    DDX_Control(pDX, IDC_STATIC_DATA_SERVER_STATE, labelDataServerState);
}
Monitor/MonitorDlg.h
@@ -134,4 +134,5 @@
    afx_msg void OnBnClickedButtonSearch();
    CStatic labelTodayKBarsCount;
    afx_msg void OnBnClickedButtonSyncKBars();
    CStatic labelDataServerState;
};
Monitor/resource.h
@@ -25,8 +25,9 @@
#define IDC_STATIC_L2_SUBSCRIPT_CODES_UPDATE_TIME2 1018
#define IDC_STATIC_L2_POSITION_SUBSCRIPT_CODES_UPDATE_TIME2 1018
#define IDC_EDIT_CODE_FOR_SEARCH        1019
#define IDC_STATIC_TODAY_ZYLT_VOLUME_COU 1020
#define IDC_STATIC_TODAY_K_BARS_COUNT   1020
#define IDC_STATIC_L2_LISTEN_ACTIVE2    1021
#define IDC_STATIC_DATA_SERVER_STATE    1021
#define IDC_BUTTON_REFRESH_DELEGATE     1038
#define IDC_BUTTON_REFRESH_DEAL         1039
#define IDC_BUTTON_REFRESH_POSITION     1040
Setup/Setup.vdproj
@@ -395,9 +395,9 @@
        "Product"
        {
        "Name" = "8:Microsoft Visual Studio"
        "ProductName" = "8:TradeDesk"
        "ProductName" = "8:悬浮盯盘"
        "ProductCode" = "8:{BCCBDACE-2D8B-4501-832D-B6805BB2D7F8}"
        "PackageCode" = "8:{B8E62A18-03D3-44EA-BBED-097A56B2C956}"
        "PackageCode" = "8:{26963CD1-B597-4E93-A97E-1671CD3B93E2}"
        "UpgradeCode" = "8:{DEEAA9A2-A9D8-45B3-8DCF-A22B320A8E25}"
        "AspNetVersion" = "8:4.0.30319.0"
        "RestartWWWService" = "11:FALSE"
@@ -408,7 +408,7 @@
        "Manufacturer" = "8:yeshi"
        "ARPHELPTELEPHONE" = "8:"
        "ARPHELPLINK" = "8:"
        "Title" = "8:TradeDesk"
        "Title" = "8:悬浮盯盘"
        "Subject" = "8:"
        "ARPCONTACT" = "8:hxh"
        "Keywords" = "8:"
@@ -519,7 +519,7 @@
        {
            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_D47C2054303D46A59B4FAF86DA37F9FA"
            {
            "Name" = "8:TradeDesk"
            "Name" = "8:悬浮盯盘"
            "Arguments" = "8:"
            "Description" = "8:"
            "ShowCmd" = "3:1"
@@ -932,7 +932,7 @@
        {
            "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_E9DFEEFEA0BB48CEAE99B76404DEB89D"
            {
            "SourcePath" = "8:..\\x64\\Debug\\FloatTrade.exe"
            "SourcePath" = "8:..\\x64\\Debug\\悬浮盯盘.exe"
            "TargetName" = "8:"
            "Tag" = "8:"
            "Folder" = "8:_E4711B38A1AA44659A28C6E3B77D3008"
SetupCBTrade/SetupCBTrade.vdproj
@@ -292,15 +292,15 @@
        {
        "Name" = "8:Microsoft Visual Studio"
        "ProductName" = "8:可转债交易"
        "ProductCode" = "8:{D8A9380B-DEDF-40D5-B571-75A5D2C9C6F1}"
        "PackageCode" = "8:{DC79D12F-7BC8-4269-A033-E1FD2ED83B23}"
        "ProductCode" = "8:{3B5FDBBF-C647-4A85-9825-2D303B86DDD4}"
        "PackageCode" = "8:{1F2A461F-E851-4B33-9711-8FB8509B5434}"
        "UpgradeCode" = "8:{7AED08B9-77D2-4CCC-84A2-A70E4F56F632}"
        "AspNetVersion" = "8:4.0.30319.0"
        "RestartWWWService" = "11:FALSE"
        "RemovePreviousVersions" = "11:FALSE"
        "DetectNewerInstalledVersion" = "11:TRUE"
        "InstallAllUsers" = "11:FALSE"
        "ProductVersion" = "8:1.0.16"
        "ProductVersion" = "8:1.0.17"
        "Manufacturer" = "8:yeshi"
        "ARPHELPTELEPHONE" = "8:"
        "ARPHELPLINK" = "8:"
TradeDesk.sln
@@ -15,8 +15,6 @@
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "TradeRecordSetup", "TradeRecordSetup\TradeRecordSetup.vdproj", "{CD4A5127-4BD2-451A-970E-21A107083079}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AndroidChannelPackage", "AndroidChannelPackage\AndroidChannelPackage.vcxproj", "{20E052B6-33FB-4495-A337-62CB70306CC7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CBTrade", "CBTrade\CBTrade.vcxproj", "{8BFF1459-65B0-4A91-B278-D1EF8FA3E031}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "SetupCBTrade", "SetupCBTrade\SetupCBTrade.vdproj", "{8251B028-53A6-4DC7-97DB-067F036883D5}"
@@ -69,14 +67,6 @@
        {CD4A5127-4BD2-451A-970E-21A107083079}.Debug|x86.ActiveCfg = Debug
        {CD4A5127-4BD2-451A-970E-21A107083079}.Release|x64.ActiveCfg = Release
        {CD4A5127-4BD2-451A-970E-21A107083079}.Release|x86.ActiveCfg = Release
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Debug|x64.ActiveCfg = Debug|x64
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Debug|x64.Build.0 = Debug|x64
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Debug|x86.ActiveCfg = Debug|Win32
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Debug|x86.Build.0 = Debug|Win32
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Release|x64.ActiveCfg = Release|x64
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Release|x64.Build.0 = Release|x64
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Release|x86.ActiveCfg = Release|Win32
        {20E052B6-33FB-4495-A337-62CB70306CC7}.Release|x86.Build.0 = Release|Win32
        {8BFF1459-65B0-4A91-B278-D1EF8FA3E031}.Debug|x64.ActiveCfg = Debug|x64
        {8BFF1459-65B0-4A91-B278-D1EF8FA3E031}.Debug|x64.Build.0 = Debug|x64
        {8BFF1459-65B0-4A91-B278-D1EF8FA3E031}.Debug|x86.ActiveCfg = Debug|Win32
TradeRecord/ConfigUtil.cpp
@@ -93,7 +93,7 @@
}
POINT ConfigUtil::getWindowPos()
MyPoint ConfigUtil::getWindowPos()
{
    // 页码位置
common/NetworkApi.cpp
@@ -13,6 +13,7 @@
#include <sstream>
#include <iostream>
#include <iomanip>
#include <codecvt>
string NetworkApi::_TRADE_SERVER_ADDR = string(MAIN_HOST);
@@ -237,7 +238,7 @@
                wstring desc = root[_T("data")][_T("desc")].GetString();
                wstring fresult;
                fresult.append(c).append(L" ").append(name).append(L"  ").append(desc);
                return fresult;
                return desc;
            }
        }
    }
@@ -383,7 +384,7 @@
    }
}
int NetworkApi::get_market_situation()
int NetworkApi::get_buy_unique_block_mode()
{
    rapidjson::StringBuffer buf;
@@ -394,9 +395,7 @@
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("market_situation");
    writer.Key("operate");
    writer.Int(3);
    writer.String("get_buy_block_mode");
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
@@ -411,10 +410,10 @@
    if (root[_T("code")].GetInt() != 0) {
        throw wstring(root[_T("msg")].GetString());
    }
    return root[L"data"][L"situation"].GetInt();
    return root[L"data"][L"unique_block"].GetInt();
}
void NetworkApi::set_market_situation(int situation)
void NetworkApi::set_buy_unique_block_mode(bool enable)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
@@ -424,11 +423,9 @@
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("market_situation");
    writer.Key("operate");
    writer.Int(1);
    writer.Key("situation");
    writer.Int(situation);
    writer.String("set_buy_unique_block_mode");
    writer.Key("mode");
    writer.Int(enable?1:0);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
@@ -467,6 +464,11 @@
    __request(code, 421);
}
void NetworkApi::add_green_buy(std::string code)
{
    __request(code, 441);
}
// 移除白名单 
void NetworkApi::remove_white(string code) {
    __request(code, 204);
@@ -487,6 +489,11 @@
void NetworkApi::remove_must_buy(std::string code)
{
    __request(code, 422);
}
void NetworkApi::remove_green_buy(std::string code)
{
    __request(code, 442);
}
@@ -512,6 +519,11 @@
    return __request_list(423);
}
std::list<std::wstring> NetworkApi::list_green_buy()
{
    return __request_list(443);
}
// 查询是否可以撤单
bool NetworkApi::get_can_cancel_buy(string code) {
@@ -526,7 +538,7 @@
// 买入
void NetworkApi::buy(std::string code, int volume, string price)
void NetworkApi::buy(std::string code, int money, int priceType)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
@@ -537,10 +549,12 @@
    writer.StartObject();
    writer.Key("code");
    writer.String(code.c_str());
    writer.Key("volume");
    writer.Int(volume);
    writer.Key("price");
    writer.String(price.c_str());
    writer.Key("money");
    writer.Int(money);
    writer.Key("price_type");
    writer.Int(priceType);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
@@ -592,6 +606,70 @@
    return result;
}
string NetworkApi::buy_cb(std::string code, int volume)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("buy_cb_for_commission");
    writer.Key("code");
    writer.String(code.c_str());
    writer.Key("volume");
    writer.Int(volume);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    //JSON解析
    rapidjson::GenericDocument<rapidjson::UTF16<>> root = JsonUtil::parseUTF16(result);
    if (!root.IsObject()) {
        throw wstring(L"JSON解析出错");
    }
    if (root[_T("code")].GetInt() != 0) {
        throw wstring(root[_T("msg")].GetString());
    }
    return result;
}
string NetworkApi::sell_cb(std::string code, int volume)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("sell_cb_for_commission");
    writer.Key("code");
    writer.String(code.c_str());
    writer.Key("volume");
    writer.Int(volume);
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    //JSON解析
    rapidjson::GenericDocument<rapidjson::UTF16<>> root = JsonUtil::parseUTF16(result);
    if (!root.IsObject()) {
        throw wstring(L"JSON解析出错");
    }
    if (root[_T("code")].GetInt() != 0) {
        throw wstring(root[_T("msg")].GetString());
    }
    return result;
}
string NetworkApi::get_code_position_info(std::string code)
{
    rapidjson::StringBuffer buf;
@@ -610,7 +688,7 @@
    string result = base_trade_request(std::string(json_content));
    //string result = "{\"code\": 0, \"data\": {\"code\": \"603200\", \"total\": 1200, \"available\": 1200, \"sell_orders\": [], \"sell_rules_count\": 0, \"code_info\": [\"603200\", \"\\u4e0a\\u6d77\\u6d17\\u9738\"], \"desc\": \"\"}}";
    //string result = "{\"code\": 0, \"data\": {\"code\": \"000011\", \"total\": 1200, \"available\": 1200, \"sell_orders\": [], \"sell_rules_count\": 0, \"code_info\": [\"000011\", \"\\u4e0a\\u6d77\\u6d17\\u9738\"], \"desc\": \"\",\"cost_price\":12.00}}";
         
@@ -711,7 +789,11 @@
            auto arr = doc[L"data"][L"list"].GetArray()[i].GetArray();
            CString code = arr[0].GetString();
            CString codeName= arr[1].IsNull()?L"δ֪":arr[1].GetString() ;
            CodeInfo ci = CodeInfo({ code ,codeName });
            float rate = 0.0f;
            if (arr.Size() > 2) {
                rate = arr[2].GetFloat();
            }
            CodeInfo ci = CodeInfo({ code ,codeName, rate });
            fresults.push_back(ci);
        }
        updateTime = doc[L"data"][L"update_time"].GetString();
@@ -1030,6 +1112,7 @@
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_trade_request(std::string(json_content));
    //string result = StringUtil::cstring2String(L"{\"code\":0,\"data\":[{\"code\":\"002729\",\"code_name\":\"好利科技\"}, {\"code\":\"300564\",\"code_name\":\"筑博设计\"}]}");
    return result;
}
@@ -1051,7 +1134,7 @@
    return result;
}
void NetworkApi::set_per_code_buy_money(int money)
void NetworkApi::set_buy_money_and_count(int normalCount, string normalMoneyJson, int radicalCount, string radicalMoneyJson)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
@@ -1061,14 +1144,22 @@
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("set_per_code_buy_money");
    writer.Key("money");
    writer.Int(money);
    writer.String("set_buy_money_count_setting");
    writer.Key("normal");
    writer.StartArray();
    writer.Int(normalCount);
    writer.String(normalMoneyJson.c_str());
    writer.EndArray();
    writer.Key("radical");
    writer.StartArray();
    writer.Int(radicalCount);
    writer.String(radicalMoneyJson.c_str());
    writer.EndArray();
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_request(std::string(json_content));
    auto root =    JsonUtil::parseUTF16(result);
    auto root = JsonUtil::parseUTF16(result);
    if (root.IsObject()) {
        if (root[L"code"] != 0) {
            throw wstring(root[L"msg"].GetString());
@@ -1077,6 +1168,74 @@
    else {
        throw wstring(L"网络请求错误");
    }
}
string NetworkApi::get_buy_money_and_count()
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("get_buy_money_count_setting");
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_request(std::string(json_content));
    return result;
}
void NetworkApi::set_radical_buy_block_count(string data)
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("set_radical_buy_block_count_setting");
    writer.Key("data");
    writer.String(data.c_str());
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_request(json_content);
    auto root = JsonUtil::parseUTF16(result);
    if (root.IsObject()) {
        if (root[L"code"] != 0) {
            throw wstring(root[L"msg"].GetString());
        }
    }
    else {
        throw wstring(L"网络请求错误");
    }
}
string NetworkApi::get_radical_buy_block_count()
{
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    writer.StartObject();
    writer.Key("type");
    writer.String("common");
    writer.Key("data");
    writer.StartObject();
    writer.Key("ctype");
    writer.String("get_radical_buy_block_count_setting");
    writer.EndObject();
    writer.EndObject();
    const char* json_content = buf.GetString();
    string result = base_request(std::string(json_content));
    return result;
}
int NetworkApi::get_per_code_buy_money()
common/NetworkApi.h
@@ -15,6 +15,7 @@
{
    CString code;
    CString name;
    float rate;// 涨幅
};
struct SubscriptCodesResult {
@@ -69,11 +70,11 @@
    // 设置自动撤卖模式
    static void set_auto_cancel_sell_mode(int mode);
    // 获取市场行情
    static int get_market_situation();
    // 获取是否买板块独苗
    static int get_buy_unique_block_mode();
    // 设置市场行情
    static void set_market_situation(int situation);
    // 设置是否买板块独苗
    static void set_buy_unique_block_mode(bool enable);
   
    // 加白名单
@@ -91,6 +92,9 @@
    // 加必买
    static void add_must_buy(std::string code);
    // 加绿
    static void add_green_buy(std::string code);
    // 移除白名单
    static void remove_white(std::string code);
@@ -105,6 +109,9 @@
    // 移除必买
    static void remove_must_buy(std::string code);
    // 移绿
    static void remove_green_buy(std::string code);
    // 白名单列表
    static std::list<std::wstring> list_white();
@@ -121,6 +128,9 @@
    // 必买列表
    static std::list<std::wstring> list_must_buy();
    // 绿单
    static std::list<std::wstring> list_green_buy();
    // 获取委托列表
    static string list_delegate_records(CString updateTime,bool canCancel=FALSE);
@@ -136,10 +146,16 @@
    static void cancel_buy(CString code);
    // 买入
    static void buy(std::string code, int volume, string price);
    static void buy(std::string code, int volume, int priceType);
    // 卖出
    static string sell(std::string code, int volume, int price_type, bool forceSell = FALSE);
    // 买入可转债
    static string buy_cb(std::string code, int volume);
    // 卖出可转债
    static string sell_cb(std::string code, int volume);
    // 获取持仓数据
    static string get_code_position_info(std::string code);
@@ -206,7 +222,19 @@
    static string get_buy1_info(string code);
    // 设置每个代码可买的金额
    static void set_per_code_buy_money(int money);
    static void set_buy_money_and_count(int mormalCount, string normalMoneyJson,int radicalCount, string radicalMoneyJson);
    // 获取买入设置
    static string get_buy_money_and_count();
    // 扫入板块的代码数量设置
    static void set_radical_buy_block_count(string data);
    static string get_radical_buy_block_count();
    // 获取单票买入金额
    static int get_per_code_buy_money();
common/StringUtil.h
@@ -9,6 +9,11 @@
#include <vector>
using namespace std;
const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
class StringUtil {
public:
@@ -40,6 +45,12 @@
        WideCharToMultiByte(0, 0, getbuf, -1, chRtn, iLen, NULL, NULL);  //将TCHAR 类型的数据转换为 CHAR 类型。
        std::string str(chRtn);
        return str;
    }
    static  std::string cstring2StringV2(CString getbuf) {
        std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
        std::string utf8String = converter.to_bytes(getbuf);
        return utf8String;
    }
    static string to_string(double val) {
@@ -84,4 +95,39 @@
        }
        return result;
    }
    static std::string base64_encode(const std::string& input) {
        std::string encoded;
        int val = 0, valb = -6;
        for (unsigned char c : input) {
            val = (val << 8) + c;
            valb += 8;
            while (valb >= 0) {
                encoded.push_back(base64_chars[(val >> valb) & 0x3F]);
                valb -= 6;
            }
        }
        if (valb > -6) encoded.push_back(base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
        while (encoded.size() % 4) encoded.push_back('=');
        return encoded;
    }
    static std::string base64_decode(const std::string& input) {
        std::string decoded;
        std::vector<int> T(256, -1);
        for (int i = 0; i < 64; i++) T[base64_chars[i]] = i;
        int val = 0, valb = -8;
        for (unsigned char c : input) {
            if (T[c] == -1) break;
            val = (val << 6) + T[c];
            valb += 6;
            if (valb >= 0) {
                decoded.push_back(char((val >> valb) & 0xFF));
                valb -= 8;
            }
        }
        return decoded;
    }
};
common_nopch/NetworkApi.cpp
@@ -121,7 +121,7 @@
{
    rapidjson::Document document;
    document.Parse(data.c_str());
    string requestIdStr = string(document["type"].GetString()).append(get_rquest_id());
    string requestIdStr = document["type"].IsInt()? to_string(document["type"].GetInt()) : string(document["type"].GetString()).append(get_rquest_id());
    rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
    // 添加 request_id 字段
common_nopch/TimeUtil.h
@@ -25,5 +25,12 @@
        return std::string(buffer);
    }
    static long timeStr2Seconds(string st) {
         int h = stoi(st.substr(0, 2));
        int m = stoi(st.substr(3, 2));
        int s = stoi(st.substr(6, 2));
        return h * 3600 + m * 60 + s;
    }
};
packages/libiconv.lib.1.16.0.6/.signature.p7s
Binary files differ
packages/libiconv.lib.1.16.0.6/build/configurations.autopkg
New file
@@ -0,0 +1,23 @@
configurations {
    Toolset {
        key : "PlatformToolset";
        choices : { v142, v142_mt };
    };
    Platform {
        key : "Platform";
        choices : { Win32, x64 };
        Win32.aliases : { x86, win32, ia32, 386 };
        x64.aliases : { x64, amd64, em64t, intel64, x86-64, x86_64 };
    };
    Configuration {
        key : "Configuration";
        choices : { Release, Debug };
    };
    Linkage {
        choices : { dynamic, static };
    };
    Other {
        key : "OTHER_STUFF";
        choices : { RuntimeLibraryNull };
    };
};
packages/libiconv.lib.1.16.0.6/build/native/default-propertiesui.xml
New file
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework">
  <Rule Name="ProjectSettings_globals" PageTemplate="tool" DisplayName="Project Master Settings" SwitchPrefix="/" Order="1">
    <Rule.Categories>
      <Category Name="cpp" DisplayName="C/C++ Settings" />
    </Rule.Categories>
    <Rule.DataSource>
      <DataSource Persistence="ProjectFile" ItemType="" />
    </Rule.DataSource>
    <EnumProperty Name="RuntimeLibrary" DisplayName="Runtime Library" Description="Specify runtime library for linking." Category="cpp" >
      <EnumValue Name="MultiThreaded"  DisplayName="Multi-threaded" Description="Causes your application to use the multithread, static version of the run-time library.">
      </EnumValue>
      <EnumValue Name="MultiThreadedDebug" DisplayName="Multi-threaded Debug" Description="Defines _DEBUG and _MT. This option also causes the compiler to place the library name LIBCMTD.lib into the .obj file so that the linker will use LIBCMTD.lib to resolve external symbols.">
      </EnumValue>
      <EnumValue Name="MultiThreadedDLL" DisplayName="Multi-threaded DLL" Description="Causes your application to use the multithread- and DLL-specific version of the run-time library. Defines _MT and _DLL and causes the compiler to place the library name MSVCRT.lib into the .obj file.">
      </EnumValue>
      <EnumValue Name="MultiThreadedDebugDLL" DisplayName="Multi-threaded Debug DLL" Description="Defines _DEBUG, _MT, and _DLL and causes your application to use the debug multithread- and DLL-specific version of the run-time library. It also causes the compiler to place the library name MSVCRTD.lib into the .obj file.">
      </EnumValue>
    </EnumProperty>
  </Rule>
</ProjectSchemaDefinitions>
packages/libiconv.lib.1.16.0.6/build/native/include/iconv.h
New file
@@ -0,0 +1,250 @@
/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
   This file is part of the GNU LIBICONV Library.
   The GNU LIBICONV Library is free software; you can redistribute it
   and/or modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.
   The GNU LIBICONV Library is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.
   You should have received a copy of the GNU Library General Public
   License along with the GNU LIBICONV Library; see the file COPYING.LIB.
   If not, see <https://www.gnu.org/licenses/>.  */
/* When installed, this file is called "iconv.h". */
#ifndef _LIBICONV_H
#define _LIBICONV_H
#define _LIBICONV_VERSION 0x0110    /* version number: (major<<8) + minor */
#if BUILDING_LIBICONV
#define LIBICONV_DLL_EXPORTED __declspec(dllexport)
#elif USING_STATIC_LIBICONV
#define LIBICONV_DLL_EXPORTED
#else
#define LIBICONV_DLL_EXPORTED __declspec(dllimport)
#endif
extern LIBICONV_DLL_EXPORTED int _libiconv_version; /* Likewise */
/* We would like to #include any system header file which could define
   iconv_t, 1. in order to eliminate the risk that the user gets compilation
   errors because some other system header file includes /usr/include/iconv.h
   which defines iconv_t or declares iconv after this file, 2. when compiling
   for LIBICONV_PLUG, we need the proper iconv_t type in order to produce
   binary compatible code.
   But gcc's #include_next is not portable. Thus, once libiconv's iconv.h
   has been installed in /usr/local/include, there is no way any more to
   include the original /usr/include/iconv.h. We simply have to get away
   without it.
   Ad 1. The risk that a system header file does
   #include "iconv.h"  or  #include_next "iconv.h"
   is small. They all do #include <iconv.h>.
   Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It
   has to be a scalar type because (iconv_t)(-1) is a possible return value
   from iconv_open().) */
/* Define iconv_t ourselves. */
#undef iconv_t
#define iconv_t libiconv_t
typedef void* iconv_t;
/* Get size_t declaration.
   Get wchar_t declaration if it exists. */
#include <stddef.h>
/* Get errno declaration and values. */
#include <errno.h>
/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS,
   have EILSEQ in a different header.  On these systems, define EILSEQ
   ourselves. */
#ifndef EILSEQ
#define EILSEQ EILSEQ
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Allocates descriptor for code conversion from encoding ‘fromcode’ to
   encoding ‘tocode’. */
#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif
extern LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode);
/* Converts, using conversion descriptor ‘cd’, at most ‘*inbytesleft’ bytes
   starting at ‘*inbuf’, writing at most ‘*outbytesleft’ bytes starting at
   ‘*outbuf’.
   Decrements ‘*inbytesleft’ and increments ‘*inbuf’ by the same amount.
   Decrements ‘*outbytesleft’ and increments ‘*outbuf’ by the same amount. */
#ifndef LIBICONV_PLUG
#define iconv libiconv
#endif
extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
/* Frees resources allocated for conversion descriptor ‘cd’. */
#ifndef LIBICONV_PLUG
#define iconv_close libiconv_close
#endif
extern LIBICONV_DLL_EXPORTED int iconv_close (iconv_t cd);
#ifdef __cplusplus
}
#endif
#ifndef LIBICONV_PLUG
/* Nonstandard extensions. */
#if USE_MBSTATE_T
#if BROKEN_WCHAR_H
/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
   <wchar.h>.
   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
   included before <wchar.h>.  */
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#endif
#include <wchar.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* A type that holds all memory needed by a conversion descriptor.
   A pointer to such an object can be used as an iconv_t. */
typedef struct {
  void* dummy1[28];
#if USE_MBSTATE_T
  mbstate_t dummy2;
#endif
} iconv_allocation_t;
/* Allocates descriptor for code conversion from encoding ‘fromcode’ to
   encoding ‘tocode’ into preallocated memory. Returns an error indicator
   (0 or -1 with errno set). */
#define iconv_open_into libiconv_open_into
extern LIBICONV_DLL_EXPORTED int iconv_open_into (const char* tocode, const char* fromcode,
                            iconv_allocation_t* resultp);
/* Control of attributes. */
#define iconvctl libiconvctl
extern LIBICONV_DLL_EXPORTED int iconvctl (iconv_t cd, int request, void* argument);
/* Hook performed after every successful conversion of a Unicode character. */
typedef void (*iconv_unicode_char_hook) (unsigned int uc, void* data);
/* Hook performed after every successful conversion of a wide character. */
typedef void (*iconv_wide_char_hook) (wchar_t wc, void* data);
/* Set of hooks. */
struct iconv_hooks {
  iconv_unicode_char_hook uc_hook;
  iconv_wide_char_hook wc_hook;
  void* data;
};
/* Fallback function.  Invoked when a small number of bytes could not be
   converted to a Unicode character.  This function should process all
   bytes from inbuf and may produce replacement Unicode characters by calling
   the write_replacement callback repeatedly.  */
typedef void (*iconv_unicode_mb_to_uc_fallback)
             (const char* inbuf, size_t inbufsize,
              void (*write_replacement) (const unsigned int *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
/* Fallback function.  Invoked when a Unicode character could not be converted
   to the target encoding.  This function should process the character and
   may produce replacement bytes (in the target encoding) by calling the
   write_replacement callback repeatedly.  */
typedef void (*iconv_unicode_uc_to_mb_fallback)
             (unsigned int code,
              void (*write_replacement) (const char *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
#if HAVE_WCHAR_T
/* Fallback function.  Invoked when a number of bytes could not be converted to
   a wide character.  This function should process all bytes from inbuf and may
   produce replacement wide characters by calling the write_replacement
   callback repeatedly.  */
typedef void (*iconv_wchar_mb_to_wc_fallback)
             (const char* inbuf, size_t inbufsize,
              void (*write_replacement) (const wchar_t *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
/* Fallback function.  Invoked when a wide character could not be converted to
   the target encoding.  This function should process the character and may
   produce replacement bytes (in the target encoding) by calling the
   write_replacement callback repeatedly.  */
typedef void (*iconv_wchar_wc_to_mb_fallback)
             (wchar_t code,
              void (*write_replacement) (const char *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
#else
/* If the wchar_t type does not exist, these two fallback functions are never
   invoked.  Their argument list therefore does not matter.  */
typedef void (*iconv_wchar_mb_to_wc_fallback) ();
typedef void (*iconv_wchar_wc_to_mb_fallback) ();
#endif
/* Set of fallbacks. */
struct iconv_fallbacks {
  iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback;
  iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback;
  iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback;
  iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback;
  void* data;
};
/* Requests for iconvctl. */
#define ICONV_TRIVIALP            0  /* int *argument */
#define ICONV_GET_TRANSLITERATE   1  /* int *argument */
#define ICONV_SET_TRANSLITERATE   2  /* const int *argument */
#define ICONV_GET_DISCARD_ILSEQ   3  /* int *argument */
#define ICONV_SET_DISCARD_ILSEQ   4  /* const int *argument */
#define ICONV_SET_HOOKS           5  /* const struct iconv_hooks *argument */
#define ICONV_SET_FALLBACKS       6  /* const struct iconv_fallbacks *argument */
/* Listing of locale independent encodings. */
#define iconvlist libiconvlist
extern LIBICONV_DLL_EXPORTED void iconvlist (int (*do_one) (unsigned int namescount,
                                      const char * const * names,
                                      void* data),
                       void* data);
/* Canonicalize an encoding name.
   The result is either a canonical encoding name, or name itself. */
extern LIBICONV_DLL_EXPORTED const char * iconv_canonicalize (const char * name);
/* Support for relocatable packages.  */
/* Sets the original and the current installation prefix of the package.
   Relocation simply replaces a pathname starting with the original prefix
   by the corresponding pathname with the current prefix instead.  Both
   prefixes should be directory names without trailing slash (i.e. use ""
   instead of "/").  */
extern LIBICONV_DLL_EXPORTED void libiconv_set_relocation_prefix (const char *orig_prefix,
                                            const char *curr_prefix);
#ifdef __cplusplus
}
#endif
#endif
#endif /* _LIBICONV_H */
packages/libiconv.lib.1.16.0.6/build/native/libiconv.lib-propertiesui-8226f8b4-4a12-413f-938e-c8190803e882.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework">
  <Rule Name="ReferencedPackages77f82d09-db91-46d9-9d0c-ac90d789741d" PageTemplate="tool" DisplayName="Referenced Packages" SwitchPrefix="/" Order="1">
    <Rule.Categories>
      <Category Name="libiconv.lib" DisplayName="libiconv.lib" />
    </Rule.Categories>
    <Rule.DataSource>
      <DataSource Persistence="ProjectFile" ItemType="" />
    </Rule.DataSource>
    <EnumProperty Name="Linkage-libiconv.lib" DisplayName="Linkage" Description="Which version of the .lib file to link to this library" Category="libiconv.lib">
      <EnumValue Name="" DisplayName="Dynamic Library (DLL)" />
      <EnumValue Name="static" DisplayName="Static" />
    </EnumProperty>
  </Rule>
</ProjectSchemaDefinitions>
packages/libiconv.lib.1.16.0.6/build/native/libiconv.lib.targets
New file
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="libiconv_lib_init">
  <PropertyGroup Label="UserMacros">
    <ItemDefinitionGroupRegex>
      <![CDATA[<ItemDefinitionGroup Condition=".*']]>$(Configuration)\|$(Platform)<![CDATA['">(?:.*\n)*?.*</ItemDefinitionGroup>]]>
    </ItemDefinitionGroupRegex>
    <RuntimeLibraryRegex>
      <![CDATA[<RuntimeLibrary>(.*)</RuntimeLibrary>]]>
    </RuntimeLibraryRegex>
    <ItemDefinitionGroup Condition="$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText($(MSBuildProjectFullPath))), $(ItemDefinitionGroupRegex)).Success) == True">$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText($(MSBuildProjectFullPath))), $(ItemDefinitionGroupRegex)).Result('$0'))</ItemDefinitionGroup>
    <ItemDefinitionGroup Condition="$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText($(MSBuildProjectFullPath))), $(ItemDefinitionGroupRegex)).Success) == False"></ItemDefinitionGroup>
    <RuntimeLibrary Condition="$([System.Text.RegularExpressions.Regex]::Match($(ItemDefinitionGroup), $(RuntimeLibraryRegex)).Success) == True">$([System.Text.RegularExpressions.Regex]::Match($(ItemDefinitionGroup), $(RuntimeLibraryRegex)).Result('$1'))</RuntimeLibrary>
    <RuntimeLibrary Condition="$([System.Text.RegularExpressions.Regex]::Match($(ItemDefinitionGroup), $(RuntimeLibraryRegex)).Success) == False And $(Configuration.ToLower().IndexOf('debug')) == -1">MultiThreadedDLL</RuntimeLibrary>
    <RuntimeLibrary Condition="$([System.Text.RegularExpressions.Regex]::Match($(ItemDefinitionGroup), $(RuntimeLibraryRegex)).Success) == False And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">MultiThreadedDebugDLL</RuntimeLibrary>
  </PropertyGroup>
  <PropertyGroup Label="Debug and static and RuntimeLibraryNull" Condition="( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 ) And '$(Linkage-libiconv_lib.ToLower())' == 'static' And ('$(RuntimeLibrary)' == '')">
    <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  </PropertyGroup>
  <PropertyGroup Label="Release and static and RuntimeLibraryNull" Condition="( $(Configuration.ToLower().IndexOf('debug')) == -1 ) And '$(Linkage-libiconv_lib.ToLower())' == 'static' And ('$(RuntimeLibrary)' == '')">
    <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
  </PropertyGroup>
  <PropertyGroup Label="Default initializers for properties">
    <Linkage-libiconv_lib Condition="'$(Linkage-libiconv_lib)' == ''">dynamic</Linkage-libiconv_lib>
    <CallingConvention-libiconv_lib Condition="'$(CallingConvention-libiconv_lib)' == ''">cdecl</CallingConvention-libiconv_lib>
  </PropertyGroup>
  <ItemGroup>
    <PropertyPageSchema Include="$(MSBuildThisFileDirectory)\default-propertiesui.xml" />
  </ItemGroup>
  <ItemGroup>
    <PropertyPageSchema Include="$(MSBuildThisFileDirectory)\libiconv.lib-propertiesui-8226f8b4-4a12-413f-938e-c8190803e882.xml" />
  </ItemGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>USING_STATIC_LIBICONV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)../..//build/native/include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <ResourceCompile>
      <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)../..//build/native/include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="static" Condition="'$(Linkage-libiconv_lib.ToLower())' == 'static'">
    <ClCompile>
      <RuntimeLibrary>$(RuntimeLibrary)</RuntimeLibrary>
    </ClCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="Win32 and v142 and Debug" Condition="'$(Platform.ToLower())' == 'win32' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == '' Or '$(RuntimeLibrary)' == 'MultiThreadedDebugDLL' Or '$(RuntimeLibrary)' == 'MultiThreadedDLL') ) And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/Win32\v142\Debug\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="Win32 and v142_mt and Debug" Condition="'$(Platform.ToLower())' == 'win32' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == 'MultiThreaded' Or '$(RuntimeLibrary)' == 'MultiThreadedDebug') ) And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/Win32\v142_mt\Debug\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="Win32 and v142 and Release" Condition="'$(Platform.ToLower())' == 'win32' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == '' Or '$(RuntimeLibrary)' == 'MultiThreadedDebugDLL' Or '$(RuntimeLibrary)' == 'MultiThreadedDLL') ) And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/Win32\v142\Release\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="Win32 and v142_mt and Release" Condition="'$(Platform.ToLower())' == 'win32' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == 'MultiThreaded' Or '$(RuntimeLibrary)' == 'MultiThreadedDebug') ) And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/Win32\v142_mt\Release\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="x64 and v142 and Debug" Condition="'$(Platform.ToLower())' == 'x64' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == '' Or '$(RuntimeLibrary)' == 'MultiThreadedDebugDLL' Or '$(RuntimeLibrary)' == 'MultiThreadedDLL') ) And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/x64\v142\Debug\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="x64 and v142_mt and Debug" Condition="'$(Platform.ToLower())' == 'x64' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == 'MultiThreaded' Or '$(RuntimeLibrary)' == 'MultiThreadedDebug') ) And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/x64\v142_mt\Debug\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="x64 and v142 and Release" Condition="'$(Platform.ToLower())' == 'x64' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == '' Or '$(RuntimeLibrary)' == 'MultiThreadedDebugDLL' Or '$(RuntimeLibrary)' == 'MultiThreadedDLL') ) And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/x64\v142\Release\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Label="x64 and v142_mt and Release" Condition="'$(Platform.ToLower())' == 'x64' And ( '$(PlatformToolset)' == 'v142' And ('$(RuntimeLibrary)' == 'MultiThreaded' Or '$(RuntimeLibrary)' == 'MultiThreadedDebug') ) And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )">
    <Link>
      <AdditionalDependencies>$(MSBuildThisFileDirectory)../..//build/native/lib/x64\v142_mt\Release\libiconv.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <UsingTask TaskName="libiconv_lib_Contains" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory">
    <ParameterGroup>
      <Text Output="false" ParameterType="System.String" />
      <Library Output="false" Required="true" ParameterType="System.String" />
      <Value Output="false" Required="true" ParameterType="System.String" />
      <Result Output="true" ParameterType="System.String" />
    </ParameterGroup>
    <Task>
      <Code>Result = ((Text ?? "").Split(';').Contains(Library) ) ? Value : String.Empty;</Code>
    </Task>
  </UsingTask>
  <Target Name="libiconv_lib_init">
    <libiconv_lib_Contains Text="Linkage-dynamic" Library="libiconv_lib" Value="dynamic" Condition="'$(Linkage-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="Linkage-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="Linkage-static" Library="libiconv_lib" Value="static" Condition="'$(Linkage-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="Linkage-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="Linkage-ltcg" Library="libiconv_lib" Value="ltcg" Condition="'$(Linkage-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="Linkage-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="Linkage-sxs" Library="libiconv_lib" Value="sxs" Condition="'$(Linkage-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="Linkage-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="CallingConvention-cdecl" Library="libiconv_lib" Value="cdecl" Condition="'$(CallingConvention-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="CallingConvention-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="CallingConvention-stdcall" Library="libiconv_lib" Value="stdcall" Condition="'$(CallingConvention-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="CallingConvention-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="CallingConvention-fastcall" Library="libiconv_lib" Value="fastcall" Condition="'$(CallingConvention-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="CallingConvention-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="CallingConvention-thiscall" Library="libiconv_lib" Value="thiscall" Condition="'$(CallingConvention-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="CallingConvention-libiconv_lib" />
    </libiconv_lib_Contains>
    <libiconv_lib_Contains Text="CallingConvention-clrcall" Library="libiconv_lib" Value="clrcall" Condition="'$(CallingConvention-libiconv_lib)'==''">
      <Output TaskParameter="Result" PropertyName="CallingConvention-libiconv_lib" />
    </libiconv_lib_Contains>
  </Target>
</Project>
packages/libiconv.lib.1.16.0.6/build/publisher-info.txt
New file
@@ -0,0 +1,2 @@
Package Created: 2019/11/1 9:05:02
CoApp tools version: 1.23.521.0
packages/libiconv.lib.1.16.0.6/libiconv.lib.1.16.0.6.nupkg
Binary files differ