1

是否可以将 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 的功能,还是我做错了什么?

4

1 回答 1

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()的调用,它需要一个窗口句柄(这反过来又要求控件是父级的)。

如果您在修改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()机制,因此在这种情况下无需调用该过程的本地副本。

于 2009-08-24T19:58:59.130 回答