0

I have the following basic code :

procedure TForm4.shrek1Click(Sender: TObject);
begin
  shrek1.Picture.LoadFromFile('donkey.jpeg');
end;

Where shrek1 is a TImage, and donkey.jpeg is the image I want shrek1 to load when clicked.

donkey.jpeg is located in the same directory of literally every other related project file, yet when I attempt to run the code I get an error:

Exception class EFOpenError with message 'Cannot open file "\(removed directory for privacy)\donkey.jpeg". The system cannot find the file specified

What am I doing wrong?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Don't rely on relative paths. Pass the full path. And check that you get it right. If the system tells you the file does not exist, trust it. – David Heffernan Mar 10 '17 at 00:53
  • If you do not provide an absolute path, the executable will look for the image in the same path as the executable. You may want to check that the file exists in the Win32\Debug (or Win32\Release depending on your build) folder as that is where your executable will reside. To verify this, try copying the donkey.jpeg file to your Debug/Release folder. – Rohit Mar 10 '17 at 01:26
  • @Rohit: "*If you do not provide an absolute path, the executable will look for the image in the same path as the executable*" - **ONLY IF** the calling process's current working directory is the executable path. That is not guaranteed. – Remy Lebeau Mar 14 '17 at 04:33
  • That is true, @RemyLebeau - I made the assumption that TForm4 is just another one of the forms in the application. In any case it is always best to use absolute paths... – Rohit Mar 14 '17 at 05:08

1 Answers1

3

Always use absolute paths. Relative paths are relative to the calling processe's Current Working Directory, which can (and usually does) change value during the process's lifetime, and is not always what you expect.

If the JPG file is in the same folder as the your EXE, you can do this instead:

var
  AppPath: string;

procedure TForm4.shrek1Click(Sender: TObject);
var
  FileName: string;
begin
  FileName := AppPath+'donkey.jpeg'; // <-- make sure this path is accurate!
  shrek1.Picture.LoadFromFile(FileName);
end;

initialization
  AppPath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Unfortunately this still doesn't work , the error message clearly shows that the program is looking in the correct address and the file definitely exists yet it still "cannot find the file specified", is it possible that JPEG files aren't supported or something? – TheMagicalMuffinMan Mar 14 '17 at 04:02
  • @TheMagicalMuffinMan: JPGs are supported (provided you have the `jpeg` unit in your `uses` clause, if not you would be getting a different error). The OS does not lie. If it says the file does not exist, it really does not exist. You are clearly not loading the file from the correct path. The path in the error message shown in your question starts with `\\`, does it really start with that or did you do that manually when editing the error message? – Remy Lebeau Mar 14 '17 at 04:29
  • @TheMagicalMuffinMan: please don't obscure error messages like that, it takes away focus from the real problem. In any case, does `SysUtils.FileExist()` return false before calling `LoadFromFile()`? – Remy Lebeau Mar 15 '17 at 00:59
  • Yeah it does, also sorry if I've been difficult to understand – TheMagicalMuffinMan Mar 17 '17 at 00:26