Is there a way to execute an internal command stored in a . txt (or String) file in Delphi?

Asked

Viewed 225 times

0

I am trying to display an image when loading a Form, but the command needs to come from an external file. txt (or a string that will store this existing command in .txt). I can show the lines with Showmessage, that way:

procedure TFrmAlbum.FormShow(Sender: TObject);
var
Achar : TStringList;
j : Integer;
img : String;
begin
             Achar := TStringList.Create;
             Try
               Achar.LoadFromFile('images.txt');
               for j := 0 to Achar.Count-1 do
                 begin
                   ShowMessage(Achar[j]);
                 end;
             Finally
             Achar.Free;
             End;
end;

What I want is some command I can use instead of Showmessage for instead of showing lines, run them. Do you have how to do this?

Edit1: I don’t know if it will help, but the command lines in . txt, which should be interpreted by the program are like these:

Image1.Picture.Bitmap.LoadFromResourceName(HInstance, 'Bitmap_1');
Image2.Picture.Bitmap.LoadFromResourceName(HInstance, 'Bitmap_2');
  • Run an external file code? I find it difficult since Delphi is compiled and not interpreted.

  • In this case, do you want the operating system itself to execute the command (opening the image in the default program)? You can use the Shellexecute command (uses Shellapi).

  • @Jhonny Freire, I researched and saw that a solution would be to create an interpreter (I think of pascal), but it is complicated, especially for me that I am beginner (and self-taught) in Delphi. I’m looking for a way around this, I just don’t know if it’s possible...

  • @Ricardo Alves Carvalho, what I want is for the program I’m running to execute the command (show an image in Timage), not the Operating System.

1 answer

1


I am guessing that each row of the file will be on a Timage named Image1, Image2, etc. I am also assuming that the files are all bitmaps.

procedure TFrmAlbum.FormShow(Sender: TObject); var Achar : TStringList; i, j : Integer; begin Achar := TStringList.Create; Try Achar.LoadFromFile('images.txt'); for j := 0 to Achar.Count-1 do begin i := pos('_', Achar[j]) + 1; i := StrToInt(copy(Achar[j], i, 10)); TImage(FindComponent( 'Image' + IntToStr(i))).Picture.Bitmap.LoadFromResourceName(HInstance, Achar[j]); end; Finally Achar.Free; End; end;
  • Ricardo Alves Carvalho is correct in his assumptions. But he has not yet had the expected result. When running, I get the message: 'Unknown picture file Extension (.Loadfromresourcename(Hinstance, 'Bitmap_1');)' It looks like it took part of the command instead of taking the whole line.

  • Do you want to read from resource or file? The above code is to read from bitmap file. images.txt would have the full name of a file per line.

  • The images are stored in the executable, so the reading is resource, as it is saved in the.txt file (see the Edit1 I added in the question). I am trying to put the path that remains at the beginning of your code (which I receive as an answer), but finding the error 'Incompatible types' because I am using a String for this. What should I use in this case?

  • What I did: I declared img variable as string (tried Shortstring tb due to msg error presented with String) img := 'Image' + IntToStr(j + 1) +'.Picture.Bitmap';
 img+ TImage(FindComponent('Image' + IntToStr(j + 1))).Picture.LoadFromFile(Achar[j]);


  • The loop section: Timage(Findcomponent('Image' + Inttostr(j))).Picture.Bitmap.Loadfromresourcename(Hinstance, Find[j]); ///here, the file lines should have the resource name.

  • When used this way, I get msg "Access Violation at address 00635FCD in moidule 'Project_teste.exe'. Read of address 000001D0."

  • I put an 'Application.Processmessages;' before loading Timage, and the error became "List index out of Bounds (2)" and tb have a msg of Delphi "[dcc32 Warning] Teste.pas(179): W1037 FOR-Loop variable 'j' may be Undefined after loop". I did some research and from what I understand it’s some parameter that’s wrong, but I couldn’t find which one.

  • I made a mistake where I put the code of the loop, where is "Inttostr(j))", should be "Inttostr(j) + 1)". This is to match the "Image1" with the line "0" of the stringlist. It is also important that you do not read more lines from the file than the number of Timages that exist in your Form. Now, this message of j being undefined after the loop indicates that your code is not in the example. Check that the command inside the loop has more than one line and, if applicable, use Begin.. end to delimit the block.

  • Ricardo Alves Carvalho, almost there... His code is perfect, but the program is not found the image. I now receive the message: "Resource Image1.Picture.Bitmap.Loadfromresourcename(Hinstance, 'Bitmap_1'); not found"'. Detail, it works when I use the code: 
begin
 if (FindComponent('Image' +IntToStr(a)) as TImage).Picture.height = 0 then
 (FindComponent('Image' +IntToStr(a)) as TImage).Picture.Bitmap.LoadFromResourceName(HInstance, 'Bitmap_' +IntToStr(a));
end;
 It is the same image address, whatever is missing?

  • In addition, the code is in the Onshow of the Main Form and giving the msg above. Now if I take Onshow and put it in the Onchange of a Combobox, the error is again "Access Violation at address 006A6452 in module 'Project_teste.exe'. Read of address 000001D0." when accessing the file . txt (I did the test and if the file is empty nothing happens). If the command is the same, why different errors?

  • One more remark, the Combobox where I put the command is in another Form, maybe that is the reason for the error "Access Violation" instead "Resource ... not found". If so, can I indicate that the result should be applied in the main form? Only adding the form name in front of "Timage(Findcomponent..." with dots or parentheses did not work...

  • Formprincipal.Findcomponent.

  • It was really lack of attention from me, and to think a little more... Now the mistake is the same as before, "Resource... not found". I saw several people complaining about it, but I did not find any solution, all say that the reason is because the compiler of Delphi does not find the file, but it opens the image using the example I gave in one of the previous answers.

  • You have to include the resource file in the same Unit where you are loading it. Whereas you are making calls from one form to another, make sure that the working example is not in another Unit.

  • I included the files by "Resources and images..." of "Project" (I was in the main form when I did it, but I think it works for any Project Form). Anyway, the error of "Resource... not found" happens both from the call of the main form, and from the secondary one. I created a test button in the main form to see the possibilities of solution (so far I could not get anything) and the call by the button gives the same error. Already put the direct command, without using your code, then the image is loaded.

  • I think to understand the problem I need to see the code. If this is not a problem, post here or send to [email protected].

  • Google won’t let you send the files, but I used the wetransfer service to send it to you. You should get a link in your email. It’s no problem to release the code here, but as it is full of comments and commands that I use for testing, it would be too much trouble to clear it before posting.

  • Nelson, the loop command is: "Timage(Findcomponent('Image' + Inttostr(j+1)).Picture.Bitmap.Loadfromresourcename(Hinstance, Find[j]);". Find[i] should have content like "Bitmap_5", for example, but the file that loads the Stringlist is populated with lines like: "Image5.Picture.Bitmap.Loadfromresourcename(Hinstance, 'Bitmap_5');". The commands should be in your program; the file should only have variable content that can be loaded as a string. Change the file, and test, let’s see if it works.

  • Yes, now he reads the image, but he presses the Timage in the order they appear and not the corresponding image. If in txt I have "Bitmap_5" and "Bitmap_6", for example, it should open in "Image5" and "Image6", but it is clicking on "Image1" and "Image2", respectively.

  • I thought that was the goal. It is not difficult to adapt, I will change the code of my answer above.

  • It is not difficult for those who know, rsrs. I am trying and do not leave the place. The Findcomponent option should already make this association, I cannot understand why it finds the image and does not associate to the corresponding Image.

  • It looks like it’s a little further now, but it hasn’t been... The error message is "There is no overloaded version of 'Pos' that can be called with These Arguments". I did not understand also that "10" which put in the second value of i ( i := Strtoint(copy(Find[j], i, 10));), what his job is?

  • If I ask to ignore (I only did it to test) the search line for '_', the program compiles, but gives error when loading the image, saying that it is not a valid integer value.

  • There is an "img : String;" in the variable that did not use tb, I tried to see where it would fit but it did not work anywhere...

  • I think I found the meaning of 10 in the expression, is how far the copy should be made... but nothing about the Pos error...

  • It was my mistake. The pos should be "Pos('_', Find[j]);", I will edit the reply. The copy command has 3 parameters, the string to copy, the position from which the copy starts, and the number of characters to copy. When we pass the 3rd parameter with more characters than there are in the available string for copying, the command returns only the available characters. Then, passing 10, in practice, the command copies the string from the next position to the underline until the end of the string. The problem is I’m doing it in my head, not compiling to check for errors.

  • I removed the variable img. Tinha colocado para fazer dois comandos que acabei concatenando: TImage(FindComponent(
 'Image' + IntToStr(i))).Picture.LoadFromFile(Achar[j]); -> poderia ser: 1) img := TImage(FindComponent(
 'Image' + IntToStr(i))); 2) img.Picture.LoadFromFile(Achar[j]);

  • I had already researched about the copy, I was using, but not really knowing what I was doing... Well, now it’s compiling, but it doesn’t load the images. The more the night I see well, because now I’m working and I can’t devote myself to it.

  • I found the solution, I was just changing the last call to (TImage(FindComponent('Image' + IntToStr(i))).Picture.Bitmap.LoadFromResourceName(HInstance, Achar[j]) ); I thank you very much for your patience, help and knowledge acquired. I will wait to edit your reply to give as Accept.

  • That’s right, in the rush I ended up forgetting about Resource, kkkk. Better yet you found.

Show 25 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.