是否可以将TDateTimePicker的字体设置为斜体?我在这段代码中做到了
var
DatEdit : TDateTimePicker;
begin
//I know Canvas is a stupid name for TPanel
DatEdit:=TDateTimePicker.Create(Canvas);
DatEdit.OnEnter := CtrlInputProc;
DatEdit.OnExit := CtrlExitProc;
DatEdit.Enabled := false;
DatEdit.Font.Style := DatEdit.Font.Style + [fsItalic]; //this line creates an exception
DatEdit.Parent := Canvas;
end;
每次代码执行最后一行时,都会抛出一个带有消息的EInvalidOperation异常:
„Control” has no parent window.
这是Delphi 5的功能,还是我做错了什么?
答案 0 :(得分:7)
是的,你做错了什么。 :)
基于窗口的控件的某些方面要求将控件放在其容器窗口上。这通常反映了底层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()需要一个窗口句柄(这又需要控件成为父级)。 / p>
如果您在修改字体之后绝对需要设置父 ,则可以从派生自己的控件类> 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;
请注意,调整高度()过程是从私有 TDateTimePicker 方法中复制的。如果您只是更改 Font.Style ,则可能不需要重现此代码并删除它并调用它,但如果您更改字体的其他属性那么这应该确保控件的大小正确。
当您致电继承时,会调用私有 AdjustHeight()机制,因此在这种情况下无需调用该过程的本地副本。