2008/10/30(Thu) 16:34:24 編集(投稿者)
■No27213 (魔界の仮面弁士 さん) に返信
> ■No27210 (ごろ さん) に返信
>
> ところで、その対象となるボタンはウィンドウ ハンドルを持っているのでしょうか?
> 一般的なボタンなら、アクティブ時に BM_CLICK を送りつけてやれば済むでしょうけれども、
あくまでハンドルを持っている前提でWM_ACTIVATEを捕まえるサブクラスを作ってみました(ただしVB6)
Atach()にアクティブ時に通知が欲しいWindowのハンドルを渡せばWindowProc()に飛んできます。
サブクラスを解除したい場合はDetach()を呼んで下さい。
一応戻り値では判断するようにしましたが、実際に運用するなら適切なエラー処理を入れてください。
Option Explicit
Public Const GWL_WNDPROC = (-4)
Public Const WM_ACTIVE As Long = &H6
Public Const WA_INACTIVE As Long = &H0
Public Const WA_ACTIVE As Long = &H1
Public Const WA_CLICKACTIVE As Long = &H2
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongW" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcW" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private lpDefProc As Long
Public Function Atach(hWnd As Long) As Boolean
'サブクラス化
lpDefProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
If lpDefProc <> 0 Then
Atach = True
Exit Function
End If
Atach = False
End Function
Public Function Detach(hWnd As Long) As Boolean
Dim ret As Long
If lpDefProc <> 0 Then
'サブクラス化の停止
ret = SetWindowLong(hWnd, GWL_WNDPROC, lpDefProc)
If ret <> 0 Then
lpDefProc = 0
Detach = True
Exit Function
End If
End If
Detach = False
End Function
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case uMsg
Case WM_ACTIVE
Select Case wParam
Case WA_INACTIVE
Debug.Print "非Active化されました。"
Case WA_ACTIVE
Debug.Print "Active化されました。"
'TODO ここで押下対象となるボタンへBM_CLICKを送る
End Select
End Select
WindowProc = CallWindowProc(lpDefProc, hWnd, uMsg, wParam, lParam)
End Function
.NETでサブクラス化するならNativeWindowを継承だったかな。