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

📄 jlview.cpp

📁 很经典的用C++编的空当接龙的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// JLView.cpp : implementation of the CJLView class
//

#include "stdafx.h"
#include "JL.h"

#include "JLDoc.h"
#include "JLView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CJLView

IMPLEMENT_DYNCREATE(CJLView, CView)

BEGIN_MESSAGE_MAP(CJLView, CView)
	//{{AFX_MSG_MAP(CJLView)
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONUP()
	ON_COMMAND(IDM_BK_COLOR, OnBkColor)
	ON_COMMAND(IDM_CARD_COLOR, OnCardColor)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CJLView construction/destruction

CJLView::CJLView()
{
	// TODO: add construction code here
	CWinApp *pApp = AfxGetApp();
	m_hDown = pApp->LoadCursor(IDCSR_DOWN_ARROW);
	m_hIcon = pApp->LoadIcon(IDR_MAINFRAME);
	m_brushBk.CreateSolidBrush(RGB(255,255,255));//card bk
	m_brushBkgnd.CreateSolidBrush(RGB(0,128,0));//client bk
	//装载位图资源
	{
		//压缩后的位图文件被作为自定义资源,这里先装载资源
		HRSRC handle = FindResource(NULL,"IDR_BIN_ZIP_BMP","BIN");
		HGLOBAL hGlobal = LoadResource(NULL,handle);
		BYTE * pByte = (BYTE *) LockResource(hGlobal);
		DWORD size = SizeofResource(NULL,handle);
		
		CMemFile srcFile;
		srcFile.Attach(pByte,size,0);
		
		//准备将压缩的位图解码到临时文件
		char path[MAX_PATH],name[MAX_PATH];
		DWORD len = GetTempPath(MAX_PATH,path);
		if(len == 0 || len >= MAX_PATH || GetTempFileName(path,"bmp",0,name) == 0) {
			MessageBox("无法创建临时文件!",NULL,MB_ICONERROR | MB_OK);
		}
		
		CFile desFile(name,modeCrWr);
		
		//解码
		Decoding(desFile,srcFile);
		srcFile.Detach();
		
		//装载位图资源之前要保证位图文件已经关闭
		desFile.Flush();//这里两步是必不可少的步骤!
		desFile.Close();
		HANDLE bmp = ::LoadImage(pApp->m_hInstance,name,IMAGE_BITMAP,596,86,LR_LOADFROMFILE);
		m_AllBmps.Attach(bmp);
		
		//删除临时位图文件
		CFile::Remove(name);
	}

	m_nCardLabelHit = 0;
}

//draw all things in memory dc!!!!!!!!!!!!!
//所有的绘牌动作必须都在内存中进行否则会造成闪动
void CJLView::DrawCard(CPoint point,UINT card, CDC *pDC)
{
	CJLDoc* pDoc = GetDocument();
	ASSERT(pDoc->IsCard(card));

	CPen penBlack(PS_SOLID,1,RGB(0,0,0));
	CPen *oldPen = pDC->SelectObject(&penBlack);
	CBrush *oldBrush = pDC->SelectObject(&m_brushBk);
	CRect r(point,CSize(CARD_WID,CARD_HEI));
	pDC->RoundRect(r,CPoint(5,5));//画牌的背景与边框
	pDC->SelectObject(oldPen);
	pDC->SelectObject(oldBrush);
	CDC memDC;
	memDC.CreateCompatibleDC(pDC);
	CBitmap *poldbmp = memDC.SelectObject(&m_AllBmps);
	//画左上角 & 右下角数字(8*12)和数字下/上面的图标(8*8)
	int type = TYPE(card), num  = NUM(card);
	int idxBS = type%2*26, idxUL = idxBS + num - 1, idxBR = idxBS + 26 - num;
	pDC->BitBlt(r.left+3    , r.top+3       , 8 , 12 , &memDC , idxUL*8+32 , 0 , SRCAND);
	pDC->BitBlt(r.right-3-8 , r.bottom-3-12 , 8 , 12 , &memDC , idxBR*8+32 , 0 , SRCAND);
	pDC->BitBlt(r.left+3    , r.top+3+12+1,       8, 8, &memDC , clr[SML][type][0][0], clr[SML][type][0][1] , SRCAND);
	pDC->BitBlt(r.right-3-8 , r.bottom-3-12-1-8 , 8, 8, &memDC , clr[SML][type][1][0], clr[SML][type][1][1] , SRCAND);
	//在牌的主要部分画花色
	const UCHAR *p,*data[] = { cA , c2 , c3 , c4 , c5 , c6 , c7 , c8 , c9 , c10 };
	if(num <= 10) {
		p = ( card == CARD(8,3) ? c8FK : data[num-1] );
		UINT n = num*3;
		for(UINT j = 0; j < n ; j += 3) {
			pDC->BitBlt(point.x + p[j] - 8, point.y + p[j+1] - 8, 16, 16, &memDC, clr[BIG][type][!p[j+2]][0], clr[BIG][type][!p[j+2]][1], SRCAND);
		}
	} else { //画J Q K
		CPoint p = r.CenterPoint();
		pDC->BitBlt(p.x-23, p.y-37, 47, 74, &memDC, ( (num-11)*4 + type )*47 + 32, 12, SRCAND);
	}
	memDC.SelectObject(poldbmp);
}

void CJLView::OnDraw(CDC* pDC)
{
	CJLDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//显示步数信息
	CString strSteps;
	CRect r = pDoc->RectOfStep();
	if(!pDoc->m_pOps->IsEmpty()) {
		strSteps.Format("%d", pDoc->m_pOps->GetCount());

		CFont font; 
		font.CreatePointFont(stepFont * 10, "Arial", pDC);
		CFont * prevFont  = pDC->SelectObject(&font);
		int     prevMode  = pDC->SetBkMode(TRANSPARENT); 

		pDC->DrawText(strSteps,r, DT_CENTER);

		pDC->SetBkMode(prevMode);
		pDC->SelectObject(prevFont);
	}
	//在步数信息下面显示图标
	CPoint p = r.CenterPoint();
	p.x -= 16;
	p.y += 16;
	pDC->DrawIcon(p,m_hIcon);

	//绘制牌面提示按钮(8*12)   A-K
	CDC memDC;
	memDC.CreateCompatibleDC(pDC);
	CBitmap *poldbmp = memDC.SelectObject(&m_AllBmps);
	CBrush brush(RGB(0,0,0));
	for(UINT c = 1; c <= 13 ; c++) {
		CRect r = pDoc->RectOf(c);
		pDC->FrameRect(r,&brush);
		CPoint p = r.CenterPoint();
		p.x -= 4; p.y -= 6;
		pDC->BitBlt(p.x,p.y,8,12,&memDC,(c-1)*8+32,0,SRCAND);
	}
	memDC.SelectObject(poldbmp);

	//绘制牌局
	p.x = p.y = 0;
	for( UINT i = 1; i <= 16; i++ ) {
		UINT nCards = pDoc->CntCardsIn(i);
		if(!nCards) { //此列没有牌则只绘制方框
			//pDC->FrameRect(pDoc->RectOf(i,1,1),&brush);
			CBrush *pPrevBrush = pDC->SelectObject(&m_brushBkgnd);
			pDC->RoundRect(pDoc->RectOf(i,1,1),CPoint(5,5));
			pDC->SelectObject(&pPrevBrush);
		} else if(i <= 8) {
			for( UINT j = 1; j <= nCards; j++ ) {
				UINT card = pDoc->GetCard(i,j);
				if(card == 0) continue; //这里本不该出现牌点数为0 的情况,都是多线程惹的祸
				r = pDoc->RectOf(i, j, 1);
				DrawCard(r.TopLeft() , card , pDC);
				if(pDoc->m_nSel == i && j == nCards) {
					pDC->InvertRect(r); //被选中列的底牌需要反色
				}
			}
		} else { //绘制空档列和回收列
			r = pDoc->RectOf(i,1,1);
			DrawCard(r.TopLeft(),pDoc->BottCard(i),pDC);
			if(pDoc->m_nSel == i) { //如果此列是被选中状态,则此列牌被反色
				pDC->InvertRect(r);
			}
		}
	}
}

#ifdef _DEBUG
void CJLView::AssertValid() const
{
	CView::AssertValid();
}

void CJLView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CJLDoc* CJLView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CJLDoc)));
	return (CJLDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CJLView message handlers
void CJLView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	UINT hit = m_nCardLabelHit;
	m_nCardLabelHit = 0;
	if(hit) {
		ReleaseCapture();
		CJLDoc *pDoc = GetDocument();
		InvalidateRect(pDoc->RectOf(hit));//牌标反色
		CARD_POS pos[5], *p = pos, *pEnd = pDoc->FindCardForLabel(hit,pos);
		while(p < pEnd) { //将与此牌标对应的牌正常显示出来
			CRect r = pDoc->RectOf(p->col,p->idx,1);
			InvalidateRect(r);
			++p;
		}
	}

	CView::OnLButtonUp(nFlags, point);
}

void CJLView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	//击中提示牌对应的按钮则在此处理
	bool bInverted = false;
	UINT hit = CardLabelHitTest(point);
	if(hit) {
		CJLDoc *pDoc = GetDocument();
		CARD_POS pos[5], *p = pos, *pEnd = pDoc->FindCardForLabel(hit,pos);
		if(p < pEnd) { //如果有牌对应牌标
			SetCapture();//捕获鼠标输入
			m_nCardLabelHit = hit;//记录此牌标

			CClientDC cdc(this);
			cdc.InvertRect(pDoc->RectOf(hit));//牌标反色

			CBrush brRed(RGB(255,0,0));
			CBrush brBlk(RGB(0,0,0));
			while(p < pEnd) { //将与此牌标对应的牌显示出来并反色
				CRect r = pDoc->RectOf(p->col,p->idx,1);
				UINT card = pDoc->GetCard(p->col,p->idx);
				DrawCard(r.TopLeft(),card,&cdc);

				CBrush *pBr = TYPE(card)%2 == 0 ? &brBlk : &brRed;

⌨️ 快捷键说明

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