0

メッセージを表示する簡単なOpendialog、Edit1を作成しました

関数が返される理由がわかりません:

[DCC Error] Unit1.pas(112): E2010 Incompatible types: 'string' and 'tagSIZE'

完全なコードは次のとおりです。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Types, ExtDlgs;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
//      procedure GetGIFSize(const sGIFFile: string; var wWidth, wHeight: Word);

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function GetGIFSize(const FileName: string): Windows.TSize;
type
  // GIF header record
  TGIFHeader = packed record
    Sig: array[0..5] of AnsiChar;     // signature bytes
    ScreenWidth, ScreenHeight: Word;  // logical screen width and height
    Flags: Byte;                      // various flags
    Background: Byte;                 // background colour index
    Aspect: Byte;                     // pixel aspect ratio
  end;
  // GIF image block header record
  TGIFImageBlock = packed record
    Left, Top: Word;      // image top left
    Width, Height: Word;  // image dimensions
    Flags: Byte;          // flags and local colour table size
  end;
const
  cSignature: PAnsiChar = 'GIF';  // gif image signature
  cImageSep = $2C;                // image separator byte
var
  FS: Classes.TFileStream;      // stream onto gif file
  Header: TGIFHeader;           // gif header record
  ImageBlock: TGIFImageBlock;   // gif image block record
  BytesRead: Integer;           // bytes read in a block read
  Offset: Integer;              // file offset to seek to
  B: Byte;                      // a byte read from gif file
  DimensionsFound: Boolean;     // flag true if gif dimensions have been read
begin
  Result.cx := 0;
  Result.cy := 0;
  if (FileName = '') or not SysUtils.FileExists(FileName) then
    Exit;
  FS := Classes.TFileStream.Create(
    FileName, SysUtils.fmOpenRead or SysUtils.fmShareDenyNone
  );
  try
    // Check signature
    BytesRead := FS.Read(Header, SizeOf(Header));
    if (BytesRead <> SizeOf(TGIFHeader)) or
      (SysUtils.StrLComp(cSignature, Header.Sig, 3) <> 0) then
      // Invalid file format
      Exit;
    // Skip colour map, if there is one
    if (Header.Flags and $80) > 0 then
    begin
      Offset := 3 * (1 shl ((Header.Flags and 7) + 1));
      if Offset >= FS.Size then
        Exit;
      FS.Seek(Offset, Classes.soFromBeginning);
    end;
    DimensionsFound := False;
    FillChar(ImageBlock, SizeOf(TGIFImageBlock), #0);
    // Step through blocks
    FS.Read(B, SizeOf(B));
    while (FS.Position < FS.Size) and (not DimensionsFound) do
    begin
      if B = cImageSep then
      begin
        // We have an image block: read dimensions from it
        BytesRead := FS.Read(ImageBlock, SizeOf(ImageBlock));
        if BytesRead <> SizeOf(TGIFImageBlock) then
          // Invalid image block encountered
          Exit;
        Result.cx := ImageBlock.Width;
        Result.cy := ImageBlock.Height;
        DimensionsFound := True;
      end;
      FS.Read(B, SizeOf(B));
    end;
  finally
    FS.Free;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
begin
    Size := GetGIFSize('file.gif');
    ShowMessage(Size);
  end;
end.

私は簡単に使用します:

GetGIFSize(パス/to/ファイル名);

しかし、ファイル名は文字列です。なぜ機能しないのか分かりますか?

4

2 に答える 2

3

問題はあなたのTForm1.ButtonClickイベントにあり、ShowMessage呼び出しがあります。ShowMessageは文字列パラメーター (表示するメッセージ) を受け取り、代わりにそれを渡していますWindows.TSize

TSizeで使用するには、レコードを文字列に変換する必要がありShowMessageます。ATSizeには、 で表される幅と で表されるTSize.cx高さの 2 つの次元TSize.cyがあるため、これらの次元を表示可能な文字列表現に変換する必要があります。

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
const
  SizeDisplayMsg = 'Size - width (cx): %d height (cy): %d';
begin
    Size := GetGIFSize('file.gif');
    ShowMessage(Format(SizeDisplayMsg, [Size.cx, Size.cy]));
end;

もちろん、 を使用しTOpenFileDialogてファイル名を取得したい場合は、代わりにそれを使用する必要があります。

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
const
  SizeDisplayMsg = 'Size - width (cx): %d height (cy): %d';
begin
  if OpenDialog1.Execute(Handle) then
  begin
    Size := GetGIFSize(OpenDialog1.FileName);
    ShowMessage(Format(SizeDisplayMsg, [Size.cx, Size.cy]));
  end;
end;
于 2013-05-11T00:49:59.687 に答える
2

ShowMessageプロシージャは唯一のパラメータ タイプの値として受け取りますが、そこにレコードstringを渡そうとしました。Windows.TSizeこれが、コンパイラがそのようなメッセージでコンパイルを拒否した理由です。さらに、Windows.TSizeレコード タイプは 2 つのフィールドから構成されます。fromcxとwhere はそれぞれ数値型であるため、それらを個別cyに渡す必要がある場合を除いて、それらの値をプロシージャに渡す前に文字列に変換する必要があります。たとえば、次のように、さまざまな方法で実行できます。ShowMessage

1. Format 関数を使用する (推奨される方法)

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
begin
  Size := GetGIFSize('c:\File.gif');
  ShowMessage(Format('Width: %d; Height: %d', [Size.cx, Size.cy]));
end;

2. 文字列の手動連結 (読みにくい)

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
begin
  Size := GetGIFSize('c:\File.gif');
  ShowMessage('Width: ' + IntToStr(Size.cx) + '; Height: ' + IntToStr(Size.cy));
end;
于 2013-05-11T00:14:06.010 に答える