当我访问使用 FindControl 找到的 TValueListEditor 时,为什么会出现访问冲突?
我在 TForm
上动态创建了 TValueListEditor
VCL 组件。该代码位于主窗体方法之一的嵌套过程中。我已经设置:
ValueListEditor.KeyOptions := [keyEdit, keyAdd, keyUnique];
它看起来像这样:
TMainForm.Method();
Method
有一个嵌套过程,其中包含创建上述组件的代码。
然后,我有辅助函数:
function GetMenuListData(XMLNode: TXMLNode; const XNMLDoc: string = '') : string;
在这个辅助函数中,我使用此代码加载 XML 文件,然后检索其节点并将它们插入到 ValueListEditor
中。
XMLDoc := TXMLDocument.Create(Self);
XMLDoc.ParseOptions := [poPreserveWhiteSpace];
try
XMLDoc.LoadFromFile(XNMLDoc);
try
Control := FindControl(FindWindow('TForm',PChar('(' + ExtractFileExt(Form1.Edit1.Text) + ')')));
if Control <> nil then
begin
TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1] := XMLDoc.DocumentElement.NodeName;
if XMLDoc.DocumentElement.ChildNodes.First.AttributeNodes.Count > 0 then
TValuelistEditor(Control).Values[TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1]] := String(XMLDoc.DocumentElement.Attributes['id'])
else
TValuelistEditor(Control).Values[TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1]] := '<Empty>';
end else begin
MessageBeep(0);
FlashWindow(Application.Handle, True);
ShowMessagePos('...');
end;
finally
XMLDoc.Active := False; Result := 'Forced ' + Form1.RAWInputBtn.Caption + ' in ' + DateTimeToStr(Now);
end;
except
on E : EXMLDocError do
begin
Result := 'Forced ' + Form1.RAWInputBtn.Caption + ' in ' + DateTimeToStr(Now);
end;
end;
问题是,每次代码进入该行时,我都会遇到访问冲突:
TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1] := XMLDoc.DocumentElement.NodeName;
我尝试了各种类型转换、值、参数......没有任何效果。
我的错误是什么?
我正在使用德尔福XE。
I have dynamically created TValueListEditor
VCL component on a TForm
. The code is located in nested procedure of one of the main form's methods. I have set:
ValueListEditor.KeyOptions := [keyEdit, keyAdd, keyUnique];
It looks like this:
TMainForm.Method();
Method
has a nested procedure that contains code that creates the components mentioned above.
Then, I have helper function:
function GetMenuListData(XMLNode: TXMLNode; const XNMLDoc: string = '') : string;
In this helper I use this code to load an XML file and then retrieve its nodes and insert them into ValueListEditor
.
XMLDoc := TXMLDocument.Create(Self);
XMLDoc.ParseOptions := [poPreserveWhiteSpace];
try
XMLDoc.LoadFromFile(XNMLDoc);
try
Control := FindControl(FindWindow('TForm',PChar('(' + ExtractFileExt(Form1.Edit1.Text) + ')')));
if Control <> nil then
begin
TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1] := XMLDoc.DocumentElement.NodeName;
if XMLDoc.DocumentElement.ChildNodes.First.AttributeNodes.Count > 0 then
TValuelistEditor(Control).Values[TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1]] := String(XMLDoc.DocumentElement.Attributes['id'])
else
TValuelistEditor(Control).Values[TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1]] := '<Empty>';
end else begin
MessageBeep(0);
FlashWindow(Application.Handle, True);
ShowMessagePos('...');
end;
finally
XMLDoc.Active := False; Result := 'Forced ' + Form1.RAWInputBtn.Caption + ' in ' + DateTimeToStr(Now);
end;
except
on E : EXMLDocError do
begin
Result := 'Forced ' + Form1.RAWInputBtn.Caption + ' in ' + DateTimeToStr(Now);
end;
end;
The problem is that I get access violations every time code goes into the line:
TValuelistEditor(Control).Keys[TValuelistEditor(Control).RowCount-1] := XMLDoc.DocumentElement.NodeName;
I have tried various typecasts, values, parameters .. nothing does the trick.
What is my mistake?
I'm using Delphi XE.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 Ken 评论的那样,你的问题是,你不是找到值列表编辑器,而是找到你的表单,然后将其类型转换为值列表编辑器,因此是 AV。
首先,您将“TForm”作为“lpClassName”传递给
FindWindow
。假设“TForm”是表单的类名,它当然会找到该表单 - 而不是其上的子窗口。其次,您不能使用FindWindow
来查找子窗口,请参阅其文档,它搜索顶级窗口。
如果您测试了
FindControl
的返回,则引发 AV 的代码将永远不会运行:您可以使用
FindWindowEx
在子窗口中搜索,如果您不知道表单查找的句柄首先,就像您已经完成的那样:或者更好的是,首先测试
FindWindowEx
的返回,以避免将“0”传递给FindControl
:As Ken commented your problem is, instead of finding the value list editor, you are finding your form and then typecasting it to a value list editor, hence the AV.
First, you're passing 'TForm' as 'lpClassName' to
FindWindow
. Assuming 'TForm' is the class name of your form, it will of course find the form - not a child window on it. Second, you cannot useFindWindow
to find a child window, see its documentation, it searches top-level windows.If you had tested the return of
FindControl
, the code raising the AV would never run:You can use
FindWindowEx
to search in child windows, if you don't know the handle of your form find it first as you've done already:or better yet, test the return of
FindWindowEx
first to avoid passing '0' toFindControl
:如果您动态创建的表单是同一应用程序的一部分,则您不需要错误
FindControl(FindWindow())
带来的所有噪音。只需创建您的表单,为其命名,然后将Application
设为所有者:当您想要获取对其的新引用时:
TheForm.MethodThatLoadsXML
现在可以访问TValueListEditor 直接:
If your dynamically created form is part of the same application, you don't need all the noise of the incorrect
FindControl(FindWindow())
. Just create your form, giving it a name, and makingApplication
the owner:When you want to get a new reference to it:
TheForm.MethodThatLoadsXML
can now access theTValueListEditor
directly: