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