无法为记录类型指定左侧

时间:2015-10-12 07:14:14

标签: delphi

我正在尝试将我的应用程序从Delphi 2007升级到Delphi 10 Seattle。我知道记录需要在更改之前复制到本地变量,然后再分配回来。我正在尝试相同但我仍然得到我无法分配给左侧的错误。请有人帮忙。

procedure TMydlg.WMGetMinMaxInfo(var Msg:TMessage);
var
     MinMaxInfo: TMinMaxInfo;
begin
   inherited;
   MinMaxInfo := (PMinMaxInfo(Msg.LParam)^);

   with MinMaxInfo do
   begin

      ptMinTrackSize.X := MinWidth;
      ptMinTrackSize.Y := MinHeight;
      ptMaxTrackSize.X := MinWidth;

   end;

   // Error here. Left side cannot be assigned to
   (PMinMaxInfo(Msg.LParam)^) := MinMaxInfo;

TMinMaxInfo来自Winapi.windows

2 个答案:

答案 0 :(得分:9)

发出编译器错误,因为编译器拒绝最终赋值左侧的最外层parens。从本质上讲,您的代码类似于以下内容:

type
  TMyRecord = record
  end;

procedure Foo;
var
  rec1, rec2: TMyRecord;
begin
  rec1 := rec2;   // compiles
  (rec1) := rec2; // E2064 Left side cannot be assigned to
end;

以这种简化的方式编写它可以使问题得到非常明显的缓解。

我不确定为什么编译器拒绝这些parens。我怀疑语言的正式语法会使你的左手边无效。 Serg在注释中提供了合理的解释,即(...)是一个表达式,并且表达式无效作为赋值的左侧。我倾向于认为这是准确的。

无论如何,修复代码很简单。而不是

(PMinMaxInfo(Msg.LParam)^) := MinMaxInfo;

PMinMaxInfo(Msg.LParam)^ := MinMaxInfo;

请注意,无需复制记录,修改记录,然后将其复制回来。将LParam强制转换为指向记录的指针后,可以直接修改记录。

我会这样做:

procedure TMydlg.WMGetMinMaxInfo(var Msg:TMessage);
var
  pmmi: PMinMaxInfo;
begin
  inherited;
  pmmi := PMinMaxInfo(Msg.LParam);
  pmmi.ptMinTrackSize.X := MinWidth;
  pmmi.ptMinTrackSize.Y := MinHeight;
  pmmi.ptMaxTrackSize.X := MinWidth;
end;

我省略了^指针取消引用运算符,因为在这种情况下它是可选的。如果您愿意,可以写下这样的作业:

pmmi^.ptMinTrackSize.X := MinWidth;
pmmi^.ptMinTrackSize.Y := MinHeight;
pmmi^.ptMaxTrackSize.X := MinWidth;

答案 1 :(得分:-3)

这是因为你不使用Record类型而不是指针类型。

将您的代码更改为:

procedure TMydlg.WMGetMinMaxInfo(var Msg: TMessage);
begin
  with pMinMaxInfo(Msg.LParam)^ do
  begin    
    ptMinTrackSize.X := MinWidth;
    ptMinTrackSize.Y := MinHeight;
    ptMaxTrackSize.X := MinWidth;      
  end;
end;

我已经创建了一个虚拟测试程序:

procedure TForm9.FormCreate(Sender: TObject);
var
  MinMaxInfo: pMinMaxInfo;
  Msg: TMessage;
begin
  MinMaxInfo := new(pMinMaxInfo);
  Msg.LParam := integer(MinMaxInfo);
  WMGetMinMaxInfo(Msg);
  Assert( pMinMaxInfo(Msg.LParam)^.ptMinTrackSize.X = 10);
end;

procedure TForm9.WMGetMinMaxInfo(var Msg: TMessage);
var
  MinMaxInfo: pMinMaxInfo;
begin
  MinMaxInfo := pMinMaxInfo(Msg.LParam);

  with MinMaxInfo^ do
  begin

    ptMinTrackSize.X := 10;
    ptMinTrackSize.Y := 10;
    ptMaxTrackSize.X := 10;
  end;    
end;