TDateTimePickerのドロップダウンとクローズについて2

解決


うさこ  2003-10-29 03:05:59  No: 5469

こんにちは。
いつも参考にさせていただいております。

以前に「TDateTimePickerのドロップとクローズについて」という事で
下記の動作の実現方法をご質問をさせて頂き、以下のサンプルコードをご教授頂きました。

①TDateTimePickerにフォーカスセットでカレンダーをドロップダウン
②そのまま変更せずにENTER押下で、カレンダーをクローズし次のコントロールにフォーカス

procedure TForm1.DateTimePicker1Enter(Sender: TObject);
begin
   keybd_event(VK_LMENU, 0, 0, 0);
   keybd_event(VK_DOWN, 0, 0, 0);
   keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
   keybd_event(VK_LMENU, 0, KEYEVENTF_KEYUP, 0);
end;

procedure TForm1.DateTimePicker1CloseUp(Sender: TObject);
begin
   //フォーカス移動処理
end;

上記で私の望んでいました①②は実現出来たのですが、カレンダーが
ドロップダウンした状態でマウスで画面にあるボタンをClickすると、
複数連続しているDateTimePickerが次々とドロップダウンとクローズを
繰り返します。

OnCloseUpイベントにファーカス移動処理を書いているので当然なのですが、
このような動作を回避する手段はないものでしょうか?
どうかご教授下さいませ。

Delphi7を使っています。


Halbow  2003-10-29 04:15:53  No: 5470

Halbow です。

> ②そのまま変更せずにENTER押下で、カレンダーをクローズし次のコントロールにフォーカス

これをいかのようにしたらよいと思います。

procedure TForm1.DateTimePicker1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
    //フォーカス移動処理
end;


うさこ  2003-10-29 23:29:29  No: 5471

Halbowさんありがとうございます。

早速試してみましたところ、一つ目のDateTimePickerにフォーカスが
移動した際に、一つ目と二つ目のDateTimePicker
が同時にドロップダウンされました。
フォーカスも二つ目に移動しています。
もう一度ENTER押下で、二つ目がクローズ、
三つ目がドロップダウンされ、一つ目はドロップダウン
されたままです。

どうやら、一つ目にはFormKeyPressでENTER押下時に行っている
フォーカス移動処理で移動し、DateTimePickerのKeyUpイベントで
さらにフォーカスが移動しているようです。

フォーカス移動処理は、
if Key = char(VK_RETURN) then
begin
   FindNextControl(Form1.ActiveControl, True, True, False).SetFocus;
end;
で行っています。

もう一息という感じで、色々試しているのですが、
もしよい情報をお持ちの方がいらしゃいましたら、ご教授ください。
宜しくお願います。


Halbow  2003-10-31 04:23:35  No: 5472

Halbow です。

> どうやら、一つ目にはFormKeyPressでENTER押下時に行っている
> フォーカス移動処理で移動し、DateTimePickerのKeyUpイベントで
> さらにフォーカスが移動しているようです。

フォーカスの移動のコードがあちこちにあって、それを全部知らないと
これ以上のアドバイスはできないと思います。


うさこ  2003-10-31 19:25:44  No: 5473

度々ありがとうございます。

>フォーカスの移動のコードがあちこちにあって、それを全部知らないと
>これ以上のアドバイスはできないと思います。

ごもっともでございます。
フォーカス移動は、元々「FormKeyPressでENTER押下時のみ」です。
しかしこれだけでは、
  ENTER押下 1回目  DateTimePickerがフォーカス取得、ドロップダウン
  ENTER押下 2回目  DateTimePickerがフォーカスのまま、クローズ 
  ENTER押下 3回目  フォーカス移動
という動作になり、「ENTER押下でカレンダーをクローズし、次のコントロールにフォーカス」が実現出来なくて困っておりました。
そこで、アドバイス頂いたOnCloseUpイベントやOnKeyUpイベントにフォーカス移動処理を追加した、というのがこれまでの経緯です。

現在は「FormKeyPressでENTER押下時のみ」と「OnKeyUpイベントでENTER押下時のみ」の2箇所にフォーカス移動処理が入っています。

カレンダーがドロップダウンされている状態でENTER押下時に、FormKeyPressイベントが発生すれば問題ないのですが、そうもいかないようなのです。
何か情報を頂けないでしょうか。


masayan  2003-10-31 21:34:40  No: 5474

回答というわけではありませんが、キー入力関連のイベントについて...

OnKeyPressイベントは、キーが押されかではなく文字が入力されたときに呼び出されます。厳密な意味でキーが押されたときに処理をしたければOnKeyDownイベントかOnKeyUpイベントを使うのが正解です。
通常、何かキーが押されると...
  OnKeyDown(キーが押された)
    ↓
  OnKeyPress(文字入力)
    ↓
  OnKeyUp(キーを離された)
の順番に発生します。
ただし、押されたキーが文字キー以外またはコントロールが文字入力を受け付けないような場合、OnKeyPressは発生しません。
だから、TDateTimePickerのドロップダウン中にENTERキーを押してもOnKeyPressは発生しないし、OnKeyPressやOnKeyDownで強制的にフォーカス移動する場合など、続いて発生するOnKeyPress,OnKeyUpのことを考えてないと予想外の動作をするわけです。

よって、単純にTDateTimePickerの...
・OnEnterでカレンダーのドロップダウン
・OnKeyUpでENTERキーでフォーカス移動
とすればうまく行くと思いますよ。


うさこ  2003-10-31 23:34:03  No: 5475

masayanさん、ありがとうございます。
キー入力関連のイベントについて理解が深まりましたっ。

今回は正に
>予想外の動作をするわけです。
な訳です・・・

「OnKeyUpでENTERキーでフォーカス移動」によって、
TDateTimePickerからTDateTimePickerへの移動は問題なく行えています。
ただ、一つ目のTDateTimePickerへENTER押下でフォーカスが来た時だけ、
OnKeyUpイベントが2回走り、予想外な動作になっています。

TDateTimePickerにフォーカスが来た時に、カレンダーがドロップダウン
しているかどうかが判断出来れば、制御が出来そうに思うのですが、
そんな事は出来るのでしょうか?
(ヘルプで調べようとするもですが、英語しかないです・・・)


masayan  2003-10-31 23:54:26  No: 5476

TDateTimePickerにDroppedDownというのがありますのでこれで判断できると思いますよ。
DroppedDownは、ドロップダウン中であればTrueを返します。(←ちなみに読み取り専用プロパティです。)


うさこ  2003-11-05 01:04:25  No: 5477

Halbowさん、masayanさんありがとう御座いました。
下記のように、ドロップダウンしている時はフォーカス移動処理は行わないように
する事で、上手くいっているようです。

度々のアドバイスありがとうございました。

procedure TForm1.procDtpKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   if Key = VK_RETURN then
   begin
      if TDateTimePicker(Sender).DroppedDown = true then  
      begin
         exit;
      end;

      //フォーカス移動処理
   end;
end;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加