找茬

  1 // 仿写_4_找茬辅助.cpp : 定义应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "仿写_4_找茬辅助.h"
  6 #include <windowsx.h>
  7 #include <vector>
  8 using std::vector;
  9 
 10 #define MAX_LOADSTRING 100
 11 
 12 // 全局变量: 
 13 HINSTANCE hInst;                                // 当前实例
 14 TCHAR szTitle[MAX_LOADSTRING];                    // 标题栏文本
 15 TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
 16 
 17 // 此代码模块中包含的函数的前向声明: 
 18 ATOM                MyRegisterClass(HINSTANCE hInstance);
 19 BOOL                InitInstance(HINSTANCE, int);
 20 LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
 21 INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
 22 
 23 int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
 24                      _In_opt_ HINSTANCE hPrevInstance,
 25                      _In_ LPTSTR    lpCmdLine,
 26                      _In_ int       nCmdShow)
 27 {
 28     UNREFERENCED_PARAMETER(hPrevInstance);
 29     UNREFERENCED_PARAMETER(lpCmdLine);
 30 
 31      // TODO:  在此放置代码。
 32     MSG msg;
 33     HACCEL hAccelTable;
 34 
 35     // 初始化全局字符串
 36     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
 37     LoadString(hInstance, IDC__4_, szWindowClass, MAX_LOADSTRING);
 38     MyRegisterClass(hInstance);
 39 
 40     // 执行应用程序初始化: 
 41     if (!InitInstance (hInstance, nCmdShow))
 42     {
 43         return FALSE;
 44     }
 45 
 46     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC__4_));
 47 
 48     // 主消息循环: 
 49     while (GetMessage(&msg, NULL, 0, 0))
 50     {
 51         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
 52         {
 53             TranslateMessage(&msg);
 54             DispatchMessage(&msg);
 55         }
 56     }
 57 
 58     return (int) msg.wParam;
 59 }
 60 
 61 
 62 
 63 //
 64 //  函数:  MyRegisterClass()
 65 //
 66 //  目的:  注册窗口类。
 67 //
 68 ATOM MyRegisterClass(HINSTANCE hInstance)
 69 {
 70     WNDCLASSEX wcex;
 71 
 72     wcex.cbSize = sizeof(WNDCLASSEX);
 73 
 74     wcex.style            = CS_HREDRAW | CS_VREDRAW;
 75     wcex.lpfnWndProc    = WndProc;
 76     wcex.cbClsExtra        = 0;
 77     wcex.cbWndExtra        = 0;
 78     wcex.hInstance        = hInstance;
 79     wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI__4_));
 80     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
 81     wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
 82     wcex.lpszMenuName    = MAKEINTRESOURCE(IDC__4_);
 83     wcex.lpszClassName    = szWindowClass;
 84     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 85 
 86     return RegisterClassEx(&wcex);
 87 }
 88 
 89 //
 90 //   函数:  InitInstance(HINSTANCE, int)
 91 //
 92 //   目的:  保存实例句柄并创建主窗口
 93 //
 94 //   注释: 
 95 //
 96 //        在此函数中,我们在全局变量中保存实例句柄并
 97 //        创建和显示主程序窗口。
 98 //
 99 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
100 {
101    HWND hWnd;
102 
103    hInst = hInstance; // 将实例句柄存储在全局变量中
104 
105    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
106       CW_USEDEFAULT, 0, 1600, 700, NULL, NULL, hInstance, NULL);
107 
108    if (!hWnd)
109    {
110       return FALSE;
111    }
112 
113    ShowWindow(hWnd, nCmdShow);
114    UpdateWindow(hWnd);
115 
116    return TRUE;
117 }
118 
119 static HBITMAP hBitmap1;
120 static HBITMAP hBitmap2;
121 static BOOL   helpFlag = 0;
122 vector<COORD> vcPoints;
123 void ShowPicture(HWND hWnd){
124 
125     //加载图片
126     hBitmap1 = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
127     hBitmap2 = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP2));
128 
129     //获取图片信息
130     BITMAP bitmap;
131     GetObject(hBitmap1, sizeof(BITMAP), &bitmap);
132 
133     //获取DC
134     HDC hdc = GetDC(hWnd);
135     HDC hdcMem = CreateCompatibleDC(hdc);
136 
137     //选入图片1
138     SelectObject(hdcMem, hBitmap1);
139 
140     //复制到DC,完成图片1显示
141     BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
142 
143     //选入图片2
144     SelectObject(hdcMem, hBitmap2);
145 
146     //复制到DC,完成图片2显示
147     BitBlt(hdc, bitmap.bmWidth + 10, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
148         
149     if (helpFlag)
150     {
151         //找茬
152         //设置图片
153         SelectObject(hdc   , hBitmap1);
154         SelectObject(hdcMem, hBitmap2);
155         //设置采样系数 
156         DWORD dwAmendValue = 40;     //x,y轴 相差不超过40的点只算一个点     
157         DWORD dwSampling = 3;         //每三个像素点找一次,加快匹配速度
158         //清空容器
159         vcPoints.clear();
160 
161         COORD point = {-1,-1};        
162         //找出不一样的地方
163         for (int row = 0; row <= bitmap.bmHeight; row += dwSampling)
164         {
165             for (int col = 0; col <= bitmap.bmWidth; col += dwSampling)
166             {
167                 COLORREF src = GetPixel(hdc   , col, row);//图1
168                 COLORREF dec = GetPixel(hdcMem, col, row);//图2
169                 if (src != dec)
170                 {
171                     //精确找到不同的像素点,仅作测试用
172                     //SetPixel(hdc, col, row, 255);
173  
174                      //第一个不同点
175                      if (point.X == -1)
176                      {
177                          point.X = col;
178                          point.Y = row;
179                          continue;
180                      }
181                      //两点比较近的话,看成是一个不同的点
182                     if ((abs(col - point.X) + abs(row - point.Y)) < dwAmendValue)
183                      {
184                          point.X = (col + point.X) / 2;
185                          point.Y = (row + point.Y) / 2;
186                          continue;
187                      }
188                      //找到了一个新的点,把上一个点加入容器,并重新开始
189                     if ((abs(col - point.X) + abs(row - point.Y)) > dwAmendValue)
190                      {
191                          //把上一个点加入容器
192                         vcPoints.push_back(point);
193                          //然后开始记录新的不同点
194                          point.X = col;
195                          point.Y = row;
196                          continue;
197                      }                    
198                 }
199                 //结束的时候最后一个不同点也加到向量内
200                 if (((abs(col - bitmap.bmWidth) + abs(row - bitmap.bmHeight)))<dwSampling*dwSampling)
201                 {
202                     vcPoints.push_back(point);
203                 }
204             }
205         }
206     }    
207 
208     ReleaseDC(hWnd,hdc);
209     DeleteDC(hdcMem);
210     DeleteObject(hBitmap1);
211     DeleteObject(hBitmap2);
212 }
213 
214 void ShowDifferent(HWND hWnd){
215 
216     if (vcPoints.size()<0)
217     {
218         return;
219     }
220     //获取DC
221     HDC hdc = GetDC(hWnd);
222 
223     //显示不一样的地方
224     HPEN  hPen = CreatePen(PS_SOLID, 4, RGB(246, 106, 44));
225     HBRUSH hBrush = GetStockBrush(NULL_BRUSH);
226     SelectObject(hdc, hPen);
227     SelectObject(hdc, hBrush);
228     for (size_t i = 0; i < vcPoints.size(); i++)
229     {
230         Ellipse(hdc, vcPoints[i].X - 30, vcPoints[i].Y - 30, vcPoints[i].X + 30, vcPoints[i].Y + 30);
231     }
232     ReleaseDC(hWnd, hdc);
233 }
234 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
235 {
236     int wmId, wmEvent;
237     PAINTSTRUCT ps;
238     HDC hdc;
239     switch (message)
240     {
241     case WM_COMMAND:
242         wmId    = LOWORD(wParam);
243         wmEvent = HIWORD(wParam);
244         // 分析菜单选择: 
245         switch (wmId)
246         {
247         case IDM_HELP:
248             //既找茬,又显示图片,还显示结果
249             helpFlag = TRUE;            
250             ShowPicture(hWnd);
251             ShowDifferent(hWnd);
252             break;
253         case IDM_START:
254             //不找茬,只显示图片,不显示结果
255             helpFlag = FALSE;
256             ShowPicture(hWnd);
257             break;
258         default:
259             return DefWindowProc(hWnd, message, wParam, lParam);
260         }
261         break;
262     case WM_PAINT:
263     {
264         hdc = BeginPaint(hWnd, &ps);
265         // TODO:  在此添加任意绘图代码...
266         //响应paint消息时,不找茬,只显示图片,以及结果(无结果就不显示结果)。
267         helpFlag = FALSE;
268         ShowPicture(hWnd);
269         ShowDifferent(hWnd);
270 
271         EndPaint(hWnd, &ps);
272     }    break;
273     case WM_DESTROY:
274         PostQuitMessage(0);
275         break;
276     default:
277         return DefWindowProc(hWnd, message, wParam, lParam);
278     }
279     return 0;
280 }
让数据变得更安全!
原文地址:https://www.cnblogs.com/Alyoyojie/p/5267820.html