软件编程实践

实验一:一元二次方程的求解

  1. 新建Win32应用程序(非Win32控制台程序)
  2. 新建xxx.cpp文件用来放置代码,具体代码如下:
#include <windows.h>
#include <stdio.h>
#include <Math.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lparam); //窗口过程函数声明
GetRoot(float a, float b, float c, double *root);
char str[80];  // 全局变量

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) //主函数
{
    //窗口创建五步曲
    //1.设计一个完整的窗口类
    static TCHAR szAppName[] = TEXT ("HelloWinAPI");
	HWND hwnd ; // 定义窗口句柄
	MSG msg ; // 定义消息
	WNDCLASS wndclass ; // 定义窗口类
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
	//加载图标供程序使用
	wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
	//加载鼠标指针供程序使用
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
	//获取一个图形对象,在这个例子中,是获取绘制窗口背景的刷子
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;// 窗口类名

    //2.注册窗口类
    if (!RegisterClass(&wndclass)) //设计完窗口后,需要对窗口类进行注册,这样才能创建该类型的窗口
    return - 1;

    //3.正式创建窗口
    hwnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, 10, 10, 600, 400, NULL, NULL, hInstance, NULL);

    //4.窗口的显示与更新
    ShowWindow(hwnd, nShowCmd); //调用ShowWindow函数来显示窗口
    UpdateWindow(hwnd); //对窗口进行更新

    //5.消息循环过程
    while (msg.message != WM_QUIT) //使用while循环,如果消息不是WM_QUIT消息,就继续循环
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) //查看应用程序消息队列,有消息时将队列中的消息派发出去。
        {
            TranslateMessage(&msg); //将虚拟键消息转换为字符消息
            DispatchMessage(&msg); //分发一个消息给窗口程序。
        }
    }

    //窗口类的注销
    UnregisterClass(szAppName, wndclass.hInstance); //程序准备结束,注销窗口类
    return 0;
}

// 窗口过程函数WndProc,对窗口消息进行处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HDC hdc;
	PAINTSTRUCT ps;
	static HWND hwndButton, hwndEdit;
	char strEdit[80], strA[3][80], strHint[80];
	float a[3];
	double root[2];
	int i, j, k, m;
	switch (message)
	{
		case WM_CREATE: // 窗口创建产生的消息
		hwndEdit=CreateWindow("edit",NULL,
		WS_CHILD|WS_VISIBLE|WS_BORDER,
		10, 60, 200, 25, hwnd, NULL, NULL, NULL );
		hwndButton = CreateWindow("button", "计 算",
		WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
		240, 60, 80, 25, hwnd, NULL, NULL, NULL );
		return 0 ;
		case WM_COMMAND:// 命令消息,控件产生的通知代码在 wParam 的高字中
			if (((HWND)lParam==hwndButton)&&(HIWORD(wParam) == BN_CLICKED ))
			// 单击按钮
			{
			// 获取编辑框控件的内容,并将其转换成 float 数值
				GetWindowText( hwndEdit, strEdit, 80); // 获取编辑框内容
				k = 0; m = 0;
				for (j=0; j<80; j++)
				{
					if (strEdit[j] == ','){
					k++; m = 0;
				}
				else {
					strA[k][m] = strEdit[j];
					m++;
				}
			}
			for (i=0; i<3; i++)
				a[i] = (float)atof(strA[i]); // 将字符串转换成 float 数值
				int n = GetRoot(a[0], a[1], a[2], root);
				if (n < 1) strcpy(str, "方程无根!") ;
				else sprintf(str, "方程的解为:%f, %f", root[0], root[1]);
				InvalidateRect(hwnd, NULL, TRUE);
			}
		case WM_PAINT: //绘制窗口
			hdc = BeginPaint(hwnd, &ps);
			strcpy(strHint, "请输入一元二次方程的 3 个系数,中间用逗号分隔");
			TextOut(hdc, 10, 40, strHint, strlen(strHint));
			TextOut(hdc, 10, 90, str, strlen(str));
			EndPaint(hwnd, &ps);
			//和 BeginPaint()函数配对使用,以便使用完系统资源 hdc 后,立刻释放资源
			return 0 ;
		case WM_DESTROY:// 当窗口关闭时产生的消息
			PostQuitMessage(0) ;
			return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;// 执行默认的消息处理
}

int GetRoot(float a, float b, float c, double *root) {
	double delta, deltasqrt;
	delta = b*b - 4.0 * a * c;
	if (delta<0.0) return 0; // 无根
	deltasqrt = sqrt(delta);
	if (a!=0.0) {
		root[0] = (-b + deltasqrt) / (2.0 * a);
		root[1] = (-b - deltasqrt) / (2.0 * a);
	}
	else

	if (b != 0.0)
	root[0] = root[1] = -c / b;
	else return 0;
	if (root[0] == root[1]) return 1;
	else return 2;
}

实验二:鼠标与键盘事件

  1. 鼠标左右键自增与自减事件
    1.在View视图类新建公共变量:int M_Right; int M_Left;
    2.在View视图类构造器中完成变量初始化:M_Left = 0; M_Right = 0;
    3.在建立类向导中选择View试图类,生成如下两个Messages:VM_OnLButtonDown()、VM_OnRButtonDown()
    4.添加OnLButtonDown()与OnRButtonDown()处理函数:
OnLButtonDown():
	M_Left++;
	CString strOutput;
	strOutput.Format("鼠标左键的点击次数为:%d", M_Left);
	MessageBox(strOutput);
	CView::OnLButtonDown(nFlags, point);
OnRButtonDown():
	M_Right++;
	CString strOutput;
	strOutput.Format("鼠标右键的点击次数为:%d", M_Right);
	MessageBox(strOutput);
	CView::OnRButtonDown(nFlags, point);
  1. 键盘弹出事件
    1.在建立类向导中选择View试图类,生成一个Messages:VM_CHAR()
    2.添加VM_CHAR()处理函数:
	if (nChar == 'X') {
		MessageBox("您的学号为:hehe");
	}
	CView::OnChar(nChar, nRepCnt, nFlags);

实验三:图形与文本
1.使用不同的画笔绘制自己的姓名

  1. 在View视图通过补充OnDraw()函数完成名字的绘制:
	CDrawNameDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CPen pen0(PS_DASH, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen0);
	pDC->MoveTo(150, 150);
	pDC->LineTo(250, 150);

	CPen pen1(PS_DOT, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen1);
	pDC->MoveTo(250, 150);
	pDC->LineTo(250, 250);

	CPen pen2(PS_SOLID, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen2);
	pDC->MoveTo(180, 150);
	pDC->LineTo(180, 250);

	CPen pen3(PS_DASHDOT, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen3);
	pDC->MoveTo(180, 250);
	pDC->LineTo(300, 250);

	CPen pen4(PS_INSIDEFRAME, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen4);
	pDC->MoveTo(300, 250);
	pDC->LineTo(300, 350);

	CPen pen5(PS_INSIDEFRAME, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen5);
	pDC->MoveTo(300, 350);
	pDC->LineTo(280, 330);

	CPen pen6(PS_DASHDOTDOT, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen6);
	pDC->MoveTo(160, 300);
	pDC->LineTo(300, 300);

2.使用不同的画刷模拟交通信号灯

	CPen pen(NULL, 1, RGB(0, 0, 0));
	pDC->SelectObject(&pen);

	// 画圆1
	pDC->Ellipse(20, 20, 120, 120);   // 参数为:左上角:(x, y)、右上角:(x, y)
	// 画刷:上色
	CBrush brush(RGB(255, 0, 0));
	pDC->SelectObject(&brush);
	pDC->Ellipse(20, 20, 120, 120);

	pDC->SelectObject(&pen);

	pDC->Ellipse(20, 150, 120, 250);

	CBrush brush1(RGB(255, 255, 0));
	pDC->SelectObject(&brush1);
	pDC->Ellipse(20, 150, 120, 250);

	pDC->SelectObject(&pen);

	pDC->Ellipse(20, 280, 120, 380);

	CBrush brush2(RGB(0, 255, 0));
	pDC->SelectObject(&brush2);
	pDC->Ellipse(20, 280, 120, 380);

3.补充字体的使用:

	CFont *OldFont, NewFont1;
	NewFont1.CreatePointFont(200, "宋体", NULL);
	OldFont = pDC->SelectObject(&NewFont1);
	pDC->TextOut(0,60, "导入背景图片");
	pDC->SelectObject (OldFont);
	NewFont1.DeleteObject();

实验四:菜单栏与工具栏
1.菜单栏:添加主菜单“显示”,“显示”菜单中包含“文本”和“图形”两个子菜单。点击“文本”,显示“菜单设计程序”;点击“图形”,显示一个红色的实心矩形

  1. 在ResourceView中的Menu资源完成新的菜单项的定义与属性ID的定义(ID_TEXT与ID_PICTURE)
  2. 在View中Doc类中新建全局变量int picture;,添加在Doc类的构造函数最前面
  3. 在类向导中选择Doc类,分别对刚才定义的ID添加COMMAND处理函数:OnText()与OnPicture()
OnText():
	picture = 0;
	UpdateAllViews(NULL);
	picture = 2;
	UpdateAllViews(NULL);
OnPicture():
	picture = 0;
	UpdateAllViews(NULL);
	picture = 1;
	UpdateAllViews(NULL);
  1. 并在视图类补充完成OnDraw()函数:对应OnDraw()文件前使用extern int picture;
CDraw1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	if (picture == 1) {
		CPen pen(NULL, 1, RGB(0, 0, 0));
		pDC->SelectObject(&pen);
		// 画矩形
		pDC->Rectangle(20, 20, 120, 120);
		// 画刷
		CBrush brush(RGB(255, 0, 0));
		pDC->SelectObject(&brush);
		pDC->Rectangle(20, 20, 120, 120);
	}
	if (picture == 2) {
		CFont *OldFont, NewFont1;
		NewFont1.CreatePointFont(200, "宋体", NULL);
		OldFont = pDC->SelectObject(&NewFont1);
		pDC->TextOut(0,60, "菜单设计程序");
		pDC->SelectObject (OldFont);
		NewFont1.DeleteObject();
	}

2.工具栏:为应用程序添加两个工具栏按钮,单击第一个按钮,在视图中弹出“打开”对话框;单击第二个按钮,在消息框中显示“工具栏设计程序”

  1. 在ResourceView中的ToorBar资源完成新的工具栏的定义与属性ID的定义(ID_OPEN与ID_SHOW)
  2. 在建立类向导中的Doc类中选择对应ID,并添加ONCOMMAND函数:OnOpen()与OnShow()函数
OnOpen()AfxMessageBox("打开");
	UpdateAllViews(NULL);
OnShow()AfxMessageBox("工具栏设计程序");
	UpdateAllViews(NULL);

实验五:模态对话框与非模态对话框
1.模态对话框:编写一个 SDI 应用程序,执行某一菜单命令时打开一个模态对话框,在对话框中输入一对坐标值,单击 OK 按钮后在视图中该坐标位置显示自己的姓名。

  1. 新建一个Dialog资源,向其添加文本和编辑框控件并修改ID(IDC_EDIT1)
  2. 添加与控件关联的成员变量。启动类向导,单击Member Variables标签。在Class name下拉框选择新建的Dialog资源类,在Control IDs栏选择自己设定好的编辑框资源ID,单击Add Variable按钮。通过 Add Member Variable对话框添加成员变量m_Coor,类型为CString
  3. 为了在视图对象中接收并存储编辑控件的值,在C****View中手 工定义一个CString类型的成员变量str,并新建int x与int y进行坐标的获取
  4. 利用菜单编辑器在“编辑”菜单增加一个菜单项“输入坐标”,其ID标识 为ID_INPUTCOOR。启动ClassWzard类向导,在视图类中为菜单项添加消息COMMAND的处理函数(注意这里对CString类型转换处理int)
COMMAND()函数:
CCoorDialog dlg; // 定义一个对话框对象
	dlg.m_Coor = "50,50"; // 设置编辑框显示的初始值
	if (dlg.DoModal()==IDOK) // 显示对话框
	{
		str = dlg.m_Coor; // 接收并存储编辑框数据
		Invalidate(); // 刷新视图
	}
	int n = str.ReverseFind('.'); 
	CString x_str = str.Left(str.GetLength() - n - 1);
	CString y_str = str.Right(str.GetLength() - n - 1);
	sscanf(x_str,"%d",&x); // 将字符串转为已定义的int x坐标
	sscanf(y_str,"%d",&y);
  1. 在View类的OnDraw()函数中完成名字绘制
OnDraw()函数:
	CString name = "MT";
	CFont *OldFont, NewFont;
	LOGFONT MyFont = {30, 10, 0, 0, 0, 1, 1, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "黑体" };
	NewFont.CreateFont (30, 10, 0, 0, FW_HEAVY, false, false, false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "大号字");
	OldFont = pDC->SelectObject(&NewFont); // 这里使用从窗口获得的x与y
	pDC->TextOut(x, y, name);
	pDC->SelectObject(OldFont);
	NewFont.DeleteObject(); 
  1. 在****View.cpp中添加#include “自定义类.h”

2.非模态对话框:编写一个 SDI 应用程序,执行某一菜单命令时打开一个非模态对话框,在对话框中输入一对坐标值,单击 OK 按钮后在视图中该坐标位置显示自己的学号

  1. 新建一个Dialog资源,向其添加文本和编辑框控件并修改ID
  2. 添加与控件关联的成员变量。定义为m_Coor,CString类型
  3. 在视图类添加一个与成员变量完全相同的变量CString m_Coor,否则无法完成绑定
  4. 在 C***View视图类中增加新建类指针类型的公有成员变量 m_pDlg。在***View.h文件的头部预编译命令之前增加类的前向声明语如下: class C新建类; class C***Doc;
  5. 在自定义类中增加C***View指针类型的公有成员变量m_pParent,再在当前文件中添加class C***View 并在自定义类类的构造函数中添加该变量初始化语句m_pParent=(C**View)pParent; 在自定义类.h文件的头部预编译命令之前增加类的前向声明语句:class C***View;
  6. 在***View.cpp文件的头部所有的include语句之后添加对话框类的头文件。#include “自定义类.h”
  7. 增加菜单项使用菜单编辑器在主菜单中增加一个【对话框】菜单项,并在其中添加【非模态对话框】菜单项,其ID为ID_NOMODEDLG,用ClassWizard在视图类中为ID_NOMODEDLG菜单项添加COMMAND消息的处理函数,在OnNomodedlg()函数中添加如下代码
	if(!m_pDlg)
		m_pDlg->SetActiveWindow();//激活非模态对话框
	else
	{
		//创建非模态对话框
		m_pDlg = new CCoorDialog(this); //创建对话框对象
		m_pDlg->m_pParent = this;//获取主窗口视图指针
		m_pDlg->Create(IDD_DIALOG1, this); //创建对话框
		m_pDlg->ShowWindow(SW_SHOW); //显示对话框
	}
Invalidate();
  1. 在自定义类.cpp文件的头部所有的include语句之后添加视图类的头文件。#include “***View.h”
  2. 利用ClassWizard为对话框中的确定和取消按钮添加处理函数
OnOk():
	CDialog::OnOK();
	CClientDC dc(m_pParent);
	UpdateData(true); //获取用户数据
	// 更新用户数据
	int n = m_Coor.ReverseFind('.'); 
	CString x_str = m_Coor.Left(m_Coor.GetLength() - n - 1);
	CString y_str = m_Coor.Right(m_Coor.GetLength() - n - 1);
	int x, y;
	sscanf(x_str,"%d",&x); // 将字符串转为已定义的int x坐标
	sscanf(y_str,"%d",&y);

	CString name = "123456789";
	
	dc.TextOut(x, y, name, name.GetLength());
	
OnCancel():
	CDialog::OnCancel();
	if(m_pParent!=NULL) {
		m_pParent->m_pDlg = NULL;//表明对话框对象已不存在了
		DestroyWindow(); //删除对话框窗口 
	}
  1. 利用ClassWizard在对话框类”C自定义类”中添加PostNcDestroy消息,并添加如下代码:
	CDialog::PostNcDestroy();
	delete this;//删除对话框对象

实验六:编写一个单文档应用程序,用菜单栏打开一个对话框,通过该对话框中的红色、绿色和蓝色复选按钮选择颜色,在视图中绘制不同颜色矩形

  1. 新建一个Dialog资源,向其添加复选框并修改ID
  2. 添加与控件关联的成员变量。启动类向导,单击Member Variables标签。在Class name下拉框选择新建一个Dialog资源类,在Control IDs栏选择自己设定好的编辑框资源ID,单击Add Variable按钮。通过 Add Member Variable添加成员变量m_Red, m_Green,m_Blue均为BOOL
  3. 为了在视图对象中接收并存储编辑控件的值,在C****View中手 工定义三个BOOL类型的m_Red, m_Green,m_Blue
  4. 利用菜单编辑器在“编辑”菜单增加一个菜单项“矩形”,其ID标识为 ID_INPUTT。启动ClassWzard类向导,在视图类中为菜单项添加消息COMMAND的处理函数
	CTColorDialog dlg;		// 定义一个对话框对象,重定义需要修改
	dlg.m_Red = true;		// 设置编辑框显示的初始值
	if (dlg.DoModal()  ==  IDOK) // 显示对话框
	{
		m_Red = dlg.m_Red;	// 接收并存储编辑框数据
		m_Green = dlg.m_Green;
		m_Blue = dlg.m_Blue;

		flag = 3;			// 更新视图,避免非法显示,如果使用flag = 1 改变int flag;会产生奇怪的错误

		Invalidate();		// 刷新视图
	}
  1. 在View类的OnDraw()函数中完成图形绘制
	if(flag == 3) {
		CPen pen(NULL, 1, RGB(0, 0, 0));
		pDC->SelectObject(&pen);

		if (m_Red) {
			// 画矩形1
			pDC->Rectangle(20, 20, 120, 120); // 四个参数分别为对应的两组坐标,左上和右下
			// 画刷
			CBrush brush(RGB(255, 0, 0));
			pDC->SelectObject(&brush);
			pDC->Rectangle(20, 20, 120, 120);

			pDC->SelectObject(&pen);
		}

		if (m_Blue) {
			pDC->Rectangle(280, 20, 380, 120);
			// 画刷
			CBrush brush(RGB(0, 0, 255));
			pDC->SelectObject(&brush);
			pDC->Rectangle(280, 20, 380, 120);

			pDC->SelectObject(&pen);
		}

		if (m_Green) {
			pDC->Rectangle(150, 20, 250, 120);
			// 画刷
			CBrush brush(RGB(0, 255, 0));
			pDC->SelectObject(&brush);
			pDC->Rectangle(150, 20, 250, 120);

			pDC->SelectObject(&pen);
		}
	}
  1. 在****View.cpp中添加#include “自定义类.h”
  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值