How can I pass a string as a path into here
void SaveLogFile()
{
logTxt->SaveFile(String::Concat
(System::Environment::GetFolderPath
(System::Environment::SpecialFolder::Personal),
"\\Testdoc.rtf"), RichTextBoxStreamType::RichNoOleObjs);
}
I can't figure out how to set a non SpecialFolder
From MSDN:
void SaveMyFile()
{
// Create a SaveFileDialog to request a path and file name to save to.
SaveFileDialog^ saveFile1 = gcnew SaveFileDialog;
// Initialize the SaveFileDialog to specify the RTF extention for the file.
saveFile1->DefaultExt = "*.rtf";
saveFile1->Filter = "RTF Files|*.rtf";
// Determine whether the user selected a file name from the saveFileDialog.
if ( saveFile1->ShowDialog() == System::Windows::Forms::DialogResult::OK &&
saveFile1->FileName->Length > 0 )
{
// Save the contents of the RichTextBox into the file.
richTextBox1->SaveFile( saveFile1->FileName );
}
}
See how the System::String^ is created here. Do it this way, too...
Related
I searched everywhere but I can't find sample on how to actually save a file to the system. Threads about opening a Save File dialog box can be read in numerous sites but the successful saving of the user created file to a user selected path is always cut (//add your code here). Please bear with me as I am new in C++ (MFC).
I know I need to actually code the saving of the data to the file path but I just don't know how.
Code snippet (via CFileDialog):
void CTryDlg::OnBnClickedSaveAs()
{
CFileDialog dlg(FALSE);
dlg.m_ofn.nMaxFile = MAX_PATH;
dlg.m_ofn.lpstrFilter = _T("Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0");
dlg.m_ofn.lpstrTitle = _T("Save File As");
CString filename;
if (dlg.DoModal() == IDOK)
{
filename = dlg.GetPathName(); // return full path and filename
//write your sample code here to save the file to the user selected path
}
}
Code snippet via GetSaveFileName():
OPENFILENAME SfnInit()
{
OPENFILENAME t_sfn;
char szFileName[MAX_PATH] = "";
ZeroMemory(&t_sfn, sizeof(t_sfn));
t_sfn.lStructSize = sizeof(t_sfn);
t_sfn.hwndOwner = NULL;
t_sfn.lpstrFilter = _T("Text file\0*.txt\0");
t_sfn.lpstrFile = szFileName;
t_sfn.lpstrTitle = _T("Save As\0");
t_sfn.nMaxFile = MAX_PATH;
t_sfn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
t_sfn.lpstrDefExt = _T("Text file\0*.txt\0");
if (GetSaveFileName(&t_sfn2) != true)
{
AfxMessageBox(_T("Saving file canceled!"));
}
else
{
//write your sample code here to save the file to the user selected path
}
}
Anybody who can provide a very simple sample code that could actually save a user desired file (ex: text file) to the user selected path will be greatly appreciated.
I have also read that the program should run as administrator.
Thank you.
Since you are using MFC, I would recommend sticking with MFC classes for such file I/O.
Sadly, I am using VS 2008, but here is the class hierarchy for CFile:
If it's a text file, using/deriving from CStdioFile makes sense. It has the basic ReadString WriteString methods.
However, if you are wanting to serialize something derived from CDocument (Document/View architecture), you will want to utilize streams, possibly with schemas/versioning to go with your serialization. That's a completely different topic/answer.
EDIT: duh - here's a simple CStdioFile output
CFileDialog fd(FALSE, "txt", "MyFile.txt", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Text files (*.txt)|*.txt|All files (*.*)|*.*", this);
if (fd.DoModal() == IDOK)
{
CStdioFile fOut(fd.GetPathName(), CFile::modeCreate | CFile::modeWrite);
for (int i = 0; i < asData.GetSize(); i++)
{
fOut.WriteString(asData[i] + '\n');
}
fOut.Close();
}
Here is a very basic sample:
...
if (dlg.DoModal() == IDOK)
{
filename = dlg.GetPathName(); // return full path and filename
FILE *file = fopen(filename, "w"); // open file for writing
if (file == NULL)
AfxMessageBox("File couild not be created."};
else
{
// file could be created, write something
fprintf(file, "Some text\n");
// and close the file
fclose(file);
}
}
...
This will write "some text" into the file whose name has been provided by the user with the CFileDialog file picker.
In real world you need to write whatever text according to the data of your program.
This is really most basic knowledge.
I have a RichTextBox that I would like to allow a user to drag and drop a file from disk into. All that should appear in the textbox is the filename(s). This code currently adds "System.String[]" to the textbox instead of the filename. When I change the DataFormats::FileDrop to DataFormats::Text as this MSDN would seem to suggest, I get a NULL dereference error.
The RichTextBox name is rtbFile. In my constructor, I have:
this->rtbFile->AllowDrop = true;
I set up the events like this (within InitializeComponents):
this->rtbFile->DragEnter += gcnew System::Windows::Forms::DragEventHandler(this, &VanicheMain::rtbFile_DragEnter);
this->rtbFile->DragDrop += gcnew System::Windows::Forms::DragEventHandler(this, &VanicheMain::rtbFile_DragDrop);
The functions are defined as follows:
void rtbFile_DragEnter(System::Object ^sender, System::Windows::Forms::DragEventArgs ^ e) {
if (e->Data->GetDataPresent(DataFormats::FileDrop))
e->Effect = DragDropEffects::Copy;
else
e->Effect = DragDropEffects::None;
}
System::Void rtbFile_DragDrop(System::Object ^sender, System::Windows::Forms::DragEventArgs ^e){
int i = rtbFile->SelectionStart;;
String ^s = rtbFile->Text->Substring(i);
rtbFile->Text = rtbFile->Text->Substring(0, i);
String ^str = String::Concat(rtbFile->Text, e->Data->GetData(DataFormats::FileDrop)->ToString());
rtbFile->Text = String::Concat(str, s);
}
Dragging files always produces an array of strings. Each array element is the path to one of the files that are dragged. You'll need to write the extra code to cast the return value of GetData() to an array and iterate it, reading the content of each file. Similar to this:
array<String^>^ paths = safe_cast<array<String^>^>(e->Data->GetData(DataFormats::FileDrop));
for each (String^ path in paths) {
String^ ext = System::IO::Path::GetExtension(path)->ToLower();
if (ext == ".txt") rtbFile->AppendText(System::IO::File::ReadAllText(path));
}
I've a text file with its backup copy: backup copy has the same name with only a "2" as last character of the extension (example: Original: Myfile.txt - Backup: Myfile.txt2).
Sometimes I need to replace the original one with the backup; I do the following:
QFile BackupFile("Myfile.txt2"); // backup copy
QString nameFile = BackupFile.fileName();// name of backup copy of file
nameFile.chop(1); // remove the last letter of file name, so nameFile now is the same of Original file
QFile originalFile(nameFile); // Original copy
originalFile.remove(); // delete the original file
BackupFile.rename(nameFile); // rename the backup file as original
BackupFile.close(); // close the file
This works, but it seems too complex. I'd like something easier.
Do you have any suggestion?
I think this code can be simple method. However, you should add code for error case, such as 'check whether backup file exist.', etc..
auto ReplaceWithBackup = []( QString& backupName ) -> bool
{
QString originName = backupName;
originName.chop( 1 );
if ( QFile::exists( originName ) )
{
QFile::remove( originName );
}
return QFile::rename( backupName, originName );
};
if ( ReplaceWithBackup( "Myfile.txt2") == false )
{
// error
}
If the files are in the same directory, you can use QDir::rename. Otherwise reading one file and writing in the other is required. Here is my version of the first case.
// Generate some test data
{
QFile bf( "Myfile.txt2" );
bf.open(QIODevice::WriteOnly);
bf.write("Backup data");
QFile( "Myfile.txt" ).open(QIODevice::WriteOnly);
}
//Assume you know which back-up file to restore
QString backupFn("Myfile.txt2");
//Actual code
QString origFn = backupFn.mid( 0, backupFn.size()-1 ); //"guess" the original file name.
QFile::remove( origFn ); //Use static version to delete file by name (No QFile instance required)
QDir().rename(backupFn,origFn);
However, each line requires many checks and validations e.g. is the provided backup-file name a valid backup name, did remove/rename succeded, etc, etc.
I have a need to create an action that will:
1. copy a selected part (selected by hand) of an image in an already opened file
2. paste selection into new file
3. save new file as jpg file, but not with default file name of "untitled.jpg" - instead use a unique name or use a auto-increment suffix
Because the action will be run multiple times on different selections from the same image, saving each selection with a unique name or auto-incremented suffix would save the step of manually supplying the filename each time a different selection is saved.
I can create an action that gets to the save-as step, but don't know if it is possible to modify the default save as name as described above. Is it possible?
No. Tried it before with no success. You have to save manually.
Don't think this is possible with an action but you can write a script do to it.
I have created a script for similar work. It uses a technique to generate unique filenames and save the file.
/************************************************************************
* Author: Nishant Kumar
* Description: This script iterates through a template to create
* jpg images with id card numbers.
* Date: 08-03-2015
***********************************************************************/
//current id count
var id_count = 0;
//total no of id cards to produce
var total_id_cards = 42;
//no. of cards per sheet
var card_per_sheet = 21;
//Save path related to current file
var save_path = app.activeDocument.path;
//do an iteration, number the cards and save file
do{
//iterate 24 nos in each document
for(var i = 0; i<card_per_sheet; i++){
id_count++;
app.activeDocument.layers[i].textItem.contents = id_count;
}
//Create a jpg document with standard options
jpgSaveOptions = new JPEGSaveOptions();
jpgSaveOptions.embedColorProfile = true;
jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgSaveOptions.matte = MatteType.NONE;
jpgSaveOptions.quality = 12;
//Save jpg with incremental file names (1.jpg, 2.jpg), make sure the path exists
jpgFile = new File( save_path + "/output/" + id_count/card_per_sheet + ".jpeg" );
app.activeDocument.saveAs(jpgFile, jpgSaveOptions, true, Extension.LOWERCASE);
}while(id_count < total_id_cards);
I know this is old, but still. You can use the following script.
How to use a script:
Copy the following script in notepad, and save it in directory similar to "C:\Program Files (x86)\Adobe\Adobe Photoshop CS2\Presets\Scripts" with the extension JSX.
To run the scrip in photoshop, go to File > Scripts > "Your Script".
#target photoshop
main();
function main(){
if(!documents.length) return;
var Name = app.activeDocument.name.replace(/.[^.]+$/, '');
Name = Name.replace(/\d+$/,'');
try{
var savePath = activeDocument.path;
}catch(e){
alert("You must save this document first!");
}
var fileList= savePath.getFiles(Name +"*.jpg").sort().reverse();
var Suffix = 0;
if(fileList.length){
Suffix = Number(fileList[0].name.replace(/\.[^\.]+$/, '').match(/\d+$/));
}
Suffix= zeroPad(Suffix + 1, 4);
var saveFile = File(savePath + "/" + Name + "_" + Suffix + ".jpg");
SaveJPG(saveFile);
}
function SaveJPG(saveFile){
//Create a jpg document with standard options
jpgSaveOptions = new JPEGSaveOptions();
jpgSaveOptions.embedColorProfile = true;
jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgSaveOptions.matte = MatteType.NONE;
jpgSaveOptions.quality = 12;
//Save jpg with incremental file names (1.jpg, 2.jpg), make sure the path exists
activeDocument.saveAs(saveFile, jpgSaveOptions, true, Extension.LOWERCASE);
};
function zeroPad(n, s) {
n = n.toString();
while (n.length < s) n = '0' + n;
return n;
};
Sometimes I need to ensure I'm not overwriting an existing file when saving some data, and I'd like to use a function that appends a suffix similar to how a browser does it - if dir/file.txt exists, it becomes dir/file (1).txt.
This is an implementation I've made, that uses Qt functions:
// Adds a unique suffix to a file name so no existing file has the same file
// name. Can be used to avoid overwriting existing files. Works for both
// files/directories, and both relative/absolute paths. The suffix is in the
// form - "path/to/file.tar.gz", "path/to/file (1).tar.gz",
// "path/to/file (2).tar.gz", etc.
QString addUniqueSuffix(const QString &fileName)
{
// If the file doesn't exist return the same name.
if (!QFile::exists(fileName)) {
return fileName;
}
QFileInfo fileInfo(fileName);
QString ret;
// Split the file into 2 parts - dot+extension, and everything else. For
// example, "path/file.tar.gz" becomes "path/file"+".tar.gz", while
// "path/file" (note lack of extension) becomes "path/file"+"".
QString secondPart = fileInfo.completeSuffix();
QString firstPart;
if (!secondPart.isEmpty()) {
secondPart = "." + secondPart;
firstPart = fileName.left(fileName.size() - secondPart.size());
} else {
firstPart = fileName;
}
// Try with an ever-increasing number suffix, until we've reached a file
// that does not yet exist.
for (int ii = 1; ; ii++) {
// Construct the new file name by adding the unique number between the
// first and second part.
ret = QString("%1 (%2)%3").arg(firstPart).arg(ii).arg(secondPart);
// If no file exists with the new name, return it.
if (!QFile::exists(ret)) {
return ret;
}
}
}
QTemporaryFile can do it for non-temporary files, despite its name:
QTemporaryFile file("./foobarXXXXXX.txt");
file.open();
// now the file should have been renamed to something like ./foobarQSlkDJ.txt
file.setAutoRemove(false);
// now the file will not be removed when QTemporaryFile is deleted
A better solution is to use GUID
Or you can generate a hash based on bytes collected from within a file, either randomly or based on some data property that is fairly unique from file to file.