Home Left side cannot be assigned for a record type
Reply: 2

Left side cannot be assigned for a record type

Jack Gray
1#
Jack Gray Published in 2015-10-12 07:14:13Z

I am trying to upgrade my application from Delphi 2007 to Delphi 10 Seattle. I understand that a record needs to be copied to a local variable before changing and then assigned back. I am trying the same but I still get the error that I cannot assign to a left side. Could someone please help.

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 is from Winapi.windows

Jens Borrisholt
2#
Jens Borrisholt Reply to 2015-10-12 07:37:52Z

It is because you do not use a Record type and not a pointer type.

Change your code to this:

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

I've created a dummy test program:

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;
David Heffernan
3#
David Heffernan Reply to 2015-10-12 17:15:37Z

The compiler error is emitted because the compiler rejects the outermost parens on the left hand side of the final assignment. In essence, your code is akin to the following:

type
  TMyRecord = record
  end;

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

Writing it in this simplified manner brings the issue into very sharp relief.

I'm not sure why the compiler rejects these parens. I suspect that the formal grammar of the language renders your left hand side invalid. Serg provides a plausible explanation in the comments, that is that (...) is an expression, and an expression is not valid as the left hand side of an assignment. I'm inclined to believe that is accurate.

Anyway, it is simple to fix your code. Instead of

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

write

PMinMaxInfo(Msg.LParam)^ := MinMaxInfo;

Note that it is not necessary to make a copy of the record, modify it, and then copy it back. You can modify the record directly, once you have cast LParam to a pointer to the record.

I would do so like this:

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;

I've omitted the ^ pointer dereference operator since it is optional in this scenario. If you prefer you might write the assignments like this:

pmmi^.ptMinTrackSize.X := MinWidth;
pmmi^.ptMinTrackSize.Y := MinHeight;
pmmi^.ptMaxTrackSize.X := MinWidth;
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.323858 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO