你可以根据给定的文件名自己手工建立这种关联,欲知详情,请查看MSDN中关于CArichive和CFile的构造函数的说明.
Gook Luck!

解决方案 »

  1.   

    在你打开一个文件的时候,系统会分配一个CArchive对象与它相关联,并把这个对象
    作为参数以引用的形式传递给序列化函数。事实上,每个Carchive对象都是和CFile
    对象相对应的,先有CFile对象,后有CArchive对象。如果你有多个文件打开,看你
    是把那个文件与Carchive对象联系在一起的。如果自己想处理ONFILEOPEN消息,自己
    生成生成一个CArchive对象就是了,调用函数CArchive( CFile* pFile, UINT 
    nMode, int nBufSize = 4096, void* lpBuf = NULL )。之后把这个对象作为参数
    传递给Serialize()就可以了。
      

  2.   

    首先谢谢回答,然后是对Laole回答中的一个疑问.
    laole回答中说把自己生成的CAchiv对象作为参数传递给Serialize函数,但是Serialize是在读取或写入对象时自动被调用的.看来似乎每个Document都有一个参数在维护着Serialize所操作的文件?
    另外是否要操作CFileDialog的部分属性(比如加入文件名的filter),就一定要自己处理ONFILEOPEN呢?自己去调用dlg.DoModal呢?
      

  3.   

    ar是在CDocument::OnOpenDocument(lpFileName)和CDocument::OnSaveDocument(lpFileName)时与文件lpFileName建立关联的,这是MFC为文档/视结构提供的一个自动化机制,其实也可以自己手动操作:
    在你的对象中
    打开:
    CFileException fe;
    //建立lpszPathName对应的CFile对象
    CFile* pFile = GetFile(lpszPathName,File::modeRead and CFile::shareDenyWrite,&fe);
    //建立CFile对应的ar
    CArchive ar(pFile, CArchive::load  and  CArchive::bNoFlushOnDelete);
    //调用你的类的串行化函数
    Serialize(ar);
    保存:
    CFileException fe;
    CFile* pFile = NULL;
    pFile = GetFile(lpszPathName, CFile::modeCreate  and 
    CFile::modeReadWrite  and  CFile::shareExclusive, &fe);
    CArchive ar(pFile, CArchive::store  and  CArchive::bNoFlushOnDelete);
    Serialize(ar);
    这样在ONFILEOPEN对
    多个文件的操作时只要对每个文件都进行一次上述操作就可以了.
    CDocument::OnOpenDocument(lpFileName)和CDocument::OnSaveDocument(lpFileName)就是这样建立关联的,其实上述这段代码就是从mfc中摘出来的
      

  4.   

    char* pFileName;//文件名
    CFile FLfile;
    char buf[512];
    if( !FLfile.Open( pFileName, CFile::modeCreate  and  CFile::modeWrite ) )
    {
       #ifdef _DEBUG
          afxDump << "Unable to open file" << "\n";
          exit( 1 );
       #endif
    }
    CArchive ar( &FLfile, CArchive::store, 512, buf );
    这样就可以像操作串行化数据一样来对待ar.存储的数据放在了指定的文件中pFileName
      

  5.   

    to strangcat:
         虽然serialize是在读取对象是调用的,但是在此之前archive对象就已经生成了
    事实上,你可以这样理解每一个文件对象都有一个archive对象把物理数据与逻辑数据
    联系起来,简化呢的操作,可以想象成c语言中的流。事实上你自己处理的话,可以用
    CFileDialog地DoModal获得文件名,然后进行一系列操作,包括生成File对象和Archive
    对象。这个问题netmare和yusuco说的很清楚了,把代码都贴上了。
      

  6.   

    恩,在大家的指教下对第一个问题清楚了.但好象没人对第二个问题有说法,再问一下.
    是否要操作CFileDialog的部分属性(比如加入文件名的filter),就一定要自己处理ONFILEOPEN呢?自己去调用dlg.DoModal呢?
    谢谢!
      

  7.   

    好象就是这样,作了改动之后旧只有自己处理了。
    第2个问题:
    自己构造CFile对象,然后用CFile对象来CAhrive对象。
    具体自己去看以下MFC的原代码。
    BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
    {
    if (IsModified())
    TRACE0("Warning: OnOpenDocument replaces an unsaved document.\n"); CFileException fe;
    CFile* pFile = GetFile(lpszPathName,
    CFile::modeRead and CFile::shareDenyWrite, &fe);
    if (pFile == NULL)
    {
    ReportSaveLoadException(lpszPathName, &fe,
    FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
    return FALSE;
    } DeleteContents();
    SetModifiedFlag();  // dirty during de-serialize CArchive loadArchive(pFile, CArchive::load  and  CArchive::bNoFlushOnDelete);
    loadArchive.m_pDocument = this;
    loadArchive.m_bForceFlat = FALSE;
    TRY
    {
    CWaitCursor wait;
    if (pFile->GetLength() != 0)
    Serialize(loadArchive);     // load me
    loadArchive.Close();
    ReleaseFile(pFile, FALSE);
    }
    CATCH_ALL(e)
    {
    ReleaseFile(pFile, TRUE);
    DeleteContents();   // remove failed contents TRY
    {
    ReportSaveLoadException(lpszPathName, e,
    FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
    }
    END_TRY
    DELETE_EXCEPTION(e);
    return FALSE;
    }
    END_CATCH_ALL SetModifiedFlag(FALSE);     // start off with unmodified return TRUE;
    }
      

  8.   

    由琢磨了半天,好像修改程序的一个字符串可以达到在文件对话框中加入FILTER的目的.该字符串在ADDDOCTEMPLATE中被作为第一个参数使用.谢谢大家.