Delphi 表单集合可见问题-一段时间后表单生成验证
我在Delphi5中创建的表单应用程序有问题。在这个应用程序中,我有几个按钮可以打开不同的窗体。此窗体作为父级具有面板。 只有一个函数被重写:Delphi 表单集合可见问题-一段时间后表单生成验证,delphi,forms,Delphi,Forms,我在Delphi5中创建的表单应用程序有问题。在这个应用程序中,我有几个按钮可以打开不同的窗体。此窗体作为父级具有面板。 只有一个函数被重写: procedure TForm.CreateParams(var Params : TCreateParams); begin inherited CreateParams(Params); with Params do begin Style := ws_Child; X :=FormMain.panelMain.Left;
procedure TForm.CreateParams(var Params : TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := ws_Child;
X :=FormMain.panelMain.Left;
Y :=FormMain.panelMain.Top;
Height :=FormMain.panelMain.Height;
Width := FormMain.panelMain.Height;
WndParent := FormMain.Handle;
end
end;
我还具有更改面板上实际形状的功能:
procedure TFormMain.ChangeToForm(newForm: TMainForm);
begin
if (newForm=nil) or (newForm=lastForm) then EXIT;
actForm:=newForm;
actForm.Visible :=true;
if assigned(lastForm) then lastForm.Visible:=false;
lastForm:=actForm;
LabelScreen.Caption:=actForm.Caption;
newForm.Left := 0;
newForm.Top := 0;
newForm.Width := panelMDI.Width;
newForm.Height := panelMDI.Height;
newForm.Left := panelMDI.Left;
newForm.Top := panelMDI.Top;
end;
当我打开应用程序时,一切正常。按钮改变形式。一切都好。
但当用户不使用此应用程序时,在一段时间内不要更改表单等。
单击按钮生成异常:
Access violation at address 0044D761 in module 'rozpoznawanie.exe'. Read of address 00000004; EAccessViolation
[...]
00534f2e jz loc_534fe9
00534f34 196 mov eax, [ebp-8]
00534f37 mov [$54b3a4], eax
00534f3c 197 mov dl, 1
00534f3e mov eax, [$54b3a4]
00534f43 > call -$9c194 ($498db4) ; Forms.TCustomForm.SetVisible
00534f48 198 cmp dword ptr [$54b3a8], 0
00534f4f jz loc_534f5d
00534f51 xor edx, edx
00534f53 mov eax, [$54b3a8]
00534f58 call -$9c1a9 ($498db4) ; Forms.TCustomForm.SetVisible
[...]
我到处都找过了,不知道为什么会出现。
你有什么想法吗
编辑
我发现问题可能出现在更早的时候:
00756bc8 vcl70.bpl Controls.TWinControl.HandleNeeded
00756bd5 vcl70.bpl Controls.TWinControl.GetHandle
0076e675 vcl70.bpl Forms.TCustomForm.GetMonitor
0076ecd0 vcl70.bpl Forms.TCustomForm.SetWindowToMonitor
0076daf1 vcl70.bpl Forms.TCustomForm.SetVisible
在SetWindowToMonitor中,我读到,如果在计算机上安装了多个监视器,有时会出现此问题。但我尝试更改DefaultMonitor属性,但这不起作用。我可能找到了解决问题的方法。我有Delphi5,没有更新包1。 我做了一些研究,发现正如我所说的,生产计算机上的Delphi函数TCustomForm.GetMonitor安装了一个真正的监视器和虚拟Radmin应用程序。 安装UP1后,问题消失。 我也可以自己改变功能:
function TCustomForm.GetMonitor: TMonitor;
var
HM: HMonitor;
I: Integer;
begin
Result := nil;
HM := MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST);
for I := 0 to Screen.MonitorCount - 1 do
if Screen.Monitors[I].Handle = HM then
begin
Result := Screen.Monitors[I];
Exit;
end;
//if we get here, the Monitors array has changed, so we need to clear and reinitialize it
for i := 0 to Screen.MonitorCount-1 do
TMonitor(Screen.FMonitors[i]).Free;
Screen.FMonitors.Clear;
EnumDisplayMonitors(0, nil, @EnumMonitorsProc, LongInt(Screen.FMonitors));
for I := 0 to Screen.MonitorCount - 1 do
if Screen.Monitors[I].Handle = HM then
begin
Result := Screen.Monitors[I];
Exit;
end;
end;
谢谢你的评论 此外,是:
Height :=FormMain.panelMain.Height;
Width := FormMain.panelMain.Height;
打字错误?其他用途
Height :=FormMain.panelMain.Height;
Width := FormMain.panelMain.Width;
你能提供更多关于这个例外的信息吗?至少,在这里复制异常文本。我忘了补充一下,这个应用程序仍然在工作,而且在实际的表单上一切都正常。我有错误:模块'rozpoznawanie.exe'中地址0044D761处的访问冲突。读取地址00000004;每一次违反。但我检查了所有表单,它们不是零。我认为问题在于您正在改变MDI表单作为父表单的方式,它们可能假设父表单是MDI父表单,并且可能将父表单强制转换为此类调用操作。MDI在工作方式上受到很大限制。如果您不使用提供的MDI,请实现一个替代方案,但不要尝试弯曲现有的MDI。我知道名称MDI的部分表明您是MDI表单,但这是普通表单-这只是名称。设置WndParent的目的是什么?当重新创建主窗体的窗口句柄时,TMDIForm是否强制重新创建其窗口句柄?如果不是,那可能是你的问题。