⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 student.cpp

📁 这个个系统是学生管理系统。利用SDK做界面
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        TextOut(hMainDC, 585, yPos, lpTmp->m_szAddress, strlen(lpTmp->m_szAddress));

        lpTmp = lpTmp->m_lpNext;
        yPos += 16;     // 每次都必须让yPos增加,实现每个学生只占用一行
    }

    SelectObject(hMainDC, hOldFont);// 恢复设备上下文
    DeleteObject(hFont);            // 删除创建的字体
}

// 右键弹起消息WM_RBUTTONUP
// 将弹出一个快捷菜单
void OnRButtonUp(POINT  pt, UINT wFlags)
{
    HMENU   hMenu, hSubMenu;

    hMenu    = LoadMenu(g_hAppInst, MAKEINTRESOURCE(IDR_RIGHT));
    hSubMenu = GetSubMenu(hMenu, 0);

    ClientToScreen(g_hMainWnd, &pt);
    TrackPopupMenu(hSubMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, g_hMainWnd, NULL);

    DestroyMenu(hMenu);
}

// 左键双击实践WM_LBUTTONDBCLK,也可用来修改学生信息
void OnLButtonDblClk(POINT pt, UINT wFlags)
{
    OnToolModify();
}

// 处理窗口大小变化消息WM_SIZE
// UINT nWidht:当前窗口的宽度
// UINT nHeight:当前窗口的高度
void OnSize(UINT nWidth, UINT nHeight)
{
    //SCROLLINFO si;
    //int        nPos;
    SIZE    size;

    size.cx  = nWidth;
    size.cy  = nHeight;
    InitScrollBar(size, TRUE);      // 初始化水平滚动条
    InitScrollBar(size, FALSE);     // 初始化垂直滚动条
}

// 处理垂直滚动条消息WM_VSCROLL
// UINT nSBCode:滚动类型
// UINT nPos:滚动条滑块位置
// HWND hScrollBar:滚动条控件句柄
void OnVScroll(UINT nSBCode, UINT nPos, HWND hScrollBar)
{
    static int nOriginalPos = 0;
    int    nTmp;
    RECT   rt;

    nTmp = nOriginalPos;
    switch(nSBCode)
    {
        case SB_TOP:           // 一次性达到最顶端
            nTmp = 0;
            break;
        case SB_BOTTOM:        // 一次性达到最底端
            nTmp = g_sInfoTextSize.cy;
            break;
        case SB_PAGEUP:        // 向上翻页
            nTmp -= 150;
            if(nTmp < 0)   nTmp = 0;
            break;
        case SB_PAGEDOWN:      // 向下翻页
            nTmp += 150;
            if(nTmp > g_sInfoTextSize.cy) nTmp = g_sInfoTextSize.cy;
            break;
        case SB_LINEUP:        // 向下翻动,通常是点击滚动条的向下箭头
            nTmp -= 20;
            if(nTmp < 0) nTmp = 0;
            break;
        case SB_LINEDOWN:      // 向下翻动,通常是点击滚动条的向下箭头
            nTmp += 20;
            if(nTmp > g_sInfoTextSize.cy) nTmp = g_sInfoTextSize.cy;
            break;
        case SB_THUMBTRACK:    // 正在拖动
            nTmp = nPos;
            break;
        case SB_THUMBPOSITION: // 拖动即将结束
            break;
        case SB_ENDSCROLL:     // 停止滚动
            break;
        default:    break;
    }
    // 设置滚动条上滑块的位置
    SetScrollPos(g_hMainWnd, SB_VERT, nTmp, TRUE);
    // 滚动窗口
    ScrollWindow(g_hMainWnd, 0, nOriginalPos - nTmp, NULL, NULL);

    // 下面计算窗口中需要更新的区域
    rt.left = 0;            rt.right  = g_sInfoTextSize.cx;
    if(nTmp > nOriginalPos)
    {
        rt.bottom = g_sInfoTextSize.cy;
        rt.top = rt.bottom - (nTmp - nOriginalPos);
    }
    else
    {
        rt.top = 0;
        rt.bottom = rt.top + (nOriginalPos - nTmp);
    }
    // 更新区域
    InvalidateRect(g_hMainWnd, &rt, TRUE);
    nOriginalPos = nTmp;
}

// 处理水平滚动条消息WM_HSCROLL
// UINT nSBCode:滚动类型
// UINT nPos:滚动条滑块位置
// HWND hScrollBar:滚动条控件句柄
void OnHScroll(UINT nSBCode, UINT nPos, HWND hScrollBar)
{
    static int nOriginalPos = 0;
    int    nTmp;
    RECT   rt;

    nTmp = nOriginalPos;
    switch(nSBCode)
    {
        case SB_LEFT:           // 一次性达到最顶端
            nTmp = 0;
            break;
        case SB_RIGHT:        // 一次性达到最底端
            nTmp = g_sInfoTextSize.cx;
            break;
        case SB_PAGELEFT:        // 向上翻页
            nTmp -= 150;
            if(nTmp < 0)   nTmp = 0;
            break;
        case SB_PAGERIGHT:      // 向下翻页
            nTmp += 150;
            if(nTmp > g_sInfoTextSize.cx) nTmp = g_sInfoTextSize.cx;
            break;
        case SB_LINELEFT:        // 向下翻动,通常是点击滚动条的向下箭头
            nTmp -= 20;
            if(nTmp < 0) nTmp = 0;
            break;
        case SB_LINERIGHT:      // 向下翻动,通常是点击滚动条的向下箭头
            nTmp += 20;
            if(nTmp > g_sInfoTextSize.cx) nTmp = g_sInfoTextSize.cx;
            break;
        case SB_THUMBTRACK:    // 正在拖动
            nTmp = nPos;
            break;
        case SB_THUMBPOSITION: // 拖动即将结束
            break;
        case SB_ENDSCROLL:     // 停止滚动
            break;
        default:    break;
    }
    SetScrollPos(g_hMainWnd, SB_HORZ, nTmp, TRUE);
    ScrollWindow(g_hMainWnd, nOriginalPos - nTmp, 0, NULL, NULL);
    rt.top = 0;            rt.bottom  = g_sInfoTextSize.cy;
    if(nTmp > nOriginalPos)
    {
        rt.right = g_sInfoTextSize.cx;
        rt.left  = rt.right - (nTmp - nOriginalPos);
    }
    else
    {
        rt.left  = 0;
        rt.right = rt.left + (nOriginalPos - nTmp);
    }
    InvalidateRect(g_hMainWnd, &rt, TRUE);
    nOriginalPos = nTmp;
}

// 响应消息WM_CLOSE
void OnClose(void)
{
    if(!g_bIsSaved)
    {
        int nRet;
        nRet = MessageBox(g_hMainWnd, "文件数据已经被更改,是否需要保存?",
                          "提示", MB_YESNOCANCEL | MB_ICONQUESTION);
        if(nRet == IDCANCEL)  return;
        else if(nRet == IDYES)
        {
            OnFileSave();
        }
    }

    DefWindowProc(g_hMainWnd, WM_CLOSE, 0, 0);
}

// 响应菜单项【新建信息文件】事件
void OnFileNew(void)
{
    if(!g_bIsSaved)
    {
        int  nRet;
        nRet = MessageBox(g_hMainWnd, "当前数据已经更改,在打开新文件前是否需要保存原数据?",
                         "提示", MB_ICONQUESTION | MB_YESNOCANCEL);
        if(nRet == IDCANCEL)    return;
        else if(nRet == IDYES)
        {
            OnFileSave();
        }
    }
    ClearLink();
    memset(g_szFileName, '\0', sizeof(g_szFileName));
    SetSaveFlag(TRUE);
    InvalidateRect(g_hMainWnd, NULL, TRUE);
}

// 响应菜单项【保存文件】事件
BOOL OnFileSave(void)
{
    // 如果文件从来就没有被保存过,即文件还没有命名,
    // 则直接调用【另存为】项功能
    if(!strlen(g_szFileName))
        return OnFileSaveAs();
    else if(!SaveLinkToFile())  // 将文件保存到链表
    {
        MessageBox(g_hMainWnd, "    文件保存失败!磁盘错误!", "错误", MB_OK | MB_ICONERROR);
        SetSaveFlag(FALSE);
        return FALSE;
    }
    SetSaveFlag(TRUE);
    return TRUE;
}

// 响应菜单项【文件另存为】事件
// 返回值:TRUE表示已经保存好,FALSE表示没有保存
BOOL OnFileSaveAs(void)
{
    TCHAR   *lpszFilePath = NULL;
    TCHAR   *lpTmp;

    lpszFilePath = CommFileDlg(TRUE);
    if(!lpszFilePath) return FALSE;
    
    // 下面的代码检查用户是否为文件输入了扩展名,如果没有输入扩展名,则加上默认扩展名".DAT"
    lpTmp = lpszFilePath;
    while(!*lpTmp)  lpTmp++;        // 搜索到字符串的最后
    while(*lpTmp != '.') lpTmp--;   // 找到最后一个‘.’字符,即看用户是否输入了文件后缀名
    if(lpTmp == lpszFilePath)
    {
        strcat(lpszFilePath, ".dat");
    }
    // 将最终的文件路径保存到全局变量
    strcpy(g_szFileName, lpszFilePath);

    if(!SaveLinkToFile())
    {
        MessageBox(g_hMainWnd, "    文件保存失败!磁盘错误!", "错误", MB_OK | MB_ICONERROR);
        return FALSE;
    }
    SetSaveFlag(TRUE);
    return TRUE;
}

// 响应菜单项【打开文件】事件
void OnFileOpen(void)
{
    TCHAR  *lpText = NULL;
    RECT    rt;
    SIZE    size;
    int     cy = 0;
    LPSTUDENT_INFO lpTmp = NULL;

    lpText = CommFileDlg(FALSE);    // 显示Windows通用文件对话框
    if(!lpText)  return;

    if(!g_bIsSaved)
    {
        int  nRet;
        nRet = MessageBox(g_hMainWnd, "当前数据已经更改,在打开新文件前是否需要保存原数据?",
                         "提示", MB_ICONQUESTION | MB_YESNOCANCEL);
        if(nRet == IDCANCEL)    return;
        else if(nRet == IDYES)
        {
            if(!OnFileSave())
            {
                return;
            }
        }
    }
    ClearLink();
 
    strcpy(g_szFileName, lpText);
    if(!ReadLinkFromFile())
    {
        MessageBox(g_hMainWnd, "    文件打开失败!数据错误!", "错误", MB_OK | MB_ICONERROR);
        ClearLink();
    }
    SortLinkBy((enum tagSortBy)g_uOrderByField, g_bOrderByAsc);
    SetSaveFlag(TRUE);

    GetClientRect(g_hMainWnd, &rt);
    size.cx = rt.right  - rt.left;
    size.cy = rt.bottom - rt.top;

    // 重置滚动条
    lpTmp=g_lpStudentHeader;
    cy = 60;
    while(lpTmp)
    {
        cy += 16;
        lpTmp=lpTmp->m_lpNext;
    }
    g_sInfoTextSize.cy = cy;    // 得到文本的高度
    InitScrollBar(size, FALSE); // 重置滚动条
    InvalidateRect(g_hMainWnd, NULL, TRUE);
    return;
}

// 响应菜单项【添加新学生】事件
void OnToolAddNew(void)
{
    int   nRet;
    RECT  rt;
    SIZE  size;

    // 弹出【新建学生】对话框
    nRet = DialogBoxParam(g_hAppInst, (LPCTSTR)IDD_NEWSTU_DLG, g_hMainWnd, (DLGPROC)NewStuDlgProc, NULL);
    if(nRet == IDCANCEL || nRet == 0) return;

    AddToLink((LPSTUDENT_INFO)nRet);  // 将学生信息添加到链表
    g_sInfoTextSize.cy += 16;         // 当前文本信息的最大宽度将增加
    GetClientRect(g_hMainWnd, &rt);
    size.cx = rt.right  - rt.left;
    size.cy = rt.bottom - rt.top;
    InitScrollBar(size, FALSE);       // 此时还需要重置垂直滚动条

    // 保证插入新节点之后链表仍然是排序的
    SortLinkBy((enum tagSortBy)g_uOrderByField, g_bOrderByAsc);
    SetSaveFlag(FALSE);
    InvalidateRect(g_hMainWnd, NULL, TRUE);
    return;
}

// 响应菜单项【删除一个学生】事件
void OnToolDelete(void)
{
    int   nRet;
    RECT  rt;
    SIZE  size;

    // 弹出【删除一个学生】对话框
    nRet = DialogBoxParam(g_hAppInst, (LPCTSTR)IDD_DELETE_DLG, g_hMainWnd, (DLGPROC)DeleteDlgProc, TRUE);
    if(nRet == IDCANCEL) return;
    DeleteFromLink((LPSTUDENT_INFO)nRet);

    g_sInfoTextSize.cy -= 16;         // 当前文本信息的最大宽度将减少
    GetClientRect(g_hMainWnd, &rt);
    size.cx = rt.right  - rt.left;
    size.cy = rt.bottom - rt.top;
    InitScrollBar(size, FALSE);       // 此时需要重置垂直滚动条
    InvalidateRect(g_hMainWnd, NULL, TRUE);
}

// 响应菜单项【修改一个学生信息】事件
void OnToolModify(void)
{
    // 弹出【修改一个学生信息】对话框
    DialogBoxParam(g_hAppInst, (LPCTSTR)IDD_DELETE_DLG, g_hMainWnd, (DLGPROC)DeleteDlgProc, FALSE);
}

/////////////////////////////////////////////////////////////////
// 主窗口消息响应函数到此结束
/////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////
// 下面都是链表操作函数
/////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -