一般的文件都有文件摘要属性页,它包括了作者、标题、评论等内容。我在VC下用以下代码实现了除了图片文件以外的其他文件的文件摘要信息的写入。执行完毕后,如果是非bmp、jpg等图片文件,那么在文件的右键属性页中出现刚才写入的摘要信息。但是图片文件不显示摘要信息。
而且,此时如果,把文件的后缀名改为其他的,比如“.txt”,摘要信息就看得到了。这个是为什么呢?
请高手相助,很急啊!!!!!!!!!!!!!!!!!!!!!!!!!!
IPropertySetStorage *pPropSetStg = NULL;
IPropertyStorage *pPropStg = NULL;
PROPSPEC propspec[4]; 
PROPVARIANT propWrite[4]; 
HRESULT hr = S_OK;
USES_CONVERSION; hr = StgOpenStorageEx( szFilePath,
STGM_DIRECT |STGM_SHARE_EXCLUSIVE|STGM_READWRITE,
STGFMT_ANY,
0,
NULL,
NULL,
IID_IPropertySetStorage,
reinterpret_cast<void**>(&pPropSetStg) );
DWORD Result = 0;
if( FAILED(hr) ) 
{
Result = GetLastError();
return; // if not ntfs , it will be error.
throw L"Failed StgOpenStorageEx";
} hr = pPropSetStg->Create( FMTID_SummaryInformation, NULL, PROPSETFLAG_DEFAULT,
STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
&pPropStg );    if( FAILED(hr) ) 
throw L"Failed IPropertySetStorage::Open"; //we can identify any property through its Name or its ID
//    propspec.ulKind = PRSPEC_LPWSTR;
//    propspec.lpwstr = L"Title";    propspec[0].ulKind = PRSPEC_PROPID;
    propspec[0].propid  = 0x00000002;
    propWrite[0].vt = VT_LPWSTR;
    propWrite[0].pwszVal = LPTSTR(LPCTSTR(szTitle)); propspec[1].ulKind = PRSPEC_PROPID;
    propspec[1].propid  = 0x00000003;
    propWrite[1].vt = VT_LPWSTR;
    propWrite[1].pwszVal = LPTSTR(LPCTSTR(szSubject)); propspec[2].ulKind = PRSPEC_PROPID;
    propspec[2].propid  = 0x00000004;
    propWrite[2].vt = VT_LPWSTR;
    propWrite[2].pwszVal = LPTSTR(LPCTSTR(szAuthor)); propspec[3].ulKind = PRSPEC_PROPID;
    propspec[3].propid  = 0x00000006;
    propWrite[3].vt = VT_LPWSTR;
propWrite[3].pwszVal = LPTSTR(LPCTSTR(szComment)); hr = pPropStg->WriteMultiple(4, propspec, propWrite, PID_DICTIONARY);    if( FAILED(hr) ) 
throw L"Failed IPropertyStorage::WriteMultiple"; pPropStg->Release(); 
pPropStg = NULL;
pPropSetStg->Release();
pPropSetStg = NULL;

解决方案 »

  1.   

    理论上你的代码没有错误,我猜测这只是操作系统的行为,应该是操作系统在读取图片文件时并未使用标准方式获取概要信息,而是读取图片文件内部保存的用户定义属性(比如图片来源、相机型号、拍摄时间等等)。你可以自己通过代码读取试试看:
    StgOpenStorage
    IStorage::QueryInterface
    IPropertySetStorage::Open // 这里用两种参数分别试试,一个是FMTID_SummaryInformation(内置属性),一个是FMTID_UserDefinedProperties(用户定义属性)
      

  2.   

    感谢jameshooo!!!
    我用其他一个软件在保存为JPG文件时,也有写入文件摘要信息的功能,而它却能正常显示。我先试试你说的。
      

  3.   

    再多说一点,NTFS文件系统中,每个文件可以有多个数据属性,默认的数据属性就是文件内容,摘要是另一种数据属性,你的这段代码就是写这个数据属性的。在资源管理器里面点鼠标右键选择属性看到的摘要信息,与摘要数据属性并不是一定要对应的。一些类型(按扩展名来分)的文件,例如图片、视频、文档等文件的摘要信息是从文件内容中取得的,对于这些类型的文件,系统不再使用摘要数据属性,这些类型的文件储存在FAT32文件系统中依然可以看到摘要信息,而其它类型文件只有储存在NTFS文件系统中才能有摘要信息。
      

  4.   

    我已经试了jameshooo说的方法,没有效果,而且我在用IID_IPropertySetStorage::Delete方法都删除不掉我手动添加的内容,因此就像cnzdgs所说的那样,改的不是地方了。
    多谢cnzdgs!我查下JPEG文件格式应该就有了结果了。
      

  5.   

    我只用到了BMP文件和JPG文件,BMP文件是没有这些信息的,那我就不用考虑了。
    现在只有JPG文件了,我查了下格式,没有找着,希望高手再指点到位,谢谢!
      

  6.   

    我只是让你尝试读取不同的文件属性,仅仅为了验证你添加的概要信息是否有效,不是让你去写自定义属性,自定义属性是图片创建者写入的,并且直接保存在文件内容中,你说的其它软件其实就是图片创建者,它知道文件格式,也知道自定义属性是写在哪的。我劝你不要尝试了,除非你完全了解jpg的格式,重写jpg文件,但是这样做会降低你的代码的通用性,因为你不知道操作系统到底对哪些格式的文件显示自定义属性。
      

  7.   

    我只知道jpg的摘要会插入到在图象数据的前面,以Unicode存放,不了解jpg文件结构,没法帮你了。你到网上找找有没有jpg图象处理的源代码看看。
      

  8.   

    确实,我已经找到了jpg的摘要存放的位置了,现在正在找如何修改。普通的JPG格式说明里没有讲到如何修改的问题。
      

  9.   

    总结:问题解决。
    感谢cnzdgs和jameshooo!