是的,你做错了什么。:)
基于窗口的控件的某些方面要求将控件放置在它的容器窗口上。这通常反映了底层 Window 类本身的一些要求(不是 VCL 类,而是代表控件的 MS Windows 窗口对象)。
在这种情况下,只需移动您对 Parent 属性的分配,以便在您尝试更改 Font.Style 之前发生它:
DatEdit.OnEnter := CtrlInputProc;
DatEdit.OnExit := CtrlExitProc;
DatEdit.Enabled := false;
DatEdit.Parent := Canvas;
DatEdit.Font.Style := DatEdit.Font.Style + [fsItalic];
我不知道字体是否可以通过这种方式成功设置为斜体,但这至少应该解决您的异常。
更新:我已经确认可以通过这种方式将字体设置为斜体,只要您首先设置了控件 Parent。(我使用的是 Delphi 2009,但如果它在 Delphi 5 中不起作用,我会感到惊讶)
仅供参考:我强烈建议为“Canvas”面板控件选择不同的名称。
附录:--------
它是CMFontChanged()消息处理程序中对InvalidateRect()的调用,它需要一个窗口句柄(这反过来又要求控件是父级的)。
如果您在修改Font后绝对需要能够设置Parent ,您可以从 TDateTimePicker派生您自己的控件类并实现对CMFontChanged()消息的响应,该消息抑制继承行为,除非控件是父控件:
type
TMyDateTimePicker = class(TDateTimePicker)
protected
procedure CMFontchanged(var Message: TMessage); message CM_FONTCHANGED;
end;
procedure TMyDateTimePicker.CMFontchanged(var Message: TMessage);
procedure AdjustHeight;
var
DC: HDC;
SaveFont: HFont;
SysMetrics, Metrics: TTextMetric;
begin
DC := GetDC(0);
try
GetTextMetrics(DC, SysMetrics);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
finally
ReleaseDC(0, DC);
end;
Height := Metrics.tmHeight + (GetSystemMetrics(SM_CYBORDER) * 8);
end;
begin
if HasParent then
inherited
else
AdjustHeight;
end;
请注意,AdjustHeight()过程是从TDateTimePicker的私有方法复制而来的。如果您只更改Font.Style,您可能不需要重现此代码并且可以删除它和对它的调用,但是如果您更改Font的其他属性,那么这应该确保控件的大小正确。
当您调用继承时,将调用私有AdjustHeight()机制,因此在这种情况下无需调用该过程的本地副本。