代码之家  ›  专栏  ›  技术社区  ›  Girish Kolari

如何使用cocoa标记文件和文件夹

  •  5
  • Girish Kolari  · 技术社区  · 15 年前

    我想用一些颜色(图像)标记一个文件和文件夹。如何做到这一点?

    我看到这种行为奏效了 Dropbox

    博客帖子 Cocoa Tutorial: Custom Folder Icons

    除了图标服务还有其他解决方案吗?

    3 回复  |  直到 6 年前
        1
  •  4
  •   Dave DeLong    15 年前

    下面的函数是我为这个问题找到的解决方案

    BOOL AddBadgeToItem(NSString* path,NSData* tag)
    
    {   
        FSCatalogInfo info;
        FSRef par;
        FSRef ref;
        Boolean dir = false;
    
        if (tag&&(FSPathMakeRef([path fileSystemRepresentation],&par,&dir)==noErr)) 
        {
            HFSUniStr255 fork = {0,{0}};
            sint16 refnum = kResFileNotOpened;
            FSGetResourceForkName(&fork);
    
            if (dir) 
            {
    
                NSString *name = @"Icon\r";
                memset(&info,0,sizeof(info));
                ((FileInfo*)(&info.finderInfo))->finderFlags = kIsInvisible;
    
                OSErr error = FSCreateResourceFile(&par,[name lengthOfBytesUsingEncoding:NSUTF16LittleEndianStringEncoding],(UniChar*)[name cStringUsingEncoding:NSUTF16LittleEndianStringEncoding],kFSCatInfoFinderXInfo,&info,fork.length, fork.unicode,&ref,NULL);
    
                if( error == dupFNErr )
                {
                    // file already exists; prepare to try to open it
                    const char *iconFileSystemPath = [[path stringByAppendingPathComponent:@"\000I\000c\000o\000n\000\r"] fileSystemRepresentation];
    
                    OSStatus status = FSPathMakeRef((const UInt8 *)iconFileSystemPath, &ref, NULL);
                    if (status != noErr)
                    {
                        fprintf(stderr, "error: FSPathMakeRef() returned %d for file \"%s\"\n", (int)status, iconFileSystemPath);
    
                    }
                }else if ( error != noErr)
                {
                    return NO;
                }
    
            } 
            else 
            {
                BlockMoveData(&par,&ref,sizeof(FSRef));
                if (FSCreateResourceFork(&ref,fork.length,fork.unicode,0)!=noErr) 
                {
                    //test
    
                    if (FSOpenResourceFile(&ref,fork.length,fork.unicode,fsRdWrPerm,&refnum)!=noErr) {
                        return NO;
                    }
                    if (refnum!=kResFileNotOpened) {
    
                        UpdateResFile(refnum);
                        CloseResFile(refnum);
    
                        if (FSGetCatalogInfo(&par,kFSCatInfoFinderXInfo,&info,NULL,NULL,NULL)==noErr) {
                            ((ExtendedFileInfo*)(&info.extFinderInfo))->extendedFinderFlags = kExtendedFlagsAreInvalid;
                            FSSetCatalogInfo(&par,kFSCatInfoFinderXInfo,&info);
                        }
                    }
    
                    //Test end
                    return NO;
                }
            }
            OSErr errorr = FSOpenResourceFile(&ref,fork.length,fork.unicode,fsRdWrPerm,&refnum);
            if (errorr!=noErr) {
                return NO;
            }
            if (refnum!=kResFileNotOpened) {
                CustomBadgeResource* cbr;
    
                int len = [tag length]; 
                Handle h = NewHandle(len);
                if (h) {
                    BlockMoveData([tag bytes],*h,len);
                    AddResource(h,kIconFamilyType,128,"\p");
                    WriteResource(h);
                    ReleaseResource(h);
                }
    
                h = NewHandle(sizeof(CustomBadgeResource)); 
                if (h) {
                    cbr = (CustomBadgeResource*)*h;
                    memset(cbr,0,sizeof(CustomBadgeResource));
                    cbr->version = kCustomBadgeResourceVersion;
                    cbr->customBadgeResourceID = 128;
                    AddResource(h,kCustomBadgeResourceType,kCustomBadgeResourceID,"\p");
                    WriteResource(h);
                    ReleaseResource(h);
                }
    
                UpdateResFile(refnum);
                CloseResFile(refnum);
    
                if (FSGetCatalogInfo(&par,kFSCatInfoFinderXInfo,&info,NULL,NULL,NULL)==noErr) {
                    ((ExtendedFileInfo*)(&info.extFinderInfo))->extendedFinderFlags = kExtendedFlagHasCustomBadge;
                    FSSetCatalogInfo(&par,kFSCatInfoFinderXInfo,&info);
                }
            }
        }
        return NO;
    }
    
        2
  •  0
  •   Brian Webster    15 年前

    -setIcon:forFile:options: 方法,该方法允许您仅指定一个NSImage,以应用于给定路径下的文件/文件夹。

        3
  •  0
  •   Ky -    8 年前
    推荐文章