コンボボックスをプルダウンした時、
デフォルトでは8行表示と思いますが
それ以上又は以下に任意の行数表示と
するにはどうすればいいか教えて下さい。
MoveWindow API などを使用して高さを指定して下さい。
たしか、SendMessageで設定できなかったかなぁ…。
理由として、Delphiではデフォルトで、そういう設定ができるんですけど、
だから、MoveWindowを使うというような、ある種うら技的なことをやらなくても、いいと思うんですよ。
あとは、どこかで見たような記憶があるということ。
ここのサンプルに情報があったような気もしますし、
どこかの情報があるサイトを探さないといけないかもしれません。
先ほど簡単に調べてみましたけど、見つかりませんでした。
>たしか、SendMessageで設定できなかったかなぁ…。
流れとしてはSendMessageで項目の高さを取得して、
それと項目数からWindowの高さを計算して、
MoveWindow することになります。
APIの比較的簡単な使用例なら
vbvbvb.comあたりにサンプルあるでしょう。
.frm
Option Explicit
Private Sub Command1_Click()
Dim udtPointForm As tagPOINT
Dim udtRectCombo As tagRECT
Dim lngComboBoxHeight As Long
Dim lngComboBoxWidth As Long
Dim lngListItemHeight As Long
Dim lngNewCtrlHeight As Long
Dim lngGetComponent As Long
Dim lngWin32apiResultCode As Long
' 変更する構成要素にリストボックスを指定
lngGetComponent = 0
With Combo1
' シンプルコンボ(標準コンボ)以外で有効
If .Style <> vbComboSimple Then
' コンボボックスの画面上の相対座標を取得
lngWin32apiResultCode = GetWindowRect(.hwnd, udtRectCombo)
' 取得した座標からフォームの相対座標を取得
udtPointForm.x = udtRectCombo.Left
udtPointForm.y = udtRectCombo.Top
lngWin32apiResultCode = ScreenToClient(Form1.hwnd, udtPointForm)
' リストボックス項目の高さを取得
lngListItemHeight = SendMessage(.hwnd, CB_GETITEMHEIGHT, lngGetComponent, _
ByVal CLng(0))
' コンボボックスの高さを取得
lngComboBoxHeight = .Height \ Screen.TwipsPerPixelX
' コンボボックスの幅を取得
lngComboBoxWidth = .Width \ Screen.TwipsPerPixelY
' 新しいサイズを計算
lngNewCtrlHeight = lngComboBoxHeight + (lngListItemHeight * .ListCount) _
+ (1 * 2)
' 新しいサイズで再描画
lngWin32apiResultCode = MoveWindow(.hwnd, udtPointForm.x, udtPointForm.y, _
lngComboBoxWidth, lngNewCtrlHeight, CLng(1))
End If
End With
End Sub
Private Sub Form_Load()
Dim lngAddItemCount As Long
Dim i As Integer
Label1.Alignment = vbRightJustify
Label1.Caption = "コンボボックス"
With Combo1
For lngAddItemCount = 0 To (12 - 1)
.AddItem (Format(CDate(lngAddItemCount + 1 & "/1"), "mmmm"))
Next lngAddItemCount
.ListIndex = 0
End With
' コマンドボタンの初期化
Command1.Caption = "実行"
End Sub
.bas
Option Explicit
' 点のx座標とy座標を定義する構造体の宣言
Type tagPOINT
x As Long
y As Long
End Type
' 長方形の左上隅と右下隅の座標を定義する構造体の宣言
Type tagRECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
' 指定されたウィンドウの位置と寸法を変更する関数の宣言
Declare Function MoveWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal x As Long, _
ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal bRepaint As Long) As Long
' 指定されたウィンドウの境界長方形の寸法を取得する関数の
' 宣言
Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, _
lpRect As tagRECT) As Long
' 画面上の指定された点のスクリーン座標をクライアント座標に
' 変換する関数の宣言
Declare Function ScreenToClient Lib "user32.dll" (ByVal hwnd As Long, _
lpPoint As tagPOINT) As Long
' ウィンドウにメッセージを送る関数の宣言
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As Long
' コンボボックスの構成要素の高さを取得することを
' 示す定数の宣言
Public Const CB_GETITEMHEIGHT = &H154
もっと簡単な方法ってないのかな?
リストボックスで代替させる方法として下記の方法
を気がつきましたが、コンボボックス自体の行数変更
をするには、APIでないと駄目ですか?
Form に Command1、Combo1 および List1(Width
はCombo1と同じ、Heightは適宜、位置はCombo1の
直下に配置、VisibleプロパティーはFalse)を配置。
Option Explicit
Private Sub Combo1_GotFocus()
'コンボボックスがClickされたらリストボックスを表示。
List1.Visible = True
'フォーカスをリストボックスに移すことにより、 _
コンボボックスのDrop Down メニューを非表示。
List1.SetFocus
End Sub
Private Sub Command1_Click()
End
End Sub
Private Sub Form_Load()
Dim lngAddItemCount As Long
With Combo1
For lngAddItemCount = 0 To (12 - 1)
.AddItem (Format(CDate(lngAddItemCount + 1 & "/1"), "mmmm"))
Next lngAddItemCount
.ListIndex = 0
End With
'コマンドボタンの初期化。
Command1.Caption = "終了"
'コンボボックスと同内容をリストボックスに設定。
With List1
For lngAddItemCount = 0 To (12 - 1)
.AddItem (Format(CDate(lngAddItemCount + 1 & "/1"), "mmmm"))
Next
.ListIndex = 0
End With
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Formにフォーカスが移ったら、List1を非表示。
List1.Visible = False
End Sub
Private Sub List1_Click()
With List1
'リストボックスの選択を、コンボボックスに反映。
Combo1.ListIndex = .ListIndex
'選択項目を最上端に設定。
.TopIndex = .ListIndex
'リストボックスの非表示。
.Visible = False
End With
End Sub
Private Sub List1_LostFocus()
'List1がフォーカスを失ったら、List1を非表示。
List1.Visible = False
End Sub
続けて発言させて頂きます。
前回、リストボックスを使っての提案をしましたが、下側に余裕が
ない時コンボボックスであれば自動的に上側に表示されますので、
そのための追加修正が必要です。
もう一つ、自分で質問しておきながら、回答もどきを提案するなど
とんでもない了見であると気が付きました。
しかも上記の通り欠陥回答であり誠にもってお恥ずかしい次第です。
当初はそんな積りではなかったとは言え皆様方にお詫び致します。
標準のコンボボックスでの高さ変更ではありませんが・・・
Microsoft Forms 2.0 Object Library (FM20.DLL)が使えれば、
そのComboBoxにはリストの高さを取得・設定するListRowsプロパティが
備わっています。
直接的な回答ではなく、代替え案であり、単なる逃げ道かもしれませんが、
これで十分かもしれませんので参考までに。
Microsoft Forms 2.0 Object Library (FM20.DLL)は使用しない方がいいです。
VBで使うにはバグだらけなんで後で泣きを見ます。
さらに……詳しくは↓のHPをどうぞ。
http://www.gj.il24.net/~nakasima/vb/trap/index.htm#VBTRAP12
多数の方々からご回答を頂き全て勉強になることばかりでした。
ありがとうございました。今後共初心者をお助け下さい。
ずいぶん時間がかかりましたけど、さっき見かけましたので。
まだ、問題解決してないかな?
SendMessage(Hwnd,CB_SETDROPPEDWIDTH, 幅, 0)
ツイート | ![]() |