![]() 今回のサンプルの実行画面 |
タブコントロールを作るにはCreateWindowEx()関数を使います。
ウィンドウクラスはWC_TABCONTROLを指定します。
一般的にタブコントロールは子ウィンドウなのでWS_CHILDを指定します。
あとはWS_VISIBLEを忘れずに。コードは下のようになります。
'タブコントロール作成
hTabWnd = CreateWindowEx(0, WC_TABCONTROL, "", _
WS_VISIBLE Or WS_TABSTOP Or WS_CHILD, _
0, 0, Me.ScaleWidth, Me.ScaleHeight, Me.hWnd, IDM_TAB1, App.hInstance, 0) |
Type TCITEM
mask As Long 'どのパラメータを有効にするかのマスクフラグ
dwState As Long '現在のタグの状態を取得
dwStateMask As Long 'dwStateのマスクフラグ
pszText As String 'タブ内に表示する文字列
cchTextMax As Long '同、バイト数
iImage As Long '同、イメージ(不要のとき-1)
lParam As Long 'アプリケーション定義の値
End Type |
Public Const TCIF_TEXT = &H1 'pdzTextにデータが含まれる Public Const TCIF_IMAGE = &H2 'hImageにデータが含まれる Public Const TCIF_STATE = &H10 'dwStateにデータが含まれる Public Const TCIF_PARAM = &H8 'lParamにデータが含まれる |
タブコントロールに決められた定数を送ると、さまざまな情報を取得したり設定したりすることができます。
それらの定数はSendMessage()関数で送ればいいだけなのですが、マクロが定義されているのでそれを使うのが一般的です。
今回はよく使うマクロだけリストアップしてVBに変換してみました。
Public Sub TabCtrl_Adjustrect _
(ByVal hTabWnd As Long, ByVal operation As Boolean, lpRect As RECT)
'タブコントロールの表示領域のサイズを取得
'operation=true タブコントロール領域の表示領域を渡す
'operation=false ウィンドウ矩形のサイズを取得する
Call SendMessageAny(hTabWnd, TCM_ADJUSTRECT, operation, lpRect)
End Sub
|
メッセージが送信できればタブコントロールを作ることはできますが、メッセージを受け取ることはできません。
例えば、マウスがクリックされたとかタブページが切り替えられたなどです。
特に後者はそのメッセージが取得できないと致命的です。
ところが困ったことにVBにはメッセージを取得する仕組みがありません。
何故かって?実はメッセージの処理をすると凄く面倒だからです。
そのため、VBではウィンドウに送られてくるメッセージは全てVBが受け取って処理してしまいます。
![]() フック処理の説明図 |
Private Sub Form_Load()
'ウィンドウプロシージャのアドレスを変更する
hOrgWndProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, ChangeAddressOf(AddressOf WndProc))
End Sub
|
タブコントロールからのメッセージはWM_NOTIFYメッセージで送られてきます。
lParamにはNMHDR構造体のアドレスが送られてくるので、CopyMemory()関数でコピーして内容を取得します。
送られてくるメッセージもいくつか定義されていますが、今回はシンプルにタブが切り替わったときだけ処理することにします。
タブが切り替わったときに送られてくるメッセージはTCN_SELCHANGEです。
このメッセージの受信をコードにすると下のようになります。
Public Function WndProc(ByVal hWnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
'ユーザー定義のウィンドウプロシージャ
Select Case msg
Case WM_NOTIFY
Dim lpNMHDR As NMHDR, num As Long
Call CopyMemory(lpNMHDR, ByVal lParam, Len(lpNMHDR))
If lpNMHDR.code = TCN_SELCHANGE Then
msgbox "ページが切り替わった"
End If
End Select
WndProc = CallWindowProc(hOrgWndProc, hWnd, msg, wParam, lParam)
End Function |
ここではタブコントロールを使った簡単なプログラムを紹介します。
ここまでの説明を理解するうえで最低限必要なコードの部分だけを紹介します。
全部のコードを見たい場合には、ページ下部からダウンロードして下さい。
![]() 今回のサンプルの実行画面 |
Form1Private Const IDM_TAB1 = &H100 'TABコントロールのID
Private Sub Form_Load()
'============================
' ウィンドウの初期化
'============================
Dim hTabWnd As Long
Dim tci As TCITEM
'タブコントロール作成
hTabWnd = CreateWindowEx(0, WC_TABCONTROL, "", _
WS_VISIBLE Or WS_TABSTOP Or WS_CHILD, _
0, 0, Me.ScaleWidth, Me.ScaleHeight, Me.hWnd, IDM_TAB1, App.hInstance, 0)
'アイテムの追加
tci.mask = TCIF_TEXT
tci.iImage = -1
tci.pszText = "1ページ"
Call TabCtrl_InsertItem(hTabWnd, 0, tci)
tci.pszText = "2ページ"
Call TabCtrl_InsertItem(hTabWnd, 1, tci)
tci.pszText = "3ページ"
Call TabCtrl_InsertItem(hTabWnd, 2, tci)
'ウィンドウプロシージャのアドレスを変更する
hOrgWndProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, ChangeAddressOf(AddressOf WndProc))
End Sub
|
Module2Public Function WndProc(ByVal hWnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
'ユーザー定義のウィンドウプロシージャ
Select Case msg
Case WM_NOTIFY
Dim lpNMHDR As NMHDR, num As Long
Call CopyMemory(lpNMHDR, ByVal lParam, Len(lpNMHDR))
If lpNMHDR.code = TCN_SELCHANGE Then
'タブコントロールのアイテム選択が変化した
num = TabCtrl_GetCurSel(lpNMHDR.hwndFrom)
Call OutMessage(lpNMHDR.hwndFrom, 40, 100, _
(num + 1) & "ページ目が選択されました")
End If
End Select
WndProc = CallWindowProc(hOrgWndProc, hWnd, msg, wParam, lParam)
End Function
|
ダウンロード(TabControl.lzh 3.98KB)