cpp

// 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(&current_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;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值