以编程方式创建.textClipping的官方方法?

时间:2014-07-15 12:41:18

标签: macos cocoa

当删除拖动的文本时,Finder会创建.textClipping。

底层代码是否暴露在某处?我没有在文档,本网站和互联网上找到任何内容。

或者是否有比下面更好的方法以编程方式创建.textClipping?

-(void)makeTextClip:(NSString*)srcStr :(NSString*)clipPath
{
    NSUInteger len;
    NSData *data = [NSData dataWithBytes:[srcStr UTF8String]
        length:(len = [srcStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding])];
    NSMutableString *hexStr = [NSMutableString stringWithCapacity:len+150];
    [hexStr setString:[data description]];
    if([hexStr hasPrefix:@"<"]) [hexStr deleteCharactersInRange:NSMakeRange(0,1)];
    if([hexStr hasSuffix:@">"]) [hexStr deleteCharactersInRange:NSMakeRange([hexStr length]-1,1)];
    [hexStr insertString:
        @"data 'utf8' (256) {\n"
        "$\"" 
        atIndex:0];
    [hexStr appendString:
        @"\"\n};\n"
        "data \'drag\' (128) "
        "{\n$\"0000 0001 0000 0000 0000 0000 0000 0001\"\n"
        "$\"7574 6638 0000 0100 0000 0000 0000 0000\"\n};"
    ];
    NSError *err = nil;
    NSURL *tmpDir = [[NSFileManager defaultManager]
        URLForDirectory:NSItemReplacementDirectory
        inDomain:NSUserDomainMask
        appropriateForURL:[NSURL fileURLWithPath:@"M"]
        create:YES
        error:&err];
    if(err || !tmpDir) { NSBeep(); return; }
    char *tmpName = mktemp((char*)
        [[[tmpDir
        URLByAppendingPathComponent:@"XXXXXX"]
        path]
        cStringUsingEncoding:NSASCIIStringEncoding]
        );
    if(!tmpName) { NSBeep(); return; }
    FILE *tmpFile = fopen(tmpName, "w+");
    if(!tmpFile) { NSBeep(); return; }
    const char *cStr = [hexStr cStringUsingEncoding:NSASCIIStringEncoding];
    if(!cStr) { NSBeep(); goto cleanup; }
    len = strlen(cStr);
    int ret = fprintf(tmpFile, "%s", cStr);
    if(ret < 0 || ret != len) { NSBeep(); goto cleanup; }
    fclose(tmpFile);
    tmpFile = NULL;
    const char *cmd = [[NSString
        stringWithFormat:
            @"Rez \'%s\' -align longword -c MACS -t clpt -o \'%@\'",
            tmpName, clipPath]
        cStringUsingEncoding:NSASCIIStringEncoding];
    if(!cmd) { NSBeep(); goto cleanup; }
    ret = system(NULL);
    if(!ret) { NSBeep(); goto cleanup; }
    ret = system(cmd);
    if(ret < 0 || ret == 127) NSBeep();
cleanup:
    if(tmpFile) fclose(tmpFile);
    if(tmpDir) [[NSFileManager defaultManager] removeItemAtURL:tmpDir error:nil];
}

编辑:

更好,但不是官方的:

OSStatus dragCoreEndianFlipProc(OSType ostype, OSType datatype, short rid, void* dataPtr, UInt32 dataSize, Boolean currentlyNative, void* refcon)
{
    return handlerNotFoundErr;
}

-(void)makeTextClip:(NSString*)srcStr :(NSURL*)clipPath
{
    NSFileManager *fm = [NSFileManager defaultManager];
    if(![fm createFileAtPath:[clipPath path] contents:[NSData data] attributes:nil]) { NSBeep(); return; }

    FSRef fsRef;
    if(!CFURLGetFSRef((CFURLRef)clipPath, &fsRef)) { NSBeep(); return; }

    HFSUniStr255 resourceForkName;
    OSErr err = FSGetResourceForkName(&resourceForkName);
    if(err) { NSBeep(); return; }

    OSStatus stat;
    stat = CoreEndianInstallFlipper(kCoreEndianResourceManagerDomain, 'drag', (CoreEndianFlipProc)dragCoreEndianFlipProc, NULL);

    ResFileRefNum newForkRef = -1, curForkRef;
    curForkRef = CurResFile();
    err = FSCreateResourceFork(&fsRef, resourceForkName.length, resourceForkName.unicode, 0);
    err = FSOpenResourceFile(&fsRef, resourceForkName.length, resourceForkName.unicode, fsCurPerm, &newForkRef);
    if(err) { NSBeep(); return; }
    UseResFile(newForkRef);

    Handle dragHand, utf8Hand;
    int dragBytes[8] = { Endian32_Swap(1), 0, 0, Endian32_Swap(1), Endian32_Swap('utf8'), Endian32_Swap(256), 0, 0 };
    err = PtrToHand(dragBytes, &dragHand, 32);
    if(err) {
        NSBeep();
        DisposeHandle(dragHand);
        dragHand = NULL;
        goto cleanup;
    }

    const char *utf8Bytes = [srcStr UTF8String];
    err = PtrToHand(utf8Bytes, &utf8Hand, strlen(utf8Bytes));
    if(err) {
        NSBeep();
        if(dragHand) DisposeHandle(dragHand);
        DisposeHandle(utf8Hand);
        goto cleanup;
    }

    ResType dragResType = 'drag', utf8Type = 'utf8';
    ResID dragid = 128, utf8id = 256;

    if(CurResFile() == newForkRef) {
        AddResource(dragHand, dragResType, dragid, NULL);
        if(ResError()) { NSBeep(); goto cleanup; }
        AddResource(utf8Hand, utf8Type, utf8id, NULL);
        if(ResError()) { NSBeep(); goto cleanup; }
    }

cleanup:
    CloseResFile(newForkRef);
    UseResFile(curForkRef);
}

0 个答案:

没有答案