There were changes in recent releases that were related to file formats, such as the ability to put non-binary files in books. This effort has improved the handling of native file formats, but maybe it also affected F_ApiSimpleSave() too. I don't know. I would, however, strongly recommend F_ApiSave(), as it is much more reliable. Below is a function I use for saving files. It has some quirks related to my own personal needs, but hopefully you can make some sense of it. Warning - it is littered with references to other functions that you don't have. Things like ds() which is my shortcut to deallocate a string and sie() which is my shortcut to check for an empty string. So, it won't just work as-is for you, but maybe it can be of some use.
//////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// Two things... to do a Save As, send a path. Also, normally
// send -1 for the fileType unless you want to change it from the
// extention of the target path. This function will figure it out
// based on the extension if you do not send it.
// Options:
//FV_SaveFmtXml
//FV_SaveFmtSgml
//FV_SaveFmtInterchange
//FV_SaveFmtText
//FV_SaveFmtBinary
// 4/7/2014 NEW to specify a structure application,
// append it to the path following two colons. Or,
// if a docID is sent, send it for the path, preceeded
// by two colons.
// 5/20/2015 NEW, to save as RTF, send 100 for the file type.
// YOU MUST SEND THE PATH TOO.
F_ObjHandleT ws_SaveFile(F_ObjHandleT docId,
StringT path,
IntT fileType,
IntT ignoreErrors,
IntT doBackup,
IntT notifyAPIClients)
{
F_PropValsT saveScript, *returnp = NULL;
UIntT sn;
StringT tempPath,
structApp;
F_StringsT tempStrings;
if(ws_StrIndexOf(path, "::", 0, False) > -1)
{
tempStrings = ws_GetArgumentsFromString_2(path, "::");
if(sie(tempStrings.val[0]))
tempPath = F_ApiGetString(FV_SessionId, docId, FP_Name);
else tempPath = cs(tempStrings.val[0]);
if(tempStrings.len > 1) structApp = cs(tempStrings.val[1]);
else structApp = cs("");
dss(&tempStrings);
}
else if(sie(path))
{
tempPath = F_ApiGetString(FV_SessionId, docId, FP_Name);
structApp = cs("");
}
else
{
tempPath = F_ApiCopyString(path);
structApp = cs("");
}
//let's figure out the fileType if we don't have one
if(fileType < 0)
{
if(ws_StrIsSuffix(tempPath, ".xml", False))
fileType = FV_SaveFmtXml;
else if(ws_StrIsSuffix(tempPath, ".sgml", False))
fileType = FV_SaveFmtSgml;
else if(ws_StrIsSuffix(tempPath, ".mif", False))
fileType = FV_SaveFmtInterchange;
else if(ws_StrIsSuffix(tempPath, ".txt", False))
fileType = FV_SaveFmtText;
else if(ws_StrIsSuffix(tempPath, ".pdf", False))
fileType = FV_SaveFmtPdf;
else
fileType = FV_SaveFmtBinary;
}
saveScript = F_ApiGetSaveDefaultParams();
sn = F_ApiGetPropIndex(&saveScript, FS_AlertUserAboutFailure);
if(ignoreErrors)
saveScript.val[sn].propVal.u.ival = False;
else
saveScript.val[sn].propVal.u.ival = True;
sn = F_ApiGetPropIndex(&saveScript, FS_AutoBackupOnSave);
if(doBackup)
saveScript.val[sn].propVal.u.ival = FV_SaveYesAutoBackup;
else
saveScript.val[sn].propVal.u.ival = FV_SaveNoAutoBackup;
sn = F_ApiGetPropIndex(&saveScript, FS_DontNotifyAPIClients);
if(notifyAPIClients)
saveScript.val[sn].propVal.u.ival = False;
else
saveScript.val[sn].propVal.u.ival = True;
//File type
sn = F_ApiGetPropIndex(&saveScript, FS_FileType);
//For RTF, a hack
if(fileType == 100)
{
saveScript.val[sn].propVal.u.ival = FV_SaveFmtFilter;
sn = F_ApiGetPropIndex(&saveScript, FS_SaveFileTypeHint);
ds(&saveScript.val[sn].propVal.u.sval);
saveScript.val[sn].propVal.u.sval = cs("0001ADBIRTF Microsoft RTF1.6");
}
else
{
saveScript.val[sn].propVal.u.ival = fileType;
}
sn = F_ApiGetPropIndex(&saveScript, FS_RetainNameStripe);
saveScript.val[sn].propVal.u.ival = False;
//if we didn't have a path, it's just a save, but only
//for binaries. All other file formats are always a Save As.
if(sie(path) && fileType == FV_SaveFmtBinary)
{
sn = F_ApiGetPropIndex(&saveScript, FS_SaveMode);
saveScript.val[sn].propVal.u.ival = FV_ModeSave;
sn = F_ApiGetPropIndex(&saveScript, FS_SaveAsModeName);
saveScript.val[sn].propVal.u.ival = FV_SaveAsUseFileName;
}
else
{
sn = F_ApiGetPropIndex(&saveScript, FS_SaveMode);
saveScript.val[sn].propVal.u.ival = FV_ModeSaveAs;
sn = F_ApiGetPropIndex(&saveScript, FS_SaveAsModeName);
saveScript.val[sn].propVal.u.ival = FV_SaveAsNameProvided;
}
if(fileType == FV_SaveFmtXml ||
fileType == FV_SaveFmtSgml)
{
sn = F_ApiGetPropIndex(&saveScript, FS_StructuredSaveApplication);
ds(&saveScript.val[sn].propVal.u.sval);
saveScript.val[sn].propVal.u.sval = cs(structApp);
}
//save the document
docId = F_ApiSave(docId, tempPath, &saveScript, &returnp);
//we are done with these structures, so deallocate
F_ApiDeallocatePropVals(&saveScript);
F_ApiDeallocatePropVals(returnp);
//if something went wrong, ensure the return value is zero
if(!docId) docId = 0;
F_ApiDeallocateString(&tempPath);
F_ApiDeallocateString(&structApp);
//F_ApiPrintFAErrno();
return docId;
}