登录对话框之VC中用INI文件保存登录信息的操作

在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下:

        一.将信息写入.INI文件中.

        1.所用的WINAPI函数原型为:

      BOOL WritePrivateProfileString(
      LPCTSTR lpAppName,
      LPCTSTR lpKeyName,
      LPCTSTR lpString,
      LPCTSTR lpFileName
      );

        其中各参数的意义:

         LPCTSTR lpAppName 是INI文件中的一个字段名.

         LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.

         LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.

         LPCTSTR lpFileName 是完整的INI文件名.

        2.具体使用方法:设现有一名学生,需把他的姓名和年龄写入 c:/stud/student.ini 文件中.

      CString strName,strTemp;
      int nAge;
      strName="张三";
      nAge=12;
      ::WritePrivateProfileString("StudentInfo","Name",strName,"c://stud//student.ini");


        此时c:/stud/student.ini文件中的内容如下:

         [StudentInfo]
         Name=张三

        3.要将学生的年龄保存下来,只需将整型的值变为字符型即可:

      strTemp.Format("%d",nAge);
      ::WritePrivateProfileString("StudentInfo","Age",strTemp,"c://stud//student.ini");

       二.将信息从INI文件中读入程序中的变量.

        1.所用的WINAPI函数原型为:

      DWORD GetPrivateProfileString(
      LPCTSTR lpAppName,
      LPCTSTR lpKeyName,
      LPCTSTR lpDefault,
      LPTSTR lpReturnedString,
      DWORD nSize,
      LPCTSTR lpFileName
      );

        其中各参数的意义:

         前二个参数与 WritePrivateProfileString中的意义一样.

         lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.

         lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.

         nSize : 目的缓存器的大小.

         lpFileName : 是完整的INI文件名.

        2.具体使用方法:现要将上一步中写入的学生的信息读入程序中.

      CString strStudName;
      int nStudAge;
      GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c://stud//student.ini");


        执行后 strStudName 的值为:"张三",若前两个参数有误,其值为:"默认姓名".

        3.读入整型值要用另一个WINAPI函数:

      UINT GetPrivateProfileInt(
      LPCTSTR lpAppName,
      LPCTSTR lpKeyName,
      INT nDefault,
      LPCTSTR lpFileName
      );

        这里的参数意义与上相同.使用方法如下:

      nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c://stud//student.ini");

      三.循环写入多个值,设现有一程序,要将最近使用的几个文件名保存下来,具体程序如下:

        1.写入:

      CString strTemp,strTempA;
      int i;
      int nCount=6;
      file://共有6个文件名需要保存
      for(i=0;i {strTemp.Format("%d",i);
      strTempA=文件名;
      file://文件名可以从数组,列表框等处取得.
      ::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,
      "c://usefile//usefile.ini");
      }
      strTemp.Format("%d",nCount);
      ::WritePrivateProfileString("FileCount","Count",strTemp,"c://usefile//usefile.ini");
      file://将文件总数写入,以便读出.

        2.读出:

      nCount=::GetPrivateProfileInt("FileCount","Count",0,"c://usefile//usefile.ini");
      for(i=0;i {strTemp.Format("%d",i);
      strTemp="FileName"+strTemp;
      ::GetPrivateProfileString("CurrentIni",strTemp,"default.fil",
      strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c://usefile//usefile.ini");

      file://使用strTempA中的内容.

      }

        补充四点:
         1.INI文件的路径必须完整,文件名前面的各级目录必须存在,否则写入不成功,该函数返回 FALSE 值.
         2.文件名的路径中必须为 // ,因为在VC++中, // 才表示一个 / .
         3.也可将INI文件放在程序所在目录,此时 lpFileName 参数为: ".//student.ini".

      //----------------------------------------------------------------------------------
      /*
      类名:CIni
      版本:v2.0
      最后更新:
      v2.0
      梦小孩于2004年2月14日情人节
      加入高级操作的功能
      v1.0
      梦小孩于2003年某日
      一般操作完成

      类描述:
      本类可以于.ini文件进行操作
      */

      文件 1:

      #pragma once

      #include "afxTempl.h"

      class CIni
      {
      private:
      CString m_strFileName;
      public:
      CIni(CString strFileName):m_strFileName(strFileName)
      {
      }
      public:
      //一般性操作:
      BOOL SetFileName(LPCTSTR lpFileName);   //设置文件名
      CString GetFileName(void); //获得文件名
      BOOL SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue,bool
      bCreate=true); //设置键值,bCreate是指段名及键名未存在时,是否创建。
      CString GetValue(LPCTSTR lpSection, LPCTSTR lpKey); //得到键值.
      BOOL DelSection(LPCTSTR strSection);   //删除段名
      BOOL DelKey(LPCTSTR lpSection, LPCTSTR lpKey);   //删除键名


      public:
      //高级操作:
      int GetSections(CStringArray& arrSection);   //枚举出全部的段名
      int GetKeyValues(CStringArray& arrKey,CStringArray& arrValue,LPCTSTR
      lpSection);   //枚举出一段内的全部键名及值

      BOOL DelAllSections();

      };

      文件 2:

      #include "StdAfx.h"
      #include "ini.h"

      #define MAX_ALLSECTIONS 2048   //全部的段名
      #define MAX_SECTION 260   //一个段名长度
      #define MAX_ALLKEYS 6000   //全部的键名
      #define MAX_KEY 260   //一个键名长度

      BOOL CIni::SetFileName(LPCTSTR lpFileName)
      {
      CFile file;
      CFileStatus status;

      if(!file.GetStatus(lpFileName,status))
         return TRUE;

      m_strFileName=lpFileName;
      return FALSE;
      }

      CString CIni::GetFileName(void)
      {
      return m_strFileName;
      }

      BOOL CIni::SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue,bool
      bCreate)
      {
      TCHAR lpTemp[MAX_PATH] ={0};

      //以下if语句表示如果设置bCreate为false时,当没有这个键名时则返回TRUE(表示出错)
      //!*&*none-value*&!* 这是个垃圾字符没有特别意义,这样乱写是防止凑巧相同。
      if (!bCreate)
      {
        
      GetPrivateProfileString(lpSection,lpKey,"!*&*none-value*&!*",lpTemp,MAX_PATH,m_strFileName);
         if(strcmp(lpTemp,"!*&*none-value*&!*")==0)
          return TRUE;
      }

      if(WritePrivateProfileString(lpSection,lpKey,lpValue,m_strFileName))
         return FALSE;
      else
         return GetLastError();
      }

      CString CIni::GetValue(LPCTSTR lpSection, LPCTSTR lpKey)
      {
      DWORD dValue;
      TCHAR lpValue[MAX_PATH] ={0};

      dValue=GetPrivateProfileString(lpSection,lpKey,"",lpValue,MAX_PATH,m_strFileName);
      return lpValue;
      }

      BOOL CIni::DelSection(LPCTSTR lpSection)
      {
      if(WritePrivateProfileString(lpSection,NULL,NULL,m_strFileName))
         return FALSE;
      else
         return GetLastError();
      }

      BOOL CIni::DelKey(LPCTSTR lpSection, LPCTSTR lpKey)
      {
      if(WritePrivateProfileString(lpSection,lpKey,NULL,m_strFileName))
         return FALSE;
      else
         return GetLastError();
      }


      int CIni::GetSections(CStringArray& arrSection)
      {
      /*
      本函数基础:
      GetPrivateProfileSectionNames - 从 ini 文件中获得 Section 的名称
      如果 ini 中有两个 Section: [sec1] 和 [sec2],则返回的是 'sec1',0,'sec2',0,0 ,当你不知道 
      ini 中有哪些 section 的时候可以用这个 api 来获取名称
      */
      int i; 
      int iPos=0; 
      int iMaxCount;
      TCHAR chSectionNames[MAX_ALLSECTIONS]={0}; //总的提出来的字符串
      TCHAR chSection[MAX_SECTION]={0}; //存放一个段名。
      GetPrivateProfileSectionNames(chSectionNames,MAX_ALLSECTIONS,m_strFileName);

      //以下循环,截断到两个连续的0
      for(i=0;i<MAX_ALLSECTIONS;i++)
      {
         if (chSectionNames[i]==0)
          if (chSectionNames[i]==chSectionNames[i+1])
           break;
      }

      iMaxCount=i+1; //要多一个0号元素。即找出全部字符串的结束部分。
      arrSection.RemoveAll();//清空原数组

      for(i=0;i<iMaxCount;i++)
      {
         chSection[iPos++]=chSectionNames[i];
         if(chSectionNames[i]==0)
         {  
          arrSection.Add(chSection);
          memset(chSection,0,MAX_SECTION);
          iPos=0;
         }

      }

      return (int)arrSection.GetSize();
      }

      int CIni::GetKeyValues(CStringArray& arrKey,CStringArray& arrValue,
      LPCTSTR lpSection)
      {
      /*
      本函数基础:
      GetPrivateProfileSection- 从 ini 文件中获得一个Section的全部键名及值名
      如果ini中有一个段,其下有 "段1=值1" "段2=值2",则返回的是 '段1=值1',0,'段2=值2',0,0 ,当你不知道 
      获得一个段中的所有键及值可以用这个。
      */
      int i; 
      int iPos=0;
      CString strKeyValue;
      int iMaxCount;
      TCHAR chKeyNames[MAX_ALLKEYS]={0}; //总的提出来的字符串
      TCHAR chKey[MAX_KEY]={0}; //提出来的一个键名

      GetPrivateProfileSection(lpSection,chKeyNames,MAX_ALLKEYS,m_strFileName);

      for(i=0;i<MAX_ALLKEYS;i++)
      {
         if (chKeyNames[i]==0)
          if (chKeyNames[i]==chKeyNames[i+1])
           break;
      }

      iMaxCount=i+1; //要多一个0号元素。即找出全部字符串的结束部分。
      arrKey.RemoveAll();//清空原数组
      arrValue.RemoveAll();

      for(i=0;i<iMaxCount;i++)
      {
         chKey[iPos++]=chKeyNames[i];
         if(chKeyNames[i]==0)
         {
          strKeyValue=chKey;
          arrKey.Add(strKeyValue.Left(strKeyValue.Find("=")));
          arrValue.Add(strKeyValue.Mid(strKeyValue.Find("=")+1));
          memset(chKey,0,MAX_KEY);
          iPos=0;
         }

      }

      return (int)arrKey.GetSize();
      }

      BOOL CIni::DelAllSections()
      {
      int nSection;
      CStringArray arrSection;
      nSection=GetSections(arrSection);
      for(int i=0;i<nSection;i++)
      {
         if(DelSection(arrSection[i]))
          return GetLastError();
      }
      return FALSE;
      }


      使用方法:
      CIni ini("c://a.ini");
      int n;

      /*获得值
      TRACE("%s",ini.GetValue("段1","键1"));
      */

      /*添加值
      ini.SetValue("自定义段","键1","值");
      ini.SetValue("自定义段2","键1","值",false);
      */

      /*枚举全部段名
      CStringArray arrSection;
      n=ini.GetSections(arrSection);
      for(int i=0;i<n;i++)
      TRACE("%s/n",arrSection[i]);
      */

      /*枚举全部键名及值
      CStringArray arrKey,arrValue;
      n=ini.GetKeyValues(arrKey,arrValue,"段1");
      for(int i=0;i<n;i++)
      TRACE("键:%s/n值:%s/n",arrKey[i],arrValue[i]);
      */

      /*删除键值
      ini.DelKey("段1","键1");
      */

      /*删除段
      ini.DelSection("段1");
      */

      /*删除全部
      ini.DelAllSections();
      */

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值