【问题标题】:Left side cannot be assigned for a record type无法为记录类型分配左侧
【发布时间】:2015-10-12 07:14:13
【问题描述】:

我正在尝试将我的应用程序从 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

【问题讨论】:

  • 去掉PMinMaxInfo(Msg.LParam)^周围的括号'('和')'

标签: delphi


【解决方案1】:

编译器错误是因为编译器拒绝了最终赋值左侧的最外层括号。本质上,您的代码类似于以下内容:

type
  TMyRecord = record
  end;

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

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

我不确定为什么编译器会拒绝这些括号。我怀疑该语言的形式语法会使您的左侧无效。 Serg 在 cmets 中提供了一个似是而非的解释,即 (...) 是一个表达式,而表达式作为赋值的左侧是无效的。我倾向于相信这是准确的。

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

(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;

【讨论】:

  • 我不认为这是一个编译器错误;括号中的变量是一个表达式,并且表达式不能位于赋值的左侧。它不特定于记录类型。
  • @user246408:是的,我就是这么想的。 “不是 LVal”是表达式 IIRC。
【解决方案2】:

这是因为你没有使用 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;

【讨论】:

  • 这是因为你没有使用 Record 类型而不是指针类型。不,不是这样。
  • 也许你应该仔细阅读我的回答,看看我没有抄袭你写的东西。
  • 编写代码的方法并不多。此外,在您进行编辑之前,我开始写我的答案。回到你仍然有一个本质上的任务时:ptr^ := ptr^。有趣的是理解编译器错误,你错过了。所以是的,我认为我可以写下我的答案。
  • @DavidHeffernan 我真的很喜欢阅读你的答案,因为你花时间不仅回答了被问到的问题,而且还解释了在各种情况下发生的事情,对我来说,我从像你这样的答案中学到了很多,因为它有助于更​​好地了解实际问题是什么以及可以采取哪些方法来解决这些问题。
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
相关资源
最近更新 更多