admin
2022-06-27 eda1a611bc4afcf1c36a6c728f432aec1f688e1b
ConsoleApplication/THSActionUtil.cpp
@@ -1,18 +1,193 @@
#include "THSActionUtil.h"
#include "ImgDivider.h"
#include "Win32Util.h"
//获取副屏
HWND getSecondWindow() {
   list<HWND> wlist = Win32Util::searchWindow("同花顺(");
   list<HWND>::iterator ele;
   for (ele = wlist.begin();ele != wlist.end();ele++) {
      HWND hwnd = *ele;
      string str = Win32Util::getWindowName(hwnd);
      if (str.find("同花顺") != string::npos && str.find("副屏") != string::npos)
      {
         return hwnd;
      }
   }
   return 0;
}
void THSActionUtil::openSecondScreen() {
   list<HWND> wlist = Win32Util::searchWindow("同花顺(");
   bool open = false;
   HWND mainPage = 0;
   list<HWND>::iterator ele;
   for (ele = wlist.begin();ele != wlist.end();ele++) {
      HWND hwnd = *ele;
      string str = Win32Util::getWindowName(hwnd);
      if (str.find("同花顺") != string::npos && str.find("副屏") != string::npos)
      {
         cout << str << endl;
         SetForegroundWindow(hwnd);
         SetFocus(hwnd);
         open = true;
         break;
      }
      if (str.find("同花顺") != string::npos && str.find("热门股") != string::npos) {
         cout << hwnd << endl;
         //获取尺寸
         RECT rc;
         GetWindowRect(hwnd, &rc);
         if (rc.right - rc.left > 200 && rc.bottom - rc.top > 200) {
            mainPage = hwnd;
         }
      }
   }
   if (!open) {
      Win32Util::focus(mainPage);
      //查找主窗口的工具栏
      HWND tool = FindWindowExA(mainPage, NULL, "AfxControlBar100s", NULL);
      //获取第一个子窗口
      tool = FindWindowExA(tool, NULL, NULL, NULL);
      cout << "操作栏:" << tool << endl;
      //打开副屏,多窗按钮ID为:0x00007AF9
      HWND btn = GetDlgItem(tool, 0x00007AF9);
      RECT rc;
      GetWindowRect(btn, &rc);
      //获取需要点击的位置
      int x = rc.left + (rc.right - rc.left) / 3;
      int y = rc.top + (rc.bottom - rc.top) / 3;
      //点击多窗
      Win32Util::click(x, y);
      //点击副屏1
      Win32Util::click(x + 10, y + 21 * 7 + 5, 500);
   }
}
//添加股票
void THSActionUtil::addGP(std::string quickCode, std::string code) {
void THSActionUtil::setGP(std::string quickCode, list<std::string> codeList) {
   //打开副屏
   HWND sw = getSecondWindow();
   if (sw <= 0)
   {
      openSecondScreen();
      Sleep(2000);
      sw = getSecondWindow();
   }
   if (sw <= 0) {
      throw("未打开副屏");
   }
   //打开板块
   Win32Util::keyboardNum(quickCode);
   Win32Util::keyboard(VK_RETURN, 200);
   Sleep(1000);
   //设置板块中的股票
   //获取板块内容句柄
   HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL);
   cv::Mat img = CaptureUtil::capture(content);
   if (img.cols <= 0 || img.rows <= 0) {
      throw("板块截屏内容为空");
   }
   std::list<GPCodeArea>  areaList = recognitionGPArea(img);
   std::list<string> addList;
   std::list<GPCodeArea> delList;
   std::list<GPCodeArea> resultList = recognitionNum(img, areaList);
   for (std::list<GPCodeArea>::reverse_iterator ele= resultList.rbegin();ele != resultList.rend();++ele) {
      bool contains = false;
      std::list<string>::iterator e;
      for (e = codeList.begin();e != codeList.end();e++) {
         if (*e == (*ele).code) {
            contains = true;
            break;
         }
      }
      if (!contains) {
         delList.push_back(*ele);
      }
      else
      {
         codeList.remove((*ele).code);
      }
   }
   //-----先删除需要删除的
   //获取内容板块坐标
   RECT rect;
   GetWindowRect(content, &rect);
   for (std::list<GPCodeArea>::iterator ele = delList.begin();ele != delList.end();++ele) {
      int x = rect.left;
      int y = rect.top;
      x += (*ele).startx+5;
      y += (*ele).starty+5;
       //选中删除
      Win32Util::click(x,y,50);
      Win32Util::keyboard(VK_DELETE, 50);
   }
   //----增加
   //截图,识别出增加按钮位置,点击增加,输入内容
}
//删除股票
void  THSActionUtil::deleteGP(std::string quickCode, std::string code) {
void add(string code) {
   //打开副屏
   HWND sw = getSecondWindow();
   if (sw <= 0)
   {
      openSecondScreen();
      Sleep(2000);
      sw = getSecondWindow();
   }
   if (sw <= 0) {
      throw("未打开副屏");
   }
   HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL);
   cv::Mat img = CaptureUtil::capture(content);
   if (img.cols <= 0 || img.rows <= 0) {
      throw("板块截屏内容为空");
   }
   std::list<GPCodeArea>  areaList = recognitionGPArea(img);
   for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();++ele) {
      GPCodeArea codeArea = *ele;
      if (codeArea.type == IMG_TYPE_ADD) {
         RECT rc;
         GetWindowRect(HWND(0x00161728), &rc);
         int y = rc.top + codeArea.starty + (codeArea.endy - codeArea.starty) / 2;
         int x = rc.left + codeArea.startx + (codeArea.endx - codeArea.startx) / 2;
         Win32Util::click(x, y, 50);
         //输入股票代码
         Win32Util::keyboardNum(code,1000);
         Win32Util::keyboard(VK_RETURN, 1500);
         //关闭按钮
         Sleep(100);
         HWND close = FindWindowA(0, "添加股票");
         SendMessage(close, WM_CLOSE, 0, 0);
         break;
      }
   }
}
//识别股票代码
std::list<GPCodeArea>  THSActionUtil::recognitionGPCode(cv::Mat img) {
std::list<GPCodeArea>  THSActionUtil::recognitionGPArea(cv::Mat img) {
   //获取title分隔线
   int rows = img.rows;
   int cols = img.cols;
@@ -70,7 +245,7 @@
   std::list<int*> dataItemList;
   for (int i = contentStartRow + 30;i < rows;i++) {
      bool empty = ImgDivider::isRowEmpty(img, i, startC, startC+50, 1, 64)&& ImgDivider::isRowEmpty(img, i, startC +(endC-startC)/2-40, startC + (endC - startC) / 2 + 40, 1, 64);
      bool empty = ImgDivider::isRowEmpty(img, i, startC, startC + 50, 1, 64) && ImgDivider::isRowEmpty(img, i, startC + (endC - startC) / 2 - 40, startC + (endC - startC) / 2 + 40, 1, 64);
      if (empty) {
         if (emptyStartRow < 0) {
            emptyStartRow = i;
@@ -80,7 +255,7 @@
            emptyEndRow = i;
         }
         if (emptyEndRow - emptyStartRow > 50&& dataItemList.size()>0) {
         if (emptyEndRow - emptyStartRow > 50 && dataItemList.size() > 0) {
            //没有数据了
            break;
         }
@@ -133,7 +308,7 @@
      LogUtil::debug("%d %d %d %d\n", startRow, startCol, endRow, endCol);
      //保存行数据
      if (true) {
      if (false) {
         std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\split\\";
         path.append(std::to_string(index)).append(".jpg");
         imwrite(path, cv::Mat(img, cv::Rect(startCol, startRow, endCol - startCol + 1, endRow - startRow + 1)));
@@ -160,14 +335,14 @@
            //3个及以上的空白数据才分列
            if (emptyEnd - emptyStart >= 5 && dataEnd - dataStart > 0) {
               int* dd = (int*)malloc(sizeof(int) * 4);
               *dd = dataStart ;
               *dd = dataStart;
               *(dd + 1) = startRow;
               *(dd + 2) = dataEnd ;
               *(dd + 2) = dataEnd;
               *(dd + 3) = endRow;
               rowDataList.push_back(dd);
               dataEnd = -1;
               dataStart = -1;
               if (rowDataList.size() >= 2){
               if (rowDataList.size() >= 2) {
                  break;
               }
            }
@@ -188,9 +363,9 @@
      //后面的数据没有足够的空白分隔
      if (dataEnd - dataStart > 0) {
         int* dd = (int*)malloc(sizeof(int) * 4);
         *dd = dataStart ;
         *dd = dataStart;
         *(dd + 1) = startRow;
         *(dd + 2) = dataEnd ;
         *(dd + 2) = dataEnd;
         *(dd + 3) = endRow;
         rowDataList.push_back(dd);
      }
@@ -198,15 +373,15 @@
      int rowDataSize = rowDataList.size();
      if (rowDataSize == 2) {
         std::list<int*>::iterator ele= rowDataList.begin();
         std::list<int*>::iterator ele = rowDataList.begin();
         std::advance(ele, 1);
         GPCodeArea area = GPCodeArea();
         area.type = IMG_TYPE_GP;
         area.startx = **ele;
         area.starty = *(*ele+1);
         area.endx = *(*ele+2);
         area.endy = *(*ele+3);
         area.starty = *(*ele + 1);
         area.endx = *(*ele + 2);
         area.endy = *(*ele + 3);
         resultList.push_back(area);
      }
      else {
@@ -245,9 +420,38 @@
            cc++;
         }
      }
   }
   return resultList;
}
std::list<GPCodeArea>   THSActionUtil::recognitionNum(cv::Mat img, std::list<GPCodeArea> areaList) {
   if (!recognitionManager) {
      recognitionManager = new RecognitionManager();
   }
   //识别数字
   std::list<GPCodeArea> codeList;
   std::list<GPCodeArea>::iterator ele;
   for (ele = areaList.begin();ele != areaList.end();ele++) {
      GPCodeArea codeArea = *ele;
      if (codeArea.type == IMG_TYPE_GP) {
         cv::Mat nums = cv::Mat(img, cv::Rect(codeArea.startx, codeArea.starty, codeArea.endx - codeArea.startx + 1, codeArea.endy - codeArea.starty + 1));
         std::list<cv::Mat> list2 = ImgUtil::splitNum(nums);
         std::list<uchar> resultList = recognitionManager->recognitionGPCode(list2);
         std::list<uchar>::iterator ele1;
         string code = "";
         for (ele1 = resultList.begin();ele1 != resultList.end();++ele1) {
            code.append(to_string(*ele1));
         }
         codeArea.code = code;
         codeList.push_back(codeArea);
      }
   }
   return codeList;
}