// LLkDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "LLk.h"
#include "LLkDlg.h"
#include "RectHandle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CLLkDlg 对话框
CLLkDlg::CLLkDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLLkDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_nTime = 5;
m_Brush.CreateSolidBrush(RGB(202,232,207));
}
void CLLkDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT, m_nTime);
DDV_MinMaxInt(pDX, m_nTime, 1, 20);
}
BEGIN_MESSAGE_MAP(CLLkDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_ERASEONE, &CLLkDlg::OnBnClickedEraseone)
ON_BN_CLICKED(IDC_START, &CLLkDlg::OnBnClickedStart)
ON_BN_CLICKED(IDC_SCAN, &CLLkDlg::OnBnClickedScan)
ON_BN_CLICKED(IDC_KILL, &CLLkDlg::OnBnClickedKill)
ON_WM_CTLCOLOR()
ON_EN_CHANGE(IDC_EDIT, &CLLkDlg::OnEnChangeEdit)
END_MESSAGE_MAP()
// CLLkDlg 消息处理程序
BOOL CLLkDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
//设置窗口位置
//GetSystemMetrics(lparam);参数 :=SM_CXSCREEN 返回屏幕宽 = SM_CYSCREEN 返回屏幕高
CRect r;
this->GetWindowRect(&r);
::SetWindowPos(this->m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOREPOSITION|SWP_NOSIZE);
::MoveWindow(this->m_hWnd,GetSystemMetrics(SM_CXSCREEN)-r.Width(),0,r.Width(),r.Height(),false);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CLLkDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CLLkDlg::OnPaint()
{
//CRect m_rect;
//GetClientRect(&m_rect);
//CClientDC myDC(this);
//CDC dcMem; //用于缓冲作图的内存DC
////dcMem.CreateCompatibleDC((CDC*)&myDC); //依附窗口DC创建兼容内存DC
//dcMem.CreateCompatibleDC(NULL);
//CBitmap bmp; //内存中承载临时图象的位图
//bmp.CreateCompatibleBitmap((CDC*)&myDC,m_rect.Width(),m_rect.Height());//创建兼容位图 (注:要得到彩色位图,第一个参数不能是内存dc)
//dcMem.SelectObject(&bmp); //将位图选择进内存DC
//
//CBitmap bitmap; //位图画刷
// //bitmap.LoadBitmapW(IDB_BITMAP_BK);
//CBrush hbr(&bitmap);
//dcMem.FillRect(&m_rect,&hbr);
//dcMem.SetBkMode(TRANSPARENT) ;
//dcMem.SetTextColor(RGB(0,255,255));
////dcMem.TextOutW(0,0,_T("剩余:"),5);
//myDC.BitBlt(0,0,m_rect.Width(),m_rect.Height(),&dcMem,0,0,SRCCOPY);
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CLLkDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
bool CLLkDlg::IsLLK()
{
CWnd *p=CWnd::FindWindow(NULL, WINDOWNTITLE);
if(p==NULL)
{
return false;
}
else
{
h_Game = p->GetSafeHwnd();
return true;
}
}
void CLLkDlg::OnBnClickedEraseone()
{
//GetDlgItem(IDC_ERASEONE)->EnableWindow(FALSE);
//if(!IsLLK())
//{
// MessageBox(_T("请打开 ,并确保没有窗口覆盖它"));
// return;
//}
//
if(m_cRectHandle.m_AllBlockCount == 0)
return;
POINT pt1,pt2;
if(FAIL == m_cRectHandle.GetOneErasePoint(h_Game,pt1,pt2))
{
MessageBox(_T("清除Error" ));
return;
}
pt1.x = 20 + X_START + pt1.x * X_LENGTH;
pt1.y = 20+Y_START+pt1.y *Y_LENGTH;
pt2.x = 20 + X_START + pt2.x * X_LENGTH;
pt2.y = 20+Y_START+pt2.y *Y_LENGTH;
::ClientToScreen(h_Game, &pt1); //该函数将指定点的用户坐标转换成屏幕坐标。
::ClientToScreen(h_Game, &pt2);
POINT current_mouse_pos;
GetCursorPos(¤t_mouse_pos);
SetCursorPos(pt1.x,pt1.y);
mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,0,0,0,0);
SetCursorPos(pt2.x ,pt2.y );
mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,0,0,0,0);
::SetCursorPos(current_mouse_pos.x, current_mouse_pos.y);
}
void CLLkDlg::OnBnClickedStart()
{
if(!IsLLK())
{
::MessageBox(NULL, _T("请打开游戏,并确保没有窗口覆盖它"), _T("错误信息"), MB_OK);
return;
}
if(FAIL == m_cRectHandle.Decode(h_Game))
{
MessageBox(_T("编码Error,游戏是否开始?" )); ////
return;
}
if (!UpdateData()) //Updatedata(TRUE) == 将控件的值赋值给成员变量;Updatedata(FALSE) == 将成员变量的值赋值给控件;
return;
m_cRectHandle.AutoErase( NULL );
//GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
//GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
//GetDlgItem(IDC_START)->EnableWindow(TRUE);
///GetDlgItem(IDC_BUTTON7)->EnableWindow(TRUE);
//GetDlgItem(IDC_BUTTON5)->SetWindowText(_T("暂停"));
}
void CLLkDlg::OnBnClickedScan()
{
if(!IsLLK())
{
::MessageBox(NULL, _T("请打开游戏,并确保没有窗口覆盖它"), _T("错误信息"), MB_OK);
return;
}
if(FAIL == m_cRectHandle.Decode(h_Game))
{
MessageBox(_T("编码Error,游戏是否开始?" )); ////
return;
}
CString str;
str.Format(_T("总个数为:%d个,图案种类共%d种"), m_cRectHandle.m_AllBlockCount,m_cRectHandle.m_NoSameBlocksCount);
::MessageBox(NULL, str, _T("打描结果 ^_*"), MB_OK);
}
void CLLkDlg::OnBnClickedKill()
{
if(!IsLLK())
{
::MessageBox(NULL, _T("请打开游戏,并确保没有窗口覆盖它"), _T("错误信息"), MB_OK);
return;
}
if(FAIL == m_cRectHandle.Decode(h_Game))
{
MessageBox(_T("编码Error,游戏是否开始?" )); ////
return;
}
m_nTime = 0;
m_cRectHandle.AutoErase( NULL );
}
HBRUSH CLLkDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor != CTLCOLOR_BTN )
{
pDC ->SetBkMode(TRANSPARENT);
hbr = (HBRUSH)m_Brush.GetSafeHandle();
}
if(nCtlColor == CTLCOLOR_BTN )
{
pDC-> SetTextColor(RGB(225,20,130));
hbr = (HBRUSH)m_Brush.GetSafeHandle();
}
if(pWnd-> GetDlgCtrlID()==IDC_STATIC3 || pWnd-> GetDlgCtrlID() == IDC_EDIT ||pWnd-> GetDlgCtrlID()==IDC_STATIC4 )
{
pDC-> SetTextColor(RGB(145,10,10)); //字体颜色
// pDC-> SetBkColor(RGB(40,230, 55)); //字体背景色
}
return hbr;
}
void CLLkDlg::OnEnChangeEdit()
{
UpdateData();
return;
}
BOOL CLLkDlg::PreTranslateMessage( MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
{
return TRUE; //屏蔽掉Esc键
}
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
return TRUE; //屏蔽掉Enter键
}
return CDialog::PreTranslateMessage( pMsg );
}
#include "StdAfx.h"
#include "RectHandle.h"
#include "variables.h"
#include <vector>
RectHandle::RectHandle(void)
{
m_AllBlockCount = 0;
m_NoSameBlocksCount = 0;
memset(m_LLK,BLANK_BLOCK,X_COUNT*Y_COUNT);
}
RectHandle::~RectHandle(void)
{
}
RECT RectHandle::GetBlockRect(int xCount, int yCount)
{
RECT rt;
rt.left = X_START + xCount * X_LENGTH;
rt.top = Y_START + yCount * Y_LENGTH;
rt.right = rt.left + X_LENGTH;
rt.bottom = rt.top + Y_LENGTH;
return rt;
}
int RectHandle::AddBlock(const HDC &dc, RECT block)
{
// 获得四个特征点的颜色值。
BlockColorFlag color_flag;
for (int i = 0; i < 4; ++i)
{
color_flag.color[i] = 0x00111111; // 7753015;
color_flag.color[i] = GetPixel(dc, block.left + FOUR_POINTS[i].x, block.top + FOUR_POINTS[i].y);
if(color_flag.color[i] == CLR_INVALID)
return BLANK_BLOCK;
}
// 判断是不是空白块。
int sh = 0;
for(int i = 0; i< 4; ++i)
{
int myr=GetRValue(color_flag.color[i]);
int myg=GetGValue(color_flag.color[i]);
int myb=GetBValue(color_flag.color[i]);
if ( (myr<73) &&(myr>45) &&(myg>50) &&(myg<90) &&(myb>103) &&(myb<129) ) //BK color 是48,76,112
sh++;
}
if(sh==4)
return BLANK_BLOCK;
++m_AllBlockCount;
// 查找是不是已经存在此块,并返回它的编号。不存在返回一个新的编号。
return FindExistBlock(color_flag);
}
//返回相同图,所在的索引
int RectHandle::FindExistBlock(const BlockColorFlag& block_flag)
{
// 从已经存在的块中查找。
for(int i = 0; i < m_NoSameBlocksCount; ++i)
{
int color_temp = 0;
for(int j = 0; j < 4; ++j)
{
color_temp += color_diff(m_NoSameBlocks[i].color[j], block_flag.color[j]);
}
if (color_temp < 15) //color 结果应为4
{
return i;
}
}
// 找不到,则把它记录到一个新的块标识中,然后返回新的标识号。
for (int i = 0; i < 4; ++i)
{
m_NoSameBlocks[m_NoSameBlocksCount].color[i] = block_flag.color[i];
}
++m_NoSameBlocksCount;
ASSERT(m_NoSameBlocksCount <= BLOCK_MAX);
return m_NoSameBlocksCount-1;
}
int RectHandle::color_diff(COLORREF a,COLORREF b)
{
int r1=GetRValue(a);
int r2=GetRValue(b);
int g1=GetGValue(a);
int g2=GetGValue(b);
int b1=GetBValue(a);
int b2=GetBValue(b);
return abs(r1-r2)+abs(g1-g2)+abs(b1-b2);
}
int RectHandle::IsNormal()
{
for (int i = 0; i < m_NoSameBlocksCount; ++i)
{
for (int j = 0; j < 4; ++j)
{
if (m_NoSameBlocks[i].color[j] == BLANK_BLOCK)
return FAIL;
}
}
return SUCCESS;
}
int RectHandle::Decode(const HWND &m_wndLLK)
{
int block_index = 0;
//初始化变量
m_AllBlockCount = 0;
m_NoSameBlocksCount = 0;
memset(m_NoSameBlocks,BLANK_BLOCK,BLOCK_MAX);
memset(m_LLK,BLANK_BLOCK,X_COUNT*Y_COUNT);
HDC dc = GetDC(m_wndLLK);
if(dc == NULL)
return FAIL;
for(int i = 0; i < X_COUNT; ++i)
{
for(int j = 0; j < Y_COUNT; ++j)
{
RECT block_rect = GetBlockRect(i, j);
block_index = AddBlock(dc, block_rect);
m_LLK[i][j] = block_index;
}
}
ReleaseDC(m_wndLLK, dc);
if(FAIL == IsNormal())
return FAIL;
return SUCCESS;
}
void RectHandle::AutoErase(const HWND hGame)
{
AfxBeginThread(&RemoveThread, this);
}
UINT RectHandle::RemoveThread(PVOID pvParam)
{
POINT pt1,pt2;
while(SUCCESS == GetOneErasePoint(NULL,pt1,pt2))
{
SendClickMessage(pt1.x,pt1.y );
SendClickMessage(pt2.x,pt2.y );
m_LLK[pt1.x][pt1.y] = BLANK_BLOCK;
m_LLK[pt2.x][pt2.y] = BLANK_BLOCK;
Sleep(m_nTime*1000);
}
return SUCCESS;
}
int RectHandle::GetOneErasePoint(const HWND &hGame,POINT &pt1, POINT &pt2)
{
std::vector <DubPoint> AllCanErasePoint;
AllCanErasePoint.clear();
DubPoint tempDPoint;
int temp_i=0,temp_j=0;
for(int i = 0; i < X_COUNT; ++i) //如果消一个,不需要全部统计出来,待改。。。。。。。。。。
{
for(int j = 0; j < Y_COUNT; ++j)
{
if(m_LLK[i][j] == BLANK_BLOCK)
continue;
if(HandlePoint(i,j,temp_i,temp_j)) //只找一个相同,可以消的
{
tempDPoint.Point1.x = i;
tempDPoint.Point1.y = j;
tempDPoint.Point2.x = temp_i;
tempDPoint.Point2.y = temp_j;
AllCanErasePoint.push_back(tempDPoint);
}
}
}
if( AllCanErasePoint.size() < 1)
return FAIL;
pt1.x = AllCanErasePoint[0].Point1.x;
pt1.y = AllCanErasePoint[0].Point1.y;
pt2.x = AllCanErasePoint[0].Point2.x;
pt2.y = AllCanErasePoint[0].Point2.y;
return SUCCESS;
}
//只找一个相同,可以消的
bool RectHandle::HandlePoint(int point1_x, int point1_y, int &point2_x, int &point2_y)
{
for(point2_x = point1_x; point2_x < X_COUNT; point2_x++)
{
if(point2_x == point1_x) //保证不是同一个点
point2_y = point1_y+1;
else
point2_y = 0;
for(;point2_y < Y_COUNT;point2_y++)
{
if(m_LLK[point1_x][point1_y] == m_LLK[point2_x][point2_y])
{
if( IsPath(point1_x,point1_y,point2_x,point2_y) )
return true;
}
}
}
return false;
}
bool RectHandle::IsPath(int point1_x, int point1_y, int point2_x, int point2_y)
{
if(point1_x == point2_x)
return isXpath( point1_x, point1_y, point2_x, point2_y);
else if(point1_y == point2_y)
return isYpath( point1_x, point1_y, point2_x, point2_y);
else
return isXpath( point1_x, point1_y, point2_x, point2_y) || /
isYpath( point1_x, point1_y, point2_x, point2_y);
}
bool RectHandle::isYpath(int point1_x, int point1_y, int point2_x, int point2_y)
{
int left,right,bottom,top,bottom1 , top1, bottom2,top2;
bool flag;
YArea(point1_x,point1_y,top1,bottom1);
YArea(point2_x,point2_y,top2,bottom2);
top = max(top1,top2);
bottom =min(bottom1,bottom2);
if(bottom < top)
return false;
left = min(point1_x,point2_x);
right = max(point1_x,point2_x);
while( top <= bottom )
{
flag = true;
while(++left < right)
{
if( m_LLK[left][top] != BLANK_BLOCK)
{
flag = false;
break;
}
}
if(flag)
return true;
top++;
}
return false;
}
bool RectHandle::isXpath(int point1_x, int point1_y, int point2_x, int point2_y)
{
int left,right,top,bottom,left1,right1,left2,right2;
bool flag;
XArea(point1_x,point1_y,left1,right1);
XArea(point2_x,point2_y,left2,right2);
left = max(left1,left2);
right= min(right1,right2);
if(left >right)
return false;
top = min(point1_y,point2_y);
bottom = max(point1_y,point2_y);
while(left <= right)
{
flag = true;
while(++top < bottom)
{
if(m_LLK[left][top] != BLANK_BLOCK)
{
flag = false;
break;
}
}
if(flag)
return true;
left++;
}
return false;
}
//点可达的最左,和最右的位置。
void RectHandle::XArea(const int pointx, const int pointy, int &xLeft, int &xRight)
{
int tempLeft = pointx;
int tempRight = pointx;
if( 0 == tempLeft)
xLeft = 0;
else
{
while( m_LLK[tempLeft-1][pointy] == BLANK_BLOCK)
{
if((--tempLeft) == 0)
break;
}
xLeft = tempLeft;
}
if(X_COUNT-1 ==tempRight)
xRight = tempRight;
else
{
while(m_LLK[tempRight+1][pointy] == BLANK_BLOCK)
{
if((++tempRight) == (X_COUNT-1))
break;
}
xRight = tempRight;
}
}
//点可达的最上和最下位置
void RectHandle::YArea(const int pointx, const int pointy, int &yTop,int &yBottom)
{
int tempTop = pointy;
int tempBottom = pointy;
if(0 == tempTop)
yTop = 0;
else
{
while( m_LLK[pointx][tempTop-1] ==BLANK_BLOCK)
{
if((--tempTop) == 0)
break;
}
yTop = tempTop;
}
if(Y_COUNT-1 == tempBottom)
yBottom = tempBottom;
else
{
while(m_LLK[pointx][tempBottom+1] == BLANK_BLOCK)
{
if((++tempBottom) == Y_COUNT-1)
break;
}
yBottom = tempBottom;
}
}
void RectHandle::SendClickMessage(int x, int y)
{
// 转换坐标。
POINT block_pt, client_pt;
block_pt.x = x;
block_pt.y = y;
GetCenterPointFromBlockInClient(block_pt, client_pt);
// 发送消息.
WPARAM wparam = MK_LBUTTON;
LPARAM lparam = MAKELPARAM(client_pt.x, client_pt.y);
// SendMessage(hwnd, WM_SETFOCUS, NULL, NULL);
SendMessage(h_Game, WM_LBUTTONDOWN, wparam, lparam);
SendMessage(h_Game, WM_LBUTTONUP, wparam, lparam);
}
void RectHandle::GetCenterPointFromBlockInClient(const POINT &pt, POINT &out_pt)
{
RECT rt = GetBlockRect(pt.x, pt.y);
out_pt.x = rt.left+X_LENGTH/2;
out_pt.y = rt.top+Y_LENGTH/2;
}

被折叠的 条评论
为什么被折叠?



