Как известно, события окон в Visual Basic 6 являются реакцией на получение определённых сообщений, посылаемых операционной системой Windows. К примеру событие формы Form_KeyDown соответствует получению окном сообщения WM_KEYDOWN.
Не секрет, что количество сообщений, получаемых окном, значительно превышает количество событий, обрабатываемых средой Visual Basic 6. Для того, чтобы обрабатывать сообщения, не поддерживаемые средой, применяется субклассирование.
Субклассирование представляет собой замену стандартной оконной процедуры, вызываемой по умолчанию, пользовательской. В пользовательской оконной процедуре содержится код обработки выбранного сообщения, и последующий вызов стандартной.
Все оконные процедуры должны иметь следующий вид:
Public Function WindowProc( _
ByVal hwnd As Long, _
ByVal iMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
End Function
Название процедуры может быть любым, но соблюдение сигнатуры обязательно.
Каждое сообщение, как Вы уже поняли, имеет четыре параметра:
hwnd - дескриптор окна, для которого предназначено сообщение;
iMsg - идентификатор сообщения (например WM_KEYDOWN);
wParam и lParam - два длинных целых числа, параметры, специфичные для каждого типа сообщения, каждое из которых может содержать, в свою очередь, по два коротких целых числа.
Как же можно заменить стандартную оконную процедуру? Здесь нам на помощь придёт функция Windows API SetWindowLong. Она определяется так:
Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Давайте попробуем переопределить событие нажатия пользователем левой кнопки мыши. Создайте новый проект типа Standard EXE. Переименуйте форму на SubclassedForm1. Добавьте к нему стандартный модуль, назвав его, к примеру basSubclass. В модуле введите следующий код.
Option Explicit
Const GWL_WNDPROC = -4&
Const WM_LBUTTONDOWN = &H201&
Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" _
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 Sub SetWndProc()
SubclassedForm1.hPrevWndProc = _
SetWindowLong(SubclassedForm1.hwnd, _
GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Function WindowProc(ByVal hwnd As Long, _
ByVal iMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Select Case iMsg
Case WM_LBUTTONDOWN
MsgBox "Обработка события нажатия " _
& "левой кнопки мыши временно " & _
"не производится.", _
vbInformation, "Санитарный день"
End Select
WindowProc = CallWindowProc( _
SubclassedForm1.hPrevWndProc, hwnd, _
iMsg, wParam, lParam)
End Function
В модуле формы введите следующий код:
Option Explicit
Private m_hPrevWndProc As Long
Public Property Get hPrevWndProc() As Long
hPrevWndProc = m_hPrevWndProc
End Property
Public Property Let hPrevWndProc(Value As Long)
m_hPrevWndProc = Value
End Property
Private Sub Form_Initialize()
SetWndProc
End Sub
Запустите проект на выполнение, и нажмите левую кнопку мыши. Результат ошеломляющий!
Автор - Цзяофань
|