一、设计目的
通过对操作系统启动过程的模拟,以及软件功能设计与实现,进一步理解和掌握《操作系统》中学习到的各个功能模块的原理和用法,提高自己的系统设计能力。
二、编程环境
硬件环境:计算机,无特殊配置要求
软件环境:QEMU虚拟机、批处理文件、相关编译工具等
语言环境:C语言、汇编语言
三、功能简介
- 进入开机过程,维持10s左右,显示开机进度;
- 开机之后进入密码输入界面:密码最长为10个字符,如果输入密码正确则进入桌面,若密码错误则打印“Error”提示语,并给用户再次输入密码的机会;
- 进入桌面后:桌面有一个文本快捷图标,右下角显示时间
对于文本的功能有:
(1)编辑窗口未打开时一直按住鼠标左键可随意拖动图标;编辑窗口打开时只能在窗口之外的区域拖动图标;
(2)双击图标,打开文本,桌面下方显示表示文本正在运行的小窗口,进入文本编辑状态,初始为默认大小,可移动、最大 化、还原、最小化以及关闭窗口;
(3)文本编辑状态下可进行按键输入、退格删除,当关闭编辑窗口时,若文本内容没有更新则直接关闭,若有更新,则用户 可选择保存或不保存,然后再关闭,一旦退出编辑状态,运行窗口也跟着关闭。
四、设计思路、代码以及运行效果
(一)实验设计思路以及部分代码
实验的设计思路基本按照上述中的功能框架来设计代码的,其余就是细节问题。
1、首先将程序运行窗口分成3种状态(对应boot_flag的不同值):
0--开机启动界面; 1--密码输入界面; 2--用户桌面;
对于这三种状态都是共享一个背景图层,然后明确整个程序总共需要7个图层,然后针对这3种状态依次设计每种状态下的图层变化情况;然后需要明确总共需要4个定时器,但有的定时器并不只是在某个界面下使用,比如第3个定时器(timer3),在密码输入界面作为光标闪烁的定时器,同样在桌面的文本编辑状态也是作为光标闪烁的定时器。
Boot_flag的变化情况:初始为0
2、开机界面: 只有一个背景图层
定义一个10ms的定时器以及一个记录启动进度的变量,每隔10ms就加1直到加到100即10s,关闭该定时器,进入密码输入界面;
3、密码输入界面:有两个图层--背景图层和密码输入窗口图层
该界面的背景图层颜色为亮蓝色同时会动态显示一个圆,圆的大小、颜色和位置不定,显示的间隔时间为1.5s,在显示新的圆的时候只需要刷新显示前后两次的区域即可:
密码长度最大为10即10个字符(空格也算1个字符),按下【Backspace】进行删除之前输入的字符,输入的密码超过10个字符之后就无法继续输入按下【Enter】键确认密码;密码输入错误则提示“Error”,提示信息显示大概0.8s左右,显示期间禁止输入密码,信息消失后才能重新输入密码;我的密码设置为********,输入正确后进入用户桌面;
4、用户桌面:进入用户桌面后,在任务栏的右下角显示实时时间
(1)桌面有一个文本图标,任务栏右下角显示时间;打开文本前可通过长按鼠标左键将该图标拖动到桌面(任务栏上方)任意位置;文本打开后只能在编辑窗口之外拖动文本图标;
(2)鼠标双击图标打开文本编辑窗口,两次双击的间隔时间必须少于1s才可以打开,而且必须都必须是双击图标位置,双击打开文本编辑窗口的时候在任务栏也会跟着显示表示文本正在运行的运行窗口;
(3)打开文本编辑窗口之后进入文本编辑状态:可进行输入,当输入的字符超过一行之后会自动换行,按下【backspace】删除字符,最多输入的字符为240个即输满默认大小的编辑窗口;
(4)最大化/最小化/还原/关闭/拖动功能(文本编辑窗口都是利用1个图层实现的):
关闭:当关闭编辑窗口时,若文本内容没有更新则直接关闭(即不会出现提示是否保存的从窗口);若有更新,则用户可选择保存或不保存,然后再关闭,一旦退出编辑状态,任务栏中的运行窗口也跟着关闭,若关闭的时候选择不保存则再次打开的时候是上一次保存的状态,若关闭的时候选择了保存则再次打开的时候是刚刚保存的状态;而且若是关闭前处于最大化状态则先变成默认窗口再关闭(不过这个过程是不可见的);由于用户输入的时候就是保存到文本的缓冲区中了所以选择保存的时候直接关闭窗口即可。
对于不保存的情况:
最小化:用户选择最小化之后,单击任务栏中表示文本正在运行的运行窗口则回到最小化时的编辑窗口;
拖动功能:只有当鼠标移动到编辑窗口的名称栏时长按鼠标左键才可拖动窗口,其他情况下不能拖动窗口;
其他小细节:当鼠标移动到关闭/最大化/还原区域时,该区域的背景色改变表示选定,离开该区域时又切换回原来的背景色,此时只需要刷新该图层的关闭/最大化/还原区域即可,而不是刷新整个图层。
(二)运行结果
部分截图如下:
详细演示视频:
链接:https://pan.baidu.com/s/1hwWrysJpv9yLFTkbDcT0pA
提取码:cgos
五、遇见的问题 以及解决方法
问题:实现文本快捷窗口的相关功能时,通过每按下1次鼠标左键,记录鼠标左键按下的次数left_count就加1,然后判断增加的次数来实现双击打开,最后却发现在长按鼠标左键并移动鼠标以拖动文本快捷窗口在桌面的位置时,会与双击打开的功能冲突。
分析过程:通过在屏幕上显示left_count的值来观察该值的变化,发现长按鼠标并同时移动鼠标的过程是“按下-->移动-->按下-->移动”循环交替的过程,程序会认为这个循环过程中的鼠标按下操作中有多个两次连续点击鼠标左键的操作而非一直按着鼠标,也就是有双击打开的功能
解决方法:只在鼠标未移动位置的情况下记录鼠标按下左键的次数left_count同通过该变量的值记录前后两次按下时的时间timerctl.count,当间隔时间少于1s时则认为双击鼠标,这样双击图标和拖动图标的功能就不会冲突了。