需要源码和资源请点赞关注收藏后评论区留言私信~~~
我们的Visual C++工程采用MFC框架模式,下面讲解各个功能模块的界面实现
可分为如下几个步骤
1:在工程资源中添加一个菜单资源
2:给每个菜单栏添加响应函数到CTertisView类中
3:菜单响应函数应该尽量调用类中的其他功能函数,减少直接处理的过程,这样程序代码阅读起来结构简单,功能明确,菜单响应函数代码如下
// TetrisView.cpp : implementation of the CTetrisView class
//
#include "stdafx.h"
#include "Tetris.h"
#include "TetrisDoc.h"
#include "TetrisView.h"
#include "HelpDlg.h"
#include "HeroDlg.h"
#include "LevelDlg.h"
#include "Russia.h"
#include <mmsystem.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CTetrisView
IMPLEMENT_DYNCREATE(CTetrisView, CView)
BEGIN_MESSAGE_MAP(CTetrisView, CView)
//{{AFX_MSG_MAP(CTetrisView)
ON_COMMAND(IDR_ABOUT, OnAbout)
ON_COMMAND(IDR_HERO_LIST, OnHeroList)
ON_COMMAND(IDR_LEVEL_SETUP, OnLevelSetup)
ON_COMMAND(IDR_PLAY_MUSIC, OnPlayMusic)
ON_COMMAND(IDR_START_GAME, OnStartGame)
ON_COMMAND(IDR_HELP, OnHelp)
ON_WM_KEYDOWN()
ON_WM_TIMER()
//}}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()
/
// CTetrisView construction/destruction
CTetrisView::CTetrisView()
{
m_bStart = FALSE;
}
CTetrisView::~CTetrisView()
{
}
BOOL CTetrisView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/
// CTetrisView drawing
void CTetrisView::OnDraw(CDC* pDC)
{
CTetrisDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
//没有开始,显示封面
if( m_bStart)
{
russia.DrawBK(pDC);
}
}
/
// CTetrisView printing
BOOL CTetrisView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CTetrisView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CTetrisView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CTetrisView diagnostics
#ifdef _DEBUG
void CTetrisView::AssertValid() const
{
CView::AssertValid();
}
void CTetrisView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CTetrisDoc* CTetrisView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTetrisDoc)));
return (CTetrisDoc*)m_pDocument;
}
#endif //_DEBUG
/
// CTetrisView message handlers
void CTetrisView::OnAbout()
{
CAboutDlg aboutDlg; //生成关于对话框
aboutDlg.DoModal(); //弹出关于对话框
}
void CTetrisView::OnHeroList()
{
CHeroDlg dlg; //生成英雄榜对话框
dlg.DoModal(); //弹出英雄榜对话框
}
void CTetrisView::OnLevelSetup()
{
CLevelDlg dlg; //生成等级设置对话框
dlg.DoModal(); //弹出等级设置对话框
}
void CTetrisView::OnPlayMusic()
{
CWnd* pMain = AfxGetMainWnd();
CMenu* pMenu = pMain->GetMenu();
//判断播放音乐菜单当前状态
BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_PLAY_MUSIC, MF_CHECKED);
if(m_bStart)
{
if(bCheck)
{
pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_UNCHECKED);
}
else
{
pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_CHECKED);
}
PlayBackMusic(!bCheck); //调用播放背景音乐功能函数
}
}
void CTetrisView::OnStartGame()
{
m_bStart = true;
russia.GameStart(); //调用RUSSIA对象的游戏开始函数
SetTimer(1, russia.m_Speed, NULL);
}
void CTetrisView::OnHelp()
{
CHelpDlg dlg; //生成帮助对话框
dlg.DoModal(); //弹出对话框
}
void CTetrisView::PlayBackMusic(BOOL bCheck)
{
//指定文件并播放
if(bCheck)
{ //播放音乐
sndPlaySound("music.wav",SND_ASYNC);
}
else
{ //停止播放
sndPlaySound(NULL,SND_PURGE);
}
}
void CTetrisView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
//没有开始
if(!m_bStart)
return;
switch(nChar)
{
case VK_LEFT:
russia.Move(KEY_LEFT);
break;
case VK_RIGHT:
russia.Move(KEY_RIGHT);
break;
case VK_UP:
russia.Move(KEY_UP);
break;
case VK_DOWN:
russia.Move(KEY_DOWN);
break;
}
//重画
CDC* pDC=GetDC();
russia.DrawBK(pDC);
ReleaseDC(pDC);
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CTetrisView::OnTimer(UINT nIDEvent)
{
//下移
russia.Move(KEY_DOWN);
//重画
russia.DrawBK(GetDC());
//关闭TIME1
KillTimer(1);
//调整速度
SetTimer(1, russia.m_Speed, NULL);
CView::OnTimer(nIDEvent);
}
创建一个对话框类,通过资源中的文字说明对游戏操作方法进行描述
#if !defined(AFX_HERODLG_H__6D0A81F3_A5F6_4816_899E_ACC62CDE229A__INCLUDED_)
#define AFX_HERODLG_H__6D0A81F3_A5F6_4816_899E_ACC62CDE229A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HeroDlg.h : header file
//
/
// CHeroDlg dialog
// CHeroDlg dialog
class CHeroDlg : public CDialog
{
// Construction
public:
void SetWriteFlg(BOOL bflg);
CHeroDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CHeroDlg)
enum { IDD = IDD_HERO_LIST };
int m_level;
CString m_name;
int m_score;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHeroDlg)
public:
virtual int DoModal();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CHeroDlg)
virtual void OnOK();
afx_msg void OnBtn();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
BOOL m_bWriteflg;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HERODLG_H__6D0A81F3_A5F6_4816_899E_ACC62CDE229A__INCLUDED_)
类的实现比较简单,就是一个基本对话框类的结构,只对其中的知道了按钮响应函数进行实现,用于退出当前对话框
// HelpDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Tetris.h"
#include "HelpDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CHelpDlg dialog
CHelpDlg::CHelpDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHelpDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHelpDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CHelpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHelpDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHelpDlg, CDialog)
//{{AFX_MSG_MAP(CHelpDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CHelpDlg message handlers
void CHelpDlg::OnOK()
{
// TODO: Add extra validation here
CDialog::OnOK();
}
要创建一个对话框资源和一个setup.ini配置文件,类声明如下
#if !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)
#define AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HelpDlg.h : header file
//
/
// CHelpDlg dialog
class CHelpDlg : public CDialog
{
// Construction
public:
CHelpDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CHelpDlg)
enum { IDD = IDD_HELP };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHelpDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CHelpDlg)
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)
类的实现中通过调用系统API函数对配置文件进行读写操作,而设置读写标志接口函数是对类中的一个成员变量进行赋值操作,达到写入或者读取的区分,代码如下
// HeroDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Tetris.h"
#include "HeroDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CHeroDlg dialog
CHeroDlg::CHeroDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHeroDlg::IDD, pParent)
{
m_bWriteflg = FALSE;
}
void CHeroDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHeroDlg)
DDX_Text(pDX, IDC_LEVEL_EDIT, m_level);
DDX_Text(pDX, IDC_NAME_EDIT, m_name);
DDX_Text(pDX, IDC_SCORE_EDIT, m_score);
DDV_MinMaxInt(pDX, m_score, 0, 10000);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHeroDlg, CDialog)
//{{AFX_MSG_MAP(CHeroDlg)
ON_BN_CLICKED(IDOK_BTN, OnBtn)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CHeroDlg message handlers
void CHeroDlg::OnOK()
{
}
void CHeroDlg::SetWriteFlg(BOOL bflg)
{
m_bWriteflg = bflg;
}
int CHeroDlg::DoModal()
{
char pszTmp[128] = {0};
//读取配置文件
GetPrivateProfileString("HERO", "name", "0",
pszTmp, 127, ".\\setup.ini");
m_name = CString(pszTmp);
if(!m_bWriteflg)
{
GetPrivateProfileString("HERO", "score", "0",
pszTmp, 127, ".\\setup.ini");
m_score = atoi(pszTmp);
GetPrivateProfileString("HERO", "level", "0",
pszTmp, 127, ".\\setup.ini");
m_level = atoi(pszTmp);
}
return CDialog::DoModal();
}
void CHeroDlg::OnBtn()
{
UpdateData(TRUE);
if(m_bWriteflg)
{
CString tmp;
tmp.Format("%d", m_score);
WritePrivateProfileString("HERO", "name", m_name, ".\\setup.ini");
WritePrivateProfileString("HERO", "score", tmp, ".\\setup.ini");
tmp.Format("%d", m_level);
WritePrivateProfileString("HERO", "level", tmp, ".\\setup.ini");
}
m_bWriteflg = FALSE;
CDialog::OnOK();
}
BOOL CHeroDlg::OnInitDialog()
{
CDialog::OnInitDialog();
if(m_bWriteflg)
{
SetDlgItemText(IDOK_BTN, "记录");
}
return TRUE;
}
播放游戏背景音乐,是通过调用Windows的API函数sndPlaySound来实现的,需要如下几个步骤
1:在工程文件中,添加winmm.lib静态库文件以及头文件
2:实现CTetrisView类中的PlayBackMusic成员函数
创建一个对话框资源,并往配置文件中添加一个小节用于记录设置游戏的等级,并且对确定按钮和取消按钮绑定响应函数,类的声明如下
#if !defined(AFX_LEVELDLG_H__E423F5C3_7698_4365_A009_4E6C7BC62189__INCLUDED_)
#define AFX_LEVELDLG_H__E423F5C3_7698_4365_A009_4E6C7BC62189__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// LevelDlg.h : header file
//
/
// CLevelDlg dialog
class CLevelDlg : public CDialog
{
// Construction
public:
CLevelDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CLevelDlg)
enum { IDD = IDD_LEVEL_DLG };
int m_level;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CLevelDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CLevelDlg)
virtual void OnOK();
virtual void OnCancel();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LEVELDLG_H__E423F5C3_7698_4365_A009_4E6C7BC62189__INCLUDED_)
游戏等级设置对话框通过初始化对话框时,把配置文件中的当前等级参数读出来并显示,然后根据用户单击确定按钮进行相应的写入操作,类的实现代码如下
// LevelDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Tetris.h"
#include "LevelDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CLevelDlg dialog
CLevelDlg::CLevelDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLevelDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CLevelDlg)
m_level = 0;
//}}AFX_DATA_INIT
}
void CLevelDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLevelDlg)
DDX_Text(pDX, IDC_LEVEL_EDIT, m_level);
DDV_MinMaxInt(pDX, m_level, 1, 10);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLevelDlg, CDialog)
//{{AFX_MSG_MAP(CLevelDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CLevelDlg message handlers
void CLevelDlg::OnOK()
{
if(UpdateData(TRUE))
{
CString tmp;
tmp.Format("%d", m_level);
WritePrivateProfileString("SETUP", "level", tmp, ".\\setup.ini");
CDialog::OnOK();
}
}
void CLevelDlg::OnCancel()
{
CDialog::OnCancel();
}
BOOL CLevelDlg::OnInitDialog()
{
CDialog::OnInitDialog();
char pszTmp[128] = {0};
GetPrivateProfileString("SETUP", "level", "0",
pszTmp, 127, ".\\setup.ini");
m_level = atoi(pszTmp);
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
测试效果如下



创作不易 觉得有帮助请点赞关注收藏~~~
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我的rails3.1.6应用程序中有一个自定义访问器方法,它为一个属性分配一个值,即使该值不存在。my_attr属性是一个序列化的哈希,除非为空白,否则应与给定值合并指定了值,在这种情况下,它将当前值设置为空值。(添加了检查以确保值是它们应该的值,但为简洁起见被删除,因为它们不是我的问题的一部分。)我的setter定义为:defmy_attr=(new_val)cur_val=read_attribute(:my_attr)#storecurrentvalue#makesureweareworkingwithahash,andresetvalueifablankvalueisgiven