Create a file with Windows Property Store (metadata) using win32 API - winapi

I'd like to create a new stub file "test.mp3" for instance, and add a Window Property to it ( System.Author for instance).
the solution must be usable for several file extension as text, picture, videos, etc...
If I just create a file and use IShellItem2::GetPropertyStore I get a HRESULT fail for invalid Arguments.
Use IShellItem2::GetPropertyStore on a real music file I can read and write Its properties just fine.
Please test your suggestions first.

Property Stores typically access and store data within the file itself. In your case of a mp3 file, it would be attempting to read and write the ID3 tags. Also, Property Stores are not stored in a database and cannot be arbitrarily added to files that don't support it.
You'll most likely need to implement your own property handlers to do what it appears you're trying to accomplish. For types that already have handlers, you'll have to replace the system handlers with your own.
The most likely reason your mp3 test is failing is that you have an empty file with no data and no valid ID3 tags.

Related

What is the relationship between CGPDFContext and CGPDFDocument?

My understanding of this was that perhaps CGPDFContext is to be used for editing PDF document data and CGPDFDocument is used for storing it, since the documentation doesn't list any ways to alter the content of a CGPDFDocument.
I'm also not quite sure what CGDataConsumer/Provider does. From reading the documentation I got the impression that the consumer/provider abstracts the relationship between the CG object and the CFData it writes to; so I don't have to do that myself. So I figured the following code would create a two page blank PDFdocument:
//Don't know exactly how large a PDF is so I gave it 1 MB for now
self->pdfData = CFDataCreateMutable(kCFAllocatorDefault, 1024);
self->consumerRef = CGDataConsumerCreateWithCFData(self->pdfData);
self.pdfRef = CGPDFContextCreate(self->consumerRef, NULL, NULL);
CGPDFContextBeginPage(self.pdfRef, NULL); //Creates a blank page?
CGPDFContextEndPage(self.pdfRef);
CGPDFContextBeginPage(self.pdfRef, NULL); //Creates a second blank page?
CGPDFContextEndPage(self.pdfRef);
//Copies the data from pdfRef's consumer into docRef's provider?
self.docRef = CGPDFDocumentCreateWithProvider(
CGDataProviderCreateWithCFData(
CFDataCreateCopy(kCFAllocatorDefault, self->pdfData)
));
It didn't work though, and NSLogging the first two pages of docRef returns NULL. I'm rather new at this, the C-Layer stuff in particular. Can someone explain to me the relationship between CGPDFContext, CGPDFDocument, CGDataConsumer & CGDataProvider and how I'd use them to create a blank PDF?
Your basic understanding is correct as far as I can see:
A CGPDFContext is a drawing context that "translates" everything that is drawn onto it to PDF instructions (typically for storage in a PDF file).
A CGPDFDocument is used to open an existing PDF file and get information from it.
When you want to create your own PDF file, you have two ways to do it as described here: https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGPDFContext/Reference/reference.html
Use "CGPDFContextCreate" which you pass a data consumer. The data consumer gets the data and can do with it as it pleases (you could create a data consumer that passes the PDF onto the clipboard for example).
Use "CGPDFContextCreateWithURL" which you pass a URL. In that case your data will be written to a PDF file at that URL.
If you want to use these functions, have a look at this page https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html#//apple_ref/doc/uid/TP30001066-CH214-TPXREF101 which explains in detail how to create PDF files with a data provider and without (simply to a PDF).
To figure out what is happening I would start by trying to write a simple PDF file to disk before writing one to a data provider and then using that data provider immediately to read it again. Without trying your code however, let me point out that you didn't use "CGPDFContextClose" which is described in the document as closing the PDF document and flushing all information to output. You could actually having a situation where stuff is cached and not written to your data provider yet, simply because you haven't forced that.

App that is a viewer and editor for the same data type?

The NSDocument system is primarily for files that read and write a particular data type. What about a type that needs to be both read-only and read-write? I'm planning an e-mail app; it would need a read-write document type for composing messages before sending, and a read-only type for reviewing already sent messages (from a Sent Items folder). The Mail.app works like this.
Would this be done as two NSDocument subclasses? (They would use the same RFC822 class for their model class.) How would you make one document type read-only?
It's still one document. You just have a different UI that you display for editing.
In the case of email you would only display editing from New or Reply/Reply All/forward action methods. (Quoting the original mail as appropriate. )
You could technically go and open the "read only" mail file in any editor that can open the file.
One of the easiest way would be to create one BOOL sayingisReadOnly`.
If its value is YES(readonly mode) make the NSTextView readonly, if it is NO(edit mode) make it default one i.e, read & write enabled.
The following will work as per your BOOL isReadOnly; value
[self.yourTextView setEditable:isReadOnly];

OS X Data file editor saving to XML: Document based or not?

So I'm trying to make a data editor for an iOS/Android app I've got. There's 3 separate data files that I'd like to be able to edit, and I would like to save them to plist files or xml files. I'm planning on using Core Data in the app. The problems I'm running into:
1). Should this be a Document-Based Application or not?
2). If so, how would I set it up to allow editing of 3 different structures of files?
3). And if so, how would I go about setting the document based app to use regular plist/xml files as the file type instead of some custom file type?
The plan is for the editor to be able to open up and edit the files, and then the saved files can be copied into the project resources of the iOS and Android apps.
1. Should the app be document-based?
Yes.
2. How would one allow editing three different structures of files?
Choose from any of the following:
Create three dictionaries in the document types list, all three of which reference the same document class.
The same as above, but with windowNibName or makeWindowControllers choosing the UI depending on the document type. In other words, shared model code, but different view hierarchies. (I probably would choose either of the alternatives instead.)
Create three document type dictionaries, each of which has its own document class.
Which one you choose will depend on just how different the types are.
You'll probably want to export a UTI for each document type, as well. Xcode will not help you there; you'll need to write each UTI dictionary by hand.
3. How would I set the document based app to use regular plist/xml files as the file type instead of some custom file type?
If you export one or more UTIs, you should set the parent UTI(s) of each UTI appropriately, but that's advisory; all it means is you'll be able to open the documents with generic plist or XML editors/viewers.
Reading in and writing out the data is up to you, in each document class. You will have to use NSPropertyListSerialization, NSXMLParser, PRHXMLParser, NSXMLDocument, or something else, as you see fit; NSDocument does not handle your file format for you.

distinguish use cases in NSAutosaveElsewhereOperation

I try to add AutoSave support to the Core Data File Wrapper example
Now if i have a new/untitled document writeSafelyToURL is called with the NSAutosaveElsewhereOperation type.
The bad thing is, I get this type in both typical use cases
- new file: which store a complete new document by creating the file wrapper and the persistent store file
- save diff: where the file wrapper already exists and only an update is required.
Does somebody else already handled this topic or did somebody already migrated this?
The original sample use the originalStoreURL to distinguish those two use cases, which solution worked best for you?
Thanks

How to add components in to an existing GUI created by guide?

I just created a GUI using guide in MATLAB for a small project I'm working on. I have amongst other things two text fields for from and to dates. Now I'd like to get rid of them and use a Java date select tool. Of course this is not possible using guide so I need to add them manually.
I've managed to get them to show up by putting this code into my Opening_Fcn,
uicomponent(handles, 'style','com.jidesoft.combobox.DateChooserPanel','tag','til2');
using UICOMPONENT.
But even though it shows up I can't access the date select's attributes, for example
get(handles.til2)
returns
??? Reference to non-existent field 'til2'.
How can I fix this?
Unless you edit the saved GUI figure, the basic handles structure will not include your new component by default.
One way to access you component is to store the handle via guidata, by adding the following to your opening function:
handles.til2 = uicomponent(handles, 'style','com.jidesoft.combobox.DateChooserPanel','tag','til2');
guidata(hObject,handles)
Functions that need to access the handle need the line
handles = guidata(hObject)
to return the full handles structure that includes the filed til2

Resources