Delphi 2007-在输入时将TDateTimePicker的焦点设置为秒

Delphi 2007-在输入时将TDateTimePicker的焦点设置为秒,delphi,focus,datetimepicker,delphi-2007,Delphi,Focus,Datetimepicker,Delphi 2007,当控件第一次接收到焦点时,是否有任何方法可以显式地将TDateTimePicker(设置为时间选择器)的焦点设置为“秒”字段?默认值似乎是“小时”字段。当您在控件之间进行制表时,该控件似乎记得H、M、S中的哪一个具有焦点,这没关系,但我希望能够在第一次显示与该控件的对话框时将焦点显式设置为秒字段 建议切换格式(将焦点初始化为“小时”字段),然后我可以发送两条光标右键消息移动到“秒”字段,但我希望希思·罗宾逊(Heath Robinson)能做得少一点。没有直接的方法,但如果包含以下代码,您可以在

当控件第一次接收到焦点时,是否有任何方法可以显式地将TDateTimePicker(设置为时间选择器)的焦点设置为“秒”字段?默认值似乎是“小时”字段。当您在控件之间进行制表时,该控件似乎记得H、M、S中的哪一个具有焦点,这没关系,但我希望能够在第一次显示与该控件的对话框时将焦点显式设置为秒字段


建议切换格式(将焦点初始化为“小时”字段),然后我可以发送两条光标右键消息移动到“秒”字段,但我希望希思·罗宾逊(Heath Robinson)能做得少一点。

没有直接的方法,但如果包含以下代码,您可以在TDateTimePicker控件中操纵焦点的位置:

{$IF CompilerVersion >= 17 }
{$DEFINE D2005UP }
{$ELSE }
{$UNDEF D2005UP }
{$ENDIF }

{$IF CompilerVersion >= 20 }
{$DEFINE D2009UP }
{$ELSE }
{$UNDEF D2009UP }
{$ENDIF }

PROCEDURE SendKeys(CONST Keys : ARRAY OF WORD);
  VAR
    {$IFDEF D2009UP }
    InputEvents : TArray<TInput>;
    {$ELSE }
    InputEvents : ARRAY OF TInput;
    {$ENDIF }
    {$IFNDEF D2005UP }
    I           : INTEGER;
    {$ENDIF }
    Key         : WORD;

  PROCEDURE Add(Key : WORD ; Action : WORD = 0);
    VAR
      INP       : TInput;

    BEGIN
      FillChar(INP,SizeOf(TInput),0);
      INP.Itype:=INPUT_KEYBOARD;
      INP.ki.wVk:=Key;
      INP.ki.wScan:=0;
      INP.ki.dwFlags:=Action;
      INP.ki.time:=0;
      INP.ki.dwExtraInfo:=0;
      {$IFDEF D2009UP }
        InputEvents:=InputEvents+[INP]
      {$ELSE }
        SetLength(InputEvents,SUCC(LENGTH(InputEvents)));
        InputEvents[HIGH(InputEvents)]:=INP
      {$ENDIF }
    END;

  PROCEDURE AddKeyDown(Key : WORD);
    BEGIN
      Add(Key)
    END;

  PROCEDURE AddKeyUp(Key : WORD);
    BEGIN
      Add(Key,KEYEVENTF_KEYUP)
    END;

  PROCEDURE AddKeyPress(Key : WORD);
    BEGIN
      AddKeyDown(Key);
      AddKeyUp(Key)
    END;

  BEGIN
    IF LENGTH(Keys)=0 THEN EXIT;
    {$IFDEF D2005UP }
      FOR Key IN Keys DO AddKeyPress(Key);
    {$ELSE }
      FOR I:=LOW(Keys) TO HIGH(Keys) DO BEGIN
        Key:=Keys[I];
        AddKeyPress(Key)
      END;
    {$ENDIF }
    SendInput(LENGTH(InputEvents),InputEvents[LOW(InputEvents)],SizeOf(TInput));
    Application.ProcessMessages
  end;

PROCEDURE SetDateTimePickerFocus(DTP : TDateTimePicker ; FocusTo : CHAR);
  VAR
    S   : STRING;

  BEGIN
    DTP.SetFocus;
    Application.ProcessMessages;
    S:=DTP.Format; DTP.Format:='HH';
    Application.ProcessMessages;
    DTP.Format:=S;
    Application.ProcessMessages;
    CASE UpCase(FocusTo) OF
      'H' : ; // NOTHING //
      'M' : SendKeys([VK_RIGHT]);
      'S' : SendKeys([VK_RIGHT,VK_RIGHT])
    ELSE // OTHERWISE //
      RAISE ERangeError.Create('Unsupported FocusTo value in SetDateTimePickerFocus: "'+FocusTo+'"')
    END
  END;

{$IFDEF D2005UP }
TYPE
  TDateTimePickerHelper = CLASS HELPER FOR TDateTimePicker
                            PROCEDURE   SetFocusTo(C : CHAR);
                          END;

{ TDateTimePickerHelper }

PROCEDURE TDateTimePickerHelper.SetFocusTo(C : CHAR);
  BEGIN
    SetDateTimePickerFocus(Self,C)
  END;
{$ENDIF }
用法(Delphi 2005+):


没有直接的方法可以做到这一点,但如果包含以下代码,则可以在TDateTimePicker控件中操纵焦点的位置:

{$IF CompilerVersion >= 17 }
{$DEFINE D2005UP }
{$ELSE }
{$UNDEF D2005UP }
{$ENDIF }

{$IF CompilerVersion >= 20 }
{$DEFINE D2009UP }
{$ELSE }
{$UNDEF D2009UP }
{$ENDIF }

PROCEDURE SendKeys(CONST Keys : ARRAY OF WORD);
  VAR
    {$IFDEF D2009UP }
    InputEvents : TArray<TInput>;
    {$ELSE }
    InputEvents : ARRAY OF TInput;
    {$ENDIF }
    {$IFNDEF D2005UP }
    I           : INTEGER;
    {$ENDIF }
    Key         : WORD;

  PROCEDURE Add(Key : WORD ; Action : WORD = 0);
    VAR
      INP       : TInput;

    BEGIN
      FillChar(INP,SizeOf(TInput),0);
      INP.Itype:=INPUT_KEYBOARD;
      INP.ki.wVk:=Key;
      INP.ki.wScan:=0;
      INP.ki.dwFlags:=Action;
      INP.ki.time:=0;
      INP.ki.dwExtraInfo:=0;
      {$IFDEF D2009UP }
        InputEvents:=InputEvents+[INP]
      {$ELSE }
        SetLength(InputEvents,SUCC(LENGTH(InputEvents)));
        InputEvents[HIGH(InputEvents)]:=INP
      {$ENDIF }
    END;

  PROCEDURE AddKeyDown(Key : WORD);
    BEGIN
      Add(Key)
    END;

  PROCEDURE AddKeyUp(Key : WORD);
    BEGIN
      Add(Key,KEYEVENTF_KEYUP)
    END;

  PROCEDURE AddKeyPress(Key : WORD);
    BEGIN
      AddKeyDown(Key);
      AddKeyUp(Key)
    END;

  BEGIN
    IF LENGTH(Keys)=0 THEN EXIT;
    {$IFDEF D2005UP }
      FOR Key IN Keys DO AddKeyPress(Key);
    {$ELSE }
      FOR I:=LOW(Keys) TO HIGH(Keys) DO BEGIN
        Key:=Keys[I];
        AddKeyPress(Key)
      END;
    {$ENDIF }
    SendInput(LENGTH(InputEvents),InputEvents[LOW(InputEvents)],SizeOf(TInput));
    Application.ProcessMessages
  end;

PROCEDURE SetDateTimePickerFocus(DTP : TDateTimePicker ; FocusTo : CHAR);
  VAR
    S   : STRING;

  BEGIN
    DTP.SetFocus;
    Application.ProcessMessages;
    S:=DTP.Format; DTP.Format:='HH';
    Application.ProcessMessages;
    DTP.Format:=S;
    Application.ProcessMessages;
    CASE UpCase(FocusTo) OF
      'H' : ; // NOTHING //
      'M' : SendKeys([VK_RIGHT]);
      'S' : SendKeys([VK_RIGHT,VK_RIGHT])
    ELSE // OTHERWISE //
      RAISE ERangeError.Create('Unsupported FocusTo value in SetDateTimePickerFocus: "'+FocusTo+'"')
    END
  END;

{$IFDEF D2005UP }
TYPE
  TDateTimePickerHelper = CLASS HELPER FOR TDateTimePicker
                            PROCEDURE   SetFocusTo(C : CHAR);
                          END;

{ TDateTimePickerHelper }

PROCEDURE TDateTimePickerHelper.SetFocusTo(C : CHAR);
  BEGIN
    SetDateTimePickerFocus(Self,C)
  END;
{$ENDIF }
用法(Delphi 2005+):


根据,没有可以发送给控件以选择特定字段的消息,这通常意味着没有直接的方法。根据,没有可以发送给控件以选择特定字段的消息,这通常意味着没有直接的方法。为什么需要
Application.ProcessMessages
?我的经验告诉我,在大多数情况下,如果您更改属性并希望确保其生效,则需要允许Windows查看您的更改。在本例中,我没有专门测试它,但在许多其他情况下,我发现如果在某些点忽略ProcessMessages,我下面的代码就不会像预期的那样工作,因为它基于上一个操作已经完全完成的假设(没有ProcessMessages,它就没有)。我可以向您保证
应用程序。不需要ProcessMessages
。您可以在DTP上调用
recreatWnd
,将焦点重置为小时字段,而不是
格式
技巧。为什么需要
应用程序。ProcessMessages
?我的经验告诉我,在大多数情况下,如果您更改属性并希望确保其生效,则需要允许Windows查看您的更改。在本例中,我没有专门测试它,但在许多其他情况下,我发现如果在某些点忽略ProcessMessages,我下面的代码就不会像预期的那样工作,因为它基于上一个操作已经完全完成的假设(没有ProcessMessages,它就没有)。我可以向您保证
应用程序。不需要ProcessMessages
。您可以在DTP上调用
recreatWnd
,将焦点重置为小时字段,而不是
Format
技巧。
DateTimePicker1.SetFocusTo('S'); // 'H', 'M' or 'S' to select field