VC++6.0MFC编程心得

简介:

数据库:

       一个程序的最基本功能有输入、查询、修改、删除、保存、打印,均与数据库有关。而对数据库的基本操作使用最频繁,以Access 为例:

1、用程序创建Access 数据库文件:

手工创建数据文件的方法大家并不陌生,如果用程序创建有时候也需要,下面就是其中一种方法,可以使用ADOX::CatalogPtr来创建mdb文件。用下面“配置设置文件”文件方法设置数据库的参数,配置数据文件的名称、密码、ID和路径,在有安装程序的情况下需要它。

ADOX的建库,它是在没有数据库文件的情况下,用ADOX的目录指针CatalogPtr来创建ACCESS数据库文件,如下:

BOOLCRecord::UseADOXCatalogPtrCreatAccessDB()

{

       CString str=DBPath + DBName;         //数据库的路径和名称

       CString strPassword=DBPasswd;         //数据库的密码

       CStringstrcnn=_T("Provider=Microsoft.JET.OLEDB.4.0;Data source ="+str+";\

              Jet OLEDB:DatabasePassword="+strPassword); //数据库的字串

             

       //使用ADOX::CatalogPtr来创建mdb文件:

       HRESULT hr = S_OK;

       hr=::CoInitialize(NULL);

       if(SUCCEEDED(hr))

       {

              HRESULT hr = S_OK;

              try

              {

                     ADOX::_CatalogPtrm_pCatalog = NULL;

                     hr=m_pCatalog.CreateInstance(__uuidof(ADOX::Catalog));

                     if(FAILED(hr))

                     {

                            _com_issue_error(hr);

}else

                     {

                            m_pCatalog->Create(_bstr_t(strcnn));//Create MDB

                     }

              }catch(_com_error e)  //异常处理

{//错误显示}

       }

       ::CoUninitialize();

       return TRUE;

}

2、用程序在系统中创建Access的数据源名称DSN

手工配置ODBC的数据源名称,大家也不陌生。而通过程序动态建立ODBCDSN,在有安装程序的情况下也需要它。它是在已有数据库文件的情况下建立数据源名称。

       BOOLCRecord::CreatAccessDSN()

{

              CString DBID ,lpszFile=DBPath+DBName;

              int mlen;

              char* szDesc=new char[512];

              sprintf(szDesc,"DSN=%s?UID=%s?;PWD=%s?;DESCRIPTION=;?DBQ=%s?\

FIL=MicrosoftAccess?DEFAULTDIR=%s??"\

                     ,DBName,DBID,DBPasswd,lpszFile,DBPath);

              mlen=strlen(szDesc);

              for(int i=0;i<mlen;i++)

              {

                     if(szDesc[i]=='?')    szDesc[i]='\0';

              }

              if(SQLConfigDataSource(NULL,ODBC_ADD_DSN,"MicrosoftAccess\

                    Driver (*.mdb)\0", (LPCSTR)szDesc)) return TRUE;

              ……

}

3、动态建数据库表

       一种方法可以通过一个配置数据库表的txt文件,它包括创建数据表的SQL语句,程序读入该文件的,并分析该文件的内容,得到一SQL字串,进行创建,这种方法建表比较灵活;另一种方法也可以通过有包括创建Access数据表SQL语句的程序代码创建。两种创建方法都要注意在字段名与它的字段类型之间必需用tab键隔开。如下,采用后者:

       try

       {

              VARIANT* RecordsAffected=0;

              CStringstrSQL=\

"CREATE TABLE accesstable(ID  longinteger ID ENTITY(1,1) not null,";

              strPSW=strPSW+"name        text(10)not null,";

              strPSW=strPSW+"cash  DOUBLE,remark   text(100));";   //SQL字串

              m_pCon->Execute((_bstr_t)(LPCTSTR)strSQL,NULL,adExecuteNoRecords);

       }

       catch(_com_error&e)    { …… }

       VC++程序来动态建库很多数据类型不支持,但表名、字段名可以是变量。

4、数据库的连接和关闭

       boolCRecordSonPrg::CreatConnect()   //数据库的连接

{

CStringstr="Provider=MSDASQL.1;Password='"+DBPasswd+"';\

              PersistSecurity Info=True;Data Source="+DBName;  //连接字串

              try

              {

                     m_pCon.CreateInstance(__uuidof(Connection));

                     m_strConnection = _T(str);  

                     intbCon=m_pCon->Open(_bstr_t(m_strConnection),"","",adConnectUnspecified);

              }

              catch(_com_error &e)    { ……    }

              return true;

}

voidCRecordSonPrg::CloseConnect()  //数据库的关闭

{

       try

       {

              m_pCon->Close();  //关闭连接

              m_pCon.Release(); //释放

       }

       catch(_com_error &e){ ……       }

}

5、用ADO对数据库记录的增、删、改、存、查、排序、过滤、打印

       //打开一个数据表DBtable

       m_pRs.CreateInstance(__uuidof(Recordset));

       m_strCmdText= _T("DBtable");

       m_pRs->Open((LPCTSTR)m_strCmdText,(LPCTSTR)m_strConnection,adOpenStatic,adLockOptimistic,adCmdTable);

       ①增加记录:

       try

       {

              if(!m_pRs->Supports(adAddNew))return false;

              m_pRs->AddNew();

       m_pRs->Fields->GetItem("user")->Value=(_variant_t)strm_newuser;

              ……

             m_pRs->Update();

       }

       ②删除记录:

       try

       {    

              m_pRs->Delete(adAffectCurrent );      //删除当前记录

       }

       ③改动、保存记录:

       voidCRsCgDlg::SaveModifiedRecord()       //记录修改后保存

       {

              ……       //拷贝对话框数据到ADOC++ 绑定成员

              //调用ADO数据绑定更新模式的接口

              HRESULThr = m_piAdoRecordBinding->Update( (CADORecordBinding*)this );

       }

       ④查找记录:

       CStringtemp ="user='"+m_FindUserName+"'";  

//查找字串

       _bstr_ttemp1=(_bstr_t)temp;                                  

//类型转换为_bstr_t

       m_pRs->Find(temp1,0,adSearchForward,"");

       ⑤排序记录:

CString temp="’user,"+m_FindUserName+"'";  

//排序字串

       _bstr_ttemp1=(_bstr_t)temp;                                  

//类型转换为_bstr_t

m_pRs->Sort=(temp1);

m_pRs->Sort=("");                                          

//取消排序

⑥过滤记录:

CStringstrfilter = _T("name = '"+m_strFilter+"'");    

//过滤字串

m_pRs->Filter= (_variant_t)strfilter;

m_pRs->Filter= (long) adFilterNone;        

//取消过滤

       ⑦打印记录:

       打印记录可以采用CDocument类的serialize()文档类的方式,也可以借助显示控件实现。这里是用FlexGrid控件编写的打印代码。

       voidCMyApp::PrintToText()

{

              CStringcFilePath = "C:\\Documents and Settings\\Administrator\\";

              CString cFileName = "打印统计表.txt";

              CString cFile = cFilePath+cFileName;

CStdioFile file; 

//CStdioFile类是CFile类的派生类,它是以流方式操作文本

              file.Open(cFile,CFile::modeCreate|CFile::modeWrite|CFile::typeText)

CString str;

              str.Format("%s\n\n",cFileName);      

//格式化文件主题

              file.WriteString(str);                   

//写入文件主题

              int RowCount = m_MSFGrid.GetRows();   

//FlexGrid控件表取行数

              int ColCount = m_MSFGrid.GetCol();       

//FlexGrid控件表取列数

              for(long r=0;r<RowCount;r++)     //行循环

              {

                     for(long c=0;c<ColCount;c++)     //列循环

                     {

                            CString Matrix =m_MSFGrid.GetTextMatrix(r,c);

//得到rc列的文本

                            switch(c)

                            { str.Format( …… );//产生打印格式 }

                            file.WriteString(str);

                     }

              }

              file.SetLength(file.GetPosition());     

//设置文件长度

              file.Close();                      

//关闭文件

              str="notepad "+cFile;

              WinExec(str,SW_SHOW);            

//利用记事本打开生成的文本文件

}

6、配置设置文件:

为了增加程序的灵活性,对配置文件的读、写也是必要的。Windows操作系统专门为此提供了6API函数来对配置设置文件进行读、写:  

GetPrivateProfileInt()               

//从私有初始化文件获取整型数值  

GetPrivateProfileString()  

//从私有初始化文件获取字符串型值  

GetProfileInt                    

//win.ini获取整数值  

GetProfileString                      

//win.ini获取字符串值  

WritePrivateProfileString  

//写字符串到私有初始化文件  

WriteProfileString      

//写字符串到win.ini 

下面采用私有初始化文件获取或写入字符串型值的函数来读写配置文件:

       读文件:

       CStringCMyApp::GetOneIniData(CString sFilePath)

{

              CString str;

              char buf[256] =NULL;

              int len=0;

              len = GetPrivateProfileString(

                     "Custom",      //节名

                     "UserName"   //项名

                     "No",             //没找到此项时的返回值

                     buf,               //目标缓冲区地址

                     256,               //目标缓冲区长度

                     sFilePath        //配置文件的准确路径

              );

              str=buf;

              return str;

}

写文件:

BOOLCKaApp::WriteIniData(CString cstr,CString strUserName)

{

       CString sFile = cstr;

       CFileStatus status;  

       BOOL RetUser=WritePrivateProfileString(

              "Custom",             //节名

              "UserName",         //项名

              strUserName,         //内容

              sFile                            //配置文件的准确路径

              );

              returnTRUE;

       }

对于SQL Server的操作类似。
目录
相关文章
|
1月前
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
251 65
|
1月前
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
120 6
|
1月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
51 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
1月前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
81 11
|
1月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
54 5
|
1月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
43 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
1月前
|
算法 编译器 C++
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
80 2
|
1月前
|
存储 编译器 C++
【C++篇】引领C++模板初体验:泛型编程的力量与妙用
【C++篇】引领C++模板初体验:泛型编程的力量与妙用
39 2
|
1月前
|
程序员 C++
C++编程:While与For循环的流程控制全解析
总结而言,`while`循环和 `for`循环各有千秋,它们在C++编程中扮演着重要的角色。选择哪一种循环结构应根据具体的应用场景、循环逻辑的复杂性以及个人的编程风格偏好来决定。理解这些循环结构的内在机制和它们之间的差异,对于编写高效、易于维护的代码至关重要。
54 1
|
1月前
|
自然语言处理 编译器 Linux
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器