OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

ComboBoxについておしえてください

  • すぐに回答を!
  • 質問No.161752
  • 閲覧数357
  • ありがとう数2
  • 気になる数0
  • 回答数6
  • コメント数0

お礼率 23% (40/169)

↓・↑とクリックを区別したいのですがどうすればよいのか
教えてください。

↑をおすとKeyDownにいきClickにいきます。

↑をおしたときにClickにいかないようにすることはできませんか?

よろしくおねがいします。
通報する
  • 回答数6
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.5
レベル12

ベストアンサー率 65% (276/422)

サンプルを作ってみました。
必要なものは
フォーム1
コンボボックス1
標準モジュール
です。


処理を説明します。
サブクラス化という処理をしています。
VBにはクリックやボタンダウンなどのイベントがありますが、全てWIndowsが送ってくる定数(メッセージ)を読み取り、その値によってイベントの内容が決まります。このプログラムはコンボボックスにくるWINDOWSからのメッセージをcomboProc関数にて監視し(これがサブクラス化)、カーソルのイベントだけコンボボックスのリスト部分が非表示のときには、メッセージをWINDOWSに返さないようにしています。もしリスト部分が表示されていても、WM_COMMANDという決定というメッセージを返さないようにしています。


サブクラス化の最中に強制終了をすると、VBが落ちます。必ず普通にフォームを閉じて終了しましょう。
常にこの関数が動いている状態なので、プログラム作成最終段階での組み込みをお奨めします。それまでは、[サブクラス化の開始][サブクラス化の終了]部分をコメントにしておくだけで、このプログラムは動きませんので安心してください。


-----フォーム1(ここから)-----
Private Sub Form_Load()
  With Me
    'ダミーのデータ
    With .Combo1
      .AddItem 1
      .AddItem 2
      .AddItem 3
      .AddItem 4
    End With
    
    'サブクラス化の開始
    pLngProc = SetWindowLong(.Combo1.hwnd, GWL_WNDPROC, AddressOf comboProc)
  End With
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  With Me
    'サブクラス化の終了
    Call SetWindowLong(.Combo1.hwnd, GWL_WNDPROC, pLngProc)
  End With
End Sub
-----フォーム1(ここまで)-----

-----標準モジュール(ここから)-----
Option Explicit

Public Const GWL_WNDPROC  As Long = (-4)
Private Const WM_COMMAND = &H111 'メニューが選択されたあるいはコントロールにイベントが発生した
Private Const WM_KEYDOWN = &H100 'キーボードのキーが押された
Private Const WM_KEYUP = &H101 'キーが解放された

Private Const CB_GETDROPPEDSTATE = &H157 'コンボボックスでリストボックス部が開いているかどうか調べる
Private Const CB_SHOWDROPDOWN = &H14F 'コンボボックスでドロップダウンリストを表示・非表示

Private Const KEY_UP  As Byte = &H1
Private Const KEY_DOWN As Byte = &H2

Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long


'プロセス
Public pLngProc   As Long

'カーソル↑←を押されたとき、1バイト目にフラグを立てる
'カーソル↓→を押されたとき、2バイト目にフラグを立てる
Private bytKeyFlg  As Byte


Public Function comboProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Select Case uMsg
    'キーダウン
    Case WM_KEYDOWN
      'wParamにはキーコードが入る
      Select Case wParam
        'カーソル↑←
        Case vbKeyUp, vbKeyLeft
          '1バイト目にフラグを立てる
          bytKeyFlg = bytKeyFlg Or KEY_UP
        'カーソル↓→
        Case vbKeyDown, vbKeyRight
          '2バイト目にフラグを立てる
          bytKeyFlg = bytKeyFlg Or KEY_DOWN
        'その他のキー
        Case Else
          '通常処理でメッセージを返す
          GoTo PGMEND
      End Select
      
      'コンボボックスのリスト部分が非表示のときは、メッセージを返さない
      If SendMessage(hwnd, CB_GETDROPPEDSTATE, ByVal 0&, ByVal 0&) = 0 Then
        GoTo PGMEXIT
      End If

    'キーアップ
    Case WM_KEYUP
      'wParamにはキーコードが入る
      Select Case wParam
        'カーソル↑←
        Case vbKeyUp, vbKeyLeft
          '1バイト目のフラグをおろす
          bytKeyFlg = bytKeyFlg And (Not KEY_UP)
        'カーソル↓→
        Case vbKeyDown, vbKeyRight
          '2バイト目のフラグをおろす
          bytKeyFlg = bytKeyFlg And (Not KEY_DOWN)
      End Select
    
    'クリックやEnter入力時の処理
    Case WM_COMMAND
      'カーソル↑←やカーソル↓→が移動するたびに、値を設定してしまうのを防ぐ
      If bytKeyFlg > 0 Then
        'カーソルキーのフラグがたっているので、メッセージを返さない
        GoTo PGMEXIT
      End If
      '強制的にDROPDOWNリストを閉じる
      Call SendMessage(hwnd, CB_SHOWDROPDOWN, 0&, ByVal 0&)
  End Select
PGMEND:
  comboProc = CallWindowProc(pLngProc, hwnd, uMsg, wParam, lParam)
PGMEXIT:
End Function
-----標準モジュール(ここまで)-----
-PR-
-PR-

その他の回答 (全5件)

  • 回答No.1
レベル12

ベストアンサー率 65% (276/422)

オブジェクトは何ですか?コマンドボタンですか? ↓・↑はカーソルキーですか? 何らかのオブジェクトの上でカーソルキーを押したら、クリックイベントが発生するのを回避したいという捕らえ方でよろしいですか? ...続きを読む
オブジェクトは何ですか?コマンドボタンですか?
↓・↑はカーソルキーですか?

何らかのオブジェクトの上でカーソルキーを押したら、クリックイベントが発生するのを回避したいという捕らえ方でよろしいですか?
補足コメント
chiba-masaru

お礼率 23% (40/169)

やりたいことは、comboBoxでF4をおして内容を画面上に出力して
クリックされたときは、Enterと同じように選択さらた内容をとりこみ
次の項目にいきたいのです。
また、↑・↓は青の帯びが上下するだけにしたいのですがどうすればいいですか

またComboBoxには名称とコードをもたして
ComboBox.Textには名称のみ表示したいのですが
なかなかうまくいきません、これも何かいい方法はないのですか?
教えてください。
投稿日時 - 2001-11-02 16:36:06
  • 回答No.2
レベル12

ベストアンサー率 65% (276/422)

多分VBの標準機能では無理のような気がします。 あるといえば、 1.コンボボックスのプロセスを監視 2.キーダウンイベントにフラグを立てる 3.フラグによりテキストの変更を破棄させる といったような処理ですが、プロセス監視は結構ムズイですよ。 デバッグもしづらいし。。。
多分VBの標準機能では無理のような気がします。
あるといえば、
1.コンボボックスのプロセスを監視
2.キーダウンイベントにフラグを立てる
3.フラグによりテキストの変更を破棄させる

といったような処理ですが、プロセス監視は結構ムズイですよ。
デバッグもしづらいし。。。
  • 回答No.3
レベル13

ベストアンサー率 59% (729/1235)

Private Sub Combo1_KeyDown(KeyCode As Integer, Shift As Integer) If (KeyCode = vbKeyDown Or KeyCode = vbKeyUp) Then SendMessage Combo1, CB_SHOWDROPDOWN, 1, 0 End If E ...続きを読む
Private Sub Combo1_KeyDown(KeyCode As Integer, Shift As Integer)

If (KeyCode = vbKeyDown Or KeyCode = vbKeyUp) Then
SendMessage Combo1, CB_SHOWDROPDOWN, 1, 0
End If
End Sub
  • 回答No.4
レベル12

ベストアンサー率 65% (276/422)

>  SendMessage Combo1, CB_SHOWDROPDOWN, 1, 0 の書き方が違います   SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, 1, 0 が正しい書き方です。 でもこのAPI、ドロップダウンリストの表示/非表示の切り替えをするだけで、仕様を満たさないのではないのでしょうか?
>  SendMessage Combo1, CB_SHOWDROPDOWN, 1, 0
の書き方が違います
  SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, 1, 0
が正しい書き方です。

でもこのAPI、ドロップダウンリストの表示/非表示の切り替えをするだけで、仕様を満たさないのではないのでしょうか?
  • 回答No.6
レベル12

ベストアンサー率 65% (276/422)

すいません。さっきのエラーです。+書き忘れです。 書き忘れは、コンボボックスのスタイルがドロップダウンリスト限定だと言うことです。ドロップダウンコンボのままでは無意味です。 エラーはカーソルで選んでエンターを押してもクリックイベントが発生しません。。。もうちょっと研究が必要です。。。m(__)m
すいません。さっきのエラーです。+書き忘れです。

書き忘れは、コンボボックスのスタイルがドロップダウンリスト限定だと言うことです。ドロップダウンコンボのままでは無意味です。

エラーはカーソルで選んでエンターを押してもクリックイベントが発生しません。。。もうちょっと研究が必要です。。。m(__)m
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ