::LoadString() 函数从资源中提取一个字符串拷贝至缓冲区中。现在有这么一个问题,它是怎么工作的呢?或者说,字符串资源在模块中是如何存放的。按照我的理解,一般字符串是以零为结束标志,常见的字符串处理函数也都是按照这个原则工作。平时也都没什么奇怪。当我试图打开一个CommonOpenFileDialog时,问题产生了。
GetOpenFileName() / GetSaveFileName() 的参数类型 OPENFILENAME,其中的 Filter 是一个以0为分隔符的字符串(真不知道当初设计函数时微软怎么想的)。当我试图将Filter的内容作为字符串资源放在dll中时,使用LoadString()可以正常读取,并且返回正确的总长度。完全没有异常!问题就在这里,这个字符串中间有若干0,如果LoadString()以0为字符串结束标志,那么它是如何得到完整的串的呢?

解决方案 »

  1.   

    1 字符串的结束是'\0'而不是'0'。
    2 你说的情况不是字符串,而是“字符串组”,在注册表中就有这样的数据类型。LoadString对这个试支持的,所以你能试验成功。
      

  2.   

    你使用配置文件所有信息按行存储,呵呵,那么就没有什么‘0’的烦恼了,呵呵
    参考:
    自己写,不要使用MFC的类,MFC很多意外情况。
    ================================================== FILE *pSourFile; //指向源文件
    CString sSourLine=""; //从源文件中取出的一行 pSourFile = fopen(sFileName,"rt");
    if(pSourFile==NULL) {
    AfxMessageBox("源文件打开失败!");
    return false;
    }
    while(!feof(pSourFile)){
    ReadLine(pSourFile, sSourLine);//读一行
    }
    }
    //读取文件的一行
    void CSetEx::ReadLine(FILE *pFile, CString &line)
    {
    line="";
    char ch;
    int pos=0;
    while(!feof(pFile)){
    //Read(&ch,1);
    ch = fgetc(pFile);
    if(ch=='\r'||ch=='\n')break;
    line+=ch;
    pos++;
    if(line.Find("", 0))
    {
    ftell(pFile);
    }
    }
    line.TrimRight('\r'); 
    line.TrimRight('\n'); 
    line.TrimRight('\r'); 
    line.TrimRight(0xff); //过滤文件结束符
    return;

    }或者:
    CStdioFile file;
    if(file.Open(_T(m_sAppPath+"\\text"),CFile::modeReadWrite))
        {
    CString sss;
    DWORD o=0;
    int ol=0;
    while(file.ReadString(sss))
    {
    if(find.FindFile(m_sAppPath+"\\text"))
    m_cbBkGround.AddString(sss);//sss即为一行
    }
    }
      

  3.   

    REG_MULTI_SZ是一种注册表键值的数据类型,其特点是包含多个字符串,其间以'\0'隔开,最后用连续的两个'\0'表示结束,LoadString支持这种类型字符串的存取,你不必要担心出现字符串丢失的问题。当然,strcpy就不行了,会截断第一个'\0'后面的东西。
      

  4.   

    多谢了。我刚刚打开资源文件的dll看了一下,它是这么存储的,首先是每个字符串的字符数,一个word,然后是字符串。我想LoadString大概是直接进行的内存拷贝,通过每个字符串前面的字符数来决定拷贝的长度的。:)