control '' has no parent window 是怎么回事?(50分)

  • 主题发起人 主题发起人 fx
  • 开始时间 开始时间
F

fx

Unregistered / Unconfirmed
GUEST, unregistred user!
想继承TCombobox做一个新的控件TMyCombobox,
使之确省的Items中有DefaultString,
但运行时报如题的错误,代码如下:

constructor TMyCombobox.create (AOwner: TComponent);
begin
inherited Create(AOwner);
style:=csDropDownList;
items.Add (DeflautString);//此时出错
end;

请问原因,及如何修改可得到想要的效果?

 
好象应该在Loaded里面加出错的行.
 
检查了TCustomComboBox的源码, 其中Items是一个TComboBoxStrings类.
TComboBoxStrings的Add方法不是普通的TStringList的Add方法, 她是通过给
ComboBox窗体的handle发送消息实现添加字符串的:

SendMessage(ComboBox.Handle, CB_ADDSTRING, 0, Longint(PChar(S)));

因为你继承的ComboBox在Create阶段还没有Panent, 致使这个ComboBox还没有
Handle(一个TWinControl只有在Parent<>nil的时候才能够通过HandleNeeded方法
获得一个Handle), 因此不能给ComboBox窗口发消息.

你需要Override它的CreateHandle方法, 在新的CreateHandle的后面添加
DefaultString才行.

Good luck!!
 
huizhang:
多谢你的指教!问题已解决。
不过Override CreateHandle方法虽不报错,但不能达到要求的效果
(Items无DefalutString),我Override CreateWnd的方法才满足的要求。
能介绍一下CreateHandle,CreateWnd的区别吗?我看了Help还是不大懂:(
 
fx: >CreateHandle,CreateWnd的区别? 这个问题文的很好
我们先看一下TVomboBox的继承关系:
TComboBox<-TCustonComboBox<-TWinContro<-TControl<-TComponent<-...

TComponent -- 是我们常说的"控件", 他运行时是不可视的, 在设计时可见
TControl ---- 是运行的时候可见的, 有一个Parent属性, 本身不是一个窗体
TWinControl - 本身是一个窗体, 有一个Handle属性, 需要调用CreateWnd

TWinControl的Create(AOwner)方法是从TComponent.Create(AOwner)继承来的,
此时只是创建了一个TComponent, 直到给他一个Parent并且Visible的时候才调用
CreateHandle. CreateHandle中调用CreateWnd来创建窗体. CreateWnd调用API
函数来创建一个窗体, 同时给Handle赋值, 并注册这个窗体的类. 注册后, 窗体才
能够接收消息.

在你这个问题中, Override CreateHandle 或者 Override CreateWnd 应该没有
什么区别才对.
 
多谢会长指点。
 
接受答案了.
 
后退
顶部