CommandButtonのKeyEventが発生しない

解決


はっしー  2010-09-22 21:26:23  No: 102571  IP: [192.*.*.*]

VB6.0で以下のような制御をしていますが、うまく動作しない端末があり
原因がわからない状態となっています。

【環境】
・VB6.0 SP6
・OS:Window XP Professional 2002 SP3

【現象】
タブインデックスの順序を
1.テキストボックス
2.コマンドボタン
3.テキストボックス
とし、

A)1.のテキストボックスでEnterを押したときに
2.のコマンドボタンでのKeyEventでKeyCodeを判断し、3に遷移

B)3.のテキストボックスで↑等で2.のコマンドボタンに移動したときは、2.のコマンドボタンのKeyEventでKeyCodeを判断し、1.に遷移

私の端末(上記の環境と同様)では制御がうまくいっているのですが、
お客さんの端末ではKeyEventが発生せずコマンドボタンで止まってしまいます。
もし分かる方がおりましたらご教授願います。
宜しくお願い致します。

編集 削除
魔界の仮面弁士  2010-09-23 07:48:50  No: 102572  IP: [192.*.*.*]

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1047467510

> A)1.のテキストボックスでEnterを押したときに
> 2.のコマンドボタンでのKeyEventでKeyCodeを判断し、3に遷移

Text1 で押されたキーを、Command1 で判断して、Text2 に SetFocus…?
KeyEvent というのは、KeyPress/KeyDown/KeyUp の事でしょうか?
(KeyCode ということは、KeyPress では無さそうですが)


コードが無いので話がよく見えていないのですが、そもそも、
ボタンでそれらのイベントを制御すること自体がレアケースだと思います。
Enter でボタンが押されたことにするなら、CommandButton の Default プロパティで、
フォーム既定のデフォルトボタンとして働かせるでしょうし、
キー操作を統一的に検証するなら、KeyPreview な Form 側にて
判定させる事が多い気がします。


> B)3.のテキストボックスで↑等で2.のコマンドボタンに移動したときは、
> 2.のコマンドボタンのKeyEventでKeyCodeを判断し、1.に遷移
キー操作以外でフォーカス移動した場合は?


> 私の端末(上記の環境と同様)では制御がうまくいっているのですが、
> お客さんの端末ではKeyEventが発生せずコマンドボタンで止まってしまいます。
VB6 に、KeyEvent というイベントやプロパティは無いと思います。

とりあえず、ボタンで止まるというか、キー入力をうまく拾えて
いないという話なら、それぞれのキーイベントに渡されるキー入力を、
App.LogEvent メソッド等で記録して、違いを比較してみては如何でしょう。

あと、(KeyPress ではなく)KeyDown/Up の場合は、キーボードの種類にも
気を付けてみてください。

編集 削除
はっしー  2010-09-24 02:34:58  No: 102573  IP: [192.*.*.*]

魔界の仮面弁士様
回答して頂きありがとうございます。
コマンドボタンに書いているソースは以下になります(Keydownも同じKeyUpと同じ内容で書いています)。
この間は
1.テキストボックス
2.コマンドボタン
3.テキストボックス
と書きましたが、
実際はコマンドボタンが複数のテキストボックスに間にある並びとなっています(コマンドボタンは制御用のダミー項目として使用)。
1.商品コードテキストボックス
2.商品名テキストボックス
3.売上数量テキストボックス
4.単位テキストボックス
5.コマンドボタン(ダミー項目)
6.売上単価
7.売上金額

【コマンドボタンのソース】
Private Sub 頁開始_KeyUp(Index As Integer, KeyCode As MSForms.ReturnInteger, Shift As Integer)
    Debug.Print "頁開始_KeyUp" & KeyCode
    If KeyCode = 13 Or KeyCode = 9 Or KeyCode = 97 Or KeyCode = 39 Or KeyCode = 40 Then
            If 売上単価(Index).TabStop = True Then
                売上単価(Index).SetFocus
            ElseIf 売上金額(Index).TabStop = True Then
                売上金額(Index).SetFocus
            End If
    ElseIf KeyCode = 37 Or KeyCode = 38 Then
        If 単位(Index).TabStop = True Then
            単位(Index).SetFocus
        ElseIf 売上数量(Index).TabStop = True Then
            売上数量(Index).SetFocus
        ElseIf 商品名(Index).TabStop = True Then
            商品名(Index).SetFocus
        ElseIf 商品コード(Index).TabStop = True Then
            商品コード(Index).SetFocus
        End If
    End If
End Sub

>キー操作以外でフォーカス移動した場合は?
マウスでクリックした場合はコマンドボタンにフォーカスがとまったままでした。

>VB6 に、KeyEvent というイベントやプロパティは無いと思います
申し訳ありません。KeyDownとKeyUpのことを指しています。

>とりあえず、ボタンで止まるというか、キー入力をうまく拾えて
>いないという話なら、それぞれのキーイベントに渡されるキー入力を、
>App.LogEvent メソッド等で記録して、違いを比較してみては如何でしょう。
Debug.Printで私の端末とお客さんの端末で動きを確認しました。
私の端末では、コマンドボタンにフォーカスが移動したのち(gotFocusイベント発生)、KeyUpのイベントが発生し、テキストボックスに遷移していたのですが、お客さんの端末では、
Enterや↑を遅く押した場合は私の端末と同じ動きをしますが、
すばやくEnterや↑を押した(たとえば7.の項目からすばやく↑を2回)
ときにはコマンドボタンのGotFocusイベントのみが発生し、KeyUpのイベントがはしらず、コマンドボタンにとまってしまいました。
ただし、プログラムを立ち上げた直後(Form_Load後)の一回目は
すばやく押してもコマンドボタンにとまるようなことはなく、
二回目以降はすばやく押すとコマンドボタンでとまってしまう現象と
なってます。

>あと、(KeyPress ではなく)KeyDown/Up の場合は、キーボードの種類にも
>気を付けてみてください。
普段は109を使っていますが、106でも同様でした。

今のところお客さんの端末との違いはスペックぐらいと思われます
(スペックの違いでイベントがひろえないのでしょうか?)。
私の端末:Pentium4 2.66GHz メモリ504MB
お客さんの端末:Intel Core2 Duo 2.93GHz メモリ2GB

編集 削除
魔界の仮面弁士  2010-09-24 10:07:31  No: 102574  IP: [192.*.*.*]

> Keydownも同じKeyUpと同じ内容で書いています。
…? KeyDown と KeyUp の両方に、同じコードを書いているのですか?

> コマンドボタンは制御用のダミー項目として使用
「制御用のダミー項目」というのは、どのような物を意図しているのでしょうか?

> Private Sub 頁開始_KeyUp(Index As Integer, KeyCode As MSForms.ReturnInteger, Shift As Integer)
Microsoft Forms 2.0 コントロールは使用しないでください。
標準コントロールか、または VB6 用に開発された ActiveX コントロールを
利用するようにするべきです。

MSForms 2.0 は VBA から利用されるものであって、VB6 からの利用を
想定したものではありません。Office や Service Pack のバージョン等にも
依存することになるので、動作的に不安定となります。
(なお、MSForms に関する動作不具合については、
Microsoft Knowledge Base 等を参照してください)

一例を挙げると、VB6 フォーム上に MSForms 版の TextBox を貼った場合に、
Shift + Tab でのコントロール遷移が正常に機能しない可能性があります。
# VB標準のForm + TextBox の組み合わせや、
# VBA UserForm + MSForms.TextBox の組み合わせでは問題なし。


どうしても VB6 から MSForms を使いたいのであれば、VB6 標準の
フォームではなく、VBA の ユーザーフォーム上に貼り付けて
利用してください。これなら問題は少ないです。

(1) [プロジェクト(P)]-[コンポーネント(O)...]メニューで表示されるダイアログの、
  「デザイナ」タブを開きます。(「コントロール」タブではありません)。

(2) その中の『Microsoft Forms 2.0 Form』にチェックを入れ、
  ダイアログを [OK] で閉じます。

(3) [プロジェクト(P)]-[Microsoft Forms 2.0 Form]メニューを選択します。
  プロジェクト エクスプローラに、VBA のユーザーフォームが追加されます。

(4) VBA Form のデザイナ画面を開き、MSForms 専用ツールボックスから、
  必要なコントロールを貼り付けます。MSForms のツールボックスが
  見当たらない場合は、フォームを右クリックして、[ツールボックス...]に
  チェックを入れると表示されます。

(5) あとは普通のフォームと同様に使用できます。
  ただし、VB.Form と MSForms.UserForm、VB.TextBox と MSForms.TextBox とでは
  使用できる機能に差があるので注意が必要です。

編集 削除
はっしー  2010-10-06 12:44:52  No: 102575  IP: [192.*.*.*]

魔界の仮面弁士様
返答が遅れて申し訳ありません。

>…? KeyDown と KeyUp の両方に、同じコードを書いているのですか?
両方に同じコードは不要でしたので、Keydownのコードは削除しました。

>「制御用のダミー項目」というのは、どのような物を意図しているのでしょうか?
Enterや↑キーを押されときにこのような制御用のCommadbuttonで
キーコードを判断して次に行く項目を指定しています。
(次に行く項目がTabIndexどおりでないため、今回は制御用の項目を用意しました)

>Microsoft Forms 2.0 コントロールは使用しないでください。
>標準コントロールか、または VB6 用に開発された ActiveX コントロール>を利用するようにするべきです。
MSFORMSはやめて、標準のコントロールを使用することで
開発環境とお客様の端末で動作が異なることはなくなりました。
ありがとうございました。

編集 削除