CreateHandle CreateParams CreateWnd什么功能,什么时候被调用。 (50分)

  • 主题发起人 主题发起人 Shepherd
  • 开始时间 开始时间
S

Shepherd

Unregistered / Unconfirmed
GUEST, unregistred user!
CreateHandle CreateParams CreateWnd什么功能,什么时候被调用。
 
窗口的创建过程中用到了CreateHandle CreateParams CreateWnd,具体过程如下:

1、TCustomForm.Create
在 TCustomForm.Create 中调用 TCustomForm.CreateNew;

2、TCustomForm.CreateNew;
调用 FCanvas := TControlCanvas.Create;
触发 TControlCanvas.Create;
触发 TControlCanvas.CreateHandle;

3、TControlCanvas.CreateHandle;
调用 FControl.GetDeviceContext(FWindowHandle);
即 TWinControl.GetDeviceContext(FWindowHandle);

4、TWinControl.GetDeviceContext(FWindowHandle);
调用 TWinControl.GetDC(Handle);

此处说明一下:
对 TWinControl 的 Handle 属性的读取会触发 TWinControl.GetHandle;
可以察看 Property Handle; 的声明。

5、第四步中对 Handle 进行读取,触发下述序列:(TWinControl)
Handle->GetHandle->HandleNeeded

6、TWinControl.HandleNeeded 检查 FHandle 的值:
if FHandle = 0 then
begin
if Parent <> nil then Parent.HandleNeeded;
CreateHandle; // 调用 CreateHandle;
end;

7、TWinControl.CreateHandle
调用 CreateWnd;
if FHandle = 0 then // 此时 FHandle 仍然为零
begin
CreateWnd;
...
end;

8、TWinControl.CreateWnd
调用 CreateParams(Params);
// 让用户有机会加入新的特征参数
CreateParams(Params);
with Params do
begin
...
// 标准的 API 使用,注册窗口类,CreateWindowEx ...
if Windows.RegisterClass(WindowClass) = 0 then RaiseLastWin32Error;
...
CreateWindowHandle(Params);
...
end;

9、CreateWindowHandle(Params);
FHandle := CreateWindowEx(ExStyle, WinClassName, Caption, Style,
X, Y, Width, Height, WndParent, 0, WindowClass.hInstance, Param);
完成真正的窗口创建,并赋予 FHandle 窗口句柄。

10、回到第一步
CreateNew 之后调用 DoCreate
try
CreateNew(AOwner);
...
if OldCreateOrder then DoCreate;
finally
...
end;

11、DoCreate
调用用户的 OnCreate 事件:
if Assigned(FOnCreate) then
try
FOnCreate(Self); // 调用 OnCreate;
except
Application.HandleException(Self);
end;
if fsVisible in FFormState then Visible := True;

补充一点:
其他的控件比如 TEdit 等都是 TWinControl 的子孙,构造的顺序都差不多,
关键的一点是:

对 TWinControl.Handle 属性的第一次访问会触发对窗口句柄的真正创建。

即:Handle->GetHandle->HandleNeeded

关于这一点,可以察看 Delphi Help->HandleAllocated 方法的注解。

上文只是剖析了 TForm 的构造过程,其它类似控件可能有所差别,其它控件并不
一定是在构造 TControlCanvas 时才第一次访问 TWinControl.Handle 的,也许
是在其他地方,不过没有必要都写出来。

From: BaKuBaKu大侠
 
这里只有他们之间的调用顺序,但每一步都是些什么功能并没有说清楚阿
 
请发一份给我
 
接受答案了.
 
后退
顶部