📄 dialgbox.cpp
字号:
/**********************************
Dialogbox.cpp文件
定义了对话框类PopOutBoxClass,
用于系统和用户之间的信息交换,
保证了本软件的安全性和易用性
**********************************/
#define mDIALOGMODE 0
#define mINPUTMODE 1
#define mDIRMODE_SAVE 2
#define mDIRMODE_OPEN 3
#define mDIRSEARCH 16
#define mFILESEARCH 0
//定义按钮类
class ButtonClass:public Item
{
private:
int iCaption[10]; //按钮名称
public:
int x,y; //按钮位置
ButtonClass(int ix,int iy,char *Caption); //初始化按钮
void GetFocus(); //按钮得到焦点
void LoseFocus(); //按钮失去焦点
};
//定义文件列表框类
class FileListClass:public Item
{
private:
FILE *fp;
int iCurFile; //文本列表框当前选定的文件序号
int iStartColm; //开始显示的文件序号
int iDirCount,iFileCount; //文本列表框中的目录总数和文件总数
int FindFile(); //查找文件
void Order(int iLow,int iHight); //文件排序
int Partiton(int iLow,int iHight); //
public:
int iTop,iLeft; //文本框位置
const int iWidth,iHeight; //文本框尺寸
char *cCurDirect; //当前目录名指针
FileListClass(int Top,int Left,char *Text); //
~FileListClass();
int GetKey(char c); //文件列表框的键盘响应
void GetFocus(); //得到焦点
void LoseFocus(); //失去焦点
void MouseClick(char cPosex,char cPosey);//鼠标点击响应
void Refresh(); //文本框刷新
friend class PopOutBoxClass;
};
//定义简单文本框类
class SimpleTextWinClass:public Item
{
private:
int iStartColm; //文本开始显示的字符序号
public:
int iTop,iLeft,iWidth; //文本框位置尺寸
int iCurColm; //光标位置
char cInputText[256]; //输入文本字符串
SimpleTextWinClass(int Top,int Left,int Width); //
void GetKey(char c); //键盘响应
void GetFocus(); //得到焦点
void LoseFocus(); //失去焦点
void Refresh(); //文本框刷新
};
class PopOutBoxClass
{
private:
char *cCaption; //对话框标题字符串指针
char *cText; //对话框文本字符串指针
int *iBuf; //屏幕数据保护缓冲区指针
int iMode; //显示模式,一共有
//mDIALOGMODE简单对话框模式
//mINPUTMODE输入框模式
//mDIRMODE_SAVE"保存"对话框模式
//mDIRMODE_OPEN"打开"对话框模式
int iCurButton; //指示当前激活对象
Item *Items[4]; //指向按钮、文本框和文件列表框的指针
ButtonClass *Buttons[2]; //两个按钮对象指针
SimpleTextWinClass *TextWin; //文本框指针
FileListClass *FileList; //文件列表框指针
int KeyInput_DialogMode(); //对话框模式的键盘输入程序
int KeyInput_InputMode(); //输入框模式的键盘输入程序
int KeyInput_DirectMode(int c=0); //带文件列表框模式的键盘输入程序
int MouseClick(char cPosex,char cPosey); //鼠标点击响应
void Show(char *cAddString); //显示对话框
public:
int iTop,iLeft,iWidth,iHeight; //对话框尺寸位置
char *cInputText; //对话框输入文本指针
PopOutBoxClass(char *Caption,char *Text,int Mode);//初始化对话框
~PopOutBoxClass();
int CreateDialogBox(char *cAddString=""); //生成显示对话框
};
/*------------------------------------
ButtonClass
-------------------------------------*/
//按钮类构造函数
ButtonClass::ButtonClass(int ix,int iy,char *cCaption)
{
//确定按钮位置
x=ix;y=iy;
int i=0;
//定义按钮名称和显示模式
iCaption[i++]=(GREEN<<12)|' ';
for(;i<10&&cCaption[i-1]!='\0';i++)
iCaption[i]=(GREEN<<12)|0xff&cCaption[i-1];
for(;i<10;i++)
iCaption[i]=(GREEN<<12)|' ';
}
//按钮得到焦点函数
void ButtonClass::GetFocus()
{//按钮以高亮度显示
_setcursortype(_NOCURSOR);
for(int i=0;i<10;i++) iCaption[i]|=WHITE<<8;
puttext(x,y,x+9,y,iCaption);
}
//按钮失去焦点函数
void ButtonClass::LoseFocus()
{//取消按钮的高亮度
for(int i=0;i<10;i++) iCaption[i]=iCaption[i]&0xf0ff|(BLACK<<8);
puttext(x,y,x+9,y,iCaption);
}
/*----------------------------------
FileListClass
----------------------------------*/
//文件列表框类构造函数
FileListClass::FileListClass(int Top,int Left,char *Text=NULL):iWidth(31),iHeight(8)
{
//定义文件列表框位置
iTop=Top;iLeft=Left;
//设顶cCurDirect指向用于存储目录名的存储空间
if(Text==NULL) //如果没有给定该空间地址,那么重新开辟空间
cCurDirect=(char *)malloc(256);
else
cCurDirect=Text;
//将当前目录名存储于cCurDirect指向的内存空间
strcpy(cCurDirect,"X:\\");
cCurDirect[0]='A'+getdisk(); //得到当前驱动器名
getcurdir(0,cCurDirect+3);
strcat(cCurDirect,"\\*.*");
//打开Dirlist.lst文件作为存储文件名的空间
fp=fopen("dirlist.lst","wb+");
if(fp==NULL) exit(0);
//查询当前目录下的文件和目录
FindFile();
//从第一个文件开始显示,当前文件为第一个文件
iStartColm=0;iCurFile=0;
}
//FileListClass析构函数
FileListClass::~FileListClass()
{
//关闭Dirlist.lst文件
fclose(fp);
//删除该文件
remove("dirlist.lst");
}
//查找文件和目录函数
int FileListClass::FindFile()
{
unsigned Attr;
struct ffblk ffblk;
int i,done,notroot=0;
char cTemp[13];
//检测目录名输入是否合法
for(i=strlen(cCurDirect);cCurDirect[i-1]!='\\';i--);
//如果只输入了目录名,那么追加"*.*"为文件名便于查找
if(cCurDirect[i]=='\0')
strcat(cCurDirect,"*.*");
//如果只输入了扩展名,那么追加"*"为文件名便于查找
if(cCurDirect[i]=='.')
{
strcpy(cTemp,cCurDirect+i);
cCurDirect[i]='*';
strcpy(cCurDirect+i+1,cTemp);
}
//文件计数器,目录计数器清零
iFileCount=0;
iDirCount=0;
//为向DirList.lst中写数据做好准备
fseek(fp,0,0);
strcpy(cTemp,cCurDirect+i);
strcpy(cCurDirect+i,"*.*");
//开始查找文件
if(findfirst(cCurDirect,&ffblk,mDIRSEARCH))
{//如果没有文件,那么函数返回
strcpy(cCurDirect+i,cTemp);
return -1;
}
strcpy(cCurDirect+i,cTemp);
done = findfirst(cCurDirect,&ffblk,mFILESEARCH);
while (!done)
{
iFileCount++; //文件计数器加一
fwrite(ffblk.ff_name,13,1,fp); //将文件名存储在Dirlist.lst文件中
done = findnext(&ffblk); //寻找下一个文件
}
//开始查找目录
strcpy(cTemp,cCurDirect+i);
strcpy(cCurDirect+i,"*");
done = findfirst(cCurDirect,&ffblk,mDIRSEARCH);
while (!done)
{
if(ffblk.ff_attrib&mDIRSEARCH
&&ffblk.ff_name[0]!='.')
{
//找到的不是".\"目录或"..\"目录,
//那么目录计数器加一,并且目录名存储在Dirlist.lst文件中
iDirCount++;
strcat(ffblk.ff_name,"\\");
fwrite(ffblk.ff_name,13,1,fp);
}
//如果没有找到".\"目录或"..\"目录,说明是根目录
if(ffblk.ff_name[0]=='.') notroot=1;
done = findnext(&ffblk);
}
//恢复用户输入的目录名和文件名
strcpy(cCurDirect+i,cTemp);
//对文件名进行排序
Order(0,iFileCount-1);
//对目录名进行排序
Order(iFileCount,iFileCount+iDirCount-1);
fseek(fp,(iFileCount+iDirCount)*13,0);
if(notroot)
{
//如果当前目录不是根目录,那么追加"..\"做为上级目录标记
fwrite("..\\",13,1,fp);
iDirCount++;
}
iStartColm=0;iCurFile=0;
return iFileCount;
}
//键盘输入响应函数
int FileListClass::GetKey(char c)
{
char cfilename[13];
LoseFocus(); //清除高亮度显示
//根据输入字符做出响应
switch(c)
{
//如果是方向键输入,那么改变当前选定的文件名或目录名
case 72:iCurFile--;break;
case 80:iCurFile++;break;
case 75:iCurFile-=8;break;
case 77:iCurFile+=8;
}
if(c=='\r') //如果输入的是回车键
{
int i,len=strlen(cCurDirect);
char ctemp;
//准备用cCurDirect所指向的空间返回用户选定的文件名
if(len+13>255) exit(0);
while(cCurDirect[len--]!='\\');
len+=2;
fseek(fp,iCurFile*13,0);
fread(cfilename,13,1,fp);
if(iCurFile<iFileCount)
{ //如果选定的是文件,那么将文件名和目录连为一体,返回
strcpy(cCurDirect+len,cfilename);
return 1;
}
else if(iCurFile<iFileCount+iDirCount)
{ //如果选定的是目录,那么建立新的目录名,并重新查询文件名
if(cfilename[0]=='.')
{
i=len-2;
while(cCurDirect[i--]!='\\');
i+=2;
strcpy(cCurDirect+i,cCurDirect+len);
FindFile();
}
else
{//如果选定的是上一级目录,那么建立新目录名,重新查询文件名
for(i=0;i<14;i++,len++)
{
c=cCurDirect[len];
cCurDirect[len]=cfilename[i];
cfilename[i]=c;
}
strcat(cCurDirect,cfilename);
FindFile();
}
}
}
Refresh(); //刷新文件列表框
GetFocus(); //高亮度显示用户选定的文件名
return 0;
}
//文件列表得到焦点
void FileListClass::GetFocus()
{
//将当前文件名用高亮度显示
int x,y,iCount;
_setcursortype(_NOCURSOR);
iCount=iCurFile-(iStartColm<<3);
x=(iCount<<1)&0x10;
y=iCount&0x07;
ChangeColor(iLeft+x,iTop+y,iLeft+x+14,iTop+y,GREEN<<4|WHITE);
}
//文件列表失去焦点
void FileListClass::LoseFocus()
{
//去掉高亮度显示
int x,y,iCount;
iCount=iCurFile-(iStartColm<<3);
x=(iCount<<1)&0x10;
y=iCount&0x07;
ChangeColor(iLeft+x,iTop+y,iLeft+x+14,iTop+y,CYAN<<4|BLACK);
}
//快速排序法,枢轴函数
int FileListClass::Partiton(int iLow,int iHight)
{
char cPivotkey[13];
char cFilename1[13],cFilename2[13];
fseek(fp,iLow*13,0);
fread(cPivotkey,13,1,fp);
strcpy(cFilename1,cPivotkey);
while(iLow<iHight)
{
do //将文件名字母小的文件排到枢轴的前面
{
fseek(fp,iHight*13,0);
fread(cFilename2,13,1,fp);
if(strcmp(cFilename2,cPivotkey)<0) break;
iHight--;
}while(iLow<iHight);
fseek(fp,iLow*13,0);
fwrite(cFilename2,13,1,fp);
do //将文件名字母大的文件排到枢轴的后面
{
fseek(fp,iLow*13,0);
fread(cFilename1,13,1,fp);
if(strcmp(cFilename1,cPivotkey)>0) break;
iLow++;
}while(iLow<iHight);
fseek(fp,iHight*13,0);
fwrite(cFilename1,13,1,fp);
}
//将枢轴排到相应位置
fseek(fp,iLow*13,0);
fwrite(cPivotkey,13,1,fp);
return iLow; //返回枢轴位置
}
//快速排序
void FileListClass::Order(int iLow,int iHight)
{
int iPivotloc;
if(iLow<iHight)
{
iPivotloc = Partiton(iLow,iHight); //初步排序
Order(iLow,iPivotloc-1); //将枢轴前面的项排序
Order(iPivotloc+1,iHight); //将枢轴后面的项排序
}
}
//鼠标响应函数
void FileListClass::MouseClick(char cPosex,char cPosey)
{
//将当前文件设定为鼠标点击的文件
iCurFile=(iStartColm<<3)+cPosey-iTop;
if(cPosex>iLeft+(iWidth>>1))
iCurFile+=8;
Refresh();
}
//刷新函数
void FileListClass::Refresh()
{
int i,j,k;
int x;
int iShowBuf[15]={' '|(CYAN<<12)|(BLACK<<8)};
char cFileName[13];
//如果当前文件序号iCurFile不合法,那么修订iCurFile
if(iCurFile<0) iCurFile=0;
if(iDirCount+iFileCount<=0) {iCurFile=0;return;}
if(iCurFile>=iDirCount+iFileCount) iCurFile=iDirCount+iFileCount-1;
//找到开始显示的文件序号
while(iCurFile<(iStartColm<<3)) iStartColm--;
while(iCurFile>(iStartColm<<3)+15) iStartColm++;
//绘制文件列表框
for(i=iStartColm<<3,j=0,fseek(fp,i*13,0);
i<iDirCount+iFileCount&&j<16;
i++,j++)
{
fread(cFileName,13,1,fp);
for(k=0;cFileName[k];k++)
iShowBuf[k+1]=0xff&cFileName[k]|(CYAN<<12)|(BLACK<<8);
for(;k<14;k++)
iShowBuf[k+1]=' '|(CYAN<<12)|(BLACK<<8);
puttext(iLeft+((j<<1)&0x10),iTop+(j&0x7),iLeft+((j<<1)&0x10)+14,iTop+(j&0x7),iShowBuf);
}
for(;j<16;j++)
{
for(k=0;k<14;k++)
iShowBuf[k+1]=' '|(CYAN<<12)|(BLACK<<8);
puttext(iLeft+((j<<1)&0x10),iTop+(j&0x7),iLeft+((j<<1)&0x10)+14,iTop+(j&0x7),iShowBuf);
}
for(k=0;k<8;k++)
iShowBuf[k]='
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -