admin
2023-01-02 954ead41d9391bca28a3cc4f9592f73f25b3bbc8
'完善批量设置代码'
1个文件已删除
34个文件已修改
2个文件已添加
1636 ■■■■ 已修改文件
ConsoleApplication/CaptureUtil.cpp 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/ConsoleApplication.vcxproj 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/ConsoleApplication.vcxproj.filters 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/CurrentPriceCapture.cpp 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/GPUtil.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/ImgUtil.cpp 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/ImgUtil.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/L2DataCapture.cpp 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/L2DataCapture.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/L2TradeQueueUtil.cpp 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/L2TradeQueueUtil.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/OpenCLExcuter.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/OpenCLExcuter.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSActionUtil.cpp 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSActionUtil.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSGPDataCapture.cpp 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeListCapture.cpp 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeListCapture.h 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeQueueCapture.cpp 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeQueueCaptureManager.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/Win32Util.cpp 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/Win32Util.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/kernel.cl 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/main.cpp 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/JsonUtil.h 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/SocketManager.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/SocketManager.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/app.aps 补丁 | 查看 | 原始文档 | blame | 历史
app/app.rc 补丁 | 查看 | 原始文档 | blame | 历史
app/app.vcxproj.user 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/appDlg.cpp 363 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/appDlg.h 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/codesDataDlog.cpp 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/codesDataDlog.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/resource.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/setting.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/user.txt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/CaptureUtil.cpp
@@ -56,26 +56,11 @@
            tempL2.push_back(frameInfo);
        }
        else {
            //查找第一个子元素
            HWND temp =  FindWindowEx(frameInfo.frame, NULL,NULL, NULL);
            RECT tempRect;
            GetWindowRect(temp, &tempRect);
        
            while (!IsWindowVisible(temp) || tempRect.right- tempRect.left<100) {
                temp= FindWindowEx(frameInfo.frame, temp, NULL, NULL);
                GetWindowRect(temp, &tempRect);
            if (frameInfo.position.bottom - frameInfo.position.top < 100 && frameInfo.position.bottom - frameInfo.position.top >40)
            {
                tempTrade.push_back(frameInfo);
            }
            HWND tempc = FindWindowEx(temp, NULL, NULL, NULL);
            tempc = FindWindowEx(temp, tempc, NULL, NULL);
            tempc = FindWindowEx(tempc, NULL, TEXT("SysListView32"), NULL);
            GetWindowRect(tempc, &tempRect);
            FrameInfo tempFrame = FrameInfo();
            tempFrame.frame = tempc;
            tempFrame.position = tempRect;
            tempTrade.push_back(tempFrame);
        }
    }
    //排序
ConsoleApplication/ConsoleApplication.vcxproj
@@ -126,7 +126,7 @@
    <Link>
      <SubSystem>Console</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AdditionalDependencies>opencv_world455d.lib;OpenCL.lib;jemallocd.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <AdditionalDependencies>opencv_world455d.lib;OpenCL.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -148,6 +148,7 @@
  <ItemGroup>
    <ClCompile Include="BaseCapture.cpp" />
    <ClCompile Include="CurrentPriceCapture.cpp" />
    <ClCompile Include="L2TradeQueueUtil.cpp" />
    <ClCompile Include="TaskChecker.cpp" />
    <ClCompile Include="THSGPDataCapture.cpp" />
    <ClCompile Include="THSL2RepairTool.cpp" />
@@ -174,6 +175,7 @@
    <ClInclude Include="BaseCapture.h" />
    <ClInclude Include="CurrentPriceCapture.h" />
    <ClInclude Include="GPUtil.h" />
    <ClInclude Include="L2TradeQueueUtil.h" />
    <ClInclude Include="TaskChecker.h" />
    <ClInclude Include="THSGPDataCapture.h" />
    <ClInclude Include="THSL2RepairTool.h" />
ConsoleApplication/ConsoleApplication.vcxproj.filters
@@ -84,6 +84,9 @@
    <ClCompile Include="TradeQueueCaptureManager.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="L2TradeQueueUtil.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="resource.h">
@@ -158,6 +161,9 @@
    <ClInclude Include="TradeQueueCaptureManager.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="L2TradeQueueUtil.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="ConsoleApplication.rc">
ConsoleApplication/CurrentPriceCapture.cpp
@@ -325,6 +325,11 @@
            int y = wrect.top + 50;
            PostMessage(win, WM_MOUSEWHEEL, 0, MAKEWORD(x, y));
            Sleep(1000);
            int re_try_count = 0;
            while (re_try_count < 3) {
                int invalid_price_count = 0;
                re_try_count++;
            cv::Mat oimg = CaptureUtil::capture(win);
            list<CurrentPriceData> codes = capture(oimg,openCLExcuter);
            for (list<CurrentPriceData>::iterator ele = codes.begin();ele != codes.end();ele++) {
@@ -333,8 +338,20 @@
                    codesSet.insert(code);
                    flist.push_back(*ele);
                }
                    else if (stof((*ele).price) <= 0) {
                        // 获取的价格无效
                        invalid_price_count++;
                    }
            }
            codes.clear();
                if (invalid_price_count <= 1) {
                    // 无效价格代码数量小于1个就退出
                    break;
                }
                else {
                    Sleep(500);
                }
            }
            Sleep(50);
    }
    return flist;
ConsoleApplication/GPUtil.h
@@ -41,5 +41,15 @@
        return in;
    }
    static bool isBeforeTradeTime() {
        //9:25-9:31
        int time = getNowSecondTime();
        bool in = false;
        if (time < 9 * 3600 + 29 * 60) {
            in = true;
        }
        return in;
    }
};
ConsoleApplication/ImgUtil.cpp
@@ -675,17 +675,18 @@
                if (startf > -1 && endf > -1) {
                    //内容坐标
                       //LogUtil::debug("内容的高度为:%d \n", endf - startf);
                    int* dd = (int*)malloc(sizeof(int) * 4);
                    *dd = startf;
                    *(dd + 1) = startCol;
                    *(dd + 2) = endf;
                    *(dd + 3) = endCol;
                    //行数据高大于6才为有效的行高
                    if (endf - startf > 6)
                    {
                        //删除第一条数据
                        if (deleteEmpty)
                        {
                            int* dd = (int*)malloc(sizeof(int) * 4);
                            *dd = startf;
                            *(dd + 1) = startCol;
                            *(dd + 2) = endf;
                            *(dd + 3) = endCol;
                            dataItemList.push_back(dd);
                        }
                        deleteEmpty = 1;
ConsoleApplication/ImgUtil.h
@@ -58,6 +58,14 @@
#endif 
struct  ImgArea
{
    int startx;
    int starty;
    int endx;
    int endy;
};
using namespace std;
class ImgUtil
{
ConsoleApplication/L2DataCapture.cpp
@@ -6,6 +6,7 @@
#include "TaskChecker.h"
#include "GPUtil.h"
#include "LogUtil.h"
#include "L2TradeQueueUtil.h"
//#define malloc(size) malloc(size)
//#define free(ptr) free(ptr)
@@ -14,6 +15,8 @@
bool L2DataCapture::tradeTimeCapture;
OpenCLExcuter* L2DataCapture::openCLExcuter[THS_FRAME_COUNT];
OpenCLExcuter* L2DataCapture::openCLExcuterQueue[THS_FRAME_COUNT];
TradeQueueCapture* L2DataCapture::tradeQueueCapture[THS_FRAME_COUNT];
@@ -43,6 +46,10 @@
                Sleep(2);
                continue;
            }
        }
        if (GPUtil::isBeforeTradeTime()) {
            Sleep(1000);
        }
        if (running && runnings[index] && gpCodes[index].length() > 0) {
@@ -88,12 +95,37 @@
void L2DataCapture::_run_trade_queue(int index)
{
    while (true) {
        if (killRunnings[index])
            break;
        TaskChecker::clientLiveTime.l2[index] = clock();
        if (tradeTimeCapture) {
            if (!GPUtil::isTradeTime()) {
                Sleep(2);
                continue;
            }
        }
        if (GPUtil::isBeforeTradeTime()) {
            Sleep(1000);
        }
        if (running && runnings[index] && gpCodes[index].length() > 0) {
            //识别数据
            string code = gpCodes[index];
            try {
                list<int> numList;//= tradeQueueCapture[index]->recognition(CaptureUtil::getHWND(index, CAPTURE_TYPE_TRADE_QUEUE));
                trade_queue_data_callback(index, code, numList, context);
                clock_t start = clock();
                cv::Mat mat = CaptureUtil::capture(index, CAPTURE_TYPE_TRADE_QUEUE);
                if (mat.cols <= 400 || mat.rows <= 30) {
                    mat.release();
                    mat = NULL;
                    Sleep(100);
                    throw string("截图出错");
                }
                L2TradeQueue result = captureLevel2TradeQueueData(mat, index);
                long processTime = clock() - start;
                cout << "时间消耗:" << processTime << endl;
                trade_queue_data_callback(index, code, result, context);
            }
            catch (...) {
@@ -138,6 +170,9 @@
    {
        openCLExcuter[i] = new OpenCLExcuter();
        openCLExcuter[i]->init();
        openCLExcuterQueue[i]= new OpenCLExcuter();
        openCLExcuterQueue[i]->init();
        tradeQueueCapture[i] = new TradeQueueCapture();
    }
@@ -148,8 +183,8 @@
        thread rt(&(L2DataCapture::_run), i);
        rt.detach();
        killRunnings[i] = FALSE;
        //thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i);
        //rt_trade_queue.detach();
        thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i);
        rt_trade_queue.detach();
    }
    //获取同花顺窗口句柄
@@ -224,6 +259,7 @@
    return resultList;
}
list<TradeData> L2DataCapture::captureLevel2TradeData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify)
{
@@ -620,6 +656,189 @@
    return resultList;
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(HWND hwnd, int index)
{
    cv::Mat mat =    CaptureUtil::capture(hwnd);
    return captureLevel2TradeQueueData(mat,index);
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(cv::Mat& oimg, int identify)
{
    return captureLevel2TradeQueueData(openCLExcuterQueue[identify],oimg,identify);
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify)
{
    cv::Mat img = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
    if (oimg.channels() == 1) {
        //黑白图片
        img.data = oimg.data;
    }
    else {
        try {
            if (oimg.channels() == 3)
            {
                openCLExcuter->rgb2Gray(oimg, img.data);
            }
            else {
                openCLExcuter->rgba2Gray(oimg, img.data);
            }
            oimg.release();
        }
        catch (...) {
            oimg.release();
            oimg = NULL;
            img.release();
            img = NULL;
            throw string("灰度出错");
        }
    }
    try {
        list<ImgArea> splitAreas = L2TradeQueueUtil::splitElements(img);
        int* splitResult = (int*)malloc(sizeof(int) * 4 * 6);
        int index = 0;
        for (list<ImgArea>::iterator ele = splitAreas.begin(); ele != splitAreas.end(); ++ele) {
            ImgArea area = *ele;
            if (area.startx < 0) {
                splitResult[index * 4 + 0] = 0;
                splitResult[index * 4 + 1] = 0;
                splitResult[index * 4 + 2] = 0;
                splitResult[index * 4 + 3] = 0;
            }
            else {
                splitResult[index * 4 + 0] = area.startx;
                splitResult[index * 4 + 1] = area.starty;
                splitResult[index * 4 + 2] = area.endx;
                splitResult[index * 4 + 3] = area.endy;
            }
            index++;
        }
        clock_t time_2 = clock();
        unsigned char* zeroData = (unsigned char*)malloc(sizeof(unsigned char) * _NUMBER_GP_CODE_WIDTH * _NUMBER_GP_CODE_HEIGHT);
        for (int r = 0; r < _NUMBER_GP_CODE_HEIGHT; r++) {
            for (int c = 0; c < _NUMBER_GP_CODE_WIDTH; c++)
            {
                zeroData[r * _NUMBER_GP_CODE_WIDTH + c] = ImgUtil::NUMS_GP_CODE[0].data.ptr<uchar>(r)[c];
            }
        }
        int num_length_per_ele = 6;
        int ele_count_per_line = 6;
        int line_number_count = ele_count_per_line * num_length_per_ele;
        unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
        unsigned char types[] = { NUM_TYPE_TIME,NUM_TYPE_TIME,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU };
        UcharDataInfo typesData = UcharDataInfo();
        typesData.length = 6;
        typesData.data = types;
        openCLExcuter->splitPlateNum(img, IntDataInfo({ splitResult,(int)(ele_count_per_line * 1) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, ele_count_per_line, num_length_per_ele);
        free(splitResult);
        free(zeroData);
        //识别
        uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
        try {
            openCLExcuter->createNumberTemplates(1, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count, ImgUtil::numsOneLevel_gpcode, templateNums);
        }
        catch (...) {
            free(totalNumberData);
            free(templateNums);
            throw string("创建数据模板出错");
        }
        uchar** numberResult = nullptr;
        //数字识别
        try {
            numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, 1 * _NUMBER_GP_CODE_HEIGHT, _NUMBER_GP_CODE_WIDTH * 10 * line_number_count, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count);
            //释放内存
            free(totalNumberData);
            free(templateNums);
        }
        catch (...) {
            //释放内存
            free(totalNumberData);
            free(templateNums);
            throw string("数字识别出错");
        }
        img.release();
        //循环读取数字
        uchar* lineData = numberResult[0];
        string sellOneTime = "";
        sellOneTime.append(to_string(lineData[0])).append(to_string(lineData[1]));
        sellOneTime.append(":");
        sellOneTime.append(to_string(lineData[2])).append(to_string(lineData[3]));
        sellOneTime.append(":");
        sellOneTime.append(to_string(lineData[4])).append(to_string(lineData[5]));
        string buyOneTime = "";
        buyOneTime.append(to_string(lineData[6])).append(to_string(lineData[7]));
        buyOneTime.append(":");
        buyOneTime.append(to_string(lineData[8])).append(to_string(lineData[9]));
        buyOneTime.append(":");
        buyOneTime.append(to_string(lineData[10])).append(to_string(lineData[11]));
        string sellOnePrice = "";
        for (int i = 0; i < 6; i++)
        {
            sellOnePrice.append(to_string(lineData[12 + i]));
            if (i == 3) {
                sellOnePrice.append(".");
            }
        }
        string sellOneNum = "";
        for (int i = 0; i < 6; i++)
        {
            sellOneNum.append(to_string(lineData[18 + i]));
        }
        string buyOnePrice = "";
        for (int i = 0; i < 6; i++)
        {
            buyOnePrice.append(to_string(lineData[24 + i]));
            if (i == 3) {
                buyOnePrice.append(".");
            }
        }
        string buyOneNum = "";
        for (int i = 0; i < 6; i++)
        {
            buyOneNum.append(to_string(lineData[30 + i]));
        }
        //释放内存
        free(lineData);
        index++;
        free(numberResult);
        L2TradeQueue tradeQueue = L2TradeQueue();
        tradeQueue.buyOnePrice = buyOnePrice;
        tradeQueue.buyOneVolumn = buyOneNum;
        tradeQueue.buyTime = buyOneTime;
        tradeQueue.sellOnePrice = sellOnePrice;
        tradeQueue.sellOneVolumn = sellOneNum;
        tradeQueue.sellTime = sellOneTime;
        return tradeQueue;
    }
    catch (...) {
        img.release();
        img = NULL;
        throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
    }
}
//捕获level2的盘口数据
list<TradeData> L2DataCapture::captureLevel2TradeData(HWND hwnd, int index) throw(int) {
    clock_t  starttime = clock();
ConsoleApplication/L2DataCapture.h
@@ -8,14 +8,25 @@
#include "BaseCapture.h"
#define THS_FRAME_COUNT 8
struct  L2TradeQueue
{
    string sellTime;
    string sellOnePrice;
    string sellOneVolumn;
    string buyTime;
    string buyOnePrice;
    string buyOneVolumn;
};
typedef void (*CallbackFun)(int index, string code,long captureTime,long processTime, list<TradeData> dataList, void* contex);
typedef void (*CallbackFun_Trade_Queue)(int index, string code, list<int> numList, void* contex);
typedef void (*CallbackFun_Trade_Queue)(int index, string code, L2TradeQueue info, void* contex);
class L2DataCapture: public BaseCapture
{
private:
    static OpenCLExcuter* openCLExcuter[THS_FRAME_COUNT];
    static OpenCLExcuter* openCLExcuterQueue[THS_FRAME_COUNT];
    static TradeQueueCapture* tradeQueueCapture[THS_FRAME_COUNT];
    //是否在交易时间才截图
@@ -78,6 +89,15 @@
    static list<TradeData>  captureLevel2TradeData(HWND hwnd,int index) throw(int);
    static list<TradeData>  captureLevel2TradeData(cv::Mat& oimg,int identify);
    static list<TradeData>  captureLevel2TradeData(OpenCLExcuter *openCLExcuter, cv::Mat& oimg, int identify);
    static L2TradeQueue captureLevel2TradeQueueData(HWND hwnd, int index);
    static L2TradeQueue  captureLevel2TradeQueueData(cv::Mat& oimg, int identify);
    static L2TradeQueue  captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify);
    //设置代码
    static void setGPCode(int index, string code);
    //获取代码
ConsoleApplication/L2TradeQueueUtil.cpp
New file
@@ -0,0 +1,184 @@
#include "L2TradeQueueUtil.h"
list<ImgArea> L2TradeQueueUtil::splitElements(cv::Mat img)
{
    list<int*> rowDataList = splitRows(img);
    if (rowDataList.size() != 2) {
        for (list<int*>::iterator ele = rowDataList.begin(); ele != rowDataList.end(); ++ele) {
            free(*ele);
        }
        throw string("分隔行出错");
    }
    list<ImgArea> posList;
    //分隔出委卖队列时间,委卖单价,委卖手数,委买队列时间,委买单价,委买手数
    int* rowData = *(rowDataList.begin());
    //委卖队列时间
    list<int*> dataList = splitCols(img, 0, rowData[0], img.cols / 2, rowData[1]);
    if (dataList.size() > 1)
    {
        list<int*>::iterator ele = dataList.begin();
        ++ele;
        posList.push_back({ (*ele)[0],(*ele)[1],(*ele)[2],(*ele)[3] });
    }
    else {
        posList.push_back({ -1,-1,-1,-1 });
    }
    freeData(dataList);
    //委买队列时间
    dataList = splitCols(img, img.cols / 2 + 1, rowData[0], img.cols - 1, rowData[1]);
    if (dataList.size() > 1)
    {
        list<int*>::iterator ele = dataList.begin();
        ++ele;
        posList.push_back({ (*ele)[0],(*ele)[1],(*ele)[2],(*ele)[3] });
    }
    else {
        posList.push_back({ -1,-1,-1,-1 });
    }
    free(rowData);
    rowData = *(++rowDataList.begin());
    //委卖单价,委卖手数
    freeData(dataList);
    dataList = splitCols(img, 0, rowData[0], img.cols / 2, rowData[1]);
    if (dataList.size() > 2)
    {
        list<int*>::iterator ele = dataList.begin();
        ++ele;
        posList.push_back({ (*ele)[0],(*ele)[1],(*ele)[2],(*ele)[3] });
        ++ele;
        posList.push_back({ (*ele)[0],(*ele)[1],(*ele)[2],(*ele)[3] });
    }
    else {
        posList.push_back({ -1,-1,-1,-1 });
        posList.push_back({ -1,-1,-1,-1 });
    }
    freeData(dataList);
    //委买单价,委买手数
    dataList = splitCols(img, img.cols / 2 + 1, rowData[0], img.cols - 1, rowData[1]);
    if (dataList.size() > 2)
    {
        list<int*>::iterator ele = dataList.begin();
        ++ele;
        posList.push_back({ (*ele)[0],(*ele)[1],(*ele)[2],(*ele)[3] });
        ++ele;
        posList.push_back({ (*ele)[0],(*ele)[1],(*ele)[2],(*ele)[3] });
    }
    else {
        posList.push_back({-1,-1,-1,-1});
        posList.push_back({-1,-1,-1,-1});
    }
    freeData(dataList);
    free(rowData);
    if (false) {
        //保存
        int index = -1;
        for (list<ImgArea>::iterator ele = posList.begin(); ele != posList.end(); ++ele) {
            index++;
            ImgArea data = *ele;
            if (data.startx>-1) {
                //保存数据
                cv::Mat mat = cv::Mat(img, cv::Rect(data.startx, data.starty, data.endx - data.startx + 1, data.endy - data.starty + 1));
                string path = "C:\\Users\\Administrator\\Desktop\\ocr\\l2_trade\\";
                path.append(to_string(index)).append(".png");
                cv::imwrite(path, mat);
            }
        }
    }
    return posList;
}
list<int*> L2TradeQueueUtil::splitRows(cv::Mat img)
{
    list<int*>  rowDataList;
    //图像分隔
    //先分隔
    int start_row = -1;
    int end_row = -1;
    for (int r = 0; r < img.rows; r++) {
        if (ImgDivider::isRowEmpty(img, r, 1, img.cols/4,1, _IMG_BINARY_THRESHOLD)) {
            if (end_row - start_row >=10) {
                //有数据
                int* rowRata = (int*)malloc(sizeof(int) * 2);
                rowRata[0] = start_row;
                rowRata[1] = end_row;
                rowDataList.push_back(rowRata);
                start_row = -1;
                end_row = -1;
                if (rowDataList.size() >= 2) {
                    break;
                }
            }
            start_row = r + 1;
        }
        else {
            if (start_row < 0) {
                start_row = r;
            }
            end_row =r;
        }
    }
    return rowDataList;
}
list<int*> L2TradeQueueUtil::splitCols(cv::Mat img, int startx, int starty, int endx, int endy)
{
    cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\l2_trade\\test.png", cv::Mat(img, cv::Rect(startx, starty, endx - startx, endy - starty)));
    list<int*> splitList;
    int empty_start = -1;
    int empty_end = -1;
    int start_col = -1;
    int end_col = -1;
    for (int c = startx; c <= endx; c++) {
        if (ImgDivider::isColEmpty(img, c, starty, endy)) {
            if (empty_start < 0) {
                empty_start = c;
            }
            empty_end = c;
            if (empty_end - empty_start > 10) {
                if (end_col - start_col >= 6) {
                    int* itemData = (int*)malloc(sizeof(int) * 4);
                    itemData[0] = start_col;
                    itemData[1] = starty;
                    itemData[2] = empty_start - 1;
                    itemData[3] = endy;
                    splitList.push_back(itemData);
                    start_col = -1;
                    end_col = -1;
                }
            }
        }
        else {
            if (start_col < 0) {
                start_col = c;
            }
            end_col = c;
            empty_start = -1;
            empty_end = -1;
        }
    }
    return splitList;
}
void L2TradeQueueUtil::freeData(list<int*> dataList)
{
    if (dataList.size()>0) {
        for (list<int*>::iterator ele = dataList.begin(); ele != dataList.end(); ele++) {
            free(*ele);
        }
    }
}
ConsoleApplication/L2TradeQueueUtil.h
New file
@@ -0,0 +1,18 @@
#pragma once
#include "ImgUtil.h"
class L2TradeQueueUtil
{
private:
    //行分隔
    static list<int*> splitRows(cv::Mat img);
    //列分隔
    static list<int*> splitCols(cv::Mat img,int startx,int starty,int endx,int endy);
    static void freeData(list<int*> dataList);
public:
    // 分隔元素
    static list<ImgArea> splitElements(cv::Mat img);
};
ConsoleApplication/OpenCLExcuter.cpp
@@ -138,8 +138,8 @@
void OpenCLExcuter::excuteError()
{
    destory();
    reCreateQueue();
    //destory();
    //reCreateQueue();
}
void OpenCLExcuter::init() {
ConsoleApplication/OpenCLExcuter.h
@@ -12,6 +12,7 @@
    NUM_TYPE_CODE,
    NUM_TYPE_NUM,
    NUM_TYPE_PERCENT,
    NUM_TYPE_NUM_SHOU,
};
ConsoleApplication/THSActionUtil.cpp
@@ -96,6 +96,21 @@
    return 0;
}
HWND THSActionUtil::getTradeSimpleDelegateWindow()
{
    list<HWND> wlist = Win32Util::searchWindow("同花顺远航版");
    list<HWND>::iterator ele;
    for (ele = wlist.begin(); ele != wlist.end(); ele++) {
        HWND hwnd = *ele;
        hwnd = FindWindowExA(hwnd, NULL, NULL, NULL);
        string name = Win32Util::getWindowName(hwnd);
        if (name.find("网上股票交易系统") != string::npos) {
            return hwnd;
        }
    }
    return 0;
}
HWND THSActionUtil::getTradeSuccessWindow() {
    list<HWND> wlist = Win32Util::searchWindow("网上股票交易系统");
@@ -217,10 +232,16 @@
void THSActionUtil::openSecondScreen() {
    HWND second = getSecondWindow();
    if (second > 0) {
        Win32Util::showWindow(second);
        return;
    }
    list<HWND> wlist = Win32Util::searchWindow("同花顺(");
    bool open = false;
    HWND mainPage = 0;
    HWND mainPage = getMainWin();
    list<HWND>::iterator ele;
    for (ele = wlist.begin();ele != wlist.end();ele++) {
ConsoleApplication/THSActionUtil.h
@@ -61,6 +61,8 @@
    static HWND getTradeDelegateWindow();
    static HWND getTradeSimpleDelegateWindow();
    //检测环境
    static bool checkEnv();
ConsoleApplication/THSGPDataCapture.cpp
ConsoleApplication/TradeListCapture.cpp
@@ -5,12 +5,15 @@
#include "GPUtil.h"
bool TradeListCapture::tradeTimeCapture_success;
bool TradeListCapture::tradeTimeCapture_delegate;
OpenCLExcuter* TradeListCapture::openCLExcuter;
OpenCLExcuter* TradeListCapture::openCLExcuterDelegate;
OpenCLExcuter* TradeListCapture::openCLExcuterSuccess;
bool TradeListCapture::inited;
bool TradeListCapture::kill_d;
bool TradeListCapture::kill_s;
HWND TradeListCapture::trade_delegate_win;
HWND TradeListCapture::trade_success_win;
HWND TradeListCapture::trade_simple_delegate_win;
RecognitionManager* TradeListCapture::recognitionManager;
//是否正在执行
@@ -72,8 +75,8 @@
        if (running_d && inited) {
            clock_t start = clock();
            try {
                list<TradeDelegateData> datas = captureTradeDelegateInfo();
                string money = getAvaiableMoney();
                list<TradeDelegateData> datas = captureSimpleTradeDelegateInfo();
                string money = getSimpleAvaiableMoney();
                cout << "耗时:" << clock() - start << "  数量:" << datas.size() << endl;
                data_callback_delegate(datas, money, context);
                datas.clear();
@@ -81,7 +84,7 @@
            catch (...) {
            }
            Sleep(5);
            Sleep(500);
        }
        else {
            Sleep(2000);
@@ -91,7 +94,7 @@
cv::Mat TradeListCapture::grayImgs(cv::Mat oimg) {
cv::Mat TradeListCapture::grayImgs(cv::Mat oimg, OpenCLExcuter* openCLExcuter) {
    cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);//ImgUtil::grayImage(oimg);
    uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols);
@@ -118,8 +121,11 @@
    running_d = false;
    recognitionManager = new RecognitionManager();
    openCLExcuter = new OpenCLExcuter();
    openCLExcuter->init();
    openCLExcuterDelegate = new OpenCLExcuter();
    openCLExcuterDelegate->init();
    openCLExcuterSuccess = new OpenCLExcuter();
    openCLExcuterSuccess->init();
    thread rt(&(TradeListCapture::_run_s));
    rt.detach();
@@ -138,6 +144,13 @@
    try {
        refreshTradeDelegateHWND();
    }
    catch (...) {
    }
    try {
        refreshTradeSimpleDelegateHWND();
    }
    catch (...) {
@@ -174,6 +187,33 @@
        throw string("未获取到内容窗口句柄");
    trade_delegate_win = content;
}
void TradeListCapture::refreshTradeSimpleDelegateHWND()
{
    HWND hwnd = THSActionUtil::getTradeSimpleDelegateWindow();
    if (hwnd <= 0)
        throw string("同花顺远航版精简交易页面未打开");
    HWND win = FindWindowExA(hwnd, NULL, "AfxMDIFrame140s", NULL);
    HWND child = NULL;
    HWND content = 0;
    for (int i = 0; i < 3; i++) {
        child = FindWindowExA(win, child, "#32770", NULL);
        if (child > 0) {
            HWND table = FindWindowExA(child, NULL, NULL, "HexinScrollWnd");
            if (table > 0) {
                content = table;
                break;
            }
        }
    }
    if (content <= 0)
        throw string("未获取到内容窗口句柄");
    trade_simple_delegate_win = content;
}
@@ -216,7 +256,7 @@
//顺序 代码-成交时间-成交数量-成交均价-成交金额-合同编号-操作
list<TradeSuccessData> TradeListCapture::captureTradeSuccessInfo(cv::Mat oimg) {
    cv::Mat grayImg = grayImgs(oimg);
    cv::Mat grayImg = grayImgs(oimg, openCLExcuterSuccess);
    list<TradeSuccessData> dataList;
    //分隔元素
    int empty_start = -1;
@@ -295,7 +335,7 @@
    int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size());
    openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 6, splitResult);
    openCLExcuterSuccess->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 6, splitResult);
    if (false) {
        //保存分隔结果
@@ -335,7 +375,7 @@
    typesData.length = ele_count_per_line;
    typesData.data = types;
    openCLExcuter->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num);
    openCLExcuterSuccess->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num);
@@ -343,8 +383,8 @@
    //识别数字
    uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count);
    openCLExcuter->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
    uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count);
    openCLExcuterSuccess->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
    uchar** numberResult = openCLExcuterSuccess->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count);
    for (int i = 0;i < rowData.size();i++) {
        TradeSuccessData industryData = TradeSuccessData();
@@ -468,6 +508,14 @@
list<TradeSuccessData> TradeListCapture::captureTradeSuccessInfo() {
    HWND win = THSActionUtil::getTradeSuccessWindow();
    //刷新数据,按F5刷新
    Win32Util::virtualKeyboard(win, VK_F5);
    //HWND toolBar = FindWindowExA(win, NULL, "ToolbarWindow32", NULL);
    //RECT rect;
    //Win32Util::getWindowRect(toolBar, &rect);
    //Win32Util::click(rect.left + 170, rect.top + 5);
    cv::Mat oimg = CaptureUtil::capture(trade_success_win);
    if (oimg.cols < 10 || oimg.rows < 10) {
        throw string("截图出错");
@@ -480,7 +528,7 @@
//顺序:委托时间-代码-委托数量-委托价格-成交均价-成效数量-操作
list<TradeDelegateData> TradeListCapture::captureTradeDelegateInfo(cv::Mat oimg) {
    cv::Mat grayImg = grayImgs(oimg);
    cv::Mat grayImg = grayImgs(oimg, openCLExcuterDelegate);
        list<TradeDelegateData> dataList;
        //分隔元素
@@ -490,7 +538,7 @@
        int data_end = -1;
        list<int*> rowData;
        for (int r = 0;r < grayImg.rows;r++) {
            if (ImgDivider::isRowEmpty(grayImg, r, 0, 50)) {
        if (ImgDivider::isRowEmpty(grayImg, r, 0, 100)) {
                if (empty_start < 0) {
                    empty_start = r;
@@ -560,7 +608,7 @@
        int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size());
        openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 6, splitResult);
    openCLExcuterDelegate->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 6, splitResult);
        if (false) {
            //保存分隔结果
@@ -600,7 +648,7 @@
        typesData.length = ele_count_per_line;
        typesData.data = types;
        openCLExcuter->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num);
    openCLExcuterDelegate->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num);
@@ -608,8 +656,8 @@
        //识别数字
        uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count);
        openCLExcuter->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
        uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count);
    openCLExcuterDelegate->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
    uchar** numberResult = openCLExcuterDelegate->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count);
        for (int i = 0;i < rowData.size();i++) {
            TradeDelegateData delegateData = TradeDelegateData();
@@ -744,6 +792,298 @@
    return codes;
}
list<TradeDelegateData> TradeListCapture::captureSimpleTradeDelegateInfo(cv::Mat img)
{
    cv::Mat grayImg = grayImgs(img, openCLExcuterDelegate);
    list<TradeDelegateData> dataList;
    //分隔元素
    int empty_start = -1;
    int empty_end = -1;
    int data_start = -1;
    int data_end = -1;
    list<int*> rowData;
    for (int r = 0; r < grayImg.rows; r++) {
        if (ImgDivider::isRowEmpty(grayImg, r, 0, 100)) {
            if (empty_start < 0) {
                empty_start = r;
                empty_end = r;
            }
            else {
                empty_end = r;
            }
            if (data_start > -1 && data_end > -1 && data_end - data_start > 5) {
                printf("%d-%d\n", data_start, data_end);
                int* d = (int*)malloc(sizeof(int) * 2);
                d[0] = data_start;
                d[1] = data_end;
                rowData.push_back(d);
                data_start = -1;
                data_end = -1;
            }
        }
        else {
            empty_start = -1;
            empty_end = -1;
            if (data_start < 0) {
                data_start = r;
                data_end = r;
            }
            else {
                data_end = r;
            }
        }
    }
    if (rowData.size() < 2)
    {
        free(grayImg.data);
        grayImg.release();
        for (list<int*>::iterator ele = rowData.begin(); ele != rowData.end(); ele++) {
            free(*ele);
        }
        return dataList;
    }
    //ȥͷȥβ
    list<int*>::iterator start = rowData.begin();
    list<int*>::iterator end = rowData.end();
    int start_end = (*start)[1];
    free(*start);
    rowData.erase(start);
    if (rowData.size() == 1)
    {
        std::advance(end, -1);
        if ((*end)[0] - start_end > 30)
        {
            free(*end);
            rowData.erase(end);
        }
    }
    else {
        std::advance(end, -1);
        free(*end);
        rowData.erase(end);
    }
    int* rowIndex = (int*)malloc(sizeof(int) * rowData.size() * 4);
    int index = 0;
    for (list<int*>::iterator ele = rowData.begin(); ele != rowData.end(); ele++) {
        rowIndex[index * 4 + 0] = 0;
        rowIndex[index * 4 + 1] = (*ele)[0];
        rowIndex[index * 4 + 2] = grayImg.cols - 1;
        rowIndex[index * 4 + 3] = (*ele)[1];
        free(*ele);
        index++;
    }
    int ele_count_per_line = 8;
    int length_per_num = 9;
    int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size());
    openCLExcuterDelegate->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 7, splitResult);
    if (false) {
        //保存分隔结果
        for (int i = 0; i < rowData.size(); i++) {
            int start = i * ele_count_per_line * 4;
            for (int j = 0; j < ele_count_per_line; j++)
            {
                int startx = splitResult[start];
                int starty = splitResult[start + 1];
                int endx = splitResult[start + 2];
                int endy = splitResult[start + 3];
                start += 4;
                string path = "C:\\Users\\Administrator\\Desktop\\ocr\\trade\\";
                path.append(to_string(i)).append("_").append(to_string(j)).append(".jpg");
                cv::imwrite(path, cv::Mat(grayImg, cv::Rect(startx, starty, endx - startx + 1, endy - starty + 1)));
            }
        }
    }
    //分割数字
    unsigned char* zeroData = (unsigned char*)malloc(sizeof(unsigned char) * _NUMBER_L2_WIDTH * _NUMBER_L2_HEIGHT);
    for (int r = 0; r < _NUMBER_L2_HEIGHT; r++) {
        for (int c = 0; c < _NUMBER_L2_WIDTH; c++)
        {
            zeroData[r * _NUMBER_L2_WIDTH + c] = ImgUtil::NUMS_LEVEL2[0].data.ptr<uchar>(r)[c];
        }
    }
    int line_number_count = ele_count_per_line * length_per_num;
    unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count);
    UcharDataInfo typesData = UcharDataInfo();
    //委托时间,证券代码,申报时间,委托数量,委托价格,成交均价,成交数量,操作
    unsigned char types[] = { NUM_TYPE_TIME,NUM_TYPE_CODE,NUM_TYPE_NUM,NUM_TYPE_CODE,NUM_TYPE_PRICE,NUM_TYPE_PRICE,NUM_TYPE_CODE, NUM_TYPE_CODE };
    typesData.length = ele_count_per_line;
    typesData.data = types;
    openCLExcuterDelegate->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num);
    //识别数字
    uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count);
    openCLExcuterDelegate->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
    uchar** numberResult = openCLExcuterDelegate->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count);
    for (int i = 0; i < rowData.size(); i++) {
        TradeDelegateData delegateData = TradeDelegateData();
        //时间
        string time = "";
        for (int j = length_per_num - 6; j < length_per_num; j++)
        {
            if (j - (length_per_num - 6) == 2 || j - (length_per_num - 6) == 4)
                time.append(":");
            time.append(to_string(numberResult[i][length_per_num * 0 + j]));
        }
        //代码
        string code = "";
        for (int j = length_per_num - 6; j < length_per_num; j++)
        {
            code.append(to_string(numberResult[i][length_per_num * 1 + j]));
        }
        // 申报时间
        string apply_time = "";
        for (int j = length_per_num - 9; j < length_per_num; j++)
        {
            apply_time.append(to_string(numberResult[i][length_per_num * 2 + j]));
        }
        //委托数量
        string num = "";
        for (int j = 0; j < length_per_num; j++)
        {
            num.append(to_string(numberResult[i][length_per_num * 3 + j]));
        }
        num = to_string(stoi(num));
        //委托价格
        string delegate_price = "";
        for (int j = 0; j < length_per_num; j++)
        {
            if (length_per_num - j == 3)
                delegate_price.append(".");
            delegate_price.append(to_string(numberResult[i][length_per_num * 4 + j]));
        }
        delegate_price = to_string(stod(delegate_price));
        char* chCode;
        chCode = new char[20];
        sprintf_s(chCode, delegate_price.length(), "%.3lf", stod(delegate_price));
        std::string delegate_price_str(chCode);
        delegate_price = delegate_price_str;
        //成交均价
        string percent_price = "";
        for (int j = 0; j < length_per_num; j++)
        {
            if (length_per_num - j == 3)
                percent_price.append(".");
            percent_price.append(to_string(numberResult[i][length_per_num * 5 + j]));
        }
        chCode = new char[20];
        sprintf_s(chCode, percent_price.length(), "%.3lf", stod(percent_price));
        std::string percent_price_str(chCode);
        percent_price = percent_price_str;
        //成交数量
        string success_num = "";
        for (int j = 0; j < length_per_num; j++)
        {
            success_num.append(to_string(numberResult[i][length_per_num * 6 + j]));
        }
        success_num = to_string(stoi(success_num));
        //买入卖出
        int start = i * 4 * ele_count_per_line + 7 * 4;
        int startx = splitResult[start];
        int starty = splitResult[start + 1];
        int endx = splitResult[start + 2];
        int endy = splitResult[start + 3];
        int count = 0;
        for (int r = starty; r <= endy; r++) {
            for (int c = startx; c <= endx; c++) {
                uchar v = grayImg.ptr<uchar>(r)[c];
                if (v >= _IMG_BINARY_THRESHOLD) {
                    count++;
                }
            }
        }
        if (count > 50) {
            //卖出
            delegateData.type = TRADE_TYPE_SELL;
        }
        else {
            //买入
            delegateData.type = TRADE_TYPE_BUY;
        }
        delegateData.index = i;
        delegateData.code = code;
        delegateData.time = time;
        delegateData.apply_time = apply_time;
        delegateData.num = num;
        delegateData.price = delegate_price;
        delegateData.trade_price = percent_price;
        delegateData.trade_num = success_num;
        dataList.push_back(delegateData);
        free(numberResult[i]);
    }
    free(totalNumberData);
    free(numberResult);
    free(rowIndex);
    free(splitResult);
    free(zeroData);
    free(templateNums);
    free(grayImg.data);
    grayImg.release();
    return dataList;
}
list<TradeDelegateData> TradeListCapture::captureSimpleTradeDelegateInfo()
{
    HWND win = THSActionUtil::getTradeSimpleDelegateWindow();
    //刷新数据,按F5刷新
    Win32Util::virtualKeyboard(win, VK_F5);
    cv::Mat oimg = CaptureUtil::capture(trade_simple_delegate_win);
    if (oimg.cols < 10 || oimg.rows < 10) {
        throw string("截图出错");
    }
    list<TradeDelegateData> codes = captureSimpleTradeDelegateInfo(oimg);
    return codes;
}
string TradeListCapture::getAvaiableMoney()
{
    HWND hwnd = THSActionUtil::getTradeDelegateWindow();
@@ -772,6 +1112,34 @@
    return text;
}
string TradeListCapture::getSimpleAvaiableMoney()
{
    HWND hwnd = THSActionUtil::getTradeSimpleDelegateWindow();
    if (hwnd <= 0) {
        throw    string("委托窗口未打开");
    }
    HWND win = FindWindowExA(hwnd, NULL, "AfxMDIFrame140s", NULL);
    HWND child = NULL;
    HWND avaiableMoneyHWND = 0;
    for (int i = 0; i < 5; i++) {
        child = FindWindowExA(win, child, "#32770", NULL);
        if (child > 0 && Win32Util::isWindowShow(child)) {
            HWND table = FindWindowExA(child, NULL, NULL, "HexinScrollWnd");
            if (table > 0) {
                child = FindWindowExA(child, NULL, "#32770", NULL);
                avaiableMoneyHWND = GetDlgItem(child, 0x000003F8);
                break;
            }
        }
    }
    if (avaiableMoneyHWND <= 0) {
        throw    string("未查找到可用余额控件");
    }
    string text = Win32Util::getWindowName(avaiableMoneyHWND);
    return text;
}
bool TradeListCapture::isInited() {
    return inited;
}
ConsoleApplication/TradeListCapture.h
@@ -33,6 +33,7 @@
{
    string code;
    string time;
    string apply_time;//申报时间
    string num;
    string price;
    string trade_price;
@@ -53,7 +54,8 @@
    //交易时段识别
    static bool tradeTimeCapture_success;
    static bool tradeTimeCapture_delegate;
    static OpenCLExcuter* openCLExcuter;
    static OpenCLExcuter* openCLExcuterDelegate;
    static OpenCLExcuter* openCLExcuterSuccess;
    static RecognitionManager* recognitionManager;
    static bool inited;
@@ -72,6 +74,8 @@
    static HWND trade_delegate_win;
    //成功窗体
    static HWND trade_success_win;
    //精简版委托窗体
    static HWND trade_simple_delegate_win;
    
@@ -93,8 +97,9 @@
    void reCreateTradeDelegateRunning();
    void refreshTradeDelegateHWND();
    void refreshTradeSimpleDelegateHWND();
    void refreshTradeSuccessHWND();
    static cv::Mat grayImgs(cv::Mat img);
    static cv::Mat grayImgs(cv::Mat img,OpenCLExcuter* openCLExcuter);
    //交易成功
    static list<TradeSuccessData> captureTradeSuccessInfo(cv::Mat img);
@@ -102,13 +107,20 @@
    static list<TradeSuccessData> captureTradeSuccessInfo();
    //交易委托
    //专业版交易委托
    static list<TradeDelegateData> captureTradeDelegateInfo(cv::Mat img);
    static list<TradeDelegateData> captureTradeDelegateInfo();
    //精简版交易委托
    static list<TradeDelegateData> captureSimpleTradeDelegateInfo(cv::Mat img);
    static list<TradeDelegateData> captureSimpleTradeDelegateInfo();
    //获取账户的剩余资金
    static string getAvaiableMoney();
    // 获取精简版的可用余额
    static string getSimpleAvaiableMoney();
    
    bool isInited();
ConsoleApplication/TradeQueueCapture.cpp
@@ -149,6 +149,8 @@
    openCLExcuter->splitTradeQueueNum(img, IntDataInfo({ splitResult,(int)(ele_count * 1) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_TRADE_QUEUE_WIDTH, _NUMBER_TRADE_QUEUE_HEIGHT, ele_count, length_per_num);
    free(splitResult);
    uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_TRADE_QUEUE_HEIGHT * 1) * _NUMBER_TRADE_QUEUE_WIDTH * 10 * line_number_count);
ConsoleApplication/TradeQueueCaptureManager.cpp
@@ -41,9 +41,9 @@
        catch (string st) {
            cout << index<<":"<< st << endl;
        }
        //catch (...) {
        //    cout << index << ":" << "未知异常" << endl;
        //}
        catch (...) {
            cout << index << ":" << "未知异常" << endl;
        }
    }
}
ConsoleApplication/Win32Util.cpp
@@ -138,6 +138,12 @@
    runner.join();
}
void Win32Util::virtualKeyboard(HWND hwnd,int code)
{
    PostMessage(hwnd, WM_KEYDOWN, code, 0);
    PostMessage(hwnd, WM_KEYUP, code, 0);
}
void Win32Util::keyboardPaste()
{
    keybd_event(VK_CONTROL, 0, 0, 0);    // 按下CTRL键
@@ -290,5 +296,10 @@
    return st;
}
void Win32Util::sendMessage(HWND hwnd, UINT  msg, LPARAM p0, LPARAM p1)
{
    SendMessage(hwnd, msg, p0, p1);
}
ConsoleApplication/Win32Util.h
@@ -36,6 +36,9 @@
    //键盘输入其他键
    static void keyboard(int code, int delay=0);
    //虚拟键入
    static void virtualKeyboard(HWND hwnd, int code);
    //键盘键入粘贴
    static void keyboardPaste();
@@ -64,5 +67,7 @@
    //获取现在的时间
    static string getNowTime();
    static void sendMessage(HWND hwnd, UINT  msg, LPARAM p0, LPARAM p1);
};
ConsoleApplication/kernel.cl
@@ -615,6 +615,92 @@
    }
    //手数,带有单位手
    else if (type == 6) {
        //分隔手
        int num_end = endx;
        int emptyIndex=-1;
        int i;
        for (i = endx; i >= startx; i--) {
            bool empty = 1;
            for (int y = starty; y < endy; y++) {
                if (get_binary_value(img_in[get_one_level_position(width, i, y)]) > 0) {
                    empty = 0;
                    break;
                }
            }
            if (empty) {
                emptyIndex = i;
            }
            else if (emptyIndex > 0) {
                num_end = i;
                break;
            }
        }
        endx = num_end;
        //去除上下空白
        int startNy = -1;
        int endNy = -1;
        int y;
        for (y = starty; y <= endy; y++) {
            bool empty = 1;
            for (int x = startx; x <= endx; x++)
            {
                int p = get_one_level_position(width, x, y);
                unsigned char value = get_binary_value(img_in[p]);
                //有数据
                if (value > 0) {
                    empty = 0;
                    break;
                }
            }
            if (!empty) {
                startNy = y;
                break;
            }
        }
        for (y = endy; y >= starty; y--) {
            bool empty = 1;
            for (int x = startx; x <= endx; x++)
            {
                int p = get_one_level_position(width, x, y);
                unsigned char value = get_binary_value(img_in[p]);
                //有数据
                if (value > 0) {
                    empty = 0;
                    break;
                }
            }
            if (!empty) {
                endNy = y;
                break;
            }
        }
        if (endNy > 0)
        {
            endy = endNy;
        }
        if (startNy > 0)
        {
            starty = startNy;
        }
        nps[0] = startx;
        nps[1] = starty;
        nps[2] = endx;
        nps[3] = endy;
        nps[4] = -1;
        nps[5] = -1;
        nps[6] = -1;
        nps[7] = -1;
        nps[8] = -1;
        nps[9] = -1;
        nps[10] = -1;
        nps[11] = -1;
    }
    //分隔数据
ConsoleApplication/main.cpp
@@ -13,6 +13,7 @@
#include <log4cpp/PatternLayout.hh>
#include "TradeQueueCaptureManager.h"
#include "LogUtil.h"
#include "L2TradeQueueUtil.h"
using namespace log4cpp;
void gray();
@@ -140,33 +141,113 @@
    ImgUtil::init();
    OpenCLExcuter* openCLExcuter = new OpenCLExcuter();
    openCLExcuter->init();
    L2DataCapture* l2DataCapture = new L2DataCapture();
    try {
        ;
        // l2DataCapture->init(NULL, NULL, NULL);
    cv::Mat img = cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\order_origin.jpg");
    uchar* datas = (uchar*)malloc(sizeof(uchar) * img.rows * img.cols);
    if (img.channels() == 4)
    {
        openCLExcuter->rgba2Gray(img, datas);
    }
    catch (...) {
    else {
        openCLExcuter->rgb2Gray(img,datas);
    }
    
    }
    cv::Mat mat;
void grayImg() {
    ImgUtil::init();
    OpenCLExcuter* openCLExcuter = new OpenCLExcuter();
    openCLExcuter->init();
    cv::Mat img = cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\l2_trade_queue_2.png");
    uchar* datas = (uchar*)malloc(sizeof(uchar) * img.rows * img.cols);
    if (img.channels() == 4)
    {
        openCLExcuter->rgba2Gray(img, datas);
    }
    else {
        openCLExcuter->rgb2Gray(img, datas);
    }
    cv::Mat img1 = cv::Mat::zeros(img.rows, img.cols, CV_8UC1);
    img1.data = datas;
    cv::Mat binary;
    threshold(img1, binary, 96, 255, cv::THRESH_BINARY);
    cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\l2_trade_queue_gray.png", img1);
}
void testSplit() {
    ImgUtil::init();
    L2TradeQueueUtil::splitElements(cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\l2_trade_queue_2.png", cv::IMREAD_GRAYSCALE));
}
void testCaptureL2Trade() {
    ImgUtil::init();
    OpenCLExcuter* openCLExcuter = new OpenCLExcuter();
    openCLExcuter->init();
    L2DataCapture *capture = new L2DataCapture();
    HWND win = THSActionUtil::getL2Win();
    CaptureUtil::init(win);
    while (TRUE)
    {
        //cv::Mat img = cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\l2_trade_queue_2_2.png");
        cv::Mat img = CaptureUtil::capture(0, CAPTURE_TYPE_TRADE_QUEUE);
        L2TradeQueue tradeQueue = capture->captureLevel2TradeQueueData(openCLExcuter, img, 0);
        printf("\n");
        Sleep(10);
    }
}
void testCaptureL2TradeQueue() {
    ImgUtil::init();
    L2DataCapture* capture = new L2DataCapture();
    capture->init(NULL,NULL,NULL);
    capture->setGPCode(0,"000610");
    capture->startAll();
    while (TRUE) {
        Sleep(1000);
    }
}
void testDelegate() {
    ImgUtil::init();
    TradeListCapture* capture = new TradeListCapture();
    capture->init(NULL,NULL,NULL);
    cv::Mat oimg = cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\trade\\Snipaste_2022-12-23_09-42-19.png");
    capture->captureSimpleTradeDelegateInfo(oimg);
}
void testTradeSuccess() {
    ImgUtil::init();
    TradeListCapture* capture = new TradeListCapture();
    capture->init(NULL, NULL, NULL);
    capture->captureTradeSuccessInfo(cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\trade\\Snipaste_2022-12-23_09-39-02.png"));
}
int main() {
    //grayImg();
    testTradeSuccess();
    return 1;
    //testL2();
    //if (TRUE) {
    //    return 0;
    //}
    if (TRUE) {
        return 0;
    }
    //Win32Util::moveWin(HWND(0x000508D8), 0, 0, 1920, 1080);
    //return 0;
    cout << "开始程序" << endl;
    ImgUtil::init();
    THSActionUtil::updateMainSite();
    TradeQueueCaptureManager *manager = new TradeQueueCaptureManager();
    manager->init(NULL, NULL);
    manager->start();
    TradeListCapture *manager = new TradeListCapture();
    manager->init(NULL, NULL,NULL);
    for (int i = 0; i < 10; i++)
    {
        manager->captureTradeSuccessInfo();
        Sleep(2000);
    }
    //TradeQueueCapture* manager = new TradeQueueCapture();
    //manager->recognition_buy_1_volumn(HWND(0x00020F28));
app/JsonUtil.h
@@ -72,18 +72,19 @@
    }
    static  std::string loadTradeQueueData(int clientID, int channel, string code, std::list<int> numList) {
    static  std::string loadTradeQueueData(int clientID, int channel, string code, L2TradeQueue tradeQueue) {
        Json::Value data;
        data["channel"] = channel;
        data["code"] = code;
        Json::Value _data;
        _data["buyOnePrice"] = tradeQueue.buyOnePrice;
        _data["buyOneVolumn"] = tradeQueue.buyOneVolumn;
        _data["buyTime"] = tradeQueue.buyTime;
        _data["sellOnePrice"] = tradeQueue.sellOnePrice;
        _data["sellOneVolumn"] = tradeQueue.sellOneVolumn;
        _data["sellTime"] = tradeQueue.sellTime;
        std::list<int>::iterator ele;
        int index = 0;
        for (ele = numList.begin();ele != numList.end();ele++) {
            _data[index++] = *ele;
        }
        data["data"] = _data;
        Json::Value root;
        root["type"] = 10;
@@ -160,6 +161,7 @@
            Json::Value  item;
            item["code"] = (*ele).code;
            item["time"] = (*ele).time;
            item["apply_time"] = (*ele).apply_time;
            item["num"] = (*ele).num;
            item["type"] = (*ele).type;
            item["price"] = (*ele).price;
@@ -223,7 +225,7 @@
    }
    static  std::string loadGPCodeData(std::list<IndustryData> codeList) {
    static  std::string loadGPCodeData(std::list<IndustryData> codeList,bool add) {
        Json::Value root;
        root["type"] = 1;
        Json::Value data;
@@ -238,6 +240,7 @@
            data[index++] = item;
        }
        root["data"] = data;
        root["add"] = add;
        return toJsonStr(root);
    }
@@ -292,6 +295,17 @@
        return toJsonStr(root);
    }
    // 自动启动L2成功
    static  std::string loadAutoStartL2(int client) {
        Json::Value root;
        root["type"] = 60;
        Json::Value data;
        data["client"] = client;
        root["data"] = data;
        return toJsonStr(root);
    }
    static std::string toJson(ClientEnvState state) {
        Json::Value root;
        root["ths_l2_win"] = state.ths_l2_win;
app/SocketManager.cpp
@@ -1,6 +1,6 @@
#include "pch.h"
#include "SocketManager.h"
#define CHANNEL_NUM 9
#define CHANNEL_NUM 8*2+1
#include <thread>
#include <string>
@@ -187,19 +187,19 @@
}
BOOL SocketManager::sendMsg(int p, const char* msg) {
string SocketManager::sendMsg(int p, const char* msg) {
    SOCKET socket = getClient(p);
    char buffer[64];
    char buffer[10240];
    int result = send(socket, msg, strlen(msg), 0);
    if (result < 0) {
        throw string("发送失败");
    }
    int num = recv(socket, buffer, 64, 0);
    int num = recv(socket, buffer, 10240, 0);
    if (num < 0) {
        throw string("未接收到信息");
    }
    return 1;
    return string(buffer);
}
app/SocketManager.h
@@ -56,7 +56,7 @@
    void disConnect();
    int disConnect(int p);
    BOOL sendMsg(int, const char *);
    string sendMsg(int, const char *);
    static string sendMsg(const char*);
app/app.aps
Binary files differ
app/app.rc
Binary files differ
app/app.vcxproj.user
@@ -5,9 +5,9 @@
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>
    <RemoteDebuggerCommand>\\192.168.3.241\FXDMounter\Debug\DataCapture.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>\\192.168.3.241\FXDMounter\</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>192.168.3.241</RemoteDebuggerServerName>
    <RemoteDebuggerCommand>\\192.168.3.242\FXDMounter\Debug\DataCapture.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>\\192.168.3.242\FXDMounter\</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>192.168.3.242</RemoteDebuggerServerName>
    <RemoteDebuggerConnection>RemoteWithoutAuthentication</RemoteDebuggerConnection>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
app/appDlg.cpp
@@ -142,11 +142,11 @@
    DDX_Control(pDX, IDC_CHECK_TRADE_TIME_TRADE_SUCCESS, tradeSuccessTimeCheck);
    DDX_Control(pDX, IDC_CHECK_TRADE_TIME_DELEGATE, delegateTimeCheck);
    DDX_Control(pDX, IDC_CHECK_TRADE_TIME_LIMIT_UP, limitUpTimeCheck);
    DDX_Control(pDX, IDC_BUTTON_UPLOAD_EXCEL_CODE, uploadExcelGPBtn);
    DDX_Control(pDX, IDC_CHECK_BUY1_VOLUMN_TIME_LIMIT, buy1VolumnTimeLimitCheck);
    DDX_Control(pDX, IDC_BUTTON_BUY_1_VOLUMN, buy1VolumnBtn);
    DDX_Control(pDX, IDC_CHECK_ONLINE, onlineCheck);
    DDX_Control(pDX, IDC_BUTTON_UPLOAD_GPCODE, uploadGPCodeBtn);
    DDX_Control(pDX, IDC_BUTTON_GP_CODE_ADD, addGPCodeBtn);
}
BEGIN_MESSAGE_MAP(CappDlg, CDialogEx)
@@ -177,9 +177,10 @@
    ON_BN_CLICKED(IDC_CHECK_TRADE_TIME_TRADE_SUCCESS, &CappDlg::OnBnClickedCheckTradeTimeTradeSuccess)
    ON_BN_CLICKED(IDC_CHECK_TRADE_TIME_DELEGATE, &CappDlg::OnBnClickedCheckTradeTimeDelegate)
    ON_BN_CLICKED(IDC_CHECK_PRICE_TIME_LIMIT, &CappDlg::OnBnClickedCheckPriceTimeLimit)
    ON_BN_CLICKED(IDC_BUTTON_UPLOAD_EXCEL_CODE, &CappDlg::OnBnClickedButtonUploadExcelCode)
    ON_BN_CLICKED(IDC_BUTTON_BUY_1_VOLUMN, &CappDlg::OnBnClickedButtonBuy1Volumn)
    ON_BN_CLICKED(IDC_BUTTON_UPLOAD_GPCODE, &CappDlg::OnBnClickedButtonUploadGpcode)
    ON_BN_CLICKED(IDC_CHECK_BUY1_VOLUMN_TIME_LIMIT, &CappDlg::OnBnClickedCheckBuy1VolumnTimeLimit)
    ON_BN_CLICKED(IDC_BUTTON_GP_CODE_ADD, &CappDlg::OnBnClickedButtonGpCodeAdd)
END_MESSAGE_MAP()
@@ -231,16 +232,34 @@
    delegateTimeCheck.SetCheck(TRUE);
    TradeListCapture::setTradeTimeCapture_delegate(delegateTimeCheck.GetCheck());
    priceTimeLimitCheck.SetCheck(TRUE);
    CurrentPriceCapture::setTradeTimeCapture(TRUE);
    buy1VolumnTimeLimitCheck.SetCheck(TRUE);
    TradeQueueCaptureManager::setTradeTimeCapture(priceTimeLimitCheck.GetCheck());
    TradeQueueCaptureManager::setTradeTimeCapture(buy1VolumnTimeLimitCheck.GetCheck());
    onlineCheck.SetCheck(TRUE);
    //是否自动开启功能
    bool autoOpen = FALSE;
    list<string> settings = Tool::getSettings("setting.txt");
    if (settings.size() > 0) {
        string c = *(settings.begin());
        if (c == "1") {
            autoOpen = TRUE;
        }
        else {
            autoMsgStatic.SetWindowTextW(_T(""));
            autoL2Check.SetCheck(FALSE);
        }
    }
    if (autoOpen) {
        autoL2Check.SetCheck(TRUE);
    }
    if (authoritySet.count(AUTHORITY_L2) > 0) {
        onlineCheck.SetCheck(FALSE);
@@ -248,19 +267,10 @@
        resetTHSBtn.EnableWindow(TRUE);
        refreshHWNDBtn.EnableWindow(TRUE);
        onlineCheck.EnableWindow(TRUE);
        list<string> settings = Tool::getSettings("setting.txt");
        if (settings.size() > 0) {
            string c = *(settings.begin());
            if (c == "1") {
        if (autoOpen) {
                autoMsgStatic.SetWindowTextW(_T("正在自动启动中..."));
                autoL2Check.SetCheck(TRUE);
                thread rt(&(CappDlg::autoStartL2), this);
                rt.detach();
            }
            else {
                autoMsgStatic.SetWindowTextW(_T(""));
                autoL2Check.SetCheck(FALSE);
            }
        }
    }
    else {
@@ -272,6 +282,26 @@
    if (authoritySet.count(AUTHORITY_LIMIT_UP) > 0) {
        limitUpBtn.EnableWindow(TRUE);
        //自动开启涨停
        if (autoOpen) {
            //等待同花顺主屏是否打开
            autoMsgStatic.SetWindowTextW(_T("正在等待THS主屏启动..."));
            for (int i = 0; i < 10; i++) {
                HWND hwnd = THSActionUtil::getMainWin();
                Sleep(1000);
                if (hwnd > 0) {
                    break;
                }
            }
            autoMsgStatic.SetWindowTextW(_T("等待打开副屏1..."));
            THSActionUtil::openSecondScreen();
            autoMsgStatic.SetWindowTextW(_T("副屏1已打开..."));
            Sleep(1000);
            // 开启 涨停识别
            autoMsgStatic.SetWindowTextW(_T("启动涨停识别中..."));
            CappDlg::OnBnClickedButton12();
            autoMsgStatic.SetWindowTextW(_T("启动涨停启动成功"));
        }
    }
    else {
        limitUpBtn.EnableWindow(FALSE);
@@ -279,6 +309,33 @@
    if (authoritySet.count(AUTHORITY_TRADE_SUCCESS) > 0) {
        tradeBtn.EnableWindow(TRUE);
        if (autoOpen) {
            //自动打开交易成功页面成功
            HWND hwnd = THSActionUtil::getTradeSuccessWindow();
            if (hwnd <= 0) {
                //打开交易成功页面,在主屏上按F12
                HWND mainWin = THSActionUtil::getMainWin();
                if (mainWin > 0) {
                    Win32Util::sendMessage(mainWin, WM_KEYDOWN, VK_F12, 0);
                    Win32Util::sendMessage(mainWin, WM_KEYUP, VK_F12, 0);
                    //等待页面打开
                    for (int i = 0; i < 10; i++) {
                        hwnd = THSActionUtil::getTradeSuccessWindow();
                        Sleep(1000);
                        if (hwnd > 0) {
                            break;
                        }
                    }
                }
            }
            if (hwnd > 0) {
                //交易页面打开
                THSActionUtil::openTradeSuccessScreen();
                //启动交易成功识别
                OnBnClickedButtonTrade();
            }
        }
    }
    else {
        tradeBtn.EnableWindow(FALSE);
@@ -288,6 +345,12 @@
    if (authoritySet.count(AUTHORITY_TRADE_DELEGATE) > 0) {
        delegateBtn.EnableWindow(TRUE);
        currentPriceBtn.EnableWindow(TRUE);
        if (autoOpen) {
            thread rt1(&(CappDlg::autoStartTradeDelegate), this);
            rt1.detach();
            thread rt2(&(CappDlg::autoStartCurrentPrice), this);
            rt2.detach();
        }
    }
    else {
        delegateBtn.EnableWindow(FALSE);
@@ -305,18 +368,22 @@
    if (authoritySet.count(AUTHORITY_UPLOAD_CODE) > 0) {
        uploadGPBtn.EnableWindow(FALSE);
        uploadExcelGPBtn.EnableWindow(FALSE);
        addGPCodeBtn.EnableWindow(TRUE);
        uploadGPCodeBtn.EnableWindow(TRUE);
    }
    else {
        uploadGPBtn.EnableWindow(FALSE);
        uploadExcelGPBtn.EnableWindow(FALSE);
        addGPCodeBtn.EnableWindow(FALSE);
        uploadGPCodeBtn.EnableWindow(FALSE);
    }
    if (authoritySet.count(AUTHORITY_TRADE_QUEUE) > 0) {
        buy1VolumnBtn.EnableWindow(TRUE);
        if (autoOpen) {
            thread rt3(&(CappDlg::autoStartBuy1Volumn), this);
            rt3.detach();
        }
    }
    else {
        buy1VolumnBtn.EnableWindow(FALSE);
@@ -351,8 +418,13 @@
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
        // 关闭按钮退出应用
        if (nID == 61536) {
            exit(0);
    }
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
@@ -383,10 +455,6 @@
    }
}
void CappDlg::OnClose() {
    MessageBox(_T("内容"), _T("标题"), MB_OKCANCEL);
    CDialogEx::OnClose();
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
@@ -417,22 +485,22 @@
    }
}
void  CappDlg::OnTradeQueueDataCallback(int index, string code, list<int> numList, void* context) {
void  CappDlg::OnTradeQueueDataCallback(int index, string code, L2TradeQueue tradeQueue, void* context) {
    //转为json
    CappDlg* app = (CappDlg*)context;
    //cout << "回调:" << std::this_thread::get_id() << ":" << index << endl;
    CButton* btn = (CButton*)app->GetDlgItem(IDC_CHECK1);
    bool check = btn->GetCheck();
    if (check) {
        string data = JsonUtil::loadTradeQueueData(app->clientNum, index, code, numList);
        string data = JsonUtil::loadTradeQueueData(app->clientNum, index, code, tradeQueue);
        clock_t time_start = clock();
        try {
            app->socketManager->sendMsg(index, data.c_str());
            app->socketManager->sendMsg(index + 9, data.c_str());
        }
        catch (string st) {
            //重新连接服务器
            app->socketManager->resetClient(index);
            app->socketManager->Connect(index);
            app->socketManager->resetClient(index + 9);
            app->socketManager->Connect(index + 9);
        }
        //cout << "*****数据处理时间:" << (clock() - time_start) << endl;
    }
@@ -493,7 +561,6 @@
    if (check) {
        string data = JsonUtil::loadTradeDelegateData(dataList);
        clock_t time_start = clock();
        try {
            app->socketManager->sendMsg(8, data.c_str());
@@ -585,13 +652,15 @@
    if (! app->onlineCheck) {
        return "未知错误";
    }
    if (!app->onlineCheck.GetCheck())
    {
        throw string("客户端离线");
    }
    cout << "action回调:" << std::this_thread::get_id() << ":" << data << endl;
    //解析命令
    Json::Value root = JsonUtil::parseJson(data);
    bool forceAction = root["force"].asBool();
    if (!app->onlineCheck.GetCheck() && !forceAction)
    {
        throw string("客户端离线");
    }
    string action = root["action"].asString();
    if (action == "setGPCode") {
        //设置股票代码
@@ -651,6 +720,106 @@
        //恢复涨停识别
        LimitUpCapture::pause = FALSE;
    }
    else if (action == "betchSetGPCodes") {
        //批量设置代码
        int len = root["data"].size();
        for (int i = 0; i < len; i++) {
            int index = root["data"][i]["index"].asInt();
            string code = root["data"][i]["code"].asString();
            string quickCode = "5";
            quickCode.append(to_string(index + 1));
            list<string> codeList;
            if (code.length() > 0)
            {
                codeList.push_back(code);
            }
            try {
                if (!app->capture->isInited()) {
                    app->initCapture(false);
                }
                //暂停采集
                app->capture->stop(index);
                //暂停涨停识别
                LimitUpCapture::pause = TRUE;
                //打开Level2监控屏幕
                THSActionUtil::openL2Screen();
                bool result = THSActionUtil::setGP(quickCode, codeList, recognitionManager);
                if (!result) {
                    throw string("设置版块监控的GP失败");
                }
            }
            catch (string e) {
                throw e;
            }
            catch (...) {
                throw string("未知错误(unknown error)");
            }
        }
        //map<int, string> results = THSActionUtil::getListenL2GPCodes(recognitionManager);
        //设置代码
        //for (map<int, string>::iterator ele = results.begin(); ele != results.end(); ele++) {
        //    int key = (*ele).first;
        //    string value = (*ele).second;
        //    app->capture->setGPCode(key, value);
        //    cout << "代码位:" << key << " CODE:" << value;
        //}
        for (int i = 0; i < len; i++) {
            try {
                int index = root["data"][i]["index"].asInt();
                string code = root["data"][i]["code"].asString();
                app->capture->setGPCode(index, code);
                cout << "代码位:" << index << " CODE:" << code;
            }
            catch (...) {
            }
            Sleep(100);
        }
        for (int i = 0; i < len; i++) {
            try {
                int index = root["data"][i]["index"].asInt();
                string code = root["data"][i]["code"].asString();
                //刷新L2数据
                THSActionUtil::setListenL2GP(index, code, recognitionManager);
                //打开Level2监控屏幕
                THSActionUtil::openL2Screen();
            }
            catch (...) {
            }
            Sleep(100);
        }
        //恢复识别
        for (int i = 0; i < len; i++) {
            int index = root["data"][i]["index"].asInt();
            app->capture->start(index);
        }
        //恢复涨停识别
        LimitUpCapture::pause = FALSE;
        //可以接受命令
        //app->onlineCheck.SetCheck(TRUE);
        //app->onlineCheck.PostMessage(WM_LBUTTONDOWN, 0, 0);
        //app->onlineCheck.PostMessage(WM_LBUTTONUP, 0, 0);
        RECT rect;
        Win32Util::getWindowRect(app->onlineCheck.m_hWnd, &rect);
        Win32Util::click((rect.left + rect.right )/ 2, (rect.top + rect.bottom) / 2, 10);
    }
    else if (action == "repairL2Data") {
        //修正代码与L2行情代码不对应 或者 L2行情无数据的情况
        cout << "修复L2数据" << endl;
@@ -668,6 +837,9 @@
        }
        catch (string st) {
            throw st;
        }
        catch (...) {
            throw string("未知错误");
        }
    }
@@ -817,6 +989,9 @@
        catch (string st) {
            throw st;
        }
        catch (...) {
            throw string("未知错误");
        }
    }
    return "";
@@ -840,6 +1015,11 @@
        root["msg"] = "未知错误";
    }
    return  JsonUtil::jsonValue2String(root);
}
string CappDlg::OnActionCallbackQueue(string data, void* context)
{
    return string();
}
//心跳信号
@@ -1046,10 +1226,56 @@
    //app->OnBnClickedButtonTrade();
    //启动涨停识别
    //OnBnClickedButton12();
    //发送自动化开始成功
    string data = JsonUtil::loadAutoStartL2(clientNum);
    clock_t time_start = clock();
    try {
        string result_msg = app->socketManager->sendMsg(8, data.c_str());
        Json::Value v_ = JsonUtil::parseJson(result_msg);
        if (v_["code"] == 0) {
            //判断是否需要自动开启在线
    //可以接受命令
    app->onlineCheck.SetCheck(TRUE);
}
        else {
            //不可以接受命令
            app->onlineCheck.SetCheck(FALSE);
        }
    }
    catch (string st) {
        //重新连接服务器
        app->socketManager->resetClient(8);
        app->socketManager->Connect(8);
    }
}
void CappDlg::autoStartTradeDelegate(void* context)
{
    CappDlg* app = (CappDlg*)context;
    app->autoMsgStatic.SetWindowTextW(_T("开始委托识别..."));
    app->OnBnClickedButtonTradeDelegate();
    app->autoMsgStatic.SetWindowTextW(_T("委托识别启动成功"));
}
void CappDlg::autoStartCurrentPrice(void* context)
{
    CappDlg* app = (CappDlg*)context;
    app->autoMsgStatic.SetWindowTextW(_T("开始现价识别..."));
    app->OnBnClickedCurrentPrice();
    app->autoMsgStatic.SetWindowTextW(_T("现价识别启动成功"));
}
void CappDlg::autoStartBuy1Volumn(void* context)
{
    CappDlg* app = (CappDlg*)context;
    app->autoMsgStatic.SetWindowTextW(_T("开始买1识别..."));
    app->OnBnClickedButtonBuy1Volumn();
    app->autoMsgStatic.SetWindowTextW(_T("买1识别启动成功"));
}
@@ -1099,9 +1325,9 @@
    for (int i = 0; i < num; i++)
    {
        try {
            if (socketManager->sendMsg(i, "test")) {
            socketManager->sendMsg(i, "test");
                scount++;
            }
        }
        catch (string st) {
@@ -1129,9 +1355,9 @@
    int num = socketManager->getClientsNum();
    for (int i = 0; i < num; i++)
    {
        if (socketManager->sendMsg(i, "test")) {
        socketManager->sendMsg(i, "test");
            scount++;
        }
    }
@@ -1402,51 +1628,6 @@
    dlg.DoModal();
}
// Excel上传股票代码
void CappDlg::OnBnClickedButtonUploadExcelCode()
{
    CString cpath = GUITool::selectExcel();
    std:string path = Tool::cstring2String(cpath);
    if (path.length() > 0)
    {
        std::list<IndustryData> fresult;
        list<ExcelGPCodeInfo> codesList =    ExcelUtil::readGPCodes(path);
        list<ExcelGPCodeInfo>::iterator ele;
        for (ele = codesList.begin();ele != codesList.end();++ele) {
            ExcelGPCodeInfo info= *ele;
            IndustryData finfo;
            if (info.code.length()>0)
            {
                finfo.code = info.code.replace(0, 2, "");
                if (info.zyltgb.find("亿",0) > 0) {
                    finfo.zyltMoneyUnit = MONEY_UNIT_Y;
                    string zyltgb = info.zyltgb;
                    finfo.zyltMoney = zyltgb.substr(0, zyltgb.length()-2);
                }
                else if (info.zyltgb.find("万",0) > 0) {
                    finfo.zyltMoneyUnit = MONEY_UNIT_W;
                    string zyltgb = info.zyltgb;
                    finfo.zyltMoney = zyltgb.substr(0, zyltgb.length() - 2);
                }
                else {
                    finfo.zyltMoneyUnit = MONEY_UNIT_NO;
                    finfo.zyltMoney = info.zyltgb;
                }
                fresult.push_back(finfo);
            }
        }
        codesDataDlog::codeData = fresult;
        codesDataDlog::upload = TRUE;
        codesDataDlog dlg;
        dlg.DoModal();
    }
}
//涨停上传
void CappDlg::OnBnClickedButton12()
@@ -1598,7 +1779,7 @@
    else {
        try
        {
            tradeListCapture->refreshTradeDelegateHWND();
            tradeListCapture->refreshTradeSimpleDelegateHWND();
        }
        catch (string st)
        {
@@ -1917,6 +2098,24 @@
    std::list<IndustryData> fresult;
    codesDataDlog::codeData = fresult;
    codesDataDlog::upload = TRUE;
    codesDataDlog::add = FALSE;
    codesDataDlog dlg;
    dlg.DoModal();
}
void CappDlg::OnBnClickedCheckBuy1VolumnTimeLimit()
{
    TradeQueueCaptureManager::setTradeTimeCapture(buy1VolumnTimeLimitCheck.GetCheck());
}
//新增股票代码
void CappDlg::OnBnClickedButtonGpCodeAdd()
{
    std::list<IndustryData> fresult;
    codesDataDlog::codeData = fresult;
    codesDataDlog::upload = TRUE;
    codesDataDlog::add = TRUE;
    codesDataDlog dlg;
    dlg.DoModal();
}
app/appDlg.h
@@ -47,7 +47,7 @@
    void OnDataCallback(int index, list<TradeData> dataList);
    static void  OnL2DataCallback(int index,string code, long captureTime, long processTime, list<TradeData> dataList, void* context);
    static void  OnTradeQueueDataCallback(int index, string code, list<int> numList, void* context);
    static void  OnTradeQueueDataCallback(int index, string code, L2TradeQueue tradeQueue, void* context);
    static void  OnLimitUpDataCallback(list<LimitUpData> dataList, void* context);
    static void  OnTradeSuccessDataCallback(list<TradeSuccessData> dataList, void* context);
    static void  OnTradeDelegateDataCallback(list<TradeDelegateData> dataList,string money, void* context);
@@ -56,6 +56,7 @@
    static void OnTradeQueueCallback(int index, TradeQueueResult result, void* context);
    static string  OnActionProcess(string data, void* context);
    static string  OnActionCallback(string data, void* context);
    static string  OnActionCallbackQueue(string data, void* context);
@@ -73,6 +74,12 @@
    static void checkTHSEnv(CappDlg* app);
    static void autoStartL2(void* context);
    static void autoStartTradeDelegate(void* context);
    static void autoStartCurrentPrice(void* context);
    static void autoStartBuy1Volumn(void* context);
// 构造
@@ -104,7 +111,6 @@
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP();
    afx_msg void OnClose();
public:
    afx_msg void OnBnClickedButton1();
@@ -151,12 +157,13 @@
    afx_msg void OnBnClickedCheckTradeTimeTradeSuccess();
    afx_msg void OnBnClickedCheckTradeTimeDelegate();
    afx_msg void OnBnClickedCheckPriceTimeLimit();
    CButton uploadExcelGPBtn;
    afx_msg void OnBnClickedButtonUploadExcelCode();
    CButton buy1VolumnTimeLimitCheck;
    CButton buy1VolumnBtn;
    afx_msg void OnBnClickedButtonBuy1Volumn();
    CButton onlineCheck;
    CButton uploadGPCodeBtn;
    afx_msg void OnBnClickedButtonUploadGpcode();
    afx_msg void OnBnClickedCheckBuy1VolumnTimeLimit();
    CButton addGPCodeBtn;
    afx_msg void OnBnClickedButtonGpCodeAdd();
};
app/codesDataDlog.cpp
@@ -24,6 +24,7 @@
std::list<IndustryData> codesDataDlog::codeData;
bool  codesDataDlog::upload;
bool  codesDataDlog::add;
codesDataDlog::codesDataDlog(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_CODE_DATA, pParent)
@@ -74,7 +75,7 @@
        uploadBtn.ShowWindow(FALSE);
    CString st;
    st.Format(_T("总共%d条数据"), codeData.size());
    st.Format(_T("总共%d条数据(%s)"), codeData.size(),add? _T("新增"): _T("覆盖"));
    GetDlgItem(IDC_STATIC)->SetWindowTextW(st);
@@ -118,7 +119,7 @@
void codesDataDlog::OnBnClickedButton1()
{
    codeData.clear();
    if (codeData.size() == 0 ) {
        CString text;
        codesEdit.GetWindowTextW(text);
@@ -164,7 +165,7 @@
    }
    try {
        SocketManager::sendMsg(JsonUtil::loadGPCodeData(codeData).c_str());
        SocketManager::sendMsg(JsonUtil::loadGPCodeData(codeData,add).c_str());
        AfxMessageBox(_T("上传成功"));
app/codesDataDlog.h
@@ -12,6 +12,8 @@
public:
    static std::list<IndustryData> codeData;
    static bool upload;
    //新增
    static bool add;
public:
    codesDataDlog(CWnd* pParent = nullptr);   // 标准构造函数
app/resource.h
@@ -55,6 +55,7 @@
#define IDC_CHECK_BUY1_VOLUMN_TIME_LIMIT 1049
#define IDC_CHECK_ONLINE                1050
#define IDC_BUTTON_UPLOAD_GPCODE        1051
#define IDC_BUTTON_GP_CODE_ADD          1052
// Next default values for new objects
// 
@@ -62,7 +63,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        136
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1052
#define _APS_NEXT_CONTROL_VALUE         1053
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
app/setting.txt
File was deleted
app/user.txt
@@ -1,3 +1,3 @@
admin
123456
0
1