globefun.cpp

来自「深入浅出Visual C++入门进阶与应用实例 随书光盘 作者 何志丹」· C++ 代码 · 共 448 行

CPP
448
字号


#include "stdafx.h"
#include "GlobeFun.h"


//*********************************************************************
//  函数名称: CreateDBFile
//  函数说明: 
//  入口参数:
//  HDBType type -- 
//  CString strFileName -- 
//  返回值  :
//  bool  -- 
//  作者    : 何志丹 
//  时间    : 2005-01-05 14:21:34 
//*********************************************************************
bool CreateDBFile(HDBType type,CString strFileName)
{
	CString strResName,strResType;
	strResName = pDBTemResID[type];
	strResType = pUserResType[type];	
	
	//取得资源
	HRSRC hmdbFile = ::FindResource(ghInstance, strResName, strResType);
	HGLOBAL hRes = ::LoadResource(ghInstance, hmdbFile);
	DWORD dwResSize = ::SizeofResource(ghInstance, hmdbFile);
	
	//将资源写进文件
	if(NULL == hRes)
		return false;
	UINT FAR* lpnRes = (UINT FAR*)::LockResource(hRes);	
	try
	{
		CFile f( strFileName, CFile::modeCreate | CFile::modeWrite );
		f.WriteHuge(lpnRes, dwResSize);
		f.Flush();
	}
	catch( CFileException* e )
	{
	//	afxDump << "File could not be opened " << e->m_cause << "\n";
	}
		
#ifndef WIN32 
		::UnlockResource(hRes);
#endif
	::FreeResource(hRes);

	return true;
}

bool GetCreateDBFTableSql(CString strTableName,HFIELDINFOS& fileinfos,CStringArray& arSql)
{
	CString strSQLExcute,sFormat;
	CString strTemp = "[" + strTableName + "]";

	strSQLExcute.Format("create table [%s] (ID char(7) ",strTableName);

	const int fieldCount = fileinfos.GetSize();
	//通过判断字段的长度来确定字段的类型,大于250就设为备注类型,小于250就设为文本类型
	for(int  i=0;i<fieldCount ;i++)
	{
		if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
		{
			if (fileinfos[i]->sFieldName.GetLength() > 10)
				sFormat.Format("%s Memo",fileinfos[i]->sFieldName.Left(10));
			else 
				sFormat.Format("%s Memo",fileinfos[i]->sFieldName);
		}
		else//字段长度小于250就此字段设为文本类型
		{
			if (fileinfos[i]->sFieldName.GetLength() > 10)
				sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName.Left(10),fileinfos[i]->iFieldLength);
			else 
				sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
		}	
		sFormat = "," + sFormat;
		if(strlen(strSQLExcute) + sFormat.GetLength() > nMaxSql) 
		{		   
			break;
		}			
		strSQLExcute += sFormat ;		   
	}
	strSQLExcute += ")";
	arSql.Add(strSQLExcute);
	
	const CString strAlterTableHead = "ALTER TABLE " + strTemp ;
	while(i<fieldCount)
	{
		CString strAddField = strAlterTableHead ;
		for( ;i<fieldCount ;i++)
		{		   
			if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
			{
				if (fileinfos[i]->sFieldName.GetLength() > 10)
					sFormat.Format("%s Memo",fileinfos[i]->sFieldName.Left(10));
				else 
					sFormat.Format("%s Memo",fileinfos[i]->sFieldName);
			}
			else//字段长度小于250就此字段设为文本类型
			{
				if (fileinfos[i]->sFieldName.GetLength() > 10)
					sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName.Left(10),fileinfos[i]->iFieldLength);
				else 
					sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
			}
			if(strAlterTableHead == strAddField)//避免死循环
			{	
				if(strlen(strAddField) + sFormat.GetLength() > nMaxSql) 
				{
					AfxMessageBox("字段名太长");
					i++;
					break;			  
				}
			}
			
			sFormat = " ADD COLUMN " + sFormat ;		   
			if(strlen(strAddField) + sFormat.GetLength() > nMaxSql) 
				break;
			
			strAddField += sFormat;
		}
		arSql.Add(strAddField);
	}

	return true;
}

bool GetCreateMDBTableSql(CString strTableName,HFIELDINFOS& fileinfos,CStringArray& arSql)
{
	CString strFormat;
	CString strSQL;
	
	strSQL.Format("create table %s (",strTableName);	
	//通过判断字段的长度来确定字段的类型,大于250就设为备注类型,小于250就设为文本类型
	const int nFieldCount = fileinfos.GetSize();
	for(int i=0;i<nFieldCount ;i++)
	{
		if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
			strFormat.Format("%s longchar",fileinfos[i]->sFieldName);			
		else//字段长度小于250就此字段设为文本类型
			strFormat.Format("%s text(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
		if(strlen(strSQL) + strFormat.GetLength() > nMaxSql) 
		{		   
			break;
		}
		if(0 != i)
			strFormat = "," + strFormat;
		strSQL = strSQL + strFormat ;					
	}
	strSQL +=")";
	arSql.Add(strSQL);
	
	//把建表时没有建的列加上去
	const CString strAlterTableHead = "ALTER TABLE " + strTableName + " ADD";
	while(i < nFieldCount )
	{
		strSQL = strAlterTableHead ;
		for( ;i < nFieldCount ;i++)
		{		   
			if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
				strFormat.Format(" %s longchar",fileinfos[i]->sFieldName);			
			else//字段长度小于250就此字段设为文本类型
				strFormat.Format(" %s text(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);	
			if(strAlterTableHead == strSQL)//避免死循环
			{	
				if(strlen(strSQL) + strFormat.GetLength() > nMaxSql) 
				{
					AfxMessageBox("字段名太长");
					i++;
					break;			  
				}
			}
			else
				strFormat = "," + strFormat ;		   
			if(strlen(strSQL) + strFormat.GetLength() > nMaxSql) 
				break;
			
			strSQL += strFormat;
		}
		arSql.Add(strSQL);
	}
	
	return true;
}
bool GetCreateTableSql(enum HDBType type,CString strTableName,HFIELDINFOS& fileinfos,CStringArray& arSql)
{
	switch(type)
	{
	case HDBType_ACCESS: GetCreateMDBTableSql(strTableName,fileinfos,arSql);
						 break;
	case HDBType_FOXPRO: GetCreateDBFTableSql(strTableName,fileinfos,arSql);
						 break;
	default:			 return false;
	}

	return true;	
}

bool GetDeleteTableSql(CString strTableName,CString& strSQL)
{
	strSQL.Format("drop table %s",strTableName);
	return true;
}

enum HDBType GetDBTypeByFileName(CString strFileName)
{
	if(strFileName.GetLength() < 4)
		return HDBType_UNKNOWN;

	CString strFileExt = strFileName.Right(4);
	if(".mdb" == strFileExt)
		return HDBType_ACCESS;
	else if(".xls" == strFileExt)
		return HDBType_EXCEL;
	else if(".dbf" == strFileExt)
		return HDBType_FOXPRO;

	return HDBType_UNKNOWN;
};


bool GetTables(CString strDSN,CStringArray & strTableNames)
{	
	strDSN = "DSN=" + strDSN;
	CDatabase database;
	int		ret= -1;
	HSTMT	hStmt;
	UCHAR   szName[256];
	SDWORD  cbName;
	
	// 缺省取用户表、参数选择视图、系统表
	CString	type = "'TABLE'";	
	// 通过ODBC打开数据库
	try
	{
		if( !database.OpenEx(strDSN) )
			return false;
	}
	catch(CDBException * e)
	{
		AfxMessageBox(e->m_strError);
		return false;
	}
	// 分配Statement句柄
	//SQLAllocStmt (database.m_hdbc,&hStmt);
	SQLAllocHandle (SQL_HANDLE_STMT,database.m_hdbc,&hStmt);
	// 获取表信息(返回一个数据表)
	ret = SQLTables(hStmt,
		NULL,SQL_NTS,
		NULL,SQL_NTS,
		NULL,SQL_NTS,
		(unsigned char *)type.GetBuffer(0),SQL_NTS);
	if(ret == SQL_ERROR)
	{
		SQLFreeStmt(hStmt,SQL_CLOSE);
		database.Close();
		if(ret ==  SQL_INVALID_HANDLE )
		{
			AfxMessageBox("Invalid handle");
			return false;
		}
		AfxMessageBox("Database Could Not be Open");
		return false;
	}
	
	while(1)
	{
		// 取数据到缓冲区
		ret = SQLFetch(hStmt);
		if(ret == SQL_NO_DATA_FOUND)
			break;
		// 取某一列数据(第3列为表名,其他还有表属性、数据库名等)
		ret = SQLGetData(hStmt, 3, SQL_C_CHAR, szName, TABLE_NAME_LENGTH, &cbName);		
		strTableNames.Add(szName);
	}
	
	// 释放句柄
	SQLFreeStmt(hStmt,SQL_CLOSE);
	database.Close();
	
	return true;
}


int IsDirectoryOrFile(CString strFileName)
{
	strFileName.TrimLeft();
	strFileName.TrimRight();
	
	WIN32_FIND_DATA fd;
	HANDLE hFind = ::FindFirstFile(strFileName,&fd);
	::FindClose(hFind);
	
	//不存在同名的文件或文件夹
	if (hFind == INVALID_HANDLE_VALUE)
	{
		return 0 ;
	}
	//判断是否为目录
	else if (fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
	{
		return 2 ;
	}
	else//判断为文件
	{		
		return 1;
	}	
}

bool IsLegalName(CString strFileName,CString& strErr)
{
	strErr.Empty();

	int nPos1 = strFileName.ReverseFind('\\');
	int nPos2 = strFileName.ReverseFind(':');
	int nPos = max(nPos1,nPos2);
	if(-1 != nPos)//检查文件夹是否存在,不存在就新建
	{
		CString strPath = strFileName.Left(nPos);
		const int nType = IsDirectoryOrFile(strPath) ;
		if(1 == nType)//存在同名的文件,无法新建文件夹
		{
			strErr.Format("存在与〖%s〗同名的文件,无法新建文件夹",strPath);
			return 0;
		}
		else if( 0 == nType)
		{
			if(IDYES != AfxMessageBox("文件夹不存在,创建此文件夹吗?",MB_YESNO))
			{
				strErr.Format("文件夹〖%s〗不存在",strPath);
				return 0 ;
			}
			if(!CreateDirectory(strPath,NULL))
			{
				strErr.Format("文件夹〖%s〗不存在",strPath);
				return 0 ;
			}
		}
		strFileName = strFileName.Mid(nPos + 1 );
	}
	
	//文件名为空
	if(strFileName.IsEmpty())
	{
		strErr = "文件名不能为空";
		return false;
	}
	
	//只允许汉字字母数字及下划线
	const int nLength = strFileName.GetLength();
	for(int i = 0 ; i < nLength ; i ++ )
	{
		char ch = strFileName[i];
		if(ch & 0x80)//半个汉字
		{
			i++;
			continue;
		}
		if(ch >= 'A' && ch <='Z')//大写字母
			continue;
		if(ch >='a' && ch <= 'z')//小写字母
			continue;
		if(ch >= '0' && ch <= '9')//数字
			continue;
		if('_' == ch)//下划线
			continue;
		CString strSpeChar = ".";//. 都可以
		if(-1 != strSpeChar.Find(ch))
			continue;

		strErr.Format("文件名中包含非法字符%c",ch);
		return  false;
	}

	char ch = strFileName[0] ;
	if(ch >= '0' && ch <= '9')//不能以数字开头
	{
		strErr = "文件名不能以数字开头";
		return false;
	}

	return true;
}


int FindStrFromStrArr(const CStringArray& arDest,CString strSour)
{	
	for(int i = arDest.GetSize()-1 ; i >= 0 ; i-- )
	{
		if(strSour == arDest[i])
			return i;
	}

	return i; 
}


static CString GetNewColName(HFIELDINFOS& tFieldInfos)
{
	const int nColCount = tFieldInfos.GetSize();
	for(int nPostFix = 1 ; nPostFix < 10000/*避免死循环*/; nPostFix++)
	{
		CString strNewColName; 
		strNewColName.Format("_col%d" , nPostFix);
		for(int i = 0 ; i < nColCount ; i++ )
		{
			if(strNewColName == tFieldInfos[i]->sFieldName)
				break;
		}
		if(nColCount == i)
			return strNewColName;
	}	

	return "";
}

void DoIllegalColName(HDBType type,HFIELDINFOS& tFieldInfos)
{
	const nColCount = tFieldInfos.GetSize();
	for(int i = 0 ; i < nColCount ; i++ )
	{
		if(HDBType_FOXPRO == type)
		{
			if(tFieldInfos[i]->sFieldName.GetLength() > 10)
			{
				tFieldInfos[i]->sFieldName = GetNewColName(tFieldInfos);
				continue;
			}
		}
		else
		{
		}
		
		//看是否有重名的列
		for(int j = 0 ; j < i  ; j++ )
		{
			CString str1,str2;
			str1 = tFieldInfos[i]->sFieldName;
			str2 = tFieldInfos[j]->sFieldName;
			if(tFieldInfos[i]->sFieldName == tFieldInfos[j]->sFieldName)
			{
				tFieldInfos[i]->sFieldName = GetNewColName(tFieldInfos);
				break;
			}
		}
	}
}

⌨️ 快捷键说明

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