⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 llkdlg.cpp

📁 鼠标操作
💻 CPP
字号:
// llkDlg.cpp : implementation file
//

#include "stdafx.h"
#include "llk.h"
#include "llkDlg.h"
#include <Mmsystem.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define IDC_BLOCK 2000 
/////////////////////////////////////////////////////////////////////////////
// CLlkDlg dialog

CLlkDlg::CLlkDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLlkDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLlkDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLlkDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLlkDlg)
	DDX_Control(pDX, IDC_LINE, m_line);
	DDX_Control(pDX, IDC_BKPIC, m_bkPic);
	DDX_Control(pDX, IDC_EXCHANGENUM, m_exchangeLabel);
	DDX_Control(pDX, IDC_HINTNUM, m_hintLabel);
	DDX_Control(pDX, IDC_METHOD, m_method);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CLlkDlg, CDialog)
	//{{AFX_MSG_MAP(CLlkDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLlkDlg message handlers

BOOL CLlkDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	SetWindowPos(NULL, 100, 100, 800, 600, SWP_SHOWWINDOW|SWP_NOZORDER);
	//m_start.SetWindowPos(NULL, 650, 150, 60, 25, SWP_SHOWWINDOW|SWP_NOZORDER);
	//m_exit.SetWindowPos(NULL, 650, 220, 60, 25, SWP_SHOWWINDOW|SWP_NOZORDER);
	m_method.SetWindowPos(NULL, 300, 500, 200, 25, SWP_SHOWWINDOW|SWP_NOZORDER);
	m_bkPic.SetWindowPos(NULL, 130, 70, 480, 280, SWP_SHOWWINDOW|SWP_NOZORDER);
	m_line.SetWindowPos(NULL, 90, 30, 560, 360, SWP_SHOWWINDOW|SWP_NOZORDER);

	m_timeRgn.CreateRectRgn(150, 20, 550, 40);

	m_bStart = false;

	memset(&OpenParms1, 0, sizeof(MCI_OPEN_PARMSW));
	memset(&OpenParms2, 0, sizeof(MCI_OPEN_PARMSW));

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CLlkDlg::OnPaint() 
{
	/*	if (IsIconic())
	{
	CPaintDC dc(this); // device context for painting

	SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

	// Center icon in client rectangle
	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;

	// Draw the icon
	dc.DrawIcon(x, y, m_hIcon);

	DrawLine(&dc);
	}
	*/
	//防止重绘时时间条无法显示
	if(m_bStart)
	{
		CPaintDC dc(this);

		CBrush *pRedBrush = new CBrush;
		pRedBrush->CreateSolidBrush(RGB(255, 0, 0));
		CGdiObject *pOldBrush = dc.SelectObject(pRedBrush);

		dc.PaintRgn(&m_timeRgn);
		dc.SelectObject(pOldBrush);

		CPen *pYellowPen = new CPen;
		pYellowPen->CreatePen(PS_SOLID, 2, RGB(255,255,0));
		CPen *pOldPen = dc.SelectObject(pYellowPen);
		//pDC->Rectangle(150, 20, 550, 40);
		dc.MoveTo(150-1, 20-1);
		dc.LineTo(550+1, 20-1);
		dc.LineTo(550+1, 40+1);
		dc.LineTo(150-1, 40+1);
		dc.LineTo(150-1, 20-1);
		dc.SelectObject(pOldPen);
		pYellowPen->DeleteObject();
	}

	CDialog::OnPaint();
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CLlkDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CLlkDlg::InitMap(int map[][MAXY])
{
	int i, j;
	int x, y;

	//初始化边界
	for(i=0; i<MAXX; i++)
		for(j=0; j<MAXY; j++)
			if((i==0) || (i==MAXX-1) || (j==0) || (j==MAXY-1))
				map[i][j] = -1;
			else
				map[i][j] = 0;

	srand((unsigned int)time(NULL));//随机数种子

	//初始化地图
	for(i=0; i<SAME; i++)
		for(j=1; j<=TYPENUM; j++)
		{
			x = rand()%MAXX;
			y = rand()%MAXY;
			if(map[x][y])
				j--;
			else
				map[x][y] = j;
		}
}

void CLlkDlg::ShowMap(int map[][MAXY])
{
	this->Invalidate();
	int i, j;
	POINT p;
	CString str;

	//清除原有按钮
	for(i=0; i<m_btnGroup.GetSize(); i++)
		delete (CLLKButton *)m_btnGroup.GetAt(i);

	m_btnGroup.RemoveAll();
	for(i=1; i<MAXX-1; i++)
		for(j=1; j<MAXY-1; j++)
		{
			p.x = i;
			p.y = j;
			m_btnGroup.Add(new CLLKButton(map[i][j], p));
		}
		for(i=0; i<(MAXX-2)*(MAXY-2); i++)
		{
			CLLKButton *btn = (CLLKButton *)m_btnGroup.GetAt(i);

			btn->Create(str, WS_CHILD|BS_BITMAP, //注意属性!!!
				CRect(130+(i%(MAXY-2))*40, 70+(i/(MAXY-2))*40, 170+(i%(MAXY-2))*40, 110+(i/(MAXY-2))*40), this, IDC_BLOCK+i);
			if(btn->m_id)//如果为0则不显示
			{
				str.Format("res\\%d.bmp", btn->m_id);
				HBITMAP m_fkBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
				if(m_fkBmp == NULL) 
					if(MessageBox("缺少图片资源!", "错误", MB_ICONERROR|MB_OK) == IDOK)
					{
						CDialog::OnCancel();
						return;
					}

					btn->SetBitmap(m_fkBmp);
					btn->ShowWindow(SW_SHOW);
			}
			else
				btn->ShowWindow(SW_HIDE);
		}
}

void CLlkDlg::RefreshMap(){
	CRgn resultRgn;
	resultRgn.CreateRectRgn(90,30,690,430);
	CRgn tmpRgn;
	tmpRgn.CreateRectRgn(0,0,0,0);
	for(int i=0; i<MAXX; i++)
	{
		for(int j=0; j<MAXY; j++){
			CRect rect;
			CRgn srcRgn;

			if(map[i][j]==-1 || map[i][j]==0){
				rect.top = 30 + i*40;
				rect.bottom = 70 + i*40;
				rect.left = 90 + j*40;
				rect.right = 130 + j*40;
		
				srcRgn.CreateRectRgnIndirect(&rect);
				resultRgn.CombineRgn(&srcRgn,&tmpRgn,RGN_OR);//把消去的区域加进来(覆盖原有区域),以便刷新
				tmpRgn.CopyRgn(&resultRgn);
			}
		}
	}
	this->InvalidateRgn(&resultRgn);//只刷新被消去的区域,防止界面闪烁
}

void CLlkDlg::Reset()
{
	CString str;

	//随机设置背景图片
	srand((unsigned int)time(NULL));
	m_bkType = rand()%BKTYPENUM;
	str.Format("res\\b%d.bmp", m_bkType+1);
	m_bkPic.ModifyStyle(0,SS_BITMAP|SS_CENTERIMAGE);    
	HBITMAP m_bkBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); 
	m_bkPic.SetBitmap(m_bkBmp);

	do
	InitMap(map);
	while(!CLLKButton::Hint(map));
	ShowMap(map);

	m_p = NULL;
	m_hintNum = 3;
	m_exchangeNum = 3;
	m_line.m_lineNum = 0;

	str.Format("Hint:%d", m_hintNum);
	m_hintLabel.SetWindowText(str);
	str.Format("Exchange:%d", m_exchangeNum);
	m_exchangeLabel.SetWindowText(str);

	m_method.SetWindowText("Start!");

	//设置计时器
	KillTimer(2);
	CRgn rgn;
	rgn.CreateRectRgn(250, 20, 550, 40);
	m_timeRgn.CopyRgn(&rgn);
	m_timePoint = 550;
	ShowTimer(&m_timeRgn);
	SetTimer(2, 1200, NULL);
	m_bStart = true;

	/*播放声音*/
	if(OpenParms1.wDeviceID)
		mciSendCommand(OpenParms1.wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)&OpenParms1);
	if(OpenParms2.wDeviceID)
		mciSendCommand(OpenParms2.wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)&OpenParms2);

	//打开    
	//MCI_OPEN_PARMS OpenParms;
	OpenParms1.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_WAVEFORM_AUDIO;//MIDI设备类型
	OpenParms1.lpstrElementName = (LPCSTR)"res\\start.wav";//文件名
	OpenParms1.wDeviceID = 0;//设备标识号(用于和其他设备区分)
	mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT|MCI_NOTIFY, (DWORD)&OpenParms1);
	//播放
	MCI_PLAY_PARMS PlayParms;
	PlayParms.dwFrom = 0;//从头开始播放
	mciSendCommand(OpenParms1.wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)&PlayParms);

	OpenParms2.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_SEQUENCER;//WAV设备类型
	OpenParms2.lpstrElementName = (LPCSTR)"res\\bg.mid";//文件名
	OpenParms2.wDeviceID = 0;//设备标识号(用于和其他设备区分)
	mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT|MCI_NOTIFY, (DWORD)&OpenParms2);
	//播放
	PlayParms.dwFrom = 0;//从头开始播放
	mciSendCommand(OpenParms2.wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)&PlayParms);
}

void CLlkDlg::Exchange(int map[][MAXY])
{
	int i, j;
	int k = 0;
	int temp[(MAXX-2)*(MAXY-2)+1] = {0};//比格子数多一个,防止数组越界!!!
	for(i=1; i<MAXX-1; i++)
		for(j=1; j<MAXY-1; j++)
			if(map[i][j])
			{
				temp[k++] = map[i][j];
				map[i][j] = 0;
			}
			srand((unsigned int)time(NULL));
			k = 0;
			while(temp[k])
			{
				i = rand()%MAXX;
				j = rand()%MAXY;
				if(map[i][j])
					k--;
				else
					map[i][j] = temp[k];
				k++;
			}
}

void CLlkDlg::CallExchange()
{
	if(m_exchangeNum)
	{
		do
		Exchange(map);
		while(!CLLKButton::Hint(map));//至少有一个可消去
		ShowMap(map);
		m_exchangeNum--;

		CString str;
		str.Format("Exchange:%d", m_exchangeNum);
		m_exchangeLabel.SetWindowText(str);
	}
}

void CLlkDlg::CallHint()
{
	if(m_hintNum)
	{
		if(CLLKButton::Hint(map, &m_hintP1, &m_hintP2))
		{
			CLLKButton *temp;
			temp = (CLLKButton *)m_btnGroup.GetAt(m_hintP1);
			temp->SetButtonStyle(BS_DEFPUSHBUTTON);
			temp = (CLLKButton *)m_btnGroup.GetAt(m_hintP2);
			temp->SetButtonStyle(BS_DEFPUSHBUTTON);
			m_hintNum--;

			CString str;
			str.Format("Hint:%d", m_hintNum);
			m_hintLabel.SetWindowText(str);
		}
	}
}

BOOL CLlkDlg::PreTranslateMessage(MSG* pMsg) //对话框不响应OnKeyDown()
{
	// TODO: Add your specialized code here and/or call the base class
	if(pMsg->message==WM_KEYDOWN)
	{
		switch((int)pMsg->wParam)
		{
		case VK_F5:
			CallHint();
			m_line.m_lineNum = 0;
			RefreshMap();
			m_line.Invalidate();
			break;
		case VK_F6:
			CallExchange();			
			m_line.m_lineNum = 0;
			RefreshMap();
			m_line.Invalidate();
			break;
		default:
			break;
		}
	}

	return CDialog::PreTranslateMessage(pMsg);
}

void CLlkDlg::ShowTimer(CRgn *rgn)
{
	CClientDC *pDC = (CClientDC *)GetDC();

	CBrush *pRedBrush = new CBrush;
	pRedBrush->CreateSolidBrush(RGB(255, 0, 0));
	CGdiObject *pOldBrush = pDC->SelectObject(pRedBrush);

	//CRect rect;
	//rgn->GetRgnBox(rect);
	pDC->PaintRgn(rgn);
	//Sleep(1000);
	pDC->SelectObject(pOldBrush);
	pRedBrush->DeleteObject();

	CPen *pYellowPen = new CPen;
	pYellowPen->CreatePen(PS_SOLID, 2, RGB(255,255,0));
	CPen *pOldPen = pDC->SelectObject(pYellowPen);
	//pDC->Rectangle(150, 20, 550, 40);
	pDC->MoveTo(150-1, 20-1);
	pDC->LineTo(550+1, 20-1);
	pDC->LineTo(550+1, 40+1);
	pDC->LineTo(150-1, 40+1);
	pDC->LineTo(150-1, 20-1);
	pDC->SelectObject(pOldPen);
	pYellowPen->DeleteObject();
}

void CLlkDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	m_timePoint -= 10;
	if(m_timePoint < 150)
	{
		KillTimer(2);
		int ret = MessageBox("时间到!继续闯关吗?", "闯关失败", MB_YESNO|MB_ICONINFORMATION);
		if(ret == IDYES)
		{
			Reset();
			return;
		}
		else
			CDialog::OnCancel();
	}

	InvalidateRgn(&m_timeRgn);

	CRgn rgn;
	rgn.CreateRectRgn(150, 20, m_timePoint, 40);
	m_timeRgn.CopyRgn(&rgn);   

	ShowTimer(&m_timeRgn);

	//CDialog::OnTimer(nIDEvent);
}

BOOL CLlkDlg::OnCommand(WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	switch(LOWORD(wParam))
	{
	case ID_START:
		Reset();
		break;
	case ID_EXIT:
		CDialog::OnCancel();
		break;
	default:
		break;
	}
	
	return CDialog::OnCommand(wParam, lParam);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -