DelegateQueue/DataStruct.h
New file @@ -0,0 +1,38 @@ #pragma once #include <wx/wx.h> #include <list> enum MsgTypeEnum { MSG_TYPE_ERROR, MSG_TYPE_WARNING, MSG_TYPE_INFO }; struct TradeQueue { wxString num; int type; }; // 委托信息 struct DelegateInfo { int index; wxString id; wxString code; wxString codeName; wxString buy1_money; int big_num_count; wxString big_num_money; int not_deal_big_num_count_pre;// 没成交前大单 int not_deal_total_big_count_after;// 没成交后大单 wxString not_deal_big_num_money_pre;// 没成交前大单 wxString not_deal_big_num_money_after;// 没成交后大单 int left_count; // 总共剩余笔数 wxString left_money;// 总共剩余金额 float volume_rate;// 量比 bool pay_attention;// 是否需要注意 float trade_progress_percent;//成交进度比例 float limit_up_price;//涨停价 bool is_near_big_order; // 是否靠近大单 wxString block;// 板块 std::list<TradeQueue> tradeQueueList; }; DelegateQueue/DelegateQueue.vcxproj
New file @@ -0,0 +1,195 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Debug|x64"> <Configuration>Debug</Configuration> <Platform>x64</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Release|x64"> <Configuration>Release</Configuration> <Platform>x64</Platform> </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> <VCProjectVersion>16.0</VCProjectVersion> <Keyword>Win32Proj</Keyword> <ProjectGuid>{e145394e-ff3e-4c4a-b76e-19c4e70153af}</ProjectGuid> <RootNamespace>DelegateQueue</RootNamespace> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <PlatformToolset>v142</PlatformToolset> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v142</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <PlatformToolset>v142</PlatformToolset> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v142</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> <ImportGroup Label="Shared"> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <LinkIncremental>true</LinkIncremental> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <LinkIncremental>false</LinkIncremental> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <LinkIncremental>true</LinkIncremental> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <LinkIncremental>false</LinkIncremental> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> <WarningLevel>Level3</WarningLevel> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> </ClCompile> <Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> <WarningLevel>Level3</WarningLevel> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> </ClCompile> <Link> <SubSystem>Console</SubSystem> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> <WarningLevel>Level3</WarningLevel> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> </ClCompile> <Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> <WarningLevel>Level3</WarningLevel> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <SDLCheck>false</SDLCheck> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> <AdditionalIncludeDirectories>..\lib_config\include;..\wxWidgets-3.2.4\include;..\wxWidgets-3.2.4\include\msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>..\lib_config\x64;..\wxWidgets-3.2.4\lib\vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>libconfig++.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> <PostBuildEvent> <Command> </Command> </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> <ClInclude Include="..\common_nopch\ConfigUtil.h" /> <ClInclude Include="..\common_nopch\md5.h" /> <ClInclude Include="..\common_nopch\NetworkApi.h" /> <ClInclude Include="..\common_nopch\SocketManager.h" /> <ClInclude Include="..\common_nopch\StringUtil.h" /> <ClInclude Include="..\common_nopch\TimeUtil.h" /> <ClInclude Include="..\common_nopch\WidgetsRenderUtil.h" /> <ClInclude Include="..\common_nopch\Win32Util.h" /> <ClInclude Include="common.h" /> <ClInclude Include="DataStruct.h" /> <ClInclude Include="MainFrame.h" /> <ClInclude Include="MyConfigUtil.h" /> <ClInclude Include="MyNetworkApi.h" /> <ClInclude Include="TradeQueueFrame.h" /> <ClInclude Include="TradeQueueListControl.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="..\common_nopch\ConfigUtil.cpp" /> <ClCompile Include="..\common_nopch\md5.cpp" /> <ClCompile Include="..\common_nopch\NetworkApi.cpp" /> <ClCompile Include="..\common_nopch\SocketManager.cpp" /> <ClCompile Include="..\common_nopch\WidgetsRenderUtil.cpp" /> <ClCompile Include="..\common_nopch\Win32Util.cpp" /> <ClCompile Include="main.cpp" /> <ClCompile Include="MainFrame.cpp" /> <ClCompile Include="MyConfigUtil.cpp" /> <ClCompile Include="MyNetworkApi.cpp" /> <ClCompile Include="TradeQueueFrame.cpp" /> <ClCompile Include="TradeQueueListControl.cpp" /> </ItemGroup> <ItemGroup> <None Include="packages.config" /> </ItemGroup> <ItemGroup> <Image Include="icon.ico" /> </ItemGroup> <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')" /> </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'))" /> </Target> </Project> DelegateQueue/DelegateQueue.vcxproj.filters
New file @@ -0,0 +1,116 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="源文件"> <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> <Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions> </Filter> <Filter Include="头文件"> <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions> </Filter> <Filter Include="资源文件"> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> </Filter> <Filter Include="头文件\common"> <UniqueIdentifier>{a6568c59-da2b-4b75-8302-fd45329ee5cd}</UniqueIdentifier> </Filter> <Filter Include="源文件\common"> <UniqueIdentifier>{7a6df50a-4396-4439-8d30-77008b5ed0ed}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> <ClInclude Include="MainFrame.h"> <Filter>头文件</Filter> </ClInclude> <ClInclude Include="TradeQueueFrame.h"> <Filter>头文件</Filter> </ClInclude> <ClInclude Include="DataStruct.h"> <Filter>头文件</Filter> </ClInclude> <ClInclude Include="TradeQueueListControl.h"> <Filter>头文件</Filter> </ClInclude> <ClInclude Include="MyConfigUtil.h"> <Filter>头文件</Filter> </ClInclude> <ClInclude Include="MyNetworkApi.h"> <Filter>头文件</Filter> </ClInclude> <ClInclude Include="..\common_nopch\ConfigUtil.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\md5.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\NetworkApi.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\SocketManager.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\StringUtil.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\WidgetsRenderUtil.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\Win32Util.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="..\common_nopch\TimeUtil.h"> <Filter>头文件\common</Filter> </ClInclude> <ClInclude Include="common.h"> <Filter>头文件</Filter> </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="main.cpp"> <Filter>源文件</Filter> </ClCompile> <ClCompile Include="MainFrame.cpp"> <Filter>源文件</Filter> </ClCompile> <ClCompile Include="TradeQueueFrame.cpp"> <Filter>源文件</Filter> </ClCompile> <ClCompile Include="TradeQueueListControl.cpp"> <Filter>源文件</Filter> </ClCompile> <ClCompile Include="MyConfigUtil.cpp"> <Filter>源文件</Filter> </ClCompile> <ClCompile Include="MyNetworkApi.cpp"> <Filter>源文件</Filter> </ClCompile> <ClCompile Include="..\common_nopch\ConfigUtil.cpp"> <Filter>源文件\common</Filter> </ClCompile> <ClCompile Include="..\common_nopch\md5.cpp"> <Filter>源文件\common</Filter> </ClCompile> <ClCompile Include="..\common_nopch\NetworkApi.cpp"> <Filter>源文件\common</Filter> </ClCompile> <ClCompile Include="..\common_nopch\SocketManager.cpp"> <Filter>源文件\common</Filter> </ClCompile> <ClCompile Include="..\common_nopch\WidgetsRenderUtil.cpp"> <Filter>源文件\common</Filter> </ClCompile> <ClCompile Include="..\common_nopch\Win32Util.cpp"> <Filter>源文件\common</Filter> </ClCompile> </ItemGroup> <ItemGroup> <None Include="packages.config" /> </ItemGroup> <ItemGroup> <Image Include="icon.ico"> <Filter>资源文件</Filter> </Image> </ItemGroup> </Project> DelegateQueue/DelegateQueue.vcxproj.user
New file @@ -0,0 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <LocalDebuggerEnvironment>PATH=D:\workspace\GP\trade_desk_cplus\TradeDesk\lib_config\x64 $(LocalDebuggerEnvironment)</LocalDebuggerEnvironment> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> </PropertyGroup> </Project> DelegateQueue/MainFrame.cpp
New file @@ -0,0 +1,675 @@ #include "MainFrame.h" #include <list> #include "../common_nopch/WidgetsRenderUtil.h" #include "../common_nopch/JsonUtil.h" #include "MyNetworkApi.h" #include <thread> #include "../common_nopch/Win32Util.h" #include "../common_nopch/TimeUtil.h" #include "MyConfigUtil.h" #include <wx/graphics.h> #define ROW_WIDTH_DELEGATE_INFO (FRAME_WIDTH - 30)*DPI/100 #define TEXT_LINE_HEIGHT 20*DPI/100 #define ROW_HEIGHT (20*3 + 22 + 32 )*DPI/100 #define DEFAULT_FONT_SIZE 10 using namespace std; std::map<wxString, DelegateInfo> MainFrame::delegateMap; enum BtnClickType { CLICK_TYPE_UNKNOWN, CLICK_TYPE_CANCEL_BUY, CLICK_TYPE_VIEW_DETAIL, CLICK_TYPE_QUEUE, }; // 委托信息数据 class DelegateInfoRenderer : public wxDataViewCustomRenderer { private: DelegateInfo delegateInfo; wxString delegateInfoStr; list<ColorIndexInfo> delegateColors; map<wxString, wxRect> viewBtnRectMap; map<wxString, wxRect> cancelBtnRectMap; map<wxString, wxRect> queueRectMap; map<wxString, wxRect> gridPostionMap; public: /*static void addDelegateInfo(DelegateInfo info) { delegateMap[info.id] = info; }*/ private: wxString floatToString(float value) { std::ostringstream ss; ss << std::fixed << std::setprecision(2) << std::round(value * 100) / 100; return ss.str(); } void loadContent() { delegateColors.clear(); delegateInfoStr.Clear(); delegateInfoStr.Append("ʣ"); ColorIndexInfo colorInfo0; colorInfo0.start_index = delegateInfoStr.Length(); delegateInfoStr.Append(to_string(delegateInfo.left_count)); colorInfo0.end_index = delegateInfoStr.Length() - 1; if (delegateInfo.left_count <= 10) { colorInfo0.color = *wxRED; delegateColors.push_back(colorInfo0); } delegateInfoStr.Append("笔 "); ColorIndexInfo colorInfo1; colorInfo1.start_index = delegateInfoStr.Length(); delegateInfoStr.Append(delegateInfo.left_money); colorInfo1.end_index = delegateInfoStr.Length() - 1; if (parseMoneyAsW(delegateInfo.left_money) <= 1500) { colorInfo1.color = *wxRED; delegateColors.push_back(colorInfo1); } delegateInfoStr.Append("/").Append("封单").Append(delegateInfo.buy1_money); delegateInfoStr.Append(" 【比例: ").Append(floatToString(delegateInfo.trade_progress_percent)).Append("%").Append("】,"); delegateInfoStr.Append("已成大单").Append(to_string(delegateInfo.big_num_count)).Append("笔").Append(delegateInfo.big_num_money).Append(" "); delegateInfoStr.Append("待成前大单").Append(to_string(delegateInfo.not_deal_big_num_count_pre)).Append("笔").Append(delegateInfo.not_deal_big_num_money_pre).Append(","); delegateInfoStr.Append("待成后大单"); ColorIndexInfo colorInfo; colorInfo.start_index = delegateInfoStr.Length(); delegateInfoStr.Append(to_string(delegateInfo.not_deal_total_big_count_after)); colorInfo.end_index = delegateInfoStr.Length() - 1; if (delegateInfo.not_deal_total_big_count_after <= 3) { colorInfo.color = *wxRED; delegateColors.push_back(colorInfo); } delegateInfoStr.Append("笔").Append(delegateInfo.not_deal_big_num_money_after).Append(","); delegateInfoStr.Append("涨停价:").Append(floatToString(delegateInfo.limit_up_price)).Append("元").Append(","); delegateInfoStr.Append(delegateInfo.block); } float parseMoneyAsW(wxString st) { wxString money= st; if (st.Find("万")>=0) { money = st.Mid(0, st.Find("万")); double d; money.ToDouble(&d); return d; } else if (st.Find("亿") >= 0) { money = st.Mid(0, st.Find("亿")); double d; money.ToDouble(&d); return d*10000; } else { double d; money.ToDouble(&d); return d; } } void drawOperateLine(wxDC* dc, int startx, int starty, int line_width) { //绘制红点 /* wxFont font(dc->GetFont().GetPixelSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT), wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);*/ // 绘制名字 wxString codeName = ""; codeName.Append(delegateInfo.code).Append("(").Append(delegateInfo.codeName).Append(")"); WidgetsRenderUtil::drawText(dc, codeName, wxPoint(startx, starty + 3),line_width, TEXT_LINE_HEIGHT); if (delegateInfo.pay_attention) { wxSize textSize = dc->GetTextExtent(codeName); WidgetsRenderUtil::drawText(dc, "****", wxPoint(startx + textSize.GetWidth() + 5*DPI/100, starty + 5*DPI/100), line_width, TEXT_LINE_HEIGHT, std::list<ColorIndexInfo>(), *wxRED); } // 绘制按钮 dc->SetPen(wxColour(225, 225, 225)); dc->SetBrush(wxColour(225, 225, 225)); int btnWidth = 50*DPI/100; int btnHeight = 25*DPI/100; int padding = 10*DPI/100; viewBtnRectMap[delegateInfo.id] = wxRect({ startx + line_width - btnWidth, starty, btnWidth, btnHeight }); WidgetsRenderUtil::drawBtn(dc, "查看", viewBtnRectMap[delegateInfo.id], *wxWHITE, wxColour(0, 150, 136)); // 相邻的撤单错位显示 cancelBtnRectMap[delegateInfo.id] = wxRect({ startx + line_width - viewBtnRectMap[delegateInfo.id].GetWidth() - btnWidth - padding - (delegateInfo.index%2==0?0: btnWidth + 5*DPI/100), starty, btnWidth, btnHeight }); cout << "撤单位置渲染:"<< delegateInfo.index << " - "<< cancelBtnRectMap[delegateInfo.id].x << ":" << cancelBtnRectMap[delegateInfo.id].y <<endl; WidgetsRenderUtil::drawBtn(dc, "撤单", cancelBtnRectMap[delegateInfo.id], *wxWHITE, wxColour(255, 87, 34)); } void drawDelegateQueue(wxDC* dc, wxPoint start, int line_width) { wxGraphicsContext* gc = wxGraphicsContext::CreateFromUnknownDC(*dc); //wxFont font = dc->GetFont(); //font.SetNumericWeight(wxFONTWEIGHT_BOLD); //gc->SetFont(font,*wxRED); wxSize queueSize(43*DPI/100, 22*DPI/100); // 绘制背景颜色 wxRect queueRect = wxRect(start, wxSize(line_width, queueSize.y)); gc->SetPen(*wxBLACK); gc->SetBrush(*wxBLACK); gc->DrawRectangle(queueRect.x, queueRect.y, queueRect.GetWidth(), queueRect.GetHeight()); queueRectMap[delegateInfo.id] = queueRect; int padding = 5*DPI/100; int countPerLine = (line_width - padding) / (queueSize.x + padding); int index = 0; for (list<TradeQueue>::iterator e = delegateInfo.tradeQueueList.begin(); e != delegateInfo.tradeQueueList.end(); e++) { wxRect rect = wxRect(start.x + padding + (queueSize.x + padding) * index, start.y, queueSize.x, queueSize.y); wxColour color; switch ((*e).type) { case 0: color = *wxRED; break; case 1: color = *wxWHITE; break; case 2: color = wxColor(209, 135, 252); break; default: color = *wxRED; break; } gc->SetFont(dc->GetFont(), color); WidgetsRenderUtil::drawBtnByGC(gc, (*e).num, rect, color, *wxBLACK); index++; if (index >= countPerLine) { break; } } /*font = dc->GetFont(); font.SetNumericWeight(wxFONTWEIGHT_NORMAL); dc->SetFont(font);*/ delete gc; } BtnClickType getClickType(int x_, int y_) { cout << "点击位置:" << x_ << "-" << y_ << endl; wxRect gridPostion = gridPostionMap[delegateInfo.id]; wxRect queueRect = queueRectMap[delegateInfo.id]; wxRect cancelBtnRect = cancelBtnRectMap[delegateInfo.id]; wxRect viewBtnRect = viewBtnRectMap[delegateInfo.id]; cout << "单元位置:" << gridPostion.x << "-" << gridPostion.y << endl; int x = gridPostion.x + x_; int y = gridPostion.y + y_; cout << "队列Y:" << queueRect.y << endl; cout << "撤单位置:" << cancelBtnRect.GetLeft() << " " << cancelBtnRect.GetTop() << " " << cancelBtnRect.GetRight() << " " << cancelBtnRect.GetBottom() << endl; if (x >= viewBtnRect.x && x <= viewBtnRect.x + viewBtnRect.GetWidth() && y > viewBtnRect.y && y <= viewBtnRect.y + viewBtnRect.GetHeight()) { return CLICK_TYPE_VIEW_DETAIL; } 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 >= queueRect.x && x <= queueRect.x + queueRect.GetWidth() && y > queueRect.y && y <= queueRect.y + queueRect.GetHeight()) { return CLICK_TYPE_QUEUE; } return CLICK_TYPE_UNKNOWN; } public: DelegateInfoRenderer(const wxString& varianttype = "string") : wxDataViewCustomRenderer(varianttype, wxDATAVIEW_CELL_ACTIVATABLE) { } virtual bool Render(wxRect cell, wxDC* dc, int state) { cout <<"内存地址:"<< this << endl; dc->Clear(); dc->SetUserScale(1,1); gridPostionMap[delegateInfo.id] = wxRect(cell.GetPosition(), cell.GetSize()); //// 设置绘制按钮的位置和大小 //dc->SetTextForeground(wxColour(64, 64, 64)); //// 绘制按钮的外框 //dc->SetPen(wxColour(255, 255, 255)); //dc->SetBrush(wxColour(255, 255, 255)); loadContent(); int start_y = cell.GetPosition().y + 3*DPI/100; int start_x = cell.GetPosition().x; // 绘制操作区域 drawOperateLine(dc, start_x, start_y, cell.GetSize().GetWidth()); // 绘制简介区 int infoWidth = cell.GetSize().GetWidth(); int infoHeight = WidgetsRenderUtil::drawText(dc, delegateInfoStr, wxPoint(start_x, start_y + 25*DPI/100), infoWidth, TEXT_LINE_HEIGHT, delegateColors); // 绘制队列,给文字信息留3排左右的位置 drawDelegateQueue(dc, wxPoint(start_x, TEXT_LINE_HEIGHT * 3 + start_y + 30 * DPI / 100), infoWidth); dc->SetTextForeground(wxColour(255, 0, 0)); wxRect queueRect(cell.GetPosition().x, cell.GetPosition().y + 50 * DPI / 100, infoWidth, infoHeight + 50 * DPI / 100); return false; } void cancelOrder(string code) { string results = MyNetworkApi::cancel_order(code); auto doc = JsonUtil::parseUTF16(results); if (doc.IsObject()) { if (doc[L"code"].GetInt() == 0) { showMsg(wxString(delegateInfo.codeName).Append(":撤单提交成功").ToStdString(), MSG_TYPE_INFO); MainFrame* mainFrame = getWindowFrame(); if (mainFrame) { mainFrame->requestDelegatedInfoList(); } } else { showMsg(wxString(doc[L"msg"].GetString()).ToStdString(), MSG_TYPE_WARNING); } } else { showMsg("网络请求失败", MSG_TYPE_ERROR); } } MainFrame* getWindowFrame() { wxWindow* window = this->GetOwner()->GetOwner()->GetParent(); while (true) { MainFrame* root = dynamic_cast<MainFrame*>(window); if (root) { return root; } else { window = window->GetParent(); } } } void showMsg(string msg,MsgTypeEnum type) { MainFrame* mainFrame = getWindowFrame(); if (mainFrame) { mainFrame->showMsg(msg, type); } } // 点击事件处理方法 bool ActivateCell(const wxRect& WXUNUSED(cell), wxDataViewModel* WXUNUSED(model), const wxDataViewItem& WXUNUSED(item), unsigned int WXUNUSED(col), const wxMouseEvent* mouseEvent) override { // 处理点击事件 if (mouseEvent->LeftDown()) { BtnClickType clickType = getClickType(mouseEvent->GetX(), mouseEvent->GetY()); switch (clickType) { case CLICK_TYPE_CANCEL_BUY: cancelOrder(delegateInfo.code.ToStdString()); break; case CLICK_TYPE_VIEW_DETAIL: try { Win32Util::addToTHS(delegateInfo.code.ToStdString()); } catch (string msg) { wxMessageBox(msg.c_str()); } break; default: break; } } if (mouseEvent->LeftDClick()) { BtnClickType clickType = getClickType(mouseEvent->GetX(), mouseEvent->GetY()); if (clickType == CLICK_TYPE_QUEUE) { WindowPosSize r = MyConfigUtil::getTradeQueueWindowPos(); if (r.x == -1 && r.y == -1 && r.width == -1 && r.height == -1) { // 默认的尺寸与位置 HWND framePos = GetOwner()->GetOwner()->GetParent()->GetHandle(); RECT rect; Win32Util::getWindowRect(framePos, &rect); TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(rect.left, rect.top), wxSize(350,400)); tradeQueueFrame->Show(true); } else { TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(r.x,r.y), wxSize(r.width, r.height)); tradeQueueFrame->Show(true); } // 默认查看 try { thread t(Win32Util::addToTHS, delegateInfo.code.ToStdString()); t.detach(); } catch (...) { } } } return false; // 返回 true 表示已经处理了点击事件 } virtual wxSize GetSize() const { // 返回按钮的大小 return wxSize(ROW_WIDTH_DELEGATE_INFO, ROW_HEIGHT); } virtual bool SetValue(const wxVariant& value) { wxString id = value; delegateInfo = MainFrame::delegateMap[id]; return true; } virtual bool GetValue(wxVariant& value) const { return true; } }; MainFrame::MainFrame(const wxString& title, wxPoint position, wxSize size) :wxFrame(NULL, wxID_ANY, title, position, size) { // 初始化 killed = false; Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnClose, this); wxIcon icon; icon.LoadFile("icon.ico", wxBITMAP_TYPE_ICO); // 替换 "app_icon.ico" 为你的应用程序图标文件路径 SetIcon(icon); SetTransparent(225); SetWindowStyle(GetWindowStyle() | wxSTAY_ON_TOP); wxPanel* panel = new wxPanel(this, wxID_ANY); // 创建 wxDataViewListCtrl 控件 m_listCtrl = new wxDataViewListCtrl(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_SINGLE| wxDV_NO_HEADER); m_listCtrl->SetBackgroundColour(wxColor(242, 242, 242)); // 绑定没行的选中事件 m_listCtrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MainFrame::OnSelectionChanged, this); // 添加列 auto bc = new DelegateInfoRenderer(); wxDataViewColumn *delegateColumn = new wxDataViewColumn("委托信息", bc, 0, ROW_WIDTH_DELEGATE_INFO, wxALIGN_LEFT); m_listCtrl->AppendColumn(delegateColumn); m_listCtrl->SetRowHeight(ROW_HEIGHT); // 设置布局 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); // 提示信息 msgCtrl = new wxStaticText(panel,wxID_ANY,""); wxButton *openTradeQueueBtn =new wxButton(panel, wxID_ANY,"查看全部"); wxBoxSizer *topSizer=new wxBoxSizer(wxHORIZONTAL); topSizer->Add(msgCtrl, 1, wxEXPAND); topSizer->Add(openTradeQueueBtn, 0); sizer->Add(topSizer, 0, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 5); sizer->Add(m_listCtrl, 1, wxEXPAND | wxALL, 5); panel->SetSizerAndFit(sizer); openTradeQueueBtn->Bind(wxEVT_BUTTON, &MainFrame::OnButtonOpenTradeQueueClick,this); std::thread t1(startRequestDelegatedInfoListTask, this); t1.detach(); } void MainFrame::showMsg(string msg, MsgTypeEnum type) { // 显示15s msgExpireTime = TimeUtil::getNowTimeStamp() + 1000 * 15; switch (type) { case MSG_TYPE_ERROR: msgCtrl->SetForegroundColour(*wxGREEN); break; case MSG_TYPE_WARNING: msgCtrl->SetForegroundColour(*wxGREEN); break; case MSG_TYPE_INFO: msgCtrl->SetForegroundColour(*wxBLACK); break; default: break; } msgCtrl->SetLabelText(msg); // 启动线程结束显示 thread t(clearMsg, this); t.detach(); } void MainFrame::clearMsg( MainFrame* context) { Sleep(15* 1000); if (TimeUtil::getNowTimeStamp() > context->msgExpireTime) { context->msgCtrl->SetLabelText(""); } } void MainFrame::OnClose(wxCloseEvent& event) { killed = true; MyConfigUtil::setMainWindowPos(GetPosition(), GetSize()); event.Skip(); exit(0); } void MainFrame::refresh() { m_listCtrl->DeleteAllItems(); for (list<DelegateInfo>::iterator e = delegateList.begin(); e != delegateList.end(); ++e) { DelegateInfo info = *e; delegateMap[info.id] = info; wxVector<wxVariant> data; data.push_back(info.id); m_listCtrl->AppendItem(data); } } list<DelegateInfo> MainFrame::parseDelegates(string result) { list<DelegateInfo> fresults; auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject() && doc[L"code"].GetInt() == 0) { auto root = doc[L"data"].GetObject(); auto delegates = root[L"delegates"].GetArray(); auto money = root[L"account_available_money"].GetString(); for (int i = 0; i < delegates.Size(); i++) { auto doc = delegates[i].GetObject(); auto array = doc[L"code_info"].GetArray(); DelegateInfo delegateInfo; delegateInfo.index = i; delegateInfo.id = doc[L"id"].GetString(); delegateInfo.code = array[0].GetString(); delegateInfo.codeName = array[1].GetString(); delegateInfo.buy1_money = doc[L"buy1_money"].GetString(); delegateInfo.big_num_count = doc[L"big_num_count"].GetInt(); delegateInfo.big_num_money = doc[L"big_num_money"].GetString(); array = doc[L"not_deal_big_num_count"].GetArray(); delegateInfo.not_deal_big_num_count_pre = array[0].GetInt(); delegateInfo.not_deal_total_big_count_after = array[1].GetInt(); array = doc[L"not_deal_big_num_money"].GetArray(); delegateInfo.not_deal_big_num_money_pre = array[0].GetString(); delegateInfo.not_deal_big_num_money_after = array[1].GetString(); delegateInfo.left_count = doc[L"left_count"].GetInt(); delegateInfo.left_money = doc[L"left_money"].GetString(); delegateInfo.volume_rate = doc[L"volume_rate"].GetFloat(); delegateInfo.pay_attention = doc[L"pay_attention"].GetBool(); delegateInfo.trade_progress_percent = doc[L"trade_progress_percent"].GetFloat(); delegateInfo.limit_up_price = doc[L"limit_up_price"].GetFloat(); delegateInfo.is_near_big_order = doc[L"is_near_big_order"].GetString(); delegateInfo.block = doc[L"block"].GetString(); array=doc[L"trade_queue"].GetArray(); list<TradeQueue> queueList; for (int j = 0; j < array.Size(); j++) { int num = array[j].GetArray()[0].GetInt(); int type = array[j].GetArray()[1].GetInt(); queueList.push_back(TradeQueue({to_string(num),type})); } delegateInfo.tradeQueueList = queueList; fresults.push_back(delegateInfo); } } else { throw string("网络请求出错"); } return fresults; } void MainFrame::startRequestDelegatedInfoListTask(MainFrame* context) { while (TRUE) { if (context->killed) { break; } try { context->requestDelegatedInfoList(); } catch (string st) { } catch (...) { } Sleep(2000); } } void MainFrame::requestDelegatedInfoList() { try { cout <<"请求委托列表"<< endl; string result = MyNetworkApi::get_delegated_buy_code_infos(); if (killed) { return; } auto doc = JsonUtil::parseUTF8(result); auto delegateList = parseDelegates(result); // 根据ID if (this != nullptr) { this->delegateList = delegateList; this->refresh(); } } catch (string st) { } } void MainFrame::OnSelectionChanged(wxDataViewEvent& event) { // 不允许响应 event.Veto(); } void MainFrame::OnButtonOpenTradeQueueClick(wxCommandEvent& event) { if (delegateList.size()>0) { WindowPosSize r = MyConfigUtil::getTradeQueueWindowPos(); if (r.x == -1 && r.y == -1) { r.x = 0; r.y = 0; r.width = 400; r.height = 400; } for (list<DelegateInfo>::iterator e = delegateList.begin(); e != delegateList.end(); ++e) { auto delegateInfo = *e; TradeQueueFrame* tradeQueueFrame = new TradeQueueFrame(delegateInfo.codeName, delegateInfo.code, wxPoint(r.x, r.y), wxSize(r.width, r.height)); tradeQueueFrame->Show(true); } } } DelegateQueue/MainFrame.h
New file @@ -0,0 +1,65 @@ #pragma once #include <wx/wx.h> #include <wx/listctrl.h> #include <wx/dataview.h> #include <list> #include <map> #include <string> #include "../common_nopch/JsonUtil.h" #include "TradeQueueFrame.h" #include "common.h" #define FRAME_WIDTH 386*DPI/100 #define FRAME_HEIGHT 660*DPI/100 using namespace std; class MainFrame :public wxFrame { private: wxDataViewListCtrl* m_listCtrl; wxStaticText* msgCtrl; list<DelegateInfo> delegateList; bool killed; long msgExpireTime; public: static std::map<wxString, DelegateInfo> delegateMap; public: // Constructor MainFrame(const wxString& title, wxPoint position = wxDefaultPosition, wxSize size = wxDefaultSize); // Event handlers void showMsg(string msg, MsgTypeEnum type); // 请求列表 void requestDelegatedInfoList(); private: static void clearMsg(MainFrame *context); // This class handles events void OnClose(wxCloseEvent& event); // 刷新 void refresh(); static list<DelegateInfo> parseDelegates(string result); static void startRequestDelegatedInfoListTask(MainFrame* context); // 行选中事件 void OnSelectionChanged(wxDataViewEvent& event); void OnButtonOpenTradeQueueClick(wxCommandEvent& event); }; DelegateQueue/MyConfigUtil.cpp
New file @@ -0,0 +1,59 @@ #include "../common_nopch/JsonUtil.h" #include "MyConfigUtil.h" void MyConfigUtil::setMainWindowPos(wxPoint point, wxSize size) { rapidjson::StringBuffer buf; rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); writer.StartArray(); writer.Int(point.x); writer.Int(point.y); writer.Int(size.GetWidth()); writer.Int(size.GetHeight()); writer.EndArray(); const char* json_content = buf.GetString(); setStringConfig("main_window", json_content); } WindowPosSize MyConfigUtil::getMainWindowPos() { try { string result = readStringConfig("main_window"); auto doc = JsonUtil::parseUTF8(result); return WindowPosSize({ doc[0].GetInt(), doc[1].GetInt(),doc[2].GetInt(), doc[3].GetInt() }); } catch (...) { } return DEFAULT_WINOW_POS_AND_SIZE; } void MyConfigUtil::setTradeQueueWindowPos(wxPoint point, wxSize size) { rapidjson::StringBuffer buf; rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); writer.StartArray(); writer.Int(point.x); writer.Int(point.y); writer.Int(size.GetWidth()); writer.Int(size.GetHeight()); writer.EndArray(); const char* json_content = buf.GetString(); setStringConfig("trade_queue_window", json_content); } WindowPosSize MyConfigUtil::getTradeQueueWindowPos() { try { string result = readStringConfig("trade_queue_window"); auto doc = JsonUtil::parseUTF8(result); WindowPosSize info={ doc[0].GetInt(), doc[1].GetInt(),doc[2].GetInt(), doc[3].GetInt() }; return info; } catch (...) { } return DEFAULT_WINOW_POS_AND_SIZE; } DelegateQueue/MyConfigUtil.h
New file @@ -0,0 +1,33 @@ #pragma once #include "../common_nopch/ConfigUtil.h" #include <wx/wx.h> #define DEFAULT_WINOW_POS_AND_SIZE WindowPosSize({-1, -1, -1, -1}) struct WindowPosSize { int x; int y; int width; int height; }; class MyConfigUtil:public ConfigUtil { public: // 设置主窗口的位置与大小 static void setMainWindowPos(wxPoint point, wxSize size); // 获取主窗口位置与大小 static WindowPosSize getMainWindowPos(); // 设置成交队列的位置与大小 static void setTradeQueueWindowPos(wxPoint point, wxSize size); // 获取成交队列位置与大小 static WindowPosSize getTradeQueueWindowPos(); }; DelegateQueue/MyNetworkApi.cpp
New file @@ -0,0 +1,62 @@ #include "MyNetworkApi.h" string MyNetworkApi::get_delegated_buy_code_infos() { 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_delegated_buy_code_infos"); writer.EndObject(); writer.EndObject(); 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]]}]}}";*/ return result; } string MyNetworkApi::get_trade_queue(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("get_trade_queue"); 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; } string MyNetworkApi::cancel_order(string code) { // 撤单 rapidjson::StringBuffer buf; rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); writer.StartObject(); writer.Key("type"); writer.String("cancel_order"); writer.Key("data"); writer.StartObject(); 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; } DelegateQueue/MyNetworkApi.h
New file @@ -0,0 +1,11 @@ #pragma once #include "../common_nopch/NetworkApi.h" class MyNetworkApi:public NetworkApi { public: static string get_delegated_buy_code_infos(); static string get_trade_queue(string code); static string cancel_order(string code); }; DelegateQueue/TradeQueueFrame.cpp
New file @@ -0,0 +1,95 @@ #include "TradeQueueFrame.h" #include "MyNetworkApi.h" #include <thread> #include "MyConfigUtil.h" #include "../common_nopch/Win32Util.h" TradeQueueFrame::TradeQueueFrame(const wxString& title, wxString code, wxPoint position, wxSize size) :wxFrame(NULL, wxID_ANY, title, position, size) { SetWindowStyle(GetWindowStyle() | wxSTAY_ON_TOP); //SetTransparent(225); this->killed = false; Bind(wxEVT_CLOSE_WINDOW, &TradeQueueFrame::OnClose, this); listControl = new TradeQueueListControl(this, wxID_ANY); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(listControl, 1, wxEXPAND); SetSizer(sizer); SetBackgroundColour(*wxBLACK); requestThread = new std::thread(requestTradeQueue, code, this); requestThread->detach(); } TradeQueueFrame::~TradeQueueFrame() { cout << "TradeQueueFrame 析构函数" << endl; this->killed = true; } void TradeQueueFrame::OnClose(wxCloseEvent& event) { this->killed = true; cout << "关闭窗口:" << this << endl; delete listControl; delete requestThread; // 保存当前的尺寸与位置 MyConfigUtil::setTradeQueueWindowPos(GetPosition(), GetSize()); // 正常关闭 event.Skip(); } void TradeQueueFrame::requestTradeQueue(wxString code, TradeQueueFrame* context) { int count = 0; while (TRUE) { if (context->killed) { break; } if (count % 30 == 0) { count = 1; cout << "请求的代码:" << code << " 内容地址:" << &context << "killed:" << context->killed << endl; try { list<TradeQueue> queueList; string result = MyNetworkApi::get_trade_queue(code.ToStdString()); if (context->killed) { break; } if (context->latest_request_result != result) { 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++) { int num = array[i][0].GetInt(); int type = array[i][1].GetInt(); queueList.push_back(TradeQueue({ to_string(num),type })); } } } cout << code << endl; if (context != nullptr && context->listControl != nullptr) { context->listControl->setTradeQueue(queueList); context->latest_request_result = result; } } } catch (string st) { } } count++; Sleep(100); } } DelegateQueue/TradeQueueFrame.h
New file @@ -0,0 +1,47 @@ #pragma once #include <wx/wx.h> #include <wx/listctrl.h> #include <wx/dataview.h> #include<list> #include "DataStruct.h" #include "../common_nopch/WidgetsRenderUtil.h" #include "TradeQueueListControl.h" #include <thread> using namespace std; class RequestThread : public wxThread { public: RequestThread() : wxThread(wxTHREAD_DETACHED) {} protected: virtual ExitCode Entry() override { while (TRUE) { } return (ExitCode)0; } }; class TradeQueueFrame:public wxFrame { private: TradeQueueListControl* listControl; bool killed; string latest_request_result; std::thread *requestThread; public: TradeQueueFrame(const wxString& title, wxString code, wxPoint position=wxDefaultPosition, wxSize size = wxDefaultSize); ~TradeQueueFrame(); void OnClose(wxCloseEvent& event); private: // 请求列表 // 获取交易队列 static void requestTradeQueue(wxString code, TradeQueueFrame* context); }; DelegateQueue/TradeQueueListControl.cpp
New file @@ -0,0 +1,106 @@ #include "TradeQueueListControl.h" #include "common.h" using namespace std; //wxDEFINE_EVENT(wxEVT_UPDATE_UI, wxCommandEvent); // //BEGIN_EVENT_TABLE(TradeQueueListControl, wxControl) // EVT_COMMAND(wxID_ANY, wxEVT_UPDATE_UI, TradeQueueListControl::OnUpdateUI) //END_EVENT_TABLE() TradeQueueListControl::TradeQueueListControl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size) : wxControl(parent, id, pos, size, wxBORDER_NONE) { Bind(wxEVT_PAINT, &TradeQueueListControl::OnPaint, this); } void TradeQueueListControl::OnPaint(wxPaintEvent& event) { cout <<"OnPaint"<< endl; try { wxPaintDC dc(this); dc.SetBackground(wxBrush(GetBackgroundColour())); dc.Clear(); dc.SetPen(*wxBLACK_PEN); dc.SetBrush(*wxLIGHT_GREY_BRUSH); dc.DrawRectangle(GetClientRect()); wxSize queueSize(50*DPI/100, 22*DPI/100); // 绘制背景颜色 wxRect queueRect = wxRect(GetPosition(), GetSize()); dc.SetPen(*wxBLACK); dc.SetBrush(*wxBLACK); dc.DrawRectangle(queueRect); int width = GetSize().GetWidth(); int padding = 3*DPI/100; int countPerLine = (width+padding) / (queueSize.x+padding); int lineCount = queueList.size() % countPerLine == 0 ? queueList.size() / countPerLine : queueList.size() / countPerLine + 1; std::list<TradeQueue>::iterator e = queueList.begin(); int startx = GetPosition().x + padding; int starty = GetPosition().y + padding; wxFont font = dc.GetFont(); //font.SetNumericWeight(wxFONTWEIGHT_BOLD); font.SetPointSize(10); dc.SetFont(font); for (int r = 0; r < lineCount; r++) { int top = r * queueSize.GetHeight() + padding*r; for (int c = 0; c < countPerLine; c++) { if (r * countPerLine + c >= queueList.size()) { break; } int left = c * queueSize.GetWidth() + c* padding; wxRect rect = wxRect(left + startx, top + starty, queueSize.x, queueSize.y); wxColour color; switch ((*e).type) { case 0: color = *wxRED; break; case 1: color = *wxWHITE; break; case 2: color = wxColor(209, 135, 252); break; default: color = *wxRED; break; } // wxColor(66,32,33) WidgetsRenderUtil::drawBtn(&dc, (*e).num, rect, color, *wxBLACK); if (e != queueList.end()) { ++e; } } } dc.SetTextForeground(*wxBLACK); // 更新界面 Update(); } catch (...) { } } void TradeQueueListControl::setTradeQueue(std::list<TradeQueue> queueList) { cout << "setTradeQueue" << endl; if (this != nullptr) { this->queueList = queueList; Refresh(); } } DelegateQueue/TradeQueueListControl.h
New file @@ -0,0 +1,22 @@ #pragma once #include <wx/wx.h> #include<list> #include "DataStruct.h" #include "../common_nopch/WidgetsRenderUtil.h" class TradeQueueListControl : public wxControl { private: std::list<TradeQueue> queueList; public: TradeQueueListControl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); void OnPaint(wxPaintEvent& event); void setTradeQueue(std::list<TradeQueue> queueList); }; DelegateQueue/common.h
New file @@ -0,0 +1,4 @@ #pragma once #include "DataStruct.h" #define DPI 121 DelegateQueue/config.cfg
New file @@ -0,0 +1,2 @@ trade_queue_window = "[\n -1130,\n 376,\n 565,\n 483\n]"; main_window = "[\n 132,\n 240,\n 600,\n 660\n]"; DelegateQueue/icon.ico
DelegateQueue/main.cpp
New file @@ -0,0 +1,42 @@ #include<iostream> #include <wx/wx.h> #include "MainFrame.h" #include "MyConfigUtil.h" class App :public wxApp { public: bool OnInit() { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); WindowPosSize rect = MyConfigUtil::getMainWindowPos(); cout << "获取到的坐标:" << rect.x <<" "<< rect.y << endl; wxString title = "加贝控制中心"; title.Append(to_string(DPI)); if (rect.x==-1&&rect.y==-1) { wxPoint p = wxDefaultPosition; wxSize s = wxSize(FRAME_WIDTH, FRAME_HEIGHT); MainFrame* window = new MainFrame(title, p, s); window->Show(); } else { wxPoint p= wxPoint(rect.x, rect.y); cout << "设置的坐标:" << p.x << " " << p.y << endl; wxSize s = wxSize(rect.width, rect.height); MainFrame* window = new MainFrame(title, p, s); window->Show(); } return true; } }; wxIMPLEMENT_APP(App); DelegateQueue/packages.config
New file @@ -0,0 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <packages> <package id="tencent.rapidjson" version="1.1.1" targetFramework="native" /> </packages>