Search code examples
delphidelphi-10.2-tokyo

Delphi cannot execute brcc32 via shellexecute


I have started writing components and I want to write a program to generate DCR files for me. The picture of a component must be a 24x24 bitmap, so I need to create a resource file and then use brcc32 to create the DCR.

Steps:

  1. Create a 24x24 bitmap (Paint, old but gold)
  2. Create the RC file
  3. Create the DCR using brcc32

So, I want to write a program to make all this stuff for me and this is the form. Inside the edit fields I have written their Name property.

image

This is the code:

unit uBmp2rc;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.IOUtils,
  Vcl.ExtDlgs, Vcl.ExtCtrls, ShellApi;

type
  TBitmapConverter = class(TForm)
    Label1: TLabel;
    edtClassName: TEdit;
    Label2: TLabel;
    edtSource: TEdit;
    Label3: TLabel;
    Label4: TLabel;
    edtDirectory: TEdit;
    OpenPicture: TOpenPictureDialog;
    Label5: TLabel;
    edtBitmap: TEdit;
    Button1: TButton;
    Button2: TButton;
    Label6: TLabel;
    Preview: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    path: string;
  public
    { Public declarations }
  end;

var
  BitmapConverter: TBitmapConverter;

implementation

{$R *.dfm}

procedure TBitmapConverter.Button1Click(Sender: TObject);
begin

 if OpenPicture.Execute then
  begin
   edtBitmap.Text := OpenPicture.FileName;
   Preview.Picture.LoadFromFile(OpenPicture.FileName);
  end;

end;

procedure TBitmapConverter.Button2Click(Sender: TObject);
var sw: TStreamWriter;
    tmpName, source, command: string;
begin

 path := edtDirectory.Text;
 source := edtSource.Text;

 tmpName := TPath.Combine(path, source+'.rc');
 Preview.Picture.SaveToFile(TPath.Combine(path, source + '.bmp'));

 sw := TStreamWriter.Create(tmpName, False, TEncoding.UTF8);
 try
  sw.Write(edtClassName.Text + ' BITMAP "' + source + '.bmp"');
 finally
  sw.Free;
 end;

 command := '/C brcc32 -fo"' + TPath.Combine(path, source) + '.dcr" "' + TPath.Combine(path, source) + '.rc"';
 ShellExecute(0, nil, PChar('cmd.exe'), PChar(command), nil, SW_HIDE);

end;

procedure TBitmapConverter.FormCreate(Sender: TObject);
begin
 edtDirectory.Text := TPath.GetDocumentsPath;
end;

I can correctly create the RC file, but the DCR is not being created. Am I doing something wrong in the command?

I have added the PChar() after Googling this and I have found the hint on StackOverflow, but still I'm not sure.


Solution

  • When I create the image for my components I use notepad and I save the file as filename.rc with the default encoding (ANSI, not UTF8). You are using UTF8 and you should change:

    sw := TStreamWriter.Create(tmpName, False, TEncoding.UTF8);
    

    with this:

    sw := TStreamWriter.Create(tmpName, False, TEncoding.ANSI);
    

    If you use the ANSI encoding your program will work. Your command is correct; if you try to run cmd.exe and call the brcc32 with those parameters you'll see that the UTF8 encoding gives you an error. Instead, the ANSI encoding works perfectly and you'll have yout *.drc file ready to use.

    See here something similar, it's about c++ builder but it shows that the problem is related to the UTF8 encoding.