因项目代码过长,本文将介绍主要类的设计,所有代码都基于这几个类进行继承
目录
工具类
Ctool.h
工具类,实现画边框、光标跳转、键盘按键获取
#pragma once
#include <conio.h>
/*
宏定义
*/
#define KEY_UP -1
#define KEY_DOWN -2
#define KEY_LEFT -3
#define KEY_RIGHT -4
class Ctool //工具类
{
public:
/*
函数功能:
按照给定参数画出边框、设置为静态函数方便每个类中调用此函数,无返回值
函数参数:
x 边框起始x坐标
y 边框起始y坐标
w 边框宽度
h 边框高度
*/
static void PaintWindow(int x, int y, int w, int h); //画边框
/*
函数功能:
光标移动,将光标停留在编辑框或者按钮位置
函数参数:
x 要跳转到的x坐标
y 要跳转到的y坐标
*/
static void gotoxy(int x, int y); //移动光标
/*
函数功能:获取键盘中输入的按键
函数参数:无参
*/
static int getKey(); //获取按键
};
Ctool.c
#include "Ctool.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
void Ctool::PaintWindow(int x, int y, int w, int h) //打印窗口 可以设置窗口大小 用户登录系统窗口
{
int i = 0;//循环变量i初始化
//打印顶部
//光标定位 找规律 ┗ ┛ ┏ ┓ ┃ ━
//顶部 y行不变 x 列在变 (x到x+width)
gotoxy(x, y); //光标起始
printf("┏"); //光标起始定位先打印左上角
for (i = 0; i < w - 2; i++) //控制循环次数width-2次 打印顶部
{
Sleep(0.5);
printf("━ ");
}
printf("┓");
//左边 x列不变 y行在变 (y到y+height) 打印左竖线
for (i = 1; i <= h - 1; i++) //竖线这边i初始值为1(第一行打过了) <=
{
gotoxy(x, y + i);//打印左竖线时光标一直移动 Y行在变
Sleep(0.5);
printf("┃"); //打印左竖线
}
//右边 x不变 =startx+width-1(x列) y在变 y 到 y+height(y行)右竖线
for (i = 1; i <= h - 1; i++)//竖线这边i初始值为1(第一行打过了) <=
{
gotoxy(x + w * 2 - 3, y + i);// startx+(width-1)*2-1 宽一//个横杠两个字符 横杠中文字符占两列
Sleep(0.5);
printf("┃"); //打印右竖线
}
//底部 x在变化 y不变 (x到x+width) ━ 打印
gotoxy(x, y + h - 1);//找到左下角
printf("┗");//打印左下角
for (i = 0; i < w - 2; i++) //打印底部 打印横杠
{
Sleep(0.5);
printf("━ ");
}
printf("┛");//打印右下角
gotoxy(x, x + h);
}
void Ctool::gotoxy(int x, int y)
{
COORD coord = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
int Ctool::getKey()
{
int key = _getch();
if (key == 224) //方向按键
{
key = _getch();
if (key == 72)
{
return KEY_UP;
}
else if (key == 80)
{
return KEY_DOWN;
}
else if (key == 75)
{
return KEY_LEFT;
}
else if (key == 77)
{
return KEY_RIGHT;
}
}
else
{
return key;
}
}
控件类
控件类包括了界面中用到的标签、编辑框、按钮
CtrlBase.h
#pragma once
#include <string.h>
class CtrlBase
{
public:
CtrlBase(int x = 0, int y = 0, int w = 0, int h = 0, const char* content = nullptr,int type = 1, int role = 0); //带参构造函数 type:1 标签 2 编辑框 3 按钮
virtual void show(); //显示控件
virtual void keyListen(char key){} //按键监听
int getX(); //获取控件的x坐标
int getY(); //获取控件的y坐标
int getrole()
{
return role;
}
int getType() //获取控件的类型
{
return type;
}
void clear() //清空编辑框内容
{
memset(content, 0, sizeof(content));
}
char *getContent() //获取编辑框内容
{
return this->content;
}
protected:
int x, y, w, h;
char content[50];
int type; //1 标签 2 编辑框 3 按钮
int role; //1 管理员 2 医生 3 患者
};
CtrlBase.c
#define _CRT_SECURE_NO_WARNINGS
#include "CtrlBase.h"
#include "Label.h"
#include <string.h>
#include <windows.h>
#include <iostream>
#include "Ctool.h"
using namespace std;
CtrlBase::CtrlBase(int x, int y, int w, int h, const char* content, int type, int role)
{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->type = type;
this->role = role;
memset(this->content, 0, sizeof(this->content)); // 初始化字符串
if (content != nullptr)
{
strcpy(this->content, content);
}
}
void CtrlBase::show()
{
if (this->type == 1)
{
//改变光标位置
Ctool::gotoxy(x, y);
//输出内容
cout << content << endl;
}
else if (this->type == 3)
{
//改变光标位置
Ctool::PaintWindow(x, y, w, h);
Ctool::gotoxy(x + (w * 2 - strlen(content)) / 2 - 1, y + 1);
//输出内容
cout << content << endl;
}
else
{
Ctool::PaintWindow(x - 1, y - 1, w, h);
Ctool::gotoxy(x, y);
cout << this->content << endl;
}
}
int CtrlBase::getX()
{
return this->x;
}
int CtrlBase::getY()
{
return this->y;
}
标签类
Label.h
#pragma once //相当于条件编译的三行
#include "CtrlBase.h"
class Label : public CtrlBase
{
public:
Label(int x = 0, int y = 0, int width = 0, int height = 0, const char* content = nullptr); //带参构造函数
void show(); //显示
protected:
};
Label.c
#define _CRT_SECURE_NO_WARNINGS
#include "Label.h"
#include <string.h>
#include <windows.h>
#include <iostream>
#include "Ctool.h"
using namespace std;
Label::Label(int x, int y, int width, int height, const char* content)
:CtrlBase(x, y, width, height, content,1)
{
}
void Label:: show()
{
//改变光标位置
Ctool::gotoxy(x, y);
//输出内容
cout << content << endl;
}
Cbutton.h
#pragma once
#include "CtrlBase.h"
class Cbuttun : public CtrlBase
{
public:
Cbuttun(int x = 0, int y = 0, int w = 0, int h = 0, const char* content = "Button"); //带参构造函数
protected:
};
Cbutton.c
#define _CRT_SECURE_NO_WARNINGS
#include "Cbuttun.h"
#include <string.h>
#include <iostream>
#include <windows.h>
#include "Ctool.h"
using namespace std;
Cbuttun::Cbuttun(int x, int y, int w, int h, const char* content)
:CtrlBase(x, y, w, h, content,3)
{
}
Cedit.h
#pragma once
#include "CtrlBase.h"
class Cedit :public CtrlBase
{
public:
Cedit(int x = 0, int y = 0, int w = 0, int h = 0, const char* content = nullptr, int type = 0, int maxLen = 0, int ips = 0); //带参构造函数
void keyListen(char key); //键盘监听
protected:
int maxLen;
int ips;
int type;
};
Cedit.c
#define _CRT_SECURE_NO_WARNINGS
#include "Cedit.h"
#include <iostream>
#include <string>
#include "Ctool.h"
using namespace std;
Cedit::Cedit(int x, int y, int w , int h, const char* content, int type,int maxLen, int ips):CtrlBase(x, y, w, h, content,2)
{
this->maxLen = maxLen;
this->ips = ips;
this->type = type;
}
void Cedit::keyListen(char key)
{
int count = strlen(this->content);
if (count == this->maxLen)
{
return;
}
else
{
if (this->type == 0) //数字
{
if (key >= '0' && key <= '9')
{
if (ips == 0)
{
_putch(key);
}
else
{
_putch('*');
}
this->content[count] = key;
}
else if(key == '\b')
{
if (count > 0)
{
this->content[count - 1] = '\0';
count--;
printf("\b \b");
}
}
}
else if (this->type == 1) //字母
{
if (key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z')
{
if (ips == 0)
{
_putch(key);
}
else
{
_putch('*');
}
this->content[count] = key;
}
else if (key == '\b')
{
if (count > 0)
{
this->content[count - 1] = '\0';
count--;
printf("\b \b");
}
}
}
else if (this->type == 2) //字母和数字
{
if (key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z' || key >= '0' && key <= '9')
{
if (ips == 0)
{
_putch(key);
}
else
{
_putch('*');
}
this->content[count] = key;
}
else if (key == '\b')
{
if (count > 0)
{
this->content[count - 1] = '\0';
count--;
printf("\b \b");
}
}
}
else if (this->type == 3) //中文
{
if ((unsigned char)key >= 0xA1 && (unsigned char)key <= 0xFE)
{
char key2 = _getch();
if ((unsigned char)key2 >= 0xA1 && (unsigned char)key2 <= 0xFE)
{
this->content[count++] = key;
this->content[count++] = key2;
if (this->ips == 0)
{
printf("%c%c", key, key2);
}
else
{
printf("**");
}
}
}
else if (key == '\b')
{
if (count > 0)
{
this->content[count - 1] = '\0';
count--;
printf("\b \b");
}
}
}
}
}
界面类
ScreenBase.h
#pragma once
#include "CtrlBase.h"
#include <vector>
#include <iostream>
#include "Ctool.h"
using namespace std;
class screenBase
{
public:
screenBase(int x = 0, int y = 0, int w = 0, int h = 0, int index = 0); //构造函数
void show(); //显示界面
void run(); //光标移动
virtual int doaction() = 0; //界面操作
protected:
int x, y, w, h;
int index;
vector<CtrlBase*> Screen; //保存界面中的按键、标签、编辑框
};
ScreenBase.c
#include "screenBase.h"
#include "Cedit.h"
screenBase::screenBase(int x, int y, int w, int h, int index)
{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->index = index;
this->Screen.clear();
}
void screenBase::show()
{
Ctool::PaintWindow(this->x, this->y, this->w, this->h);
for (int i = 0; i < this->Screen.size(); i++)
{
this->Screen.at(i)->show();
}
}
void screenBase::run()
{
//找编辑框或者是按钮,让光标可以停下来
int i = 0;
char key;
for (i = 0; i < this->Screen.size(); i++)
{
if (this->Screen.at(i)->getType() == 2) //编辑框
{
Ctool::gotoxy(this->Screen.at(i)->getX(), this->Screen.at(i)->getY());
break;
}
else if (this->Screen.at(i)->getType() == 3)//按钮
{
Ctool::gotoxy(this->Screen.at(i)->getX() + 2, this->Screen.at(i)->getY() + 1);
break;
}
}
//输入: 光标可以切换、编辑框做输入、按钮可以按回车
while (1)
{
key = Ctool::getKey();
switch (key)
{
case KEY_DOWN://光标一定要切换位置,定位到下一个编辑框或者按钮的位置上
//从上面定位好的位置开始继续往后面找,索引++
i++;
if (i == this->Screen.size()) //已经到最后
{
i = 0;//从头开始继续找
}
for (; i < this->Screen.size(); i++)
{
if (this->Screen.at(i)->getType() == 2) //编辑框
{
Ctool::gotoxy(this->Screen.at(i)->getX(), this->Screen.at(i)->getY());
break;
}
else if (this->Screen.at(i)->getType() == 3)//按钮
{
Ctool::gotoxy(this->Screen.at(i)->getX() + 2, this->Screen.at(i)->getY() + 1);
break;
}
if (i == this->Screen.size() - 1)
{
i = -1;
}
}
break;
case KEY_UP:
i--;
if (i < 0)
{
i = this->Screen.size() - 1;
}
for (; i >= 0; i--)
{
if (this->Screen.at(i)->getType() == 2) //编辑框
{
Ctool::gotoxy(this->Screen.at(i)->getX(), this->Screen.at(i)->getY());
break;
}
else if (this->Screen.at(i)->getType() == 3)//按钮
{
Ctool::gotoxy(this->Screen.at(i)->getX() + 2, this->Screen.at(i)->getY() + 1);
break;
}
if (i == 0)
{
i = this->Screen.size();
}
}
break;
case 13: //回车,按钮的业务
if (this->Screen.at(i)->getType() == 3) //按钮
{
this->index = i;
//去做业务处理
return;
}
break;
default: //编辑框的输入
if (this->Screen.at(i)->getType() == 2) //编辑框
{
this->Screen.at(i)->keyListen(key);
}
break;
}
}
}
代码量过长,剩余的管理员模块、医生模块、用户模块下一篇更新
源码---->