中国体彩投注系统演示界面设计说明书MiniGUI版需求分析1.docx
- 文档编号:4791622
- 上传时间:2022-12-09
- 格式:DOCX
- 页数:15
- 大小:22.93KB
中国体彩投注系统演示界面设计说明书MiniGUI版需求分析1.docx
《中国体彩投注系统演示界面设计说明书MiniGUI版需求分析1.docx》由会员分享,可在线阅读,更多相关《中国体彩投注系统演示界面设计说明书MiniGUI版需求分析1.docx(15页珍藏版)》请在冰豆网上搜索。
中国体彩投注系统演示界面设计说明书MiniGUI版需求分析1
中国体彩投注系统演示界面设计说明书
(MiniGUI版)
一、需求分析:
1.有登录界面,需用户输入代号和密码,输入正确方可进入系统。
代号由体彩中心指定,密码可自行修改。
2.支持键盘选择、切换功能。
包括选择菜单、菜单项,选择各个按钮,在各控件间进行切换。
3.状态栏显示当前日期和时间,标题栏显示当前进行操作的销售员的代号。
4.要体现硬件设计的特点。
具体为:
要能够启动网卡和Modem的接收和传输功能;能够打印样票。
二、概要设计:
1.模块划分:
1主窗口:
包含标题栏、状态栏、各菜单项;
2菜单:
其他:
修改密码、打印、帮助、退出;
文件传输:
网卡传输、Modem传输;
文件接收:
启动网卡接收、停止网卡接收、启动Modem接收;开始时停止网卡接收菜单项显灰(不可用),启动网卡接收时,该菜单项变灰(不可用),停止网卡接收菜单项被激活。
报表:
日报表、班报表、时段报表。
(该功能暂不实现,菜单项显灰)。
3修改密码对话框:
要求输入旧密码,新密码,确认新密码。
按确定提交新密码,按取消不修改密码。
4打印消息框:
提示打印机是否准备好,准备好则调用打印样票程序。
5帮助消息框:
给出一些版本信息。
6退出消息框:
提示用户是否决定要退出系统,是则退出系统,关机。
7网卡传输对话框:
要求用户输入IP地址号和要传输的文件名,文件名可用文件选择对话框进行选择。
8Modem传输对话框:
要求用户输入电话号码和要传输的文件名,文件名可用文件选择对话框进行选择。
9Modem传输/接收状态框:
在用户选择该项功能时,弹出提示,表明该项功能正在进行中。
10系统登录对话框:
要求用户输入正确的销售员代号和密码。
取消则退出系统,关机。
三、详细设计:
1.主窗口:
用MiniGUIMain搭建主窗口框架,指定主窗口消息处理函数,指定菜单创建函数,建立主窗口消息循环。
因为要在标题栏中显示当前操作员的代号,故需将系统登录时输入的销售员代号做为全局变量,在给窗口标题栏赋值时加入。
在建立主窗口框架之前先显示登录对话框。
由于在主窗口内建立状态栏比较困难,故考虑“借用”开发平台mginit的状态栏,具体实现详见“系统配置”。
2.各菜单的建立:
先创建各菜单项,再创建菜单条。
其中,需要显灰的菜单项,给MENUITEMINFO结构的state成员赋值为1,其余赋值为0。
3.创建各对话框:
使用DLGTEMPLATE结构创建各对话框,再在CTRLDATA结构中为对话框创建各控件。
在DisplayDialog中为对话框指定该对话框的控件属性和对话框处理函数。
4.以上实现可详见代码部分。
以下为开发中的几处难点:
1绘制菜单条的边框:
在主窗口处理过程(MainWinProc)中添加MSG_PAINT消息:
hdc=GetDC(hWnd);
Draw3DUpThinFrame(hdc,4,26,188,55,PIXEL_invalid);
Draw3DUpThinFrame(hdc,189,26,399,55,PIXEL_invalid);
Draw3DUpThinFrame(hdc,400,26,610,55,PIXEL_invalid);
Draw3DUpThinFrame(hdc,611,26,795,55,PIXEL_invalid);
ReleaseDC(hdc);
2使用键盘键选择菜单:
由于MiniGUI的快捷键功能存在Bug,故需自己进行一些处理以实现键盘选择菜单的功能。
在MainWinProc函数的MSG_KEYDOWN消息中添加:
caseSCANCODE_F1:
TrackMenuBar(hWnd,0);
break;
caseSCANCODE_F2:
TrackMenuBar(hWnd,1);
break;
caseSCANCODE_F3:
TrackMenuBar(hWnd,2);
break;
caseSCANCODE_F4:
TrackMenuBar(hWnd,3);
break;
即可实现键盘键与菜单项一一对应。
其中TrackMenuBar(hWnd,pos)函数中的pos参数可用0,1,2…来表示菜单条的第1、2、3…项。
各下拉菜单项的键盘选择功能实现详见“系统配置”。
3Modem传输/接收状态窗:
分别创建两个窗口(MR.c---Modem接收、MT.c---Modem传输)。
以Modem传输为例,在用户按下Modem传输对话框的确定按钮时,先隐藏该对话框,然后生成传输状态窗口,提示用户传输正在进行,之后调用Modem传输程序send_modem,传输结束之后隐藏状态窗口,弹出消息框,返回主函数之后再关闭掉Modem传输对话框。
此处难点在于该状态窗口是以窗口的形式还是对话框的形式创建。
若用对话框的形式创建,那么必须有一个消息触发才能调用send_modem函数,而状态窗口除了MSG_CREATE和MSG_CLOSE消息,是不需要响应别的消息的,但是在这两个消息中调用send_modem都不合适。
而使用窗口创建的话,只要在窗口创建之后调用send_modem就可以。
具体见代码部分。
4编辑框的子类化:
有一些编辑框需要限制其输入,如IP地址编辑框、电话号码编辑框、密码编辑框和销售员代号编辑框等。
应注意以下两点:
a.创建对话框中的控件可不用在CTRLDATACtrlInitProgress中完成,可在对话框消息处理函数中响应MSG_CREATE消息,用CreateWindow的方法生成,这样以生成控件句柄,好进行控制;
b.不能如此生成所有控件,必须在CtrlInitProgress中生成至少一个以上控件。
(即该结构不能是空的)
子类化代码部分详见代码(eig.c)中1152行DigitEdit函数部分,该函数屏蔽掉了除数字和小数点之外的所有键盘输入。
还有一些编辑框须控制其输入长度,可在生成编辑框之后发送EM_LIMITTEXT消息,如:
SendMessage(hEdit,EM_LIMITTEXT,6,0)。
5菜单条显灰:
可调用EnableMenuItem(hmnu,item,flag)函数,其中flag为TRUE时则显灰(该菜单不可用)。
6登录系统代号和密码的获取:
采用文件来存放销售员的代码,故每次登录时需要读文件,在用户修改密码时还要写文件。
代号和密码按行写,必须都为六位数字,代号和密码之间以“|”分隔,不同用户之间以“&”分隔,并换行。
读密码文件的函数是第1229行(eig.c)findkey。
使用一个循环,当未遇到换行符时,将一行字符(包括用户代号和密码)存入一个字符数组中,然后比较数组的前六位是否与用户输入的销售员代号相等,相等则继续判断数组的第七位起后六位(密码)是否相等,否则读取文件下一行,即下一个用户代号和密码。
(因为代号和密码都是指定长度,故可知其在数组的哪个位置上。
)
当代号和密码都相等时,返回1,登录系统;否则返回0,可继续输入。
写密码文件的函数是第1266行的ChangePWD。
首先与都密码文件相似,先要判断输入的旧密码是否与原密码相等,不等则不允许修改;其次,判断两次输入密码是否一致,密码位数是否小于6位;最后,若符合修改要求,用fseek(fp,-8L,1)在文件中定位,指定密码写入文件的位置,确保将原密码覆盖,再用fputs(tmp,fp)将新密码写入文件。
7杀死文件接收进程和退出mginit系统:
在第1170行的ExeclSys函数中,使用了系统调用来杀死进程。
(ExitSys---退出系统也类似)。
首先调用“ps-Crecvf-opid=>num”来获得进程号,并将其输出到num文件中,然后从该文件中读出进程号i,再调用killi来杀死进程。
至此,代码部分基本结束。
四、系统配置:
在开发过程中不仅写了大量的代码,还对MiniGUI系统的源代码做了很多修改,以达到完善我们的界面的目的。
现将所作修改一一列出备案。
在该文件中主要是针对菜单快捷键做改动。
原系统中选择下拉菜单中的菜单项只能用上下方向键来选择,而需求分析中指出,下拉菜单的选择要实现用数字键来控制。
如按1键选择第一个菜单项,按2键则选择第二个菜单项。
在menu.c的第2143行的staticvoidmnuTrackMenuWithKey(PTRACKMENUINFOptmi,intmessage,intscan,DWORDstatus)函数,就是处理按键选择菜单的函数。
在原函数中,按下上下方向键则会调用mnuGetNextMenuItem(pcurtmi,pcurmi)或mnuGetPrevMenuItem(pcurtmi,pcurmi)函数以获得当前所选菜单项的上一个或下一个菜单。
需要加入自己的处理代码,使数字按键和各菜单项一一对应起来。
考虑目前项目的实际情况,设定下拉菜单的最大数目为8项。
定义一个PMENUITEM数组,除掉分隔条,将菜单项链表中的结点(即各菜单项)存入数组中。
具体代码如下:
(在第2178行加入)
PMENUITEMmitem[8];
PMENUITEMhead;
inti=0;
//将当前弹出下拉菜单的标题栏赋值给head
head=pcurtmi->pmi;
//放入数组的第一个单元
mitem[0]=head;
//如果该菜单有下拉菜单,则将第一个菜单项放入数组的第二个单元
if(head->type==TYPE_PPPMENU)
{
head=head->submenu;
mitem[1]=head;
}
i=1;
//当菜单项非空且少于8个时,依次将链表中结点放入数组
while((head->next!
=NULL)&&i<8)
{
i++;
//跳过分隔条
while(head->next&&(head->next->mnutype&MFT_SEPARATOR))
head->next=head->next->next;
mitem[i]=head->next;
head=head->next;
}
处理按键消息,将各数字键与菜单项一一对应:
if(message==MSG_KEYDOWN)
{
switch(scan)
{
caseSCANCODE_1:
caseSCANCODE_2:
caseSCANCODE_3:
caseSCANCODE_4:
caseSCANCODE_5:
caseSCANCODE_6:
caseSCANCODE_7:
if(scan==SCANCODE_1)
{
/*如果下拉菜单数目不少于1个
*则按键后将要指向的菜单赋值为
*数组的第一个值*/
if(i>=1)
pnewmi=mitem[1];
/*否则指向空,若不指向空,该指针
*指向未知区域,会出错*/
else
pnewmi=NULL;
}
//下同
elseif(scan==SCANCODE_2)
{
if(i>=2)
pnewmi=mitem[2];
else
pnewmi=NULL;
}
elseif(scan==SCANCODE_3)
{
if(i>=3)
pnewmi=mitem[3];
else
pnewmi=NULL;
}
elseif(scan==SCANCODE_4)
{
if(i>=4)
pnewmi=mitem[4];
else
pnewmi=NULL;
}
elseif(scan==SCANCODE_5)
{
if(i>=5)
pnewmi=mitem[5];
else
pnewmi=NULL;
}
elseif(scan==SCANCODE_6)
{
if(i>=6)
pnewmi=mitem[6];
else
pnewmi=NULL;
}
elseif(scan==SCANCODE_7)
{
if(i>=7)
pnewmi=mitem[7];
else
pnewmi=NULL;
}
if(pnewmi==NULL)
break;
//若将选中菜单不是当前菜单
if(pnewmi!
=pcurmi)
{
//当前菜单恢复不被选中状态
if(pcurmi)
mnuHiliteMenuItem(pcurtmi,
pcurmi,FALSE);
/*将选中菜单置为选中状态,同时将当前菜
*单置为选中菜单*/
if(pnewmi)
{
mnuHiliteMenuItem(pcurtmi,
pnewmi,TRUE);
pcurtmi->philite=pnewmi;
}
}
break;
选中菜单后要执行该菜单项的操作,在第2369行中加入代码:
elseif(message==MSG_KEYUP)
{
switch(scan)
{
caseSCANCODE_1:
caseSCANCODE_2:
caseSCANCODE_3:
caseSCANCODE_4:
caseSCANCODE_5:
caseSCANCODE_6:
caseSCANCODE_7:
//菜单项为空、分隔条、显灰时返回
if(pcurmi==NULL)return;
if(pcurmi->mnutype&MFT_SEPARATOR)return;
if(pcurmi->mnustate&MFS_DISABLED)return;
//有第三级菜单时弹出
if(pcurmi->submenu)
{
mnuOpenNewSubMenu(pcurtmi,
pcurmi->submenu,
pcurtmi->rc.right,
mnuGetMenuItemY(pcurtmi,pcurmi));
return;
}
if(pcurmi&&pcurmi->type!
=TYPE_PPPMENU&&
pcurmi->submenu==NULL)
{
hwnd=ptmi->hwnd;
id=pcurmi->id;
//关闭菜单
SendMessage(HWND_DESKTOP,MSG_CLOSEMENU,0,1);
if(flags&TPM_SYSCMD)
//执行系统命令
SendNotifyMessage(hwnd,MSG_SYSCOMMAND,id,0);
else
//执行菜单命令
SendNotifyMessage(hwnd,MSG_COMMAND,id,0);
if(flags&TPM_DESTROY)
//销毁菜单
DestroyMenu(hmnu);
}
break;
由于对系统字体做了更改,而控件大小并未相应改动,文件打开对话框是做为控件调用的,故要对其大小进行更改。
第126行:
returnOpenFileDialogEx(hWnd,50,50,330,280,pmwfi);
同上。
第557行:
intOpenFileDialogEx(HWNDhWnd,intlx,intty,intw,inth,PFILEDLGDATApfdi)
intLstH多减掉10。
以下代码注意控件大小及坐标的变化:
CTRLDATAWinFileCtrl[]=
{
{"button",WS_VISIBLE|WS_TABSTOP,
2*SPACE_WIDTH+totalW*2/5,SPACE_HEIGHT,90,28,
IDC_UP,"上一级目录",0},
{"listbox",WS_VISIBLE|WS_TABSTOP|LBS_NOTIFY|WS_VSCROLL|WS_BORDER|LBS_SORT,
SPACE_WIDTH+10,LstTY+10,totalW*2/5,LstH,IDC_DIRCHOISE,NULL,0},
{"listbox",WS_VISIBLE|WS_TABSTOP|LBS_NOTIFY|WS_VSCROLL|WS_BORDER|LBS_SORT,
2*SPACE_WIDTH+totalW*2/5+30,LstTY+10,totalW*3/5,LstH,IDC_FILECHOISE,NULL,0},
{"static",WS_VISIBLE|SS_LEFT,
SPACE_WIDTH+10,LstH+LstTY+SPACE_HEIGHT+10,4*GetSysCCharWidth()+30,GetSysCharHeight()+10,IDC_STATIC1,"当前路径",0},
{"static",WS_VISIBLE|SS_LEFT,
2*SPACE_WIDTH+4*GetSysCCharWidth()+50,LstH+LstTY+SPACE_HEIGHT+10,totalW-4*GetSysCCharWidth()-3*SPACE_WIDTH,GetSysCharHeight()+10,IDC_PATH,"",0},
{"static",WS_VISIBLE|SS_LEFT,
SPACE_WIDTH+10,LstH+LstTY+2*SPACE_HEIGHT+GetSysCharHeight()+30,2*GetSysCCharWidth()+20,GetSysCharHeight()+10,IDC_STATIC2,"文件",0},
{"edit",WS_VISIBLE|WS_TABSTOP|WS_BORDER|LBS_NOTIFY,
2*SPACE_WIDTH+2*GetSysCCharWidth()+40,LstH+LstTY+2*SPACE_HEIGHT+GetSysCharHeight()+30,totalW-2*GetSysCCharWidth()-3*SPACE_WIDTH,21,IDC_FILENAME,NULL,0},
{"button",WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON|WS_GROUP,
(totalW-2*40)*2/5+SPACE_WIDTH,LstH+LstTY+3*SPACE_HEIGHT+GetSysCharHeight()+55,70,28,IDOK,"确认",0},
{"button",WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,
(totalW-2*40)*3/5+2*SPACE_WIDTH+40,LstH+LstTY+3*SPACE_HEIGHT+GetSysCharHeight()+55,70,28,IDCANCEL,"取消",0}
};
DLGTEMPLATEWinFileDlg={
WS_BORDER|WS_CAPTION|WS_MINIMIZEBOX,WS_EX_NONE,
lx,ty,w+40,h+40,NULL,0,0,9,NULL};
该文件更改如下:
[mginit]
nr=1
autostart=0
[app0]
path=../EIGdemo/
name=eig
layer=
tip=EIGdemo
icon=res/kcmx.gif
nr是在mginit的状态栏上放应用程序的图标的个数,autostart是启动mginit时,第几个应用程序就自动运行。
Path是该应用程序的存放路径,name是该应用程序的名称,layer是该应用程序所在的层数,tip是当鼠标放在图标上时显示的提示,icon是图标的存放位置。
启动mginit的主函数。
由于自己没有做出状态栏,故需要使用其中的状态栏。
第156行staticvoidon_change_layer(intop,MG_Layer*layer,MG_Client*client),将该函数屏蔽掉。
这样状态栏上就不会显示应用程序的层。
将第245行屏蔽掉。
不再调用on_change_layer函数。
将第263、264行屏蔽掉,不再弹出系统提示对话框。
第252行改动如下:
if(SetDesktopRect(0,g_rcScr.bottom-HEIGHT_TASKBAR,
g_rcScr.right,g_rcScr.bottom)==0)
不再减去输入法框所占空间(本程序中不需使用输入法)。
定义状态栏的各控件的ID和大小,改动如下,注意大小的改动:
#defineHEIGHT_TASKBAR35
#define_ID_TIME_STATIC110
#define_ID_LABEL_STATIC130
#define_ID_LAYER_BOX200
#define_MARGIN2
#define_HEIGHT_CTRL28
#define_WIDTH_TIME270
#define_WIDTH_APPS150
#define_ID_TIMER50
生成状态栏。
改动其代码,定制自己所需要的状态栏。
加入日期,第49行:
staticchar*Xinqi[]={
"日",
"一",
"二",
"三",
"四",
"五",
"六",
};
第67行:
sprintf(buff,"%d年%02d月%02d日星期%s%02d:
%02d:
%02d",tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,Xinqi[tm->tm_wday],tm->tm_hour,tm->tm_min,tm->tm_sec);
生成公司名称窗口、日期时间窗口,屏蔽掉工具栏窗口、“start”窗口:
staticintTaskBarWinProc(HWNDhWnd,intmessage,WPARAMwParam,LPARAMlParam)函数中屏蔽掉第242行:
/*CreateWindow(CTRL_BUTTON,"Start",WS_CHILD|WS_VISIBLE,_ID_START_BUTTON,_MARGIN,_MARGIN,_WIDTH_START,_HEIGHT_CTRL,h
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 中国 体彩 投注 系统 演示 界面设计 说明书 MiniGUI 需求 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)