From eda1a611bc4afcf1c36a6c728f432aec1f688e1b Mon Sep 17 00:00:00 2001
From: admin <weikou2014>
Date: 星期一, 27 六月 2022 19:13:36 +0800
Subject: [PATCH] 'GP代码识别'

---
 ConsoleApplication/THSActionUtil.cpp |  238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 221 insertions(+), 17 deletions(-)

diff --git a/ConsoleApplication/THSActionUtil.cpp b/ConsoleApplication/THSActionUtil.cpp
index 27429a5..3506f84 100644
--- a/ConsoleApplication/THSActionUtil.cpp
+++ b/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;
 }
\ No newline at end of file

--
Gitblit v1.8.0