如何获取我自己的文件格式的文件以拥有自己的动态图标?

时间:2008-09-23 13:06:58

标签: file icons opendocument

我们的应用程序的文件格式类似于OpenDocument文件格式(请参阅http://en.wikipedia.org/wiki/OpenDocument) - 即使用清单文件,缩略图等进行压缩。

我注意到OpenOffice文件在Windows和Linux中都有Open Office文件的预览图像作为图标。有没有办法为我们的文件实现这一点:即我想要一个基于内部thumbnail.png的动态图标?

编辑1 哇,谢谢你所有的快速解答。 Thumbnailer看起来非常适合GNOME世界。 Windows我会查看这些链接,谢谢。至于评论问题:通过我们的安装程序以编程方式OR。

编辑2 哦,忘了Mac。在Mac上怎么样? (对不起Mac爱好者!)也有任何关于OpenOffice如何处理他们的IconHandler内容的链接或信息 - 因为我们的非常相似?

9 个答案:

答案 0 :(得分:8)

您需要的是Icon Handler,也称为缩略图处理程序。以下是以active x control编写的示例。

另一个资源是查找Property Handlers,这也应该指向您在Windows中正确处理动态元数据的最新方式。

这些是动态解决方案 - 如果您只想要一个与您的所有文件相关联的图标,则不需要它们 - 仅当您希望Windows资源管理器根据其中的内容显示图标时才使用它们文件,而不仅仅是扩展名,当文件更改时,图标会更新以反映更改。它不必是文件本身的图像,缩略图处理程序也可以根据文件内容生成任何图像。

属性处理程序会更新其他元数据,例如歌曲或视频长度,因此您可以使用Windows资源管理器支持的所有元数据。

关于MAC支持,this page说,“Mac和Windows操作系统有不同的方法来启用这种类型的缩略图,而在Mac OS的情况下,这种支持在版本之间不一致,所以[Adobe InDesign]没有追求它。“

OS X

Mac OSX的图标由Launch Services Database决定。但是,它指的是由注册应用程序处理的所有文件的静态图标文件(它不是基于扩展名 - 每个文件都附加了元数据,用于确定它所属的应用程序,尽管扩展在元数据不提供时提供提示存在,例如从不同的OS或文件系统获取文件)

OSX中的动态图标功能似乎是由Finder提供的,但搜索并没有在这方面提出任何简单的指示。由于Finder不断变化,我可以看出为什么这个目标很难被击中......

侏儒

对于Gnome,您使用thumbnailer。 (感谢Dorward

这是一个非常简单的程序,它有3个命令行参数:

  • 输入文件名,您用缩略图描述的文件(如果您接受,则为URI)
  • 输出文件名,您需要编写PNG
  • 尺寸,以像素为单位的数字,用于描述您应生成的最大方形图像尺寸(128 - > 128x128或更小)

我希望所有系统都这么简单。另一方面,这不支持动画和其他系统上更难实现的插件提供的一些其他功能。

KDE

我有点不确定,但有一些指针应该让你开始。首先是Konqueror是文件管理器并显示图标 - 它支持一些内置类型的动态图标,但我不知道这些是硬编码还是可以编写的插件。查看Embedded Components Tutorial作为起点。

有一个名为Plasma的新(ish?)功能(或计划功能...),它与图标和图标功能有很大关系。查看this announcmentthis initial implementation

您可能需要深入了解Konqueror的来源,并查看他们是如何为文本文件和其他已实现的文件执行此操作。

- 亚当

答案 1 :(得分:4)

自10.5版以来的Mac OSX ......

......有两种方法:

  1. 您的文档采用标准OSX捆绑包格式,并具有静态图片 这可以通过创建一个子文件夹QuickLook并将Thumbnail / Preview.png / tiff / jpg放在里面来完成。

  2. 其他所有需要一个QuickLook生成器插件,该插件可以存储在/ Library / QuickLook~ / Library / QuickLook或YourApp.app/Contents/Library/QuickLook文件夹中。< / p>

  3. 此生成器用于动态创建缩略图和QuickLook预览。 XCode为此提供了一个模板。该模板生成必须实现的所需 ANSI C 文件。如果您要编写 Object-C 代码,则必须将GenerateThumbnailForURL。 c 和GeneratePreviewForURL。 c 重命名为GenerateThumbnailForURL。 m < / strong>和GeneratePreviewForURL。 m (并仔细阅读Apple Devel Docs;)


    基于简单zip容器的演示:

    您必须将Cocoa.framework和Foundation.framework添加到您的项目中 在您的GenerateThumbnailForURL.c中(这部分不在我的脑海中 - 所以不能保证它开箱即用;)):

    #include <Cocoa/Cocoa.h>
    #include <Foundation/Foundation.h>
    
    OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
    {
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
      /* unzip the thumbnail and put it into an NSData object */
      // Create temporary path and writing handle for extraction
      NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingFormat: [NSString stringWithFormat: @"%.0f.%@" , [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"png"]];
      [[NSFileManager defaultManager] createFileAtPath: tmpPath contents: [NSData alloc] attributes:nil];
      NSFileHandle *writingHandle = [NSFileHandle fileHandleForWritingAtPath: tmpPath];
    
    
      // Use task to unzip - create command: /usr/bin/unzip -p <pathToFile> <fileToExtract>
      NSTask *unzipTask = [[NSTask alloc] init];
      [unzipTask setLaunchPath: @"/usr/bin/unzip"];
    
      // -p -> output to StandardOut, added File to extract, nil to terminate Array
      [unzipTask setArguments: [NSArray arrayWithObjects: @"-p", [(NSURL *) url path], @"Thumbnails/thumbnail.png", nil]];
    
      // redirect standardOut to writingHandle
      [unzipTask setStandardOutput: writingHandle];
    
      // Unzip - run task
      [unzipTask launch];
      [unzipTask waitUntilExit];
    
      // Read Image Data and remove File
      NSData *thumbnailData = [NSData dataWithContentsOfFile: tmpPath];
      [[NSFileManager defaultManager] removeFileAtPath: tmpPath handler:nil];
    
    
      if ( thumbnailData == nil || [thumbnailData length] == 0 ) {
         // Nothing Found. Don't care.
         [pool release];
         return noErr;
      }
    
      // That is the Size our image should have - create a dictionary too
      CGSize size = CGSizeMake(256, 256);
      NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
          [NSNumber numberWithInt:size.width],kQLPreviewPropertyWidthKey,
          [NSNumber numberWithInt:size.height],kQLPreviewPropertyHeightKey,
          nil];
    
      // Get CGContext for Thumbnail
      CGContextRef CGContext = QLThumbnailRequestCreateContext(thumbnail, size, TRUE, (CFDictionaryRef)properties);
      if(CGContext) {
         NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)CGContext flipped:size.width > size.height];
         if(context) {
            //These two lines of code are just good safe programming…
           [NSGraphicsContext saveGraphicsState];
           [NSGraphicsContext setCurrentContext:context];
    
           NSBitmapImageRep *thumbnailBitmap = [NSBitmapImageRep imageRepWithData:thumbnailData];
           [thumbnailBitmap draw];
    
           //This line sets the context back to what it was when we're done
           [NSGraphicsContext restoreGraphicsState];
        }
    
        // When we are done with our drawing code QLThumbnailRequestFlushContext() is called to flush the context
        QLThumbnailRequestFlushContext(thumbnail, CGContext);
    
        // Release the CGContext
        CFRelease(CGContext);
      }
    
      [pool release];
      return noErr;
    }
    

    的Info.plist

    你也必须修改你的info.plist文件 - 当你打开它时,它预先设置了很多字段。他们中的大多数是自我解释(或不必更改)但我必须添加以下结构(复制粘贴应该 - 复制文本,进入plist编辑器,然后粘贴。):

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <array>
       <dict>
         <key>UTTypeConformsTo</key>
         <array>
           <string>com.pkware.zip-archive</string>
         </array>
         <key>UTTypeDescription</key>
         <string>i-net Crystal-Clear Report File</string>
         <key>UTTypeIconName</key>
         <string>generic</string>
         <key>UTTypeIdentifier</key>
         <string>com.company.product</string>
         <key>UTTypeReferenceURL</key>
         <string>http://your-url.com</string>
         <key>UTTypeTagSpecification</key>
         <dict>
           <key>public.filename-extension</key>
             <array>
               <string>$fileEXT$</string>
             </array>
         </dict>
      </dict>
    </array>
    </plist>
    

    这将注册您的filetype $ fileExt $并告诉系统您的文件类型是压缩格式类型。我在这里使用的一个很好的参考是QuickLook IPA Plugin from googlecode

答案 2 :(得分:2)

在Windows中,您需要实现一个图标处理程序。我之前做了很多这个月,只要你了解COM的基础知识就不难了。

请参阅:http://msdn.microsoft.com/en-us/library/bb776857(VS.85).aspx

答案 3 :(得分:1)

对于Gnome,您使用thumbnailer

答案 4 :(得分:0)

据我所知,这取决于操作系统,它将基于文件扩展名。

答案 5 :(得分:0)

答案 6 :(得分:0)

可执行文件将文件内的图标(可能是多个)作为“资源”。

数据文件根据文件关联选择一个图标。

如果您希望每个文件的自定义图标更难。你要么太傻了,操作系统认为它是一个可执行文件,并将图标作为资源嵌入到文件中,或深入链接到操作系统以覆盖默认的图标选择例程。

答案 7 :(得分:0)

我认为,“自定义”图标在Windows中只能包含PE文件。文件扩展名的每个其他图标都存储在Windows注册表中。

对于PE文件的规范,您可以查看An In-Depth Look into the Win32 Portable Executable File FormatPeering Inside the PE: A Tour of the Win32 Portable Executable File Format

在其他操作系统中如何工作,我不知道:/。

答案 8 :(得分:0)

我不了解Linux,但对于Windows,您可以从这里开始: http://msdn.microsoft.com/en-us/library/bb774614.aspx

编辑:我认为此界面适用于缩略图视图中显示的缩略图,而不是图标。抱歉浪费你的时间。