#include"hospital.h"

int main()
{
    COORD size={SCR_COL,SCR_ROW};        /*设置缓冲区大小*/

    gh_std_out=GetStdHandle(STD_OUTPUT_HANDLE);  /*获取输出句柄*/
    gh_std_in=GetStdHandle(STD_INPUT_HANDLE);     /*获取输入句柄*/

    SetConsoleTitle(gp_sys_name);             /*设置窗口标题*/
    SetConsoleScreenBufferSize(gh_std_out,size); /*设置窗口缓冲区大小100*35*/
    InitInterface();          /*界面初始化*/
    RunSys();
    CloseSys();
    return 0;
}
/***********************************************************************************************************************************************************
********************************************************************菜单函数部分****************************************************************************

/**
*函数名称：ShowMenu
*函数功能：在屏幕上显示主菜单，并设置热区，在主菜单第一项上置选中标记
*输入参数：无
*输出参数：无
*返回值*无
*调用说明：
*/
void ShowMenu()
{
    CONSOLE_SCREEN_BUFFER_INFO bInfo;
    CONSOLE_CURSOR_INFO lpCur;
    COORD size;
    COORD pos={0,0};
    int i,j;
    int PosA=2,PosB;
    char ch;
    GetConsoleScreenBufferInfo(gh_std_out,&bInfo);
    size.X=bInfo.dwSize.X;
    size.Y=1;
    SetConsoleCursorPosition(gh_std_out,pos);
    for(i=0;i<7;i++)/*在窗口第一行第一列处输出主菜单项*/
    {
        printf("    %s",ga_main_menu[i]);
    }
    GetConsoleCursorInfo(gh_std_out,&lpCur);
    lpCur.bVisible=FALSE;
    SetConsoleCursorInfo(gh_std_out,&lpCur);/*隐藏光标*/

    /*申请动态储存区作为存放菜单条屏幕区字符信息的缓冲区*/
    gp_buff_menubar_info=(CHAR_INFO *)malloc(size.X*size.Y*sizeof(CHAR_INFO));
    SMALL_RECT rcMenu ={0, 0, size.X-1, 0} ;

    /*将窗口第一行的内容读入到存放菜单条屏幕区字符信息的缓冲区中*/
    ReadConsoleOutput(gh_std_out, gp_buff_menubar_info, size, pos, &rcMenu);

    /*将这一行中英文字母置为红色，其他字符单元置为白底黑字*/
    for (i=0; i<size.X; i++)
    {
        (gp_buff_menubar_info+i)->Attributes = BACKGROUND_BLUE | BACKGROUND_GREEN
                                               | BACKGROUND_RED;
        ch = (char)((gp_buff_menubar_info+i)->Char.AsciiChar);
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
        {
            (gp_buff_menubar_info+i)->Attributes |= FOREGROUND_RED;
        }
    }

    /*修改后的菜单条字符信息回写到窗口的第一行*/
    WriteConsoleOutput(gh_std_out, gp_buff_menubar_info, size, pos, &rcMenu);
    COORD endPos = {0, 1};
    SetConsoleCursorPosition(gh_std_out, endPos);  /*将光标位置设置在第2行第1列*/

    /*将菜单项置为热区，热区编号为菜单项号，热区类型为0(按钮型)*/
    i = 0;
    do
    {
        PosB = PosA + strlen(ga_main_menu[i]);  /*定位第i+1号菜单项的起止位置*/
        for (j=PosA; j<PosB; j++)
        {
            gp_scr_att[j] |= (i+1) << 2; /*设置菜单项所在字符单元的属性值*/
        }
        PosA = PosB + 4;
        i++;
    } while (i<7);

    TagMainMenu(gi_sel_menu);  /*在选中主菜单项上做标记，gi_sel_menu初值为1*/

    return;
}
/**
 * 函数名称: PopMenu
 * 函数功能: 弹出指定主菜单项对应的子菜单.
 * 输入参数: num 指定的主菜单项号
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void PopMenu(int num)
{
    LABEL_BUNDLE labels;
    HOT_AREA areas;
    SMALL_RECT rcPop;
    COORD pos;
    WORD att;
    char *pCh;
    int i, j, loc = 0;

    if (num != gi_sel_menu)       /*如果指定主菜单不是已选中菜单*/
    {
        if (gp_top_layer->LayerNo != 0) /*如果此前已有子菜单弹出*/
        {
            PopOff();
            gi_sel_sub_menu = 0;
        }
    }
    else if (gp_top_layer->LayerNo != 0) /*若已弹出该子菜单，则返回*/
    {
        return;
    }

    gi_sel_menu = num;    /*将选中主菜单项置为指定的主菜单项*/
    TagMainMenu(gi_sel_menu); /*在选中的主菜单项上做标记*/
    LocSubMenu(gi_sel_menu, &rcPop); /*计算弹出子菜单的区域位置, 存放在rcPop中*/

    /*计算该子菜单中的第一项在子菜单字符串数组中的位置(下标)*/
    for (i=1; i<gi_sel_menu; i++)
    {
        loc += ga_sub_menu_count[i-1];
    }
    /*将该组子菜单项项名存入标签束结构变量*/
    labels.ppLabel = ga_sub_menu + loc;   /*标签束第一个标签字符串的地址*/
    labels.num = ga_sub_menu_count[gi_sel_menu-1]; /*标签束中标签字符串的个数*/
    COORD aLoc[labels.num];/*定义一个坐标数组，存放每个标签字符串输出位置的坐标*/
    for (i=0; i<labels.num; i++) /*确定标签字符串的输出位置，存放在坐标数组中*/
    {
        aLoc[i].X = rcPop.Left + 2;
        aLoc[i].Y = rcPop.Top + i + 1;
    }
    labels.pLoc = aLoc; /*使标签束结构变量labels的成员pLoc指向坐标数组的首元素*/
    /*设置热区信息*/
    areas.num = labels.num;       /*热区的个数，等于标签的个数，即子菜单的项数*/
    SMALL_RECT aArea[areas.num];                    /*定义数组存放所有热区位置*/
    char aSort[areas.num];                      /*定义数组存放所有热区对应类别*/
    char aTag[areas.num];                         /*定义数组存放每个热区的编号*/
    for (i=0; i<areas.num; i++)
    {
        aArea[i].Left = rcPop.Left + 2;  /*热区定位*/
        aArea[i].Top = rcPop.Top + i + 1;
        aArea[i].Right = rcPop.Right - 2;
        aArea[i].Bottom = aArea[i].Top;
        aSort[i] = 0;       /*热区类别都为0(按钮型)*/
        aTag[i] = i + 1;           /*热区按顺序编号*/
    }
    areas.pArea = aArea;/*使热区结构变量areas的成员pArea指向热区位置数组首元素*/
    areas.pSort = aSort;/*使热区结构变量areas的成员pSort指向热区类别数组首元素*/
    areas.pTag = aTag;   /*使热区结构变量areas的成员pTag指向热区编号数组首元素*/

    att = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;  /*白底黑字*/
    PopUp(&rcPop, att, &labels, &areas);
    DrawBox(&rcPop);  /*给弹出窗口画边框*/
    pos.X = rcPop.Left + 2;
    for (pos.Y=rcPop.Top+1; pos.Y<rcPop.Bottom; pos.Y++)
    { /*此循环用来在空串子菜项位置画线形成分隔，并取消此菜单项的热区属性*/
        pCh = ga_sub_menu[loc+pos.Y-rcPop.Top-1];
        if (strlen(pCh)==0) /*串长为0，表明为空串*/
        {   /*首先画横线*/
            FillConsoleOutputCharacter(gh_std_out, '-', rcPop.Right-rcPop.Left-3, pos, &num_written);
            for (j=rcPop.Left+2; j<rcPop.Right-1; j++)
            {   /*取消该区域字符单元的热区属性*/
                gp_scr_att[pos.Y*SCR_COL+j] &=3; /*按位与的结果保留了低两位*/
            }
        }

    }
    /*将子菜单项的功能键设为白底红字*/
    pos.X = rcPop.Left + 3;
    att =  FOREGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
    for (pos.Y=rcPop.Top+1; pos.Y<rcPop.Bottom; pos.Y++)
    {
        if (strlen(ga_sub_menu[loc+pos.Y-rcPop.Top-1])==0)
        {
            continue;  /*跳过空串*/
        }
        FillConsoleOutputAttribute(gh_std_out, att, 1, pos, &num_written);
    }
    return;
}
/**
 * 函数名称: PopUp
 * 函数功能: 在指定区域输出弹出窗口信息, 同时设置热区, 将弹出窗口位置信息入栈.
 * 输入参数: pRc 弹出窗口位置数据存放的地址
 *           att 弹出窗口区域字符属性
 *           pLabel 弹出窗口中标签束信息存放的地址
             pHotArea 弹出窗口中热区信息存放的地址
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void PopUp(SMALL_RECT *pRc, WORD att, LABEL_BUNDLE *pLabel, HOT_AREA *pHotArea)
{
    LAYER_NODE *nextLayer;
    COORD size;
    COORD pos = {0, 0};
    char *pCh;
    int i, j, row;

    /*弹出窗口所在位置字符单元信息入栈*/
    size.X = pRc->Right - pRc->Left + 1;    /*弹出窗口的宽度*/
    size.Y = pRc->Bottom - pRc->Top + 1;    /*弹出窗口的高度*/
    /*申请存放弹出窗口相关信息的动态存储区*/
    nextLayer = (LAYER_NODE *)malloc(sizeof(LAYER_NODE));
    nextLayer->next = gp_top_layer;
    nextLayer->LayerNo = gp_top_layer->LayerNo + 1;
    nextLayer->rcArea = *pRc;
    nextLayer->pContent = (CHAR_INFO *)malloc(size.X*size.Y*sizeof(CHAR_INFO));
    nextLayer->pScrAtt = (char *)malloc(size.X*size.Y*sizeof(char));
    pCh = nextLayer->pScrAtt;
    /*将弹出窗口覆盖区域的字符信息保存，用于在关闭弹出窗口时恢复原样*/
    ReadConsoleOutput(gh_std_out, nextLayer->pContent, size, pos, pRc);
    for (i=pRc->Top; i<=pRc->Bottom; i++)
    {   /*此二重循环将所覆盖字符单元的原先属性值存入动态存储区，便于以后恢复*/
        for (j=pRc->Left; j<=pRc->Right; j++)
        {
            *pCh = gp_scr_att[i*SCR_COL+j];
            pCh++;
        }
    }
    gp_top_layer = nextLayer;  /*完成弹出窗口相关信息入栈操作*/
    /*设置弹出窗口区域字符的新属性*/
    pos.X = pRc->Left;
    pos.Y = pRc->Top;
    for (i=pRc->Top; i<=pRc->Bottom; i++)
    {
        FillConsoleOutputAttribute(gh_std_out, att, size.X, pos, &num_written);
        pos.Y++;
    }
    /*将标签束中的标签字符串在设定的位置输出*/
    for (i=0; i<pLabel->num; i++)
    {
        pCh = pLabel->ppLabel[i];
        if (strlen(pCh) != 0)
        {
            WriteConsoleOutputCharacter(gh_std_out, pCh, strlen(pCh),
                                        pLabel->pLoc[i], &num_written);
        }
    }
    /*设置弹出窗口区域字符单元的新属性*/
    for (i=pRc->Top; i<=pRc->Bottom; i++)
    {   /*此二重循环设置字符单元的层号*/
        for (j=pRc->Left; j<=pRc->Right; j++)
        {
            gp_scr_att[i*SCR_COL+j] = gp_top_layer->LayerNo;
        }
    }

    for (i=0; i<pHotArea->num; i++)
    {   /*此二重循环设置所有热区中字符单元的热区类型和热区编号*/
        row = pHotArea->pArea[i].Top;
        for (j=pHotArea->pArea[i].Left; j<=pHotArea->pArea[i].Right; j++)
        {
            gp_scr_att[row*SCR_COL+j] |= (pHotArea->pSort[i] << 6)
                                    | (pHotArea->pTag[i] << 2);
        }
    }
    return;
}
/**
 * 函数名称: PopOff
 * 函数功能: 关闭顶层弹出窗口, 恢复覆盖区域原外观和字符单元原属性.
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void PopOff(void)
{
    LAYER_NODE *nextLayer;
    COORD size;
    COORD pos = {0, 0};
    char *pCh;
    int i, j;

    if ((gp_top_layer->next==NULL) || (gp_top_layer->pContent==NULL))
    {   /*栈底存放的主界面屏幕信息，不用关闭*/
        return;
    }
    nextLayer = gp_top_layer->next;
    /*恢复弹出窗口区域原外观*/
    size.X = gp_top_layer->rcArea.Right - gp_top_layer->rcArea.Left + 1;
    size.Y = gp_top_layer->rcArea.Bottom - gp_top_layer->rcArea.Top + 1;
    WriteConsoleOutput(gh_std_out, gp_top_layer->pContent, size, pos, &(gp_top_layer->rcArea));
    /*恢复字符单元原属性*/
    pCh = gp_top_layer->pScrAtt;
    for (i=gp_top_layer->rcArea.Top; i<=gp_top_layer->rcArea.Bottom; i++)
    {
        for (j=gp_top_layer->rcArea.Left; j<=gp_top_layer->rcArea.Right; j++)
        {
            gp_scr_att[i*SCR_COL+j] = *pCh;
            pCh++;
        }
    }
    free(gp_top_layer->pContent);    /*释放动态存储区*/
    free(gp_top_layer->pScrAtt);
    free(gp_top_layer);
    gp_top_layer = nextLayer;
    gi_sel_sub_menu = 0;
    return;
}
/**
 * 函数名称: DrawBox
 * 函数功能: 在指定区域画边框.
 * 输入参数: pRc 存放区域位置信息的地址
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void DrawBox(SMALL_RECT *pRc)
{
    char chBox[] = {'+','-','|'};  /*画框用的字符*/
    COORD pos = {pRc->Left, pRc->Top};  /*定位在区域的左上角*/

    WriteConsoleOutputCharacter(gh_std_out, &chBox[0], 1, pos, &num_written);/*画边框左上角*/
    for (pos.X = pRc->Left + 1; pos.X < pRc->Right; pos.X++)
    {   /*此循环画上边框横线*/
        WriteConsoleOutputCharacter(gh_std_out, &chBox[1], 1, pos, &num_written);
    }
    pos.X = pRc->Right;
    WriteConsoleOutputCharacter(gh_std_out, &chBox[0], 1, pos, &num_written);/*画边框右上角*/
    for (pos.Y = pRc->Top+1; pos.Y < pRc->Bottom; pos.Y++)
    {   /*此循环画边框左边线和右边线*/
        pos.X = pRc->Left;
        WriteConsoleOutputCharacter(gh_std_out, &chBox[2], 1, pos, &num_written);
        pos.X = pRc->Right;
        WriteConsoleOutputCharacter(gh_std_out, &chBox[2], 1, pos, &num_written);
    }
    pos.X = pRc->Left;
    pos.Y = pRc->Bottom;
    WriteConsoleOutputCharacter(gh_std_out, &chBox[0], 1, pos, &num_written);/*画边框左下角*/
    for (pos.X = pRc->Left + 1; pos.X < pRc->Right; pos.X++)
    {   /*画下边框横线*/
        WriteConsoleOutputCharacter(gh_std_out, &chBox[1], 1, pos, &num_written);
    }
    pos.X = pRc->Right;
    WriteConsoleOutputCharacter(gh_std_out, &chBox[0], 1, pos, &num_written);/*画边框右下角*/
    return;
}
/**
 * 函数名称: TagMainMenu
 * 函数功能: 在指定主菜单项上置选中标志
 * 输入参数: num 选中的主菜单项号
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void TagMainMenu(int num)
{
    CONSOLE_SCREEN_BUFFER_INFO bInfo;
    COORD size;
    COORD pos = {0, 0};
    int PosA = 2, PosB;
    char ch;
    int i;

    if (num == 0) /*num为0时，将会去除主菜单项选中标记*/
    {
        PosA = 0;
        PosB = 0;
    }
    else  /*否则，定位选中主菜单项的起止位置: PosA为起始位置, PosB为截止位置*/
    {
        for (i=1; i<num; i++)
        {
            PosA += strlen(ga_main_menu[i-1]) + 4;
        }
        PosB = PosA + strlen(ga_main_menu[num-1]);
    }

    GetConsoleScreenBufferInfo( gh_std_out, &bInfo );
    size.X = bInfo.dwSize.X;
    size.Y = 1;

    /*去除选中菜单项前面的菜单项选中标记*/
    for (i=0; i<PosA; i++)
    {
        (gp_buff_menubar_info+i)->Attributes = BACKGROUND_BLUE | BACKGROUND_GREEN
                                               | BACKGROUND_RED;
        ch = (gp_buff_menubar_info+i)->Char.AsciiChar;
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
        {
            (gp_buff_menubar_info+i)->Attributes |= FOREGROUND_RED;
        }
    }

    /*在选中菜单项上做标记，黑底白字*/
    for (i=PosA; i<PosB; i++)
    {
        (gp_buff_menubar_info+i)->Attributes = FOREGROUND_BLUE | FOREGROUND_GREEN
                                               | FOREGROUND_RED;
    }

    /*去除选中菜单项后面的菜单项选中标记*/
    for (i=PosB; i<bInfo.dwSize.X; i++)
    {
        (gp_buff_menubar_info+i)->Attributes = BACKGROUND_BLUE | BACKGROUND_GREEN
                                               | BACKGROUND_RED;
        ch = (char)((gp_buff_menubar_info+i)->Char.AsciiChar);
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
        {
            (gp_buff_menubar_info+i)->Attributes |= FOREGROUND_RED;
        }
    }

    /*将做好标记的菜单条信息写到窗口第一行*/
    SMALL_RECT rcMenu ={0, 0, size.X-1, 0};
    WriteConsoleOutput(gh_std_out, gp_buff_menubar_info, size, pos, &rcMenu);

    return;
}
/**
 * 函数名称: TagSubMenu
 * 函数功能: 在指定子菜单项上做选中标记.
 * 输入参数: num 选中的子菜单项号
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void TagSubMenu(int num)
{
    SMALL_RECT rcPop;
    COORD pos;
    WORD att;
    int width;

    LocSubMenu(gi_sel_menu, &rcPop);  /*计算弹出子菜单的区域位置, 存放在rcPop中*/
    if ((num<1) || (num == gi_sel_sub_menu) || (num>rcPop.Bottom-rcPop.Top-1))
    {   /*如果子菜单项号越界，或该项子菜单已被选中，则返回*/
        return;
    }

    pos.X = rcPop.Left + 2;
    width = rcPop.Right - rcPop.Left - 3;
    if (gi_sel_sub_menu != 0) /*首先取消原选中子菜单项上的标记*/
    {
        pos.Y = rcPop.Top + gi_sel_sub_menu;
        att = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;  /*白底黑字*/
        FillConsoleOutputAttribute(gh_std_out, att, width, pos, &num_written);
        pos.X += 1;
        att |=  FOREGROUND_RED;/*白底红字*/
        FillConsoleOutputAttribute(gh_std_out, att, 1, pos, &num_written);
    }
    /*在制定子菜单项上做选中标记*/
    pos.X = rcPop.Left + 2;
    pos.Y = rcPop.Top + num;
    att = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;  /*黑底白字*/
    FillConsoleOutputAttribute(gh_std_out, att, width, pos, &num_written);
    gi_sel_sub_menu = num;  /*修改选中子菜单项号*/
    return;
}
/**
 * 函数名称: LocSubMenu
 * 函数功能: 计算弹出子菜单区域左上角和右下角的位置.
 * 输入参数: num 选中的主菜单项号
 * 输出参数: rc 存放区域位置信息的地址
 * 返 回 值: 无
 *
 * 调用说明:
 */
void LocSubMenu(int num, SMALL_RECT *rc)
{
    int i, len, loc = 0;

    rc->Top = 1; /*区域的上边定在第2行，行号为1*/
    rc->Left = 1;
    for (i=1; i<num; i++)
    {   /*计算区域左边界位置, 同时计算第一个子菜单项在子菜单字符串数组中的位置*/
        rc->Left += strlen(ga_main_menu[i-1]) + 4;
        loc += ga_sub_menu_count[i-1];
    }
    rc->Right = strlen(ga_sub_menu[loc]);/*暂时存放第一个子菜单项字符串长度*/
    for (i=1; i<ga_sub_menu_count[num-1]; i++)
    {   /*查找最长子菜单字符串，将其长度存放在rc->Right*/
        len = strlen(ga_sub_menu[loc+i]);
        if (rc->Right < len)
        {
            rc->Right = len;
        }
    }
    rc->Right += rc->Left + 3;  /*计算区域的右边界*/
    rc->Bottom = rc->Top + ga_sub_menu_count[num-1] + 1;/*计算区域下边的行号*/
    if (rc->Right >= SCR_COL)  /*右边界越界的处理*/
    {
        len = rc->Right - SCR_COL + 1;
        rc->Left -= len;
        rc->Right = SCR_COL - 1;
    }
    return;
}
/**
 * 函数名称: ClearScreen
 * 函数功能: 清除屏幕信息.
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void ClearScreen()
{
    CONSOLE_SCREEN_BUFFER_INFO bInfo;
    COORD home = {0, 0};
    unsigned long size;

    GetConsoleScreenBufferInfo( gh_std_out, &bInfo );/*取屏幕缓冲区信息*/
    size =  bInfo.dwSize.X * bInfo.dwSize.Y; /*计算屏幕缓冲区字符单元数*/

    /*将屏幕缓冲区所有单元的字符属性设置为当前屏幕缓冲区字符属性*/
    FillConsoleOutputAttribute(gh_std_out, bInfo.wAttributes, size, home, &num_written);

    /*将屏幕缓冲区所有单元填充为空格字符*/
    FillConsoleOutputCharacter(gh_std_out, ' ', size, home, &num_written);

    return;
}
/**
 * 函数名称: InitInterface
 * 函数功能: 初始化界面.
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void InitInterface()
{
    WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
               | BACKGROUND_BLUE;  /*黄色前景和蓝色背景*/

    SetConsoleTextAttribute(gh_std_out, att);  /*设置控制台屏幕缓冲区字符属性*/

    ClearScreen();  /* 清屏*/

    /*创建弹出窗口信息堆栈，将初始化后的屏幕窗口当作第一层弹出窗口*/
    gp_scr_att = (char *)calloc(SCR_COL * SCR_ROW, sizeof(char));/*屏幕字符属性*/
    gp_top_layer = (LAYER_NODE *)malloc(sizeof(LAYER_NODE));
    gp_top_layer->LayerNo = 0;      /*弹出窗口的层号为0*/
    gp_top_layer->rcArea.Left = 0;  /*弹出窗口的区域为整个屏幕窗口*/
    gp_top_layer->rcArea.Top = 0;
    gp_top_layer->rcArea.Right = SCR_COL - 1;
    gp_top_layer->rcArea.Bottom = SCR_ROW - 1;
    gp_top_layer->pContent = NULL;
    gp_top_layer->pScrAtt = gp_scr_att;
    gp_top_layer->next = NULL;

    ShowMenu();     /*显示菜单栏*/
    ShowState();    /*显示状态栏*/

    return;
}
/**
 * 函数名称: ShowState
 * 函数功能: 显示状态条.
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明: 状态条字符属性为白底黑字, 初始状态无状态信息.
 */
void ShowState()
{
    CONSOLE_SCREEN_BUFFER_INFO bInfo;
    COORD size;
    COORD pos = {0, 0};
    int i;

    GetConsoleScreenBufferInfo( gh_std_out, &bInfo );
    size.X = bInfo.dwSize.X;
    size.Y = 1;
    SMALL_RECT rcMenu ={0, bInfo.dwSize.Y-1, size.X-1, bInfo.dwSize.Y-1};

    if (gp_buff_stateBar_info == NULL)
    {
        gp_buff_stateBar_info = (CHAR_INFO *)malloc(size.X * size.Y * sizeof(CHAR_INFO));
        ReadConsoleOutput(gh_std_out, gp_buff_stateBar_info, size, pos, &rcMenu);
    }

    for (i=0; i<size.X; i++)
    {
        (gp_buff_stateBar_info+i)->Attributes = BACKGROUND_BLUE | BACKGROUND_GREEN
                                                | BACKGROUND_RED;
    }

    WriteConsoleOutput(gh_std_out, gp_buff_stateBar_info, size, pos, &rcMenu);

    return;
}
/**
 * 函数名称: RunSys
 * 函数功能: 运行系统, 在系统主界面下运行用户所选择的功能模块.
 * 输入参数: 无
 * 输出参数: phead 主链头指针的地址
 * 返 回 值: 无
 *
 * 调用说明:
 */
void RunSys()
{
    INPUT_RECORD inRec;
    DWORD res;
    COORD pos = {0, 0};
    BOOL bRet = TRUE;
    int i, loc, num;
    int cNo, cAtt;      /*cNo:字符单元层号, cAtt:字符单元属性*/
    char vkc, asc;      /*vkc:虚拟键代码, asc:字符的ASCII码值*/

    while (bRet)
    {
        /*从控制台输入缓冲区中读一条记录*/
        ReadConsoleInput(gh_std_in, &inRec, 1, &res);

        if (inRec.EventType == MOUSE_EVENT) /*如果记录由鼠标事件产生*/
        {
            pos = inRec.Event.MouseEvent.dwMousePosition;  /*获取鼠标坐标位置*/
            cNo = gp_scr_att[pos.Y * SCR_COL + pos.X] & 3; /*取该位置的层号*/
            cAtt = gp_scr_att[pos.Y * SCR_COL + pos.X] >> 2;/*取该字符单元属性*/
            if (cNo == 0) /*层号为0，表明该位置未被弹出子菜单覆盖*/
            {
                /* cAtt > 0 表明该位置处于热区(主菜单项字符单元)
                 * cAtt != gi_sel_menu 表明该位置的主菜单项未被选中
                 * gp_top_layer->LayerNo > 0 表明当前有子菜单弹出
                 */
                if (cAtt > 0 && cAtt != gi_sel_menu && gp_top_layer->LayerNo > 0)
                {
                    PopOff();            /*关闭弹出的子菜单*/
                    gi_sel_sub_menu = 0; /*将选中子菜单项的项号置为0*/
                    PopMenu(cAtt);       /*弹出鼠标所在主菜单项对应的子菜单*/
                }
            }
            else if (cAtt > 0) /*鼠标所在位置为弹出子菜单的菜单项字符单元*/
            {
                TagSubMenu(cAtt); /*在该子菜单项上做选中标记*/
            }

            if (inRec.Event.MouseEvent.dwButtonState
                == FROM_LEFT_1ST_BUTTON_PRESSED) /*如果按下鼠标左边第一键*/
            {
                if (cNo == 0) /*层号为0，表明该位置未被弹出子菜单覆盖*/
                {
                    if (cAtt > 0) /*如果该位置处于热区(主菜单项字符单元)*/
                    {
                        PopMenu(cAtt);   /*弹出鼠标所在主菜单项对应的子菜单*/
                    }
                    /*如果该位置不属于主菜单项字符单元，且有子菜单弹出*/
                    else if (gp_top_layer->LayerNo > 0)
                    {
                        PopOff();            /*关闭弹出的子菜单*/
                        gi_sel_sub_menu = 0; /*将选中子菜单项的项号置为0*/
                    }
                }
                else /*层号不为0，表明该位置被弹出子菜单覆盖*/
                {
                    if (cAtt > 0) /*如果该位置处于热区(子菜单项字符单元)*/
                    {
                        PopOff(); /*关闭弹出的子菜单*/
                        gi_sel_sub_menu = 0; /*将选中子菜单项的项号置为0*/

                        /*执行对应功能函数:gi_sel_menu主菜单项号,cAtt子菜单项号*/
                        bRet = ExeFunction(gi_sel_menu, cAtt);
                    }
                }
            }
            else if (inRec.Event.MouseEvent.dwButtonState
                     == RIGHTMOST_BUTTON_PRESSED) /*如果按下鼠标右键*/
            {
                if (cNo == 0) /*层号为0，表明该位置未被弹出子菜单覆盖*/
                {
                    PopOff();            /*关闭弹出的子菜单*/
                    gi_sel_sub_menu = 0; /*将选中子菜单项的项号置为0*/
                }
            }
        }
        else if (inRec.EventType == KEY_EVENT  /*如果记录由按键产生*/
                 && inRec.Event.KeyEvent.bKeyDown) /*且键被按下*/
        {
            vkc = inRec.Event.KeyEvent.wVirtualKeyCode; /*获取按键的虚拟键码*/
            asc = inRec.Event.KeyEvent.uChar.AsciiChar; /*获取按键的ASC码*/

            /*系统快捷键的处理*/
            if (vkc == 112) /*如果按下F1键*/
            {
                if (gp_top_layer->LayerNo != 0) /*如果当前有子菜单弹出*/
                {
                    PopOff();            /*关闭弹出的子菜单*/
                    gi_sel_sub_menu = 0; /*将选中子菜单项的项号置为0*/
                }
                bRet = ExeFunction(9, 1);  /*运行帮助主题功能函数*/
            }
            else if (inRec.Event.KeyEvent.dwControlKeyState
                     & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
            { /*如果按下左或右Alt键*/
                switch (vkc)  /*判断组合键Alt+字母*/
                {
                    case 88:  /*Alt+X 退出*/
                        if (gp_top_layer->LayerNo != 0)
                        {
                            PopOff();
                            gi_sel_sub_menu = 0;
                        }
                        bRet = ExeFunction(1,7);
                        break;
                    case 70:  /*Alt+F*/
                        PopMenu(1);
                        break;
                    case 65: /*Alt+A*/
                        PopMenu(2);
                        break;
                    case 77: /*Alt+M*/
                        PopMenu(3);
                        break;
                    case 73: /*Alt+I*/
                        PopMenu(4);
                        break;
                    case 68: /*Alt+D*/
                        PopMenu(5);
                        break;
                    case 81: /*Alt+Q*/
                        PopMenu(6);
                        break;
                    case 83: /*Alt+S*/
                        PopMenu(7);
                        break;
                    case  80:/*Alt+P*/
                        PopMenu(8);
                        break;
                    case 72: /*Alt+H*/
                        PopMenu(9);
                        break;
                }
            }
            else if (asc == 0) /*其他控制键的处理*/
            {
                if (gp_top_layer->LayerNo == 0) /*如果未弹出子菜单*/
                {
                    switch (vkc) /*处理方向键(左、右、下)，不响应其他控制键*/
                    {
                        case 37:
                            gi_sel_menu--;
                            if (gi_sel_menu == 0)
                            {
                                gi_sel_menu = 8;
                            }
                            TagMainMenu(gi_sel_menu);
                            break;
                        case 39:
                            gi_sel_menu++;
                            if (gi_sel_menu == 9)
                            {
                                gi_sel_menu = 1;
                            }
                            TagMainMenu(gi_sel_menu);
                            break;
                        case 40:
                            PopMenu(gi_sel_menu);
                            TagSubMenu(1);
                            break;
                    }
                }
                else  /*已弹出子菜单时*/
                {
                    for (loc=0,i=1; i<gi_sel_menu; i++)
                    {
                        loc += ga_sub_menu_count[i-1];
                    }  /*计算该子菜单中的第一项在子菜单字符串数组中的位置(下标)*/
                    switch (vkc) /*方向键(左、右、上、下)的处理*/
                    {
                        case 37:
                            gi_sel_menu--;
                            if (gi_sel_menu < 1)
                            {
                                gi_sel_menu = 8;
                            }
                            TagMainMenu(gi_sel_menu);
                            PopOff();
                            PopMenu(gi_sel_menu);
                            TagSubMenu(1);
                            break;
                        case 38:
                            num = gi_sel_sub_menu - 1;
                            if (num < 1)
                            {
                                num = ga_sub_menu_count[gi_sel_menu-1];
                            }
                            if (strlen(ga_sub_menu[loc+num-1]) == 0)
                            {
                                num--;
                            }
                            TagSubMenu(num);
                            break;
                        case 39:
                            gi_sel_menu++;
                            if (gi_sel_menu > 8)
                            {
                                gi_sel_menu = 1;
                            }
                            TagMainMenu(gi_sel_menu);
                            PopOff();
                            PopMenu(gi_sel_menu);
                            TagSubMenu(1);
                            break;
                        case 40:
                            num = gi_sel_sub_menu + 1;
                            if (num > ga_sub_menu_count[gi_sel_menu-1])
                            {
                                num = 1;
                            }
                            if (strlen(ga_sub_menu[loc+num-1]) == 0)
                            {
                                num++;
                            }
                            TagSubMenu(num);
                            break;
                    }
                }
            }
            else if ((asc-vkc == 0) || (asc-vkc == 32)){  /*按下普通键*/
                if (gp_top_layer->LayerNo == 0)  /*如果未弹出子菜单*/
                {
                    switch (vkc)
                    {
                        case 70: /*f或F*/
                            PopMenu(1);
                            break;
                        case 65: /*a或A*/
                            PopMenu(2);
                            break;
                        case 77: /*m或M*/
                            PopMenu(3);
                            break;
                        case 73: /*i或I*/
                            PopMenu(4);
                            break;
                        case 68: /*d或D*/
                            PopMenu(5);
                            break;
                        case 81: /*q或Q*/
                            PopMenu(6);
                            break;
                        case 83: /*s或S*/
                            PopMenu(7);
                            break;
                        case 80:/*p或P*/
                             PopMenu(8);
                             break;
                        case 72: /*h或H*/
                            PopMenu(8);
                            break;
                        case 13: /*回车*/
                            PopMenu(gi_sel_menu);
                            TagSubMenu(1);
                            break;
                    }
                }
                else /*已弹出子菜单时的键盘输入处理*/
                {
                    if (vkc == 27) /*如果按下ESC键*/
                    {
                        PopOff();
                        gi_sel_sub_menu = 0;
                    }
                    else if(vkc == 13) /*如果按下回车键*/
                    {
                        num = gi_sel_sub_menu;
                        PopOff();
                        gi_sel_sub_menu = 0;
                        bRet = ExeFunction(gi_sel_menu, num);
                    }
                    else /*其他普通键的处理*/
                    {
                        /*计算该子菜单中的第一项在子菜单字符串数组中的位置(下标)*/
                        for (loc=0,i=1; i<gi_sel_menu; i++)
                        {
                            loc += ga_sub_menu_count[i-1];
                        }

                        /*依次与当前子菜单中每一项的代表字符进行比较*/
                        for (i=loc; i<loc+ga_sub_menu_count[gi_sel_menu-1]; i++)
                        {
                            if (strlen(ga_sub_menu[i])>0 && vkc==ga_sub_menu[i][1])
                            { /*如果匹配成功*/
                                PopOff();
                                gi_sel_sub_menu = 0;
                                bRet = ExeFunction(gi_sel_menu, i-loc+1);
                            }
                        }
                    }
                }
            }
        }
    }
}
/**
 * 函数名称: DealConInput
 * 函数功能: 设置虚拟键.
 * 输入参数: pHotArea  piHot
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
 int DealConInput(HOT_AREA *pHotArea, int *piHot)
{
    INPUT_RECORD inRec;
    DWORD res;
    COORD pos = {0, 0};
    int num, arrow, iRet = 0;
    int cNo, cTag, cSort;/*cNo:层号, cTag:热区编号, cSort: 热区类型*/
    char vkc, asc;       /*vkc:虚拟键代码, asc:字符的ASCII码值*/

    SetHotPoint(pHotArea, *piHot);
    while (TRUE)
    {    /*循环*/
        ReadConsoleInput(gh_std_in, &inRec, 1, &res);
        if ((inRec.EventType == MOUSE_EVENT) &&
            (inRec.Event.MouseEvent.dwButtonState
             == FROM_LEFT_1ST_BUTTON_PRESSED))
        {
            pos = inRec.Event.MouseEvent.dwMousePosition;
            cNo = gp_scr_att[pos.Y * SCR_COL + pos.X] & 3;
            cTag = (gp_scr_att[pos.Y * SCR_COL + pos.X] >> 2) & 15;
            cSort = (gp_scr_att[pos.Y * SCR_COL + pos.X] >> 6) & 3;

            if ((cNo == gp_top_layer->LayerNo) && cTag > 0)
            {
                *piHot = cTag;
                SetHotPoint(pHotArea, *piHot);
                if (cSort == 0)
                {
                    iRet = 13;
                    break;
                }
            }
        }
        else if (inRec.EventType == KEY_EVENT && inRec.Event.KeyEvent.bKeyDown)
        {
            vkc = inRec.Event.KeyEvent.wVirtualKeyCode;
            asc = inRec.Event.KeyEvent.uChar.AsciiChar;;
            if (asc == 0)
            {
                arrow = 0;
                switch (vkc)
                {  /*方向键(左、上、右、下)的处理*/
                    case 37: arrow = 1; break;
                    case 38: arrow = 2; break;
                    case 39: arrow = 3; break;
                    case 40: arrow = 4; break;
                }
                if (arrow > 0)
                {
                    num = *piHot;
                    while (TRUE)
                    {
                        if (arrow < 3)
                        {
                            num--;
                        }
                        else
                        {
                            num++;
                        }
                        if ((num < 1) || (num > pHotArea->num) ||
                            ((arrow % 2) && (pHotArea->pArea[num-1].Top
                            == pHotArea->pArea[*piHot-1].Top)) || ((!(arrow % 2))
                            && (pHotArea->pArea[num-1].Top
                            != pHotArea->pArea[*piHot-1].Top)))
                        {
                            break;
                        }
                    }
                    if (num > 0 && num <= pHotArea->num)
                    {
                        *piHot = num;
                        SetHotPoint(pHotArea, *piHot);
                    }
                }
            }
            else if (vkc == 27)
            {  /*ESC键*/
                iRet = 27;
                break;
            }
            else if (vkc == 13 || vkc == 32)
            {  /*回车键或空格表示按下当前按钮*/
                iRet = 13;
                break;
            }
        }
    }
    return iRet;
}
/**
 * 函数名称: SetHotPoint
 * 函数功能: 设置热区.
 * 输入参数: pHotArea  iHot
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void SetHotPoint(HOT_AREA *pHotArea, int iHot)
{
    CONSOLE_CURSOR_INFO lpCur;
    COORD pos = {0, 0};
    WORD att1, att2;
    int i, width;

    att1 = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;  /*黑底白字*/
    att2 = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;  /*白底黑字*/
    for (i=0; i<pHotArea->num; i++)
    {  /*将按钮类热区置为白底黑字*/
        pos.X = pHotArea->pArea[i].Left;
        pos.Y = pHotArea->pArea[i].Top;
        width = pHotArea->pArea[i].Right - pHotArea->pArea[i].Left + 1;
        if (pHotArea->pSort[i] == 0)
        {  /*热区是按钮类*/
            FillConsoleOutputAttribute(gh_std_out, att2, width, pos, &num_written);
        }
    }

    pos.X = pHotArea->pArea[iHot-1].Left;
    pos.Y = pHotArea->pArea[iHot-1].Top;
    width = pHotArea->pArea[iHot-1].Right - pHotArea->pArea[iHot-1].Left + 1;
    if (pHotArea->pSort[iHot-1] == 0)
    {  /*被激活热区是按钮类*/
        FillConsoleOutputAttribute(gh_std_out, att1, width, pos, &num_written);
    }
    else if (pHotArea->pSort[iHot-1] == 1)
    {  /*被激活热区是文本框类*/
        SetConsoleCursorPosition(gh_std_out, pos);
        GetConsoleCursorInfo(gh_std_out, &lpCur);
        lpCur.bVisible = TRUE;
        SetConsoleCursorInfo(gh_std_out, &lpCur);
    }
}
/**
 * 函数名称: ExeFunction
 * 函数功能: 执行由主菜单号和子菜单号确定的功能函数.
 * 输入参数: m 主菜单项号
 *           s 子菜单项号
 * 输出参数: 无
 * 返 回 值: BOOL类型, TRUE 或 FALSE
 *
 * 调用说明: 仅在执行函数ExitSys时, 才可能返回FALSE, 其他情况下总是返回TRUE
 */
BOOL ExeFunction(int m, int s)
{
    BOOL bRet = TRUE;
    /*函数指针数组，用来存放所有功能函数的入口地址*/
    BOOL (*pFunction[ga_sub_menu_count[0]+ga_sub_menu_count[1]+ga_sub_menu_count[2]+ga_sub_menu_count[3]+ga_sub_menu_count[4]
          +ga_sub_menu_count[5]+ga_sub_menu_count[6]+ga_sub_menu_count[7]+ga_sub_menu_count[8]])(void);
    int i, loc;

    /*将功能函数入口地址存入与功能函数所在主菜单号和子菜单号对应下标的数组元素*/
    pFunction[0] = CreateList;
    pFunction[1] = SaveSysData;
//    pFunction[2] = BackupSysData;
//    pFunction[3] = RestoreSysData;
    pFunction[2] = ExitSys;
    pFunction[3] = CreateM;
    pFunction[4] = CreateA;
    pFunction[5] = CreateL;
    pFunction[6] = ModM;
    pFunction[7] = ModA;
    pFunction[8] = ModL;
    pFunction[9] = InserM;
    pFunction[10] = InserA;
    pFunction[11] = InserL;
    pFunction[12] = DeleM;
    pFunction[13] = DeleA;
    pFunction[14] = DeleL;
    pFunction[15] = QueryM;
    pFunction[16] = QueryA;
    pFunction[17] = QueryL;
    pFunction[18] = PutM;
    pFunction[19] = PutA;
    pFunction[20] = PutL;
    pFunction[21] = NULL;
    pFunction[22] = HelpTopic;
    pFunction[23] = About;
    for (i=1,loc=0; i<m; i++)  /*根据主菜单号和子菜单号计算对应下标*/
    {
        loc += ga_sub_menu_count[i-1];
    }
    loc += s - 1;

    if (pFunction[loc] != NULL)
    {
        bRet = (*pFunction[loc])();  /*用函数指针调用所指向的功能函数*/
    }

    return bRet;
}
/***
 * 函数名称: CloseSys
 * 函数功能: 关闭系统.
 * 输入参数: hd 主链头指针
 * 输出参数: 无
 * 返 回 值: 无
 *
 * 调用说明:
 */
BOOL CloseSys()
{
    LABEL_BUNDLE labels;
    HOT_AREA areas;
    BOOL bRet = TRUE;
    SMALL_RECT rcPop;
    COORD pos;
    WORD att;
    char *pCh[] = {"一个窗口样例！退出吗？", "确定    取消"};
    int iHot = 1;

    pos.X = strlen(pCh[0]) + 6;
    pos.Y = 7;
    rcPop.Left = (SCR_COL - pos.X) / 2;
    rcPop.Right = rcPop.Left + pos.X - 1;
    rcPop.Top = (SCR_ROW - pos.Y) / 2;
    rcPop.Bottom = rcPop.Top + pos.Y - 1;

    att = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;  /*白底黑字*/
    labels.num = 2;
    labels.ppLabel = pCh;
    COORD aLoc[] = {{rcPop.Left+3, rcPop.Top+2},
                    {rcPop.Left+5, rcPop.Top+5}};
    labels.pLoc = aLoc;

    areas.num = 2;
    SMALL_RECT aArea[] = {{rcPop.Left + 5, rcPop.Top + 5,
                           rcPop.Left + 8, rcPop.Top + 5},
                          {rcPop.Left + 13, rcPop.Top + 5,
                           rcPop.Left + 16, rcPop.Top + 5}};
    char aSort[] = {0, 0};
    char aTag[] = {1, 2};
    areas.pArea = aArea;
    areas.pSort = aSort;
    areas.pTag = aTag;
    PopUp(&rcPop, att, &labels, &areas);

    pos.X = rcPop.Left + 1;
    pos.Y = rcPop.Top + 4;
    FillConsoleOutputCharacter(gh_std_out, '-', rcPop.Right-rcPop.Left-1, pos, &num_written);

    if (DealConInput(&areas, &iHot) == 13 && iHot == 1)
    {
        bRet = FALSE;
    }
    else
    {
        bRet = TRUE;
    }
    PopOff();

    return bRet;
}

/***********************************************************************************************************************************************************
********************************************************************功能函数部分****************************************************************************
                                                                                                                                        功能函数部分
********************************************************************功能函数部分****************************************************************************
*************************************************************************************************************************************************************/


/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
文件相关功能部分*********************************************************************************************************************************************
*************************************************************************************************************************************************************/
/**
 * 函数名称: LoadData
 * 函数功能: 将代码表和三类基础数据从数据文件载入到内存缓冲区和十字链表中.
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: BOOL类型, 功能函数中除了函数ExitSys的返回值可以为FALSE外,
 *           其他函数的返回值必须为TRUE.
 *
 * 调用说明: 为了能够以统一的方式调用各功能函数, 将这些功能函数的原型设为
 *           一致, 即无参数且返回值为BOOL. 返回值为FALSE时, 结束程序运行.
 */
BOOL LoadData()
{
    COORD pos3 = {25, 4};
    SetConsoleCursorPosition(gh_std_out, pos3);
    int Re = 0;
    Re = CreateList();
    gc_sys_state |= Re;
    gc_sys_state &= ~(4 + 8 + 16 - Re);
    if (gc_sys_state < (1 | 2 | 4 | 8 | 16))
    {  /**数据加载提示信息*/
        COORD pos1 = {27, 6};
        SetConsoleCursorPosition(gh_std_out, pos1);
        printf("系统基础数据不完整!");
        COORD pos2 = {29,8};
        SetConsoleCursorPosition(gh_std_out, pos2);
        printf("按任意键继续...\n");
        getch();
        ClearScreen();
    }

    return TRUE;
}
/**
 * 函数名称:CreateList
 * 函数功能: 加载基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL CreateList()          /**创建科室信息*/
{
    ClearScreen();
    DEPART_NODE *hd = NULL, *pmember_node;
    DEPART_NODE **phead=&hp;
    PATIENT_NODE *passet_node;
    RECORD_NODE *plend_node;
    FILE *pFile;
    int find;
    int re = 0;
    COORD pos1={20,5};
    SetConsoleCursorPosition(gh_std_out,pos1);
    if ((pFile = fopen(gp_member_info_filename, "rb")) == NULL)
    {
        printf("科室信息数据文件打开失败!");
        return TRUE;
    }
    printf("科室信息数据文件打开成功!");

    /**从数据文件中读入科室信息数据，存入以后进先出方式建立的主链中*/
    while (!feof(pFile))
    {
        pmember_node = (DEPART_NODE *)malloc(sizeof(DEPART_NODE));
        fread(pmember_node, sizeof(DEPART_NODE), 1, pFile);
        if(!feof(pFile))
        {
            pmember_node->anext = NULL;
            pmember_node->next = hd;
            hd = pmember_node;
        }

    }
    free(pmember_node);
    fclose(pFile);
    COORD pos2={20,7};
    SetConsoleCursorPosition(gh_std_out,pos2);
    if (hd == NULL)
    {
        printf("科室信息数据文件加载失败!");
        return re;
    }
    printf("科室信息数据文件加载成功!");
    *phead = hd;
    re += 4;
    COORD pos3={20,9};
    SetConsoleCursorPosition(gh_std_out,pos3);
    if ((pFile = fopen(gp_asset_info_filename, "rb")) == NULL)
    {
        printf("病人信息数据文件加载失败!");
        return re;
    }
    printf("病人信息数据文件加载成功!");
    re += 8;

    /**从数据文件中读取
    病人基本信息数据，存入主链对应结点病人基本信息支链中*/
    while (!feof(pFile))
    {
        /**创建结点，存放从数据文件中读出的病人基本信息*/
        passet_node = (PATIENT_NODE *)malloc(sizeof(PATIENT_NODE));
        fread(passet_node, sizeof(PATIENT_NODE), 1, pFile);
        if(!feof(pFile)){
           passet_node->lnext = NULL;


           /**在主链上查找该病人所属科室对应的主链结点*/
           pmember_node = hd;
        while (pmember_node != NULL
               && pmember_node->number!= passet_node->number)
        {
            pmember_node = pmember_node->next;
        }
        if (pmember_node != NULL) /**如果找到，则将结点以后进先出方式插入病人信息支链*/
        {
            passet_node->next = pmember_node->anext;
            pmember_node->anext = passet_node;
        }
        else  /**如果未找到，则释放所创建结点的内存空间*/
        {
            free(passet_node);
        }
}
    }
    fclose(pFile);
    COORD pos4={20,11};
    SetConsoleCursorPosition(gh_std_out,pos4);
    if ((pFile = fopen(gp_lend_info_filename, "rb")) == NULL)
    {
        printf("就诊记录信息数据文件加载失败!");
        return re;
    }
    printf("就诊记录信息数据文件加载成功!");
    re += 16;

    /**从数据文件中读取就诊记录信息数据，存入就诊记录支链对应结点的就诊记录信息支链中*/
    while (!feof(pFile))
    {
        /**创建结点，存放从数据文件中读出的就诊记录信息*/
        plend_node = (RECORD_NODE *)malloc(sizeof(RECORD_NODE));
        fread(plend_node, sizeof(RECORD_NODE), 1, pFile);

        /**查找就诊记录信息支链上对应就诊记录信息结点*/
        if(!feof(pFile))
        {
            pmember_node = hd;
            find = 0;
        while (pmember_node != NULL && find == 0)
        {
            passet_node = pmember_node->anext;
            while (passet_node!= NULL && find == 0)
            {
                if (passet_node->number1== plend_node->number1)
                {
                    find = 1;
                    break;
                }
                passet_node = passet_node->next;
            }
            pmember_node = pmember_node->next;
        }
        if (find)  /**如果找到，则将结点以后进先出方式插入预约信息支链中*/
        {
            plend_node->next = passet_node->lnext;
            passet_node->lnext = plend_node;
        }
        else /**如果未找到，则释放所创建结点的内存空间*/
        {
            free(plend_node);
        }
        }
    }
    fclose(pFile);
    return TRUE;
    }
/**
 * 函数名称: SaveSysData
 * 函数功能: 保存系统代码表和三类基础数据.
 * 输入参数: hd 主链头结点指针
 * 输出参数:
 * 返 回 值: BOOL类型, 总是为TRUE
 *
 * 调用说明:
 */
BOOL SaveSysData(DEPART_NODE *p1)
{
    PATIENT_NODE  *p2;
    RECORD_NODE  *p3;
    FILE *pfout;

    pfout=fopen(gp_member_info_filename,"wb");
    for(p1=hp;p1!=NULL;p1=p1->next)
    {
       fwrite(p1,sizeof(DEPART_NODE),1,pfout);
     }
     fclose(pfout);

     pfout=fopen(gp_asset_info_filename,"wb");
    for(p1=hp;p1!=NULL;p1=p1->next)
    {
        p2=p1->anext;
        while(p2!=NULL)
        {
            fwrite(p2,sizeof(PATIENT_NODE),1,pfout);
            p2=p2->next;
        }
    }
    fclose(pfout);

    pfout=fopen(gp_lend_info_filename,"wb");
    for(p1=hp;p1!=NULL;p1=p1->next)
    {
        p2=p1->anext;
        while(p2!=NULL)
        {
            p3=p2->lnext;
            while(p3!=NULL)
            {
                fwrite(p3,sizeof(RECORD_NODE),1,pfout);
                p3=p3->next;
            }
            p2=p2->next;
        }
    }
    fclose(pfout);
    return TRUE;

}

/**
 * 函数名称: ExitSys
 * 函数功能: 退出程序
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, TRUE或者FALSE
 *
 * 调用说明:
 */
BOOL ExitSys(void)
{
    LABEL_BUNDLE labels;
    HOT_AREA areas;
    BOOL bRet = TRUE;
    SMALL_RECT rcPop;
    COORD pos;
    WORD att;
    ClearScreen();
    char *pCh[] = {"确认退出系统吗？", "确定    取消"};
    int iHot = 1;

    pos.X = strlen(pCh[0]) + 6;
    pos.Y = 7;
    rcPop.Left = (SCR_COL - pos.X) / 2;
    rcPop.Right = rcPop.Left + pos.X - 1;
    rcPop.Top = (SCR_ROW - pos.Y) / 2;
    rcPop.Bottom = rcPop.Top + pos.Y - 1;

    att = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;  /*白底黑字*/
    labels.num = 2;
    labels.ppLabel = pCh;
    COORD aLoc[] = {{rcPop.Left+3, rcPop.Top+2},
                    {rcPop.Left+5, rcPop.Top+5}};
    labels.pLoc = aLoc;

    areas.num = 2;
    SMALL_RECT aArea[] = {{rcPop.Left + 5, rcPop.Top + 5,
                           rcPop.Left + 8, rcPop.Top + 5},
                          {rcPop.Left + 13, rcPop.Top + 5,
                           rcPop.Left + 16, rcPop.Top + 5}};
    char aSort[] = {0, 0};
    char aTag[] = {1, 2};
    areas.pArea = aArea;
    areas.pSort = aSort;
    areas.pTag = aTag;
    PopUp(&rcPop, att, &labels, &areas);

    pos.X = rcPop.Left + 1;
    pos.Y = rcPop.Top + 4;
    FillConsoleOutputCharacter(gh_std_out, '-', rcPop.Right-rcPop.Left-1, pos, &num_written);

    if (DealConInput(&areas, &iHot) == 13 && iHot == 1)
    {
        bRet = FALSE;
    }
    else
    {
        bRet = TRUE;
    }
    PopOff();

    return bRet;
}

/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
添加相关功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: CreateM
 * 函数功能: 创建科室基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
DEPART_NODE *CreateM()                                  /*创建科室基本信息链*/
{
    DEPART_NODE *pmember_node;
    char ch;
    ClearScreen();
    for(;;)
    {
        ClearScreen();
        pmember_node=(DEPART_NODE*)malloc(sizeof(DEPART_NODE));
        if(!pmember_node)
        {
            printf("\n动态分配内存失败！");
            return (hp);
        }
        COORD  new_pos1 = {1,3};
        SetConsoleCursorPosition(gh_std_out, new_pos1);
        printf("科室编号：");
        COORD  new_pos2 = {1,4};
        SetConsoleCursorPosition(gh_std_out, new_pos2);
        printf("科室名称：");
        COORD  new_pos3 = {1,5};
        SetConsoleCursorPosition(gh_std_out, new_pos3);
        printf("科室地址：");
        COORD  new_pos4 = {1,6};
        SetConsoleCursorPosition(gh_std_out, new_pos4);
        printf("科室电话：");
        COORD  new_pos5 = {11,3};
        SetConsoleCursorPosition(gh_std_out, new_pos5);
        scanf("%d%*c",&pmember_node->number);
        COORD  new_pos6= {11,4};
        SetConsoleCursorPosition(gh_std_out, new_pos6);
        scanf("%s%*c",pmember_node->name);
        COORD  new_pos7= {11,5};
        SetConsoleCursorPosition(gh_std_out, new_pos7);
        scanf("%s%*c",pmember_node->adr);
        COORD  new_pos8= {11,6};
        SetConsoleCursorPosition(gh_std_out, new_pos8);
        scanf("%s%*c",pmember_node->phone);
        pmember_node->anext=NULL;
        pmember_node->next=hp;
        hp=pmember_node;
        COORD  new_pos9 = {1,5};
        SetConsoleCursorPosition(gh_std_out, new_pos9);
        printf("是否继续添加？'Y'or 'N':");
        scanf(" %c",&ch);
        if(ch=='N'||ch=='n') break;
    }
    ClearScreen();
    return pmember_node;
}
/**
 * 函数名称: CreateA
 * 函数功能: 创建病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL CreateA()
{
    down:
    ClearScreen();
    DEPART_NODE *pmember_node;
    PATIENT_NODE *passet_node=NULL,*hpp;
    int num;
    char ch;
    DEPART_NODE* head=(DEPART_NODE*)malloc(sizeof(DEPART_NODE));
    head=hp;
    pmember_node=head;
    COORD pos0 = {40,10};
    SetConsoleCursorPosition(gh_std_out, pos0);
    if(pmember_node==NULL)
    {
        printf("未创建任何科室信息！任意键返回");
        getch();
        return TRUE;
    }
    COORD pos = {2,2};
    SetConsoleCursorPosition(gh_std_out, pos);
    printf("科室编号     科室名称\n");
    while(pmember_node!=NULL)
    {
        printf("  %-14d%-20s\n\n",pmember_node->number,pmember_node->name);
        pmember_node=pmember_node->next;
    }
    printf(" 请输入您所要新建的病人信息所属科室的编号：");
    scanf("%d%*c",&num);
    head=hp;
    pmember_node=findM(num,head);
    if(pmember_node==NULL)
    {
        printf("未创建任何科室信息！按任意键返回");
        getch();
        goto down;
    }
    while(1)
    {
        ClearScreen();
        COORD pos = {1, 2};
        SetConsoleCursorPosition(gh_std_out, pos);
        printf("科室编号：%d  科室名称：%s",pmember_node->number,pmember_node->name);
        passet_node=(PATIENT_NODE*)malloc(sizeof(PATIENT_NODE));
        hpp=pmember_node->anext;
        passet_node->number=pmember_node->number;
        COORD pos1 = {1, 3};
        SetConsoleCursorPosition(gh_std_out, pos1);
        printf("病人编号：");
        COORD pos2 = {1, 4};
        SetConsoleCursorPosition(gh_std_out, pos2);
        printf("病人姓名：");
        COORD pos3 = {1, 5};
        SetConsoleCursorPosition(gh_std_out, pos3);
        printf("病人电话：");
        COORD pos4 = {1, 6};
        SetConsoleCursorPosition(gh_std_out, pos4);
        printf("病人性别：");
        COORD pos5 = {1, 7};
        SetConsoleCursorPosition(gh_std_out, pos5);
        printf("病人住址：");
        COORD pos9 = {11, 3};
        SetConsoleCursorPosition(gh_std_out, pos9);
        scanf("%d%*c",&passet_node->number1);
        COORD pos10 = {11, 4};
        SetConsoleCursorPosition(gh_std_out, pos10);
        scanf("%s%*c",passet_node->name);
        COORD pos11= {11, 5};
        SetConsoleCursorPosition(gh_std_out, pos11);
        scanf("%s%*c",passet_node->phone);
        COORD pos12 = {11, 6};
        SetConsoleCursorPosition(gh_std_out, pos12);
        scanf("%d%*c",&passet_node->sex);
        COORD pos13 = {11, 7};
        SetConsoleCursorPosition(gh_std_out, pos13);
        scanf("%s%*c",&passet_node->adr);
        passet_node->lnext=NULL;
        pmember_node->anext=passet_node;
        passet_node->next=hpp;
        COORD pos23 = {1, 8};
        SetConsoleCursorPosition(gh_std_out, pos23);
        printf("成功添加一条病人信息!\n 是否继续？'Y or 'N':");
        scanf(" %c%*c",&ch);
        if(ch=='N'||ch=='n') break;
    }
    ClearScreen();
    return TRUE;


}
/**
 * 函数名称: CreateL
 * 函数功能: 创建就诊记录基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL CreateL()
{
    ClearScreen();
    DEPART_NODE *p1,*head,*head1;
    PATIENT_NODE *p2;
    RECORD_NODE *p3=NULL;
    int num1,num2;
    char ch, c1;
    p1=hp;
    COORD pos0={40,10};
    SetConsoleCursorPosition(gh_std_out, pos0);
    if(p1==NULL)
    {
        printf("未创建任何科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    COORD pos1={1,2};
    SetConsoleCursorPosition(gh_std_out, pos1);
    printf("科室编号    科室名称\n\n");
    while(p1!=NULL)
    {
        printf("  %-12d%-16s\n\n",p1->number,p1->name);
        p1=p1->next;
    }
    printf(" 请输入您所要添加的就诊记录所属科室的编号：");
    scanf("%d%*c",&num1);
    head=hp;
    p1=findM(num1,head);
    p2=p1->anext;
    if(p2==NULL)
    {
        printf("该科室不存在病人信息！\n");
        getch();
        return TRUE;
    }
    printf("\n 科室编号    病人编号   病人姓名      病人性别\n");
    while(p2!=NULL)
    {
        printf(" %-12d%-12d%-12s%-11d\n",p2->number,p2->number1,p2->name,p2->sex);
        p2=p2->next;
    }
    repeat:
    printf("是否需要查看对应病人的详细信息？'Y' or 'N':   ");
    scanf("%c",&c1);
    if(c1 =='Y'|| c1 =='y')
    {
        LookA();
        goto up;
    }
    else if(c1 == 'N'||c1 =='n')
    {
        up:
       printf("\n 请输入您所要添加的就诊记录信息所属病人的编号:");
       scanf("%d",&num2);
       head1=hp;
       p2=findA(num2,head1);
       if(p2==NULL)
        {
           printf("该病人信息不存在！");
           getch();
           return TRUE;
        }
       while(1)
         {
             AGAIN:
           ClearScreen();
           p3=(RECORD_NODE*)malloc(sizeof(RECORD_NODE));
           COORD new_pos2={1,2};
           SetConsoleCursorPosition(gh_std_out,new_pos2);
           printf("病人编号：%d   病人姓名：%s",p2->number1,p2->name);
           p3->number1=p2->number1;
           COORD  new_pos3 = {1, 3};
           SetConsoleCursorPosition(gh_std_out, new_pos3);
           printf("记录编号：");
           COORD  new_pos4 = {1, 4};
           SetConsoleCursorPosition(gh_std_out, new_pos4);
           printf("主治医生：");
           COORD  new_pos5 = {1, 5};
           SetConsoleCursorPosition(gh_std_out, new_pos5);
           printf("就诊费用：");
           COORD  new_pos6 = {1, 6};
           SetConsoleCursorPosition(gh_std_out, new_pos6);
           printf("就诊日期：");
           COORD  new_pos7 = {1, 7};
           SetConsoleCursorPosition(gh_std_out, new_pos7);
           printf("计划复诊日期：");
           COORD  new_pos8 = {1, 8};
           SetConsoleCursorPosition(gh_std_out, new_pos8);
           printf("实际复诊日期：");
           COORD  new_pos9 = {1, 9};
           SetConsoleCursorPosition(gh_std_out, new_pos9);
           printf("详细说明：");
           COORD  new_pos10 = {15, 3};
           SetConsoleCursorPosition(gh_std_out, new_pos10);
           scanf("%d%*c",&p3->number2);
           COORD  new_pos11 = {15, 4};
           SetConsoleCursorPosition(gh_std_out, new_pos11);
           scanf("%s%*c",p3->name);
           COORD  new_pos12 = {15, 5};
           SetConsoleCursorPosition(gh_std_out, new_pos12);
           scanf("%f%*c",&p3->lmoney);
           COORD  new_pos13 = {15, 6};
           SetConsoleCursorPosition(gh_std_out, new_pos13);
           scanf("%s%*c",p3->ldate);
           COORD  new_pos14 = {15, 7};
           SetConsoleCursorPosition(gh_std_out, new_pos14);
           scanf("%s%*c",p3->bdate);
           COORD  new_pos15 = {15, 8};
           SetConsoleCursorPosition(gh_std_out, new_pos15);
           scanf("%s%*c",p3->tdate);
           COORD  new_pos16 = {15, 9};
           SetConsoleCursorPosition(gh_std_out, new_pos16);
           scanf("%s%*c",p3->tell);
           p3->next=p2->lnext;
           p2->lnext=p3;
           COORD  new_pos17 = {1, 10};
           SetConsoleCursorPosition(gh_std_out, new_pos17);
           printf("成功插入一条就诊记录信息!\n 是否继续？Y/N:    ");
           scanf(" %c%*c",&ch);
           if(ch=='N'||ch=='n')
           break;
           else if(ch=='Y'||ch=='y')
           goto AGAIN;
            else
     {
        printf("输入错误，请重新输入，");
        goto repeat;
    }
    }
    }
  ClearScreen();
  return TRUE;

}
/**
 * 函数名称: LookA
 * 函数功能: 查询详细病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: 无
 *
 * 调用说明:
 */
void LookA(void)
{
    DEPART_NODE*head=hp;
    PATIENT_NODE *p2;
    int num;
    char ch='y';
    while(ch !='n'&&ch!='N')
    {
        if(ch=='y'||ch=='Y')
          {
              printf("请输入您所要查询的病人编号： ");
              scanf("%d%*c",&num);
              p2=findA(num,head);
              if(p2==NULL)
                {
                  printf("该病人信息不存在！");
                }
              else
                {
                  printf("\n  %s病人的信息为：\n",p2->name);
                  printf("\n  科室编号     病人编号     病人姓名        电话           性别      住址\n");
                  if(p2!=NULL)
                    {
                       printf("  %-14d%-13d%-15s%-14s%-14d%-15s\n",p2->number,p2->number1,
                                  p2->name,p2->phone,p2->sex,p2->adr);
                    }
                }
              printf("是否继续查看病人信息？（Y/N）:");
              scanf("%c%*c",&ch);
          }
        else
          {
              printf("输入错误，请重新输入：");
              scanf("%c%*c",&ch);
          }
      }
}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
查找各种结点，返回相应指针        功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: findM
 * 函数功能: 查找科室信息结点
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
DEPART_NODE *findM(int num,DEPART_NODE *head)
{
    DEPART_NODE *p;
    p=head;
    while(p!=NULL)
    {
        if(num==p->number)
           return p;
           p=p->next;
    }
    printf("此科室不存在！\n");
    return NULL;
}
/**
 * 函数名称: findA
 * 函数功能: 查找病人信息结点
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
PATIENT_NODE *findA(int num,DEPART_NODE *head)
{
   DEPART_NODE *p1;
    PATIENT_NODE *p2;
    p1=head;
    while(p1!=NULL)
    {
        p2=p1->anext;
        while(p2!=NULL)
        {
            if(num==p2->number1)
               return p2;
            p2=p2->next;
        }
        p1=p1->next;
    }
    return NULL;
}
/**
 * 函数名称:findL
 * 函数功能: 查找就诊记录信息结点
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
RECORD_NODE *findL(int num,DEPART_NODE *head)
{
    DEPART_NODE *p1;
    PATIENT_NODE *p2;
    RECORD_NODE *p3;
    p1=head;
    while(p1!=NULL)
    {
        p2=p1->anext;
        while(p2!=NULL)
        {
            p3=p2->lnext;
            while(p3!=NULL)
            {
                if(num==p3->number2)
                    return p3;
                p3=p3->next;
            }
            p2=p2->next;
        }
        p1=p1->next;
    }return p3;
}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
修改相关功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: ModM
 * 函数功能: 修改科室基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL ModM()               /**修改科室基本信息*/
{
    ClearScreen();
    DEPART_NODE *p1=hp,*head=hp;
    int num;
    ClearScreen();
    COORD pos1={40,10};
    SetConsoleCursorPosition(gh_std_out,pos1);
    if(p1==NULL)
        {
            printf("未创建任何信息！");
            getch();
            return TRUE;
        }
    COORD pos={1,3};
    SetConsoleCursorPosition(gh_std_out,pos);
    printf(" 科室编号  科室名称    \n\n");
    while(p1!=NULL)
    {
        printf("  %-10d%-12s\n",p1->number,p1->name);
        p1=p1->next;
    }
    printf(" 请输入您所要修改的科室的编号：");
    scanf("%d%*c",&num);
    p1=findM(num,head);
    ClearScreen();                     /**找到要修改的科室信息的结点*/
    if(p1==NULL)
    {
        getch();
        return TRUE;
    }
    COORD  new_pos11 = {1,2};
    SetConsoleCursorPosition(gh_std_out, new_pos11);
    printf("\n  科室编号  科室名称\n");
    printf("\n  %-10d%-12s\n",p1->number,p1->name);
    printf("\n请输入修改的内容：\n");
        COORD  new_pos1 = {1,10};
        SetConsoleCursorPosition(gh_std_out, new_pos1);
        printf("科室编号：");
        COORD  new_pos2 = {1,11};
        SetConsoleCursorPosition(gh_std_out, new_pos2);
        printf("科室名称：");
        COORD  new_pos3 = {1,12};
        SetConsoleCursorPosition(gh_std_out, new_pos3);
        printf("科室地址：");
        COORD  new_pos4 = {1,13};
        SetConsoleCursorPosition(gh_std_out, new_pos4);
        printf("科室电话：");

        COORD  new_pos5= {11,10};
        SetConsoleCursorPosition(gh_std_out, new_pos5);
        scanf("%d%*c",&p1->number);
        COORD  new_pos6 = {11,11};
        SetConsoleCursorPosition(gh_std_out, new_pos6);
        scanf("%s%*c",p1->name);
        COORD  new_pos7 = {11,12};
        SetConsoleCursorPosition(gh_std_out, new_pos7);
        scanf("%s%*c",p1->adr);
        COORD  new_pos8 = {11,13};
        SetConsoleCursorPosition(gh_std_out, new_pos8);
        scanf("%s%*c",p1->phone);

    COORD pos3 = {1,17};
    SetConsoleCursorPosition(gh_std_out, pos3);
    printf("修改成功！");
    return TRUE;

}
/**
 * 函数名称: ModA
 * 函数功能: 修改病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL ModA()              /**修改病人基本信息*/
{
    ClearScreen();
    DEPART_NODE *p1=hp,*head=hp;
    PATIENT_NODE *p2=NULL,*passet_node;
    int num;
    ClearScreen();
    COORD pos = {40, 10};
    SetConsoleCursorPosition(gh_std_out, pos);
    if(p1==NULL)
        {
            printf("不存在任何病人信息！");
            getch();
            return TRUE;
        }
    COORD pos1={1,1};
    SetConsoleCursorPosition(gh_std_out,pos1);
    printf("\n  科室编号     病人编号     病人姓名        电话           性别      住址\n");
    while(p1!=NULL)
       {
           p2=p1->anext;
           while(p2!=NULL)
              {
                printf("    %-14d%-13d%-15s%-14s%-14d%-15s\n",p2->number,p2->number1,
                                  p2->name,p2->phone,p2->sex,p2->adr);

                p2=p2->next;
              }
           p1=p1->next;
       }
    printf("\n 请输入病人编号:");
    scanf("%d",&num);
    p2=findA(num,head);         /**找到要修改的病人信息的结点*/
    if(p2==NULL)
    {
        printf("该病人不存在！");
        getch();
        return TRUE;
    }
    ClearScreen();
    COORD posA = {1, 3};
    SetConsoleCursorPosition(gh_std_out, posA);
    printf("已找到该病人信息\n");
     printf("\n  科室编号     病人编号     病人姓名        电话           性别      住址\n");
    printf("    %-14d%-13d%-15s%-14s%-14d%-15s\n",p2->number,p2->number1,
                  p2->name,p2->phone,p2->sex,p2->adr);

    printf("\n请输入修改的内容：\n");

        COORD pos2 = {1, 12};
        SetConsoleCursorPosition(gh_std_out, pos2);
        printf("病人编号：");
        COORD pos3 = {1, 13};
        SetConsoleCursorPosition(gh_std_out, pos3);
        printf("病人姓名：");
        COORD pos4 = {1, 14};
        SetConsoleCursorPosition(gh_std_out, pos4);
        printf("病人电话：");
        COORD pos5 = {1, 15};
        SetConsoleCursorPosition(gh_std_out, pos5);
        printf("病人性别：");
        COORD pos6 = {1, 16};
        SetConsoleCursorPosition(gh_std_out, pos6);
        printf("病人住址：");
        COORD pos7 = {11, 12};
        SetConsoleCursorPosition(gh_std_out, pos7);
        scanf("%d%*c",&p2->number1);
        COORD pos8 = {11, 13};
        SetConsoleCursorPosition(gh_std_out, pos8);
        scanf("%s%*c",p2->name);
        COORD pos9= {11, 14};
        SetConsoleCursorPosition(gh_std_out, pos9);
        scanf("%s%*c",p2->phone);
        COORD pos10 = {11, 15};
        SetConsoleCursorPosition(gh_std_out, pos10);
        scanf("%d%*c",&p2->sex);
        COORD pos11 = {11, 16};
        SetConsoleCursorPosition(gh_std_out, pos11);
        scanf("%s%*c",p2->adr);
    printf("修改成功！任意键返回！");
    getch();
    ClearScreen();
    return TRUE;

}
/**
 * 函数名称: ModL
 * 函数功能: 修改就诊记录基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL ModL()              /**修改就诊记录基本信息*/
{
    ClearScreen();
    DEPART_NODE *p1,*head=hp;
    PATIENT_NODE *p2=NULL;
    RECORD_NODE *p3=NULL;
    int num;
    p1=head;
    ClearScreen();
    COORD pos1 = {40, 10};
    SetConsoleCursorPosition(gh_std_out, pos1);
    if(p1==NULL)
        {
            printf("未创建任何信息！任意键返回！");
            getch();
            return TRUE;
        }
    COORD pos0= {1,1};
    SetConsoleCursorPosition(gh_std_out, pos0);
    printf(" 病人编号  记录编号   主治医生       就诊费用   就诊日期    计划复诊日期   实际复诊日期   详细说明\n");
    while(p1!=NULL)
       {
           p2=p1->anext;
           while(p2!=NULL)
              {
                  p3=p2->lnext;
                  while(p3!=NULL)
                    {
                       printf("  %-10d%-11d%-15s%8.2f   %-12s%-15s%-15s%-50s\n",p3->number1,
                           p3->number2,p3->name,p3->lmoney,p3->ldate,p3->bdate,p3->tdate,p3->tell);
                        p3=p3->next;
                    }
                  p2=p2->next;
              }
           p1=p1->next;
       }
    COORD  pos2 = {1, 15};
    SetConsoleCursorPosition(gh_std_out, pos2);
    printf("\n请输入记录编号:");
    scanf("%d%*c",&num);
    ClearScreen();
    p3=findL(num,head);
    COORD  pos17 = {40, 10};
    SetConsoleCursorPosition(gh_std_out, pos17);
    if(p3==NULL)
    {
        ClearScreen();
        printf("该病人就诊记录信息不存在！按任意键返回");
        getch();
        return TRUE;
    }
    ClearScreen();
    COORD  pos3 = {1, 2};
    SetConsoleCursorPosition(gh_std_out, pos3);
    printf("已找到该病人就诊记录信息\n\n\n");
    printf(" 病人编号  记录编号   主治医生       就诊费用   就诊日期    计划复诊日期   实际复诊日期   详细说明\n");
    printf("  %-10d%-11d%-15s%8.2f   %-12s%-15s%-15s%-50s\n",p3->number1,
                           p3->number2,p3->name,p3->lmoney,p3->ldate,p3->bdate,p3->tdate,p3->tell);

    printf("\n\n请输入修改的内容：\n");

        COORD  new_pos3 = {1, 10};
        SetConsoleCursorPosition(gh_std_out, new_pos3);
        printf("记录编号：");
        COORD  new_pos4 = {1, 11};
        SetConsoleCursorPosition(gh_std_out, new_pos4);
        printf("主治医生姓名:");
        COORD  new_pos5 = {1, 12};
        SetConsoleCursorPosition(gh_std_out, new_pos5);
        printf("就诊费用:");
        COORD  new_pos6 = {1, 13};
        SetConsoleCursorPosition(gh_std_out, new_pos6);
        printf("就诊日期:");
        COORD  new_pos7 = {1, 14};
        SetConsoleCursorPosition(gh_std_out, new_pos7);
        printf("计划复诊日期:");
        COORD  new_pos8 = {1, 15};
        SetConsoleCursorPosition(gh_std_out, new_pos8);
        printf("实际复诊日期:");
        COORD  new_pos9 = {1, 16};
        SetConsoleCursorPosition(gh_std_out, new_pos9);
        printf("详细说明:");
        COORD  new_pos10 = {15, 10};
        SetConsoleCursorPosition(gh_std_out, new_pos10);
        scanf("%d*c",&p3->number2);
        COORD  new_pos11 = {15, 11};
        SetConsoleCursorPosition(gh_std_out, new_pos11);
        scanf("%s%*c",p3->name);
        COORD  new_pos12 = {15, 12};
        SetConsoleCursorPosition(gh_std_out, new_pos12);
        scanf("%f%*c",&p3->lmoney);
        COORD  new_pos13 = {15, 13};
        SetConsoleCursorPosition(gh_std_out, new_pos13);
        scanf("%s%*c",p3->ldate);
        COORD  new_pos14 = {15, 14};
        SetConsoleCursorPosition(gh_std_out, new_pos14);
        scanf("%s%*c",p3->bdate);
        COORD  new_pos15 = {15, 15};
        SetConsoleCursorPosition(gh_std_out, new_pos15);
        scanf("%s%*c",p3->tdate);
        COORD  new_pos16 = {15, 16};
        SetConsoleCursorPosition(gh_std_out, new_pos16);
        scanf("%s%*c",p3->tell);
    printf("修改成功！任意键返回！");
    return TRUE;
    ClearScreen();
}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
插入相关功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: InserM
 * 函数功能: 插入科室基本信息结点
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL InserM(void)
{
    ClearScreen();
    DEPART_NODE *current1=hp,*prior1=hp,*head=hp;
    int num;
    char flag;
    ClearScreen();
    COORD  new_pos0 = {40,10};
    SetConsoleCursorPosition(gh_std_out, new_pos0);
    if(head==NULL)
    {
        printf("未创建任何科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    COORD  new_pos = {1,2};
    SetConsoleCursorPosition(gh_std_out, new_pos);
    printf(" 科室编号  科室名称\n\n");
    while(current1!=NULL)
    {
        printf("  %-10d%-12s\n\n",current1->number,current1->name);
        current1=current1->next;
    }
    printf("\n请输入您要插入科室的前一科室的编号：");
    scanf("%d%*c",&num);
    current1=head;
    while(current1!=NULL&&num!=current1->number)
    {
        prior1=current1;
        current1=current1->next;
    }
    if(current1==NULL)
    {
        printf("没有该科室信息！");
        getch();
        return TRUE;
    }
    else
    {
        printf("已找到该科室信息，您确定要在其后插入科室信息吗？\nY/N:");
        scanf("%c%*c",&flag);
    }
    if(flag=='N'||flag=='n') return FALSE;
    else
    {
        ClearScreen();
        prior1=(DEPART_NODE*)malloc(sizeof(DEPART_NODE));
        prior1->anext=NULL;
        prior1->next=current1->next;
        current1->next=prior1;
        COORD new_pos1={1,4};
        SetConsoleCursorPosition(gh_std_out, new_pos1);
        printf("\n\n请输入插入科室内容:\n");
        COORD new_pos2={1,10};
        SetConsoleCursorPosition(gh_std_out,new_pos2);
        printf("科室编号：");
        COORD new_pos3={1,11};
        SetConsoleCursorPosition(gh_std_out,new_pos3);
        printf("科室名称：");
        COORD new_pos4={1,12};
        SetConsoleCursorPosition(gh_std_out,new_pos4);
        printf("科室地址：");
        COORD new_pos5={1,13};
        SetConsoleCursorPosition(gh_std_out,new_pos5);
        printf("科室电话：");
        COORD new_pos6={15,10};
        SetConsoleCursorPosition(gh_std_out,new_pos6);
        scanf("%d%*c",&prior1->number);
        COORD new_pos7={15,11};
        SetConsoleCursorPosition(gh_std_out,new_pos7);
        scanf("%s%*c",prior1->name);
        COORD new_pos8={15,12};
        SetConsoleCursorPosition(gh_std_out,new_pos8);
        scanf("%s%*c",prior1->adr);
        COORD new_pos9={15,13};
        SetConsoleCursorPosition(gh_std_out,new_pos9);
        scanf("%s%*c",prior1->phone);
        printf("插入科室信息成功！");
        getch();
        ClearScreen();
    }
    return TRUE;
}
/**
 * 函数名称: InserA
 * 函数功能: 插入病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL InserA(void)
{
    ClearScreen();
    DEPART_NODE *current1=hp;
    PATIENT_NODE *current2,*prior2,*prior3;
    int num;
    char ch;
    COORD new_pos1={2,2};
    SetConsoleCursorPosition(gh_std_out,new_pos1);
    printf("\n科室编号  病人编号  病人姓名         病人性别\n");
    while(current1!=NULL)
      {
          current2=current1->anext;
          while(current2!=NULL)
             {
                 printf("  %-10d%-10d%-15s%-11d\n",current2->number,current2->number1,
                                           current2->name,current2->sex);
                 current2=current2->next;
             }
          current1=current1->next;
      }
    printf("请输入要插入的病人信息的前一病人的编号：");
    scanf("%d%*c",&num);
    current1=hp;
    while(current1!=NULL)
    {
        current2=NULL;
        prior2=current1->anext;
        while(prior2!=NULL)
        {
            if(num==prior2->number1)
            {
                printf("病人信息已找到，确认在其后插入？Y/N:  ");
                scanf("%c%*c",&ch);
                ClearScreen();
                prior3=(PATIENT_NODE*)malloc(sizeof(PATIENT_NODE));
                if(ch=='N'||ch=='n')
                return TRUE;
                prior3->next=prior2->next;
                prior3->lnext=NULL;
                prior3->number=prior2->number;
                COORD new_pos2={1,4};
                SetConsoleCursorPosition(gh_std_out,new_pos2);
                printf("\n\n请输入插入病人信息内容：\n");
                COORD new_pos3={1,10};
                SetConsoleCursorPosition(gh_std_out,new_pos3);
                printf("病人编号：");
                COORD new_pos4={1,11};
                SetConsoleCursorPosition(gh_std_out,new_pos4);
                printf("病人姓名：");
                COORD new_pos5={1,12};
                SetConsoleCursorPosition(gh_std_out,new_pos5);
                printf("电话：");
                COORD new_pos6={1,13};
                SetConsoleCursorPosition(gh_std_out,new_pos6);
                printf("性别：");
                COORD new_pos7={1,14};
                SetConsoleCursorPosition(gh_std_out,new_pos7);
                printf("住址：");
                COORD new_pos11={15,10};
                SetConsoleCursorPosition(gh_std_out,new_pos11);
                scanf("%d%*c",&prior3->number1);
                COORD new_pos12={15,11};
                SetConsoleCursorPosition(gh_std_out,new_pos12);
                scanf("%s%*c",prior3->name);
                COORD new_pos13={15,12};
                SetConsoleCursorPosition(gh_std_out,new_pos13);
                scanf("%s%*c",prior3->phone);
                COORD new_pos14={15,13};
                SetConsoleCursorPosition(gh_std_out,new_pos14);
                scanf("%d%*c",&prior3->sex);
                COORD new_pos15={15,14};
                SetConsoleCursorPosition(gh_std_out,new_pos15);
                scanf("%s%*c",&prior3->adr);
                COORD new_pos19={1,19};
                SetConsoleCursorPosition(gh_std_out,new_pos19);
                prior3->next=prior2->next;
                prior2->next=prior3;
                printf("插入病人信息成功！");
                getch();
                break;
            }
            current2=prior2;
            prior2=prior2->next;
        }
        current1=current1->next;
    }
    ClearScreen();
    return TRUE;

}
/**
 * 函数名称: InserL
 * 函数功能: 插入就诊记录信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL InserL(void)
{
    ClearScreen();
    DEPART_NODE *p1,*head=hp;
    PATIENT_NODE *p2;
    RECORD_NODE *p3,*prior3,*head3;
    int num1,num2;
    char flag,ch;
    int n;
    p1=hp;
    ClearScreen();
    COORD  new_pos0 = {40,10};
    SetConsoleCursorPosition(gh_std_out, new_pos0);
    if(p1==NULL)
    {
        printf("未创建任何科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    COORD  new_pos = {1,2};
    SetConsoleCursorPosition(gh_std_out, new_pos);
    printf(" 科室编号  科室名称\n\n");
    while(p1!=NULL)
    {
        printf("  %-10d%-15s\n",p1->number,p1->name);
        p1=p1->next;
    }
    printf(" 请输入您插入就诊记录信息所属的科室编号：");
    scanf("%d%*c",&num1);
    p1=findM(num1,head);
    if(p1==NULL)
    {
        printf("该科室不存在！按任意键返回");
        getch();
        return TRUE;
    }
    p2=p1->anext;
    if(p2==NULL)
    {
        printf("%s该科室不存在病人信息！按任意键返回",p1->name);
        getch();
        return TRUE;
    }
    printf("\n 科室编号  病人编号  病人姓名       性别\n");
    while(p2!=NULL)
    {
        printf(" %-10d%-10d%-15s%-11d\n",p2->number,p2->number1,p2->name,p2->sex);
        p2=p2->next;
    }
    printf("\n 请输入您插入就诊记录信息所属的病人编号:");
    scanf("%d",&num2);
    head=hp;
    p2=findA(num2,head);
    if(p2==NULL)
    {
        printf("该病人信息不存在！按任意键返回");
        getch();
        return TRUE;
    }
    prior3=p2->lnext;
    p3=p2->lnext;
    if(p3==NULL)
    {
        printf("%s病人没有就诊记录信息!按任意键返回",p2->name);
        getch();
        return TRUE;
    }
    printf("\n%s病人的就诊记录信息如下：\n\n",p2->name);
    printf(" 病人编号  记录编号   主治医生       就诊费用   就诊日期    计划复诊日期   实际复诊日期   详细说明\n");
    while(p3!=NULL)
    {
        printf("  %-10d%-11d%-15s%8.2f   %-12s%-15s%-15s%-50s\n",p3->number1,
        p3->number2,p3->name,p3->lmoney,p3->ldate,p3->bdate,p3->tdate,p3->tell);
        p3=p3->next;
    }
    printf("\n以上是该病人的所有就诊记录信息\n");
    repeat1:
    printf("请输入要插入就诊记录信息的前一条就诊记录的记录编号:  ");
    scanf("%d%*c",&n);
    p3=p2->lnext;
    while(p3!=NULL)
    {
        if(p3->number2==n)
        break;
        else
        p3=p3->next;
    }
    if(p3==NULL)
    {
        printf("输入错误！是否重新输入?    'Y' or 'N':   ");
        scanf("%c%*c",&ch);
        if(ch=='Y'||ch=='y')
        goto repeat1;
        else
        {
            printf("按任意键返回！");
            getch();
            return TRUE;
        }
    }
    printf("已找到该就诊记录信息，确定要在其后插入信息？Y/N:");
    scanf("%c%*c",&flag);
    if(flag=='N'||flag=='n') return TRUE;
    else
    {
        ClearScreen();
     prior3=findL(n,head);
     head3=(RECORD_NODE*)malloc(sizeof(RECORD_NODE));
     head3->next=prior3->next;
     prior3->next=head3;
     head3->number1=prior3->number1;
     COORD new_pos1={1,4};
     SetConsoleCursorPosition(gh_std_out,new_pos1);
     printf("\n\n请输入插入就诊记录的信息\n");
     COORD new_pos4={1,10};
     SetConsoleCursorPosition(gh_std_out,new_pos4);
     printf("记录编号：");
     COORD new_pos5={1,11};
     SetConsoleCursorPosition(gh_std_out,new_pos5);
     printf("主治医生姓名：");
     COORD new_pos6={1,12};
     SetConsoleCursorPosition(gh_std_out,new_pos6);
     printf("就诊费用：");
     COORD new_pos7={1,13};
     SetConsoleCursorPosition(gh_std_out,new_pos7);
     printf("就诊日期：");
     COORD new_pos8={1,14};
     SetConsoleCursorPosition(gh_std_out,new_pos8);
     printf("计划复诊日期：");
     COORD new_pos9={1,15};
     SetConsoleCursorPosition(gh_std_out,new_pos9);
     printf("实际复诊日期：");
     COORD new_pos10={1,16};
     SetConsoleCursorPosition(gh_std_out,new_pos10);
     printf("详细说明：");
     COORD new_pos11={15,10};
     SetConsoleCursorPosition(gh_std_out,new_pos11);
     scanf("%d%*c",&head3->number2);
     COORD new_pos12={15,11};
     SetConsoleCursorPosition(gh_std_out,new_pos12);
     scanf("%s%*c",head3->name);
     COORD new_pos13={15,12};
     SetConsoleCursorPosition(gh_std_out,new_pos13);
     scanf("%f%*c",&head3->lmoney);
     COORD new_pos14={15,13};
     SetConsoleCursorPosition(gh_std_out,new_pos14);
     scanf("%s%*c",head3->ldate);
     COORD new_pos15={15,14};
     SetConsoleCursorPosition(gh_std_out,new_pos15);
     scanf("%s%*c",head3->bdate);
     COORD new_pos16={15,15};
     SetConsoleCursorPosition(gh_std_out,new_pos16);
     scanf("%s%*c",head3->tdate);
     COORD new_pos17={15,16};
     SetConsoleCursorPosition(gh_std_out,new_pos17);
     scanf("%s%*c",head3->tell);
}
    printf("成功插入一条就诊记录信息！");
    getch();
    ClearScreen();
    return TRUE;

}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
删除相关功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: DeleM
 * 函数功能: 删除科室基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL DeleM(void)
{
    ClearScreen();
    DEPART_NODE *current1=hp,*prior1=hp,*head=hp;
    PATIENT_NODE *current2,*prior2;
    RECORD_NODE *current3,*prior3;
    int num;
    char flag;
    ClearScreen();
    COORD  new_pos0 = {40,10};
    SetConsoleCursorPosition(gh_std_out, new_pos0);
    if(hp==NULL)
    {
        printf("未创建任何科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    COORD  new_pos = {1,2};
    SetConsoleCursorPosition(gh_std_out, new_pos);
    printf(" 科室编号  科室名称\n\n");
    while(current1!=NULL)
    {
        printf("  %-10d%-15s\n\n",current1->number,current1->name);
        current1=current1->next;
    }
    printf("\n请输入您要删除科室的编号：");
    scanf("%d%*c",&num);
    current1=hp;
    while(current1!=NULL&&num!=current1->number)
    {
        prior1=current1;
        current1=current1->next;
    }
    if(current1==NULL)
    {
        printf("没有该科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    else
    {
        printf("已找到该科室信息，您确定要删除该科室吗？\nY/N:");
        scanf("%c%*c",&flag);
    }
    if(flag=='N'||flag=='n') return FALSE;
    else
    {
        current2=current1->anext;
        while(current2!=NULL)
        {
            current3=current2->lnext;
            while(current3!=NULL)
            {
                prior3=current3->next;
                free(current3);
                current3=prior3;
            }
            prior2=current2->next;
            free(current2);
            current2=prior2;
        }
        if(current1==head)
            hp=current1->next;
        else
            prior1->next=current1->next;
        free(current1);
        printf("删除科室信息成功！按任意键返回");
        getch();
        ClearScreen();
    }
    return TRUE;
}
/**
 * 函数名称: DeleM
 * 函数功能: 删除病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL DeleA(void)
{
    ClearScreen();
    DEPART_NODE *p1=hp;
    PATIENT_NODE *p2,*prior2;
    RECORD_NODE *p3,*prior3;
    int num;
    char ch;
    COORD new_pos1={2,2};
    SetConsoleCursorPosition(gh_std_out,new_pos1);
    if(p1==NULL)
    {
        printf("没有任何科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    p2=p1->anext;
    while(p1!=NULL)
    {
        if(p1->anext!=NULL)
        break;
        else
        p1=p1->next;
    }
    if(p1==NULL)
    {
        printf("未有任何病人信息！按任意键返回");
        getch();
        return TRUE;
    }
    p1=hp;
    printf("\n科室编号  病人编号  病人姓名         性别\n");
    while(p1!=NULL)
      {
          p2=p1->anext;
          while(p2!=NULL)
             {
                 printf("  %-10d%-10d%-15s%-11s\n",p2->number,p2->number1,p2->name,p2->sex);
                 p2=p2->next;
             }
          p1=p1->next;
      }
    printf("请输入要删除的病人编号：");
    scanf("%d%*c",&num);
    p1=hp;
    while(p1!=NULL)
    {
        p2=NULL;
        prior2=p1->anext;
        while(prior2!=NULL)
        {
            if(num==prior2->number1)
            {
                printf("病人信息已找到，确认删除？Y/N:  ");
                scanf("%c%*c",&ch);
                if(ch=='N'||ch=='n') return FALSE;
                p3=prior2->lnext;
                while(p3!=NULL)
                {
                    prior3=p3->next;
                    free(p3);
                    p3=prior3;
                }
                if(p2==NULL)
                   p1->anext=prior2->next;
                else
                   p2->next=prior2->next;
                   free(prior2);
                printf("成功删除一条病人信息！按任意键返回");
                getch();
            }
            p2=prior2;
            prior2=prior2->next;
        }
        p1=p1->next;
    }
    ClearScreen();
    return TRUE;

}
/**
 * 函数名称: DeleL
 * 函数功能: 删除就诊记录信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL DeleL(void)
{
    ClearScreen();
    DEPART_NODE *p1,*head=hp;
    PATIENT_NODE *p2;
    RECORD_NODE *p3,*prior3,*head3;
    int num1,num2;
    char flag;
    int n;
    p1=hp;
    ClearScreen();
    COORD  new_pos0 = {40,10};
    SetConsoleCursorPosition(gh_std_out, new_pos0);
    if(p1==NULL)
    {
        printf("未创建任何科室信息！按任意键返回");
        getch();
        return TRUE;
    }
    p1=hp;
    COORD  new_pos = {1,1};
    SetConsoleCursorPosition(gh_std_out, new_pos);
    printf(" 科室编号  \t科室名称\n\n");
    while(p1!=NULL)
    {
        printf("  %-15d%-15s\n\n",p1->number,p1->name);
        p1=p1->next;
    }
    printf(" 请输入您删除就诊记录信息所属的科室编号：");
    scanf("%d%*c",&num1);
    p1=findM(num1,head);
    if(p1==NULL)
    {
        printf("该科室信息不存在！按任意键返回");
        getch();
        return TRUE;
    }
    p2=p1->anext;
    printf("\n 科室编号  病人编号  病人姓名       性别\n");
    while(p2!=NULL)
    {
        printf(" %-10d%-10d%-15s%-11s\n",p2->number,p2->number1,p2->name,p2->sex);
        p2=p2->next;
    }
    printf("\n 请输入您删除就诊记录信息所属的病人编号:");
    scanf("%d",&num2);
    ClearScreen();
    head=hp;
    p2=findA(num2,head);
    if(p2==NULL)
    {
        printf("该病人信息不存在！按任意键返回");
        getch();
        return TRUE;
    }
    prior3=p2->lnext;
    p3=p2->lnext;
    if(p3==NULL)
    {
        printf("该病人就诊记录信息不存在！按任意键返回");
        getch();
        return TRUE;
    }
    COORD pos0={2,2};
    SetConsoleCursorPosition(gh_std_out,pos0);
    printf("\n%s病人的就诊记录信息如下：\n",p2->name);
     printf(" 病人编号  记录编号   主治医生       就诊费用   就诊日期    计划复诊日期   实际复诊日期   详细说明\n");
    while(p3!=NULL)
    {
       printf("  %-10d%-11d%-15s%8.2f   %-12s%-15s%-15s%-50s\n",p3->number1,
        p3->number2,p3->name,p3->lmoney,p3->ldate,p3->bdate,p3->tdate,p3->tell);
        p3=p3->next;
    }
    printf("\n以上是该病人的所有就诊记录信息\n\n\n");
    printf("请选择要删除信息的记录编号：");
    scanf("%d%*c",&n);
    prior3=findL(n,head);
    if(prior3==NULL)
    {
        printf("不存在该就诊记录信息！按任意键返回\n");
        getch();
        return TRUE;
    }
    printf("\n已找到该就诊记录信息，确定要删除该信息？Y/N:");
    scanf("%c%*c",&flag);
    if(flag=='N'||flag=='n')
    {
    getch();
    return TRUE;
    }
    else
    {
        p3=p2->lnext;
        if(p3->number2==n)
        {
            p2->lnext=p3->next;
            free(p3);
        }
        else
        {
        while(p3!=NULL)
        {
            head3=p3;
            p3=p3->next;
            if(p3->number2==n)
            break;
        }
        head3->next=p3->next;
        free(p3);
        }
        printf("成功删除一条就诊记录信息！按任意键返回");
    }
    getch();
    ClearScreen();
    return TRUE;

}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
查询相关功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: QueryM
 * 函数功能: 查询科室基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL QueryM()
{
    ClearScreen();
    DEPART_NODE *p1,*head=hp;
    int  num;
    ClearScreen();
    COORD pos={2,2};
    SetConsoleCursorPosition(gh_std_out,pos);
    printf("请输入您所要查询的科室编号:  ");
    scanf("%d%*c",&num);
    p1=findM(num,head);
    if(p1==NULL)
    {

        COORD pos={2,4};
        SetConsoleCursorPosition(gh_std_out,pos);
        printf("该科室不存在！");
        getch();
        return TRUE;
    }
    else
    {
        if(num==p1->number)
        {
            printf("\n 科室编号     科室名称     科室地址     科室电话 \n\n");
            printf(" %-13d%-15s%-15s%-15s\n\n",p1->number,p1->name,p1->adr,p1->phone);
            getch(); 
        }
    }
    return TRUE;
    ClearScreen();
} 
/**
 * 函数名称: QueryA
 * 函数功能: 查询病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL QueryA(void)
{
    ClearScreen();
    DEPART_NODE *head=hp;
    PATIENT_NODE *p2;
    int num;
    COORD pos={2,2};
    SetConsoleCursorPosition(gh_std_out,pos);
    printf("请输入您所要查询病人编号： ");
    scanf("%d%*c",&num);
    p2=findA(num,head);
    if(p2==NULL)
    {
        printf("该病人不存在！按任意键返回");
        return TRUE;
    }
    else{
            printf("\n %s病人的信息为：\n",p2->name);
            printf("\n  科室编号     病人编号     病人姓名        电话           性别      住址\n");
            if(p2!=NULL)
                {
                    printf("    %-14d%-13d%-15s%-14s%-14d%-15s\n",p2->number,p2->number1,
                  p2->name,p2->phone,p2->sex,p2->adr);
                }
    }
    return TRUE;
    }


/**
 * 函数名称: QueryL
 * 函数功能: 查询就诊记录信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL QueryL(void)
{
    ClearScreen();
     DEPART_NODE *head=hp;
    RECORD_NODE *p3;
    int num;
    ClearScreen();
    COORD pos={1,2};
    SetConsoleCursorPosition(gh_std_out,pos);
    printf("请输入您所要查询的记录编号： ");
    scanf("%d%*c",&num);
    p3=findL(num,head);
    if(p3==NULL)
    printf("  该就诊记录信息不存在！按任意键返回");
    else{
            printf("\n 就诊记录信息如下：\n");
           printf(" 病人编号  记录编号   主治医生       就诊费用   就诊日期    计划复诊日期   实际复诊日期   详细说明\n");
            if(p3!=NULL)
                {
                   printf("  %-10d%-11d%-15s%8.2f   %-12s%-15s%-15s%-50s\n",p3->number1,p3->number2,
                             p3->name,p3->lmoney,p3->ldate,p3->bdate,p3->tdate,p3->tell);
                }
        }
    return TRUE;
}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
输出十字交叉链表中信息功能部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称: PutM
 * 函数功能: 输出科室信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL PutM()
{

    ClearScreen();
    DEPART_NODE *p1=hp;
    COORD pos1={40,10};
    SetConsoleCursorPosition(gh_std_out,pos1);
        if(p1==NULL)
    {
        printf("未创建任何科室信息!");
        getch();
        return TRUE;
    }
    COORD pos={2,2};
    SetConsoleCursorPosition(gh_std_out,pos);
    printf("科室编号\t\t科室名称\t科室电话\t科室地址\n");
    while(p1 != NULL)
    {
        printf("  %-22d%-16s%-16s%-16s\n",p1->number,p1->name,p1->phone,p1->adr);
        p1=p1->next;
    }
    return TRUE;
}
/**
 * 函数名称: PutA
 * 函数功能: 输出病人基本信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL PutA()
{
   DEPART_NODE *p1=hp;
    PATIENT_NODE *p2=NULL;
    ClearScreen();
    COORD pos={40,10};
    SetConsoleCursorPosition(gh_std_out,pos);
    if(p1==NULL)
    {
        printf("未创建任何科室信息！");
        getch();
        return TRUE;
    }
    COORD pos1={2,2};
    SetConsoleCursorPosition(gh_std_out,pos1);
    printf("\n  科室编号\t病人编号\t病人姓名\t电话\t\t性别\t住址\n");
    while(p1!=NULL)
    {
         p2=p1->anext;
         while(p2!=NULL)
         {
            printf("  %-14d%-16d%-16s%-16s%-8d%-16s\n",p2->number,p2->number1,
                  p2->name,p2->phone,p2->sex,p2->adr);
            p2=p2->next;
         }
         p1=p1->next;
    }
    return TRUE;
}
/**
 * 函数名称: PutL
 * 函数功能: 输出就诊记录信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL PutL()
{
    DEPART_NODE *p1=hp;
   PATIENT_NODE *p2=NULL;
   RECORD_NODE *p3=NULL;
    ClearScreen();
    COORD pos1 = {40, 10};
    SetConsoleCursorPosition(gh_std_out, pos1);
    if(p1==NULL)
    {
        printf("未创建任何科室信息！");
        getch();
        return TRUE;
    }
    COORD pos = {1,4};
    SetConsoleCursorPosition(gh_std_out, pos);
    printf(" 病人编号  记录编号   主治医生       就诊费用   就诊日期    计划复诊日期   实际复诊日期   详细说明\n");
    while(p1!=NULL)
    {
        p2=p1->anext;
        while(p2!=NULL)
        {
            p3=p2->lnext;
            while(p3!=NULL)
            {
                printf("  %-10d%-11d%-15s%8.2f   %-12s%-15s%-15s%-50s\n",p3->number1,
                           p3->number2,p3->name,p3->lmoney,p3->ldate,p3->bdate,p3->tdate,p3->tell);
                p3=p3->next;
            }
            p2=p2->next;
        }
       p1=p1->next;
    }
    return TRUE;

}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
帮助部分***********************************************************************************************************************************************
*************************************************************************************************************************************************************/

/**
 * 函数名称:HelpTopic
 * 函数功能: 帮助解释本管理系统以及其功能
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL HelpTopic(void)
{
    ClearScreen();
    COORD pos = {1, 5};
    SetConsoleCursorPosition(gh_std_out, pos);
    printf(" \t\t\t\t             电子医嘱管理系统\n\n");
    printf("\t\t\t\t                   五大功能：\n\n");
    printf(" \t\t\t\t添加(A)、修改(M)、插入(I)、删除(D)和查询(Q)\n\n");
    return TRUE;
    ClearScreen();
}
/**
 * 函数名称: About
 * 函数功能: 关于该电子医嘱管理系统的相关信息
 * 输入参数: 无
 * 输出参数:无
 * 返 回 值: BOOL类型, 返回值总为TRUE
 *
 * 调用说明:
 */
BOOL About(void)
{
    ClearScreen();
    COORD pos = {25,5};
    SetConsoleCursorPosition(gh_std_out, pos);
    printf("  本信息管理系统适用于医院病人就诊记录信息的管理，可以实现对信息管理的相关功能");
    COORD pos1 = {50,8};
    SetConsoleCursorPosition(gh_std_out, pos1);
    printf("欢迎使用本系统！");
    COORD pos2 = {38,17};
    SetConsoleCursorPosition(gh_std_out, pos2);
    printf("不足之处，敬请原谅，联系电话：66666666666");
    COORD pos3 = {39,19};
    SetConsoleCursorPosition(gh_std_out, pos3);
    printf("Copyright@2015   华中科技大学计算机学院\n\n");
    return TRUE;
    ClearScreen();
}


