// TradeRecordDlg.cpp: 实现文件
|
//
|
|
#include "common/pch.h"
|
#include "TradeRecord.h"
|
#include "TradeRecordDlg.h"
|
#include "afxdialogex.h"
|
#include "string.h"
|
#include "../common/Win32Util.h"
|
#include <thread>
|
#include <map>
|
#include "../common/NetworkApi.h"
|
#include "../common/JsonUtil.h"
|
#include "ConfigUtil.h"
|
|
// TradeRecordDlg 对话框
|
|
IMPLEMENT_DYNAMIC(TradeRecordDlg, CDialogEx)
|
|
bool TradeRecordDlg::kill;
|
|
CString TradeRecordDlg::updateTime;
|
|
|
list<TradeDelegateRecord> TradeRecordDlg::recordList;
|
|
void TradeRecordDlg::initView()
|
{
|
// 设置位置
|
POINT p = ConfigUtil::getWindowPos();
|
RECT re;
|
Win32Util::getWindowRect(GetSafeHwnd(), &re);
|
Win32Util::moveWin(GetSafeHwnd(), p.x, p.y, (re.right - re.left + 1), (re.bottom - re.top + 1));
|
|
|
//初始化列表
|
listDelegateRecord.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
|
CRect rect;
|
listDelegateRecord.GetClientRect(&rect);
|
listDelegateRecord.SetRowHeigt(24);
|
|
int unitSize = (rect.Width() - 20) / 8.2f;
|
listDelegateRecord.InsertColumn(0, _T("委托时间"), LVCFMT_LEFT, unitSize*1 ,0);
|
listDelegateRecord.InsertColumn(1, _T("合约代码"), LVCFMT_LEFT, unitSize * 1,1);
|
listDelegateRecord.InsertColumn(2, _T("合约名称"), LVCFMT_LEFT, unitSize * 1.2, 2);
|
listDelegateRecord.InsertColumn(3, _T("操作"), LVCFMT_LEFT, unitSize * 0.8,3);
|
listDelegateRecord.InsertColumn(4, _T("备注"), LVCFMT_LEFT, unitSize * 1.4,4);
|
listDelegateRecord.InsertColumn(5, _T("委托数量"), LVCFMT_LEFT, unitSize * 1, 5);
|
listDelegateRecord.InsertColumn(6, _T("单价"), LVCFMT_LEFT, unitSize * 0.8, 6);
|
listDelegateRecord.InsertColumn(7, _T("撤单时间"), LVCFMT_LEFT, unitSize * 1,7);
|
listDelegateRecord.AutoColumn();
|
}
|
|
void TradeRecordDlg::refreshData()
|
{
|
std::thread t1(requestData, this);
|
t1.detach();
|
}
|
|
void TradeRecordDlg::requestData(TradeRecordDlg* dlg)
|
{
|
while (TRUE) {
|
if (kill) {
|
break;
|
}
|
try {
|
string result = NetworkApi::list_delegate_records(updateTime);
|
cout << result << endl;
|
rapidjson::GenericDocument<rapidjson::UTF16<>> doc = JsonUtil::parseUTF16(result);
|
if (kill) {
|
break;
|
}
|
if (doc.IsObject() && doc[L"code"].GetInt() == 0) {
|
if (!doc.HasMember(L"data"))
|
continue;
|
if (!doc[L"data"].HasMember(L"list"))
|
continue;
|
list<TradeDelegateRecord> tempRecordList;
|
//解析结果
|
auto dataList = doc[L"data"][L"list"].GetArray();
|
if (dataList.Size() > 0)
|
{
|
if(doc[L"data"].HasMember(L"updateTime"))
|
dlg->updateTime = doc[L"data"][L"updateTime"].GetString();
|
}
|
for (int i = 0; i < dataList.Size(); i++) {
|
TradeDelegateRecord record;
|
record.accountID = dataList[i][L"accountID"].GetString();
|
record.orderLocalID = dataList[i][L"orderLocalID"].GetString();
|
record.securityID = dataList[i][L"securityID"].GetString();
|
record.securityName = dataList[i][L"securityName"].GetString();
|
record.direction = dataList[i][L"direction"].GetInt();
|
record.orderSysID = dataList[i][L"orderSysID"].GetString();
|
record.insertTime = dataList[i][L"insertTime"].GetString();
|
record.acceptTime = dataList[i][L"acceptTime"].GetString();
|
record.cancelTime = dataList[i][L"cancelTime"].GetString();
|
record.limitPrice = dataList[i][L"limitPrice"].GetString();
|
record.volume = dataList[i][L"volume"].GetInt();
|
record.volumeTraded = dataList[i][L"volumeTraded"].GetInt();
|
record.orderStatus = dataList[i][L"orderStatus"].GetInt();
|
record.orderSubmitStatus = dataList[i][L"orderSubmitStatus"].GetInt();
|
record.statusMsg = dataList[i][L"statusMsg"].GetString();
|
record.updateTime = dataList[i][L"updateTime"].GetString();
|
tempRecordList.push_back(record);
|
}
|
|
if (tempRecordList.size() > 0) {
|
//将原来的数据映射为map
|
map<CString, int> recordMap;
|
int index = 0;
|
for (list<TradeDelegateRecord>::iterator el = recordList.begin(); el != recordList.end(); ++el) {
|
TradeDelegateRecord r = *el;
|
recordMap.emplace(r.orderLocalID, index);
|
index++;
|
}
|
|
//判断数据是否有所变化
|
bool hasChanged = FALSE;
|
if (tempRecordList.size() != recordList.size()){
|
hasChanged = TRUE;
|
}
|
if (!hasChanged) {
|
|
for (list<TradeDelegateRecord>::iterator el = tempRecordList.begin(); el != tempRecordList.end(); ++el) {
|
TradeDelegateRecord r = *el;
|
if (recordMap.count(r.orderLocalID) < 1) {
|
//新增
|
hasChanged = TRUE;
|
break;
|
}
|
else {
|
//更改数据
|
list<TradeDelegateRecord>::iterator begin = recordList.begin();
|
int index = recordMap.find(r.orderLocalID)->second;
|
std::advance(begin, index);
|
if ((*begin).orderSysID != r.orderSysID) {
|
hasChanged = TRUE;
|
break;
|
}
|
|
if ((*begin).orderStatus != r.orderStatus) {
|
hasChanged = TRUE;
|
break;
|
}
|
|
if ((*begin).orderSubmitStatus != r.orderSubmitStatus) {
|
hasChanged = TRUE;
|
break;
|
}
|
}
|
}
|
}
|
|
|
if (hasChanged) {
|
|
dlg->listDelegateRecord.SetRedraw(false);
|
|
//更改数据
|
for (list<TradeDelegateRecord>::iterator el = tempRecordList.begin(); el != tempRecordList.end(); ++el) {
|
TradeDelegateRecord r = *el;
|
if (recordMap.count(r.orderLocalID) < 1) {
|
//新增
|
dlg->recordList.push_back(r);
|
int count = dlg->listDelegateRecord.GetItemCount();
|
// 添加一行数据
|
dlg->listDelegateRecord.InsertItem(count, r.acceptTime.GetLength() > 0 ? r.acceptTime : r.insertTime);
|
dlg->listDelegateRecord.SetItemText(count, 1, r.securityID);
|
dlg->listDelegateRecord.SetItemText(count, 2, r.securityName);
|
dlg->listDelegateRecord.SetItemText(count, 3, dlg->getDirectionDesc(r.direction));
|
dlg->listDelegateRecord.SetItemText(count, 4, dlg->getOrderStatusDesc(r.orderStatus));
|
dlg->listDelegateRecord.SetItemText(count, 5, CString(std::to_string(r.volume).c_str()));
|
dlg->listDelegateRecord.SetItemText(count, 6,r.limitPrice);
|
dlg->listDelegateRecord.SetItemText(count, 7,r.cancelTime);
|
//撤单,拒绝
|
if (r.orderStatus == 6 || r.orderStatus == 7) {
|
dlg->listDelegateRecord.SetItemData(count, COLOR_DEFAULT);
|
}
|
else {
|
if (r.direction == 0) {
|
//买入
|
dlg->listDelegateRecord.SetItemData(count, COLOR_RED);
|
}
|
else if (r.direction == 1) {
|
//卖出
|
dlg->listDelegateRecord.SetItemData(count, COLOR_BLUE);
|
}
|
}
|
}
|
else {
|
//更改数据
|
list<TradeDelegateRecord>::iterator begin = recordList.begin();
|
int index = recordMap.find(r.orderLocalID)->second;
|
std::advance(begin, index);
|
(*begin).orderSysID = r.orderSysID;
|
(*begin).acceptTime = r.acceptTime;
|
(*begin).cancelTime = r.cancelTime;
|
(*begin).volumeTraded = r.volumeTraded;
|
(*begin).orderStatus = r.orderStatus;
|
(*begin).orderSubmitStatus = r.orderSubmitStatus;
|
(*begin).statusMsg = r.statusMsg;
|
(*begin).updateTime = r.updateTime;
|
|
dlg->listDelegateRecord.SetItemText(index, 0, r.acceptTime.GetLength() > 0 ? r.acceptTime : r.insertTime);
|
dlg->listDelegateRecord.SetItemText(index, 1, r.securityID);
|
dlg->listDelegateRecord.SetItemText(index, 2, r.securityName);
|
dlg->listDelegateRecord.SetItemText(index, 3, dlg->getDirectionDesc(r.direction));
|
dlg->listDelegateRecord.SetItemText(index, 4, dlg->getOrderStatusDesc(r.orderStatus));
|
dlg->listDelegateRecord.SetItemText(index, 5, CString(std::to_string(r.volume).c_str()));
|
dlg->listDelegateRecord.SetItemText(index, 6, r.limitPrice);
|
dlg->listDelegateRecord.SetItemText(index, 7, r.cancelTime);
|
//撤单,拒绝
|
if (r.orderStatus == 6 || r.orderStatus == 7) {
|
dlg->listDelegateRecord.SetItemData(index, COLOR_DEFAULT);
|
}
|
else {
|
if (r.direction == 0) {
|
//买入
|
dlg->listDelegateRecord.SetItemData(index, COLOR_RED);
|
}
|
else if (r.direction == 1) {
|
//卖出
|
dlg->listDelegateRecord.SetItemData(index, COLOR_BLUE);
|
}
|
}
|
}
|
}
|
dlg->listDelegateRecord.SetRedraw(true);
|
}
|
}
|
}
|
|
result = NetworkApi::get_money();
|
if (kill) {
|
break;
|
}
|
cout << result << endl;
|
rapidjson::Document doc1 = JsonUtil::parseUTF8(result);
|
if (doc1.IsObject() && doc1["code"].GetInt() == 0) {
|
if (doc1.HasMember("data")&& doc1["data"].IsArray())
|
{
|
dlg->labelUseful.SetWindowTextW(CString(StringUtil::to_string(doc1["data"][0]["usefulMoney"].GetDouble()).c_str()));
|
dlg->labelTotal.SetWindowTextW(CString(StringUtil::to_string(doc1["data"][0]["usefulMoney"].GetDouble() + doc1["data"][0]["frozenCash"].GetDouble()).c_str()));
|
dlg->labelFetchLimit.SetWindowTextW(CString(StringUtil::to_string(doc1["data"][0]["fetchLimit"].GetDouble()).c_str()));
|
dlg->labelFrozen.SetWindowTextW(CString(StringUtil::to_string(doc1["data"][0]["frozenCash"].GetDouble()).c_str()));
|
}
|
}
|
|
|
}
|
catch (...) {
|
|
|
}
|
// 每1s请求一次
|
Sleep(1000);
|
}
|
|
|
}
|
|
CString TradeRecordDlg::getOrderStatusDesc(int orderStatus)
|
{
|
switch (orderStatus)
|
{
|
case 0:
|
return L"预埋";
|
case 1:
|
return L"未知";
|
case 2:
|
return L"交易所已接收";
|
case 3:
|
return L"部分成交";
|
case 4:
|
return L"全部成交";
|
case 5:
|
return L"部成部撤";
|
case 6:
|
return L"全部撤单";
|
case 7:
|
return L"交易所已拒绝";
|
default:
|
return L"发往交易核心";
|
}
|
}
|
|
CString TradeRecordDlg::getDirectionDesc(int direction)
|
{
|
switch(direction)
|
{
|
case 0:
|
return L"买入";
|
case 1:
|
return L"卖出";
|
}
|
return CString();
|
}
|
|
TradeRecordDlg::TradeRecordDlg(CWnd* pParent /*=nullptr*/)
|
: CDialogEx(IDD_TRADE_RECORD, pParent)
|
{
|
|
}
|
|
TradeRecordDlg::~TradeRecordDlg()
|
{
|
}
|
|
void TradeRecordDlg::DoDataExchange(CDataExchange* pDX)
|
{
|
CDialogEx::DoDataExchange(pDX);
|
DDX_Control(pDX, label_total, labelTotal);
|
DDX_Control(pDX, label_fetchlimit, labelFetchLimit);
|
DDX_Control(pDX, label_frozen, labelFrozen);
|
DDX_Control(pDX, label_useful, labelUseful);
|
DDX_Control(pDX, label_make_money, labelMake);
|
DDX_Control(pDX, label_make_rate, labelMakeRate);
|
DDX_Control(pDX, list_delegate_record, listDelegateRecord);
|
}
|
|
|
BEGIN_MESSAGE_MAP(TradeRecordDlg, CDialogEx)
|
ON_WM_CTLCOLOR()
|
ON_WM_MEASUREITEM()
|
ON_WM_SIZE()
|
ON_NOTIFY(NM_CUSTOMDRAW, list_delegate_record, &TradeRecordDlg::OnNMCustomdrawdelegaterecord)
|
ON_NOTIFY(NM_DBLCLK, list_delegate_record, &TradeRecordDlg::OnNMDblclkdelegaterecord)
|
ON_WM_CLOSE()
|
END_MESSAGE_MAP()
|
|
|
// TradeRecordDlg 消息处理程序
|
|
|
HBRUSH TradeRecordDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
|
{
|
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
|
|
if (nCtlColor == CTLCOLOR_STATIC) {
|
int nID = pWnd->GetDlgCtrlID();
|
switch (nID) {
|
case label_total:
|
case label_fetchlimit:
|
case label_useful:
|
case label_make_money:
|
case label_frozen:
|
case label_make_rate:
|
pDC->SetTextColor(RGB(255, 50, 50));
|
break;
|
}
|
}
|
return hbr;
|
}
|
|
|
BOOL TradeRecordDlg::OnInitDialog()
|
{
|
CDialogEx::OnInitDialog();
|
initView();
|
kill = FALSE;
|
//自动刷新数据
|
refreshData();
|
return TRUE;
|
}
|
|
|
void TradeRecordDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
|
{
|
if (list_delegate_record == nIDCtl)
|
{
|
// 设置行高为20像素
|
lpMeasureItemStruct->itemHeight = 40;
|
}
|
|
|
CDialogEx::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
|
|
}
|
|
|
void TradeRecordDlg::OnSize(UINT nType, int cx, int cy)
|
{
|
CDialogEx::OnSize(nType, cx, cy);
|
if (nType == SIZE_RESTORED || nType == SIZE_MAXIMIZED)
|
{
|
// TODO 改变控件大小
|
RECT rect;
|
Win32Util::getWindowRect(GetSafeHwnd(), &rect);
|
int topHeight = 88;
|
int margin = 11;
|
if (Win32Util::isWindowShow(GetSafeHwnd()))
|
{
|
int x = margin;
|
int y = topHeight;
|
listDelegateRecord.MoveWindow(x,y, (rect.right - rect.left + 1 - (int)(3.5* margin)), (rect.bottom - rect.top + 1 - topHeight - (int)(margin*4.5)), TRUE);
|
}
|
}
|
|
|
}
|
|
|
void TradeRecordDlg::OnNMCustomdrawdelegaterecord(NMHDR* pNMHDR, LRESULT* pResult)
|
{
|
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
|
// TODO: 在此添加控件通知处理程序代码
|
|
NMCUSTOMDRAW nmCustomDraw = pLVCD->nmcd;
|
|
if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
|
{
|
*pResult = CDRF_NOTIFYITEMDRAW;
|
}
|
else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
|
{
|
//整行处理
|
if (COLOR_BLUE == nmCustomDraw.lItemlParam)
|
{
|
pLVCD->clrText = RGB(0, 0, 159);
|
}
|
else if (COLOR_RED == nmCustomDraw.lItemlParam)
|
{
|
pLVCD->clrText = RGB(206, 38, 26); //背景颜色
|
//pLVCD->clrText = RGB(255, 255, 255); //文字颜色
|
}
|
else if (COLOR_DEFAULT == nmCustomDraw.lItemlParam)
|
{
|
//pLVCD->clrTextBk = RGB(255, 255, 255);
|
pLVCD->clrText = RGB(96, 96, 96);
|
}
|
*pResult = CDRF_NOTIFYSUBITEMDRAW;
|
}//这上面的都是默认的不用理
|
else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
|
{
|
// 暂时不处理每一列
|
return;
|
//处理列
|
COLORREF clrNewTextColor, clrNewBkColor;//当前单元格的文本颜色以及背景颜色
|
int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);//当前行
|
CString strTemp = listDelegateRecord.GetItemText(nItem, pLVCD->iSubItem);//当前行的某一列的内容
|
switch (pLVCD->iSubItem)//pLVCD->iSubItem表示当前列,等到所有列都遍历完才会进入下一行
|
{
|
case 3://表明处理到此行的第3列时
|
{
|
int age = atoi((CT2A(strTemp.GetBuffer())));//字符串转int
|
if (age > 22 || age < 18)//当年龄超过范围,设置字体颜色异常
|
{
|
clrNewTextColor = RGB(255, 0, 0);
|
clrNewBkColor = RGB(255, 255, 255);
|
pLVCD->clrText = clrNewTextColor;
|
//pLVCD->clrTextBk = clrNewBkColor;
|
}
|
else //正常年龄范围为黑色文本
|
{
|
pLVCD->clrText = RGB(0, 0, 0);
|
//pLVCD->clrTextBk = RGB(255, 255, 255);
|
}
|
*pResult = CDRF_DODEFAULT;
|
break;
|
}
|
case 4://表明处理到此行的第4列时
|
{
|
int height = atoi((CT2A(strTemp.GetBuffer())));//字符串转int
|
if (height > 190 || height < 150)//当身高超过范围,设置字体颜色异常
|
{
|
clrNewTextColor = RGB(0, 0, 255);
|
clrNewBkColor = RGB(255, 255, 255);
|
pLVCD->clrText = clrNewTextColor;
|
//pLVCD->clrTextBk = clrNewBkColor;
|
}
|
else //正常年龄范围为黑色文本
|
{
|
pLVCD->clrText = RGB(0, 0, 0);
|
//pLVCD->clrTextBk = RGB(255, 255, 255);
|
}
|
*pResult = CDRF_DODEFAULT;
|
break;
|
}
|
default://默认为黑色文本
|
pLVCD->clrText = RGB(0, 0, 0);
|
//pLVCD->clrTextBk = RGB(255, 255, 255);
|
*pResult = CDRF_DODEFAULT;
|
break;
|
}
|
|
}
|
|
// *pResult = 0;
|
// *pResult |= CDRF_NOTIFYPOSTPAINT; //必须有,不然就没有效果
|
// *pResult |= CDRF_NOTIFYITEMDRAW; //必须有,不然就没有效果
|
return;
|
}
|
|
|
void TradeRecordDlg::OnNMDblclkdelegaterecord(NMHDR* pNMHDR, LRESULT* pResult)
|
{
|
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
|
int rowIndex = pNMItemActivate->iItem;
|
std::list<TradeDelegateRecord>::iterator ele = recordList.begin();
|
std::advance(ele,rowIndex);
|
CString code = (*ele).securityID;
|
CString orderSysID = (*ele).orderSysID;
|
CString accountId = (*ele).accountID;
|
|
try {
|
NetworkApi::cancel_order(code, orderSysID, accountId);
|
}
|
catch (CString st) {
|
AfxMessageBox(st);
|
}
|
catch (wstring st) {
|
AfxMessageBox(CString( StringUtil::wstringToString(st).c_str()));
|
}
|
//第几行
|
*pResult = 0;
|
}
|
|
|
void TradeRecordDlg::OnClose()
|
{
|
// TODO: 在此添加消息处理程序代码和/或调用默认值
|
kill = TRUE;
|
recordList.clear();
|
updateTime = "";
|
RECT rect;
|
Win32Util::getWindowRect(GetSafeHwnd(), &rect);
|
ConfigUtil::setWindowPos(rect.left, rect.top);
|
CDialogEx::OnClose();
|
}
|