Well, I'm making a program in Delphi that uses a TValueListEditor object to store Keys and Values and save them to a .txt file. I used this functions to do so:
procedure TfrmInserir.FormClose(Sender: TObject; var Action: TCloseAction);
begin
vlePalavras.Strings.SaveToFile('C:\Users\Felipe Knop\Desktop\Felipe\Algoritmos\Delphi\Projetos\Palavras Japonês\Lista.txt');
end;
procedure TfrmInserir.FormCreate(Sender: TObject);
begin
vlePalavras.Strings.LoadFromFile('C:\Users\Felipe Knop\Desktop\Felipe\Algoritmos\Delphi\Projetos\Palavras Japonês\Lista.txt');
end;
In my computer it works fine because the saving path is in the code, but I wanted to share the program with my friends and wanted them to be able to choose the path. Thought about using a TSaveDialog, but since I never used, I don't know if it would do what I want. I need a way to make the user able to choose a path just once and the file will be saved there every time he closes the form. Any ideas?
EDIT: Thank you both Jason and Sean for you answers. Both helped me alot and I figured out a way to make the program more interactive and give my friends the possibility to even share their lists. May sound dumb but it's one of my first programs and I really thank you alot.
Firstly I would suggest not using the FormCreate to load things from file. If its excepts or fails for any reason your form won't load. Create a method called something like "FormInit" and call this after your have created the form, then show it. Allows for better handling of FormInit issues. Same for closing down the form, have a FormDeInit and call it in the "CloseQuery".
Onto your question. I use "ForceDirectories" to ensure that the path chosen exists for saving. This will return false if the directory couldn't be created, true in all other cases. Again you can handle the error nicely when you can't create the folder.
The save dialog is fine for saying where to store the file, however when you run up again how do you know where they set this the last time? Answer you don't, you need to store that somewhere. So the answer here is to simply store your initial configuration in a known place or ask them where it is. I prefer to have base configurations stored in a known place, and store the location of other configs in there. For simplicity lets stay at one level.
If you need to have a known location then use the following calls
ExtractFileDir(Application.ExeName);
This will give you the directory in which the application executable is running. From here you can attach any directory structure you see fit.
If you choose to use the save dialog to get the directory or the application path, make sure to still use the forceDirectory call to make sure the path exists.
Related
My traditional workflow must be a little different to the PHPStorm default. I often work on multiple files at the same time and want to be able to save just one file when I've finished with it, without saving the others that I've modified.
I've managed to turn off the auto-save feature. Now, when I edit files I get stars on the ones I've edited and they stay like that until I hit 'save'. So far so good.
But when press CTRL-S to save, expecting it to save the one file I'm looking at so I can go back to the ones with asterisks to polish them off too, it also saves ALL the other files too.
I hope there's some way to change this behaviour or set up something to allow me to save just one file at a time!
Yes, you can .. but that still does not change a lot (e.g if you change your settings, or run/re-run something -- all files will be saved automatically anyway). Eventually (after few weeks or month of adaptation) you will get used to this behaviour and quite likely will love it (yes, this means changing working habits a bit, which is quite hard to do (requires time) for some people/in some cases).
Anyway ... to enable "save single file" functionality:
Settings | Keymap
On that screen, in search box type "save"
The action you are after is called "Other | Save Document"
Assign whatever shortcut you want.
P.S.
This action will NOT ask for confirmation (same behaviour as standard save does).
P.P.S.
This action is available since PhpStorm v7 ONLY.
I was asked to develop a game called "Flag Quiz" in which the player have to guess the correct name of the flag that appears in the middle of the screen.
Of course I have a lot of pictures (221 flags) and I have to put them inside the program because, when the button Play is pressed, the program has to pick randomly 10 of these flags.
Problem
I was thinking to use an ImageList but the flags are 480x311 and so Delphi asks me to separate the picutre in 30 different bitmaps. Can I do anything about this?
My idea, to avoid that problem, was the following (although I think that it's not very good): create 221 TPicture components (invisible to the user of course) and load in each of them a picture of a flag.
I'd prefer not using the last idea I had. Do you know any improvement?
This sort of problem is simply not suited to the form designer. You want to store 221 images, and managing that in the IDE will be horrible. Once you've got them all in you won't be able to see them readily because they will be base 16 encoded in a .dfm file. Under revision control it will be a mess because you won't be able to change individual images in a manageable and traceable manner.
The accepted way to do this is to use resources. If it were me, I'd arrange for my images to have predicatable names. For instance, flag1, flag2, etc. I'd generate a resource script (.rc) that listed all the flags. I'd compile that resource script to a compiled resource (.res) which is linked to the executable. I'd have the resource script and the image files committed to revision control.
Then at runtime you have a single TImage control to display the flag. Every time you need a new image you load it with TResourceStream, and push it into the TImage control.
Devexpress has a Componnect named cximagecolletion that you can put your images on it and save and load images from/to file
or you can save all flags in small access db and load it when you need using tadodataset
there is no doubt that if you put your images direct on your form your dfm grow very high and so you Get Into trouble
Personally I would store each file as an image in a dedicated subdirectory, using the country as a file name. Then I would read the subdirectory file names on entry to the program (so I have a list of countries that I can randomly choose from) and use TImage.LoadFromFile to display the flag. This is far easier to extend than using a resource file (IMHO).
I am using Express Quantum Grid from developer express. From code i came to know that they are storing the user settings using TMemIniFile. I know the sections where they are storing but is there any way to open the Ini file and see the contents? If so where is the file located?
From code I came to know that they are storing the user settings using TMemIniFile.
The constructor of TMemIniFile receives the name of the file that stores the INI file. So, you simply need to find the call to TMemIniFile.Create and your answer will be revealed.
For years I've put my application data files in c:\MyCompany\MyDataFileFolder\App where 'App' is my application name. I made this choice in the early days of Wild-West-Windows when Microsoft seemed to keep changing its own mind (My Documents, Documents, Program Data etc). As I've learnt more about how to do things correctly, and as Windows has now 'settled down' and is more picky about permissions I'd like to move my files. Users have got used to where they are though, and what I'd really like to do is to implement something like Windows does with 'special folders' where there are several synonymous names, thus in my legacy folder I'd like to put something in (or change a folder to) an alias for the real location which will now be something descended from Program Data. This way, the files are in a good place with the correct permissions and if we run a utility expecting or modifying files in the 'old' place this gets changed transparently to the 'new' place (thus a simple shortcut wont work).
Is this possible? Is there are recognised technique for this? I'm using Delphi XE2.
What you are looking for is either a Symbolic Link or a Reparse Point.
This might be a dumb question, but I don't seem to be able to create a textfile that is writeable by all the users on a machine, they are always owned by the currently logged in user.
Any ideas? Should I be using TextFile or TFileStream?
I think OP wants to know where to create file writable by all users.
If so, Windows ideology dictates what such files should be created in directory returned by SHGetFolderPath(CSIDL_COMMON_DOCUMENTS) or probabably CSIDL_COMMON_APPDATA
If you create a file it will simply inherit the permissions of its parent container, in other words the folder in which it resides. So you simply need to create it in a folder which has the necessary rights.
What do you mean by "Writable by all the users on a machine" ?
Do you mean you create a file by one user, then another user comes and tries to write into that file, and it fails?
Or do you mean a user creates a file, and other users who are simultaneously connected to the same machine (via terminal sessions) cannot write into the file while the first user is writing in it?
If it is the first case, where is the file saved? Is it in a folder which all users have write access to it?
If it is the second case, you can open the file for read/write without locking it:
var
Stream : TFileStream;
begin
Stream := TFileStream.Create('D:\MyFile',fmOpenReadWrite + fmShareDenyNone);
try
finally
Stream.Free;
end;
end;
Take note with such a code, multiple users might overwrite each other!
Are you talking about NTFS permissions for the file? If yes, you need to look Delphi wrapper for NT security API, and using that API change file security settings to allow Everyone group access the file. If you are just talking about shared access while the file is opened), vcldeveloper above has given the answer.