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

📄 dialog.c

📁 这是早期MiniGUI DOS版本的最终版
💻 C
📖 第 1 页 / 共 5 页
字号:
// Dialog.c The implementation file of dialog.
//
// This file include functions that handle
// dialog box procedures, message box procedure etc.
//
// Copyright (c) 1994.8 ~ 1998.4, Mr. Wei Yongming.
//
// Last modified date: 1998.04.15.

#include <stdio.h>
#include <conio.h> 
#include <io.h>
#include <dos.h>
#include <bios.h>
#include <process.h>
#include <time.h>
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
#include <graph.h>
#include <memory.h>
#include <Vmemory.h>
#include <string.h>
#include <direct.h>
#include <ctype.h>
#include <float.h>
#include <math.h>

#include "Common.h"
#include "Support.h"
#include "MainGUI.h"
#include "Dialog.h"

extern struct _videoconfig vc;
extern BOOL fNewKb;
extern void (__interrupt __far *oldvect)();

static MSGBOXDATA MsgBoxData;
static int CtrlIndex;
static BOOL fAlreadyUp;
    
static void CheckCtrl( PDLGHEADER pDlgHeader, PCTRLDATA pCtrlData );
static void PushButton(PCTRLDATA pCurCtrl, BOOL uCheck);
static void DrawBox( short lx, short ty, short rx, short by );
static void DrawFocus(PCTRLDATA pCtrlData);
static void CheckButtonDown(BOOL fDlg, PDLGHEADER pDlgHeader, PMSG pMsg);
static void CheckButtonUp(BOOL fDlg, PDLGHEADER pDlgHeader, PMSG pMsg, int CtrlIndex);

static BOOL StartDialog( PDLGHEADER pDlgHeader );
static BOOL CreateDialog( PDLGHEADER pDlgHeader, int (FAR *DlgProc)() );
static void EndDialog( PDLGHEADER pDlgHeader );

static PCTRLDATA GetNextTabstop( PDLGHEADER pDlgHeader, PCTRLDATA pCtrlData );
static PCTRLDATA GetLastTabstop( PDLGHEADER pDlgHeader, PCTRLDATA pCtrlData );
static PCTRLDATA GetNextItemInGroup( PDLGHEADER pDlgHeader, PCTRLDATA pCtrlData );
static PCTRLDATA GetLastItemInGroup( PDLGHEADER pDlgHeader, PCTRLDATA pCtrlData );

static BOOL HaveCancelButton( PDLGHEADER pDlgHeader );

static void DrawListBoxItem( PCTRLDATA pCtrlData, int iOffset, int iIndex, BOOL fSel );
static void ScrollListBox(PCTRLDATA pCtrlData, WORD uAction);
static void SetVScrollPosition(PCTRLDATA pCtrlData, BOOL fErase);

// 系统“有关……”对话框
static DLGHEADER  SysAboutDlg = {WS_BORDER|WS_POPUP|WS_CAPTION, 17, 70,100,490,274, NULL, "有关MINIGUI--图形用户界面支持系统"};
// 系统文件打开/保存对话框
static DLGHEADER  OpenFileDlg = {WS_BORDER|WS_POPUP|WS_CAPTION, 8, 100,100,416,230, NULL, NULL};
// 系统简单文件打开/保存对话框,此对话框只能完成在特定目录下的文件打开和保存功能。
static DLGHEADER  SimpleOpenFileDlg = {WS_BORDER|WS_POPUP|WS_CAPTION, 7, 70, 80, 354, 244, NULL, "选择要打开的文件"};

static CTRLDATA   SysDlgCtrl[]={
        // About Box's controls
        {SS_OWNER, 12, 10,84,84, IDC_ICON, STATIC, NULL, NULL},
        {SS_LEFT, 106, 8, 340, 16, IDC_STATIC, STATIC, "MINIGUI--图形用户界面支持系统  版本3.0", NULL},
        {SS_LEFT, 106, 26, 370, 16, IDC_STATIC, STATIC, "版权 (C) 1995~1998 清华大学魏永明", NULL},
        {SS_LEFT, 106, 44, 370, 16, IDC_STATIC, STATIC, "部分版权 (C) 清华大学李铁民", NULL},
        {SS_LEFT, 106, 72, 340, 16, IDC_STATIC, STATIC, "本支持系统的合法使用者是", NULL},
        {SS_LEFT, 106, 96, 340, 16, IDC_STATIC, STATIC, "清华大学", NULL},
        {SS_LEFT, 106, 116, 340, 16, IDC_STATIC, STATIC, "精仪系科协", NULL},
        {SS_BLACKRECT, 106, 138, 374, 2, IDC_STATIC, STATIC, NULL,NULL},
        {SS_LEFT, 106, 152, 130, 16, IDC_STATIC, STATIC, "近堆中可用内存:", NULL},
        {SS_LEFT, 106, 174, 130, 16, IDC_STATIC, STATIC, "远堆最大内存块:", NULL},
        {SS_LEFT, 106, 196, 114, 16, IDC_STATIC, STATIC, "数学协处理器:", NULL},
        {SS_LEFT, 106, 218, 114, 16, IDC_STATIC, STATIC, "剩余磁盘空间:", NULL},
        {SS_OWNER, 250, 152, 114, 16, IDC_MEMORY, STATIC, NULL, NULL},
        {SS_OWNER, 250, 174, 114, 16, IDC_FARMEMORY, STATIC, NULL, NULL},
        {SS_OWNER, 250, 196, 114, 16, IDC_MATH, STATIC, NULL, NULL},
        {SS_OWNER, 250, 218, 114, 16, IDC_DISK, STATIC, NULL, NULL},
        {BS_PUSHBUTTON | WS_TABSTOP, 390,167,80,30, IDOK, BUTTON, "确定", NULL},

        // Open and Save As Box's controls
        {SS_LEFT, 14, 16, 92, 18, IDC_STATIC, STATIC, "文件名:", NULL},
        {SS_LEFT, 160, 16, 160, 18, IDC_STATIC, STATIC, "目录/驱动器:", NULL},
        {ES_LEFT | WS_TABSTOP,  14,40,127,20, IDC_FILENAME, EDIT, NULL, NULL},
        {SS_OWNER, 160, 42, 240, 18, IDC_DIRECTORY, STATIC, NULL, NULL},
        {WS_VSCROLL | WS_BORDER | WS_TABSTOP, 14, 74, 128, 112, IDC_FILE, LISTBOX, NULL, NULL},
        {WS_VSCROLL | WS_BORDER | WS_TABSTOP, 160, 74, 128, 112, IDC_DIR, LISTBOX, NULL, NULL},
        {BS_PUSHBUTTON | WS_TABSTOP, 300,108,100,28, IDOK, BUTTON, "确定", NULL},
        {BS_PUSHBUTTON | WS_TABSTOP, 300,150,100,28, IDCANCEL, BUTTON, "取消", NULL},
        
        // Simple Open and Save file dialog
        {SS_LEFT,  14,12,132,18, IDC_STATIC, STATIC, "当前目录/驱动器:", NULL},
        {SS_OWNER, 14,36,328,18, IDC_DIRECTORY, STATIC, NULL, NULL},
        {SS_LEFT,  14,60,68,18, IDC_STATIC, STATIC, "文件名:", NULL},
        {ES_LEFT | WS_TABSTOP,  84,60,134,18, IDC_FILENAME, EDIT, NULL, NULL},
        {WS_VSCROLL | WS_BORDER | WS_TABSTOP, 84,94,134,112, IDC_FILE, LISTBOX, NULL, NULL},
        {BS_PUSHBUTTON | WS_TABSTOP, 240,56,100,28, IDOK, BUTTON, "确定", NULL},
        {BS_PUSHBUTTON | WS_TABSTOP, 240,94,100,28, IDCANCEL, BUTTON, "取消", NULL},
    };

PDLGHEADER GUIAPI GetSysDlgHeader(int iID)
{
    int j;
    switch(iID)
    {
        case IDD_SYSABOUTDLG:
            if(SysAboutDlg.pCtrlData == NULL)
            {
                SysAboutDlg.pCtrlData = SysDlgCtrl;

                SysAboutDlg.rx += SysAboutDlg.lx;
                SysAboutDlg.by += SysAboutDlg.ty;
                for(j=0; j<SysAboutDlg.NumOfItems; j++)
                {
                    (SysAboutDlg.pCtrlData + j)->lx = (SysAboutDlg.pCtrlData + j)->lx
                        + SysAboutDlg.lx;
                    (SysAboutDlg.pCtrlData + j)->rx = (SysAboutDlg.pCtrlData + j)->rx
                        + (SysAboutDlg.pCtrlData + j)->lx;
                    (SysAboutDlg.pCtrlData + j)->ty = (SysAboutDlg.pCtrlData + j)->ty
                        + SysAboutDlg.ty + 25;
                    (SysAboutDlg.pCtrlData + j)->by = (SysAboutDlg.pCtrlData + j)->by
                        + (SysAboutDlg.pCtrlData + j)->ty;
                }
            }
            return &SysAboutDlg;
            
        case IDD_OPENFILEDLG:
            if(OpenFileDlg.pCtrlData == NULL)
            {
                OpenFileDlg.pCtrlData = SysDlgCtrl + 17;

                OpenFileDlg.rx += OpenFileDlg.lx;
                OpenFileDlg.by += OpenFileDlg.ty;
                for(j=0; j<OpenFileDlg.NumOfItems; j++)
                {
                    (OpenFileDlg.pCtrlData + j)->lx = (OpenFileDlg.pCtrlData + j)->lx
                        + OpenFileDlg.lx;
                    (OpenFileDlg.pCtrlData + j)->rx = (OpenFileDlg.pCtrlData + j)->rx
                        + (OpenFileDlg.pCtrlData + j)->lx;
                    (OpenFileDlg.pCtrlData + j)->ty = (OpenFileDlg.pCtrlData + j)->ty
                        + OpenFileDlg.ty + 25;
                    (OpenFileDlg.pCtrlData + j)->by = (OpenFileDlg.pCtrlData + j)->by
                        + (OpenFileDlg.pCtrlData + j)->ty;
                }
            }
            return &OpenFileDlg;
            
        case IDD_SIMPLEOPENFILEDLG:
            if(SimpleOpenFileDlg.pCtrlData == NULL)
            {
                SimpleOpenFileDlg.pCtrlData = SysDlgCtrl + 25;

                SimpleOpenFileDlg.rx += SimpleOpenFileDlg.lx;
                SimpleOpenFileDlg.by += SimpleOpenFileDlg.ty;
                for(j=0; j<SimpleOpenFileDlg.NumOfItems; j++)
                {
                    (SimpleOpenFileDlg.pCtrlData + j)->lx = (SimpleOpenFileDlg.pCtrlData + j)->lx
                        + SimpleOpenFileDlg.lx;
                    (SimpleOpenFileDlg.pCtrlData + j)->rx = (SimpleOpenFileDlg.pCtrlData + j)->rx
                        + (SimpleOpenFileDlg.pCtrlData + j)->lx;
                    (SimpleOpenFileDlg.pCtrlData + j)->ty = (SimpleOpenFileDlg.pCtrlData + j)->ty
                        + SimpleOpenFileDlg.ty + 25;
                    (SimpleOpenFileDlg.pCtrlData + j)->by = (SimpleOpenFileDlg.pCtrlData + j)->by
                        + (SimpleOpenFileDlg.pCtrlData + j)->ty;
                }
            }
            return &SimpleOpenFileDlg;
    }
    
    return NULL;
}

/*
 * Function: int FAR SysAboutBoxProc( PDLGHEADER pDlgHeader, UINT uAction, PCTRLDATA pCtrlData, LONG lParam ).
 *      This function process the system about dialog box.
 * Parameters:
 *      pDlgHeader: the pointer to DLGHEADER structure.
 *      uAction: the Message given by DialogBoxParam function;
 *      pCtrlData: the control that have input focus;
 *      lParam: the LONG type parameter.
 * Return: 
 *      DEFAULT: for current action, to handle with a default procdure;
 *      OWNER  : for current action, not to handle with default;
 *      COLSE  : close dialog;
 *      NOCLOSE: do not close dialog.
 */
int FAR SysAboutBoxProc( PDLGHEADER pDlgHeader, UINT uAction, WORD wID, LONG lParam )
{
    char strBuffer[40];
    unsigned maxsize;
    
    switch(uAction)
    {
        case INITDIALOG:
        return DEFAULT;
        
        case COMMAND:
            switch(wID)
            {
                case IDOK:
                case IDCANCEL:
                return CLOSE;
                
                default:
                return DEFAULT;
            }
        break;

        case DRAWCTRL:
            if(wID == IDC_ICON)
            {
                Bitmap((LPSTR)".\\bin\\minigui1.bmp", 14, ((PCTRLDATA)lParam)->lx, ((PCTRLDATA)lParam)->by);
                Bitmap((LPSTR)".\\bin\\minigui2.bmp", 8, ((PCTRLDATA)lParam)->lx, ((PCTRLDATA)lParam)->by);
                return OWNER;
            }
        return DEFAULT;
        
        case DRAWTEXT:
            switch( wID )
            {
                case IDC_MEMORY:
                    sprintf(strBuffer, "%d Kb", _memavl()/1024);
                    cc_wt16(strBuffer, ((PCTRLDATA)lParam)->lx, ((PCTRLDATA)lParam)->ty);
                    return OWNER;
                    
                case IDC_FARMEMORY:
                    _dos_allocmem(0xFFFF, &maxsize);
                    sprintf(strBuffer, "%d Kb", maxsize/64);
                    cc_wt16(strBuffer, ((PCTRLDATA)lParam)->lx, ((PCTRLDATA)lParam)->ty);
                    return OWNER;
                    
                case IDC_MATH:
                    if(_bios_equiplist() & 0x0002)
                        strcpy(strBuffer, "已安装");
                    else
                        strcpy(strBuffer, "未安装");
                    cc_wt16(strBuffer, ((PCTRLDATA)lParam)->lx, ((PCTRLDATA)lParam)->ty);
                    return OWNER;
                    
                case IDC_DISK:
                {
                    // fill disk free information
                    struct _diskfree_t diskfree;
                    if (_dos_getdiskfree(_getdrive(), &diskfree) == 0)
                    {
                        sprintf(strBuffer, "%ld Kb",
                            (DWORD)diskfree.avail_clusters *
                            (DWORD)diskfree.sectors_per_cluster *
                            (DWORD)diskfree.bytes_per_sector / (DWORD)1024L);
                    }
                    else
                        strcpy(strBuffer, "无可用空间");
                    cc_wt16(strBuffer, ((PCTRLDATA)lParam)->lx, ((PCTRLDATA)lParam)->ty);
                    return OWNER;
                }
                
            }
        return DEFAULT;
            
        default:
        return DEFAULT;
    }
    return DEFAULT;
}

// static functions used by OpenBoxProc
static void FillFileListBox(PDLGHEADER pDlgHeader, WORD wID, PSTR pFileName)
{
    struct find_t c_file;
    
    if(_dos_findfirst(pFileName, _A_NORMAL, &c_file) == 0)
    {
        if(!(c_file.attrib & _A_SUBDIR))
            AddListBoxItem(pDlgHeader, wID, c_file.name);
    }
    else
        return;

    while( _dos_findnext(&c_file) == 0)
        if(!(c_file.attrib & _A_SUBDIR))
            AddListBoxItem(pDlgHeader, wID, c_file.name);
}

static void FillDirListBox(PDLGHEADER pDlgHeader, WORD wID)
{
    struct find_t c_file;
    
    if(_dos_findfirst("*.*", _A_SUBDIR, &c_file) == 0)
    {
        if(c_file.attrib & _A_SUBDIR)
            if(strcmp(c_file.name, ".") != 0)
                AddListBoxItem(pDlgHeader, wID, c_file.name);
    }
    else
        goto adddrive;
    
    while( _dos_findnext(&c_file) == 0)
    {
        if(c_file.attrib & _A_SUBDIR)
            AddListBoxItem(pDlgHeader, wID, c_file.name);
    }
    
adddrive:
    AddListBoxItem(pDlgHeader, IDC_DIR, "[D]");
    AddListBoxItem(pDlgHeader, IDC_DIR, "[C]");
}

static BOOL CheckFileName(BOOL fOpen, PSTR filename)
{
    if(fOpen)
    {
        if(_access(filename, 0) == -1)
        {
            MessageBox(NULL, "无法找到给定的文件!", "文件打开", MB_OK);
            return FALSE;
        }
    }
    else
    {
        if(_access(filename, 0) == 0)
        {
            if(MessageBox(NULL, "给定的文件已存在,是否替换?", "文件另存为", 
                    MB_YESNO | MB_ICONQUESTION) == IDNO)
            return FALSE;
        }
        if(strpbrk(filename," #%;/\\") != NULL)
        {
            MessageBox(NULL, "由于给定的文件名中有歧义字符,\n无法用给定的文件名创建文件!", "文件另存为", 
                    MB_OK);
            return FALSE;
        }
        {
            char* spExtName;
            int iWholeL, iExtL, iNameL;
                            
            iWholeL = strlen(filename);
            spExtName = strchr(filename, '.');
            if(spExtName == NULL)
            {
                iExtL = 0;
                iNameL = iWholeL - iExtL;
            }
            else
            {
                iExtL = strlen(spExtName + 1);
                iNameL = iWholeL - iExtL - 1;
            }
                
            if(iExtL > 3 || iNameL > 8)
            {
                MessageBox(NULL, "给定的文件名(或后缀名)太长!", "文件另存为",
                    MB_OK);
                return FALSE;
            }
        }
    }
    
    return TRUE;
}

/*
 * Function: int FAR OpenBoxProc( PDLGHEADER pDlgHeader, UINT uAction, PCTRLDATA pCtrlData, LONG lParam ).
 *      This function Process the open file dialog box.
 * Parameters:
 *      pDlgHeader: the pointer to DLGHEADER structure.
 *      uAction: the Message given by DialogBoxParam function;
 *      pCtrlData: the control that have input focus;
 *      lParam: the LONG type parameter.
 * Return: 

⌨️ 快捷键说明

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